diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2014-02-10 23:10:55 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2014-02-10 23:14:27 +0100 |
commit | 04fc97b3623f31f081694aa5a1f122b312aa9642 (patch) | |
tree | 861526d46a77817f0760285b3d7f79d212947340 /utils/regtools | |
parent | 6e132b48d52ad285728529f982bb6421b100ba8a (diff) | |
download | rockbox-04fc97b3623f31f081694aa5a1f122b312aa9642.tar.gz rockbox-04fc97b3623f31f081694aa5a1f122b312aa9642.zip |
regtools/qeditor: implement UI code to write registers
The UI now has a "read-only" check box to prevent accidently changes: once
unchecked, the UI can do write to register (only full register writes are
supported for now). If the register supports it, the UI provides SCT writes
as well. The display register panel was moved to its own class to cleanup
things a bit.
Change-Id: I0fc6aab3b351f9080076102ee6fad0037ab5353b
Diffstat (limited to 'utils/regtools')
-rw-r--r-- | utils/regtools/qeditor/regtab.cpp | 450 | ||||
-rw-r--r-- | utils/regtools/qeditor/regtab.h | 76 |
2 files changed, 374 insertions, 152 deletions
diff --git a/utils/regtools/qeditor/regtab.cpp b/utils/regtools/qeditor/regtab.cpp index 8403a19ea1..4cd4e7b283 100644 --- a/utils/regtools/qeditor/regtab.cpp +++ b/utils/regtools/qeditor/regtab.cpp | |||
@@ -2,7 +2,6 @@ | |||
2 | 2 | ||
3 | #include <QSplitter> | 3 | #include <QSplitter> |
4 | #include <QVBoxLayout> | 4 | #include <QVBoxLayout> |
5 | #include <QGroupBox> | ||
6 | #include <QAbstractListModel> | 5 | #include <QAbstractListModel> |
7 | #include <QMessageBox> | 6 | #include <QMessageBox> |
8 | #include <QSizePolicy> | 7 | #include <QSizePolicy> |
@@ -14,9 +13,14 @@ | |||
14 | #include <QHeaderView> | 13 | #include <QHeaderView> |
15 | #include <QFileDialog> | 14 | #include <QFileDialog> |
16 | #include <QDebug> | 15 | #include <QDebug> |
16 | #include <QStyle> | ||
17 | #include "backend.h" | 17 | #include "backend.h" |
18 | #include "analyser.h" | 18 | #include "analyser.h" |
19 | 19 | ||
20 | /** | ||
21 | * SocFieldValidator | ||
22 | */ | ||
23 | |||
20 | SocFieldValidator::SocFieldValidator(QObject *parent) | 24 | SocFieldValidator::SocFieldValidator(QObject *parent) |
21 | :QValidator(parent) | 25 | :QValidator(parent) |
22 | { | 26 | { |
@@ -39,7 +43,6 @@ QValidator::State SocFieldValidator::validate(QString& input, int& pos) const | |||
39 | (void) pos; | 43 | (void) pos; |
40 | soc_word_t val; | 44 | soc_word_t val; |
41 | State state = parse(input, val); | 45 | State state = parse(input, val); |
42 | qDebug() << "validate(" << input << "): " << state; | ||
43 | return state; | 46 | return state; |
44 | } | 47 | } |
45 | 48 | ||
@@ -113,6 +116,289 @@ QValidator::State SocFieldValidator::parse(const QString& input, soc_word_t& val | |||
113 | return state; | 116 | return state; |
114 | } | 117 | } |
115 | 118 | ||
119 | /** | ||
120 | * RegLineEdit | ||
121 | */ | ||
122 | RegLineEdit::RegLineEdit(QWidget *parent) | ||
123 | :QWidget(parent) | ||
124 | { | ||
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 | |||
144 | void RegLineEdit::SetReadOnly(bool ro) | ||
145 | { | ||
146 | m_edit->setReadOnly(ro); | ||
147 | m_readonly = ro; | ||
148 | ShowMode(!ro); | ||
149 | } | ||
150 | |||
151 | void RegLineEdit::EnableSCT(bool en) | ||
152 | { | ||
153 | m_has_sct = en; | ||
154 | if(!m_has_sct) | ||
155 | { | ||
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 | |||
167 | QLineEdit *RegLineEdit::GetLineEdit() | ||
168 | { | ||
169 | return m_edit; | ||
170 | } | ||
171 | |||
172 | void RegLineEdit::ShowMode(bool show) | ||
173 | { | ||
174 | if(show) | ||
175 | m_button->show(); | ||
176 | else | ||
177 | m_button->hide(); | ||
178 | } | ||
179 | |||
180 | void RegLineEdit::OnWriteAct() | ||
181 | { | ||
182 | SetMode(Write); | ||
183 | } | ||
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 | |||
213 | RegLineEdit::EditMode RegLineEdit::GetMode() | ||
214 | { | ||
215 | return m_mode; | ||
216 | } | ||
217 | |||
218 | /** | ||
219 | * RegDisplayPanel | ||
220 | */ | ||
221 | |||
222 | RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const SocRegRef& reg_ref) | ||
223 | :QGroupBox(parent), m_io_backend(io_backend), m_reg(reg_ref) | ||
224 | { | ||
225 | bool read_only = m_io_backend->IsReadOnly(); | ||
226 | |||
227 | QVBoxLayout *right_layout = new QVBoxLayout; | ||
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 | } | ||
363 | |||
364 | void RegDisplayPanel::AllowWrite(bool en) | ||
365 | { | ||
366 | m_allow_write = en; | ||
367 | if(m_raw_val_edit) | ||
368 | m_raw_val_edit->SetReadOnly(m_io_backend->IsReadOnly() || !m_allow_write); | ||
369 | } | ||
370 | |||
371 | IoBackend::WriteMode RegDisplayPanel::EditModeToWriteMode(RegLineEdit::EditMode mode) | ||
372 | { | ||
373 | switch(mode) | ||
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 | } | ||
382 | |||
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 | |||
398 | /** | ||
399 | * RegTab | ||
400 | */ | ||
401 | |||
116 | RegTab::RegTab(Backend *backend) | 402 | RegTab::RegTab(Backend *backend) |
117 | :m_backend(backend) | 403 | :m_backend(backend) |
118 | { | 404 | { |
@@ -153,15 +439,19 @@ RegTab::RegTab(Backend *backend) | |||
153 | #endif | 439 | #endif |
154 | m_data_sel_edit = new QLineEdit; | 440 | m_data_sel_edit = new QLineEdit; |
155 | m_data_sel_edit->setReadOnly(true); | 441 | m_data_sel_edit->setReadOnly(true); |
442 | m_readonly_check = new QCheckBox("Read-only"); | ||
443 | m_readonly_check->setCheckState(Qt::Checked); | ||
156 | m_data_soc_label = new QLabel; | 444 | m_data_soc_label = new QLabel; |
157 | QPushButton *data_sel_reload = new QPushButton; | 445 | QPushButton *data_sel_reload = new QPushButton; |
158 | data_sel_reload->setIcon(QIcon::fromTheme("view-refresh")); | 446 | data_sel_reload->setIcon(QIcon::fromTheme("view-refresh")); |
447 | data_sel_reload->setToolTip("Reload data"); | ||
159 | data_sel_layout->addWidget(m_data_selector); | 448 | data_sel_layout->addWidget(m_data_selector); |
160 | data_sel_layout->addWidget(m_data_sel_edit); | 449 | data_sel_layout->addWidget(m_data_sel_edit); |
161 | #ifdef HAVE_HWSTUB | 450 | #ifdef HAVE_HWSTUB |
162 | m_dev_selector = new QComboBox; | 451 | m_dev_selector = new QComboBox; |
163 | data_sel_layout->addWidget(m_dev_selector, 1); | 452 | data_sel_layout->addWidget(m_dev_selector, 1); |
164 | #endif | 453 | #endif |
454 | data_sel_layout->addWidget(m_readonly_check); | ||
165 | data_sel_layout->addWidget(m_data_soc_label); | 455 | data_sel_layout->addWidget(m_data_soc_label); |
166 | data_sel_layout->addWidget(data_sel_reload); | 456 | data_sel_layout->addWidget(data_sel_reload); |
167 | data_sel_group->setLayout(data_sel_layout); | 457 | data_sel_group->setLayout(data_sel_layout); |
@@ -199,6 +489,7 @@ RegTab::RegTab(Backend *backend) | |||
199 | connect(m_dev_selector, SIGNAL(currentIndexChanged(int)), | 489 | connect(m_dev_selector, SIGNAL(currentIndexChanged(int)), |
200 | this, SLOT(OnDevChanged(int))); | 490 | this, SLOT(OnDevChanged(int))); |
201 | #endif | 491 | #endif |
492 | connect(m_readonly_check, SIGNAL(clicked(bool)), this, SLOT(OnReadOnlyClicked(bool))); | ||
202 | 493 | ||
203 | OnSocListChanged(); | 494 | OnSocListChanged(); |
204 | OnDataSelChanged(DataSelNothing); | 495 | OnDataSelChanged(DataSelNothing); |
@@ -280,6 +571,8 @@ void RegTab::OnDataSelChanged(int index) | |||
280 | 571 | ||
281 | void RegTab::SetReadOnlyIndicator() | 572 | void RegTab::SetReadOnlyIndicator() |
282 | { | 573 | { |
574 | if(m_io_backend->IsReadOnly()) | ||
575 | m_readonly_check->setCheckState(Qt::Checked); | ||
283 | } | 576 | } |
284 | 577 | ||
285 | void RegTab::OnDataChanged() | 578 | void RegTab::OnDataChanged() |
@@ -322,140 +615,9 @@ void RegTab::OnAnalyserClicked(QListWidgetItem *current) | |||
322 | void RegTab::DisplayRegister(const SocRegRef& ref) | 615 | void RegTab::DisplayRegister(const SocRegRef& ref) |
323 | { | 616 | { |
324 | delete m_right_content; | 617 | delete m_right_content; |
325 | 618 | RegDisplayPanel *panel = new RegDisplayPanel(this, m_io_backend, ref); | |
326 | bool read_only = m_io_backend->IsReadOnly(); | 619 | panel->AllowWrite(m_readonly_check->checkState() == Qt::Unchecked); |
327 | 620 | m_right_content = panel; | |
328 | QVBoxLayout *right_layout = new QVBoxLayout; | ||
329 | |||
330 | const soc_dev_addr_t& dev_addr = ref.GetDevAddr(); | ||
331 | const soc_reg_t& reg = ref.GetReg(); | ||
332 | const soc_reg_addr_t& reg_addr = ref.GetRegAddr(); | ||
333 | |||
334 | QString reg_name; | ||
335 | reg_name.sprintf("HW_%s_%s", dev_addr.name.c_str(), reg_addr.name.c_str()); | ||
336 | QStringList names; | ||
337 | QVector< soc_addr_t > addresses; | ||
338 | names.append(reg_name); | ||
339 | addresses.append(reg_addr.addr); | ||
340 | if(reg.flags & REG_HAS_SCT) | ||
341 | { | ||
342 | names.append(reg_name + "_SET"); | ||
343 | names.append(reg_name + "_CLR"); | ||
344 | names.append(reg_name + "_TOG"); | ||
345 | addresses.append(reg_addr.addr + 4); | ||
346 | addresses.append(reg_addr.addr + 8); | ||
347 | addresses.append(reg_addr.addr + 12); | ||
348 | } | ||
349 | |||
350 | QString str; | ||
351 | str += "<table align=left>"; | ||
352 | for(int i = 0; i < names.size(); i++) | ||
353 | str += "<tr><td><b>" + names[i] + "</b></td></tr>"; | ||
354 | str += "</table>"; | ||
355 | QLabel *label_names = new QLabel; | ||
356 | label_names->setTextFormat(Qt::RichText); | ||
357 | label_names->setText(str); | ||
358 | |||
359 | QString str_addr; | ||
360 | str_addr += "<table align=left>"; | ||
361 | for(int i = 0; i < names.size(); i++) | ||
362 | str_addr += "<tr><td><b>" + QString().sprintf("0x%03x", addresses[i]) + "</b></td></tr>"; | ||
363 | str_addr += "</table>"; | ||
364 | QLabel *label_addr = new QLabel; | ||
365 | label_addr->setTextFormat(Qt::RichText); | ||
366 | label_addr->setText(str_addr); | ||
367 | |||
368 | QHBoxLayout *top_layout = new QHBoxLayout; | ||
369 | top_layout->addStretch(); | ||
370 | top_layout->addWidget(label_names); | ||
371 | top_layout->addWidget(label_addr); | ||
372 | top_layout->addStretch(); | ||
373 | |||
374 | soc_word_t value; | ||
375 | BackendHelper helper(m_io_backend, m_cur_soc); | ||
376 | bool has_value = helper.ReadRegister(dev_addr.name.c_str(), reg_addr.name.c_str(), value); | ||
377 | |||
378 | QHBoxLayout *raw_val_layout = 0; | ||
379 | if(has_value) | ||
380 | { | ||
381 | QLabel *raw_val_name = new QLabel; | ||
382 | raw_val_name->setText("Raw value:"); | ||
383 | QLineEdit *raw_val_edit = new QLineEdit; | ||
384 | raw_val_edit->setReadOnly(read_only); | ||
385 | raw_val_edit->setText(QString().sprintf("0x%08x", value)); | ||
386 | raw_val_edit->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); | ||
387 | raw_val_edit->setValidator(new SocFieldValidator(raw_val_edit)); | ||
388 | connect(raw_val_edit, SIGNAL(returnPressed()), this, SLOT(OnRawRegValueReturnPressed())); | ||
389 | raw_val_layout = new QHBoxLayout; | ||
390 | raw_val_layout->addStretch(); | ||
391 | raw_val_layout->addWidget(raw_val_name); | ||
392 | raw_val_layout->addWidget(raw_val_edit); | ||
393 | raw_val_layout->addStretch(); | ||
394 | } | ||
395 | |||
396 | QTableWidget *value_table = new QTableWidget; | ||
397 | value_table->setRowCount(reg.field.size()); | ||
398 | value_table->setColumnCount(4); | ||
399 | int row = 0; | ||
400 | foreach(const soc_reg_field_t& field, reg.field) | ||
401 | { | ||
402 | QString bits_str; | ||
403 | if(field.first_bit == field.last_bit) | ||
404 | bits_str.sprintf("%d", field.first_bit); | ||
405 | else | ||
406 | bits_str.sprintf("%d:%d", field.last_bit, field.first_bit); | ||
407 | QTableWidgetItem *item = new QTableWidgetItem(bits_str); | ||
408 | item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | ||
409 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
410 | value_table->setItem(row, 0, item); | ||
411 | item = new QTableWidgetItem(QString(field.name.c_str())); | ||
412 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
413 | value_table->setItem(row, 1, item); | ||
414 | item = new QTableWidgetItem(); | ||
415 | if(has_value) | ||
416 | { | ||
417 | soc_word_t v = (value & field.bitmask()) >> field.first_bit; | ||
418 | QString value_name; | ||
419 | foreach(const soc_reg_field_value_t& rval, field.value) | ||
420 | if(v == rval.value) | ||
421 | value_name = rval.name.c_str(); | ||
422 | const char *fmt = "%lu"; | ||
423 | // heuristic | ||
424 | if((field.last_bit - field.first_bit + 1) > 16) | ||
425 | fmt = "0x%lx"; | ||
426 | item->setText(QString().sprintf(fmt, (unsigned long)v)); | ||
427 | item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | ||
428 | |||
429 | if(value_name.size() != 0) | ||
430 | { | ||
431 | QTableWidgetItem *t = new QTableWidgetItem(value_name); | ||
432 | t->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter); | ||
433 | t->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
434 | value_table->setItem(row, 3, t); | ||
435 | } | ||
436 | } | ||
437 | item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); | ||
438 | value_table->setItem(row, 2, item); | ||
439 | row++; | ||
440 | } | ||
441 | value_table->setHorizontalHeaderItem(0, new QTableWidgetItem("Bits")); | ||
442 | value_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Name")); | ||
443 | value_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Value")); | ||
444 | value_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Meaning")); | ||
445 | value_table->verticalHeader()->setVisible(false); | ||
446 | value_table->resizeColumnsToContents(); | ||
447 | value_table->horizontalHeader()->setStretchLastSection(true); | ||
448 | value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||
449 | |||
450 | right_layout->addLayout(top_layout); | ||
451 | if(raw_val_layout) | ||
452 | right_layout->addLayout(raw_val_layout); | ||
453 | //right_layout->addWidget(bits_label); | ||
454 | right_layout->addWidget(value_table); | ||
455 | //right_layout->addStretch(); | ||
456 | |||
457 | m_right_content = new QGroupBox("Register Description"); | ||
458 | m_right_content->setLayout(right_layout); | ||
459 | m_right_panel->addWidget(m_right_content); | 621 | m_right_panel->addWidget(m_right_content); |
460 | } | 622 | } |
461 | 623 | ||
@@ -483,6 +645,7 @@ void RegTab::OnDevListChanged() | |||
483 | m_dev_selector->setCurrentIndex(0); | 645 | m_dev_selector->setCurrentIndex(0); |
484 | else | 646 | else |
485 | SetDataSocName(""); | 647 | SetDataSocName(""); |
648 | SetReadOnlyIndicator(); | ||
486 | } | 649 | } |
487 | 650 | ||
488 | void RegTab::OnDevChanged(int index) | 651 | void RegTab::OnDevChanged(int index) |
@@ -543,11 +706,14 @@ void RegTab::OnSocChanged(const QString& soc) | |||
543 | FillAnalyserList(); | 706 | FillAnalyserList(); |
544 | } | 707 | } |
545 | 708 | ||
546 | void RegTab::OnRawRegValueReturnPressed() | 709 | void RegTab::OnReadOnlyClicked(bool checked) |
547 | { | 710 | { |
548 | QObject *obj = sender(); | 711 | if(m_io_backend->IsReadOnly()) |
549 | QLineEdit *edit = dynamic_cast< QLineEdit* >(obj); | 712 | return SetReadOnlyIndicator(); |
550 | const SocFieldValidator *validator = dynamic_cast< const SocFieldValidator* >(edit->validator()); | 713 | if(m_right_content == 0) |
551 | soc_word_t val; | 714 | return; |
552 | QValidator::State state = validator->parse(edit->text(), val); | 715 | RegDisplayPanel *panel = dynamic_cast< RegDisplayPanel* >(m_right_content); |
716 | if(panel == 0) | ||
717 | return; | ||
718 | panel->AllowWrite(!checked); | ||
553 | } | 719 | } |
diff --git a/utils/regtools/qeditor/regtab.h b/utils/regtools/qeditor/regtab.h index 8afa21c346..9fa1437119 100644 --- a/utils/regtools/qeditor/regtab.h +++ b/utils/regtools/qeditor/regtab.h | |||
@@ -12,6 +12,10 @@ | |||
12 | #include <QLabel> | 12 | #include <QLabel> |
13 | #include <QListWidget> | 13 | #include <QListWidget> |
14 | #include <QValidator> | 14 | #include <QValidator> |
15 | #include <QGroupBox> | ||
16 | #include <QToolButton> | ||
17 | #include <QMenu> | ||
18 | #include <QCheckBox> | ||
15 | #include <soc_desc.hpp> | 19 | #include <soc_desc.hpp> |
16 | #include "backend.h" | 20 | #include "backend.h" |
17 | #include "settings.h" | 21 | #include "settings.h" |
@@ -22,15 +26,6 @@ enum | |||
22 | RegTreeRegType | 26 | RegTreeRegType |
23 | }; | 27 | }; |
24 | 28 | ||
25 | enum | ||
26 | { | ||
27 | DataSelNothing, | ||
28 | DataSelFile, | ||
29 | #ifdef HAVE_HWSTUB | ||
30 | DataSelDevice, | ||
31 | #endif | ||
32 | }; | ||
33 | |||
34 | class DevTreeItem : public QTreeWidgetItem | 29 | class DevTreeItem : public QTreeWidgetItem |
35 | { | 30 | { |
36 | public: | 31 | public: |
@@ -69,6 +64,57 @@ protected: | |||
69 | soc_reg_field_t m_field; | 64 | soc_reg_field_t m_field; |
70 | }; | 65 | }; |
71 | 66 | ||
67 | class RegLineEdit : public QWidget | ||
68 | { | ||
69 | Q_OBJECT | ||
70 | public: | ||
71 | enum EditMode | ||
72 | { | ||
73 | Write, Set, Clear, Toggle | ||
74 | }; | ||
75 | |||
76 | RegLineEdit(QWidget *parent = 0); | ||
77 | ~RegLineEdit(); | ||
78 | void SetReadOnly(bool ro); | ||
79 | void EnableSCT(bool en); | ||
80 | void SetMode(EditMode mode); | ||
81 | EditMode GetMode(); | ||
82 | QLineEdit *GetLineEdit(); | ||
83 | |||
84 | protected slots: | ||
85 | void OnWriteAct(); | ||
86 | void OnSetAct(); | ||
87 | void OnClearAct(); | ||
88 | void OnToggleAct(); | ||
89 | protected: | ||
90 | void ShowMode(bool show); | ||
91 | |||
92 | QHBoxLayout *m_layout; | ||
93 | QToolButton *m_button; | ||
94 | QLineEdit *m_edit; | ||
95 | EditMode m_mode; | ||
96 | bool m_has_sct; | ||
97 | bool m_readonly; | ||
98 | QMenu *m_menu; | ||
99 | }; | ||
100 | |||
101 | class RegDisplayPanel : public QGroupBox | ||
102 | { | ||
103 | Q_OBJECT | ||
104 | public: | ||
105 | RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const SocRegRef& reg); | ||
106 | void AllowWrite(bool en); | ||
107 | |||
108 | protected: | ||
109 | IoBackend::WriteMode EditModeToWriteMode(RegLineEdit::EditMode mode); | ||
110 | |||
111 | IoBackend *m_io_backend; | ||
112 | const SocRegRef& m_reg; | ||
113 | bool m_allow_write; | ||
114 | RegLineEdit *m_raw_val_edit; | ||
115 | |||
116 | private slots: | ||
117 | void OnRawRegValueReturnPressed(); | ||
72 | }; | 118 | }; |
73 | 119 | ||
74 | class RegTab : public QSplitter | 120 | class RegTab : public QSplitter |
@@ -79,6 +125,15 @@ public: | |||
79 | ~RegTab(); | 125 | ~RegTab(); |
80 | 126 | ||
81 | protected: | 127 | protected: |
128 | enum | ||
129 | { | ||
130 | DataSelNothing, | ||
131 | DataSelFile, | ||
132 | #ifdef HAVE_HWSTUB | ||
133 | DataSelDevice, | ||
134 | #endif | ||
135 | }; | ||
136 | |||
82 | void FillDevSubTree(DevTreeItem *item); | 137 | void FillDevSubTree(DevTreeItem *item); |
83 | void FillRegTree(); | 138 | void FillRegTree(); |
84 | void FillAnalyserList(); | 139 | void FillAnalyserList(); |
@@ -96,6 +151,7 @@ protected: | |||
96 | QVBoxLayout *m_right_panel; | 151 | QVBoxLayout *m_right_panel; |
97 | QWidget *m_right_content; | 152 | QWidget *m_right_content; |
98 | QLineEdit *m_data_sel_edit; | 153 | QLineEdit *m_data_sel_edit; |
154 | QCheckBox *m_readonly_check; | ||
99 | QLabel *m_data_soc_label; | 155 | QLabel *m_data_soc_label; |
100 | QPushButton *m_data_sel_reload; | 156 | QPushButton *m_data_sel_reload; |
101 | QComboBox *m_data_selector; | 157 | QComboBox *m_data_selector; |
@@ -118,7 +174,7 @@ private slots: | |||
118 | void OnDataSocActivated(const QString&); | 174 | void OnDataSocActivated(const QString&); |
119 | void OnAnalyserChanged(QListWidgetItem *current, QListWidgetItem *previous); | 175 | void OnAnalyserChanged(QListWidgetItem *current, QListWidgetItem *previous); |
120 | void OnAnalyserClicked(QListWidgetItem *clicked); | 176 | void OnAnalyserClicked(QListWidgetItem *clicked); |
121 | void OnRawRegValueReturnPressed(); | 177 | void OnReadOnlyClicked(bool); |
122 | }; | 178 | }; |
123 | 179 | ||
124 | #endif /* REGTAB_H */ \ No newline at end of file | 180 | #endif /* REGTAB_H */ \ No newline at end of file |