Merge remote-tracking branch 'origin/5.6' into dev

Conflicts:
	config.tests/unix/compile.test
	src/plugins/platforms/cocoa/qcocoahelpers.mm
	src/tools/qlalr/cppgenerator.cpp

Change-Id: I0103ca076a9aca7118b2fd99f0fdaf81055998c3
This commit is contained in:
Liang Qi 2016-02-02 15:57:44 +01:00
commit d3e6e732c7
119 changed files with 1840 additions and 1086 deletions

View File

@ -1,6 +1,6 @@
GNU LESSER GENERAL PUBLIC LICENSE 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/ Contact: http://www.qt.io/licensing/
You may use, distribute and copy the Qt GUI Toolkit under the terms of You may use, distribute and copy the Qt GUI Toolkit under the terms of

View File

@ -1,6 +1,6 @@
GNU LESSER GENERAL PUBLIC LICENSE 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/ Contact: http://www.qt.io/licensing/
You may use, distribute and copy the Qt GUI Toolkit under the terms of You may use, distribute and copy the Qt GUI Toolkit under the terms of

View File

@ -72,7 +72,7 @@ test -r Makefile && $MAKE distclean >/dev/null 2>&1
# Make sure output from possible previous tests is gone # Make sure output from possible previous tests is gone
rm -f "$EXE" "${EXE}.exe" rm -f "$EXE" "${EXE}.exe"
set -- "$QMAKE" -qtconf "$QTCONF" -nocache -spec "$QMKSPEC" "CONFIG+=$QMAKE_CONFIG" "CONFIG+=android_app" "CONFIG-=debug_and_release app_bundle lib_bundle" "LIBS*=$LFLAGS" "LIBS+=$MAC_ARCH_LFLAGS" "INCLUDEPATH*=$INCLUDEPATH" "QMAKE_CXXFLAGS*=$CXXFLAGS" "QMAKE_CXXFLAGS+=$MAC_ARCH_CXXFLAGS" $QMAKE_ARGS "$SRCDIR/$TEST/$EXE.pro" -o "$OUTDIR/$TEST/Makefile" set -- "$QMAKE" -qtconf "$QTCONF" -nocache -spec "$QMKSPEC" "CONFIG+=$QMAKE_CONFIG" "CONFIG+=android_app" "CONFIG-=debug_and_release app_bundle lib_bundle" "LIBS+=$LFLAGS" "LIBS+=$MAC_ARCH_LFLAGS" "INCLUDEPATH*=$INCLUDEPATH" "QMAKE_CXXFLAGS*=$CXXFLAGS" "QMAKE_CXXFLAGS+=$MAC_ARCH_CXXFLAGS" $QMAKE_ARGS "$SRCDIR/$TEST/$EXE.pro" -o "$OUTDIR/$TEST/Makefile"
if [ "$VERBOSE" = "yes" ]; then if [ "$VERBOSE" = "yes" ]; then
OUTDIR=$OUTDIR "$@" && $MAKE && SUCCESS=yes OUTDIR=$OUTDIR "$@" && $MAKE && SUCCESS=yes
else else

View File

@ -3,7 +3,7 @@
dita.metadata.default.author = Qt Project dita.metadata.default.author = Qt Project
dita.metadata.default.permissions = all dita.metadata.default.permissions = all
dita.metadata.default.publisher = Qt Project 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.copyrholder = The Qt Company Ltd
dita.metadata.default.audience = programmer dita.metadata.default.audience = programmer

View File

@ -78,7 +78,7 @@ HTML.footer += \
" <ul id=\"menu-footer-submenu\" class=\"right clearfix\"><li id=\"menu-item-1795\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1795\"><a title=\"Sign into your account.\" href=\"https://account.qt.io/login\">Sign In</a></li>\n" \ " <ul id=\"menu-footer-submenu\" class=\"right clearfix\"><li id=\"menu-item-1795\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1795\"><a title=\"Sign into your account.\" href=\"https://account.qt.io/login\">Sign In</a></li>\n" \
" <li id=\"menu-item-10375\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-10375\"><a href=\"mailto:feedback@theqtcompany.com?Subject=Feedback%20about%20doc.qt.io%20site\">Feedback</a></li>\n" \ " <li id=\"menu-item-10375\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-10375\"><a href=\"mailto:feedback@theqtcompany.com?Subject=Feedback%20about%20doc.qt.io%20site\">Feedback</a></li>\n" \
" <li id=\"menu-item-1494\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1494\"><a href=\"http://qt.io/contact-us/\">Contact us</a></li>\n" \ " <li id=\"menu-item-1494\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1494\"><a href=\"http://qt.io/contact-us/\">Contact us</a></li>\n" \
" <li id=\"menu-item-4472\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4472\"><a href=\"http://qt.io/about-us/\">© 2015 The Qt Company</a></li>\n" \ " <li id=\"menu-item-4472\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4472\"><a href=\"http://qt.io/about-us/\">© 2016 The Qt Company</a></li>\n" \
" </ul>\n" \ " </ul>\n" \
"</div>\n" \ "</div>\n" \
"</div>\n" \ "</div>\n" \

View File

@ -8,7 +8,7 @@ HTML.footer = \
"</div>\n" \ "</div>\n" \
"<div class=\"footer\">\n" \ "<div class=\"footer\">\n" \
" <p>\n" \ " <p>\n" \
" <acronym title=\"Copyright\">&copy;</acronym> 2015 The Qt Company Ltd.\n" \ " <acronym title=\"Copyright\">&copy;</acronym> 2016 The Qt Company Ltd.\n" \
" Documentation contributions included herein are the copyrights of\n" \ " Documentation contributions included herein are the copyrights of\n" \
" their respective owners.<br>" \ " their respective owners.<br>" \
" The documentation provided herein is licensed under the terms of the" \ " The documentation provided herein is licensed under the terms of the" \

View File

@ -5,7 +5,7 @@
HTML.footer = \ HTML.footer = \
" </div>\n" \ " </div>\n" \
" <p class=\"copy-notice\">\n" \ " <p class=\"copy-notice\">\n" \
" <acronym title=\"Copyright\">&copy;</acronym> 2015 The Qt Company Ltd.\n" \ " <acronym title=\"Copyright\">&copy;</acronym> 2016 The Qt Company Ltd.\n" \
" Documentation contributions included herein are the copyrights of\n" \ " Documentation contributions included herein are the copyrights of\n" \
" their respective owners. " \ " their respective owners. " \
" The documentation provided herein is licensed under the terms of the" \ " The documentation provided herein is licensed under the terms of the" \

View File

@ -5,6 +5,7 @@ body {
text-align: left; text-align: left;
margin-left: 5px; margin-left: 5px;
margin-right: 5px; margin-right: 5px;
background-color: #fff;
} }
p { p {

View File

@ -34,41 +34,41 @@
\image tabletexample.png \image tabletexample.png
When you use a tablet with Qt applications, \l{QTabletEvent}s are When you use a tablet with Qt applications, \l{QTabletEvent}s are
generated. You need to reimplement the generated. You need to reimplement the \l{QWidget::}{tabletEvent()} event
\l{QWidget::}{tabletEvent()} event handler if you want to handle handler if you want to handle tablet events. Events are generated when the
tablet events. Events are generated when the device used for tool (stylus) used for drawing enters and leaves the proximity of the
drawing enters and leaves the proximity of the tablet (i.e., when tablet (i.e., when it is close but not pressed down on it), when the tool
it is close but not pressed down on it), when a device is pushed is pressed down and released from it, when the tool is moved across the
down and released from it, and when a device is moved on the tablet, and when one of the buttons on the tool is pressed or released.
tablet.
The information available in QTabletEvent depends on the device The information available in QTabletEvent depends on the device used.
used. The tablet in this example has two different devices for This example can handle a tablet with up to three different drawing tools:
drawing: a stylus and an airbrush. For both devices the event a stylus, an airbrush, and an art pen. For any of these the event will
contains the position of the device, pressure on the tablet, contain the position of the tool, pressure on the tablet, button status,
vertical tilt, and horizontal tilt (i.e, the angle between the vertical tilt, and horizontal tilt (i.e, the angle between the device and
device and the perpendicular of the tablet). The airbrush has a the perpendicular of the tablet, if the tablet hardware can provide it).
finger wheel; the position of this is also available in the tablet The airbrush has a finger wheel; the position of this is also available
event. 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 In this example we implement a drawing program. You can use the stylus to
stylus to draw on the tablet as you use a pencil on paper. When draw on the tablet as you use a pencil on paper. When you draw with the
you draw with the airbrush you get a spray of paint; the finger airbrush you get a spray of virtual paint; the finger wheel is used to
wheel is used to change the density of the spray. The pressure and change the density of the spray. When you draw with the art pen, you get a
tilt can change the alpha and saturation values of the QColor and the a line whose width and endpoint angle depend on the rotation of the pen.
width of the QPen used for drawing. 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: The example consists of the following:
\list \list
\li The \c MainWindow class inherits QMainWindow and creates \li The \c MainWindow class inherits QMainWindow, creates
the examples menus and connect their slots and signals. the menus, and connects their slots and signals.
\li The \c TabletCanvas class inherits QWidget and \li The \c TabletCanvas class inherits QWidget and
receives tablet events. It uses the events to paint on a receives tablet events. It uses the events to paint onto an
offscreen pixmap, which it draws onto itself. offscreen pixmap, and then renders it.
\li The \c TabletApplication class inherits QApplication. This \li The \c TabletApplication class inherits QApplication. This
class handles tablet events that are not sent to \c tabletEvent(). class handles tablet proximity events.
We will look at this later.
\li The \c main() function creates a \c MainWindow and shows it \li The \c main() function creates a \c MainWindow and shows it
as a top level window. as a top level window.
\endlist \endlist
@ -81,110 +81,99 @@
\snippet widgets/tablet/mainwindow.h 0 \snippet widgets/tablet/mainwindow.h 0
The QActions let the user select if the tablets pressure and \c createMenus() sets up the menus with the actions. We have one
tilt should change the pen width, color alpha component and color QActionGroup for the actions that alter the alpha channel, color saturation
saturation. \c createActions() creates all actions, and \c and line width respectively. The action groups are connected to the
createMenus() sets up the menus with the actions. We have one \c setAlphaValuator(), \c setSaturationValuator(), and
QActionGroup for the actions that alter the alpha channel, color \c setLineWidthValuator() slots, which call functions in \c TabletCanvas.
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.
\section1 MainWindow Class Implementation \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 \snippet widgets/tablet/mainwindow.cpp 0
In the constructor we create the canvas, actions, and menus. In the constructor we call \c createMenus() to create all the actions and
We set the canvas as the center widget. We also initialize the menus, and set the canvas as the center widget.
canvas to match the state of our menus and start drawing with a
red color.
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 also populate the \b Brush menu. The command to change a brush does not
we set a new drawing color with \c setColor(). 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 \snippet widgets/tablet/mainwindow.cpp 2
The \c TabletCanvas class supports two ways by which the alpha It simply needs to retrieve the \c Valuator enum from QAction::data(), and
channel of the drawing color can be changed: tablet pressure and pass that to \c TabletCanvas::setAlphaChannelValuator(). If we were not
tilt. We have one action for each and an action if the alpha using the \c data property, we would instead need to compare the QAction
channel should not be changed. 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 We do lazy initialization of a QColorDialog the first time the user
how the canvas should change the drawing line width. 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(): Here is the implementation of \c save():
\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():
\snippet widgets/tablet/mainwindow.cpp 5 \snippet widgets/tablet/mainwindow.cpp 5
We use the QFileDialog to let the user select a file to save the We use the QFileDialog to let the user select a file to save the drawing,
drawing in. It is the \c TabletCanvas that save the drawing, so we and then call \c TabletCanvas::saveImage() to actually write it to the
call its \c saveImage() function. file.
Here is the implementation of \c loadAct(): Here is the implementation of \c load():
\snippet widgets/tablet/mainwindow.cpp 6 \snippet widgets/tablet/mainwindow.cpp 6
We let the user select the image file to be opened with We let the user select the image file to be opened with a QFileDialog; we
a QFileDialog; we then ask the canvas to load the image with \c then ask the canvas to load the image with \c loadImage().
loadImage().
Here is the implementation of \c aboutAct(): Here is the implementation of \c about():
\snippet widgets/tablet/mainwindow.cpp 7 \snippet widgets/tablet/mainwindow.cpp 7
We show a message box with a short description of the example. 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 \section1 TabletCanvas Class Definition
@ -193,24 +182,22 @@
\snippet widgets/tablet/tabletcanvas.h 0 \snippet widgets/tablet/tabletcanvas.h 0
The canvas can change the alpha channel, color saturation, The canvas can change the alpha channel, color saturation, and line width
and line width of the drawing. We have one enum for each of of the stroke. We have an enum listing the QTabletEvent properties with
these; their values decide if it is the tablet pressure or tilt which it is possible to modulate them. We keep a private variable for each:
that will alter them. We keep a private variable for each, the \c \c m_alphaChannelValuator, \c m_colorSaturationValuator and
alphaChannelType, \c colorSturationType, and \c penWidthType, \c m_lineWidthValuator, and we provide accessor functions for them.
which we provide access functions for.
We draw on a QPixmap with \c myPen and \c myBrush using \c We draw on a QPixmap with \c m_pen and \c m_brush using \c m_color.
myColor. The \c saveImage() and \c loadImage() saves and loads Each time a QTabletEvent is received, the stroke is drawn from
the QPixmap to disk. The pixmap is drawn on the widget in \c \c lastPoint to the point given in the current QTabletEvent,
paintEvent(). The \c pointerType and \c deviceType keeps the type and then the position and rotation are saved in \c lastPoint for next time.
of pointer, which is either a pen or an eraser, and device The \c saveImage() and \c loadImage() functions save and load the QPixmap to disk.
currently used on the tablet, which is either a stylus or an The pixmap is drawn on the widget in \c paintEvent().
airbrush.
The interpretation of events from the tablet is done in \c The interpretation of events from the tablet is done in \c tabletEvent(), and
tabletEvent(); \c paintPixmap(), \c updateBrush(), and \c \c paintPixmap(), \c updateBrush(), and \c updateCursor() are helper
brushPattern() are helper functions used by \c tabletEvent(). functions used by \c tabletEvent().
\section1 TabletCanvas Class Implementation \section1 TabletCanvas Class Implementation
@ -233,21 +220,28 @@
\snippet widgets/tablet/tabletcanvas.cpp 2 \snippet widgets/tablet/tabletcanvas.cpp 2
We simply call \l{QPixmap::}{load()}, which loads the image in \a We simply call \l{QPixmap::}{load()}, which loads the image from \a file.
file.
Here is the implementation of \c tabletEvent(): Here is the implementation of \c tabletEvent():
\snippet widgets/tablet/tabletcanvas.cpp 3 \snippet widgets/tablet/tabletcanvas.cpp 3
We get three kind of events to this function: TabletPress, We get three kind of events to this function: \c TabletPress, \c TabletRelease,
TabletRelease, and TabletMove, which is generated when a device and \c TabletMove, which are generated when a drawing tool is pressed down on,
is pressed down on, leaves, or moves on the tablet. We set the \c lifed up from, or moved across the tablet. We set \c m_deviceDown to \c true
deviceDown to true when a device is pressed down on the tablet; when a device is pressed down on the tablet; we then know that we should
we then know when we should draw when we receive move events. We draw when we receive move events. We have implemented \c updateBrush()
have implemented the \c updateBrush() and \c paintPixmap() helper to update \c m_brush and \c m_pen depending on which of the tablet event
functions to update \c myBrush and \c myPen after the state of \c properties the user has chosen to pay attention to. The \c updateCursor()
alphaChannelType, \c colorSaturationType, and \c lineWidthType. 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(): Here is the implementation of \c paintEvent():
@ -259,22 +253,22 @@
\snippet widgets/tablet/tabletcanvas.cpp 5 \snippet widgets/tablet/tabletcanvas.cpp 5
In this function we draw on the pixmap based on the movement of the device. In this function we draw on the pixmap based on the movement of the tool.
If the device used on the tablet is a stylus, we want to draw a line from 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 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 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 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. a soft gradient, whose density can depend on various event parameters.
By default it depends on the tangential pressure, which is the position of 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 the finger wheel on the airbrush. If the tool is a rotation stylus, we
a felt marker by drawing trapezoidal strokes. simulate a felt marker by drawing trapezoidal stroke segments.
\snippet widgets/tablet/tabletcanvas.cpp 6 \snippet widgets/tablet/tabletcanvas.cpp 6
In \c updateBrush() we set the pen and brush used for drawing In \c updateBrush() we set the pen and brush used for drawing to match
to match \c alphaChannelType, \c lineWidthType, \c \c m_alphaChannelValuator, \c m_lineWidthValuator, \c m_colorSaturationValuator,
colorSaturationType, and \c myColor. We will examine the code to and \c m_color. We will examine the code to set up \c m_brush and
set up \c myBrush and \c myPen for each of these variables: \c m_pen for each of these variables:
\snippet widgets/tablet/tabletcanvas.cpp 7 \snippet widgets/tablet/tabletcanvas.cpp 7
@ -288,34 +282,33 @@
\snippet widgets/tablet/tabletcanvas.cpp 8 \snippet widgets/tablet/tabletcanvas.cpp 8
The alpha channel of QColor is given as a number between 0 The alpha channel of QColor is given as a number between 0 and 255 where 0
and 255 where 0 is transparent and 255 is opaque. is transparent and 255 is opaque, or as a floating-point number where 0 is
\l{QTabletEvent::}{pressure()} returns the pressure as a qreal transparent and 1.0 is opaque. \l{QTabletEvent::}{pressure()} returns the
between 0.0 and 1.0. By subtracting 127 from the tilt values and pressure as a qreal between 0.0 and 1.0. We get the smallest alpha values
taking the absolute value we get the smallest alpha values (i.e., (i.e., the color is most transparent) when the pen is perpendicular to the
the color is most transparent) when the pen is perpendicular to tablet. We select the largest of the vertical and horizontal tilt values.
the tablet. We select the largest of the vertical and horizontal
tilt value.
\snippet widgets/tablet/tabletcanvas.cpp 9 \snippet widgets/tablet/tabletcanvas.cpp 9
The colorsaturation is given as a number between 0 and 255. It is The color saturation in the HSV color model can be given as an integer
set with \l{QColor::}{setHsv()}. We can set the tilt values between 0 and 255 or as a floating-point value between 0 and 1. We chose to
directly, but must multiply the pressure to a number between 0 and represent alpha as an integer, so we call \l{QColor::}{setHsv()} with
255. integer values. That means we need to multiply the pressure to a number
between 0 and 255.
\snippet widgets/tablet/tabletcanvas.cpp 10 \snippet widgets/tablet/tabletcanvas.cpp 10
The width of the pen increases with the pressure. When the pen The width of the pen stroke can increase with pressure, if so chosen.
width is controlled with the tilt we let the width increse with But when the pen width is controlled by tilt, we let the width increase
the angle between the device and the perpendicular of the tablet. with the angle between the tool and the perpendicular of the tablet.
\snippet widgets/tablet/tabletcanvas.cpp 11 \snippet widgets/tablet/tabletcanvas.cpp 11
We finally check whether the pointer is the stylus or the eraser. 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 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 pixmap and let the pressure decide the pen width, else we set
the colors we have set up previously in the function. the colors we have decided previously in the function.
\section1 TabletApplication Class Definition \section1 TabletApplication Class Definition
@ -325,13 +318,11 @@
\snippet widgets/tablet/tabletapplication.h 0 \snippet widgets/tablet/tabletapplication.h 0
We keep a \c TabletCanvas we send the device type of the events we \c TabletApplication exists as a subclass of QApplication in order to
handle in the \c event() function to. The TabletEnterProximity receive tablet proximity events and forward them to \c TabletCanvas.
and TabletLeaveProximity events are not sendt to the QApplication The \c TabletEnterProximity and \c TabletLeaveProximity events are sent to
object, while other tablet events are sendt to the QWidget's the QApplication object, while other tablet events are sent to the QWidget's
\c event(), which sends them on to \l{QWidget::}{tabletEvent()}. \c event() hander, which sends them on to \l{QWidget::}{tabletEvent()}.
Since we want to handle these events we have implemented \c
TabletApplication.
\section1 TabletApplication Class Implementation \section1 TabletApplication Class Implementation
@ -340,24 +331,24 @@
\snippet widgets/tablet/tabletapplication.cpp 0 \snippet widgets/tablet/tabletapplication.cpp 0
We use this function to handle the TabletEnterProximity and We use this function to handle the \c TabletEnterProximity and
TabletLeaveProximity events, which is generated when a device \c TabletLeaveProximity events, which are generated when a drawing
enters and leaves the proximity of the tablet. The intended use of these tool enters or leaves the proximity of the tablet. Here we call
events is to do work that is dependent on what kind of device is \c TabletCanvas::setTabletDevice(), which then calls \c updateCursor(),
used on the tablet. This way, you don't have to do this work which will set an appropriate cursor. This is the only reason we
when other events are generated, which is more frequently than the need the proximity events; for the purpose of correct drawing, it is
leave and enter proximity events. We call \c setTabletDevice() in enough for \c TabletCanvas to observe the \l{QTabletEvent::}{device()} and
\c TabletCanvas. \l{QTabletEvent::}{pointerType()} in each event that it receives.
\section1 The \c main() function \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 \snippet widgets/tablet/main.cpp 0
In the \c main() function we create a \c MainWinow and display it Here we create a \c MainWindow and display it as a top level window. We use
as a top level window. We use the \c TabletApplication class. We the \c TabletApplication class. We need to set the canvas after the
need to set the canvas after the application is created. We cannot application is created. We cannot use classes that implement event handling
use classes that implement event handling before an QApplication before an QApplication object is instantiated.
object is instantiated.
*/ */

View File

@ -45,237 +45,172 @@
//! [0] //! [0]
MainWindow::MainWindow(TabletCanvas *canvas) MainWindow::MainWindow(TabletCanvas *canvas)
: m_canvas(canvas), m_colorDialog(Q_NULLPTR)
{ {
myCanvas = canvas;
createActions();
createMenus(); createMenus();
myCanvas->setColor(Qt::red);
myCanvas->setLineWidthType(TabletCanvas::LineWidthPressure);
myCanvas->setAlphaChannelType(TabletCanvas::AlphaTangentialPressure);
myCanvas->setColorSaturationType(TabletCanvas::NoSaturation);
setWindowTitle(tr("Tablet Example")); setWindowTitle(tr("Tablet Example"));
setCentralWidget(myCanvas); setCentralWidget(m_canvas);
} }
//! [0] //! [0]
//! [1] //! [1]
void MainWindow::brushColorAct() void MainWindow::setBrushColor()
{ {
QColor color = QColorDialog::getColor(myCanvas->color()); if (!m_colorDialog) {
m_colorDialog = new QColorDialog(this);
if (color.isValid()) m_colorDialog->setModal(false);
myCanvas->setColor(color); m_colorDialog->setCurrentColor(m_canvas->color());
connect(m_colorDialog, &QColorDialog::colorSelected, m_canvas, &TabletCanvas::setColor);
}
m_colorDialog->setVisible(true);
} }
//! [1] //! [1]
//! [2] //! [2]
void MainWindow::alphaActionTriggered(QAction *action) void MainWindow::setAlphaValuator(QAction *action)
{ {
if (action == alphaChannelPressureAction) { m_canvas->setAlphaChannelValuator(action->data().value<TabletCanvas::Valuator>());
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);
}
} }
//! [2] //! [2]
//! [3] //! [3]
void MainWindow::lineWidthActionTriggered(QAction *action) void MainWindow::setLineWidthValuator(QAction *action)
{ {
if (action == lineWidthPressureAction) { m_canvas->setLineWidthType(action->data().value<TabletCanvas::Valuator>());
myCanvas->setLineWidthType(TabletCanvas::LineWidthPressure);
} else if (action == lineWidthTiltAction) {
myCanvas->setLineWidthType(TabletCanvas::LineWidthTilt);
} else {
myCanvas->setLineWidthType(TabletCanvas::NoLineWidth);
}
} }
//! [3] //! [3]
//! [4] //! [4]
void MainWindow::saturationActionTriggered(QAction *action) void MainWindow::setSaturationValuator(QAction *action)
{ {
if (action == colorSaturationVTiltAction) { m_canvas->setColorSaturationValuator(action->data().value<TabletCanvas::Valuator>());
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);
}
} }
//! [4] //! [4]
//! [5] //! [5]
void MainWindow::saveAct() void MainWindow::save()
{ {
QString path = QDir::currentPath() + "/untitled.png"; QString path = QDir::currentPath() + "/untitled.png";
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Picture"), QString fileName = QFileDialog::getSaveFileName(this, tr("Save Picture"),
path); path);
if (!myCanvas->saveImage(fileName)) if (!m_canvas->saveImage(fileName))
QMessageBox::information(this, "Error Saving Picture", QMessageBox::information(this, "Error Saving Picture",
"Could not save the image"); "Could not save the image");
} }
//! [5] //! [5]
//! [6] //! [6]
void MainWindow::loadAct() void MainWindow::load()
{ {
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Picture"), QString fileName = QFileDialog::getOpenFileName(this, tr("Open Picture"),
QDir::currentPath()); QDir::currentPath());
if (!myCanvas->loadImage(fileName)) if (!m_canvas->loadImage(fileName))
QMessageBox::information(this, "Error Opening Picture", QMessageBox::information(this, "Error Opening Picture",
"Could not open picture"); "Could not open picture");
} }
//! [6] //! [6]
//! [7] //! [7]
void MainWindow::aboutAct() void MainWindow::about()
{ {
QMessageBox::about(this, tr("About Tablet Example"), 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] //! [7]
//! [8] //! [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] //! [8]
brushColorAction = new QAction(tr("&Brush Color..."), this);
brushColorAction->setShortcut(tr("Ctrl+C")); QMenu *tabletMenu = menuBar()->addMenu(tr("&Tablet"));
connect(brushColorAction, SIGNAL(triggered()), QMenu *lineWidthMenu = tabletMenu->addMenu(tr("&Line Width"));
this, SLOT(brushColorAct()));
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] //! [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); 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->setCheckable(true);
alphaChannelTangentialPressureAction->setChecked(true); alphaChannelTangentialPressureAction->setChecked(true);
alphaChannelTiltAction = new QAction(tr("&Tilt"), this); QAction *alphaChannelTiltAction = alphaChannelMenu->addAction(tr("&Tilt"));
alphaChannelTiltAction->setData(TabletCanvas::TiltValuator);
alphaChannelTiltAction->setCheckable(true); 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); noAlphaChannelAction->setCheckable(true);
alphaChannelGroup = new QActionGroup(this); QActionGroup *alphaChannelGroup = new QActionGroup(this);
alphaChannelGroup->addAction(alphaChannelPressureAction); alphaChannelGroup->addAction(alphaChannelPressureAction);
alphaChannelGroup->addAction(alphaChannelTangentialPressureAction); alphaChannelGroup->addAction(alphaChannelTangentialPressureAction);
alphaChannelGroup->addAction(alphaChannelTiltAction); alphaChannelGroup->addAction(alphaChannelTiltAction);
alphaChannelGroup->addAction(noAlphaChannelAction); alphaChannelGroup->addAction(noAlphaChannelAction);
connect(alphaChannelGroup, SIGNAL(triggered(QAction*)), connect(alphaChannelGroup, &QActionGroup::triggered,
this, SLOT(alphaActionTriggered(QAction*))); this, &MainWindow::setAlphaValuator);
//! [9] //! [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); colorSaturationVTiltAction->setCheckable(true);
colorSaturationHTiltAction = new QAction(tr("&Horizontal Tilt"), this); QAction *colorSaturationHTiltAction = colorSaturationMenu->addAction(tr("&Horizontal Tilt"));
colorSaturationHTiltAction->setData(TabletCanvas::HTiltValuator);
colorSaturationHTiltAction->setCheckable(true); colorSaturationHTiltAction->setCheckable(true);
colorSaturationPressureAction = new QAction(tr("&Pressure"), this); QAction *colorSaturationPressureAction = colorSaturationMenu->addAction(tr("&Pressure"));
colorSaturationPressureAction->setData(TabletCanvas::PressureValuator);
colorSaturationPressureAction->setCheckable(true); 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->setCheckable(true);
noColorSaturationAction->setChecked(true); noColorSaturationAction->setChecked(true);
colorSaturationGroup = new QActionGroup(this); QActionGroup *colorSaturationGroup = new QActionGroup(this);
colorSaturationGroup->addAction(colorSaturationVTiltAction); colorSaturationGroup->addAction(colorSaturationVTiltAction);
colorSaturationGroup->addAction(colorSaturationHTiltAction); colorSaturationGroup->addAction(colorSaturationHTiltAction);
colorSaturationGroup->addAction(colorSaturationPressureAction); colorSaturationGroup->addAction(colorSaturationPressureAction);
colorSaturationGroup->addAction(noColorSaturationAction); colorSaturationGroup->addAction(noColorSaturationAction);
connect(colorSaturationGroup, SIGNAL(triggered(QAction*)), connect(colorSaturationGroup, &QActionGroup::triggered,
this, SLOT(saturationActionTriggered(QAction*))); this, &MainWindow::setSaturationValuator);
lineWidthPressureAction = new QAction(tr("&Pressure"), this); QMenu *helpMenu = menuBar()->addMenu("&Help");
lineWidthPressureAction->setCheckable(true); helpMenu->addAction(tr("A&bout"), this, &MainWindow::about);
lineWidthPressureAction->setChecked(true); helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
lineWidthTiltAction = new QAction(tr("&Tilt"), this);
lineWidthTiltAction->setCheckable(true);
lineWidthFixedAction = new QAction(tr("&Fixed"), this);
lineWidthFixedAction->setCheckable(true);
lineWidthGroup = new QActionGroup(this);
lineWidthGroup->addAction(lineWidthPressureAction);
lineWidthGroup->addAction(lineWidthTiltAction);
lineWidthGroup->addAction(lineWidthFixedAction);
connect(lineWidthGroup, SIGNAL(triggered(QAction*)),
this, SLOT(lineWidthActionTriggered(QAction*)));
exitAction = new QAction(tr("E&xit"), this);
exitAction->setShortcuts(QKeySequence::Quit);
connect(exitAction, SIGNAL(triggered()),
this, SLOT(close()));
loadAction = new QAction(tr("&Open..."), this);
loadAction->setShortcuts(QKeySequence::Open);
connect(loadAction, SIGNAL(triggered()),
this, SLOT(loadAct()));
saveAction = new QAction(tr("&Save As..."), this);
saveAction->setShortcuts(QKeySequence::SaveAs);
connect(saveAction, SIGNAL(triggered()),
this, SLOT(saveAct()));
aboutAction = new QAction(tr("A&bout"), this);
aboutAction->setShortcut(tr("Ctrl+B"));
connect(aboutAction, SIGNAL(triggered()),
this, SLOT(aboutAct()));
aboutQtAction = new QAction(tr("About &Qt"), this);
aboutQtAction->setShortcut(tr("Ctrl+Q"));
connect(aboutQtAction, SIGNAL(triggered()),
qApp, SLOT(aboutQt()));
//! [10]
} }
//! [10]
//! [11]
void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(loadAction);
fileMenu->addAction(saveAction);
fileMenu->addSeparator();
fileMenu->addAction(exitAction);
brushMenu = menuBar()->addMenu(tr("&Brush"));
brushMenu->addAction(brushColorAction);
tabletMenu = menuBar()->addMenu(tr("&Tablet"));
lineWidthMenu = tabletMenu->addMenu(tr("&Line Width"));
lineWidthMenu->addAction(lineWidthPressureAction);
lineWidthMenu->addAction(lineWidthTiltAction);
lineWidthMenu->addAction(lineWidthFixedAction);
alphaChannelMenu = tabletMenu->addMenu(tr("&Alpha Channel"));
alphaChannelMenu->addAction(alphaChannelPressureAction);
alphaChannelMenu->addAction(alphaChannelTangentialPressureAction);
alphaChannelMenu->addAction(alphaChannelTiltAction);
alphaChannelMenu->addAction(noAlphaChannelAction);
colorSaturationMenu = tabletMenu->addMenu(tr("&Color Saturation"));
colorSaturationMenu->addAction(colorSaturationVTiltAction);
colorSaturationMenu->addAction(colorSaturationHTiltAction);
colorSaturationMenu->addAction(noColorSaturationAction);
helpMenu = menuBar()->addMenu("&Help");
helpMenu->addAction(aboutAction);
helpMenu->addAction(aboutQtAction);
}
//! [11]

View File

@ -44,10 +44,7 @@
#include <QMainWindow> #include <QMainWindow>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QAction; class QColorDialog;
class QActionGroup;
class QMenu;
class QStatusBar;
QT_END_NAMESPACE QT_END_NAMESPACE
class TabletCanvas; class TabletCanvas;
@ -60,54 +57,19 @@ public:
MainWindow(TabletCanvas *canvas); MainWindow(TabletCanvas *canvas);
private slots: private slots:
void brushColorAct(); void setBrushColor();
void alphaActionTriggered(QAction *action); void setAlphaValuator(QAction *action);
void lineWidthActionTriggered(QAction *action); void setLineWidthValuator(QAction *action);
void saturationActionTriggered(QAction *action); void setSaturationValuator(QAction *action);
void saveAct(); void save();
void loadAct(); void load();
void aboutAct(); void about();
private: private:
void createActions();
void createMenus(); void createMenus();
TabletCanvas *myCanvas; TabletCanvas *m_canvas;
QColorDialog *m_colorDialog;
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;
}; };
//! [0] //! [0]

View File

@ -47,7 +47,7 @@ bool TabletApplication::event(QEvent *event)
{ {
if (event->type() == QEvent::TabletEnterProximity || if (event->type() == QEvent::TabletEnterProximity ||
event->type() == QEvent::TabletLeaveProximity) { event->type() == QEvent::TabletLeaveProximity) {
myCanvas->setTabletDevice(static_cast<QTabletEvent *>(event)); m_canvas->setTabletDevice(static_cast<QTabletEvent *>(event));
return true; return true;
} }
return QApplication::event(event); return QApplication::event(event);

View File

@ -56,10 +56,10 @@ public:
bool event(QEvent *event) Q_DECL_OVERRIDE; bool event(QEvent *event) Q_DECL_OVERRIDE;
void setCanvas(TabletCanvas *canvas) void setCanvas(TabletCanvas *canvas)
{ myCanvas = canvas; } { m_canvas = canvas; }
private: private:
TabletCanvas *myCanvas; TabletCanvas *m_canvas;
}; };
//! [0] //! [0]

View File

@ -45,17 +45,18 @@
//! [0] //! [0]
TabletCanvas::TabletCanvas() 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); resize(500, 500);
myColor = Qt::red;
myBrush = QBrush(myColor);
myPen = QPen(myBrush, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
initPixmap(); initPixmap();
setAutoFillBackground(true); setAutoFillBackground(true);
deviceDown = false;
alphaChannelType = AlphaTangentialPressure;
colorSaturationType = NoSaturation;
lineWidthType = LineWidthPressure;
} }
void TabletCanvas::initPixmap() void TabletCanvas::initPixmap()
@ -63,24 +64,24 @@ void TabletCanvas::initPixmap()
QPixmap newPixmap = QPixmap(width(), height()); QPixmap newPixmap = QPixmap(width(), height());
newPixmap.fill(Qt::white); newPixmap.fill(Qt::white);
QPainter painter(&newPixmap); QPainter painter(&newPixmap);
if (!pixmap.isNull()) if (!m_pixmap.isNull())
painter.drawPixmap(0, 0, pixmap); painter.drawPixmap(0, 0, m_pixmap);
painter.end(); painter.end();
pixmap = newPixmap; m_pixmap = newPixmap;
} }
//! [0] //! [0]
//! [1] //! [1]
bool TabletCanvas::saveImage(const QString &file) bool TabletCanvas::saveImage(const QString &file)
{ {
return pixmap.save(file); return m_pixmap.save(file);
} }
//! [1] //! [1]
//! [2] //! [2]
bool TabletCanvas::loadImage(const QString &file) bool TabletCanvas::loadImage(const QString &file)
{ {
bool success = pixmap.load(file); bool success = m_pixmap.load(file);
if (success) { if (success) {
update(); update();
@ -96,8 +97,8 @@ void TabletCanvas::tabletEvent(QTabletEvent *event)
switch (event->type()) { switch (event->type()) {
case QEvent::TabletPress: case QEvent::TabletPress:
if (!deviceDown) { if (!m_deviceDown) {
deviceDown = true; m_deviceDown = true;
lastPoint.pos = event->posF(); lastPoint.pos = event->posF();
lastPoint.rotation = event->rotation(); lastPoint.rotation = event->rotation();
} }
@ -105,17 +106,17 @@ void TabletCanvas::tabletEvent(QTabletEvent *event)
case QEvent::TabletMove: case QEvent::TabletMove:
if (event->device() == QTabletEvent::RotationStylus) if (event->device() == QTabletEvent::RotationStylus)
updateCursor(event); updateCursor(event);
if (deviceDown) { if (m_deviceDown) {
updateBrush(event); updateBrush(event);
QPainter painter(&pixmap); QPainter painter(&m_pixmap);
paintPixmap(painter, event); paintPixmap(painter, event);
lastPoint.pos = event->posF(); lastPoint.pos = event->posF();
lastPoint.rotation = event->rotation(); lastPoint.rotation = event->rotation();
} }
break; break;
case QEvent::TabletRelease: case QEvent::TabletRelease:
if (deviceDown && event->buttons() == Qt::NoButton) if (m_deviceDown && event->buttons() == Qt::NoButton)
deviceDown = false; m_deviceDown = false;
break; break;
default: default:
break; break;
@ -128,7 +129,7 @@ void TabletCanvas::tabletEvent(QTabletEvent *event)
void TabletCanvas::paintEvent(QPaintEvent *) void TabletCanvas::paintEvent(QPaintEvent *)
{ {
QPainter painter(this); QPainter painter(this);
painter.drawPixmap(0, 0, pixmap); painter.drawPixmap(0, 0, m_pixmap);
} }
//! [4] //! [4]
@ -142,10 +143,10 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
case QTabletEvent::Airbrush: case QTabletEvent::Airbrush:
{ {
painter.setPen(Qt::NoPen); painter.setPen(Qt::NoPen);
QRadialGradient grad(lastPoint.pos, myPen.widthF() * 10.0); QRadialGradient grad(lastPoint.pos, m_pen.widthF() * 10.0);
QColor color = myBrush.color(); QColor color = m_brush.color();
color.setAlphaF(color.alphaF() * 0.25); color.setAlphaF(color.alphaF() * 0.25);
grad.setColorAt(0, myBrush.color()); grad.setColorAt(0, m_brush.color());
grad.setColorAt(0.5, Qt::transparent); grad.setColorAt(0.5, Qt::transparent);
painter.setBrush(grad); painter.setBrush(grad);
qreal radius = grad.radius(); qreal radius = grad.radius();
@ -154,11 +155,11 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
break; break;
case QTabletEvent::RotationStylus: case QTabletEvent::RotationStylus:
{ {
myBrush.setStyle(Qt::SolidPattern); m_brush.setStyle(Qt::SolidPattern);
painter.setPen(Qt::NoPen); painter.setPen(Qt::NoPen);
painter.setBrush(myBrush); painter.setBrush(m_brush);
QPolygonF poly; QPolygonF poly;
qreal halfWidth = myPen.widthF(); qreal halfWidth = m_pen.widthF();
QPointF brushAdjust(qSin(qDegreesToRadians(lastPoint.rotation)) * halfWidth, QPointF brushAdjust(qSin(qDegreesToRadians(lastPoint.rotation)) * halfWidth,
qCos(qDegreesToRadians(lastPoint.rotation)) * halfWidth); qCos(qDegreesToRadians(lastPoint.rotation)) * halfWidth);
poly << lastPoint.pos + brushAdjust; poly << lastPoint.pos + brushAdjust;
@ -195,7 +196,7 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
} }
// FALL-THROUGH // FALL-THROUGH
case QTabletEvent::Stylus: case QTabletEvent::Stylus:
painter.setPen(myPen); painter.setPen(m_pen);
painter.drawLine(lastPoint.pos, event->posF()); painter.drawLine(lastPoint.pos, event->posF());
break; break;
} }
@ -206,68 +207,69 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
void TabletCanvas::updateBrush(const QTabletEvent *event) void TabletCanvas::updateBrush(const QTabletEvent *event)
{ {
int hue, saturation, value, alpha; 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 vValue = int(((event->yTilt() + 60.0) / 120.0) * 255);
int hValue = int(((event->xTilt() + 60.0) / 120.0) * 255); int hValue = int(((event->xTilt() + 60.0) / 120.0) * 255);
//! [7] //! [8] //! [7] //! [8]
switch (alphaChannelType) { switch (m_alphaChannelValuator) {
case AlphaPressure: case PressureValuator:
myColor.setAlphaF(event->pressure()); m_color.setAlphaF(event->pressure());
break; break;
case AlphaTangentialPressure: case TangentialPressureValuator:
if (event->device() == QTabletEvent::Airbrush) 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 else
myColor.setAlpha(255); m_color.setAlpha(255);
break; break;
case AlphaTilt: case TiltValuator:
myColor.setAlpha(maximum(abs(vValue - 127), abs(hValue - 127))); m_color.setAlpha(maximum(abs(vValue - 127), abs(hValue - 127)));
break; break;
default: default:
myColor.setAlpha(255); m_color.setAlpha(255);
} }
//! [8] //! [9] //! [8] //! [9]
switch (colorSaturationType) { switch (m_colorSaturationValuator) {
case SaturationVTilt: case VTiltValuator:
myColor.setHsv(hue, vValue, value, alpha); m_color.setHsv(hue, vValue, value, alpha);
break; break;
case SaturationHTilt: case HTiltValuator:
myColor.setHsv(hue, hValue, value, alpha); m_color.setHsv(hue, hValue, value, alpha);
break; break;
case SaturationPressure: case PressureValuator:
myColor.setHsv(hue, int(event->pressure() * 255.0), value, alpha); m_color.setHsv(hue, int(event->pressure() * 255.0), value, alpha);
break; break;
default: default:
; ;
} }
//! [9] //! [10] //! [9] //! [10]
switch (lineWidthType) { switch (m_lineWidthValuator) {
case LineWidthPressure: case PressureValuator:
myPen.setWidthF(event->pressure() * 10 + 1); m_pen.setWidthF(event->pressure() * 10 + 1);
break; break;
case LineWidthTilt: case TiltValuator:
myPen.setWidthF(maximum(abs(vValue - 127), abs(hValue - 127)) / 12); m_pen.setWidthF(maximum(abs(vValue - 127), abs(hValue - 127)) / 12);
break; break;
default: default:
myPen.setWidthF(1); m_pen.setWidthF(1);
} }
//! [10] //! [11] //! [10] //! [11]
if (event->pointerType() == QTabletEvent::Eraser) { if (event->pointerType() == QTabletEvent::Eraser) {
myBrush.setColor(Qt::white); m_brush.setColor(Qt::white);
myPen.setColor(Qt::white); m_pen.setColor(Qt::white);
myPen.setWidthF(event->pressure() * 10 + 1); m_pen.setWidthF(event->pressure() * 10 + 1);
} else { } else {
myBrush.setColor(myColor); m_brush.setColor(m_color);
myPen.setColor(myColor); m_pen.setColor(m_color);
} }
} }
//! [11] //! [11]
//! [12]
void TabletCanvas::updateCursor(const QTabletEvent *event) void TabletCanvas::updateCursor(const QTabletEvent *event)
{ {
QCursor cursor; QCursor cursor;
@ -285,7 +287,7 @@ void TabletCanvas::updateCursor(const QTabletEvent *event)
case QTabletEvent::RotationStylus: { case QTabletEvent::RotationStylus: {
QImage origImg(QLatin1String(":/images/cursor-felt-marker.png")); QImage origImg(QLatin1String(":/images/cursor-felt-marker.png"));
QImage img(32, 32, QImage::Format_ARGB32); QImage img(32, 32, QImage::Format_ARGB32);
QColor solid = myColor; QColor solid = m_color;
solid.setAlpha(255); solid.setAlpha(255);
img.fill(solid); img.fill(solid);
QPainter painter(&img); QPainter painter(&img);
@ -307,6 +309,7 @@ void TabletCanvas::updateCursor(const QTabletEvent *event)
} }
setCursor(cursor); setCursor(cursor);
} }
//! [12]
void TabletCanvas::resizeEvent(QResizeEvent *) void TabletCanvas::resizeEvent(QResizeEvent *)
{ {

View File

@ -61,27 +61,26 @@ class TabletCanvas : public QWidget
Q_OBJECT Q_OBJECT
public: public:
enum AlphaChannelType { AlphaPressure, AlphaTangentialPressure, AlphaTilt, NoAlpha }; enum Valuator { PressureValuator, TangentialPressureValuator,
enum ColorSaturationType { SaturationVTilt, SaturationHTilt, TiltValuator, VTiltValuator, HTiltValuator, NoValuator };
SaturationPressure, NoSaturation }; Q_ENUM(Valuator)
enum LineWidthType { LineWidthPressure, LineWidthTilt, NoLineWidth };
TabletCanvas(); TabletCanvas();
bool saveImage(const QString &file); bool saveImage(const QString &file);
bool loadImage(const QString &file); bool loadImage(const QString &file);
void setAlphaChannelType(AlphaChannelType type) void setAlphaChannelValuator(Valuator type)
{ alphaChannelType = type; } { m_alphaChannelValuator = type; }
void setColorSaturationType(ColorSaturationType type) void setColorSaturationValuator(Valuator type)
{ colorSaturationType = type; } { m_colorSaturationValuator = type; }
void setLineWidthType(LineWidthType type) void setLineWidthType(Valuator type)
{ lineWidthType = type; } { m_lineWidthValuator = type; }
void setColor(const QColor &color) void setColor(const QColor &c)
{ myColor = color; } { if (c.isValid()) m_color = c; }
QColor color() const QColor color() const
{ return myColor; } { return m_color; }
void setTabletDevice(QTabletEvent *event) void setTabletDevice(QTabletEvent *event)
{ myTabletDevice = event->device(); updateCursor(event); } { updateCursor(event); }
int maximum(int a, int b) int maximum(int a, int b)
{ return a > b ? a : b; } { return a > b ? a : b; }
@ -97,17 +96,14 @@ private:
void updateBrush(const QTabletEvent *event); void updateBrush(const QTabletEvent *event);
void updateCursor(const QTabletEvent *event); void updateCursor(const QTabletEvent *event);
AlphaChannelType alphaChannelType; Valuator m_alphaChannelValuator;
ColorSaturationType colorSaturationType; Valuator m_colorSaturationValuator;
LineWidthType lineWidthType; Valuator m_lineWidthValuator;
QTabletEvent::PointerType pointerType; QColor m_color;
QTabletEvent::TabletDevice myTabletDevice; QPixmap m_pixmap;
QColor myColor; QBrush m_brush;
QPen m_pen;
QPixmap pixmap; bool m_deviceDown;
QBrush myBrush;
QPen myPen;
bool deviceDown;
struct Point { struct Point {
QPointF pos; QPointF pos;

View File

@ -4,7 +4,8 @@
xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\" xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\"
xmlns:mp=\"http://schemas.microsoft.com/appx/2014/phone/manifest\" xmlns:mp=\"http://schemas.microsoft.com/appx/2014/phone/manifest\"
xmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\" xmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\"
IgnorableNamespaces=\"uap mp\"> xmlns:mobile=\"http://schemas.microsoft.com/appx/manifest/mobile/windows10\"
IgnorableNamespaces=\"uap mp mobile\">
<Identity <Identity
Name=\"$${WINRT_MANIFEST.identity}\" Name=\"$${WINRT_MANIFEST.identity}\"
@ -21,7 +22,7 @@
</Properties> </Properties>
<Dependencies> <Dependencies>
<TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.10069.0\" MaxVersionTested=\"10.0.10069.0\" />$${WINRT_MANIFEST.dependencies} <TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.10240.0\" MaxVersionTested=\"10.0.10586.0\" />$${WINRT_MANIFEST.dependencies}
</Dependencies> </Dependencies>
<Resources> <Resources>

View File

@ -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

View File

@ -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

View File

@ -3,7 +3,8 @@ TARGET = qtfreetype
CONFIG += \ CONFIG += \
static \ static \
hide_symbols \ hide_symbols \
exceptions_off rtti_off warn_off exceptions_off rtti_off warn_off \
installed
load(qt_helper_lib) load(qt_helper_lib)

View File

@ -226,6 +226,16 @@ public class QtNative
} }
} }
private static void setViewVisibility(final View view, final boolean visible)
{
runAction(new Runnable() {
@Override
public void run() {
view.setVisibility(visible ? View.VISIBLE : View.GONE);
}
});
}
public static boolean startApplication(String params, public static boolean startApplication(String params,
String environment, String environment,
String mainLibrary, String mainLibrary,

View File

@ -653,7 +653,7 @@ extern "C" void qt_core_boilerplate();
void qt_core_boilerplate() void qt_core_boilerplate()
{ {
printf("This is the QtCore library version " QT_BUILD_STR "\n" 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" "Contact: http://www.qt.io/licensing/\n"
"\n" "\n"
"Installation prefix: %s\n" "Installation prefix: %s\n"

View File

@ -107,8 +107,6 @@ win32 {
!winrt { !winrt {
SOURCES += io/qsettings_win.cpp SOURCES += io/qsettings_win.cpp
HEADERS += io/qwindowspipewriter_p.h
SOURCES += io/qwindowspipewriter.cpp
SOURCES += io/qstandardpaths_win.cpp SOURCES += io/qstandardpaths_win.cpp
wince* { wince* {
@ -117,11 +115,13 @@ win32 {
} else { } else {
HEADERS += \ HEADERS += \
io/qwinoverlappedionotifier_p.h \ io/qwinoverlappedionotifier_p.h \
io/qwindowspipereader_p.h io/qwindowspipereader_p.h \
io/qwindowspipewriter_p.h
SOURCES += \ SOURCES += \
io/qprocess_win.cpp \ io/qprocess_win.cpp \
io/qwinoverlappedionotifier.cpp \ io/qwinoverlappedionotifier.cpp \
io/qwindowspipereader.cpp \ io/qwindowspipereader.cpp \
io/qwindowspipewriter.cpp \
io/qstorageinfo_win.cpp io/qstorageinfo_win.cpp
LIBS += -lmpr LIBS += -lmpr
} }

View File

@ -753,7 +753,7 @@ QFile::copy(const QString &newName)
qWarning("QFile::copy: Empty or null file name"); qWarning("QFile::copy: Empty or null file name");
return false; return false;
} }
if (QFile(newName).exists()) { if (QFile::exists(newName)) {
// ### Race condition. If a file is moved in after this, it /will/ be // ### Race condition. If a file is moved in after this, it /will/ be
// overwritten. On Unix, the proper solution is to use hardlinks: // overwritten. On Unix, the proper solution is to use hardlinks:
// return ::link(old, new) && ::remove(old); See also rename(). // return ::link(old, new) && ::remove(old); See also rename().

View File

@ -39,7 +39,6 @@
#include "qprocess.h" #include "qprocess.h"
#include "qprocess_p.h" #include "qprocess_p.h"
#include "qwindowspipewriter_p.h"
#include <qdir.h> #include <qdir.h>
#include <qfileinfo.h> #include <qfileinfo.h>
@ -162,7 +161,7 @@ void QProcessPrivate::startProcess()
} }
// give the process a chance to start ... // give the process a chance to start ...
Sleep(SLEEPMIN * 2); Sleep(20);
_q_startupNotification(); _q_startupNotification();
} }

View File

@ -47,9 +47,7 @@
#include <qcoreapplication.h> #include <qcoreapplication.h>
#endif #endif
#if !defined(Q_OS_WINCE)
const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } }; const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } };
#endif
#include <qt_windows.h> #include <qt_windows.h>
#include <shlobj.h> #include <shlobj.h>
@ -70,113 +68,152 @@ const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x6
QT_BEGIN_NAMESPACE 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) static QString convertCharArray(const wchar_t *path)
{ {
return QDir::fromNativeSeparators(QString::fromWCharArray(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::GenericConfigLocation || type == QStandardPaths::GenericDataLocation;
return type == QStandardPaths::AppDataLocation ? }
CSIDL_APPDATA : // "Roaming" path
CSIDL_LOCAL_APPDATA; // Local path static inline bool isConfigLocation(QStandardPaths::StandardLocation type)
#else {
Q_UNUSED(type) return type == QStandardPaths::ConfigLocation || type == QStandardPaths::AppConfigLocation
return CSIDL_APPDATA; || 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 #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<GetKnownFolderPath>(QSystemLibrary::resolve(QLatin1String("shell32"), "SHGetKnownFolderPath"));
LPWSTR path;
if (Q_LIKELY(sHGetKnownFolderPath && SUCCEEDED(sHGetKnownFolderPath(clsid, 0, 0, &path)))) {
result = convertCharArray(path);
CoTaskMemFree(path);
} else {
if (warn) {
qErrnoWarning("SHGetKnownFolderPath() failed for standard location \"%s\".",
qPrintable(displayName(type)));
}
}
#else // !Q_OS_WINCE
Q_UNUSED(clsid)
Q_UNUSED(type)
Q_UNUSED(warn)
#endif
return result;
}
QString QStandardPaths::writableLocation(StandardLocation type) QString QStandardPaths::writableLocation(StandardLocation type)
{ {
QString result; QString result;
#if !defined(Q_OS_WINCE)
static GetKnownFolderPath SHGetKnownFolderPath = (GetKnownFolderPath)QSystemLibrary::resolve(QLatin1String("shell32"), "SHGetKnownFolderPath");
#endif
wchar_t path[MAX_PATH];
switch (type) { 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: case DownloadLocation:
#if !defined(Q_OS_WINCE) result = sHGetKnownFolderPath(qCLSID_FOLDERID_Downloads, type);
if (SHGetKnownFolderPath) { if (result.isEmpty())
LPWSTR path; result = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
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);
break; break;
case CacheLocation: case CacheLocation:
// Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache // 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 // location for everyone. Most applications seem to be using a
// cache directory located in their AppData directory // 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: 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 RuntimeLocation:
case HomeLocation: case HomeLocation:
@ -186,6 +223,15 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case TempLocation: case TempLocation:
result = QDir::tempPath(); result = QDir::tempPath();
break; 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; return result;
} }
@ -193,44 +239,26 @@ QString QStandardPaths::writableLocation(StandardLocation type)
QStringList QStandardPaths::standardLocations(StandardLocation type) QStringList QStandardPaths::standardLocations(StandardLocation type)
{ {
QStringList dirs; QStringList dirs;
const QString localDir = writableLocation(type);
if (!localDir.isEmpty())
dirs.append(localDir);
// type-specific handling goes here // type-specific handling goes here
#ifndef Q_OS_WINCE #ifndef Q_OS_WINCE
{ if (isConfigLocation(type)) {
wchar_t path[MAX_PATH]; QString programData = sHGetSpecialFolderPath(CSIDL_COMMON_APPDATA, type);
switch (type) { if (!programData.isEmpty()) {
case ConfigLocation: // same as AppLocalDataLocation, on Windows (oversight, but too late to fix it) if (!isGenericConfigLocation(type))
case GenericConfigLocation: // same as GenericDataLocation, on Windows appendOrganizationAndApp(programData);
case AppConfigLocation: // same as AppLocalDataLocation, that one on purpose dirs.append(programData);
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;
} }
} # ifndef QT_BOOTSTRAPPED
#endif 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; return dirs;
} }

View File

@ -685,8 +685,11 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
/*! \typedef QJsonObject::iterator::iterator_category /*! \typedef QJsonObject::iterator::iterator_category
A synonym for \e {std::bidirectional_iterator_tag} indicating A synonym for \e {std::random_access_iterator_tag} indicating
this iterator is a bidirectional iterator. 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 /*! \typedef QJsonObject::iterator::reference
@ -892,8 +895,11 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
/*! \typedef QJsonObject::const_iterator::iterator_category /*! \typedef QJsonObject::const_iterator::iterator_category
A synonym for \e {std::bidirectional_iterator_tag} indicating A synonym for \e {std::random_access_iterator_tag} indicating
this iterator is a bidirectional iterator. 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 /*! \typedef QJsonObject::const_iterator::reference

View File

@ -106,7 +106,7 @@ public:
int i; int i;
public: public:
typedef std::bidirectional_iterator_tag iterator_category; typedef std::random_access_iterator_tag iterator_category;
typedef int difference_type; typedef int difference_type;
typedef QJsonValue value_type; typedef QJsonValue value_type;
typedef QJsonValueRef reference; typedef QJsonValueRef reference;
@ -149,7 +149,7 @@ public:
int i; int i;
public: public:
typedef std::bidirectional_iterator_tag iterator_category; typedef std::random_access_iterator_tag iterator_category;
typedef int difference_type; typedef int difference_type;
typedef QJsonValue value_type; typedef QJsonValue value_type;
typedef QJsonValue reference; typedef QJsonValue reference;

View File

@ -40,6 +40,11 @@
#include <private/qcore_mac_p.h> #include <private/qcore_mac_p.h>
#ifdef Q_OS_OSX
#include <AppKit/NSText.h>
#include <Carbon/Carbon.h>
#endif
#include <qdebug.h> #include <qdebug.h>
#ifdef Q_OS_IOS #ifdef Q_OS_IOS
@ -154,5 +159,148 @@ QMacAutoReleasePool::~QMacAutoReleasePool()
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
#ifdef Q_OS_OSX
// Use this method to keep all the information in the TextSegment. As long as it is ordered
// we are in OK shape, and we can influence that ourselves.
struct KeyPair
{
QChar cocoaKey;
Qt::Key qtKey;
};
bool operator==(const KeyPair &entry, QChar qchar)
{
return entry.cocoaKey == qchar;
}
bool operator<(const KeyPair &entry, QChar qchar)
{
return entry.cocoaKey < qchar;
}
bool operator<(QChar qchar, const KeyPair &entry)
{
return qchar < entry.cocoaKey;
}
bool operator<(const Qt::Key &key, const KeyPair &entry)
{
return key < entry.qtKey;
}
bool operator<(const KeyPair &entry, const Qt::Key &key)
{
return entry.qtKey < key;
}
struct qtKey2CocoaKeySortLessThan
{
typedef bool result_type;
Q_DECL_CONSTEXPR result_type operator()(const KeyPair &entry1, const KeyPair &entry2) const Q_DECL_NOTHROW
{
return entry1.qtKey < entry2.qtKey;
}
};
static const int NumEntries = 59;
static const KeyPair entries[NumEntries] = {
{ NSEnterCharacter, Qt::Key_Enter },
{ NSBackspaceCharacter, Qt::Key_Backspace },
{ NSTabCharacter, Qt::Key_Tab },
{ NSNewlineCharacter, Qt::Key_Return },
{ NSCarriageReturnCharacter, Qt::Key_Return },
{ NSBackTabCharacter, Qt::Key_Backtab },
{ kEscapeCharCode, Qt::Key_Escape },
// Cocoa sends us delete when pressing backspace!
// (NB when we reverse this list in qtKey2CocoaKey, there
// will be two indices of Qt::Key_Backspace. But is seems to work
// ok for menu shortcuts (which uses that function):
{ NSDeleteCharacter, Qt::Key_Backspace },
{ NSUpArrowFunctionKey, Qt::Key_Up },
{ NSDownArrowFunctionKey, Qt::Key_Down },
{ NSLeftArrowFunctionKey, Qt::Key_Left },
{ NSRightArrowFunctionKey, Qt::Key_Right },
{ NSF1FunctionKey, Qt::Key_F1 },
{ NSF2FunctionKey, Qt::Key_F2 },
{ NSF3FunctionKey, Qt::Key_F3 },
{ NSF4FunctionKey, Qt::Key_F4 },
{ NSF5FunctionKey, Qt::Key_F5 },
{ NSF6FunctionKey, Qt::Key_F6 },
{ NSF7FunctionKey, Qt::Key_F7 },
{ NSF8FunctionKey, Qt::Key_F8 },
{ NSF9FunctionKey, Qt::Key_F9 },
{ NSF10FunctionKey, Qt::Key_F10 },
{ NSF11FunctionKey, Qt::Key_F11 },
{ NSF12FunctionKey, Qt::Key_F12 },
{ NSF13FunctionKey, Qt::Key_F13 },
{ NSF14FunctionKey, Qt::Key_F14 },
{ NSF15FunctionKey, Qt::Key_F15 },
{ NSF16FunctionKey, Qt::Key_F16 },
{ NSF17FunctionKey, Qt::Key_F17 },
{ NSF18FunctionKey, Qt::Key_F18 },
{ NSF19FunctionKey, Qt::Key_F19 },
{ NSF20FunctionKey, Qt::Key_F20 },
{ NSF21FunctionKey, Qt::Key_F21 },
{ NSF22FunctionKey, Qt::Key_F22 },
{ NSF23FunctionKey, Qt::Key_F23 },
{ NSF24FunctionKey, Qt::Key_F24 },
{ NSF25FunctionKey, Qt::Key_F25 },
{ NSF26FunctionKey, Qt::Key_F26 },
{ NSF27FunctionKey, Qt::Key_F27 },
{ NSF28FunctionKey, Qt::Key_F28 },
{ NSF29FunctionKey, Qt::Key_F29 },
{ NSF30FunctionKey, Qt::Key_F30 },
{ NSF31FunctionKey, Qt::Key_F31 },
{ NSF32FunctionKey, Qt::Key_F32 },
{ NSF33FunctionKey, Qt::Key_F33 },
{ NSF34FunctionKey, Qt::Key_F34 },
{ NSF35FunctionKey, Qt::Key_F35 },
{ NSInsertFunctionKey, Qt::Key_Insert },
{ NSDeleteFunctionKey, Qt::Key_Delete },
{ NSHomeFunctionKey, Qt::Key_Home },
{ NSEndFunctionKey, Qt::Key_End },
{ NSPageUpFunctionKey, Qt::Key_PageUp },
{ NSPageDownFunctionKey, Qt::Key_PageDown },
{ NSPrintScreenFunctionKey, Qt::Key_Print },
{ NSScrollLockFunctionKey, Qt::Key_ScrollLock },
{ NSPauseFunctionKey, Qt::Key_Pause },
{ NSSysReqFunctionKey, Qt::Key_SysReq },
{ NSMenuFunctionKey, Qt::Key_Menu },
{ NSHelpFunctionKey, Qt::Key_Help },
};
static const KeyPair * const end = entries + NumEntries;
QChar qt_mac_qtKey2CocoaKey(Qt::Key key)
{
// The first time this function is called, create a reverse
// lookup table sorted on Qt Key rather than Cocoa key:
static QVector<KeyPair> rev_entries(NumEntries);
static bool mustInit = true;
if (mustInit){
mustInit = false;
for (int i=0; i<NumEntries; ++i)
rev_entries[i] = entries[i];
std::sort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan());
}
const QVector<KeyPair>::iterator i
= std::lower_bound(rev_entries.begin(), rev_entries.end(), key);
if ((i == rev_entries.end()) || (key < *i))
return QChar();
return i->cocoaKey;
}
Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode)
{
const KeyPair *i = std::lower_bound(entries, end, keyCode);
if ((i == end) || (keyCode < *i))
return Qt::Key(keyCode.toUpper().unicode());
return i->qtKey;
}
#endif // Q_OS_OSX
// -------------------------------------------------------------------------
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -143,6 +143,11 @@ typedef struct {
QAppleOperatingSystemVersion qt_apple_os_version(); 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 QT_END_NAMESPACE
#endif // QCORE_MAC_P_H #endif // QCORE_MAC_P_H

View File

@ -1704,8 +1704,9 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
void *QMetaType::create(int type, const void *copy) void *QMetaType::create(int type, const void *copy)
{ {
QMetaType info(type); QMetaType info(type);
int size = info.sizeOf(); if (int size = info.sizeOf())
return info.construct(operator new(size), copy); return info.construct(operator new(size), copy);
return 0;
} }
/*! /*!

View File

@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
static const char boilerplate_supported_but_time_limited[] = static const char boilerplate_supported_but_time_limited[] =
"\nQt %1 Evaluation License\n" "\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" "This trial version may only be used for evaluation purposes\n"
"and will shut down after 120 minutes.\n" "and will shut down after 120 minutes.\n"
"Registered to:\n" "Registered to:\n"
@ -63,7 +63,7 @@ static const char boilerplate_supported_but_time_limited[] =
static const char boilerplate_supported[] = static const char boilerplate_supported[] =
"\nQt %1 Evaluation License\n" "\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" "This trial version may only be used for evaluation purposes\n"
"Registered to:\n" "Registered to:\n"
" Licensee: %2\n\n" " Licensee: %2\n\n"

View File

@ -37,12 +37,10 @@
** **
****************************************************************************/ ****************************************************************************/
#include "qfinalstate.h" #include "qfinalstate_p.h"
#ifndef QT_NO_STATEMACHINE #ifndef QT_NO_STATEMACHINE
#include "qabstractstate_p.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
/*! /*!
@ -82,19 +80,16 @@ QT_BEGIN_NAMESPACE
\sa QState::finished() \sa QState::finished()
*/ */
class QFinalStatePrivate : public QAbstractStatePrivate
{
Q_DECLARE_PUBLIC(QFinalState)
public:
QFinalStatePrivate();
};
QFinalStatePrivate::QFinalStatePrivate() QFinalStatePrivate::QFinalStatePrivate()
: QAbstractStatePrivate(FinalState) : 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. Constructs a new QFinalState object with the given \a parent state.
*/ */
@ -103,6 +98,15 @@ QFinalState::QFinalState(QState *parent)
{ {
} }
/*!
\internal
*/
QFinalState::QFinalState(QFinalStatePrivate &dd, QState *parent)
: QAbstractState(dd, parent)
{
}
/*! /*!
Destroys this final state. Destroys this final state.
*/ */

View File

@ -44,7 +44,6 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#ifndef QT_NO_STATEMACHINE #ifndef QT_NO_STATEMACHINE
class QFinalStatePrivate; class QFinalStatePrivate;
@ -61,6 +60,9 @@ protected:
bool event(QEvent *e) Q_DECL_OVERRIDE; bool event(QEvent *e) Q_DECL_OVERRIDE;
protected:
explicit QFinalState(QFinalStatePrivate &dd, QState *parent);
private: private:
Q_DISABLE_COPY(QFinalState) Q_DISABLE_COPY(QFinalState)
Q_DECLARE_PRIVATE(QFinalState) Q_DECLARE_PRIVATE(QFinalState)

View File

@ -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

View File

@ -37,11 +37,10 @@
** **
****************************************************************************/ ****************************************************************************/
#include "qstate.h" #include "qstate_p.h"
#ifndef QT_NO_STATEMACHINE #ifndef QT_NO_STATEMACHINE
#include "qstate_p.h"
#include "qhistorystate.h" #include "qhistorystate.h"
#include "qhistorystate_p.h" #include "qhistorystate_p.h"
#include "qabstracttransition.h" #include "qabstracttransition.h"

View File

@ -51,6 +51,7 @@
// We mean it. // We mean it.
// //
#include "qstate.h"
#include "private/qabstractstate_p.h" #include "private/qabstractstate_p.h"
#include <QtCore/qlist.h> #include <QtCore/qlist.h>
@ -58,6 +59,8 @@
#include <QtCore/qpointer.h> #include <QtCore/qpointer.h>
#include <QtCore/qvariant.h> #include <QtCore/qvariant.h>
#ifndef QT_NO_STATEMACHINE
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#ifndef QT_NO_PROPERTIES #ifndef QT_NO_PROPERTIES
@ -89,7 +92,7 @@ class QAbstractTransition;
class QHistoryState; class QHistoryState;
class QState; class QState;
class Q_AUTOTEST_EXPORT QStatePrivate : public QAbstractStatePrivate class Q_CORE_EXPORT QStatePrivate : public QAbstractStatePrivate
{ {
Q_DECLARE_PUBLIC(QState) Q_DECLARE_PUBLIC(QState)
public: public:
@ -121,4 +124,6 @@ public:
QT_END_NAMESPACE QT_END_NAMESPACE
#endif // QT_NO_STATEMACHINE
#endif #endif

View File

@ -6,6 +6,7 @@ HEADERS += $$PWD/qstatemachine.h \
$$PWD/qstate.h \ $$PWD/qstate.h \
$$PWD/qstate_p.h \ $$PWD/qstate_p.h \
$$PWD/qfinalstate.h \ $$PWD/qfinalstate.h \
$$PWD/qfinalstate_p.h \
$$PWD/qhistorystate.h \ $$PWD/qhistorystate.h \
$$PWD/qhistorystate_p.h \ $$PWD/qhistorystate_p.h \
$$PWD/qabstracttransition.h \ $$PWD/qabstracttransition.h \

View File

@ -199,16 +199,19 @@ void QFutureInterfaceBase::waitForResume()
int QFutureInterfaceBase::progressValue() const int QFutureInterfaceBase::progressValue() const
{ {
const QMutexLocker lock(&d->m_mutex);
return d->m_progressValue; return d->m_progressValue;
} }
int QFutureInterfaceBase::progressMinimum() const int QFutureInterfaceBase::progressMinimum() const
{ {
const QMutexLocker lock(&d->m_mutex);
return d->m_progressMinimum; return d->m_progressMinimum;
} }
int QFutureInterfaceBase::progressMaximum() const int QFutureInterfaceBase::progressMaximum() const
{ {
const QMutexLocker lock(&d->m_mutex);
return d->m_progressMaximum; return d->m_progressMaximum;
} }

View File

@ -152,18 +152,20 @@ public:
QAtomicInt m_refCountT; QAtomicInt m_refCountT;
}; };
// T: accessed from executing thread
// Q: accessed from the waiting/querying thread
RefCount refCount; RefCount refCount;
mutable QMutex m_mutex; mutable QMutex m_mutex;
QWaitCondition waitCondition; QWaitCondition waitCondition;
QList<QFutureCallOutInterface *> outputConnections; QList<QFutureCallOutInterface *> outputConnections;
int m_progressValue; int m_progressValue; // TQ
int m_progressMinimum; int m_progressMinimum; // TQ
int m_progressMaximum; int m_progressMaximum; // TQ
QFutureInterfaceBase::State state; QFutureInterfaceBase::State state;
QElapsedTimer progressTime; QElapsedTimer progressTime;
QWaitCondition pausedWaitCondition; QWaitCondition pausedWaitCondition;
QtPrivate::ResultStoreBase m_results; QtPrivate::ResultStoreBase m_results;
bool manualProgress; bool manualProgress; // only accessed from executing thread
int m_expectedResultCount; int m_expectedResultCount;
QtPrivate::ExceptionStore m_exceptionStore; QtPrivate::ExceptionStore m_exceptionStore;
QString m_progressText; QString m_progressText;

View File

@ -131,14 +131,13 @@ bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
} }
const SectionNode &node = sectionNodes.at(index); const SectionNode &node = sectionNodes.at(index);
int year, month, day, hour, minute, second, msec; int year = v.date().year();
year = v.date().year(); int month = v.date().month();
month = v.date().month(); int day = v.date().day();
day = v.date().day(); int hour = v.time().hour();
hour = v.time().hour(); int minute = v.time().minute();
minute = v.time().minute(); int second = v.time().second();
second = v.time().second(); int msec = v.time().msec();
msec = v.time().msec();
switch (node.type) { switch (node.type) {
case Hour24Section: case Hour12Section: hour = newVal; break; case Hour24Section: case Hour12Section: hour = newVal; break;
@ -676,15 +675,7 @@ QString QDateTimeParser::sectionText(const QString &text, int sectionIndex, int
QString QDateTimeParser::sectionText(int sectionIndex) const QString QDateTimeParser::sectionText(int sectionIndex) const
{ {
const SectionNode &sn = sectionNode(sectionIndex); const SectionNode &sn = sectionNode(sectionIndex);
switch (sn.type) { return sectionText(displayText(), sectionIndex, sn.pos);
case NoSectionIndex:
case FirstSectionIndex:
case LastSectionIndex:
return QString();
default: break;
}
return displayText().mid(sn.pos, sectionSize(sectionIndex));
} }
@ -1012,8 +1003,10 @@ QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPos
const QDate date(year, month, day); const QDate date(year, month, day);
const int diff = dayofweek - date.dayOfWeek(); const int diff = dayofweek - date.dayOfWeek();
if (diff != 0 && state == Acceptable && isSet & (DayOfWeekSectionShort|DayOfWeekSectionLong)) { if (diff != 0 && state == Acceptable
conflicts = isSet & DaySection; && isSet & (DayOfWeekSectionShort | DayOfWeekSectionLong)) {
if (isSet & DaySection)
conflicts = true;
const SectionNode &sn = sectionNode(currentSectionIndex); const SectionNode &sn = sectionNode(currentSectionIndex);
if (sn.type & (DayOfWeekSectionShort|DayOfWeekSectionLong) || currentSectionIndex == -1) { if (sn.type & (DayOfWeekSectionShort|DayOfWeekSectionLong) || currentSectionIndex == -1) {
// dayofweek should be preferred // dayofweek should be preferred
@ -1377,9 +1370,9 @@ int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex
*/ */
int QDateTimeParser::findAmPm(QString &str, int index, int *used) const int QDateTimeParser::findAmPm(QString &str, int sectionIndex, int *used) const
{ {
const SectionNode &s = sectionNode(index); const SectionNode &s = sectionNode(sectionIndex);
if (s.type != AmPmSection) { if (s.type != AmPmSection) {
qWarning("QDateTimeParser::findAmPm Internal error"); qWarning("QDateTimeParser::findAmPm Internal error");
return -1; return -1;
@ -1390,7 +1383,7 @@ int QDateTimeParser::findAmPm(QString &str, int index, int *used) const
return PossibleBoth; return PossibleBoth;
} }
const QLatin1Char space(' '); const QLatin1Char space(' ');
int size = sectionMaxSize(index); int size = sectionMaxSize(sectionIndex);
enum { enum {
amindex = 0, amindex = 0,

View File

@ -93,7 +93,7 @@ public:
first.pos = -1; first.pos = -1;
first.count = -1; first.count = -1;
first.zeroesAdded = 0; first.zeroesAdded = 0;
last.type = FirstSection; last.type = LastSection;
last.pos = -1; last.pos = -1;
last.count = -1; last.count = -1;
last.zeroesAdded = 0; last.zeroesAdded = 0;

View File

@ -242,9 +242,9 @@ template <> struct QConcatenable<QLatin1String> : private QAbstractConcatenable
} }
static inline void appendTo(const QLatin1String a, char *&out) static inline void appendTo(const QLatin1String a, char *&out)
{ {
if (a.data()) { if (const char *data = a.data()) {
for (const char *s = a.data(); *s; ) memcpy(out, data, a.size());
*out++ = *s++; out += a.size();
} }
} }
}; };

View File

@ -812,7 +812,6 @@ bool QDBusConnectionPrivate::activateCall(QObject* object, int flags, const QDBu
if (!object) if (!object)
return false; return false;
#ifndef QT_NO_PROPERTIES
Q_ASSERT_X(QThread::currentThread() == object->thread(), Q_ASSERT_X(QThread::currentThread() == object->thread(),
"QDBusConnection: internal threading error", "QDBusConnection: internal threading error",
"function called for an object that is in another thread!!"); "function called for an object that is in another thread!!");
@ -871,7 +870,6 @@ bool QDBusConnectionPrivate::activateCall(QObject* object, int flags, const QDBu
deliverCall(object, flags, msg, cacheIt->metaTypes, cacheIt->slotIdx); deliverCall(object, flags, msg, cacheIt->metaTypes, cacheIt->slotIdx);
return true; return true;
} }
#endif // QT_NO_PROPERTIES
return false; return false;
} }

View File

@ -1765,15 +1765,8 @@ QAccessibleInterface *QAccessibleEvent::accessibleInterface() const
return QAccessible::accessibleInterface(m_uniqueId); return QAccessible::accessibleInterface(m_uniqueId);
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(m_object); QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(m_object);
if (!iface || !iface->isValid()) { 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;
}
return 0; return 0;
}
if (m_child >= 0) { if (m_child >= 0) {
QAccessibleInterface *child = iface->child(m_child); QAccessibleInterface *child = iface->child(m_child);

View File

@ -960,15 +960,10 @@ QList<QScreen *> QGuiApplication::screens()
/*! /*!
\property QGuiApplication::primaryScreen \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. 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. The primaryScreenChanged signal was introduced in Qt 5.6.
\sa screens() \sa screens()
@ -1095,7 +1090,7 @@ static void init_platform(const QString &pluginArgument, const QString &platform
QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath); QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
QString fatalMessage 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()) { if (!keys.isEmpty()) {
fatalMessage += QStringLiteral("Available platform plugins are: %1.\n\n").arg( fatalMessage += QStringLiteral("Available platform plugins are: %1.\n\n").arg(
keys.join(QStringLiteral(", "))); keys.join(QStringLiteral(", ")));
@ -1999,6 +1994,16 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE
window = QGuiApplication::focusWindow(); 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, QKeyEvent ev(e->keyType, e->key, e->modifiers,
e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers, e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers,
e->unicode, e->repeat, e->repeatCount); e->unicode, e->repeat, e->repeatCount);

View File

@ -146,6 +146,23 @@ static int qtkeyForMacSymbol(const QChar ch)
#else #else
static bool qt_sequence_no_mnemonics = false; static bool qt_sequence_no_mnemonics = false;
#endif #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; } void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemonics = !b; }
/*! /*!

View File

@ -58,7 +58,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#ifndef QT_NO_SHORTCUT #ifndef QT_NO_SHORTCUT
struct Q_AUTOTEST_EXPORT QKeyBinding struct QKeyBinding
{ {
QKeySequence::StandardKey standardKey; QKeySequence::StandardKey standardKey;
uchar priority; uchar priority;
@ -66,7 +66,7 @@ struct Q_AUTOTEST_EXPORT QKeyBinding
uint platform; uint platform;
}; };
class Q_AUTOTEST_EXPORT QKeySequencePrivate class QKeySequencePrivate
{ {
public: public:
enum { MaxKeyCount = 4 }; // also used in QKeySequenceEdit enum { MaxKeyCount = 4 }; // also used in QKeySequenceEdit

View File

@ -255,8 +255,10 @@ bool QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Q
bool QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) 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)) if (t == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(tlw, timestamp, k, mods, 0, 0, 0, text, autorep, count))
return true; return true;
#endif
QWindowSystemInterfacePrivate::KeyEvent * e = QWindowSystemInterfacePrivate::KeyEvent * e =
new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count); new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count);
@ -281,10 +283,14 @@ bool QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestam
const QString& text, bool autorep, const QString& text, bool autorep,
ushort count, bool tryShortcutOverride) ushort count, bool tryShortcutOverride)
{ {
#if defined(Q_OS_OSX)
if (tryShortcutOverride && type == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(tlw, if (tryShortcutOverride && type == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(tlw,
timestamp, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count)) { timestamp, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count)) {
return true; return true;
} }
#else
Q_UNUSED(tryShortcutOverride)
#endif
QWindowSystemInterfacePrivate::KeyEvent * e = QWindowSystemInterfacePrivate::KeyEvent * e =
new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, type, key, modifiers, new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, type, key, modifiers,

View File

@ -2815,6 +2815,10 @@ QFontEngine *QFontCache::findEngine(const Key &key)
EngineCache::Iterator it = engineCache.find(key), EngineCache::Iterator it = engineCache.find(key),
end = engineCache.end(); end = engineCache.end();
if (it == end) return 0; 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 // found... update the hitcount and timestamp
updateHitCountAndTimeStamp(it.value()); updateHitCountAndTimeStamp(it.value());
@ -2835,6 +2839,9 @@ void QFontCache::updateHitCountAndTimeStamp(Engine &value)
void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMulti) 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 #ifdef QFONTCACHE_DEBUG
FC_DEBUG("QFontCache: inserting new engine %p, refcount %d", engine, engine->ref.load()); FC_DEBUG("QFontCache: inserting new engine %p, refcount %d", engine, engine->ref.load());
if (!insertMulti && engineCache.contains(key)) { if (!insertMulti && engineCache.contains(key)) {

View File

@ -927,23 +927,28 @@ QFontEngine *loadSingleEngine(int script,
QFontDef def = request; QFontDef def = request;
def.pixelSize = pixelSize; def.pixelSize = pixelSize;
QFontCache *fontCache = QFontCache::instance();
QFontCache::Key key(def,script); QFontCache::Key key(def,script);
QFontEngine *engine = QFontCache::instance()->findEngine(key); QFontEngine *engine = fontCache->findEngine(key);
if (!engine) { 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 // fast path: check if engine was loaded for another script
key.script = QChar::Script_Common; key.script = QChar::Script_Common;
engine = QFontCache::instance()->findEngine(key); engine = fontCache->findEngine(key);
key.script = script; key.script = script;
if (engine) { if (engine) {
Q_ASSERT(engine->type() != QFontEngine::Multi);
// Also check for OpenType tables when using complex scripts // Also check for OpenType tables when using complex scripts
if (Q_UNLIKELY(!engine->supportsScript(QChar::Script(script)))) { if (Q_UNLIKELY(!engine->supportsScript(QChar::Script(script)))) {
qWarning(" OpenType support missing for script %d", script); qWarning(" OpenType support missing for script %d", script);
return 0; return 0;
} }
QFontCache::instance()->insertEngine(key, engine); fontCache->insertEngine(key, engine);
return engine; return engine;
} }
} }
@ -951,13 +956,13 @@ QFontEngine *loadSingleEngine(int script,
// If the font data's native stretch matches the requested stretch we need to set stretch to 100 // 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 // 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. // the new stretch factor. This only done if not matched by styleName.
bool styleNameMatch = !request.styleName.isEmpty() && request.styleName == style->styleName; if (style->key.stretch != 0 && request.stretch != 0
if (!styleNameMatch && style->key.stretch != 0 && request.stretch != 0) && (request.styleName.isEmpty() || request.styleName != style->styleName)) {
def.stretch = (request.stretch * 100 + 50) / style->key.stretch; def.stretch = (request.stretch * 100 + 50) / style->key.stretch;
}
engine = pfdb->fontEngine(def, size->handle); engine = pfdb->fontEngine(def, size->handle);
if (engine) { if (engine) {
Q_ASSERT(engine->type() != QFontEngine::Multi);
// Also check for OpenType tables when using complex scripts // Also check for OpenType tables when using complex scripts
if (!engine->supportsScript(QChar::Script(script))) { if (!engine->supportsScript(QChar::Script(script))) {
qWarning(" OpenType support missing for script %d", script); qWarning(" OpenType support missing for script %d", script);
@ -966,13 +971,13 @@ QFontEngine *loadSingleEngine(int script,
return 0; 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 // cache engine for Common script as well
key.script = QChar::Script_Common; key.script = QChar::Script_Common;
if (!QFontCache::instance()->findEngine(key)) if (!fontCache->findEngine(key))
QFontCache::instance()->insertEngine(key, engine); fontCache->insertEngine(key, engine);
} }
} }
} }
@ -985,7 +990,7 @@ QFontEngine *loadEngine(int script, const QFontDef &request,
QtFontStyle *style, QtFontSize *size) QtFontStyle *style, QtFontSize *size)
{ {
QFontEngine *engine = loadSingleEngine(script, request, family, foundry, style, 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) { if (engine && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) {
QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine, QChar::Script(script)); QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine, QChar::Script(script));
@ -2641,12 +2646,14 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
} }
#endif #endif
QFontCache *fontCache = QFontCache::instance();
// Until we specifically asked not to, try looking for Multi font engine // Until we specifically asked not to, try looking for Multi font engine
// first, the last '1' indicates that we want Multi font engine instead // first, the last '1' indicates that we want Multi font engine instead
// of single ones // of single ones
bool multi = !(request.styleStrategy & QFont::NoFontMerging); bool multi = !(request.styleStrategy & QFont::NoFontMerging);
QFontCache::Key key(request, script, multi ? 1 : 0); QFontCache::Key key(request, script, multi ? 1 : 0);
engine = QFontCache::instance()->findEngine(key); engine = fontCache->findEngine(key);
if (engine) { if (engine) {
FM_DEBUG("Cache hit level 1"); FM_DEBUG("Cache hit level 1");
return engine; return engine;
@ -2687,7 +2694,7 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
QFontDef def = request; QFontDef def = request;
def.family = fallbacks.at(i); def.family = fallbacks.at(i);
QFontCache::Key key(def, script, multi ? 1 : 0); QFontCache::Key key(def, script, multi ? 1 : 0);
engine = QFontCache::instance()->findEngine(key); engine = fontCache->findEngine(key);
if (!engine) { if (!engine) {
QtFontDesc desc; QtFontDesc desc;
do { do {
@ -2731,13 +2738,21 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
if (req.stretch == 0) if (req.stretch == 0)
req.stretch = 100; req.stretch = 100;
// respect the fallback families that might be passed through the request
const QStringList fallBackFamilies = familyList(req);
if (!d->engineData) { if (!d->engineData) {
QFontCache *fontCache = QFontCache::instance();
// look for the requested font in the engine data cache // 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) { if (!d->engineData) {
// create a new one // create a new one
d->engineData = new QFontEngineData; d->engineData = new QFontEngineData;
QFontCache::instance()->insertEngineData(req, d->engineData); fontCache->insertEngineData(req, d->engineData);
} }
d->engineData->ref.ref(); d->engineData->ref.ref();
} }
@ -2746,25 +2761,18 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
if (d->engineData->engines[script]) if (d->engineData->engines[script])
return; return;
// Until we specifically asked not to, try looking for Multi font engine QFontEngine *fe = Q_NULLPTR;
// 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 = QFontCache::instance()->findEngine(key); req.fallBackFamilies = fallBackFamilies;
if (!req.fallBackFamilies.isEmpty())
req.family = req.fallBackFamilies.takeFirst();
// list of families to try // list of families to try
QStringList family_list; QStringList family_list;
if (!req.family.isEmpty()) { if (!req.family.isEmpty()) {
QStringList familiesForRequest = familyList(req);
// Add primary selection // Add primary selection
family_list << familiesForRequest.takeFirst(); family_list << req.family;
// Fallbacks requested in font request
req.fallBackFamilies = familiesForRequest;
// add the default family // add the default family
QString defaultFamily = QGuiApplication::font().family(); QString defaultFamily = QGuiApplication::font().family();

View File

@ -2296,7 +2296,7 @@ QFontEngine *QFontEngineMulti::createMultiFontEngine(QFontEngine *fe, int script
} }
if (!engine) { if (!engine) {
engine = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fontEngineMulti(fe, QChar::Script(script)); 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); Q_ASSERT(engine);
return engine; return engine;

View File

@ -127,14 +127,15 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
bool haveDirectConnection = false; bool haveDirectConnection = false;
foreach (const QUrl& url, rawProxies) { foreach (const QUrl& url, rawProxies) {
QNetworkProxy::ProxyType type; QNetworkProxy::ProxyType type;
if (url.scheme() == QStringLiteral("http")) { const QString scheme = url.scheme();
if (scheme == QLatin1String("http")) {
type = QNetworkProxy::HttpProxy; type = QNetworkProxy::HttpProxy;
} else if (url.scheme() == QStringLiteral("socks") } else if (scheme == QLatin1String("socks")
|| url.scheme() == QStringLiteral("socks5")) { || scheme == QLatin1String("socks5")) {
type = QNetworkProxy::Socks5Proxy; type = QNetworkProxy::Socks5Proxy;
} else if (url.scheme() == QStringLiteral("ftp")) { } else if (scheme == QLatin1String("ftp")) {
type = QNetworkProxy::FtpCachingProxy; type = QNetworkProxy::FtpCachingProxy;
} else if (url.scheme() == QStringLiteral("direct")) { } else if (scheme == QLatin1String("direct")) {
type = QNetworkProxy::NoProxy; type = QNetworkProxy::NoProxy;
haveDirectConnection = true; haveDirectConnection = true;
} else { } else {

View File

@ -55,7 +55,7 @@ QDBusPlatformMenuItem::QDBusPlatformMenuItem(quintptr tag)
: m_tag(tag ? tag : reinterpret_cast<quintptr>(this)) // QMenu will overwrite this later : m_tag(tag ? tag : reinterpret_cast<quintptr>(this)) // QMenu will overwrite this later
, m_subMenu(Q_NULLPTR) , m_subMenu(Q_NULLPTR)
, m_role(NoRole) , m_role(NoRole)
, m_isEnabled(false) , m_isEnabled(true)
, m_isVisible(true) , m_isVisible(true)
, m_isSeparator(false) , m_isSeparator(false)
, m_isCheckable(false) , m_isCheckable(false)
@ -152,7 +152,7 @@ QList<const QDBusPlatformMenuItem *> QDBusPlatformMenuItem::byIds(const QList<in
QDBusPlatformMenu::QDBusPlatformMenu(quintptr tag) QDBusPlatformMenu::QDBusPlatformMenu(quintptr tag)
: m_tag(tag ? tag : reinterpret_cast<quintptr>(this)) : m_tag(tag ? tag : reinterpret_cast<quintptr>(this))
, m_isEnabled(false) , m_isEnabled(true)
, m_isVisible(true) , m_isVisible(true)
, m_isSeparator(false) , m_isSeparator(false)
, m_dbusID(nextDBusID++) , m_dbusID(nextDBusID++)

View File

@ -1967,71 +1967,71 @@ namespace
// https://bugzilla.gnome.org/show_bug.cgi?id=744553 "ATK docs provide no guidance for allowed values of some text attributes" // 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 // specifically for "weight", "invalid", "language" and value range for colors
if (ia2Name == QStringLiteral("background-color")) { if (ia2Name == QLatin1String("background-color")) {
name = QStringLiteral("bg-color"); name = QStringLiteral("bg-color");
value = atspiColor(value); value = atspiColor(value);
} else if (ia2Name == QStringLiteral("font-family")) { } else if (ia2Name == QLatin1String("font-family")) {
name = QStringLiteral("family-name"); name = QStringLiteral("family-name");
} else if (ia2Name == QStringLiteral("color")) { } else if (ia2Name == QLatin1String("color")) {
name = QStringLiteral("fg-color"); name = QStringLiteral("fg-color");
value = atspiColor(value); value = atspiColor(value);
} else if (ia2Name == QStringLiteral("text-align")) { } else if (ia2Name == QLatin1String("text-align")) {
name = QStringLiteral("justification"); name = QStringLiteral("justification");
if (value == QStringLiteral("justify")) { if (value == QLatin1String("justify")) {
value = QStringLiteral("fill"); value = QStringLiteral("fill");
} else { } else {
if (value != QStringLiteral("left") && if (value != QLatin1String("left") &&
value != QStringLiteral("right") && value != QLatin1String("right") &&
value != QStringLiteral("center") value != QLatin1String("center")
) { ) {
value = QString(); value = QString();
qAtspiDebug() << "Unknown text-align attribute value \"" << value << "\" cannot be translated to AT-SPI."; 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"); name = QStringLiteral("size");
value = atspiSize(value); value = atspiSize(value);
} else if (ia2Name == QStringLiteral("font-style")) { } else if (ia2Name == QLatin1String("font-style")) {
name = QStringLiteral("style"); name = QStringLiteral("style");
if (value != QStringLiteral("normal") && if (value != QLatin1String("normal") &&
value != QStringLiteral("italic") && value != QLatin1String("italic") &&
value != QStringLiteral("oblique") value != QLatin1String("oblique")
) { ) {
value = QString(); value = QString();
qAtspiDebug() << "Unknown font-style attribute value \"" << value << "\" cannot be translated to AT-SPI."; 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"); name = QStringLiteral("underline");
if (value != QStringLiteral("none") && if (value != QLatin1String("none") &&
value != QStringLiteral("single") && value != QLatin1String("single") &&
value != QStringLiteral("double") value != QLatin1String("double")
) { ) {
value = QString(); value = QString();
qAtspiDebug() << "Unknown text-underline-type attribute value \"" << value << "\" cannot be translated to AT-SPI."; 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"); name = QStringLiteral("weight");
if (value == QStringLiteral("normal")) if (value == QLatin1String("normal"))
// Orca seems to accept all IAccessible2 values except for "normal" // Orca seems to accept all IAccessible2 values except for "normal"
// (on which it produces traceback and fails to read any following text attributes), // (on which it produces traceback and fails to read any following text attributes),
// but that is the default value, so omit it anyway // but that is the default value, so omit it anyway
value = QString(); value = QString();
} else if (ia2Name == QStringLiteral("text-position")) { } else if (ia2Name == QLatin1String("text-position")) {
name = QStringLiteral("vertical-align"); name = QStringLiteral("vertical-align");
if (value != QStringLiteral("baseline") && if (value != QLatin1String("baseline") &&
value != QStringLiteral("super") && value != QLatin1String("super") &&
value != QStringLiteral("sub") value != QLatin1String("sub")
) { ) {
value = QString(); value = QString();
qAtspiDebug() << "Unknown text-position attribute value \"" << value << "\" cannot be translated to AT-SPI."; 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"); name = QStringLiteral("direction");
if (value == QStringLiteral("lr")) if (value == QLatin1String("lr"))
value = QStringLiteral("ltr"); value = QStringLiteral("ltr");
else if (value == QStringLiteral("rl")) else if (value == QLatin1String("rl"))
value = QStringLiteral("rtl"); 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)) // 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"); value = QStringLiteral("rtl");
qAtspiDebug() << "writing-mode attribute value \"tb\" translated only w.r.t. horizontal direction; vertical direction ignored"; qAtspiDebug() << "writing-mode attribute value \"tb\" translated only w.r.t. horizontal direction; vertical direction ignored";
@ -2039,9 +2039,9 @@ namespace
value = QString(); value = QString();
qAtspiDebug() << "Unknown writing-mode attribute value \"" << value << "\" cannot be translated to AT-SPI."; 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 // 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 // OK - ATK docs are vague but suggest they support the same range of values as IAccessible2
} else { } else {
// attribute we know nothing about // attribute we know nothing about

View File

@ -1036,17 +1036,17 @@ QNetworkConfiguration::BearerType QNetworkManagerEngine::currentBearerType(const
QString bearer = i.value()->bearer(); QString bearer = i.value()->bearer();
if (bearer == QStringLiteral("gsm")) { if (bearer == QLatin1String("gsm")) {
return QNetworkConfiguration::Bearer2G; return QNetworkConfiguration::Bearer2G;
} else if (bearer == QStringLiteral("edge")) { } else if (bearer == QLatin1String("edge")) {
return QNetworkConfiguration::Bearer2G; return QNetworkConfiguration::Bearer2G;
} else if (bearer == QStringLiteral("umts")) { } else if (bearer == QLatin1String("umts")) {
return QNetworkConfiguration::BearerWCDMA; return QNetworkConfiguration::BearerWCDMA;
} else if (bearer == QStringLiteral("hspa") } else if (bearer == QLatin1String("hspa")
|| bearer == QStringLiteral("hsdpa") || bearer == QLatin1String("hsdpa")
|| bearer == QStringLiteral("hsupa")) { || bearer == QLatin1String("hsupa")) {
return QNetworkConfiguration::BearerHSPA; return QNetworkConfiguration::BearerHSPA;
} else if (bearer == QStringLiteral("lte")) { } else if (bearer == QLatin1String("lte")) {
return QNetworkConfiguration::BearerLTE; return QNetworkConfiguration::BearerLTE;
} }
} }

View File

@ -220,7 +220,7 @@ void QNetworkManagerInterface::propertiesSwap(QMap<QString,QVariant> map)
i.next(); i.next();
propertyMap.insert(i.key(),i.value()); propertyMap.insert(i.key(),i.value());
if (i.key() == QStringLiteral("State")) { if (i.key() == QLatin1String("State")) {
quint32 state = i.value().toUInt(); quint32 state = i.value().toUInt();
if (state == NM_DEVICE_STATE_ACTIVATED if (state == NM_DEVICE_STATE_ACTIVATED
|| state == NM_DEVICE_STATE_DISCONNECTED || state == NM_DEVICE_STATE_DISCONNECTED
@ -229,7 +229,7 @@ void QNetworkManagerInterface::propertiesSwap(QMap<QString,QVariant> map)
Q_EMIT propertiesChanged(map); Q_EMIT propertiesChanged(map);
Q_EMIT stateChanged(state); Q_EMIT stateChanged(state);
} }
} else if (i.key() == QStringLiteral("ActiveConnections")) { } else if (i.key() == QLatin1String("ActiveConnections")) {
Q_EMIT propertiesChanged(map); Q_EMIT propertiesChanged(map);
} }
} }
@ -424,7 +424,7 @@ void QNetworkManagerInterfaceDevice::propertiesSwap(QMap<QString,QVariant> map)
QMapIterator<QString, QVariant> i(map); QMapIterator<QString, QVariant> i(map);
while (i.hasNext()) { while (i.hasNext()) {
i.next(); i.next();
if (i.key() == QStringLiteral("AvailableConnections")) { //Device if (i.key() == QLatin1String("AvailableConnections")) { //Device
const QDBusArgument &dbusArgs = i.value().value<QDBusArgument>(); const QDBusArgument &dbusArgs = i.value().value<QDBusArgument>();
QDBusObjectPath path; QDBusObjectPath path;
QStringList paths; QStringList paths;
@ -520,9 +520,8 @@ void QNetworkManagerInterfaceDeviceWired::propertiesSwap(QMap<QString,QVariant>
while (i.hasNext()) { while (i.hasNext()) {
i.next(); i.next();
propertyMap.insert(i.key(),i.value()); propertyMap.insert(i.key(),i.value());
if (i.key() == QStringLiteral("Carrier")) { if (i.key() == QLatin1String("Carrier"))
Q_EMIT carrierChanged(i.value().toBool()); Q_EMIT carrierChanged(i.value().toBool());
}
} }
Q_EMIT propertiesChanged(map); Q_EMIT propertiesChanged(map);
} }
@ -699,9 +698,8 @@ void QNetworkManagerInterfaceDeviceWireless::propertiesSwap(QMap<QString,QVarian
while (i.hasNext()) { while (i.hasNext()) {
i.next(); i.next();
propertyMap.insert(i.key(),i.value()); propertyMap.insert(i.key(),i.value());
if (i.key() == QStringLiteral("ActiveAccessPoint")) { //DeviceWireless if (i.key() == QLatin1String("ActiveAccessPoint")) //DeviceWireless
Q_EMIT propertiesChanged(map); Q_EMIT propertiesChanged(map);
}
} }
} }
@ -1057,7 +1055,7 @@ void QNetworkManagerConnectionActive::propertiesSwap(QMap<QString,QVariant> map)
while (i.hasNext()) { while (i.hasNext()) {
i.next(); i.next();
propertyMap.insert(i.key(),i.value()); propertyMap.insert(i.key(),i.value());
if (i.key() == QStringLiteral("State")) { if (i.key() == QLatin1String("State")) {
quint32 state = i.value().toUInt(); quint32 state = i.value().toUInt();
if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
|| state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) { || state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {

View File

@ -279,7 +279,7 @@ QString TableGenerator::findComposeFile()
// check if users home directory has a file named .XCompose // check if users home directory has a file named .XCompose
if (cleanState()) { if (cleanState()) {
QString path = qgetenv("HOME") + QStringLiteral("/.XCompose"); QString path = qgetenv("HOME") + QStringLiteral("/.XCompose");
if (QFile(path).exists()) if (QFile::exists(path))
return path; return path;
} }
@ -292,7 +292,7 @@ QString TableGenerator::findComposeFile()
m_state = UnsupportedLocale; m_state = UnsupportedLocale;
else { else {
QString path = QDir(systemComposeDir()).filePath(table); QString path = QDir(systemComposeDir()).filePath(table);
if (QFile(path).exists()) if (QFile::exists(path))
return path; return path;
} }
} }
@ -314,7 +314,7 @@ bool TableGenerator::findSystemComposeDir()
bool found = false; bool found = false;
for (int i = 0; i < m_possibleLocations.size(); ++i) { for (int i = 0; i < m_possibleLocations.size(); ++i) {
QString path = m_possibleLocations.at(i); QString path = m_possibleLocations.at(i);
if (QFile(path + QLatin1String("/compose.dir")).exists()) { if (QFile::exists(path + QLatin1String("/compose.dir"))) {
m_systemComposeDir = path; m_systemComposeDir = path;
found = true; found = true;
break; break;

View File

@ -362,6 +362,15 @@ namespace QtAndroid
return surfaceId; return surfaceId;
} }
void setViewVisibility(jobject view, bool visible)
{
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass,
"setViewVisibility",
"(Landroid/view/View;Z)V",
view,
visible);
}
void setSurfaceGeometry(int surfaceId, const QRect &geometry) void setSurfaceGeometry(int surfaceId, const QRect &geometry)
{ {
if (surfaceId == -1) if (surfaceId == -1)

View File

@ -68,6 +68,7 @@ namespace QtAndroid
int createSurface(AndroidSurfaceClient * client, const QRect &geometry, bool onTop, int imageDepth); int createSurface(AndroidSurfaceClient * client, const QRect &geometry, bool onTop, int imageDepth);
int insertNativeView(jobject view, const QRect &geometry); int insertNativeView(jobject view, const QRect &geometry);
void setViewVisibility(jobject view, bool visible);
void setSurfaceGeometry(int surfaceId, const QRect &geometry); void setSurfaceGeometry(int surfaceId, const QRect &geometry);
void destroySurface(int surfaceId); void destroySurface(int surfaceId);
void bringChildToFront(int surfaceId); void bringChildToFront(int surfaceId);

View File

@ -51,10 +51,14 @@ QAndroidPlatformForeignWindow::QAndroidPlatformForeignWindow(QWindow *window)
{ {
const WId wId = window->property("_q_foreignWinId").value<WId>(); const WId wId = window->property("_q_foreignWinId").value<WId>();
m_view = reinterpret_cast<jobject>(wId); m_view = reinterpret_cast<jobject>(wId);
if (m_view.isValid())
QtAndroid::setViewVisibility(m_view.object(), false);
} }
QAndroidPlatformForeignWindow::~QAndroidPlatformForeignWindow() QAndroidPlatformForeignWindow::~QAndroidPlatformForeignWindow()
{ {
if (m_view.isValid())
QtAndroid::setViewVisibility(m_view.object(), false);
if (m_surfaceId != -1) if (m_surfaceId != -1)
QtAndroid::destroySurface(m_surfaceId); QtAndroid::destroySurface(m_surfaceId);
} }
@ -90,8 +94,9 @@ void QAndroidPlatformForeignWindow::setVisible(bool visible)
if (!m_view.isValid()) if (!m_view.isValid())
return; return;
QAndroidPlatformWindow::setVisible(visible); QtAndroid::setViewVisibility(m_view.object(), visible);
QAndroidPlatformWindow::setVisible(visible);
if (!visible && m_surfaceId != -1) { if (!visible && m_surfaceId != -1) {
QtAndroid::destroySurface(m_surfaceId); QtAndroid::destroySurface(m_surfaceId);
m_surfaceId = -1; m_surfaceId = -1;

View File

@ -126,7 +126,9 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
QPoint hotSpot = m_drag->hotSpot(); QPoint hotSpot = m_drag->hotSpot();
QPixmap pm = dragPixmap(m_drag, hotSpot); QPixmap pm = dragPixmap(m_drag, hotSpot);
QSize pmDeviceIndependentSize = pm.size() / pm.devicePixelRatio();
NSImage *nsimage = qt_mac_create_nsimage(pm); NSImage *nsimage = qt_mac_create_nsimage(pm);
[nsimage setSize : qt_mac_toNSSize(pmDeviceIndependentSize)];
QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacInternalPasteboardMime::MIME_DND); QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacInternalPasteboardMime::MIME_DND);
m_drag->mimeData()->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy")); m_drag->mimeData()->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy"));
@ -136,7 +138,7 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
NSWindow *theWindow = [m_lastEvent window]; NSWindow *theWindow = [m_lastEvent window];
Q_ASSERT(theWindow != nil); Q_ASSERT(theWindow != nil);
event_location.x -= hotSpot.x(); event_location.x -= hotSpot.x();
CGFloat flippedY = pm.height() - hotSpot.y(); CGFloat flippedY = pmDeviceIndependentSize.height() - hotSpot.y();
event_location.y -= flippedY; event_location.y -= flippedY;
NSSize mouseOffset_unused = NSMakeSize(0.0, 0.0); NSSize mouseOffset_unused = NSMakeSize(0.0, 0.0);
NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];

View File

@ -90,9 +90,6 @@ HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion &region);
OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage); 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_mapDropAction(Qt::DropAction action);
NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions); NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions);
Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions); Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions);

View File

@ -384,143 +384,6 @@ QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup)
return qtBrush; return qtBrush;
} }
// Use this method to keep all the information in the TextSegment. As long as it is ordered
// we are in OK shape, and we can influence that ourselves.
struct KeyPair
{
QChar cocoaKey;
Qt::Key qtKey;
};
bool operator==(const KeyPair &entry, QChar qchar)
{
return entry.cocoaKey == qchar;
}
bool operator<(const KeyPair &entry, QChar qchar)
{
return entry.cocoaKey < qchar;
}
bool operator<(QChar qchar, const KeyPair &entry)
{
return qchar < entry.cocoaKey;
}
bool operator<(const Qt::Key &key, const KeyPair &entry)
{
return key < entry.qtKey;
}
bool operator<(const KeyPair &entry, const Qt::Key &key)
{
return entry.qtKey < key;
}
struct qtKey2CocoaKeySortLessThan
{
typedef bool result_type;
Q_DECL_CONSTEXPR result_type operator()(const KeyPair &entry1, const KeyPair &entry2) const Q_DECL_NOTHROW
{
return entry1.qtKey < entry2.qtKey;
}
};
static const int NumEntries = 59;
static const KeyPair entries[NumEntries] = {
{ NSEnterCharacter, Qt::Key_Enter },
{ NSBackspaceCharacter, Qt::Key_Backspace },
{ NSTabCharacter, Qt::Key_Tab },
{ NSNewlineCharacter, Qt::Key_Return },
{ NSCarriageReturnCharacter, Qt::Key_Return },
{ NSBackTabCharacter, Qt::Key_Backtab },
{ kEscapeCharCode, Qt::Key_Escape },
// Cocoa sends us delete when pressing backspace!
// (NB when we reverse this list in qtKey2CocoaKey, there
// will be two indices of Qt::Key_Backspace. But is seems to work
// ok for menu shortcuts (which uses that function):
{ NSDeleteCharacter, Qt::Key_Backspace },
{ NSUpArrowFunctionKey, Qt::Key_Up },
{ NSDownArrowFunctionKey, Qt::Key_Down },
{ NSLeftArrowFunctionKey, Qt::Key_Left },
{ NSRightArrowFunctionKey, Qt::Key_Right },
{ NSF1FunctionKey, Qt::Key_F1 },
{ NSF2FunctionKey, Qt::Key_F2 },
{ NSF3FunctionKey, Qt::Key_F3 },
{ NSF4FunctionKey, Qt::Key_F4 },
{ NSF5FunctionKey, Qt::Key_F5 },
{ NSF6FunctionKey, Qt::Key_F6 },
{ NSF7FunctionKey, Qt::Key_F7 },
{ NSF8FunctionKey, Qt::Key_F8 },
{ NSF9FunctionKey, Qt::Key_F9 },
{ NSF10FunctionKey, Qt::Key_F10 },
{ NSF11FunctionKey, Qt::Key_F11 },
{ NSF12FunctionKey, Qt::Key_F12 },
{ NSF13FunctionKey, Qt::Key_F13 },
{ NSF14FunctionKey, Qt::Key_F14 },
{ NSF15FunctionKey, Qt::Key_F15 },
{ NSF16FunctionKey, Qt::Key_F16 },
{ NSF17FunctionKey, Qt::Key_F17 },
{ NSF18FunctionKey, Qt::Key_F18 },
{ NSF19FunctionKey, Qt::Key_F19 },
{ NSF20FunctionKey, Qt::Key_F20 },
{ NSF21FunctionKey, Qt::Key_F21 },
{ NSF22FunctionKey, Qt::Key_F22 },
{ NSF23FunctionKey, Qt::Key_F23 },
{ NSF24FunctionKey, Qt::Key_F24 },
{ NSF25FunctionKey, Qt::Key_F25 },
{ NSF26FunctionKey, Qt::Key_F26 },
{ NSF27FunctionKey, Qt::Key_F27 },
{ NSF28FunctionKey, Qt::Key_F28 },
{ NSF29FunctionKey, Qt::Key_F29 },
{ NSF30FunctionKey, Qt::Key_F30 },
{ NSF31FunctionKey, Qt::Key_F31 },
{ NSF32FunctionKey, Qt::Key_F32 },
{ NSF33FunctionKey, Qt::Key_F33 },
{ NSF34FunctionKey, Qt::Key_F34 },
{ NSF35FunctionKey, Qt::Key_F35 },
{ NSInsertFunctionKey, Qt::Key_Insert },
{ NSDeleteFunctionKey, Qt::Key_Delete },
{ NSHomeFunctionKey, Qt::Key_Home },
{ NSEndFunctionKey, Qt::Key_End },
{ NSPageUpFunctionKey, Qt::Key_PageUp },
{ NSPageDownFunctionKey, Qt::Key_PageDown },
{ NSPrintScreenFunctionKey, Qt::Key_Print },
{ NSScrollLockFunctionKey, Qt::Key_ScrollLock },
{ NSPauseFunctionKey, Qt::Key_Pause },
{ NSSysReqFunctionKey, Qt::Key_SysReq },
{ NSMenuFunctionKey, Qt::Key_Menu },
{ NSHelpFunctionKey, Qt::Key_Help },
};
static const KeyPair * const end = entries + NumEntries;
QChar qt_mac_qtKey2CocoaKey(Qt::Key key)
{
// The first time this function is called, create a reverse
// lookup table sorted on Qt Key rather than Cocoa key:
static QVector<KeyPair> rev_entries(NumEntries);
static bool mustInit = true;
if (mustInit){
mustInit = false;
for (int i=0; i<NumEntries; ++i)
rev_entries[i] = entries[i];
std::sort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan());
}
const QVector<KeyPair>::iterator i
= std::lower_bound(rev_entries.begin(), rev_entries.end(), key);
if ((i == rev_entries.end()) || (key < *i))
return QChar();
return i->cocoaKey;
}
Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode)
{
const KeyPair *i = std::lower_bound(entries, end, keyCode);
if ((i == end) || (keyCode < *i))
return Qt::Key(keyCode.toUpper().unicode());
return i->qtKey;
}
struct dndenum_mapper struct dndenum_mapper
{ {
NSDragOperation mac_code; NSDragOperation mac_code;

View File

@ -92,9 +92,9 @@ QMimeData *QHaikuClipboard::mimeData(QClipboard::Mode mode)
const status_t status = clipboard->FindData(name, B_MIME_TYPE, &data, &dataLen); const status_t status = clipboard->FindData(name, B_MIME_TYPE, &data, &dataLen);
if (dataLen && (status == B_OK)) { if (dataLen && (status == B_OK)) {
const QString format = QString::fromLatin1(name); const QString format = QString::fromLatin1(name);
if (format == QStringLiteral("text/plain")) { if (format == QLatin1String("text/plain")) {
m_systemMimeData->setText(QString::fromLocal8Bit(reinterpret_cast<const char*>(data), dataLen)); m_systemMimeData->setText(QString::fromLocal8Bit(reinterpret_cast<const char*>(data), dataLen));
} else if (format == QStringLiteral("text/html")) { } else if (format == QLatin1String("text/html")) {
m_systemMimeData->setHtml(QString::fromLocal8Bit(reinterpret_cast<const char*>(data), dataLen)); m_systemMimeData->setHtml(QString::fromLocal8Bit(reinterpret_cast<const char*>(data), dataLen));
} else { } else {
m_systemMimeData->setData(format, QByteArray(reinterpret_cast<const char*>(data), dataLen)); m_systemMimeData->setData(format, QByteArray(reinterpret_cast<const char*>(data), dataLen));

View File

@ -286,30 +286,33 @@ void QWindowsOleDropSource::createCursors()
const bool hasPixmap = !pixmap.isNull(); const bool hasPixmap = !pixmap.isNull();
// Find screen for drag. Could be obtained from QDrag::source(), but that might be a QWidget. // Find screen for drag. Could be obtained from QDrag::source(), but that might be a QWidget.
const QPlatformScreen *platformScreen = QWindowsContext::instance()->screenManager().screenAtDp(QWindowsCursor::mousePosition());
qreal scaleFactor = 1; if (!platformScreen) {
QPlatformCursor *platformCursor = Q_NULLPTR; if (const QScreen *primaryScreen = QGuiApplication::primaryScreen())
if (const QPlatformScreen *platformScreen = QWindowsContext::instance()->screenManager().screenAtDp(QWindowsCursor::mousePosition())) { platformScreen = primaryScreen->handle();
scaleFactor = QHighDpiScaling::factor(platformScreen);
platformCursor = platformScreen->cursor();
} }
if (!platformCursor && QGuiApplication::primaryScreen()) Q_ASSERT(platformScreen);
platformCursor = QGuiApplication::primaryScreen()->handle()->cursor(); 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 }; Qt::DropAction actions[] = { Qt::MoveAction, Qt::CopyAction, Qt::LinkAction, Qt::IgnoreAction };
int actionCount = int(sizeof(actions) / sizeof(actions[0])); int actionCount = int(sizeof(actions) / sizeof(actions[0]));
if (!hasPixmap) if (!hasPixmap)
--actionCount; // No Qt::IgnoreAction unless pixmap --actionCount; // No Qt::IgnoreAction unless pixmap
const QPoint hotSpot = scalePixmap const QPoint hotSpot = qFuzzyCompare(hotSpotScaleFactor, 1.0)
? (QPointF(drag->hotSpot()) * scaleFactor).toPoint() ? drag->hotSpot()
: drag->hotSpot(); : (QPointF(drag->hotSpot()) * hotSpotScaleFactor).toPoint();
for (int cnum = 0; cnum < actionCount; ++cnum) { for (int cnum = 0; cnum < actionCount; ++cnum) {
const Qt::DropAction action = actions[cnum]; const Qt::DropAction action = actions[cnum];
QPixmap cursorPixmap = drag->dragCursor(action); QPixmap cursorPixmap = drag->dragCursor(action);
@ -462,7 +465,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
if (!m_touchDragWindow) if (!m_touchDragWindow)
m_touchDragWindow = new QWindowsDragCursorWindow; m_touchDragWindow = new QWindowsDragCursorWindow;
m_touchDragWindow->setPixmap(e.pixmap); m_touchDragWindow->setPixmap(e.pixmap);
m_touchDragWindow->setFramePosition(QWindowsCursor::mousePosition() - e.hotSpot); m_touchDragWindow->setFramePosition(QCursor::pos() - e.hotSpot);
if (!m_touchDragWindow->isVisible()) if (!m_touchDragWindow->isVisible())
m_touchDragWindow->show(); m_touchDragWindow->show();
break; break;

View File

@ -1620,7 +1620,7 @@ LOGFONT QWindowsFontDatabase::fontDefToLOGFONT(const QFontDef &request)
if (fam.isEmpty()) if (fam.isEmpty())
fam = QStringLiteral("MS Sans Serif"); 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))) { && (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 fam = QStringLiteral("Arial"); // MS Sans Serif has bearing problems in italic, and does not scale
} }

View File

@ -238,17 +238,10 @@ int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLa
} }
} else { } else {
#endif #endif
wchar_t first = tm.tmFirstChar;
wchar_t last = tm.tmLastChar;
QStringIterator it(str, str + numChars); QStringIterator it(str, str + numChars);
while (it.hasNext()) { while (it.hasNext()) {
const uint uc = it.next(); const uint uc = it.next();
if ( if (uc >= tm.tmFirstChar && uc <= tm.tmLastChar)
#ifdef Q_DEAD_CODE_FROM_QT4_WINCE
tm.tmFirstChar > 60000 ||
#endif
uc >= first && uc <= last)
glyphs->glyphs[glyph_pos] = uc; glyphs->glyphs[glyph_pos] = uc;
else else
glyphs->glyphs[glyph_pos] = 0; glyphs->glyphs[glyph_pos] = 0;
@ -358,11 +351,9 @@ glyph_t QWindowsFontEngine::glyphIndex(uint ucs4) const
glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4 + 0xf000); glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4 + 0xf000);
} else if (ttf) { } else if (ttf) {
glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4); glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4);
#else } else
if (tm.tmFirstChar > 60000) {
glyph = ucs4;
#endif #endif
} else if (ucs4 >= tm.tmFirstChar && ucs4 <= tm.tmLastChar) { if (ucs4 >= tm.tmFirstChar && ucs4 <= tm.tmLastChar) {
glyph = ucs4; glyph = ucs4;
} else { } else {
glyph = 0; glyph = 0;

View File

@ -1151,7 +1151,7 @@ QVariant QWindowsMimeImage::convertToMime(const QString &mimeType, IDataObject *
{ {
Q_UNUSED(preferredType); Q_UNUSED(preferredType);
QVariant result; QVariant result;
if (mimeType != QStringLiteral("application/x-qt-image")) if (mimeType != QLatin1String("application/x-qt-image"))
return result; return result;
//Try to convert from a format which has more data //Try to convert from a format which has more data
//DIBV5, use only if its is not synthesized //DIBV5, use only if its is not synthesized

View File

@ -230,6 +230,30 @@ static inline QRect frameGeometry(HWND hwnd, bool topLevel)
return qrectFromRECT(rect); 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) static inline QSize clientSize(HWND hwnd)
{ {
RECT rect = { 0, 0, 0, 0 }; RECT rect = { 0, 0, 0, 0 };
@ -1867,6 +1891,10 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
swpf |= SWP_NOSIZE | SWP_NOMOVE; swpf |= SWP_NOSIZE | SWP_NOMOVE;
const bool wasSync = testFlag(SynchronousGeometryChangeEvent); const bool wasSync = testFlag(SynchronousGeometryChangeEvent);
setFlag(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(), SetWindowPos(m_data.hwnd, 0, m_savedFrameGeometry.x(), m_savedFrameGeometry.y(),
m_savedFrameGeometry.width(), m_savedFrameGeometry.height(), swpf); m_savedFrameGeometry.width(), m_savedFrameGeometry.height(), swpf);
if (!wasSync) if (!wasSync)

View File

@ -1169,7 +1169,7 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEvent
Q_D(QWinRTScreen); Q_D(QWinRTScreen);
boolean visible; boolean visible;
HRESULT hr = args ? args->get_Visible(&visible) : d->coreWindow->get_Visible(&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); QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden);
if (visible) if (visible)
handleExpose(); handleExpose();

View File

@ -645,7 +645,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
QString glIntegrationName = QString::fromLocal8Bit(qgetenv("QT_XCB_GL_INTEGRATION")); QString glIntegrationName = QString::fromLocal8Bit(qgetenv("QT_XCB_GL_INTEGRATION"));
if (!glIntegrationName.isEmpty()) { if (!glIntegrationName.isEmpty()) {
qCDebug(QT_XCB_GLINTEGRATION) << "QT_XCB_GL_INTEGRATION is set to" << glIntegrationName; qCDebug(QT_XCB_GLINTEGRATION) << "QT_XCB_GL_INTEGRATION is set to" << glIntegrationName;
if (glIntegrationName != QStringLiteral("none")) { if (glIntegrationName != QLatin1String("none")) {
glIntegrationNames.removeAll(glIntegrationName); glIntegrationNames.removeAll(glIntegrationName);
glIntegrationNames.prepend(glIntegrationName); glIntegrationNames.prepend(glIntegrationName);
} else { } else {

View File

@ -2265,12 +2265,13 @@ void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, con
static bool ignoreLeaveEvent(const xcb_leave_notify_event_t *event) static bool ignoreLeaveEvent(const xcb_leave_notify_event_t *event)
{ {
return event->detail == XCB_NOTIFY_DETAIL_VIRTUAL 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) 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_VIRTUAL
|| event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL);
} }

View File

@ -55,7 +55,7 @@ public:
QPlatformPrinterSupport *QCocoaPrinterSupportPlugin::create(const QString &key) 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; return 0;
QGuiApplication *app = qobject_cast<QGuiApplication *>(QCoreApplication::instance()); QGuiApplication *app = qobject_cast<QGuiApplication *>(QCoreApplication::instance());
if (!app) if (!app)

View File

@ -75,11 +75,7 @@ namespace QTest
QEvent::Type type; QEvent::Type type;
type = press ? QEvent::KeyPress : QEvent::KeyRelease; type = press ? QEvent::KeyPress : QEvent::KeyRelease;
qt_handleKeyEvent(window, type, code, modifier, text, repeat, delay); qt_handleKeyEvent(window, type, code, modifier, text, repeat, delay);
#ifdef QT_MAC_USE_COCOA
QTest::qWait(20);
#else
qApp->processEvents(); qApp->processEvents();
#endif
} }
static void sendKeyEvent(KeyAction action, QWindow *window, Qt::Key code, static void sendKeyEvent(KeyAction action, QWindow *window, Qt::Key code,

View File

@ -62,7 +62,7 @@ static const char docTypeHeader[] =
#define PROGRAMNAME "qdbuscpp2xml" #define PROGRAMNAME "qdbuscpp2xml"
#define PROGRAMVERSION "0.2" #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 QString outputFile;
static int flags; static int flags;

View File

@ -43,7 +43,7 @@
#define PROGRAMNAME "qdbusxml2cpp" #define PROGRAMNAME "qdbusxml2cpp"
#define PROGRAMVERSION "0.8" #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" #define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply"

View File

@ -117,13 +117,13 @@ void Uic::writeCopyrightHeader(DomUI *ui)
if (comment.size()) if (comment.size())
out << "/*\n" << comment << "\n*/\n\n"; out << "/*\n" << comment << "\n*/\n\n";
out << "/********************************************************************************\n"; out << "/********************************************************************************\n";
out << "** Form generated from reading UI file '" << QFileInfo(opt.inputFile).fileName() << "'\n"; out << "** Form generated from reading UI file '" << QFileInfo(opt.inputFile).fileName() << "'\n";
out << "**\n"; out << "**\n";
out << "** Created by: Qt User Interface Compiler version " << QLatin1String(QT_VERSION_STR) << "\n"; out << "** Created by: Qt User Interface Compiler version " << QLatin1String(QT_VERSION_STR) << "\n";
out << "**\n"; out << "**\n";
out << "** WARNING! All changes made in this file will be lost when recompiling UI file!\n"; out << "** WARNING! All changes made in this file will be lost when recompiling UI file!\n";
out << "********************************************************************************/\n\n"; out << "********************************************************************************/\n\n";
} }
// Check the version with a stream reader at the <ui> element. // Check the version with a stream reader at the <ui> element.

View File

@ -3407,27 +3407,27 @@ void QFileDialogPrivate::_q_deleteCurrent()
if (!index.isValid()) if (!index.isValid())
continue; continue;
QString fileName = index.data(QFileSystemModel::FileNameRole).toString(); QString fileName = index.data(QFileSystemModel::FileNameRole).toString();
QString filePath = index.data(QFileSystemModel::FilePathRole).toString(); QString filePath = index.data(QFileSystemModel::FilePathRole).toString();
bool isDir = model->isDir(index); 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 #ifndef QT_NO_MESSAGEBOX
Q_Q(QFileDialog); Q_Q(QFileDialog);
if (!(p & QFile::WriteUser) && (QMessageBox::warning(q_func(), QFileDialog::tr("Delete"), if (!(p & QFile::WriteUser) && (QMessageBox::warning(q_func(), QFileDialog::tr("Delete"),
QFileDialog::tr("'%1' is write protected.\nDo you want to delete it anyway?") QFileDialog::tr("'%1' is write protected.\nDo you want to delete it anyway?")
.arg(fileName), .arg(fileName),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No)) QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No))
return; return;
else if (QMessageBox::warning(q_func(), QFileDialog::tr("Delete"), else if (QMessageBox::warning(q_func(), QFileDialog::tr("Delete"),
QFileDialog::tr("Are you sure you want to delete '%1'?") QFileDialog::tr("Are you sure you want to delete '%1'?")
.arg(fileName), .arg(fileName),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No)
return; return;
#else #else
if (!(p & QFile::WriteUser)) if (!(p & QFile::WriteUser))
return; return;
#endif // QT_NO_MESSAGEBOX #endif // QT_NO_MESSAGEBOX
// the event loop has run, we can NOT reuse index because the model might have removed it. // the event loop has run, we can NOT reuse index because the model might have removed it.

View File

@ -1903,7 +1903,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title)
"<p>Qt and the Qt logo are trademarks of The Qt Company Ltd.</p>" "<p>Qt and the Qt logo are trademarks of The Qt Company Ltd.</p>"
"<p>Qt is The Qt Company Ltd product developed as an open source " "<p>Qt is The Qt Company Ltd product developed as an open source "
"project. See <a href=\"http://%3/\">%3</a> for more information.</p>" "project. See <a href=\"http://%3/\">%3</a> for more information.</p>"
).arg(QStringLiteral("2015"), ).arg(QStringLiteral("2016"),
QStringLiteral("qt.io/licensing"), QStringLiteral("qt.io/licensing"),
QStringLiteral("qt.io")); QStringLiteral("qt.io"));
QMessageBox *msgBox = new QMessageBox(parent); QMessageBox *msgBox = new QMessageBox(parent);

View File

@ -45,8 +45,6 @@
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
#ifdef QT_MAC_USE_COCOA
//![0] //![0]
SearchWidget::SearchWidget(QWidget *parent) SearchWidget::SearchWidget(QWidget *parent)
: QMacCocoaViewContainer(0, parent) : QMacCocoaViewContainer(0, parent)
@ -82,57 +80,6 @@ QSize SearchWidget::sizeHint() const
return QSize(150, 40); return QSize(150, 40);
} }
#else
// The SearchWidget class wraps a native HISearchField.
SearchWidget::SearchWidget(QWidget *parent)
:QWidget(parent)
{
// Create a native search field and pass its window id to QWidget::create.
searchFieldText = CFStringCreateWithCString(0, "search", 0);
HISearchFieldCreate(NULL/*bounds*/, kHISearchFieldAttributesSearchIcon | kHISearchFieldAttributesCancel,
NULL/*menu ref*/, searchFieldText, &searchField);
create(reinterpret_cast<WId>(searchField));
// Use a Qt menu for the search field menu.
QMenu *searchMenu = createMenu(this);
MenuRef menuRef = searchMenu->macMenu(0);
HISearchFieldSetSearchMenu(searchField, menuRef);
setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
}
SearchWidget::~SearchWidget()
{
CFRelease(searchField);
CFRelease(searchFieldText);
}
// Get the size hint from the search field.
QSize SearchWidget::sizeHint() const
{
EventRef event;
HIRect optimalBounds;
CreateEvent(0, kEventClassControl,
kEventControlGetOptimalBounds,
GetCurrentEventTime(),
kEventAttributeUserEvent, &event);
SendEventToEventTargetWithOptions(event,
HIObjectGetEventTarget(HIObjectRef(winId())),
kEventTargetDontPropagate);
GetEventParameter(event,
kEventParamControlOptimalBounds, typeHIRect,
0, sizeof(HIRect), 0, &optimalBounds);
ReleaseEvent(event);
return QSize(optimalBounds.size.width + 100, // make it a bit wider.
optimalBounds.size.height);
}
#endif
QMenu *createMenu(QWidget *parent) QMenu *createMenu(QWidget *parent)
{ {
QMenu *searchMenu = new QMenu(parent); QMenu *searchMenu = new QMenu(parent);

View File

@ -1181,8 +1181,8 @@ void QGraphicsViewPrivate::updateInputMethodSensitivity()
if (!proxy) { if (!proxy) {
q->setInputMethodHints(focusItem->inputMethodHints()); q->setInputMethodHints(focusItem->inputMethodHints());
} else if (QWidget *widget = proxy->widget()) { } else if (QWidget *widget = proxy->widget()) {
if (QWidget *fw = widget->focusWidget()) if (QWidget *fw = widget->focusWidget())
widget = fw; widget = fw;
q->setInputMethodHints(widget->inputMethodHints()); q->setInputMethodHints(widget->inputMethodHints());
} else { } else {
q->setInputMethodHints(0); q->setInputMethodHints(0);

View File

@ -45,10 +45,10 @@
#include "qapplication.h" #include "qapplication.h"
#include "qevent.h" #include "qevent.h"
#include "qlist.h" #include "qlist.h"
#include "qdebug.h"
#include <private/qshortcutmap_p.h> #include <private/qshortcutmap_p.h>
#include <private/qapplication_p.h> #include <private/qapplication_p.h>
#include <private/qmenu_p.h> #include <private/qmenu_p.h>
#include <private/qdebug_p.h>
#define QAPP_CHECK(functionName) \ #define QAPP_CHECK(functionName) \
if (Q_UNLIKELY(!qApp)) { \ if (Q_UNLIKELY(!qApp)) { \
@ -1302,6 +1302,31 @@ bool QAction::isIconVisibleInMenu() const
return d->iconVisibleInMenu; return d->iconVisibleInMenu;
} }
#ifndef QT_NO_DEBUG_STREAM
Q_WIDGETS_EXPORT QDebug operator<<(QDebug d, const QAction *action)
{
QDebugStateSaver saver(d);
d.nospace();
d << "QAction(" << static_cast<const void *>(action);
if (action) {
d << " text=" << action->text();
if (!action->toolTip().isEmpty())
d << " toolTip=" << action->toolTip();
if (action->isCheckable())
d << " checked=" << action->isChecked();
if (!action->shortcut().isEmpty())
d << " shortcut=" << action->shortcut();
d << " menuRole=";
QtDebugUtils::formatQEnum(d, action->menuRole());
d << " visible=" << action->isVisible();
} else {
d << '0';
}
d << ')';
return d;
}
#endif // QT_NO_DEBUG_STREAM
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qaction.cpp" #include "moc_qaction.cpp"

View File

@ -209,6 +209,10 @@ private:
#endif #endif
}; };
#ifndef QT_NO_DEBUG_STREAM
Q_WIDGETS_EXPORT QDebug operator<<(QDebug, const QAction *);
#endif
QT_BEGIN_INCLUDE_NAMESPACE QT_BEGIN_INCLUDE_NAMESPACE
#include <QtWidgets/qactiongroup.h> #include <QtWidgets/qactiongroup.h>
QT_END_INCLUDE_NAMESPACE QT_END_INCLUDE_NAMESPACE

View File

@ -238,11 +238,6 @@
\property QDesktopWidget::screenCount \property QDesktopWidget::screenCount
\brief the number of screens currently available on the system. \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 \since 4.6
*/ */

View File

@ -335,7 +335,7 @@ static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidge
shown and the character will be underlined. On Windows, shortcuts shown and the character will be underlined. On Windows, shortcuts
are normally not displayed until the user presses the \uicontrol Alt are normally not displayed until the user presses the \uicontrol Alt
key, but this is a setting the user can change. On Mac, shortcuts 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 enable them. However, because mnemonic shortcuts do not fit in
with Aqua's guidelines, Qt will not show the shortcut character with Aqua's guidelines, Qt will not show the shortcut character
underlined. underlined.

View File

@ -90,6 +90,11 @@ public:
if (usesNativeWidgets || window->parent() == 0) if (usesNativeWidgets || window->parent() == 0)
return; return;
Q_Q(QWindowContainer); 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(); QWidget *p = q->parentWidget();
while (p) { while (p) {
if ( if (
@ -153,8 +158,10 @@ public:
as a child of a QAbstractScrollArea or QMdiArea, it will as a child of a QAbstractScrollArea or QMdiArea, it will
create a \l {Native Widgets vs Alien Widgets} {native window} for create a \l {Native Widgets vs Alien Widgets} {native window} for
every widget in its parent chain to allow for proper stacking and every widget in its parent chain to allow for proper stacking and
clipping in this use case. Applications with many native child clipping in this use case. Creating a native window for the window
windows may suffer from performance issues. 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: The window container has a number of known limitations:

View File

@ -404,7 +404,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
{ {
XPThemeData theme(widget, painter, QWindowsXPStylePrivate::TreeViewTheme); XPThemeData theme(widget, painter, QWindowsXPStylePrivate::TreeViewTheme);
static int decoration_size = 0; static int decoration_size = 0;
if (d->initTreeViewTheming() && theme.isValid() && !decoration_size) { if (!decoration_size && d->initTreeViewTheming() && theme.isValid()) {
XPThemeData themeSize = theme; XPThemeData themeSize = theme;
themeSize.partId = TVP_HOTGLYPH; themeSize.partId = TVP_HOTGLYPH;
themeSize.stateId = GLPS_OPENED; themeSize.stateId = GLPS_OPENED;

View File

@ -1317,8 +1317,8 @@ void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index)
if (!lineEdit) if (!lineEdit)
emit q->currentTextChanged(text); emit q->currentTextChanged(text);
#ifndef QT_NO_ACCESSIBILITY #ifndef QT_NO_ACCESSIBILITY
QAccessibleValueChangeEvent event(q, text); QAccessibleValueChangeEvent event(q, text);
QAccessible::updateAccessibility(&event); QAccessible::updateAccessibility(&event);
#endif #endif
} }
@ -2838,8 +2838,8 @@ void QComboBox::clear()
Q_D(QComboBox); Q_D(QComboBox);
d->model->removeRows(0, d->model->rowCount(d->root), d->root); d->model->removeRows(0, d->model->rowCount(d->root), d->root);
#ifndef QT_NO_ACCESSIBILITY #ifndef QT_NO_ACCESSIBILITY
QAccessibleValueChangeEvent event(this, QString()); QAccessibleValueChangeEvent event(this, QString());
QAccessible::updateAccessibility(&event); QAccessible::updateAccessibility(&event);
#endif #endif
} }
@ -2852,8 +2852,8 @@ void QComboBox::clearEditText()
if (d->lineEdit) if (d->lineEdit)
d->lineEdit->clear(); d->lineEdit->clear();
#ifndef QT_NO_ACCESSIBILITY #ifndef QT_NO_ACCESSIBILITY
QAccessibleValueChangeEvent event(this, QString()); QAccessibleValueChangeEvent event(this, QString());
QAccessible::updateAccessibility(&event); QAccessible::updateAccessibility(&event);
#endif #endif
} }
@ -2866,8 +2866,8 @@ void QComboBox::setEditText(const QString &text)
if (d->lineEdit) if (d->lineEdit)
d->lineEdit->setText(text); d->lineEdit->setText(text);
#ifndef QT_NO_ACCESSIBILITY #ifndef QT_NO_ACCESSIBILITY
QAccessibleValueChangeEvent event(this, text); QAccessibleValueChangeEvent event(this, text);
QAccessible::updateAccessibility(&event); QAccessible::updateAccessibility(&event);
#endif #endif
} }
@ -3012,8 +3012,8 @@ bool QComboBox::event(QEvent *event)
case QEvent::HoverEnter: case QEvent::HoverEnter:
case QEvent::HoverLeave: case QEvent::HoverLeave:
case QEvent::HoverMove: case QEvent::HoverMove:
if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event)) if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event))
d->updateHoverControl(he->pos()); d->updateHoverControl(he->pos());
break; break;
case QEvent::ShortcutOverride: case QEvent::ShortcutOverride:
if (d->lineEdit) if (d->lineEdit)

View File

@ -1950,12 +1950,8 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*>
qt_mac_set_drawer_preferred_edge(widget, toDockWidgetArea(dockPos)); qt_mac_set_drawer_preferred_edge(widget, toDockWidgetArea(dockPos));
} else } else
#endif #endif
if (!testing) { if (!testing)
QRect r(x, y, w, h); widget->setGeometry(QDockAreaLayout::constrainedRect(QRect(x, y, w, h), widget));
r = QDockAreaLayout::constrainedRect(r, widget);
widget->move(r.topLeft());
widget->resize(r.size());
}
if (!testing) { if (!testing) {
widget->setVisible(flags & StateFlagVisible); widget->setVisible(flags & StateFlagVisible);

View File

@ -590,7 +590,9 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason
if (reason != SelectedFromKeyboard) { if (reason != SelectedFromKeyboard) {
if (QMenu *menu = qobject_cast<QMenu*>(causedPopup.widget)) { if (QMenu *menu = qobject_cast<QMenu*>(causedPopup.widget)) {
if (causedPopup.action && menu->d_func()->activeMenu == q) 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);
} }
} }

View File

@ -104,15 +104,13 @@ void QMenu::setAsDockMenu()
/*! \fn void qt_mac_set_dock_menu(QMenu *menu) /*! \fn void qt_mac_set_dock_menu(QMenu *menu)
\since 5.2 \relates QMenu
\deprecated \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. on the application dock icon. Available on OS X only.
Deprecated; use QMenu:setAsDockMenu() instead. Deprecated; use \l QMenu::setAsDockMenu() instead.
\sa QMenu:setAsDockMenu()
*/ */
void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem* item) void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem* item)

View File

@ -485,8 +485,8 @@ bool QScrollBar::event(QEvent *event)
case QEvent::HoverEnter: case QEvent::HoverEnter:
case QEvent::HoverLeave: case QEvent::HoverLeave:
case QEvent::HoverMove: case QEvent::HoverMove:
if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event)) if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event))
d_func()->updateHoverControl(he->pos()); d_func()->updateHoverControl(he->pos());
break; break;
case QEvent::StyleChange: case QEvent::StyleChange:
d_func()->setTransient(style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, this)); d_func()->setTransient(style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, this));

View File

@ -126,7 +126,7 @@ bool QToolButtonPrivate::hasMenu() const
One classic use of a tool button is to select tools; for example, One classic use of a tool button is to select tools; for example,
the "pen" tool in a drawing program. This would be implemented 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 QToolButton supports auto-raising. In auto-raise mode, the button
draws a 3D frame only when the mouse points at it. The feature is draws a 3D frame only when the mouse points at it. The feature is
@ -153,8 +153,8 @@ bool QToolButtonPrivate::hasMenu() const
menu set. The default mode is DelayedPopupMode which is sometimes menu set. The default mode is DelayedPopupMode which is sometimes
used with the "Back" button in a web browser. After pressing and 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 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 of possible pages to jump to. The timeout is style dependent,
adjust it with setPopupDelay(). see QStyle::SH_ToolButton_PopupDelay.
\table 100% \table 100%
\row \li \inlineimage assistant-toolbar.png Qt Assistant's toolbar with tool buttons \row \li \inlineimage assistant-toolbar.png Qt Assistant's toolbar with tool buttons
@ -826,7 +826,7 @@ void QToolButtonPrivate::_q_menuTriggered(QAction *action)
a menu set or contains a list of actions. a menu set or contains a list of actions.
\value DelayedPopup After pressing and holding the tool button \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 see QStyle::SH_ToolButton_PopupDelay), the menu is displayed. A
typical application example is the "back" button in some web typical application example is the "back" button in some web
browsers's tool bars. If the user clicks it, the browser simply browsers's tool bars. If the user clicks it, the browser simply
@ -967,8 +967,8 @@ bool QToolButton::event(QEvent *event)
case QEvent::HoverEnter: case QEvent::HoverEnter:
case QEvent::HoverLeave: case QEvent::HoverLeave:
case QEvent::HoverMove: case QEvent::HoverMove:
if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event)) if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event))
d_func()->updateHoverControl(he->pos()); d_func()->updateHoverControl(he->pos());
break; break;
default: default:
break; break;

View File

@ -5,6 +5,7 @@ HEADERS = plugin1.h
SOURCES = plugin1.cpp SOURCES = plugin1.cpp
TARGET = $$qtLibraryTarget(plugin1) TARGET = $$qtLibraryTarget(plugin1)
DESTDIR = ../bin DESTDIR = ../bin
winrt:include(../winrt.pri)
# This is testdata for the tst_qpluginloader test. # This is testdata for the tst_qpluginloader test.
target.path = $$[QT_INSTALL_TESTS]/tst_qfactoryloader/bin target.path = $$[QT_INSTALL_TESTS]/tst_qfactoryloader/bin

View File

@ -5,6 +5,7 @@ HEADERS = plugin2.h
SOURCES = plugin2.cpp SOURCES = plugin2.cpp
TARGET = $$qtLibraryTarget(plugin2) TARGET = $$qtLibraryTarget(plugin2)
DESTDIR = ../bin DESTDIR = ../bin
winrt:include(../winrt.pri)
# This is testdata for the tst_qpluginloader test. # This is testdata for the tst_qpluginloader test.
target.path = $$[QT_INSTALL_TESTS]/tst_qfactoryloader/bin target.path = $$[QT_INSTALL_TESTS]/tst_qfactoryloader/bin

View File

@ -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
}
}

View File

@ -134,9 +134,11 @@ typedef int (*VersionFunction)(void);
void tst_QLibrary::initTestCase() void tst_QLibrary::initTestCase()
{ {
#ifndef Q_OS_WINRT
// chdir to our testdata directory, and use relative paths in some tests. // chdir to our testdata directory, and use relative paths in some tests.
QString testdatadir = QFileInfo(QFINDTESTDATA("library_path")).absolutePath(); QString testdatadir = QFileInfo(QFINDTESTDATA("library_path")).absolutePath();
QVERIFY2(QDir::setCurrent(testdatadir), qPrintable("Could not chdir to " + testdatadir)); QVERIFY2(QDir::setCurrent(testdatadir), qPrintable("Could not chdir to " + testdatadir));
#endif
} }
void tst_QLibrary::version_data() void tst_QLibrary::version_data()
@ -412,7 +414,7 @@ void tst_QLibrary::loadHints_data()
QString appDir = QCoreApplication::applicationDirPath(); QString appDir = QCoreApplication::applicationDirPath();
lh |= QLibrary::ResolveAllSymbolsHint; 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( "ok01 (with suffix)" ) << appDir + "/mylib.dll" << int(lh) << true;
QTest::newRow( "ok02 (with non-standard suffix)" ) << appDir + "/mylib.dl2" << 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; QTest::newRow( "ok03 (with many dots)" ) << appDir + "/system.qt.test.mylib.dll" << int(lh) << true;
@ -464,7 +466,7 @@ void tst_QLibrary::fileName_data()
QTest::newRow( "ok02" ) << sys_qualifiedLibraryName(QLatin1String("mylib")) QTest::newRow( "ok02" ) << sys_qualifiedLibraryName(QLatin1String("mylib"))
<< 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 #ifndef Q_OS_WINCE
QTest::newRow( "ok03" ) << "user32" QTest::newRow( "ok03" ) << "user32"
<< "USER32.dll"; << "USER32.dll";

View File

@ -4,6 +4,7 @@ CONFIG -= staticlib
SOURCES = mylib.c SOURCES = mylib.c
TARGET = tst_qpluginloaderlib TARGET = tst_qpluginloaderlib
DESTDIR = ../bin DESTDIR = ../bin
winrt:include(../winrt.pri)
QT = core QT = core
win32-msvc: DEFINES += WIN32_MSVC win32-msvc: DEFINES += WIN32_MSVC

View File

@ -6,6 +6,7 @@ SOURCES = theplugin.cpp
#TARGET = $$qtLibraryTarget(theplugin) #TARGET = $$qtLibraryTarget(theplugin)
TARGET = theplugin TARGET = theplugin
DESTDIR = ../bin DESTDIR = ../bin
winrt:include(../winrt.pri)
QT = core QT = core
# This is testdata for the tst_qpluginloader test. # This is testdata for the tst_qpluginloader test.

View File

@ -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
}
}

Some files were not shown because too many files have changed in this diff Show More