diff options
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp | 35 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsproxywidget.cpp | 4 | ||||
-rw-r--r-- | src/gui/itemviews/qabstractproxymodel.cpp | 24 | ||||
-rw-r--r-- | src/gui/itemviews/qabstractproxymodel.h | 3 | ||||
-rw-r--r-- | src/gui/itemviews/qstringlistmodel.cpp | 3 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 4 | ||||
-rw-r--r-- | src/gui/painting/qunifiedtoolbarsurface_mac.cpp | 4 | ||||
-rw-r--r-- | src/gui/painting/qunifiedtoolbarsurface_mac_p.h | 4 | ||||
-rw-r--r-- | src/gui/painting/qwindowsurface_raster.cpp | 8 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase.cpp | 10 | ||||
-rw-r--r-- | src/gui/widgets/qmainwindow.cpp | 2 | ||||
-rw-r--r-- | src/gui/widgets/qmainwindowlayout_mac.mm | 2 | ||||
-rw-r--r-- | src/gui/widgets/qmainwindowlayout_p.h | 3 | ||||
-rw-r--r-- | tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp | 65 | ||||
-rw-r--r-- | tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp | 138 |
16 files changed, 298 insertions, 13 deletions
@@ -3161,7 +3161,7 @@ else CFG_FRAMEWORK=no fi -QMAKE_CONF_COMPILER=`getQMakeConf "$XQMAKESPEC" | grep "\(^\|\s\)QMAKE_CXX[^_A-Z0-9]" | sed "s,.* *= *\(.*\)$,\1," | tail -1` +QMAKE_CONF_COMPILER=`getQMakeConf "$XQMAKESPEC" | grep "\(^\| \)QMAKE_CXX[^_A-Z0-9]" | sed "s,.* *= *\(.*\)$,\1," | tail -1` TEST_COMPILER="$CXX" [ -z "$TEST_COMPILER" ] && TEST_COMPILER=$QMAKE_CONF_COMPILER diff --git a/doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp b/doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp index 59e6ae0..07ff2a0 100644 --- a/doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp +++ b/doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp @@ -86,3 +86,38 @@ beginMoveRows(parent, 2, 2, parent, 0); //! [9] beginMoveRows(parent, 2, 2, parent, 4); //! [9] + + +//! [10] +class CustomDataProxy : public QSortFilterProxyModel +{ + Q_OBJECT +public: + CustomDataProxy(QObject *parent) + : QSortFilterProxyModel(parent) + { + } + + ... + + QVariant data(const QModelIndex &index, int role) + { + if (role != Qt::BackgroundRole) + return QSortFilterProxyModel::data(index, role); + + if (m_customData.contains(index.row())) + return m_customData.value(index.row()); + return QSortFilterProxyModel::data(index, role); + } + +private slots: + void resetInternalData() + { + m_customData.clear(); + } + +private: + QHash<int, QVariant> m_customData; +}; +//! [10] + diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index 320395e..ce63659 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -266,8 +266,8 @@ void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneMouseEvent } if (!lastWidgetUnderMouse) { - QApplicationPrivate::dispatchEnterLeave(embeddedMouseGrabber ? embeddedMouseGrabber : widget, 0); - lastWidgetUnderMouse = widget; + QApplicationPrivate::dispatchEnterLeave(embeddedMouseGrabber ? embeddedMouseGrabber : receiver, 0); + lastWidgetUnderMouse = receiver; } // Map event position from us to the receiver diff --git a/src/gui/itemviews/qabstractproxymodel.cpp b/src/gui/itemviews/qabstractproxymodel.cpp index 51dfa7a..12c4c7b 100644 --- a/src/gui/itemviews/qabstractproxymodel.cpp +++ b/src/gui/itemviews/qabstractproxymodel.cpp @@ -121,12 +121,15 @@ QAbstractProxyModel::~QAbstractProxyModel() void QAbstractProxyModel::setSourceModel(QAbstractItemModel *sourceModel) { Q_D(QAbstractProxyModel); - if (d->model) + if (d->model) { disconnect(d->model, SIGNAL(destroyed()), this, SLOT(_q_sourceModelDestroyed())); + disconnect(d->model, SIGNAL(modelReset()), this, SLOT(resetInternalData())); + } if (sourceModel) { d->model = sourceModel; connect(d->model, SIGNAL(destroyed()), this, SLOT(_q_sourceModelDestroyed())); + connect(d->model, SIGNAL(modelReset()), this, SLOT(resetInternalData())); } else { d->model = QAbstractItemModelPrivate::staticEmptyModel(); } @@ -380,6 +383,25 @@ Qt::DropActions QAbstractProxyModel::supportedDropActions() const return d->model->supportedDropActions(); } +/* + \since 4.8 + + This slot is called just after the internal data of a model is cleared + while it is being reset. + + This slot is provided the convenience of subclasses of concrete proxy + models, such as subclasses of QSortFilterProxyModel which maintain extra + data. + + \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 10 + + \sa modelAboutToBeReset(), modelReset() +*/ +void QAbstractProxyModel::resetInternalData() +{ + +} + QT_END_NAMESPACE #include "moc_qabstractproxymodel.cpp" diff --git a/src/gui/itemviews/qabstractproxymodel.h b/src/gui/itemviews/qabstractproxymodel.h index a5a1168..0daa7f8 100644 --- a/src/gui/itemviews/qabstractproxymodel.h +++ b/src/gui/itemviews/qabstractproxymodel.h @@ -95,6 +95,9 @@ public: QStringList mimeTypes() const; Qt::DropActions supportedDropActions() const; +protected Q_SLOTS: + void resetInternalData(); + protected: QAbstractProxyModel(QAbstractProxyModelPrivate &, QObject *parent); diff --git a/src/gui/itemviews/qstringlistmodel.cpp b/src/gui/itemviews/qstringlistmodel.cpp index 8d69ee4..60ff952 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/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index a75fc38..a773e7a 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -5322,12 +5322,12 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP if (rgn.isEmpty()) return; -#ifdef Q_WS_MAC +#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA) // We disable the rendering of QToolBar in the backingStore if // it's supposed to be in the unified toolbar on Mac OS X. if (backingStore && isInUnifiedToolbar) return; -#endif // Q_WS_MAC +#endif // Q_WS_MAC && QT_MAC_USE_COCOA Q_Q(QWidget); diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp index 722355e..ab05dbd 100644 --- a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp +++ b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp @@ -45,6 +45,8 @@ #include <QDebug> +#ifdef QT_MAC_USE_COCOA + QT_BEGIN_NAMESPACE QUnifiedToolbarSurface::QUnifiedToolbarSurface(QWidget *widget) @@ -231,3 +233,5 @@ void QUnifiedToolbarSurface::prepareBuffer(QImage::Format format, QWidget *widge } QT_END_NAMESPACE + +#endif // QT_MAC_USE_COCOA diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h index d7805e8..4d72ff9 100644 --- a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h +++ b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h @@ -58,6 +58,8 @@ #include <private/qwidget_p.h> #include <private/qnativeimage_p.h> +#ifdef QT_MAC_USE_COCOA + QT_BEGIN_NAMESPACE class QNativeImage; @@ -92,4 +94,6 @@ private: QT_END_NAMESPACE +#endif // QT_MAC_USE_COCOA + #endif // QUNIFIEDTOOLBARSURFACE_MAC_P_H diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp index 99f8597..217723f 100644 --- a/src/gui/painting/qwindowsurface_raster.cpp +++ b/src/gui/painting/qwindowsurface_raster.cpp @@ -251,6 +251,7 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi #ifdef Q_WS_MAC +#ifdef QT_MAC_USE_COCOA // Unified toolbar hack. QMainWindow* mWindow = qobject_cast<QMainWindow*>(widget->window()); if (mWindow) { @@ -267,6 +268,7 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi } } } +#endif // QT_MAC_USE_COCOA Q_UNUSED(offset); // Get a context for the widget. @@ -338,7 +340,8 @@ void QRasterWindowSurface::setGeometry(const QRect &rect) prepareBuffer(QNativeImage::systemFormat(), window()); } d->inSetGeometry = false; -#ifdef Q_WS_MAC + +#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA) QMainWindow* mWindow = qobject_cast<QMainWindow*>(window()); if (mWindow) { QMainWindowLayout *mLayout = qobject_cast<QMainWindowLayout*>(mWindow->layout()); @@ -354,7 +357,8 @@ void QRasterWindowSurface::setGeometry(const QRect &rect) } } } -#endif // Q_WS_MAC +#endif // Q_WS_MAC && QT_MAC_USE_COCOA + } // from qwindowsurface.cpp diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 2b26638..9ed09c2 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -2423,10 +2423,12 @@ QString QFontDatabase::writingSystemSample(WritingSystem writingSystem) sample += QChar(0x4f8b); break; case Japanese: - sample += QChar(0x3050); - sample += QChar(0x3060); - sample += QChar(0x30b0); - sample += QChar(0x30c0); + sample += QChar(0x30b5); + sample += QChar(0x30f3); + sample += QChar(0x30d7); + sample += QChar(0x30eb); + sample += QChar(0x3067); + sample += QChar(0x3059); break; case Korean: sample += QChar(0xac00); diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 861cfaa..d4118bd 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -1524,10 +1524,12 @@ void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set) d->useHIToolBar = set; createWinId(); // We need the hiview for down below. +#ifdef QT_MAC_USE_COCOA // Activate the unified toolbar with the raster engine. if (windowSurface()) { d->layout->unifiedSurface = new QUnifiedToolbarSurface(this); } +#endif // QT_MAC_USE_COCOA d->layout->updateHIToolBarStatus(); // Enabling the unified toolbar clears the opaque size grip setting, update it. diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index 21f6067..126cc4a 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -452,7 +452,9 @@ void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar for (int i = 0; i < beforeIndex; ++i) { offset.setX(offset.x() + qtoolbarsInUnifiedToolbarList.at(i)->size().width()); } +#ifdef QT_MAC_USE_COCOA unifiedSurface->insertToolbar(toolbar, offset); +#endif // QT_MAC_USE_COCOA } #ifndef QT_MAC_USE_COCOA diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index 3eb2545..e882d11 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -342,7 +342,10 @@ public: void syncUnifiedToolbarVisibility(); bool blockVisiblityCheck; +#ifdef QT_MAC_USE_COCOA QUnifiedToolbarSurface *unifiedSurface; +#endif // QT_MAC_USE_COCOA + #endif // Q_WS_MAC }; QT_END_NAMESPACE diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 411c790..ad7ccf7 100644 --- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -183,6 +183,7 @@ private slots: void inputMethod(); void clickFocus(); void windowFrameMargins(); + void QTBUG_6986_sendMouseEventToAlienWidget(); }; // Subclass that exposes the protected functions. @@ -3583,6 +3584,70 @@ void tst_QGraphicsProxyWidget::windowFrameMargins() QVERIFY(top > 0); } +class HoverButton : public QPushButton +{ +public: + HoverButton(QWidget *parent = 0) : QPushButton(parent), hoverLeaveReceived(false) + {} + + bool hoverLeaveReceived; + + bool event(QEvent* e) + { + if(QEvent::HoverLeave == e->type()) + hoverLeaveReceived = true; + return QPushButton::event(e); + } +}; + +class Scene : public QGraphicsScene +{ +Q_OBJECT +public: + Scene() { + QWidget *background = new QWidget; + background->setGeometry(0, 0, 500, 500); + hoverButton = new HoverButton; + hoverButton->setParent(background); + hoverButton->setText("Second button"); + hoverButton->setGeometry(10, 10, 200, 50); + addWidget(background); + + QPushButton *hideButton = new QPushButton("I'm a button with a very very long text"); + hideButton->setGeometry(10, 10, 400, 50); + topButton = addWidget(hideButton); + connect(hideButton, SIGNAL(clicked()), this, SLOT(hideButton())); + topButton->setFocus(); + } + + QGraphicsProxyWidget *topButton; + HoverButton *hoverButton; + +public slots: + void hideButton() { + QCursor::setPos(600,600); + topButton->hide(); + } +}; + +void tst_QGraphicsProxyWidget::QTBUG_6986_sendMouseEventToAlienWidget() +{ +#if defined(Q_OS_MAC) || defined(Q_OS_WIN) || defined(QT_NO_CURSOR) + QSKIP("Test case unstable on this platform", SkipAll); +#endif + QGraphicsView view; + Scene scene; + view.setScene(&scene); + view.resize(600, 600); + QApplication::setActiveWindow(&view); + view.show(); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(QApplication::activeWindow(), &view); + QCursor::setPos(view.mapToGlobal(view.mapFromScene(scene.topButton->boundingRect().center()))); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(scene.topButton->scenePos())); + QTRY_COMPARE(scene.hoverButton->hoverLeaveReceived, true); +} + QTEST_MAIN(tst_QGraphicsProxyWidget) #include "tst_qgraphicsproxywidget.moc" diff --git a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 2b62ccc..bc6ba77 100644 --- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -144,6 +144,7 @@ private slots: void testMultipleProxiesWithSelection(); void mapSelectionFromSource(); + void testResetInternalData(); protected: void buildHierarchy(const QStringList &data, QAbstractItemModel *model); @@ -3176,5 +3177,142 @@ void tst_QSortFilterProxyModel::taskQTBUG_10287_unnecessaryMapCreation() // No assert failure, it passes. } +/** + * A proxy which changes the background color for items ending in 'y' or 'r' + */ +class CustomDataProxy : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + CustomDataProxy(QObject *parent = 0) + : QSortFilterProxyModel(parent) + { + setDynamicSortFilter(true); + } + + void setSourceModel(QAbstractItemModel *sourceModel) + { + // It would be possible to use only the modelReset signal of the source model to clear + // the data in *this, however, this requires that the slot is connected + // before QSortFilterProxyModel::setSourceModel is called, and even then depends + // on the order of invokation of slots being the same as the order of connection. + // ie, not reliable. +// connect(sourceModel, SIGNAL(modelReset()), SLOT(resetInternalData())); + QSortFilterProxyModel::setSourceModel(sourceModel); + // Making the connect after the setSourceModel call clears the data too late. +// connect(sourceModel, SIGNAL(modelReset()), SLOT(resetInternalData())); + + // This could be done in data(), but the point is to need to cache something in the proxy + // which needs to be cleared on reset. + for (int i = 0; i < sourceModel->rowCount(); ++i) + { + if (sourceModel->index(i, 0).data().toString().endsWith(QLatin1Char('y'))) + { + m_backgroundColours.insert(i, Qt::blue); + } else if (sourceModel->index(i, 0).data().toString().endsWith(QLatin1Char('r'))) + { + m_backgroundColours.insert(i, Qt::red); + } + } + } + + QVariant data(const QModelIndex &index, int role) const + { + if (role != Qt::BackgroundRole) + return QSortFilterProxyModel::data(index, role); + return m_backgroundColours.value(index.row()); + } + +private slots: + void resetInternalData() + { + m_backgroundColours.clear(); + } + +private: + QHash<int, QColor> m_backgroundColours; +}; + +class ModelObserver : public QObject +{ + Q_OBJECT +public: + ModelObserver(QAbstractItemModel *model, QObject *parent = 0) + : QObject(parent), m_model(model) + { + connect(m_model, SIGNAL(modelAboutToBeReset()), SLOT(modelAboutToBeReset())); + connect(m_model, SIGNAL(modelReset()), SLOT(modelReset())); + } + +public slots: + void modelAboutToBeReset() + { + int reds = 0, blues = 0; + for (int i = 0; i < m_model->rowCount(); ++i) + { + QColor color = m_model->index(i, 0).data(Qt::BackgroundRole).value<QColor>(); + if (color == Qt::blue) + ++blues; + if (color == Qt::red) + ++reds; + } + QCOMPARE(blues, 11); + QCOMPARE(reds, 4); + } + + void modelReset() + { + int reds = 0, blues = 0; + for (int i = 0; i < m_model->rowCount(); ++i) + { + QColor color = m_model->index(i, 0).data(Qt::BackgroundRole).value<QColor>(); + if (color == Qt::blue) + ++blues; + if (color == Qt::red) + ++reds; + } + QCOMPARE(reds, 0); + QCOMPARE(blues, 0); + } + +private: + QAbstractItemModel * const m_model; + +}; + +void tst_QSortFilterProxyModel::testResetInternalData() +{ + + QStringListModel model(QStringList() << "Monday" + << "Tuesday" + << "Wednesday" + << "Thursday" + << "Friday" + << "January" + << "February" + << "March" + << "April" + << "May" + << "Saturday" + << "June" + << "Sunday" + << "July" + << "August" + << "September" + << "October" + << "November" + << "December"); + + CustomDataProxy proxy; + proxy.setSourceModel(&model); + + ModelObserver observer(&proxy); + + // Cause the source model to reset. + model.setStringList(QStringList() << "Spam" << "Eggs"); + +} + QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" |