summaryrefslogtreecommitdiffstats
path: root/src/gui/itemviews
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/itemviews')
-rw-r--r--src/gui/itemviews/itemviews.pri2
-rw-r--r--src/gui/itemviews/qabstractitemdelegate.cpp4
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp244
-rw-r--r--src/gui/itemviews/qabstractitemview.h1
-rw-r--r--src/gui/itemviews/qabstractitemview_p.h36
-rw-r--r--src/gui/itemviews/qabstractproxymodel.cpp105
-rw-r--r--src/gui/itemviews/qabstractproxymodel.h12
-rw-r--r--src/gui/itemviews/qfileiconprovider.cpp2
-rw-r--r--src/gui/itemviews/qheaderview.cpp22
-rw-r--r--src/gui/itemviews/qidentityproxymodel.cpp587
-rw-r--r--src/gui/itemviews/qidentityproxymodel.h120
-rw-r--r--src/gui/itemviews/qitemdelegate.cpp10
-rw-r--r--src/gui/itemviews/qitemselectionmodel.cpp28
-rw-r--r--src/gui/itemviews/qitemselectionmodel.h24
-rw-r--r--src/gui/itemviews/qlistview.cpp138
-rw-r--r--src/gui/itemviews/qlistview_p.h9
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.cpp4
-rw-r--r--src/gui/itemviews/qstringlistmodel.cpp3
-rw-r--r--src/gui/itemviews/qstyleditemdelegate.cpp9
-rw-r--r--src/gui/itemviews/qtableview.cpp52
-rw-r--r--src/gui/itemviews/qtableview.h1
-rw-r--r--src/gui/itemviews/qtableview_p.h5
-rw-r--r--src/gui/itemviews/qtreeview.cpp89
-rw-r--r--src/gui/itemviews/qtreeview.h3
-rw-r--r--src/gui/itemviews/qtreeview_p.h6
25 files changed, 1318 insertions, 198 deletions
diff --git a/src/gui/itemviews/itemviews.pri b/src/gui/itemviews/itemviews.pri
index bbc1e98..149bfd6 100644
--- a/src/gui/itemviews/itemviews.pri
+++ b/src/gui/itemviews/itemviews.pri
@@ -4,6 +4,7 @@ HEADERS += \
itemviews/qabstractitemview.h \
itemviews/qabstractitemview_p.h \
itemviews/qheaderview.h \
+ itemviews/qidentityproxymodel.h \
itemviews/qlistview.h \
itemviews/qlistview_p.h \
itemviews/qbsptree_p.h \
@@ -44,6 +45,7 @@ HEADERS += \
SOURCES += \
itemviews/qabstractitemview.cpp \
itemviews/qheaderview.cpp \
+ itemviews/qidentityproxymodel.cpp \
itemviews/qlistview.cpp \
itemviews/qbsptree.cpp \
itemviews/qtableview.cpp \
diff --git a/src/gui/itemviews/qabstractitemdelegate.cpp b/src/gui/itemviews/qabstractitemdelegate.cpp
index bdd73e0..34d3a25 100644
--- a/src/gui/itemviews/qabstractitemdelegate.cpp
+++ b/src/gui/itemviews/qabstractitemdelegate.cpp
@@ -362,7 +362,7 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
case QEvent::ToolTip: {
QHelpEvent *he = static_cast<QHelpEvent*>(event);
QVariant tooltip = index.data(Qt::ToolTipRole);
- if (qVariantCanConvert<QString>(tooltip)) {
+ if (tooltip.canConvert<QString>()) {
QToolTip::showText(he->globalPos(), tooltip.toString(), view);
return true;
}
@@ -376,7 +376,7 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
case QEvent::WhatsThis: {
QHelpEvent *he = static_cast<QHelpEvent*>(event);
QVariant whatsthis = index.data(Qt::WhatsThisRole);
- if (qVariantCanConvert<QString>(whatsthis)) {
+ if (whatsthis.canConvert<QString>()) {
QWhatsThis::showText(he->globalPos(), whatsthis.toString(), view);
return true;
}
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index 624b047..ded4d63 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -60,6 +60,7 @@
#include <private/qabstractitemmodel_p.h>
#ifndef QT_NO_ACCESSIBILITY
#include <qaccessible.h>
+#include <qaccessible2.h>
#endif
#include <private/qsoftkeymanager_p.h>
@@ -79,6 +80,7 @@ QAbstractItemViewPrivate::QAbstractItemViewPrivate()
pressedAlreadySelected(false),
viewportEnteredNeeded(false),
state(QAbstractItemView::NoState),
+ stateBeforeAnimation(QAbstractItemView::NoState),
editTriggers(QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed),
lastTrigger(QAbstractItemView::NoEditTriggers),
tabKeyNavigation(false),
@@ -644,6 +646,8 @@ void QAbstractItemView::setModel(QAbstractItemModel *model)
this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+ disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
@@ -661,7 +665,7 @@ void QAbstractItemView::setModel(QAbstractItemModel *model)
"QAbstractItemView::setModel",
"A model should return the exact same index "
"(including its internal id/pointer) when asked for it twice in a row.");
- Q_ASSERT_X(d->model->index(0,0).parent() == QModelIndex(),
+ Q_ASSERT_X(!d->model->index(0,0).parent().isValid(),
"QAbstractItemView::setModel",
"The parent of a top level index should be invalid");
@@ -674,6 +678,8 @@ void QAbstractItemView::setModel(QAbstractItemModel *model)
this, SLOT(_q_headerDataChanged()));
connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(rowsInserted(QModelIndex,int,int)));
+ connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
connect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
@@ -1045,16 +1051,26 @@ void QAbstractItemView::reset()
{
Q_D(QAbstractItemView);
d->delayedReset.stop(); //make sure we stop the timer
- QList<QEditorInfo>::const_iterator it = d->editors.constBegin();
- for (; it != d->editors.constEnd(); ++it)
- d->releaseEditor(it->editor);
- d->editors.clear();
+ foreach (const QEditorInfo &info, d->indexEditorHash) {
+ if (info.widget)
+ d->releaseEditor(info.widget.data());
+ }
+ d->editorIndexHash.clear();
+ d->indexEditorHash.clear();
d->persistent.clear();
d->currentIndexSet = false;
setState(NoState);
setRootIndex(QModelIndex());
if (d->selectionModel)
d->selectionModel->reset();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(this)->table2Interface()->modelReset();
+ QAccessible::updateAccessibility(this, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
/*!
@@ -2342,7 +2358,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event)
case Qt::Key_Return:
// Propagate the enter if you couldn't edit the item and there are no
// current editors (if there are editors, the event was most likely propagated from it).
- if (!edit(currentIndex(), EditKeyPressed, event) && d->editors.isEmpty())
+ if (!edit(currentIndex(), EditKeyPressed, event) && d->editorIndexHash.isEmpty())
event->ignore();
break;
#else
@@ -2527,7 +2543,7 @@ bool QAbstractItemView::edit(const QModelIndex &index, EditTrigger trigger, QEve
if (!d->isIndexValid(index))
return false;
- if (QWidget *w = (d->persistent.isEmpty() ? static_cast<QWidget*>(0) : d->editorForIndex(index).editor.data())) {
+ if (QWidget *w = (d->persistent.isEmpty() ? static_cast<QWidget*>(0) : d->editorForIndex(index).widget.data())) {
if (w->focusPolicy() == Qt::NoFocus)
return false;
w->setFocus();
@@ -2587,15 +2603,15 @@ void QAbstractItemView::updateEditorData()
void QAbstractItemView::updateEditorGeometries()
{
Q_D(QAbstractItemView);
- if(d->editors.isEmpty())
+ if(d->editorIndexHash.isEmpty())
return;
QStyleOptionViewItemV4 option = d->viewOptionsV4();
- QList<QEditorInfo>::iterator it = d->editors.begin();
+ QEditorIndexHash::iterator it = d->editorIndexHash.begin();
QWidgetList editorsToRelease;
QWidgetList editorsToHide;
- while (it != d->editors.end()) {
- QModelIndex index = it->index;
- QWidget *editor = it->editor;
+ while (it != d->editorIndexHash.end()) {
+ QModelIndex index = it.value();
+ QWidget *editor = it.key();
if (index.isValid() && editor) {
option.rect = visualRect(index);
if (option.rect.isValid()) {
@@ -2608,13 +2624,14 @@ void QAbstractItemView::updateEditorGeometries()
}
++it;
} else {
- it = d->editors.erase(it);
+ d->indexEditorHash.remove(it.value());
+ it = d->editorIndexHash.erase(it);
editorsToRelease << editor;
}
}
//we hide and release the editor outside of the loop because it might change the focus and try
- //to change the d->editors list.
+ //to change the editors hashes.
for (int i = 0; i < editorsToHide.count(); ++i) {
editorsToHide.at(i)->hide();
}
@@ -2801,7 +2818,7 @@ void QAbstractItemView::editorDestroyed(QObject *editor)
*/
void QAbstractItemView::setHorizontalStepsPerItem(int steps)
{
- Q_UNUSED(steps);
+ Q_UNUSED(steps)
// do nothing
}
@@ -2830,7 +2847,7 @@ int QAbstractItemView::horizontalStepsPerItem() const
*/
void QAbstractItemView::setVerticalStepsPerItem(int steps)
{
- Q_UNUSED(steps);
+ Q_UNUSED(steps)
// do nothing
}
@@ -2954,7 +2971,7 @@ int QAbstractItemView::sizeHintForRow(int row) const
{
Q_D(const QAbstractItemView);
- if (row < 0 || row >= d->model->rowCount() || !model())
+ if (row < 0 || row >= d->model->rowCount(d->root))
return -1;
ensurePolished();
@@ -2965,8 +2982,8 @@ int QAbstractItemView::sizeHintForRow(int row) const
QModelIndex index;
for (int c = 0; c < colCount; ++c) {
index = d->model->index(row, c, d->root);
- if (QWidget *editor = d->editorForIndex(index).editor)
- height = qMax(height, editor->size().height());
+ if (QWidget *editor = d->editorForIndex(index).widget.data())
+ height = qMax(height, editor->height());
int hint = d->delegateForIndex(index)->sizeHint(option, index).height();
height = qMax(height, hint);
}
@@ -2985,7 +3002,7 @@ int QAbstractItemView::sizeHintForColumn(int column) const
{
Q_D(const QAbstractItemView);
- if (column < 0 || column >= d->model->columnCount() || !model())
+ if (column < 0 || column >= d->model->columnCount(d->root))
return -1;
ensurePolished();
@@ -2996,7 +3013,7 @@ int QAbstractItemView::sizeHintForColumn(int column) const
QModelIndex index;
for (int r = 0; r < rows; ++r) {
index = d->model->index(r, column, d->root);
- if (QWidget *editor = d->editorForIndex(index).editor)
+ if (QWidget *editor = d->editorForIndex(index).widget.data())
width = qMax(width, editor->sizeHint().width());
int hint = d->delegateForIndex(index)->sizeHint(option, index).width();
width = qMax(width, hint);
@@ -3032,8 +3049,7 @@ void QAbstractItemView::openPersistentEditor(const QModelIndex &index)
void QAbstractItemView::closePersistentEditor(const QModelIndex &index)
{
Q_D(QAbstractItemView);
- QWidget *editor = d->editorForIndex(index).editor;
- if (editor) {
+ if (QWidget *editor = d->editorForIndex(index).widget.data()) {
if (index == selectionModel()->currentIndex())
closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
d->persistent.remove(editor);
@@ -3097,9 +3113,11 @@ void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget
QWidget* QAbstractItemView::indexWidget(const QModelIndex &index) const
{
Q_D(const QAbstractItemView);
- if (!d->isIndexValid(index))
- return 0;
- return d->editorForIndex(index).editor;
+ if (d->isIndexValid(index))
+ if (QWidget *editor = d->editorForIndex(index).widget.data())
+ return editor;
+
+ return 0;
}
/*!
@@ -3161,12 +3179,12 @@ void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelInde
// Single item changed
Q_D(QAbstractItemView);
if (topLeft == bottomRight && topLeft.isValid()) {
- const QEditorInfo editorInfo = d->editorForIndex(topLeft);
+ const QEditorInfo &editorInfo = d->editorForIndex(topLeft);
//we don't update the edit data if it is static
- if (!editorInfo.isStatic && editorInfo.editor) {
+ if (!editorInfo.isStatic && editorInfo.widget) {
QAbstractItemDelegate *delegate = d->delegateForIndex(topLeft);
if (delegate) {
- delegate->setEditorData(editorInfo.editor, topLeft);
+ delegate->setEditorData(editorInfo.widget.data(), topLeft);
}
}
if (isVisible() && !d->delayedPendingLayout) {
@@ -3240,12 +3258,17 @@ void QAbstractItemView::rowsAboutToBeRemoved(const QModelIndex &parent, int star
}
// Remove all affected editors; this is more efficient than waiting for updateGeometries() to clean out editors for invalid indexes
- for (int i = d->editors.size() - 1; i >= 0; --i) {
- const QModelIndex index = d->editors.at(i).index;
- QWidget *editor = d->editors.at(i).editor;
+ QEditorIndexHash::iterator i = d->editorIndexHash.begin();
+ while (i != d->editorIndexHash.end()) {
+ const QModelIndex index = i.value();
if (index.row() >= start && index.row() <= end && d->model->parent(index) == parent) {
- d->editors.removeAt(i);
- d->releaseEditor(editor);
+ QWidget *editor = i.key();
+ QEditorInfo info = d->indexEditorHash.take(index);
+ i = d->editorIndexHash.erase(i);
+ if (info.widget)
+ d->releaseEditor(editor);
+ } else {
+ ++i;
}
}
}
@@ -3257,12 +3280,24 @@ void QAbstractItemView::rowsAboutToBeRemoved(const QModelIndex &parent, int star
rows are those under the given \a parent from \a start to \a end
inclusive.
*/
-void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &, int, int)
+void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &index, int start, int end)
{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
Q_Q(QAbstractItemView);
if (q->isVisible())
q->updateEditorGeometries();
q->setState(QAbstractItemView::NoState);
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsRemoved(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
/*!
@@ -3302,17 +3337,20 @@ void QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &par
}
// Remove all affected editors; this is more efficient than waiting for updateGeometries() to clean out editors for invalid indexes
- QList<QEditorInfo>::iterator it = editors.begin();
- while (it != editors.end()) {
- QModelIndex index = it->index;
+ QEditorIndexHash::iterator it = editorIndexHash.begin();
+ while (it != editorIndexHash.end()) {
+ QModelIndex index = it.value();
if (index.column() <= start && index.column() >= end && model->parent(index) == parent) {
- QWidget *editor = it->editor;
- it = editors.erase(it);
- releaseEditor(editor);
+ QWidget *editor = it.key();
+ QEditorInfo info = indexEditorHash.take(it.value());
+ it = editorIndexHash.erase(it);
+ if (info.widget)
+ releaseEditor(editor);
} else {
++it;
}
}
+
}
/*!
@@ -3322,27 +3360,72 @@ void QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &par
rows are those under the given \a parent from \a start to \a end
inclusive.
*/
-void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &, int, int)
+void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &index, int start, int end)
{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
Q_Q(QAbstractItemView);
if (q->isVisible())
q->updateEditorGeometries();
q->setState(QAbstractItemView::NoState);
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->columnsRemoved(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
+
/*!
\internal
This slot is called when rows have been inserted.
*/
-void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &, int, int)
+void QAbstractItemViewPrivate::_q_rowsInserted(const QModelIndex &index, int start, int end)
{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
Q_Q(QAbstractItemView);
- if (q->isVisible())
- q->updateEditorGeometries();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsInserted(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
+/*!
+ \internal
+
+ This slot is called when columns have been inserted.
+*/
+void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int start, int end)
+{
+ Q_UNUSED(index)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+ Q_Q(QAbstractItemView);
+ if (q->isVisible())
+ q->updateEditorGeometries();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->columnsInserted(index, start, end);
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
+}
/*!
\internal
@@ -3360,7 +3443,16 @@ void QAbstractItemViewPrivate::_q_modelDestroyed()
*/
void QAbstractItemViewPrivate::_q_layoutChanged()
{
+ Q_Q(QAbstractItemView);
doDelayedItemsLayout();
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::queryAccessibleInterface(q)->table2Interface()->modelReset();
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
/*!
@@ -3394,7 +3486,7 @@ void QAbstractItemView::currentChanged(const QModelIndex &current, const QModelI
if (previous.isValid()) {
QModelIndex buddy = d->model->buddy(previous);
- QWidget *editor = d->editorForIndex(buddy).editor;
+ QWidget *editor = d->editorForIndex(buddy).widget.data();
if (editor && !d->persistent.contains(editor)) {
commitData(editor);
if (current.row() != previous.row())
@@ -3685,7 +3777,7 @@ QItemSelectionModel::SelectionFlags QAbstractItemView::selectionCommand(const QM
QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::multiSelectionCommand(
const QModelIndex &index, const QEvent *event) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
if (event) {
switch (event->type()) {
@@ -3920,7 +4012,7 @@ QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
const QStyleOptionViewItem &options)
{
Q_Q(QAbstractItemView);
- QWidget *w = editorForIndex(index).editor;
+ QWidget *w = editorForIndex(index).widget.data();
if (!w) {
QAbstractItemDelegate *delegate = delegateForIndex(index);
if (!delegate)
@@ -3951,6 +4043,7 @@ QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
#endif
}
}
+
return w;
}
@@ -3959,11 +4052,11 @@ void QAbstractItemViewPrivate::updateEditorData(const QModelIndex &tl, const QMo
// we are counting on having relatively few editors
const bool checkIndexes = tl.isValid() && br.isValid();
const QModelIndex parent = tl.parent();
- QList<QEditorInfo>::const_iterator it = editors.constBegin();
- for (; it != editors.constEnd(); ++it) {
- QWidget *editor = it->editor;
- const QModelIndex index = it->index;
- if (it->isStatic || editor == 0 || !index.isValid() ||
+ QIndexEditorHash::const_iterator it = indexEditorHash.constBegin();
+ for (; it != indexEditorHash.constEnd(); ++it) {
+ QWidget *editor = it.value().widget.data();
+ const QModelIndex index = it.key();
+ if (it.value().isStatic || !editor || !index.isValid() ||
(checkIndexes
&& (index.row() < tl.row() || index.row() > br.row()
|| index.column() < tl.column() || index.column() > br.column()
@@ -4036,41 +4129,40 @@ void QAbstractItemViewPrivate::checkPersistentEditorFocus()
}
-QEditorInfo QAbstractItemViewPrivate::editorForIndex(const QModelIndex &index) const
+const QEditorInfo & QAbstractItemViewPrivate::editorForIndex(const QModelIndex &index) const
{
- QList<QEditorInfo>::const_iterator it = editors.constBegin();
- for (; it != editors.constEnd(); ++it) {
- if (it->index == index)
- return *it;
- }
+ static QEditorInfo nullInfo;
- return QEditorInfo();
+ QIndexEditorHash::const_iterator it = indexEditorHash.find(index);
+ if (it == indexEditorHash.end())
+ return nullInfo;
+
+ return it.value();
}
QModelIndex QAbstractItemViewPrivate::indexForEditor(QWidget *editor) const
{
- QList<QEditorInfo>::const_iterator it = editors.constBegin();
- for (; it != editors.constEnd(); ++it) {
- if (it->editor == editor)
- return it->index;
- }
- return QModelIndex();
+ QEditorIndexHash::const_iterator it = editorIndexHash.find(editor);
+ if (it == editorIndexHash.end())
+ return QModelIndex();
+
+ return it.value();
}
void QAbstractItemViewPrivate::removeEditor(QWidget *editor)
{
- QList<QEditorInfo>::iterator it = editors.begin();
- for (; it != editors.end(); ) {
- if (it->editor == editor)
- it = editors.erase(it);
- else
- ++it;
+ QEditorIndexHash::iterator it = editorIndexHash.find(editor);
+ if (it != editorIndexHash.end())
+ {
+ indexEditorHash.remove(it.value());
+ editorIndexHash.erase(it);
}
}
void QAbstractItemViewPrivate::addEditor(const QModelIndex &index, QWidget *editor, bool isStatic)
{
- editors.append(QEditorInfo(index, editor, isStatic));
+ editorIndexHash.insert(editor, index);
+ indexEditorHash.insert(index, QEditorInfo(editor, isStatic));
}
bool QAbstractItemViewPrivate::sendDelegateEvent(const QModelIndex &index, QEvent *event) const
@@ -4097,13 +4189,13 @@ bool QAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *even
if (!w)
return false;
- if (event)
- QApplication::sendEvent(w->focusProxy() ? w->focusProxy() : w, event);
-
q->setState(QAbstractItemView::EditingState);
w->show();
w->setFocus();
+ if (event)
+ QApplication::sendEvent(w->focusProxy() ? w->focusProxy() : w, event);
+
return true;
}
diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h
index cb7b78d..1d0c36e 100644
--- a/src/gui/itemviews/qabstractitemview.h
+++ b/src/gui/itemviews/qabstractitemview.h
@@ -355,6 +355,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeRemoved(const QModelIndex&, int, int))
Q_PRIVATE_SLOT(d_func(), void _q_columnsRemoved(const QModelIndex&, int, int))
Q_PRIVATE_SLOT(d_func(), void _q_columnsInserted(const QModelIndex&, int, int))
+ Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex&, int, int))
Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex&, int, int))
Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged())
diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h
index cadc1f7..04babde 100644
--- a/src/gui/itemviews/qabstractitemview_p.h
+++ b/src/gui/itemviews/qabstractitemview_p.h
@@ -70,22 +70,18 @@
QT_BEGIN_NAMESPACE
-struct QEditorInfo
-{
- QEditorInfo() : isStatic(false)
- {
- }
-
- QEditorInfo(const QPersistentModelIndex &i, QWidget *e, bool b) : index(i), editor(e), isStatic(b)
- {
- }
-
- QPersistentModelIndex index;
- QPointer<QWidget> editor;
- bool isStatic; //true when called from setIndexWidget
+struct QEditorInfo {
+ QEditorInfo(QWidget *e, bool s): widget(QWeakPointer<QWidget>(e)), isStatic(s) {}
+ QEditorInfo(): isStatic(false) {}
+ QWeakPointer<QWidget> widget;
+ bool isStatic;
};
+// Fast associativity between Persistent editors and indices.
+typedef QHash<QWidget *, QPersistentModelIndex> QEditorIndexHash;
+typedef QHash<QPersistentModelIndex, QEditorInfo> QIndexEditorHash;
+
typedef QPair<QRect, QModelIndex> QItemViewPaintPair;
typedef QList<QItemViewPaintPair> QItemViewPaintPairs;
@@ -112,6 +108,7 @@ public:
void init();
virtual void _q_rowsRemoved(const QModelIndex &parent, int start, int end);
+ virtual void _q_rowsInserted(const QModelIndex &parent, int start, int end);
virtual void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
virtual void _q_columnsRemoved(const QModelIndex &parent, int start, int end);
virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end);
@@ -135,8 +132,9 @@ public:
}
void stopAutoScroll() { autoScrollTimer.stop(); autoScrollCount = 0;}
-
- bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index);
+#ifndef QT_NO_DRAGANDDROP
+ virtual bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index);
+#endif
bool droppingOnItself(QDropEvent *event, const QModelIndex &index);
QWidget *editor(const QModelIndex &index, const QStyleOptionViewItem &options);
@@ -247,9 +245,9 @@ public:
: q->horizontalOffset(), q->verticalOffset());
}
- QEditorInfo editorForIndex(const QModelIndex &index) const;
+ const QEditorInfo &editorForIndex(const QModelIndex &index) const;
inline bool hasEditor(const QModelIndex &index) const {
- return editorForIndex(index).editor != 0;
+ return indexEditorHash.find(index) != indexEditorHash.constEnd();
}
QModelIndex indexForEditor(QWidget *editor) const;
@@ -352,7 +350,8 @@ public:
QAbstractItemView::SelectionMode selectionMode;
QAbstractItemView::SelectionBehavior selectionBehavior;
- QList<QEditorInfo> editors;
+ QEditorIndexHash editorIndexHash;
+ QIndexEditorHash indexEditorHash;
QSet<QWidget*> persistent;
QWidget *currentlyCommittingEditor;
@@ -367,6 +366,7 @@ public:
bool viewportEnteredNeeded;
QAbstractItemView::State state;
+ QAbstractItemView::State stateBeforeAnimation;
QAbstractItemView::EditTriggers editTriggers;
QAbstractItemView::EditTrigger lastTrigger;
diff --git a/src/gui/itemviews/qabstractproxymodel.cpp b/src/gui/itemviews/qabstractproxymodel.cpp
index 4f3dbf2..f00b7ee 100644
--- a/src/gui/itemviews/qabstractproxymodel.cpp
+++ b/src/gui/itemviews/qabstractproxymodel.cpp
@@ -45,6 +45,9 @@
#include "qitemselectionmodel.h"
#include <private/qabstractproxymodel_p.h>
+#include <QtCore/QSize>
+#include <QtCore/QStringList>
+
QT_BEGIN_NAMESPACE
@@ -270,6 +273,15 @@ bool QAbstractProxyModel::setData(const QModelIndex &index, const QVariant &valu
/*!
\reimp
*/
+bool QAbstractProxyModel::setItemData(const QModelIndex &index, const QMap< int, QVariant >& roles)
+{
+ Q_D(QAbstractProxyModel);
+ return d->model->setItemData(mapToSource(index), roles);
+}
+
+/*!
+ \reimp
+ */
bool QAbstractProxyModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
{
Q_D(QAbstractProxyModel);
@@ -284,6 +296,99 @@ bool QAbstractProxyModel::setHeaderData(int section, Qt::Orientation orientation
return d->model->setHeaderData(sourceSection, orientation, value, role);
}
+/*!
+ \reimp
+ \since 4.8
+ */
+QModelIndex QAbstractProxyModel::buddy(const QModelIndex &index) const
+{
+ Q_D(const QAbstractProxyModel);
+ return mapFromSource(d->model->buddy(mapToSource(index)));
+}
+
+/*!
+ \reimp
+ \since 4.8
+ */
+bool QAbstractProxyModel::canFetchMore(const QModelIndex &parent) const
+{
+ Q_D(const QAbstractProxyModel);
+ return d->model->canFetchMore(mapToSource(parent));
+}
+
+/*!
+ \reimp
+ \since 4.8
+ */
+void QAbstractProxyModel::fetchMore(const QModelIndex &parent)
+{
+ Q_D(QAbstractProxyModel);
+ d->model->fetchMore(mapToSource(parent));
+}
+
+/*!
+ \reimp
+ \since 4.8
+ */
+void QAbstractProxyModel::sort(int column, Qt::SortOrder order)
+{
+ Q_D(QAbstractProxyModel);
+ d->model->sort(column, order);
+}
+
+/*!
+ \reimp
+ \since 4.8
+ */
+QSize QAbstractProxyModel::span(const QModelIndex &index) const
+{
+ Q_D(const QAbstractProxyModel);
+ return d->model->span(mapToSource(index));
+}
+
+/*!
+ \reimp
+ \since 4.8
+ */
+bool QAbstractProxyModel::hasChildren(const QModelIndex &parent) const
+{
+ Q_D(const QAbstractProxyModel);
+ return d->model->hasChildren(mapToSource(parent));
+}
+
+/*!
+ \reimp
+ \since 4.8
+ */
+QMimeData* QAbstractProxyModel::mimeData(const QModelIndexList &indexes) const
+{
+ Q_D(const QAbstractProxyModel);
+ QModelIndexList list;
+ foreach(const QModelIndex &index, indexes)
+ list << mapToSource(index);
+ return d->model->mimeData(list);
+}
+
+/*!
+ \reimp
+ \since 4.8
+ */
+QStringList QAbstractProxyModel::mimeTypes() const
+{
+ Q_D(const QAbstractProxyModel);
+ return d->model->mimeTypes();
+}
+
+/*!
+ \reimp
+ \since 4.8
+ */
+Qt::DropActions QAbstractProxyModel::supportedDropActions() const
+{
+ Q_D(const QAbstractProxyModel);
+ return d->model->supportedDropActions();
+}
+
QT_END_NAMESPACE
#include "moc_qabstractproxymodel.cpp"
diff --git a/src/gui/itemviews/qabstractproxymodel.h b/src/gui/itemviews/qabstractproxymodel.h
index de68d24..1c2c8ea 100644
--- a/src/gui/itemviews/qabstractproxymodel.h
+++ b/src/gui/itemviews/qabstractproxymodel.h
@@ -81,8 +81,20 @@ public:
Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+ bool setItemData(const QModelIndex& index, const QMap<int, QVariant> &roles);
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole);
+ QModelIndex buddy(const QModelIndex &index) const;
+ bool canFetchMore(const QModelIndex &parent) const;
+ void fetchMore(const QModelIndex &parent);
+ void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
+ QSize span(const QModelIndex &index) const;
+ bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
+
+ QMimeData* mimeData(const QModelIndexList &indexes) const;
+ QStringList mimeTypes() const;
+ Qt::DropActions supportedDropActions() const;
+
protected:
QAbstractProxyModel(QAbstractProxyModelPrivate &, QObject *parent);
diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/gui/itemviews/qfileiconprovider.cpp
index 2218fbb..84081c5 100644
--- a/src/gui/itemviews/qfileiconprovider.cpp
+++ b/src/gui/itemviews/qfileiconprovider.cpp
@@ -234,7 +234,7 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const
const QString fileExtension = QLatin1Char('.') + fileInfo.suffix().toUpper();
QString key;
- if (fileInfo.isFile() && !fileInfo.isExecutable() && !fileInfo.isSymLink())
+ if (fileInfo.isFile() && !fileInfo.isExecutable() && !fileInfo.isSymLink() && fileExtension != QLatin1String(".ICO"))
key = QLatin1String("qt_") + fileExtension;
QPixmap pixmap;
diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp
index 5e5f916..8b3c6e8 100644
--- a/src/gui/itemviews/qheaderview.cpp
+++ b/src/gui/itemviews/qheaderview.cpp
@@ -2109,7 +2109,7 @@ void QHeaderView::paintEvent(QPaintEvent *e)
QVariant variant = d->model->headerData(logical, d->orientation,
Qt::FontRole);
- if (variant.isValid() && qVariantCanConvert<QFont>(variant)) {
+ if (variant.isValid() && variant.canConvert<QFont>()) {
QFont sectionFont = qvariant_cast<QFont>(variant);
painter.setFont(sectionFont);
}
@@ -2489,13 +2489,13 @@ void QHeaderView::paintSection(QPainter *painter, const QRect &rect, int logical
opt.icon = qvariant_cast<QPixmap>(variant);
QVariant foregroundBrush = d->model->headerData(logicalIndex, d->orientation,
Qt::ForegroundRole);
- if (qVariantCanConvert<QBrush>(foregroundBrush))
+ if (foregroundBrush.canConvert<QBrush>())
opt.palette.setBrush(QPalette::ButtonText, qvariant_cast<QBrush>(foregroundBrush));
QPointF oldBO = painter->brushOrigin();
QVariant backgroundBrush = d->model->headerData(logicalIndex, d->orientation,
Qt::BackgroundRole);
- if (qVariantCanConvert<QBrush>(backgroundBrush)) {
+ if (backgroundBrush.canConvert<QBrush>()) {
opt.palette.setBrush(QPalette::Button, qvariant_cast<QBrush>(backgroundBrush));
opt.palette.setBrush(QPalette::Window, qvariant_cast<QBrush>(backgroundBrush));
painter->setBrushOrigin(opt.rect.topLeft());
@@ -2556,7 +2556,7 @@ QSize QHeaderView::sectionSizeFromContents(int logicalIndex) const
QVariant var = d->model->headerData(logicalIndex, d->orientation,
Qt::FontRole);
QFont fnt;
- if (var.isValid() && qVariantCanConvert<QFont>(var))
+ if (var.isValid() && var.canConvert<QFont>())
fnt = qvariant_cast<QFont>(var);
else
fnt = font();
@@ -3278,9 +3278,17 @@ void QHeaderViewPrivate::clear()
void QHeaderViewPrivate::flipSortIndicator(int section)
{
Q_Q(QHeaderView);
- bool ascending = (sortIndicatorSection != section
- || sortIndicatorOrder == Qt::DescendingOrder);
- q->setSortIndicator(section, ascending ? Qt::AscendingOrder : Qt::DescendingOrder);
+ Qt::SortOrder sortOrder;
+ if (sortIndicatorSection == section) {
+ sortOrder = (sortIndicatorOrder == Qt::DescendingOrder) ? Qt::AscendingOrder : Qt::DescendingOrder;
+ } else {
+ const QVariant value = model->headerData(section, orientation, Qt::InitialSortOrderRole);
+ if (value.canConvert(QVariant::Int))
+ sortOrder = static_cast<Qt::SortOrder>(value.toInt());
+ else
+ sortOrder = Qt::AscendingOrder;
+ }
+ q->setSortIndicator(section, sortOrder);
}
void QHeaderViewPrivate::cascadingResize(int visual, int newSize)
diff --git a/src/gui/itemviews/qidentityproxymodel.cpp b/src/gui/itemviews/qidentityproxymodel.cpp
new file mode 100644
index 0000000..ee36b831
--- /dev/null
+++ b/src/gui/itemviews/qidentityproxymodel.cpp
@@ -0,0 +1,587 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qidentityproxymodel.h"
+
+#ifndef QT_NO_IDENTITYPROXYMODEL
+
+#include "qitemselectionmodel.h"
+#include <private/qabstractproxymodel_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QIdentityProxyModelPrivate : public QAbstractProxyModelPrivate
+{
+ QIdentityProxyModelPrivate()
+ : ignoreNextLayoutAboutToBeChanged(false),
+ ignoreNextLayoutChanged(false)
+ {
+
+ }
+
+ Q_DECLARE_PUBLIC(QIdentityProxyModel)
+
+ bool ignoreNextLayoutAboutToBeChanged;
+ bool ignoreNextLayoutChanged;
+ QList<QPersistentModelIndex> layoutChangePersistentIndexes;
+ QModelIndexList proxyIndexes;
+
+ void _q_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end);
+ void _q_sourceRowsInserted(const QModelIndex &parent, int start, int end);
+ void _q_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
+ void _q_sourceRowsRemoved(const QModelIndex &parent, int start, int end);
+ void _q_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
+ void _q_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
+
+ void _q_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end);
+ void _q_sourceColumnsInserted(const QModelIndex &parent, int start, int end);
+ void _q_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
+ void _q_sourceColumnsRemoved(const QModelIndex &parent, int start, int end);
+ void _q_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
+ void _q_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
+
+ void _q_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last);
+
+ void _q_sourceLayoutAboutToBeChanged();
+ void _q_sourceLayoutChanged();
+ void _q_sourceModelAboutToBeReset();
+ void _q_sourceModelReset();
+
+};
+
+/*!
+ \since 4.8
+ \class QIdentityProxyModel
+ \brief The QIdentityProxyModel class proxies its source model unmodified
+
+ \ingroup model-view
+
+ QIdentityProxyModel can be used to forward the structure of a source model exactly, with no sorting, filtering or other transformation.
+ This is similar in concept to an identity matrix where A.I = A.
+
+ Because it does no sorting or filtering, this class is most suitable to proxy models which transform the data() of the source model.
+ For example, a proxy model could be created to define the font used, or the background colour, or the tooltip etc. This removes the
+ need to implement all data handling in the same class that creates the structure of the model, and can also be used to create
+ re-usable components.
+
+ This also provides a way to change the data in the case where a source model is supplied by a third party which can not be modified.
+
+ \snippet doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp 0
+
+ \sa QAbstractProxyModel, {Model/View Programming}, QAbstractItemModel
+
+*/
+
+/*!
+ Constructs an identity model with the given \a parent.
+*/
+QIdentityProxyModel::QIdentityProxyModel(QObject* parent)
+ : QAbstractProxyModel(*new QIdentityProxyModelPrivate, parent)
+{
+
+}
+
+/*! \internal
+ */
+QIdentityProxyModel::QIdentityProxyModel(QIdentityProxyModelPrivate &dd, QObject* parent)
+ : QAbstractProxyModel(dd, parent)
+{
+
+}
+
+/*!
+ Destroys this identity model.
+*/
+QIdentityProxyModel::~QIdentityProxyModel()
+{
+}
+
+/*!
+ \reimp
+ */
+int QIdentityProxyModel::columnCount(const QModelIndex& parent) const
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == this : true);
+ Q_D(const QIdentityProxyModel);
+ return d->model->columnCount(mapToSource(parent));
+}
+
+/*!
+ \reimp
+ */
+bool QIdentityProxyModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent)
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == this : true);
+ Q_D(QIdentityProxyModel);
+ return d->model->dropMimeData(data, action, row, column, mapToSource(parent));
+}
+
+/*!
+ \reimp
+ */
+QModelIndex QIdentityProxyModel::index(int row, int column, const QModelIndex& parent) const
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == this : true);
+ Q_D(const QIdentityProxyModel);
+ if (!hasIndex(row, column, parent))
+ return QModelIndex();
+ const QModelIndex sourceParent = mapToSource(parent);
+ const QModelIndex sourceIndex = d->model->index(row, column, sourceParent);
+ Q_ASSERT(sourceIndex.isValid());
+ return mapFromSource(sourceIndex);
+}
+
+/*!
+ \reimp
+ */
+bool QIdentityProxyModel::insertColumns(int column, int count, const QModelIndex& parent)
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == this : true);
+ Q_D(QIdentityProxyModel);
+ return d->model->insertColumns(column, count, mapToSource(parent));
+}
+
+/*!
+ \reimp
+ */
+bool QIdentityProxyModel::insertRows(int row, int count, const QModelIndex& parent)
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == this : true);
+ Q_D(QIdentityProxyModel);
+ return d->model->insertRows(row, count, mapToSource(parent));
+}
+
+/*!
+ \reimp
+ */
+QModelIndex QIdentityProxyModel::mapFromSource(const QModelIndex& sourceIndex) const
+{
+ Q_D(const QIdentityProxyModel);
+ if (!d->model || !sourceIndex.isValid())
+ return QModelIndex();
+
+ Q_ASSERT(sourceIndex.model() == d->model);
+ return createIndex(sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer());
+}
+
+/*!
+ \reimp
+ */
+QItemSelection QIdentityProxyModel::mapSelectionFromSource(const QItemSelection& selection) const
+{
+ Q_D(const QIdentityProxyModel);
+ QItemSelection proxySelection;
+
+ if (!d->model)
+ return proxySelection;
+
+ QItemSelection::const_iterator it = selection.constBegin();
+ const QItemSelection::const_iterator end = selection.constEnd();
+ for ( ; it != end; ++it) {
+ Q_ASSERT(it->model() == d->model);
+ const QItemSelectionRange range(mapFromSource(it->topLeft()), mapFromSource(it->bottomRight()));
+ proxySelection.append(range);
+ }
+
+ return proxySelection;
+}
+
+/*!
+ \reimp
+ */
+QItemSelection QIdentityProxyModel::mapSelectionToSource(const QItemSelection& selection) const
+{
+ Q_D(const QIdentityProxyModel);
+ QItemSelection sourceSelection;
+
+ if (!d->model)
+ return sourceSelection;
+
+ QItemSelection::const_iterator it = selection.constBegin();
+ const QItemSelection::const_iterator end = selection.constEnd();
+ for ( ; it != end; ++it) {
+ Q_ASSERT(it->model() == this);
+ const QItemSelectionRange range(mapToSource(it->topLeft()), mapToSource(it->bottomRight()));
+ sourceSelection.append(range);
+ }
+
+ return sourceSelection;
+}
+
+/*!
+ \reimp
+ */
+QModelIndex QIdentityProxyModel::mapToSource(const QModelIndex& proxyIndex) const
+{
+ Q_D(const QIdentityProxyModel);
+ if (!d->model || !proxyIndex.isValid())
+ return QModelIndex();
+ Q_ASSERT(proxyIndex.model() == this);
+ return d->model->createIndex(proxyIndex.row(), proxyIndex.column(), proxyIndex.internalPointer());
+}
+
+/*!
+ \reimp
+ */
+QModelIndexList QIdentityProxyModel::match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const
+{
+ Q_D(const QIdentityProxyModel);
+ Q_ASSERT(start.isValid() ? start.model() == this : true);
+ if (!d->model)
+ return QModelIndexList();
+
+ const QModelIndexList sourceList = d->model->match(mapToSource(start), role, value, hits, flags);
+ QModelIndexList::const_iterator it = sourceList.constBegin();
+ const QModelIndexList::const_iterator end = sourceList.constEnd();
+ QModelIndexList proxyList;
+ for ( ; it != end; ++it)
+ proxyList.append(mapFromSource(*it));
+ return proxyList;
+}
+
+/*!
+ \reimp
+ */
+QModelIndex QIdentityProxyModel::parent(const QModelIndex& child) const
+{
+ Q_ASSERT(child.isValid() ? child.model() == this : true);
+ const QModelIndex sourceIndex = mapToSource(child);
+ const QModelIndex sourceParent = sourceIndex.parent();
+ return mapFromSource(sourceParent);
+}
+
+/*!
+ \reimp
+ */
+bool QIdentityProxyModel::removeColumns(int column, int count, const QModelIndex& parent)
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == this : true);
+ Q_D(QIdentityProxyModel);
+ return d->model->removeColumns(column, count, mapToSource(parent));
+}
+
+/*!
+ \reimp
+ */
+bool QIdentityProxyModel::removeRows(int row, int count, const QModelIndex& parent)
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == this : true);
+ Q_D(QIdentityProxyModel);
+ return d->model->removeRows(row, count, mapToSource(parent));
+}
+
+/*!
+ \reimp
+ */
+int QIdentityProxyModel::rowCount(const QModelIndex& parent) const
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == this : true);
+ Q_D(const QIdentityProxyModel);
+ return d->model->rowCount(mapToSource(parent));
+}
+
+/*!
+ \reimp
+ */
+void QIdentityProxyModel::setSourceModel(QAbstractItemModel* sourceModel)
+{
+ beginResetModel();
+
+ if (sourceModel) {
+ disconnect(sourceModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)),
+ this, SLOT(_q_sourceRowsAboutToBeInserted(const QModelIndex &, int, int)));
+ disconnect(sourceModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
+ this, SLOT(_q_sourceRowsInserted(const QModelIndex &, int, int)));
+ disconnect(sourceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
+ this, SLOT(_q_sourceRowsAboutToBeRemoved(const QModelIndex &, int, int)));
+ disconnect(sourceModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
+ this, SLOT(_q_sourceRowsRemoved(const QModelIndex &, int, int)));
+ disconnect(sourceModel, SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
+ this, SLOT(_q_sourceRowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
+ disconnect(sourceModel, SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
+ this, SLOT(_q_sourceRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
+ disconnect(sourceModel, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)),
+ this, SLOT(_q_sourceColumnsAboutToBeInserted(const QModelIndex &, int, int)));
+ disconnect(sourceModel, SIGNAL(columnsInserted(const QModelIndex &, int, int)),
+ this, SLOT(_q_sourceColumnsInserted(const QModelIndex &, int, int)));
+ disconnect(sourceModel, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)),
+ this, SLOT(_q_sourceColumnsAboutToBeRemoved(const QModelIndex &, int, int)));
+ disconnect(sourceModel, SIGNAL(columnsRemoved(const QModelIndex &, int, int)),
+ this, SLOT(_q_sourceColumnsRemoved(const QModelIndex &, int, int)));
+ disconnect(sourceModel, SIGNAL(columnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
+ this, SLOT(_q_sourceColumnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
+ disconnect(sourceModel, SIGNAL(columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
+ this, SLOT(_q_sourceColumnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
+ disconnect(sourceModel, SIGNAL(modelAboutToBeReset()),
+ this, SLOT(_q_sourceModelAboutToBeReset()));
+ disconnect(sourceModel, SIGNAL(modelReset()),
+ this, SLOT(_q_sourceModelReset()));
+ disconnect(sourceModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
+ this, SLOT(_q_sourceDataChanged(const QModelIndex &, const QModelIndex &)));
+ disconnect(sourceModel, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
+ this, SLOT(_q_sourceHeaderDataChanged(Qt::Orientation,int,int)));
+ disconnect(sourceModel, SIGNAL(layoutAboutToBeChanged()),
+ this, SLOT(_q_sourceLayoutAboutToBeChanged()));
+ disconnect(sourceModel, SIGNAL(layoutChanged()),
+ this, SLOT(_q_sourceLayoutChanged()));
+ }
+
+ QAbstractProxyModel::setSourceModel(sourceModel);
+
+ if (sourceModel) {
+ connect(sourceModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)),
+ SLOT(_q_sourceRowsAboutToBeInserted(const QModelIndex &, int, int)));
+ connect(sourceModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
+ SLOT(_q_sourceRowsInserted(const QModelIndex &, int, int)));
+ connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
+ SLOT(_q_sourceRowsAboutToBeRemoved(const QModelIndex &, int, int)));
+ connect(sourceModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
+ SLOT(_q_sourceRowsRemoved(const QModelIndex &, int, int)));
+ connect(sourceModel, SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
+ SLOT(_q_sourceRowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
+ connect(sourceModel, SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
+ SLOT(_q_sourceRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
+ connect(sourceModel, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)),
+ SLOT(_q_sourceColumnsAboutToBeInserted(const QModelIndex &, int, int)));
+ connect(sourceModel, SIGNAL(columnsInserted(const QModelIndex &, int, int)),
+ SLOT(_q_sourceColumnsInserted(const QModelIndex &, int, int)));
+ connect(sourceModel, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)),
+ SLOT(_q_sourceColumnsAboutToBeRemoved(const QModelIndex &, int, int)));
+ connect(sourceModel, SIGNAL(columnsRemoved(const QModelIndex &, int, int)),
+ SLOT(_q_sourceColumnsRemoved(const QModelIndex &, int, int)));
+ connect(sourceModel, SIGNAL(columnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
+ SLOT(_q_sourceColumnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
+ connect(sourceModel, SIGNAL(columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
+ SLOT(_q_sourceColumnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
+ connect(sourceModel, SIGNAL(modelAboutToBeReset()),
+ SLOT(_q_sourceModelAboutToBeReset()));
+ connect(sourceModel, SIGNAL(modelReset()),
+ SLOT(_q_sourceModelReset()));
+ connect(sourceModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
+ SLOT(_q_sourceDataChanged(const QModelIndex &, const QModelIndex &)));
+ connect(sourceModel, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
+ SLOT(_q_sourceHeaderDataChanged(Qt::Orientation,int,int)));
+ connect(sourceModel, SIGNAL(layoutAboutToBeChanged()),
+ SLOT(_q_sourceLayoutAboutToBeChanged()));
+ connect(sourceModel, SIGNAL(layoutChanged()),
+ SLOT(_q_sourceLayoutChanged()));
+ }
+
+ endResetModel();
+}
+
+void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end)
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == model : true);
+ Q_Q(QIdentityProxyModel);
+ q->beginInsertColumns(q->mapFromSource(parent), start, end);
+}
+
+void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
+{
+ Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
+ Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
+ Q_Q(QIdentityProxyModel);
+ q->beginMoveColumns(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destParent), dest);
+}
+
+void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == model : true);
+ Q_Q(QIdentityProxyModel);
+ q->beginRemoveColumns(q->mapFromSource(parent), start, end);
+}
+
+void QIdentityProxyModelPrivate::_q_sourceColumnsInserted(const QModelIndex &parent, int start, int end)
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == model : true);
+ Q_Q(QIdentityProxyModel);
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+ q->endInsertColumns();
+}
+
+void QIdentityProxyModelPrivate::_q_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
+{
+ Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
+ Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
+ Q_Q(QIdentityProxyModel);
+ Q_UNUSED(sourceParent)
+ Q_UNUSED(sourceStart)
+ Q_UNUSED(sourceEnd)
+ Q_UNUSED(destParent)
+ Q_UNUSED(dest)
+ q->endMoveColumns();
+}
+
+void QIdentityProxyModelPrivate::_q_sourceColumnsRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == model : true);
+ Q_Q(QIdentityProxyModel);
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+ q->endRemoveColumns();
+}
+
+void QIdentityProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+{
+ Q_ASSERT(topLeft.isValid() ? topLeft.model() == model : true);
+ Q_ASSERT(bottomRight.isValid() ? bottomRight.model() == model : true);
+ Q_Q(QIdentityProxyModel);
+ q->dataChanged(q->mapFromSource(topLeft), q->mapFromSource(bottomRight));
+}
+
+void QIdentityProxyModelPrivate::_q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last)
+{
+ Q_Q(QIdentityProxyModel);
+ q->headerDataChanged(orientation, first, last);
+}
+
+void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged()
+{
+ if (ignoreNextLayoutAboutToBeChanged)
+ return;
+
+ Q_Q(QIdentityProxyModel);
+
+ foreach(const QPersistentModelIndex &proxyPersistentIndex, q->persistentIndexList()) {
+ proxyIndexes << proxyPersistentIndex;
+ Q_ASSERT(proxyPersistentIndex.isValid());
+ const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
+ Q_ASSERT(srcPersistentIndex.isValid());
+ layoutChangePersistentIndexes << srcPersistentIndex;
+ }
+
+ q->layoutAboutToBeChanged();
+}
+
+void QIdentityProxyModelPrivate::_q_sourceLayoutChanged()
+{
+ if (ignoreNextLayoutChanged)
+ return;
+
+ Q_Q(QIdentityProxyModel);
+
+ for (int i = 0; i < proxyIndexes.size(); ++i) {
+ q->changePersistentIndex(proxyIndexes.at(i), q->mapFromSource(layoutChangePersistentIndexes.at(i)));
+ }
+
+ layoutChangePersistentIndexes.clear();
+ proxyIndexes.clear();
+
+ q->layoutChanged();
+}
+
+void QIdentityProxyModelPrivate::_q_sourceModelAboutToBeReset()
+{
+ Q_Q(QIdentityProxyModel);
+ q->beginResetModel();
+}
+
+void QIdentityProxyModelPrivate::_q_sourceModelReset()
+{
+ Q_Q(QIdentityProxyModel);
+ q->endResetModel();
+}
+
+void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == model : true);
+ Q_Q(QIdentityProxyModel);
+ q->beginInsertRows(q->mapFromSource(parent), start, end);
+}
+
+void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
+{
+ Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
+ Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
+ Q_Q(QIdentityProxyModel);
+ q->beginMoveRows(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destParent), dest);
+}
+
+void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == model : true);
+ Q_Q(QIdentityProxyModel);
+ q->beginRemoveRows(q->mapFromSource(parent), start, end);
+}
+
+void QIdentityProxyModelPrivate::_q_sourceRowsInserted(const QModelIndex &parent, int start, int end)
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == model : true);
+ Q_Q(QIdentityProxyModel);
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+ q->endInsertRows();
+}
+
+void QIdentityProxyModelPrivate::_q_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
+{
+ Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
+ Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
+ Q_Q(QIdentityProxyModel);
+ Q_UNUSED(sourceParent)
+ Q_UNUSED(sourceStart)
+ Q_UNUSED(sourceEnd)
+ Q_UNUSED(destParent)
+ Q_UNUSED(dest)
+ q->endMoveRows();
+}
+
+void QIdentityProxyModelPrivate::_q_sourceRowsRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_ASSERT(parent.isValid() ? parent.model() == model : true);
+ Q_Q(QIdentityProxyModel);
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+ q->endRemoveRows();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qidentityproxymodel.cpp"
+
+#endif // QT_NO_IDENTITYPROXYMODEL
diff --git a/src/gui/itemviews/qidentityproxymodel.h b/src/gui/itemviews/qidentityproxymodel.h
new file mode 100644
index 0000000..40ad673
--- /dev/null
+++ b/src/gui/itemviews/qidentityproxymodel.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QIDENTITYPROXYMODEL_H
+#define QIDENTITYPROXYMODEL_H
+
+#include <QtGui/qabstractproxymodel.h>
+
+#ifndef QT_NO_IDENTITYPROXYMODEL
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QIdentityProxyModelPrivate;
+
+class Q_GUI_EXPORT QIdentityProxyModel : public QAbstractProxyModel
+{
+ Q_OBJECT
+public:
+ explicit QIdentityProxyModel(QObject* parent = 0);
+ ~QIdentityProxyModel();
+
+ int columnCount(const QModelIndex& parent = QModelIndex()) const;
+ QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
+ QModelIndex mapFromSource(const QModelIndex& sourceIndex) const;
+ QModelIndex mapToSource(const QModelIndex& proxyIndex) const;
+ QModelIndex parent(const QModelIndex& child) const;
+ int rowCount(const QModelIndex& parent = QModelIndex()) const;
+ bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent);
+
+ QItemSelection mapSelectionFromSource(const QItemSelection& selection) const;
+ QItemSelection mapSelectionToSource(const QItemSelection& selection) const;
+ QModelIndexList match(const QModelIndex& start, int role, const QVariant& value, int hits = 1, Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const;
+ void setSourceModel(QAbstractItemModel* sourceModel);
+
+ bool insertColumns(int column, int count, const QModelIndex& parent = QModelIndex());
+ bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex());
+ bool removeColumns(int column, int count, const QModelIndex& parent = QModelIndex());
+ bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex());
+
+protected:
+ QIdentityProxyModel(QIdentityProxyModelPrivate &dd, QObject* parent);
+
+private:
+ Q_DECLARE_PRIVATE(QIdentityProxyModel)
+ Q_DISABLE_COPY(QIdentityProxyModel)
+
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeInserted(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsInserted(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeRemoved(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsRemoved(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int))
+
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeInserted(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(QModelIndex,int,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int))
+
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(QModelIndex,QModelIndex))
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last))
+
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutAboutToBeChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceModelAboutToBeReset())
+ Q_PRIVATE_SLOT(d_func(), void _q_sourceModelReset())
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_IDENTITYPROXYMODEL
+
+#endif // QIDENTITYPROXYMODEL_H
+
diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp
index 1daf394..c1f957b 100644
--- a/src/gui/itemviews/qitemdelegate.cpp
+++ b/src/gui/itemviews/qitemdelegate.cpp
@@ -850,7 +850,7 @@ void QItemDelegate::drawBackground(QPainter *painter,
painter->fillRect(option.rect, option.palette.brush(cg, QPalette::Highlight));
} else {
QVariant value = index.data(Qt::BackgroundRole);
- if (qVariantCanConvert<QBrush>(value)) {
+ if (value.canConvert<QBrush>()) {
QPointF oldBO = painter->brushOrigin();
painter->setBrushOrigin(option.rect.topLeft());
painter->fillRect(option.rect, qvariant_cast<QBrush>(value));
@@ -1278,7 +1278,8 @@ bool QItemDelegate::editorEvent(QEvent *event,
// make sure that we have the right event type
if ((event->type() == QEvent::MouseButtonRelease)
- || (event->type() == QEvent::MouseButtonDblClick)) {
+ || (event->type() == QEvent::MouseButtonDblClick)
+ || (event->type() == QEvent::MouseButtonPress)) {
QRect checkRect = check(option, option.rect, Qt::Checked);
QRect emptyRect;
doLayout(option, &checkRect, &emptyRect, &emptyRect, false);
@@ -1287,7 +1288,8 @@ bool QItemDelegate::editorEvent(QEvent *event,
return false;
// eat the double click events inside the check rect
- if (event->type() == QEvent::MouseButtonDblClick)
+ if ((event->type() == QEvent::MouseButtonPress)
+ || (event->type() == QEvent::MouseButtonDblClick))
return true;
} else if (event->type() == QEvent::KeyPress) {
@@ -1326,7 +1328,7 @@ QStyleOptionViewItem QItemDelegate::setOptions(const QModelIndex &index,
// set foreground brush
value = index.data(Qt::ForegroundRole);
- if (qVariantCanConvert<QBrush>(value))
+ if (value.canConvert<QBrush>())
opt.palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value));
return opt;
diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp
index e6209f7..0d0b5b1 100644
--- a/src/gui/itemviews/qitemselectionmodel.cpp
+++ b/src/gui/itemviews/qitemselectionmodel.cpp
@@ -212,6 +212,7 @@ bool QItemSelectionRange::intersects(const QItemSelectionRange &other) const
{
return (isValid() && other.isValid()
&& parent() == other.parent()
+ && model() == other.model()
&& ((top() <= other.top() && bottom() >= other.top())
|| (top() >= other.top() && top() <= other.bottom()))
&& ((left() <= other.left() && right() >= other.left())
@@ -508,7 +509,7 @@ void QItemSelection::merge(const QItemSelection &other, QItemSelectionModel::Sel
void QItemSelection::split(const QItemSelectionRange &range,
const QItemSelectionRange &other, QItemSelection *result)
{
- if (range.parent() != other.parent())
+ if (range.parent() != other.parent() || range.model() != other.model())
return;
QModelIndex parent = other.parent();
@@ -634,6 +635,7 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &pare
}
QItemSelection deselected;
+ QItemSelection newParts;
QItemSelection::iterator it = ranges.begin();
while (it != ranges.end()) {
if (it->topLeft().parent() != parent) { // Check parents until reaching root or contained in range
@@ -659,13 +661,20 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &pare
deselected.append(QItemSelectionRange(model->index(start, it->right(), it->parent()), it->bottomRight()));
*it = QItemSelectionRange(it->topLeft(), model->index(start - 1, it->right(), it->parent()));
++it;
- } else {
- if (it->top() < start && end < it->bottom()) // Middle intersection (do nothing)
- deselected.append(QItemSelectionRange(model->index(start, it->right(), it->parent()),
- model->index(end, it->left(), it->parent())));
+ } else if (it->top() < start && end < it->bottom()) { // Middle intersection
+ // If the parent contains (1, 2, 3, 4, 5, 6, 7, 8) and [3, 4, 5, 6] is selected,
+ // and [4, 5] is removed, we need to split [3, 4, 5, 6] into [3], [4, 5] and [6].
+ // [4, 5] is appended to deselected, and [3] and [6] remain part of the selection
+ // in ranges.
+ const QItemSelectionRange removedRange(model->index(start, it->right(), it->parent()),
+ model->index(end, it->left(), it->parent()));
+ deselected.append(removedRange);
+ QItemSelection::split(*it, removedRange, &newParts);
+ it = ranges.erase(it);
+ } else
++it;
- }
}
+ ranges.append(newParts);
if (!deselected.isEmpty())
emit q->selectionChanged(QItemSelection(), deselected);
@@ -1136,11 +1145,8 @@ void QItemSelectionModel::clearSelection()
Q_D(QItemSelectionModel);
if (d->ranges.count() == 0 && d->currentSelection.count() == 0)
return;
- QItemSelection selection = d->ranges;
- selection.merge(d->currentSelection, d->currentCommand);
- d->ranges.clear();
- d->currentSelection.clear();
- emit selectionChanged(QItemSelection(), selection);
+
+ select(QItemSelection(), Clear);
}
diff --git a/src/gui/itemviews/qitemselectionmodel.h b/src/gui/itemviews/qitemselectionmodel.h
index 43327aa..3f4aa72 100644
--- a/src/gui/itemviews/qitemselectionmodel.h
+++ b/src/gui/itemviews/qitemselectionmodel.h
@@ -101,6 +101,30 @@ public:
{ return (tl == other.tl && br == other.br); }
inline bool operator!=(const QItemSelectionRange &other) const
{ return !operator==(other); }
+ inline bool operator<(const QItemSelectionRange &other) const
+ {
+ // Comparing parents will compare the models, but if two equivalent ranges
+ // in two different models have invalid parents, they would appear the same
+ if (other.tl.model() == tl.model()) {
+ // parent has to be calculated, so we only do so once.
+ const QModelIndex topLeftParent = tl.parent();
+ const QModelIndex otherTopLeftParent = other.tl.parent();
+ if (topLeftParent == otherTopLeftParent) {
+ if (other.tl.row() == tl.row()) {
+ if (other.tl.column() == tl.column()) {
+ if (other.br.row() == br.row()) {
+ return br.column() < other.br.column();
+ }
+ return br.row() < other.br.row();
+ }
+ return tl.column() < other.tl.column();
+ }
+ return tl.row() < other.tl.row();
+ }
+ return topLeftParent < otherTopLeftParent;
+ }
+ return tl.model() < other.tl.model();
+ }
inline bool isValid() const
{
diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp
index 8c83642..a0955d2 100644
--- a/src/gui/itemviews/qlistview.cpp
+++ b/src/gui/itemviews/qlistview.cpp
@@ -756,10 +756,13 @@ void QListView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int e
// if the parent is above d->root in the tree, nothing will happen
QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);
if (parent == d->root) {
- for (int i = d->hiddenRows.count() - 1; i >= 0; --i) {
- int hiddenRow = d->hiddenRows.at(i).row();
+ QSet<QPersistentModelIndex>::iterator it = d->hiddenRows.begin();
+ while (it != d->hiddenRows.end()) {
+ int hiddenRow = it->row();
if (hiddenRow >= start && hiddenRow <= end) {
- d->hiddenRows.remove(i);
+ it = d->hiddenRows.erase(it);
+ } else {
+ ++it;
}
}
}
@@ -1033,16 +1036,7 @@ void QListView::paintEvent(QPaintEvent *e)
previousRow = row;
}
- if (const QWidget *widget = d->editorForIndex(*it).editor) {
- QRegion itemGeometry(option.rect);
- QRegion widgetGeometry(widget->geometry());
- painter.save();
- painter.setClipRegion(itemGeometry.subtracted(widgetGeometry));
- d->delegateForIndex(*it)->paint(&painter, option, *it);
- painter.restore();
- } else {
- d->delegateForIndex(*it)->paint(&painter, option, *it);
- }
+ d->delegateForIndex(*it)->paint(&painter, option, *it);
}
#ifndef QT_NO_DRAGANDDROP
@@ -1496,19 +1490,20 @@ void QListView::updateGeometries()
// if the scroll bars are turned off, we resize the contents to the viewport
if (d->movement == Static && !d->isWrapping()) {
- d->layoutChildren(); // we need the viewport size to be updated
+ const QSize maxSize = maximumViewportSize();
if (d->flow == TopToBottom) {
if (horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) {
- d->setContentsSize(viewport()->width(), contentsSize().height());
+ d->setContentsSize(maxSize.width(), contentsSize().height());
horizontalScrollBar()->setRange(0, 0); // we see all the contents anyway
}
} else { // LeftToRight
if (verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) {
- d->setContentsSize(contentsSize().width(), viewport()->height());
+ d->setContentsSize(contentsSize().width(), maxSize.height());
verticalScrollBar()->setRange(0, 0); // we see all the contents anyway
}
}
}
+
}
/*!
@@ -1833,6 +1828,14 @@ QAbstractItemView::DropIndicatorPosition QListViewPrivate::position(const QPoint
else
return QAbstractItemViewPrivate::position(pos, rect, idx);
}
+
+bool QListViewPrivate::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex)
+{
+ if (viewMode == QListView::ListMode && flow == QListView::LeftToRight)
+ return static_cast<QListModeViewBase *>(commonListView)->dropOn(event, dropRow, dropCol, dropIndex);
+ else
+ return QAbstractItemViewPrivate::dropOn(event, dropRow, dropCol, dropIndex);
+}
#endif
/*
@@ -1841,12 +1844,12 @@ QAbstractItemView::DropIndicatorPosition QListViewPrivate::position(const QPoint
void QCommonListViewBase::appendHiddenRow(int row)
{
- dd->hiddenRows.append(dd->model->index(row, 0, qq->rootIndex()));
+ dd->hiddenRows.insert(dd->model->index(row, 0, qq->rootIndex()));
}
void QCommonListViewBase::removeHiddenRow(int row)
{
- dd->hiddenRows.remove(dd->hiddenRows.indexOf(dd->model->index(row, 0, qq->rootIndex())));
+ dd->hiddenRows.remove(dd->model->index(row, 0, qq->rootIndex()));
}
void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step)
@@ -1960,7 +1963,13 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
// ignore by default
event->ignore();
- QModelIndex index = qq->indexAt(event->pos());
+ // can't use indexAt, doesn't account for spacing.
+ QPoint p = event->pos();
+ QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
+ rect.adjust(-dd->spacing(), -dd->spacing(), dd->spacing(), dd->spacing());
+ const QVector<QModelIndex> intersectVector = dd->intersectingSet(rect);
+ QModelIndex index = intersectVector.count() > 0
+ ? intersectVector.last() : QModelIndex();
dd->hover = index;
if (!dd->droppingOnItself(event, index)
&& dd->canDecode(event)) {
@@ -1968,10 +1977,11 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
if (index.isValid() && dd->showDropIndicator) {
QRect rect = qq->visualRect(index);
dd->dropIndicatorPosition = position(event->pos(), rect, index);
+ // if spacing, should try to draw between items, not just next to item.
switch (dd->dropIndicatorPosition) {
case QAbstractItemView::AboveItem:
if (dd->isIndexDropEnabled(index.parent())) {
- dd->dropIndicatorRect = QRect(rect.left(), rect.top(), 0, rect.height());
+ dd->dropIndicatorRect = QRect(rect.left()-dd->spacing(), rect.top(), 0, rect.height());
event->accept();
} else {
dd->dropIndicatorRect = QRect();
@@ -1979,7 +1989,7 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
break;
case QAbstractItemView::BelowItem:
if (dd->isIndexDropEnabled(index.parent())) {
- dd->dropIndicatorRect = QRect(rect.right(), rect.top(), 0, rect.height());
+ dd->dropIndicatorRect = QRect(rect.right()+dd->spacing(), rect.top(), 0, rect.height());
event->accept();
} else {
dd->dropIndicatorRect = QRect();
@@ -2014,6 +2024,68 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
qq->startAutoScroll();
}
+/*!
+ If the event hasn't already been accepted, determines the index to drop on.
+
+ if (row == -1 && col == -1)
+ // append to this drop index
+ else
+ // place at row, col in drop index
+
+ If it returns true a drop can be done, and dropRow, dropCol and dropIndex reflects the position of the drop.
+ \internal
+ */
+bool QListModeViewBase::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex)
+{
+ if (event->isAccepted())
+ return false;
+
+ QModelIndex index;
+ if (dd->viewport->rect().contains(event->pos())) {
+ // can't use indexAt, doesn't account for spacing.
+ QPoint p = event->pos();
+ QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
+ rect.adjust(-dd->spacing(), -dd->spacing(), dd->spacing(), dd->spacing());
+ const QVector<QModelIndex> intersectVector = dd->intersectingSet(rect);
+ index = intersectVector.count() > 0
+ ? intersectVector.last() : QModelIndex();
+ if (!index.isValid())
+ index = dd->root;
+ }
+
+ // If we are allowed to do the drop
+ if (dd->model->supportedDropActions() & event->dropAction()) {
+ int row = -1;
+ int col = -1;
+ if (index != dd->root) {
+ dd->dropIndicatorPosition = position(event->pos(), qq->visualRect(index), index);
+ switch (dd->dropIndicatorPosition) {
+ case QAbstractItemView::AboveItem:
+ row = index.row();
+ col = index.column();
+ index = index.parent();
+ break;
+ case QAbstractItemView::BelowItem:
+ row = index.row() + 1;
+ col = index.column();
+ index = index.parent();
+ break;
+ case QAbstractItemView::OnItem:
+ case QAbstractItemView::OnViewport:
+ break;
+ }
+ } else {
+ dd->dropIndicatorPosition = QAbstractItemView::OnViewport;
+ }
+ *dropIndex = index;
+ *dropRow = row;
+ *dropCol = col;
+ if (!dd->droppingOnItself(event, index))
+ return true;
+ }
+ return false;
+}
+
#endif //QT_NO_DRAGANDDROP
void QListModeViewBase::updateVerticalScrollBar(const QSize &step)
@@ -2107,7 +2179,7 @@ int QListModeViewBase::verticalOffset() const
int value = verticalScrollBar()->value();
if (value >= segmentPositions.count())
return 0;
- return segmentPositions.at(value);
+ return segmentPositions.at(value) - spacing();
}
} else if (flow() == QListView::TopToBottom && !flowPositions.isEmpty()) {
int value = verticalScrollBar()->value();
@@ -2155,14 +2227,14 @@ void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
if (horizontal && flow() == QListView::TopToBottom && dx != 0) {
int currentValue = qBound(0, horizontalValue, max);
int previousValue = qBound(0, currentValue + dx, max);
- int currentCoordinate = segmentPositions.at(currentValue);
- int previousCoordinate = segmentPositions.at(previousValue);
+ int currentCoordinate = segmentPositions.at(currentValue) - spacing();
+ int previousCoordinate = segmentPositions.at(previousValue) - spacing();
dx = previousCoordinate - currentCoordinate;
} else if (vertical && flow() == QListView::LeftToRight && dy != 0) {
int currentValue = qBound(0, verticalValue, max);
int previousValue = qBound(0, currentValue + dy, max);
- int currentCoordinate = segmentPositions.at(currentValue);
- int previousCoordinate = segmentPositions.at(previousValue);
+ int currentCoordinate = segmentPositions.at(currentValue) - spacing();
+ int previousCoordinate = segmentPositions.at(previousValue) - spacing();
dy = previousCoordinate - currentCoordinate;
}
} else {
@@ -2330,6 +2402,8 @@ void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info)
segmentExtents.append(flowPosition);
flowPosition = info.spacing + segStartPosition;
segPosition += deltaSegPosition;
+ if (info.wrap)
+ segPosition += info.spacing;
segmentPositions.append(segPosition);
segmentStartRows.append(row);
deltaSegPosition = 0;
@@ -3094,7 +3168,11 @@ void QListView::currentChanged(const QModelIndex &current, const QModelIndex &pr
if (QAccessible::isActive()) {
if (current.isValid()) {
int entry = visualIndex(current) + 1;
+#ifdef Q_WS_X11
+ QAccessible::updateAccessibility(this, entry, QAccessible::Focus);
+#else
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
+#endif
}
}
#endif
@@ -3113,12 +3191,20 @@ void QListView::selectionChanged(const QItemSelection &selected,
QModelIndex sel = selected.indexes().value(0);
if (sel.isValid()) {
int entry = visualIndex(sel) + 1;
+#ifdef Q_WS_X11
+ QAccessible::updateAccessibility(this, entry, QAccessible::Selection);
+#else
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection);
+#endif
}
QModelIndex desel = deselected.indexes().value(0);
if (desel.isValid()) {
int entry = visualIndex(desel) + 1;
+#ifdef Q_WS_X11
+ QAccessible::updateAccessibility(this, entry, QAccessible::SelectionRemove);
+#else
QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove);
+#endif
}
}
#endif
diff --git a/src/gui/itemviews/qlistview_p.h b/src/gui/itemviews/qlistview_p.h
index 6b4a65d..6a7acf6 100644
--- a/src/gui/itemviews/qlistview_p.h
+++ b/src/gui/itemviews/qlistview_p.h
@@ -237,6 +237,7 @@ public:
// WARNING: Plenty of duplicated code from QAbstractItemView{,Private}.
QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
void dragMoveEvent(QDragMoveEvent *e);
+ bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index);
#endif
private:
@@ -364,6 +365,7 @@ public:
#ifndef QT_NO_DRAGANDDROP
virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
+ bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index);
#endif
inline void setGridSize(const QSize &size) { grid = size; }
@@ -376,7 +378,10 @@ public:
inline bool isSelectionRectVisible() const { return showElasticBand; }
inline QModelIndex modelIndex(int row) const { return model->index(row, column, root); }
- inline bool isHidden(int row) const { return hiddenRows.contains(model->index(row, 0, root)); }
+ inline bool isHidden(int row) const {
+ QModelIndex idx = model->index(row, 0, root);
+ return isPersistent(idx) && hiddenRows.contains(idx);
+ }
inline bool isHiddenOrDisabled(int row) const { return isHidden(row) || !isIndexEnabled(modelIndex(row)); }
inline void removeCurrentAndDisabled(QVector<QModelIndex> *indexes, const QModelIndex &current) const {
@@ -430,7 +435,7 @@ public:
QBasicTimer batchLayoutTimer;
// used for hidden items
- QVector<QPersistentModelIndex> hiddenRows;
+ QSet<QPersistentModelIndex> hiddenRows;
int column;
bool uniformItemSizes;
diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp
index 415bd54..b749286 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.cpp
+++ b/src/gui/itemviews/qsortfilterproxymodel.cpp
@@ -362,6 +362,7 @@ QModelIndex QSortFilterProxyModelPrivate::proxy_to_source(const QModelIndex &pro
return QModelIndex(); // for now; we may want to be able to set a root index later
if (proxy_index.model() != q_func()) {
qWarning() << "QSortFilterProxyModel: index from wrong model passed to mapToSource";
+ Q_ASSERT(!"QSortFilterProxyModel: index from wrong model passed to mapToSource");
return QModelIndex();
}
IndexMap::const_iterator it = index_to_iterator(proxy_index);
@@ -379,6 +380,7 @@ QModelIndex QSortFilterProxyModelPrivate::source_to_proxy(const QModelIndex &sou
return QModelIndex(); // for now; we may want to be able to set a root index later
if (source_index.model() != model) {
qWarning() << "QSortFilterProxyModel: index from wrong model passed to mapFromSource";
+ Q_ASSERT(!"QSortFilterProxyModel: index from wrong model passed to mapFromSource");
return QModelIndex();
}
QModelIndex source_parent = source_index.parent();
@@ -1500,7 +1502,7 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsRemoved(
\l{Model Subclassing Reference}.
\sa QAbstractProxyModel, QAbstractItemModel, {Model/View Programming},
- {Basic Sort/Filter Model Example}, {Custom Sort/Filter Model Example}
+ {Basic Sort/Filter Model Example}, {Custom Sort/Filter Model Example}, QIdentityProxyModel
*/
/*!
diff --git a/src/gui/itemviews/qstringlistmodel.cpp b/src/gui/itemviews/qstringlistmodel.cpp
index df7e7c6..367decc 100644
--- a/src/gui/itemviews/qstringlistmodel.cpp
+++ b/src/gui/itemviews/qstringlistmodel.cpp
@@ -290,8 +290,9 @@ QStringList QStringListModel::stringList() const
*/
void QStringListModel::setStringList(const QStringList &strings)
{
+ emit beginResetModel();
lst = strings;
- reset();
+ emit endResetModel();
}
/*!
diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp
index 1eeb8f7..931d870 100644
--- a/src/gui/itemviews/qstyleditemdelegate.cpp
+++ b/src/gui/itemviews/qstyleditemdelegate.cpp
@@ -331,7 +331,7 @@ void QStyledItemDelegate::initStyleOption(QStyleOptionViewItem *option,
option->displayAlignment = Qt::Alignment(value.toInt());
value = index.data(Qt::ForegroundRole);
- if (qVariantCanConvert<QBrush>(value))
+ if (value.canConvert<QBrush>())
option->palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value));
if (QStyleOptionViewItemV4 *v4 = qstyleoption_cast<QStyleOptionViewItemV4 *>(option)) {
@@ -732,7 +732,8 @@ bool QStyledItemDelegate::editorEvent(QEvent *event,
// make sure that we have the right event type
if ((event->type() == QEvent::MouseButtonRelease)
- || (event->type() == QEvent::MouseButtonDblClick)) {
+ || (event->type() == QEvent::MouseButtonDblClick)
+ || (event->type() == QEvent::MouseButtonPress)) {
QStyleOptionViewItemV4 viewOpt(option);
initStyleOption(&viewOpt, index);
QRect checkRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &viewOpt, widget);
@@ -740,8 +741,8 @@ bool QStyledItemDelegate::editorEvent(QEvent *event,
if (me->button() != Qt::LeftButton || !checkRect.contains(me->pos()))
return false;
- // eat the double click events inside the check rect
- if (event->type() == QEvent::MouseButtonDblClick)
+ if ((event->type() == QEvent::MouseButtonPress)
+ || (event->type() == QEvent::MouseButtonDblClick))
return true;
} else if (event->type() == QEvent::KeyPress) {
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index 056e633..6f532eb 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -926,14 +926,7 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItemV4
q->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, q);
- if (const QWidget *widget = editorForIndex(index).editor) {
- painter->save();
- painter->setClipRect(widget->geometry());
- q->itemDelegate(index)->paint(painter, opt, index);
- painter->restore();
- } else {
- q->itemDelegate(index)->paint(painter, opt, index);
- }
+ q->itemDelegate(index)->paint(painter, opt, index);
}
/*!
@@ -1109,6 +1102,21 @@ void QTableView::setRootIndex(const QModelIndex &index)
}
/*!
+ \internal
+*/
+void QTableView::doItemsLayout()
+{
+ Q_D(QTableView);
+ QAbstractItemView::doItemsLayout();
+ if (verticalScrollMode() == QAbstractItemView::ScrollPerItem)
+ d->verticalHeader->setOffsetToSectionPosition(verticalScrollBar()->value());
+ else
+ d->verticalHeader->setOffset(verticalScrollBar()->value());
+ if (!d->verticalHeader->updatesEnabled())
+ d->verticalHeader->setUpdatesEnabled(true);
+}
+
+/*!
\reimp
*/
void QTableView::setSelectionModel(QItemSelectionModel *selectionModel)
@@ -1292,7 +1300,6 @@ void QTableView::paintEvent(QPaintEvent *event)
const QPen gridPen = QPen(gridColor, 0, d->gridStyle);
const QHeaderView *verticalHeader = d->verticalHeader;
const QHeaderView *horizontalHeader = d->horizontalHeader;
- const QStyle::State state = option.state;
const bool alternate = d->alternatingColors;
const bool rightToLeft = isRightToLeft();
@@ -1982,9 +1989,13 @@ QModelIndexList QTableView::selectedIndexes() const
previous number of rows is specified by \a oldCount, and the new
number of rows is specified by \a newCount.
*/
-void QTableView::rowCountChanged(int /*oldCount*/, int /*newCount*/ )
+void QTableView::rowCountChanged(int oldCount, int newCount )
{
Q_D(QTableView);
+ //when removing rows, we need to disable updates for the header until the geometries have been
+ //updated and the offset has been adjusted, or we risk calling paintSection for all the sections
+ if (newCount < oldCount)
+ d->verticalHeader->setUpdatesEnabled(false);
d->doDelayedItemsLayout();
}
@@ -2166,7 +2177,7 @@ int QTableView::sizeHintForRow(int row) const
option.rect.setWidth(columnWidth(index.column()));
}
- QWidget *editor = d->editorForIndex(index).editor;
+ QWidget *editor = d->editorForIndex(index).widget.data();
if (editor && d->persistent.contains(editor)) {
hint = qMax(hint, editor->sizeHint().height());
int min = editor->minimumSize().height();
@@ -2219,7 +2230,7 @@ int QTableView::sizeHintForColumn(int column) const
continue;
index = d->model->index(logicalRow, column, d->root);
- QWidget *editor = d->editorForIndex(index).editor;
+ QWidget *editor = d->editorForIndex(index).widget.data();
if (editor && d->persistent.contains(editor)) {
hint = qMax(hint, editor->sizeHint().width());
int min = editor->minimumSize().width();
@@ -3153,10 +3164,16 @@ void QTableView::currentChanged(const QModelIndex &current, const QModelIndex &p
#ifndef QT_NO_ACCESSIBILITY
if (QAccessible::isActive()) {
if (current.isValid()) {
+#ifdef Q_WS_X11
+ Q_D(QTableView);
+ int entry = d->accessibleTable2Index(current);
+ QAccessible::updateAccessibility(this, entry, QAccessible::Focus);
+#else
int entry = visualIndex(current) + 1;
if (horizontalHeader())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
+#endif
}
}
#endif
@@ -3169,22 +3186,33 @@ void QTableView::currentChanged(const QModelIndex &current, const QModelIndex &p
void QTableView::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
+ Q_D(QTableView);
#ifndef QT_NO_ACCESSIBILITY
if (QAccessible::isActive()) {
// ### does not work properly for selection ranges.
QModelIndex sel = selected.indexes().value(0);
if (sel.isValid()) {
+#ifdef Q_WS_X11
+ int entry = d->accessibleTable2Index(sel);
+ QAccessible::updateAccessibility(this, entry, QAccessible::Selection);
+#else
int entry = visualIndex(sel);
if (horizontalHeader())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection);
+#endif
}
QModelIndex desel = deselected.indexes().value(0);
if (desel.isValid()) {
+#ifdef Q_WS_X11
+ int entry = d->accessibleTable2Index(sel);
+ QAccessible::updateAccessibility(this, entry, QAccessible::SelectionRemove);
+#else
int entry = visualIndex(sel);
if (horizontalHeader())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove);
+#endif
}
}
#endif
diff --git a/src/gui/itemviews/qtableview.h b/src/gui/itemviews/qtableview.h
index 7266dda..27b2dcc 100644
--- a/src/gui/itemviews/qtableview.h
+++ b/src/gui/itemviews/qtableview.h
@@ -71,6 +71,7 @@ public:
void setModel(QAbstractItemModel *model);
void setRootIndex(const QModelIndex &index);
void setSelectionModel(QItemSelectionModel *selectionModel);
+ void doItemsLayout();
QHeaderView *horizontalHeader() const;
QHeaderView *verticalHeader() const;
diff --git a/src/gui/itemviews/qtableview_p.h b/src/gui/itemviews/qtableview_p.h
index f973acf..dce0ed0 100644
--- a/src/gui/itemviews/qtableview_p.h
+++ b/src/gui/itemviews/qtableview_p.h
@@ -167,6 +167,11 @@ public:
return horizontalHeader->logicalIndex(visualCol);
}
+ inline int accessibleTable2Index(const QModelIndex &index) const {
+ return (index.row() + (horizontalHeader ? 1 : 0)) * (index.model()->columnCount() + (verticalHeader ? 1 : 0))
+ + index.column() + (verticalHeader ? 1 : 0) + 1;
+ }
+
int sectionSpanEndLogical(const QHeaderView *header, int logical, int span) const;
int sectionSpanSize(const QHeaderView *header, int logical, int span) const;
bool spanContainsSection(const QHeaderView *header, int logical, int spanLogical, int span) const;
diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp
index e3d71c6..9228ac8 100644
--- a/src/gui/itemviews/qtreeview.cpp
+++ b/src/gui/itemviews/qtreeview.cpp
@@ -54,6 +54,7 @@
#include <qdebug.h>
#ifndef QT_NO_ACCESSIBILITY
#include <qaccessible.h>
+#include <qaccessible2.h>
#endif
#include <private/qtreeview_p.h>
@@ -1493,7 +1494,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
// when the row contains an index widget which has focus,
// we want to paint the entire row as active
bool indexWidgetHasFocus = false;
- if ((current.row() == index.row()) && !d->editors.isEmpty()) {
+ if ((current.row() == index.row()) && !d->editorIndexHash.isEmpty()) {
const int r = index.row();
QWidget *fw = QApplication::focusWidget();
for (int c = 0; c < header->count(); ++c) {
@@ -1669,14 +1670,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
opt.state = oldState;
}
- if (const QWidget *widget = d->editorForIndex(modelIndex).editor) {
- painter->save();
- painter->setClipRect(widget->geometry());
- d->delegateForIndex(modelIndex)->paint(painter, opt, modelIndex);
- painter->restore();
- } else {
- d->delegateForIndex(modelIndex)->paint(painter, opt, modelIndex);
- }
+ d->delegateForIndex(modelIndex)->paint(painter, opt, modelIndex);
}
if (currentRowHasFocus) {
@@ -2395,7 +2389,7 @@ void QTreeView::scrollContentsBy(int dx, int dy)
int viewCount = d->viewport->height() / itemHeight;
int maxDeltaY = qMin(d->viewItems.count(), viewCount);
// no need to do a lot of work if we are going to redraw the whole thing anyway
- if (qAbs(dy) > qAbs(maxDeltaY) && d->editors.isEmpty()) {
+ if (qAbs(dy) > qAbs(maxDeltaY) && d->editorIndexHash.isEmpty()) {
verticalScrollBar()->update();
d->viewport->update();
return;
@@ -2469,11 +2463,9 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end)
}
const int parentItem = d->viewIndex(parent);
- if (((parentItem != -1) && d->viewItems.at(parentItem).expanded && updatesEnabled())
+ if (((parentItem != -1) && d->viewItems.at(parentItem).expanded)
|| (parent == d->root)) {
d->doDelayedItemsLayout();
- } else if ((parentItem != -1) && d->viewItems.at(parentItem).expanded) {
- d->doDelayedItemsLayout();
} else if (parentItem != -1 && (d->model->rowCount(parent) == end - start + 1)) {
// the parent just went from 0 children to more. update to re-paint the decoration
d->viewItems[parentItem].hasChildren = true;
@@ -2727,7 +2719,7 @@ int QTreeView::sizeHintForColumn(int column) const
continue; // we have no good size hint
QModelIndex index = viewItems.at(i).index;
index = index.sibling(index.row(), column);
- QWidget *editor = d->editorForIndex(index).editor;
+ QWidget *editor = d->editorForIndex(index).widget.data();
if (editor && d->persistent.contains(editor)) {
w = qMax(w, editor->sizeHint().width());
int min = editor->minimumSize().width();
@@ -2792,7 +2784,7 @@ int QTreeView::indexRowSizeHint(const QModelIndex &index) const
continue;
QModelIndex idx = d->model->index(indexRow, logicalColumn, parent);
if (idx.isValid()) {
- QWidget *editor = d->editorForIndex(idx).editor;
+ QWidget *editor = d->editorForIndex(idx).widget.data();
if (editor && d->persistent.contains(editor)) {
height = qMax(height, editor->sizeHint().height());
int min = editor->minimumSize().height();
@@ -2871,13 +2863,13 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
if (emitSignal && animationsEnabled)
prepareAnimatedOperation(item, QVariantAnimation::Forward);
#endif //QT_NO_ANIMATION
- QAbstractItemView::State oldState = state;
+ stateBeforeAnimation = state;
q->setState(QAbstractItemView::ExpandingState);
const QModelIndex index = viewItems.at(item).index;
storeExpanded(index);
viewItems[item].expanded = true;
layout(item);
- q->setState(oldState);
+ q->setState(stateBeforeAnimation);
if (model->canFetchMore(index))
model->fetchMore(index);
@@ -2892,20 +2884,36 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
void QTreeViewPrivate::insertViewItems(int pos, int count, const QTreeViewItem &viewItem)
{
+ Q_Q(QTreeView);
viewItems.insert(pos, count, viewItem);
QTreeViewItem *items = viewItems.data();
for (int i = pos + count; i < viewItems.count(); i++)
if (items[i].parentItem >= pos)
items[i].parentItem += count;
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
void QTreeViewPrivate::removeViewItems(int pos, int count)
{
+ Q_Q(QTreeView);
viewItems.remove(pos, count);
QTreeViewItem *items = viewItems.data();
for (int i = pos; i < viewItems.count(); i++)
if (items[i].parentItem >= pos)
items[i].parentItem -= count;
+#ifndef QT_NO_ACCESSIBILITY
+#ifdef Q_WS_X11
+ if (QAccessible::isActive()) {
+ QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged);
+ }
+#endif
+#endif
}
#if 0
@@ -2946,7 +2954,7 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal)
prepareAnimatedOperation(item, QVariantAnimation::Backward);
#endif //QT_NO_ANIMATION
- QAbstractItemView::State oldState = state;
+ stateBeforeAnimation = state;
q->setState(QAbstractItemView::CollapsingState);
expandedIndexes.erase(it);
viewItems[item].expanded = false;
@@ -2956,7 +2964,7 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal)
index = viewItems[index].parentItem;
}
removeViewItems(item + 1, total); // collapse
- q->setState(oldState);
+ q->setState(stateBeforeAnimation);
if (emitSignal) {
emit q->collapsed(modelIndex);
@@ -3041,9 +3049,9 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons
//and now let's render the editors the editors
QStyleOptionViewItemV4 option = viewOptionsV4();
- for (QList<QEditorInfo>::const_iterator it = editors.constBegin(); it != editors.constEnd(); ++it) {
- QWidget *editor = it->editor;
- QModelIndex index = it->index;
+ for (QEditorIndexHash::const_iterator it = editorIndexHash.constBegin(); it != editorIndexHash.constEnd(); ++it) {
+ QWidget *editor = it.key();
+ const QModelIndex &index = it.value();
option.rect = q->visualRect(index);
if (option.rect.isValid()) {
@@ -3067,7 +3075,7 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons
void QTreeViewPrivate::_q_endAnimatedOperation()
{
Q_Q(QTreeView);
- q->setState(QAbstractItemView::NoState);
+ q->setState(stateBeforeAnimation);
q->updateGeometries();
viewport->update();
}
@@ -3696,14 +3704,6 @@ void QTreeViewPrivate::_q_sortIndicatorChanged(int column, Qt::SortOrder order)
*/
void QTreeView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
-#ifndef QT_NO_ACCESSIBILITY
- if (QAccessible::isActive()) {
- int entry = visualIndex(current) + 1;
- if (header())
- ++entry;
- QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
- }
-#endif
QAbstractItemView::currentChanged(current, previous);
if (allColumnsShowFocus()) {
@@ -3720,6 +3720,19 @@ void QTreeView::currentChanged(const QModelIndex &current, const QModelIndex &pr
viewport()->update(currentRect);
}
}
+#ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive() && current.isValid()) {
+#ifdef Q_WS_X11
+ int entry = (visualIndex(current) + (header()?1:0))*current.model()->columnCount()+current.column() + 1;
+ QAccessible::updateAccessibility(this, entry, QAccessible::Focus);
+#else
+ int entry = visualIndex(current) + 1;
+ if (header())
+ ++entry;
+ QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus);
+#endif
+ }
+#endif
}
/*!
@@ -3728,26 +3741,38 @@ void QTreeView::currentChanged(const QModelIndex &current, const QModelIndex &pr
void QTreeView::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
+ QAbstractItemView::selectionChanged(selected, deselected);
#ifndef QT_NO_ACCESSIBILITY
if (QAccessible::isActive()) {
// ### does not work properly for selection ranges.
QModelIndex sel = selected.indexes().value(0);
if (sel.isValid()) {
+#ifdef Q_WS_X11
+ int entry = (visualIndex(sel) + (header()?1:0))*sel.model()->columnCount()+sel.column() + 1;
+ Q_ASSERT(entry > 0);
+ QAccessible::updateAccessibility(this, entry, QAccessible::Selection);
+#else
int entry = visualIndex(sel) + 1;
if (header())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection);
+#endif
}
QModelIndex desel = deselected.indexes().value(0);
if (desel.isValid()) {
+#ifdef Q_WS_X11
+ int entry = (visualIndex(desel) + (header()?1:0))*desel.model()->columnCount()+desel.column() + 1;
+ Q_ASSERT(entry > 0);
+ QAccessible::updateAccessibility(this, entry, QAccessible::SelectionRemove);
+#else
int entry = visualIndex(desel) + 1;
if (header())
++entry;
QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove);
+#endif
}
}
#endif
- QAbstractItemView::selectionChanged(selected, deselected);
}
int QTreeView::visualIndex(const QModelIndex &index) const
diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h
index 26c7315..b77da4e 100644
--- a/src/gui/itemviews/qtreeview.h
+++ b/src/gui/itemviews/qtreeview.h
@@ -219,6 +219,9 @@ protected:
private:
friend class QAccessibleItemView;
+ friend class QAccessibleTable2;
+ friend class QAccessibleTree;
+ friend class QAccessibleTable2Cell;
int visualIndex(const QModelIndex &index) const;
Q_DECLARE_PRIVATE(QTreeView)
diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h
index b6d8458..a9dc452 100644
--- a/src/gui/itemviews/qtreeview_p.h
+++ b/src/gui/itemviews/qtreeview_p.h
@@ -78,7 +78,7 @@ struct QTreeViewItem
Q_DECLARE_TYPEINFO(QTreeViewItem, Q_MOVABLE_TYPE);
-class QTreeViewPrivate : public QAbstractItemViewPrivate
+class Q_GUI_EXPORT QTreeViewPrivate : public QAbstractItemViewPrivate
{
Q_DECLARE_PUBLIC(QTreeView)
public:
@@ -223,6 +223,10 @@ public:
inline void invalidateHeightCache(int item) const
{ viewItems[item].height = 0; }
+ inline int accessibleTable2Index(const QModelIndex &index) const {
+ return (viewIndex(index) + (header ? 1 : 0)) * model->columnCount()+index.column() + 1;
+ }
+
// used for spanning rows
QVector<QPersistentModelIndex> spanningIndexes;