rockbox/utils/regtools/qeditor/regedit.cpp

1416 lines
47 KiB
C++

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2014 by Amaury Pouly
*
* 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.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "regedit.h"
#include <QFileDialog>
#include <QDebug>
#include <QHeaderView>
#include <QMessageBox>
#include <QInputDialog>
/**
* EmptyEditPanel
*/
EmptyEditPanel::EmptyEditPanel(QWidget *parent)
:QWidget(parent)
{
}
/**
* SocEditPanel
*/
SocEditPanel::SocEditPanel(SocRef ref, QWidget *parent)
:QWidget(parent), m_ref(ref)
{
m_name_group = new QGroupBox("Name", this);
m_name_edit = new QLineEdit(this);
m_name_edit->setText(QString::fromStdString(ref.GetSoc().name));
QVBoxLayout *name_group_layout = new QVBoxLayout;
name_group_layout->addWidget(m_name_edit);
m_name_group->setLayout(name_group_layout);
m_desc_group = new QGroupBox("Description", this);
QHBoxLayout *group_layout = new QHBoxLayout;
m_desc_edit = new MyTextEditor(this);
m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetSoc().desc));
group_layout->addWidget(m_desc_edit);
m_desc_group->setLayout(group_layout);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(m_name_group);
layout->addWidget(m_desc_group);
layout->addStretch(1);
connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&)));
connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnTextEdited()));
setLayout(layout);
}
void SocEditPanel::OnNameEdited(const QString& text)
{
m_ref.GetSoc().name = text.toStdString();
OnModified(m_name_edit->isModified());
}
void SocEditPanel::OnTextEdited()
{
m_ref.GetSoc().desc = m_desc_edit->GetTextHtml().toStdString();
OnModified(m_desc_edit->IsModified());
}
/**
* DevEditPanel
*/
DevEditPanel::DevEditPanel(SocDevRef ref, QWidget *parent)
:QWidget(parent), m_ref(ref)
{
m_name_group = new QGroupBox("Name", this);
m_name_edit = new QLineEdit(this);
m_name_edit->setText(QString::fromStdString(ref.GetDev().name));
QVBoxLayout *name_group_layout = new QVBoxLayout;
name_group_layout->addWidget(m_name_edit);
m_name_group->setLayout(name_group_layout);
m_long_name_group = new QGroupBox("Long Name", this);
m_long_name_edit = new QLineEdit(this);
m_long_name_edit->setText(QString::fromStdString(ref.GetDev().long_name));
QVBoxLayout *long_name_group_layout = new QVBoxLayout;
long_name_group_layout->addWidget(m_long_name_edit);
m_long_name_group->setLayout(long_name_group_layout);
m_version_group = new QGroupBox("Version", this);
m_version_edit = new QLineEdit(this);
m_version_edit->setText(QString::fromStdString(ref.GetDev().version));
QVBoxLayout *version_group_layout = new QVBoxLayout;
version_group_layout->addWidget(m_version_edit);
m_version_group->setLayout(version_group_layout);
QVBoxLayout *name_ver_layout = new QVBoxLayout;
name_ver_layout->addWidget(m_name_group);
name_ver_layout->addWidget(m_long_name_group);
name_ver_layout->addWidget(m_version_group);
name_ver_layout->addStretch();
m_instances_table = new QTableWidget(this);
m_instances_table->setRowCount(ref.GetDev().addr.size() + 1);
m_instances_table->setColumnCount(3);
for(size_t row = 0; row < ref.GetDev().addr.size(); row++)
FillRow(row, ref.GetDev().addr[row]);
CreateNewRow(ref.GetDev().addr.size());
m_instances_table->setHorizontalHeaderItem(0, new QTableWidgetItem(""));
m_instances_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name"));
m_instances_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Address"));
m_instances_table->verticalHeader()->setVisible(false);
m_instances_table->resizeColumnsToContents();
m_instances_table->horizontalHeader()->setStretchLastSection(true);
m_instances_table->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
m_instances_group = new QGroupBox("Instances", this);
QHBoxLayout *instances_group_layout = new QHBoxLayout;
instances_group_layout->addWidget(m_instances_table);
m_instances_group->setLayout(instances_group_layout);
QHBoxLayout *top_layout = new QHBoxLayout;
top_layout->addWidget(m_instances_group);
top_layout->addLayout(name_ver_layout);
top_layout->addStretch();
m_desc_group = new QGroupBox("Description", this);
QHBoxLayout *group_layout = new QHBoxLayout;
m_desc_edit = new MyTextEditor(this);
m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetDev().desc));
group_layout->addWidget(m_desc_edit);
m_desc_group->setLayout(group_layout);
QVBoxLayout *layout = new QVBoxLayout;
layout->addLayout(top_layout, 0);
layout->addWidget(m_desc_group, 1);
setLayout(layout);
SocFieldItemDelegate *m_table_delegate = new SocFieldItemDelegate(this);
QItemEditorFactory *m_table_edit_factory = new QItemEditorFactory();
SocFieldEditorCreator *m_table_edit_creator = new SocFieldEditorCreator();
m_table_edit_factory->registerEditor(QVariant::UInt, m_table_edit_creator);
m_table_delegate->setItemEditorFactory(m_table_edit_factory);
m_instances_table->setItemDelegate(m_table_delegate);
connect(m_instances_table, SIGNAL(cellActivated(int,int)), this, SLOT(OnInstActivated(int,int)));
connect(m_instances_table, SIGNAL(cellChanged(int,int)), this, SLOT(OnInstChanged(int,int)));
connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&)));
connect(m_long_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnLongNameEdited(const QString&)));
connect(m_version_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnVersionEdited(const QString&)));
connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited()));
}
void DevEditPanel::OnNameEdited(const QString& text)
{
m_ref.GetDev().name = text.toStdString();
OnModified(m_name_edit->isModified());
}
void DevEditPanel::OnLongNameEdited(const QString& text)
{
m_ref.GetDev().long_name = text.toStdString();
OnModified(m_long_name_edit->isModified());
}
void DevEditPanel::OnVersionEdited(const QString& text)
{
m_ref.GetDev().version = text.toStdString();
OnModified(m_version_edit->isModified());
}
void DevEditPanel::OnDescEdited()
{
m_ref.GetDev().desc = m_desc_edit->GetTextHtml().toStdString();
OnModified(m_desc_edit->IsModified());
}
void DevEditPanel::CreateNewRow(int row)
{
QTableWidgetItem *item = new QTableWidgetItem(QIcon::fromTheme("list-add"), "", DevInstNewType);
item->setToolTip("New?");
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_instances_table->setItem(row, DevInstIconColumn, item);
item = new QTableWidgetItem("New instance...");
QFont font = item->font();
font.setItalic(true);
item->setFont(font);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_instances_table->setItem(row, DevInstNameColumn, item);
item = new QTableWidgetItem("");
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_instances_table->setItem(row, DevInstAddrColumn, item);
}
void DevEditPanel::FillRow(int row, const soc_dev_addr_t& addr)
{
QTableWidgetItem *item = new QTableWidgetItem(QString::fromStdString(addr.name));
item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
m_instances_table->setItem(row, DevInstNameColumn, item);
item = new QTableWidgetItem();
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
item->setData(Qt::DisplayRole, QVariant(addr.addr));
m_instances_table->setItem(row, DevInstAddrColumn, item);
item = new QTableWidgetItem(QIcon::fromTheme("list-remove"), "", DevInstDeleteType);
item->setToolTip("Remove?");
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_instances_table->setItem(row, DevInstIconColumn, item);
}
void DevEditPanel::OnInstActivated(int row, int column)
{
if(column != 0)
return;
int type = m_instances_table->item(row, column)->type();
if(type == DevInstDeleteType)
{
m_ref.GetDev().addr.erase(m_ref.GetDev().addr.begin() + row);
m_instances_table->removeRow(row);
OnModified(true);
}
else if(type == DevInstNewType)
{
m_instances_table->insertRow(row);
soc_dev_addr_t addr;
addr.name = QString("UNNAMED_%1").arg(row).toStdString();
addr.addr = 0;
m_ref.GetDev().addr.push_back(addr);
FillRow(row, addr);
}
}
void DevEditPanel::OnInstChanged(int row, int column)
{
/* ignore extra row for addition */
if(row >= (int)m_ref.GetDev().addr.size())
return;
QTableWidgetItem *item = m_instances_table->item(row, column);
if(column == DevInstNameColumn)
{
m_ref.GetDev().addr[row].name = item->text().toStdString();
OnModified(true);
}
else if(column == DevInstAddrColumn)
{
m_ref.GetDev().addr[row].addr = item->data(Qt::DisplayRole).toUInt();
OnModified(true);
}
}
/**
* RegEditPanel
*/
RegEditPanel::RegEditPanel(SocRegRef ref, QWidget *parent)
:QWidget(parent), m_ref(ref), m_reg_font(font())
{
m_reg_font.setWeight(100);
m_reg_font.setKerning(false);
m_name_group = new QGroupBox("Name", this);
m_name_edit = new QLineEdit(this);
m_name_edit->setText(QString::fromStdString(ref.GetReg().name));
QVBoxLayout *name_group_layout = new QVBoxLayout;
name_group_layout->addWidget(m_name_edit);
m_name_group->setLayout(name_group_layout);
m_instances_table = new QTableWidget(this);
m_instances_table->setRowCount(ref.GetReg().addr.size() + 1);
m_instances_table->setColumnCount(RegInstNrColumns);
for(size_t row = 0; row < ref.GetReg().addr.size(); row++)
FillRow(row, ref.GetReg().addr[row]);
CreateNewAddrRow(ref.GetReg().addr.size());
m_instances_table->setHorizontalHeaderItem(RegInstIconColumn, new QTableWidgetItem(""));
m_instances_table->setHorizontalHeaderItem(RegInstNameColumn, new QTableWidgetItem("Name"));
m_instances_table->setHorizontalHeaderItem(RegInstAddrColumn, new QTableWidgetItem("Address"));
m_instances_table->verticalHeader()->setVisible(false);
m_instances_table->resizeColumnsToContents();
m_instances_table->horizontalHeader()->setStretchLastSection(true);
m_instances_table->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
m_instances_group = new QGroupBox("Instances", this);
QHBoxLayout *instances_group_layout = new QHBoxLayout;
instances_group_layout->addWidget(m_instances_table);
m_instances_group->setLayout(instances_group_layout);
m_desc_group = new QGroupBox("Description", this);
QHBoxLayout *group_layout = new QHBoxLayout;
m_desc_edit = new MyTextEditor(this);
m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetReg().desc));
group_layout->addWidget(m_desc_edit);
m_desc_group->setLayout(group_layout);
bool has_sct = m_ref.GetReg().flags & REG_HAS_SCT;
m_sct_check = new QCheckBox("Set/Clear/Toggle", this);
m_sct_check->setCheckState(has_sct ? Qt::Checked : Qt::Unchecked);
QHBoxLayout *flags_layout = new QHBoxLayout;
flags_layout->addWidget(m_sct_check);
flags_layout->addStretch();
m_flags_group = new QGroupBox("Flags", this);
m_flags_group->setLayout(flags_layout);
m_formula_combo = new QComboBox(this);
m_formula_combo->addItem("None", QVariant(REG_FORMULA_NONE));
m_formula_combo->addItem("String", QVariant(REG_FORMULA_STRING));
m_formula_combo->setCurrentIndex(m_formula_combo->findData(QVariant(m_ref.GetReg().formula.type)));
m_formula_type_label = new QLabel("Type:", this);
QHBoxLayout *formula_top_layout = new QHBoxLayout;
formula_top_layout->addWidget(m_formula_type_label);
formula_top_layout->addWidget(m_formula_combo);
m_formula_string_edit = new QLineEdit(QString::fromStdString(ref.GetReg().formula.string), this);
QVBoxLayout *formula_layout = new QVBoxLayout;
formula_layout->addLayout(formula_top_layout);
formula_layout->addWidget(m_formula_string_edit);
m_formula_string_gen = new QPushButton("Generate", this);
formula_layout->addWidget(m_formula_string_gen);
m_formula_group = new QGroupBox("Formula", this);
m_formula_group->setLayout(formula_layout);
QVBoxLayout *name_layout = new QVBoxLayout;
name_layout->addWidget(m_name_group);
name_layout->addWidget(m_flags_group);
name_layout->addWidget(m_formula_group);
name_layout->addStretch();
QHBoxLayout *top_layout = new QHBoxLayout;
top_layout->addWidget(m_instances_group);
top_layout->addLayout(name_layout);
top_layout->addWidget(m_desc_group, 1);
m_value_table = new QTableView(this);
m_value_model = new RegFieldTableModel(m_value_table); // view takes ownership
m_value_model->SetRegister(m_ref.GetReg());
m_value_model->SetReadOnly(true);
m_value_table->setModel(m_value_model);
m_value_table->verticalHeader()->setVisible(false);
m_value_table->horizontalHeader()->setStretchLastSection(true);
m_value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
// FIXME we cannot use setAlternatingRowColors() because we override the
// background color, should it be part of the model ?
m_table_delegate = new SocFieldCachedItemDelegate(this);
m_value_table->setItemDelegate(m_table_delegate);
m_value_table->resizeColumnsToContents();
m_sexy_display2 = new Unscroll<RegSexyDisplay2>(this);
m_sexy_display2->setFont(m_reg_font);
m_sexy_display2->setModel(m_value_model);
m_sexy_display2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QHBoxLayout *field_layout = new QHBoxLayout;
field_layout->addWidget(m_value_table);
m_field_group = new QGroupBox("Flags", this);
m_field_group->setLayout(field_layout);
QVBoxLayout *layout = new QVBoxLayout;
layout->addLayout(top_layout, 0);
layout->addWidget(m_sexy_display2, 0);
layout->addWidget(m_field_group);
UpdateFormula();
setLayout(layout);
SocFieldItemDelegate *m_table_delegate = new SocFieldItemDelegate(this);
QItemEditorFactory *m_table_edit_factory = new QItemEditorFactory();
SocFieldEditorCreator *m_table_edit_creator = new SocFieldEditorCreator();
m_table_edit_factory->registerEditor(QVariant::UInt, m_table_edit_creator);
m_table_delegate->setItemEditorFactory(m_table_edit_factory);
m_instances_table->setItemDelegate(m_table_delegate);
connect(m_instances_table, SIGNAL(cellActivated(int,int)), this, SLOT(OnInstActivated(int,int)));
connect(m_instances_table, SIGNAL(cellChanged(int,int)), this, SLOT(OnInstChanged(int,int)));
connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&)));
connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited()));
connect(m_sct_check, SIGNAL(stateChanged(int)), this, SLOT(OnSctEdited(int)));
connect(m_formula_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(OnFormulaChanged(int)));
connect(m_formula_string_edit, SIGNAL(textChanged(const QString&)), this,
SLOT(OnFormulaStringChanged(const QString&)));
connect(m_formula_string_gen, SIGNAL(clicked(bool)), this, SLOT(OnFormulaGenerate(bool)));
}
void RegEditPanel::UpdateWarning(int row)
{
Q_UNUSED(row);
}
void RegEditPanel::OnFormulaStringChanged(const QString& text)
{
m_ref.GetReg().formula.string = text.toStdString();
OnModified(true);
}
void RegEditPanel::OnFormulaGenerate(bool checked)
{
Q_UNUSED(checked);
bool ok;
int count = QInputDialog::getInt(this, "Instance generator", "Number of instances",
0, 0, 100, 1, &ok);
if(!ok)
return;
std::string name(m_ref.GetReg().name);
size_t pos = name.find('n');
if(pos == std::string::npos)
{
name.push_back('n');
pos = name.size() - 1;
}
std::map< std::string, soc_word_t > map;
std::vector< std::pair< std::string, soc_word_t > > list;
std::string formula = m_ref.GetReg().formula.string;
for(int n = 0; n < count; n++)
{
map["n"] = n;
std::string err;
soc_word_t res;
if(!evaluate_formula(formula, map, res, err))
{
qDebug() << "Cannot evaluator " << QString::fromStdString(formula)
<< "for n=" << n << ": " << QString::fromStdString(err);
return;
}
std::string regname = name;
std::string strn = QString("%1").arg(n).toStdString();
regname.replace(pos, 1, strn);
list.push_back(std::make_pair(regname, res));
}
// everything went good, commit result
while(m_instances_table->rowCount() > 1)
m_instances_table->removeRow(0);
m_ref.GetReg().addr.resize(list.size());
for(size_t i = 0; i < list.size(); i++)
{
m_instances_table->insertRow(i);
m_ref.GetReg().addr[i].name = list[i].first;
m_ref.GetReg().addr[i].addr = list[i].second;
FillRow(i, m_ref.GetReg().addr[i]);
}
}
void RegEditPanel::OnFormulaChanged(int index)
{
if(index == -1)
return;
m_ref.GetReg().formula.type = static_cast< soc_reg_formula_type_t >(m_formula_combo->itemData(index).toInt());
UpdateFormula();
OnModified(true);
}
void RegEditPanel::UpdateFormula()
{
m_formula_string_edit->hide();
m_formula_string_gen->hide();
switch(m_ref.GetReg().formula.type)
{
case REG_FORMULA_STRING:
m_formula_string_edit->show();
m_formula_string_gen->show();
break;
case REG_FORMULA_NONE:
default:
break;
}
}
void RegEditPanel::OnSctEdited(int state)
{
if(state == Qt::Checked)
m_ref.GetReg().flags |= REG_HAS_SCT;
else
m_ref.GetReg().flags &= ~REG_HAS_SCT;
OnModified(true);
}
void RegEditPanel::FillRow(int row, const soc_reg_addr_t& addr)
{
QTableWidgetItem *item = new QTableWidgetItem(QString::fromStdString(addr.name));
item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
m_instances_table->setItem(row, RegInstNameColumn, item);
item = new QTableWidgetItem();
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
item->setData(Qt::DisplayRole, QVariant(addr.addr));
m_instances_table->setItem(row, RegInstAddrColumn, item);
item = new QTableWidgetItem(QIcon::fromTheme("list-remove"), "", RegInstDeleteType);
item->setToolTip("Remove?");
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_instances_table->setItem(row, RegInstIconColumn, item);
}
void RegEditPanel::CreateNewAddrRow(int row)
{
QTableWidgetItem *item = new QTableWidgetItem(QIcon::fromTheme("list-add"), "", RegInstNewType);
item->setToolTip("New?");
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_instances_table->setItem(row, RegInstIconColumn, item);
item = new QTableWidgetItem("New instance...");
QFont font = item->font();
font.setItalic(true);
item->setFont(font);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_instances_table->setItem(row, RegInstNameColumn, item);
item = new QTableWidgetItem("");
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_instances_table->setItem(row, RegInstAddrColumn, item);
}
void RegEditPanel::OnNameEdited(const QString& text)
{
m_ref.GetReg().name = text.toStdString();
OnModified(m_name_edit->isModified());
}
void RegEditPanel::OnDescEdited()
{
m_ref.GetReg().desc = m_desc_edit->GetTextHtml().toStdString();
OnModified(m_desc_edit->IsModified());
}
void RegEditPanel::OnInstActivated(int row, int column)
{
if(column != 0)
return;
int type = m_instances_table->item(row, column)->type();
if(type == RegInstDeleteType)
{
m_ref.GetReg().addr.erase(m_ref.GetReg().addr.begin() + row);
m_instances_table->removeRow(row);
OnModified(true);
}
else if(type == RegInstNewType)
{
m_instances_table->insertRow(row);
soc_reg_addr_t addr;
addr.name = QString("UNNAMED_%1").arg(row).toStdString();
addr.addr = 0;
m_ref.GetReg().addr.push_back(addr);
FillRow(row, addr);
}
}
void RegEditPanel::OnInstChanged(int row, int column)
{
/* ignore extra row for addition */
if(row >= (int)m_ref.GetReg().addr.size())
return;
QTableWidgetItem *item = m_instances_table->item(row, column);
if(column == RegInstNameColumn)
{
m_ref.GetReg().addr[row].name = item->text().toStdString();
OnModified(true);
}
else if(column == RegInstAddrColumn)
{
m_ref.GetReg().addr[row].addr = item->data(Qt::DisplayRole).toUInt();
OnModified(true);
}
}
/**
* FieldEditPanel
*/
FieldEditPanel::FieldEditPanel(SocFieldRef ref, QWidget *parent)
:QWidget(parent), m_ref(ref)
{
m_name_group = new QGroupBox("Name", this);
m_name_edit = new QLineEdit(this);
m_name_edit->setText(QString::fromStdString(ref.GetField().name));
QVBoxLayout *name_group_layout = new QVBoxLayout;
name_group_layout->addWidget(m_name_edit);
m_name_group->setLayout(name_group_layout);
m_bitrange_group = new QGroupBox("Bit Range", this);
m_bitrange_edit = new QLineEdit(this);
const soc_reg_field_t& field = ref.GetField();
QString bits_str;
if(field.first_bit == field.last_bit)
bits_str.sprintf("%d", field.first_bit);
else
bits_str.sprintf("%d:%d", field.last_bit, field.first_bit);
m_bitrange_edit->setText(bits_str);
m_bitrange_edit->setValidator(new SocBitRangeValidator(m_bitrange_edit));
QVBoxLayout *bitrange_group_layout = new QVBoxLayout;
bitrange_group_layout->addWidget(m_bitrange_edit);
m_bitrange_group->setLayout(bitrange_group_layout);
m_desc_group = new QGroupBox("Description", this);
QHBoxLayout *group_layout = new QHBoxLayout;
m_desc_edit = new MyTextEditor(this);
m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetField().desc));
group_layout->addWidget(m_desc_edit);
m_desc_group->setLayout(group_layout);
m_value_group = new QGroupBox("Values", this);
QHBoxLayout *value_layout = new QHBoxLayout;
m_value_table = new QTableWidget(this);
m_value_table->setRowCount(ref.GetField().value.size() + 1);
m_value_table->setColumnCount(FieldValueNrColumns);
for(size_t row = 0; row < ref.GetField().value.size(); row++)
FillRow(row, ref.GetField().value[row]);
CreateNewRow(ref.GetField().value.size());
m_value_table->setHorizontalHeaderItem(FieldValueIconColumn, new QTableWidgetItem(""));
m_value_table->setHorizontalHeaderItem(FieldValueNameColumn, new QTableWidgetItem("Name"));
m_value_table->setHorizontalHeaderItem(FieldValueValueColumn, new QTableWidgetItem("Value"));
m_value_table->setHorizontalHeaderItem(FieldValueDescColumn, new QTableWidgetItem("Description"));
m_value_table->verticalHeader()->setVisible(false);
m_value_table->horizontalHeader()->setStretchLastSection(true);
value_layout->addWidget(m_value_table);
m_value_group->setLayout(value_layout);
QHBoxLayout *line_layout = new QHBoxLayout;
line_layout->addWidget(m_name_group);
line_layout->addWidget(m_bitrange_group);
line_layout->addStretch();
QVBoxLayout *left_layout = new QVBoxLayout;
left_layout->addLayout(line_layout);
left_layout->addWidget(m_desc_group);
left_layout->addWidget(m_value_group, 1);
UpdateDelegates();
connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&)));
connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited()));
connect(m_value_table, SIGNAL(cellActivated(int,int)), this, SLOT(OnValueActivated(int,int)));
connect(m_value_table, SIGNAL(cellChanged(int,int)), this, SLOT(OnValueChanged(int,int)));
connect(m_bitrange_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnBitRangeEdited(const QString&)));
setLayout(left_layout);
}
void FieldEditPanel::UpdateDelegates()
{
SocFieldItemDelegate *m_table_delegate = new SocFieldItemDelegate(m_ref.GetField(), this);
QItemEditorFactory *m_table_edit_factory = new QItemEditorFactory();
SocFieldEditorCreator *m_table_edit_creator = new SocFieldEditorCreator(m_ref.GetField());
m_table_edit_factory->registerEditor(QVariant::UInt, m_table_edit_creator);
m_table_delegate->setItemEditorFactory(m_table_edit_factory);
m_value_table->setItemDelegate(m_table_delegate);
m_value_table->resizeColumnsToContents();
}
void FieldEditPanel::UpdateWarning(int row)
{
soc_word_t val = m_ref.GetField().value[row].value;
soc_word_t max = m_ref.GetField().bitmask() >> m_ref.GetField().first_bit;
QTableWidgetItem *item = m_value_table->item(row, FieldValueValueColumn);
if(val > max)
{
item->setIcon(QIcon::fromTheme("dialog-warning"));
item->setToolTip("Value is too big for the field");
}
else
{
item->setIcon(QIcon());
item->setToolTip("");
}
}
void FieldEditPanel::FillRow(int row, const soc_reg_field_value_t& val)
{
QTableWidgetItem *item = new QTableWidgetItem(QString::fromStdString(val.name));
item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
m_value_table->setItem(row, FieldValueNameColumn, item);
item = new QTableWidgetItem();
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
item->setData(Qt::DisplayRole, QVariant(val.value));
m_value_table->setItem(row, FieldValueValueColumn, item);
item = new QTableWidgetItem(QString::fromStdString(val.desc));
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
m_value_table->setItem(row, FieldValueDescColumn, item);
item = new QTableWidgetItem(QIcon::fromTheme("list-remove"), "", FieldValueDeleteType);
item->setToolTip("Remove?");
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_value_table->setItem(row, FieldValueIconColumn, item);
UpdateWarning(row);
}
void FieldEditPanel::CreateNewRow(int row)
{
QTableWidgetItem *item = new QTableWidgetItem(QIcon::fromTheme("list-add"), "", FieldValueNewType);
item->setToolTip("New?");
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_value_table->setItem(row, FieldValueIconColumn, item);
item = new QTableWidgetItem("New value...");
QFont font = item->font();
font.setItalic(true);
item->setFont(font);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
m_value_table->setItem(row, FieldValueNameColumn, item);
}
void FieldEditPanel::OnBitRangeEdited(const QString& input)
{
const SocBitRangeValidator *validator =
dynamic_cast< const SocBitRangeValidator *>(m_bitrange_edit->validator());
int first, last;
QValidator::State state = validator->parse(input, last, first);
if(state != QValidator::Acceptable)
return;
m_ref.GetField().first_bit = first;
m_ref.GetField().last_bit = last;
// update all warning signs
for(size_t row = 0; row < m_ref.GetField().value.size(); row++)
UpdateWarning(row);
// also updates delegates because they now have the wrong view of the field
UpdateDelegates();
OnModified(true);
}
void FieldEditPanel::OnNameEdited(const QString& text)
{
m_ref.GetField().name = text.toStdString();
OnModified(m_name_edit->isModified());
}
void FieldEditPanel::OnDescEdited()
{
m_ref.GetField().desc = m_desc_edit->GetTextHtml().toStdString();
OnModified(m_desc_edit->IsModified());
}
void FieldEditPanel::OnValueActivated(int row, int column)
{
if(column != 0)
return;
int type = m_value_table->item(row, column)->type();
if(type == FieldValueDeleteType)
{
m_ref.GetField().value.erase(m_ref.GetField().value.begin() + row);
m_value_table->removeRow(row);
OnModified(true);
}
else if(type == FieldValueNewType)
{
m_value_table->insertRow(row);
soc_reg_field_value_t val;
val.name = QString("UNNAMED_%1").arg(row).toStdString();
val.value = 0;
m_ref.GetField().value.push_back(val);
FillRow(row, val);
}
}
void FieldEditPanel::OnValueChanged(int row, int column)
{
/* ignore extra row for addition */
if(row >= (int)m_ref.GetField().value.size())
return;
QTableWidgetItem *item = m_value_table->item(row, column);
if(column == FieldValueNameColumn)
m_ref.GetField().value[row].name = item->text().toStdString();
else if(column == FieldValueValueColumn)
{
soc_word_t& fval = m_ref.GetField().value[row].value;
soc_word_t new_val = item->data(Qt::DisplayRole).toUInt();
/* avoid infinite recursion by calling UpdateWarning() when
* only the icon changes which would trigger this callback again */
if(fval != new_val)
{
fval = new_val;
UpdateWarning(row);
}
}
else if(column == FieldValueDescColumn)
m_ref.GetField().value[row].desc = item->text().toStdString();
OnModified(true);
}
namespace
{
enum
{
SocTreeSocType = QTreeWidgetItem::UserType,
SocTreeDevType,
SocTreeRegType,
SocTreeFieldType,
SocTreeNewDevType,
SocTreeNewRegType,
SocTreeNewFieldType,
};
/**
* SocTreeItem
*/
class SocTreeItem : public QTreeWidgetItem
{
public:
SocTreeItem(const QString& string, const SocRef& ref)
:QTreeWidgetItem(QStringList(string), SocTreeSocType), m_ref(ref) {}
const SocRef& GetRef() { return m_ref; }
private:
SocRef m_ref;
};
/**
* NewDevTreeItem
*/
class NewDevTreeItem : public QTreeWidgetItem
{
public:
NewDevTreeItem(const QString& string, const SocRef& ref)
:QTreeWidgetItem(QStringList(string), SocTreeNewDevType), m_ref(ref) {}
const SocRef& GetRef() { return m_ref; }
private:
SocRef m_ref;
};
/**
* DevTreeItem
*/
class DevTreeItem : public QTreeWidgetItem
{
public:
DevTreeItem(const QString& string, const SocDevRef& ref)
:QTreeWidgetItem(QStringList(string), SocTreeDevType), m_ref(ref) {}
const SocDevRef& GetRef() { return m_ref; }
private:
SocDevRef m_ref;
};
/**
* NewRegTreeItem
*/
class NewRegTreeItem : public QTreeWidgetItem
{
public:
NewRegTreeItem(const QString& string, const SocDevRef& ref)
:QTreeWidgetItem(QStringList(string), SocTreeNewRegType), m_ref(ref) {}
const SocDevRef& GetRef() { return m_ref; }
private:
SocDevRef m_ref;
};
/**
* RegTreeItem
*/
class RegTreeItem : public QTreeWidgetItem
{
public:
RegTreeItem(const QString& string, const SocRegRef& ref)
:QTreeWidgetItem(QStringList(string), SocTreeRegType), m_ref(ref) {}
const SocRegRef& GetRef() { return m_ref; }
private:
SocRegRef m_ref;
};
/**
* NewFieldTreeItem
*/
class NewFieldTreeItem : public QTreeWidgetItem
{
public:
NewFieldTreeItem(const QString& string, const SocRegRef& ref)
:QTreeWidgetItem(QStringList(string), SocTreeNewFieldType), m_ref(ref) {}
const SocRegRef& GetRef() { return m_ref; }
private:
SocRegRef m_ref;
};
/**
* FieldTreeItem
*/
class FieldTreeItem : public QTreeWidgetItem
{
public:
FieldTreeItem(const QString& string, const SocFieldRef& ref)
:QTreeWidgetItem(QStringList(string), SocTreeFieldType), m_ref(ref) {}
const SocFieldRef& GetRef() { return m_ref; }
private:
SocFieldRef m_ref;
};
}
/**
* RegEdit
*/
RegEdit::RegEdit(Backend *backend, QWidget *parent)
:QWidget(parent), m_backend(backend)
{
QVBoxLayout *m_vert_layout = new QVBoxLayout();
m_file_group = new QGroupBox("File selection", this);
QHBoxLayout *m_file_group_layout = new QHBoxLayout();
m_file_edit = new QLineEdit(this);
m_file_edit->setReadOnly(true);
m_file_open = new QToolButton(this);
m_file_open->setText("Open");
m_file_open->setIcon(QIcon::fromTheme("document-open"));
m_file_open->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
QMenu *file_open_menu = new QMenu(this);
QAction *new_act = file_open_menu->addAction(QIcon::fromTheme("document-new"), "New...");
m_file_open->setMenu(file_open_menu);
m_file_save = new QToolButton(this);
m_file_save->setText("Save");
m_file_save->setIcon(QIcon::fromTheme("document-save"));
m_file_save->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
QMenu *file_save_menu = new QMenu(this);
QAction *saveas_act = file_save_menu->addAction(QIcon::fromTheme("document-save-as"), "Save as...");
m_file_save->setMenu(file_save_menu);
m_file_group_layout->addWidget(m_file_open);
m_file_group_layout->addWidget(m_file_save);
m_file_group_layout->addWidget(m_file_edit);
m_splitter = new QSplitter(this);
m_soc_tree = new QTreeWidget(this);
m_soc_tree->setColumnCount(1);
m_soc_tree->setHeaderLabel(QString("Name"));
m_soc_tree->setContextMenuPolicy(Qt::ActionsContextMenu);
QAction *soc_tree_delete_action = new QAction("&Delete", this);
soc_tree_delete_action->setIcon(QIcon::fromTheme("list-remove"));
connect(soc_tree_delete_action, SIGNAL(triggered()), this, SLOT(OnSocItemDelete()));
m_soc_tree->addAction(soc_tree_delete_action);
m_splitter->addWidget(m_soc_tree);
m_splitter->setStretchFactor(0, 0);
m_file_group->setLayout(m_file_group_layout);
m_vert_layout->addWidget(m_file_group);
m_vert_layout->addWidget(m_splitter, 1);
setLayout(m_vert_layout);
SetModified(false, false);
m_right_panel = 0;
SetPanel(new EmptyEditPanel(this));
UpdateTabName();
connect(m_file_open, SIGNAL(clicked()), this, SLOT(OnOpen()));
connect(m_file_save, SIGNAL(clicked()), this, SLOT(OnSave()));
connect(new_act, SIGNAL(triggered()), this, SLOT(OnNew()));
connect(saveas_act, SIGNAL(triggered()), this, SLOT(OnSaveAs()));
connect(m_soc_tree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
this, SLOT(OnSocItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
connect(m_soc_tree, SIGNAL(itemActivated(QTreeWidgetItem*, int)),
this, SLOT(OnSocItemActivated(QTreeWidgetItem*, int)));
}
QWidget *RegEdit::GetWidget()
{
return this;
}
RegEdit::~RegEdit()
{
}
void RegEdit::OnSave()
{
SaveSoc();
}
void RegEdit::OnSaveAs()
{
SaveSocAs();
}
bool RegEdit::CloseSoc()
{
if(!m_modified)
return true;
QMessageBox msgbox(QMessageBox::Question, "Save changes ?",
"The description has been modified. Do you want to save your changes ?",
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, this);
msgbox.setDefaultButton(QMessageBox::Cancel);
int ret = msgbox.exec();
if(ret == QMessageBox::Discard)
return true;
if(ret == QMessageBox::Cancel)
return false;
return SaveSoc();
}
bool RegEdit::SaveSoc()
{
if(m_file_edit->text().size() == 0)
return SaveSocAs();
else
return SaveSocFile(m_file_edit->text());
}
bool RegEdit::GetFilename(QString& filename, bool save)
{
QFileDialog *fd = new QFileDialog(this);
if(save)
fd->setAcceptMode(QFileDialog::AcceptSave);
fd->setFilter("Description files (*.xml);;All files (*)");
fd->setDirectory(Settings::Get()->value("regedit/loaddescdir", QDir::currentPath()).toString());
if(fd->exec())
{
QStringList filenames = fd->selectedFiles();
filename = filenames[0];
Settings::Get()->setValue("regedit/loaddescdir", fd->directory().absolutePath());
return true;
}
else
return false;
}
bool RegEdit::SaveSocAs()
{
QString filename;
if(!GetFilename(filename, true))
return false;
m_file_edit->setText(filename);
return SaveSocFile(filename);
}
void RegEdit::OnOpen()
{
if(!CloseSoc())
return;
QString filename;
if(!GetFilename(filename, false))
return;
LoadSocFile(filename);
}
void RegEdit::OnNew()
{
if(!CloseSoc())
return;
m_cur_socfile = SocFile();
m_file_edit->setText("");
SetModified(false, false);
UpdateSocFile();
}
bool RegEdit::SaveSocFile(const QString& filename)
{
normalize(m_cur_socfile.GetSoc());
if(!produce_xml(filename.toStdString(), m_cur_socfile.GetSoc()))
{
QMessageBox::warning(this, "The description was not saved",
"There was an error when saving the file");
return false;
}
m_soc_tree->clear();
FillSocTree();
SetModified(false, false);
return true;
}
void RegEdit::UpdateTabName()
{
QFileInfo info(m_cur_socfile.GetFilename());
if(info.exists())
SetTabName(info.fileName());
else
SetTabName("Register Editor");
}
void RegEdit::LoadSocFile(const QString& filename)
{
m_cur_socfile = SocFile(filename);
if(!m_cur_socfile.IsValid())
{
QMessageBox::warning(this, "The description was not loaded",
"There was an error when loading the file");
return;
}
m_file_edit->setText(filename);
SetModified(false, false);
UpdateSocFile();
UpdateTabName();
}
void RegEdit::CreateNewFieldItem(QTreeWidgetItem *_parent)
{
RegTreeItem *parent = dynamic_cast< RegTreeItem* >(_parent);
NewFieldTreeItem *newdev_item = new NewFieldTreeItem("New field...", parent->GetRef());
MakeItalic(newdev_item, true);
newdev_item->setIcon(0, QIcon::fromTheme("list-add"));
parent->addChild(newdev_item);
}
void RegEdit::FillRegTreeItem(QTreeWidgetItem *_item)
{
RegTreeItem *item = dynamic_cast< RegTreeItem* >(_item);
const soc_reg_t& reg = item->GetRef().GetReg();
for(size_t i = 0; i < reg.field.size(); i++)
{
const soc_reg_field_t& field = reg.field[i];
FieldTreeItem *field_item = new FieldTreeItem(QString::fromStdString(field.name),
SocFieldRef(item->GetRef(), i));
FixupEmptyItem(field_item);
item->addChild(field_item);
}
CreateNewFieldItem(item);
}
void RegEdit::CreateNewRegisterItem(QTreeWidgetItem *_parent)
{
DevTreeItem *parent = dynamic_cast< DevTreeItem* >(_parent);
NewRegTreeItem *newdev_item = new NewRegTreeItem("New register...", parent->GetRef());
MakeItalic(newdev_item, true);
newdev_item->setIcon(0, QIcon::fromTheme("list-add"));
parent->addChild(newdev_item);
}
void RegEdit::FillDevTreeItem(QTreeWidgetItem *_item)
{
DevTreeItem *item = dynamic_cast< DevTreeItem* >(_item);
const soc_dev_t& dev = item->GetRef().GetDev();
for(size_t i = 0; i < dev.reg.size(); i++)
{
const soc_reg_t& reg = dev.reg[i];
RegTreeItem *reg_item = new RegTreeItem(QString::fromStdString(reg.name),
SocRegRef(item->GetRef(), i, -1));
FixupEmptyItem(reg_item);
FillRegTreeItem(reg_item);
item->addChild(reg_item);
}
CreateNewRegisterItem(item);
}
void RegEdit::CreateNewDeviceItem(QTreeWidgetItem *_parent)
{
SocTreeItem *parent = dynamic_cast< SocTreeItem* >(_parent);
NewDevTreeItem *newdev_item = new NewDevTreeItem("New device...", parent->GetRef());
MakeItalic(newdev_item, true);
newdev_item->setIcon(0, QIcon::fromTheme("list-add"));
parent->addChild(newdev_item);
}
void RegEdit::FillSocTreeItem(QTreeWidgetItem *_item)
{
SocTreeItem *item = dynamic_cast< SocTreeItem* >(_item);
const soc_t& soc = item->GetRef().GetSoc();
for(size_t i = 0; i < soc.dev.size(); i++)
{
const soc_dev_t& reg = soc.dev[i];
DevTreeItem *dev_item = new DevTreeItem(QString::fromStdString(reg.name),
SocDevRef(item->GetRef(), i, -1));
FixupEmptyItem(dev_item);
FillDevTreeItem(dev_item);
item->addChild(dev_item);
}
CreateNewDeviceItem(item);
}
void RegEdit::FillSocTree()
{
SocRef ref = m_cur_socfile.GetSocRef();
SocTreeItem *soc_item = new SocTreeItem(
QString::fromStdString(ref.GetSoc().name), ref);
FixupEmptyItem(soc_item);
FillSocTreeItem(soc_item);
m_soc_tree->addTopLevelItem(soc_item);
soc_item->setExpanded(true);
}
void RegEdit::MakeItalic(QTreeWidgetItem *item, bool it)
{
QFont font = item->font(0);
font.setItalic(it);
item->setFont(0, font);
}
void RegEdit::FixupEmptyItem(QTreeWidgetItem *item)
{
if(item->text(0).size() == 0)
{
item->setIcon(0, QIcon::fromTheme("dialog-error"));
MakeItalic(item, true);
item->setText(0, "Unnamed");
}
else
{
item->setIcon(0, QIcon::fromTheme("cpu"));
MakeItalic(item, false);
}
}
void RegEdit::UpdateSocFile()
{
m_soc_tree->clear();
FillSocTree();
SetPanel(new EmptyEditPanel(this));
}
void RegEdit::SetPanel(QWidget *panel)
{
delete m_right_panel;
m_right_panel = panel;
connect(m_right_panel, SIGNAL(OnModified(bool)), this, SLOT(OnSocModified(bool)));
m_splitter->addWidget(m_right_panel);
m_splitter->setStretchFactor(1, 2);
}
void RegEdit::SetModified(bool add, bool mod)
{
m_modified = add ? (m_modified || mod) : mod;
OnModified(mod);
}
namespace
{
template< typename T >
void my_remove_at(std::vector< T >& v, size_t at)
{
v.erase(v.begin() + at);
}
}
void RegEdit::OnSocItemDelete()
{
QTreeWidgetItem *current = m_soc_tree->currentItem();
if(current == 0)
return;
QMessageBox msgbox(QMessageBox::Question, "Delete item ?",
"Are you sure you want to delete this item ?",
QMessageBox::Yes | QMessageBox::No, this);
msgbox.setDefaultButton(QMessageBox::No);
int ret = msgbox.exec();
if(ret != QMessageBox::Yes)
return;
if(current->type() == SocTreeSocType)
{
SocTreeItem *item = dynamic_cast< SocTreeItem * >(current);
item->GetRef().GetSoc().dev.clear();
item->takeChildren();
FillSocTreeItem(item);
m_soc_tree->expandItem(item);
}
else if(current->type() == SocTreeDevType)
{
DevTreeItem *item = dynamic_cast< DevTreeItem * >(current);
my_remove_at(item->GetRef().GetSoc().dev, item->GetRef().GetDevIndex());
QTreeWidgetItem *parent = item->parent();
parent->takeChildren();
FillSocTreeItem(parent);
m_soc_tree->expandItem(parent);
}
else if(current->type() == SocTreeRegType)
{
RegTreeItem *item = dynamic_cast< RegTreeItem * >(current);
my_remove_at(item->GetRef().GetDev().reg, item->GetRef().GetRegIndex());
QTreeWidgetItem *parent = item->parent();
parent->takeChildren();
FillDevTreeItem(parent);
m_soc_tree->expandItem(parent);
}
else if(current->type() == SocTreeFieldType)
{
FieldTreeItem *item = dynamic_cast< FieldTreeItem * >(current);
my_remove_at(item->GetRef().GetReg().field, item->GetRef().GetFieldIndex());
QTreeWidgetItem *parent = item->parent();
parent->takeChildren();
FillRegTreeItem(parent);
m_soc_tree->expandItem(parent);
}
}
void RegEdit::OnSocModified(bool modified)
{
// we might need to update the name in the tree
UpdateName(m_soc_tree->currentItem());
if(modified)
SetModified(true, true);
}
void RegEdit::DisplaySoc(SocRef ref)
{
SetPanel(new SocEditPanel(ref, this));
}
void RegEdit::DisplayDev(SocDevRef ref)
{
SetPanel(new DevEditPanel(ref, this));
}
void RegEdit::DisplayReg(SocRegRef ref)
{
SetPanel(new RegEditPanel(ref, this));
}
void RegEdit::DisplayField(SocFieldRef ref)
{
SetPanel(new FieldEditPanel(ref, this));
}
void RegEdit::UpdateName(QTreeWidgetItem *current)
{
if(current == 0)
return;
if(current->type() == SocTreeSocType)
{
SocTreeItem *item = dynamic_cast< SocTreeItem * >(current);
item->setText(0, QString::fromStdString(item->GetRef().GetSoc().name));
}
else if(current->type() == SocTreeDevType)
{
DevTreeItem *item = dynamic_cast< DevTreeItem * >(current);
item->setText(0, QString::fromStdString(item->GetRef().GetDev().name));
}
else if(current->type() == SocTreeRegType)
{
RegTreeItem *item = dynamic_cast< RegTreeItem * >(current);
item->setText(0, QString::fromStdString(item->GetRef().GetReg().name));
}
else if(current->type() == SocTreeFieldType)
{
FieldTreeItem *item = dynamic_cast< FieldTreeItem * >(current);
item->setText(0, QString::fromStdString(item->GetRef().GetField().name));
}
FixupEmptyItem(current);
}
void RegEdit::OnSocItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
Q_UNUSED(previous);
if(current == 0)
return;
if(current->type() == SocTreeSocType)
{
SocTreeItem *item = dynamic_cast< SocTreeItem * >(current);
DisplaySoc(item->GetRef());
}
else if(current->type() == SocTreeDevType)
{
DevTreeItem *item = dynamic_cast< DevTreeItem * >(current);
DisplayDev(item->GetRef());
}
else if(current->type() == SocTreeRegType)
{
RegTreeItem *item = dynamic_cast< RegTreeItem * >(current);
DisplayReg(item->GetRef());
}
else if(current->type() == SocTreeFieldType)
{
FieldTreeItem *item = dynamic_cast< FieldTreeItem * >(current);
DisplayField(item->GetRef());
}
}
void RegEdit::OnSocItemActivated(QTreeWidgetItem *current, int column)
{
Q_UNUSED(column);
if(current == 0)
return;
if(current->type() == SocTreeNewDevType)
AddDevice(current);
else if(current->type() == SocTreeNewRegType)
AddRegister(current);
else if(current->type() == SocTreeNewFieldType)
AddField(current);
}
void RegEdit::AddDevice(QTreeWidgetItem *_item)
{
NewDevTreeItem *item = dynamic_cast< NewDevTreeItem * >(_item);
item->GetRef().GetSoc().dev.push_back(soc_dev_t());
DevTreeItem *dev_item = new DevTreeItem("",
SocDevRef(item->GetRef(), item->GetRef().GetSoc().dev.size() - 1, -1));
FixupEmptyItem(dev_item);
item->parent()->insertChild(item->parent()->indexOfChild(item), dev_item);
CreateNewRegisterItem(dev_item);
m_soc_tree->setCurrentItem(dev_item);
OnModified(true);
}
void RegEdit::AddRegister(QTreeWidgetItem *_item)
{
NewRegTreeItem *item = dynamic_cast< NewRegTreeItem * >(_item);
item->GetRef().GetDev().reg.push_back(soc_reg_t());
RegTreeItem *reg_item = new RegTreeItem("",
SocRegRef(item->GetRef(), item->GetRef().GetDev().reg.size() - 1, -1));
FixupEmptyItem(reg_item);
item->parent()->insertChild(item->parent()->indexOfChild(item), reg_item);
CreateNewFieldItem(reg_item);
m_soc_tree->setCurrentItem(reg_item);
OnModified(true);
}
void RegEdit::AddField(QTreeWidgetItem *_item)
{
NewFieldTreeItem *item = dynamic_cast< NewFieldTreeItem * >(_item);
item->GetRef().GetReg().field.push_back(soc_reg_field_t());
FieldTreeItem *field_item = new FieldTreeItem("",
SocFieldRef(item->GetRef(), item->GetRef().GetReg().field.size() - 1));
FixupEmptyItem(field_item);
item->parent()->insertChild(item->parent()->indexOfChild(item), field_item);
m_soc_tree->setCurrentItem(field_item);
OnModified(true);
}
bool RegEdit::Quit()
{
return CloseSoc();
}