diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index d9d45eefb14..1971d93c736 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -455,6 +455,11 @@ jobs: find_package(Python3 REQUIRED COMPONENTS Interpreter) string(REPLACE "x86" "x64" Python3_EXECUTABLE "${Python3_EXECUTABLE}") + set(WITH_TESTS "--with-tests") + if (${{github.ref}} MATCHES "tags/v") + unset(WITH_TESTS) + endif() + execute_process( COMMAND python -u @@ -465,7 +470,7 @@ jobs: --qt-path "${{ steps.qt.outputs.qt_dir }}" --llvm-path "${{ steps.libclang.outputs.libclang_dir }}" --python3 "${Python3_EXECUTABLE}" - --with-tests + ${WITH_TESTS} ${CDB_OPTION} ${ELFUTILS_OPTION} --add-config=-DCMAKE_C_COMPILER_LAUNCHER=ccache @@ -597,12 +602,10 @@ jobs: config: - { name: "Windows Latest MSVC", artifact: "Windows-MSVC", - is_msvc: true, os: ubuntu-latest } - { name: "Windows Latest MinGW", artifact: "Windows-MinGW", - is_msvc: false, os: ubuntu-latest } - { @@ -629,21 +632,21 @@ jobs: path: ./ - name: Download wininterrupt artifact - if: runner.os == 'Windows' + if: contains(matrix.config.artifact, 'Windows') uses: actions/download-artifact@v1 with: name: wininterrupt-${{ matrix.config.artifact }}-${{ github.run_id }}.7z path: ./ - name: Download qtcreatorcdbext artifact - if: runner.os == 'Windows' && matrix.config.is_msvc + if: matrix.config.artifact == 'Windows-MSVC' uses: actions/upload-artifact@v1 with: name: qtcreatorcdbext-${{ matrix.config.artifact }}-${{ github.run_id }}.7z path: ./ - name: Download disk image artifact - if: runner.os == 'macOS' + if: matrix.config.artifact == 'macOS' uses: actions/upload-artifact@v1 with: name: qt-creator-${{ matrix.config.artifact }}-${{ github.run_id }}.dmg @@ -680,7 +683,7 @@ jobs: asset_content_type: application/x-gtar - name: Upload wininterrupt to Release - if: runner.os == 'Windows' + if: contains(matrix.config.artifact, 'Windows') uses: actions/upload-release-asset@v1.0.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -691,7 +694,7 @@ jobs: asset_content_type: application/x-gtar - name: Upload qtcreatorcdbext to Release - if: runner.os == 'Windows' && matrix.config.is_msvc + if: matrix.config.artifact == 'Windows-MSVC' uses: actions/upload-release-asset@v1.0.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -702,7 +705,7 @@ jobs: asset_content_type: application/x-gtar - name: Upload disk image to Release - if: runner.os == 'macOS' + if: matrix.config.artifact == 'macOS' uses: actions/upload-release-asset@v1.0.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 6274362ab4d..744b94d4d6f 100644 --- a/README.md +++ b/README.md @@ -353,7 +353,7 @@ we thank the authors who made this possible: Roberto Raggi - QtCreator/src/shared/cplusplus + QtCreator/src/libs/3rdparty/cplusplus Copyright 2005 Roberto Raggi diff --git a/doc/qtcreator/src/overview/creator-acknowledgements.qdoc b/doc/qtcreator/src/overview/creator-acknowledgements.qdoc index 28b967d8f98..226160d7695 100644 --- a/doc/qtcreator/src/overview/creator-acknowledgements.qdoc +++ b/doc/qtcreator/src/overview/creator-acknowledgements.qdoc @@ -441,7 +441,7 @@ \li \b{Open Source front-end for C++ (license MIT)}, enhanced for use in \QC.\br Roberto Raggi \br - QtCreator/src/shared/cplusplus\br\br + QtCreator/src/libs/3rdparty/cplusplus\br\br \li \b{ANGLE Library (Windows)} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml index cd956dd99e0..d07812f02fd 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml @@ -303,38 +303,59 @@ SecondColumnLayout { } } + // This connection is meant to update the popups y-position and the main scrollviews + // height as soon as the height of the color picker changes. Initially the height of the + // color picker is 0 until its completion is done. + Connections { + target: colorPicker + function onHeightChanged() { + cePopup.setPopupY() + cePopup.setMainScrollViewHeight() + } + } + onOpened: { + cePopup.setPopupY() + cePopup.setMainScrollViewHeight() + } + onYChanged: cePopup.setMainScrollViewHeight() + onHeightChanged: cePopup.setMainScrollViewHeight() + + function setMainScrollViewHeight() { if (Controller.mainScrollView === null) return var mapped = preview.mapToItem(Controller.mainScrollView.contentItem, cePopup.x, cePopup.y) - Controller.mainScrollView.temporaryHeight = mapped.y + cePopup.height + 20 + Controller.mainScrollView.temporaryHeight = mapped.y + cePopup.height + + StudioTheme.Values.colorEditorPopupMargin } - onHeightChanged: { + function setPopupY() { if (Controller.mainScrollView === null) return - var mapped = preview.mapToItem(Controller.mainScrollView.contentItem, cePopup.x, cePopup.y) - Controller.mainScrollView.temporaryHeight = mapped.y + cePopup.height + 20 + var tmp = preview.mapToItem(Controller.mainScrollView.contentItem, preview.x, preview.y) + cePopup.y = Math.max(-tmp.y + StudioTheme.Values.colorEditorPopupMargin, + cePopup.__defaultY) } - onClosed: { - Controller.mainScrollView.temporaryHeight = 0 - } + onClosed: Controller.mainScrollView.temporaryHeight = 0 - x: - StudioTheme.Values.colorEditorPopupWidth * 0.5 - + preview.width * 0.5 - y: - StudioTheme.Values.colorEditorPopupMargin - - (StudioTheme.Values.colorEditorPopupSpacing * 2) - - StudioTheme.Values.defaultControlHeight - - StudioTheme.Values.colorEditorPopupLineHeight - - colorPicker.height * 0.5 - + preview.height * 0.5 + property real __defaultX: - StudioTheme.Values.colorEditorPopupWidth * 0.5 + + preview.width * 0.5 + property real __defaultY: - StudioTheme.Values.colorEditorPopupPadding + - (StudioTheme.Values.colorEditorPopupSpacing * 2) + - StudioTheme.Values.defaultControlHeight + - StudioTheme.Values.colorEditorPopupLineHeight + - colorPicker.height * 0.5 + + preview.height * 0.5 + + x: cePopup.__defaultX + y: cePopup.__defaultY width: StudioTheme.Values.colorEditorPopupWidth height: colorColumn.height + sectionColumn.height - + StudioTheme.Values.colorEditorPopupMargin + 2 // TODO magic number + + StudioTheme.Values.colorEditorPopupPadding + 2 // TODO magic number padding: StudioTheme.Values.border margins: -1 // If not defined margin will be -1 @@ -353,7 +374,7 @@ SecondColumnLayout { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.margins: StudioTheme.Values.colorEditorPopupMargin + anchors.margins: StudioTheme.Values.colorEditorPopupPadding spacing: StudioTheme.Values.colorEditorPopupSpacing RowLayout { @@ -714,7 +735,7 @@ SecondColumnLayout { Column { id: sectionColumn - anchors.topMargin: StudioTheme.Values.colorEditorPopupMargin + anchors.topMargin: StudioTheme.Values.colorEditorPopupPadding anchors.top: colorColumn.bottom anchors.left: parent.left anchors.right: parent.right diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorLogic.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorLogic.qml index 2f5a78bdbc2..06ec4ff1aca 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorLogic.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorLogic.qml @@ -27,57 +27,57 @@ import QtQuick 2.15 import StudioTheme 1.0 as StudioTheme QtObject { - id: innerObject + id: root property variant backendValue property color textColor: StudioTheme.Values.themeTextColor - property variant valueFromBackend: backendValue === undefined ? 0 : backendValue.value + property variant valueFromBackend: root.backendValue === undefined ? 0 : root.backendValue.value property bool baseStateFlag: isBaseState property bool isInModel: { - if (backendValue !== undefined && backendValue.isInModel !== undefined) - return backendValue.isInModel + if (root.backendValue !== undefined && root.backendValue.isInModel !== undefined) + return root.backendValue.isInModel return false } property bool isInSubState: { - if (backendValue !== undefined && backendValue.isInSubState !== undefined) - return backendValue.isInSubState + if (root.backendValue !== undefined && root.backendValue.isInSubState !== undefined) + return root.backendValue.isInSubState return false } - property bool highlight: textColor === __changedTextColor + property bool highlight: root.textColor === root.__changedTextColor property bool errorState: false readonly property color __defaultTextColor: StudioTheme.Values.themeTextColor readonly property color __changedTextColor: StudioTheme.Values.themeInteraction readonly property color __errorTextColor: StudioTheme.Values.themeError - onBackendValueChanged: evaluate() - onValueFromBackendChanged: evaluate() - onBaseStateFlagChanged: evaluate() - onIsInModelChanged: evaluate() - onIsInSubStateChanged: evaluate() - onErrorStateChanged: evaluate() + onBackendValueChanged: root.evaluate() + onValueFromBackendChanged: root.evaluate() + onBaseStateFlagChanged: root.evaluate() + onIsInModelChanged: root.evaluate() + onIsInSubStateChanged: root.evaluate() + onErrorStateChanged: root.evaluate() function evaluate() { - if (innerObject.backendValue === undefined) + if (root.backendValue === undefined) return - if (innerObject.errorState) { - innerObject.textColor = __errorTextColor + if (root.errorState) { + root.textColor = root.__errorTextColor return } - if (innerObject.baseStateFlag) { - if (innerObject.backendValue.isInModel) - innerObject.textColor = __changedTextColor + if (root.baseStateFlag) { + if (root.backendValue.isInModel) + root.textColor = root.__changedTextColor else - innerObject.textColor = __defaultTextColor + root.textColor = root.__defaultTextColor } else { - if (innerObject.backendValue.isInSubState) - innerObject.textColor = StudioTheme.Values.themeChangedStateText + if (root.backendValue.isInSubState) + root.textColor = StudioTheme.Values.themeChangedStateText else - innerObject.textColor = __defaultTextColor + root.textColor = root.__defaultTextColor } } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml index 58cba0a1930..716dfc3b28a 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml @@ -185,9 +185,10 @@ QtObject { // Color Editor Popup property real colorEditorPopupWidth: 4 * values.colorEditorPopupSpinBoxWidth + 3 * values.controlGap - + 2 * values.colorEditorPopupMargin + + 2 * values.colorEditorPopupPadding property real colorEditorPopupHeight: 800 - property real colorEditorPopupMargin: 10 + property real colorEditorPopupPadding: 10 + property real colorEditorPopupMargin: 20 property real colorEditorPopupSpacing: 10 property real colorEditorPopupLineHeight: 60 diff --git a/src/libs/3rdparty/sqlite/config.h b/src/libs/3rdparty/sqlite/config.h index dbd0c36e123..345e2b0b01d 100644 --- a/src/libs/3rdparty/sqlite/config.h +++ b/src/libs/3rdparty/sqlite/config.h @@ -88,3 +88,4 @@ #define SQLITE_OMIT_EXPLAIN 1 #define SQLITE_OMIT_TRACE 1 #define SQLITE_DEFAULT_LOCKING_MODE 1 +#define SQLITE_WIN32_GETVERSIONEX 0 diff --git a/src/plugins/coreplugin/helpitem.cpp b/src/plugins/coreplugin/helpitem.cpp index 2a972cb98eb..50f84bbf7ab 100644 --- a/src/plugins/coreplugin/helpitem.cpp +++ b/src/plugins/coreplugin/helpitem.cpp @@ -29,6 +29,8 @@ #include #include +#include + using namespace Core; HelpItem::HelpItem() = default; @@ -165,31 +167,66 @@ QString HelpItem::extractContent(bool extended) const return contents; } -static std::pair extractVersion(const QUrl &url) +// The following is only correct under the specific current conditions, and it will +// always be quite some guessing as long as the version information does not +// include separators for major vs minor vs patch version. +static QVersionNumber qtVersionHeuristic(const QString &digits) +{ + if (digits.count() > 6 || digits.count() < 3) + return {}; // suspicious version number + + for (const QChar &digit : digits) + if (!digit.isDigit()) + return {}; // we should have only digits + + // When we have 3 digits, we split it like: ABC -> A.B.C + // When we have 4 digits, we split it like: ABCD -> A.BC.D + // When we have 5 digits, we split it like: ABCDE -> A.BC.DE + // When we have 6 digits, we split it like: ABCDEF -> AB.CD.EF + switch (digits.count()) { + case 3: + return QVersionNumber(digits.mid(0, 1).toInt(), + digits.mid(1, 1).toInt(), + digits.mid(2, 1).toInt()); + case 4: + return QVersionNumber(digits.mid(0, 1).toInt(), + digits.mid(1, 2).toInt(), + digits.mid(3, 1).toInt()); + case 5: + return QVersionNumber(digits.mid(0, 1).toInt(), + digits.mid(1, 2).toInt(), + digits.mid(3, 2).toInt()); + case 6: + return QVersionNumber(digits.mid(0, 2).toInt(), + digits.mid(2, 2).toInt(), + digits.mid(4, 2).toInt()); + default: + break; + } + return {}; +} + +static std::pair extractVersion(const QUrl &url) { const QString host = url.host(); const QStringList hostParts = host.split('.'); if (hostParts.size() == 4 && (host.startsWith("com.trolltech.") || host.startsWith("org.qt-project."))) { - bool ok = false; - // the following is only correct under the specific current conditions, and it will - // always be quite some guessing as long as the version information does not - // include separators for major vs minor vs patch version - const int version = hostParts.at(3).toInt(&ok); - if (ok) { + const QVersionNumber version = qtVersionHeuristic(hostParts.at(3)); + if (!version.isNull()) { QUrl urlWithoutVersion(url); urlWithoutVersion.setHost(hostParts.mid(0, 3).join('.')); return {urlWithoutVersion, version}; } } - return {url, 0}; + return {url, {}}; } // sort primary by "url without version" and seconday by "version" static bool helpUrlLessThan(const QUrl &a, const QUrl &b) { - const std::pair va = extractVersion(a); - const std::pair vb = extractVersion(b); + const std::pair va = extractVersion(a); + const std::pair vb = extractVersion(b); const QString sa = va.first.toString(); const QString sb = vb.first.toString(); if (sa == sb) @@ -260,10 +297,10 @@ static const HelpItem::Links getBestLink(const HelpItem::Links &links) // This is to ensure that if we succeeded with an ID lookup, and we have e.g. Qt5 and Qt4 // documentation, that we only return the Qt5 link even though the Qt5 and Qt4 URLs look // different. - int highestVersion = -1; + QVersionNumber highestVersion; HelpItem::Link bestLink; for (const HelpItem::Link &link : links) { - const int version = extractVersion(link.second).second; + const QVersionNumber version = extractVersion(link.second).second; if (version > highestVersion) { highestVersion = version; bestLink = link; diff --git a/src/plugins/qtsupport/qtprojectimporter.cpp b/src/plugins/qtsupport/qtprojectimporter.cpp index 1127482bc73..faa8d6fe850 100644 --- a/src/plugins/qtsupport/qtprojectimporter.cpp +++ b/src/plugins/qtsupport/qtprojectimporter.cpp @@ -33,7 +33,8 @@ #include #include -#include +#include +#include #include #include @@ -41,6 +42,7 @@ #include using namespace ProjectExplorer; +using namespace Utils; namespace QtSupport { @@ -269,14 +271,51 @@ void TestQtProjectImporter::deleteDirectoryData(void *directoryData) const delete static_cast(directoryData); } +static QStringList additionalFilesToCopy(const BaseQtVersion *qt) +{ + // This is a hack and only works with local, "standard" installations of Qt + const int major = qt->qtVersion().majorVersion; + if (major >= 6) { + if (HostOsInfo::isMacHost()) { + return {"lib/QtCore.framework/Versions/A/QtCore"}; + } else if (HostOsInfo::isWindowsHost()) { + const QString release = QString("bin/Qt%1Core.dll").arg(major); + const QString debug = QString("bin/Qt%1Cored.dll").arg(major); + const FilePath base = qt->qmakeFilePath().parentDir().parentDir(); + if (base.pathAppended(release).exists()) + return {release}; + if (base.pathAppended(debug).exists()) + return {debug}; + return {release}; + } else if (HostOsInfo::isLinuxHost()) { + const QString core = QString("lib/libQt%1Core.so.%1").arg(major); + const QDir base(qt->qmakeFilePath().parentDir().parentDir().pathAppended("lib").toString()); + const QStringList icuLibs = Utils::transform(base.entryList({"libicu*.so.*"}), [](const QString &lib) { return QString("lib/" + lib); }); + return QStringList(core) + icuLibs; + } + } + return {}; +} + static Utils::FilePath setupQmake(const BaseQtVersion *qt, const QString &path) { - const QFileInfo fi = QFileInfo(qt->qmakeFilePath().toFileInfo().canonicalFilePath()); - const QString qmakeFile = path + "/" + fi.fileName(); - if (!QFile::copy(fi.absoluteFilePath(), qmakeFile)) - return Utils::FilePath(); + // This is a hack and only works with local, "standard" installations of Qt + const FilePath qmake = qt->qmakeFilePath().canonicalPath(); + const QString qmakeFile = "bin/" + qmake.fileName(); + const FilePath source = qmake.parentDir().parentDir(); + const FilePath target = FilePath::fromString(path); - return Utils::FilePath::fromString(qmakeFile); + const QStringList filesToCopy = QStringList(qmakeFile) + additionalFilesToCopy(qt); + for (const QString &file : filesToCopy) { + const FilePath sourceFile = source.pathAppended(file); + const FilePath targetFile = target.pathAppended(file); + if (!targetFile.parentDir().ensureWritableDir() || !sourceFile.copyFile(targetFile)) { + qDebug() << "Failed to copy" << sourceFile.toString() << "to" << targetFile.toString(); + return {}; + } + } + + return target.pathAppended(qmakeFile); } void QtSupportPlugin::testQtProjectImporter_oneProject_data() diff --git a/src/shared/qbs b/src/shared/qbs index 351461d3680..27bd9ac836b 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit 351461d3680ec680a606fc5333e529c00e161c50 +Subproject commit 27bd9ac836b5cd2937b8d19dfa32cb4ff617b73c