1
0
Fork 0
forked from len0rd/rockbox

qeditor: many enhancement

Qeditor has been improved in many ways:
- it can now dump all registers, just like the lua DUMPER.dump_all() command
- several crash were fixed
- when connected to a hwstub command, one can correctly edit individual fields
- the code was simplified in several places

Change-Id: I092b99ce3a12ff6417552de61d62c65f706bcff0
This commit is contained in:
Amaury Pouly 2014-05-11 19:51:55 +02:00
parent 4c1eafc208
commit 7b590a9536
8 changed files with 261 additions and 40 deletions

View file

@ -320,6 +320,47 @@ void SocFieldEditor::setField(uint field)
setText(QString("0x%1").arg(field, digits, 16, QChar('0'))); setText(QString("0x%1").arg(field, digits, 16, QChar('0')));
} }
/**
* SocFieldCachedItemDelegate
*/
QString SocFieldCachedItemDelegate::displayText(const QVariant& value, const QLocale& locale) const
{
// FIXME see QTBUG-30392
if(value.type() == QVariant::UserType && value.userType() == qMetaTypeId< SocFieldCachedValue >())
{
const SocFieldCachedValue& v = value.value< SocFieldCachedValue >();
int bitcount = v.field().last_bit - v.field().first_bit;
return QString("0x%1").arg(v.value(), (bitcount + 3) / 4, 16, QChar('0'));
}
else
return QStyledItemDelegate::displayText(value, locale);
}
/**
* SocFieldCachedEditor
*/
SocFieldCachedEditor::SocFieldCachedEditor(QWidget *parent)
:SocFieldEditor(soc_reg_field_t(), parent)
{
}
SocFieldCachedEditor::~SocFieldCachedEditor()
{
}
SocFieldCachedValue SocFieldCachedEditor::value() const
{
return SocFieldCachedValue(m_value.field(), field());
}
void SocFieldCachedEditor::setValue(SocFieldCachedValue val)
{
m_value = val;
SetRegField(m_value.field());
setField(m_value.value());
}
/** /**
* SocFieldEditorCreator * SocFieldEditorCreator
*/ */
@ -333,6 +374,19 @@ QByteArray SocFieldEditorCreator::valuePropertyName() const
return QByteArray("field"); return QByteArray("field");
} }
/**
* SocFieldCachedEditorCreator
*/
QWidget *SocFieldCachedEditorCreator::createWidget(QWidget *parent) const
{
return new SocFieldCachedEditor(parent);
}
QByteArray SocFieldCachedEditorCreator::valuePropertyName() const
{
return QByteArray("value");
}
/** /**
* RegSexyDisplay * RegSexyDisplay
*/ */

View file

@ -106,6 +106,7 @@ public:
uint field() const; uint field() const;
void setField(uint field); void setField(uint field);
void SetRegField(const soc_reg_field_t& field) { m_reg_field = field; }
protected: protected:
SocFieldValidator *m_validator; SocFieldValidator *m_validator;
@ -126,6 +127,55 @@ protected:
soc_reg_field_t m_field; soc_reg_field_t m_field;
}; };
class SocFieldCachedValue
{
public:
SocFieldCachedValue():m_value(0) {}
SocFieldCachedValue(const soc_reg_field_t& field, uint value)
:m_field(field), m_value(value) {}
virtual ~SocFieldCachedValue() {}
const soc_reg_field_t& field() const { return m_field; }
uint value() const { return m_value; }
protected:
soc_reg_field_t m_field;
uint m_value;
};
Q_DECLARE_METATYPE(SocFieldCachedValue)
class SocFieldCachedItemDelegate : public QStyledItemDelegate
{
public:
SocFieldCachedItemDelegate(QObject *parent = 0):QStyledItemDelegate(parent) {}
virtual QString displayText(const QVariant& value, const QLocale& locale) const;
};
class SocFieldCachedEditor : public SocFieldEditor
{
Q_OBJECT
Q_PROPERTY(SocFieldCachedValue value READ value WRITE setValue USER true)
public:
SocFieldCachedEditor(QWidget *parent = 0);
virtual ~SocFieldCachedEditor();
SocFieldCachedValue value() const;
void setValue(SocFieldCachedValue field);
protected:
SocFieldCachedValue m_value;
};
class SocFieldCachedEditorCreator : public QItemEditorCreatorBase
{
public:
SocFieldCachedEditorCreator() {}
virtual QWidget *createWidget(QWidget *parent) const;
virtual QByteArray valuePropertyName() const;
protected:
};
class RegSexyDisplay : public QWidget class RegSexyDisplay : public QWidget
{ {
Q_OBJECT Q_OBJECT

View file

@ -90,9 +90,10 @@ IoBackend *Backend::CreateHWStubIoBackend(HWStubDevice *dev)
* FileIoBackend * FileIoBackend
*/ */
FileIoBackend::FileIoBackend(const QString& filename) FileIoBackend::FileIoBackend(const QString& filename, const QString& soc_name)
{ {
m_filename = filename; m_filename = filename;
m_soc = soc_name;
Reload(); Reload();
} }
@ -163,7 +164,7 @@ bool FileIoBackend::Commit()
while(it.hasNext()) while(it.hasNext())
{ {
it.next(); it.next();
out << it.key() << " = " << it.value() << "\n"; out << it.key() << " = " << hex << showbase << it.value() << "\n";
} }
out.flush(); out.flush();
return file.flush(); return file.flush();
@ -174,6 +175,16 @@ bool FileIoBackend::Commit()
* HWStubDevice * HWStubDevice
*/ */
HWStubDevice::HWStubDevice(struct libusb_device *dev) HWStubDevice::HWStubDevice(struct libusb_device *dev)
{
Init(dev);
}
HWStubDevice::HWStubDevice(const HWStubDevice *dev)
{
Init(dev->m_dev);
}
void HWStubDevice::Init(struct libusb_device *dev)
{ {
libusb_ref_device(dev); libusb_ref_device(dev);
m_dev = dev; m_dev = dev;
@ -325,7 +336,7 @@ QString HWStubIoBackend::GetSocName()
HWStubIoBackend::~HWStubIoBackend() HWStubIoBackend::~HWStubIoBackend()
{ {
m_dev->Close(); delete m_dev;
} }
bool HWStubIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value) bool HWStubIoBackend::ReadRegister(soc_addr_t addr, soc_word_t& value)
@ -530,3 +541,31 @@ bool BackendHelper::ReadRegisterField(const QString& dev, const QString& reg,
v = (v & field_ref.GetField().bitmask()) >> field_ref.GetField().first_bit; v = (v & field_ref.GetField().bitmask()) >> field_ref.GetField().first_bit;
return true; return true;
} }
bool BackendHelper::DumpAllRegisters(const QString& filename)
{
FileIoBackend b(filename, QString::fromStdString(m_soc.GetSoc().name));
BackendHelper bh(&b, m_soc);
for(size_t i = 0; i < m_soc.GetSoc().dev.size(); i++)
{
const soc_dev_t& dev = m_soc.GetSoc().dev[i];
for(size_t j = 0; j < dev.addr.size(); j++)
{
QString devname = QString::fromStdString(dev.addr[j].name);
for(size_t k = 0; k < dev.reg.size(); k++)
{
const soc_reg_t& reg = dev.reg[k];
for(size_t l = 0; l < reg.addr.size(); l++)
{
QString regname = QString::fromStdString(reg.addr[l].name);
soc_word_t val;
if(!ReadRegister(devname, regname, val))
return false;
if(!bh.WriteRegister(devname, regname, val))
return false;
}
}
}
}
return b.Commit();
}

View file

@ -85,7 +85,7 @@ class FileIoBackend : public IoBackend
{ {
Q_OBJECT Q_OBJECT
public: public:
FileIoBackend(const QString& filename); FileIoBackend(const QString& filename, const QString& soc_name = "");
virtual bool SupportAccess(AccessType type) { return type == ByName; } virtual bool SupportAccess(AccessType type) { return type == ByName; }
virtual QString GetSocName(); virtual QString GetSocName();
@ -113,6 +113,7 @@ class HWStubDevice
{ {
public: public:
HWStubDevice(struct libusb_device *dev); HWStubDevice(struct libusb_device *dev);
HWStubDevice(const HWStubDevice *dev);
~HWStubDevice(); ~HWStubDevice();
bool IsValid(); bool IsValid();
bool Open(); bool Open();
@ -130,6 +131,7 @@ public:
protected: protected:
bool Probe(); bool Probe();
void Init(struct libusb_device *dev);
bool m_valid; bool m_valid;
struct libusb_device *m_dev; struct libusb_device *m_dev;
@ -146,6 +148,7 @@ class HWStubIoBackend : public IoBackend
{ {
Q_OBJECT Q_OBJECT
public: public:
// NOTE: HWStubIoBackend takes ownership of the device and will delete it
HWStubIoBackend(HWStubDevice *dev); HWStubIoBackend(HWStubDevice *dev);
virtual ~HWStubIoBackend(); virtual ~HWStubIoBackend();
@ -310,6 +313,8 @@ public:
bool GetRegRef(const SocDevRef& dev, const QString& reg, SocRegRef& ref); bool GetRegRef(const SocDevRef& dev, const QString& reg, SocRegRef& ref);
bool GetFieldRef(const SocRegRef& reg, const QString& field, SocFieldRef& ref); bool GetFieldRef(const SocRegRef& reg, const QString& field, SocFieldRef& ref);
bool GetRegisterAddress(const QString& dev, const QString& reg, soc_addr_t& addr); bool GetRegisterAddress(const QString& dev, const QString& reg, soc_addr_t& addr);
bool DumpAllRegisters(const QString& filename);
private: private:
IoBackend *m_io_backend; IoBackend *m_io_backend;
const SocRef& m_soc; const SocRef& m_soc;

View file

@ -136,7 +136,6 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
m_raw_val_edit->GetLineEdit()->setValidator(new SocFieldValidator(m_raw_val_edit)); m_raw_val_edit->GetLineEdit()->setValidator(new SocFieldValidator(m_raw_val_edit));
m_raw_val_edit->EnableSCT(!!(reg.flags & REG_HAS_SCT)); m_raw_val_edit->EnableSCT(!!(reg.flags & REG_HAS_SCT));
m_raw_val_edit->GetLineEdit()->setFont(m_reg_font); m_raw_val_edit->GetLineEdit()->setFont(m_reg_font);
connect(m_raw_val_edit->GetLineEdit(), SIGNAL(returnPressed()), this, SLOT(OnRawRegValueReturnPressed()));
QHBoxLayout *raw_val_layout = new QHBoxLayout; QHBoxLayout *raw_val_layout = new QHBoxLayout;
raw_val_layout->addStretch(); raw_val_layout->addStretch();
raw_val_layout->addWidget(m_raw_val_name); raw_val_layout->addWidget(m_raw_val_name);
@ -157,28 +156,39 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
QTableWidgetItem *item = new QTableWidgetItem(bits_str); QTableWidgetItem *item = new QTableWidgetItem(bits_str);
item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_value_table->setItem(row, 0, item); m_value_table->setItem(row, FieldBitsColumn, item);
item = new QTableWidgetItem(QString(field.name.c_str())); item = new QTableWidgetItem(QString(field.name.c_str()));
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_value_table->setItem(row, 1, item); m_value_table->setItem(row, FieldNameColumn, item);
item = new QTableWidgetItem();
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
item->setData(Qt::DisplayRole, QVariant::fromValue(SocFieldCachedValue()));
item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
m_value_table->setItem(row, FieldValueColumn, item);
item = new QTableWidgetItem("");
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
m_value_table->setItem(row, FieldMeaningColumn, item);
item = new QTableWidgetItem(QString(field.desc.c_str())); item = new QTableWidgetItem(QString(field.desc.c_str()));
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_value_table->setItem(row, 4, item); m_value_table->setItem(row, FieldDescColumn, item);
} }
m_value_table->setHorizontalHeaderItem(0, new QTableWidgetItem("Bits")); m_value_table->setHorizontalHeaderItem(FieldBitsColumn, new QTableWidgetItem("Bits"));
m_value_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name")); m_value_table->setHorizontalHeaderItem(FieldNameColumn, new QTableWidgetItem("Name"));
m_value_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Value")); m_value_table->setHorizontalHeaderItem(FieldValueColumn, new QTableWidgetItem("Value"));
m_value_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Meaning")); m_value_table->setHorizontalHeaderItem(FieldMeaningColumn, new QTableWidgetItem("Meaning"));
m_value_table->setHorizontalHeaderItem(4, new QTableWidgetItem("Description")); m_value_table->setHorizontalHeaderItem(FieldDescColumn, new QTableWidgetItem("Description"));
m_value_table->verticalHeader()->setVisible(false); m_value_table->verticalHeader()->setVisible(false);
m_value_table->resizeColumnsToContents(); m_value_table->resizeColumnsToContents();
m_value_table->horizontalHeader()->setStretchLastSection(true); m_value_table->horizontalHeader()->setStretchLastSection(true);
m_value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_table_delegate = new QStyledItemDelegate(this); SocFieldCachedItemDelegate *m_table_delegate = new SocFieldCachedItemDelegate(this);
m_table_edit_factory = new QItemEditorFactory(); m_table_edit_factory = new QItemEditorFactory();
m_regedit_creator = new RegItemEditorCreator(); SocFieldCachedEditorCreator *m_table_edit_creator = new SocFieldCachedEditorCreator();
m_table_edit_factory->registerEditor(QVariant::String, m_regedit_creator); // FIXME see QTBUG-30392
m_table_edit_factory->registerEditor((QVariant::Type)qMetaTypeId< SocFieldCachedValue >(),
m_table_edit_creator);
m_table_delegate->setItemEditorFactory(m_table_edit_factory); m_table_delegate->setItemEditorFactory(m_table_edit_factory);
m_value_table->setItemDelegate(m_table_delegate); m_value_table->setItemDelegate(m_table_delegate);
@ -209,8 +219,12 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
setLayout(layout); setLayout(layout);
AllowWrite(false); AllowWrite(false);
m_ignore_cell_change = false;
// load data // load data
Reload(); Reload();
connect(m_raw_val_edit->GetLineEdit(), SIGNAL(returnPressed()), this, SLOT(OnRawRegValueReturnPressed()));
connect(m_value_table, SIGNAL(cellChanged(int, int)), this, SLOT(OnRegFieldValueChanged(int, int)));
} }
RegDisplayPanel::~RegDisplayPanel() RegDisplayPanel::~RegDisplayPanel()
@ -239,11 +253,12 @@ void RegDisplayPanel::Reload()
m_raw_val_edit->hide(); m_raw_val_edit->hide();
} }
int row = 0; m_ignore_cell_change = true;
foreach(const soc_reg_field_t& field, reg.field) for(size_t row = 0; row < reg.field.size(); row++)
{ {
QTableWidgetItem *item = new QTableWidgetItem(); const soc_reg_field_t& field = reg.field[row];
QTableWidgetItem *desc_item = new QTableWidgetItem(); QTableWidgetItem *item = m_value_table->item(row, FieldValueColumn);
QTableWidgetItem *desc_item = m_value_table->item(row, FieldMeaningColumn);
if(has_value) if(has_value)
{ {
soc_word_t v = (value & field.bitmask()) >> field.first_bit; soc_word_t v = (value & field.bitmask()) >> field.first_bit;
@ -251,25 +266,20 @@ void RegDisplayPanel::Reload()
foreach(const soc_reg_field_value_t& rval, field.value) foreach(const soc_reg_field_value_t& rval, field.value)
if(v == rval.value) if(v == rval.value)
value_name = rval.name.c_str(); value_name = rval.name.c_str();
const char *fmt = "%lu"; item->setData(Qt::DisplayRole, QVariant::fromValue(SocFieldCachedValue(field, v)));
// heuristic
if((field.last_bit - field.first_bit + 1) > 16)
fmt = "0x%lx";
item->setText(QString().sprintf(fmt, (unsigned long)v));
item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
if(value_name.size() != 0) if(value_name.size() != 0)
{
desc_item->setText(value_name); desc_item->setText(value_name);
desc_item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
}
} }
else
item->setData(Qt::DisplayRole, QVariant::fromValue(SocFieldCachedValue()));
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
desc_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); if(m_allow_write)
m_value_table->setItem(row, 2, item); item->setFlags(item->flags() | Qt::ItemIsEditable);
m_value_table->setItem(row, 3, desc_item);
row++;
} }
m_ignore_cell_change = false;
m_value_table->resizeColumnsToContents();
m_value_table->horizontalHeader()->setStretchLastSection(true);
} }
void RegDisplayPanel::AllowWrite(bool en) void RegDisplayPanel::AllowWrite(bool en)
@ -277,6 +287,7 @@ void RegDisplayPanel::AllowWrite(bool en)
m_allow_write = en; m_allow_write = en;
if(m_raw_val_edit) if(m_raw_val_edit)
m_raw_val_edit->SetReadOnly(m_io_backend->IsReadOnly() || !m_allow_write); m_raw_val_edit->SetReadOnly(m_io_backend->IsReadOnly() || !m_allow_write);
Reload();
} }
IoBackend::WriteMode RegDisplayPanel::EditModeToWriteMode(RegLineEdit::EditMode mode) IoBackend::WriteMode RegDisplayPanel::EditModeToWriteMode(RegLineEdit::EditMode mode)
@ -303,7 +314,23 @@ void RegDisplayPanel::OnRawRegValueReturnPressed()
BackendHelper helper(m_io_backend, m_reg); BackendHelper helper(m_io_backend, m_reg);
helper.WriteRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(), helper.WriteRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(),
val, mode); val, mode);
// FIXME: we should notify the UI to read value back because it has changed Reload();
}
void RegDisplayPanel::OnRegFieldValueChanged(int row, int col)
{
if(m_ignore_cell_change || col != FieldValueColumn)
return;
QTableWidgetItem *item = m_value_table->item(row, col);
SocFieldCachedValue val = item->data(Qt::DisplayRole).value< SocFieldCachedValue >();
BackendHelper helper(m_io_backend, m_reg);
soc_word_t regval;
if(!helper.ReadRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(), regval))
return;
regval = (regval & ~val.field().bitmask()) |
((val.value() << val.field().first_bit) & val.field().bitmask());
helper.WriteRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(),
regval, IoBackend::Write);
Reload(); Reload();
} }

View file

@ -55,6 +55,15 @@ public:
protected: protected:
IoBackend::WriteMode EditModeToWriteMode(RegLineEdit::EditMode mode); IoBackend::WriteMode EditModeToWriteMode(RegLineEdit::EditMode mode);
enum
{
FieldBitsColumn = 0,
FieldNameColumn = 1,
FieldValueColumn = 2,
FieldMeaningColumn = 3,
FieldDescColumn = 4,
};
IoBackend *m_io_backend; IoBackend *m_io_backend;
const SocRegRef& m_reg; const SocRegRef& m_reg;
bool m_allow_write; bool m_allow_write;
@ -69,9 +78,11 @@ protected:
QLabel *m_desc; QLabel *m_desc;
QWidget *m_viewport; QWidget *m_viewport;
QScrollArea *m_scroll; QScrollArea *m_scroll;
bool m_ignore_cell_change;
private slots: private slots:
void OnRawRegValueReturnPressed(); void OnRawRegValueReturnPressed();
void OnRegFieldValueChanged(int row, int col);
}; };
#endif /* REGDISPLAYPANEL_H */ #endif /* REGDISPLAYPANEL_H */

View file

@ -5,6 +5,7 @@
#include <QFileDialog> #include <QFileDialog>
#include <QDebug> #include <QDebug>
#include <QStyle> #include <QStyle>
#include <QMessageBox>
#include "backend.h" #include "backend.h"
#include "analyser.h" #include "analyser.h"
#include "regdisplaypanel.h" #include "regdisplaypanel.h"
@ -111,9 +112,11 @@ RegTab::RegTab(Backend *backend, QWidget *parent)
m_readonly_check = new QCheckBox("Read-only"); m_readonly_check = new QCheckBox("Read-only");
m_readonly_check->setCheckState(Qt::Checked); m_readonly_check->setCheckState(Qt::Checked);
m_data_soc_label = new QLabel; m_data_soc_label = new QLabel;
QPushButton *data_sel_reload = new QPushButton; m_dump = new QPushButton("Dump", this);
data_sel_reload->setIcon(QIcon::fromTheme("view-refresh")); m_dump->setIcon(QIcon::fromTheme("system-run"));
data_sel_reload->setToolTip("Reload data"); m_data_sel_reload = new QPushButton(this);
m_data_sel_reload->setIcon(QIcon::fromTheme("view-refresh"));
m_data_sel_reload->setToolTip("Reload data");
data_sel_layout->addWidget(m_data_selector); data_sel_layout->addWidget(m_data_selector);
data_sel_layout->addWidget(m_data_sel_edit, 1); data_sel_layout->addWidget(m_data_sel_edit, 1);
data_sel_layout->addStretch(0); data_sel_layout->addStretch(0);
@ -123,7 +126,8 @@ RegTab::RegTab(Backend *backend, QWidget *parent)
#endif #endif
data_sel_layout->addWidget(m_readonly_check); data_sel_layout->addWidget(m_readonly_check);
data_sel_layout->addWidget(m_data_soc_label); data_sel_layout->addWidget(m_data_soc_label);
data_sel_layout->addWidget(data_sel_reload); data_sel_layout->addWidget(m_dump);
data_sel_layout->addWidget(m_data_sel_reload);
data_sel_group->setLayout(data_sel_layout); data_sel_group->setLayout(data_sel_layout);
m_data_soc_label->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); m_data_soc_label->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
@ -153,6 +157,7 @@ RegTab::RegTab(Backend *backend, QWidget *parent)
this, SLOT(OnDevChanged(int))); this, SLOT(OnDevChanged(int)));
#endif #endif
connect(m_readonly_check, SIGNAL(clicked(bool)), this, SLOT(OnReadOnlyClicked(bool))); connect(m_readonly_check, SIGNAL(clicked(bool)), this, SLOT(OnReadOnlyClicked(bool)));
connect(m_dump, SIGNAL(clicked(bool)), this, SLOT(OnDumpRegs(bool)));
OnSocListChanged(); OnSocListChanged();
OnDataSelChanged(0); OnDataSelChanged(0);
@ -205,6 +210,8 @@ void RegTab::OnDataSelChanged(int index)
m_dev_selector->hide(); m_dev_selector->hide();
#endif #endif
m_readonly_check->show(); m_readonly_check->show();
m_data_sel_reload->show();
m_dump->hide();
QFileDialog *fd = new QFileDialog(m_data_selector); QFileDialog *fd = new QFileDialog(m_data_selector);
fd->setFilter("Textual files (*.txt);;All files (*)"); fd->setFilter("Textual files (*.txt);;All files (*)");
fd->setDirectory(Settings::Get()->value("loaddatadir", QDir::currentPath()).toString()); fd->setDirectory(Settings::Get()->value("loaddatadir", QDir::currentPath()).toString());
@ -226,6 +233,8 @@ void RegTab::OnDataSelChanged(int index)
m_data_sel_edit->hide(); m_data_sel_edit->hide();
m_readonly_check->show(); m_readonly_check->show();
m_dev_selector->show(); m_dev_selector->show();
m_data_sel_reload->hide();
m_dump->show();
OnDevListChanged(); OnDevListChanged();
} }
#endif #endif
@ -236,6 +245,8 @@ void RegTab::OnDataSelChanged(int index)
m_dev_selector->hide(); m_dev_selector->hide();
#endif #endif
m_readonly_check->hide(); m_readonly_check->hide();
m_data_sel_reload->hide();
m_dump->hide();
delete m_io_backend; delete m_io_backend;
m_io_backend = m_backend->CreateDummyIoBackend(); m_io_backend = m_backend->CreateDummyIoBackend();
@ -363,7 +374,10 @@ void RegTab::OnDevChanged(int index)
return; return;
HWStubDevice *dev = reinterpret_cast< HWStubDevice* >(m_dev_selector->itemData(index).value< void* >()); HWStubDevice *dev = reinterpret_cast< HWStubDevice* >(m_dev_selector->itemData(index).value< void* >());
delete m_io_backend; delete m_io_backend;
m_io_backend = m_backend->CreateHWStubIoBackend(dev); /* NOTE: make a copy of the HWStubDevice device because the one in the list
* might get destroyed when clearing the list while the backend is still
* active: this would result in a double free when the backend is also destroyed */
m_io_backend = m_backend->CreateHWStubIoBackend(new HWStubDevice(dev));
SetDataSocName(m_io_backend->GetSocName()); SetDataSocName(m_io_backend->GetSocName());
OnDataSocActivated(m_io_backend->GetSocName()); OnDataSocActivated(m_io_backend->GetSocName());
OnDataChanged(); OnDataChanged();
@ -435,3 +449,22 @@ void RegTab::OnReadOnlyClicked(bool checked)
m_right_content->AllowWrite(!checked); m_right_content->AllowWrite(!checked);
UpdateSocFilename(); UpdateSocFilename();
} }
void RegTab::OnDumpRegs(bool c)
{
Q_UNUSED(c);
QFileDialog *fd = new QFileDialog(this);
fd->setAcceptMode(QFileDialog::AcceptSave);
fd->setFilter("Textual files (*.txt);;All files (*)");
fd->setDirectory(Settings::Get()->value("loaddatadir", QDir::currentPath()).toString());
if(!fd->exec())
return;
QStringList filenames = fd->selectedFiles();
Settings::Get()->setValue("loaddatadir", fd->directory().absolutePath());
BackendHelper bh(m_io_backend, m_cur_soc);
if(!bh.DumpAllRegisters(filenames[0]))
{
QMessageBox::warning(this, "The register dump was not saved",
"There was an error when dumping the registers");
}
}

View file

@ -80,6 +80,7 @@ protected:
QCheckBox *m_readonly_check; QCheckBox *m_readonly_check;
QLabel *m_data_soc_label; QLabel *m_data_soc_label;
QPushButton *m_data_sel_reload; QPushButton *m_data_sel_reload;
QPushButton *m_dump;
QComboBox *m_data_selector; QComboBox *m_data_selector;
IoBackend *m_io_backend; IoBackend *m_io_backend;
QTabWidget *m_type_selector; QTabWidget *m_type_selector;
@ -102,6 +103,7 @@ private slots:
void OnAnalyserChanged(QListWidgetItem *current, QListWidgetItem *previous); void OnAnalyserChanged(QListWidgetItem *current, QListWidgetItem *previous);
void OnAnalyserClicked(QListWidgetItem *clicked); void OnAnalyserClicked(QListWidgetItem *clicked);
void OnReadOnlyClicked(bool); void OnReadOnlyClicked(bool);
void OnDumpRegs(bool);
}; };
#endif /* REGTAB_H */ #endif /* REGTAB_H */