summaryrefslogtreecommitdiff
path: root/utils/regtools/qeditor/regedit.cpp
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2016-02-06 15:08:43 +0000
committerAmaury Pouly <amaury.pouly@gmail.com>2016-02-06 15:20:48 +0000
commit6b9610fb908b27d1e0383c8d9bde3a88f35ed30c (patch)
tree1b0f5e2821b44d20f3704c584e309f5911357040 /utils/regtools/qeditor/regedit.cpp
parent0f701a64bee43e79f95970ae9c0ec43ea7fcdf17 (diff)
downloadrockbox-6b9610fb908b27d1e0383c8d9bde3a88f35ed30c.tar.gz
rockbox-6b9610fb908b27d1e0383c8d9bde3a88f35ed30c.zip
regtoosl/qeditor: port to the new description format
This big commit port qeditor from v1 to v2 register file format. Although the display code was much simplified, the edit code had to be rewritten. The new code also brings many improvement to the register display widget. The new code also compiles with both Qt4 and Qt5, although it is recommended to use Qt5 to get some improvements, especially in the layout of editor. Change-Id: I24633ac37a144f25d9e705b565654269ec9cfbd3
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()