From 1f00130097f81bc78aebb3c055f38c066221bc98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Tue, 13 Apr 2010 16:24:34 +0200 Subject: Revert "Revert "Implement heightForWidth support for QTabWidget and QStackedLayout."" This reverts commit 42fc3d36260c409918431c1fc058ee2d10f6c147. --- src/gui/kernel/qlayoutitem.cpp | 4 +-- src/gui/kernel/qstackedlayout.cpp | 26 +++++++++++++++++ src/gui/kernel/qstackedlayout.h | 2 ++ src/gui/kernel/qwidget.cpp | 17 +++++++++++ src/gui/kernel/qwidget.h | 1 + src/gui/kernel/qwidget_p.h | 1 + src/gui/widgets/qsizegrip.cpp | 17 +++-------- src/gui/widgets/qtabwidget.cpp | 49 ++++++++++++++++++++++++++++++++ src/gui/widgets/qtabwidget.h | 1 + tests/auto/qtabwidget/tst_qtabwidget.cpp | 47 ++++++++++++++++++++++++++++++ 10 files changed, 149 insertions(+), 16 deletions(-) diff --git a/src/gui/kernel/qlayoutitem.cpp b/src/gui/kernel/qlayoutitem.cpp index 6a91d95..e615b2d 100644 --- a/src/gui/kernel/qlayoutitem.cpp +++ b/src/gui/kernel/qlayoutitem.cpp @@ -516,9 +516,7 @@ bool QWidgetItem::hasHeightForWidth() const { if (isEmpty()) return false; - if (wid->layout()) - return wid->layout()->hasHeightForWidth(); - return wid->sizePolicy().hasHeightForWidth(); + return wid->hasHeightForWidth(); } /*! diff --git a/src/gui/kernel/qstackedlayout.cpp b/src/gui/kernel/qstackedlayout.cpp index 7559066..4b49638 100644 --- a/src/gui/kernel/qstackedlayout.cpp +++ b/src/gui/kernel/qstackedlayout.cpp @@ -475,6 +475,32 @@ void QStackedLayout::setGeometry(const QRect &rect) } } +bool QStackedLayout::hasHeightForWidth() const +{ + const int n = count(); + + for (int i = 0; i < n; ++i) { + if (QLayoutItem *item = itemAt(i)) { + if (item->hasHeightForWidth()) + return true; + } + } + return false; +} + +int QStackedLayout::heightForWidth(int width) const +{ + const int n = count(); + + int hfw = 0; + for (int i = 0; i < n; ++i) { + if (QLayoutItem *item = itemAt(i)) { + hfw = qMax(hfw, item->heightForWidth(width)); + } + } + return hfw; +} + /*! \enum QStackedLayout::StackingMode \since 4.4 diff --git a/src/gui/kernel/qstackedlayout.h b/src/gui/kernel/qstackedlayout.h index c069149..842b62b 100644 --- a/src/gui/kernel/qstackedlayout.h +++ b/src/gui/kernel/qstackedlayout.h @@ -95,6 +95,8 @@ public: QLayoutItem *itemAt(int) const; QLayoutItem *takeAt(int); void setGeometry(const QRect &rect); + bool hasHeightForWidth() const; + int heightForWidth(int width) const; Q_SIGNALS: void widgetRemoved(int index); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 4fba8cf..b19f7aa 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -3820,6 +3820,11 @@ void QWidget::setMaximumSize(int maxw, int maxh) d->updateGeometry_helper(d->extra->minw == d->extra->maxw && d->extra->minh == d->extra->maxh); } +bool QWidgetPrivate::hasHeightForWidth() const +{ + return layout ? layout->hasHeightForWidth() : size_policy.hasHeightForWidth(); +} + /*! \overload @@ -7965,6 +7970,18 @@ QSize QWidget::minimumSizeHint() const return QSize(-1, -1); } +/*! + \internal + This is a bit hackish, but ideally this would have been a virtual + function so that subclasses could reimplement their own function. + Instead we add a virtual function to QWidgetPrivate. +*/ +bool QWidget::hasHeightForWidth() const +{ + Q_D(const QWidget); + return d->hasHeightForWidth(); +} + /*! \fn QWidget *QWidget::parentWidget() const diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index e12148b..6e5de7d 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -524,6 +524,7 @@ public: virtual QSize sizeHint() const; virtual QSize minimumSizeHint() const; + bool hasHeightForWidth() const; QSizePolicy sizePolicy() const; void setSizePolicy(QSizePolicy); diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 89ea256..05a859c 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -493,6 +493,7 @@ public: bool setMinimumSize_helper(int &minw, int &minh); bool setMaximumSize_helper(int &maxw, int &maxh); + virtual bool hasHeightForWidth() const; void setConstraints_sys(); QWidget *childAt_helper(const QPoint &, bool) const; void updateGeometry_helper(bool forceUpdate); diff --git a/src/gui/widgets/qsizegrip.cpp b/src/gui/widgets/qsizegrip.cpp index c9d613a..40f3129 100644 --- a/src/gui/widgets/qsizegrip.cpp +++ b/src/gui/widgets/qsizegrip.cpp @@ -78,15 +78,6 @@ static QWidget *qt_sizegrip_topLevelWidget(QWidget* w) return w; } -static inline bool hasHeightForWidth(QWidget *widget) -{ - if (!widget) - return false; - if (QLayout *layout = widget->layout()) - return layout->hasHeightForWidth(); - return widget->sizePolicy().hasHeightForWidth(); -} - class QSizeGripPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QSizeGrip) @@ -318,7 +309,7 @@ void QSizeGrip::mousePressEvent(QMouseEvent * e) #ifdef Q_WS_X11 // Use a native X11 sizegrip for "real" top-level windows if supported. if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE)) - && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) { + && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !tlw->hasHeightForWidth()) { XEvent xev; xev.xclient.type = ClientMessage; xev.xclient.message_type = ATOM(_NET_WM_MOVERESIZE); @@ -340,7 +331,7 @@ void QSizeGrip::mousePressEvent(QMouseEvent * e) } #endif // Q_WS_X11 #ifdef Q_WS_WIN - if (tlw->isWindow() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) { + if (tlw->isWindow() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !tlw->hasHeightForWidth()) { uint orientation = 0; if (d->atBottom()) orientation = d->atLeft() ? SZ_SIZEBOTTOMLEFT : SZ_SIZEBOTTOMRIGHT; @@ -429,12 +420,12 @@ void QSizeGrip::mouseMoveEvent(QMouseEvent * e) #ifdef Q_WS_X11 if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE)) - && tlw->isTopLevel() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) + && tlw->isTopLevel() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !tlw->hasHeightForWidth()) return; #endif #ifdef Q_WS_WIN if (tlw->isWindow() && GetSystemMenu(tlw->winId(), FALSE) != 0 && internalWinId() - && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) { + && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !tlw->hasHeightForWidth()) { MSG msg; while(PeekMessage(&msg, winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)); return; diff --git a/src/gui/widgets/qtabwidget.cpp b/src/gui/widgets/qtabwidget.cpp index 047a905..fb7ca64 100644 --- a/src/gui/widgets/qtabwidget.cpp +++ b/src/gui/widgets/qtabwidget.cpp @@ -195,6 +195,7 @@ public: void _q_removeTab(int); void _q_tabMoved(int from, int to); void init(); + bool hasHeightForWidth() const; QTabBar *tabs; QStackedWidget *stack; @@ -871,6 +872,46 @@ QSize QTabWidget::minimumSizeHint() const .expandedTo(QApplication::globalStrut()); } +int QTabWidget::heightForWidth(int width) const +{ + Q_D(const QTabWidget); + QStyleOption opt(0); + opt.init(this); + opt.state = QStyle::State_None; + + QSize zero(0,0); + const QSize padding = style()->sizeFromContents(QStyle::CT_TabWidget, &opt, zero, this) + .expandedTo(QApplication::globalStrut()); + + QSize lc(0, 0), rc(0, 0); + if (d->leftCornerWidget) + lc = d->leftCornerWidget->sizeHint(); + if(d->rightCornerWidget) + rc = d->rightCornerWidget->sizeHint(); + if (!d->dirty) { + QTabWidget *that = (QTabWidget*)this; + that->setUpLayout(true); + } + QSize t(d->tabs->sizeHint()); + + if(usesScrollButtons()) + t = t.boundedTo(QSize(200,200)); + else + t = t.boundedTo(QApplication::desktop()->size()); + + const bool tabIsHorizontal = (d->pos == North || d->pos == South); + const int contentsWidth = width - padding.width(); + int stackWidth = contentsWidth; + if (!tabIsHorizontal) + stackWidth -= qMax(t.width(), qMax(lc.width(), rc.width())); + + int stackHeight = d->stack->heightForWidth(stackWidth); + QSize s(stackWidth, stackHeight); + + QSize contentSize = basicSize(tabIsHorizontal, lc, rc, s, t); + return (contentSize + padding).expandedTo(QApplication::globalStrut()).height(); +} + /*! \reimp */ @@ -903,6 +944,14 @@ void QTabWidgetPrivate::updateTabBarPosition() q->setUpLayout(); } +bool QTabWidgetPrivate::hasHeightForWidth() const +{ + bool has = size_policy.hasHeightForWidth(); + if (!has && stack) + has = stack->hasHeightForWidth(); + return has; +} + /*! \property QTabWidget::tabPosition \brief the position of the tabs in this tab widget diff --git a/src/gui/widgets/qtabwidget.h b/src/gui/widgets/qtabwidget.h index 68200c8..ee50655 100644 --- a/src/gui/widgets/qtabwidget.h +++ b/src/gui/widgets/qtabwidget.h @@ -129,6 +129,7 @@ public: QSize sizeHint() const; QSize minimumSizeHint() const; + int heightForWidth(int width) const; void setCornerWidget(QWidget * w, Qt::Corner corner = Qt::TopRightCorner); QWidget * cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const; diff --git a/tests/auto/qtabwidget/tst_qtabwidget.cpp b/tests/auto/qtabwidget/tst_qtabwidget.cpp index 4491fb3..204c27a 100644 --- a/tests/auto/qtabwidget/tst_qtabwidget.cpp +++ b/tests/auto/qtabwidget/tst_qtabwidget.cpp @@ -45,6 +45,7 @@ #include #include #include +#include //TESTED_CLASS= //TESTED_FILES= @@ -120,6 +121,8 @@ class tst_QTabWidget:public QObject { void clear(); void keyboardNavigation(); void paintEventCount(); + void heightForWidth(); + void heightForWidth_data(); private: int addPage(); @@ -621,6 +624,50 @@ void tst_QTabWidget::paintEventCount() QCOMPARE(tab2->count, 1); } +void tst_QTabWidget::heightForWidth_data() +{ + QTest::addColumn("tabPosition"); + QTest::newRow("West") << int(QTabWidget::West); + QTest::newRow("North") << int(QTabWidget::North); + QTest::newRow("East") << int(QTabWidget::East); + QTest::newRow("South") << int(QTabWidget::South); +} + +void tst_QTabWidget::heightForWidth() +{ + QFETCH(int, tabPosition); + + QWidget *window = new QWidget; + QVBoxLayout *lay = new QVBoxLayout(window); + lay->setMargin(0); + lay->setSpacing(0); + QTabWidget *tabWid = new QTabWidget(window); + QWidget *w = new QWidget; + tabWid->addTab(w, QLatin1String("HFW page")); + tabWid->setTabPosition(QTabWidget::TabPosition(tabPosition)); + QVBoxLayout *lay2 = new QVBoxLayout(w); + QLabel *label = new QLabel("Label with wordwrap turned on makes it trade height for width." + " Make it a really long text so that it spans on several lines" + " when the label is on its narrowest." + " I don't like to repeat myself." + " I don't like to repeat myself." + " I don't like to repeat myself." + " I don't like to repeat myself." + ); + label->setWordWrap(true); + lay2->addWidget(label); + lay2->setMargin(0); + + lay->addWidget(tabWid); + int h = window->heightForWidth(160); + window->resize(160, h); + window->show(); + + QTest::qWaitForWindowShown(window); + QVERIFY(label->height() >= label->heightForWidth(label->width())); + + delete window; +} QTEST_MAIN(tst_QTabWidget) #include "tst_qtabwidget.moc" -- cgit v0.12 From 939fdb8f03b998996e532cb89c8e522565c1aecc Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 27 Apr 2010 11:16:10 +0200 Subject: Fix crash when using opengl graphicssystem on desktop Reviewed-By: Eskil Task-number: QTBUG-10225 --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 6 +++++- src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 3 ++- src/opengl/qgl.cpp | 8 ++++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 8460430..4461358 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1337,9 +1337,12 @@ void QGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem) d->drawCachedGlyphs(glyphType, textItem, true); } -void QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src) +bool QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src) { Q_D(QGL2PaintEngineEx); + if (!d->shaderManager) + return false; + ensureActive(); d->transferMode(ImageDrawingMode); @@ -1354,6 +1357,7 @@ void QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, state()->renderHints & QPainter::SmoothPixmapTransform, textureId); d->drawTexture(dest, srcRect, size, false); + return true; } void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 30f6634..6ba0c42 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -123,7 +123,6 @@ public: virtual void renderHintsChanged(); virtual void transformChanged(); - virtual void drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr); virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, QPainter::PixmapFragmentHints hints); @@ -136,6 +135,8 @@ public: virtual void drawStaticTextItem(QStaticTextItem *textItem); + bool drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr); + Type type() const { return OpenGL2; } virtual void setState(QPainterState *s); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 72ed6be..52efea5 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2774,8 +2774,8 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text if (!eng->isNativePaintingActive()) { QRectF src(0, 0, target.width(), target.height()); QSize size(target.width(), target.height()); - eng->drawTexture(target, textureId, size, src); - return; + if (eng->drawTexture(target, textureId, size, src)) + return; } } @@ -2850,8 +2850,8 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text QRectF dest(point, QSizeF(textureWidth, textureHeight)); QRectF src(0, 0, textureWidth, textureHeight); QSize size(textureWidth, textureHeight); - eng->drawTexture(dest, textureId, size, src); - return; + if (eng->drawTexture(dest, textureId, size, src)) + return; } } -- cgit v0.12 From 346b680ab51776e6660df635b0921637f727cc75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 27 Apr 2010 15:53:13 +0200 Subject: Fix crash when CoreText fails to shape text for us As a fallback we assume one glyph per character and manually build a list of invalid glyphs with zero advance. Reviewed-and-inspired-by: Simon Hausmann --- src/gui/text/qfontengine_mac.mm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 0bfdbc0..a6510cb 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -226,8 +226,19 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay QFixed *outAdvances_y = glyphs->advances_y; glyph_t *initialGlyph = outGlyphs; - if (arraySize == 0) - return false; + if (arraySize == 0) { + // CoreText failed to shape the text we gave it, so we assume one glyph + // per character and build a list of invalid glyphs with zero advance + *nglyphs = len; + for (int i = 0; i < len; ++i) { + outGlyphs[i] = 0; + logClusters[i] = i; + outAdvances_x[i] = QFixed(); + outAdvances_y[i] = QFixed(); + outAttributes[i].clusterStart = true; + } + return true; + } const bool rtl = (CTRunGetStatus(static_cast(CFArrayGetValueAtIndex(array, 0))) & kCTRunStatusRightToLeft); -- cgit v0.12 From 83a59e90ebf3aa2b8381f746a2c731426805b649 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Tue, 27 Apr 2010 13:13:42 +0100 Subject: Add unit tests covering most of QVector's API. Similarly to the QList tests, if this breaks, it'll be found out quickly - but it is nice to have tests to pinpoint exactly what, and why. Reviewed-by: Olivier Goffart Merge-Request: 584 --- tests/auto/qvector/tst_qvector.cpp | 600 +++++++++++++++++++++++++++++++++++++ 1 file changed, 600 insertions(+) diff --git a/tests/auto/qvector/tst_qvector.cpp b/tests/auto/qvector/tst_qvector.cpp index ebc19ed..2bc8d15 100644 --- a/tests/auto/qvector/tst_qvector.cpp +++ b/tests/auto/qvector/tst_qvector.cpp @@ -55,10 +55,610 @@ public: virtual ~tst_QVector() {} private slots: + void constructors() const; + void append() const; + void at() const; + void capacity() const; + void clear() const; + void constData() const; + void contains() const; + void count() const; + void data() const; + void empty() const; + void endsWith() const; + void fill() const; + void first() const; + void fromList() const; + void fromStdVector() const; + void indexOf() const; + void insert() const; + void isEmpty() const; + void last() const; + void lastIndexOf() const; + void mid() const; + void prepend() const; + void remove() const; + void size() const; + void startsWith() const; + void toList() const; + void toStdVector() const; + void value() const; + + void testOperators() const; + void outOfMemory(); void QTBUG6416_reserve(); }; +void tst_QVector::constructors() const +{ + // pre-reserve capacity + { + QVector myvec(5); + + QVERIFY(myvec.capacity() == 5); + } + + // default-initialise items + { + QVector myvec(5, 42); + + QVERIFY(myvec.capacity() == 5); + + // make sure all items are initialised ok + foreach (int meaningoflife, myvec) { + QCOMPARE(meaningoflife, 42); + } + } +} + +void tst_QVector::append() const +{ + QVector myvec; + myvec.append(42); + myvec.append(43); + myvec.append(44); + + QVERIFY(myvec.size() == 3); + QCOMPARE(myvec, QVector() << 42 << 43 << 44); +} + +void tst_QVector::at() const +{ + QVector myvec; + myvec << "foo" << "bar" << "baz"; + + QVERIFY(myvec.size() == 3); + QCOMPARE(myvec.at(0), QLatin1String("foo")); + QCOMPARE(myvec.at(1), QLatin1String("bar")); + QCOMPARE(myvec.at(2), QLatin1String("baz")); + + // append an item + myvec << "hello"; + QVERIFY(myvec.size() == 4); + QCOMPARE(myvec.at(0), QLatin1String("foo")); + QCOMPARE(myvec.at(1), QLatin1String("bar")); + QCOMPARE(myvec.at(2), QLatin1String("baz")); + QCOMPARE(myvec.at(3), QLatin1String("hello")); + + // remove an item + myvec.remove(1); + QVERIFY(myvec.size() == 3); + QCOMPARE(myvec.at(0), QLatin1String("foo")); + QCOMPARE(myvec.at(1), QLatin1String("baz")); + QCOMPARE(myvec.at(2), QLatin1String("hello")); +} + +void tst_QVector::capacity() const +{ + QVector myvec; + + // TODO: is this guarenteed? seems a safe assumption, but I suppose preallocation of a + // few items isn't an entirely unforseeable possibility. + QVERIFY(myvec.capacity() == 0); + + // test it gets a size + myvec << "aaa" << "bbb" << "ccc"; + QVERIFY(myvec.capacity() >= 3); + + // make sure it grows ok + myvec << "aaa" << "bbb" << "ccc"; + QVERIFY(myvec.capacity() >= 6); + + // let's try squeeze a bit + myvec.remove(3); + myvec.remove(3); + myvec.remove(3); + // TODO: is this a safe assumption? presumably it won't release memory until shrink(), but can we asser that is true? + QVERIFY(myvec.capacity() >= 6); + myvec.squeeze(); + QVERIFY(myvec.capacity() >= 3); + + myvec.remove(0); + myvec.remove(0); + myvec.remove(0); + // TODO: as above note + QVERIFY(myvec.capacity() >= 3); + myvec.squeeze(); + QVERIFY(myvec.capacity() == 0); +} + +void tst_QVector::clear() const +{ + QVector myvec; + myvec << "aaa" << "bbb" << "ccc"; + + QVERIFY(myvec.size() == 3); + myvec.clear(); + QVERIFY(myvec.size() == 0); + QVERIFY(myvec.capacity() == 0); +} + +void tst_QVector::constData() const +{ + int arr[] = { 42, 43, 44 }; + QVector myvec; + myvec << 42 << 43 << 44; + + QVERIFY(memcmp(myvec.constData(), reinterpret_cast(&arr), sizeof(int) * 3) == 0); +} + +void tst_QVector::contains() const +{ + QVector myvec; + myvec << "aaa" << "bbb" << "ccc"; + + QVERIFY(myvec.contains(QLatin1String("aaa"))); + QVERIFY(myvec.contains(QLatin1String("bbb"))); + QVERIFY(myvec.contains(QLatin1String("ccc"))); + QVERIFY(!myvec.contains(QLatin1String("I don't exist"))); + + // add it and make sure it does :) + myvec.append(QLatin1String("I don't exist")); + QVERIFY(myvec.contains(QLatin1String("I don't exist"))); +} + +void tst_QVector::count() const +{ + // total size + { + // zero size + QVector myvec; + QVERIFY(myvec.count() == 0); + + // grow + myvec.append(42); + QVERIFY(myvec.count() == 1); + myvec.append(42); + QVERIFY(myvec.count() == 2); + + // shrink + myvec.remove(0); + QVERIFY(myvec.count() == 1); + myvec.remove(0); + QVERIFY(myvec.count() == 0); + } + + // count of items + { + QVector myvec; + myvec << "aaa" << "bbb" << "ccc"; + + // initial tests + QVERIFY(myvec.count(QLatin1String("aaa")) == 1); + QVERIFY(myvec.count(QLatin1String("pirates")) == 0); + + // grow + myvec.append(QLatin1String("aaa")); + QVERIFY(myvec.count(QLatin1String("aaa")) == 2); + + // shrink + myvec.remove(0); + QVERIFY(myvec.count(QLatin1String("aaa")) == 1); + } +} + +void tst_QVector::data() const +{ + QVector myvec; + myvec << 42 << 43 << 44; + + // make sure it starts off ok + QCOMPARE(*(myvec.data() + 1), 43); + + // alter it + *(myvec.data() + 1) = 69; + + // check it altered + QCOMPARE(*(myvec.data() + 1), 69); + + int arr[] = { 42, 69, 44 }; + QVERIFY(memcmp(myvec.data(), reinterpret_cast(&arr), sizeof(int) * 3) == 0); +} + +void tst_QVector::empty() const +{ + QVector myvec; + + // starts empty + QVERIFY(myvec.empty()); + + // not empty + myvec.append(1); + QVERIFY(!myvec.empty()); + + // empty again + myvec.remove(0); + QVERIFY(myvec.empty()); +} + +void tst_QVector::endsWith() const +{ + QVector myvec; + + // empty vector + QVERIFY(!myvec.endsWith(1)); + + // add the one, should work + myvec.append(1); + QVERIFY(myvec.endsWith(1)); + + // add something else, fails now + myvec.append(3); + QVERIFY(!myvec.endsWith(1)); + + // remove it again :) + myvec.remove(1); + QVERIFY(myvec.endsWith(1)); +} + +void tst_QVector::fill() const +{ + QVector myvec; + + // resize + myvec.resize(5); + myvec.fill(69); + QCOMPARE(myvec, QVector() << 69 << 69 << 69 << 69 << 69); + + // make sure it can resize itself too + myvec.fill(42, 10); + QCOMPARE(myvec, QVector() << 42 << 42 << 42 << 42 << 42 << 42 << 42 << 42 << 42 << 42); +} + +void tst_QVector::first() const +{ + QVector myvec; + myvec << 69 << 42 << 3; + + // test it starts ok + QCOMPARE(myvec.first(), 69); + + // test removal changes + myvec.remove(0); + QCOMPARE(myvec.first(), 42); + + // test prepend changes + myvec.prepend(23); + QCOMPARE(myvec.first(), 23); +} + +void tst_QVector::fromList() const +{ + QList list; + list << "aaa" << "bbb" << "ninjas" << "pirates"; + + QVector myvec; + myvec = QVector::fromList(list); + + // test it worked ok + QCOMPARE(myvec, QVector() << "aaa" << "bbb" << "ninjas" << "pirates"); + QCOMPARE(list, QList() << "aaa" << "bbb" << "ninjas" << "pirates"); +} + +void tst_QVector::fromStdVector() const +{ + // stl = :( + std::vector svec; + svec.push_back(QLatin1String("aaa")); + svec.push_back(QLatin1String("bbb")); + svec.push_back(QLatin1String("ninjas")); + svec.push_back(QLatin1String("pirates")); + QVector myvec = QVector::fromStdVector(svec); + + // test it converts ok + QCOMPARE(myvec, QVector() << "aaa" << "bbb" << "ninjas" << "pirates"); +} + +void tst_QVector::indexOf() const +{ + QVector myvec; + myvec << "A" << "B" << "C" << "B" << "A"; + + QVERIFY(myvec.indexOf("B") == 1); + QVERIFY(myvec.indexOf("B", 1) == 1); + QVERIFY(myvec.indexOf("B", 2) == 3); + QVERIFY(myvec.indexOf("X") == -1); + QVERIFY(myvec.indexOf("X", 2) == -1); + + // add an X + myvec << "X"; + QVERIFY(myvec.indexOf("X") == 5); + QVERIFY(myvec.indexOf("X", 5) == 5); + QVERIFY(myvec.indexOf("X", 6) == -1); + + // remove first A + myvec.remove(0); + QVERIFY(myvec.indexOf("A") == 3); + QVERIFY(myvec.indexOf("A", 3) == 3); + QVERIFY(myvec.indexOf("A", 4) == -1); +} + +void tst_QVector::insert() const +{ + QVector myvec; + myvec << "A" << "B" << "C"; + + // first position + QCOMPARE(myvec.at(0), QLatin1String("A")); + myvec.insert(0, QLatin1String("X")); + QCOMPARE(myvec.at(0), QLatin1String("X")); + QCOMPARE(myvec.at(1), QLatin1String("A")); + + // middle + myvec.insert(1, QLatin1String("Z")); + QCOMPARE(myvec.at(0), QLatin1String("X")); + QCOMPARE(myvec.at(1), QLatin1String("Z")); + QCOMPARE(myvec.at(2), QLatin1String("A")); + + // end + myvec.insert(5, QLatin1String("T")); + QCOMPARE(myvec.at(5), QLatin1String("T")); + QCOMPARE(myvec.at(4), QLatin1String("C")); + + // insert a lot of garbage in the middle + myvec.insert(2, 2, QLatin1String("infinity")); + QCOMPARE(myvec, QVector() << "X" << "Z" << "infinity" << "infinity" + << "A" << "B" << "C" << "T"); +} + +void tst_QVector::isEmpty() const +{ + QVector myvec; + + // starts ok + QVERIFY(myvec.isEmpty()); + + // not empty now + myvec.append(QLatin1String("hello there")); + QVERIFY(!myvec.isEmpty()); + + // empty again + myvec.remove(0); + QVERIFY(myvec.isEmpty()); +} + +void tst_QVector::last() const +{ + QVector myvec; + myvec << "A" << "B" << "C"; + + // test starts ok + QCOMPARE(myvec.last(), QLatin1String("C")); + + // test it changes ok + myvec.append(QLatin1String("X")); + QCOMPARE(myvec.last(), QLatin1String("X")); + + // and remove again + myvec.remove(3); + QCOMPARE(myvec.last(), QLatin1String("C")); +} + +void tst_QVector::lastIndexOf() const +{ + QVector myvec; + myvec << "A" << "B" << "C" << "B" << "A"; + + QVERIFY(myvec.lastIndexOf("B") == 3); + QVERIFY(myvec.lastIndexOf("B", 2) == 1); + QVERIFY(myvec.lastIndexOf("X") == -1); + QVERIFY(myvec.lastIndexOf("X", 2) == -1); + + // add an X + myvec << "X"; + QVERIFY(myvec.lastIndexOf("X") == 5); + QVERIFY(myvec.lastIndexOf("X", 5) == 5); + QVERIFY(myvec.lastIndexOf("X", 3) == -1); + + // remove first A + myvec.remove(0); + QVERIFY(myvec.lastIndexOf("A") == 3); + QVERIFY(myvec.lastIndexOf("A", 3) == 3); + QVERIFY(myvec.lastIndexOf("A", 2) == -1); +} + +void tst_QVector::mid() const +{ + QVector list; + list << "foo" << "bar" << "baz" << "bak" << "buck" << "hello" << "kitty"; + + QCOMPARE(list.mid(3, 3), QVector() << "bak" << "buck" << "hello"); + QCOMPARE(list.mid(4), QVector() << "buck" << "hello" << "kitty"); +} + +void tst_QVector::prepend() const +{ + QVector myvec; + myvec << "A" << "B" << "C"; + + // starts ok + QVERIFY(myvec.size() == 3); + QCOMPARE(myvec.at(0), QLatin1String("A")); + + // add something + myvec.prepend(QLatin1String("X")); + QCOMPARE(myvec.at(0), QLatin1String("X")); + QCOMPARE(myvec.at(1), QLatin1String("A")); + QVERIFY(myvec.size() == 4); + + // something else + myvec.prepend(QLatin1String("Z")); + QCOMPARE(myvec.at(0), QLatin1String("Z")); + QCOMPARE(myvec.at(1), QLatin1String("X")); + QCOMPARE(myvec.at(2), QLatin1String("A")); + QVERIFY(myvec.size() == 5); + + // clear and append to an empty vector + myvec.clear(); + QVERIFY(myvec.size() == 0); + myvec.prepend(QLatin1String("ninjas")); + QVERIFY(myvec.size() == 1); + QCOMPARE(myvec.at(0), QLatin1String("ninjas")); +} + +void tst_QVector::remove() const +{ + QVector myvec; + myvec << "A" << "B" << "C"; + + // remove middle + myvec.remove(1); + QCOMPARE(myvec, QVector() << "A" << "C"); + + // remove rest + myvec.remove(0, 2); + QCOMPARE(myvec, QVector()); +} + +// ::reserve() is really hard to think of tests for, so not doing it. +// ::resize() is tested in ::capacity(). + +void tst_QVector::size() const +{ + // total size + { + // zero size + QVector myvec; + QVERIFY(myvec.size() == 0); + + // grow + myvec.append(42); + QVERIFY(myvec.size() == 1); + myvec.append(42); + QVERIFY(myvec.size() == 2); + + // shrink + myvec.remove(0); + QVERIFY(myvec.size() == 1); + myvec.remove(0); + QVERIFY(myvec.size() == 0); + } +} + +// ::squeeze() is tested in ::capacity(). + +void tst_QVector::startsWith() const +{ + QVector myvec; + + // empty vector + QVERIFY(!myvec.startsWith(1)); + + // add the one, should work + myvec.prepend(1); + QVERIFY(myvec.startsWith(1)); + + // add something else, fails now + myvec.prepend(3); + QVERIFY(!myvec.startsWith(1)); + + // remove it again :) + myvec.remove(0); + QVERIFY(myvec.startsWith(1)); +} + +void tst_QVector::toList() const +{ + QVector myvec; + myvec << "A" << "B" << "C"; + + // make sure it converts and doesn't modify the original vector + QCOMPARE(myvec.toList(), QList() << "A" << "B" << "C"); + QCOMPARE(myvec, QVector() << "A" << "B" << "C"); +} + +void tst_QVector::toStdVector() const +{ + QVector myvec; + myvec << "A" << "B" << "C"; + + std::vector svec = myvec.toStdVector(); + QCOMPARE(svec.at(0), QLatin1String("A")); + QCOMPARE(svec.at(1), QLatin1String("B")); + QCOMPARE(svec.at(2), QLatin1String("C")); + + QCOMPARE(myvec, QVector() << "A" << "B" << "C"); +} + +void tst_QVector::value() const +{ + QVector myvec; + myvec << "A" << "B" << "C"; + + // valid calls + QCOMPARE(myvec.value(0), QLatin1String("A")); + QCOMPARE(myvec.value(1), QLatin1String("B")); + QCOMPARE(myvec.value(2), QLatin1String("C")); + + // default calls + QCOMPARE(myvec.value(-1), QString()); + QCOMPARE(myvec.value(3), QString()); + + // test calls with a provided default, valid calls + QCOMPARE(myvec.value(0, QLatin1String("default")), QLatin1String("A")); + QCOMPARE(myvec.value(1, QLatin1String("default")), QLatin1String("B")); + QCOMPARE(myvec.value(2, QLatin1String("default")), QLatin1String("C")); + + // test calls with a provided default that will return the default + QCOMPARE(myvec.value(-1, QLatin1String("default")), QLatin1String("default")); + QCOMPARE(myvec.value(3, QLatin1String("default")), QLatin1String("default")); +} + +void tst_QVector::testOperators() const +{ + QVector myvec; + myvec << "A" << "B" << "C"; + QVector myvectwo; + myvectwo << "D" << "E" << "F"; + QVector combined; + combined << "A" << "B" << "C" << "D" << "E" << "F"; + + // != + QVERIFY(myvec != myvectwo); + + // + + QCOMPARE(myvec + myvectwo, combined); + QCOMPARE(myvec, QVector() << "A" << "B" << "C"); + QCOMPARE(myvectwo, QVector() << "D" << "E" << "F"); + + // += + myvec += myvectwo; + QCOMPARE(myvec, combined); + + // == + QVERIFY(myvec == combined); + + // [] + QCOMPARE(myvec[0], QLatin1String("A")); + QCOMPARE(myvec[1], QLatin1String("B")); + QCOMPARE(myvec[2], QLatin1String("C")); + QCOMPARE(myvec[3], QLatin1String("D")); + QCOMPARE(myvec[4], QLatin1String("E")); + QCOMPARE(myvec[5], QLatin1String("F")); +} + + int fooCtor; int fooDtor; -- cgit v0.12 From 3eded761167af317bab4f4d8c1ac0a12433eb03a Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 28 Apr 2010 03:50:42 +0200 Subject: A small mistake when comparing the flag. Qt::NoTextInteraction is equal to 0 so you can't compare using & because it will always be false even if the flag is set. Reviewed-by:janarve --- src/gui/text/qtextcontrol.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index 3c596e5..a2ee659 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -885,8 +885,10 @@ void QTextControl::processEvent(QEvent *e, const QPointF &coordinateOffset, QWid void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *contextWidget) { Q_D(QTextControl); - if (d->interactionFlags & Qt::NoTextInteraction) + if (d->interactionFlags == Qt::NoTextInteraction) { + e->ignore(); return; + } d->contextWidget = contextWidget; -- cgit v0.12 From f35b1fd3807c634f5fe60efecd401db7683a37fb Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 28 Apr 2010 11:52:33 +0200 Subject: Revert "Try to use multisampled opengl graphicssystem on all platforms" This reverts commit 5f63f95def838ce72af99dc697ecce092fe7eb69. Fixes GL graphics system on Windows. With the patch, windows would pop up as completely empty. --- src/opengl/qwindowsurface_gl.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 92a347b..7efa9bc 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -97,7 +97,6 @@ extern Q_GUI_EXPORT bool qt_win_owndc_required; QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL) : QGraphicsSystem(), m_useX11GL(useX11GL) { - QGLWindowSurface::surfaceFormat.setSampleBuffers(true); #if defined(Q_WS_X11) && !defined(QT_OPENGL_ES) // only override the system defaults if the user hasn't already // picked a visual -- cgit v0.12 From 18480fd6cec52722d9d096991790e32837a7ebd8 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 28 Apr 2010 11:05:29 +0200 Subject: Null pointer check Fixes crash for certain SVGs Reviewed-by: Kim --- src/svg/qsvghandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index b6e771f..d545440 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -3751,7 +3751,7 @@ bool QSvgHandler::characters(const QStringRef &str) QCss::Parser(css).parse(&sheet); m_selector->styleSheets.append(sheet); return true; - } else if (m_skipNodes.isEmpty() || m_skipNodes.top() == Unknown) + } else if (m_skipNodes.isEmpty() || m_skipNodes.top() == Unknown || m_nodes.isEmpty()) return true; if (m_nodes.top()->type() == QSvgNode::TEXT || m_nodes.top()->type() == QSvgNode::TEXTAREA) { -- cgit v0.12 From a8065da96b96fcc4baeca7615c2a4195c05cbc03 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 26 Apr 2010 15:16:34 +0200 Subject: QUrl: parsing of host name with an undercore. This is not supposed to be allowed, but it work with other browsers Rask-number: QTBUG-7434 Reviewed-by: Thiago Reviewed-by: Markus Goetz --- src/corelib/io/qurl.cpp | 4 +++- tests/auto/qurl/tst_qurl.cpp | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index a60f206..4e580dd 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -2997,7 +2997,9 @@ bool qt_check_std3rules(const QChar *uc, int len) // only LDH is present if (c == '-' || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') - || (c >= 'a' && c <= 'z')) + || (c >= 'a' && c <= 'z') + //underscore is not supposed to be allowed, but other browser accept it (QTBUG-7434) + || c == '_') continue; return false; diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index b7cbdb8..fa42adc 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -1632,6 +1632,10 @@ void tst_QUrl::toString_data() QTest::newRow("nopath_task31320") << QString::fromLatin1("host://protocol") << uint(QUrl::None) << QString::fromLatin1("host://protocol"); + + QTest::newRow("underscore_QTBUG-7434") << QString::fromLatin1("http://foo_bar.host.com/rss.php") + << uint(QUrl::None) + << QString::fromLatin1("http://foo_bar.host.com/rss.php"); } void tst_QUrl::toString() @@ -3244,7 +3248,6 @@ void tst_QUrl::std3violations_data() QTest::newRow("question") << "foo?bar" << true; QTest::newRow("at") << "foo@bar" << true; QTest::newRow("backslash") << "foo\\bar" << false; - QTest::newRow("underline") << "foo_bar" << false; // these characters are transformed by NFKC to non-LDH characters QTest::newRow("dot-like") << QString::fromUtf8("foo\342\200\244bar") << false; // U+2024 ONE DOT LEADER @@ -3289,6 +3292,7 @@ void tst_QUrl::std3deviations_data() QTest::newRow("ending-dot") << "example.com."; QTest::newRow("ending-dot3002") << QString("example.com") + QChar(0x3002); + QTest::newRow("underline") << "foo_bar"; //QTBUG-7434 } void tst_QUrl::std3deviations() -- cgit v0.12 From 8bde410a6d0b1510d182a365d769db182b1c07dd Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 28 Apr 2010 14:12:59 +0200 Subject: Fixed the sizehint for cols/rows in qtableview It could return wrong values because we were not always checking the right cols/rows. Reviewed-By: gabi Task-Number: QTBUG-10169 --- src/gui/itemviews/qtableview.cpp | 8 ++++---- tests/auto/qtableview/tst_qtableview.cpp | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index 80334a6..4492e53 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -2145,8 +2145,8 @@ int QTableView::sizeHintForRow(int row) const ensurePolished(); - int left = qMax(0, columnAt(0)); - int right = columnAt(d->viewport->width()); + int left = qMax(0, d->horizontalHeader->visualIndexAt(0)); + int right = d->horizontalHeader->visualIndexAt(d->viewport->width()); if (right == -1) // the table don't have enough columns to fill the viewport right = d->model->columnCount(d->root) - 1; @@ -2204,8 +2204,8 @@ int QTableView::sizeHintForColumn(int column) const ensurePolished(); - int top = qMax(0, rowAt(0)); - int bottom = rowAt(d->viewport->height()); + int top = qMax(0, d->verticalHeader->visualIndexAt(0)); + int bottom = d->verticalHeader->visualIndexAt(d->viewport->height()); if (!isVisible() || bottom == -1) // the table don't have enough rows to fill the viewport bottom = d->model->rowCount(d->root) - 1; diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index 2062e8e..3e5d077 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -202,6 +202,7 @@ private slots: void taskQTBUG_8585_crashForNoGoodReason(); void taskQTBUG_7774_RtoLVisualRegionForSelection(); void taskQTBUG_8777_scrollToSpans(); + void taskQTBUG_10169_sizeHintForRow(); void mouseWheel_data(); void mouseWheel(); @@ -478,6 +479,11 @@ public: return QTableView::selectedIndexes(); } + int sizeHintForRow(int row) const + { + return QTableView::sizeHintForRow(row); + } + bool checkSignalOrder; public slots: void currentChanged(QModelIndex , QModelIndex ) { @@ -4042,5 +4048,20 @@ void tst_QTableView::taskQTBUG_8777_scrollToSpans() QVERIFY(table.verticalScrollBar()->value() > 10); } +void tst_QTableView::taskQTBUG_10169_sizeHintForRow() +{ + QtTestTableView tableView; + QStandardItemModel model(1, 3); + model.setData(model.index(0, 0), "Word wrapping text goes here."); + tableView.setModel(&model); + tableView.verticalHeader()->setResizeMode(QHeaderView::ResizeToContents); + const int orderedHeight = tableView.sizeHintForRow(0); + tableView.horizontalHeader()->moveSection(2, 0); + const int reorderedHeight = tableView.sizeHintForRow(0); + + //the order of the columns shouldn't matter. + QCOMPARE(orderedHeight, reorderedHeight); +} + QTEST_MAIN(tst_QTableView) #include "tst_qtableview.moc" -- cgit v0.12 From f2d647aa0a203e3598b37abcd69c65aec0d3ef21 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 28 Apr 2010 14:18:25 +0200 Subject: Fix crash in styles example when running with opengl graphicssystem When drawing text using glyphs, the shader manager will select the "MaskFragmentShader" which requires a varying called "textureCoords" which is used to sample the glyph from the glyph texture. That's fine, except when you try to use one of the pattern brushes or a texture brush, because the src pixel fragment shader snippets for those brushes also sample from a texture (the brush texture) and name the verying they use "textureCoords" too. This led to textureCoords being defined twice, which in turn caused a shader compile error which then casued the seg-fault. This patch simply renames the varying used to pass the coordinates for the brush texture so it doesn't conflict. Reviewed-By: Kim Task-Number: QTBUG-9522 --- src/opengl/gl2paintengineex/qglengineshadersource_p.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index 3379296..8dba951 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -282,7 +282,7 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\n\ uniform mediump vec2 halfViewportSize; \n\ uniform highp vec2 invertedTextureSize; \n\ uniform highp mat3 brushTransform; \n\ - varying highp vec2 textureCoords; \n\ + varying highp vec2 brushTextureCoords; \n\ void setPosition(void) \n\ { \n\ highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ @@ -292,7 +292,7 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\n\ mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ - textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\ + brushTextureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\ }\n"; static const char* const qglslAffinePositionWithTextureBrushVertexShader @@ -303,28 +303,28 @@ static const char* const qglslAffinePositionWithTextureBrushVertexShader // we emulate GL_REPEAT by only taking the fractional part of the texture coords. // TODO: Special case POT textures which don't need this emulation static const char* const qglslTextureBrushSrcFragmentShader = "\n\ - varying highp vec2 textureCoords; \n\ + varying highp vec2 brushTextureCoords; \n\ uniform lowp sampler2D brushTexture; \n\ lowp vec4 srcPixel() { \n\ - return texture2D(brushTexture, fract(textureCoords)); \n\ + return texture2D(brushTexture, fract(brushTextureCoords)); \n\ }\n"; #else static const char* const qglslTextureBrushSrcFragmentShader = "\n\ - varying highp vec2 textureCoords; \n\ + varying highp vec2 brushTextureCoords; \n\ uniform lowp sampler2D brushTexture; \n\ lowp vec4 srcPixel() \n\ { \n\ - return texture2D(brushTexture, textureCoords); \n\ + return texture2D(brushTexture, brushTextureCoords); \n\ }\n"; #endif static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\n\ - varying highp vec2 textureCoords; \n\ + varying highp vec2 brushTextureCoords; \n\ uniform lowp vec4 patternColor; \n\ uniform lowp sampler2D brushTexture; \n\ lowp vec4 srcPixel() \n\ { \n\ - return patternColor * (1.0 - texture2D(brushTexture, textureCoords).r); \n\ + return patternColor * (1.0 - texture2D(brushTexture, brushTextureCoords).r); \n\ }\n"; // Solid Fill Brush -- cgit v0.12 From 5506677d71341f5bfe31db0cfb31b2e7a36c1846 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Mon, 26 Apr 2010 15:35:10 +0200 Subject: Documentation for the Drag and Drop Robot example. Checked that it doesn't introduce qdoc errors. Discussed with David and Martin; recommendation was to commit first and fix any errors via review in later commits. --- doc/src/examples/dragdroprobot.qdoc | 334 +++++++++++++++++++++- doc/src/getting-started/examples.qdoc | 2 +- examples/graphicsview/dragdroprobot/coloritem.cpp | 24 +- examples/graphicsview/dragdroprobot/coloritem.h | 2 + examples/graphicsview/dragdroprobot/main.cpp | 8 +- examples/graphicsview/dragdroprobot/robot.cpp | 217 ++++++++------ examples/graphicsview/dragdroprobot/robot.h | 29 +- 7 files changed, 504 insertions(+), 112 deletions(-) diff --git a/doc/src/examples/dragdroprobot.qdoc b/doc/src/examples/dragdroprobot.qdoc index 413f190..887b254 100644 --- a/doc/src/examples/dragdroprobot.qdoc +++ b/doc/src/examples/dragdroprobot.qdoc @@ -43,9 +43,337 @@ \example graphicsview/dragdroprobot \title Drag and Drop Robot Example - This GraphicsView example shows how to implement drag and drop in - a QGraphicsItem subclass, as well as how to animate items using - QGraphicsItemAnimation and QTimeLine. + This GraphicsView example shows how to implement Drag and Drop in a + QGraphicsItem subclass, as well as how to animate items using Qt's + \l{Animation Framework}. \image dragdroprobot-example.png + + Graphics View provides the QGraphicsScene class for managing and + interacting with a large number of custom-made 2D graphical items derived + from the QGraphicsItem class, and a QGraphicsView widget for visualizing + the items, with support for zooming and rotation. + + This example consists of a \c Robot class, a \c ColorItem class, and a main + function: the \c Robot class describes a simple robot consisting of several + \c RobotPart derived limbs, including \c RobotHead and \c RobotLimb, the \c + ColorItem class provides a draggable colored ellipse, and the \c main() + function provides the main application window. + + We will first review the \c Robot class to see how to assemble the + different parts so that they can be individually rotated and animated using + QPropertyAnimation, and we will then review the \c ColorItem class to + demonstrate how to implement Drag and Drop between items. Finally we will + review the main() function to see how we can put all the pieces together, + to form the final application. + + \section1 Robot Class Definition + + The robot consists of three main classes: the \c RobotHead, the \c + RobotTorso, and the \c RobotLimb, which is used for the upper and lower + arms and legs. All parts derive from the \c RobotPart class, which in turn + inherits \c QGraphicsObject. The \c Robot class itself has no visual + appearance and serves only as a root node for the robot. + + Let's start with the \c RobotPart class declaration. + + \snippet examples/graphicsview/dragdroprobot/robot.h 0 + + This base class inherits QGraphicsObject. QGraphicsObject provides signals + and slots through inheriting QObject, and it also declares QGraphicsItem's + properties using Q_PROPERTY, which makes the properties accessible for + QPropertyAnimation. + + RobotPart also implements the three most important event handlers for + accepting drop events: + \l{QGraphicsItem::dragEnterEvent()}{dragEnterEvent()}, + \l{QGraphicsItem::dragLeaveEvent()}{dragLeaveEvent()}, and + \l{QGraphicsItem::dropEvent()}{dropEvent()}. + + The color is stored as a member variable, along with the \c dragOver + variable, which we will use later to indicate visually that the limb can + accept colors that are is dragged onto it. + + \snippet examples/graphicsview/dragdroprobot/robot.cpp 0 + + \c RobotPart's constructor initializes the dragOver member and sets the + color to Qt::lightGray. In the constructor body we enable support for + accepting drop events by calling + \l{QGraphicsItem::setAcceptDrops()}{setAcceptDrops(true)}. + + The rest of this class's implementation is to support Drag and Drop. + + \snippet examples/graphicsview/dragdroprobot/robot.cpp 1 + + The \l{QGraphicsItem::dragEnterEvent()}{dragEnterEvent()} handler is called + when a Drag and Drop element is dragged into the robot part's area. + + The handler implementation determines whether or not this item as a whole + can accept the mime data assiciated with the incoming drag object. \c + RobotPart provides a base behavior for all parts that accepts color drops. + So if the incoming drag object contains a color, the event is accepted, we + set \c dragOver to \c true and call update() to help provide positive + visual feedback to the user; otherwise the event is ignored, which in turn + allows the event to propagate to parent elements. + + \snippet examples/graphicsview/dragdroprobot/robot.cpp 2 + + The \l{QGraphicsItem::dragLeaveEvent()}{dragLeaveEvent()} handler is called + when a Drag and Drop element is dragged away from the robot part's area. + Our implementation simply resets \e dragOver to false and calls + \l{QGraphicsItem::update()}{update()} to help provide visual feedback that + the drag has left this item. + + \snippet examples/graphicsview/dragdroprobot/robot.cpp 3 + + The \l{QGraphicsItem::dropEvent()}{dropEvent()} handler is called when a + Drag and Drop element is dropped onto an item (i.e., when the mouse button + is released over the item while dragging). + + We reset \c dragOver to false, assign the item's new color, and call + \l{QGraphicsItem::update()}{update()}. + + The declaration and implementation of \c RobotHead, \c RobotTorso, and \c + RobotLimb are practically identical. We will review \c RobotHead in detail, + as this class has one minor difference, and leave the other classes as an + exercise for the reader. + + \snippet examples/graphicsview/dragdroprobot/robot.h 1 + + The \c RobotHead class inherits \c RobotPart and provides the necessary + implementations of \l{QGraphicsItem::boundingRect()}{boundingRect()} and + \l{QGraphicsItem::paint()}{paint()}. It also reimplements + \l{QGraphicsItem::dragEnterEvent()}{dragEnterEvent()} and dropEvent() to + provide special handling of image drops. + + The class contains a private pixmap member that we can use to implement + support for accepting image drops. + + \snippet examples/graphicsview/dragdroprobot/robot.cpp 4 + + \c RobotHead has a rather plain constructor that simply forwards to + \c RobotPart's constructor. + + \snippet examples/graphicsview/dragdroprobot/robot.cpp 5 + + The \l{QGraphicsItem::boundingRect()}{boundingRect()} reimplementation + returns the extents for the head. Because we want the center of rotation to + be the bottom center of the item, we have chosen a bounding rectangle that + starts at (-15, -50) and extends to 30 units wide and 50 units tall. When + rotating the head, the "neck" will stay still while the top of the head + tilts from side to side. + + \snippet examples/graphicsview/dragdroprobot/robot.cpp 6 + + In \l{QGraphicsItem::paint()}{paint()} we draw the actual head. The + implementation is split into two sections; if an image has been dropped + onto the head, we draw the image, otherwise we draw a round rectangular + robot head with simple vector graphics. + + For performance reasons, depending on the complexity of what is painted, it + can often be faster to draw the head as an image rather than using a + sequence of vector operations. + + \snippet examples/graphicsview/dragdroprobot/robot.cpp 7 + + The robot head can accept image drops. In order to support this, its + reimplementation of \l{QGraphicsItem::dragEnterEvent()}{dragEnterEvent()} + checks if the drag object contains image data, and if it does, then the + event is accepted. Otherwise we fall back to the base \c RobotPart + implementation. + + \snippet examples/graphicsview/dragdroprobot/robot.cpp 8 + + To follow up on image support, we must also implement + \l{QGraphicsItem::dropEvent()}{dropEvent()}. We check if the drag object + contains image data, and if it does, we store this data as a member pixmap + and call \l{QGraphicsItem::update()}{update()}. This pixmap is used inside + the \l{QGraphicsItem::paint()}{paint()} implementation that we reviewed + before. + + \c RobotTorso and \c RobotLimb are similar to \c RobotHead, so let's + skip directly to the \c Robot class. + + \snippet examples/graphicsview/dragdroprobot/robot.h 4 + + The \c Robot class also inherits \c RobotPart, and like the other parts it + also implements \l{QGraphicsItem::boundingRect()}{boundingRect()} and + \l{QGraphicsItem::paint()}{paint()}. It provides a rather special + implementation, though: + + \snippet examples/graphicsview/dragdroprobot/robot.cpp 9 + + Because the \c Robot class is only used as a base node for the rest of the + robot, it has no visual representation. Its + \l{QGraphicsItem::boundingRect()}{boundingRect()} implementation can + therefore return a null QRectF, and its paint() function does nothing. + + \snippet examples/graphicsview/dragdroprobot/robot.cpp 10 + + The constuctor starts by setting the flag + \l{QGraphicsItem::ItemHasNoContents}{ItemHasNoContents}, which is a minor + optimization for items that have no visual appearance. + + We then construct all the robot parts (head, torso, and upper/lower arms + and legs). The stacking order is very important, and we use the + parent-child hierarchy to ensure the elements rotate and move properly. We + construct the torso first, as this is the root element. We then construct + the head and pass the torso to \c HeadItem's constructor. This will make + the head a child of the torso; if you rotate the torso, the head will + follow. The same pattern is applied to the rest of the limbs. + + \snippet examples/graphicsview/dragdroprobot/robot.cpp 11 + + Each robot part is carefully positioned. For example, the upper left arm is + moved precisely to the top-left area of the torso, and the upper right arm + is moved to the top-right area. + + \snippet examples/graphicsview/dragdroprobot/robot.cpp 12 + + The next section creates all animation objects. This snippet shows the two + animations that operate on the head's scale and rotation. The two + QPropertyAnimation instances simply set the object, property, and + respective start and end values. + + All animations are controlled by one top-level parallel animation group. + The scale and rotation animations are added to this group. + + The rest of the animations are defined in a similar way. + + \snippet examples/graphicsview/dragdroprobot/robot.cpp 13 + + Finally we set an easing curve and duration on each animation, ensure the + toplevel animation group loops forever, and start the toplevel animation. + + \section1 ColorItem Class Definition + + The \c ColorItem class represents a circular item that can be pressed to + drag colors onto robot parts. + + \snippet examples/graphicsview/dragdroprobot/coloritem.h 0 + + This class is very simple. It does not use animations, and has no need for + properties nor signals and slots, so to save resources, it's most natural + that it inherits QGraphicsItem (as opposed to QGraphicsObject). + + It declares the mandatory \l{QGraphicsItem::boundingRect()}{boundingRect()} + and \l{QGraphicsItem::paint()}{paint()} functions, and adds + reimplementations of + \l{QGraphicsItem::mousePressEvent()}{mousePressEvent()}, + \l{QGraphicsItem::mouseMoveEvent()}{mouseMoveEvent()}, and + \l{QGraphicsItem::mouseReleaseEvent()}{mouseReleaseEvent()}. It contains a + single private color member. + + Let's take a look at its implementation. + + \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 0 + + \c ColorItem's constructor assigns an opaque random color to its color + member by making use of qrand(). For improved usability, it assigns a + tooltip that provides a useful hint to the user, and it also sets a + suitable cursor. This ensures that the cursor will chance to + Qt::OpenHandCursor when the mouse pointer hovers over the item. + + Finally, we call + \l{QGraphicsItem::setAcceptedMouseButtons()}{setAcceptedMouseButtons()} to + ensure that this item can only process Qt::LeftButton. This simplifies the + mouse event handlers greatly, as we can always assume that only the left + mouse button is pressed and released. + + \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 1 + + The item's bounding rect is a fixed 30x30 units centered around the item's + origin (0, 0), and adjusted by 0.5 units in all directions to allow a + scalable pen to draw its outline. For a final visual touch the bounds + also compensate with a few units down and to the right to make room + for a simple dropshadow. + + \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 2 + + The \l{QGraphicsItem::paint()}{paint()} implementation draws an ellipse + with a 1-unit black outline, a plain color fill, and a dark gray + dropshadow. + + \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 3 + + The \l{QGraphicsItem::mousePressEvent()}{mousePressEvent()} handler is + called when you press the mouse button inside the item's area. Our + implementation simply sets the cursor to Qt::ClosedHandCursor. + + \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 4 + + The \l{QGraphicsItem::mouseReleaseEvent()}{mouseReleaseEvent()} handler is + called when you release the mouse button after having pressed it inside an + item's area. Our implementation sets the cursor back to Qt::OpenHandCursor. + The mouse press and release event handlers together provide useful visual + feedback to the user: when you move the mouse pointer over a \c CircleItem, + the cursor changes to an open hand. Pressing the item will show a closed + hand cursor. Releasing will restore to an open hand cursor again. + + \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 5 + + The \l{QGraphicsItem::mouseMoveEvent()}{mouseMoveEvent()} handler is called + when you move the mouse around after pressing the mouse button inside the + \c ColorItem's area. This implementation provides the most important piece + of logic for \c CircleItem: the code that starts and manages drags. + + The implementation starts by checking if the mouse has been dragged far + enough to eliminate mouse jitter noise. We only want to start a drag if the + mouse has been dragged farther than the application start drag distance. + + Continuing, we create a QDrag object, passing the event + \l{QGraphicsSceneEvent::widget()}{widget} (i.e., the QGraphicsView + viewport) to its constructor. Qt will ensure that this object is deleted at + the right time. We also create a QMimeData instance that can contain our + color or image data, and assign this to the drag object. + + \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 6 + + This snippet has a somewhat random outcome: once in a while, a special + image is assigned to the drag object's mime data. The pixmap is also + assiged as the drag object's pixmap. This will ensure that you can see the + image that is being dragged as a pixmap under the mouse cursor. + + \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 7 + + Otherwise, and this is the most common outcome, a simple color is assigned + to the drag object's mime data. We render this \c ColorItem into a new + pixmap to give the user visual feedback that the color is being "dragged". + + \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 8 + + Finally we execute the drag. QDrag::exec() will reenter the event loop, and + only exit if the drag has either been dropped, or canceled. In any case we + reset the cursor to Qt::OpenHandCursor. + + \section1 The main() Function + + Now that the \c Robot and \c ColorItem classes are complete, we can put all + the pieces together inside the main() function. + + \snippet examples/graphicsview/dragdroprobot/main.cpp 0 + + We start off by constructing QApplication, and initializing the random + number generator. This ensures that the color items have different colors + every time the application starts. + + \snippet examples/graphicsview/dragdroprobot/main.cpp 1 + + We construct a fixed size scene, and create 10 \c ColorItem instances + arranged in a circle. Each item is added to the scene. + + In the center of this circle we create one \c Robot instance. The + robot is scaled and moved up a few units. It is then added to the scene. + + \snippet examples/graphicsview/dragdroprobot/main.cpp 2 + + Finally we create a QGraphicsView window, and assign the scene to it. + + For increased visual quality, we enable antialiasing. We also choose to use + bounding rectangle updates to simplify visual update handling. + The view is given a fixed sand-colored background, and a window title. + + We then show the view. The animations start immediately after + control enters the event loop. */ + diff --git a/doc/src/getting-started/examples.qdoc b/doc/src/getting-started/examples.qdoc index 071a107..c96c70f 100644 --- a/doc/src/getting-started/examples.qdoc +++ b/doc/src/getting-started/examples.qdoc @@ -649,7 +649,7 @@ \list \o \l{graphicsview/collidingmice}{Colliding Mice}\raisedaster \o \l{graphicsview/diagramscene}{Diagram Scene}\raisedaster - \o \l{graphicsview/dragdroprobot}{Drag and Drop Robot} + \o \l{graphicsview/dragdroprobot}{Drag and Drop Robot}\raisedaster \o \l{graphicsview/elasticnodes}{Elastic Nodes} \o \l{graphicsview/portedasteroids}{Ported Asteroids} \o \l{graphicsview/portedcanvas}{Ported Canvas} diff --git a/examples/graphicsview/dragdroprobot/coloritem.cpp b/examples/graphicsview/dragdroprobot/coloritem.cpp index 95878b1..08edd38 100644 --- a/examples/graphicsview/dragdroprobot/coloritem.cpp +++ b/examples/graphicsview/dragdroprobot/coloritem.cpp @@ -43,6 +43,7 @@ #include "coloritem.h" +//! [0] ColorItem::ColorItem() : color(qrand() % 256, qrand() % 256, qrand() % 256) { @@ -50,13 +51,18 @@ ColorItem::ColorItem() .arg(color.red()).arg(color.green()).arg(color.blue()) .arg("Click and drag this color onto the robot!")); setCursor(Qt::OpenHandCursor); + setAcceptedMouseButtons(Qt::LeftButton); } +//! [0] +//! [1] QRectF ColorItem::boundingRect() const { return QRectF(-15.5, -15.5, 34, 34); } +//! [1] +//! [2] void ColorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); @@ -68,17 +74,16 @@ void ColorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, painter->setBrush(QBrush(color)); painter->drawEllipse(-15, -15, 30, 30); } +//! [2] +//! [3] void ColorItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { - if (event->button() != Qt::LeftButton) { - event->ignore(); - return; - } - setCursor(Qt::ClosedHandCursor); } +//! [3] +//! [5] void ColorItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if (QLineF(event->screenPos(), event->buttonDownScreenPos(Qt::LeftButton)) @@ -89,7 +94,9 @@ void ColorItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) QDrag *drag = new QDrag(event->widget()); QMimeData *mime = new QMimeData; drag->setMimeData(mime); +//! [5] +//! [6] static int n = 0; if (n++ > 2 && (qrand() % 3) == 0) { QImage image(":/images/head.png"); @@ -97,6 +104,8 @@ void ColorItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) drag->setPixmap(QPixmap::fromImage(image).scaled(30, 40)); drag->setHotSpot(QPoint(15, 30)); +//! [6] +//! [7] } else { mime->setColorData(color); mime->setText(QString("#%1%2%3") @@ -118,12 +127,17 @@ void ColorItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) drag->setPixmap(pixmap); drag->setHotSpot(QPoint(15, 20)); } +//! [7] +//! [8] drag->exec(); setCursor(Qt::OpenHandCursor); } +//! [8] +//! [4] void ColorItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *) { setCursor(Qt::OpenHandCursor); } +//! [4] diff --git a/examples/graphicsview/dragdroprobot/coloritem.h b/examples/graphicsview/dragdroprobot/coloritem.h index 788d19e..eb19db6 100644 --- a/examples/graphicsview/dragdroprobot/coloritem.h +++ b/examples/graphicsview/dragdroprobot/coloritem.h @@ -44,6 +44,7 @@ #include +//! [0] class ColorItem : public QGraphicsItem { public: @@ -60,5 +61,6 @@ protected: private: QColor color; }; +//! [0] #endif diff --git a/examples/graphicsview/dragdroprobot/main.cpp b/examples/graphicsview/dragdroprobot/main.cpp index 02585e1..2669c41 100644 --- a/examples/graphicsview/dragdroprobot/main.cpp +++ b/examples/graphicsview/dragdroprobot/main.cpp @@ -46,12 +46,14 @@ #include +//! [0] int main(int argc, char **argv) { QApplication app(argc, argv); qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); - +//! [0] +//! [1] QGraphicsScene scene(-200, -200, 400, 400); for (int i = 0; i < 10; ++i) { @@ -66,7 +68,8 @@ int main(int argc, char **argv) robot->scale(1.2, 1.2); robot->setPos(0, -20); scene.addItem(robot); - +//! [1] +//! [2] QGraphicsView view(&scene); view.setRenderHint(QPainter::Antialiasing); view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); @@ -76,3 +79,4 @@ int main(int argc, char **argv) return app.exec(); } +//! [2] diff --git a/examples/graphicsview/dragdroprobot/robot.cpp b/examples/graphicsview/dragdroprobot/robot.cpp index 9ac6d26..705bd9d 100644 --- a/examples/graphicsview/dragdroprobot/robot.cpp +++ b/examples/graphicsview/dragdroprobot/robot.cpp @@ -43,16 +43,18 @@ #include "robot.h" +//! [0] RobotPart::RobotPart(QGraphicsItem *parent) - : QGraphicsItem(parent), color(Qt::lightGray), dragOver(false) + : QGraphicsObject(parent), color(Qt::lightGray), dragOver(false) { setAcceptDrops(true); } +//! [0] +//! [1] void RobotPart::dragEnterEvent(QGraphicsSceneDragDropEvent *event) { - if (event->mimeData()->hasColor() - || (qgraphicsitem_cast(this) && event->mimeData()->hasImage())) { + if (event->mimeData()->hasColor()) { event->setAccepted(true); dragOver = true; update(); @@ -60,34 +62,42 @@ void RobotPart::dragEnterEvent(QGraphicsSceneDragDropEvent *event) event->setAccepted(false); } } +//! [1] +//! [2] void RobotPart::dragLeaveEvent(QGraphicsSceneDragDropEvent *event) { Q_UNUSED(event); dragOver = false; update(); } +//! [2] +//! [3] void RobotPart::dropEvent(QGraphicsSceneDragDropEvent *event) { dragOver = false; if (event->mimeData()->hasColor()) color = qVariantValue(event->mimeData()->colorData()); - else if (event->mimeData()->hasImage()) - pixmap = qVariantValue(event->mimeData()->imageData()); update(); } +//! [3] +//! [4] RobotHead::RobotHead(QGraphicsItem *parent) : RobotPart(parent) { } +//! [4] +//! [5] QRectF RobotHead::boundingRect() const { return QRectF(-15, -50, 30, 50); } +//! [5] +//! [6] void RobotHead::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { @@ -110,11 +120,33 @@ void RobotHead::paint(QPainter *painter, painter->drawPixmap(QPointF(-15 * 4.4, -50 * 3.54), pixmap); } } +//! [6] -int RobotHead::type() const +//! [7] +void RobotHead::dragEnterEvent(QGraphicsSceneDragDropEvent *event) { - return Type; + if (event->mimeData()->hasImage()) { + event->setAccepted(true); + dragOver = true; + update(); + } else { + RobotPart::dragEnterEvent(event); + } } +//! [7] + +//! [8] +void RobotHead::dropEvent(QGraphicsSceneDragDropEvent *event) +{ + if (event->mimeData()->hasImage()) { + dragOver = false; + pixmap = qVariantValue(event->mimeData()->imageData()); + update(); + } else { + RobotPart::dropEvent(event); + } +} +//! [8] RobotTorso::RobotTorso(QGraphicsItem *parent) : RobotPart(parent) @@ -161,19 +193,25 @@ void RobotLimb::paint(QPainter *painter, painter->drawEllipse(-5, -5, 10, 10); } -Robot::Robot() +//! [10] +Robot::Robot(QGraphicsItem *parent) + : RobotPart(parent) { - QGraphicsItem *torsoItem = new RobotTorso(this); - QGraphicsItem *headItem = new RobotHead(torsoItem); - QGraphicsItem *upperLeftArmItem = new RobotLimb(torsoItem); - QGraphicsItem *lowerLeftArmItem = new RobotLimb(upperLeftArmItem); - QGraphicsItem *upperRightArmItem = new RobotLimb(torsoItem); - QGraphicsItem *lowerRightArmItem = new RobotLimb(upperRightArmItem); - QGraphicsItem *upperRightLegItem = new RobotLimb(torsoItem); - QGraphicsItem *lowerRightLegItem = new RobotLimb(upperRightLegItem); - QGraphicsItem *upperLeftLegItem = new RobotLimb(torsoItem); - QGraphicsItem *lowerLeftLegItem = new RobotLimb(upperLeftLegItem); - + setFlag(ItemHasNoContents); + + QGraphicsObject *torsoItem = new RobotTorso(this); + QGraphicsObject *headItem = new RobotHead(torsoItem); + QGraphicsObject *upperLeftArmItem = new RobotLimb(torsoItem); + QGraphicsObject *lowerLeftArmItem = new RobotLimb(upperLeftArmItem); + QGraphicsObject *upperRightArmItem = new RobotLimb(torsoItem); + QGraphicsObject *lowerRightArmItem = new RobotLimb(upperRightArmItem); + QGraphicsObject *upperRightLegItem = new RobotLimb(torsoItem); + QGraphicsObject *lowerRightLegItem = new RobotLimb(upperRightLegItem); + QGraphicsObject *upperLeftLegItem = new RobotLimb(torsoItem); + QGraphicsObject *lowerLeftLegItem = new RobotLimb(upperLeftLegItem); +//! [10] + +//! [11] headItem->setPos(0, -18); upperLeftArmItem->setPos(-15, -10); lowerLeftArmItem->setPos(30, 0); @@ -183,82 +221,78 @@ Robot::Robot() lowerRightLegItem->setPos(30, 0); upperLeftLegItem->setPos(-10, 32); lowerLeftLegItem->setPos(30, 0); +//! [11] - timeLine = new QTimeLine; - - QGraphicsItemAnimation *headAnimation = new QGraphicsItemAnimation; - headAnimation->setItem(headItem); - headAnimation->setTimeLine(timeLine); - headAnimation->setRotationAt(0, 20); - headAnimation->setRotationAt(1, -20); - headAnimation->setScaleAt(1, 1.1, 1.1); - - QGraphicsItemAnimation *upperLeftArmAnimation = new QGraphicsItemAnimation; - upperLeftArmAnimation->setItem(upperLeftArmItem); - upperLeftArmAnimation->setTimeLine(timeLine); - upperLeftArmAnimation->setRotationAt(0, 190); - upperLeftArmAnimation->setRotationAt(1, 180); - - QGraphicsItemAnimation *lowerLeftArmAnimation = new QGraphicsItemAnimation; - lowerLeftArmAnimation->setItem(lowerLeftArmItem); - lowerLeftArmAnimation->setTimeLine(timeLine); - lowerLeftArmAnimation->setRotationAt(0, 50); - lowerLeftArmAnimation->setRotationAt(1, 10); - - QGraphicsItemAnimation *upperRightArmAnimation = new QGraphicsItemAnimation; - upperRightArmAnimation->setItem(upperRightArmItem); - upperRightArmAnimation->setTimeLine(timeLine); - upperRightArmAnimation->setRotationAt(0, 300); - upperRightArmAnimation->setRotationAt(1, 310); - - QGraphicsItemAnimation *lowerRightArmAnimation = new QGraphicsItemAnimation; - lowerRightArmAnimation->setItem(lowerRightArmItem); - lowerRightArmAnimation->setTimeLine(timeLine); - lowerRightArmAnimation->setRotationAt(0, 0); - lowerRightArmAnimation->setRotationAt(1, -70); - - QGraphicsItemAnimation *upperLeftLegAnimation = new QGraphicsItemAnimation; - upperLeftLegAnimation->setItem(upperLeftLegItem); - upperLeftLegAnimation->setTimeLine(timeLine); - upperLeftLegAnimation->setRotationAt(0, 150); - upperLeftLegAnimation->setRotationAt(1, 80); - - QGraphicsItemAnimation *lowerLeftLegAnimation = new QGraphicsItemAnimation; - lowerLeftLegAnimation->setItem(lowerLeftLegItem); - lowerLeftLegAnimation->setTimeLine(timeLine); - lowerLeftLegAnimation->setRotationAt(0, 70); - lowerLeftLegAnimation->setRotationAt(1, 10); - - QGraphicsItemAnimation *upperRightLegAnimation = new QGraphicsItemAnimation; - upperRightLegAnimation->setItem(upperRightLegItem); - upperRightLegAnimation->setTimeLine(timeLine); - upperRightLegAnimation->setRotationAt(0, 40); - upperRightLegAnimation->setRotationAt(1, 120); - - QGraphicsItemAnimation *lowerRightLegAnimation = new QGraphicsItemAnimation; - lowerRightLegAnimation->setItem(lowerRightLegItem); - lowerRightLegAnimation->setTimeLine(timeLine); - lowerRightLegAnimation->setRotationAt(0, 10); - lowerRightLegAnimation->setRotationAt(1, 50); - - QGraphicsItemAnimation *torsoAnimation = new QGraphicsItemAnimation; - torsoAnimation->setItem(torsoItem); - torsoAnimation->setTimeLine(timeLine); - torsoAnimation->setRotationAt(0, 5); - torsoAnimation->setRotationAt(1, -20); - - timeLine->setUpdateInterval(1000 / 25); - timeLine->setCurveShape(QTimeLine::SineCurve); - timeLine->setLoopCount(0); - timeLine->setDuration(2000); - timeLine->start(); -} +//! [12] + QParallelAnimationGroup *animation = new QParallelAnimationGroup(this); -Robot::~Robot() -{ - delete timeLine; + QPropertyAnimation *headAnimation = new QPropertyAnimation(headItem, "rotation"); + headAnimation->setStartValue(20); + headAnimation->setEndValue(-20); + QPropertyAnimation *headScaleAnimation = new QPropertyAnimation(headItem, "scale"); + headScaleAnimation->setEndValue(1.1); + animation->addAnimation(headAnimation); + animation->addAnimation(headScaleAnimation); +//! [12] + + QPropertyAnimation *upperLeftArmAnimation = new QPropertyAnimation(upperLeftArmItem, "rotation"); + upperLeftArmAnimation->setStartValue(190); + upperLeftArmAnimation->setEndValue(180); + animation->addAnimation(upperLeftArmAnimation); + + QPropertyAnimation *lowerLeftArmAnimation = new QPropertyAnimation(lowerLeftArmItem, "rotation"); + lowerLeftArmAnimation->setStartValue(50); + lowerLeftArmAnimation->setEndValue(10); + animation->addAnimation(lowerLeftArmAnimation); + + QPropertyAnimation *upperRightArmAnimation = new QPropertyAnimation(upperRightArmItem, "rotation"); + upperRightArmAnimation->setStartValue(300); + upperRightArmAnimation->setEndValue(310); + animation->addAnimation(upperRightArmAnimation); + + QPropertyAnimation *lowerRightArmAnimation = new QPropertyAnimation(lowerRightArmItem, "rotation"); + lowerRightArmAnimation->setStartValue(0); + lowerRightArmAnimation->setEndValue(-70); + animation->addAnimation(lowerRightArmAnimation); + + QPropertyAnimation *upperLeftLegAnimation = new QPropertyAnimation(upperLeftLegItem, "rotation"); + upperLeftLegAnimation->setStartValue(150); + upperLeftLegAnimation->setEndValue(80); + animation->addAnimation(upperLeftLegAnimation); + + QPropertyAnimation *lowerLeftLegAnimation = new QPropertyAnimation(lowerLeftLegItem, "rotation"); + lowerLeftLegAnimation->setStartValue(70); + lowerLeftLegAnimation->setEndValue(10); + animation->addAnimation(lowerLeftLegAnimation); + + QPropertyAnimation *upperRightLegAnimation = new QPropertyAnimation(upperRightLegItem, "rotation"); + upperRightLegAnimation->setStartValue(40); + upperRightLegAnimation->setEndValue(120); + animation->addAnimation(upperRightLegAnimation); + + QPropertyAnimation *lowerRightLegAnimation = new QPropertyAnimation(lowerRightLegItem, "rotation"); + lowerRightLegAnimation->setStartValue(10); + lowerRightLegAnimation->setEndValue(50); + animation->addAnimation(lowerRightLegAnimation); + + QPropertyAnimation *torsoAnimation = new QPropertyAnimation(torsoItem, "rotation"); + torsoAnimation->setStartValue(5); + torsoAnimation->setEndValue(-20); + animation->addAnimation(torsoAnimation); + +//! [13] + for (int i = 0; i < animation->animationCount(); ++i) { + QPropertyAnimation *anim = qobject_cast(animation->animationAt(i)); + anim->setEasingCurve(QEasingCurve::SineCurve); + anim->setDuration(2000); + } + + animation->setLoopCount(-1); + animation->start(); +//! [13] } +//! [9] QRectF Robot::boundingRect() const { return QRectF(); @@ -271,3 +305,4 @@ void Robot::paint(QPainter *painter, Q_UNUSED(option); Q_UNUSED(widget); } +//! [9] diff --git a/examples/graphicsview/dragdroprobot/robot.h b/examples/graphicsview/dragdroprobot/robot.h index 88c4364..f5ff32c 100644 --- a/examples/graphicsview/dragdroprobot/robot.h +++ b/examples/graphicsview/dragdroprobot/robot.h @@ -46,10 +46,11 @@ QT_BEGIN_NAMESPACE class QGraphicsSceneMouseEvent; -class QTimeLine; +class QParallelAnimationGroup; QT_END_NAMESPACE -class RobotPart : public QGraphicsItem +//! [0] +class RobotPart : public QGraphicsObject { public: RobotPart(QGraphicsItem *parent = 0); @@ -59,11 +60,12 @@ protected: void dragLeaveEvent(QGraphicsSceneDragDropEvent *event); void dropEvent(QGraphicsSceneDragDropEvent *event); - QPixmap pixmap; QColor color; bool dragOver; }; +//! [0] +//! [1] class RobotHead : public RobotPart { public: @@ -72,10 +74,16 @@ public: QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); - enum { Type = UserType + 1 }; - int type() const; +protected: + void dragEnterEvent(QGraphicsSceneDragDropEvent *event); + void dropEvent(QGraphicsSceneDragDropEvent *event); + +private: + QPixmap pixmap; }; +//! [1] +//! [2] class RobotTorso : public RobotPart { public: @@ -84,7 +92,9 @@ public: QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); }; +//! [2] +//! [3] class RobotLimb : public RobotPart { public: @@ -93,18 +103,17 @@ public: QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); }; +//! [3] +//! [4] class Robot : public RobotPart { public: - Robot(); - ~Robot(); + Robot(QGraphicsItem *parent = 0); QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); - -private: - QTimeLine *timeLine; }; +//! [4] #endif -- cgit v0.12 From 9b67f0b314b249b5bb7db2b9fe13f8e874f2a200 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 28 Apr 2010 17:39:19 +0200 Subject: qmake: fix duplicate compiler options in VS project files We don't have to evaluate QMAKE_CXX_FLAGS_WARN_ON / ..._OFF mkspecs/features/warn_on.prf / ..._off.prf do it for us. Reviewed-by: andy --- qmake/generators/win32/msvc_vcproj.cpp | 4 ---- qmake/generators/win32/msvc_vcxproj.cpp | 4 ---- 2 files changed, 8 deletions(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 8c9bba8..6cc8272 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -934,10 +934,6 @@ void VcprojGenerator::initCompilerTool() } // Common for both release and debug - if(project->isActiveConfig("warn_off")) - conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_WARN_OFF")); - else if(project->isActiveConfig("warn_on")) - conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_WARN_ON")); if(project->isActiveConfig("windows")) conf.compiler.PreprocessorDefinitions += project->values("MSVCPROJ_WINCONDEF"); diff --git a/qmake/generators/win32/msvc_vcxproj.cpp b/qmake/generators/win32/msvc_vcxproj.cpp index 6a91c6b..92caa31 100644 --- a/qmake/generators/win32/msvc_vcxproj.cpp +++ b/qmake/generators/win32/msvc_vcxproj.cpp @@ -311,10 +311,6 @@ void VcxprojGenerator::initCompilerTool() } // Common for both release and debug - if(project->isActiveConfig("warn_off")) - conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_WARN_OFF")); - else if(project->isActiveConfig("warn_on")) - conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_WARN_ON")); if(project->isActiveConfig("windows")) conf.compiler.PreprocessorDefinitions += project->values("MSVCPROJ_WINCONDEF"); -- cgit v0.12 From e24b4b83fa4e71ab137ac254a9c69fec672d5e66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Thu, 29 Apr 2010 09:11:02 +0200 Subject: Ensured that WA_InputMethodEnabled was set before FocusInEvent was sent. When focusInEvent is called we need to ensure that WA_InputMethodEnabled is set, since FocusInEvent might lead to that QInputContext::setFocusWidget is called (with the QGraphicsView as the widget parameter). However, if the widget still does not have WA_InputMethodEnabled set yet it will assert in QInputContext::setFocusWidget (it requires that the widget has the flag set). This was a problem for the morbit bridge, where Dui requires the attribute to be set (while Orbit actually does not require) Task-number: QTBUG-10276 Reviewed-by: jasplin Reviewed-by: Alexis Menard --- src/gui/graphicsview/qgraphicsscene.cpp | 6 +++--- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 26 ++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index bd0f0d8..8cee021 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -820,13 +820,13 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item, #endif //QT_NO_IM } - if (item) { + if (item) focusItem = item; + updateInputMethodSensitivityInViews(); + if (item) { QFocusEvent event(QEvent::FocusIn, focusReason); sendEvent(item, &event); } - - updateInputMethodSensitivityInViews(); } /*! diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 5e889f4..d0752af 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -3665,6 +3665,22 @@ void tst_QGraphicsView::update() #endif } +class FocusItem : public QGraphicsRectItem +{ +public: + FocusItem() : QGraphicsRectItem(0, 0, 20, 20) { + m_viewHasIMEnabledInFocusInEvent = false; + } + + void focusInEvent(QFocusEvent *event) + { + QGraphicsView *view = scene()->views().first(); + m_viewHasIMEnabledInFocusInEvent = view->testAttribute(Qt::WA_InputMethodEnabled); + } + + bool m_viewHasIMEnabledInFocusInEvent; +}; + void tst_QGraphicsView::inputMethodSensitivity() { QGraphicsScene scene; @@ -3674,7 +3690,7 @@ void tst_QGraphicsView::inputMethodSensitivity() QApplication::setActiveWindow(&view); QTRY_COMPARE(QApplication::activeWindow(), static_cast(&view)); - QGraphicsRectItem *item = new QGraphicsRectItem; + FocusItem *item = new FocusItem; view.setAttribute(Qt::WA_InputMethodEnabled, true); @@ -3703,6 +3719,7 @@ void tst_QGraphicsView::inputMethodSensitivity() scene.setFocusItem(item); QCOMPARE(scene.focusItem(), static_cast(item)); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + QCOMPARE(item->m_viewHasIMEnabledInFocusInEvent, true); item->setFlag(QGraphicsItem::ItemAcceptsInputMethod, false); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); @@ -3711,15 +3728,17 @@ void tst_QGraphicsView::inputMethodSensitivity() QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); // introduce another item that is focusable but does not accept input methods - QGraphicsRectItem *item2 = new QGraphicsRectItem; + FocusItem *item2 = new FocusItem; item2->setFlag(QGraphicsItem::ItemIsFocusable); scene.addItem(item2); scene.setFocusItem(item2); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + QCOMPARE(item2->m_viewHasIMEnabledInFocusInEvent, false); QCOMPARE(scene.focusItem(), static_cast(item2)); scene.setFocusItem(item); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + QCOMPARE(item->m_viewHasIMEnabledInFocusInEvent, true); QCOMPARE(scene.focusItem(), static_cast(item)); view.setScene(0); @@ -3728,10 +3747,12 @@ void tst_QGraphicsView::inputMethodSensitivity() view.setScene(&scene); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + QCOMPARE(item->m_viewHasIMEnabledInFocusInEvent, true); QCOMPARE(scene.focusItem(), static_cast(item)); scene.setFocusItem(item2); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false); + QCOMPARE(item2->m_viewHasIMEnabledInFocusInEvent, false); QCOMPARE(scene.focusItem(), static_cast(item2)); view.setScene(0); @@ -3744,6 +3765,7 @@ void tst_QGraphicsView::inputMethodSensitivity() view.setScene(&scene); QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true); + QCOMPARE(item->m_viewHasIMEnabledInFocusInEvent, true); QCOMPARE(scene.focusItem(), static_cast(item)); } -- cgit v0.12 From 1f5e2724e788e53ede53a7e9ee4e08f4ad3ccc51 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 28 Apr 2010 17:48:14 +0200 Subject: qmake: fix duplicate linker options in VS project files We don't have to evaluate QMAKE_FLAGS_CONSOLE or QMAKE_LFLAGS_WINDOWS. These files do it for us: mkspecs/features/win32/console.prf mkspecs/features/win32/windows.prf Reviewed-by: andy --- qmake/generators/win32/msvc_vcproj.cpp | 7 ------- qmake/generators/win32/msvc_vcxproj.cpp | 7 ------- 2 files changed, 14 deletions(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 6cc8272..1b4e51b 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1005,13 +1005,6 @@ void VcprojGenerator::initLinkerTool() if(project->isActiveConfig("dll")){ conf.linker.parseOptions(project->values("QMAKE_LFLAGS_QT_DLL")); } - - if(project->isActiveConfig("console")){ - conf.linker.parseOptions(project->values("QMAKE_LFLAGS_CONSOLE")); - } else { - conf.linker.parseOptions(project->values("QMAKE_LFLAGS_WINDOWS")); - } - } void VcprojGenerator::initResourceTool() diff --git a/qmake/generators/win32/msvc_vcxproj.cpp b/qmake/generators/win32/msvc_vcxproj.cpp index 92caa31..85239fe 100644 --- a/qmake/generators/win32/msvc_vcxproj.cpp +++ b/qmake/generators/win32/msvc_vcxproj.cpp @@ -368,13 +368,6 @@ void VcxprojGenerator::initLinkerTool() if(project->isActiveConfig("dll")){ conf.linker.parseOptions(project->values("QMAKE_LFLAGS_QT_DLL")); } - - if(project->isActiveConfig("console")){ - conf.linker.parseOptions(project->values("QMAKE_LFLAGS_CONSOLE")); - } else { - conf.linker.parseOptions(project->values("QMAKE_LFLAGS_WINDOWS")); - } - } void VcxprojGenerator::initResourceTool() -- cgit v0.12 From 4d312a6e635ce0cde0ae5c439541f315d7fddff3 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Thu, 29 Apr 2010 12:39:13 +0200 Subject: Documentation for the Elastic Nodes example. Checked for qdoc errors. --- doc/src/examples/elasticnodes.qdoc | 391 ++++++++++++++++++++- doc/src/getting-started/examples.qdoc | 2 +- examples/graphicsview/elasticnodes/edge.cpp | 30 +- examples/graphicsview/elasticnodes/edge.h | 6 +- examples/graphicsview/elasticnodes/graphwidget.cpp | 34 +- examples/graphicsview/elasticnodes/graphwidget.h | 4 +- examples/graphicsview/elasticnodes/node.cpp | 46 ++- examples/graphicsview/elasticnodes/node.h | 2 + 8 files changed, 471 insertions(+), 44 deletions(-) diff --git a/doc/src/examples/elasticnodes.qdoc b/doc/src/examples/elasticnodes.qdoc index f7b1c37..edc62d8 100644 --- a/doc/src/examples/elasticnodes.qdoc +++ b/doc/src/examples/elasticnodes.qdoc @@ -43,7 +43,396 @@ \example graphicsview/elasticnodes \title Elastic Nodes Example - This GraphicsView example shows how to implement edges between nodes in a graph. + This GraphicsView example shows how to implement edges between nodes in a + graph, with basic interaction. You can click to drag a node around, and + zoom in and out using the mouse wheel or the keyboard. Hitting the space + bar will randomize the nodes. The example is also resolution independent; + as you zoom in, the graphics remain crisp. \image elasticnodes-example.png + + Graphics View provides the QGraphicsScene class for managing and + interacting with a large number of custom-made 2D graphical items derived + from the QGraphicsItem class, and a QGraphicsView widget for visualizing + the items, with support for zooming and rotation. + + This example consists of a \c Node class, an \c Edge class, a \c + GraphWidget test, and a \c main function: the \c Node class represents + draggable yellow nodes in a grid, the \c Edge class represents the lines + between the nodes, the \c GraphWidget class represents the application + window, and the \c main() function creates and shows this window, and runs + the event loop. + + \section1 Node Class Definition + + The \c Node class serves three purposes: + + \list + \o Painting a yellow gradient "ball" in two states: sunken and raised. + \o Managing connections to other nodes. + \o Calculating forces pulling and pushing the nodes in the grid. + \endlist + + Let's start by looking at the \c Node class declaration. + + \snippet examples/graphicsview/elasticnodes/node.h 0 + + The \c Node class inherits QGraphicsItem, and reimplements the two + mandatory functions \l{QGraphicsItem::boundingRect()}{boundingRect()} and + \l{QGraphicsItem::paint()}{paint()} to provide its visual appearance. It + also reimplements \l{QGraphicsItem::shape()}{shape()} to ensure its hit + area has an elliptic shape (as opposed to the default bounding rectangle). + + For edge management purposes the node provides a simple API for adding + edges to a node, and for listing all connected edges. + + The \l{QGraphicsItem::advance()}{advance()} reimplementation is called + whenever the scene's state advances by one step. The calculateForces() + function is called to calculate the forces that push and pull on this node + and its neighbors. + + The \c Node class also reimplements + \l{QGraphicsItem::itemChange()}{itemChange()} to react to state changes (in + this case, position changes), and + \l{QGraphicsItem::mousePressEvent()}{mousePressEvent()} and + \l{QGraphicsItem::mouseReleaseEvent()}{mouseReleaseEvent()} to update the + item's visual appearance. + + We will start reviewing the \c Node implementation by looking at its + constructor: + + \snippet examples/graphicsview/elasticnodes/node.cpp 0 + + In the constructor, we set the + \l{QGraphicsItem::ItemIsMovable}{ItemIsMovable} flag to allow the item to + move in response to mouse dragging, and + \l{QGraphicsItem::ItemSendsGeometryChanges}{ItemSendsGeometryChanges} to + enable \l{QGraphicsItem::itemChange()}{itemChange()} notifications for + position and transformation changes. We also enable + \l{QGraphicsItem::DeviceCoordinateCache}{DeviceCoordinateCache} to speed up + rendering performance. To ensure that the nodes are always stacked on top + of edges, we finally set the item's Z value to -1. + + \c Node's constructor takes a \c GraphWidget pointer and stores this as a + member variable. We will revisit this pointer later on. + + \snippet examples/graphicsview/elasticnodes/node.cpp 1 + + The addEdge() function adds the input edge to a list of attached edges. The + edge is then adjusted so that the end points for the edge match the + positions of the source and destination nodes. + + The edges() function simply returns the list of attached edges. + + \snippet examples/graphicsview/elasticnodes/node.cpp 2 + + The \e calculateForces() function implements the elastic forces effect that + pulls and pushes on nodes in the grid. In addition to this algorithm, the + user can move one node around with the mouse. Because we do not want the + two to interfere, we start by checking if this \c Node is the current mouse + grabber item (i.e., QGraphicsScene::mouseGrabberItem()). Because we need to + find all neighboring (but not necessarily connected) nodes, we also make + sure the item is part of a scene in the first place. + + \snippet examples/graphicsview/elasticnodes/node.cpp 3 + + The algorithm has two steps: the first is to calculate the forces that push + the nodes apart, and the second is to subtract the forces that pull the + nodes together. First we need to find all the nodes in the graph. We call + QGraphicsScene::items() to find all items in the scene, and then use + qgraphicsitem_cast() to look for \c Node instances. + + We make use of \l{QGraphicsItem::mapFromItem()}{mapFromItem()} to create a + vector pointing from this node to each other node, in \l{The Graphics View + Coordinate System}{local coordinates}. We use the decomposed components of + this vector to determine the direction and strength of force that apply to + the node. The forces are added up for each node, and weighted so that the + closest nodes are given the strongest force. The sum of all forces are + stored in \e xvel (X-velocity) and \e yvel (Y-velocity). + + \snippet examples/graphicsview/elasticnodes/node.cpp 4 + + The edges between the nodes represent the forces that pull the nodes + together. By visiting each edge that is connected to this node, we can use + a similar approach as above to find the direction and strength of all + forces. These forces are subtracted from \e xvel and \e yvel. + + \snippet examples/graphicsview/elasticnodes/node.cpp 5 + + In theory, the sum of pushing and pulling forces should stabilize to + precisely 0. In practise, however, they never do. To circumvent errors in + numerical precision, we simply force the sum of forces to be 0 when they + are less than 0.1. + + \snippet examples/graphicsview/elasticnodes/node.cpp 6 + + The final step of \e calculateForces() determines the node's new position. + We add the force to the node's current position. We also make sure the new + position stays inside of our defined boundaries. We don't actually move the + item in this function; that's done in a separate step, from \e advance(). + + \snippet examples/graphicsview/elasticnodes/node.cpp 7 + + The \e advance() function updates the item's current position. It is called + from \e GraphWidget::timerEvent(). If the node's position changed, the + function returns true; otherwise false is returned. + + \snippet examples/graphicsview/elasticnodes/node.cpp 8 + + The \e Node's bounding rectangle is a 20x20 sized rectangle centered around + its origin (0, 0), adjusted by 2 units in all directions to compensate for + the node's outline stroke, and by 3 units down and to the right to make + room for a simple drop shadow. + + \snippet examples/graphicsview/elasticnodes/node.cpp 9 + + The shape is a simple ellipse. This ensures that you must click inside the + node's elliptic shape in order to drag it around. You can test this effect + by running the example, and zooming far enough in so that the nodes become + very large. Without reimplementing \l{QGraphicsItem::shape()}{shape()}, the + item's hit area would be identical to its bounding rectangle (i.e., + rectangular). + + \snippet examples/graphicsview/elasticnodes/node.cpp 10 + + This function implements the node's painting. We start by drawing a simple + dark gray elliptic drop shadow at (-7, -7), that is, (3, 3) units down and + to the right. + + We then draw an ellipse with a radial gradient fill. This fill is either + Qt::yellow to Qt::darkYellow when raised, or the opposite when sunken. In + sunken state we also shift the center and focal point by (3, 3) to + emphasize the impression that something has been pushed down. + + Drawing filled ellipses with gradients can be quite slow, especially when + using complex gradients such as QRadialGradient. This is why this example + uses \l{QGraphicsItem::DeviceCoordinateCache}{DeviceCoordinateCache}, a + simple yet effective measure that prevents unnecessary redrawing. + + \snippet examples/graphicsview/elasticnodes/node.cpp 11 + + We reimplement \l{QGraphicsItem::itemChange()}{itemChange()} to adjust the + position of all connected edges, and to notify the scene that an item has + moved (i.e., "something has happened"). This will trigger new force + calculations. + + This notification is the only reason why the nodes need to keep a pointer + back to the \e GraphWidget. Another approach could be to provide such + notification using a signal; in such case, \e Node would need to inherit + from QGraphicsObject. + + \snippet examples/graphicsview/elasticnodes/node.cpp 12 + + Because we have set the \l{QGraphicsItem::ItemIsMovable}{ItemIsMovable} + flag, we don't need to implement the logic that moves the node according to + mouse input; this is already provided for us. We still need to reimplement + the mouse press and release handlers though, to update the nodes' visual + appearance (i.e., sunken or raised). + + \section1 Edge Class Definition + + The \e Edge class represents the arrow-lines between the nodes in this + example. The class is very simple: it maintains a source- and destination + node pointer, and provides an \e adjust() function that makes sure the line + starts at the position of the source, and ends at the position of the + destination. The edges are the only items that change continuously as + forces pull and push on the nodes. + + Let's take a look at the class declaration: + + \snippet examples/graphicsview/elasticnodes/edge.h 0 + + \e Edge inherits from QGraphicsItem, as it's a simple class that has no use + for signals, slots, and properties (compare to QGraphicsObject). + + The constructor takes two node pointers as input. Both pointers are + mandatory in this example. We also provide get-functions for each node. + + The \e adjust() function repositions the edge, and the item also implements + \l{QGraphicsItem::boundingRect()}{boundingRect()} and + \{QGraphicsItem::paint()}{paint()}. + + We will now review its implementation. + + \snippet examples/graphicsview/elasticnodes/edge.cpp 0 + + The \e Edge constructor initializes its arrowSize data member to 10 units; + this determines the size of the arrow which is drawn in + \l{QGraphicsItem::paint()}{paint()}. + + In the constructor body, we call + \l{QGraphicsItem::setAcceptedMouseButtons()}{setAcceptedMouseButtons(0)}. + This ensures that the edge items are not considered for mouse input at all + (i.e., you cannot click the edges). Then, the source and destination + pointers are updated, this edge is registered with each node, and we call + \e adjust() to update this edge's start end end position. + + \snippet examples/graphicsview/elasticnodes/edge.cpp 1 + + The source and destination get-functions simply return the respective + pointers. + + \snippet examples/graphicsview/elasticnodes/edge.cpp 2 + + In \e adjust(), we define two points: \e sourcePoint, and \e destPoint, + pointing at the source and destination nodes' origins respectively. Each + point is calculated using \l{The Graphics View Coordinate System}{local + coordinates}. + + We want the tip of the edge's arrows to point to the exact outline of the + nodes, as opposed to the center of the nodes. To find this point, we first + decompose the vector pointing from the center of the source to the center + of the destination node into X and Y, and then normalize the components by + dividing by the length of the vector. This gives us an X and Y unit delta + that, when multiplied by the radius of the node (which is 10), gives us the + offset that must be added to one point of the edge, and subtracted from the + other. + + If the length of the vector is less than 20 (i.e., if two nodes overlap), + then we fix the source and destination pointer at the center of the source + node. In practise this case is very hard to reproduce manually, as the + forces between the two nodes is then at its maximum. + + It's important to notice that we call + \l{QGraphicsItem::prepareGeometryChange()}{prepareGeometryChange()} in this + function. The reason is that the variables \e sourcePoint and \e destPoint + are used directly when painting, and they are returned from the + \l{QGraphicsItem::boundingRect()}{boundingRect()} reimplementation. We must + always call + \l{QGraphicsItem::prepareGeometryChange()}{prepareGeometryChange()} before + changing what \l{QGraphicsItem::boundingRect()}{boundingRect()} returns, + and before these variables can be used by + \l{QGraphicsItem::paint()}{paint()}, to keep Graphics View's internal + bookkeeping clean. It's safest to call this function once, immediately + before any such variable is modified. + + \snippet examples/graphicsview/elasticnodes/edge.cpp 3 + + The edge's bounding rectangle is defined as the smallest rectangle that + includes both the start and the end point of the edge. Because we draw an + arrow on each edge, we also need to compensate by adjusting with half the + arrow size and half the pen width in all directions. The pen is used to + draw the outline of the arrow, and we can assume that half of the outline + can be drawn outside of the arrow's area, and half will be drawn inside. + + \snippet examples/graphicsview/elasticnodes/edge.cpp 4 + + We start the reimplementation of \l{QGraphicsItem::paint()}{paint()} by + checking a few preconditions. Firstly, if either the source or destination + node is not set, then we return immediately; there is nothing to draw. + + At the same time, we check if the length of the edge is approximately 0, + and if it is, then we also return. + + \snippet examples/graphicsview/elasticnodes/edge.cpp 5 + + We draw the line using a pen that has round joins and caps. If you run the + example, zoom in and study the edge in detail, you will see that there are + no sharp/square edges. + + \snippet examples/graphicsview/elasticnodes/edge.cpp 6 + + We proceed to drawing one arrow at each end of the edge. Each arrow is + drawn as a polygon with a black fill. The coordinates for the arrow are + determined using simple trigonometry. + + \section1 GraphWidget Class Definition + + \e GraphWidget is a subclass of QGraphicsView, which provides the main + window with scrollbars. + + \snippet examples/graphicsview/elasticnodes/graphwidget.h 0 + + It provides a basic constructor that initializes the scene, an \e + itemMoved() function to notify changes in the scene's node graph, a few + event handlers, a reimplementation of + \l{QGraphicsView::drawBackground()}{drawBackground()}, and a helper + function for scaling the view by mouse or keyboard. + + \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 0 + + \e GraphicsWidget's constructor creates the scene, and because most items + move around most of the time, it sets QGraphicsScene::NoIndex. Then the + scene gets a fixed \l{QGraphicsScene::sceneRect}{scene rectangle}. + The scene is then assigned to the \e GraphWidget view. + + The view enables QGraphicsView::CacheBackground to cache rendering of its + static and somewhat complex background. Because the graph renders a close + collection of small items that all move around, it's unnecessary for + Graphics View to waste time finding accurate update regions, so we set the + QGraphicsView::BoundingRectViewportUpdate viewport update mode. The default + would work fine, but this mode is noticably faster for this example. + + To improve rendering quality, we set QPainter::Antialiasing. + + The transformation anchor decides how the view should scroll when you + transform the view, or in our case, when we zoom in or out. We have chosen + QGraphicsView::AnchorUnderMouse, which centers the view on the point under + the mouse cursor. This makes it easy to zoom towards a point in the scene + by moving the mouse over it, and then rolling the mouse wheel. + + Finally we give the window a minimum size that matches the scene's default + size, and set a suitable window title. + + \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 1 + + The last part of the constructor creates the grid of nodes and edges, and + gives each node an initial position. + + \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 2 + + \e GraphWidget is notified of node movement through this \e itemMoved() + function. Its job is simply to restart the main timer in case it's not + running already. The timer is designed to stop when the graph stabilizes, + and start once it's unstable again. + + \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 3 + + This is \e GraphWidget's key event handler. The arrow keys move the center + node around, the '+' and '-' keys zoom in and out by calling \e + scaleView(), and the enter and space keys randomize the positions of the + nodes. All other key events (e.g., page up and page down) are handled by + QGraphicsView's default implementation. + + \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 4 + + The timer event handler's job is to run the whole force calculation + machinery as a smooth animation. Each time the timer is triggered, the + handler will find all nodes in the scene, and call \e + Node::calculateForces() on each node, one at a time. Then, in a final step + it will call \e Node::advance() to move all nodes to their new positions. + By checking the return value of \e advance(), we can decide if the grid + stabilized (i.e., no nodes moved). If so, we can stop the timer. + + \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 5 + + In the wheel event handler, we convert the mouse wheel delta to a scale + factor, and pass this factor to \e scaleView(). This approach takes into + account the speed that the wheel is rolled. The faster you roll the mouse + wheel, the faster the view will zoom. + + \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 6 + + The view's background is rendered in a reimplementation of + QGraphicsView::drawBackground(). We draw a large rectangle filled with a + linear gradient, with a drop shadow, and then render text in top. The text + is rendered twice to give a similar simple drop-shadow effect. + + This background rendering is quite expensive; this is why the view enables + QGraphicsView::CacheBackground. + + \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 7 + + The \e scaleView() helper function checks that the scale factor stays + within certain limits (i.e., you cannot zoom too far in nor too far out), + and then applies this scale. + + \section1 The main() Function + + In contrast to the complexity of the rest of this example, the \e main() + function is very simple: We create a QApplication instance, seed the + randomizer using qsrand(), and then create and show an instance of \e + GraphWidget. Because all nodes in the grid are moved initially, the \e + GraphWidget timer will start immediately after control has returned to the + event loop. */ diff --git a/doc/src/getting-started/examples.qdoc b/doc/src/getting-started/examples.qdoc index c96c70f..542f672 100644 --- a/doc/src/getting-started/examples.qdoc +++ b/doc/src/getting-started/examples.qdoc @@ -650,7 +650,7 @@ \o \l{graphicsview/collidingmice}{Colliding Mice}\raisedaster \o \l{graphicsview/diagramscene}{Diagram Scene}\raisedaster \o \l{graphicsview/dragdroprobot}{Drag and Drop Robot}\raisedaster - \o \l{graphicsview/elasticnodes}{Elastic Nodes} + \o \l{graphicsview/elasticnodes}{Elastic Nodes}\raisedaster \o \l{graphicsview/portedasteroids}{Ported Asteroids} \o \l{graphicsview/portedcanvas}{Ported Canvas} \endlist diff --git a/examples/graphicsview/elasticnodes/edge.cpp b/examples/graphicsview/elasticnodes/edge.cpp index 25c769b..634fbee 100644 --- a/examples/graphicsview/elasticnodes/edge.cpp +++ b/examples/graphicsview/elasticnodes/edge.cpp @@ -49,6 +49,7 @@ static const double Pi = 3.14159265358979323846264338327950288419717; static double TwoPi = 2.0 * Pi; +//! [0] Edge::Edge(Node *sourceNode, Node *destNode) : arrowSize(10) { @@ -59,33 +60,21 @@ Edge::Edge(Node *sourceNode, Node *destNode) dest->addEdge(this); adjust(); } +//! [0] -Edge::~Edge() -{ -} - +//! [1] Node *Edge::sourceNode() const { return source; } -void Edge::setSourceNode(Node *node) -{ - source = node; - adjust(); -} - Node *Edge::destNode() const { return dest; } +//! [1] -void Edge::setDestNode(Node *node) -{ - dest = node; - adjust(); -} - +//! [2] void Edge::adjust() { if (!source || !dest) @@ -104,7 +93,9 @@ void Edge::adjust() sourcePoint = destPoint = line.p1(); } } +//! [2] +//! [3] QRectF Edge::boundingRect() const { if (!source || !dest) @@ -118,7 +109,9 @@ QRectF Edge::boundingRect() const .normalized() .adjusted(-extra, -extra, extra, extra); } +//! [3] +//! [4] void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { if (!source || !dest) @@ -127,11 +120,15 @@ void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) QLineF line(sourcePoint, destPoint); if (qFuzzyCompare(line.length(), qreal(0.))) return; +//! [4] +//! [5] // Draw the line itself painter->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->drawLine(line); +//! [5] +//! [6] // Draw the arrows double angle = ::acos(line.dx() / line.length()); if (line.dy() >= 0) @@ -150,3 +147,4 @@ void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) painter->drawPolygon(QPolygonF() << line.p1() << sourceArrowP1 << sourceArrowP2); painter->drawPolygon(QPolygonF() << line.p2() << destArrowP1 << destArrowP2); } +//! [6] diff --git a/examples/graphicsview/elasticnodes/edge.h b/examples/graphicsview/elasticnodes/edge.h index b6b951f..58cc89c 100644 --- a/examples/graphicsview/elasticnodes/edge.h +++ b/examples/graphicsview/elasticnodes/edge.h @@ -46,17 +46,14 @@ class Node; +//! [0] class Edge : public QGraphicsItem { public: Edge(Node *sourceNode, Node *destNode); - ~Edge(); Node *sourceNode() const; - void setSourceNode(Node *node); - Node *destNode() const; - void setDestNode(Node *node); void adjust(); @@ -74,5 +71,6 @@ private: QPointF destPoint; qreal arrowSize; }; +//! [0] #endif diff --git a/examples/graphicsview/elasticnodes/graphwidget.cpp b/examples/graphicsview/elasticnodes/graphwidget.cpp index 7c244be..8b419b8 100644 --- a/examples/graphicsview/elasticnodes/graphwidget.cpp +++ b/examples/graphicsview/elasticnodes/graphwidget.cpp @@ -43,14 +43,13 @@ #include "edge.h" #include "node.h" -#include -#include -#include +#include #include -GraphWidget::GraphWidget() - : timerId(0) +//! [0] +GraphWidget::GraphWidget(QWidget *parent) + : QGraphicsView(parent), timerId(0) { QGraphicsScene *scene = new QGraphicsScene(this); scene->setItemIndexMethod(QGraphicsScene::NoIndex); @@ -60,8 +59,12 @@ GraphWidget::GraphWidget() setViewportUpdateMode(BoundingRectViewportUpdate); setRenderHint(QPainter::Antialiasing); setTransformationAnchor(AnchorUnderMouse); - setResizeAnchor(AnchorViewCenter); + scale(qreal(0.8), qreal(0.8)); + setMinimumSize(400, 400); + setWindowTitle(tr("Elastic Nodes")); +//! [0] +//! [1] Node *node1 = new Node(this); Node *node2 = new Node(this); Node *node3 = new Node(this); @@ -102,18 +105,18 @@ GraphWidget::GraphWidget() node7->setPos(-50, 50); node8->setPos(0, 50); node9->setPos(50, 50); - - scale(qreal(0.8), qreal(0.8)); - setMinimumSize(400, 400); - setWindowTitle(tr("Elastic Nodes")); } +//! [1] +//! [2] void GraphWidget::itemMoved() { if (!timerId) timerId = startTimer(1000 / 25); } +//! [2] +//! [3] void GraphWidget::keyPressEvent(QKeyEvent *event) { switch (event->key()) { @@ -146,7 +149,9 @@ void GraphWidget::keyPressEvent(QKeyEvent *event) QGraphicsView::keyPressEvent(event); } } +//! [3] +//! [4] void GraphWidget::timerEvent(QTimerEvent *event) { Q_UNUSED(event); @@ -171,12 +176,16 @@ void GraphWidget::timerEvent(QTimerEvent *event) timerId = 0; } } +//! [4] +//! [5] void GraphWidget::wheelEvent(QWheelEvent *event) { scaleView(pow((double)2, -event->delta() / 240.0)); } +//! [5] +//! [6] void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect) { Q_UNUSED(rect); @@ -213,12 +222,15 @@ void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect) painter->setPen(Qt::black); painter->drawText(textRect, message); } +//! [6] +//! [7] void GraphWidget::scaleView(qreal scaleFactor) { - qreal factor = matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width(); + qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width(); if (factor < 0.07 || factor > 100) return; scale(scaleFactor, scaleFactor); } +//! [7] diff --git a/examples/graphicsview/elasticnodes/graphwidget.h b/examples/graphicsview/elasticnodes/graphwidget.h index 6f67b4e..3f78a5f 100644 --- a/examples/graphicsview/elasticnodes/graphwidget.h +++ b/examples/graphicsview/elasticnodes/graphwidget.h @@ -46,12 +46,13 @@ class Node; +//! [0] class GraphWidget : public QGraphicsView { Q_OBJECT public: - GraphWidget(); + GraphWidget(QWidget *parent = 0); void itemMoved(); @@ -67,5 +68,6 @@ private: int timerId; Node *centerNode; }; +//! [0] #endif diff --git a/examples/graphicsview/elasticnodes/node.cpp b/examples/graphicsview/elasticnodes/node.cpp index 774046c..495aa89 100644 --- a/examples/graphicsview/elasticnodes/node.cpp +++ b/examples/graphicsview/elasticnodes/node.cpp @@ -48,6 +48,7 @@ #include "node.h" #include "graphwidget.h" +//! [0] Node::Node(GraphWidget *graphWidget) : graph(graphWidget) { @@ -56,7 +57,9 @@ Node::Node(GraphWidget *graphWidget) setCacheMode(DeviceCoordinateCache); setZValue(-1); } +//! [0] +//! [1] void Node::addEdge(Edge *edge) { edgeList << edge; @@ -67,14 +70,18 @@ QList Node::edges() const { return edgeList; } +//! [1] +//! [2] void Node::calculateForces() { if (!scene() || scene()->mouseGrabberItem() == this) { newPos = pos(); return; } - +//! [2] + +//! [3] // Sum up all forces pushing this item away qreal xvel = 0; qreal yvel = 0; @@ -83,37 +90,45 @@ void Node::calculateForces() if (!node) continue; - QLineF line(mapFromItem(node, 0, 0), QPointF(0, 0)); - qreal dx = line.dx(); - qreal dy = line.dy(); + QPointF vec = mapToItem(node, 0, 0); + qreal dx = vec.x(); + qreal dy = vec.y(); double l = 2.0 * (dx * dx + dy * dy); if (l > 0) { xvel += (dx * 150.0) / l; yvel += (dy * 150.0) / l; } } +//! [3] +//! [4] // Now subtract all forces pulling items together double weight = (edgeList.size() + 1) * 10; foreach (Edge *edge, edgeList) { - QPointF pos; + QPointF vec; if (edge->sourceNode() == this) - pos = mapFromItem(edge->destNode(), 0, 0); + vec = mapToItem(edge->destNode(), 0, 0); else - pos = mapFromItem(edge->sourceNode(), 0, 0); - xvel += pos.x() / weight; - yvel += pos.y() / weight; + vec = mapToItem(edge->sourceNode(), 0, 0); + xvel -= vec.x() / weight; + yvel -= vec.y() / weight; } - +//! [4] + +//! [5] if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1) xvel = yvel = 0; +//! [5] +//! [6] QRectF sceneRect = scene()->sceneRect(); newPos = pos() + QPointF(xvel, yvel); newPos.setX(qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10)); newPos.setY(qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10)); } +//! [6] +//! [7] bool Node::advance() { if (newPos == pos()) @@ -122,21 +137,27 @@ bool Node::advance() setPos(newPos); return true; } +//! [7] +//! [8] QRectF Node::boundingRect() const { qreal adjust = 2; return QRectF(-10 - adjust, -10 - adjust, 23 + adjust, 23 + adjust); } +//! [8] +//! [9] QPainterPath Node::shape() const { QPainterPath path; path.addEllipse(-10, -10, 20, 20); return path; } +//! [9] +//! [10] void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) { painter->setPen(Qt::NoPen); @@ -157,7 +178,9 @@ void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid painter->setPen(QPen(Qt::black, 0)); painter->drawEllipse(-10, -10, 20, 20); } +//! [10] +//! [11] QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value) { switch (change) { @@ -172,7 +195,9 @@ QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value) return QGraphicsItem::itemChange(change, value); } +//! [11] +//! [12] void Node::mousePressEvent(QGraphicsSceneMouseEvent *event) { update(); @@ -184,3 +209,4 @@ void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) update(); QGraphicsItem::mouseReleaseEvent(event); } +//! [12] diff --git a/examples/graphicsview/elasticnodes/node.h b/examples/graphicsview/elasticnodes/node.h index 0df579d..990346e 100644 --- a/examples/graphicsview/elasticnodes/node.h +++ b/examples/graphicsview/elasticnodes/node.h @@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE class QGraphicsSceneMouseEvent; QT_END_NAMESPACE +//! [0] class Node : public QGraphicsItem { public: @@ -80,5 +81,6 @@ private: QPointF newPos; GraphWidget *graph; }; +//! [0] #endif -- cgit v0.12 From e709077eff4d8b05cc9022d85dcb48587d96c720 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Thu, 29 Apr 2010 15:17:36 +0200 Subject: Fix QT_NO_LIBRARY Some class uses QFactoryLoader without checking if QT_NO_LIBRARY is not defined. Remove QT_NO_SETTINGS used with QT_NO_LIBRARY for QFactoryLoader because LIBRARY depends on SETTINGS. Merge-request: 578 Reviewed-by: Thierry Bastian --- src/corelib/codecs/qtextcodec.cpp | 8 ++++---- src/corelib/kernel/qcoreapplication.cpp | 10 ++-------- src/corelib/plugin/qfactoryloader.cpp | 2 +- src/corelib/plugin/qfactoryloader_p.h | 2 +- src/gui/accessible/qaccessible.cpp | 4 ++-- src/gui/image/qicon.cpp | 2 +- src/gui/image/qimagereader.cpp | 14 +++++++------- src/gui/image/qimagewriter.cpp | 16 ++++++++-------- src/gui/inputmethod/qinputcontextfactory.cpp | 6 +++--- src/gui/kernel/qguiplatformplugin.cpp | 2 +- src/gui/painting/qgraphicssystemfactory.cpp | 6 +++--- src/gui/styles/qstylefactory.cpp | 2 +- src/multimedia/multimedia/audio/qaudiodevicefactory.cpp | 14 +++++++------- src/network/bearer/qnetworkconfigmanager_p.cpp | 4 ++++ src/sql/kernel/qsqldatabase.cpp | 6 +++--- 15 files changed, 48 insertions(+), 50 deletions(-) diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 59a601e..c9fbec8 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -105,7 +105,7 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_TEXTCODECPLUGIN +#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_TEXTCODECPLUGIN) Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QTextCodecFactoryInterface_iid, QLatin1String("/codecs"))) #endif @@ -149,7 +149,7 @@ static bool nameMatch(const QByteArray &name, const QByteArray &test) static QTextCodec *createForName(const QByteArray &name) { -#ifndef QT_NO_TEXTCODECPLUGIN +#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_TEXTCODECPLUGIN) QFactoryLoader *l = loader(); QStringList keys = l->keys(); for (int i = 0; i < keys.size(); ++i) { @@ -1141,7 +1141,7 @@ QList QTextCodec::availableCodecs() locker.unlock(); #endif -#ifndef QT_NO_TEXTCODECPLUGIN +#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_TEXTCODECPLUGIN) QFactoryLoader *l = loader(); QStringList keys = l->keys(); for (int i = 0; i < keys.size(); ++i) { @@ -1181,7 +1181,7 @@ QList QTextCodec::availableMibs() locker.unlock(); #endif -#ifndef QT_NO_TEXTCODECPLUGIN +#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_TEXTCODECPLUGIN) QFactoryLoader *l = loader(); QStringList keys = l->keys(); for (int i = 0; i < keys.size(); ++i) { diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index bf2e2e4..609e6b3 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -514,7 +514,7 @@ QCoreApplication::QCoreApplication(int &argc, char **argv) { init(); QCoreApplicationPrivate::eventDispatcher->startingUp(); -#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_LIBRARY) // Refresh factoryloader, as text codecs are requested during lib path // resolving process and won't be therefore properly loaded. // Unknown if this is symbian specific issue. @@ -2189,7 +2189,7 @@ QString QCoreApplication::applicationVersion() return coreappdata()->applicationVersion; } -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive)) @@ -2291,13 +2291,11 @@ QStringList QCoreApplication::libraryPaths() */ void QCoreApplication::setLibraryPaths(const QStringList &paths) { -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) QMutexLocker locker(libraryPathMutex()); if (!coreappdata()->app_libpaths) coreappdata()->app_libpaths = new QStringList; *(coreappdata()->app_libpaths) = paths; QFactoryLoader::refreshAll(); -#endif } /*! @@ -2318,7 +2316,6 @@ void QCoreApplication::setLibraryPaths(const QStringList &paths) */ void QCoreApplication::addLibraryPath(const QString &path) { -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) if (path.isEmpty()) return; @@ -2333,7 +2330,6 @@ void QCoreApplication::addLibraryPath(const QString &path) coreappdata()->app_libpaths->prepend(canonicalPath); QFactoryLoader::refreshAll(); } -#endif } /*! @@ -2344,7 +2340,6 @@ void QCoreApplication::addLibraryPath(const QString &path) */ void QCoreApplication::removeLibraryPath(const QString &path) { -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) if (path.isEmpty()) return; @@ -2356,7 +2351,6 @@ void QCoreApplication::removeLibraryPath(const QString &path) QString canonicalPath = QDir(path).canonicalPath(); coreappdata()->app_libpaths->removeAll(canonicalPath); QFactoryLoader::refreshAll(); -#endif } #endif //QT_NO_LIBRARY diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index 87decc6..62d565a 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -41,7 +41,7 @@ #include "qfactoryloader_p.h" -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY #include "qfactoryinterface.h" #include "qmap.h" #include diff --git a/src/corelib/plugin/qfactoryloader_p.h b/src/corelib/plugin/qfactoryloader_p.h index 51426ba..10e6e2a 100644 --- a/src/corelib/plugin/qfactoryloader_p.h +++ b/src/corelib/plugin/qfactoryloader_p.h @@ -57,7 +57,7 @@ #include "QtCore/qstringlist.h" #include "private/qlibrary_p.h" -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY QT_BEGIN_NAMESPACE diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index a55a061..0921bdb 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -389,7 +389,7 @@ QT_BEGIN_NAMESPACE \internal */ -#if !defined(QT_NO_LIBRARY) && (!defined(QT_NO_SETTINGS) || !defined(Q_OS_WIN)) +#ifndef QT_NO_LIBRARY Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QAccessibleFactoryInterface_iid, QLatin1String("/accessible"))) #endif @@ -532,7 +532,7 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object) if (iface) return iface; } -#if !defined(QT_NO_LIBRARY) && (!defined(QT_NO_SETTINGS) || !defined(Q_OS_WIN)) +#ifndef QT_NO_LIBRARY QAccessibleFactoryInterface *factory = qobject_cast(loader()->instance(cn)); if (factory) { iface = factory->create(cn, object); diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index bc52e99..891b1db 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -441,7 +441,7 @@ void QPixmapIconEngine::virtual_hook(int id, void *data) } } -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive)) Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loaderV2, diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 27f9627..93d5cd3 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -144,7 +144,7 @@ QT_BEGIN_NAMESPACE -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats"))) #endif @@ -205,7 +205,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, QByteArray form = format.toLower(); QImageIOHandler *handler = 0; -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY // check if we have plugins that support the image format QFactoryLoader *l = loader(); QStringList keys = l->keys(); @@ -217,7 +217,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, << keys.size() << "plugins available: " << keys; #endif -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY int suffixPluginIndex = -1; if (device && format.isEmpty() && autoDetectImageFormat && !ignoresFormatAndExtension) { // if there's no format, see if \a device is a file, and if so, find @@ -246,7 +246,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, if (ignoresFormatAndExtension) testFormat = QByteArray(); -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY if (suffixPluginIndex != -1) { // check if the plugin that claims support for this format can load // from this device with this format. @@ -331,7 +331,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, #endif } -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) { // check if any of our plugins recognize the file from its contents. const qint64 pos = device ? device->pos() : 0; @@ -350,7 +350,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, if (device && !device->isSequential()) device->seek(pos); } -#endif +#endif // QT_NO_LIBRARY if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) { // check if any of our built-in handlers recognize the file from its @@ -1414,7 +1414,7 @@ QList QImageReader::supportedImageFormats() for (int i = 0; i < _qt_NumFormats; ++i) formats << _qt_BuiltInFormats[i].extension; -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY QFactoryLoader *l = loader(); QStringList keys = l->keys(); diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index 503a1b2..552729f 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -117,7 +117,7 @@ QT_BEGIN_NAMESPACE -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats"))) #endif @@ -129,7 +129,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device, QByteArray suffix; QImageIOHandler *handler = 0; -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY // check if any plugins can write the image QFactoryLoader *l = loader(); QStringList keys = l->keys(); @@ -142,7 +142,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device, // this allows plugins to override our built-in handlers. if (QFile *file = qobject_cast(device)) { if (!(suffix = QFileInfo(file->fileName()).suffix().toLower().toLatin1()).isEmpty()) { -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY int index = keys.indexOf(QString::fromLatin1(suffix)); if (index != -1) suffixPluginIndex = index; @@ -153,7 +153,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device, QByteArray testFormat = !form.isEmpty() ? form : suffix; -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY if (suffixPluginIndex != -1) { // when format is missing, check if we can find a plugin for the // suffix. @@ -161,7 +161,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device, if (plugin && (plugin->capabilities(device, suffix) & QImageIOPlugin::CanWrite)) handler = plugin->create(device, suffix); } -#endif // Q_NO_LIBRARY +#endif // QT_NO_LIBRARY // check if any built-in handlers can write the image if (!handler && !testFormat.isEmpty()) { @@ -192,7 +192,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device, } } -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY if (!testFormat.isEmpty()) { for (int i = 0; i < keys.size(); ++i) { QImageIOPlugin *plugin = qobject_cast(l->instance(keys.at(i))); @@ -203,7 +203,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device, } } } -#endif +#endif // QT_NO_LIBRARY if (!handler) return 0; @@ -670,7 +670,7 @@ QList QImageWriter::supportedImageFormats() formats << "png"; #endif -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY QFactoryLoader *l = loader(); QStringList keys = l->keys(); for (int i = 0; i < keys.count(); ++i) { diff --git a/src/gui/inputmethod/qinputcontextfactory.cpp b/src/gui/inputmethod/qinputcontextfactory.cpp index d47e343..ec8d8e2 100644 --- a/src/gui/inputmethod/qinputcontextfactory.cpp +++ b/src/gui/inputmethod/qinputcontextfactory.cpp @@ -81,7 +81,7 @@ QT_BEGIN_NAMESPACE -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QInputContextFactoryInterface_iid, QLatin1String("/inputmethods"))) #endif @@ -153,7 +153,7 @@ QInputContext *QInputContextFactory::create( const QString& key, QObject *parent result = new QCoeFepInputContext; } #endif -#if defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS) +#ifdef QT_NO_LIBRARY Q_UNUSED(key); #else if (QInputContextFactoryInterface *factory = @@ -193,7 +193,7 @@ QStringList QInputContextFactory::keys() #if defined(Q_WS_S60) result << QLatin1String("coefep"); #endif -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY result += loader()->keys(); #endif // QT_NO_LIBRARY return result; diff --git a/src/gui/kernel/qguiplatformplugin.cpp b/src/gui/kernel/qguiplatformplugin.cpp index c4119af..2dd251b 100644 --- a/src/gui/kernel/qguiplatformplugin.cpp +++ b/src/gui/kernel/qguiplatformplugin.cpp @@ -81,7 +81,7 @@ QGuiPlatformPlugin *qt_guiPlatformPlugin() static QGuiPlatformPlugin *plugin; if (!plugin) { -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY QString key = QString::fromLocal8Bit(qgetenv("QT_PLATFORM_PLUGIN")); #ifdef Q_WS_X11 diff --git a/src/gui/painting/qgraphicssystemfactory.cpp b/src/gui/painting/qgraphicssystemfactory.cpp index 29f24a3..3c09894 100644 --- a/src/gui/painting/qgraphicssystemfactory.cpp +++ b/src/gui/painting/qgraphicssystemfactory.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QGraphicsSystemFactoryInterface_iid, QLatin1String("/graphicssystems"), Qt::CaseInsensitive)) #endif @@ -79,7 +79,7 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key) else if (system.isEmpty() || system == QLatin1String("native")) return 0; -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY if (!ret) { if (QGraphicsSystemFactoryInterface *factory = qobject_cast(loader()->instance(system))) ret = factory->create(system); @@ -100,7 +100,7 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key) */ QStringList QGraphicsSystemFactory::keys() { -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY QStringList list = loader()->keys(); #else QStringList list; diff --git a/src/gui/styles/qstylefactory.cpp b/src/gui/styles/qstylefactory.cpp index 0dbb21f..9009878 100644 --- a/src/gui/styles/qstylefactory.cpp +++ b/src/gui/styles/qstylefactory.cpp @@ -81,7 +81,7 @@ QT_BEGIN_INCLUDE_NAMESPACE QT_END_INCLUDE_NAMESPACE #endif -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QStyleFactoryInterface_iid, QLatin1String("/styles"), Qt::CaseInsensitive)) #endif diff --git a/src/multimedia/multimedia/audio/qaudiodevicefactory.cpp b/src/multimedia/multimedia/audio/qaudiodevicefactory.cpp index 74add64..96545b4 100644 --- a/src/multimedia/multimedia/audio/qaudiodevicefactory.cpp +++ b/src/multimedia/multimedia/audio/qaudiodevicefactory.cpp @@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QAudioEngineFactoryInterface_iid, QLatin1String("/audio"), Qt::CaseInsensitive)) #endif @@ -139,7 +139,7 @@ QList QAudioDeviceFactory::availableDevices(QAudio::Mode mode) #endif #endif -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY QFactoryLoader* l = loader(); foreach (QString const& key, l->keys()) { @@ -158,7 +158,7 @@ QList QAudioDeviceFactory::availableDevices(QAudio::Mode mode) QAudioDeviceInfo QAudioDeviceFactory::defaultInputDevice() { -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance(QLatin1String("default"))); if (plugin) { @@ -178,7 +178,7 @@ QAudioDeviceInfo QAudioDeviceFactory::defaultInputDevice() QAudioDeviceInfo QAudioDeviceFactory::defaultOutputDevice() { -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance(QLatin1String("default"))); if (plugin) { @@ -207,7 +207,7 @@ QAbstractAudioDeviceInfo* QAudioDeviceFactory::audioDeviceInfo(const QString &re #endif #endif -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance(realm)); @@ -238,7 +238,7 @@ QAbstractAudioInput* QAudioDeviceFactory::createInputDevice(QAudioDeviceInfo con return new QAudioInputPrivate(deviceInfo.handle(), format); #endif #endif -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance(deviceInfo.realm())); @@ -260,7 +260,7 @@ QAbstractAudioOutput* QAudioDeviceFactory::createOutputDevice(QAudioDeviceInfo c #endif #endif -#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY QAudioEngineFactoryInterface* plugin = qobject_cast(loader()->instance(deviceInfo.realm())); diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index a7bd2d5..471927a 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -54,8 +54,10 @@ QT_BEGIN_NAMESPACE +#ifndef QT_NO_LIBRARY Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QBearerEngineFactoryInterface_iid, QLatin1String("/bearer"))) +#endif QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate() : pollTimer(0), mutex(QMutex::Recursive), forcedPolling(0), firstUpdate(true) @@ -354,6 +356,7 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() updating = false; +#ifndef QT_NO_LIBRARY QFactoryLoader *l = loader(); QBearerEngine *generic = 0; @@ -387,6 +390,7 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() if (generic) sessionEngines.append(generic); +#endif // QT_NO_LIBRARY } QBearerEngine *engine = qobject_cast(sender()); diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp index 1416ee3..76bc2b0 100644 --- a/src/sql/kernel/qsqldatabase.cpp +++ b/src/sql/kernel/qsqldatabase.cpp @@ -98,7 +98,7 @@ QT_BEGIN_NAMESPACE -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QSqlDriverFactoryInterface_iid, QLatin1String("/sqldrivers"))) @@ -576,7 +576,7 @@ QStringList QSqlDatabase::drivers() list << QLatin1String("QIBASE"); #endif -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY if (QFactoryLoader *fl = loader()) { QStringList keys = fl->keys(); for (QStringList::const_iterator i = keys.constBegin(); i != keys.constEnd(); ++i) { @@ -774,7 +774,7 @@ void QSqlDatabasePrivate::init(const QString &type) } } -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) +#ifndef QT_NO_LIBRARY if (!driver && loader()) { if (QSqlDriverFactoryInterface *factory = qobject_cast(loader()->instance(type))) driver = factory->create(type); -- cgit v0.12 From 070ac81db30d25f129a2ec94c227ab74ce00b8d3 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 29 Apr 2010 11:15:35 +0200 Subject: qmake: remove useless evaluation of variables from VS project generators The variables QMAKE_LFLAGS_DEBUG, QMAKE_LFLAGS_RELEASE, QMAKE_CXXFLAGS_DEBUG and QMAKE_CXXFLAGS_RELEASE are handled by .prf files in mkspecs/features and don't need to be evaluated by generators. Reviewed-by: ossi --- qmake/generators/win32/msvc_vcproj.cpp | 8 -------- qmake/generators/win32/msvc_vcxproj.cpp | 8 -------- 2 files changed, 16 deletions(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 1b4e51b..35e4896 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -917,14 +917,12 @@ void VcprojGenerator::initCompilerTool() conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS")); if(project->isActiveConfig("debug")){ // Debug version - conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_DEBUG")); if((projectTarget == Application) || (projectTarget == StaticLib)) conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DBG")); else conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DLLDBG")); } else { // Release version - conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_RELEASE")); conf.compiler.PreprocessorDefinitions += "QT_NO_DEBUG"; conf.compiler.PreprocessorDefinitions += "NDEBUG"; if((projectTarget == Application) || (projectTarget == StaticLib)) @@ -996,12 +994,6 @@ void VcprojGenerator::initLinkerTool() conf.linker.OutputFile += project->first("MSVCPROJ_TARGET"); - if(project->isActiveConfig("debug")){ - conf.linker.parseOptions(project->values("QMAKE_LFLAGS_DEBUG")); - } else { - conf.linker.parseOptions(project->values("QMAKE_LFLAGS_RELEASE")); - } - if(project->isActiveConfig("dll")){ conf.linker.parseOptions(project->values("QMAKE_LFLAGS_QT_DLL")); } diff --git a/qmake/generators/win32/msvc_vcxproj.cpp b/qmake/generators/win32/msvc_vcxproj.cpp index 85239fe..76aa2a9 100644 --- a/qmake/generators/win32/msvc_vcxproj.cpp +++ b/qmake/generators/win32/msvc_vcxproj.cpp @@ -294,14 +294,12 @@ void VcxprojGenerator::initCompilerTool() conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS")); if(project->isActiveConfig("debug")){ // Debug version - conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_DEBUG")); if((projectTarget == Application) || (projectTarget == StaticLib)) conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DBG")); else conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DLLDBG")); } else { // Release version - conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_RELEASE")); conf.compiler.PreprocessorDefinitions += "QT_NO_DEBUG"; conf.compiler.PreprocessorDefinitions += "NDEBUG"; if((projectTarget == Application) || (projectTarget == StaticLib)) @@ -359,12 +357,6 @@ void VcxprojGenerator::initLinkerTool() conf.linker.OutputFile += project->first("MSVCPROJ_TARGET"); - if(project->isActiveConfig("debug")){ - conf.linker.parseOptions(project->values("QMAKE_LFLAGS_DEBUG")); - } else { - conf.linker.parseOptions(project->values("QMAKE_LFLAGS_RELEASE")); - } - if(project->isActiveConfig("dll")){ conf.linker.parseOptions(project->values("QMAKE_LFLAGS_QT_DLL")); } -- cgit v0.12 From 777fd03ca38f3ced43d2e2da45ddfa1f9a4d2456 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 30 Apr 2010 09:44:02 +0200 Subject: Return the correct library name in qt_gl_library_name for GLES* Reviewed-By: Gunnar --- src/opengl/qgl.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 52efea5..3e4032a 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -5161,11 +5161,17 @@ Q_OPENGL_EXPORT void qt_set_gl_library_name(const QString& name) Q_OPENGL_EXPORT const QString qt_gl_library_name() { if (qt_gl_lib_name()->isNull()) { -#if defined(Q_WS_X11) || defined(Q_WS_QWS) - return QLatin1String("GL"); -#else // Q_WS_MAC +#ifdef Q_WS_MAC return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib"); -#endif +#else +# if defined(QT_OPENGL_ES_1) + return QLatin1String("GLES_CM"); +# elif defined(QT_OPENGL_ES_2) + return QLatin1String("GLESv2"); +# else + return QLatin1String("GL"); +# endif +#endif // defined Q_WS_MAC } return *qt_gl_lib_name(); } -- cgit v0.12 From 37a36bcc768fb8ec1cdcca03d4d4cfba6fcc8bb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 29 Apr 2010 15:43:00 +0200 Subject: Fix wrong translation and clip for the raster paint-engine on Mac When setting up the CGContextRef for a painter we need to take into account both the redirection-transform and the transform on the painter. Reviewed-by: Gunnar --- src/gui/painting/qpaintengine_mac.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qpaintengine_mac.cpp b/src/gui/painting/qpaintengine_mac.cpp index ac2fcf4..14ba94e 100644 --- a/src/gui/painting/qpaintengine_mac.cpp +++ b/src/gui/painting/qpaintengine_mac.cpp @@ -118,9 +118,10 @@ QMacCGContext::QMacCGContext(QPainter *p) QRegion clip = p->paintEngine()->systemClip(); QTransform native = p->deviceTransform(); QTransform logical = p->combinedTransform(); + if (p->hasClipping()) { QRegion r = p->clipRegion(); - r.translate(native.dx() - logical.dx(), native.dy() - logical.dy()); + r.translate(native.dx(), native.dy()); if (clip.isEmpty()) clip = r; else @@ -128,10 +129,7 @@ QMacCGContext::QMacCGContext(QPainter *p) } qt_mac_clip_cg(context, clip, 0); - QPainterState *state = static_cast(pe->state); - Q_ASSERT(state); - if (!state->redirectionMatrix.isIdentity()) - CGContextTranslateCTM(context, state->redirectionMatrix.dx(), state->redirectionMatrix.dy()); + CGContextTranslateCTM(context, native.dx(), native.dy()); } } CGContextRetain(context); -- cgit v0.12 From 736f0a0dd113e54a4d49a1e1e992dc42070866b5 Mon Sep 17 00:00:00 2001 From: Martin Petersson Date: Fri, 30 Apr 2010 15:34:26 +0200 Subject: Fix project file generation for MSVC 2010 Adding the post-build step to copy the dll into bin Reviewed-By: Thierry --- qmake/generators/win32/msbuild_objectmodel.cpp | 24 ++++++++++++++++++++++++ qmake/generators/win32/msvc_vcxproj.cpp | 11 ++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index d011c5c..522d517 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -2837,6 +2837,18 @@ XmlOutput &operator<<(XmlOutput &xml, const VCXProjectSingleConfig &tool) // ResourceCompiler xml << tool.Configuration.resource; + // Post build event + if ( tool.Configuration.postBuild.UseInBuild != unset ) + xml << tool.Configuration.postBuild; + + // Pre build event + if ( tool.Configuration.preBuild.UseInBuild != unset ) + xml << tool.Configuration.preBuild; + + // Pre link event + if ( tool.Configuration.preLink.UseInBuild != unset ) + xml << tool.Configuration.preLink; + xml << closetag(); QFile filterFile; @@ -3266,6 +3278,18 @@ XmlOutput &operator<<(XmlOutput &xml, VCXProject &tool) // ResourceCompiler xml << tool.SingleProjects.at(i).Configuration.resource; + // Post build event + if ( tool.SingleProjects.at(i).Configuration.postBuild.UseInBuild != unset ) + xml << tool.SingleProjects.at(i).Configuration.postBuild; + + // Pre build event + if ( tool.SingleProjects.at(i).Configuration.preBuild.UseInBuild != unset ) + xml << tool.SingleProjects.at(i).Configuration.preBuild; + + // Pre link event + if ( tool.SingleProjects.at(i).Configuration.preLink.UseInBuild != unset ) + xml << tool.SingleProjects.at(i).Configuration.preLink; + xml << closetag(); } diff --git a/qmake/generators/win32/msvc_vcxproj.cpp b/qmake/generators/win32/msvc_vcxproj.cpp index 76aa2a9..da93fe3 100644 --- a/qmake/generators/win32/msvc_vcxproj.cpp +++ b/qmake/generators/win32/msvc_vcxproj.cpp @@ -384,20 +384,24 @@ void VcxprojGenerator::initPostBuildEventTools() QString cmdline = var("QMAKE_POST_LINK"); conf.postBuild.CommandLine = cmdline; conf.postBuild.Description = cmdline; + conf.postBuild.UseInBuild = _True; } QString signature = !project->isEmpty("SIGNATURE_FILE") ? var("SIGNATURE_FILE") : var("DEFAULT_SIGNATURE"); bool useSignature = !signature.isEmpty() && !project->isActiveConfig("staticlib") && !project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH"); - if(useSignature) - conf.postBuild.CommandLine.prepend(QLatin1String("signtool sign /F ") + signature + " \"$(TargetPath)\"\n" + - (!conf.postBuild.CommandLine.isEmpty() ? " && " : "")); + if(useSignature) { + conf.postBuild.CommandLine.prepend(QLatin1String("signtool sign /F ") + signature + " \"$(TargetPath)\"\n" + + (!conf.postBuild.CommandLine.isEmpty() ? " && " : "")); + conf.postBuild.UseInBuild = _True; + } if(!project->values("MSVCPROJ_COPY_DLL").isEmpty()) { if(!conf.postBuild.CommandLine.isEmpty()) conf.postBuild.CommandLine += " && "; conf.postBuild.Description += var("MSVCPROJ_COPY_DLL_DESC"); conf.postBuild.CommandLine += var("MSVCPROJ_COPY_DLL"); + conf.postBuild.UseInBuild = _True; } } @@ -530,6 +534,7 @@ void VcxprojGenerator::initPreLinkEventTools() QString cmdline = var("QMAKE_PRE_LINK"); conf.preLink.Description = cmdline; conf.preLink.CommandLine = cmdline; + conf.preLink.UseInBuild = _True; } } -- cgit v0.12 From a590f7941caeb4f5c687992ddbbc6f02733b12fc Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 3 May 2010 09:22:23 +0200 Subject: Updated WebKit to 8941bee5706ef2171ed5def63834deefc7440d11 Fixes integrated: || || [Qt] QWebPage::userAgentForUrl is terrible API || || || [Qt] GraphicsLayer: animation incorrect when scrolling || || || Make it possible to distinguish between NPAPI plugins and Application plugins || || || [Qt] QtWebKit 2.0 library version needs to be maintained in WebCore.pro || --- src/3rdparty/webkit/.tag | 2 +- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 22 ++ src/3rdparty/webkit/WebCore/WebCore.pro | 6 +- .../webkit/WebKit/qt/Api/qgraphicswebview.cpp | 1 + src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp | 348 +++++++++++---------- src/3rdparty/webkit/WebKit/qt/ChangeLog | 52 +++ src/3rdparty/webkit/WebKit/qt/qtwebkit_version.pri | 4 + .../WebKit/qt/tests/qwebpage/tst_qwebpage.cpp | 35 +++ 9 files changed, 304 insertions(+), 168 deletions(-) create mode 100644 src/3rdparty/webkit/WebKit/qt/qtwebkit_version.pri diff --git a/src/3rdparty/webkit/.tag b/src/3rdparty/webkit/.tag index c750e67..7c2b233 100644 --- a/src/3rdparty/webkit/.tag +++ b/src/3rdparty/webkit/.tag @@ -1 +1 @@ -8941bee5706ef2171ed5def63834deefc7440d11 +3f0f51f4c87e65bfe04165c6af4c00934b0ca1e2 diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 23cae67..ddaaf50 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -4,4 +4,4 @@ This is a snapshot of the Qt port of WebKit from and has the sha1 checksum - 540ae4ccd25609e1bfe1673195ce126255e36774 + 8941bee5706ef2171ed5def63834deefc7440d11 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index b8825bd..22315fe 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,25 @@ +2010-05-03 Thomas Zander + + Reviewed by Simon Hausmann. + + [Qt] Fix library infix usage when compiling inside of Qt + + Don't apply the infix when building inside Qt, as that's done through the + inclusion of qbase.pri. + + * WebCore.pro: + +2010-04-29 Janne Koskinen + + Reviewed by Simon Hausmann. + + [Qt] QtWebKit versioning added + https://bugs.webkit.org/show_bug.cgi?id=37207 + + QtWebkit releases separated from Qt release cycle. + + * WebCore.pro: + 2010-03-27 Robert Hogan Reviewed by nobody, fix typo in previous commit. diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index 2a64982..626e050 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -69,13 +69,13 @@ CONFIG(standalone_package) { CONFIG(QTDIR_build) { include($$QT_SOURCE_TREE/src/qbase.pri) - # Qt will set the version for us when building in Qt's tree } else { - VERSION = $${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} DESTDIR = $$OUTPUT_DIR/lib !static: DEFINES += QT_MAKEDLL - symbian: TARGET +=$${QT_LIBINFIX} + symbian: TARGET += $${QT_LIBINFIX} } +include($$PWD/../WebKit/qt/qtwebkit_version.pri) +VERSION = $${QT_WEBKIT_MAJOR_VERSION}.$${QT_WEBKIT_MINOR_VERSION}.$${QT_WEBKIT_PATCH_VERSION} unix { QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui QtNetwork diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp index 3c86770..1efae16 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp @@ -292,6 +292,7 @@ void QGraphicsWebViewPrivate::update(const QRect & dirtyRect) if (overlay) overlay->update(QRectF(dirtyRect)); #if USE(ACCELERATED_COMPOSITING) + updateCompositingScrollPosition(); syncLayers(); #endif } diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index f28524a..b8b50b7 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -3191,233 +3191,255 @@ QWebPluginFactory *QWebPage::pluginFactory() const \o %AppVersion% expands to QCoreApplication::applicationName()/QCoreApplication::applicationVersion() if they're set; otherwise defaulting to Qt and the current Qt version. \endlist */ -QString QWebPage::userAgentForUrl(const QUrl& url) const +QString QWebPage::userAgentForUrl(const QUrl&) const { - Q_UNUSED(url) - QString ua = QLatin1String("Mozilla/5.0 (" + // splitting the string in three and user QStringBuilder is better than using QString::arg() + static QString firstPart; + static QString secondPart; + static QString thirdPart; + + if (firstPart.isNull() || secondPart.isNull() || thirdPart.isNull()) { + QString firstPartTemp; + firstPartTemp.reserve(150); + firstPartTemp += QString::fromLatin1("Mozilla/5.0 (" // Platform #ifdef Q_WS_MAC - "Macintosh" + "Macintosh" #elif defined Q_WS_QWS - "QtEmbedded" + "QtEmbedded" #elif defined Q_WS_WIN - "Windows" + "Windows" #elif defined Q_WS_X11 - "X11" + "X11" #elif defined Q_OS_SYMBIAN - "SymbianOS" + "SymbianOS" #else - "Unknown" + "Unknown" #endif - // Placeholder for Platform Version - "%1; " + ); + + firstPartTemp += QString::fromLatin1("; "); - // Placeholder for security strength (N or U) - "%2; " + // SSL support +#if !defined(QT_NO_OPENSSL) + // we could check QSslSocket::supportsSsl() here, but this makes + // OpenSSL, certificates etc being loaded in all cases were QWebPage + // is used. This loading is not needed for non-https. + firstPartTemp += QString::fromLatin1("U; "); + // this may lead to a false positive: We indicate SSL since it is + // compiled in even though supportsSsl() might return false +#else + firstPartTemp += QString::fromLatin1("N; "); +#endif - // Subplatform" + // Operating system #ifdef Q_OS_AIX - "AIX" + firstPartTemp += QString::fromLatin1("AIX"); #elif defined Q_OS_WIN32 - "%3" + + switch (QSysInfo::WindowsVersion) { + case QSysInfo::WV_32s: + firstPartTemp += QString::fromLatin1("Windows 3.1"); + break; + case QSysInfo::WV_95: + firstPartTemp += QString::fromLatin1("Windows 95"); + break; + case QSysInfo::WV_98: + firstPartTemp += QString::fromLatin1("Windows 98"); + break; + case QSysInfo::WV_Me: + firstPartTemp += QString::fromLatin1("Windows 98; Win 9x 4.90"); + break; + case QSysInfo::WV_NT: + firstPartTemp += QString::fromLatin1("WinNT4.0"); + break; + case QSysInfo::WV_2000: + firstPartTemp += QString::fromLatin1("Windows NT 5.0"); + break; + case QSysInfo::WV_XP: + firstPartTemp += QString::fromLatin1("Windows NT 5.1"); + break; + case QSysInfo::WV_2003: + firstPartTemp += QString::fromLatin1("Windows NT 5.2"); + break; + case QSysInfo::WV_VISTA: + firstPartTemp += QString::fromLatin1("Windows NT 6.0"); + break; + case QSysInfo::WV_WINDOWS7: + firstPartTemp += QString::fromLatin1("Windows NT 6.1"); + break; + case QSysInfo::WV_CE: + firstPartTemp += QString::fromLatin1("Windows CE"); + break; + case QSysInfo::WV_CENET: + firstPartTemp += QString::fromLatin1("Windows CE .NET"); + break; + case QSysInfo::WV_CE_5: + firstPartTemp += QString::fromLatin1("Windows CE 5.x"); + break; + case QSysInfo::WV_CE_6: + firstPartTemp += QString::fromLatin1("Windows CE 6.x"); + break; + } + #elif defined Q_OS_DARWIN #ifdef __i386__ || __x86_64__ - "Intel Mac OS X" + firstPartTemp += QString::fromLatin1("Intel Mac OS X"); #else - "PPC Mac OS X" + firstPartTemp += QString::fromLatin1("PPC Mac OS X"); #endif #elif defined Q_OS_BSDI - "BSD" + firstPartTemp += QString::fromLatin1("BSD"); #elif defined Q_OS_BSD4 - "BSD Four" + firstPartTemp += QString::fromLatin1("BSD Four"); #elif defined Q_OS_CYGWIN - "Cygwin" + firstPartTemp += QString::fromLatin1("Cygwin"); #elif defined Q_OS_DGUX - "DG/UX" + firstPartTemp += QString::fromLatin1("DG/UX"); #elif defined Q_OS_DYNIX - "DYNIX/ptx" + firstPartTemp += QString::fromLatin1("DYNIX/ptx"); #elif defined Q_OS_FREEBSD - "FreeBSD" + firstPartTemp += QString::fromLatin1("FreeBSD"); #elif defined Q_OS_HPUX - "HP-UX" + firstPartTemp += QString::fromLatin1("HP-UX"); #elif defined Q_OS_HURD - "GNU Hurd" + firstPartTemp += QString::fromLatin1("GNU Hurd"); #elif defined Q_OS_IRIX - "SGI Irix" + firstPartTemp += QString::fromLatin1("SGI Irix"); #elif defined Q_OS_LINUX - "Linux" + +#if defined(__x86_64__) + firstPartTemp += QString::fromLatin1("Linux x86_64"); +#elif defined(__i386__) + firstPartTemp += QString::fromLatin1("Linux i686"); +#else + firstPartTemp += QString::fromLatin1("Linux"); +#endif + #elif defined Q_OS_LYNX - "LynxOS" + firstPartTemp += QString::fromLatin1("LynxOS"); #elif defined Q_OS_NETBSD - "NetBSD" + firstPartTemp += QString::fromLatin1("NetBSD"); #elif defined Q_OS_OS2 - "OS/2" + firstPartTemp += QString::fromLatin1("OS/2"); #elif defined Q_OS_OPENBSD - "OpenBSD" + firstPartTemp += QString::fromLatin1("OpenBSD"); #elif defined Q_OS_OS2EMX - "OS/2" + firstPartTemp += QString::fromLatin1("OS/2"); #elif defined Q_OS_OSF - "HP Tru64 UNIX" + firstPartTemp += QString::fromLatin1("HP Tru64 UNIX"); #elif defined Q_OS_QNX6 - "QNX RTP Six" + firstPartTemp += QString::fromLatin1("QNX RTP Six"); #elif defined Q_OS_QNX - "QNX" + firstPartTemp += QString::fromLatin1("QNX"); #elif defined Q_OS_RELIANT - "Reliant UNIX" + firstPartTemp += QString::fromLatin1("Reliant UNIX"); #elif defined Q_OS_SCO - "SCO OpenServer" + firstPartTemp += QString::fromLatin1("SCO OpenServer"); #elif defined Q_OS_SOLARIS - "Sun Solaris" + firstPartTemp += QString::fromLatin1("Sun Solaris"); #elif defined Q_OS_ULTRIX - "DEC Ultrix" -#elif defined Q_WS_S60 - "Series60" -#elif defined Q_OS_UNIX - "UNIX BSD/SYSV system" -#elif defined Q_OS_UNIXWARE - "UnixWare Seven, Open UNIX Eight" -#else - "Unknown" -#endif - // Placeholder for SubPlatform Version - "%4; "); - - // Platform Version - QString osVer; -#ifdef Q_OS_SYMBIAN - QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); - switch (symbianVersion) { - case QSysInfo::SV_9_2: - osVer = "/9.2"; - break; - case QSysInfo::SV_9_3: - osVer = "/9.3"; - break; - case QSysInfo::SV_9_4: - osVer = "/9.4"; - break; - default: - osVer = "Unknown"; - } -#endif - ua = ua.arg(osVer); - - QChar securityStrength(QLatin1Char('N')); -#if !defined(QT_NO_OPENSSL) - // we could check QSslSocket::supportsSsl() here, but this makes - // OpenSSL, certificates etc being loaded in all cases were QWebPage - // is used. This loading is not needed for non-https. - securityStrength = QLatin1Char('U'); - // this may lead to a false positive: We indicate SSL since it is - // compiled in even though supportsSsl() might return false -#endif - ua = ua.arg(securityStrength); - -#if defined Q_OS_WIN32 - QString ver; - switch (QSysInfo::WindowsVersion) { - case QSysInfo::WV_32s: - ver = "Windows 3.1"; - break; - case QSysInfo::WV_95: - ver = "Windows 95"; - break; - case QSysInfo::WV_98: - ver = "Windows 98"; - break; - case QSysInfo::WV_Me: - ver = "Windows 98; Win 9x 4.90"; - break; - case QSysInfo::WV_NT: - ver = "WinNT4.0"; + firstPartTemp += QString::fromLatin1("DEC Ultrix"); +#elif defined Q_OS_SYMBIAN + firstPartTemp += QString::fromLatin1("SymbianOS"); + QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); + switch (symbianVersion) { + case QSysInfo::SV_9_2: + firstPartTemp += QString::fromLatin1("/9.2"); break; - case QSysInfo::WV_2000: - ver = "Windows NT 5.0"; + case QSysInfo::SV_9_3: + firstPartTemp += QString::fromLatin1("/9.3"); break; - case QSysInfo::WV_XP: - ver = "Windows NT 5.1"; + case QSysInfo::SV_9_4: + firstPartTemp += QString::fromLatin1("/9.4"); break; - case QSysInfo::WV_2003: - ver = "Windows NT 5.2"; + default: + firstPartTemp += QString::fromLatin1("/Unknown"); + } + +#if defined Q_WS_S60 + firstPartTemp += QLatin1Char(' '); + firstPartTemp += QString::fromLatin1("Series60"); + QSysInfo::S60Version s60Version = QSysInfo::s60Version(); + switch (s60Version) { + case QSysInfo::SV_S60_3_1: + firstPartTemp += QString::fromLatin1("/3.1"); break; - case QSysInfo::WV_VISTA: - ver = "Windows NT 6.0"; + case QSysInfo::SV_S60_3_2: + firstPartTemp += QString::fromLatin1("/3.2"); break; -#if QT_VERSION > 0x040500 - case QSysInfo::WV_WINDOWS7: - ver = "Windows NT 6.1"; + case QSysInfo::SV_S60_5_0: + firstPartTemp += QString::fromLatin1("/5.0"); break; + default: + firstPartTemp += QString::fromLatin1("/Unknown"); + } #endif - case QSysInfo::WV_CE: - ver = "Windows CE"; - break; - case QSysInfo::WV_CENET: - ver = "Windows CE .NET"; - break; - case QSysInfo::WV_CE_5: - ver = "Windows CE 5.x"; - break; - case QSysInfo::WV_CE_6: - ver = "Windows CE 6.x"; - break; - } - ua = QString(ua).arg(ver); + +#elif defined Q_OS_UNIX + firstPartTemp += QString::fromLatin1("UNIX BSD/SYSV system"); +#elif defined Q_OS_UNIXWARE + firstPartTemp += QString::fromLatin1("UnixWare Seven, Open UNIX Eight"); +#else + firstPartTemp += QString::fromLatin1("Unknown"); #endif - // SubPlatform Version - QString subPlatformVer; -#ifdef Q_OS_SYMBIAN - QSysInfo::S60Version s60Version = QSysInfo::s60Version(); - switch (s60Version) { - case QSysInfo::SV_S60_3_1: - subPlatformVer = "/3.1"; - break; - case QSysInfo::SV_S60_3_2: - subPlatformVer = "/3.2"; - break; - case QSysInfo::SV_S60_5_0: - subPlatformVer = "/5.0"; - break; - default: - subPlatformVer = " Unknown"; - } + // language is the split + firstPartTemp += QString::fromLatin1("; "); + firstPartTemp.squeeze(); + firstPart = firstPartTemp; + + QString secondPartTemp; + secondPartTemp.reserve(150); + secondPartTemp += QString::fromLatin1(") "); + + // webkit/qt version + secondPartTemp += QString::fromLatin1("AppleWebKit/"); + secondPartTemp += qWebKitVersion(); + secondPartTemp += QString::fromLatin1(" (KHTML, like Gecko) "); + + + // Application name split the third part + secondPartTemp.squeeze(); + secondPart = secondPartTemp; + + QString thirdPartTemp; + thirdPartTemp.reserve(150); +#if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5) + thirdPartTemp + QLatin1String(" Mobile Safari/"); +#else + thirdPartTemp += QLatin1String(" Safari/"); #endif - ua = ua.arg(subPlatformVer); + thirdPartTemp += qWebKitVersion(); + thirdPartTemp.squeeze(); + thirdPart = thirdPartTemp; + Q_ASSERT(!firstPart.isNull()); + Q_ASSERT(!secondPart.isNull()); + Q_ASSERT(!thirdPart.isNull()); + } // Language - QLocale locale; + QString languageName; if (d->client && d->client->ownerWidget()) - locale = d->client->ownerWidget()->locale(); - QString name = locale.name(); - name[2] = QLatin1Char('-'); - ua.append(name); - ua.append(QLatin1String(") ")); - - // webkit/qt version - ua.append(QString(QLatin1String("AppleWebKit/%1 (KHTML, like Gecko) ")) - .arg(QString(qWebKitVersion()))); + languageName = d->client->ownerWidget()->locale().name(); + else + languageName = QLocale().name(); + languageName[2] = QLatin1Char('-'); // Application name/version QString appName = QCoreApplication::applicationName(); if (!appName.isEmpty()) { - ua.append(appName); QString appVer = QCoreApplication::applicationVersion(); if (!appVer.isEmpty()) - ua.append(QLatin1Char('/') + appVer); + appName.append(QLatin1Char('/') + appVer); } else { // Qt version - ua.append(QLatin1String("Qt/")); - ua.append(QLatin1String(qVersion())); + appName = QString::fromLatin1("Qt/") + QString::fromLatin1(qVersion()); } -#if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5) - ua.append(QString(QLatin1String(" Mobile Safari/%1")).arg(qWebKitVersion())); -#else - ua.append(QString(QLatin1String(" Safari/%1")).arg(qWebKitVersion())); -#endif - return ua; + return firstPart + languageName + secondPart + appName + thirdPart; } diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index 8594f09..6e450c2 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,55 @@ +2010-04-29 Janne Koskinen + + Reviewed by Simon Hausmann. + + [Qt] QtWebKit versioning added + https://bugs.webkit.org/show_bug.cgi?id=37207 + + QtWebkit releases separated from Qt release cycle. + + * qtwebkit_version.pri: Added. + +2010-05-02 Benjamin Poulain + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] QWebPage::userAgentForUrl is terrible API + https://bugs.webkit.org/show_bug.cgi?id=33875 + + Simplify the creation of the user agent string to avoid some + overhead for each loaded url. + + The static part of the user agent is cached so it only have + to be made once. + This creation has been made in order to simplify the code. + + The two variable: application name and current language are + set dynamically when needed. + The default locale is non longer created if the widget locale + is used. + + * Api/qwebpage.cpp: + (QWebPage::userAgentForUrl): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::userAgentApplicationName): + (tst_QWebPage::userAgentLocaleChange): + +2010-05-02 Noam Rosenthal + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] GraphicsLayer: animation incorrect when scrolling + https://bugs.webkit.org/show_bug.cgi?id=38371 + + This is a regression introduced with the invalidate-on-scroll code path, that uses QGraphicsWebViewPrivate::update() + instead of QGraphicsWebViewPrivate::scroll(). The patch makes sure that the scrolling position is correct on + each content update - this shouldn't have a performance impact - the only overhead is an additional value-test on each update. + + Tested by http://www.the-art-of-web.com/css/css-animation/ + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::update): + 2010-04-29 Andreas Kling Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebKit/qt/qtwebkit_version.pri b/src/3rdparty/webkit/WebKit/qt/qtwebkit_version.pri new file mode 100644 index 0000000..ffd192c --- /dev/null +++ b/src/3rdparty/webkit/WebKit/qt/qtwebkit_version.pri @@ -0,0 +1,4 @@ +QT_WEBKIT_VERSION = 4.7.0 +QT_WEBKIT_MAJOR_VERSION = 4 +QT_WEBKIT_MINOR_VERSION = 7 +QT_WEBKIT_PATCH_VERSION = 0 diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index 85d4b60..f7eddd5 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,8 @@ private slots: void errorPageExtension(); void errorPageExtensionInIFrames(); void errorPageExtensionInFrameset(); + void userAgentApplicationName(); + void userAgentLocaleChange(); void crashTests_LazyInitializationOfMainFrame(); @@ -1748,6 +1751,38 @@ void tst_QWebPage::errorPageExtensionInFrameset() m_view->setPage(0); } +class FriendlyWebPage : public QWebPage +{ +public: + friend class tst_QWebPage; +}; + +void tst_QWebPage::userAgentApplicationName() +{ + const QString oldApplicationName = QCoreApplication::applicationName(); + FriendlyWebPage page; + + const QString applicationNameMarker = QString::fromUtf8("StrangeName\342\210\236"); + QCoreApplication::setApplicationName(applicationNameMarker); + QVERIFY(page.userAgentForUrl(QUrl()).contains(applicationNameMarker)); + + QCoreApplication::setApplicationName(oldApplicationName); +} + +void tst_QWebPage::userAgentLocaleChange() +{ + FriendlyWebPage page; + m_view->setPage(&page); + + const QString markerString = QString::fromLatin1(" nn-NO)"); + + if (page.userAgentForUrl(QUrl()).contains(markerString)) + QSKIP("marker string already present", SkipSingle); + + m_view->setLocale(QLocale(QString::fromLatin1("nn_NO"))); + QVERIFY(page.userAgentForUrl(QUrl()).contains(markerString)); +} + void tst_QWebPage::crashTests_LazyInitializationOfMainFrame() { { -- cgit v0.12 From 68de350953841e5789656831b08099a6d136c397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Mon, 3 May 2010 10:11:20 +0200 Subject: Revert "Revert "Revert "Implement heightForWidth support for QTabWidget and QStackedLayout.""" This reverts commit 1f00130097f81bc78aebb3c055f38c066221bc98. (Sorry about this. The previous commit got pushed by accident. The proper fix has been done for 4.8 instead.) --- src/gui/kernel/qlayoutitem.cpp | 4 ++- src/gui/kernel/qstackedlayout.cpp | 26 ----------------- src/gui/kernel/qstackedlayout.h | 2 -- src/gui/kernel/qwidget.cpp | 17 ----------- src/gui/kernel/qwidget.h | 1 - src/gui/kernel/qwidget_p.h | 1 - src/gui/widgets/qsizegrip.cpp | 17 ++++++++--- src/gui/widgets/qtabwidget.cpp | 49 -------------------------------- src/gui/widgets/qtabwidget.h | 1 - tests/auto/qtabwidget/tst_qtabwidget.cpp | 47 ------------------------------ 10 files changed, 16 insertions(+), 149 deletions(-) diff --git a/src/gui/kernel/qlayoutitem.cpp b/src/gui/kernel/qlayoutitem.cpp index e615b2d..6a91d95 100644 --- a/src/gui/kernel/qlayoutitem.cpp +++ b/src/gui/kernel/qlayoutitem.cpp @@ -516,7 +516,9 @@ bool QWidgetItem::hasHeightForWidth() const { if (isEmpty()) return false; - return wid->hasHeightForWidth(); + if (wid->layout()) + return wid->layout()->hasHeightForWidth(); + return wid->sizePolicy().hasHeightForWidth(); } /*! diff --git a/src/gui/kernel/qstackedlayout.cpp b/src/gui/kernel/qstackedlayout.cpp index 4b49638..7559066 100644 --- a/src/gui/kernel/qstackedlayout.cpp +++ b/src/gui/kernel/qstackedlayout.cpp @@ -475,32 +475,6 @@ void QStackedLayout::setGeometry(const QRect &rect) } } -bool QStackedLayout::hasHeightForWidth() const -{ - const int n = count(); - - for (int i = 0; i < n; ++i) { - if (QLayoutItem *item = itemAt(i)) { - if (item->hasHeightForWidth()) - return true; - } - } - return false; -} - -int QStackedLayout::heightForWidth(int width) const -{ - const int n = count(); - - int hfw = 0; - for (int i = 0; i < n; ++i) { - if (QLayoutItem *item = itemAt(i)) { - hfw = qMax(hfw, item->heightForWidth(width)); - } - } - return hfw; -} - /*! \enum QStackedLayout::StackingMode \since 4.4 diff --git a/src/gui/kernel/qstackedlayout.h b/src/gui/kernel/qstackedlayout.h index 842b62b..c069149 100644 --- a/src/gui/kernel/qstackedlayout.h +++ b/src/gui/kernel/qstackedlayout.h @@ -95,8 +95,6 @@ public: QLayoutItem *itemAt(int) const; QLayoutItem *takeAt(int); void setGeometry(const QRect &rect); - bool hasHeightForWidth() const; - int heightForWidth(int width) const; Q_SIGNALS: void widgetRemoved(int index); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 399a27b..20d1d30 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -3825,11 +3825,6 @@ void QWidget::setMaximumSize(int maxw, int maxh) d->updateGeometry_helper(d->extra->minw == d->extra->maxw && d->extra->minh == d->extra->maxh); } -bool QWidgetPrivate::hasHeightForWidth() const -{ - return layout ? layout->hasHeightForWidth() : size_policy.hasHeightForWidth(); -} - /*! \overload @@ -7975,18 +7970,6 @@ QSize QWidget::minimumSizeHint() const return QSize(-1, -1); } -/*! - \internal - This is a bit hackish, but ideally this would have been a virtual - function so that subclasses could reimplement their own function. - Instead we add a virtual function to QWidgetPrivate. -*/ -bool QWidget::hasHeightForWidth() const -{ - Q_D(const QWidget); - return d->hasHeightForWidth(); -} - /*! \fn QWidget *QWidget::parentWidget() const diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index 6e5de7d..e12148b 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -524,7 +524,6 @@ public: virtual QSize sizeHint() const; virtual QSize minimumSizeHint() const; - bool hasHeightForWidth() const; QSizePolicy sizePolicy() const; void setSizePolicy(QSizePolicy); diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 9926b2c..cad60b5 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -493,7 +493,6 @@ public: bool setMinimumSize_helper(int &minw, int &minh); bool setMaximumSize_helper(int &maxw, int &maxh); - virtual bool hasHeightForWidth() const; void setConstraints_sys(); QWidget *childAt_helper(const QPoint &, bool) const; void updateGeometry_helper(bool forceUpdate); diff --git a/src/gui/widgets/qsizegrip.cpp b/src/gui/widgets/qsizegrip.cpp index 40f3129..c9d613a 100644 --- a/src/gui/widgets/qsizegrip.cpp +++ b/src/gui/widgets/qsizegrip.cpp @@ -78,6 +78,15 @@ static QWidget *qt_sizegrip_topLevelWidget(QWidget* w) return w; } +static inline bool hasHeightForWidth(QWidget *widget) +{ + if (!widget) + return false; + if (QLayout *layout = widget->layout()) + return layout->hasHeightForWidth(); + return widget->sizePolicy().hasHeightForWidth(); +} + class QSizeGripPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QSizeGrip) @@ -309,7 +318,7 @@ void QSizeGrip::mousePressEvent(QMouseEvent * e) #ifdef Q_WS_X11 // Use a native X11 sizegrip for "real" top-level windows if supported. if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE)) - && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !tlw->hasHeightForWidth()) { + && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) { XEvent xev; xev.xclient.type = ClientMessage; xev.xclient.message_type = ATOM(_NET_WM_MOVERESIZE); @@ -331,7 +340,7 @@ void QSizeGrip::mousePressEvent(QMouseEvent * e) } #endif // Q_WS_X11 #ifdef Q_WS_WIN - if (tlw->isWindow() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !tlw->hasHeightForWidth()) { + if (tlw->isWindow() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) { uint orientation = 0; if (d->atBottom()) orientation = d->atLeft() ? SZ_SIZEBOTTOMLEFT : SZ_SIZEBOTTOMRIGHT; @@ -420,12 +429,12 @@ void QSizeGrip::mouseMoveEvent(QMouseEvent * e) #ifdef Q_WS_X11 if (tlw->isWindow() && X11->isSupportedByWM(ATOM(_NET_WM_MOVERESIZE)) - && tlw->isTopLevel() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !tlw->hasHeightForWidth()) + && tlw->isTopLevel() && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) return; #endif #ifdef Q_WS_WIN if (tlw->isWindow() && GetSystemMenu(tlw->winId(), FALSE) != 0 && internalWinId() - && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !tlw->hasHeightForWidth()) { + && !tlw->testAttribute(Qt::WA_DontShowOnScreen) && !hasHeightForWidth(tlw)) { MSG msg; while(PeekMessage(&msg, winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)); return; diff --git a/src/gui/widgets/qtabwidget.cpp b/src/gui/widgets/qtabwidget.cpp index 3463241..4a61935 100644 --- a/src/gui/widgets/qtabwidget.cpp +++ b/src/gui/widgets/qtabwidget.cpp @@ -195,7 +195,6 @@ public: void _q_removeTab(int); void _q_tabMoved(int from, int to); void init(); - bool hasHeightForWidth() const; QTabBar *tabs; QStackedWidget *stack; @@ -874,46 +873,6 @@ QSize QTabWidget::minimumSizeHint() const .expandedTo(QApplication::globalStrut()); } -int QTabWidget::heightForWidth(int width) const -{ - Q_D(const QTabWidget); - QStyleOption opt(0); - opt.init(this); - opt.state = QStyle::State_None; - - QSize zero(0,0); - const QSize padding = style()->sizeFromContents(QStyle::CT_TabWidget, &opt, zero, this) - .expandedTo(QApplication::globalStrut()); - - QSize lc(0, 0), rc(0, 0); - if (d->leftCornerWidget) - lc = d->leftCornerWidget->sizeHint(); - if(d->rightCornerWidget) - rc = d->rightCornerWidget->sizeHint(); - if (!d->dirty) { - QTabWidget *that = (QTabWidget*)this; - that->setUpLayout(true); - } - QSize t(d->tabs->sizeHint()); - - if(usesScrollButtons()) - t = t.boundedTo(QSize(200,200)); - else - t = t.boundedTo(QApplication::desktop()->size()); - - const bool tabIsHorizontal = (d->pos == North || d->pos == South); - const int contentsWidth = width - padding.width(); - int stackWidth = contentsWidth; - if (!tabIsHorizontal) - stackWidth -= qMax(t.width(), qMax(lc.width(), rc.width())); - - int stackHeight = d->stack->heightForWidth(stackWidth); - QSize s(stackWidth, stackHeight); - - QSize contentSize = basicSize(tabIsHorizontal, lc, rc, s, t); - return (contentSize + padding).expandedTo(QApplication::globalStrut()).height(); -} - /*! \reimp */ @@ -946,14 +905,6 @@ void QTabWidgetPrivate::updateTabBarPosition() q->setUpLayout(); } -bool QTabWidgetPrivate::hasHeightForWidth() const -{ - bool has = size_policy.hasHeightForWidth(); - if (!has && stack) - has = stack->hasHeightForWidth(); - return has; -} - /*! \property QTabWidget::tabPosition \brief the position of the tabs in this tab widget diff --git a/src/gui/widgets/qtabwidget.h b/src/gui/widgets/qtabwidget.h index ee50655..68200c8 100644 --- a/src/gui/widgets/qtabwidget.h +++ b/src/gui/widgets/qtabwidget.h @@ -129,7 +129,6 @@ public: QSize sizeHint() const; QSize minimumSizeHint() const; - int heightForWidth(int width) const; void setCornerWidget(QWidget * w, Qt::Corner corner = Qt::TopRightCorner); QWidget * cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const; diff --git a/tests/auto/qtabwidget/tst_qtabwidget.cpp b/tests/auto/qtabwidget/tst_qtabwidget.cpp index 54e7259..504579f 100644 --- a/tests/auto/qtabwidget/tst_qtabwidget.cpp +++ b/tests/auto/qtabwidget/tst_qtabwidget.cpp @@ -45,7 +45,6 @@ #include #include #include -#include //TESTED_CLASS= //TESTED_FILES= @@ -121,8 +120,6 @@ class tst_QTabWidget:public QObject { void clear(); void keyboardNavigation(); void paintEventCount(); - void heightForWidth(); - void heightForWidth_data(); private: int addPage(); @@ -627,50 +624,6 @@ void tst_QTabWidget::paintEventCount() QCOMPARE(tab2->count, 1); } -void tst_QTabWidget::heightForWidth_data() -{ - QTest::addColumn("tabPosition"); - QTest::newRow("West") << int(QTabWidget::West); - QTest::newRow("North") << int(QTabWidget::North); - QTest::newRow("East") << int(QTabWidget::East); - QTest::newRow("South") << int(QTabWidget::South); -} - -void tst_QTabWidget::heightForWidth() -{ - QFETCH(int, tabPosition); - - QWidget *window = new QWidget; - QVBoxLayout *lay = new QVBoxLayout(window); - lay->setMargin(0); - lay->setSpacing(0); - QTabWidget *tabWid = new QTabWidget(window); - QWidget *w = new QWidget; - tabWid->addTab(w, QLatin1String("HFW page")); - tabWid->setTabPosition(QTabWidget::TabPosition(tabPosition)); - QVBoxLayout *lay2 = new QVBoxLayout(w); - QLabel *label = new QLabel("Label with wordwrap turned on makes it trade height for width." - " Make it a really long text so that it spans on several lines" - " when the label is on its narrowest." - " I don't like to repeat myself." - " I don't like to repeat myself." - " I don't like to repeat myself." - " I don't like to repeat myself." - ); - label->setWordWrap(true); - lay2->addWidget(label); - lay2->setMargin(0); - - lay->addWidget(tabWid); - int h = window->heightForWidth(160); - window->resize(160, h); - window->show(); - - QTest::qWaitForWindowShown(window); - QVERIFY(label->height() >= label->heightForWidth(label->width())); - - delete window; -} QTEST_MAIN(tst_QTabWidget) #include "tst_qtabwidget.moc" -- cgit v0.12 From f275b24b3c38359ab0fedab340bad230d764a0d1 Mon Sep 17 00:00:00 2001 From: Gordon Schumacher Date: Mon, 3 May 2010 12:38:06 +0200 Subject: Do not link QtGui in benchmarks which don't need it Merge-request: 598 Reviewed-by: Olivier Goffart Reviewed-by: Joao --- tests/benchmarks/corelib/kernel/events/events.pro | 1 + .../corelib/kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro | 1 + tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro | 2 +- .../corelib/tools/containers-associative/containers-associative.pro | 1 + tests/benchmarks/corelib/tools/containers-associative/main.cpp | 1 - .../corelib/tools/containers-sequential/containers-sequential.pro | 1 + 6 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/benchmarks/corelib/kernel/events/events.pro b/tests/benchmarks/corelib/kernel/events/events.pro index 43a7131..d7d770a 100644 --- a/tests/benchmarks/corelib/kernel/events/events.pro +++ b/tests/benchmarks/corelib/kernel/events/events.pro @@ -5,3 +5,4 @@ DEPENDPATH += . INCLUDEPATH += . # Input SOURCES += main.cpp +QT -= gui diff --git a/tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro b/tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro index 9c6b16b..5ecb94c 100644 --- a/tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro +++ b/tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro @@ -9,3 +9,4 @@ CONFIG += release SOURCES += tst_qtimer_vs_qmetaobject.cpp +QT -= gui diff --git a/tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro b/tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro index 654b7b6..e8014d6 100644 --- a/tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro +++ b/tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro @@ -3,4 +3,4 @@ TEMPLATE = app TARGET = tst_bench_qthreadstorage SOURCES += tst_qthreadstorage.cpp - +QT -= gui diff --git a/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro b/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro index 3e3bf2b..0dcee4f 100644 --- a/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro +++ b/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro @@ -6,3 +6,4 @@ INCLUDEPATH += . # Input SOURCES += main.cpp +QT -= gui diff --git a/tests/benchmarks/corelib/tools/containers-associative/main.cpp b/tests/benchmarks/corelib/tools/containers-associative/main.cpp index 4c6dae4..afb1ea5 100644 --- a/tests/benchmarks/corelib/tools/containers-associative/main.cpp +++ b/tests/benchmarks/corelib/tools/containers-associative/main.cpp @@ -38,7 +38,6 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include #include #include diff --git a/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro b/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro index 4236b35..656510e 100644 --- a/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro +++ b/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro @@ -6,3 +6,4 @@ INCLUDEPATH += . # Input SOURCES += main.cpp +QT -= gui -- cgit v0.12 From 28659c21d12a267b10e5b441bf4c776e04d69bdc Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 3 May 2010 13:21:54 +0200 Subject: Fixed OpenGL version flags for versions > 3.2. If the system supports an OpenGL version higher than what is recognized by Qt, all the version flags up to 3.2 should be set. Reviewed-by: Trond --- src/opengl/qgl.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 7abf4bc..cfacf26 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1259,11 +1259,24 @@ QGLFormat::OpenGLVersionFlags Q_AUTOTEST_EXPORT qOpenGLVersionFlagsFromString(co versionFlags |= QGLFormat::OpenGL_Version_3_2; case '1': versionFlags |= QGLFormat::OpenGL_Version_3_1; + case '0': + break; default: + versionFlags |= QGLFormat::OpenGL_Version_3_1 | + QGLFormat::OpenGL_Version_3_2; break; } } else { - qWarning("Unrecognised OpenGL version"); + versionFlags |= QGLFormat::OpenGL_Version_1_1 | + QGLFormat::OpenGL_Version_1_2 | + QGLFormat::OpenGL_Version_1_3 | + QGLFormat::OpenGL_Version_1_4 | + QGLFormat::OpenGL_Version_1_5 | + QGLFormat::OpenGL_Version_2_0 | + QGLFormat::OpenGL_Version_2_1 | + QGLFormat::OpenGL_Version_3_0 | + QGLFormat::OpenGL_Version_3_1 | + QGLFormat::OpenGL_Version_3_2; } } return versionFlags; -- cgit v0.12 From 666cacd03d57da6a9caab5936f14c68d1c486e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Mon, 26 Apr 2010 09:40:19 +0200 Subject: QGraphicsView drawing artifacts due to rounding errors. Found during investigation of QTBUG-8820, and clearly visible in examples/graphicsview/diagramscene when slowly moving an item out of the viewport (left and top edge). Caused by two problems: 1) Using QRectF::toRect() instead of QRectF::toAlignedRect(). 2) Didn't adjust the item's bounding rect properly in drawSubtree(). QRectF::toRect() is completely useless since all the coordinates are rounded to the nearest integer. E.g. QRectF(-0.4, -0.4, 10.4, 10.4).toRect() -> QRect(0, 0, 10, 10), whereas toAlignedRect() returns QRect(-1, -1, 11, 11). Then when we have a proper aligned rect, we have to adjust it by 2 pixels in all directions (or 1 pixel in case of QGraphicsView::DontAdjustForAntialiasing). At first glance this adjustment seems too much, since one would assume adjusing the QRectF by 0.5 before using toAlignedRect() would be sufficient. That's sufficient in an untransformed world with pens using BevelJoin. However, the story is completely different as soon as the world is transformed or the pens use a different join. It's basically complicated (in some cases impossible) to calculate a pixel perfect aligned QRect, so instead we adjust by the amount of pixels required in the worst case. This commit also includes some optimizations for QRegion updates (since I anyways had to change the code). There's no point in using QRegion granularity if the viewport update mode is either FullViewportUpdate or BoundingRectViewportUpdate. Auto tests adjusted and new ones included. Task-number: QTBUG-10338 --- src/gui/graphicsview/qgraphicsscene.cpp | 44 +++++---- src/gui/graphicsview/qgraphicsscene_p.h | 6 +- src/gui/graphicsview/qgraphicsview.cpp | 76 ++++++++------- src/gui/graphicsview/qgraphicsview_p.h | 11 ++- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 14 ++- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 123 ++++++++++++++++++++++--- 6 files changed, 194 insertions(+), 80 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 8cee021..0d4e48a 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -297,6 +297,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() scenePosDescendantsUpdatePending(false), stickyFocus(false), hasFocus(false), + rectAdjust(2), focusItem(0), lastFocusItem(0), tabFocusFirst(0), @@ -3217,7 +3218,10 @@ void QGraphicsScene::update(const QRectF &rect) // Update all views. for (int i = 0; i < d->views.size(); ++i) { QGraphicsView *view = d->views.at(i); - view->d_func()->updateRegion(QRegion(view->mapFromScene(rect).boundingRect())); + if (view->isTransformed()) + view->d_func()->updateRectF(view->viewportTransform().mapRect(rect)); + else + view->d_func()->updateRectF(rect); } } else { d->updatedRects << rect; @@ -4701,11 +4705,11 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * if (drawItem) { const QRectF brect = adjustedItemEffectiveBoundingRect(item); ENSURE_TRANSFORM_PTR - QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toRect() - : transformPtr->mapRect(brect).toRect(); + QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toAlignedRect() + : transformPtr->mapRect(brect).toAlignedRect(); + viewBoundingRect.adjust(-rectAdjust, -rectAdjust, rectAdjust, rectAdjust); if (widget) item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect); - viewBoundingRect.adjust(-1, -1, 1, 1); drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect) : !viewBoundingRect.normalized().isEmpty(); if (!drawItem) { @@ -4954,34 +4958,29 @@ static inline bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate if (itemIsUntransformable) { const QTransform xform = itemq->deviceTransform(viewq->viewportTransform()); if (!item->hasBoundingRegionGranularity) - return view->updateRect(xform.mapRect(rect).toRect()); - return view->updateRegion(xform.map(QRegion(rect.toRect()))); + return view->updateRectF(xform.mapRect(rect)); + return view->updateRegion(rect, xform); } if (item->sceneTransformTranslateOnly && view->identityMatrix) { const qreal dx = item->sceneTransform.dx(); const qreal dy = item->sceneTransform.dy(); - if (!item->hasBoundingRegionGranularity) { - QRectF r(rect); - r.translate(dx - view->horizontalScroll(), dy - view->verticalScroll()); - return view->updateRect(r.toRect()); - } - QRegion r(rect.toRect()); - r.translate(qRound(dx) - view->horizontalScroll(), qRound(dy) - view->verticalScroll()); - return view->updateRegion(r); + QRectF r(rect); + r.translate(dx - view->horizontalScroll(), dy - view->verticalScroll()); + return view->updateRectF(r); } if (!viewq->isTransformed()) { if (!item->hasBoundingRegionGranularity) - return view->updateRect(item->sceneTransform.mapRect(rect).toRect()); - return view->updateRegion(item->sceneTransform.map(QRegion(rect.toRect()))); + return view->updateRectF(item->sceneTransform.mapRect(rect)); + return view->updateRegion(rect, item->sceneTransform); } QTransform xform = item->sceneTransform; xform *= viewq->viewportTransform(); if (!item->hasBoundingRegionGranularity) - return view->updateRect(xform.mapRect(rect).toRect()); - return view->updateRegion(xform.map(QRegion(rect.toRect()))); + return view->updateRectF(xform.mapRect(rect)); + return view->updateRegion(rect, xform); } void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren, @@ -5197,8 +5196,14 @@ void QGraphicsScene::drawItems(QPainter *painter, // Determine view, expose and flags. QGraphicsView *view = widget ? qobject_cast(widget->parentWidget()) : 0; QRegion *expose = 0; - if (view) + const quint32 oldRectAdjust = d->rectAdjust; + if (view) { expose = &view->d_func()->exposedRegion; + if (view->d_func()->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) + d->rectAdjust = 1; + else + d->rectAdjust = 2; + } // Find all toplevels, they are already sorted. QList topLevelItems; @@ -5211,6 +5216,7 @@ void QGraphicsScene::drawItems(QPainter *painter, } } + d->rectAdjust = oldRectAdjust; // Reset discovery bits. for (int i = 0; i < topLevelItems.size(); ++i) topLevelItems.at(i)->d_ptr->itemDiscovered = 0; diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 11e250e..0a85f0e 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -136,8 +136,10 @@ public: QBrush backgroundBrush; QBrush foregroundBrush; - bool stickyFocus; - bool hasFocus; + quint32 stickyFocus : 1; + quint32 hasFocus : 1; + quint32 padding : 30; + quint32 rectAdjust; QGraphicsItem *focusItem; QGraphicsItem *lastFocusItem; QGraphicsWidget *tabFocusFirst; diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index c951dce..0bba7e9 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -854,10 +854,7 @@ void QGraphicsViewPrivate::processPendingUpdates() if (fullUpdatePending) { viewport->update(); } else if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) { - if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) - viewport->update(dirtyBoundingRect.adjusted(-1, -1, 1, 1)); - else - viewport->update(dirtyBoundingRect.adjusted(-2, -2, 2, 2)); + viewport->update(dirtyBoundingRect); } else { viewport->update(dirtyRegion); // Already adjusted in updateRect/Region. } @@ -882,46 +879,44 @@ static inline void QRect_unite(QRect *rect, const QRect &other) } } -bool QGraphicsViewPrivate::updateRegion(const QRegion &r) +bool QGraphicsViewPrivate::updateRegion(const QRectF &rect, const QTransform &xform) { - if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate || r.isEmpty()) + if (rect.isEmpty()) return false; - const QRect boundingRect = r.boundingRect(); - if (!intersectsViewport(boundingRect, viewport->width(), viewport->height())) - return false; // Update region outside viewport. - - switch (viewportUpdateMode) { - case QGraphicsView::FullViewportUpdate: - fullUpdatePending = true; - viewport->update(); - break; - case QGraphicsView::BoundingRectViewportUpdate: - QRect_unite(&dirtyBoundingRect, boundingRect); - if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) { - fullUpdatePending = true; - viewport->update(); - } - break; - case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE - case QGraphicsView::MinimalViewportUpdate: - { - const QVector &rects = r.rects(); - for (int i = 0; i < rects.size(); ++i) { - if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) - dirtyRegion += rects.at(i).adjusted(-1, -1, 1, 1); - else - dirtyRegion += rects.at(i).adjusted(-2, -2, 2, 2); - } - break; + if (viewportUpdateMode != QGraphicsView::MinimalViewportUpdate + && viewportUpdateMode != QGraphicsView::SmartViewportUpdate) { + // No point in updating with QRegion granularity; use the rect instead. + return updateRectF(xform.mapRect(rect)); } - default: - break; + + // Update mode is either Minimal or Smart, so we have to do a potentially slow operation, + // which is clearly documented here: QGraphicsItem::setBoundingRegionGranularity. + const QRegion region = xform.map(QRegion(rect.toAlignedRect())); + QRect viewRect = region.boundingRect(); + const bool dontAdjustForAntialiasing = optimizationFlags & QGraphicsView::DontAdjustForAntialiasing; + if (dontAdjustForAntialiasing) + viewRect.adjust(-1, -1, 1, 1); + else + viewRect.adjust(-2, -2, 2, 2); + if (!intersectsViewport(viewRect, viewport->width(), viewport->height())) + return false; // Update region for sure outside viewport. + + const QVector &rects = region.rects(); + for (int i = 0; i < rects.size(); ++i) { + viewRect = rects.at(i); + if (dontAdjustForAntialiasing) + viewRect.adjust(-1, -1, 1, 1); + else + viewRect.adjust(-2, -2, 2, 2); + dirtyRegion += viewRect; } return true; } +// NB! Assumes the rect 'r' is already aligned and adjusted for antialiasing. +// For QRectF use updateRectF(const QRectF &) to ensure proper adjustments. bool QGraphicsViewPrivate::updateRect(const QRect &r) { if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate @@ -943,10 +938,7 @@ bool QGraphicsViewPrivate::updateRect(const QRect &r) break; case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE case QGraphicsView::MinimalViewportUpdate: - if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) - dirtyRegion += r.adjusted(-1, -1, 1, 1); - else - dirtyRegion += r.adjusted(-2, -2, 2, 2); + dirtyRegion += r; break; default: break; @@ -3403,8 +3395,14 @@ void QGraphicsView::paintEvent(QPaintEvent *event) // Items if (!(d->optimizationFlags & IndirectPainting)) { + const quint32 oldRectAdjust = d->scene->d_func()->rectAdjust; + if (d->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) + d->scene->d_func()->rectAdjust = 1; + else + d->scene->d_func()->rectAdjust = 2; d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0, &d->exposedRegion, viewport()); + d->scene->d_func()->rectAdjust = oldRectAdjust; // 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 diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index 80e3ec1..aeff28a 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -192,8 +192,17 @@ public: #endif } + inline bool updateRectF(const QRectF &rect) + { + if (rect.isEmpty()) + return false; + if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) + return updateRect(rect.toAlignedRect().adjusted(-1, -1, 1, 1)); + return updateRect(rect.toAlignedRect().adjusted(-2, -2, 2, 2)); + } + bool updateRect(const QRect &rect); - bool updateRegion(const QRegion ®ion); + bool updateRegion(const QRectF &rect, const QTransform &xform); bool updateSceneSlotReimplementedChecked; QRegion exposedRegion; diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 055ae80..81097be 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -7293,7 +7293,7 @@ void tst_QGraphicsItem::update() QCOMPARE(item->repaints, 1); QCOMPARE(view.repaints, 1); QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform()) - .mapRect(item->boundingRect()).toRect(); + .mapRect(item->boundingRect()).toAlignedRect(); QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); // The entire item's bounding rect (adjusted for antialiasing) should have been painted. QCOMPARE(view.paintedRegion, expectedRegion); @@ -7372,7 +7372,7 @@ void tst_QGraphicsItem::update() scene.addItem(parent); QTest::qWait(50); itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform()) - .mapRect(item->boundingRect()).toRect(); + .mapRect(item->boundingRect()).toAlignedRect(); expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); view.reset(); item->repaints = 0; @@ -7648,7 +7648,7 @@ void tst_QGraphicsItem::moveItem() // Item's boundingRect: (-10, -10, 20, 20). QRect parentDeviceBoundingRect = parent->deviceTransform(view.viewportTransform()) - .mapRect(parent->boundingRect()).toRect() + .mapRect(parent->boundingRect()).toAlignedRect() .adjusted(-2, -2, 2, 2); // Adjusted for antialiasing. parent->setPos(20, 20); @@ -7711,8 +7711,14 @@ void tst_QGraphicsItem::moveLineItem() QTest::qWait(200); view.reset(); + QRectF brect = item->boundingRect(); + // Do same adjustments as in qgraphicsscene.cpp + if (!brect.width()) + brect.adjust(qreal(-0.00001), 0, qreal(0.00001), 0); + if (!brect.height()) + brect.adjust(0, qreal(-0.00001), 0, qreal(0.00001)); const QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform()) - .mapRect(item->boundingRect()).toRect(); + .mapRect(brect).toAlignedRect(); QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); // antialiasing // Make sure the calculated region is correct. diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index d0752af..1df9a37 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -216,6 +216,8 @@ private slots: void exposeRegion(); void update_data(); void update(); + void update2_data(); + void update2(); void inputMethodSensitivity(); void inputContextReset(); void indirectPainting(); @@ -1383,28 +1385,48 @@ void tst_QGraphicsView::itemsInRect_cosmeticAdjust_data() { QTest::addColumn("updateRect"); QTest::addColumn("numPaints"); + QTest::addColumn("adjustForAntialiasing"); - QTest::newRow("nil") << QRect() << 1; - QTest::newRow("0, 0, 300, 100") << QRect(0, 0, 300, 100) << 1; - QTest::newRow("0, 0, 100, 300") << QRect(0, 0, 100, 300) << 1; - QTest::newRow("200, 0, 100, 300") << QRect(200, 0, 100, 300) << 1; - QTest::newRow("0, 200, 300, 100") << QRect(0, 200, 300, 100) << 1; - QTest::newRow("0, 0, 300, 99") << QRect(0, 0, 300, 99) << 0; - QTest::newRow("0, 0, 99, 300") << QRect(0, 0, 99, 300) << 0; - QTest::newRow("201, 0, 99, 300") << QRect(201, 0, 99, 300) << 0; - QTest::newRow("0, 201, 300, 99") << QRect(0, 201, 300, 99) << 0; + // Aliased. + QTest::newRow("nil") << QRect() << 1 << false; + QTest::newRow("0, 0, 300, 100") << QRect(0, 0, 300, 100) << 1 << false; + QTest::newRow("0, 0, 100, 300") << QRect(0, 0, 100, 300) << 1 << false; + QTest::newRow("200, 0, 100, 300") << QRect(200, 0, 100, 300) << 1 << false; + QTest::newRow("0, 200, 300, 100") << QRect(0, 200, 300, 100) << 1 << false; + QTest::newRow("0, 0, 300, 99") << QRect(0, 0, 300, 99) << 0 << false; + QTest::newRow("0, 0, 99, 300") << QRect(0, 0, 99, 300) << 0 << false; + QTest::newRow("201, 0, 99, 300") << QRect(201, 0, 99, 300) << 0 << false; + QTest::newRow("0, 201, 300, 99") << QRect(0, 201, 300, 99) << 0 << false; + + // Anti-aliased. + QTest::newRow("nil") << QRect() << 1 << true; + QTest::newRow("0, 0, 300, 100") << QRect(0, 0, 300, 100) << 1 << true; + QTest::newRow("0, 0, 100, 300") << QRect(0, 0, 100, 300) << 1 << true; + QTest::newRow("200, 0, 100, 300") << QRect(200, 0, 100, 300) << 1 << true; + QTest::newRow("0, 200, 300, 100") << QRect(0, 200, 300, 100) << 1 << true; + QTest::newRow("0, 0, 300, 99") << QRect(0, 0, 300, 99) << 1 << true; + QTest::newRow("0, 0, 99, 300") << QRect(0, 0, 99, 300) << 1 << true; + QTest::newRow("201, 0, 99, 300") << QRect(201, 0, 99, 300) << 1 << true; + QTest::newRow("0, 201, 300, 99") << QRect(0, 201, 300, 99) << 1 << true; + QTest::newRow("0, 0, 300, 98") << QRect(0, 0, 300, 98) << 0 << false; + QTest::newRow("0, 0, 98, 300") << QRect(0, 0, 98, 300) << 0 << false; + QTest::newRow("202, 0, 98, 300") << QRect(202, 0, 98, 300) << 0 << false; + QTest::newRow("0, 202, 300, 98") << QRect(0, 202, 300, 98) << 0 << false; } void tst_QGraphicsView::itemsInRect_cosmeticAdjust() { QFETCH(QRect, updateRect); QFETCH(int, numPaints); + QFETCH(bool, adjustForAntialiasing); QGraphicsScene scene(-100, -100, 200, 200); CountPaintItem *rect = new CountPaintItem(QRectF(-50, -50, 100, 100)); scene.addItem(rect); QGraphicsView view(&scene); + view.setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing, !adjustForAntialiasing); + view.setRenderHint(QPainter::Antialiasing, adjustForAntialiasing); view.setFrameStyle(0); view.resize(300, 300); view.show(); @@ -2219,8 +2241,8 @@ void tst_QGraphicsView::viewportUpdateMode() QTRY_VERIFY(!view.lastUpdateRegions.isEmpty()); #ifndef QT_MAC_USE_COCOA //cocoa doesn't support drawing regions QCOMPARE(view.lastUpdateRegions.last().rects().size(), 2); - QCOMPARE(view.lastUpdateRegions.last().rects().at(0).size(), QSize(15, 15)); - QCOMPARE(view.lastUpdateRegions.last().rects().at(1).size(), QSize(15, 15)); + QCOMPARE(view.lastUpdateRegions.last().rects().at(0).size(), QSize(14, 14)); + QCOMPARE(view.lastUpdateRegions.last().rects().at(1).size(), QSize(14, 14)); #endif // Set full update mode. @@ -2254,7 +2276,7 @@ void tst_QGraphicsView::viewportUpdateMode() // The view gets one bounding rect update. QCOMPARE(view.lastUpdateRegions.last().rects().size(), 1); - QCOMPARE(view.lastUpdateRegions.last().rects().at(0).size(), QSize(33, 33)); + QCOMPARE(view.lastUpdateRegions.last().rects().at(0).size(), QSize(32, 32)); // Set no update mode view.setViewportUpdateMode(QGraphicsView::NoViewportUpdate); @@ -3647,7 +3669,6 @@ void tst_QGraphicsView::update() const bool intersects = updateRect.intersects(viewportRect); QGraphicsViewPrivate *viewPrivate = static_cast(qt_widget_private(&view)); QTRY_COMPARE(viewPrivate->updateRect(updateRect), intersects); - QCOMPARE(viewPrivate->updateRegion(updateRect), intersects); view.lastUpdateRegions.clear(); viewPrivate->processPendingUpdates(); @@ -3658,13 +3679,85 @@ void tst_QGraphicsView::update() QTRY_VERIFY(view.lastUpdateRegions.isEmpty()); } else { QTRY_COMPARE(view.lastUpdateRegions.size(), 1); - // Note that we adjust by 2 for antialiasing. - QTRY_COMPARE(view.lastUpdateRegions.at(0), QRegion(updateRect.adjusted(-2, -2, 2, 2) & viewportRect)); + QTRY_COMPARE(view.lastUpdateRegions.at(0), QRegion(updateRect) & viewportRect); } QTRY_VERIFY(!viewPrivate->fullUpdatePending); #endif } +void tst_QGraphicsView::update2_data() +{ + QTest::addColumn("penWidth"); + QTest::addColumn("antialiasing"); + + // Anti-aliased. + QTest::newRow("pen width: 0.0, antialiasing: true") << 0.0 << true; + QTest::newRow("pen width: 1.5, antialiasing: true") << 1.5 << true; + QTest::newRow("pen width: 2.0, antialiasing: true") << 2.0 << true; + QTest::newRow("pen width: 3.0, antialiasing: true") << 3.0 << true; + + // Aliased. + QTest::newRow("pen width: 0.0, antialiasing: false") << 0.0 << false; + QTest::newRow("pen width: 1.5, antialiasing: false") << 1.5 << false; + QTest::newRow("pen width: 2.0, antialiasing: false") << 2.0 << false; + QTest::newRow("pen width: 3.0, antialiasing: false") << 3.0 << false; +} + +void tst_QGraphicsView::update2() +{ + QFETCH(qreal, penWidth); + QFETCH(bool, antialiasing); + + // Create a rect item. + const QRectF rawItemRect(-50.4, -50.3, 100.2, 100.1); + CountPaintItem *rect = new CountPaintItem(rawItemRect); + QPen pen; + pen.setWidthF(penWidth); + rect->setPen(pen); + + // Add item to a scene. + QGraphicsScene scene(-100, -100, 200, 200); + scene.addItem(rect); + + // Create a view on the scene. + CustomView view(&scene); + view.setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing, !antialiasing); + view.setRenderHint(QPainter::Antialiasing, antialiasing); + view.setFrameStyle(0); + view.resize(200, 200); + view.show(); + QTest::qWaitForWindowShown(&view) ; + QTRY_VERIFY(rect->numPaints > 0); + + // Calculate expected update region for the rect. + QRectF expectedItemBoundingRect = rawItemRect; + const qreal halfPenWidth = penWidth / qreal(2.0); + expectedItemBoundingRect.adjust(-halfPenWidth, -halfPenWidth, halfPenWidth, halfPenWidth); + QCOMPARE(rect->boundingRect(), expectedItemBoundingRect); + + QRect expectedItemDeviceBoundingRect = rect->deviceTransform(view.viewportTransform()) + .mapRect(expectedItemBoundingRect).toAlignedRect(); + if (antialiasing) + expectedItemDeviceBoundingRect.adjust(-2, -2, 2, 2); + else + expectedItemDeviceBoundingRect.adjust(-1, -1, 1, 1); + const QRegion expectedUpdateRegion(expectedItemDeviceBoundingRect); + + // Reset. + rect->numPaints = 0; + view.lastUpdateRegions.clear(); + view.painted = false; + + rect->update(); + QTRY_VERIFY(view.painted); + +#ifndef QT_MAC_USE_COCOA //cocoa doesn't support drawing regions + QTRY_VERIFY(view.painted); + QCOMPARE(view.lastUpdateRegions.size(), 1); + QCOMPARE(view.lastUpdateRegions.at(0), expectedUpdateRegion); +#endif +} + class FocusItem : public QGraphicsRectItem { public: -- cgit v0.12 From d7c7d3666fa593598bfa5ca6a5e6f3b7f8db7486 Mon Sep 17 00:00:00 2001 From: John Brooks Date: Mon, 3 May 2010 15:40:56 +0200 Subject: Fixed a QBuffer warning caused by a regression in qjpeg Commit c1431e6d introduced an invalid QBuffer seek that generates a warning when decoding JPEG from QBuffer. Also fixes the behavior of seeking after the image data, and the behavior when the device is not at position 0. Merge-request: 2378 Reviewed-by: aavit --- src/plugins/imageformats/jpeg/qjpeghandler.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index 1c6a289..72dde15 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -121,8 +121,8 @@ static boolean qt_fill_input_buffer(j_decompress_ptr cinfo) { my_jpeg_source_mgr* src = (my_jpeg_source_mgr*)cinfo->src; if (src->memDevice) { - src->next_input_byte = (const JOCTET *)src->memDevice->data().constData(); - src->bytes_in_buffer = (size_t)src->memDevice->data().size(); + src->next_input_byte = (const JOCTET *)(src->memDevice->data().constData() + src->memDevice->pos()); + src->bytes_in_buffer = (size_t)(src->memDevice->data().size() - src->memDevice->pos()); return true; } src->next_input_byte = src->buffer; @@ -169,7 +169,13 @@ static void qt_term_source(j_decompress_ptr cinfo) { my_jpeg_source_mgr* src = (my_jpeg_source_mgr*)cinfo->src; if (!src->device->isSequential()) - src->device->seek(src->device->pos() - src->bytes_in_buffer); + { + // read() isn't used for memDevice, so seek past everything that was used + if (src->memDevice) + src->device->seek(src->device->pos() + (src->memDevice->data().size() - src->memDevice->pos() - src->bytes_in_buffer)); + else + src->device->seek(src->device->pos() - src->bytes_in_buffer); + } } #if defined(Q_C_CALLBACKS) -- cgit v0.12 From 3d852917187e29892529ab51d24c1a1177068a88 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 3 May 2010 13:22:09 +0200 Subject: QMap: make sure we never access forward and backward through typed Node structs See the comment in the file why. Reviewed-By: Olivier Goffart --- src/corelib/tools/qmap.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index df0ae46..5696ba6 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -125,6 +125,10 @@ template struct QMapNode { Key key; T value; + +private: + // never access these members through this structure. + // see below QMapData::Node *backward; QMapData::Node *forward[1]; }; @@ -134,6 +138,22 @@ struct QMapPayloadNode { Key key; T value; + +private: + // QMap::e is a pointer to QMapData::Node, which matches the member + // below. However, the memory allocation node in QMapData::node_create + // allocates sizeof(QMapPayloNode) and incorrectly calculates the offset + // of 'backward' below. If the alignment of QMapPayloadNode is larger + // than the alignment of a pointer, the 'backward' member is aligned to + // the end of this structure, not to 'value' above, and will occupy the + // tail-padding area. + // + // e.g., on a 32-bit archictecture with Key = int and + // sizeof(T) = alignof(T) = 8 + // 0 4 8 12 16 20 24 byte + // | key | PAD | value |backward| PAD | correct layout + // | key | PAD | value | |backward| how it's actually used + // |<----- value of QMap::payload() = 20 ----->| QMapData::Node *backward; }; -- cgit v0.12 From a2ed290c33f7c087b71a4da53a4baa891f35751a Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 3 May 2010 16:21:20 +0200 Subject: Updated WebKit to 3f0f51f4c87e65bfe04165c6af4c00934b0ca1e2 * Integrated http://trac.webkit.org/changeset/58673 -- Fix qtlibraryinfix not to contain space --- src/3rdparty/webkit/.tag | 2 +- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 11 +++++++++++ src/3rdparty/webkit/WebCore/WebCore.pro | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/3rdparty/webkit/.tag b/src/3rdparty/webkit/.tag index 7c2b233..b6feeb1 100644 --- a/src/3rdparty/webkit/.tag +++ b/src/3rdparty/webkit/.tag @@ -1 +1 @@ -3f0f51f4c87e65bfe04165c6af4c00934b0ca1e2 +992e57ee469bd8c6a2afef6b15896a161ab8aeb3 diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index ddaaf50..c3d6314 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -4,4 +4,4 @@ This is a snapshot of the Qt port of WebKit from and has the sha1 checksum - 8941bee5706ef2171ed5def63834deefc7440d11 + 3f0f51f4c87e65bfe04165c6af4c00934b0ca1e2 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 22315fe..05fc2af 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,14 @@ +2010-05-03 Janne Koskinen + + Reviewed by Simon Hausmann. + + [Qt] Fix qtlibraryinfix not to contain space + + List catenation with += adds whitespace cutting the infix + from the final target. + + * WebCore.pro: + 2010-05-03 Thomas Zander Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index 626e050..3d57562 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -72,7 +72,7 @@ CONFIG(QTDIR_build) { } else { DESTDIR = $$OUTPUT_DIR/lib !static: DEFINES += QT_MAKEDLL - symbian: TARGET += $${QT_LIBINFIX} + symbian: TARGET =$$TARGET$${QT_LIBINFIX} } include($$PWD/../WebKit/qt/qtwebkit_version.pri) VERSION = $${QT_WEBKIT_MAJOR_VERSION}.$${QT_WEBKIT_MINOR_VERSION}.$${QT_WEBKIT_PATCH_VERSION} -- cgit v0.12 From e4c60e6b8d111c6214d8ee47b8c2bb8b9f8fcfe2 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 21 Apr 2010 14:56:40 +0200 Subject: Support updating system locale data on Symbian Subscribing to the locale change notification to be able to update the system locale whenever the user changes the current system locale. Task-number: QTBUG-4870 Reviewed-by: Thomas Zander Reviewed-by: Jason Barron --- mkspecs/common/symbian/symbian.conf | 2 +- src/corelib/kernel/qcoreapplication.cpp | 13 ++++++ src/corelib/kernel/qcoreapplication_p.h | 7 ++++ src/corelib/kernel/qeventdispatcher_symbian.cpp | 2 + src/corelib/kernel/qeventdispatcher_symbian_p.h | 1 + src/corelib/tools/qlocale.cpp | 12 ++++++ src/corelib/tools/qlocale_p.h | 18 +++++++++ src/corelib/tools/qlocale_symbian.cpp | 53 +++++++++++++++++++++++-- src/gui/kernel/qapplication.cpp | 4 ++ 9 files changed, 107 insertions(+), 5 deletions(-) diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 0bd0bf2..89034ca 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -66,7 +66,7 @@ QMAKE_LINK_OBJECT_MAX = QMAKE_LINK_OBJECT_SCRIPT= QMAKE_LIBS = -llibc -llibm -leuser -llibdl -QMAKE_LIBS_CORE = $$QMAKE_LIBS -lefsrv -lhal +QMAKE_LIBS_CORE = $$QMAKE_LIBS -lefsrv -lhal -lbafl QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE -lfbscli -lbitgdi -lgdi -lws32 -lapgrfx -lcone -leikcore -lmediaclientaudio -leikcoctl -leiksrv -lapparc -lcentralrepository QMAKE_LIBS_NETWORK = QMAKE_LIBS_EGL = -llibEGL diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index bf2e2e4..f44fe99 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -63,6 +63,7 @@ #include #include #include +#include #ifdef Q_OS_SYMBIAN # include @@ -521,6 +522,9 @@ QCoreApplication::QCoreApplication(int &argc, char **argv) QFactoryLoader::refreshAll(); #endif +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) + d_func()->symbianInit(); +#endif } // ### move to QCoreApplicationPrivate constructor? @@ -597,6 +601,15 @@ void QCoreApplication::init() qt_startup_hook(); } +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) +void QCoreApplicationPrivate::symbianInit() +{ + if (!environmentChangeNotifier) + environmentChangeNotifier.reset(new QEnvironmentChangeNotifier); +} +#endif + + /*! Destroys the QCoreApplication object. */ diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 77188d3..e066137 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -65,6 +65,9 @@ QT_BEGIN_NAMESPACE typedef QList QTranslatorList; +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) +class QEnvironmentChangeNotifier; +#endif class QAbstractEventDispatcher; class Q_CORE_EXPORT QCoreApplicationPrivate : public QObjectPrivate @@ -113,6 +116,10 @@ public: bool aboutToQuitEmitted; QString cachedApplicationDirPath; QString cachedApplicationFilePath; +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) + QScopedPointer environmentChangeNotifier; + void symbianInit(); +#endif static bool isTranslatorInstalled(QTranslator *translator); diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index a6d486e..687a6d9 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -1105,3 +1105,5 @@ void CQtActiveScheduler::Error(TInt aError) const } QT_END_NAMESPACE + +#include "moc_qeventdispatcher_symbian_p.cpp" diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h index 05758ca..bc42753 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian_p.h +++ b/src/corelib/kernel/qeventdispatcher_symbian_p.h @@ -221,6 +221,7 @@ public: // from CActiveScheduler class Q_CORE_EXPORT QEventDispatcherSymbian : public QAbstractEventDispatcher { + Q_OBJECT Q_DECLARE_PRIVATE(QAbstractEventDispatcher) public: diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index c3f6783..20c2e27 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -129,6 +129,11 @@ inline bool isascii(int c) } #endif +#if defined(Q_OS_SYMBIAN) +void qt_symbianUpdateSystemPrivate(); +void qt_symbianInitSystemLocale(); +#endif + /****************************************************************************** ** Helpers for accessing Qt locale database */ @@ -1407,6 +1412,9 @@ static const QSystemLocale *systemLocale() { if (_systemLocale) return _systemLocale; +#if defined(Q_OS_SYMBIAN) + qt_symbianInitSystemLocale(); +#endif return QSystemLocale_globalSystemLocale(); } @@ -1417,6 +1425,10 @@ void QLocalePrivate::updateSystemPrivate() system_lp = globalLocalePrivate(); *system_lp = *sys_locale->fallbackLocale().d(); +#if defined(Q_OS_SYMBIAN) + qt_symbianUpdateSystemPrivate(); +#endif + QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant()); if (!res.isNull()) system_lp->m_language_id = res.toInt(); diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h index ecf79e9..6205745 100644 --- a/src/corelib/tools/qlocale_p.h +++ b/src/corelib/tools/qlocale_p.h @@ -58,6 +58,10 @@ #include "qlocale.h" +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) +class CEnvironmentChangeNotifier; +#endif + QT_BEGIN_NAMESPACE struct Q_CORE_EXPORT QLocalePrivate @@ -201,6 +205,20 @@ inline char QLocalePrivate::digitToCLocale(const QChar &in) const return 0; } +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) +class QEnvironmentChangeNotifier +{ +public: + QEnvironmentChangeNotifier(); + ~QEnvironmentChangeNotifier(); + + static TInt localeChanged(TAny *data); + +private: + CEnvironmentChangeNotifier *iChangeNotifier; +}; +#endif + QT_END_NAMESPACE #endif // QLOCALE_P_H diff --git a/src/corelib/tools/qlocale_symbian.cpp b/src/corelib/tools/qlocale_symbian.cpp index 01f56cc..6e36dcd 100644 --- a/src/corelib/tools/qlocale_symbian.cpp +++ b/src/corelib/tools/qlocale_symbian.cpp @@ -46,8 +46,14 @@ #include #include +#include +#include +#include +#include #include "private/qcore_symbian_p.h" - +#include "private/qcoreapplication_p.h" +#include "private/qlocale_p.h" +#include QT_BEGIN_NAMESPACE @@ -771,13 +777,18 @@ static QLocale::MeasurementSystem symbianMeasurementSystem() return QLocale::MetricSystem; } -QLocale QSystemLocale::fallbackLocale() const +void qt_symbianUpdateSystemPrivate() { // load system data before query calls + _s60Locale.LoadSystemSettings(); +} + +void qt_symbianInitSystemLocale() +{ static QBasicAtomicInt initDone = Q_BASIC_ATOMIC_INITIALIZER(0); + if (initDone == 2) + return; if (initDone.testAndSetRelaxed(0, 1)) { - _s60Locale.LoadSystemSettings(); - // Initialize platform version dependent function pointers ptrTimeFormatL = reinterpret_cast (qt_resolveS60PluginFunc(S60Plugin_TimeFormatL)); @@ -801,7 +812,10 @@ QLocale QSystemLocale::fallbackLocale() const } while(initDone != 2) QThread::yieldCurrentThread(); +} +QLocale QSystemLocale::fallbackLocale() const +{ TLanguage lang = User::Language(); QString locale = QLatin1String(qt_symbianLocaleName(lang)); return QLocale(locale); @@ -884,4 +898,35 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const return QVariant(); } +#if !defined(QT_NO_SYSTEMLOCALE) +QEnvironmentChangeNotifier::QEnvironmentChangeNotifier() +{ + // Create the change notifier and install the callback function + const TCallBack callback(&QEnvironmentChangeNotifier::localeChanged, this); + QT_TRAP_THROWING(iChangeNotifier = CEnvironmentChangeNotifier::NewL(CActive::EPriorityStandard, callback)); + iChangeNotifier->Start(); +} + +TInt QEnvironmentChangeNotifier::localeChanged(TAny *data) +{ + QEnvironmentChangeNotifier *that = reinterpret_cast(data); + + TInt flag = that->iChangeNotifier->Change(); + if (flag & EChangesLocale) { + static bool first = true; + if (!first) { // skip the first notification on app startup + QT_TRYCATCH_LEAVING(QLocalePrivate::updateSystemPrivate()); + QT_TRYCATCH_LEAVING(QCoreApplication::postEvent(qApp, new QEvent(QEvent::LocaleChange))); + } + first = false; + } + return KErrNone; +} + +QEnvironmentChangeNotifier::~QEnvironmentChangeNotifier() +{ + delete iChangeNotifier; +} +#endif + QT_END_NAMESPACE diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index ec635d4..bc58c76 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -788,6 +788,10 @@ void QApplicationPrivate::construct( qt_gui_eval_init(application_type); #endif +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE) + symbianInit(); +#endif + #ifndef QT_NO_LIBRARY if(load_testability) { QLibrary testLib(QLatin1String("qttestability")); -- cgit v0.12 From fe59ef0bf3c8d0ae92c15cd69839df2232a60936 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 21 Apr 2010 11:47:31 +0200 Subject: Propagate LocaleChange event from application to widgets. The LocaleChange event will be sent to the QApplication object and then propagated to all widgets down the hierarchy starting with toplevels. Reviewed-by: Thomas Zander --- src/gui/kernel/qapplication.cpp | 13 +++++++++++++ src/gui/kernel/qapplication_win.cpp | 2 ++ 2 files changed, 15 insertions(+) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index bc58c76..7b62de1 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -2368,6 +2368,19 @@ bool QApplication::event(QEvent *e) if (!(w->windowType() == Qt::Desktop)) postEvent(w, new QEvent(QEvent::LanguageChange)); } +#ifndef Q_OS_WIN + } else if (e->type() == QEvent::LocaleChange) { + // on Windows the event propagation is taken care by the + // WM_SETTINGCHANGE event handler. + QWidgetList list = topLevelWidgets(); + for (int i = 0; i < list.size(); ++i) { + QWidget *w = list.at(i); + if (!(w->windowType() == Qt::Desktop)) { + if (!w->testAttribute(Qt::WA_SetLocale)) + w->d_func()->setLocale_helper(QLocale(), true); + } + } +#endif } else if (e->type() == QEvent::Timer) { QTimerEvent *te = static_cast(e); Q_ASSERT(te != 0); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index fb2837e..50b9759 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -1936,6 +1936,8 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa QLocalePrivate::updateSystemPrivate(); if (!widget->testAttribute(Qt::WA_SetLocale)) widget->dptr()->setLocale_helper(QLocale(), true); + QEvent e(QEvent::LocaleChange); + QApplication::sendEvent(qApp, &e); } } else if (msg.wParam == SPI_SETICONTITLELOGFONT) { -- cgit v0.12 From 7bcc52d4c1905a5d1777c4c43427e359948959fe Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 3 May 2010 16:03:11 +0200 Subject: Fixes a crash in QGestureManager when unregistering recognizers. Task-number: QTBUG-9801 Reviewed-by: Thomas Zander --- src/gui/kernel/qgesturemanager.cpp | 20 +++++----- tests/auto/gestures/tst_gestures.cpp | 71 ++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 10 deletions(-) diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index aa6720e..a806629 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -132,20 +132,20 @@ void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type) QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g); if (list.contains(recognizer)) { m_deletedRecognizers.insert(g, recognizer); - m_gestureToRecognizer.remove(g); } } - foreach (QGestureRecognizer *recognizer, list) { - QList obsoleteGestures; - QMap >::Iterator iter = m_objectGestures.begin(); - while (iter != m_objectGestures.end()) { - ObjectGesture objectGesture = iter.key(); - if (objectGesture.gesture == type) - obsoleteGestures << iter.value(); - ++iter; + QMap >::const_iterator iter = m_objectGestures.begin(); + while (iter != m_objectGestures.end()) { + ObjectGesture objectGesture = iter.key(); + if (objectGesture.gesture == type) { + foreach (QGesture *g, iter.value()) { + QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g); + m_gestureToRecognizer.remove(g); + m_obsoleteGestures[recognizer].append(g); + } } - m_obsoleteGestures.insert(recognizer, obsoleteGestures); + ++iter; } } diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index f8ecca3..dfadf48 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include @@ -355,6 +356,7 @@ private slots: void deleteGestureTargetItem(); void viewportCoordinates(); void partialGesturePropagation(); + void testQGestureRecognizerCleanup(); }; tst_Gestures::tst_Gestures() @@ -1949,5 +1951,74 @@ void tst_Gestures::partialGesturePropagation() QCOMPARE(item4->gestureEventsReceived, 0); } +class WinNativePan : public QPanGesture { +public: + WinNativePan() {} +}; + +class Pan : public QPanGesture { +public: + Pan() {} +}; + +class CustomPan : public QPanGesture { +public: + CustomPan() {} +}; + +// Recognizer for active gesture triggers on mouse press +class PanRecognizer : public QGestureRecognizer { +public: + enum PanType { Platform, Default, Custom }; + + PanRecognizer(int id) : m_id(id) {} + QGesture *create(QObject *) { + switch(m_id) { + case Platform: return new WinNativePan(); + case Default: return new Pan(); + default: return new CustomPan(); + } + } + + Result recognize(QGesture *, QObject *, QEvent *) { return QGestureRecognizer::Ignore; } + + const int m_id; +}; + +void tst_Gestures::testQGestureRecognizerCleanup() +{ + // Clean first the current recognizers in QGManager + QGestureRecognizer::unregisterRecognizer(Qt::PanGesture); + + // v-- Qt singleton QGManager initialization + + // Mimic QGestureManager: register both default and "platform" recognizers + // (this is done in windows when QT_NO_NATIVE_GESTURES is not defined) + PanRecognizer *def = new PanRecognizer(PanRecognizer::Default); + QGestureRecognizer::registerRecognizer(def); + PanRecognizer *plt = new PanRecognizer(PanRecognizer::Platform); + QGestureRecognizer::registerRecognizer(plt); + qDebug () << "register: default =" << def << "; platform =" << plt; + + // ^-- Qt singleton QGManager initialization + + // Here, application code would start + + // Create QGV (has a QAScrollArea, which uses Qt::PanGesture) + QMainWindow *w = new QMainWindow; + QGraphicsView *v = new QGraphicsView(); + w->setCentralWidget(v); + + // Unregister Qt recognizers + QGestureRecognizer::unregisterRecognizer(Qt::PanGesture); + + // Register a custom Pan recognizer + //QGestureRecognizer::registerRecognizer(new PanRecognizer(PanRecognizer::Custom)); + + w->show(); + QTest::qWaitForWindowShown(w); + delete w; +} + QTEST_MAIN(tst_Gestures) #include "tst_gestures.moc" -- cgit v0.12 From 7b3092423dc4b6c66aa34c483e6ede2e22747159 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Mon, 3 May 2010 20:43:30 +0200 Subject: Increase tooltip margin for cleanlooks+gtk While gtkstyle should really query the width/height individually, this will help visually for now. The current 1-pixel margin look quite ugly in the Qt Creator editor at the moment. Reviewed-by: mae --- src/gui/styles/qcleanlooksstyle.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp index 0f39b23..ba24d97 100644 --- a/src/gui/styles/qcleanlooksstyle.cpp +++ b/src/gui/styles/qcleanlooksstyle.cpp @@ -3714,6 +3714,9 @@ int QCleanlooksStyle::pixelMetric(PixelMetric metric, const QStyleOption *option { int ret = -1; switch (metric) { + case PM_ToolTipLabelFrameWidth: + ret = 2; + break; case PM_ButtonDefaultIndicator: ret = 0; break; -- cgit v0.12 From 3d745d7ded2ed8d52a8c6d9f7113bd6a61e13647 Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Mon, 3 May 2010 23:53:23 +0400 Subject: add static QChar::is(High|Low)Surrogate methods to avoid recoding of character this also adds QChar::requiresSurrogates() static member supposed to save from common mistake like `ucs4 > 0x10000` Merge-request: 606 Reviewed-by: Thiago Macieira --- src/corelib/tools/qchar.cpp | 31 +++++++++++++++++++++++++++++-- src/corelib/tools/qchar.h | 9 +++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp index 67ea00d..2f09b0e 100644 --- a/src/corelib/tools/qchar.cpp +++ b/src/corelib/tools/qchar.cpp @@ -653,14 +653,41 @@ bool QChar::isSymbol() const \fn bool QChar::isHighSurrogate() const Returns true if the QChar is the high part of a utf16 surrogate - (ie. if its code point is between 0xd800 and 0xdbff). + (ie. if its code point is between 0xd800 and 0xdbff, inclusive). */ /*! \fn bool QChar::isLowSurrogate() const Returns true if the QChar is the low part of a utf16 surrogate - (ie. if its code point is between 0xdc00 and 0xdfff). + (ie. if its code point is between 0xdc00 and 0xdfff, inclusive). +*/ + +/*! + \fn static bool QChar::isHighSurrogate(uint ucs4) + \since 4.7 + + Returns true if the UCS-4-encoded character specified by \a ucs4 + is the high part of a utf16 surrogate + (ie. if its code point is between 0xd800 and 0xdbff, inclusive). +*/ + +/*! + \fn static bool QChar::isLowSurrogate(uint ucs4) + \since 4.7 + + Returns true if the UCS-4-encoded character specified by \a ucs4 + is the high part of a utf16 surrogate + (ie. if its code point is between 0xdc00 and 0xdfff, inclusive). +*/ + +/*! + \fn static bool QChar::requiresSurrogates(uint ucs4) + \since 4.7 + + Returns true if the UCS-4-encoded character specified by \a ucs4 + can be splited to the high and low parts of a utf16 surrogate + (ie. if its code point is greater than or equals to 0x10000). */ /*! diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h index 1432c7f..205f911 100644 --- a/src/corelib/tools/qchar.h +++ b/src/corelib/tools/qchar.h @@ -285,6 +285,15 @@ public: inline void setCell(uchar cell); inline void setRow(uchar row); + static inline bool isHighSurrogate(uint ucs4) { + return ((ucs4 & 0xfffffc00) == 0xd800); + } + static inline bool isLowSurrogate(uint ucs4) { + return ((ucs4 & 0xfffffc00) == 0xdc00); + } + static inline bool requiresSurrogates(uint ucs4) { + return (ucs4 >= 0x10000); + } static inline uint surrogateToUcs4(ushort high, ushort low) { return (uint(high)<<10) + low - 0x35fdc00; } -- cgit v0.12 From adf6f5fb5a4f7827df6f589cac9ca8503c50e3b1 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 4 May 2010 09:27:50 +0200 Subject: qdoc: Minor reordering of list index.qdoc This page will be changed quite a lot soon. --- doc/src/index.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/index.qdoc b/doc/src/index.qdoc index 2e6f9bd..6047e91 100644 --- a/doc/src/index.qdoc +++ b/doc/src/index.qdoc @@ -73,8 +73,8 @@ -- cgit v0.12 From c1abca564b4ff30d7d061394424f500143deb466 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 4 May 2010 09:43:12 +0200 Subject: Ensure that the Mac specific Qt classes are namespaced When configuring Qt to be in a namespace then the Mac specific Qt classes should be namespaced as well to prevent any duplicated class names when a non namespaced version of Qt is used in conjunction. Reviewed-by: Richard --- src/gui/dialogs/qcolordialog_mac.mm | 20 +++++++-------- src/gui/dialogs/qfiledialog_mac.mm | 32 +++++++++++------------ src/gui/dialogs/qfontdialog_mac.mm | 16 ++++++------ src/gui/dialogs/qnspanelproxy_mac.mm | 24 ++++++++--------- src/gui/dialogs/qpagesetupdialog_mac.mm | 8 +++--- src/gui/dialogs/qprintdialog_mac.mm | 8 +++--- src/gui/kernel/qsound_mac.mm | 6 ++--- src/gui/util/qsystemtrayicon_mac.mm | 37 +++++++++++++-------------- src/gui/widgets/qcocoatoolbardelegate_mac.mm | 2 +- src/gui/widgets/qcocoatoolbardelegate_mac_p.h | 2 +- src/gui/widgets/qmainwindowlayout_mac.mm | 2 +- 11 files changed, 78 insertions(+), 79 deletions(-) diff --git a/src/gui/dialogs/qcolordialog_mac.mm b/src/gui/dialogs/qcolordialog_mac.mm index 8af0d2b..82cfa24 100644 --- a/src/gui/dialogs/qcolordialog_mac.mm +++ b/src/gui/dialogs/qcolordialog_mac.mm @@ -65,9 +65,9 @@ typedef float CGFloat; // Should only not be defined on 32-bit platforms QT_USE_NAMESPACE -@class QCocoaColorPanelDelegate; +@class QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate); -@interface QCocoaColorPanelDelegate : NSObject { +@interface QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate) : NSObject { NSColorPanel *mColorPanel; NSView *mStolenContentView; NSButton *mOkButton; @@ -99,7 +99,7 @@ QT_USE_NAMESPACE - (void)setResultSet:(BOOL)result; @end -@implementation QCocoaColorPanelDelegate +@implementation QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate) - (id)initWithColorPanel:(NSColorPanel *)panel stolenContentView:(NSView *)stolenContentView okButton:(NSButton *)okButton @@ -432,26 +432,26 @@ void QColorDialogPrivate::openCocoaColorPanel(const QColor &initial, [colorPanel setDefaultButtonCell:[okButton cell]]; } - delegate = [[QCocoaColorPanelDelegate alloc] initWithColorPanel:colorPanel + delegate = [[QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate) alloc] initWithColorPanel:colorPanel stolenContentView:stolenContentView okButton:okButton cancelButton:cancelButton priv:this]; - [colorPanel setDelegate:static_cast(delegate)]; + [colorPanel setDelegate:static_cast(delegate)]; } [delegate setResultSet:false]; setCocoaPanelColor(initial); - [static_cast(delegate) showColorPanel]; + [static_cast(delegate) showColorPanel]; } void QColorDialogPrivate::closeCocoaColorPanel() { - [static_cast(delegate) onCancelClicked]; + [static_cast(delegate) onCancelClicked]; } void QColorDialogPrivate::releaseCocoaColorPanelDelegate() { - [static_cast(delegate) release]; + [static_cast(delegate) release]; } void QColorDialogPrivate::mac_nativeDialogModalHelp() @@ -471,13 +471,13 @@ void QColorDialogPrivate::mac_nativeDialogModalHelp() void QColorDialogPrivate::_q_macRunNativeAppModalPanel() { - [static_cast(delegate) exec]; + [static_cast(delegate) exec]; } void QColorDialogPrivate::setCocoaPanelColor(const QColor &color) { QMacCocoaAutoReleasePool pool; - QCocoaColorPanelDelegate *theDelegate = static_cast(delegate); + QT_MANGLE_NAMESPACE(QCocoaColorPanelDelegate) *theDelegate = static_cast(delegate); NSColor *nsColor; const QColor::Spec spec = color.spec(); if (spec == QColor::Cmyk) { diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm index 28acf24..b07b1ea 100644 --- a/src/gui/dialogs/qfiledialog_mac.mm +++ b/src/gui/dialogs/qfiledialog_mac.mm @@ -82,9 +82,9 @@ QT_FORWARD_DECLARE_CLASS(QAction) QT_FORWARD_DECLARE_CLASS(QFileInfo) QT_USE_NAMESPACE -@class QNSOpenSavePanelDelegate; +@class QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate); -@interface QNSOpenSavePanelDelegate : NSObject { +@interface QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) : NSObject { @public NSOpenPanel *mOpenPanel; NSSavePanel *mSavePanel; @@ -123,7 +123,7 @@ QT_USE_NAMESPACE @end -@implementation QNSOpenSavePanelDelegate +@implementation QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) - (id)initWithAcceptMode:(QT_PREPEND_NAMESPACE(QFileDialog::AcceptMode))acceptMode title:(const QString &)title @@ -554,7 +554,7 @@ void QFileDialogPrivate::setDirectory_sys(const QString &directory) } #else QMacCocoaAutoReleasePool pool; - QNSOpenSavePanelDelegate *delegate = static_cast(mDelegate); + QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); [delegate->mSavePanel setDirectory:qt_mac_QStringToNSString(directory)]; #endif } @@ -565,7 +565,7 @@ QString QFileDialogPrivate::directory_sys() const return mCurrentLocation; #else QMacCocoaAutoReleasePool pool; - QNSOpenSavePanelDelegate *delegate = static_cast(mDelegate); + QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); return qt_mac_NSStringToQString([delegate->mSavePanel directory]); #endif } @@ -622,7 +622,7 @@ QStringList QFileDialogPrivate::selectedFiles_sys() const } #else QMacCocoaAutoReleasePool pool; - QNSOpenSavePanelDelegate *delegate = static_cast(mDelegate); + QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); return [delegate selectedFiles]; #endif } @@ -633,7 +633,7 @@ void QFileDialogPrivate::setNameFilters_sys(const QStringList &filters) Q_UNUSED(filters); #else QMacCocoaAutoReleasePool pool; - QNSOpenSavePanelDelegate *delegate = static_cast(mDelegate); + QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); bool hideDetails = q_func()->testOption(QFileDialog::HideNameFilterDetails); [delegate setNameFilters:filters hideDetails:hideDetails]; #endif @@ -645,7 +645,7 @@ void QFileDialogPrivate::setFilter_sys() #else Q_Q(QFileDialog); QMacCocoaAutoReleasePool pool; - QNSOpenSavePanelDelegate *delegate = static_cast(mDelegate); + QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); *(delegate->mQDirFilter) = model->filter(); delegate->mFileMode = fileMode; [delegate->mSavePanel setTitle:qt_mac_QStringToNSString(q->windowTitle())]; @@ -668,7 +668,7 @@ void QFileDialogPrivate::selectNameFilter_sys(const QString &filter) NavCustomControl(mDialog, kNavCtlSelectCustomType, &navSpec); #else QMacCocoaAutoReleasePool pool; - QNSOpenSavePanelDelegate *delegate = static_cast(mDelegate); + QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); [delegate->mPopUpButton selectItemAtIndex:index]; [delegate filterChanged:nil]; #endif @@ -681,7 +681,7 @@ QString QFileDialogPrivate::selectedNameFilter_sys() const int index = filterInfo.currentSelection; #else QMacCocoaAutoReleasePool pool; - QNSOpenSavePanelDelegate *delegate = static_cast(mDelegate); + QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); int index = [delegate->mPopUpButton indexOfSelectedItem]; #endif return index != -1 ? nameFilters.at(index) : QString(); @@ -696,7 +696,7 @@ void QFileDialogPrivate::deleteNativeDialog_sys() mDialogStarted = false; #else QMacCocoaAutoReleasePool pool; - [reinterpret_cast(mDelegate) release]; + [reinterpret_cast(mDelegate) release]; mDelegate = 0; #endif nativeDialogInUse = false; @@ -1034,7 +1034,7 @@ void QFileDialogPrivate::createNSOpenSavePanelDelegate() bool selectDir = q->selectedFiles().isEmpty(); QString selection(selectDir ? q->directory().absolutePath() : q->selectedFiles().value(0)); - QNSOpenSavePanelDelegate *delegate = [[QNSOpenSavePanelDelegate alloc] + QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) alloc] initWithAcceptMode:acceptMode title:q->windowTitle() nameFilters:q->nameFilters() @@ -1055,7 +1055,7 @@ bool QFileDialogPrivate::showCocoaFilePanel() Q_Q(QFileDialog); QMacCocoaAutoReleasePool pool; createNSOpenSavePanelDelegate(); - QNSOpenSavePanelDelegate *delegate = static_cast(mDelegate); + QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); if (qt_mac_is_macsheet(q)) [delegate showWindowModalSheet:q->parentWidget()]; else @@ -1071,7 +1071,7 @@ bool QFileDialogPrivate::hideCocoaFilePanel() return false; } else { QMacCocoaAutoReleasePool pool; - QNSOpenSavePanelDelegate *delegate = static_cast(mDelegate); + QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); [delegate closePanel]; // Even when we hide it, we are still using a // native dialog, so return true: @@ -1104,7 +1104,7 @@ void QFileDialogPrivate::_q_macRunNativeAppModalPanel() #else Q_Q(QFileDialog); QMacCocoaAutoReleasePool pool; - QNSOpenSavePanelDelegate *delegate = static_cast(mDelegate); + QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); [delegate runApplicationModalPanel]; dialogResultCode_sys() == QDialog::Accepted ? q->accept() : q->reject(); #endif @@ -1119,7 +1119,7 @@ QDialog::DialogCode QFileDialogPrivate::dialogResultCode_sys() else return QDialog::Accepted; #else - QNSOpenSavePanelDelegate *delegate = static_cast(mDelegate); + QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); return [delegate dialogResultCode]; #endif } diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm index 919790b..bb8ef3f 100644 --- a/src/gui/dialogs/qfontdialog_mac.mm +++ b/src/gui/dialogs/qfontdialog_mac.mm @@ -82,7 +82,7 @@ const CGFloat DialogSideMargin = 9.0; const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask; -@class QCocoaFontPanelDelegate; +@class QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate); #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 @@ -93,7 +93,7 @@ const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWin #endif -@interface QCocoaFontPanelDelegate : NSObject { +@interface QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) : NSObject { NSFontPanel *mFontPanel; NSView *mStolenContentView; NSButton *mOkButton; @@ -156,7 +156,7 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) return newFont; } -@implementation QCocoaFontPanelDelegate +@implementation QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) - (id)initWithFontPanel:(NSFontPanel *)panel stolenContentView:(NSView *)stolenContentView okButton:(NSButton *)okButton @@ -478,7 +478,7 @@ QT_BEGIN_NAMESPACE void QFontDialogPrivate::closeCocoaFontPanel() { QMacCocoaAutoReleasePool pool; - QCocoaFontPanelDelegate *theDelegate = static_cast(delegate); + QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *theDelegate = static_cast(delegate); NSWindow *ourPanel = [theDelegate actualPanel]; [ourPanel close]; [theDelegate cleanUpAfterMyself]; @@ -519,7 +519,7 @@ void QFontDialogPrivate::setFont(void *delegate, const QFont &font) } [mgr setSelectedFont:nsFont isMultiple:NO]; - [static_cast(delegate) setQtFont:font]; + [static_cast(delegate) setQtFont:font]; } void QFontDialogPrivate::createNSFontPanelDelegate() @@ -584,7 +584,7 @@ void QFontDialogPrivate::createNSFontPanelDelegate() } // create the delegate and set it - QCocoaFontPanelDelegate *del = [[QCocoaFontPanelDelegate alloc] initWithFontPanel:sharedFontPanel + QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *del = [[QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) alloc] initWithFontPanel:sharedFontPanel stolenContentView:stolenContentView okButton:okButton cancelButton:cancelButton @@ -637,7 +637,7 @@ void QFontDialogPrivate::mac_nativeDialogModalHelp() void QFontDialogPrivate::_q_macRunNativeAppModalPanel() { createNSFontPanelDelegate(); - QCocoaFontPanelDelegate *del = static_cast(delegate); + QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *del = static_cast(delegate); [del runApplicationModalPanel]; } @@ -649,7 +649,7 @@ bool QFontDialogPrivate::showCocoaFontPanel() Q_Q(QFontDialog); QMacCocoaAutoReleasePool pool; createNSFontPanelDelegate(); - QCocoaFontPanelDelegate *del = static_cast(delegate); + QT_MANGLE_NAMESPACE(QCocoaFontPanelDelegate) *del = static_cast(delegate); if (qt_mac_is_macsheet(q)) [del showWindowModalSheet:q->parentWidget()]; else diff --git a/src/gui/dialogs/qnspanelproxy_mac.mm b/src/gui/dialogs/qnspanelproxy_mac.mm index 3229a4d..0bd5c63 100644 --- a/src/gui/dialogs/qnspanelproxy_mac.mm +++ b/src/gui/dialogs/qnspanelproxy_mac.mm @@ -52,9 +52,9 @@ QT_END_NAMESPACE QT_USE_NAMESPACE -@class QNSPanelProxy; +@class QT_MANGLE_NAMESPACE(QNSPanelProxy); -@interface QNSPanelProxy : NSWindow { +@interface QT_MANGLE_NAMESPACE(QNSPanelProxy) : NSWindow { } - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation; @@ -66,7 +66,7 @@ QT_USE_NAMESPACE backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation screen:(NSScreen *)screen; @end -@implementation QNSPanelProxy +@implementation QT_MANGLE_NAMESPACE(QNSPanelProxy) - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)windowStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation { @@ -108,15 +108,15 @@ QT_USE_NAMESPACE } @end -@class QNSWindowProxy; +@class QT_MANGLE_NAMESPACE(QNSWindowProxy); -@interface QNSWindowProxy : NSWindow { +@interface QT_MANGLE_NAMESPACE(QNSWindowProxy) : NSWindow { } - (void)setTitle:(NSString *)title; - (void)qt_fakeSetTitle:(NSString *)title; @end -@implementation QNSWindowProxy +@implementation QT_MANGLE_NAMESPACE(QNSWindowProxy) - (void)setTitle:(NSString *)title { QCFString cftitle(currentWindow->windowTitle()); @@ -190,10 +190,10 @@ void macStartInterceptNSPanelCtor() { macStartIntercept(@selector(initWithContentRect:styleMask:backing:defer:), @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:), - [NSPanel class], [QNSPanelProxy class]); + [NSPanel class], [QT_MANGLE_NAMESPACE(QNSPanelProxy) class]); macStartIntercept(@selector(initWithContentRect:styleMask:backing:defer:screen:), @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:screen:), - [NSPanel class], [QNSPanelProxy class]); + [NSPanel class], [QT_MANGLE_NAMESPACE(QNSPanelProxy) class]); } /* @@ -203,10 +203,10 @@ void macStopInterceptNSPanelCtor() { macStopIntercept(@selector(initWithContentRect:styleMask:backing:defer:screen:), @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:screen:), - [NSPanel class], [QNSPanelProxy class]); + [NSPanel class], [QT_MANGLE_NAMESPACE(QNSPanelProxy) class]); macStopIntercept(@selector(initWithContentRect:styleMask:backing:defer:), @selector(qt_fakeInitWithContentRect:styleMask:backing:defer:), - [NSPanel class], [QNSPanelProxy class]); + [NSPanel class], [QT_MANGLE_NAMESPACE(QNSPanelProxy) class]); } /* @@ -217,7 +217,7 @@ void macStartInterceptWindowTitle(QWidget *window) { currentWindow = window; macStartIntercept(@selector(setTitle:), @selector(qt_fakeSetTitle:), - [NSWindow class], [QNSWindowProxy class]); + [NSWindow class], [QT_MANGLE_NAMESPACE(QNSWindowProxy) class]); } /* @@ -227,7 +227,7 @@ void macStopInterceptWindowTitle() { currentWindow = 0; macStopIntercept(@selector(setTitle:), @selector(qt_fakeSetTitle:), - [NSWindow class], [QNSWindowProxy class]); + [NSWindow class], [QT_MANGLE_NAMESPACE(QNSWindowProxy) class]); } /* diff --git a/src/gui/dialogs/qpagesetupdialog_mac.mm b/src/gui/dialogs/qpagesetupdialog_mac.mm index cfcde0f..0302be4 100644 --- a/src/gui/dialogs/qpagesetupdialog_mac.mm +++ b/src/gui/dialogs/qpagesetupdialog_mac.mm @@ -50,9 +50,9 @@ QT_USE_NAMESPACE -@class QCocoaPageLayoutDelegate; +@class QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate); -@interface QCocoaPageLayoutDelegate : NSObject { +@interface QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) : NSObject { QMacPrintEnginePrivate *pe; } - (id)initWithMacPrintEngine:(QMacPrintEnginePrivate *)printEngine; @@ -60,7 +60,7 @@ QT_USE_NAMESPACE returnCode:(int)returnCode contextInfo:(void *)contextInfo; @end -@implementation QCocoaPageLayoutDelegate +@implementation QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) - (id)initWithMacPrintEngine:(QMacPrintEnginePrivate *)printEngine; { self = [super init]; @@ -213,7 +213,7 @@ void QPageSetupDialogPrivate::openCocoaPageLayout(Qt::WindowModality modality) pageLayout = [NSPageLayout pageLayout]; // Keep a copy to this since we plan on using it for a bit. [pageLayout retain]; - QCocoaPageLayoutDelegate *delegate = [[QCocoaPageLayoutDelegate alloc] initWithMacPrintEngine:ep]; + QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QCocoaPageLayoutDelegate) alloc] initWithMacPrintEngine:ep]; if (modality == Qt::ApplicationModal) { int rval = [pageLayout runModalWithPrintInfo:ep->printInfo]; diff --git a/src/gui/dialogs/qprintdialog_mac.mm b/src/gui/dialogs/qprintdialog_mac.mm index 6a8d6a4..84a72db 100644 --- a/src/gui/dialogs/qprintdialog_mac.mm +++ b/src/gui/dialogs/qprintdialog_mac.mm @@ -124,15 +124,15 @@ QT_USE_NAMESPACE #ifdef QT_MAC_USE_COCOA -@class QCocoaPrintPanelDelegate; +@class QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate); -@interface QCocoaPrintPanelDelegate : NSObject { +@interface QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) : NSObject { } - (void)printPanelDidEnd:(NSPrintPanel *)printPanel returnCode:(int)returnCode contextInfo:(void *)contextInfo; @end -@implementation QCocoaPrintPanelDelegate +@implementation QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) - (void)printPanelDidEnd:(NSPrintPanel *)printPanel returnCode:(int)returnCode contextInfo:(void *)contextInfo { @@ -313,7 +313,7 @@ void QPrintDialogPrivate::openCocoaPrintPanel(Qt::WindowModality modality) macStartInterceptWindowTitle(q); printPanel = [NSPrintPanel printPanel]; - QCocoaPrintPanelDelegate *delegate = [[QCocoaPrintPanelDelegate alloc] init]; + QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) alloc] init]; [printPanel setOptions:macOptions]; if (modality == Qt::ApplicationModal) { diff --git a/src/gui/kernel/qsound_mac.mm b/src/gui/kernel/qsound_mac.mm index 71fd663..2aff44d 100644 --- a/src/gui/kernel/qsound_mac.mm +++ b/src/gui/kernel/qsound_mac.mm @@ -88,14 +88,14 @@ QT_END_NAMESPACE QT_USE_NAMESPACE -@interface QMacSoundDelegate : NSObject { +@interface QT_MANGLE_NAMESPACE(QMacSoundDelegate) : NSObject { QSound *qSound; // may be null. QAuServerMac* server; } -(id)initWithQSound:(QSound*)sound:(QAuServerMac*)server; @end -@implementation QMacSoundDelegate +@implementation QT_MANGLE_NAMESPACE(QMacSoundDelegate) -(id)initWithQSound:(QSound*)s:(QAuServerMac*)serv { self = [super init]; if(self) { @@ -172,7 +172,7 @@ NSSound *QAuServerMac::createNSSound(const QString &fileName, QSound *qSound) { NSString *nsFileName = const_cast(reinterpret_cast(QCFString::toCFStringRef(fileName))); NSSound * const nsSound = [[NSSound alloc] initWithContentsOfFile: nsFileName byReference:YES]; - QMacSoundDelegate * const delegate = [[QMacSoundDelegate alloc] initWithQSound:qSound:this]; + QT_MANGLE_NAMESPACE(QMacSoundDelegate) * const delegate = [[QT_MANGLE_NAMESPACE(QMacSoundDelegate) alloc] initWithQSound:qSound:this]; [nsSound setDelegate:delegate]; [nsFileName release]; return nsSound; diff --git a/src/gui/util/qsystemtrayicon_mac.mm b/src/gui/util/qsystemtrayicon_mac.mm index d943c8c..8aaaa0f 100644 --- a/src/gui/util/qsystemtrayicon_mac.mm +++ b/src/gui/util/qsystemtrayicon_mac.mm @@ -75,8 +75,6 @@ #define QT_MAC_SYSTEMTRAY_USE_GROWL -@class QNSMenu; - #include #include #include @@ -98,13 +96,14 @@ QT_END_NAMESPACE QT_USE_NAMESPACE -@class QNSImageView; +@class QT_MANGLE_NAMESPACE(QNSMenu); +@class QT_MANGLE_NAMESPACE(QNSImageView); -@interface QNSStatusItem : NSObject { +@interface QT_MANGLE_NAMESPACE(QNSStatusItem) : NSObject { NSStatusItem *item; QSystemTrayIcon *icon; QSystemTrayIconPrivate *iconPrivate; - QNSImageView *imageCell; + QT_MANGLE_NAMESPACE(QNSImageView) *imageCell; } -(id)initWithIcon:(QSystemTrayIcon*)icon iconPrivate:(QSystemTrayIconPrivate *)iprivate; -(void)dealloc; @@ -115,11 +114,11 @@ QT_USE_NAMESPACE - (void)doubleClickSelector:(id)sender; @end -@interface QNSImageView : NSImageView { +@interface QT_MANGLE_NAMESPACE(QNSImageView) : NSImageView { BOOL down; - QNSStatusItem *parent; + QT_MANGLE_NAMESPACE(QNSStatusItem) *parent; } --(id)initWithParent:(QNSStatusItem*)myParent; +-(id)initWithParent:(QT_MANGLE_NAMESPACE(QNSStatusItem)*)myParent; -(QSystemTrayIcon*)icon; -(void)menuTrackingDone:(NSNotification*)notification; -(void)mousePressed:(NSEvent *)mouseEvent button:(Qt::MouseButton)mouseButton; @@ -134,7 +133,7 @@ QT_USE_NAMESPACE #endif -@interface QNSMenu : NSMenu { +@interface QT_MANGLE_NAMESPACE(QNSMenu) : NSMenu { QMenu *qmenu; } -(QMenu*)menu; @@ -148,14 +147,14 @@ class QSystemTrayIconSys public: QSystemTrayIconSys(QSystemTrayIcon *icon, QSystemTrayIconPrivate *d) { QMacCocoaAutoReleasePool pool; - item = [[QNSStatusItem alloc] initWithIcon:icon iconPrivate:d]; + item = [[QT_MANGLE_NAMESPACE(QNSStatusItem) alloc] initWithIcon:icon iconPrivate:d]; } ~QSystemTrayIconSys() { QMacCocoaAutoReleasePool pool; [[[item item] view] setHidden: YES]; [item release]; } - QNSStatusItem *item; + QT_MANGLE_NAMESPACE(QNSStatusItem) *item; }; void QSystemTrayIconPrivate::install_sys() @@ -299,8 +298,8 @@ QT_END_NAMESPACE @implementation NSStatusItem (Qt) @end -@implementation QNSImageView --(id)initWithParent:(QNSStatusItem*)myParent { +@implementation QT_MANGLE_NAMESPACE(QNSImageView) +-(id)initWithParent:(QT_MANGLE_NAMESPACE(QNSStatusItem)*)myParent { self = [super init]; parent = myParent; down = NO; @@ -400,7 +399,7 @@ QT_END_NAMESPACE } @end -@implementation QNSStatusItem +@implementation QT_MANGLE_NAMESPACE(QNSStatusItem) -(id)initWithIcon:(QSystemTrayIcon*)i iconPrivate:(QSystemTrayIconPrivate *)iPrivate { @@ -409,7 +408,7 @@ QT_END_NAMESPACE icon = i; iconPrivate = iPrivate; item = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain]; - imageCell = [[QNSImageView alloc] initWithParent:self]; + imageCell = [[QT_MANGLE_NAMESPACE(QNSImageView) alloc] initWithParent:self]; [item setView: imageCell]; } return self; @@ -453,7 +452,7 @@ QT_END_NAMESPACE [[[self item] view] removeAllToolTips]; iconPrivate->updateToolTip_sys(); #endif - NSMenu *m = [[QNSMenu alloc] initWithQMenu:icon->contextMenu()]; + NSMenu *m = [[QT_MANGLE_NAMESPACE(QNSMenu) alloc] initWithQMenu:icon->contextMenu()]; [m setAutoenablesItems: NO]; [[NSNotificationCenter defaultCenter] addObserver:imageCell selector:@selector(menuTrackingDone:) @@ -481,7 +480,7 @@ private: QSystemTrayIconQMenu(); }; -@implementation QNSMenu +@implementation QT_MANGLE_NAMESPACE(QNSMenu) -(id)initWithQMenu:(QMenu*)qm { self = [super init]; if(self) { @@ -494,7 +493,7 @@ private: return qmenu; } -(void)menuNeedsUpdate:(NSMenu*)nsmenu { - QNSMenu *menu = static_cast(nsmenu); + QT_MANGLE_NAMESPACE(QNSMenu) *menu = static_cast(nsmenu); emit static_cast(menu->qmenu)->doAboutToShow(); for(int i = [menu numberOfItems]-1; i >= 0; --i) [menu removeItemAtIndex:i]; @@ -539,7 +538,7 @@ private: [nsimage release]; } if(action->menu()) { - QNSMenu *sub = [[QNSMenu alloc] initWithQMenu:action->menu()]; + QT_MANGLE_NAMESPACE(QNSMenu) *sub = [[QT_MANGLE_NAMESPACE(QNSMenu) alloc] initWithQMenu:action->menu()]; [item setSubmenu:sub]; } else { [item setAction:@selector(selectedAction:)]; diff --git a/src/gui/widgets/qcocoatoolbardelegate_mac.mm b/src/gui/widgets/qcocoatoolbardelegate_mac.mm index b2a0e0c..e68ee7c 100644 --- a/src/gui/widgets/qcocoatoolbardelegate_mac.mm +++ b/src/gui/widgets/qcocoatoolbardelegate_mac.mm @@ -58,7 +58,7 @@ QT_FORWARD_DECLARE_CLASS(QMainWindowLayout); QT_FORWARD_DECLARE_CLASS(QToolBar); QT_FORWARD_DECLARE_CLASS(QCFString); -@implementation QCocoaToolBarDelegate +@implementation QT_MANGLE_NAMESPACE(QCocoaToolBarDelegate) - (id)initWithMainWindowLayout:(QMainWindowLayout *)layout { diff --git a/src/gui/widgets/qcocoatoolbardelegate_mac_p.h b/src/gui/widgets/qcocoatoolbardelegate_mac_p.h index 8e3d06f..b4af54f 100644 --- a/src/gui/widgets/qcocoatoolbardelegate_mac_p.h +++ b/src/gui/widgets/qcocoatoolbardelegate_mac_p.h @@ -61,7 +61,7 @@ QT_END_NAMESPACE @class NSToolbarItem; -@interface QCocoaToolBarDelegate : NSObject { +@interface QT_MANGLE_NAMESPACE(QCocoaToolBarDelegate) : NSObject { QT_PREPEND_NAMESPACE(QMainWindowLayout) *mainWindowLayout; NSToolbarItem *toolbarItem; } diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index 9527057..b8cef93 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -410,7 +410,7 @@ void QMainWindowLayout::insertIntoMacToolbar(QToolBar *before, QToolBar *toolbar macToolbar = [[NSToolbar alloc] initWithIdentifier:(NSString *)kQMainWindowMacToolbarID]; [macToolbar setDisplayMode:NSToolbarDisplayModeIconOnly]; [macToolbar setSizeMode:NSToolbarSizeModeRegular]; - [macToolbar setDelegate:[[QCocoaToolBarDelegate alloc] initWithMainWindowLayout:this]]; + [macToolbar setDelegate:[[QT_MANGLE_NAMESPACE(QCocoaToolBarDelegate) alloc] initWithMainWindowLayout:this]]; [window setToolbar:macToolbar]; [macToolbar release]; } -- cgit v0.12