moving to Qt 5.5.0

This commit is contained in:
John Preston 2015-07-14 15:21:13 +03:00
parent f37159911c
commit 7d51682edd
38 changed files with 14746 additions and 15905 deletions

View File

@ -105,7 +105,7 @@
<SubSystem>Console</SubSystem>
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;qtharfbuzzngd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;qtharfbuzzngd.lib;qtpcred.lib;qtfreetyped.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
@ -123,7 +123,7 @@
<SubSystem>Console</SubSystem>
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;glu32.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;glu32.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
@ -142,7 +142,7 @@
<SubSystem>Console</SubSystem>
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;glu32.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;glu32.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>

View File

@ -105,7 +105,7 @@
<SubSystem>Console</SubSystem>
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;qtharfbuzzngd.lib;Qt5Widgetsd.lib;Qt5Networkd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;qtharfbuzzngd.lib;qtpcred.lib;qtfreetyped.lib;Qt5Widgetsd.lib;Qt5Networkd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
@ -123,7 +123,7 @@
<SubSystem>Console</SubSystem>
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
@ -140,7 +140,7 @@
<SubSystem>Console</SubSystem>
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>

View File

@ -126,7 +126,7 @@
<SubSystem>Console</SubSystem>
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;qtharfbuzzngd.lib;Qt5Widgetsd.lib;Qt5Networkd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;qtharfbuzzngd.lib;qtpcred.lib;qtfreetyped.lib;Qt5Widgetsd.lib;Qt5Networkd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
@ -145,7 +145,7 @@
<SubSystem>Console</SubSystem>
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
@ -162,7 +162,7 @@
<SubSystem>Console</SubSystem>
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;qtharfbuzzng.lib;qtpcre.lib;qtfreetype.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>

View File

@ -113,7 +113,7 @@
<SubSystem>Console</SubSystem>
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>.\..\..\Libraries\lzma\C\Util\LzmaLib\Release;$(QTDIR)\lib;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatRelease;.\..\..\Libraries\OpenSSL-Win32\lib\VC\static;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;zlibstat.lib;libeay32MT.lib;Qt5Core.lib;LzmaLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;zlibstat.lib;libeay32MT.lib;Qt5Core.lib;qtpcre.lib;LzmaLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ImageHasSafeExceptionHandlers>
</ImageHasSafeExceptionHandlers>

View File

@ -23,6 +23,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
#include <QtCore/QDir>
#include <QtCore/QStringList>
#include <QtCore/QBuffer>
#include <QtCore/QDataStream>
#include <zlib.h>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,35 +1,36 @@
diff --git a/qtbase/mkspecs/win32-msvc2013/qmake.conf b/qtbase/mkspecs/win32-msvc2013/qmake.conf
index 535904a..6d0e9b9 100644
--- a/qtbase/mkspecs/win32-msvc2013/qmake.conf
+++ b/qtbase/mkspecs/win32-msvc2013/qmake.conf
@@ -25,9 +25,9 @@ QMAKE_YACCFLAGS = -d
QMAKE_CFLAGS = -nologo -Zm200 -Zc:wchar_t -FS
diff --git a/qtbase/mkspecs/common/msvc-desktop.conf b/qtbase/mkspecs/common/msvc-desktop.conf
index e638af6..e44ee5e 100644
--- a/qtbase/mkspecs/common/msvc-desktop.conf
+++ b/qtbase/mkspecs/common/msvc-desktop.conf
@@ -28,9 +28,9 @@ QMAKE_YACCFLAGS = -d
QMAKE_CFLAGS = -nologo -Zc:wchar_t
QMAKE_CFLAGS_WARN_ON = -W3
QMAKE_CFLAGS_WARN_OFF = -W0
-QMAKE_CFLAGS_RELEASE = -O2 -MD -Zc:strictStrings
-QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi -Zc:strictStrings
-QMAKE_CFLAGS_RELEASE = -O2 -MD
-QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi
-QMAKE_CFLAGS_DEBUG = -Zi -MDd
+QMAKE_CFLAGS_RELEASE = -O2 -MT -Zc:strictStrings
+QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi -Zc:strictStrings
+QMAKE_CFLAGS_RELEASE = -O2 -MT
+QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi
+QMAKE_CFLAGS_DEBUG = -Zi -MTd
QMAKE_CFLAGS_YACC =
QMAKE_CFLAGS_LTCG = -GL
QMAKE_CFLAGS_MP = -MP
QMAKE_CFLAGS_SSE2 = -arch:SSE2
diff --git a/qtbase/qmake/generators/mac/pbuilder_pbx.cpp b/qtbase/qmake/generators/mac/pbuilder_pbx.cpp
index 0ff4250..9ed555c 100644
index 81bb068..a0fe016 100644
--- a/qtbase/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qtbase/qmake/generators/mac/pbuilder_pbx.cpp
@@ -1445,11 +1445,15 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
plist_in_text = plist_in_text.replace("@TYPEINFO@",
@@ -1500,11 +1500,15 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
plist_in_text.replace("@TYPEINFO@",
(project->isEmpty("QMAKE_PKGINFO_TYPEINFO")
? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4).toQString()));
- QFile plist_out_file("Info.plist");
- QFile plist_out_file(Option::output_dir + "/Info.plist");
- if (plist_out_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ QString plist_dir;
+ if (!project->isEmpty("PLIST_DIR"))
+ plist_dir = project->first("PLIST_DIR").toQString();
+ QString plist_in_filename = QFileInfo(plist_in_file).fileName();
+ QFile plist_out_file(plist_dir + plist_in_filename);
if (plist_out_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ QFile plist_out_file(Option::output_dir + "/" + plist_dir + plist_in_filename);
+ if (plist_out_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream plist_out(&plist_out_file);
plist_out << plist_in_text;
- t << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", "Info.plist") << ";\n";
@ -38,10 +39,10 @@ index 0ff4250..9ed555c 100644
}
}
diff --git a/qtbase/qmake/generators/makefile.cpp b/qtbase/qmake/generators/makefile.cpp
index bf9a9d8..0216f5c 100644
index 4a03faf..2c18c48 100644
--- a/qtbase/qmake/generators/makefile.cpp
+++ b/qtbase/qmake/generators/makefile.cpp
@@ -206,7 +206,7 @@ MakefileGenerator::initOutPaths()
@@ -167,7 +167,7 @@ MakefileGenerator::initOutPaths()
v["PRECOMPILED_DIR"] = v["OBJECTS_DIR"];
static const char * const dirs[] = { "OBJECTS_DIR", "DESTDIR",
"SUBLIBS_DIR", "DLLDESTDIR",
@ -51,7 +52,7 @@ index bf9a9d8..0216f5c 100644
const ProKey dkey(dirs[x]);
if (v[dkey].isEmpty())
diff --git a/qtbase/src/3rdparty/pcre/pcre16_valid_utf16.c b/qtbase/src/3rdparty/pcre/pcre16_valid_utf16.c
index 1987f27..6b36e4f 100644
index 0907653..96f6e19 100644
--- a/qtbase/src/3rdparty/pcre/pcre16_valid_utf16.c
+++ b/qtbase/src/3rdparty/pcre/pcre16_valid_utf16.c
@@ -101,7 +101,7 @@ for (p = string; length-- > 0; p++)
@ -64,10 +65,10 @@ index 1987f27..6b36e4f 100644
/* High surrogate. Must be a followed by a low surrogate. */
if (length == 0)
diff --git a/qtbase/src/corelib/tools/qunicodetables.cpp b/qtbase/src/corelib/tools/qunicodetables.cpp
index 072e8ad..2bf3bfd 100644
index 73dce81..76c6933 100644
--- a/qtbase/src/corelib/tools/qunicodetables.cpp
+++ b/qtbase/src/corelib/tools/qunicodetables.cpp
@@ -5360,7 +5360,7 @@ static const Properties uc_properties[] = {
@@ -5839,7 +5839,7 @@ static const Properties uc_properties[] = {
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 11 },
{ 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 8, 8, 12, 11 },
@ -77,7 +78,7 @@ index 072e8ad..2bf3bfd 100644
{ 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
{ 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
diff --git a/qtbase/src/gui/image/qbmphandler.cpp b/qtbase/src/gui/image/qbmphandler.cpp
index 21c1a2f..f293ef9 100644
index f124ced..eb78a13 100644
--- a/qtbase/src/gui/image/qbmphandler.cpp
+++ b/qtbase/src/gui/image/qbmphandler.cpp
@@ -212,6 +212,9 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
@ -101,7 +102,7 @@ index 21c1a2f..f293ef9 100644
uchar rgb[4];
int rgb_len = t == BMP_OLD ? 3 : 4;
diff --git a/qtbase/src/gui/kernel/qplatformdialoghelper.h b/qtbase/src/gui/kernel/qplatformdialoghelper.h
index e0730cd..00fccad 100644
index 8b2b988..2d1cdd9 100644
--- a/qtbase/src/gui/kernel/qplatformdialoghelper.h
+++ b/qtbase/src/gui/kernel/qplatformdialoghelper.h
@@ -363,6 +363,7 @@ public:
@ -113,7 +114,7 @@ index e0730cd..00fccad 100644
virtual void selectNameFilter(const QString &filter) = 0;
virtual QString selectedNameFilter() const = 0;
diff --git a/qtbase/src/gui/painting/qpaintengine_p.h b/qtbase/src/gui/painting/qpaintengine_p.h
index 312320c..5e82318 100644
index c58662e..468d671 100644
--- a/qtbase/src/gui/painting/qpaintengine_p.h
+++ b/qtbase/src/gui/painting/qpaintengine_p.h
@@ -79,8 +79,18 @@ public:
@ -123,8 +124,8 @@ index 312320c..5e82318 100644
- else
- systemClip = systemTransform.map(systemClip);
+ else {
+ // Transform the system clip region back from device pixels to device-independent pixels before
+ // applying systemTransform, which already has transform from device-independent pixels to device pixels
+// Transform the system clip region back from device pixels to device-independent pixels before
+// applying systemTransform, which already has transform from device-independent pixels to device pixels
+#ifdef Q_OS_MAC
+ QTransform scaleTransform;
+ const qreal invDevicePixelRatio = 1. / pdev->devicePixelRatio();
@ -138,32 +139,30 @@ index 312320c..5e82318 100644
// Make sure we're inside the viewport.
diff --git a/qtbase/src/gui/text/qtextlayout.cpp b/qtbase/src/gui/text/qtextlayout.cpp
index 1ac50d3..3c88caa 100644
index 7da3e84..0829250 100644
--- a/qtbase/src/gui/text/qtextlayout.cpp
+++ b/qtbase/src/gui/text/qtextlayout.cpp
@@ -643,7 +643,10 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
@@ -643,6 +643,9 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
while (oldPos < len && !attributes[oldPos].graphemeBoundary)
oldPos++;
} else {
- if (oldPos < len && d->atWordSeparator(oldPos)) {
+ while (oldPos < len && d->atSpace(oldPos))
+ while (oldPos < len && attributes[oldPos].whiteSpace)
+ oldPos++;
+
+ if (oldPos < len && d->atWordSeparator(oldPos)) {
if (oldPos < len && d->atWordSeparator(oldPos)) {
oldPos++;
while (oldPos < len && d->atWordSeparator(oldPos))
oldPos++;
@@ -651,8 +654,6 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
while (oldPos < len && !d->atSpace(oldPos) && !d->atWordSeparator(oldPos))
while (oldPos < len && !attributes[oldPos].whiteSpace && !d->atWordSeparator(oldPos))
oldPos++;
}
- while (oldPos < len && d->atSpace(oldPos))
- while (oldPos < len && attributes[oldPos].whiteSpace)
- oldPos++;
}
return oldPos;
diff --git a/qtbase/src/gui/text/qtextlayout.h b/qtbase/src/gui/text/qtextlayout.h
index 1e0ab9b..47972d3 100644
index 47dcd38..64c3810 100644
--- a/qtbase/src/gui/text/qtextlayout.h
+++ b/qtbase/src/gui/text/qtextlayout.h
@@ -186,6 +186,8 @@ private:
@ -176,27 +175,29 @@ index 1e0ab9b..47972d3 100644
diff --git a/qtbase/src/network/socket/qnativesocketengine_win.cpp b/qtbase/src/network/socket/qnativesocketengine_win.cpp
index f5943d6..f7787c3 100644
index 72f85c8..a1c2e08 100644
--- a/qtbase/src/network/socket/qnativesocketengine_win.cpp
+++ b/qtbase/src/network/socket/qnativesocketengine_win.cpp
@@ -703,6 +703,12 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
@@ -685,7 +685,13 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
errorDetected = true;
break;
}
- if (value == WSAEADDRNOTAVAIL) {
+ if (value == WSAENETUNREACH) {
+ setError(QAbstractSocket::NetworkError, NetworkUnreachableErrorString);
+ socketState = QAbstractSocket::UnconnectedState;
+ errorDetected = true;
+ break;
+ }
if (value == WSAEADDRNOTAVAIL) {
+ if (value == WSAEADDRNOTAVAIL) {
setError(QAbstractSocket::NetworkError, AddressNotAvailableErrorString);
socketState = QAbstractSocket::UnconnectedState;
errorDetected = true;
diff --git a/qtbase/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/qtbase/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
index 43903ac..efa7014 100644
index 65cdabd..190683e 100644
--- a/qtbase/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
+++ b/qtbase/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
@@ -213,6 +213,78 @@ void QBasicFontDatabase::releaseHandle(void *handle)
@@ -198,6 +198,78 @@ void QBasicFontDatabase::releaseHandle(void *handle)
extern FT_Library qt_getFreetype();
@ -275,12 +276,12 @@ index 43903ac..efa7014 100644
QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file, QSupportedWritingSystems *supportedWritingSystems)
{
FT_Library library = qt_getFreetype();
@@ -224,9 +296,9 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt
@@ -209,9 +281,9 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt
FT_Face face;
FT_Error error;
if (!fontData.isEmpty()) {
- error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
+ error = __ft_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
+ error = __ft_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
} else {
- error = FT_New_Face(library, file.constData(), index, &face);
+ error = __ft_New_Face(library, file.constData(), index, &face);
@ -288,10 +289,10 @@ index 43903ac..efa7014 100644
if (error != FT_Err_Ok) {
qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
diff --git a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index 5dec1d0..f4d6fcd 100644
index 112bb8e..9f1df70 100644
--- a/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/qtbase/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -341,6 +341,15 @@ static void populateFromPattern(FcPattern *pattern)
@@ -373,6 +373,15 @@ static void populateFromPattern(FcPattern *pattern)
return;
familyName = QString::fromUtf8((const char *)value);
@ -307,7 +308,7 @@ index 5dec1d0..f4d6fcd 100644
slant_value = FC_SLANT_ROMAN;
weight_value = FC_WEIGHT_REGULAR;
@@ -742,6 +751,15 @@ QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData,
@@ -781,6 +790,15 @@ QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData,
FcChar8 *fam = 0;
if (FcPatternGetString(pattern, FC_FAMILY, 0, &fam) == FcResultMatch) {
QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
@ -324,10 +325,10 @@ index 5dec1d0..f4d6fcd 100644
}
populateFromPattern(pattern);
diff --git a/qtbase/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/qtbase/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 9f2ff10..fe87ca1 100644
index be70092..1594dac 100644
--- a/qtbase/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/qtbase/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -257,6 +257,10 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
@@ -263,6 +263,10 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
fd->foundryName = QStringLiteral("CoreText");
fd->familyName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
@ -339,10 +340,10 @@ index 9f2ff10..fe87ca1 100644
fd->weight = QFont::Normal;
fd->style = QFont::StyleNormal;
diff --git a/qtbase/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/qtbase/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 9f7609f..5df1514 100644
index f3a0216..643ebdd 100644
--- a/qtbase/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/qtbase/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -216,7 +216,7 @@ static void cleanupCocoaApplicationDelegate()
@@ -210,7 +210,7 @@ QT_END_NAMESPACE
if (reflectionDelegate) {
if ([reflectionDelegate respondsToSelector:@selector(applicationShouldTerminate:)])
return [reflectionDelegate applicationShouldTerminate:sender];
@ -352,25 +353,18 @@ index 9f7609f..5df1514 100644
if ([self canQuit]) {
diff --git a/qtbase/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/qtbase/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index e449fd3..7f7bd24 100644
index 713758c..9c695aa 100644
--- a/qtbase/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/qtbase/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -102,7 +102,7 @@ QT_USE_NAMESPACE
@@ -94,6 +94,7 @@ QT_USE_NAMESPACE
QCocoaSystemTrayIcon *systray;
NSStatusItem *item;
QCocoaMenu *menu;
- bool menuVisible;
+ bool menuVisible, iconSelected;
+ bool menuVisible, iconSelected;
QIcon icon;
QT_MANGLE_NAMESPACE(QNSImageView) *imageCell;
}
@@ -202,13 +202,11 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
m_sys->item->icon = icon;
- const bool menuVisible = m_sys->item->menu && m_sys->item->menuVisible;
-
// The reccomended maximum title bar icon height is 18 points
@@ -197,7 +198,7 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
// (device independent pixels). The menu height on past and
// current OS X versions is 22 points. Provide some future-proofing
// by deriving the icon height from the menu height.
@ -379,32 +373,51 @@ index e449fd3..7f7bd24 100644
const int menuHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
const int maxImageHeight = menuHeight - padding;
@@ -218,7 +216,7 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
@@ -207,8 +208,9 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
// devicePixelRatio for the "best" screen on the system.
qreal devicePixelRatio = qApp->devicePixelRatio();
const int maxPixmapHeight = maxImageHeight * devicePixelRatio;
- const QIcon::Mode mode = menuVisible ? QIcon::Selected : QIcon::Normal;
+ const QIcon::Mode mode = m_sys->item->iconSelected ? QIcon::Selected : QIcon::Normal;
+ const QIcon::Mode mode = m_sys->item->iconSelected ? QIcon::Selected : QIcon::Normal;
QSize selectedSize;
Q_FOREACH (const QSize& size, sortByHeight(icon.availableSizes(mode))) {
- Q_FOREACH (const QSize& size, sortByHeight(icon.availableSizes())) {
+ Q_FOREACH (const QSize& size, sortByHeight(icon.availableSizes(mode))) {
// Select a pixmap based on the height. We want the largest pixmap
@@ -381,6 +379,7 @@ QT_END_NAMESPACE
// with a height smaller or equal to maxPixmapHeight. The pixmap
// may rectangular; assume it has a reasonable size. If there is
@@ -224,9 +226,9 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
// Handle SVG icons, which do not return anything for availableSizes().
if (!selectedSize.isValid())
- selectedSize = icon.actualSize(QSize(maxPixmapHeight, maxPixmapHeight));
+ selectedSize = icon.actualSize(QSize(maxPixmapHeight, maxPixmapHeight), mode);
- QPixmap pixmap = icon.pixmap(selectedSize);
+ QPixmap pixmap = icon.pixmap(selectedSize, mode);
// Draw a low-resolution icon if there is not enough pixels for a retina
// icon. This prevents showing a small icon on retina displays.
@@ -373,6 +375,10 @@ QT_END_NAMESPACE
Q_UNUSED(notification);
down = NO;
+ parent->iconSelected = false;
parent->systray->updateIcon(parent->icon);
parent->menuVisible = false;
+ parent->systray->updateIcon(parent->icon);
+ parent->menuVisible = false;
+
[self setNeedsDisplay:YES];
}
@@ -393,6 +392,7 @@ QT_END_NAMESPACE
@@ -381,6 +387,9 @@ QT_END_NAMESPACE
down = YES;
int clickCount = [mouseEvent clickCount];
[self setNeedsDisplay:YES];
+ parent->iconSelected = (clickCount != 2) && parent->menu;
parent->systray->updateIcon(parent->icon);
+
+ parent->iconSelected = (clickCount != 2) && parent->menu;
+ parent->systray->updateIcon(parent->icon);
if (clickCount == 2) {
@@ -411,6 +411,10 @@ QT_END_NAMESPACE
[self menuTrackingDone:nil];
@@ -398,6 +407,10 @@ QT_END_NAMESPACE
-(void)mouseUp:(NSEvent *)mouseEvent
{
Q_UNUSED(mouseEvent);
@ -415,7 +428,7 @@ index e449fd3..7f7bd24 100644
[self menuTrackingDone:nil];
}
@@ -422,6 +426,10 @@ QT_END_NAMESPACE
@@ -409,6 +422,10 @@ QT_END_NAMESPACE
-(void)rightMouseUp:(NSEvent *)mouseEvent
{
Q_UNUSED(mouseEvent);
@ -426,20 +439,36 @@ index e449fd3..7f7bd24 100644
[self menuTrackingDone:nil];
}
@@ -437,7 +445,7 @@ QT_END_NAMESPACE
@@ -424,7 +441,7 @@ QT_END_NAMESPACE
}
-(void)drawRect:(NSRect)rect {
- [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:down];
+ [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:parent->menu ? down : NO];
+ [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:parent->menu ? down : NO];
[super drawRect:rect];
}
@end
@@ -437,6 +454,7 @@ QT_END_NAMESPACE
if (self) {
item = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
menu = 0;
+ menuVisible = false;
systray = sys;
imageCell = [[QNSImageView alloc] initWithParent:self];
[item setView: imageCell];
@@ -481,6 +499,7 @@ QT_END_NAMESPACE
selector:@selector(menuTrackingDone:)
name:NSMenuDidEndTrackingNotification
object:m];
+ menuVisible = true;
[item popUpStatusItemMenu: m];
}
}
diff --git a/qtbase/src/plugins/platforms/cocoa/qcocoawindow.mm b/qtbase/src/plugins/platforms/cocoa/qcocoawindow.mm
index 6656212..486fda0 100644
index 92fc66a..d18884a 100644
--- a/qtbase/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/qtbase/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -175,7 +175,7 @@ static void selectNextKeyWindow(NSWindow *currentKeyWindow)
@@ -142,7 +142,7 @@ static bool isMouseEvent(NSEvent *ev)
if (!self.window.delegate)
return; // Already detached, pending NSAppKitDefined event
@ -448,7 +477,7 @@ index 6656212..486fda0 100644
NSPoint loc = [theEvent locationInWindow];
NSRect windowFrame = [self.window convertRectFromScreen:[self.window frame]];
NSRect contentFrame = [[self.window contentView] frame];
@@ -918,6 +918,14 @@ void QCocoaWindow::setWindowFilePath(const QString &filePath)
@@ -924,6 +924,14 @@ void QCocoaWindow::setWindowFilePath(const QString &filePath)
[m_nsWindow setRepresentedFilename: fi.exists() ? QCFString::toNSString(filePath) : @""];
}
@ -463,7 +492,7 @@ index 6656212..486fda0 100644
void QCocoaWindow::setWindowIcon(const QIcon &icon)
{
QCocoaAutoReleasePool pool;
@@ -933,7 +941,8 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon)
@@ -939,7 +947,8 @@ void QCocoaWindow::setWindowIcon(const QIcon &icon)
if (icon.isNull()) {
[iconButton setImage:nil];
} else {
@ -474,33 +503,34 @@ index 6656212..486fda0 100644
[iconButton setImage:image];
[image release];
diff --git a/qtbase/src/plugins/platforms/cocoa/qnsview.mm b/qtbase/src/plugins/platforms/cocoa/qnsview.mm
index 6993407..0357bf4 100644
index d44cdb3..cfc8705 100644
--- a/qtbase/src/plugins/platforms/cocoa/qnsview.mm
+++ b/qtbase/src/plugins/platforms/cocoa/qnsview.mm
@@ -1321,7 +1321,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
@@ -1348,7 +1348,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
// On 10.8 and above, MayBegin is likely to happen. We treat it the same as an actual begin.
- if (phase == NSEventPhaseMayBegin)
+ if (phase == NSEventPhaseMayBegin || phase == NSEventPhaseBegan)
- if (phase == NSEventPhaseMayBegin) {
+ if (phase == NSEventPhaseMayBegin || phase == NSEventPhaseBegan) {
m_scrolling = true;
ph = Qt::ScrollBegin;
} else
#endif
@@ -1451,6 +1451,9 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
}
@@ -1489,6 +1489,10 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
&& qtKey == Qt::Key_Period) {
[self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)];
return YES;
+ } else if ([nsevent modifierFlags] & NSControlKeyMask && (qtKey == Qt::Key_Tab || qtKey == Qt::Key_Backtab)) {
+ } else if ([nsevent modifierFlags] & NSControlKeyMask
+ && (qtKey == Qt::Key_Tab || qtKey == Qt::Key_Backtab)) {
+ [self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)];
+ return YES;
}
}
return [super performKeyEquivalent:nsevent];
diff --git a/qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index f1f472b..97819dd 100644
index da0ba27..1d42b79 100644
--- a/qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/qtbase/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -710,6 +710,8 @@ public:
@@ -713,6 +713,8 @@ public:
QList<QUrl> selectedFiles() const;
void setSelectedFiles(const QList<QUrl> &);
QString selectedFile() const;
@ -509,7 +539,7 @@ index f1f472b..97819dd 100644
private:
class Data : public QSharedData {
@@ -717,6 +719,7 @@ private:
@@ -720,6 +722,7 @@ private:
QUrl directory;
QString selectedNameFilter;
QList<QUrl> selectedFiles;
@ -517,7 +547,7 @@ index f1f472b..97819dd 100644
QMutex mutex;
};
QExplicitlySharedDataPointer<Data> m_data;
@@ -770,6 +773,20 @@ inline void QWindowsFileDialogSharedData::setSelectedFiles(const QList<QUrl> &ur
@@ -773,6 +776,20 @@ inline void QWindowsFileDialogSharedData::setSelectedFiles(const QList<QUrl> &ur
m_data->selectedFiles = urls;
}
@ -538,7 +568,7 @@ index f1f472b..97819dd 100644
inline void QWindowsFileDialogSharedData::fromOptions(const QSharedPointer<QFileDialogOptions> &o)
{
QMutexLocker (&m_data->mutex);
@@ -893,6 +910,7 @@ public:
@@ -896,6 +913,7 @@ public:
// Return the result for tracking in OnFileOk(). Differs from selection for
// example by appended default suffixes, etc.
virtual QList<QUrl> dialogResult() const = 0;
@ -546,21 +576,25 @@ index f1f472b..97819dd 100644
inline void onFolderChange(IShellItem *);
inline void onSelectionChange();
@@ -1286,7 +1304,12 @@ void QWindowsNativeFileDialogBase::setLabelText(QFileDialogOptions::DialogLabel
void QWindowsNativeFileDialogBase::selectFile(const QString &fileName) const
@@ -1332,8 +1350,15 @@ void QWindowsNativeFileDialogBase::selectFile(const QString &fileName) const
{
- m_fileDialog->SetFileName((wchar_t*)fileName.utf16());
+ QString file = QDir::toNativeSeparators(fileName);
+ int lastBackSlash = file.lastIndexOf(QChar::fromLatin1('\\'));
+ if (lastBackSlash >= 0) {
+ file = file.mid(lastBackSlash + 1);
// Hack to prevent CLSIDs from being set as file name due to
// QFileDialogPrivate::initialSelection() being QString-based.
- if (!isClsid(fileName))
- m_fileDialog->SetFileName((wchar_t*)fileName.utf16());
+ if (!isClsid(fileName))
+ {
+ QString file = QDir::toNativeSeparators(fileName);
+ int lastBackSlash = file.lastIndexOf(QChar::fromLatin1('\\'));
+ if (lastBackSlash >= 0) {
+ file = file.mid(lastBackSlash + 1);
+ }
+ m_fileDialog->SetFileName((wchar_t*)file.utf16());;
+ }
+ m_fileDialog->SetFileName((wchar_t*)file.utf16());;
}
// Return the index of the selected filter, accounting for QFileDialog
@@ -1356,6 +1379,7 @@ bool QWindowsNativeFileDialogBase::onFileOk()
@@ -1403,6 +1428,7 @@ bool QWindowsNativeFileDialogBase::onFileOk()
{
// Store selected files as GetResults() returns invalid data after the dialog closes.
m_data.setSelectedFiles(dialogResult());
@ -568,7 +602,7 @@ index f1f472b..97819dd 100644
return true;
}
@@ -1484,6 +1508,7 @@ public:
@@ -1531,6 +1557,7 @@ public:
QWindowsNativeFileDialogBase(data) {}
virtual QList<QUrl> selectedFiles() const;
virtual QList<QUrl> dialogResult() const;
@ -576,7 +610,7 @@ index f1f472b..97819dd 100644
private:
inline IFileOpenDialog *openFileDialog() const
@@ -1499,6 +1524,54 @@ QList<QUrl> QWindowsNativeOpenFileDialog::dialogResult() const
@@ -1546,6 +1573,54 @@ QList<QUrl> QWindowsNativeOpenFileDialog::dialogResult() const
return result;
}
@ -631,7 +665,7 @@ index f1f472b..97819dd 100644
QList<QUrl> QWindowsNativeOpenFileDialog::selectedFiles() const
{
QList<QUrl> result;
@@ -1562,6 +1635,7 @@ public:
@@ -1609,6 +1684,7 @@ public:
virtual QUrl directory() const Q_DECL_OVERRIDE;
virtual void selectFile(const QUrl &filename) Q_DECL_OVERRIDE;
virtual QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
@ -639,7 +673,7 @@ index f1f472b..97819dd 100644
virtual void setFilter() Q_DECL_OVERRIDE;
virtual void selectNameFilter(const QString &filter) Q_DECL_OVERRIDE;
virtual QString selectedNameFilter() const Q_DECL_OVERRIDE;
@@ -1655,6 +1729,11 @@ QList<QUrl> QWindowsFileDialogHelper::selectedFiles() const
@@ -1702,6 +1778,11 @@ QList<QUrl> QWindowsFileDialogHelper::selectedFiles() const
return m_data.selectedFiles();
}
@ -651,7 +685,7 @@ index f1f472b..97819dd 100644
void QWindowsFileDialogHelper::setFilter()
{
qCDebug(lcQpaDialogs) << __FUNCTION__;
@@ -1945,6 +2024,7 @@ public:
@@ -1992,6 +2073,7 @@ public:
virtual QUrl directory() const Q_DECL_OVERRIDE;
virtual void selectFile(const QUrl &url) Q_DECL_OVERRIDE;
virtual QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
@ -659,7 +693,7 @@ index f1f472b..97819dd 100644
virtual void setFilter() Q_DECL_OVERRIDE {}
virtual void selectNameFilter(const QString &) Q_DECL_OVERRIDE;
virtual QString selectedNameFilter() const Q_DECL_OVERRIDE;
@@ -1988,6 +2068,11 @@ QList<QUrl> QWindowsXpFileDialogHelper::selectedFiles() const
@@ -2035,6 +2117,11 @@ QList<QUrl> QWindowsXpFileDialogHelper::selectedFiles() const
return m_data.selectedFiles();
}
@ -671,55 +705,11 @@ index f1f472b..97819dd 100644
void QWindowsXpFileDialogHelper::selectNameFilter(const QString &f)
{
m_data.setSelectedNameFilter(f); // Dialog cannot be updated at run-time.
diff --git a/qtbase/src/plugins/platforms/windows/qwindowskeymapper.cpp b/qtbase/src/plugins/platforms/windows/qwindowskeymapper.cpp
index ff9ad18..3fd0848 100644
--- a/qtbase/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/qtbase/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -537,17 +537,16 @@ static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer,
Q_ASSERT(vk > 0 && vk < 256);
int code = 0;
QChar unicodeBuffer[5];
- // While key combinations containing alt and ctrl might trigger the third assignment of a key
- // (for example "alt+ctrl+q" causes '@' on a German layout), ToUnicode often does not return the
- // wanted character if only the ctrl modifier is used. Thus we unset this modifier temporarily
- // if it is not used together with alt.
- const unsigned char controlState = kbdBuffer[VK_MENU] ? 0 : kbdBuffer[VK_CONTROL];
- if (controlState)
- kbdBuffer[VK_CONTROL] = 0;
- int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
- if (controlState)
- kbdBuffer[VK_CONTROL] = controlState;
- if (res)
+ int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
+ // When Ctrl modifier is used ToUnicode does not return correct values. In order to assign the
+ // right key the control modifier is removed for just that function if the previous call failed.
+ if (res == 0 && kbdBuffer[VK_CONTROL]) {
+ const unsigned char controlState = kbdBuffer[VK_CONTROL];
+ kbdBuffer[VK_CONTROL] = 0;
+ res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
+ kbdBuffer[VK_CONTROL] = controlState;
+ }
+ if (res)
code = unicodeBuffer[0].toUpper().unicode();
// Qt::Key_*'s are not encoded below 0x20, so try again, and DEL keys (0x7f) is encoded with a
@@ -833,7 +832,10 @@ bool QWindowsKeyMapper::translateMultimediaKeyEventInternal(QWindow *window, con
const int qtKey = CmdTbl[cmd];
sendExtendedPressRelease(receiver, qtKey, Qt::KeyboardModifier(state), 0, 0, 0);
- return true;
+ // QTBUG-43343: Make sure to return false if Qt does not handle the key, otherwise,
+ // the keys are not passed to the active media player.
+ const QKeySequence sequence(Qt::Modifier(state) + qtKey);
+ return QGuiApplicationPrivate::instance()->shortcutMap.hasShortcutForKeySequence(sequence);
#else
Q_UNREACHABLE();
return false;
diff --git a/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp b/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp
index 8a80729..16fda26 100644
index 543c081..d80429b 100644
--- a/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -943,7 +943,7 @@ void QWindowsWindow::destroyWindow()
@@ -973,7 +973,7 @@ void QWindowsWindow::destroyWindow()
// Clear any transient child relationships as Windows will otherwise destroy them (QTBUG-35499, QTBUG-36666)
if (QWindow *transientChild = findTransientChild(window()))
if (QWindowsWindow *tw = QWindowsWindow::baseWindowOf(transientChild))
@ -728,7 +718,7 @@ index 8a80729..16fda26 100644
QWindowsContext *context = QWindowsContext::instance();
if (context->windowUnderMouse() == window())
context->clearWindowUnderMouse();
@@ -1144,11 +1144,24 @@ void QWindowsWindow::updateTransientParent() const
@@ -1178,11 +1178,24 @@ void QWindowsWindow::updateTransientParent() const
if (const QWindowsWindow *tw = QWindowsWindow::baseWindowOf(tp))
if (!tw->testFlag(WithinDestroy)) // Prevent destruction by parent window (QTBUG-35499, QTBUG-36666)
newTransientParent = tw->handle();
@ -755,10 +745,10 @@ index 8a80729..16fda26 100644
{
// QWidget-attribute Qt::WA_ShowWithoutActivating .
diff --git a/qtbase/src/plugins/platforms/windows/qwindowswindow.h b/qtbase/src/plugins/platforms/windows/qwindowswindow.h
index 71debf2..4fa2e5d 100644
index fff90b4..71d060b 100644
--- a/qtbase/src/plugins/platforms/windows/qwindowswindow.h
+++ b/qtbase/src/plugins/platforms/windows/qwindowswindow.h
@@ -268,6 +268,7 @@ private:
@@ -273,6 +273,7 @@ private:
inline void setWindowState_sys(Qt::WindowState newState);
inline void setParent_sys(const QPlatformWindow *parent);
inline void updateTransientParent() const;
@ -767,10 +757,10 @@ index 71debf2..4fa2e5d 100644
inline bool isDropSiteEnabled() const { return m_dropTarget != 0; }
void setDropSiteEnabled(bool enabled);
diff --git a/qtbase/src/widgets/dialogs/qfiledialog.cpp b/qtbase/src/widgets/dialogs/qfiledialog.cpp
index 6065ad0..03fad7a 100644
index a9d5574..ea8aa43 100644
--- a/qtbase/src/widgets/dialogs/qfiledialog.cpp
+++ b/qtbase/src/widgets/dialogs/qfiledialog.cpp
@@ -1219,6 +1219,14 @@ QList<QUrl> QFileDialogPrivate::userSelectedFiles() const
@@ -1199,6 +1199,14 @@ QList<QUrl> QFileDialogPrivate::userSelectedFiles() const
return files;
}
@ -782,10 +772,10 @@ index 6065ad0..03fad7a 100644
+ return QByteArray();
+}
+
QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList filesToFix) const
QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList &filesToFix) const
{
QStringList files;
@@ -1282,6 +1290,13 @@ QStringList QFileDialog::selectedFiles() const
@@ -1262,6 +1270,13 @@ QStringList QFileDialog::selectedFiles() const
return files;
}
@ -800,10 +790,10 @@ index 6065ad0..03fad7a 100644
Returns a list of urls containing the selected files in the dialog.
If no files are selected, or the mode is not ExistingFiles or
diff --git a/qtbase/src/widgets/dialogs/qfiledialog.h b/qtbase/src/widgets/dialogs/qfiledialog.h
index 70e498a..b13e8b2 100644
index 95209bc..0dca0ef 100644
--- a/qtbase/src/widgets/dialogs/qfiledialog.h
+++ b/qtbase/src/widgets/dialogs/qfiledialog.h
@@ -103,6 +103,7 @@ public:
@@ -106,6 +106,7 @@ public:
void selectFile(const QString &filename);
QStringList selectedFiles() const;
@ -812,7 +802,7 @@ index 70e498a..b13e8b2 100644
void selectUrl(const QUrl &url);
QList<QUrl> selectedUrls() const;
diff --git a/qtbase/src/widgets/dialogs/qfiledialog_p.h b/qtbase/src/widgets/dialogs/qfiledialog_p.h
index cc2f481..cf70355 100644
index f610e46..16fa44e 100644
--- a/qtbase/src/widgets/dialogs/qfiledialog_p.h
+++ b/qtbase/src/widgets/dialogs/qfiledialog_p.h
@@ -123,6 +123,7 @@ public:
@ -820,10 +810,10 @@ index cc2f481..cf70355 100644
QStringList typedFiles() const;
QList<QUrl> userSelectedFiles() const;
+ QByteArray userSelectedRemoteContent() const;
QStringList addDefaultSuffixToFiles(const QStringList filesToFix) const;
QStringList addDefaultSuffixToFiles(const QStringList &filesToFix) const;
QList<QUrl> addDefaultSuffixToUrls(const QList<QUrl> &urlsToFix) const;
bool removeDirectory(const QString &path);
@@ -250,6 +251,7 @@ public:
@@ -256,6 +257,7 @@ public:
QUrl directory_sys() const;
void selectFile_sys(const QUrl &filename);
QList<QUrl> selectedFiles_sys() const;
@ -831,7 +821,7 @@ index cc2f481..cf70355 100644
void setFilter_sys();
void selectNameFilter_sys(const QString &filter);
QString selectedNameFilter_sys() const;
@@ -387,6 +389,13 @@ inline QList<QUrl> QFileDialogPrivate::selectedFiles_sys() const
@@ -393,6 +395,13 @@ inline QList<QUrl> QFileDialogPrivate::selectedFiles_sys() const
return QList<QUrl>();
}
@ -846,95 +836,54 @@ index cc2f481..cf70355 100644
{
if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
diff --git a/qtbase/src/widgets/kernel/qwidget.cpp b/qtbase/src/widgets/kernel/qwidget.cpp
index 315d615..e99b1c3 100644
index e701eb0..1bdaff5 100644
--- a/qtbase/src/widgets/kernel/qwidget.cpp
+++ b/qtbase/src/widgets/kernel/qwidget.cpp
@@ -8674,7 +8674,7 @@ bool QWidget::event(QEvent *event)
@@ -8683,7 +8683,7 @@ bool QWidget::event(QEvent *event)
case QEvent::KeyPress: {
QKeyEvent *k = (QKeyEvent *)event;
bool res = false;
- if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) { //### Add MetaModifier?
+ if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier))) { //### Add MetaModifier?
+ if (!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier))) { //### Add MetaModifier?
if (k->key() == Qt::Key_Backtab
|| (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier)))
res = focusNextPrevChild(false);
diff --git a/qtbase/src/widgets/util/qsystemtrayicon.cpp b/qtbase/src/widgets/util/qsystemtrayicon.cpp
index 7d04cab..53c2856 100644
index dc2737c..aa9bc91 100644
--- a/qtbase/src/widgets/util/qsystemtrayicon.cpp
+++ b/qtbase/src/widgets/util/qsystemtrayicon.cpp
@@ -710,7 +710,9 @@ void QSystemTrayIconPrivate::updateMenu_sys_qpa()
menu->setPlatformMenu(platformMenu);
}
@@ -711,6 +711,8 @@ void QSystemTrayIconPrivate::updateMenu_sys_qpa()
if (menu) {
addPlatformMenu(menu);
qpa_sys->updateMenu(menu->platformMenu());
- }
+ } else {
+ qpa_sys->updateMenu(0);
+ }
}
}
void QSystemTrayIconPrivate::updateToolTip_sys_qpa()
diff --git a/qtbase/src/widgets/widgets/qwidgetlinecontrol.cpp b/qtbase/src/widgets/widgets/qwidgetlinecontrol.cpp
index e6385ba..8e1543e 100644
index 759e41a..fbd3064 100644
--- a/qtbase/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/qtbase/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -1870,7 +1870,7 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
if (unknown && !isReadOnly()) {
@@ -1884,7 +1884,7 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
&& event->modifiers() != Qt::ControlModifier
&& event->modifiers() != (Qt::ControlModifier | Qt::ShiftModifier)) {
QString t = event->text();
- if (!t.isEmpty() && t.at(0).isPrint()) {
+ if (!t.isEmpty() && (t.at(0).isPrint() || t.at(0).unicode() == 0x200C || t.at(0).unicode() == 0x200D)) {
+ if (!t.isEmpty() && (t.at(0).isPrint() || t.at(0).unicode() == 0x200C || t.at(0).unicode() == 0x200D)) {
insert(t);
#ifndef QT_NO_COMPLETER
complete(event->key());
diff --git a/qtbase/src/widgets/widgets/qwidgettextcontrol.cpp b/qtbase/src/widgets/widgets/qwidgettextcontrol.cpp
index dfec6a1..a1be4a1 100644
index faa63cb..f3de539 100644
--- a/qtbase/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/qtbase/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -1340,7 +1340,7 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
process:
{
@@ -1348,7 +1348,7 @@ process:
return;
}
QString text = e->text();
- if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t'))) {
+ if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t') || text.at(0).unicode() == 0x200C || text.at(0).unicode() == 0x200D)) {
+ if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t') || text.at(0).unicode() == 0x200C || text.at(0).unicode() == 0x200D)) {
if (overwriteMode
// no need to call deleteChar() if we have a selection, insertText
// does it already
diff --git a/qtimageformats/src/3rdparty/libwebp/src/dec/vp8l.c b/qtimageformats/src/3rdparty/libwebp/src/dec/vp8l.c
index ea0254d..93d9dc4 100644
--- a/qtimageformats/src/3rdparty/libwebp/src/dec/vp8l.c
+++ b/qtimageformats/src/3rdparty/libwebp/src/dec/vp8l.c
@@ -12,7 +12,6 @@
// Authors: Vikas Arora (vikaas.arora@gmail.com)
// Jyrki Alakuijala (jyrki@google.com)
-#include <stdio.h>
#include <stdlib.h>
#include "./alphai.h"
#include "./vp8li.h"
@@ -740,6 +739,7 @@ static int DecodeAlphaData(VP8LDecoder* const dec, uint8_t* const data,
const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
const int mask = hdr->huffman_mask_;
assert(htree_group != NULL);
+ assert(pos < end);
assert(last_row <= height);
assert(Is8bOptimizable(hdr));
@@ -830,6 +830,7 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
(hdr->color_cache_size_ > 0) ? &hdr->color_cache_ : NULL;
const int mask = hdr->huffman_mask_;
assert(htree_group != NULL);
+ assert(src < src_end);
assert(src_last <= src_end);
while (!br->eos_ && src < src_last) {
@@ -1294,6 +1295,10 @@ int VP8LDecodeAlphaImageStream(ALPHDecoder* const alph_dec, int last_row) {
assert(dec->action_ == READ_DATA);
assert(last_row <= dec->height_);
+ if (dec->last_pixel_ == dec->width_ * dec->height_) {
+ return 1; // Done
+ }
+
// Decode (with special row processing).
return alph_dec->use_8b_decode ?
DecodeAlphaData(dec, (uint8_t*)dec->pixels_, dec->width_, dec->height_,

View File

@ -1,60 +1,59 @@
#
# qmake configuration for win32-msvc2013
#
# Written for Microsoft Visual C++ 2013
# qmake configuration for Microsoft Visual Studio C/C++ Compiler
# This mkspec is used for all win32-msvcXXXX specs
#
MAKEFILE_GENERATOR = MSBUILD
isEmpty(MSC_VER)|isEmpty(MSVC_VER): error("Source mkspec must set both MSC_VER and MSVC_VER.")
#
# Baseline: Visual Studio 2005 (8.0), VC++ 14.0
#
MAKEFILE_GENERATOR = MSVC.NET
QMAKE_PLATFORM = win32
QMAKE_COMPILER = msvc
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
DEFINES += UNICODE WIN32
MSVC_VER = 12.0
QMAKE_COMPILER_DEFINES += _MSC_VER=1800 _WIN32
QMAKE_COMPILER_DEFINES += _MSC_VER=$$MSC_VER _WIN32
contains(QMAKE_TARGET.arch, x86_64) {
DEFINES += WIN64
QMAKE_COMPILER_DEFINES += _WIN64
}
QMAKE_COMPILER = msvc
QMAKE_CC = cl
QMAKE_LEX = flex
QMAKE_LEXFLAGS =
QMAKE_YACC = byacc
QMAKE_YACCFLAGS = -d
QMAKE_CFLAGS = -nologo -Zm200 -Zc:wchar_t -FS
QMAKE_CFLAGS = -nologo -Zc:wchar_t
QMAKE_CFLAGS_WARN_ON = -W3
QMAKE_CFLAGS_WARN_OFF = -W0
QMAKE_CFLAGS_RELEASE = -O2 -MT -Zc:strictStrings
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi -Zc:strictStrings
QMAKE_CFLAGS_RELEASE = -O2 -MT
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MT -Zi
QMAKE_CFLAGS_DEBUG = -Zi -MTd
QMAKE_CFLAGS_YACC =
QMAKE_CFLAGS_LTCG = -GL
QMAKE_CFLAGS_MP = -MP
QMAKE_CFLAGS_SSE2 = -arch:SSE2
QMAKE_CFLAGS_SSE3 = -arch:SSE2
QMAKE_CFLAGS_SSSE3 = -arch:SSE2
QMAKE_CFLAGS_SSE4_1 = -arch:SSE2
QMAKE_CFLAGS_SSE4_2 = -arch:SSE2
QMAKE_CFLAGS_AVX = -arch:AVX
QMAKE_CFLAGS_AVX2 = -arch:AVX
QMAKE_CXX = $$QMAKE_CC
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -w34100 -w34189
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -w34100 -w34189 -w44996
QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
QMAKE_CXXFLAGS_MP = $$QMAKE_CFLAGS_MP
QMAKE_CXXFLAGS_STL_ON = -EHsc
QMAKE_CXXFLAGS_STL_OFF =
QMAKE_CXXFLAGS_RTTI_ON = -GR
QMAKE_CXXFLAGS_RTTI_OFF =
QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHsc
QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -D_HAS_EXCEPTIONS=0
QMAKE_CXXFLAGS_EXCEPTIONS_OFF =
QMAKE_INCDIR =
@ -70,8 +69,8 @@ QMAKE_LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT
QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO
QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF /INCREMENTAL:NO
QMAKE_LFLAGS_DEBUG = /DEBUG
QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE@QMAKE_SUBSYSTEM_SUFFIX@
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS@QMAKE_SUBSYSTEM_SUFFIX@
QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS
QMAKE_LFLAGS_EXE = \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\"
QMAKE_LFLAGS_DLL = /DLL
QMAKE_LFLAGS_LTCG = /LTCG
@ -91,9 +90,58 @@ QMAKE_IDL = midl
QMAKE_LIB = lib /NOLOGO
QMAKE_RC = rc
include(../common/shell-win32.conf)
VCPROJ_EXTENSION = .vcxproj
VCPROJ_EXTENSION = .vcproj
VCSOLUTION_EXTENSION = .sln
VCPROJ_KEYWORD = Qt4VSv1.0
load(qt_config)
#
# Version-specific changes
#
greaterThan(MSC_VER, 1499) {
# Visual Studio 2008 (9.0) / Visual C++ 15.0 and up
QMAKE_CFLAGS_MP = -MP
QMAKE_CXXFLAGS_MP = $$QMAKE_CFLAGS_MP
}
greaterThan(MSC_VER, 1599) {
# Visual Studio 2010 (10.0) / Visual C++ 16.0 and up
MAKEFILE_GENERATOR = MSBUILD
QMAKE_CFLAGS_AVX = -arch:AVX
QMAKE_CFLAGS_AVX2 = -arch:AVX
VCPROJ_EXTENSION = .vcxproj
}
greaterThan(MSC_VER, 1699) {
# Visual Studio 2012 (11.0) / Visual C++ 17.0 and up
QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -D_HAS_EXCEPTIONS=0
QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE@QMAKE_SUBSYSTEM_SUFFIX@
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS@QMAKE_SUBSYSTEM_SUFFIX@
QT_CONFIG += c++11
CONFIG += c++11
}
greaterThan(MSC_VER, 1799) {
# Visual Studio 2013 (12.0) / Visual C++ 18.0 and up
QMAKE_CFLAGS += -FS
QMAKE_CXXFLAGS += -FS
equals(MSC_VER, 1800) {
QMAKE_CFLAGS_RELEASE += -Zc:strictStrings
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -Zc:strictStrings
QMAKE_CXXFLAGS_RELEASE += -Zc:strictStrings
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += -Zc:strictStrings
}
}
greaterThan(MSC_VER, 1899) {
# Visual Studio 2015 (14.0) / Visual C++ 19.0 and up
QMAKE_CFLAGS += -Zc:strictStrings
QMAKE_CFLAGS_WARN_ON += -w44456 -w44457 -w44458
QMAKE_CFLAGS_AVX2 = -arch:AVX2
QMAKE_CXXFLAGS += -Zc:strictStrings
QMAKE_CXXFLAGS_WARN_ON += -w44456 -w44457 -w44458
}
unset(MSC_VER)

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the qmake application of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -105,7 +105,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
{
if(project->isActiveConfig("generate_pbxbuild_makefile")) {
QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"),
qmake_getpwd());
FileFixifyToIndir);
QFile mkwrapf(mkwrap);
if(mkwrapf.open(QIODevice::WriteOnly | QIODevice::Text)) {
debug_msg(1, "pbuilder: Creating file: %s", mkwrap.toLatin1().constData());
@ -151,7 +151,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
subdir += Option::dir_sep;
tmp = subdir + tmp;
}
QFileInfo fi(fileInfo(Option::fixPathToLocalOS(tmp, true)));
QFileInfo fi(fileInfo(Option::normalizePath(tmp)));
if(fi.exists()) {
if(fi.isDir()) {
QString profile = tmp;
@ -184,13 +184,13 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
bool in_root = true;
QString name = qmake_getpwd();
if(project->isActiveConfig("flat")) {
QString flat_file = fileFixify(name, oldpwd, oldoutpwd, FileFixifyRelative);
QString flat_file = fileFixify(name, FileFixifyBackwards | FileFixifyRelative);
if(flat_file.indexOf(Option::dir_sep) != -1) {
QStringList dirs = flat_file.split(Option::dir_sep);
name = dirs.back();
}
} else {
QString flat_file = fileFixify(name, oldpwd, oldoutpwd, FileFixifyRelative);
QString flat_file = fileFixify(name, FileFixifyBackwards | FileFixifyRelative);
if(QDir::isRelativePath(flat_file) && flat_file.indexOf(Option::dir_sep) != -1) {
QString last_grp("QMAKE_SUBDIR_PBX_HEIR_GROUP");
QStringList dirs = flat_file.split(Option::dir_sep);
@ -215,7 +215,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
t << "\t\t" << project_key << " = {\n"
<< "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("lastKnownFileType", "wrapper.pb-project") << ";\n"
<< "\t\t\t" << writeSettings("name", escapeFilePath(tmp_proj.first("TARGET") + projectSuffix())) << ";\n"
<< "\t\t\t" << writeSettings("name", tmp_proj.first("TARGET") + projectSuffix()) << ";\n"
<< "\t\t\t" << writeSettings("path", pbxproj) << ";\n"
<< "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n"
<< "\t\t};\n";
@ -283,7 +283,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
t << "\t\t" << keyFor(grp_it.key()) << " = {\n"
<< "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("children", grp_it.value(), SettingsAsList, 4) << ";\n"
<< "\t\t\t" << writeSettings("name", escapeFilePath(grp_it.key().section(Option::dir_sep, -1))) << ";\n"
<< "\t\t\t" << writeSettings("name", grp_it.key().section(Option::dir_sep, -1)) << ";\n"
<< "\t\t\t" << writeSettings("sourceTree", "<Group>") << ";\n"
<< "\t\t};\n";
}
@ -307,7 +307,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
ProString name = l.at(i);
const ProKey buildKey(name + ".build");
if (!project->isEmpty(buildKey)) {
const QString build = project->values(buildKey).first().toQString();
const QString build = project->first(buildKey).toQString();
if (build.toLower() != configName.toLower())
continue;
}
@ -344,7 +344,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
t << "\t\t" << keyFor("QMAKE_SUBDIR_PBX_AGGREGATE_TARGET") << " = {\n"
<< "\t\t\t" << writeSettings("buildPhases", ProStringList(), SettingsAsList, 4) << ";\n"
<< "\t\t\tbuildSettings = {\n"
<< "\t\t\t\t" << writeSettings("PRODUCT_NAME", project->values("TARGET").first()) << ";\n"
<< "\t\t\t\t" << writeSettings("PRODUCT_NAME", project->first("TARGET")) << ";\n"
<< "\t\t\t};\n";
{
ProStringList dependencies;
@ -354,8 +354,8 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
t << "\t\t\t" << writeSettings("dependencies", dependencies, SettingsAsList, 4) << ";\n"
}
t << "\t\t\t" << writeSettings("isa", "PBXAggregateTarget", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("name", project->values("TARGET").first()) << ";\n"
<< "\t\t\t" << writeSettings("productName", project->values("TARGET").first()) << ";\n"
<< "\t\t\t" << writeSettings("name", project->first("TARGET")) << ";\n"
<< "\t\t\t" << writeSettings("productName", project->first("TARGET")) << ";\n"
<< "\t\t};\n";
#endif
@ -455,8 +455,8 @@ ProjectBuilderSources::files(QMakeProject *project) const
{
QStringList ret = project->values(ProKey(key)).toQStringList();
if(key == "QMAKE_INTERNAL_INCLUDED_FILES") {
QString qtPrefix(QLibraryInfo::rawLocation(QLibraryInfo::PrefixPath, QLibraryInfo::EffectivePaths) + '/');
QString qtSrcPrefix(QLibraryInfo::rawLocation(QLibraryInfo::PrefixPath, QLibraryInfo::EffectiveSourcePaths) + '/');
QString qtPrefix(project->propertyValue(ProKey("QT_INSTALL_PREFIX/get")).toQString() + '/');
QString qtSrcPrefix(project->propertyValue(ProKey("QT_INSTALL_PREFIX/src")).toQString() + '/');
QStringList newret;
for(int i = 0; i < ret.size(); ++i) {
@ -507,14 +507,6 @@ static QString xcodeFiletypeForFilename(const QString &filename)
bool
ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
{
// The code in this function assumes that the current directory matches
// the output directory, which is not actually the case when we are called
// from the generic generator code. Instead of changing every single
// assumption and fileFixify we cheat by moving into the output directory
// for the duration of this function.
QString input_dir = qmake_getpwd();
qmake_setpwd(Option::output_dir);
ProStringList tmp;
bool did_preprocess = false;
@ -536,7 +528,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
QFile mkf(mkfile);
if(mkf.open(QIODevice::WriteOnly | QIODevice::Text)) {
writingUnixMakefileGenerator = true;
qmake_setpwd(input_dir); // Makefile generation assumes input_dir as pwd
debug_msg(1, "pbuilder: Creating file: %s", mkfile.toLatin1().constData());
QTextStream mkt(&mkf);
writeHeader(mkt);
@ -545,10 +536,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
mkt.flush();
mkf.close();
writingUnixMakefileGenerator = false;
qmake_setpwd(Option::output_dir);
}
QString phase_key = keyFor("QMAKE_PBX_MAKEQMAKE_BUILDPHASE");
mkfile = fileFixify(mkfile, qmake_getpwd());
mkfile = fileFixify(mkfile);
project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key);
t << "\t\t" << phase_key << " = {\n"
<< "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
@ -557,16 +547,20 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("name", "Qt Qmake") << ";\n"
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
<< "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
<< "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(Option::output_dir)
+ " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
<< "\t\t};\n";
}
// FIXME: Move all file resolving logic out of ProjectBuilderSources::files(), as it
// doesn't have access to any of the information it needs to resolve relative paths.
project->values("QMAKE_INTERNAL_INCLUDED_FILES").prepend(fileFixify(project->projectFile(), qmake_getpwd(), input_dir));
project->values("QMAKE_INTERNAL_INCLUDED_FILES").prepend(project->projectFile());
// Since we can't fileFixify inside ProjectBuilderSources::files(), we resolve the absolute paths here
project->values("QMAKE_INTERNAL_INCLUDED_FILES") = ProStringList(fileFixify(project->values("QMAKE_INTERNAL_INCLUDED_FILES").toQStringList(), FileFixifyAbsolute));
project->values("QMAKE_INTERNAL_INCLUDED_FILES") = ProStringList(
fileFixify(project->values("QMAKE_INTERNAL_INCLUDED_FILES").toQStringList(),
FileFixifyFromOutdir | FileFixifyAbsolute));
//DUMP SOURCES
QMap<QString, ProStringList> groups;
@ -623,11 +617,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
ProStringList &src_list = project->values(ProKey("QMAKE_PBX_" + sources.at(source).keyName()));
ProStringList &root_group_list = project->values("QMAKE_PBX_GROUPS");
const QStringList &files = fileFixify(sources.at(source).files(project));
const QStringList &files = fileFixify(sources.at(source).files(project),
FileFixifyFromOutdir | FileFixifyAbsolute);
for(int f = 0; f < files.count(); ++f) {
QString file = files[f];
if(file.length() >= 2 && (file[0] == '"' || file[0] == '\'') && file[(int) file.length()-1] == file[0])
file = file.mid(1, file.length()-2);
if(!sources.at(source).compilerName().isNull() &&
!verifyExtraCompiler(sources.at(source).compilerName(), file))
continue;
@ -637,12 +630,11 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
bool in_root = true;
QString src_key = keyFor(file);
file = fileFixify(file, qmake_getpwd(), Option::output_dir, FileFixifyAbsolute);
QString name = file.split(Option::dir_sep).back();
if (!project->isActiveConfig("flat")) {
// Build group hierarchy for file references that match the source our build dir
QString relativePath = fileFixify(file, input_dir, qmake_getpwd(), FileFixifyRelative);
QString relativePath = fileFixify(file, FileFixifyToIndir | FileFixifyRelative);
if (QDir::isRelativePath(relativePath) && relativePath.startsWith(QLatin1String("../")))
relativePath = fileFixify(file, FileFixifyRelative); // Try build dir
@ -678,9 +670,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
//source reference
t << "\t\t" << src_key << " = {\n"
<< "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("path", escapeFilePath(file)) << ";\n";
<< "\t\t\t" << writeSettings("path", file) << ";\n";
if (name != file)
t << "\t\t\t" << writeSettings("name", escapeFilePath(name)) << ";\n";
t << "\t\t\t" << writeSettings("name", name) << ";\n";
t << "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n";
QString filetype = xcodeFiletypeForFilename(file);
if (!filetype.isNull())
@ -715,7 +707,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\t\t" << keyFor(grp_it.key()) << " = {\n"
<< "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("children", grp_it.value(), SettingsAsList, 4) << ";\n"
<< "\t\t\t" << writeSettings("name", escapeFilePath(grp_it.key().section(Option::dir_sep, -1))) << ";\n"
<< "\t\t\t" << writeSettings("name", grp_it.key().section(Option::dir_sep, -1)) << ";\n"
<< "\t\t\t" << writeSettings("sourceTree", "<Group>") << ";\n"
<< "\t\t};\n";
}
@ -730,8 +722,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
debug_msg(1, "pbuilder: Creating file: %s", mkfile.toLatin1().constData());
QTextStream mkt(&mkf);
writeHeader(mkt);
mkt << "MOC = " << Option::fixPathToTargetOS(var("QMAKE_MOC")) << endl;
mkt << "UIC = " << Option::fixPathToTargetOS(var("QMAKE_UIC")) << endl;
mkt << "MOC = " << var("QMAKE_MOC") << endl;
mkt << "UIC = " << var("QMAKE_UIC") << endl;
mkt << "LEX = " << var("QMAKE_LEX") << endl;
mkt << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl;
mkt << "YACC = " << var("QMAKE_YACC") << endl;
@ -739,13 +731,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
mkt << "DEFINES = "
<< varGlue("PRL_EXPORT_DEFINES","-D"," -D"," ")
<< varGlue("DEFINES","-D"," -D","") << endl;
mkt << "INCPATH = -I" << specdir();
if(!project->isActiveConfig("no_include_pwd")) {
QString pwd = escapeFilePath(fileFixify(qmake_getpwd()));
if(pwd.isEmpty())
pwd = ".";
mkt << " -I" << pwd;
}
mkt << "INCPATH =";
{
const ProStringList &incs = project->values("INCLUDEPATH");
for (ProStringList::ConstIterator incit = incs.begin(); incit != incs.end(); ++incit)
@ -756,30 +742,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
mkt << endl;
mkt << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
mkt << "MOVE = " << var("QMAKE_MOVE") << endl << endl;
mkt << "IMAGES = " << varList("QMAKE_IMAGE_COLLECTION") << endl;
mkt << "PARSERS =";
if(!project->isEmpty("YACCSOURCES")) {
const ProStringList &yaccs = project->values("YACCSOURCES");
for (ProStringList::ConstIterator yit = yaccs.begin(); yit != yaccs.end(); ++yit) {
QFileInfo fi(fileInfo((*yit).toQString()));
mkt << " " << fi.path() << Option::dir_sep << fi.baseName()
<< Option::yacc_mod << Option::cpp_ext.first();
}
}
if(!project->isEmpty("LEXSOURCES")) {
const ProStringList &lexs = project->values("LEXSOURCES");
for (ProStringList::ConstIterator lit = lexs.begin(); lit != lexs.end(); ++lit) {
QFileInfo fi(fileInfo((*lit).toQString()));
mkt << " " << fi.path() << Option::dir_sep << fi.baseName()
<< Option::lex_mod << Option::cpp_ext.first();
}
}
mkt << "\n";
mkt << "preprocess: $(PARSERS) compilers\n";
mkt << "clean preprocess_clean: parser_clean compiler_clean\n\n";
mkt << "parser_clean:\n";
if(!project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES"))
mkt << "\t-rm -f $(PARSERS)\n";
mkt << "preprocess: compilers\n";
mkt << "clean preprocess_clean: compiler_clean\n\n";
writeExtraTargets(mkt);
if(!project->isEmpty("QMAKE_EXTRA_COMPILERS")) {
mkt << "compilers:";
@ -800,8 +764,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
if(added && !(added % 3))
mkt << "\\\n\t";
++added;
const QString file_name = fileFixify(fn, Option::output_dir, Option::output_dir);
mkt << " " << replaceExtraCompilerVariables(Option::fixPathToTargetOS(tmp_out.first().toQString(), false), file_name, QString());
const QString file_name = fileFixify(fn, FileFixifyFromOutdir);
mkt << ' ' << escapeDependencyPath(Option::fixPathToTargetOS(
replaceExtraCompilerVariables(tmp_out.first().toQString(), file_name, QString(), NoShell)));
}
}
}
@ -812,7 +777,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
mkt.flush();
mkf.close();
}
mkfile = fileFixify(mkfile, qmake_getpwd());
mkfile = fileFixify(mkfile);
QString phase_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET");
// project->values("QMAKE_PBX_BUILDPHASES").append(phase_key);
project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key);
@ -823,7 +788,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("name", "Qt Preprocessors") << ";\n"
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
<< "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
<< "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(Option::output_dir)
+ " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
<< "\t\t};\n";
}
@ -843,22 +810,17 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES
ProStringList &libdirs = project->values("QMAKE_PBX_LIBPATHS"),
&frameworkdirs = project->values("QMAKE_FRAMEWORKPATH");
static const char * const libs[] = { "QMAKE_LFLAGS", "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 };
static const char * const libs[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 };
for (int i = 0; libs[i]; i++) {
tmp = project->values(libs[i]);
for(int x = 0; x < tmp.count();) {
bool remove = false;
QString library, name;
ProString opt = tmp[x].trimmed();
if (opt.length() >= 2 && (opt.at(0) == '"' || opt.at(0) == '\'') && opt.endsWith(opt.at(0)))
opt = opt.mid(1, opt.length()-2);
if(opt.startsWith("-L")) {
QString r = opt.mid(2).toQString();
fixForOutput(r);
libdirs.append(r);
} else if(opt == "-prebind") {
project->values("QMAKE_DO_PREBINDING").append("TRUE");
remove = true;
} else if(opt.startsWith("-l")) {
name = opt.mid(2).toQString();
QString lib("lib" + name);
@ -887,10 +849,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
QString librarySuffix = project->first("QMAKE_XCODE_LIBRARY_SUFFIX").toQString();
suffixSetting = "$(" + suffixSetting + ")";
if (!librarySuffix.isEmpty()) {
library = library.replace(librarySuffix, suffixSetting);
name = name.remove(librarySuffix);
library.replace(librarySuffix, suffixSetting);
name.remove(librarySuffix);
} else {
library = library.replace(name, name + suffixSetting);
library.replace(name, name + suffixSetting);
}
}
}
@ -956,15 +918,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
if(!path.isEmpty() && !libdirs.contains(path))
libdirs += path;
}
library = fileFixify(library);
QString filetype = xcodeFiletypeForFilename(library);
library = fileFixify(library, FileFixifyFromOutdir | FileFixifyAbsolute);
QString key = keyFor(library);
if (!project->values("QMAKE_PBX_LIBRARIES").contains(key)) {
bool is_frmwrk = (library.endsWith(".framework"));
t << "\t\t" << key << " = {\n"
<< "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("name", escapeFilePath(name)) << ";\n"
<< "\t\t\t" << writeSettings("path", escapeFilePath(library)) << ";\n"
<< "\t\t\t" << writeSettings("name", name) << ";\n"
<< "\t\t\t" << writeSettings("path", library) << ";\n"
<< "\t\t\t" << writeSettings("refType", QString::number(reftypeForFile(library)), SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n";
if (is_frmwrk)
@ -999,21 +960,22 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
QTextStream mkt(&mkf);
writeHeader(mkt);
mkt << "SUBLIBS= ";
// ### This is missing the parametrization found in unixmake2.cpp
tmp = project->values("SUBLIBS");
for(int i = 0; i < tmp.count(); i++)
t << "tmp/lib" << tmp[i] << ".a ";
t << escapeFilePath("tmp/lib" + tmp[i] + ".a") << ' ';
t << endl << endl;
mkt << "sublibs: $(SUBLIBS)\n\n";
tmp = project->values("SUBLIBS");
for(int i = 0; i < tmp.count(); i++)
t << "tmp/lib" << tmp[i] << ".a:\n\t"
t << escapeFilePath("tmp/lib" + tmp[i] + ".a") + ":\n\t"
<< var(ProKey("MAKELIB" + tmp[i])) << endl << endl;
mkt.flush();
mkf.close();
writingUnixMakefileGenerator = false;
}
QString phase_key = keyFor("QMAKE_PBX_SUBLIBS_BUILDPHASE");
mkfile = fileFixify(mkfile, qmake_getpwd());
mkfile = fileFixify(mkfile);
project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key);
t << "\t\t" << phase_key << " = {\n"
<< "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
@ -1022,7 +984,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("name", "Qt Sublibs") << ";\n"
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << "\n"
<< "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
<< "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(Option::output_dir)
+ " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
<< "\t\t};\n";
}
@ -1058,6 +1022,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("name", "Qt Prelink") << ";\n"
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
<< "\t\t\t" << writeSettings("shellScript", project->values("QMAKE_PRE_LINK")) << ";\n"
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
<< "\t\t};\n";
}
@ -1070,7 +1035,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\t\t" << key << " = {\n"
<< "\t\t\t" << writeSettings("children", project->values("QMAKE_PBX_LIBRARIES"), SettingsAsList, 4) << ";\n"
<< "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";\n"
<< "\t\t\t" << writeSettings("name", grp) << ";\n"
<< "\t\t\t" << writeSettings("sourceTree", "<Group>") << ";\n"
<< "\t\t};\n";
}
@ -1083,7 +1048,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("files", project->values("QMAKE_PBX_BUILD_LIBRARIES"), SettingsAsList, 4) << ";\n"
<< "\t\t\t" << writeSettings("isa", "PBXFrameworksBuildPhase", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";\n"
<< "\t\t\t" << writeSettings("name", grp) << ";\n"
<< "\t\t};\n";
}
@ -1101,14 +1066,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("name", "Qt Postlink") << ";\n"
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
<< "\t\t\t" << writeSettings("shellScript", project->values("QMAKE_POST_LINK")) << ";\n"
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
<< "\t\t};\n";
}
if (!project->isEmpty("DESTDIR")) {
QString phase_key = keyFor("QMAKE_PBX_TARGET_COPY_PHASE");
QString destDir = project->first("DESTDIR").toQString();
destDir = fixForOutput(destDir);
destDir = fileInfo(Option::fixPathToLocalOS(destDir)).absoluteFilePath();
QString destDir = fileFixify(project->first("DESTDIR").toQString(),
FileFixifyFromOutdir | FileFixifyAbsolute);
project->values("QMAKE_PBX_BUILDPHASES").append(phase_key);
t << "\t\t" << phase_key << " = {\n"
<< "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";\n"
@ -1119,7 +1084,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("outputPaths", ProStringList(), SettingsAsList, 4) << ";\n"
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
<< "\t\t\t" << writeSettings("shellScript", fixForOutput("cp -r $BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME " + escapeFilePath(destDir))) << ";\n"
<< "\t\t\t" << writeSettings("shellScript", fixForOutput("cp -r $BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME " + IoUtils::shellQuoteUnix(destDir))) << ";\n"
<< "\t\t\t" << writeSettings("showEnvVarsInLog", "0") << ";\n"
<< "\t\t};\n";
}
bool copyBundleResources = project->isActiveConfig("app_bundle") && project->first("TEMPLATE") == "app";
@ -1137,13 +1103,13 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
//all files
const ProStringList &files = project->values(ProKey(bundle_data[i] + ".files"));
for(int file = 0; file < files.count(); file++) {
QString fn = fileFixify(files[file].toQString(), Option::output_dir, input_dir, FileFixifyAbsolute);
QString fn = fileFixify(files[file].toQString(), FileFixifyAbsolute);
QString name = fn.split(Option::dir_sep).back();
QString file_ref_key = keyFor("QMAKE_PBX_BUNDLE_DATA_FILE_REF." + bundle_data[i] + "-" + fn);
bundle_file_refs += file_ref_key;
t << "\t\t" << file_ref_key << " = {\n"
<< "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("path", escapeFilePath(fn)) << ";\n"
<< "\t\t\t" << writeSettings("path", fn) << ";\n"
<< "\t\t\t" << writeSettings("name", name) << ";\n"
<< "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n"
<< "\t\t};\n";
@ -1169,7 +1135,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\t\t" << phase_key << " = {\n"
<< "\t\t\t" << writeSettings("name", "Copy '" + bundle_data[i] + "' Files to Bundle") << ";\n"
<< "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("dstPath", escapeFilePath(path)) << ";\n"
<< "\t\t\t" << writeSettings("dstPath", path) << ";\n"
<< "\t\t\t" << writeSettings("dstSubfolderSpec", "1", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("isa", "PBXCopyFilesBuildPhase", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("files", bundle_files, SettingsAsList, 4) << ";\n"
@ -1193,8 +1159,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
if (copyBundleResources) {
if (!project->isEmpty("ICON")) {
ProString icon = project->first("ICON");
if (icon.length() >= 2 && (icon.at(0) == '"' || icon.at(0) == '\'') && icon.endsWith(icon.at(0)))
icon = icon.mid(1, icon.length() - 2);
bundle_resources_files += keyFor(icon + ".BUILDABLE");
}
@ -1207,7 +1171,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("files", bundle_resources_files, SettingsAsList, 4) << ";\n"
<< "\t\t\t" << writeSettings("isa", "PBXResourcesBuildPhase", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";\n"
<< "\t\t\t" << writeSettings("name", grp) << ";\n"
<< "\t\t};\n";
}
@ -1232,9 +1196,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
} else {
t << "\t\t\t" << writeSettings("explicitFileType", "compiled.mach-o.executable") << ";\n";
}
QString app = (!project->isEmpty("DESTDIR") ? project->first("DESTDIR") + project->first("QMAKE_ORIG_TARGET") :
qmake_getpwd()) + Option::dir_sep + targ;
t << "\t\t\t" << writeSettings("path", escapeFilePath(targ)) << ";\n";
t << "\t\t\t" << writeSettings("path", targ) << ";\n";
} else {
ProString lib = project->first("QMAKE_ORIG_TARGET");
if(project->isActiveConfig("staticlib")) {
@ -1262,7 +1224,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
} else {
t << "\t\t\t" << writeSettings("explicitFileType", "compiled.mach-o.dylib") << ";\n";
}
t << "\t\t\t" << writeSettings("path", escapeFilePath(lib)) << ";\n";
t << "\t\t\t" << writeSettings("path", lib) << ";\n";
}
t << "\t\t\t" << writeSettings("sourceTree", "BUILT_PRODUCTS_DIR", SettingsNoQuote) << ";\n"
<< "\t\t};\n";
@ -1282,7 +1244,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\t\t" << keyFor("QMAKE_PBX_ROOT_GROUP") << " = {\n"
<< "\t\t\t" << writeSettings("children", project->values("QMAKE_PBX_GROUPS"), SettingsAsList, 4) << ";\n"
<< "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("name", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";\n"
<< "\t\t\t" << writeSettings("name", project->first("QMAKE_ORIG_TARGET")) << ";\n"
<< "\t\t\t" << writeSettings("sourceTree", "<Group>") << ";\n"
<< "\t\t};\n";
@ -1328,14 +1290,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
else
t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.tool") << ";\n";
}
t << "\t\t\t" << writeSettings("name", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";\n"
<< "\t\t\t" << writeSettings("productName", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";\n";
t << "\t\t\t" << writeSettings("name", project->first("QMAKE_ORIG_TARGET")) << ";\n"
<< "\t\t\t" << writeSettings("productName", project->first("QMAKE_ORIG_TARGET")) << ";\n";
} else {
ProString lib = project->first("QMAKE_ORIG_TARGET");
if(!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib"))
lib.prepend("lib");
t << "\t\t\t" << writeSettings("name", escapeFilePath(lib)) << ";\n"
<< "\t\t\t" << writeSettings("productName", escapeFilePath(lib)) << ";\n";
t << "\t\t\t" << writeSettings("name", lib) << ";\n"
<< "\t\t\t" << writeSettings("productName", lib) << ";\n";
if (!project->isEmpty("QMAKE_PBX_PRODUCT_TYPE"))
t << "\t\t\t" << writeSettings("productType", project->first("QMAKE_PBX_PRODUCT_TYPE")) << ";\n";
else if (project->isActiveConfig("staticlib"))
@ -1346,8 +1308,98 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.library.dynamic") << ";\n";
}
if(!project->isEmpty("DESTDIR"))
t << "\t\t\t" << writeSettings("productInstallPath", escapeFilePath(project->first("DESTDIR"))) << ";\n";
t << "\t\t\t" << writeSettings("productInstallPath", project->first("DESTDIR")) << ";\n";
t << "\t\t};\n";
// Test target for running Qt unit tests under XCTest
if (project->isActiveConfig("testcase") && project->isActiveConfig("app_bundle")) {
QString devNullFileReferenceKey = keyFor(pbx_dir + "QMAKE_PBX_DEV_NULL_FILE_REFERENCE");
t << "\t\t" << devNullFileReferenceKey << " = {\n"
<< "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("name", "/dev/null") << ";\n"
<< "\t\t\t" << writeSettings("path", "/dev/null") << ";\n"
<< "\t\t\t" << writeSettings("lastKnownFileType", "sourcecode.c.c") << ";\n"
<< "\t\t\t" << writeSettings("sourceTree", "<absolute>") << ";\n"
<< "\t\t};\n";
QString devNullBuildFileKey = keyFor(pbx_dir + "QMAKE_PBX_DEV_NULL_BUILD_FILE");
t << "\t\t" << devNullBuildFileKey << " = {\n"
<< "\t\t\t" << writeSettings("fileRef", devNullFileReferenceKey) << ";\n"
<< "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";\n"
<< "\t\t};\n";
QString dummySourceBuildPhaseKey = keyFor(pbx_dir + "QMAKE_PBX_DUMMY_SOURCE_BUILD_PHASE");
t << "\t\t" << dummySourceBuildPhaseKey << " = {\n"
<< "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("files", devNullBuildFileKey, SettingsAsList, 4) << ";\n"
<< "\t\t\t" << writeSettings("isa", "PBXSourcesBuildPhase", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
<< "\t\t};\n";
ProStringList testBundleBuildConfigs;
ProString targetName = project->first("QMAKE_ORIG_TARGET");
ProString testHost = "$(BUILT_PRODUCTS_DIR)/" + targetName + ".app/";
if (!project->isActiveConfig("ios"))
testHost.append("Contents/MacOS/");
testHost.append(targetName);
static const char * const configs[] = { "Debug", "Release", 0 };
for (int i = 0; configs[i]; i++) {
QString testBundleBuildConfig = keyFor(pbx_dir + "QMAKE_PBX_TEST_BUNDLE_BUILDCONFIG_" + configs[i]);
t << "\t\t" << testBundleBuildConfig << " = {\n"
<< "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";\n"
<< "\t\t\tbuildSettings = {\n"
<< "\t\t\t\t" << writeSettings("INFOPLIST_FILE", project->first("QMAKE_XCODE_SPECDIR") + "/QtTest.plist") << ";\n"
<< "\t\t\t\t" << writeSettings("OTHER_LDFLAGS", "") << ";\n"
<< "\t\t\t\t" << writeSettings("TEST_HOST", testHost) << ";\n"
<< "\t\t\t\t" << writeSettings("DEBUG_INFORMATION_FORMAT", "dwarf-with-dsym") << ";\n"
<< "\t\t\t};\n"
<< "\t\t\t" << writeSettings("name", configs[i], SettingsNoQuote) << ";\n"
<< "\t\t};\n";
testBundleBuildConfigs.append(testBundleBuildConfig);
}
QString testBundleBuildConfigurationListKey = keyFor(pbx_dir + "QMAKE_PBX_TEST_BUNDLE_BUILDCONFIG_LIST");
t << "\t\t" << testBundleBuildConfigurationListKey << " = {\n"
<< "\t\t\t" << writeSettings("isa", "XCConfigurationList", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("buildConfigurations", testBundleBuildConfigs, SettingsAsList, 4) << ";\n"
<< "\t\t\t" << writeSettings("defaultConfigurationIsVisible", "0", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("defaultConfigurationName", "Debug", SettingsNoQuote) << ";\n"
<< "\t\t};\n";
QString primaryTargetDependencyKey = keyFor(pbx_dir + "QMAKE_PBX_PRIMARY_TARGET_DEP");
t << "\t\t" << primaryTargetDependencyKey << " = {\n"
<< "\t\t\t" << writeSettings("isa", "PBXTargetDependency", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("target", keyFor(pbx_dir + "QMAKE_PBX_TARGET")) << ";\n"
<< "\t\t};\n";
QString testBundleReferenceKey = keyFor("QMAKE_TEST_BUNDLE_REFERENCE");
t << "\t\t" << testBundleReferenceKey << " = {\n"
<< "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("explicitFileType", "wrapper.cfbundle") << ";\n"
<< "\t\t\t" << writeSettings("includeInIndex", "0", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("sourceTree", "BUILT_PRODUCTS_DIR", SettingsNoQuote) << ";\n"
<< "\t\t};\n";
QString testTargetKey = keyFor(pbx_dir + "QMAKE_PBX_TEST_TARGET");
project->values("QMAKE_PBX_TARGETS").append(testTargetKey);
t << "\t\t" << testTargetKey << " = {\n"
<< "\t\t\t" << writeSettings("buildPhases", dummySourceBuildPhaseKey, SettingsAsList, 4) << ";\n"
<< "\t\t\t" << writeSettings("dependencies", primaryTargetDependencyKey, SettingsAsList, 4) << ";\n"
<< "\t\t\t" << writeSettings("buildConfigurationList", testBundleBuildConfigurationListKey) << ";\n"
<< "\t\t\t" << writeSettings("productType", "com.apple.product-type.bundle.unit-test") << ";\n"
<< "\t\t\t" << writeSettings("isa", "PBXNativeTarget", SettingsNoQuote) << ";\n"
<< "\t\t\t" << writeSettings("productReference", testBundleReferenceKey) << ";\n"
<< "\t\t\t" << writeSettings("name", "Qt Test") << ";\n"
<< "\t\t};\n";
QLatin1Literal testTargetID("TestTargetID");
project->values(ProKey("QMAKE_PBX_TARGET_ATTRIBUTES_" + testTargetKey + "_" + testTargetID)).append(keyFor(pbx_dir + "QMAKE_PBX_TARGET"));
project->values(ProKey("QMAKE_PBX_TARGET_ATTRIBUTES_" + testTargetKey)).append(ProKey(testTargetID));
}
//DEBUG/RELEASE
QString defaultConfig;
for(int as_release = 0; as_release < 2; as_release++)
@ -1356,6 +1408,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
QMap<QString, QString> settings;
settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO"));
// Bitcode is only supported with a deployment target >= iOS 6.0.
// Disable it for now, and consider switching it on when later
// bumping the deployment target.
settings.insert("ENABLE_BITCODE", "NO");
settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", as_release ? "NO" : "YES");
if(!as_release)
settings.insert("GCC_OPTIMIZATION_LEVEL", "0");
@ -1367,14 +1423,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
ProString name = l.at(i);
const ProKey buildKey(name + ".build");
if (!project->isEmpty(buildKey)) {
const QString build = project->values(buildKey).first().toQString();
const QString build = project->first(buildKey).toQString();
if (build.toLower() != configName.toLower())
continue;
}
const QString value = project->values(ProKey(name + ".value")).join(QString(Option::field_sep));
const ProKey nkey(name + ".name");
if (!project->isEmpty(nkey))
name = project->values(nkey).first();
name = project->first(nkey);
settings.insert(name.toQString(), value);
}
}
@ -1384,7 +1440,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
ProString lib = project->first("QMAKE_ORIG_TARGET");
if (!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib"))
lib.prepend("lib");
settings.insert("PRODUCT_NAME", escapeFilePath(lib.toQString()));
settings.insert("PRODUCT_NAME", lib.toQString());
}
if (project->isActiveConfig("debug") != (bool)as_release)
@ -1415,10 +1471,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
if ((project->first("TEMPLATE") == "app" && project->isActiveConfig("app_bundle")) ||
(project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") &&
project->isActiveConfig("lib_bundle"))) {
QString plist = fileFixify(project->first("QMAKE_INFO_PLIST").toQString(), Option::output_dir, input_dir);
QString plist = fileFixify(project->first("QMAKE_INFO_PLIST").toQString(), FileFixifyToIndir);
if (!plist.isEmpty()) {
if (exists(plist))
t << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", plist) << ";\n";
t << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", fileFixify(plist)) << ";\n";
else
warn_msg(WarnLogic, "Could not resolve Info.plist: '%s'. Check if QMAKE_INFO_PLIST points to a valid file.", plist.toLatin1().constData());
} else {
@ -1427,30 +1483,29 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
if (plist_in_file.open(QIODevice::ReadOnly)) {
QTextStream plist_in(&plist_in_file);
QString plist_in_text = plist_in.readAll();
plist_in_text = plist_in_text.replace("@ICON@",
plist_in_text.replace("@ICON@",
(project->isEmpty("ICON") ? QString("") : project->first("ICON").toQString().section(Option::dir_sep, -1)));
if (project->first("TEMPLATE") == "app") {
plist_in_text = plist_in_text.replace("@EXECUTABLE@", project->first("QMAKE_ORIG_TARGET").toQString());
plist_in_text.replace("@EXECUTABLE@", project->first("QMAKE_ORIG_TARGET").toQString());
} else {
plist_in_text = plist_in_text.replace("@LIBRARY@", project->first("QMAKE_ORIG_TARGET").toQString());
plist_in_text.replace("@LIBRARY@", project->first("QMAKE_ORIG_TARGET").toQString());
}
QString bundlePrefix = project->first("QMAKE_TARGET_BUNDLE_PREFIX").toQString();
if (bundlePrefix.isEmpty())
bundlePrefix = "com.yourcompany";
plist_in_text = plist_in_text.replace("@BUNDLEIDENTIFIER@", bundlePrefix + "." + QLatin1String("${PRODUCT_NAME:rfc1034identifier}"));
plist_in_text.replace("@BUNDLEIDENTIFIER@", bundlePrefix + '.' + QLatin1String("${PRODUCT_NAME:rfc1034identifier}"));
if (!project->values("VERSION").isEmpty()) {
plist_in_text = plist_in_text.replace("@SHORT_VERSION@", project->first("VER_MAJ") + "." +
project->first("VER_MIN"));
plist_in_text.replace("@SHORT_VERSION@", project->first("VER_MAJ") + "." + project->first("VER_MIN"));
}
plist_in_text = plist_in_text.replace("@TYPEINFO@",
plist_in_text.replace("@TYPEINFO@",
(project->isEmpty("QMAKE_PKGINFO_TYPEINFO")
? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4).toQString()));
QString plist_dir;
if (!project->isEmpty("PLIST_DIR"))
plist_dir = project->first("PLIST_DIR").toQString();
QString plist_in_filename = QFileInfo(plist_in_file).fileName();
QFile plist_out_file(plist_dir + plist_in_filename);
if (plist_out_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QFile plist_out_file(Option::output_dir + "/" + plist_dir + plist_in_filename);
if (plist_out_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream plist_out(&plist_out_file);
plist_out << plist_in_text;
t << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", fixForOutput(plist_dir + plist_in_filename)) << ";\n";
@ -1459,12 +1514,12 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
}
}
t << "\t\t\t\t" << writeSettings("SYMROOT", escapeFilePath(qmake_getpwd())) << ";\n";
t << "\t\t\t\t" << writeSettings("SYMROOT", Option::output_dir) << ";\n";
if (!project->isEmpty("DESTDIR")) {
ProString dir = project->first("DESTDIR");
if (QDir::isRelativePath(dir.toQString()))
dir.prepend(qmake_getpwd() + Option::dir_sep);
dir.prepend(Option::output_dir + Option::dir_sep);
t << "\t\t\t\t" << writeSettings("INSTALL_DIR", dir) << ";\n";
}
@ -1495,13 +1550,13 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
QString var = tmp[i].toQString(), val = QString::fromLocal8Bit(qgetenv(var.toLatin1().constData()));
if (val.isEmpty() && var == "TB")
val = "/usr/bin/";
t << "\t\t\t\t" << writeSettings(var, escapeFilePath(val)) << ";\n";
t << "\t\t\t\t" << writeSettings(var, val) << ";\n";
}
if (!project->isEmpty("PRECOMPILED_HEADER")) {
t << "\t\t\t\t" << writeSettings("GCC_PRECOMPILE_PREFIX_HEADER", "YES") << ";\n"
<< "\t\t\t\t" << writeSettings("GCC_PREFIX_HEADER", escapeFilePath(project->first("PRECOMPILED_HEADER"))) << ";\n";
<< "\t\t\t\t" << writeSettings("GCC_PREFIX_HEADER", project->first("PRECOMPILED_HEADER")) << ";\n";
}
t << "\t\t\t\t" << writeSettings("HEADER_SEARCH_PATHS", fixListForOutput("INCLUDEPATH") + ProStringList(fixForOutput(specdir())), SettingsAsList, 5) << ";\n"
t << "\t\t\t\t" << writeSettings("HEADER_SEARCH_PATHS", fixListForOutput("INCLUDEPATH"), SettingsAsList, 5) << ";\n"
<< "\t\t\t\t" << writeSettings("LIBRARY_SEARCH_PATHS", fixListForOutput("QMAKE_PBX_LIBPATHS"), SettingsAsList, 5) << ";\n"
<< "\t\t\t\t" << writeSettings("FRAMEWORK_SEARCH_PATHS", fixListForOutput("QMAKE_FRAMEWORKPATH"),
!project->values("QMAKE_FRAMEWORKPATH").isEmpty() ? SettingsAsList : 0, 5) << ";\n";
@ -1530,8 +1585,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\t\t\t\t" << writeSettings("OTHER_LDFLAGS",
fixListForOutput("SUBLIBS")
+ fixListForOutput("QMAKE_LFLAGS")
+ fixListForOutput("QMAKE_LIBS")
+ fixListForOutput("QMAKE_LIBS_PRIVATE"),
+ fixListForOutput(fixLibFlags("QMAKE_LIBS"))
+ fixListForOutput(fixLibFlags("QMAKE_LIBS_PRIVATE")),
SettingsAsList, 6) << ";\n";
}
const ProStringList &archs = !project->values("QMAKE_XCODE_ARCHS").isEmpty() ?
@ -1539,7 +1594,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
if (!archs.isEmpty())
t << "\t\t\t\t" << writeSettings("ARCHS", archs) << ";\n";
if (!project->isEmpty("OBJECTS_DIR"))
t << "\t\t\t\t" << writeSettings("OBJROOT", escapeFilePath(project->first("OBJECTS_DIR").toQString())) << ";\n";
t << "\t\t\t\t" << writeSettings("OBJROOT", project->first("OBJECTS_DIR")) << ";\n";
} else {
if (project->first("TEMPLATE") == "app") {
t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", fixForOutput(project->first("QMAKE_ORIG_TARGET").toQString())) << ";\n";
@ -1551,7 +1606,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
ProString lib = project->first("QMAKE_ORIG_TARGET");
if (!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib"))
lib.prepend("lib");
t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", escapeFilePath(lib)) << ";\n";
t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", lib) << ";\n";
}
}
t << "\t\t\t};\n"
@ -1578,6 +1633,19 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\t\t\t" << writeSettings("projectDirPath", ProStringList()) << ";\n"
<< "\t\t\t" << writeSettings("projectRoot", "") << ";\n"
<< "\t\t\t" << writeSettings("targets", project->values("QMAKE_PBX_TARGETS"), SettingsAsList, 4) << ";\n"
<< "\t\t\t" << "attributes = {\n"
<< "\t\t\t\tTargetAttributes = {\n";
foreach (const ProString &target, project->values("QMAKE_PBX_TARGETS")) {
const ProStringList &attributes = project->values(ProKey("QMAKE_PBX_TARGET_ATTRIBUTES_" + target));
if (attributes.isEmpty())
continue;
t << "\t\t\t\t\t" << target << " = {\n";
foreach (const ProString &attribute, attributes)
t << "\t\t\t\t\t\t" << writeSettings(attribute.toQString(), project->first(ProKey("QMAKE_PBX_TARGET_ATTRIBUTES_" + target + "_" + attribute))) << ";\n";
t << "\t\t\t\t\t};\n";
}
t << "\t\t\t\t};\n"
<< "\t\t\t};\n"
<< "\t\t};\n";
// FIXME: Deal with developmentRegion and knownRegions for QMAKE_PBX_ROOT
@ -1588,8 +1656,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "}\n";
if(project->isActiveConfig("generate_pbxbuild_makefile")) {
QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"),
qmake_getpwd());
QString mkwrap = Option::output_dir + project->first("/MAKEFILE");
QFile mkwrapf(mkwrap);
if(mkwrapf.open(QIODevice::WriteOnly | QIODevice::Text)) {
writingUnixMakefileGenerator = true;
@ -1597,13 +1664,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
QTextStream mkwrapt(&mkwrapf);
writeHeader(mkwrapt);
const char cleans[] = "preprocess_clean ";
const QString cmd = escapeFilePath(project->first("QMAKE_ORIG_TARGET") + projectSuffix() + "/") + " && " + pbxbuild();
mkwrapt << "#This is a makefile wrapper for PROJECT BUILDER\n"
<< "all:\n\t"
<< "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << "\n"
<< "cd " << cmd << "\n"
<< "install: all\n\t"
<< "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " install\n"
<< "cd " << cmd << " install\n"
<< "distclean clean: preprocess_clean\n\t"
<< "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " clean\n"
<< "cd " << cmd << " clean\n"
<< (!did_preprocess ? cleans : "") << ":\n";
if(did_preprocess)
mkwrapt << cleans << ":\n\t"
@ -1613,7 +1681,52 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
}
}
qmake_setpwd(input_dir);
// Scheme
{
QString xcodeSpecDir = project->first("QMAKE_XCODE_SPECDIR").toQString();
bool wroteCustomScheme = false;
QString projectSharedSchemesPath = pbx_dir + "/xcshareddata/xcschemes";
if (mkdir(projectSharedSchemesPath)) {
QString target = project->first("QMAKE_ORIG_TARGET").toQString();
QFile defaultSchemeFile(xcodeSpecDir + "/default.xcscheme");
QFile outputSchemeFile(projectSharedSchemesPath + Option::dir_sep + target + ".xcscheme");
if (defaultSchemeFile.open(QIODevice::ReadOnly)
&& outputSchemeFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream defaultSchemeStream(&defaultSchemeFile);
QString schemeData = defaultSchemeStream.readAll();
schemeData.replace("@QMAKE_ORIG_TARGET@", target);
schemeData.replace("@TARGET_PBX_KEY@", keyFor(pbx_dir + "QMAKE_PBX_TARGET"));
schemeData.replace("@TEST_BUNDLE_PBX_KEY@", keyFor("QMAKE_TEST_BUNDLE_REFERENCE"));
QTextStream outputSchemeStream(&outputSchemeFile);
outputSchemeStream << schemeData;
wroteCustomScheme = true;
}
}
if (wroteCustomScheme) {
// Prevent Xcode from auto-generating schemes
QString workspaceSettingsFilename("WorkspaceSettings.xcsettings");
QString workspaceSharedDataPath = pbx_dir + "/project.xcworkspace/xcshareddata";
if (mkdir(workspaceSharedDataPath)) {
QFile::copy(xcodeSpecDir + Option::dir_sep + workspaceSettingsFilename,
workspaceSharedDataPath + Option::dir_sep + workspaceSettingsFilename);
} else {
wroteCustomScheme = false;
}
}
if (!wroteCustomScheme)
warn_msg(WarnLogic, "Failed to generate schemes in '%s', " \
"falling back to Xcode auto-generated schemes", qPrintable(projectSharedSchemesPath));
}
return true;
}
@ -1703,13 +1816,15 @@ ProjectBuilderMakefileGenerator::openOutput(QFile &file, const QString &build) c
output += QDir::separator();
}
output += QString("project.pbxproj");
output = unescapeFilePath(output);
file.setFileName(output);
bool ret = UnixMakefileGenerator::openOutput(file, build);
((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1);
Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2);
return ret;
}
bool ret = UnixMakefileGenerator::openOutput(file, build);
((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1);
Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2);
return ret;
((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir;
return UnixMakefileGenerator::openOutput(file, build);
}
/* This function is such a hack it is almost pointless, but it
@ -1760,8 +1875,6 @@ ProjectBuilderMakefileGenerator::pbuilderVersion() const
else
version_plist = "/Developer/Applications/Project Builder.app/Contents/version.plist";
#endif
} else {
version_plist = version_plist.replace(QRegExp("\""), "");
}
if (ret.isEmpty()) {
QFile version_file(version_plist);
@ -1822,7 +1935,7 @@ int
ProjectBuilderMakefileGenerator::reftypeForFile(const QString &where)
{
int ret = 0; //absolute is the default..
if(QDir::isRelativePath(unescapeFilePath(where)))
if (QDir::isRelativePath(where))
ret = 4; //relative
return ret;
}
@ -1848,26 +1961,6 @@ ProjectBuilderMakefileGenerator::pbxbuild()
return (pbuilderVersion() >= 38 ? "xcodebuild" : "pbxbuild");
}
QString
ProjectBuilderMakefileGenerator::escapeFilePath(const QString &path) const
{
#if 1
//in the middle of generating a Makefile!
if(writingUnixMakefileGenerator)
return UnixMakefileGenerator::escapeFilePath(path);
//generating stuff for the xml file!
QString ret = path;
if(!ret.isEmpty()) {
ret = unescapeFilePath(ret);
debug_msg(2, "EscapeFilePath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData());
}
return ret;
#else
return UnixMakefileGenerator::escapeFilePath(path);
#endif
}
static QString quotedStringLiteral(const QString &value)
{
QString result;

View File

@ -42,7 +42,7 @@ POSSIBILITY OF SUCH DAMAGE.
strings. */
#ifdef PCRE_HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -314,12 +314,20 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
}
} else if (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32)) {
red_shift = calc_shift(red_mask);
if (((red_mask >> red_shift) + 1) == 0)
return false;
red_scale = 256 / ((red_mask >> red_shift) + 1);
green_shift = calc_shift(green_mask);
if (((green_mask >> green_shift) + 1) == 0)
return false;
green_scale = 256 / ((green_mask >> green_shift) + 1);
blue_shift = calc_shift(blue_mask);
if (((blue_mask >> blue_shift) + 1) == 0)
return false;
blue_scale = 256 / ((blue_mask >> blue_shift) + 1);
alpha_shift = calc_shift(alpha_mask);
if (((alpha_mask >> alpha_shift) + 1) == 0)
return false;
alpha_scale = 256 / ((alpha_mask >> alpha_shift) + 1);
} else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {
blue_mask = 0x000000ff;
@ -476,12 +484,6 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
p = data + (h-y-1)*bpl;
break;
case 2: // delta (jump)
// Protection
if ((uint)x >= (uint)w)
x = w-1;
if ((uint)y >= (uint)h)
y = h-1;
{
quint8 tmp;
d->getChar((char *)&tmp);
@ -489,6 +491,13 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
d->getChar((char *)&tmp);
y += tmp;
}
// Protection
if ((uint)x >= (uint)w)
x = w-1;
if ((uint)y >= (uint)h)
y = h-1;
p = data + (h-y-1)*bpl + x;
break;
default: // absolute mode
@ -631,7 +640,7 @@ bool qt_write_dib(QDataStream &s, QImage image)
if (nbits == 1 || nbits == 8) { // direct output
for (y=image.height()-1; y>=0; y--) {
if (d->write((char*)image.constScanLine(y), bpl) == -1)
if (d->write((const char*)image.constScanLine(y), bpl) == -1)
return false;
}
return true;
@ -791,6 +800,10 @@ bool QBmpHandler::write(const QImage &img)
case QImage::Format_ARGB32:
image = img;
break;
case QImage::Format_Alpha8:
case QImage::Format_Grayscale8:
image = img.convertToFormat(QImage::Format_Indexed8);
break;
default:
if (img.hasAlphaChannel())
image = img.convertToFormat(QImage::Format_ARGB32);

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -80,8 +80,8 @@ public:
if (systemTransform.type() <= QTransform::TxTranslate)
systemClip.translate(qRound(systemTransform.dx()), qRound(systemTransform.dy()));
else {
// Transform the system clip region back from device pixels to device-independent pixels before
// applying systemTransform, which already has transform from device-independent pixels to device pixels
// Transform the system clip region back from device pixels to device-independent pixels before
// applying systemTransform, which already has transform from device-independent pixels to device pixels
#ifdef Q_OS_MAC
QTransform scaleTransform;
const qreal invDevicePixelRatio = 1. / pdev->devicePixelRatio();

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -643,15 +643,15 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
while (oldPos < len && !attributes[oldPos].graphemeBoundary)
oldPos++;
} else {
while (oldPos < len && d->atSpace(oldPos))
while (oldPos < len && attributes[oldPos].whiteSpace)
oldPos++;
if (oldPos < len && d->atWordSeparator(oldPos)) {
if (oldPos < len && d->atWordSeparator(oldPos)) {
oldPos++;
while (oldPos < len && d->atWordSeparator(oldPos))
oldPos++;
} else {
while (oldPos < len && !d->atSpace(oldPos) && !d->atWordSeparator(oldPos))
while (oldPos < len && !attributes[oldPos].whiteSpace && !d->atWordSeparator(oldPos))
oldPos++;
}
}
@ -680,7 +680,7 @@ int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const
while (oldPos && !attributes[oldPos].graphemeBoundary)
oldPos--;
} else {
while (oldPos && d->atSpace(oldPos-1))
while (oldPos > 0 && attributes[oldPos - 1].whiteSpace)
oldPos--;
if (oldPos && d->atWordSeparator(oldPos-1)) {
@ -688,7 +688,7 @@ int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const
while (oldPos && d->atWordSeparator(oldPos-1))
oldPos--;
} else {
while (oldPos && !d->atSpace(oldPos-1) && !d->atWordSeparator(oldPos-1))
while (oldPos > 0 && !attributes[oldPos - 1].whiteSpace && !d->atWordSeparator(oldPos-1))
oldPos--;
}
}
@ -1777,6 +1777,11 @@ void QTextLine::layout_helper(int maxGlyphs)
QFixed x = line.x + line.textWidth + lbh.tmpData.textWidth + lbh.spaceData.textWidth;
QFixed tabWidth = eng->calculateTabWidth(item, x);
attributes = eng->attributes();
if (!attributes)
return;
lbh.logClusters = eng->layoutData->logClustersPtr;
lbh.glyphs = eng->shapedGlyphs(&current);
lbh.spaceData.textWidth += tabWidth;
lbh.spaceData.length++;
@ -2064,9 +2069,8 @@ static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine,
// Make a font for this particular engine
QRawFont font;
QRawFontPrivate *fontD = QRawFontPrivate::get(font);
fontD->fontEngine = fontEngine;
fontD->thread = QThread::currentThread();
fontD->fontEngine->ref.ref();
fontD->setFontEngine(fontEngine);
QVarLengthArray<glyph_t> glyphsArray;
QVarLengthArray<QFixedPoint> positionsArray;
@ -2088,7 +2092,9 @@ static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine,
qreal minY = 0;
qreal maxY = 0;
QVector<quint32> glyphs;
glyphs.reserve(glyphsArray.size());
QVector<QPointF> positions;
positions.reserve(glyphsArray.size());
for (int i=0; i<glyphsArray.size(); ++i) {
glyphs.append(glyphsArray.at(i) & 0xffffff);

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$

View File

@ -1,7 +1,8 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2015 Intel Corporation.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
@ -10,9 +11,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +24,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -195,6 +196,64 @@ static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, const qt
}
}
static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt,
QAbstractSocket::NetworkLayerProtocol socketProtocol, int &level, int &n)
{
n = 0;
level = SOL_SOCKET; // default
switch (opt) {
case QNativeSocketEngine::NonBlockingSocketOption: // WSAIoctl
case QNativeSocketEngine::TypeOfServiceOption: // not supported
Q_UNREACHABLE();
case QNativeSocketEngine::ReceiveBufferSocketOption:
n = SO_RCVBUF;
break;
case QNativeSocketEngine::SendBufferSocketOption:
n = SO_SNDBUF;
break;
case QNativeSocketEngine::BroadcastSocketOption:
n = SO_BROADCAST;
break;
case QNativeSocketEngine::AddressReusable:
n = SO_REUSEADDR;
break;
case QNativeSocketEngine::BindExclusively:
n = SO_EXCLUSIVEADDRUSE;
break;
case QNativeSocketEngine::ReceiveOutOfBandData:
n = SO_OOBINLINE;
break;
case QNativeSocketEngine::LowDelayOption:
level = IPPROTO_TCP;
n = TCP_NODELAY;
break;
case QNativeSocketEngine::KeepAliveOption:
n = SO_KEEPALIVE;
break;
case QNativeSocketEngine::MulticastTtlOption:
if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
level = IPPROTO_IPV6;
n = IPV6_MULTICAST_HOPS;
} else
{
level = IPPROTO_IP;
n = IP_MULTICAST_TTL;
}
break;
case QNativeSocketEngine::MulticastLoopbackOption:
if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
level = IPPROTO_IPV6;
n = IPV6_MULTICAST_LOOP;
} else
{
level = IPPROTO_IP;
n = IP_MULTICAST_LOOP;
}
break;
}
}
/*! \internal
@ -209,7 +268,7 @@ void QNativeSocketEnginePrivate::setPortAndAddress(sockaddr_in * sockAddrIPv4, q
|| socketProtocol == QAbstractSocket::AnyIPProtocol) {
memset(sockAddrIPv6, 0, sizeof(qt_sockaddr_in6));
sockAddrIPv6->sin6_family = AF_INET6;
sockAddrIPv6->sin6_scope_id = address.scopeId().toInt();
sockAddrIPv6->sin6_scope_id = address.scopeId().toUInt();
WSAHtons(socketDescriptor, port, &(sockAddrIPv6->sin6_port));
Q_IPV6ADDR tmp = address.toIPv6Address();
memcpy(&(sockAddrIPv6->sin6_addr.qt_s6_addr), &tmp, sizeof(tmp));
@ -383,8 +442,15 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
#endif
socketDescriptor = socket;
return true;
// Make the socket nonblocking.
if (!setOption(QAbstractSocketEngine::NonBlockingSocketOption, 1)) {
setError(QAbstractSocket::UnsupportedSocketOperationError, NonBlockingInitFailedErrorString);
q_func()->close();
return false;
}
return true;
}
/*! \internal
@ -397,19 +463,8 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co
if (!q->isValid())
return -1;
int n = -1;
int level = SOL_SOCKET; // default
// handle non-getsockopt
switch (opt) {
case QNativeSocketEngine::ReceiveBufferSocketOption:
n = SO_RCVBUF;
break;
case QNativeSocketEngine::SendBufferSocketOption:
n = SO_SNDBUF;
break;
case QNativeSocketEngine::BroadcastSocketOption:
n = SO_BROADCAST;
break;
case QNativeSocketEngine::NonBlockingSocketOption: {
unsigned long buf = 0;
if (WSAIoctl(socketDescriptor, FIONBIO, 0,0, &buf, sizeof(buf), 0,0,0) == 0)
@ -418,53 +473,21 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co
return -1;
break;
}
case QNativeSocketEngine::AddressReusable:
n = SO_REUSEADDR;
break;
case QNativeSocketEngine::BindExclusively:
n = SO_EXCLUSIVEADDRUSE;
break;
case QNativeSocketEngine::ReceiveOutOfBandData:
n = SO_OOBINLINE;
break;
case QNativeSocketEngine::LowDelayOption:
level = IPPROTO_TCP;
n = TCP_NODELAY;
break;
case QNativeSocketEngine::KeepAliveOption:
n = SO_KEEPALIVE;
break;
case QNativeSocketEngine::MulticastTtlOption:
if (socketProtocol == QAbstractSocket::IPv6Protocol) {
level = IPPROTO_IPV6;
n = IPV6_MULTICAST_HOPS;
} else
{
level = IPPROTO_IP;
n = IP_MULTICAST_TTL;
}
break;
case QNativeSocketEngine::MulticastLoopbackOption:
if (socketProtocol == QAbstractSocket::IPv6Protocol) {
level = IPPROTO_IPV6;
n = IPV6_MULTICAST_LOOP;
} else
{
level = IPPROTO_IP;
n = IP_MULTICAST_LOOP;
}
break;
case QNativeSocketEngine::TypeOfServiceOption:
return -1;
default:
break;
}
#if Q_BYTE_ORDER != Q_LITTLE_ENDIAN
#error code assumes windows is little endian
#endif
int n, level;
int v = 0; //note: windows doesn't write to all bytes if the option type is smaller than int
QT_SOCKOPTLEN_T len = sizeof(v);
convertToLevelAndOption(opt, socketProtocol, level, n);
if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) == 0)
return v;
WS_ERROR_DEBUG(WSAGetLastError());
@ -481,21 +504,12 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
if (!q->isValid())
return false;
int n = 0;
int level = SOL_SOCKET; // default
// handle non-setsockopt options
switch (opt) {
case QNativeSocketEngine::ReceiveBufferSocketOption:
n = SO_RCVBUF;
break;
case QNativeSocketEngine::SendBufferSocketOption:
// see QTBUG-30478 SO_SNDBUF should not be used on Vista or later
if (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA)
return false;
n = SO_SNDBUF;
break;
case QNativeSocketEngine::BroadcastSocketOption:
n = SO_BROADCAST;
break;
case QNativeSocketEngine::NonBlockingSocketOption:
{
@ -509,47 +523,15 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
return true;
break;
}
case QNativeSocketEngine::AddressReusable:
n = SO_REUSEADDR;
break;
case QNativeSocketEngine::BindExclusively:
n = SO_EXCLUSIVEADDRUSE;
break;
case QNativeSocketEngine::ReceiveOutOfBandData:
n = SO_OOBINLINE;
break;
case QNativeSocketEngine::LowDelayOption:
level = IPPROTO_TCP;
n = TCP_NODELAY;
break;
case QNativeSocketEngine::KeepAliveOption:
n = SO_KEEPALIVE;
break;
case QNativeSocketEngine::MulticastTtlOption:
if (socketProtocol == QAbstractSocket::IPv6Protocol) {
level = IPPROTO_IPV6;
n = IPV6_MULTICAST_HOPS;
} else
{
level = IPPROTO_IP;
n = IP_MULTICAST_TTL;
}
break;
case QNativeSocketEngine::MulticastLoopbackOption:
if (socketProtocol == QAbstractSocket::IPv6Protocol) {
level = IPPROTO_IPV6;
n = IPV6_MULTICAST_LOOP;
} else
{
level = IPPROTO_IP;
n = IP_MULTICAST_LOOP;
}
break;
case QNativeSocketEngine::TypeOfServiceOption:
return false;
default:
break;
}
int n, level;
convertToLevelAndOption(opt, socketProtocol, level, n);
if (::setsockopt(socketDescriptor, level, n, (char*)&v, sizeof(v)) != 0) {
WS_ERROR_DEBUG(WSAGetLastError());
return false;
@ -651,7 +633,7 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
setPortAndAddress(&sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize);
if (socketProtocol == QAbstractSocket::IPv6Protocol && address.toIPv4Address()) {
if ((socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) && address.toIPv4Address()) {
//IPV6_V6ONLY option must be cleared to connect to a V4 mapped address
if (QSysInfo::windowsVersion() >= QSysInfo::WV_6_0) {
DWORD ipv6only = 0;
@ -709,7 +691,7 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
errorDetected = true;
break;
}
if (value == WSAEADDRNOTAVAIL) {
if (value == WSAEADDRNOTAVAIL) {
setError(QAbstractSocket::NetworkError, AddressNotAvailableErrorString);
socketState = QAbstractSocket::UnconnectedState;
errorDetected = true;
@ -858,9 +840,6 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &a, quint16 port)
return false;
}
localPort = port;
localAddress = address;
#if defined (QNATIVESOCKETENGINE_DEBUG)
qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == true",
address.toString().toLatin1().constData(), port);
@ -1037,7 +1016,7 @@ bool QNativeSocketEnginePrivate::nativeLeaveMulticastGroup(const QHostAddress &g
QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const
{
if (socketProtocol == QAbstractSocket::IPv6Protocol) {
if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
uint v;
QT_SOCKOPTLEN_T sizeofv = sizeof(v);
if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &v, &sizeofv) == -1)
@ -1071,7 +1050,7 @@ QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const
bool QNativeSocketEnginePrivate::nativeSetMulticastInterface(const QNetworkInterface &iface)
{
if (socketProtocol == QAbstractSocket::IPv6Protocol) {
if (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) {
uint v = iface.isValid() ? iface.index() : 0;
return (::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &v, sizeof(v)) != -1);
}

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -52,37 +52,6 @@
QT_BEGIN_NAMESPACE
typedef struct {
quint16 majorVersion;
quint16 minorVersion;
quint16 numTables;
quint16 searchRange;
quint16 entrySelector;
quint16 rangeShift;
} OFFSET_TABLE;
typedef struct {
quint32 tag;
quint32 checkSum;
quint32 offset;
quint32 length;
} TABLE_DIRECTORY;
typedef struct {
quint16 fontSelector;
quint16 nrCount;
quint16 storageOffset;
} NAME_TABLE_HEADER;
typedef struct {
quint16 platformID;
quint16 encodingID;
quint16 languageID;
quint16 nameID;
quint16 stringLength;
quint16 stringOffset;
} NAME_RECORD;
void QBasicFontDatabase::populateFontDatabase()
{
QString fontpath = fontDir();
@ -106,6 +75,24 @@ void QBasicFontDatabase::populateFontDatabase()
}
}
inline static void setHintingPreference(QFontEngine *engine, QFont::HintingPreference hintingPreference)
{
switch (hintingPreference) {
case QFont::PreferNoHinting:
engine->setDefaultHintStyle(QFontEngineFT::HintNone);
break;
case QFont::PreferFullHinting:
engine->setDefaultHintStyle(QFontEngineFT::HintFull);
break;
case QFont::PreferVerticalHinting:
engine->setDefaultHintStyle(QFontEngineFT::HintLight);
break;
case QFont::PreferDefaultHinting:
// Leave it as it is
break;
}
}
QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, void *usrPtr)
{
FontFile *fontfile = static_cast<FontFile *> (usrPtr);
@ -114,12 +101,24 @@ QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, void *usrPt
fid.index = fontfile->indexValue;
bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
QFontEngineFT *engine = new QFontEngineFT(fontDef);
QFontEngineFT::GlyphFormat format = QFontEngineFT::Format_Mono;
if (antialias) {
QFontEngine::SubpixelAntialiasingType subpixelType = subpixelAntialiasingTypeHint();
if (subpixelType == QFontEngine::Subpixel_None || (fontDef.styleStrategy & QFont::NoSubpixelAntialias)) {
format = QFontEngineFT::Format_A8;
engine->subpixelType = QFontEngine::Subpixel_None;
} else {
format = QFontEngineFT::Format_A32;
engine->subpixelType = subpixelType;
}
}
if (!engine->init(fid, antialias, format) || engine->invalid()) {
delete engine;
engine = 0;
} else {
setHintingPreference(engine, static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
}
return engine;
@ -172,21 +171,7 @@ QFontEngine *QBasicFontDatabase::fontEngine(const QByteArray &fontData, qreal pi
}
fe->updateFamilyNameAndStyle();
switch (hintingPreference) {
case QFont::PreferNoHinting:
fe->setDefaultHintStyle(QFontEngineFT::HintNone);
break;
case QFont::PreferFullHinting:
fe->setDefaultHintStyle(QFontEngineFT::HintFull);
break;
case QFont::PreferVerticalHinting:
fe->setDefaultHintStyle(QFontEngineFT::HintLight);
break;
default:
// Leave it as it is
break;
}
setHintingPreference(fe, hintingPreference);
return fe;
}
@ -296,7 +281,7 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt
FT_Face face;
FT_Error error;
if (!fontData.isEmpty()) {
error = __ft_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
error = __ft_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
} else {
error = __ft_New_Face(library, file.constData(), index, &face);
}
@ -347,41 +332,26 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt
if (supportedWritingSystems)
*supportedWritingSystems = writingSystems;
if (os2->usWeightClass == 0)
;
else if (os2->usWeightClass < 150)
weight = qt_thinFontWeight;
else if (os2->usWeightClass < 250)
weight = qt_extralightFontWeight;
else if (os2->usWeightClass < 350)
weight = QFont::Light;
else if (os2->usWeightClass < 450)
weight = QFont::Normal;
else if (os2->usWeightClass < 550)
weight = qt_mediumFontWeight;
else if (os2->usWeightClass < 650)
weight = QFont::DemiBold;
else if (os2->usWeightClass < 750)
weight = QFont::Bold;
else if (os2->usWeightClass < 1000)
weight = QFont::Black;
if (os2->panose[2] >= 2) {
if (os2->usWeightClass) {
weight = QPlatformFontDatabase::weightFromInteger(os2->usWeightClass);
} else if (os2->panose[2]) {
int w = os2->panose[2];
if (w <= 1)
weight = qt_thinFontWeight;
weight = QFont::Thin;
else if (w <= 2)
weight = qt_extralightFontWeight;
weight = QFont::ExtraLight;
else if (w <= 3)
weight = QFont::Light;
else if (w <= 5)
weight = QFont::Normal;
else if (w <= 6)
weight = qt_mediumFontWeight;
weight = QFont::Medium;
else if (w <= 7)
weight = QFont::DemiBold;
else if (w <= 8)
weight = QFont::Bold;
else if (w <= 9)
weight = QFont::ExtraBold;
else if (w <= 10)
weight = QFont::Black;
}
@ -404,92 +374,4 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt
return families;
}
QString QBasicFontDatabase::fontNameFromTTFile(const QString &filename)
{
QFile f(filename);
QString retVal;
qint64 bytesRead;
qint64 bytesToRead;
if (f.open(QIODevice::ReadOnly)) {
OFFSET_TABLE ttOffsetTable;
bytesToRead = sizeof(OFFSET_TABLE);
bytesRead = f.read((char*)&ttOffsetTable, bytesToRead);
if (bytesToRead != bytesRead)
return retVal;
ttOffsetTable.numTables = qFromBigEndian(ttOffsetTable.numTables);
ttOffsetTable.majorVersion = qFromBigEndian(ttOffsetTable.majorVersion);
ttOffsetTable.minorVersion = qFromBigEndian(ttOffsetTable.minorVersion);
if (ttOffsetTable.majorVersion != 1 || ttOffsetTable.minorVersion != 0)
return retVal;
TABLE_DIRECTORY tblDir;
bool found = false;
for (int i = 0; i < ttOffsetTable.numTables; i++) {
bytesToRead = sizeof(TABLE_DIRECTORY);
bytesRead = f.read((char*)&tblDir, bytesToRead);
if (bytesToRead != bytesRead)
return retVal;
if (qFromBigEndian(tblDir.tag) == MAKE_TAG('n', 'a', 'm', 'e')) {
found = true;
tblDir.length = qFromBigEndian(tblDir.length);
tblDir.offset = qFromBigEndian(tblDir.offset);
break;
}
}
if (found) {
f.seek(tblDir.offset);
NAME_TABLE_HEADER ttNTHeader;
bytesToRead = sizeof(NAME_TABLE_HEADER);
bytesRead = f.read((char*)&ttNTHeader, bytesToRead);
if (bytesToRead != bytesRead)
return retVal;
ttNTHeader.nrCount = qFromBigEndian(ttNTHeader.nrCount);
ttNTHeader.storageOffset = qFromBigEndian(ttNTHeader.storageOffset);
NAME_RECORD ttRecord;
found = false;
for (int i = 0; i < ttNTHeader.nrCount; i++) {
bytesToRead = sizeof(NAME_RECORD);
bytesRead = f.read((char*)&ttRecord, bytesToRead);
if (bytesToRead != bytesRead)
return retVal;
ttRecord.nameID = qFromBigEndian(ttRecord.nameID);
if (ttRecord.nameID == 1) {
ttRecord.stringLength = qFromBigEndian(ttRecord.stringLength);
ttRecord.stringOffset = qFromBigEndian(ttRecord.stringOffset);
int nPos = f.pos();
f.seek(tblDir.offset + ttRecord.stringOffset + ttNTHeader.storageOffset);
QByteArray nameByteArray = f.read(ttRecord.stringLength);
if (!nameByteArray.isEmpty()) {
if (ttRecord.encodingID == 256 || ttRecord.encodingID == 768) {
//This is UTF-16 in big endian
int stringLength = ttRecord.stringLength / 2;
retVal.resize(stringLength);
QChar *data = retVal.data();
const ushort *srcData = (const ushort *)nameByteArray.data();
for (int i = 0; i < stringLength; ++i)
data[i] = qFromBigEndian(srcData[i]);
return retVal;
} else if (ttRecord.encodingID == 0) {
//This is Latin1
retVal = QString::fromLatin1(nameByteArray);
} else {
qWarning("Could not retrieve Font name from file: %s", qPrintable(QDir::toNativeSeparators(filename)));
}
break;
}
f.seek(nPos);
}
}
}
f.close();
}
return retVal;
}
QT_END_NAMESPACE

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -54,6 +54,13 @@
QT_BEGIN_NAMESPACE
static const int maxWeight = 99;
static inline int mapToQtWeightForRange(int fcweight, int fcLower, int fcUpper, int qtLower, int qtUpper)
{
return qtLower + ((fcweight - fcLower) * (qtUpper - qtLower)) / (fcUpper - fcLower);
}
static inline bool requiresOpenType(int writingSystem)
{
return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
@ -68,26 +75,28 @@ static inline int weightFromFcWeight(int fcweight)
// mapping. This ensures that where there is a corresponding enum on both sides (for example
// FC_WEIGHT_DEMIBOLD and QFont::DemiBold) we map one to the other but other values map
// to intermediate Qt weights.
const int maxWeight = 99;
int qtweight;
if (fcweight < 0)
qtweight = 0;
else if (fcweight <= FC_WEIGHT_LIGHT)
qtweight = (fcweight * QFont::Light) / FC_WEIGHT_LIGHT;
else if (fcweight <= FC_WEIGHT_NORMAL)
qtweight = QFont::Light + ((fcweight - FC_WEIGHT_LIGHT) * (QFont::Normal - QFont::Light)) / (FC_WEIGHT_NORMAL - FC_WEIGHT_LIGHT);
else if (fcweight <= FC_WEIGHT_DEMIBOLD)
qtweight = QFont::Normal + ((fcweight - FC_WEIGHT_NORMAL) * (QFont::DemiBold - QFont::Normal)) / (FC_WEIGHT_DEMIBOLD - FC_WEIGHT_NORMAL);
else if (fcweight <= FC_WEIGHT_BOLD)
qtweight = QFont::DemiBold + ((fcweight - FC_WEIGHT_DEMIBOLD) * (QFont::Bold - QFont::DemiBold)) / (FC_WEIGHT_BOLD - FC_WEIGHT_DEMIBOLD);
else if (fcweight <= FC_WEIGHT_BLACK)
qtweight = QFont::Bold + ((fcweight - FC_WEIGHT_BOLD) * (QFont::Black - QFont::Bold)) / (FC_WEIGHT_BLACK - FC_WEIGHT_BOLD);
else if (fcweight <= FC_WEIGHT_ULTRABLACK)
qtweight = QFont::Black + ((fcweight - FC_WEIGHT_BLACK) * (maxWeight - QFont::Black)) / (FC_WEIGHT_ULTRABLACK - FC_WEIGHT_BLACK);
else
qtweight = maxWeight;
return qtweight;
if (fcweight <= FC_WEIGHT_THIN)
return QFont::Thin;
if (fcweight <= FC_WEIGHT_ULTRALIGHT)
return mapToQtWeightForRange(fcweight, FC_WEIGHT_THIN, FC_WEIGHT_ULTRALIGHT, QFont::Thin, QFont::ExtraLight);
if (fcweight <= FC_WEIGHT_LIGHT)
return mapToQtWeightForRange(fcweight, FC_WEIGHT_ULTRALIGHT, FC_WEIGHT_LIGHT, QFont::ExtraLight, QFont::Light);
if (fcweight <= FC_WEIGHT_NORMAL)
return mapToQtWeightForRange(fcweight, FC_WEIGHT_LIGHT, FC_WEIGHT_NORMAL, QFont::Light, QFont::Normal);
if (fcweight <= FC_WEIGHT_MEDIUM)
return mapToQtWeightForRange(fcweight, FC_WEIGHT_NORMAL, FC_WEIGHT_MEDIUM, QFont::Normal, QFont::Medium);
if (fcweight <= FC_WEIGHT_DEMIBOLD)
return mapToQtWeightForRange(fcweight, FC_WEIGHT_MEDIUM, FC_WEIGHT_DEMIBOLD, QFont::Medium, QFont::DemiBold);
if (fcweight <= FC_WEIGHT_BOLD)
return mapToQtWeightForRange(fcweight, FC_WEIGHT_DEMIBOLD, FC_WEIGHT_BOLD, QFont::DemiBold, QFont::Bold);
if (fcweight <= FC_WEIGHT_ULTRABOLD)
return mapToQtWeightForRange(fcweight, FC_WEIGHT_BOLD, FC_WEIGHT_ULTRABOLD, QFont::Bold, QFont::ExtraBold);
if (fcweight <= FC_WEIGHT_BLACK)
return mapToQtWeightForRange(fcweight, FC_WEIGHT_ULTRABOLD, FC_WEIGHT_BLACK, QFont::ExtraBold, QFont::Black);
if (fcweight <= FC_WEIGHT_ULTRABLACK)
return mapToQtWeightForRange(fcweight, FC_WEIGHT_BLACK, FC_WEIGHT_ULTRABLACK, QFont::Black, maxWeight);
return maxWeight;
}
static inline int stretchFromFcWidth(int fcwidth)
@ -209,7 +218,30 @@ static const char *specialLanguages[] = {
"hmd", // Miao
"sa", // Sharada
"srb", // SoraSompeng
"doi" // Takri
"doi", // Takri
"lez", // CaucasianAlbanian
"bsq", // BassaVah
"fr", // Duployan
"sq", // Elbasan
"sa", // Grantha
"hnj", // PahawhHmong
"sd", // Khojki
"lab", // LinearA
"hi", // Mahajani
"xmn", // Manichaean
"men", // MendeKikakui
"mr", // Modi
"mru", // Mro
"xna", // OldNorthArabian
"arc", // Nabataean
"arc", // Palmyrene
"ctd", // PauCinHau
"kv", // OldPermic
"pal", // PsalterPahlavi
"sa", // Siddham
"sd", // Khudawadi
"mai", // Tirhuta
"hoc" // WarangCiti
};
Q_STATIC_ASSERT(sizeof(specialLanguages) / sizeof(const char *) == QChar::ScriptCount);
@ -270,7 +302,7 @@ static const char *openType[] = {
"deva", // Devanagari
"beng", // Bengali
"guru", // Gurmukhi
"gurj", // Gujarati
"gujr", // Gujarati
"orya", // Oriya
"taml", // Tamil
"telu", // Telugu
@ -530,6 +562,28 @@ QFontEngine::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintin
break;
}
if (QGuiApplication::platformNativeInterface()->nativeResourceForScreen("nofonthinting",
QGuiApplication::primaryScreen())) {
return QFontEngine::HintNone;
}
int hint_style = 0;
if (FcPatternGetInteger (match, FC_HINT_STYLE, 0, &hint_style) == FcResultMatch) {
switch (hint_style) {
case FC_HINT_NONE:
return QFontEngine::HintNone;
case FC_HINT_SLIGHT:
return QFontEngine::HintLight;
case FC_HINT_MEDIUM:
return QFontEngine::HintMedium;
case FC_HINT_FULL:
return QFontEngine::HintFull;
default:
Q_UNREACHABLE();
break;
}
}
if (useXftConf) {
void *hintStyleResource =
QGuiApplication::platformNativeInterface()->nativeResourceForScreen("hintstyle",
@ -539,27 +593,31 @@ QFontEngine::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintin
return QFontEngine::HintStyle(hintStyle - 1);
}
int hint_style = 0;
if (FcPatternGetInteger (match, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)
hint_style = FC_HINT_FULL;
switch (hint_style) {
case FC_HINT_NONE:
return QFontEngine::HintNone;
case FC_HINT_SLIGHT:
return QFontEngine::HintLight;
case FC_HINT_MEDIUM:
return QFontEngine::HintMedium;
case FC_HINT_FULL:
return QFontEngine::HintFull;
default:
Q_UNREACHABLE();
break;
}
return QFontEngine::HintFull;
}
QFontEngine::SubpixelAntialiasingType subpixelTypeFromMatch(FcPattern *match, bool useXftConf)
{
int subpixel = FC_RGBA_UNKNOWN;
if (FcPatternGetInteger(match, FC_RGBA, 0, &subpixel) == FcResultMatch) {
switch (subpixel) {
case FC_RGBA_UNKNOWN:
case FC_RGBA_NONE:
return QFontEngine::Subpixel_None;
case FC_RGBA_RGB:
return QFontEngine::Subpixel_RGB;
case FC_RGBA_BGR:
return QFontEngine::Subpixel_BGR;
case FC_RGBA_VRGB:
return QFontEngine::Subpixel_VRGB;
case FC_RGBA_VBGR:
return QFontEngine::Subpixel_VBGR;
default:
Q_UNREACHABLE();
break;
}
}
if (useXftConf) {
void *subpixelTypeResource =
QGuiApplication::platformNativeInterface()->nativeResourceForScreen("subpixeltype",
@ -569,25 +627,6 @@ QFontEngine::SubpixelAntialiasingType subpixelTypeFromMatch(FcPattern *match, bo
return QFontEngine::SubpixelAntialiasingType(subpixelType - 1);
}
int subpixel = FC_RGBA_UNKNOWN;
FcPatternGetInteger(match, FC_RGBA, 0, &subpixel);
switch (subpixel) {
case FC_RGBA_UNKNOWN:
case FC_RGBA_NONE:
return QFontEngine::Subpixel_None;
case FC_RGBA_RGB:
return QFontEngine::Subpixel_RGB;
case FC_RGBA_BGR:
return QFontEngine::Subpixel_BGR;
case FC_RGBA_VRGB:
return QFontEngine::Subpixel_VRGB;
case FC_RGBA_VBGR:
return QFontEngine::Subpixel_VBGR;
default:
Q_UNREACHABLE();
break;
}
return QFontEngine::Subpixel_None;
}
} // namespace
@ -836,10 +875,8 @@ void QFontconfigDatabase::setupFontEngine(QFontEngineFT *engine, const QFontDef
QGuiApplication::platformNativeInterface()->nativeResourceForScreen("antialiasingEnabled",
QGuiApplication::primaryScreen());
int antialiasingEnabled = int(reinterpret_cast<qintptr>(antialiasResource));
if (antialiasingEnabled > 0) {
if (antialiasingEnabled > 0)
antialias = antialiasingEnabled - 1;
forcedAntialiasSetting = true;
}
}
QFontEngine::GlyphFormat format;

View File

@ -1,40 +1,32 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
@ -56,6 +48,18 @@
QT_BEGIN_NAMESPACE
namespace {
class AutoReleasePool
{
public:
AutoReleasePool(): pool([[NSAutoreleasePool alloc] init]) {}
~AutoReleasePool() { [pool release]; }
private:
NSAutoreleasePool *pool;
};
}
// this could become a list of all languages used for each writing
// system, instead of using the single most common language.
static const char *languageForWritingSystem[] = {
@ -177,6 +181,8 @@ QCoreTextFontDatabase::QCoreTextFontDatabase()
QCoreTextFontDatabase::~QCoreTextFontDatabase()
{
foreach (CTFontDescriptorRef ref, m_systemFontDescriptors)
CFRelease(ref);
}
static CFArrayRef availableFamilyNames()
@ -268,47 +274,37 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
fd->fixedPitch = false;
if (QCFType<CTFontRef> tempFont = CTFontCreateWithFontDescriptor(font, 0.0, 0)) {
uint length = 0;
uint tag = MAKE_TAG('O', 'S', '/', '2');
CTFontRef tempFontRef = tempFont;
void *userData = reinterpret_cast<void *>(&tempFontRef);
if (QCoreTextFontEngine::ct_getSfntTable(userData, tag, 0, &length)) {
QVarLengthArray<uchar> os2Table(length);
if (length >= 86 && QCoreTextFontEngine::ct_getSfntTable(userData, tag, os2Table.data(), &length)) {
quint32 unicodeRange[4] = {
qFromBigEndian<quint32>(os2Table.data() + 42),
qFromBigEndian<quint32>(os2Table.data() + 46),
qFromBigEndian<quint32>(os2Table.data() + 50),
qFromBigEndian<quint32>(os2Table.data() + 54)
};
quint32 codePageRange[2] = { qFromBigEndian<quint32>(os2Table.data() + 78),
qFromBigEndian<quint32>(os2Table.data() + 82) };
fd->writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
uint length = 128;
QVarLengthArray<uchar, 128> os2Table(length);
if (QCoreTextFontEngine::ct_getSfntTable(userData, tag, os2Table.data(), &length) && length >= 86) {
if (length > uint(os2Table.length())) {
os2Table.resize(length);
if (!QCoreTextFontEngine::ct_getSfntTable(userData, tag, os2Table.data(), &length))
Q_UNREACHABLE();
Q_ASSERT(length >= 86);
}
quint32 unicodeRange[4] = {
qFromBigEndian<quint32>(os2Table.data() + 42),
qFromBigEndian<quint32>(os2Table.data() + 46),
qFromBigEndian<quint32>(os2Table.data() + 50),
qFromBigEndian<quint32>(os2Table.data() + 54)
};
quint32 codePageRange[2] = {
qFromBigEndian<quint32>(os2Table.data() + 78),
qFromBigEndian<quint32>(os2Table.data() + 82)
};
fd->writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
}
}
if (styles) {
if (CFNumberRef weightValue = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
double normalizedWeight;
if (CFNumberGetValue(weightValue, kCFNumberDoubleType, &normalizedWeight)) {
if (normalizedWeight >= 0.62)
fd->weight = QFont::Black;
else if (normalizedWeight >= 0.4)
fd->weight = QFont::Bold;
else if (normalizedWeight >= 0.3)
fd->weight = QFont::DemiBold;
else if (normalizedWeight >= 0.2)
fd->weight = qt_mediumFontWeight;
else if (normalizedWeight == 0.0)
fd->weight = QFont::Normal;
else if (normalizedWeight <= -0.4)
fd->weight = QFont::Light;
else if (normalizedWeight <= -0.6)
fd->weight = qt_extralightFontWeight;
else if (normalizedWeight <= -0.8)
fd->weight = qt_thinFontWeight;
}
float normalizedWeight;
if (CFNumberGetValue(weightValue, kCFNumberFloatType, &normalizedWeight))
fd->weight = QCoreTextFontEngine::qtWeightFromCFWeight(normalizedWeight);
}
if (CFNumberRef italic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
double d;
@ -356,11 +352,7 @@ void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font)
{
FontDescription fd;
getFontDescription(font, &fd);
populateFromFontDescription(font, fd);
}
void QCoreTextFontDatabase::populateFromFontDescription(CTFontDescriptorRef font, const FontDescription &fd)
{
CFRetain(font);
QPlatformFontDatabase::registerFont(fd.familyName, fd.styleName, fd.foundryName, fd.weight, fd.style, fd.stretch,
true /* antialiased */, true /* scalable */,
@ -372,6 +364,8 @@ void QCoreTextFontDatabase::releaseHandle(void *handle)
CFRelease(CTFontDescriptorRef(handle));
}
extern CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, void *usrPtr)
{
qreal scaledPointSize = f.pixelSize;
@ -386,7 +380,8 @@ QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, void *usrPtr)
scaledPointSize = f.pointSize;
CTFontDescriptorRef descriptor = (CTFontDescriptorRef) usrPtr;
CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, NULL);
CGAffineTransform matrix = qt_transform_from_fontdef(f);
CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, &matrix);
if (font) {
QFontEngine *engine = new QCoreTextFontEngine(font, f);
engine->fontDef = f;
@ -462,6 +457,8 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
Q_UNUSED(style);
Q_UNUSED(script);
AutoReleasePool pool;
static QHash<QString, QStringList> fallbackLists;
if (!family.isEmpty()) {
@ -830,7 +827,11 @@ QFont *QCoreTextFontDatabase::themeFont(QPlatformTheme::Font f) const
CTFontDescriptorRef fontDesc = fontDescriptorFromTheme(f);
FontDescription fd;
getFontDescription(fontDesc, &fd);
m_systemFontDescriptors.insert(fontDesc);
if (!m_systemFontDescriptors.contains(fontDesc))
m_systemFontDescriptors.insert(fontDesc);
else
CFRelease(fontDesc);
QFont *font = new QFont(fd.familyName, fd.pixelSize, fd.weight, fd.style == QFont::StyleItalic);
return font;
@ -846,6 +847,11 @@ QFont QCoreTextFontDatabase::defaultFont() const
return QFont(defaultFontName);
}
bool QCoreTextFontDatabase::fontsAlwaysScalable() const
{
return true;
}
QList<int> QCoreTextFontDatabase::standardSizes() const
{
QList<int> ret;

View File

@ -1,40 +1,32 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
@ -88,12 +80,14 @@
QT_USE_NAMESPACE
QT_BEGIN_NAMESPACE
static QCocoaApplicationDelegate *sharedCocoaApplicationDelegate = nil;
static void cleanupCocoaApplicationDelegate()
{
[sharedCocoaApplicationDelegate release];
}
QT_END_NAMESPACE
@implementation QCocoaApplicationDelegate

View File

@ -1,41 +1,33 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Copyright (C) 2015 The Qt Company Ltd.
** Copyright (C) 2012 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Christoph Schleifenbaum <christoph.schleifenbaum@kdab.com>
** Contact: http://www.qt-project.org/legal
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
@ -102,7 +94,7 @@ QT_USE_NAMESPACE
QCocoaSystemTrayIcon *systray;
NSStatusItem *item;
QCocoaMenu *menu;
bool menuVisible, iconSelected;
bool menuVisible, iconSelected;
QIcon icon;
QT_MANGLE_NAMESPACE(QNSImageView) *imageCell;
}
@ -188,7 +180,7 @@ void QCocoaSystemTrayIcon::cleanup()
}
static bool heightCompareFunction (QSize a, QSize b) { return (a.height() < b.height()); }
static QList<QSize> sortByHeight(const QList<QSize> sizes)
static QList<QSize> sortByHeight(const QList<QSize> &sizes)
{
QList<QSize> sorted = sizes;
std::sort(sorted.begin(), sorted.end(), heightCompareFunction);
@ -216,7 +208,7 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
// devicePixelRatio for the "best" screen on the system.
qreal devicePixelRatio = qApp->devicePixelRatio();
const int maxPixmapHeight = maxImageHeight * devicePixelRatio;
const QIcon::Mode mode = m_sys->item->iconSelected ? QIcon::Selected : QIcon::Normal;
const QIcon::Mode mode = m_sys->item->iconSelected ? QIcon::Selected : QIcon::Normal;
QSize selectedSize;
Q_FOREACH (const QSize& size, sortByHeight(icon.availableSizes(mode))) {
// Select a pixmap based on the height. We want the largest pixmap
@ -232,6 +224,10 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
}
}
// Handle SVG icons, which do not return anything for availableSizes().
if (!selectedSize.isValid())
selectedSize = icon.actualSize(QSize(maxPixmapHeight, maxPixmapHeight), mode);
QPixmap pixmap = icon.pixmap(selectedSize, mode);
// Draw a low-resolution icon if there is not enough pixels for a retina
@ -391,8 +387,8 @@ QT_END_NAMESPACE
down = YES;
int clickCount = [mouseEvent clickCount];
[self setNeedsDisplay:YES];
parent->iconSelected = (clickCount != 2) && parent->menu;
parent->iconSelected = (clickCount != 2) && parent->menu;
parent->systray->updateIcon(parent->icon);
if (clickCount == 2) {
@ -445,7 +441,7 @@ QT_END_NAMESPACE
}
-(void)drawRect:(NSRect)rect {
[[parent item] drawStatusBarBackgroundInRect:rect withHighlight:parent->menu ? down : NO];
[[parent item] drawStatusBarBackgroundInRect:rect withHighlight:parent->menu ? down : NO];
[super drawRect:rect];
}
@end
@ -458,7 +454,7 @@ QT_END_NAMESPACE
if (self) {
item = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
menu = 0;
menuVisible = false;
menuVisible = false;
systray = sys;
imageCell = [[QNSImageView alloc] initWithParent:self];
[item setView: imageCell];
@ -468,6 +464,7 @@ QT_END_NAMESPACE
-(void)dealloc {
[[NSStatusBar systemStatusBar] removeStatusItem:item];
[[NSNotificationCenter defaultCenter] removeObserver:imageCell];
[imageCell release];
[item release];
[super dealloc];
@ -502,7 +499,7 @@ QT_END_NAMESPACE
selector:@selector(menuTrackingDone:)
name:NSMenuDidEndTrackingNotification
object:m];
menuVisible = true;
menuVisible = true;
[item popUpStatusItemMenu: m];
}
}

View File

@ -1,40 +1,32 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
@ -82,31 +74,6 @@ static bool isMouseEvent(NSEvent *ev)
}
}
static void selectNextKeyWindow(NSWindow *currentKeyWindow)
{
if (!currentKeyWindow)
return;
const QCocoaAutoReleasePool pool;
if ([[NSApplication sharedApplication] keyWindow] != currentKeyWindow)
return;//currentKeyWindow is not a key window actually.
NSArray *const windows = [[NSApplication sharedApplication] windows];
bool startLookup = false;
for (NSWindow *candidate in [windows reverseObjectEnumerator]) {
if (!startLookup) {
if (candidate == currentKeyWindow)
startLookup = true;
} else {
if ([candidate isVisible] && [candidate canBecomeKeyWindow]) {
[candidate makeKeyWindow];
break;
}
}
}
}
@implementation QNSWindowHelper
@synthesize window = _window;
@ -379,6 +346,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_synchedWindowState(Qt::WindowActive)
, m_windowModality(Qt::NonModal)
, m_windowUnderMouse(false)
, m_ignoreWindowShouldClose(false)
, m_inConstructor(true)
, m_inSetVisible(false)
, m_inSetGeometry(false)
@ -447,11 +415,28 @@ QCocoaWindow::~QCocoaWindow()
if (m_isNSWindowChild) {
if (m_parentCocoaWindow)
m_parentCocoaWindow->removeChildWindow(this);
} else if (parent()) {
} else if ([m_contentView superview]) {
[m_contentView removeFromSuperview];
} else if (m_qtView) {
[[NSNotificationCenter defaultCenter] removeObserver:m_qtView
name:nil object:m_nsWindow];
}
// Make sure to disconnect observer in all case if view is valid
// to avoid notifications received when deleting when using Qt::AA_NativeWindows attribute
if (m_qtView) {
[[NSNotificationCenter defaultCenter] removeObserver:m_qtView];
}
// The QNSView object may outlive the corresponding QCocoaWindow object,
// for example during app shutdown when the QNSView is embedded in a
// foregin NSView hiearchy. Clear the pointers to the QWindow/QCocoaWindow
// here to make sure QNSView does not dereference stale pointers.
if (m_qtView) {
[m_qtView clearQWindowPointers];
}
// While it is unlikely that this window will be in the popup stack
// during deletetion we clear any pointers here to make sure.
if (QCocoaIntegration::instance()) {
QCocoaIntegration::instance()->popupWindowStack()->removeAll(this);
}
foreach (QCocoaWindow *child, m_childWindows) {
@ -466,7 +451,13 @@ QCocoaWindow::~QCocoaWindow()
QSurfaceFormat QCocoaWindow::format() const
{
return window()->requestedFormat();
QSurfaceFormat format = window()->requestedFormat();
// Upgrade the default surface format to include an alpha channel. The default RGB format
// causes Cocoa to spend an unreasonable amount of time converting it to RGBA internally.
if (format == QSurfaceFormat())
format.setAlphaBufferSize(8);
return format;
}
void QCocoaWindow::setGeometry(const QRect &rectIn)
@ -599,9 +590,6 @@ void QCocoaWindow::hide(bool becauseOfAncestor)
foreach (QCocoaWindow *childWindow, m_childWindows)
childWindow->hide(true);
if (window()->transientParent() && m_nsWindow == [[NSApplication sharedApplication] keyWindow])
selectNextKeyWindow(m_nsWindow); // Otherwise, Cocoa can do it wrong.
[m_nsWindow orderOut:nil];
}
@ -646,17 +634,17 @@ void QCocoaWindow::setVisible(bool visible)
// We need to recreate if the modality has changed as the style mask will need updating
if (m_windowModality != window()->modality())
recreateWindow(parent());
// Register popup windows. The Cocoa platform plugin will forward mouse events
// to them and close them when needed.
if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip)
QCocoaIntegration::instance()->pushPopupWindow(this);
if (parentCocoaWindow) {
// The parent window might have moved while this window was hidden,
// update the window geometry if there is a parent.
setGeometry(window()->geometry());
// Register popup windows so that the parent window can close them when needed.
if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) {
// qDebug() << "transientParent and popup" << window()->type() << Qt::Popup << (window()->type() & Qt::Popup);
parentCocoaWindow->m_activePopupWindow = window();
}
if (window()->type() == Qt::Popup) {
// QTBUG-30266: a window should not be resizable while a transient popup is open
// Since this isn't a native popup, the window manager doesn't close the popup when you click outside
@ -708,8 +696,10 @@ void QCocoaWindow::setVisible(bool visible)
&& [m_nsWindow isKindOfClass:[NSPanel class]]) {
[(NSPanel *)m_nsWindow setWorksWhenModal:YES];
if (!(parentCocoaWindow && window()->transientParent()->isActive()) && window()->type() == Qt::Popup) {
monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDown handler:^(NSEvent *) {
QWindowSystemInterface::handleMouseEvent(window(), QPointF(-1, -1), QPointF(window()->framePosition() - QPointF(1, 1)), Qt::LeftButton);
monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDownMask|NSMouseMovedMask handler:^(NSEvent *e) {
QPointF localPoint = qt_mac_flipPoint([NSEvent mouseLocation]);
QWindowSystemInterface::handleMouseEvent(window(), window()->mapFromGlobal(localPoint.toPoint()), localPoint,
cocoaButton2QtButton([e buttonNumber]));
}];
}
}
@ -758,8 +748,11 @@ void QCocoaWindow::setVisible(bool visible)
[NSEvent removeMonitor:monitor];
monitor = nil;
}
if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip)
QCocoaIntegration::instance()->popupWindowStack()->removeAll(this);
if (parentCocoaWindow && window()->type() == Qt::Popup) {
parentCocoaWindow->m_activePopupWindow = 0;
if (m_resizableTransientParent
&& !([parentCocoaWindow->m_nsWindow styleMask] & NSFullScreenWindowMask))
// QTBUG-30266: a window should not be resizable while a transient popup is open
@ -806,9 +799,22 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
if (flags & Qt::FramelessWindowHint)
return styleMask;
if ((type & Qt::Popup) == Qt::Popup) {
if (!windowIsPopupType(type))
styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask | NSTitledWindowMask);
if (!windowIsPopupType(type)) {
styleMask = NSUtilityWindowMask;
if (!(flags & Qt::CustomizeWindowHint)) {
styleMask |= NSResizableWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask | NSTitledWindowMask;
} else {
if (flags & Qt::WindowMaximizeButtonHint)
styleMask |= NSResizableWindowMask;
if (flags & Qt::WindowTitleHint)
styleMask |= NSTitledWindowMask;
if (flags & Qt::WindowCloseButtonHint)
styleMask |= NSClosableWindowMask;
if (flags & Qt::WindowMinimizeButtonHint)
styleMask |= NSMiniaturizableWindowMask;
}
}
} else {
if (type == Qt::Window && !(flags & Qt::CustomizeWindowHint)) {
styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask);
@ -1181,10 +1187,9 @@ void QCocoaWindow::setEmbeddedInForeignView(bool embedded)
void QCocoaWindow::windowWillMove()
{
// Close any open popups on window move
if (m_activePopupWindow) {
QWindowSystemInterface::handleCloseEvent(m_activePopupWindow);
while (QCocoaWindow *popup = QCocoaIntegration::instance()->popPopupWindow()) {
QWindowSystemInterface::handleCloseEvent(popup->window());
QWindowSystemInterface::flushWindowSystemEvents();
m_activePopupWindow = 0;
}
}
@ -1218,6 +1223,9 @@ void QCocoaWindow::windowDidEndLiveResize()
bool QCocoaWindow::windowShouldClose()
{
// might have been set from qnsview.mm
if (m_ignoreWindowShouldClose)
return false;
bool accepted = false;
QWindowSystemInterface::handleCloseEvent(window(), &accepted);
QWindowSystemInterface::flushWindowSystemEvents();
@ -1512,19 +1520,33 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState)
}
Qt::WindowState predictedState = newState;
if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized)) {
const int styleMask = [m_nsWindow styleMask];
const bool usePerform = styleMask & NSResizableWindowMask;
[m_nsWindow setStyleMask:styleMask | NSResizableWindowMask];
if (usePerform)
[m_nsWindow performZoom : m_nsWindow]; // toggles
else
[m_nsWindow zoom : m_nsWindow]; // toggles
[m_nsWindow setStyleMask:styleMask];
}
if ((m_synchedWindowState & Qt::WindowMinimized) != (newState & Qt::WindowMinimized)) {
if (newState & Qt::WindowMinimized) {
[m_nsWindow performMiniaturize : m_nsWindow];
if ([m_nsWindow styleMask] & NSMiniaturizableWindowMask)
[m_nsWindow performMiniaturize : m_nsWindow];
else
[m_nsWindow miniaturize : m_nsWindow];
} else {
[m_nsWindow deminiaturize : m_nsWindow];
}
}
const bool effMax = m_effectivelyMaximized;
if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized) || (m_effectivelyMaximized && newState == Qt::WindowNoState)) {
if ((m_synchedWindowState & Qt::WindowFullScreen) == (newState & Qt::WindowFullScreen)) {
[m_nsWindow zoom : m_nsWindow]; // toggles
m_effectivelyMaximized = !m_effectivelyMaximized;
m_effectivelyMaximized = !effMax;
} else if (!(newState & Qt::WindowMaximized)) {
// it would be nice to change the target geometry that toggleFullScreen will animate toward
// but there is no known way, so the maximized state is not possible at this time

View File

@ -1,40 +1,32 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
@ -83,7 +75,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
- (CGFloat)deviceDeltaZ;
@end
@interface QNSViewMouseMoveHelper : NSObject
@interface QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) : NSObject
{
QNSView *view;
}
@ -97,7 +89,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
@end
@implementation QNSViewMouseMoveHelper
@implementation QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)
- (id)initWithView:(QNSView *)theView
{
@ -158,13 +150,14 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
currentCustomDragTypes = 0;
m_sendUpAsRightButton = false;
m_inputSource = 0;
m_mouseMoveHelper = [[QNSViewMouseMoveHelper alloc] initWithView:self];
m_mouseMoveHelper = [[QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) alloc] initWithView:self];
m_resendKeyEvent = false;
m_scrolling = false;
if (!touchDevice) {
touchDevice = new QTouchDevice;
touchDevice->setType(QTouchDevice::TouchPad);
touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition);
touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition | QTouchDevice::MouseEmulation);
QWindowSystemInterface::registerTouchDevice(touchDevice);
}
}
@ -174,6 +167,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
- (void)dealloc
{
CGImageRelease(m_maskImage);
[m_trackingArea release];
m_maskImage = 0;
m_window = 0;
m_subscribesForGlobalFrameNotifications = false;
@ -195,6 +189,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
m_window = window;
m_platformWindow = platformWindow;
m_sendKeyEvent = false;
m_trackingArea = nil;
#ifdef QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR
// prevent rift in space-time continuum, disable
@ -221,6 +216,12 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
return self;
}
- (void) clearQWindowPointers
{
m_window = 0;
m_platformWindow = 0;
}
#ifndef QT_NO_OPENGL
- (void) setQCocoaGLContext:(QCocoaGLContext *)context
{
@ -271,10 +272,13 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
if (self.window) {
// This is the case of QWidgetAction's generated QWidget inserted in an NSMenu.
// 10.9 and newer get the NSWindowDidChangeOcclusionStateNotification
if (!_q_NSWindowDidChangeOcclusionStateNotification
&& [self.window.className isEqualToString:@"NSCarbonMenuWindow"])
if ((!_q_NSWindowDidChangeOcclusionStateNotification
&& [self.window.className isEqualToString:@"NSCarbonMenuWindow"])) {
m_exposedOnMoveToWindow = true;
m_platformWindow->exposeWindow();
} else {
}
} else if (m_exposedOnMoveToWindow) {
m_exposedOnMoveToWindow = false;
m_platformWindow->obscureWindow();
}
}
@ -366,6 +370,8 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
// calles, which Qt and Qt applications do not excpect.
if (!m_platformWindow->m_inSetGeometry)
QWindowSystemInterface::flushWindowSystemEvents();
else
m_backingStore = QImage();
}
}
@ -415,8 +421,8 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
&& [notificationName isEqualToString:_q_NSWindowDidChangeOcclusionStateNotification]) {
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9
// ### HACK Remove the enum declaration, the warning disabling and the cast further down once 10.8 is unsupported
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-method-access"
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wobjc-method-access")
enum { NSWindowOcclusionStateVisible = 1UL << 1 };
#endif
if ((NSUInteger)[self.window occlusionState] & NSWindowOcclusionStateVisible) {
@ -431,7 +437,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
m_platformWindow->obscureWindow();
}
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9
#pragma clang diagnostic pop
QT_WARNING_POP
#endif
} else if (notificationName == NSWindowDidChangeScreenNotification) {
if (m_window) {
@ -485,6 +491,8 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
- (BOOL) isOpaque
{
if (!m_platformWindow)
return true;
return m_platformWindow->isOpaque();
}
@ -689,6 +697,12 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
m_platformWindow->m_forwardWindow = 0;
}
// Popups implicitly grap mouse events; forward to the active popup if there is one
if (QCocoaWindow *popup = QCocoaIntegration::instance()->activePopupWindow()) {
if (QNSView *popupView = popup->qtView())
targetView = popupView;
}
[targetView convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
ulong timestamp = [theEvent timestamp] * 1000;
@ -739,12 +753,13 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
NSPoint windowPoint = [theEvent locationInWindow];
int windowScreenY = [window frame].origin.y + [window frame].size.height;
int viewScreenY = [window convertBaseToScreen:[self convertPoint:[self frame].origin toView:nil]].y;
NSPoint windowCoord = [self convertPoint:[self frame].origin toView:nil];
int viewScreenY = [window convertRectToScreen:NSMakeRect(windowCoord.x, windowCoord.y, 0, 0)].origin.y;
int titleBarHeight = windowScreenY - viewScreenY;
NSPoint nsViewPoint = [self convertPoint: windowPoint fromView: nil];
QPoint qtWindowPoint = QPoint(nsViewPoint.x, titleBarHeight + nsViewPoint.y);
NSPoint screenPoint = [window convertBaseToScreen:windowPoint];
NSPoint screenPoint = [window convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 0, 0)].origin;
QPoint qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y));
ulong timestamp = [theEvent timestamp] * 1000;
@ -756,21 +771,41 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
if (m_window->flags() & Qt::WindowTransparentForInput)
return [super mouseDown:theEvent];
m_sendUpAsRightButton = false;
if (m_platformWindow->m_activePopupWindow) {
Qt::WindowType type = m_platformWindow->m_activePopupWindow->type();
QWindowSystemInterface::handleCloseEvent(m_platformWindow->m_activePopupWindow);
QWindowSystemInterface::flushWindowSystemEvents();
m_platformWindow->m_activePopupWindow = 0;
// Consume the mouse event when closing the popup, except for tool tips
// were it's expected that the event is processed normally.
if (type != Qt::ToolTip)
return;
}
if ([self hasMarkedText]) {
NSInputManager* inputManager = [NSInputManager currentInputManager];
if ([inputManager wantsToHandleMouseEvents]) {
[inputManager handleMouseEvent:theEvent];
// Handle any active poup windows; clicking outisde them should close them
// all. Don't do anything or clicks inside one of the menus, let Cocoa
// handle that case. Note that in practice many windows of the Qt::Popup type
// will actually close themselves in this case using logic implemented in
// that particular poup type (for example context menus). However, Qt expects
// that plain popup QWindows will also be closed, so we implement the logic
// here as well.
QList<QCocoaWindow *> *popups = QCocoaIntegration::instance()->popupWindowStack();
if (!popups->isEmpty()) {
// Check if the click is outside all popups.
bool inside = false;
QPointF qtScreenPoint = qt_mac_flipPoint([self screenMousePoint:theEvent]);
for (QList<QCocoaWindow *>::const_iterator it = popups->begin(); it != popups->end(); ++it) {
if ((*it)->geometry().contains(qtScreenPoint.toPoint())) {
inside = true;
break;
}
}
// Close the popups if the click was outside.
if (!inside) {
Qt::WindowType type = QCocoaIntegration::instance()->activePopupWindow()->window()->type();
while (QCocoaWindow *popup = QCocoaIntegration::instance()->popPopupWindow()) {
QWindowSystemInterface::handleCloseEvent(popup->window());
QWindowSystemInterface::flushWindowSystemEvents();
}
// Consume the mouse event when closing the popup, except for tool tips
// were it's expected that the event is processed normally.
if (type != Qt::ToolTip)
return;
}
}
if ([self hasMarkedText]) {
[[NSTextInputContext currentInputContext] handleEvent:theEvent];
} else {
if ([QNSView convertKeyModifiers:[theEvent modifierFlags]] & Qt::MetaModifier) {
m_buttons |= Qt::RightButton;
@ -808,19 +843,11 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
{
[super updateTrackingAreas];
// [NSView addTrackingArea] is slow, so bail out early if we can:
if (NSIsEmptyRect([self visibleRect]))
return;
// Remove current trakcing areas:
QCocoaAutoReleasePool pool;
if (NSArray *trackingArray = [self trackingAreas]) {
NSUInteger size = [trackingArray count];
for (NSUInteger i = 0; i < size; ++i) {
NSTrackingArea *t = [trackingArray objectAtIndex:i];
[self removeTrackingArea:t];
}
}
// NSTrackingInVisibleRect keeps care of updating once the tracking is set up, so bail out early
if (m_trackingArea && [[self trackingAreas] containsObject:m_trackingArea])
return;
// Ideally, we shouldn't have NSTrackingMouseMoved events included below, it should
// only be turned on if mouseTracking, hover is on or a tool tip is set.
@ -830,12 +857,12 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
// is a performance hit). So it goes.
NSUInteger trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp
| NSTrackingInVisibleRect | NSTrackingMouseMoved | NSTrackingCursorUpdate;
NSTrackingArea *ta = [[[NSTrackingArea alloc] initWithRect:[self frame]
options:trackingOptions
owner:m_mouseMoveHelper
userInfo:nil]
autorelease];
[self addTrackingArea:ta];
[m_trackingArea release];
m_trackingArea = [[NSTrackingArea alloc] initWithRect:[self frame]
options:trackingOptions
owner:m_mouseMoveHelper
userInfo:nil];
[self addTrackingArea:m_trackingArea];
}
-(void)cursorUpdateImpl:(NSEvent *)theEvent
@ -925,6 +952,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
if (m_window->flags() & Qt::WindowTransparentForInput)
return [super rightMouseDown:theEvent];
m_buttons |= Qt::RightButton;
m_sendUpAsRightButton = true;
[self handleMouseEvent:theEvent];
}
@ -942,6 +970,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
if (m_window->flags() & Qt::WindowTransparentForInput)
return [super rightMouseUp:theEvent];
m_buttons &= ~Qt::RightButton;
m_sendUpAsRightButton = false;
[self handleMouseEvent:theEvent];
}
@ -1265,12 +1294,10 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
{
if (m_window->flags() & Qt::WindowTransparentForInput)
return [super scrollWheel:theEvent];
const EventRef carbonEvent = (EventRef)[theEvent eventRef];
const UInt32 carbonEventKind = carbonEvent ? ::GetEventKind(carbonEvent) : 0;
const bool scrollEvent = carbonEventKind == kEventMouseScroll;
QPoint angleDelta;
if (scrollEvent) {
Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
if ([theEvent hasPreciseScrollingDeltas]) {
// The mouse device contains pixel scroll wheel support (Mighty Mouse, Trackpad).
// Since deviceDelta is delivered as pixels rather than degrees, we need to
// convert from pixels to degrees in a sensible manner.
@ -1279,8 +1306,8 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
const int pixelsToDegrees = 2; // 8 * 1/4
angleDelta.setX([theEvent scrollingDeltaX] * pixelsToDegrees);
angleDelta.setY([theEvent scrollingDeltaY] * pixelsToDegrees);
source = Qt::MouseEventSynthesizedBySystem;
} else {
// carbonEventKind == kEventMouseWheelMoved
// Remove acceleration, and use either -120 or 120 as delta:
angleDelta.setX(qBound(-120, int([theEvent deltaX] * 10000), 120));
angleDelta.setY(qBound(-120, int([theEvent deltaY] * 10000), 120));
@ -1321,19 +1348,24 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
// On 10.8 and above, MayBegin is likely to happen. We treat it the same as an actual begin.
if (phase == NSEventPhaseMayBegin || phase == NSEventPhaseBegan)
ph = Qt::ScrollBegin;
} else
#endif
if (phase == NSEventPhaseBegan) {
// On 10.7, MayBegin will not happen, so Began is the actual beginning.
if (phase == NSEventPhaseMayBegin || phase == NSEventPhaseBegan) {
m_scrolling = true;
ph = Qt::ScrollBegin;
}
if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled) {
}
#endif
if (phase == NSEventPhaseBegan) {
// If MayBegin did not happen, Began is the actual beginning.
if (!m_scrolling)
ph = Qt::ScrollBegin;
m_scrolling = true;
} else if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled ||
momentumPhase == NSEventPhaseEnded || momentumPhase == NSEventPhaseCancelled) {
ph = Qt::ScrollEnd;
m_scrolling = false;
}
QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers, ph);
QWindowSystemInterface::handleWheelEvent(m_window, qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, currentWheelModifiers, ph, source);
}
#endif //QT_NO_WHEELEVENT
@ -1403,6 +1435,10 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QObject *fo = QGuiApplication::focusObject();
if (m_sendKeyEvent && fo) {
// if escape is pressed we don't want interpretKeyEvents to close a dialog. This will be done via QWindowSystemInterface
if (keyCode == Qt::Key_Escape)
m_platformWindow->m_ignoreWindowShouldClose = true;
QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImHints);
if (QCoreApplication::sendEvent(fo, &queryEvent)) {
bool imEnabled = queryEvent.value(Qt::ImEnabled).toBool();
@ -1412,6 +1448,8 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
[self interpretKeyEvents:[NSArray arrayWithObject:nsevent]];
}
}
m_platformWindow->m_ignoreWindowShouldClose = false;;
}
if (m_resendKeyEvent)
m_sendKeyEvent = true;
@ -1419,7 +1457,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
if (m_sendKeyEvent && m_composingText.isEmpty())
QWindowSystemInterface::handleExtendedKeyEvent(focusWindow, timestamp, QEvent::Type(eventType), keyCode, modifiers,
nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat]);
nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat], 1, false);
m_sendKeyEvent = false;
m_resendKeyEvent = false;
@ -1451,7 +1489,8 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
&& qtKey == Qt::Key_Period) {
[self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)];
return YES;
} else if ([nsevent modifierFlags] & NSControlKeyMask && (qtKey == Qt::Key_Tab || qtKey == Qt::Key_Backtab)) {
} else if ([nsevent modifierFlags] & NSControlKeyMask
&& (qtKey == Qt::Key_Tab || qtKey == Qt::Key_Backtab)) {
[self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)];
return YES;
}
@ -1809,6 +1848,50 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
return NO;
}
- (void)updateCursorFromDragResponse:(QPlatformDragQtResponse)response drag:(QCocoaDrag *)drag
{
const QPixmap pixmapCursor = drag->currentDrag()->dragCursor(response.acceptedAction());
NSCursor *nativeCursor = nil;
if (pixmapCursor.isNull()) {
switch (response.acceptedAction()) {
case Qt::CopyAction:
nativeCursor = [NSCursor dragCopyCursor];
break;
case Qt::LinkAction:
nativeCursor = [NSCursor dragLinkCursor];
break;
case Qt::IgnoreAction:
// Uncomment the next lines if forbiden cursor wanted on non droppable targets.
/*nativeCursor = [NSCursor operationNotAllowedCursor];
break;*/
case Qt::MoveAction:
default:
nativeCursor = [NSCursor arrowCursor];
break;
}
}
else {
NSImage *nsimage = qt_mac_create_nsimage(pixmapCursor);
nativeCursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSZeroPoint];
[nsimage release];
}
// change the cursor
[nativeCursor set];
// Make sure the cursor is updated correctly if the mouse does not move and window is under cursor
// by creating a fake move event
const QPoint mousePos(QCursor::pos());
CGEventRef moveEvent(CGEventCreateMouseEvent(
NULL, kCGEventMouseMoved,
CGPointMake(mousePos.x(), mousePos.y()),
kCGMouseButtonLeft // ignored
));
CGEventPost(kCGHIDEventTap, moveEvent);
CFRelease(moveEvent);
}
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
return [self handleDrag : sender];
@ -1827,14 +1910,18 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
QWindow *target = findEventTargetWindow(m_window);
if (!target)
return NSDragOperationNone;
// update these so selecting move/copy/link works
QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers: [[NSApp currentEvent] modifierFlags]];
QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect());
if ([sender draggingSource] != nil) {
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
if (nativeDrag->currentDrag()) {
// The drag was started from within the application
response = QWindowSystemInterface::handleDrag(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
[self updateCursorFromDragResponse:response drag:nativeDrag];
} else {
QCocoaDropData mimeData([sender draggingPasteboard]);
response = QWindowSystemInterface::handleDrag(target, &mimeData, mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
@ -1846,6 +1933,8 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
- (void)draggingExited:(id <NSDraggingInfo>)sender
{
QWindow *target = findEventTargetWindow(m_window);
if (!target)
return;
NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
@ -1858,14 +1947,17 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
QWindow *target = findEventTargetWindow(m_window);
if (!target)
return false;
NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
QPlatformDropQtResponse response(false, Qt::IgnoreAction);
if ([sender draggingSource] != nil) {
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
if (nativeDrag->currentDrag()) {
// The drag was started from within the application
response = QWindowSystemInterface::handleDrop(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
} else {
QCocoaDropData mimeData([sender draggingPasteboard]);
@ -1883,6 +1975,8 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
Q_UNUSED(img);
Q_UNUSED(operation);
QWindow *target = findEventTargetWindow(m_window);
if (!target)
return;
// keep our state, and QGuiApplication state (buttons member) in-sync,
// or future mouse events will be processed incorrectly
@ -1892,7 +1986,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
QPoint qtWindowPoint(windowPoint.x, windowPoint.y);
NSWindow *window = [self window];
NSPoint screenPoint = [window convertBaseToScreen :point];
NSPoint screenPoint = [window convertRectToScreen:NSMakeRect(point.x, point.y, 0, 0)].origin;
QPoint qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y));
QWindowSystemInterface::handleMouseEvent(target, mapWindowCoordinates(m_window, target, qtWindowPoint), qtScreenPoint, m_buttons);

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -58,16 +58,14 @@
#include <QtCore/QExplicitlySharedDataPointer>
#include <QtCore/QMutex>
#include <QtCore/QMutexLocker>
#include <QtCore/QUuid>
#include <QtCore/QRegularExpression>
#include <QtCore/private/qsystemlibrary_p.h>
#include <algorithm>
#include "qtwindows_additional.h"
#define STRICT_TYPED_ITEMIDS
#include <shlobj.h>
#include <shlwapi.h>
// #define USE_NATIVE_COLOR_DIALOG /* Testing purposes only */
#ifdef Q_CC_MINGW /* Add missing declarations for MinGW */
@ -381,7 +379,12 @@ static inline QString guidToString(const GUID &g)
}
inline QDebug operator<<(QDebug d, const GUID &g)
{ d.nospace() << guidToString(g); return d; }
{
QDebugStateSaver saver(d);
d.nospace();
d << guidToString(g);
return d;
}
// Return an allocated wchar_t array from a QString, reserve more memory if desired.
static wchar_t *qStringToWCharArray(const QString &s, size_t reserveSize = 0)
@ -890,8 +893,8 @@ public:
virtual void setWindowTitle(const QString &title);
inline void setMode(QFileDialogOptions::FileMode mode, QFileDialogOptions::AcceptMode acceptMode, QFileDialogOptions::FileDialogOptions options);
inline void setDirectory(const QString &directory);
inline void updateDirectory() { setDirectory(m_data.directory().toLocalFile()); }
inline void setDirectory(const QUrl &directory);
inline void updateDirectory() { setDirectory(m_data.directory()); }
inline QString directory() const;
virtual void doExec(HWND owner = 0);
virtual void setNameFilters(const QStringList &f);
@ -934,7 +937,7 @@ protected:
static QList<QUrl> libraryItemFolders(IShellItem *item);
static QString libraryItemDefaultSaveFolder(IShellItem *item);
static int itemPaths(IShellItemArray *items, QList<QUrl> *fileResult = 0);
static IShellItem *shellItem(const QString &path);
static IShellItem *shellItem(const QUrl &url);
const QWindowsFileDialogSharedData &data() const { return m_data; }
QWindowsFileDialogSharedData &data() { return m_data; }
@ -994,25 +997,58 @@ void QWindowsNativeFileDialogBase::setWindowTitle(const QString &title)
m_fileDialog->SetTitle(reinterpret_cast<const wchar_t *>(title.utf16()));
}
IShellItem *QWindowsNativeFileDialogBase::shellItem(const QString &path)
IShellItem *QWindowsNativeFileDialogBase::shellItem(const QUrl &url)
{
#ifndef Q_OS_WINCE
if (QWindowsContext::shell32dll.sHCreateItemFromParsingName) {
IShellItem *result = 0;
const QString native = QDir::toNativeSeparators(path);
if (url.isLocalFile()) {
if (!QWindowsContext::shell32dll.sHCreateItemFromParsingName)
return Q_NULLPTR;
IShellItem *result = Q_NULLPTR;
const QString native = QDir::toNativeSeparators(url.toLocalFile());
const HRESULT hr =
QWindowsContext::shell32dll.sHCreateItemFromParsingName(reinterpret_cast<const wchar_t *>(native.utf16()),
NULL, IID_IShellItem,
reinterpret_cast<void **>(&result));
if (SUCCEEDED(hr))
return result;
QWindowsContext::shell32dll.sHCreateItemFromParsingName(reinterpret_cast<const wchar_t *>(native.utf16()),
NULL, IID_IShellItem,
reinterpret_cast<void **>(&result));
if (FAILED(hr)) {
qErrnoWarning("%s: SHCreateItemFromParsingName(%s)) failed", __FUNCTION__, qPrintable(url.toString()));
return Q_NULLPTR;
}
return result;
} else if (url.scheme() == QLatin1String("clsid")) {
if (!QWindowsContext::shell32dll.sHGetKnownFolderIDList || !QWindowsContext::shell32dll.sHCreateItemFromIDList)
return Q_NULLPTR;
// Support for virtual folders via GUID
// (see https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx)
// specified as "clsid:<GUID>" (without '{', '}').
IShellItem *result = Q_NULLPTR;
const QUuid uuid(url.path());
if (uuid.isNull()) {
qWarning() << __FUNCTION__ << ": Invalid CLSID: " << url.path();
return Q_NULLPTR;
}
PIDLIST_ABSOLUTE idList;
HRESULT hr = QWindowsContext::shell32dll.sHGetKnownFolderIDList(uuid, 0, 0, &idList);
if (FAILED(hr)) {
qErrnoWarning("%s: SHGetKnownFolderIDList(%s)) failed", __FUNCTION__, qPrintable(url.toString()));
return Q_NULLPTR;
}
hr = QWindowsContext::shell32dll.sHCreateItemFromIDList(idList, IID_IShellItem, reinterpret_cast<void **>(&result));
CoTaskMemFree(idList);
if (FAILED(hr)) {
qErrnoWarning("%s: SHCreateItemFromIDList(%s)) failed", __FUNCTION__, qPrintable(url.toString()));
return Q_NULLPTR;
}
return result;
} else {
qWarning() << __FUNCTION__ << ": Unhandled scheme: " << url.scheme();
}
#else // !Q_OS_WINCE
Q_UNUSED(url)
#endif
qErrnoWarning("%s: SHCreateItemFromParsingName(%s)) failed", __FUNCTION__, qPrintable(path));
return 0;
}
void QWindowsNativeFileDialogBase::setDirectory(const QString &directory)
void QWindowsNativeFileDialogBase::setDirectory(const QUrl &directory)
{
if (!directory.isEmpty()) {
if (IShellItem *psi = QWindowsNativeFileDialogBase::shellItem(directory)) {
@ -1302,14 +1338,27 @@ void QWindowsNativeFileDialogBase::setLabelText(QFileDialogOptions::DialogLabel
}
}
static inline bool isClsid(const QString &s)
{
// detect "374DE290-123F-4565-9164-39C4925E467B".
static const QRegularExpression pattern(QLatin1String("[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{8}"));
Q_ASSERT(pattern.isValid());
return pattern.match(s).hasMatch();
}
void QWindowsNativeFileDialogBase::selectFile(const QString &fileName) const
{
QString file = QDir::toNativeSeparators(fileName);
int lastBackSlash = file.lastIndexOf(QChar::fromLatin1('\\'));
if (lastBackSlash >= 0) {
file = file.mid(lastBackSlash + 1);
// Hack to prevent CLSIDs from being set as file name due to
// QFileDialogPrivate::initialSelection() being QString-based.
if (!isClsid(fileName))
{
QString file = QDir::toNativeSeparators(fileName);
int lastBackSlash = file.lastIndexOf(QChar::fromLatin1('\\'));
if (lastBackSlash >= 0) {
file = file.mid(lastBackSlash + 1);
}
m_fileDialog->SetFileName((wchar_t*)file.utf16());;
}
m_fileDialog->SetFileName((wchar_t*)file.utf16());;
}
// Return the index of the selected filter, accounting for QFileDialog
@ -1654,14 +1703,14 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
QWindowsNativeFileDialogBase *result = QWindowsNativeFileDialogBase::create(options()->acceptMode(), m_data);
if (!result)
return 0;
QObject::connect(result, SIGNAL(accepted()), this, SIGNAL(accept()));
QObject::connect(result, SIGNAL(rejected()), this, SIGNAL(reject()));
QObject::connect(result, SIGNAL(directoryEntered(QUrl)),
this, SIGNAL(directoryEntered(QUrl)));
QObject::connect(result, SIGNAL(currentChanged(QUrl)),
this, SIGNAL(currentChanged(QUrl)));
QObject::connect(result, SIGNAL(filterSelected(QString)),
this, SIGNAL(filterSelected(QString)));
QObject::connect(result, &QWindowsNativeDialogBase::accepted, this, &QPlatformDialogHelper::accept);
QObject::connect(result, &QWindowsNativeDialogBase::rejected, this, &QPlatformDialogHelper::reject);
QObject::connect(result, &QWindowsNativeFileDialogBase::directoryEntered,
this, &QPlatformFileDialogHelper::directoryEntered);
QObject::connect(result, &QWindowsNativeFileDialogBase::currentChanged,
this, &QPlatformFileDialogHelper::currentChanged);
QObject::connect(result, &QWindowsNativeFileDialogBase::filterSelected,
this, &QPlatformFileDialogHelper::filterSelected);
// Apply settings.
const QSharedPointer<QFileDialogOptions> &opts = options();
@ -2041,8 +2090,8 @@ QWindowsNativeDialogBase *QWindowsXpFileDialogHelper::createNativeDialog()
{
m_data.fromOptions(options());
if (QWindowsXpNativeFileDialog *result = QWindowsXpNativeFileDialog::create(options(), m_data)) {
QObject::connect(result, SIGNAL(accepted()), this, SIGNAL(accept()));
QObject::connect(result, SIGNAL(rejected()), this, SIGNAL(reject()));
QObject::connect(result, &QWindowsNativeDialogBase::accepted, this, &QPlatformDialogHelper::accept);
QObject::connect(result, &QWindowsNativeDialogBase::rejected, this, &QPlatformDialogHelper::reject);
return result;
}
return 0;
@ -2202,8 +2251,8 @@ QWindowsNativeDialogBase *QWindowsColorDialogHelper::createNativeDialog()
{
QWindowsNativeColorDialog *nativeDialog = new QWindowsNativeColorDialog(m_currentColor);
nativeDialog->setWindowTitle(options()->windowTitle());
connect(nativeDialog, SIGNAL(accepted()), this, SIGNAL(accept()));
connect(nativeDialog, SIGNAL(rejected()), this, SIGNAL(reject()));
connect(nativeDialog, &QWindowsNativeDialogBase::accepted, this, &QPlatformDialogHelper::accept);
connect(nativeDialog, &QWindowsNativeDialogBase::rejected, this, &QPlatformDialogHelper::reject);
return nativeDialog;
}
#endif // USE_NATIVE_COLOR_DIALOG

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -37,6 +37,8 @@
#include "qwindowsdrag.h"
#include "qwindowsscreen.h"
#include "qwindowsscaling.h"
#include "qwindowsintegration.h"
#include "qwindowsopenglcontext.h"
#ifdef QT_NO_CURSOR
# include "qwindowscursor.h"
#endif
@ -104,31 +106,16 @@ static QByteArray debugWinExStyle(DWORD exStyle)
return rc;
}
static QByteArray debugWindowStates(Qt::WindowStates s)
{
QByteArray rc = "0x";
rc += QByteArray::number(int(s), 16);
if (s & Qt::WindowMinimized)
rc += " WindowMinimized";
if (s & Qt::WindowMaximized)
rc += " WindowMaximized";
if (s & Qt::WindowFullScreen)
rc += " WindowFullScreen";
if (s & Qt::WindowActive)
rc += " WindowActive";
return rc;
}
#ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_GETMINMAXINFO
QDebug operator<<(QDebug d, const MINMAXINFO &i)
{
d.nospace() << "MINMAXINFO maxSize=" << i.ptMaxSize.x << ','
<< i.ptMaxSize.y << " maxpos=" << i.ptMaxPosition.x
<< ',' << i.ptMaxPosition.y << " mintrack="
<< i.ptMinTrackSize.x << ',' << i.ptMinTrackSize.y
<< " maxtrack=" << i.ptMaxTrackSize.x << ','
<< i.ptMaxTrackSize.y;
QDebugStateSaver saver(d);
d.nospace();
d << "MINMAXINFO maxSize=" << i.ptMaxSize.x << ','
<< i.ptMaxSize.y << " maxpos=" << i.ptMaxPosition.x
<< ',' << i.ptMaxPosition.y << " mintrack="
<< i.ptMinTrackSize.x << ',' << i.ptMinTrackSize.y
<< " maxtrack=" << i.ptMaxTrackSize.x << ',' << i.ptMaxTrackSize.y;
return d;
}
#endif // !Q_OS_WINCE
@ -153,22 +140,43 @@ static inline RECT RECTfromQRect(const QRect &rect)
QDebug operator<<(QDebug d, const RECT &r)
{
d.nospace() << "RECT: left/top=" << r.left << ',' << r.top
<< " right/bottom=" << r.right << ',' << r.bottom;
QDebugStateSaver saver(d);
d.nospace();
d << "RECT: left/top=" << r.left << ',' << r.top
<< " right/bottom=" << r.right << ',' << r.bottom;
return d;
}
#ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_NCCALCSIZE
QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p)
{
qDebug().nospace() << "NCCALCSIZE_PARAMS "
<< qrectFromRECT(p.rgrc[0])
<< ' ' << qrectFromRECT(p.rgrc[1]) << ' '
<< qrectFromRECT(p.rgrc[2]);
QDebugStateSaver saver(d);
d.nospace();
d << "NCCALCSIZE_PARAMS " << qrectFromRECT(p.rgrc[0])
<< ' ' << qrectFromRECT(p.rgrc[1]) << ' ' << qrectFromRECT(p.rgrc[2]);
return d;
}
#endif // !Q_OS_WINCE
// QTBUG-43872, for windows that do not have WS_EX_TOOLWINDOW set, WINDOWPLACEMENT
// is in workspace/available area coordinates.
static QPoint windowPlacementOffset(HWND hwnd, const QPoint &point)
{
#ifndef Q_OS_WINCE
if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)
return QPoint(0, 0);
const QWindowsScreenManager &screenManager = QWindowsContext::instance()->screenManager();
const QWindowsScreen *screen = screenManager.screens().size() == 1
? screenManager.screens().first() : screenManager.screenAtDp(point);
if (screen)
return screen->availableGeometryDp().topLeft() - screen->geometryDp().topLeft();
#else
Q_UNUSED(hwnd)
Q_UNUSED(point)
#endif
return QPoint(0, 0);
}
// Return the frame geometry relative to the parent
// if there is one.
static inline QRect frameGeometry(HWND hwnd, bool topLevel)
@ -179,8 +187,10 @@ static inline QRect frameGeometry(HWND hwnd, bool topLevel)
WINDOWPLACEMENT windowPlacement;
windowPlacement.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hwnd, &windowPlacement);
if (windowPlacement.showCmd == SW_SHOWMINIMIZED)
return qrectFromRECT(windowPlacement.rcNormalPosition);
if (windowPlacement.showCmd == SW_SHOWMINIMIZED) {
const QRect result = qrectFromRECT(windowPlacement.rcNormalPosition);
return result.translated(windowPlacementOffset(hwnd, result.topLeft()));
}
}
#endif // !Q_OS_WINCE
GetWindowRect(hwnd, &rect); // Screen coordinates.
@ -205,6 +215,18 @@ static inline QSize clientSize(HWND hwnd)
return qSizeOfRect(rect);
}
static inline bool windowIsOpenGL(const QWindow *w)
{
switch (w->surfaceType()) {
case QSurface::OpenGLSurface:
return true;
case QSurface::RasterGLSurface:
return qt_window_private(const_cast<QWindow *>(w))->compositing;
default:
return false;
}
}
static bool applyBlurBehindWindow(HWND hwnd)
{
#ifdef Q_OS_WINCE
@ -328,6 +350,17 @@ static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, bo
#endif // !Q_OS_WINCE
}
static inline void updateGLWindowSettings(const QWindow *w, HWND hwnd, Qt::WindowFlags flags, qreal opacity)
{
const bool isGL = windowIsOpenGL(w);
const bool hasAlpha = w->format().hasAlpha();
if (isGL && hasAlpha)
applyBlurBehindWindow(hwnd);
setWindowOpacity(hwnd, flags, hasAlpha, isGL, opacity);
}
/*!
\class WindowCreationData
\brief Window creation code.
@ -369,14 +402,13 @@ struct WindowCreationData
void fromWindow(const QWindow *w, const Qt::WindowFlags flags, unsigned creationFlags = 0);
inline WindowData create(const QWindow *w, const WindowData &data, QString title) const;
inline void applyWindowFlags(HWND hwnd) const;
void initialize(HWND h, bool frameChange, qreal opacityLevel) const;
void initialize(const QWindow *w, HWND h, bool frameChange, qreal opacityLevel) const;
Qt::WindowFlags flags;
HWND parentHandle;
Qt::WindowType type;
unsigned style;
unsigned exStyle;
bool isGL;
bool topLevel;
bool popup;
bool dialog;
@ -388,19 +420,26 @@ struct WindowCreationData
QDebug operator<<(QDebug debug, const WindowCreationData &d)
{
debug.nospace() << QWindowsWindow::debugWindowFlags(d.flags)
<< " GL=" << d.isGL << " topLevel=" << d.topLevel << " popup="
<< d.popup << " dialog=" << d.dialog << " desktop=" << d.desktop
<< " embedded=" << d.embedded
<< " tool=" << d.tool << " style=" << debugWinStyle(d.style)
<< " exStyle=" << debugWinExStyle(d.exStyle)
<< " parent=" << d.parentHandle;
QDebugStateSaver saver(debug);
debug.nospace();
debug.noquote();
debug << "WindowCreationData: " << d.flags
<< "\n topLevel=" << d.topLevel;
if (d.parentHandle)
debug << " parent=" << d.parentHandle;
debug << " popup=" << d.popup << " dialog=" << d.dialog << " desktop=" << d.desktop
<< " embedded=" << d.embedded << " tool=" << d.tool
<< "\n style=" << debugWinStyle(d.style);
if (d.exStyle)
debug << "\n exStyle=" << debugWinExStyle(d.exStyle);
return debug;
}
// Fix top level window flags in case only the type flags are passed.
static inline void fixTopLevelWindowFlags(Qt::WindowFlags &flags)
{
// Not supported on Windows, also do correction when it is set.
flags &= ~Qt::WindowFullscreenButtonHint;
switch (flags) {
case Qt::Window:
flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint
@ -420,8 +459,6 @@ static inline void fixTopLevelWindowFlags(Qt::WindowFlags &flags)
void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flagsIn,
unsigned creationFlags)
{
isGL = w->surfaceType() == QWindow::OpenGLSurface;
hasAlpha = w->format().hasAlpha();
flags = flagsIn;
// Sometimes QWindow doesn't have a QWindow parent but does have a native parent window,
@ -494,7 +531,7 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag
// ### Commented out for now as it causes some problems, but
// this should be correct anyway, so dig some more into this
#ifdef Q_FLATTEN_EXPOSE
if (isGL)
if (windowIsOpenGL(w)) // a bit incorrect since the is-opengl status may change from false to true at any time later on
style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; // see SetPixelFormat
#else
style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
@ -513,7 +550,7 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag
}
if (flags & Qt::WindowSystemMenuHint)
style |= WS_SYSMENU;
else if (dialog) {
else if (dialog && (flags & Qt::WindowCloseButtonHint) && !(flags & Qt::FramelessWindowHint)) {
style |= WS_SYSMENU | WS_BORDER; // QTBUG-2027, dialogs without system menu.
exStyle |= WS_EX_DLGMODALFRAME;
}
@ -559,16 +596,17 @@ QWindowsWindowData
Q_ASSERT(result.hwnd);
const LONG_PTR style = GetWindowLongPtr(result.hwnd, GWL_STYLE);
const LONG_PTR exStyle = GetWindowLongPtr(result.hwnd, GWL_EXSTYLE);
result.geometry = frameGeometry(result.hwnd, !GetParent(result.hwnd));
result.frame = QWindowsGeometryHint::frame(style, exStyle);
result.embedded = false;
qCDebug(lcQpaWindows) << "Foreign window: " << w << result.hwnd << result.geometry << result.frame;
result.frame = QWindowsGeometryHint::frame(style, exStyle);
result.geometry = frameGeometry(result.hwnd, !GetParent(result.hwnd))
.marginsRemoved(result.frame);
qCDebug(lcQpaWindows) << "Foreign window: " << w << result.hwnd << result.geometry;
return result;
}
const HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0);
const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w, isGL);
const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w);
const QRect geometryDip = QWindowsScaling::mapFromNative(data.geometry);
QRect fixedGeometryDip = QPlatformWindow::initialGeometry(w, geometryDip, defaultWindowWidth, defaultWindowHeight);
@ -586,8 +624,8 @@ QWindowsWindowData
QWindowsContext::instance()->setWindowCreationContext(context);
qCDebug(lcQpaWindows).nospace()
<< "CreateWindowEx: " << w << *this << " class=" <<windowClassName << " title=" << title
<< "\nrequested: " << rect << ": "
<< "CreateWindowEx: " << w << " class=" << windowClassName << " title=" << title
<< '\n' << *this << "\nrequested: " << rect << ": "
<< context->frameWidth << 'x' << context->frameHeight
<< '+' << context->frameX << '+' << context->frameY
<< " custom margins: " << context->customMargins;
@ -597,9 +635,13 @@ QWindowsWindowData
context->frameX, context->frameY,
context->frameWidth, context->frameHeight,
parentHandle, NULL, appinst, NULL);
#ifdef Q_OS_WINCE
if (DisableGestures(result.hwnd, TGF_GID_ALL, TGF_SCOPE_WINDOW))
EnableGestures(result.hwnd, TGF_GID_DIRECTMANIPULATION, TGF_SCOPE_WINDOW);
#endif
qCDebug(lcQpaWindows).nospace()
<< "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: "
<< context->obtainedGeometry << context->margins;
<< context->obtainedGeometry << ' ' << context->margins;
if (!result.hwnd) {
qErrnoWarning("%s: CreateWindowEx failed", __FUNCTION__);
@ -611,9 +653,6 @@ QWindowsWindowData
result.embedded = embedded;
result.customMargins = context->customMargins;
if (isGL && hasAlpha)
applyBlurBehindWindow(result.hwnd);
return result;
}
@ -636,7 +675,7 @@ void WindowCreationData::applyWindowFlags(HWND hwnd) const
<< debugWinExStyle(newExStyle);
}
void WindowCreationData::initialize(HWND hwnd, bool frameChange, qreal opacityLevel) const
void WindowCreationData::initialize(const QWindow *w, HWND hwnd, bool frameChange, qreal opacityLevel) const
{
if (desktop || !hwnd)
return;
@ -661,8 +700,7 @@ void WindowCreationData::initialize(HWND hwnd, bool frameChange, qreal opacityLe
else
EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
}
setWindowOpacity(hwnd, flags, hasAlpha, isGL, opacityLevel);
updateGLWindowSettings(w, hwnd, flags, opacityLevel);
} else { // child.
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, swpFlags);
}
@ -704,9 +742,9 @@ QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle)
qErrnoWarning("%s: AdjustWindowRectEx failed", __FUNCTION__);
const QMargins result(qAbs(rect.left), qAbs(rect.top),
qAbs(rect.right), qAbs(rect.bottom));
qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << " style= 0x"
<< QString::number(style, 16) << " exStyle=0x" << QString::number(exStyle, 16) << ' ' << rect << ' ' << result;
qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << " style="
<< showbase << hex << style << " exStyle=" << exStyle << dec << noshowbase
<< ' ' << rect << ' ' << result;
return result;
}
@ -801,7 +839,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
const QRect &geometry,
const QMargins &cm,
DWORD style_, DWORD exStyle_) :
geometryHint(w, cm), style(style_), exStyle(exStyle_),
geometryHint(w, cm), window(w), style(style_), exStyle(exStyle_),
requestedGeometry(geometry), obtainedGeometry(geometry),
margins(QWindowsGeometryHint::frame(style, exStyle)), customMargins(cm),
frameX(CW_USEDEFAULT), frameY(CW_USEDEFAULT),
@ -825,12 +863,12 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
}
qCDebug(lcQpaWindows).nospace()
<< __FUNCTION__ << ' ' << w << geometry
<< " pos incl. frame" << QWindowsGeometryHint::positionIncludesFrame(w)
<< " frame: " << frameWidth << 'x' << frameHeight << '+'
<< __FUNCTION__ << ' ' << w << ' ' << geometry
<< " pos incl. frame=" << QWindowsGeometryHint::positionIncludesFrame(w)
<< " frame=" << frameWidth << 'x' << frameHeight << '+'
<< frameX << '+' << frameY
<< " min" << geometryHint.minimumSize << " max" << geometryHint.maximumSize
<< " custom margins " << customMargins;
<< " min=" << geometryHint.minimumSize << " max=" << geometryHint.maximumSize
<< " custom margins=" << customMargins;
}
/*!
@ -886,17 +924,9 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
setFlag(OpenGL_ES2);
}
#endif // QT_NO_OPENGL
updateDropSite();
updateDropSite(window()->isTopLevel());
#ifndef Q_OS_WINCE
if (QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch) {
if (QWindowsContext::user32dll.registerTouchWindow(m_data.hwnd, 0)) {
setFlag(TouchRegistered);
} else {
qErrnoWarning("RegisterTouchWindow() failed for window '%s'.", qPrintable(aWindow->objectName()));
}
}
#endif // !Q_OS_WINCE
registerTouchWindow();
setWindowState(aWindow->windowState());
const qreal opacity = qt_window_private(aWindow)->opacity;
if (!qFuzzyCompare(opacity, qreal(1.0)))
@ -952,7 +982,8 @@ void QWindowsWindow::destroyWindow()
setDropSiteEnabled(false);
#ifndef QT_NO_OPENGL
if (m_surface) {
m_data.staticOpenGLContext->destroyWindowSurface(m_surface);
if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
staticOpenGLContext->destroyWindowSurface(m_surface);
m_surface = 0;
}
#endif
@ -971,10 +1002,10 @@ void QWindowsWindow::destroyWindow()
}
}
void QWindowsWindow::updateDropSite()
void QWindowsWindow::updateDropSite(bool topLevel)
{
bool enabled = false;
if (window()->isTopLevel()) {
if (topLevel) {
switch (window()->type()) {
case Qt::Window:
case Qt::Dialog:
@ -1043,13 +1074,14 @@ QWindowsWindowData
creationData.fromWindow(w, parameters.flags);
QWindowsWindowData result = creationData.create(w, parameters, title);
// Force WM_NCCALCSIZE (with wParam=1) via SWP_FRAMECHANGED for custom margin.
creationData.initialize(result.hwnd, !parameters.customMargins.isNull(), 1);
creationData.initialize(w, result.hwnd, !parameters.customMargins.isNull(), 1);
return result;
}
void QWindowsWindow::setVisible(bool visible)
{
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << m_data.hwnd << visible;
const QWindow *win = window();
qCDebug(lcQpaWindows) << __FUNCTION__ << this << win << m_data.hwnd << visible;
if (m_data.hwnd) {
if (visible) {
show_sys();
@ -1057,11 +1089,13 @@ void QWindowsWindow::setVisible(bool visible)
// When the window is layered, we won't get WM_PAINT, and "we" are in control
// over the rendering of the window
// There is nobody waiting for this, so we don't need to flush afterwards.
if (isLayered()) {
QWindow *w = window();
fireExpose(QRect(0, 0, w->width(), w->height()));
}
if (isLayered())
fireExpose(QRect(0, 0, win->width(), win->height()));
// QTBUG-44928, QTBUG-7386: This is to resolve the problem where popups are
// opened from the system tray and not being implicitly activated
if (win->type() == Qt::Popup && !win->parent() && !QGuiApplication::focusWindow())
SetForegroundWindow(m_data.hwnd);
} else {
if (hasMouseCapture())
setMouseGrabEnabled(false);
@ -1270,7 +1304,7 @@ void QWindowsWindow::setParent_sys(const QPlatformWindow *parent)
if (wasTopLevel != isTopLevel) {
setDropSiteEnabled(false);
setWindowFlags_sys(window()->flags(), unsigned(isTopLevel ? WindowCreationData::ForceTopLevel : WindowCreationData::ForceChild));
updateDropSite();
updateDropSite(isTopLevel);
}
}
}
@ -1292,8 +1326,10 @@ static QRect normalFrameGeometry(HWND hwnd)
#ifndef Q_OS_WINCE
WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWPLACEMENT);
if (GetWindowPlacement(hwnd, &wp))
return qrectFromRECT(wp.rcNormalPosition);
if (GetWindowPlacement(hwnd, &wp)) {
const QRect result = qrectFromRECT(wp.rcNormalPosition);
return result.translated(windowPlacementOffset(hwnd, result.topLeft()));
}
#else
Q_UNUSED(hwnd)
#endif
@ -1318,21 +1354,8 @@ void QWindowsWindow::setGeometryDp(const QRect &rectIn)
const QMargins margins = frameMarginsDp();
rect.moveTopLeft(rect.topLeft() + QPoint(margins.left(), margins.top()));
}
const QSize oldSize = m_data.geometry.size();
m_data.geometry = rect;
const QSize newSize = rect.size();
// Check on hint.
if (newSize != oldSize) {
const QWindowsGeometryHint hint(window(), m_data.customMargins);
if (!hint.validSize(newSize)) {
qWarning("%s: Attempt to set a size (%dx%d) violating the constraints"
"(%dx%d - %dx%d) on window %s/'%s'.", __FUNCTION__,
newSize.width(), newSize.height(),
hint.minimumSize.width(), hint.minimumSize.height(),
hint.maximumSize.width(), hint.maximumSize.height(),
window()->metaObject()->className(), qPrintable(window()->objectName()));
}
}
if (m_windowState == Qt::WindowMinimized)
m_data.geometry = rect; // Otherwise set by handleGeometryChange() triggered by event.
if (m_data.hwnd) {
// A ResizeEvent with resulting geometry will be sent. If we cannot
// achieve that size (for example, window title minimal constraint),
@ -1403,11 +1426,11 @@ void QWindowsWindow::handleGeometryChange()
// QTBUG-32121: OpenGL/normal windows (with exception of ANGLE) do not receive
// expose events when shrinking, synthesize.
if (!testFlag(OpenGL_ES2) && isExposed()
&& !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) {
&& !(m_data.geometry.width() >= previousGeometry.width() || m_data.geometry.height() >= previousGeometry.height())) {
fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true);
}
if (previousGeometry.topLeft() != m_data.geometry.topLeft()) {
QPlatformScreen *newScreen = screenForGeometry(m_data.geometry);
QPlatformScreen *newScreen = screenForGeometry(geometryDip);
if (newScreen != screen())
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
}
@ -1422,10 +1445,10 @@ void QWindowsWindow::setGeometry_sys(const QRect &rect) const
const QMargins margins = frameMarginsDp();
const QRect frameGeometry = rect + margins;
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window()
<< " \n from " << geometry_sys() << " frame: "
<< margins << " to " <<rect
<< " new frame: " << frameGeometry;
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << window()
<< "\n from " << geometry_sys() << " frame: "
<< margins << " to " <<rect
<< " new frame: " << frameGeometry;
bool result = false;
#ifndef Q_OS_WINCE
@ -1436,7 +1459,8 @@ void QWindowsWindow::setGeometry_sys(const QRect &rect) const
// window, set the normal position of the window.
if ((windowPlacement.showCmd == SW_MAXIMIZE && !IsWindowVisible(m_data.hwnd))
|| windowPlacement.showCmd == SW_SHOWMINIMIZED) {
windowPlacement.rcNormalPosition = RECTfromQRect(frameGeometry);
windowPlacement.rcNormalPosition =
RECTfromQRect(frameGeometry.translated(-windowPlacementOffset(m_data.hwnd, frameGeometry.topLeft())));
windowPlacement.showCmd = windowPlacement.showCmd == SW_SHOWMINIMIZED ? SW_SHOWMINIMIZED : SW_HIDE;
result = SetWindowPlacement(m_data.hwnd, &windowPlacement);
} else
@ -1445,8 +1469,8 @@ void QWindowsWindow::setGeometry_sys(const QRect &rect) const
result = MoveWindow(m_data.hwnd, frameGeometry.x(), frameGeometry.y(),
frameGeometry.width(), frameGeometry.height(), true);
}
qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << this << window()
<< " \n resulting " << result << geometry_sys();
qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << window()
<< "\n resulting " << result << geometry_sys();
}
QRect QWindowsWindow::frameGeometry_sys() const
@ -1528,14 +1552,13 @@ void QWindowsWindow::setWindowTitle(const QString &title)
void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
{
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window() << "\n from: "
<< QWindowsWindow::debugWindowFlags(m_data.flags)
<< "\n to: " << QWindowsWindow::debugWindowFlags(flags);
<< m_data.flags << "\n to: " << flags;
const QRect oldGeometry = geometryDp();
if (m_data.flags != flags) {
m_data.flags = flags;
if (m_data.hwnd) {
m_data = setWindowFlags_sys(flags);
updateDropSite();
updateDropSite(window()->isTopLevel());
}
}
// When switching to a frameless window, geometry
@ -1547,8 +1570,7 @@ void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
handleGeometryChange();
qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << "\n returns: "
<< QWindowsWindow::debugWindowFlags(m_data.flags)
<< " geometry " << oldGeometry << "->" << newGeometry;
<< m_data.flags << " geometry " << oldGeometry << "->" << newGeometry;
}
QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt,
@ -1557,7 +1579,7 @@ QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt,
WindowCreationData creationData;
creationData.fromWindow(window(), wt, flags);
creationData.applyWindowFlags(m_data.hwnd);
creationData.initialize(m_data.hwnd, true, m_opacity);
creationData.initialize(window(), m_data.hwnd, true, m_opacity);
QWindowsWindowData result = m_data;
result.flags = creationData.flags;
@ -1569,8 +1591,7 @@ QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt,
void QWindowsWindow::handleWindowStateChange(Qt::WindowState state)
{
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window()
<< "\n from " << debugWindowStates(m_windowState)
<< " to " << debugWindowStates(state);
<< "\n from " << m_windowState << " to " << state;
setFlag(FrameDirty);
m_windowState = state;
QWindowSystemInterface::handleWindowStateChanged(window(), state);
@ -1639,23 +1660,12 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
if (oldState == newState)
return;
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window()
<< " from " << debugWindowStates(oldState) << " to " << debugWindowStates(newState);
<< " from " << oldState << " to " << newState;
const bool visible = isVisible();
setFlag(FrameDirty);
if ((oldState == Qt::WindowMaximized) != (newState == Qt::WindowMaximized)) {
if (visible && !(newState == Qt::WindowMinimized)) {
setFlag(WithinMaximize);
if (newState == Qt::WindowFullScreen)
setFlag(MaximizeToFullScreen);
ShowWindow(m_data.hwnd, (newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
clearFlag(WithinMaximize);
clearFlag(MaximizeToFullScreen);
}
}
if ((oldState == Qt::WindowFullScreen) != (newState == Qt::WindowFullScreen)) {
#ifdef Q_OS_WINCE
HWND handle = FindWindow(L"HHTaskBar", L"");
@ -1735,6 +1745,15 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
m_savedStyle = 0;
m_savedFrameGeometry = QRect();
}
} else if ((oldState == Qt::WindowMaximized) != (newState == Qt::WindowMaximized)) {
if (visible && !(newState == Qt::WindowMinimized)) {
setFlag(WithinMaximize);
if (newState == Qt::WindowFullScreen)
setFlag(MaximizeToFullScreen);
ShowWindow(m_data.hwnd, (newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
clearFlag(WithinMaximize);
clearFlag(MaximizeToFullScreen);
}
}
if ((oldState == Qt::WindowMinimized) != (newState == Qt::WindowMinimized)) {
@ -1742,7 +1761,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
ShowWindow(m_data.hwnd, (newState == Qt::WindowMinimized) ? SW_MINIMIZE :
(newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
}
qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << this << window() << debugWindowStates(newState);
qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << this << window() << newState;
}
void QWindowsWindow::setStyle(unsigned s) const
@ -1781,6 +1800,8 @@ void QWindowsWindow::windowEvent(QEvent *event)
case QEvent::WindowBlocked: // Blocked by another modal window.
setEnabled(false);
setFlag(BlockedByModal);
if (hasMouseCapture())
ReleaseCapture();
break;
case QEvent::WindowUnblocked:
setEnabled(true);
@ -1796,6 +1817,47 @@ void QWindowsWindow::propagateSizeHints()
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
}
bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp)
{
#ifndef Q_OS_WINCE
if (!qWindow->isTopLevel()) // Implement hasHeightForWidth().
return false;
WINDOWPOS *windowPos = reinterpret_cast<WINDOWPOS *>(message->lParam);
if ((windowPos->flags & (SWP_NOCOPYBITS | SWP_NOSIZE)))
return false;
const QRect suggestedFrameGeometryDp(windowPos->x, windowPos->y,
windowPos->cx, windowPos->cy);
const qreal factor = QWindowsScaling::factor();
const QRect suggestedGeometryDp = suggestedFrameGeometryDp - marginsDp;
const QRectF suggestedGeometry = QRectF(QPointF(suggestedGeometryDp.topLeft()) / factor,
QSizeF(suggestedGeometryDp.size()) / factor);
const QRectF correctedGeometryF =
qt_window_private(const_cast<QWindow *>(qWindow))->closestAcceptableGeometry(suggestedGeometry);
if (!correctedGeometryF.isValid())
return false;
const QRect correctedFrameGeometryDp
= QRectF(correctedGeometryF.topLeft() * factor,
correctedGeometryF.size() * factor).toRect()
+ marginsDp;
if (correctedFrameGeometryDp == suggestedFrameGeometryDp)
return false;
windowPos->x = correctedFrameGeometryDp.left();
windowPos->y = correctedFrameGeometryDp.top();
windowPos->cx = correctedFrameGeometryDp.width();
windowPos->cy = correctedFrameGeometryDp.height();
return true;
#else // !Q_OS_WINCE
Q_UNUSED(message)
return false;
#endif
}
bool QWindowsWindow::handleGeometryChanging(MSG *message) const
{
const QMargins marginsDp = window()->isTopLevel() ? frameMarginsDp() : QMargins();
return QWindowsWindow::handleGeometryChangingMessage(message, window(), marginsDp);
}
QMargins QWindowsWindow::frameMarginsDp() const
{
// Frames are invalidated by style changes (window state, flags).
@ -1803,7 +1865,12 @@ QMargins QWindowsWindow::frameMarginsDp() const
// event sequences, introduce a dirty flag mechanism to be able
// to cache results.
if (testFlag(FrameDirty)) {
m_data.frame = QWindowsGeometryHint::frame(style(), exStyle());
// Always skip calculating style-dependent margins for windows claimed to be frameless.
// This allows users to remove the margins by handling WM_NCCALCSIZE with WS_THICKFRAME set
// to ensure Areo snap still works (QTBUG-40578).
m_data.frame = window()->flags() & Qt::FramelessWindowHint
? QMargins(0, 0, 0, 0)
: QWindowsGeometryHint::frame(style(), exStyle());
clearFlag(FrameDirty);
}
return m_data.frame + m_data.customMargins;
@ -2087,8 +2154,8 @@ void QWindowsWindow::setCursor(const QWindowsWindowCursor &c)
#ifndef QT_NO_CURSOR
if (c.handle() != m_cursor.handle()) {
const bool apply = applyNewCursor(window());
qCDebug(lcQpaWindows) <<window() << __FUNCTION__
<< "Shape=" << c.cursor().shape() << " doApply=" << apply;
qCDebug(lcQpaWindows) << window() << __FUNCTION__
<< c.cursor().shape() << " doApply=" << apply;
m_cursor = c;
if (apply)
applyCursor();
@ -2155,62 +2222,6 @@ void QWindowsWindow::setEnabled(bool enabled)
setStyle(newStyle);
}
QByteArray QWindowsWindow::debugWindowFlags(Qt::WindowFlags wf)
{
const int iwf = int(wf);
QByteArray rc = "0x";
rc += QByteArray::number(iwf, 16);
rc += " [";
switch ((iwf & Qt::WindowType_Mask)) {
case Qt::Widget:
rc += " Widget";
break;
case Qt::Window:
rc += " Window";
break;
case Qt::Dialog:
rc += " Dialog";
break;
case Qt::Sheet:
rc += " Sheet";
break;
case Qt::Popup:
rc += " Popup";
break;
case Qt::Tool:
rc += " Tool";
break;
case Qt::ToolTip:
rc += " ToolTip";
break;
case Qt::SplashScreen:
rc += " SplashScreen";
break;
case Qt::Desktop:
rc += " Desktop";
break;
case Qt::SubWindow:
rc += " SubWindow";
break;
}
if (iwf & Qt::MSWindowsFixedSizeDialogHint) rc += " MSWindowsFixedSizeDialogHint";
if (iwf & Qt::MSWindowsOwnDC) rc += " MSWindowsOwnDC";
if (iwf & Qt::FramelessWindowHint) rc += " FramelessWindowHint";
if (iwf & Qt::WindowTitleHint) rc += " WindowTitleHint";
if (iwf & Qt::WindowSystemMenuHint) rc += " WindowSystemMenuHint";
if (iwf & Qt::WindowMinimizeButtonHint) rc += " WindowMinimizeButtonHint";
if (iwf & Qt::WindowMaximizeButtonHint) rc += " WindowMaximizeButtonHint";
if (iwf & Qt::WindowContextHelpButtonHint) rc += " WindowContextHelpButtonHint";
if (iwf & Qt::WindowShadeButtonHint) rc += " WindowShadeButtonHint";
if (iwf & Qt::WindowStaysOnTopHint) rc += " WindowStaysOnTopHint";
if (iwf & Qt::CustomizeWindowHint) rc += " CustomizeWindowHint";
if (iwf & Qt::WindowStaysOnBottomHint) rc += " WindowStaysOnBottomHint";
if (iwf & Qt::WindowCloseButtonHint) rc += " WindowCloseButtonHint";
rc += ']';
return rc;
}
static HICON createHIcon(const QIcon &icon, int xSize, int ySize)
{
if (!icon.isNull()) {
@ -2270,16 +2281,74 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins)
}
}
void *QWindowsWindow::surface(void *nativeConfig)
void *QWindowsWindow::surface(void *nativeConfig, int *err)
{
#ifdef QT_NO_OPENGL
Q_UNUSED(nativeConfig)
return 0;
#else
if (!m_surface)
m_surface = m_data.staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig);
if (!m_surface) {
if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig, err);
}
return m_surface;
#endif
}
void QWindowsWindow::invalidateSurface()
{
#ifndef QT_NO_OPENGL
if (m_surface) {
if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
staticOpenGLContext->destroyWindowSurface(m_surface);
m_surface = 0;
}
#endif // QT_NO_OPENGL
}
void QWindowsWindow::setTouchWindowTouchTypeStatic(QWindow *window, QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes)
{
if (!window->handle())
return;
static_cast<QWindowsWindow *>(window->handle())->registerTouchWindow(touchTypes);
}
void QWindowsWindow::registerTouchWindow(QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes)
{
#ifndef Q_OS_WINCE
if ((QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch)
&& window()->type() != Qt::ForeignWindow) {
ULONG touchFlags = 0;
const bool ret = QWindowsContext::user32dll.isTouchWindow(m_data.hwnd, &touchFlags);
// Return if it is not a touch window or the flags are already set by a hook
// such as HCBT_CREATEWND
if (ret || touchFlags != 0)
return;
if (QWindowsContext::user32dll.registerTouchWindow(m_data.hwnd, (ULONG)touchTypes))
setFlag(TouchRegistered);
else
qErrnoWarning("RegisterTouchWindow() failed for window '%s'.", qPrintable(window()->objectName()));
}
#endif // !Q_OS_WINCE
}
void QWindowsWindow::aboutToMakeCurrent()
{
#ifndef QT_NO_OPENGL
// For RasterGLSurface windows, that become OpenGL windows dynamically, it might be
// time to set up some GL specifics. This is particularly important for layered
// windows (WS_EX_LAYERED due to alpha > 0).
const bool isCompositing = qt_window_private(window())->compositing;
if (isCompositing != testFlag(Compositing)) {
if (isCompositing)
setFlag(Compositing);
else
clearFlag(Compositing);
updateGLWindowSettings(window(), m_data.hwnd, m_data.flags, m_opacity);
}
#endif
}
QT_END_NAMESPACE

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -40,9 +40,9 @@
#endif
#include "qwindowsscaling.h"
#include "qwindowscursor.h"
#include "qwindowsopenglcontext.h"
#include <qpa/qplatformwindow.h>
#include <QtPlatformHeaders/qwindowswindowfunctions.h>
QT_BEGIN_NAMESPACE
@ -84,6 +84,7 @@ struct QWindowCreationContext
#endif
QWindowsGeometryHint geometryHint;
const QWindow *window;
DWORD style;
DWORD exStyle;
QRect requestedGeometry;
@ -106,9 +107,6 @@ struct QWindowsWindowData
QMargins customMargins; // User-defined, additional frame for NCCALCSIZE
HWND hwnd;
bool embedded;
#ifndef QT_NO_OPENGL
QSharedPointer<QWindowsStaticOpenGLContext> staticOpenGLContext;
#endif // QT_NO_OPENGL
static QWindowsWindowData create(const QWindow *w,
const QWindowsWindowData &parameters,
@ -138,7 +136,9 @@ public:
Exposed = 0x10000,
WithinCreate = 0x20000,
WithinMaximize = 0x40000,
MaximizeToFullScreen = 0x80000
MaximizeToFullScreen = 0x80000,
InputMethodDisabled = 0x100000,
Compositing = 0x200000
};
QWindowsWindow(QWindow *window, const QWindowsWindowData &data);
@ -182,6 +182,8 @@ public:
void windowEvent(QEvent *event);
void propagateSizeHints() Q_DECL_OVERRIDE;
static bool handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp);
bool handleGeometryChanging(MSG *message) const;
QMargins frameMarginsDp() const;
QMargins frameMargins() const Q_DECL_OVERRIDE { return frameMarginsDp() / QWindowsScaling::factor(); }
@ -238,8 +240,6 @@ public:
void setCursor(const QWindowsWindowCursor &c);
void applyCursor();
static QByteArray debugWindowFlags(Qt::WindowFlags wf);
inline bool testFlag(unsigned f) const { return (m_flags & f) != 0; }
inline void setFlag(unsigned f) const { m_flags |= f; }
inline void clearFlag(unsigned f) const { m_flags &= ~f; }
@ -248,7 +248,9 @@ public:
bool isEnabled() const;
void setWindowIcon(const QIcon &icon);
void *surface(void *nativeConfig);
void *surface(void *nativeConfig, int *err);
void invalidateSurface() Q_DECL_OVERRIDE;
void aboutToMakeCurrent();
#ifndef Q_OS_WINCE
void setAlertState(bool enabled);
@ -257,6 +259,9 @@ public:
void stopAlertWindow();
#endif
static void setTouchWindowTouchTypeStatic(QWindow *window, QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes);
void registerTouchWindow(QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes = QWindowsWindowFunctions::NormalTouch);
private:
inline void show_sys() const;
inline void hide_sys() const;
@ -272,7 +277,7 @@ private:
void destroyWindow();
inline bool isDropSiteEnabled() const { return m_dropTarget != 0; }
void setDropSiteEnabled(bool enabled);
void updateDropSite();
void updateDropSite(bool topLevel);
void handleGeometryChange();
void handleWindowStateChange(Qt::WindowState state);
inline void destroyIcon();

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -327,16 +327,13 @@ Q_GLOBAL_STATIC(QUrl, lastVisitedDir)
This signal is emitted when the user selects a \a filter.
*/
//#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
//bool Q_WIDGETS_EXPORT qt_use_native_dialogs = true; // for the benefit of testing tools, until we have a proper API
//#endif
QT_BEGIN_INCLUDE_NAMESPACE
#ifdef Q_WS_WIN
#ifdef Q_DEAD_CODE_FROM_QT4_WIN
#include <qwindowsstyle_p.h>
#endif
#include <QMetaEnum>
#include <qshortcut.h>
#ifdef Q_WS_MAC
#ifdef Q_DEAD_CODE_FROM_QT4_MAC
#include <qmacstyle_mac_p.h>
#endif
QT_END_INCLUDE_NAMESPACE
@ -389,9 +386,8 @@ QFileDialog::QFileDialog(const QFileDialogArgs &args)
QFileDialog::~QFileDialog()
{
#ifndef QT_NO_SETTINGS
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
settings.beginGroup(QLatin1String("Qt"));
settings.setValue(QLatin1String("filedialog"), saveState());
Q_D(QFileDialog);
d->saveSettings();
#endif
}
@ -507,34 +503,7 @@ bool QFileDialog::restoreState(const QByteArray &state)
if (!d->usingWidgets())
return true;
if (!d->qFileDialogUi->splitter->restoreState(d->splitterState))
return false;
QList<int> list = d->qFileDialogUi->splitter->sizes();
if (list.count() >= 2 && (list.at(0) == 0 || list.at(1) == 0)) {
for (int i = 0; i < list.count(); ++i)
list[i] = d->qFileDialogUi->splitter->widget(i)->sizeHint().width();
d->qFileDialogUi->splitter->setSizes(list);
}
d->qFileDialogUi->sidebar->setUrls(d->sidebarUrls);
while (history.count() > 5)
history.pop_front();
setHistory(history);
QHeaderView *headerView = d->qFileDialogUi->treeView->header();
if (!headerView->restoreState(d->headerData))
return false;
QList<QAction*> actions = headerView->actions();
QAbstractItemModel *abstractModel = d->model;
#ifndef QT_NO_PROXYMODEL
if (d->proxyModel)
abstractModel = d->proxyModel;
#endif
int total = qMin(abstractModel->columnCount(QModelIndex()), actions.count() + 1);
for (int i = 1; i < total; ++i)
actions.at(i - 1)->setChecked(!headerView->isSectionHidden(i));
return true;
return d->restoreWidgetState(history, -1);
}
/*!
@ -590,10 +559,6 @@ void QFileDialogPrivate::helperPrepareShow(QPlatformDialogHelper *)
options->setHistory(q->history());
if (usingWidgets())
options->setSidebarUrls(qFileDialogUi->sidebar->urls());
const QDir directory = q->directory();
options->setInitialDirectory(directory.exists() ?
QUrl::fromLocalFile(directory.absolutePath()) :
QUrl());
if (options->initiallySelectedNameFilter().isEmpty())
options->setInitiallySelectedNameFilter(q->selectedNameFilter());
if (options->initiallySelectedFiles().isEmpty())
@ -928,12 +893,17 @@ void QFileDialogPrivate::_q_goToUrl(const QUrl &url)
/*!
Sets the file dialog's current \a directory.
\note On iOS, if you set \a directory to \l{QStandardPaths::standardLocations()}
{QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).last()},
a native image picker dialog will be used for accessing the user's photo album.
The filename returned can be loaded using QFile and related APIs.
This feature was added in Qt 5.5.
*/
void QFileDialog::setDirectory(const QString &directory)
{
Q_D(QFileDialog);
QString newDirectory = directory;
QFileInfo info(directory);
//we remove .. and . from the given path if exist
if (!directory.isEmpty())
newDirectory = QDir::cleanPath(directory);
@ -942,7 +912,7 @@ void QFileDialog::setDirectory(const QString &directory)
return;
QUrl newDirUrl = QUrl::fromLocalFile(newDirectory);
d->setLastVisitedDirectory(newDirUrl);
QFileDialogPrivate::setLastVisitedDirectory(newDirUrl);
d->options->setInitialDirectory(QUrl::fromLocalFile(directory));
if (!d->usingWidgets()) {
@ -985,6 +955,16 @@ QDir QFileDialog::directory() const
\note The non-native QFileDialog supports only local files.
\note On Windows, it is possible to pass URLs representing
one of the \e {virtual folders}, such as "Computer" or "Network".
This is done by passing a QUrl using the scheme \c clsid followed
by the CLSID value with the curly braces removed. For example the URL
\c clsid:374DE290-123F-4565-9164-39C4925E467B denotes the download
location. For a complete list of possible values, see the MSDN documentation on
\l{https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457.aspx}{KNOWNFOLDERID}.
This feature was added in Qt 5.5.
\sa QUuid
\since 5.2
*/
void QFileDialog::setDirectoryUrl(const QUrl &directory)
@ -993,14 +973,14 @@ void QFileDialog::setDirectoryUrl(const QUrl &directory)
if (!directory.isValid())
return;
d->setLastVisitedDirectory(directory);
QFileDialogPrivate::setLastVisitedDirectory(directory);
d->options->setInitialDirectory(directory);
if (d->nativeDialogInUse)
d->setDirectory_sys(directory);
else if (directory.isLocalFile())
setDirectory(directory.toLocalFile());
else
else if (d->usingWidgets())
qWarning() << "Non-native QFileDialog supports only local files";
}
@ -1227,7 +1207,7 @@ QByteArray QFileDialogPrivate::userSelectedRemoteContent() const
return QByteArray();
}
QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList filesToFix) const
QStringList QFileDialogPrivate::addDefaultSuffixToFiles(const QStringList &filesToFix) const
{
QStringList files;
for (int i=0; i<filesToFix.size(); ++i) {
@ -1540,6 +1520,8 @@ void QFileDialog::setFilter(QDir::Filters filters)
d->showHiddenAction->setChecked((filters & QDir::Hidden));
}
#ifndef QT_NO_MIMETYPE
static QString nameFilterForMime(const QString &mimeType)
{
QMimeDatabase db;
@ -1609,6 +1591,8 @@ void QFileDialog::selectMimeTypeFilter(const QString &filter)
selectNameFilter(text);
}
#endif // QT_NO_MIMETYPE
/*!
\property QFileDialog::viewMode
\brief the way files and directories are displayed in the dialog
@ -2680,6 +2664,104 @@ void QFileDialog::accept()
}
}
#ifndef QT_NO_SETTINGS
void QFileDialogPrivate::saveSettings()
{
Q_Q(QFileDialog);
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
settings.beginGroup(QLatin1String("FileDialog"));
if (usingWidgets()) {
settings.setValue(QLatin1String("sidebarWidth"), qFileDialogUi->splitter->sizes().first());
settings.setValue(QLatin1String("shortcuts"), QUrl::toStringList(qFileDialogUi->sidebar->urls()));
settings.setValue(QLatin1String("treeViewHeader"), qFileDialogUi->treeView->header()->saveState());
}
QStringList historyUrls;
foreach (const QString &path, q->history())
historyUrls << QUrl::fromLocalFile(path).toString();
settings.setValue(QLatin1String("history"), historyUrls);
settings.setValue(QLatin1String("lastVisited"), lastVisitedDir()->toString());
const QMetaEnum &viewModeMeta = q->metaObject()->enumerator(q->metaObject()->indexOfEnumerator("ViewMode"));
settings.setValue(QLatin1String("viewMode"), QLatin1String(viewModeMeta.key(q->viewMode())));
settings.setValue(QLatin1String("qtVersion"), QLatin1String(QT_VERSION_STR));
}
bool QFileDialogPrivate::restoreFromSettings()
{
Q_Q(QFileDialog);
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
if (!settings.childGroups().contains(QLatin1String("FileDialog")))
return false;
settings.beginGroup(QLatin1String("FileDialog"));
q->setDirectoryUrl(lastVisitedDir()->isEmpty() ? settings.value(QLatin1String("lastVisited")).toUrl() : *lastVisitedDir());
QByteArray viewModeStr = settings.value(QLatin1String("viewMode")).toString().toLatin1();
const QMetaEnum &viewModeMeta = q->metaObject()->enumerator(q->metaObject()->indexOfEnumerator("ViewMode"));
bool ok = false;
int viewMode = viewModeMeta.keyToValue(viewModeStr.constData(), &ok);
if (!ok)
viewMode = QFileDialog::List;
q->setViewMode(static_cast<QFileDialog::ViewMode>(viewMode));
sidebarUrls = QUrl::fromStringList(settings.value(QLatin1String("shortcuts")).toStringList());
headerData = settings.value(QLatin1String("treeViewHeader")).toByteArray();
if (!usingWidgets())
return true;
QStringList history;
foreach (const QString &urlStr, settings.value(QLatin1String("history")).toStringList()) {
QUrl url(urlStr);
if (url.isLocalFile())
history << url.toLocalFile();
}
return restoreWidgetState(history, settings.value(QLatin1String("sidebarWidth"), -1).toInt());
}
#endif // QT_NO_SETTINGS
bool QFileDialogPrivate::restoreWidgetState(QStringList &history, int splitterPosition)
{
Q_Q(QFileDialog);
if (splitterPosition >= 0) {
QList<int> splitterSizes;
splitterSizes.append(splitterPosition);
splitterSizes.append(qFileDialogUi->splitter->widget(1)->sizeHint().width());
qFileDialogUi->splitter->setSizes(splitterSizes);
} else {
if (!qFileDialogUi->splitter->restoreState(splitterState))
return false;
QList<int> list = qFileDialogUi->splitter->sizes();
if (list.count() >= 2 && (list.at(0) == 0 || list.at(1) == 0)) {
for (int i = 0; i < list.count(); ++i)
list[i] = qFileDialogUi->splitter->widget(i)->sizeHint().width();
qFileDialogUi->splitter->setSizes(list);
}
}
qFileDialogUi->sidebar->setUrls(sidebarUrls);
while (history.count() > 5)
history.pop_front();
q->setHistory(history);
QHeaderView *headerView = qFileDialogUi->treeView->header();
if (!headerView->restoreState(headerData))
return false;
QList<QAction*> actions = headerView->actions();
QAbstractItemModel *abstractModel = model;
#ifndef QT_NO_PROXYMODEL
if (proxyModel)
abstractModel = proxyModel;
#endif
int total = qMin(abstractModel->columnCount(QModelIndex()), actions.count() + 1);
for (int i = 1; i < total; ++i)
actions.at(i - 1)->setChecked(!headerView->isSectionHidden(i));
return true;
}
/*!
\internal
@ -2706,8 +2788,12 @@ void QFileDialogPrivate::init(const QUrl &directory, const QString &nameFilter,
q->selectFile(initialSelection(directory));
#ifndef QT_NO_SETTINGS
const QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
q->restoreState(settings.value(QLatin1String("Qt/filedialog")).toByteArray());
// Try to restore from the FileDialog settings group; if it fails, fall back
// to the pre-5.5 QByteArray serialized settings.
if (!restoreFromSettings()) {
const QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
q->restoreState(settings.value(QLatin1String("Qt/filedialog")).toByteArray());
}
#endif
#if defined(Q_EMBEDDED_SMALLSCREEN)
@ -2731,7 +2817,7 @@ void QFileDialogPrivate::createWidgets()
return;
Q_Q(QFileDialog);
model = new QFileSystemModel(q);
options->setFilter(model->filter());
model->setFilter(options->filter());
model->setObjectName(QLatin1String("qt_filesystem_model"));
if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
model->setNameFilterDisables(helper->defaultNameFilterDisables());
@ -2855,8 +2941,12 @@ void QFileDialogPrivate::createWidgets()
createMenuActions();
#ifndef QT_NO_SETTINGS
const QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
q->restoreState(settings.value(QLatin1String("Qt/filedialog")).toByteArray());
// Try to restore from the FileDialog settings group; if it fails, fall back
// to the pre-5.5 QByteArray serialized settings.
if (!restoreFromSettings()) {
const QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
q->restoreState(settings.value(QLatin1String("Qt/filedialog")).toByteArray());
}
#endif
// Initial widget states from options
@ -2867,9 +2957,12 @@ void QFileDialogPrivate::createWidgets()
if (!options->sidebarUrls().isEmpty())
q->setSidebarUrls(options->sidebarUrls());
q->setDirectoryUrl(options->initialDirectory());
#ifndef QT_NO_MIMETYPE
if (!options->mimeTypeFilters().isEmpty())
q->setMimeTypeFilters(options->mimeTypeFilters());
else if (!options->nameFilters().isEmpty())
else
#endif
if (!options->nameFilters().isEmpty())
q->setNameFilters(options->nameFilters());
q->selectNameFilter(options->initiallySelectedNameFilter());
q->setDefaultSuffix(options->defaultSuffix());
@ -3610,7 +3703,7 @@ void QFileDialogPrivate::_q_rowsInserted(const QModelIndex &parent)
return;
}
void QFileDialogPrivate::_q_fileRenamed(const QString &path, const QString oldName, const QString newName)
void QFileDialogPrivate::_q_fileRenamed(const QString &path, const QString &oldName, const QString &newName)
{
const QFileDialog::FileMode fileMode = q_func()->fileMode();
if (fileMode == QFileDialog::Directory || fileMode == QFileDialog::DirectoryOnly) {

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -55,7 +55,6 @@ class QAbstractProxyModel;
class Q_WIDGETS_EXPORT QFileDialog : public QDialog
{
Q_OBJECT
Q_ENUMS(ViewMode FileMode AcceptMode Option)
Q_FLAGS(Options)
Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode)
Q_PROPERTY(FileMode fileMode READ fileMode WRITE setFileMode)
@ -70,8 +69,11 @@ class Q_WIDGETS_EXPORT QFileDialog : public QDialog
public:
enum ViewMode { Detail, List };
Q_ENUM(ViewMode)
enum FileMode { AnyFile, ExistingFile, Directory, ExistingFiles, DirectoryOnly };
Q_ENUM(FileMode)
enum AcceptMode { AcceptOpen, AcceptSave };
Q_ENUM(AcceptMode)
enum DialogLabel { LookIn, FileName, FileType, Accept, Reject };
enum Option
@ -85,6 +87,7 @@ public:
HideNameFilterDetails = 0x00000040,
DontUseCustomDirectoryIcons = 0x00000080
};
Q_ENUM(Option)
Q_DECLARE_FLAGS(Options, Option)
QFileDialog(QWidget *parent, Qt::WindowFlags f);
@ -117,9 +120,11 @@ public:
void selectNameFilter(const QString &filter);
QString selectedNameFilter() const;
#ifndef QT_NO_MIMETYPE
void setMimeTypeFilters(const QStringList &filters);
QStringList mimeTypeFilters() const;
void selectMimeTypeFilter(const QString &filter);
#endif
QDir::Filters filter() const;
void setFilter(QDir::Filters filters);
@ -173,15 +178,9 @@ public:
void setOptions(Options options);
Options options() const;
#ifdef Q_NO_USING_KEYWORD
#ifndef Q_QDOC
void open() { QDialog::open(); }
#endif
#else
using QDialog::open;
#endif
void open(QObject *receiver, const char *member);
void setVisible(bool visible);
void setVisible(bool visible) Q_DECL_OVERRIDE;
Q_SIGNALS:
void fileSelected(const QString &file);
@ -257,9 +256,9 @@ public:
protected:
QFileDialog(const QFileDialogArgs &args);
void done(int result);
void accept();
void changeEvent(QEvent *e);
void done(int result) Q_DECL_OVERRIDE;
void accept() Q_DECL_OVERRIDE;
void changeEvent(QEvent *e) Q_DECL_OVERRIDE;
private:
Q_DECLARE_PRIVATE(QFileDialog)
@ -293,7 +292,8 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_autoCompleteFileName(const QString &text))
Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex & parent))
Q_PRIVATE_SLOT(d_func(), void _q_fileRenamed(const QString &path,
const QString oldName, const QString newName))
const QString &oldName,
const QString &newName))
friend class QPlatformDialogHelper;
};

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -124,7 +124,7 @@ public:
QStringList typedFiles() const;
QList<QUrl> userSelectedFiles() const;
QByteArray userSelectedRemoteContent() const;
QStringList addDefaultSuffixToFiles(const QStringList filesToFix) const;
QStringList addDefaultSuffixToFiles(const QStringList &filesToFix) const;
QList<QUrl> addDefaultSuffixToUrls(const QList<QUrl> &urlsToFix) const;
bool removeDirectory(const QString &path);
void setLabelTextControl(QFileDialog::DialogLabel label, const QString &text);
@ -182,7 +182,13 @@ public:
#endif
}
void setLastVisitedDirectory(const QUrl &dir);
#ifndef QT_NO_SETTINGS
void saveSettings();
bool restoreFromSettings();
#endif
bool restoreWidgetState(QStringList &history, int splitterPosition);
static void setLastVisitedDirectory(const QUrl &dir);
void retranslateWindowTitle();
void retranslateStrings();
void emitFilesSelected(const QStringList &files);
@ -213,7 +219,7 @@ public:
void _q_goToUrl(const QUrl &url);
void _q_autoCompleteFileName(const QString &);
void _q_rowsInserted(const QModelIndex & parent);
void _q_fileRenamed(const QString &path, const QString oldName, const QString newName);
void _q_fileRenamed(const QString &path, const QString &oldName, const QString &newName);
// layout
#ifndef QT_NO_PROXYMODEL
@ -244,7 +250,7 @@ public:
// setVisible_sys returns true if it ends up showing a native
// dialog. Returning false means that a non-native dialog must be
// used instead.
bool canBeNativeDialog() const;
bool canBeNativeDialog() const Q_DECL_OVERRIDE;
inline bool usingWidgets() const;
void setDirectory_sys(const QUrl &directory);
@ -275,9 +281,9 @@ public:
~QFileDialogPrivate();
private:
virtual void initHelper(QPlatformDialogHelper *);
virtual void helperPrepareShow(QPlatformDialogHelper *);
virtual void helperDone(QDialog::DialogCode, QPlatformDialogHelper *);
virtual void initHelper(QPlatformDialogHelper *) Q_DECL_OVERRIDE;
virtual void helperPrepareShow(QPlatformDialogHelper *) Q_DECL_OVERRIDE;
virtual void helperDone(QDialog::DialogCode, QPlatformDialogHelper *) Q_DECL_OVERRIDE;
Q_DISABLE_COPY(QFileDialogPrivate)
};
@ -287,7 +293,7 @@ class QFileDialogLineEdit : public QLineEdit
public:
QFileDialogLineEdit(QWidget *parent = 0) : QLineEdit(parent), d_ptr(0){}
void setFileDialogPrivate(QFileDialogPrivate *d_pointer) {d_ptr = d_pointer; }
void keyPressEvent(QKeyEvent *e);
void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE;
bool hideOnEsc;
private:
QFileDialogPrivate *d_ptr;
@ -298,10 +304,10 @@ class QFileDialogComboBox : public QComboBox
public:
QFileDialogComboBox(QWidget *parent = 0) : QComboBox(parent), urlModel(0) {}
void setFileDialogPrivate(QFileDialogPrivate *d_pointer);
void showPopup();
void showPopup() Q_DECL_OVERRIDE;
void setHistory(const QStringList &paths);
QStringList history() const { return m_history; }
void paintEvent(QPaintEvent *);
void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
private:
QUrlModel *urlModel;
@ -314,9 +320,9 @@ class QFileDialogListView : public QListView
public:
QFileDialogListView(QWidget *parent = 0);
void setFileDialogPrivate(QFileDialogPrivate *d_pointer);
QSize sizeHint() const;
QSize sizeHint() const Q_DECL_OVERRIDE;
protected:
void keyPressEvent(QKeyEvent *e);
void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE;
private:
QFileDialogPrivate *d_ptr;
};
@ -326,10 +332,10 @@ class QFileDialogTreeView : public QTreeView
public:
QFileDialogTreeView(QWidget *parent);
void setFileDialogPrivate(QFileDialogPrivate *d_pointer);
QSize sizeHint() const;
QSize sizeHint() const Q_DECL_OVERRIDE;
protected:
void keyPressEvent(QKeyEvent *e);
void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE;
private:
QFileDialogPrivate *d_ptr;
};

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -37,6 +37,7 @@
#ifndef QT_NO_SYSTEMTRAYICON
#include "qmenu.h"
#include "qlist.h"
#include "qevent.h"
#include "qpoint.h"
#include "qlabel.h"
@ -69,8 +70,12 @@ QT_BEGIN_NAMESPACE
\list
\li All supported versions of Windows.
\li All window managers for X11 that implement the \l{freedesktop.org} system
tray specification, including recent versions of KDE and GNOME.
\li All window managers and independent tray implementations for X11 that implement the
\l{http://standards.freedesktop.org/systemtray-spec/systemtray-spec-0.2.html freedesktop.org}
XEmbed system tray specification.
\li All X11 desktop environments that implement the D-Bus
\l{http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/ StatusNotifierItem}
specification, including recent versions of KDE and Unity.
\li All supported versions of Mac OS X. Note that the Growl
notification system must be installed for
QSystemTrayIcon::showMessage() to display messages on Mac OS X prior to 10.8 (Mountain Lion).
@ -279,7 +284,7 @@ bool QSystemTrayIcon::isVisible() const
*/
bool QSystemTrayIcon::event(QEvent *e)
{
#if defined(Q_WS_X11)
#if defined(Q_DEAD_CODE_FROM_QT4_X11)
if (e->type() == QEvent::ToolTip) {
Q_D(QSystemTrayIcon);
return d->sys->deliverToolTipEvent(e);
@ -582,7 +587,7 @@ void QBalloonTip::balloon(const QPoint& pos, int msecs, bool showArrow)
}
QPainterPath path;
#if defined(QT_NO_XSHAPE) && defined(Q_WS_X11)
#if defined(QT_NO_XSHAPE) && defined(Q_DEAD_CODE_FROM_QT4_X11)
// XShape is required for setting the mask, so we just
// draw an ugly square when its not available
path.moveTo(0, 0);
@ -704,15 +709,11 @@ void QSystemTrayIconPrivate::updateIcon_sys_qpa()
void QSystemTrayIconPrivate::updateMenu_sys_qpa()
{
if (menu) {
if (!menu->platformMenu()) {
QPlatformMenu *platformMenu = qpa_sys->createMenu();
if (platformMenu)
menu->setPlatformMenu(platformMenu);
}
addPlatformMenu(menu);
qpa_sys->updateMenu(menu->platformMenu());
} else {
qpa_sys->updateMenu(0);
}
}
}
void QSystemTrayIconPrivate::updateToolTip_sys_qpa()
@ -720,8 +721,8 @@ void QSystemTrayIconPrivate::updateToolTip_sys_qpa()
qpa_sys->updateToolTip(toolTip);
}
void QSystemTrayIconPrivate::showMessage_sys_qpa(const QString &message,
const QString &title,
void QSystemTrayIconPrivate::showMessage_sys_qpa(const QString &title,
const QString &message,
QSystemTrayIcon::MessageIcon icon,
int msecs)
{
@ -739,10 +740,31 @@ void QSystemTrayIconPrivate::showMessage_sys_qpa(const QString &message,
default:
break;
}
qpa_sys->showMessage(message, title, notificationIcon,
qpa_sys->showMessage(title, message, notificationIcon,
static_cast<QPlatformSystemTrayIcon::MessageIcon>(icon), msecs);
}
void QSystemTrayIconPrivate::addPlatformMenu(QMenu *menu) const
{
if (menu->platformMenu())
return; // The platform menu already exists.
// The recursion depth is the same as menu depth, so should not
// be higher than 3 levels.
QListIterator<QAction *> it(menu->actions());
while (it.hasNext()) {
QAction *action = it.next();
if (action->menu())
addPlatformMenu(action->menu());
}
// This menu should be processed *after* its children, otherwise
// setMenu() is not called on respective QPlatformMenuItems.
QPlatformMenu *platformMenu = qpa_sys->createMenu();
if (platformMenu)
menu->setPlatformMenu(platformMenu);
}
QT_END_NAMESPACE
#endif // QT_NO_SYSTEMTRAYICON

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -66,7 +66,7 @@ int QWidgetLineControl::redoTextLayout() const
QTextLine l = m_textLayout.createLine();
m_textLayout.endLayout();
#if defined(Q_WS_MAC)
#if defined(Q_DEAD_CODE_FROM_QT4_MAC)
if (m_threadChecks)
m_textLayoutThread = QThread::currentThread();
#endif
@ -183,7 +183,7 @@ void QWidgetLineControl::commitPreedit()
if (!composeMode())
return;
qApp->inputMethod()->commit();
QGuiApplication::inputMethod()->commit();
if (!composeMode())
return;
@ -279,6 +279,23 @@ void QWidgetLineControl::clear()
separate();
finishChange(priorState, /*update*/false, /*edited*/false);
}
/*!
\internal
Undoes the previous operation.
*/
void QWidgetLineControl::undo()
{
// Undo works only for clearing the line when in any of password the modes
if (m_echoMode == QLineEdit::Normal) {
internalUndo();
finishChange(-1, true);
} else {
cancelPasswordEchoTimer();
clear();
}
}
/*!
\internal
@ -919,7 +936,7 @@ void QWidgetLineControl::parseInputMask(const QString &maskFields)
delete [] m_maskData;
m_maskData = 0;
m_maxLength = 32767;
internalSetText(QString());
internalSetText(QString(), -1, false);
}
return;
}
@ -1005,7 +1022,7 @@ void QWidgetLineControl::parseInputMask(const QString &maskFields)
}
}
}
internalSetText(m_text);
internalSetText(m_text, -1, false);
}
@ -1278,12 +1295,6 @@ void QWidgetLineControl::internalUndo(int until)
cancelPasswordEchoTimer();
internalDeselect();
// Undo works only for clearing the line when in any of password the modes
if (m_echoMode != QLineEdit::Normal) {
clear();
return;
}
while (m_undoState && m_undoState > until) {
Command& cmd = m_history[--m_undoState];
switch (cmd.type) {
@ -1868,9 +1879,12 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
unknown = false;
}
if (unknown && !isReadOnly()) {
// QTBUG-35734: ignore Ctrl/Ctrl+Shift; accept only AltGr (Alt+Ctrl) on German keyboards
if (unknown && !isReadOnly()
&& event->modifiers() != Qt::ControlModifier
&& event->modifiers() != (Qt::ControlModifier | Qt::ShiftModifier)) {
QString t = event->text();
if (!t.isEmpty() && (t.at(0).isPrint() || t.at(0).unicode() == 0x200C || t.at(0).unicode() == 0x200D)) {
if (!t.isEmpty() && (t.at(0).isPrint() || t.at(0).unicode() == 0x200C || t.at(0).unicode() == 0x200D)) {
insert(t);
#ifndef QT_NO_COMPLETER
complete(event->key());

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
@ -10,9 +10,9 @@
** 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.
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@ -110,7 +110,7 @@ QWidgetTextControlPrivate::QWidgetTextControlPrivate()
#ifndef Q_OS_ANDROID
interactionFlags(Qt::TextEditorInteraction),
#else
interactionFlags(Qt::TextEditable),
interactionFlags(Qt::TextEditable | Qt::TextSelectableByKeyboard),
#endif
dragEnabled(true),
#ifndef QT_NO_DRAGANDDROP
@ -1312,8 +1312,10 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
else if (e == QKeySequence::Delete) {
QTextCursor localCursor = cursor;
localCursor.deleteChar();
}
else if (e == QKeySequence::DeleteEndOfWord) {
} else if (e == QKeySequence::Backspace) {
QTextCursor localCursor = cursor;
localCursor.deletePreviousChar();
}else if (e == QKeySequence::DeleteEndOfWord) {
if (!cursor.hasSelection())
cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor);
cursor.removeSelectedText();
@ -1339,8 +1341,14 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
process:
{
// QTBUG-35734: ignore Ctrl/Ctrl+Shift; accept only AltGr (Alt+Ctrl) on German keyboards
if (e->modifiers() == Qt::ControlModifier
|| e->modifiers() == (Qt::ShiftModifier | Qt::ControlModifier)) {
e->ignore();
return;
}
QString text = e->text();
if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t') || text.at(0).unicode() == 0x200C || text.at(0).unicode() == 0x200D)) {
if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t') || text.at(0).unicode() == 0x200C || text.at(0).unicode() == 0x200D)) {
if (overwriteMode
// no need to call deleteChar() if we have a selection, insertText
// does it already
@ -1731,7 +1739,7 @@ void QWidgetTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button
_q_updateCurrentCharFormatAndSelection();
#ifndef QT_NO_IM
if (contextWidget)
qApp->inputMethod()->update(Qt::ImQueryInput);
QGuiApplication::inputMethod()->update(Qt::ImQueryInput);
#endif //QT_NO_IM
} else {
//emit q->visibilityRequest(QRectF(mousePos, QSizeF(1, 1)));
@ -1879,7 +1887,7 @@ bool QWidgetTextControlPrivate::sendMouseEventToInputContext(
if (cursorPos >= 0) {
if (eventType == QEvent::MouseButtonRelease)
qApp->inputMethod()->invokeAction(QInputMethod::Click, cursorPos);
QGuiApplication::inputMethod()->invokeAction(QInputMethod::Click, cursorPos);
e->setAccepted(true);
return true;
@ -2219,15 +2227,18 @@ QMenu *QWidgetTextControl::createStandardContextMenu(const QPointF &pos, QWidget
if (d->interactionFlags & Qt::TextEditable) {
a = menu->addAction(tr("&Undo") + ACCEL_KEY(QKeySequence::Undo), this, SLOT(undo()));
a->setEnabled(d->doc->isUndoAvailable());
a->setObjectName(QStringLiteral("edit-undo"));
setActionIcon(a, QStringLiteral("edit-undo"));
a = menu->addAction(tr("&Redo") + ACCEL_KEY(QKeySequence::Redo), this, SLOT(redo()));
a->setEnabled(d->doc->isRedoAvailable());
a->setObjectName(QStringLiteral("edit-redo"));
setActionIcon(a, QStringLiteral("edit-redo"));
menu->addSeparator();
#ifndef QT_NO_CLIPBOARD
a = menu->addAction(tr("Cu&t") + ACCEL_KEY(QKeySequence::Cut), this, SLOT(cut()));
a->setEnabled(d->cursor.hasSelection());
a->setObjectName(QStringLiteral("edit-cut"));
setActionIcon(a, QStringLiteral("edit-cut"));
#endif
}
@ -2236,6 +2247,7 @@ QMenu *QWidgetTextControl::createStandardContextMenu(const QPointF &pos, QWidget
if (showTextSelectionActions) {
a = menu->addAction(tr("&Copy") + ACCEL_KEY(QKeySequence::Copy), this, SLOT(copy()));
a->setEnabled(d->cursor.hasSelection());
a->setObjectName(QStringLiteral("edit-copy"));
setActionIcon(a, QStringLiteral("edit-copy"));
}
@ -2244,6 +2256,7 @@ QMenu *QWidgetTextControl::createStandardContextMenu(const QPointF &pos, QWidget
a = menu->addAction(tr("Copy &Link Location"), this, SLOT(_q_copyLink()));
a->setEnabled(!d->linkToCopy.isEmpty());
a->setObjectName(QStringLiteral("link-copy"));
}
#endif // QT_NO_CLIPBOARD
@ -2251,10 +2264,12 @@ QMenu *QWidgetTextControl::createStandardContextMenu(const QPointF &pos, QWidget
#ifndef QT_NO_CLIPBOARD
a = menu->addAction(tr("&Paste") + ACCEL_KEY(QKeySequence::Paste), this, SLOT(paste()));
a->setEnabled(canPaste());
a->setObjectName(QStringLiteral("edit-paste"));
setActionIcon(a, QStringLiteral("edit-paste"));
#endif
a = menu->addAction(tr("Delete"), this, SLOT(_q_deleteSelected()));
a->setEnabled(d->cursor.hasSelection());
a->setObjectName(QStringLiteral("edit-delete"));
setActionIcon(a, QStringLiteral("edit-delete"));
}
@ -2263,9 +2278,10 @@ QMenu *QWidgetTextControl::createStandardContextMenu(const QPointF &pos, QWidget
menu->addSeparator();
a = menu->addAction(tr("Select All") + ACCEL_KEY(QKeySequence::SelectAll), this, SLOT(selectAll()));
a->setEnabled(!d->doc->isEmpty());
a->setObjectName(QStringLiteral("select-all"));
}
if ((d->interactionFlags & Qt::TextEditable) && qApp->styleHints()->useRtlExtensions()) {
if ((d->interactionFlags & Qt::TextEditable) && QGuiApplication::styleHints()->useRtlExtensions()) {
menu->addSeparator();
QUnicodeControlCharacterMenu *ctrlCharacterMenu = new QUnicodeControlCharacterMenu(this, menu);
menu->addMenu(ctrlCharacterMenu);
@ -2851,7 +2867,7 @@ void QWidgetTextControlPrivate::commitPreedit()
if (!isPreediting())
return;
qApp->inputMethod()->commit();
QGuiApplication::inputMethod()->commit();
if (!isPreediting())
return;