summaryrefslogtreecommitdiffstats
path: root/utils/regtools
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 /utils/regtools
parent2c832968c91cb56e4c252bd8eafb03d7d9c8aeda (diff)
downloadrockbox-c8d3638b9ebc24e4766714da1c9f961e350799c6.tar.gz
rockbox-c8d3638b9ebc24e4766714da1c9f961e350799c6.tar.bz2
rockbox-c8d3638b9ebc24e4766714da1c9f961e350799c6.zip
qeditor: introduce new "sexy register display"
Change-Id: Ib938b4be71d2c7623851dbc3c211f96105077d7d
Diffstat (limited to 'utils/regtools')
-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
QMAKE_EXTRA_TARGETS += libsocdesc
PRE_TARGETDEPS += libsocdesc
-VERSION = 2.0.3
+VERSION = 2.0.4
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
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
raw_val_layout->addWidget(m_raw_val_edit);
raw_val_layout->addStretch();
- m_value_table = new GrowingTableView;
+ m_value_table = new GrowingTableView();
m_value_model = new RegFieldTableModel(m_value_table); // view takes ownership
m_value_model->SetRegister(m_reg.GetReg());
m_value_model->SetReadOnly(read_only);
@@ -208,7 +208,7 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
// FIXME we cannot use setAlternatingRowColors() because we override the
// background color, should it be part of the model ?
- SocFieldCachedItemDelegate *m_table_delegate = new SocFieldCachedItemDelegate(this);
+ m_table_delegate = new SocFieldCachedItemDelegate(this);
m_table_edit_factory = new QItemEditorFactory();
SocFieldCachedEditorCreator *m_table_edit_creator = new SocFieldCachedEditorCreator();
// FIXME see QTBUG-30392
@@ -217,8 +217,10 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
m_table_delegate->setItemEditorFactory(m_table_edit_factory);
m_value_table->setItemDelegate(m_table_delegate);
- m_sexy_display = new RegSexyDisplay(reg_ref, this);
- m_sexy_display->setFont(m_reg_font);
+ m_sexy_display2 = new Unscroll<RegSexyDisplay2>(this);
+ m_sexy_display2->setFont(m_reg_font);
+ m_sexy_display2->setModel(m_value_model);
+ m_sexy_display2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_desc = new QLabel(this);
m_desc->setTextFormat(Qt::RichText);
@@ -228,8 +230,9 @@ RegDisplayPanel::RegDisplayPanel(QWidget *parent, IoBackend *io_backend, const S
right_layout->addLayout(top_layout);
if(raw_val_layout)
right_layout->addLayout(raw_val_layout);
- right_layout->addWidget(m_sexy_display);
+ right_layout->addWidget(m_sexy_display2);
right_layout->addWidget(m_value_table);
+ right_layout->addStretch();
setTitle("Register Description");
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:
const SocRegRef& m_reg;
bool m_allow_write;
RegLineEdit *m_raw_val_edit;
- RegSexyDisplay *m_sexy_display;
+ Unscroll< RegSexyDisplay2 > *m_sexy_display2;
GrowingTableView *m_value_table;
RegFieldTableModel *m_value_model;
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)
top_layout->addLayout(name_layout);
top_layout->addWidget(m_desc_group, 1);
- m_sexy_display = new RegSexyDisplay(m_ref, this);
- m_sexy_display->setFont(m_reg_font);
+ m_value_table = new QTableView(this);
+ m_value_model = new RegFieldTableModel(m_value_table); // view takes ownership
+ m_value_model->SetRegister(m_ref.GetReg());
+ m_value_model->SetReadOnly(true);
+ m_value_table->setModel(m_value_model);
+ m_value_table->verticalHeader()->setVisible(false);
+ m_value_table->horizontalHeader()->setStretchLastSection(true);
+ m_value_table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ // FIXME we cannot use setAlternatingRowColors() because we override the
+ // background color, should it be part of the model ?
+ m_table_delegate = new SocFieldCachedItemDelegate(this);
+ m_value_table->setItemDelegate(m_table_delegate);
+ m_value_table->resizeColumnsToContents();
+
+ m_sexy_display2 = new Unscroll<RegSexyDisplay2>(this);
+ m_sexy_display2->setFont(m_reg_font);
+ m_sexy_display2->setModel(m_value_model);
+ m_sexy_display2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- m_field_table = new QTableWidget;
- m_field_table->setRowCount(m_ref.GetReg().field.size());
- m_field_table->setColumnCount(4);
- for(size_t row = 0; row < m_ref.GetReg().field.size(); row++)
- {
- const soc_reg_field_t& field = m_ref.GetReg().field[row];
- QString bits_str;
- if(field.first_bit == field.last_bit)
- bits_str.sprintf("%d", field.first_bit);
- else
- bits_str.sprintf("%d:%d", field.last_bit, field.first_bit);
- QTableWidgetItem *item = new QTableWidgetItem(bits_str);
- item->setTextAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
- item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
- m_field_table->setItem(row, 1, item);
- item = new QTableWidgetItem(QString(field.name.c_str()));
- item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
- m_field_table->setItem(row, 2, item);
- item = new QTableWidgetItem(QString(field.desc.c_str()));
- item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
- m_field_table->setItem(row, 3, item);
- UpdateWarning(row);
- }
- m_field_table->setHorizontalHeaderItem(0, new QTableWidgetItem(""));
- m_field_table->setHorizontalHeaderItem(1, new QTableWidgetItem("Bits"));
- m_field_table->setHorizontalHeaderItem(2, new QTableWidgetItem("Name"));
- m_field_table->setHorizontalHeaderItem(3, new QTableWidgetItem("Description"));
- m_field_table->verticalHeader()->setVisible(false);
- m_field_table->resizeColumnsToContents();
- m_field_table->horizontalHeader()->setStretchLastSection(true);
QHBoxLayout *field_layout = new QHBoxLayout;
- field_layout->addWidget(m_field_table);
+ field_layout->addWidget(m_value_table);
m_field_group = new QGroupBox("Flags", this);
m_field_group->setLayout(field_layout);
QVBoxLayout *layout = new QVBoxLayout;
layout->addLayout(top_layout, 0);
- layout->addWidget(m_sexy_display, 0);
+ layout->addWidget(m_sexy_display2, 0);
layout->addWidget(m_field_group);
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:
QComboBox *m_formula_combo;
QLineEdit *m_formula_string_edit;
QPushButton *m_formula_string_gen;
- RegSexyDisplay *m_sexy_display;
+ Unscroll< RegSexyDisplay2 > *m_sexy_display2;
MyTextEditor *m_desc_edit;
QGroupBox *m_field_group;
- QTableWidget *m_field_table;
+ QTableView *m_value_table;
+ RegFieldTableModel *m_value_model;
+ QStyledItemDelegate *m_table_delegate;
};
class 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()
}
/**
- * RegSexyDisplay
+ * RegSexyDisplay2
*/
-RegSexyDisplay::RegSexyDisplay(const SocRegRef& reg, QWidget *parent)
- :QWidget(parent), m_reg(reg)
+
+RegSexyDisplay2::RegSexyDisplay2(QWidget *parent)
+ :QAbstractItemView(parent)
+{
+ m_is_dirty = true;
+ // the frame around the register is ugly, disable it
+ setFrameShape(QFrame::NoFrame);
+}
+
+QModelIndex RegSexyDisplay2::indexAt(const QPoint& point) const
+{
+ Q_UNUSED(point);
+ return QModelIndex();
+}
+
+void RegSexyDisplay2::scrollTo(const QModelIndex& index, ScrollHint hint)
+{
+ Q_UNUSED(index);
+ Q_UNUSED(hint);
+}
+
+QRect RegSexyDisplay2::visualRect(const QModelIndex& index) const
+{
+ Q_UNUSED(index);
+ return QRect();
+}
+
+bool RegSexyDisplay2::isIndexHidden(const QModelIndex& index) const
+{
+ Q_UNUSED(index);
+ return false;
+}
+
+QModelIndex RegSexyDisplay2::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
+{
+ Q_UNUSED(cursorAction);
+ Q_UNUSED(modifiers);
+ return QModelIndex();
+}
+
+void RegSexyDisplay2::setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags)
+{
+ Q_UNUSED(rect);
+ Q_UNUSED(flags);
+}
+
+int RegSexyDisplay2::verticalOffset() const
+{
+ return verticalScrollBar()->value();
+}
+
+int RegSexyDisplay2::horizontalOffset() const
+{
+ return horizontalScrollBar()->value();
+}
+
+void RegSexyDisplay2::scrollContentsBy(int dx, int dy)
+{
+ viewport()->scroll(dx, dy);
+}
+
+void RegSexyDisplay2::setModel(QAbstractItemModel *model)
{
- m_size = QSize();
+ QAbstractItemView::setModel(model);
+ m_is_dirty = true;
}
-int RegSexyDisplay::separatorSize() const
+void RegSexyDisplay2::dataChanged(const QModelIndex &topLeft,
+ const QModelIndex &bottomRight)
+{
+ m_is_dirty = true;
+ QAbstractItemView::dataChanged(topLeft, bottomRight);
+}
+
+void RegSexyDisplay2::rowsInserted(const QModelIndex &parent, int start, int end)
+{
+ m_is_dirty = true;
+ QAbstractItemView::rowsInserted(parent, start, end);
+}
+
+void RegSexyDisplay2::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
+{
+ m_is_dirty = true;
+ QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);
+}
+
+int RegSexyDisplay2::GetSeparatorSize() const
{
return 1;
}
-int RegSexyDisplay::marginSize() const
+int RegSexyDisplay2::GetMarginSize() const
{
- return fontMetrics().height() / 3;
+ return viewOptions().fontMetrics.height() / 3;
}
-int RegSexyDisplay::textSep() const
+int RegSexyDisplay2::GetHeaderTextSep() const
{
- return marginSize() / 2;
+ return GetMarginSize() / 2;
}
-int RegSexyDisplay::headerHeight() const
+int RegSexyDisplay2::GetHeaderHeight() const
{
- return 2 * marginSize() + textSep() + 2 * fontMetrics().height();
+ return 2 * GetMarginSize() + GetHeaderTextSep() + 2 * viewOptions().fontMetrics.height();
}
-int RegSexyDisplay::columnWidth() const
+int RegSexyDisplay2::GetColumnWidth() const
{
- return 2 * marginSize() + fontMetrics().height();
+ return 2 * GetMarginSize() + viewOptions().fontMetrics.height();
}
-int RegSexyDisplay::maxContentHeight() const
+int RegSexyDisplay2::GetMaxContentHeight() const
{
int max = 0;
- QFontMetrics metrics = fontMetrics();
- for(size_t i = 0; i < m_reg.GetReg().field.size(); i++)
+ QFontMetrics metrics = viewOptions().fontMetrics;
+ if(model())
{
- QString s = QString::fromStdString(m_reg.GetReg().field[i].name);
- // add extra spaces arounds
- s = " " + s + " ";
- max = qMax(max, metrics.boundingRect(s).width());
+ for(int i = 0; i < model()->rowCount(); i++)
+ {
+ QModelIndex index = model()->index(i, 1, rootIndex());
+ QString s = model()->data(index).toString();
+ max = qMax(max, metrics.boundingRect(s).width());
+ }
}
- return 2 * marginSize() + max;
-}
-
-int RegSexyDisplay::gapHeight() const
-{
- return marginSize() / 2;
+ return 2 * GetMarginSize() + max;
}
-QSize RegSexyDisplay::minimumSizeHint() const
+int RegSexyDisplay2::GetGapHeight() const
{
- /* cache computation because it's expensive */
- if(m_size.isValid())
- return m_size;
- /* width: display 32 columns + 33 vertical separators */
- m_size.setWidth(32 * columnWidth() + 33 * separatorSize());
- /* height: one separator + two digits + one separator + margin + separator
- * + names + separator */
- m_size.setHeight(4 * separatorSize() + headerHeight() + gapHeight() + maxContentHeight());
- return m_size;
+ return GetMarginSize() / 2;
}
-QSize RegSexyDisplay::sizeHint() const
+QRegion RegSexyDisplay2::visualRegionForSelection(const QItemSelection& selection) const
{
- return minimumSizeHint();
+ Q_UNUSED(selection);
+ return QRegion();
}
-void RegSexyDisplay::paintEvent(QPaintEvent *event)
+void RegSexyDisplay2::paintEvent(QPaintEvent *event)
{
- // FIXME could be optimised with QStaticText
Q_UNUSED(event);
- int txt_h = fontMetrics().height();
- int sep_sz = separatorSize();
- int w = width();
- int h = height() - 1;
- int col_w = (w - 33 * sep_sz) / 32;
- int hdr_h = headerHeight();
- int gap_h = gapHeight();
- int tot_w = 33 * sep_sz + 32 * col_w;
- int margin = marginSize();
- int txt_sep = textSep();
+ int txt_h = viewOptions().fontMetrics.height();
+ int sep_sz = GetSeparatorSize();
+ int w = qMax(m_minimum_width, viewport()->width());
+ int h = qMax(m_minimum_height, viewport()->height());
+ int nr_bits = 32;
+ int col_w = (w - (nr_bits + 1) * sep_sz) / nr_bits;
+ int hdr_h = GetHeaderHeight();
+ int gap_h = GetGapHeight();
+ int tot_w = (nr_bits + 1) * sep_sz + nr_bits * col_w;
+ int margin = GetMarginSize();
+ int txt_sep = GetHeaderTextSep();
int tot_hdr_sz = 2 * sep_sz + hdr_h;
- // computer xshift
+
int x_shift = (w - tot_w) / 2;
#define ith_col_x(i) (x_shift + (i) * (sep_sz + col_w))
- QPainter painter(this);
- QBrush back_brush = palette().base();
- QBrush line_brush = palette().dark();
+ QPainter painter(viewport());
+ painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+ painter.translate(-horizontalScrollBar()->value(), -verticalScrollBar()->value());
+ QStyleOptionViewItem option = viewOptions();
+ QBrush back_brush = option.palette.base();
+ QBrush line_brush = option.palette.dark();
// fill interesting zone with base
+ painter.fillRect(event->rect(), option.palette.window());
painter.fillRect(x_shift, 0, tot_w, h, back_brush);
// draw top and bottom lines
- painter.setPen(QPen(palette().dark(), sep_sz));
+ painter.setPen(QPen(line_brush, sep_sz));
painter.fillRect(x_shift, 0, tot_w, sep_sz, line_brush);
painter.fillRect(x_shift, h - sep_sz, tot_w, sep_sz, line_brush);
// draw intemediate lines
@@ -776,38 +850,76 @@ void RegSexyDisplay::paintEvent(QPaintEvent *event)
painter.fillRect(ith_col_x(0), sep_sz + hdr_h, tot_w, sep_sz, line_brush);
painter.fillRect(ith_col_x(0), tot_hdr_sz + gap_h, tot_w, sep_sz, line_brush);
// redraw some lines but wider
- for(int i = 4; i < 32; i += 4)
+ for(int i = 4; i < nr_bits; i += 4)
painter.fillRect(ith_col_x(i) - sep_sz, 0, 3 * sep_sz, tot_hdr_sz, line_brush);
// draw numbers in the header
painter.setPen(palette().brush(QPalette::ButtonText).color());
- for(int i = 0; i < 32; i++)
+ for(int i = 0; i < nr_bits; i++)
{
QRect r(ith_col_x(i), sep_sz + margin, col_w, txt_h);
- painter.drawText(r, Qt::AlignCenter, QString("%1").arg((31 - i) / 10));
+ painter.drawText(r, Qt::AlignCenter, QString("%1").arg((nr_bits - 1 - i) / 10));
r.translate(0, txt_h + txt_sep);
- painter.drawText(r, Qt::AlignCenter, QString("%1").arg((31 - i) % 10));
+ painter.drawText(r, Qt::AlignCenter, QString("%1").arg((nr_bits - 1 - i) % 10));
}
// display content
- for(size_t i = 0; i < m_reg.GetReg().field.size(); i++)
+ if(model())
{
- const soc_reg_field_t& field = m_reg.GetReg().field[i];
- QRect r(QPoint(ith_col_x(31 - field.last_bit) + sep_sz, tot_hdr_sz),
- QPoint(ith_col_x(32 - field.first_bit), h - sep_sz));
- painter.fillRect(r.x() - sep_sz, r.y(), sep_sz, r.height(), line_brush);
- painter.fillRect(r.right(), r.y(), sep_sz, r.height(), line_brush);
- r.setY(r.y() + gap_h + sep_sz);
- // draw rotated text
- painter.save();
- painter.translate(r.bottomLeft());
- painter.rotate(-90);
- //painter.fillRect(QRect(0, 0, r.height(), r.width()), QBrush(Qt::red));
- QRect r2(0, 0, r.height(), r.width());
- painter.drawText(r2, Qt::AlignCenter, QString::fromStdString(field.name));
- painter.restore();
+ for(int i = 0; i < model()->rowCount(); i++)
+ {
+ QVariant vrange = model()->data(model()->index(i, 0, rootIndex()));
+ if(!vrange.canConvert< SocFieldBitRange >())
+ continue;
+ SocFieldBitRange range = vrange.value< SocFieldBitRange >();
+ QString name = model()->data(model()->index(i, 1, rootIndex())).toString();
+ QRect r(QPoint(ith_col_x(nr_bits - 1 - range.GetLastBit()) + sep_sz, tot_hdr_sz),
+ QPoint(ith_col_x(nr_bits - range.GetFirstBit()), h - sep_sz));
+ painter.fillRect(r.x() - sep_sz, r.y(), sep_sz, r.height(), line_brush);
+ painter.fillRect(r.right(), r.y(), sep_sz, r.height(), line_brush);
+ r.setY(r.y() + gap_h + sep_sz);
+ // draw rotated text
+ painter.save();
+ painter.translate(r.bottomLeft());
+ painter.rotate(-90);
+ //painter.fillRect(QRect(0, 0, r.height(), r.width()), QBrush(Qt::red));
+ QRect r2(0, 0, r.height(), r.width());
+ painter.drawText(r2, Qt::AlignCenter, name);
+ painter.restore();
+ }
}
#undef ith_col_x
}
+void RegSexyDisplay2::RecomputeGeometry()
+{
+ if(!m_is_dirty)
+ return;
+ /* height: header + gap + sep + content + sep */
+ m_minimum_height = 0;
+ m_minimum_height += GetHeaderHeight() + GetGapHeight();
+ m_minimum_height += 2 * GetSeparatorSize() + GetMaxContentHeight();
+ /* width: sep + (col + sep) * n */
+ m_minimum_width = GetSeparatorSize() * 33 + GetColumnWidth() * 32;
+ m_is_dirty = false;
+ viewport()->update();
+}
+
+void RegSexyDisplay2::resizeEvent(QResizeEvent*)
+{
+ m_is_dirty = true;
+ RecomputeGeometry();
+ updateGeometries();
+}
+
+void RegSexyDisplay2::updateGeometries()
+{
+ horizontalScrollBar()->setSingleStep(1);
+ horizontalScrollBar()->setPageStep(viewport()->width());
+ horizontalScrollBar()->setRange(0, qMax(0, m_minimum_width - viewport()->width()));
+ verticalScrollBar()->setSingleStep(1);
+ verticalScrollBar()->setPageStep(viewport()->height());
+ verticalScrollBar()->setRange(0, qMax(0, m_minimum_height - viewport()->height()));
+}
+
/**
* GrowingTableView
*/
@@ -831,7 +943,6 @@ void GrowingTableView::DataChanged(const QModelIndex& tl, const QModelIndex& br)
{
Q_UNUSED(tl);
Q_UNUSED(br);
- resizeRowsToContents();
resizeColumnsToContents();
int h = contentsMargins().top() + contentsMargins().bottom();
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 @@
#include <QStyledItemDelegate>
#include <QComboBox>
#include <QFileDialog>
+#include <QScrollBar>
#include "settings.h"
#include "backend.h"
@@ -292,28 +293,77 @@ protected:
bool m_read_only;
};
-class RegSexyDisplay : public QWidget
+class RegSexyDisplay2 : public QAbstractItemView
{
Q_OBJECT
public:
- RegSexyDisplay(const SocRegRef& reg, QWidget *parent = 0);
+ RegSexyDisplay2(QWidget *parent = 0);
+ virtual QModelIndex indexAt(const QPoint& point) const;
+ virtual void scrollTo(const QModelIndex& index, ScrollHint hint = EnsureVisible);
+ virtual QRect visualRect(const QModelIndex& index ) const;
+ virtual void setModel(QAbstractItemModel *model);
- QSize minimumSizeHint() const;
- QSize sizeHint() const;
+protected slots:
+ virtual void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
+ virtual void rowsInserted(const QModelIndex &parent, int start, int end);
+ virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
+ virtual void scrollContentsBy(int dx, int dy);
+ virtual void updateGeometries();
protected:
- int marginSize() const;
- int separatorSize() const;
- int columnWidth() const;
- int headerHeight() const;
- int gapHeight() const;
- int maxContentHeight() const;
- int textSep() const;
- void paintEvent(QPaintEvent *event);
-
-private:
- SocRegRef m_reg;
- mutable QSize m_size;
+ int GetMarginSize() const; // margin in cells
+ int GetSeparatorSize() const; // size of lines betweens cells
+ int GetColumnWidth() const; // width of a 1-bit column (excluding separators)
+ int GetHeaderHeight() const; // height of the header (excluding separators)
+ int GetGapHeight() const; // height of gap between header and fields
+ int GetMaxContentHeight() const; // maximum height of field columns
+ int GetHeaderTextSep() const; // height between digits in header
+ void RecomputeGeometry();
+
+ virtual bool isIndexHidden(const QModelIndex& index) const;
+ virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
+ virtual void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags);
+ virtual int verticalOffset() const;
+ virtual int horizontalOffset() const;
+ virtual QRegion visualRegionForSelection(const QItemSelection& selection) const;
+ virtual void paintEvent(QPaintEvent *event);
+ virtual void resizeEvent(QResizeEvent* event);
+
+ bool m_is_dirty;
+ int m_minimum_width, m_minimum_height;
+};
+
+/**
+ * The Qt designers chose to make QAbstractItemView a QAbstractScrollArea, so
+ * that the table scrolls when it doesn't fit. This might be a problem when
+ * one wants to put several tables on top of another, and the whole set into a
+ * big scrollable area, because QAbstractScrollArea provides dummy values as
+ * (minimum) size hints...So the big scroll area has no way of knowing the actual
+ * size of the widget inside and it ends being a scrollable table inside another
+ * scrollable, which is just super weird.
+ * The Unscroll<T> class provides a workaround this behaviour: it expects T
+ * to derive from QAbstractScrollArea and provides correct (minimum) size hints,
+ * based on the value of the scroll bars.
+ */
+template<typename T>
+class Unscroll : public T
+{
+public:
+ Unscroll(QWidget *parent = 0):T(parent) {}
+ virtual QSize sizeHint() const
+ {
+ QScrollBar *hsb = this->horizontalScrollBar();
+ QScrollBar *vsb = this->verticalScrollBar();
+ int w = hsb->maximum() - hsb->minimum() + hsb->pageStep();
+ int h = vsb->maximum() - vsb->minimum() + vsb->pageStep();
+ QMargins m = this->contentsMargins();
+ return QSize(m.left() + w + m.right(), m.top() + h + m.bottom());
+ }
+
+ virtual QSize minimumSizeHint() const
+ {
+ return sizeHint();
+ }
};
class GrowingTableView : public QTableView