Merge remote-tracking branch 'origin/5.3' into 5.4

Change-Id: I132bb6cce68e9f8413200f7ee75586bd1cada38c
This commit is contained in:
Oswald Buddenhagen 2014-10-06 11:59:47 +02:00
commit f49d5b578c
27 changed files with 363 additions and 204 deletions

View File

@ -133,11 +133,16 @@ contains(CONFIG, plugin) {
CMAKE_PLUGIN_NAME = $$PLUGIN_CLASS_NAME CMAKE_PLUGIN_NAME = $$PLUGIN_CLASS_NAME
win32 { win32 {
isEmpty(CMAKE_STATIC_TYPE): CMAKE_PlUGIN_EXT = .dll isEmpty(CMAKE_STATIC_TYPE) {
else: CMAKE_PlUGIN_EXT = .lib CMAKE_PLUGIN_LOCATION_RELEASE = $$PLUGIN_TYPE/$${TARGET}.dll
CMAKE_PLUGIN_LOCATION_DEBUG = $$PLUGIN_TYPE/$${TARGET}d.dll
CMAKE_PLUGIN_LOCATION_RELEASE = $$PLUGIN_TYPE/$${TARGET}$${CMAKE_PlUGIN_EXT} } else:mingw {
CMAKE_PLUGIN_LOCATION_DEBUG = $$PLUGIN_TYPE/$${TARGET}d$${CMAKE_PlUGIN_EXT} CMAKE_PLUGIN_LOCATION_RELEASE = $$PLUGIN_TYPE/lib$${TARGET}.a
CMAKE_PLUGIN_LOCATION_DEBUG = $$PLUGIN_TYPE/lib$${TARGET}d.a
} else { # MSVC static
CMAKE_PLUGIN_LOCATION_RELEASE = $$PLUGIN_TYPE/$${TARGET}.lib
CMAKE_PLUGIN_LOCATION_DEBUG = $$PLUGIN_TYPE/$${TARGET}d.lib
}
} else { } else {
mac { mac {
isEmpty(CMAKE_STATIC_TYPE): CMAKE_PlUGIN_EXT = .dylib isEmpty(CMAKE_STATIC_TYPE): CMAKE_PlUGIN_EXT = .dylib

View File

@ -30,7 +30,7 @@ CONFIG += plugin no_plugin_name_prefix
javac.input = JAVASOURCES javac.input = JAVASOURCES
javac.output = $$CLASS_DIR javac.output = $$CLASS_DIR
javac.CONFIG += combine javac.CONFIG += combine
javac.commands = javac -source 6 -target 6 -Xlint:unchecked -bootclasspath $$ANDROID_JAR_FILE -cp $$shell_quote($$system_path($$join(JAVACLASSPATH, $$DIRLIST_SEP))) -d $$shell_quote($$CLASS_DIR) ${QMAKE_FILE_IN} javac.commands = javac -source 6 -target 6 -Xlint:unchecked -bootclasspath $$ANDROID_JAR_FILE -cp $$shell_quote($$system_path($$join(JAVACLASSPATH, $$DIRLIST_SEPARATOR))) -d $$shell_quote($$CLASS_DIR) ${QMAKE_FILE_IN}
# Force rebuild every time, because we don't know the paths of the destination files # Force rebuild every time, because we don't know the paths of the destination files
# as they depend on the code. # as they depend on the code.
javac.depends = FORCE javac.depends = FORCE

View File

@ -101,8 +101,10 @@ mac:CONFIG(shared, static|shared):contains(QT_CONFIG, qt_framework) {
FRAMEWORK_HEADERS.version = Versions FRAMEWORK_HEADERS.version = Versions
FRAMEWORK_HEADERS.files = $$SYNCQT.HEADER_FILES $$SYNCQT.HEADER_CLASSES FRAMEWORK_HEADERS.files = $$SYNCQT.HEADER_FILES $$SYNCQT.HEADER_CLASSES
FRAMEWORK_HEADERS.path = Headers FRAMEWORK_HEADERS.path = Headers
FRAMEWORK_PRIVATE_HEADERS.version = Versions
FRAMEWORK_PRIVATE_HEADERS.files = $$SYNCQT.PRIVATE_HEADER_FILES FRAMEWORK_PRIVATE_HEADERS.files = $$SYNCQT.PRIVATE_HEADER_FILES
FRAMEWORK_PRIVATE_HEADERS.path = Headers/$$VERSION/$$MODULE_INCNAME/private FRAMEWORK_PRIVATE_HEADERS.path = Headers/$$VERSION/$$MODULE_INCNAME/private
FRAMEWORK_QPA_HEADERS.version = Versions
FRAMEWORK_QPA_HEADERS.files = $$SYNCQT.QPA_HEADER_FILES FRAMEWORK_QPA_HEADERS.files = $$SYNCQT.QPA_HEADER_FILES
FRAMEWORK_QPA_HEADERS.path = Headers/$$VERSION/$$MODULE_INCNAME/qpa FRAMEWORK_QPA_HEADERS.path = Headers/$$VERSION/$$MODULE_INCNAME/qpa
QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS FRAMEWORK_PRIVATE_HEADERS FRAMEWORK_QPA_HEADERS QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS FRAMEWORK_PRIVATE_HEADERS FRAMEWORK_QPA_HEADERS

View File

@ -25,10 +25,13 @@ CONFIG(static, static|shared) {
!macx-xcode: \ !macx-xcode: \
addExclusiveBuilds(shared, static) addExclusiveBuilds(shared, static)
CONFIG(debug, debug|release): \ CONFIG(debug, debug|release) {
CONFIG -= release CONFIG -= release
else: \ !force_debug_plist:debug_and_release: \
CONFIG += no_plist
} else {
CONFIG -= debug CONFIG -= debug
}
!macx-xcode { !macx-xcode {
addExclusiveBuilds(debug, release) addExclusiveBuilds(debug, release)

View File

@ -6,6 +6,8 @@
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>@SHORT_VERSION@</string> <string>@SHORT_VERSION@</string>
<key>CFBundleVersion</key>
<string>@FULL_VERSION@</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string> <string>Created by Qt/QMake</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>

View File

@ -6,6 +6,8 @@
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>@SHORT_VERSION@</string> <string>@SHORT_VERSION@</string>
<key>CFBundleVersion</key>
<string>@FULL_VERSION@</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string> <string>Created by Qt/QMake</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>

View File

@ -6,6 +6,8 @@
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>@SHORT_VERSION@</string> <string>@SHORT_VERSION@</string>
<key>CFBundleVersion</key>
<string>@FULL_VERSION@</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string> <string>Created by Qt/QMake</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>

View File

@ -6,6 +6,8 @@
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>@SHORT_VERSION@</string> <string>@SHORT_VERSION@</string>
<key>CFBundleVersion</key>
<string>@FULL_VERSION@</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string> <string>Created by Qt/QMake</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>

View File

@ -6,6 +6,8 @@
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>@SHORT_VERSION@</string> <string>@SHORT_VERSION@</string>
<key>CFBundleVersion</key>
<string>@FULL_VERSION@</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string> <string>Created by Qt/QMake</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>

View File

@ -6,6 +6,8 @@
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>@SHORT_VERSION@</string> <string>@SHORT_VERSION@</string>
<key>CFBundleVersion</key>
<string>@FULL_VERSION@</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string> <string>Created by Qt/QMake</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>

View File

@ -6,6 +6,8 @@
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>@SHORT_VERSION@</string> <string>@SHORT_VERSION@</string>
<key>CFBundleVersion</key>
<string>@FULL_VERSION@</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string> <string>Created by Qt/QMake</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>

View File

@ -6,6 +6,8 @@
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>@SHORT_VERSION@</string> <string>@SHORT_VERSION@</string>
<key>CFBundleVersion</key>
<string>@FULL_VERSION@</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string> <string>Created by Qt/QMake</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>

View File

@ -6,6 +6,8 @@
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>@SHORT_VERSION@</string> <string>@SHORT_VERSION@</string>
<key>CFBundleVersion</key>
<string>@FULL_VERSION@</string>
<key>CFBundleGetInfoString</key> <key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string> <string>Created by Qt/QMake</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>

View File

@ -306,8 +306,6 @@ UnixMakefileGenerator::init()
} }
if(!bundle.isEmpty()) { if(!bundle.isEmpty()) {
project->values("QMAKE_BUNDLE") = ProStringList(bundle); project->values("QMAKE_BUNDLE") = ProStringList(bundle);
project->values("ALL_DEPS") += project->first("QMAKE_PKGINFO");
project->values("ALL_DEPS") += project->first("QMAKE_BUNDLE_RESOURCE_FILE");
} else { } else {
project->values("QMAKE_BUNDLE").clear(); project->values("QMAKE_BUNDLE").clear();
project->values("QMAKE_BUNDLE_LOCATION").clear(); project->values("QMAKE_BUNDLE_LOCATION").clear();

View File

@ -430,6 +430,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
} }
} }
} }
QString allDeps;
if (!project->values("QMAKE_APP_FLAG").isEmpty() || project->first("TEMPLATE") == "aux") { if (!project->values("QMAKE_APP_FLAG").isEmpty() || project->first("TEMPLATE") == "aux") {
QString destdir = project->first("DESTDIR").toQString(); QString destdir = project->first("DESTDIR").toQString();
if(!project->isEmpty("QMAKE_BUNDLE")) { if(!project->isEmpty("QMAKE_BUNDLE")) {
@ -490,8 +491,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
deps.prepend(incr_target_dir + " "); deps.prepend(incr_target_dir + " ");
incr_deps = "$(OBJECTS)"; incr_deps = "$(OBJECTS)";
} }
t << "all: " << escapeDependencyPath(deps) << " " << valGlue(escapeDependencyPaths(project->values("ALL_DEPS")),""," "," ") << "$(TARGET)"
<< endl << endl;
//real target //real target
t << var("TARGET") << ": " << var("PRE_TARGETDEPS") << " " << incr_deps << " " << target_deps t << var("TARGET") << ": " << var("PRE_TARGETDEPS") << " " << incr_deps << " " << target_deps
@ -505,9 +504,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\n\t" << var("QMAKE_POST_LINK"); t << "\n\t" << var("QMAKE_POST_LINK");
t << endl << endl; t << endl << endl;
} else { } else {
t << "all: " << escapeDependencyPath(deps) << " " << valGlue(escapeDependencyPaths(project->values("ALL_DEPS")),""," "," ") << "$(TARGET)"
<< endl << endl;
t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(OBJECTS) " t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(OBJECTS) "
<< target_deps << " " << var("POST_TARGETDEPS") << "\n\t"; << target_deps << " " << var("POST_TARGETDEPS") << "\n\t";
if (project->first("TEMPLATE") != "aux") { if (project->first("TEMPLATE") != "aux") {
@ -521,6 +517,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
} }
t << endl << endl; t << endl << endl;
} }
allDeps = " $(TARGET)";
} else if(!project->isActiveConfig("staticlib")) { } else if(!project->isActiveConfig("staticlib")) {
QString destdir = unescapeFilePath(project->first("DESTDIR").toQString()), incr_deps; QString destdir = unescapeFilePath(project->first("DESTDIR").toQString()), incr_deps;
if(!project->isEmpty("QMAKE_BUNDLE")) { if(!project->isEmpty("QMAKE_BUNDLE")) {
@ -580,19 +577,15 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
incr_deps = "$(OBJECTS)"; incr_deps = "$(OBJECTS)";
} }
t << "all: " << escapeDependencyPath(deps) << " " << valGlue(escapeDependencyPaths(project->values("ALL_DEPS")),""," "," ")
<< " " << destdir << "$(TARGET)\n\n";
//real target //real target
t << destdir << "$(TARGET): " << var("PRE_TARGETDEPS") << " " t << destdir << "$(TARGET): " << var("PRE_TARGETDEPS") << " "
<< incr_deps << " $(SUBLIBS) " << target_deps << " " << var("POST_TARGETDEPS"); << incr_deps << " $(SUBLIBS) " << target_deps << " " << var("POST_TARGETDEPS");
} else { } else {
t << "all: " << escapeDependencyPath(deps) << " " << valGlue(escapeDependencyPaths(project->values("ALL_DEPS")),""," "," ") << " " <<
destdir << "$(TARGET)\n\n";
t << destdir << "$(TARGET): " << var("PRE_TARGETDEPS") t << destdir << "$(TARGET): " << var("PRE_TARGETDEPS")
<< " $(OBJECTS) $(SUBLIBS) $(OBJCOMP) " << target_deps << " $(OBJECTS) $(SUBLIBS) $(OBJCOMP) " << target_deps
<< " " << var("POST_TARGETDEPS"); << " " << var("POST_TARGETDEPS");
} }
allDeps = ' ' + destdir + "$(TARGET)";
if(!destdir.isEmpty()) if(!destdir.isEmpty())
t << "\n\t" << mkdir_p_asstring(destdir, false); t << "\n\t" << mkdir_p_asstring(destdir, false);
if(!project->isEmpty("QMAKE_PRE_LINK")) if(!project->isEmpty("QMAKE_PRE_LINK"))
@ -695,9 +688,9 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
} }
} else { } else {
QString destdir = project->first("DESTDIR").toQString(); QString destdir = project->first("DESTDIR").toQString();
t << "all: " << escapeDependencyPath(deps) << " " << valGlue(escapeDependencyPaths(project->values("ALL_DEPS")),""," "," ") << destdir << "$(TARGET) " allDeps = ' ' + destdir + "$(TARGET)"
<< varGlue("QMAKE_AR_SUBLIBS", destdir, " " + destdir, "") << "\n\n" + varGlue("QMAKE_AR_SUBLIBS", ' ' + destdir, ' ' + destdir, "");
<< "staticlib: " << destdir << "$(TARGET)\n\n"; t << "staticlib: " << destdir << "$(TARGET)\n\n";
if(project->isEmpty("QMAKE_AR_SUBLIBS")) { if(project->isEmpty("QMAKE_AR_SUBLIBS")) {
t << destdir << "$(TARGET): " << var("PRE_TARGETDEPS") t << destdir << "$(TARGET): " << var("PRE_TARGETDEPS")
<< " $(OBJECTS) $(OBJCOMP) " << var("POST_TARGETDEPS") << "\n\t"; << " $(OBJECTS) $(OBJCOMP) " << var("POST_TARGETDEPS") << "\n\t";
@ -763,85 +756,111 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
<< "@$(QMAKE) -prl " << buildArgs() << " " << project->projectFile() << endl; << "@$(QMAKE) -prl " << buildArgs() << " " << project->projectFile() << endl;
} }
if(!project->first("QMAKE_PKGINFO").isEmpty()) { if (!project->isEmpty("QMAKE_BUNDLE")) {
ProString pkginfo = escapeFilePath(project->first("QMAKE_PKGINFO")); QHash<QString, QString> symlinks;
QString destdir = project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/Contents"; ProStringList &alldeps = project->values("ALL_DEPS");
t << pkginfo << ": \n\t"; QString bundle_dir = project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/";
if(!destdir.isEmpty()) if (!project->first("QMAKE_PKGINFO").isEmpty()) {
t << mkdir_p_asstring(destdir) << "\n\t"; ProString pkginfo = escapeFilePath(project->first("QMAKE_PKGINFO"));
t << "@$(DEL_FILE) " << pkginfo << "\n\t" bundledFiles << pkginfo;
<< "@echo \"APPL" alldeps << pkginfo;
<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) QString destdir = bundle_dir + "Contents";
<< "\" >" << pkginfo << endl; t << pkginfo << ": \n\t";
} if (!destdir.isEmpty())
if(!project->first("QMAKE_BUNDLE_RESOURCE_FILE").isEmpty()) { t << mkdir_p_asstring(destdir) << "\n\t";
ProString resources = escapeFilePath(project->first("QMAKE_BUNDLE_RESOURCE_FILE")); t << "@$(DEL_FILE) " << pkginfo << "\n\t"
bundledFiles << resources; << "@echo \"APPL"
QString destdir = project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/Contents/Resources"; << (project->isEmpty("QMAKE_PKGINFO_TYPEINFO")
t << resources << ": \n\t"; ? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4))
t << mkdir_p_asstring(destdir) << "\n\t"; << "\" >" << pkginfo << endl;
t << "@touch " << resources << "\n\t\n";
}
if(!project->isEmpty("QMAKE_BUNDLE")) {
//copy the plist
QString info_plist = escapeFilePath(fileFixify(project->first("QMAKE_INFO_PLIST").toQString())),
info_plist_out = escapeFilePath(project->first("QMAKE_INFO_PLIST_OUT").toQString());
if (info_plist.isEmpty())
info_plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE");
bundledFiles << info_plist_out;
QString destdir = info_plist_out.section(Option::dir_sep, 0, -2);
t << info_plist_out << ": \n\t";
if(!destdir.isEmpty())
t << mkdir_p_asstring(destdir, false) << "\n\t";
ProStringList commonSedArgs;
if (!project->values("VERSION").isEmpty())
commonSedArgs << "-e \"s,@SHORT_VERSION@," << project->first("VER_MAJ") << "." << project->first("VER_MIN") << ",g\" ";
commonSedArgs << "-e \"s,@TYPEINFO@,"<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ?
QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" ";
if(project->first("TEMPLATE") == "app") {
QString icon = fileFixify(var("ICON"));
QString bundlePrefix = project->first("QMAKE_TARGET_BUNDLE_PREFIX").toQString();
if (bundlePrefix.isEmpty())
bundlePrefix = "com.yourcompany";
if (bundlePrefix.endsWith("."))
bundlePrefix.chop(1);
QString bundleIdentifier = bundlePrefix + "." + var("QMAKE_BUNDLE");
if (bundleIdentifier.endsWith(".app"))
bundleIdentifier.chop(4);
t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
<< "@sed ";
foreach (const ProString &arg, commonSedArgs)
t << arg;
t << "-e \"s,@ICON@," << icon.section(Option::dir_sep, -1) << ",g\" "
<< "-e \"s,@BUNDLEIDENTIFIER@," << bundleIdentifier << ",g\" "
<< "-e \"s,@EXECUTABLE@," << var("QMAKE_ORIG_TARGET") << ",g\" "
<< "-e \"s,@TYPEINFO@,"<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ?
QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" "
<< "" << info_plist << " >" << info_plist_out << endl;
//copy the icon
if(!project->isEmpty("ICON")) {
QString dir = project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/Contents/Resources/";
const QString icon_path = escapeFilePath(dir + icon.section(Option::dir_sep, -1));
bundledFiles << icon_path;
t << icon_path << ": " << icon << "\n\t"
<< mkdir_p_asstring(dir) << "\n\t"
<< "@$(DEL_FILE) " << icon_path << "\n\t"
<< "@$(COPY_FILE) " << escapeFilePath(icon) << " " << icon_path << endl;
}
} else {
t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
<< "@sed ";
foreach (const ProString &arg, commonSedArgs)
t << arg;
t << "-e \"s,@LIBRARY@," << var("QMAKE_ORIG_TARGET") << ",g\" "
<< "-e \"s,@TYPEINFO@,"
<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ?
QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" "
<< "" << info_plist << " >" << info_plist_out << endl;
} }
if (!project->first("QMAKE_BUNDLE_RESOURCE_FILE").isEmpty()) {
ProString resources = escapeFilePath(project->first("QMAKE_BUNDLE_RESOURCE_FILE"));
bundledFiles << resources;
alldeps << resources;
QString destdir = bundle_dir + "Contents/Resources";
t << resources << ": \n\t";
t << mkdir_p_asstring(destdir) << "\n\t";
t << "@touch " << resources << "\n\t\n";
}
//copy the plist
while (!project->isActiveConfig("no_plist")) { // 'while' just to be able to 'break'
QString info_plist = escapeFilePath(fileFixify(project->first("QMAKE_INFO_PLIST").toQString()));
if (info_plist.isEmpty())
info_plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE");
if (!exists(Option::fixPathToLocalOS(info_plist))) {
warn_msg(WarnLogic, "Could not resolve Info.plist: '%s'. Check if QMAKE_INFO_PLIST points to a valid file.",
info_plist.toLatin1().constData());
break;
}
bool isApp = (project->first("TEMPLATE") == "app");
QString info_plist_out = escapeFilePath(
bundle_dir + (isApp ? "Contents/Info.plist"
: "Versions/" + project->first("QMAKE_FRAMEWORK_VERSION")
+ "/Resources/Info.plist"));
bundledFiles << info_plist_out;
alldeps << info_plist_out;
QString destdir = info_plist_out.section(Option::dir_sep, 0, -2);
t << info_plist_out << ": \n\t";
if (!destdir.isEmpty())
t << mkdir_p_asstring(destdir, false) << "\n\t";
ProStringList commonSedArgs;
if (!project->values("VERSION").isEmpty()) {
commonSedArgs << "-e \"s,@SHORT_VERSION@," << project->first("VER_MAJ") << "."
<< project->first("VER_MIN") << ",g\" ";
commonSedArgs << "-e \"s,@FULL_VERSION@," << project->first("VER_MAJ") << "."
<< project->first("VER_MIN") << "."
<< project->first("VER_PAT") << ",g\" ";
}
commonSedArgs << "-e \"s,@TYPEINFO@,"<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ?
QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" ";
if (isApp) {
QString icon = fileFixify(var("ICON"));
QString bundlePrefix = project->first("QMAKE_TARGET_BUNDLE_PREFIX").toQString();
if (bundlePrefix.isEmpty())
bundlePrefix = "com.yourcompany";
if (bundlePrefix.endsWith("."))
bundlePrefix.chop(1);
QString bundleIdentifier = bundlePrefix + "." + var("QMAKE_BUNDLE");
if (bundleIdentifier.endsWith(".app"))
bundleIdentifier.chop(4);
t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
<< "@sed ";
foreach (const ProString &arg, commonSedArgs)
t << arg;
t << "-e \"s,@ICON@," << icon.section(Option::dir_sep, -1) << ",g\" "
<< "-e \"s,@BUNDLEIDENTIFIER@," << bundleIdentifier << ",g\" "
<< "-e \"s,@EXECUTABLE@," << var("QMAKE_ORIG_TARGET") << ",g\" "
<< "-e \"s,@TYPEINFO@,"<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ?
QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" "
<< "" << info_plist << " >" << info_plist_out << endl;
//copy the icon
if (!project->isEmpty("ICON")) {
QString dir = bundle_dir + "Contents/Resources/";
const QString icon_path = escapeFilePath(dir + icon.section(Option::dir_sep, -1));
bundledFiles << icon_path;
alldeps << icon_path;
t << icon_path << ": " << icon << "\n\t"
<< mkdir_p_asstring(dir) << "\n\t"
<< "@$(DEL_FILE) " << icon_path << "\n\t"
<< "@$(COPY_FILE) " << escapeFilePath(icon) << " " << icon_path << endl;
}
} else {
symlinks[bundle_dir + "Resources"] = "Versions/Current/Resources";
t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
<< "@sed ";
foreach (const ProString &arg, commonSedArgs)
t << arg;
t << "-e \"s,@LIBRARY@," << var("QMAKE_ORIG_TARGET") << ",g\" "
<< "-e \"s,@TYPEINFO@,"
<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ?
QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" "
<< "" << info_plist << " >" << info_plist_out << endl;
}
break;
} // project->isActiveConfig("no_plist")
//copy other data //copy other data
if(!project->isEmpty("QMAKE_BUNDLE_DATA")) { if(!project->isEmpty("QMAKE_BUNDLE_DATA")) {
QString bundle_dir = project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/";
const ProStringList &bundle_data = project->values("QMAKE_BUNDLE_DATA"); const ProStringList &bundle_data = project->values("QMAKE_BUNDLE_DATA");
for(int i = 0; i < bundle_data.count(); i++) { for(int i = 0; i < bundle_data.count(); i++) {
const ProStringList &files = project->values(ProKey(bundle_data[i] + ".files")); const ProStringList &files = project->values(ProKey(bundle_data[i] + ".files"));
@ -851,11 +870,12 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
if (!project->isEmpty(vkey)) { if (!project->isEmpty(vkey)) {
QString version = project->first(vkey) + "/" + QString version = project->first(vkey) + "/" +
project->first("QMAKE_FRAMEWORK_VERSION") + "/"; project->first("QMAKE_FRAMEWORK_VERSION") + "/";
QString link = Option::fixPathToLocalOS(path + project->first(pkey)); ProString name = project->first(pkey);
bundledFiles << link; int pos = name.indexOf('/');
t << link << ": \n\t" if (pos > 0)
<< mkdir_p_asstring(path) << "\n\t" name = name.mid(0, pos);
<< "@$(SYMLINK) " << version << project->first(pkey) << " " << path << endl; symlinks[Option::fixPathToLocalOS(path + name)] =
project->first(vkey) + "/Current/" + name;
path += version; path += version;
} }
path += project->first(pkey).toQString(); path += project->first(pkey).toQString();
@ -868,6 +888,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
src = escapeFilePath(src); src = escapeFilePath(src);
const QString dst = escapeFilePath(path + Option::dir_sep + fileInfo(fn).fileName()); const QString dst = escapeFilePath(path + Option::dir_sep + fileInfo(fn).fileName());
bundledFiles << dst; bundledFiles << dst;
alldeps << dst;
t << dst << ": " << src << "\n\t" t << dst << ": " << src << "\n\t"
<< mkdir_p_asstring(path) << "\n\t"; << mkdir_p_asstring(path) << "\n\t";
QFileInfo fi(fileInfo(fn)); QFileInfo fi(fileInfo(fn));
@ -880,8 +901,21 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
} }
} }
} }
QHash<QString, QString>::ConstIterator symIt = symlinks.constBegin(),
symEnd = symlinks.constEnd();
for (; symIt != symEnd; ++symIt) {
bundledFiles << symIt.key();
alldeps << symIt.key();
t << symIt.key() << ":\n\t"
<< mkdir_p_asstring(bundle_dir) << "\n\t"
<< "@$(SYMLINK) " << symIt.value() << " " << bundle_dir << endl;
}
} }
t << endl << "all: " << escapeDependencyPath(deps)
<< valGlue(escapeDependencyPaths(project->values("ALL_DEPS")), " \\\n\t\t", " \\\n\t\t", "")
<< allDeps << endl << endl;
t << "dist: distdir FORCE\n\t"; t << "dist: distdir FORCE\n\t";
t << "(cd `dirname $(DISTDIR)` && $(TAR) $(DISTNAME).tar $(DISTNAME) && $(COMPRESS) $(DISTNAME).tar)" t << "(cd `dirname $(DISTDIR)` && $(TAR) $(DISTNAME).tar $(DISTNAME) && $(COMPRESS) $(DISTNAME).tar)"
" && $(MOVE) `dirname $(DISTDIR)`" << Option::dir_sep << "$(DISTNAME).tar.gz ." " && $(MOVE) `dirname $(DISTDIR)`" << Option::dir_sep << "$(DISTNAME).tar.gz ."
@ -1315,44 +1349,6 @@ void UnixMakefileGenerator::init2()
project->values("QMAKE_CFLAGS") += MD_flag; project->values("QMAKE_CFLAGS") += MD_flag;
project->values("QMAKE_CXXFLAGS") += MD_flag; project->values("QMAKE_CXXFLAGS") += MD_flag;
} }
if(!project->isEmpty("QMAKE_BUNDLE")) {
QString plist = fileFixify(project->first("QMAKE_INFO_PLIST").toQString(), qmake_getpwd());
if(plist.isEmpty())
plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE");
if(exists(Option::fixPathToLocalOS(plist))) {
project->values("QMAKE_INFO_PLIST_OUT").append(project->first("DESTDIR") +
project->first("QMAKE_BUNDLE") +
"/Contents/Info.plist");
project->values("ALL_DEPS") += project->first("QMAKE_INFO_PLIST_OUT");
if(!project->isEmpty("ICON") && project->first("TEMPLATE") == "app")
project->values("ALL_DEPS") += project->first("DESTDIR") +
project->first("QMAKE_BUNDLE") +
"/Contents/Resources/" + project->first("ICON").toQString().section('/', -1);
if(!project->isEmpty("QMAKE_BUNDLE_DATA")) {
QString bundle_dir = project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/";
ProStringList &alldeps = project->values("ALL_DEPS");
const ProStringList &bundle_data = project->values("QMAKE_BUNDLE_DATA");
for(int i = 0; i < bundle_data.count(); i++) {
const ProStringList &files = project->values(ProKey(bundle_data[i] + ".files"));
QString path = bundle_dir;
const ProKey vkey(bundle_data[i] + ".version");
const ProKey pkey(bundle_data[i] + ".path");
if (!project->isEmpty(vkey)) {
alldeps += Option::fixPathToLocalOS(path + Option::dir_sep + project->first(pkey));
path += project->first(vkey) + "/" +
project->first("QMAKE_FRAMEWORK_VERSION") + "/";
}
path += project->first(pkey);
path = Option::fixPathToLocalOS(path);
for(int file = 0; file < files.count(); file++)
alldeps += path + Option::dir_sep + fileInfo(files[file].toQString()).fileName();
}
}
} else {
warn_msg(WarnLogic, "Could not resolve Info.plist: '%s'. Check if QMAKE_INFO_PLIST points to a valid file.", plist.toLatin1().constData());
}
}
} }
QString QString

View File

@ -174,3 +174,10 @@ a[0] = 1; a[1] = 0; a[2] = 1; // a: [ 1, 0, 1 ]
b[0] = 1; b[1] = 1; // b: [ 1, 1 ] b[0] = 1; b[1] = 1; // b: [ 1, 1 ]
c = a ^ b; // c: [ 0, 1, 1 ] c = a ^ b; // c: [ 0, 1, 1 ]
//! [14] //! [14]
//! [15]
QBitArray ba(4);
ba.fill(true, 1, 2); // ba: [ 0, 1, 0, 0 ]
ba.fill(true, 1, 3); // ba: [ 0, 1, 1, 0 ]
ba.fill(true, 1, 4); // ba: [ 0, 1, 1, 1 ]
//! [15]

View File

@ -282,11 +282,18 @@ void QBitArray::resize(int size)
/*! /*!
\overload \overload
Sets bits at index positions \a begin up to and excluding \a end Sets bits at index positions \a begin up to (but not including) \a end
to \a value. to \a value.
\a begin and \a end must be a valid index position in the bit \a begin must be a valid index position in the bit array
array (i.e., 0 <= \a begin <= size() and 0 <= \a end <= size()). (0 <= \a begin < size()).
\a end must be either a valid index position or equal to size(), in
which case the fill operation runs until the end of the array
(0 <= \a end <= size()).
Example:
\snippet code/src_corelib_tools_qbitarray.cpp 15
*/ */
void QBitArray::fill(bool value, int begin, int end) void QBitArray::fill(bool value, int begin, int end)

View File

@ -159,8 +159,8 @@ Q_STATIC_ASSERT_X(sizeof(qunicodechar) == 2,
Q_STATIC_STRING_DATA_HEADER_INITIALIZER(Size), \ Q_STATIC_STRING_DATA_HEADER_INITIALIZER(Size), \
QT_UNICODE_LITERAL(str) }; \ QT_UNICODE_LITERAL(str) }; \
QStringDataPtr holder = { qstring_literal.data_ptr() }; \ QStringDataPtr holder = { qstring_literal.data_ptr() }; \
const QString s(holder); \ const QString qstring_literal_temp(holder); \
return s; \ return qstring_literal_temp; \
}()) \ }()) \
/**/ /**/

View File

@ -86,6 +86,10 @@ public:
QList<QCocoaMenuItem *> merged() const; QList<QCocoaMenuItem *> merged() const;
void setMenuBar(QCocoaMenuBar *menuBar); void setMenuBar(QCocoaMenuBar *menuBar);
QCocoaMenuBar *menuBar() const; QCocoaMenuBar *menuBar() const;
void setContainingMenuItem(QCocoaMenuItem *menuItem);
QCocoaMenuItem *containingMenuItem() const;
private: private:
QCocoaMenuItem *itemOrNull(int index) const; QCocoaMenuItem *itemOrNull(int index) const;
void insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem); void insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem);
@ -98,6 +102,7 @@ private:
bool m_visible; bool m_visible;
quintptr m_tag; quintptr m_tag;
QCocoaMenuBar *m_menuBar; QCocoaMenuBar *m_menuBar;
QCocoaMenuItem *m_containingMenuItem;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -222,7 +222,8 @@ QCocoaMenu::QCocoaMenu() :
m_enabled(true), m_enabled(true),
m_visible(true), m_visible(true),
m_tag(0), m_tag(0),
m_menuBar(0) m_menuBar(0),
m_containingMenuItem(0)
{ {
m_delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this]; m_delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this];
m_nativeItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; m_nativeItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
@ -238,6 +239,10 @@ QCocoaMenu::~QCocoaMenu()
if (COCOA_MENU_ANCESTOR(item) == this) if (COCOA_MENU_ANCESTOR(item) == this)
SET_COCOA_MENU_ANCESTOR(item, 0); SET_COCOA_MENU_ANCESTOR(item, 0);
} }
if (m_containingMenuItem)
m_containingMenuItem->clearMenu(this);
QCocoaAutoReleasePool pool; QCocoaAutoReleasePool pool;
[m_nativeItem setSubmenu:nil]; [m_nativeItem setSubmenu:nil];
[m_nativeMenu release]; [m_nativeMenu release];
@ -568,4 +573,14 @@ QCocoaMenuBar *QCocoaMenu::menuBar() const
return m_menuBar; return m_menuBar;
} }
void QCocoaMenu::setContainingMenuItem(QCocoaMenuItem *menuItem)
{
m_containingMenuItem = menuItem;
}
QCocoaMenuItem *QCocoaMenu::containingMenuItem() const
{
return m_containingMenuItem;
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -94,6 +94,7 @@ public:
inline bool isSeparator() const { return m_isSeparator; } inline bool isSeparator() const { return m_isSeparator; }
QCocoaMenu *menu() const { return m_menu; } QCocoaMenu *menu() const { return m_menu; }
void clearMenu(QCocoaMenu *menu);
MenuRole effectiveRole() const; MenuRole effectiveRole() const;
private: private:

View File

@ -132,13 +132,19 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
{ {
if (menu == m_menu) if (menu == m_menu)
return; return;
if (m_menu && COCOA_MENU_ANCESTOR(m_menu) == this)
SET_COCOA_MENU_ANCESTOR(m_menu, 0); if (m_menu) {
if (COCOA_MENU_ANCESTOR(m_menu) == this)
SET_COCOA_MENU_ANCESTOR(m_menu, 0);
if (m_menu->containingMenuItem() == this)
m_menu->setContainingMenuItem(0);
}
QCocoaAutoReleasePool pool; QCocoaAutoReleasePool pool;
m_menu = static_cast<QCocoaMenu *>(menu); m_menu = static_cast<QCocoaMenu *>(menu);
if (m_menu) { if (m_menu) {
SET_COCOA_MENU_ANCESTOR(m_menu, this); SET_COCOA_MENU_ANCESTOR(m_menu, this);
m_menu->setContainingMenuItem(this);
} else { } else {
// we previously had a menu, but no longer // we previously had a menu, but no longer
// clear out our item so the nexy sync() call builds a new one // clear out our item so the nexy sync() call builds a new one
@ -147,6 +153,12 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
} }
} }
void QCocoaMenuItem::clearMenu(QCocoaMenu *menu)
{
if (menu == m_menu)
m_menu = 0;
}
void QCocoaMenuItem::setVisible(bool isVisible) void QCocoaMenuItem::setVisible(bool isVisible)
{ {
m_isVisible = isVisible; m_isVisible = isVisible;

View File

@ -151,7 +151,7 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
// An event has to be associated with a window, // An event has to be associated with a window,
// so find the first parent that is a widget and that has a WId // so find the first parent that is a widget and that has a WId
QAccessibleInterface *iface = event->accessibleInterface(); QAccessibleInterface *iface = event->accessibleInterface();
if (!iface) // ### This should not happen, maybe make it an assert. if (!iface || !iface->isValid())
return; return;
QWindow *window = QWindowsAccessibility::windowHelper(iface); QWindow *window = QWindowsAccessibility::windowHelper(iface);

View File

@ -93,6 +93,7 @@
#include <qmath.h> #include <qmath.h>
#include <QtWidgets/qgraphicsproxywidget.h> #include <QtWidgets/qgraphicsproxywidget.h>
#include <QtWidgets/qgraphicsview.h> #include <QtWidgets/qgraphicsview.h>
#include <QtCore/qvariant.h>
#include <private/qstylehelper_p.h> #include <private/qstylehelper_p.h>
#include <private/qstyleanimation_p.h> #include <private/qstyleanimation_p.h>
#include <qpa/qplatformfontdatabase.h> #include <qpa/qplatformfontdatabase.h>
@ -1728,7 +1729,7 @@ QMacStylePrivate::QMacStylePrivate()
QMacStylePrivate::~QMacStylePrivate() QMacStylePrivate::~QMacStylePrivate()
{ {
Q_FOREACH (NSView *b, buttons) Q_FOREACH (NSView *b, cocoaControls)
[b release]; [b release];
} }
@ -1749,43 +1750,92 @@ ThemeDrawState QMacStylePrivate::getDrawState(QStyle::State flags)
return tds; return tds;
} }
NSView *QMacStylePrivate::buttonOfKind(ThemeButtonKind kind, QPoint *offset) const static QCocoaWidget cocoaWidgetFromHIThemeButtonKind(ThemeButtonKind kind)
{ {
NSView *bv = buttons[kind]; QCocoaWidget w;
switch (kind) {
case kThemePopupButton:
case kThemePopupButtonSmall:
case kThemePopupButtonMini:
w.first = QCocoaPopupButton;
break;
case kThemeComboBox:
w.first = QCocoaComboBox;
break;
case kThemeArrowButton:
w.first = QCocoaArrowButton;
break;
case kThemeCheckBox:
case kThemeCheckBoxSmall:
case kThemeCheckBoxMini:
w.first = QCocoaCheckBox;
break;
case kThemeRadioButton:
case kThemeRadioButtonSmall:
case kThemeRadioButtonMini:
w.first = QCocoaRadioButton;
break;
case kThemePushButton:
case kThemePushButtonSmall:
case kThemePushButtonMini:
w.first = QCocoaPushButton;
break;
default:
break;
}
switch (kind) {
case kThemePushButtonSmall:
case kThemePopupButtonSmall:
case kThemeCheckBoxSmall:
case kThemeRadioButtonSmall:
w.second = QAquaSizeSmall;
break;
case kThemePushButtonMini:
case kThemePopupButtonMini:
case kThemeCheckBoxMini:
case kThemeRadioButtonMini:
w.second = QAquaSizeMini;
break;
default:
w.second = QAquaSizeLarge;
break;
}
return w;
}
NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget, QPoint *offset) const
{
NSView *bv = cocoaControls[widget];
if (!bv) { if (!bv) {
if (kind == kThemePopupButton
|| kind == kThemePopupButtonSmall if (widget.first == QCocoaPopupButton)
|| kind == kThemePopupButtonMini)
bv = [[NSPopUpButton alloc] init]; bv = [[NSPopUpButton alloc] init];
else if (kind == kThemeComboBox) else if (widget.first == QCocoaComboBox)
bv = [[NSComboBox alloc] init]; bv = [[NSComboBox alloc] init];
else else
bv = [[NSButton alloc] init]; bv = [[NSButton alloc] init];
switch (kind) { switch (widget.first) {
case kThemeArrowButton: { case QCocoaArrowButton: {
NSButton *bc = (NSButton *)bv; NSButton *bc = (NSButton *)bv;
bc.buttonType = NSOnOffButton; bc.buttonType = NSOnOffButton;
bc.bezelStyle = NSDisclosureBezelStyle; bc.bezelStyle = NSDisclosureBezelStyle;
break; break;
} }
case kThemeCheckBox: case QCocoaCheckBox: {
case kThemeCheckBoxSmall:
case kThemeCheckBoxMini: {
NSButton *bc = (NSButton *)bv; NSButton *bc = (NSButton *)bv;
bc.buttonType = NSSwitchButton; bc.buttonType = NSSwitchButton;
break; break;
} }
case kThemeRadioButton: case QCocoaRadioButton: {
case kThemeRadioButtonSmall:
case kThemeRadioButtonMini: {
NSButton *bc = (NSButton *)bv; NSButton *bc = (NSButton *)bv;
bc.buttonType = NSRadioButton; bc.buttonType = NSRadioButton;
break; break;
} }
case kThemePushButton: case QCocoaPushButton: {
case kThemePushButtonSmall:
case kThemePushButtonMini: {
NSButton *bc = (NSButton *)bv; NSButton *bc = (NSButton *)bv;
bc.buttonType = NSMomentaryPushButton; bc.buttonType = NSMomentaryPushButton;
bc.bezelStyle = NSRoundedBezelStyle; bc.bezelStyle = NSRoundedBezelStyle;
@ -1798,19 +1848,15 @@ NSView *QMacStylePrivate::buttonOfKind(ThemeButtonKind kind, QPoint *offset) con
if ([bv isKindOfClass:[NSButton class]]) { if ([bv isKindOfClass:[NSButton class]]) {
NSButton *bc = (NSButton *)bv; NSButton *bc = (NSButton *)bv;
bc.title = nil; bc.title = nil;
}
NSCell *bcell = bc.cell; if ([bv isKindOfClass:[NSControl class]]) {
switch (kind) { NSCell *bcell = [(NSControl *)bv cell];
case kThemePushButtonSmall: switch (widget.second) {
case kThemePopupButtonSmall: case QAquaSizeSmall:
case kThemeCheckBoxSmall:
case kThemeRadioButtonSmall:
bcell.controlSize = NSSmallControlSize; bcell.controlSize = NSSmallControlSize;
break; break;
case kThemePushButtonMini: case QAquaSizeMini:
case kThemePopupButtonMini:
case kThemeCheckBoxMini:
case kThemeRadioButtonMini:
bcell.controlSize = NSMiniControlSize; bcell.controlSize = NSMiniControlSize;
break; break;
default: default:
@ -1818,36 +1864,25 @@ NSView *QMacStylePrivate::buttonOfKind(ThemeButtonKind kind, QPoint *offset) con
} }
} }
const_cast<QMacStylePrivate *>(this)->buttons.insert(kind, bv); const_cast<QMacStylePrivate *>(this)->cocoaControls.insert(widget, bv);
} }
if (offset) { if (offset) {
switch (kind) { if (widget == QCocoaWidget(QCocoaRadioButton, QAquaSizeLarge))
case kThemeRadioButton:
offset->setY(2); offset->setY(2);
break; else if (widget == QCocoaWidget(QCocoaRadioButton, QAquaSizeSmall))
case kThemeRadioButtonSmall:
*offset = QPoint(-1, 2); *offset = QPoint(-1, 2);
break; else if (widget == QCocoaWidget(QCocoaRadioButton, QAquaSizeMini))
case kThemeRadioButtonMini:
offset->setY(2); offset->setY(2);
break; else if (widget == QCocoaWidget(QCocoaPopupButton, QAquaSizeSmall)
case kThemePopupButtonSmall: || widget == QCocoaWidget(QCocoaCheckBox, QAquaSizeLarge))
case kThemeCheckBox:
offset->setY(1); offset->setY(1);
break; else if (widget == QCocoaWidget(QCocoaCheckBox, QAquaSizeSmall))
case kThemeCheckBoxSmall:
offset->setX(-1); offset->setX(-1);
break; else if (widget == QCocoaWidget(QCocoaCheckBox, QAquaSizeMini))
case kThemeCheckBoxMini:
*offset = QPoint(7, 5); *offset = QPoint(7, 5);
break; else if (widget == QCocoaWidget(QCocoaPopupButton, QAquaSizeMini))
case kThemePopupButtonMini:
*offset = QPoint(2, -1); *offset = QPoint(2, -1);
break;
default:
break;
}
} }
return bv; return bv;
@ -1967,7 +2002,7 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD
pm = QPixmap::fromImage(image); pm = QPixmap::fromImage(image);
} else if ((usingYosemiteOrLater && combo && !editableCombo) || button) { } else if ((usingYosemiteOrLater && combo && !editableCombo) || button) {
QPoint offset; QPoint offset;
NSButton *bc = (NSButton *)buttonOfKind(bdi->kind, &offset); NSButton *bc = (NSButton *)cocoaControl(cocoaWidgetFromHIThemeButtonKind(bdi->kind), &offset);
[bc highlight:pressed]; [bc highlight:pressed];
bc.enabled = bdi->state != kThemeStateUnavailable && bdi->state != kThemeStateUnavailableInactive; bc.enabled = bdi->state != kThemeStateUnavailable && bdi->state != kThemeStateUnavailableInactive;
bc.allowsMixedState = YES; bc.allowsMixedState = YES;
@ -5792,7 +5827,25 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
drawToolbarButtonArrow(tb->rect, tds, cg); drawToolbarButtonArrow(tb->rect, tds, cg);
} }
if (tb->state & State_On) { if (tb->state & State_On) {
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { if (QSysInfo::MacintoshVersion > QSysInfo::MV_MAVERICKS) {
QWindow *window = 0;
if (widget && widget->window())
window = widget->window()->windowHandle();
else if (opt->styleObject)
window = opt->styleObject->property("_q_styleObjectWindow").value<QWindow *>();
NSView *view = window ? (NSView *)window->winId() : nil;
bool isKey = false;
if (view)
isKey = [view.window isKeyWindow];
QBrush brush(isKey ? QColor(0, 0, 0, 28)
: QColor(0, 0, 0, 21));
QPainterPath path;
path.addRoundedRect(QRectF(tb->rect.x(), tb->rect.y(), tb->rect.width(), tb->rect.height() + 4), 4, 4);
p->setRenderHint(QPainter::Antialiasing);
p->fillPath(path, brush);
} else if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
static QPixmap pm(QLatin1String(":/qt-project.org/mac/style/images/leopard-unified-toolbar-on.png")); static QPixmap pm(QLatin1String(":/qt-project.org/mac/style/images/leopard-unified-toolbar-on.png"));
p->setRenderHint(QPainter::SmoothPixmapTransform); p->setRenderHint(QPainter::SmoothPixmapTransform);
QStyleHelper::drawBorderPixmap(pm, p, tb->rect, 2, 2, 2, 2); QStyleHelper::drawBorderPixmap(pm, p, tb->rect, 2, 2, 2, 2);

View File

@ -85,6 +85,7 @@
#include <qlibrary.h> #include <qlibrary.h>
#include <qdatetimeedit.h> #include <qdatetimeedit.h>
#include <qmath.h> #include <qmath.h>
#include <qpair.h>
#include <qset.h> #include <qset.h>
#include <QtWidgets/qgraphicsproxywidget.h> #include <QtWidgets/qgraphicsproxywidget.h>
#include <QtWidgets/qgraphicsview.h> #include <QtWidgets/qgraphicsview.h>
@ -120,6 +121,17 @@ QT_BEGIN_NAMESPACE
enum QAquaWidgetSize { QAquaSizeLarge = 0, QAquaSizeSmall = 1, QAquaSizeMini = 2, enum QAquaWidgetSize { QAquaSizeLarge = 0, QAquaSizeSmall = 1, QAquaSizeMini = 2,
QAquaSizeUnknown = -1 }; QAquaSizeUnknown = -1 };
enum QCocoaWidgetKind {
QCocoaArrowButton, // Disclosure triangle, like in QTreeView
QCocoaCheckBox,
QCocoaComboBox, // Editable QComboBox
QCocoaPopupButton, // Non-editable QComboBox
QCocoaPushButton,
QCocoaRadioButton
};
typedef QPair<QCocoaWidgetKind, QAquaWidgetSize> QCocoaWidget;
#define SIZE(large, small, mini) \ #define SIZE(large, small, mini) \
(controlSize == QAquaSizeLarge ? (large) : controlSize == QAquaSizeSmall ? (small) : (mini)) (controlSize == QAquaSizeLarge ? (large) : controlSize == QAquaSizeSmall ? (small) : (mini))
@ -187,7 +199,7 @@ public:
void setAutoDefaultButton(QObject *button) const; void setAutoDefaultButton(QObject *button) const;
NSView *buttonOfKind(ThemeButtonKind kind, QPoint *offset) const; NSView *cocoaControl(QCocoaWidget widget, QPoint *offset) const;
void drawNSViewInRect(NSView *view, const QRect &rect, QPainter *p) const; void drawNSViewInRect(NSView *view, const QRect &rect, QPainter *p) const;
void resolveCurrentNSView(QWindow *window); void resolveCurrentNSView(QWindow *window);
@ -211,7 +223,7 @@ public:
#endif #endif
void *indicatorBranchButtonCell; void *indicatorBranchButtonCell;
NSView *backingStoreNSView; NSView *backingStoreNSView;
QHash<ThemeButtonKind , NSView *> buttons; QHash<QCocoaWidget, NSView *> cocoaControls;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -281,7 +281,7 @@ void QPlainTextDocumentLayout::documentChanged(int from, int charsRemoved, int c
Q_D(QPlainTextDocumentLayout); Q_D(QPlainTextDocumentLayout);
QTextDocument *doc = document(); QTextDocument *doc = document();
int newBlockCount = doc->blockCount(); int newBlockCount = doc->blockCount();
int charsChanged = qMax(charsRemoved, charsAdded); int charsChanged = charsRemoved + charsAdded;
QTextBlock changeStartBlock = doc->findBlock(from); QTextBlock changeStartBlock = doc->findBlock(from);
QTextBlock changeEndBlock = doc->findBlock(qMax(0, from + charsChanged - 1)); QTextBlock changeEndBlock = doc->findBlock(qMax(0, from + charsChanged - 1));

View File

@ -147,6 +147,7 @@ private slots:
void findWithRegExpReturnsFalseIfNoMoreResults(); void findWithRegExpReturnsFalseIfNoMoreResults();
#endif #endif
void layoutAfterMultiLineRemove(); void layoutAfterMultiLineRemove();
void undoCommandRemovesAndReinsertsBlock();
private: private:
void createSelection(); void createSelection();
@ -1604,5 +1605,29 @@ void tst_QPlainTextEdit::layoutAfterMultiLineRemove()
QCOMPARE(curs.blockNumber(), 3); QCOMPARE(curs.blockNumber(), 3);
} }
void tst_QPlainTextEdit::undoCommandRemovesAndReinsertsBlock()
{
ed->setVisible(true);
ed->setPlainText(QStringLiteral("line1\nline2"));
QCOMPARE(ed->document()->blockCount(), 2);
QTextCursor cursor = ed->textCursor();
cursor.movePosition(QTextCursor::Start);
cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
cursor.insertText(QStringLiteral("\n"));
QCOMPARE(ed->document()->blockCount(), 2);
ed->undo();
QCOMPARE(ed->document()->blockCount(), 2);
QTextBlock block;
for (block = ed->document()->begin(); block != ed->document()->end(); block = block.next()) {
QVERIFY(block.isValid());
QCOMPARE(block.length(), 6);
QVERIFY(block.layout()->lineForTextPosition(0).isValid());
}
}
QTEST_MAIN(tst_QPlainTextEdit) QTEST_MAIN(tst_QPlainTextEdit)
#include "tst_qplaintextedit.moc" #include "tst_qplaintextedit.moc"