summaryrefslogtreecommitdiff
path: root/utils/regtools/qeditor/regedit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/regtools/qeditor/regedit.cpp')
-rw-r--r--utils/regtools/qeditor/regedit.cpp2222
1 files changed, 1317 insertions, 905 deletions
diff --git a/utils/regtools/qeditor/regedit.cpp b/utils/regtools/qeditor/regedit.cpp
index 8b4bfb7c49..826452fdbd 100644
--- a/utils/regtools/qeditor/regedit.cpp
+++ b/utils/regtools/qeditor/regedit.cpp
@@ -24,6 +24,7 @@
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 */
39SocEditPanel::SocEditPanel(SocRef ref, QWidget *parent) 40
41namespace
42{
43
44template< typename T >
45void my_remove_at(std::vector< T >& v, size_t at)
46{
47 v.erase(v.begin() + at);
48}
49
50enum
51{
52 SocEditPanelDelType = QTableWidgetItem::UserType,
53 SocEditPanelAddType,
54};
55
56}
57
58SocEditPanel::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
67void SocEditPanel::OnNameEdited(const QString& text) 146void 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
73void SocEditPanel::OnTextEdited() 152void 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/** 158void SocEditPanel::OnVersionEdited(const QString& text)
80 * DevEditPanel
81 */
82DevEditPanel::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); 164void 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
163void DevEditPanel::OnNameEdited(const QString& text) 170void 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
169void DevEditPanel::OnLongNameEdited(const QString& text) 176void 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
175void DevEditPanel::OnVersionEdited(const QString& text) 200void 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
181void DevEditPanel::OnDescEdited() 209/**
210 * NodeInstanceEditPanel
211 */
212
213namespace
182{ 214{
183 m_ref.GetDev().desc = m_desc_edit->GetTextHtml().toStdString(); 215
184 OnModified(m_desc_edit->IsModified()); 216template< typename T >
217soc_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
187void DevEditPanel::CreateNewRow(int row) 225template< typename T >
226int 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
204void DevEditPanel::FillRow(int row, const soc_dev_addr_t& addr) 234soc_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
220void DevEditPanel::OnInstActivated(int row, int column) 243bool 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
242void DevEditPanel::OnInstChanged(int row, int column) 255enum
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
263enum
264{
265 NodeInstEditPanelDelType = QTableWidgetItem::UserType,
266 NodeInstEditPanelAddType
267};
268
269}
270
271NodeInstanceEditPanel::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/** 455soc_desc::instance_t& NodeInstanceEditPanel::GetInstance()
261 * RegEditPanel 456{
262 */ 457 return *GetInstanceById(m_ref, m_id);
458}
263 459
264RegEditPanel::RegEditPanel(SocRegRef ref, QWidget *parent) 460void 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); 466void 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; 472void 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; 478void 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(); 484void NodeInstanceEditPanel::OnBaseChanged(uint base)
485{
486 GetInstance().range.base = base;
487 OnModified();
488}
369 489
370 setLayout(layout); 490void NodeInstanceEditPanel::OnStrideChanged(uint stride)
491{
492 GetInstance().range.stride = stride;
493 OnModified();
494}
371 495
372 SocFieldItemDelegate *m_table_delegate = new SocFieldItemDelegate(this); 496void 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))); 502void 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
390void RegEditPanel::UpdateWarning(int row) 508void NodeInstanceEditPanel::OnFormulaChanged(const QString& formula)
391{ 509{
392 Q_UNUSED(row); 510 GetInstance().range.formula = formula.toStdString();
511 OnModified();
393} 512}
394 513
395void RegEditPanel::OnFormulaStringChanged(const QString& text) 514void 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
401void RegEditPanel::OnFormulaGenerate(bool checked) 520void 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
448void RegEditPanel::OnFormulaChanged(int index) 548void 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
457void RegEditPanel::UpdateFormula() 559void 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
473void RegEditPanel::OnSctEdited(int state) 597void 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
482void 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
498void 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
515void RegEditPanel::OnNameEdited(const QString& text) 605soc_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
521void 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
527void RegEditPanel::OnInstActivated(int row, int column) 614NodeEditPanel::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
549void RegEditPanel::OnInstChanged(int row, int column) 670void 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) 676void 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
682void NodeEditPanel::OnDescEdited()
683{
684 m_ref.get()->desc = m_desc_edit->GetTextHtml().toStdString();
685 OnModified();
686}
687
688void 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
698void 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
707QString 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
746void 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 */
570FieldEditPanel::FieldEditPanel(SocFieldRef ref, QWidget *parent) 769
770namespace
771{
772
773enum
774{
775 RegFieldEditPanelDelType = QTableWidgetItem::UserType,
776 RegFieldEditPanelAddType,
777};
778
779}
780
781RegFieldEditPanel::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
639void FieldEditPanel::UpdateDelegates() 873void 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
650void FieldEditPanel::UpdateWarning(int row) 878void 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
667void FieldEditPanel::FillRow(int row, const soc_reg_field_value_t& val) 912void 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); 927void 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
687void 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
701void FieldEditPanel::OnBitRangeEdited(const QString& input) 933void 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
719void FieldEditPanel::OnNameEdited(const QString& text) 946void 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
725void FieldEditPanel::OnDescEdited() 952soc_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
731void FieldEditPanel::OnValueActivated(int row, int column) 957/**
958 * RegEditPanel
959 */
960
961namespace
732{ 962{
733 if(column != 0) 963
734 return; 964enum
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
972RegEditPanel::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
753void FieldEditPanel::OnValueChanged(int row, int column) 1115void 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
778namespace 1131int 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
781enum 1142void 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
796class SocTreeItem : public QTreeWidgetItem 1151void RegEditPanel::OnDescEdited()
797{ 1152{
798public: 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; } 1157void RegEditPanel::OnVariantActivated(QTableWidgetItem *item)
803private: 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/** 1186void 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
811class NewDevTreeItem : public QTreeWidgetItem 1199void RegEditPanel::OnRegFieldActivated(const QModelIndex& index)
812{ 1200{
813public: 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; } 1207void RegEditPanel::OnFieldModified()
818private: 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/** 1215void RegEditPanel::DoModify()
823 * DevTreeItem 1216{
824 */ 1217 m_value_model->UpdateRegister(*m_ref.get());
1218 UpdateWidthRestrictions();
1219 OnModified();
1220}
825 1221
826class DevTreeItem : public QTreeWidgetItem 1222void RegEditPanel::OnRegFieldDelete()
827{ 1223{
828public: 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; } 1240void RegEditPanel::OnFieldRemove(int index)
833private: 1241{
834 SocDevRef m_ref; 1242 Q_UNUSED(index);
835}; 1243}
836 1244
837/** 1245int 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
841class NewRegTreeItem : public QTreeWidgetItem 1270void RegEditPanel::OnRegFieldNew()
842{ 1271{
843public: 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);
848private: 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
856class RegTreeItem : public QTreeWidgetItem 1290void RegEditPanel::OnFieldCreate()
857{ 1291{
858public: 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; }
863private:
864 SocRegRef m_ref;
865};
866 1294
867/** 1295void 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
871class NewFieldTreeItem : public QTreeWidgetItem 1306namespace
872{ 1307{
873public:
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; } 1309enum
878private: 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/** 1316enum
883 * FieldTreeItem 1317{
884 */ 1318 SocRefRole = Qt::UserRole,
1319};
885 1320
886class FieldTreeItem : public QTreeWidgetItem 1321template<typename T>
1322T SocTreeItemVal(QTreeWidgetItem *item)
887{ 1323{
888public: 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; } 1327template<typename T>
893private: 1328QTreeWidgetItem *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
962QWidget *RegEdit::GetWidget() 1422QWidget *RegEdit::GetWidget()
@@ -968,6 +1428,16 @@ RegEdit::~RegEdit()
968{ 1428{
969} 1429}
970 1430
1431int RegEdit::SetMessage(MessageWidget::MessageType type, const QString& msg)
1432{
1433 return m_msg->SetMessage(type, msg);
1434}
1435
1436void RegEdit::HideMessage(int id)
1437{
1438 m_msg->HideMessage(id);
1439}
1440
971void RegEdit::OnSave() 1441void 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
1052bool RegEdit::SaveSocFile(const QString& filename) 1525bool 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
1091void RegEdit::CreateNewFieldItem(QTreeWidgetItem *_parent) 1566void 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
1100void 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
1115void 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
1124void 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
1140void 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
1149void 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
1165void RegEdit::FillSocTree() 1587void 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
1176void RegEdit::MakeItalic(QTreeWidgetItem *item, bool it) 1597void 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
1183void RegEdit::FixupEmptyItem(QTreeWidgetItem *item) 1604QIcon 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
1615bool 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
1625void 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
1214void RegEdit::SetModified(bool add, bool mod) 1664void 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
1220namespace 1670void RegEdit::OnSocItemNew()
1221{
1222
1223template< typename T >
1224void 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
1684void 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
1231void RegEdit::OnSocItemDelete() 1699void 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
1280void RegEdit::OnSocModified(bool modified) 1731void 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
1288void RegEdit::DisplaySoc(SocRef ref) 1738void 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
1293void RegEdit::DisplayDev(SocDevRef ref) 1743void 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
1298void RegEdit::DisplayReg(SocRegRef ref) 1748void 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
1303void RegEdit::DisplayField(SocFieldRef ref)
1304{
1305 SetPanel(new FieldEditPanel(ref, this));
1306}
1307
1308void RegEdit::UpdateName(QTreeWidgetItem *current) 1753void 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
1335void RegEdit::OnSocItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) 1774void 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
1362void RegEdit::OnSocItemActivated(QTreeWidgetItem *current, int column) 1811void 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
1375void 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
1388void 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
1401void 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
1413bool RegEdit::Quit() 1825bool RegEdit::Quit()