diff options
37 files changed, 372 insertions, 77 deletions
diff --git a/examples/designer/containerextension/containerextension.pro b/examples/designer/containerextension/containerextension.pro index b3e05d7f8..39b6dc2a2 100644 --- a/examples/designer/containerextension/containerextension.pro +++ b/examples/designer/containerextension/containerextension.pro @@ -3,6 +3,7 @@ QTDIR_build { PLUGIN_TYPE = designer PLUGIN_CLASS_NAME = MultiPageWidgetPlugin load(qt_plugin) +CONFIG += install_ok } else { # Public example: diff --git a/examples/designer/customwidgetplugin/customwidgetplugin.pro b/examples/designer/customwidgetplugin/customwidgetplugin.pro index 4c2c29843..1447acdc4 100644 --- a/examples/designer/customwidgetplugin/customwidgetplugin.pro +++ b/examples/designer/customwidgetplugin/customwidgetplugin.pro @@ -7,6 +7,7 @@ QTDIR_build { PLUGIN_TYPE = designer PLUGIN_CLASS_NAME = AnalogClockPlugin load(qt_plugin) +CONFIG += install_ok } else { # Public example: diff --git a/examples/designer/taskmenuextension/taskmenuextension.pro b/examples/designer/taskmenuextension/taskmenuextension.pro index 5cfebc015..71a3806d6 100644 --- a/examples/designer/taskmenuextension/taskmenuextension.pro +++ b/examples/designer/taskmenuextension/taskmenuextension.pro @@ -7,6 +7,7 @@ QTDIR_build { PLUGIN_TYPE = designer PLUGIN_CLASS_NAME = TicTacToePlugin load(qt_plugin) +CONFIG += install_ok } else { # Public example: diff --git a/examples/designer/worldtimeclockplugin/worldtimeclockplugin.pro b/examples/designer/worldtimeclockplugin/worldtimeclockplugin.pro index e8a2d2aab..b6332ce46 100644 --- a/examples/designer/worldtimeclockplugin/worldtimeclockplugin.pro +++ b/examples/designer/worldtimeclockplugin/worldtimeclockplugin.pro @@ -7,6 +7,7 @@ QTDIR_build { PLUGIN_TYPE = designer PLUGIN_CLASS_NAME = WorldTimeClockPlugin load(qt_plugin) +CONFIG += install_ok } else { # Public example: diff --git a/src/assistant/assistant/assistant.ico b/src/assistant/assistant/assistant.ico Binary files differindex f34505532..b821faaf2 100644 --- a/src/assistant/assistant/assistant.ico +++ b/src/assistant/assistant/assistant.ico diff --git a/src/assistant/assistant/doc/qtassistant.qdocconf b/src/assistant/assistant/doc/qtassistant.qdocconf index 01d4bf0c5..e5dcaa8ec 100644 --- a/src/assistant/assistant/doc/qtassistant.qdocconf +++ b/src/assistant/assistant/doc/qtassistant.qdocconf @@ -2,7 +2,7 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) project = QtAssistant description = Qt Assistant Manual -examplesinstallpath = qttools/assistant +examplesinstallpath = assistant qhp.projects = QtAssistant diff --git a/src/assistant/assistant/images/assistant-128.png b/src/assistant/assistant/images/assistant-128.png Binary files differindex 7b9f47477..a5d8fea1a 100644 --- a/src/assistant/assistant/images/assistant-128.png +++ b/src/assistant/assistant/images/assistant-128.png diff --git a/src/assistant/assistant/images/assistant.png b/src/assistant/assistant/images/assistant.png Binary files differindex 2d7c47744..e6d7312a8 100644 --- a/src/assistant/assistant/images/assistant.png +++ b/src/assistant/assistant/images/assistant.png diff --git a/src/assistant/help/doc/qthelp.qdocconf b/src/assistant/help/doc/qthelp.qdocconf index 90373996b..0b4223e93 100644 --- a/src/assistant/help/doc/qthelp.qdocconf +++ b/src/assistant/help/doc/qthelp.qdocconf @@ -4,7 +4,7 @@ project = QtHelp description = Qt Help Reference Documentation version = $QT_VERSION -examplesinstallpath = qttools/help +examplesinstallpath = help qhp.projects = QtHelp diff --git a/src/designer/src/components/objectinspector/objectinspector.cpp b/src/designer/src/components/objectinspector/objectinspector.cpp index b182a1485..324d7764e 100644 --- a/src/designer/src/components/objectinspector/objectinspector.cpp +++ b/src/designer/src/components/objectinspector/objectinspector.cpp @@ -63,7 +63,7 @@ #include <QtCore/QItemSelectionModel> #include <QtWidgets/QMenu> #include <QtWidgets/QTreeView> -#include <QtWidgets/QItemDelegate> +#include <QtWidgets/QStyledItemDelegate> #include <QtGui/qevent.h> #include <QtCore/QVector> @@ -119,7 +119,7 @@ static inline QPoint dropPointOffset(const qdesigner_internal::FormWindowBase *f namespace qdesigner_internal { // Delegate with object name validator for the object name column -class ObjectInspectorDelegate : public QItemDelegate { +class ObjectInspectorDelegate : public QStyledItemDelegate { public: explicit ObjectInspectorDelegate(QObject *parent = 0); @@ -127,14 +127,14 @@ public: }; ObjectInspectorDelegate::ObjectInspectorDelegate(QObject *parent) : - QItemDelegate(parent) + QStyledItemDelegate(parent) { } QWidget *ObjectInspectorDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & option, const QModelIndex &index) const { if (index.column() != ObjectInspectorModel::ObjectNameColumn) - return QItemDelegate::createEditor(parent, option, index); + return QStyledItemDelegate::createEditor(parent, option, index); // Object name editor const bool isMainContainer = !index.parent().isValid(); return new TextPropertyEditor(parent, TextPropertyEditor::EmbeddingTreeView, @@ -249,6 +249,7 @@ ObjectInspector::ObjectInspectorPrivate::ObjectInspectorPrivate(QDesignerFormEdi m_treeView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); m_treeView->header()->setSectionResizeMode(1, QHeaderView::Stretch); m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); + m_treeView->setSelectionBehavior(QAbstractItemView::SelectRows); m_treeView->setAlternatingRowColors(true); m_treeView->setTextElideMode (Qt::ElideMiddle); diff --git a/src/designer/src/designer/designer.ico b/src/designer/src/designer/designer.ico Binary files differindex 495e8d162..d9cd33f60 100644 --- a/src/designer/src/designer/designer.ico +++ b/src/designer/src/designer/designer.ico diff --git a/src/designer/src/designer/doc/qtdesigner.qdocconf b/src/designer/src/designer/doc/qtdesigner.qdocconf index ed897f76b..cc0d881aa 100644 --- a/src/designer/src/designer/doc/qtdesigner.qdocconf +++ b/src/designer/src/designer/doc/qtdesigner.qdocconf @@ -2,7 +2,7 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) project = QtDesigner description = Qt Designer Manual -examplesinstallpath = qttools/designer +examplesinstallpath = designer qhp.projects = QtDesigner diff --git a/src/designer/src/designer/images/designer.png b/src/designer/src/designer/images/designer.png Binary files differindex 15086cb70..9f8578b49 100644 --- a/src/designer/src/designer/images/designer.png +++ b/src/designer/src/designer/images/designer.png diff --git a/src/designer/src/lib/shared/qdesigner_promotion.cpp b/src/designer/src/lib/shared/qdesigner_promotion.cpp index 63d54b45c..dba920565 100644 --- a/src/designer/src/lib/shared/qdesigner_promotion.cpp +++ b/src/designer/src/lib/shared/qdesigner_promotion.cpp @@ -290,6 +290,23 @@ namespace qdesigner_internal { *errorMessage = QCoreApplication::tr("The class %1 cannot be removed because it is still referenced.").arg(className); return false; } + // QTBUG-52963: Check for classes that specify the to-be-removed class as + // base class of a promoted class. This should not happen in the normal case + // as promoted classes cannot serve as base for further promotion. It is possible + // though if a class provided by a plugin (say Qt WebKit's QWebView) is used as + // a base class for a promoted widget B and the plugin is removed in the next + // launch. QWebView will then appear as promoted class itself and the promoted + // class B will depend on it. When removing QWebView, the base class of B will + // be changed to that of QWebView by the below code. + const PromotedClasses promotedList = promotedClasses(); + for (PromotedClasses::const_iterator it = promotedList.constBegin(), end = promotedList.constEnd(); it != end; ++it) { + if (it->baseItem->name() == className) { + const QString extends = widgetDataBase->item(index)->extends(); + qWarning().nospace() << "Warning: Promoted class " << it->promotedItem->name() + << " extends " << className << ", changing its base class to " << extends << '.'; + it->promotedItem->setExtends(extends); + } + } widgetDataBase->remove(index); return true; } diff --git a/src/designer/src/uitools/doc/qtuitools.qdocconf b/src/designer/src/uitools/doc/qtuitools.qdocconf index f5abc19d1..b3306ce59 100644 --- a/src/designer/src/uitools/doc/qtuitools.qdocconf +++ b/src/designer/src/uitools/doc/qtuitools.qdocconf @@ -4,7 +4,7 @@ project = QtUiTools description = Qt UI Tools Reference Documentation version = $QT_VERSION -examplesinstallpath = qttools/uitools +examplesinstallpath = uitools qhp.projects = QtUiTools diff --git a/src/linguist/linguist/doc/qtlinguist.qdocconf b/src/linguist/linguist/doc/qtlinguist.qdocconf index b5a347916..db0558233 100644 --- a/src/linguist/linguist/doc/qtlinguist.qdocconf +++ b/src/linguist/linguist/doc/qtlinguist.qdocconf @@ -2,7 +2,7 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) project = QtLinguist description = Qt Linguist Manual -examplesinstallpath = qttools/linguist +examplesinstallpath = linguist qhp.projects = QtLinguist diff --git a/src/linguist/linguist/images/appicon.png b/src/linguist/linguist/images/appicon.png Binary files differindex 6aa09fb7a..748b07810 100644 --- a/src/linguist/linguist/images/appicon.png +++ b/src/linguist/linguist/images/appicon.png diff --git a/src/linguist/linguist/images/icons/linguist-128-32.png b/src/linguist/linguist/images/icons/linguist-128-32.png Binary files differindex e9a44cbef..4deebc24f 100644 --- a/src/linguist/linguist/images/icons/linguist-128-32.png +++ b/src/linguist/linguist/images/icons/linguist-128-32.png diff --git a/src/linguist/linguist/images/icons/linguist-16-32.png b/src/linguist/linguist/images/icons/linguist-16-32.png Binary files differindex 111b910b0..eed9bc076 100644 --- a/src/linguist/linguist/images/icons/linguist-16-32.png +++ b/src/linguist/linguist/images/icons/linguist-16-32.png diff --git a/src/linguist/linguist/images/icons/linguist-32-32.png b/src/linguist/linguist/images/icons/linguist-32-32.png Binary files differindex 6aa09fb7a..de976ccd3 100644 --- a/src/linguist/linguist/images/icons/linguist-32-32.png +++ b/src/linguist/linguist/images/icons/linguist-32-32.png diff --git a/src/linguist/linguist/images/icons/linguist-48-32.png b/src/linguist/linguist/images/icons/linguist-48-32.png Binary files differindex b7e344485..9b429c8b2 100644 --- a/src/linguist/linguist/images/icons/linguist-48-32.png +++ b/src/linguist/linguist/images/icons/linguist-48-32.png diff --git a/src/linguist/linguist/images/icons/linguist-64-32.png b/src/linguist/linguist/images/icons/linguist-64-32.png Binary files differindex 6ea58ff42..41981b645 100644 --- a/src/linguist/linguist/images/icons/linguist-64-32.png +++ b/src/linguist/linguist/images/icons/linguist-64-32.png diff --git a/src/linguist/linguist/images/splash.png b/src/linguist/linguist/images/splash.png Binary files differindex baaed6181..5824fb76c 100644 --- a/src/linguist/linguist/images/splash.png +++ b/src/linguist/linguist/images/splash.png diff --git a/src/linguist/linguist/linguist.ico b/src/linguist/linguist/linguist.ico Binary files differindex 48cd31a17..9c79249f2 100644 --- a/src/linguist/linguist/linguist.ico +++ b/src/linguist/linguist/linguist.ico diff --git a/src/linguist/lupdate/cpp.cpp b/src/linguist/lupdate/cpp.cpp index bf6d86de8..02a667320 100644 --- a/src/linguist/lupdate/cpp.cpp +++ b/src/linguist/lupdate/cpp.cpp @@ -1757,6 +1757,7 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac QString functionName; #endif bool yyTokColonSeen = false; // Start of c'tor's initializer list + bool yyTokIdentSeen = false; // Start of initializer (member or base class) metaExpected = true; prospectiveContext.clear(); @@ -1978,6 +1979,11 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac yyTok = getToken(); break; case Tok_Ident: + if (yyTokColonSeen && + yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0) { + // member or base class identifier + yyTokIdentSeen = true; + } yyTok = getToken(); if (yyTok == Tok_LeftParen) { switch (trFunctionAliasManager.trFunctionByName(yyWord)) { @@ -2034,6 +2040,11 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac } break; case Tok_ColonColon: + if (yyTokIdentSeen) { + // member or base class identifier + yyTok = getToken(); + break; + } if (yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0 && !yyTokColonSeen) prospectiveContext = prefix; prefix += strColons; @@ -2046,16 +2057,20 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac #endif break; case Tok_RightBrace: - if (yyBraceDepth + 1 == namespaceDepths.count()) // class or namespace - truncateNamespaces(&namespaces, namespaceDepths.pop()); - if (yyBraceDepth == namespaceDepths.count()) { - // function, class or namespace - if (!yyBraceDepth && !directInclude) - truncateNamespaces(&functionContext, 1); - else - functionContext = namespaces; - functionContextUnresolved.clear(); - pendingContext.clear(); + if (!yyTokColonSeen) { + if (yyBraceDepth + 1 == namespaceDepths.count()) { + // class or namespace + truncateNamespaces(&namespaces, namespaceDepths.pop()); + } + if (yyBraceDepth == namespaceDepths.count()) { + // function, class or namespace + if (!yyBraceDepth && !directInclude) + truncateNamespaces(&functionContext, 1); + else + functionContext = namespaces; + functionContextUnresolved.clear(); + pendingContext.clear(); + } } // fallthrough case Tok_Semicolon: @@ -2094,15 +2109,21 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac yyTok = getToken(); break; case Tok_LeftBrace: - if (!prospectiveContext.isEmpty() - && yyBraceDepth == namespaceDepths.count() + 1 && yyParenDepth == 0) { - pendingContext = prospectiveContext; - prospectiveContext.clear(); + if (yyBraceDepth == namespaceDepths.count() + 1 && yyParenDepth == 0) { + if (!prospectiveContext.isEmpty()) { + pendingContext = prospectiveContext; + prospectiveContext.clear(); + } + if (!yyTokIdentSeen) { + // Function body + yyTokColonSeen = false; + } } - yyTokColonSeen = false; // fallthrough - case Tok_Comma: case Tok_LeftParen: + yyTokIdentSeen = false; + // fallthrough + case Tok_Comma: case Tok_QuestionMark: metaExpected = true; yyTok = getToken(); diff --git a/src/macdeployqt/shared/shared.cpp b/src/macdeployqt/shared/shared.cpp index 35dd1402b..3b0c954cc 100644 --- a/src/macdeployqt/shared/shared.cpp +++ b/src/macdeployqt/shared/shared.cpp @@ -46,6 +46,7 @@ #include <QJsonObject> #include <QJsonArray> #include <QJsonValue> +#include <QRegularExpression> #include "shared.h" #ifdef Q_OS_DARWIN @@ -165,6 +166,56 @@ void patch_debugInInfoPlist(const QString &infoPlistPath) infoPlist.write(contents); } +OtoolInfo findDependencyInfo(const QString &binaryPath) +{ + OtoolInfo info; + info.binaryPath = binaryPath; + + LogDebug() << "Using otool:"; + LogDebug() << " inspecting" << binaryPath; + QProcess otool; + otool.start("otool", QStringList() << "-L" << binaryPath); + otool.waitForFinished(); + + if (otool.exitCode() != 0) { + LogError() << otool.readAllStandardError(); + } + + static const QRegularExpression regexp(QStringLiteral( + "^\\t(.+) \\(compatibility version (\\d+\\.\\d+\\.\\d+), " + "current version (\\d+\\.\\d+\\.\\d+)\\)$")); + + QString output = otool.readAllStandardOutput(); + QStringList outputLines = output.split("\n", QString::SkipEmptyParts); + outputLines.removeFirst(); // remove line containing the binary path + if (binaryPath.contains(".framework/") || binaryPath.endsWith(".dylib")) { + const auto match = regexp.match(outputLines.first()); + if (match.hasMatch()) { + info.installName = match.captured(1); + info.compatibilityVersion = QVersionNumber::fromString(match.captured(2)); + info.currentVersion = QVersionNumber::fromString(match.captured(3)); + } else { + LogError() << "Could not parse otool output line:" << outputLines.first(); + } + outputLines.removeFirst(); + } + + for (const QString &outputLine : outputLines) { + const auto match = regexp.match(outputLine); + if (match.hasMatch()) { + DylibInfo dylib; + dylib.binaryPath = match.captured(1); + dylib.compatibilityVersion = QVersionNumber::fromString(match.captured(2)); + dylib.currentVersion = QVersionNumber::fromString(match.captured(3)); + info.dependencies << dylib; + } else { + LogError() << "Could not parse otool output line:" << outputLine; + } + } + + return info; +} + FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs) { FrameworkInfo info; @@ -231,13 +282,11 @@ FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundl if (state == QtPath) { // Check for library name part if (part < parts.count() && parts.at(part).contains(".dylib ")) { - info.installName += "/" + (qtPath + currentPart + "/").simplified(); - info.frameworkDirectory = info.installName; + info.frameworkDirectory += "/" + (qtPath + currentPart + "/").simplified(); state = DylibName; continue; } else if (part < parts.count() && parts.at(part).endsWith(".framework")) { - info.installName += "/" + (qtPath + "lib/").simplified(); - info.frameworkDirectory = info.installName; + info.frameworkDirectory += "/" + (qtPath + "lib/").simplified(); state = FrameworkName; continue; } else if (trimmed.startsWith("/") == false) { // If the line does not contain a full path, the app is using a binary Qt package. @@ -264,11 +313,10 @@ FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundl ++part; continue; } if (state == DylibName) { - name = currentPart.split(" (compatibility").at(0); + name = currentPart; info.isDylib = true; info.frameworkName = name; info.binaryName = name.left(name.indexOf('.')) + suffix + name.mid(name.indexOf('.')); - info.installName += name; info.deployedInstallName = "@executable_path/../Frameworks/" + info.binaryName; info.frameworkPath = info.frameworkDirectory + info.binaryName; info.sourceFilePath = info.frameworkPath; @@ -284,7 +332,6 @@ FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundl info.binaryDirectory = "Versions/" + info.version; info.binaryName = name + suffix; info.binaryPath = "/" + info.binaryDirectory + "/" + info.binaryName; - info.installName += info.frameworkName + "/" + info.binaryDirectory + "/" + name; info.deployedInstallName = "@executable_path/../Frameworks/" + info.frameworkName + info.binaryPath; info.frameworkPath = info.frameworkDirectory + info.frameworkName; info.sourceFilePath = info.frameworkPath + info.binaryPath; @@ -296,6 +343,9 @@ FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundl } } + info.installName = findDependencyInfo(info.sourceFilePath).installName; + if (info.installName.startsWith("@rpath/")) + info.deployedInstallName = info.installName; return info; } @@ -395,11 +445,11 @@ QStringList findAppBundleFiles(const QString &appBundlePath, bool absolutePath = return result; } -QList<FrameworkInfo> getQtFrameworks(const QStringList &otoolLines, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs) +QList<FrameworkInfo> getQtFrameworks(const QList<DylibInfo> &dependencies, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs) { QList<FrameworkInfo> libraries; - foreach(const QString line, otoolLines) { - FrameworkInfo info = parseOtoolLibraryLine(line, appBundlePath, rpaths, useDebugLibs); + for (const DylibInfo &dylibInfo : dependencies) { + FrameworkInfo info = parseOtoolLibraryLine(dylibInfo.binaryPath, appBundlePath, rpaths, useDebugLibs); if (info.frameworkName.isEmpty() == false) { LogDebug() << "Adding framework:"; LogDebug() << info; @@ -477,23 +527,8 @@ QSet<QString> getBinaryRPaths(const QString &path, bool resolve = true, QString QList<FrameworkInfo> getQtFrameworks(const QString &path, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs) { - LogDebug() << "Using otool:"; - LogDebug() << " inspecting" << path; - QProcess otool; - otool.start("otool", QStringList() << "-L" << path); - otool.waitForFinished(); - - if (otool.exitCode() != 0) { - LogError() << otool.readAllStandardError(); - } - - QString output = otool.readAllStandardOutput(); - QStringList outputLines = output.split("\n"); - outputLines.removeFirst(); // remove line containing the binary path - if (path.contains(".framework") || path.contains(".dylib")) - outputLines.removeFirst(); // frameworks and dylibs print install name of themselves first. - - return getQtFrameworks(outputLines, appBundlePath, rpaths + getBinaryRPaths(path), useDebugLibs); + const OtoolInfo info = findDependencyInfo(path); + return getQtFrameworks(info.dependencies, appBundlePath, rpaths + getBinaryRPaths(path), useDebugLibs); } QList<FrameworkInfo> getQtFrameworksForPaths(const QStringList &paths, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs) @@ -517,24 +552,14 @@ QStringList getBinaryDependencies(const QString executablePath, { QStringList binaries; - QProcess otool; - otool.start("otool", QStringList() << "-L" << path); - otool.waitForFinished(); - - if (otool.exitCode() != 0) { - LogError() << otool.readAllStandardError(); - } - - QString output = otool.readAllStandardOutput(); - QStringList outputLines = output.split("\n"); - outputLines.removeFirst(); // remove line containing the binary path + const auto dependencies = findDependencyInfo(path).dependencies; bool rpathsLoaded = false; QSet<QString> rpaths; // return bundle-local dependencies. (those starting with @executable_path) - foreach (const QString &line, outputLines) { - QString trimmedLine = line.mid(0, line.indexOf("(")).trimmed(); // remove "(compatibility version ...)" and whitespace + foreach (const DylibInfo &info, dependencies) { + QString trimmedLine = info.binaryPath; if (trimmedLine.startsWith("@executable_path/")) { QString binary = QDir::cleanPath(executablePath + trimmedLine.mid(QStringLiteral("@executable_path/").length())); if (binary != path) @@ -875,15 +900,10 @@ DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks, const FrameworkInfo framework = frameworks.takeFirst(); copiedFrameworks.append(framework.frameworkName); - // Get the qt path from one of the Qt frameworks; - if (deploymentInfo.qtPath.isNull() && framework.frameworkName.contains("Qt") - && framework.frameworkDirectory.contains("/lib")) - { - deploymentInfo.qtPath = framework.frameworkDirectory; - deploymentInfo.qtPath.chop(5); // remove "/lib/" - } + if (deploymentInfo.qtPath.isNull()) + deploymentInfo.qtPath = QLibraryInfo::location(QLibraryInfo::PrefixPath); - if (framework.installName.startsWith("@executable_path/") || framework.installName.startsWith("@rpath/")) { + if (framework.frameworkDirectory.startsWith(bundlePath)) { LogError() << framework.frameworkName << "already deployed, skipping."; continue; } @@ -939,7 +959,9 @@ DeploymentInfo deployQtFrameworks(const QString &appBundlePath, const QStringLis applicationBundle.libraryPaths = findAppLibraries(appBundlePath); QStringList allBinaryPaths = QStringList() << applicationBundle.binaryPath << applicationBundle.libraryPaths << additionalExecutables; - QList<FrameworkInfo> frameworks = getQtFrameworksForPaths(allBinaryPaths, appBundlePath, getBinaryRPaths(applicationBundle.binaryPath, true), useDebugLibs); + QSet<QString> allLibraryPaths = getBinaryRPaths(applicationBundle.binaryPath, true); + allLibraryPaths.insert(QLibraryInfo::location(QLibraryInfo::LibrariesPath)); + QList<FrameworkInfo> frameworks = getQtFrameworksForPaths(allBinaryPaths, appBundlePath, allLibraryPaths, useDebugLibs); if (frameworks.isEmpty() && !alwaysOwerwriteEnabled) { LogWarning(); LogWarning() << "Could not find any external Qt frameworks to deploy in" << appBundlePath; diff --git a/src/macdeployqt/shared/shared.h b/src/macdeployqt/shared/shared.h index 4b4e9bed0..9aee2d424 100644 --- a/src/macdeployqt/shared/shared.h +++ b/src/macdeployqt/shared/shared.h @@ -37,6 +37,7 @@ #include <QStringList> #include <QDebug> #include <QSet> +#include <QVersionNumber> extern int logLevel; #define LogError() if (logLevel < 0) {} else qDebug() << "ERROR:" @@ -65,6 +66,24 @@ public: QString binaryDestinationDirectory; }; +class DylibInfo +{ +public: + QString binaryPath; + QVersionNumber currentVersion; + QVersionNumber compatibilityVersion; +}; + +class OtoolInfo +{ +public: + QString installName; + QString binaryPath; + QVersionNumber currentVersion; + QVersionNumber compatibilityVersion; + QList<DylibInfo> dependencies; +}; + bool operator==(const FrameworkInfo &a, const FrameworkInfo &b); QDebug operator<<(QDebug debug, const FrameworkInfo &info); @@ -92,6 +111,7 @@ inline QDebug operator<<(QDebug debug, const ApplicationBundleInfo &info); void changeQtFrameworks(const QString appPath, const QString &qtPath, bool useDebugLibs); void changeQtFrameworks(const QList<FrameworkInfo> frameworks, const QStringList &binaryPaths, const QString &qtPath); +OtoolInfo findDependencyInfo(const QString &binaryPath); FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs); QString findAppBinary(const QString &appBundlePath); QList<FrameworkInfo> getQtFrameworks(const QString &path, const QString &appBundlePath, const QSet<QString> &rpaths, bool useDebugLibs); diff --git a/src/qdbus/qdbusviewer/images/qdbusviewer-128.png b/src/qdbus/qdbusviewer/images/qdbusviewer-128.png Binary files differindex af940dcb5..8946d13c6 100644 --- a/src/qdbus/qdbusviewer/images/qdbusviewer-128.png +++ b/src/qdbus/qdbusviewer/images/qdbusviewer-128.png diff --git a/src/qdbus/qdbusviewer/images/qdbusviewer.ico b/src/qdbus/qdbusviewer/images/qdbusviewer.ico Binary files differindex c5742ccf0..32b68ca74 100644 --- a/src/qdbus/qdbusviewer/images/qdbusviewer.ico +++ b/src/qdbus/qdbusviewer/images/qdbusviewer.ico diff --git a/src/qdbus/qdbusviewer/images/qdbusviewer.png b/src/qdbus/qdbusviewer/images/qdbusviewer.png Binary files differindex b410aaf50..e8c8d7f71 100644 --- a/src/qdbus/qdbusviewer/images/qdbusviewer.png +++ b/src/qdbus/qdbusviewer/images/qdbusviewer.png diff --git a/src/qdoc/doc/files/qtgui.qdocconf b/src/qdoc/doc/files/qtgui.qdocconf index 0b2d28108..855ed538c 100644 --- a/src/qdoc/doc/files/qtgui.qdocconf +++ b/src/qdoc/doc/files/qtgui.qdocconf @@ -4,7 +4,7 @@ project = QtGui description = Qt GUI Reference Documentation version = $QT_VERSION -examplesinstallpath = qtbase/gui +examplesinstallpath = gui qhp.projects = QtGui diff --git a/src/qev/qev.cpp b/src/qev/qev.cpp index aff170d97..bd30e64b1 100644 --- a/src/qev/qev.cpp +++ b/src/qev/qev.cpp @@ -38,6 +38,8 @@ QT_USE_NAMESPACE +QIODevice *qout; + class Widget : public QWidget { public: @@ -46,7 +48,7 @@ public: bool event(QEvent *e) { if (e->type() == QEvent::ContextMenu) return false; - qDebug() << e; + QDebug(qout) << e << endl; return QWidget::event(e); } }; @@ -55,6 +57,11 @@ public: int main(int argc, char **argv) { QApplication app(argc, argv); + + QFile fout; + fout.open(stdout, QIODevice::WriteOnly); + qout = &fout; + Widget w; w.show(); return app.exec(); diff --git a/src/qtdiag/qtdiag.cpp b/src/qtdiag/qtdiag.cpp index 310cbea08..901df8f0b 100644 --- a/src/qtdiag/qtdiag.cpp +++ b/src/qtdiag/qtdiag.cpp @@ -38,6 +38,7 @@ #include <QtGui/QScreen> #include <QtGui/QFont> #include <QtGui/QFontDatabase> +#include <QtGui/QPalette> #ifndef QT_NO_OPENGL # include <QtGui/QOpenGLContext> # include <QtGui/QOpenGLFunctions> @@ -244,6 +245,17 @@ static QString formatValueQDebug(T t) return result; } +QTextStream &operator<<(QTextStream &str, const QPalette &palette) +{ + for (int r = 0; r < int(QPalette::NColorRoles); ++r) { + const QPalette::ColorRole role = static_cast< QPalette::ColorRole>(r); + const QColor color = palette.color(QPalette::Active, role); + if (color.isValid()) + str << " " << formatValueQDebug(role) << ": " << color.name(QColor::HexArgb) << '\n'; + } + return str; +} + static inline QByteArrayList qtFeatures() { QByteArrayList result; @@ -499,6 +511,8 @@ QString qtDiag(unsigned flags) str << " " << formatValueQDebug(writingSystems.at(i)) << '\n'; } + str << "\nPalette:\n" << QGuiApplication::palette(); + const QList<QScreen*> screens = QGuiApplication::screens(); const int screenCount = screens.size(); str << "\nScreens: " << screenCount << ", High DPI scaling: " diff --git a/src/qtpaths/qtpaths.cpp b/src/qtpaths/qtpaths.cpp index a45064cc7..97f613a23 100644 --- a/src/qtpaths/qtpaths.cpp +++ b/src/qtpaths/qtpaths.cpp @@ -161,7 +161,7 @@ int main(int argc, char **argv) QCoreApplication::translate("qtpaths", "Find writable path for <type>."), QStringLiteral("type")); parser.addOption(writablePath); - QCommandLineOption locateDir(QStringList() << QStringLiteral("locate-dir") << QStringLiteral("locate-directory."), + QCommandLineOption locateDir(QStringList() << QStringLiteral("locate-dir") << QStringLiteral("locate-directory"), QCoreApplication::translate("qtpaths", "Locate directory [name] in <type>."), QStringLiteral("type")); parser.addOption(locateDir); diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/parsecpp/expectedoutput.txt index c35c086c8..28f115561 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/expectedoutput.txt +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/expectedoutput.txt @@ -2,4 +2,6 @@ .*/lupdate/testdata/good/parsecpp/finddialog.cpp:127: Qualifying with unknown namespace/class ::FindDialog .*/lupdate/testdata/good/parsecpp/finddialog.cpp:167: Qualifying with unknown namespace/class ::FindDialog .*/lupdate/testdata/good/parsecpp/finddialog.cpp:173: Unsupported encoding Latin1 +.*/lupdate/testdata/good/parsecpp/main.cpp:625: tr\(\) cannot be called without context +.*/lupdate/testdata/good/parsecpp/main.cpp:627: tr\(\) cannot be called without context lupdate warning: Message with id 'yet_another_id' has no source. diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp index 31783fd6a..5b6645689 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/main.cpp @@ -516,3 +516,114 @@ void nullMacroInPlural() QObject::tr("%n NULL(s)", NULL, 3); QObject::tr("%n Q_NULLPTR(s)", Q_NULLPTR, 3); } + + + +// QTBUG-34128: lupdate ignores tr() calls in constructor if a member is +// initialized with C++11 initializer list +class ListInitializationClass : public NameSchpase::YetMoreFun, Gui::BaseClass +{ + Q_OBJECT + + ListInitializationClass() : + NameSchpase::YetMoreFun(), + Gui::BaseClass{ }, + a{ 0 }, + b(1), + c(tr("Hello World")) + { + tr("ListInitializationClass in-class constructor"); + } + + ListInitializationClass(int a); + + ListInitializationClass(int a, int b, int c); + + int a; + int b; + QString c; +}; + +ListInitializationClass::ListInitializationClass(int a) : + b{ { 2, 3 }[a] } +{ + tr("ListInitializationClass out-of-class single member initializer"); +} + +ListInitializationClass::ListInitializationClass(int a, int b, int c) : + NameSchpase::YetMoreFun{ }, + Gui::BaseClass(), + a{ 2 + (a/3) }, + b(b), + c{ tr("%n item(s)", Q_NULLPTR, c) } +{ + tr("ListInitializationClass out-of-class multi member initializer"); +} + + + +// QTBUG-42166: lupdate is confused by C++11 lambdas in constructor initializer lists +class LambdaMemberClass : public Gui::BaseClass +{ + Q_OBJECT + + LambdaMemberClass() : + Gui::BaseClass(), + a{ [](){ std::cout << QObject::tr("Hello"); } }, + b([](){ std::cout << "World\n"; }) + { + tr("LambdaMemberClass in-class constructor"); + } + + LambdaMemberClass(void *); + + std::function<void()> a; + std::function<void()> b; +}; + +LambdaMemberClass::LambdaMemberClass(void *) : + Gui::BaseClass{ }, + a([](){ std::cout << QObject::tr("Hallo "); }), + b{ [](){ std::cout << "Welt\n"; } } +{ + tr("LambdaMemberClass out-of-class constructor"); +} + + + +// Template parameters in base class initialization +class TemplateClass : QVarLengthArray<char, sizeof(std::size_t)>, std::vector<int> +{ + Q_DECLARE_TR_FUNCTIONS(TemplateClass) + QString member; + +public: + TemplateClass() : + QVarLengthArray<char, sizeof(std::size_t)>(), + std::vector<int>(3), + member(tr("TemplateClass() in-class member initialization")) + { + tr("TemplateClass() in-class body"); + } + + TemplateClass(void *); + TemplateClass(int); +}; + +// supported: combination of parens in base class template parameter with direct initialization (parens) +TemplateClass::TemplateClass(void *) : + QVarLengthArray<char, sizeof(std::size_t)>(), + std::vector<int>{ 1, 2 }, + member{ tr("TemplateClass(void *) out-of-class member initialization") } +{ + tr("TemplateClass(void *) out-of-class body"); +} + +// not supported: combination of parens in base class template parameter with list initialization (braces) +TemplateClass::TemplateClass(int) : + QVarLengthArray<char, sizeof(std::size_t)>{ 3, 4, 5 }, + member(tr("[unsupported] TemplateClass(int) out-of-class member initialization")) +{ + tr("[unsupported] TemplateClass(int) out-of-class body"); +} + diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result index 4f301b2db..d72026b1c 100644 --- a/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result +++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp/project.ts.result @@ -187,6 +187,49 @@ backslashed \ stuff.</source> </message> </context> <context> + <name>LambdaMemberClass</name> + <message> + <location filename="main.cpp" line="575"/> + <source>LambdaMemberClass in-class constructor</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.cpp" line="589"/> + <source>LambdaMemberClass out-of-class constructor</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>ListInitializationClass</name> + <message> + <location filename="main.cpp" line="533"/> + <source>Hello World</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.cpp" line="535"/> + <source>ListInitializationClass in-class constructor</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.cpp" line="550"/> + <source>ListInitializationClass out-of-class single member initializer</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location filename="main.cpp" line="558"/> + <source>%n item(s)</source> + <translation type="unfinished"> + <numerusform></numerusform> + </translation> + </message> + <message> + <location filename="main.cpp" line="560"/> + <source>ListInitializationClass out-of-class multi member initializer</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>LotsaFun</name> <message> <location filename="main.cpp" line="310"/> @@ -334,6 +377,16 @@ backslashed \ stuff.</source> </translation> </message> <message> + <location filename="main.cpp" line="572"/> + <source>Hello</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.cpp" line="586"/> + <source>Hallo </source> + <translation type="unfinished"></translation> + </message> + <message> <location filename="included.cpp" line="34"/> <source>message from #included .cpp file</source> <translation type="unfinished"></translation> @@ -386,6 +439,29 @@ backslashed \ stuff.</source> </message> </context> <context> + <name>TemplateClass</name> + <message> + <location filename="main.cpp" line="604"/> + <source>TemplateClass() in-class member initialization</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.cpp" line="606"/> + <source>TemplateClass() in-class body</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.cpp" line="617"/> + <source>TemplateClass(void *) out-of-class member initialization</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="main.cpp" line="619"/> + <source>TemplateClass(void *) out-of-class body</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> <name>TernaryClass</name> <message> <location filename="main.cpp" line="480"/> |