From 2bc7f6603c93f9754b5dfe7a86ea0b42ae17f35f Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Wed, 30 Jun 2021 15:21:04 +0200 Subject: [PATCH 01/26] WebAssembly: (Win) Use python.exe from EMSDK_PYTHON instead from Path This affects Windows only. Instead of searching python.exe in the Path, use the executable name which is stored in the "EMSDK_PYTHON" environment variable (which is set by emsdk_env). emsdk_env also prepends entries to Path, but not the one pointing to the emsdk-shipped python interpreter. I believe that earlier versions of emsdk_env used to add the python location to Path, else this is an old bug. Fixes: QTCREATORBUG-25897 Change-Id: I9b5bc43f865d19a862f8c6cd45105be54286a549 Reviewed-by: Qt CI Bot Reviewed-by: Eike Ziller --- src/plugins/webassembly/webassemblyrunconfiguration.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/webassembly/webassemblyrunconfiguration.cpp b/src/plugins/webassembly/webassemblyrunconfiguration.cpp index 8bef1249dcc..d50c3abc230 100644 --- a/src/plugins/webassembly/webassemblyrunconfiguration.cpp +++ b/src/plugins/webassembly/webassemblyrunconfiguration.cpp @@ -50,8 +50,9 @@ static CommandLine emrunCommand(Target *target, const QString &browser, const QS // that the web server is killed when the application is stopped in Qt Creator. // On Non-windows, we prefer using the shell script, because that knows how to find the // right python (not part of emsdk). The shell script stays attached to the server process. - const FilePath interpreter = bc->environment().searchInPath( - QLatin1String(HostOsInfo::isWindowsHost() ? "python" : "sh")); + const FilePath interpreter = HostOsInfo::isWindowsHost() + ? FilePath::fromUserInput(bc->environment().value("EMSDK_PYTHON")) + : bc->environment().searchInPath("sh"); const QString emrunLaunchScript = HostOsInfo::isWindowsHost() ? emrun.absolutePath() + "/" + emrun.baseName() + ".py" : emrun.absoluteFilePath(); From a894d4e07b22de1a695f635962c6365fdaff03ee Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Thu, 17 Jun 2021 17:49:37 +0200 Subject: [PATCH 02/26] Fix build with Qt 6.2 after components were renamed Some have a "Private" suffix now. cherry picked from commit 77fd87a545e2c3374b252603ad9da6e029f42f99 cherry picked from commit c29d4e09a2ddd8a9c0fac9402fb3b7875af83ad9 cherry picked from commit a803d04c171b31ec90c1ea2bb82930a967027ec8 Change-Id: Ie53d253b4fc9364b452e3eb1fe01345b6d8073d3 Reviewed-by: Alessandro Portale --- cmake/FindQt5.cmake | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cmake/FindQt5.cmake b/cmake/FindQt5.cmake index 589fd4eed50..ae58487eea7 100644 --- a/cmake/FindQt5.cmake +++ b/cmake/FindQt5.cmake @@ -42,6 +42,17 @@ if (NOT Qt6_FOUND) endif() return() else() + # since Qt 6.2 some components are renamed to *Private + foreach(possible_private_libs DesignerComponents QmlDebug) + list(FIND Qt5_FIND_COMPONENTS ${possible_private_libs} dcIndex) + if(dcIndex GREATER_EQUAL 0) + find_package(Qt6${possible_private_libs}Private CONFIG QUIET) + if(TARGET Qt6::${possible_private_libs}Private) + add_library(Qt5::${possible_private_libs} ALIAS Qt6::${possible_private_libs}Private) + list(REMOVE_AT Qt5_FIND_COMPONENTS ${dcIndex}) + endif() + endif() + endforeach() find_package(Qt6 CONFIG ${__arguments} ${Qt5_FIND_COMPONENTS}) endif() From befe84f8d2749c27cdd58eaa1dda0f700982d6e3 Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Thu, 1 Jul 2021 18:04:36 +0300 Subject: [PATCH 03/26] Update Qbs submodule to the top of 1.19 branch Change-Id: If47a7abf972258a389b2af36eb73fd0ce2852b8a Reviewed-by: Christian Kandeler --- src/shared/qbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/qbs b/src/shared/qbs index bd2d37ae336..3a408a87c15 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit bd2d37ae336e3c88e2fd484cc64eb05b46d07888 +Subproject commit 3a408a87c1583d4a5bef0aee2ed56afcf30dd002 From c8b176c9a70a6d4b8cc2231f9812965198f5989c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20L=C3=B6hning?= Date: Fri, 25 Jun 2021 16:21:41 +0200 Subject: [PATCH 04/26] Squish: Stabilize tst_HELP02 On Windows, the shortcut gets lost when clicking "Stop Recording" too quickly. Change-Id: Ieb89b7f59ded0792bf09fbad0b4b44a78d369c0f Reviewed-by: Christian Stenger --- tests/system/suite_HELP/tst_HELP02/test.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/system/suite_HELP/tst_HELP02/test.py b/tests/system/suite_HELP/tst_HELP02/test.py index 1d776689be7..2492be950fa 100755 --- a/tests/system/suite_HELP/tst_HELP02/test.py +++ b/tests/system/suite_HELP/tst_HELP02/test.py @@ -66,6 +66,11 @@ def checkQtCreatorHelpVersion(expectedVersion): test.log("Exception caught", "%s(%s)" % (str(t), str(v))) test.fail("Missing Qt Creator Manual.") + +def _shortcutMatches_(shortcutEdit, expectedText): + return str(findObject(shortcutEdit).text) == expectedText + + def setKeyboardShortcutForAboutQtC(): invokeMenuItem("Tools", "Options...") mouseClick(waitForObjectItem(":Options_QListView", "Environment")) @@ -85,20 +90,19 @@ def setKeyboardShortcutForAboutQtC(): "visible='1' text~='(Stop Recording|Record)'}" % shortcutGB) shortcut = ("{container=%s type='Utils::FancyLineEdit' unnamed='1' visible='1' " "placeholderText='Enter key sequence as text'}" % shortcutGB) + expected = 'Ctrl+Opt+A' if platform.system() == 'Darwin' else 'Ctrl+Alt+A' clickButton(record) nativeType("") + waitFor("_shortcutMatches_(shortcut, expected)", 5000) clickButton(record) - expected = 'Ctrl+Alt+A' - if platform.system() == 'Darwin': - expected = 'Ctrl+Opt+A' - shortcutMatches = waitFor("str(findObject(shortcut).text) == expected", 5000) - if not shortcutMatches and platform.system() == 'Darwin': + gotExpectedShortcut = _shortcutMatches_(shortcut, expected) + if not gotExpectedShortcut and platform.system() == 'Darwin': test.warning("Squish Issue: shortcut was set to %s - entering it manually now" % waitForObject(shortcut).text) replaceEditorContent(shortcut, expected) else: - test.verify(shortcutMatches, "Expected key sequence is displayed.") + test.verify(gotExpectedShortcut, "Expected key sequence is displayed.") clickButton(waitForObject(":Options.OK_QPushButton")) def main(): From 770182653c897ff3d656bfcdd35fbff1d2b1de8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20L=C3=B6hning?= Date: Fri, 25 Jun 2021 16:38:03 +0200 Subject: [PATCH 05/26] Squish: Add parentheses around all print statements Required by Python 3. Change-Id: Ia28491882a844d3642da38145b1ebfcfbd5883b3 Reviewed-by: Christian Stenger --- tests/system/shared/qtcreator.py | 5 +++-- tests/system/shared/utils.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/system/shared/qtcreator.py b/tests/system/shared/qtcreator.py index d78da01d925..0419a4c7589 100644 --- a/tests/system/shared/qtcreator.py +++ b/tests/system/shared/qtcreator.py @@ -144,9 +144,10 @@ def checkForStillRunningQmlExecutable(possibleNames): continue else: if subprocess.call(["taskkill", "/F", "/FI", "IMAGENAME eq %s" % qmlHelper]) == 0: - print "Killed still running %s" % qmlHelper + print("Killed still running %s" % qmlHelper) else: - print "%s is still running - failed to kill it" % qmlHelper + print("%s is still running - failed to kill it" % qmlHelper) + def __removeTestingDir__(): def __removeIt__(directory): diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index e31ed30c200..c34e39af7b8 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -579,7 +579,7 @@ def dumpChildren(item): def writeTestResults(folder): if not os.path.exists(folder): - print "Skipping writing test results (folder '%s' does not exist)." % folder + print("Skipping writing test results (folder '%s' does not exist)." % folder) return resultFile = open("%s.srf" % os.path.join(folder, os.path.basename(squishinfo.testCase)), "w") resultFile.write("suite:%s\n" % os.path.basename(os.path.dirname(squishinfo.testCase))) From 9a9b4080aef9cb1192ba6183d9fef23400394f19 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 4 Jun 2021 11:04:40 +0200 Subject: [PATCH 06/26] QmlPuppet: Fix build with Qt 6.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTCREATORBUG-25763 Change-Id: I05f4b44a3793c41fd1c6812f40f6603892cdac50 Reviewed-by: Tim Jenssen Reviewed-by: Miikka Heikkinen (cherry picked from commit dcbf26490d485c91c4475de8233b4ab1ffe705ea) Reviewed-by: Robert Löhning Reviewed-by: Eike Ziller Reviewed-by: Qt CI Bot --- .../qml2puppet/editor3d/qt5compat/qquick3darealight_p.h | 1 - 1 file changed, 1 deletion(-) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/qt5compat/qquick3darealight_p.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/qt5compat/qquick3darealight_p.h index 8db54879600..472d4477bde 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/qt5compat/qquick3darealight_p.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/qt5compat/qquick3darealight_p.h @@ -40,7 +40,6 @@ class QQuick3DAreaLight : public QQuick3DAbstractLight Q_PROPERTY(float height READ height WRITE setHeight NOTIFY heightChanged) public: - QQuick3DAreaLight() : QQuick3DAbstractLight() {} ~QQuick3DAreaLight() override {} float width() const; From 05545adb93ebdd04df7670d05e91a704375f78b5 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 8 Jul 2021 06:53:28 +0200 Subject: [PATCH 07/26] Utils: Change semantics of FilePath::onDeviceSearchInPath() ... and rename it to searchOnDevice(). We need to handle additional search directories anyways, so its more uniform to always pass a list all of them. Change-Id: I46c7860b51d11c26db58045ff3ab922148af021f Reviewed-by: Christian Stenger --- src/libs/utils/fileutils.cpp | 8 ++--- src/libs/utils/fileutils.h | 2 +- src/plugins/docker/dockerdevice.cpp | 35 ++----------------- src/plugins/docker/dockerdevice.h | 2 -- .../nim/project/nimtoolchainfactory.cpp | 2 +- .../devicesupport/devicemanager.cpp | 4 +-- .../projectexplorer/devicesupport/idevice.cpp | 19 ++++++++-- .../projectexplorer/devicesupport/idevice.h | 5 +-- 8 files changed, 31 insertions(+), 46 deletions(-) diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp index c739b74ec31..87ffc501492 100644 --- a/src/libs/utils/fileutils.cpp +++ b/src/libs/utils/fileutils.cpp @@ -1374,17 +1374,17 @@ FilePath FilePath::onDevice(const FilePath &deviceTemplate) const Example usage: \code binary = FilePath::fromUrl("docker://123/./make); - fullPath = binary.onDeviceSearchInPath(); + fullPath = binary.searchOnDevice(); assert(fullPath == FilePath::fromUrl("docker://123/usr/bin/make")) \endcode */ -FilePath FilePath::onDeviceSearchInPath(const FilePaths &additionalDirs) const +FilePath FilePath::searchOnDevice(const FilePaths &dirs) const { if (needsDevice()) { QTC_ASSERT(s_deviceHooks.searchInPath, return {}); - return s_deviceHooks.searchInPath(*this, additionalDirs); + return s_deviceHooks.searchInPath(*this, dirs); } - return Environment::systemEnvironment().searchInPath(path(), additionalDirs); + return Environment::systemEnvironment().searchInPath(path(), dirs); } Environment FilePath::deviceEnvironment() const diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h index 24da9d380d1..70988a3002d 100644 --- a/src/libs/utils/fileutils.h +++ b/src/libs/utils/fileutils.h @@ -216,7 +216,7 @@ public: static void setDeviceFileHooks(const DeviceFileHooks &hooks); - FilePath onDeviceSearchInPath(const QList &additionalDirs = {}) const; + FilePath searchOnDevice(const QList &dirs) const; Environment deviceEnvironment() const; private: diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index d90c83ee485..6136591de93 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -500,7 +500,7 @@ QList KitDetectorPrivate::autoDetectQtVersions() const emit q->logOutput('\n' + tr("Searching Qt installations...")); for (const QString &candidate : candidates) { emit q->logOutput(tr("Searching for %1 executable...").arg(candidate)); - const FilePath qmake = m_device->searchInPath(FilePath::fromString(candidate)); + const FilePath qmake = m_device->searchExecutableInPath(candidate); if (qmake.isEmpty()) continue; BaseQtVersion *qtVersion = QtVersionFactory::createQtVersionFromQMakePath(qmake, false, m_sharedId, &error); @@ -546,8 +546,8 @@ void KitDetectorPrivate::autoDetectCMake() QString error; const QStringList candidates = {"cmake"}; for (const QString &candidate : candidates) { - const FilePath cmake = m_device->searchInPath(FilePath::fromString(candidate)); - if (cmake.isExecutableFile()) { + const FilePath cmake = m_device->searchExecutableInPath(candidate); + if (!cmake.isEmpty()) { emit q->logOutput(tr("Found CMake binary: %1").arg(cmake.toUserOutput())); const bool res = QMetaObject::invokeMethod(cmakeManager, "registerCMakeByPath", @@ -1046,35 +1046,6 @@ FilePath DockerDevice::symLinkTarget(const FilePath &filePath) const return {}; } -FilePath DockerDevice::searchInPath(const FilePath &filePath, const FilePaths &additionalDirs) const -{ - QTC_ASSERT(handlesFile(filePath), return {}); - tryCreateLocalFileAccess(); - - const QString path = filePath.path(); - - // FIXME: Check whether local search via deviceEnvironment/PATH is faster? - CommandLine dcmd{"docker", {"exec", d->m_container, "which", path}}; - QtcProcess proc; - proc.setCommand(dcmd); - proc.start(); - proc.waitForFinished(); - - LOG("Run sync:" << dcmd.toUserOutput() << " result: " << proc.exitCode()); - if (proc.exitCode() == 0) { - const QString output = proc.stdOut().trimmed(); - return mapToGlobalPath(FilePath::fromString(output)); - } - - for (const FilePath &dir : additionalDirs) { - const FilePath candidate = dir / filePath.path(); - if (candidate.exists()) - return candidate; - } - - return {}; -} - FilePaths DockerDevice::directoryEntries(const FilePath &filePath, const QStringList &nameFilters, QDir::Filters filters, diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h index 0c994e73082..471d5f80273 100644 --- a/src/plugins/docker/dockerdevice.h +++ b/src/plugins/docker/dockerdevice.h @@ -88,8 +88,6 @@ public: bool removeRecursively(const Utils::FilePath &filePath) const override; bool copyFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const override; bool renameFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const override; - Utils::FilePath searchInPath(const Utils::FilePath &filePath, - const Utils::FilePaths &additionalDirs) const override; Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override; QList directoryEntries(const Utils::FilePath &filePath, const QStringList &nameFilters, diff --git a/src/plugins/nim/project/nimtoolchainfactory.cpp b/src/plugins/nim/project/nimtoolchainfactory.cpp index 7876cd30a68..b55a9e9119b 100644 --- a/src/plugins/nim/project/nimtoolchainfactory.cpp +++ b/src/plugins/nim/project/nimtoolchainfactory.cpp @@ -58,7 +58,7 @@ QList NimToolChainFactory::autoDetect(const QList &alr QList result; IDevice::ConstPtr dev = device ? device : DeviceManager::defaultDesktopDevice(); - const FilePath compilerPath = dev->searchInPath(FilePath::fromString("nim")); + const FilePath compilerPath = dev->searchExecutableInPath("nim"); if (compilerPath.isEmpty()) return result; diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp index 3d7439522dd..6bf8249695c 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp @@ -458,10 +458,10 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_uniquerenameFile(filePath, target); }; - deviceHooks.searchInPath = [](const FilePath &filePath, const FilePaths &additionalDirs) { + deviceHooks.searchInPath = [](const FilePath &filePath, const FilePaths &dirs) { auto device = DeviceManager::deviceForPath(filePath); QTC_ASSERT(device, return FilePath{}); - return device->searchInPath(filePath, additionalDirs); + return device->searchExecutable(filePath.path(), dirs); }; deviceHooks.symLinkTarget = [](const FilePath &filePath) { diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index d51040d5862..1913d786f74 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -311,9 +311,24 @@ bool IDevice::renameFile(const FilePath &filePath, const FilePath &target) const return false; } -FilePath IDevice::searchInPath(const FilePath &filePath, const FilePaths &additionalDirs) const +FilePath IDevice::searchExecutableInPath(const QString &fileName) const { - return Environment::systemEnvironment().searchInPath(filePath.path()); + FilePaths paths; + for (const FilePath &path : systemEnvironment().path()) + paths.append(mapToGlobalPath(path)); + return searchExecutable(fileName, paths); +} + +FilePath IDevice::searchExecutable(const QString &fileName, const FilePaths &dirs) const +{ + for (const FilePath &dir : dirs) { + QTC_CHECK(handlesFile(dir)); + const FilePath candidate = dir / fileName; + if (isExecutableFile(candidate)) + return candidate; + } + + return {}; } FilePath IDevice::symLinkTarget(const FilePath &filePath) const diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h index d5ad9858ad0..9e323e21944 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.h +++ b/src/plugins/projectexplorer/devicesupport/idevice.h @@ -249,8 +249,9 @@ public: virtual bool removeRecursively(const Utils::FilePath &filePath) const; virtual bool copyFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const; virtual bool renameFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const; - virtual Utils::FilePath searchInPath(const Utils::FilePath &filePath, - const QList &additionalDirs = {}) const; + virtual Utils::FilePath searchExecutableInPath(const QString &fileName) const; + virtual Utils::FilePath searchExecutable(const QString &fileName, + const QList &dirs) const; virtual Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const; virtual QList directoryEntries(const Utils::FilePath &filePath, const QStringList &nameFilters, From b998ad621bdecd056f554af4db16dba8338d6cd9 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 6 Jul 2021 14:15:29 +0200 Subject: [PATCH 08/26] Wasm: Some steps towards making it work on docker To start using the docker bits the emsdk location has to be specified manually in the path selector as docker:/// Change-Id: I70c6e7a334762953c3931105b7f697c608523159 Reviewed-by: Alessandro Portale --- src/plugins/projectexplorer/abi.cpp | 10 +++-- .../projectexplorer/devicesupport/idevice.cpp | 4 +- src/plugins/webassembly/webassemblyemsdk.cpp | 42 +++++++++---------- .../webassembly/webassemblyoptionspage.cpp | 2 +- .../webassembly/webassemblytoolchain.cpp | 25 +++++------ 5 files changed, 44 insertions(+), 39 deletions(-) diff --git a/src/plugins/projectexplorer/abi.cpp b/src/plugins/projectexplorer/abi.cpp index 0fa05caf3b2..0582fb4d3aa 100644 --- a/src/plugins/projectexplorer/abi.cpp +++ b/src/plugins/projectexplorer/abi.cpp @@ -1168,11 +1168,8 @@ Abis Abi::abisOfBinary(const Utils::FilePath &path) && getUint8(data, 6) == '>' && getUint8(data, 7) == 0x0a) { // We got an ar file: possibly a static lib for ELF, PE or Mach-O - // FIXME: Implement remote - QTC_ASSERT(!path.needsDevice(), return tmp); QFile f(path.toString()); - if (!f.open(QFile::ReadOnly)) - return tmp; + const bool canRead = f.open(QFile::ReadOnly); data = data.mid(8); // Cut of ar file magic quint64 offset = 8; @@ -1199,6 +1196,11 @@ Abis Abi::abisOfBinary(const Utils::FilePath &path) if (!tmp.isEmpty() && tmp.at(0).binaryFormat() != MachOFormat) break; + if (!canRead) { + // FIXME: Implement remote + QTC_ASSERT(!path.needsDevice(), return {}); + } + offset += (offset % 2); // ar is 2 byte aligned f.seek(offset); data = f.read(1024); diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index 1913d786f74..bb6219dc666 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -321,7 +321,9 @@ FilePath IDevice::searchExecutableInPath(const QString &fileName) const FilePath IDevice::searchExecutable(const QString &fileName, const FilePaths &dirs) const { - for (const FilePath &dir : dirs) { + for (FilePath dir : dirs) { + if (!handlesFile(dir)) // Allow device-local dirs to be used. + dir = mapToGlobalPath(dir); QTC_CHECK(handlesFile(dir)); const FilePath candidate = dir / fileName; if (isExecutableFile(candidate)) diff --git a/src/plugins/webassembly/webassemblyemsdk.cpp b/src/plugins/webassembly/webassemblyemsdk.cpp index 5997c83f06d..60ea1a74d2f 100644 --- a/src/plugins/webassembly/webassemblyemsdk.cpp +++ b/src/plugins/webassembly/webassemblyemsdk.cpp @@ -43,35 +43,36 @@ using namespace Utils; namespace WebAssembly { namespace Internal { -using EmSdkEnvCache = QCache; +using EmSdkEnvCache = QCache; Q_GLOBAL_STATIC_WITH_ARGS(EmSdkEnvCache, emSdkEnvCache, (10)) using EmSdkVersionCache = QCache; Q_GLOBAL_STATIC_WITH_ARGS(EmSdkVersionCache, emSdkVersionCache, (10)) -static QByteArray emSdkEnvOutput(const FilePath &sdkRoot) +static QString emSdkEnvOutput(const FilePath &sdkRoot) { const QString cacheKey = sdkRoot.toString(); + const bool isWindows = sdkRoot.osType() == OsTypeWindows; if (!emSdkEnvCache()->contains(cacheKey)) { const QString scriptFile = sdkRoot.pathAppended(QLatin1String("emsdk_env") + - (HostOsInfo::isWindowsHost() ? ".bat" : ".sh")).toString(); + (isWindows ? ".bat" : ".sh")).path(); QtcProcess emSdkEnv; - if (HostOsInfo::isWindowsHost()) { + if (isWindows) { emSdkEnv.setCommand(CommandLine(scriptFile)); } else { // File needs to be source'd, not executed. - emSdkEnv.setCommand({"bash", {"-c", ". " + scriptFile}}); + emSdkEnv.setCommand({FilePath::fromString("bash").onDevice(sdkRoot), + {"-c", ". " + scriptFile}}); } - emSdkEnv.start(); - if (!emSdkEnv.waitForFinished()) - return {}; - emSdkEnvCache()->insert(cacheKey, new QByteArray(emSdkEnv.readAllStandardError())); + emSdkEnv.runBlocking(); + const QString output = emSdkEnv.allOutput(); + emSdkEnvCache()->insert(cacheKey, new QString(output)); } return *emSdkEnvCache()->object(cacheKey); } -static void parseEmSdkEnvOutputAndAddToEnv(const QByteArray &output, Environment &env) +static void parseEmSdkEnvOutputAndAddToEnv(const QString &output, Environment &env) { - const QStringList lines = QString::fromLocal8Bit(output).split('\n'); + const QStringList lines = output.split('\n'); for (const QString &line : lines) { const QStringList prependParts = line.trimmed().split(" += "); @@ -104,18 +105,17 @@ QVersionNumber WebAssemblyEmSdk::version(const FilePath &sdkRoot) return {}; const QString cacheKey = sdkRoot.toString(); if (!emSdkVersionCache()->contains(cacheKey)) { - Environment env = Environment::systemEnvironment(); + Environment env; WebAssemblyEmSdk::addToEnvironment(sdkRoot, env); - const QString scriptFile = - QLatin1String("emcc") + QLatin1String(HostOsInfo::isWindowsHost() ? ".bat" : ""); - const CommandLine command(env.searchInPath(scriptFile), {"-dumpversion"}); + QLatin1String scriptFile{sdkRoot.osType() == OsType::OsTypeWindows ? "emcc.bat" : "emcc"}; + FilePath script = + FilePath::fromString(scriptFile).onDevice(sdkRoot).searchOnDevice(env.path()); + const CommandLine command(script, {"-dumpversion"}); QtcProcess emcc; emcc.setCommand(command); emcc.setEnvironment(env); - emcc.start(); - if (!emcc.waitForFinished()) - return {}; - const QString version = QLatin1String(emcc.readAllStandardOutput()); + emcc.runBlocking(); + const QString version = emcc.stdOut(); emSdkVersionCache()->insert(cacheKey, new QVersionNumber(QVersionNumber::fromString(version))); } @@ -148,7 +148,7 @@ void WebAssemblyEmSdk::clearCaches() void WebAssemblyPlugin::testEmSdkEnvParsing() { // Output of "emsdk_env" - const QByteArray emSdkEnvOutput = HostOsInfo::isWindowsHost() ? + const QString emSdkEnvOutput = QString::fromLatin1(HostOsInfo::isWindowsHost() ? R"( Adding directories to PATH: PATH += C:\Users\user\dev\emsdk @@ -177,7 +177,7 @@ EMSDK = /home/user/dev/emsdk EM_CONFIG = /home/user/dev/emsdk/.emscripten EM_CACHE = /home/user/dev/emsdk/upstream/emscripten/cache EMSDK_NODE = /home/user/dev/emsdk/node/12.18.1_64bit/bin/node - )"; + )"); Environment env; parseEmSdkEnvOutputAndAddToEnv(emSdkEnvOutput, env); diff --git a/src/plugins/webassembly/webassemblyoptionspage.cpp b/src/plugins/webassembly/webassemblyoptionspage.cpp index 209db2ef430..67c037ee13d 100644 --- a/src/plugins/webassembly/webassemblyoptionspage.cpp +++ b/src/plugins/webassembly/webassemblyoptionspage.cpp @@ -129,7 +129,7 @@ static QString environmentDisplay(const FilePath &sdkRoot) WebAssemblyEmSdk::addToEnvironment(sdkRoot, env); QString result; result.append(WebAssemblyOptionsWidget::tr("

Adding directories to PATH:

")); - result.append(env.value("PATH").replace(HostOsInfo::pathListSeparator(), "
")); + result.append(env.value("PATH").replace(OsSpecificAspects::pathListSeparator(sdkRoot.osType()), "
")); result.append(WebAssemblyOptionsWidget::tr("

Setting environment variables:

")); for (const QString &envVar : env.toStringList()) { if (!envVar.startsWith("PATH")) // Path was already printed out above diff --git a/src/plugins/webassembly/webassemblytoolchain.cpp b/src/plugins/webassembly/webassemblytoolchain.cpp index f83189efce6..d0020cb6fde 100644 --- a/src/plugins/webassembly/webassemblytoolchain.cpp +++ b/src/plugins/webassembly/webassemblytoolchain.cpp @@ -27,20 +27,20 @@ #include "webassemblyconstants.h" #include "webassemblyemsdk.h" +#include #include #include #include #include + #include + #include #include #include #include #include -#include -#include - using namespace ProjectExplorer; using namespace QtSupport; using namespace Utils; @@ -73,7 +73,7 @@ static void addRegisteredMinGWToEnvironment(Environment &env) void WebAssemblyToolChain::addToEnvironment(Environment &env) const { WebAssemblyEmSdk::addToEnvironment(WebAssemblyEmSdk::registeredEmSdk(), env); - if (HostOsInfo::isWindowsHost()) + if (env.osType() == OsTypeWindows) addRegisteredMinGWToEnvironment(env); } @@ -88,9 +88,9 @@ WebAssemblyToolChain::WebAssemblyToolChain() : FilePath WebAssemblyToolChain::makeCommand(const Environment &environment) const { // Diverged duplicate of ClangToolChain::makeCommand and MingwToolChain::makeCommand - const QStringList makes - = HostOsInfo::isWindowsHost() ? QStringList({"mingw32-make.exe", "make.exe"}) - : QStringList({"make"}); + const QStringList makes = environment.osType() == OsTypeWindows + ? QStringList({"mingw32-make.exe", "make.exe"}) + : QStringList({"make"}); FilePath tmp; for (const QString &make : makes) { @@ -162,13 +162,12 @@ QList WebAssemblyToolChainFactory::autoDetect( const IDevice::Ptr &device) { Q_UNUSED(alreadyKnown) - Q_UNUSED(device) const FilePath sdk = WebAssemblyEmSdk::registeredEmSdk(); if (!WebAssemblyEmSdk::isValid(sdk)) return {}; - Environment env; + Environment env = sdk.deviceEnvironment(); WebAssemblyEmSdk::addToEnvironment(sdk, env); QList result; @@ -178,9 +177,11 @@ QList WebAssemblyToolChainFactory::autoDetect( toolChain->setLanguage(languageId); toolChain->setDetection(ToolChain::AutoDetection); const bool cLanguage = languageId == ProjectExplorer::Constants::C_LANGUAGE_ID; - const QString scriptFile = QLatin1String(cLanguage ? "emcc" : "em++") - + QLatin1String(HostOsInfo::isWindowsHost() ? ".bat" : ""); - toolChain->setCompilerCommand(env.searchInPath(scriptFile)); + const QString script = QLatin1String(cLanguage ? "emcc" : "em++") + + QLatin1String(sdk.osType() == OsTypeWindows ? ".bat" : ""); + const FilePath scriptFile = + FilePath::fromString(script).onDevice(sdk).searchOnDevice(env.path()); + toolChain->setCompilerCommand(scriptFile); const QString displayName = WebAssemblyToolChain::tr("Emscripten Compiler %1 for %2") .arg(toolChain->version(), QLatin1String(cLanguage ? "C" : "C++")); From c08f8fa15564fb66950e8a965703ae9fa65ceef0 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Tue, 6 Jul 2021 10:22:17 +0200 Subject: [PATCH 09/26] QmlDesigner: Fix AnimationSection layout * Fix AnimationSeciton missing SecondColumnLayout * Fix QML Connections deprecation warning by using function syntax Change-Id: I2a34b94b3e07397eb42984dd851b1cc7c6adca9d Reviewed-by: Tim Jenssen --- .../QtQuick/AnimationSection.qml | 18 +++++++++++------- .../HelperWidgets/ExtendedFunctionLogic.qml | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml index e671c73165b..b4dfe0f7a5a 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml @@ -153,16 +153,20 @@ Section { visible: section.showEasingCurve } - BoolButtonRowButton { - visible: section.showEasingCurve - buttonIcon: StudioTheme.Constants.curveDesigner + SecondColumnLayout { + BoolButtonRowButton { + visible: section.showEasingCurve + buttonIcon: StudioTheme.Constants.curveDesigner - EasingCurveEditor { - id: easingCurveEditor - modelNodeBackendProperty: modelNodeBackend + EasingCurveEditor { + id: easingCurveEditor + modelNodeBackendProperty: modelNodeBackend + } + + onClicked: easingCurveEditor.runDialog() } - onClicked: easingCurveEditor.runDialog() + ExpandingSpacer {} } } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml index 94308e63b3b..d3b6a9deeca 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml @@ -97,7 +97,7 @@ Item { Connections { target: modelNodeBackend - onSelectionChanged: menu.close() + function onSelectionChanged() { menu.close() } } StudioControls.MenuItem { From e8e32894cc50c3bda0ff1ace77b2735c042985dd Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Tue, 6 Jul 2021 10:20:57 +0200 Subject: [PATCH 10/26] QmlDesigner: Update EditableListView * Apply new design to EditableListView * Add hovered property to IconIndicator Change-Id: Ie208d4de8fab8f7ca62856d80d1ad1decc609f1a Reviewed-by: Tim Jenssen --- .../HelperWidgets/EditableListView.qml | 340 +++++++++--------- .../imports/HelperWidgets/IconIndicator.qml | 2 + 2 files changed, 182 insertions(+), 160 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/EditableListView.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/EditableListView.qml index f7273cb5d43..7f34034246a 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/EditableListView.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/EditableListView.qml @@ -28,170 +28,212 @@ import QtQuick.Layouts 1.15 import StudioControls 1.0 as StudioControls import StudioTheme 1.0 as StudioTheme -Rectangle { +Item { id: editableListView - property variant backendValue - ExtendedFunctionLogic { id: extFuncLogic backendValue: editableListView.backendValue } + property var backendValue property var model onModelChanged: myRepeater.updateModel() + property alias actionIndicator: actionIndicator + property alias actionIndicatorVisible: actionIndicator.visible + property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth + property real __actionIndicatorHeight: StudioTheme.Values.height + property string typeFilter: "QtQuick3D.Material" + property int activatedReason: ComboBox.ActivatedReason.Other + + property bool delegateHover: false + signal add(string value) signal remove(int idx) signal replace(int idx, string value) - property alias actionIndicator: actionIndicator - - property alias actionIndicatorVisible: actionIndicator.visible - property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth - property real __actionIndicatorHeight: StudioTheme.Values.height - - property string typeFilter: "QtQuick3D.Material" - - property int activatedReason: ComboBox.ActivatedReason.Other - - color: "transparent" - border.color: StudioTheme.Values.themeControlOutline - border.width: StudioTheme.Values.border - Layout.preferredWidth: StudioTheme.Values.height * 10 Layout.preferredHeight: myColumn.height Component { id: myDelegate - ListViewComboBox { - id: itemFilterComboBox - - property int myIndex: index - property bool empty: itemFilterComboBox.initialModelData === "" - - validator: RegExpValidator { regExp: /(^[a-z_]\w*|^[A-Z]\w*\.{1}([a-z_]\w*\.?)+)/ } - - actionIndicatorVisible: false - typeFilter: editableListView.typeFilter - editText: modelData - initialModelData: modelData - - width: editableListView.width - - onFocusChanged: { - if (itemFilterComboBox.focus) { - myColumn.currentIndex = index - } - - if (itemFilterComboBox.empty && itemFilterComboBox.editText !== "") { - myRepeater.dirty = false - editableListView.add(itemFilterComboBox.editText) - } - } - - onCompressedActivated: { - editableListView.activatedReason = reason - - if (itemFilterComboBox.empty && itemFilterComboBox.editText !== "") { - myRepeater.dirty = false - editableListView.add(itemFilterComboBox.editText) - } else { - editableListView.replace(itemFilterComboBox.myIndex, itemFilterComboBox.editText) - } - } - } - } - - Rectangle { - id: highlightRect - color: "transparent" - border.width: StudioTheme.Values.border - border.color: StudioTheme.Values.themeInteraction - visible: myColumn.currentItem ? myColumn.currentItem.focus : false - x: myColumn.currentItem ? myColumn.currentItem.x : 0 - y: myColumn.currentItem ? myColumn.currentItem.y : 0 - z: 10 - width: myColumn.currentItem ? myColumn.currentItem.width : 0 - height: myColumn.currentItem ? myColumn.currentItem.height : 0 - } - - Column { - id: myColumn - - property int currentIndex: -1 - property Item currentItem - - spacing: -1 - - onCurrentIndexChanged: myColumn.currentItem = myRepeater.itemAt(myColumn.currentIndex) - - Repeater { - id: myRepeater - - property bool dirty: false - property var localModel: [] - - delegate: myDelegate - - onItemAdded: function(index, item) { - if (index === myColumn.currentIndex) - myColumn.currentItem = item - } - - function updateModel() { - var lastIndex = myColumn.currentIndex - myColumn.currentIndex = -1 - myRepeater.localModel = [] - - editableListView.model.forEach(function(item) { - myRepeater.localModel.push(item) - }); - - // if list view is still dirty, then last state had an unfinished/empty ComboBox - if (myRepeater.dirty) - myRepeater.localModel.push("") - - myRepeater.model = myRepeater.localModel // trigger on change handler - - if (lastIndex < 0 && myRepeater.localModel.length > 0) - myColumn.currentIndex = 0 - else if (myRepeater.localModel.length > lastIndex) - myColumn.currentIndex = lastIndex - else - myColumn.currentIndex = myRepeater.localModel.length - 1 - - if (editableListView.activatedReason === ComboBox.ActivatedReason.Other) - myColumn.currentItem.forceActiveFocus() - } - } - - Item { - id: dummyItem - visible: myRepeater.count === 0 - width: StudioTheme.Values.height - height: StudioTheme.Values.height - } Row { - id: row - spacing: -StudioTheme.Values.border + property alias comboBox: itemFilterComboBox + ListViewComboBox { + id: itemFilterComboBox - StudioControls.ActionIndicator { - id: actionIndicator - width: actionIndicator.visible ? __actionIndicatorWidth : 0 - height: actionIndicator.visible ? __actionIndicatorHeight : 0 + property int myIndex: index + property bool empty: itemFilterComboBox.initialModelData === "" - border.width: StudioTheme.Values.border - border.color: StudioTheme.Values.themeControlOutline + validator: RegExpValidator { regExp: /(^[a-z_]\w*|^[A-Z]\w*\.{1}([a-z_]\w*\.?)+)/ } - icon.color: extFuncLogic.color - icon.text: extFuncLogic.glyph - onClicked: extFuncLogic.show() + actionIndicatorVisible: false + typeFilter: editableListView.typeFilter + editText: modelData + initialModelData: modelData + implicitWidth: StudioTheme.Values.singleControlColumnWidth + width: implicitWidth + + onFocusChanged: { + if (itemFilterComboBox.focus) + myColumn.currentIndex = index + + if (itemFilterComboBox.empty && itemFilterComboBox.editText !== "") { + myRepeater.dirty = false + editableListView.add(itemFilterComboBox.editText) + } + } + + onCompressedActivated: { + editableListView.activatedReason = reason + + if (itemFilterComboBox.empty && itemFilterComboBox.editText !== "") { + myRepeater.dirty = false + editableListView.add(itemFilterComboBox.editText) + } else { + editableListView.replace(itemFilterComboBox.myIndex, itemFilterComboBox.editText) + } + } + + onHoverChanged: editableListView.delegateHover = itemFilterComboBox.hover } + + Spacer { implicitWidth: StudioTheme.Values.twoControlColumnGap } + + IconIndicator { + id: closeIndicator + icon: StudioTheme.Constants.closeCross + onClicked: { + var lastItem = index === myRepeater.localModel.length - 1 + if (myColumn.currentItem.initialModelData === "") { + myRepeater.localModel.pop() + myRepeater.dirty = false + myRepeater.model = myRepeater.localModel // trigger on change handler + } else { + editableListView.remove(index) + } + if (!lastItem) + myColumn.currentIndex = index - 1 + } + onHoveredChanged: editableListView.delegateHover = closeIndicator.hovered + } + } + } + + Row { + ActionIndicator { + id: actionIndicator + icon.visible: editableListView.delegateHover + icon.color: extFuncLogic.color + icon.text: extFuncLogic.glyph + onClicked: extFuncLogic.show() + } + + Column { + id: myColumn + + property int currentIndex: -1 + property Item currentItem + + spacing: StudioTheme.Values.sectionRowSpacing + + onCurrentIndexChanged: { + var tmp = myRepeater.itemAt(myColumn.currentIndex) + if (tmp !== null) + myColumn.currentItem = tmp.comboBox + } + + Repeater { + id: myRepeater + + property bool dirty: false + property var localModel: [] + + delegate: myDelegate + + onItemAdded: function(index, item) { + if (index === myColumn.currentIndex) + myColumn.currentItem = item + } + + function updateModel() { + var lastIndex = myColumn.currentIndex + myColumn.currentIndex = -1 + myRepeater.localModel = [] + + editableListView.model.forEach(function(item) { + myRepeater.localModel.push(item) + }); + + // if list view is still dirty, then last state had an unfinished/empty ComboBox + if (myRepeater.dirty) + myRepeater.localModel.push("") + + myRepeater.model = myRepeater.localModel // trigger on change handler + + if (lastIndex < 0 && myRepeater.localModel.length > 0) + myColumn.currentIndex = 0 + else if (myRepeater.localModel.length > lastIndex) + myColumn.currentIndex = lastIndex + else + myColumn.currentIndex = myRepeater.localModel.length - 1 + + if (editableListView.activatedReason === ComboBox.ActivatedReason.Other + && myColumn.currentItem !== null) + myColumn.currentItem.forceActiveFocus() + } + } + + ListViewComboBox { + id: dummyComboBox + + //property int myIndex: index + //property bool empty: dummyComboBox.initialModelData === "" + + visible: myRepeater.count === 0 + + validator: RegExpValidator { regExp: /(^[a-z_]\w*|^[A-Z]\w*\.{1}([a-z_]\w*\.?)+)/ } + + actionIndicatorVisible: false + typeFilter: editableListView.typeFilter + //editText: modelData + //initialModelData: modelData + implicitWidth: StudioTheme.Values.singleControlColumnWidth + width: implicitWidth + + onFocusChanged: { + //if (itemFilterComboBox.focus) + // myColumn.currentIndex = index + + if (/*dummyComboBox.empty && */dummyComboBox.editText !== "") { + //myRepeater.dirty = false + editableListView.add(dummyComboBox.editText) + } + } + + onCompressedActivated: { + editableListView.activatedReason = reason + + if (/*dummyComboBox.empty && */dummyComboBox.editText !== "") { + //myRepeater.dirty = false + editableListView.add(dummyComboBox.editText) + } else { + editableListView.replace(dummyComboBox.myIndex, dummyComboBox.editText) + } + } + + onHoverChanged: editableListView.delegateHover = dummyComboBox.hover + } + + + StudioControls.AbstractButton { + id: plusButton buttonIcon: StudioTheme.Constants.plus - enabled: !myRepeater.dirty && !(editableListView.backendValue.isInModel && !editableListView.backendValue.isIdList) + enabled: !myRepeater.dirty && !(editableListView.backendValue.isInModel + && !editableListView.backendValue.isIdList) onClicked: { var idx = myRepeater.localModel.push("") - 1 myRepeater.model = myRepeater.localModel // trigger on change handler @@ -199,29 +241,7 @@ Rectangle { myColumn.currentIndex = idx myColumn.currentItem.forceActiveFocus() } - } - StudioControls.AbstractButton { - buttonIcon: StudioTheme.Constants.minus - enabled: myRepeater.model.length && !(editableListView.backendValue.isInModel && !editableListView.backendValue.isIdList) - onClicked: { - var lastItem = myColumn.currentIndex === myRepeater.localModel.length - 1 - if (myColumn.currentItem.initialModelData === "") { - myRepeater.localModel.pop() - myRepeater.dirty = false - myRepeater.model = myRepeater.localModel // trigger on change handler - } else { - editableListView.remove(myColumn.currentIndex) - } - if (!lastItem) - myColumn.currentIndex = myColumn.currentIndex - 1 - } - } - Rectangle { - color: StudioTheme.Values.themeControlBackground - border.width: StudioTheme.Values.border - border.color: StudioTheme.Values.themeControlOutline - height: StudioTheme.Values.height - width: editableListView.width - (StudioTheme.Values.height - StudioTheme.Values.border) * (actionIndicatorVisible ? 3 : 2) + onHoveredChanged: editableListView.delegateHover = plusButton.hovered } } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/IconIndicator.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/IconIndicator.qml index 4a1487f4eaa..235f3796136 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/IconIndicator.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/IconIndicator.qml @@ -37,6 +37,8 @@ Rectangle { property alias pixelSize: indicatorIcon.font.pixelSize property alias tooltip: toolTipArea.tooltip + property bool hovered: toolTipArea.containsMouse && root.enabled + signal clicked() color: "transparent" From ed199da1dfc035c26ee3674ce8f1f7fcd7412327 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 7 Jul 2021 07:42:47 +0200 Subject: [PATCH 11/26] LanguageClient: update outline after document Do not react on documents contents changes, but postpone the document symbol request after these document changes were send to the server. Change-Id: I43ec8f832c6a1fa6471146a5ec6e3e9223b02c91 Reviewed-by: Christian Kandeler --- src/plugins/languageclient/languageclientoutline.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/plugins/languageclient/languageclientoutline.cpp b/src/plugins/languageclient/languageclientoutline.cpp index 4257efb1ff8..a9c3bf5b8b6 100644 --- a/src/plugins/languageclient/languageclientoutline.cpp +++ b/src/plugins/languageclient/languageclientoutline.cpp @@ -283,7 +283,7 @@ private: void updateModel(const DocumentUri &resultUri, const DocumentSymbolsResult &result); void updateEntry(); void activateEntry(); - void requestSymbols(); + void documentUpdated(TextEditor::TextDocument *document); LanguageClientOutlineModel m_model; QPointer m_client; @@ -318,13 +318,12 @@ OutlineComboBox::OutlineComboBox(Client *client, TextEditor::BaseTextEditor *edi connect(client->documentSymbolCache(), &DocumentSymbolCache::gotSymbols, this, &OutlineComboBox::updateModel); - connect(editor->textDocument(), &TextEditor::TextDocument::contentsChanged, - this, &OutlineComboBox::requestSymbols); + connect(client, &Client::documentUpdated, this, &OutlineComboBox::documentUpdated); connect(m_editorWidget, &TextEditor::TextEditorWidget::cursorPositionChanged, this, &OutlineComboBox::updateEntry); connect(this, QOverload::of(&QComboBox::activated), this, &OutlineComboBox::activateEntry); - requestSymbols(); + documentUpdated(editor->textDocument()); } void OutlineComboBox::updateModel(const DocumentUri &resultUri, const DocumentSymbolsResult &result) @@ -365,9 +364,9 @@ void OutlineComboBox::activateEntry() } } -void OutlineComboBox::requestSymbols() +void OutlineComboBox::documentUpdated(TextEditor::TextDocument *document) { - if (m_client) + if (document == m_editorWidget->textDocument()) m_client->documentSymbolCache()->requestSymbols(m_uri); } From 4767dfcce32ca69d88861f5ab8a18b0a1110b0b4 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 8 Jul 2021 13:01:36 +0200 Subject: [PATCH 12/26] qmake: Fix issues with executing system calls Do not try to reuse the QFutureInterface that is used for the parsing process. Reusing the QFutureInterface can lead to issues. So far no problems were triggered, but a30aa4421a0257b048197b51330e6bf5c2732af5 introduced a watcher that tells the qmake parser to ignore all system calls after the future was canceled. This was somehow, sometimes triggered on the reused QFutureInterface even though the user didn't cancel anyhing, leading to all system calls to bail out in the subsequent run. Using a new QFutureInterface instance for each parsing run solves the issue. Amends a30aa4421a0257b048197b51330e6bf5c2732af5 Fixes: QTCREATORBUG-25970 Change-Id: I6836c97038c36968e93815c6121bc284edbe19bb Reviewed-by: Christian Kandeler --- .../qmakeprojectmanager/qmakeproject.cpp | 34 ++++++++++++------- .../qmakeprojectmanager/qmakeproject.h | 2 +- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 387c0688a4b..f62398a315c 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -284,8 +284,11 @@ QmakeBuildSystem::~QmakeBuildSystem() delete m_qmakeVfs; m_qmakeVfs = nullptr; - m_asyncUpdateFutureInterface.reportCanceled(); - m_asyncUpdateFutureInterface.reportFinished(); + if (m_asyncUpdateFutureInterface) { + m_asyncUpdateFutureInterface->reportCanceled(); + m_asyncUpdateFutureInterface->reportFinished(); + m_asyncUpdateFutureInterface.reset(); + } } void QmakeBuildSystem::updateCodeModels() @@ -592,8 +595,9 @@ void QmakeBuildSystem::incrementPendingEvaluateFutures() } ++m_pendingEvaluateFuturesCount; TRACE("pending inc to: " << m_pendingEvaluateFuturesCount); - m_asyncUpdateFutureInterface.setProgressRange(m_asyncUpdateFutureInterface.progressMinimum(), - m_asyncUpdateFutureInterface.progressMaximum() + 1); + m_asyncUpdateFutureInterface->setProgressRange(m_asyncUpdateFutureInterface->progressMinimum(), + m_asyncUpdateFutureInterface->progressMaximum() + + 1); } void QmakeBuildSystem::decrementPendingEvaluateFutures() @@ -606,15 +610,17 @@ void QmakeBuildSystem::decrementPendingEvaluateFutures() return; // We are closing the project! } - m_asyncUpdateFutureInterface.setProgressValue(m_asyncUpdateFutureInterface.progressValue() + 1); + m_asyncUpdateFutureInterface->setProgressValue(m_asyncUpdateFutureInterface->progressValue() + + 1); if (m_pendingEvaluateFuturesCount == 0) { // We are done! setRootProjectNode(QmakeNodeTreeBuilder::buildTree(this)); if (!m_rootProFile->validParse()) - m_asyncUpdateFutureInterface.reportCanceled(); + m_asyncUpdateFutureInterface->reportCanceled(); - m_asyncUpdateFutureInterface.reportFinished(); + m_asyncUpdateFutureInterface->reportFinished(); + m_asyncUpdateFutureInterface.reset(); m_cancelEvaluate = false; // TODO clear the profile cache ? @@ -660,12 +666,13 @@ void QmakeBuildSystem::asyncUpdate() m_qmakeVfs->invalidateCache(); } - m_asyncUpdateFutureInterface.setProgressRange(0, 0); - Core::ProgressManager::addTask(m_asyncUpdateFutureInterface.future(), + m_asyncUpdateFutureInterface.reset(new QFutureInterface); + m_asyncUpdateFutureInterface->setProgressRange(0, 0); + Core::ProgressManager::addTask(m_asyncUpdateFutureInterface->future(), tr("Reading Project \"%1\"").arg(project()->displayName()), Constants::PROFILE_EVALUATE); - m_asyncUpdateFutureInterface.reportStarted(); + m_asyncUpdateFutureInterface->reportStarted(); const auto watcher = new QFutureWatcher(this); connect(watcher, &QFutureWatcher::canceled, this, [this, watcher] { if (!m_qmakeGlobals) @@ -677,7 +684,7 @@ void QmakeBuildSystem::asyncUpdate() watcher->disconnect(); watcher->deleteLater(); }); - watcher->setFuture(m_asyncUpdateFutureInterface.future()); + watcher->setFuture(m_asyncUpdateFutureInterface->future()); const Kit *const k = kit(); QtSupport::BaseQtVersion *const qtVersion = QtSupport::QtKitAspect::qtVersion(k); @@ -688,8 +695,9 @@ void QmakeBuildSystem::asyncUpdate() .arg(project()->displayName(), k->displayName()) : tr("Cannot parse project \"%1\": No kit selected.").arg(project()->displayName()); proFileParseError(errorMessage, project()->projectFilePath()); - m_asyncUpdateFutureInterface.reportCanceled(); - m_asyncUpdateFutureInterface.reportFinished(); + m_asyncUpdateFutureInterface->reportCanceled(); + m_asyncUpdateFutureInterface->reportFinished(); + m_asyncUpdateFutureInterface.reset(); return; } diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.h b/src/plugins/qmakeprojectmanager/qmakeproject.h index fba8c8db7a5..89397407abb 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.h +++ b/src/plugins/qmakeprojectmanager/qmakeproject.h @@ -198,7 +198,7 @@ private: QString m_qmakeSysroot; - QFutureInterface m_asyncUpdateFutureInterface; + std::unique_ptr> m_asyncUpdateFutureInterface; int m_pendingEvaluateFuturesCount = 0; AsyncUpdateState m_asyncUpdateState = Base; bool m_cancelEvaluate = false; From d6f717d0f89dbdd1585fba6da3b5e4bb3ff0b5a2 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Thu, 8 Jul 2021 16:48:41 +0200 Subject: [PATCH 13/26] QmlDesigner: Fix blocked/disabled state colors * Fix color controlsBackgroundDisabled color in light themes * Fix color value in RealSpinBoxIndicator state disabled * Remove opacity change in AnchorButtons on enabling/disabling Task-number: QDS-4692 Change-Id: I9adb28f54b8016bfffdd28f022fc746c629afe9f Reviewed-by: Tim Jenssen --- .../imports/HelperWidgets/AnchorButtons.qml | 1 - .../imports/StudioControls/RealSpinBoxIndicator.qml | 2 +- share/qtcreator/themes/default.creatortheme | 2 +- share/qtcreator/themes/design-light.creatortheme | 2 +- share/qtcreator/themes/flat-light.creatortheme | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/AnchorButtons.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/AnchorButtons.qml index 3629ca5ab64..e4eb7108d95 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/AnchorButtons.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/AnchorButtons.qml @@ -32,7 +32,6 @@ StudioControls.ButtonRow { id: buttonRow enabled: anchorBackend.hasParent && isBaseState - opacity: enabled ? 1 : 0.5 actionIndicatorVisible: false StudioControls.ButtonGroup { id: group } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxIndicator.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxIndicator.qml index 9ca34c16802..26373f4db19 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxIndicator.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBoxIndicator.qml @@ -258,7 +258,7 @@ Rectangle { } PropertyChanges { target: spinBoxIndicator - color: StudioTheme.Values.themeControlBackground + color: StudioTheme.Values.themeControlBackgroundDisabled } }, State { diff --git a/share/qtcreator/themes/default.creatortheme b/share/qtcreator/themes/default.creatortheme index 6b856d7f34e..0eb98021ba8 100644 --- a/share/qtcreator/themes/default.creatortheme +++ b/share/qtcreator/themes/default.creatortheme @@ -22,7 +22,7 @@ DSdisabledColor=ff8e8e8e DScontrolBackground=ffeaeaea DScontrolBackgroundInteraction=ffc9c9c9 -DScontrolBackgroundDisabled=ff8e8e8e +DScontrolBackgroundDisabled=ffeaeaea DScontrolBackgroundGlobalHover=ffe5e5e5 DScontrolBackgroundHover=ffd1d1d1 diff --git a/share/qtcreator/themes/design-light.creatortheme b/share/qtcreator/themes/design-light.creatortheme index 17783db3c0c..ef1b7bcbb1b 100644 --- a/share/qtcreator/themes/design-light.creatortheme +++ b/share/qtcreator/themes/design-light.creatortheme @@ -36,7 +36,7 @@ DSdisabledColor=ff8e8e8e DScontrolBackground=ffeaeaea DScontrolBackgroundInteraction=ffc9c9c9 -DScontrolBackgroundDisabled=ff8e8e8e +DScontrolBackgroundDisabled=ffeaeaea DScontrolBackgroundGlobalHover=ffe5e5e5 DScontrolBackgroundHover=ffd1d1d1 diff --git a/share/qtcreator/themes/flat-light.creatortheme b/share/qtcreator/themes/flat-light.creatortheme index 123c680fc6a..1fa9747d3a3 100644 --- a/share/qtcreator/themes/flat-light.creatortheme +++ b/share/qtcreator/themes/flat-light.creatortheme @@ -31,7 +31,7 @@ DSdisabledColor=ff8e8e8e DScontrolBackground=ffeaeaea DScontrolBackgroundInteraction=ffc9c9c9 -DScontrolBackgroundDisabled=ff8e8e8e +DScontrolBackgroundDisabled=ffeaeaea DScontrolBackgroundGlobalHover=ffe5e5e5 DScontrolBackgroundHover=ffd1d1d1 From 2451ba921357644aabf1d76d1745234e9d2700a7 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 8 Jul 2021 12:28:00 +0200 Subject: [PATCH 14/26] Wasm: Test windows and linux parsing simultaneously Change-Id: I25e562258125157b07d1fc1a950b5207abbf5d69 Reviewed-by: Alessandro Portale --- src/plugins/webassembly/webassemblyemsdk.cpp | 44 +++++++++++++------- src/plugins/webassembly/webassemblyplugin.h | 1 + 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/plugins/webassembly/webassemblyemsdk.cpp b/src/plugins/webassembly/webassemblyemsdk.cpp index 60ea1a74d2f..2449dbed7ac 100644 --- a/src/plugins/webassembly/webassemblyemsdk.cpp +++ b/src/plugins/webassembly/webassemblyemsdk.cpp @@ -146,10 +146,31 @@ void WebAssemblyEmSdk::clearCaches() // Unit tests: #ifdef WITH_TESTS void WebAssemblyPlugin::testEmSdkEnvParsing() +{ + QFETCH(QString, emSdkEnvOutput); + QFETCH(int, osType); + QFETCH(int, pathCount); + QFETCH(QString, emsdk); + QFETCH(QString, em_config); + + Environment env{OsType(osType)}; + parseEmSdkEnvOutputAndAddToEnv(emSdkEnvOutput, env); + + QVERIFY(env.path().count() == pathCount); + QCOMPARE(env.value("EMSDK"), emsdk); + QCOMPARE(env.value("EM_CONFIG"), em_config); +} + +void WebAssemblyPlugin::testEmSdkEnvParsing_data() { // Output of "emsdk_env" - const QString emSdkEnvOutput = QString::fromLatin1(HostOsInfo::isWindowsHost() ? - R"( + QTest::addColumn("emSdkEnvOutput"); + QTest::addColumn("osType"); + QTest::addColumn("pathCount"); + QTest::addColumn("emsdk"); + QTest::addColumn("em_config"); + + QTest::newRow("windows") << R"( Adding directories to PATH: PATH += C:\Users\user\dev\emsdk PATH += C:\Users\user\dev\emsdk\upstream\emscripten @@ -165,7 +186,9 @@ EM_CACHE = C:/Users/user/dev/emsdk/upstream/emscripten\cache EMSDK_NODE = C:\Users\user\dev\emsdk\node\12.18.1_64bit\bin\node.exe EMSDK_PYTHON = C:\Users\user\dev\emsdk\python\3.7.4-pywin32_64bit\python.exe JAVA_HOME = C:\Users\user\dev\emsdk\java\8.152_64bit - )" : R"( + )" << int(OsTypeWindows) << 5 << "C:/Users/user/dev/emsdk" << "C:\\Users\\user\\dev\\emsdk\\.emscripten"; + + QTest::newRow("linux") << R"( Adding directories to PATH: PATH += /home/user/dev/emsdk PATH += /home/user/dev/emsdk/upstream/emscripten @@ -177,20 +200,9 @@ EMSDK = /home/user/dev/emsdk EM_CONFIG = /home/user/dev/emsdk/.emscripten EM_CACHE = /home/user/dev/emsdk/upstream/emscripten/cache EMSDK_NODE = /home/user/dev/emsdk/node/12.18.1_64bit/bin/node - )"); - Environment env; - parseEmSdkEnvOutputAndAddToEnv(emSdkEnvOutput, env); - - if (HostOsInfo::isWindowsHost()) { - QVERIFY(env.path().count() == 5); - QCOMPARE(env.value("EMSDK"), "C:/Users/user/dev/emsdk"); - QCOMPARE(env.value("EM_CONFIG"), "C:\\Users\\user\\dev\\emsdk\\.emscripten"); - } else { - QVERIFY(env.path().count() == 3); - QCOMPARE(env.value("EMSDK"), "/home/user/dev/emsdk"); - QCOMPARE(env.value("EM_CONFIG"), "/home/user/dev/emsdk/.emscripten"); - } + )" << int(OsTypeLinux) << 3 << "/home/user/dev/emsdk" << "/home/user/dev/emsdk/.emscripten"; } + #endif // WITH_TESTS } // namespace Internal diff --git a/src/plugins/webassembly/webassemblyplugin.h b/src/plugins/webassembly/webassemblyplugin.h index eedeb89d0a6..c17909542ba 100644 --- a/src/plugins/webassembly/webassemblyplugin.h +++ b/src/plugins/webassembly/webassemblyplugin.h @@ -48,6 +48,7 @@ public: #ifdef WITH_TESTS private slots: void testEmSdkEnvParsing(); + void testEmSdkEnvParsing_data(); #endif // WITH_TESTS }; From 7c56923704e5aaf025e6ef7739322781952b4d7c Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 8 Jul 2021 16:31:36 +0200 Subject: [PATCH 15/26] AutoTest: Fix location information of data tags Broke while moving over to use Utils::FilePath and correcting the varying usages of name. Change-Id: I6099f5f0dbc022d831fef78652932d69bd2e4326 Reviewed-by: David Schulz --- src/plugins/autotest/qtest/qttestparser.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/autotest/qtest/qttestparser.cpp b/src/plugins/autotest/qtest/qttestparser.cpp index 18e0f48ca5e..e6dfb7802a0 100644 --- a/src/plugins/autotest/qtest/qttestparser.cpp +++ b/src/plugins/autotest/qtest/qttestparser.cpp @@ -410,8 +410,7 @@ QtTestParseResult *QtTestParser::createParseResult( dataTag->itemType = tag.m_type; dataTag->name = tag.m_name; dataTag->displayName = tag.m_name; - dataTag->fileName = Utils::FilePath::fromString( - data.testFunctions.value(it.key() + "_data").m_name); + dataTag->fileName = data.testFunctions.value(it.key() + "_data").m_filePath; dataTag->line = tag.m_line; dataTag->column = tag.m_column; dataTag->setInherited(tag.m_inherited); From 355a91f3e16cc03cc81914bb65ef945f40b7b1ab Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 8 Jul 2021 16:56:01 +0200 Subject: [PATCH 16/26] AutoTest: Fix displaying description for XML output CDATA is send in chunks and we lose possible newlines as we handle the output line by line. Add it explicitly while processing. Change-Id: I36bad7f23e2b9b3a5ce9ec92d2d1cb6211dd43a6 Reviewed-by: David Schulz --- src/plugins/autotest/qtest/qttestoutputreader.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/autotest/qtest/qttestoutputreader.cpp b/src/plugins/autotest/qtest/qttestoutputreader.cpp index a15a0fc1d4d..a6be21019d9 100644 --- a/src/plugins/autotest/qtest/qttestoutputreader.cpp +++ b/src/plugins/autotest/qtest/qttestoutputreader.cpp @@ -196,6 +196,8 @@ void QtTestOutputReader::processXMLOutput(const QByteArray &outputLine) break; } } + if (m_cdataMode == Description) + m_xmlReader.addData("\n"); m_xmlReader.addData(QString::fromUtf8(outputLine)); while (!m_xmlReader.atEnd()) { if (m_futureInterface.isCanceled()) From fee0a5a74a48237f11037bf19105be14c3466b29 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 8 Jul 2021 16:46:14 +0200 Subject: [PATCH 17/26] Doc: Describe copying and pasting property values in Design mode Fixes: QDS-4693 Change-Id: I2c1cb5cf1d00738c38a926d70e5b1089ce82880b Reviewed-by: Vikas Pachdha --- doc/qtcreator/images/icons/copy-formatting.png | Bin 0 -> 277 bytes doc/qtcreator/images/icons/paste-formatting.png | Bin 0 -> 243 bytes doc/qtcreator/src/qtquick/qtquick-designer.qdoc | 11 +++++++++++ .../src/qtquick/qtquick-properties.qdoc | 16 ++++++++++++++++ 4 files changed, 27 insertions(+) create mode 100644 doc/qtcreator/images/icons/copy-formatting.png create mode 100644 doc/qtcreator/images/icons/paste-formatting.png diff --git a/doc/qtcreator/images/icons/copy-formatting.png b/doc/qtcreator/images/icons/copy-formatting.png new file mode 100644 index 0000000000000000000000000000000000000000..941e051512df95645487b8cb0a117dd77d4b81cf GIT binary patch literal 277 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7?s&R5hFJ72y=3Ue0k5R@YIv^ z9Y;eid>3S%^N4M;N&ShJmhRSU4gNmdugZ7W+-QzvNS1le{KCU##v|89XWg>-*Ihif zrrh{5>%R*JIPWdo literal 0 HcmV?d00001 diff --git a/doc/qtcreator/images/icons/paste-formatting.png b/doc/qtcreator/images/icons/paste-formatting.png new file mode 100644 index 0000000000000000000000000000000000000000..2bd072071d44148626298d34acae0a6a9ee79792 GIT binary patch literal 243 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7c6quuhFJ7oy=<7p-f>yCz20F%@G+1gr z7#qLeTWRqByhERJt5lbQ_4?p5$!*5dG#7H*c<|oofSu|Uy_i)kItR-Q_|ECpEDHZr zyPWBsp=M#e;QdF>)c<535HGvVvS#it!@~@#19WEHa5sK%``|y({u__P?;0%VOSf4l yc%}QY3fG?p%={8le`vI=`rH3!-!X}!f;Ed(KR>;lIgNpVfx*+&&t;ucLK6U%-e$!B literal 0 HcmV?d00001 diff --git a/doc/qtcreator/src/qtquick/qtquick-designer.qdoc b/doc/qtcreator/src/qtquick/qtquick-designer.qdoc index fcdcf9c31a3..7536e8c7574 100644 --- a/doc/qtcreator/src/qtquick/qtquick-designer.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-designer.qdoc @@ -230,6 +230,17 @@ \li Resets anchors to their saved state for the selected component. \li \key Ctrl+Shift+R (\key Shift+Cmd+R on \macos) \li \l{Setting Anchors and Margins} + \row + \li \inlineimage icons/copy-formatting.png + \li Copies property values from the selected component. + \li + \li \l{Copying and Pasting Formatting} + \row + \li \inlineimage icons/paste-formatting.png + \li Applies copied property values to one or several selected + components. + \li + \li \l{Copying and Pasting Formatting} \row \li \inlineimage row.png \li Uses a \uicontrol Row component to lay out the selected components. diff --git a/doc/qtcreator/src/qtquick/qtquick-properties.qdoc b/doc/qtcreator/src/qtquick/qtquick-properties.qdoc index 75b12c420a5..3a55202b9e9 100644 --- a/doc/qtcreator/src/qtquick/qtquick-properties.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-properties.qdoc @@ -409,6 +409,22 @@ and vertically. Note that some OpenGL ES 2 implementations do not support the \uicontrol Repeat wrap mode with non-power-of-two textures. + \section1 Copying and Pasting Formatting + + You can copy property values from a component and paste them to one or + several other components. The values are applied if the target components + have those particular properties. + + To copy property values from the selected component, select + \inlineimage icons/copy-formatting.png + on the \uicontrol Design mode \l{Summary of Main Toolbar Actions} + {main toolbar}. + + To apply the values to one or several other components, select + them in \l Navigator or \l{Form Editor}, and then select + \inlineimage icons/paste-formatting.png + . + \section1 Editing Properties Inline You can double-click components in \l {Form Editor} to edit their From 1f4826a0c4322f361ab0ad1dafd048061326f5d6 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 8 Jul 2021 14:23:32 +0200 Subject: [PATCH 18/26] ClangCodeModel: Clear existing libclang diagnostics ... when clangd takes over a document. This fixes the problem that temporary diagnostics persisted after opening a session. Change-Id: Ic781f83747cabb4d15c2c1f8181e36f4343e0394 Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangdiagnosticmanager.h | 2 +- .../clangcodemodel/clangeditordocumentprocessor.cpp | 8 ++++++++ src/plugins/clangcodemodel/clangeditordocumentprocessor.h | 2 ++ src/plugins/clangcodemodel/clangmodelmanagersupport.cpp | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/plugins/clangcodemodel/clangdiagnosticmanager.h b/src/plugins/clangcodemodel/clangdiagnosticmanager.h index 5c2ed3c8db4..e3b8537e6a7 100644 --- a/src/plugins/clangcodemodel/clangdiagnosticmanager.h +++ b/src/plugins/clangcodemodel/clangdiagnosticmanager.h @@ -65,11 +65,11 @@ public: static void clearTaskHubIssues(); void generateTaskHubIssues(); + void cleanMarks(); static void addTask(const ClangBackEnd::DiagnosticContainer &diagnostic, bool isChild = false); private: - void cleanMarks(); QString filePath() const; void filterDiagnostics(const QVector &diagnostics); void generateEditorSelections(); diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 8e4a83c7be7..9306d8c67e9 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -251,6 +251,14 @@ void ClangEditorDocumentProcessor::generateTaskHubIssues() m_diagnosticManager.generateTaskHubIssues(); } +void ClangEditorDocumentProcessor::clearTextMarks(const Utils::FilePath &filePath) +{ + if (ClangEditorDocumentProcessor * const proc = get(filePath.toString())) { + proc->m_diagnosticManager.cleanMarks(); + emit proc->codeWarningsUpdated(proc->revision(), {}, {}, {}); + } +} + void ClangEditorDocumentProcessor::updateHighlighting( const QVector &tokenInfos, const QVector &skippedPreprocessorRanges, diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index 90890c47102..bedf3fecafe 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -108,6 +108,8 @@ public: static void clearTaskHubIssues(); void generateTaskHubIssues(); + static void clearTextMarks(const Utils::FilePath &filePath); + public: static ClangEditorDocumentProcessor *get(const QString &filePath); diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 90be3893dfc..1787a0034eb 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -316,6 +316,7 @@ void ClangModelManagerSupport::updateLanguageClient(ProjectExplorer::Project *pr if (!project->isKnownFile(entry->fileName())) continue; client->openDocument(textDocument); + ClangEditorDocumentProcessor::clearTextMarks(textDocument->filePath()); hasDocuments = true; } From f55d5d8ec1d81a6cbcfb224d06312270787a22cd Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 8 Jul 2021 12:00:13 +0200 Subject: [PATCH 19/26] LanguageClient: Do not re-highlight when receiving the error variant ... of a SemanticTokens message. Change-Id: I0f6e55d6656c11e7925e3bc4400ea2e575b9f138 Reviewed-by: David Schulz --- src/plugins/languageclient/semantichighlightsupport.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/plugins/languageclient/semantichighlightsupport.cpp b/src/plugins/languageclient/semantichighlightsupport.cpp index 3aafaf5b42f..ea5adceccd1 100644 --- a/src/plugins/languageclient/semantichighlightsupport.cpp +++ b/src/plugins/languageclient/semantichighlightsupport.cpp @@ -371,11 +371,11 @@ SemanticRequestTypes SemanticTokenSupport::supportedSemanticRequests(TextDocumen void SemanticTokenSupport::handleSemanticTokens(const Utils::FilePath &filePath, const SemanticTokensResult &result) { - if (auto tokens = Utils::get_if(&result)) + if (auto tokens = Utils::get_if(&result)) { m_tokens[filePath] = *tokens; - else - m_tokens.remove(filePath); - highlight(filePath); + highlight(filePath); + } + m_tokens.remove(filePath); } void SemanticTokenSupport::handleSemanticTokensDelta( @@ -427,6 +427,7 @@ void SemanticTokenSupport::handleSemanticTokensDelta( tokens.setResultId(tokensDelta->resultId()); } else { m_tokens.remove(filePath); + return; } highlight(filePath); } From 9a03ce80bb1ed3d8e37e68881530bae122aa32a9 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 8 Jul 2021 09:37:43 +0200 Subject: [PATCH 20/26] ProjectExplorer: Implement FilePath related functions for DesktopDevice Effectively redirecting to the !needsDevice() branches in the respective FileUtils implementation. Change-Id: Ib24f1ff6fe5301323fd1296cc2ffceb0db9e4672 Reviewed-by: Christian Stenger --- .../devicesupport/desktopdevice.cpp | 98 +++++++++++++++++++ .../devicesupport/desktopdevice.h | 18 +++- 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp index a11095435c1..5ee6d5b4bf4 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp @@ -43,6 +43,7 @@ #include #include +#include using namespace ProjectExplorer::Constants; using namespace Utils; @@ -194,4 +195,101 @@ Environment DesktopDevice::systemEnvironment() const return Environment::systemEnvironment(); } +bool DesktopDevice::isExecutableFile(const FilePath &filePath) const +{ + QTC_ASSERT(handlesFile(filePath), return false); + return filePath.isExecutableFile(); +} + +bool DesktopDevice::isReadableFile(const FilePath &filePath) const +{ + QTC_ASSERT(handlesFile(filePath), return false); + return filePath.isReadableFile(); +} + +bool DesktopDevice::isWritableFile(const Utils::FilePath &filePath) const +{ + QTC_ASSERT(handlesFile(filePath), return false); + return filePath.isWritableFile(); +} + +bool DesktopDevice::isReadableDirectory(const FilePath &filePath) const +{ + QTC_ASSERT(handlesFile(filePath), return false); + return filePath.isReadableDir(); +} + +bool DesktopDevice::isWritableDirectory(const FilePath &filePath) const +{ + QTC_ASSERT(handlesFile(filePath), return false); + return filePath.isWritableDir(); +} + +bool DesktopDevice::createDirectory(const FilePath &filePath) const +{ + QTC_ASSERT(handlesFile(filePath), return false); + return filePath.createDir(); +} + +bool DesktopDevice::exists(const FilePath &filePath) const +{ + QTC_ASSERT(handlesFile(filePath), return false); + return filePath.exists(); +} + +bool DesktopDevice::ensureExistingFile(const FilePath &filePath) const +{ + QTC_ASSERT(handlesFile(filePath), return false); + return filePath.ensureExistingFile(); +} + +bool DesktopDevice::removeFile(const FilePath &filePath) const +{ + QTC_ASSERT(handlesFile(filePath), return false); + return filePath.removeFile(); +} + +bool DesktopDevice::removeRecursively(const FilePath &filePath) const +{ + QTC_ASSERT(handlesFile(filePath), return false); + return filePath.removeRecursively(); +} + +bool DesktopDevice::copyFile(const FilePath &filePath, const FilePath &target) const +{ + QTC_ASSERT(handlesFile(filePath), return false); + return filePath.copyFile(target); +} + +bool DesktopDevice::renameFile(const FilePath &filePath, const FilePath &target) const +{ + QTC_ASSERT(handlesFile(filePath), return false); + QTC_ASSERT(handlesFile(target), return false); + return filePath.renameFile(target); +} + +QDateTime DesktopDevice::lastModified(const FilePath &filePath) const +{ + QTC_ASSERT(handlesFile(filePath), return {}); + return filePath.lastModified(); +} + +FilePath DesktopDevice::symLinkTarget(const FilePath &filePath) const +{ + QTC_ASSERT(handlesFile(filePath), return {}); + return filePath.symLinkTarget(); +} + +QByteArray DesktopDevice::fileContents(const FilePath &filePath, int limit) const +{ + QTC_ASSERT(handlesFile(filePath), return {}); + return filePath.fileContents(limit); +} + +bool DesktopDevice::writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const +{ + QTC_ASSERT(handlesFile(filePath), return {}); + return filePath.writeFileContents(data); +} + } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.h b/src/plugins/projectexplorer/devicesupport/desktopdevice.h index 9c1aac3af1f..a1a5379f00f 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopdevice.h +++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.h @@ -54,13 +54,29 @@ public: DeviceProcessSignalOperation::Ptr signalOperation() const override; DeviceEnvironmentFetcher::Ptr environmentFetcher() const override; QUrl toolControlChannel(const ControlChannelHint &) const override; + bool handlesFile(const Utils::FilePath &filePath) const override; QList directoryEntries(const Utils::FilePath &filePath, const QStringList &nameFilters, QDir::Filters filters, QDir::SortFlags sort) const override; Utils::Environment systemEnvironment() const override; - + bool isExecutableFile(const Utils::FilePath &filePath) const override; + bool isReadableFile(const Utils::FilePath &filePath) const override; + bool isWritableFile(const Utils::FilePath &filePath) const override; + bool isReadableDirectory(const Utils::FilePath &filePath) const override; + bool isWritableDirectory(const Utils::FilePath &filePath) const override; + bool ensureExistingFile(const Utils::FilePath &filePath) const override; + bool createDirectory(const Utils::FilePath &filePath) const override; + bool exists(const Utils::FilePath &filePath) const override; + bool removeFile(const Utils::FilePath &filePath) const override; + bool removeRecursively(const Utils::FilePath &filePath) const override; + bool copyFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const override; + bool renameFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const override; + QDateTime lastModified(const Utils::FilePath &filePath) const override; + Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override; + QByteArray fileContents(const Utils::FilePath &filePath, int limit) const override; + bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override; protected: DesktopDevice(); From 397f4054c7dcec35f5b2f3bf18db9dd87ba3dbed Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Fri, 9 Jul 2021 12:25:34 +0200 Subject: [PATCH 21/26] QmlDesigner: Fix copy/paste style buttons Task-number: QDS-4697 Change-Id: I689fcfb2d01f4c13f34044ed06ba2babeca0066a Reviewed-by: Alessandro Portale --- .../componentcore/designeractionmanager.cpp | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index 369df95a322..77cd00d7fa2 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -1007,20 +1007,32 @@ void DesignerActionManager::createDefaultDesignerActions() &selectionNotEmptyAndHasXorYProperty)); const QString fontName = "qtds_propertyIconFont.ttf"; - const QColor iconColorNormal(Theme::getColor(Theme::IconsBaseColor)); - const QIcon pasteIcon = Utils::StyleHelper::getIconFromIconFont(fontName, - Theme::getIconUnicode( - Theme::Icon::pasteStyle), - 28, - 28, - iconColorNormal); + const QColor iconColorDefault(Theme::getColor(Theme::IconsBaseColor)); + const QColor iconColorDisabled(Theme::getColor(Theme::IconsDisabledColor)); + const QString copyUnicode = Theme::getIconUnicode(Theme::Icon::copyStyle); + const QString pasteUnicode = Theme::getIconUnicode(Theme::Icon::pasteStyle); + const auto copyDefault = Utils::StyleHelper::IconFontHelper(copyUnicode, + iconColorDefault, + QSize(28, 28), + QIcon::Normal); + const auto copyDisabled = Utils::StyleHelper::IconFontHelper(copyUnicode, + iconColorDisabled, + QSize(28, 28), + QIcon::Disabled); const QIcon copyIcon = Utils::StyleHelper::getIconFromIconFont(fontName, - Theme::getIconUnicode( - Theme::Icon::copyStyle), - 28, - 28, - iconColorNormal); + {copyDefault, copyDisabled}); + + const auto pasteDefault = Utils::StyleHelper::IconFontHelper(pasteUnicode, + iconColorDefault, + QSize(28, 28), + QIcon::Normal); + const auto pasteDisabled = Utils::StyleHelper::IconFontHelper(pasteUnicode, + iconColorDisabled, + QSize(28, 28), + QIcon::Disabled); + const QIcon pasteIcon = Utils::StyleHelper::getIconFromIconFont(fontName, + {pasteDefault, pasteDisabled}); addDesignerAction(new ModelNodeAction(copyFormatCommandId, copyFormatDisplayName, From 4d3ed0fa93099f4906969be2b3122f7fd6485c79 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 8 Jul 2021 12:11:15 +0200 Subject: [PATCH 22/26] LanguageClient: Do not send document updates when canceling a request Change-Id: Ied675bb0eca353fd5ffe26540d99bafb6a874c0d Reviewed-by: David Schulz --- src/plugins/languageclient/client.cpp | 7 ++++--- src/plugins/languageclient/client.h | 6 +++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index a7868be19ab..aaf8d3caba5 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -400,11 +400,12 @@ void Client::openDocument(TextEditor::TextDocument *document) } } -void Client::sendContent(const IContent &content) +void Client::sendContent(const IContent &content, SendDocUpdates sendUpdates) { QTC_ASSERT(m_clientInterface, return); QTC_ASSERT(m_state == Initialized, return); - sendPostponedDocumentUpdates(); + if (sendUpdates == SendDocUpdates::Send) + sendPostponedDocumentUpdates(); if (Utils::optional responseHandler = content.responseHandler()) m_responseHandlers[responseHandler->id] = responseHandler->callback; QString error; @@ -418,7 +419,7 @@ void Client::sendContent(const IContent &content) void Client::cancelRequest(const MessageId &id) { m_responseHandlers.remove(id); - sendContent(CancelRequest(CancelParameter(id))); + sendContent(CancelRequest(CancelParameter(id)), SendDocUpdates::Ignore); } void Client::closeDocument(TextEditor::TextDocument *document) diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h index 650f0155102..c783e76aafa 100644 --- a/src/plugins/languageclient/client.h +++ b/src/plugins/languageclient/client.h @@ -92,7 +92,11 @@ public: Utils::Id id() const { return m_id; } void setName(const QString &name) { m_displayName = name; } QString name() const; - void sendContent(const LanguageServerProtocol::IContent &content); + + enum class SendDocUpdates { Send, Ignore }; + void sendContent(const LanguageServerProtocol::IContent &content, + SendDocUpdates sendUpdates = SendDocUpdates::Send); + void cancelRequest(const LanguageServerProtocol::MessageId &id); // server state handling From 792699be063f108813eeaf52c20bf69b5e7f07c0 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 8 Jul 2021 12:23:12 +0200 Subject: [PATCH 23/26] ClangdClient: Do not send document update requests ... when requesting extra data from clangd. Change-Id: I3552a2b7e09a1947de6570352936fd45e95f37a2 Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangdclient.cpp | 29 +++++++++++---------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index a427006d05a..ae1e29a8eb8 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -839,13 +839,15 @@ void ClangdClient::openExtraFile(const Utils::FilePath &filePath, const QString item.setUri(DocumentUri::fromFilePath(filePath)); item.setText(!content.isEmpty() ? content : QString::fromUtf8(cxxFile.readAll())); item.setVersion(0); - sendContent(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item))); + sendContent(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item)), + SendDocUpdates::Ignore); } void ClangdClient::closeExtraFile(const Utils::FilePath &filePath) { sendContent(DidCloseTextDocumentNotification(DidCloseTextDocumentParams( - TextDocumentIdentifier{DocumentUri::fromFilePath(filePath)}))); + TextDocumentIdentifier{DocumentUri::fromFilePath(filePath)})), + SendDocUpdates::Ignore); } void ClangdClient::findUsages(TextEditor::TextDocument *document, const QTextCursor &cursor, @@ -1036,7 +1038,7 @@ void ClangdClient::Private::handleFindUsagesResult(quint64 key, const QListpendingAstRequests << request.id(); - q->sendContent(request); + q->sendContent(request, SendDocUpdates::Ignore); if (extraOpen) q->closeExtraFile(it.key().toFilePath()); @@ -1194,7 +1196,7 @@ void ClangdClient::followSymbol( if (d->followSymbolData->defLink.hasValidTarget()) d->handleGotoDefinitionResult(); }); - sendContent(astRequest); + sendContent(astRequest, SendDocUpdates::Ignore); } void ClangdClient::switchDeclDef(TextEditor::TextDocument *document, const QTextCursor &cursor, @@ -1228,7 +1230,7 @@ void ClangdClient::switchDeclDef(TextEditor::TextDocument *document, const QText d->handleDeclDefSwitchReplies(); }); - sendContent(astRequest); + sendContent(astRequest, SendDocUpdates::Ignore); documentSymbolCache()->requestSymbols(d->switchDeclDefData->uri); } @@ -1315,8 +1317,7 @@ void ClangdClient::findLocalUsages(TextEditor::TextDocument *document, const QTe d->localRefsData.reset(); }); qCDebug(clangdLog) << "sending ast request for link"; - sendContent(astRequest); - + sendContent(astRequest, SendDocUpdates::Ignore); }; symbolSupport().findLinkAt(document, cursor, std::move(gotoDefCallback), true); } @@ -1401,7 +1402,7 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR // with mainOverload = true, such information would get ignored anyway. d->setHelpItemForTooltip(id, fqn, HelpItem::Function, isFunction ? type : "()"); }); - sendContent(symReq); + sendContent(symReq, SendDocUpdates::Ignore); return; } if ((node.role() == "expression" && node.kind() == "DeclRef") @@ -1466,7 +1467,7 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR } d->setHelpItemForTooltip(id); }); - sendContent(req); + sendContent(req, SendDocUpdates::Ignore); } void ClangdClient::Private::handleGotoDefinitionResult() @@ -1507,7 +1508,7 @@ void ClangdClient::Private::sendGotoImplementationRequest(const Utils::Link &lin followSymbolData->pendingGotoImplRequests.removeOne(reqId); handleGotoImplementationResult(response); }); - q->sendContent(req); + q->sendContent(req, SendDocUpdates::Ignore); followSymbolData->pendingGotoImplRequests << req.id(); qCDebug(clangdLog) << "sending go to implementation request" << link.targetLine; } @@ -1594,7 +1595,7 @@ void ClangdClient::Private::handleGotoImplementationResult( }); followSymbolData->pendingSymbolInfoRequests << symReq.id(); qCDebug(clangdLog) << "sending symbol info request"; - q->sendContent(symReq); + q->sendContent(symReq, SendDocUpdates::Ignore); if (link == followSymbolData->defLink) continue; @@ -1628,7 +1629,7 @@ void ClangdClient::Private::handleGotoImplementationResult( followSymbolData->pendingGotoDefRequests << defReq.id(); qCDebug(clangdLog) << "sending additional go to definition request" << link.targetFilePath << link.targetLine; - q->sendContent(defReq); + q->sendContent(defReq, SendDocUpdates::Ignore); } const DocumentUri defLinkUri @@ -1651,7 +1652,7 @@ void ClangdClient::Private::handleGotoImplementationResult( } }); qCDebug(clangdLog) << "sending ast request for def link"; - q->sendContent(astRequest); + q->sendContent(astRequest, SendDocUpdates::Ignore); } void ClangdClient::Private::handleDocumentInfoResults() @@ -2385,7 +2386,7 @@ void ClangdClient::Private::handleSemanticTokens(TextEditor::TextDocument *doc, it->second.setHighlightingRunner(runner); it->second.run(); }); - q->sendContent(astReq); + q->sendContent(astReq, SendDocUpdates::Ignore); } void ClangdClient::VirtualFunctionAssistProcessor::cancel() From 0568be071d5523478775019c9dd28d5a081efa74 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 9 Jul 2021 11:52:13 +0200 Subject: [PATCH 24/26] Add changes file for 4.15.2 Change-Id: I691d64c4faac7158009d6f93a089cab184934893 Reviewed-by: Leena Miettinen --- dist/changes-4.15.2.md | 55 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 dist/changes-4.15.2.md diff --git a/dist/changes-4.15.2.md b/dist/changes-4.15.2.md new file mode 100644 index 00000000000..cf053f0046a --- /dev/null +++ b/dist/changes-4.15.2.md @@ -0,0 +1,55 @@ +Qt Creator 4.15.2 +================= + +Qt Creator version 4.15.2 contains bug fixes. + +The most important changes are listed in this document. For a complete +list of changes, see the Git log for the Qt Creator sources that +you can check out from the public Git repository. For example: + + git clone git://code.qt.io/qt-creator/qt-creator.git + git log --cherry-pick --pretty=oneline origin/v4.15.1..v4.15.2 + +Projects +-------- + +### CMake + +* Improved performance after project load and reparse +* Fixed crash on session switch (QTCREATORBUG-25837) + +### qmake + +* Fixed issues with executing system calls (QTCREATORBUG-25970) + +Test Integration +---------------- + +### CTest + +* Fixed test detection if `ctest` takes long to run (QTCREATORBUG-25851) + +Platforms +--------- + +### WASM + +* Fixed Python version that is on Windows (QTCREATORBUG-25897) + +Credits for these changes go to: +-------------------------------- +Ahmad Samir +Alessandro Portale +Christian Stenger +Cristian Adam +Eike Ziller +Ivan Komissarov +Kai Köhne +Knud Dollereder +Michael Winkelmann +Mitch Curtis +Robert Löhning +Thomas Hartmann +Tim Blechmann +Tim Jenssen +Tuomo Pelkonen From c7ee8b5504064f172c44b28d0508787642f9f70e Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 8 Jul 2021 17:00:19 +0200 Subject: [PATCH 25/26] Doc: Update info about image properties - Fix changed field labels - Update screenshots Task-number: QDS-4561 Change-Id: I12c4db163e5dfcdd9aa9140b569e2fc2660355c8 Reviewed-by: Brook Cronin Reviewed-by: Vikas Pachdha --- ...ick-designer-animated-image-properties.png | Bin 9732 -> 3911 bytes ...quick-designer-border-image-properties.png | Bin 8309 -> 18108 bytes .../qtquick-designer-image-properties.png | Bin 15157 -> 32323 bytes .../src/qtquick/library/qtquick-images.qdoc | 14 ++++++++------ 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/qtcreator/images/qtquick-designer-animated-image-properties.png b/doc/qtcreator/images/qtquick-designer-animated-image-properties.png index 01ed4fc86ace416d472d8baf70ffc72921965763..a122bd8c25e75b9b2de5a28a8886b63fe329e888 100644 GIT binary patch literal 3911 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 XbbjBH$N7eVfq}u()z4*}Q$iB}FKN_N literal 9732 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 Q{t?9YboFyt=akR{0E5Oe8UO$Q diff --git a/doc/qtcreator/images/qtquick-designer-border-image-properties.png b/doc/qtcreator/images/qtquick-designer-border-image-properties.png index 6f082870134d828c8805e67ca6a23da7f087cc29..3f54dd428ccc042575c6f4f61da024ce90c2d5d5 100644 GIT binary patch literal 18108 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 diff --git a/doc/qtcreator/images/qtquick-designer-image-properties.png b/doc/qtcreator/images/qtquick-designer-image-properties.png index e229869a8906b5d602bd8ea834848de5e8d75512..ad01bbf400a3788287bd8de9443e0a38aa80ff42 100644 GIT binary patch literal 32323 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 U{(tQ|3=9kmp00i_>zopr0MG^WUH||9 literal 15157 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 K&t;ucLK6T{!Qa>b diff --git a/doc/qtcreator/src/qtquick/library/qtquick-images.qdoc b/doc/qtcreator/src/qtquick/library/qtquick-images.qdoc index c8cec48b890..2f7f0cffa33 100644 --- a/doc/qtcreator/src/qtquick/library/qtquick-images.qdoc +++ b/doc/qtcreator/src/qtquick/library/qtquick-images.qdoc @@ -131,8 +131,9 @@ \section1 Image Alignment - You can align images horizontally and vertically. By default, images are - centered. + You can align images horizontally and vertically in the + \uicontrol {Alignment H} and \uicontrol {Alignment V} + fields. By default, images are centered. Select the \uicontrol Mirrored check box to horizontally invert the image, effectively displaying a mirrored image. @@ -161,8 +162,7 @@ of each image. A source image is broken into 9 regions that are scaled or tiled individually. The corner regions are not scaled at all, while the horizontal and vertical regions are scaled according to the values of the - \uicontrol {Horizontal tile mode} and \uicontrol {Vertical tile mode} field, - or both. + \uicontrol {Tile mode H} and \uicontrol {Tile mode V} field, or both. The \uicontrol Stretch option scales the image to fit the available area. The \uicontrol Repeat option tiles the image until there is no more space. @@ -193,8 +193,10 @@ \image qtquick-designer-animated-image-properties.png "Animated Image properties" - To pause or play the animation, select the \uicontrol Paused or - \uicontrol Playing check boxes. + To play the animation, select the \uicontrol Playing check box. + + To pause the animation, select the \inlineimage icons/pause-icon.png + (\uicontrol Paused) check box. When the \uicontrol Cache check box is selected, every frame of the animation is cached. Deselect the check box if you are playing a long From c3e413a8643857111ea80747605ba2cf5c2e328b Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 9 Jul 2021 11:22:22 +0200 Subject: [PATCH 26/26] proparser: Update ProItems to state in Qt 6.2 Except for our Qt 5 workarounds with toStringView, qHash return value, and ProStringList which must be an explicit QVector for Qt 5. Most importantly that pulls in a change to ProString::toQString(QString &tmp) const from 76004502baa118016c8e0f32895af7a822f1ba37 in qtbase, which replaces a setRawData call which otherwise leads to severe issues when built with Qt 6. Fixes: QTCREATORBUG-25574 Change-Id: I488b4e0b63becc59a4ea34aace5c249921fa1a60 Reviewed-by: Joerg Bornemann Reviewed-by: Qt CI Bot Reviewed-by: Christian Kandeler --- src/shared/proparser/proitems.cpp | 18 +++++- src/shared/proparser/proitems.h | 94 +++++++++++++++++++++++-------- 2 files changed, 85 insertions(+), 27 deletions(-) diff --git a/src/shared/proparser/proitems.cpp b/src/shared/proparser/proitems.cpp index f689c419237..1f4a436115e 100644 --- a/src/shared/proparser/proitems.cpp +++ b/src/shared/proparser/proitems.cpp @@ -25,6 +25,7 @@ #include "proitems.h" +#include #include #include #include @@ -50,6 +51,11 @@ ProString::ProString() : { } +ProString::ProString(const ProString &other) : + m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_file(other.m_file), m_hash(other.m_hash) +{ +} + ProString::ProString(const ProString &other, OmitPreHashing) : m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_file(other.m_file), m_hash(0x80000000) { @@ -72,13 +78,13 @@ ProString::ProString(Utils::StringView str) : } ProString::ProString(const char *str, DoPreHashing) : - m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)), m_file(0) + m_string(QString::fromLatin1(str)), m_offset(0), m_length(int(qstrlen(str))), m_file(0) { updatedHash(); } ProString::ProString(const char *str) : - m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)), m_file(0), m_hash(0x80000000) + m_string(QString::fromLatin1(str)), m_offset(0), m_length(int(qstrlen(str))), m_file(0), m_hash(0x80000000) { } @@ -148,7 +154,8 @@ QString ProString::toQString() const QString &ProString::toQString(QString &tmp) const { - return tmp.setRawData(m_string.constData() + m_offset, m_length); + tmp = m_string.mid(m_offset, m_length); + return tmp; } ProString &ProString::prepend(const ProString &other) @@ -493,4 +500,9 @@ ProKey ProFile::getHashStr(const ushort *&tPtr) return ret; } +QDebug operator<<(QDebug debug, const ProString &str) +{ + return debug << str.toQString(); +} + QT_END_NAMESPACE diff --git a/src/shared/proparser/proitems.h b/src/shared/proparser/proitems.h index 3e0686fe136..9d851a9d578 100644 --- a/src/shared/proparser/proitems.h +++ b/src/shared/proparser/proitems.h @@ -64,6 +64,8 @@ class ProFile; class ProString { public: ProString(); + ProString(const ProString &other); + ProString &operator=(const ProString &) = default; template ProString &operator=(const QStringBuilder &str) { return *this = QString(str); } @@ -74,7 +76,6 @@ public: ProString(const QStringBuilder &str) : ProString(QString(str)) {} - ProString(const QString &str, int offset, int length); void setValue(const QString &str); void clear() { m_string.clear(); m_length = 0; } @@ -83,14 +84,14 @@ public: int sourceFile() const { return m_file; } ProString &prepend(const ProString &other); - ProString &append(const ProString &other, bool *pending = 0); + ProString &append(const ProString &other, bool *pending = nullptr); ProString &append(const QString &other) { return append(ProString(other)); } template ProString &append(const QStringBuilder &other) { return append(QString(other)); } ProString &append(const QLatin1String other); ProString &append(const char *other) { return append(QLatin1String(other)); } ProString &append(QChar other); - ProString &append(const ProStringList &other, bool *pending = 0, bool skipEmpty1st = false); + ProString &append(const ProStringList &other, bool *pending = nullptr, bool skipEmpty1st = false); ProString &operator+=(const ProString &other) { return append(other); } ProString &operator+=(const QString &other) { return append(other); } template @@ -146,9 +147,9 @@ public: bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(s, 0, cs) >= 0; } bool contains(const char *s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(QLatin1String(s), 0, cs) >= 0; } bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(c, 0, cs) >= 0; } - int toLongLong(bool *ok = 0, int base = 10) const { return toStringView().toLongLong(ok, base); } - int toInt(bool *ok = 0, int base = 10) const { return toStringView().toInt(ok, base); } - short toShort(bool *ok = 0, int base = 10) const { return toStringView().toShort(ok, base); } + qlonglong toLongLong(bool *ok = nullptr, int base = 10) const { return toStringView().toLongLong(ok, base); } + int toInt(bool *ok = nullptr, int base = 10) const { return toStringView().toInt(ok, base); } + short toShort(bool *ok = nullptr, int base = 10) const { return toStringView().toShort(ok, base); } uint hash() const { return m_hash; } static uint hash(const QChar *p, int n); @@ -185,7 +186,8 @@ private: friend QString operator+(const ProString &one, const ProString &two); friend class ProKey; }; -Q_DECLARE_TYPEINFO(ProString, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(ProString, Q_RELOCATABLE_TYPE); + class ProKey : public ProString { public: @@ -195,7 +197,6 @@ public: ProKey(const QStringBuilder &str) : ProString(str) {} - PROITEM_EXPLICIT ProKey(const char *str); ProKey(const QString &str, int off, int len); ProKey(const QString &str, int off, int len, uint hash); @@ -217,7 +218,7 @@ public: private: ProKey(const ProString &other); }; -Q_DECLARE_TYPEINFO(ProKey, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(ProKey, Q_RELOCATABLE_TYPE); template <> struct QConcatenable : private QAbstractConcatenable { @@ -228,6 +229,8 @@ template <> struct QConcatenable : private QAbstractConcatenable static inline void appendTo(const ProString &a, QChar *&out) { const auto n = a.size(); + if (!n) + return; memcpy(out, a.toStringView().data(), sizeof(QChar) * n); out += n; } @@ -242,6 +245,8 @@ template <> struct QConcatenable : private QAbstractConcatenable static inline void appendTo(const ProKey &a, QChar *&out) { const auto n = a.size(); + if (!n) + return; memcpy(out, a.toStringView().data(), sizeof(QChar) * n); out += n; } @@ -257,6 +262,54 @@ QTextStream &operator<<(QTextStream &t, const ProString &str); template QTextStream &operator<<(QTextStream &t, const QStringBuilder &str) { return t << QString(str); } +// This class manages read-only access to a ProString via a raw data QString +// temporary, ensuring that the latter is accessed exclusively. +class ProStringRoUser +{ +public: + ProStringRoUser(QString &rs) + { + m_rs = &rs; + } + ProStringRoUser(const ProString &ps, QString &rs) + : ProStringRoUser(rs) + { + ps.toQString(rs); + } + // No destructor, as a RAII pattern cannot be used: references to the + // temporary string can legitimately outlive instances of this class + // (if they are held by Qt, e.g. in QRegExp). + QString &set(const ProString &ps) { return ps.toQString(*m_rs); } + QString &str() { return *m_rs; } + +protected: + QString *m_rs; +}; + +// This class manages read-write access to a ProString via a raw data QString +// temporary, ensuring that the latter is accessed exclusively, and that raw +// data does not leak outside its source's refcounting. +class ProStringRwUser : public ProStringRoUser +{ +public: + ProStringRwUser(QString &rs) + : ProStringRoUser(rs), m_ps(nullptr) {} + ProStringRwUser(const ProString &ps, QString &rs) + : ProStringRoUser(ps, rs), m_ps(&ps) {} + QString &set(const ProString &ps) { m_ps = &ps; return ProStringRoUser::set(ps); } + ProString extract(const QString &s) const + { return s.isSharedWith(*m_rs) ? *m_ps : ProString(s).setSource(*m_ps); } + ProString extract(const QString &s, const ProStringRwUser &other) const + { + if (other.m_ps && s.isSharedWith(*other.m_rs)) + return *other.m_ps; + return extract(s); + } + +private: + const ProString *m_ps; +}; + class ProStringList : public QVector { public: ProStringList() {} @@ -290,21 +343,12 @@ public: { return contains(ProString(str), cs); } bool contains(const char *str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; }; -Q_DECLARE_TYPEINFO(ProStringList, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(ProStringList, Q_RELOCATABLE_TYPE); inline ProStringList operator+(const ProStringList &one, const ProStringList &two) { ProStringList ret = one; ret += two; return ret; } -typedef QHash ProValueMap; - -// For std::list (sic!) -#ifdef Q_CC_MSVC -inline bool operator<(const ProValueMap &, const ProValueMap &) -{ - Q_ASSERT(false); - return false; -} -#endif +typedef QMap ProValueMap; // These token definitions affect both ProFileEvaluator and ProWriter enum ProToken { @@ -419,7 +463,7 @@ class ProFunctionDef { public: ProFunctionDef(ProFile *pro, int offset) : m_pro(pro), m_offset(offset) { m_pro->ref(); } ProFunctionDef(const ProFunctionDef &o) : m_pro(o.m_pro), m_offset(o.m_offset) { m_pro->ref(); } - ProFunctionDef(ProFunctionDef &&other) Q_DECL_NOTHROW + ProFunctionDef(ProFunctionDef &&other) noexcept : m_pro(other.m_pro), m_offset(other.m_offset) { other.m_pro = nullptr; } ~ProFunctionDef() { if (m_pro) m_pro->deref(); } ProFunctionDef &operator=(const ProFunctionDef &o) @@ -433,13 +477,13 @@ public: } return *this; } - ProFunctionDef &operator=(ProFunctionDef &&other) Q_DECL_NOTHROW + ProFunctionDef &operator=(ProFunctionDef &&other) noexcept { ProFunctionDef moved(std::move(other)); swap(moved); return *this; } - void swap(ProFunctionDef &other) Q_DECL_NOTHROW + void swap(ProFunctionDef &other) noexcept { qSwap(m_pro, other.m_pro); qSwap(m_offset, other.m_offset); @@ -452,11 +496,13 @@ private: int m_offset; }; -Q_DECLARE_TYPEINFO(ProFunctionDef, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(ProFunctionDef, Q_RELOCATABLE_TYPE); struct ProFunctionDefs { QHash testFunctions; QHash replaceFunctions; }; +QDebug operator<<(QDebug debug, const ProString &str); + QT_END_NAMESPACE