Removed Set Font menu entry in the popup menu.
[kdbg.git] / kdbg / regwnd.cpp
blobb56ae19139631549740fe9292c38332569ccc4b2
1 // $Id$
3 // Copyright by Judin Max, Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
6 #include <qheader.h>
7 #if QT_VERSION >= 200
8 #include <kglobalsettings.h>
9 #include <klocale.h> /* i18n */
10 #include <kiconloader.h>
11 #include <qfontdialog.h>
12 #include <qmessagebox.h>
13 #else
14 #include <kapp.h> /* i18n */
15 #endif
16 #include <qpopmenu.h>
17 #include <ctype.h>
18 #include <stdlib.h> /* strtoul */
19 #include "regwnd.h"
20 #include "dbgdriver.h"
23 class RegisterViewItem : public QListViewItem
25 public:
26 RegisterViewItem(RegisterView* parent, QListViewItem* insertAfter,
27 QString reg, QString raw, QString cooked);
28 ~RegisterViewItem();
30 void setValue(QString raw, QString cooked);
31 RegisterInfo m_reg;
32 bool m_changes;
33 bool m_found;
35 protected:
36 virtual void paintCell(QPainter*, const QColorGroup& cg,
37 int column, int width, int alignment);
42 RegisterViewItem::RegisterViewItem(RegisterView* parent, QListViewItem* insertAfter,
43 QString reg, QString raw, QString cooked) :
44 QListViewItem(parent, insertAfter),
45 m_changes(false),
46 m_found(true)
48 m_reg.regName = reg;
49 setValue(raw, cooked);
50 setText(0, reg);
53 RegisterViewItem::~RegisterViewItem()
58 * We must be careful when converting the hex value because
59 * it may exceed this computer's long values.
61 inline int hexCharToDigit(char h)
63 if (h < '0')
64 return -1;
65 if (h <= '9')
66 return h - '0';
67 if (h < 'A')
68 return -1;
69 if (h <= 'F')
70 return h - ('A' - 10);
71 if (h < 'a')
72 return -1;
73 if (h <= 'f')
74 return h - ('a' - 10);
75 return -1;
77 #if QT_VERSION < 200
78 #define DIGIT(c) hexCharToDigit(c)
79 #else
80 #define DIGIT(c) hexCharToDigit(c.latin1())
81 #endif
83 static QString toBinary(QString hex)
85 static const char digits[16][8] = {
86 "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
87 "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
89 QString result;
91 for (unsigned i = 2; i < hex.length(); i++) {
92 int idx = DIGIT(hex[i]);
93 if (idx < 0) {
94 // not a hex digit; no conversion
95 return hex;
97 const char* bindigits = digits[idx];
98 result += bindigits;
100 // remove leading zeros
101 switch (DIGIT(hex[2])) {
102 case 0: case 1: result.remove(0, 3); break;
103 case 2: case 3: result.remove(0, 2); break;
104 case 4: case 5:
105 case 6: case 7: result.remove(0, 1); break;
107 return result;
110 static QString toOctal(QString hex)
112 QString result;
113 int shift = 0;
114 unsigned v = 0;
115 for (int i = hex.length()-1; i >= 2; i--) {
116 int idx = DIGIT(hex[i]);
117 if (idx < 0)
118 return hex;
119 v += idx << shift;
120 result.insert(0, (v & 7) + '0');
121 v >>= 3;
122 shift++;
123 if (shift == 3) {
124 // an extra digit this round
125 result.insert(0, v + '0');
126 shift = v = 0;
129 if (v != 0) {
130 result.insert(0, v + '0');
132 return "0" + result;
135 static QString toDecimal(QString hex)
138 * We convert only numbers that are small enough for this computer's
139 * size of long integers.
141 if (hex.length() > sizeof(unsigned long)*2+2) /* count in leading "0x" */
142 return hex;
144 #if QT_VERSION >= 200
145 const char* start = hex.latin1();
146 #else
147 const char* start = hex;
148 #endif
149 char* end;
150 unsigned long val = strtoul(start, &end, 0);
151 if (start == end)
152 return hex;
153 else
154 return QString().setNum(val);
157 #undef DIGIT
159 void RegisterViewItem::setValue(QString raw, QString cooked)
161 m_reg.rawValue = raw;
162 m_reg.cookedValue = cooked;
165 * If the raw value is in hexadecimal notation, we allow to display it
166 * in different modes (in the second column). The cooked value is
167 * displayed in the third column.
169 if (raw.length() > 2 && raw[0] == '0' && raw[1] == 'x') {
170 switch (static_cast<RegisterView*>(listView())->m_mode) {
171 case 2: raw = toBinary(raw); break;
172 case 8: raw = toOctal(raw); break;
173 case 10: raw = toDecimal(raw); break;
174 default: /* no change */ break;
178 setText(1, raw);
179 setText(2, cooked);
182 void RegisterViewItem::paintCell(QPainter* p, const QColorGroup& cg,
183 int column, int width, int alignment)
185 if (m_changes) {
186 #if QT_VERSION >= 200
187 QColorGroup newcg = cg;
188 newcg.setColor(QColorGroup::Text, red);
189 #else
190 QColorGroup newcg(cg.foreground(), cg.background(),
191 cg.light(), cg.dark(), cg.mid(),
192 red, cg.base());
193 #endif
194 QListViewItem::paintCell(p, newcg, column, width, alignment);
195 } else {
196 QListViewItem::paintCell(p, cg, column, width, alignment);
201 RegisterView::RegisterView(QWidget* parent, const char* name) :
202 QListView(parent, name),
203 m_lastItem(0),
204 m_mode(16)
206 setSorting(-1);
208 #if QT_VERSION < 200
209 addColumn(i18n("Register"));
210 addColumn(i18n("Value"));
211 addColumn(i18n("Decoded value"));
212 #else
213 QPixmap iconRegs = BarIcon("regs.xpm");
214 QPixmap iconWatchcoded = BarIcon("watchcoded.xpm");
215 QPixmap iconWatch = BarIcon("watch.xpm");
217 addColumn(QIconSet(iconRegs), i18n("Register"));
218 addColumn(QIconSet(iconWatchcoded), i18n("Value"));
219 addColumn(QIconSet(iconWatch), i18n("Decoded value"));
220 #endif
222 setColumnAlignment(0,AlignLeft);
223 setColumnAlignment(1,AlignLeft);
224 setColumnAlignment(2,AlignLeft);
226 setAllColumnsShowFocus( true );
227 header()->setClickEnabled(false);
229 connect(this, SIGNAL(doubleClicked(QListViewItem*)),
230 SLOT(doubleClicked(QListViewItem*)));
231 connect(this, SIGNAL(rightButtonClicked(QListViewItem*,const QPoint&,int)),
232 SLOT(rightButtonClicked(QListViewItem*,const QPoint&,int)));
234 m_modemenu = new QPopupMenu;
235 m_modemenu->insertItem(i18n("&Binary"),0);
236 m_modemenu->insertItem(i18n("&Octal"),1);
237 m_modemenu->insertItem(i18n("&Decimal"),2);
238 m_modemenu->insertItem(i18n("He&xadecimal"),3);
239 connect(m_modemenu,SIGNAL(activated(int)),SLOT(slotModeChange(int)));
241 resize(200,300);
244 RegisterView::~RegisterView()
248 void RegisterView::updateRegisters(QList<RegisterInfo>& regs)
250 setUpdatesEnabled(false);
252 // mark all items as 'not found'
253 for (QListViewItem* i = firstChild(); i; i = i->nextSibling()) {
254 static_cast<RegisterViewItem*>(i)->m_found = false;
257 // parse register values
258 for (RegisterInfo* reg = regs.first(); reg != 0; reg = regs.next())
260 // check if this is a new register
261 bool found = false;
262 for (QListViewItem* i = firstChild(); i; i = i->nextSibling()) {
263 RegisterViewItem* it = static_cast<RegisterViewItem*>(i);
264 if (it->m_reg.regName == reg->regName) {
265 found = true;
266 it->m_found = true;
267 if (it->m_reg.rawValue != reg->rawValue ||
268 it->m_reg.cookedValue != reg->cookedValue)
270 it->m_changes = true;
271 it->setValue(reg->rawValue, reg->cookedValue);
272 repaintItem(it);
273 } else {
275 * If there was a change last time, but not now, we
276 * must revert the color.
278 if (it->m_changes) {
279 it->m_changes = false;
280 repaintItem(it);
285 if (!found)
286 m_lastItem = new RegisterViewItem(this, m_lastItem, reg->regName,
287 reg->rawValue, reg->cookedValue);
290 // remove all 'not found' items;
291 QList<QListViewItem> deletedItem;
292 deletedItem.setAutoDelete(true);
293 m_lastItem = 0;
294 for (QListViewItem* i = firstChild(); i; i = i->nextSibling() ){
295 RegisterViewItem* it = static_cast<RegisterViewItem*>(i);
296 if (!it->m_found) {
297 deletedItem.append(it);
298 } else {
299 m_lastItem = it;
302 deletedItem.clear();
304 setUpdatesEnabled(true);
305 triggerUpdate();
308 void RegisterView::doubleClicked( QListViewItem* item )
310 #if QT_VERSION >= 200
311 RegisterViewItem* it = static_cast<RegisterViewItem*>(item);
312 QMessageBox::information(this, "work in progress...",
313 QString("Prepare for change register value\nregister: %1 current value: %2").arg(it->m_reg.regName).arg(it->m_reg.rawValue));
314 #endif
317 void RegisterView::rightButtonClicked(QListViewItem* item, const QPoint& p, int c)
319 m_modemenu->setItemChecked(0, m_mode == 2);
320 m_modemenu->setItemChecked(1, m_mode == 8);
321 m_modemenu->setItemChecked(2, m_mode == 10);
322 m_modemenu->setItemChecked(3, m_mode == 16);
323 m_modemenu->popup(p);
326 void RegisterView::slotModeChange(int code)
328 static const int modes[] = { 2, 8, 10, 16 };
329 if (code < 0 || code >= 4 || m_mode == modes[code])
330 return;
332 m_mode = modes[code];
334 for (QListViewItem* i = firstChild(); i; i = i->nextSibling()) {
335 RegisterViewItem* it = static_cast<RegisterViewItem*>(i);
336 it->setValue(it->m_reg.rawValue, it->m_reg.cookedValue);
340 #include "regwnd.moc"