summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure2
-rw-r--r--doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp35
-rw-r--r--src/gui/graphicsview/qgraphicsproxywidget.cpp4
-rw-r--r--src/gui/itemviews/qabstractproxymodel.cpp24
-rw-r--r--src/gui/itemviews/qabstractproxymodel.h3
-rw-r--r--src/gui/itemviews/qstringlistmodel.cpp3
-rw-r--r--src/gui/kernel/qwidget.cpp4
-rw-r--r--src/gui/painting/qunifiedtoolbarsurface_mac.cpp4
-rw-r--r--src/gui/painting/qunifiedtoolbarsurface_mac_p.h4
-rw-r--r--src/gui/painting/qwindowsurface_raster.cpp8
-rw-r--r--src/gui/text/qfontdatabase.cpp10
-rw-r--r--src/gui/widgets/qmainwindow.cpp2
-rw-r--r--src/gui/widgets/qmainwindowlayout_mac.mm2
-rw-r--r--src/gui/widgets/qmainwindowlayout_p.h3
-rw-r--r--tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp65
-rw-r--r--tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp138
16 files changed, 298 insertions, 13 deletions
diff --git a/configure b/configure
index 5539851..bc53bae 100755
--- a/configure
+++ b/configure
@@ -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"