Reworked memory display to have a history of expressions that is saved
[kdbg.git] / kdbg / memwindow.cpp
blobf55ba6d69bb5692db370ed66ee150a0b79f57c5f
1 // $Id$
3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
6 #include "memwindow.h"
7 #if QT_VERSION >= 200
8 #include <kglobalsettings.h>
9 #else
10 #include <kapp.h>
11 #endif
12 #include <ksimpleconfig.h>
13 #include "debugger.h"
14 #include "dbgdriver.h" /* memory dump formats */
16 MemoryWindow::MemoryWindow(QWidget* parent, const char* name) :
17 QWidget(parent, name),
18 m_debugger(0),
19 m_expression(true, this, "expression"),
20 m_memory(this, "memory"),
21 m_layout(this, 0, 2),
22 m_format(MDTword | MDThex)
24 // use fixed font for contents
25 #if QT_VERSION < 200
26 m_memory.setFont(kapp->fixedFont);
27 #else
28 m_memory.setFont(KGlobalSettings::fixedFont());
29 #endif
31 QSize minSize = m_expression.sizeHint();
32 m_expression.setMinimumSize(minSize);
33 m_expression.setInsertionPolicy(QComboBox::NoInsertion);
34 m_expression.setMaxCount(15);
36 QSize memSize = m_memory.sizeHint();
37 if (memSize.width() < 0 || memSize.height() < 0) // sizeHint unimplemented?
38 memSize = minSize;
39 m_memory.setMinimumSize(memSize);
41 // create layout
42 m_layout.addWidget(&m_expression, 0);
43 m_layout.addWidget(&m_memory, 10);
44 m_layout.activate();
46 m_memory.setReadOnly(true);
47 #if QT_VERSION < 200
48 connect(&m_expression, SIGNAL(activated(const char*)),
49 this, SLOT(slotNewExpression(const char*)));
50 #else
51 connect(&m_expression, SIGNAL(activated(const QString&)),
52 this, SLOT(slotNewExpression(const QString&)));
53 #endif
55 // the popup menu
56 m_popup.insertItem("&Bytes", MDTbyte);
57 m_popup.insertItem("&Halfwords (2 Bytes)", MDThalfword);
58 m_popup.insertItem("&Words (4 Bytes)", MDTword);
59 m_popup.insertItem("&Giantwords (8 Bytes)", MDTgiantword);
60 m_popup.insertSeparator();
61 m_popup.insertItem("He&xadecimal", MDThex);
62 m_popup.insertItem("Signed &decimal", MDTsigned);
63 m_popup.insertItem("&Unsigned decimal", MDTunsigned);
64 m_popup.insertItem("&Octal", MDToctal);
65 m_popup.insertItem("Bi&nary", MDTbinary);
66 m_popup.insertItem("&Addresses", MDTaddress);
67 m_popup.insertItem("&Character", MDTchar);
68 m_popup.insertItem("&Floatingpoint", MDTfloat);
69 m_popup.insertItem("&Strings", MDTstring);
70 m_popup.insertItem("&Instructions", MDTinsn);
71 connect(&m_popup, SIGNAL(activated(int)), this, SLOT(slotTypeChange(int)));
73 m_expression.installEventFilter(this);
74 m_memory.installEventFilter(this);
76 m_formatCache.setAutoDelete(true);
79 MemoryWindow::~MemoryWindow()
83 void MemoryWindow::paletteChange(const QPalette& oldPal)
85 // font may have changed
86 #if QT_VERSION < 200
87 m_memory.setFont(kapp->fixedFont);
88 #else
89 m_memory.setFont(KGlobalSettings::fixedFont());
90 #endif
91 QWidget::paletteChange(oldPal);
94 void MemoryWindow::mousePressEvent(QMouseEvent* ev)
96 handlePopup(ev);
99 #if QT_VERSION < 200
100 # define MOUSEPRESS Event_MouseButtonPress
101 #else
102 # define MOUSEPRESS QEvent::MouseButtonPress
103 #endif
105 bool MemoryWindow::eventFilter(QObject* o, QEvent* ev)
107 if (ev->type() == MOUSEPRESS) {
108 handlePopup(static_cast<QMouseEvent*>(ev));
109 return true;
111 return false;
114 void MemoryWindow::handlePopup(QMouseEvent* ev)
116 if (ev->button() == RightButton)
118 // show popup menu
119 if (m_popup.isVisible())
121 m_popup.hide();
123 else
125 m_popup.popup(mapToGlobal(ev->pos()));
127 return;
131 // this slot is only needed for Qt 1.44
132 void MemoryWindow::slotNewExpression(const char* newText)
134 slotNewExpression(QString(newText));
137 void MemoryWindow::slotNewExpression(const QString& newText)
139 QString text = newText.simplifyWhiteSpace();
141 // see if the string is in the list
142 // (note: must count downwards because of removeItem!)
143 for (int i = m_expression.count()-1; i >= 0; i--)
145 if (m_expression.text(i) == text) {
146 // yes it is!
147 // look up the format that was used last time for this expr
148 unsigned* pFormat = m_formatCache[text];
149 if (pFormat != 0) {
150 m_format = *pFormat;
151 m_debugger->setMemoryFormat(m_format);
153 // remove this text, will be inserted at the top
154 m_expression.removeItem(i);
157 m_expression.insertItem(text, 0);
159 if (text.isEmpty()) {
160 // if format was not in the cache, insert it
161 if (m_formatCache[text] == 0) {
162 m_formatCache.insert(text, new unsigned(m_format));
167 displayNewExpression(text);
170 void MemoryWindow::displayNewExpression(const QString& expr)
172 m_debugger->setMemoryExpression(expr);
173 m_expression.setEditText(expr);
175 // clear memory dump if no dump wanted
176 if (expr.isEmpty()) {
177 m_memory.setText(QString());
181 void MemoryWindow::slotTypeChange(int id)
183 // compute new type
184 if (id & MDTsizemask)
185 m_format = (m_format & ~MDTsizemask) | id;
186 if (id & MDTformatmask)
187 m_format = (m_format & ~MDTformatmask) | id;
188 m_debugger->setMemoryFormat(m_format);
190 // change the format in the cache
191 QString expr = m_expression.currentText();
192 expr = expr.simplifyWhiteSpace();
193 unsigned* pFormat = m_formatCache[expr];
194 if (pFormat != 0)
195 *pFormat = m_format;
197 // force redisplay
198 displayNewExpression(expr);
201 void MemoryWindow::slotNewMemoryDump(const QString& dump)
203 m_memory.setText(dump);
206 static const char MemoryGroup[] = "Memory";
207 static const char NumExprs[] = "NumExprs";
208 static const char ExpressionFmt[] = "Expression%d";
209 static const char FormatFmt[] = "Format%d";
211 void MemoryWindow::saveProgramSpecific(KSimpleConfig* config)
213 KConfigGroupSaver s(config, MemoryGroup);
215 int numEntries = m_expression.count();
216 config->writeEntry(NumExprs, numEntries);
217 QString exprEntry;
218 QString fmtEntry;
219 for (int i = 0; i < numEntries;) {
220 QString text = m_expression.text(i);
221 i++; /* entries are counted 1-based */
222 exprEntry.sprintf(ExpressionFmt, i);
223 fmtEntry.sprintf(FormatFmt, i);
224 config->writeEntry(exprEntry, text);
225 unsigned* pFormat = m_formatCache[text];
226 unsigned fmt = pFormat != 0 ? *pFormat : MDTword | MDThex;
227 config->writeEntry(fmtEntry, fmt);
231 void MemoryWindow::restoreProgramSpecific(KSimpleConfig* config)
233 KConfigGroupSaver s(config, MemoryGroup);
235 int numEntries = config->readNumEntry(NumExprs, 0);
236 m_expression.clear();
238 QString exprEntry;
239 QString fmtEntry;
240 // entries are counted 1-based
241 for (int i = 1; i <= numEntries; i++) {
242 exprEntry.sprintf(ExpressionFmt, i);
243 fmtEntry.sprintf(FormatFmt, i);
244 QString expr = config->readEntry(exprEntry);
245 unsigned fmt = config->readNumEntry(fmtEntry, MDTword | MDThex);
246 m_expression.insertItem(expr);
247 m_formatCache.replace(expr, new unsigned(fmt & (MDTsizemask | MDTformatmask)));
250 // initialize with top expression
251 if (numEntries > 0) {
252 m_expression.setCurrentItem(0);
253 QString expr = m_expression.text(0);
254 m_format = *m_formatCache[expr];
255 m_debugger->setMemoryFormat(m_format);
256 displayNewExpression(expr);
261 #include "memwindow.moc"