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

Change-Id: I2a6eb9dd7724931bc89f28bcc156e77c4e26d069
This commit is contained in:
Iikka Eklund 2014-04-01 11:44:26 +03:00
commit 0ab63b035a
205 changed files with 4051 additions and 2139 deletions

2
.gitignore vendored
View File

@ -30,6 +30,8 @@ pcviewer.cfg
*.a *.a
*.la *.la
*.core *.core
*.d
*.dylib
*.moc *.moc
*.o *.o
*.obj *.obj

View File

@ -1,6 +1,6 @@
GNU LESSER GENERAL PUBLIC LICENSE GNU LESSER GENERAL PUBLIC LICENSE
The Qt Toolkit is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). The Qt Toolkit is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
Contact: http://www.qt-project.org/legal Contact: http://www.qt-project.org/legal
You may use, distribute and copy the Qt GUI Toolkit under the terms of You may use, distribute and copy the Qt GUI Toolkit under the terms of

View File

@ -6,6 +6,10 @@ VERBOSE=$2
cat >>bsymbolic_functions.c << EOF cat >>bsymbolic_functions.c << EOF
#if !(defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) || defined(__amd64))
#error "Symbolic function binding on this architecture may be broken, disabling it (see QTBUG-36129)."
#endif
int main() { return 0; } int main() { return 0; }
EOF EOF

312
configure vendored
View File

@ -2766,203 +2766,25 @@ if [ "$COMMERCIAL_USER" = "ask" ]; then
done done
fi fi
CFG_RTOS_ENABLED=yes
EditionString=Commercial
if [ -f "$relpath"/LICENSE.PREVIEW.COMMERCIAL ] && [ $COMMERCIAL_USER = "yes" ]; then if [ -f "$relpath"/LICENSE.PREVIEW.COMMERCIAL ] && [ $COMMERCIAL_USER = "yes" ]; then
# Commercial preview release # Commercial preview release
Licensee="Preview" Licensee="Preview"
Edition="Preview" Edition="Preview"
LicenseType="Technology Preview" EditionString="Technology Preview"
elif [ $COMMERCIAL_USER = "yes" ]; then elif [ $COMMERCIAL_USER = "yes" ]; then
# one of commercial editions if test -x "$relpath/bin/licheck"; then
LicheckOutput=`$relpath/bin/licheck $relpath $outpath $PLATFORM $XPLATFORM`
# read in the license file if [ $? -ne 0 ]; then
[ -z "$LICENSE_FILE" ] && LICENSE_FILE="$QT_LICENSE_FILE"
[ -z "$LICENSE_FILE" ] && LICENSE_FILE="$HOME/.qt-license"
if [ -f "$LICENSE_FILE" ]; then
tr -d '\r' <"$LICENSE_FILE" >"${LICENSE_FILE}.tmp"
diff "${LICENSE_FILE}.tmp" "${LICENSE_FILE}" >/dev/null 2>&1 || LICENSE_FILE="${LICENSE_FILE}.tmp"
. "$LICENSE_FILE" >/dev/null 2>&1
if [ -z "$LicenseKeyExt" ]; then
echo
echo "You are using an old license file."
echo
echo "Please install the license file supplied by Digia,"
echo "or install the Qt Open Source Edition if you intend to"
echo "develop free software."
exit 1
fi
if [ -z "$Licensee" ]; then
echo
echo "Invalid license key. Please check the license key."
exit 1 exit 1
else
eval "$LicheckOutput"
fi fi
else else
if [ -z "$LicenseKeyExt" ]; then
echo echo
echo $ECHO_N "Please enter your license key: $ECHO_C" echo "Error: This is the Open Source version of Qt."
read LicenseKeyExt echo "If you want to use Enterprise features of Qt,"
Licensee="Unknown user" echo "use the contact form at http://qt.digia.com/contact-us"
fi echo "to purchase a license."
fi
# Key verification
echo "$LicenseKeyExt" | grep ".....*-....*-....*-....*-.....*-.....*-...." >/dev/null 2>&1 \
&& LicenseValid="yes" \
|| LicenseValid="no"
if [ "$LicenseValid" != "yes" ]; then
echo
echo "Invalid license key. Please check the license key."
exit 1
fi
ProductCode=`echo $LicenseKeyExt | cut -f 1 -d - | cut -b 1`
PlatformCode=`echo $LicenseKeyExt | cut -f 2 -d -`
LicenseTypeCode=`echo $LicenseKeyExt | cut -f 3 -d -`
LicenseFeatureCode=`echo $LicenseKeyExt | cut -f 4 -d - | cut -b 1`
# determine which edition we are licensed to use
case "$LicenseTypeCode" in
F4M)
LicenseType="Commercial"
case $ProductCode in
F)
Edition="Universal"
;;
B)
Edition="FullFramework"
EditionString="Full Framework"
;;
L)
Edition="GUIFramework"
EditionString="GUI Framework"
;;
esac
;;
Z4M|R4M|Q4M)
LicenseType="Evaluation"
QMakeVar add DEFINES QT_EVAL
case $ProductCode in
B)
Edition="Evaluation"
;;
esac
;;
esac
if [ -z "$LicenseType" -o -z "$Edition" ]; then
echo
echo "Invalid license key. Please check the license key."
exit 1
fi
# verify that we are licensed to use Qt on this platform
LICENSE_EXTENSION=
case "$PlatformCode" in
*L)
CFG_RTOS_ENABLED=yes
PlatformCode=`echo "$PlatformCode" | sed 'h;y/8NPQRTZ/UCWX9M7/;x;G;s/\(.\)....\(.\)./\1\2/'`
;;
*)
CFG_RTOS_ENABLED=no
PlatformCode=`echo "$PlatformCode" | sed 's/.$//'`
;;
esac
### EMBEDDED_QPA logic missing ###
case "$PlatformCode,$XPLATFORM_MAC" in
X9,* | XC,* | XU,* | XW,* | XM,*)
# Qt All-OS
LICENSE_EXTENSION="-ALLOS"
;;
8M,* | KM,* | S9,* | SC,* | SM,* | SU,* | SW,* | X9,* | XC,* | XU,* | XW,*)
# Qt for Embedded Linux
LICENSE_EXTENSION="-EMBEDDED"
;;
6M,* | N7,* | N9,* | NX,*)
# Embedded no-deploy
LICENSE_EXTENSION="-EMBEDDED"
;;
FM,* | LM,yes | ZM,no)
# Desktop
LICENSE_EXTENSION="-DESKTOP"
;;
*)
Platform=Linux/X11
[ "$XPLATFORM_MAC" = "yes" ] && Platform='Mac OS X'
echo
echo "You are not licensed for the $Platform platform."
echo
echo "Please use the contact form at http://qt.digia.com/contact-us"
echo "to upgrade your license to include the $Platform platform, or install"
echo "the Qt Open Source Edition if you intend to develop free software."
exit 1
;;
esac
if test -r "$relpath/.LICENSE"; then
# Generic, non-final license
LICENSE_EXTENSION=""
line=`sed 'y/a-z/A-Z/;q' "$relpath"/.LICENSE`
case "$line" in
*BETA*)
Edition=Beta
;;
*TECHNOLOGY?PREVIEW*)
Edition=Preview
;;
*EVALUATION*)
Edition=Evaluation
;;
*)
echo >&2 "Invalid license files; cannot continue"
exit 1
;;
esac
Licensee="$Edition"
EditionString="$Edition"
fi
case "$LicenseFeatureCode" in
B|G|L|Y)
# US
case "$LicenseType" in
Commercial)
cp -f "$relpath/.LICENSE${LICENSE_EXTENSION}-US" "$outpath/LICENSE"
;;
Evaluation)
cp -f "$relpath/.LICENSE-EVALUATION-US" "$outpath/LICENSE"
;;
esac
;;
2|4|5|F)
# non-US
case "$LicenseType" in
Commercial)
cp -f "$relpath/.LICENSE${LICENSE_EXTENSION}" "$outpath/LICENSE"
;;
Evaluation)
cp -f "$relpath/.LICENSE-EVALUATION" "$outpath/LICENSE"
;;
esac
;;
*)
echo
echo "Invalid license key. Please check the license key."
exit 1
;;
esac
case "$LicenseFeatureCode" in
4|B|F|Y)
CFG_RTOS_ENABLED=yes
;;
2|5|G|L)
CFG_RTOS_ENABLED=no
;;
esac
if [ '!' -f "$outpath/LICENSE" ]; then
echo "The LICENSE, LICENSE.GPL LICENSE.LGPL file shipped with"
echo "this software has disappeared."
echo
echo "Sorry, you are not licensed to use this software."
echo "Try re-installing."
echo echo
exit 1 exit 1
fi fi
@ -2972,22 +2794,11 @@ elif [ $COMMERCIAL_USER = "no" ]; then
Edition="OpenSource" Edition="OpenSource"
EditionString="Open Source" EditionString="Open Source"
fi fi
echo
echo "This is the Qt ${EditionString} Edition."
echo
if [ "$CFG_RTOS_ENABLED" = "no" ]; then if [ "$Edition" = "OpenSource" ] || [ "$Edition" = "Preview" ]; then
case `basename "$XPLATFORM"` in echo
qnx-* | vxworks-*) echo "This is the Qt ${EditionString} Edition."
echo "" echo
echo "You are not licensed for Qt for `basename $XPLATFORM`."
echo ""
echo "Please use the contact form at http://qt.digia.com/contact-us"
echo "to upgrade your license to include this platform, or install"
echo "the Qt Open Source Edition if you intend to develop free software."
exit 1
;;
esac
fi fi
if [ "$Edition" = "OpenSource" ]; then if [ "$Edition" = "OpenSource" ]; then
@ -3003,7 +2814,7 @@ if [ "$Edition" = "OpenSource" ]; then
fi fi
echo echo
if [ "$OPT_CONFIRM_LICENSE" = "yes" ]; then if [ "$OPT_CONFIRM_LICENSE" = "yes" ]; then
echo "You have already accepted the terms of the $LicenseType license." echo "You have already accepted the terms of the $EditionString license."
acceptance=yes acceptance=yes
else else
if [ -f "$relpath/LICENSE.GPL" ]; then if [ -f "$relpath/LICENSE.GPL" ]; then
@ -3034,7 +2845,7 @@ elif [ "$Edition" = "Preview" ]; then
while true; do while true; do
if [ "$OPT_CONFIRM_LICENSE" = "yes" ]; then if [ "$OPT_CONFIRM_LICENSE" = "yes" ]; then
echo "You have already accepted the terms of the $LicenseType license." echo "You have already accepted the terms of the $EditionString license."
acceptance=yes acceptance=yes
else else
echo "You are licensed to use this software under the terms of" echo "You are licensed to use this software under the terms of"
@ -3058,77 +2869,6 @@ elif [ "$Edition" = "Preview" ]; then
more "$relpath/LICENSE.PREVIEW.COMMERCIAL" more "$relpath/LICENSE.PREVIEW.COMMERCIAL"
fi fi
done done
elif [ "$Edition" != "OpenSource" ]; then
if [ -n "$ExpiryDate" ]; then
ExpiryDate=`echo $ExpiryDate | sed -e 's,-,,g' | tr -d '\n\r'`
[ -z "$ExpiryDate" ] && ExpiryDate="0"
Today=`date +%Y%m%d`
if [ "$Today" -gt "$ExpiryDate" ]; then
case "$LicenseType" in
Commercial|Academic|Educational)
echo
echo "WARNING WARNING WARNING WARNING"
echo
echo " Your support and upgrade period has expired."
echo
echo " You may continue to use your last licensed release"
echo " of Qt under the terms of your existing license"
echo " agreement. But you are not entitled to technical"
echo " support, nor are you entitled to use any more recent"
echo " Qt releases."
echo
echo " Please use the contact form at http://qt.digia.com/contact-us"
echo " to renew your support and upgrades for this license."
echo
echo "WARNING WARNING WARNING WARNING"
echo
sleep 3
;;
Evaluation|*)
echo
echo "NOTICE NOTICE NOTICE NOTICE"
echo
echo " Your Evaluation license has expired."
echo
echo " You are no longer licensed to use this software. Please"
echo " use the contact form at http://qt.digia.com/contact-us to"
echo " purchase license, or install the Qt Open Source Edition"
echo " if you intend to develop free software."
echo
echo "NOTICE NOTICE NOTICE NOTICE"
echo
exit 1
;;
esac
fi
fi
TheLicense=`head -n 1 "$outpath/LICENSE"`
while true; do
if [ "$OPT_CONFIRM_LICENSE" = "yes" ]; then
echo "You have already accepted the terms of the $TheLicense."
acceptance=yes
else
echo "You are licensed to use this software under the terms of"
echo "the $TheLicense."
echo
echo "Type '?' to view the $TheLicense."
echo "Type 'yes' to accept this license offer."
echo "Type 'no' to decline this license offer."
echo
echo $ECHO_N "Do you accept the terms of the $TheLicense? $ECHO_C"
read acceptance
fi
echo
if [ "$acceptance" = "yes" ]; then
break
elif [ "$acceptance" = "no" ]; then
echo "You are not licensed to use this software."
echo
exit 1
else [ "$acceptance" = "?" ]
more "$outpath/LICENSE"
fi
done
fi fi
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
@ -3851,22 +3591,6 @@ else
chmod -w "$outpath/src/corelib/global/qconfig.cpp" chmod -w "$outpath/src/corelib/global/qconfig.cpp"
fi fi
# -----------------------------------------------------------------------------
if [ "$LicenseType" = "Evaluation" ]; then
EVALKEY=qt_qevalkey=$LicenseKeyExt
elif echo "$DEFINES" | grep QT_EVAL >/dev/null 2>&1; then
EVALKEY=qt_qevalkey=
fi
if [ -n "$EVALKEY" ]; then
rm -f "$outpath/src/corelib/global/qconfig_eval.cpp"
cat > "$outpath/src/corelib/global/qconfig_eval.cpp" <<EOF
/* Evaluation license key */
static const volatile char qt_eval_key_data [512 + 12] = "$EVALKEY";
EOF
chmod -w "$outpath/src/corelib/global/qconfig_eval.cpp"
fi
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# build qmake # build qmake
@ -6224,10 +5948,6 @@ full)
;; ;;
esac esac
cat >>"$outpath/src/corelib/global/qconfig.h.new" <<EOF
EOF
echo '/* Compile time features */' >>"$outpath/src/corelib/global/qconfig.h.new" echo '/* Compile time features */' >>"$outpath/src/corelib/global/qconfig.h.new"
[ '!' -z "$LicenseKeyExt" ] && echo "#define QT_PRODUCT_LICENSEKEY \"$LicenseKeyExt\"" >>"$outpath/src/corelib/global/qconfig.h.new" [ '!' -z "$LicenseKeyExt" ] && echo "#define QT_PRODUCT_LICENSEKEY \"$LicenseKeyExt\"" >>"$outpath/src/corelib/global/qconfig.h.new"

View File

@ -3,7 +3,7 @@
dita.metadata.default.author = Qt Project dita.metadata.default.author = Qt Project
dita.metadata.default.permissions = all dita.metadata.default.permissions = all
dita.metadata.default.publisher = Qt Project dita.metadata.default.publisher = Qt Project
dita.metadata.default.copyryear = 2013 dita.metadata.default.copyryear = 2014
dita.metadata.default.copyrholder = Digia Plc dita.metadata.default.copyrholder = Digia Plc
dita.metadata.default.audience = programmer dita.metadata.default.audience = programmer

View File

@ -8,7 +8,7 @@ HTML.footer = \
"</div>\n" \ "</div>\n" \
"<div class=\"footer\">\n" \ "<div class=\"footer\">\n" \
" <p>\n" \ " <p>\n" \
" <acronym title=\"Copyright\">&copy;</acronym> 2013 Digia Plc and/or its\n" \ " <acronym title=\"Copyright\">&copy;</acronym> 2014 Digia Plc and/or its\n" \
" subsidiaries. Documentation contributions included herein are the copyrights of\n" \ " subsidiaries. Documentation contributions included herein are the copyrights of\n" \
" their respective owners.<br>" \ " their respective owners.<br>" \
" The documentation provided herein is licensed under the terms of the" \ " The documentation provided herein is licensed under the terms of the" \

View File

@ -1,31 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** 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 Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/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 remotecontrolledcar
\title D-Bus Remote Controlled Car Example
*/

View File

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -26,14 +26,14 @@
****************************************************************************/ ****************************************************************************/
/*! /*!
\example ipc/localfortuneclient \example localfortuneclient
\title Local Fortune Client Example \title Local Fortune Client Example
\ingroup examples-ipc \ingroup examples-ipc
\brief Demonstrates using QLocalSocket for a simple local service client. \brief Demonstrates using QLocalSocket for a simple local service client.
The Local Fortune Client example shows how to create a client for a simple The Local Fortune Client example shows how to create a client for a simple
local service using QLocalSocket. It is intended to be run alongside the local service using QLocalSocket. It is intended to be run alongside the
\l{ipc/localfortuneserver}{Local Fortune Server} example. \l{Local Fortune Server Example}.
\image localfortuneclient-example.png Screenshot of the Local Fortune Client example \image localfortuneclient-example.png Screenshot of the Local Fortune Client example

View File

@ -26,14 +26,14 @@
****************************************************************************/ ****************************************************************************/
/*! /*!
\example ipc/localfortuneserver \example localfortuneserver
\title Local Fortune Server Example \title Local Fortune Server Example
\ingroup examples-ipc \ingroup examples-ipc
\brief Demonstrates using QLocalServer and QLocalSocket for serving a simple local service. \brief Demonstrates using QLocalServer and QLocalSocket for serving a simple local service.
The Local Fortune Server example shows how to create a server for a simple The Local Fortune Server example shows how to create a server for a simple
local service. It is intended to be run alongside the local service. It is intended to be run alongside the
\l{ipc/localfortuneclient}{Local Fortune Client} example \l{Local Fortune Client Example}
\image localfortuneserver-example.png Screenshot of the Local Fortune Server example \image localfortuneserver-example.png Screenshot of the Local Fortune Server example
*/ */

View File

@ -26,7 +26,7 @@
****************************************************************************/ ****************************************************************************/
/*! /*!
\example ipc/sharedmemory \example sharedmemory
\title Shared Memory Example \title Shared Memory Example
\ingroup examples-ipc \ingroup examples-ipc
\brief Demonstrates doing inter-process communication using shared memory with \brief Demonstrates doing inter-process communication using shared memory with
@ -40,7 +40,7 @@
dialog is displayed and then control is passed to the application in dialog is displayed and then control is passed to the application in
the standard way. the standard way.
\snippet examples/ipc/sharedmemory/main.cpp 0 \snippet sharedmemory/main.cpp 0
Two instances of class Dialog appear. Two instances of class Dialog appear.
@ -51,12 +51,12 @@
loadFromFile() and loadFromMemory() that correspond to the two loadFromFile() and loadFromMemory() that correspond to the two
buttons on the dialog. buttons on the dialog.
\snippet examples/ipc/sharedmemory/dialog.h 0 \snippet sharedmemory/dialog.h 0
The constructor builds the user interface widgets and connects the The constructor builds the user interface widgets and connects the
clicked() signal of each button to the corresponding slot function. clicked() signal of each button to the corresponding slot function.
\snippet examples/ipc/sharedmemory/dialog.cpp 0 \snippet sharedmemory/dialog.cpp 0
Note that "QSharedMemoryExample" is passed to the \l {QSharedMemory} Note that "QSharedMemoryExample" is passed to the \l {QSharedMemory}
{QSharedMemory()} constructor to be used as the key. This will be {QSharedMemory()} constructor to be used as the key. This will be
@ -69,7 +69,7 @@
that segment is detached from the process, so we can be assured of that segment is detached from the process, so we can be assured of
starting off the example correctly. starting off the example correctly.
\snippet examples/ipc/sharedmemory/dialog.cpp 1 \snippet sharedmemory/dialog.cpp 1
The user is then asked to select an image file using The user is then asked to select an image file using
QFileDialog::getOpenFileName(). The selected file is loaded into a QFileDialog::getOpenFileName(). The selected file is loaded into a
@ -85,7 +85,7 @@
to the image data, which we then use to do a memcopy() from the to the image data, which we then use to do a memcopy() from the
QBuffer into the shared memory segment. QBuffer into the shared memory segment.
\snippet examples/ipc/sharedmemory/dialog.cpp 2 \snippet sharedmemory/dialog.cpp 2
Note that we \l {QSharedMemory::} {lock()} the shared memory segment Note that we \l {QSharedMemory::} {lock()} the shared memory segment
before we copy into it, and we \l {QSharedMemory::} {unlock()} it before we copy into it, and we \l {QSharedMemory::} {unlock()} it
@ -117,7 +117,7 @@
then streams the data into a QImage and \l {QSharedMemory::unlock()} then streams the data into a QImage and \l {QSharedMemory::unlock()}
{unlocks} the segment. {unlocks} the segment.
\snippet examples/ipc/sharedmemory/dialog.cpp 3 \snippet sharedmemory/dialog.cpp 3
In this case, the function does \l {QSharedMemory::} {detach()} from In this case, the function does \l {QSharedMemory::} {detach()} from
the segment, because now we are effectively finished using the segment, because now we are effectively finished using

View File

@ -1,9 +1,7 @@
Qt 4 makes it easier than ever to write multithreaded applications. More This folder contains examples for the use of the threading-related classes
classes have been made usable from non-GUI threads, and the signals and slots in Qt Core. For examples using the higher-level Qt Concurrent module,
mechanism can now be used to communicate between threads. check out the "qtconcurrent" folder instead.
Additionally, it is now possible to move objects between threads. Documentation for examples can be found via the Examples and Tutorials link
in the main Qt documentation. The examples and their documentation can also
be opened from the Examples tab of Qt Creator's Welcome mode.
Documentation for these examples can be found via the Examples
link in the main Qt documentation.

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the examples of the Qt Toolkit. ** This file is part of the examples of the Qt Toolkit.
@ -43,6 +43,8 @@
#include <QtWidgets> #include <QtWidgets>
Q_LOGGING_CATEGORY(lcExample, "qt.examples.imagegestures")
//! [constructor] //! [constructor]
ImageWidget::ImageWidget(QWidget *parent) ImageWidget::ImageWidget(QWidget *parent)
: QWidget(parent), : QWidget(parent),
@ -55,15 +57,17 @@ ImageWidget::ImageWidget(QWidget *parent)
{ {
setMinimumSize(QSize(100,100)); setMinimumSize(QSize(100,100));
//! [enable gestures]
grabGesture(Qt::PanGesture);
grabGesture(Qt::PinchGesture);
grabGesture(Qt::SwipeGesture);
//! [enable gestures]
} }
//! [constructor] //! [constructor]
void ImageWidget::grabGestures(const QList<Qt::GestureType> &gestures)
{
//! [enable gestures]
foreach (Qt::GestureType gesture, gestures)
grabGesture(gesture);
//! [enable gestures]
}
//! [event handler] //! [event handler]
bool ImageWidget::event(QEvent *event) bool ImageWidget::event(QEvent *event)
{ {
@ -77,10 +81,10 @@ void ImageWidget::paintEvent(QPaintEvent*)
{ {
QPainter p(this); QPainter p(this);
float iw = currentImage.width(); const qreal iw = currentImage.width();
float ih = currentImage.height(); const qreal ih = currentImage.height();
float wh = height(); const qreal wh = height();
float ww = width(); const qreal ww = width();
p.translate(ww/2, wh/2); p.translate(ww/2, wh/2);
p.translate(horizontalOffset, verticalOffset); p.translate(horizontalOffset, verticalOffset);
@ -98,11 +102,13 @@ void ImageWidget::mouseDoubleClickEvent(QMouseEvent *)
verticalOffset = 0; verticalOffset = 0;
horizontalOffset = 0; horizontalOffset = 0;
update(); update();
qCDebug(lcExample) << "reset on mouse double click";
} }
//! [gesture event handler] //! [gesture event handler]
bool ImageWidget::gestureEvent(QGestureEvent *event) bool ImageWidget::gestureEvent(QGestureEvent *event)
{ {
qCDebug(lcExample) << "gestureEvent():" << event->gestures().size();
if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) if (QGesture *swipe = event->gesture(Qt::SwipeGesture))
swipeTriggered(static_cast<QSwipeGesture *>(swipe)); swipeTriggered(static_cast<QSwipeGesture *>(swipe));
else if (QGesture *pan = event->gesture(Qt::PanGesture)) else if (QGesture *pan = event->gesture(Qt::PanGesture))
@ -126,6 +132,7 @@ void ImageWidget::panTriggered(QPanGesture *gesture)
} }
#endif #endif
QPointF delta = gesture->delta(); QPointF delta = gesture->delta();
qCDebug(lcExample) << "panTriggered():" << delta;
horizontalOffset += delta.x(); horizontalOffset += delta.x();
verticalOffset += delta.y(); verticalOffset += delta.y();
update(); update();
@ -135,13 +142,16 @@ void ImageWidget::pinchTriggered(QPinchGesture *gesture)
{ {
QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags(); QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags();
if (changeFlags & QPinchGesture::RotationAngleChanged) { if (changeFlags & QPinchGesture::RotationAngleChanged) {
qreal value = gesture->property("rotationAngle").toReal(); const qreal value = gesture->property("rotationAngle").toReal();
qreal lastValue = gesture->property("lastRotationAngle").toReal(); const qreal lastValue = gesture->property("lastRotationAngle").toReal();
rotationAngle += value - lastValue; const qreal rotationAngleDelta = value - lastValue;
rotationAngle += rotationAngleDelta;
qCDebug(lcExample) << "pinchTriggered(): rotation by" << rotationAngleDelta << rotationAngle;
} }
if (changeFlags & QPinchGesture::ScaleFactorChanged) { if (changeFlags & QPinchGesture::ScaleFactorChanged) {
qreal value = gesture->property("scaleFactor").toReal(); qreal value = gesture->property("scaleFactor").toReal();
currentStepScaleFactor = value; currentStepScaleFactor = value;
qCDebug(lcExample) << "pinchTriggered(): " << currentStepScaleFactor;
} }
if (gesture->state() == Qt::GestureFinished) { if (gesture->state() == Qt::GestureFinished) {
scaleFactor *= currentStepScaleFactor; scaleFactor *= currentStepScaleFactor;
@ -155,10 +165,13 @@ void ImageWidget::swipeTriggered(QSwipeGesture *gesture)
{ {
if (gesture->state() == Qt::GestureFinished) { if (gesture->state() == Qt::GestureFinished) {
if (gesture->horizontalDirection() == QSwipeGesture::Left if (gesture->horizontalDirection() == QSwipeGesture::Left
|| gesture->verticalDirection() == QSwipeGesture::Up) || gesture->verticalDirection() == QSwipeGesture::Up) {
qCDebug(lcExample) << "swipeTriggered(): swipe to previous";
goPrevImage(); goPrevImage();
else } else {
qCDebug(lcExample) << "swipeTriggered(): swipe to next";
goNextImage(); goNextImage();
}
update(); update();
} }
} }
@ -184,17 +197,22 @@ void ImageWidget::openDirectory(const QString &path)
QImage ImageWidget::loadImage(const QString &fileName) QImage ImageWidget::loadImage(const QString &fileName)
{ {
qDebug() << position << files << fileName;
QImageReader reader(fileName); QImageReader reader(fileName);
qCDebug(lcExample) << "loading" << QDir::toNativeSeparators(fileName) << position << '/' << files.size();
if (!reader.canRead()) { if (!reader.canRead()) {
qDebug() << fileName << ": can't load image"; qCWarning(lcExample) << QDir::toNativeSeparators(fileName) << ": can't load image";
return QImage(); return QImage();
} }
QImage image; QImage image;
if (!reader.read(&image)) { if (!reader.read(&image)) {
qDebug() << fileName << ": corrupted image"; qCWarning(lcExample) << QDir::toNativeSeparators(fileName) << ": corrupted image: " << reader.errorString();
return QImage(); return QImage();
} }
const QSize maximumSize(2000, 2000); // Reduce in case someone has large photo images.
if (image.size().width() > maximumSize.width() || image.height() > maximumSize.height())
image = image.scaled(maximumSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
return image; return image;
} }
@ -238,7 +256,7 @@ void ImageWidget::goToImage(int index)
return; return;
if (index < 0 || index >= files.size()) { if (index < 0 || index >= files.size()) {
qDebug() << "goToImage: invalid index: " << index; qCWarning(lcExample) << "goToImage: invalid index: " << index;
return; return;
} }

View File

@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the examples of the Qt Toolkit. ** This file is part of the examples of the Qt Toolkit.
@ -52,6 +52,8 @@ class QPinchGesture;
class QSwipeGesture; class QSwipeGesture;
QT_END_NAMESPACE QT_END_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcExample)
//! [class definition begin] //! [class definition begin]
class ImageWidget : public QWidget class ImageWidget : public QWidget
{ {
@ -60,6 +62,7 @@ class ImageWidget : public QWidget
public: public:
ImageWidget(QWidget *parent = 0); ImageWidget(QWidget *parent = 0);
void openDirectory(const QString &path); void openDirectory(const QString &path);
void grabGestures(const QList<Qt::GestureType> &gestures);
protected: protected:
bool event(QEvent *event); bool event(QEvent *event);
@ -88,11 +91,11 @@ private:
QImage prevImage, nextImage; QImage prevImage, nextImage;
QImage currentImage; QImage currentImage;
float horizontalOffset; qreal horizontalOffset;
float verticalOffset; qreal verticalOffset;
float rotationAngle; qreal rotationAngle;
float scaleFactor; qreal scaleFactor;
float currentStepScaleFactor; qreal currentStepScaleFactor;
//! [class definition end] //! [class definition end]
}; };
//! [class definition end] //! [class definition end]

View File

@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the examples of the Qt Toolkit. ** This file is part of the examples of the Qt Toolkit.
@ -42,17 +42,86 @@
#include "mainwidget.h" #include "mainwidget.h"
static void showHelp(QCommandLineParser &parser, const QString errorMessage = QString())
{
QString text;
QTextStream str(&text);
str << "<html><head/><body>";
if (!errorMessage.isEmpty())
str << "<p>" << errorMessage << "</p>";
str << "<pre>" << parser.helpText() << "</pre></body></html>";
QMessageBox box(errorMessage.isEmpty() ? QMessageBox::Information : QMessageBox::Warning,
QGuiApplication::applicationDisplayName(), text,
QMessageBox::Ok);
box.setTextInteractionFlags(Qt::TextBrowserInteraction);
box.exec();
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication app(argc, argv); QApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QT_VERSION_STR);
QCoreApplication::setApplicationName(QStringLiteral("imagegestures"));
QGuiApplication::setApplicationDisplayName(QStringLiteral("Image Gestures Example"));
QCommandLineParser commandLineParser;
const QCommandLineOption disablePanOption("no-pan", "Disable pan gesture");
commandLineParser.addOption(disablePanOption);
const QCommandLineOption disablePinchOption("no-pinch", "Disable pinch gesture");
commandLineParser.addOption(disablePinchOption);
const QCommandLineOption disableSwipeOption("no-swipe", "Disable swipe gesture");
commandLineParser.addOption(disableSwipeOption);
const QCommandLineOption helpOption = commandLineParser.addHelpOption();
commandLineParser.addPositionalArgument(QStringLiteral("Directory"),
QStringLiteral("Directory to display"));
const QString description = QGuiApplication::applicationDisplayName()
+ QLatin1String("\n\nEnable \"debug\" on the logging category \"qt.examples.imagegestures\" in order to\n"
"in order to obtain verbose information about Qt's gesture event processing,\n"
"for example by setting the environment variables QT_LOGGING_RULES to\n"
"qt.examples.imagegestures.debug=true\n");
commandLineParser.setApplicationDescription(description);
if (!commandLineParser.parse(QCoreApplication::arguments())) {
showHelp(commandLineParser, commandLineParser.errorText());
return -1;
}
if (commandLineParser.isSet(helpOption)) {
showHelp(commandLineParser);
return 0;
}
QStringList arguments = commandLineParser.positionalArguments();
if (!arguments.isEmpty() && !QFileInfo(arguments.front()).isDir()) {
showHelp(commandLineParser,
QLatin1Char('"') + QDir::toNativeSeparators(arguments.front())
+ QStringLiteral("\" is not a directory."));
return -1;
}
QList<Qt::GestureType> gestures;
if (!commandLineParser.isSet(disablePanOption))
gestures << Qt::PanGesture;
if (!commandLineParser.isSet(disablePinchOption))
gestures << Qt::PinchGesture;
if (!commandLineParser.isSet(disableSwipeOption))
gestures << Qt::SwipeGesture;
MainWidget w; MainWidget w;
w.grabGestures(gestures);
w.show(); w.show();
if (QApplication::arguments().size() > 1) if (arguments.isEmpty()) {
w.openDirectory(QApplication::arguments().at(1)); const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
else const QString directory =
w.openDirectory(QFileDialog::getExistingDirectory(0, "Select image folder")); QFileDialog::getExistingDirectory(&w, "Select image folder",
picturesLocations.isEmpty() ? QString() : picturesLocations.front());
if (directory.isEmpty())
return 0;
arguments.append(directory);
}
w.openDirectory(arguments.front());
return app.exec(); return app.exec();
} }

View File

@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the examples of the Qt Toolkit. ** This file is part of the examples of the Qt Toolkit.
@ -41,15 +41,28 @@
#include "imagewidget.h" #include "imagewidget.h"
#include "mainwidget.h" #include "mainwidget.h"
#include <QScreen>
#include <QGuiApplication>
#include <QDir>
MainWidget::MainWidget(QWidget *parent) MainWidget::MainWidget(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
, imageWidget(new ImageWidget(this))
{ {
resize(400, 300);
imageWidget = new ImageWidget(this);
setCentralWidget(imageWidget); setCentralWidget(imageWidget);
const QRect screenGeometry = QGuiApplication::primaryScreen()->availableGeometry();
QRect geometry(QPoint(0, 0), QSize(screenGeometry.width() * 3 / 4, screenGeometry.height() * 3 / 4));
geometry.moveCenter(screenGeometry.center());
setGeometry(geometry);
} }
void MainWidget::openDirectory(const QString &path) void MainWidget::openDirectory(const QString &path)
{ {
setWindowTitle(QDir::toNativeSeparators(path));
imageWidget->openDirectory(path); imageWidget->openDirectory(path);
} }
void MainWidget::grabGestures(const QList<Qt::GestureType> &gestures)
{
imageWidget->grabGestures(gestures);
}

View File

@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the examples of the Qt Toolkit. ** This file is part of the examples of the Qt Toolkit.
@ -51,6 +51,7 @@ class MainWidget : public QMainWindow
public: public:
MainWidget(QWidget *parent = 0); MainWidget(QWidget *parent = 0);
void grabGestures(const QList<Qt::GestureType> &gestures);
public slots: public slots:
void openDirectory(const QString &path); void openDirectory(const QString &path);

View File

@ -1,4 +1,4 @@
QMAKE_TARGET_COMPANY = Digia Plc and/or its subsidiary(-ies) QMAKE_TARGET_COMPANY = Digia Plc and/or its subsidiary(-ies)
QMAKE_TARGET_PRODUCT = Qt5 QMAKE_TARGET_PRODUCT = Qt5
QMAKE_TARGET_DESCRIPTION = C++ application development framework. QMAKE_TARGET_DESCRIPTION = C++ application development framework.
QMAKE_TARGET_COPYRIGHT = Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). QMAKE_TARGET_COPYRIGHT = Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).

View File

@ -0,0 +1,60 @@
# Provide default fonts for windows phone
# The DEFAULTFONTS variable indicates, whether the default set of fonts is
# used for deployment. The check below won't work after the fonts are added
# so this helper variable is added and used for the user warning check later.
!defined(FONTS, var):winphone {
FONTS = \
$$[QT_HOST_PREFIX/src]/lib/fonts/DejaVuSans.ttf \
$$[QT_HOST_PREFIX/src]/lib/fonts/DejaVuSans-Bold.ttf \
$$[QT_HOST_PREFIX/src]/lib/fonts/DejaVuSans-BoldOblique.ttf \
$$[QT_HOST_PREFIX/src]/lib/fonts/DejaVuSansMono.ttf \
$$[QT_HOST_PREFIX/src]/lib/fonts/DejaVuSansMono-Bold.ttf \
$$[QT_HOST_PREFIX/src]/lib/fonts/DejaVuSansMono-BoldOblique.ttf \
$$[QT_HOST_PREFIX/src]/lib/fonts/DejaVuSansMono-Oblique.ttf \
$$[QT_HOST_PREFIX/src]/lib/fonts/DejaVuSans-Oblique.ttf \
$$[QT_HOST_PREFIX/src]/lib/fonts/DejaVuSerif.ttf \
$$[QT_HOST_PREFIX/src]/lib/fonts/DejaVuSerif-Bold.ttf \
$$[QT_HOST_PREFIX/src]/lib/fonts/DejaVuSerif-BoldOblique.ttf \
$$[QT_HOST_PREFIX/src]/lib/fonts/DejaVuSerif-Oblique.ttf
DEFAULTFONTS =
}
if(build_pass:equals(TEMPLATE, "app"))| \
if(!build_pass:equals(TEMPLATE, "vcapp")) {
defined(DEFAULTFONTS, var) {
message(Default fonts will automatically be deployed with your application. \
To avoid automatic deployment unset the \"FONTS\" variable (\"FONTS =\") in your .pro file. \
You can also customize which fonts are deployed by setting the \"FONTS\" variable.)
}
contains(TEMPLATE, "vc.*") {
BUILD_DIR = $$OUT_PWD
} else {
load(resolve_target)
BUILD_DIR = $$dirname(QMAKE_RESOLVED_TARGET)
}
for (FONT, FONTS) {
font_$${FONT}.input = $$FONT
font_$${FONT}.output = $$BUILD_DIR/fonts/$$basename(FONT)
font_$${FONT}.CONFIG = verbatim
QMAKE_SUBSTITUTES += font_$${FONT}
}
!isEmpty(FONTS):equals(TEMPLATE, "app") {
fonts.files = $$BUILD_DIR/fonts/*
isEmpty($$target.path) {
fonts.path = $$OUT_PWD/fonts
} else {
fonts.path = $$target.path/fonts
}
INSTALLS += fonts
}
}
!isEmpty(FONTS):winphone:equals(TEMPLATE, "vcapp"):build_pass {
fonts.files = $$OUT_PWD/fonts/*
fonts.path = fonts
DEPLOYMENT += fonts
}

View File

@ -28,6 +28,7 @@
# WINRT_MANIFEST.iconic_tile_icon: Image file for the "iconic" tile template icon. Default provided by the mkspec. # WINRT_MANIFEST.iconic_tile_icon: Image file for the "iconic" tile template icon. Default provided by the mkspec.
# WINRT_MANIFEST.iconic_tile_small: Image file for the small "iconic" tile template logo. Default provided by the mkspec. # WINRT_MANIFEST.iconic_tile_small: Image file for the small "iconic" tile template logo. Default provided by the mkspec.
# WINRT_MANIFEST.capabilities: Specifies capabilities to add to the capability list. # WINRT_MANIFEST.capabilities: Specifies capabilities to add to the capability list.
# WINRT_MANIFEST.capabilities_device: Specifies device capabilities to add to the capability list. (location, webcam...)
# WINRT_MANIFEST.dependencies: Specifies dependencies required by the package. # WINRT_MANIFEST.dependencies: Specifies dependencies required by the package.
# The manifest is generated for each build pass for normal apps, and only once for vcapps. # The manifest is generated for each build pass for normal apps, and only once for vcapps.
@ -95,10 +96,14 @@
# Capabilities are given as a string list and may change with the configuration (network, sensors, etc.) # Capabilities are given as a string list and may change with the configuration (network, sensors, etc.)
WINRT_MANIFEST.capabilities = $$unique(WINRT_MANIFEST.capabilities) WINRT_MANIFEST.capabilities = $$unique(WINRT_MANIFEST.capabilities)
!isEmpty(WINRT_MANIFEST.capabilities)|winphone { WINRT_MANIFEST.capabilities_device = $$unique(WINRT_MANIFEST.capabilities_device)
!isEmpty(WINRT_MANIFEST.capabilities)|!isEmpty(WINRT_MANIFEST.capabilities_device)|winphone {
MANIFEST_CAPABILITIES += "<Capabilities>" MANIFEST_CAPABILITIES += "<Capabilities>"
for(CAPABILITY, WINRT_MANIFEST.capabilities): \ for(CAPABILITY, WINRT_MANIFEST.capabilities): \
MANIFEST_CAPABILITIES += " <Capability Name=\"$$CAPABILITY\" />" MANIFEST_CAPABILITIES += " <Capability Name=\"$$CAPABILITY\" />"
!winphone:for(CAPABILITY, WINRT_MANIFEST.capabilities_device): \
MANIFEST_CAPABILITIES += " <DeviceCapability Name=\"$$CAPABILITY\" />"
MANIFEST_CAPABILITIES += "</Capabilities>" MANIFEST_CAPABILITIES += "</Capabilities>"
WINRT_MANIFEST.capabilities = $$join(MANIFEST_CAPABILITIES, $$INDENT, $$INDENT) WINRT_MANIFEST.capabilities = $$join(MANIFEST_CAPABILITIES, $$INDENT, $$INDENT)

View File

@ -7,6 +7,7 @@
include(../common/winrt_winphone/qmake.conf) include(../common/winrt_winphone/qmake.conf)
QMAKE_COMPILER_DEFINES += _MSC_VER=1700 QMAKE_COMPILER_DEFINES += _MSC_VER=1700
QMAKE_PLATFORM = winphone $$QMAKE_PLATFORM QMAKE_PLATFORM = winphone $$QMAKE_PLATFORM
CONFIG += font_deployment
DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP ARM __ARM__ __arm__ DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP ARM __ARM__ __arm__
QMAKE_LFLAGS += /MACHINE:ARM QMAKE_LFLAGS += /MACHINE:ARM

View File

@ -7,6 +7,7 @@
include(../common/winrt_winphone/qmake.conf) include(../common/winrt_winphone/qmake.conf)
QMAKE_COMPILER_DEFINES += _MSC_VER=1700 QMAKE_COMPILER_DEFINES += _MSC_VER=1700
QMAKE_PLATFORM = winphone $$QMAKE_PLATFORM QMAKE_PLATFORM = winphone $$QMAKE_PLATFORM
CONFIG += font_deployment
DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP X86 __X86__ __x86__ DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP X86 __X86__ __x86__
QMAKE_LFLAGS += /MACHINE:X86 QMAKE_LFLAGS += /MACHINE:X86

View File

@ -2382,6 +2382,118 @@
See also \l{#DEPENDPATH}{DEPENDPATH}. See also \l{#DEPENDPATH}{DEPENDPATH}.
\target WINRT_MANIFEST
\section1 WINRT_MANIFEST
Specifies parameters to be passed to the application manifest on \l{Qt for WinRT}{Windows
Runtime}. The allowed values are:
\table
\header
\li Member
\li Description
\row
\li architecture
\li The target architecture. Defaults to \c VCPROJ_ARCH.
\row
\li arguments
\li Allows arguments to be passed to the executable.
\row
\li author
\li Package author. Defaults to \c{Default package author}.
This option is only available for Windows Phone.
\row
\li background
\li Tile background color. Defaults to \c{green}.
\row
\li capabilities
\li Specifies capabilities to add to the capability list.
\row
\li capabilities_device
\li Specifies device capabilities to add to the capability list
(location, webcam, and so on). This option is not available on Windows Phone.
\row
\li dependencies
\li Specifies dependencies required by the package.
\row
\li description
\li Package description. Defaults to \c{Default package description}.
\row
\li foreground
\li Tile foreground (text) color. Defaults to \c{light}.
This option is only available for Windows Store apps on Windows 8 and Windows RT.
\row
\li genre
\li Package genre. Defaults to \c{apps.normal}.
This option is only available for Windows Phone.
\row
\li iconic_tile_icon
\li Image file for the \c{iconic} tile template icon. Default provided by
the mkspec.
\row
\li iconic_tile_small
\li Image file for the small \c{iconic} tile template logo. Default provided
by the mkspec.
\row
\li identity
\li The unique ID of the app. Defaults to reusing the existing generated
manifest's UUID, or generates a new UUID if none is present.
\row
\li logo_large
\li Large logo image file. Default provided by the mkspec.
\row
\li logo_medium
\li Medium logo image file. Default provided by the mkspec.
\row
\li logo_small
\li Small logo image file. Default provided by the mkspec.
\row
\li logo_store
\li Logo image file for Windows Store. Default provided by the mkspec.
\row
\li name
\li The name of the package as displayed to the user. Defaults to TARGET.
\row
\li publisher
\li Display name of the publisher. Defaults to \c{Default publisher display name}.
\row
\li publisher_id
\li On Windows 8 or Windows RT, the publisher's distinguished name (default: \c{CN=MyCN}).
On Windows Phone, the publisher's UUID (default: invalid UUID string).
\row
\li splash_screen
\li Splash screen image file. Default provided by the mkspec.
\row
\li target
\li The name of the target (.exe). Defaults to TARGET.
\row
\li version
\li The version number of the package. Defaults to \c{1.0.0.0}.
\endtable
You can use any combination of those values.
For example:
\code
WINRT_MANIFEST.publisher = MyCompany
WINRT_MANIFEST.logo_store = someImage.png
winphone {
WINRT_MANIFEST.capabilities += ID_CAP_LOCATION ID_CAP_NETWORKING
} else {
WINRT_MANIFEST.capabilities += internetClient
WINRT_MANIFEST.device_capabilities += location
}
\endcode
Additionally, an input manifest file can be specified by using WINRT_MANIFEST.
For example:
\code
WINRT_MANIFEST = someManifest.xml.in
\endcode
\target YACCSOURCES \target YACCSOURCES
\section1 YACCSOURCES \section1 YACCSOURCES

View File

@ -3299,7 +3299,7 @@ MakefileGenerator::writePkgConfigFile()
pkgConfiglibName = "-framework " + bundle + " "; pkgConfiglibName = "-framework " + bundle + " ";
} else { } else {
pkgConfiglibDir = "-L${libdir}"; pkgConfiglibDir = "-L${libdir}";
pkgConfiglibName = "-l" + fileInfo(fname).completeBaseName(); pkgConfiglibName = "-l" + unescapeFilePath(project->first("QMAKE_ORIG_TARGET"));
if (project->isActiveConfig("shared")) if (project->isActiveConfig("shared"))
pkgConfiglibName += project->first("TARGET_VERSION_EXT").toQString(); pkgConfiglibName += project->first("TARGET_VERSION_EXT").toQString();
} }

View File

@ -69,6 +69,8 @@ void DeallocateCurrent()
} }
#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{ {
switch (reason) switch (reason)
@ -124,6 +126,8 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
return TRUE; return TRUE;
} }
#endif // !QT_OPENGL_ES_2_ANGLE_STATIC
namespace egl namespace egl
{ {

View File

@ -66,6 +66,8 @@ void DeallocateCurrent()
} }
#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{ {
switch (reason) switch (reason)
@ -107,6 +109,8 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
return TRUE; return TRUE;
} }
#endif // !QT_OPENGL_ES_2_ANGLE_STATIC
namespace gl namespace gl
{ {

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite ** This file is an amalgamation of many separate C source files from SQLite
** version 3.8.4.1. By combining all the individual C code files into this ** version 3.8.4.2. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation ** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be ** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements ** possible if the files were compiled separately. Performance improvements
@ -222,9 +222,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()]. ** [sqlite_version()] and [sqlite_source_id()].
*/ */
#define SQLITE_VERSION "3.8.4.1" #define SQLITE_VERSION "3.8.4.2"
#define SQLITE_VERSION_NUMBER 3008004 #define SQLITE_VERSION_NUMBER 3008004
#define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0" #define SQLITE_SOURCE_ID "2014-03-26 18:51:19 02ea166372bdb2ef9d8dfbb05e78a97609673a8e"
/* /*
** CAPI3REF: Run-Time Library Version Numbers ** CAPI3REF: Run-Time Library Version Numbers
@ -64786,6 +64786,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
}else{ }else{
idx1 = getVarint32(aKey1, szHdr1); idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1; d1 = szHdr1;
if( d1>(unsigned)nKey1 ) return 1; /* Corruption */
i = 0; i = 0;
} }

View File

@ -107,9 +107,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()]. ** [sqlite_version()] and [sqlite_source_id()].
*/ */
#define SQLITE_VERSION "3.8.4.1" #define SQLITE_VERSION "3.8.4.2"
#define SQLITE_VERSION_NUMBER 3008004 #define SQLITE_VERSION_NUMBER 3008004
#define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0" #define SQLITE_SOURCE_ID "2014-03-26 18:51:19 02ea166372bdb2ef9d8dfbb05e78a97609673a8e"
/* /*
** CAPI3REF: Run-Time Library Version Numbers ** CAPI3REF: Run-Time Library Version Numbers

View File

@ -120,7 +120,7 @@ public class QtActivityDelegate
private boolean m_keyboardIsVisible = false; private boolean m_keyboardIsVisible = false;
public boolean m_backKeyPressedSent = false; public boolean m_backKeyPressedSent = false;
private long m_showHideTimeStamp = System.nanoTime();
public void setFullScreen(boolean enterFullScreen) public void setFullScreen(boolean enterFullScreen)
{ {
@ -201,12 +201,18 @@ public class QtActivityDelegate
private final int ApplicationInactive = 0x2; private final int ApplicationInactive = 0x2;
private final int ApplicationActive = 0x4; private final int ApplicationActive = 0x4;
public void setKeyboardVisibility(boolean visibility)
public boolean setKeyboardVisibility(boolean visibility, long timeStamp)
{ {
if (m_showHideTimeStamp > timeStamp)
return false;
m_showHideTimeStamp = timeStamp;
if (m_keyboardIsVisible == visibility) if (m_keyboardIsVisible == visibility)
return; return false;
m_keyboardIsVisible = visibility; m_keyboardIsVisible = visibility;
QtNative.keyboardVisibilityChanged(m_keyboardIsVisible); QtNative.keyboardVisibilityChanged(m_keyboardIsVisible);
return true;
} }
public void resetSoftwareKeyboard() public void resetSoftwareKeyboard()
{ {
@ -304,11 +310,11 @@ public class QtActivityDelegate
QtNativeInputConnection.updateCursorPosition(); QtNativeInputConnection.updateCursorPosition();
//FALLTHROUGH //FALLTHROUGH
case InputMethodManager.RESULT_UNCHANGED_SHOWN: case InputMethodManager.RESULT_UNCHANGED_SHOWN:
setKeyboardVisibility(true); setKeyboardVisibility(true, System.nanoTime());
break; break;
case InputMethodManager.RESULT_HIDDEN: case InputMethodManager.RESULT_HIDDEN:
case InputMethodManager.RESULT_UNCHANGED_HIDDEN: case InputMethodManager.RESULT_UNCHANGED_HIDDEN:
setKeyboardVisibility(false); setKeyboardVisibility(false, System.nanoTime());
break; break;
} }
} }
@ -331,11 +337,11 @@ public class QtActivityDelegate
switch (resultCode) { switch (resultCode) {
case InputMethodManager.RESULT_SHOWN: case InputMethodManager.RESULT_SHOWN:
case InputMethodManager.RESULT_UNCHANGED_SHOWN: case InputMethodManager.RESULT_UNCHANGED_SHOWN:
setKeyboardVisibility(true); setKeyboardVisibility(true, System.nanoTime());
break; break;
case InputMethodManager.RESULT_HIDDEN: case InputMethodManager.RESULT_HIDDEN:
case InputMethodManager.RESULT_UNCHANGED_HIDDEN: case InputMethodManager.RESULT_UNCHANGED_HIDDEN:
setKeyboardVisibility(false); setKeyboardVisibility(false, System.nanoTime());
break; break;
} }
} }
@ -827,7 +833,7 @@ public class QtActivityDelegate
if (keyCode == KeyEvent.KEYCODE_BACK && !m_backKeyPressedSent) { if (keyCode == KeyEvent.KEYCODE_BACK && !m_backKeyPressedSent) {
hideSoftwareKeyboard(); hideSoftwareKeyboard();
setKeyboardVisibility(false); setKeyboardVisibility(false, System.nanoTime());
return true; return true;
} }

View File

@ -61,6 +61,8 @@ class QtExtractedText
class QtNativeInputConnection class QtNativeInputConnection
{ {
static native boolean beginBatchEdit();
static native boolean endBatchEdit();
static native boolean commitText(String text, int newCursorPosition); static native boolean commitText(String text, int newCursorPosition);
static native boolean commitCompletion(String text, int position); static native boolean commitCompletion(String text, int position);
static native boolean deleteSurroundingText(int leftLength, int rightLength); static native boolean deleteSurroundingText(int leftLength, int rightLength);
@ -82,18 +84,11 @@ class QtNativeInputConnection
} }
class HideKeyboardRunnable implements Runnable { class HideKeyboardRunnable implements Runnable {
private QtInputConnection m_connection; private long m_hideTimeStamp = System.nanoTime();
HideKeyboardRunnable(QtInputConnection connection)
{
m_connection = connection;
}
@Override @Override
public void run() { public void run() {
if (m_connection.getInputState() == QtInputConnection.InputStates.Hiding) { QtNative.activityDelegate().setKeyboardVisibility(false, m_hideTimeStamp);
QtNative.activityDelegate().setKeyboardVisibility(false);
m_connection.reset();
}
} }
} }
@ -107,34 +102,14 @@ public class QtInputConnection extends BaseInputConnection
private static final int ID_SWITCH_INPUT_METHOD = android.R.id.switchInputMethod; private static final int ID_SWITCH_INPUT_METHOD = android.R.id.switchInputMethod;
private static final int ID_ADD_TO_DICTIONARY = android.R.id.addToDictionary; private static final int ID_ADD_TO_DICTIONARY = android.R.id.addToDictionary;
enum InputStates { Visible, FinishComposing, Hiding };
private QtEditText m_view = null; private QtEditText m_view = null;
private InputStates m_inputState = InputStates.Visible;
public void reset()
{
m_inputState = InputStates.Visible;
}
public InputStates getInputState()
{
return m_inputState;
}
private void setClosing(boolean closing) private void setClosing(boolean closing)
{ {
if (closing && m_inputState == InputStates.Hiding) if (closing) {
return; m_view.postDelayed(new HideKeyboardRunnable(), 100);
if (closing && m_view.getActivityDelegate().isSoftwareKeyboardVisible()) {
m_view.postDelayed(new HideKeyboardRunnable(this), 100);
m_inputState = InputStates.Hiding;
} else { } else {
if (m_inputState == InputStates.Hiding) QtNative.activityDelegate().setKeyboardVisibility(true, System.nanoTime());
QtNative.activityDelegate().setKeyboardVisibility(true);
m_inputState = closing ? InputStates.FinishComposing : InputStates.Visible;
} }
} }
@ -148,14 +123,14 @@ public class QtInputConnection extends BaseInputConnection
public boolean beginBatchEdit() public boolean beginBatchEdit()
{ {
setClosing(false); setClosing(false);
return true; return QtNativeInputConnection.beginBatchEdit();
} }
@Override @Override
public boolean endBatchEdit() public boolean endBatchEdit()
{ {
// setClosing(false); setClosing(false);
return true; return QtNativeInputConnection.endBatchEdit();
} }
@Override @Override

View File

@ -4,7 +4,8 @@
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation" <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation"
android:name="org.qtproject.qt5.android.bindings.QtActivity" android:name="org.qtproject.qt5.android.bindings.QtActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:screenOrientation="unspecified"> android:screenOrientation="unspecified"
android:launchMode="singleTop">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<resources> <resources>
<array name="qt_sources"> <array name="qt_sources">
<item>https://download.qt-project.org/ministro/android/qt5/qt-5.2</item> <item>https://download.qt-project.org/ministro/android/qt5/qt-5.3</item>
</array> </array>
<!-- The following is handled automatically by the deployment tool. It should <!-- The following is handled automatically by the deployment tool. It should

View File

@ -0,0 +1,63 @@
From 6545677945d24854007d39fed86d4e44900b5c1a Mon Sep 17 00:00:00 2001
From: Andrew Knight <andrew.knight@digia.com>
Date: Thu, 27 Mar 2014 15:36:52 +0200
Subject: [PATCH] ANGLE: Don't export DLLMain functions for static builds
These ifdef guards were originally a part of
"0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch",
but were lost during the last ANGLE upgrade.
Task-number: QTBUG-37842
Change-Id: I4340c1641675dd310c14454a851eb4bc0ae2ec0d
---
src/3rdparty/angle/src/libEGL/main.cpp | 4 ++++
src/3rdparty/angle/src/libGLESv2/main.cpp | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
index e972691..4cdf5f0 100644
--- a/src/3rdparty/angle/src/libEGL/main.cpp
+++ b/src/3rdparty/angle/src/libEGL/main.cpp
@@ -69,6 +69,8 @@ void DeallocateCurrent()
}
+#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
switch (reason)
@@ -124,6 +126,8 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
return TRUE;
}
+#endif // !QT_OPENGL_ES_2_ANGLE_STATIC
+
namespace egl
{
diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
index 95f4b8d..e527994 100644
--- a/src/3rdparty/angle/src/libGLESv2/main.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/main.cpp
@@ -66,6 +66,8 @@ void DeallocateCurrent()
}
+#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
switch (reason)
@@ -107,6 +109,8 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
return TRUE;
}
+#endif // !QT_OPENGL_ES_2_ANGLE_STATIC
+
namespace gl
{
--
1.8.4.msysgit.0

View File

@ -9,6 +9,11 @@ DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
SOURCES += main.cpp SOURCES += main.cpp
win32:!winrt: LIBS += -lole32 win32:!winrt: LIBS += -lole32
winrt:equals(WINSDK_VER, 8.1) {
DEFINES += D3DCOMPILER_LINKED
LIBS += -ld3dcompiler
}
# __stdcall exports get mangled, so use a def file # __stdcall exports get mangled, so use a def file
DEF_FILE += $${TARGET}.def DEF_FILE += $${TARGET}.def

View File

@ -52,6 +52,12 @@
#include <qt_windows.h> #include <qt_windows.h>
#include <d3dcommon.h> #include <d3dcommon.h>
#ifdef D3DCOMPILER_LINKED
namespace D3D {
# include <d3dcompiler.h>
}
#endif // D3DCOMPILER_LINKED
Q_LOGGING_CATEGORY(QT_D3DCOMPILER, "qt.angle.d3dcompiler") Q_LOGGING_CATEGORY(QT_D3DCOMPILER, "qt.angle.d3dcompiler")
namespace D3DCompiler { namespace D3DCompiler {
@ -127,6 +133,7 @@ private:
static bool loadCompiler() static bool loadCompiler()
{ {
#ifndef D3DCOMPILER_LINKED
static HMODULE d3dcompiler = 0; static HMODULE d3dcompiler = 0;
if (!d3dcompiler) { if (!d3dcompiler) {
const wchar_t *dllNames[] = { const wchar_t *dllNames[] = {
@ -157,7 +164,9 @@ static bool loadCompiler()
if (!d3dcompiler) if (!d3dcompiler)
qCDebug(QT_D3DCOMPILER) << "Unable to load D3D shader compiler."; qCDebug(QT_D3DCOMPILER) << "Unable to load D3D shader compiler.";
} }
#else // !D3DCOMPILER_LINKED
compile = &D3D::D3DCompile;
#endif // D3DCOMPILER_LINKED
return bool(compile); return bool(compile);
} }
@ -190,9 +199,19 @@ HRESULT WINAPI D3DCompile(
} }
static bool initialized = false; static bool initialized = false;
static QString binaryPath; static QStringList binaryPaths;
static QString sourcePath; static QString sourcePath;
if (!initialized) { if (!initialized) {
// Precompiled directory
QString precompiledPath;
if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_BINARY_DIR"))
precompiledPath = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_BINARY_DIR"));
else
precompiledPath = QStringLiteral(":/qt.d3dcompiler"); // Default QRC path
if (QDir(precompiledPath).exists())
binaryPaths.append(precompiledPath);
// Service directory
QString base; QString base;
if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR")) if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR"))
base = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_DIR")); base = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_DIR"));
@ -203,28 +222,33 @@ HRESULT WINAPI D3DCompile(
base = location + QStringLiteral("/d3dcompiler"); base = location + QStringLiteral("/d3dcompiler");
} }
// Unless the service has run, this directory won't exist. // Create the directory structure
QDir baseDir(base); QDir baseDir(base);
if (baseDir.exists()) { if (!baseDir.exists()) {
// Check if we have can read/write blobs baseDir.cdUp();
if (baseDir.exists(QStringLiteral("binary"))) { if (!baseDir.mkdir(QStringLiteral("d3dcompiler"))) {
binaryPath = baseDir.absoluteFilePath(QStringLiteral("binary/")); qCWarning(QT_D3DCOMPILER) << "Unable to create shader base directory:"
} else { << QDir::toNativeSeparators(baseDir.absolutePath());
qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory exists, but the binary directory does not.\n" if (binaryPaths.isEmpty()) // No possibility to get a shader, abort
"Check the compiler service."; return E_FAIL;
}
baseDir.cd(QStringLiteral("d3dcompiler"));
} }
// Check if we can write shader source if (!baseDir.exists(QStringLiteral("binary")) && !baseDir.mkdir(QStringLiteral("binary"))) {
if (baseDir.exists(QStringLiteral("source"))) { qCWarning(QT_D3DCOMPILER) << "Unable to create shader binary directory:"
sourcePath = baseDir.absoluteFilePath(QStringLiteral("source/")); << QDir::toNativeSeparators(baseDir.absoluteFilePath(QStringLiteral("binary")));
if (binaryPaths.isEmpty()) // No possibility to get a shader, abort
return E_FAIL;
} else { } else {
qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory exists, but the source directory does not.\n" binaryPaths.append(baseDir.absoluteFilePath(QStringLiteral("binary/")));
"Check the compiler service.";
} }
if (!baseDir.exists(QStringLiteral("source")) && !baseDir.mkdir(QStringLiteral("source"))) {
qCWarning(QT_D3DCOMPILER) << "Unable to create shader source directory:"
<< QDir::toNativeSeparators(baseDir.absoluteFilePath(QStringLiteral("source")));
} else { } else {
qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory does not exist:" sourcePath = baseDir.absoluteFilePath(QStringLiteral("source/"));
<< QDir::toNativeSeparators(base)
<< "\nCheck that the compiler service is running.";
} }
initialized = true; initialized = true;
@ -245,8 +269,8 @@ HRESULT WINAPI D3DCompile(
+ QLatin1Char('!') + QString::number(sflags); + QLatin1Char('!') + QString::number(sflags);
// Check if pre-compiled shader blob is available // Check if pre-compiled shader blob is available
if (!binaryPath.isEmpty()) { foreach (const QString &path, binaryPaths) {
QString blobName = binaryPath + fileName; QString blobName = path + fileName;
QFile blob(blobName); QFile blob(blobName);
while (!blob.exists()) { while (!blob.exists()) {
// Progressively drop optional parts // Progressively drop optional parts
@ -262,6 +286,7 @@ HRESULT WINAPI D3DCompile(
return S_FALSE; return S_FALSE;
} }
qCDebug(QT_D3DCOMPILER) << "Found, but unable to open, precompiled shader blob at" << blob.fileName(); qCDebug(QT_D3DCOMPILER) << "Found, but unable to open, precompiled shader blob at" << blob.fileName();
break;
} }
} }
@ -284,7 +309,7 @@ HRESULT WINAPI D3DCompile(
QElapsedTimer timer; QElapsedTimer timer;
timer.start(); timer.start();
QFile blob(binaryPath + fileName); QFile blob(binaryPaths.last() + fileName);
while (!(blob.exists() && blob.open(QFile::ReadOnly)) && timer.elapsed() < timeout) while (!(blob.exists() && blob.open(QFile::ReadOnly)) && timer.elapsed() < timeout)
QThread::msleep(100); QThread::msleep(100);

View File

@ -37,6 +37,7 @@ exampledirs += \
snippets \ snippets \
../../../examples/threads/ \ ../../../examples/threads/ \
../../../examples/tools/ \ ../../../examples/tools/ \
../../../examples/ipc/ \
../../../examples/json/ \ ../../../examples/json/ \
../../../examples/network/dnslookup ../../../examples/network/dnslookup

View File

@ -55,7 +55,7 @@
#include <qfileinfo.h> #include <qfileinfo.h>
#include <qvarlengtharray.h> #include <qvarlengtharray.h>
//#define FSEVENT_DEBUG #undef FSEVENT_DEBUG
#ifdef FSEVENT_DEBUG #ifdef FSEVENT_DEBUG
# define DEBUG if (true) qDebug # define DEBUG if (true) qDebug
#else #else
@ -76,14 +76,16 @@ static void callBackFunction(ConstFSEventStreamRef streamRef,
engine->processEvent(streamRef, numEvents, paths, eventFlags, eventIds); engine->processEvent(streamRef, numEvents, paths, eventFlags, eventIds);
} }
void QFseventsFileSystemWatcherEngine::checkDir(DirsByName::iterator &it) bool QFseventsFileSystemWatcherEngine::checkDir(DirsByName::iterator &it)
{ {
bool needsRestart = false;
QT_STATBUF st; QT_STATBUF st;
const QString &name = it.key(); const QString &name = it.key();
Info &info = it->dirInfo; Info &info = it->dirInfo;
const int res = QT_STAT(QFile::encodeName(name), &st); const int res = QT_STAT(QFile::encodeName(name), &st);
if (res == -1) { if (res == -1) {
derefPath(info.watchedPath); needsRestart |= derefPath(info.watchedPath);
emit emitDirectoryChanged(info.origPath, true); emit emitDirectoryChanged(info.origPath, true);
it = watchedDirectories.erase(it); it = watchedDirectories.erase(it);
} else if (st.st_ctimespec != info.ctime || st.st_mode != info.mode) { } else if (st.st_ctimespec != info.ctime || st.st_mode != info.mode) {
@ -127,26 +129,34 @@ void QFseventsFileSystemWatcherEngine::checkDir(DirsByName::iterator &it)
if (dirChanged) if (dirChanged)
emit emitDirectoryChanged(info.origPath, false); emit emitDirectoryChanged(info.origPath, false);
} }
return needsRestart;
} }
void QFseventsFileSystemWatcherEngine::rescanDirs(const QString &path) bool QFseventsFileSystemWatcherEngine::rescanDirs(const QString &path)
{ {
bool needsRestart = false;
for (DirsByName::iterator it = watchedDirectories.begin(); it != watchedDirectories.end(); ) { for (DirsByName::iterator it = watchedDirectories.begin(); it != watchedDirectories.end(); ) {
if (it.key().startsWith(path)) if (it.key().startsWith(path))
checkDir(it); needsRestart |= checkDir(it);
else else
++it; ++it;
} }
return needsRestart;
} }
void QFseventsFileSystemWatcherEngine::rescanFiles(InfoByName &filesInPath) bool QFseventsFileSystemWatcherEngine::rescanFiles(InfoByName &filesInPath)
{ {
bool needsRestart = false;
for (InfoByName::iterator it = filesInPath.begin(); it != filesInPath.end(); ) { for (InfoByName::iterator it = filesInPath.begin(); it != filesInPath.end(); ) {
QT_STATBUF st; QT_STATBUF st;
QString name = it.key(); QString name = it.key();
const int res = QT_STAT(QFile::encodeName(name), &st); const int res = QT_STAT(QFile::encodeName(name), &st);
if (res == -1) { if (res == -1) {
derefPath(it->watchedPath); needsRestart |= derefPath(it->watchedPath);
emit emitFileChanged(it.value().origPath, true); emit emitFileChanged(it.value().origPath, true);
it = filesInPath.erase(it); it = filesInPath.erase(it);
continue; continue;
@ -158,13 +168,17 @@ void QFseventsFileSystemWatcherEngine::rescanFiles(InfoByName &filesInPath)
++it; ++it;
} }
return needsRestart;
} }
void QFseventsFileSystemWatcherEngine::rescanFiles(const QString &path) bool QFseventsFileSystemWatcherEngine::rescanFiles(const QString &path)
{ {
bool needsRestart = false;
for (FilesByPath::iterator i = watchedFiles.begin(); i != watchedFiles.end(); ) { for (FilesByPath::iterator i = watchedFiles.begin(); i != watchedFiles.end(); ) {
if (i.key().startsWith(path)) { if (i.key().startsWith(path)) {
rescanFiles(i.value()); needsRestart |= rescanFiles(i.value());
if (i.value().isEmpty()) { if (i.value().isEmpty()) {
i = watchedFiles.erase(i); i = watchedFiles.erase(i);
continue; continue;
@ -173,6 +187,8 @@ void QFseventsFileSystemWatcherEngine::rescanFiles(const QString &path)
++i; ++i;
} }
return needsRestart;
} }
void QFseventsFileSystemWatcherEngine::processEvent(ConstFSEventStreamRef streamRef, void QFseventsFileSystemWatcherEngine::processEvent(ConstFSEventStreamRef streamRef,
@ -184,11 +200,20 @@ void QFseventsFileSystemWatcherEngine::processEvent(ConstFSEventStreamRef stream
#if defined(Q_OS_OSX) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_6 #if defined(Q_OS_OSX) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_6
Q_UNUSED(streamRef); Q_UNUSED(streamRef);
bool needsRestart = false;
QMutexLocker locker(&lock); QMutexLocker locker(&lock);
for (size_t i = 0; i < numEvents; ++i) { for (size_t i = 0; i < numEvents; ++i) {
FSEventStreamEventFlags eFlags = eventFlags[i]; FSEventStreamEventFlags eFlags = eventFlags[i];
DEBUG("Change %llu in %s, flags %x", eventIds[i], eventPaths[i], (unsigned int)eFlags); DEBUG("Change %llu in %s, flags %x", eventIds[i], eventPaths[i], (unsigned int)eFlags);
if (eFlags & kFSEventStreamEventFlagEventIdsWrapped) {
DEBUG("\tthe event ids wrapped");
lastReceivedEvent = 0;
}
lastReceivedEvent = qMax(lastReceivedEvent, eventIds[i]);
QString path = QFile::decodeName(eventPaths[i]); QString path = QFile::decodeName(eventPaths[i]);
if (path.endsWith(QDir::separator())) if (path.endsWith(QDir::separator()))
path = path.mid(0, path.size() - 1); path = path.mid(0, path.size() - 1);
@ -199,38 +224,36 @@ void QFseventsFileSystemWatcherEngine::processEvent(ConstFSEventStreamRef stream
DEBUG("\t\t... user dropped."); DEBUG("\t\t... user dropped.");
if (eFlags & kFSEventStreamEventFlagKernelDropped) if (eFlags & kFSEventStreamEventFlagKernelDropped)
DEBUG("\t\t... kernel dropped."); DEBUG("\t\t... kernel dropped.");
rescanDirs(path); needsRestart |= rescanDirs(path);
rescanFiles(path); needsRestart |= rescanFiles(path);
continue; continue;
} }
if (eFlags & kFSEventStreamEventFlagEventIdsWrapped) {
DEBUG("\tthe event ids wrapped");
// TODO: verify if we need to do something
}
if (eFlags & kFSEventStreamEventFlagRootChanged) { if (eFlags & kFSEventStreamEventFlagRootChanged) {
// re-check everything: // re-check everything:
DirsByName::iterator dirIt = watchedDirectories.find(path); DirsByName::iterator dirIt = watchedDirectories.find(path);
if (dirIt != watchedDirectories.end()) if (dirIt != watchedDirectories.end())
checkDir(dirIt); needsRestart |= checkDir(dirIt);
rescanFiles(path); needsRestart |= rescanFiles(path);
continue; continue;
} }
if ((eFlags & kFSEventStreamEventFlagItemIsDir) && (eFlags & kFSEventStreamEventFlagItemRemoved)) if ((eFlags & kFSEventStreamEventFlagItemIsDir) && (eFlags & kFSEventStreamEventFlagItemRemoved))
rescanDirs(path); needsRestart |= rescanDirs(path);
// check watched directories: // check watched directories:
DirsByName::iterator dirIt = watchedDirectories.find(path); DirsByName::iterator dirIt = watchedDirectories.find(path);
if (dirIt != watchedDirectories.end()) if (dirIt != watchedDirectories.end())
checkDir(dirIt); needsRestart |= checkDir(dirIt);
// check watched files: // check watched files:
FilesByPath::iterator pIt = watchedFiles.find(path); FilesByPath::iterator pIt = watchedFiles.find(path);
if (pIt != watchedFiles.end()) if (pIt != watchedFiles.end())
rescanFiles(pIt.value()); needsRestart |= rescanFiles(pIt.value());
} }
if (needsRestart)
emit scheduleStreamRestart();
#else #else
// This is a work-around for moc: when we put the version check at the top of the header file, // This is a work-around for moc: when we put the version check at the top of the header file,
// moc will still see the Q_OBJECT macro and generate a meta-object when compiling for 10.6, // moc will still see the Q_OBJECT macro and generate a meta-object when compiling for 10.6,
@ -248,14 +271,23 @@ void QFseventsFileSystemWatcherEngine::processEvent(ConstFSEventStreamRef stream
void QFseventsFileSystemWatcherEngine::doEmitFileChanged(const QString path, bool removed) void QFseventsFileSystemWatcherEngine::doEmitFileChanged(const QString path, bool removed)
{ {
DEBUG() << "emitting fileChanged for" << path << "with removed =" << removed;
emit fileChanged(path, removed); emit fileChanged(path, removed);
} }
void QFseventsFileSystemWatcherEngine::doEmitDirectoryChanged(const QString path, bool removed) void QFseventsFileSystemWatcherEngine::doEmitDirectoryChanged(const QString path, bool removed)
{ {
DEBUG() << "emitting directoryChanged for" << path << "with removed =" << removed;
emit directoryChanged(path, removed); emit directoryChanged(path, removed);
} }
void QFseventsFileSystemWatcherEngine::restartStream()
{
QMutexLocker locker(&lock);
stopStream();
startStream();
}
QFseventsFileSystemWatcherEngine *QFseventsFileSystemWatcherEngine::create(QObject *parent) QFseventsFileSystemWatcherEngine *QFseventsFileSystemWatcherEngine::create(QObject *parent)
{ {
return new QFseventsFileSystemWatcherEngine(parent); return new QFseventsFileSystemWatcherEngine(parent);
@ -264,6 +296,7 @@ QFseventsFileSystemWatcherEngine *QFseventsFileSystemWatcherEngine::create(QObje
QFseventsFileSystemWatcherEngine::QFseventsFileSystemWatcherEngine(QObject *parent) QFseventsFileSystemWatcherEngine::QFseventsFileSystemWatcherEngine(QObject *parent)
: QFileSystemWatcherEngine(parent) : QFileSystemWatcherEngine(parent)
, stream(0) , stream(0)
, lastReceivedEvent(kFSEventStreamEventIdSinceNow)
{ {
// We cannot use signal-to-signal queued connections, because the // We cannot use signal-to-signal queued connections, because the
@ -272,6 +305,8 @@ QFseventsFileSystemWatcherEngine::QFseventsFileSystemWatcherEngine(QObject *pare
this, SLOT(doEmitDirectoryChanged(const QString, bool)), Qt::QueuedConnection); this, SLOT(doEmitDirectoryChanged(const QString, bool)), Qt::QueuedConnection);
connect(this, SIGNAL(emitFileChanged(const QString, bool)), connect(this, SIGNAL(emitFileChanged(const QString, bool)),
this, SLOT(doEmitFileChanged(const QString, bool)), Qt::QueuedConnection); this, SLOT(doEmitFileChanged(const QString, bool)), Qt::QueuedConnection);
connect(this, SIGNAL(scheduleStreamRestart()),
this, SLOT(restartStream()), Qt::QueuedConnection);
queue = dispatch_queue_create("org.qt-project.QFseventsFileSystemWatcherEngine", NULL); queue = dispatch_queue_create("org.qt-project.QFseventsFileSystemWatcherEngine", NULL);
} }
@ -284,7 +319,7 @@ QFseventsFileSystemWatcherEngine::~QFseventsFileSystemWatcherEngine()
// The assumption with the locking strategy is that this class cannot and will not be subclassed! // The assumption with the locking strategy is that this class cannot and will not be subclassed!
QMutexLocker locker(&lock); QMutexLocker locker(&lock);
stopStream(); stopStream(true);
dispatch_release(queue); dispatch_release(queue);
} }
@ -292,12 +327,14 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
QStringList *files, QStringList *files,
QStringList *directories) QStringList *directories)
{ {
if (stream) if (stream) {
DEBUG("Flushing, last id is %llu", FSEventStreamGetLatestEventId(stream));
FSEventStreamFlushSync(stream); FSEventStreamFlushSync(stream);
}
QMutexLocker locker(&lock); QMutexLocker locker(&lock);
bool newWatchPathsFound = false; bool needsRestart = false;
QStringList p = paths; QStringList p = paths;
QMutableListIterator<QString> it(p); QMutableListIterator<QString> it(p);
@ -343,8 +380,9 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
PathRefCounts::iterator it = watchedPaths.find(watchedPath); PathRefCounts::iterator it = watchedPaths.find(watchedPath);
if (it == watchedPaths.end()) { if (it == watchedPaths.end()) {
newWatchPathsFound = true; needsRestart = true;
watchedPaths.insert(watchedPath, 1); watchedPaths.insert(watchedPath, 1);
DEBUG("Adding '%s' to watchedPaths", qPrintable(watchedPath));
} else { } else {
++it.value(); ++it.value();
} }
@ -355,12 +393,14 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
dirInfo.dirInfo = info; dirInfo.dirInfo = info;
dirInfo.entries = scanForDirEntries(realPath); dirInfo.entries = scanForDirEntries(realPath);
watchedDirectories.insert(realPath, dirInfo); watchedDirectories.insert(realPath, dirInfo);
DEBUG("-- Also adding '%s' to watchedDirectories", qPrintable(realPath));
} else { } else {
watchedFiles[parentPath].insert(realPath, info); watchedFiles[parentPath].insert(realPath, info);
DEBUG("-- Also adding '%s' to watchedFiles", qPrintable(realPath));
} }
} }
if (newWatchPathsFound) { if (needsRestart) {
stopStream(); stopStream();
if (!startStream()) if (!startStream())
p = paths; p = paths;
@ -375,6 +415,8 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat
{ {
QMutexLocker locker(&lock); QMutexLocker locker(&lock);
bool needsRestart = false;
QStringList p = paths; QStringList p = paths;
QMutableListIterator<QString> it(p); QMutableListIterator<QString> it(p);
while (it.hasNext()) { while (it.hasNext()) {
@ -389,10 +431,11 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat
if (fi.isDir()) { if (fi.isDir()) {
DirsByName::iterator dirIt = watchedDirectories.find(realPath); DirsByName::iterator dirIt = watchedDirectories.find(realPath);
if (dirIt != watchedDirectories.end()) { if (dirIt != watchedDirectories.end()) {
derefPath(dirIt->dirInfo.watchedPath); needsRestart |= derefPath(dirIt->dirInfo.watchedPath);
watchedDirectories.erase(dirIt); watchedDirectories.erase(dirIt);
directories->removeAll(origPath); directories->removeAll(origPath);
it.remove(); it.remove();
DEBUG("Removed directory '%s'", qPrintable(realPath));
} }
} else { } else {
QFileInfo fi(realPath); QFileInfo fi(realPath);
@ -402,22 +445,32 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat
InfoByName &filesInDir = pIt.value(); InfoByName &filesInDir = pIt.value();
InfoByName::iterator fIt = filesInDir.find(realPath); InfoByName::iterator fIt = filesInDir.find(realPath);
if (fIt != filesInDir.end()) { if (fIt != filesInDir.end()) {
derefPath(fIt->watchedPath); needsRestart |= derefPath(fIt->watchedPath);
filesInDir.erase(fIt); filesInDir.erase(fIt);
if (filesInDir.isEmpty()) if (filesInDir.isEmpty())
watchedFiles.erase(pIt); watchedFiles.erase(pIt);
files->removeAll(origPath); files->removeAll(origPath);
it.remove(); it.remove();
DEBUG("Removed file '%s'", qPrintable(realPath));
} }
} }
} }
} }
locker.unlock();
if (needsRestart)
restartStream();
return p; return p;
} }
bool QFseventsFileSystemWatcherEngine::startStream() bool QFseventsFileSystemWatcherEngine::startStream()
{ {
Q_ASSERT(stream == 0);
if (stream) // This shouldn't happen, but let's be nice and handle it.
stopStream();
if (watchedPaths.isEmpty()) if (watchedPaths.isEmpty())
return false; return false;
@ -437,11 +490,15 @@ bool QFseventsFileSystemWatcherEngine::startStream()
const CFAbsoluteTime latency = .5; // in seconds const CFAbsoluteTime latency = .5; // in seconds
FSEventStreamCreateFlags flags = kFSEventStreamCreateFlagWatchRoot; FSEventStreamCreateFlags flags = kFSEventStreamCreateFlagWatchRoot;
// Never start with kFSEventStreamEventIdSinceNow, because this will generate an invalid
// soft-assert in FSEventStreamFlushSync in CarbonCore when no event occurred.
if (lastReceivedEvent == kFSEventStreamEventIdSinceNow)
lastReceivedEvent = FSEventsGetCurrentEventId();
stream = FSEventStreamCreate(NULL, stream = FSEventStreamCreate(NULL,
&callBackFunction, &callBackFunction,
&callBackInfo, &callBackInfo,
reinterpret_cast<CFArrayRef>(pathsToWatch), reinterpret_cast<CFArrayRef>(pathsToWatch),
kFSEventStreamEventIdSinceNow, lastReceivedEvent,
latency, latency,
flags); flags);
@ -453,10 +510,13 @@ bool QFseventsFileSystemWatcherEngine::startStream()
FSEventStreamSetDispatchQueue(stream, queue); FSEventStreamSetDispatchQueue(stream, queue);
if (FSEventStreamStart(stream)) { if (FSEventStreamStart(stream)) {
DEBUG() << "Stream started successfully."; DEBUG() << "Stream started successfully with sinceWhen =" << lastReceivedEvent;
return true; return true;
} else { } else {
DEBUG() << "Stream failed to start!"; DEBUG() << "Stream failed to start!";
FSEventStreamInvalidate(stream);
FSEventStreamRelease(stream);
stream = 0;
return false; return false;
} }
} }
@ -469,7 +529,7 @@ void QFseventsFileSystemWatcherEngine::stopStream(bool isStopped)
FSEventStreamInvalidate(stream); FSEventStreamInvalidate(stream);
FSEventStreamRelease(stream); FSEventStreamRelease(stream);
stream = 0; stream = 0;
DEBUG() << "Stream stopped."; DEBUG() << "Stream stopped. Last event ID:" << lastReceivedEvent;
} }
} }
@ -490,16 +550,16 @@ QFseventsFileSystemWatcherEngine::InfoByName QFseventsFileSystemWatcherEngine::s
return entries; return entries;
} }
void QFseventsFileSystemWatcherEngine::derefPath(const QString &watchedPath) bool QFseventsFileSystemWatcherEngine::derefPath(const QString &watchedPath)
{ {
PathRefCounts::iterator it = watchedPaths.find(watchedPath); PathRefCounts::iterator it = watchedPaths.find(watchedPath);
if (it == watchedPaths.end()) if (it != watchedPaths.end() && --it.value() < 1) {
return;
if (--it.value() < 1) {
watchedPaths.erase(it); watchedPaths.erase(it);
stopStream(); DEBUG("Removing '%s' from watchedPaths.", qPrintable(watchedPath));
startStream(); return true;
} }
return false;
} }
#endif //QT_NO_FILESYSTEMWATCHER #endif //QT_NO_FILESYSTEMWATCHER

View File

@ -84,10 +84,12 @@ public:
Q_SIGNALS: Q_SIGNALS:
void emitFileChanged(const QString path, bool removed); void emitFileChanged(const QString path, bool removed);
void emitDirectoryChanged(const QString path, bool removed); void emitDirectoryChanged(const QString path, bool removed);
void scheduleStreamRestart();
private slots: private slots:
void doEmitFileChanged(const QString path, bool removed); void doEmitFileChanged(const QString path, bool removed);
void doEmitDirectoryChanged(const QString path, bool removed); void doEmitDirectoryChanged(const QString path, bool removed);
void restartStream();
private: private:
struct Info { struct Info {
@ -122,11 +124,11 @@ private:
bool startStream(); bool startStream();
void stopStream(bool isStopped = false); void stopStream(bool isStopped = false);
InfoByName scanForDirEntries(const QString &path); InfoByName scanForDirEntries(const QString &path);
void derefPath(const QString &watchedPath); bool derefPath(const QString &watchedPath);
void checkDir(DirsByName::iterator &it); bool checkDir(DirsByName::iterator &it);
void rescanDirs(const QString &path); bool rescanDirs(const QString &path);
void rescanFiles(InfoByName &filesInPath); bool rescanFiles(InfoByName &filesInPath);
void rescanFiles(const QString &path); bool rescanFiles(const QString &path);
QMutex lock; QMutex lock;
dispatch_queue_t queue; dispatch_queue_t queue;
@ -134,6 +136,7 @@ private:
FilesByPath watchedFiles; FilesByPath watchedFiles;
DirsByName watchedDirectories; DirsByName watchedDirectories;
PathRefCounts watchedPaths; PathRefCounts watchedPaths;
FSEventStreamEventId lastReceivedEvent;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -2496,6 +2496,12 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
\snippet code/src_corelib_io_qsettings.cpp 7 \snippet code/src_corelib_io_qsettings.cpp 7
\li On Mac OS X, permissions to access settings not belonging to the
current user (i.e. SystemScope) have changed with 10.7 (Lion). Prior to
that version, users having admin rights could access these. For 10.7 and
10.8 (Mountain Lion), only root can. However, 10.9 (Mavericks) changes
that rule again but only for the native format (plist files).
\li On Unix and Mac OS X systems, the advisory file locking is disabled \li On Unix and Mac OS X systems, the advisory file locking is disabled
if NFS (or AutoFS or CacheFS) is detected to work around a bug in the if NFS (or AutoFS or CacheFS) is detected to work around a bug in the
NFS fcntl() implementation, which hangs forever if statd or lockd aren't NFS fcntl() implementation, which hangs forever if statd or lockd aren't

View File

@ -405,7 +405,6 @@ QMacSettingsPrivate::QMacSettingsPrivate(QSettings::Scope scope, const QString &
} }
// if no bundle identifier yet. use a hard coded string. // if no bundle identifier yet. use a hard coded string.
if (domainName.isEmpty()) { if (domainName.isEmpty()) {
setStatus(QSettings::AccessError);
domainName = QLatin1String("unknown-organization.trolltech.com"); domainName = QLatin1String("unknown-organization.trolltech.com");
} }
@ -540,6 +539,7 @@ void QMacSettingsPrivate::sync()
// only report failures for the primary file (the one we write to) // only report failures for the primary file (the one we write to)
if (!ok && i == 0 && hostNames[j] == hostName && status == QSettings::NoError) { if (!ok && i == 0 && hostNames[j] == hostName && status == QSettings::NoError) {
#if 1 #if 1
if (QSysInfo::macVersion() < QSysInfo::MV_10_7) {
// work around what seems to be a bug in CFPreferences: // work around what seems to be a bug in CFPreferences:
// don't report an error if there are no preferences for the application // don't report an error if there are no preferences for the application
QCFType<CFArrayRef> appIds = CFPreferencesCopyApplicationList(domains[i].userName, QCFType<CFArrayRef> appIds = CFPreferencesCopyApplicationList(domains[i].userName,
@ -558,9 +558,11 @@ void QMacSettingsPrivate::sync()
} }
} }
} }
#else } else
setStatus(QSettings::AccessError);
#endif #endif
{
setStatus(QSettings::AccessError);
}
} }
} }
} }

View File

@ -49,6 +49,10 @@
#include <qcoreapplication.h> #include <qcoreapplication.h>
#endif #endif
#if !defined(Q_OS_WINCE)
const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } };
#endif
#include <qt_windows.h> #include <qt_windows.h>
#include <shlobj.h> #include <shlobj.h>
#if !defined(Q_OS_WINCE) #if !defined(Q_OS_WINCE)
@ -68,6 +72,10 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#if !defined(Q_OS_WINCE)
typedef HRESULT (WINAPI *GetKnownFolderPath)(const GUID&, DWORD, HANDLE, LPWSTR*);
#endif
static QString convertCharArray(const wchar_t *path) static QString convertCharArray(const wchar_t *path)
{ {
return QDir::fromNativeSeparators(QString::fromWCharArray(path)); return QDir::fromNativeSeparators(QString::fromWCharArray(path));
@ -77,6 +85,10 @@ QString QStandardPaths::writableLocation(StandardLocation type)
{ {
QString result; QString result;
#if !defined(Q_OS_WINCE)
static GetKnownFolderPath SHGetKnownFolderPath = (GetKnownFolderPath)QSystemLibrary::resolve(QLatin1String("shell32"), "SHGetKnownFolderPath");
#endif
wchar_t path[MAX_PATH]; wchar_t path[MAX_PATH];
switch (type) { switch (type) {
@ -107,7 +119,18 @@ QString QStandardPaths::writableLocation(StandardLocation type)
result = convertCharArray(path); result = convertCharArray(path);
break; break;
case DownloadLocation: // TODO implement with SHGetKnownFolderPath(FOLDERID_Downloads) (starting from Vista) 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: case DocumentsLocation:
if (SHGetSpecialFolderPath(0, path, CSIDL_PERSONAL, FALSE)) if (SHGetSpecialFolderPath(0, path, CSIDL_PERSONAL, FALSE))
result = convertCharArray(path); result = convertCharArray(path);

View File

@ -407,6 +407,9 @@ Q_GLOBAL_STATIC(QEventUserEventRegistration, userEventRegistrationHelper)
between QEvent::User and QEvent::MaxUser that has not yet been between QEvent::User and QEvent::MaxUser that has not yet been
registered. The \a hint is ignored if its value is not between registered. The \a hint is ignored if its value is not between
QEvent::User and QEvent::MaxUser. QEvent::User and QEvent::MaxUser.
Returns -1 if all available values are already taken or the
program is shutting down.
*/ */
int QEvent::registerEventType(int hint) int QEvent::registerEventType(int hint)
{ {

View File

@ -45,6 +45,7 @@
#include <QtCore/QThread> #include <QtCore/QThread>
#include <QtCore/QHash> #include <QtCore/QHash>
#include <private/qabstracteventdispatcher_p.h> #include <private/qabstracteventdispatcher_p.h>
#include <private/qcoreapplication_p.h>
#include <wrl.h> #include <wrl.h>
#include <windows.foundation.h> #include <windows.foundation.h>
@ -109,6 +110,11 @@ QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent)
: QAbstractEventDispatcher(*new QEventDispatcherWinRTPrivate, parent) : QAbstractEventDispatcher(*new QEventDispatcherWinRTPrivate, parent)
{ {
Q_D(QEventDispatcherWinRT); Q_D(QEventDispatcherWinRT);
// Only look up the event dispatcher in the main thread
if (QThread::currentThread() != QCoreApplicationPrivate::theMainThread)
return;
ComPtr<ICoreApplication> application; ComPtr<ICoreApplication> application;
HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
IID_PPV_ARGS(&application)); IID_PPV_ARGS(&application));

View File

@ -938,10 +938,6 @@ public:
return IteratorOwner<typename T::const_iterator>::getData(i); return IteratorOwner<typename T::const_iterator>::getData(i);
} }
template<class T>
static void advanceImpl(void **p, int step)
{ IteratorOwner<typename T::const_iterator>::advance(p, step); }
template<class T> template<class T>
static void moveToBeginImpl(const void *container, void **iterator) static void moveToBeginImpl(const void *container, void **iterator)
{ IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->begin()); } { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->begin()); }
@ -950,22 +946,10 @@ public:
static void moveToEndImpl(const void *container, void **iterator) static void moveToEndImpl(const void *container, void **iterator)
{ IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); } { IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); }
template<class T>
static void destroyIterImpl(void **iterator)
{ IteratorOwner<typename T::const_iterator>::destroy(iterator); }
template<class T>
static bool equalIterImpl(void * const *iterator, void * const *other)
{ return IteratorOwner<typename T::const_iterator>::equal(iterator, other); }
template<class T> template<class T>
static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags) static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags)
{ return VariantData(metaTypeId, IteratorOwner<typename T::const_iterator>::getData(iterator), flags); } { return VariantData(metaTypeId, IteratorOwner<typename T::const_iterator>::getData(iterator), flags); }
template<class T>
static void copyIterImpl(void **dest, void * const * src)
{ IteratorOwner<typename T::const_iterator>::assign(dest, src); }
public: public:
template<class T> QSequentialIterableImpl(const T*p) template<class T> QSequentialIterableImpl(const T*p)
: _iterable(p) : _iterable(p)
@ -977,11 +961,11 @@ public:
, _at(atImpl<T>) , _at(atImpl<T>)
, _moveToBegin(moveToBeginImpl<T>) , _moveToBegin(moveToBeginImpl<T>)
, _moveToEnd(moveToEndImpl<T>) , _moveToEnd(moveToEndImpl<T>)
, _advance(advanceImpl<T>) , _advance(IteratorOwner<typename T::const_iterator>::advance)
, _get(getImpl<T>) , _get(getImpl<T>)
, _destroyIter(destroyIterImpl<T>) , _destroyIter(IteratorOwner<typename T::const_iterator>::destroy)
, _equalIter(equalIterImpl<T>) , _equalIter(IteratorOwner<typename T::const_iterator>::equal)
, _copyIter(copyIterImpl<T>) , _copyIter(IteratorOwner<typename T::const_iterator>::assign)
{ {
} }
@ -1134,18 +1118,6 @@ public:
static VariantData getValueImpl(void * const *iterator, int metaTypeId, uint flags) static VariantData getValueImpl(void * const *iterator, int metaTypeId, uint flags)
{ return VariantData(metaTypeId, &AssociativeContainerAccessor<T>::getValue(*static_cast<typename T::const_iterator*>(*iterator)), flags); } { return VariantData(metaTypeId, &AssociativeContainerAccessor<T>::getValue(*static_cast<typename T::const_iterator*>(*iterator)), flags); }
template<class T>
static void destroyIterImpl(void **iterator)
{ IteratorOwner<typename T::const_iterator>::destroy(iterator); }
template<class T>
static bool equalIterImpl(void * const *iterator, void * const *other)
{ return IteratorOwner<typename T::const_iterator>::equal(iterator, other); }
template<class T>
static void copyIterImpl(void **dest, void * const * src)
{ IteratorOwner<typename T::const_iterator>::assign(dest, src); }
public: public:
template<class T> QAssociativeIterableImpl(const T*p) template<class T> QAssociativeIterableImpl(const T*p)
: _iterable(p) : _iterable(p)
@ -1160,9 +1132,9 @@ public:
, _advance(advanceImpl<T>) , _advance(advanceImpl<T>)
, _getKey(getKeyImpl<T>) , _getKey(getKeyImpl<T>)
, _getValue(getValueImpl<T>) , _getValue(getValueImpl<T>)
, _destroyIter(destroyIterImpl<T>) , _destroyIter(IteratorOwner<typename T::const_iterator>::destroy)
, _equalIter(equalIterImpl<T>) , _equalIter(IteratorOwner<typename T::const_iterator>::equal)
, _copyIter(copyIterImpl<T>) , _copyIter(IteratorOwner<typename T::const_iterator>::assign)
{ {
} }

View File

@ -299,7 +299,7 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty
QMacPasteboardMime maps MIME to Mac flavors. QMacPasteboardMime maps MIME to Mac flavors.
\sa QClipboard, QDragEnterEvent, QDragMoveEvent, QDropEvent, QDrag, \sa QClipboard, QDragEnterEvent, QDragMoveEvent, QDropEvent, QDrag,
QWindowsMime, QMacPasteboardMime, {Drag and Drop} QMacPasteboardMime, {Drag and Drop}
*/ */
/*! /*!

View File

@ -551,7 +551,7 @@ void QMetaCallEvent::placeMetaCall(QObject *object)
QObject::signalsBlocked() state is transferred to this object. QObject::signalsBlocked() state is transferred to this object.
The object's signals this signal blocker was blocking prior to The object's signals this signal blocker was blocking prior to
being moved to, if any, are unblocked \em except in the case where being moved to, if any, are unblocked \e except in the case where
both instances block the same object's signals and \c *this is both instances block the same object's signals and \c *this is
unblocked while \a other is not, at the time of the move. unblocked while \a other is not, at the time of the move.
*/ */
@ -2731,9 +2731,7 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
Qt::ConnectionType type) Qt::ConnectionType type)
but it uses QMetaMethod to specify signal and method. but it uses QMetaMethod to specify signal and method.
\sa connect(const QObject *sender, const char *signal, \sa connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
const QObject *receiver, const char *method,
Qt::ConnectionType type)
*/ */
QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMethod &signal, QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMethod &signal,
const QObject *receiver, const QMetaMethod &method, const QObject *receiver, const QMetaMethod &method,

View File

@ -333,6 +333,26 @@ QT_BEGIN_NAMESPACE
\since 5.1 \since 5.1
*/ */
/*!
\fn QMargins &QMargins::operator+=(int addend)
\overload
Adds the \a addend to each component of this object
and returns a reference to it.
\sa operator-=()
*/
/*!
\fn QMargins &QMargins::operator-=(int subtrahend)
\overload
Subtracts the \a subtrahend from each component of this object
and returns a reference to it.
\sa operator+=()
*/
/*! /*!
\fn QMargins &QMargins::operator*=(int factor) \fn QMargins &QMargins::operator*=(int factor)

View File

@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE
\class QPoint \class QPoint
\inmodule QtCore \inmodule QtCore
\ingroup painting \ingroup painting
\reentrant
\brief The QPoint class defines a point in the plane using integer \brief The QPoint class defines a point in the plane using integer
precision. precision.
@ -470,6 +471,7 @@ QDebug operator<<(QDebug dbg, const QPointF &p)
\class QPointF \class QPointF
\inmodule QtCore \inmodule QtCore
\ingroup painting \ingroup painting
\reentrant
\brief The QPointF class defines a point in the plane using \brief The QPointF class defines a point in the plane using
floating point precision. floating point precision.

View File

@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE
\class QRect \class QRect
\inmodule QtCore \inmodule QtCore
\ingroup painting \ingroup painting
\reentrant
\brief The QRect class defines a rectangle in the plane using \brief The QRect class defines a rectangle in the plane using
integer precision. integer precision.
@ -1298,6 +1299,7 @@ QDebug operator<<(QDebug dbg, const QRect &r)
\class QRectF \class QRectF
\inmodule QtCore \inmodule QtCore
\ingroup painting \ingroup painting
\reentrant
\brief The QRectF class defines a rectangle in the plane using floating \brief The QRectF class defines a rectangle in the plane using floating
point precision. point precision.

View File

@ -79,7 +79,7 @@
// SSE intrinsics // SSE intrinsics
#if defined(__SSE2__) || (defined(QT_COMPILER_SUPPORTS_SSE2) && defined(Q_CC_MSVC)) #if defined(__SSE2__) || (defined(QT_COMPILER_SUPPORTS_SSE2) && defined(Q_CC_MSVC))
#if defined(QT_LINUXBASE) #if defined(QT_LINUXBASE) || defined(Q_OS_ANDROID_NO_SDK)
/// this is an evil hack - the posix_memalign declaration in LSB /// this is an evil hack - the posix_memalign declaration in LSB
/// is wrong - see http://bugs.linuxbase.org/show_bug.cgi?id=2431 /// is wrong - see http://bugs.linuxbase.org/show_bug.cgi?id=2431
# define posix_memalign _lsb_hack_posix_memalign # define posix_memalign _lsb_hack_posix_memalign

View File

@ -78,6 +78,7 @@
#include "qchar.cpp" #include "qchar.cpp"
#include "qstringmatcher.cpp" #include "qstringmatcher.cpp"
#include "qstringiterator_p.h" #include "qstringiterator_p.h"
#include "qthreadstorage.h"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
# include <qt_windows.h> # include <qt_windows.h>
@ -5319,6 +5320,10 @@ int QString::localeAwareCompare(const QString &other) const
return localeAwareCompare_helper(constData(), length(), other.constData(), other.length()); return localeAwareCompare_helper(constData(), length(), other.constData(), other.length());
} }
#if defined(QT_USE_ICU)
Q_GLOBAL_STATIC(QThreadStorage<QCollator>, defaultCollator)
#endif
/*! /*!
\internal \internal
\since 4.5 \since 4.5
@ -5362,8 +5367,9 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1,
CFRelease(otherString); CFRelease(otherString);
return result; return result;
#elif defined(QT_USE_ICU) #elif defined(QT_USE_ICU)
QCollator collator; if (!defaultCollator()->hasLocalData())
return collator.compare(data1, length1, data2, length2); defaultCollator()->setLocalData(QCollator());
return defaultCollator()->localData().compare(data1, length1, data2, length2);
#elif defined(Q_OS_UNIX) #elif defined(Q_OS_UNIX)
// declared in <string.h> // declared in <string.h>
int delta = strcoll(toLocal8Bit_helper(data1, length1).constData(), toLocal8Bit_helper(data2, length2).constData()); int delta = strcoll(toLocal8Bit_helper(data1, length1).constData(), toLocal8Bit_helper(data2, length2).constData());
@ -6168,7 +6174,7 @@ qulonglong QString::toIntegral_helper(const QChar *data, uint len, bool *ok, int
\snippet qstring/main.cpp 73 \snippet qstring/main.cpp 73
\sa number(), toULong(), toInt(), QLocale::toLong() \sa number(), toULong(), toInt(), QLocale::toInt()
*/ */
long QString::toLong(bool *ok, int base) const long QString::toLong(bool *ok, int base) const
@ -6197,7 +6203,7 @@ long QString::toLong(bool *ok, int base) const
\snippet qstring/main.cpp 78 \snippet qstring/main.cpp 78
\sa number(), QLocale::toULong() \sa number(), QLocale::toUInt()
*/ */
ulong QString::toULong(bool *ok, int base) const ulong QString::toULong(bool *ok, int base) const
@ -7562,6 +7568,8 @@ QString QString::multiArg(int numArgs, const QString **args) const
\since 5.2 \since 5.2
Constructs a new QString containing a copy of the \a string CFString. Constructs a new QString containing a copy of the \a string CFString.
\note this function is only available on Mac OS X and iOS.
*/ */
/*! \fn CFStringRef QString::toCFString() const /*! \fn CFStringRef QString::toCFString() const
@ -7569,18 +7577,24 @@ QString QString::multiArg(int numArgs, const QString **args) const
Creates a CFString from a QString. The caller owns the CFString and is Creates a CFString from a QString. The caller owns the CFString and is
responsible for releasing it. responsible for releasing it.
\note this function is only available on Mac OS X and iOS.
*/ */
/*! \fn QString QString::fromNSString(const NSString *string) /*! \fn QString QString::fromNSString(const NSString *string)
\since 5.2 \since 5.2
Constructs a new QString containing a copy of the \a string NSString. Constructs a new QString containing a copy of the \a string NSString.
\note this function is only available on Mac OS X and iOS.
*/ */
/*! \fn NSString QString::toNSString() const /*! \fn NSString QString::toNSString() const
\since 5.2 \since 5.2
Creates a NSString from a QString.g. The NSString is autoreleased. Creates a NSString from a QString. The NSString is autoreleased.
\note this function is only available on Mac OS X and iOS.
*/ */
/*! \fn bool QString::isSimpleText() const /*! \fn bool QString::isSimpleText() const

View File

@ -711,7 +711,7 @@ public:
Q_DECL_CONSTEXPR inline QString(QStringDataPtr dd) : d(dd.ptr) {} Q_DECL_CONSTEXPR inline QString(QStringDataPtr dd) : d(dd.ptr) {}
private: private:
#if defined(QT_NO_CAST_FROM_ASCII) && !defined(Q_NO_DECLARED_NOT_DEFINED) #if defined(QT_NO_CAST_FROM_ASCII)
QString &operator+=(const char *s); QString &operator+=(const char *s);
QString &operator+=(const QByteArray &s); QString &operator+=(const QByteArray &s);
QString(const char *ch); QString(const char *ch);

View File

@ -349,11 +349,11 @@ QXmlStreamEntityResolver *QXmlStreamReader::entityResolver() const
\l{QNetworkAccessManager} {network access manager}, you would issue \l{QNetworkAccessManager} {network access manager}, you would issue
a \l{QNetworkRequest} {network request} to the manager and receive a a \l{QNetworkRequest} {network request} to the manager and receive a
\l{QNetworkReply} {network reply} in return. Since a QNetworkReply \l{QNetworkReply} {network reply} in return. Since a QNetworkReply
is a QIODevice, you connect its \l{QNetworkReply::readyRead()} is a QIODevice, you connect its \l{QIODevice::readyRead()}
{readyRead()} signal to a custom slot, e.g. \c{slotReadyRead()} in {readyRead()} signal to a custom slot, e.g. \c{slotReadyRead()} in
the code snippet shown in the discussion for QNetworkAccessManager. the code snippet shown in the discussion for QNetworkAccessManager.
In this slot, you read all available data with In this slot, you read all available data with
\l{QNetworkReply::readAll()} {readAll()} and pass it to the XML \l{QIODevice::readAll()} {readAll()} and pass it to the XML
stream reader using addData(). Then you call your custom parsing stream reader using addData(). Then you call your custom parsing
function that reads the XML events from the reader. function that reads the XML events from the reader.

View File

@ -155,7 +155,7 @@ QT_BEGIN_NAMESPACE
*/ */
/*! /*!
\fn QDBusReply::error() \fn const QDBusError& QDBusReply::error() const
Returns the error code that was returned from the remote function call. If the remote call did Returns the error code that was returned from the remote function call. If the remote call did
not return an error (i.e., if it succeeded), then the QDBusError object that is returned will not return an error (i.e., if it succeeded), then the QDBusError object that is returned will
@ -164,6 +164,11 @@ QT_BEGIN_NAMESPACE
\sa isValid() \sa isValid()
*/ */
/*!
\fn const QDBusError& QDBusReply::error()
\overload
*/
/*! /*!
\fn QDBusReply::value() const \fn QDBusReply::value() const
Returns the remote function's calls return value. If the remote call returned with an error, Returns the remote function's calls return value. If the remote call returned with an error,

View File

@ -611,7 +611,7 @@ bool QImageData::checkForAlphaPixels() const
*/ */
/*! /*!
\fn QImage &operator=(QImage &&other) \fn QImage &QImage::operator=(QImage &&other)
Move-assigns \a other to this QImage instance. Move-assigns \a other to this QImage instance.

View File

@ -64,6 +64,8 @@ QNativeImage::~QNativeImage()
QImage::Format QNativeImage::systemFormat() QImage::Format QNativeImage::systemFormat()
{ {
if (!QGuiApplication::primaryScreen())
return QImage::Format_Invalid;
return QGuiApplication::primaryScreen()->handle()->format(); return QGuiApplication::primaryScreen()->handle()->format();
} }

View File

@ -101,7 +101,7 @@ QT_BEGIN_NAMESPACE
\l{QWidget::mouseMoveEvent()}{mouseMoveEvent()} to check whether a QDrag is \l{QWidget::mouseMoveEvent()}{mouseMoveEvent()} to check whether a QDrag is
required. required.
\sa {Drag and Drop}, QClipboard, QMimeData, QWindowsMime, QMacPasteboardMime, \sa {Drag and Drop}, QClipboard, QMimeData, QMacPasteboardMime,
{Draggable Icons Example}, {Draggable Text Example}, {Drop Site Example}, {Draggable Icons Example}, {Draggable Text Example}, {Drop Site Example},
{Fridge Magnets Example} {Fridge Magnets Example}
*/ */

View File

@ -628,7 +628,7 @@ QHoverEvent::~QHoverEvent()
\a modifiers holds the keyboard modifier flags at the time of the \a modifiers holds the keyboard modifier flags at the time of the
event, and \a orient holds the wheel's orientation. event, and \a orient holds the wheel's orientation.
\sa pos(), pixelDelta(), angleDelta(), state() \sa pos(), pixelDelta(), angleDelta()
*/ */
#ifndef QT_NO_WHEELEVENT #ifndef QT_NO_WHEELEVENT
QWheelEvent::QWheelEvent(const QPointF &pos, int delta, QWheelEvent::QWheelEvent(const QPointF &pos, int delta,
@ -659,7 +659,7 @@ QWheelEvent::~QWheelEvent()
\a orient holds the wheel's orientation. \a orient holds the wheel's orientation.
\sa pos(), pixelDelta(), angleDelta(), state() \sa pos(), pixelDelta(), angleDelta()
*/ */
QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta, QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,

View File

@ -71,6 +71,14 @@ QT_BEGIN_NAMESPACE
How the offscreen surface is implemented depends on the underlying platform, but it will How the offscreen surface is implemented depends on the underlying platform, but it will
typically use a pixel buffer (pbuffer). If the platform doesn't implement or support typically use a pixel buffer (pbuffer). If the platform doesn't implement or support
offscreen surfaces, QOffscreenSurface will use an invisible QWindow internally. offscreen surfaces, QOffscreenSurface will use an invisible QWindow internally.
\note In order to create an offscreen surface that is guaranteed to be compatible with
a given context and window, make sure to set the format to the context's or the
window's actual format, that is, the QSurfaceFormat returned from
QOpenGLContext::format() or QWindow::format() \e{after the context or window has been
created}. Passing the format returned from QWindow::requestedFormat() to setFormat()
may result in an incompatible offscreen surface since the underlying windowing system
interface may offer a different set of configurations for window and pbuffer surfaces.
*/ */
class Q_GUI_EXPORT QOffscreenSurfacePrivate : public QObjectPrivate class Q_GUI_EXPORT QOffscreenSurfacePrivate : public QObjectPrivate
{ {

View File

@ -165,7 +165,7 @@ void QOpenGLVersionProfile::setVersion(int majorVersion, int minorVersion)
/*! /*!
Returns the OpenGL profile. Only makes sense if profiles are supported by this version. Returns the OpenGL profile. Only makes sense if profiles are supported by this version.
\sa setProfile(), supportsProfiles() \sa setProfile()
*/ */
QSurfaceFormat::OpenGLContextProfile QOpenGLVersionProfile::profile() const QSurfaceFormat::OpenGLContextProfile QOpenGLVersionProfile::profile() const
{ {
@ -176,7 +176,7 @@ QSurfaceFormat::OpenGLContextProfile QOpenGLVersionProfile::profile() const
Sets the OpenGL profile \a profile. Only makes sense if profiles are supported by Sets the OpenGL profile \a profile. Only makes sense if profiles are supported by
this version. this version.
\sa profile(), supportsProfiles() \sa profile()
*/ */
void QOpenGLVersionProfile::setProfile(QSurfaceFormat::OpenGLContextProfile profile) void QOpenGLVersionProfile::setProfile(QSurfaceFormat::OpenGLContextProfile profile)
{ {

View File

@ -171,6 +171,7 @@ public:
template <typename T> template <typename T>
T *value(QOpenGLContext *context) { T *value(QOpenGLContext *context) {
QOpenGLContextGroup *group = context->shareGroup(); QOpenGLContextGroup *group = context->shareGroup();
QMutexLocker locker(&group->d_func()->m_mutex);
T *resource = static_cast<T *>(group->d_func()->m_resources.value(this, 0)); T *resource = static_cast<T *>(group->d_func()->m_resources.value(this, 0));
if (!resource) { if (!resource) {
resource = new T(context); resource = new T(context);

View File

@ -201,7 +201,7 @@ QString QSessionManager::sessionKey() const
Here's an example of how an application's QGuiApplication::commitDataRequest() Here's an example of how an application's QGuiApplication::commitDataRequest()
might be implemented: might be implemented:
\snippet code/src_gui_kernel_qguiapplication.cpp 8 \snippet code/src_gui_kernel_qguiapplication.cpp 1
If an error occurred within the application while saving its data, you may If an error occurred within the application while saving its data, you may
want to try allowsErrorInteraction() instead. want to try allowsErrorInteraction() instead.
@ -293,7 +293,7 @@ QSessionManager::RestartHint QSessionManager::restartHint() const
If the session manager is capable of restoring sessions it will execute If the session manager is capable of restoring sessions it will execute
\a command in order to restore the application. The command defaults to \a command in order to restore the application. The command defaults to
\snippet code/src_gui_kernel_qguiapplication.cpp 9 \snippet code/src_gui_kernel_qguiapplication.cpp 2
The \c -session option is mandatory; otherwise QGuiApplication cannot The \c -session option is mandatory; otherwise QGuiApplication cannot
tell whether it has been restored or what the current session identifier tell whether it has been restored or what the current session identifier
@ -321,7 +321,7 @@ void QSessionManager::setRestartCommand(const QStringList &command)
To iterate over the list, you can use the \l foreach pseudo-keyword: To iterate over the list, you can use the \l foreach pseudo-keyword:
\snippet code/src_gui_kernel_qguiapplication.cpp 10 \snippet code/src_gui_kernel_qguiapplication.cpp 3
\sa setRestartCommand(), restartHint() \sa setRestartCommand(), restartHint()
*/ */
@ -347,7 +347,7 @@ void QSessionManager::setDiscardCommand(const QStringList &command)
To iterate over the list, you can use the \l foreach pseudo-keyword: To iterate over the list, you can use the \l foreach pseudo-keyword:
\snippet code/src_gui_kernel_qguiapplication.cpp 11 \snippet code/src_gui_kernel_qguiapplication.cpp 4
\sa setDiscardCommand(), restartCommand(), setRestartCommand() \sa setDiscardCommand(), restartCommand(), setRestartCommand()
*/ */

View File

@ -387,7 +387,7 @@ void QSurfaceFormat::setOption(QSurfaceFormat::FormatOption option, bool on)
Returns true if the format option \a option is set; otherwise returns false. Returns true if the format option \a option is set; otherwise returns false.
\sa options(), testOption() \sa options()
*/ */
bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOption option) const bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOption option) const
{ {

View File

@ -159,10 +159,6 @@ QWindow::QWindow(QScreen *targetScreen)
d->screen = targetScreen; d->screen = targetScreen;
if (!d->screen) if (!d->screen)
d->screen = QGuiApplication::primaryScreen(); d->screen = QGuiApplication::primaryScreen();
//if your applications aborts here, then chances are your creating a QWindow before the
//screen list is populated.
Q_ASSERT(d->screen);
d->init(); d->init();
} }
@ -232,6 +228,13 @@ QWindow::~QWindow()
void QWindowPrivate::init() void QWindowPrivate::init()
{ {
Q_Q(QWindow); Q_Q(QWindow);
// If your application aborts here, you are probably creating a QWindow
// before the screen list is populated.
if (!screen) {
qFatal("Cannot create window: no screens available");
exit(1);
}
QObject::connect(screen, SIGNAL(destroyed(QObject*)), q, SLOT(screenDestroyed(QObject*))); QObject::connect(screen, SIGNAL(destroyed(QObject*)), q, SLOT(screenDestroyed(QObject*)));
QGuiApplicationPrivate::window_list.prepend(q); QGuiApplicationPrivate::window_list.prepend(q);
} }

View File

@ -81,7 +81,7 @@ QT_BEGIN_NAMESPACE
multisampling. Most hardware require significantly more memory to multisampling. Most hardware require significantly more memory to
do multisampling and the resulting quality is not on par with the do multisampling and the resulting quality is not on par with the
quality of the software paint engine. The OpenGL paint engine's quality of the software paint engine. The OpenGL paint engine's
strenght lies in its performance, not its visual rendering strength lies in its performance, not its visual rendering
quality. quality.
\section1 State Changes \section1 State Changes

View File

@ -2668,12 +2668,12 @@ void QOpenGLTexture::generateMipMaps()
} }
/*! /*!
Generates mipmaps for this texture object from mipmap level \baseLevel. If you are Generates mipmaps for this texture object from mipmap level \a baseLevel. If you are
using a texture target and filtering option that requires mipmaps and you using a texture target and filtering option that requires mipmaps and you
have disabled automatic mipmap generation then you need to call this function have disabled automatic mipmap generation then you need to call this function
or the overload to create the mipmap chain. or the overload to create the mipmap chain.
The generation of mipmaps to above \baseLevel is achieved by setting the mipmap The generation of mipmaps to above \a baseLevel is achieved by setting the mipmap
base level to \a baseLevel and then generating the mipmap chain. If \a resetBaseLevel base level to \a baseLevel and then generating the mipmap chain. If \a resetBaseLevel
is \c true, then the baseLevel of the texture will be reset to its previous value. is \c true, then the baseLevel of the texture will be reset to its previous value.
@ -3000,7 +3000,7 @@ void QOpenGLTexture::setBorderColor(QColor color)
} }
/*! /*!
Sets the color red to \a {r}, green to \a {g}, blue to \{b}, and \a {a} to the Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and \a {a} to the
alpha value. alpha value.
\overload \overload
*/ */
@ -3033,8 +3033,8 @@ void QOpenGLTexture::setBorderColor(float r, float g, float b, float a)
} }
/*! /*!
Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and \a the alpha Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and the alpha
value to {a}. value to \a {a}.
\overload \overload
*/ */
void QOpenGLTexture::setBorderColor(int r, int g, int b, int a) void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
@ -3068,8 +3068,8 @@ void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
} }
/*! /*!
Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and \a the alpha Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and the alpha
value to {a}. value to \a {a}.
\overload \overload
*/ */
void QOpenGLTexture::setBorderColor(uint r, uint g, uint b, uint a) void QOpenGLTexture::setBorderColor(uint r, uint g, uint b, uint a)

View File

@ -149,8 +149,6 @@ bool QOpenGLVertexArrayObjectPrivate::create()
} }
Q_Q(QOpenGLVertexArrayObject); Q_Q(QOpenGLVertexArrayObject);
if (context)
QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
QOpenGLContext *ctx = QOpenGLContext::currentContext(); QOpenGLContext *ctx = QOpenGLContext::currentContext();
if (!ctx) { if (!ctx) {
@ -202,6 +200,8 @@ void QOpenGLVertexArrayObjectPrivate::destroy()
if (!vao) if (!vao)
return; return;
Q_Q(QOpenGLVertexArrayObject);
switch (vaoFuncsType) { switch (vaoFuncsType) {
#ifndef QT_OPENGL_ES_2 #ifndef QT_OPENGL_ES_2
case Core_3_2: case Core_3_2:
@ -220,6 +220,10 @@ void QOpenGLVertexArrayObjectPrivate::destroy()
break; break;
} }
Q_ASSERT(context);
QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
context = 0;
vao = 0; vao = 0;
} }

View File

@ -129,7 +129,7 @@ struct Blend_ARGB32_on_RGB16_SourceAndConstAlpha {
}; };
void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl, const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect, const QRectF &targetRect,
const QRectF &sourceRect, const QRectF &sourceRect,
const QRect &clip, const QRect &clip,
@ -144,17 +144,17 @@ void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl,
#endif #endif
if (const_alpha == 256) { if (const_alpha == 256) {
Blend_RGB16_on_RGB16_NoAlpha noAlpha; Blend_RGB16_on_RGB16_NoAlpha noAlpha;
qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl, qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, noAlpha); targetRect, sourceRect, clip, noAlpha);
} else { } else {
Blend_RGB16_on_RGB16_ConstAlpha constAlpha(const_alpha); Blend_RGB16_on_RGB16_ConstAlpha constAlpha(const_alpha);
qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl, qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, constAlpha); targetRect, sourceRect, clip, constAlpha);
} }
} }
void qt_scale_image_argb32_on_rgb16(uchar *destPixels, int dbpl, void qt_scale_image_argb32_on_rgb16(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl, const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect, const QRectF &targetRect,
const QRectF &sourceRect, const QRectF &sourceRect,
const QRect &clip, const QRect &clip,
@ -169,11 +169,11 @@ void qt_scale_image_argb32_on_rgb16(uchar *destPixels, int dbpl,
#endif #endif
if (const_alpha == 256) { if (const_alpha == 256) {
Blend_ARGB32_on_RGB16_SourceAlpha noAlpha; Blend_ARGB32_on_RGB16_SourceAlpha noAlpha;
qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl, qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, noAlpha); targetRect, sourceRect, clip, noAlpha);
} else { } else {
Blend_ARGB32_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha); Blend_ARGB32_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha);
qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl, qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, constAlpha); targetRect, sourceRect, clip, constAlpha);
} }
} }
@ -453,7 +453,7 @@ struct Blend_ARGB32_on_ARGB32_SourceAndConstAlpha {
}; };
void qt_scale_image_rgb32_on_rgb32(uchar *destPixels, int dbpl, void qt_scale_image_rgb32_on_rgb32(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl, const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect, const QRectF &targetRect,
const QRectF &sourceRect, const QRectF &sourceRect,
const QRect &clip, const QRect &clip,
@ -468,17 +468,17 @@ void qt_scale_image_rgb32_on_rgb32(uchar *destPixels, int dbpl,
#endif #endif
if (const_alpha == 256) { if (const_alpha == 256) {
Blend_RGB32_on_RGB32_NoAlpha noAlpha; Blend_RGB32_on_RGB32_NoAlpha noAlpha;
qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, noAlpha); targetRect, sourceRect, clip, noAlpha);
} else { } else {
Blend_RGB32_on_RGB32_ConstAlpha constAlpha(const_alpha); Blend_RGB32_on_RGB32_ConstAlpha constAlpha(const_alpha);
qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, constAlpha); targetRect, sourceRect, clip, constAlpha);
} }
} }
void qt_scale_image_argb32_on_argb32(uchar *destPixels, int dbpl, void qt_scale_image_argb32_on_argb32(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl, const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect, const QRectF &targetRect,
const QRectF &sourceRect, const QRectF &sourceRect,
const QRect &clip, const QRect &clip,
@ -493,11 +493,11 @@ void qt_scale_image_argb32_on_argb32(uchar *destPixels, int dbpl,
#endif #endif
if (const_alpha == 256) { if (const_alpha == 256) {
Blend_ARGB32_on_ARGB32_SourceAlpha sourceAlpha; Blend_ARGB32_on_ARGB32_SourceAlpha sourceAlpha;
qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, sourceAlpha); targetRect, sourceRect, clip, sourceAlpha);
} else { } else {
Blend_ARGB32_on_ARGB32_SourceAndConstAlpha constAlpha(const_alpha); Blend_ARGB32_on_ARGB32_SourceAndConstAlpha constAlpha(const_alpha);
qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, constAlpha); targetRect, sourceRect, clip, constAlpha);
} }
} }

View File

@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
template <typename SRC, typename T> template <typename SRC, typename T>
void qt_scale_image_16bit(uchar *destPixels, int dbpl, void qt_scale_image_16bit(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl, const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect, const QRectF &targetRect,
const QRectF &srcRect, const QRectF &srcRect,
const QRect &clip, const QRect &clip,
@ -136,6 +136,15 @@ void qt_scale_image_16bit(uchar *destPixels, int dbpl,
quint16 *dst = ((quint16 *) (destPixels + ty1 * dbpl)) + tx1; quint16 *dst = ((quint16 *) (destPixels + ty1 * dbpl)) + tx1;
// this bounds check here is required as floating point rounding above might in some cases lead to
// w/h values that are one pixel too large, falling outside of the valid image area.
int yend = (srcy + iy * (h - 1)) >> 16;
if (yend < 0 || yend >= srch)
--h;
int xend = (basex + ix * (w - 1)) >> 16;
if (xend < 0 || xend >= (int)(sbpl/sizeof(quint32)))
--w;
while (h--) { while (h--) {
const SRC *src = (const SRC *) (srcPixels + (srcy >> 16) * sbpl); const SRC *src = (const SRC *) (srcPixels + (srcy >> 16) * sbpl);
int srcx = basex; int srcx = basex;
@ -161,7 +170,7 @@ void qt_scale_image_16bit(uchar *destPixels, int dbpl,
} }
template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl, template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl, const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect, const QRectF &targetRect,
const QRectF &srcRect, const QRectF &srcRect,
const QRect &clip, const QRect &clip,
@ -215,6 +224,8 @@ template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,
int h = ty2 - ty1; int h = ty2 - ty1;
int w = tx2 - tx1; int w = tx2 - tx1;
if (!w || !h)
return;
quint32 basex; quint32 basex;
quint32 srcy; quint32 srcy;
@ -236,6 +247,15 @@ template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,
quint32 *dst = ((quint32 *) (destPixels + ty1 * dbpl)) + tx1; quint32 *dst = ((quint32 *) (destPixels + ty1 * dbpl)) + tx1;
// this bounds check here is required as floating point rounding above might in some cases lead to
// w/h values that are one pixel too large, falling outside of the valid image area.
int yend = (srcy + iy * (h - 1)) >> 16;
if (yend < 0 || yend >= srch)
--h;
int xend = (basex + ix * (w - 1)) >> 16;
if (xend < 0 || xend >= (int)(sbpl/sizeof(quint32)))
--w;
while (h--) { while (h--) {
const uint *src = (const quint32 *) (srcPixels + (srcy >> 16) * sbpl); const uint *src = (const quint32 *) (srcPixels + (srcy >> 16) * sbpl);
int srcx = basex; int srcx = basex;

View File

@ -6522,7 +6522,7 @@ void qInitDrawhelperAsm()
qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit8888_sse2; qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit8888_sse2;
extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl, const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect, const QRectF &targetRect,
const QRectF &sourceRect, const QRectF &sourceRect,
const QRect &clip, const QRect &clip,

View File

@ -539,7 +539,7 @@ Blend_on_RGB16_SourceAndConstAlpha_Neon_create(BlendFunc blender, int const_alph
} }
void qt_scale_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, void qt_scale_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl, const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect, const QRectF &targetRect,
const QRectF &sourceRect, const QRectF &sourceRect,
const QRect &clip, const QRect &clip,
@ -548,19 +548,19 @@ void qt_scale_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl,
if (const_alpha == 0) if (const_alpha == 0)
return; return;
qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl, srch, targetRect, sourceRect, clip,
Blend_on_RGB16_SourceAndConstAlpha_Neon_create<quint32>(blend_8_pixels_argb32_on_rgb16_neon, const_alpha)); Blend_on_RGB16_SourceAndConstAlpha_Neon_create<quint32>(blend_8_pixels_argb32_on_rgb16_neon, const_alpha));
} }
void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl, void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl, const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect, const QRectF &targetRect,
const QRectF &sourceRect, const QRectF &sourceRect,
const QRect &clip, const QRect &clip,
int const_alpha); int const_alpha);
void qt_scale_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, void qt_scale_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl, const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect, const QRectF &targetRect,
const QRectF &sourceRect, const QRectF &sourceRect,
const QRect &clip, const QRect &clip,
@ -570,11 +570,11 @@ void qt_scale_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl,
return; return;
if (const_alpha == 256) { if (const_alpha == 256) {
qt_scale_image_rgb16_on_rgb16(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, const_alpha); qt_scale_image_rgb16_on_rgb16(destPixels, dbpl, srcPixels, sbpl, srch, targetRect, sourceRect, clip, const_alpha);
return; return;
} }
qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl, srch, targetRect, sourceRect, clip,
Blend_on_RGB16_SourceAndConstAlpha_Neon_create<quint16>(blend_8_pixels_rgb16_on_rgb16_neon, const_alpha)); Blend_on_RGB16_SourceAndConstAlpha_Neon_create<quint16>(blend_8_pixels_rgb16_on_rgb16_neon, const_alpha));
} }

View File

@ -138,7 +138,7 @@ typedef void (*SrcOverBlendFunc)(uchar *destPixels, int dbpl,
int const_alpha); int const_alpha);
typedef void (*SrcOverScaleFunc)(uchar *destPixels, int dbpl, typedef void (*SrcOverScaleFunc)(uchar *destPixels, int dbpl,
const uchar *src, int spbl, const uchar *src, int spbl, int srch,
const QRectF &targetRect, const QRectF &targetRect,
const QRectF &sourceRect, const QRectF &sourceRect,
const QRect &clipRect, const QRect &clipRect,

View File

@ -568,7 +568,7 @@ const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Opera
} }
void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl, void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl, const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect, const QRectF &targetRect,
const QRectF &sourceRect, const QRectF &sourceRect,
const QRect &clip, const QRect &clip,
@ -577,12 +577,12 @@ void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
if (const_alpha != 256) { if (const_alpha != 256) {
// from qblendfunctions.cpp // from qblendfunctions.cpp
extern void qt_scale_image_argb32_on_argb32(uchar *destPixels, int dbpl, extern void qt_scale_image_argb32_on_argb32(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl, const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect, const QRectF &targetRect,
const QRectF &sourceRect, const QRectF &sourceRect,
const QRect &clip, const QRect &clip,
int const_alpha); int const_alpha);
return qt_scale_image_argb32_on_argb32(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, const_alpha); return qt_scale_image_argb32_on_argb32(destPixels, dbpl, srcPixels, sbpl, srch, targetRect, sourceRect, clip, const_alpha);
} }
qreal sx = targetRect.width() / (qreal) sourceRect.width(); qreal sx = targetRect.width() / (qreal) sourceRect.width();
@ -651,6 +651,14 @@ void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
const __m128i alphaMask = _mm_set1_epi32(0xff000000); const __m128i alphaMask = _mm_set1_epi32(0xff000000);
const __m128i ixVector = _mm_set1_epi32(4*ix); const __m128i ixVector = _mm_set1_epi32(4*ix);
// this bounds check here is required as floating point rounding above might in some cases lead to
// w/h values that are one pixel too large, falling outside of the valid image area.
int yend = (srcy + iy * (h - 1)) >> 16;
if (yend < 0 || yend >= srch)
--h;
int xend = (basex + ix * (w - 1)) >> 16;
if (xend < 0 || xend >= (int)(sbpl/sizeof(quint32)))
--w;
while (h--) { while (h--) {
const uint *src = (const quint32 *) (srcPixels + (srcy >> 16) * sbpl); const uint *src = (const quint32 *) (srcPixels + (srcy >> 16) * sbpl);

View File

@ -2377,7 +2377,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
SrcOverScaleFunc func = qScaleFunctions[d->rasterBuffer->format][img.format()]; SrcOverScaleFunc func = qScaleFunctions[d->rasterBuffer->format][img.format()];
if (func && (!clip || clip->hasRectClip)) { if (func && (!clip || clip->hasRectClip)) {
func(d->rasterBuffer->buffer(), d->rasterBuffer->bytesPerLine(), func(d->rasterBuffer->buffer(), d->rasterBuffer->bytesPerLine(),
img.bits(), img.bytesPerLine(), img.bits(), img.bytesPerLine(), img.height(),
qt_mapRect_non_normalizing(r, s->matrix), sr, qt_mapRect_non_normalizing(r, s->matrix), sr,
!clip ? d->deviceRect : clip->clipRect, !clip ? d->deviceRect : clip->clipRect,
s->intOpacity); s->intOpacity);

View File

@ -1059,7 +1059,7 @@ void QPdfEngine::drawPath (const QPainterPath &p)
if (!d->hasPen && !d->hasBrush) if (!d->hasPen && !d->hasBrush)
return; return;
if (d->simplePen) { if (d->simplePen && d->opacity == 1.0) {
// draw strokes natively in this case for better output // draw strokes natively in this case for better output
*d->currentPage << QPdf::generatePath(p, QTransform(), d->hasBrush ? QPdf::FillAndStrokePath : QPdf::StrokePath); *d->currentPage << QPdf::generatePath(p, QTransform(), d->hasBrush ? QPdf::FillAndStrokePath : QPdf::StrokePath);
} else { } else {

View File

@ -546,6 +546,7 @@ QFontEngineData::~QFontEngineData()
/*! /*!
\fn QString QFont::rawName() const \fn QString QFont::rawName() const
\deprecated
Returns the name of the font within the underlying window system. Returns the name of the font within the underlying window system.
@ -559,6 +560,7 @@ QFontEngineData::~QFontEngineData()
/*! /*!
\fn void QFont::setRawName(const QString &name) \fn void QFont::setRawName(const QString &name)
\deprecated
Sets a font by its system specific name. Sets a font by its system specific name.
@ -1106,7 +1108,7 @@ int QFont::weight() const
Qt uses a weighting scale from 0 to 99 similar to, but not the Qt uses a weighting scale from 0 to 99 similar to, but not the
same as, the scales used in Windows or CSS. A weight of 0 is same as, the scales used in Windows or CSS. A weight of 0 is
ultralight, whilst 99 will be an extremely black. ultralight, whilst 99 will be extremely black.
This enum contains the predefined font weights: This enum contains the predefined font weights:
@ -1282,7 +1284,7 @@ bool QFont::kerning() const
When kerning is enabled, glyph metrics do not add up anymore, When kerning is enabled, glyph metrics do not add up anymore,
even for Latin text. In other words, the assumption that even for Latin text. In other words, the assumption that
width('a') + width('b') is equal to width("ab") is not width('a') + width('b') is equal to width("ab") is not
neccesairly true. necessarily true.
\sa kerning(), QFontMetrics \sa kerning(), QFontMetrics
*/ */
@ -2420,7 +2422,7 @@ QString QFontInfo::family() const
\since 4.8 \since 4.8
Returns the style name of the matched window system font on Returns the style name of the matched window system font on
system that supports it. systems that support it.
\sa QFont::styleName() \sa QFont::styleName()
*/ */

View File

@ -242,9 +242,11 @@ public:
{ qSwap(d, other.d); qSwap(resolve_mask, other.resolve_mask); return *this; } { qSwap(d, other.d); qSwap(resolve_mask, other.resolve_mask); return *this; }
#endif #endif
#if QT_DEPRECATED_SINCE(5, 3)
// needed for X11 // needed for X11
void setRawName(const QString &); QT_DEPRECATED void setRawName(const QString &);
QString rawName() const; QT_DEPRECATED QString rawName() const;
#endif
QString key() const; QString key() const;

View File

@ -251,7 +251,7 @@ public:
return script == other.script return script == other.script
&& screen == other.screen && screen == other.screen
&& multi == other.multi && multi == other.multi
&& (!multi || def.fallBackFamilies.size() == other.def.fallBackFamilies.size()) && (!multi || def.fallBackFamilies == other.def.fallBackFamilies)
&& def == other.def; && def == other.def;
} }
}; };

View File

@ -531,7 +531,7 @@ static const int scriptForWritingSystem[] = {
Q_STATIC_ASSERT(sizeof(scriptForWritingSystem) / sizeof(scriptForWritingSystem[0]) == QFontDatabase::WritingSystemsCount); Q_STATIC_ASSERT(sizeof(scriptForWritingSystem) / sizeof(scriptForWritingSystem[0]) == QFontDatabase::WritingSystemsCount);
int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem) Q_GUI_EXPORT int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem)
{ {
return scriptForWritingSystem[writingSystem]; return scriptForWritingSystem[writingSystem];
} }

View File

@ -264,16 +264,12 @@ _hb_qt_unicode_compose(hb_unicode_funcs_t * /*ufuncs*/,
// ### optimize // ### optimize
QString s = QString::fromUcs4(&a, 1) + QString::fromUcs4(&b, 1); QString s = QString::fromUcs4(&a, 1) + QString::fromUcs4(&b, 1);
QString normalized = s.normalized(QString::NormalizationForm_C); QString normalized = s.normalized(QString::NormalizationForm_C);
if (normalized.isEmpty())
return false;
QVector<uint> ucs4str = normalized.toUcs4(); QStringIterator it(normalized);
if (ucs4str.size() == 1) { Q_ASSERT(it.hasNext()); // size>0
*ab = ucs4str.at(0); *ab = it.next();
return true;
}
return false; return !it.hasNext(); // size==1
} }
static hb_bool_t static hb_bool_t
@ -287,29 +283,28 @@ _hb_qt_unicode_decompose(hb_unicode_funcs_t * /*ufuncs*/,
return false; return false;
QString normalized = QChar::decomposition(ab); QString normalized = QChar::decomposition(ab);
Q_ASSERT(!normalized.isEmpty()); if (normalized.isEmpty())
return false;
const QVector<uint> ucs4str = normalized.toUcs4(); QStringIterator it(normalized);
Q_ASSERT(ucs4str.size() <= HB_UNICODE_MAX_DECOMPOSITION_LEN); Q_ASSERT(it.hasNext()); // size>0
*a = it.next();
if (ucs4str.size() == 1) { if (!it.hasNext()) { // size==1
*a = ucs4str.at(0);
*b = 0; *b = 0;
return *a != ab; return *a != ab;
} }
if (ucs4str.size() == 2) { // size>1
*a = ucs4str.at(0); *b = it.next();
*b = ucs4str.at(1); if (!it.hasNext()) { // size==2
// Here's the ugly part: if ab decomposes to a single character and // Here's the ugly part: if ab decomposes to a single character and
// that character decomposes again, we have to detect that and undo // that character decomposes again, we have to detect that and undo
// the second part :-( // the second part :-(
QString recomposed = normalized.normalized(QString::NormalizationForm_C); const QString recomposed = normalized.normalized(QString::NormalizationForm_C);
if (recomposed.isEmpty() || recomposed == normalized) QStringIterator jt(recomposed);
return false; Q_ASSERT(jt.hasNext()); // size>0
const hb_codepoint_t c = jt.next();
hb_codepoint_t c = recomposed.toUcs4().at(0);
if (c != *a && c != ab) { if (c != *a && c != ab) {
*a = c; *a = c;
*b = 0; *b = 0;
@ -317,17 +312,18 @@ _hb_qt_unicode_decompose(hb_unicode_funcs_t * /*ufuncs*/,
return true; return true;
} }
// size>2
// If decomposed to more than two characters, take the last one, // If decomposed to more than two characters, take the last one,
// and recompose the rest to get the first component // and recompose the rest to get the first component
*b = ucs4str.last(); do {
normalized.chop(1); *b = it.next();
QString recomposed = normalized.normalized(QString::NormalizationForm_C); } while (it.hasNext());
if (recomposed.isEmpty() || recomposed == normalized) normalized.chop(QChar::requiresSurrogates(*b) ? 2 : 1);
return false; const QString recomposed = normalized.normalized(QString::NormalizationForm_C);
QStringIterator jt(recomposed);
Q_ASSERT(jt.hasNext()); // size>0
// We expect that recomposed has exactly one character now // We expect that recomposed has exactly one character now
*a = recomposed.toUcs4().at(0); *a = jt.next();
return true; return true;
} }
@ -337,9 +333,6 @@ _hb_qt_unicode_decompose_compatibility(hb_unicode_funcs_t * /*ufuncs*/,
hb_codepoint_t *decomposed, hb_codepoint_t *decomposed,
void * /*user_data*/) void * /*user_data*/)
{ {
if (QChar::decompositionTag(u) == QChar::NoDecomposition) // !NFKD
return 0;
const QString normalized = QChar::decomposition(u); const QString normalized = QChar::decomposition(u);
uint outlen = 0; uint outlen = 0;

View File

@ -700,10 +700,7 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ
if (fe != 0 && fe->type() == QFontEngine::Multi) { if (fe != 0 && fe->type() == QFontEngine::Multi) {
QFontEngineMulti *multiEngine = static_cast<QFontEngineMulti *>(fe); QFontEngineMulti *multiEngine = static_cast<QFontEngineMulti *>(fe);
fe = multiEngine->engine(0); fe = multiEngine->engine(0);
if (fe == 0) { Q_ASSERT(fe);
multiEngine->loadEngine(0);
fe = multiEngine->engine(0);
}
} }
if (fe != 0) { if (fe != 0) {

View File

@ -68,5 +68,5 @@
non-OpenGL-specific GUI functionality. non-OpenGL-specific GUI functionality.
The \l{Qt OpenGL C++ Classes} page gives an overview over the available classes The \l{Qt OpenGL C++ Classes} page gives an overview over the available classes
int this module. in this module.
*/ */

View File

@ -3227,43 +3227,6 @@ void QGLContext::moveToThread(QThread *thread)
visual. On other platforms it may work differently. visual. On other platforms it may work differently.
*/ */
/*! \fn int QGLContext::choosePixelFormat(void* dummyPfd, HDC pdc)
\b{Win32 only:} This virtual function chooses a pixel format
that matches the OpenGL \l{setFormat()}{format}.
Reimplement this function in a subclass if you need a custom
context.
\warning The \a dummyPfd pointer and \a pdc are used as a \c
PIXELFORMATDESCRIPTOR*. We use \c void to avoid using
Windows-specific types in our header files.
\sa chooseContext()
*/
/*! \fn void *QGLContext::chooseVisual()
\b{X11 only:} This virtual function tries to find a visual that
matches the format, reducing the demands if the original request
cannot be met.
The algorithm for reducing the demands of the format is quite
simple-minded, so override this method in your subclass if your
application has spcific requirements on visual selection.
\sa chooseContext()
*/
/*! \fn void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth)
\internal
\b{X11 only:} This virtual function chooses a visual that matches
the OpenGL \l{format()}{format}. Reimplement this function
in a subclass if you need a custom visual.
\sa chooseContext()
*/
/*! /*!
\fn void QGLContext::reset() \fn void QGLContext::reset()
@ -3706,7 +3669,7 @@ QGLWidget::~QGLWidget()
*/ */
/*! /*!
\fn QFunctionPointer QGLContext::getProcAddress() const \fn QFunctionPointer QGLContext::getProcAddress(const QString &proc) const
Returns a function pointer to the GL extension function passed in Returns a function pointer to the GL extension function passed in
\a proc. 0 is returned if a pointer to the function could not be \a proc. 0 is returned if a pointer to the function could not be
@ -4045,14 +4008,6 @@ void QGLWidget::paintEvent(QPaintEvent *)
*/ */
/*!
\fn void QGLWidget::setMouseTracking(bool enable)
If \a enable is true then mouse tracking is enabled; otherwise it
is disabled.
*/
/*! /*!
Renders the current scene on a pixmap and returns the pixmap. Renders the current scene on a pixmap and returns the pixmap.

View File

@ -466,7 +466,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
*/ */
/*! /*!
\fn void QGLFunctions::glBufferData(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage) \fn void QGLFunctions::glBufferData(GLenum target, qopengl_GLsizeiptr size, const void* data, GLenum usage)
Convenience function that calls glBufferData(\a target, \a size, \a data, \a usage). Convenience function that calls glBufferData(\a target, \a size, \a data, \a usage).
@ -475,7 +475,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
*/ */
/*! /*!
\fn void QGLFunctions::glBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data) \fn void QGLFunctions::glBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, const void* data)
Convenience function that calls glBufferSubData(\a target, \a offset, \a size, \a data). Convenience function that calls glBufferSubData(\a target, \a offset, \a size, \a data).

View File

@ -82,16 +82,7 @@ QVector<EGLint> q_createConfigAttributesFromFormat(const QSurfaceFormat &format)
// put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit, // put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit,
// we must set the red/green/blue sizes to zero. This has an unfortunate consequence that // we must set the red/green/blue sizes to zero. This has an unfortunate consequence that
// if the application sets the red/green/blue size to 5/6/5 on the QSurfaceFormat, // if the application sets the red/green/blue size to 5/6/5 on the QSurfaceFormat,
// they will probably get a 32-bit config, even when there's an RGB565 config available. // they might still get a 32-bit config, even when there's an RGB565 config available.
// // Now normalize the values so -1 becomes 0
// redSize = redSize > 0 ? redSize : 0;
// greenSize = greenSize > 0 ? greenSize : 0;
// blueSize = blueSize > 0 ? blueSize : 0;
// alphaSize = alphaSize > 0 ? alphaSize : 0;
// depthSize = depthSize > 0 ? depthSize : 0;
// stencilSize = stencilSize > 0 ? stencilSize : 0;
// sampleCount = sampleCount > 0 ? sampleCount : 0;
QVector<EGLint> configAttributes; QVector<EGLint> configAttributes;
@ -446,11 +437,9 @@ void q_printEglConfig(EGLDisplay display, EGLConfig config)
for (index = 0; attrs[index].attr != -1; ++index) { for (index = 0; attrs[index].attr != -1; ++index) {
EGLint value; EGLint value;
if (eglGetConfigAttrib(display, config, attrs[index].attr, &value)) { if (eglGetConfigAttrib(display, config, attrs[index].attr, &value)) {
qWarning("\t%s: %d\n", attrs[index].name, (int)value); qDebug("\t%s: %d", attrs[index].name, (int)value);
} }
} }
qWarning("\n");
} }
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX

View File

@ -44,6 +44,7 @@
#include "qeglpbuffer_p.h" #include "qeglpbuffer_p.h"
#include <qpa/qplatformwindow.h> #include <qpa/qplatformwindow.h>
#include <QOpenGLContext> #include <QOpenGLContext>
#include <QDebug>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -191,6 +192,12 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont
return; return;
} }
static const bool printConfig = qgetenv("QT_QPA_EGLFS_DEBUG").toInt();
if (printConfig) {
qDebug() << "Created context for format" << format << "with config:";
q_printEglConfig(m_eglDisplay, m_eglConfig);
}
#ifndef QT_NO_OPENGL #ifndef QT_NO_OPENGL
// Make the context current to ensure the GL version query works. This needs a surface too. // Make the context current to ensure the GL version query works. This needs a surface too.
const EGLint pbufferAttributes[] = { const EGLint pbufferAttributes[] = {
@ -261,37 +268,15 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
return true; return true;
} }
bool ok = eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_eglContext); const bool ok = eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_eglContext);
if (!ok)
qWarning("QEGLPlatformContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
#ifdef QEGL_EXTRA_DEBUG
static bool showDebug = true;
if (showDebug) {
showDebug = false;
const char *str = (const char*)glGetString(GL_VENDOR);
qWarning("Vendor %s\n", str);
str = (const char*)glGetString(GL_RENDERER);
qWarning("Renderer %s\n", str);
str = (const char*)glGetString(GL_VERSION);
qWarning("Version %s\n", str);
str = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
qWarning("Extensions %s\n",str);
str = (const char*)glGetString(GL_EXTENSIONS);
qWarning("Extensions %s\n", str);
}
#endif
if (ok) { if (ok) {
if (!m_swapIntervalEnvChecked) { if (!m_swapIntervalEnvChecked) {
m_swapIntervalEnvChecked = true; m_swapIntervalEnvChecked = true;
if (qEnvironmentVariableIsSet("QT_QPA_EGLFS_SWAPINTERVAL")) { if (qEnvironmentVariableIsSet("QT_QPA_EGLFS_SWAPINTERVAL")) {
QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL"); QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
bool ok; bool intervalOk;
const int swapInterval = swapIntervalString.toInt(&ok); const int swapInterval = swapIntervalString.toInt(&intervalOk);
if (ok) if (intervalOk)
m_swapIntervalFromEnv = swapInterval; m_swapIntervalFromEnv = swapInterval;
} }
} }
@ -302,6 +287,8 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
m_swapInterval = requestedSwapInterval; m_swapInterval = requestedSwapInterval;
eglSwapInterval(eglDisplay(), m_swapInterval); eglSwapInterval(eglDisplay(), m_swapInterval);
} }
} else {
qWarning("QEGLPlatformContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
} }
return ok; return ok;

View File

@ -220,7 +220,7 @@ void QBasicFontDatabase::releaseHandle(void *handle)
extern FT_Library qt_getFreetype(); extern FT_Library qt_getFreetype();
QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file) QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file, QSupportedWritingSystems *supportedWritingSystems)
{ {
FT_Library library = qt_getFreetype(); FT_Library library = qt_getFreetype();
@ -259,6 +259,8 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt
if (cm->encoding == FT_ENCODING_ADOBE_CUSTOM if (cm->encoding == FT_ENCODING_ADOBE_CUSTOM
|| cm->encoding == FT_ENCODING_MS_SYMBOL) { || cm->encoding == FT_ENCODING_MS_SYMBOL) {
writingSystems.setSupported(QFontDatabase::Symbol); writingSystems.setSupported(QFontDatabase::Symbol);
if (supportedWritingSystems)
supportedWritingSystems->setSupported(QFontDatabase::Symbol);
break; break;
} }
} }
@ -277,6 +279,8 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt
}; };
writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange); writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
if (supportedWritingSystems)
*supportedWritingSystems = writingSystems;
if (os2->usWeightClass == 0) if (os2->usWeightClass == 0)
; ;

View File

@ -64,7 +64,7 @@ public:
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName); QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
void releaseHandle(void *handle); void releaseHandle(void *handle);
static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file); static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file, QSupportedWritingSystems *supportedWritingSystems = 0);
static QString fontNameFromTTFile(const QString &filename); static QString fontNameFromTTFile(const QString &filename);
}; };

View File

@ -331,10 +331,8 @@ static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
return stylehint; return stylehint;
} }
void QFontconfigDatabase::populateFontDatabase() static void populateFromPattern(FcPattern *pattern)
{ {
FcFontSet *fonts;
QString familyName; QString familyName;
FcChar8 *value = 0; FcChar8 *value = 0;
int weight_value; int weight_value;
@ -348,34 +346,11 @@ void QFontconfigDatabase::populateFontDatabase()
FcBool scalable; FcBool scalable;
FcBool antialias; FcBool antialias;
{ if (FcPatternGetString(pattern, FC_FAMILY, 0, &value) != FcResultMatch)
FcObjectSet *os = FcObjectSetCreate(); return;
FcPattern *pattern = FcPatternCreate();
const char *properties [] = {
FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT,
FC_SPACING, FC_FILE, FC_INDEX,
FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE,
FC_WIDTH,
#if FC_VERSION >= 20297
FC_CAPABILITY,
#endif
(const char *)0
};
const char **p = properties;
while (*p) {
FcObjectSetAdd(os, *p);
++p;
}
fonts = FcFontList(0, pattern, os);
FcObjectSetDestroy(os);
FcPatternDestroy(pattern);
}
for (int i = 0; i < fonts->nfont; i++) {
if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
continue;
// capitalize(value);
familyName = QString::fromUtf8((const char *)value); familyName = QString::fromUtf8((const char *)value);
slant_value = FC_SLANT_ROMAN; slant_value = FC_SLANT_ROMAN;
weight_value = FC_WEIGHT_REGULAR; weight_value = FC_WEIGHT_REGULAR;
spacing_value = FC_PROPORTIONAL; spacing_value = FC_PROPORTIONAL;
@ -384,30 +359,30 @@ void QFontconfigDatabase::populateFontDatabase()
scalable = FcTrue; scalable = FcTrue;
if (FcPatternGetInteger (fonts->fonts[i], FC_SLANT, 0, &slant_value) != FcResultMatch) if (FcPatternGetInteger(pattern, FC_SLANT, 0, &slant_value) != FcResultMatch)
slant_value = FC_SLANT_ROMAN; slant_value = FC_SLANT_ROMAN;
if (FcPatternGetInteger (fonts->fonts[i], FC_WEIGHT, 0, &weight_value) != FcResultMatch) if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight_value) != FcResultMatch)
weight_value = FC_WEIGHT_REGULAR; weight_value = FC_WEIGHT_REGULAR;
if (FcPatternGetInteger (fonts->fonts[i], FC_WIDTH, 0, &width_value) != FcResultMatch) if (FcPatternGetInteger(pattern, FC_WIDTH, 0, &width_value) != FcResultMatch)
width_value = FC_WIDTH_NORMAL; width_value = FC_WIDTH_NORMAL;
if (FcPatternGetInteger (fonts->fonts[i], FC_SPACING, 0, &spacing_value) != FcResultMatch) if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing_value) != FcResultMatch)
spacing_value = FC_PROPORTIONAL; spacing_value = FC_PROPORTIONAL;
if (FcPatternGetString (fonts->fonts[i], FC_FILE, 0, &file_value) != FcResultMatch) if (FcPatternGetString(pattern, FC_FILE, 0, &file_value) != FcResultMatch)
file_value = 0; file_value = 0;
if (FcPatternGetInteger (fonts->fonts[i], FC_INDEX, 0, &indexValue) != FcResultMatch) if (FcPatternGetInteger(pattern, FC_INDEX, 0, &indexValue) != FcResultMatch)
indexValue = 0; indexValue = 0;
if (FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &scalable) != FcResultMatch) if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &scalable) != FcResultMatch)
scalable = FcTrue; scalable = FcTrue;
if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch) if (FcPatternGetString(pattern, FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
foundry_value = 0; foundry_value = 0;
if (FcPatternGetString(fonts->fonts[i], FC_STYLE, 0, &style_value) != FcResultMatch) if (FcPatternGetString(pattern, FC_STYLE, 0, &style_value) != FcResultMatch)
style_value = 0; style_value = 0;
if(FcPatternGetBool(fonts->fonts[i],FC_ANTIALIAS,0,&antialias) != FcResultMatch) if (FcPatternGetBool(pattern,FC_ANTIALIAS,0,&antialias) != FcResultMatch)
antialias = true; antialias = true;
QSupportedWritingSystems writingSystems; QSupportedWritingSystems writingSystems;
FcLangSet *langset = 0; FcLangSet *langset = 0;
FcResult res = FcPatternGetLangSet(fonts->fonts[i], FC_LANG, 0, &langset); FcResult res = FcPatternGetLangSet(pattern, FC_LANG, 0, &langset);
if (res == FcResultMatch) { if (res == FcResultMatch) {
bool hasLang = false; bool hasLang = false;
for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) { for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
@ -435,7 +410,7 @@ void QFontconfigDatabase::populateFontDatabase()
if (writingSystems.supported(QFontDatabase::WritingSystem(j)) if (writingSystems.supported(QFontDatabase::WritingSystem(j))
&& requiresOpenType(j) && openType[j]) { && requiresOpenType(j) && openType[j]) {
FcChar8 *cap; FcChar8 *cap;
res = FcPatternGetString (fonts->fonts[i], FC_CAPABILITY, 0, &cap); res = FcPatternGetString (pattern, FC_CAPABILITY, 0, &cap);
if (res != FcResultMatch || !strstr((const char *)cap, openType[j])) if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
writingSystems.setSupported(QFontDatabase::WritingSystem(j),false); writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
} }
@ -456,7 +431,7 @@ void QFontconfigDatabase::populateFontDatabase()
double pixel_size = 0; double pixel_size = 0;
if (!scalable) if (!scalable)
FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size); FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &pixel_size);
bool fixedPitch = spacing_value >= FC_MONO; bool fixedPitch = spacing_value >= FC_MONO;
// Note: stretch should really be an int but registerFont incorrectly uses an enum // Note: stretch should really be an int but registerFont incorrectly uses an enum
@ -465,9 +440,41 @@ void QFontconfigDatabase::populateFontDatabase()
QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile); QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size; // qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
for (int k = 1; FcPatternGetString(fonts->fonts[i], FC_FAMILY, k, &value) == FcResultMatch; ++k) for (int k = 1; FcPatternGetString(pattern, FC_FAMILY, k, &value) == FcResultMatch; ++k)
QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value)); QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value));
}
void QFontconfigDatabase::populateFontDatabase()
{
FcInitReinitialize();
FcFontSet *fonts;
{
FcObjectSet *os = FcObjectSetCreate();
FcPattern *pattern = FcPatternCreate();
const char *properties [] = {
FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT,
FC_SPACING, FC_FILE, FC_INDEX,
FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE,
FC_WIDTH,
#if FC_VERSION >= 20297
FC_CAPABILITY,
#endif
(const char *)0
};
const char **p = properties;
while (*p) {
FcObjectSetAdd(os, *p);
++p;
} }
fonts = FcFontList(0, pattern, os);
FcObjectSetDestroy(os);
FcPatternDestroy(pattern);
}
for (int i = 0; i < fonts->nfont; i++)
populateFromPattern(fonts->fonts[i]);
FcFontSetDestroy (fonts); FcFontSetDestroy (fonts);
@ -802,6 +809,7 @@ static FcPattern *queryFont(const FcChar8 *file, const QByteArray &data, int id,
QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
{ {
QStringList families; QStringList families;
FcFontSet *set = FcConfigGetFonts(0, FcSetApplication); FcFontSet *set = FcConfigGetFonts(0, FcSetApplication);
if (!set) { if (!set) {
FcConfigAppFontAddFile(0, (const FcChar8 *)":/non-existent"); FcConfigAppFontAddFile(0, (const FcChar8 *)":/non-existent");
@ -814,28 +822,24 @@ QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData,
FcBlanks *blanks = FcConfigGetBlanks(0); FcBlanks *blanks = FcConfigGetBlanks(0);
int count = 0; int count = 0;
FcPattern *pattern = 0; FcPattern *pattern;
do { do {
pattern = queryFont((const FcChar8 *)QFile::encodeName(fileName).constData(), pattern = queryFont((const FcChar8 *)QFile::encodeName(fileName).constData(),
fontData, id, blanks, &count); fontData, id, blanks, &count);
if (!pattern) if (!pattern)
return families; return families;
FcPatternDel(pattern, FC_FILE);
QByteArray cs = fileName.toUtf8();
FcPatternAddString(pattern, FC_FILE, (const FcChar8 *) cs.constData());
FcChar8 *fam = 0; FcChar8 *fam = 0;
if (FcPatternGetString(pattern, FC_FAMILY, 0, &fam) == FcResultMatch) { if (FcPatternGetString(pattern, FC_FAMILY, 0, &fam) == FcResultMatch) {
QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam)); QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
families << family; families << family;
} }
populateFromPattern(pattern);
if (!FcFontSetAdd(set, pattern)) FcFontSetAdd(set, pattern);
return families;
++id; ++id;
} while (pattern && id < count); } while (id < count);
return families; return families;
} }

View File

@ -1,20 +1,17 @@
Generic plug-in for evdev multiple touch (ABS_MT) events. Generic plug-in for evdev multiple touch (ABS_MT) events.
Supports protocol type A & B. Supports protocol type A & B.
Type B is supported both directly and via libmtdev. Type B is supported both directly and via libmtdev.
Single-touch devices reporting ABS_X and Y only are not supported
by this plugin. Use tslib or evdevmouse instead.
The protocol type will be detected automatically. The protocol type will be detected automatically.
libmtdev is automatically detected based on library availability. To disable it, libmtdev is automatically detected based on library availability. To disable it,
pass -no-mtdev to configure. pass -no-mtdev to configure.
Tested with the following kernel drivers: Single-touch devices reporting ABS_X and Y are supported too. Keep in
bcm5974 (type A) mind however that the libudev-based device discovery may not be able
hid_magicmouse (type A with ABS_MT_TRACKING_ID) (type B over libmtdev) to recognize such devices. If mouse events are sufficient, it may be
wacom (type B) better to use evdevmouse or tslib with such devices.
To use this "driver", pass -plugin EvdevTouch on the command line. To use this plugin, pass -plugin EvdevTouch on the command line.
If automatic detection does not work, use -plugin If automatic detection does not work, use -plugin
EvdevTouch:/dev/input/eventN to explicitly set the device file EvdevTouch:/dev/input/eventN to explicitly set the device file

View File

@ -576,6 +576,7 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
} }
QAndroidPlatformScreen *screen = static_cast<QAndroidPlatformScreen *>(m_androidPlatformIntegration->screen()); QAndroidPlatformScreen *screen = static_cast<QAndroidPlatformScreen *>(m_androidPlatformIntegration->screen());
if (screen->rasterSurfaces())
QMetaObject::invokeMethod(screen, "setDirty", Qt::QueuedConnection, Q_ARG(QRect,screen->geometry())); QMetaObject::invokeMethod(screen, "setDirty", Qt::QueuedConnection, Q_ARG(QRect,screen->geometry()));
} }

View File

@ -70,6 +70,35 @@ static jfieldID m_selectionStartFieldID = 0;
static jfieldID m_startOffsetFieldID = 0; static jfieldID m_startOffsetFieldID = 0;
static jfieldID m_textFieldID = 0; static jfieldID m_textFieldID = 0;
static jboolean beginBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
{
if (!m_androidInputContext)
return JNI_FALSE;
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ BEGINBATCH";
#endif
return m_androidInputContext->beginBatchEdit();
return JNI_TRUE;
}
static jboolean endBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
{
if (!m_androidInputContext)
return JNI_FALSE;
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ ENDBATCH";
#endif
return m_androidInputContext->endBatchEdit();
return JNI_TRUE;
}
static jboolean commitText(JNIEnv *env, jobject /*thiz*/, jstring text, jint newCursorPosition) static jboolean commitText(JNIEnv *env, jobject /*thiz*/, jstring text, jint newCursorPosition)
{ {
if (!m_androidInputContext) if (!m_androidInputContext)
@ -121,12 +150,13 @@ static jobject getExtractedText(JNIEnv *env, jobject /*thiz*/, int hintMaxChars,
if (!m_androidInputContext) if (!m_androidInputContext)
return 0; return 0;
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ GETEX";
#endif
const QAndroidInputContext::ExtractedText &extractedText = const QAndroidInputContext::ExtractedText &extractedText =
m_androidInputContext->getExtractedText(hintMaxChars, hintMaxLines, flags); m_androidInputContext->getExtractedText(hintMaxChars, hintMaxLines, flags);
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ GETEX" << hintMaxChars << hintMaxLines << QString::fromLatin1("0x") + QString::number(flags,16) << extractedText.text << "partOff:" << extractedText.partialStartOffset << extractedText.partialEndOffset << "sel:" << extractedText.selectionStart << extractedText.selectionEnd << "offset:" << extractedText.startOffset;
#endif
jobject object = env->NewObject(m_extractedTextClass, m_classConstructorMethodID); jobject object = env->NewObject(m_extractedTextClass, m_classConstructorMethodID);
env->SetIntField(object, m_partialStartOffsetFieldID, extractedText.partialStartOffset); env->SetIntField(object, m_partialStartOffsetFieldID, extractedText.partialStartOffset);
env->SetIntField(object, m_partialEndOffsetFieldID, extractedText.partialEndOffset); env->SetIntField(object, m_partialEndOffsetFieldID, extractedText.partialEndOffset);
@ -285,6 +315,8 @@ static jboolean updateCursorPosition(JNIEnv */*env*/, jobject /*thiz*/)
static JNINativeMethod methods[] = { static JNINativeMethod methods[] = {
{"beginBatchEdit", "()Z", (void *)beginBatchEdit},
{"endBatchEdit", "()Z", (void *)endBatchEdit},
{"commitText", "(Ljava/lang/String;I)Z", (void *)commitText}, {"commitText", "(Ljava/lang/String;I)Z", (void *)commitText},
{"deleteSurroundingText", "(II)Z", (void *)deleteSurroundingText}, {"deleteSurroundingText", "(II)Z", (void *)deleteSurroundingText},
{"finishComposingText", "()Z", (void *)finishComposingText}, {"finishComposingText", "()Z", (void *)finishComposingText},
@ -306,7 +338,7 @@ static JNINativeMethod methods[] = {
QAndroidInputContext::QAndroidInputContext() QAndroidInputContext::QAndroidInputContext()
: QPlatformInputContext(), m_blockUpdateSelection(false) : QPlatformInputContext(), m_blockUpdateSelection(false), m_batchEditNestingLevel(0)
{ {
QtAndroid::AttachedJNIEnv env; QtAndroid::AttachedJNIEnv env;
if (!env.jniEnv) if (!env.jniEnv)
@ -416,11 +448,14 @@ void QAndroidInputContext::commit()
void QAndroidInputContext::updateCursorPosition() void QAndroidInputContext::updateCursorPosition()
{ {
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery(); QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (!query.isNull() && !m_blockUpdateSelection) { if (!query.isNull() && !m_blockUpdateSelection && !m_batchEditNestingLevel) {
// make sure it also works with editors that have not been updated to the new API // make sure it also works with editors that have not been updated to the new API
QVariant absolutePos = query->value(Qt::ImAbsolutePosition); QVariant absolutePos = query->value(Qt::ImAbsolutePosition);
const int cursorPos = absolutePos.isValid() ? absolutePos.toInt() : query->value(Qt::ImCursorPosition).toInt(); const int cursorPos = absolutePos.isValid() ? absolutePos.toInt() : query->value(Qt::ImCursorPosition).toInt();
QtAndroidInput::updateSelection(cursorPos, cursorPos, -1, -1); //selection empty and no pre-edit text const int composeLength = m_composingText.length();
const int composeStart = composeLength ? cursorPos : -1;
QtAndroidInput::updateSelection(cursorPos + composeLength, cursorPos + composeLength, //empty selection
composeStart, composeStart + composeLength); // pre-edit text
} }
} }
@ -507,6 +542,19 @@ void QAndroidInputContext::sendEvent(QObject *receiver, QInputMethodQueryEvent *
QCoreApplication::sendEvent(receiver, event); QCoreApplication::sendEvent(receiver, event);
} }
jboolean QAndroidInputContext::beginBatchEdit()
{
++m_batchEditNestingLevel;
return JNI_TRUE;
}
jboolean QAndroidInputContext::endBatchEdit()
{
if (--m_batchEditNestingLevel == 0 && !m_blockUpdateSelection) //ending batch edit mode
updateCursorPosition();
return JNI_TRUE;
}
jboolean QAndroidInputContext::commitText(const QString &text, jint /*newCursorPosition*/) jboolean QAndroidInputContext::commitText(const QString &text, jint /*newCursorPosition*/)
{ {
m_composingText = text; m_composingText = text;
@ -559,19 +607,39 @@ jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/)
const QAndroidInputContext::ExtractedText &QAndroidInputContext::getExtractedText(jint hintMaxChars, jint /*hintMaxLines*/, jint /*flags*/) const QAndroidInputContext::ExtractedText &QAndroidInputContext::getExtractedText(jint hintMaxChars, jint /*hintMaxLines*/, jint /*flags*/)
{ {
// Note to self: "if the GET_EXTRACTED_TEXT_MONITOR flag is set, you should be calling
// updateExtractedText(View, int, ExtractedText) whenever you call
// updateSelection(View, int, int, int, int)." QTBUG-37980
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery(); QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull()) if (query.isNull())
return m_extractedText; return m_extractedText;
if (hintMaxChars) int localPos = query->value(Qt::ImCursorPosition).toInt(); //position before pre-edit text relative to the current block
m_extractedText.text = query->value(Qt::ImSurroundingText).toString().right(hintMaxChars); QVariant absolutePos = query->value(Qt::ImAbsolutePosition);
int blockPos = absolutePos.isValid() ? absolutePos.toInt() - localPos : 0; // position of the start of the current block
QString blockText = query->value(Qt::ImSurroundingText).toString() + m_composingText;
int composeLength = m_composingText.length();
int cpos = localPos + composeLength; //actual cursor pos relative to the current block
int localOffset = 0; // start of extracted text relative to the current block
if (hintMaxChars) {
if (cpos > hintMaxChars)
localOffset = cpos - hintMaxChars;
m_extractedText.text = blockText.mid(localOffset, hintMaxChars);
}
m_extractedText.startOffset = blockPos + localOffset; // "The offset in the overall text at which the extracted text starts."
m_extractedText.startOffset = query->value(Qt::ImCursorPosition).toInt();
const QString &selection = query->value(Qt::ImCurrentSelection).toString(); const QString &selection = query->value(Qt::ImCurrentSelection).toString();
const int selLen = selection.length(); const int selLen = selection.length();
if (selLen) { if (selLen) {
m_extractedText.selectionStart = query->value(Qt::ImAnchorPosition).toInt(); m_extractedText.selectionStart = query->value(Qt::ImAnchorPosition).toInt() - localOffset;
m_extractedText.selectionEnd = m_extractedText.startOffset; m_extractedText.selectionEnd = m_extractedText.selectionStart + selLen;
} else {
m_extractedText.selectionStart = cpos - localOffset;
m_extractedText.selectionEnd = cpos - localOffset;
} }
return m_extractedText; return m_extractedText;
@ -610,7 +678,7 @@ QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
{ {
QVariant textBefore = queryFocusObjectThreadSafe(Qt::ImTextBeforeCursor, QVariant(length)); QVariant textBefore = queryFocusObjectThreadSafe(Qt::ImTextBeforeCursor, QVariant(length));
if (textBefore.isValid()) { if (textBefore.isValid()) {
return textBefore.toString().left(length); return textBefore.toString().left(length) + m_composingText;
} }
//compatibility code for old controls that do not implement the new API //compatibility code for old controls that do not implement the new API
@ -624,7 +692,7 @@ QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
return text; return text;
const int wordLeftPos = cursorPos - length; const int wordLeftPos = cursorPos - length;
return text.mid(wordLeftPos > 0 ? wordLeftPos : 0, cursorPos); return text.mid(wordLeftPos > 0 ? wordLeftPos : 0, cursorPos) + m_composingText;
} }
jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCursorPosition) jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCursorPosition)
@ -647,11 +715,11 @@ jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCur
sendInputMethodEvent(&event); sendInputMethodEvent(&event);
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery(); QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (!query.isNull() && !m_blockUpdateSelection) { if (!query.isNull() && !m_blockUpdateSelection && !m_batchEditNestingLevel) {
QVariant absolutePos = query->value(Qt::ImAbsolutePosition); QVariant absolutePos = query->value(Qt::ImAbsolutePosition);
const int cursorPos = absolutePos.isValid() ? absolutePos.toInt() : query->value(Qt::ImCursorPosition).toInt(); const int cursorPos = absolutePos.isValid() ? absolutePos.toInt() : query->value(Qt::ImCursorPosition).toInt();
const int preeditLength = text.length(); const int preeditLength = text.length();
QtAndroidInput::updateSelection(cursorPos+preeditLength, cursorPos+preeditLength, cursorPos, cursorPos+preeditLength); QtAndroidInput::updateSelection(cursorPos+preeditLength, cursorPos+preeditLength, -1, -1);
} }
return JNI_TRUE; return JNI_TRUE;
@ -713,9 +781,17 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end)
jboolean QAndroidInputContext::setSelection(jint start, jint end) jboolean QAndroidInputContext::setSelection(jint start, jint end)
{ {
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return JNI_FALSE;
int localPos = query->value(Qt::ImCursorPosition).toInt();
QVariant absolutePos = query->value(Qt::ImAbsolutePosition);
int blockPosition = absolutePos.isValid() ? absolutePos.toInt() - localPos : 0;
QList<QInputMethodEvent::Attribute> attributes; QList<QInputMethodEvent::Attribute> attributes;
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection,
start, start - blockPosition,
end - start, end - start,
QVariant())); QVariant()));

View File

@ -97,6 +97,8 @@ public:
void clear(); void clear();
//---------------// //---------------//
jboolean beginBatchEdit();
jboolean endBatchEdit();
jboolean commitText(const QString &text, jint newCursorPosition); jboolean commitText(const QString &text, jint newCursorPosition);
jboolean deleteSurroundingText(jint leftLength, jint rightLength); jboolean deleteSurroundingText(jint leftLength, jint rightLength);
jboolean finishComposingText(); jboolean finishComposingText();
@ -133,6 +135,7 @@ private:
QString m_composingText; QString m_composingText;
QMetaObject::Connection m_updateCursorPosConnection; QMetaObject::Connection m_updateCursorPosConnection;
bool m_blockUpdateSelection; bool m_blockUpdateSelection;
int m_batchEditNestingLevel;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -41,6 +41,9 @@
#include "qandroidplatformdialoghelpers.h" #include "qandroidplatformdialoghelpers.h"
#include "androidjnimain.h" #include "androidjnimain.h"
#include <QTextDocument>
#include <private/qguiapplication_p.h> #include <private/qguiapplication_p.h>
#include <qpa/qplatformtheme.h> #include <qpa/qplatformtheme.h>
@ -61,6 +64,14 @@ void QAndroidPlatformMessageDialogHelper::exec()
m_loop.exec(); m_loop.exec();
} }
static QString htmlText(QString text)
{
if (Qt::mightBeRichText(text))
return text;
text.remove(QLatin1Char('\r'));
return text.toHtmlEscaped().replace(QLatin1Char('\n'), QLatin1String("<br />"));
}
bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags
, Qt::WindowModality windowModality , Qt::WindowModality windowModality
, QWindow *parent) , QWindow *parent)
@ -74,19 +85,19 @@ bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags
m_javaMessageDialog.callMethod<void>("setIcon", "(I)V", opt->icon()); m_javaMessageDialog.callMethod<void>("setIcon", "(I)V", opt->icon());
QString str = opt->windowTitle(); QString str = htmlText(opt->windowTitle());
if (!str.isEmpty()) if (!str.isEmpty())
m_javaMessageDialog.callMethod<void>("setTile", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object()); m_javaMessageDialog.callMethod<void>("setTile", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
str = opt->text(); str = htmlText(opt->text());
if (!str.isEmpty()) if (!str.isEmpty())
m_javaMessageDialog.callMethod<void>("setText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object()); m_javaMessageDialog.callMethod<void>("setText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
str = opt->informativeText(); str = htmlText(opt->informativeText());
if (!str.isEmpty()) if (!str.isEmpty())
m_javaMessageDialog.callMethod<void>("setInformativeText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object()); m_javaMessageDialog.callMethod<void>("setInformativeText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
str = opt->detailedText(); str = htmlText(opt->detailedText());
if (!str.isEmpty()) if (!str.isEmpty())
m_javaMessageDialog.callMethod<void>("setDetailedText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object()); m_javaMessageDialog.callMethod<void>("setDetailedText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());

View File

@ -60,7 +60,17 @@ void QAndroidPlatformFontDatabase::populateFontDatabase()
QDir dir(fontpath, QLatin1String("*.ttf")); QDir dir(fontpath, QLatin1String("*.ttf"));
for (int i = 0; i < int(dir.count()); ++i) { for (int i = 0; i < int(dir.count()); ++i) {
const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i])); const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
addTTFile(QByteArray(), file);
QSupportedWritingSystems supportedWritingSystems;
QStringList families = addTTFile(QByteArray(), file, &supportedWritingSystems);
extern int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem);
for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
if (i == QFontDatabase::Any || supportedWritingSystems.supported(QFontDatabase::WritingSystem(i))) {
QChar::Script script = QChar::Script(qt_script_for_writing_system(QFontDatabase::WritingSystem(i)));
m_fallbacks[script] += families;
}
}
} }
} }
@ -71,9 +81,9 @@ QStringList QAndroidPlatformFontDatabase::fallbacksForFamily(const QString &fami
{ {
Q_UNUSED(family); Q_UNUSED(family);
Q_UNUSED(style); Q_UNUSED(style);
Q_UNUSED(script);
if (styleHint == QFont::Monospace)
return QString(qgetenv("QT_ANDROID_FONTS_MONOSPACE")).split(";");
return QString(qgetenv("QT_ANDROID_FONTS")).split(";"); if (styleHint == QFont::Monospace)
return QString(qgetenv("QT_ANDROID_FONTS_MONOSPACE")).split(";") + m_fallbacks[script];
return QString(qgetenv("QT_ANDROID_FONTS")).split(";") + m_fallbacks[script];
} }

View File

@ -53,6 +53,9 @@ public:
QFont::Style style, QFont::Style style,
QFont::StyleHint styleHint, QFont::StyleHint styleHint,
QChar::Script script) const; QChar::Script script) const;
private:
QHash<QChar::Script, QStringList> m_fallbacks;
}; };
#endif // QANDROIDPLATFORMFONTDATABASE_H #endif // QANDROIDPLATFORMFONTDATABASE_H

View File

@ -41,6 +41,7 @@
#include "qandroidplatformintegration.h" #include "qandroidplatformintegration.h"
#include <QtCore/private/qjni_p.h>
#include <QGuiApplication> #include <QGuiApplication>
#include <QOpenGLContext> #include <QOpenGLContext>
#include <QThread> #include <QThread>
@ -103,9 +104,6 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
m_androidPlatformNativeInterface = new QAndroidPlatformNativeInterface(); m_androidPlatformNativeInterface = new QAndroidPlatformNativeInterface();
if (!eglBindAPI(EGL_OPENGL_ES_API))
qFatal("Could not bind GL_ES API");
m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (m_eglDisplay == EGL_NO_DISPLAY) if (m_eglDisplay == EGL_NO_DISPLAY)
qFatal("Could not open egl display"); qFatal("Could not open egl display");
@ -114,6 +112,9 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
if (!eglInitialize(m_eglDisplay, &major, &minor)) if (!eglInitialize(m_eglDisplay, &major, &minor))
qFatal("Could not initialize egl display"); qFatal("Could not initialize egl display");
if (!eglBindAPI(EGL_OPENGL_ES_API))
qFatal("Could not bind GL_ES API");
m_primaryScreen = new QAndroidPlatformScreen(); m_primaryScreen = new QAndroidPlatformScreen();
screenAdded(m_primaryScreen); screenAdded(m_primaryScreen);
m_primaryScreen->setPhysicalSize(QSize(m_defaultPhysicalSizeWidth, m_defaultPhysicalSizeHeight)); m_primaryScreen->setPhysicalSize(QSize(m_defaultPhysicalSizeWidth, m_defaultPhysicalSizeHeight));
@ -130,9 +131,41 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
#endif #endif
m_androidSystemLocale = new QAndroidSystemLocale; m_androidSystemLocale = new QAndroidSystemLocale;
QJNIObjectPrivate javaActivity(QtAndroid::activity());
if (javaActivity.isValid()) {
QJNIObjectPrivate resources = javaActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
QJNIObjectPrivate configuration = resources.callObjectMethod("getConfiguration", "()Landroid/content/res/Configuration;");
int touchScreen = configuration.getField<jint>("touchscreen");
if (touchScreen == QJNIObjectPrivate::getStaticField<jint>("android/content/res/Configuration", "TOUCHSCREEN_FINGER")
|| touchScreen == QJNIObjectPrivate::getStaticField<jint>("android/content/res/Configuration", "TOUCHSCREEN_STYLUS"))
{
m_touchDevice = new QTouchDevice;
m_touchDevice->setType(QTouchDevice::TouchScreen);
m_touchDevice->setCapabilities(QTouchDevice::Position
| QTouchDevice::Area
| QTouchDevice::Pressure
| QTouchDevice::NormalizedPosition);
QJNIObjectPrivate pm = javaActivity.callObjectMethod("getPackageManager", "()Landroid/content/pm/PackageManager;");
Q_ASSERT(pm.isValid());
if (pm.callMethod<jboolean>("hasSystemFeature","(Ljava/lang/String;)Z",
QJNIObjectPrivate::getStaticObjectField("android/content/pm/PackageManager", "FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND", "Ljava/lang/String;").object())) {
m_touchDevice->setMaximumTouchPoints(10);
} else if (pm.callMethod<jboolean>("hasSystemFeature","(Ljava/lang/String;)Z",
QJNIObjectPrivate::getStaticObjectField("android/content/pm/PackageManager", "FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT", "Ljava/lang/String;").object())) {
m_touchDevice->setMaximumTouchPoints(4);
} else if (pm.callMethod<jboolean>("hasSystemFeature","(Ljava/lang/String;)Z",
QJNIObjectPrivate::getStaticObjectField("android/content/pm/PackageManager", "FEATURE_TOUCHSCREEN_MULTITOUCH", "Ljava/lang/String;").object())) {
m_touchDevice->setMaximumTouchPoints(2);
}
QWindowSystemInterface::registerTouchDevice(m_touchDevice);
}
}
} }
bool QAndroidPlatformIntegration::needsWorkaround() bool QAndroidPlatformIntegration::needsBasicRenderloopWorkaround()
{ {
static bool needsWorkaround = static bool needsWorkaround =
QtAndroid::deviceName().compare(QStringLiteral("samsung SM-T211"), Qt::CaseInsensitive) == 0 QtAndroid::deviceName().compare(QStringLiteral("samsung SM-T211"), Qt::CaseInsensitive) == 0
@ -150,7 +183,7 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
case OpenGL: return true; case OpenGL: return true;
case ForeignWindows: return true; case ForeignWindows: return true;
case ThreadedOpenGL: case ThreadedOpenGL:
if (needsWorkaround()) if (needsBasicRenderloopWorkaround())
return false; return false;
else else
return true; return true;

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