QAbstractItemView: add virtual itemDelegateForIndex
and obsolete itemDelegate(index), which the new function replaces. This allows itemviews to override the item delegate per index. The existing APIs to set delegates for rows and columns doesn't work for tree views, or other views where the delegate should depend on the parent index as well. Adjust all itemview code that accessed the QAIVPrivate's relevant data structures directly to go through the virtual function. [ChangeLog][QtWidgets][QAbstractItemView] The itemDelegate(QModelIndex) member function has been made obsolete, and has been replaced by a new virtual itemDelegateForIndex(QModelIndex) member function that can be overridden to give subclasses control over which item delegate should be used for an index. Change-Id: Ib03529c38797386d3a1d4cf3c5646e911d95daf5 Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
This commit is contained in:
parent
605d2163f1
commit
3f8c4ae047
@ -1006,10 +1006,21 @@ QAbstractItemDelegate *QAbstractItemView::itemDelegateForColumn(int column) cons
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QAbstractItemDelegate *QAbstractItemView::itemDelegate(const QModelIndex &index) const
|
||||
\obsolete Use itemDelegateForIndex() instead.
|
||||
Returns the item delegate used by this view and model for
|
||||
the given \a index.
|
||||
*/
|
||||
QAbstractItemDelegate *QAbstractItemView::itemDelegate(const QModelIndex &index) const
|
||||
|
||||
/*!
|
||||
\since 6.0
|
||||
|
||||
Returns the item delegate used by this view and model for
|
||||
the given \a index.
|
||||
|
||||
\sa setItemDelegate(), setItemDelegateForRow(), setItemDelegateForColumn()
|
||||
*/
|
||||
QAbstractItemDelegate *QAbstractItemView::itemDelegateForIndex(const QModelIndex &index) const
|
||||
{
|
||||
Q_D(const QAbstractItemView);
|
||||
return d->delegateForIndex(index);
|
||||
@ -1723,7 +1734,7 @@ bool QAbstractItemView::viewportEvent(QEvent *event)
|
||||
option.rect = visualRect(index);
|
||||
option.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
|
||||
|
||||
QAbstractItemDelegate *delegate = d->delegateForIndex(index);
|
||||
QAbstractItemDelegate *delegate = itemDelegateForIndex(index);
|
||||
if (!delegate)
|
||||
return false;
|
||||
return delegate->helpEvent(he, this, option, index);
|
||||
@ -2734,7 +2745,7 @@ void QAbstractItemView::updateEditorGeometries()
|
||||
option.rect = visualRect(index);
|
||||
if (option.rect.isValid()) {
|
||||
editor->show();
|
||||
QAbstractItemDelegate *delegate = d->delegateForIndex(index);
|
||||
QAbstractItemDelegate *delegate = itemDelegateForIndex(index);
|
||||
if (delegate)
|
||||
delegate->updateEditorGeometry(editor, option, index);
|
||||
} else {
|
||||
@ -2837,7 +2848,7 @@ void QAbstractItemView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndE
|
||||
if (!isPersistent) {
|
||||
setState(NoState);
|
||||
QModelIndex index = d->indexForEditor(editor);
|
||||
editor->removeEventFilter(d->delegateForIndex(index));
|
||||
editor->removeEventFilter(itemDelegateForIndex(index));
|
||||
d->removeEditor(editor);
|
||||
}
|
||||
if (hadFocus) {
|
||||
@ -2907,7 +2918,7 @@ void QAbstractItemView::commitData(QWidget *editor)
|
||||
if (!index.isValid())
|
||||
return;
|
||||
d->currentlyCommittingEditor = editor;
|
||||
QAbstractItemDelegate *delegate = d->delegateForIndex(index);
|
||||
QAbstractItemDelegate *delegate = itemDelegateForIndex(index);
|
||||
editor->removeEventFilter(delegate);
|
||||
delegate->setModelData(editor, d->model, index);
|
||||
editor->installEventFilter(delegate);
|
||||
@ -3020,7 +3031,7 @@ QSize QAbstractItemView::sizeHintForIndex(const QModelIndex &index) const
|
||||
Q_D(const QAbstractItemView);
|
||||
if (!d->isIndexValid(index))
|
||||
return QSize();
|
||||
const auto delegate = d->delegateForIndex(index);
|
||||
const auto delegate = itemDelegateForIndex(index);
|
||||
QStyleOptionViewItem option;
|
||||
initViewItemOption(&option);
|
||||
return delegate ? delegate->sizeHint(option, index) : QSize();
|
||||
@ -3059,7 +3070,7 @@ int QAbstractItemView::sizeHintForRow(int row) const
|
||||
const QModelIndex index = d->model->index(row, c, d->root);
|
||||
if (QWidget *editor = d->editorForIndex(index).widget.data())
|
||||
height = qMax(height, editor->height());
|
||||
if (const QAbstractItemDelegate *delegate = d->delegateForIndex(index))
|
||||
if (const QAbstractItemDelegate *delegate = itemDelegateForIndex(index))
|
||||
height = qMax(height, delegate->sizeHint(option, index).height());
|
||||
}
|
||||
return height;
|
||||
@ -3090,7 +3101,7 @@ int QAbstractItemView::sizeHintForColumn(int column) const
|
||||
const QModelIndex index = d->model->index(r, column, d->root);
|
||||
if (QWidget *editor = d->editorForIndex(index).widget.data())
|
||||
width = qMax(width, editor->sizeHint().width());
|
||||
if (const QAbstractItemDelegate *delegate = d->delegateForIndex(index))
|
||||
if (const QAbstractItemDelegate *delegate = itemDelegateForIndex(index))
|
||||
width = qMax(width, delegate->sizeHint(option, index).width());
|
||||
}
|
||||
return width;
|
||||
@ -3283,7 +3294,7 @@ void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelInde
|
||||
const QEditorInfo &editorInfo = d->editorForIndex(topLeft);
|
||||
//we don't update the edit data if it is static
|
||||
if (!editorInfo.isStatic && editorInfo.widget) {
|
||||
QAbstractItemDelegate *delegate = d->delegateForIndex(topLeft);
|
||||
QAbstractItemDelegate *delegate = itemDelegateForIndex(topLeft);
|
||||
if (delegate) {
|
||||
delegate->setEditorData(editorInfo.widget.data(), topLeft);
|
||||
}
|
||||
@ -4193,7 +4204,7 @@ QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
|
||||
Q_Q(QAbstractItemView);
|
||||
QWidget *w = editorForIndex(index).widget.data();
|
||||
if (!w) {
|
||||
QAbstractItemDelegate *delegate = delegateForIndex(index);
|
||||
QAbstractItemDelegate *delegate = q->itemDelegateForIndex(index);
|
||||
if (!delegate)
|
||||
return nullptr;
|
||||
w = delegate->createEditor(viewport, options, index);
|
||||
@ -4228,6 +4239,7 @@ QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
|
||||
|
||||
void QAbstractItemViewPrivate::updateEditorData(const QModelIndex &tl, const QModelIndex &br)
|
||||
{
|
||||
Q_Q(QAbstractItemView);
|
||||
// we are counting on having relatively few editors
|
||||
const bool checkIndexes = tl.isValid() && br.isValid();
|
||||
const QModelIndex parent = tl.parent();
|
||||
@ -4246,7 +4258,7 @@ void QAbstractItemViewPrivate::updateEditorData(const QModelIndex &tl, const QMo
|
||||
|| index.parent() != parent)))
|
||||
continue;
|
||||
|
||||
QAbstractItemDelegate *delegate = delegateForIndex(index);
|
||||
QAbstractItemDelegate *delegate = q->itemDelegateForIndex(index);
|
||||
if (delegate) {
|
||||
delegate->setEditorData(editor, index);
|
||||
}
|
||||
@ -4369,7 +4381,7 @@ bool QAbstractItemViewPrivate::sendDelegateEvent(const QModelIndex &index, QEven
|
||||
q->initViewItemOption(&options);
|
||||
options.rect = q->visualRect(buddy);
|
||||
options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
|
||||
QAbstractItemDelegate *delegate = delegateForIndex(index);
|
||||
QAbstractItemDelegate *delegate = q->itemDelegateForIndex(index);
|
||||
return (event && delegate && delegate->editorEvent(event, model, options, buddy));
|
||||
}
|
||||
|
||||
@ -4446,7 +4458,7 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes,
|
||||
option.rect = paintPairs.at(j).rect.translated(-r->topLeft());
|
||||
const QModelIndex ¤t = paintPairs.at(j).index;
|
||||
adjustViewOptionsForIndex(&option, current);
|
||||
delegateForIndex(current)->paint(&painter, option, current);
|
||||
q->itemDelegateForIndex(current)->paint(&painter, option, current);
|
||||
}
|
||||
return pixmap;
|
||||
}
|
||||
|
@ -223,7 +223,12 @@ public:
|
||||
void setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate);
|
||||
QAbstractItemDelegate *itemDelegateForColumn(int column) const;
|
||||
|
||||
QAbstractItemDelegate *itemDelegate(const QModelIndex &index) const;
|
||||
#if QT_DEPRECATED_SINCE(6, 0)
|
||||
QT_DEPRECATED_VERSION_X_6_0("Use itemDelegateForIndex instead")
|
||||
QAbstractItemDelegate *itemDelegate(const QModelIndex &index) const
|
||||
{ return itemDelegateForIndex(index); }
|
||||
#endif
|
||||
virtual QAbstractItemDelegate *itemDelegateForIndex(const QModelIndex &index) const;
|
||||
|
||||
virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const override;
|
||||
|
||||
|
@ -211,11 +211,12 @@ public:
|
||||
|
||||
inline void releaseEditor(QWidget *editor, const QModelIndex &index = QModelIndex()) const {
|
||||
if (editor) {
|
||||
Q_Q(const QAbstractItemView);
|
||||
QObject::disconnect(editor, SIGNAL(destroyed(QObject*)),
|
||||
q_func(), SLOT(editorDestroyed(QObject*)));
|
||||
editor->removeEventFilter(itemDelegate);
|
||||
editor->hide();
|
||||
QAbstractItemDelegate *delegate = delegateForIndex(index);
|
||||
QAbstractItemDelegate *delegate = q->itemDelegateForIndex(index);
|
||||
|
||||
if (delegate)
|
||||
delegate->destroyEditor(editor, index);
|
||||
@ -276,20 +277,6 @@ public:
|
||||
return state == QAbstractItemView::AnimatingState;
|
||||
}
|
||||
|
||||
inline QAbstractItemDelegate *delegateForIndex(const QModelIndex &index) const {
|
||||
QMap<int, QPointer<QAbstractItemDelegate> >::ConstIterator it;
|
||||
|
||||
it = rowDelegates.find(index.row());
|
||||
if (it != rowDelegates.end())
|
||||
return it.value();
|
||||
|
||||
it = columnDelegates.find(index.column());
|
||||
if (it != columnDelegates.end())
|
||||
return it.value();
|
||||
|
||||
return itemDelegate;
|
||||
}
|
||||
|
||||
inline bool isIndexValid(const QModelIndex &index) const {
|
||||
return (index.row() >= 0) && (index.column() >= 0) && (index.model() == model);
|
||||
}
|
||||
@ -452,6 +439,20 @@ public:
|
||||
bool horizontalScrollModeSet;
|
||||
|
||||
private:
|
||||
inline QAbstractItemDelegate *delegateForIndex(const QModelIndex &index) const {
|
||||
QMap<int, QPointer<QAbstractItemDelegate> >::ConstIterator it;
|
||||
|
||||
it = rowDelegates.find(index.row());
|
||||
if (it != rowDelegates.end())
|
||||
return it.value();
|
||||
|
||||
it = columnDelegates.find(index.column());
|
||||
if (it != columnDelegates.end())
|
||||
return it.value();
|
||||
|
||||
return itemDelegate;
|
||||
}
|
||||
|
||||
mutable QBasicTimer delayedLayout;
|
||||
mutable QBasicTimer fetchMoreTimer;
|
||||
};
|
||||
|
@ -1083,7 +1083,7 @@ void QListView::paintEvent(QPaintEvent *e)
|
||||
previousRow = row;
|
||||
}
|
||||
|
||||
d->delegateForIndex(*it)->paint(&painter, option, *it);
|
||||
itemDelegateForIndex(*it)->paint(&painter, option, *it);
|
||||
}
|
||||
|
||||
#if QT_CONFIG(draganddrop)
|
||||
@ -1883,14 +1883,15 @@ QModelIndex QListViewPrivate::closestIndex(const QRect &target,
|
||||
|
||||
QSize QListViewPrivate::itemSize(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
Q_Q(const QListView);
|
||||
if (!uniformItemSizes) {
|
||||
const QAbstractItemDelegate *delegate = delegateForIndex(index);
|
||||
const QAbstractItemDelegate *delegate = q->itemDelegateForIndex(index);
|
||||
return delegate ? delegate->sizeHint(option, index) : QSize();
|
||||
}
|
||||
if (!cachedItemSize.isValid()) { // the last item is probaly the largest, so we use its size
|
||||
int row = model->rowCount(root) - 1;
|
||||
QModelIndex sample = model->index(row, column, root);
|
||||
const QAbstractItemDelegate *delegate = delegateForIndex(sample);
|
||||
const QAbstractItemDelegate *delegate = q->itemDelegateForIndex(sample);
|
||||
cachedItemSize = delegate ? delegate->sizeHint(option, sample) : QSize();
|
||||
}
|
||||
return cachedItemSize;
|
||||
|
@ -493,7 +493,7 @@ inline QSize QCommonListViewBase::itemSize(const QStyleOptionViewItem &opt, cons
|
||||
{ return dd->itemSize(opt, idx); }
|
||||
|
||||
inline QAbstractItemDelegate *QCommonListViewBase::delegate(const QModelIndex &idx) const
|
||||
{ return dd->delegateForIndex(idx); }
|
||||
{ return qq->itemDelegateForIndex(idx); }
|
||||
|
||||
inline bool QCommonListViewBase::isHidden(int row) const { return dd->isHidden(row); }
|
||||
inline int QCommonListViewBase::hiddenCount() const { return dd->hiddenRows.count(); }
|
||||
|
@ -1050,7 +1050,7 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItem &
|
||||
|
||||
q->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, q);
|
||||
|
||||
q->itemDelegate(index)->paint(painter, opt, index);
|
||||
q->itemDelegateForIndex(index)->paint(painter, opt, index);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1067,7 +1067,7 @@ int QTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, con
|
||||
int max = editor->maximumSize().width();
|
||||
hint = qBound(min, hint, max);
|
||||
}
|
||||
hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).width());
|
||||
hint = qMax(hint, q->itemDelegateForIndex(index)->sizeHint(option, index).width());
|
||||
return hint;
|
||||
}
|
||||
|
||||
@ -1089,7 +1089,7 @@ int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QS
|
||||
if (wrapItemText) {// for wrapping boundaries
|
||||
option.rect.setY(q->rowViewportPosition(index.row()));
|
||||
int height = q->rowHeight(index.row());
|
||||
// if the option.height == 0 then q->itemDelegate(index)->sizeHint(option, index) will be wrong.
|
||||
// if the option.height == 0 then q->itemDelegateForIndex(index)->sizeHint(option, index) will be wrong.
|
||||
// The option.height == 0 is used to conclude that the text is not wrapped, and hence it will
|
||||
// (exactly like widthHintForIndex) return a QSize with a long width (that we don't use) -
|
||||
// and the height of the text if it was/is on one line.
|
||||
@ -1104,7 +1104,7 @@ int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QS
|
||||
if (showGrid)
|
||||
option.rect.setWidth(option.rect.width() - 1);
|
||||
}
|
||||
hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).height());
|
||||
hint = qMax(hint, q->itemDelegateForIndex(index)->sizeHint(option, index).height());
|
||||
return hint;
|
||||
}
|
||||
|
||||
|
@ -1621,6 +1621,7 @@ void QTreeViewPrivate::calcLogicalIndices(
|
||||
*/
|
||||
int QTreeViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option, int i) const
|
||||
{
|
||||
Q_Q(const QTreeView);
|
||||
QWidget *editor = editorForIndex(index).widget.data();
|
||||
if (editor && persistent.contains(editor)) {
|
||||
hint = qMax(hint, editor->sizeHint().width());
|
||||
@ -1628,7 +1629,7 @@ int QTreeViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, cons
|
||||
int max = editor->maximumSize().width();
|
||||
hint = qBound(min, hint, max);
|
||||
}
|
||||
int xhint = delegateForIndex(index)->sizeHint(option, index).width();
|
||||
int xhint = q->itemDelegateForIndex(index)->sizeHint(option, index).width();
|
||||
hint = qMax(hint, xhint + (isTreePosition(index.column()) ? indentationForItem(i) : 0));
|
||||
return hint;
|
||||
}
|
||||
@ -1802,7 +1803,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
opt.state = oldState;
|
||||
}
|
||||
|
||||
d->delegateForIndex(modelIndex)->paint(painter, opt, modelIndex);
|
||||
itemDelegateForIndex(modelIndex)->paint(painter, opt, modelIndex);
|
||||
}
|
||||
|
||||
if (currentRowHasFocus) {
|
||||
@ -3015,7 +3016,7 @@ int QTreeView::indexRowSizeHint(const QModelIndex &index) const
|
||||
int max = editor->maximumSize().height();
|
||||
height = qBound(min, height, max);
|
||||
}
|
||||
int hint = d->delegateForIndex(idx)->sizeHint(option, idx).height();
|
||||
int hint = itemDelegateForIndex(idx)->sizeHint(option, idx).height();
|
||||
height = qMax(height, hint);
|
||||
}
|
||||
}
|
||||
@ -3274,7 +3275,7 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons
|
||||
option.rect = q->visualRect(index);
|
||||
if (option.rect.isValid()) {
|
||||
|
||||
if (QAbstractItemDelegate *delegate = delegateForIndex(index))
|
||||
if (QAbstractItemDelegate *delegate = q->itemDelegateForIndex(index))
|
||||
delegate->updateEditorGeometry(editor, option, index);
|
||||
|
||||
const QPoint pos = editor->pos();
|
||||
|
Loading…
Reference in New Issue
Block a user