2 * Copyright Johannes Sixt
3 * This file is licensed under the GNU General Public License Version 2.
4 * See the file COPYING in the toplevel directory of the source directory.
10 #include <kconfigbase.h>
12 #include "dbgdriver.h" /* memory dump formats */
15 class MemoryViewItem
: public QListViewItem
18 MemoryViewItem(QListView
* parent
, QListViewItem
* insertAfter
, QString raw
, QString cooked
)
19 : QListViewItem(parent
, insertAfter
, raw
, cooked
), m_changed(8) {}
21 void setChanged(uint pos
, bool b
) { m_changed
[pos
] = b
; }
24 virtual void paintCell(QPainter
* p
, const QColorGroup
& cg
,
25 int column
, int width
, int alignment
);
27 QArray
<bool> m_changed
;
30 void MemoryViewItem::paintCell(QPainter
* p
, const QColorGroup
& cg
,
31 int column
, int width
, int alignment
)
33 if( column
> 0 && m_changed
[column
- 1] ) {
34 QColorGroup newcg
= cg
;
35 newcg
.setColor(QColorGroup::Text
, red
);
36 QListViewItem::paintCell(p
, newcg
, column
, width
, alignment
);
38 QListViewItem::paintCell(p
, cg
, column
, width
, alignment
);
43 MemoryWindow::MemoryWindow(QWidget
* parent
, const char* name
) :
44 QWidget(parent
, name
),
46 m_expression(true, this, "expression"),
47 m_memory(this, "memory"),
49 m_format(MDTword
| MDThex
)
51 QSize minSize
= m_expression
.sizeHint();
52 m_expression
.setMinimumSize(minSize
);
53 m_expression
.setInsertionPolicy(QComboBox::NoInsertion
);
54 m_expression
.setMaxCount(15);
56 m_memory
.addColumn(i18n("Address"), 80);
58 m_memory
.setSorting(-1); /* don't sort */
59 m_memory
.setAllColumnsShowFocus(true);
60 m_memory
.header()->setClickEnabled(false);
63 m_layout
.addWidget(&m_expression
, 0);
64 m_layout
.addWidget(&m_memory
, 10);
67 connect(&m_expression
, SIGNAL(activated(const QString
&)),
68 this, SLOT(slotNewExpression(const QString
&)));
71 m_popup
.insertItem(i18n("B&ytes"), MDTbyte
);
72 m_popup
.insertItem(i18n("Halfwords (&2 Bytes)"), MDThalfword
);
73 m_popup
.insertItem(i18n("Words (&4 Bytes)"), MDTword
);
74 m_popup
.insertItem(i18n("Giantwords (&8 Bytes)"), MDTgiantword
);
75 m_popup
.insertSeparator();
76 m_popup
.insertItem(i18n("He&xadecimal"), MDThex
);
77 m_popup
.insertItem(i18n("Signed &decimal"), MDTsigned
);
78 m_popup
.insertItem(i18n("&Unsigned decimal"), MDTunsigned
);
79 m_popup
.insertItem(i18n("&Octal"), MDToctal
);
80 m_popup
.insertItem(i18n("&Binary"), MDTbinary
);
81 m_popup
.insertItem(i18n("&Addresses"), MDTaddress
);
82 m_popup
.insertItem(i18n("&Character"), MDTchar
);
83 m_popup
.insertItem(i18n("&Floatingpoint"), MDTfloat
);
84 m_popup
.insertItem(i18n("&Strings"), MDTstring
);
85 m_popup
.insertItem(i18n("&Instructions"), MDTinsn
);
86 connect(&m_popup
, SIGNAL(activated(int)), this, SLOT(slotTypeChange(int)));
89 * Handle right mouse button. Signal righteButtonClicked cannot be
90 * used, because it works only over items, not over the blank window.
92 m_memory
.viewport()->installEventFilter(this);
94 m_formatCache
.setAutoDelete(true);
97 MemoryWindow::~MemoryWindow()
101 bool MemoryWindow::eventFilter(QObject
*, QEvent
* ev
)
103 if (ev
->type() == QEvent::MouseButtonRelease
) {
104 handlePopup(static_cast<QMouseEvent
*>(ev
));
110 void MemoryWindow::handlePopup(QMouseEvent
* ev
)
112 if (ev
->button() == RightButton
)
115 if (m_popup
.isVisible())
121 m_popup
.popup(mapToGlobal(ev
->pos()));
127 void MemoryWindow::slotNewExpression(const QString
& newText
)
129 QString text
= newText
.simplifyWhiteSpace();
131 // see if the string is in the list
132 // (note: must count downwards because of removeItem!)
133 for (int i
= m_expression
.count()-1; i
>= 0; i
--)
135 if (m_expression
.text(i
) == text
) {
137 // look up the format that was used last time for this expr
138 unsigned* pFormat
= m_formatCache
[text
];
141 m_debugger
->setMemoryFormat(m_format
);
143 // remove this text, will be inserted at the top
144 m_expression
.removeItem(i
);
147 m_expression
.insertItem(text
, 0);
149 if (text
.isEmpty()) {
150 // if format was not in the cache, insert it
151 if (m_formatCache
[text
] == 0) {
152 m_formatCache
.insert(text
, new unsigned(m_format
));
157 displayNewExpression(text
);
160 void MemoryWindow::displayNewExpression(const QString
& expr
)
162 m_debugger
->setMemoryExpression(expr
);
163 m_expression
.setEditText(expr
);
165 // clear memory dump if no dump wanted
166 if (expr
.isEmpty()) {
168 m_old_memory
.clear();
172 void MemoryWindow::slotTypeChange(int id
)
174 m_old_memory
.clear();
177 if (id
& MDTsizemask
)
178 m_format
= (m_format
& ~MDTsizemask
) | id
;
179 if (id
& MDTformatmask
)
180 m_format
= (m_format
& ~MDTformatmask
) | id
;
181 m_debugger
->setMemoryFormat(m_format
);
183 // change the format in the cache
184 QString expr
= m_expression
.currentText();
185 expr
= expr
.simplifyWhiteSpace();
186 unsigned* pFormat
= m_formatCache
[expr
];
191 displayNewExpression(expr
);
194 void MemoryWindow::slotNewMemoryDump(const QString
& msg
, QList
<MemoryDump
>& memdump
)
197 if (!msg
.isEmpty()) {
198 new QListViewItem(&m_memory
, QString(), msg
);
202 MemoryViewItem
* after
= 0;
203 MemoryDump
* md
= memdump
.first();
205 // remove all columns, except the address column
206 for(int k
= m_memory
.columns() - 1; k
> 0; k
--)
207 m_memory
.removeColumn(k
);
209 //add the needed columns
210 QStringList sl
= QStringList::split( "\t", md
->dump
);
211 for (uint i
= 0; i
< sl
.count(); i
++)
212 m_memory
.addColumn("", -1);
214 QMap
<QString
,QString
> tmpMap
;
216 for (; md
!= 0; md
= memdump
.next())
218 QString addr
= md
->address
.asString() + " " + md
->address
.fnoffs
;
219 QStringList sl
= QStringList::split( "\t", md
->dump
);
222 tmpMap
[addr
] = md
->dump
;
224 after
= new MemoryViewItem(&m_memory
, after
, addr
, "");
227 QMap
<QString
,QString
>::Iterator pos
= m_old_memory
.find( addr
);
229 if( pos
!= m_old_memory
.end() )
230 tmplist
= QStringList::split( "\t", pos
.data() );
232 for (uint i
= 0; i
< sl
.count(); i
++)
234 after
->setText( i
+1, *sl
.at(i
) );
237 tmplist
.count() > 0 &&
238 *sl
.at(i
) != *tmplist
.at(i
);
239 after
->setChanged(i
, changed
);
243 m_old_memory
.clear();
244 m_old_memory
= tmpMap
;
247 static const char MemoryGroup
[] = "Memory";
248 static const char NumExprs
[] = "NumExprs";
249 static const char ExpressionFmt
[] = "Expression%d";
250 static const char FormatFmt
[] = "Format%d";
251 static const char ColumnWidths
[] = "ColumnWidths";
253 void MemoryWindow::saveProgramSpecific(KConfigBase
* config
)
255 KConfigGroupSaver
s(config
, MemoryGroup
);
257 int numEntries
= m_expression
.count();
258 config
->writeEntry(NumExprs
, numEntries
);
261 for (int i
= 0; i
< numEntries
;) {
262 QString text
= m_expression
.text(i
);
263 i
++; /* entries are counted 1-based */
264 exprEntry
.sprintf(ExpressionFmt
, i
);
265 fmtEntry
.sprintf(FormatFmt
, i
);
266 config
->writeEntry(exprEntry
, text
);
267 unsigned* pFormat
= m_formatCache
[text
];
268 unsigned fmt
= pFormat
!= 0 ? *pFormat
: MDTword
| MDThex
;
269 config
->writeEntry(fmtEntry
, fmt
);
275 for (int i
= 0; i
< 2; i
++) {
276 int w
= m_memory
.columnWidth(i
);
280 config
->writeEntry(ColumnWidths
, widths
);
283 void MemoryWindow::restoreProgramSpecific(KConfigBase
* config
)
285 KConfigGroupSaver
s(config
, MemoryGroup
);
287 int numEntries
= config
->readNumEntry(NumExprs
, 0);
288 m_expression
.clear();
292 // entries are counted 1-based
293 for (int i
= 1; i
<= numEntries
; i
++) {
294 exprEntry
.sprintf(ExpressionFmt
, i
);
295 fmtEntry
.sprintf(FormatFmt
, i
);
296 QString expr
= config
->readEntry(exprEntry
);
297 unsigned fmt
= config
->readNumEntry(fmtEntry
, MDTword
| MDThex
);
298 m_expression
.insertItem(expr
);
299 m_formatCache
.replace(expr
, new unsigned(fmt
& (MDTsizemask
| MDTformatmask
)));
302 // initialize with top expression
303 if (numEntries
> 0) {
304 m_expression
.setCurrentItem(0);
305 QString expr
= m_expression
.text(0);
306 m_format
= *m_formatCache
[expr
];
307 m_debugger
->setMemoryFormat(m_format
);
308 displayNewExpression(expr
);
313 int n
= config
->readListEntry(ColumnWidths
, widths
);
316 for (int i
= 0; i
< n
; i
++) {
317 QString wStr
= widths
.at(i
);
319 int w
= wStr
.toInt(&ok
);
321 m_memory
.setColumnWidth(i
, w
);
326 #include "memwindow.moc"