diff options
63 files changed, 1051 insertions, 335 deletions
diff --git a/src/3rdparty/phonon/ds9/iodevicereader.cpp b/src/3rdparty/phonon/ds9/iodevicereader.cpp index e0c505c..695af59 100644 --- a/src/3rdparty/phonon/ds9/iodevicereader.cpp +++ b/src/3rdparty/phonon/ds9/iodevicereader.cpp @@ -36,17 +36,20 @@ namespace Phonon //these mediatypes define a stream, its type will be autodetected by DirectShow static QVector<AM_MEDIA_TYPE> getMediaTypes() { - AM_MEDIA_TYPE mt = { MEDIATYPE_Stream, MEDIASUBTYPE_NULL, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0}; + //the order here is important because otherwise, + //directshow might not be able to detect the stream type correctly + + AM_MEDIA_TYPE mt = { MEDIATYPE_Stream, MEDIASUBTYPE_Avi, TRUE, FALSE, 1, GUID_NULL, 0, 0, 0}; QVector<AM_MEDIA_TYPE> ret; - //normal auto-detect stream - ret << mt; //AVI stream - mt.subtype = MEDIASUBTYPE_Avi; ret << mt; //WAVE stream mt.subtype = MEDIASUBTYPE_WAVE; ret << mt; + //normal auto-detect stream (must be at the end!) + mt.subtype = MEDIASUBTYPE_NULL; + ret << mt; return ret; } diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index f83c2a1..b8b9214 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -194,15 +194,10 @@ QUnifiedTimer *QUnifiedTimer::instance() return inst; } -void QUnifiedTimer::ensureTimerUpdate(QAbstractAnimation *animation) +void QUnifiedTimer::ensureTimerUpdate() { - if (isPauseTimerActive) { + if (isPauseTimerActive) updateAnimationsTime(); - } else { - // this code is needed when ensureTimerUpdate is called from setState because we update - // the currentTime when an animation starts running (otherwise we could remove it) - animation->setCurrentTime(animation->currentTime()); - } } void QUnifiedTimer::updateAnimationsTime() @@ -381,7 +376,7 @@ void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) case QAbstractAnimation::Paused: if (hasRegisteredTimer) // currentTime needs to be updated if pauseTimer is active - QUnifiedTimer::instance()->ensureTimerUpdate(q); + QUnifiedTimer::instance()->ensureTimerUpdate(); if (!guard) return; //here we're sure that we were in running state before and that the @@ -395,9 +390,11 @@ void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState) // this ensures that the value is updated now that the animation is running if (oldState == QAbstractAnimation::Stopped) { - if (isTopLevel) + if (isTopLevel) { // currentTime needs to be updated if pauseTimer is active - QUnifiedTimer::instance()->ensureTimerUpdate(q); + QUnifiedTimer::instance()->ensureTimerUpdate(); + q->setCurrentTime(totalCurrentTime); + } } } break; @@ -558,7 +555,7 @@ void QAbstractAnimation::setDirection(Direction direction) // the commands order below is important: first we need to setCurrentTime with the old direction, // then update the direction on this and all children and finally restart the pauseTimer if needed if (d->hasRegisteredTimer) - QUnifiedTimer::instance()->ensureTimerUpdate(this); + QUnifiedTimer::instance()->ensureTimerUpdate(); d->direction = direction; updateDirection(direction); diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index bef0499..f989bce 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -142,7 +142,7 @@ public: this is used for updating the currentTime of all animations in case the pause timer is active or, otherwise, only of the animation passed as parameter. */ - void ensureTimerUpdate(QAbstractAnimation *animation); + void ensureTimerUpdate(); /* this will evaluate the need of restarting the pause timer in case there is still diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index e8d6df0..438678a 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2509,7 +2509,7 @@ \value DisplayRole The key data to be rendered in the form of text. (QString) \value DecorationRole The data to be rendered as a decoration in the form - of an icon. (QColor) + of an icon. (QColor, QIcon or QPixmap) \value EditRole The data in a form suitable for editing in an editor. (QString) \value ToolTipRole The data displayed in the item's tooltip. (QString) diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index eb4fb56..4cce529 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -460,6 +460,7 @@ inline void qVariantSetValue(QVariant &v, const T &t) QVariant::Private &d = v.data_ptr(); if (v.isDetached() && (type <= int(QVariant::Char) || type == d.type)) { d.type = type; + d.is_null = false; T *old = reinterpret_cast<T*>(d.is_shared ? d.data.shared->ptr : &d.data.ptr); if (QTypeInfo<T>::isComplex) old->~T(); diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index e21cd99..22a7cf9 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -420,7 +420,7 @@ void QGraphicsAnchorLayout::setSpacing(qreal spacing) qreal QGraphicsAnchorLayout::horizontalSpacing() const { Q_D(const QGraphicsAnchorLayout); - return d->effectiveSpacing(QGraphicsAnchorLayoutPrivate::Horizontal); + return d->styleInfo().defaultSpacing(Qt::Horizontal); } /*! @@ -431,7 +431,7 @@ qreal QGraphicsAnchorLayout::horizontalSpacing() const qreal QGraphicsAnchorLayout::verticalSpacing() const { Q_D(const QGraphicsAnchorLayout); - return d->effectiveSpacing(QGraphicsAnchorLayoutPrivate::Vertical); + return d->styleInfo().defaultSpacing(Qt::Vertical); } /*! @@ -501,7 +501,8 @@ void QGraphicsAnchorLayout::invalidate() { Q_D(QGraphicsAnchorLayout); QGraphicsLayout::invalidate(); - d->calculateGraphCacheDirty = 1; + d->calculateGraphCacheDirty = true; + d->styleInfoDirty = true; } /*! diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index b4666c6..1d6e29d 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include <QtGui/qwidget.h> +#include <QtGui/qapplication.h> #include <QtCore/qlinkedlist.h> #include <QtCore/qstack.h> @@ -141,7 +142,7 @@ static void internalSizeHints(QSizePolicy::Policy policy, *expSize = *prefSize; } -bool AnchorData::refreshSizeHints(qreal effectiveSpacing) +bool AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo) { QSizePolicy::Policy policy; qreal minSizeHint; @@ -187,7 +188,20 @@ bool AnchorData::refreshSizeHints(qreal effectiveSpacing) // their effective size hints might be narrowed down due to their size policies. prefSizeHint = prefSize; } else { - prefSizeHint = effectiveSpacing; + const Qt::Orientation orient = Qt::Orientation(QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge) + 1); + qreal s = styleInfo->defaultSpacing(orient); + if (s < 0) { + QSizePolicy::ControlType controlTypeFrom = from->m_item->sizePolicy().controlType(); + QSizePolicy::ControlType controlTypeTo = to->m_item->sizePolicy().controlType(); + s = styleInfo->perItemSpacing(controlTypeFrom, controlTypeTo, orient); + + // ### Currently we do not support negative anchors inside the graph. + // To avoid those being created by a negative style spacing, we must + // make this test. + if (s < 0) + s = 0; + } + prefSizeHint = s; } maxSizeHint = QWIDGETSIZE_MAX; } @@ -220,16 +234,16 @@ void ParallelAnchorData::updateChildrenSizes() secondEdge->updateChildrenSizes(); } -bool ParallelAnchorData::refreshSizeHints(qreal effectiveSpacing) +bool ParallelAnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo) { - return refreshSizeHints_helper(effectiveSpacing); + return refreshSizeHints_helper(styleInfo); } -bool ParallelAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, +bool ParallelAnchorData::refreshSizeHints_helper(const QLayoutStyleInfo *styleInfo, bool refreshChildren) { - if (refreshChildren && (!firstEdge->refreshSizeHints(effectiveSpacing) - || !secondEdge->refreshSizeHints(effectiveSpacing))) { + if (refreshChildren && (!firstEdge->refreshSizeHints(styleInfo) + || !secondEdge->refreshSizeHints(styleInfo))) { return false; } @@ -360,12 +374,12 @@ void SequentialAnchorData::updateChildrenSizes() } } -bool SequentialAnchorData::refreshSizeHints(qreal effectiveSpacing) +bool SequentialAnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo) { - return refreshSizeHints_helper(effectiveSpacing); + return refreshSizeHints_helper(styleInfo); } -bool SequentialAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, +bool SequentialAnchorData::refreshSizeHints_helper(const QLayoutStyleInfo *styleInfo, bool refreshChildren) { minSize = 0; @@ -377,7 +391,7 @@ bool SequentialAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, AnchorData *edge = m_edges.at(i); // If it's the case refresh children information first - if (refreshChildren && !edge->refreshSizeHints(effectiveSpacing)) + if (refreshChildren && !edge->refreshSizeHints(styleInfo)) return false; minSize += edge->minSize; @@ -458,7 +472,7 @@ QString GraphPath::toString() const #endif QGraphicsAnchorLayoutPrivate::QGraphicsAnchorLayoutPrivate() - : calculateGraphCacheDirty(1) + : calculateGraphCacheDirty(true), styleInfoDirty(true) { for (int i = 0; i < NOrientations; ++i) { for (int j = 0; j < 3; ++j) { @@ -1614,34 +1628,32 @@ void QGraphicsAnchorLayoutPrivate::correctEdgeDirection(QGraphicsLayoutItem *&fi } } -qreal QGraphicsAnchorLayoutPrivate::effectiveSpacing(Orientation orientation) const +QLayoutStyleInfo &QGraphicsAnchorLayoutPrivate::styleInfo() const { - Q_Q(const QGraphicsAnchorLayout); - qreal s = spacings[orientation]; - if (s < 0) { - // ### make sure behaviour is the same as in QGraphicsGridLayout + if (styleInfoDirty) { + Q_Q(const QGraphicsAnchorLayout); + //### Fix this if QGV ever gets support for Metal style or different Aqua sizes. + QWidget *wid = 0; + QGraphicsLayoutItem *parent = q->parentLayoutItem(); while (parent && parent->isLayout()) { parent = parent->parentLayoutItem(); } + QGraphicsWidget *w = 0; if (parent) { QGraphicsItem *parentItem = parent->graphicsItem(); - if (parentItem && parentItem->isWidget()) { - QGraphicsWidget *w = static_cast<QGraphicsWidget*>(parentItem); - s = w->style()->pixelMetric(orientation == Horizontal - ? QStyle::PM_LayoutHorizontalSpacing - : QStyle::PM_LayoutVerticalSpacing); - } + if (parentItem && parentItem->isWidget()) + w = static_cast<QGraphicsWidget*>(parentItem); } - } - // ### Currently we do not support negative anchors inside the graph. - // To avoid those being created by a negative style spacing, we must - // make this test. - if (s < 0) - s = 0; + QStyle *style = w ? w->style() : QApplication::style(); + cachedStyleInfo = QLayoutStyleInfo(style, wid); + cachedStyleInfo.setDefaultSpacing(Qt::Horizontal, spacings[0]); + cachedStyleInfo.setDefaultSpacing(Qt::Vertical, spacings[1]); - return s; + styleInfoDirty = false; + } + return cachedStyleInfo; } /*! @@ -1669,7 +1681,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs() dumpGraph(QString::fromAscii("%1-after").arg(count)); #endif - calculateGraphCacheDirty = 0; + calculateGraphCacheDirty = false; } // ### Maybe getGraphParts could return the variables when traversing, at least @@ -1914,14 +1926,13 @@ bool QGraphicsAnchorLayoutPrivate::refreshAllSizeHints(Orientation orientation) Graph<AnchorVertex, AnchorData> &g = graph[orientation]; QList<QPair<AnchorVertex *, AnchorVertex *> > vertices = g.connections(); - qreal spacing = effectiveSpacing(orientation); - + QLayoutStyleInfo styleInf = styleInfo(); for (int i = 0; i < vertices.count(); ++i) { AnchorData *data = g.edgeData(vertices.at(i).first, vertices.at(i).second);; Q_ASSERT(data->from && data->to); // During the traversal we check the feasibility of the complex anchors. - if (!data->refreshSizeHints(spacing)) + if (!data->refreshSizeHints(&styleInf)) return false; } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 8eb65c5..99a866b 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -160,7 +160,7 @@ struct AnchorData : public QSimplexVariable { isCenterAnchor(false), orientation(0) {} virtual void updateChildrenSizes() {} - virtual bool refreshSizeHints(qreal effectiveSpacing); + virtual bool refreshSizeHints(const QLayoutStyleInfo *styleInfo); virtual ~AnchorData() {} @@ -232,9 +232,9 @@ struct SequentialAnchorData : public AnchorData } virtual void updateChildrenSizes(); - virtual bool refreshSizeHints(qreal effectiveSpacing); + virtual bool refreshSizeHints(const QLayoutStyleInfo *styleInfo); - bool refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true); + bool refreshSizeHints_helper(const QLayoutStyleInfo *styleInfo, bool refreshChildren = true); void setVertices(const QVector<AnchorVertex*> &vertices) { @@ -267,9 +267,9 @@ struct ParallelAnchorData : public AnchorData } virtual void updateChildrenSizes(); - virtual bool refreshSizeHints(qreal effectiveSpacing); + virtual bool refreshSizeHints(const QLayoutStyleInfo *styleInfo); - bool refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true); + bool refreshSizeHints_helper(const QLayoutStyleInfo *styleInfo, bool refreshChildren = true); AnchorData* firstEdge; AnchorData* secondEdge; @@ -429,9 +429,8 @@ public: Qt::AnchorPoint &firstEdge, QGraphicsLayoutItem *&secondItem, Qt::AnchorPoint &secondEdge); - // for getting the actual spacing (will query the style if the - // spacing is not explicitly set). - qreal effectiveSpacing(Orientation orientation) const; + + QLayoutStyleInfo &styleInfo() const; // Activation methods bool simplifyGraph(Orientation orientation); @@ -530,6 +529,8 @@ public: #endif uint calculateGraphCacheDirty : 1; + mutable uint styleInfoDirty : 1; + mutable QLayoutStyleInfo cachedStyleInfo; friend class QGraphicsAnchorPrivate; }; diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index f892bb4..c38365b 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -4263,7 +4263,7 @@ void QGraphicsItem::stackBefore(const QGraphicsItem *sibling) // Only move items with the same Z value, and that need moving. int siblingIndex = sibling->d_ptr->siblingIndex; int myIndex = d_ptr->siblingIndex; - if (myIndex >= siblingIndex && d_ptr->z == sibling->d_ptr->z) { + if (myIndex >= siblingIndex) { siblings->move(myIndex, siblingIndex); // Fixup the insertion ordering. for (int i = 0; i < siblings->size(); ++i) { diff --git a/src/gui/graphicsview/qgraphicslayout_p.h b/src/gui/graphicsview/qgraphicslayout_p.h index 59c6dba..4aeae39 100644 --- a/src/gui/graphicsview/qgraphicslayout_p.h +++ b/src/gui/graphicsview/qgraphicslayout_p.h @@ -60,6 +60,8 @@ #include "qgraphicslayout.h" #include "qgraphicslayoutitem_p.h" #include <QtGui/qstyle.h> +#include <QtGui/qwidget.h> +#include <QtGui/qstyleoption.h> QT_BEGIN_NAMESPACE @@ -76,6 +78,55 @@ inline bool qt_graphicsLayoutDebug() } #endif + +class QLayoutStyleInfo +{ +public: + inline QLayoutStyleInfo() { invalidate(); } + inline QLayoutStyleInfo(QStyle *style, QWidget *widget) + : m_valid(true), m_style(style), m_widget(widget) + { + Q_ASSERT(style); + if (widget) //### + m_styleOption.initFrom(widget); + m_defaultSpacing[0] = style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing); + m_defaultSpacing[1] = style->pixelMetric(QStyle::PM_LayoutVerticalSpacing); + } + + inline void invalidate() { m_valid = false; m_style = 0; m_widget = 0; } + + inline QStyle *style() const { return m_style; } + inline QWidget *widget() const { return m_widget; } + + inline bool operator==(const QLayoutStyleInfo &other) + { return m_style == other.m_style && m_widget == other.m_widget; } + inline bool operator!=(const QLayoutStyleInfo &other) + { return !(*this == other); } + + inline void setDefaultSpacing(Qt::Orientation o, qreal spacing){ + if (spacing >= 0) + m_defaultSpacing[o - 1] = spacing; + } + + inline qreal defaultSpacing(Qt::Orientation o) const { + return m_defaultSpacing[o - 1]; + } + + inline qreal perItemSpacing(QSizePolicy::ControlType control1, + QSizePolicy::ControlType control2, + Qt::Orientation orientation) const + { + Q_ASSERT(style()); + return style()->layoutSpacing(control1, control2, orientation, &m_styleOption, widget()); + } +private: + bool m_valid; + QStyle *m_style; + QWidget *m_widget; + QStyleOption m_styleOption; + qreal m_defaultSpacing[2]; +}; + class Q_AUTOTEST_EXPORT QGraphicsLayoutPrivate : public QGraphicsLayoutItemPrivate { Q_DECLARE_PUBLIC(QGraphicsLayout) diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index 64c51ad..e9173a9 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -397,7 +397,7 @@ QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next) do { if (child->isEnabled() && child->isVisibleTo(widget) - && (child->focusPolicy() & focus_flag == focus_flag) + && ((child->focusPolicy() & focus_flag) == focus_flag) && !(child->d_func()->extra && child->d_func()->extra->focus_proxy)) { return child; } diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index c459d21..a62e486 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -525,6 +525,14 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) item->d_func()->scene = 0; + //We need to remove all children first because they might use their parent + //attributes (e.g. sceneTransform). + if (!item->d_ptr->inDestructor) { + // Remove all children recursively + for (int i = 0; i < item->d_ptr->children.size(); ++i) + q->removeItem(item->d_ptr->children.at(i)); + } + // Unregister focus proxy. item->d_ptr->resetFocusProxy(); @@ -571,12 +579,6 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) ++iterator; } - if (!item->d_ptr->inDestructor) { - // Remove all children recursively - for (int i = 0; i < item->d_ptr->children.size(); ++i) - q->removeItem(item->d_ptr->children.at(i)); - } - if (item->isPanel() && item->isVisible() && item->panelModality() != QGraphicsItem::NonModal) leaveModal(item); @@ -4910,7 +4912,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool continue; } - if (item->d_ptr->paintedViewBoundingRectsNeedRepaint && !paintedViewBoundingRect.isEmpty()) { + if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) { paintedViewBoundingRect.translate(viewPrivate->dirtyScrollOffset); if (!viewPrivate->updateRect(paintedViewBoundingRect)) paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport. diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 710c745..f72aa8a 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -3319,6 +3319,14 @@ void QGraphicsView::paintEvent(QPaintEvent *event) if (!(d->optimizationFlags & IndirectPainting)) { d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0, &d->exposedRegion, viewport()); + // Make sure the painter's world transform is restored correctly when + // drawing without painter state protection (DontSavePainterState). + // We only change the worldTransform() so there's no need to do a full-blown + // save() and restore(). Also note that we don't have to do this in case of + // IndirectPainting (the else branch), because in that case we always save() + // and restore() in QGraphicsScene::drawItems(). + if (!d->scene->d_func()->painterStateProtection) + painter.setWorldTransform(viewTransform); } else { // Find all exposed items bool allItems = false; diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 35a3c13..d70a281 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -1352,6 +1352,8 @@ void QGraphicsWidget::changeEvent(QEvent *event) case QEvent::StyleChange: // ### Don't unset if the margins are explicitly set. unsetWindowFrameMargins(); + if (d->layout) + d->layout->invalidate(); case QEvent::FontChange: update(); updateGeometry(); diff --git a/src/gui/graphicsview/qgridlayoutengine_p.h b/src/gui/graphicsview/qgridlayoutengine_p.h index a42a537..ed335a8 100644 --- a/src/gui/graphicsview/qgridlayoutengine_p.h +++ b/src/gui/graphicsview/qgridlayoutengine_p.h @@ -59,7 +59,7 @@ #include "qmap.h" #include "qpair.h" #include "qvector.h" - +#include "qgraphicslayout_p.h" #include <float.h> QT_BEGIN_NAMESPACE @@ -128,29 +128,6 @@ public: }; -class QLayoutStyleInfo -{ -public: - inline QLayoutStyleInfo() { invalidate(); } - inline QLayoutStyleInfo(QStyle *style, QWidget *widget) - : q_valid(true), q_style(style), q_widget(widget) {} - - inline void invalidate() { q_valid = false; q_style = 0; q_widget = 0; } - - inline QStyle *style() const { return q_style; } - inline QWidget *widget() const { return q_widget; } - - inline bool operator==(const QLayoutStyleInfo &other) - { return q_style == other.q_style && q_widget == other.q_widget; } - inline bool operator!=(const QLayoutStyleInfo &other) - { return !(*this == other); } - -private: - bool q_valid; - QStyle *q_style; - QWidget *q_widget; -}; - class QGridLayoutBox { public: diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h index b4f0957..f438148 100644 --- a/src/gui/itemviews/qabstractitemview.h +++ b/src/gui/itemviews/qabstractitemview.h @@ -361,6 +361,7 @@ private: friend class QTreeViewPrivate; // needed to compile with MSVC friend class QAccessibleItemRow; + friend class QListModeViewBase; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractItemView::EditTriggers) diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index fcf381a..66b7662 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -164,7 +164,8 @@ public: } #ifndef QT_NO_DRAGANDDROP - QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; + virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; + inline bool canDecode(QDropEvent *e) const { QStringList modelTypes = model->mimeTypes(); const QMimeData *mime = e->mimeData(); diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index 3bd9a19..6f2cff9 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -2516,6 +2516,8 @@ QSize QHeaderView::sectionSizeFromContents(int logicalIndex) const Q_D(const QHeaderView); Q_ASSERT(logicalIndex >= 0); + ensurePolished(); + // use SizeHintRole QVariant variant = d->model->headerData(logicalIndex, d->orientation, Qt::SizeHintRole); if (variant.isValid()) diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp index 871a4b1..3b3036d 100644 --- a/src/gui/itemviews/qitemdelegate.cpp +++ b/src/gui/itemviews/qitemdelegate.cpp @@ -255,7 +255,7 @@ QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const \row \o \l Qt::BackgroundRole \o QBrush \row \o \l Qt::BackgroundColorRole \o QColor (obsolete; use Qt::BackgroundRole instead) \row \o \l Qt::CheckStateRole \o Qt::CheckState - \row \o \l Qt::DecorationRole \o QIcon and QColor + \row \o \l Qt::DecorationRole \o QIcon, QPixmap and QColor \row \o \l Qt::DisplayRole \o QString and types with a string representation \row \o \l Qt::EditRole \o See QItemEditorFactory for details \row \o \l Qt::FontRole \o QFont diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp index dfebe03..f2ccb6e 100644 --- a/src/gui/itemviews/qitemselectionmodel.cpp +++ b/src/gui/itemviews/qitemselectionmodel.cpp @@ -599,7 +599,7 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &pare while (itParent.isValid() && itParent.parent() != parent) itParent = itParent.parent(); - if (parent.isValid() && start <= itParent.row() && itParent.row() <= end) { + if (itParent.isValid() && start <= itParent.row() && itParent.row() <= end) { deselected.append(*it); it = ranges.erase(it); } else { diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index f58f458..109d760 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -853,8 +853,13 @@ void QListView::resizeEvent(QResizeEvent *e) */ void QListView::dragMoveEvent(QDragMoveEvent *e) { - if (!d_func()->commonListView->filterDragMoveEvent(e)) - QAbstractItemView::dragMoveEvent(e); + Q_D(QListView); + if (!d->commonListView->filterDragMoveEvent(e)) { + if (viewMode() == QListView::ListMode && flow() == QListView::LeftToRight) + static_cast<QListModeViewBase *>(d->commonListView)->dragMoveEvent(e); + else + QAbstractItemView::dragMoveEvent(e); + } } @@ -1804,6 +1809,16 @@ QItemSelection QListViewPrivate::selection(const QRect &rect) const return selection; } +#ifndef QT_NO_DRAGANDDROP +QAbstractItemView::DropIndicatorPosition QListViewPrivate::position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const +{ + if (viewMode == QListView::ListMode && flow == QListView::LeftToRight) + return static_cast<QListModeViewBase *>(commonListView)->position(pos, rect, idx); + else + return QAbstractItemViewPrivate::position(pos, rect, idx); +} +#endif + /* * Common ListView Implementation */ @@ -1893,6 +1908,96 @@ void QListModeViewBase::paintDragDrop(QPainter *painter) // in IconMode, it makes no sense to show it dd->paintDropIndicator(painter); } + +QAbstractItemView::DropIndicatorPosition QListModeViewBase::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const +{ + QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport; + if (!dd->overwrite) { + const int margin = 2; + if (pos.x() - rect.left() < margin) { + r = QAbstractItemView::AboveItem; // Visually, on the left + } else if (rect.right() - pos.x() < margin) { + r = QAbstractItemView::BelowItem; // Visually, on the right + } else if (rect.contains(pos, true)) { + r = QAbstractItemView::OnItem; + } + } else { + QRect touchingRect = rect; + touchingRect.adjust(-1, -1, 1, 1); + if (touchingRect.contains(pos, false)) { + r = QAbstractItemView::OnItem; + } + } + + if (r == QAbstractItemView::OnItem && (!(dd->model->flags(index) & Qt::ItemIsDropEnabled))) + r = pos.x() < rect.center().x() ? QAbstractItemView::AboveItem : QAbstractItemView::BelowItem; + + return r; +} + +void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event) +{ + if (qq->dragDropMode() == QAbstractItemView::InternalMove + && (event->source() != qq || !(event->possibleActions() & Qt::MoveAction))) + return; + + // ignore by default + event->ignore(); + + QModelIndex index = qq->indexAt(event->pos()); + dd->hover = index; + if (!dd->droppingOnItself(event, index) + && dd->canDecode(event)) { + + if (index.isValid() && dd->showDropIndicator) { + QRect rect = qq->visualRect(index); + dd->dropIndicatorPosition = position(event->pos(), rect, index); + switch (dd->dropIndicatorPosition) { + case QAbstractItemView::AboveItem: + if (dd->isIndexDropEnabled(index.parent())) { + dd->dropIndicatorRect = QRect(rect.left(), rect.top(), 0, rect.height()); + event->accept(); + } else { + dd->dropIndicatorRect = QRect(); + } + break; + case QAbstractItemView::BelowItem: + if (dd->isIndexDropEnabled(index.parent())) { + dd->dropIndicatorRect = QRect(rect.right(), rect.top(), 0, rect.height()); + event->accept(); + } else { + dd->dropIndicatorRect = QRect(); + } + break; + case QAbstractItemView::OnItem: + if (dd->isIndexDropEnabled(index)) { + dd->dropIndicatorRect = rect; + event->accept(); + } else { + dd->dropIndicatorRect = QRect(); + } + break; + case QAbstractItemView::OnViewport: + dd->dropIndicatorRect = QRect(); + if (dd->isIndexDropEnabled(qq->rootIndex())) { + event->accept(); // allow dropping in empty areas + } + break; + } + } else { + dd->dropIndicatorRect = QRect(); + dd->dropIndicatorPosition = QAbstractItemView::OnViewport; + if (dd->isIndexDropEnabled(qq->rootIndex())) { + event->accept(); // allow dropping in empty areas + } + } + dd->viewport->update(); + } // can decode + + if (dd->shouldAutoScroll(event->pos())) + qq->startAutoScroll(); +} + #endif //QT_NO_DRAGANDDROP void QListModeViewBase::updateVerticalScrollBar(const QSize &step) diff --git a/src/gui/itemviews/qlistview_p.h b/src/gui/itemviews/qlistview_p.h index de4c7f3..3f8f9db 100644 --- a/src/gui/itemviews/qlistview_p.h +++ b/src/gui/itemviews/qlistview_p.h @@ -231,6 +231,11 @@ public: #ifndef QT_NO_DRAGANDDROP void paintDragDrop(QPainter *painter); + + // The next two methods are to be used on LefToRight flow only. + // 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); #endif private: @@ -356,6 +361,10 @@ public: QItemSelection selection(const QRect &rect) const; void selectAll(QItemSelectionModel::SelectionFlags command); +#ifndef QT_NO_DRAGANDDROP + virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; +#endif + inline void setGridSize(const QSize &size) { grid = size; } inline QSize gridSize() const { return grid; } inline void setWrapping(bool b) { wrap = b; } diff --git a/src/gui/itemviews/qlistwidget.cpp b/src/gui/itemviews/qlistwidget.cpp index a978d0f..5dd1d76 100644 --- a/src/gui/itemviews/qlistwidget.cpp +++ b/src/gui/itemviews/qlistwidget.cpp @@ -169,6 +169,20 @@ QListWidgetItem *QListModel::take(int row) return item; } +void QListModel::move(int srcRow, int dstRow) +{ + if (srcRow == dstRow + || srcRow < 0 || srcRow >= items.count() + || dstRow < 0 || dstRow >= items.count()) + return; + + beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow); + if (srcRow < dstRow) + --dstRow; + items.move(srcRow, dstRow); + endMoveRows(); +} + int QListModel::rowCount(const QModelIndex &parent) const { return parent.isValid() ? 0 : items.count(); @@ -1804,22 +1818,15 @@ void QListWidget::dropEvent(QDropEvent *event) { if (persIndexes.contains(topIndex)) return; + qSort(persIndexes); // The dropped items will remain in the same visual order. QPersistentModelIndex dropRow = model()->index(row, col, topIndex); - QList<QListWidgetItem *> taken; - for (int i = 0; i < persIndexes.count(); ++i) - taken.append(takeItem(persIndexes.at(i).row())); - - // insert them back in at their new positions + int r = row == -1 ? count() : (dropRow.row() >= 0 ? dropRow.row() : row); for (int i = 0; i < persIndexes.count(); ++i) { - // Either at a specific point or appended - if (row == -1) { - insertItem(count(), taken.takeFirst()); - } else { - int r = dropRow.row() >= 0 ? dropRow.row() : row; - insertItem(qMin(r, count()), taken.takeFirst()); - } + const QPersistentModelIndex &pIndex = persIndexes.at(i); + d->listModel()->move(pIndex.row(), r); + r = pIndex.row() + 1; // Dropped items are inserted contiguously and in the right order. } event->accept(); diff --git a/src/gui/itemviews/qlistwidget_p.h b/src/gui/itemviews/qlistwidget_p.h index 69cfa26..b5f28e3 100644 --- a/src/gui/itemviews/qlistwidget_p.h +++ b/src/gui/itemviews/qlistwidget_p.h @@ -77,7 +77,7 @@ public: { return *i2 < *i1; } }; -class QListModel : public QAbstractListModel +class Q_AUTOTEST_EXPORT QListModel : public QAbstractListModel { Q_OBJECT public: @@ -90,6 +90,7 @@ public: void insert(int row, const QStringList &items); void remove(QListWidgetItem *item); QListWidgetItem *take(int row); + void move(int srcRow, int dstRow); int rowCount(const QModelIndex &parent = QModelIndex()) const; diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp index 1c36787..1ca0391 100644 --- a/src/gui/itemviews/qstyleditemdelegate.cpp +++ b/src/gui/itemviews/qstyleditemdelegate.cpp @@ -148,7 +148,7 @@ public: \row \o \l Qt::BackgroundRole \o QBrush \row \o \l Qt::BackgroundColorRole \o QColor (obsolete; use Qt::BackgroundRole instead) \row \o \l Qt::CheckStateRole \o Qt::CheckState - \row \o \l Qt::DecorationRole \o QIcon and QColor + \row \o \l Qt::DecorationRole \o QIcon, QPixmap, QImage and QColor \row \o \l Qt::DisplayRole \o QString and types with a string representation \row \o \l Qt::EditRole \o See QItemEditorFactory for details \row \o \l Qt::FontRole \o QFont diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index 2a937f1..c80faa2 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -2065,6 +2065,8 @@ int QTableView::sizeHintForRow(int row) const if (!model()) return -1; + ensurePolished(); + int left = qMax(0, columnAt(0)); int right = columnAt(d->viewport->width()); if (right == -1) // the table don't have enough columns to fill the viewport @@ -2122,6 +2124,8 @@ int QTableView::sizeHintForColumn(int column) const if (!model()) return -1; + ensurePolished(); + int top = qMax(0, rowAt(0)); int bottom = rowAt(d->viewport->height()); if (!isVisible() || bottom == -1) // the table don't have enough rows to fill the viewport diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index f37d8c7..16b454d 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -1422,8 +1422,9 @@ void QTreeView::drawTree(QPainter *painter, const QRegion ®ion) const for (; i < viewItems.count() && y <= area.bottom(); ++i) { const int itemHeight = d->itemHeight(i); option.rect.setRect(0, y, viewportWidth, itemHeight); - option.state = state | (viewItems.at(i).expanded - ? QStyle::State_Open : QStyle::State_None); + option.state = state | (viewItems.at(i).expanded ? QStyle::State_Open : QStyle::State_None) + | (viewItems.at(i).hasChildren ? QStyle::State_Children : QStyle::State_None) + | (viewItems.at(i).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None); d->current = i; d->spanning = viewItems.at(i).spanning; if (!multipleRects || !drawn.contains(i)) { @@ -1748,14 +1749,8 @@ void QTreeView::drawBranches(QPainter *painter, const QRect &rect, opt.rect = primitive; const bool expanded = viewItem.expanded; - const bool children = (((expanded && viewItem.total > 0)) // already laid out and has children - || d->hasVisibleChildren(index)); // not laid out yet, so we don't know - bool moreSiblings = false; - if (d->hiddenIndexes.isEmpty()) - moreSiblings = (d->model->rowCount(parent) - 1 > index.row()); - else - moreSiblings = ((d->viewItems.size() > item +1) - && (d->viewItems.at(item + 1).index.parent() == parent)); + const bool children = viewItem.hasChildren; + bool moreSiblings = viewItem.hasMoreSiblings; opt.state = QStyle::State_Item | extraFlags | (moreSiblings ? QStyle::State_Sibling : QStyle::State_None) @@ -1845,9 +1840,7 @@ void QTreeView::mouseDoubleClickEvent(QMouseEvent *event) return; // user clicked outside the items const QPersistentModelIndex firstColumnIndex = d->viewItems.at(i).index; - - int column = d->header->logicalIndexAt(event->x()); - QPersistentModelIndex persistent = firstColumnIndex.sibling(firstColumnIndex.row(), column); + const QPersistentModelIndex persistent = indexAt(event->pos()); if (d->pressedIndex != persistent) { mousePressEvent(event); @@ -3127,7 +3120,7 @@ void QTreeViewPrivate::layout(int i) int hidden = 0; int last = 0; int children = 0; - + QTreeViewItem *item = 0; for (int j = first; j < first + count; ++j) { current = model->index(j - first, 0, parent); if (isRowHidden(current)) { @@ -3135,17 +3128,25 @@ void QTreeViewPrivate::layout(int i) last = j - hidden + children; } else { last = j - hidden + children; - viewItems[last].index = current; - viewItems[last].level = level; - viewItems[last].height = 0; - viewItems[last].spanning = q->isFirstColumnSpanned(current.row(), parent); - viewItems[last].expanded = false; - viewItems[last].total = 0; + if (item) + item->hasMoreSiblings = true; + item = &viewItems[last]; + item->index = current; + item->level = level; + item->height = 0; + item->spanning = q->isFirstColumnSpanned(current.row(), parent); + item->expanded = false; + item->total = 0; + item->hasMoreSiblings = false; if (isIndexExpanded(current)) { - viewItems[last].expanded = true; + item->expanded = true; layout(last); - children += viewItems[last].total; + item = &viewItems[last]; + children += item->total; + item->hasChildren = item->total > 0; last = j - hidden + children; + } else { + item->hasChildren = hasVisibleChildren(current); } } } diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index def8253..62676d8 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -66,7 +66,9 @@ struct QTreeViewItem QModelIndex index; // we remove items whenever the indexes are invalidated uint expanded : 1; uint spanning : 1; - uint total : 30; // total number of children visible + uint hasChildren : 1; // if the item has visible children (even if collapsed) + uint hasMoreSiblings : 1; + uint total : 28; // total number of children visible uint level : 16; // indentation int height : 16; // row height }; diff --git a/src/gui/kernel/qguiplatformplugin.cpp b/src/gui/kernel/qguiplatformplugin.cpp index 6e074a1..b01d40f 100644 --- a/src/gui/kernel/qguiplatformplugin.cpp +++ b/src/gui/kernel/qguiplatformplugin.cpp @@ -288,6 +288,8 @@ int QGuiPlatformPlugin::platformHint(PlatformHint hint) #endif //by default keep ret = 0 so QCommonStyle will use the style default break; + default: + break; } return ret; } diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 70d130a..fbd461f 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -4661,7 +4661,7 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid case PM_ToolBarIconSize: ret = qt_guiPlatformPlugin()->platformHint(QGuiPlatformPlugin::PH_ToolBarIconSize); if (!ret) - ret = proxy()->pixelMetric(PM_SmallIconSize, opt, widget); + ret = int(QStyleHelper::dpiScaled(24.)); break; case PM_TabBarIconSize: diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index 09f5d36..f880351 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -5514,9 +5514,6 @@ int QPlastiqueStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, case PM_MenuHMargin: ret = 0; break; - case PM_ToolBarIconSize: - ret = 24; - break; case PM_ButtonShiftHorizontal: case PM_ButtonShiftVertical: ret = 1; diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 0f72440..5cf738e 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -454,9 +454,6 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW ret = proxy()->pixelMetric(PM_LargeIconSize, opt, widget); break; - case PM_ToolBarIconSize: - ret = int(QStyleHelper::dpiScaled(24.)); - break; case PM_DockWidgetTitleMargin: ret = int(QStyleHelper::dpiScaled(2.)); break; diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp index 6cb8b40..aafd087 100644 --- a/src/gui/styles/qwindowsvistastyle.cpp +++ b/src/gui/styles/qwindowsvistastyle.cpp @@ -159,7 +159,7 @@ QWindowsVistaStyle::QWindowsVistaStyle() } //convert Qt state flags to uxtheme button states -int buttonStateId(int flags, int partId) +static int buttonStateId(int flags, int partId) { int stateId = 0; if (partId == BP_RADIOBUTTON || partId == BP_CHECKBOX) { @@ -190,7 +190,7 @@ int buttonStateId(int flags, int partId) return stateId; } -void Animation::paint(QPainter *painter, const QStyleOption *option) +void QWindowsVistaAnimation::paint(QPainter *painter, const QStyleOption *option) { Q_UNUSED(option); Q_UNUSED(painter); @@ -205,7 +205,7 @@ void Animation::paint(QPainter *painter, const QStyleOption *option) + ((1-alpha)*_secondaryImage) */ -void Animation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) { +void QWindowsVistaAnimation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) { if (_secondaryImage.isNull() || _primaryImage.isNull()) return; @@ -251,7 +251,7 @@ void Animation::drawBlendedImage(QPainter *painter, QRect rect, float alpha) { initial and final state of the transition, depending on the time difference between _startTime and current time. */ -void Transition::paint(QPainter *painter, const QStyleOption *option) +void QWindowsVistaTransition::paint(QPainter *painter, const QStyleOption *option) { float alpha = 1.0; if (_duration > 0) { @@ -278,7 +278,7 @@ void Transition::paint(QPainter *painter, const QStyleOption *option) secondary pulse images depending on the time difference between _startTime and current time. */ -void Pulse::paint(QPainter *painter, const QStyleOption *option) +void QWindowsVistaPulse::paint(QPainter *painter, const QStyleOption *option) { float alpha = 1.0; if (_duration > 0) { @@ -393,8 +393,8 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt startImage.fill(0); QPainter startPainter(&startImage); - Animation *anim = d->widgetAnimation(widget); - Transition *t = new Transition; + QWindowsVistaAnimation *anim = d->widgetAnimation(widget); + QWindowsVistaTransition *t = new QWindowsVistaTransition; t->setWidget(w); // If we have a running animation on the widget already, we will use that to paint the initial @@ -531,7 +531,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt case PE_IndicatorCheckBox: case PE_IndicatorRadioButton: { - if (Animation *a = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) { a->paint(painter, option); } else { QWindowsXPStyle::drawPrimitive(element, option, painter, widget); @@ -644,7 +644,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt break; case PE_FrameLineEdit: - if (Animation *anim = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) { anim->paint(painter, option); } else { QPainter *p = painter; @@ -929,13 +929,13 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (doTransition) { QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); - Animation *anim = d->widgetAnimation(widget); + QWindowsVistaAnimation *anim = d->widgetAnimation(widget); QStyleOptionButton opt = *button; opt.state = (QStyle::State)oldState; startImage.fill(0); - Transition *t = new Transition; + QWindowsVistaTransition *t = new QWindowsVistaTransition; t->setWidget(w); QPainter startPainter(&startImage); @@ -972,7 +972,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { - if (Animation *anim = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) { anim->paint(painter, option); } else { name = QLatin1String("BUTTON"); @@ -999,14 +999,14 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption !(state & (State_Sunken | State_On)) && !(state & State_MouseOver) && (state & State_Enabled) && (state & State_Active)) { - Animation *anim = d->widgetAnimation(widget); + QWindowsVistaAnimation *anim = d->widgetAnimation(widget); if (!anim && widget) { QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); startImage.fill(0); QImage alternateImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); alternateImage.fill(0); - Pulse *pulse = new Pulse; + QWindowsVistaPulse *pulse = new QWindowsVistaPulse; pulse->setWidget(const_cast<QWidget*>(widget)); QPainter startPainter(&startImage); @@ -1079,7 +1079,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (const QProgressBar *progressbar = qobject_cast<const QProgressBar *>(widget)) { if (((progressbar->value() > 0 && d->transitionsEnabled()) || isIndeterminate)) { if (!d->widgetAnimation(progressbar) && progressbar->value() < progressbar->maximum()) { - Animation *a = new Animation; + QWindowsVistaAnimation *a = new QWindowsVistaAnimation; a->setWidget(const_cast<QWidget*>(widget)); a->setStartTime(QTime::currentTime()); d->startAnimation(a); @@ -1095,7 +1095,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption QTime current = QTime::currentTime(); if (isIndeterminate) { - if (Animation *a = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) { int glowSize = 120; int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width()); int animOffset = a->startTime().msecsTo(current) / 4; @@ -1165,7 +1165,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption } d->drawBackground(theme); - if (Animation *a = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *a = d->widgetAnimation(widget)) { int glowSize = 140; int animationWidth = glowSize * 2 + (vertical ? theme.rect.height() : theme.rect.width()); int animOffset = a->startTime().msecsTo(current) / 4; @@ -1603,8 +1603,8 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle if (doTransition) { QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); - Animation *anim = d->widgetAnimation(widget); - Transition *t = new Transition; + QWindowsVistaAnimation *anim = d->widgetAnimation(widget); + QWindowsVistaTransition *t = new QWindowsVistaTransition; t->setWidget(w); if (!anim) { if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox*>(option)) { @@ -1651,7 +1651,7 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle t->setDuration(500); } - if (Animation *anim = d->widgetAnimation(widget)) { + if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) { anim->paint(painter, option); return; } @@ -2533,7 +2533,7 @@ void QWindowsVistaStylePrivate::timerEvent() !animations[i]->running() || !QWindowsVistaStylePrivate::useVista()) { - Animation *a = animations.takeAt(i); + QWindowsVistaAnimation *a = animations.takeAt(i); delete a; } } @@ -2546,14 +2546,14 @@ void QWindowsVistaStylePrivate::stopAnimation(const QWidget *w) { for (int i = animations.size() - 1 ; i >= 0 ; --i) { if (animations[i]->widget() == w) { - Animation *a = animations.takeAt(i); + QWindowsVistaAnimation *a = animations.takeAt(i); delete a; break; } } } -void QWindowsVistaStylePrivate::startAnimation(Animation *t) +void QWindowsVistaStylePrivate::startAnimation(QWindowsVistaAnimation *t) { Q_Q(QWindowsVistaStyle); stopAnimation(t->widget()); @@ -2575,11 +2575,11 @@ bool QWindowsVistaStylePrivate::transitionsEnabled() const } -Animation * QWindowsVistaStylePrivate::widgetAnimation(const QWidget *widget) const +QWindowsVistaAnimation * QWindowsVistaStylePrivate::widgetAnimation(const QWidget *widget) const { if (!widget) return 0; - foreach (Animation *a, animations) { + foreach (QWindowsVistaAnimation *a, animations) { if (a->widget() == widget) return a; } diff --git a/src/gui/styles/qwindowsvistastyle_p.h b/src/gui/styles/qwindowsvistastyle_p.h index e9bbb77..04823c1 100644 --- a/src/gui/styles/qwindowsvistastyle_p.h +++ b/src/gui/styles/qwindowsvistastyle_p.h @@ -136,11 +136,11 @@ QT_BEGIN_NAMESPACE #define TDLG_SECONDARYPANEL 8 #endif -class Animation +class QWindowsVistaAnimation { public : - Animation() : _running(true) { } - virtual ~Animation() { } + QWindowsVistaAnimation() : _running(true) { } + virtual ~QWindowsVistaAnimation() { } QWidget * widget() const { return _widget; } bool running() const { return _running; } const QTime &startTime() const { return _startTime; } @@ -161,11 +161,11 @@ protected: // Handles state transition animations -class Transition : public Animation +class QWindowsVistaTransition : public QWindowsVistaAnimation { public : - Transition() : Animation() {} - virtual ~Transition() { } + QWindowsVistaTransition() : QWindowsVistaAnimation() {} + virtual ~QWindowsVistaTransition() { } void setDuration(int duration) { _duration = duration; } void setStartImage(const QImage &image) { _primaryImage = image; } void setEndImage(const QImage &image) { _secondaryImage = image; } @@ -176,11 +176,11 @@ public : // Handles pulse animations (default buttons) -class Pulse: public Animation +class QWindowsVistaPulse: public QWindowsVistaAnimation { public : - Pulse() : Animation() {} - virtual ~Pulse() { } + QWindowsVistaPulse() : QWindowsVistaAnimation() {} + virtual ~QWindowsVistaPulse() { } void setDuration(int duration) { _duration = duration; } void setPrimaryImage(const QImage &image) { _primaryImage = image; } void setAlternateImage(const QImage &image) { _secondaryImage = image; } @@ -199,15 +199,15 @@ public: ~QWindowsVistaStylePrivate(); static bool resolveSymbols(); static inline bool useVista(); - void startAnimation(Animation *); + void startAnimation(QWindowsVistaAnimation *); void stopAnimation(const QWidget *); - Animation* widgetAnimation(const QWidget *) const; + QWindowsVistaAnimation* widgetAnimation(const QWidget *) const; void timerEvent(); bool transitionsEnabled() const; QWidget *treeViewHelper(); private: - QList <Animation*> animations; + QList <QWindowsVistaAnimation*> animations; QBasicTimer animationTimer; QWidget *m_treeViewHelper; }; diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 1b4c380..447087c 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -2324,22 +2324,22 @@ QDataStream &operator>>(QDataStream &s, QFont &font) */ QFontInfo::QFontInfo(const QFont &font) : d(font.d.data()) -{ d->ref.ref(); } +{ +} /*! Constructs a copy of \a fi. */ QFontInfo::QFontInfo(const QFontInfo &fi) - : d(fi.d) -{ d->ref.ref(); } + : d(fi.d.data()) +{ +} /*! Destroys the font info object. */ QFontInfo::~QFontInfo() { - if (!d->ref.deref()) - delete d; } /*! @@ -2347,7 +2347,7 @@ QFontInfo::~QFontInfo() */ QFontInfo &QFontInfo::operator=(const QFontInfo &fi) { - qAtomicAssign(d, fi.d); + d = fi.d.data(); return *this; } diff --git a/src/gui/text/qfontinfo.h b/src/gui/text/qfontinfo.h index 335d761..0998949 100644 --- a/src/gui/text/qfontinfo.h +++ b/src/gui/text/qfontinfo.h @@ -43,6 +43,7 @@ #define QFONTINFO_H #include <QtGui/qfont.h> +#include <QtCore/qsharedpointer.h> QT_BEGIN_HEADER @@ -77,7 +78,7 @@ public: bool exactMatch() const; private: - QFontPrivate *d; + QExplicitlySharedDataPointer<QFontPrivate> d; }; QT_END_NAMESPACE diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index ce122aa..b8c1b33 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -165,7 +165,6 @@ extern int qt_defaultDpi(); QFontMetrics::QFontMetrics(const QFont &font) : d(font.d.data()) { - d->ref.ref(); } /*! @@ -196,7 +195,6 @@ QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice) d->screen = screen; } else { d = font.d.data(); - d->ref.ref(); } } @@ -205,8 +203,9 @@ QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice) Constructs a copy of \a fm. */ QFontMetrics::QFontMetrics(const QFontMetrics &fm) - : d(fm.d) -{ d->ref.ref(); } + : d(fm.d.data()) +{ +} /*! Destroys the font metrics object and frees all allocated @@ -214,8 +213,6 @@ QFontMetrics::QFontMetrics(const QFontMetrics &fm) */ QFontMetrics::~QFontMetrics() { - if (!d->ref.deref()) - delete d; } /*! @@ -223,7 +220,7 @@ QFontMetrics::~QFontMetrics() */ QFontMetrics &QFontMetrics::operator=(const QFontMetrics &fm) { - qAtomicAssign(d, fm.d); + d = fm.d.data(); return *this; } @@ -536,7 +533,7 @@ int QFontMetrics::width(const QString &text, int len) const if (len == 0) return 0; - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; return qRound(layout.width(0, len)); } @@ -612,7 +609,7 @@ int QFontMetrics::charWidth(const QString &text, int pos) const int from = qMax(0, pos - 8); int to = qMin(text.length(), pos + 8); QString cstr = QString::fromRawData(text.unicode() + from, to - from); - QTextEngine layout(cstr, d); + QTextEngine layout(cstr, d.data()); layout.ignoreBidi = true; layout.itemize(); width = qRound(layout.width(pos-from, 1)); @@ -661,7 +658,7 @@ QRect QFontMetrics::boundingRect(const QString &text) const if (text.length() == 0) return QRect(); - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.boundingBox(0, text.length()); @@ -770,7 +767,7 @@ QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &te QRectF rb; QRectF rr(rect); - qt_format_text(QFont(d), rr, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, + qt_format_text(QFont(d.data()), rr, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, tabArrayLen, 0); return rb.toAlignedRect(); @@ -831,7 +828,7 @@ QRect QFontMetrics::tightBoundingRect(const QString &text) const if (text.length() == 0) return QRect(); - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.tightBoundingBox(0, text.length()); @@ -876,7 +873,7 @@ QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, in } _text = _text.mid(posA); } - QStackTextEngine engine(_text, QFont(d)); + QStackTextEngine engine(_text, QFont(d.data())); return engine.elidedText(mode, width, flags); } @@ -989,9 +986,8 @@ int QFontMetrics::lineWidth() const from the given \a fontMetrics object. */ QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics) - : d(fontMetrics.d) + : d(fontMetrics.d.data()) { - d->ref.ref(); } /*! @@ -1001,7 +997,7 @@ QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics) */ QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other) { - qAtomicAssign(d, other.d); + d = other.d.data(); return *this; } @@ -1021,7 +1017,6 @@ QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other) QFontMetricsF::QFontMetricsF(const QFont &font) : d(font.d.data()) { - d->ref.ref(); } /*! @@ -1052,7 +1047,6 @@ QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice) d->screen = screen; } else { d = font.d.data(); - d->ref.ref(); } } @@ -1061,8 +1055,9 @@ QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice) Constructs a copy of \a fm. */ QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm) - : d(fm.d) -{ d->ref.ref(); } + : d(fm.d.data()) +{ +} /*! Destroys the font metrics object and frees all allocated @@ -1070,8 +1065,6 @@ QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm) */ QFontMetricsF::~QFontMetricsF() { - if (!d->ref.deref()) - delete d; } /*! @@ -1079,7 +1072,7 @@ QFontMetricsF::~QFontMetricsF() */ QFontMetricsF &QFontMetricsF::operator=(const QFontMetricsF &fm) { - qAtomicAssign(d, fm.d); + d = fm.d.data(); return *this; } @@ -1374,7 +1367,7 @@ qreal QFontMetricsF::rightBearing(QChar ch) const */ qreal QFontMetricsF::width(const QString &text) const { - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); return layout.width(0, text.length()).toReal(); @@ -1451,7 +1444,7 @@ QRectF QFontMetricsF::boundingRect(const QString &text) const if (len == 0) return QRectF(); - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.boundingBox(0, len); @@ -1559,7 +1552,7 @@ QRectF QFontMetricsF::boundingRect(const QRectF &rect, int flags, const QString& tabArrayLen++; QRectF rb; - qt_format_text(QFont(d), rect, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, + qt_format_text(QFont(d.data()), rect, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray, tabArrayLen, 0); return rb; } @@ -1624,7 +1617,7 @@ QRectF QFontMetricsF::tightBoundingRect(const QString &text) const if (text.length() == 0) return QRect(); - QTextEngine layout(text, d); + QTextEngine layout(text, d.data()); layout.ignoreBidi = true; layout.itemize(); glyph_metrics_t gm = layout.tightBoundingBox(0, text.length()); @@ -1649,7 +1642,7 @@ QRectF QFontMetricsF::tightBoundingRect(const QString &text) const */ QString QFontMetricsF::elidedText(const QString &text, Qt::TextElideMode mode, qreal width, int flags) const { - QStackTextEngine engine(text, QFont(d)); + QStackTextEngine engine(text, QFont(d.data())); return engine.elidedText(mode, QFixed::fromReal(width), flags); } diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h index 1147e3a..23200c5 100644 --- a/src/gui/text/qfontmetrics.h +++ b/src/gui/text/qfontmetrics.h @@ -43,6 +43,7 @@ #define QFONTMETRICS_H #include <QtGui/qfont.h> +#include <QtCore/qsharedpointer.h> #ifndef QT_INCLUDE_COMPAT #include <QtCore/qrect.h> #endif @@ -131,7 +132,7 @@ private: friend class QFontMetricsF; friend class QStackTextEngine; - QFontPrivate *d; + QExplicitlySharedDataPointer<QFontPrivate> d; }; @@ -187,7 +188,7 @@ public: inline bool operator !=(const QFontMetricsF &other) const { return !operator==(other); } private: - QFontPrivate *d; + QExplicitlySharedDataPointer<QFontPrivate> d; }; QT_END_NAMESPACE diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index 05e1e74..6fd8706 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -192,6 +192,8 @@ void QComboBoxPrivate::_q_modelReset() lineEdit->setText(QString()); updateLineEditGeometry(); } + if (currentIndex.row() != indexBeforeChange) + _q_emitCurrentIndexChanged(currentIndex); q->update(); } @@ -992,14 +994,6 @@ void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIn } } -void QComboBoxPrivate::_q_rowsAboutToBeInserted(const QModelIndex & parent, - int /*start*/, int /*end*/) -{ - if (parent != root) - return; - indexBeforeChange = currentIndex.row(); -} - void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int end) { Q_Q(QComboBox); @@ -1022,11 +1016,8 @@ void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int } } -void QComboBoxPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int /*start*/, int /*end*/) +void QComboBoxPrivate::_q_updateIndexBeforeChange() { - if (parent != root) - return; - indexBeforeChange = currentIndex.row(); } @@ -1868,15 +1859,17 @@ void QComboBox::setModel(QAbstractItemModel *model) disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); disconnect(d->model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int))); + this, SLOT(_q_updateIndexBeforeChange())); disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(_q_rowsInserted(QModelIndex,int,int))); disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); + this, SLOT(_q_updateIndexBeforeChange())); disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(_q_rowsRemoved(QModelIndex,int,int))); disconnect(d->model, SIGNAL(destroyed()), this, SLOT(_q_modelDestroyed())); + disconnect(d->model, SIGNAL(modelAboutToBeReset()), + this, SLOT(_q_updateIndexBeforeChange())); disconnect(d->model, SIGNAL(modelReset()), this, SLOT(_q_modelReset())); if (d->model->QObject::parent() == this) @@ -1888,15 +1881,17 @@ void QComboBox::setModel(QAbstractItemModel *model) connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); connect(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int))); + this, SLOT(_q_updateIndexBeforeChange())); connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(_q_rowsInserted(QModelIndex,int,int))); connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); + this, SLOT(_q_updateIndexBeforeChange())); connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(_q_rowsRemoved(QModelIndex,int,int))); connect(model, SIGNAL(destroyed()), this, SLOT(_q_modelDestroyed())); + connect(model, SIGNAL(modelAboutToBeReset()), + this, SLOT(_q_updateIndexBeforeChange())); connect(model, SIGNAL(modelReset()), this, SLOT(_q_modelReset())); diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h index 6a85096..4089a09 100644 --- a/src/gui/widgets/qcombobox.h +++ b/src/gui/widgets/qcombobox.h @@ -308,9 +308,8 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_returnPressed()) Q_PRIVATE_SLOT(d_func(), void _q_resetButton()) Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &, const QModelIndex &)) - Q_PRIVATE_SLOT(d_func(), void _q_rowsAboutToBeInserted(const QModelIndex & parent, int start, int end)) + Q_PRIVATE_SLOT(d_func(), void _q_updateIndexBeforeChange()) Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex & parent, int start, int end)) - Q_PRIVATE_SLOT(d_func(), void _q_rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex & parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) Q_PRIVATE_SLOT(d_func(), void _q_modelReset()) diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h index f7458c4..06e51e4 100644 --- a/src/gui/widgets/qcombobox_p.h +++ b/src/gui/widgets/qcombobox_p.h @@ -357,9 +357,8 @@ public: #endif void _q_resetButton(); void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - void _q_rowsAboutToBeInserted(const QModelIndex & parent, int start, int end); + void _q_updateIndexBeforeChange(); void _q_rowsInserted(const QModelIndex & parent, int start, int end); - void _q_rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end); void _q_rowsRemoved(const QModelIndex & parent, int start, int end); void updateArrow(QStyle::StateFlag state); bool updateHoverControl(const QPoint &pos); diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index ea25901..1b5d1cd 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1878,6 +1878,10 @@ void QMenu::popup(const QPoint &p, QAction *atAction) if(snapToMouse) //position flowing left from the mouse pos.setX(mouse.x()-size.width()); + //if in a menubar, it should be right-aligned + if (qobject_cast<QMenuBar*>(d->causedPopup.widget)) + pos.rx() -= size.width(); + if (pos.x() < screen.left()+desktopFrame) pos.setX(qMax(p.x(), screen.left()+desktopFrame)); if (pos.x()+size.width()-1 > screen.right()-desktopFrame) diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index f2f0722..689d2e1 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -336,30 +336,25 @@ void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst) const bool fitUp = (q->mapToGlobal(adjustedActionRect.topLeft()).y() >= popup_size.height()); const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom()); + const bool rtl = q->isRightToLeft(); const int actionWidth = adjustedActionRect.width(); if (!fitUp && !fitDown) { //we should shift the menu - bool shouldShiftToRight = !q->isRightToLeft(); - if (q->isRightToLeft() && popup_size.width() > pos.x()) + bool shouldShiftToRight = !rtl; + if (rtl && popup_size.width() > pos.x()) shouldShiftToRight = true; else if (actionWidth + popup_size.width() + pos.x() > screenRect.right()) shouldShiftToRight = false; - if (shouldShiftToRight) - pos.rx() += actionWidth; - else - pos.rx() -= popup_size.width(); - } else if (q->isRightToLeft()) { - pos.setX(pos.x()-(popup_size.width() - actionWidth)); - } - - if(pos.x() < screenRect.x()) { - pos.setX(screenRect.x()); - } else { - const int off = pos.x()+popup_size.width() - screenRect.right(); - if(off > 0) - pos.setX(qMax(screenRect.x(), pos.x()-off)); - + if (shouldShiftToRight) { + pos.rx() += actionWidth + (rtl ? popup_size.width() : 0); + } else { + //shift to left + if (!rtl) + pos.rx() -= popup_size.width(); + } + } else if (rtl) { + pos.rx() += actionWidth; } if(!defaultPopDown || (fitUp && !fitDown)) diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp index 40c0b02..5596ca4 100644 --- a/src/gui/widgets/qtoolbar.cpp +++ b/src/gui/widgets/qtoolbar.cpp @@ -183,6 +183,9 @@ void QToolBarPrivate::setWindowState(bool floating, bool unplug, const QRect &re if (visible) q->show(); + + if (floating != wasFloating) + emit q->topLevelChanged(floating); } void QToolBarPrivate::initDrag(const QPoint &pos) @@ -518,6 +521,19 @@ void QToolBarPrivate::plug(const QRect &r) */ /*! + \since 4.6 + + \fn void QToolBar::topLevelChanged(bool topLevel) + + This signal is emitted when the \l floating property changes. + The \a topLevel parameter is true if the toolbar is now floating; + otherwise it is false. + + \sa isWindow() +*/ + + +/*! Constructs a QToolBar with the given \a parent. */ QToolBar::QToolBar(QWidget *parent) diff --git a/src/gui/widgets/qtoolbar.h b/src/gui/widgets/qtoolbar.h index a084673..a1a24f0 100644 --- a/src/gui/widgets/qtoolbar.h +++ b/src/gui/widgets/qtoolbar.h @@ -142,6 +142,7 @@ Q_SIGNALS: void orientationChanged(Qt::Orientation orientation); void iconSizeChanged(const QSize &iconSize); void toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle); + void topLevelChanged(bool topLevel); protected: void actionEvent(QActionEvent *event); diff --git a/src/qt3support/widgets/q3dockarea.cpp b/src/qt3support/widgets/q3dockarea.cpp index afeefff..bb34622 100644 --- a/src/qt3support/widgets/q3dockarea.cpp +++ b/src/qt3support/widgets/q3dockarea.cpp @@ -1019,6 +1019,7 @@ void Q3DockArea::lineUp(bool keepNewLines) if (!keepNewLines) dw->setNewLine(false); } + layout->invalidate(); layout->activate(); } diff --git a/src/sql/models/qsqlquerymodel.cpp b/src/sql/models/qsqlquerymodel.cpp index a72ad8c..1719239 100644 --- a/src/sql/models/qsqlquerymodel.cpp +++ b/src/sql/models/qsqlquerymodel.cpp @@ -417,7 +417,7 @@ bool QSqlQueryModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) { Q_D(QSqlQueryModel); - if (orientation != Qt::Horizontal || section < 0) + if (orientation != Qt::Horizontal || section < 0 || columnCount() <= section) return false; if (d->headers.size() <= section) diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp index 0d3469d..8acae7a 100644 --- a/tests/auto/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/qcombobox/tst_qcombobox.cpp @@ -152,6 +152,7 @@ private slots: void subControlRectsWithOffset(); void task260974_menuItemRectangleForComboBoxPopup(); void removeItem(); + void resetModel(); protected slots: void onEditTextChanged( const QString &newString ); @@ -2416,5 +2417,37 @@ void tst_QComboBox::removeItem() QCOMPARE(cb.count(), 0); } +void tst_QComboBox::resetModel() +{ + class StringListModel : public QStringListModel + { + public: + StringListModel(const QStringList &list) : QStringListModel(list) + { + } + + void reset() + { + QStringListModel::reset(); + } + }; + QComboBox cb; + StringListModel model( QStringList() << "1" << "2"); + QSignalSpy spy(&cb, SIGNAL(currentIndexChanged(int))); + QCOMPARE(spy.count(), 0); + QCOMPARE(cb.currentIndex(), -1); //no selection + + cb.setModel(&model); + + QCOMPARE(spy.count(), 1); + QCOMPARE(cb.currentIndex(), 0); //first item selected + + model.reset(); + QCOMPARE(spy.count(), 2); + QCOMPARE(cb.currentIndex(), -1); //no selection + +} + + QTEST_MAIN(tst_QComboBox) #include "tst_qcombobox.moc" diff --git a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp index 6b2f0fe..e80f8e0 100644 --- a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp @@ -100,6 +100,20 @@ void tst_QFontMetrics::same() QFontMetrics fm(font); const QString text = QLatin1String("Some stupid STRING"); QCOMPARE(fm.size(0, text), fm.size(0, text)) ; + + { + QImage image; + QFontMetrics fm2(font, &image); + QString text2 = QLatin1String("Foo Foo"); + QCOMPARE(fm2.size(0, text2), fm2.size(0, text2)); //used to crash + } + + { + QImage image; + QFontMetricsF fm3(font, &image); + QString text2 = QLatin1String("Foo Foo"); + QCOMPARE(fm3.size(0, text2), fm3.size(0, text2)); //used to crash + } } diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 5348e59..c8a9fac 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -45,6 +45,7 @@ #include <QtGui/qgraphicswidget.h> #include <QtGui/qgraphicsproxywidget.h> #include <QtGui/qgraphicsview.h> +#include <QtGui/qwindowsstyle.h> class tst_QGraphicsAnchorLayout : public QObject { Q_OBJECT; @@ -72,6 +73,7 @@ private slots: void proportionalPreferred(); void example(); void setSpacing(); + void styleDefaults(); void hardComplexS60(); void stability(); void delete_anchor(); @@ -1104,6 +1106,166 @@ void tst_QGraphicsAnchorLayout::setSpacing() delete view; } +class CustomLayoutStyle : public QWindowsStyle +{ + Q_OBJECT +public: + CustomLayoutStyle() : QWindowsStyle() + { + hspacing = 5; + vspacing = 10; + } + + virtual int pixelMetric(PixelMetric metric, const QStyleOption * option = 0, + const QWidget * widget = 0 ) const; + + int hspacing; + int vspacing; + +protected slots: + int layoutSpacingImplementation(QSizePolicy::ControlType control1, + QSizePolicy::ControlType control2, + Qt::Orientation orientation, + const QStyleOption *option = 0, + const QWidget *widget = 0) const; + +}; + +#define CT1(c) CT2(c, c) +#define CT2(c1, c2) ((uint)c1 << 16) | (uint)c2 + +int CustomLayoutStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1, + QSizePolicy::ControlType control2, + Qt::Orientation orientation, + const QStyleOption * /*option = 0*/, + const QWidget * /*widget = 0*/) const +{ + if (orientation == Qt::Horizontal) { + switch (CT2(control1, control2)) { + case CT1(QSizePolicy::PushButton): + return 2; + break; + } + return 5; + } else { + switch (CT2(control1, control2)) { + case CT1(QSizePolicy::RadioButton): + return 2; + break; + + } + return 10; + } +} + +int CustomLayoutStyle::pixelMetric(PixelMetric metric, const QStyleOption * option /*= 0*/, + const QWidget * widget /*= 0*/ ) const +{ + switch (metric) { + case PM_LayoutLeftMargin: + return 0; + break; + case PM_LayoutTopMargin: + return 3; + break; + case PM_LayoutRightMargin: + return 6; + break; + case PM_LayoutBottomMargin: + return 9; + break; + case PM_LayoutHorizontalSpacing: + return hspacing; + case PM_LayoutVerticalSpacing: + return vspacing; + break; + default: + break; + } + return QWindowsStyle::pixelMetric(metric, option, widget); +} + +void tst_QGraphicsAnchorLayout::styleDefaults() +{ + QSizeF min (10, 10); + QSizeF pref(20, 20); + QSizeF max (50, 50); + + /* + create this layout, where a,b have controlType QSizePolicy::RadioButton + c,d have controlType QSizePolicy::PushButton: + +-------+ + |a | + | b | + | c | + | d| + +-------+ + */ + QGraphicsScene scene; + QGraphicsWidget *a = createItem(min, pref, max); + QSizePolicy spRadioButton = a->sizePolicy(); + spRadioButton.setControlType(QSizePolicy::RadioButton); + a->setSizePolicy(spRadioButton); + + QGraphicsWidget *b = createItem(min, pref, max); + b->setSizePolicy(spRadioButton); + + QGraphicsWidget *c = createItem(min, pref, max); + QSizePolicy spPushButton = c->sizePolicy(); + spPushButton.setControlType(QSizePolicy::PushButton); + c->setSizePolicy(spPushButton); + + QGraphicsWidget *d = createItem(min, pref, max); + d->setSizePolicy(spPushButton); + + QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window); + + // Test layoutSpacingImplementation + CustomLayoutStyle *style = new CustomLayoutStyle; + style->hspacing = -1; + style->vspacing = -1; + window->setStyle(style); + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + + l->addCornerAnchors(l, Qt::TopLeftCorner, a, Qt::TopLeftCorner); + l->addCornerAnchors(a, Qt::BottomRightCorner, b, Qt::TopLeftCorner); + l->addCornerAnchors(b, Qt::BottomRightCorner, c, Qt::TopLeftCorner); + l->addCornerAnchors(c, Qt::BottomRightCorner, d, Qt::TopLeftCorner); + l->addCornerAnchors(d, Qt::BottomRightCorner, l, Qt::BottomRightCorner); + + window->setLayout(l); + + scene.addItem(window); + + window->show(); + QGraphicsView *view = new QGraphicsView(&scene); + view->resize(200, 200); + view->show(); + + window->adjustSize(); + QCOMPARE(a->geometry(), QRectF(0, 3, 20, 20)); //radio + QCOMPARE(b->geometry(), QRectF(25, 25, 20, 20)); //radio + QCOMPARE(c->geometry(), QRectF(50, 55, 20, 20)); //push + QCOMPARE(d->geometry(), QRectF(72, 85, 20, 20)); //push + QCOMPARE(l->geometry(), QRectF(0, 0, 98, 114)); + + + // Test pixelMetric(PM_Layout{Horizontal|Vertical}Spacing + window->setStyle(0); + + style->hspacing = 1; + style->vspacing = 2; + + window->setStyle(style); + window->adjustSize(); + QCOMPARE(a->geometry(), QRectF(0, 3, 20, 20)); + QCOMPARE(b->geometry(), QRectF(21, 25, 20, 20)); + QCOMPARE(c->geometry(), QRectF(42, 47, 20, 20)); + QCOMPARE(d->geometry(), QRectF(63, 69, 20, 20)); + QCOMPARE(l->geometry(), QRectF(0, 0, 89, 98)); +} + + /*! Taken from "hard" complex case, found at https://cwiki.nokia.com/S60QTUI/AnchorLayoutComplexCases diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index dcad8e1..dabf64c 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -372,6 +372,7 @@ private slots: void itemUsesExtendedStyleOption(); void itemSendsGeometryChanges(); void moveItem(); + void moveLineItem(); void sorting_data(); void sorting(); void itemHasNoContents(); @@ -7438,6 +7439,39 @@ void tst_QGraphicsItem::moveItem() COMPARE_REGIONS(view.paintedRegion, expectedParentRegion); } +void tst_QGraphicsItem::moveLineItem() +{ + QGraphicsScene scene; + scene.setSceneRect(0, 0, 200, 200); + QGraphicsLineItem *item = new QGraphicsLineItem(0, 0, 100, 0); + item->setPos(50, 50); + scene.addItem(item); + + MyGraphicsView view(&scene); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(200); + view.reset(); + + const QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform()) + .mapRect(item->boundingRect()).toRect(); + QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); // antialiasing + + // Make sure the calculated region is correct. + item->update(); + QTest::qWait(10); + QCOMPARE(view.paintedRegion, expectedRegion); + view.reset(); + + // Old position: (50, 50) + item->setPos(50, 100); + expectedRegion += expectedRegion.translated(0, 50); + QTest::qWait(10); + QCOMPARE(view.paintedRegion, expectedRegion); +} + void tst_QGraphicsItem::sorting_data() { QTest::addColumn<int>("index"); @@ -8535,24 +8569,24 @@ void tst_QGraphicsItem::stackBefore() QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child1 << child3 << child4 << child2)); // Move child2 before child1 - child2->stackBefore(child1); + child2->stackBefore(child1); // 2134 QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child2->stackBefore(child2); + child2->stackBefore(child2); // 2134 QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child1->setZValue(1); + child1->setZValue(1); // 2341 QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child3 << child4 << child1)); - child1->stackBefore(child2); // no effect + child1->stackBefore(child2); // 2341 QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child3 << child4 << child1)); - child1->setZValue(0); - QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child4->stackBefore(child1); - QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child4 << child1 << child3)); - child4->setZValue(1); - QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child3->stackBefore(child1); - QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child3 << child1 << child4)); - child4->setZValue(0); - QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child4 << child3 << child1)); + child1->setZValue(0); // 1234 + QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child1 << child2 << child3 << child4)); + child4->stackBefore(child1); // 4123 + QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child4 << child1 << child2 << child3)); + child4->setZValue(1); // 1234 (4123) + QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child1 << child2 << child3 << child4)); + child3->stackBefore(child1); // 3124 (4312) + QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child3 << child1 << child2 << child4)); + child4->setZValue(0); // 4312 + QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child4 << child3 << child1 << child2)); // Make them all toplevels child1->setParentItem(0); @@ -8574,24 +8608,24 @@ void tst_QGraphicsItem::stackBefore() QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child1 << child3 << child4 << child2)); // Move child2 before child1 - child2->stackBefore(child1); + child2->stackBefore(child1); // 2134 QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child2->stackBefore(child2); + child2->stackBefore(child2); // 2134 QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child1->setZValue(1); + child1->setZValue(1); // 2341 QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child3 << child4 << child1)); - child1->stackBefore(child2); // no effect + child1->stackBefore(child2); // 2341 QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child3 << child4 << child1)); - child1->setZValue(0); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child4->stackBefore(child1); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child4 << child1 << child3)); - child4->setZValue(1); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4)); - child3->stackBefore(child1); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child3 << child1 << child4)); - child4->setZValue(0); - QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child4 << child3 << child1)); + child1->setZValue(0); // 1234 + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child1 << child2 << child3 << child4)); + child4->stackBefore(child1); // 4123 + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child4 << child1 << child2 << child3)); + child4->setZValue(1); // 1234 (4123) + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child1 << child2 << child3 << child4)); + child3->stackBefore(child1); // 3124 (4312) + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child3 << child1 << child2 << child4)); + child4->setZValue(0); // 4312 + QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child4 << child3 << child1 << child2)); } void tst_QGraphicsItem::QTBUG_4233_updateCachedWithSceneRect() diff --git a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp index 1109e5e..9dfd486 100644 --- a/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp +++ b/tests/auto/qgraphicssceneindex/tst_qgraphicssceneindex.cpp @@ -66,6 +66,7 @@ private slots: void movingItems(); void connectedToSceneRectChanged(); void items(); + void removeItems(); void clear(); private: @@ -268,6 +269,63 @@ void tst_QGraphicsSceneIndex::items() QCOMPARE(scene.items().size(), 3); } +class RectWidget : public QGraphicsWidget +{ + Q_OBJECT +public: + RectWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent) + { + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + painter->setBrush(brush); + painter->drawRect(boundingRect()); + } +public: + QBrush brush; +}; + +void tst_QGraphicsSceneIndex::removeItems() +{ + QGraphicsScene scene; + + RectWidget *parent = new RectWidget; + parent->brush = QBrush(QColor(Qt::magenta)); + parent->setGeometry(250, 250, 400, 400); + + RectWidget *widget = new RectWidget(parent); + widget->brush = QBrush(QColor(Qt::blue)); + widget->setGeometry(10, 10, 200, 200); + + RectWidget *widgetChild1 = new RectWidget(widget); + widgetChild1->brush = QBrush(QColor(Qt::green)); + widgetChild1->setGeometry(20, 20, 100, 100); + + RectWidget *widgetChild2 = new RectWidget(widgetChild1); + widgetChild2->brush = QBrush(QColor(Qt::yellow)); + widgetChild2->setGeometry(25, 25, 50, 50); + + scene.addItem(parent); + + QGraphicsView view(&scene); + view.resize(600, 600); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + + QApplication::processEvents(); + + scene.removeItem(widgetChild1); + + delete widgetChild1; + + //We move the parent + scene.items(295, 295, 50, 50); + + //This should not crash +} + void tst_QGraphicsSceneIndex::clear() { class MyItem : public QGraphicsItem diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index dc08d0e..092f81d 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -194,6 +194,8 @@ private slots: void acceptDrops(); void optimizationFlags(); void optimizationFlags_dontSavePainterState(); + void optimizationFlags_dontSavePainterState2_data(); + void optimizationFlags_dontSavePainterState2(); void levelOfDetail_data(); void levelOfDetail(); void scrollBarRanges_data(); @@ -2455,6 +2457,53 @@ void tst_QGraphicsView::optimizationFlags_dontSavePainterState() QTest::qWaitForWindowShown(&painter2); } +void tst_QGraphicsView::optimizationFlags_dontSavePainterState2_data() +{ + QTest::addColumn<bool>("savePainter"); + QTest::newRow("With painter state protection") << true; + QTest::newRow("Without painter state protection") << false; +} + +void tst_QGraphicsView::optimizationFlags_dontSavePainterState2() +{ + QFETCH(bool, savePainter); + + class MyScene : public QGraphicsScene + { + public: + void drawBackground(QPainter *p, const QRectF &) + { transformInDrawBackground = p->worldTransform(); } + + void drawForeground(QPainter *p, const QRectF &) + { transformInDrawForeground = p->worldTransform(); } + + QTransform transformInDrawBackground; + QTransform transformInDrawForeground; + }; + + MyScene scene; + // Add transformed dummy items to make sure the painter's worldTransform() is changed in drawItems. + scene.addRect(0, 0, 20, 20)->setTransform(QTransform::fromScale(2, 2)); + scene.addRect(50, 50, 20, 20)->setTransform(QTransform::fromTranslate(200, 200)); + + QGraphicsView view(&scene); + if (!savePainter) + view.setOptimizationFlag(QGraphicsView::DontSavePainterState); + view.rotate(45); + view.scale(1.5, 1.5); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(150); + + // Make sure the painter's world transform is preserved after drawItems. + const QTransform expectedTransform = view.viewportTransform(); + QVERIFY(!expectedTransform.isIdentity()); + QCOMPARE(scene.transformInDrawForeground, expectedTransform); + QCOMPARE(scene.transformInDrawBackground, expectedTransform); +} + class LodItem : public QGraphicsRectItem { public: diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index 6e211ae..65ab12d 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -1132,6 +1132,7 @@ void tst_QListView::selection() #endif v.show(); + QTest::qWaitForWindowShown(&v); QApplication::processEvents(); v.setSelection(selectionRect, QItemSelectionModel::ClearAndSelect); @@ -1184,6 +1185,7 @@ void tst_QListView::scrollTo() lv.setModel(&model); lv.setFixedSize(100, 200); lv.show(); + QTest::qWaitForWindowShown(&lv); //by default, the list view scrolls per item and has no wrapping QModelIndex index = model.index(6,0); @@ -1782,6 +1784,7 @@ void tst_QListView::task262152_setModelColumnNavigate() view.setModelColumn(1); view.show(); + QTest::qWaitForWindowShown(&view); QTest::qWait(100); QTest::keyClick(&view, Qt::Key_Down); QTest::qWait(100); diff --git a/tests/auto/qlistwidget/tst_qlistwidget.cpp b/tests/auto/qlistwidget/tst_qlistwidget.cpp index e825c8f..5c6ed54 100644 --- a/tests/auto/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/qlistwidget/tst_qlistwidget.cpp @@ -46,6 +46,7 @@ #include <qlist.h> #include <qlistwidget.h> +#include <private/qlistwidget_p.h> //TESTED_CLASS= //TESTED_FILES= @@ -95,6 +96,8 @@ private slots: void insertItem(); void insertItems_data(); void insertItems(); + void moveItemsPriv_data(); + void moveItemsPriv(); void itemAssignment(); void item_data(); @@ -849,6 +852,62 @@ void tst_QListWidget::removeItems() } +void tst_QListWidget::moveItemsPriv_data() +{ + QTest::addColumn<int>("rowCount"); + QTest::addColumn<int>("srcRow"); + QTest::addColumn<int>("dstRow"); + QTest::addColumn<bool>("shouldHaveSignaled"); + + QTest::newRow("Empty") << 0 << 0 << 0 << false; + QTest::newRow("Overflow src") << 5 << 5 << 2 << false; + QTest::newRow("Underflow src") << 5 << -1 << 2 << false; + QTest::newRow("Overflow dst") << 5 << 2 << 5 << false; + QTest::newRow("Underflow dst") << 5 << 2 << -1 << false; + QTest::newRow("Same place") << 5 << 2 << 2 << false; + QTest::newRow("Up") << 5 << 4 << 2 << true; + QTest::newRow("Down") << 5 << 2 << 4 << true; +} + +void tst_QListWidget::moveItemsPriv() +{ + QFETCH(int, rowCount); + QFETCH(int, srcRow); + QFETCH(int, dstRow); + QFETCH(bool, shouldHaveSignaled); + + for (int r = 0; r < rowCount; ++r) + new QListWidgetItem(QString::number(r), testWidget); + + QListModel *model = dynamic_cast<QListModel *>(testWidget->model()); + QVERIFY(model); + QSignalSpy beginMoveSpy(model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy movedSpy(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + model->move(srcRow, dstRow); + + if (shouldHaveSignaled) { + if (srcRow < dstRow) + QCOMPARE(testWidget->item(dstRow - 1)->text(), QString::number(srcRow)); + else + QCOMPARE(testWidget->item(dstRow)->text(), QString::number(srcRow)); + + QCOMPARE(beginMoveSpy.count(), 1); + const QList<QVariant> &beginMoveArgs = beginMoveSpy.takeFirst(); + QCOMPARE(beginMoveArgs.at(1).toInt(), srcRow); + QCOMPARE(beginMoveArgs.at(2).toInt(), srcRow); + QCOMPARE(beginMoveArgs.at(4).toInt(), dstRow); + + QCOMPARE(movedSpy.count(), 1); + const QList<QVariant> &movedArgs = movedSpy.takeFirst(); + QCOMPARE(movedArgs.at(1).toInt(), srcRow); + QCOMPARE(movedArgs.at(2).toInt(), srcRow); + QCOMPARE(movedArgs.at(4).toInt(), dstRow); + } else { + QCOMPARE(beginMoveSpy.count(), 0); + QCOMPARE(movedSpy.count(), 0); + } +} + void tst_QListWidget::itemStreaming_data() { QTest::addColumn<QString>("text"); diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp index 07aa9f4..4291c3e 100644 --- a/tests/auto/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/qmenubar/tst_qmenubar.cpp @@ -86,6 +86,18 @@ private: uint sel_count; }; +class Menu : public QMenu +{ + Q_OBJECT + public slots: + void addActions() + { + //this will change the geometry of the menu + addAction("action1"); + addAction("action2"); + } +}; + class tst_QMenuBar : public QObject { Q_OBJECT @@ -1442,7 +1454,7 @@ void tst_QMenuBar::check_menuPosition() #ifdef Q_OS_WINCE_WM QSKIP("Qt/CE uses native menubar", SkipAll); #endif - QMenu menu; + Menu menu; #ifdef QT3_SUPPORT initComplexMenubar(); #else @@ -1496,6 +1508,21 @@ void tst_QMenuBar::check_menuPosition() menu.close(); } + //in RTL, the menu should be stuck at the right of the action geometry + { + Qt::LayoutDirection dir = qApp->layoutDirection(); + qApp->setLayoutDirection(Qt::RightToLeft); + menu.clear(); + QObject::connect(&menu, SIGNAL(aboutToShow()), &menu, SLOT(addActions())); + QRect mbItemRect = mw->menuBar()->actionGeometry(menu_action); + mbItemRect.moveTo(mw->menuBar()->mapToGlobal(mbItemRect.topLeft())); + QTest::keyClick(mw, Qt::Key_M, Qt::AltModifier ); + QVERIFY(menu.isActiveWindow()); + QCOMPARE(menu.geometry().right(), mbItemRect.right()); + menu.close(); + qApp->setLayoutDirection(dir); + } + } void tst_QMenuBar::task223138_triggered() diff --git a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp index 8578d36..8d937e9 100644 --- a/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp +++ b/tests/auto/qparallelanimationgroup/tst_qparallelanimationgroup.cpp @@ -56,8 +56,7 @@ public: virtual ~tst_QParallelAnimationGroup(); public Q_SLOTS: - void init(); - void cleanup(); + void initTestCase(); private slots: void construction(); @@ -86,13 +85,13 @@ tst_QParallelAnimationGroup::~tst_QParallelAnimationGroup() { } -void tst_QParallelAnimationGroup::init() +void tst_QParallelAnimationGroup::initTestCase() { qRegisterMetaType<QAbstractAnimation::State>("QAbstractAnimation::State"); -} - -void tst_QParallelAnimationGroup::cleanup() -{ +#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAC) || defined(Q_WS_WINCE) + // give the Symbian and mac app start event queue time to clear + QTest::qWait(1000); +#endif } void tst_QParallelAnimationGroup::construction() @@ -486,10 +485,6 @@ void tst_QParallelAnimationGroup::updateChildrenWithRunningGroup() void tst_QParallelAnimationGroup::deleteChildrenWithRunningGroup() { -#if defined(Q_OS_SYMBIAN) - // give the Symbian app start event queue time to clear - QTest::qWait(1000); -#endif // test if children can be activated when their group is stopped QParallelAnimationGroup group; diff --git a/tests/auto/qpauseanimation/tst_qpauseanimation.cpp b/tests/auto/qpauseanimation/tst_qpauseanimation.cpp index b11efa0..4d0a7a7 100644 --- a/tests/auto/qpauseanimation/tst_qpauseanimation.cpp +++ b/tests/auto/qpauseanimation/tst_qpauseanimation.cpp @@ -93,8 +93,7 @@ public: virtual ~tst_QPauseAnimation(); public Q_SLOTS: - void init(); - void cleanup(); + void initTestCase(); private slots: void changeDirectionWhileRunning(); @@ -117,20 +116,15 @@ tst_QPauseAnimation::~tst_QPauseAnimation() { } -void tst_QPauseAnimation::init() +void tst_QPauseAnimation::initTestCase() { qRegisterMetaType<QAbstractAnimation::State>("QAbstractAnimation::State"); qRegisterMetaType<QAbstractAnimation::DeletionPolicy>("QAbstractAnimation::DeletionPolicy"); } -void tst_QPauseAnimation::cleanup() -{ -} - void tst_QPauseAnimation::changeDirectionWhileRunning() { - QUnifiedTimer *timer = QUnifiedTimer::instance(); - timer->setConsistentTiming(true); + EnableConsistentTiming enabled; TestablePauseAnimation animation; animation.setDuration(400); @@ -140,8 +134,6 @@ void tst_QPauseAnimation::changeDirectionWhileRunning() animation.setDirection(QAbstractAnimation::Backward); QTest::qWait(animation.totalDuration() + 50); QVERIFY(animation.state() == QAbstractAnimation::Stopped); - - timer->setConsistentTiming(false); } void tst_QPauseAnimation::noTimerUpdates_data() @@ -157,8 +149,7 @@ void tst_QPauseAnimation::noTimerUpdates_data() void tst_QPauseAnimation::noTimerUpdates() { - QUnifiedTimer *timer = QUnifiedTimer::instance(); - timer->setConsistentTiming(true); + EnableConsistentTiming enabled; QFETCH(int, duration); QFETCH(int, loopCount); @@ -168,16 +159,19 @@ void tst_QPauseAnimation::noTimerUpdates() animation.setLoopCount(loopCount); animation.start(); QTest::qWait(animation.totalDuration() + 100); + +#ifdef Q_OS_WIN + if (animation.state() != QAbstractAnimation::Stopped) + QEXPECT_FAIL("", "On windows, consistent timing is not working properly due to bad timer resolution", Abort); +#endif + QVERIFY(animation.state() == QAbstractAnimation::Stopped); QCOMPARE(animation.m_updateCurrentTimeCount, 1 + loopCount); - - timer->setConsistentTiming(false); } void tst_QPauseAnimation::mulitplePauseAnimations() { - QUnifiedTimer *timer = QUnifiedTimer::instance(); - timer->setConsistentTiming(true); + EnableConsistentTiming enabled; TestablePauseAnimation animation; animation.setDuration(200); @@ -188,16 +182,26 @@ void tst_QPauseAnimation::mulitplePauseAnimations() animation.start(); animation2.start(); QTest::qWait(animation.totalDuration() + 100); + +#ifdef Q_OS_WIN + if (animation.state() != QAbstractAnimation::Stopped) + QEXPECT_FAIL("", "On windows, consistent timing is not working properly due to bad timer resolution", Abort); +#endif + QVERIFY(animation.state() == QAbstractAnimation::Stopped); QVERIFY(animation2.state() == QAbstractAnimation::Running); QCOMPARE(animation.m_updateCurrentTimeCount, 2); QCOMPARE(animation2.m_updateCurrentTimeCount, 2); QTest::qWait(550); + +#ifdef Q_OS_WIN + if (animation2.state() != QAbstractAnimation::Stopped) + QEXPECT_FAIL("", "On windows, consistent timing is not working properly due to bad timer resolution", Abort); +#endif + QVERIFY(animation2.state() == QAbstractAnimation::Stopped); QCOMPARE(animation2.m_updateCurrentTimeCount, 3); - - timer->setConsistentTiming(false); } void tst_QPauseAnimation::pauseAndPropertyAnimations() @@ -243,7 +247,7 @@ void tst_QPauseAnimation::pauseResume() animation.pause(); QVERIFY(animation.state() == QAbstractAnimation::Paused); animation.start(); - QTest::qWait(250); + QTest::qWait(300); QVERIFY(animation.state() == QAbstractAnimation::Stopped); QCOMPARE(animation.m_updateCurrentTimeCount, 3); } @@ -260,6 +264,9 @@ void tst_QPauseAnimation::sequentialPauseGroup() animation3.setDuration(200); group.start(); + QCOMPARE(animation1.m_updateCurrentTimeCount, 1); + QCOMPARE(animation2.m_updateCurrentTimeCount, 0); + QCOMPARE(animation3.m_updateCurrentTimeCount, 0); QVERIFY(group.state() == QAbstractAnimation::Running); QVERIFY(animation1.state() == QAbstractAnimation::Running); @@ -267,6 +274,9 @@ void tst_QPauseAnimation::sequentialPauseGroup() QVERIFY(animation3.state() == QAbstractAnimation::Stopped); group.setCurrentTime(250); + QCOMPARE(animation1.m_updateCurrentTimeCount, 2); + QCOMPARE(animation2.m_updateCurrentTimeCount, 1); + QCOMPARE(animation3.m_updateCurrentTimeCount, 0); QVERIFY(group.state() == QAbstractAnimation::Running); QVERIFY(animation1.state() == QAbstractAnimation::Stopped); @@ -275,6 +285,9 @@ void tst_QPauseAnimation::sequentialPauseGroup() QVERIFY(animation3.state() == QAbstractAnimation::Stopped); group.setCurrentTime(500); + QCOMPARE(animation1.m_updateCurrentTimeCount, 2); + QCOMPARE(animation2.m_updateCurrentTimeCount, 2); + QCOMPARE(animation3.m_updateCurrentTimeCount, 1); QVERIFY(group.state() == QAbstractAnimation::Running); QVERIFY(animation1.state() == QAbstractAnimation::Stopped); diff --git a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp index aa6801a..f6afc5b 100644 --- a/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp +++ b/tests/auto/qsequentialanimationgroup/tst_qsequentialanimationgroup.cpp @@ -929,16 +929,13 @@ void tst_QSequentialAnimationGroup::startDelay() group.addPause(125); QCOMPARE(group.totalDuration(), 375); - QEventLoop loop; - QObject::connect(&group, SIGNAL(finished()), &loop, SLOT(quit())); - - QTime time; - time.start(); group.start(); - loop.exec(); + QCOMPARE(group.state(), QAnimationGroup::Running); - QVERIFY(time.elapsed() >= 375); - QVERIFY(time.elapsed() < 1000); + QTest::qWait(500); + + QVERIFY(group.currentTime() == 375); + QCOMPARE(group.state(), QAnimationGroup::Stopped); } void tst_QSequentialAnimationGroup::clearGroup() diff --git a/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp b/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp index 3131f35..02b48fa 100644 --- a/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp +++ b/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp @@ -96,6 +96,7 @@ private slots: void task_180617(); void task_180617_data() { generic_data(); } + void task_QTBUG_4963_setHeaderDataWithProxyModel(); private: void generic_data(const QString &engine=QString()); @@ -428,6 +429,8 @@ void tst_QSqlQueryModel::setHeaderData() QVERIFY(!model.setHeaderData(5, Qt::Vertical, "foo")); QVERIFY(model.headerData(5, Qt::Vertical).isValid()); + model.setQuery(QSqlQuery("select * from " + qTableName("test"), db)); + qRegisterMetaType<Qt::Orientation>("Qt::Orientation"); QSignalSpy spy(&model, SIGNAL(headerDataChanged(Qt::Orientation, int, int))); QVERIFY(model.setHeaderData(2, Qt::Horizontal, "bar")); @@ -437,10 +440,8 @@ void tst_QSqlQueryModel::setHeaderData() QCOMPARE(spy.value(0).value(1).toInt(), 2); QCOMPARE(spy.value(0).value(2).toInt(), 2); - QVERIFY(model.setHeaderData(7, Qt::Horizontal, "foo", Qt::ToolTipRole)); - QVERIFY(model.headerData(7, Qt::Horizontal, Qt::ToolTipRole).isValid()); - - model.setQuery(QSqlQuery("select * from " + qTableName("test"), db)); + QVERIFY(!model.setHeaderData(7, Qt::Horizontal, "foo", Qt::ToolTipRole)); + QVERIFY(!model.headerData(7, Qt::Horizontal, Qt::ToolTipRole).isValid()); bool isToUpper = db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2"); QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), isToUpper ? QString("ID") : QString("id")); @@ -603,5 +604,14 @@ void tst_QSqlQueryModel::task_180617() QCOMPARE(view.rowAt(0), -1); } +void tst_QSqlQueryModel::task_QTBUG_4963_setHeaderDataWithProxyModel() +{ + QSqlQueryModel plainModel; + QSortFilterProxyModel proxyModel; + proxyModel.setSourceModel(&plainModel); + QVERIFY(!plainModel.setHeaderData(0, Qt::Horizontal, QObject::tr("ID"))); + // And it should not crash. +} + QTEST_MAIN(tst_QSqlQueryModel) #include "tst_qsqlquerymodel.moc" diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index d8110e1..8f8781d 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -2017,8 +2017,9 @@ void tst_QTableView::resizeRowsToContents() view.resizeRowsToContents(); QCOMPARE(resizedSpy.count(), model.rowCount()); - for (int r = 0; r < model.rowCount(); ++r) + for (int r = 0; r < model.rowCount(); ++r) { QCOMPARE(view.rowHeight(r), rowHeight); + } } void tst_QTableView::resizeColumnsToContents_data() @@ -3267,12 +3268,12 @@ void tst_QTableView::resizeToContents() //now let's check the row/col sizes for(int i = 0;i<table.columnCount();i++) { - QVERIFY( table.columnWidth(i) == table2.columnWidth(i)); - QVERIFY( table2.columnWidth(i) == table3.columnWidth(i)); + QCOMPARE( table.columnWidth(i), table2.columnWidth(i)); + QCOMPARE( table2.columnWidth(i), table3.columnWidth(i)); } for(int i = 0;i<table.rowCount();i++) { - QVERIFY( table.rowHeight(i) == table2.rowHeight(i)); - QVERIFY( table2.rowHeight(i) == table3.rowHeight(i)); + QCOMPARE( table.rowHeight(i), table2.rowHeight(i)); + QCOMPARE( table2.rowHeight(i), table3.rowHeight(i)); } } diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index da58725..1429771 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -235,6 +235,7 @@ private slots: void task254234_proxySort(); void task248022_changeSelection(); void task245654_changeModelAndExpandAll(); + void doubleClickedWithSpans(); }; class QtTestModel: public QAbstractItemModel @@ -2891,7 +2892,8 @@ void tst_QTreeView::styleOptionViewItem() QVERIFY(!opt.text.isEmpty()); QCOMPARE(opt.index, index); - QCOMPARE(!(opt.features & QStyleOptionViewItemV2::Alternate), !(index.row() % 2)); + if (allCollapsed) + QCOMPARE(!(opt.features & QStyleOptionViewItemV2::Alternate), !(index.row() % 2)); QCOMPARE(!(opt.features & QStyleOptionViewItemV2::HasCheckIndicator), !opt.text.contains("Checkable")); if (opt.text.contains("Beginning")) @@ -2911,12 +2913,16 @@ void tst_QTreeView::styleOptionViewItem() else QCOMPARE(opt.checkState, Qt::Unchecked); + QCOMPARE(!(opt.state & QStyle::State_Children) , !opt.text.contains("HasChildren")); + QCOMPARE(!!(opt.state & QStyle::State_Sibling) , !opt.text.contains("Last")); + QVERIFY(!opt.text.contains("Assert")); QStyledItemDelegate::paint(painter, option, index); count++; } mutable int count; + bool allCollapsed; }; QTreeView view; @@ -2926,8 +2932,9 @@ void tst_QTreeView::styleOptionViewItem() view.setItemDelegate(&delegate); model.appendRow(QList<QStandardItem*>() << new QStandardItem("Beginning") << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + QStandardItem *par1 = new QStandardItem("Beginning HasChildren"); model.appendRow(QList<QStandardItem*>() - << new QStandardItem("Beginning") << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + << par1 << new QStandardItem("Middle HasChildren") << new QStandardItem("Middle HasChildren") << new QStandardItem("End HasChildren") ); model.appendRow(QList<QStandardItem*>() << new QStandardItem("OnlyOne") << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Assert") ); QStandardItem *checkable = new QStandardItem("Checkable"); @@ -2937,13 +2944,44 @@ void tst_QTreeView::styleOptionViewItem() checked->setCheckState(Qt::Checked); model.appendRow(QList<QStandardItem*>() << new QStandardItem("Beginning") << checkable << checked << new QStandardItem("End") ); + model.appendRow(QList<QStandardItem*>() + << new QStandardItem("Beginning Last") << new QStandardItem("Middle Last") << new QStandardItem("Middle Last") << new QStandardItem("End Last") ); + + par1->appendRow(QList<QStandardItem*>() + << new QStandardItem("Beginning") << new QStandardItem("Middle") << new QStandardItem("Middle") << new QStandardItem("End") ); + QStandardItem *par2 = new QStandardItem("Beginning HasChildren"); + par1->appendRow(QList<QStandardItem*>() + << par2 << new QStandardItem("Middle HasChildren") << new QStandardItem("Middle HasChildren") << new QStandardItem("End HasChildren") ); + par2->appendRow(QList<QStandardItem*>() + << new QStandardItem("Beginning Last") << new QStandardItem("Middle Last") << new QStandardItem("Middle Last") << new QStandardItem("End Last") ); + + QStandardItem *par3 = new QStandardItem("Beginning Last"); + par1->appendRow(QList<QStandardItem*>() + << par3 << new QStandardItem("Middle Last") << new QStandardItem("Middle Last") << new QStandardItem("End Last") ); + par3->appendRow(QList<QStandardItem*>() + << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Asser") ); + view.setRowHidden(0, par3->index(), true); + par1->appendRow(QList<QStandardItem*>() + << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Assert") << new QStandardItem("Asser") ); + view.setRowHidden(3, par1->index(), true); + view.setFirstColumnSpanned(2, QModelIndex(), true); view.setAlternatingRowColors(true); delegate.count = 0; + delegate.allCollapsed = true; view.showMaximized(); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 13); + delegate.count = 0; + delegate.allCollapsed = false; + view.expandAll(); + QApplication::processEvents(); QTRY_VERIFY(delegate.count >= 13); + view.collapse(par2->index()); + QApplication::processEvents(); + QTRY_VERIFY(delegate.count >= 4); } class task174627_TreeView : public QTreeView @@ -3507,7 +3545,34 @@ void tst_QTreeView::task245654_changeModelAndExpandAll() } +void tst_QTreeView::doubleClickedWithSpans() +{ + QTreeView view; + QStandardItemModel model(1, 2); + view.setModel(&model); + view.setFirstColumnSpanned(0, QModelIndex(), true); + view.show(); + + QPoint p(10, 10); + QCOMPARE(view.indexAt(p), model.index(0, 0)); + QSignalSpy spy(&view, SIGNAL(doubleClicked(QModelIndex))); + QTest::mousePress(view.viewport(), Qt::LeftButton, 0, p); + QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, p); + QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, p); + QCOMPARE(spy.count(), 1); + + //let's click on the 2nd column + p.setX(p.x() + view.header()->sectionSize(0)); + QCOMPARE(view.indexAt(p), model.index(0, 0)); + //end the previous edition + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, p); + QTest::qWait(100); + QTest::mousePress(view.viewport(), Qt::LeftButton, 0, p); + QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, p); + QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, p); + QCOMPARE(spy.count(), 2); +} QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" diff --git a/tests/auto/qvariant/tst_qvariant.cpp b/tests/auto/qvariant/tst_qvariant.cpp index 9295897..de4d7b4 100644 --- a/tests/auto/qvariant/tst_qvariant.cpp +++ b/tests/auto/qvariant/tst_qvariant.cpp @@ -318,6 +318,14 @@ void tst_QVariant::constructor() QVariant var6(qlonglong(0)); QCOMPARE(var6.type(), QVariant::LongLong); QCOMPARE(var6.typeName(), "qlonglong"); + + QVariant var7 = 5; + QVERIFY(var7.isValid()); + QVERIFY(!var7.isNull()); + QVariant var8; + var8.setValue<int>(5); + QVERIFY(var8.isValid()); + QVERIFY(!var8.isNull()); } void tst_QVariant::copy_constructor() |