diff options
Diffstat (limited to 'utils/regtools/qeditor')
-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 |