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.
12 #include <kconfigbase.h>
13 #include <kconfiggroup.h>
17 MemoryWindow::MemoryWindow(QWidget
* parent
) :
22 m_layout(QBoxLayout::TopToBottom
, this),
23 m_format(MDTword
| MDThex
)
25 m_expression
.setEditable(true);
26 QSize minSize
= m_expression
.sizeHint();
27 m_expression
.setMinimumSize(minSize
);
28 m_expression
.setInsertPolicy(QComboBox::NoInsert
);
29 m_expression
.setMaxCount(15);
31 m_memory
.setColumnCount(9);
32 m_memory
.setHeaderLabel(i18n("Address"));
33 for (int i
= 1; i
< 9; i
++) {
34 m_memory
.hideColumn(i
);
35 m_memory
.header()->setResizeMode(QHeaderView::ResizeToContents
);
36 m_memory
.headerItem()->setText(i
, QString());
38 m_memory
.header()->setStretchLastSection(false);
40 m_memory
.setSortingEnabled(false); /* don't sort */
41 m_memory
.setAllColumnsShowFocus(true);
42 m_memory
.setRootIsDecorated(false);
43 m_memory
.header()->setClickable(false);
44 m_memory
.setContextMenuPolicy(Qt::NoContextMenu
); // defer to parent
47 m_layout
.setSpacing(2);
48 m_layout
.addWidget(&m_expression
, 0);
49 m_layout
.addWidget(&m_memory
, 10);
52 connect(&m_expression
, SIGNAL(activated(const QString
&)),
53 this, SLOT(slotNewExpression(const QString
&)));
54 connect(m_expression
.lineEdit(), SIGNAL(returnPressed()),
55 this, SLOT(slotNewExpression()));
59 pAction
= m_popup
.addAction(i18n("B&ytes"));
60 pAction
->setData(MDTbyte
);
61 pAction
= m_popup
.addAction(i18n("Halfwords (&2 Bytes)"));
62 pAction
->setData(MDThalfword
);
63 pAction
= m_popup
.addAction(i18n("Words (&4 Bytes)"));
64 pAction
->setData(MDTword
);
65 pAction
= m_popup
.addAction(i18n("Giantwords (&8 Bytes)"));
66 pAction
->setData(MDTgiantword
);
67 m_popup
.addSeparator();
68 pAction
= m_popup
.addAction(i18n("He&xadecimal"));
69 pAction
->setData(MDThex
);
70 pAction
= m_popup
.addAction(i18n("Signed &decimal"));
71 pAction
->setData(MDTsigned
);
72 pAction
= m_popup
.addAction(i18n("&Unsigned decimal"));
73 pAction
->setData(MDTunsigned
);
74 pAction
= m_popup
.addAction(i18n("&Octal"));
75 pAction
->setData(MDToctal
);
76 pAction
= m_popup
.addAction(i18n("&Binary"));
77 pAction
->setData(MDTbinary
);
78 pAction
= m_popup
.addAction(i18n("&Addresses"));
79 pAction
->setData(MDTaddress
);
80 pAction
= m_popup
.addAction(i18n("&Character"));
81 pAction
->setData(MDTchar
);
82 pAction
= m_popup
.addAction(i18n("&Floatingpoint"));
83 pAction
->setData(MDTfloat
);
84 pAction
= m_popup
.addAction(i18n("&Strings"));
85 pAction
->setData(MDTstring
);
86 pAction
= m_popup
.addAction(i18n("&Instructions"));
87 pAction
->setData(MDTinsn
);
88 connect(&m_popup
, SIGNAL(triggered(QAction
*)), this, SLOT(slotTypeChange(QAction
*)));
91 MemoryWindow::~MemoryWindow()
95 void MemoryWindow::contextMenuEvent(QContextMenuEvent
* ev
)
97 m_popup
.popup(ev
->globalPos());
101 void MemoryWindow::slotNewExpression()
103 slotNewExpression(m_expression
.lineEdit()->text());
106 void MemoryWindow::slotNewExpression(const QString
& newText
)
108 QString text
= newText
.simplified();
110 // see if the string is in the list
111 // (note: must count downwards because of removeItem!)
112 for (int i
= m_expression
.count()-1; i
>= 0; i
--)
114 if (m_expression
.itemText(i
) == text
) {
116 // look up the format that was used last time for this expr
117 QMap
<QString
,unsigned>::iterator pFormat
= m_formatCache
.find(text
);
118 if (pFormat
!= m_formatCache
.end()) {
120 m_debugger
->setMemoryFormat(m_format
);
122 // remove this text, will be inserted at the top
123 m_expression
.removeItem(i
);
126 m_expression
.insertItem(0, text
);
128 if (!text
.isEmpty()) {
129 m_formatCache
[text
] = m_format
;
132 displayNewExpression(text
);
135 void MemoryWindow::displayNewExpression(const QString
& expr
)
137 m_debugger
->setMemoryExpression(expr
);
138 m_expression
.setEditText(expr
);
140 // clear memory dump if no dump wanted
141 if (expr
.isEmpty()) {
143 m_old_memory
.clear();
147 void MemoryWindow::slotTypeChange(QAction
* action
)
149 int id
= action
->data().toInt();
151 m_old_memory
.clear();
154 if (id
& MDTsizemask
)
155 m_format
= (m_format
& ~MDTsizemask
) | id
;
156 if (id
& MDTformatmask
)
157 m_format
= (m_format
& ~MDTformatmask
) | id
;
158 m_debugger
->setMemoryFormat(m_format
);
160 // change the format in the cache
161 QString expr
= m_expression
.currentText();
162 m_formatCache
[expr
.simplified()] = m_format
;
165 displayNewExpression(expr
);
168 void MemoryWindow::slotNewMemoryDump(const QString
& msg
, const std::list
<MemoryDump
>& memdump
)
171 if (!msg
.isEmpty()) {
172 new QTreeWidgetItem(&m_memory
, QStringList() << QString() << msg
);
176 std::list
<MemoryDump
>::const_iterator md
= memdump
.begin();
178 // show only needed columns
179 QStringList sl
= md
->dump
.split( "\t" );
180 for (int i
= m_memory
.columnCount()-1; i
> 0; i
--)
181 m_memory
.setColumnHidden(i
, i
> sl
.count());
183 QMap
<QString
,QString
> tmpMap
;
185 for (; md
!= memdump
.end(); ++md
)
187 QString addr
= md
->address
.asString() + " " + md
->address
.fnoffs
;
188 QStringList sl
= md
->dump
.split( "\t" );
191 tmpMap
[addr
] = md
->dump
;
193 QTreeWidgetItem
* line
=
194 new QTreeWidgetItem(&m_memory
, QStringList(addr
) << sl
);
197 QMap
<QString
,QString
>::Iterator pos
= m_old_memory
.find( addr
);
199 if( pos
!= m_old_memory
.end() )
200 tmplist
= pos
.value().split( "\t" );
202 for (int i
= 0; i
< sl
.count(); i
++)
205 i
< tmplist
.count() &&
207 line
->setForeground(i
+1, changed
? QBrush(QColor(Qt::red
)) : palette().text());
211 m_old_memory
.clear();
212 m_old_memory
= tmpMap
;
215 static const char MemoryGroup
[] = "Memory";
216 static const char NumExprs
[] = "NumExprs";
217 static const char ExpressionFmt
[] = "Expression%d";
218 static const char FormatFmt
[] = "Format%d";
219 static const char ColumnWidths
[] = "ColumnWidths";
221 void MemoryWindow::saveProgramSpecific(KConfigBase
* config
)
223 KConfigGroup g
= config
->group(MemoryGroup
);
225 int numEntries
= m_expression
.count();
226 g
.writeEntry(NumExprs
, numEntries
);
229 for (int i
= 0; i
< numEntries
;) {
230 QString text
= m_expression
.itemText(i
);
231 i
++; /* entries are counted 1-based */
232 exprEntry
.sprintf(ExpressionFmt
, i
);
233 fmtEntry
.sprintf(FormatFmt
, i
);
234 g
.writeEntry(exprEntry
, text
);
235 QMap
<QString
,unsigned>::iterator pFormat
= m_formatCache
.find(text
);
236 unsigned fmt
= pFormat
!= m_formatCache
.end() ? *pFormat
: MDTword
| MDThex
;
237 g
.writeEntry(fmtEntry
, fmt
);
242 for (int i
= 0; i
< 2; i
++) {
243 int w
= m_memory
.columnWidth(i
);
246 g
.writeEntry(ColumnWidths
, widths
);
249 void MemoryWindow::restoreProgramSpecific(KConfigBase
* config
)
251 KConfigGroup g
= config
->group(MemoryGroup
);
253 int numEntries
= g
.readEntry(NumExprs
, 0);
254 m_expression
.clear();
258 // entries are counted 1-based
259 for (int i
= 1; i
<= numEntries
; i
++) {
260 exprEntry
.sprintf(ExpressionFmt
, i
);
261 fmtEntry
.sprintf(FormatFmt
, i
);
262 QString expr
= g
.readEntry(exprEntry
, QString());
263 unsigned fmt
= g
.readEntry(fmtEntry
, MDTword
| MDThex
);
264 m_expression
.addItem(expr
);
265 m_formatCache
[expr
] = fmt
& (MDTsizemask
| MDTformatmask
);
268 // initialize with top expression
269 if (numEntries
> 0) {
270 m_expression
.setCurrentIndex(0);
271 QString expr
= m_expression
.itemText(0);
272 m_format
= m_formatCache
[expr
];
273 m_debugger
->setMemoryFormat(m_format
);
274 displayNewExpression(expr
);
278 QList
<int> widths
= g
.readEntry(ColumnWidths
, QList
<int>());
279 QList
<int>::iterator w
= widths
.begin();
280 for (int i
= 0; i
< 2 && w
!= widths
.end(); ++i
, ++w
) {
281 m_memory
.setColumnWidth(i
, *w
);
286 #include "memwindow.moc"