3 // Copyright by Judin Max, Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
8 #include <kglobalsettings.h>
9 #include <klocale.h> /* i18n */
10 #include <kiconloader.h>
11 #include <qfontdialog.h>
12 #include <qmessagebox.h>
14 #include <kapp.h> /* i18n */
18 #include <stdlib.h> /* strtoul */
20 #include "dbgdriver.h"
23 class RegisterViewItem
: public QListViewItem
26 RegisterViewItem(RegisterView
* parent
, QListViewItem
* insertAfter
,
27 QString reg
, QString raw
, QString cooked
);
30 void setValue(QString raw
, QString cooked
);
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
),
49 setValue(raw
, cooked
);
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
)
70 return h
- ('A' - 10);
74 return h
- ('a' - 10);
78 #define DIGIT(c) hexCharToDigit(c)
80 #define DIGIT(c) hexCharToDigit(c.latin1())
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"
91 for (unsigned i
= 2; i
< hex
.length(); i
++) {
92 int idx
= DIGIT(hex
[i
]);
94 // not a hex digit; no conversion
97 const char* bindigits
= digits
[idx
];
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;
105 case 6: case 7: result
.remove(0, 1); break;
110 static QString
toOctal(QString hex
)
115 for (int i
= hex
.length()-1; i
>= 2; i
--) {
116 int idx
= DIGIT(hex
[i
]);
120 result
.insert(0, (v
& 7) + '0');
124 // an extra digit this round
125 result
.insert(0, v
+ '0');
130 result
.insert(0, v
+ '0');
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" */
144 #if QT_VERSION >= 200
145 const char* start
= hex
.latin1();
147 const char* start
= hex
;
150 unsigned long val
= strtoul(start
, &end
, 0);
154 return QString().setNum(val
);
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;
182 void RegisterViewItem::paintCell(QPainter
* p
, const QColorGroup
& cg
,
183 int column
, int width
, int alignment
)
186 #if QT_VERSION >= 200
187 QColorGroup newcg
= cg
;
188 newcg
.setColor(QColorGroup::Text
, red
);
190 QColorGroup
newcg(cg
.foreground(), cg
.background(),
191 cg
.light(), cg
.dark(), cg
.mid(),
194 QListViewItem::paintCell(p
, newcg
, column
, width
, alignment
);
196 QListViewItem::paintCell(p
, cg
, column
, width
, alignment
);
201 RegisterView::RegisterView(QWidget
* parent
, const char* name
) :
202 QListView(parent
, name
),
209 addColumn(i18n("Register"));
210 addColumn(i18n("Value"));
211 addColumn(i18n("Decoded value"));
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"));
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)));
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
262 for (QListViewItem
* i
= firstChild(); i
; i
= i
->nextSibling()) {
263 RegisterViewItem
* it
= static_cast<RegisterViewItem
*>(i
);
264 if (it
->m_reg
.regName
== reg
->regName
) {
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
);
275 * If there was a change last time, but not now, we
276 * must revert the color.
279 it
->m_changes
= false;
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);
294 for (QListViewItem
* i
= firstChild(); i
; i
= i
->nextSibling() ){
295 RegisterViewItem
* it
= static_cast<RegisterViewItem
*>(i
);
297 deletedItem
.append(it
);
304 setUpdatesEnabled(true);
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
));
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
])
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"