Update the admin/ directory.
[kdbg.git] / kdbg / memwindow.cpp
blob05727d18789a23f44cba3984f7cefa1994502725
1 /*
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.
5 */
7 #include "memwindow.h"
8 #include <qheader.h>
9 #include <klocale.h>
10 #include <kconfigbase.h>
11 #include "debugger.h"
12 #include "dbgdriver.h" /* memory dump formats */
15 class MemoryViewItem : public QListViewItem
17 public:
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; }
23 protected:
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);
37 } else {
38 QListViewItem::paintCell(p, cg, column, width, alignment);
43 MemoryWindow::MemoryWindow(QWidget* parent, const char* name) :
44 QWidget(parent, name),
45 m_debugger(0),
46 m_expression(true, this, "expression"),
47 m_memory(this, "memory"),
48 m_layout(this, 0, 2),
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);
62 // create layout
63 m_layout.addWidget(&m_expression, 0);
64 m_layout.addWidget(&m_memory, 10);
65 m_layout.activate();
67 connect(&m_expression, SIGNAL(activated(const QString&)),
68 this, SLOT(slotNewExpression(const QString&)));
70 // the popup menu
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));
105 return true;
107 return false;
110 void MemoryWindow::handlePopup(QMouseEvent* ev)
112 if (ev->button() == RightButton)
114 // show popup menu
115 if (m_popup.isVisible())
117 m_popup.hide();
119 else
121 m_popup.popup(mapToGlobal(ev->pos()));
123 return;
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) {
136 // yes it is!
137 // look up the format that was used last time for this expr
138 unsigned* pFormat = m_formatCache[text];
139 if (pFormat != 0) {
140 m_format = *pFormat;
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()) {
167 m_memory.clear();
168 m_old_memory.clear();
172 void MemoryWindow::slotTypeChange(int id)
174 m_old_memory.clear();
176 // compute new type
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];
187 if (pFormat != 0)
188 *pFormat = m_format;
190 // force redisplay
191 displayNewExpression(expr);
194 void MemoryWindow::slotNewMemoryDump(const QString& msg, QList<MemoryDump>& memdump)
196 m_memory.clear();
197 if (!msg.isEmpty()) {
198 new QListViewItem(&m_memory, QString(), msg);
199 return;
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 );
221 // save memory
222 tmpMap[addr] = md->dump;
224 after = new MemoryViewItem(&m_memory, after, addr, "");
226 QStringList tmplist;
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) );
236 bool changed =
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);
259 QString exprEntry;
260 QString fmtEntry;
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);
272 // column widths
273 QStrList widths;
274 QString wStr;
275 for (int i = 0; i < 2; i++) {
276 int w = m_memory.columnWidth(i);
277 wStr.setNum(w);
278 widths.append(wStr);
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();
290 QString exprEntry;
291 QString fmtEntry;
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);
311 // column widths
312 QStrList widths;
313 int n = config->readListEntry(ColumnWidths, widths);
314 if (n > 2)
315 n = 2;
316 for (int i = 0; i < n; i++) {
317 QString wStr = widths.at(i);
318 bool ok;
319 int w = wStr.toInt(&ok);
320 if (ok)
321 m_memory.setColumnWidth(i, w);
326 #include "memwindow.moc"