diff options
Diffstat (limited to 'utils/regtools/qeditor/regedit.cpp')
-rw-r--r-- | utils/regtools/qeditor/regedit.cpp | 1324 |
1 files changed, 1324 insertions, 0 deletions
diff --git a/utils/regtools/qeditor/regedit.cpp b/utils/regtools/qeditor/regedit.cpp new file mode 100644 index 0000000000..5e498ce496 --- /dev/null +++ b/utils/regtools/qeditor/regedit.cpp | |||
@@ -0,0 +1,1324 @@ | |||
1 | #include "regedit.h" | ||
2 | #include <QFileDialog> | ||
3 | #include <QDebug> | ||
4 | #include <QHeaderView> | ||
5 | #include <QMessageBox> | ||
6 | #include <QInputDialog> | ||
7 | |||
8 | /** | ||
9 | * EmptyEditPanel | ||
10 | */ | ||
11 | EmptyEditPanel::EmptyEditPanel(QWidget *parent) | ||
12 | :QWidget(parent) | ||
13 | { | ||
14 | } | ||
15 | |||
16 | /** | ||
17 | * SocEditPanel | ||
18 | */ | ||
19 | SocEditPanel::SocEditPanel(SocRef ref, QWidget *parent) | ||
20 | :QWidget(parent), m_ref(ref) | ||
21 | { | ||
22 | m_name_group = new QGroupBox("Name", this); | ||
23 | m_name_edit = new QLineEdit(this); | ||
24 | m_name_edit->setText(QString::fromStdString(ref.GetSoc().name)); | ||
25 | QVBoxLayout *name_group_layout = new QVBoxLayout; | ||
26 | name_group_layout->addWidget(m_name_edit); | ||
27 | m_name_group->setLayout(name_group_layout); | ||
28 | |||
29 | m_desc_group = new QGroupBox("Description", this); | ||
30 | QHBoxLayout *group_layout = new QHBoxLayout; | ||
31 | m_desc_edit = new MyTextEditor(this); | ||
32 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetSoc().desc)); | ||
33 | group_layout->addWidget(m_desc_edit); | ||
34 | m_desc_group->setLayout(group_layout); | ||
35 | |||
36 | QVBoxLayout *layout = new QVBoxLayout; | ||
37 | layout->addWidget(m_name_group); | ||
38 | layout->addWidget(m_desc_group); | ||
39 | layout->addStretch(1); | ||
40 | |||
41 | connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&))); | ||
42 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnTextEdited())); | ||
43 | |||
44 | setLayout(layout); | ||
45 | } | ||
46 | |||
47 | void SocEditPanel::OnNameEdited(const QString& text) | ||
48 | { | ||
49 | m_ref.GetSoc().name = text.toStdString(); | ||
50 | emit OnModified(m_name_edit->isModified()); | ||
51 | } | ||
52 | |||
53 | void SocEditPanel::OnTextEdited() | ||
54 | { | ||
55 | m_ref.GetSoc().desc = m_desc_edit->GetTextHtml().toStdString(); | ||
56 | emit OnModified(m_desc_edit->IsModified()); | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * DevEditPanel | ||
61 | */ | ||
62 | DevEditPanel::DevEditPanel(SocDevRef ref, QWidget *parent) | ||
63 | :QWidget(parent), m_ref(ref) | ||
64 | { | ||
65 | m_name_group = new QGroupBox("Name", this); | ||
66 | m_name_edit = new QLineEdit(this); | ||
67 | m_name_edit->setText(QString::fromStdString(ref.GetDev().name)); | ||
68 | QVBoxLayout *name_group_layout = new QVBoxLayout; | ||
69 | name_group_layout->addWidget(m_name_edit); | ||
70 | m_name_group->setLayout(name_group_layout); | ||
71 | |||
72 | m_long_name_group = new QGroupBox("Long Name", this); | ||
73 | m_long_name_edit = new QLineEdit(this); | ||
74 | m_long_name_edit->setText(QString::fromStdString(ref.GetDev().long_name)); | ||
75 | QVBoxLayout *long_name_group_layout = new QVBoxLayout; | ||
76 | long_name_group_layout->addWidget(m_long_name_edit); | ||
77 | m_long_name_group->setLayout(long_name_group_layout); | ||
78 | |||
79 | m_version_group = new QGroupBox("Version", this); | ||
80 | m_version_edit = new QLineEdit(this); | ||
81 | m_version_edit->setText(QString::fromStdString(ref.GetDev().version)); | ||
82 | QVBoxLayout *version_group_layout = new QVBoxLayout; | ||
83 | version_group_layout->addWidget(m_version_edit); | ||
84 | m_version_group->setLayout(version_group_layout); | ||
85 | |||
86 | QVBoxLayout *name_ver_layout = new QVBoxLayout; | ||
87 | name_ver_layout->addWidget(m_name_group); | ||
88 | name_ver_layout->addWidget(m_long_name_group); | ||
89 | name_ver_layout->addWidget(m_version_group); | ||
90 | name_ver_layout->addStretch(); | ||
91 | |||
92 | m_instances_table = new QTableWidget(this); | ||
93 | m_instances_table->setRowCount(ref.GetDev().addr.size() + 1); | ||
94 | m_instances_table->setColumnCount(3); | ||
95 | for(size_t row = 0; row < ref.GetDev().addr.size(); row++) | ||
96 | FillRow(row, ref.GetDev().addr[row]); | ||
97 | CreateNewRow(ref.GetDev().addr.size()); | ||
98 | m_instances_table->setHorizontalHeaderItem(0, new QTableWidgetItem("")); | ||
99 | m_instances_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name")); | ||
100 | m_instances_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Address")); | ||
101 | m_instances_table->verticalHeader()->setVisible(false); | ||
102 | m_instances_table->resizeColumnsToContents(); | ||
103 | m_instances_table->horizontalHeader()->setStretchLastSection(true); | ||
104 | m_instances_table->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); | ||
105 | m_instances_group = new QGroupBox("Instances", this); | ||
106 | QHBoxLayout *instances_group_layout = new QHBoxLayout; | ||
107 | instances_group_layout->addWidget(m_instances_table); | ||
108 | m_instances_group->setLayout(instances_group_layout); | ||
109 | |||
110 | QHBoxLayout *top_layout = new QHBoxLayout; | ||
111 | top_layout->addWidget(m_instances_group); | ||
112 | top_layout->addLayout(name_ver_layout); | ||
113 | top_layout->addStretch(); | ||
114 | |||
115 | m_desc_group = new QGroupBox("Description", this); | ||
116 | QHBoxLayout *group_layout = new QHBoxLayout; | ||
117 | m_desc_edit = new MyTextEditor(this); | ||
118 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetDev().desc)); | ||
119 | group_layout->addWidget(m_desc_edit); | ||
120 | m_desc_group->setLayout(group_layout); | ||
121 | |||
122 | QVBoxLayout *layout = new QVBoxLayout; | ||
123 | layout->addLayout(top_layout, 0); | ||
124 | layout->addWidget(m_desc_group, 1); | ||
125 | |||
126 | setLayout(layout); | ||
127 | |||
128 | SocFieldItemDelegate *m_table_delegate = new SocFieldItemDelegate(this); | ||
129 | QItemEditorFactory *m_table_edit_factory = new QItemEditorFactory(); | ||
130 | SocFieldEditorCreator *m_table_edit_creator = new SocFieldEditorCreator(); | ||
131 | m_table_edit_factory->registerEditor(QVariant::UInt, m_table_edit_creator); | ||
132 | m_table_delegate->setItemEditorFactory(m_table_edit_factory); | ||
133 | m_instances_table->setItemDelegate(m_table_delegate); | ||
134 | |||
135 | connect(m_instances_table, SIGNAL(cellActivated(int,int)), this, SLOT(OnInstActivated(int,int))); | ||
136 | connect(m_instances_table, SIGNAL(cellChanged(int,int)), this, SLOT(OnInstChanged(int,int))); | ||
137 | connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&))); | ||
138 | connect(m_long_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnLongNameEdited(const QString&))); | ||
139 | connect(m_version_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnVersionEdited(const QString&))); | ||
140 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); | ||
141 | } | ||
142 | |||
143 | void DevEditPanel::OnNameEdited(const QString& text) | ||
144 | { | ||
145 | m_ref.GetDev().name = text.toStdString(); | ||
146 | emit OnModified(m_name_edit->isModified()); | ||
147 | } | ||
148 | |||
149 | void DevEditPanel::OnLongNameEdited(const QString& text) | ||
150 | { | ||
151 | m_ref.GetDev().long_name = text.toStdString(); | ||
152 | emit OnModified(m_long_name_edit->isModified()); | ||
153 | } | ||
154 | |||
155 | void DevEditPanel::OnVersionEdited(const QString& text) | ||
156 | { | ||
157 | m_ref.GetDev().version = text.toStdString(); | ||
158 | emit OnModified(m_version_edit->isModified()); | ||
159 | } | ||
160 | |||
161 | void DevEditPanel::OnDescEdited() | ||
162 | { | ||
163 | m_ref.GetDev().desc = m_desc_edit->GetTextHtml().toStdString(); | ||
164 | emit OnModified(m_desc_edit->IsModified()); | ||
165 | } | ||
166 | |||
167 | void DevEditPanel::CreateNewRow(int row) | ||
168 | { | ||
169 | QTableWidgetItem *item = new QTableWidgetItem(QIcon::fromTheme("list-add"), "", DevInstNewType); | ||
170 | item->setToolTip("New?"); | ||
171 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
172 | m_instances_table->setItem(row, DevInstIconColumn, item); | ||
173 | item = new QTableWidgetItem("New instance..."); | ||
174 | QFont font = item->font(); | ||
175 | font.setItalic(true); | ||
176 | item->setFont(font); | ||
177 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
178 | m_instances_table->setItem(row, DevInstNameColumn, item); | ||
179 | item = new QTableWidgetItem(""); | ||
180 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
181 | m_instances_table->setItem(row, DevInstAddrColumn, item); | ||
182 | } | ||
183 | |||
184 | void DevEditPanel::FillRow(int row, const soc_dev_addr_t& addr) | ||
185 | { | ||
186 | QTableWidgetItem *item = new QTableWidgetItem(QString::fromStdString(addr.name)); | ||
187 | item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | ||
188 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | ||
189 | m_instances_table->setItem(row, DevInstNameColumn, item); | ||
190 | item = new QTableWidgetItem(); | ||
191 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | ||
192 | item->setData(Qt::DisplayRole, QVariant(addr.addr)); | ||
193 | m_instances_table->setItem(row, DevInstAddrColumn, item); | ||
194 | item = new QTableWidgetItem(QIcon::fromTheme("list-remove"), "", DevInstDeleteType); | ||
195 | item->setToolTip("Remove?"); | ||
196 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
197 | m_instances_table->setItem(row, DevInstIconColumn, item); | ||
198 | } | ||
199 | |||
200 | void DevEditPanel::OnInstActivated(int row, int column) | ||
201 | { | ||
202 | if(column != 0) | ||
203 | return; | ||
204 | int type = m_instances_table->item(row, column)->type(); | ||
205 | if(type == DevInstDeleteType) | ||
206 | { | ||
207 | m_ref.GetDev().addr.erase(m_ref.GetDev().addr.begin() + row); | ||
208 | m_instances_table->removeRow(row); | ||
209 | } | ||
210 | else if(type == DevInstNewType) | ||
211 | { | ||
212 | m_instances_table->insertRow(row); | ||
213 | soc_dev_addr_t addr; | ||
214 | addr.name = QString("UNNAMED_%1").arg(row).toStdString(); | ||
215 | addr.addr = 0; | ||
216 | m_ref.GetDev().addr.push_back(addr); | ||
217 | FillRow(row, addr); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | void DevEditPanel::OnInstChanged(int row, int column) | ||
222 | { | ||
223 | /* ignore extra row for addition */ | ||
224 | if(row >= (int)m_ref.GetDev().addr.size()) | ||
225 | return; | ||
226 | QTableWidgetItem *item = m_instances_table->item(row, column); | ||
227 | if(column == DevInstNameColumn) | ||
228 | { | ||
229 | m_ref.GetDev().addr[row].name = item->text().toStdString(); | ||
230 | emit OnModified(true); | ||
231 | } | ||
232 | else if(column == DevInstAddrColumn) | ||
233 | { | ||
234 | m_ref.GetDev().addr[row].addr = item->data(Qt::DisplayRole).toUInt(); | ||
235 | emit OnModified(true); | ||
236 | } | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * RegEditPanel | ||
241 | */ | ||
242 | |||
243 | RegEditPanel::RegEditPanel(SocRegRef ref, QWidget *parent) | ||
244 | :QWidget(parent), m_ref(ref), m_reg_font(font()) | ||
245 | { | ||
246 | m_reg_font.setWeight(100); | ||
247 | m_reg_font.setKerning(false); | ||
248 | |||
249 | m_name_group = new QGroupBox("Name", this); | ||
250 | m_name_edit = new QLineEdit(this); | ||
251 | m_name_edit->setText(QString::fromStdString(ref.GetReg().name)); | ||
252 | QVBoxLayout *name_group_layout = new QVBoxLayout; | ||
253 | name_group_layout->addWidget(m_name_edit); | ||
254 | m_name_group->setLayout(name_group_layout); | ||
255 | |||
256 | m_instances_table = new QTableWidget(this); | ||
257 | m_instances_table->setRowCount(ref.GetReg().addr.size() + 1); | ||
258 | m_instances_table->setColumnCount(RegInstNrColumns); | ||
259 | for(size_t row = 0; row < ref.GetReg().addr.size(); row++) | ||
260 | FillRow(row, ref.GetReg().addr[row]); | ||
261 | CreateNewAddrRow(ref.GetReg().addr.size()); | ||
262 | m_instances_table->setHorizontalHeaderItem(RegInstIconColumn, new QTableWidgetItem("")); | ||
263 | m_instances_table->setHorizontalHeaderItem(RegInstNameColumn, new QTableWidgetItem("Name")); | ||
264 | m_instances_table->setHorizontalHeaderItem(RegInstAddrColumn, new QTableWidgetItem("Address")); | ||
265 | m_instances_table->verticalHeader()->setVisible(false); | ||
266 | m_instances_table->resizeColumnsToContents(); | ||
267 | m_instances_table->horizontalHeader()->setStretchLastSection(true); | ||
268 | m_instances_table->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); | ||
269 | m_instances_group = new QGroupBox("Instances", this); | ||
270 | QHBoxLayout *instances_group_layout = new QHBoxLayout; | ||
271 | instances_group_layout->addWidget(m_instances_table); | ||
272 | m_instances_group->setLayout(instances_group_layout); | ||
273 | |||
274 | m_desc_group = new QGroupBox("Description", this); | ||
275 | QHBoxLayout *group_layout = new QHBoxLayout; | ||
276 | m_desc_edit = new MyTextEditor(this); | ||
277 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetReg().desc)); | ||
278 | group_layout->addWidget(m_desc_edit); | ||
279 | m_desc_group->setLayout(group_layout); | ||
280 | |||
281 | bool has_sct = m_ref.GetReg().flags & REG_HAS_SCT; | ||
282 | m_sct_check = new QCheckBox("Set/Clear/Toggle", this); | ||
283 | m_sct_check->setCheckState(has_sct ? Qt::Checked : Qt::Unchecked); | ||
284 | QHBoxLayout *flags_layout = new QHBoxLayout; | ||
285 | flags_layout->addWidget(m_sct_check); | ||
286 | flags_layout->addStretch(); | ||
287 | m_flags_group = new QGroupBox("Flags", this); | ||
288 | m_flags_group->setLayout(flags_layout); | ||
289 | |||
290 | m_formula_combo = new QComboBox(this); | ||
291 | m_formula_combo->addItem("None", QVariant(REG_FORMULA_NONE)); | ||
292 | m_formula_combo->addItem("String", QVariant(REG_FORMULA_STRING)); | ||
293 | m_formula_combo->setCurrentIndex(m_formula_combo->findData(QVariant(m_ref.GetReg().formula.type))); | ||
294 | m_formula_type_label = new QLabel("Type:", this); | ||
295 | QHBoxLayout *formula_top_layout = new QHBoxLayout; | ||
296 | formula_top_layout->addWidget(m_formula_type_label); | ||
297 | formula_top_layout->addWidget(m_formula_combo); | ||
298 | m_formula_string_edit = new QLineEdit(QString::fromStdString(ref.GetReg().formula.string), this); | ||
299 | QVBoxLayout *formula_layout = new QVBoxLayout; | ||
300 | formula_layout->addLayout(formula_top_layout); | ||
301 | formula_layout->addWidget(m_formula_string_edit); | ||
302 | m_formula_string_gen = new QPushButton("Generate", this); | ||
303 | formula_layout->addWidget(m_formula_string_gen); | ||
304 | m_formula_group = new QGroupBox("Formula", this); | ||
305 | m_formula_group->setLayout(formula_layout); | ||
306 | |||
307 | QVBoxLayout *name_layout = new QVBoxLayout; | ||
308 | name_layout->addWidget(m_name_group); | ||
309 | name_layout->addWidget(m_flags_group); | ||
310 | name_layout->addWidget(m_formula_group); | ||
311 | name_layout->addStretch(); | ||
312 | |||
313 | QHBoxLayout *top_layout = new QHBoxLayout; | ||
314 | top_layout->addWidget(m_instances_group); | ||
315 | top_layout->addLayout(name_layout); | ||
316 | top_layout->addWidget(m_desc_group, 1); | ||
317 | |||
318 | m_sexy_display = new RegSexyDisplay(m_ref, this); | ||
319 | m_sexy_display->setFont(m_reg_font); | ||
320 | |||
321 | m_field_table = new QTableWidget; | ||
322 | m_field_table->setRowCount(m_ref.GetReg().field.size()); | ||
323 | m_field_table->setColumnCount(4); | ||
324 | for(size_t row = 0; row < m_ref.GetReg().field.size(); row++) | ||
325 | { | ||
326 | const soc_reg_field_t& field = m_ref.GetReg().field[row]; | ||
327 | QString bits_str; | ||
328 | if(field.first_bit == field.last_bit) | ||
329 | bits_str.sprintf("%d", field.first_bit); | ||
330 | else | ||
331 | bits_str.sprintf("%d:%d", field.last_bit, field.first_bit); | ||
332 | QTableWidgetItem *item = new QTableWidgetItem(bits_str); | ||
333 | item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | ||
334 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
335 | m_field_table->setItem(row, 1, item); | ||
336 | item = new QTableWidgetItem(QString(field.name.c_str())); | ||
337 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
338 | m_field_table->setItem(row, 2, item); | ||
339 | item = new QTableWidgetItem(QString(field.desc.c_str())); | ||
340 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
341 | m_field_table->setItem(row, 3, item); | ||
342 | UpdateWarning(row); | ||
343 | } | ||
344 | m_field_table->setHorizontalHeaderItem(0, new QTableWidgetItem("")); | ||
345 | m_field_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Bits")); | ||
346 | m_field_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Name")); | ||
347 | m_field_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Description")); | ||
348 | m_field_table->verticalHeader()->setVisible(false); | ||
349 | m_field_table->resizeColumnsToContents(); | ||
350 | m_field_table->horizontalHeader()->setStretchLastSection(true); | ||
351 | QHBoxLayout *field_layout = new QHBoxLayout; | ||
352 | field_layout->addWidget(m_field_table); | ||
353 | m_field_group = new QGroupBox("Flags", this); | ||
354 | m_field_group->setLayout(field_layout); | ||
355 | |||
356 | QVBoxLayout *layout = new QVBoxLayout; | ||
357 | layout->addLayout(top_layout, 0); | ||
358 | layout->addWidget(m_sexy_display, 0); | ||
359 | layout->addWidget(m_field_group); | ||
360 | |||
361 | UpdateFormula(); | ||
362 | |||
363 | setLayout(layout); | ||
364 | |||
365 | SocFieldItemDelegate *m_table_delegate = new SocFieldItemDelegate(this); | ||
366 | QItemEditorFactory *m_table_edit_factory = new QItemEditorFactory(); | ||
367 | SocFieldEditorCreator *m_table_edit_creator = new SocFieldEditorCreator(); | ||
368 | m_table_edit_factory->registerEditor(QVariant::UInt, m_table_edit_creator); | ||
369 | m_table_delegate->setItemEditorFactory(m_table_edit_factory); | ||
370 | m_instances_table->setItemDelegate(m_table_delegate); | ||
371 | |||
372 | connect(m_instances_table, SIGNAL(cellActivated(int,int)), this, SLOT(OnInstActivated(int,int))); | ||
373 | connect(m_instances_table, SIGNAL(cellChanged(int,int)), this, SLOT(OnInstChanged(int,int))); | ||
374 | connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&))); | ||
375 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); | ||
376 | connect(m_sct_check, SIGNAL(stateChanged(int)), this, SLOT(OnSctEdited(int))); | ||
377 | connect(m_formula_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(OnFormulaChanged(int))); | ||
378 | connect(m_formula_string_edit, SIGNAL(textChanged(const QString&)), this, | ||
379 | SLOT(OnFormulaStringChanged(const QString&))); | ||
380 | connect(m_formula_string_gen, SIGNAL(clicked(bool)), this, SLOT(OnFormulaGenerate(bool))); | ||
381 | } | ||
382 | |||
383 | void RegEditPanel::UpdateWarning(int row) | ||
384 | { | ||
385 | Q_UNUSED(row); | ||
386 | } | ||
387 | |||
388 | void RegEditPanel::OnFormulaStringChanged(const QString& text) | ||
389 | { | ||
390 | m_ref.GetReg().formula.string = text.toStdString(); | ||
391 | emit OnModified(true); | ||
392 | } | ||
393 | |||
394 | void RegEditPanel::OnFormulaGenerate(bool checked) | ||
395 | { | ||
396 | Q_UNUSED(checked); | ||
397 | bool ok; | ||
398 | int count = QInputDialog::getInt(this, "Instance generator", "Number of instances", | ||
399 | 0, 0, 100, 1, &ok); | ||
400 | if(!ok) | ||
401 | return; | ||
402 | std::string name(m_ref.GetReg().name); | ||
403 | size_t pos = name.find('n'); | ||
404 | if(pos == std::string::npos) | ||
405 | { | ||
406 | name.push_back('n'); | ||
407 | pos = name.size() - 1; | ||
408 | } | ||
409 | std::map< std::string, soc_word_t > map; | ||
410 | std::vector< std::pair< std::string, soc_word_t > > list; | ||
411 | std::string formula = m_ref.GetReg().formula.string; | ||
412 | for(int n = 0; n < count; n++) | ||
413 | { | ||
414 | map["n"] = n; | ||
415 | std::string err; | ||
416 | soc_word_t res; | ||
417 | if(!soc_desc_evaluate_formula(formula, map, res, err)) | ||
418 | { | ||
419 | qDebug() << "Cannot evaluator " << QString::fromStdString(formula) | ||
420 | << "for n=" << n << ": " << QString::fromStdString(err); | ||
421 | return; | ||
422 | } | ||
423 | std::string regname = name; | ||
424 | std::string strn = QString("%1").arg(n).toStdString(); | ||
425 | regname.replace(pos, 1, strn); | ||
426 | list.push_back(std::make_pair(regname, res)); | ||
427 | } | ||
428 | // everything went good, commit result | ||
429 | while(m_instances_table->rowCount() > 1) | ||
430 | m_instances_table->removeRow(0); | ||
431 | m_ref.GetReg().addr.resize(list.size()); | ||
432 | for(size_t i = 0; i < list.size(); i++) | ||
433 | { | ||
434 | m_instances_table->insertRow(i); | ||
435 | m_ref.GetReg().addr[i].name = list[i].first; | ||
436 | m_ref.GetReg().addr[i].addr = list[i].second; | ||
437 | FillRow(i, m_ref.GetReg().addr[i]); | ||
438 | } | ||
439 | } | ||
440 | |||
441 | void RegEditPanel::OnFormulaChanged(int index) | ||
442 | { | ||
443 | if(index == -1) | ||
444 | return; | ||
445 | m_ref.GetReg().formula.type = static_cast< soc_reg_formula_type_t >(m_formula_combo->itemData(index).toInt()); | ||
446 | UpdateFormula(); | ||
447 | emit OnModified(true); | ||
448 | } | ||
449 | |||
450 | void RegEditPanel::UpdateFormula() | ||
451 | { | ||
452 | m_formula_string_edit->hide(); | ||
453 | m_formula_string_gen->hide(); | ||
454 | switch(m_ref.GetReg().formula.type) | ||
455 | { | ||
456 | case REG_FORMULA_STRING: | ||
457 | m_formula_string_edit->show(); | ||
458 | m_formula_string_gen->show(); | ||
459 | break; | ||
460 | case REG_FORMULA_NONE: | ||
461 | default: | ||
462 | break; | ||
463 | } | ||
464 | } | ||
465 | |||
466 | void RegEditPanel::OnSctEdited(int state) | ||
467 | { | ||
468 | if(state == Qt::Checked) | ||
469 | m_ref.GetReg().flags |= REG_HAS_SCT; | ||
470 | else | ||
471 | m_ref.GetReg().flags &= ~REG_HAS_SCT; | ||
472 | emit OnModified(true); | ||
473 | } | ||
474 | |||
475 | void RegEditPanel::FillRow(int row, const soc_reg_addr_t& addr) | ||
476 | { | ||
477 | QTableWidgetItem *item = new QTableWidgetItem(QString::fromStdString(addr.name)); | ||
478 | item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | ||
479 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | ||
480 | m_instances_table->setItem(row, RegInstNameColumn, item); | ||
481 | item = new QTableWidgetItem(); | ||
482 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | ||
483 | item->setData(Qt::DisplayRole, QVariant(addr.addr)); | ||
484 | m_instances_table->setItem(row, RegInstAddrColumn, item); | ||
485 | item = new QTableWidgetItem(QIcon::fromTheme("list-remove"), "", RegInstDeleteType); | ||
486 | item->setToolTip("Remove?"); | ||
487 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
488 | m_instances_table->setItem(row, RegInstIconColumn, item); | ||
489 | } | ||
490 | |||
491 | void RegEditPanel::CreateNewAddrRow(int row) | ||
492 | { | ||
493 | QTableWidgetItem *item = new QTableWidgetItem(QIcon::fromTheme("list-add"), "", RegInstNewType); | ||
494 | item->setToolTip("New?"); | ||
495 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
496 | m_instances_table->setItem(row, RegInstIconColumn, item); | ||
497 | item = new QTableWidgetItem("New instance..."); | ||
498 | QFont font = item->font(); | ||
499 | font.setItalic(true); | ||
500 | item->setFont(font); | ||
501 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
502 | m_instances_table->setItem(row, RegInstNameColumn, item); | ||
503 | item = new QTableWidgetItem(""); | ||
504 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
505 | m_instances_table->setItem(row, RegInstAddrColumn, item); | ||
506 | } | ||
507 | |||
508 | void RegEditPanel::OnNameEdited(const QString& text) | ||
509 | { | ||
510 | m_ref.GetReg().name = text.toStdString(); | ||
511 | emit OnModified(m_name_edit->isModified()); | ||
512 | } | ||
513 | |||
514 | void RegEditPanel::OnDescEdited() | ||
515 | { | ||
516 | m_ref.GetReg().desc = m_desc_edit->GetTextHtml().toStdString(); | ||
517 | emit OnModified(m_desc_edit->IsModified()); | ||
518 | } | ||
519 | |||
520 | void RegEditPanel::OnInstActivated(int row, int column) | ||
521 | { | ||
522 | if(column != 0) | ||
523 | return; | ||
524 | int type = m_instances_table->item(row, column)->type(); | ||
525 | if(type == RegInstDeleteType) | ||
526 | { | ||
527 | m_ref.GetReg().addr.erase(m_ref.GetReg().addr.begin() + row); | ||
528 | m_instances_table->removeRow(row); | ||
529 | } | ||
530 | else if(type == RegInstNewType) | ||
531 | { | ||
532 | m_instances_table->insertRow(row); | ||
533 | soc_reg_addr_t addr; | ||
534 | addr.name = QString("UNNAMED_%1").arg(row).toStdString(); | ||
535 | addr.addr = 0; | ||
536 | m_ref.GetReg().addr.push_back(addr); | ||
537 | FillRow(row, addr); | ||
538 | } | ||
539 | } | ||
540 | |||
541 | void RegEditPanel::OnInstChanged(int row, int column) | ||
542 | { | ||
543 | /* ignore extra row for addition */ | ||
544 | if(row >= (int)m_ref.GetReg().addr.size()) | ||
545 | return; | ||
546 | QTableWidgetItem *item = m_instances_table->item(row, column); | ||
547 | if(column == RegInstNameColumn) | ||
548 | { | ||
549 | m_ref.GetReg().addr[row].name = item->text().toStdString(); | ||
550 | emit OnModified(true); | ||
551 | } | ||
552 | else if(column == RegInstAddrColumn) | ||
553 | { | ||
554 | m_ref.GetReg().addr[row].addr = item->data(Qt::DisplayRole).toUInt(); | ||
555 | emit OnModified(true); | ||
556 | } | ||
557 | } | ||
558 | |||
559 | /** | ||
560 | * FieldEditPanel | ||
561 | */ | ||
562 | FieldEditPanel::FieldEditPanel(SocFieldRef ref, QWidget *parent) | ||
563 | :QWidget(parent), m_ref(ref) | ||
564 | { | ||
565 | m_name_group = new QGroupBox("Name", this); | ||
566 | m_name_edit = new QLineEdit(this); | ||
567 | m_name_edit->setText(QString::fromStdString(ref.GetField().name)); | ||
568 | QVBoxLayout *name_group_layout = new QVBoxLayout; | ||
569 | name_group_layout->addWidget(m_name_edit); | ||
570 | m_name_group->setLayout(name_group_layout); | ||
571 | |||
572 | m_bitrange_group = new QGroupBox("Bit Range", this); | ||
573 | m_bitrange_edit = new QLineEdit(this); | ||
574 | const soc_reg_field_t& field = ref.GetField(); | ||
575 | QString bits_str; | ||
576 | if(field.first_bit == field.last_bit) | ||
577 | bits_str.sprintf("%d", field.first_bit); | ||
578 | else | ||
579 | bits_str.sprintf("%d:%d", field.last_bit, field.first_bit); | ||
580 | m_bitrange_edit->setText(bits_str); | ||
581 | m_bitrange_edit->setValidator(new SocBitRangeValidator(m_bitrange_edit)); | ||
582 | QVBoxLayout *bitrange_group_layout = new QVBoxLayout; | ||
583 | bitrange_group_layout->addWidget(m_bitrange_edit); | ||
584 | m_bitrange_group->setLayout(bitrange_group_layout); | ||
585 | |||
586 | m_desc_group = new QGroupBox("Description", this); | ||
587 | QHBoxLayout *group_layout = new QHBoxLayout; | ||
588 | m_desc_edit = new MyTextEditor(this); | ||
589 | m_desc_edit->SetTextHtml(QString::fromStdString(ref.GetField().desc)); | ||
590 | group_layout->addWidget(m_desc_edit); | ||
591 | m_desc_group->setLayout(group_layout); | ||
592 | |||
593 | m_value_group = new QGroupBox("Values", this); | ||
594 | QHBoxLayout *value_layout = new QHBoxLayout; | ||
595 | m_value_table = new QTableWidget(this); | ||
596 | m_value_table->setRowCount(ref.GetField().value.size() + 1); | ||
597 | m_value_table->setColumnCount(FieldValueNrColumns); | ||
598 | for(size_t row = 0; row < ref.GetField().value.size(); row++) | ||
599 | FillRow(row, ref.GetField().value[row]); | ||
600 | CreateNewRow(ref.GetField().value.size()); | ||
601 | m_value_table->setHorizontalHeaderItem(FieldValueIconColumn, new QTableWidgetItem("")); | ||
602 | m_value_table->setHorizontalHeaderItem(FieldValueNameColumn, new QTableWidgetItem("Name")); | ||
603 | m_value_table->setHorizontalHeaderItem(FieldValueValueColumn, new QTableWidgetItem("Value")); | ||
604 | m_value_table->setHorizontalHeaderItem(FieldValueDescColumn, new QTableWidgetItem("Description")); | ||
605 | m_value_table->verticalHeader()->setVisible(false); | ||
606 | m_value_table->horizontalHeader()->setStretchLastSection(true); | ||
607 | value_layout->addWidget(m_value_table); | ||
608 | m_value_group->setLayout(value_layout); | ||
609 | |||
610 | QHBoxLayout *line_layout = new QHBoxLayout; | ||
611 | line_layout->addWidget(m_name_group); | ||
612 | line_layout->addWidget(m_bitrange_group); | ||
613 | line_layout->addStretch(); | ||
614 | |||
615 | QVBoxLayout *left_layout = new QVBoxLayout; | ||
616 | left_layout->addLayout(line_layout); | ||
617 | left_layout->addWidget(m_desc_group); | ||
618 | left_layout->addWidget(m_value_group, 1); | ||
619 | |||
620 | UpdateDelegates(); | ||
621 | |||
622 | connect(m_name_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnNameEdited(const QString&))); | ||
623 | connect(m_desc_edit, SIGNAL(OnTextChanged()), this, SLOT(OnDescEdited())); | ||
624 | connect(m_value_table, SIGNAL(cellActivated(int,int)), this, SLOT(OnValueActivated(int,int))); | ||
625 | connect(m_value_table, SIGNAL(cellChanged(int,int)), this, SLOT(OnValueChanged(int,int))); | ||
626 | connect(m_bitrange_edit, SIGNAL(textChanged(const QString&)), this, SLOT(OnBitRangeEdited(const QString&))); | ||
627 | |||
628 | setLayout(left_layout); | ||
629 | } | ||
630 | |||
631 | void FieldEditPanel::UpdateDelegates() | ||
632 | { | ||
633 | SocFieldItemDelegate *m_table_delegate = new SocFieldItemDelegate(m_ref.GetField(), this); | ||
634 | QItemEditorFactory *m_table_edit_factory = new QItemEditorFactory(); | ||
635 | SocFieldEditorCreator *m_table_edit_creator = new SocFieldEditorCreator(m_ref.GetField()); | ||
636 | m_table_edit_factory->registerEditor(QVariant::UInt, m_table_edit_creator); | ||
637 | m_table_delegate->setItemEditorFactory(m_table_edit_factory); | ||
638 | m_value_table->setItemDelegate(m_table_delegate); | ||
639 | m_value_table->resizeColumnsToContents(); | ||
640 | } | ||
641 | |||
642 | void FieldEditPanel::UpdateWarning(int row) | ||
643 | { | ||
644 | soc_word_t val = m_ref.GetField().value[row].value; | ||
645 | soc_word_t max = m_ref.GetField().bitmask() >> m_ref.GetField().first_bit; | ||
646 | QTableWidgetItem *item = m_value_table->item(row, FieldValueValueColumn); | ||
647 | if(val > max) | ||
648 | { | ||
649 | item->setIcon(QIcon::fromTheme("dialog-warning")); | ||
650 | item->setToolTip("Value is too big for the field"); | ||
651 | } | ||
652 | else | ||
653 | { | ||
654 | item->setIcon(QIcon()); | ||
655 | item->setToolTip(""); | ||
656 | } | ||
657 | } | ||
658 | |||
659 | void FieldEditPanel::FillRow(int row, const soc_reg_field_value_t& val) | ||
660 | { | ||
661 | QTableWidgetItem *item = new QTableWidgetItem(QString::fromStdString(val.name)); | ||
662 | item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | ||
663 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | ||
664 | m_value_table->setItem(row, FieldValueNameColumn, item); | ||
665 | item = new QTableWidgetItem(); | ||
666 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | ||
667 | item->setData(Qt::DisplayRole, QVariant(val.value)); | ||
668 | m_value_table->setItem(row, FieldValueValueColumn, item); | ||
669 | item = new QTableWidgetItem(QString::fromStdString(val.desc)); | ||
670 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable); | ||
671 | m_value_table->setItem(row, FieldValueDescColumn, item); | ||
672 | item = new QTableWidgetItem(QIcon::fromTheme("list-remove"), "", FieldValueDeleteType); | ||
673 | item->setToolTip("Remove?"); | ||
674 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
675 | m_value_table->setItem(row, FieldValueIconColumn, item); | ||
676 | UpdateWarning(row); | ||
677 | } | ||
678 | |||
679 | void FieldEditPanel::CreateNewRow(int row) | ||
680 | { | ||
681 | QTableWidgetItem *item = new QTableWidgetItem(QIcon::fromTheme("list-add"), "", FieldValueNewType); | ||
682 | item->setToolTip("New?"); | ||
683 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
684 | m_value_table->setItem(row, FieldValueIconColumn, item); | ||
685 | item = new QTableWidgetItem("New value..."); | ||
686 | QFont font = item->font(); | ||
687 | font.setItalic(true); | ||
688 | item->setFont(font); | ||
689 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
690 | m_value_table->setItem(row, FieldValueNameColumn, item); | ||
691 | } | ||
692 | |||
693 | void FieldEditPanel::OnBitRangeEdited(const QString& input) | ||
694 | { | ||
695 | const SocBitRangeValidator *validator = | ||
696 | dynamic_cast< const SocBitRangeValidator *>(m_bitrange_edit->validator()); | ||
697 | int first, last; | ||
698 | QValidator::State state = validator->parse(input, last, first); | ||
699 | if(state != QValidator::Acceptable) | ||
700 | return; | ||
701 | m_ref.GetField().first_bit = first; | ||
702 | m_ref.GetField().last_bit = last; | ||
703 | // update all warning signs | ||
704 | for(size_t row = 0; row < m_ref.GetField().value.size(); row++) | ||
705 | UpdateWarning(row); | ||
706 | // also updates delegates because they now have the wrong view of the field | ||
707 | UpdateDelegates(); | ||
708 | emit OnModified(true); | ||
709 | } | ||
710 | |||
711 | void FieldEditPanel::OnNameEdited(const QString& text) | ||
712 | { | ||
713 | m_ref.GetField().name = text.toStdString(); | ||
714 | emit OnModified(m_name_edit->isModified()); | ||
715 | } | ||
716 | |||
717 | void FieldEditPanel::OnDescEdited() | ||
718 | { | ||
719 | m_ref.GetField().desc = m_desc_edit->GetTextHtml().toStdString(); | ||
720 | emit OnModified(m_desc_edit->IsModified()); | ||
721 | } | ||
722 | |||
723 | void FieldEditPanel::OnValueActivated(int row, int column) | ||
724 | { | ||
725 | if(column != 0) | ||
726 | return; | ||
727 | int type = m_value_table->item(row, column)->type(); | ||
728 | if(type == FieldValueDeleteType) | ||
729 | { | ||
730 | m_ref.GetField().value.erase(m_ref.GetField().value.begin() + row); | ||
731 | m_value_table->removeRow(row); | ||
732 | } | ||
733 | else if(type == FieldValueNewType) | ||
734 | { | ||
735 | m_value_table->insertRow(row); | ||
736 | soc_reg_field_value_t val; | ||
737 | val.name = QString("UNNAMED_%1").arg(row).toStdString(); | ||
738 | val.value = 0; | ||
739 | m_ref.GetField().value.push_back(val); | ||
740 | FillRow(row, val); | ||
741 | } | ||
742 | } | ||
743 | |||
744 | void FieldEditPanel::OnValueChanged(int row, int column) | ||
745 | { | ||
746 | /* ignore extra row for addition */ | ||
747 | if(row >= (int)m_ref.GetField().value.size()) | ||
748 | return; | ||
749 | QTableWidgetItem *item = m_value_table->item(row, column); | ||
750 | if(column == FieldValueNameColumn) | ||
751 | m_ref.GetField().value[row].name = item->text().toStdString(); | ||
752 | else if(column == FieldValueValueColumn) | ||
753 | { | ||
754 | soc_word_t& fval = m_ref.GetField().value[row].value; | ||
755 | soc_word_t new_val = item->data(Qt::DisplayRole).toUInt(); | ||
756 | /* avoid infinite recursion by calling UpdateWarning() when | ||
757 | * only the icon changes which would trigger this callback again */ | ||
758 | if(fval != new_val) | ||
759 | { | ||
760 | fval = new_val; | ||
761 | UpdateWarning(row); | ||
762 | } | ||
763 | } | ||
764 | else if(column == FieldValueDescColumn) | ||
765 | m_ref.GetField().value[row].desc = item->text().toStdString(); | ||
766 | emit OnModified(true); | ||
767 | } | ||
768 | |||
769 | namespace | ||
770 | { | ||
771 | |||
772 | enum | ||
773 | { | ||
774 | SocTreeSocType = QTreeWidgetItem::UserType, | ||
775 | SocTreeDevType, | ||
776 | SocTreeRegType, | ||
777 | SocTreeFieldType, | ||
778 | SocTreeNewDevType, | ||
779 | SocTreeNewRegType, | ||
780 | SocTreeNewFieldType, | ||
781 | }; | ||
782 | |||
783 | /** | ||
784 | * SocTreeItem | ||
785 | */ | ||
786 | |||
787 | class SocTreeItem : public QTreeWidgetItem | ||
788 | { | ||
789 | public: | ||
790 | SocTreeItem(const QString& string, const SocRef& ref) | ||
791 | :QTreeWidgetItem(QStringList(string), SocTreeSocType), m_ref(ref) {} | ||
792 | |||
793 | const SocRef& GetRef() { return m_ref; } | ||
794 | private: | ||
795 | SocRef m_ref; | ||
796 | }; | ||
797 | |||
798 | /** | ||
799 | * NewDevTreeItem | ||
800 | */ | ||
801 | |||
802 | class NewDevTreeItem : public QTreeWidgetItem | ||
803 | { | ||
804 | public: | ||
805 | NewDevTreeItem(const QString& string, const SocRef& ref) | ||
806 | :QTreeWidgetItem(QStringList(string), SocTreeNewDevType), m_ref(ref) {} | ||
807 | |||
808 | const SocRef& GetRef() { return m_ref; } | ||
809 | private: | ||
810 | SocRef m_ref; | ||
811 | }; | ||
812 | |||
813 | /** | ||
814 | * DevTreeItem | ||
815 | */ | ||
816 | |||
817 | class DevTreeItem : public QTreeWidgetItem | ||
818 | { | ||
819 | public: | ||
820 | DevTreeItem(const QString& string, const SocDevRef& ref) | ||
821 | :QTreeWidgetItem(QStringList(string), SocTreeDevType), m_ref(ref) {} | ||
822 | |||
823 | const SocDevRef& GetRef() { return m_ref; } | ||
824 | private: | ||
825 | SocDevRef m_ref; | ||
826 | }; | ||
827 | |||
828 | /** | ||
829 | * NewRegTreeItem | ||
830 | */ | ||
831 | |||
832 | class NewRegTreeItem : public QTreeWidgetItem | ||
833 | { | ||
834 | public: | ||
835 | NewRegTreeItem(const QString& string, const SocDevRef& ref) | ||
836 | :QTreeWidgetItem(QStringList(string), SocTreeNewRegType), m_ref(ref) {} | ||
837 | |||
838 | const SocDevRef& GetRef() { return m_ref; } | ||
839 | private: | ||
840 | SocDevRef m_ref; | ||
841 | }; | ||
842 | |||
843 | /** | ||
844 | * RegTreeItem | ||
845 | */ | ||
846 | |||
847 | class RegTreeItem : public QTreeWidgetItem | ||
848 | { | ||
849 | public: | ||
850 | RegTreeItem(const QString& string, const SocRegRef& ref) | ||
851 | :QTreeWidgetItem(QStringList(string), SocTreeRegType), m_ref(ref) {} | ||
852 | |||
853 | const SocRegRef& GetRef() { return m_ref; } | ||
854 | private: | ||
855 | SocRegRef m_ref; | ||
856 | }; | ||
857 | |||
858 | /** | ||
859 | * NewFieldTreeItem | ||
860 | */ | ||
861 | |||
862 | class NewFieldTreeItem : public QTreeWidgetItem | ||
863 | { | ||
864 | public: | ||
865 | NewFieldTreeItem(const QString& string, const SocRegRef& ref) | ||
866 | :QTreeWidgetItem(QStringList(string), SocTreeNewFieldType), m_ref(ref) {} | ||
867 | |||
868 | const SocRegRef& GetRef() { return m_ref; } | ||
869 | private: | ||
870 | SocRegRef m_ref; | ||
871 | }; | ||
872 | |||
873 | /** | ||
874 | * FieldTreeItem | ||
875 | */ | ||
876 | |||
877 | class FieldTreeItem : public QTreeWidgetItem | ||
878 | { | ||
879 | public: | ||
880 | FieldTreeItem(const QString& string, const SocFieldRef& ref) | ||
881 | :QTreeWidgetItem(QStringList(string), SocTreeFieldType), m_ref(ref) {} | ||
882 | |||
883 | const SocFieldRef& GetRef() { return m_ref; } | ||
884 | private: | ||
885 | SocFieldRef m_ref; | ||
886 | }; | ||
887 | |||
888 | } | ||
889 | |||
890 | /** | ||
891 | * RegEdit | ||
892 | */ | ||
893 | RegEdit::RegEdit(Backend *backend, QWidget *parent) | ||
894 | :QWidget(parent), m_backend(backend) | ||
895 | { | ||
896 | QVBoxLayout *m_vert_layout = new QVBoxLayout(); | ||
897 | m_file_group = new QGroupBox("File selection", this); | ||
898 | QHBoxLayout *m_file_group_layout = new QHBoxLayout(); | ||
899 | m_file_edit = new QLineEdit(this); | ||
900 | m_file_edit->setReadOnly(true); | ||
901 | m_file_open = new QToolButton(this); | ||
902 | m_file_open->setText("Open"); | ||
903 | m_file_open->setIcon(QIcon::fromTheme("document-open")); | ||
904 | m_file_open->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); | ||
905 | QMenu *file_open_menu = new QMenu(this); | ||
906 | QAction *new_act = file_open_menu->addAction(QIcon::fromTheme("document-new"), "New..."); | ||
907 | m_file_open->setMenu(file_open_menu); | ||
908 | |||
909 | m_file_save = new QToolButton(this); | ||
910 | m_file_save->setText("Save"); | ||
911 | m_file_save->setIcon(QIcon::fromTheme("document-save")); | ||
912 | m_file_save->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); | ||
913 | QMenu *file_save_menu = new QMenu(this); | ||
914 | QAction *saveas_act = file_save_menu->addAction(QIcon::fromTheme("document-save-as"), "Save as..."); | ||
915 | m_file_save->setMenu(file_save_menu); | ||
916 | m_file_group_layout->addWidget(m_file_open); | ||
917 | m_file_group_layout->addWidget(m_file_save); | ||
918 | m_file_group_layout->addWidget(m_file_edit); | ||
919 | |||
920 | m_splitter = new QSplitter(this); | ||
921 | m_soc_tree = new QTreeWidget(this); | ||
922 | m_soc_tree->setColumnCount(1); | ||
923 | m_soc_tree->setHeaderLabel(QString("Name")); | ||
924 | m_splitter->addWidget(m_soc_tree); | ||
925 | m_splitter->setStretchFactor(0, 0); | ||
926 | |||
927 | m_file_group->setLayout(m_file_group_layout); | ||
928 | m_vert_layout->addWidget(m_file_group); | ||
929 | m_vert_layout->addWidget(m_splitter, 1); | ||
930 | |||
931 | setLayout(m_vert_layout); | ||
932 | |||
933 | SetModified(false, false); | ||
934 | m_right_panel = 0; | ||
935 | SetPanel(new EmptyEditPanel(this)); | ||
936 | |||
937 | connect(m_file_open, SIGNAL(clicked()), this, SLOT(OnOpen())); | ||
938 | connect(m_file_save, SIGNAL(clicked()), this, SLOT(OnSave())); | ||
939 | connect(new_act, SIGNAL(triggered()), this, SLOT(OnNew())); | ||
940 | connect(saveas_act, SIGNAL(triggered()), this, SLOT(OnSaveAs())); | ||
941 | connect(m_soc_tree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), | ||
942 | this, SLOT(OnSocItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); | ||
943 | connect(m_soc_tree, SIGNAL(itemActivated(QTreeWidgetItem*, int)), | ||
944 | this, SLOT(OnSocItemActivated(QTreeWidgetItem*, int))); | ||
945 | } | ||
946 | |||
947 | RegEdit::~RegEdit() | ||
948 | { | ||
949 | } | ||
950 | |||
951 | void RegEdit::OnSave() | ||
952 | { | ||
953 | SaveSoc(); | ||
954 | } | ||
955 | |||
956 | void RegEdit::OnSaveAs() | ||
957 | { | ||
958 | SaveSocAs(); | ||
959 | } | ||
960 | |||
961 | bool RegEdit::CloseSoc() | ||
962 | { | ||
963 | if(!m_modified) | ||
964 | return true; | ||
965 | QMessageBox msgBox; | ||
966 | msgBox.setText("The description has been modified."); | ||
967 | msgBox.setInformativeText("Do you want to save your changes?"); | ||
968 | msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); | ||
969 | msgBox.setDefaultButton(QMessageBox::Save); | ||
970 | int ret = msgBox.exec(); | ||
971 | if(ret == QMessageBox::Discard) | ||
972 | return true; | ||
973 | if(ret == QMessageBox::Cancel) | ||
974 | return false; | ||
975 | return SaveSoc(); | ||
976 | } | ||
977 | |||
978 | bool RegEdit::SaveSoc() | ||
979 | { | ||
980 | if(m_file_edit->text().size() == 0) | ||
981 | return SaveSocAs(); | ||
982 | else | ||
983 | return SaveSocFile(m_file_edit->text()); | ||
984 | } | ||
985 | |||
986 | bool RegEdit::GetFilename(QString& filename, bool save) | ||
987 | { | ||
988 | QFileDialog *fd = new QFileDialog(this); | ||
989 | if(save) | ||
990 | fd->setAcceptMode(QFileDialog::AcceptSave); | ||
991 | fd->setFilter("Description files (*.xml);;All files (*)"); | ||
992 | fd->setDirectory(Settings::Get()->value("loaddescdir", QDir::currentPath()).toString()); | ||
993 | if(fd->exec()) | ||
994 | { | ||
995 | QStringList filenames = fd->selectedFiles(); | ||
996 | filename = filenames[0]; | ||
997 | Settings::Get()->setValue("loaddescdir", fd->directory().absolutePath()); | ||
998 | return true; | ||
999 | } | ||
1000 | else | ||
1001 | return false; | ||
1002 | } | ||
1003 | |||
1004 | bool RegEdit::SaveSocAs() | ||
1005 | { | ||
1006 | QString filename; | ||
1007 | if(!GetFilename(filename, true)) | ||
1008 | return false; | ||
1009 | m_file_edit->setText(filename); | ||
1010 | return SaveSocFile(filename); | ||
1011 | } | ||
1012 | |||
1013 | void RegEdit::OnOpen() | ||
1014 | { | ||
1015 | if(!CloseSoc()) | ||
1016 | return; | ||
1017 | QString filename; | ||
1018 | if(!GetFilename(filename, false)) | ||
1019 | return; | ||
1020 | LoadSocFile(filename); | ||
1021 | } | ||
1022 | |||
1023 | void RegEdit::OnNew() | ||
1024 | { | ||
1025 | if(!CloseSoc()) | ||
1026 | return; | ||
1027 | m_cur_socfile = SocFile(); | ||
1028 | m_file_edit->setText(""); | ||
1029 | SetModified(false, false); | ||
1030 | UpdateSocFile(); | ||
1031 | } | ||
1032 | |||
1033 | bool RegEdit::SaveSocFile(const QString& filename) | ||
1034 | { | ||
1035 | soc_desc_normalize(m_cur_socfile.GetSoc()); | ||
1036 | if(!soc_desc_produce_xml(filename.toStdString(), m_cur_socfile.GetSoc())) | ||
1037 | { | ||
1038 | QMessageBox::warning(this, "The description was not saved", | ||
1039 | "There was an error when saving the file"); | ||
1040 | return false; | ||
1041 | } | ||
1042 | m_soc_tree->clear(); | ||
1043 | FillSocTree(); | ||
1044 | SetModified(false, false); | ||
1045 | return true; | ||
1046 | } | ||
1047 | |||
1048 | void RegEdit::LoadSocFile(const QString& filename) | ||
1049 | { | ||
1050 | m_cur_socfile = SocFile(filename); | ||
1051 | if(!m_cur_socfile.IsValid()) | ||
1052 | { | ||
1053 | QMessageBox::warning(this, "The description was not loaded", | ||
1054 | "There was an error when loading the file"); | ||
1055 | return; | ||
1056 | } | ||
1057 | m_file_edit->setText(filename); | ||
1058 | SetModified(false, false); | ||
1059 | UpdateSocFile(); | ||
1060 | } | ||
1061 | |||
1062 | void RegEdit::CreateNewFieldItem(QTreeWidgetItem *_parent) | ||
1063 | { | ||
1064 | RegTreeItem *parent = dynamic_cast< RegTreeItem* >(_parent); | ||
1065 | NewFieldTreeItem *newdev_item = new NewFieldTreeItem("New field...", parent->GetRef()); | ||
1066 | MakeItalic(newdev_item, true); | ||
1067 | newdev_item->setIcon(0, QIcon::fromTheme("list-add")); | ||
1068 | parent->addChild(newdev_item); | ||
1069 | } | ||
1070 | |||
1071 | void RegEdit::FillRegTreeItem(QTreeWidgetItem *_item) | ||
1072 | { | ||
1073 | RegTreeItem *item = dynamic_cast< RegTreeItem* >(_item); | ||
1074 | const soc_reg_t& reg = item->GetRef().GetReg(); | ||
1075 | for(size_t i = 0; i < reg.field.size(); i++) | ||
1076 | { | ||
1077 | const soc_reg_field_t& field = reg.field[i]; | ||
1078 | FieldTreeItem *field_item = new FieldTreeItem(QString::fromStdString(field.name), | ||
1079 | SocFieldRef(item->GetRef(), i)); | ||
1080 | FixupEmptyItem(field_item); | ||
1081 | item->addChild(field_item); | ||
1082 | } | ||
1083 | CreateNewFieldItem(item); | ||
1084 | } | ||
1085 | |||
1086 | void RegEdit::CreateNewRegisterItem(QTreeWidgetItem *_parent) | ||
1087 | { | ||
1088 | DevTreeItem *parent = dynamic_cast< DevTreeItem* >(_parent); | ||
1089 | NewRegTreeItem *newdev_item = new NewRegTreeItem("New register...", parent->GetRef()); | ||
1090 | MakeItalic(newdev_item, true); | ||
1091 | newdev_item->setIcon(0, QIcon::fromTheme("list-add")); | ||
1092 | parent->addChild(newdev_item); | ||
1093 | } | ||
1094 | |||
1095 | void RegEdit::FillDevTreeItem(QTreeWidgetItem *_item) | ||
1096 | { | ||
1097 | DevTreeItem *item = dynamic_cast< DevTreeItem* >(_item); | ||
1098 | const soc_dev_t& dev = item->GetRef().GetDev(); | ||
1099 | for(size_t i = 0; i < dev.reg.size(); i++) | ||
1100 | { | ||
1101 | const soc_reg_t& reg = dev.reg[i]; | ||
1102 | RegTreeItem *reg_item = new RegTreeItem(QString::fromStdString(reg.name), | ||
1103 | SocRegRef(item->GetRef(), i, -1)); | ||
1104 | FixupEmptyItem(reg_item); | ||
1105 | FillRegTreeItem(reg_item); | ||
1106 | item->addChild(reg_item); | ||
1107 | } | ||
1108 | CreateNewRegisterItem(item); | ||
1109 | } | ||
1110 | |||
1111 | void RegEdit::CreateNewDeviceItem(QTreeWidgetItem *_parent) | ||
1112 | { | ||
1113 | SocTreeItem *parent = dynamic_cast< SocTreeItem* >(_parent); | ||
1114 | NewDevTreeItem *newdev_item = new NewDevTreeItem("New device...", parent->GetRef()); | ||
1115 | MakeItalic(newdev_item, true); | ||
1116 | newdev_item->setIcon(0, QIcon::fromTheme("list-add")); | ||
1117 | parent->addChild(newdev_item); | ||
1118 | } | ||
1119 | |||
1120 | void RegEdit::FillSocTreeItem(QTreeWidgetItem *_item) | ||
1121 | { | ||
1122 | SocTreeItem *item = dynamic_cast< SocTreeItem* >(_item); | ||
1123 | const soc_t& soc = item->GetRef().GetSoc(); | ||
1124 | for(size_t i = 0; i < soc.dev.size(); i++) | ||
1125 | { | ||
1126 | const soc_dev_t& reg = soc.dev[i]; | ||
1127 | DevTreeItem *dev_item = new DevTreeItem(QString::fromStdString(reg.name), | ||
1128 | SocDevRef(item->GetRef(), i, -1)); | ||
1129 | FixupEmptyItem(dev_item); | ||
1130 | FillDevTreeItem(dev_item); | ||
1131 | item->addChild(dev_item); | ||
1132 | } | ||
1133 | CreateNewDeviceItem(item); | ||
1134 | } | ||
1135 | |||
1136 | void RegEdit::FillSocTree() | ||
1137 | { | ||
1138 | SocRef ref = m_cur_socfile.GetSocRef(); | ||
1139 | SocTreeItem *soc_item = new SocTreeItem( | ||
1140 | QString::fromStdString(ref.GetSoc().name), ref); | ||
1141 | FixupEmptyItem(soc_item); | ||
1142 | FillSocTreeItem(soc_item); | ||
1143 | m_soc_tree->addTopLevelItem(soc_item); | ||
1144 | soc_item->setExpanded(true); | ||
1145 | } | ||
1146 | |||
1147 | void RegEdit::MakeItalic(QTreeWidgetItem *item, bool it) | ||
1148 | { | ||
1149 | QFont font = item->font(0); | ||
1150 | font.setItalic(it); | ||
1151 | item->setFont(0, font); | ||
1152 | } | ||
1153 | |||
1154 | void RegEdit::FixupEmptyItem(QTreeWidgetItem *item) | ||
1155 | { | ||
1156 | if(item->text(0).size() == 0) | ||
1157 | { | ||
1158 | item->setIcon(0, QIcon::fromTheme("dialog-error")); | ||
1159 | MakeItalic(item, true); | ||
1160 | item->setText(0, "Unnamed"); | ||
1161 | } | ||
1162 | else | ||
1163 | { | ||
1164 | item->setIcon(0, QIcon::fromTheme("cpu")); | ||
1165 | MakeItalic(item, false); | ||
1166 | } | ||
1167 | } | ||
1168 | |||
1169 | void RegEdit::UpdateSocFile() | ||
1170 | { | ||
1171 | m_soc_tree->clear(); | ||
1172 | FillSocTree(); | ||
1173 | SetPanel(new EmptyEditPanel(this)); | ||
1174 | } | ||
1175 | |||
1176 | void RegEdit::SetPanel(QWidget *panel) | ||
1177 | { | ||
1178 | delete m_right_panel; | ||
1179 | m_right_panel = panel; | ||
1180 | connect(m_right_panel, SIGNAL(OnModified(bool)), this, SLOT(OnSocModified(bool))); | ||
1181 | m_splitter->addWidget(m_right_panel); | ||
1182 | m_splitter->setStretchFactor(1, 2); | ||
1183 | } | ||
1184 | |||
1185 | void RegEdit::SetModified(bool add, bool mod) | ||
1186 | { | ||
1187 | m_modified = add ? (m_modified || mod) : mod; | ||
1188 | emit OnModified(mod); | ||
1189 | } | ||
1190 | |||
1191 | void RegEdit::OnSocModified(bool modified) | ||
1192 | { | ||
1193 | // we might need to update the name in the tree | ||
1194 | UpdateName(m_soc_tree->currentItem()); | ||
1195 | if(modified) | ||
1196 | SetModified(true, true); | ||
1197 | } | ||
1198 | |||
1199 | void RegEdit::DisplaySoc(SocRef ref) | ||
1200 | { | ||
1201 | SetPanel(new SocEditPanel(ref, this)); | ||
1202 | } | ||
1203 | |||
1204 | void RegEdit::DisplayDev(SocDevRef ref) | ||
1205 | { | ||
1206 | SetPanel(new DevEditPanel(ref, this)); | ||
1207 | } | ||
1208 | |||
1209 | void RegEdit::DisplayReg(SocRegRef ref) | ||
1210 | { | ||
1211 | SetPanel(new RegEditPanel(ref, this)); | ||
1212 | } | ||
1213 | |||
1214 | void RegEdit::DisplayField(SocFieldRef ref) | ||
1215 | { | ||
1216 | SetPanel(new FieldEditPanel(ref, this)); | ||
1217 | } | ||
1218 | |||
1219 | void RegEdit::UpdateName(QTreeWidgetItem *current) | ||
1220 | { | ||
1221 | if(current == 0) | ||
1222 | return; | ||
1223 | if(current->type() == SocTreeSocType) | ||
1224 | { | ||
1225 | SocTreeItem *item = dynamic_cast< SocTreeItem * >(current); | ||
1226 | item->setText(0, QString::fromStdString(item->GetRef().GetSoc().name)); | ||
1227 | } | ||
1228 | else if(current->type() == SocTreeDevType) | ||
1229 | { | ||
1230 | DevTreeItem *item = dynamic_cast< DevTreeItem * >(current); | ||
1231 | item->setText(0, QString::fromStdString(item->GetRef().GetDev().name)); | ||
1232 | } | ||
1233 | else if(current->type() == SocTreeRegType) | ||
1234 | { | ||
1235 | RegTreeItem *item = dynamic_cast< RegTreeItem * >(current); | ||
1236 | item->setText(0, QString::fromStdString(item->GetRef().GetReg().name)); | ||
1237 | } | ||
1238 | else if(current->type() == SocTreeFieldType) | ||
1239 | { | ||
1240 | FieldTreeItem *item = dynamic_cast< FieldTreeItem * >(current); | ||
1241 | item->setText(0, QString::fromStdString(item->GetRef().GetField().name)); | ||
1242 | } | ||
1243 | FixupEmptyItem(current); | ||
1244 | } | ||
1245 | |||
1246 | void RegEdit::OnSocItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) | ||
1247 | { | ||
1248 | Q_UNUSED(previous); | ||
1249 | if(current == 0) | ||
1250 | return; | ||
1251 | if(current->type() == SocTreeSocType) | ||
1252 | { | ||
1253 | SocTreeItem *item = dynamic_cast< SocTreeItem * >(current); | ||
1254 | DisplaySoc(item->GetRef()); | ||
1255 | } | ||
1256 | else if(current->type() == SocTreeDevType) | ||
1257 | { | ||
1258 | DevTreeItem *item = dynamic_cast< DevTreeItem * >(current); | ||
1259 | DisplayDev(item->GetRef()); | ||
1260 | } | ||
1261 | else if(current->type() == SocTreeRegType) | ||
1262 | { | ||
1263 | RegTreeItem *item = dynamic_cast< RegTreeItem * >(current); | ||
1264 | DisplayReg(item->GetRef()); | ||
1265 | } | ||
1266 | else if(current->type() == SocTreeFieldType) | ||
1267 | { | ||
1268 | FieldTreeItem *item = dynamic_cast< FieldTreeItem * >(current); | ||
1269 | DisplayField(item->GetRef()); | ||
1270 | } | ||
1271 | } | ||
1272 | |||
1273 | void RegEdit::OnSocItemActivated(QTreeWidgetItem *current, int column) | ||
1274 | { | ||
1275 | Q_UNUSED(column); | ||
1276 | if(current == 0) | ||
1277 | return; | ||
1278 | if(current->type() == SocTreeNewDevType) | ||
1279 | AddDevice(current); | ||
1280 | else if(current->type() == SocTreeNewRegType) | ||
1281 | AddRegister(current); | ||
1282 | else if(current->type() == SocTreeNewFieldType) | ||
1283 | AddField(current); | ||
1284 | } | ||
1285 | |||
1286 | void RegEdit::AddDevice(QTreeWidgetItem *_item) | ||
1287 | { | ||
1288 | NewDevTreeItem *item = dynamic_cast< NewDevTreeItem * >(_item); | ||
1289 | item->GetRef().GetSoc().dev.push_back(soc_dev_t()); | ||
1290 | DevTreeItem *dev_item = new DevTreeItem("", | ||
1291 | SocDevRef(item->GetRef(), item->GetRef().GetSoc().dev.size() - 1, -1)); | ||
1292 | FixupEmptyItem(dev_item); | ||
1293 | item->parent()->insertChild(item->parent()->indexOfChild(item), dev_item); | ||
1294 | CreateNewRegisterItem(dev_item); | ||
1295 | m_soc_tree->setCurrentItem(dev_item); | ||
1296 | } | ||
1297 | |||
1298 | void RegEdit::AddRegister(QTreeWidgetItem *_item) | ||
1299 | { | ||
1300 | NewRegTreeItem *item = dynamic_cast< NewRegTreeItem * >(_item); | ||
1301 | item->GetRef().GetDev().reg.push_back(soc_reg_t()); | ||
1302 | RegTreeItem *reg_item = new RegTreeItem("", | ||
1303 | SocRegRef(item->GetRef(), item->GetRef().GetDev().reg.size() - 1, -1)); | ||
1304 | FixupEmptyItem(reg_item); | ||
1305 | item->parent()->insertChild(item->parent()->indexOfChild(item), reg_item); | ||
1306 | CreateNewFieldItem(reg_item); | ||
1307 | m_soc_tree->setCurrentItem(reg_item); | ||
1308 | } | ||
1309 | |||
1310 | void RegEdit::AddField(QTreeWidgetItem *_item) | ||
1311 | { | ||
1312 | NewFieldTreeItem *item = dynamic_cast< NewFieldTreeItem * >(_item); | ||
1313 | item->GetRef().GetReg().field.push_back(soc_reg_field_t()); | ||
1314 | FieldTreeItem *field_item = new FieldTreeItem("", | ||
1315 | SocFieldRef(item->GetRef(), item->GetRef().GetReg().field.size() - 1)); | ||
1316 | FixupEmptyItem(field_item); | ||
1317 | item->parent()->insertChild(item->parent()->indexOfChild(item), field_item); | ||
1318 | m_soc_tree->setCurrentItem(field_item); | ||
1319 | } | ||
1320 | |||
1321 | bool RegEdit::Quit() | ||
1322 | { | ||
1323 | return CloseSoc(); | ||
1324 | } \ No newline at end of file | ||