You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
piklab/src/devices/gui/register_view.cpp

209 lines
7.2 KiB

/***************************************************************************
* 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, TDEListViewItem *parent)
: TDEListViewItem(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);
TDEListViewItem::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, TDEListViewItem *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, TQ_SIGNAL(lostFocus()), TQ_SLOT(updateText()));
connect(this, TQ_SIGNAL(returnPressed()), TQ_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())
{}