diff options
Diffstat (limited to 'utils/regtools/qeditor/regtab.cpp')
-rw-r--r-- | utils/regtools/qeditor/regtab.cpp | 534 |
1 files changed, 126 insertions, 408 deletions
diff --git a/utils/regtools/qeditor/regtab.cpp b/utils/regtools/qeditor/regtab.cpp index 4cd4e7b283..568d859c0e 100644 --- a/utils/regtools/qeditor/regtab.cpp +++ b/utils/regtools/qeditor/regtab.cpp | |||
@@ -1,406 +1,75 @@ | |||
1 | #include "regtab.h" | 1 | #include "regtab.h" |
2 | 2 | ||
3 | #include <QSplitter> | ||
4 | #include <QVBoxLayout> | ||
5 | #include <QAbstractListModel> | ||
6 | #include <QMessageBox> | ||
7 | #include <QSizePolicy> | 3 | #include <QSizePolicy> |
8 | #include <QHBoxLayout> | ||
9 | #include <QStringBuilder> | 4 | #include <QStringBuilder> |
10 | #include <QLabel> | ||
11 | #include <QGridLayout> | ||
12 | #include <QTableWidget> | ||
13 | #include <QHeaderView> | ||
14 | #include <QFileDialog> | 5 | #include <QFileDialog> |
15 | #include <QDebug> | 6 | #include <QDebug> |
16 | #include <QStyle> | 7 | #include <QStyle> |
17 | #include "backend.h" | 8 | #include "backend.h" |
18 | #include "analyser.h" | 9 | #include "analyser.h" |
10 | #include "regdisplaypanel.h" | ||
19 | 11 | ||
20 | /** | 12 | namespace |
21 | * SocFieldValidator | ||
22 | */ | ||
23 | |||
24 | SocFieldValidator::SocFieldValidator(QObject *parent) | ||
25 | :QValidator(parent) | ||
26 | { | ||
27 | m_field.first_bit = 0; | ||
28 | m_field.last_bit = 31; | ||
29 | } | ||
30 | |||
31 | SocFieldValidator::SocFieldValidator(const soc_reg_field_t& field, QObject *parent) | ||
32 | :QValidator(parent), m_field(field) | ||
33 | { | ||
34 | } | ||
35 | |||
36 | void SocFieldValidator::fixup(QString& input) const | ||
37 | { | ||
38 | input = input.trimmed(); | ||
39 | } | ||
40 | |||
41 | QValidator::State SocFieldValidator::validate(QString& input, int& pos) const | ||
42 | { | ||
43 | (void) pos; | ||
44 | soc_word_t val; | ||
45 | State state = parse(input, val); | ||
46 | return state; | ||
47 | } | ||
48 | |||
49 | QValidator::State SocFieldValidator::parse(const QString& input, soc_word_t& val) const | ||
50 | { | ||
51 | // the empty string is all alwats intermediate | ||
52 | if(input.size() == 0) | ||
53 | return Intermediate; | ||
54 | // first check named values | ||
55 | State state = Invalid; | ||
56 | foreach(const soc_reg_field_value_t& value, m_field.value) | ||
57 | { | ||
58 | QString name = QString::fromLocal8Bit(value.name.c_str()); | ||
59 | // cannot be a substring if too long or empty | ||
60 | if(input.size() > name.size()) | ||
61 | continue; | ||
62 | // check equal string | ||
63 | if(input == name) | ||
64 | { | ||
65 | state = Acceptable; | ||
66 | val = value.value; | ||
67 | break; | ||
68 | } | ||
69 | // check substring | ||
70 | if(name.startsWith(input)) | ||
71 | state = Intermediate; | ||
72 | } | ||
73 | // early return for exact match | ||
74 | if(state == Acceptable) | ||
75 | return state; | ||
76 | // do a few special cases for convenience | ||
77 | if(input.compare("0x", Qt::CaseInsensitive) == 0 || | ||
78 | input.compare("0b", Qt::CaseInsensitive) == 0) | ||
79 | return Intermediate; | ||
80 | // try by parsing | ||
81 | unsigned basis, pos; | ||
82 | if(input.size() >= 2 && input.startsWith("0x", Qt::CaseInsensitive)) | ||
83 | { | ||
84 | basis = 16; | ||
85 | pos = 2; | ||
86 | } | ||
87 | else if(input.size() >= 2 && input.startsWith("0b", Qt::CaseInsensitive)) | ||
88 | { | ||
89 | basis = 2; | ||
90 | pos = 2; | ||
91 | } | ||
92 | else if(input.size() >= 2 && input.startsWith("0")) | ||
93 | { | ||
94 | basis = 8; | ||
95 | pos = 1; | ||
96 | } | ||
97 | else | ||
98 | { | ||
99 | basis = 10; | ||
100 | pos = 0; | ||
101 | } | ||
102 | bool ok = false; | ||
103 | unsigned long v = input.mid(pos).toULong(&ok, basis); | ||
104 | // if not ok, return result of name parsing | ||
105 | if(!ok) | ||
106 | return state; | ||
107 | // if ok, check if it fits in the number of bits | ||
108 | unsigned nr_bits = m_field.last_bit - m_field.first_bit + 1; | ||
109 | unsigned long max = nr_bits == 32 ? 0xffffffff : (1 << nr_bits) - 1; | ||
110 | if(v <= max) | ||
111 | { | ||
112 | val = v; | ||
113 | return Acceptable; | ||
114 | } | ||
115 | |||
116 | return state; | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * RegLineEdit | ||
121 | */ | ||
122 | RegLineEdit::RegLineEdit(QWidget *parent) | ||
123 | :QWidget(parent) | ||
124 | { | 13 | { |
125 | m_layout = new QHBoxLayout(this); | ||
126 | m_button = new QToolButton(this); | ||
127 | m_button->setCursor(Qt::ArrowCursor); | ||
128 | m_button->setStyleSheet("QToolButton { font-weight: bold; color: white; background: black; }"); | ||
129 | m_button->setPopupMode(QToolButton::InstantPopup); | ||
130 | m_edit = new QLineEdit(this); | ||
131 | m_layout->addWidget(m_button); | ||
132 | m_layout->addWidget(m_edit); | ||
133 | m_menu = new QMenu(this); | ||
134 | connect(m_menu->addAction("Write"), SIGNAL(triggered()), this, SLOT(OnWriteAct())); | ||
135 | connect(m_menu->addAction("Set"), SIGNAL(triggered()), this, SLOT(OnSetAct())); | ||
136 | connect(m_menu->addAction("Clear"), SIGNAL(triggered()), this, SLOT(OnClearAct())); | ||
137 | connect(m_menu->addAction("Toggle"), SIGNAL(triggered()), this, SLOT(OnToggleAct())); | ||
138 | EnableSCT(false); | ||
139 | SetReadOnly(false); | ||
140 | ShowMode(true); | ||
141 | SetMode(Write); | ||
142 | } | ||
143 | 14 | ||
144 | void RegLineEdit::SetReadOnly(bool ro) | 15 | enum |
145 | { | 16 | { |
146 | m_edit->setReadOnly(ro); | 17 | RegTreeDevType = QTreeWidgetItem::UserType, |
147 | m_readonly = ro; | 18 | RegTreeRegType |
148 | ShowMode(!ro); | 19 | }; |
149 | } | ||
150 | 20 | ||
151 | void RegLineEdit::EnableSCT(bool en) | 21 | class DevTreeItem : public QTreeWidgetItem |
152 | { | 22 | { |
153 | m_has_sct = en; | 23 | public: |
154 | if(!m_has_sct) | 24 | DevTreeItem(const QString& string, const SocDevRef& ref) |
155 | { | 25 | :QTreeWidgetItem(QStringList(string), RegTreeDevType), m_ref(ref) {} |
156 | m_button->setMenu(0); | ||
157 | SetMode(Write); | ||
158 | } | ||
159 | else | ||
160 | m_button->setMenu(m_menu); | ||
161 | } | ||
162 | |||
163 | RegLineEdit::~RegLineEdit() | ||
164 | { | ||
165 | } | ||
166 | 26 | ||
167 | QLineEdit *RegLineEdit::GetLineEdit() | 27 | const SocDevRef& GetRef() { return m_ref; } |
168 | { | 28 | private: |
169 | return m_edit; | 29 | SocDevRef m_ref; |
170 | } | 30 | }; |
171 | 31 | ||
172 | void RegLineEdit::ShowMode(bool show) | 32 | class RegTreeItem : public QTreeWidgetItem |
173 | { | 33 | { |
174 | if(show) | 34 | public: |
175 | m_button->show(); | 35 | RegTreeItem(const QString& string, const SocRegRef& ref) |
176 | else | 36 | :QTreeWidgetItem(QStringList(string), RegTreeRegType), m_ref(ref) {} |
177 | m_button->hide(); | ||
178 | } | ||
179 | 37 | ||
180 | void RegLineEdit::OnWriteAct() | 38 | const SocRegRef& GetRef() { return m_ref; } |
181 | { | 39 | private: |
182 | SetMode(Write); | 40 | SocRegRef m_ref; |
183 | } | 41 | }; |
184 | |||
185 | void RegLineEdit::OnSetAct() | ||
186 | { | ||
187 | SetMode(Set); | ||
188 | } | ||
189 | |||
190 | void RegLineEdit::OnClearAct() | ||
191 | { | ||
192 | SetMode(Clear); | ||
193 | } | ||
194 | |||
195 | void RegLineEdit::OnToggleAct() | ||
196 | { | ||
197 | SetMode(Toggle); | ||
198 | } | ||
199 | |||
200 | void RegLineEdit::SetMode(EditMode mode) | ||
201 | { | ||
202 | m_mode = mode; | ||
203 | switch(m_mode) | ||
204 | { | ||
205 | case Write: m_button->setText("WR"); break; | ||
206 | case Set: m_button->setText("SET"); break; | ||
207 | case Clear: m_button->setText("CLR"); break; | ||
208 | case Toggle: m_button->setText("TOG"); break; | ||
209 | default: break; | ||
210 | } | ||
211 | } | ||
212 | 42 | ||
213 | RegLineEdit::EditMode RegLineEdit::GetMode() | ||
214 | { | ||
215 | return m_mode; | ||
216 | } | 43 | } |
217 | 44 | ||
218 | /** | 45 | /** |
219 | * RegDisplayPanel | 46 | * EmptyRegTabPanel |
220 | */ | 47 | */ |
221 | 48 | EmptyRegTabPanel::EmptyRegTabPanel(QWidget *parent) | |
222 | RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const SocRegRef& reg_ref) | 49 | :QWidget(parent) |
223 | :QGroupBox(parent), m_io_backend(io_backend), m_reg(reg_ref) | ||
224 | { | 50 | { |
225 | bool read_only = m_io_backend->IsReadOnly(); | 51 | QVBoxLayout *l = new QVBoxLayout; |
226 | 52 | l->addStretch(); | |
227 | QVBoxLayout *right_layout = new QVBoxLayout; | 53 | setLayout(l); |
228 | |||
229 | const soc_dev_addr_t& dev_addr = m_reg.GetDevAddr(); | ||
230 | const soc_reg_t& reg = m_reg.GetReg(); | ||
231 | const soc_reg_addr_t& reg_addr = m_reg.GetRegAddr(); | ||
232 | |||
233 | QString reg_name; | ||
234 | reg_name.sprintf("HW_%s_%s", dev_addr.name.c_str(), reg_addr.name.c_str()); | ||
235 | QStringList names; | ||
236 | QVector< soc_addr_t > addresses; | ||
237 | names.append(reg_name); | ||
238 | addresses.append(reg_addr.addr); | ||
239 | if(reg.flags & REG_HAS_SCT) | ||
240 | { | ||
241 | names.append(reg_name + "_SET"); | ||
242 | names.append(reg_name + "_CLR"); | ||
243 | names.append(reg_name + "_TOG"); | ||
244 | addresses.append(reg_addr.addr + 4); | ||
245 | addresses.append(reg_addr.addr + 8); | ||
246 | addresses.append(reg_addr.addr + 12); | ||
247 | } | ||
248 | |||
249 | QString str; | ||
250 | str += "<table align=left>"; | ||
251 | for(int i = 0; i < names.size(); i++) | ||
252 | str += "<tr><td><b>" + names[i] + "</b></td></tr>"; | ||
253 | str += "</table>"; | ||
254 | QLabel *label_names = new QLabel; | ||
255 | label_names->setTextFormat(Qt::RichText); | ||
256 | label_names->setText(str); | ||
257 | |||
258 | QString str_addr; | ||
259 | str_addr += "<table align=left>"; | ||
260 | for(int i = 0; i < names.size(); i++) | ||
261 | str_addr += "<tr><td><b>" + QString().sprintf("0x%03x", addresses[i]) + "</b></td></tr>"; | ||
262 | str_addr += "</table>"; | ||
263 | QLabel *label_addr = new QLabel; | ||
264 | label_addr->setTextFormat(Qt::RichText); | ||
265 | label_addr->setText(str_addr); | ||
266 | |||
267 | QHBoxLayout *top_layout = new QHBoxLayout; | ||
268 | top_layout->addStretch(); | ||
269 | top_layout->addWidget(label_names); | ||
270 | top_layout->addWidget(label_addr); | ||
271 | top_layout->addStretch(); | ||
272 | |||
273 | soc_word_t value; | ||
274 | BackendHelper helper(m_io_backend, m_reg); | ||
275 | bool has_value = helper.ReadRegister(dev_addr.name.c_str(), reg_addr.name.c_str(), value); | ||
276 | |||
277 | QHBoxLayout *raw_val_layout = 0; | ||
278 | if(has_value) | ||
279 | { | ||
280 | QLabel *raw_val_name = new QLabel; | ||
281 | raw_val_name->setText("Raw value:"); | ||
282 | m_raw_val_edit = new RegLineEdit; | ||
283 | m_raw_val_edit->SetReadOnly(read_only); | ||
284 | m_raw_val_edit->GetLineEdit()->setText(QString().sprintf("0x%08x", value)); | ||
285 | m_raw_val_edit->GetLineEdit()->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); | ||
286 | m_raw_val_edit->GetLineEdit()->setValidator(new SocFieldValidator(m_raw_val_edit)); | ||
287 | m_raw_val_edit->EnableSCT(!!(reg.flags & REG_HAS_SCT)); | ||
288 | connect(m_raw_val_edit->GetLineEdit(), SIGNAL(returnPressed()), this, SLOT(OnRawRegValueReturnPressed())); | ||
289 | raw_val_layout = new QHBoxLayout; | ||
290 | raw_val_layout->addStretch(); | ||
291 | raw_val_layout->addWidget(raw_val_name); | ||
292 | raw_val_layout->addWidget(m_raw_val_edit); | ||
293 | raw_val_layout->addStretch(); | ||
294 | } | ||
295 | else | ||
296 | m_raw_val_edit = 0; | ||
297 | |||
298 | QTableWidget *value_table = new QTableWidget; | ||
299 | value_table->setRowCount(reg.field.size()); | ||
300 | value_table->setColumnCount(4); | ||
301 | int row = 0; | ||
302 | foreach(const soc_reg_field_t& field, reg.field) | ||
303 | { | ||
304 | QString bits_str; | ||
305 | if(field.first_bit == field.last_bit) | ||
306 | bits_str.sprintf("%d", field.first_bit); | ||
307 | else | ||
308 | bits_str.sprintf("%d:%d", field.last_bit, field.first_bit); | ||
309 | QTableWidgetItem *item = new QTableWidgetItem(bits_str); | ||
310 | item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | ||
311 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
312 | value_table->setItem(row, 0, item); | ||
313 | item = new QTableWidgetItem(QString(field.name.c_str())); | ||
314 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
315 | value_table->setItem(row, 1, item); | ||
316 | item = new QTableWidgetItem(); | ||
317 | if(has_value) | ||
318 | { | ||
319 | soc_word_t v = (value & field.bitmask()) >> field.first_bit; | ||
320 | QString value_name; | ||
321 | foreach(const soc_reg_field_value_t& rval, field.value) | ||
322 | if(v == rval.value) | ||
323 | value_name = rval.name.c_str(); | ||
324 | const char *fmt = "%lu"; | ||
325 | // heuristic | ||
326 | if((field.last_bit - field.first_bit + 1) > 16) | ||
327 | fmt = "0x%lx"; | ||
328 | item->setText(QString().sprintf(fmt, (unsigned long)v)); | ||
329 | item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | ||
330 | |||
331 | if(value_name.size() != 0) | ||
332 | { | ||
333 | QTableWidgetItem *t = new QTableWidgetItem(value_name); | ||
334 | t->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | ||
335 | t->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
336 | value_table->setItem(row, 3, t); | ||
337 | } | ||
338 | } | ||
339 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
340 | value_table->setItem(row, 2, item); | ||
341 | row++; | ||
342 | } | ||
343 | value_table->setHorizontalHeaderItem(0, new QTableWidgetItem("Bits")); | ||
344 | value_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name")); | ||
345 | value_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Value")); | ||
346 | value_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Meaning")); | ||
347 | value_table->verticalHeader()->setVisible(false); | ||
348 | value_table->resizeColumnsToContents(); | ||
349 | value_table->horizontalHeader()->setStretchLastSection(true); | ||
350 | value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
351 | |||
352 | right_layout->addLayout(top_layout); | ||
353 | if(raw_val_layout) | ||
354 | right_layout->addLayout(raw_val_layout); | ||
355 | //right_layout->addWidget(bits_label); | ||
356 | right_layout->addWidget(value_table); | ||
357 | //right_layout->addStretch(); | ||
358 | |||
359 | setTitle("Register Description"); | ||
360 | setLayout(right_layout); | ||
361 | AllowWrite(false); | ||
362 | } | 54 | } |
363 | 55 | ||
364 | void RegDisplayPanel::AllowWrite(bool en) | 56 | void EmptyRegTabPanel::AllowWrite(bool en) |
365 | { | 57 | { |
366 | m_allow_write = en; | 58 | Q_UNUSED(en); |
367 | if(m_raw_val_edit) | ||
368 | m_raw_val_edit->SetReadOnly(m_io_backend->IsReadOnly() || !m_allow_write); | ||
369 | } | 59 | } |
370 | 60 | ||
371 | IoBackend::WriteMode RegDisplayPanel::EditModeToWriteMode(RegLineEdit::EditMode mode) | 61 | QWidget *EmptyRegTabPanel::GetWidget() |
372 | { | 62 | { |
373 | switch(mode) | 63 | return this; |
374 | { | ||
375 | case RegLineEdit::Write: return IoBackend::Write; | ||
376 | case RegLineEdit::Set: return IoBackend::Set; | ||
377 | case RegLineEdit::Clear: return IoBackend::Clear; | ||
378 | case RegLineEdit::Toggle: return IoBackend::Toggle; | ||
379 | default: return IoBackend::Write; | ||
380 | } | ||
381 | } | 64 | } |
382 | 65 | ||
383 | void RegDisplayPanel::OnRawRegValueReturnPressed() | ||
384 | { | ||
385 | soc_word_t val; | ||
386 | QLineEdit *edit = m_raw_val_edit->GetLineEdit(); | ||
387 | const SocFieldValidator *validator = dynamic_cast< const SocFieldValidator *>(edit->validator()); | ||
388 | QValidator::State state = validator->parse(edit->text(), val); | ||
389 | if(state != QValidator::Acceptable) | ||
390 | return; | ||
391 | IoBackend::WriteMode mode = EditModeToWriteMode(m_raw_val_edit->GetMode()); | ||
392 | BackendHelper helper(m_io_backend, m_reg); | ||
393 | helper.WriteRegister(m_reg.GetDevAddr().name.c_str(), m_reg.GetRegAddr().name.c_str(), | ||
394 | val, mode); | ||
395 | // FIXME: we should notify the UI to read value back because it has changed | ||
396 | } | ||
397 | 66 | ||
398 | /** | 67 | /** |
399 | * RegTab | 68 | * RegTab |
400 | */ | 69 | */ |
401 | 70 | ||
402 | RegTab::RegTab(Backend *backend) | 71 | RegTab::RegTab(Backend *backend, QWidget *parent) |
403 | :m_backend(backend) | 72 | :QSplitter(parent), m_backend(backend) |
404 | { | 73 | { |
405 | QWidget *left = new QWidget; | 74 | QWidget *left = new QWidget; |
406 | this->addWidget(left); | 75 | this->addWidget(left); |
@@ -432,7 +101,7 @@ RegTab::RegTab(Backend *backend) | |||
432 | QGroupBox *data_sel_group = new QGroupBox("Data selection"); | 101 | QGroupBox *data_sel_group = new QGroupBox("Data selection"); |
433 | QHBoxLayout *data_sel_layout = new QHBoxLayout; | 102 | QHBoxLayout *data_sel_layout = new QHBoxLayout; |
434 | m_data_selector = new QComboBox; | 103 | m_data_selector = new QComboBox; |
435 | m_data_selector->addItem(QIcon::fromTheme("face-sad"), "None", QVariant(DataSelNothing)); | 104 | m_data_selector->addItem(QIcon::fromTheme("text-x-generic"), "Explore", QVariant(DataSelNothing)); |
436 | m_data_selector->addItem(QIcon::fromTheme("document-open"), "File...", QVariant(DataSelFile)); | 105 | m_data_selector->addItem(QIcon::fromTheme("document-open"), "File...", QVariant(DataSelFile)); |
437 | #ifdef HAVE_HWSTUB | 106 | #ifdef HAVE_HWSTUB |
438 | m_data_selector->addItem(QIcon::fromTheme("multimedia-player"), "Device...", QVariant(DataSelDevice)); | 107 | m_data_selector->addItem(QIcon::fromTheme("multimedia-player"), "Device...", QVariant(DataSelDevice)); |
@@ -446,7 +115,8 @@ RegTab::RegTab(Backend *backend) | |||
446 | data_sel_reload->setIcon(QIcon::fromTheme("view-refresh")); | 115 | data_sel_reload->setIcon(QIcon::fromTheme("view-refresh")); |
447 | data_sel_reload->setToolTip("Reload data"); | 116 | data_sel_reload->setToolTip("Reload data"); |
448 | data_sel_layout->addWidget(m_data_selector); | 117 | data_sel_layout->addWidget(m_data_selector); |
449 | data_sel_layout->addWidget(m_data_sel_edit); | 118 | data_sel_layout->addWidget(m_data_sel_edit, 1); |
119 | data_sel_layout->addStretch(0); | ||
450 | #ifdef HAVE_HWSTUB | 120 | #ifdef HAVE_HWSTUB |
451 | m_dev_selector = new QComboBox; | 121 | m_dev_selector = new QComboBox; |
452 | data_sel_layout->addWidget(m_dev_selector, 1); | 122 | data_sel_layout->addWidget(m_dev_selector, 1); |
@@ -457,12 +127,9 @@ RegTab::RegTab(Backend *backend) | |||
457 | data_sel_group->setLayout(data_sel_layout); | 127 | data_sel_group->setLayout(data_sel_layout); |
458 | m_data_soc_label->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); | 128 | m_data_soc_label->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); |
459 | 129 | ||
460 | m_right_panel->addWidget(data_sel_group); | 130 | m_right_panel->addWidget(data_sel_group, 0); |
461 | m_right_content = new QWidget; | 131 | m_right_content = 0; |
462 | QVBoxLayout *l = new QVBoxLayout; | 132 | SetPanel(new EmptyRegTabPanel); |
463 | l->addStretch(); | ||
464 | m_right_content->setLayout(l); | ||
465 | m_right_panel->addWidget(m_right_content); | ||
466 | QWidget *w = new QWidget; | 133 | QWidget *w = new QWidget; |
467 | w->setLayout(m_right_panel); | 134 | w->setLayout(m_right_panel); |
468 | this->addWidget(w); | 135 | this->addWidget(w); |
@@ -470,21 +137,17 @@ RegTab::RegTab(Backend *backend) | |||
470 | 137 | ||
471 | m_io_backend = m_backend->CreateDummyIoBackend(); | 138 | m_io_backend = m_backend->CreateDummyIoBackend(); |
472 | 139 | ||
473 | connect(m_soc_selector, SIGNAL(currentIndexChanged(const QString&)), | 140 | connect(m_soc_selector, SIGNAL(currentIndexChanged(int)), |
474 | this, SLOT(OnSocChanged(const QString&))); | 141 | this, SLOT(OnSocChanged(int))); |
475 | connect(m_backend, SIGNAL(OnSocListChanged()), this, SLOT(OnSocListChanged())); | 142 | connect(m_backend, SIGNAL(OnSocListChanged()), this, SLOT(OnSocListChanged())); |
476 | connect(m_reg_tree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), | 143 | connect(m_reg_tree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), |
477 | this, SLOT(OnRegItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); | 144 | this, SLOT(OnRegItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); |
478 | connect(m_reg_tree, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, | ||
479 | SLOT(OnRegItemClicked(QTreeWidgetItem *, int))); | ||
480 | connect(m_data_selector, SIGNAL(activated(int)), | 145 | connect(m_data_selector, SIGNAL(activated(int)), |
481 | this, SLOT(OnDataSelChanged(int))); | 146 | this, SLOT(OnDataSelChanged(int))); |
482 | connect(m_data_soc_label, SIGNAL(linkActivated(const QString&)), this, | 147 | connect(m_data_soc_label, SIGNAL(linkActivated(const QString&)), this, |
483 | SLOT(OnDataSocActivated(const QString&))); | 148 | SLOT(OnDataSocActivated(const QString&))); |
484 | connect(m_analysers_list, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), | 149 | connect(m_analysers_list, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), |
485 | this, SLOT(OnAnalyserChanged(QListWidgetItem *, QListWidgetItem *))); | 150 | this, SLOT(OnAnalyserChanged(QListWidgetItem *, QListWidgetItem *))); |
486 | connect(m_analysers_list, SIGNAL(itemClicked(QListWidgetItem *)), this, | ||
487 | SLOT(OnAnalyserClicked(QListWidgetItem *))); | ||
488 | #ifdef HAVE_HWSTUB | 151 | #ifdef HAVE_HWSTUB |
489 | connect(m_dev_selector, SIGNAL(currentIndexChanged(int)), | 152 | connect(m_dev_selector, SIGNAL(currentIndexChanged(int)), |
490 | this, SLOT(OnDevChanged(int))); | 153 | this, SLOT(OnDevChanged(int))); |
@@ -492,14 +155,22 @@ RegTab::RegTab(Backend *backend) | |||
492 | connect(m_readonly_check, SIGNAL(clicked(bool)), this, SLOT(OnReadOnlyClicked(bool))); | 155 | connect(m_readonly_check, SIGNAL(clicked(bool)), this, SLOT(OnReadOnlyClicked(bool))); |
493 | 156 | ||
494 | OnSocListChanged(); | 157 | OnSocListChanged(); |
495 | OnDataSelChanged(DataSelNothing); | 158 | OnDataSelChanged(0); |
496 | } | 159 | } |
497 | 160 | ||
498 | RegTab::~RegTab() | 161 | RegTab::~RegTab() |
499 | { | 162 | { |
163 | #ifdef HAVE_HWSTUB | ||
164 | ClearDevList(); | ||
165 | #endif | ||
500 | delete m_io_backend; | 166 | delete m_io_backend; |
501 | } | 167 | } |
502 | 168 | ||
169 | bool RegTab::Quit() | ||
170 | { | ||
171 | return true; | ||
172 | } | ||
173 | |||
503 | void RegTab::SetDataSocName(const QString& socname) | 174 | void RegTab::SetDataSocName(const QString& socname) |
504 | { | 175 | { |
505 | if(socname.size() != 0) | 176 | if(socname.size() != 0) |
@@ -533,9 +204,10 @@ void RegTab::OnDataSelChanged(int index) | |||
533 | #ifdef HAVE_HWSTUB | 204 | #ifdef HAVE_HWSTUB |
534 | m_dev_selector->hide(); | 205 | m_dev_selector->hide(); |
535 | #endif | 206 | #endif |
207 | m_readonly_check->show(); | ||
536 | QFileDialog *fd = new QFileDialog(m_data_selector); | 208 | QFileDialog *fd = new QFileDialog(m_data_selector); |
537 | fd->setFilter("Textual files (*.txt);;All files (*)"); | 209 | fd->setFilter("Textual files (*.txt);;All files (*)"); |
538 | fd->setDirectory(Settings::Get()->value("regtab/loaddatadir", QDir::currentPath()).toString()); | 210 | fd->setDirectory(Settings::Get()->value("loaddatadir", QDir::currentPath()).toString()); |
539 | if(fd->exec()) | 211 | if(fd->exec()) |
540 | { | 212 | { |
541 | QStringList filenames = fd->selectedFiles(); | 213 | QStringList filenames = fd->selectedFiles(); |
@@ -545,13 +217,14 @@ void RegTab::OnDataSelChanged(int index) | |||
545 | SetDataSocName(m_io_backend->GetSocName()); | 217 | SetDataSocName(m_io_backend->GetSocName()); |
546 | OnDataSocActivated(m_io_backend->GetSocName()); | 218 | OnDataSocActivated(m_io_backend->GetSocName()); |
547 | } | 219 | } |
548 | Settings::Get()->setValue("regtab/loaddatadir", fd->directory().absolutePath()); | 220 | Settings::Get()->setValue("loaddatadir", fd->directory().absolutePath()); |
549 | SetReadOnlyIndicator(); | 221 | SetReadOnlyIndicator(); |
550 | } | 222 | } |
551 | #ifdef HAVE_HWSTUB | 223 | #ifdef HAVE_HWSTUB |
552 | else if(var == DataSelDevice) | 224 | else if(var == DataSelDevice) |
553 | { | 225 | { |
554 | m_data_sel_edit->hide(); | 226 | m_data_sel_edit->hide(); |
227 | m_readonly_check->show(); | ||
555 | m_dev_selector->show(); | 228 | m_dev_selector->show(); |
556 | OnDevListChanged(); | 229 | OnDevListChanged(); |
557 | } | 230 | } |
@@ -562,13 +235,31 @@ void RegTab::OnDataSelChanged(int index) | |||
562 | #ifdef HAVE_HWSTUB | 235 | #ifdef HAVE_HWSTUB |
563 | m_dev_selector->hide(); | 236 | m_dev_selector->hide(); |
564 | #endif | 237 | #endif |
238 | m_readonly_check->hide(); | ||
239 | |||
565 | delete m_io_backend; | 240 | delete m_io_backend; |
566 | m_io_backend = m_backend->CreateDummyIoBackend(); | 241 | m_io_backend = m_backend->CreateDummyIoBackend(); |
242 | m_readonly_check->setCheckState(Qt::Checked); | ||
567 | SetDataSocName(""); | 243 | SetDataSocName(""); |
244 | UpdateSocFilename(); | ||
568 | } | 245 | } |
569 | OnDataChanged(); | 246 | OnDataChanged(); |
570 | } | 247 | } |
571 | 248 | ||
249 | void RegTab::UpdateSocFilename() | ||
250 | { | ||
251 | int index = m_data_selector->currentIndex(); | ||
252 | if(index == -1) | ||
253 | return; | ||
254 | if(m_data_selector->itemData(index) != DataSelNothing) | ||
255 | return; | ||
256 | index = m_soc_selector->currentIndex(); | ||
257 | if(index == -1) | ||
258 | return; | ||
259 | SocRef ref = m_soc_selector->itemData(index).value< SocRef >(); | ||
260 | m_data_sel_edit->setText(ref.GetSocFile()->GetFilename()); | ||
261 | } | ||
262 | |||
572 | void RegTab::SetReadOnlyIndicator() | 263 | void RegTab::SetReadOnlyIndicator() |
573 | { | 264 | { |
574 | if(m_io_backend->IsReadOnly()) | 265 | if(m_io_backend->IsReadOnly()) |
@@ -582,23 +273,30 @@ void RegTab::OnDataChanged() | |||
582 | 273 | ||
583 | void RegTab::OnRegItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) | 274 | void RegTab::OnRegItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) |
584 | { | 275 | { |
585 | (void) previous; | 276 | Q_UNUSED(previous); |
586 | OnRegItemClicked(current, 0); | 277 | OnRegItemClicked(current, 0); |
587 | } | 278 | } |
588 | 279 | ||
589 | void RegTab::OnRegItemClicked(QTreeWidgetItem *current, int col) | 280 | void RegTab::OnRegItemClicked(QTreeWidgetItem *current, int col) |
590 | { | 281 | { |
591 | (void) col; | 282 | Q_UNUSED(col); |
592 | if(current == 0 || current->type() != RegTreeRegType) | 283 | if(current == 0) |
593 | return; | 284 | return; |
594 | RegTreeItem *item = dynamic_cast< RegTreeItem * >(current); | 285 | if(current->type() == RegTreeRegType) |
595 | 286 | { | |
596 | DisplayRegister(item->GetRef()); | 287 | RegTreeItem *item = dynamic_cast< RegTreeItem * >(current); |
288 | DisplayRegister(item->GetRef()); | ||
289 | } | ||
290 | else if(current->type() == RegTreeDevType) | ||
291 | { | ||
292 | DevTreeItem *item = dynamic_cast< DevTreeItem * >(current); | ||
293 | DisplayDevice(item->GetRef()); | ||
294 | } | ||
597 | } | 295 | } |
598 | 296 | ||
599 | void RegTab::OnAnalyserChanged(QListWidgetItem *current, QListWidgetItem *previous) | 297 | void RegTab::OnAnalyserChanged(QListWidgetItem *current, QListWidgetItem *previous) |
600 | { | 298 | { |
601 | (void) previous; | 299 | Q_UNUSED(previous); |
602 | OnAnalyserClicked(current); | 300 | OnAnalyserClicked(current); |
603 | } | 301 | } |
604 | 302 | ||
@@ -606,33 +304,44 @@ void RegTab::OnAnalyserClicked(QListWidgetItem *current) | |||
606 | { | 304 | { |
607 | if(current == 0) | 305 | if(current == 0) |
608 | return; | 306 | return; |
609 | delete m_right_content; | ||
610 | AnalyserFactory *ana = AnalyserFactory::GetAnalyserByName(current->text()); | 307 | AnalyserFactory *ana = AnalyserFactory::GetAnalyserByName(current->text()); |
611 | m_right_content = ana->Create(m_cur_soc, m_io_backend)->GetWidget(); | 308 | SetPanel(ana->Create(m_cur_soc, m_io_backend)); |
612 | m_right_panel->addWidget(m_right_content, 1); | ||
613 | } | 309 | } |
614 | 310 | ||
615 | void RegTab::DisplayRegister(const SocRegRef& ref) | 311 | void RegTab::DisplayRegister(const SocRegRef& ref) |
616 | { | 312 | { |
313 | SetPanel(new RegDisplayPanel(this, m_io_backend, ref)); | ||
314 | } | ||
315 | |||
316 | void RegTab::DisplayDevice(const SocDevRef& ref) | ||
317 | { | ||
318 | SetPanel(new DevDisplayPanel(this, ref)); | ||
319 | } | ||
320 | |||
321 | void RegTab::SetPanel(RegTabPanel *panel) | ||
322 | { | ||
617 | delete m_right_content; | 323 | delete m_right_content; |
618 | RegDisplayPanel *panel = new RegDisplayPanel(this, m_io_backend, ref); | ||
619 | panel->AllowWrite(m_readonly_check->checkState() == Qt::Unchecked); | ||
620 | m_right_content = panel; | 324 | m_right_content = panel; |
621 | m_right_panel->addWidget(m_right_content); | 325 | m_right_content->AllowWrite(m_readonly_check->checkState() == Qt::Unchecked); |
326 | m_right_panel->addWidget(m_right_content->GetWidget(), 1); | ||
622 | } | 327 | } |
623 | 328 | ||
624 | void RegTab::OnSocListChanged() | 329 | void RegTab::OnSocListChanged() |
625 | { | 330 | { |
626 | m_soc_selector->clear(); | 331 | m_soc_selector->clear(); |
627 | QStringList socs = m_backend->GetSocNameList(); | 332 | QList< SocRef > socs = m_backend->GetSocList(); |
628 | for(int i = 0; i < socs.size(); i++) | 333 | for(int i = 0; i < socs.size(); i++) |
629 | m_soc_selector->addItem(socs[i]); | 334 | { |
335 | QVariant v; | ||
336 | v.setValue(socs[i]); | ||
337 | m_soc_selector->addItem(QString::fromStdString(socs[i].GetSoc().name), v); | ||
338 | } | ||
630 | } | 339 | } |
631 | 340 | ||
632 | #ifdef HAVE_HWSTUB | 341 | #ifdef HAVE_HWSTUB |
633 | void RegTab::OnDevListChanged() | 342 | void RegTab::OnDevListChanged() |
634 | { | 343 | { |
635 | m_dev_selector->clear(); | 344 | ClearDevList(); |
636 | QList< HWStubDevice* > list = m_hwstub_helper.GetDevList(); | 345 | QList< HWStubDevice* > list = m_hwstub_helper.GetDevList(); |
637 | foreach(HWStubDevice *dev, list) | 346 | foreach(HWStubDevice *dev, list) |
638 | { | 347 | { |
@@ -659,10 +368,21 @@ void RegTab::OnDevChanged(int index) | |||
659 | OnDataSocActivated(m_io_backend->GetSocName()); | 368 | OnDataSocActivated(m_io_backend->GetSocName()); |
660 | OnDataChanged(); | 369 | OnDataChanged(); |
661 | } | 370 | } |
371 | |||
372 | void RegTab::ClearDevList() | ||
373 | { | ||
374 | while(m_dev_selector->count() > 0) | ||
375 | { | ||
376 | HWStubDevice *dev = reinterpret_cast< HWStubDevice* >(m_dev_selector->itemData(0).value< void* >()); | ||
377 | delete dev; | ||
378 | m_dev_selector->removeItem(0); | ||
379 | } | ||
380 | } | ||
662 | #endif | 381 | #endif |
663 | 382 | ||
664 | void RegTab::FillDevSubTree(DevTreeItem *item) | 383 | void RegTab::FillDevSubTree(QTreeWidgetItem *_item) |
665 | { | 384 | { |
385 | DevTreeItem *item = dynamic_cast< DevTreeItem* >(_item); | ||
666 | const soc_dev_t& dev = item->GetRef().GetDev(); | 386 | const soc_dev_t& dev = item->GetRef().GetDev(); |
667 | for(size_t i = 0; i < dev.reg.size(); i++) | 387 | for(size_t i = 0; i < dev.reg.size(); i++) |
668 | { | 388 | { |
@@ -697,23 +417,21 @@ void RegTab::FillAnalyserList() | |||
697 | m_analysers_list->addItems(AnalyserFactory::GetAnalysersForSoc(m_cur_soc.GetSoc().name.c_str())); | 417 | m_analysers_list->addItems(AnalyserFactory::GetAnalysersForSoc(m_cur_soc.GetSoc().name.c_str())); |
698 | } | 418 | } |
699 | 419 | ||
700 | void RegTab::OnSocChanged(const QString& soc) | 420 | void RegTab::OnSocChanged(int index) |
701 | { | 421 | { |
702 | m_reg_tree->clear(); | 422 | if(index == -1) |
703 | if(!m_backend->GetSocByName(soc, m_cur_soc)) | ||
704 | return; | 423 | return; |
424 | m_reg_tree->clear(); | ||
425 | m_cur_soc = m_soc_selector->itemData(index).value< SocRef >(); | ||
705 | FillRegTree(); | 426 | FillRegTree(); |
706 | FillAnalyserList(); | 427 | FillAnalyserList(); |
428 | UpdateSocFilename(); | ||
707 | } | 429 | } |
708 | 430 | ||
709 | void RegTab::OnReadOnlyClicked(bool checked) | 431 | void RegTab::OnReadOnlyClicked(bool checked) |
710 | { | 432 | { |
711 | if(m_io_backend->IsReadOnly()) | 433 | if(m_io_backend->IsReadOnly()) |
712 | return SetReadOnlyIndicator(); | 434 | return SetReadOnlyIndicator(); |
713 | if(m_right_content == 0) | 435 | m_right_content->AllowWrite(!checked); |
714 | return; | 436 | UpdateSocFilename(); |
715 | RegDisplayPanel *panel = dynamic_cast< RegDisplayPanel* >(m_right_content); | ||
716 | if(panel == 0) | ||
717 | return; | ||
718 | panel->AllowWrite(!checked); | ||
719 | } | 437 | } |