diff options
Diffstat (limited to 'utils/regtools/qeditor/regedit.cpp')
-rw-r--r-- | utils/regtools/qeditor/regedit.cpp | 2222 |
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 @@ | |||
24 | #include <QHeaderView> | 24 | #include <QHeaderView> |
25 | #include <QMessageBox> | 25 | #include <QMessageBox> |
26 | #include <QInputDialog> | 26 | #include <QInputDialog> |
27 | #include <QStandardItemModel> | ||
27 | 28 | ||
28 | /** | 29 | /** |
29 | * EmptyEditPanel | 30 | * EmptyEditPanel |
@@ -36,863 +37,1300 @@ EmptyEditPanel::EmptyEditPanel(QWidget *parent) | |||
36 | /** | 37 | /** |
37 | * SocEditPanel | 38 | * SocEditPanel |
38 | */ | 39 | */ |
39 | SocEditPanel::SocEditPanel(SocRef ref, QWidget *parent) | 40 | |
41 | namespace | ||
42 | { | ||
43 | |||
44 | template< typename T > | ||
45 | void my_remove_at(std::vector< T >& v, size_t at) | ||
46 | { | ||
47 | v.erase(v.begin() + at); | ||
48 | } | ||
49 | |||
50 | enum | ||
51 | { | ||
52 | SocEditPanelDelType = QTableWidgetItem::UserType, | ||
53 | SocEditPanelAddType, | ||
54 | }; | ||
55 | |||
56 | } | ||
57 | |||
58 | SocEditPanel::SocEditPanel(const soc_desc::soc_ref_t& ref, QWidget *parent) | ||
40 | :QWidget(parent), m_ref(ref) | 59 | :QWidget(parent), m_ref(ref) |
41 | { | 60 | { |
42 | m_name_group = new QGroupBox("Name", this); | 61 | QLineEdit *name_edit = new QLineEdit(this); |
43 | m_name_edit = new QLineEdit(this); | 62 | QLineEdit *title_edit = new QLineEdit(this); |
44 | m_name_edit->setText(QString::fromStdString(ref.GetSoc().name)); | 63 | QLineEdit *isa_edit = new QLineEdit(this); |
45 | QVBoxLayout *name_group_layout = new QVBoxLayout; | 64 | QLineEdit *version_edit = new QLineEdit(this); |
46 | name_group_layout->addWidget(m_name_edit); | 65 | |
47 | m_name_group->setLayout(name_group_layout); | 66 | m_authors_list = new QTableWidget(this); |
67 | QGroupBox *authors_group = Misc::EncloseInBox("Authors", m_authors_list); | ||
48 | 68 | ||
49 | m_desc_group = new QGroupBox("Description", this); | ||
50 | QHBoxLayout *group_layout = new QHBoxLayout; | ||
51 | m_desc_edit = new MyTextEditor(this); | 69 | m_desc_edit = new MyTextEditor(this); |
52 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetSoc().desc)); | 70 | |
53 | group_layout->addWidget(m_desc_edit); | 71 | QGroupBox *desc_group = Misc::EncloseInBox("Description", m_desc_edit); |
54 | m_desc_group->setLayout(group_layout); | 72 | |
73 | QFormLayout *banner_left_layout = new QFormLayout; | ||
74 | banner_left_layout->addRow("Name:", name_edit); | ||
75 | banner_left_layout->addRow("Title:", title_edit); | ||
76 | banner_left_layout->addRow("Instruction Set:", isa_edit); | ||
77 | banner_left_layout->addRow("Version:", version_edit); | ||
78 | |||
79 | QGroupBox *banner_left_group = new QGroupBox("Information"); | ||
80 | banner_left_group->setLayout(banner_left_layout); | ||
81 | |||
82 | QHBoxLayout *banner_layout = new QHBoxLayout; | ||
83 | banner_layout->addWidget(banner_left_group); | ||
84 | banner_layout->addWidget(authors_group); | ||
85 | banner_layout->addStretch(0); | ||
55 | 86 | ||
56 | QVBoxLayout *layout = new QVBoxLayout; | 87 | QVBoxLayout *layout = new QVBoxLayout; |
57 | layout->addWidget(m_name_group); | 88 | layout->addLayout(banner_layout); |
58 | layout->addWidget(m_desc_group); | 89 | layout->addWidget(desc_group); |
59 | layout->addStretch(1); | 90 | layout->addStretch(1); |
60 | 91 | ||
61 | connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&))); | 92 | /* fill data */ |
93 | name_edit->setText(QString::fromStdString(ref.get()->name)); | ||
94 | title_edit->setText(QString::fromStdString(ref.get()->title)); | ||
95 | isa_edit->setText(QString::fromStdString(ref.get()->isa)); | ||
96 | version_edit->setText(QString::fromStdString(ref.get()->version)); | ||
97 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.get()->desc)); | ||
98 | |||
99 | m_authors_list->setColumnCount(2); | ||
100 | m_authors_list->setHorizontalHeaderItem(0, new QTableWidgetItem("")); | ||
101 | m_authors_list->setHorizontalHeaderItem(1, new QTableWidgetItem("Name")); | ||
102 | m_authors_list->horizontalHeader()->setVisible(false); | ||
103 | m_authors_list->verticalHeader()->setVisible(false); | ||
104 | m_authors_list->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
105 | std::vector< std::string >& authors = ref.get()->author; | ||
106 | m_authors_list->setRowCount(authors.size() + 1); | ||
107 | for(size_t i = 0; i < authors.size(); i++) | ||
108 | { | ||
109 | QTableWidgetItem *item = new QTableWidgetItem( | ||
110 | QIcon::fromTheme("list-remove"), "", SocEditPanelDelType); | ||
111 | item->setFlags(Qt::ItemIsEnabled); | ||
112 | m_authors_list->setItem(i, 0, item); | ||
113 | item = new QTableWidgetItem(QString::fromStdString(authors[i])); | ||
114 | m_authors_list->setItem(i, 1, item); | ||
115 | } | ||
116 | QTableWidgetItem *new_item = new QTableWidgetItem( | ||
117 | QIcon::fromTheme("list-add"), "", SocEditPanelAddType); | ||
118 | new_item->setFlags(Qt::ItemIsEnabled); | ||
119 | m_authors_list->setItem(authors.size(), 0, new_item); | ||
120 | new_item = new QTableWidgetItem("New author...", QTableWidgetItem::UserType); | ||
121 | new_item->setFlags(Qt::ItemIsEnabled); | ||
122 | QFont font = new_item->font(); | ||
123 | font.setItalic(true); | ||
124 | new_item->setFont(font); | ||
125 | m_authors_list->setItem(authors.size(), 1, new_item); | ||
126 | m_authors_list->resizeColumnsToContents(); | ||
127 | m_authors_list->horizontalHeader()->setStretchLastSection(true); | ||
128 | |||
129 | connect(name_edit, SIGNAL(textChanged(const QString&)), this, | ||
130 | SLOT(OnNameEdited(const QString&))); | ||
62 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnTextEdited())); | 131 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnTextEdited())); |
132 | connect(title_edit, SIGNAL(textChanged(const QString&)), this, | ||
133 | SLOT(OnTitleEdited(const QString&))); | ||
134 | connect(version_edit, SIGNAL(textChanged(const QString&)), this, | ||
135 | SLOT(OnVersionEdited(const QString&))); | ||
136 | connect(isa_edit, SIGNAL(textChanged(const QString&)), this, | ||
137 | SLOT(OnIsaEdited(const QString&))); | ||
138 | connect(m_authors_list, SIGNAL(itemActivated(QTableWidgetItem *)), this, | ||
139 | SLOT(OnAuthorActivated(QTableWidgetItem *))); | ||
140 | connect(m_authors_list, SIGNAL(itemChanged(QTableWidgetItem *)), this, | ||
141 | SLOT(OnAuthorChanged(QTableWidgetItem *))); | ||
63 | 142 | ||
64 | setLayout(layout); | 143 | setLayout(layout); |
65 | } | 144 | } |
66 | 145 | ||
67 | void SocEditPanel::OnNameEdited(const QString& text) | 146 | void SocEditPanel::OnNameEdited(const QString& text) |
68 | { | 147 | { |
69 | m_ref.GetSoc().name = text.toStdString(); | 148 | m_ref.get()->name = text.toStdString(); |
70 | OnModified(m_name_edit->isModified()); | 149 | OnModified(); |
71 | } | 150 | } |
72 | 151 | ||
73 | void SocEditPanel::OnTextEdited() | 152 | void SocEditPanel::OnTitleEdited(const QString& text) |
74 | { | 153 | { |
75 | m_ref.GetSoc().desc = m_desc_edit->GetTextHtml().toStdString(); | 154 | m_ref.get()->title = text.toStdString(); |
76 | OnModified(m_desc_edit->IsModified()); | 155 | OnModified(); |
77 | } | 156 | } |
78 | 157 | ||
79 | /** | 158 | void SocEditPanel::OnVersionEdited(const QString& text) |
80 | * DevEditPanel | ||
81 | */ | ||
82 | DevEditPanel::DevEditPanel(SocDevRef ref, QWidget *parent) | ||
83 | :QWidget(parent), m_ref(ref) | ||
84 | { | 159 | { |
85 | m_name_group = new QGroupBox("Name", this); | 160 | m_ref.get()->version = text.toStdString(); |
86 | m_name_edit = new QLineEdit(this); | 161 | OnModified(); |
87 | m_name_edit->setText(QString::fromStdString(ref.GetDev().name)); | 162 | } |
88 | QVBoxLayout *name_group_layout = new QVBoxLayout; | ||
89 | name_group_layout->addWidget(m_name_edit); | ||
90 | m_name_group->setLayout(name_group_layout); | ||
91 | |||
92 | m_long_name_group = new QGroupBox("Long Name", this); | ||
93 | m_long_name_edit = new QLineEdit(this); | ||
94 | m_long_name_edit->setText(QString::fromStdString(ref.GetDev().long_name)); | ||
95 | QVBoxLayout *long_name_group_layout = new QVBoxLayout; | ||
96 | long_name_group_layout->addWidget(m_long_name_edit); | ||
97 | m_long_name_group->setLayout(long_name_group_layout); | ||
98 | |||
99 | m_version_group = new QGroupBox("Version", this); | ||
100 | m_version_edit = new QLineEdit(this); | ||
101 | m_version_edit->setText(QString::fromStdString(ref.GetDev().version)); | ||
102 | QVBoxLayout *version_group_layout = new QVBoxLayout; | ||
103 | version_group_layout->addWidget(m_version_edit); | ||
104 | m_version_group->setLayout(version_group_layout); | ||
105 | |||
106 | QVBoxLayout *name_ver_layout = new QVBoxLayout; | ||
107 | name_ver_layout->addWidget(m_name_group); | ||
108 | name_ver_layout->addWidget(m_long_name_group); | ||
109 | name_ver_layout->addWidget(m_version_group); | ||
110 | name_ver_layout->addStretch(); | ||
111 | |||
112 | m_instances_table = new QTableWidget(this); | ||
113 | m_instances_table->setRowCount(ref.GetDev().addr.size() + 1); | ||
114 | m_instances_table->setColumnCount(3); | ||
115 | for(size_t row = 0; row < ref.GetDev().addr.size(); row++) | ||
116 | FillRow(row, ref.GetDev().addr[row]); | ||
117 | CreateNewRow(ref.GetDev().addr.size()); | ||
118 | m_instances_table->setHorizontalHeaderItem(0, new QTableWidgetItem("")); | ||
119 | m_instances_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name")); | ||
120 | m_instances_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Address")); | ||
121 | m_instances_table->verticalHeader()->setVisible(false); | ||
122 | m_instances_table->resizeColumnsToContents(); | ||
123 | m_instances_table->horizontalHeader()->setStretchLastSection(true); | ||
124 | m_instances_table->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); | ||
125 | m_instances_group = new QGroupBox("Instances", this); | ||
126 | QHBoxLayout *instances_group_layout = new QHBoxLayout; | ||
127 | instances_group_layout->addWidget(m_instances_table); | ||
128 | m_instances_group->setLayout(instances_group_layout); | ||
129 | |||
130 | QHBoxLayout *top_layout = new QHBoxLayout; | ||
131 | top_layout->addWidget(m_instances_group); | ||
132 | top_layout->addLayout(name_ver_layout); | ||
133 | top_layout->addStretch(); | ||
134 | |||
135 | m_desc_group = new QGroupBox("Description", this); | ||
136 | QHBoxLayout *group_layout = new QHBoxLayout; | ||
137 | m_desc_edit = new MyTextEditor(this); | ||
138 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetDev().desc)); | ||
139 | group_layout->addWidget(m_desc_edit); | ||
140 | m_desc_group->setLayout(group_layout); | ||
141 | |||
142 | QVBoxLayout *layout = new QVBoxLayout; | ||
143 | layout->addLayout(top_layout, 0); | ||
144 | layout->addWidget(m_desc_group, 1); | ||
145 | |||
146 | setLayout(layout); | ||
147 | 163 | ||
148 | SocFieldItemDelegate *m_table_delegate = new SocFieldItemDelegate(this); | 164 | void SocEditPanel::OnIsaEdited(const QString& text) |
149 | QItemEditorFactory *m_table_edit_factory = new QItemEditorFactory(); | 165 | { |
150 | SocFieldEditorCreator *m_table_edit_creator = new SocFieldEditorCreator(); | 166 | m_ref.get()->isa = text.toStdString(); |
151 | m_table_edit_factory->registerEditor(QVariant::UInt, m_table_edit_creator); | 167 | OnModified(); |
152 | m_table_delegate->setItemEditorFactory(m_table_edit_factory); | ||
153 | m_instances_table->setItemDelegate(m_table_delegate); | ||
154 | |||
155 | connect(m_instances_table, SIGNAL(cellActivated(int,int)), this, SLOT(OnInstActivated(int,int))); | ||
156 | connect(m_instances_table, SIGNAL(cellChanged(int,int)), this, SLOT(OnInstChanged(int,int))); | ||
157 | connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&))); | ||
158 | connect(m_long_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnLongNameEdited(const QString&))); | ||
159 | connect(m_version_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnVersionEdited(const QString&))); | ||
160 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); | ||
161 | } | 168 | } |
162 | 169 | ||
163 | void DevEditPanel::OnNameEdited(const QString& text) | 170 | void SocEditPanel::OnTextEdited() |
164 | { | 171 | { |
165 | m_ref.GetDev().name = text.toStdString(); | 172 | m_ref.get()->desc = m_desc_edit->GetTextHtml().toStdString(); |
166 | OnModified(m_name_edit->isModified()); | 173 | OnModified(); |
167 | } | 174 | } |
168 | 175 | ||
169 | void DevEditPanel::OnLongNameEdited(const QString& text) | 176 | void SocEditPanel::OnAuthorActivated(QTableWidgetItem *item) |
170 | { | 177 | { |
171 | m_ref.GetDev().long_name = text.toStdString(); | 178 | if(item->type() == SocEditPanelDelType) |
172 | OnModified(m_long_name_edit->isModified()); | 179 | { |
180 | int row = item->row(); | ||
181 | my_remove_at(m_ref.get()->author, row); | ||
182 | m_authors_list->removeRow(row); | ||
183 | OnModified(); | ||
184 | } | ||
185 | else if(item->type() == SocEditPanelAddType) | ||
186 | { | ||
187 | int row = m_ref.get()->author.size(); | ||
188 | m_ref.get()->author.push_back("Anonymous"); | ||
189 | m_authors_list->insertRow(row); | ||
190 | QTableWidgetItem *item = new QTableWidgetItem( | ||
191 | QIcon::fromTheme("list-remove"), "", SocEditPanelDelType); | ||
192 | item->setFlags(Qt::ItemIsEnabled); | ||
193 | m_authors_list->setItem(row, 0, item); | ||
194 | item = new QTableWidgetItem(QString::fromStdString(m_ref.get()->author.back())); | ||
195 | m_authors_list->setItem(row, 1, item); | ||
196 | OnModified(); | ||
197 | } | ||
173 | } | 198 | } |
174 | 199 | ||
175 | void DevEditPanel::OnVersionEdited(const QString& text) | 200 | void SocEditPanel::OnAuthorChanged(QTableWidgetItem *item) |
176 | { | 201 | { |
177 | m_ref.GetDev().version = text.toStdString(); | 202 | if((size_t)item->row() >= m_ref.get()->author.size()) |
178 | OnModified(m_version_edit->isModified()); | 203 | return; |
204 | if(item->column() == 1) | ||
205 | m_ref.get()->author[item->row()] = item->text().toStdString(); | ||
206 | OnModified(); | ||
179 | } | 207 | } |
180 | 208 | ||
181 | void DevEditPanel::OnDescEdited() | 209 | /** |
210 | * NodeInstanceEditPanel | ||
211 | */ | ||
212 | |||
213 | namespace | ||
182 | { | 214 | { |
183 | m_ref.GetDev().desc = m_desc_edit->GetTextHtml().toStdString(); | 215 | |
184 | OnModified(m_desc_edit->IsModified()); | 216 | template< typename T > |
217 | soc_id_t GetFreshId(const std::vector< T >& list) | ||
218 | { | ||
219 | soc_id_t id = 0; | ||
220 | for(size_t i = 0; i < list.size(); i++) | ||
221 | id = std::max(id, list[i].id); | ||
222 | return id + 1; | ||
185 | } | 223 | } |
186 | 224 | ||
187 | void DevEditPanel::CreateNewRow(int row) | 225 | template< typename T > |
226 | int GetIndexById(const std::vector< T >& list, soc_id_t id) | ||
188 | { | 227 | { |
189 | QTableWidgetItem *item = new QTableWidgetItem(QIcon::fromTheme("list-add"), "", DevInstNewType); | 228 | for(size_t i = 0; i < list.size(); i++) |
190 | item->setToolTip("New?"); | 229 | if(list[i].id == id) |
191 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | 230 | return i; |
192 | m_instances_table->setItem(row, DevInstIconColumn, item); | 231 | return -1; |
193 | item = new QTableWidgetItem("New instance..."); | ||
194 | QFont font = item->font(); | ||
195 | font.setItalic(true); | ||
196 | item->setFont(font); | ||
197 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
198 | m_instances_table->setItem(row, DevInstNameColumn, item); | ||
199 | item = new QTableWidgetItem(""); | ||
200 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
201 | m_instances_table->setItem(row, DevInstAddrColumn, item); | ||
202 | } | 232 | } |
203 | 233 | ||
204 | void DevEditPanel::FillRow(int row, const soc_dev_addr_t& addr) | 234 | soc_desc::instance_t *GetInstanceById(const soc_desc::node_ref_t& node, soc_id_t id) |
205 | { | 235 | { |
206 | QTableWidgetItem *item = new QTableWidgetItem(QString::fromStdString(addr.name)); | 236 | std::vector< soc_desc::instance_t >& inst_list = node.get()->instance; |
207 | item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | 237 | for(size_t i = 0; i < inst_list.size(); i++) |
208 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | 238 | if(inst_list[i].id == id) |
209 | m_instances_table->setItem(row, DevInstNameColumn, item); | 239 | return &inst_list[i]; |
210 | item = new QTableWidgetItem(); | 240 | return 0; |
211 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | ||
212 | item->setData(Qt::DisplayRole, QVariant(addr.addr)); | ||
213 | m_instances_table->setItem(row, DevInstAddrColumn, item); | ||
214 | item = new QTableWidgetItem(QIcon::fromTheme("list-remove"), "", DevInstDeleteType); | ||
215 | item->setToolTip("Remove?"); | ||
216 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
217 | m_instances_table->setItem(row, DevInstIconColumn, item); | ||
218 | } | 241 | } |
219 | 242 | ||
220 | void DevEditPanel::OnInstActivated(int row, int column) | 243 | bool RemoveInstanceById(const soc_desc::node_ref_t& node, soc_id_t id) |
221 | { | 244 | { |
222 | if(column != 0) | 245 | std::vector< soc_desc::instance_t >& inst_list = node.get()->instance; |
223 | return; | 246 | for(size_t i = 0; i < inst_list.size(); i++) |
224 | int type = m_instances_table->item(row, column)->type(); | 247 | if(inst_list[i].id == id) |
225 | if(type == DevInstDeleteType) | 248 | { |
226 | { | 249 | my_remove_at(inst_list, i); |
227 | m_ref.GetDev().addr.erase(m_ref.GetDev().addr.begin() + row); | 250 | return true; |
228 | m_instances_table->removeRow(row); | 251 | } |
229 | OnModified(true); | 252 | return false; |
230 | } | ||
231 | else if(type == DevInstNewType) | ||
232 | { | ||
233 | m_instances_table->insertRow(row); | ||
234 | soc_dev_addr_t addr; | ||
235 | addr.name = QString("UNNAMED_%1").arg(row).toStdString(); | ||
236 | addr.addr = 0; | ||
237 | m_ref.GetDev().addr.push_back(addr); | ||
238 | FillRow(row, addr); | ||
239 | } | ||
240 | } | 253 | } |
241 | 254 | ||
242 | void DevEditPanel::OnInstChanged(int row, int column) | 255 | enum |
243 | { | 256 | { |
244 | /* ignore extra row for addition */ | 257 | InstTypeSingle, |
245 | if(row >= (int)m_ref.GetDev().addr.size()) | 258 | InstTypeRangeStride, |
246 | return; | 259 | InstTypeRangeFormula, |
247 | QTableWidgetItem *item = m_instances_table->item(row, column); | 260 | InstTypeRangeList |
248 | if(column == DevInstNameColumn) | 261 | }; |
262 | |||
263 | enum | ||
264 | { | ||
265 | NodeInstEditPanelDelType = QTableWidgetItem::UserType, | ||
266 | NodeInstEditPanelAddType | ||
267 | }; | ||
268 | |||
269 | } | ||
270 | |||
271 | NodeInstanceEditPanel::NodeInstanceEditPanel(const soc_desc::node_ref_t& ref, | ||
272 | soc_id_t inst_id, QWidget *parent) | ||
273 | :QWidget(parent), m_ref(ref), m_id(inst_id) | ||
274 | { | ||
275 | QLineEdit *name_edit = new QLineEdit(this); | ||
276 | QLineEdit *title_edit = new QLineEdit(this); | ||
277 | m_type_combo = new QComboBox(this); | ||
278 | QLabel *type_label = new QLabel("Type:", this); | ||
279 | QFont f = type_label->font(); | ||
280 | f.setBold(true); | ||
281 | type_label->setFont(f); | ||
282 | |||
283 | QHBoxLayout *type_layout = new QHBoxLayout; | ||
284 | type_layout->addWidget(type_label); | ||
285 | type_layout->addWidget(m_type_combo); | ||
286 | type_layout->addStretch(0); | ||
287 | |||
288 | soc_desc::field_t fake_field; | ||
289 | fake_field.pos = 0; | ||
290 | fake_field.width = 32; | ||
291 | |||
292 | m_single_group = new QWidget(this); | ||
293 | QHBoxLayout *sg_layout = new QHBoxLayout; | ||
294 | sg_layout->addWidget(new QLabel("Address:", m_single_group)); | ||
295 | SocFieldEditor *addr_edit = new SocFieldEditor(fake_field, m_single_group); | ||
296 | sg_layout->addWidget(addr_edit); | ||
297 | m_single_group->setLayout(sg_layout); | ||
298 | |||
299 | m_range_group = new QWidget(this); | ||
300 | QGridLayout *rg_layout = new QGridLayout; | ||
301 | rg_layout->addWidget(new QLabel("First:", m_range_group), 0, 0); | ||
302 | QSpinBox *first_spin = new QSpinBox(m_range_group); | ||
303 | rg_layout->addWidget(first_spin, 0, 1); | ||
304 | rg_layout->addWidget(new QLabel("Count:", m_range_group), 1, 0); | ||
305 | QSpinBox *count_spin = new QSpinBox(m_range_group); | ||
306 | rg_layout->addWidget(count_spin, 1, 1); | ||
307 | m_range_group->setLayout(rg_layout); | ||
308 | |||
309 | m_stride_group = new QWidget(m_range_group); | ||
310 | QGridLayout *rsg_layout = new QGridLayout; | ||
311 | rsg_layout->addWidget(new QLabel("Base:", m_stride_group), 0, 0); | ||
312 | SocFieldEditor *base_edit = new SocFieldEditor(fake_field, m_stride_group); | ||
313 | rsg_layout->addWidget(base_edit, 0, 1); | ||
314 | rsg_layout->addWidget(new QLabel("Stride:", m_stride_group), 1, 0); | ||
315 | SocFieldEditor *stride_edit = new SocFieldEditor(fake_field, m_stride_group); | ||
316 | rsg_layout->addWidget(stride_edit, 1, 1); | ||
317 | m_stride_group->setLayout(rsg_layout); | ||
318 | |||
319 | m_formula_group = new QWidget(m_range_group); | ||
320 | QGridLayout *fsg_layout = new QGridLayout; | ||
321 | fsg_layout->addWidget(new QLabel("Variable:", m_formula_group), 0, 0); | ||
322 | QLineEdit *variable_edit = new QLineEdit(m_formula_group); | ||
323 | fsg_layout->addWidget(variable_edit, 0, 1); | ||
324 | fsg_layout->addWidget(new QLabel("Formula:", m_formula_group), 1, 0); | ||
325 | QLineEdit *formula_edit = new QLineEdit(m_formula_group); | ||
326 | fsg_layout->addWidget(formula_edit, 1, 1); | ||
327 | m_formula_group->setLayout(fsg_layout); | ||
328 | |||
329 | QTableWidget *addr_list = new QTableWidget(m_range_group); | ||
330 | m_list_group = addr_list; | ||
331 | |||
332 | QHBoxLayout *inst_layout = new QHBoxLayout; | ||
333 | inst_layout->addWidget(m_single_group); | ||
334 | inst_layout->addWidget(m_range_group); | ||
335 | inst_layout->addWidget(m_stride_group); | ||
336 | inst_layout->addWidget(m_formula_group); | ||
337 | inst_layout->addWidget(m_list_group); | ||
338 | inst_layout->addStretch(0); | ||
339 | |||
340 | QGroupBox *inst_groupbox = new QGroupBox(this); | ||
341 | inst_groupbox->setLayout(inst_layout); | ||
342 | |||
343 | MyTextEditor *desc_edit = new MyTextEditor(this); | ||
344 | QVBoxLayout *ii_layout = new QVBoxLayout; | ||
345 | |||
346 | QFormLayout *info_layout = new QFormLayout(); | ||
347 | info_layout->addRow("Name", name_edit); | ||
348 | info_layout->addRow("Title", title_edit); | ||
349 | |||
350 | QGroupBox *info_group = Misc::EncloseInBox("Information", info_layout); | ||
351 | QGroupBox *desc_group = Misc::EncloseInBox("Description", desc_edit); | ||
352 | QHBoxLayout *name_title_desc_layout = new QHBoxLayout; | ||
353 | name_title_desc_layout->addWidget(info_group, 1); | ||
354 | name_title_desc_layout->addWidget(desc_group, 2); | ||
355 | |||
356 | ii_layout->addLayout(name_title_desc_layout); | ||
357 | ii_layout->addLayout(type_layout); | ||
358 | ii_layout->addWidget(inst_groupbox); | ||
359 | ii_layout->addStretch(1); | ||
360 | |||
361 | m_type_combo->addItem("Single", QVariant(InstTypeSingle)); | ||
362 | m_type_combo->addItem("Range > Stride", QVariant(InstTypeRangeStride)); | ||
363 | m_type_combo->addItem("Range > Formula", QVariant(InstTypeRangeFormula)); | ||
364 | m_type_combo->addItem("Range > List", QVariant(InstTypeRangeList)); | ||
365 | |||
366 | /* fill info */ | ||
367 | soc_desc::instance_t& inst = GetInstance(); | ||
368 | name_edit->setText(QString::fromStdString(inst.name)); | ||
369 | title_edit->setText(QString::fromStdString(inst.title)); | ||
370 | desc_edit->SetTextHtml(QString::fromStdString(inst.desc)); | ||
371 | addr_edit->setField(inst.addr); | ||
372 | base_edit->setField(inst.range.base); | ||
373 | stride_edit->setField(inst.range.stride); | ||
374 | first_spin->setValue(inst.range.first); | ||
375 | count_spin->setValue(inst.range.count); | ||
376 | formula_edit->setText(QString::fromStdString(inst.range.formula)); | ||
377 | variable_edit->setText(QString::fromStdString(inst.range.variable)); | ||
378 | addr_list->setColumnCount(2); | ||
379 | addr_list->setHorizontalHeaderItem(0, new QTableWidgetItem("")); | ||
380 | addr_list->setHorizontalHeaderItem(1, new QTableWidgetItem("Address")); | ||
381 | addr_list->horizontalHeader()->setVisible(false); | ||
382 | addr_list->verticalHeader()->setVisible(false); | ||
383 | addr_list->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
384 | std::vector< soc_word_t >& addrs = inst.range.list; | ||
385 | addr_list->setRowCount(addrs.size() + 1); | ||
386 | for(size_t i = 0; i < addrs.size(); i++) | ||
249 | { | 387 | { |
250 | m_ref.GetDev().addr[row].name = item->text().toStdString(); | 388 | QTableWidgetItem *item = new QTableWidgetItem( |
251 | OnModified(true); | 389 | QIcon::fromTheme("list-remove"), "", NodeInstEditPanelDelType); |
390 | item->setFlags(Qt::ItemIsEnabled); | ||
391 | addr_list->setItem(i, 0, item); | ||
392 | item = new QTableWidgetItem(); | ||
393 | item->setData(Qt::EditRole, QVariant::fromValue(addrs[i])); | ||
394 | addr_list->setItem(i, 1, item); | ||
252 | } | 395 | } |
253 | else if(column == DevInstAddrColumn) | 396 | QTableWidgetItem *new_item = new QTableWidgetItem( |
397 | QIcon::fromTheme("list-add"), "", NodeInstEditPanelAddType); | ||
398 | new_item->setFlags(Qt::ItemIsEnabled); | ||
399 | addr_list->setItem(addrs.size(), 0, new_item); | ||
400 | new_item = new QTableWidgetItem("New address...", QTableWidgetItem::UserType); | ||
401 | new_item->setFlags(Qt::ItemIsEnabled); | ||
402 | QFont font = new_item->font(); | ||
403 | font.setItalic(true); | ||
404 | new_item->setFont(font); | ||
405 | addr_list->setItem(addrs.size(), 1, new_item); | ||
406 | addr_list->resizeColumnsToContents(); | ||
407 | addr_list->horizontalHeader()->setStretchLastSection(true); | ||
408 | m_table_delegate = new SocFieldItemDelegate(this); | ||
409 | m_table_delegate->setItemEditorFactory(new QItemEditorFactory); | ||
410 | m_table_edit_factory = new SocFieldEditorCreator; | ||
411 | m_table_delegate->itemEditorFactory()->registerEditor(QVariant::UInt, m_table_edit_factory); | ||
412 | addr_list->setItemDelegate(m_table_delegate); | ||
413 | |||
414 | setLayout(ii_layout); | ||
415 | |||
416 | connect(name_edit, SIGNAL(textChanged(const QString&)), this, | ||
417 | SLOT(OnNameEdited(const QString&))); | ||
418 | connect(desc_edit, SIGNAL(OnTextChanged(const QString&)), this, | ||
419 | SLOT(OnDescEdited(const QString&))); | ||
420 | connect(title_edit, SIGNAL(textChanged(const QString&)), this, | ||
421 | SLOT(OnTitleEdited(const QString&))); | ||
422 | connect(addr_edit, SIGNAL(editingFinished(uint)), this, SLOT(OnAddrChanged(uint))); | ||
423 | connect(base_edit, SIGNAL(editingFinished(uint)), this, SLOT(OnBaseChanged(uint))); | ||
424 | connect(stride_edit, SIGNAL(editingFinished(uint)), this, SLOT(OnStrideChanged(uint))); | ||
425 | connect(first_spin, SIGNAL(valueChanged(int)), this, SLOT(OnFirstChanged(int))); | ||
426 | connect(count_spin, SIGNAL(valueChanged(int)), this, SLOT(OnCountChanged(int))); | ||
427 | connect(formula_edit, SIGNAL(textChanged(const QString&)), this, | ||
428 | SLOT(OnFormulaChanged(const QString&))); | ||
429 | connect(variable_edit, SIGNAL(textChanged(const QString&)), this, | ||
430 | SLOT(OnVariableChanged(const QString&))); | ||
431 | connect(m_type_combo, SIGNAL(currentIndexChanged(int)), | ||
432 | this, SLOT(OnTypeChanged(int))); | ||
433 | connect(addr_list, SIGNAL(itemActivated(QTableWidgetItem *)), this, | ||
434 | SLOT(OnAddressActivated(QTableWidgetItem *))); | ||
435 | connect(addr_list, SIGNAL(itemChanged(QTableWidgetItem *)), this, | ||
436 | SLOT(OnAddressChanged(QTableWidgetItem *))); | ||
437 | |||
438 | /* fill info */ | ||
439 | int combo_type; | ||
440 | if(inst.type == soc_desc::instance_t::RANGE) | ||
254 | { | 441 | { |
255 | m_ref.GetDev().addr[row].addr = item->data(Qt::DisplayRole).toUInt(); | 442 | if(inst.range.type == soc_desc::range_t::STRIDE) |
256 | OnModified(true); | 443 | combo_type = InstTypeRangeStride; |
444 | else if(inst.range.type == soc_desc::range_t::FORMULA) | ||
445 | combo_type = InstTypeRangeFormula; | ||
446 | else /* LIST */ | ||
447 | combo_type = InstTypeRangeList; | ||
257 | } | 448 | } |
449 | else | ||
450 | combo_type = InstTypeSingle; | ||
451 | m_type_combo->setCurrentIndex(m_type_combo->findData(QVariant(combo_type))); | ||
452 | UpdateType(combo_type); | ||
258 | } | 453 | } |
259 | 454 | ||
260 | /** | 455 | soc_desc::instance_t& NodeInstanceEditPanel::GetInstance() |
261 | * RegEditPanel | 456 | { |
262 | */ | 457 | return *GetInstanceById(m_ref, m_id); |
458 | } | ||
263 | 459 | ||
264 | RegEditPanel::RegEditPanel(SocRegRef ref, QWidget *parent) | 460 | void NodeInstanceEditPanel::OnNameEdited(const QString& text) |
265 | :QWidget(parent), m_ref(ref), m_reg_font(font()) | ||
266 | { | 461 | { |
267 | m_reg_font.setWeight(100); | 462 | GetInstance().name = text.toStdString(); |
268 | m_reg_font.setKerning(false); | 463 | OnModified(); |
464 | } | ||
269 | 465 | ||
270 | m_name_group = new QGroupBox("Name", this); | 466 | void NodeInstanceEditPanel::OnTitleEdited(const QString& text) |
271 | m_name_edit = new QLineEdit(this); | 467 | { |
272 | m_name_edit->setText(QString::fromStdString(ref.GetReg().name)); | 468 | GetInstance().title = text.toStdString(); |
273 | QVBoxLayout *name_group_layout = new QVBoxLayout; | 469 | OnModified(); |
274 | name_group_layout->addWidget(m_name_edit); | 470 | } |
275 | m_name_group->setLayout(name_group_layout); | ||
276 | |||
277 | m_instances_table = new QTableWidget(this); | ||
278 | m_instances_table->setRowCount(ref.GetReg().addr.size() + 1); | ||
279 | m_instances_table->setColumnCount(RegInstNrColumns); | ||
280 | for(size_t row = 0; row < ref.GetReg().addr.size(); row++) | ||
281 | FillRow(row, ref.GetReg().addr[row]); | ||
282 | CreateNewAddrRow(ref.GetReg().addr.size()); | ||
283 | m_instances_table->setHorizontalHeaderItem(RegInstIconColumn, new QTableWidgetItem("")); | ||
284 | m_instances_table->setHorizontalHeaderItem(RegInstNameColumn, new QTableWidgetItem("Name")); | ||
285 | m_instances_table->setHorizontalHeaderItem(RegInstAddrColumn, new QTableWidgetItem("Address")); | ||
286 | m_instances_table->verticalHeader()->setVisible(false); | ||
287 | m_instances_table->resizeColumnsToContents(); | ||
288 | m_instances_table->horizontalHeader()->setStretchLastSection(true); | ||
289 | m_instances_table->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); | ||
290 | m_instances_group = new QGroupBox("Instances", this); | ||
291 | QHBoxLayout *instances_group_layout = new QHBoxLayout; | ||
292 | instances_group_layout->addWidget(m_instances_table); | ||
293 | m_instances_group->setLayout(instances_group_layout); | ||
294 | |||
295 | m_desc_group = new QGroupBox("Description", this); | ||
296 | QHBoxLayout *group_layout = new QHBoxLayout; | ||
297 | m_desc_edit = new MyTextEditor(this); | ||
298 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetReg().desc)); | ||
299 | group_layout->addWidget(m_desc_edit); | ||
300 | m_desc_group->setLayout(group_layout); | ||
301 | |||
302 | bool has_sct = m_ref.GetReg().flags & REG_HAS_SCT; | ||
303 | m_sct_check = new QCheckBox("Set/Clear/Toggle", this); | ||
304 | m_sct_check->setCheckState(has_sct ? Qt::Checked : Qt::Unchecked); | ||
305 | QHBoxLayout *flags_layout = new QHBoxLayout; | ||
306 | flags_layout->addWidget(m_sct_check); | ||
307 | flags_layout->addStretch(); | ||
308 | m_flags_group = new QGroupBox("Flags", this); | ||
309 | m_flags_group->setLayout(flags_layout); | ||
310 | |||
311 | m_formula_combo = new QComboBox(this); | ||
312 | m_formula_combo->addItem("None", QVariant(REG_FORMULA_NONE)); | ||
313 | m_formula_combo->addItem("String", QVariant(REG_FORMULA_STRING)); | ||
314 | m_formula_combo->setCurrentIndex(m_formula_combo->findData(QVariant(m_ref.GetReg().formula.type))); | ||
315 | m_formula_type_label = new QLabel("Type:", this); | ||
316 | QHBoxLayout *formula_top_layout = new QHBoxLayout; | ||
317 | formula_top_layout->addWidget(m_formula_type_label); | ||
318 | formula_top_layout->addWidget(m_formula_combo); | ||
319 | m_formula_string_edit = new QLineEdit(QString::fromStdString(ref.GetReg().formula.string), this); | ||
320 | QVBoxLayout *formula_layout = new QVBoxLayout; | ||
321 | formula_layout->addLayout(formula_top_layout); | ||
322 | formula_layout->addWidget(m_formula_string_edit); | ||
323 | m_formula_string_gen = new QPushButton("Generate", this); | ||
324 | formula_layout->addWidget(m_formula_string_gen); | ||
325 | m_formula_group = new QGroupBox("Formula", this); | ||
326 | m_formula_group->setLayout(formula_layout); | ||
327 | |||
328 | QVBoxLayout *name_layout = new QVBoxLayout; | ||
329 | name_layout->addWidget(m_name_group); | ||
330 | name_layout->addWidget(m_flags_group); | ||
331 | name_layout->addWidget(m_formula_group); | ||
332 | name_layout->addStretch(); | ||
333 | |||
334 | QHBoxLayout *top_layout = new QHBoxLayout; | ||
335 | top_layout->addWidget(m_instances_group); | ||
336 | top_layout->addLayout(name_layout); | ||
337 | top_layout->addWidget(m_desc_group, 1); | ||
338 | |||
339 | m_value_table = new QTableView(this); | ||
340 | m_value_model = new RegFieldTableModel(m_value_table); // view takes ownership | ||
341 | m_value_model->SetRegister(m_ref.GetReg()); | ||
342 | m_value_model->SetReadOnly(true); | ||
343 | m_value_table->setModel(m_value_model); | ||
344 | m_value_table->verticalHeader()->setVisible(false); | ||
345 | m_value_table->horizontalHeader()->setStretchLastSection(true); | ||
346 | m_value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
347 | // FIXME we cannot use setAlternatingRowColors() because we override the | ||
348 | // background color, should it be part of the model ? | ||
349 | m_table_delegate = new SocFieldCachedItemDelegate(this); | ||
350 | m_value_table->setItemDelegate(m_table_delegate); | ||
351 | m_value_table->resizeColumnsToContents(); | ||
352 | |||
353 | m_sexy_display2 = new Unscroll<RegSexyDisplay2>(this); | ||
354 | m_sexy_display2->setFont(m_reg_font); | ||
355 | m_sexy_display2->setModel(m_value_model); | ||
356 | m_sexy_display2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
357 | 471 | ||
358 | QHBoxLayout *field_layout = new QHBoxLayout; | 472 | void NodeInstanceEditPanel::OnDescEdited(const QString& text) |
359 | field_layout->addWidget(m_value_table); | 473 | { |
360 | m_field_group = new QGroupBox("Flags", this); | 474 | GetInstance().desc = text.toStdString(); |
361 | m_field_group->setLayout(field_layout); | 475 | OnModified(); |
476 | } | ||
362 | 477 | ||
363 | QVBoxLayout *layout = new QVBoxLayout; | 478 | void NodeInstanceEditPanel::OnAddrChanged(uint addr) |
364 | layout->addLayout(top_layout, 0); | 479 | { |
365 | layout->addWidget(m_sexy_display2, 0); | 480 | GetInstance().addr = addr; |
366 | layout->addWidget(m_field_group); | 481 | OnModified(); |
482 | } | ||
367 | 483 | ||
368 | UpdateFormula(); | 484 | void NodeInstanceEditPanel::OnBaseChanged(uint base) |
485 | { | ||
486 | GetInstance().range.base = base; | ||
487 | OnModified(); | ||
488 | } | ||
369 | 489 | ||
370 | setLayout(layout); | 490 | void NodeInstanceEditPanel::OnStrideChanged(uint stride) |
491 | { | ||
492 | GetInstance().range.stride = stride; | ||
493 | OnModified(); | ||
494 | } | ||
371 | 495 | ||
372 | SocFieldItemDelegate *m_table_delegate = new SocFieldItemDelegate(this); | 496 | void NodeInstanceEditPanel::OnFirstChanged(int first) |
373 | QItemEditorFactory *m_table_edit_factory = new QItemEditorFactory(); | 497 | { |
374 | SocFieldEditorCreator *m_table_edit_creator = new SocFieldEditorCreator(); | 498 | GetInstance().range.first = first; |
375 | m_table_edit_factory->registerEditor(QVariant::UInt, m_table_edit_creator); | 499 | OnModified(); |
376 | m_table_delegate->setItemEditorFactory(m_table_edit_factory); | 500 | } |
377 | m_instances_table->setItemDelegate(m_table_delegate); | ||
378 | 501 | ||
379 | connect(m_instances_table, SIGNAL(cellActivated(int,int)), this, SLOT(OnInstActivated(int,int))); | 502 | void NodeInstanceEditPanel::OnCountChanged(int count) |
380 | connect(m_instances_table, SIGNAL(cellChanged(int,int)), this, SLOT(OnInstChanged(int,int))); | 503 | { |
381 | connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&))); | 504 | GetInstance().range.count = count; |
382 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); | 505 | OnModified(); |
383 | connect(m_sct_check, SIGNAL(stateChanged(int)), this, SLOT(OnSctEdited(int))); | ||
384 | connect(m_formula_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(OnFormulaChanged(int))); | ||
385 | connect(m_formula_string_edit, SIGNAL(textChanged(const QString&)), this, | ||
386 | SLOT(OnFormulaStringChanged(const QString&))); | ||
387 | connect(m_formula_string_gen, SIGNAL(clicked(bool)), this, SLOT(OnFormulaGenerate(bool))); | ||
388 | } | 506 | } |
389 | 507 | ||
390 | void RegEditPanel::UpdateWarning(int row) | 508 | void NodeInstanceEditPanel::OnFormulaChanged(const QString& formula) |
391 | { | 509 | { |
392 | Q_UNUSED(row); | 510 | GetInstance().range.formula = formula.toStdString(); |
511 | OnModified(); | ||
393 | } | 512 | } |
394 | 513 | ||
395 | void RegEditPanel::OnFormulaStringChanged(const QString& text) | 514 | void NodeInstanceEditPanel::OnVariableChanged(const QString& variable) |
396 | { | 515 | { |
397 | m_ref.GetReg().formula.string = text.toStdString(); | 516 | GetInstance().range.variable = variable.toStdString(); |
398 | OnModified(true); | 517 | OnModified(); |
399 | } | 518 | } |
400 | 519 | ||
401 | void RegEditPanel::OnFormulaGenerate(bool checked) | 520 | void NodeInstanceEditPanel::OnAddressActivated(QTableWidgetItem *item) |
402 | { | 521 | { |
403 | Q_UNUSED(checked); | 522 | QTableWidget *table = item->tableWidget(); |
404 | bool ok; | 523 | soc_desc::instance_t& inst = GetInstance(); |
405 | int count = QInputDialog::getInt(this, "Instance generator", "Number of instances", | 524 | if(item->type() == NodeInstEditPanelDelType) |
406 | 0, 0, 100, 1, &ok); | ||
407 | if(!ok) | ||
408 | return; | ||
409 | std::string name(m_ref.GetReg().name); | ||
410 | size_t pos = name.find('n'); | ||
411 | if(pos == std::string::npos) | ||
412 | { | ||
413 | name.push_back('n'); | ||
414 | pos = name.size() - 1; | ||
415 | } | ||
416 | std::map< std::string, soc_word_t > map; | ||
417 | std::vector< std::pair< std::string, soc_word_t > > list; | ||
418 | std::string formula = m_ref.GetReg().formula.string; | ||
419 | for(int n = 0; n < count; n++) | ||
420 | { | 525 | { |
421 | map["n"] = n; | 526 | int row = item->row(); |
422 | std::string err; | 527 | my_remove_at(inst.range.list, row); |
423 | soc_word_t res; | 528 | table->removeRow(row); |
424 | if(!evaluate_formula(formula, map, res, err)) | 529 | OnModified(); |
425 | { | ||
426 | qDebug() << "Cannot evaluator " << QString::fromStdString(formula) | ||
427 | << "for n=" << n << ": " << QString::fromStdString(err); | ||
428 | return; | ||
429 | } | ||
430 | std::string regname = name; | ||
431 | std::string strn = QString("%1").arg(n).toStdString(); | ||
432 | regname.replace(pos, 1, strn); | ||
433 | list.push_back(std::make_pair(regname, res)); | ||
434 | } | 530 | } |
435 | // everything went good, commit result | 531 | else if(item->type() == NodeInstEditPanelAddType) |
436 | while(m_instances_table->rowCount() > 1) | ||
437 | m_instances_table->removeRow(0); | ||
438 | m_ref.GetReg().addr.resize(list.size()); | ||
439 | for(size_t i = 0; i < list.size(); i++) | ||
440 | { | 532 | { |
441 | m_instances_table->insertRow(i); | 533 | int row = inst.range.list.size(); |
442 | m_ref.GetReg().addr[i].name = list[i].first; | 534 | soc_word_t new_addr = 0; |
443 | m_ref.GetReg().addr[i].addr = list[i].second; | 535 | GetInstance().range.list.push_back(new_addr); |
444 | FillRow(i, m_ref.GetReg().addr[i]); | 536 | table->insertRow(row); |
537 | QTableWidgetItem *item = new QTableWidgetItem( | ||
538 | QIcon::fromTheme("list-remove"), "", NodeInstEditPanelDelType); | ||
539 | item->setFlags(Qt::ItemIsEnabled); | ||
540 | table->setItem(row, 0, item); | ||
541 | item = new QTableWidgetItem(); | ||
542 | item->setData(Qt::EditRole, QVariant(new_addr)); | ||
543 | table->setItem(row, 1, item); | ||
544 | OnModified(); | ||
445 | } | 545 | } |
446 | } | 546 | } |
447 | 547 | ||
448 | void RegEditPanel::OnFormulaChanged(int index) | 548 | void NodeInstanceEditPanel::OnAddressChanged(QTableWidgetItem *item) |
449 | { | 549 | { |
450 | if(index == -1) | 550 | soc_desc::instance_t& inst = GetInstance(); |
551 | if((size_t)item->row() >= inst.range.list.size()) | ||
451 | return; | 552 | return; |
452 | m_ref.GetReg().formula.type = static_cast< soc_reg_formula_type_t >(m_formula_combo->itemData(index).toInt()); | 553 | soc_word_t& addr = inst.range.list[item->row()]; |
453 | UpdateFormula(); | 554 | if(item->column() == 1) |
454 | OnModified(true); | 555 | addr = item->data(Qt::EditRole).value< soc_word_t >(); |
556 | OnModified(); | ||
455 | } | 557 | } |
456 | 558 | ||
457 | void RegEditPanel::UpdateFormula() | 559 | void NodeInstanceEditPanel::UpdateType(int type) |
458 | { | 560 | { |
459 | m_formula_string_edit->hide(); | 561 | m_single_group->hide(); |
460 | m_formula_string_gen->hide(); | 562 | m_range_group->hide(); |
461 | switch(m_ref.GetReg().formula.type) | 563 | m_stride_group->hide(); |
564 | m_formula_group->hide(); | ||
565 | m_list_group->hide(); | ||
566 | |||
567 | switch(type) | ||
462 | { | 568 | { |
463 | case REG_FORMULA_STRING: | 569 | case InstTypeSingle: |
464 | m_formula_string_edit->show(); | 570 | m_single_group->show(); |
465 | m_formula_string_gen->show(); | 571 | GetInstance().type = soc_desc::instance_t::SINGLE; |
572 | break; | ||
573 | case InstTypeRangeStride: | ||
574 | m_range_group->show(); | ||
575 | m_stride_group->show(); | ||
576 | GetInstance().type = soc_desc::instance_t::RANGE; | ||
577 | GetInstance().range.type = soc_desc::range_t::STRIDE; | ||
578 | break; | ||
579 | case InstTypeRangeFormula: | ||
580 | m_range_group->show(); | ||
581 | m_formula_group->show(); | ||
582 | GetInstance().type = soc_desc::instance_t::RANGE; | ||
583 | GetInstance().range.type = soc_desc::range_t::FORMULA; | ||
584 | break; | ||
585 | case InstTypeRangeList: | ||
586 | m_range_group->show(); | ||
587 | m_formula_group->hide(); | ||
588 | m_list_group->show(); | ||
589 | GetInstance().type = soc_desc::instance_t::RANGE; | ||
590 | GetInstance().range.type = soc_desc::range_t::LIST; | ||
466 | break; | 591 | break; |
467 | case REG_FORMULA_NONE: | ||
468 | default: | 592 | default: |
469 | break; | 593 | break; |
470 | } | 594 | } |
471 | } | 595 | } |
472 | 596 | ||
473 | void RegEditPanel::OnSctEdited(int state) | 597 | void NodeInstanceEditPanel::OnTypeChanged(int index) |
474 | { | 598 | { |
475 | if(state == Qt::Checked) | 599 | if(index == -1) |
476 | m_ref.GetReg().flags |= REG_HAS_SCT; | 600 | return; |
477 | else | 601 | UpdateType(m_type_combo->itemData(index).toInt()); |
478 | m_ref.GetReg().flags &= ~REG_HAS_SCT; | 602 | OnModified(); |
479 | OnModified(true); | ||
480 | } | ||
481 | |||
482 | void RegEditPanel::FillRow(int row, const soc_reg_addr_t& addr) | ||
483 | { | ||
484 | QTableWidgetItem *item = new QTableWidgetItem(QString::fromStdString(addr.name)); | ||
485 | item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | ||
486 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | ||
487 | m_instances_table->setItem(row, RegInstNameColumn, item); | ||
488 | item = new QTableWidgetItem(); | ||
489 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | ||
490 | item->setData(Qt::DisplayRole, QVariant(addr.addr)); | ||
491 | m_instances_table->setItem(row, RegInstAddrColumn, item); | ||
492 | item = new QTableWidgetItem(QIcon::fromTheme("list-remove"), "", RegInstDeleteType); | ||
493 | item->setToolTip("Remove?"); | ||
494 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
495 | m_instances_table->setItem(row, RegInstIconColumn, item); | ||
496 | } | ||
497 | |||
498 | void RegEditPanel::CreateNewAddrRow(int row) | ||
499 | { | ||
500 | QTableWidgetItem *item = new QTableWidgetItem(QIcon::fromTheme("list-add"), "", RegInstNewType); | ||
501 | item->setToolTip("New?"); | ||
502 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
503 | m_instances_table->setItem(row, RegInstIconColumn, item); | ||
504 | item = new QTableWidgetItem("New instance..."); | ||
505 | QFont font = item->font(); | ||
506 | font.setItalic(true); | ||
507 | item->setFont(font); | ||
508 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
509 | m_instances_table->setItem(row, RegInstNameColumn, item); | ||
510 | item = new QTableWidgetItem(""); | ||
511 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
512 | m_instances_table->setItem(row, RegInstAddrColumn, item); | ||
513 | } | 603 | } |
514 | 604 | ||
515 | void RegEditPanel::OnNameEdited(const QString& text) | 605 | soc_id_t NodeInstanceEditPanel::GetId() |
516 | { | 606 | { |
517 | m_ref.GetReg().name = text.toStdString(); | 607 | return m_id; |
518 | OnModified(m_name_edit->isModified()); | ||
519 | } | 608 | } |
520 | 609 | ||
521 | void RegEditPanel::OnDescEdited() | 610 | /** |
522 | { | 611 | * NodeEditPanel |
523 | m_ref.GetReg().desc = m_desc_edit->GetTextHtml().toStdString(); | 612 | */ |
524 | OnModified(m_desc_edit->IsModified()); | ||
525 | } | ||
526 | 613 | ||
527 | void RegEditPanel::OnInstActivated(int row, int column) | 614 | NodeEditPanel::NodeEditPanel(const soc_desc::node_ref_t& ref, QWidget *parent) |
615 | :QWidget(parent), m_ref(ref) | ||
528 | { | 616 | { |
529 | if(column != 0) | 617 | /* top layout: name, title then desc */ |
530 | return; | 618 | QLineEdit *name_edit = new QLineEdit(this); |
531 | int type = m_instances_table->item(row, column)->type(); | 619 | name_edit->setText(QString::fromStdString(ref.get()->name)); |
532 | if(type == RegInstDeleteType) | 620 | |
533 | { | 621 | QLineEdit *title_edit = new QLineEdit(this); |
534 | m_ref.GetReg().addr.erase(m_ref.GetReg().addr.begin() + row); | 622 | title_edit->setText(QString::fromStdString(ref.get()->title)); |
535 | m_instances_table->removeRow(row); | 623 | |
536 | OnModified(true); | 624 | QFormLayout *info_layout = new QFormLayout(); |
537 | } | 625 | info_layout->addRow("Name", name_edit); |
538 | else if(type == RegInstNewType) | 626 | info_layout->addRow("Title", title_edit); |
627 | |||
628 | QGroupBox *info_group = Misc::EncloseInBox("Information", info_layout); | ||
629 | |||
630 | m_desc_edit = new MyTextEditor(this); | ||
631 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.get()->desc)); | ||
632 | QGroupBox *desc_group = Misc::EncloseInBox("Description", m_desc_edit); | ||
633 | |||
634 | QHBoxLayout *name_title_desc_layout = new QHBoxLayout; | ||
635 | name_title_desc_layout->addWidget(info_group, 1); | ||
636 | name_title_desc_layout->addWidget(desc_group, 2); | ||
637 | |||
638 | /* instance tab */ | ||
639 | m_instances_tab = new YTabWidget(0, this); | ||
640 | m_instances_tab->setTabOpenable(true); | ||
641 | std::vector< soc_desc::instance_t >& inst_list = m_ref.get()->instance; | ||
642 | m_instances_tab->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); | ||
643 | m_instances_tab->setTabsClosable(true); | ||
644 | QGroupBox *instance_tab_group = Misc::EncloseInBox("Instances", m_instances_tab); | ||
645 | for(size_t i = 0; i < inst_list.size(); i++) | ||
539 | { | 646 | { |
540 | m_instances_table->insertRow(row); | 647 | NodeInstanceEditPanel *p = new NodeInstanceEditPanel(m_ref, inst_list[i].id, this); |
541 | soc_reg_addr_t addr; | 648 | connect(p, SIGNAL(OnModified()), this, SLOT(OnInstModified())); |
542 | addr.name = QString("UNNAMED_%1").arg(row).toStdString(); | 649 | m_instances_tab->addTab(p, QString::fromStdString(inst_list[i].name)); |
543 | addr.addr = 0; | ||
544 | m_ref.GetReg().addr.push_back(addr); | ||
545 | FillRow(row, addr); | ||
546 | } | 650 | } |
651 | |||
652 | /* boring */ | ||
653 | QVBoxLayout *layout = new QVBoxLayout; | ||
654 | layout->addLayout(name_title_desc_layout); | ||
655 | layout->addWidget(instance_tab_group); | ||
656 | layout->addStretch(1); | ||
657 | |||
658 | setLayout(layout); | ||
659 | |||
660 | connect(name_edit, SIGNAL(textChanged(const QString&)), this, | ||
661 | SLOT(OnNameEdited(const QString&))); | ||
662 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); | ||
663 | connect(title_edit, SIGNAL(textChanged(const QString&)), this, | ||
664 | SLOT(OnTitleEdited(const QString&))); | ||
665 | connect(m_instances_tab, SIGNAL(tabCloseRequested(int)), this, | ||
666 | SLOT(OnInstRemove(int))); | ||
667 | connect(m_instances_tab, SIGNAL(tabOpenRequested()), this, SLOT(OnInstCreate())); | ||
547 | } | 668 | } |
548 | 669 | ||
549 | void RegEditPanel::OnInstChanged(int row, int column) | 670 | void NodeEditPanel::OnNameEdited(const QString& text) |
550 | { | 671 | { |
551 | /* ignore extra row for addition */ | 672 | m_ref.get()->name = text.toStdString(); |
552 | if(row >= (int)m_ref.GetReg().addr.size()) | 673 | OnModified(); |
553 | return; | 674 | } |
554 | QTableWidgetItem *item = m_instances_table->item(row, column); | 675 | |
555 | if(column == RegInstNameColumn) | 676 | void NodeEditPanel::OnTitleEdited(const QString& text) |
556 | { | 677 | { |
557 | m_ref.GetReg().addr[row].name = item->text().toStdString(); | 678 | m_ref.get()->title = text.toStdString(); |
558 | OnModified(true); | 679 | OnModified(); |
559 | } | 680 | } |
560 | else if(column == RegInstAddrColumn) | 681 | |
682 | void NodeEditPanel::OnDescEdited() | ||
683 | { | ||
684 | m_ref.get()->desc = m_desc_edit->GetTextHtml().toStdString(); | ||
685 | OnModified(); | ||
686 | } | ||
687 | |||
688 | void NodeEditPanel::OnInstRemove(int index) | ||
689 | { | ||
690 | NodeInstanceEditPanel *panel = | ||
691 | dynamic_cast< NodeInstanceEditPanel * >(m_instances_tab->widget(index)); | ||
692 | RemoveInstanceById(m_ref, panel->GetId()); | ||
693 | m_instances_tab->removeTab(index); | ||
694 | delete panel; | ||
695 | OnModified(); | ||
696 | } | ||
697 | |||
698 | void NodeEditPanel::OnInstModified() | ||
699 | { | ||
700 | int index = m_instances_tab->currentIndex(); | ||
701 | NodeInstanceEditPanel *panel = | ||
702 | dynamic_cast< NodeInstanceEditPanel * >(m_instances_tab->widget(index)); | ||
703 | m_instances_tab->setTabText(index, QString::fromStdString(panel->GetInstance().name)); | ||
704 | OnModified(); | ||
705 | } | ||
706 | |||
707 | QString NodeEditPanel::GuessName() | ||
708 | { | ||
709 | /* try to find instances named Xddd where X is the node name (case insensitive) | ||
710 | * and d are digits. */ | ||
711 | int max_nr_digits = -1; | ||
712 | int max_value = -1; | ||
713 | QString node_name = QString::fromStdString(m_ref.get()->name); | ||
714 | std::vector< soc_desc::instance_t >& inst_list = m_ref.get()->instance; | ||
715 | for(size_t i = 0; i < inst_list.size(); i++) | ||
561 | { | 716 | { |
562 | m_ref.GetReg().addr[row].addr = item->data(Qt::DisplayRole).toUInt(); | 717 | QString inst_name = QString::fromStdString(inst_list[i].name); |
563 | OnModified(true); | 718 | /* ignore name if it doesn't start like the node name */ |
719 | if(!inst_name.startsWith(node_name, Qt::CaseInsensitive)) | ||
720 | continue; | ||
721 | /* check if the suffix is a digit */ | ||
722 | QString suffix = inst_name.mid(node_name.size()); | ||
723 | if(suffix.size() == 0) | ||
724 | { | ||
725 | max_nr_digits = qMax(max_nr_digits, 0); | ||
726 | continue; | ||
727 | } | ||
728 | bool ok; | ||
729 | int value = suffix.toUInt(&ok); | ||
730 | if(!ok) | ||
731 | continue; | ||
732 | max_value = qMax(max_value, value); | ||
733 | max_nr_digits = qMax(max_nr_digits, suffix.size()); | ||
564 | } | 734 | } |
735 | /* if no match, use node name */ | ||
736 | if(max_nr_digits == -1) | ||
737 | return node_name; | ||
738 | /* match of size 0, add "1" at the end */ | ||
739 | if(max_nr_digits == 0) | ||
740 | return node_name + "1"; | ||
741 | /* otherwise, pick next value */ | ||
742 | return QString("%1%2").arg(node_name) | ||
743 | .arg(max_value + 1, max_nr_digits, 10, QChar('0')); | ||
744 | } | ||
745 | |||
746 | void NodeEditPanel::OnInstCreate() | ||
747 | { | ||
748 | std::vector< soc_desc::instance_t >& inst_list = m_ref.get()->instance; | ||
749 | soc_desc::instance_t inst; | ||
750 | inst.id = GetFreshId(inst_list); | ||
751 | inst.name = GuessName().toStdString(); | ||
752 | inst.type = soc_desc::instance_t::SINGLE; | ||
753 | inst.addr = 0; | ||
754 | inst.range.type = soc_desc::range_t::STRIDE; | ||
755 | inst.range.first = 0; | ||
756 | inst.range.count = 0; | ||
757 | inst.range.stride = 0; | ||
758 | inst_list.push_back(inst); | ||
759 | NodeInstanceEditPanel *p = new NodeInstanceEditPanel(m_ref, inst.id, this); | ||
760 | connect(p, SIGNAL(OnModified()), this, SLOT(OnInstModified())); | ||
761 | int idx = m_instances_tab->addTab(p, QString::fromStdString(inst.name)); | ||
762 | m_instances_tab->setCurrentIndex(idx); | ||
763 | OnModified(); | ||
565 | } | 764 | } |
566 | 765 | ||
567 | /** | 766 | /** |
568 | * FieldEditPanel | 767 | * RegFieldEditPanel |
569 | */ | 768 | */ |
570 | FieldEditPanel::FieldEditPanel(SocFieldRef ref, QWidget *parent) | 769 | |
770 | namespace | ||
771 | { | ||
772 | |||
773 | enum | ||
774 | { | ||
775 | RegFieldEditPanelDelType = QTableWidgetItem::UserType, | ||
776 | RegFieldEditPanelAddType, | ||
777 | }; | ||
778 | |||
779 | } | ||
780 | |||
781 | RegFieldEditPanel::RegFieldEditPanel(const soc_desc::field_ref_t& ref, QWidget *parent) | ||
571 | :QWidget(parent), m_ref(ref) | 782 | :QWidget(parent), m_ref(ref) |
572 | { | 783 | { |
573 | m_name_group = new QGroupBox("Name", this); | ||
574 | m_name_edit = new QLineEdit(this); | 784 | m_name_edit = new QLineEdit(this); |
575 | m_name_edit->setText(QString::fromStdString(ref.GetField().name)); | 785 | m_range_edit = new QLineEdit(this); |
576 | QVBoxLayout *name_group_layout = new QVBoxLayout; | 786 | m_range_validator = new SocBitRangeValidator(this); |
577 | name_group_layout->addWidget(m_name_edit); | 787 | m_range_validator->setWidth(m_ref.reg().get()->width); |
578 | m_name_group->setLayout(name_group_layout); | 788 | m_range_edit->setValidator(m_range_validator); |
579 | |||
580 | m_bitrange_group = new QGroupBox("Bit Range", this); | ||
581 | m_bitrange_edit = new QLineEdit(this); | ||
582 | const soc_reg_field_t& field = ref.GetField(); | ||
583 | QString bits_str; | ||
584 | if(field.first_bit == field.last_bit) | ||
585 | bits_str.sprintf("%d", field.first_bit); | ||
586 | else | ||
587 | bits_str.sprintf("%d:%d", field.last_bit, field.first_bit); | ||
588 | m_bitrange_edit->setText(bits_str); | ||
589 | m_bitrange_edit->setValidator(new SocBitRangeValidator(m_bitrange_edit)); | ||
590 | QVBoxLayout *bitrange_group_layout = new QVBoxLayout; | ||
591 | bitrange_group_layout->addWidget(m_bitrange_edit); | ||
592 | m_bitrange_group->setLayout(bitrange_group_layout); | ||
593 | |||
594 | m_desc_group = new QGroupBox("Description", this); | ||
595 | QHBoxLayout *group_layout = new QHBoxLayout; | ||
596 | m_desc_edit = new MyTextEditor(this); | 789 | m_desc_edit = new MyTextEditor(this); |
597 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetField().desc)); | 790 | QHBoxLayout *namepos_layout = new QHBoxLayout; |
598 | group_layout->addWidget(m_desc_edit); | 791 | namepos_layout->addWidget(new QLabel("Name:")); |
599 | m_desc_group->setLayout(group_layout); | 792 | namepos_layout->addWidget(m_name_edit); |
600 | 793 | namepos_layout->addWidget(new QLabel("Range:")); | |
601 | m_value_group = new QGroupBox("Values", this); | 794 | namepos_layout->addWidget(m_range_edit); |
602 | QHBoxLayout *value_layout = new QHBoxLayout; | 795 | QVBoxLayout *nameposdesc_layout = new QVBoxLayout; |
603 | m_value_table = new QTableWidget(this); | 796 | nameposdesc_layout->addWidget(Misc::EncloseInBox("Information", namepos_layout)); |
604 | m_value_table->setRowCount(ref.GetField().value.size() + 1); | 797 | nameposdesc_layout->addWidget(Misc::EncloseInBox("Description", m_desc_edit)); |
605 | m_value_table->setColumnCount(FieldValueNrColumns); | 798 | nameposdesc_layout->addStretch(0); |
606 | for(size_t row = 0; row < ref.GetField().value.size(); row++) | 799 | |
607 | FillRow(row, ref.GetField().value[row]); | 800 | m_enum_table = new QTableWidget(this); |
608 | CreateNewRow(ref.GetField().value.size()); | 801 | m_enum_table->setColumnCount(4); |
609 | m_value_table->setHorizontalHeaderItem(FieldValueIconColumn, new QTableWidgetItem("")); | 802 | m_enum_table->setHorizontalHeaderItem(0, new QTableWidgetItem("")); |
610 | m_value_table->setHorizontalHeaderItem(FieldValueNameColumn, new QTableWidgetItem("Name")); | 803 | m_enum_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name")); |
611 | m_value_table->setHorizontalHeaderItem(FieldValueValueColumn, new QTableWidgetItem("Value")); | 804 | m_enum_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Value")); |
612 | m_value_table->setHorizontalHeaderItem(FieldValueDescColumn, new QTableWidgetItem("Description")); | 805 | m_enum_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Description")); |
613 | m_value_table->verticalHeader()->setVisible(false); | 806 | m_enum_table->verticalHeader()->setVisible(false); |
614 | m_value_table->horizontalHeader()->setStretchLastSection(true); | 807 | m_enum_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
615 | value_layout->addWidget(m_value_table); | 808 | m_enum_delegate = new SocFieldItemDelegate(this); |
616 | m_value_group->setLayout(value_layout); | 809 | m_enum_delegate->setItemEditorFactory(new QItemEditorFactory); |
617 | 810 | m_enum_editor = new SocFieldEditorCreator; | |
618 | QHBoxLayout *line_layout = new QHBoxLayout; | 811 | m_enum_delegate->itemEditorFactory()->registerEditor(QVariant::UInt, m_enum_editor); |
619 | line_layout->addWidget(m_name_group); | 812 | m_enum_table->setItemDelegate(m_enum_delegate); |
620 | line_layout->addWidget(m_bitrange_group); | ||
621 | line_layout->addStretch(); | ||
622 | |||
623 | QVBoxLayout *left_layout = new QVBoxLayout; | ||
624 | left_layout->addLayout(line_layout); | ||
625 | left_layout->addWidget(m_desc_group); | ||
626 | left_layout->addWidget(m_value_group, 1); | ||
627 | |||
628 | UpdateDelegates(); | ||
629 | |||
630 | connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&))); | ||
631 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); | ||
632 | connect(m_value_table, SIGNAL(cellActivated(int,int)), this, SLOT(OnValueActivated(int,int))); | ||
633 | connect(m_value_table, SIGNAL(cellChanged(int,int)), this, SLOT(OnValueChanged(int,int))); | ||
634 | connect(m_bitrange_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnBitRangeEdited(const QString&))); | ||
635 | 813 | ||
636 | setLayout(left_layout); | 814 | QHBoxLayout *field_layout = new QHBoxLayout; |
815 | field_layout->addLayout(nameposdesc_layout); | ||
816 | field_layout->addWidget(Misc::EncloseInBox("Special Values", m_enum_table), 1); | ||
817 | |||
818 | setLayout(field_layout); | ||
819 | |||
820 | const soc_desc::field_t& field = *m_ref.get(); | ||
821 | m_name_edit->setText(QString::fromStdString(field.name)); | ||
822 | m_range_edit->setText(m_range_validator->generate( | ||
823 | field.pos + field.width - 1, field.pos)); | ||
824 | m_desc_edit->SetTextHtml(QString::fromStdString(field.desc)); | ||
825 | m_enum_delegate->setWidth(field.width); | ||
826 | m_enum_editor->setWidth(field.width); | ||
827 | m_enum_table->setRowCount(field.enum_.size() + 1); | ||
828 | for(size_t i = 0; i < field.enum_.size(); i++) | ||
829 | { | ||
830 | QTableWidgetItem *item = new QTableWidgetItem( | ||
831 | QIcon::fromTheme("list-remove"), "", RegFieldEditPanelDelType); | ||
832 | item->setFlags(Qt::ItemIsEnabled); | ||
833 | m_enum_table->setItem(i, 0, item); | ||
834 | item = new QTableWidgetItem(QString::fromStdString(field.enum_[i].name)); | ||
835 | m_enum_table->setItem(i, 1, item); | ||
836 | item = new QTableWidgetItem(); | ||
837 | item->setData(Qt::EditRole, QVariant(field.enum_[i].value)); | ||
838 | m_enum_table->setItem(i, 2, item); | ||
839 | item = new QTableWidgetItem(QString::fromStdString(field.enum_[i].desc)); | ||
840 | m_enum_table->setItem(i, 3, item); | ||
841 | } | ||
842 | QTableWidgetItem *new_item = new QTableWidgetItem( | ||
843 | QIcon::fromTheme("list-add"), "", RegFieldEditPanelAddType); | ||
844 | new_item->setFlags(Qt::ItemIsEnabled); | ||
845 | m_enum_table->setItem(field.enum_.size(), 0, new_item); | ||
846 | new_item = new QTableWidgetItem("New field..."); | ||
847 | new_item->setFlags(Qt::ItemIsEnabled); | ||
848 | QFont font = new_item->font(); | ||
849 | font.setItalic(true); | ||
850 | new_item->setFont(font); | ||
851 | m_enum_table->setItem(field.enum_.size(), 1, new_item); | ||
852 | new_item = new QTableWidgetItem(); | ||
853 | new_item->setFlags(Qt::ItemIsEnabled); | ||
854 | m_enum_table->setItem(field.enum_.size(), 2, new_item); | ||
855 | new_item = new QTableWidgetItem(); | ||
856 | new_item->setFlags(Qt::ItemIsEnabled); | ||
857 | m_enum_table->setItem(field.enum_.size(), 3, new_item); | ||
858 | m_enum_table->resizeColumnsToContents(); | ||
859 | m_enum_table->horizontalHeader()->setStretchLastSection(true); | ||
860 | |||
861 | connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, | ||
862 | SLOT(OnFieldNameChanged(const QString&))); | ||
863 | connect(m_range_edit, SIGNAL(textChanged(const QString&)), this, | ||
864 | SLOT(OnFieldRangeChanged(const QString&))); | ||
865 | connect(m_desc_edit, SIGNAL(OnTextChanged(const QString&)), this, | ||
866 | SLOT(OnFieldDescChanged(const QString&))); | ||
867 | connect(m_enum_table, SIGNAL(itemActivated(QTableWidgetItem *)), this, | ||
868 | SLOT(OnFieldValueActivated(QTableWidgetItem *))); | ||
869 | connect(m_enum_table, SIGNAL(itemChanged(QTableWidgetItem *)), this, | ||
870 | SLOT(OnFieldValueChanged(QTableWidgetItem *))); | ||
637 | } | 871 | } |
638 | 872 | ||
639 | void FieldEditPanel::UpdateDelegates() | 873 | void RegFieldEditPanel::UpdateWidth() |
640 | { | 874 | { |
641 | SocFieldItemDelegate *m_table_delegate = new SocFieldItemDelegate(m_ref.GetField(), this); | 875 | m_range_validator->setWidth(m_ref.reg().get()->width); |
642 | QItemEditorFactory *m_table_edit_factory = new QItemEditorFactory(); | ||
643 | SocFieldEditorCreator *m_table_edit_creator = new SocFieldEditorCreator(m_ref.GetField()); | ||
644 | m_table_edit_factory->registerEditor(QVariant::UInt, m_table_edit_creator); | ||
645 | m_table_delegate->setItemEditorFactory(m_table_edit_factory); | ||
646 | m_value_table->setItemDelegate(m_table_delegate); | ||
647 | m_value_table->resizeColumnsToContents(); | ||
648 | } | 876 | } |
649 | 877 | ||
650 | void FieldEditPanel::UpdateWarning(int row) | 878 | void RegFieldEditPanel::OnFieldValueActivated(QTableWidgetItem *item) |
651 | { | 879 | { |
652 | soc_word_t val = m_ref.GetField().value[row].value; | 880 | if(item->type() == RegFieldEditPanelDelType) |
653 | soc_word_t max = m_ref.GetField().bitmask() >> m_ref.GetField().first_bit; | ||
654 | QTableWidgetItem *item = m_value_table->item(row, FieldValueValueColumn); | ||
655 | if(val > max) | ||
656 | { | 881 | { |
657 | item->setIcon(QIcon::fromTheme("dialog-warning")); | 882 | int row = item->row(); |
658 | item->setToolTip("Value is too big for the field"); | 883 | my_remove_at(m_ref.get()->enum_, row); |
884 | m_enum_table->removeRow(row); | ||
885 | OnModified(); | ||
659 | } | 886 | } |
660 | else | 887 | else if(item->type() == RegFieldEditPanelAddType) |
661 | { | 888 | { |
662 | item->setIcon(QIcon()); | 889 | soc_desc::field_t& field = *m_ref.get(); |
663 | item->setToolTip(""); | 890 | int row = field.enum_.size(); |
891 | soc_desc::enum_t new_enum; | ||
892 | new_enum.id = GetFreshId(field.enum_); | ||
893 | new_enum.name = "UNNAMED"; | ||
894 | new_enum.value = 0; | ||
895 | field.enum_.push_back(new_enum); | ||
896 | m_enum_table->insertRow(row); | ||
897 | QTableWidgetItem *item = new QTableWidgetItem( | ||
898 | QIcon::fromTheme("list-remove"), "", RegFieldEditPanelDelType); | ||
899 | item->setFlags(Qt::ItemIsEnabled); | ||
900 | m_enum_table->setItem(row, 0, item); | ||
901 | item = new QTableWidgetItem(QString::fromStdString(new_enum.name)); | ||
902 | m_enum_table->setItem(row, 1, item); | ||
903 | item = new QTableWidgetItem(); | ||
904 | item->setData(Qt::EditRole, QVariant(new_enum.value)); | ||
905 | m_enum_table->setItem(row, 2, item); | ||
906 | item = new QTableWidgetItem(QString::fromStdString(new_enum.desc)); | ||
907 | m_enum_table->setItem(row, 3, item); | ||
908 | OnModified(); | ||
664 | } | 909 | } |
665 | } | 910 | } |
666 | 911 | ||
667 | void FieldEditPanel::FillRow(int row, const soc_reg_field_value_t& val) | 912 | void RegFieldEditPanel::OnFieldValueChanged(QTableWidgetItem *item) |
668 | { | 913 | { |
669 | QTableWidgetItem *item = new QTableWidgetItem(QString::fromStdString(val.name)); | 914 | soc_desc::field_t& field = *m_ref.get(); |
670 | item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | 915 | if((size_t)item->row() >= field.enum_.size()) |
671 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | 916 | return; |
672 | m_value_table->setItem(row, FieldValueNameColumn, item); | 917 | soc_desc::enum_t& enum_ = field.enum_[item->row()]; |
673 | item = new QTableWidgetItem(); | 918 | if(item->column() == 1) |
674 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | 919 | enum_.name = item->text().toStdString(); |
675 | item->setData(Qt::DisplayRole, QVariant(val.value)); | 920 | else if(item->column() == 2) |
676 | m_value_table->setItem(row, FieldValueValueColumn, item); | 921 | enum_.value = item->data(Qt::EditRole).value< soc_word_t >(); |
677 | item = new QTableWidgetItem(QString::fromStdString(val.desc)); | 922 | else if(item->column() == 3) |
678 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | 923 | enum_.desc = item->text().toStdString(); |
679 | m_value_table->setItem(row, FieldValueDescColumn, item); | 924 | OnModified(); |
680 | item = new QTableWidgetItem(QIcon::fromTheme("list-remove"), "", FieldValueDeleteType); | 925 | } |
681 | item->setToolTip("Remove?"); | 926 | |
682 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | 927 | void RegFieldEditPanel::OnFieldNameChanged(const QString& name) |
683 | m_value_table->setItem(row, FieldValueIconColumn, item); | 928 | { |
684 | UpdateWarning(row); | 929 | m_ref.get()->name = name.toStdString(); |
685 | } | 930 | OnModified(); |
686 | |||
687 | void FieldEditPanel::CreateNewRow(int row) | ||
688 | { | ||
689 | QTableWidgetItem *item = new QTableWidgetItem(QIcon::fromTheme("list-add"), "", FieldValueNewType); | ||
690 | item->setToolTip("New?"); | ||
691 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
692 | m_value_table->setItem(row, FieldValueIconColumn, item); | ||
693 | item = new QTableWidgetItem("New value..."); | ||
694 | QFont font = item->font(); | ||
695 | font.setItalic(true); | ||
696 | item->setFont(font); | ||
697 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
698 | m_value_table->setItem(row, FieldValueNameColumn, item); | ||
699 | } | 931 | } |
700 | 932 | ||
701 | void FieldEditPanel::OnBitRangeEdited(const QString& input) | 933 | void RegFieldEditPanel::OnFieldRangeChanged(const QString& range) |
702 | { | 934 | { |
703 | const SocBitRangeValidator *validator = | 935 | soc_desc::field_t *field = m_ref.get(); |
704 | dynamic_cast< const SocBitRangeValidator *>(m_bitrange_edit->validator()); | 936 | int last, first; |
705 | int first, last; | 937 | if(m_range_validator->parse(range, last, first) != QValidator::Acceptable) |
706 | QValidator::State state = validator->parse(input, last, first); | ||
707 | if(state != QValidator::Acceptable) | ||
708 | return; | 938 | return; |
709 | m_ref.GetField().first_bit = first; | 939 | field->pos = first; |
710 | m_ref.GetField().last_bit = last; | 940 | field->width = last - first + 1; |
711 | // update all warning signs | 941 | m_enum_delegate->setWidth(field->width); |
712 | for(size_t row = 0; row < m_ref.GetField().value.size(); row++) | 942 | m_enum_editor->setWidth(field->width); |
713 | UpdateWarning(row); | 943 | OnModified(); |
714 | // also updates delegates because they now have the wrong view of the field | ||
715 | UpdateDelegates(); | ||
716 | OnModified(true); | ||
717 | } | 944 | } |
718 | 945 | ||
719 | void FieldEditPanel::OnNameEdited(const QString& text) | 946 | void RegFieldEditPanel::OnFieldDescChanged(const QString& desc) |
720 | { | 947 | { |
721 | m_ref.GetField().name = text.toStdString(); | 948 | m_ref.get()->desc = desc.toStdString(); |
722 | OnModified(m_name_edit->isModified()); | 949 | OnModified(); |
723 | } | 950 | } |
724 | 951 | ||
725 | void FieldEditPanel::OnDescEdited() | 952 | soc_desc::field_ref_t RegFieldEditPanel::GetField() |
726 | { | 953 | { |
727 | m_ref.GetField().desc = m_desc_edit->GetTextHtml().toStdString(); | 954 | return m_ref; |
728 | OnModified(m_desc_edit->IsModified()); | ||
729 | } | 955 | } |
730 | 956 | ||
731 | void FieldEditPanel::OnValueActivated(int row, int column) | 957 | /** |
958 | * RegEditPanel | ||
959 | */ | ||
960 | |||
961 | namespace | ||
732 | { | 962 | { |
733 | if(column != 0) | 963 | |
734 | return; | 964 | enum |
735 | int type = m_value_table->item(row, column)->type(); | 965 | { |
736 | if(type == FieldValueDeleteType) | 966 | RegVariantEditPanelDelType = QTableWidgetItem::UserType, |
967 | RegVariantEditPanelAddType, | ||
968 | }; | ||
969 | |||
970 | } | ||
971 | |||
972 | RegEditPanel::RegEditPanel(const soc_desc::register_ref_t& ref, QWidget *parent) | ||
973 | :QWidget(parent), m_ref(ref), m_reg_font(font()) | ||
974 | { | ||
975 | m_reg_font.setWeight(100); | ||
976 | m_reg_font.setKerning(false); | ||
977 | |||
978 | m_value_model = new RegFieldTableModel(this); // view takes ownership | ||
979 | m_value_model->SetRegister(*ref.get()); | ||
980 | m_value_model->SetReadOnly(true); | ||
981 | |||
982 | m_sexy_display2 = new Unscroll<YRegDisplay>(this); | ||
983 | m_sexy_display2->setFont(m_reg_font); | ||
984 | m_sexy_display2->setModel(m_value_model); | ||
985 | m_sexy_display2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
986 | m_sexy_display2->setContextMenuPolicy(Qt::CustomContextMenu); | ||
987 | m_sexy_display2->setWidth(m_ref.get()->width); | ||
988 | |||
989 | m_view_tab = new QTabWidget(this); | ||
990 | m_view_tab->setTabPosition(QTabWidget::West); | ||
991 | |||
992 | /* field tab */ | ||
993 | m_fields_tab = new YTabWidget(0, this); | ||
994 | m_fields_tab->setTabOpenable(true); | ||
995 | std::vector< soc_desc::field_ref_t > field_list = m_ref.fields(); | ||
996 | m_fields_tab->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); | ||
997 | m_fields_tab->setTabsClosable(true); | ||
998 | m_fields_tab->setElideMode(Qt::ElideRight); | ||
999 | for(size_t i = 0; i < field_list.size(); i++) | ||
737 | { | 1000 | { |
738 | m_ref.GetField().value.erase(m_ref.GetField().value.begin() + row); | 1001 | RegFieldEditPanel *p = new RegFieldEditPanel(field_list[i], this); |
739 | m_value_table->removeRow(row); | 1002 | connect(p, SIGNAL(OnModified()), this, SLOT(OnFieldModified())); |
740 | OnModified(true); | 1003 | m_fields_tab->addTab(p, QString::fromStdString(field_list[i].get()->name)); |
741 | } | 1004 | } |
742 | else if(type == FieldValueNewType) | 1005 | |
1006 | m_reg_size_group = new QButtonGroup(this); | ||
1007 | QRadioButton *reg_size_32 = new QRadioButton("32-bit"); | ||
1008 | QRadioButton *reg_size_16 = new QRadioButton("16-bit"); | ||
1009 | QRadioButton *reg_size_8 = new QRadioButton("8-bit"); | ||
1010 | m_reg_size_group->addButton(reg_size_32, 32); | ||
1011 | m_reg_size_group->addButton(reg_size_16, 16); | ||
1012 | m_reg_size_group->addButton(reg_size_8, 8); | ||
1013 | if(m_reg_size_group->button(m_ref.get()->width)) | ||
1014 | m_reg_size_group->button(m_ref.get()->width)->click(); | ||
1015 | QVBoxLayout *width_group_layout = new QVBoxLayout; | ||
1016 | width_group_layout->addWidget(reg_size_32); | ||
1017 | width_group_layout->addWidget(reg_size_16); | ||
1018 | width_group_layout->addWidget(reg_size_8); | ||
1019 | width_group_layout->addStretch(0); | ||
1020 | QGroupBox *width_group = new QGroupBox("Width"); | ||
1021 | width_group->setLayout(width_group_layout); | ||
1022 | |||
1023 | m_variant_table = new QTableWidget; | ||
1024 | m_variant_table->setColumnCount(3); | ||
1025 | m_variant_table->setHorizontalHeaderItem(0, new QTableWidgetItem("")); | ||
1026 | m_variant_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Type")); | ||
1027 | m_variant_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Offset")); | ||
1028 | m_variant_table->verticalHeader()->setVisible(false); | ||
1029 | m_variant_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
1030 | m_variant_delegate = new SocFieldItemDelegate(this); | ||
1031 | m_variant_delegate->setItemEditorFactory(new QItemEditorFactory); | ||
1032 | m_variant_editor = new SocFieldEditorCreator; | ||
1033 | m_variant_delegate->itemEditorFactory()->registerEditor(QVariant::UInt, m_variant_editor); | ||
1034 | m_variant_table->setItemDelegate(m_variant_delegate); | ||
1035 | |||
1036 | std::vector< soc_desc::variant_ref_t > variants = m_ref.variants(); | ||
1037 | m_variant_table->setRowCount(variants.size() + 1); | ||
1038 | for(size_t i = 0; i < variants.size(); i++) | ||
743 | { | 1039 | { |
744 | m_value_table->insertRow(row); | 1040 | QTableWidgetItem *item = new QTableWidgetItem( |
745 | soc_reg_field_value_t val; | 1041 | QIcon::fromTheme("list-remove"), "", RegVariantEditPanelDelType); |
746 | val.name = QString("UNNAMED_%1").arg(row).toStdString(); | 1042 | item->setFlags(Qt::ItemIsEnabled); |
747 | val.value = 0; | 1043 | m_variant_table->setItem(i, 0, item); |
748 | m_ref.GetField().value.push_back(val); | 1044 | item = new QTableWidgetItem(QString::fromStdString(variants[i].get()->type)); |
749 | FillRow(row, val); | 1045 | m_variant_table->setItem(i, 1, item); |
1046 | item = new QTableWidgetItem(); | ||
1047 | item->setData(Qt::EditRole, QVariant(variants[i].get()->offset)); | ||
1048 | m_variant_table->setItem(i, 2, item); | ||
750 | } | 1049 | } |
1050 | QTableWidgetItem *new_item = new QTableWidgetItem( | ||
1051 | QIcon::fromTheme("list-add"), "", RegVariantEditPanelAddType); | ||
1052 | new_item->setFlags(Qt::ItemIsEnabled); | ||
1053 | m_variant_table->setItem(variants.size(), 0, new_item); | ||
1054 | new_item = new QTableWidgetItem("New variant..."); | ||
1055 | new_item->setFlags(Qt::ItemIsEnabled); | ||
1056 | QFont font = new_item->font(); | ||
1057 | font.setItalic(true); | ||
1058 | new_item->setFont(font); | ||
1059 | m_variant_table->setItem(variants.size(), 1, new_item); | ||
1060 | new_item = new QTableWidgetItem(); | ||
1061 | new_item->setFlags(Qt::ItemIsEnabled); | ||
1062 | m_variant_table->setItem(variants.size(), 2, new_item); | ||
1063 | new_item = new QTableWidgetItem(); | ||
1064 | new_item->setFlags(Qt::ItemIsEnabled); | ||
1065 | m_variant_table->resizeColumnsToContents(); | ||
1066 | m_variant_table->horizontalHeader()->setStretchLastSection(true); | ||
1067 | |||
1068 | m_desc_edit = new MyTextEditor(this); | ||
1069 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.get()->desc)); | ||
1070 | |||
1071 | QHBoxLayout *top_info_layout = new QHBoxLayout; | ||
1072 | top_info_layout->addWidget(width_group); | ||
1073 | top_info_layout->addWidget(Misc::EncloseInBox("Variants", m_variant_table)); | ||
1074 | top_info_layout->addWidget(Misc::EncloseInBox("Description", m_desc_edit)); | ||
1075 | |||
1076 | QWidget *reg_info = new QWidget(this); | ||
1077 | QVBoxLayout *reg_info_layout = new QVBoxLayout; | ||
1078 | reg_info_layout->addLayout(top_info_layout); | ||
1079 | reg_info_layout->addStretch(0); | ||
1080 | reg_info->setLayout(reg_info_layout); | ||
1081 | |||
1082 | m_view_tab->addTab(reg_info, "Information"); | ||
1083 | m_view_tab->addTab(m_fields_tab, "Fields"); | ||
1084 | |||
1085 | QVBoxLayout *main_layout = new QVBoxLayout; | ||
1086 | main_layout->addWidget(m_sexy_display2, 1); | ||
1087 | main_layout->addWidget(m_view_tab, 2); | ||
1088 | |||
1089 | m_delete_action = new QAction("&Delete", this); | ||
1090 | m_delete_action->setIcon(QIcon::fromTheme("list-remove")); | ||
1091 | m_new_action = new QAction("&New field", this); | ||
1092 | m_new_action->setIcon(QIcon::fromTheme("list-add")); | ||
1093 | |||
1094 | setLayout(main_layout); | ||
1095 | |||
1096 | OnRegFieldActivated(QModelIndex()); | ||
1097 | UpdateWidthRestrictions(); | ||
1098 | |||
1099 | connect(m_sexy_display2, SIGNAL(clicked(const QModelIndex&)), this, | ||
1100 | SLOT(OnRegFieldActivated(const QModelIndex&))); | ||
1101 | connect(m_sexy_display2, SIGNAL(customContextMenuRequested(QPoint)), this, | ||
1102 | SLOT(OnRegDisplayContextMenu(QPoint))); | ||
1103 | connect(m_reg_size_group, SIGNAL(buttonClicked(int)), this, SLOT(OnWidthChanged(int))); | ||
1104 | connect(m_delete_action, SIGNAL(triggered()), this, SLOT(OnRegFieldDelete())); | ||
1105 | connect(m_new_action, SIGNAL(triggered()), this, SLOT(OnRegFieldNew())); | ||
1106 | connect(m_variant_table, SIGNAL(itemActivated(QTableWidgetItem *)), this, | ||
1107 | SLOT(OnVariantActivated(QTableWidgetItem *))); | ||
1108 | connect(m_variant_table, SIGNAL(itemChanged(QTableWidgetItem *)), this, | ||
1109 | SLOT(OnVariantValueChanged(QTableWidgetItem *))); | ||
1110 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); | ||
1111 | connect(m_fields_tab, SIGNAL(tabCloseRequested(int)), this, SLOT(OnFieldRemove(int))); | ||
1112 | connect(m_fields_tab, SIGNAL(tabOpenRequested()), this, SLOT(OnFieldCreate())); | ||
751 | } | 1113 | } |
752 | 1114 | ||
753 | void FieldEditPanel::OnValueChanged(int row, int column) | 1115 | void RegEditPanel::UpdateWidthRestrictions() |
754 | { | 1116 | { |
755 | /* ignore extra row for addition */ | 1117 | /* only allow width large enough to fit all fields */ |
756 | if(row >= (int)m_ref.GetField().value.size()) | 1118 | size_t max_bit = 0; |
757 | return; | 1119 | std::vector< soc_desc::field_ref_t > field_list = m_ref.fields(); |
758 | QTableWidgetItem *item = m_value_table->item(row, column); | 1120 | for(size_t i = 0; i < field_list.size(); i++) |
759 | if(column == FieldValueNameColumn) | ||
760 | m_ref.GetField().value[row].name = item->text().toStdString(); | ||
761 | else if(column == FieldValueValueColumn) | ||
762 | { | 1121 | { |
763 | soc_word_t& fval = m_ref.GetField().value[row].value; | 1122 | soc_desc::field_t& f = *field_list[i].get(); |
764 | soc_word_t new_val = item->data(Qt::DisplayRole).toUInt(); | 1123 | max_bit = std::max(max_bit, f.pos + f.width - 1); |
765 | /* avoid infinite recursion by calling UpdateWarning() when | ||
766 | * only the icon changes which would trigger this callback again */ | ||
767 | if(fval != new_val) | ||
768 | { | ||
769 | fval = new_val; | ||
770 | UpdateWarning(row); | ||
771 | } | ||
772 | } | 1124 | } |
773 | else if(column == FieldValueDescColumn) | 1125 | /* update buttons */ |
774 | m_ref.GetField().value[row].desc = item->text().toStdString(); | 1126 | m_reg_size_group->button(8)->setEnabled(max_bit < 8); |
775 | OnModified(true); | 1127 | m_reg_size_group->button(16)->setEnabled(max_bit < 16); |
1128 | m_reg_size_group->button(32)->setEnabled(max_bit < 32); | ||
776 | } | 1129 | } |
777 | 1130 | ||
778 | namespace | 1131 | int RegEditPanel::IndexById(soc_id_t id) |
779 | { | 1132 | { |
1133 | for(int i = 0; i < m_fields_tab->count(); i++) | ||
1134 | { | ||
1135 | RegFieldEditPanel *p = dynamic_cast< RegFieldEditPanel * >(m_fields_tab->widget(i)); | ||
1136 | if(p->GetField().get()->id == id) | ||
1137 | return i; | ||
1138 | } | ||
1139 | return -1; | ||
1140 | } | ||
780 | 1141 | ||
781 | enum | 1142 | void RegEditPanel::OnWidthChanged(int w) |
782 | { | 1143 | { |
783 | SocTreeSocType = QTreeWidgetItem::UserType, | 1144 | m_ref.get()->width = w; |
784 | SocTreeDevType, | 1145 | m_sexy_display2->setWidth(w); |
785 | SocTreeRegType, | 1146 | for(int i = 0; i < m_fields_tab->count(); i++) |
786 | SocTreeFieldType, | 1147 | dynamic_cast< RegFieldEditPanel * >(m_fields_tab->widget(i))->UpdateWidth(); |
787 | SocTreeNewDevType, | 1148 | OnModified(); |
788 | SocTreeNewRegType, | 1149 | } |
789 | SocTreeNewFieldType, | ||
790 | }; | ||
791 | |||
792 | /** | ||
793 | * SocTreeItem | ||
794 | */ | ||
795 | 1150 | ||
796 | class SocTreeItem : public QTreeWidgetItem | 1151 | void RegEditPanel::OnDescEdited() |
797 | { | 1152 | { |
798 | public: | 1153 | m_ref.get()->desc = m_desc_edit->GetTextHtml().toStdString(); |
799 | SocTreeItem(const QString& string, const SocRef& ref) | 1154 | OnModified(); |
800 | :QTreeWidgetItem(QStringList(string), SocTreeSocType), m_ref(ref) {} | 1155 | } |
801 | 1156 | ||
802 | const SocRef& GetRef() { return m_ref; } | 1157 | void RegEditPanel::OnVariantActivated(QTableWidgetItem *item) |
803 | private: | 1158 | { |
804 | SocRef m_ref; | 1159 | if(item->type() == RegVariantEditPanelDelType) |
805 | }; | 1160 | { |
1161 | int row = item->row(); | ||
1162 | my_remove_at(m_ref.get()->variant, row); | ||
1163 | m_variant_table->removeRow(row); | ||
1164 | OnModified(); | ||
1165 | } | ||
1166 | else if(item->type() == RegVariantEditPanelAddType) | ||
1167 | { | ||
1168 | int row = m_ref.get()->variant.size(); | ||
1169 | soc_desc::variant_t& variant = *m_ref.create_variant().get(); | ||
1170 | variant.type = "untyped"; | ||
1171 | variant.offset = 0; | ||
1172 | m_variant_table->insertRow(row); | ||
1173 | QTableWidgetItem *item = new QTableWidgetItem( | ||
1174 | QIcon::fromTheme("list-remove"), "", RegVariantEditPanelDelType); | ||
1175 | item->setFlags(Qt::ItemIsEnabled); | ||
1176 | m_variant_table->setItem(row, 0, item); | ||
1177 | item = new QTableWidgetItem(QString::fromStdString(variant.type)); | ||
1178 | m_variant_table->setItem(row, 1, item); | ||
1179 | item = new QTableWidgetItem(); | ||
1180 | item->setData(Qt::EditRole, QVariant(variant.offset)); | ||
1181 | m_variant_table->setItem(row, 2, item); | ||
1182 | OnModified(); | ||
1183 | } | ||
1184 | } | ||
806 | 1185 | ||
807 | /** | 1186 | void RegEditPanel::OnVariantValueChanged(QTableWidgetItem *item) |
808 | * NewDevTreeItem | 1187 | { |
809 | */ | 1188 | soc_desc::register_t& reg = *m_ref.get(); |
1189 | if((size_t)item->row() >= reg.variant.size()) | ||
1190 | return; | ||
1191 | soc_desc::variant_t& var = reg.variant[item->row()]; | ||
1192 | if(item->column() == 1) | ||
1193 | var.type = item->text().toStdString(); | ||
1194 | else if(item->column() == 2) | ||
1195 | var.offset = item->data(Qt::EditRole).value< soc_word_t >(); | ||
1196 | OnModified(); | ||
1197 | } | ||
810 | 1198 | ||
811 | class NewDevTreeItem : public QTreeWidgetItem | 1199 | void RegEditPanel::OnRegFieldActivated(const QModelIndex& index) |
812 | { | 1200 | { |
813 | public: | 1201 | if(!index.isValid()) |
814 | NewDevTreeItem(const QString& string, const SocRef& ref) | 1202 | return; |
815 | :QTreeWidgetItem(QStringList(string), SocTreeNewDevType), m_ref(ref) {} | 1203 | m_fields_tab->setCurrentIndex(IndexById(m_ref.get()->field[index.row()].id)); |
1204 | m_view_tab->setCurrentIndex(1); | ||
1205 | } | ||
816 | 1206 | ||
817 | const SocRef& GetRef() { return m_ref; } | 1207 | void RegEditPanel::OnFieldModified() |
818 | private: | 1208 | { |
819 | SocRef m_ref; | 1209 | int idx = m_fields_tab->currentIndex(); |
820 | }; | 1210 | RegFieldEditPanel *p = dynamic_cast< RegFieldEditPanel * >(m_fields_tab->widget(idx)); |
1211 | m_fields_tab->setTabText(idx, QString::fromStdString(p->GetField().get()->name)); | ||
1212 | DoModify(); | ||
1213 | } | ||
821 | 1214 | ||
822 | /** | 1215 | void RegEditPanel::DoModify() |
823 | * DevTreeItem | 1216 | { |
824 | */ | 1217 | m_value_model->UpdateRegister(*m_ref.get()); |
1218 | UpdateWidthRestrictions(); | ||
1219 | OnModified(); | ||
1220 | } | ||
825 | 1221 | ||
826 | class DevTreeItem : public QTreeWidgetItem | 1222 | void RegEditPanel::OnRegFieldDelete() |
827 | { | 1223 | { |
828 | public: | 1224 | QModelIndex current = m_sexy_display2->currentIndex(); |
829 | DevTreeItem(const QString& string, const SocDevRef& ref) | 1225 | if(!current.isValid()) |
830 | :QTreeWidgetItem(QStringList(string), SocTreeDevType), m_ref(ref) {} | 1226 | return; |
1227 | QMessageBox msgbox(QMessageBox::Question, "Delete field ?", | ||
1228 | "Are you sure you want to delete this field ?", | ||
1229 | QMessageBox::Yes | QMessageBox::No, this); | ||
1230 | msgbox.setDefaultButton(QMessageBox::No); | ||
1231 | int ret = msgbox.exec(); | ||
1232 | if(ret != QMessageBox::Yes) | ||
1233 | return; | ||
1234 | m_fields_tab->removeTab(IndexById(m_ref.get()->field[current.row()].id)); | ||
1235 | my_remove_at(m_ref.get()->field, current.row()); | ||
1236 | DoModify(); | ||
1237 | OnRegFieldActivated(QModelIndex()); | ||
1238 | } | ||
831 | 1239 | ||
832 | const SocDevRef& GetRef() { return m_ref; } | 1240 | void RegEditPanel::OnFieldRemove(int index) |
833 | private: | 1241 | { |
834 | SocDevRef m_ref; | 1242 | Q_UNUSED(index); |
835 | }; | 1243 | } |
836 | 1244 | ||
837 | /** | 1245 | int RegEditPanel::FindFreeBit(int preferred) |
838 | * NewRegTreeItem | 1246 | { |
839 | */ | 1247 | int nr_bits = m_ref.get()->width; |
1248 | soc_word_t free_mask = (nr_bits == 32) ? 0xffffffff : (1 << nr_bits) - 1; | ||
1249 | soc_desc::register_t& reg = *m_ref.get(); | ||
1250 | for(size_t i = 0; i < reg.field.size(); i++) | ||
1251 | free_mask &= ~reg.field[i].bitmask(); | ||
1252 | /* any space ? */ | ||
1253 | if(free_mask == 0) | ||
1254 | return -1; | ||
1255 | int closest_bit = -1; | ||
1256 | int closest_dist = nr_bits; | ||
1257 | for(int bit = 0; bit < nr_bits; bit++) | ||
1258 | { | ||
1259 | if(!(free_mask & (1 << bit))) | ||
1260 | continue; | ||
1261 | if(abs(bit - preferred) < closest_dist) | ||
1262 | { | ||
1263 | closest_bit = bit; | ||
1264 | closest_dist = abs(bit - preferred); | ||
1265 | } | ||
1266 | } | ||
1267 | return closest_bit; | ||
1268 | } | ||
840 | 1269 | ||
841 | class NewRegTreeItem : public QTreeWidgetItem | 1270 | void RegEditPanel::OnRegFieldNew() |
842 | { | 1271 | { |
843 | public: | 1272 | int bit_col = m_sexy_display2->bitColumnAt(m_menu_point); |
844 | NewRegTreeItem(const QString& string, const SocDevRef& ref) | 1273 | /* we need to make sure the created field does not overlap something */ |
845 | :QTreeWidgetItem(QStringList(string), SocTreeNewRegType), m_ref(ref) {} | 1274 | bit_col = FindFreeBit(bit_col); |
1275 | if(bit_col == -1) | ||
1276 | return; /* impossible to find a free position */ | ||
1277 | soc_desc::field_ref_t ref = m_ref.create_field(); | ||
1278 | soc_desc::field_t& field = *ref.get(); | ||
1279 | field.pos = bit_col; | ||
1280 | field.width = 1; | ||
1281 | field.name = "UNNAMED"; | ||
846 | 1282 | ||
847 | const SocDevRef& GetRef() { return m_ref; } | 1283 | RegFieldEditPanel *p = new RegFieldEditPanel(ref, this); |
848 | private: | 1284 | connect(p, SIGNAL(OnModified()), this, SLOT(OnFieldModified())); |
849 | SocDevRef m_ref; | 1285 | m_fields_tab->addTab(p, QString::fromStdString(field.name)); |
850 | }; | ||
851 | 1286 | ||
852 | /** | 1287 | DoModify(); |
853 | * RegTreeItem | 1288 | } |
854 | */ | ||
855 | 1289 | ||
856 | class RegTreeItem : public QTreeWidgetItem | 1290 | void RegEditPanel::OnFieldCreate() |
857 | { | 1291 | { |
858 | public: | 1292 | OnRegFieldNew(); |
859 | RegTreeItem(const QString& string, const SocRegRef& ref) | 1293 | } |
860 | :QTreeWidgetItem(QStringList(string), SocTreeRegType), m_ref(ref) {} | ||
861 | |||
862 | const SocRegRef& GetRef() { return m_ref; } | ||
863 | private: | ||
864 | SocRegRef m_ref; | ||
865 | }; | ||
866 | 1294 | ||
867 | /** | 1295 | void RegEditPanel::OnRegDisplayContextMenu(QPoint point) |
868 | * NewFieldTreeItem | 1296 | { |
869 | */ | 1297 | m_menu_point = point; |
1298 | QMenu *menu = new QMenu(this); | ||
1299 | QModelIndex item = m_sexy_display2->indexAt(point); | ||
1300 | menu->addAction(m_new_action); | ||
1301 | if(item.isValid()) | ||
1302 | menu->addAction(m_delete_action); | ||
1303 | menu->popup(m_sexy_display2->viewport()->mapToGlobal(point)); | ||
1304 | } | ||
870 | 1305 | ||
871 | class NewFieldTreeItem : public QTreeWidgetItem | 1306 | namespace |
872 | { | 1307 | { |
873 | public: | ||
874 | NewFieldTreeItem(const QString& string, const SocRegRef& ref) | ||
875 | :QTreeWidgetItem(QStringList(string), SocTreeNewFieldType), m_ref(ref) {} | ||
876 | 1308 | ||
877 | const SocRegRef& GetRef() { return m_ref; } | 1309 | enum |
878 | private: | 1310 | { |
879 | SocRegRef m_ref; | 1311 | SocTreeSocType = QTreeWidgetItem::UserType, // SocRefRole -> node_ref_t to root |
1312 | SocTreeNodeType, // SocRefRole -> node_ref_t | ||
1313 | SocTreeRegType, // SocRefRole -> register_ref_t | ||
880 | }; | 1314 | }; |
881 | 1315 | ||
882 | /** | 1316 | enum |
883 | * FieldTreeItem | 1317 | { |
884 | */ | 1318 | SocRefRole = Qt::UserRole, |
1319 | }; | ||
885 | 1320 | ||
886 | class FieldTreeItem : public QTreeWidgetItem | 1321 | template<typename T> |
1322 | T SocTreeItemVal(QTreeWidgetItem *item) | ||
887 | { | 1323 | { |
888 | public: | 1324 | return item->data(0, SocRefRole).value<T>(); |
889 | FieldTreeItem(const QString& string, const SocFieldRef& ref) | 1325 | } |
890 | :QTreeWidgetItem(QStringList(string), SocTreeFieldType), m_ref(ref) {} | ||
891 | 1326 | ||
892 | const SocFieldRef& GetRef() { return m_ref; } | 1327 | template<typename T> |
893 | private: | 1328 | QTreeWidgetItem *MakeSocTreeItem(int type, const T& val) |
894 | SocFieldRef m_ref; | 1329 | { |
895 | }; | 1330 | QTreeWidgetItem *item = new QTreeWidgetItem(type); |
1331 | item->setData(0, SocRefRole, QVariant::fromValue(val)); | ||
1332 | return item; | ||
1333 | } | ||
896 | 1334 | ||
897 | } | 1335 | } |
898 | 1336 | ||
@@ -903,8 +1341,7 @@ RegEdit::RegEdit(Backend *backend, QWidget *parent) | |||
903 | :QWidget(parent), m_backend(backend) | 1341 | :QWidget(parent), m_backend(backend) |
904 | { | 1342 | { |
905 | QVBoxLayout *m_vert_layout = new QVBoxLayout(); | 1343 | QVBoxLayout *m_vert_layout = new QVBoxLayout(); |
906 | m_file_group = new QGroupBox("File selection", this); | 1344 | QLabel *file_static = new QLabel("File:"); |
907 | QHBoxLayout *m_file_group_layout = new QHBoxLayout(); | ||
908 | m_file_edit = new QLineEdit(this); | 1345 | m_file_edit = new QLineEdit(this); |
909 | m_file_edit->setReadOnly(true); | 1346 | m_file_edit->setReadOnly(true); |
910 | m_file_open = new QToolButton(this); | 1347 | m_file_open = new QToolButton(this); |
@@ -913,33 +1350,53 @@ RegEdit::RegEdit(Backend *backend, QWidget *parent) | |||
913 | m_file_open->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); | 1350 | m_file_open->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); |
914 | QMenu *file_open_menu = new QMenu(this); | 1351 | QMenu *file_open_menu = new QMenu(this); |
915 | QAction *new_act = file_open_menu->addAction(QIcon::fromTheme("document-new"), "New..."); | 1352 | QAction *new_act = file_open_menu->addAction(QIcon::fromTheme("document-new"), "New..."); |
1353 | m_file_open->setPopupMode(QToolButton::MenuButtonPopup); | ||
916 | m_file_open->setMenu(file_open_menu); | 1354 | m_file_open->setMenu(file_open_menu); |
917 | 1355 | ||
918 | m_file_save = new QToolButton(this); | 1356 | m_file_save = new QToolButton(this); |
919 | m_file_save->setText("Save"); | 1357 | m_file_save->setText("Save"); |
920 | m_file_save->setIcon(QIcon::fromTheme("document-save")); | 1358 | m_file_save->setIcon(QIcon::fromTheme("document-save")); |
921 | m_file_save->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); | 1359 | m_file_save->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); |
1360 | m_file_save->setPopupMode(QToolButton::MenuButtonPopup); | ||
922 | QMenu *file_save_menu = new QMenu(this); | 1361 | QMenu *file_save_menu = new QMenu(this); |
923 | QAction *saveas_act = file_save_menu->addAction(QIcon::fromTheme("document-save-as"), "Save as..."); | 1362 | QAction *saveas_act = file_save_menu->addAction(QIcon::fromTheme("document-save-as"), "Save as..."); |
924 | m_file_save->setMenu(file_save_menu); | 1363 | m_file_save->setMenu(file_save_menu); |
925 | m_file_group_layout->addWidget(m_file_open); | 1364 | |
926 | m_file_group_layout->addWidget(m_file_save); | 1365 | QHBoxLayout *file_group_layout = new QHBoxLayout(); |
927 | m_file_group_layout->addWidget(m_file_edit); | 1366 | file_group_layout->addWidget(m_file_open); |
1367 | file_group_layout->addWidget(m_file_save); | ||
1368 | file_group_layout->addWidget(file_static); | ||
1369 | file_group_layout->addWidget(m_file_edit); | ||
928 | 1370 | ||
929 | m_splitter = new QSplitter(this); | 1371 | m_splitter = new QSplitter(this); |
930 | m_soc_tree = new QTreeWidget(this); | 1372 | m_soc_tree = new QTreeWidget(this); |
931 | m_soc_tree->setColumnCount(1); | 1373 | m_soc_tree->setColumnCount(1); |
932 | m_soc_tree->setHeaderLabel(QString("Name")); | 1374 | m_soc_tree->setHeaderLabel(QString("Name")); |
933 | m_soc_tree->setContextMenuPolicy(Qt::ActionsContextMenu); | 1375 | m_soc_tree->setContextMenuPolicy(Qt::CustomContextMenu); |
934 | QAction *soc_tree_delete_action = new QAction("&Delete", this); | 1376 | |
935 | soc_tree_delete_action->setIcon(QIcon::fromTheme("list-remove")); | 1377 | m_delete_action = new QAction("&Delete", this); |
936 | connect(soc_tree_delete_action, SIGNAL(triggered()), this, SLOT(OnSocItemDelete())); | 1378 | m_delete_action->setIcon(QIcon::fromTheme("list-remove")); |
937 | m_soc_tree->addAction(soc_tree_delete_action); | 1379 | m_new_action = new QAction("&New", this); |
1380 | m_new_action->setIcon(QIcon::fromTheme("list-add")); | ||
1381 | m_create_action = new QAction("&Create register", this); | ||
1382 | m_create_action->setIcon(QIcon::fromTheme("folder-new")); | ||
1383 | |||
938 | m_splitter->addWidget(m_soc_tree); | 1384 | m_splitter->addWidget(m_soc_tree); |
939 | m_splitter->setStretchFactor(0, 0); | 1385 | m_splitter->setStretchFactor(0, 0); |
940 | 1386 | ||
941 | m_file_group->setLayout(m_file_group_layout); | 1387 | m_msg = new MessageWidget(this); |
942 | m_vert_layout->addWidget(m_file_group); | 1388 | QWidget *splitter_right = new QWidget(this); |
1389 | m_right_panel_layout = new QVBoxLayout; | ||
1390 | m_right_panel_layout->addWidget(m_msg, 0); | ||
1391 | splitter_right->setLayout(m_right_panel_layout); | ||
1392 | m_splitter->addWidget(splitter_right); | ||
1393 | m_splitter->setStretchFactor(1, 2); | ||
1394 | |||
1395 | m_msg_welcome_id = SetMessage(MessageWidget::Information, | ||
1396 | "Open a description file to edit, or create a new file from scratch."); | ||
1397 | m_msg_name_error_id = 0; | ||
1398 | |||
1399 | m_vert_layout->addLayout(file_group_layout); | ||
943 | m_vert_layout->addWidget(m_splitter, 1); | 1400 | m_vert_layout->addWidget(m_splitter, 1); |
944 | 1401 | ||
945 | setLayout(m_vert_layout); | 1402 | setLayout(m_vert_layout); |
@@ -949,14 +1406,17 @@ RegEdit::RegEdit(Backend *backend, QWidget *parent) | |||
949 | SetPanel(new EmptyEditPanel(this)); | 1406 | SetPanel(new EmptyEditPanel(this)); |
950 | UpdateTabName(); | 1407 | UpdateTabName(); |
951 | 1408 | ||
1409 | connect(m_soc_tree, SIGNAL(customContextMenuRequested(QPoint)), this, | ||
1410 | SLOT(OnSocTreeContextMenu(QPoint))); | ||
1411 | connect(m_delete_action, SIGNAL(triggered()), this, SLOT(OnSocItemDelete())); | ||
1412 | connect(m_new_action, SIGNAL(triggered()), this, SLOT(OnSocItemNew())); | ||
1413 | connect(m_create_action, SIGNAL(triggered()), this, SLOT(OnSocItemCreate())); | ||
952 | connect(m_file_open, SIGNAL(clicked()), this, SLOT(OnOpen())); | 1414 | connect(m_file_open, SIGNAL(clicked()), this, SLOT(OnOpen())); |
953 | connect(m_file_save, SIGNAL(clicked()), this, SLOT(OnSave())); | 1415 | connect(m_file_save, SIGNAL(clicked()), this, SLOT(OnSave())); |
954 | connect(new_act, SIGNAL(triggered()), this, SLOT(OnNew())); | 1416 | connect(new_act, SIGNAL(triggered()), this, SLOT(OnNew())); |
955 | connect(saveas_act, SIGNAL(triggered()), this, SLOT(OnSaveAs())); | 1417 | connect(saveas_act, SIGNAL(triggered()), this, SLOT(OnSaveAs())); |
956 | connect(m_soc_tree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), | 1418 | connect(m_soc_tree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), |
957 | this, SLOT(OnSocItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); | 1419 | this, SLOT(OnSocItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); |
958 | connect(m_soc_tree, SIGNAL(itemActivated(QTreeWidgetItem*, int)), | ||
959 | this, SLOT(OnSocItemActivated(QTreeWidgetItem*, int))); | ||
960 | } | 1420 | } |
961 | 1421 | ||
962 | QWidget *RegEdit::GetWidget() | 1422 | QWidget *RegEdit::GetWidget() |
@@ -968,6 +1428,16 @@ RegEdit::~RegEdit() | |||
968 | { | 1428 | { |
969 | } | 1429 | } |
970 | 1430 | ||
1431 | int RegEdit::SetMessage(MessageWidget::MessageType type, const QString& msg) | ||
1432 | { | ||
1433 | return m_msg->SetMessage(type, msg); | ||
1434 | } | ||
1435 | |||
1436 | void RegEdit::HideMessage(int id) | ||
1437 | { | ||
1438 | m_msg->HideMessage(id); | ||
1439 | } | ||
1440 | |||
971 | void RegEdit::OnSave() | 1441 | void RegEdit::OnSave() |
972 | { | 1442 | { |
973 | SaveSoc(); | 1443 | SaveSoc(); |
@@ -1007,7 +1477,10 @@ bool RegEdit::GetFilename(QString& filename, bool save) | |||
1007 | QFileDialog *fd = new QFileDialog(this); | 1477 | QFileDialog *fd = new QFileDialog(this); |
1008 | if(save) | 1478 | if(save) |
1009 | fd->setAcceptMode(QFileDialog::AcceptSave); | 1479 | fd->setAcceptMode(QFileDialog::AcceptSave); |
1010 | fd->setFilter("Description files (*.xml);;All files (*)"); | 1480 | QStringList filters; |
1481 | filters << "Description files (*.xml)"; | ||
1482 | filters << "All files (*)"; | ||
1483 | fd->setNameFilters(filters); | ||
1011 | fd->setDirectory(Settings::Get()->value("regedit/loaddescdir", QDir::currentPath()).toString()); | 1484 | fd->setDirectory(Settings::Get()->value("regedit/loaddescdir", QDir::currentPath()).toString()); |
1012 | if(fd->exec()) | 1485 | if(fd->exec()) |
1013 | { | 1486 | { |
@@ -1051,15 +1524,15 @@ void RegEdit::OnNew() | |||
1051 | 1524 | ||
1052 | bool RegEdit::SaveSocFile(const QString& filename) | 1525 | bool RegEdit::SaveSocFile(const QString& filename) |
1053 | { | 1526 | { |
1054 | normalize(m_cur_socfile.GetSoc()); | 1527 | soc_desc::error_context_t ctx; |
1055 | if(!produce_xml(filename.toStdString(), m_cur_socfile.GetSoc())) | 1528 | soc_desc::normalize(m_cur_socfile.GetSoc()); |
1529 | if(!soc_desc::produce_xml(filename.toStdString(), m_cur_socfile.GetSoc(), ctx)) | ||
1056 | { | 1530 | { |
1057 | QMessageBox::warning(this, "The description was not saved", | 1531 | QMessageBox::warning(this, "The description was not saved", |
1058 | "There was an error when saving the file"); | 1532 | "There was an error when saving the file"); |
1059 | return false; | 1533 | return false; |
1060 | } | 1534 | } |
1061 | m_soc_tree->clear(); | 1535 | UpdateSocFile(); |
1062 | FillSocTree(); | ||
1063 | SetModified(false, false); | 1536 | SetModified(false, false); |
1064 | return true; | 1537 | return true; |
1065 | } | 1538 | } |
@@ -1086,91 +1559,39 @@ void RegEdit::LoadSocFile(const QString& filename) | |||
1086 | SetModified(false, false); | 1559 | SetModified(false, false); |
1087 | UpdateSocFile(); | 1560 | UpdateSocFile(); |
1088 | UpdateTabName(); | 1561 | UpdateTabName(); |
1562 | m_msg_welcome_id = SetMessage(MessageWidget::Information, | ||
1563 | "Select items to edit in tree, or right-click on them to see available actions."); | ||
1089 | } | 1564 | } |
1090 | 1565 | ||
1091 | void RegEdit::CreateNewFieldItem(QTreeWidgetItem *_parent) | 1566 | void RegEdit::FillNodeTreeItem(QTreeWidgetItem *item) |
1092 | { | ||
1093 | RegTreeItem *parent = dynamic_cast< RegTreeItem* >(_parent); | ||
1094 | NewFieldTreeItem *newdev_item = new NewFieldTreeItem("New field...", parent->GetRef()); | ||
1095 | MakeItalic(newdev_item, true); | ||
1096 | newdev_item->setIcon(0, QIcon::fromTheme("list-add")); | ||
1097 | parent->addChild(newdev_item); | ||
1098 | } | ||
1099 | |||
1100 | void RegEdit::FillRegTreeItem(QTreeWidgetItem *_item) | ||
1101 | { | ||
1102 | RegTreeItem *item = dynamic_cast< RegTreeItem* >(_item); | ||
1103 | const soc_reg_t& reg = item->GetRef().GetReg(); | ||
1104 | for(size_t i = 0; i < reg.field.size(); i++) | ||
1105 | { | ||
1106 | const soc_reg_field_t& field = reg.field[i]; | ||
1107 | FieldTreeItem *field_item = new FieldTreeItem(QString::fromStdString(field.name), | ||
1108 | SocFieldRef(item->GetRef(), i)); | ||
1109 | FixupEmptyItem(field_item); | ||
1110 | item->addChild(field_item); | ||
1111 | } | ||
1112 | CreateNewFieldItem(item); | ||
1113 | } | ||
1114 | |||
1115 | void RegEdit::CreateNewRegisterItem(QTreeWidgetItem *_parent) | ||
1116 | { | ||
1117 | DevTreeItem *parent = dynamic_cast< DevTreeItem* >(_parent); | ||
1118 | NewRegTreeItem *newdev_item = new NewRegTreeItem("New register...", parent->GetRef()); | ||
1119 | MakeItalic(newdev_item, true); | ||
1120 | newdev_item->setIcon(0, QIcon::fromTheme("list-add")); | ||
1121 | parent->addChild(newdev_item); | ||
1122 | } | ||
1123 | |||
1124 | void RegEdit::FillDevTreeItem(QTreeWidgetItem *_item) | ||
1125 | { | 1567 | { |
1126 | DevTreeItem *item = dynamic_cast< DevTreeItem* >(_item); | 1568 | soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(item); |
1127 | const soc_dev_t& dev = item->GetRef().GetDev(); | 1569 | soc_desc::register_ref_t reg = node.reg(); |
1128 | for(size_t i = 0; i < dev.reg.size(); i++) | 1570 | /* put register if there, otherwise offer to create one */ |
1571 | if(reg.valid() && reg.node() == node) | ||
1129 | { | 1572 | { |
1130 | const soc_reg_t& reg = dev.reg[i]; | 1573 | QTreeWidgetItem *reg_item = MakeSocTreeItem(SocTreeRegType, reg); |
1131 | RegTreeItem *reg_item = new RegTreeItem(QString::fromStdString(reg.name), | 1574 | FixupItem(reg_item); |
1132 | SocRegRef(item->GetRef(), i, -1)); | ||
1133 | FixupEmptyItem(reg_item); | ||
1134 | FillRegTreeItem(reg_item); | ||
1135 | item->addChild(reg_item); | 1575 | item->addChild(reg_item); |
1136 | } | 1576 | } |
1137 | CreateNewRegisterItem(item); | 1577 | std::vector< soc_desc::node_ref_t > list = node.children(); |
1138 | } | 1578 | for(size_t i = 0; i < list.size(); i++) |
1139 | |||
1140 | void RegEdit::CreateNewDeviceItem(QTreeWidgetItem *_parent) | ||
1141 | { | ||
1142 | SocTreeItem *parent = dynamic_cast< SocTreeItem* >(_parent); | ||
1143 | NewDevTreeItem *newdev_item = new NewDevTreeItem("New device...", parent->GetRef()); | ||
1144 | MakeItalic(newdev_item, true); | ||
1145 | newdev_item->setIcon(0, QIcon::fromTheme("list-add")); | ||
1146 | parent->addChild(newdev_item); | ||
1147 | } | ||
1148 | |||
1149 | void RegEdit::FillSocTreeItem(QTreeWidgetItem *_item) | ||
1150 | { | ||
1151 | SocTreeItem *item = dynamic_cast< SocTreeItem* >(_item); | ||
1152 | const soc_t& soc = item->GetRef().GetSoc(); | ||
1153 | for(size_t i = 0; i < soc.dev.size(); i++) | ||
1154 | { | 1579 | { |
1155 | const soc_dev_t& reg = soc.dev[i]; | 1580 | QTreeWidgetItem *node_item = MakeSocTreeItem(SocTreeNodeType, list[i]); |
1156 | DevTreeItem *dev_item = new DevTreeItem(QString::fromStdString(reg.name), | 1581 | FixupItem(node_item); |
1157 | SocDevRef(item->GetRef(), i, -1)); | 1582 | FillNodeTreeItem(node_item); |
1158 | FixupEmptyItem(dev_item); | 1583 | item->addChild(node_item); |
1159 | FillDevTreeItem(dev_item); | ||
1160 | item->addChild(dev_item); | ||
1161 | } | 1584 | } |
1162 | CreateNewDeviceItem(item); | ||
1163 | } | 1585 | } |
1164 | 1586 | ||
1165 | void RegEdit::FillSocTree() | 1587 | void RegEdit::FillSocTree() |
1166 | { | 1588 | { |
1167 | SocRef ref = m_cur_socfile.GetSocRef(); | 1589 | soc_desc::soc_ref_t ref = m_cur_socfile.GetSocRef(); |
1168 | SocTreeItem *soc_item = new SocTreeItem( | 1590 | QTreeWidgetItem *root_item = MakeSocTreeItem(SocTreeSocType, ref.root()); |
1169 | QString::fromStdString(ref.GetSoc().name), ref); | 1591 | FixupItem(root_item); |
1170 | FixupEmptyItem(soc_item); | 1592 | FillNodeTreeItem(root_item); |
1171 | FillSocTreeItem(soc_item); | 1593 | m_soc_tree->addTopLevelItem(root_item); |
1172 | m_soc_tree->addTopLevelItem(soc_item); | 1594 | root_item->setExpanded(true); |
1173 | soc_item->setExpanded(true); | ||
1174 | } | 1595 | } |
1175 | 1596 | ||
1176 | void RegEdit::MakeItalic(QTreeWidgetItem *item, bool it) | 1597 | void RegEdit::MakeItalic(QTreeWidgetItem *item, bool it) |
@@ -1180,17 +1601,46 @@ void RegEdit::MakeItalic(QTreeWidgetItem *item, bool it) | |||
1180 | item->setFont(0, font); | 1601 | item->setFont(0, font); |
1181 | } | 1602 | } |
1182 | 1603 | ||
1183 | void RegEdit::FixupEmptyItem(QTreeWidgetItem *item) | 1604 | QIcon RegEdit::GetIconFromType(int type) |
1605 | { | ||
1606 | switch(type) | ||
1607 | { | ||
1608 | case SocTreeSocType: return QIcon::fromTheme("computer"); | ||
1609 | case SocTreeNodeType: return QIcon::fromTheme("cpu"); | ||
1610 | case SocTreeRegType: return style()->standardIcon(QStyle::SP_ArrowRight); | ||
1611 | default: return QIcon(); | ||
1612 | } | ||
1613 | } | ||
1614 | |||
1615 | bool RegEdit::ValidateName(const QString& name) | ||
1184 | { | 1616 | { |
1185 | if(item->text(0).size() == 0) | 1617 | if(name.size() == 0) |
1618 | return false; | ||
1619 | for(int i = 0; i < name.size(); i++) | ||
1620 | if(!name[i].isLetterOrNumber() && name[i] != QChar('_')) | ||
1621 | return false; | ||
1622 | return true; | ||
1623 | } | ||
1624 | |||
1625 | void RegEdit::FixupItem(QTreeWidgetItem *item) | ||
1626 | { | ||
1627 | UpdateName(item); | ||
1628 | if(!ValidateName(item->text(0))) | ||
1186 | { | 1629 | { |
1187 | item->setIcon(0, QIcon::fromTheme("dialog-error")); | 1630 | item->setIcon(0, QIcon::fromTheme("dialog-error")); |
1188 | MakeItalic(item, true); | 1631 | if(item->text(0).size() == 0) |
1189 | item->setText(0, "Unnamed"); | 1632 | { |
1633 | MakeItalic(item, true); | ||
1634 | item->setText(0, "Unnamed"); | ||
1635 | } | ||
1636 | m_msg_name_error_id = SetMessage(MessageWidget::Error, | ||
1637 | "The item name is invalid. It must be non-empty and consists only " | ||
1638 | "of alphanumerical or underscore characters"); | ||
1190 | } | 1639 | } |
1191 | else | 1640 | else |
1192 | { | 1641 | { |
1193 | item->setIcon(0, QIcon::fromTheme("cpu")); | 1642 | HideMessage(m_msg_name_error_id); |
1643 | item->setIcon(0, GetIconFromType(item->type())); | ||
1194 | MakeItalic(item, false); | 1644 | MakeItalic(item, false); |
1195 | } | 1645 | } |
1196 | } | 1646 | } |
@@ -1206,9 +1656,9 @@ void RegEdit::SetPanel(QWidget *panel) | |||
1206 | { | 1656 | { |
1207 | delete m_right_panel; | 1657 | delete m_right_panel; |
1208 | m_right_panel = panel; | 1658 | m_right_panel = panel; |
1209 | connect(m_right_panel, SIGNAL(OnModified(bool)), this, SLOT(OnSocModified(bool))); | 1659 | connect(m_right_panel, SIGNAL(OnModified()), this, |
1210 | m_splitter->addWidget(m_right_panel); | 1660 | SLOT(OnSocModified())); |
1211 | m_splitter->setStretchFactor(1, 2); | 1661 | m_right_panel_layout->addWidget(m_right_panel, 1); |
1212 | } | 1662 | } |
1213 | 1663 | ||
1214 | void RegEdit::SetModified(bool add, bool mod) | 1664 | void RegEdit::SetModified(bool add, bool mod) |
@@ -1217,15 +1667,33 @@ void RegEdit::SetModified(bool add, bool mod) | |||
1217 | OnModified(mod); | 1667 | OnModified(mod); |
1218 | } | 1668 | } |
1219 | 1669 | ||
1220 | namespace | 1670 | void RegEdit::OnSocItemNew() |
1221 | { | ||
1222 | |||
1223 | template< typename T > | ||
1224 | void my_remove_at(std::vector< T >& v, size_t at) | ||
1225 | { | 1671 | { |
1226 | v.erase(v.begin() + at); | 1672 | QTreeWidgetItem *current = m_soc_tree->currentItem(); |
1673 | if(current == 0) | ||
1674 | return; | ||
1675 | soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(current); | ||
1676 | node = node.create(); | ||
1677 | node.get()->name = "unnamed"; | ||
1678 | QTreeWidgetItem *node_item = MakeSocTreeItem(SocTreeNodeType, node); | ||
1679 | FixupItem(node_item); | ||
1680 | current->addChild(node_item); | ||
1681 | m_soc_tree->setCurrentItem(node_item); | ||
1227 | } | 1682 | } |
1228 | 1683 | ||
1684 | void RegEdit::OnSocItemCreate() | ||
1685 | { | ||
1686 | QTreeWidgetItem *current = m_soc_tree->currentItem(); | ||
1687 | if(current == 0) | ||
1688 | return; | ||
1689 | soc_desc::register_t reg; | ||
1690 | reg.width = 32; | ||
1691 | soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(current); | ||
1692 | node.get()->register_.push_back(reg); | ||
1693 | QTreeWidgetItem *reg_item = MakeSocTreeItem(SocTreeRegType, node.reg()); | ||
1694 | FixupItem(reg_item); | ||
1695 | current->insertChild(0, reg_item); | ||
1696 | m_soc_tree->setCurrentItem(reg_item); | ||
1229 | } | 1697 | } |
1230 | 1698 | ||
1231 | void RegEdit::OnSocItemDelete() | 1699 | void RegEdit::OnSocItemDelete() |
@@ -1242,172 +1710,116 @@ void RegEdit::OnSocItemDelete() | |||
1242 | return; | 1710 | return; |
1243 | if(current->type() == SocTreeSocType) | 1711 | if(current->type() == SocTreeSocType) |
1244 | { | 1712 | { |
1245 | SocTreeItem *item = dynamic_cast< SocTreeItem * >(current); | 1713 | SocTreeItemVal< soc_desc::node_ref_t >(current).remove(); |
1246 | item->GetRef().GetSoc().dev.clear(); | 1714 | current->takeChildren(); |
1247 | item->takeChildren(); | 1715 | OnSocModified(); |
1248 | FillSocTreeItem(item); | ||
1249 | m_soc_tree->expandItem(item); | ||
1250 | } | 1716 | } |
1251 | else if(current->type() == SocTreeDevType) | 1717 | else if(current->type() == SocTreeNodeType) |
1252 | { | 1718 | { |
1253 | DevTreeItem *item = dynamic_cast< DevTreeItem * >(current); | 1719 | SocTreeItemVal< soc_desc::node_ref_t >(current).remove(); |
1254 | my_remove_at(item->GetRef().GetSoc().dev, item->GetRef().GetDevIndex()); | 1720 | current->parent()->removeChild(current); |
1255 | QTreeWidgetItem *parent = item->parent(); | 1721 | OnSocModified(); |
1256 | parent->takeChildren(); | ||
1257 | FillSocTreeItem(parent); | ||
1258 | m_soc_tree->expandItem(parent); | ||
1259 | } | 1722 | } |
1260 | else if(current->type() == SocTreeRegType) | 1723 | else if(current->type() == SocTreeRegType) |
1261 | { | 1724 | { |
1262 | RegTreeItem *item = dynamic_cast< RegTreeItem * >(current); | 1725 | SocTreeItemVal< soc_desc::register_ref_t >(current).remove(); |
1263 | my_remove_at(item->GetRef().GetDev().reg, item->GetRef().GetRegIndex()); | 1726 | current->parent()->removeChild(current); |
1264 | QTreeWidgetItem *parent = item->parent(); | 1727 | OnSocModified(); |
1265 | parent->takeChildren(); | ||
1266 | FillDevTreeItem(parent); | ||
1267 | m_soc_tree->expandItem(parent); | ||
1268 | } | ||
1269 | else if(current->type() == SocTreeFieldType) | ||
1270 | { | ||
1271 | FieldTreeItem *item = dynamic_cast< FieldTreeItem * >(current); | ||
1272 | my_remove_at(item->GetRef().GetReg().field, item->GetRef().GetFieldIndex()); | ||
1273 | QTreeWidgetItem *parent = item->parent(); | ||
1274 | parent->takeChildren(); | ||
1275 | FillRegTreeItem(parent); | ||
1276 | m_soc_tree->expandItem(parent); | ||
1277 | } | 1728 | } |
1278 | } | 1729 | } |
1279 | 1730 | ||
1280 | void RegEdit::OnSocModified(bool modified) | 1731 | void RegEdit::OnSocModified() |
1281 | { | 1732 | { |
1282 | // we might need to update the name in the tree | 1733 | // we might need to update the name in the tree |
1283 | UpdateName(m_soc_tree->currentItem()); | 1734 | FixupItem(m_soc_tree->currentItem()); |
1284 | if(modified) | 1735 | SetModified(true, true); |
1285 | SetModified(true, true); | ||
1286 | } | 1736 | } |
1287 | 1737 | ||
1288 | void RegEdit::DisplaySoc(SocRef ref) | 1738 | void RegEdit::DisplaySoc(const soc_desc::soc_ref_t& ref) |
1289 | { | 1739 | { |
1290 | SetPanel(new SocEditPanel(ref, this)); | 1740 | SetPanel(new SocEditPanel(ref, this)); |
1291 | } | 1741 | } |
1292 | 1742 | ||
1293 | void RegEdit::DisplayDev(SocDevRef ref) | 1743 | void RegEdit::DisplayNode(const soc_desc::node_ref_t& ref) |
1294 | { | 1744 | { |
1295 | SetPanel(new DevEditPanel(ref, this)); | 1745 | SetPanel(new NodeEditPanel(ref, this)); |
1296 | } | 1746 | } |
1297 | 1747 | ||
1298 | void RegEdit::DisplayReg(SocRegRef ref) | 1748 | void RegEdit::DisplayReg(const soc_desc::register_ref_t& ref) |
1299 | { | 1749 | { |
1300 | SetPanel(new RegEditPanel(ref, this)); | 1750 | SetPanel(new RegEditPanel(ref, this)); |
1301 | } | 1751 | } |
1302 | 1752 | ||
1303 | void RegEdit::DisplayField(SocFieldRef ref) | ||
1304 | { | ||
1305 | SetPanel(new FieldEditPanel(ref, this)); | ||
1306 | } | ||
1307 | |||
1308 | void RegEdit::UpdateName(QTreeWidgetItem *current) | 1753 | void RegEdit::UpdateName(QTreeWidgetItem *current) |
1309 | { | 1754 | { |
1310 | if(current == 0) | 1755 | if(current == 0) |
1311 | return; | 1756 | return; |
1757 | |||
1312 | if(current->type() == SocTreeSocType) | 1758 | if(current->type() == SocTreeSocType) |
1313 | { | 1759 | { |
1314 | SocTreeItem *item = dynamic_cast< SocTreeItem * >(current); | 1760 | current->setText(0, QString::fromStdString( |
1315 | item->setText(0, QString::fromStdString(item->GetRef().GetSoc().name)); | 1761 | SocTreeItemVal< soc_desc::node_ref_t >(current).soc().get()->name)); |
1316 | } | 1762 | } |
1317 | else if(current->type() == SocTreeDevType) | 1763 | else if(current->type() == SocTreeNodeType) |
1318 | { | 1764 | { |
1319 | DevTreeItem *item = dynamic_cast< DevTreeItem * >(current); | 1765 | current->setText(0, QString::fromStdString( |
1320 | item->setText(0, QString::fromStdString(item->GetRef().GetDev().name)); | 1766 | SocTreeItemVal< soc_desc::node_ref_t >(current).get()->name)); |
1321 | } | 1767 | } |
1322 | else if(current->type() == SocTreeRegType) | 1768 | else if(current->type() == SocTreeRegType) |
1323 | { | 1769 | { |
1324 | RegTreeItem *item = dynamic_cast< RegTreeItem * >(current); | 1770 | current->setText(0, "register"); |
1325 | item->setText(0, QString::fromStdString(item->GetRef().GetReg().name)); | ||
1326 | } | ||
1327 | else if(current->type() == SocTreeFieldType) | ||
1328 | { | ||
1329 | FieldTreeItem *item = dynamic_cast< FieldTreeItem * >(current); | ||
1330 | item->setText(0, QString::fromStdString(item->GetRef().GetField().name)); | ||
1331 | } | 1771 | } |
1332 | FixupEmptyItem(current); | ||
1333 | } | 1772 | } |
1334 | 1773 | ||
1335 | void RegEdit::OnSocItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) | 1774 | void RegEdit::OnSocTreeContextMenu(QPoint point) |
1336 | { | 1775 | { |
1337 | Q_UNUSED(previous); | 1776 | HideMessage(m_msg_welcome_id); |
1338 | if(current == 0) | 1777 | QTreeWidgetItem *item = m_soc_tree->itemAt(point); |
1778 | if(item == 0) | ||
1339 | return; | 1779 | return; |
1340 | if(current->type() == SocTreeSocType) | 1780 | /* customise messages with item */ |
1341 | { | 1781 | m_action_item = item; |
1342 | SocTreeItem *item = dynamic_cast< SocTreeItem * >(current); | 1782 | QMenu *menu = new QMenu(this); |
1343 | DisplaySoc(item->GetRef()); | 1783 | switch(item->type()) |
1344 | } | ||
1345 | else if(current->type() == SocTreeDevType) | ||
1346 | { | 1784 | { |
1347 | DevTreeItem *item = dynamic_cast< DevTreeItem * >(current); | 1785 | case SocTreeSocType: |
1348 | DisplayDev(item->GetRef()); | 1786 | m_new_action->setText("New node..."); |
1349 | } | 1787 | m_delete_action->setText("Delete all nodes..."); |
1350 | else if(current->type() == SocTreeRegType) | 1788 | menu->addAction(m_new_action); |
1351 | { | 1789 | menu->addAction(m_delete_action); |
1352 | RegTreeItem *item = dynamic_cast< RegTreeItem * >(current); | 1790 | break; |
1353 | DisplayReg(item->GetRef()); | 1791 | case SocTreeNodeType: |
1354 | } | 1792 | { |
1355 | else if(current->type() == SocTreeFieldType) | 1793 | m_new_action->setText("New node..."); |
1356 | { | 1794 | m_delete_action->setText("Delete node..."); |
1357 | FieldTreeItem *item = dynamic_cast< FieldTreeItem * >(current); | 1795 | soc_desc::node_ref_t node = SocTreeItemVal< soc_desc::node_ref_t >(item); |
1358 | DisplayField(item->GetRef()); | 1796 | if(node.reg().node() != node) |
1797 | menu->addAction(m_create_action); | ||
1798 | menu->addAction(m_new_action); | ||
1799 | menu->addAction(m_delete_action); | ||
1800 | break; | ||
1801 | } | ||
1802 | case SocTreeRegType: | ||
1803 | m_delete_action->setText("Delete register..."); | ||
1804 | menu->addAction(m_new_action); | ||
1805 | menu->addAction(m_delete_action); | ||
1806 | break; | ||
1359 | } | 1807 | } |
1808 | menu->popup(m_soc_tree->viewport()->mapToGlobal(point)); | ||
1360 | } | 1809 | } |
1361 | 1810 | ||
1362 | void RegEdit::OnSocItemActivated(QTreeWidgetItem *current, int column) | 1811 | void RegEdit::OnSocItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) |
1363 | { | 1812 | { |
1364 | Q_UNUSED(column); | 1813 | Q_UNUSED(previous); |
1814 | HideMessage(m_msg_welcome_id); | ||
1365 | if(current == 0) | 1815 | if(current == 0) |
1366 | return; | 1816 | return; |
1367 | if(current->type() == SocTreeNewDevType) | 1817 | if(current->type() == SocTreeSocType) |
1368 | AddDevice(current); | 1818 | DisplaySoc(SocTreeItemVal< soc_desc::node_ref_t >(current).soc()); |
1369 | else if(current->type() == SocTreeNewRegType) | 1819 | else if(current->type() == SocTreeNodeType) |
1370 | AddRegister(current); | 1820 | DisplayNode(SocTreeItemVal< soc_desc::node_ref_t >(current)); |
1371 | else if(current->type() == SocTreeNewFieldType) | 1821 | else if(current->type() == SocTreeRegType) |
1372 | AddField(current); | 1822 | DisplayReg(SocTreeItemVal< soc_desc::register_ref_t >(current)); |
1373 | } | ||
1374 | |||
1375 | void RegEdit::AddDevice(QTreeWidgetItem *_item) | ||
1376 | { | ||
1377 | NewDevTreeItem *item = dynamic_cast< NewDevTreeItem * >(_item); | ||
1378 | item->GetRef().GetSoc().dev.push_back(soc_dev_t()); | ||
1379 | DevTreeItem *dev_item = new DevTreeItem("", | ||
1380 | SocDevRef(item->GetRef(), item->GetRef().GetSoc().dev.size() - 1, -1)); | ||
1381 | FixupEmptyItem(dev_item); | ||
1382 | item->parent()->insertChild(item->parent()->indexOfChild(item), dev_item); | ||
1383 | CreateNewRegisterItem(dev_item); | ||
1384 | m_soc_tree->setCurrentItem(dev_item); | ||
1385 | OnModified(true); | ||
1386 | } | ||
1387 | |||
1388 | void RegEdit::AddRegister(QTreeWidgetItem *_item) | ||
1389 | { | ||
1390 | NewRegTreeItem *item = dynamic_cast< NewRegTreeItem * >(_item); | ||
1391 | item->GetRef().GetDev().reg.push_back(soc_reg_t()); | ||
1392 | RegTreeItem *reg_item = new RegTreeItem("", | ||
1393 | SocRegRef(item->GetRef(), item->GetRef().GetDev().reg.size() - 1, -1)); | ||
1394 | FixupEmptyItem(reg_item); | ||
1395 | item->parent()->insertChild(item->parent()->indexOfChild(item), reg_item); | ||
1396 | CreateNewFieldItem(reg_item); | ||
1397 | m_soc_tree->setCurrentItem(reg_item); | ||
1398 | OnModified(true); | ||
1399 | } | ||
1400 | |||
1401 | void RegEdit::AddField(QTreeWidgetItem *_item) | ||
1402 | { | ||
1403 | NewFieldTreeItem *item = dynamic_cast< NewFieldTreeItem * >(_item); | ||
1404 | item->GetRef().GetReg().field.push_back(soc_reg_field_t()); | ||
1405 | FieldTreeItem *field_item = new FieldTreeItem("", | ||
1406 | SocFieldRef(item->GetRef(), item->GetRef().GetReg().field.size() - 1)); | ||
1407 | FixupEmptyItem(field_item); | ||
1408 | item->parent()->insertChild(item->parent()->indexOfChild(item), field_item); | ||
1409 | m_soc_tree->setCurrentItem(field_item); | ||
1410 | OnModified(true); | ||
1411 | } | 1823 | } |
1412 | 1824 | ||
1413 | bool RegEdit::Quit() | 1825 | bool RegEdit::Quit() |