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/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 += \ " \n" \ "\n" \ "\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 = \ "\n" \ "
\n" \ "

\n" \ - " © 2015 The Qt Company Ltd.\n" \ + " © 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/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 = \ "

\n" \ "

\n" \ - " © 2015 The Qt Company Ltd.\n" \ + " © 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/desktop/systray/doc/src/systray.qdoc b/examples/widgets/desktop/systray/doc/src/systray.qdoc index fa2dbb2721..ae6df351bb 100644 --- a/examples/widgets/desktop/systray/doc/src/systray.qdoc +++ b/examples/widgets/desktop/systray/doc/src/systray.qdoc @@ -28,9 +28,8 @@ /*! \example desktop/systray \title System Tray Icon Example - - - The System Tray Icon example shows how to add an icon with a menu + \ingroup examples-widgets + \brief The System Tray Icon example shows how to add an icon with a menu and popup messages to a desktop environment's system tray. \image systemtray-example.png Screenshot of the System Tray Icon. @@ -47,7 +46,7 @@ The editor allows the user to choose the preferred icon as well as set the balloon message's type and duration. The user can also - edit the message's title and body. Finally, the editor provide a + edit the message's title and body. Finally, the editor provides a checkbox controlling whether the icon is actually shown in the system tray, or not. @@ -65,8 +64,8 @@ check whether a system tray is present on the user's desktop, call the static QSystemTrayIcon::isSystemTrayAvailable() function. Associated with the icon, we provide a menu containing - the typical \gui minimize, \gui maximize, \gui restore and \gui - quit actions. We reimplement the QWidget::setVisible() function to + the typical \uicontrol minimize, \uicontrol maximize, \uicontrol restore and + \uicontrol quit actions. We reimplement the QWidget::setVisible() function to update the tray icon's menu whenever the editor's appearance changes, e.g., when maximizing or minimizing the main application window. @@ -74,7 +73,7 @@ Finally, we reimplement QWidget's \l {QWidget::}{closeEvent()} function to be able to inform the user (when closing the editor window) that the program will keep running in the system tray - until the user chooses the \gui Quit entry in the icon's context + until the user chooses the \uicontrol Quit entry in the icon's context menu. \section1 Window Class Implementation diff --git a/examples/widgets/doc/src/fridgemagnets.qdoc b/examples/widgets/doc/src/fridgemagnets.qdoc index 5e1052b413..bf3343af0e 100644 --- a/examples/widgets/doc/src/fridgemagnets.qdoc +++ b/examples/widgets/doc/src/fridgemagnets.qdoc @@ -28,6 +28,8 @@ /*! \example draganddrop/fridgemagnets \title Fridge Magnets Example + \brief The Fridge Magnets example illustrates how to move around several types of + MIME-encoded data with drag and drop. The Fridge Magnets example shows how to supply more than one type of MIME-encoded data with a drag and drop operation. diff --git a/examples/widgets/doc/src/systray.qdoc b/examples/widgets/doc/src/systray.qdoc deleted file mode 100644 index b05f999dfa..0000000000 --- a/examples/widgets/doc/src/systray.qdoc +++ /dev/null @@ -1,179 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** 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 Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example desktop/systray - \title System Tray Icon Example - \ingroup examples-widgets - \brief The System Tray Icon example shows how to add an icon with a menu - and popup messages to a desktop environment's system tray. - - \image systemtray-example.png Screenshot of the System Tray Icon. - - Modern operating systems usually provide a special area on the - desktop, called the system tray or notification area, where - long-running applications can display icons and short messages. - - This example consists of one single class, \c Window, providing - the main application window (i.e., an editor for the system tray - icon) and the associated icon. - - \image systemtray-editor.png - - The editor allows the user to choose the preferred icon as well as - set the balloon message's type and duration. The user can also - edit the message's title and body. Finally, the editor provides a - checkbox controlling whether the icon is actually shown in the - system tray, or not. - - \section1 Window Class Definition - - The \c Window class inherits QWidget: - - \snippet desktop/systray/window.h 0 - - We implement several private slots to respond to user - interaction. The other private functions are only convenience - functions provided to simplify the constructor. - - The tray icon is an instance of the QSystemTrayIcon class. To - check whether a system tray is present on the user's desktop, call - the static QSystemTrayIcon::isSystemTrayAvailable() - function. Associated with the icon, we provide a menu containing - the typical \uicontrol minimize, \uicontrol maximize, \uicontrol restore and - \uicontrol quit actions. We reimplement the QWidget::setVisible() function - to update the tray icon's menu whenever the editor's appearance - changes, e.g., when maximizing or minimizing the main application - window. - - Finally, we reimplement QWidget's \l {QWidget::}{closeEvent()} - function to be able to inform the user (when closing the editor - window) that the program will keep running in the system tray - until the user chooses the \uicontrol Quit entry in the icon's context - menu. - - \section1 Window Class Implementation - - When constructing the editor widget, we first create the various - editor elements before we create the actual system tray icon: - - \snippet desktop/systray/window.cpp 0 - - We ensure that the application responds to user input by - connecting most of the editor's input widgets (including the - system tray icon) to the application's private slots. But note the - visibility checkbox; its \l {QCheckBox::}{toggled()} signal is - connected to the \e {icon}'s \l {QSystemTrayIcon::}{setVisible()} - function instead. - - \snippet desktop/systray/window.cpp 3 - - The \c setIcon() slot is triggered whenever the current index in - the icon combobox changes, i.e., whenever the user chooses another - icon in the editor. Note that it is also called when the user - activates the tray icon with the left mouse button, triggering the - icon's \l {QSystemTrayIcon::}{activated()} signal. We will come - back to this signal shortly. - - The QSystemTrayIcon::setIcon() function sets the \l - {QSystemTrayIcon::}{icon} property that holds the actual system - tray icon. On Windows, the system tray icon size is 16x16; on X11, - the preferred size is 22x22. The icon will be scaled to the - appropriate size as necessary. - - Note that on X11, due to a limitation in the system tray - specification, mouse clicks on transparent areas in the icon are - propagated to the system tray. If this behavior is unacceptable, - we suggest using an icon with no transparency. - - \snippet desktop/systray/window.cpp 4 - - Whenever the user activates the system tray icon, it emits its \l - {QSystemTrayIcon::}{activated()} signal passing the triggering - reason as parameter. QSystemTrayIcon provides the \l - {QSystemTrayIcon::}{ActivationReason} enum to describe how the - icon was activated. - - In the constructor, we connected our icon's \l - {QSystemTrayIcon::}{activated()} signal to our custom \c - iconActivated() slot: If the user has clicked the icon using the - left mouse button, this function changes the icon image by - incrementing the icon combobox's current index, triggering the \c - setIcon() slot as mentioned above. If the user activates the icon - using the middle mouse button, it calls the custom \c - showMessage() slot: - - \snippet desktop/systray/window.cpp 5 - - When the \e showMessage() slot is triggered, we first retrieve the - message icon depending on the currently chosen message type. The - QSystemTrayIcon::MessageIcon enum describes the icon that is shown - when a balloon message is displayed. Then we call - QSystemTrayIcon's \l {QSystemTrayIcon::}{showMessage()} function - to show the message with the title, body, and icon for the time - specified in milliseconds. - - QSystemTrayIcon also has the corresponding, \l {QSystemTrayIcon::} - {messageClicked()} signal, which is emitted when the user clicks a - message displayed by \l {QSystemTrayIcon::}{showMessage()}. - - \snippet desktop/systray/window.cpp 6 - - In the constructor, we connected the \l - {QSystemTrayIcon::}{messageClicked()} signal to our custom \c - messageClicked() slot that simply displays a message using the - QMessageBox class. - - QMessageBox provides a modal dialog with a short message, an icon, - and buttons laid out depending on the current style. It supports - four severity levels: "Question", "Information", "Warning" and - "Critical". The easiest way to pop up a message box in Qt is to - call one of the associated static functions, e.g., - QMessageBox::information(). - - As we mentioned earlier, we reimplement a couple of QWidget's - virtual functions: - - \snippet desktop/systray/window.cpp 1 - - Our reimplementation of the QWidget::setVisible() function updates - the tray icon's menu whenever the editor's appearance changes, - e.g., when maximizing or minimizing the main application window, - before calling the base class implementation. - - \snippet desktop/systray/window.cpp 2 - - We have reimplemented the QWidget::closeEvent() event handler to - receive widget close events, showing the above message to the - users when they are closing the editor window. - - In addition to the functions and slots discussed above, we have - also implemented several convenience functions to simplify the - constructor: \c createIconGroupBox(), \c createMessageGroupBox(), - \c createActions() and \c createTrayIcon(). See the \l - {desktop/systray/window.cpp}{window.cpp} file for details. -*/ 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. + 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. 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. + 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 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. + 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. + In the constructor we call \c createMenus() to create all the actions and + menus, and set the canvas as the center widget. - Here is the implementation of \c brushColorAct(): + \snippet widgets/tablet/mainwindow.cpp 8 - \snippet widgets/tablet/mainwindow.cpp 1 + 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. - We let the user pick a color with a QColorDialog. If it is valid, - we set a new drawing color with \c setColor(). + 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. - Here is the implementation of \c alphaActionTriggered(): + 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.) + + \snippet widgets/tablet/mainwindow.cpp 9 + + 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 2 - 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. + 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 lineWidthActionTriggered(): + Here is the implementation of \c setBrushColor(): - \snippet widgets/tablet/mainwindow.cpp 3 + \snippet widgets/tablet/mainwindow.cpp 1 - We check which action is selected in \c lineWidthGroup, and set - how the canvas should change the drawing line width. + 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 saturationActionTriggered(): - - \snippet widgets/tablet/mainwindow.cpp 4 - - We check which action is selected in \c colorSaturationGroup, and - set how the canvas should change the color saturation of the - drawing color. - - 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/tools/codecs/doc/src/codecs.qdoc b/examples/widgets/tools/codecs/doc/src/codecs.qdoc index b640d95c38..69bf1470b1 100644 --- a/examples/widgets/tools/codecs/doc/src/codecs.qdoc +++ b/examples/widgets/tools/codecs/doc/src/codecs.qdoc @@ -28,6 +28,7 @@ /*! \example tools/codecs \title Text Codecs Example + \brief How to import and export text using text codecs. The Text Codecs example demonstrates the principles behind importing and exporting text using codecs to ensure that characters are encoded properly, avoiding loss of data 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()); } //! [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()); } //! [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()); } //! [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*))); + connect(colorSaturationGroup, &QActionGroup::triggered, + this, &MainWindow::setSaturationValuator); - 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] + QMenu *helpMenu = menuBar()->addMenu("&Help"); + helpMenu->addAction(tr("A&bout"), this, &MainWindow::about); + helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); } -//! [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); - - helpMenu = menuBar()->addMenu("&Help"); - helpMenu->addAction(aboutAction); - helpMenu->addAction(aboutQtAction); -} -//! [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 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(event)); + m_canvas->setTabletDevice(static_cast(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/examples/xml/dombookmarks/doc/src/dombookmarks.qdoc b/examples/xml/dombookmarks/doc/src/dombookmarks.qdoc index 86d422de80..63e2e93654 100644 --- a/examples/xml/dombookmarks/doc/src/dombookmarks.qdoc +++ b/examples/xml/dombookmarks/doc/src/dombookmarks.qdoc @@ -29,6 +29,7 @@ \example dombookmarks \title DOM Bookmarks Example \ingroup xml-examples + \brief Provides a reader for XML Bookmark Exchange Language files The DOM Bookmarks example provides a reader for XML Bookmark Exchange Language (XBEL) files that uses Qt's DOM-based XML API to read and parse the files. The SAX Bookmarks diff --git a/examples/xml/xmlstreamlint/doc/src/xmlstreamlint.qdoc b/examples/xml/xmlstreamlint/doc/src/xmlstreamlint.qdoc index 48e6fe0734..d13708cb60 100644 --- a/examples/xml/xmlstreamlint/doc/src/xmlstreamlint.qdoc +++ b/examples/xml/xmlstreamlint/doc/src/xmlstreamlint.qdoc @@ -29,6 +29,8 @@ \example xmlstreamlint \title XML Stream Lint Example \ingroup xml-examples + \brief A commandline tool reading from an input file and writing to + the standard output file. The XML Stream Lint example provides a simple command line utility that accepts a file name as its single argument and writes it to the standard 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\"> - $${WINRT_MANIFEST.dependencies} + $${WINRT_MANIFEST.dependencies} 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/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index dd5a7b4fec..ac77de0bab 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -42,6 +42,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.graphics.drawable.ColorDrawable; +import android.graphics.Rect; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.os.Build; @@ -67,7 +68,6 @@ import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.view.ViewTreeObserver; -import android.graphics.Rect; import java.io.BufferedReader; import java.io.DataOutputStream; @@ -125,6 +125,9 @@ public class QtActivityDelegate private boolean m_keyboardIsVisible = false; public boolean m_backKeyPressedSent = false; private long m_showHideTimeStamp = System.nanoTime(); + private int m_portraitKeyboardHeight = 0; + private int m_landscapeKeyboardHeight = 0; + private int m_probeKeyboardHeightDelay = 50; // ms public void setFullScreen(boolean enterFullScreen) { @@ -247,19 +250,26 @@ public class QtActivityDelegate }, 5); } - public void showSoftwareKeyboard(int x, int y, int width, int height, int inputHints, int enterKeyType) + public void showSoftwareKeyboard(final int x, final int y, final int width, final int height, final int inputHints, final int enterKeyType) { if (m_imm == null) return; + DisplayMetrics metrics = new DisplayMetrics(); + m_activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); + + // If the screen is in portrait mode than we estimate that keyboard height will not be higher than 2/5 of the screen. + // else than we estimate that keyboard height will not be higher than 2/3 of the screen + final int visibleHeight; + if (metrics.widthPixels < metrics.heightPixels) + visibleHeight = m_portraitKeyboardHeight != 0 ? m_portraitKeyboardHeight : metrics.heightPixels * 3 / 5; + else + visibleHeight = m_landscapeKeyboardHeight != 0 ? m_landscapeKeyboardHeight : metrics.heightPixels / 3; + if (m_softInputMode != 0) { m_activity.getWindow().setSoftInputMode(m_softInputMode); - // softInputIsHidden is true if SOFT_INPUT_STATE_HIDDEN or SOFT_INPUT_STATE_ALWAYS_HIDDEN is set. - final boolean softInputIsHidden = (m_softInputMode & WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) != 0; - if (softInputIsHidden) - return; } else { - if (height > m_layout.getHeight() * 2 / 3) + if (height > visibleHeight) m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); else m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); @@ -366,6 +376,38 @@ public class QtActivityDelegate //FALLTHROUGH case InputMethodManager.RESULT_UNCHANGED_SHOWN: setKeyboardVisibility(true, System.nanoTime()); + if (m_softInputMode == 0) { + // probe for real keyboard height + m_layout.postDelayed(new Runnable() { + @Override + public void run() { + if (!m_keyboardIsVisible) + return; + DisplayMetrics metrics = new DisplayMetrics(); + m_activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); + Rect r = new Rect(); + m_activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r); + if (metrics.heightPixels != r.bottom) { + if (metrics.widthPixels > metrics.heightPixels) { // landscape + if (m_landscapeKeyboardHeight != r.bottom) { + m_landscapeKeyboardHeight = r.bottom; + showSoftwareKeyboard(x, y, width, height, inputHints, enterKeyType); + } + } else { + if (m_portraitKeyboardHeight != r.bottom) { + m_portraitKeyboardHeight = r.bottom; + showSoftwareKeyboard(x, y, width, height, inputHints, enterKeyType); + } + } + } else { + // no luck ? + // maybe the delay was too short, so let's make it longer + if (m_probeKeyboardHeightDelay < 1000) + m_probeKeyboardHeightDelay *= 2; + } + } + }, m_probeKeyboardHeightDelay); + } break; case InputMethodManager.RESULT_HIDDEN: case InputMethodManager.RESULT_UNCHANGED_HIDDEN: 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 2349ea6db1..14da281a76 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -214,6 +214,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 0cfcc4e659..b0c7c65c1b 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -647,7 +647,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 b2bcbdf727..8d9908cd90 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 ce1684a943..4474fd3f52 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -747,7 +747,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 acacdb8540..050d6879db 100644 --- a/src/corelib/io/qprocess_wince.cpp +++ b/src/corelib/io/qprocess_wince.cpp @@ -33,7 +33,6 @@ #include "qprocess.h" #include "qprocess_p.h" -#include "qwindowspipewriter_p.h" #include #include @@ -156,7 +155,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 ed1c14ad8a..73d49cbc25 100644 --- a/src/corelib/io/qstandardpaths_win.cpp +++ b/src/corelib/io/qstandardpaths_win.cpp @@ -41,9 +41,7 @@ #include #endif -#if !defined(Q_OS_WINCE) const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } }; -#endif #include #include @@ -64,113 +62,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; + return type == QStandardPaths::GenericConfigLocation || type == QStandardPaths::GenericDataLocation; +} + +static inline bool isConfigLocation(QStandardPaths::StandardLocation type) +{ + return type == QStandardPaths::ConfigLocation || type == QStandardPaths::AppConfigLocation + || type == QStandardPaths::AppDataLocation || type == QStandardPaths::AppLocalDataLocation + || isGenericConfigLocation(type); +} + +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 } +static inline QString displayName(QStandardPaths::StandardLocation type) +{ +#ifndef QT_BOOTSTRAPPED + return QStandardPaths::displayName(type); +#else + return QString::number(type); +#endif +} + +static inline void appendTestMode(QString &path) +{ + if (QStandardPaths::isTestModeEnabled()) + path += QLatin1String("/qttest"); +} + +// 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); + } + } + return result; +} + +// 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(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; +} + QString QStandardPaths::writableLocation(StandardLocation type) { QString result; - -#if !defined(Q_OS_WINCE) - static GetKnownFolderPath SHGetKnownFolderPath = (GetKnownFolderPath)QSystemLibrary::resolve(QLatin1String("shell32"), "SHGetKnownFolderPath"); -#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"); -#ifndef QT_BOOTSTRAPPED - if (type != GenericDataLocation && type != GenericConfigLocation) { - if (!QCoreApplication::organizationName().isEmpty()) - result += QLatin1Char('/') + QCoreApplication::organizationName(); - if (!QCoreApplication::applicationName().isEmpty()) - result += QLatin1Char('/') + QCoreApplication::applicationName(); - } -#endif - break; - - case DesktopLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_DESKTOPDIRECTORY, FALSE)) - result = convertCharArray(path); - break; - 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; - } -#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; - - case MoviesLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_MYVIDEO, FALSE)) - result = convertCharArray(path); - break; - - case PicturesLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_MYPICTURES, FALSE)) - result = convertCharArray(path); + 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: @@ -180,6 +217,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; } @@ -187,44 +233,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 c225606717..27f937e750 100644 --- a/src/corelib/json/qjsonobject.cpp +++ b/src/corelib/json/qjsonobject.cpp @@ -679,8 +679,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 @@ -886,8 +889,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 5b475f52ae..8535da4a6c 100644 --- a/src/corelib/json/qjsonobject.h +++ b/src/corelib/json/qjsonobject.h @@ -100,7 +100,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; @@ -143,7 +143,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 14c0f803b9..798307f8ab 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -34,6 +34,11 @@ #include +#ifdef Q_OS_OSX +#include +#include +#endif + #include #ifdef Q_OS_IOS @@ -148,5 +153,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 rev_entries(NumEntries); + static bool mustInit = true; + if (mustInit){ + mustInit = false; + for (int i=0; i::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 16156d0f2c..e79f310163 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -137,6 +137,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 e6d745bb74..dc6e3737b6 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1698,8 +1698,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 0dd0e64977..60873b5616 100644 --- a/src/corelib/kernel/qtcore_eval.cpp +++ b/src/corelib/kernel/qtcore_eval.cpp @@ -47,7 +47,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" @@ -57,7 +57,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 ea96cc64c4..7e159ec1d1 100644 --- a/src/corelib/statemachine/qfinalstate.cpp +++ b/src/corelib/statemachine/qfinalstate.cpp @@ -31,12 +31,10 @@ ** ****************************************************************************/ -#include "qfinalstate.h" +#include "qfinalstate_p.h" #ifndef QT_NO_STATEMACHINE -#include "qabstractstate_p.h" - QT_BEGIN_NAMESPACE /*! @@ -76,19 +74,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. */ @@ -97,6 +92,15 @@ QFinalState::QFinalState(QState *parent) { } +/*! + \internal + */ +QFinalState::QFinalState(QFinalStatePrivate &dd, QState *parent) + : QAbstractState(dd, parent) +{ +} + + /*! Destroys this final state. */ diff --git a/src/corelib/statemachine/qfinalstate.h b/src/corelib/statemachine/qfinalstate.h index 2c76e7b6e6..74f73d559c 100644 --- a/src/corelib/statemachine/qfinalstate.h +++ b/src/corelib/statemachine/qfinalstate.h @@ -38,7 +38,6 @@ QT_BEGIN_NAMESPACE - #ifndef QT_NO_STATEMACHINE class QFinalStatePrivate; @@ -55,6 +54,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 3b84230cb2..cad524c720 100644 --- a/src/corelib/statemachine/qstate.cpp +++ b/src/corelib/statemachine/qstate.cpp @@ -31,11 +31,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 3b8dae9499..938822bcda 100644 --- a/src/corelib/statemachine/qstate_p.h +++ b/src/corelib/statemachine/qstate_p.h @@ -45,6 +45,7 @@ // We mean it. // +#include "qstate.h" #include "private/qabstractstate_p.h" #include @@ -52,6 +53,8 @@ #include #include +#ifndef QT_NO_STATEMACHINE + QT_BEGIN_NAMESPACE #ifndef QT_NO_PROPERTIES @@ -83,7 +86,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: @@ -115,4 +118,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/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 9ca2e1ffc0..cf4fcd4929 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -125,14 +125,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; @@ -670,15 +669,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); } @@ -1006,8 +997,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 @@ -1371,9 +1364,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; @@ -1384,7 +1377,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 a1cf8f283f..c96def6046 100644 --- a/src/corelib/tools/qdatetimeparser_p.h +++ b/src/corelib/tools/qdatetimeparser_p.h @@ -87,7 +87,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 3d41aeee18..69bd344f47 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -236,9 +236,9 @@ template <> struct QConcatenable : 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 f0b8f1b441..ebf42b0b06 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -807,7 +807,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!!"); @@ -866,7 +865,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 1a8d263f94..4731e8a240 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -1758,15 +1758,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 7d469dd25e..65d679cdad 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -921,15 +921,10 @@ QList 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() @@ -1058,7 +1053,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(", "))); @@ -1960,6 +1955,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 881d7cc76a..46784f59be 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -140,6 +140,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 3e4c5bae88..a03549634f 100644 --- a/src/gui/kernel/qkeysequence_p.h +++ b/src/gui/kernel/qkeysequence_p.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_SHORTCUT -struct Q_AUTOTEST_EXPORT QKeyBinding +struct QKeyBinding { QKeySequence::StandardKey standardKey; uchar priority; @@ -60,7 +60,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 d17a1f1d5b..a9dcb8bb7d 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -249,8 +249,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); @@ -275,10 +277,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 bc9da5b564..2c5a0c74fc 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -2809,6 +2809,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()); @@ -2829,6 +2833,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 aae84dc988..d606681e52 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -921,23 +921,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; } } @@ -945,13 +950,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); @@ -960,13 +965,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); } } } @@ -979,7 +984,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)); @@ -2635,12 +2640,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; @@ -2681,7 +2688,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 { @@ -2725,13 +2732,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(); } @@ -2740,25 +2755,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 f267b2d147..fc66c4ec4c 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -2290,7 +2290,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 1df9d674e7..06ce10e2f9 100644 --- a/src/network/kernel/qnetworkproxy_libproxy.cpp +++ b/src/network/kernel/qnetworkproxy_libproxy.cpp @@ -121,14 +121,15 @@ QList 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 1dd2b462ed..62f041bc86 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp @@ -49,7 +49,7 @@ QDBusPlatformMenuItem::QDBusPlatformMenuItem(quintptr tag) : m_tag(tag ? tag : reinterpret_cast(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) @@ -146,7 +146,7 @@ QList QDBusPlatformMenuItem::byIds(const QList(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 0293c74fb9..f902ec230b 100644 --- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp +++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp @@ -1961,71 +1961,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"; @@ -2033,9 +2033,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 3b8a85a26b..42037ffb9a 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -1030,17 +1030,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 fc9a3281b8..d550887ba6 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.cpp @@ -214,7 +214,7 @@ void QNetworkManagerInterface::propertiesSwap(QMap 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 @@ -223,7 +223,7 @@ void QNetworkManagerInterface::propertiesSwap(QMap 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); } } @@ -418,7 +418,7 @@ void QNetworkManagerInterfaceDevice::propertiesSwap(QMap map) QMapIterator 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(); QDBusObjectPath path; QStringList paths; @@ -514,9 +514,8 @@ void QNetworkManagerInterfaceDeviceWired::propertiesSwap(QMap 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); } @@ -693,9 +692,8 @@ void QNetworkManagerInterfaceDeviceWireless::propertiesSwap(QMap 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 4126456f90..44f1d7e6ba 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -273,7 +273,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; } @@ -286,7 +286,7 @@ QString TableGenerator::findComposeFile() m_state = UnsupportedLocale; else { QString path = QDir(systemComposeDir()).filePath(table); - if (QFile(path).exists()) + if (QFile::exists(path)) return path; } } @@ -308,7 +308,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 dd9154f8d2..ac37e7bd92 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -356,6 +356,15 @@ namespace QtAndroid return surfaceId; } + void setViewVisibility(jobject view, bool visible) + { + QJNIObjectPrivate::callStaticMethod(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 cdedeb38f8..037a070516 100644 --- a/src/plugins/platforms/android/androidjnimain.h +++ b/src/plugins/platforms/android/androidjnimain.h @@ -62,6 +62,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 315a0faac0..03927dbe5a 100644 --- a/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp @@ -45,10 +45,14 @@ QAndroidPlatformForeignWindow::QAndroidPlatformForeignWindow(QWindow *window) { const WId wId = window->property("_q_foreignWinId").value(); m_view = reinterpret_cast(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); } @@ -84,8 +88,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 8aa7a6b583..80006ae9b8 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.mm +++ b/src/plugins/platforms/cocoa/qcocoadrag.mm @@ -120,7 +120,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")); @@ -130,7 +132,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 b86a17ca12..89f8bc2f6a 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -80,9 +80,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 7bc8d6585b..29a204d579 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -236,143 +236,6 @@ QColor qt_mac_toQColor(CGColorRef color) return qtColor; } -// 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 rev_entries(NumEntries); - static bool mustInit = true; - if (mustInit){ - mustInit = false; - for (int i=0; i::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 a2d7e96d71..9b2fe3cfa3 100644 --- a/src/plugins/platforms/haiku/qhaikuclipboard.cpp +++ b/src/plugins/platforms/haiku/qhaikuclipboard.cpp @@ -86,9 +86,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(data), dataLen)); - } else if (format == QStringLiteral("text/html")) { + } else if (format == QLatin1String("text/html")) { m_systemMimeData->setHtml(QString::fromLocal8Bit(reinterpret_cast(data), dataLen)); } else { m_systemMimeData->setData(format, QByteArray(reinterpret_cast(data), dataLen)); diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index 16079576a2..18e67ff1a3 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -282,30 +282,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(); } - if (!platformCursor && QGuiApplication::primaryScreen()) - platformCursor = QGuiApplication::primaryScreen()->handle()->cursor(); + 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(); + } + QPixmap scaledPixmap = qFuzzyCompare(pixmapScaleFactor, 1.0) + ? pixmap + : pixmap.scaled((QSizeF(pixmap.size()) * pixmapScaleFactor).toSize(), + Qt::KeepAspectRatio, Qt::SmoothTransformation); + scaledPixmap.setDevicePixelRatio(1); - 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; 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); @@ -458,7 +461,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 8a2fbe1f6d..bf42ca190b 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1613,7 +1613,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 30417f7cee..bf62052ee5 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -231,17 +231,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; @@ -351,11 +344,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 171ace5c20..eaaf2820ee 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -1145,7 +1145,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 cac8ec5ecc..7f45b4817a 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -224,6 +224,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 }; @@ -1764,6 +1788,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 abb48034cd..9cedd296e1 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -639,7 +639,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 c6eb5aa66b..f97f570831 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2251,12 +2251,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 3db7b49ba4..2733c3fa60 100644 --- a/src/plugins/printsupport/cocoa/main.cpp +++ b/src/plugins/printsupport/cocoa/main.cpp @@ -49,7 +49,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(QCoreApplication::instance()); if (!app) diff --git a/src/testlib/qtestkeyboard.h b/src/testlib/qtestkeyboard.h index d2b3ef240b..aa117ed7de 100644 --- a/src/testlib/qtestkeyboard.h +++ b/src/testlib/qtestkeyboard.h @@ -69,11 +69,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 2825e0b7a3..51e6b4af4d 100644 --- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp +++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp @@ -67,7 +67,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 b4c23da628..84d82db9a7 100644 --- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp +++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp @@ -48,7 +48,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/qlalr/cppgenerator.cpp b/src/tools/qlalr/cppgenerator.cpp index 3005690e6e..8c292e5106 100644 --- a/src/tools/qlalr/cppgenerator.cpp +++ b/src/tools/qlalr/cppgenerator.cpp @@ -47,7 +47,7 @@ QString CppGenerator::copyrightHeader() const return QLatin1String( "/****************************************************************************\n" "**\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" "** This file is part of the Qt Toolkit.\n" diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp index b72864a157..c300f3ab9c 100644 --- a/src/tools/uic/uic.cpp +++ b/src/tools/uic/uic.cpp @@ -122,13 +122,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 element. diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 06102ec1d6..3f3a6e7c65 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -3400,27 +3400,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 8a48100ea7..8375624f71 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) "

Qt and the Qt logo are trademarks of The Qt Company Ltd.

" "

Qt is The Qt Company Ltd product developed as an open source " "project. See %3 for more information.

" - ).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 d0d74631ab..3e1ee7ca51 100644 --- a/src/widgets/doc/snippets/macmainwindow.mm +++ b/src/widgets/doc/snippets/macmainwindow.mm @@ -39,8 +39,6 @@ #include -#ifdef QT_MAC_USE_COCOA - //![0] SearchWidget::SearchWidget(QWidget *parent) : QMacCocoaViewContainer(0, parent) @@ -76,57 +74,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(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 ac8cd45f9e..1c5c541628 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -1173,8 +1173,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 2c4e4d3125..1ef9e4ef98 100644 --- a/src/widgets/kernel/qaction.cpp +++ b/src/widgets/kernel/qaction.cpp @@ -39,10 +39,10 @@ #include "qapplication.h" #include "qevent.h" #include "qlist.h" -#include "qdebug.h" #include #include #include +#include #define QAPP_CHECK(functionName) \ if (!qApp) { \ @@ -1296,6 +1296,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(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 8ef26b60bf..0eb2c60c70 100644 --- a/src/widgets/kernel/qaction.h +++ b/src/widgets/kernel/qaction.h @@ -203,6 +203,10 @@ private: #endif }; +#ifndef QT_NO_DEBUG_STREAM +Q_WIDGETS_EXPORT QDebug operator<<(QDebug, const QAction *); +#endif + QT_BEGIN_INCLUDE_NAMESPACE #include 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 c08c4eeb32..ce728e0330 100644 --- a/src/widgets/kernel/qshortcut.cpp +++ b/src/widgets/kernel/qshortcut.cpp @@ -329,7 +329,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 3885431b05..e8c4a763ee 100644 --- a/src/widgets/kernel/qwindowcontainer.cpp +++ b/src/widgets/kernel/qwindowcontainer.cpp @@ -84,6 +84,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 ( @@ -147,8 +152,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 083b1d1707..3fa0fc899d 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -398,7 +398,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 35c54f102f..4a5ae6578a 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -1311,8 +1311,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 } @@ -2830,8 +2830,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 } @@ -2844,8 +2844,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 } @@ -2858,8 +2858,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 } @@ -3004,8 +3004,8 @@ bool QComboBox::event(QEvent *event) case QEvent::HoverEnter: case QEvent::HoverLeave: case QEvent::HoverMove: - if (const QHoverEvent *he = static_cast(event)) - d->updateHoverControl(he->pos()); + if (const QHoverEvent *he = static_cast(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 8c79425e44..df26db57ae 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -1944,12 +1944,8 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList 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 ea3e4c4488..744fecb3f3 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -584,7 +584,9 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason if (reason != SelectedFromKeyboard) { if (QMenu *menu = qobject_cast(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 8b29011178..5322a8f3f5 100644 --- a/src/widgets/widgets/qmenu_mac.mm +++ b/src/widgets/widgets/qmenu_mac.mm @@ -98,15 +98,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 0d4c6b25c4..46f903fa1e 100644 --- a/src/widgets/widgets/qscrollbar.cpp +++ b/src/widgets/widgets/qscrollbar.cpp @@ -479,8 +479,8 @@ bool QScrollBar::event(QEvent *event) case QEvent::HoverEnter: case QEvent::HoverLeave: case QEvent::HoverMove: - if (const QHoverEvent *he = static_cast(event)) - d_func()->updateHoverControl(he->pos()); + if (const QHoverEvent *he = static_cast(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 69432761e6..f866fe8bda 100644 --- a/src/widgets/widgets/qtoolbutton.cpp +++ b/src/widgets/widgets/qtoolbutton.cpp @@ -120,7 +120,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 @@ -147,8 +147,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 @@ -820,7 +820,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 @@ -961,8 +961,8 @@ bool QToolButton::event(QEvent *event) case QEvent::HoverEnter: case QEvent::HoverLeave: case QEvent::HoverMove: - if (const QHoverEvent *he = static_cast(event)) - d_func()->updateHoverControl(he->pos()); + if (const QHoverEvent *he = static_cast(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 2496cd2f1e..fbc9f353d9 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 e70ed4fb25..4aa9bd0b95 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 f31a7af6dd..9063ac38de 100644 --- a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp +++ b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp @@ -139,9 +139,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() @@ -417,7 +419,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; @@ -469,7 +471,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 c74a00e9a6..51435b2266 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 2ea9c27cc9..8acd58323c 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 f31aed6976..a40f226d59 100644 --- a/tests/auto/corelib/plugin/quuid/tst_quuid.cpp +++ b/tests/auto/corelib/plugin/quuid/tst_quuid.cpp @@ -94,9 +94,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 d880d907d1..f6f1c05814 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -1614,8 +1614,14 @@ void tst_QDateTime::daylightSavingsTimeChange_data() { QTest::addColumn("inDST"); QTest::addColumn("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("days"); // from in to out; -ve if reversed + QTest::addColumn("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() @@ -1635,6 +1641,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); @@ -1644,6 +1652,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))); @@ -1651,6 +1675,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() @@ -2224,7 +2286,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 + +#include +#include +#include + +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 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 &v1, const QVector &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> 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 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("modifiers"); + foreach (const QVector 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 3fcbd0a16f..1793dc5ff5 100644 --- a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp +++ b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp b/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp index 272827e57b..4d5ddfd523 100644 --- a/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp +++ b/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp @@ -48,6 +48,9 @@ public: virtual ~tst_QFontCache(); private slots: + void engineData_data(); + void engineData(); + void clear(); }; @@ -69,6 +72,52 @@ tst_QFontCache::~tst_QFontCache() { } +void tst_QFontCache::engineData_data() +{ + QTest::addColumn("family"); + QTest::addColumn("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 @@ -110,7 +159,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/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index ddbb4e6d75..8a5250aad4 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -261,9 +261,7 @@ private slots: #endif void raise(); void lower(); -#ifndef QT_MAC_USE_COCOA void stackUnder(); -#endif void testContentsPropagation(); void saveRestoreGeometry(); void restoreVersion1Geometry_data(); @@ -320,9 +318,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 dfc53c9164..94b3f9089f 100644 --- a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp +++ b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp @@ -81,6 +81,7 @@ private slots: void testActivation(); void testAncestorChange(); void testDockWidget(); + void testNativeContainerParent(); void cleanup(); private: @@ -330,6 +331,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 713dc6b9b8..61a9461a62 100644 --- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp @@ -75,6 +75,7 @@ private slots: void titleBarDoubleClick(); void restoreStateOfFloating(); void restoreDockWidget(); + void restoreStateWhileStillFloating(); // task specific tests: void task165177_deleteFocusWidget(); void task169808_setFloating(); @@ -757,6 +758,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 f057a58ff0..e5fdfaeb71 100644 --- a/tests/manual/diaglib/qwidgetdump.cpp +++ b/tests/manual/diaglib/qwidgetdump.cpp @@ -61,10 +61,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()) { @@ -79,12 +101,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(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 0519a0307c..6f8d9548b3 100644 --- a/tests/manual/diaglib/qwidgetdump.h +++ b/tests/manual/diaglib/qwidgetdump.h @@ -36,9 +36,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 c0faefb918..04576dbcf4 100644 --- a/tests/manual/diaglib/qwindowdump.cpp +++ b/tests/manual/diaglib/qwindowdump.cpp @@ -38,6 +38,7 @@ # include # include # include +# include # if QT_VERSION >= 0x050600 # include # endif @@ -151,6 +152,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 9ab00790b6..2a7d69c915 100644 --- a/tests/manual/diaglib/qwindowdump.h +++ b/tests/manual/diaglib/qwindowdump.h @@ -44,7 +44,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 160ccf5778..555ccbf740 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1094,7 +1094,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; @@ -3810,7 +3810,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 f590e42960..15db4d0a83 100644 --- a/util/glgen/codegenerator.cpp +++ b/util/glgen/codegenerator.cpp @@ -389,11 +389,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; @@ -810,7 +810,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 fc34eca80c..77b106bd5d 100644 --- a/util/glgen/legacyspecparser.cpp +++ b/util/glgen/legacyspecparser.cpp @@ -80,7 +80,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) { @@ -88,7 +88,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); @@ -144,7 +144,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"); @@ -191,9 +191,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; @@ -201,11 +201,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; @@ -246,7 +246,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) { @@ -301,5 +301,5 @@ void LegacySpecParser::parseFunctions(QTextStream &stream) bool LegacySpecParser::inDeprecationException(const QString &functionName) const { - return (functionName == QStringLiteral("TexImage3D")); + return functionName == QLatin1String("TexImage3D"); }