Merge 5.6 into 5.6.0
Change-Id: I95962e28b6fc101cbbad41230585e2b61f1f6c0f
This commit is contained in:
commit
615534f14c
@ -1,6 +1,6 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
|
||||
The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd.
|
||||
The Qt Toolkit is Copyright (C) 2016 The Qt Company Ltd.
|
||||
Contact: http://www.qt.io/licensing/
|
||||
|
||||
You may use, distribute and copy the Qt GUI Toolkit under the terms of
|
||||
|
@ -1,6 +1,6 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
|
||||
The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd.
|
||||
The Qt Toolkit is Copyright (C) 2016 The Qt Company Ltd.
|
||||
Contact: http://www.qt.io/licensing/
|
||||
|
||||
You may use, distribute and copy the Qt GUI Toolkit under the terms of
|
||||
|
@ -3,7 +3,7 @@
|
||||
dita.metadata.default.author = Qt Project
|
||||
dita.metadata.default.permissions = all
|
||||
dita.metadata.default.publisher = Qt Project
|
||||
dita.metadata.default.copyryear = 2015
|
||||
dita.metadata.default.copyryear = 2016
|
||||
dita.metadata.default.copyrholder = The Qt Company Ltd
|
||||
dita.metadata.default.audience = programmer
|
||||
|
||||
|
@ -78,7 +78,7 @@ HTML.footer += \
|
||||
" <ul id=\"menu-footer-submenu\" class=\"right clearfix\"><li id=\"menu-item-1795\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1795\"><a title=\"Sign into your account.\" href=\"https://account.qt.io/login\">Sign In</a></li>\n" \
|
||||
" <li id=\"menu-item-10375\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-10375\"><a href=\"mailto:feedback@theqtcompany.com?Subject=Feedback%20about%20doc.qt.io%20site\">Feedback</a></li>\n" \
|
||||
" <li id=\"menu-item-1494\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1494\"><a href=\"http://qt.io/contact-us/\">Contact us</a></li>\n" \
|
||||
" <li id=\"menu-item-4472\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4472\"><a href=\"http://qt.io/about-us/\">© 2015 The Qt Company</a></li>\n" \
|
||||
" <li id=\"menu-item-4472\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4472\"><a href=\"http://qt.io/about-us/\">© 2016 The Qt Company</a></li>\n" \
|
||||
" </ul>\n" \
|
||||
"</div>\n" \
|
||||
"</div>\n" \
|
||||
|
@ -8,7 +8,7 @@ HTML.footer = \
|
||||
"</div>\n" \
|
||||
"<div class=\"footer\">\n" \
|
||||
" <p>\n" \
|
||||
" <acronym title=\"Copyright\">©</acronym> 2015 The Qt Company Ltd.\n" \
|
||||
" <acronym title=\"Copyright\">©</acronym> 2016 The Qt Company Ltd.\n" \
|
||||
" Documentation contributions included herein are the copyrights of\n" \
|
||||
" their respective owners.<br>" \
|
||||
" The documentation provided herein is licensed under the terms of the" \
|
||||
|
@ -5,7 +5,7 @@
|
||||
HTML.footer = \
|
||||
" </div>\n" \
|
||||
" <p class=\"copy-notice\">\n" \
|
||||
" <acronym title=\"Copyright\">©</acronym> 2015 The Qt Company Ltd.\n" \
|
||||
" <acronym title=\"Copyright\">©</acronym> 2016 The Qt Company Ltd.\n" \
|
||||
" Documentation contributions included herein are the copyrights of\n" \
|
||||
" their respective owners. " \
|
||||
" The documentation provided herein is licensed under the terms of the" \
|
||||
|
@ -5,6 +5,7 @@ body {
|
||||
text-align: left;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
p {
|
||||
|
@ -28,9 +28,8 @@
|
||||
/*!
|
||||
\example desktop/systray
|
||||
\title System Tray Icon Example
|
||||
|
||||
|
||||
The System Tray Icon example shows how to add an icon with a menu
|
||||
\ingroup examples-widgets
|
||||
\brief The System Tray Icon example shows how to add an icon with a menu
|
||||
and popup messages to a desktop environment's system tray.
|
||||
|
||||
\image systemtray-example.png Screenshot of the System Tray Icon.
|
||||
@ -47,7 +46,7 @@
|
||||
|
||||
The editor allows the user to choose the preferred icon as well as
|
||||
set the balloon message's type and duration. The user can also
|
||||
edit the message's title and body. Finally, the editor provide a
|
||||
edit the message's title and body. Finally, the editor provides a
|
||||
checkbox controlling whether the icon is actually shown in the
|
||||
system tray, or not.
|
||||
|
||||
@ -65,8 +64,8 @@
|
||||
check whether a system tray is present on the user's desktop, call
|
||||
the static QSystemTrayIcon::isSystemTrayAvailable()
|
||||
function. Associated with the icon, we provide a menu containing
|
||||
the typical \gui minimize, \gui maximize, \gui restore and \gui
|
||||
quit actions. We reimplement the QWidget::setVisible() function to
|
||||
the typical \uicontrol minimize, \uicontrol maximize, \uicontrol restore and
|
||||
\uicontrol quit actions. We reimplement the QWidget::setVisible() function to
|
||||
update the tray icon's menu whenever the editor's appearance
|
||||
changes, e.g., when maximizing or minimizing the main application
|
||||
window.
|
||||
@ -74,7 +73,7 @@
|
||||
Finally, we reimplement QWidget's \l {QWidget::}{closeEvent()}
|
||||
function to be able to inform the user (when closing the editor
|
||||
window) that the program will keep running in the system tray
|
||||
until the user chooses the \gui Quit entry in the icon's context
|
||||
until the user chooses the \uicontrol Quit entry in the icon's context
|
||||
menu.
|
||||
|
||||
\section1 Window Class Implementation
|
||||
|
@ -28,6 +28,8 @@
|
||||
/*!
|
||||
\example draganddrop/fridgemagnets
|
||||
\title Fridge Magnets Example
|
||||
\brief The Fridge Magnets example illustrates how to move around several types of
|
||||
MIME-encoded data with drag and drop.
|
||||
|
||||
The Fridge Magnets example shows how to supply more than one type
|
||||
of MIME-encoded data with a drag and drop operation.
|
||||
|
@ -1,179 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:FDL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Free Documentation License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Free
|
||||
** Documentation License version 1.3 as published by the Free Software
|
||||
** Foundation and appearing in the file included in the packaging of
|
||||
** this file. Please review the following information to ensure
|
||||
** the GNU Free Documentation License version 1.3 requirements
|
||||
** will be met: http://www.gnu.org/copyleft/fdl.html.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/*!
|
||||
\example desktop/systray
|
||||
\title System Tray Icon Example
|
||||
\ingroup examples-widgets
|
||||
\brief The System Tray Icon example shows how to add an icon with a menu
|
||||
and popup messages to a desktop environment's system tray.
|
||||
|
||||
\image systemtray-example.png Screenshot of the System Tray Icon.
|
||||
|
||||
Modern operating systems usually provide a special area on the
|
||||
desktop, called the system tray or notification area, where
|
||||
long-running applications can display icons and short messages.
|
||||
|
||||
This example consists of one single class, \c Window, providing
|
||||
the main application window (i.e., an editor for the system tray
|
||||
icon) and the associated icon.
|
||||
|
||||
\image systemtray-editor.png
|
||||
|
||||
The editor allows the user to choose the preferred icon as well as
|
||||
set the balloon message's type and duration. The user can also
|
||||
edit the message's title and body. Finally, the editor provides a
|
||||
checkbox controlling whether the icon is actually shown in the
|
||||
system tray, or not.
|
||||
|
||||
\section1 Window Class Definition
|
||||
|
||||
The \c Window class inherits QWidget:
|
||||
|
||||
\snippet desktop/systray/window.h 0
|
||||
|
||||
We implement several private slots to respond to user
|
||||
interaction. The other private functions are only convenience
|
||||
functions provided to simplify the constructor.
|
||||
|
||||
The tray icon is an instance of the QSystemTrayIcon class. To
|
||||
check whether a system tray is present on the user's desktop, call
|
||||
the static QSystemTrayIcon::isSystemTrayAvailable()
|
||||
function. Associated with the icon, we provide a menu containing
|
||||
the typical \uicontrol minimize, \uicontrol maximize, \uicontrol restore and
|
||||
\uicontrol quit actions. We reimplement the QWidget::setVisible() function
|
||||
to update the tray icon's menu whenever the editor's appearance
|
||||
changes, e.g., when maximizing or minimizing the main application
|
||||
window.
|
||||
|
||||
Finally, we reimplement QWidget's \l {QWidget::}{closeEvent()}
|
||||
function to be able to inform the user (when closing the editor
|
||||
window) that the program will keep running in the system tray
|
||||
until the user chooses the \uicontrol Quit entry in the icon's context
|
||||
menu.
|
||||
|
||||
\section1 Window Class Implementation
|
||||
|
||||
When constructing the editor widget, we first create the various
|
||||
editor elements before we create the actual system tray icon:
|
||||
|
||||
\snippet desktop/systray/window.cpp 0
|
||||
|
||||
We ensure that the application responds to user input by
|
||||
connecting most of the editor's input widgets (including the
|
||||
system tray icon) to the application's private slots. But note the
|
||||
visibility checkbox; its \l {QCheckBox::}{toggled()} signal is
|
||||
connected to the \e {icon}'s \l {QSystemTrayIcon::}{setVisible()}
|
||||
function instead.
|
||||
|
||||
\snippet desktop/systray/window.cpp 3
|
||||
|
||||
The \c setIcon() slot is triggered whenever the current index in
|
||||
the icon combobox changes, i.e., whenever the user chooses another
|
||||
icon in the editor. Note that it is also called when the user
|
||||
activates the tray icon with the left mouse button, triggering the
|
||||
icon's \l {QSystemTrayIcon::}{activated()} signal. We will come
|
||||
back to this signal shortly.
|
||||
|
||||
The QSystemTrayIcon::setIcon() function sets the \l
|
||||
{QSystemTrayIcon::}{icon} property that holds the actual system
|
||||
tray icon. On Windows, the system tray icon size is 16x16; on X11,
|
||||
the preferred size is 22x22. The icon will be scaled to the
|
||||
appropriate size as necessary.
|
||||
|
||||
Note that on X11, due to a limitation in the system tray
|
||||
specification, mouse clicks on transparent areas in the icon are
|
||||
propagated to the system tray. If this behavior is unacceptable,
|
||||
we suggest using an icon with no transparency.
|
||||
|
||||
\snippet desktop/systray/window.cpp 4
|
||||
|
||||
Whenever the user activates the system tray icon, it emits its \l
|
||||
{QSystemTrayIcon::}{activated()} signal passing the triggering
|
||||
reason as parameter. QSystemTrayIcon provides the \l
|
||||
{QSystemTrayIcon::}{ActivationReason} enum to describe how the
|
||||
icon was activated.
|
||||
|
||||
In the constructor, we connected our icon's \l
|
||||
{QSystemTrayIcon::}{activated()} signal to our custom \c
|
||||
iconActivated() slot: If the user has clicked the icon using the
|
||||
left mouse button, this function changes the icon image by
|
||||
incrementing the icon combobox's current index, triggering the \c
|
||||
setIcon() slot as mentioned above. If the user activates the icon
|
||||
using the middle mouse button, it calls the custom \c
|
||||
showMessage() slot:
|
||||
|
||||
\snippet desktop/systray/window.cpp 5
|
||||
|
||||
When the \e showMessage() slot is triggered, we first retrieve the
|
||||
message icon depending on the currently chosen message type. The
|
||||
QSystemTrayIcon::MessageIcon enum describes the icon that is shown
|
||||
when a balloon message is displayed. Then we call
|
||||
QSystemTrayIcon's \l {QSystemTrayIcon::}{showMessage()} function
|
||||
to show the message with the title, body, and icon for the time
|
||||
specified in milliseconds.
|
||||
|
||||
QSystemTrayIcon also has the corresponding, \l {QSystemTrayIcon::}
|
||||
{messageClicked()} signal, which is emitted when the user clicks a
|
||||
message displayed by \l {QSystemTrayIcon::}{showMessage()}.
|
||||
|
||||
\snippet desktop/systray/window.cpp 6
|
||||
|
||||
In the constructor, we connected the \l
|
||||
{QSystemTrayIcon::}{messageClicked()} signal to our custom \c
|
||||
messageClicked() slot that simply displays a message using the
|
||||
QMessageBox class.
|
||||
|
||||
QMessageBox provides a modal dialog with a short message, an icon,
|
||||
and buttons laid out depending on the current style. It supports
|
||||
four severity levels: "Question", "Information", "Warning" and
|
||||
"Critical". The easiest way to pop up a message box in Qt is to
|
||||
call one of the associated static functions, e.g.,
|
||||
QMessageBox::information().
|
||||
|
||||
As we mentioned earlier, we reimplement a couple of QWidget's
|
||||
virtual functions:
|
||||
|
||||
\snippet desktop/systray/window.cpp 1
|
||||
|
||||
Our reimplementation of the QWidget::setVisible() function updates
|
||||
the tray icon's menu whenever the editor's appearance changes,
|
||||
e.g., when maximizing or minimizing the main application window,
|
||||
before calling the base class implementation.
|
||||
|
||||
\snippet desktop/systray/window.cpp 2
|
||||
|
||||
We have reimplemented the QWidget::closeEvent() event handler to
|
||||
receive widget close events, showing the above message to the
|
||||
users when they are closing the editor window.
|
||||
|
||||
In addition to the functions and slots discussed above, we have
|
||||
also implemented several convenience functions to simplify the
|
||||
constructor: \c createIconGroupBox(), \c createMessageGroupBox(),
|
||||
\c createActions() and \c createTrayIcon(). See the \l
|
||||
{desktop/systray/window.cpp}{window.cpp} file for details.
|
||||
*/
|
@ -34,41 +34,41 @@
|
||||
\image tabletexample.png
|
||||
|
||||
When you use a tablet with Qt applications, \l{QTabletEvent}s are
|
||||
generated. You need to reimplement the
|
||||
\l{QWidget::}{tabletEvent()} event handler if you want to handle
|
||||
tablet events. Events are generated when the device used for
|
||||
drawing enters and leaves the proximity of the tablet (i.e., when
|
||||
it is close but not pressed down on it), when a device is pushed
|
||||
down and released from it, and when a device is moved on the
|
||||
tablet.
|
||||
generated. You need to reimplement the \l{QWidget::}{tabletEvent()} event
|
||||
handler if you want to handle tablet events. Events are generated when the
|
||||
tool (stylus) used for drawing enters and leaves the proximity of the
|
||||
tablet (i.e., when it is close but not pressed down on it), when the tool
|
||||
is pressed down and released from it, when the tool is moved across the
|
||||
tablet, and when one of the buttons on the tool is pressed or released.
|
||||
|
||||
The information available in QTabletEvent depends on the device
|
||||
used. The tablet in this example has two different devices for
|
||||
drawing: a stylus and an airbrush. For both devices the event
|
||||
contains the position of the device, pressure on the tablet,
|
||||
vertical tilt, and horizontal tilt (i.e, the angle between the
|
||||
device and the perpendicular of the tablet). The airbrush has a
|
||||
finger wheel; the position of this is also available in the tablet
|
||||
event.
|
||||
The information available in QTabletEvent depends on the device used.
|
||||
This example can handle a tablet with up to three different drawing tools:
|
||||
a stylus, an airbrush, and an art pen. For any of these the event will
|
||||
contain the position of the tool, pressure on the tablet, button status,
|
||||
vertical tilt, and horizontal tilt (i.e, the angle between the device and
|
||||
the perpendicular of the tablet, if the tablet hardware can provide it).
|
||||
The airbrush has a finger wheel; the position of this is also available
|
||||
in the tablet event. The art pen provides rotation around the axis
|
||||
perpendicular to the tablet surface, so that it can be used for calligraphy.
|
||||
|
||||
In this example we implement a drawing program. You can use the
|
||||
stylus to draw on the tablet as you use a pencil on paper. When
|
||||
you draw with the airbrush you get a spray of paint; the finger
|
||||
wheel is used to change the density of the spray. The pressure and
|
||||
tilt can change the alpha and saturation values of the QColor and the
|
||||
width of the QPen used for drawing.
|
||||
In this example we implement a drawing program. You can use the stylus to
|
||||
draw on the tablet as you use a pencil on paper. When you draw with the
|
||||
airbrush you get a spray of virtual paint; the finger wheel is used to
|
||||
change the density of the spray. When you draw with the art pen, you get a
|
||||
a line whose width and endpoint angle depend on the rotation of the pen.
|
||||
The pressure and tilt can also be assigned to change the alpha and
|
||||
saturation values of the color and the width of the stroke.
|
||||
|
||||
The example consists of the following:
|
||||
|
||||
\list
|
||||
\li The \c MainWindow class inherits QMainWindow and creates
|
||||
the examples menus and connect their slots and signals.
|
||||
\li The \c MainWindow class inherits QMainWindow, creates
|
||||
the menus, and connects their slots and signals.
|
||||
\li The \c TabletCanvas class inherits QWidget and
|
||||
receives tablet events. It uses the events to paint on a
|
||||
offscreen pixmap, which it draws onto itself.
|
||||
receives tablet events. It uses the events to paint onto an
|
||||
offscreen pixmap, and then renders it.
|
||||
\li The \c TabletApplication class inherits QApplication. This
|
||||
class handles tablet events that are not sent to \c tabletEvent().
|
||||
We will look at this later.
|
||||
class handles tablet proximity events.
|
||||
\li The \c main() function creates a \c MainWindow and shows it
|
||||
as a top level window.
|
||||
\endlist
|
||||
@ -81,110 +81,99 @@
|
||||
|
||||
\snippet widgets/tablet/mainwindow.h 0
|
||||
|
||||
The QActions let the user select if the tablets pressure and
|
||||
tilt should change the pen width, color alpha component and color
|
||||
saturation. \c createActions() creates all actions, and \c
|
||||
createMenus() sets up the menus with the actions. We have one
|
||||
QActionGroup for the actions that alter the alpha channel, color
|
||||
saturation and line width respectively. The action groups are
|
||||
connected to the \c alphaActionTriggered(), \c
|
||||
colorSaturationActiontriggered(), and \c
|
||||
lineWidthActionTriggered() slots, which calls functions in \c
|
||||
myCanvas.
|
||||
|
||||
\c createMenus() sets up the menus with the actions. We have one
|
||||
QActionGroup for the actions that alter the alpha channel, color saturation
|
||||
and line width respectively. The action groups are connected to the
|
||||
\c setAlphaValuator(), \c setSaturationValuator(), and
|
||||
\c setLineWidthValuator() slots, which call functions in \c TabletCanvas.
|
||||
|
||||
\section1 MainWindow Class Implementation
|
||||
|
||||
We start width a look at the constructor \c MainWindow():
|
||||
We start with a look at the constructor \c MainWindow():
|
||||
|
||||
\snippet widgets/tablet/mainwindow.cpp 0
|
||||
|
||||
In the constructor we create the canvas, actions, and menus.
|
||||
We set the canvas as the center widget. We also initialize the
|
||||
canvas to match the state of our menus and start drawing with a
|
||||
red color.
|
||||
In the constructor we call \c createMenus() to create all the actions and
|
||||
menus, and set the canvas as the center widget.
|
||||
|
||||
Here is the implementation of \c brushColorAct():
|
||||
\snippet widgets/tablet/mainwindow.cpp 8
|
||||
|
||||
\snippet widgets/tablet/mainwindow.cpp 1
|
||||
At the beginning of \c createMenus() we populate the \b File menu.
|
||||
We use an overload of \l{QMenu::}{addAction()}, introduced in Qt 5.6, to create
|
||||
a menu item with a shortcut (and optionally an icon), add it to its menu,
|
||||
and connect it to a slot, all with one line of code. We use QKeySequence to
|
||||
get the platform-specific standard key shortcuts for these common menu items.
|
||||
|
||||
We let the user pick a color with a QColorDialog. If it is valid,
|
||||
we set a new drawing color with \c setColor().
|
||||
We also populate the \b Brush menu. The command to change a brush does not
|
||||
normally have a standard shortcut, so we use \l{QObject::}{tr()} to enable
|
||||
translating the shortcut along with the language translation of the application.
|
||||
|
||||
Here is the implementation of \c alphaActionTriggered():
|
||||
Now we will look at the creation of one group of mutually-exclusive actions
|
||||
in a submenu of the \b Tablet menu, for selecting which property of each
|
||||
QTabletEvent will be used to vary the translucency (alpha channel) of the
|
||||
line being drawn or color being airbrushed.
|
||||
(See the \l{Application Example}{application example} if you want a
|
||||
high-level introduction to QActions.)
|
||||
|
||||
\snippet widgets/tablet/mainwindow.cpp 9
|
||||
|
||||
We want the user to be able to choose whether the drawing color's alpha
|
||||
component should be modulated by the tablet pressure, tilt, or the position
|
||||
of the thumbwheel on the airbrush tool. We have one action for each choice,
|
||||
and an additional action to choose not to change the alpha, that is, to keep
|
||||
the color opaque. We make the actions checkable; the \c alphaChannelGroup
|
||||
will then ensure that only one of the actions are checked at any time. The
|
||||
\c triggered() signal is emitted from the group when an action is checked,
|
||||
so we connect that to \c MainWindow::setAlphaValuator(). It will need to know
|
||||
which property (valuator) of the QTabletEvent to pay attention to from now
|
||||
on, so we use the QAction::data property to pass this information along.
|
||||
(In order for this to be possible, the enum \c Valuator must be a registered
|
||||
metatype, so that it can be inserted into a QVariant. That is accomplished
|
||||
by the \c Q_ENUM declaration in tabletcanvas.h.)
|
||||
|
||||
Here is the implementation of \c setAlphaValuator():
|
||||
|
||||
\snippet widgets/tablet/mainwindow.cpp 2
|
||||
|
||||
The \c TabletCanvas class supports two ways by which the alpha
|
||||
channel of the drawing color can be changed: tablet pressure and
|
||||
tilt. We have one action for each and an action if the alpha
|
||||
channel should not be changed.
|
||||
It simply needs to retrieve the \c Valuator enum from QAction::data(), and
|
||||
pass that to \c TabletCanvas::setAlphaChannelValuator(). If we were not
|
||||
using the \c data property, we would instead need to compare the QAction
|
||||
pointer itself, for example in a switch statement. But that would require
|
||||
keeping pointers to each QAction in class variables, for comparison purposes.
|
||||
|
||||
Here is the implementation of \c lineWidthActionTriggered():
|
||||
Here is the implementation of \c setBrushColor():
|
||||
|
||||
\snippet widgets/tablet/mainwindow.cpp 3
|
||||
\snippet widgets/tablet/mainwindow.cpp 1
|
||||
|
||||
We check which action is selected in \c lineWidthGroup, and set
|
||||
how the canvas should change the drawing line width.
|
||||
We do lazy initialization of a QColorDialog the first time the user
|
||||
chooses \b {Brush color...} from the menu or via the action shortcut.
|
||||
While the dialog is open, each time the user chooses a different color,
|
||||
\c TabletCanvas::setColor() will be called to change the drawing color.
|
||||
Because it is a non-modal dialog, the user is free to leave the color
|
||||
dialog open, so as to be able to conveniently and frequently change colors,
|
||||
or close it and re-open it later.
|
||||
|
||||
Here is the implementation of \c saturationActionTriggered():
|
||||
|
||||
\snippet widgets/tablet/mainwindow.cpp 4
|
||||
|
||||
We check which action is selected in \c colorSaturationGroup, and
|
||||
set how the canvas should change the color saturation of the
|
||||
drawing color.
|
||||
|
||||
Here is the implementation of \c saveAct():
|
||||
Here is the implementation of \c save():
|
||||
|
||||
\snippet widgets/tablet/mainwindow.cpp 5
|
||||
|
||||
We use the QFileDialog to let the user select a file to save the
|
||||
drawing in. It is the \c TabletCanvas that save the drawing, so we
|
||||
call its \c saveImage() function.
|
||||
We use the QFileDialog to let the user select a file to save the drawing,
|
||||
and then call \c TabletCanvas::saveImage() to actually write it to the
|
||||
file.
|
||||
|
||||
Here is the implementation of \c loadAct():
|
||||
Here is the implementation of \c load():
|
||||
|
||||
\snippet widgets/tablet/mainwindow.cpp 6
|
||||
|
||||
We let the user select the image file to be opened with
|
||||
a QFileDialog; we then ask the canvas to load the image with \c
|
||||
loadImage().
|
||||
We let the user select the image file to be opened with a QFileDialog; we
|
||||
then ask the canvas to load the image with \c loadImage().
|
||||
|
||||
Here is the implementation of \c aboutAct():
|
||||
Here is the implementation of \c about():
|
||||
|
||||
\snippet widgets/tablet/mainwindow.cpp 7
|
||||
|
||||
We show a message box with a short description of the example.
|
||||
|
||||
\c createActions() creates all actions and action groups of
|
||||
the example. We look at the creation of one action group and its
|
||||
actions. See the \l{Application Example}{application example} if
|
||||
you want a high-level introduction to QActions.
|
||||
|
||||
Here is the implementation of \c createActions:
|
||||
|
||||
\snippet widgets/tablet/mainwindow.cpp 8
|
||||
\dots
|
||||
\snippet widgets/tablet/mainwindow.cpp 9
|
||||
|
||||
We want the user to be able to choose if the drawing color's
|
||||
alpha component should be changed by the tablet pressure or tilt.
|
||||
We have one action for each choice and an action if the alpha
|
||||
channel is not to be changed, i.e, the color is opaque. We make
|
||||
the actions checkable; the \c alphaChannelGroup will then ensure
|
||||
that only one of the actions are checked at any time. The \c
|
||||
triggered() signal is emitted when an action is checked.
|
||||
|
||||
\dots
|
||||
\snippet widgets/tablet/mainwindow.cpp 10
|
||||
|
||||
Here is the implementation of \c createMenus():
|
||||
|
||||
\snippet widgets/tablet/mainwindow.cpp 11
|
||||
|
||||
We create the menus of the example and add the actions to them.
|
||||
|
||||
|
||||
\section1 TabletCanvas Class Definition
|
||||
|
||||
@ -193,24 +182,22 @@
|
||||
|
||||
\snippet widgets/tablet/tabletcanvas.h 0
|
||||
|
||||
The canvas can change the alpha channel, color saturation,
|
||||
and line width of the drawing. We have one enum for each of
|
||||
these; their values decide if it is the tablet pressure or tilt
|
||||
that will alter them. We keep a private variable for each, the \c
|
||||
alphaChannelType, \c colorSturationType, and \c penWidthType,
|
||||
which we provide access functions for.
|
||||
The canvas can change the alpha channel, color saturation, and line width
|
||||
of the stroke. We have an enum listing the QTabletEvent properties with
|
||||
which it is possible to modulate them. We keep a private variable for each:
|
||||
\c m_alphaChannelValuator, \c m_colorSaturationValuator and
|
||||
\c m_lineWidthValuator, and we provide accessor functions for them.
|
||||
|
||||
We draw on a QPixmap with \c myPen and \c myBrush using \c
|
||||
myColor. The \c saveImage() and \c loadImage() saves and loads
|
||||
the QPixmap to disk. The pixmap is drawn on the widget in \c
|
||||
paintEvent(). The \c pointerType and \c deviceType keeps the type
|
||||
of pointer, which is either a pen or an eraser, and device
|
||||
currently used on the tablet, which is either a stylus or an
|
||||
airbrush.
|
||||
We draw on a QPixmap with \c m_pen and \c m_brush using \c m_color.
|
||||
Each time a QTabletEvent is received, the stroke is drawn from
|
||||
\c lastPoint to the point given in the current QTabletEvent,
|
||||
and then the position and rotation are saved in \c lastPoint for next time.
|
||||
The \c saveImage() and \c loadImage() functions save and load the QPixmap to disk.
|
||||
The pixmap is drawn on the widget in \c paintEvent().
|
||||
|
||||
The interpretation of events from the tablet is done in \c
|
||||
tabletEvent(); \c paintPixmap(), \c updateBrush(), and \c
|
||||
brushPattern() are helper functions used by \c tabletEvent().
|
||||
The interpretation of events from the tablet is done in \c tabletEvent(), and
|
||||
\c paintPixmap(), \c updateBrush(), and \c updateCursor() are helper
|
||||
functions used by \c tabletEvent().
|
||||
|
||||
|
||||
\section1 TabletCanvas Class Implementation
|
||||
@ -233,21 +220,28 @@
|
||||
|
||||
\snippet widgets/tablet/tabletcanvas.cpp 2
|
||||
|
||||
We simply call \l{QPixmap::}{load()}, which loads the image in \a
|
||||
file.
|
||||
We simply call \l{QPixmap::}{load()}, which loads the image from \a file.
|
||||
|
||||
Here is the implementation of \c tabletEvent():
|
||||
|
||||
\snippet widgets/tablet/tabletcanvas.cpp 3
|
||||
|
||||
We get three kind of events to this function: TabletPress,
|
||||
TabletRelease, and TabletMove, which is generated when a device
|
||||
is pressed down on, leaves, or moves on the tablet. We set the \c
|
||||
deviceDown to true when a device is pressed down on the tablet;
|
||||
we then know when we should draw when we receive move events. We
|
||||
have implemented the \c updateBrush() and \c paintPixmap() helper
|
||||
functions to update \c myBrush and \c myPen after the state of \c
|
||||
alphaChannelType, \c colorSaturationType, and \c lineWidthType.
|
||||
We get three kind of events to this function: \c TabletPress, \c TabletRelease,
|
||||
and \c TabletMove, which are generated when a drawing tool is pressed down on,
|
||||
lifed up from, or moved across the tablet. We set \c m_deviceDown to \c true
|
||||
when a device is pressed down on the tablet; we then know that we should
|
||||
draw when we receive move events. We have implemented \c updateBrush()
|
||||
to update \c m_brush and \c m_pen depending on which of the tablet event
|
||||
properties the user has chosen to pay attention to. The \c updateCursor()
|
||||
function selects a cursor to represent the drawing tool in use, so that
|
||||
as you hover with the tool in proximity of the tablet, you can see what
|
||||
kind of stroke you are about to make.
|
||||
|
||||
\snippet widgets/tablet/tabletcanvas.cpp 12
|
||||
|
||||
If an art pen (\c RotationStylus) is in use, \c updateCursor()
|
||||
is also called for each \c TabletMove event, and renders a rotated cursor
|
||||
so that you can see the angle of the pen tip.
|
||||
|
||||
Here is the implementation of \c paintEvent():
|
||||
|
||||
@ -259,22 +253,22 @@
|
||||
|
||||
\snippet widgets/tablet/tabletcanvas.cpp 5
|
||||
|
||||
In this function we draw on the pixmap based on the movement of the device.
|
||||
If the device used on the tablet is a stylus, we want to draw a line from
|
||||
In this function we draw on the pixmap based on the movement of the tool.
|
||||
If the tool used on the tablet is a stylus, we want to draw a line from
|
||||
the last-known position to the current position. We also assume that this
|
||||
is a reasonable handling of any unknown device, but update the status bar
|
||||
with a warning. If it is an airbrush, we want to draw a circle filled with
|
||||
a soft gradient, whose density can depend on various event parameters.
|
||||
By default it depends on the tangential pressure, which is the position of
|
||||
the finger wheel on the airbrush. If it is a rotation stylus, we simulate
|
||||
a felt marker by drawing trapezoidal strokes.
|
||||
the finger wheel on the airbrush. If the tool is a rotation stylus, we
|
||||
simulate a felt marker by drawing trapezoidal stroke segments.
|
||||
|
||||
\snippet widgets/tablet/tabletcanvas.cpp 6
|
||||
|
||||
In \c updateBrush() we set the pen and brush used for drawing
|
||||
to match \c alphaChannelType, \c lineWidthType, \c
|
||||
colorSaturationType, and \c myColor. We will examine the code to
|
||||
set up \c myBrush and \c myPen for each of these variables:
|
||||
In \c updateBrush() we set the pen and brush used for drawing to match
|
||||
\c m_alphaChannelValuator, \c m_lineWidthValuator, \c m_colorSaturationValuator,
|
||||
and \c m_color. We will examine the code to set up \c m_brush and
|
||||
\c m_pen for each of these variables:
|
||||
|
||||
\snippet widgets/tablet/tabletcanvas.cpp 7
|
||||
|
||||
@ -288,34 +282,33 @@
|
||||
|
||||
\snippet widgets/tablet/tabletcanvas.cpp 8
|
||||
|
||||
The alpha channel of QColor is given as a number between 0
|
||||
and 255 where 0 is transparent and 255 is opaque.
|
||||
\l{QTabletEvent::}{pressure()} returns the pressure as a qreal
|
||||
between 0.0 and 1.0. By subtracting 127 from the tilt values and
|
||||
taking the absolute value we get the smallest alpha values (i.e.,
|
||||
the color is most transparent) when the pen is perpendicular to
|
||||
the tablet. We select the largest of the vertical and horizontal
|
||||
tilt value.
|
||||
The alpha channel of QColor is given as a number between 0 and 255 where 0
|
||||
is transparent and 255 is opaque, or as a floating-point number where 0 is
|
||||
transparent and 1.0 is opaque. \l{QTabletEvent::}{pressure()} returns the
|
||||
pressure as a qreal between 0.0 and 1.0. We get the smallest alpha values
|
||||
(i.e., the color is most transparent) when the pen is perpendicular to the
|
||||
tablet. We select the largest of the vertical and horizontal tilt values.
|
||||
|
||||
\snippet widgets/tablet/tabletcanvas.cpp 9
|
||||
|
||||
The colorsaturation is given as a number between 0 and 255. It is
|
||||
set with \l{QColor::}{setHsv()}. We can set the tilt values
|
||||
directly, but must multiply the pressure to a number between 0 and
|
||||
255.
|
||||
The color saturation in the HSV color model can be given as an integer
|
||||
between 0 and 255 or as a floating-point value between 0 and 1. We chose to
|
||||
represent alpha as an integer, so we call \l{QColor::}{setHsv()} with
|
||||
integer values. That means we need to multiply the pressure to a number
|
||||
between 0 and 255.
|
||||
|
||||
\snippet widgets/tablet/tabletcanvas.cpp 10
|
||||
|
||||
The width of the pen increases with the pressure. When the pen
|
||||
width is controlled with the tilt we let the width increse with
|
||||
the angle between the device and the perpendicular of the tablet.
|
||||
The width of the pen stroke can increase with pressure, if so chosen.
|
||||
But when the pen width is controlled by tilt, we let the width increase
|
||||
with the angle between the tool and the perpendicular of the tablet.
|
||||
|
||||
\snippet widgets/tablet/tabletcanvas.cpp 11
|
||||
|
||||
We finally check whether the pointer is the stylus or the eraser.
|
||||
If it is the eraser, we set the color to the background color of
|
||||
the pixmap an let the pressure decide the pen width, else we set
|
||||
the colors we have set up previously in the function.
|
||||
the pixmap and let the pressure decide the pen width, else we set
|
||||
the colors we have decided previously in the function.
|
||||
|
||||
|
||||
\section1 TabletApplication Class Definition
|
||||
@ -325,13 +318,11 @@
|
||||
|
||||
\snippet widgets/tablet/tabletapplication.h 0
|
||||
|
||||
We keep a \c TabletCanvas we send the device type of the events we
|
||||
handle in the \c event() function to. The TabletEnterProximity
|
||||
and TabletLeaveProximity events are not sendt to the QApplication
|
||||
object, while other tablet events are sendt to the QWidget's
|
||||
\c event(), which sends them on to \l{QWidget::}{tabletEvent()}.
|
||||
Since we want to handle these events we have implemented \c
|
||||
TabletApplication.
|
||||
\c TabletApplication exists as a subclass of QApplication in order to
|
||||
receive tablet proximity events and forward them to \c TabletCanvas.
|
||||
The \c TabletEnterProximity and \c TabletLeaveProximity events are sent to
|
||||
the QApplication object, while other tablet events are sent to the QWidget's
|
||||
\c event() hander, which sends them on to \l{QWidget::}{tabletEvent()}.
|
||||
|
||||
|
||||
\section1 TabletApplication Class Implementation
|
||||
@ -340,24 +331,24 @@
|
||||
|
||||
\snippet widgets/tablet/tabletapplication.cpp 0
|
||||
|
||||
We use this function to handle the TabletEnterProximity and
|
||||
TabletLeaveProximity events, which is generated when a device
|
||||
enters and leaves the proximity of the tablet. The intended use of these
|
||||
events is to do work that is dependent on what kind of device is
|
||||
used on the tablet. This way, you don't have to do this work
|
||||
when other events are generated, which is more frequently than the
|
||||
leave and enter proximity events. We call \c setTabletDevice() in
|
||||
\c TabletCanvas.
|
||||
We use this function to handle the \c TabletEnterProximity and
|
||||
\c TabletLeaveProximity events, which are generated when a drawing
|
||||
tool enters or leaves the proximity of the tablet. Here we call
|
||||
\c TabletCanvas::setTabletDevice(), which then calls \c updateCursor(),
|
||||
which will set an appropriate cursor. This is the only reason we
|
||||
need the proximity events; for the purpose of correct drawing, it is
|
||||
enough for \c TabletCanvas to observe the \l{QTabletEvent::}{device()} and
|
||||
\l{QTabletEvent::}{pointerType()} in each event that it receives.
|
||||
|
||||
|
||||
\section1 The \c main() function
|
||||
|
||||
Here is the examples \c main() function:
|
||||
Here is the example's \c main() function:
|
||||
|
||||
\snippet widgets/tablet/main.cpp 0
|
||||
|
||||
In the \c main() function we create a \c MainWinow and display it
|
||||
as a top level window. We use the \c TabletApplication class. We
|
||||
need to set the canvas after the application is created. We cannot
|
||||
use classes that implement event handling before an QApplication
|
||||
object is instantiated.
|
||||
Here we create a \c MainWindow and display it as a top level window. We use
|
||||
the \c TabletApplication class. We need to set the canvas after the
|
||||
application is created. We cannot use classes that implement event handling
|
||||
before an QApplication object is instantiated.
|
||||
*/
|
||||
|
@ -28,6 +28,7 @@
|
||||
/*!
|
||||
\example tools/codecs
|
||||
\title Text Codecs Example
|
||||
\brief How to import and export text using text codecs.
|
||||
|
||||
The Text Codecs example demonstrates the principles behind importing and exporting text
|
||||
using codecs to ensure that characters are encoded properly, avoiding loss of data
|
||||
|
@ -45,237 +45,172 @@
|
||||
|
||||
//! [0]
|
||||
MainWindow::MainWindow(TabletCanvas *canvas)
|
||||
: m_canvas(canvas), m_colorDialog(Q_NULLPTR)
|
||||
{
|
||||
myCanvas = canvas;
|
||||
createActions();
|
||||
createMenus();
|
||||
|
||||
myCanvas->setColor(Qt::red);
|
||||
myCanvas->setLineWidthType(TabletCanvas::LineWidthPressure);
|
||||
myCanvas->setAlphaChannelType(TabletCanvas::AlphaTangentialPressure);
|
||||
myCanvas->setColorSaturationType(TabletCanvas::NoSaturation);
|
||||
|
||||
setWindowTitle(tr("Tablet Example"));
|
||||
setCentralWidget(myCanvas);
|
||||
setCentralWidget(m_canvas);
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
void MainWindow::brushColorAct()
|
||||
void MainWindow::setBrushColor()
|
||||
{
|
||||
QColor color = QColorDialog::getColor(myCanvas->color());
|
||||
|
||||
if (color.isValid())
|
||||
myCanvas->setColor(color);
|
||||
if (!m_colorDialog) {
|
||||
m_colorDialog = new QColorDialog(this);
|
||||
m_colorDialog->setModal(false);
|
||||
m_colorDialog->setCurrentColor(m_canvas->color());
|
||||
connect(m_colorDialog, &QColorDialog::colorSelected, m_canvas, &TabletCanvas::setColor);
|
||||
}
|
||||
m_colorDialog->setVisible(true);
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
void MainWindow::alphaActionTriggered(QAction *action)
|
||||
void MainWindow::setAlphaValuator(QAction *action)
|
||||
{
|
||||
if (action == alphaChannelPressureAction) {
|
||||
myCanvas->setAlphaChannelType(TabletCanvas::AlphaPressure);
|
||||
} else if (action == alphaChannelTangentialPressureAction) {
|
||||
myCanvas->setAlphaChannelType(TabletCanvas::AlphaTangentialPressure);
|
||||
} else if (action == alphaChannelTiltAction) {
|
||||
myCanvas->setAlphaChannelType(TabletCanvas::AlphaTilt);
|
||||
} else {
|
||||
myCanvas->setAlphaChannelType(TabletCanvas::NoAlpha);
|
||||
}
|
||||
m_canvas->setAlphaChannelValuator(action->data().value<TabletCanvas::Valuator>());
|
||||
}
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
void MainWindow::lineWidthActionTriggered(QAction *action)
|
||||
void MainWindow::setLineWidthValuator(QAction *action)
|
||||
{
|
||||
if (action == lineWidthPressureAction) {
|
||||
myCanvas->setLineWidthType(TabletCanvas::LineWidthPressure);
|
||||
} else if (action == lineWidthTiltAction) {
|
||||
myCanvas->setLineWidthType(TabletCanvas::LineWidthTilt);
|
||||
} else {
|
||||
myCanvas->setLineWidthType(TabletCanvas::NoLineWidth);
|
||||
}
|
||||
m_canvas->setLineWidthType(action->data().value<TabletCanvas::Valuator>());
|
||||
}
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
void MainWindow::saturationActionTriggered(QAction *action)
|
||||
void MainWindow::setSaturationValuator(QAction *action)
|
||||
{
|
||||
if (action == colorSaturationVTiltAction) {
|
||||
myCanvas->setColorSaturationType(TabletCanvas::SaturationVTilt);
|
||||
} else if (action == colorSaturationHTiltAction) {
|
||||
myCanvas->setColorSaturationType(TabletCanvas::SaturationHTilt);
|
||||
} else if (action == colorSaturationPressureAction) {
|
||||
myCanvas->setColorSaturationType(TabletCanvas::SaturationPressure);
|
||||
} else {
|
||||
myCanvas->setColorSaturationType(TabletCanvas::NoSaturation);
|
||||
}
|
||||
m_canvas->setColorSaturationValuator(action->data().value<TabletCanvas::Valuator>());
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
void MainWindow::saveAct()
|
||||
void MainWindow::save()
|
||||
{
|
||||
QString path = QDir::currentPath() + "/untitled.png";
|
||||
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Picture"),
|
||||
path);
|
||||
|
||||
if (!myCanvas->saveImage(fileName))
|
||||
if (!m_canvas->saveImage(fileName))
|
||||
QMessageBox::information(this, "Error Saving Picture",
|
||||
"Could not save the image");
|
||||
}
|
||||
//! [5]
|
||||
|
||||
//! [6]
|
||||
void MainWindow::loadAct()
|
||||
void MainWindow::load()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Picture"),
|
||||
QDir::currentPath());
|
||||
|
||||
if (!myCanvas->loadImage(fileName))
|
||||
if (!m_canvas->loadImage(fileName))
|
||||
QMessageBox::information(this, "Error Opening Picture",
|
||||
"Could not open picture");
|
||||
}
|
||||
//! [6]
|
||||
|
||||
//! [7]
|
||||
void MainWindow::aboutAct()
|
||||
void MainWindow::about()
|
||||
{
|
||||
QMessageBox::about(this, tr("About Tablet Example"),
|
||||
tr("This example shows use of a Wacom tablet in Qt"));
|
||||
tr("This example shows how to use a graphics drawing tablet in Qt."));
|
||||
}
|
||||
//! [7]
|
||||
|
||||
//! [8]
|
||||
void MainWindow::createActions()
|
||||
void MainWindow::createMenus()
|
||||
{
|
||||
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
|
||||
fileMenu->addAction(tr("&Open..."), this, &MainWindow::load, QKeySequence::Open);
|
||||
fileMenu->addAction(tr("&Save As..."), this, &MainWindow::save, QKeySequence::SaveAs);
|
||||
fileMenu->addAction(tr("E&xit"), this, &MainWindow::close, QKeySequence::Quit);
|
||||
|
||||
QMenu *brushMenu = menuBar()->addMenu(tr("&Brush"));
|
||||
brushMenu->addAction(tr("&Brush Color..."), this, &MainWindow::setBrushColor, tr("Ctrl+B"));
|
||||
//! [8]
|
||||
brushColorAction = new QAction(tr("&Brush Color..."), this);
|
||||
brushColorAction->setShortcut(tr("Ctrl+C"));
|
||||
connect(brushColorAction, SIGNAL(triggered()),
|
||||
this, SLOT(brushColorAct()));
|
||||
|
||||
QMenu *tabletMenu = menuBar()->addMenu(tr("&Tablet"));
|
||||
QMenu *lineWidthMenu = tabletMenu->addMenu(tr("&Line Width"));
|
||||
|
||||
QAction *lineWidthPressureAction = lineWidthMenu->addAction(tr("&Pressure"));
|
||||
lineWidthPressureAction->setData(TabletCanvas::PressureValuator);
|
||||
lineWidthPressureAction->setCheckable(true);
|
||||
lineWidthPressureAction->setChecked(true);
|
||||
|
||||
QAction *lineWidthTiltAction = lineWidthMenu->addAction(tr("&Tilt"));
|
||||
lineWidthTiltAction->setData(TabletCanvas::TiltValuator);
|
||||
lineWidthTiltAction->setCheckable(true);
|
||||
|
||||
QAction *lineWidthFixedAction = lineWidthMenu->addAction(tr("&Fixed"));
|
||||
lineWidthFixedAction->setData(TabletCanvas::NoValuator);
|
||||
lineWidthFixedAction->setCheckable(true);
|
||||
|
||||
QActionGroup *lineWidthGroup = new QActionGroup(this);
|
||||
lineWidthGroup->addAction(lineWidthPressureAction);
|
||||
lineWidthGroup->addAction(lineWidthTiltAction);
|
||||
lineWidthGroup->addAction(lineWidthFixedAction);
|
||||
connect(lineWidthGroup, &QActionGroup::triggered, this,
|
||||
&MainWindow::setLineWidthValuator);
|
||||
|
||||
//! [9]
|
||||
alphaChannelPressureAction = new QAction(tr("&Pressure"), this);
|
||||
QMenu *alphaChannelMenu = tabletMenu->addMenu(tr("&Alpha Channel"));
|
||||
QAction *alphaChannelPressureAction = alphaChannelMenu->addAction(tr("&Pressure"));
|
||||
alphaChannelPressureAction->setData(TabletCanvas::PressureValuator);
|
||||
alphaChannelPressureAction->setCheckable(true);
|
||||
|
||||
alphaChannelTangentialPressureAction = new QAction(tr("T&angential Pressure"), this);
|
||||
QAction *alphaChannelTangentialPressureAction = alphaChannelMenu->addAction(tr("T&angential Pressure"));
|
||||
alphaChannelTangentialPressureAction->setData(TabletCanvas::TangentialPressureValuator);
|
||||
alphaChannelTangentialPressureAction->setCheckable(true);
|
||||
alphaChannelTangentialPressureAction->setChecked(true);
|
||||
|
||||
alphaChannelTiltAction = new QAction(tr("&Tilt"), this);
|
||||
QAction *alphaChannelTiltAction = alphaChannelMenu->addAction(tr("&Tilt"));
|
||||
alphaChannelTiltAction->setData(TabletCanvas::TiltValuator);
|
||||
alphaChannelTiltAction->setCheckable(true);
|
||||
|
||||
noAlphaChannelAction = new QAction(tr("No Alpha Channel"), this);
|
||||
QAction *noAlphaChannelAction = alphaChannelMenu->addAction(tr("No Alpha Channel"));
|
||||
noAlphaChannelAction->setData(TabletCanvas::NoValuator);
|
||||
noAlphaChannelAction->setCheckable(true);
|
||||
|
||||
alphaChannelGroup = new QActionGroup(this);
|
||||
QActionGroup *alphaChannelGroup = new QActionGroup(this);
|
||||
alphaChannelGroup->addAction(alphaChannelPressureAction);
|
||||
alphaChannelGroup->addAction(alphaChannelTangentialPressureAction);
|
||||
alphaChannelGroup->addAction(alphaChannelTiltAction);
|
||||
alphaChannelGroup->addAction(noAlphaChannelAction);
|
||||
connect(alphaChannelGroup, SIGNAL(triggered(QAction*)),
|
||||
this, SLOT(alphaActionTriggered(QAction*)));
|
||||
|
||||
connect(alphaChannelGroup, &QActionGroup::triggered,
|
||||
this, &MainWindow::setAlphaValuator);
|
||||
//! [9]
|
||||
colorSaturationVTiltAction = new QAction(tr("&Vertical Tilt"), this);
|
||||
|
||||
QMenu *colorSaturationMenu = tabletMenu->addMenu(tr("&Color Saturation"));
|
||||
|
||||
QAction *colorSaturationVTiltAction = colorSaturationMenu->addAction(tr("&Vertical Tilt"));
|
||||
colorSaturationVTiltAction->setData(TabletCanvas::VTiltValuator);
|
||||
colorSaturationVTiltAction->setCheckable(true);
|
||||
|
||||
colorSaturationHTiltAction = new QAction(tr("&Horizontal Tilt"), this);
|
||||
QAction *colorSaturationHTiltAction = colorSaturationMenu->addAction(tr("&Horizontal Tilt"));
|
||||
colorSaturationHTiltAction->setData(TabletCanvas::HTiltValuator);
|
||||
colorSaturationHTiltAction->setCheckable(true);
|
||||
|
||||
colorSaturationPressureAction = new QAction(tr("&Pressure"), this);
|
||||
QAction *colorSaturationPressureAction = colorSaturationMenu->addAction(tr("&Pressure"));
|
||||
colorSaturationPressureAction->setData(TabletCanvas::PressureValuator);
|
||||
colorSaturationPressureAction->setCheckable(true);
|
||||
|
||||
noColorSaturationAction = new QAction(tr("&No Color Saturation"), this);
|
||||
QAction *noColorSaturationAction = colorSaturationMenu->addAction(tr("&No Color Saturation"));
|
||||
noColorSaturationAction->setData(TabletCanvas::NoValuator);
|
||||
noColorSaturationAction->setCheckable(true);
|
||||
noColorSaturationAction->setChecked(true);
|
||||
|
||||
colorSaturationGroup = new QActionGroup(this);
|
||||
QActionGroup *colorSaturationGroup = new QActionGroup(this);
|
||||
colorSaturationGroup->addAction(colorSaturationVTiltAction);
|
||||
colorSaturationGroup->addAction(colorSaturationHTiltAction);
|
||||
colorSaturationGroup->addAction(colorSaturationPressureAction);
|
||||
colorSaturationGroup->addAction(noColorSaturationAction);
|
||||
connect(colorSaturationGroup, SIGNAL(triggered(QAction*)),
|
||||
this, SLOT(saturationActionTriggered(QAction*)));
|
||||
connect(colorSaturationGroup, &QActionGroup::triggered,
|
||||
this, &MainWindow::setSaturationValuator);
|
||||
|
||||
lineWidthPressureAction = new QAction(tr("&Pressure"), this);
|
||||
lineWidthPressureAction->setCheckable(true);
|
||||
lineWidthPressureAction->setChecked(true);
|
||||
|
||||
lineWidthTiltAction = new QAction(tr("&Tilt"), this);
|
||||
lineWidthTiltAction->setCheckable(true);
|
||||
|
||||
lineWidthFixedAction = new QAction(tr("&Fixed"), this);
|
||||
lineWidthFixedAction->setCheckable(true);
|
||||
|
||||
lineWidthGroup = new QActionGroup(this);
|
||||
lineWidthGroup->addAction(lineWidthPressureAction);
|
||||
lineWidthGroup->addAction(lineWidthTiltAction);
|
||||
lineWidthGroup->addAction(lineWidthFixedAction);
|
||||
connect(lineWidthGroup, SIGNAL(triggered(QAction*)),
|
||||
this, SLOT(lineWidthActionTriggered(QAction*)));
|
||||
|
||||
exitAction = new QAction(tr("E&xit"), this);
|
||||
exitAction->setShortcuts(QKeySequence::Quit);
|
||||
connect(exitAction, SIGNAL(triggered()),
|
||||
this, SLOT(close()));
|
||||
|
||||
loadAction = new QAction(tr("&Open..."), this);
|
||||
loadAction->setShortcuts(QKeySequence::Open);
|
||||
connect(loadAction, SIGNAL(triggered()),
|
||||
this, SLOT(loadAct()));
|
||||
|
||||
saveAction = new QAction(tr("&Save As..."), this);
|
||||
saveAction->setShortcuts(QKeySequence::SaveAs);
|
||||
connect(saveAction, SIGNAL(triggered()),
|
||||
this, SLOT(saveAct()));
|
||||
|
||||
aboutAction = new QAction(tr("A&bout"), this);
|
||||
aboutAction->setShortcut(tr("Ctrl+B"));
|
||||
connect(aboutAction, SIGNAL(triggered()),
|
||||
this, SLOT(aboutAct()));
|
||||
|
||||
aboutQtAction = new QAction(tr("About &Qt"), this);
|
||||
aboutQtAction->setShortcut(tr("Ctrl+Q"));
|
||||
connect(aboutQtAction, SIGNAL(triggered()),
|
||||
qApp, SLOT(aboutQt()));
|
||||
//! [10]
|
||||
QMenu *helpMenu = menuBar()->addMenu("&Help");
|
||||
helpMenu->addAction(tr("A&bout"), this, &MainWindow::about);
|
||||
helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
|
||||
}
|
||||
//! [10]
|
||||
|
||||
//! [11]
|
||||
void MainWindow::createMenus()
|
||||
{
|
||||
fileMenu = menuBar()->addMenu(tr("&File"));
|
||||
fileMenu->addAction(loadAction);
|
||||
fileMenu->addAction(saveAction);
|
||||
fileMenu->addSeparator();
|
||||
fileMenu->addAction(exitAction);
|
||||
|
||||
brushMenu = menuBar()->addMenu(tr("&Brush"));
|
||||
brushMenu->addAction(brushColorAction);
|
||||
|
||||
tabletMenu = menuBar()->addMenu(tr("&Tablet"));
|
||||
|
||||
lineWidthMenu = tabletMenu->addMenu(tr("&Line Width"));
|
||||
lineWidthMenu->addAction(lineWidthPressureAction);
|
||||
lineWidthMenu->addAction(lineWidthTiltAction);
|
||||
lineWidthMenu->addAction(lineWidthFixedAction);
|
||||
|
||||
alphaChannelMenu = tabletMenu->addMenu(tr("&Alpha Channel"));
|
||||
alphaChannelMenu->addAction(alphaChannelPressureAction);
|
||||
alphaChannelMenu->addAction(alphaChannelTangentialPressureAction);
|
||||
alphaChannelMenu->addAction(alphaChannelTiltAction);
|
||||
alphaChannelMenu->addAction(noAlphaChannelAction);
|
||||
|
||||
colorSaturationMenu = tabletMenu->addMenu(tr("&Color Saturation"));
|
||||
colorSaturationMenu->addAction(colorSaturationVTiltAction);
|
||||
colorSaturationMenu->addAction(colorSaturationHTiltAction);
|
||||
colorSaturationMenu->addAction(noColorSaturationAction);
|
||||
|
||||
helpMenu = menuBar()->addMenu("&Help");
|
||||
helpMenu->addAction(aboutAction);
|
||||
helpMenu->addAction(aboutQtAction);
|
||||
}
|
||||
//! [11]
|
||||
|
@ -44,10 +44,7 @@
|
||||
#include <QMainWindow>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QActionGroup;
|
||||
class QMenu;
|
||||
class QStatusBar;
|
||||
class QColorDialog;
|
||||
QT_END_NAMESPACE
|
||||
class TabletCanvas;
|
||||
|
||||
@ -60,54 +57,19 @@ public:
|
||||
MainWindow(TabletCanvas *canvas);
|
||||
|
||||
private slots:
|
||||
void brushColorAct();
|
||||
void alphaActionTriggered(QAction *action);
|
||||
void lineWidthActionTriggered(QAction *action);
|
||||
void saturationActionTriggered(QAction *action);
|
||||
void saveAct();
|
||||
void loadAct();
|
||||
void aboutAct();
|
||||
void setBrushColor();
|
||||
void setAlphaValuator(QAction *action);
|
||||
void setLineWidthValuator(QAction *action);
|
||||
void setSaturationValuator(QAction *action);
|
||||
void save();
|
||||
void load();
|
||||
void about();
|
||||
|
||||
private:
|
||||
void createActions();
|
||||
void createMenus();
|
||||
|
||||
TabletCanvas *myCanvas;
|
||||
|
||||
QAction *brushColorAction;
|
||||
QActionGroup *brushActionGroup;
|
||||
|
||||
QActionGroup *alphaChannelGroup;
|
||||
QAction *alphaChannelPressureAction;
|
||||
QAction *alphaChannelTangentialPressureAction;
|
||||
QAction *alphaChannelTiltAction;
|
||||
QAction *noAlphaChannelAction;
|
||||
|
||||
QActionGroup *colorSaturationGroup;
|
||||
QAction *colorSaturationVTiltAction;
|
||||
QAction *colorSaturationHTiltAction;
|
||||
QAction *colorSaturationPressureAction;
|
||||
QAction *noColorSaturationAction;
|
||||
|
||||
QActionGroup *lineWidthGroup;
|
||||
QAction *lineWidthPressureAction;
|
||||
QAction *lineWidthTiltAction;
|
||||
QAction *lineWidthFixedAction;
|
||||
|
||||
QAction *exitAction;
|
||||
QAction *saveAction;
|
||||
QAction *loadAction;
|
||||
|
||||
QAction *aboutAction;
|
||||
QAction *aboutQtAction;
|
||||
|
||||
QMenu *fileMenu;
|
||||
QMenu *brushMenu;
|
||||
QMenu *tabletMenu;
|
||||
QMenu *helpMenu;
|
||||
QMenu *colorSaturationMenu;
|
||||
QMenu *lineWidthMenu;
|
||||
QMenu *alphaChannelMenu;
|
||||
TabletCanvas *m_canvas;
|
||||
QColorDialog *m_colorDialog;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
|
@ -47,7 +47,7 @@ bool TabletApplication::event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::TabletEnterProximity ||
|
||||
event->type() == QEvent::TabletLeaveProximity) {
|
||||
myCanvas->setTabletDevice(static_cast<QTabletEvent *>(event));
|
||||
m_canvas->setTabletDevice(static_cast<QTabletEvent *>(event));
|
||||
return true;
|
||||
}
|
||||
return QApplication::event(event);
|
||||
|
@ -56,10 +56,10 @@ public:
|
||||
|
||||
bool event(QEvent *event) Q_DECL_OVERRIDE;
|
||||
void setCanvas(TabletCanvas *canvas)
|
||||
{ myCanvas = canvas; }
|
||||
{ m_canvas = canvas; }
|
||||
|
||||
private:
|
||||
TabletCanvas *myCanvas;
|
||||
TabletCanvas *m_canvas;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
|
@ -45,17 +45,18 @@
|
||||
|
||||
//! [0]
|
||||
TabletCanvas::TabletCanvas()
|
||||
: QWidget(Q_NULLPTR)
|
||||
, m_alphaChannelValuator(TangentialPressureValuator)
|
||||
, m_colorSaturationValuator(NoValuator)
|
||||
, m_lineWidthValuator(PressureValuator)
|
||||
, m_color(Qt::red)
|
||||
, m_brush(m_color)
|
||||
, m_pen(m_brush, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)
|
||||
, m_deviceDown(false)
|
||||
{
|
||||
resize(500, 500);
|
||||
myColor = Qt::red;
|
||||
myBrush = QBrush(myColor);
|
||||
myPen = QPen(myBrush, 1.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
|
||||
initPixmap();
|
||||
setAutoFillBackground(true);
|
||||
deviceDown = false;
|
||||
alphaChannelType = AlphaTangentialPressure;
|
||||
colorSaturationType = NoSaturation;
|
||||
lineWidthType = LineWidthPressure;
|
||||
}
|
||||
|
||||
void TabletCanvas::initPixmap()
|
||||
@ -63,24 +64,24 @@ void TabletCanvas::initPixmap()
|
||||
QPixmap newPixmap = QPixmap(width(), height());
|
||||
newPixmap.fill(Qt::white);
|
||||
QPainter painter(&newPixmap);
|
||||
if (!pixmap.isNull())
|
||||
painter.drawPixmap(0, 0, pixmap);
|
||||
if (!m_pixmap.isNull())
|
||||
painter.drawPixmap(0, 0, m_pixmap);
|
||||
painter.end();
|
||||
pixmap = newPixmap;
|
||||
m_pixmap = newPixmap;
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
bool TabletCanvas::saveImage(const QString &file)
|
||||
{
|
||||
return pixmap.save(file);
|
||||
return m_pixmap.save(file);
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
bool TabletCanvas::loadImage(const QString &file)
|
||||
{
|
||||
bool success = pixmap.load(file);
|
||||
bool success = m_pixmap.load(file);
|
||||
|
||||
if (success) {
|
||||
update();
|
||||
@ -96,8 +97,8 @@ void TabletCanvas::tabletEvent(QTabletEvent *event)
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::TabletPress:
|
||||
if (!deviceDown) {
|
||||
deviceDown = true;
|
||||
if (!m_deviceDown) {
|
||||
m_deviceDown = true;
|
||||
lastPoint.pos = event->posF();
|
||||
lastPoint.rotation = event->rotation();
|
||||
}
|
||||
@ -105,17 +106,17 @@ void TabletCanvas::tabletEvent(QTabletEvent *event)
|
||||
case QEvent::TabletMove:
|
||||
if (event->device() == QTabletEvent::RotationStylus)
|
||||
updateCursor(event);
|
||||
if (deviceDown) {
|
||||
if (m_deviceDown) {
|
||||
updateBrush(event);
|
||||
QPainter painter(&pixmap);
|
||||
QPainter painter(&m_pixmap);
|
||||
paintPixmap(painter, event);
|
||||
lastPoint.pos = event->posF();
|
||||
lastPoint.rotation = event->rotation();
|
||||
}
|
||||
break;
|
||||
case QEvent::TabletRelease:
|
||||
if (deviceDown && event->buttons() == Qt::NoButton)
|
||||
deviceDown = false;
|
||||
if (m_deviceDown && event->buttons() == Qt::NoButton)
|
||||
m_deviceDown = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -128,7 +129,7 @@ void TabletCanvas::tabletEvent(QTabletEvent *event)
|
||||
void TabletCanvas::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.drawPixmap(0, 0, pixmap);
|
||||
painter.drawPixmap(0, 0, m_pixmap);
|
||||
}
|
||||
//! [4]
|
||||
|
||||
@ -142,10 +143,10 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
|
||||
case QTabletEvent::Airbrush:
|
||||
{
|
||||
painter.setPen(Qt::NoPen);
|
||||
QRadialGradient grad(lastPoint.pos, myPen.widthF() * 10.0);
|
||||
QColor color = myBrush.color();
|
||||
QRadialGradient grad(lastPoint.pos, m_pen.widthF() * 10.0);
|
||||
QColor color = m_brush.color();
|
||||
color.setAlphaF(color.alphaF() * 0.25);
|
||||
grad.setColorAt(0, myBrush.color());
|
||||
grad.setColorAt(0, m_brush.color());
|
||||
grad.setColorAt(0.5, Qt::transparent);
|
||||
painter.setBrush(grad);
|
||||
qreal radius = grad.radius();
|
||||
@ -154,11 +155,11 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
|
||||
break;
|
||||
case QTabletEvent::RotationStylus:
|
||||
{
|
||||
myBrush.setStyle(Qt::SolidPattern);
|
||||
m_brush.setStyle(Qt::SolidPattern);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(myBrush);
|
||||
painter.setBrush(m_brush);
|
||||
QPolygonF poly;
|
||||
qreal halfWidth = myPen.widthF();
|
||||
qreal halfWidth = m_pen.widthF();
|
||||
QPointF brushAdjust(qSin(qDegreesToRadians(lastPoint.rotation)) * halfWidth,
|
||||
qCos(qDegreesToRadians(lastPoint.rotation)) * halfWidth);
|
||||
poly << lastPoint.pos + brushAdjust;
|
||||
@ -195,7 +196,7 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
|
||||
}
|
||||
// FALL-THROUGH
|
||||
case QTabletEvent::Stylus:
|
||||
painter.setPen(myPen);
|
||||
painter.setPen(m_pen);
|
||||
painter.drawLine(lastPoint.pos, event->posF());
|
||||
break;
|
||||
}
|
||||
@ -206,68 +207,69 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event)
|
||||
void TabletCanvas::updateBrush(const QTabletEvent *event)
|
||||
{
|
||||
int hue, saturation, value, alpha;
|
||||
myColor.getHsv(&hue, &saturation, &value, &alpha);
|
||||
m_color.getHsv(&hue, &saturation, &value, &alpha);
|
||||
|
||||
int vValue = int(((event->yTilt() + 60.0) / 120.0) * 255);
|
||||
int hValue = int(((event->xTilt() + 60.0) / 120.0) * 255);
|
||||
//! [7] //! [8]
|
||||
|
||||
switch (alphaChannelType) {
|
||||
case AlphaPressure:
|
||||
myColor.setAlphaF(event->pressure());
|
||||
switch (m_alphaChannelValuator) {
|
||||
case PressureValuator:
|
||||
m_color.setAlphaF(event->pressure());
|
||||
break;
|
||||
case AlphaTangentialPressure:
|
||||
case TangentialPressureValuator:
|
||||
if (event->device() == QTabletEvent::Airbrush)
|
||||
myColor.setAlphaF(qMax(0.01, (event->tangentialPressure() + 1.0) / 2.0));
|
||||
m_color.setAlphaF(qMax(0.01, (event->tangentialPressure() + 1.0) / 2.0));
|
||||
else
|
||||
myColor.setAlpha(255);
|
||||
m_color.setAlpha(255);
|
||||
break;
|
||||
case AlphaTilt:
|
||||
myColor.setAlpha(maximum(abs(vValue - 127), abs(hValue - 127)));
|
||||
case TiltValuator:
|
||||
m_color.setAlpha(maximum(abs(vValue - 127), abs(hValue - 127)));
|
||||
break;
|
||||
default:
|
||||
myColor.setAlpha(255);
|
||||
m_color.setAlpha(255);
|
||||
}
|
||||
|
||||
//! [8] //! [9]
|
||||
switch (colorSaturationType) {
|
||||
case SaturationVTilt:
|
||||
myColor.setHsv(hue, vValue, value, alpha);
|
||||
switch (m_colorSaturationValuator) {
|
||||
case VTiltValuator:
|
||||
m_color.setHsv(hue, vValue, value, alpha);
|
||||
break;
|
||||
case SaturationHTilt:
|
||||
myColor.setHsv(hue, hValue, value, alpha);
|
||||
case HTiltValuator:
|
||||
m_color.setHsv(hue, hValue, value, alpha);
|
||||
break;
|
||||
case SaturationPressure:
|
||||
myColor.setHsv(hue, int(event->pressure() * 255.0), value, alpha);
|
||||
case PressureValuator:
|
||||
m_color.setHsv(hue, int(event->pressure() * 255.0), value, alpha);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
//! [9] //! [10]
|
||||
switch (lineWidthType) {
|
||||
case LineWidthPressure:
|
||||
myPen.setWidthF(event->pressure() * 10 + 1);
|
||||
switch (m_lineWidthValuator) {
|
||||
case PressureValuator:
|
||||
m_pen.setWidthF(event->pressure() * 10 + 1);
|
||||
break;
|
||||
case LineWidthTilt:
|
||||
myPen.setWidthF(maximum(abs(vValue - 127), abs(hValue - 127)) / 12);
|
||||
case TiltValuator:
|
||||
m_pen.setWidthF(maximum(abs(vValue - 127), abs(hValue - 127)) / 12);
|
||||
break;
|
||||
default:
|
||||
myPen.setWidthF(1);
|
||||
m_pen.setWidthF(1);
|
||||
}
|
||||
|
||||
//! [10] //! [11]
|
||||
if (event->pointerType() == QTabletEvent::Eraser) {
|
||||
myBrush.setColor(Qt::white);
|
||||
myPen.setColor(Qt::white);
|
||||
myPen.setWidthF(event->pressure() * 10 + 1);
|
||||
m_brush.setColor(Qt::white);
|
||||
m_pen.setColor(Qt::white);
|
||||
m_pen.setWidthF(event->pressure() * 10 + 1);
|
||||
} else {
|
||||
myBrush.setColor(myColor);
|
||||
myPen.setColor(myColor);
|
||||
m_brush.setColor(m_color);
|
||||
m_pen.setColor(m_color);
|
||||
}
|
||||
}
|
||||
//! [11]
|
||||
|
||||
//! [12]
|
||||
void TabletCanvas::updateCursor(const QTabletEvent *event)
|
||||
{
|
||||
QCursor cursor;
|
||||
@ -285,7 +287,7 @@ void TabletCanvas::updateCursor(const QTabletEvent *event)
|
||||
case QTabletEvent::RotationStylus: {
|
||||
QImage origImg(QLatin1String(":/images/cursor-felt-marker.png"));
|
||||
QImage img(32, 32, QImage::Format_ARGB32);
|
||||
QColor solid = myColor;
|
||||
QColor solid = m_color;
|
||||
solid.setAlpha(255);
|
||||
img.fill(solid);
|
||||
QPainter painter(&img);
|
||||
@ -307,6 +309,7 @@ void TabletCanvas::updateCursor(const QTabletEvent *event)
|
||||
}
|
||||
setCursor(cursor);
|
||||
}
|
||||
//! [12]
|
||||
|
||||
void TabletCanvas::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
|
@ -61,27 +61,26 @@ class TabletCanvas : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum AlphaChannelType { AlphaPressure, AlphaTangentialPressure, AlphaTilt, NoAlpha };
|
||||
enum ColorSaturationType { SaturationVTilt, SaturationHTilt,
|
||||
SaturationPressure, NoSaturation };
|
||||
enum LineWidthType { LineWidthPressure, LineWidthTilt, NoLineWidth };
|
||||
enum Valuator { PressureValuator, TangentialPressureValuator,
|
||||
TiltValuator, VTiltValuator, HTiltValuator, NoValuator };
|
||||
Q_ENUM(Valuator)
|
||||
|
||||
TabletCanvas();
|
||||
|
||||
bool saveImage(const QString &file);
|
||||
bool loadImage(const QString &file);
|
||||
void setAlphaChannelType(AlphaChannelType type)
|
||||
{ alphaChannelType = type; }
|
||||
void setColorSaturationType(ColorSaturationType type)
|
||||
{ colorSaturationType = type; }
|
||||
void setLineWidthType(LineWidthType type)
|
||||
{ lineWidthType = type; }
|
||||
void setColor(const QColor &color)
|
||||
{ myColor = color; }
|
||||
void setAlphaChannelValuator(Valuator type)
|
||||
{ m_alphaChannelValuator = type; }
|
||||
void setColorSaturationValuator(Valuator type)
|
||||
{ m_colorSaturationValuator = type; }
|
||||
void setLineWidthType(Valuator type)
|
||||
{ m_lineWidthValuator = type; }
|
||||
void setColor(const QColor &c)
|
||||
{ if (c.isValid()) m_color = c; }
|
||||
QColor color() const
|
||||
{ return myColor; }
|
||||
{ return m_color; }
|
||||
void setTabletDevice(QTabletEvent *event)
|
||||
{ myTabletDevice = event->device(); updateCursor(event); }
|
||||
{ updateCursor(event); }
|
||||
int maximum(int a, int b)
|
||||
{ return a > b ? a : b; }
|
||||
|
||||
@ -97,17 +96,14 @@ private:
|
||||
void updateBrush(const QTabletEvent *event);
|
||||
void updateCursor(const QTabletEvent *event);
|
||||
|
||||
AlphaChannelType alphaChannelType;
|
||||
ColorSaturationType colorSaturationType;
|
||||
LineWidthType lineWidthType;
|
||||
QTabletEvent::PointerType pointerType;
|
||||
QTabletEvent::TabletDevice myTabletDevice;
|
||||
QColor myColor;
|
||||
|
||||
QPixmap pixmap;
|
||||
QBrush myBrush;
|
||||
QPen myPen;
|
||||
bool deviceDown;
|
||||
Valuator m_alphaChannelValuator;
|
||||
Valuator m_colorSaturationValuator;
|
||||
Valuator m_lineWidthValuator;
|
||||
QColor m_color;
|
||||
QPixmap m_pixmap;
|
||||
QBrush m_brush;
|
||||
QPen m_pen;
|
||||
bool m_deviceDown;
|
||||
|
||||
struct Point {
|
||||
QPointF pos;
|
||||
|
@ -29,6 +29,7 @@
|
||||
\example dombookmarks
|
||||
\title DOM Bookmarks Example
|
||||
\ingroup xml-examples
|
||||
\brief Provides a reader for XML Bookmark Exchange Language files
|
||||
|
||||
The DOM Bookmarks example provides a reader for XML Bookmark Exchange Language (XBEL)
|
||||
files that uses Qt's DOM-based XML API to read and parse the files. The SAX Bookmarks
|
||||
|
@ -29,6 +29,8 @@
|
||||
\example xmlstreamlint
|
||||
\title XML Stream Lint Example
|
||||
\ingroup xml-examples
|
||||
\brief A commandline tool reading from an input file and writing to
|
||||
the standard output file.
|
||||
|
||||
The XML Stream Lint example provides a simple command line utility that
|
||||
accepts a file name as its single argument and writes it to the standard
|
||||
|
@ -4,7 +4,8 @@
|
||||
xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\"
|
||||
xmlns:mp=\"http://schemas.microsoft.com/appx/2014/phone/manifest\"
|
||||
xmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\"
|
||||
IgnorableNamespaces=\"uap mp\">
|
||||
xmlns:mobile=\"http://schemas.microsoft.com/appx/manifest/mobile/windows10\"
|
||||
IgnorableNamespaces=\"uap mp mobile\">
|
||||
|
||||
<Identity
|
||||
Name=\"$${WINRT_MANIFEST.identity}\"
|
||||
@ -21,7 +22,7 @@
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.10069.0\" MaxVersionTested=\"10.0.10069.0\" />$${WINRT_MANIFEST.dependencies}
|
||||
<TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.10240.0\" MaxVersionTested=\"10.0.10586.0\" />$${WINRT_MANIFEST.dependencies}
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
|
216
mkspecs/features/data/mac/objc_namespace.sh
Executable file
216
mkspecs/features/data/mac/objc_namespace.sh
Executable 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
|
||||
|
50
mkspecs/features/mac/unsupported/objc_namespace.prf
Normal file
50
mkspecs/features/mac/unsupported/objc_namespace.prf
Normal 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
|
3
src/3rdparty/freetype/freetype.pro
vendored
3
src/3rdparty/freetype/freetype.pro
vendored
@ -3,7 +3,8 @@ TARGET = qtfreetype
|
||||
CONFIG += \
|
||||
static \
|
||||
hide_symbols \
|
||||
exceptions_off rtti_off warn_off
|
||||
exceptions_off rtti_off warn_off \
|
||||
installed
|
||||
|
||||
load(qt_helper_lib)
|
||||
|
||||
|
@ -42,6 +42,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.Rect;
|
||||
import android.net.LocalServerSocket;
|
||||
import android.net.LocalSocket;
|
||||
import android.os.Build;
|
||||
@ -67,7 +68,6 @@ import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.graphics.Rect;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
@ -125,6 +125,9 @@ public class QtActivityDelegate
|
||||
private boolean m_keyboardIsVisible = false;
|
||||
public boolean m_backKeyPressedSent = false;
|
||||
private long m_showHideTimeStamp = System.nanoTime();
|
||||
private int m_portraitKeyboardHeight = 0;
|
||||
private int m_landscapeKeyboardHeight = 0;
|
||||
private int m_probeKeyboardHeightDelay = 50; // ms
|
||||
|
||||
public void setFullScreen(boolean enterFullScreen)
|
||||
{
|
||||
@ -247,19 +250,26 @@ public class QtActivityDelegate
|
||||
}, 5);
|
||||
}
|
||||
|
||||
public void showSoftwareKeyboard(int x, int y, int width, int height, int inputHints, int enterKeyType)
|
||||
public void showSoftwareKeyboard(final int x, final int y, final int width, final int height, final int inputHints, final int enterKeyType)
|
||||
{
|
||||
if (m_imm == null)
|
||||
return;
|
||||
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
m_activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
|
||||
// If the screen is in portrait mode than we estimate that keyboard height will not be higher than 2/5 of the screen.
|
||||
// else than we estimate that keyboard height will not be higher than 2/3 of the screen
|
||||
final int visibleHeight;
|
||||
if (metrics.widthPixels < metrics.heightPixels)
|
||||
visibleHeight = m_portraitKeyboardHeight != 0 ? m_portraitKeyboardHeight : metrics.heightPixels * 3 / 5;
|
||||
else
|
||||
visibleHeight = m_landscapeKeyboardHeight != 0 ? m_landscapeKeyboardHeight : metrics.heightPixels / 3;
|
||||
|
||||
if (m_softInputMode != 0) {
|
||||
m_activity.getWindow().setSoftInputMode(m_softInputMode);
|
||||
// softInputIsHidden is true if SOFT_INPUT_STATE_HIDDEN or SOFT_INPUT_STATE_ALWAYS_HIDDEN is set.
|
||||
final boolean softInputIsHidden = (m_softInputMode & WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) != 0;
|
||||
if (softInputIsHidden)
|
||||
return;
|
||||
} else {
|
||||
if (height > m_layout.getHeight() * 2 / 3)
|
||||
if (height > visibleHeight)
|
||||
m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
||||
else
|
||||
m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
|
||||
@ -366,6 +376,38 @@ public class QtActivityDelegate
|
||||
//FALLTHROUGH
|
||||
case InputMethodManager.RESULT_UNCHANGED_SHOWN:
|
||||
setKeyboardVisibility(true, System.nanoTime());
|
||||
if (m_softInputMode == 0) {
|
||||
// probe for real keyboard height
|
||||
m_layout.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!m_keyboardIsVisible)
|
||||
return;
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
m_activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
Rect r = new Rect();
|
||||
m_activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
|
||||
if (metrics.heightPixels != r.bottom) {
|
||||
if (metrics.widthPixels > metrics.heightPixels) { // landscape
|
||||
if (m_landscapeKeyboardHeight != r.bottom) {
|
||||
m_landscapeKeyboardHeight = r.bottom;
|
||||
showSoftwareKeyboard(x, y, width, height, inputHints, enterKeyType);
|
||||
}
|
||||
} else {
|
||||
if (m_portraitKeyboardHeight != r.bottom) {
|
||||
m_portraitKeyboardHeight = r.bottom;
|
||||
showSoftwareKeyboard(x, y, width, height, inputHints, enterKeyType);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// no luck ?
|
||||
// maybe the delay was too short, so let's make it longer
|
||||
if (m_probeKeyboardHeightDelay < 1000)
|
||||
m_probeKeyboardHeightDelay *= 2;
|
||||
}
|
||||
}
|
||||
}, m_probeKeyboardHeightDelay);
|
||||
}
|
||||
break;
|
||||
case InputMethodManager.RESULT_HIDDEN:
|
||||
case InputMethodManager.RESULT_UNCHANGED_HIDDEN:
|
||||
|
@ -214,6 +214,16 @@ public class QtNative
|
||||
});
|
||||
}
|
||||
|
||||
private static void setViewVisibility(final View view, final boolean visible)
|
||||
{
|
||||
runAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
view.setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean startApplication(String params,
|
||||
String environment,
|
||||
String mainLibrary,
|
||||
|
@ -647,7 +647,7 @@ extern "C" void qt_core_boilerplate();
|
||||
void qt_core_boilerplate()
|
||||
{
|
||||
printf("This is the QtCore library version " QT_BUILD_STR "\n"
|
||||
"Copyright (C) 2015 The Qt Company Ltd.\n"
|
||||
"Copyright (C) 2016 The Qt Company Ltd.\n"
|
||||
"Contact: http://www.qt.io/licensing/\n"
|
||||
"\n"
|
||||
"Installation prefix: %s\n"
|
||||
|
@ -107,8 +107,6 @@ win32 {
|
||||
|
||||
!winrt {
|
||||
SOURCES += io/qsettings_win.cpp
|
||||
HEADERS += io/qwindowspipewriter_p.h
|
||||
SOURCES += io/qwindowspipewriter.cpp
|
||||
SOURCES += io/qstandardpaths_win.cpp
|
||||
|
||||
wince* {
|
||||
@ -117,11 +115,13 @@ win32 {
|
||||
} else {
|
||||
HEADERS += \
|
||||
io/qwinoverlappedionotifier_p.h \
|
||||
io/qwindowspipereader_p.h
|
||||
io/qwindowspipereader_p.h \
|
||||
io/qwindowspipewriter_p.h
|
||||
SOURCES += \
|
||||
io/qprocess_win.cpp \
|
||||
io/qwinoverlappedionotifier.cpp \
|
||||
io/qwindowspipereader.cpp \
|
||||
io/qwindowspipewriter.cpp \
|
||||
io/qstorageinfo_win.cpp
|
||||
LIBS += -lmpr
|
||||
}
|
||||
|
@ -747,7 +747,7 @@ QFile::copy(const QString &newName)
|
||||
qWarning("QFile::copy: Empty or null file name");
|
||||
return false;
|
||||
}
|
||||
if (QFile(newName).exists()) {
|
||||
if (QFile::exists(newName)) {
|
||||
// ### Race condition. If a file is moved in after this, it /will/ be
|
||||
// overwritten. On Unix, the proper solution is to use hardlinks:
|
||||
// return ::link(old, new) && ::remove(old); See also rename().
|
||||
|
@ -33,7 +33,6 @@
|
||||
|
||||
#include "qprocess.h"
|
||||
#include "qprocess_p.h"
|
||||
#include "qwindowspipewriter_p.h"
|
||||
|
||||
#include <qdir.h>
|
||||
#include <qfileinfo.h>
|
||||
@ -156,7 +155,7 @@ void QProcessPrivate::startProcess()
|
||||
}
|
||||
|
||||
// give the process a chance to start ...
|
||||
Sleep(SLEEPMIN * 2);
|
||||
Sleep(20);
|
||||
_q_startupNotification();
|
||||
}
|
||||
|
||||
|
@ -41,9 +41,7 @@
|
||||
#include <qcoreapplication.h>
|
||||
#endif
|
||||
|
||||
#if !defined(Q_OS_WINCE)
|
||||
const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } };
|
||||
#endif
|
||||
|
||||
#include <qt_windows.h>
|
||||
#include <shlobj.h>
|
||||
@ -64,113 +62,152 @@ const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x6
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if !defined(Q_OS_WINCE)
|
||||
typedef HRESULT (WINAPI *GetKnownFolderPath)(const GUID&, DWORD, HANDLE, LPWSTR*);
|
||||
#endif
|
||||
|
||||
static QString convertCharArray(const wchar_t *path)
|
||||
{
|
||||
return QDir::fromNativeSeparators(QString::fromWCharArray(path));
|
||||
}
|
||||
|
||||
static inline int clsidForAppDataLocation(QStandardPaths::StandardLocation type)
|
||||
static inline bool isGenericConfigLocation(QStandardPaths::StandardLocation type)
|
||||
{
|
||||
#ifndef Q_OS_WINCE
|
||||
return type == QStandardPaths::AppDataLocation ?
|
||||
CSIDL_APPDATA : // "Roaming" path
|
||||
CSIDL_LOCAL_APPDATA; // Local path
|
||||
#else
|
||||
Q_UNUSED(type)
|
||||
return CSIDL_APPDATA;
|
||||
return type == QStandardPaths::GenericConfigLocation || type == QStandardPaths::GenericDataLocation;
|
||||
}
|
||||
|
||||
static inline bool isConfigLocation(QStandardPaths::StandardLocation type)
|
||||
{
|
||||
return type == QStandardPaths::ConfigLocation || type == QStandardPaths::AppConfigLocation
|
||||
|| type == QStandardPaths::AppDataLocation || type == QStandardPaths::AppLocalDataLocation
|
||||
|| isGenericConfigLocation(type);
|
||||
}
|
||||
|
||||
static void appendOrganizationAndApp(QString &path) // Courtesy qstandardpaths_unix.cpp
|
||||
{
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
const QString &org = QCoreApplication::organizationName();
|
||||
if (!org.isEmpty())
|
||||
path += QLatin1Char('/') + org;
|
||||
const QString &appName = QCoreApplication::applicationName();
|
||||
if (!appName.isEmpty())
|
||||
path += QLatin1Char('/') + appName;
|
||||
#else // !QT_BOOTSTRAPPED
|
||||
Q_UNUSED(path)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline QString displayName(QStandardPaths::StandardLocation type)
|
||||
{
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
return QStandardPaths::displayName(type);
|
||||
#else
|
||||
return QString::number(type);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void appendTestMode(QString &path)
|
||||
{
|
||||
if (QStandardPaths::isTestModeEnabled())
|
||||
path += QLatin1String("/qttest");
|
||||
}
|
||||
|
||||
// Map QStandardPaths::StandardLocation to CLSID of SHGetSpecialFolderPath()
|
||||
static int writableSpecialFolderClsid(QStandardPaths::StandardLocation type)
|
||||
{
|
||||
static const int clsids[] = {
|
||||
CSIDL_DESKTOPDIRECTORY, // DesktopLocation
|
||||
CSIDL_PERSONAL, // DocumentsLocation
|
||||
CSIDL_FONTS, // FontsLocation
|
||||
CSIDL_PROGRAMS, // ApplicationsLocation
|
||||
CSIDL_MYMUSIC, // MusicLocation
|
||||
CSIDL_MYVIDEO, // MoviesLocation
|
||||
CSIDL_MYPICTURES, // PicturesLocation
|
||||
-1, -1, // TempLocation/HomeLocation
|
||||
CSIDL_LOCAL_APPDATA, // AppLocalDataLocation ("Local" path), AppLocalDataLocation = DataLocation
|
||||
-1, // CacheLocation
|
||||
CSIDL_LOCAL_APPDATA, // GenericDataLocation ("Local" path)
|
||||
-1, // RuntimeLocation
|
||||
CSIDL_LOCAL_APPDATA, // ConfigLocation ("Local" path)
|
||||
-1, -1, // DownloadLocation/GenericCacheLocation
|
||||
CSIDL_LOCAL_APPDATA, // GenericConfigLocation ("Local" path)
|
||||
CSIDL_APPDATA, // AppDataLocation ("Roaming" path)
|
||||
CSIDL_LOCAL_APPDATA, // AppConfigLocation ("Local" path)
|
||||
};
|
||||
|
||||
Q_STATIC_ASSERT(sizeof(clsids) / sizeof(clsids[0]) == size_t(QStandardPaths::AppConfigLocation + 1));
|
||||
return size_t(type) < sizeof(clsids) / sizeof(clsids[0]) ? clsids[type] : -1;
|
||||
};
|
||||
|
||||
// Convenience for SHGetSpecialFolderPath().
|
||||
static QString sHGetSpecialFolderPath(int clsid, QStandardPaths::StandardLocation type, bool warn = false)
|
||||
{
|
||||
QString result;
|
||||
wchar_t path[MAX_PATH];
|
||||
if (Q_LIKELY(clsid >= 0 && SHGetSpecialFolderPath(0, path, clsid, FALSE))) {
|
||||
result = convertCharArray(path);
|
||||
} else {
|
||||
if (warn) {
|
||||
qErrnoWarning("SHGetSpecialFolderPath() failed for standard location \"%s\", clsid=0x%x.",
|
||||
qPrintable(displayName(type)), clsid);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Convenience for SHGetKnownFolderPath().
|
||||
static QString sHGetKnownFolderPath(const GUID &clsid, QStandardPaths::StandardLocation type, bool warn = false)
|
||||
{
|
||||
QString result;
|
||||
#ifndef Q_OS_WINCE
|
||||
typedef HRESULT (WINAPI *GetKnownFolderPath)(const GUID&, DWORD, HANDLE, LPWSTR*);
|
||||
|
||||
static const GetKnownFolderPath sHGetKnownFolderPath = // Vista onwards.
|
||||
reinterpret_cast<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 result;
|
||||
|
||||
#if !defined(Q_OS_WINCE)
|
||||
static GetKnownFolderPath SHGetKnownFolderPath = (GetKnownFolderPath)QSystemLibrary::resolve(QLatin1String("shell32"), "SHGetKnownFolderPath");
|
||||
#endif
|
||||
|
||||
wchar_t path[MAX_PATH];
|
||||
|
||||
switch (type) {
|
||||
case ConfigLocation: // same as AppLocalDataLocation, on Windows
|
||||
case GenericConfigLocation: // same as GenericDataLocation on Windows
|
||||
case AppConfigLocation:
|
||||
case AppDataLocation:
|
||||
case AppLocalDataLocation:
|
||||
case GenericDataLocation:
|
||||
if (SHGetSpecialFolderPath(0, path, clsidForAppDataLocation(type), FALSE))
|
||||
result = convertCharArray(path);
|
||||
if (isTestModeEnabled())
|
||||
result += QLatin1String("/qttest");
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
if (type != GenericDataLocation && type != GenericConfigLocation) {
|
||||
if (!QCoreApplication::organizationName().isEmpty())
|
||||
result += QLatin1Char('/') + QCoreApplication::organizationName();
|
||||
if (!QCoreApplication::applicationName().isEmpty())
|
||||
result += QLatin1Char('/') + QCoreApplication::applicationName();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case DesktopLocation:
|
||||
if (SHGetSpecialFolderPath(0, path, CSIDL_DESKTOPDIRECTORY, FALSE))
|
||||
result = convertCharArray(path);
|
||||
break;
|
||||
|
||||
case DownloadLocation:
|
||||
#if !defined(Q_OS_WINCE)
|
||||
if (SHGetKnownFolderPath) {
|
||||
LPWSTR path;
|
||||
if (SHGetKnownFolderPath(qCLSID_FOLDERID_Downloads, 0, 0, &path) == S_OK) {
|
||||
result = convertCharArray(path);
|
||||
CoTaskMemFree(path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
// fall through
|
||||
case DocumentsLocation:
|
||||
if (SHGetSpecialFolderPath(0, path, CSIDL_PERSONAL, FALSE))
|
||||
result = convertCharArray(path);
|
||||
break;
|
||||
|
||||
case FontsLocation:
|
||||
if (SHGetSpecialFolderPath(0, path, CSIDL_FONTS, FALSE))
|
||||
result = convertCharArray(path);
|
||||
break;
|
||||
|
||||
case ApplicationsLocation:
|
||||
if (SHGetSpecialFolderPath(0, path, CSIDL_PROGRAMS, FALSE))
|
||||
result = convertCharArray(path);
|
||||
break;
|
||||
|
||||
case MusicLocation:
|
||||
if (SHGetSpecialFolderPath(0, path, CSIDL_MYMUSIC, FALSE))
|
||||
result = convertCharArray(path);
|
||||
break;
|
||||
|
||||
case MoviesLocation:
|
||||
if (SHGetSpecialFolderPath(0, path, CSIDL_MYVIDEO, FALSE))
|
||||
result = convertCharArray(path);
|
||||
break;
|
||||
|
||||
case PicturesLocation:
|
||||
if (SHGetSpecialFolderPath(0, path, CSIDL_MYPICTURES, FALSE))
|
||||
result = convertCharArray(path);
|
||||
result = sHGetKnownFolderPath(qCLSID_FOLDERID_Downloads, type);
|
||||
if (result.isEmpty())
|
||||
result = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||
break;
|
||||
|
||||
case CacheLocation:
|
||||
// Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache
|
||||
// location for everyone. Most applications seem to be using a
|
||||
// cache directory located in their AppData directory
|
||||
return writableLocation(AppLocalDataLocation) + QLatin1String("/cache");
|
||||
result = sHGetSpecialFolderPath(writableSpecialFolderClsid(AppLocalDataLocation), type, /* warn */ true);
|
||||
if (!result.isEmpty()) {
|
||||
appendTestMode(result);
|
||||
appendOrganizationAndApp(result);
|
||||
result += QLatin1String("/cache");
|
||||
}
|
||||
break;
|
||||
|
||||
case GenericCacheLocation:
|
||||
return writableLocation(GenericDataLocation) + QLatin1String("/cache");
|
||||
result = sHGetSpecialFolderPath(writableSpecialFolderClsid(GenericDataLocation), type, /* warn */ true);
|
||||
if (!result.isEmpty()) {
|
||||
appendTestMode(result);
|
||||
result += QLatin1String("/cache");
|
||||
}
|
||||
break;
|
||||
|
||||
case RuntimeLocation:
|
||||
case HomeLocation:
|
||||
@ -180,6 +217,15 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
||||
case TempLocation:
|
||||
result = QDir::tempPath();
|
||||
break;
|
||||
|
||||
default:
|
||||
result = sHGetSpecialFolderPath(writableSpecialFolderClsid(type), type, /* warn */ isConfigLocation(type));
|
||||
if (!result.isEmpty() && isConfigLocation(type)) {
|
||||
appendTestMode(result);
|
||||
if (!isGenericConfigLocation(type))
|
||||
appendOrganizationAndApp(result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -187,44 +233,26 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
||||
QStringList QStandardPaths::standardLocations(StandardLocation type)
|
||||
{
|
||||
QStringList dirs;
|
||||
const QString localDir = writableLocation(type);
|
||||
if (!localDir.isEmpty())
|
||||
dirs.append(localDir);
|
||||
|
||||
// type-specific handling goes here
|
||||
|
||||
#ifndef Q_OS_WINCE
|
||||
{
|
||||
wchar_t path[MAX_PATH];
|
||||
switch (type) {
|
||||
case ConfigLocation: // same as AppLocalDataLocation, on Windows (oversight, but too late to fix it)
|
||||
case GenericConfigLocation: // same as GenericDataLocation, on Windows
|
||||
case AppConfigLocation: // same as AppLocalDataLocation, that one on purpose
|
||||
case AppDataLocation:
|
||||
case AppLocalDataLocation:
|
||||
case GenericDataLocation:
|
||||
if (SHGetSpecialFolderPath(0, path, CSIDL_COMMON_APPDATA, FALSE)) {
|
||||
QString result = convertCharArray(path);
|
||||
if (type != GenericDataLocation && type != GenericConfigLocation) {
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
if (!QCoreApplication::organizationName().isEmpty())
|
||||
result += QLatin1Char('/') + QCoreApplication::organizationName();
|
||||
if (!QCoreApplication::applicationName().isEmpty())
|
||||
result += QLatin1Char('/') + QCoreApplication::applicationName();
|
||||
#endif
|
||||
if (isConfigLocation(type)) {
|
||||
QString programData = sHGetSpecialFolderPath(CSIDL_COMMON_APPDATA, type);
|
||||
if (!programData.isEmpty()) {
|
||||
if (!isGenericConfigLocation(type))
|
||||
appendOrganizationAndApp(programData);
|
||||
dirs.append(programData);
|
||||
}
|
||||
dirs.append(result);
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
# ifndef QT_BOOTSTRAPPED
|
||||
dirs.append(QCoreApplication::applicationDirPath());
|
||||
dirs.append(QCoreApplication::applicationDirPath() + QLatin1String("/data"));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
# endif // !QT_BOOTSTRAPPED
|
||||
} // isConfigLocation()
|
||||
#endif // !Q_OS_WINCE
|
||||
|
||||
const QString localDir = writableLocation(type);
|
||||
dirs.prepend(localDir);
|
||||
return dirs;
|
||||
}
|
||||
|
||||
|
@ -679,8 +679,11 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
|
||||
|
||||
/*! \typedef QJsonObject::iterator::iterator_category
|
||||
|
||||
A synonym for \e {std::bidirectional_iterator_tag} indicating
|
||||
this iterator is a bidirectional iterator.
|
||||
A synonym for \e {std::random_access_iterator_tag} indicating
|
||||
this iterator is a random-access iterator.
|
||||
|
||||
\note In Qt versions before 5.6, this was set by mistake to
|
||||
\e {std::bidirectional_iterator_tag}.
|
||||
*/
|
||||
|
||||
/*! \typedef QJsonObject::iterator::reference
|
||||
@ -886,8 +889,11 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
|
||||
|
||||
/*! \typedef QJsonObject::const_iterator::iterator_category
|
||||
|
||||
A synonym for \e {std::bidirectional_iterator_tag} indicating
|
||||
this iterator is a bidirectional iterator.
|
||||
A synonym for \e {std::random_access_iterator_tag} indicating
|
||||
this iterator is a random-access iterator.
|
||||
|
||||
\note In Qt versions before 5.6, this was set by mistake to
|
||||
\e {std::bidirectional_iterator_tag}.
|
||||
*/
|
||||
|
||||
/*! \typedef QJsonObject::const_iterator::reference
|
||||
|
@ -100,7 +100,7 @@ public:
|
||||
int i;
|
||||
|
||||
public:
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef int difference_type;
|
||||
typedef QJsonValue value_type;
|
||||
typedef QJsonValueRef reference;
|
||||
@ -143,7 +143,7 @@ public:
|
||||
int i;
|
||||
|
||||
public:
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef int difference_type;
|
||||
typedef QJsonValue value_type;
|
||||
typedef QJsonValue reference;
|
||||
|
@ -34,6 +34,11 @@
|
||||
|
||||
#include <private/qcore_mac_p.h>
|
||||
|
||||
#ifdef Q_OS_OSX
|
||||
#include <AppKit/NSText.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
|
||||
#include <qdebug.h>
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
@ -148,5 +153,148 @@ QMacAutoReleasePool::~QMacAutoReleasePool()
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
#ifdef Q_OS_OSX
|
||||
|
||||
// Use this method to keep all the information in the TextSegment. As long as it is ordered
|
||||
// we are in OK shape, and we can influence that ourselves.
|
||||
struct KeyPair
|
||||
{
|
||||
QChar cocoaKey;
|
||||
Qt::Key qtKey;
|
||||
};
|
||||
|
||||
bool operator==(const KeyPair &entry, QChar qchar)
|
||||
{
|
||||
return entry.cocoaKey == qchar;
|
||||
}
|
||||
|
||||
bool operator<(const KeyPair &entry, QChar qchar)
|
||||
{
|
||||
return entry.cocoaKey < qchar;
|
||||
}
|
||||
|
||||
bool operator<(QChar qchar, const KeyPair &entry)
|
||||
{
|
||||
return qchar < entry.cocoaKey;
|
||||
}
|
||||
|
||||
bool operator<(const Qt::Key &key, const KeyPair &entry)
|
||||
{
|
||||
return key < entry.qtKey;
|
||||
}
|
||||
|
||||
bool operator<(const KeyPair &entry, const Qt::Key &key)
|
||||
{
|
||||
return entry.qtKey < key;
|
||||
}
|
||||
|
||||
struct qtKey2CocoaKeySortLessThan
|
||||
{
|
||||
typedef bool result_type;
|
||||
Q_DECL_CONSTEXPR result_type operator()(const KeyPair &entry1, const KeyPair &entry2) const Q_DECL_NOTHROW
|
||||
{
|
||||
return entry1.qtKey < entry2.qtKey;
|
||||
}
|
||||
};
|
||||
|
||||
static const int NumEntries = 59;
|
||||
static const KeyPair entries[NumEntries] = {
|
||||
{ NSEnterCharacter, Qt::Key_Enter },
|
||||
{ NSBackspaceCharacter, Qt::Key_Backspace },
|
||||
{ NSTabCharacter, Qt::Key_Tab },
|
||||
{ NSNewlineCharacter, Qt::Key_Return },
|
||||
{ NSCarriageReturnCharacter, Qt::Key_Return },
|
||||
{ NSBackTabCharacter, Qt::Key_Backtab },
|
||||
{ kEscapeCharCode, Qt::Key_Escape },
|
||||
// Cocoa sends us delete when pressing backspace!
|
||||
// (NB when we reverse this list in qtKey2CocoaKey, there
|
||||
// will be two indices of Qt::Key_Backspace. But is seems to work
|
||||
// ok for menu shortcuts (which uses that function):
|
||||
{ NSDeleteCharacter, Qt::Key_Backspace },
|
||||
{ NSUpArrowFunctionKey, Qt::Key_Up },
|
||||
{ NSDownArrowFunctionKey, Qt::Key_Down },
|
||||
{ NSLeftArrowFunctionKey, Qt::Key_Left },
|
||||
{ NSRightArrowFunctionKey, Qt::Key_Right },
|
||||
{ NSF1FunctionKey, Qt::Key_F1 },
|
||||
{ NSF2FunctionKey, Qt::Key_F2 },
|
||||
{ NSF3FunctionKey, Qt::Key_F3 },
|
||||
{ NSF4FunctionKey, Qt::Key_F4 },
|
||||
{ NSF5FunctionKey, Qt::Key_F5 },
|
||||
{ NSF6FunctionKey, Qt::Key_F6 },
|
||||
{ NSF7FunctionKey, Qt::Key_F7 },
|
||||
{ NSF8FunctionKey, Qt::Key_F8 },
|
||||
{ NSF9FunctionKey, Qt::Key_F9 },
|
||||
{ NSF10FunctionKey, Qt::Key_F10 },
|
||||
{ NSF11FunctionKey, Qt::Key_F11 },
|
||||
{ NSF12FunctionKey, Qt::Key_F12 },
|
||||
{ NSF13FunctionKey, Qt::Key_F13 },
|
||||
{ NSF14FunctionKey, Qt::Key_F14 },
|
||||
{ NSF15FunctionKey, Qt::Key_F15 },
|
||||
{ NSF16FunctionKey, Qt::Key_F16 },
|
||||
{ NSF17FunctionKey, Qt::Key_F17 },
|
||||
{ NSF18FunctionKey, Qt::Key_F18 },
|
||||
{ NSF19FunctionKey, Qt::Key_F19 },
|
||||
{ NSF20FunctionKey, Qt::Key_F20 },
|
||||
{ NSF21FunctionKey, Qt::Key_F21 },
|
||||
{ NSF22FunctionKey, Qt::Key_F22 },
|
||||
{ NSF23FunctionKey, Qt::Key_F23 },
|
||||
{ NSF24FunctionKey, Qt::Key_F24 },
|
||||
{ NSF25FunctionKey, Qt::Key_F25 },
|
||||
{ NSF26FunctionKey, Qt::Key_F26 },
|
||||
{ NSF27FunctionKey, Qt::Key_F27 },
|
||||
{ NSF28FunctionKey, Qt::Key_F28 },
|
||||
{ NSF29FunctionKey, Qt::Key_F29 },
|
||||
{ NSF30FunctionKey, Qt::Key_F30 },
|
||||
{ NSF31FunctionKey, Qt::Key_F31 },
|
||||
{ NSF32FunctionKey, Qt::Key_F32 },
|
||||
{ NSF33FunctionKey, Qt::Key_F33 },
|
||||
{ NSF34FunctionKey, Qt::Key_F34 },
|
||||
{ NSF35FunctionKey, Qt::Key_F35 },
|
||||
{ NSInsertFunctionKey, Qt::Key_Insert },
|
||||
{ NSDeleteFunctionKey, Qt::Key_Delete },
|
||||
{ NSHomeFunctionKey, Qt::Key_Home },
|
||||
{ NSEndFunctionKey, Qt::Key_End },
|
||||
{ NSPageUpFunctionKey, Qt::Key_PageUp },
|
||||
{ NSPageDownFunctionKey, Qt::Key_PageDown },
|
||||
{ NSPrintScreenFunctionKey, Qt::Key_Print },
|
||||
{ NSScrollLockFunctionKey, Qt::Key_ScrollLock },
|
||||
{ NSPauseFunctionKey, Qt::Key_Pause },
|
||||
{ NSSysReqFunctionKey, Qt::Key_SysReq },
|
||||
{ NSMenuFunctionKey, Qt::Key_Menu },
|
||||
{ NSHelpFunctionKey, Qt::Key_Help },
|
||||
};
|
||||
static const KeyPair * const end = entries + NumEntries;
|
||||
|
||||
QChar qt_mac_qtKey2CocoaKey(Qt::Key key)
|
||||
{
|
||||
// The first time this function is called, create a reverse
|
||||
// lookup table sorted on Qt Key rather than Cocoa key:
|
||||
static QVector<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
|
||||
|
||||
|
@ -137,6 +137,11 @@ typedef struct {
|
||||
|
||||
QAppleOperatingSystemVersion qt_apple_os_version();
|
||||
|
||||
#ifdef Q_OS_OSX
|
||||
Q_CORE_EXPORT QChar qt_mac_qtKey2CocoaKey(Qt::Key key);
|
||||
Q_CORE_EXPORT Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode);
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QCORE_MAC_P_H
|
||||
|
@ -1698,8 +1698,9 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
|
||||
void *QMetaType::create(int type, const void *copy)
|
||||
{
|
||||
QMetaType info(type);
|
||||
int size = info.sizeOf();
|
||||
if (int size = info.sizeOf())
|
||||
return info.construct(operator new(size), copy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
static const char boilerplate_supported_but_time_limited[] =
|
||||
"\nQt %1 Evaluation License\n"
|
||||
"Copyright (C) 2015 The Qt Company Ltd.\n"
|
||||
"Copyright (C) 2016 The Qt Company Ltd.\n"
|
||||
"This trial version may only be used for evaluation purposes\n"
|
||||
"and will shut down after 120 minutes.\n"
|
||||
"Registered to:\n"
|
||||
@ -57,7 +57,7 @@ static const char boilerplate_supported_but_time_limited[] =
|
||||
|
||||
static const char boilerplate_supported[] =
|
||||
"\nQt %1 Evaluation License\n"
|
||||
"Copyright (C) 2015 The Qt Company Ltd.\n"
|
||||
"Copyright (C) 2016 The Qt Company Ltd.\n"
|
||||
"This trial version may only be used for evaluation purposes\n"
|
||||
"Registered to:\n"
|
||||
" Licensee: %2\n\n"
|
||||
|
@ -31,12 +31,10 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qfinalstate.h"
|
||||
#include "qfinalstate_p.h"
|
||||
|
||||
#ifndef QT_NO_STATEMACHINE
|
||||
|
||||
#include "qabstractstate_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
@ -76,19 +74,16 @@ QT_BEGIN_NAMESPACE
|
||||
\sa QState::finished()
|
||||
*/
|
||||
|
||||
class QFinalStatePrivate : public QAbstractStatePrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QFinalState)
|
||||
|
||||
public:
|
||||
QFinalStatePrivate();
|
||||
};
|
||||
|
||||
QFinalStatePrivate::QFinalStatePrivate()
|
||||
: QAbstractStatePrivate(FinalState)
|
||||
{
|
||||
}
|
||||
|
||||
QFinalStatePrivate::~QFinalStatePrivate()
|
||||
{
|
||||
// to prevent vtables being generated in every file that includes the private header
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a new QFinalState object with the given \a parent state.
|
||||
*/
|
||||
@ -97,6 +92,15 @@ QFinalState::QFinalState(QState *parent)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
QFinalState::QFinalState(QFinalStatePrivate &dd, QState *parent)
|
||||
: QAbstractState(dd, parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Destroys this final state.
|
||||
*/
|
||||
|
@ -38,7 +38,6 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
#ifndef QT_NO_STATEMACHINE
|
||||
|
||||
class QFinalStatePrivate;
|
||||
@ -55,6 +54,9 @@ protected:
|
||||
|
||||
bool event(QEvent *e) Q_DECL_OVERRIDE;
|
||||
|
||||
protected:
|
||||
explicit QFinalState(QFinalStatePrivate &dd, QState *parent);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QFinalState)
|
||||
Q_DECLARE_PRIVATE(QFinalState)
|
||||
|
68
src/corelib/statemachine/qfinalstate_p.h
Normal file
68
src/corelib/statemachine/qfinalstate_p.h
Normal 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
|
@ -31,11 +31,10 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qstate.h"
|
||||
#include "qstate_p.h"
|
||||
|
||||
#ifndef QT_NO_STATEMACHINE
|
||||
|
||||
#include "qstate_p.h"
|
||||
#include "qhistorystate.h"
|
||||
#include "qhistorystate_p.h"
|
||||
#include "qabstracttransition.h"
|
||||
|
@ -45,6 +45,7 @@
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qstate.h"
|
||||
#include "private/qabstractstate_p.h"
|
||||
|
||||
#include <QtCore/qlist.h>
|
||||
@ -52,6 +53,8 @@
|
||||
#include <QtCore/qpointer.h>
|
||||
#include <QtCore/qvariant.h>
|
||||
|
||||
#ifndef QT_NO_STATEMACHINE
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifndef QT_NO_PROPERTIES
|
||||
@ -83,7 +86,7 @@ class QAbstractTransition;
|
||||
class QHistoryState;
|
||||
|
||||
class QState;
|
||||
class Q_AUTOTEST_EXPORT QStatePrivate : public QAbstractStatePrivate
|
||||
class Q_CORE_EXPORT QStatePrivate : public QAbstractStatePrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QState)
|
||||
public:
|
||||
@ -115,4 +118,6 @@ public:
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_STATEMACHINE
|
||||
|
||||
#endif
|
||||
|
@ -6,6 +6,7 @@ HEADERS += $$PWD/qstatemachine.h \
|
||||
$$PWD/qstate.h \
|
||||
$$PWD/qstate_p.h \
|
||||
$$PWD/qfinalstate.h \
|
||||
$$PWD/qfinalstate_p.h \
|
||||
$$PWD/qhistorystate.h \
|
||||
$$PWD/qhistorystate_p.h \
|
||||
$$PWD/qabstracttransition.h \
|
||||
|
@ -125,14 +125,13 @@ bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
|
||||
}
|
||||
const SectionNode &node = sectionNodes.at(index);
|
||||
|
||||
int year, month, day, hour, minute, second, msec;
|
||||
year = v.date().year();
|
||||
month = v.date().month();
|
||||
day = v.date().day();
|
||||
hour = v.time().hour();
|
||||
minute = v.time().minute();
|
||||
second = v.time().second();
|
||||
msec = v.time().msec();
|
||||
int year = v.date().year();
|
||||
int month = v.date().month();
|
||||
int day = v.date().day();
|
||||
int hour = v.time().hour();
|
||||
int minute = v.time().minute();
|
||||
int second = v.time().second();
|
||||
int msec = v.time().msec();
|
||||
|
||||
switch (node.type) {
|
||||
case Hour24Section: case Hour12Section: hour = newVal; break;
|
||||
@ -670,15 +669,7 @@ QString QDateTimeParser::sectionText(const QString &text, int sectionIndex, int
|
||||
QString QDateTimeParser::sectionText(int sectionIndex) const
|
||||
{
|
||||
const SectionNode &sn = sectionNode(sectionIndex);
|
||||
switch (sn.type) {
|
||||
case NoSectionIndex:
|
||||
case FirstSectionIndex:
|
||||
case LastSectionIndex:
|
||||
return QString();
|
||||
default: break;
|
||||
}
|
||||
|
||||
return displayText().mid(sn.pos, sectionSize(sectionIndex));
|
||||
return sectionText(displayText(), sectionIndex, sn.pos);
|
||||
}
|
||||
|
||||
|
||||
@ -1006,8 +997,10 @@ QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPos
|
||||
|
||||
const QDate date(year, month, day);
|
||||
const int diff = dayofweek - date.dayOfWeek();
|
||||
if (diff != 0 && state == Acceptable && isSet & (DayOfWeekSectionShort|DayOfWeekSectionLong)) {
|
||||
conflicts = isSet & DaySection;
|
||||
if (diff != 0 && state == Acceptable
|
||||
&& isSet & (DayOfWeekSectionShort | DayOfWeekSectionLong)) {
|
||||
if (isSet & DaySection)
|
||||
conflicts = true;
|
||||
const SectionNode &sn = sectionNode(currentSectionIndex);
|
||||
if (sn.type & (DayOfWeekSectionShort|DayOfWeekSectionLong) || currentSectionIndex == -1) {
|
||||
// dayofweek should be preferred
|
||||
@ -1371,9 +1364,9 @@ int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex
|
||||
|
||||
*/
|
||||
|
||||
int QDateTimeParser::findAmPm(QString &str, int index, int *used) const
|
||||
int QDateTimeParser::findAmPm(QString &str, int sectionIndex, int *used) const
|
||||
{
|
||||
const SectionNode &s = sectionNode(index);
|
||||
const SectionNode &s = sectionNode(sectionIndex);
|
||||
if (s.type != AmPmSection) {
|
||||
qWarning("QDateTimeParser::findAmPm Internal error");
|
||||
return -1;
|
||||
@ -1384,7 +1377,7 @@ int QDateTimeParser::findAmPm(QString &str, int index, int *used) const
|
||||
return PossibleBoth;
|
||||
}
|
||||
const QLatin1Char space(' ');
|
||||
int size = sectionMaxSize(index);
|
||||
int size = sectionMaxSize(sectionIndex);
|
||||
|
||||
enum {
|
||||
amindex = 0,
|
||||
|
@ -87,7 +87,7 @@ public:
|
||||
first.pos = -1;
|
||||
first.count = -1;
|
||||
first.zeroesAdded = 0;
|
||||
last.type = FirstSection;
|
||||
last.type = LastSection;
|
||||
last.pos = -1;
|
||||
last.count = -1;
|
||||
last.zeroesAdded = 0;
|
||||
|
@ -236,9 +236,9 @@ template <> struct QConcatenable<QLatin1String> : private QAbstractConcatenable
|
||||
}
|
||||
static inline void appendTo(const QLatin1String a, char *&out)
|
||||
{
|
||||
if (a.data()) {
|
||||
for (const char *s = a.data(); *s; )
|
||||
*out++ = *s++;
|
||||
if (const char *data = a.data()) {
|
||||
memcpy(out, data, a.size());
|
||||
out += a.size();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -807,7 +807,6 @@ bool QDBusConnectionPrivate::activateCall(QObject* object, int flags, const QDBu
|
||||
if (!object)
|
||||
return false;
|
||||
|
||||
#ifndef QT_NO_PROPERTIES
|
||||
Q_ASSERT_X(QThread::currentThread() == object->thread(),
|
||||
"QDBusConnection: internal threading error",
|
||||
"function called for an object that is in another thread!!");
|
||||
@ -866,7 +865,6 @@ bool QDBusConnectionPrivate::activateCall(QObject* object, int flags, const QDBu
|
||||
deliverCall(object, flags, msg, cacheIt->metaTypes, cacheIt->slotIdx);
|
||||
return true;
|
||||
}
|
||||
#endif // QT_NO_PROPERTIES
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1758,15 +1758,8 @@ QAccessibleInterface *QAccessibleEvent::accessibleInterface() const
|
||||
return QAccessible::accessibleInterface(m_uniqueId);
|
||||
|
||||
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(m_object);
|
||||
if (!iface || !iface->isValid()) {
|
||||
static bool hasWarned = false;
|
||||
if (!iface && !hasWarned) {
|
||||
qWarning() << "Problem creating accessible interface for: " << m_object << endl
|
||||
<< "Make sure to deploy Qt with accessibility plugins.";
|
||||
hasWarned = true;
|
||||
}
|
||||
if (!iface || !iface->isValid())
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (m_child >= 0) {
|
||||
QAccessibleInterface *child = iface->child(m_child);
|
||||
|
@ -921,15 +921,10 @@ QList<QScreen *> QGuiApplication::screens()
|
||||
/*!
|
||||
\property QGuiApplication::primaryScreen
|
||||
|
||||
\brief the primary (or default) screen of the application, or null if there is none.
|
||||
\brief the primary (or default) screen of the application.
|
||||
|
||||
This will be the screen where QWindows are initially shown, unless otherwise specified.
|
||||
|
||||
On some platforms, it may be null when there are actually no screens connected.
|
||||
It is not possible to start a new QGuiApplication while there are no screens.
|
||||
Applications which were running at the time the primary screen was removed
|
||||
will stop rendering graphics until one or more screens are restored.
|
||||
|
||||
The primaryScreenChanged signal was introduced in Qt 5.6.
|
||||
|
||||
\sa screens()
|
||||
@ -1058,7 +1053,7 @@ static void init_platform(const QString &pluginArgument, const QString &platform
|
||||
QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
|
||||
|
||||
QString fatalMessage
|
||||
= QStringLiteral("This application failed to start because it could not find or load the Qt platform plugin \"%1\".\n\n").arg(name);
|
||||
= QStringLiteral("This application failed to start because it could not find or load the Qt platform plugin \"%1\"\nin \"%2\".\n\n").arg(name, QDir::toNativeSeparators(platformPluginPath));
|
||||
if (!keys.isEmpty()) {
|
||||
fatalMessage += QStringLiteral("Available platform plugins are: %1.\n\n").arg(
|
||||
keys.join(QStringLiteral(", ")));
|
||||
@ -1960,6 +1955,16 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE
|
||||
window = QGuiApplication::focusWindow();
|
||||
}
|
||||
|
||||
#if !defined(Q_OS_OSX)
|
||||
// FIXME: Include OS X in this code path by passing the key event through
|
||||
// QPlatformInputContext::filterEvent().
|
||||
if (e->keyType == QEvent::KeyPress && window) {
|
||||
if (QWindowSystemInterface::handleShortcutEvent(window, e->timestamp, e->key, e->modifiers,
|
||||
e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers, e->unicode, e->repeat, e->repeatCount))
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
QKeyEvent ev(e->keyType, e->key, e->modifiers,
|
||||
e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers,
|
||||
e->unicode, e->repeat, e->repeatCount);
|
||||
|
@ -140,6 +140,23 @@ static int qtkeyForMacSymbol(const QChar ch)
|
||||
#else
|
||||
static bool qt_sequence_no_mnemonics = false;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\fn void qt_set_sequence_auto_mnemonic(bool b)
|
||||
\relates QKeySequence
|
||||
|
||||
Specifies whether mnemonics for menu items, labels, etc., should
|
||||
be honored or not. On Windows and X11, this feature is
|
||||
on by default; on OS X, it is off. When this feature is off
|
||||
(that is, when \a b is false), QKeySequence::mnemonic() always
|
||||
returns an empty string.
|
||||
|
||||
\note This function is not declared in any of Qt's header files.
|
||||
To use it in your application, declare the function prototype
|
||||
before calling it.
|
||||
|
||||
\sa QShortcut
|
||||
*/
|
||||
void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemonics = !b; }
|
||||
|
||||
/*!
|
||||
|
@ -52,7 +52,7 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifndef QT_NO_SHORTCUT
|
||||
struct Q_AUTOTEST_EXPORT QKeyBinding
|
||||
struct QKeyBinding
|
||||
{
|
||||
QKeySequence::StandardKey standardKey;
|
||||
uchar priority;
|
||||
@ -60,7 +60,7 @@ struct Q_AUTOTEST_EXPORT QKeyBinding
|
||||
uint platform;
|
||||
};
|
||||
|
||||
class Q_AUTOTEST_EXPORT QKeySequencePrivate
|
||||
class QKeySequencePrivate
|
||||
{
|
||||
public:
|
||||
enum { MaxKeyCount = 4 }; // also used in QKeySequenceEdit
|
||||
|
@ -249,8 +249,10 @@ bool QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Q
|
||||
|
||||
bool QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
|
||||
{
|
||||
#if defined(Q_OS_OSX)
|
||||
if (t == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(tlw, timestamp, k, mods, 0, 0, 0, text, autorep, count))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
QWindowSystemInterfacePrivate::KeyEvent * e =
|
||||
new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count);
|
||||
@ -275,10 +277,14 @@ bool QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestam
|
||||
const QString& text, bool autorep,
|
||||
ushort count, bool tryShortcutOverride)
|
||||
{
|
||||
#if defined(Q_OS_OSX)
|
||||
if (tryShortcutOverride && type == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(tlw,
|
||||
timestamp, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count)) {
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(tryShortcutOverride)
|
||||
#endif
|
||||
|
||||
QWindowSystemInterfacePrivate::KeyEvent * e =
|
||||
new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, type, key, modifiers,
|
||||
|
@ -2809,6 +2809,10 @@ QFontEngine *QFontCache::findEngine(const Key &key)
|
||||
EngineCache::Iterator it = engineCache.find(key),
|
||||
end = engineCache.end();
|
||||
if (it == end) return 0;
|
||||
|
||||
Q_ASSERT(it.value().data != Q_NULLPTR);
|
||||
Q_ASSERT(key.multi == (it.value().data->type() == QFontEngine::Multi));
|
||||
|
||||
// found... update the hitcount and timestamp
|
||||
updateHitCountAndTimeStamp(it.value());
|
||||
|
||||
@ -2829,6 +2833,9 @@ void QFontCache::updateHitCountAndTimeStamp(Engine &value)
|
||||
|
||||
void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMulti)
|
||||
{
|
||||
Q_ASSERT(engine != Q_NULLPTR);
|
||||
Q_ASSERT(key.multi == (engine->type() == QFontEngine::Multi));
|
||||
|
||||
#ifdef QFONTCACHE_DEBUG
|
||||
FC_DEBUG("QFontCache: inserting new engine %p, refcount %d", engine, engine->ref.load());
|
||||
if (!insertMulti && engineCache.contains(key)) {
|
||||
|
@ -921,23 +921,28 @@ QFontEngine *loadSingleEngine(int script,
|
||||
QFontDef def = request;
|
||||
def.pixelSize = pixelSize;
|
||||
|
||||
QFontCache *fontCache = QFontCache::instance();
|
||||
|
||||
QFontCache::Key key(def,script);
|
||||
QFontEngine *engine = QFontCache::instance()->findEngine(key);
|
||||
QFontEngine *engine = fontCache->findEngine(key);
|
||||
if (!engine) {
|
||||
if (script != QChar::Script_Common) {
|
||||
const bool cacheForCommonScript = script != QChar::Script_Common
|
||||
&& (family->writingSystems[QFontDatabase::Latin] & QtFontFamily::Supported) != 0;
|
||||
|
||||
if (Q_LIKELY(cacheForCommonScript)) {
|
||||
// fast path: check if engine was loaded for another script
|
||||
key.script = QChar::Script_Common;
|
||||
engine = QFontCache::instance()->findEngine(key);
|
||||
engine = fontCache->findEngine(key);
|
||||
key.script = script;
|
||||
if (engine) {
|
||||
Q_ASSERT(engine->type() != QFontEngine::Multi);
|
||||
// Also check for OpenType tables when using complex scripts
|
||||
if (Q_UNLIKELY(!engine->supportsScript(QChar::Script(script)))) {
|
||||
qWarning(" OpenType support missing for script %d", script);
|
||||
return 0;
|
||||
}
|
||||
|
||||
QFontCache::instance()->insertEngine(key, engine);
|
||||
fontCache->insertEngine(key, engine);
|
||||
|
||||
return engine;
|
||||
}
|
||||
}
|
||||
@ -945,13 +950,13 @@ QFontEngine *loadSingleEngine(int script,
|
||||
// If the font data's native stretch matches the requested stretch we need to set stretch to 100
|
||||
// to avoid the fontengine synthesizing stretch. If they didn't match exactly we need to calculate
|
||||
// the new stretch factor. This only done if not matched by styleName.
|
||||
bool styleNameMatch = !request.styleName.isEmpty() && request.styleName == style->styleName;
|
||||
if (!styleNameMatch && style->key.stretch != 0 && request.stretch != 0)
|
||||
if (style->key.stretch != 0 && request.stretch != 0
|
||||
&& (request.styleName.isEmpty() || request.styleName != style->styleName)) {
|
||||
def.stretch = (request.stretch * 100 + 50) / style->key.stretch;
|
||||
}
|
||||
|
||||
engine = pfdb->fontEngine(def, size->handle);
|
||||
if (engine) {
|
||||
Q_ASSERT(engine->type() != QFontEngine::Multi);
|
||||
// Also check for OpenType tables when using complex scripts
|
||||
if (!engine->supportsScript(QChar::Script(script))) {
|
||||
qWarning(" OpenType support missing for script %d", script);
|
||||
@ -960,13 +965,13 @@ QFontEngine *loadSingleEngine(int script,
|
||||
return 0;
|
||||
}
|
||||
|
||||
QFontCache::instance()->insertEngine(key, engine);
|
||||
fontCache->insertEngine(key, engine);
|
||||
|
||||
if (!engine->symbol && script != QChar::Script_Common && (family->writingSystems[QFontDatabase::Latin] & QtFontFamily::Supported) != 0) {
|
||||
if (Q_LIKELY(cacheForCommonScript && !engine->symbol)) {
|
||||
// cache engine for Common script as well
|
||||
key.script = QChar::Script_Common;
|
||||
if (!QFontCache::instance()->findEngine(key))
|
||||
QFontCache::instance()->insertEngine(key, engine);
|
||||
if (!fontCache->findEngine(key))
|
||||
fontCache->insertEngine(key, engine);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -979,7 +984,7 @@ QFontEngine *loadEngine(int script, const QFontDef &request,
|
||||
QtFontStyle *style, QtFontSize *size)
|
||||
{
|
||||
QFontEngine *engine = loadSingleEngine(script, request, family, foundry, style, size);
|
||||
Q_ASSERT(!engine || engine->type() != QFontEngine::Multi);
|
||||
|
||||
if (engine && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) {
|
||||
QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
|
||||
QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine, QChar::Script(script));
|
||||
@ -2635,12 +2640,14 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
|
||||
}
|
||||
#endif
|
||||
|
||||
QFontCache *fontCache = QFontCache::instance();
|
||||
|
||||
// Until we specifically asked not to, try looking for Multi font engine
|
||||
// first, the last '1' indicates that we want Multi font engine instead
|
||||
// of single ones
|
||||
bool multi = !(request.styleStrategy & QFont::NoFontMerging);
|
||||
QFontCache::Key key(request, script, multi ? 1 : 0);
|
||||
engine = QFontCache::instance()->findEngine(key);
|
||||
engine = fontCache->findEngine(key);
|
||||
if (engine) {
|
||||
FM_DEBUG("Cache hit level 1");
|
||||
return engine;
|
||||
@ -2681,7 +2688,7 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
|
||||
QFontDef def = request;
|
||||
def.family = fallbacks.at(i);
|
||||
QFontCache::Key key(def, script, multi ? 1 : 0);
|
||||
engine = QFontCache::instance()->findEngine(key);
|
||||
engine = fontCache->findEngine(key);
|
||||
if (!engine) {
|
||||
QtFontDesc desc;
|
||||
do {
|
||||
@ -2725,13 +2732,21 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
|
||||
if (req.stretch == 0)
|
||||
req.stretch = 100;
|
||||
|
||||
// respect the fallback families that might be passed through the request
|
||||
const QStringList fallBackFamilies = familyList(req);
|
||||
|
||||
if (!d->engineData) {
|
||||
QFontCache *fontCache = QFontCache::instance();
|
||||
// look for the requested font in the engine data cache
|
||||
d->engineData = QFontCache::instance()->findEngineData(req);
|
||||
// note: fallBackFamilies are not respected in the EngineData cache key;
|
||||
// join them with the primary selection family to avoid cache misses
|
||||
req.family = fallBackFamilies.join(QLatin1Char(','));
|
||||
|
||||
d->engineData = fontCache->findEngineData(req);
|
||||
if (!d->engineData) {
|
||||
// create a new one
|
||||
d->engineData = new QFontEngineData;
|
||||
QFontCache::instance()->insertEngineData(req, d->engineData);
|
||||
fontCache->insertEngineData(req, d->engineData);
|
||||
}
|
||||
d->engineData->ref.ref();
|
||||
}
|
||||
@ -2740,25 +2755,18 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
|
||||
if (d->engineData->engines[script])
|
||||
return;
|
||||
|
||||
// Until we specifically asked not to, try looking for Multi font engine
|
||||
// first, the last '1' indicates that we want Multi font engine instead
|
||||
// of single ones
|
||||
bool multi = !(req.styleStrategy & QFont::NoFontMerging);
|
||||
QFontCache::Key key(req, script, multi ? 1 : 0);
|
||||
QFontEngine *fe = Q_NULLPTR;
|
||||
|
||||
QFontEngine *fe = QFontCache::instance()->findEngine(key);
|
||||
req.fallBackFamilies = fallBackFamilies;
|
||||
if (!req.fallBackFamilies.isEmpty())
|
||||
req.family = req.fallBackFamilies.takeFirst();
|
||||
|
||||
// list of families to try
|
||||
QStringList family_list;
|
||||
|
||||
if (!req.family.isEmpty()) {
|
||||
QStringList familiesForRequest = familyList(req);
|
||||
|
||||
// Add primary selection
|
||||
family_list << familiesForRequest.takeFirst();
|
||||
|
||||
// Fallbacks requested in font request
|
||||
req.fallBackFamilies = familiesForRequest;
|
||||
family_list << req.family;
|
||||
|
||||
// add the default family
|
||||
QString defaultFamily = QGuiApplication::font().family();
|
||||
|
@ -2290,7 +2290,7 @@ QFontEngine *QFontEngineMulti::createMultiFontEngine(QFontEngine *fe, int script
|
||||
}
|
||||
if (!engine) {
|
||||
engine = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fontEngineMulti(fe, QChar::Script(script));
|
||||
QFontCache::instance()->insertEngine(key, engine, /* insertMulti */ !faceIsLocal);
|
||||
fc->insertEngine(key, engine, /* insertMulti */ !faceIsLocal);
|
||||
}
|
||||
Q_ASSERT(engine);
|
||||
return engine;
|
||||
|
@ -121,14 +121,15 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
|
||||
bool haveDirectConnection = false;
|
||||
foreach (const QUrl& url, rawProxies) {
|
||||
QNetworkProxy::ProxyType type;
|
||||
if (url.scheme() == QStringLiteral("http")) {
|
||||
const QString scheme = url.scheme();
|
||||
if (scheme == QLatin1String("http")) {
|
||||
type = QNetworkProxy::HttpProxy;
|
||||
} else if (url.scheme() == QStringLiteral("socks")
|
||||
|| url.scheme() == QStringLiteral("socks5")) {
|
||||
} else if (scheme == QLatin1String("socks")
|
||||
|| scheme == QLatin1String("socks5")) {
|
||||
type = QNetworkProxy::Socks5Proxy;
|
||||
} else if (url.scheme() == QStringLiteral("ftp")) {
|
||||
} else if (scheme == QLatin1String("ftp")) {
|
||||
type = QNetworkProxy::FtpCachingProxy;
|
||||
} else if (url.scheme() == QStringLiteral("direct")) {
|
||||
} else if (scheme == QLatin1String("direct")) {
|
||||
type = QNetworkProxy::NoProxy;
|
||||
haveDirectConnection = true;
|
||||
} else {
|
||||
|
@ -49,7 +49,7 @@ QDBusPlatformMenuItem::QDBusPlatformMenuItem(quintptr tag)
|
||||
: m_tag(tag ? tag : reinterpret_cast<quintptr>(this)) // QMenu will overwrite this later
|
||||
, m_subMenu(Q_NULLPTR)
|
||||
, m_role(NoRole)
|
||||
, m_isEnabled(false)
|
||||
, m_isEnabled(true)
|
||||
, m_isVisible(true)
|
||||
, m_isSeparator(false)
|
||||
, m_isCheckable(false)
|
||||
@ -146,7 +146,7 @@ QList<const QDBusPlatformMenuItem *> QDBusPlatformMenuItem::byIds(const QList<in
|
||||
|
||||
QDBusPlatformMenu::QDBusPlatformMenu(quintptr tag)
|
||||
: m_tag(tag ? tag : reinterpret_cast<quintptr>(this))
|
||||
, m_isEnabled(false)
|
||||
, m_isEnabled(true)
|
||||
, m_isVisible(true)
|
||||
, m_isSeparator(false)
|
||||
, m_dbusID(nextDBusID++)
|
||||
|
@ -1961,71 +1961,71 @@ namespace
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=744553 "ATK docs provide no guidance for allowed values of some text attributes"
|
||||
// specifically for "weight", "invalid", "language" and value range for colors
|
||||
|
||||
if (ia2Name == QStringLiteral("background-color")) {
|
||||
if (ia2Name == QLatin1String("background-color")) {
|
||||
name = QStringLiteral("bg-color");
|
||||
value = atspiColor(value);
|
||||
} else if (ia2Name == QStringLiteral("font-family")) {
|
||||
} else if (ia2Name == QLatin1String("font-family")) {
|
||||
name = QStringLiteral("family-name");
|
||||
} else if (ia2Name == QStringLiteral("color")) {
|
||||
} else if (ia2Name == QLatin1String("color")) {
|
||||
name = QStringLiteral("fg-color");
|
||||
value = atspiColor(value);
|
||||
} else if (ia2Name == QStringLiteral("text-align")) {
|
||||
} else if (ia2Name == QLatin1String("text-align")) {
|
||||
name = QStringLiteral("justification");
|
||||
if (value == QStringLiteral("justify")) {
|
||||
if (value == QLatin1String("justify")) {
|
||||
value = QStringLiteral("fill");
|
||||
} else {
|
||||
if (value != QStringLiteral("left") &&
|
||||
value != QStringLiteral("right") &&
|
||||
value != QStringLiteral("center")
|
||||
if (value != QLatin1String("left") &&
|
||||
value != QLatin1String("right") &&
|
||||
value != QLatin1String("center")
|
||||
) {
|
||||
value = QString();
|
||||
qAtspiDebug() << "Unknown text-align attribute value \"" << value << "\" cannot be translated to AT-SPI.";
|
||||
}
|
||||
}
|
||||
} else if (ia2Name == QStringLiteral("font-size")) {
|
||||
} else if (ia2Name == QLatin1String("font-size")) {
|
||||
name = QStringLiteral("size");
|
||||
value = atspiSize(value);
|
||||
} else if (ia2Name == QStringLiteral("font-style")) {
|
||||
} else if (ia2Name == QLatin1String("font-style")) {
|
||||
name = QStringLiteral("style");
|
||||
if (value != QStringLiteral("normal") &&
|
||||
value != QStringLiteral("italic") &&
|
||||
value != QStringLiteral("oblique")
|
||||
if (value != QLatin1String("normal") &&
|
||||
value != QLatin1String("italic") &&
|
||||
value != QLatin1String("oblique")
|
||||
) {
|
||||
value = QString();
|
||||
qAtspiDebug() << "Unknown font-style attribute value \"" << value << "\" cannot be translated to AT-SPI.";
|
||||
}
|
||||
} else if (ia2Name == QStringLiteral("text-underline-type")) {
|
||||
} else if (ia2Name == QLatin1String("text-underline-type")) {
|
||||
name = QStringLiteral("underline");
|
||||
if (value != QStringLiteral("none") &&
|
||||
value != QStringLiteral("single") &&
|
||||
value != QStringLiteral("double")
|
||||
if (value != QLatin1String("none") &&
|
||||
value != QLatin1String("single") &&
|
||||
value != QLatin1String("double")
|
||||
) {
|
||||
value = QString();
|
||||
qAtspiDebug() << "Unknown text-underline-type attribute value \"" << value << "\" cannot be translated to AT-SPI.";
|
||||
}
|
||||
} else if (ia2Name == QStringLiteral("font-weight")) {
|
||||
} else if (ia2Name == QLatin1String("font-weight")) {
|
||||
name = QStringLiteral("weight");
|
||||
if (value == QStringLiteral("normal"))
|
||||
if (value == QLatin1String("normal"))
|
||||
// Orca seems to accept all IAccessible2 values except for "normal"
|
||||
// (on which it produces traceback and fails to read any following text attributes),
|
||||
// but that is the default value, so omit it anyway
|
||||
value = QString();
|
||||
} else if (ia2Name == QStringLiteral("text-position")) {
|
||||
} else if (ia2Name == QLatin1String("text-position")) {
|
||||
name = QStringLiteral("vertical-align");
|
||||
if (value != QStringLiteral("baseline") &&
|
||||
value != QStringLiteral("super") &&
|
||||
value != QStringLiteral("sub")
|
||||
if (value != QLatin1String("baseline") &&
|
||||
value != QLatin1String("super") &&
|
||||
value != QLatin1String("sub")
|
||||
) {
|
||||
value = QString();
|
||||
qAtspiDebug() << "Unknown text-position attribute value \"" << value << "\" cannot be translated to AT-SPI.";
|
||||
}
|
||||
} else if (ia2Name == QStringLiteral("writing-mode")) {
|
||||
} else if (ia2Name == QLatin1String("writing-mode")) {
|
||||
name = QStringLiteral("direction");
|
||||
if (value == QStringLiteral("lr"))
|
||||
if (value == QLatin1String("lr"))
|
||||
value = QStringLiteral("ltr");
|
||||
else if (value == QStringLiteral("rl"))
|
||||
else if (value == QLatin1String("rl"))
|
||||
value = QStringLiteral("rtl");
|
||||
else if (value == QStringLiteral("tb")) {
|
||||
else if (value == QLatin1String("tb")) {
|
||||
// IAccessible2 docs refer to XSL, which specifies "tb" is shorthand for "tb-rl"; so at least give a hint about the horizontal direction (ATK does not support vertical direction in this attribute (yet))
|
||||
value = QStringLiteral("rtl");
|
||||
qAtspiDebug() << "writing-mode attribute value \"tb\" translated only w.r.t. horizontal direction; vertical direction ignored";
|
||||
@ -2033,9 +2033,9 @@ namespace
|
||||
value = QString();
|
||||
qAtspiDebug() << "Unknown writing-mode attribute value \"" << value << "\" cannot be translated to AT-SPI.";
|
||||
}
|
||||
} else if (ia2Name == QStringLiteral("language")) {
|
||||
} else if (ia2Name == QLatin1String("language")) {
|
||||
// OK - ATK has no docs on the format of the value, IAccessible2 has reasonable format - leave it at that now
|
||||
} else if (ia2Name == QStringLiteral("invalid")) {
|
||||
} else if (ia2Name == QLatin1String("invalid")) {
|
||||
// OK - ATK docs are vague but suggest they support the same range of values as IAccessible2
|
||||
} else {
|
||||
// attribute we know nothing about
|
||||
|
@ -1030,17 +1030,17 @@ QNetworkConfiguration::BearerType QNetworkManagerEngine::currentBearerType(const
|
||||
|
||||
QString bearer = i.value()->bearer();
|
||||
|
||||
if (bearer == QStringLiteral("gsm")) {
|
||||
if (bearer == QLatin1String("gsm")) {
|
||||
return QNetworkConfiguration::Bearer2G;
|
||||
} else if (bearer == QStringLiteral("edge")) {
|
||||
} else if (bearer == QLatin1String("edge")) {
|
||||
return QNetworkConfiguration::Bearer2G;
|
||||
} else if (bearer == QStringLiteral("umts")) {
|
||||
} else if (bearer == QLatin1String("umts")) {
|
||||
return QNetworkConfiguration::BearerWCDMA;
|
||||
} else if (bearer == QStringLiteral("hspa")
|
||||
|| bearer == QStringLiteral("hsdpa")
|
||||
|| bearer == QStringLiteral("hsupa")) {
|
||||
} else if (bearer == QLatin1String("hspa")
|
||||
|| bearer == QLatin1String("hsdpa")
|
||||
|| bearer == QLatin1String("hsupa")) {
|
||||
return QNetworkConfiguration::BearerHSPA;
|
||||
} else if (bearer == QStringLiteral("lte")) {
|
||||
} else if (bearer == QLatin1String("lte")) {
|
||||
return QNetworkConfiguration::BearerLTE;
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ void QNetworkManagerInterface::propertiesSwap(QMap<QString,QVariant> map)
|
||||
i.next();
|
||||
propertyMap.insert(i.key(),i.value());
|
||||
|
||||
if (i.key() == QStringLiteral("State")) {
|
||||
if (i.key() == QLatin1String("State")) {
|
||||
quint32 state = i.value().toUInt();
|
||||
if (state == NM_DEVICE_STATE_ACTIVATED
|
||||
|| state == NM_DEVICE_STATE_DISCONNECTED
|
||||
@ -223,7 +223,7 @@ void QNetworkManagerInterface::propertiesSwap(QMap<QString,QVariant> map)
|
||||
Q_EMIT propertiesChanged(map);
|
||||
Q_EMIT stateChanged(state);
|
||||
}
|
||||
} else if (i.key() == QStringLiteral("ActiveConnections")) {
|
||||
} else if (i.key() == QLatin1String("ActiveConnections")) {
|
||||
Q_EMIT propertiesChanged(map);
|
||||
}
|
||||
}
|
||||
@ -418,7 +418,7 @@ void QNetworkManagerInterfaceDevice::propertiesSwap(QMap<QString,QVariant> map)
|
||||
QMapIterator<QString, QVariant> i(map);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
if (i.key() == QStringLiteral("AvailableConnections")) { //Device
|
||||
if (i.key() == QLatin1String("AvailableConnections")) { //Device
|
||||
const QDBusArgument &dbusArgs = i.value().value<QDBusArgument>();
|
||||
QDBusObjectPath path;
|
||||
QStringList paths;
|
||||
@ -514,10 +514,9 @@ void QNetworkManagerInterfaceDeviceWired::propertiesSwap(QMap<QString,QVariant>
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
propertyMap.insert(i.key(),i.value());
|
||||
if (i.key() == QStringLiteral("Carrier")) {
|
||||
if (i.key() == QLatin1String("Carrier"))
|
||||
Q_EMIT carrierChanged(i.value().toBool());
|
||||
}
|
||||
}
|
||||
Q_EMIT propertiesChanged(map);
|
||||
}
|
||||
|
||||
@ -693,10 +692,9 @@ void QNetworkManagerInterfaceDeviceWireless::propertiesSwap(QMap<QString,QVarian
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
propertyMap.insert(i.key(),i.value());
|
||||
if (i.key() == QStringLiteral("ActiveAccessPoint")) { //DeviceWireless
|
||||
if (i.key() == QLatin1String("ActiveAccessPoint")) //DeviceWireless
|
||||
Q_EMIT propertiesChanged(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QNetworkManagerInterfaceDeviceModem::QNetworkManagerInterfaceDeviceModem(const QString &ifaceDevicePath, QObject *parent)
|
||||
@ -1051,7 +1049,7 @@ void QNetworkManagerConnectionActive::propertiesSwap(QMap<QString,QVariant> map)
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
propertyMap.insert(i.key(),i.value());
|
||||
if (i.key() == QStringLiteral("State")) {
|
||||
if (i.key() == QLatin1String("State")) {
|
||||
quint32 state = i.value().toUInt();
|
||||
if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
|
||||
|| state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
|
||||
|
@ -273,7 +273,7 @@ QString TableGenerator::findComposeFile()
|
||||
// check if user’s home directory has a file named .XCompose
|
||||
if (cleanState()) {
|
||||
QString path = qgetenv("HOME") + QStringLiteral("/.XCompose");
|
||||
if (QFile(path).exists())
|
||||
if (QFile::exists(path))
|
||||
return path;
|
||||
}
|
||||
|
||||
@ -286,7 +286,7 @@ QString TableGenerator::findComposeFile()
|
||||
m_state = UnsupportedLocale;
|
||||
else {
|
||||
QString path = QDir(systemComposeDir()).filePath(table);
|
||||
if (QFile(path).exists())
|
||||
if (QFile::exists(path))
|
||||
return path;
|
||||
}
|
||||
}
|
||||
@ -308,7 +308,7 @@ bool TableGenerator::findSystemComposeDir()
|
||||
bool found = false;
|
||||
for (int i = 0; i < m_possibleLocations.size(); ++i) {
|
||||
QString path = m_possibleLocations.at(i);
|
||||
if (QFile(path + QLatin1String("/compose.dir")).exists()) {
|
||||
if (QFile::exists(path + QLatin1String("/compose.dir"))) {
|
||||
m_systemComposeDir = path;
|
||||
found = true;
|
||||
break;
|
||||
|
@ -356,6 +356,15 @@ namespace QtAndroid
|
||||
return surfaceId;
|
||||
}
|
||||
|
||||
void setViewVisibility(jobject view, bool visible)
|
||||
{
|
||||
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass,
|
||||
"setViewVisibility",
|
||||
"(Landroid/view/View;Z)V",
|
||||
view,
|
||||
visible);
|
||||
}
|
||||
|
||||
void setSurfaceGeometry(int surfaceId, const QRect &geometry)
|
||||
{
|
||||
if (surfaceId == -1)
|
||||
|
@ -62,6 +62,7 @@ namespace QtAndroid
|
||||
|
||||
int createSurface(AndroidSurfaceClient * client, const QRect &geometry, bool onTop, int imageDepth);
|
||||
int insertNativeView(jobject view, const QRect &geometry);
|
||||
void setViewVisibility(jobject view, bool visible);
|
||||
void setSurfaceGeometry(int surfaceId, const QRect &geometry);
|
||||
void destroySurface(int surfaceId);
|
||||
void bringChildToFront(int surfaceId);
|
||||
|
@ -45,10 +45,14 @@ QAndroidPlatformForeignWindow::QAndroidPlatformForeignWindow(QWindow *window)
|
||||
{
|
||||
const WId wId = window->property("_q_foreignWinId").value<WId>();
|
||||
m_view = reinterpret_cast<jobject>(wId);
|
||||
if (m_view.isValid())
|
||||
QtAndroid::setViewVisibility(m_view.object(), false);
|
||||
}
|
||||
|
||||
QAndroidPlatformForeignWindow::~QAndroidPlatformForeignWindow()
|
||||
{
|
||||
if (m_view.isValid())
|
||||
QtAndroid::setViewVisibility(m_view.object(), false);
|
||||
if (m_surfaceId != -1)
|
||||
QtAndroid::destroySurface(m_surfaceId);
|
||||
}
|
||||
@ -84,8 +88,9 @@ void QAndroidPlatformForeignWindow::setVisible(bool visible)
|
||||
if (!m_view.isValid())
|
||||
return;
|
||||
|
||||
QAndroidPlatformWindow::setVisible(visible);
|
||||
QtAndroid::setViewVisibility(m_view.object(), visible);
|
||||
|
||||
QAndroidPlatformWindow::setVisible(visible);
|
||||
if (!visible && m_surfaceId != -1) {
|
||||
QtAndroid::destroySurface(m_surfaceId);
|
||||
m_surfaceId = -1;
|
||||
|
@ -120,7 +120,9 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
|
||||
|
||||
QPoint hotSpot = m_drag->hotSpot();
|
||||
QPixmap pm = dragPixmap(m_drag, hotSpot);
|
||||
QSize pmDeviceIndependentSize = pm.size() / pm.devicePixelRatio();
|
||||
NSImage *nsimage = qt_mac_create_nsimage(pm);
|
||||
[nsimage setSize : qt_mac_toNSSize(pmDeviceIndependentSize)];
|
||||
|
||||
QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacInternalPasteboardMime::MIME_DND);
|
||||
m_drag->mimeData()->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy"));
|
||||
@ -130,7 +132,7 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
|
||||
NSWindow *theWindow = [m_lastEvent window];
|
||||
Q_ASSERT(theWindow != nil);
|
||||
event_location.x -= hotSpot.x();
|
||||
CGFloat flippedY = pm.height() - hotSpot.y();
|
||||
CGFloat flippedY = pmDeviceIndependentSize.height() - hotSpot.y();
|
||||
event_location.y -= flippedY;
|
||||
NSSize mouseOffset_unused = NSMakeSize(0.0, 0.0);
|
||||
NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
|
||||
|
@ -80,9 +80,6 @@ HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion ®ion);
|
||||
|
||||
OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage);
|
||||
|
||||
QChar qt_mac_qtKey2CocoaKey(Qt::Key key);
|
||||
Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode);
|
||||
|
||||
NSDragOperation qt_mac_mapDropAction(Qt::DropAction action);
|
||||
NSDragOperation qt_mac_mapDropActions(Qt::DropActions actions);
|
||||
Qt::DropAction qt_mac_mapNSDragOperation(NSDragOperation nsActions);
|
||||
|
@ -236,143 +236,6 @@ QColor qt_mac_toQColor(CGColorRef color)
|
||||
return qtColor;
|
||||
}
|
||||
|
||||
// Use this method to keep all the information in the TextSegment. As long as it is ordered
|
||||
// we are in OK shape, and we can influence that ourselves.
|
||||
struct KeyPair
|
||||
{
|
||||
QChar cocoaKey;
|
||||
Qt::Key qtKey;
|
||||
};
|
||||
|
||||
bool operator==(const KeyPair &entry, QChar qchar)
|
||||
{
|
||||
return entry.cocoaKey == qchar;
|
||||
}
|
||||
|
||||
bool operator<(const KeyPair &entry, QChar qchar)
|
||||
{
|
||||
return entry.cocoaKey < qchar;
|
||||
}
|
||||
|
||||
bool operator<(QChar qchar, const KeyPair &entry)
|
||||
{
|
||||
return qchar < entry.cocoaKey;
|
||||
}
|
||||
|
||||
bool operator<(const Qt::Key &key, const KeyPair &entry)
|
||||
{
|
||||
return key < entry.qtKey;
|
||||
}
|
||||
|
||||
bool operator<(const KeyPair &entry, const Qt::Key &key)
|
||||
{
|
||||
return entry.qtKey < key;
|
||||
}
|
||||
|
||||
struct qtKey2CocoaKeySortLessThan
|
||||
{
|
||||
typedef bool result_type;
|
||||
Q_DECL_CONSTEXPR result_type operator()(const KeyPair &entry1, const KeyPair &entry2) const Q_DECL_NOTHROW
|
||||
{
|
||||
return entry1.qtKey < entry2.qtKey;
|
||||
}
|
||||
};
|
||||
|
||||
static const int NumEntries = 59;
|
||||
static const KeyPair entries[NumEntries] = {
|
||||
{ NSEnterCharacter, Qt::Key_Enter },
|
||||
{ NSBackspaceCharacter, Qt::Key_Backspace },
|
||||
{ NSTabCharacter, Qt::Key_Tab },
|
||||
{ NSNewlineCharacter, Qt::Key_Return },
|
||||
{ NSCarriageReturnCharacter, Qt::Key_Return },
|
||||
{ NSBackTabCharacter, Qt::Key_Backtab },
|
||||
{ kEscapeCharCode, Qt::Key_Escape },
|
||||
// Cocoa sends us delete when pressing backspace!
|
||||
// (NB when we reverse this list in qtKey2CocoaKey, there
|
||||
// will be two indices of Qt::Key_Backspace. But is seems to work
|
||||
// ok for menu shortcuts (which uses that function):
|
||||
{ NSDeleteCharacter, Qt::Key_Backspace },
|
||||
{ NSUpArrowFunctionKey, Qt::Key_Up },
|
||||
{ NSDownArrowFunctionKey, Qt::Key_Down },
|
||||
{ NSLeftArrowFunctionKey, Qt::Key_Left },
|
||||
{ NSRightArrowFunctionKey, Qt::Key_Right },
|
||||
{ NSF1FunctionKey, Qt::Key_F1 },
|
||||
{ NSF2FunctionKey, Qt::Key_F2 },
|
||||
{ NSF3FunctionKey, Qt::Key_F3 },
|
||||
{ NSF4FunctionKey, Qt::Key_F4 },
|
||||
{ NSF5FunctionKey, Qt::Key_F5 },
|
||||
{ NSF6FunctionKey, Qt::Key_F6 },
|
||||
{ NSF7FunctionKey, Qt::Key_F7 },
|
||||
{ NSF8FunctionKey, Qt::Key_F8 },
|
||||
{ NSF9FunctionKey, Qt::Key_F9 },
|
||||
{ NSF10FunctionKey, Qt::Key_F10 },
|
||||
{ NSF11FunctionKey, Qt::Key_F11 },
|
||||
{ NSF12FunctionKey, Qt::Key_F12 },
|
||||
{ NSF13FunctionKey, Qt::Key_F13 },
|
||||
{ NSF14FunctionKey, Qt::Key_F14 },
|
||||
{ NSF15FunctionKey, Qt::Key_F15 },
|
||||
{ NSF16FunctionKey, Qt::Key_F16 },
|
||||
{ NSF17FunctionKey, Qt::Key_F17 },
|
||||
{ NSF18FunctionKey, Qt::Key_F18 },
|
||||
{ NSF19FunctionKey, Qt::Key_F19 },
|
||||
{ NSF20FunctionKey, Qt::Key_F20 },
|
||||
{ NSF21FunctionKey, Qt::Key_F21 },
|
||||
{ NSF22FunctionKey, Qt::Key_F22 },
|
||||
{ NSF23FunctionKey, Qt::Key_F23 },
|
||||
{ NSF24FunctionKey, Qt::Key_F24 },
|
||||
{ NSF25FunctionKey, Qt::Key_F25 },
|
||||
{ NSF26FunctionKey, Qt::Key_F26 },
|
||||
{ NSF27FunctionKey, Qt::Key_F27 },
|
||||
{ NSF28FunctionKey, Qt::Key_F28 },
|
||||
{ NSF29FunctionKey, Qt::Key_F29 },
|
||||
{ NSF30FunctionKey, Qt::Key_F30 },
|
||||
{ NSF31FunctionKey, Qt::Key_F31 },
|
||||
{ NSF32FunctionKey, Qt::Key_F32 },
|
||||
{ NSF33FunctionKey, Qt::Key_F33 },
|
||||
{ NSF34FunctionKey, Qt::Key_F34 },
|
||||
{ NSF35FunctionKey, Qt::Key_F35 },
|
||||
{ NSInsertFunctionKey, Qt::Key_Insert },
|
||||
{ NSDeleteFunctionKey, Qt::Key_Delete },
|
||||
{ NSHomeFunctionKey, Qt::Key_Home },
|
||||
{ NSEndFunctionKey, Qt::Key_End },
|
||||
{ NSPageUpFunctionKey, Qt::Key_PageUp },
|
||||
{ NSPageDownFunctionKey, Qt::Key_PageDown },
|
||||
{ NSPrintScreenFunctionKey, Qt::Key_Print },
|
||||
{ NSScrollLockFunctionKey, Qt::Key_ScrollLock },
|
||||
{ NSPauseFunctionKey, Qt::Key_Pause },
|
||||
{ NSSysReqFunctionKey, Qt::Key_SysReq },
|
||||
{ NSMenuFunctionKey, Qt::Key_Menu },
|
||||
{ NSHelpFunctionKey, Qt::Key_Help },
|
||||
};
|
||||
static const KeyPair * const end = entries + NumEntries;
|
||||
|
||||
QChar qt_mac_qtKey2CocoaKey(Qt::Key key)
|
||||
{
|
||||
// The first time this function is called, create a reverse
|
||||
// lookup table sorted on Qt Key rather than Cocoa key:
|
||||
static QVector<KeyPair> rev_entries(NumEntries);
|
||||
static bool mustInit = true;
|
||||
if (mustInit){
|
||||
mustInit = false;
|
||||
for (int i=0; i<NumEntries; ++i)
|
||||
rev_entries[i] = entries[i];
|
||||
std::sort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan());
|
||||
}
|
||||
const QVector<KeyPair>::iterator i
|
||||
= std::lower_bound(rev_entries.begin(), rev_entries.end(), key);
|
||||
if ((i == rev_entries.end()) || (key < *i))
|
||||
return QChar();
|
||||
return i->cocoaKey;
|
||||
}
|
||||
|
||||
Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode)
|
||||
{
|
||||
const KeyPair *i = std::lower_bound(entries, end, keyCode);
|
||||
if ((i == end) || (keyCode < *i))
|
||||
return Qt::Key(keyCode.toUpper().unicode());
|
||||
return i->qtKey;
|
||||
}
|
||||
|
||||
struct dndenum_mapper
|
||||
{
|
||||
NSDragOperation mac_code;
|
||||
|
@ -86,9 +86,9 @@ QMimeData *QHaikuClipboard::mimeData(QClipboard::Mode mode)
|
||||
const status_t status = clipboard->FindData(name, B_MIME_TYPE, &data, &dataLen);
|
||||
if (dataLen && (status == B_OK)) {
|
||||
const QString format = QString::fromLatin1(name);
|
||||
if (format == QStringLiteral("text/plain")) {
|
||||
if (format == QLatin1String("text/plain")) {
|
||||
m_systemMimeData->setText(QString::fromLocal8Bit(reinterpret_cast<const char*>(data), dataLen));
|
||||
} else if (format == QStringLiteral("text/html")) {
|
||||
} else if (format == QLatin1String("text/html")) {
|
||||
m_systemMimeData->setHtml(QString::fromLocal8Bit(reinterpret_cast<const char*>(data), dataLen));
|
||||
} else {
|
||||
m_systemMimeData->setData(format, QByteArray(reinterpret_cast<const char*>(data), dataLen));
|
||||
|
@ -282,30 +282,33 @@ void QWindowsOleDropSource::createCursors()
|
||||
const bool hasPixmap = !pixmap.isNull();
|
||||
|
||||
// Find screen for drag. Could be obtained from QDrag::source(), but that might be a QWidget.
|
||||
|
||||
qreal scaleFactor = 1;
|
||||
QPlatformCursor *platformCursor = Q_NULLPTR;
|
||||
if (const QPlatformScreen *platformScreen = QWindowsContext::instance()->screenManager().screenAtDp(QWindowsCursor::mousePosition())) {
|
||||
scaleFactor = QHighDpiScaling::factor(platformScreen);
|
||||
platformCursor = platformScreen->cursor();
|
||||
const QPlatformScreen *platformScreen = QWindowsContext::instance()->screenManager().screenAtDp(QWindowsCursor::mousePosition());
|
||||
if (!platformScreen) {
|
||||
if (const QScreen *primaryScreen = QGuiApplication::primaryScreen())
|
||||
platformScreen = primaryScreen->handle();
|
||||
}
|
||||
if (!platformCursor && QGuiApplication::primaryScreen())
|
||||
platformCursor = QGuiApplication::primaryScreen()->handle()->cursor();
|
||||
Q_ASSERT(platformScreen);
|
||||
QPlatformCursor *platformCursor = platformScreen->cursor();
|
||||
|
||||
qreal pixmapScaleFactor = 1;
|
||||
qreal hotSpotScaleFactor = 1;
|
||||
if (m_mode != TouchDrag) { // Touch drag: pixmap is shown in a separate QWindow, which will be scaled.)
|
||||
hotSpotScaleFactor = QHighDpiScaling::factor(platformScreen);
|
||||
pixmapScaleFactor = hotSpotScaleFactor / pixmap.devicePixelRatio();
|
||||
}
|
||||
QPixmap scaledPixmap = qFuzzyCompare(pixmapScaleFactor, 1.0)
|
||||
? pixmap
|
||||
: pixmap.scaled((QSizeF(pixmap.size()) * pixmapScaleFactor).toSize(),
|
||||
Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
scaledPixmap.setDevicePixelRatio(1);
|
||||
|
||||
const bool scalePixmap = hasPixmap
|
||||
&& m_mode != TouchDrag // Touch drag: pixmap is shown in a separate QWindow, which will be scaled.
|
||||
&& (scaleFactor != 1 && scaleFactor != qRound(pixmap.devicePixelRatio()));
|
||||
const QPixmap scaledPixmap = scalePixmap
|
||||
? pixmap.scaled((QSizeF(pixmap.size()) * scaleFactor).toSize(),
|
||||
Qt::KeepAspectRatio, Qt::SmoothTransformation)
|
||||
: pixmap;
|
||||
Qt::DropAction actions[] = { Qt::MoveAction, Qt::CopyAction, Qt::LinkAction, Qt::IgnoreAction };
|
||||
int actionCount = int(sizeof(actions) / sizeof(actions[0]));
|
||||
if (!hasPixmap)
|
||||
--actionCount; // No Qt::IgnoreAction unless pixmap
|
||||
const QPoint hotSpot = scalePixmap
|
||||
? (QPointF(drag->hotSpot()) * scaleFactor).toPoint()
|
||||
: drag->hotSpot();
|
||||
const QPoint hotSpot = qFuzzyCompare(hotSpotScaleFactor, 1.0)
|
||||
? drag->hotSpot()
|
||||
: (QPointF(drag->hotSpot()) * hotSpotScaleFactor).toPoint();
|
||||
for (int cnum = 0; cnum < actionCount; ++cnum) {
|
||||
const Qt::DropAction action = actions[cnum];
|
||||
QPixmap cursorPixmap = drag->dragCursor(action);
|
||||
@ -458,7 +461,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
|
||||
if (!m_touchDragWindow)
|
||||
m_touchDragWindow = new QWindowsDragCursorWindow;
|
||||
m_touchDragWindow->setPixmap(e.pixmap);
|
||||
m_touchDragWindow->setFramePosition(QWindowsCursor::mousePosition() - e.hotSpot);
|
||||
m_touchDragWindow->setFramePosition(QCursor::pos() - e.hotSpot);
|
||||
if (!m_touchDragWindow->isVisible())
|
||||
m_touchDragWindow->show();
|
||||
break;
|
||||
|
@ -1613,7 +1613,7 @@ LOGFONT QWindowsFontDatabase::fontDefToLOGFONT(const QFontDef &request)
|
||||
if (fam.isEmpty())
|
||||
fam = QStringLiteral("MS Sans Serif");
|
||||
|
||||
if ((fam == QStringLiteral("MS Sans Serif"))
|
||||
if (fam == QLatin1String("MS Sans Serif")
|
||||
&& (request.style == QFont::StyleItalic || (-lf.lfHeight > 18 && -lf.lfHeight != 24))) {
|
||||
fam = QStringLiteral("Arial"); // MS Sans Serif has bearing problems in italic, and does not scale
|
||||
}
|
||||
|
@ -231,17 +231,10 @@ int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLa
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
wchar_t first = tm.tmFirstChar;
|
||||
wchar_t last = tm.tmLastChar;
|
||||
|
||||
QStringIterator it(str, str + numChars);
|
||||
while (it.hasNext()) {
|
||||
const uint uc = it.next();
|
||||
if (
|
||||
#ifdef Q_DEAD_CODE_FROM_QT4_WINCE
|
||||
tm.tmFirstChar > 60000 ||
|
||||
#endif
|
||||
uc >= first && uc <= last)
|
||||
if (uc >= tm.tmFirstChar && uc <= tm.tmLastChar)
|
||||
glyphs->glyphs[glyph_pos] = uc;
|
||||
else
|
||||
glyphs->glyphs[glyph_pos] = 0;
|
||||
@ -351,11 +344,9 @@ glyph_t QWindowsFontEngine::glyphIndex(uint ucs4) const
|
||||
glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4 + 0xf000);
|
||||
} else if (ttf) {
|
||||
glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4);
|
||||
#else
|
||||
if (tm.tmFirstChar > 60000) {
|
||||
glyph = ucs4;
|
||||
} else
|
||||
#endif
|
||||
} else if (ucs4 >= tm.tmFirstChar && ucs4 <= tm.tmLastChar) {
|
||||
if (ucs4 >= tm.tmFirstChar && ucs4 <= tm.tmLastChar) {
|
||||
glyph = ucs4;
|
||||
} else {
|
||||
glyph = 0;
|
||||
|
@ -1145,7 +1145,7 @@ QVariant QWindowsMimeImage::convertToMime(const QString &mimeType, IDataObject *
|
||||
{
|
||||
Q_UNUSED(preferredType);
|
||||
QVariant result;
|
||||
if (mimeType != QStringLiteral("application/x-qt-image"))
|
||||
if (mimeType != QLatin1String("application/x-qt-image"))
|
||||
return result;
|
||||
//Try to convert from a format which has more data
|
||||
//DIBV5, use only if its is not synthesized
|
||||
|
@ -224,6 +224,30 @@ static inline QRect frameGeometry(HWND hwnd, bool topLevel)
|
||||
return qrectFromRECT(rect);
|
||||
}
|
||||
|
||||
// Return the visibility of the Window (except full screen since it is not a window state).
|
||||
static QWindow::Visibility windowVisibility_sys(HWND hwnd)
|
||||
{
|
||||
if (!IsWindowVisible(hwnd))
|
||||
return QWindow::Hidden;
|
||||
#ifndef Q_OS_WINCE
|
||||
WINDOWPLACEMENT windowPlacement;
|
||||
windowPlacement.length = sizeof(WINDOWPLACEMENT);
|
||||
if (GetWindowPlacement(hwnd, &windowPlacement)) {
|
||||
switch (windowPlacement.showCmd) {
|
||||
case SW_SHOWMINIMIZED:
|
||||
case SW_MINIMIZE:
|
||||
case SW_FORCEMINIMIZE:
|
||||
return QWindow::Minimized;
|
||||
case SW_SHOWMAXIMIZED:
|
||||
return QWindow::Maximized;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif // !Q_OS_WINCE
|
||||
return QWindow::Windowed;
|
||||
}
|
||||
|
||||
static inline QSize clientSize(HWND hwnd)
|
||||
{
|
||||
RECT rect = { 0, 0, 0, 0 };
|
||||
@ -1764,6 +1788,10 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
|
||||
swpf |= SWP_NOSIZE | SWP_NOMOVE;
|
||||
const bool wasSync = testFlag(SynchronousGeometryChangeEvent);
|
||||
setFlag(SynchronousGeometryChangeEvent);
|
||||
// After maximized/fullscreen; the window can be in a maximized state. Clear
|
||||
// it before applying the normal geometry.
|
||||
if (windowVisibility_sys(m_data.hwnd) == QWindow::Maximized)
|
||||
ShowWindow(m_data.hwnd, SW_SHOWNOACTIVATE);
|
||||
SetWindowPos(m_data.hwnd, 0, m_savedFrameGeometry.x(), m_savedFrameGeometry.y(),
|
||||
m_savedFrameGeometry.width(), m_savedFrameGeometry.height(), swpf);
|
||||
if (!wasSync)
|
||||
|
@ -1169,7 +1169,7 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEvent
|
||||
Q_D(QWinRTScreen);
|
||||
boolean visible;
|
||||
HRESULT hr = args ? args->get_Visible(&visible) : d->coreWindow->get_Visible(&visible);
|
||||
RETURN_OK_IF_FAILED("Failed to get visbile.");
|
||||
RETURN_OK_IF_FAILED("Failed to get visibility.");
|
||||
QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden);
|
||||
if (visible)
|
||||
handleExpose();
|
||||
|
@ -639,7 +639,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
|
||||
QString glIntegrationName = QString::fromLocal8Bit(qgetenv("QT_XCB_GL_INTEGRATION"));
|
||||
if (!glIntegrationName.isEmpty()) {
|
||||
qCDebug(QT_XCB_GLINTEGRATION) << "QT_XCB_GL_INTEGRATION is set to" << glIntegrationName;
|
||||
if (glIntegrationName != QStringLiteral("none")) {
|
||||
if (glIntegrationName != QLatin1String("none")) {
|
||||
glIntegrationNames.removeAll(glIntegrationName);
|
||||
glIntegrationNames.prepend(glIntegrationName);
|
||||
} else {
|
||||
|
@ -2251,12 +2251,13 @@ void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, con
|
||||
static bool ignoreLeaveEvent(const xcb_leave_notify_event_t *event)
|
||||
{
|
||||
return event->detail == XCB_NOTIFY_DETAIL_VIRTUAL
|
||||
|| event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL;
|
||||
|| event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL
|
||||
|| event->mode == XCB_NOTIFY_MODE_GRAB;
|
||||
}
|
||||
|
||||
static bool ignoreEnterEvent(const xcb_enter_notify_event_t *event)
|
||||
{
|
||||
return ((event->mode != XCB_NOTIFY_MODE_NORMAL && event->mode != XCB_NOTIFY_MODE_UNGRAB)
|
||||
return (event->mode != XCB_NOTIFY_MODE_NORMAL
|
||||
|| event->detail == XCB_NOTIFY_DETAIL_VIRTUAL
|
||||
|| event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
|
||||
QPlatformPrinterSupport *QCocoaPrinterSupportPlugin::create(const QString &key)
|
||||
{
|
||||
if (key.compare(key, QStringLiteral("cocoaprintersupport"), Qt::CaseInsensitive) != 0)
|
||||
if (key.compare(key, QLatin1String("cocoaprintersupport"), Qt::CaseInsensitive) != 0)
|
||||
return 0;
|
||||
QGuiApplication *app = qobject_cast<QGuiApplication *>(QCoreApplication::instance());
|
||||
if (!app)
|
||||
|
@ -69,11 +69,7 @@ namespace QTest
|
||||
QEvent::Type type;
|
||||
type = press ? QEvent::KeyPress : QEvent::KeyRelease;
|
||||
qt_handleKeyEvent(window, type, code, modifier, text, repeat, delay);
|
||||
#ifdef QT_MAC_USE_COCOA
|
||||
QTest::qWait(20);
|
||||
#else
|
||||
qApp->processEvents();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void sendKeyEvent(KeyAction action, QWindow *window, Qt::Key code,
|
||||
|
@ -67,7 +67,7 @@ static const char docTypeHeader[] =
|
||||
|
||||
#define PROGRAMNAME "qdbuscpp2xml"
|
||||
#define PROGRAMVERSION "0.2"
|
||||
#define PROGRAMCOPYRIGHT "Copyright (C) 2015 The Qt Company Ltd."
|
||||
#define PROGRAMCOPYRIGHT "Copyright (C) 2016 The Qt Company Ltd."
|
||||
|
||||
static QString outputFile;
|
||||
static int flags;
|
||||
|
@ -48,7 +48,7 @@
|
||||
|
||||
#define PROGRAMNAME "qdbusxml2cpp"
|
||||
#define PROGRAMVERSION "0.8"
|
||||
#define PROGRAMCOPYRIGHT "Copyright (C) 2015 The Qt Company Ltd."
|
||||
#define PROGRAMCOPYRIGHT "Copyright (C) 2016 The Qt Company Ltd."
|
||||
|
||||
#define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply"
|
||||
|
||||
|
@ -47,7 +47,7 @@ QString CppGenerator::copyrightHeader() const
|
||||
return QLatin1String(
|
||||
"/****************************************************************************\n"
|
||||
"**\n"
|
||||
"** Copyright (C) 2015 The Qt Company Ltd.\n"
|
||||
"** Copyright (C) 2016 The Qt Company Ltd.\n"
|
||||
"** Contact: http://www.qt.io/licensing/\n"
|
||||
"**\n"
|
||||
"** This file is part of the Qt Toolkit.\n"
|
||||
|
@ -1903,7 +1903,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title)
|
||||
"<p>Qt and the Qt logo are trademarks of The Qt Company Ltd.</p>"
|
||||
"<p>Qt is The Qt Company Ltd product developed as an open source "
|
||||
"project. See <a href=\"http://%3/\">%3</a> for more information.</p>"
|
||||
).arg(QStringLiteral("2015"),
|
||||
).arg(QStringLiteral("2016"),
|
||||
QStringLiteral("qt.io/licensing"),
|
||||
QStringLiteral("qt.io"));
|
||||
QMessageBox *msgBox = new QMessageBox(parent);
|
||||
|
@ -39,8 +39,6 @@
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
#ifdef QT_MAC_USE_COCOA
|
||||
|
||||
//![0]
|
||||
SearchWidget::SearchWidget(QWidget *parent)
|
||||
: QMacCocoaViewContainer(0, parent)
|
||||
@ -76,57 +74,6 @@ QSize SearchWidget::sizeHint() const
|
||||
return QSize(150, 40);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// The SearchWidget class wraps a native HISearchField.
|
||||
SearchWidget::SearchWidget(QWidget *parent)
|
||||
:QWidget(parent)
|
||||
{
|
||||
|
||||
// Create a native search field and pass its window id to QWidget::create.
|
||||
searchFieldText = CFStringCreateWithCString(0, "search", 0);
|
||||
HISearchFieldCreate(NULL/*bounds*/, kHISearchFieldAttributesSearchIcon | kHISearchFieldAttributesCancel,
|
||||
NULL/*menu ref*/, searchFieldText, &searchField);
|
||||
create(reinterpret_cast<WId>(searchField));
|
||||
|
||||
// Use a Qt menu for the search field menu.
|
||||
QMenu *searchMenu = createMenu(this);
|
||||
MenuRef menuRef = searchMenu->macMenu(0);
|
||||
HISearchFieldSetSearchMenu(searchField, menuRef);
|
||||
setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||
}
|
||||
|
||||
SearchWidget::~SearchWidget()
|
||||
{
|
||||
CFRelease(searchField);
|
||||
CFRelease(searchFieldText);
|
||||
}
|
||||
|
||||
// Get the size hint from the search field.
|
||||
QSize SearchWidget::sizeHint() const
|
||||
{
|
||||
EventRef event;
|
||||
HIRect optimalBounds;
|
||||
CreateEvent(0, kEventClassControl,
|
||||
kEventControlGetOptimalBounds,
|
||||
GetCurrentEventTime(),
|
||||
kEventAttributeUserEvent, &event);
|
||||
|
||||
SendEventToEventTargetWithOptions(event,
|
||||
HIObjectGetEventTarget(HIObjectRef(winId())),
|
||||
kEventTargetDontPropagate);
|
||||
|
||||
GetEventParameter(event,
|
||||
kEventParamControlOptimalBounds, typeHIRect,
|
||||
0, sizeof(HIRect), 0, &optimalBounds);
|
||||
|
||||
ReleaseEvent(event);
|
||||
return QSize(optimalBounds.size.width + 100, // make it a bit wider.
|
||||
optimalBounds.size.height);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
QMenu *createMenu(QWidget *parent)
|
||||
{
|
||||
QMenu *searchMenu = new QMenu(parent);
|
||||
|
@ -39,10 +39,10 @@
|
||||
#include "qapplication.h"
|
||||
#include "qevent.h"
|
||||
#include "qlist.h"
|
||||
#include "qdebug.h"
|
||||
#include <private/qshortcutmap_p.h>
|
||||
#include <private/qapplication_p.h>
|
||||
#include <private/qmenu_p.h>
|
||||
#include <private/qdebug_p.h>
|
||||
|
||||
#define QAPP_CHECK(functionName) \
|
||||
if (!qApp) { \
|
||||
@ -1296,6 +1296,31 @@ bool QAction::isIconVisibleInMenu() const
|
||||
return d->iconVisibleInMenu;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
Q_WIDGETS_EXPORT QDebug operator<<(QDebug d, const QAction *action)
|
||||
{
|
||||
QDebugStateSaver saver(d);
|
||||
d.nospace();
|
||||
d << "QAction(" << static_cast<const void *>(action);
|
||||
if (action) {
|
||||
d << " text=" << action->text();
|
||||
if (!action->toolTip().isEmpty())
|
||||
d << " toolTip=" << action->toolTip();
|
||||
if (action->isCheckable())
|
||||
d << " checked=" << action->isChecked();
|
||||
if (!action->shortcut().isEmpty())
|
||||
d << " shortcut=" << action->shortcut();
|
||||
d << " menuRole=";
|
||||
QtDebugUtils::formatQEnum(d, action->menuRole());
|
||||
d << " visible=" << action->isVisible();
|
||||
} else {
|
||||
d << '0';
|
||||
}
|
||||
d << ')';
|
||||
return d;
|
||||
}
|
||||
#endif // QT_NO_DEBUG_STREAM
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "moc_qaction.cpp"
|
||||
|
@ -203,6 +203,10 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
Q_WIDGETS_EXPORT QDebug operator<<(QDebug, const QAction *);
|
||||
#endif
|
||||
|
||||
QT_BEGIN_INCLUDE_NAMESPACE
|
||||
#include <QtWidgets/qactiongroup.h>
|
||||
QT_END_INCLUDE_NAMESPACE
|
||||
|
@ -238,11 +238,6 @@
|
||||
\property QDesktopWidget::screenCount
|
||||
\brief the number of screens currently available on the system.
|
||||
|
||||
Note that on some platforms, screenCount will be zero if there are actually
|
||||
no screens connected. Applications which were running at the time the
|
||||
screenCount went to zero will stop rendering graphics until one or more
|
||||
screens are restored.
|
||||
|
||||
\since 4.6
|
||||
*/
|
||||
|
||||
|
@ -329,7 +329,7 @@ static bool correctActionContext(Qt::ShortcutContext context, QAction *a, QWidge
|
||||
shown and the character will be underlined. On Windows, shortcuts
|
||||
are normally not displayed until the user presses the \uicontrol Alt
|
||||
key, but this is a setting the user can change. On Mac, shortcuts
|
||||
are disabled by default. Call qt_set_sequence_auto_mnemonic() to
|
||||
are disabled by default. Call \l qt_set_sequence_auto_mnemonic() to
|
||||
enable them. However, because mnemonic shortcuts do not fit in
|
||||
with Aqua's guidelines, Qt will not show the shortcut character
|
||||
underlined.
|
||||
|
@ -84,6 +84,11 @@ public:
|
||||
if (usesNativeWidgets || window->parent() == 0)
|
||||
return;
|
||||
Q_Q(QWindowContainer);
|
||||
if (q->internalWinId()) {
|
||||
// Allow use native widgets if the window container is already a native widget
|
||||
usesNativeWidgets = true;
|
||||
return;
|
||||
}
|
||||
QWidget *p = q->parentWidget();
|
||||
while (p) {
|
||||
if (
|
||||
@ -147,8 +152,10 @@ public:
|
||||
as a child of a QAbstractScrollArea or QMdiArea, it will
|
||||
create a \l {Native Widgets vs Alien Widgets} {native window} for
|
||||
every widget in its parent chain to allow for proper stacking and
|
||||
clipping in this use case. Applications with many native child
|
||||
windows may suffer from performance issues.
|
||||
clipping in this use case. Creating a native window for the window
|
||||
container also allows for proper stacking and clipping. This must
|
||||
be done before showing the window container. Applications with
|
||||
many native child windows may suffer from performance issues.
|
||||
|
||||
The window container has a number of known limitations:
|
||||
|
||||
|
@ -398,7 +398,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
|
||||
{
|
||||
XPThemeData theme(widget, painter, QWindowsXPStylePrivate::TreeViewTheme);
|
||||
static int decoration_size = 0;
|
||||
if (d->initTreeViewTheming() && theme.isValid() && !decoration_size) {
|
||||
if (!decoration_size && d->initTreeViewTheming() && theme.isValid()) {
|
||||
XPThemeData themeSize = theme;
|
||||
themeSize.partId = TVP_HOTGLYPH;
|
||||
themeSize.stateId = GLPS_OPENED;
|
||||
|
@ -1944,12 +1944,8 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*>
|
||||
qt_mac_set_drawer_preferred_edge(widget, toDockWidgetArea(dockPos));
|
||||
} else
|
||||
#endif
|
||||
if (!testing) {
|
||||
QRect r(x, y, w, h);
|
||||
r = QDockAreaLayout::constrainedRect(r, widget);
|
||||
widget->move(r.topLeft());
|
||||
widget->resize(r.size());
|
||||
}
|
||||
if (!testing)
|
||||
widget->setGeometry(QDockAreaLayout::constrainedRect(QRect(x, y, w, h), widget));
|
||||
|
||||
if (!testing) {
|
||||
widget->setVisible(flags & StateFlagVisible);
|
||||
|
@ -584,6 +584,8 @@ void QMenuPrivate::setCurrentAction(QAction *action, int popup, SelectionReason
|
||||
if (reason != SelectedFromKeyboard) {
|
||||
if (QMenu *menu = qobject_cast<QMenu*>(causedPopup.widget)) {
|
||||
if (causedPopup.action && menu->d_func()->activeMenu == q)
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
@ -98,15 +98,13 @@ void QMenu::setAsDockMenu()
|
||||
|
||||
|
||||
/*! \fn void qt_mac_set_dock_menu(QMenu *menu)
|
||||
\since 5.2
|
||||
\relates QMenu
|
||||
\deprecated
|
||||
|
||||
Set this menu to be the dock menu available by option-clicking
|
||||
Sets this \a menu to be the dock menu available by option-clicking
|
||||
on the application dock icon. Available on OS X only.
|
||||
|
||||
Deprecated; use QMenu:setAsDockMenu() instead.
|
||||
|
||||
\sa QMenu:setAsDockMenu()
|
||||
Deprecated; use \l QMenu::setAsDockMenu() instead.
|
||||
*/
|
||||
|
||||
void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem* item)
|
||||
|
@ -120,7 +120,7 @@ bool QToolButtonPrivate::hasMenu() const
|
||||
|
||||
One classic use of a tool button is to select tools; for example,
|
||||
the "pen" tool in a drawing program. This would be implemented
|
||||
by using a QToolButton as a toggle button (see setToggleButton()).
|
||||
by using a QToolButton as a toggle button (see setCheckable()).
|
||||
|
||||
QToolButton supports auto-raising. In auto-raise mode, the button
|
||||
draws a 3D frame only when the mouse points at it. The feature is
|
||||
@ -147,8 +147,8 @@ bool QToolButtonPrivate::hasMenu() const
|
||||
menu set. The default mode is DelayedPopupMode which is sometimes
|
||||
used with the "Back" button in a web browser. After pressing and
|
||||
holding the button down for a while, a menu pops up showing a list
|
||||
of possible pages to jump to. The default delay is 600 ms; you can
|
||||
adjust it with setPopupDelay().
|
||||
of possible pages to jump to. The timeout is style dependent,
|
||||
see QStyle::SH_ToolButton_PopupDelay.
|
||||
|
||||
\table 100%
|
||||
\row \li \inlineimage assistant-toolbar.png Qt Assistant's toolbar with tool buttons
|
||||
@ -820,7 +820,7 @@ void QToolButtonPrivate::_q_menuTriggered(QAction *action)
|
||||
a menu set or contains a list of actions.
|
||||
|
||||
\value DelayedPopup After pressing and holding the tool button
|
||||
down for a certain amount of time (the timeout is style dependant,
|
||||
down for a certain amount of time (the timeout is style dependent,
|
||||
see QStyle::SH_ToolButton_PopupDelay), the menu is displayed. A
|
||||
typical application example is the "back" button in some web
|
||||
browsers's tool bars. If the user clicks it, the browser simply
|
||||
|
@ -5,6 +5,7 @@ HEADERS = plugin1.h
|
||||
SOURCES = plugin1.cpp
|
||||
TARGET = $$qtLibraryTarget(plugin1)
|
||||
DESTDIR = ../bin
|
||||
winrt:include(../winrt.pri)
|
||||
|
||||
# This is testdata for the tst_qpluginloader test.
|
||||
target.path = $$[QT_INSTALL_TESTS]/tst_qfactoryloader/bin
|
||||
|
@ -5,6 +5,7 @@ HEADERS = plugin2.h
|
||||
SOURCES = plugin2.cpp
|
||||
TARGET = $$qtLibraryTarget(plugin2)
|
||||
DESTDIR = ../bin
|
||||
winrt:include(../winrt.pri)
|
||||
|
||||
# This is testdata for the tst_qpluginloader test.
|
||||
target.path = $$[QT_INSTALL_TESTS]/tst_qfactoryloader/bin
|
||||
|
9
tests/auto/corelib/plugin/qfactoryloader/winrt.pri
Normal file
9
tests/auto/corelib/plugin/qfactoryloader/winrt.pri
Normal 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
|
||||
}
|
||||
}
|
@ -139,9 +139,11 @@ typedef int (*VersionFunction)(void);
|
||||
|
||||
void tst_QLibrary::initTestCase()
|
||||
{
|
||||
#ifndef Q_OS_WINRT
|
||||
// chdir to our testdata directory, and use relative paths in some tests.
|
||||
QString testdatadir = QFileInfo(QFINDTESTDATA("library_path")).absolutePath();
|
||||
QVERIFY2(QDir::setCurrent(testdatadir), qPrintable("Could not chdir to " + testdatadir));
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QLibrary::version_data()
|
||||
@ -417,7 +419,7 @@ void tst_QLibrary::loadHints_data()
|
||||
QString appDir = QCoreApplication::applicationDirPath();
|
||||
|
||||
lh |= QLibrary::ResolveAllSymbolsHint;
|
||||
# if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
|
||||
# if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
|
||||
QTest::newRow( "ok01 (with suffix)" ) << appDir + "/mylib.dll" << int(lh) << true;
|
||||
QTest::newRow( "ok02 (with non-standard suffix)" ) << appDir + "/mylib.dl2" << int(lh) << true;
|
||||
QTest::newRow( "ok03 (with many dots)" ) << appDir + "/system.qt.test.mylib.dll" << int(lh) << true;
|
||||
@ -469,7 +471,7 @@ void tst_QLibrary::fileName_data()
|
||||
|
||||
QTest::newRow( "ok02" ) << sys_qualifiedLibraryName(QLatin1String("mylib"))
|
||||
<< sys_qualifiedLibraryName(QLatin1String("mylib"));
|
||||
#ifdef Q_OS_WIN
|
||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
||||
#ifndef Q_OS_WINCE
|
||||
QTest::newRow( "ok03" ) << "user32"
|
||||
<< "USER32.dll";
|
||||
|
@ -4,6 +4,7 @@ CONFIG -= staticlib
|
||||
SOURCES = mylib.c
|
||||
TARGET = tst_qpluginloaderlib
|
||||
DESTDIR = ../bin
|
||||
winrt:include(../winrt.pri)
|
||||
QT = core
|
||||
|
||||
win32-msvc: DEFINES += WIN32_MSVC
|
||||
|
@ -6,6 +6,7 @@ SOURCES = theplugin.cpp
|
||||
#TARGET = $$qtLibraryTarget(theplugin)
|
||||
TARGET = theplugin
|
||||
DESTDIR = ../bin
|
||||
winrt:include(../winrt.pri)
|
||||
QT = core
|
||||
|
||||
# This is testdata for the tst_qpluginloader test.
|
||||
|
9
tests/auto/corelib/plugin/qpluginloader/winrt.pri
Normal file
9
tests/auto/corelib/plugin/qpluginloader/winrt.pri
Normal 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
Loading…
Reference in New Issue
Block a user