summaryrefslogtreecommitdiffstats
path: root/utils/regtools/qeditor/regedit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/regtools/qeditor/regedit.cpp')
-rw-r--r--utils/regtools/qeditor/regedit.cpp2222
1 files changed, 1317 insertions, 905 deletions
diff --git a/utils/regtools/qeditor/regedit.cpp b/utils/regtools/qeditor/regedit.cpp
index 8b4bfb7c49..826452fdbd 100644
--- a/utils/regtools/qeditor/regedit.cpp
+++ b/utils/regtools/qeditor/regedit.cpp
@@ -24,6 +24,7 @@
#include <QHeaderView>
#include <QMessageBox>
#include <QInputDialog>
+#include <QStandardItemModel>
/**
* EmptyEditPanel
@@ -36,863 +37,1300 @@ EmptyEditPanel::EmptyEditPanel(QWidget *parent)
/**
* SocEditPanel
*/
-SocEditPanel::SocEditPanel(SocRef ref, QWidget *parent)
+
+namespace
+{
+
+template< typename T >
+void my_remove_at(std::vector< T >& v, size_t at)
+{
+ v.erase(v.begin() + at);
+}
+
+enum
+{
+ SocEditPanelDelType = QTableWidgetItem::UserType,
+ SocEditPanelAddType,
+};
+
+}
+
+SocEditPanel::SocEditPanel(const soc_desc::soc_ref_t& 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);
+ QLineEdit *name_edit = new QLineEdit(this);
+ QLineEdit *title_edit = new QLineEdit(this);
+ QLineEdit *isa_edit = new QLineEdit(this);
+ QLineEdit *version_edit = new QLineEdit(this);
+
+ m_authors_list = new QTableWidget(this);
+ QGroupBox *authors_group = Misc::EncloseInBox("Authors", m_authors_list);
- 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);
+
+ QGroupBox *desc_group = Misc::EncloseInBox("Description", m_desc_edit);
+
+ QFormLayout *banner_left_layout = new QFormLayout;
+ banner_left_layout->addRow("Name:", name_edit);
+ banner_left_layout->addRow("Title:", title_edit);
+ banner_left_layout->addRow("Instruction Set:", isa_edit);
+ banner_left_layout->addRow("Version:", version_edit);
+
+ QGroupBox *banner_left_group = new QGroupBox("Information");
+ banner_left_group->setLayout(banner_left_layout);
+
+ QHBoxLayout *banner_layout = new QHBoxLayout;
+ banner_layout->addWidget(banner_left_group);
+ banner_layout->addWidget(authors_group);
+ banner_layout->addStretch(0);
QVBoxLayout *layout = new QVBoxLayout;
- layout->addWidget(m_name_group);
- layout->addWidget(m_desc_group);
+ layout->addLayout(banner_layout);
+ layout->addWidget(desc_group);
layout->addStretch(1);
- connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&)));
+ /* fill data */
+ name_edit->setText(QString::fromStdString(ref.get()->name));
+ title_edit->setText(QString::fromStdString(ref.get()->title));
+ isa_edit->setText(QString::fromStdString(ref.get()->isa));
+ version_edit->setText(QString::fromStdString(ref.get()->version));
+ m_desc_edit->SetTextHtml(QString::fromStdString(ref.get()->desc));
+
+ m_authors_list->setColumnCount(2);
+ m_authors_list->setHorizontalHeaderItem(0, new QTableWidgetItem(""));
+ m_authors_list->setHorizontalHeaderItem(1, new QTableWidgetItem("Name"));
+ m_authors_list->horizontalHeader()->setVisible(false);
+ m_authors_list->verticalHeader()->setVisible(false);
+ m_authors_list->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ std::vector< std::string >& authors = ref.get()->author;
+ m_authors_list->setRowCount(authors.size() + 1);
+ for(size_t i = 0; i < authors.size(); i++)
+ {
+ QTableWidgetItem *item = new QTableWidgetItem(
+ QIcon::fromTheme("list-remove"), "", SocEditPanelDelType);
+ item->setFlags(Qt::ItemIsEnabled);
+ m_authors_list->setItem(i, 0, item);
+ item = new QTableWidgetItem(QString::fromStdString(authors[i]));
+ m_authors_list->setItem(i, 1, item);
+ }
+ QTableWidgetItem *new_item = new QTableWidgetItem(
+ QIcon::fromTheme("list-add"), "", SocEditPanelAddType);
+ new_item->setFlags(Qt::ItemIsEnabled);
+ m_authors_list->setItem(authors.size(), 0, new_item);
+ new_item = new QTableWidgetItem("New author...", QTableWidgetItem::UserType);
+ new_item->setFlags(Qt::ItemIsEnabled);
+ QFont font = new_item->font();
+ font.setItalic(true);
+ new_item->setFont(font);
+ m_authors_list->setItem(authors.size(), 1, new_item);
+ m_authors_list->resizeColumnsToContents();
+ m_authors_list->horizontalHeader()->setStretchLastSection(true);
+
+ connect(name_edit, SIGNAL(textChanged(const QString&)), this,
+ SLOT(OnNameEdited(const QString&)));
connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnTextEdited()));
+ connect(title_edit, SIGNAL(textChanged(const QString&)), this,
+ SLOT(OnTitleEdited(const QString&)));
+ connect(version_edit, SIGNAL(textChanged(const QString&)), this,
+ SLOT(OnVersionEdited(const QString&)));
+ connect(isa_edit, SIGNAL(textChanged(const QString&)), this,
+ SLOT(OnIsaEdited(const QString&)));
+ connect(m_authors_list, SIGNAL(itemActivated(QTableWidgetItem *)), this,
+ SLOT(OnAuthorActivated(QTableWidgetItem *)));
+ connect(m_authors_list, SIGNAL(itemChanged(QTableWidgetItem *)), this,
+ SLOT(OnAuthorChanged(QTableWidgetItem *)));
setLayout(layout);
}
void SocEditPanel::OnNameEdited(const QString& text)
{
- m_ref.GetSoc().name = text.toStdString();
- OnModified(m_name_edit->isModified());
+ m_ref.get()->name = text.toStdString();
+ OnModified();
}
-void SocEditPanel::OnTextEdited()
+void SocEditPanel::OnTitleEdited(const QString& text)
{
- m_ref.GetSoc().desc = m_desc_edit->GetTextHtml().toStdString();
- OnModified(m_desc_edit->IsModified());
+ m_ref.get()->title = text.toStdString();
+ OnModified();
}
-/**
- * DevEditPanel
- */
-DevEditPanel::DevEditPanel(SocDevRef ref, QWidget *parent)
- :QWidget(parent), m_ref(ref)
+void SocEditPanel::OnVersionEdited(const QString& text)
{
- 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);
+ m_ref.get()->version = text.toStdString();
+ OnModified();
+}
- 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 SocEditPanel::OnIsaEdited(const QString& text)
+{
+ m_ref.get()->isa = text.toStdString();
+ OnModified();
}
-void DevEditPanel::OnNameEdited(const QString& text)
+void SocEditPanel::OnTextEdited()
{
- m_ref.GetDev().name = text.toStdString();
- OnModified(m_name_edit->isModified());
+ m_ref.get()->desc = m_desc_edit->GetTextHtml().toStdString();
+ OnModified();
}
-void DevEditPanel::OnLongNameEdited(const QString& text)
+void SocEditPanel::OnAuthorActivated(QTableWidgetItem *item)
{
- m_ref.GetDev().long_name = text.toStdString();
- OnModified(m_long_name_edit->isModified());
+ if(item->type() == SocEditPanelDelType)
+ {
+ int row = item->row();
+ my_remove_at(m_ref.get()->author, row);
+ m_authors_list->removeRow(row);
+ OnModified();
+ }
+ else if(item->type() == SocEditPanelAddType)
+ {
+ int row = m_ref.get()->author.size();
+ m_ref.get()->author.push_back("Anonymous");
+ m_authors_list->insertRow(row);
+ QTableWidgetItem *item = new QTableWidgetItem(
+ QIcon::fromTheme("list-remove"), "", SocEditPanelDelType);
+ item->setFlags(Qt::ItemIsEnabled);
+ m_authors_list->setItem(row, 0, item);
+ item = new QTableWidgetItem(QString::fromStdString(m_ref.get()->author.back()));
+ m_authors_list->setItem(row, 1, item);
+ OnModified();
+ }
}
-void DevEditPanel::OnVersionEdited(const QString& text)
+void SocEditPanel::OnAuthorChanged(QTableWidgetItem *item)
{
- m_ref.GetDev().version = text.toStdString();
- OnModified(m_version_edit->isModified());
+ if((size_t)item->row() >= m_ref.get()->author.size())
+ return;
+ if(item->column() == 1)
+ m_ref.get()->author[item->row()] = item->text().toStdString();
+ OnModified();
}
-void DevEditPanel::OnDescEdited()
+/**
+ * NodeInstanceEditPanel
+ */
+
+namespace
{
- m_ref.GetDev().desc = m_desc_edit->GetTextHtml().toStdString();
- OnModified(m_desc_edit->IsModified());
+
+template< typename T >
+soc_id_t GetFreshId(const std::vector< T >& list)
+{
+ soc_id_t id = 0;
+ for(size_t i = 0; i < list.size(); i++)
+ id = std::max(id, list[i].id);
+ return id + 1;
}
-void DevEditPanel::CreateNewRow(int row)
+template< typename T >
+int GetIndexById(const std::vector< T >& list, soc_id_t id)
{
- 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);
+ for(size_t i = 0; i < list.size(); i++)
+ if(list[i].id == id)
+ return i;
+ return -1;
}
-void DevEditPanel::FillRow(int row, const soc_dev_addr_t& addr)
+soc_desc::instance_t *GetInstanceById(const soc_desc::node_ref_t& node, soc_id_t id)
{
- 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);
+ std::vector< soc_desc::instance_t >& inst_list = node.get()->instance;
+ for(size_t i = 0; i < inst_list.size(); i++)
+ if(inst_list[i].id == id)
+ return &inst_list[i];
+ return 0;
}
-void DevEditPanel::OnInstActivated(int row, int column)
+bool RemoveInstanceById(const soc_desc::node_ref_t& node, soc_id_t id)
{
- 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);
- }
+ std::vector< soc_desc::instance_t >& inst_list = node.get()->instance;
+ for(size_t i = 0; i < inst_list.size(); i++)
+ if(inst_list[i].id == id)
+ {
+ my_remove_at(inst_list, i);
+ return true;
+ }
+ return false;
}
-void DevEditPanel::OnInstChanged(int row, int column)
+enum
{
- /* 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)
+ InstTypeSingle,
+ InstTypeRangeStride,
+ InstTypeRangeFormula,
+ InstTypeRangeList
+};
+
+enum
+{
+ NodeInstEditPanelDelType = QTableWidgetItem::UserType,
+ NodeInstEditPanelAddType
+};
+
+}
+
+NodeInstanceEditPanel::NodeInstanceEditPanel(const soc_desc::node_ref_t& ref,
+ soc_id_t inst_id, QWidget *parent)
+ :QWidget(parent), m_ref(ref), m_id(inst_id)
+{
+ QLineEdit *name_edit = new QLineEdit(this);
+ QLineEdit *title_edit = new QLineEdit(this);
+ m_type_combo = new QComboBox(this);
+ QLabel *type_label = new QLabel("Type:", this);
+ QFont f = type_label->font();
+ f.setBold(true);
+ type_label->setFont(f);
+
+ QHBoxLayout *type_layout = new QHBoxLayout;
+ type_layout->addWidget(type_label);
+ type_layout->addWidget(m_type_combo);
+ type_layout->addStretch(0);
+
+ soc_desc::field_t fake_field;
+ fake_field.pos = 0;
+ fake_field.width = 32;
+
+ m_single_group = new QWidget(this);
+ QHBoxLayout *sg_layout = new QHBoxLayout;
+ sg_layout->addWidget(new QLabel("Address:", m_single_group));
+ SocFieldEditor *addr_edit = new SocFieldEditor(fake_field, m_single_group);
+ sg_layout->addWidget(addr_edit);
+ m_single_group->setLayout(sg_layout);
+
+ m_range_group = new QWidget(this);
+ QGridLayout *rg_layout = new QGridLayout;
+ rg_layout->addWidget(new QLabel("First:", m_range_group), 0, 0);
+ QSpinBox *first_spin = new QSpinBox(m_range_group);
+ rg_layout->addWidget(first_spin, 0, 1);
+ rg_layout->addWidget(new QLabel("Count:", m_range_group), 1, 0);
+ QSpinBox *count_spin = new QSpinBox(m_range_group);
+ rg_layout->addWidget(count_spin, 1, 1);
+ m_range_group->setLayout(rg_layout);
+
+ m_stride_group = new QWidget(m_range_group);
+ QGridLayout *rsg_layout = new QGridLayout;
+ rsg_layout->addWidget(new QLabel("Base:", m_stride_group), 0, 0);
+ SocFieldEditor *base_edit = new SocFieldEditor(fake_field, m_stride_group);
+ rsg_layout->addWidget(base_edit, 0, 1);
+ rsg_layout->addWidget(new QLabel("Stride:", m_stride_group), 1, 0);
+ SocFieldEditor *stride_edit = new SocFieldEditor(fake_field, m_stride_group);
+ rsg_layout->addWidget(stride_edit, 1, 1);
+ m_stride_group->setLayout(rsg_layout);
+
+ m_formula_group = new QWidget(m_range_group);
+ QGridLayout *fsg_layout = new QGridLayout;
+ fsg_layout->addWidget(new QLabel("Variable:", m_formula_group), 0, 0);
+ QLineEdit *variable_edit = new QLineEdit(m_formula_group);
+ fsg_layout->addWidget(variable_edit, 0, 1);
+ fsg_layout->addWidget(new QLabel("Formula:", m_formula_group), 1, 0);
+ QLineEdit *formula_edit = new QLineEdit(m_formula_group);
+ fsg_layout->addWidget(formula_edit, 1, 1);
+ m_formula_group->setLayout(fsg_layout);
+
+ QTableWidget *addr_list = new QTableWidget(m_range_group);
+ m_list_group = addr_list;
+
+ QHBoxLayout *inst_layout = new QHBoxLayout;
+ inst_layout->addWidget(m_single_group);
+ inst_layout->addWidget(m_range_group);
+ inst_layout->addWidget(m_stride_group);
+ inst_layout->addWidget(m_formula_group);
+ inst_layout->addWidget(m_list_group);
+ inst_layout->addStretch(0);
+
+ QGroupBox *inst_groupbox = new QGroupBox(this);
+ inst_groupbox->setLayout(inst_layout);
+
+ MyTextEditor *desc_edit = new MyTextEditor(this);
+ QVBoxLayout *ii_layout = new QVBoxLayout;
+
+ QFormLayout *info_layout = new QFormLayout();
+ info_layout->addRow("Name", name_edit);
+ info_layout->addRow("Title", title_edit);
+
+ QGroupBox *info_group = Misc::EncloseInBox("Information", info_layout);
+ QGroupBox *desc_group = Misc::EncloseInBox("Description", desc_edit);
+ QHBoxLayout *name_title_desc_layout = new QHBoxLayout;
+ name_title_desc_layout->addWidget(info_group, 1);
+ name_title_desc_layout->addWidget(desc_group, 2);
+
+ ii_layout->addLayout(name_title_desc_layout);
+ ii_layout->addLayout(type_layout);
+ ii_layout->addWidget(inst_groupbox);
+ ii_layout->addStretch(1);
+
+ m_type_combo->addItem("Single", QVariant(InstTypeSingle));
+ m_type_combo->addItem("Range > Stride", QVariant(InstTypeRangeStride));
+ m_type_combo->addItem("Range > Formula", QVariant(InstTypeRangeFormula));
+ m_type_combo->addItem("Range > List", QVariant(InstTypeRangeList));
+
+ /* fill info */
+ soc_desc::instance_t& inst = GetInstance();
+ name_edit->setText(QString::fromStdString(inst.name));
+ title_edit->setText(QString::fromStdString(inst.title));
+ desc_edit->SetTextHtml(QString::fromStdString(inst.desc));
+ addr_edit->setField(inst.addr);
+ base_edit->setField(inst.range.base);
+ stride_edit->setField(inst.range.stride);
+ first_spin->setValue(inst.range.first);
+ count_spin->setValue(inst.range.count);
+ formula_edit->setText(QString::fromStdString(inst.range.formula));
+ variable_edit->setText(QString::fromStdString(inst.range.variable));
+ addr_list->setColumnCount(2);
+ addr_list->setHorizontalHeaderItem(0, new QTableWidgetItem(""));
+ addr_list->setHorizontalHeaderItem(1, new QTableWidgetItem("Address"));
+ addr_list->horizontalHeader()->setVisible(false);
+ addr_list->verticalHeader()->setVisible(false);
+ addr_list->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ std::vector< soc_word_t >& addrs = inst.range.list;
+ addr_list->setRowCount(addrs.size() + 1);
+ for(size_t i = 0; i < addrs.size(); i++)
{
- m_ref.GetDev().addr[row].name = item->text().toStdString();
- OnModified(true);
+ QTableWidgetItem *item = new QTableWidgetItem(
+ QIcon::fromTheme("list-remove"), "", NodeInstEditPanelDelType);
+ item->setFlags(Qt::ItemIsEnabled);
+ addr_list->setItem(i, 0, item);
+ item = new QTableWidgetItem();
+ item->setData(Qt::EditRole, QVariant::fromValue(addrs[i]));
+ addr_list->setItem(i, 1, item);
}
- else if(column == DevInstAddrColumn)
+ QTableWidgetItem *new_item = new QTableWidgetItem(
+ QIcon::fromTheme("list-add"), "", NodeInstEditPanelAddType);
+ new_item->setFlags(Qt::ItemIsEnabled);
+ addr_list->setItem(addrs.size(), 0, new_item);
+ new_item = new QTableWidgetItem("New address...", QTableWidgetItem::UserType);
+ new_item->setFlags(Qt::ItemIsEnabled);
+ QFont font = new_item->font();
+ font.setItalic(true);
+ new_item->setFont(font);
+ addr_list->setItem(addrs.size(), 1, new_item);
+ addr_list->resizeColumnsToContents();
+ addr_list->horizontalHeader()->setStretchLastSection(true);
+ m_table_delegate = new SocFieldItemDelegate(this);
+ m_table_delegate->setItemEditorFactory(new QItemEditorFactory);
+ m_table_edit_factory = new SocFieldEditorCreator;
+ m_table_delegate->itemEditorFactory()->registerEditor(QVariant::UInt, m_table_edit_factory);
+ addr_list->setItemDelegate(m_table_delegate);
+
+ setLayout(ii_layout);
+
+ connect(name_edit, SIGNAL(textChanged(const QString&)), this,
+ SLOT(OnNameEdited(const QString&)));
+ connect(desc_edit, SIGNAL(OnTextChanged(const QString&)), this,
+ SLOT(OnDescEdited(const QString&)));
+ connect(title_edit, SIGNAL(textChanged(const QString&)), this,
+ SLOT(OnTitleEdited(const QString&)));
+ connect(addr_edit, SIGNAL(editingFinished(uint)), this, SLOT(OnAddrChanged(uint)));
+ connect(base_edit, SIGNAL(editingFinished(uint)), this, SLOT(OnBaseChanged(uint)));
+ connect(stride_edit, SIGNAL(editingFinished(uint)), this, SLOT(OnStrideChanged(uint)));
+ connect(first_spin, SIGNAL(valueChanged(int)), this, SLOT(OnFirstChanged(int)));
+ connect(count_spin, SIGNAL(valueChanged(int)), this, SLOT(OnCountChanged(int)));
+ connect(formula_edit, SIGNAL(textChanged(const QString&)), this,
+ SLOT(OnFormulaChanged(const QString&)));
+ connect(variable_edit, SIGNAL(textChanged(const QString&)), this,
+ SLOT(OnVariableChanged(const QString&)));
+ connect(m_type_combo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(OnTypeChanged(int)));
+ connect(addr_list, SIGNAL(itemActivated(QTableWidgetItem *)), this,
+ SLOT(OnAddressActivated(QTableWidgetItem *)));
+ connect(addr_list, SIGNAL(itemChanged(QTableWidgetItem *)), this,
+ SLOT(OnAddressChanged(QTableWidgetItem *)));
+
+ /* fill info */
+ int combo_type;
+ if(inst.type == soc_desc::instance_t::RANGE)
{
- m_ref.GetDev().addr[row].addr = item->data(Qt::DisplayRole).toUInt();
- OnModified(true);
+ if(inst.range.type == soc_desc::range_t::STRIDE)
+ combo_type = InstTypeRangeStride;
+ else if(inst.range.type == soc_desc::range_t::FORMULA)
+ combo_type = InstTypeRangeFormula;
+ else /* LIST */
+ combo_type = InstTypeRangeList;
}
+ else
+ combo_type = InstTypeSingle;
+ m_type_combo->setCurrentIndex(m_type_combo->findData(QVariant(combo_type)));
+ UpdateType(combo_type);
}
-/**
- * RegEditPanel
- */
+soc_desc::instance_t& NodeInstanceEditPanel::GetInstance()
+{
+ return *GetInstanceById(m_ref, m_id);
+}
-RegEditPanel::RegEditPanel(SocRegRef ref, QWidget *parent)
- :QWidget(parent), m_ref(ref), m_reg_font(font())
+void NodeInstanceEditPanel::OnNameEdited(const QString& text)
{
- m_reg_font.setWeight(100);
- m_reg_font.setKerning(false);
+ GetInstance().name = text.toStdString();
+ OnModified();
+}
- 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);
+void NodeInstanceEditPanel::OnTitleEdited(const QString& text)
+{
+ GetInstance().title = text.toStdString();
+ OnModified();
+}
- QHBoxLayout *field_layout = new QHBoxLayout;
- field_layout->addWidget(m_value_table);
- m_field_group = new QGroupBox("Flags", this);
- m_field_group->setLayout(field_layout);
+void NodeInstanceEditPanel::OnDescEdited(const QString& text)
+{
+ GetInstance().desc = text.toStdString();
+ OnModified();
+}
- QVBoxLayout *layout = new QVBoxLayout;
- layout->addLayout(top_layout, 0);
- layout->addWidget(m_sexy_display2, 0);
- layout->addWidget(m_field_group);
+void NodeInstanceEditPanel::OnAddrChanged(uint addr)
+{
+ GetInstance().addr = addr;
+ OnModified();
+}
- UpdateFormula();
+void NodeInstanceEditPanel::OnBaseChanged(uint base)
+{
+ GetInstance().range.base = base;
+ OnModified();
+}
- setLayout(layout);
+void NodeInstanceEditPanel::OnStrideChanged(uint stride)
+{
+ GetInstance().range.stride = stride;
+ OnModified();
+}
- 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);
+void NodeInstanceEditPanel::OnFirstChanged(int first)
+{
+ GetInstance().range.first = first;
+ OnModified();
+}
- 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 NodeInstanceEditPanel::OnCountChanged(int count)
+{
+ GetInstance().range.count = count;
+ OnModified();
}
-void RegEditPanel::UpdateWarning(int row)
+void NodeInstanceEditPanel::OnFormulaChanged(const QString& formula)
{
- Q_UNUSED(row);
+ GetInstance().range.formula = formula.toStdString();
+ OnModified();
}
-void RegEditPanel::OnFormulaStringChanged(const QString& text)
+void NodeInstanceEditPanel::OnVariableChanged(const QString& variable)
{
- m_ref.GetReg().formula.string = text.toStdString();
- OnModified(true);
+ GetInstance().range.variable = variable.toStdString();
+ OnModified();
}
-void RegEditPanel::OnFormulaGenerate(bool checked)
+void NodeInstanceEditPanel::OnAddressActivated(QTableWidgetItem *item)
{
- 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++)
+ QTableWidget *table = item->tableWidget();
+ soc_desc::instance_t& inst = GetInstance();
+ if(item->type() == NodeInstEditPanelDelType)
{
- 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));
+ int row = item->row();
+ my_remove_at(inst.range.list, row);
+ table->removeRow(row);
+ OnModified();
}
- // 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++)
+ else if(item->type() == NodeInstEditPanelAddType)
{
- 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]);
+ int row = inst.range.list.size();
+ soc_word_t new_addr = 0;
+ GetInstance().range.list.push_back(new_addr);
+ table->insertRow(row);
+ QTableWidgetItem *item = new QTableWidgetItem(
+ QIcon::fromTheme("list-remove"), "", NodeInstEditPanelDelType);
+ item->setFlags(Qt::ItemIsEnabled);
+ table->setItem(row, 0, item);
+ item = new QTableWidgetItem();
+ item->setData(Qt::EditRole, QVariant(new_addr));
+ table->setItem(row, 1, item);
+ OnModified();
}
}
-void RegEditPanel::OnFormulaChanged(int index)
+void NodeInstanceEditPanel::OnAddressChanged(QTableWidgetItem *item)
{
- if(index == -1)
+ soc_desc::instance_t& inst = GetInstance();
+ if((size_t)item->row() >= inst.range.list.size())
return;
- m_ref.GetReg().formula.type = static_cast< soc_reg_formula_type_t >(m_formula_combo->itemData(index).toInt());
- UpdateFormula();
- OnModified(true);
+ soc_word_t& addr = inst.range.list[item->row()];
+ if(item->column() == 1)
+ addr = item->data(Qt::EditRole).value< soc_word_t >();
+ OnModified();
}
-void RegEditPanel::UpdateFormula()
+void NodeInstanceEditPanel::UpdateType(int type)
{
- m_formula_string_edit->hide();
- m_formula_string_gen->hide();
- switch(m_ref.GetReg().formula.type)
+ m_single_group->hide();
+ m_range_group->hide();
+ m_stride_group->hide();
+ m_formula_group->hide();
+ m_list_group->hide();
+
+ switch(type)
{
- case REG_FORMULA_STRING:
- m_formula_string_edit->show();
- m_formula_string_gen->show();
+ case InstTypeSingle:
+ m_single_group->show();
+ GetInstance().type = soc_desc::instance_t::SINGLE;
+ break;
+ case InstTypeRangeStride:
+ m_range_group->show();
+ m_stride_group->show();
+ GetInstance().type = soc_desc::instance_t::RANGE;
+ GetInstance().range.type = soc_desc::range_t::STRIDE;
+ break;
+ case InstTypeRangeFormula:
+ m_range_group->show();
+ m_formula_group->show();
+ GetInstance().type = soc_desc::instance_t::RANGE;
+ GetInstance().range.type = soc_desc::range_t::FORMULA;
+ break;
+ case InstTypeRangeList:
+ m_range_group->show();
+ m_formula_group->hide();
+ m_list_group->show();
+ GetInstance().type = soc_desc::instance_t::RANGE;
+ GetInstance().range.type = soc_desc::range_t::LIST;
break;
- case REG_FORMULA_NONE:
default:
break;
}
}
-void RegEditPanel::OnSctEdited(int state)
+void NodeInstanceEditPanel::OnTypeChanged(int index)
{
- 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);
+ if(index == -1)
+ return;
+ UpdateType(m_type_combo->itemData(index).toInt());
+ OnModified();
}
-void RegEditPanel::OnNameEdited(const QString& text)
+soc_id_t NodeInstanceEditPanel::GetId()
{
- m_ref.GetReg().name = text.toStdString();
- OnModified(m_name_edit->isModified());
+ return m_id;
}
-void RegEditPanel::OnDescEdited()
-{
- m_ref.GetReg().desc = m_desc_edit->GetTextHtml().toStdString();
- OnModified(m_desc_edit->IsModified());
-}
+/**
+ * NodeEditPanel
+ */
-void RegEditPanel::OnInstActivated(int row, int column)
+NodeEditPanel::NodeEditPanel(const soc_desc::node_ref_t& ref, QWidget *parent)
+ :QWidget(parent), m_ref(ref)
{
- 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)
+ /* top layout: name, title then desc */
+ QLineEdit *name_edit = new QLineEdit(this);
+ name_edit->setText(QString::fromStdString(ref.get()->name));
+
+ QLineEdit *title_edit = new QLineEdit(this);
+ title_edit->setText(QString::fromStdString(ref.get()->title));
+
+ QFormLayout *info_layout = new QFormLayout();
+ info_layout->addRow("Name", name_edit);
+ info_layout->addRow("Title", title_edit);
+
+ QGroupBox *info_group = Misc::EncloseInBox("Information", info_layout);
+
+ m_desc_edit = new MyTextEditor(this);
+ m_desc_edit->SetTextHtml(QString::fromStdString(ref.get()->desc));
+ QGroupBox *desc_group = Misc::EncloseInBox("Description", m_desc_edit);
+
+ QHBoxLayout *name_title_desc_layout = new QHBoxLayout;
+ name_title_desc_layout->addWidget(info_group, 1);
+ name_title_desc_layout->addWidget(desc_group, 2);
+
+ /* instance tab */
+ m_instances_tab = new YTabWidget(0, this);
+ m_instances_tab->setTabOpenable(true);
+ std::vector< soc_desc::instance_t >& inst_list = m_ref.get()->instance;
+ m_instances_tab->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
+ m_instances_tab->setTabsClosable(true);
+ QGroupBox *instance_tab_group = Misc::EncloseInBox("Instances", m_instances_tab);
+ for(size_t i = 0; i < inst_list.size(); i++)
{
- 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);
+ NodeInstanceEditPanel *p = new NodeInstanceEditPanel(m_ref, inst_list[i].id, this);
+ connect(p, SIGNAL(OnModified()), this, SLOT(OnInstModified()));
+ m_instances_tab->addTab(p, QString::fromStdString(inst_list[i].name));
}
+
+ /* boring */
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addLayout(name_title_desc_layout);
+ layout->addWidget(instance_tab_group);
+ layout->addStretch(1);
+
+ setLayout(layout);
+
+ connect(name_edit, SIGNAL(textChanged(const QString&)), this,
+ SLOT(OnNameEdited(const QString&)));
+ connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited()));
+ connect(title_edit, SIGNAL(textChanged(const QString&)), this,
+ SLOT(OnTitleEdited(const QString&)));
+ connect(m_instances_tab, SIGNAL(tabCloseRequested(int)), this,
+ SLOT(OnInstRemove(int)));
+ connect(m_instances_tab, SIGNAL(tabOpenRequested()), this, SLOT(OnInstCreate()));
}
-void RegEditPanel::OnInstChanged(int row, int column)
+void NodeEditPanel::OnNameEdited(const QString& text)
{
- /* 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.get()->name = text.toStdString();
+ OnModified();
+}
+
+void NodeEditPanel::OnTitleEdited(const QString& text)
+{
+ m_ref.get()->title = text.toStdString();
+ OnModified();
+}
+
+void NodeEditPanel::OnDescEdited()
+{
+ m_ref.get()->desc = m_desc_edit->GetTextHtml().toStdString();
+ OnModified();
+}
+
+void NodeEditPanel::OnInstRemove(int index)
+{
+ NodeInstanceEditPanel *panel =
+ dynamic_cast< NodeInstanceEditPanel * >(m_instances_tab->widget(index));
+ RemoveInstanceById(m_ref, panel->GetId());
+ m_instances_tab->removeTab(index);
+ delete panel;
+ OnModified();
+}
+
+void NodeEditPanel::OnInstModified()
+{
+ int index = m_instances_tab->currentIndex();
+ NodeInstanceEditPanel *panel =
+ dynamic_cast< NodeInstanceEditPanel * >(m_instances_tab->widget(index));
+ m_instances_tab->setTabText(index, QString::fromStdString(panel->GetInstance().name));
+ OnModified();
+}
+
+QString NodeEditPanel::GuessName()
+{
+ /* try to find instances named Xddd where X is the node name (case insensitive)
+ * and d are digits. */
+ int max_nr_digits = -1;
+ int max_value = -1;
+ QString node_name = QString::fromStdString(m_ref.get()->name);
+ std::vector< soc_desc::instance_t >& inst_list = m_ref.get()->instance;
+ for(size_t i = 0; i < inst_list.size(); i++)
{
- m_ref.GetReg().addr[row].addr = item->data(Qt::DisplayRole).toUInt();
- OnModified(true);
+ QString inst_name = QString::fromStdString(inst_list[i].name);
+ /* ignore name if it doesn't start like the node name */
+ if(!inst_name.startsWith(node_name, Qt::CaseInsensitive))
+ continue;
+ /* check if the suffix is a digit */
+ QString suffix = inst_name.mid(node_name.size());
+ if(suffix.size() == 0)
+ {
+ max_nr_digits = qMax(max_nr_digits, 0);
+ continue;
+ }
+ bool ok;
+ int value = suffix.toUInt(&ok);
+ if(!ok)
+ continue;
+ max_value = qMax(max_value, value);
+ max_nr_digits = qMax(max_nr_digits, suffix.size());
}
+ /* if no match, use node name */
+ if(max_nr_digits == -1)
+ return node_name;
+ /* match of size 0, add "1" at the end */
+ if(max_nr_digits == 0)
+ return node_name + "1";
+ /* otherwise, pick next value */
+ return QString("%1%2").arg(node_name)
+ .arg(max_value + 1, max_nr_digits, 10, QChar('0'));
+}
+
+void NodeEditPanel::OnInstCreate()
+{
+ std::vector< soc_desc::instance_t >& inst_list = m_ref.get()->instance;
+ soc_desc::instance_t inst;
+ inst.id = GetFreshId(inst_list);
+ inst.name = GuessName().toStdString();
+ inst.type = soc_desc::instance_t::SINGLE;
+ inst.addr = 0;
+ inst.range.type = soc_desc::range_t::STRIDE;
+ inst.range.first = 0;
+ inst.range.count = 0;
+ inst.range.stride = 0;
+ inst_list.push_back(inst);
+ NodeInstanceEditPanel *p = new NodeInstanceEditPanel(m_ref, inst.id, this);
+ connect(p, SIGNAL(OnModified()), this, SLOT(OnInstModified()));
+ int idx = m_instances_tab->addTab(p, QString::fromStdString(inst.name));
+ m_instances_tab->setCurrentIndex(idx);
+ OnModified();
}
/**
- * FieldEditPanel
+ * RegFieldEditPanel
*/
-FieldEditPanel::FieldEditPanel(SocFieldRef ref, QWidget *parent)
+
+namespace
+{
+
+enum
+{
+ RegFieldEditPanelDelType = QTableWidgetItem::UserType,
+ RegFieldEditPanelAddType,
+};
+
+}
+
+RegFieldEditPanel::RegFieldEditPanel(const soc_desc::field_ref_t& 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_range_edit = new QLineEdit(this);
+ m_range_validator = new SocBitRangeValidator(this);
+ m_range_validator->setWidth(m_ref.reg().get()->width);
+ m_range_edit->setValidator(m_range_validator);
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&)));
+ QHBoxLayout *namepos_layout = new QHBoxLayout;
+ namepos_layout->addWidget(new QLabel("Name:"));
+ namepos_layout->addWidget(m_name_edit);
+ namepos_layout->addWidget(new QLabel("Range:"));
+ namepos_layout->addWidget(m_range_edit);
+ QVBoxLayout *nameposdesc_layout = new QVBoxLayout;
+ nameposdesc_layout->addWidget(Misc::EncloseInBox("Information", namepos_layout));
+ nameposdesc_layout->addWidget(Misc::EncloseInBox("Description", m_desc_edit));
+ nameposdesc_layout->addStretch(0);
+
+ m_enum_table = new QTableWidget(this);
+ m_enum_table->setColumnCount(4);
+ m_enum_table->setHorizontalHeaderItem(0, new QTableWidgetItem(""));
+ m_enum_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name"));
+ m_enum_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Value"));
+ m_enum_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Description"));
+ m_enum_table->verticalHeader()->setVisible(false);
+ m_enum_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ m_enum_delegate = new SocFieldItemDelegate(this);
+ m_enum_delegate->setItemEditorFactory(new QItemEditorFactory);
+ m_enum_editor = new SocFieldEditorCreator;
+ m_enum_delegate->itemEditorFactory()->registerEditor(QVariant::UInt, m_enum_editor);
+ m_enum_table->setItemDelegate(m_enum_delegate);
- setLayout(left_layout);
+ QHBoxLayout *field_layout = new QHBoxLayout;
+ field_layout->addLayout(nameposdesc_layout);
+ field_layout->addWidget(Misc::EncloseInBox("Special Values", m_enum_table), 1);
+
+ setLayout(field_layout);
+
+ const soc_desc::field_t& field = *m_ref.get();
+ m_name_edit->setText(QString::fromStdString(field.name));
+ m_range_edit->setText(m_range_validator->generate(
+ field.pos + field.width - 1, field.pos));
+ m_desc_edit->SetTextHtml(QString::fromStdString(field.desc));
+ m_enum_delegate->setWidth(field.width);
+ m_enum_editor->setWidth(field.width);
+ m_enum_table->setRowCount(field.enum_.size() + 1);
+ for(size_t i = 0; i < field.enum_.size(); i++)
+ {
+ QTableWidgetItem *item = new QTableWidgetItem(
+ QIcon::fromTheme("list-remove"), "", RegFieldEditPanelDelType);
+ item->setFlags(Qt::ItemIsEnabled);
+ m_enum_table->setItem(i, 0, item);
+ item = new QTableWidgetItem(QString::fromStdString(field.enum_[i].name));
+ m_enum_table->setItem(i, 1, item);
+ item = new QTableWidgetItem();
+ item->setData(Qt::EditRole, QVariant(field.enum_[i].value));
+ m_enum_table->setItem(i, 2, item);
+ item = new QTableWidgetItem(QString::fromStdString(field.enum_[i].desc));
+ m_enum_table->setItem(i, 3, item);
+ }
+ QTableWidgetItem *new_item = new QTableWidgetItem(
+ QIcon::fromTheme("list-add"), "", RegFieldEditPanelAddType);
+ new_item->setFlags(Qt::ItemIsEnabled);
+ m_enum_table->setItem(field.enum_.size(), 0, new_item);
+ new_item = new QTableWidgetItem("New field...");
+ new_item->setFlags(Qt::ItemIsEnabled);
+ QFont font = new_item->font();
+ font.setItalic(true);
+ new_item->setFont(font);
+ m_enum_table->setItem(field.enum_.size(), 1, new_item);
+ new_item = new QTableWidgetItem();
+ new_item->setFlags(Qt::ItemIsEnabled);
+ m_enum_table->setItem(field.enum_.size(), 2, new_item);
+ new_item = new QTableWidgetItem();
+ new_item->setFlags(Qt::ItemIsEnabled);
+ m_enum_table->setItem(field.enum_.size(), 3, new_item);
+ m_enum_table->resizeColumnsToContents();
+ m_enum_table->horizontalHeader()->setStretchLastSection(true);
+
+ connect(m_name_edit, SIGNAL(textChanged(const QString&)), this,
+ SLOT(OnFieldNameChanged(const QString&)));
+ connect(m_range_edit, SIGNAL(textChanged(const QString&)), this,
+ SLOT(OnFieldRangeChanged(const QString&)));
+ connect(m_desc_edit, SIGNAL(OnTextChanged(const QString&)), this,
+ SLOT(OnFieldDescChanged(const QString&)));
+ connect(m_enum_table, SIGNAL(itemActivated(QTableWidgetItem *)), this,
+ SLOT(OnFieldValueActivated(QTableWidgetItem *)));
+ connect(m_enum_table, SIGNAL(itemChanged(QTableWidgetItem *)), this,
+ SLOT(OnFieldValueChanged(QTableWidgetItem *)));
}
-void FieldEditPanel::UpdateDelegates()
+void RegFieldEditPanel::UpdateWidth()
{
- 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();
+ m_range_validator->setWidth(m_ref.reg().get()->width);
}
-void FieldEditPanel::UpdateWarning(int row)
+void RegFieldEditPanel::OnFieldValueActivated(QTableWidgetItem *item)
{
- 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)
+ if(item->type() == RegFieldEditPanelDelType)
{
- item->setIcon(QIcon::fromTheme("dialog-warning"));
- item->setToolTip("Value is too big for the field");
+ int row = item->row();
+ my_remove_at(m_ref.get()->enum_, row);
+ m_enum_table->removeRow(row);
+ OnModified();
}
- else
+ else if(item->type() == RegFieldEditPanelAddType)
{
- item->setIcon(QIcon());
- item->setToolTip("");
+ soc_desc::field_t& field = *m_ref.get();
+ int row = field.enum_.size();
+ soc_desc::enum_t new_enum;
+ new_enum.id = GetFreshId(field.enum_);
+ new_enum.name = "UNNAMED";
+ new_enum.value = 0;
+ field.enum_.push_back(new_enum);
+ m_enum_table->insertRow(row);
+ QTableWidgetItem *item = new QTableWidgetItem(
+ QIcon::fromTheme("list-remove"), "", RegFieldEditPanelDelType);
+ item->setFlags(Qt::ItemIsEnabled);
+ m_enum_table->setItem(row, 0, item);
+ item = new QTableWidgetItem(QString::fromStdString(new_enum.name));
+ m_enum_table->setItem(row, 1, item);
+ item = new QTableWidgetItem();
+ item->setData(Qt::EditRole, QVariant(new_enum.value));
+ m_enum_table->setItem(row, 2, item);
+ item = new QTableWidgetItem(QString::fromStdString(new_enum.desc));
+ m_enum_table->setItem(row, 3, item);
+ OnModified();
}
}
-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 RegFieldEditPanel::OnFieldValueChanged(QTableWidgetItem *item)
+{
+ soc_desc::field_t& field = *m_ref.get();
+ if((size_t)item->row() >= field.enum_.size())
+ return;
+ soc_desc::enum_t& enum_ = field.enum_[item->row()];
+ if(item->column() == 1)
+ enum_.name = item->text().toStdString();
+ else if(item->column() == 2)
+ enum_.value = item->data(Qt::EditRole).value< soc_word_t >();
+ else if(item->column() == 3)
+ enum_.desc = item->text().toStdString();
+ OnModified();
+}
+
+void RegFieldEditPanel::OnFieldNameChanged(const QString& name)
+{
+ m_ref.get()->name = name.toStdString();
+ OnModified();
}
-void FieldEditPanel::OnBitRangeEdited(const QString& input)
+void RegFieldEditPanel::OnFieldRangeChanged(const QString& range)
{
- 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)
+ soc_desc::field_t *field = m_ref.get();
+ int last, first;
+ if(m_range_validator->parse(range, last, first) != 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);
+ field->pos = first;
+ field->width = last - first + 1;
+ m_enum_delegate->setWidth(field->width);
+ m_enum_editor->setWidth(field->width);
+ OnModified();
}
-void FieldEditPanel::OnNameEdited(const QString& text)
+void RegFieldEditPanel::OnFieldDescChanged(const QString& desc)
{
- m_ref.GetField().name = text.toStdString();
- OnModified(m_name_edit->isModified());
+ m_ref.get()->desc = desc.toStdString();
+ OnModified();
}
-void FieldEditPanel::OnDescEdited()
+soc_desc::field_ref_t RegFieldEditPanel::GetField()
{
- m_ref.GetField().desc = m_desc_edit->GetTextHtml().toStdString();
- OnModified(m_desc_edit->IsModified());
+ return m_ref;
}
-void FieldEditPanel::OnValueActivated(int row, int column)
+/**
+ * RegEditPanel
+ */
+
+namespace
{
- if(column != 0)
- return;
- int type = m_value_table->item(row, column)->type();
- if(type == FieldValueDeleteType)
+
+enum
+{
+ RegVariantEditPanelDelType = QTableWidgetItem::UserType,
+ RegVariantEditPanelAddType,
+};
+
+}
+
+RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent)
+ :QWidget(parent), m_ref(ref), m_reg_font(font())
+{
+ m_reg_font.setWeight(100);
+ m_reg_font.setKerning(false);
+
+ m_value_model = new RegFieldTableModel(this); // view takes ownership
+ m_value_model->SetRegister(*ref.get());
+ m_value_model->SetReadOnly(true);
+
+ m_sexy_display2 = new Unscroll<YRegDisplay>(this);
+ m_sexy_display2->setFont(m_reg_font);
+ m_sexy_display2->setModel(m_value_model);
+ m_sexy_display2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ m_sexy_display2->setContextMenuPolicy(Qt::CustomContextMenu);
+ m_sexy_display2->setWidth(m_ref.get()->width);
+
+ m_view_tab = new QTabWidget(this);
+ m_view_tab->setTabPosition(QTabWidget::West);
+
+ /* field tab */
+ m_fields_tab = new YTabWidget(0, this);
+ m_fields_tab->setTabOpenable(true);
+ std::vector< soc_desc::field_ref_t > field_list = m_ref.fields();
+ m_fields_tab->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
+ m_fields_tab->setTabsClosable(true);
+ m_fields_tab->setElideMode(Qt::ElideRight);
+ for(size_t i = 0; i < field_list.size(); i++)
{
- m_ref.GetField().value.erase(m_ref.GetField().value.begin() + row);
- m_value_table->removeRow(row);
- OnModified(true);
+ RegFieldEditPanel *p = new RegFieldEditPanel(field_list[i], this);
+ connect(p, SIGNAL(OnModified()), this, SLOT(OnFieldModified()));
+ m_fields_tab->addTab(p, QString::fromStdString(field_list[i].get()->name));
}
- else if(type == FieldValueNewType)
+
+ m_reg_size_group = new QButtonGroup(this);
+ QRadioButton *reg_size_32 = new QRadioButton("32-bit");
+ QRadioButton *reg_size_16 = new QRadioButton("16-bit");
+ QRadioButton *reg_size_8 = new QRadioButton("8-bit");
+ m_reg_size_group->addButton(reg_size_32, 32);
+ m_reg_size_group->addButton(reg_size_16, 16);
+ m_reg_size_group->addButton(reg_size_8, 8);
+ if(m_reg_size_group->button(m_ref.get()->width))
+ m_reg_size_group->button(m_ref.get()->width)->click();
+ QVBoxLayout *width_group_layout = new QVBoxLayout;
+ width_group_layout->addWidget(reg_size_32);
+ width_group_layout->addWidget(reg_size_16);
+ width_group_layout->addWidget(reg_size_8);
+ width_group_layout->addStretch(0);
+ QGroupBox *width_group = new QGroupBox("Width");
+ width_group->setLayout(width_group_layout);
+
+ m_variant_table = new QTableWidget;
+ m_variant_table->setColumnCount(3);
+ m_variant_table->setHorizontalHeaderItem(0, new QTableWidgetItem(""));
+ m_variant_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Type"));
+ m_variant_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Offset"));
+ m_variant_table->verticalHeader()->setVisible(false);
+ m_variant_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ m_variant_delegate = new SocFieldItemDelegate(this);
+ m_variant_delegate->setItemEditorFactory(new QItemEditorFactory);
+ m_variant_editor = new SocFieldEditorCreator;
+ m_variant_delegate->itemEditorFactory()->registerEditor(QVariant::UInt, m_variant_editor);
+ m_variant_table->setItemDelegate(m_variant_delegate);
+
+ std::vector< soc_desc::variant_ref_t > variants = m_ref.variants();
+ m_variant_table->setRowCount(variants.size() + 1);
+ for(size_t i = 0; i < variants.size(); i++)
{
- 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);
+ QTableWidgetItem *item = new QTableWidgetItem(
+ QIcon::fromTheme("list-remove"), "", RegVariantEditPanelDelType);
+ item->setFlags(Qt::ItemIsEnabled);
+ m_variant_table->setItem(i, 0, item);
+ item = new QTableWidgetItem(QString::fromStdString(variants[i].get()->type));
+ m_variant_table->setItem(i, 1, item);
+ item = new QTableWidgetItem();
+ item->setData(Qt::EditRole, QVariant(variants[i].get()->offset));
+ m_variant_table->setItem(i, 2, item);
}
+ QTableWidgetItem *new_item = new QTableWidgetItem(
+ QIcon::fromTheme("list-add"), "", RegVariantEditPanelAddType);
+ new_item->setFlags(Qt::ItemIsEnabled);
+ m_variant_table->setItem(variants.size(), 0, new_item);
+ new_item = new QTableWidgetItem("New variant...");
+ new_item->setFlags(Qt::ItemIsEnabled);
+ QFont font = new_item->font();
+ font.setItalic(true);
+ new_item->setFont(font);
+ m_variant_table->setItem(variants.size(), 1, new_item);
+ new_item = new QTableWidgetItem();
+ new_item->setFlags(Qt::ItemIsEnabled);
+ m_variant_table->setItem(variants.size(), 2, new_item);
+ new_item = new QTableWidgetItem();
+ new_item->setFlags(Qt::ItemIsEnabled);
+ m_variant_table->resizeColumnsToContents();
+ m_variant_table->horizontalHeader()->setStretchLastSection(true);
+
+ m_desc_edit = new MyTextEditor(this);
+ m_desc_edit->SetTextHtml(QString::fromStdString(ref.get()->desc));
+
+ QHBoxLayout *top_info_layout = new QHBoxLayout;
+ top_info_layout->addWidget(width_group);
+ top_info_layout->addWidget(Misc::EncloseInBox("Variants", m_variant_table));
+ top_info_layout->addWidget(Misc::EncloseInBox("Description", m_desc_edit));
+
+ QWidget *reg_info = new QWidget(this);
+ QVBoxLayout *reg_info_layout = new QVBoxLayout;
+ reg_info_layout->addLayout(top_info_layout);
+ reg_info_layout->addStretch(0);
+ reg_info->setLayout(reg_info_layout);
+
+ m_view_tab->addTab(reg_info, "Information");
+ m_view_tab->addTab(m_fields_tab, "Fields");
+
+ QVBoxLayout *main_layout = new QVBoxLayout;
+ main_layout->addWidget(m_sexy_display2, 1);
+ main_layout->addWidget(m_view_tab, 2);
+
+ m_delete_action = new QAction("&Delete", this);
+ m_delete_action->setIcon(QIcon::fromTheme("list-remove"));
+ m_new_action = new QAction("&New field", this);
+ m_new_action->setIcon(QIcon::fromTheme("list-add"));
+
+ setLayout(main_layout);
+
+ OnRegFieldActivated(QModelIndex());
+ UpdateWidthRestrictions();
+
+ connect(m_sexy_display2, SIGNAL(clicked(const QModelIndex&)), this,
+ SLOT(OnRegFieldActivated(const QModelIndex&)));
+ connect(m_sexy_display2, SIGNAL(customContextMenuRequested(QPoint)), this,
+ SLOT(OnRegDisplayContextMenu(QPoint)));
+ connect(m_reg_size_group, SIGNAL(buttonClicked(int)), this, SLOT(OnWidthChanged(int)));
+ connect(m_delete_action, SIGNAL(triggered()), this, SLOT(OnRegFieldDelete()));
+ connect(m_new_action, SIGNAL(triggered()), this, SLOT(OnRegFieldNew()));
+ connect(m_variant_table, SIGNAL(itemActivated(QTableWidgetItem *)), this,
+ SLOT(OnVariantActivated(QTableWidgetItem *)));
+ connect(m_variant_table, SIGNAL(itemChanged(QTableWidgetItem *)), this,
+ SLOT(OnVariantValueChanged(QTableWidgetItem *)));
+ connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited()));
+ connect(m_fields_tab, SIGNAL(tabCloseRequested(int)), this, SLOT(OnFieldRemove(int)));
+ connect(m_fields_tab, SIGNAL(tabOpenRequested()), this, SLOT(OnFieldCreate()));
}
-void FieldEditPanel::OnValueChanged(int row, int column)
+void RegEditPanel::UpdateWidthRestrictions()
{
- /* 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)
+ /* only allow width large enough to fit all fields */
+ size_t max_bit = 0;
+ std::vector< soc_desc::field_ref_t > field_list = m_ref.fields();
+ for(size_t i = 0; i < field_list.size(); i++)
{
- 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);
- }
+ soc_desc::field_t& f = *field_list[i].get();
+ max_bit = std::max(max_bit, f.pos + f.width - 1);
}
- else if(column == FieldValueDescColumn)
- m_ref.GetField().value[row].desc = item->text().toStdString();
- OnModified(true);
+ /* update buttons */
+ m_reg_size_group->button(8)->setEnabled(max_bit < 8);
+ m_reg_size_group->button(16)->setEnabled(max_bit < 16);
+ m_reg_size_group->button(32)->setEnabled(max_bit < 32);
}
-namespace
+int RegEditPanel::IndexById(soc_id_t id)
{
+ for(int i = 0; i < m_fields_tab->count(); i++)
+ {
+ RegFieldEditPanel *p = dynamic_cast< RegFieldEditPanel * >(m_fields_tab->widget(i));
+ if(p->GetField().get()->id == id)
+ return i;
+ }
+ return -1;
+}
-enum
+void RegEditPanel::OnWidthChanged(int w)
{
- SocTreeSocType = QTreeWidgetItem::UserType,
- SocTreeDevType,
- SocTreeRegType,
- SocTreeFieldType,
- SocTreeNewDevType,
- SocTreeNewRegType,
- SocTreeNewFieldType,
-};
-
-/**
- * SocTreeItem
- */
+ m_ref.get()->width = w;
+ m_sexy_display2->setWidth(w);
+ for(int i = 0; i < m_fields_tab->count(); i++)
+ dynamic_cast< RegFieldEditPanel * >(m_fields_tab->widget(i))->UpdateWidth();
+ OnModified();
+}
-class SocTreeItem : public QTreeWidgetItem
+void RegEditPanel::OnDescEdited()
{
-public:
- SocTreeItem(const QString& string, const SocRef& ref)
- :QTreeWidgetItem(QStringList(string), SocTreeSocType), m_ref(ref) {}
+ m_ref.get()->desc = m_desc_edit->GetTextHtml().toStdString();
+ OnModified();
+}
- const SocRef& GetRef() { return m_ref; }
-private:
- SocRef m_ref;
-};
+void RegEditPanel::OnVariantActivated(QTableWidgetItem *item)
+{
+ if(item->type() == RegVariantEditPanelDelType)
+ {
+ int row = item->row();
+ my_remove_at(m_ref.get()->variant, row);
+ m_variant_table->removeRow(row);
+ OnModified();
+ }
+ else if(item->type() == RegVariantEditPanelAddType)
+ {
+ int row = m_ref.get()->variant.size();
+ soc_desc::variant_t& variant = *m_ref.create_variant().get();
+ variant.type = "untyped";
+ variant.offset = 0;
+ m_variant_table->insertRow(row);
+ QTableWidgetItem *item = new QTableWidgetItem(
+ QIcon::fromTheme("list-remove"), "", RegVariantEditPanelDelType);
+ item->setFlags(Qt::ItemIsEnabled);
+ m_variant_table->setItem(row, 0, item);
+ item = new QTableWidgetItem(QString::fromStdString(variant.type));
+ m_variant_table->setItem(row, 1, item);
+ item = new QTableWidgetItem();
+ item->setData(Qt::EditRole, QVariant(variant.offset));
+ m_variant_table->setItem(row, 2, item);
+ OnModified();
+ }
+}
-/**
- * NewDevTreeItem
- */
+void RegEditPanel::OnVariantValueChanged(QTableWidgetItem *item)
+{
+ soc_desc::register_t& reg = *m_ref.get();
+ if((size_t)item->row() >= reg.variant.size())
+ return;
+ soc_desc::variant_t& var = reg.variant[item->row()];
+ if(item->column() == 1)
+ var.type = item->text().toStdString();
+ else if(item->column() == 2)
+ var.offset = item->data(Qt::EditRole).value< soc_word_t >();
+ OnModified();
+}
-class NewDevTreeItem : public QTreeWidgetItem
+void RegEditPanel::OnRegFieldActivated(const QModelIndex& index)
{
-public:
- NewDevTreeItem(const QString& string, const SocRef& ref)
- :QTreeWidgetItem(QStringList(string), SocTreeNewDevType), m_ref(ref) {}
+ if(!index.isValid())
+ return;
+ m_fields_tab->setCurrentIndex(IndexById(m_ref.get()->field[index.row()].id));
+ m_view_tab->setCurrentIndex(1);
+}
- const SocRef& GetRef() { return m_ref; }
-private:
- SocRef m_ref;
-};
+void RegEditPanel::OnFieldModified()
+{
+ int idx = m_fields_tab->currentIndex();
+ RegFieldEditPanel *p = dynamic_cast< RegFieldEditPanel * >(m_fields_tab->widget(idx));
+ m_fields_tab->setTabText(idx, QString::fromStdString(p->GetField().get()->name));
+ DoModify();
+}
-/**
- * DevTreeItem
- */
+void RegEditPanel::DoModify()
+{
+ m_value_model->UpdateRegister(*m_ref.get());
+ UpdateWidthRestrictions();
+ OnModified();
+}
-class DevTreeItem : public QTreeWidgetItem
+void RegEditPanel::OnRegFieldDelete()
{
-public:
- DevTreeItem(const QString& string, const SocDevRef& ref)
- :QTreeWidgetItem(QStringList(string), SocTreeDevType), m_ref(ref) {}
+ QModelIndex current = m_sexy_display2->currentIndex();
+ if(!current.isValid())
+ return;
+ QMessageBox msgbox(QMessageBox::Question, "Delete field ?",
+ "Are you sure you want to delete this field ?",
+ QMessageBox::Yes | QMessageBox::No, this);
+ msgbox.setDefaultButton(QMessageBox::No);
+ int ret = msgbox.exec();
+ if(ret != QMessageBox::Yes)
+ return;
+ m_fields_tab->removeTab(IndexById(m_ref.get()->field[current.row()].id));
+ my_remove_at(m_ref.get()->field, current.row());
+ DoModify();
+ OnRegFieldActivated(QModelIndex());
+}
- const SocDevRef& GetRef() { return m_ref; }
-private:
- SocDevRef m_ref;
-};
+void RegEditPanel::OnFieldRemove(int index)
+{
+ Q_UNUSED(index);
+}
-/**
- * NewRegTreeItem
- */
+int RegEditPanel::FindFreeBit(int preferred)
+{
+ int nr_bits = m_ref.get()->width;
+ soc_word_t free_mask = (nr_bits == 32) ? 0xffffffff : (1 << nr_bits) - 1;
+ soc_desc::register_t& reg = *m_ref.get();
+ for(size_t i = 0; i < reg.field.size(); i++)
+ free_mask &= ~reg.field[i].bitmask();
+ /* any space ? */
+ if(free_mask == 0)
+ return -1;
+ int closest_bit = -1;
+ int closest_dist = nr_bits;
+ for(int bit = 0; bit < nr_bits; bit++)
+ {
+ if(!(free_mask & (1 << bit)))
+ continue;
+ if(abs(bit - preferred) < closest_dist)
+ {
+ closest_bit = bit;
+ closest_dist = abs(bit - preferred);
+ }
+ }
+ return closest_bit;
+}
-class NewRegTreeItem : public QTreeWidgetItem
+void RegEditPanel::OnRegFieldNew()
{
-public:
- NewRegTreeItem(const QString& string, const SocDevRef& ref)
- :QTreeWidgetItem(QStringList(string), SocTreeNewRegType), m_ref(ref) {}
+ int bit_col = m_sexy_display2->bitColumnAt(m_menu_point);
+ /* we need to make sure the created field does not overlap something */
+ bit_col = FindFreeBit(bit_col);
+ if(bit_col == -1)
+ return; /* impossible to find a free position */
+ soc_desc::field_ref_t ref = m_ref.create_field();
+ soc_desc::field_t& field = *ref.get();
+ field.pos = bit_col;
+ field.width = 1;
+ field.name = "UNNAMED";
- const SocDevRef& GetRef() { return m_ref; }
-private:
- SocDevRef m_ref;
-};
+ RegFieldEditPanel *p = new RegFieldEditPanel(ref, this);
+ connect(p, SIGNAL(OnModified()), this, SLOT(OnFieldModified()));
+ m_fields_tab->addTab(p, QString::fromStdString(field.name));
-/**
- * RegTreeItem
- */
+ DoModify();
+}
-class RegTreeItem : public QTreeWidgetItem
+void RegEditPanel::OnFieldCreate()
{
-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;
-};
+ OnRegFieldNew();
+}
-/**
- * NewFieldTreeItem
- */
+void RegEditPanel::OnRegDisplayContextMenu(QPoint point)
+{
+ m_menu_point = point;
+ QMenu *menu = new QMenu(this);
+ QModelIndex item = m_sexy_display2->indexAt(point);
+ menu->addAction(m_new_action);
+ if(item.isValid())
+ menu->addAction(m_delete_action);
+ menu->popup(m_sexy_display2->viewport()->mapToGlobal(point));
+}
-class NewFieldTreeItem : public QTreeWidgetItem
+namespace
{
-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;
+enum
+{
+ SocTreeSocType = QTreeWidgetItem::UserType, // SocRefRole -> node_ref_t to root
+ SocTreeNodeType, // SocRefRole -> node_ref_t
+ SocTreeRegType, // SocRefRole -> register_ref_t
};
-/**
- * FieldTreeItem
- */
+enum
+{
+ SocRefRole = Qt::UserRole,
+};
-class FieldTreeItem : public QTreeWidgetItem
+template<typename T>
+T SocTreeItemVal(QTreeWidgetItem *item)
{
-public:
- FieldTreeItem(const QString& string, const SocFieldRef& ref)
- :QTreeWidgetItem(QStringList(string), SocTreeFieldType), m_ref(ref) {}
+ return item->data(0, SocRefRole).value<T>();
+}
- const SocFieldRef& GetRef() { return m_ref; }
-private:
- SocFieldRef m_ref;
-};
+template<typename T>
+QTreeWidgetItem *MakeSocTreeItem(int type, const T& val)
+{
+ QTreeWidgetItem *item = new QTreeWidgetItem(type);
+ item->setData(0, SocRefRole, QVariant::fromValue(val));
+ return item;
+}
}
@@ -903,8 +1341,7 @@ 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();
+ QLabel *file_static = new QLabel("File:");
m_file_edit = new QLineEdit(this);
m_file_edit->setReadOnly(true);
m_file_open = new QToolButton(this);
@@ -913,33 +1350,53 @@ RegEdit::RegEdit(Backend *backend, QWidget *parent)
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->setPopupMode(QToolButton::MenuButtonPopup);
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);
+ m_file_save->setPopupMode(QToolButton::MenuButtonPopup);
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);
+
+ QHBoxLayout *file_group_layout = new QHBoxLayout();
+ file_group_layout->addWidget(m_file_open);
+ file_group_layout->addWidget(m_file_save);
+ file_group_layout->addWidget(file_static);
+ 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_soc_tree->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ m_delete_action = new QAction("&Delete", this);
+ m_delete_action->setIcon(QIcon::fromTheme("list-remove"));
+ m_new_action = new QAction("&New", this);
+ m_new_action->setIcon(QIcon::fromTheme("list-add"));
+ m_create_action = new QAction("&Create register", this);
+ m_create_action->setIcon(QIcon::fromTheme("folder-new"));
+
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_msg = new MessageWidget(this);
+ QWidget *splitter_right = new QWidget(this);
+ m_right_panel_layout = new QVBoxLayout;
+ m_right_panel_layout->addWidget(m_msg, 0);
+ splitter_right->setLayout(m_right_panel_layout);
+ m_splitter->addWidget(splitter_right);
+ m_splitter->setStretchFactor(1, 2);
+
+ m_msg_welcome_id = SetMessage(MessageWidget::Information,
+ "Open a description file to edit, or create a new file from scratch.");
+ m_msg_name_error_id = 0;
+
+ m_vert_layout->addLayout(file_group_layout);
m_vert_layout->addWidget(m_splitter, 1);
setLayout(m_vert_layout);
@@ -949,14 +1406,17 @@ RegEdit::RegEdit(Backend *backend, QWidget *parent)
SetPanel(new EmptyEditPanel(this));
UpdateTabName();
+ connect(m_soc_tree, SIGNAL(customContextMenuRequested(QPoint)), this,
+ SLOT(OnSocTreeContextMenu(QPoint)));
+ connect(m_delete_action, SIGNAL(triggered()), this, SLOT(OnSocItemDelete()));
+ connect(m_new_action, SIGNAL(triggered()), this, SLOT(OnSocItemNew()));
+ connect(m_create_action, SIGNAL(triggered()), this, SLOT(OnSocItemCreate()));
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()
@@ -968,6 +1428,16 @@ RegEdit::~RegEdit()
{
}
+int RegEdit::SetMessage(MessageWidget::MessageType type, const QString& msg)
+{
+ return m_msg->SetMessage(type, msg);
+}
+
+void RegEdit::HideMessage(int id)
+{
+ m_msg->HideMessage(id);
+}
+
void RegEdit::OnSave()
{
SaveSoc();
@@ -1007,7 +1477,10 @@ 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 (*)");
+ QStringList filters;
+ filters << "Description files (*.xml)";
+ filters << "All files (*)";
+ fd->setNameFilters(filters);
fd->setDirectory(Settings::Get()->value("regedit/loaddescdir", QDir::currentPath()).toString());
if(fd->exec())
{
@@ -1051,15 +1524,15 @@ void RegEdit::OnNew()
bool RegEdit::SaveSocFile(const QString& filename)
{
- normalize(m_cur_socfile.GetSoc());
- if(!produce_xml(filename.toStdString(), m_cur_socfile.GetSoc()))
+ soc_desc::error_context_t ctx;
+ soc_desc::normalize(m_cur_socfile.GetSoc());
+ if(!soc_desc::produce_xml(filename.toStdString(), m_cur_socfile.GetSoc(), ctx))
{
QMessageBox::warning(this, "The description was not saved",
"There was an error when saving the file");
return false;
}
- m_soc_tree->clear();
- FillSocTree();
+ UpdateSocFile();
SetModified(false, false);
return true;
}
@@ -1086,91 +1559,39 @@ void RegEdit::LoadSocFile(const QString& filename)
SetModified(false, false);
UpdateSocFile();
UpdateTabName();
+ m_msg_welcome_id = SetMessage(MessageWidget::Information,
+ "Select items to edit in tree, or right-click on them to see available actions.");
}
-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)
+void RegEdit::FillNodeTreeItem(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++)
+ soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(item);
+ soc_desc::register_ref_t reg = node.reg();
+ /* put register if there, otherwise offer to create one */
+ if(reg.valid() && reg.node() == node)
{
- 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);
+ QTreeWidgetItem *reg_item = MakeSocTreeItem(SocTreeRegType, reg);
+ FixupItem(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++)
+ std::vector< soc_desc::node_ref_t > list = node.children();
+ for(size_t i = 0; i < list.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);
+ QTreeWidgetItem *node_item = MakeSocTreeItem(SocTreeNodeType, list[i]);
+ FixupItem(node_item);
+ FillNodeTreeItem(node_item);
+ item->addChild(node_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);
+ soc_desc::soc_ref_t ref = m_cur_socfile.GetSocRef();
+ QTreeWidgetItem *root_item = MakeSocTreeItem(SocTreeSocType, ref.root());
+ FixupItem(root_item);
+ FillNodeTreeItem(root_item);
+ m_soc_tree->addTopLevelItem(root_item);
+ root_item->setExpanded(true);
}
void RegEdit::MakeItalic(QTreeWidgetItem *item, bool it)
@@ -1180,17 +1601,46 @@ void RegEdit::MakeItalic(QTreeWidgetItem *item, bool it)
item->setFont(0, font);
}
-void RegEdit::FixupEmptyItem(QTreeWidgetItem *item)
+QIcon RegEdit::GetIconFromType(int type)
+{
+ switch(type)
+ {
+ case SocTreeSocType: return QIcon::fromTheme("computer");
+ case SocTreeNodeType: return QIcon::fromTheme("cpu");
+ case SocTreeRegType: return style()->standardIcon(QStyle::SP_ArrowRight);
+ default: return QIcon();
+ }
+}
+
+bool RegEdit::ValidateName(const QString& name)
{
- if(item->text(0).size() == 0)
+ if(name.size() == 0)
+ return false;
+ for(int i = 0; i < name.size(); i++)
+ if(!name[i].isLetterOrNumber() && name[i] != QChar('_'))
+ return false;
+ return true;
+}
+
+void RegEdit::FixupItem(QTreeWidgetItem *item)
+{
+ UpdateName(item);
+ if(!ValidateName(item->text(0)))
{
item->setIcon(0, QIcon::fromTheme("dialog-error"));
- MakeItalic(item, true);
- item->setText(0, "Unnamed");
+ if(item->text(0).size() == 0)
+ {
+ MakeItalic(item, true);
+ item->setText(0, "Unnamed");
+ }
+ m_msg_name_error_id = SetMessage(MessageWidget::Error,
+ "The item name is invalid. It must be non-empty and consists only "
+ "of alphanumerical or underscore characters");
}
else
{
- item->setIcon(0, QIcon::fromTheme("cpu"));
+ HideMessage(m_msg_name_error_id);
+ item->setIcon(0, GetIconFromType(item->type()));
MakeItalic(item, false);
}
}
@@ -1206,9 +1656,9 @@ 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);
+ connect(m_right_panel, SIGNAL(OnModified()), this,
+ SLOT(OnSocModified()));
+ m_right_panel_layout->addWidget(m_right_panel, 1);
}
void RegEdit::SetModified(bool add, bool mod)
@@ -1217,15 +1667,33 @@ void RegEdit::SetModified(bool add, bool mod)
OnModified(mod);
}
-namespace
-{
-
-template< typename T >
-void my_remove_at(std::vector< T >& v, size_t at)
+void RegEdit::OnSocItemNew()
{
- v.erase(v.begin() + at);
+ QTreeWidgetItem *current = m_soc_tree->currentItem();
+ if(current == 0)
+ return;
+ soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(current);
+ node = node.create();
+ node.get()->name = "unnamed";
+ QTreeWidgetItem *node_item = MakeSocTreeItem(SocTreeNodeType, node);
+ FixupItem(node_item);
+ current->addChild(node_item);
+ m_soc_tree->setCurrentItem(node_item);
}
+void RegEdit::OnSocItemCreate()
+{
+ QTreeWidgetItem *current = m_soc_tree->currentItem();
+ if(current == 0)
+ return;
+ soc_desc::register_t reg;
+ reg.width = 32;
+ soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(current);
+ node.get()->register_.push_back(reg);
+ QTreeWidgetItem *reg_item = MakeSocTreeItem(SocTreeRegType, node.reg());
+ FixupItem(reg_item);
+ current->insertChild(0, reg_item);
+ m_soc_tree->setCurrentItem(reg_item);
}
void RegEdit::OnSocItemDelete()
@@ -1242,172 +1710,116 @@ void RegEdit::OnSocItemDelete()
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);
+ SocTreeItemVal< soc_desc::node_ref_t >(current).remove();
+ current->takeChildren();
+ OnSocModified();
}
- else if(current->type() == SocTreeDevType)
+ else if(current->type() == SocTreeNodeType)
{
- 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);
+ SocTreeItemVal< soc_desc::node_ref_t >(current).remove();
+ current->parent()->removeChild(current);
+ OnSocModified();
}
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);
+ SocTreeItemVal< soc_desc::register_ref_t >(current).remove();
+ current->parent()->removeChild(current);
+ OnSocModified();
}
}
-void RegEdit::OnSocModified(bool modified)
+void RegEdit::OnSocModified()
{
// we might need to update the name in the tree
- UpdateName(m_soc_tree->currentItem());
- if(modified)
- SetModified(true, true);
+ FixupItem(m_soc_tree->currentItem());
+ SetModified(true, true);
}
-void RegEdit::DisplaySoc(SocRef ref)
+void RegEdit::DisplaySoc(const soc_desc::soc_ref_t& ref)
{
SetPanel(new SocEditPanel(ref, this));
}
-void RegEdit::DisplayDev(SocDevRef ref)
+void RegEdit::DisplayNode(const soc_desc::node_ref_t& ref)
{
- SetPanel(new DevEditPanel(ref, this));
+ SetPanel(new NodeEditPanel(ref, this));
}
-void RegEdit::DisplayReg(SocRegRef ref)
+void RegEdit::DisplayReg(const soc_desc::register_ref_t& 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));
+ current->setText(0, QString::fromStdString(
+ SocTreeItemVal< soc_desc::node_ref_t >(current).soc().get()->name));
}
- else if(current->type() == SocTreeDevType)
+ else if(current->type() == SocTreeNodeType)
{
- DevTreeItem *item = dynamic_cast< DevTreeItem * >(current);
- item->setText(0, QString::fromStdString(item->GetRef().GetDev().name));
+ current->setText(0, QString::fromStdString(
+ SocTreeItemVal< soc_desc::node_ref_t >(current).get()->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));
+ current->setText(0, "register");
}
- FixupEmptyItem(current);
}
-void RegEdit::OnSocItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
+void RegEdit::OnSocTreeContextMenu(QPoint point)
{
- Q_UNUSED(previous);
- if(current == 0)
+ HideMessage(m_msg_welcome_id);
+ QTreeWidgetItem *item = m_soc_tree->itemAt(point);
+ if(item == 0)
return;
- if(current->type() == SocTreeSocType)
- {
- SocTreeItem *item = dynamic_cast< SocTreeItem * >(current);
- DisplaySoc(item->GetRef());
- }
- else if(current->type() == SocTreeDevType)
+ /* customise messages with item */
+ m_action_item = item;
+ QMenu *menu = new QMenu(this);
+ switch(item->type())
{
- 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());
+ case SocTreeSocType:
+ m_new_action->setText("New node...");
+ m_delete_action->setText("Delete all nodes...");
+ menu->addAction(m_new_action);
+ menu->addAction(m_delete_action);
+ break;
+ case SocTreeNodeType:
+ {
+ m_new_action->setText("New node...");
+ m_delete_action->setText("Delete node...");
+ soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(item);
+ if(node.reg().node() != node)
+ menu->addAction(m_create_action);
+ menu->addAction(m_new_action);
+ menu->addAction(m_delete_action);
+ break;
+ }
+ case SocTreeRegType:
+ m_delete_action->setText("Delete register...");
+ menu->addAction(m_new_action);
+ menu->addAction(m_delete_action);
+ break;
}
+ menu->popup(m_soc_tree->viewport()->mapToGlobal(point));
}
-void RegEdit::OnSocItemActivated(QTreeWidgetItem *current, int column)
+void RegEdit::OnSocItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
- Q_UNUSED(column);
+ Q_UNUSED(previous);
+ HideMessage(m_msg_welcome_id);
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);
+ if(current->type() == SocTreeSocType)
+ DisplaySoc(SocTreeItemVal< soc_desc::node_ref_t >(current).soc());
+ else if(current->type() == SocTreeNodeType)
+ DisplayNode(SocTreeItemVal< soc_desc::node_ref_t >(current));
+ else if(current->type() == SocTreeRegType)
+ DisplayReg(SocTreeItemVal< soc_desc::register_ref_t >(current));
}
bool RegEdit::Quit()