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