|
|
|
/***************************************************************************
|
|
|
|
* Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
|
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
***************************************************************************/
|
|
|
|
#include "register_view.h"
|
|
|
|
|
|
|
|
#include "libgui/main_global.h"
|
|
|
|
#include "libgui/gui_debug_manager.h"
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
Register::PortBitListViewItem::PortBitListViewItem(uint index, uint bit, KListViewItem *parent)
|
|
|
|
: KListViewItem(parent), _index(index), _bit(bit)
|
|
|
|
{
|
|
|
|
const Device::RegistersData *rdata = Main::deviceData()->registersData();
|
|
|
|
setText(1, rdata->portBitName(_index, _bit));
|
|
|
|
setSelectable(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Register::PortBitListViewItem::updateView()
|
|
|
|
{
|
|
|
|
const TQMap<uint, Device::PortBitData> &pdata = Register::list().portData(_index);
|
|
|
|
TQString text;
|
|
|
|
if ( pdata.isEmpty() ) text = "--";
|
|
|
|
else {
|
|
|
|
/*
|
|
|
|
switch (pdata[_bit].state) {
|
|
|
|
case Device::High: text = " 1"; break;
|
|
|
|
case Device::Low: text = " 0"; break;
|
|
|
|
case Device::WeakPullUp: text = "w1"; break;
|
|
|
|
case Device::WeakPullDown: text = "w0"; break;
|
|
|
|
case Device::HighImpedance: text = "HZ"; break;
|
|
|
|
case Device::Unknown: text = " "; break;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
if ( pdata[_bit].drivingState==Device::IoUnknown ) text = " ";
|
|
|
|
else text += (pdata[_bit].drivingState==Device::IoHigh ? "1" : "0");
|
|
|
|
text += (pdata[_bit].driving ? " > " : " < ");
|
|
|
|
if ( pdata[_bit].drivenState==Device::IoUnknown ) text += " ";
|
|
|
|
else text += (pdata[_bit].drivenState==Device::IoHigh ? "1" : "0");
|
|
|
|
}
|
|
|
|
setText(2, text);
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Register::PortBitListViewItem::paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int align)
|
|
|
|
{
|
|
|
|
TQColorGroup ncg = cg;
|
|
|
|
const TQMap<uint, Device::PortBitData> &data = Register::list().portData(_index);
|
|
|
|
const TQMap<uint, Device::PortBitData> &odata = Register::list().oldPortData(_index);
|
|
|
|
bool changed = ( !data.isEmpty() && data[_bit]!=odata[_bit] );
|
|
|
|
if ( column==2 && changed ) ncg.setColor(TQColorGroup::Text, red);
|
|
|
|
KListViewItem::paintCell(p, ncg, column, width, align);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Register::PortBitListViewItem::tooltip(int col) const
|
|
|
|
{
|
|
|
|
if ( col!=2 ) return TQString();
|
|
|
|
const TQMap<uint, Device::PortBitData> &pdata = Register::list().portData(_index);
|
|
|
|
if ( pdata.isEmpty() ) return TQString();
|
|
|
|
TQString s = text(1) + ": ";
|
|
|
|
if (pdata[_bit].driving) {
|
|
|
|
if ( pdata[_bit].drivingState!=Device::IoUnknown ) s += i18n("unknown state");
|
|
|
|
else s += (pdata[_bit].drivingState==Device::IoHigh ? i18n("driving high") : i18n("driving low"));
|
|
|
|
s += i18n(" (output)");
|
|
|
|
} else {
|
|
|
|
if ( pdata[_bit].drivenState==Device::IoUnknown ) s += i18n("unknown state");
|
|
|
|
else s += (pdata[_bit].drivenState==Device::IoHigh ? i18n("driven high") : i18n("driven low"));
|
|
|
|
s += i18n(" (input)");
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
Register::ListViewItem::ListViewItem(const TypeData &data, KListViewItem *parent)
|
|
|
|
: EditListViewItem(parent), _data(data), _base(NumberBase::Hex)
|
|
|
|
{
|
|
|
|
setSelectable(false);
|
|
|
|
const Device::RegistersData *rdata = Main::deviceData()->registersData();
|
|
|
|
if ( data.type()==Regular && rdata ) {
|
|
|
|
int i = rdata->portIndex(data.address());
|
|
|
|
if ( i!=-1 ) {
|
|
|
|
for (int k=Device::MAX_NB_PORT_BITS-1; k>=0; k--) {
|
|
|
|
if ( !rdata->hasPortBit(i, k) ) continue;
|
|
|
|
PortBitListViewItem *item = new PortBitListViewItem(i, k, this);
|
|
|
|
_items.append(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Register::ListViewItem::text() const
|
|
|
|
{
|
|
|
|
BitValue value = Register::list().value(_data);
|
|
|
|
uint nbChars = convertNbChars(_data.nbChars(), NumberBase::Hex, _base);
|
|
|
|
return (value.isInitialized() ? toLabel(_base, value, nbChars) : "--");
|
|
|
|
}
|
|
|
|
|
|
|
|
int Register::ListViewItem::compare(TQListViewItem *item, int, bool) const
|
|
|
|
{
|
|
|
|
const TypeData &data = static_cast<ListViewItem *>(item)->data();
|
|
|
|
int i1 = list().watched().findIndex(data);
|
|
|
|
Q_ASSERT( i1!=-1 );
|
|
|
|
int i2 = list().watched().findIndex(_data);
|
|
|
|
Q_ASSERT( i2!=-1 );
|
|
|
|
return ( i1-i2 );
|
|
|
|
}
|
|
|
|
|
|
|
|
void Register::ListViewItem::updateView()
|
|
|
|
{
|
|
|
|
if ( _data.type()!=Special ) setText(0, toHexLabel(_data.address(), nbCharsAddress()) + ":");
|
|
|
|
setText(1, label());
|
|
|
|
setText(2, text());
|
|
|
|
repaint();
|
|
|
|
for (uint i=0; i<_items.count(); i++) _items[i]->updateView();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Register::ListViewItem::setBase(NumberBase base)
|
|
|
|
{
|
|
|
|
_base = base;
|
|
|
|
updateView();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Register::ListViewItem::paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int align)
|
|
|
|
{
|
|
|
|
TQColorGroup ncg = cg;
|
|
|
|
BitValue value = Register::list().value(_data);
|
|
|
|
BitValue oldValue = Register::list().oldValue(_data);
|
|
|
|
if ( column==2 && value!=oldValue ) ncg.setColor(TQColorGroup::Text, red);
|
|
|
|
EditListViewItem::paintCell(p, ncg, column, width, align);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Register::ListViewItem::tooltip(int col) const
|
|
|
|
{
|
|
|
|
if ( col!=2 ) return TQString();
|
|
|
|
BitValue value = Register::list().value(_data);
|
|
|
|
if ( !value.isInitialized() ) return TQString();
|
|
|
|
BitValue v = value;
|
|
|
|
TQString s;
|
|
|
|
for (uint i=0; i<_data.nbChars(); i++) {
|
|
|
|
char c = v.nybble(i);
|
|
|
|
if ( isprint(c) ) s = c + s;
|
|
|
|
else s = "." + s;
|
|
|
|
}
|
|
|
|
return TQString("%1 - %2 - \"%3\"").arg(toHexLabel(value, _data.nbChars()))
|
|
|
|
.arg(toLabel(NumberBase::Bin, value, 4*_data.nbChars())).arg(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQWidget *Register::ListViewItem::editWidgetFactory(int col) const
|
|
|
|
{
|
|
|
|
if ( col!=2 || Main::programmerState()!=Programmer::Halted ) return 0;
|
|
|
|
return new NumberLineEdit(text(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Register::ListViewItem::editDone(int col, const TQWidget *edit)
|
|
|
|
{
|
|
|
|
if ( col!=2 ) return;
|
|
|
|
bool ok;
|
|
|
|
ulong value = static_cast<const NumberLineEdit *>(edit)->value(&ok);
|
|
|
|
if (ok) Debugger::manager->writeRegister(_data, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
Register::LineEdit::LineEdit(TQWidget *parent, const char *name)
|
|
|
|
: NumberLineEdit(parent, name), _base(NumberBase::Nb_Types)
|
|
|
|
{
|
|
|
|
connect(this, TQT_SIGNAL(lostFocus()), TQT_SLOT(updateText()));
|
|
|
|
connect(this, TQT_SIGNAL(returnPressed()), TQT_SLOT(returnPressedSlot()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Register::LineEdit::updateText()
|
|
|
|
{
|
|
|
|
setText(_value.isInitialized() ? toLabel(_base, _value, _nbChars) : "--");
|
|
|
|
uint w = 2*frameWidth() + maxLabelWidth(_base, _nbChars, font());
|
|
|
|
setFixedWidth(w+5);
|
|
|
|
setFixedHeight(minimumSizeHint().height());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Register::LineEdit::setValue(NumberBase base, BitValue value, uint nbChars)
|
|
|
|
{
|
|
|
|
_base = base;
|
|
|
|
_value = value;
|
|
|
|
_nbChars = nbChars;
|
|
|
|
updateText();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Register::LineEdit::returnPressedSlot()
|
|
|
|
{
|
|
|
|
bool ok;
|
|
|
|
uint v = fromAnyLabel(text(), &ok);
|
|
|
|
if (ok) _value = v;
|
|
|
|
updateText();
|
|
|
|
emit modified();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Register::LineEdit::keyPressEvent(TQKeyEvent *e)
|
|
|
|
{
|
|
|
|
if ( e->key()==Key_Escape ) clearFocus();
|
|
|
|
else NumberLineEdit::keyPressEvent(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
Register::View::View(TQWidget *parent, const char *name)
|
|
|
|
: TQFrame(parent, name), GenericView(list())
|
|
|
|
{}
|