diff options
119 files changed, 1837 insertions, 1083 deletions
diff --git a/LICENSE.LGPLv21 b/LICENSE.LGPLv21 index 6e18461125..ca5adae7e9 100644 --- a/LICENSE.LGPLv21 +++ b/LICENSE.LGPLv21 @@ -1,6 +1,6 @@ GNU LESSER GENERAL PUBLIC LICENSE - The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd. + The Qt Toolkit is Copyright (C) 2016 The Qt Company Ltd. Contact: http://www.qt.io/licensing/ You may use, distribute and copy the Qt GUI Toolkit under the terms of diff --git a/LICENSE.LGPLv3 b/LICENSE.LGPLv3 index 4d67bac0b4..d3268e665e 100644 --- a/LICENSE.LGPLv3 +++ b/LICENSE.LGPLv3 @@ -1,6 +1,6 @@ GNU LESSER GENERAL PUBLIC LICENSE - The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd. + The Qt Toolkit is Copyright (C) 2016 The Qt Company Ltd. Contact: http://www.qt.io/licensing/ You may use, distribute and copy the Qt GUI Toolkit under the terms of diff --git a/config.tests/unix/compile.test b/config.tests/unix/compile.test index 9c0a7cb845..c8929a37f1 100755 --- a/config.tests/unix/compile.test +++ b/config.tests/unix/compile.test @@ -72,7 +72,7 @@ test -r Makefile && $MAKE distclean >/dev/null 2>&1 # Make sure output from possible previous tests is gone rm -f "$EXE" "${EXE}.exe" -set -- "$QMAKE" -qtconf "$QTCONF" -nocache -spec "$QMKSPEC" "CONFIG+=$QMAKE_CONFIG" "CONFIG+=android_app" "CONFIG-=debug_and_release app_bundle lib_bundle" "LIBS*=$LFLAGS" "LIBS+=$MAC_ARCH_LFLAGS" "INCLUDEPATH*=$INCLUDEPATH" "QMAKE_CXXFLAGS*=$CXXFLAGS" "QMAKE_CXXFLAGS+=$MAC_ARCH_CXXFLAGS" $QMAKE_ARGS "$SRCDIR/$TEST/$EXE.pro" -o "$OUTDIR/$TEST/Makefile" +set -- "$QMAKE" -qtconf "$QTCONF" -nocache -spec "$QMKSPEC" "CONFIG+=$QMAKE_CONFIG" "CONFIG+=android_app" "CONFIG-=debug_and_release app_bundle lib_bundle" "LIBS+=$LFLAGS" "LIBS+=$MAC_ARCH_LFLAGS" "INCLUDEPATH*=$INCLUDEPATH" "QMAKE_CXXFLAGS*=$CXXFLAGS" "QMAKE_CXXFLAGS+=$MAC_ARCH_CXXFLAGS" $QMAKE_ARGS "$SRCDIR/$TEST/$EXE.pro" -o "$OUTDIR/$TEST/Makefile" if [ "$VERBOSE" = "yes" ]; then OUTDIR=$OUTDIR "$@" && $MAKE && SUCCESS=yes else diff --git a/doc/global/config.qdocconf b/doc/global/config.qdocconf index 35e7535824..97357345c9 100644 --- a/doc/global/config.qdocconf +++ b/doc/global/config.qdocconf @@ -3,7 +3,7 @@ dita.metadata.default.author = Qt Project dita.metadata.default.permissions = all dita.metadata.default.publisher = Qt Project -dita.metadata.default.copyryear = 2015 +dita.metadata.default.copyryear = 2016 dita.metadata.default.copyrholder = The Qt Company Ltd dita.metadata.default.audience = programmer diff --git a/doc/global/html-footer-online.qdocconf b/doc/global/html-footer-online.qdocconf index 18022cabff..86f75ab073 100644 --- a/doc/global/html-footer-online.qdocconf +++ b/doc/global/html-footer-online.qdocconf @@ -78,7 +78,7 @@ HTML.footer += \ " <ul id=\"menu-footer-submenu\" class=\"right clearfix\"><li id=\"menu-item-1795\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1795\"><a title=\"Sign into your account.\" href=\"https://account.qt.io/login\">Sign In</a></li>\n" \ " <li id=\"menu-item-10375\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-10375\"><a href=\"mailto:feedback@theqtcompany.com?Subject=Feedback%20about%20doc.qt.io%20site\">Feedback</a></li>\n" \ " <li id=\"menu-item-1494\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1494\"><a href=\"http://qt.io/contact-us/\">Contact us</a></li>\n" \ - " <li id=\"menu-item-4472\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4472\"><a href=\"http://qt.io/about-us/\">© 2015 The Qt Company</a></li>\n" \ + " <li id=\"menu-item-4472\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4472\"><a href=\"http://qt.io/about-us/\">© 2016 The Qt Company</a></li>\n" \ " </ul>\n" \ "</div>\n" \ "</div>\n" \ diff --git a/doc/global/html-footer.qdocconf b/doc/global/html-footer.qdocconf index e41f6dc5c5..d350bc4772 100644 --- a/doc/global/html-footer.qdocconf +++ b/doc/global/html-footer.qdocconf @@ -8,7 +8,7 @@ HTML.footer = \ "</div>\n" \ "<div class=\"footer\">\n" \ " <p>\n" \ - " <acronym title=\"Copyright\">©</acronym> 2015 The Qt Company Ltd.\n" \ + " <acronym title=\"Copyright\">©</acronym> 2016 The Qt Company Ltd.\n" \ " Documentation contributions included herein are the copyrights of\n" \ " their respective owners.<br>" \ " The documentation provided herein is licensed under the terms of the" \ diff --git a/doc/global/qt-module-defaults-online.qdocconf b/doc/global/qt-module-defaults-online.qdocconf index 3085b493fe..fb8c261804 100644 --- a/doc/global/qt-module-defaults-online.qdocconf +++ b/doc/global/qt-module-defaults-online.qdocconf @@ -5,7 +5,7 @@ HTML.footer = \ " </div>\n" \ " <p class=\"copy-notice\">\n" \ - " <acronym title=\"Copyright\">©</acronym> 2015 The Qt Company Ltd.\n" \ + " <acronym title=\"Copyright\">©</acronym> 2016 The Qt Company Ltd.\n" \ " Documentation contributions included herein are the copyrights of\n" \ " their respective owners. " \ " The documentation provided herein is licensed under the terms of the" \ diff --git a/doc/global/template/style/offline.css b/doc/global/template/style/offline.css index 1f76efbd38..1c5a2dfa61 100644 --- a/doc/global/template/style/offline.css +++ b/doc/global/template/style/offline.css @@ -5,6 +5,7 @@ body { text-align: left; margin-left: 5px; margin-right: 5px; + background-color: #fff; } p { diff --git a/examples/widgets/doc/src/tablet.qdoc b/examples/widgets/doc/src/tablet.qdoc index bc03d46332..88012fd30f 100644 --- a/examples/widgets/doc/src/tablet.qdoc +++ b/examples/widgets/doc/src/tablet.qdoc @@ -34,41 +34,41 @@ \image tabletexample.png When you use a tablet with Qt applications, \l{QTabletEvent}s are - generated. You need to reimplement the - \l{QWidget::}{tabletEvent()} event handler if you want to handle - tablet events. Events are generated when the device used for - drawing enters and leaves the proximity of the tablet (i.e., when - it is close but not pressed down on it), when a device is pushed - down and released from it, and when a device is moved on the - tablet. - - The information available in QTabletEvent depends on the device - used. The tablet in this example has two different devices for - drawing: a stylus and an airbrush. For both devices the event - contains the position of the device, pressure on the tablet, - vertical tilt, and horizontal tilt (i.e, the angle between the - device and the perpendicular of the tablet). The airbrush has a - finger wheel; the position of this is also available in the tablet - event. - - In this example we implement a drawing program. You can use the - stylus to draw on the tablet as you use a pencil on paper. When - you draw with the airbrush you get a spray of paint; the finger - wheel is used to change the density of the spray. The pressure and - tilt can change the alpha and saturation values of the QColor and the - width of the QPen used for drawing. + generated. You need to reimplement the \l{QWidget::}{tabletEvent()} event + handler if you want to handle tablet events. Events are generated when the + tool (stylus) used for drawing enters and leaves the proximity of the + tablet (i.e., when it is close but not pressed down on it), when the tool + is pressed down and released from it, when the tool is moved across the + tablet, and when one of the buttons on the tool is pressed or released. + + The information available in QTabletEvent depends on the device used. + This example can handle a tablet with up to three different drawing tools: + a stylus, an airbrush, and an art pen. For any of these the event will + contain the position of the tool, pressure on the tablet, button status, + vertical tilt, and horizontal tilt (i.e, the angle between the device and + the perpendicular of the tablet, if the tablet hardware can provide it). + The airbrush has a finger wheel; the position of this is also available + in the tablet event. The art pen provides rotation around the axis + perpendicular to the tablet surface, so that it can be used for calligraphy. + + In this example we implement a drawing program. You can use the stylus to + draw on the tablet as you use a pencil on paper. When you draw with the + airbrush you get a spray of virtual paint; the finger wheel is used to + change the density of the spray. When you draw with the art pen, you get a + a line whose width and endpoint angle depend on the rotation of the pen. + The pressure and tilt can also be assigned to change the alpha and + saturation values of the color and the width of the stroke. The example consists of the following: \list - \li The \c MainWindow class inherits QMainWindow and creates - the examples menus and connect their slots and signals. + \li The \c MainWindow class inherits QMainWindow, creates + the menus, and connects their slots and signals. \li The \c TabletCanvas class inherits QWidget and - receives tablet events. It uses the events to paint on a - offscreen pixmap, which it draws onto itself. + receives tablet events. It uses the events to paint onto an + offscreen pixmap, and then renders it. \li The \c TabletApplication class inherits QApplication. This - class handles tablet events that are not sent to \c tabletEvent(). - We will look at this later. + class handles tablet proximity events. \li The \c main() function creates a \c MainWindow and shows it as a top level window. \endlist @@ -81,110 +81,99 @@ \snippet widgets/tablet/mainwindow.h 0 - The QActions let the user select if the tablets pressure and - tilt should change the pen width, color alpha component and color - saturation. \c createActions() creates all actions, and \c - createMenus() sets up the menus with the actions. We have one - QActionGroup for the actions that alter the alpha channel, color - saturation and line width respectively. The action groups are - connected to the \c alphaActionTriggered(), \c - colorSaturationActiontriggered(), and \c - lineWidthActionTriggered() slots, which calls functions in \c - myCanvas. - + \c createMenus() sets up the menus with the actions. We have one + QActionGroup for the actions that alter the alpha channel, color saturation + and line width respectively. The action groups are connected to the + \c setAlphaValuator(), \c setSaturationValuator(), and + \c setLineWidthValuator() slots, which call functions in \c TabletCanvas. \section1 MainWindow Class Implementation - We start width a look at the constructor \c MainWindow(): + We start with a look at the constructor \c MainWindow(): \snippet widgets/tablet/mainwindow.cpp 0 - In the constructor we create the canvas, actions, and menus. - We set the canvas as the center widget. We also initialize the - canvas to match the state of our menus and start drawing with a - red color. - - Here is the implementation of \c brushColorAct(): + In the constructor we call \c createMenus() to create all the actions and + menus, and set the canvas as the center widget. - \snippet widgets/tablet/mainwindow.cpp 1 + \snippet widgets/tablet/mainwindow.cpp 8 - We let the user pick a color with a QColorDialog. If it is valid, - we set a new drawing color with \c setColor(). + At the beginning of \c createMenus() we populate the \b File menu. + We use an overload of \l{QMenu::}{addAction()}, introduced in Qt 5.6, to create + a menu item with a shortcut (and optionally an icon), add it to its menu, + and connect it to a slot, all with one line of code. We use QKeySequence to + get the platform-specific standard key shortcuts for these common menu items. - Here is the implementation of \c alphaActionTriggered(): + We also populate the \b Brush menu. The command to change a brush does not + normally have a standard shortcut, so we use \l{QObject::}{tr()} to enable + translating the shortcut along with the language translation of the application. - \snippet widgets/tablet/mainwindow.cpp 2 + Now we will look at the creation of one group of mutually-exclusive actions + in a submenu of the \b Tablet menu, for selecting which property of each + QTabletEvent will be used to vary the translucency (alpha channel) of the + line being drawn or color being airbrushed. + (See the \l{Application Example}{application example} if you want a + high-level introduction to QActions.) - The \c TabletCanvas class supports two ways by which the alpha - channel of the drawing color can be changed: tablet pressure and - tilt. We have one action for each and an action if the alpha - channel should not be changed. + \snippet widgets/tablet/mainwindow.cpp 9 - Here is the implementation of \c lineWidthActionTriggered(): + We want the user to be able to choose whether the drawing color's alpha + component should be modulated by the tablet pressure, tilt, or the position + of the thumbwheel on the airbrush tool. We have one action for each choice, + and an additional action to choose not to change the alpha, that is, to keep + the color opaque. We make the actions checkable; the \c alphaChannelGroup + will then ensure that only one of the actions are checked at any time. The + \c triggered() signal is emitted from the group when an action is checked, + so we connect that to \c MainWindow::setAlphaValuator(). It will need to know + which property (valuator) of the QTabletEvent to pay attention to from now + on, so we use the QAction::data property to pass this information along. + (In order for this to be possible, the enum \c Valuator must be a registered + metatype, so that it can be inserted into a QVariant. That is accomplished + by the \c Q_ENUM declaration in tabletcanvas.h.) + + Here is the implementation of \c setAlphaValuator(): - \snippet widgets/tablet/mainwindow.cpp 3 + \snippet widgets/tablet/mainwindow.cpp 2 - We check which action is selected in \c lineWidthGroup, and set - how the canvas should change the drawing line width. + It simply needs to retrieve the \c Valuator enum from QAction::data(), and + pass that to \c TabletCanvas::setAlphaChannelValuator(). If we were not + using the \c data property, we would instead need to compare the QAction + pointer itself, for example in a switch statement. But that would require + keeping pointers to each QAction in class variables, for comparison purposes. - Here is the implementation of \c saturationActionTriggered(): + Here is the implementation of \c setBrushColor(): - \snippet widgets/tablet/mainwindow.cpp 4 + \snippet widgets/tablet/mainwindow.cpp 1 - We check which action is selected in \c colorSaturationGroup, and - set how the canvas should change the color saturation of the - drawing color. + We do lazy initialization of a QColorDialog the first time the user + chooses \b {Brush color...} from the menu or via the action shortcut. + While the dialog is open, each time the user chooses a different color, + \c TabletCanvas::setColor() will be called to change the drawing color. + Because it is a non-modal dialog, the user is free to leave the color + dialog open, so as to be able to conveniently and frequently change colors, + or close it and re-open it later. - Here is the implementation of \c saveAct(): + Here is the implementation of \c save(): \snippet widgets/tablet/mainwindow.cpp 5 - We use the QFileDialog to let the user select a file to save the - drawing in. It is the \c TabletCanvas that save the drawing, so we - call its \c saveImage() function. + We use the QFileDialog to let the user select a file to save the drawing, + and then call \c TabletCanvas::saveImage() to actually write it to the + file. - Here is the implementation of \c loadAct(): + Here is the implementation of \c load(): \snippet widgets/tablet/mainwindow.cpp 6 - We let the user select the image file to be opened with - a QFileDialog; we then ask the canvas to load the image with \c - loadImage(). + We let the user select the image file to be opened with a QFileDialog; we + then ask the canvas to load the image with \c loadImage(). - Here is the implementation of \c aboutAct(): + Here is the implementation of \c about(): \snippet widgets/tablet/mainwindow.cpp 7 We show a message box with a short description of the example. - \c createActions() creates all actions and action groups of - the example. We look at the creation of one action group and its - actions. See the \l{Application Example}{application example} if - you want a high-level introduction to QActions. - - Here is the implementation of \c createActions: - - \snippet widgets/tablet/mainwindow.cpp 8 - \dots - \snippet widgets/tablet/mainwindow.cpp 9 - - We want the user to be able to choose if the drawing color's - alpha component should be changed by the tablet pressure or tilt. - We have one action for each choice and an action if the alpha - channel is not to be changed, i.e, the color is opaque. We make - the actions checkable; the \c alphaChannelGroup will then ensure - that only one of the actions are checked at any time. The \c - triggered() signal is emitted when an action is checked. - - \dots - \snippet widgets/tablet/mainwindow.cpp 10 - - Here is the implementation of \c createMenus(): - - \snippet widgets/tablet/mainwindow.cpp 11 - - We create the menus of the example and add the actions to them. - \section1 TabletCanvas Class Definition @@ -193,24 +182,22 @@ \snippet widgets/tablet/tabletcanvas.h 0 - The canvas can change the alpha channel, color saturation, - and line width of the drawing. We have one enum for each of - these; their values decide if it is the tablet pressure or tilt - that will alter them. We keep a private variable for each, the \c - alphaChannelType, \c colorSturationType, and \c penWidthType, - which we provide access functions for. + The canvas can change the alpha channel, color saturation, and line width + of the stroke. We have an enum listing the QTabletEvent properties with + which it is possible to modulate them. We keep a private variable for each: + \c m_alphaChannelValuator, \c m_colorSaturationValuator and + \c m_lineWidthValuator, and we provide accessor functions for them. - We draw on a QPixmap with \c myPen and \c myBrush using \c - myColor. The \c saveImage() and \c loadImage() saves and loads - the QPixmap to disk. The pixmap is drawn on the widget in \c - paintEvent(). The \c pointerType and \c deviceType keeps the type - of pointer, which is either a pen or an eraser, and device - currently used on the tablet, which is either a stylus or an - airbrush. + We draw on a QPixmap with \c m_pen and \c m_brush using \c m_color. + Each time a QTabletEvent is received, the stroke is drawn from + \c lastPoint to the point given in the current QTabletEvent, + and then the position and rotation are saved in \c lastPoint for next time. + The \c saveImage() and \c loadImage() functions save and load the QPixmap to disk. + The pixmap is drawn on the widget in \c paintEvent(). - The interpretation of events from the tablet is done in \c - tabletEvent(); \c paintPixmap(), \c updateBrush(), and \c - brushPattern() are helper functions used by \c tabletEvent(). + The interpretation of events from the tablet is done in \c tabletEvent(), and + \c paintPixmap(), \c updateBrush(), and \c updateCursor() are helper + functions used by \c tabletEvent(). \section1 TabletCanvas Class Implementation @@ -233,21 +220,28 @@ \snippet widgets/tablet/tabletcanvas.cpp 2 - We simply call \l{QPixmap::}{load()}, which loads the image in \a - file. + We simply call \l{QPixmap::}{load()}, which loads the image from \a file. Here is the implementation of \c tabletEvent(): \snippet widgets/tablet/tabletcanvas.cpp 3 - We get three kind of events to this function: TabletPress, - TabletRelease, and TabletMove, which is generated when a device - is pressed down on, leaves, or moves on the tablet. We set the \c - deviceDown to true when a device is pressed down on the tablet; - we then know when we should draw when we receive move events. We - have implemented the \c updateBrush() and \c paintPixmap() helper - functions to update \c myBrush and \c myPen after the state of \c - alphaChannelType, \c colorSaturationType, and \c lineWidthType. + We get three kind of events to this function: \c TabletPress, \c TabletRelease, + and \c TabletMove, which are generated when a drawing tool is pressed down on, + lifed up from, or moved across the tablet. We set \c m_deviceDown to \c true + when a device is pressed down on the tablet; we then know that we should + draw when we receive move events. We have implemented \c updateBrush() + to update \c m_brush and \c m_pen depending on which of the tablet event + properties the user has chosen to pay attention to. The \c updateCursor() + function selects a cursor to represent the drawing tool in use, so that + as you hover with the tool in proximity of the tablet, you can see what + kind of stroke you are about to make. + + \snippet widgets/tablet/tabletcanvas.cpp 12 + + If an art pen (\c RotationStylus) is in use, \c updateCursor() + is also called for each \c TabletMove event, and renders a rotated cursor + so that you can see the angle of the pen tip. Here is the implementation of \c paintEvent(): @@ -259,22 +253,22 @@ \snippet widgets/tablet/tabletcanvas.cpp 5 - In this function we draw on the pixmap based on the movement of the device. - If the device used on the tablet is a stylus, we want to draw a line from + In this function we draw on the pixmap based on the movement of the tool. + If the tool used on the tablet is a stylus, we want to draw a line from the last-known position to the current position. We also assume that this is a reasonable handling of any unknown device, but update the status bar with a warning. If it is an airbrush, we want to draw a circle filled with a soft gradient, whose density can depend on various event parameters. By default it depends on the tangential pressure, which is the position of - the finger wheel on the airbrush. If it is a rotation stylus, we simulate - a felt marker by drawing trapezoidal strokes. + the finger wheel on the airbrush. If the tool is a rotation stylus, we + simulate a felt marker by drawing trapezoidal stroke segments. \snippet widgets/tablet/tabletcanvas.cpp 6 - In \c updateBrush() we set the pen and brush used for drawing - to match \c alphaChannelType, \c lineWidthType, \c - colorSaturationType, and \c myColor. We will examine the code to - set up \c myBrush and \c myPen for each of these variables: + In \c updateBrush() we set the pen and brush used for drawing to match + \c m_alphaChannelValuator, \c m_lineWidthValuator, \c m_colorSaturationValuator, + and \c m_color. We will examine the code to set up \c m_brush and + \c m_pen for each of these variables: \snippet widgets/tablet/tabletcanvas.cpp 7 @@ -288,34 +282,33 @@ \snippet widgets/tablet/tabletcanvas.cpp 8 - The alpha channel of QColor is given as a number between 0 - and 255 where 0 is transparent and 255 is opaque. - \l{QTabletEvent::}{pressure()} returns the pressure as a qreal - between 0.0 and 1.0. By subtracting 127 from the tilt values and - taking the absolute value we get the smallest alpha values (i.e., - the color is most transparent) when the pen is perpendicular to - the tablet. We select the largest of the vertical and horizontal - tilt value. + The alpha channel of QColor is given as a number between 0 and 255 where 0 + is transparent and 255 is opaque, or as a floating-point number where 0 is + transparent and 1.0 is opaque. \l{QTabletEvent::}{pressure()} returns the + pressure as a qreal between 0.0 and 1.0. We get the smallest alpha values + (i.e., the color is most transparent) when the pen is perpendicular to the + tablet. We select the largest of the vertical and horizontal tilt values. \snippet widgets/tablet/tabletcanvas.cpp 9 - The colorsaturation is given as a number between 0 and 255. It is - set with \l{QColor::}{setHsv()}. We can set the tilt values - directly, but must multiply the pressure to a number between 0 and - 255. + The color saturation in the HSV color model can be given as an integer + between 0 and 255 or as a floating-point value between 0 and 1. We chose to + represent alpha as an integer, so we call \l{QColor::}{setHsv()} with + integer values. That means we need to multiply the pressure to a number + between 0 and 255. \snippet widgets/tablet/tabletcanvas.cpp 10 - The width of the pen increases with the pressure. When the pen - width is controlled with the tilt we let the width increse with - the angle between the device and the perpendicular of the tablet. + The width of the pen stroke can increase with pressure, if so chosen. + But when the pen width is controlled by tilt, we let the width increase + with the angle between the tool and the perpendicular of the tablet. \snippet widgets/tablet/tabletcanvas.cpp 11 We finally check whether the pointer is the stylus or the eraser. If it is the eraser, we set the color to the background color of - the pixmap an let the pressure decide the pen width, else we set - the colors we have set up previously in the function. + the pixmap and let the pressure decide the pen width, else we set + the colors we have decided previously in the function. \section1 TabletApplication Class Definition @@ -325,13 +318,11 @@ \snippet widgets/tablet/tabletapplication.h 0 - We keep a \c TabletCanvas we send the device type of the events we - handle in the \c event() function to. The TabletEnterProximity - and TabletLeaveProximity events are not sendt to the QApplication - object, while other tablet events are sendt to the QWidget's - \c event(), which sends them on to \l{QWidget::}{tabletEvent()}. - Since we want to handle these events we have implemented \c - TabletApplication. + \c TabletApplication exists as a subclass of QApplication in order to + receive tablet proximity events and forward them to \c TabletCanvas. + The \c TabletEnterProximity and \c TabletLeaveProximity events are sent to + the QApplication object, while other tablet events are sent to the QWidget's + \c event() hander, which sends them on to \l{QWidget::}{tabletEvent()}. \section1 TabletApplication Class Implementation @@ -340,24 +331,24 @@ \snippet widgets/tablet/tabletapplication.cpp 0 - We use this function to handle the TabletEnterProximity and - TabletLeaveProximity events, which is generated when a device - enters and leaves the proximity of the tablet. The intended use of these - events is to do work that is dependent on what kind of device is - used on the tablet. This way, you don't have to do this work - when other events are generated, which is more frequently than the - leave and enter proximity events. We call \c setTabletDevice() in - \c TabletCanvas. + We use this function to handle the \c TabletEnterProximity and + \c TabletLeaveProximity events, which are generated when a drawing + tool enters or leaves the proximity of the tablet. Here we call + \c TabletCanvas::setTabletDevice(), which then calls \c updateCursor(), + which will set an appropriate cursor. This is the only reason we + need the proximity events; for the purpose of correct drawing, it is + enough for \c TabletCanvas to observe the \l{QTabletEvent::}{device()} and + \l{QTabletEvent::}{pointerType()} in each event that it receives. + \section1 The \c main() function - Here is the examples \c main() function: + Here is the example's \c main() function: \snippet widgets/tablet/main.cpp 0 - In the \c main() function we create a \c MainWinow and display it - as a top level window. We use the \c TabletApplication class. We - need to set the canvas after the application is created. We cannot - use classes that implement event handling before an QApplication - object is instantiated. + Here we create a \c MainWindow and display it as a top level window. We use + the \c TabletApplication class. We need to set the canvas after the + application is created. We cannot use classes that implement event handling + before an QApplication object is instantiated. */ diff --git a/examples/widgets/widgets/tablet/mainwindow.cpp b/examples/widgets/widgets/tablet/mainwindow.cpp index 5e84f5b6a2..950a5a2e29 100644 --- a/examples/widgets/widgets/tablet/mainwindow.cpp +++ b/examples/widgets/widgets/tablet/mainwindow.cpp @@ -45,237 +45,172 @@ //! [0] MainWindow::MainWindow(TabletCanvas *canvas) + : m_canvas(canvas), m_colorDialog(Q_NULLPTR) { - myCanvas = canvas; - createActions(); createMenus(); - - myCanvas->setColor(Qt::red); - myCanvas->setLineWidthType(TabletCanvas::LineWidthPressure); - myCanvas->setAlphaChannelType(TabletCanvas::AlphaTangentialPressure); - myCanvas->setColorSaturationType(TabletCanvas::NoSaturation); - setWindowTitle(tr("Tablet Example")); - setCentralWidget(myCanvas); + setCentralWidget(m_canvas); } //! [0] //! [1] -void MainWindow::brushColorAct() +void MainWindow::setBrushColor() { - QColor color = QColorDialog::getColor(myCanvas->color()); - - if (color.isValid()) - myCanvas->setColor(color); + if (!m_colorDialog) { + m_colorDialog = new QColorDialog(this); + m_colorDialog->setModal(false); + m_colorDialog->setCurrentColor(m_canvas->color()); + connect(m_colorDialog, &QColorDialog::colorSelected, m_canvas, &TabletCanvas::setColor); + } + m_colorDialog->setVisible(true); } //! [1] //! [2] -void MainWindow::alphaActionTriggered(QAction *action) +void MainWindow::setAlphaValuator(QAction *action) { - if (action == alphaChannelPressureAction) { - myCanvas->setAlphaChannelType(TabletCanvas::AlphaPressure); - } else if (action == alphaChannelTangentialPressureAction) { - myCanvas->setAlphaChannelType(TabletCanvas::AlphaTangentialPressure); - } else if (action == alphaChannelTiltAction) { - myCanvas->setAlphaChannelType(TabletCanvas::AlphaTilt); - } else { - myCanvas->setAlphaChannelType(TabletCanvas::NoAlpha); - } + m_canvas->setAlphaChannelValuator(action->data().value<TabletCanvas::Valuator>()); } //! [2] //! [3] -void MainWindow::lineWidthActionTriggered(QAction *action) +void MainWindow::setLineWidthValuator(QAction *action) { - if (action == lineWidthPressureAction) { - myCanvas->setLineWidthType(TabletCanvas::LineWidthPressure); - } else if (action == lineWidthTiltAction) { - myCanvas->setLineWidthType(TabletCanvas::LineWidthTilt); - } else { - myCanvas->setLineWidthType(TabletCanvas::NoLineWidth); - } + m_canvas->setLineWidthType(action->data().value<TabletCanvas::Valuator>()); } //! [3] //! [4] -void MainWindow::saturationActionTriggered(QAction *action) +void MainWindow::setSaturationValuator(QAction *action) { - if (action == colorSaturationVTiltAction) { - myCanvas->setColorSaturationType(TabletCanvas::SaturationVTilt); - } else if (action == colorSaturationHTiltAction) { - myCanvas->setColorSaturationType(TabletCanvas::SaturationHTilt); - } else if (action == colorSaturationPressureAction) { - myCanvas->setColorSaturationType(TabletCanvas::SaturationPressure); - } else { - myCanvas->setColorSaturationType(TabletCanvas::NoSaturation); - } + m_canvas->setColorSaturationValuator(action->data().value<TabletCanvas::Valuator>()); } //! [4] //! [5] -void MainWindow::saveAct() +void MainWindow::save() { QString path = QDir::currentPath() + "/untitled.png"; QString fileName = QFileDialog::getSaveFileName(this, tr("Save Picture"), path); - if (!myCanvas->saveImage(fileName)) + if (!m_canvas->saveImage(fileName)) QMessageBox::information(this, "Error Saving Picture", "Could not save the image"); } //! [5] //! [6] -void MainWindow::loadAct() +void MainWindow::load() { QString fileName = QFileDialog::getOpenFileName(this, tr("Open Picture"), QDir::currentPath()); - if (!myCanvas->loadImage(fileName)) + if (!m_canvas->loadImage(fileName)) QMessageBox::information(this, "Error Opening Picture", "Could not open picture"); } //! [6] //! [7] -void MainWindow::aboutAct() +void MainWindow::about() { QMessageBox::about(this, tr("About Tablet Example"), - tr("This example shows use of a Wacom tablet in Qt")); + tr("This example shows how to use a graphics drawing tablet in Qt.")); } //! [7] //! [8] -void MainWindow::createActions() +void MainWindow::createMenus() { + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + fileMenu->addAction(tr("&Open..."), this, &MainWindow::load, QKeySequence::Open); + fileMenu->addAction(tr("&Save As..."), this, &MainWindow::save, QKeySequence::SaveAs); + fileMenu->addAction(tr("E&xit"), this, &MainWindow::close, QKeySequence::Quit); + + QMenu *brushMenu = menuBar()->addMenu(tr("&Brush")); + brushMenu->addAction(tr("&Brush Color..."), this, &MainWindow::setBrushColor, tr("Ctrl+B")); //! [8] - brushColorAction = new QAction(tr("&Brush Color..."), this); - brushColorAction->setShortcut(tr("Ctrl+C")); - connect(brushColorAction, SIGNAL(triggered()), - this, SLOT(brushColorAct())); + + QMenu *tabletMenu = menuBar()->addMenu(tr("&Tablet")); + QMenu *lineWidthMenu = tabletMenu->addMenu(tr("&Line Width")); + + QAction *lineWidthPressureAction = lineWidthMenu->addAction(tr("&Pressure")); + lineWidthPressureAction->setData(TabletCanvas::PressureValuator); + lineWidthPressureAction->setCheckable(true); + lineWidthPressureAction->setChecked(true); + + QAction *lineWidthTiltAction = lineWidthMenu->addAction(tr("&Tilt")); + lineWidthTiltAction->setData(TabletCanvas::TiltValuator); + lineWidthTiltAction->setCheckable(true); + + QAction *lineWidthFixedAction = lineWidthMenu->addAction(tr("&Fixed")); + lineWidthFixedAction->setData(TabletCanvas::NoValuator); + lineWidthFixedAction->setCheckable(true); + + QActionGroup *lineWidthGroup = new QActionGroup(this); + lineWidthGroup->addAction(lineWidthPressureAction); + lineWidthGroup->addAction(lineWidthTiltAction); + lineWidthGroup->addAction(lineWidthFixedAction); + connect(lineWidthGroup, &QActionGroup::triggered, this, + &MainWindow::setLineWidthValuator); //! [9] - alphaChannelPressureAction = new QAction(tr("&Pressure"), this); + QMenu *alphaChannelMenu = tabletMenu->addMenu(tr("&Alpha Channel")); + QAction *alphaChannelPressureAction = alphaChannelMenu->addAction(tr("&Pressure")); + alphaChannelPressureAction->setData(TabletCanvas::PressureValuator); alphaChannelPressureAction->setCheckable(true); - alphaChannelTangentialPressureAction = new QAction(tr("T&angential Pressure"), this); + QAction *alphaChannelTangentialPressureAction = alphaChannelMenu->addAction(tr("T&angential Pressure")); + alphaChannelTangentialPressureAction->setData(TabletCanvas::TangentialPressureValuator); alphaChannelTangentialPressureAction->setCheckable(true); alphaChannelTangentialPressureAction->setChecked(true); - alphaChannelTiltAction = new QAction(tr("&Tilt"), this); + QAction *alphaChannelTiltAction = alphaChannelMenu->addAction(tr("&Tilt")); + alphaChannelTiltAction->setData(TabletCanvas::TiltValuator); alphaChannelTiltAction->setCheckable(true); - noAlphaChannelAction = new QAction(tr("No Alpha Channel"), this); + QAction *noAlphaChannelAction = alphaChannelMenu->addAction(tr("No Alpha Channel")); + noAlphaChannelAction->setData(TabletCanvas::NoValuator); noAlphaChannelAction->setCheckable(true); - alphaChannelGroup = new QActionGroup(this); + QActionGroup *alphaChannelGroup = new QActionGroup(this); alphaChannelGroup->addAction(alphaChannelPressureAction); alphaChannelGroup->addAction(alphaChannelTangentialPressureAction); alphaChannelGroup->addAction(alphaChannelTiltAction); alphaChannelGroup->addAction(noAlphaChannelAction); - connect(alphaChannelGroup, SIGNAL(triggered(QAction*)), - this, SLOT(alphaActionTriggered(QAction*))); - + connect(alphaChannelGroup, &QActionGroup::triggered, + this, &MainWindow::setAlphaValuator); //! [9] - colorSaturationVTiltAction = new QAction(tr("&Vertical Tilt"), this); + + QMenu *colorSaturationMenu = tabletMenu->addMenu(tr("&Color Saturation")); + + QAction *colorSaturationVTiltAction = colorSaturationMenu->addAction(tr("&Vertical Tilt")); + colorSaturationVTiltAction->setData(TabletCanvas::VTiltValuator); colorSaturationVTiltAction->setCheckable(true); - colorSaturationHTiltAction = new QAction(tr("&Horizontal Tilt"), this); + QAction *colorSaturationHTiltAction = colorSaturationMenu->addAction(tr("&Horizontal Tilt")); + colorSaturationHTiltAction->setData(TabletCanvas::HTiltValuator); colorSaturationHTiltAction->setCheckable(true); - colorSaturationPressureAction = new QAction(tr("&Pressure"), this); + QAction *colorSaturationPressureAction = colorSaturationMenu->addAction(tr("&Pressure")); + colorSaturationPressureAction->setData(TabletCanvas::PressureValuator); colorSaturationPressureAction->setCheckable(true); - noColorSaturationAction = new QAction(tr("&No Color Saturation"), this); + QAction *noColorSaturationAction = colorSaturationMenu->addAction(tr("&No Color Saturation")); + noColorSaturationAction->setData(TabletCanvas::NoValuator); noColorSaturationAction->setCheckable(true); noColorSaturationAction->setChecked(true); - colorSaturationGroup = new QActionGroup(this); + QActionGroup *colorSaturationGroup = new QActionGroup(this); colorSaturationGroup->addAction(colorSaturationVTiltAction); colorSaturationGroup->addAction(colorSaturationHTiltAction); colorSaturationGroup->addAction(colorSaturationPressureAction); colorSaturationGroup->addAction(noColorSaturationAction); - connect(colorSaturationGroup, SIGNAL(triggered(QAction*)), - this, SLOT(saturationActionTriggered(QAction*))); - - lineWidthPressureAction = new QAction(tr("&Pressure"), this); - lineWidthPressureAction->setCheckable(true); - lineWidthPressureAction->setChecked(true); - - lineWidthTiltAction = new QAction(tr("&Tilt"), this); - lineWidthTiltAction->setCheckable(true); - - lineWidthFixedAction = new QAction(tr("&Fixed"), this); - lineWidthFixedAction->setCheckable(true); - - lineWidthGroup = new QActionGroup(this); - lineWidthGroup->addAction(lineWidthPressureAction); - lineWidthGroup->addAction(lineWidthTiltAction); - lineWidthGroup->addAction(lineWidthFixedAction); - connect(lineWidthGroup, SIGNAL(triggered(QAction*)), - this, SLOT(lineWidthActionTriggered(QAction*))); - - exitAction = new QAction(tr("E&xit"), this); - exitAction->setShortcuts(QKeySequence::Quit); - connect(exitAction, SIGNAL(triggered()), - this, SLOT(close())); - - loadAction = new QAction(tr("&Open..."), this); - loadAction->setShortcuts(QKeySequence::Open); - connect(loadAction, SIGNAL(triggered()), - this, SLOT(loadAct())); - - saveAction = new QAction(tr("&Save As..."), this); - saveAction->setShortcuts(QKeySequence::SaveAs); - connect(saveAction, SIGNAL(triggered()), - this, SLOT(saveAct())); - - aboutAction = new QAction(tr("A&bout"), this); - aboutAction->setShortcut(tr("Ctrl+B")); - connect(aboutAction, SIGNAL(triggered()), - this, SLOT(aboutAct())); - - aboutQtAction = new QAction(tr("About &Qt"), this); - aboutQtAction->setShortcut(tr("Ctrl+Q")); - connect(aboutQtAction, SIGNAL(triggered()), - qApp, SLOT(aboutQt())); -//! [10] -} -//! [10] - -//! [11] -void MainWindow::createMenus() -{ - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(loadAction); - fileMenu->addAction(saveAction); - fileMenu->addSeparator(); - fileMenu->addAction(exitAction); - - brushMenu = menuBar()->addMenu(tr("&Brush")); - brushMenu->addAction(brushColorAction); - - tabletMenu = menuBar()->addMenu(tr("&Tablet")); - - lineWidthMenu = tabletMenu->addMenu(tr("&Line Width")); - lineWidthMenu->addAction(lineWidthPressureAction); - lineWidthMenu->addAction(lineWidthTiltAction); - lineWidthMenu->addAction(lineWidthFixedAction); - - alphaChannelMenu = tabletMenu->addMenu(tr("&Alpha Channel")); - alphaChannelMenu->addAction(alphaChannelPressureAction); - alphaChannelMenu->addAction(alphaChannelTangentialPressureAction); - alphaChannelMenu->addAction(alphaChannelTiltAction); - alphaChannelMenu->addAction(noAlphaChannelAction); - - colorSaturationMenu = tabletMenu->addMenu(tr("&Color Saturation")); - colorSaturationMenu->addAction(colorSaturationVTiltAction); - colorSaturationMenu->addAction(colorSaturationHTiltAction); - colorSaturationMenu->addAction(noColorSaturationAction); + connect(colorSaturationGroup, &QActionGroup::triggered, + this, &MainWindow::setSaturationValuator); - helpMenu = menuBar()->addMenu("&Help"); - helpMenu->addAction(aboutAction); - helpMenu->addAction(aboutQtAction); + QMenu *helpMenu = menuBar()->addMenu("&Help"); + helpMenu->addAction(tr("A&bout"), this, &MainWindow::about); + helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); } -//! [11] diff --git a/examples/widgets/widgets/tablet/mainwindow.h b/examples/widgets/widgets/tablet/mainwindow.h index c6ac2e6026..23d587baac 100644 --- a/examples/widgets/widgets/tablet/mainwindow.h +++ b/examples/widgets/widgets/tablet/mainwindow.h @@ -44,10 +44,7 @@ #include <QMainWindow> QT_BEGIN_NAMESPACE -class QAction; -class QActionGroup; -class QMenu; -class QStatusBar; +class QColorDialog; QT_END_NAMESPACE class TabletCanvas; @@ -60,54 +57,19 @@ public: MainWindow(TabletCanvas *canvas); private slots: - void brushColorAct(); - void alphaActionTriggered(QAction *action); - void lineWidthActionTriggered(QAction *action); - void saturationActionTriggered(QAction *action); - void saveAct(); - void loadAct(); - void aboutAct(); + void setBrushColor(); + void setAlphaValuator(QAction *action); + void setLineWidthValuator(QAction *action); + void setSaturationValuator(QAction *action); + void save(); + void load(); + void about(); private: - void createActions(); void createMenus(); - TabletCanvas *myCanvas; - - QAction *brushColorAction; - QActionGroup *brushActionGroup; - - QActionGroup *alphaChannelGroup; - QAction *alphaChannelPressureAction; - QAction *alphaChannelTangentialPressureAction; - QAction *alphaChannelTiltAction; - QAction *noAlphaChannelAction; - - QActionGroup *colorSaturationGroup; - QAction *colorSaturationVTiltAction; - QAction *colorSaturationHTiltAction; - QAction *colorSaturationPressureAction; - QAction *noColorSaturationAction; - - QActionGroup *lineWidthGroup; - QAction *lineWidthPressureAction; - QAction *lineWidthTiltAction; - QAction *lineWidthFixedAction; - - QAction *exitAction; - QAction *saveAction; - QAction *loadAction; - - QAction *aboutAction; - QAction *aboutQtAction; - - QMenu *fileMenu; - QMenu *brushMenu; - QMenu *tabletMenu; - QMenu *helpMenu; - QMenu *colorSaturationMenu; - QMenu *lineWidthMenu; - QMenu *alphaChannelMenu; + TabletCanvas *m_canvas; + QColorDialog *m_colorDialog; }; //! [0] diff --git a/examples/widgets/widgets/tablet/tabletapplication.cpp b/examples/widgets/widgets/tablet/tabletapplication.cpp index 3e1356ee9c..7c0912c8f9 100644 --- a/examples/widgets/widgets/tablet/tabletapplication.cpp +++ b/examples/widgets/widgets/tablet/tabletapplication.cpp @@ -47,7 +47,7 @@ bool TabletApplication::event(QEvent *event) { if (event->type() == QEvent::TabletEnterProximity || event->type() == QEvent::TabletLeaveProximity) { - myCanvas->setTabletDevice(static_cast<QTabletEvent *>(event)); + m_canvas->setTabletDevice(static_cast<QTabletEvent *>(event)); return true; } return QApplication::event(event); diff --git a/examples/widgets/widgets/tablet/tabletapplication.h b/examples/widgets/widgets/tablet/tabletapplication.h index d755ff9891..be238b9a0d 100644 --- a/examples/widgets/widgets/tablet/tabletapplication.h +++ b/examples/widgets/widgets/tablet/tabletapplication.h @@ -56,10 +56,10 @@ public: bool event(QEvent *event) Q_DECL_OVERRIDE; void setCanvas(TabletCanvas *canvas) - { myCanvas = canvas; } + { m_canvas = canvas; } private: - TabletCanvas *myCanvas; + TabletCanvas *m_canvas; }; //! [0] diff --git a/examples/widgets/widgets/tablet/tabletcanvas.cpp b/examples/widgets/widgets/tablet/tabletcanvas.cpp index 8ff3d41e0e..0d2fc2a958 100644 --- a/examples/widgets/widgets/tablet/tabletcanvas.cpp +++ b/examples/widgets/widgets/tablet/tabletcanvas.cpp @@ -45,17 +45,18 @@ //! [0] TabletCanvas::TabletCanvas() + : QWidget(Q_NULLPTR) + , m_alphaChannelValuator(TangentialPressureValuator) + , m_colorSaturationValuator(NoValuator) + , m_lineWidthValuator(PressureValuator) + , m_color(Qt::red) + , m_brush(m_color) + , m_pen(m_brush, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin) + , m_deviceDown(false) { resize(500, 500); - myColor = Qt::red; - myBrush = QBrush(myColor); - myPen = QPen(myBrush, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); initPixmap(); setAutoFillBackground(true); - deviceDown = false; - alphaChannelType = AlphaTangentialPressure; - colorSaturationType = NoSaturation; - lineWidthType = LineWidthPressure; } void TabletCanvas::initPixmap() @@ -63,24 +64,24 @@ void TabletCanvas::initPixmap() QPixmap newPixmap = QPixmap(width(), height()); newPixmap.fill(Qt::white); QPainter painter(&newPixmap); - if (!pixmap.isNull()) - painter.drawPixmap(0, 0, pixmap); + if (!m_pixmap.isNull()) + painter.drawPixmap(0, 0, m_pixmap); painter.end(); - pixmap = newPixmap; + m_pixmap = newPixmap; } //! [0] //! [1] bool TabletCanvas::saveImage(const QString &file) { - return pixmap.save(file); + return m_pixmap.save(file); } //! [1] //! [2] bool TabletCanvas::loadImage(const QString &file) { - bool success = pixmap.load(file); + bool success = m_pixmap.load(file); if (success) { update(); @@ -96,8 +97,8 @@ void TabletCanvas::tabletEvent(QTabletEvent *event) switch (event->type()) { case QEvent::TabletPress: - if (!deviceDown) { - deviceDown = true; + if (!m_deviceDown) { + m_deviceDown = true; lastPoint.pos = event->posF(); lastPoint.rotation = event->rotation(); } @@ -105,17 +106,17 @@ void TabletCanvas::tabletEvent(QTabletEvent *event) case QEvent::TabletMove: if (event->device() == QTabletEvent::RotationStylus) updateCursor(event); - if (deviceDown) { + if (m_deviceDown) { updateBrush(event); - QPainter painter(&pixmap); + QPainter painter(&m_pixmap); paintPixmap(painter, event); lastPoint.pos = event->posF(); lastPoint.rotation = event->rotation(); } break; case QEvent::TabletRelease: - if (deviceDown && event->buttons() == Qt::NoButton) - deviceDown = false; + if (m_deviceDown && event->buttons() == Qt::NoButton) + m_deviceDown = false; break; default: break; @@ -128,7 +129,7 @@ void TabletCanvas::tabletEvent(QTabletEvent *event) void TabletCanvas::paintEvent(QPaintEvent *) { QPainter painter(this); - painter.drawPixmap(0, 0, pixmap); + painter.drawPixmap(0, 0, m_pixmap); } //! [4] @@ -142,10 +143,10 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event) case QTabletEvent::Airbrush: { painter.setPen(Qt::NoPen); - QRadialGradient grad(lastPoint.pos, myPen.widthF() * 10.0); - QColor color = myBrush.color(); + QRadialGradient grad(lastPoint.pos, m_pen.widthF() * 10.0); + QColor color = m_brush.color(); color.setAlphaF(color.alphaF() * 0.25); - grad.setColorAt(0, myBrush.color()); + grad.setColorAt(0, m_brush.color()); grad.setColorAt(0.5, Qt::transparent); painter.setBrush(grad); qreal radius = grad.radius(); @@ -154,11 +155,11 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event) break; case QTabletEvent::RotationStylus: { - myBrush.setStyle(Qt::SolidPattern); + m_brush.setStyle(Qt::SolidPattern); painter.setPen(Qt::NoPen); - painter.setBrush(myBrush); + painter.setBrush(m_brush); QPolygonF poly; - qreal halfWidth = myPen.widthF(); + qreal halfWidth = m_pen.widthF(); QPointF brushAdjust(qSin(qDegreesToRadians(lastPoint.rotation)) * halfWidth, qCos(qDegreesToRadians(lastPoint.rotation)) * halfWidth); poly << lastPoint.pos + brushAdjust; @@ -195,7 +196,7 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event) } // FALL-THROUGH case QTabletEvent::Stylus: - painter.setPen(myPen); + painter.setPen(m_pen); painter.drawLine(lastPoint.pos, event->posF()); break; } @@ -206,68 +207,69 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event) void TabletCanvas::updateBrush(const QTabletEvent *event) { int hue, saturation, value, alpha; - myColor.getHsv(&hue, &saturation, &value, &alpha); + m_color.getHsv(&hue, &saturation, &value, &alpha); int vValue = int(((event->yTilt() + 60.0) / 120.0) * 255); int hValue = int(((event->xTilt() + 60.0) / 120.0) * 255); //! [7] //! [8] - switch (alphaChannelType) { - case AlphaPressure: - myColor.setAlphaF(event->pressure()); + switch (m_alphaChannelValuator) { + case PressureValuator: + m_color.setAlphaF(event->pressure()); break; - case AlphaTangentialPressure: + case TangentialPressureValuator: if (event->device() == QTabletEvent::Airbrush) - myColor.setAlphaF(qMax(0.01, (event->tangentialPressure() + 1.0) / 2.0)); + m_color.setAlphaF(qMax(0.01, (event->tangentialPressure() + 1.0) / 2.0)); else - myColor.setAlpha(255); + m_color.setAlpha(255); break; - case AlphaTilt: - myColor.setAlpha(maximum(abs(vValue - 127), abs(hValue - 127))); + case TiltValuator: + m_color.setAlpha(maximum(abs(vValue - 127), abs(hValue - 127))); break; default: - myColor.setAlpha(255); + m_color.setAlpha(255); } //! [8] //! [9] - switch (colorSaturationType) { - case SaturationVTilt: - myColor.setHsv(hue, vValue, value, alpha); + switch (m_colorSaturationValuator) { + case VTiltValuator: + m_color.setHsv(hue, vValue, value, alpha); break; - case SaturationHTilt: - myColor.setHsv(hue, hValue, value, alpha); + case HTiltValuator: + m_color.setHsv(hue, hValue, value, alpha); break; - case SaturationPressure: - myColor.setHsv(hue, int(event->pressure() * 255.0), value, alpha); + case PressureValuator: + m_color.setHsv(hue, int(event->pressure() * 255.0), value, alpha); break; default: ; } //! [9] //! [10] - switch (lineWidthType) { - case LineWidthPressure: - myPen.setWidthF(event->pressure() * 10 + 1); + switch (m_lineWidthValuator) { + case PressureValuator: + m_pen.setWidthF(event->pressure() * 10 + 1); break; - case LineWidthTilt: - myPen.setWidthF(maximum(abs(vValue - 127), abs(hValue - 127)) / 12); + case TiltValuator: + m_pen.setWidthF(maximum(abs(vValue - 127), abs(hValue - 127)) / 12); break; default: - myPen.setWidthF(1); + m_pen.setWidthF(1); } //! [10] //! [11] if (event->pointerType() == QTabletEvent::Eraser) { - myBrush.setColor(Qt::white); - myPen.setColor(Qt::white); - myPen.setWidthF(event->pressure() * 10 + 1); + m_brush.setColor(Qt::white); + m_pen.setColor(Qt::white); + m_pen.setWidthF(event->pressure() * 10 + 1); } else { - myBrush.setColor(myColor); - myPen.setColor(myColor); + m_brush.setColor(m_color); + m_pen.setColor(m_color); } } //! [11] +//! [12] void TabletCanvas::updateCursor(const QTabletEvent *event) { QCursor cursor; @@ -285,7 +287,7 @@ void TabletCanvas::updateCursor(const QTabletEvent *event) case QTabletEvent::RotationStylus: { QImage origImg(QLatin1String(":/images/cursor-felt-marker.png")); QImage img(32, 32, QImage::Format_ARGB32); - QColor solid = myColor; + QColor solid = m_color; solid.setAlpha(255); img.fill(solid); QPainter painter(&img); @@ -307,6 +309,7 @@ void TabletCanvas::updateCursor(const QTabletEvent *event) } setCursor(cursor); } +//! [12] void TabletCanvas::resizeEvent(QResizeEvent *) { diff --git a/examples/widgets/widgets/tablet/tabletcanvas.h b/examples/widgets/widgets/tablet/tabletcanvas.h index a7335dbaf0..6044884d32 100644 --- a/examples/widgets/widgets/tablet/tabletcanvas.h +++ b/examples/widgets/widgets/tablet/tabletcanvas.h @@ -61,27 +61,26 @@ class TabletCanvas : public QWidget Q_OBJECT public: - enum AlphaChannelType { AlphaPressure, AlphaTangentialPressure, AlphaTilt, NoAlpha }; - enum ColorSaturationType { SaturationVTilt, SaturationHTilt, - SaturationPressure, NoSaturation }; - enum LineWidthType { LineWidthPressure, LineWidthTilt, NoLineWidth }; + enum Valuator { PressureValuator, TangentialPressureValuator, + TiltValuator, VTiltValuator, HTiltValuator, NoValuator }; + Q_ENUM(Valuator) TabletCanvas(); bool saveImage(const QString &file); bool loadImage(const QString &file); - void setAlphaChannelType(AlphaChannelType type) - { alphaChannelType = type; } - void setColorSaturationType(ColorSaturationType type) - { colorSaturationType = type; } - void setLineWidthType(LineWidthType type) - { lineWidthType = type; } - void setColor(const QColor &color) - { myColor = color; } + void setAlphaChannelValuator(Valuator type) + { m_alphaChannelValuator = type; } + void setColorSaturationValuator(Valuator type) + { m_colorSaturationValuator = type; } + void setLineWidthType(Valuator type) + { m_lineWidthValuator = type; } + void setColor(const QColor &c) + { if (c.isValid()) m_color = c; } QColor color() const - { return myColor; } + { return m_color; } void setTabletDevice(QTabletEvent *event) - { myTabletDevice = event->device(); updateCursor(event); } + { updateCursor(event); } int maximum(int a, int b) { return a > b ? a : b; } @@ -97,17 +96,14 @@ private: void updateBrush(const QTabletEvent *event); void updateCursor(const QTabletEvent *event); - AlphaChannelType alphaChannelType; - ColorSaturationType colorSaturationType; - LineWidthType lineWidthType; - QTabletEvent::PointerType pointerType; - QTabletEvent::TabletDevice myTabletDevice; - QColor myColor; - - QPixmap pixmap; - QBrush myBrush; - QPen myPen; - bool deviceDown; + Valuator m_alphaChannelValuator; + Valuator m_colorSaturationValuator; + Valuator m_lineWidthValuator; + QColor m_color; + QPixmap m_pixmap; + QBrush m_brush; + QPen m_pen; + bool m_deviceDown; struct Point { QPointF pos; diff --git a/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in index d091ea3b82..c25d7b77af 100644 --- a/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +++ b/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in @@ -4,7 +4,8 @@ xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\" xmlns:mp=\"http://schemas.microsoft.com/appx/2014/phone/manifest\" xmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\" - IgnorableNamespaces=\"uap mp\"> + xmlns:mobile=\"http://schemas.microsoft.com/appx/manifest/mobile/windows10\" + IgnorableNamespaces=\"uap mp mobile\"> <Identity Name=\"$${WINRT_MANIFEST.identity}\" @@ -21,7 +22,7 @@ </Properties> <Dependencies> - <TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.10069.0\" MaxVersionTested=\"10.0.10069.0\" />$${WINRT_MANIFEST.dependencies} + <TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.10240.0\" MaxVersionTested=\"10.0.10586.0\" />$${WINRT_MANIFEST.dependencies} </Dependencies> <Resources> diff --git a/mkspecs/features/data/mac/objc_namespace.sh b/mkspecs/features/data/mac/objc_namespace.sh new file mode 100755 index 0000000000..0c7faf18bf --- /dev/null +++ b/mkspecs/features/data/mac/objc_namespace.sh @@ -0,0 +1,216 @@ +#!/bin/bash + +############################################################################# +## +## Copyright (C) 2015 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is the build configuration utility of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL21$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see http://www.qt.io/terms-conditions. For further +## information use the contact form at http://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 2.1 or version 3 as published by the Free +## Software Foundation and appearing in the file LICENSE.LGPLv21 and +## LICENSE.LGPLv3 included in the packaging of this file. Please review the +## following information to ensure the GNU Lesser General Public License +## requirements will be met: https://www.gnu.org/licenses/lgpl.html and +## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +## +## As a special exception, The Qt Company gives you certain additional +## rights. These rights are described in The Qt Company LGPL Exception +## version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +## +## $QT_END_LICENSE$ +## +############################################################################# + +script_argument_prefix="-Wobjc_namespace,--" + +required_arguments="target suffix original_ld" +optional_arguments="exclude_list exclude_regex slient" + +for argument in $required_arguments $optional_arguments; do + declare "$argument=" +done + +declare -i silent=0 +declare -a linker_arguments + +for i in "$@"; do + case $1 in + $script_argument_prefix*) + declare "${1#$script_argument_prefix}" + ;; + -o) + if [ -n "$2" ]; then + target="$2" + fi + linker_arguments+=("$1") + ;; + *) + linker_arguments+=("$1") + ;; + esac + shift +done + +get_entry() { + local map=$1 key=$2 + local i="${map}_map_${2}" + printf '%s' "${!i}" +} + +error() { + echo "$0: error: $*" >&2 + exit 1 +} + +for argument in $required_arguments; do + if [ -z "${!argument}" ]; then + error "missing argument --${argument}" + fi +done + +# Normalize suffix so we can use it as a bash variable +suffix=${suffix//[-. ]/_} + +link_binary() { + (PS4=; test $silent -ne 1 && set -x; $original_ld "${linker_arguments[@]}" "$@") 2>&1 || exit 1 +} + +sanitize_address() { + local address="$1" + address=${address#0x} # Remove hex prefix + address=${address: ${#address} < 8 ? 0 : -8} # Limit to 32-bit + echo "0x$address" +} + +read_binary() { + local address=$1 + local length=$2 + + dd if="$target" bs=1 iseek=$address count=$length 2>|/dev/null +} + +read_32bit_value() { + local address=$1 + read_binary $address 4 | xxd -p | dd conv=swab 2>/dev/null | rev +} + +inspect_binary() { + inspect_mode="$1" + + echo -n "🔎 Inspecting binary '$target', " + if [ ! -f "$target" ]; then + echo "target does not exist!" + exit 1 + fi + + read -a mach_header <<< "$(otool -h "$target" -v | tail -n 1)" + if [ "${mach_header[1]}" != "X86_64" ]; then + echo "binary is not 64-bit, only 64-bit binaries are supported!" + exit 1 + fi + + classnames_section="__objc_classname" + classnames=$(otool -v -s __TEXT $classnames_section "$target" | tail -n +3) + while read -a classname; do + address=$(sanitize_address ${classname[0]}) + name=${classname[1]} + + declare "address_to_classname_map_$address=$name" + declare "classname_to_address_map_$name=$address" + done <<< "$classnames" + + extra_classnames_file="$(mktemp -t ${classnames_section}_additions).S" + + if [ "$inspect_mode" == "inject_classnames" ]; then + echo "class names have not been namespaced, adding suffix '$suffix'..." + printf ".section __TEXT,$classnames_section,cstring_literals,no_dead_strip\n" > $extra_classnames_file + elif [ "$inspect_mode" == "patch_classes" ]; then + echo "found namespaced class names, updating class entries..." + fi + + classes=$(otool -o "$target" | grep class_ro_t) + while read -a class; do + address="$(sanitize_address ${class[1]})" + + class_flags="0x$(read_32bit_value $address)" + if [ -z "$class_flags" ]; then + echo " 💥 failed to read class flags for class at $address" + continue + fi + + is_metaclass=$(($class_flags & 0x1)) + + name_offset=$(($address + 24)) + classname_address="0x$(read_32bit_value $name_offset)" + if [ -z "$classname_address" ]; then + echo " 💥 failed to read class name address for class at $address" + continue + fi + + classname=$(get_entry address_to_classname $classname_address) + if [ -z "$classname" ]; then + echo " 💥 failed to resolve class name for address '$classname_address'" + continue + fi + + if [[ $exclude_list =~ $classname || $classname =~ $exclude_regex ]]; then + if [ $is_metaclass -eq 1 ]; then + class_type="meta class" + else + class_type="class" + fi + echo " 🚽 skipping excluded $class_type '$classname'" + continue + fi + + newclassname="${classname}_${suffix}" + + if [ "$inspect_mode" == "inject_classnames" ]; then + if [ $is_metaclass -eq 1 ]; then + continue + fi + + echo " 💉 injecting $classnames_section entry '$newclassname' for '$classname'" + printf ".asciz \"$newclassname\"\n" >> $extra_classnames_file + + elif [ "$inspect_mode" == "patch_classes" ]; then + newclassname_address=$(get_entry classname_to_address ${newclassname}) + if [ -z "$newclassname_address" ]; then + echo " 💥 failed to resolve class name address for class '$newclassname'" + continue + fi + + if [ $is_metaclass -eq 1 ]; then + class_type="meta" + else + class_type="class" + fi + + echo " 🔨 patching class_ro_t at $address ($class_type) from $classname_address ($classname) to $newclassname_address ($newclassname)" + echo ${newclassname_address: -8} | rev | dd conv=swab 2>/dev/null | xxd -p -r -seek $name_offset -l 4 - "$target" + fi + done <<< "$classes" +} + +echo "🔩 Linking binary using '$original_ld'..." +link_binary + +inspect_binary inject_classnames + +echo "🔩 Re-linking binary with extra __objc_classname section..." +link_binary $extra_classnames_file + +inspect_binary patch_classes + diff --git a/mkspecs/features/mac/unsupported/objc_namespace.prf b/mkspecs/features/mac/unsupported/objc_namespace.prf new file mode 100644 index 0000000000..94e0fbe0de --- /dev/null +++ b/mkspecs/features/mac/unsupported/objc_namespace.prf @@ -0,0 +1,50 @@ +# +# W A R N I N G +# ------------- +# +# This file is not part of the Qt API. It exists purely as an +# implementation detail. It may change from version to version +# without notice, or even be removed. +# +# We mean it. +# + +# The Objective-C runtime will complain when loading a binary that +# introduces as class name that already exists in the global namespace. +# This may happen when linking Qt statically into a plugin, and then +# loading more than two plugins into the same host, both using Qt. +# +# We work around this by doing a bit of post-processing on the final +# binary, adding new suffixed class name entries to the __objc_classname +# section of the __TEXT segment, and then patching the class_ro_t +# entries to point to the newly added class names. +# +# By linking the binary between these two steps we avoid having to +# manually remap all the offsets in the Mach-O binary due to the +# added class names, instead relying on the linker to do this +# for us by linking in an assembly file with the added names. + +objc_namespace_script = $$clean_path($$PWD/../../data/mac/objc_namespace.sh) + +isEmpty(QMAKE_OBJC_NAMESPACE_SUFFIX) { + QMAKE_OBJC_NAMESPACE_SUFFIX = $$TARGET + !isEmpty(QMAKE_TARGET_BUNDLE_PREFIX): \ + QMAKE_OBJC_NAMESPACE_SUFFIX = $${QMAKE_TARGET_BUNDLE_PREFIX}.$${QMAKE_OBJC_NAMESPACE_SUFFIX} +} + +QMAKE_LFLAGS += \ + -Wobjc_namespace,--target=$$shell_quote($$TARGET) \ + -Wobjc_namespace,--suffix=$$shell_quote($$QMAKE_OBJC_NAMESPACE_SUFFIX) \ + -Wobjc_namespace,--original_ld=$$shell_quote($$QMAKE_LINK) + +!isEmpty(QMAKE_OBJC_NAMESPACE_EXCLUDE): \ + QMAKE_LFLAGS += -Wobjc_namespace,--exclude_list=$$shell_quote($$QMAKE_OBJC_NAMESPACE_EXCLUDE) +!isEmpty(QMAKE_OBJC_NAMESPACE_EXCLUDE_REGEX) { + equals(MAKEFILE_GENERATOR, UNIX): \ + QMAKE_OBJC_NAMESPACE_EXCLUDE_REGEX ~= s/\\$/\$\$/ + QMAKE_LFLAGS += -Wobjc_namespace,--exclude_regex=$$shell_quote($$QMAKE_OBJC_NAMESPACE_EXCLUDE_REGEX) +} + +slient: QMAKE_LFLAGS += -Wobjc_namespace,--silent=1 + +QMAKE_LINK = $$objc_namespace_script diff --git a/src/3rdparty/freetype/freetype.pro b/src/3rdparty/freetype/freetype.pro index e9436febc6..04aa3b8e18 100644 --- a/src/3rdparty/freetype/freetype.pro +++ b/src/3rdparty/freetype/freetype.pro @@ -3,7 +3,8 @@ TARGET = qtfreetype CONFIG += \ static \ hide_symbols \ - exceptions_off rtti_off warn_off + exceptions_off rtti_off warn_off \ + installed load(qt_helper_lib) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 3729555d52..d9be4c7d9f 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -226,6 +226,16 @@ public class QtNative } } + private static void setViewVisibility(final View view, final boolean visible) + { + runAction(new Runnable() { + @Override + public void run() { + view.setVisibility(visible ? View.VISIBLE : View.GONE); + } + }); + } + public static boolean startApplication(String params, String environment, String mainLibrary, diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index ce838622bc..7d558cbf81 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -653,7 +653,7 @@ extern "C" void qt_core_boilerplate(); void qt_core_boilerplate() { printf("This is the QtCore library version " QT_BUILD_STR "\n" - "Copyright (C) 2015 The Qt Company Ltd.\n" + "Copyright (C) 2016 The Qt Company Ltd.\n" "Contact: http://www.qt.io/licensing/\n" "\n" "Installation prefix: %s\n" diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 218fb5b078..1ae0485840 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -107,8 +107,6 @@ win32 { !winrt { SOURCES += io/qsettings_win.cpp - HEADERS += io/qwindowspipewriter_p.h - SOURCES += io/qwindowspipewriter.cpp SOURCES += io/qstandardpaths_win.cpp wince* { @@ -117,11 +115,13 @@ win32 { } else { HEADERS += \ io/qwinoverlappedionotifier_p.h \ - io/qwindowspipereader_p.h + io/qwindowspipereader_p.h \ + io/qwindowspipewriter_p.h SOURCES += \ io/qprocess_win.cpp \ io/qwinoverlappedionotifier.cpp \ io/qwindowspipereader.cpp \ + io/qwindowspipewriter.cpp \ io/qstorageinfo_win.cpp LIBS += -lmpr } diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 6ddabc2351..ccacb6ed20 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -753,7 +753,7 @@ QFile::copy(const QString &newName) qWarning("QFile::copy: Empty or null file name"); return false; } - if (QFile(newName).exists()) { + if (QFile::exists(newName)) { // ### Race condition. If a file is moved in after this, it /will/ be // overwritten. On Unix, the proper solution is to use hardlinks: // return ::link(old, new) && ::remove(old); See also rename(). diff --git a/src/corelib/io/qprocess_wince.cpp b/src/corelib/io/qprocess_wince.cpp index aef043fcaa..c859a740d5 100644 --- a/src/corelib/io/qprocess_wince.cpp +++ b/src/corelib/io/qprocess_wince.cpp @@ -39,7 +39,6 @@ #include "qprocess.h" #include "qprocess_p.h" -#include "qwindowspipewriter_p.h" #include <qdir.h> #include <qfileinfo.h> @@ -162,7 +161,7 @@ void QProcessPrivate::startProcess() } // give the process a chance to start ... - Sleep(SLEEPMIN * 2); + Sleep(20); _q_startupNotification(); } diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp index 3961d56b63..9e3cb9ab4d 100644 --- a/src/corelib/io/qstandardpaths_win.cpp +++ b/src/corelib/io/qstandardpaths_win.cpp @@ -47,9 +47,7 @@ #include <qcoreapplication.h> #endif -#if !defined(Q_OS_WINCE) const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } }; -#endif #include <qt_windows.h> #include <shlobj.h> @@ -70,113 +68,152 @@ const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x6 QT_BEGIN_NAMESPACE -#if !defined(Q_OS_WINCE) -typedef HRESULT (WINAPI *GetKnownFolderPath)(const GUID&, DWORD, HANDLE, LPWSTR*); -#endif - static QString convertCharArray(const wchar_t *path) { return QDir::fromNativeSeparators(QString::fromWCharArray(path)); } -static inline int clsidForAppDataLocation(QStandardPaths::StandardLocation type) +static inline bool isGenericConfigLocation(QStandardPaths::StandardLocation type) { -#ifndef Q_OS_WINCE - return type == QStandardPaths::AppDataLocation ? - CSIDL_APPDATA : // "Roaming" path - CSIDL_LOCAL_APPDATA; // Local path -#else - Q_UNUSED(type) - return CSIDL_APPDATA; -#endif + return type == QStandardPaths::GenericConfigLocation || type == QStandardPaths::GenericDataLocation; } -QString QStandardPaths::writableLocation(StandardLocation type) +static inline bool isConfigLocation(QStandardPaths::StandardLocation type) { - QString result; + return type == QStandardPaths::ConfigLocation || type == QStandardPaths::AppConfigLocation + || type == QStandardPaths::AppDataLocation || type == QStandardPaths::AppLocalDataLocation + || isGenericConfigLocation(type); +} -#if !defined(Q_OS_WINCE) - static GetKnownFolderPath SHGetKnownFolderPath = (GetKnownFolderPath)QSystemLibrary::resolve(QLatin1String("shell32"), "SHGetKnownFolderPath"); +static void appendOrganizationAndApp(QString &path) // Courtesy qstandardpaths_unix.cpp +{ +#ifndef QT_BOOTSTRAPPED + const QString &org = QCoreApplication::organizationName(); + if (!org.isEmpty()) + path += QLatin1Char('/') + org; + const QString &appName = QCoreApplication::applicationName(); + if (!appName.isEmpty()) + path += QLatin1Char('/') + appName; +#else // !QT_BOOTSTRAPPED + Q_UNUSED(path) #endif +} - wchar_t path[MAX_PATH]; - - switch (type) { - case ConfigLocation: // same as AppLocalDataLocation, on Windows - case GenericConfigLocation: // same as GenericDataLocation on Windows - case AppConfigLocation: - case AppDataLocation: - case AppLocalDataLocation: - case GenericDataLocation: - if (SHGetSpecialFolderPath(0, path, clsidForAppDataLocation(type), FALSE)) - result = convertCharArray(path); - if (isTestModeEnabled()) - result += QLatin1String("/qttest"); +static inline QString displayName(QStandardPaths::StandardLocation type) +{ #ifndef QT_BOOTSTRAPPED - if (type != GenericDataLocation && type != GenericConfigLocation) { - if (!QCoreApplication::organizationName().isEmpty()) - result += QLatin1Char('/') + QCoreApplication::organizationName(); - if (!QCoreApplication::applicationName().isEmpty()) - result += QLatin1Char('/') + QCoreApplication::applicationName(); - } + return QStandardPaths::displayName(type); +#else + return QString::number(type); #endif - break; +} - case DesktopLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_DESKTOPDIRECTORY, FALSE)) - result = convertCharArray(path); - break; +static inline void appendTestMode(QString &path) +{ + if (QStandardPaths::isTestModeEnabled()) + path += QLatin1String("/qttest"); +} - case DownloadLocation: -#if !defined(Q_OS_WINCE) - if (SHGetKnownFolderPath) { - LPWSTR path; - if (SHGetKnownFolderPath(qCLSID_FOLDERID_Downloads, 0, 0, &path) == S_OK) { - result = convertCharArray(path); - CoTaskMemFree(path); - } - break; +// Map QStandardPaths::StandardLocation to CLSID of SHGetSpecialFolderPath() +static int writableSpecialFolderClsid(QStandardPaths::StandardLocation type) +{ + static const int clsids[] = { + CSIDL_DESKTOPDIRECTORY, // DesktopLocation + CSIDL_PERSONAL, // DocumentsLocation + CSIDL_FONTS, // FontsLocation + CSIDL_PROGRAMS, // ApplicationsLocation + CSIDL_MYMUSIC, // MusicLocation + CSIDL_MYVIDEO, // MoviesLocation + CSIDL_MYPICTURES, // PicturesLocation + -1, -1, // TempLocation/HomeLocation + CSIDL_LOCAL_APPDATA, // AppLocalDataLocation ("Local" path), AppLocalDataLocation = DataLocation + -1, // CacheLocation + CSIDL_LOCAL_APPDATA, // GenericDataLocation ("Local" path) + -1, // RuntimeLocation + CSIDL_LOCAL_APPDATA, // ConfigLocation ("Local" path) + -1, -1, // DownloadLocation/GenericCacheLocation + CSIDL_LOCAL_APPDATA, // GenericConfigLocation ("Local" path) + CSIDL_APPDATA, // AppDataLocation ("Roaming" path) + CSIDL_LOCAL_APPDATA, // AppConfigLocation ("Local" path) + }; + + Q_STATIC_ASSERT(sizeof(clsids) / sizeof(clsids[0]) == size_t(QStandardPaths::AppConfigLocation + 1)); + return size_t(type) < sizeof(clsids) / sizeof(clsids[0]) ? clsids[type] : -1; +}; + +// Convenience for SHGetSpecialFolderPath(). +static QString sHGetSpecialFolderPath(int clsid, QStandardPaths::StandardLocation type, bool warn = false) +{ + QString result; + wchar_t path[MAX_PATH]; + if (Q_LIKELY(clsid >= 0 && SHGetSpecialFolderPath(0, path, clsid, FALSE))) { + result = convertCharArray(path); + } else { + if (warn) { + qErrnoWarning("SHGetSpecialFolderPath() failed for standard location \"%s\", clsid=0x%x.", + qPrintable(displayName(type)), clsid); } -#endif - // fall through - case DocumentsLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_PERSONAL, FALSE)) - result = convertCharArray(path); - break; - - case FontsLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_FONTS, FALSE)) - result = convertCharArray(path); - break; - - case ApplicationsLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_PROGRAMS, FALSE)) - result = convertCharArray(path); - break; - - case MusicLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_MYMUSIC, FALSE)) - result = convertCharArray(path); - break; + } + return result; +} - case MoviesLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_MYVIDEO, FALSE)) - result = convertCharArray(path); - break; +// Convenience for SHGetKnownFolderPath(). +static QString sHGetKnownFolderPath(const GUID &clsid, QStandardPaths::StandardLocation type, bool warn = false) +{ + QString result; +#ifndef Q_OS_WINCE + typedef HRESULT (WINAPI *GetKnownFolderPath)(const GUID&, DWORD, HANDLE, LPWSTR*); + + static const GetKnownFolderPath sHGetKnownFolderPath = // Vista onwards. + reinterpret_cast<GetKnownFolderPath>(QSystemLibrary::resolve(QLatin1String("shell32"), "SHGetKnownFolderPath")); + + LPWSTR path; + if (Q_LIKELY(sHGetKnownFolderPath && SUCCEEDED(sHGetKnownFolderPath(clsid, 0, 0, &path)))) { + result = convertCharArray(path); + CoTaskMemFree(path); + } else { + if (warn) { + qErrnoWarning("SHGetKnownFolderPath() failed for standard location \"%s\".", + qPrintable(displayName(type))); + } + } +#else // !Q_OS_WINCE + Q_UNUSED(clsid) + Q_UNUSED(type) + Q_UNUSED(warn) +#endif + return result; +} - case PicturesLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_MYPICTURES, FALSE)) - result = convertCharArray(path); +QString QStandardPaths::writableLocation(StandardLocation type) +{ + QString result; + switch (type) { + case DownloadLocation: + result = sHGetKnownFolderPath(qCLSID_FOLDERID_Downloads, type); + if (result.isEmpty()) + result = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); break; case CacheLocation: // Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache // location for everyone. Most applications seem to be using a // cache directory located in their AppData directory - return writableLocation(AppLocalDataLocation) + QLatin1String("/cache"); + result = sHGetSpecialFolderPath(writableSpecialFolderClsid(AppLocalDataLocation), type, /* warn */ true); + if (!result.isEmpty()) { + appendTestMode(result); + appendOrganizationAndApp(result); + result += QLatin1String("/cache"); + } + break; case GenericCacheLocation: - return writableLocation(GenericDataLocation) + QLatin1String("/cache"); + result = sHGetSpecialFolderPath(writableSpecialFolderClsid(GenericDataLocation), type, /* warn */ true); + if (!result.isEmpty()) { + appendTestMode(result); + result += QLatin1String("/cache"); + } + break; case RuntimeLocation: case HomeLocation: @@ -186,6 +223,15 @@ QString QStandardPaths::writableLocation(StandardLocation type) case TempLocation: result = QDir::tempPath(); break; + + default: + result = sHGetSpecialFolderPath(writableSpecialFolderClsid(type), type, /* warn */ isConfigLocation(type)); + if (!result.isEmpty() && isConfigLocation(type)) { + appendTestMode(result); + if (!isGenericConfigLocation(type)) + appendOrganizationAndApp(result); + } + break; } return result; } @@ -193,44 +239,26 @@ QString QStandardPaths::writableLocation(StandardLocation type) QStringList QStandardPaths::standardLocations(StandardLocation type) { QStringList dirs; + const QString localDir = writableLocation(type); + if (!localDir.isEmpty()) + dirs.append(localDir); // type-specific handling goes here - #ifndef Q_OS_WINCE - { - wchar_t path[MAX_PATH]; - switch (type) { - case ConfigLocation: // same as AppLocalDataLocation, on Windows (oversight, but too late to fix it) - case GenericConfigLocation: // same as GenericDataLocation, on Windows - case AppConfigLocation: // same as AppLocalDataLocation, that one on purpose - case AppDataLocation: - case AppLocalDataLocation: - case GenericDataLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_COMMON_APPDATA, FALSE)) { - QString result = convertCharArray(path); - if (type != GenericDataLocation && type != GenericConfigLocation) { -#ifndef QT_BOOTSTRAPPED - if (!QCoreApplication::organizationName().isEmpty()) - result += QLatin1Char('/') + QCoreApplication::organizationName(); - if (!QCoreApplication::applicationName().isEmpty()) - result += QLatin1Char('/') + QCoreApplication::applicationName(); -#endif - } - dirs.append(result); -#ifndef QT_BOOTSTRAPPED - dirs.append(QCoreApplication::applicationDirPath()); - dirs.append(QCoreApplication::applicationDirPath() + QLatin1String("/data")); -#endif - } - break; - default: - break; + if (isConfigLocation(type)) { + QString programData = sHGetSpecialFolderPath(CSIDL_COMMON_APPDATA, type); + if (!programData.isEmpty()) { + if (!isGenericConfigLocation(type)) + appendOrganizationAndApp(programData); + dirs.append(programData); } - } -#endif +# ifndef QT_BOOTSTRAPPED + dirs.append(QCoreApplication::applicationDirPath()); + dirs.append(QCoreApplication::applicationDirPath() + QLatin1String("/data")); +# endif // !QT_BOOTSTRAPPED + } // isConfigLocation() +#endif // !Q_OS_WINCE - const QString localDir = writableLocation(type); - dirs.prepend(localDir); return dirs; } diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp index 3b9a2113fd..a3ce13a99f 100644 --- a/src/corelib/json/qjsonobject.cpp +++ b/src/corelib/json/qjsonobject.cpp @@ -685,8 +685,11 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const /*! \typedef QJsonObject::iterator::iterator_category - A synonym for \e {std::bidirectional_iterator_tag} indicating - this iterator is a bidirectional iterator. + A synonym for \e {std::random_access_iterator_tag} indicating + this iterator is a random-access iterator. + + \note In Qt versions before 5.6, this was set by mistake to + \e {std::bidirectional_iterator_tag}. */ /*! \typedef QJsonObject::iterator::reference @@ -892,8 +895,11 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const /*! \typedef QJsonObject::const_iterator::iterator_category - A synonym for \e {std::bidirectional_iterator_tag} indicating - this iterator is a bidirectional iterator. + A synonym for \e {std::random_access_iterator_tag} indicating + this iterator is a random-access iterator. + + \note In Qt versions before 5.6, this was set by mistake to + \e {std::bidirectional_iterator_tag}. */ /*! \typedef QJsonObject::const_iterator::reference diff --git a/src/corelib/json/qjsonobject.h b/src/corelib/json/qjsonobject.h index bc4c8f46e3..5617eee04f 100644 --- a/src/corelib/json/qjsonobject.h +++ b/src/corelib/json/qjsonobject.h @@ -106,7 +106,7 @@ public: int i; public: - typedef std::bidirectional_iterator_tag iterator_category; + typedef std::random_access_iterator_tag iterator_category; typedef int difference_type; typedef QJsonValue value_type; typedef QJsonValueRef reference; @@ -149,7 +149,7 @@ public: int i; public: - typedef std::bidirectional_iterator_tag iterator_category; + typedef std::random_access_iterator_tag iterator_category; typedef int difference_type; typedef QJsonValue value_type; typedef QJsonValue reference; diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 9dc8656c50..4d5b0f156c 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -40,6 +40,11 @@ #include <private/qcore_mac_p.h> +#ifdef Q_OS_OSX +#include <AppKit/NSText.h> +#include <Carbon/Carbon.h> +#endif + #include <qdebug.h> #ifdef Q_OS_IOS @@ -154,5 +159,148 @@ QMacAutoReleasePool::~QMacAutoReleasePool() // ------------------------------------------------------------------------- +#ifdef Q_OS_OSX + +// Use this method to keep all the information in the TextSegment. As long as it is ordered +// we are in OK shape, and we can influence that ourselves. +struct KeyPair +{ + QChar cocoaKey; + Qt::Key qtKey; +}; + +bool operator==(const KeyPair &entry, QChar qchar) +{ + return entry.cocoaKey == qchar; +} + +bool operator<(const KeyPair &entry, QChar qchar) +{ + return entry.cocoaKey < qchar; +} + +bool operator<(QChar qchar, const KeyPair &entry) +{ + return qchar < entry.cocoaKey; +} + +bool operator<(const Qt::Key &key, const KeyPair &entry) +{ + return key < entry.qtKey; +} + +bool operator<(const KeyPair &entry, const Qt::Key &key) +{ + return entry.qtKey < key; +} + +struct qtKey2CocoaKeySortLessThan +{ + typedef bool result_type; + Q_DECL_CONSTEXPR result_type operator()(const KeyPair &entry1, const KeyPair &entry2) const Q_DECL_NOTHROW + { + return entry1.qtKey < entry2.qtKey; + } +}; + +static const int NumEntries = 59; +static const KeyPair entries[NumEntries] = { + { NSEnterCharacter, Qt::Key_Enter }, + { NSBackspaceCharacter, Qt::Key_Backspace }, + { NSTabCharacter, Qt::Key_Tab }, + { NSNewlineCharacter, Qt::Key_Return }, + { NSCarriageReturnCharacter, Qt::Key_Return }, + { NSBackTabCharacter, Qt::Key_Backtab }, + { kEscapeCharCode, Qt::Key_Escape }, + // Cocoa sends us delete when pressing backspace! + // (NB when we reverse this list in qtKey2CocoaKey, there + // will be two indices of Qt::Key_Backspace. But is seems to work + // ok for menu shortcuts (which uses that function): + { NSDeleteCharacter, Qt::Key_Backspace }, + { NSUpArrowFunctionKey, Qt::Key_Up }, + { NSDownArrowFunctionKey, Qt::Key_Down }, + { NSLeftArrowFunctionKey, Qt::Key_Left }, + { NSRightArrowFunctionKey, Qt::Key_Right }, + { NSF1FunctionKey, Qt::Key_F1 }, + { NSF2FunctionKey, Qt::Key_F2 }, + { NSF3FunctionKey, Qt::Key_F3 }, + { NSF4FunctionKey, Qt::Key_F4 }, + { NSF5FunctionKey, Qt::Key_F5 }, + { NSF6FunctionKey, Qt::Key_F6 }, + { NSF7FunctionKey, Qt::Key_F7 }, + { NSF8FunctionKey, Qt::Key_F8 }, + { NSF9FunctionKey, Qt::Key_F9 }, + { NSF10FunctionKey, Qt::Key_F10 }, + { NSF11FunctionKey, Qt::Key_F11 }, + { NSF12FunctionKey, Qt::Key_F12 }, + { NSF13FunctionKey, Qt::Key_F13 }, + { NSF14FunctionKey, Qt::Key_F14 }, + { NSF15FunctionKey, Qt::Key_F15 }, + { NSF16FunctionKey, Qt::Key_F16 }, + { NSF17FunctionKey, Qt::Key_F17 }, + { NSF18FunctionKey, Qt::Key_F18 }, + { NSF19FunctionKey, Qt::Key_F19 }, + { NSF20FunctionKey, Qt::Key_F20 }, + { NSF21FunctionKey, Qt::Key_F21 }, + { NSF22FunctionKey, Qt::Key_F22 }, + { NSF23FunctionKey, Qt::Key_F23 }, + { NSF24FunctionKey, Qt::Key_F24 }, + { NSF25FunctionKey, Qt::Key_F25 }, + { NSF26FunctionKey, Qt::Key_F26 }, + { NSF27FunctionKey, Qt::Key_F27 }, + { NSF28FunctionKey, Qt::Key_F28 }, + { NSF29FunctionKey, Qt::Key_F29 }, + { NSF30FunctionKey, Qt::Key_F30 }, + { NSF31FunctionKey, Qt::Key_F31 }, + { NSF32FunctionKey, Qt::Key_F32 }, + { NSF33FunctionKey, Qt::Key_F33 }, + { NSF34FunctionKey, Qt::Key_F34 }, + { NSF35FunctionKey, Qt::Key_F35 }, + { NSInsertFunctionKey, Qt::Key_Insert }, + { NSDeleteFunctionKey, Qt::Key_Delete }, + { NSHomeFunctionKey, Qt::Key_Home }, + { NSEndFunctionKey, Qt::Key_End }, + { NSPageUpFunctionKey, Qt::Key_PageUp }, + { NSPageDownFunctionKey, Qt::Key_PageDown }, + { NSPrintScreenFunctionKey, Qt::Key_Print }, + { NSScrollLockFunctionKey, Qt::Key_ScrollLock }, + { NSPauseFunctionKey, Qt::Key_Pause }, + { NSSysReqFunctionKey, Qt::Key_SysReq }, + { NSMenuFunctionKey, Qt::Key_Menu }, + { NSHelpFunctionKey, Qt::Key_Help }, +}; +static const KeyPair * const end = entries + NumEntries; + +QChar qt_mac_qtKey2CocoaKey(Qt::Key key) +{ + // The first time this function is called, create a reverse + // lookup table sorted on Qt Key rather than Cocoa key: + static QVector<KeyPair> rev_entries(NumEntries); + static bool mustInit = true; + if (mustInit){ + mustInit = false; + for (int i=0; i<NumEntries; ++i) + rev_entries[i] = entries[i]; + std::sort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan()); + } + const QVector<KeyPair>::iterator i + = std::lower_bound(rev_entries.begin(), rev_entries.end(), key); + if ((i == rev_entries.end()) || (key < *i)) + return QChar(); + return i->cocoaKey; +} + +Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode) +{ + const KeyPair *i = std::lower_bound(entries, end, keyCode); + if ((i == end) || (keyCode < *i)) + return Qt::Key(keyCode.toUpper().unicode()); + return i->qtKey; +} + +#endif // Q_OS_OSX + +// ------------------------------------------------------------------------- + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index 5403014611..b94aac1093 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -143,6 +143,11 @@ typedef struct { QAppleOperatingSystemVersion qt_apple_os_version(); +#ifdef Q_OS_OSX +Q_CORE_EXPORT QChar qt_mac_qtKey2CocoaKey(Qt::Key key); +Q_CORE_EXPORT Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode); +#endif + QT_END_NAMESPACE #endif // QCORE_MAC_P_H diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 96f9203d4a..3ac1f28638 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1704,8 +1704,9 @@ bool QMetaType::load(QDataStream &stream, int type, void *data) void *QMetaType::create(int type, const void *copy) { QMetaType info(type); - int size = info.sizeOf(); - return info.construct(operator new(size), copy); + if (int size = info.sizeOf()) + return info.construct(operator new(size), copy); + return 0; } /*! diff --git a/src/corelib/kernel/qtcore_eval.cpp b/src/corelib/kernel/qtcore_eval.cpp index ee0c34a7a8..787db8a8a6 100644 --- a/src/corelib/kernel/qtcore_eval.cpp +++ b/src/corelib/kernel/qtcore_eval.cpp @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE static const char boilerplate_supported_but_time_limited[] = "\nQt %1 Evaluation License\n" - "Copyright (C) 2015 The Qt Company Ltd.\n" + "Copyright (C) 2016 The Qt Company Ltd.\n" "This trial version may only be used for evaluation purposes\n" "and will shut down after 120 minutes.\n" "Registered to:\n" @@ -63,7 +63,7 @@ static const char boilerplate_supported_but_time_limited[] = static const char boilerplate_supported[] = "\nQt %1 Evaluation License\n" - "Copyright (C) 2015 The Qt Company Ltd.\n" + "Copyright (C) 2016 The Qt Company Ltd.\n" "This trial version may only be used for evaluation purposes\n" "Registered to:\n" " Licensee: %2\n\n" diff --git a/src/corelib/statemachine/qfinalstate.cpp b/src/corelib/statemachine/qfinalstate.cpp index 61eca2c74d..efcb364794 100644 --- a/src/corelib/statemachine/qfinalstate.cpp +++ b/src/corelib/statemachine/qfinalstate.cpp @@ -37,12 +37,10 @@ ** ****************************************************************************/ -#include "qfinalstate.h" +#include "qfinalstate_p.h" #ifndef QT_NO_STATEMACHINE -#include "qabstractstate_p.h" - QT_BEGIN_NAMESPACE /*! @@ -82,19 +80,16 @@ QT_BEGIN_NAMESPACE \sa QState::finished() */ -class QFinalStatePrivate : public QAbstractStatePrivate -{ - Q_DECLARE_PUBLIC(QFinalState) - -public: - QFinalStatePrivate(); -}; - QFinalStatePrivate::QFinalStatePrivate() : QAbstractStatePrivate(FinalState) { } +QFinalStatePrivate::~QFinalStatePrivate() +{ + // to prevent vtables being generated in every file that includes the private header +} + /*! Constructs a new QFinalState object with the given \a parent state. */ @@ -104,6 +99,15 @@ QFinalState::QFinalState(QState *parent) } /*! + \internal + */ +QFinalState::QFinalState(QFinalStatePrivate &dd, QState *parent) + : QAbstractState(dd, parent) +{ +} + + +/*! Destroys this final state. */ QFinalState::~QFinalState() diff --git a/src/corelib/statemachine/qfinalstate.h b/src/corelib/statemachine/qfinalstate.h index f9b32ef128..9b6b193231 100644 --- a/src/corelib/statemachine/qfinalstate.h +++ b/src/corelib/statemachine/qfinalstate.h @@ -44,7 +44,6 @@ QT_BEGIN_NAMESPACE - #ifndef QT_NO_STATEMACHINE class QFinalStatePrivate; @@ -61,6 +60,9 @@ protected: bool event(QEvent *e) Q_DECL_OVERRIDE; +protected: + explicit QFinalState(QFinalStatePrivate &dd, QState *parent); + private: Q_DISABLE_COPY(QFinalState) Q_DECLARE_PRIVATE(QFinalState) diff --git a/src/corelib/statemachine/qfinalstate_p.h b/src/corelib/statemachine/qfinalstate_p.h new file mode 100644 index 0000000000..74640289f1 --- /dev/null +++ b/src/corelib/statemachine/qfinalstate_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QFINALSTATE_P_H +#define QFINALSTATE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qfinalstate.h" +#include "private/qabstractstate_p.h" + +#ifndef QT_NO_STATEMACHINE + +QT_BEGIN_NAMESPACE + +class Q_CORE_EXPORT QFinalStatePrivate : public QAbstractStatePrivate +{ + Q_DECLARE_PUBLIC(QFinalState) + +public: + QFinalStatePrivate(); + ~QFinalStatePrivate(); +}; + +QT_END_NAMESPACE + +#endif // QT_NO_STATEMACHINE + +#endif // QFINALSTATE_P_H diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp index bcfff1e462..cae6474c32 100644 --- a/src/corelib/statemachine/qstate.cpp +++ b/src/corelib/statemachine/qstate.cpp @@ -37,11 +37,10 @@ ** ****************************************************************************/ -#include "qstate.h" +#include "qstate_p.h" #ifndef QT_NO_STATEMACHINE -#include "qstate_p.h" #include "qhistorystate.h" #include "qhistorystate_p.h" #include "qabstracttransition.h" diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h index 438de427f5..913657e53b 100644 --- a/src/corelib/statemachine/qstate_p.h +++ b/src/corelib/statemachine/qstate_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include "qstate.h" #include "private/qabstractstate_p.h" #include <QtCore/qlist.h> @@ -58,6 +59,8 @@ #include <QtCore/qpointer.h> #include <QtCore/qvariant.h> +#ifndef QT_NO_STATEMACHINE + QT_BEGIN_NAMESPACE #ifndef QT_NO_PROPERTIES @@ -89,7 +92,7 @@ class QAbstractTransition; class QHistoryState; class QState; -class Q_AUTOTEST_EXPORT QStatePrivate : public QAbstractStatePrivate +class Q_CORE_EXPORT QStatePrivate : public QAbstractStatePrivate { Q_DECLARE_PUBLIC(QState) public: @@ -121,4 +124,6 @@ public: QT_END_NAMESPACE +#endif // QT_NO_STATEMACHINE + #endif diff --git a/src/corelib/statemachine/statemachine.pri b/src/corelib/statemachine/statemachine.pri index 910cf5e9b3..c5396a2ef8 100644 --- a/src/corelib/statemachine/statemachine.pri +++ b/src/corelib/statemachine/statemachine.pri @@ -6,6 +6,7 @@ HEADERS += $$PWD/qstatemachine.h \ $$PWD/qstate.h \ $$PWD/qstate_p.h \ $$PWD/qfinalstate.h \ + $$PWD/qfinalstate_p.h \ $$PWD/qhistorystate.h \ $$PWD/qhistorystate_p.h \ $$PWD/qabstracttransition.h \ diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index 3146a6d6fa..6690f28556 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -199,16 +199,19 @@ void QFutureInterfaceBase::waitForResume() int QFutureInterfaceBase::progressValue() const { + const QMutexLocker lock(&d->m_mutex); return d->m_progressValue; } int QFutureInterfaceBase::progressMinimum() const { + const QMutexLocker lock(&d->m_mutex); return d->m_progressMinimum; } int QFutureInterfaceBase::progressMaximum() const { + const QMutexLocker lock(&d->m_mutex); return d->m_progressMaximum; } diff --git a/src/corelib/thread/qfutureinterface_p.h b/src/corelib/thread/qfutureinterface_p.h index 92e2cdc7af..f5f0e7047f 100644 --- a/src/corelib/thread/qfutureinterface_p.h +++ b/src/corelib/thread/qfutureinterface_p.h @@ -152,18 +152,20 @@ public: QAtomicInt m_refCountT; }; + // T: accessed from executing thread + // Q: accessed from the waiting/querying thread RefCount refCount; mutable QMutex m_mutex; QWaitCondition waitCondition; QList<QFutureCallOutInterface *> outputConnections; - int m_progressValue; - int m_progressMinimum; - int m_progressMaximum; + int m_progressValue; // TQ + int m_progressMinimum; // TQ + int m_progressMaximum; // TQ QFutureInterfaceBase::State state; QElapsedTimer progressTime; QWaitCondition pausedWaitCondition; QtPrivate::ResultStoreBase m_results; - bool manualProgress; + bool manualProgress; // only accessed from executing thread int m_expectedResultCount; QtPrivate::ExceptionStore m_exceptionStore; QString m_progressText; diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index ace663ae30..853903619f 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -131,14 +131,13 @@ bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const } const SectionNode &node = sectionNodes.at(index); - int year, month, day, hour, minute, second, msec; - year = v.date().year(); - month = v.date().month(); - day = v.date().day(); - hour = v.time().hour(); - minute = v.time().minute(); - second = v.time().second(); - msec = v.time().msec(); + int year = v.date().year(); + int month = v.date().month(); + int day = v.date().day(); + int hour = v.time().hour(); + int minute = v.time().minute(); + int second = v.time().second(); + int msec = v.time().msec(); switch (node.type) { case Hour24Section: case Hour12Section: hour = newVal; break; @@ -676,15 +675,7 @@ QString QDateTimeParser::sectionText(const QString &text, int sectionIndex, int QString QDateTimeParser::sectionText(int sectionIndex) const { const SectionNode &sn = sectionNode(sectionIndex); - switch (sn.type) { - case NoSectionIndex: - case FirstSectionIndex: - case LastSectionIndex: - return QString(); - default: break; - } - - return displayText().mid(sn.pos, sectionSize(sectionIndex)); + return sectionText(displayText(), sectionIndex, sn.pos); } @@ -1012,8 +1003,10 @@ QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPos const QDate date(year, month, day); const int diff = dayofweek - date.dayOfWeek(); - if (diff != 0 && state == Acceptable && isSet & (DayOfWeekSectionShort|DayOfWeekSectionLong)) { - conflicts = isSet & DaySection; + if (diff != 0 && state == Acceptable + && isSet & (DayOfWeekSectionShort | DayOfWeekSectionLong)) { + if (isSet & DaySection) + conflicts = true; const SectionNode &sn = sectionNode(currentSectionIndex); if (sn.type & (DayOfWeekSectionShort|DayOfWeekSectionLong) || currentSectionIndex == -1) { // dayofweek should be preferred @@ -1377,9 +1370,9 @@ int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex */ -int QDateTimeParser::findAmPm(QString &str, int index, int *used) const +int QDateTimeParser::findAmPm(QString &str, int sectionIndex, int *used) const { - const SectionNode &s = sectionNode(index); + const SectionNode &s = sectionNode(sectionIndex); if (s.type != AmPmSection) { qWarning("QDateTimeParser::findAmPm Internal error"); return -1; @@ -1390,7 +1383,7 @@ int QDateTimeParser::findAmPm(QString &str, int index, int *used) const return PossibleBoth; } const QLatin1Char space(' '); - int size = sectionMaxSize(index); + int size = sectionMaxSize(sectionIndex); enum { amindex = 0, diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h index 2c1c14f05a..64e73346f2 100644 --- a/src/corelib/tools/qdatetimeparser_p.h +++ b/src/corelib/tools/qdatetimeparser_p.h @@ -93,7 +93,7 @@ public: first.pos = -1; first.count = -1; first.zeroesAdded = 0; - last.type = FirstSection; + last.type = LastSection; last.pos = -1; last.count = -1; last.zeroesAdded = 0; diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 524c9a14ae..faf9eb4b4d 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -242,9 +242,9 @@ template <> struct QConcatenable<QLatin1String> : private QAbstractConcatenable } static inline void appendTo(const QLatin1String a, char *&out) { - if (a.data()) { - for (const char *s = a.data(); *s; ) - *out++ = *s++; + if (const char *data = a.data()) { + memcpy(out, data, a.size()); + out += a.size(); } } }; diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 3cd5c4d8e4..b6fb9ae7cf 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -812,7 +812,6 @@ bool QDBusConnectionPrivate::activateCall(QObject* object, int flags, const QDBu if (!object) return false; -#ifndef QT_NO_PROPERTIES Q_ASSERT_X(QThread::currentThread() == object->thread(), "QDBusConnection: internal threading error", "function called for an object that is in another thread!!"); @@ -871,7 +870,6 @@ bool QDBusConnectionPrivate::activateCall(QObject* object, int flags, const QDBu deliverCall(object, flags, msg, cacheIt->metaTypes, cacheIt->slotIdx); return true; } -#endif // QT_NO_PROPERTIES return false; } diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 739f2a1c61..4758d1b5d4 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -1765,15 +1765,8 @@ QAccessibleInterface *QAccessibleEvent::accessibleInterface() const return QAccessible::accessibleInterface(m_uniqueId); QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(m_object); - if (!iface || !iface->isValid()) { - static bool hasWarned = false; - if (!iface && !hasWarned) { - qWarning() << "Problem creating accessible interface for: " << m_object << endl - << "Make sure to deploy Qt with accessibility plugins."; - hasWarned = true; - } + if (!iface || !iface->isValid()) return 0; - } if (m_child >= 0) { QAccessibleInterface *child = iface->child(m_child); diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 58e2586024..f98b4236fe 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -960,15 +960,10 @@ QList<QScreen *> QGuiApplication::screens() /*! \property QGuiApplication::primaryScreen - \brief the primary (or default) screen of the application, or null if there is none. + \brief the primary (or default) screen of the application. This will be the screen where QWindows are initially shown, unless otherwise specified. - On some platforms, it may be null when there are actually no screens connected. - It is not possible to start a new QGuiApplication while there are no screens. - Applications which were running at the time the primary screen was removed - will stop rendering graphics until one or more screens are restored. - The primaryScreenChanged signal was introduced in Qt 5.6. \sa screens() @@ -1095,7 +1090,7 @@ static void init_platform(const QString &pluginArgument, const QString &platform QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath); QString fatalMessage - = QStringLiteral("This application failed to start because it could not find or load the Qt platform plugin \"%1\".\n\n").arg(name); + = QStringLiteral("This application failed to start because it could not find or load the Qt platform plugin \"%1\"\nin \"%2\".\n\n").arg(name, QDir::toNativeSeparators(platformPluginPath)); if (!keys.isEmpty()) { fatalMessage += QStringLiteral("Available platform plugins are: %1.\n\n").arg( keys.join(QStringLiteral(", "))); @@ -1999,6 +1994,16 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE window = QGuiApplication::focusWindow(); } +#if !defined(Q_OS_OSX) + // FIXME: Include OS X in this code path by passing the key event through + // QPlatformInputContext::filterEvent(). + if (e->keyType == QEvent::KeyPress && window) { + if (QWindowSystemInterface::handleShortcutEvent(window, e->timestamp, e->key, e->modifiers, + e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers, e->unicode, e->repeat, e->repeatCount)) + return; + } +#endif + QKeyEvent ev(e->keyType, e->key, e->modifiers, e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers, e->unicode, e->repeat, e->repeatCount); diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 9fe7267607..38cc9506ee 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -146,6 +146,23 @@ static int qtkeyForMacSymbol(const QChar ch) #else static bool qt_sequence_no_mnemonics = false; #endif + +/*! + \fn void qt_set_sequence_auto_mnemonic(bool b) + \relates QKeySequence + + Specifies whether mnemonics for menu items, labels, etc., should + be honored or not. On Windows and X11, this feature is + on by default; on OS X, it is off. When this feature is off + (that is, when \a b is false), QKeySequence::mnemonic() always + returns an empty string. + + \note This function is not declared in any of Qt's header files. + To use it in your application, declare the function prototype + before calling it. + + \sa QShortcut +*/ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemonics = !b; } /*! diff --git a/src/gui/kernel/qkeysequence_p.h b/src/gui/kernel/qkeysequence_p.h index abe91df2ee..492546616b 100644 --- a/src/gui/kernel/qkeysequence_p.h +++ b/src/gui/kernel/qkeysequence_p.h @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_SHORTCUT -struct Q_AUTOTEST_EXPORT QKeyBinding +struct QKeyBinding { QKeySequence::StandardKey standardKey; uchar priority; @@ -66,7 +66,7 @@ struct Q_AUTOTEST_EXPORT QKeyBinding uint platform; }; -class Q_AUTOTEST_EXPORT QKeySequencePrivate +class QKeySequencePrivate { public: enum { MaxKeyCount = 4 }; // also used in QKeySequenceEdit diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 7055b7947a..d17c9c08a8 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -255,8 +255,10 @@ bool QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Q bool QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) { +#if defined(Q_OS_OSX) if (t == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(tlw, timestamp, k, mods, 0, 0, 0, text, autorep, count)) return true; +#endif QWindowSystemInterfacePrivate::KeyEvent * e = new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count); @@ -281,10 +283,14 @@ bool QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestam const QString& text, bool autorep, ushort count, bool tryShortcutOverride) { +#if defined(Q_OS_OSX) if (tryShortcutOverride && type == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(tlw, timestamp, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count)) { return true; } +#else + Q_UNUSED(tryShortcutOverride) +#endif QWindowSystemInterfacePrivate::KeyEvent * e = new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, type, key, modifiers, diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 16e88dad5f..089104665f 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -2815,6 +2815,10 @@ QFontEngine *QFontCache::findEngine(const Key &key) EngineCache::Iterator it = engineCache.find(key), end = engineCache.end(); if (it == end) return 0; + + Q_ASSERT(it.value().data != Q_NULLPTR); + Q_ASSERT(key.multi == (it.value().data->type() == QFontEngine::Multi)); + // found... update the hitcount and timestamp updateHitCountAndTimeStamp(it.value()); @@ -2835,6 +2839,9 @@ void QFontCache::updateHitCountAndTimeStamp(Engine &value) void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMulti) { + Q_ASSERT(engine != Q_NULLPTR); + Q_ASSERT(key.multi == (engine->type() == QFontEngine::Multi)); + #ifdef QFONTCACHE_DEBUG FC_DEBUG("QFontCache: inserting new engine %p, refcount %d", engine, engine->ref.load()); if (!insertMulti && engineCache.contains(key)) { diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 6c63f5c7ee..b680bb4717 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -927,23 +927,28 @@ QFontEngine *loadSingleEngine(int script, QFontDef def = request; def.pixelSize = pixelSize; + QFontCache *fontCache = QFontCache::instance(); + QFontCache::Key key(def,script); - QFontEngine *engine = QFontCache::instance()->findEngine(key); + QFontEngine *engine = fontCache->findEngine(key); if (!engine) { - if (script != QChar::Script_Common) { + const bool cacheForCommonScript = script != QChar::Script_Common + && (family->writingSystems[QFontDatabase::Latin] & QtFontFamily::Supported) != 0; + + if (Q_LIKELY(cacheForCommonScript)) { // fast path: check if engine was loaded for another script key.script = QChar::Script_Common; - engine = QFontCache::instance()->findEngine(key); + engine = fontCache->findEngine(key); key.script = script; if (engine) { - Q_ASSERT(engine->type() != QFontEngine::Multi); // Also check for OpenType tables when using complex scripts if (Q_UNLIKELY(!engine->supportsScript(QChar::Script(script)))) { qWarning(" OpenType support missing for script %d", script); return 0; } - QFontCache::instance()->insertEngine(key, engine); + fontCache->insertEngine(key, engine); + return engine; } } @@ -951,13 +956,13 @@ QFontEngine *loadSingleEngine(int script, // If the font data's native stretch matches the requested stretch we need to set stretch to 100 // to avoid the fontengine synthesizing stretch. If they didn't match exactly we need to calculate // the new stretch factor. This only done if not matched by styleName. - bool styleNameMatch = !request.styleName.isEmpty() && request.styleName == style->styleName; - if (!styleNameMatch && style->key.stretch != 0 && request.stretch != 0) + if (style->key.stretch != 0 && request.stretch != 0 + && (request.styleName.isEmpty() || request.styleName != style->styleName)) { def.stretch = (request.stretch * 100 + 50) / style->key.stretch; + } engine = pfdb->fontEngine(def, size->handle); if (engine) { - Q_ASSERT(engine->type() != QFontEngine::Multi); // Also check for OpenType tables when using complex scripts if (!engine->supportsScript(QChar::Script(script))) { qWarning(" OpenType support missing for script %d", script); @@ -966,13 +971,13 @@ QFontEngine *loadSingleEngine(int script, return 0; } - QFontCache::instance()->insertEngine(key, engine); + fontCache->insertEngine(key, engine); - if (!engine->symbol && script != QChar::Script_Common && (family->writingSystems[QFontDatabase::Latin] & QtFontFamily::Supported) != 0) { + if (Q_LIKELY(cacheForCommonScript && !engine->symbol)) { // cache engine for Common script as well key.script = QChar::Script_Common; - if (!QFontCache::instance()->findEngine(key)) - QFontCache::instance()->insertEngine(key, engine); + if (!fontCache->findEngine(key)) + fontCache->insertEngine(key, engine); } } } @@ -985,7 +990,7 @@ QFontEngine *loadEngine(int script, const QFontDef &request, QtFontStyle *style, QtFontSize *size) { QFontEngine *engine = loadSingleEngine(script, request, family, foundry, style, size); - Q_ASSERT(!engine || engine->type() != QFontEngine::Multi); + if (engine && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) { QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine, QChar::Script(script)); @@ -2641,12 +2646,14 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script) } #endif + QFontCache *fontCache = QFontCache::instance(); + // Until we specifically asked not to, try looking for Multi font engine // first, the last '1' indicates that we want Multi font engine instead // of single ones bool multi = !(request.styleStrategy & QFont::NoFontMerging); QFontCache::Key key(request, script, multi ? 1 : 0); - engine = QFontCache::instance()->findEngine(key); + engine = fontCache->findEngine(key); if (engine) { FM_DEBUG("Cache hit level 1"); return engine; @@ -2687,7 +2694,7 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script) QFontDef def = request; def.family = fallbacks.at(i); QFontCache::Key key(def, script, multi ? 1 : 0); - engine = QFontCache::instance()->findEngine(key); + engine = fontCache->findEngine(key); if (!engine) { QtFontDesc desc; do { @@ -2731,13 +2738,21 @@ void QFontDatabase::load(const QFontPrivate *d, int script) if (req.stretch == 0) req.stretch = 100; + // respect the fallback families that might be passed through the request + const QStringList fallBackFamilies = familyList(req); + if (!d->engineData) { + QFontCache *fontCache = QFontCache::instance(); // look for the requested font in the engine data cache - d->engineData = QFontCache::instance()->findEngineData(req); + // note: fallBackFamilies are not respected in the EngineData cache key; + // join them with the primary selection family to avoid cache misses + req.family = fallBackFamilies.join(QLatin1Char(',')); + + d->engineData = fontCache->findEngineData(req); if (!d->engineData) { // create a new one d->engineData = new QFontEngineData; - QFontCache::instance()->insertEngineData(req, d->engineData); + fontCache->insertEngineData(req, d->engineData); } d->engineData->ref.ref(); } @@ -2746,25 +2761,18 @@ void QFontDatabase::load(const QFontPrivate *d, int script) if (d->engineData->engines[script]) return; - // Until we specifically asked not to, try looking for Multi font engine - // first, the last '1' indicates that we want Multi font engine instead - // of single ones - bool multi = !(req.styleStrategy & QFont::NoFontMerging); - QFontCache::Key key(req, script, multi ? 1 : 0); + QFontEngine *fe = Q_NULLPTR; - QFontEngine *fe = QFontCache::instance()->findEngine(key); + req.fallBackFamilies = fallBackFamilies; + if (!req.fallBackFamilies.isEmpty()) + req.family = req.fallBackFamilies.takeFirst(); // list of families to try QStringList family_list; if (!req.family.isEmpty()) { - QStringList familiesForRequest = familyList(req); - // Add primary selection - family_list << familiesForRequest.takeFirst(); - - // Fallbacks requested in font request - req.fallBackFamilies = familiesForRequest; + family_list << req.family; // add the default family QString defaultFamily = QGuiApplication::font().family(); diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 26914b63d2..8924a7c4ae 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -2296,7 +2296,7 @@ QFontEngine *QFontEngineMulti::createMultiFontEngine(QFontEngine *fe, int script } if (!engine) { engine = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fontEngineMulti(fe, QChar::Script(script)); - QFontCache::instance()->insertEngine(key, engine, /* insertMulti */ !faceIsLocal); + fc->insertEngine(key, engine, /* insertMulti */ !faceIsLocal); } Q_ASSERT(engine); return engine; diff --git a/src/network/kernel/qnetworkproxy_libproxy.cpp b/src/network/kernel/qnetworkproxy_libproxy.cpp index eb310615f3..e89df79226 100644 --- a/src/network/kernel/qnetworkproxy_libproxy.cpp +++ b/src/network/kernel/qnetworkproxy_libproxy.cpp @@ -127,14 +127,15 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro bool haveDirectConnection = false; foreach (const QUrl& url, rawProxies) { QNetworkProxy::ProxyType type; - if (url.scheme() == QStringLiteral("http")) { + const QString scheme = url.scheme(); + if (scheme == QLatin1String("http")) { type = QNetworkProxy::HttpProxy; - } else if (url.scheme() == QStringLiteral("socks") - || url.scheme() == QStringLiteral("socks5")) { + } else if (scheme == QLatin1String("socks") + || scheme == QLatin1String("socks5")) { type = QNetworkProxy::Socks5Proxy; - } else if (url.scheme() == QStringLiteral("ftp")) { + } else if (scheme == QLatin1String("ftp")) { type = QNetworkProxy::FtpCachingProxy; - } else if (url.scheme() == QStringLiteral("direct")) { + } else if (scheme == QLatin1String("direct")) { type = QNetworkProxy::NoProxy; haveDirectConnection = true; } else { diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp index 661e77cee3..c813d8255b 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp @@ -55,7 +55,7 @@ QDBusPlatformMenuItem::QDBusPlatformMenuItem(quintptr tag) : m_tag(tag ? tag : reinterpret_cast<quintptr>(this)) // QMenu will overwrite this later , m_subMenu(Q_NULLPTR) , m_role(NoRole) - , m_isEnabled(false) + , m_isEnabled(true) , m_isVisible(true) , m_isSeparator(false) , m_isCheckable(false) @@ -152,7 +152,7 @@ QList<const QDBusPlatformMenuItem *> QDBusPlatformMenuItem::byIds(const QList<in QDBusPlatformMenu::QDBusPlatformMenu(quintptr tag) : m_tag(tag ? tag : reinterpret_cast<quintptr>(this)) - , m_isEnabled(false) + , m_isEnabled(true) , m_isVisible(true) , m_isSeparator(false) , m_dbusID(nextDBusID++) diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp index 97ff761a22..d982c5afff 100644 --- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp +++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp @@ -1967,71 +1967,71 @@ namespace // https://bugzilla.gnome.org/show_bug.cgi?id=744553 "ATK docs provide no guidance for allowed values of some text attributes" // specifically for "weight", "invalid", "language" and value range for colors - if (ia2Name == QStringLiteral("background-color")) { + if (ia2Name == QLatin1String("background-color")) { name = QStringLiteral("bg-color"); value = atspiColor(value); - } else if (ia2Name == QStringLiteral("font-family")) { + } else if (ia2Name == QLatin1String("font-family")) { name = QStringLiteral("family-name"); - } else if (ia2Name == QStringLiteral("color")) { + } else if (ia2Name == QLatin1String("color")) { name = QStringLiteral("fg-color"); value = atspiColor(value); - } else if (ia2Name == QStringLiteral("text-align")) { + } else if (ia2Name == QLatin1String("text-align")) { name = QStringLiteral("justification"); - if (value == QStringLiteral("justify")) { + if (value == QLatin1String("justify")) { value = QStringLiteral("fill"); } else { - if (value != QStringLiteral("left") && - value != QStringLiteral("right") && - value != QStringLiteral("center") + if (value != QLatin1String("left") && + value != QLatin1String("right") && + value != QLatin1String("center") ) { value = QString(); qAtspiDebug() << "Unknown text-align attribute value \"" << value << "\" cannot be translated to AT-SPI."; } } - } else if (ia2Name == QStringLiteral("font-size")) { + } else if (ia2Name == QLatin1String("font-size")) { name = QStringLiteral("size"); value = atspiSize(value); - } else if (ia2Name == QStringLiteral("font-style")) { + } else if (ia2Name == QLatin1String("font-style")) { name = QStringLiteral("style"); - if (value != QStringLiteral("normal") && - value != QStringLiteral("italic") && - value != QStringLiteral("oblique") + if (value != QLatin1String("normal") && + value != QLatin1String("italic") && + value != QLatin1String("oblique") ) { value = QString(); qAtspiDebug() << "Unknown font-style attribute value \"" << value << "\" cannot be translated to AT-SPI."; } - } else if (ia2Name == QStringLiteral("text-underline-type")) { + } else if (ia2Name == QLatin1String("text-underline-type")) { name = QStringLiteral("underline"); - if (value != QStringLiteral("none") && - value != QStringLiteral("single") && - value != QStringLiteral("double") + if (value != QLatin1String("none") && + value != QLatin1String("single") && + value != QLatin1String("double") ) { value = QString(); qAtspiDebug() << "Unknown text-underline-type attribute value \"" << value << "\" cannot be translated to AT-SPI."; } - } else if (ia2Name == QStringLiteral("font-weight")) { + } else if (ia2Name == QLatin1String("font-weight")) { name = QStringLiteral("weight"); - if (value == QStringLiteral("normal")) + if (value == QLatin1String("normal")) // Orca seems to accept all IAccessible2 values except for "normal" // (on which it produces traceback and fails to read any following text attributes), // but that is the default value, so omit it anyway value = QString(); - } else if (ia2Name == QStringLiteral("text-position")) { + } else if (ia2Name == QLatin1String("text-position")) { name = QStringLiteral("vertical-align"); - if (value != QStringLiteral("baseline") && - value != QStringLiteral("super") && - value != QStringLiteral("sub") + if (value != QLatin1String("baseline") && + value != QLatin1String("super") && + value != QLatin1String("sub") ) { value = QString(); qAtspiDebug() << "Unknown text-position attribute value \"" << value << "\" cannot be translated to AT-SPI."; } - } else if (ia2Name == QStringLiteral("writing-mode")) { + } else if (ia2Name == QLatin1String("writing-mode")) { name = QStringLiteral("direction"); - if (value == QStringLiteral("lr")) + if (value == QLatin1String("lr")) value = QStringLiteral("ltr"); - else if (value == QStringLiteral("rl")) + else if (value == QLatin1String("rl")) value = QStringLiteral("rtl"); - else if (value == QStringLiteral("tb")) { + else if (value == QLatin1String("tb")) { // IAccessible2 docs refer to XSL, which specifies "tb" is shorthand for "tb-rl"; so at least give a hint about the horizontal direction (ATK does not support vertical direction in this attribute (yet)) value = QStringLiteral("rtl"); qAtspiDebug() << "writing-mode attribute value \"tb\" translated only w.r.t. horizontal direction; vertical direction ignored"; @@ -2039,9 +2039,9 @@ namespace value = QString(); qAtspiDebug() << "Unknown writing-mode attribute value \"" << value << "\" cannot be translated to AT-SPI."; } - } else if (ia2Name == QStringLiteral("language")) { + } else if (ia2Name == QLatin1String("language")) { // OK - ATK has no docs on the format of the value, IAccessible2 has reasonable format - leave it at that now - } else if (ia2Name == QStringLiteral("invalid")) { + } else if (ia2Name == QLatin1String("invalid")) { // OK - ATK docs are vague but suggest they support the same range of values as IAccessible2 } else { // attribute we know nothing about diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index ab9560f93e..b0bc8a265e 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -1036,17 +1036,17 @@ QNetworkConfiguration::BearerType QNetworkManagerEngine::currentBearerType(const QString bearer = i.value()->bearer(); - if (bearer == QStringLiteral("gsm")) { + if (bearer == QLatin1String("gsm")) { return QNetworkConfiguration::Bearer2G; - } else if (bearer == QStringLiteral("edge")) { + } else if (bearer == QLatin1String("edge")) { return QNetworkConfiguration::Bearer2G; - } else if (bearer == QStringLiteral("umts")) { + } else if (bearer == QLatin1String("umts")) { return QNetworkConfiguration::BearerWCDMA; - } else if (bearer == QStringLiteral("hspa") - || bearer == QStringLiteral("hsdpa") - || bearer == QStringLiteral("hsupa")) { + } else if (bearer == QLatin1String("hspa") + || bearer == QLatin1String("hsdpa") + || bearer == QLatin1String("hsupa")) { return QNetworkConfiguration::BearerHSPA; - } else if (bearer == QStringLiteral("lte")) { + } else if (bearer == QLatin1String("lte")) { return QNetworkConfiguration::BearerLTE; } } diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp index e72ed10e99..8eebf86d67 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp @@ -220,7 +220,7 @@ void QNetworkManagerInterface::propertiesSwap(QMap<QString,QVariant> map) i.next(); propertyMap.insert(i.key(),i.value()); - if (i.key() == QStringLiteral("State")) { + if (i.key() == QLatin1String("State")) { quint32 state = i.value().toUInt(); if (state == NM_DEVICE_STATE_ACTIVATED || state == NM_DEVICE_STATE_DISCONNECTED @@ -229,7 +229,7 @@ void QNetworkManagerInterface::propertiesSwap(QMap<QString,QVariant> map) Q_EMIT propertiesChanged(map); Q_EMIT stateChanged(state); } - } else if (i.key() == QStringLiteral("ActiveConnections")) { + } else if (i.key() == QLatin1String("ActiveConnections")) { Q_EMIT propertiesChanged(map); } } @@ -424,7 +424,7 @@ void QNetworkManagerInterfaceDevice::propertiesSwap(QMap<QString,QVariant> map) QMapIterator<QString, QVariant> i(map); while (i.hasNext()) { i.next(); - if (i.key() == QStringLiteral("AvailableConnections")) { //Device + if (i.key() == QLatin1String("AvailableConnections")) { //Device const QDBusArgument &dbusArgs = i.value().value<QDBusArgument>(); QDBusObjectPath path; QStringList paths; @@ -520,9 +520,8 @@ void QNetworkManagerInterfaceDeviceWired::propertiesSwap(QMap<QString,QVariant> while (i.hasNext()) { i.next(); propertyMap.insert(i.key(),i.value()); - if (i.key() == QStringLiteral("Carrier")) { + if (i.key() == QLatin1String("Carrier")) Q_EMIT carrierChanged(i.value().toBool()); - } } Q_EMIT propertiesChanged(map); } @@ -699,9 +698,8 @@ void QNetworkManagerInterfaceDeviceWireless::propertiesSwap(QMap<QString,QVarian while (i.hasNext()) { i.next(); propertyMap.insert(i.key(),i.value()); - if (i.key() == QStringLiteral("ActiveAccessPoint")) { //DeviceWireless + if (i.key() == QLatin1String("ActiveAccessPoint")) //DeviceWireless Q_EMIT propertiesChanged(map); - } } } @@ -1057,7 +1055,7 @@ void QNetworkManagerConnectionActive::propertiesSwap(QMap<QString,QVariant> map) while (i.hasNext()) { i.next(); propertyMap.insert(i.key(),i.value()); - if (i.key() == QStringLiteral("State")) { + if (i.key() == QLatin1String("State")) { quint32 state = i.value().toUInt(); if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED || state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) { diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index 81d605933a..52d14e5324 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -279,7 +279,7 @@ QString TableGenerator::findComposeFile() // check if user’s home directory has a file named .XCompose if (cleanState()) { QString path = qgetenv("HOME") + QStringLiteral("/.XCompose"); - if (QFile(path).exists()) + if (QFile::exists(path)) return path; } @@ -292,7 +292,7 @@ QString TableGenerator::findComposeFile() m_state = UnsupportedLocale; else { QString path = QDir(systemComposeDir()).filePath(table); - if (QFile(path).exists()) + if (QFile::exists(path)) return path; } } @@ -314,7 +314,7 @@ bool TableGenerator::findSystemComposeDir() bool found = false; for (int i = 0; i < m_possibleLocations.size(); ++i) { QString path = m_possibleLocations.at(i); - if (QFile(path + QLatin1String("/compose.dir")).exists()) { + if (QFile::exists(path + QLatin1String("/compose.dir"))) { m_systemComposeDir = path; found = true; break; diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index e59632a9ec..1eae295724 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -362,6 +362,15 @@ namespace QtAndroid return surfaceId; } + void setViewVisibility(jobject view, bool visible) + { + QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, + "setViewVisibility", + "(Landroid/view/View;Z)V", + view, + visible); + } + void setSurfaceGeometry(int surfaceId, const QRect &geometry) { if (surfaceId == -1) diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h index 2fed5af61b..e3c18b2e7a 100644 --- a/src/plugins/platforms/android/androidjnimain.h +++ b/src/plugins/platforms/android/androidjnimain.h @@ -68,6 +68,7 @@ namespace QtAndroid int createSurface(AndroidSurfaceClient * client, const QRect &geometry, bool onTop, int imageDepth); int insertNativeView(jobject view, const QRect &geometry); + void setViewVisibility(jobject view, bool visible); void setSurfaceGeometry(int surfaceId, const QRect &geometry); void destroySurface(int surfaceId); void bringChildToFront(int surfaceId); diff --git a/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp b/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp index 89d4b08307..8c1f0ea8d2 100644 --- a/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp @@ -51,10 +51,14 @@ QAndroidPlatformForeignWindow::QAndroidPlatformForeignWindow(QWindow *window) { const WId wId = window->property("_q_foreignWinId").value<WId>(); m_view = reinterpret_cast<jobject>(wId); + if (m_view.isValid()) + QtAndroid::setViewVisibility(m_view.object(), false); } QAndroidPlatformForeignWindow::~QAndroidPlatformForeignWindow() { + if (m_view.isValid()) + QtAndroid::setViewVisibility(m_view.object(), false); if (m_surfaceId != -1) QtAndroid::destroySurface(m_surfaceId); } @@ -90,8 +94,9 @@ void QAndroidPlatformForeignWindow::setVisible(bool visible) if (!m_view.isValid()) return; - QAndroidPlatformWindow::setVisible(visible); + QtAndroid::setViewVisibility(m_view.object(), visible); + QAndroidPlatformWindow::setVisible(visible); if (!visible && m_surfaceId != -1) { QtAndroid::destroySurface(m_surfaceId); m_surfaceId = -1; diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm index 1c318e09bf..872b97566f 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.mm +++ b/src/plugins/platforms/cocoa/qcocoadrag.mm @@ -126,7 +126,9 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o) QPoint hotSpot = m_drag->hotSpot(); QPixmap pm = dragPixmap(m_drag, hotSpot); + QSize pmDeviceIndependentSize = pm.size() / pm.devicePixelRatio(); NSImage *nsimage = qt_mac_create_nsimage(pm); + [nsimage setSize : qt_mac_toNSSize(pmDeviceIndependentSize)]; QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacInternalPasteboardMime::MIME_DND); m_drag->mimeData()->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy")); @@ -136,7 +138,7 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o) NSWindow *theWindow = [m_lastEvent window]; Q_ASSERT(theWindow != nil); event_location.x -= hotSpot.x(); - CGFloat flippedY = pm.height() - hotSpot.y(); + CGFloat flippedY = pmDeviceIndependentSize.height() - hotSpot.y(); event_location.y -= flippedY; NSSize mouseOffset_unused = NSMakeSize(0.0, 0.0); NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index 09973680c2..766561a264 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -90,9 +90,6 @@ HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion ®ion); OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage); -QChar qt_mac_qtKey2CocoaKey(Qt::Key key); -Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode); - NSDragOperation qt_mac_mapDropAction(Qt::DropAction action); NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions); Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions); diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index b176549ca8..25fc9f0d5e 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -384,143 +384,6 @@ QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup) return qtBrush; } -// Use this method to keep all the information in the TextSegment. As long as it is ordered -// we are in OK shape, and we can influence that ourselves. -struct KeyPair -{ - QChar cocoaKey; - Qt::Key qtKey; -}; - -bool operator==(const KeyPair &entry, QChar qchar) -{ - return entry.cocoaKey == qchar; -} - -bool operator<(const KeyPair &entry, QChar qchar) -{ - return entry.cocoaKey < qchar; -} - -bool operator<(QChar qchar, const KeyPair &entry) -{ - return qchar < entry.cocoaKey; -} - -bool operator<(const Qt::Key &key, const KeyPair &entry) -{ - return key < entry.qtKey; -} - -bool operator<(const KeyPair &entry, const Qt::Key &key) -{ - return entry.qtKey < key; -} - -struct qtKey2CocoaKeySortLessThan -{ - typedef bool result_type; - Q_DECL_CONSTEXPR result_type operator()(const KeyPair &entry1, const KeyPair &entry2) const Q_DECL_NOTHROW - { - return entry1.qtKey < entry2.qtKey; - } -}; - -static const int NumEntries = 59; -static const KeyPair entries[NumEntries] = { - { NSEnterCharacter, Qt::Key_Enter }, - { NSBackspaceCharacter, Qt::Key_Backspace }, - { NSTabCharacter, Qt::Key_Tab }, - { NSNewlineCharacter, Qt::Key_Return }, - { NSCarriageReturnCharacter, Qt::Key_Return }, - { NSBackTabCharacter, Qt::Key_Backtab }, - { kEscapeCharCode, Qt::Key_Escape }, - // Cocoa sends us delete when pressing backspace! - // (NB when we reverse this list in qtKey2CocoaKey, there - // will be two indices of Qt::Key_Backspace. But is seems to work - // ok for menu shortcuts (which uses that function): - { NSDeleteCharacter, Qt::Key_Backspace }, - { NSUpArrowFunctionKey, Qt::Key_Up }, - { NSDownArrowFunctionKey, Qt::Key_Down }, - { NSLeftArrowFunctionKey, Qt::Key_Left }, - { NSRightArrowFunctionKey, Qt::Key_Right }, - { NSF1FunctionKey, Qt::Key_F1 }, - { NSF2FunctionKey, Qt::Key_F2 }, - { NSF3FunctionKey, Qt::Key_F3 }, - { NSF4FunctionKey, Qt::Key_F4 }, - { NSF5FunctionKey, Qt::Key_F5 }, - { NSF6FunctionKey, Qt::Key_F6 }, - { NSF7FunctionKey, Qt::Key_F7 }, - { NSF8FunctionKey, Qt::Key_F8 }, - { NSF9FunctionKey, Qt::Key_F9 }, - { NSF10FunctionKey, Qt::Key_F10 }, - { NSF11FunctionKey, Qt::Key_F11 }, - { NSF12FunctionKey, Qt::Key_F12 }, - { NSF13FunctionKey, Qt::Key_F13 }, - { NSF14FunctionKey, Qt::Key_F14 }, - { NSF15FunctionKey, Qt::Key_F15 }, - { NSF16FunctionKey, Qt::Key_F16 }, - { NSF17FunctionKey, Qt::Key_F17 }, - { NSF18FunctionKey, Qt::Key_F18 }, - { NSF19FunctionKey, Qt::Key_F19 }, - { NSF20FunctionKey, Qt::Key_F20 }, - { NSF21FunctionKey, Qt::Key_F21 }, - { NSF22FunctionKey, Qt::Key_F22 }, - { NSF23FunctionKey, Qt::Key_F23 }, - { NSF24FunctionKey, Qt::Key_F24 }, - { NSF25FunctionKey, Qt::Key_F25 }, - { NSF26FunctionKey, Qt::Key_F26 }, - { NSF27FunctionKey, Qt::Key_F27 }, - { NSF28FunctionKey, Qt::Key_F28 }, - { NSF29FunctionKey, Qt::Key_F29 }, - { NSF30FunctionKey, Qt::Key_F30 }, - { NSF31FunctionKey, Qt::Key_F31 }, - { NSF32FunctionKey, Qt::Key_F32 }, - { NSF33FunctionKey, Qt::Key_F33 }, - { NSF34FunctionKey, Qt::Key_F34 }, - { NSF35FunctionKey, Qt::Key_F35 }, - { NSInsertFunctionKey, Qt::Key_Insert }, - { NSDeleteFunctionKey, Qt::Key_Delete }, - { NSHomeFunctionKey, Qt::Key_Home }, - { NSEndFunctionKey, Qt::Key_End }, - { NSPageUpFunctionKey, Qt::Key_PageUp }, - { NSPageDownFunctionKey, Qt::Key_PageDown }, - { NSPrintScreenFunctionKey, Qt::Key_Print }, - { NSScrollLockFunctionKey, Qt::Key_ScrollLock }, - { NSPauseFunctionKey, Qt::Key_Pause }, - { NSSysReqFunctionKey, Qt::Key_SysReq }, - { NSMenuFunctionKey, Qt::Key_Menu }, - { NSHelpFunctionKey, Qt::Key_Help }, -}; -static const KeyPair * const end = entries + NumEntries; - -QChar qt_mac_qtKey2CocoaKey(Qt::Key key) -{ - // The first time this function is called, create a reverse - // lookup table sorted on Qt Key rather than Cocoa key: - static QVector<KeyPair> rev_entries(NumEntries); - static bool mustInit = true; - if (mustInit){ - mustInit = false; - for (int i=0; i<NumEntries; ++i) - rev_entries[i] = entries[i]; - std::sort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan()); - } - const QVector<KeyPair>::iterator i - = std::lower_bound(rev_entries.begin(), rev_entries.end(), key); - if ((i == rev_entries.end()) || (key < *i)) - return QChar(); - return i->cocoaKey; -} - -Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode) -{ - const KeyPair *i = std::lower_bound(entries, end, keyCode); - if ((i == end) || (keyCode < *i)) - return Qt::Key(keyCode.toUpper().unicode()); - return i->qtKey; -} - struct dndenum_mapper { NSDragOperation mac_code; diff --git a/src/plugins/platforms/haiku/qhaikuclipboard.cpp b/src/plugins/platforms/haiku/qhaikuclipboard.cpp index a838a05e2d..0194a0415a 100644 --- a/src/plugins/platforms/haiku/qhaikuclipboard.cpp +++ b/src/plugins/platforms/haiku/qhaikuclipboard.cpp @@ -92,9 +92,9 @@ QMimeData *QHaikuClipboard::mimeData(QClipboard::Mode mode) const status_t status = clipboard->FindData(name, B_MIME_TYPE, &data, &dataLen); if (dataLen && (status == B_OK)) { const QString format = QString::fromLatin1(name); - if (format == QStringLiteral("text/plain")) { + if (format == QLatin1String("text/plain")) { m_systemMimeData->setText(QString::fromLocal8Bit(reinterpret_cast<const char*>(data), dataLen)); - } else if (format == QStringLiteral("text/html")) { + } else if (format == QLatin1String("text/html")) { m_systemMimeData->setHtml(QString::fromLocal8Bit(reinterpret_cast<const char*>(data), dataLen)); } else { m_systemMimeData->setData(format, QByteArray(reinterpret_cast<const char*>(data), dataLen)); diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index bde9a77e77..2c6e6b9771 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -286,30 +286,33 @@ void QWindowsOleDropSource::createCursors() const bool hasPixmap = !pixmap.isNull(); // Find screen for drag. Could be obtained from QDrag::source(), but that might be a QWidget. - - qreal scaleFactor = 1; - QPlatformCursor *platformCursor = Q_NULLPTR; - if (const QPlatformScreen *platformScreen = QWindowsContext::instance()->screenManager().screenAtDp(QWindowsCursor::mousePosition())) { - scaleFactor = QHighDpiScaling::factor(platformScreen); - platformCursor = platformScreen->cursor(); + const QPlatformScreen *platformScreen = QWindowsContext::instance()->screenManager().screenAtDp(QWindowsCursor::mousePosition()); + if (!platformScreen) { + if (const QScreen *primaryScreen = QGuiApplication::primaryScreen()) + platformScreen = primaryScreen->handle(); + } + Q_ASSERT(platformScreen); + QPlatformCursor *platformCursor = platformScreen->cursor(); + + qreal pixmapScaleFactor = 1; + qreal hotSpotScaleFactor = 1; + if (m_mode != TouchDrag) { // Touch drag: pixmap is shown in a separate QWindow, which will be scaled.) + hotSpotScaleFactor = QHighDpiScaling::factor(platformScreen); + pixmapScaleFactor = hotSpotScaleFactor / pixmap.devicePixelRatio(); } - if (!platformCursor && QGuiApplication::primaryScreen()) - platformCursor = QGuiApplication::primaryScreen()->handle()->cursor(); - - const bool scalePixmap = hasPixmap - && m_mode != TouchDrag // Touch drag: pixmap is shown in a separate QWindow, which will be scaled. - && (scaleFactor != 1 && scaleFactor != qRound(pixmap.devicePixelRatio())); - const QPixmap scaledPixmap = scalePixmap - ? pixmap.scaled((QSizeF(pixmap.size()) * scaleFactor).toSize(), - Qt::KeepAspectRatio, Qt::SmoothTransformation) - : pixmap; + QPixmap scaledPixmap = qFuzzyCompare(pixmapScaleFactor, 1.0) + ? pixmap + : pixmap.scaled((QSizeF(pixmap.size()) * pixmapScaleFactor).toSize(), + Qt::KeepAspectRatio, Qt::SmoothTransformation); + scaledPixmap.setDevicePixelRatio(1); + Qt::DropAction actions[] = { Qt::MoveAction, Qt::CopyAction, Qt::LinkAction, Qt::IgnoreAction }; int actionCount = int(sizeof(actions) / sizeof(actions[0])); if (!hasPixmap) --actionCount; // No Qt::IgnoreAction unless pixmap - const QPoint hotSpot = scalePixmap - ? (QPointF(drag->hotSpot()) * scaleFactor).toPoint() - : drag->hotSpot(); + const QPoint hotSpot = qFuzzyCompare(hotSpotScaleFactor, 1.0) + ? drag->hotSpot() + : (QPointF(drag->hotSpot()) * hotSpotScaleFactor).toPoint(); for (int cnum = 0; cnum < actionCount; ++cnum) { const Qt::DropAction action = actions[cnum]; QPixmap cursorPixmap = drag->dragCursor(action); @@ -462,7 +465,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect) if (!m_touchDragWindow) m_touchDragWindow = new QWindowsDragCursorWindow; m_touchDragWindow->setPixmap(e.pixmap); - m_touchDragWindow->setFramePosition(QWindowsCursor::mousePosition() - e.hotSpot); + m_touchDragWindow->setFramePosition(QCursor::pos() - e.hotSpot); if (!m_touchDragWindow->isVisible()) m_touchDragWindow->show(); break; diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index bfb76dfee7..2d5eb4b4b9 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1620,7 +1620,7 @@ LOGFONT QWindowsFontDatabase::fontDefToLOGFONT(const QFontDef &request) if (fam.isEmpty()) fam = QStringLiteral("MS Sans Serif"); - if ((fam == QStringLiteral("MS Sans Serif")) + if (fam == QLatin1String("MS Sans Serif") && (request.style == QFont::StyleItalic || (-lf.lfHeight > 18 && -lf.lfHeight != 24))) { fam = QStringLiteral("Arial"); // MS Sans Serif has bearing problems in italic, and does not scale } diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index 3411381d4e..ed7fa441b2 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -238,17 +238,10 @@ int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLa } } else { #endif - wchar_t first = tm.tmFirstChar; - wchar_t last = tm.tmLastChar; - QStringIterator it(str, str + numChars); while (it.hasNext()) { const uint uc = it.next(); - if ( -#ifdef Q_DEAD_CODE_FROM_QT4_WINCE - tm.tmFirstChar > 60000 || -#endif - uc >= first && uc <= last) + if (uc >= tm.tmFirstChar && uc <= tm.tmLastChar) glyphs->glyphs[glyph_pos] = uc; else glyphs->glyphs[glyph_pos] = 0; @@ -358,11 +351,9 @@ glyph_t QWindowsFontEngine::glyphIndex(uint ucs4) const glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4 + 0xf000); } else if (ttf) { glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4); -#else - if (tm.tmFirstChar > 60000) { - glyph = ucs4; + } else #endif - } else if (ucs4 >= tm.tmFirstChar && ucs4 <= tm.tmLastChar) { + if (ucs4 >= tm.tmFirstChar && ucs4 <= tm.tmLastChar) { glyph = ucs4; } else { glyph = 0; diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index a16397f169..61c867cf07 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -1151,7 +1151,7 @@ QVariant QWindowsMimeImage::convertToMime(const QString &mimeType, IDataObject * { Q_UNUSED(preferredType); QVariant result; - if (mimeType != QStringLiteral("application/x-qt-image")) + if (mimeType != QLatin1String("application/x-qt-image")) return result; //Try to convert from a format which has more data //DIBV5, use only if its is not synthesized diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 246ebcb238..e83d44bbfe 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -230,6 +230,30 @@ static inline QRect frameGeometry(HWND hwnd, bool topLevel) return qrectFromRECT(rect); } +// Return the visibility of the Window (except full screen since it is not a window state). +static QWindow::Visibility windowVisibility_sys(HWND hwnd) +{ + if (!IsWindowVisible(hwnd)) + return QWindow::Hidden; +#ifndef Q_OS_WINCE + WINDOWPLACEMENT windowPlacement; + windowPlacement.length = sizeof(WINDOWPLACEMENT); + if (GetWindowPlacement(hwnd, &windowPlacement)) { + switch (windowPlacement.showCmd) { + case SW_SHOWMINIMIZED: + case SW_MINIMIZE: + case SW_FORCEMINIMIZE: + return QWindow::Minimized; + case SW_SHOWMAXIMIZED: + return QWindow::Maximized; + default: + break; + } + } +#endif // !Q_OS_WINCE + return QWindow::Windowed; +} + static inline QSize clientSize(HWND hwnd) { RECT rect = { 0, 0, 0, 0 }; @@ -1867,6 +1891,10 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState) swpf |= SWP_NOSIZE | SWP_NOMOVE; const bool wasSync = testFlag(SynchronousGeometryChangeEvent); setFlag(SynchronousGeometryChangeEvent); + // After maximized/fullscreen; the window can be in a maximized state. Clear + // it before applying the normal geometry. + if (windowVisibility_sys(m_data.hwnd) == QWindow::Maximized) + ShowWindow(m_data.hwnd, SW_SHOWNOACTIVATE); SetWindowPos(m_data.hwnd, 0, m_savedFrameGeometry.x(), m_savedFrameGeometry.y(), m_savedFrameGeometry.width(), m_savedFrameGeometry.height(), swpf); if (!wasSync) diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 997aa0d86c..4c4d553b2d 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -1169,7 +1169,7 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEvent Q_D(QWinRTScreen); boolean visible; HRESULT hr = args ? args->get_Visible(&visible) : d->coreWindow->get_Visible(&visible); - RETURN_OK_IF_FAILED("Failed to get visbile."); + RETURN_OK_IF_FAILED("Failed to get visibility."); QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden); if (visible) handleExpose(); diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 20a5232235..4d29cdc316 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -645,7 +645,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra QString glIntegrationName = QString::fromLocal8Bit(qgetenv("QT_XCB_GL_INTEGRATION")); if (!glIntegrationName.isEmpty()) { qCDebug(QT_XCB_GLINTEGRATION) << "QT_XCB_GL_INTEGRATION is set to" << glIntegrationName; - if (glIntegrationName != QStringLiteral("none")) { + if (glIntegrationName != QLatin1String("none")) { glIntegrationNames.removeAll(glIntegrationName); glIntegrationNames.prepend(glIntegrationName); } else { diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index e69fa2d1df..848cd85b03 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2265,12 +2265,13 @@ void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, con static bool ignoreLeaveEvent(const xcb_leave_notify_event_t *event) { return event->detail == XCB_NOTIFY_DETAIL_VIRTUAL - || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL; + || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL + || event->mode == XCB_NOTIFY_MODE_GRAB; } static bool ignoreEnterEvent(const xcb_enter_notify_event_t *event) { - return ((event->mode != XCB_NOTIFY_MODE_NORMAL && event->mode != XCB_NOTIFY_MODE_UNGRAB) + return (event->mode != XCB_NOTIFY_MODE_NORMAL || event->detail == XCB_NOTIFY_DETAIL_VIRTUAL || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); } diff --git a/src/plugins/printsupport/cocoa/main.cpp b/src/plugins/printsupport/cocoa/main.cpp index 5f8d15b999..b6830c88d4 100644 --- a/src/plugins/printsupport/cocoa/main.cpp +++ b/src/plugins/printsupport/cocoa/main.cpp @@ -55,7 +55,7 @@ public: QPlatformPrinterSupport *QCocoaPrinterSupportPlugin::create(const QString &key) { - if (key.compare(key, QStringLiteral("cocoaprintersupport"), Qt::CaseInsensitive) != 0) + if (key.compare(key, QLatin1String("cocoaprintersupport"), Qt::CaseInsensitive) != 0) return 0; QGuiApplication *app = qobject_cast<QGuiApplication *>(QCoreApplication::instance()); if (!app) diff --git a/src/testlib/qtestkeyboard.h b/src/testlib/qtestkeyboard.h index 325e1f69e8..1119b04293 100644 --- a/src/testlib/qtestkeyboard.h +++ b/src/testlib/qtestkeyboard.h @@ -75,11 +75,7 @@ namespace QTest QEvent::Type type; type = press ? QEvent::KeyPress : QEvent::KeyRelease; qt_handleKeyEvent(window, type, code, modifier, text, repeat, delay); -#ifdef QT_MAC_USE_COCOA - QTest::qWait(20); -#else qApp->processEvents(); -#endif } static void sendKeyEvent(KeyAction action, QWindow *window, Qt::Key code, diff --git a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp index 2aa8efe7b4..1b06845c46 100644 --- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp +++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp @@ -62,7 +62,7 @@ static const char docTypeHeader[] = #define PROGRAMNAME "qdbuscpp2xml" #define PROGRAMVERSION "0.2" -#define PROGRAMCOPYRIGHT "Copyright (C) 2015 The Qt Company Ltd." +#define PROGRAMCOPYRIGHT "Copyright (C) 2016 The Qt Company Ltd." static QString outputFile; static int flags; diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp index 95c0f7c46e..ae5178fffc 100644 --- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp +++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp @@ -43,7 +43,7 @@ #define PROGRAMNAME "qdbusxml2cpp" #define PROGRAMVERSION "0.8" -#define PROGRAMCOPYRIGHT "Copyright (C) 2015 The Qt Company Ltd." +#define PROGRAMCOPYRIGHT "Copyright (C) 2016 The Qt Company Ltd." #define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply" diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp index 555a1f39ff..97a63d49c6 100644 --- a/src/tools/uic/uic.cpp +++ b/src/tools/uic/uic.cpp @@ -117,13 +117,13 @@ void Uic::writeCopyrightHeader(DomUI *ui) if (comment.size()) out << "/*\n" << comment << "\n*/\n\n"; - out << "/********************************************************************************\n"; - out << "** Form generated from reading UI file '" << QFileInfo(opt.inputFile).fileName() << "'\n"; - out << "**\n"; - out << "** Created by: Qt User Interface Compiler version " << QLatin1String(QT_VERSION_STR) << "\n"; - out << "**\n"; - out << "** WARNING! All changes made in this file will be lost when recompiling UI file!\n"; - out << "********************************************************************************/\n\n"; + out << "/********************************************************************************\n"; + out << "** Form generated from reading UI file '" << QFileInfo(opt.inputFile).fileName() << "'\n"; + out << "**\n"; + out << "** Created by: Qt User Interface Compiler version " << QLatin1String(QT_VERSION_STR) << "\n"; + out << "**\n"; + out << "** WARNING! All changes made in this file will be lost when recompiling UI file!\n"; + out << "********************************************************************************/\n\n"; } // Check the version with a stream reader at the <ui> element. diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 7b59f96f30..288922d740 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -3407,27 +3407,27 @@ void QFileDialogPrivate::_q_deleteCurrent() if (!index.isValid()) continue; - QString fileName = index.data(QFileSystemModel::FileNameRole).toString(); - QString filePath = index.data(QFileSystemModel::FilePathRole).toString(); - bool isDir = model->isDir(index); + QString fileName = index.data(QFileSystemModel::FileNameRole).toString(); + QString filePath = index.data(QFileSystemModel::FilePathRole).toString(); + bool isDir = model->isDir(index); - QFile::Permissions p(index.parent().data(QFileSystemModel::FilePermissions).toInt()); + QFile::Permissions p(index.parent().data(QFileSystemModel::FilePermissions).toInt()); #ifndef QT_NO_MESSAGEBOX - Q_Q(QFileDialog); - if (!(p & QFile::WriteUser) && (QMessageBox::warning(q_func(), QFileDialog::tr("Delete"), - QFileDialog::tr("'%1' is write protected.\nDo you want to delete it anyway?") - .arg(fileName), - QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No)) - return; - else if (QMessageBox::warning(q_func(), QFileDialog::tr("Delete"), - QFileDialog::tr("Are you sure you want to delete '%1'?") - .arg(fileName), - QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) - return; + Q_Q(QFileDialog); + if (!(p & QFile::WriteUser) && (QMessageBox::warning(q_func(), QFileDialog::tr("Delete"), + QFileDialog::tr("'%1' is write protected.\nDo you want to delete it anyway?") + .arg(fileName), + QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No)) + return; + else if (QMessageBox::warning(q_func(), QFileDialog::tr("Delete"), + QFileDialog::tr("Are you sure you want to delete '%1'?") + .arg(fileName), + QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) + return; #else - if (!(p & QFile::WriteUser)) - return; + if (!(p & QFile::WriteUser)) + return; #endif // QT_NO_MESSAGEBOX // the event loop has run, we can NOT reuse index because the model might have removed it. diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index cd5643660d..207b6e3919 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -1903,7 +1903,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title) "<p>Qt and the Qt logo are trademarks of The Qt Company Ltd.</p>" "<p>Qt is The Qt Company Ltd product developed as an open source " "project. See <a href=\"http://%3/\">%3</a> for more information.</p>" - ).arg(QStringLiteral("2015"), + ).arg(QStringLiteral("2016"), QStringLiteral("qt.io/licensing"), QStringLiteral("qt.io")); QMessageBox *msgBox = new QMessageBox(parent); diff --git a/src/widgets/doc/snippets/macmainwindow.mm b/src/widgets/doc/snippets/macmainwindow.mm index cfa7271bbd..f74f8453c7 100644 --- a/src/widgets/doc/snippets/macmainwindow.mm +++ b/src/widgets/doc/snippets/macmainwindow.mm @@ -45,8 +45,6 @@ #include <Carbon/Carbon.h> -#ifdef QT_MAC_USE_COCOA - //![0] SearchWidget::SearchWidget(QWidget *parent) : QMacCocoaViewContainer(0, parent) @@ -82,57 +80,6 @@ QSize SearchWidget::sizeHint() const return QSize(150, 40); } -#else - -// The SearchWidget class wraps a native HISearchField. -SearchWidget::SearchWidget(QWidget *parent) - :QWidget(parent) -{ - - // Create a native search field and pass its window id to QWidget::create. - searchFieldText = CFStringCreateWithCString(0, "search", 0); - HISearchFieldCreate(NULL/*bounds*/, kHISearchFieldAttributesSearchIcon | kHISearchFieldAttributesCancel, - NULL/*menu ref*/, searchFieldText, &searchField); - create(reinterpret_cast<WId>(searchField)); - - // Use a Qt menu for the search field menu. - QMenu *searchMenu = createMenu(this); - MenuRef menuRef = searchMenu->macMenu(0); - HISearchFieldSetSearchMenu(searchField, menuRef); - setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); -} - -SearchWidget::~SearchWidget() -{ - CFRelease(searchField); - CFRelease(searchFieldText); -} - -// Get the size hint from the search field. -QSize SearchWidget::sizeHint() const -{ - EventRef event; - HIRect optimalBounds; - CreateEvent(0, kEventClassControl, - kEventControlGetOptimalBounds, - GetCurrentEventTime(), - kEventAttributeUserEvent, &event); - - SendEventToEventTargetWithOptions(event, - HIObjectGetEventTarget(HIObjectRef(winId())), - kEventTargetDontPropagate); - - GetEventParameter(event, - kEventParamControlOptimalBounds, typeHIRect, - 0, sizeof(HIRect), 0, &optimalBounds); - - ReleaseEvent(event); - return QSize(optimalBounds.size.width + 100, // make it a bit wider. - optimalBounds.size.height); -} - -#endif - QMenu *createMenu(QWidget *parent) { QMenu *searchMenu = new QMenu(parent); diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index ef70a39a2c..e1b835e727 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -1181,8 +1181,8 @@ void QGraphicsViewPrivate::updateInputMethodSensitivity() if (!proxy) { q->setInputMethodHints(focusItem->inputMethodHints()); } else if (QWidget *widget = proxy->widget()) { - if (QWidget *fw = widget->focusWidget()) - widget = fw; + if (QWidget *fw = widget->focusWidget()) + widget = fw; q->setInputMethodHints(widget->inputMethodHints()); } else { q->setInputMethodHints(0); diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp index dbec689efa..72d6fffefd 100644 --- a/src/widgets/kernel/qaction.cpp +++ b/src/widgets/kernel/qaction.cpp @@ -45,10 +45,10 @@ #include "qapplication.h" #include "qevent.h" #include "qlist.h" -#include "qdebug.h" #include <private/qshortcutmap_p.h> #include <private/qapplication_p.h> #include <private/qmenu_p.h> +#include <private/qdebug_p.h> #define QAPP_CHECK(functionName) \ if (Q_UNLIKELY(!qApp)) { \ @@ -1302,6 +1302,31 @@ bool QAction::isIconVisibleInMenu() const return d->iconVisibleInMenu; } +#ifndef QT_NO_DEBUG_STREAM +Q_WIDGETS_EXPORT QDebug operator<<(QDebug d, const QAction *action) +{ + QDebugStateSaver saver(d); + d.nospace(); + d << "QAction(" << static_cast<const void *>(action); + if (action) { + d << " text=" << action->text(); + if (!action->toolTip().isEmpty()) + d << " toolTip=" << action->toolTip(); + if (action->isCheckable()) + d << " checked=" << action->isChecked(); + if (!action->shortcut().isEmpty()) + d << " shortcut=" << action->shortcut(); + d << " menuRole="; + QtDebugUtils::formatQEnum(d, action->menuRole()); + d << " visible=" << action->isVisible(); + } else { + d << '0'; + } + d << ')'; + return d; +} +#endif // QT_NO_DEBUG_STREAM + QT_END_NAMESPACE #include "moc_qaction.cpp" diff --git a/src/widgets/kernel/qaction.h b/src/widgets/kernel/qaction.h index 6caf37c80f..abfa2cdd42 100644 --- a/src/widgets/kernel/qaction.h +++ b/src/widgets/kernel/qaction.h @@ -209,6 +209,10 @@ private: #endif }; +#ifndef QT_NO_DEBUG_STREAM +Q_WIDGETS_EXPORT QDebug operator<<(QDebug, const QAction *); +#endif + QT_BEGIN_INCLUDE_NAMESPACE #include <QtWidgets/qactiongroup.h> QT_END_INCLUDE_NAMESPACE diff --git a/src/widgets/kernel/qdesktopwidget.qdoc b/src/widgets/kernel/qdesktopwidget.qdoc index d1a6ecabd6..abdbd35f5b 100644 --- a/src/widgets/kernel/qdesktopwidget.qdoc +++ b/src/widgets/kernel/qdesktopwidget.qdoc @@ -238,11 +238,6 @@ \property QDesktopWidget::screenCount \brief the number of screens currently available on the system. - Note that on some platforms, screenCount will be zero if there are actually - no screens connected. Applications which were running at the time the - screenCount went to zero will stop rendering graphics until one or more - screens are restored. - \since 4.6 */ diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp index 55f733045e..77efaf1632 100644 --- a/src/widgets/kernel/qshortcut.cpp +++ b/src/widgets/kernel/qshortcut.cpp @@ -335,7 +335,7 @@ static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidge shown and the character will be underlined. On Windows, shortcuts are normally not displayed until the user presses the \uicontrol Alt key, but this is a setting the user can change. On Mac, shortcuts - are disabled by default. Call qt_set_sequence_auto_mnemonic() to + are disabled by default. Call \l qt_set_sequence_auto_mnemonic() to enable them. However, because mnemonic shortcuts do not fit in with Aqua's guidelines, Qt will not show the shortcut character underlined. diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp index dab49f2f11..462a41ce5d 100644 --- a/src/widgets/kernel/qwindowcontainer.cpp +++ b/src/widgets/kernel/qwindowcontainer.cpp @@ -90,6 +90,11 @@ public: if (usesNativeWidgets || window->parent() == 0) return; Q_Q(QWindowContainer); + if (q->internalWinId()) { + // Allow use native widgets if the window container is already a native widget + usesNativeWidgets = true; + return; + } QWidget *p = q->parentWidget(); while (p) { if ( @@ -153,8 +158,10 @@ public: as a child of a QAbstractScrollArea or QMdiArea, it will create a \l {Native Widgets vs Alien Widgets} {native window} for every widget in its parent chain to allow for proper stacking and - clipping in this use case. Applications with many native child - windows may suffer from performance issues. + clipping in this use case. Creating a native window for the window + container also allows for proper stacking and clipping. This must + be done before showing the window container. Applications with + many native child windows may suffer from performance issues. The window container has a number of known limitations: diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index 2467040f29..3136118cdd 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -404,7 +404,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt { XPThemeData theme(widget, painter, QWindowsXPStylePrivate::TreeViewTheme); static int decoration_size = 0; - if (d->initTreeViewTheming() && theme.isValid() && !decoration_size) { + if (!decoration_size && d->initTreeViewTheming() && theme.isValid()) { XPThemeData themeSize = theme; themeSize.partId = TVP_HOTGLYPH; themeSize.stateId = GLPS_OPENED; diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 2c32acf701..46507e3e3c 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -1317,8 +1317,8 @@ void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index) if (!lineEdit) emit q->currentTextChanged(text); #ifndef QT_NO_ACCESSIBILITY - QAccessibleValueChangeEvent event(q, text); - QAccessible::updateAccessibility(&event); + QAccessibleValueChangeEvent event(q, text); + QAccessible::updateAccessibility(&event); #endif } @@ -2838,8 +2838,8 @@ void QComboBox::clear() Q_D(QComboBox); d->model->removeRows(0, d->model->rowCount(d->root), d->root); #ifndef QT_NO_ACCESSIBILITY - QAccessibleValueChangeEvent event(this, QString()); - QAccessible::updateAccessibility(&event); + QAccessibleValueChangeEvent event(this, QString()); + QAccessible::updateAccessibility(&event); #endif } @@ -2852,8 +2852,8 @@ void QComboBox::clearEditText() if (d->lineEdit) d->lineEdit->clear(); #ifndef QT_NO_ACCESSIBILITY - QAccessibleValueChangeEvent event(this, QString()); - QAccessible::updateAccessibility(&event); + QAccessibleValueChangeEvent event(this, QString()); + QAccessible::updateAccessibility(&event); #endif } @@ -2866,8 +2866,8 @@ void QComboBox::setEditText(const QString &text) if (d->lineEdit) d->lineEdit->setText(text); #ifndef QT_NO_ACCESSIBILITY - QAccessibleValueChangeEvent event(this, text); - QAccessible::updateAccessibility(&event); + QAccessibleValueChangeEvent event(this, text); + QAccessible::updateAccessibility(&event); #endif } @@ -3012,8 +3012,8 @@ bool QComboBox::event(QEvent *event) case QEvent::HoverEnter: case QEvent::HoverLeave: case QEvent::HoverMove: - if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event)) - d->updateHoverControl(he->pos()); + if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event)) + d->updateHoverControl(he->pos()); break; case QEvent::ShortcutOverride: if (d->lineEdit) diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index 030472f757..69be43a51e 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -1950,12 +1950,8 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*> qt_mac_set_drawer_preferred_edge(widget, toDockWidgetArea(dockPos)); } else #endif - if (!testing) { - QRect r(x, y, w, h); - r = QDockAreaLayout::constrainedRect(r, widget); - widget->move(r.topLeft()); - widget->resize(r.size()); - } + if (!testing) + widget->setGeometry(QDockAreaLayout::constrainedRect(QRect(x, y, w, h), widget)); if (!testing) { widget->setVisible(flags & StateFlagVisible); diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 02215c4129..ae20159473 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -590,7 +590,9 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason if (reason != SelectedFromKeyboard) { if (QMenu *menu = qobject_cast<QMenu*>(causedPopup.widget)) { if (causedPopup.action && menu->d_func()->activeMenu == q) - menu->d_func()->setCurrentAction(causedPopup.action, 0, reason, false); + // Reselect parent menu action only if mouse is over a menu and parent menu action is not already selected (QTBUG-47987) + if (hasReceievedEnter && menu->d_func()->currentAction != causedPopup.action) + menu->d_func()->setCurrentAction(causedPopup.action, 0, reason, false); } } diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm index 3cc572cb37..c24779d61f 100644 --- a/src/widgets/widgets/qmenu_mac.mm +++ b/src/widgets/widgets/qmenu_mac.mm @@ -104,15 +104,13 @@ void QMenu::setAsDockMenu() /*! \fn void qt_mac_set_dock_menu(QMenu *menu) - \since 5.2 + \relates QMenu \deprecated - Set this menu to be the dock menu available by option-clicking + Sets this \a menu to be the dock menu available by option-clicking on the application dock icon. Available on OS X only. - Deprecated; use QMenu:setAsDockMenu() instead. - - \sa QMenu:setAsDockMenu() + Deprecated; use \l QMenu::setAsDockMenu() instead. */ void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem* item) diff --git a/src/widgets/widgets/qscrollbar.cpp b/src/widgets/widgets/qscrollbar.cpp index 89f8ba46cf..7399601c2e 100644 --- a/src/widgets/widgets/qscrollbar.cpp +++ b/src/widgets/widgets/qscrollbar.cpp @@ -485,8 +485,8 @@ bool QScrollBar::event(QEvent *event) case QEvent::HoverEnter: case QEvent::HoverLeave: case QEvent::HoverMove: - if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event)) - d_func()->updateHoverControl(he->pos()); + if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event)) + d_func()->updateHoverControl(he->pos()); break; case QEvent::StyleChange: d_func()->setTransient(style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, this)); diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp index d5bbe14b25..664aec9a53 100644 --- a/src/widgets/widgets/qtoolbutton.cpp +++ b/src/widgets/widgets/qtoolbutton.cpp @@ -126,7 +126,7 @@ bool QToolButtonPrivate::hasMenu() const One classic use of a tool button is to select tools; for example, the "pen" tool in a drawing program. This would be implemented - by using a QToolButton as a toggle button (see setToggleButton()). + by using a QToolButton as a toggle button (see setCheckable()). QToolButton supports auto-raising. In auto-raise mode, the button draws a 3D frame only when the mouse points at it. The feature is @@ -153,8 +153,8 @@ bool QToolButtonPrivate::hasMenu() const menu set. The default mode is DelayedPopupMode which is sometimes used with the "Back" button in a web browser. After pressing and holding the button down for a while, a menu pops up showing a list - of possible pages to jump to. The default delay is 600 ms; you can - adjust it with setPopupDelay(). + of possible pages to jump to. The timeout is style dependent, + see QStyle::SH_ToolButton_PopupDelay. \table 100% \row \li \inlineimage assistant-toolbar.png Qt Assistant's toolbar with tool buttons @@ -826,7 +826,7 @@ void QToolButtonPrivate::_q_menuTriggered(QAction *action) a menu set or contains a list of actions. \value DelayedPopup After pressing and holding the tool button - down for a certain amount of time (the timeout is style dependant, + down for a certain amount of time (the timeout is style dependent, see QStyle::SH_ToolButton_PopupDelay), the menu is displayed. A typical application example is the "back" button in some web browsers's tool bars. If the user clicks it, the browser simply @@ -967,8 +967,8 @@ bool QToolButton::event(QEvent *event) case QEvent::HoverEnter: case QEvent::HoverLeave: case QEvent::HoverMove: - if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event)) - d_func()->updateHoverControl(he->pos()); + if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event)) + d_func()->updateHoverControl(he->pos()); break; default: break; diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro index b7a641959a..132f01092a 100644 --- a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro +++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro @@ -5,6 +5,7 @@ HEADERS = plugin1.h SOURCES = plugin1.cpp TARGET = $$qtLibraryTarget(plugin1) DESTDIR = ../bin +winrt:include(../winrt.pri) # This is testdata for the tst_qpluginloader test. target.path = $$[QT_INSTALL_TESTS]/tst_qfactoryloader/bin diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro index b536aff486..b47ed91535 100644 --- a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro +++ b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro @@ -5,6 +5,7 @@ HEADERS = plugin2.h SOURCES = plugin2.cpp TARGET = $$qtLibraryTarget(plugin2) DESTDIR = ../bin +winrt:include(../winrt.pri) # This is testdata for the tst_qpluginloader test. target.path = $$[QT_INSTALL_TESTS]/tst_qfactoryloader/bin diff --git a/tests/auto/corelib/plugin/qfactoryloader/winrt.pri b/tests/auto/corelib/plugin/qfactoryloader/winrt.pri new file mode 100644 index 0000000000..31602634b2 --- /dev/null +++ b/tests/auto/corelib/plugin/qfactoryloader/winrt.pri @@ -0,0 +1,9 @@ +# We cannot use TESTDATA as plugins have to reside physically +# inside the package directory +winrt { + CONFIG(debug, debug|release) { + DESTDIR = ../debug/bin + } else { + DESTDIR = ../release/bin + } +} diff --git a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp index d1c5ee92cb..ed41ab51e1 100644 --- a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp +++ b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp @@ -134,9 +134,11 @@ typedef int (*VersionFunction)(void); void tst_QLibrary::initTestCase() { +#ifndef Q_OS_WINRT // chdir to our testdata directory, and use relative paths in some tests. QString testdatadir = QFileInfo(QFINDTESTDATA("library_path")).absolutePath(); QVERIFY2(QDir::setCurrent(testdatadir), qPrintable("Could not chdir to " + testdatadir)); +#endif } void tst_QLibrary::version_data() @@ -412,7 +414,7 @@ void tst_QLibrary::loadHints_data() QString appDir = QCoreApplication::applicationDirPath(); lh |= QLibrary::ResolveAllSymbolsHint; -# if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) +# if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_WINRT) QTest::newRow( "ok01 (with suffix)" ) << appDir + "/mylib.dll" << int(lh) << true; QTest::newRow( "ok02 (with non-standard suffix)" ) << appDir + "/mylib.dl2" << int(lh) << true; QTest::newRow( "ok03 (with many dots)" ) << appDir + "/system.qt.test.mylib.dll" << int(lh) << true; @@ -464,7 +466,7 @@ void tst_QLibrary::fileName_data() QTest::newRow( "ok02" ) << sys_qualifiedLibraryName(QLatin1String("mylib")) << sys_qualifiedLibraryName(QLatin1String("mylib")); -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) #ifndef Q_OS_WINCE QTest::newRow( "ok03" ) << "user32" << "USER32.dll"; diff --git a/tests/auto/corelib/plugin/qpluginloader/lib/lib.pro b/tests/auto/corelib/plugin/qpluginloader/lib/lib.pro index bd6f19cb4f..44b71e6e99 100644 --- a/tests/auto/corelib/plugin/qpluginloader/lib/lib.pro +++ b/tests/auto/corelib/plugin/qpluginloader/lib/lib.pro @@ -4,6 +4,7 @@ CONFIG -= staticlib SOURCES = mylib.c TARGET = tst_qpluginloaderlib DESTDIR = ../bin +winrt:include(../winrt.pri) QT = core win32-msvc: DEFINES += WIN32_MSVC diff --git a/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.pro b/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.pro index 6ec4a8de05..6aa8161699 100644 --- a/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.pro +++ b/tests/auto/corelib/plugin/qpluginloader/theplugin/theplugin.pro @@ -6,6 +6,7 @@ SOURCES = theplugin.cpp #TARGET = $$qtLibraryTarget(theplugin) TARGET = theplugin DESTDIR = ../bin +winrt:include(../winrt.pri) QT = core # This is testdata for the tst_qpluginloader test. diff --git a/tests/auto/corelib/plugin/qpluginloader/winrt.pri b/tests/auto/corelib/plugin/qpluginloader/winrt.pri new file mode 100644 index 0000000000..31602634b2 --- /dev/null +++ b/tests/auto/corelib/plugin/qpluginloader/winrt.pri @@ -0,0 +1,9 @@ +# We cannot use TESTDATA as plugins have to reside physically +# inside the package directory +winrt { + CONFIG(debug, debug|release) { + DESTDIR = ../debug/bin + } else { + DESTDIR = ../release/bin + } +} diff --git a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp index 2e6b1a31cc..e2c137e25f 100644 --- a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp +++ b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp @@ -91,9 +91,11 @@ void tst_QUuid::initTestCase() //"{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"; uuidB = QUuid(0x1ab6e93a, 0xb1cb, 0x4a87, 0xba, 0x47, 0xec, 0x7e, 0x99, 0x03, 0x9a, 0x7b); +#ifndef QT_NO_PROCESS // chdir to the directory containing our testdata, then refer to it with relative paths QString testdata_dir = QFileInfo(QFINDTESTDATA("testProcessUniqueness")).absolutePath(); QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir)); +#endif //"{3d813cbb-47fb-32ba-91df-831e1593ac29}"; http://www.rfc-editor.org/errata_search.php?rfc=4122&eid=1352 uuidC = QUuid(0x3d813cbb, 0x47fb, 0x32ba, 0x91, 0xdf, 0x83, 0x1e, 0x15, 0x93, 0xac, 0x29); diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index 9cadf60afb..ff049b7600 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -1610,8 +1610,14 @@ void tst_QDateTime::daylightSavingsTimeChange_data() { QTest::addColumn<QDate>("inDST"); QTest::addColumn<QDate>("outDST"); - QTest::newRow("Autumn") << QDate(2006, 8, 1) << QDate(2006, 12, 1); - QTest::newRow("Spring") << QDate(2006, 5, 1) << QDate(2006, 2, 1); + QTest::addColumn<int>("days"); // from in to out; -ve if reversed + QTest::addColumn<int>("months"); + + QTest::newRow("Autumn") << QDate(2006, 8, 1) << QDate(2006, 12, 1) + << 122 << 4; + + QTest::newRow("Spring") << QDate(2006, 5, 1) << QDate(2006, 2, 1) + << -89 << -3; } void tst_QDateTime::daylightSavingsTimeChange() @@ -1631,6 +1637,8 @@ void tst_QDateTime::daylightSavingsTimeChange() QFETCH(QDate, inDST); QFETCH(QDate, outDST); + QFETCH(int, days); + QFETCH(int, months); // First with simple construction QDateTime dt = QDateTime(outDST, QTime(0, 0, 0), Qt::LocalTime); @@ -1640,6 +1648,22 @@ void tst_QDateTime::daylightSavingsTimeChange() dt = dt.addSecs(1); QCOMPARE(dt, QDateTime(inDST, QTime(0, 0, 1))); + // now using addDays: + dt = dt.addDays(days).addSecs(1); + QCOMPARE(dt, QDateTime(outDST, QTime(0, 0, 2))); + + // ... and back again: + dt = dt.addDays(-days).addSecs(1); + QCOMPARE(dt, QDateTime(inDST, QTime(0, 0, 3))); + + // now using addMonths: + dt = dt.addMonths(months).addSecs(1); + QCOMPARE(dt, QDateTime(outDST, QTime(0, 0, 4))); + + // ... and back again: + dt = dt.addMonths(-months).addSecs(1); + QCOMPARE(dt, QDateTime(inDST, QTime(0, 0, 5))); + // now using fromTime_t dt = QDateTime::fromTime_t(outDSTsecs); QCOMPARE(dt, QDateTime(outDST, QTime(0, 0, 0))); @@ -1647,6 +1671,44 @@ void tst_QDateTime::daylightSavingsTimeChange() dt.setDate(inDST); dt = dt.addSecs(60); QCOMPARE(dt, QDateTime(inDST, QTime(0, 1, 0))); + + // using addMonths: + dt = dt.addMonths(months).addSecs(60); + QCOMPARE(dt, QDateTime(outDST, QTime(0, 2, 0))); + // back again: + dt = dt.addMonths(-months).addSecs(60); + QCOMPARE(dt, QDateTime(inDST, QTime(0, 3, 0))); + + // using addDays: + dt = dt.addDays(days).addSecs(60); + QCOMPARE(dt, QDateTime(outDST, QTime(0, 4, 0))); + // back again: + dt = dt.addDays(-days).addSecs(60); + QCOMPARE(dt, QDateTime(inDST, QTime(0, 5, 0))); + + // Now use the result of a UTC -> LocalTime conversion + dt = QDateTime(outDST, QTime(0, 0, 0), Qt::LocalTime).toUTC(); + dt = QDateTime(dt.date(), dt.time(), Qt::UTC).toLocalTime(); + QCOMPARE(dt, QDateTime(outDST, QTime(0, 0, 0))); + + // using addDays: + dt = dt.addDays(-days).addSecs(3600); + QCOMPARE(dt, QDateTime(inDST, QTime(1, 0, 0))); + // back again + dt = dt.addDays(days).addSecs(3600); + QCOMPARE(dt, QDateTime(outDST, QTime(2, 0, 0))); + + // using addMonths: + dt = dt.addMonths(-months).addSecs(3600); + QCOMPARE(dt, QDateTime(inDST, QTime(3, 0, 0))); + // back again: + dt = dt.addMonths(months).addSecs(3600); + QCOMPARE(dt, QDateTime(outDST, QTime(4, 0, 0))); + + // using setDate: + dt.setDate(inDST); + dt = dt.addSecs(3600); + QCOMPARE(dt, QDateTime(inDST, QTime(5, 0, 0))); } void tst_QDateTime::springForward_data() @@ -2222,7 +2284,9 @@ void tst_QDateTime::fromStringStringFormat_data() QTest::newRow("data5") << QString("10") << QString("'") << invalidDateTime(); QTest::newRow("data6") << QString("pm") << QString("ap") << QDateTime(defDate(), QTime(12, 0, 0)); QTest::newRow("data7") << QString("foo") << QString("ap") << invalidDateTime(); - QTest::newRow("data8") << QString("101010") << QString("dMyy") << QDateTime(QDate(1910, 10, 10), QTime()); + // Day non-conflict should not hide earlier year conflict (1963-03-01 was a + // Friday; asking for Thursday moves this, without conflict, to the 7th): + QTest::newRow("data8") << QString("77 03 1963 " + thu) << QString("yy MM yyyy ddd") << invalidDateTime(); QTest::newRow("data9") << QString("101010") << QString("dMyy") << QDateTime(QDate(1910, 10, 10), QTime()); QTest::newRow("data10") << QString("101010") << QString("dMyy") << QDateTime(QDate(1910, 10, 10), QTime()); QTest::newRow("data11") << date << QString("dd MMM yy") << QDateTime(QDate(1910, 10, 10), QTime()); diff --git a/tests/auto/dbus/qdbusconnection_no_libdbus/qdbusconnection_no_libdbus.pro b/tests/auto/dbus/qdbusconnection_no_libdbus/qdbusconnection_no_libdbus.pro index cb0eab1a18..d1b27ee8c0 100644 --- a/tests/auto/dbus/qdbusconnection_no_libdbus/qdbusconnection_no_libdbus.pro +++ b/tests/auto/dbus/qdbusconnection_no_libdbus/qdbusconnection_no_libdbus.pro @@ -1,5 +1,5 @@ CONFIG += testcase parallel_test TARGET = tst_qdbusconnection_no_libdbus QT = core dbus testlib -DEFINES += SIMULATE_LOAD_FAIL +DEFINES += SIMULATE_LOAD_FAIL tst_QDBusConnectionNoBus=tst_QDBusConnectionNoLibDBus1 SOURCES += ../qdbusconnection_no_bus/tst_qdbusconnection_no_bus.cpp diff --git a/tests/auto/gui/kernel/kernel.pro b/tests/auto/gui/kernel/kernel.pro index 5254e755d4..5000e1a926 100644 --- a/tests/auto/gui/kernel/kernel.pro +++ b/tests/auto/gui/kernel/kernel.pro @@ -11,6 +11,7 @@ SUBDIRS=\ qguitimer \ qguivariant \ qinputmethod \ + qkeyevent \ qkeysequence \ qmouseevent \ qmouseevent_modal \ diff --git a/tests/auto/gui/kernel/qkeyevent/qkeyevent.pro b/tests/auto/gui/kernel/qkeyevent/qkeyevent.pro new file mode 100644 index 0000000000..c0a5786e27 --- /dev/null +++ b/tests/auto/gui/kernel/qkeyevent/qkeyevent.pro @@ -0,0 +1,4 @@ +CONFIG += testcase +TARGET = tst_qkeyevent +SOURCES += tst_qkeyevent.cpp +QT = core gui testlib diff --git a/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp b/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp new file mode 100644 index 0000000000..bd68400047 --- /dev/null +++ b/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <QtCore/qcoreapplication.h> +#include <QtGui/qevent.h> +#include <QtGui/qwindow.h> + +class Window : public QWindow +{ +public: + ~Window() { reset(); } + + void keyPressEvent(QKeyEvent *event) { recordEvent(event); } + void keyReleaseEvent(QKeyEvent *event) { recordEvent(event); } + + void reset() { + qDeleteAll(keyEvents.begin(), keyEvents.end()); + keyEvents.clear(); + } +private: + void recordEvent(QKeyEvent *event) { + keyEvents.append(new QKeyEvent(event->type(), event->key(), event->modifiers(), event->nativeScanCode(), + event->nativeVirtualKey(), event->nativeModifiers(), event->text(), + event->isAutoRepeat(), event->count())); + } + +public: + QVector<QKeyEvent*> keyEvents; +}; + +class tst_QKeyEvent : public QObject +{ + Q_OBJECT +public: + tst_QKeyEvent(); + ~tst_QKeyEvent(); + +private slots: + void basicEventDelivery(); + void modifiers_data(); + void modifiers(); +}; + +tst_QKeyEvent::tst_QKeyEvent() +{ +} + +tst_QKeyEvent::~tst_QKeyEvent() +{ +} + +void tst_QKeyEvent::basicEventDelivery() +{ + Window window; + window.showNormal(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + const Qt::Key key = Qt::Key_A; + const Qt::KeyboardModifier modifiers = Qt::NoModifier; + + QTest::keyClick(&window, key, modifiers); + + QCOMPARE(window.keyEvents.size(), 2); + QCOMPARE(window.keyEvents.first()->type(), QKeyEvent::KeyPress); + QCOMPARE(window.keyEvents.last()->type(), QKeyEvent::KeyRelease); + foreach (const QKeyEvent *event, window.keyEvents) { + QCOMPARE(Qt::Key(event->key()), key); + QCOMPARE(Qt::KeyboardModifiers(event->modifiers()), modifiers); + } +} + +static bool orderByModifier(const QVector<int> &v1, const QVector<int> &v2) +{ + if (v1.size() != v2.size()) + return v1.size() < v2.size(); + + for (int i = 0; i < qMin(v1.size(), v2.size()); ++i) { + if (v1.at(i) == v2.at(i)) + continue; + + return v1.at(i) < v2.at(i); + } + + return true; +} + +void tst_QKeyEvent::modifiers_data() +{ + struct Modifier + { + Qt::Key key; + Qt::KeyboardModifier modifier; + }; + static const Modifier modifiers[] = { + { Qt::Key_Shift, Qt::ShiftModifier }, + { Qt::Key_Control, Qt::ControlModifier }, + { Qt::Key_Alt, Qt::AltModifier }, + { Qt::Key_Meta, Qt::MetaModifier }, + }; + + QVector<QVector<int>> modifierCombinations; + + // Generate powerset (minus the empty set) of possible modifier combinations + static const int kNumModifiers = sizeof(modifiers) / sizeof(Modifier); + for (quint64 bitmask = 1; bitmask < (1 << kNumModifiers) ; ++bitmask) { + QVector<int> modifierCombination; + for (quint64 modifier = 0; modifier < kNumModifiers; ++modifier) { + if (bitmask & (1 << modifier)) + modifierCombination.append(modifier); + } + modifierCombinations.append(modifierCombination); + } + + qSort(modifierCombinations.begin(), modifierCombinations.end(), orderByModifier); + + QTest::addColumn<Qt::KeyboardModifiers>("modifiers"); + foreach (const QVector<int> combination, modifierCombinations) { + int keys[4] = {}; + Qt::KeyboardModifiers mods; + for (int i = 0; i < combination.size(); ++i) { + Modifier modifier = modifiers[combination.at(i)]; + keys[i] = modifier.key; + mods |= modifier.modifier; + } + QKeySequence keySequence(keys[0], keys[1], keys[2], keys[3]); + QTest::newRow(keySequence.toString(QKeySequence::NativeText).toUtf8().constData()) << mods; + } +} + +void tst_QKeyEvent::modifiers() +{ + Window window; + window.showNormal(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + const Qt::Key key = Qt::Key_A; + QFETCH(Qt::KeyboardModifiers, modifiers); + + QTest::keyClick(&window, key, modifiers); + + int numKeys = qPopulationCount(quint64(modifiers)) + 1; + QCOMPARE(window.keyEvents.size(), numKeys * 2); + + for (int i = 0; i < window.keyEvents.size(); ++i) { + const QKeyEvent *event = window.keyEvents.at(i); + QCOMPARE(event->type(), i < numKeys ? QKeyEvent::KeyPress : QKeyEvent::KeyRelease); + if (i == numKeys - 1 || i == numKeys) { + QCOMPARE(Qt::Key(event->key()), key); + QCOMPARE(event->modifiers(), modifiers); + } else { + QVERIFY(Qt::Key(event->key()) != key); + } + } +} + +QTEST_MAIN(tst_QKeyEvent) +#include "tst_qkeyevent.moc" diff --git a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp index cde9f95612..0d0b6ae81e 100644 --- a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp +++ b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp @@ -31,7 +31,6 @@ #include <qkeysequence.h> #include <qpa/qplatformtheme.h> #include <qpa/qplatformtheme_p.h> -#include <private/qkeysequence_p.h> #include <private/qguiapplication_p.h> #include <QTranslator> #include <QLibraryInfo> diff --git a/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp b/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp index 9a25eb353d..27796cda51 100644 --- a/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp +++ b/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp @@ -43,6 +43,9 @@ public: virtual ~tst_QFontCache(); private slots: + void engineData_data(); + void engineData(); + void clear(); }; @@ -64,6 +67,52 @@ tst_QFontCache::~tst_QFontCache() { } +void tst_QFontCache::engineData_data() +{ + QTest::addColumn<QString>("family"); + QTest::addColumn<QString>("cacheKey"); + + QTest::newRow("unquoted-family-name") << QString("Times New Roman") << QString("Times New Roman"); + QTest::newRow("quoted-family-name") << QString("'Times New Roman'") << QString("Times New Roman"); + QTest::newRow("invalid") << QString("invalid") << QString("invalid"); + QTest::newRow("multiple") << QString("invalid, Times New Roman") << QString("invalid,Times New Roman"); + QTest::newRow("multiple spaces") << QString("invalid, Times New Roman ") << QString("invalid,Times New Roman"); + QTest::newRow("multiple spaces quotes") << QString("'invalid', Times New Roman ") << QString("invalid,Times New Roman"); + QTest::newRow("multiple2") << QString("invalid, Times New Roman , foobar, 'baz'") << QString("invalid,Times New Roman,foobar,baz"); + QTest::newRow("invalid spaces") << QString("invalid spaces, Times New Roman ") << QString("invalid spaces,Times New Roman"); + QTest::newRow("invalid spaces quotes") << QString("'invalid spaces', 'Times New Roman' ") << QString("invalid spaces,Times New Roman"); +} + +void tst_QFontCache::engineData() +{ + QFETCH(QString, family); + QFETCH(QString, cacheKey); + + QFont f(family); + f.exactMatch(); // loads engine + + QFontPrivate *d = QFontPrivate::get(f); + + QFontDef req = d->request; + // copy-pasted from QFontDatabase::load(), to engineer the cache key + if (req.pixelSize == -1) { + req.pixelSize = std::floor(((req.pointSize * d->dpi) / 72) * 100 + 0.5) / 100; + req.pixelSize = qRound(req.pixelSize); + } + if (req.pointSize < 0) + req.pointSize = req.pixelSize*72.0/d->dpi; + if (req.weight == 0) + req.weight = QFont::Normal; + if (req.stretch == 0) + req.stretch = 100; + + req.family = cacheKey; + + QFontEngineData *engineData = QFontCache::instance()->findEngineData(req); + + QCOMPARE(engineData, QFontPrivate::get(f)->engineData); +} + void tst_QFontCache::clear() { #ifdef QT_BUILD_INTERNAL @@ -105,7 +154,7 @@ void tst_QFontCache::clear() fontEngine->ref.ref(); // cache the engine once again; there is a special case when the engine is cached more than once - QFontCache::instance()->insertEngine(QFontCache::Key(QFontDef(), 0, 0), fontEngine); + QFontCache::instance()->insertEngine(QFontCache::Key(QFontDef(), 0, 1), fontEngine); } // use it: diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp index e6d31b8770..bd8fbcca0e 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp @@ -141,6 +141,7 @@ private slots: void mysql_multiselect(); // For task 144331 void mysql_savepointtest_data() { generic_data("QMYSQL"); } void mysql_savepointtest(); + void mysql_connectWithInvalidAddress(); void accessOdbc_strings_data() { generic_data(); } void accessOdbc_strings(); @@ -2187,6 +2188,14 @@ void tst_QSqlDatabase::mysql_savepointtest() QVERIFY_SQL(q, exec("savepoint foo")); } +void tst_QSqlDatabase::mysql_connectWithInvalidAddress() +{ + // Ensure that giving invalid connection parameters fails correctly + QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); + db.setHostName("invalid.local"); + QCOMPARE(db.open(), false); +} + void tst_QSqlDatabase::oci_tables() { QSKIP("Requires specific permissions to create a system table"); diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 24f9471a92..afee548c9b 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -256,9 +256,7 @@ private slots: #endif void raise(); void lower(); -#ifndef QT_MAC_USE_COCOA void stackUnder(); -#endif void testContentsPropagation(); void saveRestoreGeometry(); void restoreVersion1Geometry_data(); @@ -315,9 +313,7 @@ private slots: void moveChild(); void showAndMoveChild(); -#ifndef QT_MAC_USE_COCOA void subtractOpaqueSiblings(); -#endif #if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) void setGeometry_win(); diff --git a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp index 3178b31e06..406b21ccf6 100644 --- a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp +++ b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp @@ -76,6 +76,7 @@ private slots: void testActivation(); void testAncestorChange(); void testDockWidget(); + void testNativeContainerParent(); void cleanup(); private: @@ -325,6 +326,23 @@ void tst_QWindowContainer::testDockWidget() QTRY_COMPARE(window->parent(), mainWindow.window()->windowHandle()); } +void tst_QWindowContainer::testNativeContainerParent() +{ + QWidget root; + root.setWindowTitle(QTest::currentTestFunction()); + root.setGeometry(m_availableGeometry.x() + 50, m_availableGeometry.y() + 50, 200, 200); + + Window *window = new Window(); + QWidget *container = QWidget::createWindowContainer(window, &root); + container->setAttribute(Qt::WA_NativeWindow); + container->setGeometry(50, 50, 150, 150); + + root.show(); + + QVERIFY(QTest::qWaitForWindowExposed(window)); + QTRY_COMPARE(window->parent(), container->windowHandle()); +} + QTEST_MAIN(tst_QWindowContainer) #include "tst_qwindowcontainer.moc" diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp index baa1628714..cb55bd32b0 100644 --- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp @@ -70,6 +70,7 @@ private slots: void titleBarDoubleClick(); void restoreStateOfFloating(); void restoreDockWidget(); + void restoreStateWhileStillFloating(); // task specific tests: void task165177_deleteFocusWidget(); void task169808_setFloating(); @@ -752,6 +753,31 @@ void tst_QDockWidget::restoreStateOfFloating() QVERIFY(!dock->isFloating()); } +void tst_QDockWidget::restoreStateWhileStillFloating() +{ + // When the dock widget is already floating then it takes a different code path + // so this test covers the case where the restoreState() is effectively just + // moving it back and resizing it + const QRect availGeom = QApplication::desktop()->availableGeometry(); + const QPoint startingDockPos = availGeom.center(); + QMainWindow mw; + QDockWidget *dock = createTestDock(mw); + mw.addDockWidget(Qt::TopDockWidgetArea, dock); + dock->setFloating(true); + dock->move(startingDockPos); + mw.show(); + QVERIFY(QTest::qWaitForWindowExposed(&mw)); + QVERIFY(dock->isFloating()); + QByteArray ba = mw.saveState(); + const QPoint dockPos = dock->pos(); + dock->move(availGeom.topLeft() + QPoint(10, 10)); + dock->resize(dock->size() + QSize(10, 10)); + QVERIFY(mw.restoreState(ba)); + QVERIFY(dock->isFloating()); + if (!QGuiApplication::platformName().compare("xcb", Qt::CaseInsensitive)) + QTRY_COMPARE(dock->pos(), dockPos); +} + void tst_QDockWidget::restoreDockWidget() { QByteArray geometry; diff --git a/tests/manual/diaglib/qwidgetdump.cpp b/tests/manual/diaglib/qwidgetdump.cpp index 4b5b2342e6..0ccf109ebb 100644 --- a/tests/manual/diaglib/qwidgetdump.cpp +++ b/tests/manual/diaglib/qwidgetdump.cpp @@ -56,10 +56,32 @@ static void dumpWidgetRecursion(QTextStream &str, const QWidget *w, if (const int states = w->windowState()) str << "windowState=" << hex << showbase << states << dec << noshowbase << ' '; formatRect(str, w->geometry()); + if (w->isWindow()) { + const QRect normalGeometry = w->normalGeometry(); + if (normalGeometry.isValid() && !normalGeometry.isEmpty() && normalGeometry != w->geometry()) { + str << " normal="; + formatRect(str, w->normalGeometry()); + } + } if (!(options & DontPrintWindowFlags)) { str << ' '; formatWindowFlags(str, w->windowFlags()); } + if (options & PrintSizeConstraints) { + str << ' '; + const QSize minimumSize = w->minimumSize(); + if (minimumSize.width() > 0 || minimumSize.height() > 0) + str << "minimumSize=" << minimumSize.width() << 'x' << minimumSize.height() << ' '; + const QSize sizeHint = w->sizeHint(); + const QSize minimumSizeHint = w->minimumSizeHint(); + if (minimumSizeHint.isValid() && !(sizeHint.isValid() && minimumSizeHint == sizeHint)) + str << "minimumSizeHint=" << minimumSizeHint.width() << 'x' << minimumSizeHint.height() << ' '; + if (sizeHint.isValid()) + str << "sizeHint=" << sizeHint.width() << 'x' << sizeHint.height() << ' '; + const QSize maximumSize = w->maximumSize(); + if (maximumSize.width() < QWIDGETSIZE_MAX || maximumSize.height() < QWIDGETSIZE_MAX) + str << "maximumSize=" << maximumSize.width() << 'x' << maximumSize.height() << ' '; + } str << '\n'; #if QT_VERSION > 0x050000 if (const QWindow *win = w->windowHandle()) { @@ -74,12 +96,17 @@ static void dumpWidgetRecursion(QTextStream &str, const QWidget *w, } } -void dumpAllWidgets(FormatWindowOptions options) +void dumpAllWidgets(FormatWindowOptions options, const QWidget *root) { QString d; QTextStream str(&d); str << "### QWidgets:\n"; - foreach (QWidget *tw, QApplication::topLevelWidgets()) + QWidgetList topLevels; + if (root) + topLevels.append(const_cast<QWidget *>(root)); + else + topLevels = QApplication::topLevelWidgets(); + foreach (QWidget *tw, topLevels) dumpWidgetRecursion(str, tw, options); #if QT_VERSION >= 0x050400 qDebug().noquote() << d; diff --git a/tests/manual/diaglib/qwidgetdump.h b/tests/manual/diaglib/qwidgetdump.h index 961f26a2f5..f3eb1fda8d 100644 --- a/tests/manual/diaglib/qwidgetdump.h +++ b/tests/manual/diaglib/qwidgetdump.h @@ -31,9 +31,11 @@ #include "qwindowdump.h" +QT_FORWARD_DECLARE_CLASS(QWidget) + namespace QtDiag { -void dumpAllWidgets(FormatWindowOptions options = 0); +void dumpAllWidgets(FormatWindowOptions options = 0, const QWidget *root = 0); } // namespace QtDiag diff --git a/tests/manual/diaglib/qwindowdump.cpp b/tests/manual/diaglib/qwindowdump.cpp index 5e245bcdc7..19c9ca30e9 100644 --- a/tests/manual/diaglib/qwindowdump.cpp +++ b/tests/manual/diaglib/qwindowdump.cpp @@ -33,6 +33,7 @@ # include <QtGui/QScreen> # include <QtGui/QWindow> # include <qpa/qplatformwindow.h> +# include <private/qwindow_p.h> # if QT_VERSION >= 0x050600 # include <private/qhighdpiscaling_p.h> # endif @@ -146,6 +147,15 @@ void formatWindow(QTextStream &str, const QWindow *w, FormatWindowOptions option str << ' '; formatWindowFlags(str, w->flags()); } + if (options & PrintSizeConstraints) { + str << ' '; + const QSize minimumSize = w->minimumSize(); + if (minimumSize.width() > 0 || minimumSize.height() > 0) + str << "minimumSize=" << minimumSize.width() << 'x' << minimumSize.height() << ' '; + const QSize maximumSize = w->maximumSize(); + if (maximumSize.width() < QWINDOWSIZE_MAX || maximumSize.height() < QWINDOWSIZE_MAX) + str << "maximumSize=" << maximumSize.width() << 'x' << maximumSize.height() << ' '; + } str << '\n'; } diff --git a/tests/manual/diaglib/qwindowdump.h b/tests/manual/diaglib/qwindowdump.h index 385f624f10..74f976567a 100644 --- a/tests/manual/diaglib/qwindowdump.h +++ b/tests/manual/diaglib/qwindowdump.h @@ -39,7 +39,8 @@ QT_FORWARD_DECLARE_CLASS(QTextStream) namespace QtDiag { enum FormatWindowOption { - DontPrintWindowFlags = 0x001 + DontPrintWindowFlags = 0x001, + PrintSizeConstraints = 0x002 }; Q_DECLARE_FLAGS(FormatWindowOptions, FormatWindowOption) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index ad20819701..871251df2e 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1099,7 +1099,7 @@ void Configure::parseCmdLine() if (i == argCount) break; QString mod = configCmdLine.at(i); - if (!mod.startsWith(QStringLiteral("qt"))) + if (!mod.startsWith(QLatin1String("qt"))) mod.insert(0, QStringLiteral("qt")); if (!QFileInfo(sourcePath + "/../" + mod).isDir()) { cout << "Attempting to skip non-existent module " << mod << "." << endl; @@ -3850,7 +3850,7 @@ void Configure::displayConfig() env = "Unset"; sout << " PATH=\n " << env << endl; - if (dictionary[QStringLiteral("EDITION")] != QStringLiteral("OpenSource")) { + if (dictionary[QStringLiteral("EDITION")] != QLatin1String("OpenSource")) { QString l1 = dictionary[ "LICENSEE" ]; QString l2 = dictionary[ "LICENSEID" ]; QString l3 = dictionary["EDITION"] + ' ' + "Edition"; diff --git a/util/glgen/codegenerator.cpp b/util/glgen/codegenerator.cpp index e06fe7e2f2..70cd3a7931 100644 --- a/util/glgen/codegenerator.cpp +++ b/util/glgen/codegenerator.cpp @@ -384,11 +384,11 @@ QString CodeGenerator::passByType(const Argument &arg) const QString CodeGenerator::safeArgumentName(const QString& arg) const { - if (arg == QStringLiteral("near")) // MS Windows defines near and far + if (arg == QLatin1String("near")) // MS Windows defines near and far return QStringLiteral("nearVal"); - else if (arg == QStringLiteral("far")) + else if (arg == QLatin1String("far")) return QStringLiteral("farVal"); - else if (arg == QStringLiteral("d")) + else if (arg == QLatin1String("d")) return QStringLiteral("dd"); // Don't shadow d pointer else return arg; @@ -805,7 +805,7 @@ void CodeGenerator::writeInlineFunction(QTextStream &stream, const QString &clas argumentNames.append(safeArgumentName(arg.name)); QString argNames = argumentNames.join(", "); - if (f.returnType == QStringLiteral("void")) + if (f.returnType == QLatin1String("void")) stream << QString(QStringLiteral(" %1->%2(%3);")).arg(backendVar).arg(f.name).arg(argNames) << endl; else stream << QString(QStringLiteral(" return %1->%2(%3);")).arg(backendVar).arg(f.name).arg(argNames) << endl; diff --git a/util/glgen/legacyspecparser.cpp b/util/glgen/legacyspecparser.cpp index af8ceffd7f..0f4d085bba 100644 --- a/util/glgen/legacyspecparser.cpp +++ b/util/glgen/legacyspecparser.cpp @@ -75,7 +75,7 @@ bool LegacySpecParser::parseTypeMap() while (!stream.atEnd()) { QString line = stream.readLine(); - if (line.startsWith(QStringLiteral("#"))) + if (line.startsWith(QLatin1Char('#'))) continue; if (typeMapRegExp.indexIn(line) != -1) { @@ -83,7 +83,7 @@ bool LegacySpecParser::parseTypeMap() QString value = typeMapRegExp.cap(2).simplified(); // Special case for void - if (value == QStringLiteral("*")) + if (value == QLatin1String("*")) value = QStringLiteral("void"); m_typeMap.insert(key, value); @@ -139,7 +139,7 @@ void LegacySpecParser::parseFunctions(QTextStream &stream) // extension. These functions should be added to the DSA extension rather // than the core functionality. The core will already contain non-DSA // versions of these functions. - if (acceptCurrentFunctionInCore && currentFunction.name.endsWith(QStringLiteral("EXT"))) { + if (acceptCurrentFunctionInCore && currentFunction.name.endsWith(QLatin1String("EXT"))) { acceptCurrentFunctionInCore = false; acceptCurrentFunctionInExtension = true; currentCategory = QStringLiteral("EXT_direct_state_access"); @@ -186,9 +186,9 @@ void LegacySpecParser::parseFunctions(QTextStream &stream) arg.type = m_typeMap.value(type); QString direction = argumentRegExp.cap(3); - if (direction == QStringLiteral("in")) { + if (direction == QLatin1String("in")) { arg.direction = Argument::In; - } else if (direction == QStringLiteral("out")) { + } else if (direction == QLatin1String("out")) { arg.direction = Argument::Out; } else { qWarning() << "Invalid argument direction found:" << direction; @@ -196,11 +196,11 @@ void LegacySpecParser::parseFunctions(QTextStream &stream) } QString mode = argumentRegExp.cap(4); - if (mode == QStringLiteral("value")) { + if (mode == QLatin1String("value")) { arg.mode = Argument::Value; - } else if (mode == QStringLiteral("array")) { + } else if (mode == QLatin1String("array")) { arg.mode = Argument::Array; - } else if (mode == QStringLiteral("reference")) { + } else if (mode == QLatin1String("reference")) { arg.mode = Argument::Reference; } else { qWarning() << "Invalid argument mode found:" << mode; @@ -241,7 +241,7 @@ void LegacySpecParser::parseFunctions(QTextStream &stream) // Extract the OpenGL version in which this function was deprecated. // If it is OpenGL 3.1 then it must be a compatibility profile function QString deprecatedVersion = deprecatedRegExp.cap(1).simplified(); - if (deprecatedVersion == QStringLiteral("3.1") && !inDeprecationException(currentFunction.name)) + if (deprecatedVersion == QLatin1String("3.1") && !inDeprecationException(currentFunction.name)) currentVersionProfile.profile = VersionProfile::CompatibilityProfile; } else if (categoryRegExp.indexIn(line) != -1) { @@ -296,5 +296,5 @@ void LegacySpecParser::parseFunctions(QTextStream &stream) bool LegacySpecParser::inDeprecationException(const QString &functionName) const { - return (functionName == QStringLiteral("TexImage3D")); + return functionName == QLatin1String("TexImage3D"); } |