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.
13 #include <kconfigbase.h>
17 class MemoryViewItem
: public Q3ListViewItem
20 MemoryViewItem(Q3ListView
* parent
, Q3ListViewItem
* insertAfter
, QString raw
, QString cooked
)
21 : Q3ListViewItem(parent
, insertAfter
, raw
, cooked
) {}
23 void setChanged(uint pos
, bool b
) { m_changed
[pos
] = b
; }
26 virtual void paintCell(QPainter
* p
, const QColorGroup
& cg
,
27 int column
, int width
, int alignment
);
32 void MemoryViewItem::paintCell(QPainter
* p
, const QColorGroup
& cg
,
33 int column
, int width
, int alignment
)
35 if( column
> 0 && m_changed
[column
- 1] ) {
36 QColorGroup newcg
= cg
;
37 newcg
.setColor(QColorGroup::Text
, Qt::red
);
38 Q3ListViewItem::paintCell(p
, newcg
, column
, width
, alignment
);
40 Q3ListViewItem::paintCell(p
, cg
, column
, width
, alignment
);
45 MemoryWindow::MemoryWindow(QWidget
* parent
) :
48 m_expression(true, this, "expression"),
49 m_memory(this, "memory"),
51 m_format(MDTword
| MDThex
)
53 QSize minSize
= m_expression
.sizeHint();
54 m_expression
.setMinimumSize(minSize
);
55 m_expression
.setInsertionPolicy(QComboBox::NoInsertion
);
56 m_expression
.setMaxCount(15);
58 m_memory
.addColumn(i18n("Address"), 80);
60 m_memory
.setSorting(-1); /* don't sort */
61 m_memory
.setAllColumnsShowFocus(true);
62 m_memory
.header()->setClickEnabled(false);
65 m_layout
.addWidget(&m_expression
, 0);
66 m_layout
.addWidget(&m_memory
, 10);
69 connect(&m_expression
, SIGNAL(activated(const QString
&)),
70 this, SLOT(slotNewExpression(const QString
&)));
73 m_popup
.insertItem(i18n("B&ytes"), MDTbyte
);
74 m_popup
.insertItem(i18n("Halfwords (&2 Bytes)"), MDThalfword
);
75 m_popup
.insertItem(i18n("Words (&4 Bytes)"), MDTword
);
76 m_popup
.insertItem(i18n("Giantwords (&8 Bytes)"), MDTgiantword
);
77 m_popup
.insertSeparator();
78 m_popup
.insertItem(i18n("He&xadecimal"), MDThex
);
79 m_popup
.insertItem(i18n("Signed &decimal"), MDTsigned
);
80 m_popup
.insertItem(i18n("&Unsigned decimal"), MDTunsigned
);
81 m_popup
.insertItem(i18n("&Octal"), MDToctal
);
82 m_popup
.insertItem(i18n("&Binary"), MDTbinary
);
83 m_popup
.insertItem(i18n("&Addresses"), MDTaddress
);
84 m_popup
.insertItem(i18n("&Character"), MDTchar
);
85 m_popup
.insertItem(i18n("&Floatingpoint"), MDTfloat
);
86 m_popup
.insertItem(i18n("&Strings"), MDTstring
);
87 m_popup
.insertItem(i18n("&Instructions"), MDTinsn
);
88 connect(&m_popup
, SIGNAL(activated(int)), this, SLOT(slotTypeChange(int)));
91 * Handle right mouse button. Signal righteButtonClicked cannot be
92 * used, because it works only over items, not over the blank window.
94 m_memory
.viewport()->installEventFilter(this);
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() == Qt::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 QMap
<QString
,unsigned>::iterator pFormat
= m_formatCache
.find(text
);
139 if (pFormat
!= m_formatCache
.end()) {
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 m_formatCache
[text
] = m_format
;
153 displayNewExpression(text
);
156 void MemoryWindow::displayNewExpression(const QString
& expr
)
158 m_debugger
->setMemoryExpression(expr
);
159 m_expression
.setEditText(expr
);
161 // clear memory dump if no dump wanted
162 if (expr
.isEmpty()) {
164 m_old_memory
.clear();
168 void MemoryWindow::slotTypeChange(int id
)
170 m_old_memory
.clear();
173 if (id
& MDTsizemask
)
174 m_format
= (m_format
& ~MDTsizemask
) | id
;
175 if (id
& MDTformatmask
)
176 m_format
= (m_format
& ~MDTformatmask
) | id
;
177 m_debugger
->setMemoryFormat(m_format
);
179 // change the format in the cache
180 QString expr
= m_expression
.currentText();
181 m_formatCache
[expr
.simplifyWhiteSpace()] = m_format
;
184 displayNewExpression(expr
);
187 void MemoryWindow::slotNewMemoryDump(const QString
& msg
, const std::list
<MemoryDump
>& memdump
)
190 if (!msg
.isEmpty()) {
191 new Q3ListViewItem(&m_memory
, QString(), msg
);
195 MemoryViewItem
* after
= 0;
196 std::list
<MemoryDump
>::const_iterator md
= memdump
.begin();
198 // remove all columns, except the address column
199 for(int k
= m_memory
.columns() - 1; k
> 0; k
--)
200 m_memory
.removeColumn(k
);
202 //add the needed columns
203 QStringList sl
= QStringList::split( "\t", md
->dump
);
204 for (uint i
= 0; i
< sl
.count(); i
++)
205 m_memory
.addColumn("", -1);
207 QMap
<QString
,QString
> tmpMap
;
209 for (; md
!= memdump
.end(); ++md
)
211 QString addr
= md
->address
.asString() + " " + md
->address
.fnoffs
;
212 QStringList sl
= QStringList::split( "\t", md
->dump
);
215 tmpMap
[addr
] = md
->dump
;
217 after
= new MemoryViewItem(&m_memory
, after
, addr
, "");
220 QMap
<QString
,QString
>::Iterator pos
= m_old_memory
.find( addr
);
222 if( pos
!= m_old_memory
.end() )
223 tmplist
= QStringList::split( "\t", pos
.data() );
225 for (uint i
= 0; i
< sl
.count(); i
++)
227 after
->setText( i
+1, *sl
.at(i
) );
230 tmplist
.count() > 0 &&
231 *sl
.at(i
) != *tmplist
.at(i
);
232 after
->setChanged(i
, changed
);
236 m_old_memory
.clear();
237 m_old_memory
= tmpMap
;
240 static const char MemoryGroup
[] = "Memory";
241 static const char NumExprs
[] = "NumExprs";
242 static const char ExpressionFmt
[] = "Expression%d";
243 static const char FormatFmt
[] = "Format%d";
244 static const char ColumnWidths
[] = "ColumnWidths";
246 void MemoryWindow::saveProgramSpecific(KConfigBase
* config
)
248 KConfigGroupSaver
s(config
, MemoryGroup
);
250 int numEntries
= m_expression
.count();
251 config
->writeEntry(NumExprs
, numEntries
);
254 for (int i
= 0; i
< numEntries
;) {
255 QString text
= m_expression
.text(i
);
256 i
++; /* entries are counted 1-based */
257 exprEntry
.sprintf(ExpressionFmt
, i
);
258 fmtEntry
.sprintf(FormatFmt
, i
);
259 config
->writeEntry(exprEntry
, text
);
260 QMap
<QString
,unsigned>::iterator pFormat
= m_formatCache
.find(text
);
261 unsigned fmt
= pFormat
!= m_formatCache
.end() ? *pFormat
: MDTword
| MDThex
;
262 config
->writeEntry(fmtEntry
, fmt
);
268 for (int i
= 0; i
< 2; i
++) {
269 int w
= m_memory
.columnWidth(i
);
273 config
->writeEntry(ColumnWidths
, widths
);
276 void MemoryWindow::restoreProgramSpecific(KConfigBase
* config
)
278 KConfigGroupSaver
s(config
, MemoryGroup
);
280 int numEntries
= config
->readNumEntry(NumExprs
, 0);
281 m_expression
.clear();
285 // entries are counted 1-based
286 for (int i
= 1; i
<= numEntries
; i
++) {
287 exprEntry
.sprintf(ExpressionFmt
, i
);
288 fmtEntry
.sprintf(FormatFmt
, i
);
289 QString expr
= config
->readEntry(exprEntry
);
290 unsigned fmt
= config
->readNumEntry(fmtEntry
, MDTword
| MDThex
);
291 m_expression
.insertItem(expr
);
292 m_formatCache
[expr
] = fmt
& (MDTsizemask
| MDTformatmask
);
295 // initialize with top expression
296 if (numEntries
> 0) {
297 m_expression
.setCurrentItem(0);
298 QString expr
= m_expression
.text(0);
299 m_format
= m_formatCache
[expr
];
300 m_debugger
->setMemoryFormat(m_format
);
301 displayNewExpression(expr
);
306 int n
= config
->readListEntry(ColumnWidths
, widths
);
309 for (int i
= 0; i
< n
; i
++) {
310 QString wStr
= widths
.at(i
);
312 int w
= wStr
.toInt(&ok
);
314 m_memory
.setColumnWidth(i
, w
);
319 #include "memwindow.moc"