Replace QAbstractItemView::viewOptions with initViewItemOption

viewOptions returned a QStyleOptionViewItem object. Such a method
can never support newer versions of the option structure.

Most styleable QWidget classes provide a virtual method
initStyleOption that initializes the option object passed in as a
pointer, e.g QFrame, QAbstractSpinBox, or QComboBox.

Follow that API convention, but name it initViewItemOption, as the
QStyleOptionViewItem struct contains information about the item as
well as the widget itelf.

This is a source incompatible change that will go unnoticed unless
existing subclasses mark their overrides as 'override', or call
the removed QAbstractItemView::viewOption virtual function.

[ChangeLog][QtWidgets][QAbstractItemView] The virtual viewOptions
method that previously returned a QStyleOptionViewItem object has
been renamed to initViewItemOption, and initializes a
QStyleOptionViewItem object that's passed in through a pointer.

Change-Id: Ie058702aed42d77274fa3c4abb43ba302e57e348
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
Volker Hilsheimer 2020-08-16 13:55:11 +02:00
parent 70f7c484c3
commit c501e09efa
15 changed files with 122 additions and 85 deletions

View File

@ -137,7 +137,9 @@ QModelIndex PieView::indexAt(const QPoint &point) const
}
}
} else {
double itemHeight = QFontMetrics(viewOptions().font).height();
QStyleOptionViewItem option;
initViewItemOption(&option);
double itemHeight = QFontMetrics(option.font).height();
int listItem = int((wy - margin) / itemHeight);
int validRow = 0;
@ -193,8 +195,9 @@ QRect PieView::itemRect(const QModelIndex &index) const
switch (index.column()) {
case 0: {
const qreal itemHeight = QFontMetricsF(viewOptions().font).height();
QStyleOptionViewItem option;
initViewItemOption(&option);
const qreal itemHeight = QFontMetricsF(option.font).height();
return QRect(totalSize,
qRound(margin + listItem * itemHeight),
totalSize - margin, qRound(itemHeight));
@ -306,7 +309,8 @@ QModelIndex PieView::moveCursor(QAbstractItemView::CursorAction cursorAction,
void PieView::paintEvent(QPaintEvent *event)
{
QItemSelectionModel *selections = selectionModel();
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
QBrush background = option.palette.base();
QPen foreground(option.palette.color(QPalette::WindowText));
@ -363,7 +367,9 @@ void PieView::paintEvent(QPaintEvent *event)
if (value > 0.0) {
QModelIndex labelIndex = model()->index(row, 0, rootIndex());
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
option.rect = visualRect(labelIndex);
if (selections->isSelected(labelIndex))
option.state |= QStyle::State_Selected;

View File

@ -1718,7 +1718,8 @@ bool QAbstractItemView::viewportEvent(QEvent *event)
case QEvent::WhatsThis: {
QHelpEvent *he = static_cast<QHelpEvent*>(event);
const QModelIndex index = indexAt(he->pos());
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
option.rect = visualRect(index);
option.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
@ -1931,7 +1932,8 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event)
emit clicked(index);
if (edited)
return;
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
if (d->pressedAlreadySelected)
option.state |= QStyle::State_Selected;
if ((d->model->flags(index) & Qt::ItemIsEnabled)
@ -2720,7 +2722,8 @@ void QAbstractItemView::updateEditorGeometries()
d->executePostedLayout();
return;
}
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
QEditorIndexHash::iterator it = d->editorIndexHash.begin();
QWidgetList editorsToRelease;
QWidgetList editorsToHide;
@ -3018,7 +3021,9 @@ QSize QAbstractItemView::sizeHintForIndex(const QModelIndex &index) const
if (!d->isIndexValid(index))
return QSize();
const auto delegate = d->delegateForIndex(index);
return delegate ? delegate->sizeHint(viewOptions(), index) : QSize();
QStyleOptionViewItem option;
initViewItemOption(&option);
return delegate ? delegate->sizeHint(option, index) : QSize();
}
/*!
@ -3046,7 +3051,8 @@ int QAbstractItemView::sizeHintForRow(int row) const
ensurePolished();
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
int height = 0;
int colCount = d->model->columnCount(d->root);
for (int c = 0; c < colCount; ++c) {
@ -3076,7 +3082,8 @@ int QAbstractItemView::sizeHintForColumn(int column) const
ensurePolished();
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
int width = 0;
int rows = d->model->rowCount(d->root);
for (int r = 0; r < rows; ++r) {
@ -3098,7 +3105,8 @@ int QAbstractItemView::sizeHintForColumn(int column) const
void QAbstractItemView::openPersistentEditor(const QModelIndex &index)
{
Q_D(QAbstractItemView);
QStyleOptionViewItem options = viewOptions();
QStyleOptionViewItem options;
initViewItemOption(&options);
options.rect = visualRect(index);
options.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
@ -3688,41 +3696,46 @@ void QAbstractItemView::startDrag(Qt::DropActions supportedActions)
#endif // QT_CONFIG(draganddrop)
/*!
Returns a QStyleOptionViewItem structure populated with the view's
palette, font, state, alignments etc.
\since 6.0
Initialize the \a option structure with the view's palette, font, state,
alignments etc.
\note Implementations of this methods should check the \l{QStyleOption::}
version of the structure received, populate all members the implementation
is familiar with, and set the version member to the one supported by the
implementation before returning.
*/
QStyleOptionViewItem QAbstractItemView::viewOptions() const
void QAbstractItemView::initViewItemOption(QStyleOptionViewItem *option) const
{
Q_D(const QAbstractItemView);
QStyleOptionViewItem option;
option.initFrom(this);
option.state &= ~QStyle::State_MouseOver;
option.font = font();
option->initFrom(this);
option->state &= ~QStyle::State_MouseOver;
option->font = font();
// On mac the focus appearance follows window activation
// not widget activation
if (!hasFocus())
option.state &= ~QStyle::State_Active;
option->state &= ~QStyle::State_Active;
option.state &= ~QStyle::State_HasFocus;
option->state &= ~QStyle::State_HasFocus;
if (d->iconSize.isValid()) {
option.decorationSize = d->iconSize;
option->decorationSize = d->iconSize;
} else {
int pm = style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, this);
option.decorationSize = QSize(pm, pm);
option->decorationSize = QSize(pm, pm);
}
option.decorationPosition = QStyleOptionViewItem::Left;
option.decorationAlignment = Qt::AlignCenter;
option.displayAlignment = Qt::AlignLeft|Qt::AlignVCenter;
option.textElideMode = d->textElideMode;
option.rect = QRect();
option.showDecorationSelected = style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, nullptr, this);
option->decorationPosition = QStyleOptionViewItem::Left;
option->decorationAlignment = Qt::AlignCenter;
option->displayAlignment = Qt::AlignLeft|Qt::AlignVCenter;
option->textElideMode = d->textElideMode;
option->rect = QRect();
option->showDecorationSelected = style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, nullptr, this);
if (d->wrapItemText)
option.features = QStyleOptionViewItem::WrapText;
option.locale = locale();
option.locale.setNumberOptions(QLocale::OmitGroupSeparator);
option.widget = this;
return option;
option->features = QStyleOptionViewItem::WrapText;
option->locale = locale();
option->locale.setNumberOptions(QLocale::OmitGroupSeparator);
option->widget = this;
}
/*!
@ -4352,7 +4365,8 @@ bool QAbstractItemViewPrivate::sendDelegateEvent(const QModelIndex &index, QEven
{
Q_Q(const QAbstractItemView);
QModelIndex buddy = model->buddy(index);
QStyleOptionViewItem options = q->viewOptions();
QStyleOptionViewItem options;
q->initViewItemOption(&options);
options.rect = q->visualRect(buddy);
options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
QAbstractItemDelegate *delegate = delegateForIndex(index);
@ -4364,7 +4378,8 @@ bool QAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *even
Q_Q(QAbstractItemView);
QModelIndex buddy = model->buddy(index);
QStyleOptionViewItem options = q->viewOptions();
QStyleOptionViewItem options;
q->initViewItemOption(&options);
options.rect = q->visualRect(buddy);
options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
@ -4424,7 +4439,8 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes,
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
QStyleOptionViewItem option = q->viewOptions();
QStyleOptionViewItem option;
q->initViewItemOption(&option);
option.state |= QStyle::State_Selected;
for (int j = 0; j < paintPairs.count(); ++j) {
option.rect = paintPairs.at(j).rect.translated(-r->topLeft());

View File

@ -297,7 +297,7 @@ protected:
virtual void startDrag(Qt::DropActions supportedActions);
#endif
virtual QStyleOptionViewItem viewOptions() const;
virtual void initViewItemOption(QStyleOptionViewItem *option) const;
enum State {
NoState,

View File

@ -971,29 +971,27 @@ void QListView::startDrag(Qt::DropActions supportedActions)
/*!
\reimp
*/
QStyleOptionViewItem QListView::viewOptions() const
void QListView::initViewItemOption(QStyleOptionViewItem *option) const
{
Q_D(const QListView);
QStyleOptionViewItem option = QAbstractItemView::viewOptions();
QAbstractItemView::initViewItemOption(option);
if (!d->iconSize.isValid()) { // otherwise it was already set in abstractitemview
int pm = (d->viewMode == QListView::ListMode
? style()->pixelMetric(QStyle::PM_ListViewIconSize, nullptr, this)
: style()->pixelMetric(QStyle::PM_IconViewIconSize, nullptr, this));
option.decorationSize = QSize(pm, pm);
option->decorationSize = QSize(pm, pm);
}
if (d->viewMode == QListView::IconMode) {
option.showDecorationSelected = false;
option.decorationPosition = QStyleOptionViewItem::Top;
option.displayAlignment = Qt::AlignCenter;
option->showDecorationSelected = false;
option->decorationPosition = QStyleOptionViewItem::Top;
option->displayAlignment = Qt::AlignCenter;
} else {
option.decorationPosition = QStyleOptionViewItem::Left;
option->decorationPosition = QStyleOptionViewItem::Left;
}
if (d->gridSize().isValid()) {
option.rect.setSize(d->gridSize());
option->rect.setSize(d->gridSize());
}
return option;
}
@ -1005,7 +1003,8 @@ void QListView::paintEvent(QPaintEvent *e)
Q_D(QListView);
if (!d->itemDelegate)
return;
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
QPainter painter(d->viewport);
const QList<QModelIndex> toBeRendered =
@ -1555,7 +1554,8 @@ void QListView::updateGeometries()
verticalScrollBar()->setRange(0, 0);
} else {
QModelIndex index = d->model->index(0, d->column, d->root);
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
QSize step = d->itemSize(option, index);
d->commonListView->updateHorizontalScrollBar(step);
d->commonListView->updateVerticalScrollBar(step);
@ -2457,7 +2457,8 @@ QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) c
0, segmentStartRows.count() - 1);
QStyleOptionViewItem options = viewOptions();
QStyleOptionViewItem options;
initViewItemOption(&options);
options.rect.setSize(contentsSize);
QSize size = (uniformItemSizes() && cachedItemSize().isValid())
? cachedItemSize() : itemSize(options, index);
@ -2533,7 +2534,8 @@ void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info)
{
const bool useItemSize = !info.grid.isValid();
const QPoint topLeft = initStaticLayout(info);
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
option.rect = info.bounds;
option.rect.adjust(info.spacing, info.spacing, -info.spacing, -info.spacing);
@ -3007,7 +3009,8 @@ void QIconModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
void QIconModeViewBase::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
if (column() >= topLeft.column() && column() <= bottomRight.column()) {
const QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
const int bottom = qMin(items.count(), bottomRight.row() + 1);
const bool useItemSize = !dd->grid.isValid();
for (int row = topLeft.row(); row < bottom; ++row)
@ -3027,7 +3030,8 @@ bool QIconModeViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int
{
if (info.last >= items.count()) {
//first we create the items
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
for (int row = items.count(); row <= info.last; ++row) {
QSize size = itemSize(option, modelIndex(row));
QListViewItem item(QRect(0, 0, size.width(), size.height()), row); // default pos

View File

@ -170,7 +170,7 @@ protected:
void startDrag(Qt::DropActions supportedActions) override;
#endif // QT_CONFIG(draganddrop)
QStyleOptionViewItem viewOptions() const override;
void initViewItemOption(QStyleOptionViewItem *option) const override;
void paintEvent(QPaintEvent *e) override;
int horizontalOffset() const override;

View File

@ -172,7 +172,7 @@ public:
inline QModelIndex modelIndex(int row) const;
inline int rowCount() const;
inline QStyleOptionViewItem viewOptions() const;
inline void initViewItemOption(QStyleOptionViewItem *option) const;
inline QWidget *viewport() const;
inline QRect clipRect() const;
@ -483,7 +483,7 @@ inline QModelIndex QCommonListViewBase::modelIndex(int row) const
{ return dd->model->index(row, dd->column, dd->root); }
inline int QCommonListViewBase::rowCount() const { return dd->model->rowCount(dd->root); }
inline QStyleOptionViewItem QCommonListViewBase::viewOptions() const { return qq->viewOptions(); }
inline void QCommonListViewBase::initViewItemOption(QStyleOptionViewItem *option) const { qq->initViewItemOption(option); }
inline QWidget *QCommonListViewBase::viewport() const { return dd->viewport; }
inline QRect QCommonListViewBase::clipRect() const { return dd->clipRect(); }

View File

@ -1459,11 +1459,10 @@ void QTableView::scrollContentsBy(int dx, int dy)
/*!
\reimp
*/
QStyleOptionViewItem QTableView::viewOptions() const
void QTableView::initViewItemOption(QStyleOptionViewItem *option) const
{
QStyleOptionViewItem option = QAbstractItemView::viewOptions();
option.showDecorationSelected = true;
return option;
QAbstractItemView::initViewItemOption(option);
option->showDecorationSelected = true;
}
/*!
@ -1473,7 +1472,8 @@ void QTableView::paintEvent(QPaintEvent *event)
{
Q_D(QTableView);
// setup temp variables for the painting
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
const QPoint offset = d->scrollDelayOffset;
const bool showGrid = d->showGrid;
const int gridSize = showGrid ? 1 : 0;
@ -2352,7 +2352,8 @@ int QTableView::sizeHintForRow(int row) const
if (right == -1) // the table don't have enough columns to fill the viewport
right = d->model->columnCount(d->root) - 1;
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
int hint = 0;
QModelIndex index;
@ -2440,7 +2441,8 @@ int QTableView::sizeHintForColumn(int column) const
if (!isVisible() || bottom == -1) // the table don't have enough rows to fill the viewport
bottom = d->model->rowCount(d->root) - 1;
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
int hint = 0;
int rowsProcessed = 0;

View File

@ -145,7 +145,7 @@ protected:
QTableView(QTableViewPrivate &, QWidget *parent);
void scrollContentsBy(int dx, int dy) override;
QStyleOptionViewItem viewOptions() const override;
void initViewItemOption(QStyleOptionViewItem *option) const override;
void paintEvent(QPaintEvent *e) override;
void timerEvent(QTimerEvent *event) override;

View File

@ -1472,7 +1472,8 @@ void QTreeView::drawTree(QPainter *painter, const QRegion &region) const
Q_D(const QTreeView);
const QList<QTreeViewItem> viewItems = d->viewItems;
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
const QStyle::State state = option.state;
d->current = 0;
@ -1834,7 +1835,8 @@ void QTreeView::drawBranches(QPainter *painter, const QRect &rect,
QModelIndex current = parent;
QModelIndex ancestor = current.parent();
QStyleOptionViewItem opt = viewOptions();
QStyleOptionViewItem opt;
initViewItemOption(&opt);
QStyle::State extraFlags = QStyle::State_None;
if (isEnabled())
extraFlags |= QStyle::State_Enabled;
@ -2868,7 +2870,8 @@ int QTreeView::sizeHintForColumn(int column) const
return -1;
ensurePolished();
int w = 0;
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
const QList<QTreeViewItem> viewItems = d->viewItems;
const int maximumProcessRows = d->header->resizeContentsPrecision(); // To avoid this to take forever.
@ -2980,7 +2983,8 @@ int QTreeView::indexRowSizeHint(const QModelIndex &index) const
qSwap(end, start);
int height = -1;
QStyleOptionViewItem option = viewOptions();
QStyleOptionViewItem option;
initViewItemOption(&option);
// ### If we want word wrapping in the items,
// ### we need to go through all the columns
// ### and set the width of the column
@ -3252,7 +3256,8 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons
painter.end();
//and now let's render the editors the editors
QStyleOptionViewItem option = q->viewOptions();
QStyleOptionViewItem option;
q->initViewItemOption(&option);
for (QEditorIndexHash::const_iterator it = editorIndexHash.constBegin(); it != editorIndexHash.constEnd(); ++it) {
QWidget *editor = it.key();
const QModelIndex &index = it.value();

View File

@ -94,13 +94,12 @@ protected:
QListView::resizeEvent(event);
}
QStyleOptionViewItem viewOptions() const override
void initViewItemOption(QStyleOptionViewItem *option) const override
{
QStyleOptionViewItem option = QListView::viewOptions();
option.showDecorationSelected = true;
QListView::initViewItemOption(option);
option->showDecorationSelected = true;
if (combo)
option.font = combo->font();
return option;
option->font = combo->font();
}
void paintEvent(QPaintEvent *e) override

View File

@ -516,8 +516,8 @@ void tst_QAbstractItemView::basic_tests(QAbstractItemView *view)
#if QT_CONFIG(draganddrop)
if (!view->model())
view->startDrag(Qt::CopyAction);
view->viewOptions();
QStyleOptionViewItem option;
view->initViewItemOption(&option);
view->setState(QAbstractItemView::NoState);
QCOMPARE(view->state(), QAbstractItemView::NoState);

View File

@ -843,7 +843,9 @@ class FastEditItemView : public QTableView
public:
QWidget* fastEdit(const QModelIndex &i) // Consider this as QAbstractItemView::edit( )
{
QWidget *v = itemDelegate()->createEditor(viewport(), viewOptions(), i);
QStyleOptionViewItem option;
initViewItemOption(&option);
QWidget *v = itemDelegate()->createEditor(viewport(), option, i);
if (v)
itemDelegate()->setEditorData(v, i);
return v;

View File

@ -84,7 +84,7 @@ public:
using QListView::setSelection;
using QListView::setViewportMargins;
using QListView::startDrag;
using QListView::viewOptions;
using QListView::initViewItemOption;
QRegion getVisualRegionForSelection() const
{
return QListView::visualRegionForSelection(selectionModel()->selection());
@ -2258,10 +2258,11 @@ void tst_QListView::testScrollToWithHidden()
void tst_QListView::testViewOptions()
{
PublicListView view;
QStyleOptionViewItem options = view.viewOptions();
QStyleOptionViewItem options;
view.initViewItemOption(&options);
QCOMPARE(options.decorationPosition, QStyleOptionViewItem::Left);
view.setViewMode(QListView::IconMode);
options = view.viewOptions();
view.initViewItemOption(&options);
QCOMPARE(options.decorationPosition, QStyleOptionViewItem::Top);
}

View File

@ -257,7 +257,7 @@ public:
using QTableView::setSelection;
using QTableView::selectedIndexes;
using QTableView::sizeHintForRow;
using QTableView::viewOptions;
using QTableView::initViewItemOption;
bool checkSignalOrder = false;
public slots:
@ -4523,7 +4523,8 @@ void tst_QTableView::taskQTBUG_10169_sizeHintForRow()
void tst_QTableView::viewOptions()
{
QtTestTableView view;
QStyleOptionViewItem options = view.viewOptions();
QStyleOptionViewItem options;
view.initViewItemOption(&options);
QVERIFY(options.showDecorationSelected);
}

View File

@ -2490,7 +2490,8 @@ void tst_QTreeView::spanningItems()
// size hint
// every second row is un-spanned
QStyleOptionViewItem option = view.viewOptions();
QStyleOptionViewItem option;
view.initViewItemOption(&option);
int w = view.header()->sectionSizeHint(0);
for (int i = 0; i < model.rowCount(QModelIndex()); ++i) {
if (!view.isFirstColumnSpanned(i, QModelIndex())) {