diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/effects/qgraphicseffect.cpp | 63 | ||||
-rw-r--r-- | src/gui/effects/qgraphicseffect.h | 13 | ||||
-rw-r--r-- | src/gui/effects/qgraphicseffect_p.h | 11 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsanchorlayout.cpp | 185 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsanchorlayout.h | 73 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 168 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsanchorlayout_p.h | 66 | ||||
-rw-r--r-- | src/gui/image/qpixmapfilter.cpp | 51 | ||||
-rw-r--r-- | src/gui/image/qpixmapfilter_p.h | 3 | ||||
-rw-r--r-- | src/gui/itemviews/qlistview.cpp | 6 | ||||
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 18 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_p.h | 5 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_qws.cpp | 3 | ||||
-rw-r--r-- | src/gui/kernel/qkeymapper_x11.cpp | 2 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 12 | ||||
-rw-r--r-- | src/gui/painting/qpaintengineex.cpp | 9 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 3 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 3 | ||||
-rw-r--r-- | src/gui/text/qtextengine_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 3 | ||||
-rw-r--r-- | src/gui/widgets/qmenubar.cpp | 4 |
21 files changed, 482 insertions, 220 deletions
diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp index 683a984..26489c5 100644 --- a/src/gui/effects/qgraphicseffect.cpp +++ b/src/gui/effects/qgraphicseffect.cpp @@ -467,12 +467,44 @@ QGraphicsGrayscaleEffect::~QGraphicsGrayscaleEffect() { } + +/*! + \property QGraphicsGrayscaleEffect::strength + \brief the strength of the effect. + + By default, the strength is 1.0. + A strength 0.0 equals to no effect, while 1.0 means full grayscale. +*/ +qreal QGraphicsGrayscaleEffect::strength() const +{ + Q_D(const QGraphicsGrayscaleEffect); + return d->filter->strength(); +} + +void QGraphicsGrayscaleEffect::setStrength(qreal strength) +{ + Q_D(QGraphicsGrayscaleEffect); + if (qFuzzyCompare(d->filter->strength(), strength)) + return; + + d->filter->setStrength(strength); + d->opaque = !qFuzzyIsNull(strength); + update(); + emit strengthChanged(strength); +} + /*! \reimp */ void QGraphicsGrayscaleEffect::draw(QPainter *painter, QGraphicsEffectSource *source) { Q_D(QGraphicsGrayscaleEffect); + + if (!d->opaque) { + source->draw(painter); + return; + } + QPoint offset; if (source->isPixmap()) { // No point in drawing in device coordinates (pixmap will be scaled anyways). @@ -546,6 +578,31 @@ void QGraphicsColorizeEffect::setColor(const QColor &color) } /*! + \property QGraphicsColorizeEffect::strength + \brief the strength of the effect. + + By default, the strength is 1.0. + A strength 0.0 equals to no effect, while 1.0 means full colorization. +*/ +qreal QGraphicsColorizeEffect::strength() const +{ + Q_D(const QGraphicsColorizeEffect); + return d->filter->strength(); +} + +void QGraphicsColorizeEffect::setStrength(qreal strength) +{ + Q_D(QGraphicsColorizeEffect); + if (qFuzzyCompare(d->filter->strength(), strength)) + return; + + d->filter->setStrength(strength); + d->opaque = !qFuzzyIsNull(strength); + update(); + emit strengthChanged(strength); +} + +/*! \fn void QGraphicsColorizeEffect::colorChanged(const QColor &color) This signal is emitted whenever the effect's color changes. @@ -558,6 +615,12 @@ void QGraphicsColorizeEffect::setColor(const QColor &color) void QGraphicsColorizeEffect::draw(QPainter *painter, QGraphicsEffectSource *source) { Q_D(QGraphicsColorizeEffect); + + if (!d->opaque) { + source->draw(painter); + return; + } + QPoint offset; if (source->isPixmap()) { // No point in drawing in device coordinates (pixmap will be scaled anyways). diff --git a/src/gui/effects/qgraphicseffect.h b/src/gui/effects/qgraphicseffect.h index 5822d8c..5062826 100644 --- a/src/gui/effects/qgraphicseffect.h +++ b/src/gui/effects/qgraphicseffect.h @@ -144,13 +144,22 @@ class QGraphicsGrayscaleEffectPrivate; class Q_GUI_EXPORT QGraphicsGrayscaleEffect: public QGraphicsEffect { Q_OBJECT + Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) public: QGraphicsGrayscaleEffect(QObject *parent = 0); ~QGraphicsGrayscaleEffect(); + qreal strength() const; + protected: void draw(QPainter *painter, QGraphicsEffectSource *source); +public Q_SLOTS: + void setStrength(qreal strength); + +Q_SIGNALS: + void strengthChanged(qreal strength); + private: Q_DECLARE_PRIVATE(QGraphicsGrayscaleEffect) Q_DISABLE_COPY(QGraphicsGrayscaleEffect) @@ -161,17 +170,21 @@ class Q_GUI_EXPORT QGraphicsColorizeEffect: public QGraphicsEffect { Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) + Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) public: QGraphicsColorizeEffect(QObject *parent = 0); ~QGraphicsColorizeEffect(); QColor color() const; + qreal strength() const; public Q_SLOTS: void setColor(const QColor &c); + void setStrength(qreal strength); Q_SIGNALS: void colorChanged(const QColor &color); + void strengthChanged(qreal strength); protected: void draw(QPainter *painter, QGraphicsEffectSource *source); diff --git a/src/gui/effects/qgraphicseffect_p.h b/src/gui/effects/qgraphicseffect_p.h index 4771384..e109790 100644 --- a/src/gui/effects/qgraphicseffect_p.h +++ b/src/gui/effects/qgraphicseffect_p.h @@ -113,6 +113,7 @@ class QGraphicsGrayscaleEffectPrivate : public QGraphicsEffectPrivate Q_DECLARE_PUBLIC(QGraphicsGrayscaleEffect) public: QGraphicsGrayscaleEffectPrivate() + : opaque(true) { filter = new QPixmapColorizeFilter; filter->setColor(Qt::black); @@ -120,16 +121,24 @@ public: ~QGraphicsGrayscaleEffectPrivate() { delete filter; } QPixmapColorizeFilter *filter; + quint32 opaque : 1; + quint32 padding : 31; }; class QGraphicsColorizeEffectPrivate : public QGraphicsEffectPrivate { Q_DECLARE_PUBLIC(QGraphicsColorizeEffect) public: - QGraphicsColorizeEffectPrivate() { filter = new QPixmapColorizeFilter; } + QGraphicsColorizeEffectPrivate() + : opaque(true) + { + filter = new QPixmapColorizeFilter; + } ~QGraphicsColorizeEffectPrivate() { delete filter; } QPixmapColorizeFilter *filter; + quint32 opaque : 1; + quint32 padding : 31; }; class QGraphicsPixelizeEffectPrivate : public QGraphicsEffectPrivate diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index c7033c6..f57f65f 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -84,6 +84,55 @@ QT_BEGIN_NAMESPACE +QGraphicsAnchor::QGraphicsAnchor(QGraphicsAnchorLayout *parentLayout) + : QObject(*(new QGraphicsAnchorPrivate)) +{ + Q_D(QGraphicsAnchor); + Q_ASSERT(parentLayout); + d->layoutPrivate = parentLayout->d_func(); +} + +/*! + Removes the QGraphicsAnchor object from the layout and destroys it. +*/ +QGraphicsAnchor::~QGraphicsAnchor() +{ +} + +/*! + Set the spacing for the anchor to \a spacing. + + \sa spacing(), unsetSpacing() +*/ +void QGraphicsAnchor::setSpacing(qreal spacing) +{ + Q_D(QGraphicsAnchor); + d->setSpacing(spacing); +} + +/*! + Returns the spacing for the anchor + + \sa setSpacing() +*/ +qreal QGraphicsAnchor::spacing() const +{ + Q_D(const QGraphicsAnchor); + return d->spacing(); +} + +/*! + Resets the spacing of the anchor point to be the default spacing. Depending on the anchor type, + the default spacing is either 0 or a value returned from the style. + + \sa setSpacing(), spacing(), QGraphicsAnchorLayout::anchor() +*/ +void QGraphicsAnchor::unsetSpacing() +{ + Q_D(QGraphicsAnchor); + d->unsetSpacing(); +} + /*! Constructs a QGraphicsAnchorLayout instance. \a parent is passed to QGraphicsLayout's constructor. @@ -136,17 +185,30 @@ QGraphicsAnchorLayout::~QGraphicsAnchorLayout() * the default vertical spacing). For all other anchor combinations, the spacing will be 0. * All anchoring functions will follow this rule. * - * The spacing can also be set manually by using setAnchorSpacing() method. + * The spacing can also be set manually by using QGraphicsAnchor::setSpacing() method. * - * \sa removeAnchor(), addCornerAnchors(), addLeftAndRightAnchors(), addTopAndBottomAnchors(), - * addAllAnchors() + * \sa addCornerAnchors(), addAnchors() */ -void QGraphicsAnchorLayout::addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) +QGraphicsAnchor * +QGraphicsAnchorLayout::addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) { Q_D(QGraphicsAnchorLayout); - d->anchor(firstItem, firstEdge, secondItem, secondEdge); + QGraphicsAnchor *a = d->anchor(firstItem, firstEdge, secondItem, secondEdge); invalidate(); + return a; +} + +/*! + Returns the anchor between the anchor points defined by \a firstItem and \a firstEdge and + \a secondItem and \a secondEdge. If there is no such anchor, the function will return 0. +*/ +QGraphicsAnchor * +QGraphicsAnchorLayout::anchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) +{ + Q_D(QGraphicsAnchorLayout); + return d->getAnchor(firstItem, firstEdge, secondItem, secondEdge); } /*! @@ -195,6 +257,37 @@ void QGraphicsAnchorLayout::addCornerAnchors(QGraphicsLayoutItem *firstItem, } /*! + Anchors two or four edges of \a firstItem with the corresponding edges of \secondItem, + so that \a firstItem has the same size as \a secondItem in the dimensions specified by + \a orientation. + + Calling this convenience function with the following arguments + \code + l->addAnchors(firstItem, secondItem, Qt::Horizontal) + \endcode + + is the same as + + \code + l->addAnchor(firstItem, Qt::AnchorLeft, secondItem, Qt::AnchorLeft); + l->addAnchor(firstItem, Qt::AnchorRight, secondItem, Qt::AnchorRight); + \endcode +*/ +void QGraphicsAnchorLayout::addAnchors(QGraphicsLayoutItem *firstItem, + QGraphicsLayoutItem *secondItem, + Qt::Orientations orientations) +{ + if (orientations & Qt::Horizontal) { + addAnchor(secondItem, Qt::AnchorLeft, firstItem, Qt::AnchorLeft); + addAnchor(firstItem, Qt::AnchorRight, secondItem, Qt::AnchorRight); + } + if (orientations & Qt::Vertical) { + addAnchor(secondItem, Qt::AnchorTop, firstItem, Qt::AnchorTop); + addAnchor(firstItem, Qt::AnchorBottom, secondItem, Qt::AnchorBottom); + } +} + +/*! \fn QGraphicsAnchorLayout::addLeftAndRightAnchors(QGraphicsLayoutItem *firstItem, QGraphicsLayoutItem *secondItem) Anchors the left and right edges of \a firstItem to the same edges of @@ -234,86 +327,6 @@ void QGraphicsAnchorLayout::addCornerAnchors(QGraphicsLayoutItem *firstItem, */ /*! - Set the spacing between the anchor point defined by \a firstItem and \a firstEdge and - \a secondItem and \a secondEdge to be \a spacing. -*/ -void QGraphicsAnchorLayout::setAnchorSpacing(const QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge, - qreal spacing) -{ - Q_D(QGraphicsAnchorLayout); - - if (!d->setAnchorSize(firstItem, firstEdge, secondItem, secondEdge, &spacing)) { - qWarning("setAnchorSpacing: The anchor does not exist."); - return; - } - invalidate(); -} - -/*! - Returns the spacing between the anchor point defined by \a firstItem and \a firstEdge and - \a secondItem and \a secondEdge. The anchor must exist. -*/ -qreal QGraphicsAnchorLayout::anchorSpacing(const QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) const -{ - Q_D(const QGraphicsAnchorLayout); - qreal size = 0; - if (!d->anchorSize(firstItem, firstEdge, secondItem, secondEdge, 0, &size)) { - qWarning("anchorSpacing: The anchor does not exist."); - } - return size; -} - -/*! - Resets the spacing between the anchor point defined by \a firstItem and \a firstEdge and - \a secondItem and \a secondEdge to be the default spacing. Depending on the anchor type, the - default spacing is either 0 or a value returned from the style. - - \sa setAnchorSpacing(), anchorSpacing(), addAnchor() -*/ -void QGraphicsAnchorLayout::unsetAnchorSpacing(const QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) -{ - Q_D(QGraphicsAnchorLayout); - - if (!d->setAnchorSize(firstItem, firstEdge, secondItem, secondEdge, 0)) { - qWarning("unsetAnchorSpacing: The anchor does not exist."); - } - invalidate(); -} - -/*! - Removes the anchor between the edge \a firstEdge of item \a firstItem and the edge \a secondEdge - of item \a secondItem. If such an anchor does not exist, the layout will be left unchanged. -*/ -void QGraphicsAnchorLayout::removeAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) -{ - Q_D(QGraphicsAnchorLayout); - if ((firstItem == 0) || (secondItem == 0)) { - qWarning("QGraphicsAnchorLayout::removeAnchor: " - "Cannot remove anchor between NULL items"); - return; - } - - if (firstItem == secondItem) { - qWarning("QGraphicsAnchorLayout::removeAnchor: " - "Cannot remove anchor from the item to itself"); - return; - } - - if (d->edgeOrientation(secondEdge) != d->edgeOrientation(firstEdge)) { - qWarning("QGraphicsAnchorLayout::removeAnchor: " - "Cannot remove anchor from edges of different orientations"); - return; - } - - d->removeAnchor(firstItem, firstEdge, secondItem, secondEdge); - invalidate(); -} - -/*! Sets the default horizontal spacing for the anchor layout to \a spacing. \sa horizontalSpacing(), setVerticalSpacing(), setSpacing() diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.h b/src/gui/graphicsview/qgraphicsanchorlayout.h index 70b73ef..d9a87ba 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout.h @@ -54,41 +54,44 @@ QT_MODULE(Gui) #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW +class QGraphicsAnchorPrivate; +class QGraphicsAnchorLayout; class QGraphicsAnchorLayoutPrivate; +class Q_GUI_EXPORT QGraphicsAnchor : public QObject +{ + Q_OBJECT + Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing) +public: + void setSpacing(qreal spacing); + void unsetSpacing(); + qreal spacing() const; + ~QGraphicsAnchor(); +private: + QGraphicsAnchor(QGraphicsAnchorLayout *parent); + + Q_DECLARE_PRIVATE(QGraphicsAnchor) + + friend class QGraphicsAnchorLayoutPrivate; +}; + class Q_GUI_EXPORT QGraphicsAnchorLayout : public QGraphicsLayout { public: QGraphicsAnchorLayout(QGraphicsLayoutItem *parent = 0); virtual ~QGraphicsAnchorLayout(); - void addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); + QGraphicsAnchor *addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); + QGraphicsAnchor *anchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); void addCornerAnchors(QGraphicsLayoutItem *firstItem, Qt::Corner firstCorner, QGraphicsLayoutItem *secondItem, Qt::Corner secondCorner); - inline void addLeftAndRightAnchors(QGraphicsLayoutItem *firstItem, - QGraphicsLayoutItem *secondItem); - - inline void addTopAndBottomAnchors(QGraphicsLayoutItem *firstItem, - QGraphicsLayoutItem *secondItem); - - inline void addAllAnchors(QGraphicsLayoutItem *firstItem, - QGraphicsLayoutItem *secondItem); - - void setAnchorSpacing(const QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge, - qreal spacing); - - qreal anchorSpacing(const QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) const; - - void unsetAnchorSpacing(const QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); - - void removeAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, - QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); + void addAnchors(QGraphicsLayoutItem *firstItem, + QGraphicsLayoutItem *secondItem, + Qt::Orientations orientations = Qt::Horizontal | Qt::Vertical); void setHorizontalSpacing(qreal spacing); void setVerticalSpacing(qreal spacing); @@ -108,29 +111,9 @@ protected: private: Q_DISABLE_COPY(QGraphicsAnchorLayout) Q_DECLARE_PRIVATE(QGraphicsAnchorLayout) -}; - -void QGraphicsAnchorLayout::addLeftAndRightAnchors(QGraphicsLayoutItem *firstItem, - QGraphicsLayoutItem *secondItem) -{ - addAnchor(secondItem, Qt::AnchorLeft, firstItem, Qt::AnchorLeft); - addAnchor(firstItem, Qt::AnchorRight, secondItem, Qt::AnchorRight); -} - -void QGraphicsAnchorLayout::addTopAndBottomAnchors(QGraphicsLayoutItem *firstItem, - QGraphicsLayoutItem *secondItem) -{ - addAnchor(secondItem, Qt::AnchorTop, firstItem, Qt::AnchorTop); - addAnchor(firstItem, Qt::AnchorBottom, secondItem, Qt::AnchorBottom); -} - -void QGraphicsAnchorLayout::addAllAnchors(QGraphicsLayoutItem *firstItem, - QGraphicsLayoutItem *secondItem) -{ - addLeftAndRightAnchors(firstItem, secondItem); - addTopAndBottomAnchors(firstItem, secondItem); -} + friend class QGraphicsAnchor; +}; #endif diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index f81ede0..a37ec96 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -51,6 +51,47 @@ QT_BEGIN_NAMESPACE + +QGraphicsAnchorPrivate::QGraphicsAnchorPrivate(int version) + : QObjectPrivate(version), layoutPrivate(0), data(0) +{ +} + +QGraphicsAnchorPrivate::~QGraphicsAnchorPrivate() +{ + layoutPrivate->deleteAnchorData(data); +} + +void QGraphicsAnchorPrivate::setSpacing(qreal value) +{ + if (data) { + layoutPrivate->setAnchorSize(data, &value); + } else { + qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist."); + } +} + +void QGraphicsAnchorPrivate::unsetSpacing() +{ + if (data) { + layoutPrivate->setAnchorSize(data, 0); + } else { + qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist."); + } +} + +qreal QGraphicsAnchorPrivate::spacing() const +{ + qreal size = 0; + if (data) { + layoutPrivate->anchorSize(data, 0, &size, 0); + } else { + qWarning("QGraphicsAnchor::setSpacing: The anchor does not exist."); + } + return size; +} + + void AnchorData::refreshSizeHints(qreal effectiveSpacing) { if (!isLayoutAnchor && from->m_item == to->m_item) { @@ -998,29 +1039,29 @@ void QGraphicsAnchorLayoutPrivate::removeCenterConstraints(QGraphicsLayoutItem * * Helper function that is called from the anchor functions in the public API. * If \a spacing is 0, it will pick up the spacing defined by the style. */ -void QGraphicsAnchorLayoutPrivate::anchor(QGraphicsLayoutItem *firstItem, - Qt::AnchorPoint firstEdge, - QGraphicsLayoutItem *secondItem, - Qt::AnchorPoint secondEdge, - qreal *spacing) +QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::anchor(QGraphicsLayoutItem *firstItem, + Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, + Qt::AnchorPoint secondEdge, + qreal *spacing) { Q_Q(QGraphicsAnchorLayout); if ((firstItem == 0) || (secondItem == 0)) { qWarning("QGraphicsAnchorLayout::addAnchor(): " "Cannot anchor NULL items"); - return; + return 0; } if (firstItem == secondItem) { qWarning("QGraphicsAnchorLayout::addAnchor(): " "Cannot anchor the item to itself"); - return; + return 0; } if (edgeOrientation(secondEdge) != edgeOrientation(firstEdge)) { qWarning("QGraphicsAnchorLayout::addAnchor(): " "Cannot anchor edges of different orientations"); - return; + return 0; } // Guarantee that the graph is no simplified when adding this anchor, @@ -1079,6 +1120,7 @@ void QGraphicsAnchorLayoutPrivate::anchor(QGraphicsLayoutItem *firstItem, data = new AnchorData(-*spacing); addAnchor(secondItem, secondEdge, firstItem, firstEdge, data); } + return acquireGraphicsAnchor(data); } void QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem, @@ -1117,77 +1159,97 @@ void QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem, graph[edgeOrientation(firstEdge)].createEdge(v1, v2, data); } +QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *firstItem, + Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, + Qt::AnchorPoint secondEdge) +{ + Orientation orient = edgeOrientation(firstEdge); + restoreSimplifiedGraph(orient); + + AnchorVertex *v1 = internalVertex(firstItem, firstEdge); + AnchorVertex *v2 = internalVertex(secondItem, secondEdge); + + QGraphicsAnchor *graphicsAnchor = 0; + + AnchorData *data = graph[orient].edgeData(v1, v2); + if (data) + graphicsAnchor = acquireGraphicsAnchor(data); + return graphicsAnchor; +} + void QGraphicsAnchorLayoutPrivate::removeAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) { - // Guarantee that the graph is no simplified when adding this anchor, - // anchor manipulation always happen in the full graph - restoreSimplifiedGraph(edgeOrientation(firstEdge)); - - // Look for both vertices - AnchorVertex *v1 = internalVertex(firstItem, firstEdge); - AnchorVertex *v2 = internalVertex(secondItem, secondEdge); + removeAnchor_helper(internalVertex(firstItem, firstEdge), + internalVertex(secondItem, secondEdge)); +} +void QGraphicsAnchorLayoutPrivate::removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2) +{ Q_ASSERT(v1 && v2); + // Guarantee that the graph is no simplified when removing this anchor, + // anchor manipulation always happen in the full graph + Orientation o = edgeOrientation(v1->m_edge); + restoreSimplifiedGraph(o); // Remove edge from graph - graph[edgeOrientation(firstEdge)].removeEdge(v1, v2); + graph[o].removeEdge(v1, v2); // Decrease vertices reference count (may trigger a deletion) - removeInternalVertex(firstItem, firstEdge); - removeInternalVertex(secondItem, secondEdge); + removeInternalVertex(v1->m_item, v1->m_edge); + removeInternalVertex(v2->m_item, v2->m_edge); } -bool QGraphicsAnchorLayoutPrivate::setAnchorSize(const QGraphicsLayoutItem *firstItem, - Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, - Qt::AnchorPoint secondEdge, - const qreal *anchorSize) +/*! + \internal + Only called from outside. (calls invalidate()) +*/ +void QGraphicsAnchorLayoutPrivate::deleteAnchorData(AnchorData *data) { + Q_Q(QGraphicsAnchorLayout); + removeAnchor_helper(data->from, data->to); + q->invalidate(); +} + +/*! + \internal + Only called from outside. (calls invalidate()) +*/ +void QGraphicsAnchorLayoutPrivate::setAnchorSize(AnchorData *data, const qreal *anchorSize) +{ + Q_Q(QGraphicsAnchorLayout); // ### we can avoid restoration if we really want to, but we would have to // search recursively through all composite anchors - restoreSimplifiedGraph(edgeOrientation(firstEdge)); - AnchorVertex *v1 = internalVertex(firstItem, firstEdge); - AnchorVertex *v2 = internalVertex(secondItem, secondEdge); - - AnchorData *data = graph[edgeOrientation(firstEdge)].edgeData(v1, v2); - if (data) { - if (anchorSize) { - data->setFixedSize(*anchorSize); - } else { - data->unsetSize(); - } + Q_ASSERT(data); + restoreSimplifiedGraph(edgeOrientation(data->from->m_edge)); + if (anchorSize) { + data->setFixedSize(*anchorSize); + } else { + data->unsetSize(); } - return data; + q->invalidate(); } -bool QGraphicsAnchorLayoutPrivate::anchorSize(const QGraphicsLayoutItem *firstItem, - Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, - Qt::AnchorPoint secondEdge, +void QGraphicsAnchorLayoutPrivate::anchorSize(const AnchorData *data, qreal *minSize, qreal *prefSize, qreal *maxSize) const { Q_ASSERT(minSize || prefSize || maxSize); + Q_ASSERT(data); QGraphicsAnchorLayoutPrivate *that = const_cast<QGraphicsAnchorLayoutPrivate *>(this); - that->restoreSimplifiedGraph(edgeOrientation(firstEdge)); - AnchorVertex *v1 = internalVertex(firstItem, firstEdge); - AnchorVertex *v2 = internalVertex(secondItem, secondEdge); - - AnchorData *data = that->graph[edgeOrientation(firstEdge)].edgeData(v1, v2); - if (data) { - if (minSize) - *minSize = data->minSize; - if (prefSize) - *prefSize = data->prefSize; - if (maxSize) - *maxSize = data->maxSize; - } - return data; + that->restoreSimplifiedGraph(edgeOrientation(data->from->m_edge)); + + if (minSize) + *minSize = data->minSize; + if (prefSize) + *prefSize = data->prefSize; + if (maxSize) + *maxSize = data->maxSize; } AnchorVertex *QGraphicsAnchorLayoutPrivate::addInternalVertex(QGraphicsLayoutItem *item, diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 31da1a1..f701c3f 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -54,6 +54,7 @@ // #include <QGraphicsWidget> +#include <private/qobject_p.h> #include "qgraphicslayout_p.h" #include "qgraphicsanchorlayout.h" @@ -153,6 +154,7 @@ struct AnchorData : public QSimplexVariable { minSize(minimumSize), prefSize(preferredSize), maxSize(maximumSize), sizeAtMinimum(preferredSize), sizeAtPreferred(preferredSize), sizeAtMaximum(preferredSize), + graphicsAnchor(0), skipInPreferred(0), type(Normal), hasSize(true), isLayoutAnchor(false) {} @@ -160,6 +162,7 @@ struct AnchorData : public QSimplexVariable { : QSimplexVariable(), from(0), to(0), minSize(size), prefSize(size), maxSize(size), sizeAtMinimum(size), sizeAtPreferred(size), sizeAtMaximum(size), + graphicsAnchor(0), skipInPreferred(0), type(Normal), hasSize(true), isLayoutAnchor(false) {} @@ -167,6 +170,7 @@ struct AnchorData : public QSimplexVariable { : QSimplexVariable(), from(0), to(0), minSize(0), prefSize(0), maxSize(0), sizeAtMinimum(0), sizeAtPreferred(0), sizeAtMaximum(0), + graphicsAnchor(0), skipInPreferred(0), type(Normal), hasSize(false), isLayoutAnchor(false) {} @@ -215,6 +219,7 @@ struct AnchorData : public QSimplexVariable { qreal sizeAtMinimum; qreal sizeAtPreferred; qreal sizeAtMaximum; + QGraphicsAnchor *graphicsAnchor; uint skipInPreferred : 1; uint type : 2; // either Normal, Sequential or Parallel @@ -226,6 +231,7 @@ protected: minSize(size), prefSize(size), maxSize(size), sizeAtMinimum(size), sizeAtPreferred(size), sizeAtMaximum(size), + graphicsAnchor(0), skipInPreferred(0), type(type), hasSize(true), isLayoutAnchor(false) {} }; @@ -309,6 +315,28 @@ public: QSet<AnchorData *> negatives; }; +class QGraphicsAnchorLayoutPrivate; +/*! + \internal +*/ +class QGraphicsAnchorPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QGraphicsAnchor) + +public: + explicit QGraphicsAnchorPrivate(int version = QObjectPrivateVersion); + ~QGraphicsAnchorPrivate(); + + void setSpacing(qreal value); + void unsetSpacing(); + qreal spacing() const; + + QGraphicsAnchorLayoutPrivate *layoutPrivate; + AnchorData *data; +}; + + + /*! \internal @@ -365,12 +393,22 @@ public: void removeCenterAnchors(QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge, bool substitute = true); void removeCenterConstraints(QGraphicsLayoutItem *item, Orientation orientation); + QGraphicsAnchor *acquireGraphicsAnchor(AnchorData *data) + { + Q_Q(QGraphicsAnchorLayout); + if (!data->graphicsAnchor) { + data->graphicsAnchor = new QGraphicsAnchor(q); + data->graphicsAnchor->d_func()->data = data; + } + return data->graphicsAnchor; + } + // helper function used by the 4 API functions - void anchor(QGraphicsLayoutItem *firstItem, - Qt::AnchorPoint firstEdge, - QGraphicsLayoutItem *secondItem, - Qt::AnchorPoint secondEdge, - qreal *spacing = 0); + QGraphicsAnchor *anchor(QGraphicsLayoutItem *firstItem, + Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, + Qt::AnchorPoint secondEdge, + qreal *spacing = 0); // Anchor Manipulation methods void addAnchor(QGraphicsLayoutItem *firstItem, @@ -379,21 +417,17 @@ public: Qt::AnchorPoint secondEdge, AnchorData *data); + QGraphicsAnchor *getAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, + QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); + void removeAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge); - - bool setAnchorSize(const QGraphicsLayoutItem *firstItem, - Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, - Qt::AnchorPoint secondEdge, - const qreal *anchorSize); - - bool anchorSize(const QGraphicsLayoutItem *firstItem, - Qt::AnchorPoint firstEdge, - const QGraphicsLayoutItem *secondItem, - Qt::AnchorPoint secondEdge, + void removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2); + void deleteAnchorData(AnchorData *data); + void setAnchorSize(AnchorData *data, const qreal *anchorSize); + void anchorSize(const AnchorData *data, qreal *minSize = 0, qreal *prefSize = 0, qreal *maxSize = 0) const; diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index 15704ba..4fa2e6c 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -759,6 +759,10 @@ class QPixmapColorizeFilterPrivate : public QPixmapFilterPrivate Q_DECLARE_PUBLIC(QPixmapColorizeFilter) public: QColor color; + qreal strength; + quint32 opaque : 1; + quint32 alphaBlend : 1; + quint32 padding : 30; }; /*! @@ -771,7 +775,11 @@ public: QPixmapColorizeFilter::QPixmapColorizeFilter(QObject *parent) : QPixmapFilter(*new QPixmapColorizeFilterPrivate, ColorizeFilter, parent) { - d_func()->color = QColor(0, 0, 192); + Q_D(QPixmapColorizeFilter); + d->color = QColor(0, 0, 192); + d->strength = qreal(1); + d->opaque = true; + d->alphaBlend = false; } /*! @@ -797,6 +805,31 @@ void QPixmapColorizeFilter::setColor(const QColor &color) } /*! + Gets the strength of the colorize filter, 1.0 means full colorized while + 0.0 equals to no filtering at all. + + \internal +*/ +qreal QPixmapColorizeFilter::strength() const +{ + Q_D(const QPixmapColorizeFilter); + return d->strength; +} + +/*! + Sets the strength of the colorize filter to \a strength. + + \internal +*/ +void QPixmapColorizeFilter::setStrength(qreal strength) +{ + Q_D(QPixmapColorizeFilter); + d->strength = qBound(qreal(0), strength, qreal(1)); + d->opaque = !qFuzzyIsNull(d->strength); + d->alphaBlend = !qFuzzyIsNull(d->strength - 1); +} + +/*! \internal */ void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const @@ -807,6 +840,7 @@ void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const Q QPixmapColorizeFilter *colorizeFilter = static_cast<QPixmapColorizeFilter*>(filter); if (colorizeFilter) { colorizeFilter->setColor(d->color); + colorizeFilter->setStrength(d->strength); colorizeFilter->draw(painter, dest, src, srcRect); delete colorizeFilter; return; @@ -814,6 +848,11 @@ void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const Q // falling back to raster implementation + if (!d->opaque) { + painter->drawPixmap(dest, src, srcRect); + return; + } + QImage srcImage; QImage destImage; @@ -836,6 +875,16 @@ void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const Q destPainter.fillRect(srcImage.rect(), d->color); destPainter.end(); + if (d->alphaBlend) { + // alpha blending srcImage and destImage + QImage buffer = srcImage; + QPainter bufPainter(&buffer); + bufPainter.setOpacity(d->strength); + bufPainter.drawImage(0, 0, destImage); + bufPainter.end(); + destImage = buffer; + } + if (srcImage.hasAlphaChannel()) destImage.setAlphaChannel(srcImage.alphaChannel()); diff --git a/src/gui/image/qpixmapfilter_p.h b/src/gui/image/qpixmapfilter_p.h index 4cbf7a3..2565110 100644 --- a/src/gui/image/qpixmapfilter_p.h +++ b/src/gui/image/qpixmapfilter_p.h @@ -155,6 +155,9 @@ public: void setColor(const QColor& color); QColor color() const; + void setStrength(qreal strength); + qreal strength() const; + void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const; }; diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index cbb54d8..a4cebe3 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -965,6 +965,12 @@ void QListView::paintEvent(QPaintEvent *e) for (QVector<QModelIndex>::const_iterator it = toBeRendered.constBegin(); it != end; ++it) { Q_ASSERT((*it).isValid()); option.rect = visualRect(*it); + + if (flow() == TopToBottom) + option.rect.setWidth(qMin(viewport()->size().width(), option.rect.width())); + else + option.rect.setHeight(qMin(viewport()->size().height(), option.rect.height())); + option.state = state; if (selections && selections->isSelected(*it)) option.state |= QStyle::State_Selected; diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 300e519..a19e022 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -469,12 +469,18 @@ QWidget *QApplicationPrivate::oldEditFocus = 0; bool qt_tabletChokeMouse = false; static bool force_reverse = false; -static inline bool isAlien(QWidget *widget) +inline bool QApplicationPrivate::isAlien(QWidget *widget) { if (!widget) return false; -#ifdef Q_WS_MAC // Fake alien behavior on the Mac :) +#if defined(Q_WS_MAC) // Fake alien behavior on the Mac :) return !widget->isWindow() && widget->window()->testAttribute(Qt::WA_DontShowOnScreen); +#elif defined(Q_WS_QWS) + return !widget->isWindow() +# ifdef Q_BACKINGSTORE_SUBSURFACES + && !(widget->d_func()->maybeTopData() && widget->d_func()->maybeTopData()->windowSurface) +# endif + ; #else return !widget->internalWinId(); #endif @@ -2974,7 +2980,7 @@ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event, return result; } -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) /* This function should only be called when the widget changes visibility, i.e. when the \a widget is shown, hidden or deleted. This function does nothing @@ -2986,9 +2992,13 @@ extern QWidget *qt_button_down; void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget) { #ifndef QT_NO_CURSOR +#ifdef Q_WS_QWS + if (!widget || widget->isWindow()) + return; +#else if (!widget || widget->internalWinId() || widget->isWindow()) return; - +#endif const bool widgetInShow = widget->isVisible() && !widget->data->in_destructor; if (!widgetInShow && widget != qt_last_mouse_receiver) return; // Widget was not under the cursor when it was hidden/deleted. diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index c027763..c33eb1a 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -513,7 +513,7 @@ public: #ifdef Q_OS_SYMBIAN static TUint resolveS60ScanCode(TInt scanCode, TUint keysym); #endif -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) void sendSyntheticEnterLeave(QWidget *widget); #endif @@ -586,6 +586,9 @@ private: Qt::FocusPolicy focusPolicy, Qt::FocusReason focusReason); static bool shouldSetFocus(QWidget *w, Qt::FocusPolicy policy); + + + static bool isAlien(QWidget *); }; Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window, diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp index e6bfd28..e9284f7 100644 --- a/src/gui/kernel/qapplication_qws.cpp +++ b/src/gui/kernel/qapplication_qws.cpp @@ -430,6 +430,7 @@ static QWidget *popupOfPopupButtonFocus = 0; static bool popupCloseDownMode = false; static bool popupGrabOk; static QPointer<QWidget> *mouseInWidget = 0; +QPointer<QWidget> qt_last_mouse_receiver = 0; static bool sm_blockUserInput = false; // session management @@ -3523,10 +3524,12 @@ bool QETWidget::translateMouseEvent(const QWSMouseEvent *event, int prevstate) if (widget != (*mouseInWidget)) { QApplicationPrivate::dispatchEnterLeave(widget, *mouseInWidget); (*mouseInWidget) = widget; + qt_last_mouse_receiver = widget; } QApplication::sendSpontaneousEvent(widget, &e); if (leaveAfterRelease && !QWidget::mouseGrabber()) { *mouseInWidget = QApplication::widgetAt(globalPos); + qt_last_mouse_receiver = *mouseInWidget; QApplicationPrivate::dispatchEnterLeave(*mouseInWidget, leaveAfterRelease); leaveAfterRelease = 0; } diff --git a/src/gui/kernel/qkeymapper_x11.cpp b/src/gui/kernel/qkeymapper_x11.cpp index 488cc6a..0ce77fe 100644 --- a/src/gui/kernel/qkeymapper_x11.cpp +++ b/src/gui/kernel/qkeymapper_x11.cpp @@ -536,7 +536,7 @@ void QKeyMapperPrivate::clearMappings() coreDesc.keysyms_per_keycode = 0; coreDesc.keysyms = XGetKeyboardMapping(X11->display, coreDesc.min_keycode, - coreDesc.max_keycode - coreDesc.min_keycode, + coreDesc.max_keycode - coreDesc.min_keycode + 1, &coreDesc.keysyms_per_keycode); #if 0 diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index fd44d78..fd89cb9 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1442,9 +1442,13 @@ QWidget::~QWidget() } } -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) else if (!internalWinId() && isVisible()) { qApp->d_func()->sendSyntheticEnterLeave(this); +#ifdef Q_WS_QWS + } else if (isVisible()) { + qApp->d_func()->sendSyntheticEnterLeave(this); +#endif } #endif @@ -7181,7 +7185,7 @@ void QWidgetPrivate::hide_helper() // next bit tries to move the focus if the focus widget is now // hidden. if (wasVisible) { -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) qApp->d_func()->sendSyntheticEnterLeave(q); #endif @@ -7313,7 +7317,7 @@ void QWidget::setVisible(bool visible) d->show_helper(); -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) qApp->d_func()->sendSyntheticEnterLeave(this); #endif } @@ -7428,7 +7432,7 @@ void QWidgetPrivate::hideChildren(bool spontaneous) widget->d_func()->hide_sys(); } } -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) qApp->d_func()->sendSyntheticEnterLeave(widget); #endif #ifndef QT_NO_ACCESSIBILITY diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index e75240c..656f383 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -535,8 +535,13 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) void QPaintEngineEx::draw(const QVectorPath &path) { - fill(path, state()->brush); - stroke(path, state()->pen); + const QBrush &brush = state()->brush; + if (qbrush_style(brush) != Qt::NoBrush) + fill(path, brush); + + const QPen &pen = state()->pen; + if (qpen_style(pen) != Qt::NoPen && qbrush_style(qpen_brush(pen)) != Qt::NoBrush) + stroke(path, pen); } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index a9257c7..beda9d6 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -475,7 +475,8 @@ void QPainterPrivate::draw_helper(const QPainterPath &originalPath, DrawOperatio p.end(); q->save(); - q->resetMatrix(); + state->matrix = QTransform(); + state->dirtyFlags |= QPaintEngine::DirtyTransform; updateState(state); engine->drawImage(absPathRect, image, diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 88837ca..b43bd06 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1645,7 +1645,8 @@ glyph_metrics_t QTextEngine::boundingBox(int from, int len) const glyph_t glyph = glyphs.glyphs[logClusters[pos + ilen - 1]]; glyph_metrics_t gi = fe->boundingBox(glyph); - gm.width -= qRound(gi.xoff - gi.x - gi.width); + if (gi.isValid()) + gm.width -= qRound(gi.xoff - gi.x - gi.width); } } return gm; diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 28ac7d9..85c6928 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -110,6 +110,7 @@ struct glyph_metrics_t QFixed yoff; glyph_metrics_t transformed(const QTransform &xform) const; + inline bool isValid() const {return x != 100000 && y != 100000;} }; Q_DECLARE_TYPEINFO(glyph_metrics_t, Q_PRIMITIVE_TYPE); diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 62795f8..f8b0cbc 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1807,7 +1807,8 @@ void QTextLine::layout_helper(int maxGlyphs) QFontEngine *fontEngine = eng->fontEngine(current); glyph_t glyph = glyphs.glyphs[logClusters[pos - 1]]; glyph_metrics_t gi = fontEngine->boundingBox(glyph); - lbh.rightBearing = -qRound(gi.xoff - gi.x - gi.width); + if (gi.isValid()) + lbh.rightBearing = -qRound(gi.xoff - gi.x - gi.width); } if ((sb_or_ws|breakany) && lbh.checkFullOtherwiseExtend(line)) { diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index d5a7982..8591a77 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -1252,9 +1252,7 @@ void QMenuBar::keyPressEvent(QKeyEvent *e) void QMenuBar::mouseMoveEvent(QMouseEvent *e) { Q_D(QMenuBar); - bool popupState = d->popupState || e->buttons() & Qt::LeftButton; - if (!d->mouseDown || !popupState) - return; + bool popupState = d->popupState || d->mouseDown; QAction *action = d->actionAt(e->pos()); if (action && d->isVisible(action)) d->setCurrentAction(action, popupState); |