summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2014-10-28 11:19:24 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2015-09-11 16:02:34 +0200
commitc8d3638b9ebc24e4766714da1c9f961e350799c6 (patch)
treefe9ea6420575091dda63092ea9467a4fa0306a99
parent2c832968c91cb56e4c252bd8eafb03d7d9c8aeda (diff)
downloadrockbox-c8d3638b9ebc24e4766714da1c9f961e350799c6.tar.gz
rockbox-c8d3638b9ebc24e4766714da1c9f961e350799c6.zip
qeditor: introduce new "sexy register display"
Change-Id: Ib938b4be71d2c7623851dbc3c211f96105077d7d
-rw-r--r--utils/regtools/qeditor/qeditor.pro2
-rw-r--r--utils/regtools/qeditor/regdisplaypanel.cpp13
-rw-r--r--utils/regtools/qeditor/regdisplaypanel.h2
-rw-r--r--utils/regtools/qeditor/regedit.cpp54
-rw-r--r--utils/regtools/qeditor/regedit.h6
-rw-r--r--utils/regtools/qeditor/utils.cpp261
-rw-r--r--utils/regtools/qeditor/utils.h82
7 files changed, 286 insertions, 134 deletions
diff --git a/utils/regtools/qeditor/qeditor.pro b/utils/regtools/qeditor/qeditor.pro
index 39b6c76cc9..eecc0aba3f 100644
--- a/utils/regtools/qeditor/qeditor.pro
+++ b/utils/regtools/qeditor/qeditor.pro
@@ -12,7 +12,7 @@ libsocdesc.commands = cd ../lib && make
12QMAKE_EXTRA_TARGETS += libsocdesc 12QMAKE_EXTRA_TARGETS += libsocdesc
13PRE_TARGETDEPS += libsocdesc 13PRE_TARGETDEPS += libsocdesc
14 14
15VERSION = 2.0.3 15VERSION = 2.0.4
16 16
17DEFINES += APP_VERSION=\\\"$$VERSION\\\" 17DEFINES += APP_VERSION=\\\"$$VERSION\\\"
18 18
diff --git a/utils/regtools/qeditor/regdisplaypanel.cpp b/utils/regtools/qeditor/regdisplaypanel.cpp
index 3dbdb54241..167c776cce 100644
--- a/utils/regtools/qeditor/regdisplaypanel.cpp
+++ b/utils/regtools/qeditor/regdisplaypanel.cpp
@@ -196,7 +196,7 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
196 raw_val_layout->addWidget(m_raw_val_edit); 196 raw_val_layout->addWidget(m_raw_val_edit);
197 raw_val_layout->addStretch(); 197 raw_val_layout->addStretch();
198 198
199 m_value_table = new GrowingTableView; 199 m_value_table = new GrowingTableView();
200 m_value_model = new RegFieldTableModel(m_value_table); // view takes ownership 200 m_value_model = new RegFieldTableModel(m_value_table); // view takes ownership
201 m_value_model->SetRegister(m_reg.GetReg()); 201 m_value_model->SetRegister(m_reg.GetReg());
202 m_value_model->SetReadOnly(read_only); 202 m_value_model->SetReadOnly(read_only);
@@ -208,7 +208,7 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
208 // FIXME we cannot use setAlternatingRowColors() because we override the 208 // FIXME we cannot use setAlternatingRowColors() because we override the
209 // background color, should it be part of the model ? 209 // background color, should it be part of the model ?
210 210
211 SocFieldCachedItemDelegate *m_table_delegate = new SocFieldCachedItemDelegate(this); 211 m_table_delegate = new SocFieldCachedItemDelegate(this);
212 m_table_edit_factory = new QItemEditorFactory(); 212 m_table_edit_factory = new QItemEditorFactory();
213 SocFieldCachedEditorCreator *m_table_edit_creator = new SocFieldCachedEditorCreator(); 213 SocFieldCachedEditorCreator *m_table_edit_creator = new SocFieldCachedEditorCreator();
214 // FIXME see QTBUG-30392 214 // FIXME see QTBUG-30392
@@ -217,8 +217,10 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
217 m_table_delegate->setItemEditorFactory(m_table_edit_factory); 217 m_table_delegate->setItemEditorFactory(m_table_edit_factory);
218 m_value_table->setItemDelegate(m_table_delegate); 218 m_value_table->setItemDelegate(m_table_delegate);
219 219
220 m_sexy_display = new RegSexyDisplay(reg_ref, this); 220 m_sexy_display2 = new Unscroll<RegSexyDisplay2>(this);
221 m_sexy_display->setFont(m_reg_font); 221 m_sexy_display2->setFont(m_reg_font);
222 m_sexy_display2->setModel(m_value_model);
223 m_sexy_display2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
222 224
223 m_desc = new QLabel(this); 225 m_desc = new QLabel(this);
224 m_desc->setTextFormat(Qt::RichText); 226 m_desc->setTextFormat(Qt::RichText);
@@ -228,8 +230,9 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
228 right_layout->addLayout(top_layout); 230 right_layout->addLayout(top_layout);
229 if(raw_val_layout) 231 if(raw_val_layout)
230 right_layout->addLayout(raw_val_layout); 232 right_layout->addLayout(raw_val_layout);
231 right_layout->addWidget(m_sexy_display); 233 right_layout->addWidget(m_sexy_display2);
232 right_layout->addWidget(m_value_table); 234 right_layout->addWidget(m_value_table);
235 right_layout->addStretch();
233 236
234 setTitle("Register Description"); 237 setTitle("Register Description");
235 m_viewport = new QWidget; 238 m_viewport = new QWidget;
diff --git a/utils/regtools/qeditor/regdisplaypanel.h b/utils/regtools/qeditor/regdisplaypanel.h
index 313fc7e369..9a692778fe 100644
--- a/utils/regtools/qeditor/regdisplaypanel.h
+++ b/utils/regtools/qeditor/regdisplaypanel.h
@@ -105,7 +105,7 @@ protected:
105 const SocRegRef& m_reg; 105 const SocRegRef& m_reg;
106 bool m_allow_write; 106 bool m_allow_write;
107 RegLineEdit *m_raw_val_edit; 107 RegLineEdit *m_raw_val_edit;
108 RegSexyDisplay *m_sexy_display; 108 Unscroll< RegSexyDisplay2 > *m_sexy_display2;
109 GrowingTableView *m_value_table; 109 GrowingTableView *m_value_table;
110 RegFieldTableModel *m_value_model; 110 RegFieldTableModel *m_value_model;
111 QStyledItemDelegate *m_table_delegate; 111 QStyledItemDelegate *m_table_delegate;
diff --git a/utils/regtools/qeditor/regedit.cpp b/utils/regtools/qeditor/regedit.cpp
index 9dca6280e0..851e054eb0 100644
--- a/utils/regtools/qeditor/regedit.cpp
+++ b/utils/regtools/qeditor/regedit.cpp
@@ -336,47 +336,33 @@ RegEditPanel::RegEditPanel(SocRegRef ref, QWidget *parent)
336 top_layout->addLayout(name_layout); 336 top_layout->addLayout(name_layout);
337 top_layout->addWidget(m_desc_group, 1); 337 top_layout->addWidget(m_desc_group, 1);
338 338
339 m_sexy_display = new RegSexyDisplay(m_ref, this); 339 m_value_table = new QTableView(this);
340 m_sexy_display->setFont(m_reg_font); 340 m_value_model = new RegFieldTableModel(m_value_table); // view takes ownership
341 m_value_model->SetRegister(m_ref.GetReg());
342 m_value_model->SetReadOnly(true);
343 m_value_table->setModel(m_value_model);
344 m_value_table->verticalHeader()->setVisible(false);
345 m_value_table->horizontalHeader()->setStretchLastSection(true);
346 m_value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
347 // FIXME we cannot use setAlternatingRowColors() because we override the
348 // background color, should it be part of the model ?
349 m_table_delegate = new SocFieldCachedItemDelegate(this);
350 m_value_table->setItemDelegate(m_table_delegate);
351 m_value_table->resizeColumnsToContents();
352
353 m_sexy_display2 = new Unscroll<RegSexyDisplay2>(this);
354 m_sexy_display2->setFont(m_reg_font);
355 m_sexy_display2->setModel(m_value_model);
356 m_sexy_display2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
341 357
342 m_field_table = new QTableWidget;
343 m_field_table->setRowCount(m_ref.GetReg().field.size());
344 m_field_table->setColumnCount(4);
345 for(size_t row = 0; row < m_ref.GetReg().field.size(); row++)
346 {
347 const soc_reg_field_t& field = m_ref.GetReg().field[row];
348 QString bits_str;
349 if(field.first_bit == field.last_bit)
350 bits_str.sprintf("%d", field.first_bit);
351 else
352 bits_str.sprintf("%d:%d", field.last_bit, field.first_bit);
353 QTableWidgetItem *item = new QTableWidgetItem(bits_str);
354 item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
355 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
356 m_field_table->setItem(row, 1, item);
357 item = new QTableWidgetItem(QString(field.name.c_str()));
358 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
359 m_field_table->setItem(row, 2, item);
360 item = new QTableWidgetItem(QString(field.desc.c_str()));
361 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
362 m_field_table->setItem(row, 3, item);
363 UpdateWarning(row);
364 }
365 m_field_table->setHorizontalHeaderItem(0, new QTableWidgetItem(""));
366 m_field_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Bits"));
367 m_field_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Name"));
368 m_field_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Description"));
369 m_field_table->verticalHeader()->setVisible(false);
370 m_field_table->resizeColumnsToContents();
371 m_field_table->horizontalHeader()->setStretchLastSection(true);
372 QHBoxLayout *field_layout = new QHBoxLayout; 358 QHBoxLayout *field_layout = new QHBoxLayout;
373 field_layout->addWidget(m_field_table); 359 field_layout->addWidget(m_value_table);
374 m_field_group = new QGroupBox("Flags", this); 360 m_field_group = new QGroupBox("Flags", this);
375 m_field_group->setLayout(field_layout); 361 m_field_group->setLayout(field_layout);
376 362
377 QVBoxLayout *layout = new QVBoxLayout; 363 QVBoxLayout *layout = new QVBoxLayout;
378 layout->addLayout(top_layout, 0); 364 layout->addLayout(top_layout, 0);
379 layout->addWidget(m_sexy_display, 0); 365 layout->addWidget(m_sexy_display2, 0);
380 layout->addWidget(m_field_group); 366 layout->addWidget(m_field_group);
381 367
382 UpdateFormula(); 368 UpdateFormula();
diff --git a/utils/regtools/qeditor/regedit.h b/utils/regtools/qeditor/regedit.h
index 96c4875833..c56f0d9026 100644
--- a/utils/regtools/qeditor/regedit.h
+++ b/utils/regtools/qeditor/regedit.h
@@ -185,10 +185,12 @@ protected:
185 QComboBox *m_formula_combo; 185 QComboBox *m_formula_combo;
186 QLineEdit *m_formula_string_edit; 186 QLineEdit *m_formula_string_edit;
187 QPushButton *m_formula_string_gen; 187 QPushButton *m_formula_string_gen;
188 RegSexyDisplay *m_sexy_display; 188 Unscroll< RegSexyDisplay2 > *m_sexy_display2;
189 MyTextEditor *m_desc_edit; 189 MyTextEditor *m_desc_edit;
190 QGroupBox *m_field_group; 190 QGroupBox *m_field_group;
191 QTableWidget *m_field_table; 191 QTableView *m_value_table;
192 RegFieldTableModel *m_value_model;
193 QStyledItemDelegate *m_table_delegate;
192}; 194};
193 195
194class FieldEditPanel : public QWidget, public AbstractRegEditPanel 196class FieldEditPanel : public QWidget, public AbstractRegEditPanel
diff --git a/utils/regtools/qeditor/utils.cpp b/utils/regtools/qeditor/utils.cpp
index 4116dbcc81..e4a872ed49 100644
--- a/utils/regtools/qeditor/utils.cpp
+++ b/utils/regtools/qeditor/utils.cpp
@@ -669,104 +669,178 @@ void RegFieldTableModel::RecomputeTheme()
669} 669}
670 670
671/** 671/**
672 * RegSexyDisplay 672 * RegSexyDisplay2
673 */ 673 */
674RegSexyDisplay::RegSexyDisplay(const SocRegRef& reg, QWidget *parent) 674
675 :QWidget(parent), m_reg(reg) 675RegSexyDisplay2::RegSexyDisplay2(QWidget *parent)
676 :QAbstractItemView(parent)
677{
678 m_is_dirty = true;
679 // the frame around the register is ugly, disable it
680 setFrameShape(QFrame::NoFrame);
681}
682
683QModelIndex RegSexyDisplay2::indexAt(const QPoint& point) const
684{
685 Q_UNUSED(point);
686 return QModelIndex();
687}
688
689void RegSexyDisplay2::scrollTo(const QModelIndex& index, ScrollHint hint)
690{
691 Q_UNUSED(index);
692 Q_UNUSED(hint);
693}
694
695QRect RegSexyDisplay2::visualRect(const QModelIndex& index) const
696{
697 Q_UNUSED(index);
698 return QRect();
699}
700
701bool RegSexyDisplay2::isIndexHidden(const QModelIndex& index) const
702{
703 Q_UNUSED(index);
704 return false;
705}
706
707QModelIndex RegSexyDisplay2::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
708{
709 Q_UNUSED(cursorAction);
710 Q_UNUSED(modifiers);
711 return QModelIndex();
712}
713
714void RegSexyDisplay2::setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags)
715{
716 Q_UNUSED(rect);
717 Q_UNUSED(flags);
718}
719
720int RegSexyDisplay2::verticalOffset() const
721{
722 return verticalScrollBar()->value();
723}
724
725int RegSexyDisplay2::horizontalOffset() const
726{
727 return horizontalScrollBar()->value();
728}
729
730void RegSexyDisplay2::scrollContentsBy(int dx, int dy)
731{
732 viewport()->scroll(dx, dy);
733}
734
735void RegSexyDisplay2::setModel(QAbstractItemModel *model)
676{ 736{
677 m_size = QSize(); 737 QAbstractItemView::setModel(model);
738 m_is_dirty = true;
678} 739}
679 740
680int RegSexyDisplay::separatorSize() const 741void RegSexyDisplay2::dataChanged(const QModelIndex &topLeft,
742 const QModelIndex &bottomRight)
743{
744 m_is_dirty = true;
745 QAbstractItemView::dataChanged(topLeft, bottomRight);
746}
747
748void RegSexyDisplay2::rowsInserted(const QModelIndex &parent, int start, int end)
749{
750 m_is_dirty = true;
751 QAbstractItemView::rowsInserted(parent, start, end);
752}
753
754void RegSexyDisplay2::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
755{
756 m_is_dirty = true;
757 QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);
758}
759
760int RegSexyDisplay2::GetSeparatorSize() const
681{ 761{
682 return 1; 762 return 1;
683} 763}
684 764
685int RegSexyDisplay::marginSize() const 765int RegSexyDisplay2::GetMarginSize() const
686{ 766{
687 return fontMetrics().height() / 3; 767 return viewOptions().fontMetrics.height() / 3;
688} 768}
689 769
690int RegSexyDisplay::textSep() const 770int RegSexyDisplay2::GetHeaderTextSep() const
691{ 771{
692 return marginSize() / 2; 772 return GetMarginSize() / 2;
693} 773}
694 774
695int RegSexyDisplay::headerHeight() const 775int RegSexyDisplay2::GetHeaderHeight() const
696{ 776{
697 return 2 * marginSize() + textSep() + 2 * fontMetrics().height(); 777 return 2 * GetMarginSize() + GetHeaderTextSep() + 2 * viewOptions().fontMetrics.height();
698} 778}
699 779
700int RegSexyDisplay::columnWidth() const 780int RegSexyDisplay2::GetColumnWidth() const
701{ 781{
702 return 2 * marginSize() + fontMetrics().height(); 782 return 2 * GetMarginSize() + viewOptions().fontMetrics.height();
703} 783}
704 784
705int RegSexyDisplay::maxContentHeight() const 785int RegSexyDisplay2::GetMaxContentHeight() const
706{ 786{
707 int max = 0; 787 int max = 0;
708 QFontMetrics metrics = fontMetrics(); 788 QFontMetrics metrics = viewOptions().fontMetrics;
709 for(size_t i = 0; i < m_reg.GetReg().field.size(); i++) 789 if(model())
710 { 790 {
711 QString s = QString::fromStdString(m_reg.GetReg().field[i].name); 791 for(int i = 0; i < model()->rowCount(); i++)
712 // add extra spaces arounds 792 {
713 s = " " + s + " "; 793 QModelIndex index = model()->index(i, 1, rootIndex());
714 max = qMax(max, metrics.boundingRect(s).width()); 794 QString s = model()->data(index).toString();
795 max = qMax(max, metrics.boundingRect(s).width());
796 }
715 } 797 }
716 return 2 * marginSize() + max; 798 return 2 * GetMarginSize() + max;
717}
718
719int RegSexyDisplay::gapHeight() const
720{
721 return marginSize() / 2;
722} 799}
723 800
724QSize RegSexyDisplay::minimumSizeHint() const 801int RegSexyDisplay2::GetGapHeight() const
725{ 802{
726 /* cache computation because it's expensive */ 803 return GetMarginSize() / 2;
727 if(m_size.isValid())
728 return m_size;
729 /* width: display 32 columns + 33 vertical separators */
730 m_size.setWidth(32 * columnWidth() + 33 * separatorSize());
731 /* height: one separator + two digits + one separator + margin + separator
732 * + names + separator */
733 m_size.setHeight(4 * separatorSize() + headerHeight() + gapHeight() + maxContentHeight());
734 return m_size;
735} 804}
736 805
737QSize RegSexyDisplay::sizeHint() const 806QRegion RegSexyDisplay2::visualRegionForSelection(const QItemSelection& selection) const
738{ 807{
739 return minimumSizeHint(); 808 Q_UNUSED(selection);
809 return QRegion();
740} 810}
741 811
742void RegSexyDisplay::paintEvent(QPaintEvent *event) 812void RegSexyDisplay2::paintEvent(QPaintEvent *event)
743{ 813{
744 // FIXME could be optimised with QStaticText
745 Q_UNUSED(event); 814 Q_UNUSED(event);
746 int txt_h = fontMetrics().height(); 815 int txt_h = viewOptions().fontMetrics.height();
747 int sep_sz = separatorSize(); 816 int sep_sz = GetSeparatorSize();
748 int w = width(); 817 int w = qMax(m_minimum_width, viewport()->width());
749 int h = height() - 1; 818 int h = qMax(m_minimum_height, viewport()->height());
750 int col_w = (w - 33 * sep_sz) / 32; 819 int nr_bits = 32;
751 int hdr_h = headerHeight(); 820 int col_w = (w - (nr_bits + 1) * sep_sz) / nr_bits;
752 int gap_h = gapHeight(); 821 int hdr_h = GetHeaderHeight();
753 int tot_w = 33 * sep_sz + 32 * col_w; 822 int gap_h = GetGapHeight();
754 int margin = marginSize(); 823 int tot_w = (nr_bits + 1) * sep_sz + nr_bits * col_w;
755 int txt_sep = textSep(); 824 int margin = GetMarginSize();
825 int txt_sep = GetHeaderTextSep();
756 int tot_hdr_sz = 2 * sep_sz + hdr_h; 826 int tot_hdr_sz = 2 * sep_sz + hdr_h;
757 // computer xshift 827
758 int x_shift = (w - tot_w) / 2; 828 int x_shift = (w - tot_w) / 2;
759#define ith_col_x(i) (x_shift + (i) * (sep_sz + col_w)) 829#define ith_col_x(i) (x_shift + (i) * (sep_sz + col_w))
760 830
761 QPainter painter(this); 831 QPainter painter(viewport());
762 QBrush back_brush = palette().base(); 832 painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
763 QBrush line_brush = palette().dark(); 833 painter.translate(-horizontalScrollBar()->value(), -verticalScrollBar()->value());
834 QStyleOptionViewItem option = viewOptions();
835 QBrush back_brush = option.palette.base();
836 QBrush line_brush = option.palette.dark();
764 837
765 // fill interesting zone with base 838 // fill interesting zone with base
839 painter.fillRect(event->rect(), option.palette.window());
766 painter.fillRect(x_shift, 0, tot_w, h, back_brush); 840 painter.fillRect(x_shift, 0, tot_w, h, back_brush);
767 841
768 // draw top and bottom lines 842 // draw top and bottom lines
769 painter.setPen(QPen(palette().dark(), sep_sz)); 843 painter.setPen(QPen(line_brush, sep_sz));
770 painter.fillRect(x_shift, 0, tot_w, sep_sz, line_brush); 844 painter.fillRect(x_shift, 0, tot_w, sep_sz, line_brush);
771 painter.fillRect(x_shift, h - sep_sz, tot_w, sep_sz, line_brush); 845 painter.fillRect(x_shift, h - sep_sz, tot_w, sep_sz, line_brush);
772 // draw intemediate lines 846 // draw intemediate lines
@@ -776,38 +850,76 @@ void RegSexyDisplay::paintEvent(QPaintEvent *event)
776 painter.fillRect(ith_col_x(0), sep_sz + hdr_h, tot_w, sep_sz, line_brush); 850 painter.fillRect(ith_col_x(0), sep_sz + hdr_h, tot_w, sep_sz, line_brush);
777 painter.fillRect(ith_col_x(0), tot_hdr_sz + gap_h, tot_w, sep_sz, line_brush); 851 painter.fillRect(ith_col_x(0), tot_hdr_sz + gap_h, tot_w, sep_sz, line_brush);
778 // redraw some lines but wider 852 // redraw some lines but wider
779 for(int i = 4; i < 32; i += 4) 853 for(int i = 4; i < nr_bits; i += 4)
780 painter.fillRect(ith_col_x(i) - sep_sz, 0, 3 * sep_sz, tot_hdr_sz, line_brush); 854 painter.fillRect(ith_col_x(i) - sep_sz, 0, 3 * sep_sz, tot_hdr_sz, line_brush);
781 // draw numbers in the header 855 // draw numbers in the header
782 painter.setPen(palette().brush(QPalette::ButtonText).color()); 856 painter.setPen(palette().brush(QPalette::ButtonText).color());
783 for(int i = 0; i < 32; i++) 857 for(int i = 0; i < nr_bits; i++)
784 { 858 {
785 QRect r(ith_col_x(i), sep_sz + margin, col_w, txt_h); 859 QRect r(ith_col_x(i), sep_sz + margin, col_w, txt_h);
786 painter.drawText(r, Qt::AlignCenter, QString("%1").arg((31 - i) / 10)); 860 painter.drawText(r, Qt::AlignCenter, QString("%1").arg((nr_bits - 1 - i) / 10));
787 r.translate(0, txt_h + txt_sep); 861 r.translate(0, txt_h + txt_sep);
788 painter.drawText(r, Qt::AlignCenter, QString("%1").arg((31 - i) % 10)); 862 painter.drawText(r, Qt::AlignCenter, QString("%1").arg((nr_bits - 1 - i) % 10));
789 } 863 }
790 // display content 864 // display content
791 for(size_t i = 0; i < m_reg.GetReg().field.size(); i++) 865 if(model())
792 { 866 {
793 const soc_reg_field_t& field = m_reg.GetReg().field[i]; 867 for(int i = 0; i < model()->rowCount(); i++)
794 QRect r(QPoint(ith_col_x(31 - field.last_bit) + sep_sz, tot_hdr_sz), 868 {
795 QPoint(ith_col_x(32 - field.first_bit), h - sep_sz)); 869 QVariant vrange = model()->data(model()->index(i, 0, rootIndex()));
796 painter.fillRect(r.x() - sep_sz, r.y(), sep_sz, r.height(), line_brush); 870 if(!vrange.canConvert< SocFieldBitRange >())
797 painter.fillRect(r.right(), r.y(), sep_sz, r.height(), line_brush); 871 continue;
798 r.setY(r.y() + gap_h + sep_sz); 872 SocFieldBitRange range = vrange.value< SocFieldBitRange >();
799 // draw rotated text 873 QString name = model()->data(model()->index(i, 1, rootIndex())).toString();
800 painter.save(); 874 QRect r(QPoint(ith_col_x(nr_bits - 1 - range.GetLastBit()) + sep_sz, tot_hdr_sz),
801 painter.translate(r.bottomLeft()); 875 QPoint(ith_col_x(nr_bits - range.GetFirstBit()), h - sep_sz));
802 painter.rotate(-90); 876 painter.fillRect(r.x() - sep_sz, r.y(), sep_sz, r.height(), line_brush);
803 //painter.fillRect(QRect(0, 0, r.height(), r.width()), QBrush(Qt::red)); 877 painter.fillRect(r.right(), r.y(), sep_sz, r.height(), line_brush);
804 QRect r2(0, 0, r.height(), r.width()); 878 r.setY(r.y() + gap_h + sep_sz);
805 painter.drawText(r2, Qt::AlignCenter, QString::fromStdString(field.name)); 879 // draw rotated text
806 painter.restore(); 880 painter.save();
881 painter.translate(r.bottomLeft());
882 painter.rotate(-90);
883 //painter.fillRect(QRect(0, 0, r.height(), r.width()), QBrush(Qt::red));
884 QRect r2(0, 0, r.height(), r.width());
885 painter.drawText(r2, Qt::AlignCenter, name);
886 painter.restore();
887 }
807 } 888 }
808#undef ith_col_x 889#undef ith_col_x
809} 890}
810 891
892void RegSexyDisplay2::RecomputeGeometry()
893{
894 if(!m_is_dirty)
895 return;
896 /* height: header + gap + sep + content + sep */
897 m_minimum_height = 0;
898 m_minimum_height += GetHeaderHeight() + GetGapHeight();
899 m_minimum_height += 2 * GetSeparatorSize() + GetMaxContentHeight();
900 /* width: sep + (col + sep) * n */
901 m_minimum_width = GetSeparatorSize() * 33 + GetColumnWidth() * 32;
902 m_is_dirty = false;
903 viewport()->update();
904}
905
906void RegSexyDisplay2::resizeEvent(QResizeEvent*)
907{
908 m_is_dirty = true;
909 RecomputeGeometry();
910 updateGeometries();
911}
912
913void RegSexyDisplay2::updateGeometries()
914{
915 horizontalScrollBar()->setSingleStep(1);
916 horizontalScrollBar()->setPageStep(viewport()->width());
917 horizontalScrollBar()->setRange(0, qMax(0, m_minimum_width - viewport()->width()));
918 verticalScrollBar()->setSingleStep(1);
919 verticalScrollBar()->setPageStep(viewport()->height());
920 verticalScrollBar()->setRange(0, qMax(0, m_minimum_height - viewport()->height()));
921}
922
811/** 923/**
812 * GrowingTableView 924 * GrowingTableView
813 */ 925 */
@@ -831,7 +943,6 @@ void GrowingTableView::DataChanged(const QModelIndex& tl, const QModelIndex& br)
831{ 943{
832 Q_UNUSED(tl); 944 Q_UNUSED(tl);
833 Q_UNUSED(br); 945 Q_UNUSED(br);
834 resizeRowsToContents();
835 resizeColumnsToContents(); 946 resizeColumnsToContents();
836 int h = contentsMargins().top() + contentsMargins().bottom(); 947 int h = contentsMargins().top() + contentsMargins().bottom();
837 h += horizontalHeader()->height(); 948 h += horizontalHeader()->height();
diff --git a/utils/regtools/qeditor/utils.h b/utils/regtools/qeditor/utils.h
index c78b0a40e4..078f3a85d7 100644
--- a/utils/regtools/qeditor/utils.h
+++ b/utils/regtools/qeditor/utils.h
@@ -37,6 +37,7 @@
37#include <QStyledItemDelegate> 37#include <QStyledItemDelegate>
38#include <QComboBox> 38#include <QComboBox>
39#include <QFileDialog> 39#include <QFileDialog>
40#include <QScrollBar>
40#include "settings.h" 41#include "settings.h"
41#include "backend.h" 42#include "backend.h"
42 43
@@ -292,28 +293,77 @@ protected:
292 bool m_read_only; 293 bool m_read_only;
293}; 294};
294 295
295class RegSexyDisplay : public QWidget 296class RegSexyDisplay2 : public QAbstractItemView
296{ 297{
297 Q_OBJECT 298 Q_OBJECT
298public: 299public:
299 RegSexyDisplay(const SocRegRef& reg, QWidget *parent = 0); 300 RegSexyDisplay2(QWidget *parent = 0);
301 virtual QModelIndex indexAt(const QPoint& point) const;
302 virtual void scrollTo(const QModelIndex& index, ScrollHint hint = EnsureVisible);
303 virtual QRect visualRect(const QModelIndex& index ) const;
304 virtual void setModel(QAbstractItemModel *model);
300 305
301 QSize minimumSizeHint() const; 306protected slots:
302 QSize sizeHint() const; 307 virtual void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
308 virtual void rowsInserted(const QModelIndex &parent, int start, int end);
309 virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
310 virtual void scrollContentsBy(int dx, int dy);
311 virtual void updateGeometries();
303 312
304protected: 313protected:
305 int marginSize() const; 314 int GetMarginSize() const; // margin in cells
306 int separatorSize() const; 315 int GetSeparatorSize() const; // size of lines betweens cells
307 int columnWidth() const; 316 int GetColumnWidth() const; // width of a 1-bit column (excluding separators)
308 int headerHeight() const; 317 int GetHeaderHeight() const; // height of the header (excluding separators)
309 int gapHeight() const; 318 int GetGapHeight() const; // height of gap between header and fields
310 int maxContentHeight() const; 319 int GetMaxContentHeight() const; // maximum height of field columns
311 int textSep() const; 320 int GetHeaderTextSep() const; // height between digits in header
312 void paintEvent(QPaintEvent *event); 321 void RecomputeGeometry();
313 322
314private: 323 virtual bool isIndexHidden(const QModelIndex& index) const;
315 SocRegRef m_reg; 324 virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
316 mutable QSize m_size; 325 virtual void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags);
326 virtual int verticalOffset() const;
327 virtual int horizontalOffset() const;
328 virtual QRegion visualRegionForSelection(const QItemSelection& selection) const;
329 virtual void paintEvent(QPaintEvent *event);
330 virtual void resizeEvent(QResizeEvent* event);
331
332 bool m_is_dirty;
333 int m_minimum_width, m_minimum_height;
334};
335
336/**
337 * The Qt designers chose to make QAbstractItemView a QAbstractScrollArea, so
338 * that the table scrolls when it doesn't fit. This might be a problem when
339 * one wants to put several tables on top of another, and the whole set into a
340 * big scrollable area, because QAbstractScrollArea provides dummy values as
341 * (minimum) size hints...So the big scroll area has no way of knowing the actual
342 * size of the widget inside and it ends being a scrollable table inside another
343 * scrollable, which is just super weird.
344 * The Unscroll<T> class provides a workaround this behaviour: it expects T
345 * to derive from QAbstractScrollArea and provides correct (minimum) size hints,
346 * based on the value of the scroll bars.
347 */
348template<typename T>
349class Unscroll : public T
350{
351public:
352 Unscroll(QWidget *parent = 0):T(parent) {}
353 virtual QSize sizeHint() const
354 {
355 QScrollBar *hsb = this->horizontalScrollBar();
356 QScrollBar *vsb = this->verticalScrollBar();
357 int w = hsb->maximum() - hsb->minimum() + hsb->pageStep();
358 int h = vsb->maximum() - vsb->minimum() + vsb->pageStep();
359 QMargins m = this->contentsMargins();
360 return QSize(m.left() + w + m.right(), m.top() + h + m.bottom());
361 }
362
363 virtual QSize minimumSizeHint() const
364 {
365 return sizeHint();
366 }
317}; 367};
318 368
319class GrowingTableView : public QTableView 369class GrowingTableView : public QTableView