From 4a240bb67e72b34c80af448e0a74846609fa6975 Mon Sep 17 00:00:00 2001 From: Nils Jeisecke Date: Thu, 1 Sep 2016 14:26:18 +0200 Subject: QTextDocument: Fix device scaling for QTextFrameFormat margins, padding and border Those values must be scaled to device coordinates - otherwise borders, margins etc. will be too small when rendered on high dpi devices (printers etc.). This change will add the scaling to those values. QTextDocument::print applies 2cm margins to the root frame of a unpaginated QTextDocument. Those margins were previously scaled to device coordinates in order to give the correct result. But because scaling is now done inside QTextDocumentLayout that scaling must be removed and pixel values based on qt_defaultDpi are provided instead. Fixes: QTBUG-78318 Change-Id: I6fe6dcc25f846341f6a2fe5df2f54baea473fdfd Reviewed-by: Shawn Rutledge --- src/gui/text/qtextdocument.cpp | 26 +++++++++++++--------- src/gui/text/qtextdocumentlayout.cpp | 12 +++++----- .../widgets/widgets/qtextedit/tst_qtextedit.cpp | 17 ++++++++++++++ 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 3652a180a8..22c249d604 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -1970,9 +1970,12 @@ void QTextDocument::print(QPagedPaintDevice *printer) const QRectF body = QRectF(QPointF(0, 0), d->pageSize); QPointF pageNumberPos; + qreal sourceDpiX = qt_defaultDpiX(); + qreal sourceDpiY = qt_defaultDpiY(); + const qreal dpiScaleX = qreal(printer->logicalDpiX()) / sourceDpiX; + const qreal dpiScaleY = qreal(printer->logicalDpiY()) / sourceDpiY; + if (documentPaginated) { - qreal sourceDpiX = qt_defaultDpi(); - qreal sourceDpiY = sourceDpiX; QPaintDevice *dev = doc->documentLayout()->paintDevice(); if (dev) { @@ -1980,9 +1983,6 @@ void QTextDocument::print(QPagedPaintDevice *printer) const sourceDpiY = dev->logicalDpiY(); } - const qreal dpiScaleX = qreal(printer->logicalDpiX()) / sourceDpiX; - const qreal dpiScaleY = qreal(printer->logicalDpiY()) / sourceDpiY; - // scale to dpi p.scale(dpiScaleX, dpiScaleY); @@ -2011,15 +2011,21 @@ void QTextDocument::print(QPagedPaintDevice *printer) const // copy the custom object handlers layout->d_func()->handlers = documentLayout()->d_func()->handlers; - int dpiy = p.device()->logicalDpiY(); - int margin = (int) ((2/2.54)*dpiy); // 2 cm margins + // 2 cm margins, scaled to device in QTextDocumentLayoutPrivate::layoutFrame + const int horizontalMargin = int((2/2.54)*sourceDpiX); + const int verticalMargin = int((2/2.54)*sourceDpiY); QTextFrameFormat fmt = doc->rootFrame()->frameFormat(); - fmt.setMargin(margin); + fmt.setLeftMargin(horizontalMargin); + fmt.setRightMargin(horizontalMargin); + fmt.setTopMargin(verticalMargin); + fmt.setBottomMargin(verticalMargin); doc->rootFrame()->setFrameFormat(fmt); + // pageNumberPos must be in device coordinates, so scale to device here + const int dpiy = p.device()->logicalDpiY(); body = QRectF(0, 0, printer->width(), printer->height()); - pageNumberPos = QPointF(body.width() - margin, - body.height() - margin + pageNumberPos = QPointF(body.width() - horizontalMargin * dpiScaleX, + body.height() - verticalMargin * dpiScaleY + QFontMetrics(doc->defaultFont(), p.device()).ascent() + 5 * dpiy / 72.0); clonedDoc->setPageSize(body.size()); diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index b02723c047..a9a177da8b 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -2915,24 +2915,24 @@ QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, in { QTextFrameFormat fformat = f->frameFormat(); // set sizes of this frame from the format - QFixed tm = QFixed::fromReal(fformat.topMargin()); + QFixed tm = QFixed::fromReal(scaleToDevice(fformat.topMargin())).round(); if (tm != fd->topMargin) { fd->topMargin = tm; fullLayout = true; } - QFixed bm = QFixed::fromReal(fformat.bottomMargin()); + QFixed bm = QFixed::fromReal(scaleToDevice(fformat.bottomMargin())).round(); if (bm != fd->bottomMargin) { fd->bottomMargin = bm; fullLayout = true; } - fd->leftMargin = QFixed::fromReal(fformat.leftMargin()); - fd->rightMargin = QFixed::fromReal(fformat.rightMargin()); - QFixed b = QFixed::fromReal(fformat.border()); + fd->leftMargin = QFixed::fromReal(scaleToDevice(fformat.leftMargin())).round(); + fd->rightMargin = QFixed::fromReal(scaleToDevice(fformat.rightMargin())).round(); + QFixed b = QFixed::fromReal(scaleToDevice(fformat.border())).round(); if (b != fd->border) { fd->border = b; fullLayout = true; } - QFixed p = QFixed::fromReal(fformat.padding()); + QFixed p = QFixed::fromReal(scaleToDevice(fformat.padding())).round(); if (p != fd->padding) { fd->padding = p; fullLayout = true; diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp index c2cf31bfa4..b31e230893 100644 --- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp @@ -1978,8 +1978,23 @@ void tst_QTextEdit::fullWidthSelection_data() #endif #ifdef QT_BUILD_INTERNAL + +// With the fix for QTBUG-78318 scaling of documentMargin is added. The testing framework +// forces qt_defaultDpi() to always return 96 DPI. For systems where the actual DPI differs +// (typically 72 DPI) this would now cause scaling of the documentMargin when +// drawing QTextEdit into QImage. In order to avoid the need of multiple reference PNGs +// for comparison we disable the Qt::AA_Use96Dpi attribute for these tests. + +struct ForceSystemDpiHelper { + ForceSystemDpiHelper() { QCoreApplication::setAttribute(Qt::AA_Use96Dpi, false); } + ~ForceSystemDpiHelper() { QCoreApplication::setAttribute(Qt::AA_Use96Dpi, old); } + bool old = QCoreApplication::testAttribute(Qt::AA_Use96Dpi); +}; + void tst_QTextEdit::fullWidthSelection() { + ForceSystemDpiHelper useSystemDpi; + QFETCH(int, cursorFrom); QFETCH(int, cursorTo); QFETCH(QString, imageFileName); @@ -2048,6 +2063,8 @@ void tst_QTextEdit::fullWidthSelection() #ifdef QT_BUILD_INTERNAL void tst_QTextEdit::fullWidthSelection2() { + ForceSystemDpiHelper useSystemDpi; + QPalette myPalette; myPalette.setColor(QPalette::All, QPalette::HighlightedText, QColor(0,0,0,0)); myPalette.setColor(QPalette::All, QPalette::Highlight, QColor(239,221,85)); -- cgit v1.2.3 From ff8e7fd7d3ef9f5400fb1d71d9cfd5158a7ee25a Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Thu, 29 Aug 2019 14:42:08 +0200 Subject: Enable debug plugin check for MinGW / Unix in debug_and_release mode In the case when the Qt build is debug_and_release the debug plugin check should be enabled, otherwise the mixture of Qt debug and Qt release libraries will cause crashes (e.g. QTBUG-77431) Task-number: QTBUG-78445 Change-Id: Ice0b03e63ddad893334a0e1a4ede1f6ace83007b Reviewed-by: Simon Hausmann --- src/corelib/plugin/qlibrary.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 98a198df43..eeaa3c18ec 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -74,7 +74,7 @@ QT_BEGIN_NAMESPACE # define QLIBRARY_AS_DEBUG true #endif -#if defined(Q_OS_UNIX) +#if defined(Q_OS_UNIX) || (defined(Q_CC_MINGW) && !QT_CONFIG(debug_and_release)) // We don't use separate debug and release libs on UNIX, so we want // to allow loading plugins, regardless of how they were built. # define QT_NO_DEBUG_PLUGIN_CHECK -- cgit v1.2.3 From 217dd1b3b03cd40b4bb926631464c684f7f84a69 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 16 Sep 2019 13:55:57 +0200 Subject: Mark stationary touch points as updated if pressure or velocity changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is to inform Qt Quick when a stationary touchpoint is delivered that it is because of a changed property. Qt Quick still needs to avoid delivering item-customized events (with only the touch points that occur inside the item) that contain only stationary touch points without changed properties. To be able to check this private flag, QQuickPointerTouchEvent needs to be a friend. Task-number: QTBUG-77142 Change-Id: I6ee0dffbbeca9e513c77227b757252e2eec6a4ef Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qevent.h | 1 + src/gui/kernel/qevent_p.h | 4 +++- src/gui/kernel/qguiapplication.cpp | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index b73d90529a..bf00d4a9a3 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -959,6 +959,7 @@ public: friend class QGuiApplicationPrivate; friend class QApplication; friend class QApplicationPrivate; + friend class QQuickPointerTouchEvent; }; #if QT_DEPRECATED_SINCE(5, 0) diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index c2d8bd72b9..b7645496f8 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -67,7 +67,8 @@ public: state(Qt::TouchPointReleased), pressure(-1), rotation(0), - ellipseDiameters(0, 0) + ellipseDiameters(0, 0), + stationaryWithModifiedProperty(false) { } inline QTouchEventTouchPointPrivate *detach() @@ -91,6 +92,7 @@ public: QSizeF ellipseDiameters; QVector2D velocity; QTouchEvent::TouchPoint::InfoFlags flags; + bool stationaryWithModifiedProperty : 1; QVector rawScreenPositions; }; diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index a3ef3b2314..83ca337aaa 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2843,10 +2843,12 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To if (touchPoint.state() == Qt::TouchPointStationary) { if (touchInfo.touchPoint.velocity() != touchPoint.velocity()) { touchInfo.touchPoint.setVelocity(touchPoint.velocity()); + touchPoint.d->stationaryWithModifiedProperty = true; stationaryTouchPointChangedProperty = true; } if (!qFuzzyCompare(touchInfo.touchPoint.pressure(), touchPoint.pressure())) { touchInfo.touchPoint.setPressure(touchPoint.pressure()); + touchPoint.d->stationaryWithModifiedProperty = true; stationaryTouchPointChangedProperty = true; } } else { -- cgit v1.2.3 From 7db335a77e9efcfc8e0d4c1bd0834100403ec3b1 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 9 Sep 2019 13:13:34 +0200 Subject: Add back QWheelEvent position() and globalPosition() docs Change 7d29807296cb7ccc7f3459e106d74f93a321c493 removed the docs for the obsolete pos() and globalPos() accessors, but the text should have been reused to document their replacements. Change-Id: If4d64e0f07666a99d9a0a4f0de9fca42d3acf0f8 Reviewed-by: Sona Kurazyan --- src/gui/kernel/qevent.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 616cca1422..d41e3e5e3c 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -931,6 +931,30 @@ QWheelEvent::~QWheelEvent() \endlist */ +/*! + \fn QPoint QWheelEvent::position() const + + Returns the position of the mouse cursor relative to the widget + that received the event. + + If you move your widgets around in response to mouse events, + use globalPosition() instead of this function. + + \sa globalPosition() +*/ + +/*! + \fn QPoint QWheelEvent::globalPosition() const + + Returns the global position of the mouse pointer \e{at the time + of the event}. This is important on asynchronous window systems + such as X11; whenever you move your widgets around in response to + mouse events, globalPosition() can differ a lot from the current + cursor position returned by QCursor::pos(). + + \sa position() +*/ + #if QT_DEPRECATED_SINCE(5, 15) /*! \fn int QWheelEvent::delta() const -- cgit v1.2.3 From cb54c16584cf3be746a1a536c1e37cb3022a2f1b Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 6 Sep 2019 22:38:45 +0200 Subject: Cleanup QtWidgets (widgets) examples Cleanup QtWidgets widgets examples: - use member-init (clang-tidy) - fix includes/don't include QtWidgets globally - include own header first - use nullptr (clang-tidy) - avoid c-style casts - use QVector instead QList Change-Id: Ib56bb507eb2ef885f1ddc664050d3c7af92adb70 Reviewed-by: Friedemann Kleint --- examples/widgets/doc/src/calculator.qdoc | 3 ++ examples/widgets/doc/src/tooltips.qdoc | 2 +- .../widgets/widgets/analogclock/analogclock.cpp | 4 ++- examples/widgets/widgets/calculator/button.cpp | 2 -- examples/widgets/widgets/calculator/calculator.cpp | 22 ++++++------- examples/widgets/widgets/calendarwidget/main.cpp | 2 +- examples/widgets/widgets/calendarwidget/window.cpp | 19 +++++++---- .../widgets/charactermap/characterwidget.cpp | 37 ++++++++++++---------- .../widgets/widgets/charactermap/characterwidget.h | 6 ++-- .../widgets/widgets/charactermap/mainwindow.cpp | 22 ++++++++++--- examples/widgets/widgets/codeeditor/codeeditor.cpp | 11 ++++--- examples/widgets/widgets/codeeditor/codeeditor.h | 13 ++++---- examples/widgets/widgets/codeeditor/main.cpp | 2 +- .../widgets/widgets/digitalclock/digitalclock.cpp | 3 +- examples/widgets/widgets/groupbox/window.cpp | 9 ++++-- examples/widgets/widgets/icons/iconpreviewarea.cpp | 3 +- examples/widgets/widgets/icons/iconsizespinbox.cpp | 2 +- examples/widgets/widgets/icons/imagedelegate.cpp | 2 +- examples/widgets/widgets/icons/mainwindow.cpp | 23 +++++++++++--- .../widgets/widgets/imageviewer/imageviewer.cpp | 23 ++++++++++++-- examples/widgets/widgets/imageviewer/imageviewer.h | 2 +- examples/widgets/widgets/lineedits/window.cpp | 13 ++++++-- examples/widgets/widgets/movie/movieplayer.cpp | 10 +++++- examples/widgets/widgets/scribble/mainwindow.cpp | 26 ++++++++------- examples/widgets/widgets/scribble/scribblearea.cpp | 11 +++---- examples/widgets/widgets/scribble/scribblearea.h | 8 ++--- .../widgets/widgets/shapedclock/shapedclock.cpp | 9 ++++-- examples/widgets/widgets/sliders/slidersgroup.cpp | 5 ++- examples/widgets/widgets/sliders/window.cpp | 9 ++++-- examples/widgets/widgets/spinboxes/window.cpp | 10 ++++-- .../widgets/widgets/styles/norwegianwoodstyle.cpp | 5 ++- examples/widgets/widgets/styles/widgetgallery.cpp | 19 ++++++++++- examples/widgets/widgets/stylesheet/main.cpp | 2 +- examples/widgets/widgets/stylesheet/mainwindow.cpp | 4 +-- examples/widgets/widgets/stylesheet/mainwindow.h | 2 +- .../widgets/stylesheet/stylesheeteditor.cpp | 4 ++- examples/widgets/widgets/tablet/main.cpp | 2 -- examples/widgets/widgets/tablet/mainwindow.cpp | 11 +++++-- examples/widgets/widgets/tablet/mainwindow.h | 2 +- .../widgets/widgets/tablet/tabletapplication.cpp | 2 -- examples/widgets/widgets/tablet/tabletcanvas.cpp | 29 ++++++++--------- examples/widgets/widgets/tablet/tabletcanvas.h | 25 +++++++-------- examples/widgets/widgets/tetrix/tetrixboard.cpp | 10 +++--- examples/widgets/widgets/tetrix/tetrixpiece.cpp | 2 +- examples/widgets/widgets/tetrix/tetrixwindow.cpp | 15 +++++---- examples/widgets/widgets/tooltips/main.cpp | 2 +- examples/widgets/widgets/tooltips/sortingbox.cpp | 14 +++++--- examples/widgets/widgets/tooltips/sortingbox.h | 2 +- .../widgets/widgets/validators/validatorwidget.cpp | 2 +- examples/widgets/widgets/wiggly/wigglywidget.cpp | 9 +++--- .../widgets/windowflags/controllerwindow.cpp | 30 ++++++++++-------- .../widgets/widgets/windowflags/previewwindow.cpp | 21 ++++++------ 52 files changed, 330 insertions(+), 197 deletions(-) diff --git a/examples/widgets/doc/src/calculator.qdoc b/examples/widgets/doc/src/calculator.qdoc index e8f8030207..7d34a86c19 100644 --- a/examples/widgets/doc/src/calculator.qdoc +++ b/examples/widgets/doc/src/calculator.qdoc @@ -142,6 +142,9 @@ pendingAdditiveOperator and \c pendingMultiplicativeOperator variables don't need to be initialized explicitly, because the QString constructor initializes them to empty strings. + It is also possible to initialize those variable directly in the + header. This is called \c member-initializaton and avoids a long + initialization list. \snippet widgets/calculator/calculator.cpp 1 \snippet widgets/calculator/calculator.cpp 2 diff --git a/examples/widgets/doc/src/tooltips.qdoc b/examples/widgets/doc/src/tooltips.qdoc index a278215503..35e3b1e29f 100644 --- a/examples/widgets/doc/src/tooltips.qdoc +++ b/examples/widgets/doc/src/tooltips.qdoc @@ -95,7 +95,7 @@ \snippet widgets/tooltips/sortingbox.h 2 - We keep all the shape items in a QList, and we keep three + We keep all the shape items in a QVector, and we keep three QPainterPath objects holding the shapes of a circle, a square and a triangle. We also need to have a pointer to an item when it is moving, and we need to know its previous position. diff --git a/examples/widgets/widgets/analogclock/analogclock.cpp b/examples/widgets/widgets/analogclock/analogclock.cpp index c7b3f66cca..06e298659d 100644 --- a/examples/widgets/widgets/analogclock/analogclock.cpp +++ b/examples/widgets/widgets/analogclock/analogclock.cpp @@ -50,7 +50,9 @@ #include "analogclock.h" -#include +#include +#include +#include //! [0] //! [1] AnalogClock::AnalogClock(QWidget *parent) diff --git a/examples/widgets/widgets/calculator/button.cpp b/examples/widgets/widgets/calculator/button.cpp index a1ce0bf428..cc370a563c 100644 --- a/examples/widgets/widgets/calculator/button.cpp +++ b/examples/widgets/widgets/calculator/button.cpp @@ -50,8 +50,6 @@ #include "button.h" -#include - //! [0] Button::Button(const QString &text, QWidget *parent) : QToolButton(parent) diff --git a/examples/widgets/widgets/calculator/calculator.cpp b/examples/widgets/widgets/calculator/calculator.cpp index dd908cf40a..2c3669b7a8 100644 --- a/examples/widgets/widgets/calculator/calculator.cpp +++ b/examples/widgets/widgets/calculator/calculator.cpp @@ -48,21 +48,18 @@ ** ****************************************************************************/ -#include "button.h" #include "calculator.h" +#include "button.h" -#include - -#include +#include +#include +#include //! [0] Calculator::Calculator(QWidget *parent) - : QWidget(parent) + : QWidget(parent), sumInMemory(0.0), sumSoFar(0.0) + , factorSoFar(0.0), waitingForOperand(true) { - sumInMemory = 0.0; - sumSoFar = 0.0; - factorSoFar = 0.0; - waitingForOperand = true; //! [0] //! [1] @@ -78,9 +75,8 @@ Calculator::Calculator(QWidget *parent) //! [2] //! [4] - for (int i = 0; i < NumDigitButtons; ++i) { + for (int i = 0; i < NumDigitButtons; ++i) digitButtons[i] = createButton(QString::number(i), SLOT(digitClicked())); - } Button *pointButton = createButton(tr("."), SLOT(pointClicked())); Button *changeSignButton = createButton(tr("\302\261"), SLOT(changeSignClicked())); @@ -194,6 +190,8 @@ void Calculator::additiveOperatorClicked() //! [10] //! [11] { Button *clickedButton = qobject_cast