From d80f3f4d8a1399431b70f3d7d8d188163806c6e6 Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Tue, 26 Oct 2021 18:34:04 +0300 Subject: [PATCH 01/57] Android: remove unused function that couldn't be removed in 5.0 branch ... because of binary compatibility. Comes after a2b6dba0bcec4675cbc5c951cfb112296e65d4e4. Change-Id: I18866de39a05c6690b47632cc5503f8555e006da Reviewed-by: Alessandro Portale --- src/plugins/android/androidmanager.cpp | 5 ----- src/plugins/android/androidmanager.h | 2 -- 2 files changed, 7 deletions(-) diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index b1a1f15fdee..74695c219b1 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -246,11 +246,6 @@ bool AndroidManager::isQtCreatorGenerated(const FilePath &deploymentFile) return QJsonDocument::fromJson(f.readAll()).object()["_description"].toString() == qtcSignature; } -FilePath AndroidManager::dirPath(const Target *target) -{ - return androidBuildDirectory(target); -} - FilePath AndroidManager::androidBuildDirectory(const Target *target) { return buildDirectory(target) / Constants::ANDROID_BUILD_DIRECTORY; diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h index a32bbcacbca..f41dc42be28 100644 --- a/src/plugins/android/androidmanager.h +++ b/src/plugins/android/androidmanager.h @@ -95,8 +95,6 @@ public: static bool isQt5CmakeProject(const ProjectExplorer::Target *target); - // TODO: remove this on 6.0 branch, kept here for binary compatibility for 5.0 release. - static Utils::FilePath dirPath(const ProjectExplorer::Target *target); static Utils::FilePath androidBuildDirectory(const ProjectExplorer::Target *target); static Utils::FilePath buildDirectory(const ProjectExplorer::Target *target); static Utils::FilePath manifestPath(const ProjectExplorer::Target *target); From bcc5c9a344d27b08d5c629f763f54262da4efa93 Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Fri, 5 Nov 2021 15:21:21 +0200 Subject: [PATCH 02/57] Android: since jpg is allowd, add jpeg to icon/splash file dialog Change-Id: I018650a33d681f4ea75c9333eb875a197ce96e3d Reviewed-by: Alessandro Portale --- src/plugins/android/androidmanifesteditoriconwidget.cpp | 2 +- src/plugins/android/splashscreencontainerwidget.cpp | 6 +++--- src/plugins/android/splashscreenwidget.cpp | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/plugins/android/androidmanifesteditoriconwidget.cpp b/src/plugins/android/androidmanifesteditoriconwidget.cpp index 3774a5cf00a..1202c8ebc18 100644 --- a/src/plugins/android/androidmanifesteditoriconwidget.cpp +++ b/src/plugins/android/androidmanifesteditoriconwidget.cpp @@ -166,7 +166,7 @@ void AndroidManifestEditorIconWidget::selectIcon() { FilePath file = FileUtils::getOpenFilePath(this, m_iconSelectionText, FileUtils::homePath(), - tr("Images (*.png *.jpg *.webp *.svg)")); + tr("Images (*.png *.jpg *.jpeg *.webp *.svg)")); if (file.isEmpty()) return; setIconFromPath(file); diff --git a/src/plugins/android/splashscreencontainerwidget.cpp b/src/plugins/android/splashscreencontainerwidget.cpp index fbbada112eb..a738b0ed127 100644 --- a/src/plugins/android/splashscreencontainerwidget.cpp +++ b/src/plugins/android/splashscreencontainerwidget.cpp @@ -62,7 +62,7 @@ const char splashscreenFileName[] = "logo"; const char splashscreenPortraitFileName[] = "logo_port"; const char splashscreenLandscapeFileName[] = "logo_land"; const char imageSuffix[] = ".png"; -const QString fileDialogImageFiles = QString(QWidget::tr("Images (*.png *.jpg)")); +const QString fileDialogImageFiles = QString(QWidget::tr("Images (*.png *.jpg *.jpeg)")); const QSize lowDpiImageSize{200, 320}; const QSize mediumDpiImageSize{320, 480}; const QSize highDpiImageSize{480, 800}; @@ -608,8 +608,8 @@ void SplashScreenContainerWidget::checkSplashscreenImage(const QString &name) for (const QString &path : paths) { const FilePath filePath = baseDir.pathAppended(path + name); - if (filePath.stringAppended(".png").exists() - || filePath.stringAppended(".jpg").exists()) { + if (filePath.stringAppended(".png").exists() || filePath.stringAppended(".jpg").exists() + || filePath.stringAppended(".jpeg").exists()) { setCurrentIndex(1); break; } diff --git a/src/plugins/android/splashscreenwidget.cpp b/src/plugins/android/splashscreenwidget.cpp index 23e5ddccb97..386e6802df2 100644 --- a/src/plugins/android/splashscreenwidget.cpp +++ b/src/plugins/android/splashscreenwidget.cpp @@ -189,7 +189,8 @@ void SplashScreenWidget::selectImage() { const FilePath file = FileUtils::getOpenFilePath(this, m_imageSelectionText, FileUtils::homePath(), - QStringLiteral("%1 (*.png *.jpg)").arg(tr("Images"))); + QStringLiteral("%1 (*.png *.jpg *.jpeg)") + .arg(tr("Images"))); if (file.isEmpty()) return; setImageFromPath(file, false); From 9a16eb5fe62780dda7ba10d22f2bfbe6aadd366b Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 5 Nov 2021 15:35:54 +0100 Subject: [PATCH 03/57] ClangCodeModel: Inform clangd about changes to non-open files That is, project-wide changes done from Qt Creator, such as search/ replace or quickfixes. Fixes: QTCREATORBUG-26523 Change-Id: Ide4e56a7a1300eb6f25cabf1cfd94624d66e7e4e Reviewed-by: David Schulz --- .../clangmodelmanagersupport.cpp | 24 +++++++++++++++++++ .../clangcodemodel/clangmodelmanagersupport.h | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 090a4549c3b..3bd9d2640f6 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -112,6 +112,7 @@ ClangModelManagerSupport::ClangModelManagerSupport() m_instance = this; watchForExternalChanges(); + watchForInternalChanges(); cppModelManager()->setCurrentDocumentFilter(std::make_unique()); cppModelManager()->setLocatorFilter(std::make_unique()); cppModelManager()->setClassesFilter(std::make_unique()); @@ -488,6 +489,29 @@ void ClangModelManagerSupport::watchForExternalChanges() }); } +void ClangModelManagerSupport::watchForInternalChanges() +{ + connect(Core::DocumentManager::instance(), &Core::DocumentManager::filesChangedInternally, + this, [this](const Utils::FilePaths &filePaths) { + for (const Utils::FilePath &fp : filePaths) { + ClangdClient * const client = clientForFile(fp); + if (!client || client->documentForFilePath(fp)) + continue; + client->openExtraFile(fp); + + // We need to give clangd some time to start re-parsing the file. + // Closing right away does not work, and neither does doing it queued. + // If it turns out that this delay is not always enough, we'll need to come up + // with something more clever. + // Ideally, clangd would implement workspace/didChangeWatchedFiles; let's keep + // any eye on that. + QTimer::singleShot(5000, client, [client, fp] { + if (!client->documentForFilePath(fp)) + client->closeExtraFile(fp); }); + } + }); +} + void ClangModelManagerSupport::onEditorOpened(Core::IEditor *editor) { QTC_ASSERT(editor, return); diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index fc4e1d1a4b4..5d591d6925f 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -135,8 +135,8 @@ private: ClangdClient *createClient(ProjectExplorer::Project *project, const Utils::FilePath &jsonDbDir); void claimNonProjectSources(ClangdClient *fallbackClient); void watchForExternalChanges(); + void watchForInternalChanges(); -private: UiHeaderOnDiskManager m_uiHeaderOnDiskManager; BackendCommunicator m_communicator; ClangCompletionAssistProvider m_completionAssistProvider; From 6077bde638c481df9135e045370e571178df15ef Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 5 Nov 2021 13:47:18 +0100 Subject: [PATCH 04/57] CPlusPlus: Allow numeric literals with single quotes ... also in macro expansions. Amends 8c437362bc. Just like in that patch, we don't prevent trailing quotes, even though they are not allowed. Unlike in that patch, we don't check the language version, as it is not set during preprocessor mode (for whatever reason). Fixes: QTCREATORBUG-26484 Change-Id: I8737724208802ed9a9005af538cf13fbfd2efd42 Reviewed-by: Christian Stenger --- src/libs/3rdparty/cplusplus/Lexer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/3rdparty/cplusplus/Lexer.cpp b/src/libs/3rdparty/cplusplus/Lexer.cpp index 1d814845fec..c0f8731db0c 100644 --- a/src/libs/3rdparty/cplusplus/Lexer.cpp +++ b/src/libs/3rdparty/cplusplus/Lexer.cpp @@ -1034,7 +1034,7 @@ void Lexer::scanPreprocessorNumber(Token *tok, bool dotAlreadySkipped) yyinp(); if (_yychar == '+' || _yychar == '-') yyinp(); - } else if (std::isalnum(_yychar) || _yychar == '_' || _yychar == '.') { + } else if (std::isalnum(_yychar) || (_yychar == '\'') || _yychar == '_' || _yychar == '.') { yyinp(); } else { scanOptionalUserDefinedLiteral(tok); From 33122b564a34cb0cd73c1c4f3e22efefbaef2c02 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 8 Nov 2021 11:10:32 +0100 Subject: [PATCH 05/57] Editor: prevent endless loop for empty search results Fixes: QTCREATORBUG-26536 Change-Id: Ia49559c5b340085ef8371d8d90bda26bb6d728bb Reviewed-by: Eike Ziller Reviewed-by: Orgad Shaneh --- src/plugins/coreplugin/find/basetextfind.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/plugins/coreplugin/find/basetextfind.cpp b/src/plugins/coreplugin/find/basetextfind.cpp index ce213362230..12afaf8a659 100644 --- a/src/plugins/coreplugin/find/basetextfind.cpp +++ b/src/plugins/coreplugin/find/basetextfind.cpp @@ -421,10 +421,13 @@ QTextCursor BaseTextFind::findOne(const QRegularExpression &expr, QTextCursor found = document()->find(expr, from, options); while (!found.isNull() && !inScope(found)) { if (!found.hasSelection()) { - from = found; - found.movePosition(options & QTextDocument::FindBackward - ? QTextCursor::PreviousCharacter - : QTextCursor::NextCharacter); + if (found.movePosition(options & QTextDocument::FindBackward + ? QTextCursor::PreviousCharacter + : QTextCursor::NextCharacter)) { + from = found; + } else { + return {}; + } } else { from.setPosition(options & QTextDocument::FindBackward ? found.selectionStart() : found.selectionEnd()); From d06ddd12b605c08f4f0387bc346380b7c79299c6 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Fri, 5 Nov 2021 00:45:34 +0200 Subject: [PATCH 06/57] QmlDesigner: Add placeholder controls for when the assets view is empty Change-Id: I8cf864f97aff09f846411e50cec17e7cdf1be2d0 Reviewed-by: Leena Miettinen Reviewed-by: Samuel Ghinet Reviewed-by: Miikka Heikkinen --- .../itemLibraryQmlSources/Assets.qml | 50 ++++++++++++++++++ .../components/itemlibrary/images/browse.png | Bin 0 -> 494 bytes .../itemlibrary/images/browse@2x.png | Bin 0 -> 871 bytes .../components/itemlibrary/itemlibrary.qrc | 2 + .../itemlibraryassetsiconprovider.cpp | 8 +-- .../itemlibrary/itemlibraryassetsmodel.cpp | 2 +- .../itemlibrary/itemlibraryassetsmodel.h | 6 ++- 7 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 src/plugins/qmldesigner/components/itemlibrary/images/browse.png create mode 100644 src/plugins/qmldesigner/components/itemlibrary/images/browse@2x.png diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml index 5ca714051b0..cd07ba29450 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml @@ -32,6 +32,8 @@ import StudioControls 1.0 as StudioControls import StudioTheme 1.0 as StudioTheme Item { + id: rootItem + property var selectedAssets: ({}) property int allExpandedState: 0 property string delFilePath: "" @@ -257,4 +259,52 @@ Item { } } } + + // Placeholder when the assets panel is empty + Column { + id: colNoAssets + visible: assetsModel.isEmpty() + + spacing: 20 + x: 20 + width: rootItem.width - 2 * x + anchors.verticalCenter: parent.verticalCenter + + Text { + text: qsTr("Looks like you don't have any assets yet.") + color: StudioTheme.Values.themeTextColor + font.pixelSize: 18 + width: colNoAssets.width + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + } + + Image { + source: "image://qmldesigner_assets/browse" + anchors.horizontalCenter: parent.horizontalCenter + scale: maBrowse.containsMouse ? 1.2 : 1 + Behavior on scale { + NumberAnimation { + duration: 300 + easing.type: Easing.OutQuad + } + } + + MouseArea { + id: maBrowse + anchors.fill: parent + hoverEnabled: true + onClicked: rootView.handleAddAsset(); + } + } + + Text { + text: qsTr("Drag-and-drop your assets here or click the '+' button to browse assets from the file system.") + color: StudioTheme.Values.themeTextColor + font.pixelSize: 18 + width: colNoAssets.width + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + } + } } diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/browse.png b/src/plugins/qmldesigner/components/itemlibrary/images/browse.png new file mode 100644 index 0000000000000000000000000000000000000000..003b9e5d81b58a5b5dbfe72b387463a0b2b8176d GIT binary patch literal 494 zcmeAS@N?(olHy`uVBq!ia0y~yU@!w=7G?$phPv$XcMJ>+x&b~RuK)l4*IfOGNMtS1 zJ%fRPfv+UUFPK3%j^y6{o^j8dqamA*iY$Hld;dkFIk90EC-GVMPkQ3eKEKFhF5~uz zh0U@HZX~?vQV)7*FZ+tg{LK@t4=H~YjutQdrS~aAXxjR)8zEMlCG)f=O+Pp1^nq0| z66u@8mNDNyJ9Ev3t5Kdg+G(xlOuPB3s~Fv{y-i*)&o-tyf_?pxYN6_g71hEU*bJ9B zDP_%mVD&n&|5@x#uGbF&KkDkw4*dD6V~PDht#brP4 zJ3P_H?ISDJyk#kW7MnUR|7Wvj`Gj|RUwvL}{nEdrUi)l|iT5R*Pd8J;&gsprOnZ7} zb8O+a&DxjxOy4|P@TFz0*j9&20-n__XN9(&%X%`)UD-8P)b!@^r}wJ^yx3)1#Gf!Q PFfe$!`njxgN@xNAQ^4i) literal 0 HcmV?d00001 diff --git a/src/plugins/qmldesigner/components/itemlibrary/images/browse@2x.png b/src/plugins/qmldesigner/components/itemlibrary/images/browse@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..b13400f788e782134258808c7c76d102a82ece24 GIT binary patch literal 871 zcmeAS@N?(olHy`uVBq!ia0y~yV8{Vs4rT@hh8;VW|7T!eFb?nuasB`Qzvk*kB%u&# z%{vSX3<4!Ve!&a^3I+}V2?Y%k7Hl|h;lYQH2P;l6Ffd*Aba4#Hxc4^duGA6*j!^H* zpO$~GzqQxnw3M;N)1>m9v+|F9?2r*;JoZ3o$-K4k<%MO}f;N0J^6`%77Mhls(W#QY zKkVrFO}vu~_&o&A*WABwab3d3$LbnS!>3eS4OpGfJ1tpcWiM~<7U9#CQt2xHWsfc` zd|r5(`?l|LSN&B+tpUqRTRB&U?Q4#+*9&`bXP4O0Ij62{a#*}Nr)kEdYG%>BizHEoMzBVIL6ZeI8{ z;^Ae{QXgdon-cl;hY#8oUs{;KZDsfFrB40vQx|;huG8IMv_G;J%p_u}Kf^`)9(MFlmEPDseyVG->1 zl`%Md(eKr~vzz8FpMHCOslLJ9-swBph4&tCc~@F{vfh-XyY71WKku*1!R`0wPT1YS zE_{6JwkwMluq7B~MN1?zemzpjx=r@UhSwU^O(#=U{%HKp^4L>xZpa%BG2f++CvK}f zm}7HI>~z0*f?C#-ce0NYx`mqeed=HKNX~ZkguUTzO&xk~|kW*(}%`#t5wmiVjPID_8y7M-%^Wn&m>=+c6edo>4&YS_RiKkeXBHEIJIXBV_Eg=Nn5|U p{r9@IWsX_MtDC#{-`=Qa@RDDCF?sz57X}6f22WQ%mvv4FO#rgNn6Cf; literal 0 HcmV?d00001 diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc index 197dd87655b..b1777bbbec6 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc @@ -31,5 +31,7 @@ images/asset_sound_384.png images/x.png images/x@2x.png + images/browse.png + images/browse@2x.png diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsiconprovider.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsiconprovider.cpp index deb8312b8f2..ece6e8abaab 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsiconprovider.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsiconprovider.cpp @@ -42,16 +42,18 @@ QPixmap ItemLibraryAssetsIconProvider::requestPixmap(const QString &id, QSize *s { QPixmap pixmap; const QString suffix = "*." + id.split('.').last().toLower(); - if (ItemLibraryAssetsModel::supportedFontSuffixes().contains(suffix)) + if (id == "browse") + pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/ItemLibrary/images/browse.png"); + else if (ItemLibraryAssetsModel::supportedFontSuffixes().contains(suffix)) pixmap = generateFontIcons(id); else if (ItemLibraryAssetsModel::supportedImageSuffixes().contains(suffix)) pixmap = Utils::StyleHelper::dpiSpecificImageFile(id); else if (ItemLibraryAssetsModel::supportedTexture3DSuffixes().contains(suffix)) pixmap = HdrImage{id}.toPixmap(); else if (ItemLibraryAssetsModel::supportedShaderSuffixes().contains(suffix)) - pixmap = QPixmap(Utils::StyleHelper::dpiSpecificImageFile(":/ItemLibrary/images/asset_shader_48.png")); + pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/ItemLibrary/images/asset_shader_48.png"); else if (ItemLibraryAssetsModel::supportedAudioSuffixes().contains(suffix)) - pixmap = QPixmap(Utils::StyleHelper::dpiSpecificImageFile(":/ItemLibrary/images/asset_sound_48.png")); + pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/ItemLibrary/images/asset_sound_48.png"); if (size) { size->setWidth(pixmap.width()); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp index db3ea452d2b..febaf8a2154 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp @@ -275,7 +275,7 @@ void ItemLibraryAssetsModel::setRootPath(const QString &path) beginResetModel(); m_assetsDir = new ItemLibraryAssetsDir(path, 0, true, this); - parseDirRecursive(m_assetsDir, 1); + m_isEmpty = parseDirRecursive(m_assetsDir, 1); endResetModel(); } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.h index 294a760a6b5..d79426d40a8 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.h @@ -51,8 +51,8 @@ public: Utils::FileSystemWatcher *fileSystemWatcher, QObject *parent = nullptr); - QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; - int rowCount(const QModelIndex & parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; QHash roleNames() const override; void refresh(); @@ -81,6 +81,7 @@ public: Q_INVOKABLE void toggleExpandAll(bool expand); Q_INVOKABLE DirExpandState getAllExpandedState() const; Q_INVOKABLE void removeFile(const QString &filePath); + Q_INVOKABLE bool isEmpty() const { return m_isEmpty; }; private: const QSet &supportedSuffixes() const; @@ -91,6 +92,7 @@ private: QString m_searchText; Utils::FileSystemWatcher *m_fileSystemWatcher = nullptr; ItemLibraryAssetsDir *m_assetsDir = nullptr; + bool m_isEmpty = true; QHash m_roleNames; inline static QHash m_expandedStateHash; // From 5c0c3ff6cad1c2cb2227f07b9c5b7ecf6c27dbf5 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Mon, 8 Nov 2021 11:37:19 +0100 Subject: [PATCH 07/57] Debugger: Also look for "/ndk/" path segment in LldbEngine::setupEngine And pull the env-modifying code into a function which we might want to use in other places where lldb gets executed. Change-Id: Ic9caaf8c29896c54d67c969d2812b4da627a5fc0 Reviewed-by: Christian Stenger --- src/plugins/debugger/lldb/lldbengine.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index a5440edb7fd..ad2f4f2974e 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -204,6 +204,18 @@ static QString adapterStartFailed() return LldbEngine::tr("Adapter start failed."); } +static void addAndroidPythonDir(const FilePath &lldbCmd, Environment &env) +{ + if (!lldbCmd.path().contains("/ndk/") && !lldbCmd.path().contains("/ndk-bundle/")) + return; + + FilePath androidPythonDir = lldbCmd.parentDir().parentDir().pathAppended("python3"); + if (HostOsInfo::isAnyUnixHost()) + androidPythonDir = androidPythonDir.pathAppended("bin"); + if (androidPythonDir.exists()) + env.prependOrSetPath(androidPythonDir.path()); +} + void LldbEngine::setupEngine() { QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); @@ -213,13 +225,7 @@ void LldbEngine::setupEngine() showMessage("STARTING LLDB: " + lldbCmd.toUserOutput()); Environment environment = runParameters().debugger.environment; environment.appendOrSet("PYTHONUNBUFFERED", "1"); // avoid flushing problem on macOS - if (lldbCmd.path().contains("/ndk-bundle/")) { - FilePath androidPythonDir = lldbCmd.parentDir().parentDir().pathAppended("python3"); - if (HostOsInfo::isAnyUnixHost()) - androidPythonDir = androidPythonDir.pathAppended("bin"); - if (androidPythonDir.exists()) - environment.prependOrSetPath(androidPythonDir.path()); - } + addAndroidPythonDir(lldbCmd, environment); m_lldbProc.setEnvironment(environment); if (runParameters().debugger.workingDirectory.isDir()) From 39d2fc91fdcbca87d9adf915906433fc6ce79eec Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 4 Nov 2021 17:46:48 +0100 Subject: [PATCH 08/57] QmlDesigner: Do not allow resizing scaled items MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The resize tool does not work as expected in this case. Task-number: QDS-5346 Change-Id: Id977bb29670d216cf0989e4b2cd5072ae40ad6d1 Reviewed-by: Henning Gründl Reviewed-by: Qt CI Bot --- .../qmldesigner/components/formeditor/resizeindicator.cpp | 2 +- src/plugins/qmldesigner/designercore/include/qmlitemnode.h | 2 +- src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/qmldesigner/components/formeditor/resizeindicator.cpp b/src/plugins/qmldesigner/components/formeditor/resizeindicator.cpp index 4a2426f29f6..ad5f2feffff 100644 --- a/src/plugins/qmldesigner/components/formeditor/resizeindicator.cpp +++ b/src/plugins/qmldesigner/components/formeditor/resizeindicator.cpp @@ -63,7 +63,7 @@ static bool itemIsResizable(const QmlItemNode &qmlItemNode) && qmlItemNode.instanceIsResizable() && qmlItemNode.modelIsMovable() && qmlItemNode.modelIsResizable() - && !qmlItemNode.instanceHasRotationTransform() + && !qmlItemNode.instanceHasScaleOrRotationTransform() && !qmlItemNode.instanceIsInLayoutable(); } diff --git a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h index 9be07edfbfa..3a3498e6c9a 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h +++ b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h @@ -99,7 +99,7 @@ public: bool instanceIsMovable() const; bool instanceIsResizable() const; bool instanceIsInLayoutable() const; - bool instanceHasRotationTransform() const; + bool instanceHasScaleOrRotationTransform() const; bool modelIsMovable() const; bool modelIsResizable() const; diff --git a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp index c65f281f64a..bc5089f5305 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp @@ -303,9 +303,9 @@ bool QmlItemNode::instanceIsInLayoutable() const return nodeInstance().isInLayoutable(); } -bool QmlItemNode::instanceHasRotationTransform() const +bool QmlItemNode::instanceHasScaleOrRotationTransform() const { - return nodeInstance().transform().type() > QTransform::TxScale; + return nodeInstance().transform().type() > QTransform::TxTranslate; } bool itemIsMovable(const ModelNode &modelNode) From 50b23958046a617c9182f4f44fa09b310449b24e Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 8 Nov 2021 11:44:10 +0100 Subject: [PATCH 09/57] Debugger: Fix running android lldb ..when gathering version information. Change-Id: I99d69de661edad856fe66a045e8e2ee03036dd2c Reviewed-by: Alessandro Portale --- src/plugins/debugger/debuggeritem.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp index 2f71c8606bf..2e689ae9d3d 100644 --- a/src/plugins/debugger/debuggeritem.cpp +++ b/src/plugins/debugger/debuggeritem.cpp @@ -144,6 +144,8 @@ void DebuggerItem::createId() void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *error) { + const bool isAndroid = m_command.path().contains("/ndk/") + || m_command.path().contains("/ndk-bundle/"); // CDB only understands the single-dash -version, whereas GDB and LLDB are // happy with both -version and --version. So use the "working" -version // except for the experimental LLDB-MI which insists on --version. @@ -167,7 +169,8 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro // Prevent calling lldb on Windows because the lldb from the llvm package is linked against // python but does not contain a python dll. - if (HostOsInfo::isWindowsHost() && m_command.fileName().startsWith("lldb")) { + if (HostOsInfo::isWindowsHost() && m_command.fileName().startsWith("lldb") + && !isAndroid) { QString errorMessage; m_version = winGetDLLVersion(WinDLLFileVersion, m_command.absoluteFilePath().path(), @@ -177,8 +180,18 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro return; } + Environment env = sysEnv.toProcessEnvironment().isEmpty() ? Environment::systemEnvironment() + : sysEnv; + if (isAndroid && m_command.fileName().startsWith("lldb")) { + FilePath pythonPath = m_command.parentDir().parentDir().pathAppended("python3"); + if (HostOsInfo::isAnyUnixHost()) + pythonPath = pythonPath.pathAppended("bin"); + if (pythonPath.exists()) + env.prependOrSetPath(pythonPath.toUserOutput()); + } + QtcProcess proc; - proc.setEnvironment(sysEnv); + proc.setEnvironment(env); proc.setCommand({m_command, {version}}); proc.runBlocking(); const QString output = proc.allOutput().trimmed(); From af8937f10fcbe1f210f1609fb1c927b675b83fd6 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 5 Nov 2021 16:42:42 +0200 Subject: [PATCH 10/57] QmlDesigner: Update possible imports at model attach in component lib Without this, add module list will be empty after project load sometimes. Change-Id: Ia45949bc0cb22e4e3a0942d5858f2b395c0b8722 Reviewed-by: Thomas Hartmann --- .../qmldesigner/components/itemlibrary/itemlibraryview.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp index 95f1fc3faa5..151be411ad1 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp @@ -118,6 +118,8 @@ void ItemLibraryView::modelAttached(Model *model) m_widget->clearSearchFilter(); m_widget->setModel(model); updateImports(); + if (model) + m_widget->updatePossibleImports(model->possibleImports()); m_hasErrors = !rewriterView()->errors().isEmpty(); m_widget->setFlowMode(QmlItemNode(rootModelNode()).isFlowView()); setResourcePath(DocumentManager::currentResourcePath().toFileInfo().absoluteFilePath()); From f16589f96991d3801d2ec0a0068b5b231e1570fe Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 5 Nov 2021 12:27:45 +0100 Subject: [PATCH 11/57] Fix that Restart Now might not close Qt Creator The call of QWidget::close() on the main window is blocked by Qt if there are modal windows open. First close/accept all currently open modal dialogs, then close the main window. Reverts a8bc9774f9c1948c603ec23daf47d4c4af67f23f which was specific to the Link with Qt functionality, and generalizes the code in MainWindow::exit(). Fixes: QTCREATORBUG-26525 Task-number: QTCREATORBUG-24098 Change-Id: I4c62f684cdfd749dfb3d3c18bd513b9fee10ddda Reviewed-by: Cristian Adam --- src/plugins/coreplugin/mainwindow.cpp | 25 ++++++++++++++++++++++++- src/plugins/qtsupport/qtoptionspage.cpp | 18 ++++-------------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index bc8e438dcfc..59ba9b08abc 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -92,6 +92,7 @@ #include #include #include +#include using namespace ExtensionSystem; using namespace Utils; @@ -939,6 +940,20 @@ void MainWindow::setFocusToEditor() EditorManagerPrivate::doEscapeKeyFocusMoveMagic(); } +static void acceptModalDialogs() +{ + const QWidgetList topLevels = QApplication::topLevelWidgets(); + QList dialogsToClose; + for (QWidget *topLevel : topLevels) { + if (auto dialog = qobject_cast(topLevel)) { + if (dialog->isModal()) + dialogsToClose.append(dialog); + } + } + for (QDialog *dialog : dialogsToClose) + dialog->accept(); +} + void MainWindow::exit() { // this function is most likely called from a user action @@ -946,7 +961,15 @@ void MainWindow::exit() // since on close we are going to delete everything // so to prevent the deleting of that object we // just append it - QMetaObject::invokeMethod(this, &QWidget::close, Qt::QueuedConnection); + QMetaObject::invokeMethod( + this, + [this] { + // Modal dialogs block the close event. So close them, in case this was triggered from + // a RestartDialog in the settings dialog. + acceptModalDialogs(); + close(); + }, + Qt::QueuedConnection); } void MainWindow::openFileWith() diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp index 0a8d55818a4..b026363b34a 100644 --- a/src/plugins/qtsupport/qtoptionspage.cpp +++ b/src/plugins/qtsupport/qtoptionspage.cpp @@ -177,7 +177,7 @@ public: QtOptionsPageWidget(); ~QtOptionsPageWidget(); - static bool linkWithQt(); + static void linkWithQt(); private: void apply() final; @@ -857,16 +857,7 @@ void QtOptionsPageWidget::setupLinkWithQtButton() QString tip; canLinkWithQt(&tip); m_ui.linkWithQtButton->setToolTip(tip); - connect(m_ui.linkWithQtButton, &QPushButton::clicked, this, [this] { - if (linkWithQt()) { - QWidget *w = window(); - // close options dialog - if (QDialog *dialog = qobject_cast(w)) - dialog->accept(); - else - window()->close(); - } - }); + connect(m_ui.linkWithQtButton, &QPushButton::clicked, this, &QtOptionsPage::linkWithQt); } void QtOptionsPageWidget::updateCurrentQtName() @@ -959,7 +950,7 @@ static FilePath defaultQtInstallationPath() return FileUtils::homePath() / "Qt"; } -bool QtOptionsPageWidget::linkWithQt() +void QtOptionsPageWidget::linkWithQt() { const QString title = tr("Choose Qt Installation"); const QString restartText = tr("The change will take effect after restart."); @@ -1028,9 +1019,8 @@ bool QtOptionsPageWidget::linkWithQt() } if (askForRestart) { Core::RestartDialog restartDialog(Core::ICore::dialogParent(), restartText); - return restartDialog.exec() == QDialog::Accepted; + restartDialog.exec(); } - return false; } // QtOptionsPage From 35e57ca748398edf569d357a7ca192ecc5fd8d5e Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 1 Nov 2021 14:44:32 +0100 Subject: [PATCH 12/57] ClangCodeModel: Make sure not to overwrite macros with their expansion ... when highlighting with clangd. Change-Id: I89ec8bf5a1ed4d43e0e9a398b26705df00ca9a46 Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangdclient.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index 17fe2775074..09f9cedd191 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -3140,6 +3140,18 @@ void ExtraHighlightingResultsCollector::insertResult(const HighlightingResult &r return; const auto it = std::lower_bound(m_results.begin(), m_results.end(), result, lessThan); if (it == m_results.end() || *it != result) { + + // Prevent inserting expansions for function-like macros. For instance: + // #define TEST() "blubb" + // const char *s = TEST(); + // The macro name is always shorter than the expansion and starts at the same + // location, so it should occur right before the insertion position. + if (it > m_results.begin() && (it - 1)->line == result.line + && (it - 1)->column == result.column + && (it - 1)->textStyles.mainStyle == C_PREPROCESSOR) { + return; + } + qCDebug(clangdLogHighlight) << "adding additional highlighting result" << result.line << result.column << result.length; m_results.insert(it, result); From ce924f74b6a11b1447d2d91bddb914f3fa1a79ec Mon Sep 17 00:00:00 2001 From: Jonas Singe Date: Thu, 4 Nov 2021 22:33:48 +0100 Subject: [PATCH 13/57] AutoTest: Set gtest_catch_exceptions=0 during debug runs This allows the debugger to show the code location from which an uncaught exception originates. Change-Id: I6edbc381a4028e95d1844affac85a79ecdf55197 Reviewed-by: Christian Stenger --- src/plugins/autotest/gtest/gtestconfiguration.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/autotest/gtest/gtestconfiguration.cpp b/src/plugins/autotest/gtest/gtestconfiguration.cpp index a4903b075ad..cbdd0c8e8a2 100644 --- a/src/plugins/autotest/gtest/gtestconfiguration.cpp +++ b/src/plugins/autotest/gtest/gtestconfiguration.cpp @@ -55,6 +55,7 @@ QStringList filterInterfering(const QStringList &provided, QStringList *omitted) "--gtest_stream_result_to=", "--gtest_break_on_failure", "--gtest_throw_on_failure", + "--gtest_catch_exceptions=", "--gtest_print_time=" }; @@ -100,6 +101,7 @@ QStringList GTestConfiguration::argumentsForTestRunner(QStringList *omitted) con if (isDebugRunMode()) { if (gSettings->breakOnFailure.value()) arguments << "--gtest_break_on_failure"; + arguments << "--gtest_catch_exceptions=0"; } return arguments; } From a1c476d864822d637f9e2704ca91598761d8b252 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Mon, 8 Nov 2021 16:15:51 +0100 Subject: [PATCH 14/57] QmlDesigner: Avoid exception when database is missing Task-numner: QDS-5365 Change-Id: I0231d7b0fbe29be39ff5f0de4c01efd6073531fa Reviewed-by: Qt CI Bot Reviewed-by: Thomas Hartmann --- .../qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp index c1c086c58d6..1b0fdd5a418 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp @@ -1393,7 +1393,8 @@ void NodeInstanceServer::setTranslationLanguage(const QString &language) engine()->setUiLanguage(language); #endif static QPointer multilanguageTranslator; - if (!MultiLanguage::databaseFilePath().isEmpty()) { + if (!MultiLanguage::databaseFilePath().isEmpty() + && QFileInfo::exists(QString::fromUtf8(MultiLanguage::databaseFilePath()))) { if (!multilanguageLink) { multilanguageLink = std::make_unique(); multilanguageTranslator = multilanguageLink->translator().release(); From 3f0aa40d353ec6101652eace96f9490198c3784e Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Mon, 8 Nov 2021 16:05:38 +0200 Subject: [PATCH 15/57] QmlDesigner: Correct Assets view empty status Make isEmpty a property instead of an invokable method so that Qml side is properly notified when its value changes. Change-Id: I2552b23cc533bbd740902a31bae89b1dfbd3b0cf Reviewed-by: Miikka Heikkinen Reviewed-by: Qt CI Bot Reviewed-by: Thomas Hartmann --- .../qmldesigner/itemLibraryQmlSources/Assets.qml | 2 +- .../itemlibrary/itemlibraryassetsmodel.cpp | 16 +++++++++++++++- .../itemlibrary/itemlibraryassetsmodel.h | 9 ++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml index cd07ba29450..8444a2c88f6 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml @@ -263,7 +263,7 @@ Item { // Placeholder when the assets panel is empty Column { id: colNoAssets - visible: assetsModel.isEmpty() + visible: assetsModel.isEmpty spacing: 20 x: 20 diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp index febaf8a2154..caaaa374528 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.cpp @@ -275,7 +275,8 @@ void ItemLibraryAssetsModel::setRootPath(const QString &path) beginResetModel(); m_assetsDir = new ItemLibraryAssetsDir(path, 0, true, this); - m_isEmpty = parseDirRecursive(m_assetsDir, 1); + bool noAssets = parseDirRecursive(m_assetsDir, 1); + setIsEmpty(noAssets); endResetModel(); } @@ -304,6 +305,19 @@ const QSet &ItemLibraryAssetsModel::supportedSuffixes() const return allSuffixes; } +bool ItemLibraryAssetsModel::isEmpty() const +{ + return m_isEmpty; +}; + +void ItemLibraryAssetsModel::setIsEmpty(bool empty) +{ + if (m_isEmpty != empty) { + m_isEmpty = empty; + emit isEmptyChanged(); + } +}; + const QSet &ItemLibraryAssetsModel::previewableSuffixes() const { static QSet previewableSuffixes; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.h index d79426d40a8..c1dcc845da0 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetsmodel.h @@ -46,6 +46,8 @@ class ItemLibraryAssetsModel : public QAbstractListModel { Q_OBJECT + Q_PROPERTY(bool isEmpty READ isEmpty WRITE setIsEmpty NOTIFY isEmptyChanged) + public: ItemLibraryAssetsModel(QmlDesigner::SynchronousImageCache &fontImageCache, Utils::FileSystemWatcher *fileSystemWatcher, @@ -81,11 +83,16 @@ public: Q_INVOKABLE void toggleExpandAll(bool expand); Q_INVOKABLE DirExpandState getAllExpandedState() const; Q_INVOKABLE void removeFile(const QString &filePath); - Q_INVOKABLE bool isEmpty() const { return m_isEmpty; }; + +signals: + void isEmptyChanged(); private: const QSet &supportedSuffixes() const; + bool isEmpty() const; + void setIsEmpty(bool empty); + SynchronousImageCache &m_fontImageCache; QHash> m_iconCache; From bfe6c46f9f557e3fc63ed2d61bb53b9f36f3ebbf Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 11 Oct 2021 11:49:54 +0200 Subject: [PATCH 16/57] QmlJSEditor: block non Utf8 codecs Additionally adjust the postioning of the initial setCodec to all other forced codecs. Change-Id: Id60bfdac858851e5ad6554ff2dbcb3dd5b806c0b Reviewed-by: Qt CI Bot Reviewed-by: Alessandro Portale --- src/plugins/qmljseditor/qmljseditor.cpp | 2 -- src/plugins/qmljseditor/qmljseditordocument.cpp | 7 +++++++ src/plugins/qmljseditor/qmljseditordocument.h | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index a3c0d8ee2e3..265b59ca1a7 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -131,8 +131,6 @@ void QmlJSEditorWidget::finalizeInitialization() connect(&m_updateOutlineIndexTimer, &QTimer::timeout, this, &QmlJSEditorWidget::updateOutlineIndexNow); - textDocument()->setCodec(QTextCodec::codecForName("UTF-8")); // qml files are defined to be utf-8 - m_modelManager = ModelManagerInterface::instance(); m_contextPane = Internal::QmlJSEditorPlugin::quickToolBar(); diff --git a/src/plugins/qmljseditor/qmljseditordocument.cpp b/src/plugins/qmljseditor/qmljseditordocument.cpp index 59270b2ae0d..13d29e72ccc 100644 --- a/src/plugins/qmljseditor/qmljseditordocument.cpp +++ b/src/plugins/qmljseditor/qmljseditordocument.cpp @@ -45,6 +45,7 @@ #include #include +#include const char QML_UI_FILE_WARNING[] = "QmlJSEditor.QmlUiFileWarning"; @@ -655,9 +656,15 @@ QmlJSEditorDocument::QmlJSEditorDocument(Utils::Id id) connect(this, &TextEditor::TextDocument::tabSettingsChanged, d, &Internal::QmlJSEditorDocumentPrivate::invalidateFormatterCache); setSyntaxHighlighter(new QmlJSHighlighter(document())); + setCodec(QTextCodec::codecForName("UTF-8")); // qml files are defined to be utf-8 setIndenter(new Internal::Indenter(document())); } +bool QmlJSEditorDocument::supportsCodec(const QTextCodec *codec) const +{ + return codec == QTextCodec::codecForName("UTF-8"); +} + QmlJSEditorDocument::~QmlJSEditorDocument() { delete d; diff --git a/src/plugins/qmljseditor/qmljseditordocument.h b/src/plugins/qmljseditor/qmljseditordocument.h index a42b367885d..1c73ed1e32e 100644 --- a/src/plugins/qmljseditor/qmljseditordocument.h +++ b/src/plugins/qmljseditor/qmljseditordocument.h @@ -46,6 +46,8 @@ public: QmlJSEditorDocument(Utils::Id id); ~QmlJSEditorDocument() override; + bool supportsCodec(const QTextCodec *codec) const override; + const QmlJSTools::SemanticInfo &semanticInfo() const; bool isSemanticInfoOutdated() const; QVector diagnosticRanges() const; From eab5315904c78497b39ea88b3e93d1ae842f2c8a Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 4 Nov 2021 22:22:45 +0100 Subject: [PATCH 17/57] Android: Register Lldb if it is present Change-Id: I46a544c0541ca4f0a969064faf055c1e99b9c5ad Reviewed-by: hjk Reviewed-by: Alessandro Portale --- src/plugins/android/androidconfigurations.cpp | 78 +++++++++++++++---- src/plugins/android/androidconfigurations.h | 1 + 2 files changed, 65 insertions(+), 14 deletions(-) diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index c9e3603dddd..0fb2b476e54 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -563,6 +563,16 @@ FilePath AndroidConfig::gdbPathFromNdk(const Abi &abi, const FilePath &ndkLocati QString(QTC_HOST_EXE_SUFFIX))); } +FilePath AndroidConfig::lldbPathFromNdk(const FilePath &ndkLocation) const +{ + const FilePath path = ndkLocation.pathAppended( + QString("toolchains/llvm/prebuilt/%1/bin/lldb%2").arg(toolchainHostFromNdk(ndkLocation), + QString(QTC_HOST_EXE_SUFFIX))); + if (path.exists()) + return path; + return {}; +} + FilePath AndroidConfig::makePathFromNdk(const FilePath &ndkLocation) const { return ndkLocation.pathAppended( @@ -1241,39 +1251,79 @@ static QString getMultiOrSingleAbiString(const QStringList &abis) return containsAllAbis(abis) ? "Multi-Abi" : abis.join(","); } +static const Debugger::DebuggerItem *existingDebugger(const FilePath &command, + Debugger::DebuggerEngineType type) +{ + // check if the debugger is already registered, but ignoring the display name + const Debugger::DebuggerItem *existing = Debugger::DebuggerItemManager::findByCommand(command); + + // Return existing debugger with same command + if (existing && existing->engineType() == type && existing->isAutoDetected()) + return existing; + return nullptr; +} + static QVariant findOrRegisterDebugger(ToolChain *tc, const QStringList &abisList, bool customDebugger = false) { const auto ¤tConfig = AndroidConfigurations::currentConfig(); const FilePath ndk = static_cast(tc)->ndkLocation(); - const FilePath command = currentConfig.gdbPathFromNdk(tc->targetAbi(), ndk); + const FilePath lldbCommand = currentConfig.lldbPathFromNdk(ndk); + const Debugger::DebuggerItem *existingLldb = existingDebugger(lldbCommand, + Debugger::LldbEngineType); + // Return existing debugger with same command - prefer lldb (limit to sdk/ndk min version?) + if (existingLldb) + return existingLldb->id(); + + const FilePath gdbCommand = currentConfig.gdbPathFromNdk(tc->targetAbi(), ndk); // check if the debugger is already registered, but ignoring the display name - const Debugger::DebuggerItem *existing = Debugger::DebuggerItemManager::findByCommand(command); - + const Debugger::DebuggerItem *existingGdb = existingDebugger(gdbCommand, + Debugger::GdbEngineType); // Return existing debugger with same command - if (existing && existing->engineType() == Debugger::GdbEngineType - && existing->isAutoDetected()) { - return existing->id(); + if (existingGdb) + return existingGdb->id(); + + const QString mainName = AndroidConfigurations::tr("Android Debugger (%1, NDK %2)"); + const QString custom = customDebugger ? QString{"Custom "} : QString{}; + // debugger not found, register a new one + // check lldb + QVariant registeredLldb; + if (!lldbCommand.isEmpty()) { + Debugger::DebuggerItem debugger; + debugger.setCommand(lldbCommand); + debugger.setEngineType(Debugger::LldbEngineType); + debugger.setUnexpandedDisplayName(custom + mainName + .arg(getMultiOrSingleAbiString(allSupportedAbis())) + .arg(AndroidConfigurations::currentConfig().ndkVersion(ndk).toString()) + + ' ' + debugger.engineTypeName()); + debugger.setAutoDetected(true); + debugger.reinitializeFromFile(); + registeredLldb = Debugger::DebuggerItemManager::registerDebugger(debugger); + } + + // we always have a value for gdb (but we shouldn't - we currently use a fallback) + if (!gdbCommand.exists()) { + if (!registeredLldb.isNull()) + return registeredLldb; + return {}; } - // debugger not found, register a new one Debugger::DebuggerItem debugger; - debugger.setCommand(command); + debugger.setCommand(gdbCommand); debugger.setEngineType(Debugger::GdbEngineType); // NDK 10 and older have multiple gdb versions per ABI, so check for that. const bool oldNdkVersion = currentConfig.ndkVersion(ndk) <= QVersionNumber{11}; - QString mainName = AndroidConfigurations::tr("Android Debugger (%1, NDK %2)"); - if (customDebugger) - mainName.prepend("Custom "); - debugger.setUnexpandedDisplayName(mainName + debugger.setUnexpandedDisplayName(custom + mainName .arg(getMultiOrSingleAbiString(oldNdkVersion ? abisList : allSupportedAbis())) - .arg(AndroidConfigurations::currentConfig().ndkVersion(ndk).toString())); + .arg(AndroidConfigurations::currentConfig().ndkVersion(ndk).toString()) + + ' ' + debugger.engineTypeName()); debugger.setAutoDetected(true); debugger.reinitializeFromFile(); - return Debugger::DebuggerItemManager::registerDebugger(debugger); + QVariant registeredGdb = Debugger::DebuggerItemManager::registerDebugger(debugger); + return registeredLldb.isNull() ? registeredGdb : registeredLldb; } void AndroidConfigurations::registerCustomToolChainsAndDebuggers() diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index 2110125ad70..84d1142cce4 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -140,6 +140,7 @@ public: Utils::FilePath gdbPath(const ProjectExplorer::Abi &abi, const QtSupport::BaseQtVersion *qtVersion) const; Utils::FilePath gdbPathFromNdk(const ProjectExplorer::Abi &abi, const Utils::FilePath &ndkLocation) const; + Utils::FilePath lldbPathFromNdk(const Utils::FilePath &ndkLocation) const; Utils::FilePath makePathFromNdk(const Utils::FilePath &ndkLocation) const; Utils::FilePath keytoolPath() const; From 1021c1b42d8cad6d7360dd6f396e635ec79386f6 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 5 Nov 2021 15:47:01 +0200 Subject: [PATCH 18/57] QmlDesigner: Fix property binding after drag from component library Restricted the properties offered for a newly created node to be bound to after a drag from component library. Read only properties are no longer offered for binding. Properties of common base types are also omitted due to large amount of invalid properties offered. Fixes: QDS-5357 Change-Id: I96fea067c3c4f64dd60d7cb6edebd4333c9fb51a Reviewed-by: Samuel Ghinet Reviewed-by: Mahmoud Badri Reviewed-by: Qt CI Bot Reviewed-by: Thomas Hartmann --- .../choosefrompropertylistdialog.cpp | 99 ++++++++++++++----- .../navigator/choosefrompropertylistdialog.h | 12 ++- .../navigator/navigatortreemodel.cpp | 35 +++---- 3 files changed, 96 insertions(+), 50 deletions(-) diff --git a/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp b/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp index 598f2ade758..b7d9fb6b9e9 100644 --- a/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp +++ b/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp @@ -29,12 +29,12 @@ namespace QmlDesigner { -// This dialog displays all given type properties of an object and allows the user to choose one -ChooseFromPropertyListDialog::ChooseFromPropertyListDialog(const ModelNode &node, TypeName type, QWidget *parent) +// This dialog displays specified properties and allows the user to choose one +ChooseFromPropertyListDialog::ChooseFromPropertyListDialog(const QStringList &propNames, + QWidget *parent) : QDialog(parent) , m_ui(new Ui::ChooseFromPropertyListDialog) { - m_propertyTypeName = type; m_ui->setupUi(this); setWindowTitle(tr("Select property")); m_ui->label->setText(tr("Bind to property:")); @@ -50,7 +50,7 @@ ChooseFromPropertyListDialog::ChooseFromPropertyListDialog(const ModelNode &node QDialog::accept(); }); - fillList(node); + fillList(propNames); } ChooseFromPropertyListDialog::~ChooseFromPropertyListDialog() @@ -63,31 +63,80 @@ TypeName ChooseFromPropertyListDialog::selectedProperty() const return m_selectedProperty; } -void ChooseFromPropertyListDialog::fillList(const ModelNode &node) +// Create dialog for selecting any property matching newNode type +// Subclass type matches are also valid +ChooseFromPropertyListDialog *ChooseFromPropertyListDialog::createIfNeeded( + const ModelNode &targetNode, const ModelNode &newNode, QWidget *parent) { - // Fill the list with all properties of given type - const auto metaInfo = node.metaInfo(); - const auto propNames = metaInfo.propertyNames(); - const TypeName property(m_propertyTypeName); - QStringList nameList; + TypeName typeName = newNode.type(); + + // Component matches cases where you don't want to insert a plain component, + // such as layer.effect. Also, default property is often a Component (typically 'delegate'), + // and inserting into such property will silently overwrite implicit component, if any. + if (typeName == "QtQml.Component") + return nullptr; + + const NodeMetaInfo metaInfo = targetNode.metaInfo(); + const PropertyNameList propNames = metaInfo.propertyNames(); + QStringList matchingNames; + + // Common base types cause too many rarely valid matches, so they are ignored + const QSet ignoredTypes {".QObject", + ".QQuickItem", + "QtQuick.Item", + "QtQuick3D.Object3D", + "QtQuick3D.Node"}; + for (const auto &propName : propNames) { - if (metaInfo.propertyTypeName(propName) == property) - nameList.append(QString::fromLatin1(propName)); - } - - if (!nameList.isEmpty()) { - QString defaultProp = nameList.first(); - - nameList.sort(); - for (const auto &propName : qAsConst(nameList)) { - QListWidgetItem *newItem = new QListWidgetItem(propName); - m_ui->listProps->addItem(newItem); + const TypeName testType = metaInfo.propertyTypeName(propName); + if (!ignoredTypes.contains(testType) + && metaInfo.propertyIsWritable(propName) + && (testType == typeName || newNode.isSubclassOf(testType))) { + matchingNames.append(QString::fromLatin1(propName)); } - - // Select the default prop - m_ui->listProps->setCurrentRow(nameList.indexOf(defaultProp)); - m_selectedProperty = defaultProp.toLatin1(); } + + if (!matchingNames.isEmpty()) + return new ChooseFromPropertyListDialog(matchingNames, parent); + + return nullptr; +} + +// Create dialog for selecting writable properties of exact property type +ChooseFromPropertyListDialog *ChooseFromPropertyListDialog::createIfNeeded( + const ModelNode &targetNode, TypeName type, QWidget *parent) +{ + const NodeMetaInfo metaInfo = targetNode.metaInfo(); + const PropertyNameList propNames = metaInfo.propertyNames(); + const TypeName property(type); + QStringList matchingNames; + for (const auto &propName : propNames) { + if (metaInfo.propertyTypeName(propName) == property && metaInfo.propertyIsWritable(propName)) + matchingNames.append(QString::fromLatin1(propName)); + } + + if (!matchingNames.isEmpty()) + return new ChooseFromPropertyListDialog(matchingNames, parent); + + return nullptr; +} + +void ChooseFromPropertyListDialog::fillList(const QStringList &propNames) +{ + if (propNames.isEmpty()) + return; + + QString defaultProp = propNames.first(); + QStringList sortedNames = propNames; + sortedNames.sort(); + for (const auto &propName : qAsConst(sortedNames)) { + QListWidgetItem *newItem = new QListWidgetItem(propName); + m_ui->listProps->addItem(newItem); + } + + // Select the default prop + m_ui->listProps->setCurrentRow(sortedNames.indexOf(defaultProp)); + m_selectedProperty = defaultProp.toLatin1(); } } diff --git a/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.h b/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.h index 2d2612e0a8a..4cc59242f19 100644 --- a/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.h +++ b/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.h @@ -40,16 +40,22 @@ class ChooseFromPropertyListDialog : public QDialog Q_OBJECT public: - explicit ChooseFromPropertyListDialog(const ModelNode &node, TypeName type, QWidget *parent = 0); ~ChooseFromPropertyListDialog(); TypeName selectedProperty() const; + static ChooseFromPropertyListDialog *createIfNeeded(const ModelNode &targetNode, + const ModelNode &newNode, + QWidget *parent = 0); + static ChooseFromPropertyListDialog *createIfNeeded(const ModelNode &targetNode, + TypeName type, + QWidget *parent = 0); + private: - void fillList(const ModelNode &node); + explicit ChooseFromPropertyListDialog(const QStringList &propNames, QWidget *parent = 0); + void fillList(const QStringList &propNames); Ui::ChooseFromPropertyListDialog *m_ui; TypeName m_selectedProperty; - TypeName m_propertyTypeName; }; } diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index cb98389b171..0eed7dec4af 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -739,25 +739,13 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in } } else { ModelNode targetNode = targetProperty.parentModelNode(); - NodeMetaInfo metaInfo = targetNode.metaInfo(); - TypeName typeName = newModelNode.type(); - - // Empty components are not supported and having one as property value is generally - // unstable, so let's not offer user to put a fresh Component into a property - if (typeName != "QtQml.Component") { - const PropertyNameList nameList = targetNode.metaInfo().directPropertyNames(); - for (const auto &propertyName : nameList) { - auto testType = metaInfo.propertyTypeName(propertyName); - if (testType == typeName || newModelNode.isSubclassOf(testType)) { - ChooseFromPropertyListDialog *dialog = nullptr; - dialog = new ChooseFromPropertyListDialog(targetNode, testType, Core::ICore::dialogParent()); - dialog->exec(); - if (dialog->result() == QDialog::Accepted) - targetNode.bindingProperty(dialog->selectedProperty()).setExpression(newModelNode.validId()); - delete dialog; - break; - } - } + ChooseFromPropertyListDialog *dialog = ChooseFromPropertyListDialog::createIfNeeded( + targetNode, newModelNode, Core::ICore::dialogParent()); + if (dialog) { + dialog->exec(); + if (dialog->result() == QDialog::Accepted) + targetNode.bindingProperty(dialog->selectedProperty()).setExpression(newModelNode.validId()); + delete dialog; } } @@ -1015,10 +1003,13 @@ bool NavigatorTreeModel::dropAsImage3dTexture(const ModelNode &targetNode, if (targetNode.isSubclassOf("QtQuick3D.Material")) { // if dropping an image on a default material, create a texture instead of image ChooseFromPropertyListDialog *dialog = nullptr; - if (targetNode.isSubclassOf("QtQuick3D.DefaultMaterial") || targetNode.isSubclassOf("QtQuick3D.PrincipledMaterial")) { + if (targetNode.isSubclassOf("QtQuick3D.DefaultMaterial") + || targetNode.isSubclassOf("QtQuick3D.PrincipledMaterial")) { // Show texture property selection dialog - dialog = new ChooseFromPropertyListDialog(targetNode, "QtQuick3D.Texture", Core::ICore::dialogParent()); - dialog->exec(); + dialog = ChooseFromPropertyListDialog::createIfNeeded(targetNode, "QtQuick3D.Texture", + Core::ICore::dialogParent()); + if (dialog) + dialog->exec(); } if (!dialog || dialog->result() == QDialog::Accepted) { m_view->executeInTransaction("NavigatorTreeModel::dropAsImage3dTexture", [&] { From f6c974fc1bf20211d7f6cc9c464a0fd00ba79168 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 4 Nov 2021 12:41:20 +0100 Subject: [PATCH 19/57] CPlusPlus: Fix "Find references" ... for certain types of template/namespace combinations. This essentially reverts 2798c11d1d. Fixes: QTCREATORBUG-26520 Change-Id: I1ab0e4e19bd09695d1536bf6f10960107e9ecbc4 Reviewed-by: Christian Stenger --- src/libs/cplusplus/ResolveExpression.cpp | 2 +- src/plugins/cppeditor/cppquickfix_test.cpp | 1 + .../cplusplus/findusages/tst_findusages.cpp | 40 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp index f59dcdac427..99db8cef9df 100644 --- a/src/libs/cplusplus/ResolveExpression.cpp +++ b/src/libs/cplusplus/ResolveExpression.cpp @@ -910,7 +910,7 @@ bool ResolveExpression::visit(CallAST *ast) if (Symbol *declaration = templateTy->declaration()) { if (Function *funTy = declaration->asFunction()) { if (maybeValidPrototype(funTy, actualArgumentCount)) - addResult(funTy->returnType().simplified(), _scope); + addResult(funTy->returnType().simplified(), scope); } } } diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 5a0e21ad693..dd85e95470e 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -213,6 +213,7 @@ QuickFixOperationTest::QuickFixOperationTest(const QList &testD QuickFixOperations operations; factory->match(quickFixInterface, operations); if (operations.isEmpty()) { + QEXPECT_FAIL("CompleteSwitchCaseStatement_QTCREATORBUG-25998", "FIXME", Abort); QVERIFY(testDocuments.first()->m_expectedSource.isEmpty()); return; } diff --git a/tests/auto/cplusplus/findusages/tst_findusages.cpp b/tests/auto/cplusplus/findusages/tst_findusages.cpp index cee57808e61..e43d1692b8f 100644 --- a/tests/auto/cplusplus/findusages/tst_findusages.cpp +++ b/tests/auto/cplusplus/findusages/tst_findusages.cpp @@ -112,6 +112,7 @@ private Q_SLOTS: void using_insideNamespace(); void using_insideFunction(); void templatedFunction_QTCREATORBUG9749(); + void templateInNamespaceTypeOutside(); void usingInDifferentNamespace_QTCREATORBUG7978(); @@ -1228,6 +1229,45 @@ void tst_FindUsages::templatedFunction_QTCREATORBUG9749() QCOMPARE(findUsages.usages().at(1).type, Usage::Type::Other); } +void tst_FindUsages::templateInNamespaceTypeOutside() +{ + const QByteArray src = R"( +struct S { int v; }; +namespace N { +template struct Ptr { + T* operator->() { return {}; } +}; +template Ptr makePtr() { return {}; } +} +int func() +{ + auto s = N::makePtr(); + return s->v; +})"; + + Document::Ptr doc = Document::create("templateInNamespaceTypeOutside"); + doc->setUtf8Source(src); + doc->parse(); + doc->check(); + + QVERIFY(doc->diagnosticMessages().isEmpty()); + QCOMPARE(doc->globalSymbolCount(), 3); + + Snapshot snapshot; + snapshot.insert(doc); + + Class * const structDecl = doc->globalSymbolAt(0)->asClass(); + QVERIFY(structDecl); + QCOMPARE(structDecl->memberCount(), 1); + Symbol * const v = structDecl->memberAt(0); + + FindUsages findUsages(src, doc, snapshot, true); + findUsages(v); + QCOMPARE(findUsages.usages().size(), 2); + QCOMPARE(findUsages.usages().at(0).type, Usage::Type::Declaration); + QCOMPARE(findUsages.usages().at(1).type, Usage::Type::Read); +} + void tst_FindUsages::usingInDifferentNamespace_QTCREATORBUG7978() { const QByteArray src = "\n" From 1b6d374d62fd3563aadf91e0db1594003f6c29d3 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 9 Nov 2021 10:17:48 +0100 Subject: [PATCH 20/57] QmlPuppet: Fix qbs build Amends b8b6af0dbb6c077daf2ef4f26f773e2af58846f3. Change-Id: If3dc168243939c90205ad274cf61b2d0d2e03cc3 Reviewed-by: Christian Kandeler --- src/tools/qml2puppet/qml2puppet.qbs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/qml2puppet/qml2puppet.qbs b/src/tools/qml2puppet/qml2puppet.qbs index 626aed22255..9f90a0e29a0 100644 --- a/src/tools/qml2puppet/qml2puppet.qbs +++ b/src/tools/qml2puppet/qml2puppet.qbs @@ -16,6 +16,8 @@ QtcTool { ] } Depends { name: "Qt.quick3d-private"; required: false } + Depends { name: "Qt.quick3dparticles-private"; required: false } + property bool useQuick3d: Utilities.versionCompare(Qt.core.version, "5.15") >= 0 && Qt["quick3d-private"].present property bool useParticle3d: Utilities.versionCompare(Qt.core.version, "6.2") >= 0 From d33cd5194ab6f51ee25836debb5d955400d7d7af Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Mon, 8 Nov 2021 13:07:00 +0100 Subject: [PATCH 21/57] Debugger: Consolidate search code for python-path Not just to deduplicate/reuse code but also to make make it clear that different places where lldb is called, the same preparations have to be done. Change-Id: I104aca845fd7b42f63443bda2502574f4d28b411 Reviewed-by: Christian Stenger --- src/plugins/debugger/debuggeritem.cpp | 32 ++++++++++++++---------- src/plugins/debugger/debuggeritem.h | 2 ++ src/plugins/debugger/lldb/lldbengine.cpp | 14 +---------- 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp index 2e689ae9d3d..85206926fb8 100644 --- a/src/plugins/debugger/debuggeritem.cpp +++ b/src/plugins/debugger/debuggeritem.cpp @@ -144,8 +144,6 @@ void DebuggerItem::createId() void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *error) { - const bool isAndroid = m_command.path().contains("/ndk/") - || m_command.path().contains("/ndk-bundle/"); // CDB only understands the single-dash -version, whereas GDB and LLDB are // happy with both -version and --version. So use the "working" -version // except for the experimental LLDB-MI which insists on --version. @@ -167,10 +165,12 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro return; } + Environment env = sysEnv.size() == 0 ? Environment::systemEnvironment() : sysEnv; // Prevent calling lldb on Windows because the lldb from the llvm package is linked against // python but does not contain a python dll. + const bool isAndroidNdkLldb = DebuggerItem::addAndroidLldbPythonEnv(m_command, env); if (HostOsInfo::isWindowsHost() && m_command.fileName().startsWith("lldb") - && !isAndroid) { + && !isAndroidNdkLldb) { QString errorMessage; m_version = winGetDLLVersion(WinDLLFileVersion, m_command.absoluteFilePath().path(), @@ -180,16 +180,6 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro return; } - Environment env = sysEnv.toProcessEnvironment().isEmpty() ? Environment::systemEnvironment() - : sysEnv; - if (isAndroid && m_command.fileName().startsWith("lldb")) { - FilePath pythonPath = m_command.parentDir().parentDir().pathAppended("python3"); - if (HostOsInfo::isAnyUnixHost()) - pythonPath = pythonPath.pathAppended("bin"); - if (pythonPath.exists()) - env.prependOrSetPath(pythonPath.toUserOutput()); - } - QtcProcess proc; proc.setEnvironment(env); proc.setCommand({m_command, {version}}); @@ -275,6 +265,22 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro m_engineType = NoEngineType; } +bool DebuggerItem::addAndroidLldbPythonEnv(const Utils::FilePath &lldbCmd, Utils::Environment &env) +{ + if (lldbCmd.baseName().contains("lldb") && + (lldbCmd.path().contains("/ndk/") || lldbCmd.path().contains("/ndk-bundle/"))) { + const FilePath pythonDir = lldbCmd.parentDir().parentDir().pathAppended("python3"); + const FilePath pythonBinDir = + HostOsInfo::isAnyUnixHost() ? pythonDir.pathAppended("bin") : pythonDir; + if (pythonBinDir.exists()) { + env.set("PYTHONHOME", pythonDir.path()); + env.prependOrSetPath(pythonBinDir.path()); + return true; + } + } + return false; +} + QString DebuggerItem::engineTypeName() const { switch (m_engineType) { diff --git a/src/plugins/debugger/debuggeritem.h b/src/plugins/debugger/debuggeritem.h index 12bc903bdd0..f8d5e602ded 100644 --- a/src/plugins/debugger/debuggeritem.h +++ b/src/plugins/debugger/debuggeritem.h @@ -107,6 +107,8 @@ public: QString detectionSource() const { return m_detectionSource; } void setDetectionSource(const QString &source) { m_detectionSource = source; } + static bool addAndroidLldbPythonEnv(const Utils::FilePath &lldbCmd, Utils::Environment &env); + private: DebuggerItem(const QVariant &id); void initMacroExpander(); diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index ad2f4f2974e..49124aca320 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -204,18 +204,6 @@ static QString adapterStartFailed() return LldbEngine::tr("Adapter start failed."); } -static void addAndroidPythonDir(const FilePath &lldbCmd, Environment &env) -{ - if (!lldbCmd.path().contains("/ndk/") && !lldbCmd.path().contains("/ndk-bundle/")) - return; - - FilePath androidPythonDir = lldbCmd.parentDir().parentDir().pathAppended("python3"); - if (HostOsInfo::isAnyUnixHost()) - androidPythonDir = androidPythonDir.pathAppended("bin"); - if (androidPythonDir.exists()) - env.prependOrSetPath(androidPythonDir.path()); -} - void LldbEngine::setupEngine() { QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); @@ -225,7 +213,7 @@ void LldbEngine::setupEngine() showMessage("STARTING LLDB: " + lldbCmd.toUserOutput()); Environment environment = runParameters().debugger.environment; environment.appendOrSet("PYTHONUNBUFFERED", "1"); // avoid flushing problem on macOS - addAndroidPythonDir(lldbCmd, environment); + DebuggerItem::addAndroidLldbPythonEnv(lldbCmd, environment); m_lldbProc.setEnvironment(environment); if (runParameters().debugger.workingDirectory.isDir()) From 122edddb6a541d70d6f0fa7ed1707770d59e16f1 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 9 Nov 2021 10:11:44 +0100 Subject: [PATCH 22/57] Debugger: Robustify view access Task-number: QTCREATORBUG-26449 Change-Id: Ic13508e15bc9e33ce0641703f8827870adeaf2d4 Reviewed-by: Christian Kandeler --- src/plugins/debugger/debuggerengine.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index ebe4ac3c04f..cc1c6d6396b 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -931,22 +931,27 @@ void DebuggerEngine::showStatusMessage(const QString &msg, int timeout) const void DebuggerEngine::updateLocalsWindow(bool showReturn) { + QTC_ASSERT(d->m_returnWindow, return); + QTC_ASSERT(d->m_localsView, return); d->m_returnWindow->setVisible(showReturn); d->m_localsView->resizeColumns(); } bool DebuggerEngine::isRegistersWindowVisible() const { + QTC_ASSERT(d->m_registerWindow, return false); return d->m_registerWindow->isVisible(); } bool DebuggerEngine::isPeripheralRegistersWindowVisible() const { + QTC_ASSERT(d->m_peripheralRegisterWindow, return false); return d->m_peripheralRegisterWindow->isVisible(); } bool DebuggerEngine::isModulesWindowVisible() const { + QTC_ASSERT(d->m_modulesWindow, return false); return d->m_modulesWindow->isVisible(); } From a59797afa515dc2ef65a8279ea7a0c1993cd22c1 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 8 Nov 2021 14:02:21 +0100 Subject: [PATCH 23/57] Doc: Update info about using CMake Update screenshots. Task-number: QTCREATORBUG-26278 Change-Id: I069908acf0cf4cf529460286362b4da579cba8f3 Reviewed-by: Cristian Adam --- .../images/qtcreator-build-cmake-output.png | Bin 28639 -> 27900 bytes ...qtcreator-cmake-build-settings-initial.png | Bin 18765 -> 28157 bytes .../images/qtcreator-projects-view-cmake.png | Bin 10589 -> 0 bytes .../images/qtcreator-projects-view-edit.png | Bin 14527 -> 10482 bytes .../creator-projects-cmake-building.qdoc | 5 ++++- .../src/cmake/creator-projects-cmake.qdoc | 17 ++++++++++------- 6 files changed, 14 insertions(+), 8 deletions(-) delete mode 100644 doc/qtcreator/images/qtcreator-projects-view-cmake.png diff --git a/doc/qtcreator/images/qtcreator-build-cmake-output.png b/doc/qtcreator/images/qtcreator-build-cmake-output.png index 886380206524419ff087356ee49a4066ec15bf6b..4311c61249a06b837f7581ba0151536bfd3cb333 100644 GIT binary patch literal 27900 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 diff --git a/doc/qtcreator/images/qtcreator-cmake-build-settings-initial.png b/doc/qtcreator/images/qtcreator-cmake-build-settings-initial.png index 0fce3dd71165b6b894c20860f9bf4c4a0acdffa7..ce7f75f881fd94db67c52c06726f88f3b62a8424 100644 GIT binary patch literal 28157 zcmeAS@N?(olHy`uVBq!ia0y~yU|P+XX&V_S85v!-=bQP_ zKm7haHUS4*i;9xIuAnYxJvoxPt=dE3zKfcJQp2qc{V8xO(#fMI% zv^@MfH}MoB1H-Si3|`ZBT(*66EA;#Z{sTXstrR)%z=d=D+b_X<3=9{HSrerHF1k7Q z+x=Ln`{F?i)_yZjFg#lksSR?9NW=TtuhTY`9$Pfureta3>2T2l2^zn}*(zBRn4eoe zFHaG7yPUak@t5qLf9vZttbN%IFNtDI;c_XP;Br`L?M=?fhBpszF)$oR{mN)kowkr6 zDE8M|E`_`H>yJeqF_UJUFkAZKytxNIGzEif(@U0X$k~0~fl-F<^4Tvg?KM+2BseJg zgbMHTOt~J|(8JX6&BT3cTKZ|#yyNqvK%utUP`IG1mf`IDO{Vt~J>ooP_bSeFyYOb^ z+;^>_4pk9LY^{}^2A^Nbz`zjk!G_`WnXKvciL49!e!c!<+YrDWQg>a|=pw(pJ?jNk z>x%}AvJ4Ci8@_Nke94?{t-ppLB;Dqrcw-Bn#^l0It_9g;hgLEO?~UbTVA$}BOW}>{ zdn>L9v!o-ItO|9|S-`&_x@=CFq--!NBSS)~8{?zS{6(d=Gvyj4i@cObs(;_VV0Q@X z@(){28_d#BcpO;fXUM<6)_PgU)x#^B7#KD%88be$`Br#+`hB5%=55C(rgdHK z`+d%yIpx#eGpdLCd`pZkIDR=&(vppUxTN$ z>3!0Mczx`_k9sgH{ug}ZPef$2se8P>8G_C%XPRo>H zcYX@9e=VWvz!|`_i6wwxb>qaGXS43^EPfu$v%6uYR*Kf7m418ICQo5db>O@q2|Nj1-pKzn~Y=}zm++Q)rH5k1bgjRSlux>EoI#6==!QKtsvsZeoOpo_}1u;34 za{)uxO8y7QJi9kMjkX6H_GLLs0D}et59@);^Mw|$1TZu(9jN#g$TWpP^+GVMq%-T8#QUo}o>y2IS!foSTHVX?{C{*t=96bZcXyY+S57}) zFDCxt&u?~l)w3;U{`Gx5bonWDDVi}UBzS5EF;y<)Q-RlEvtooEMGaN{Lkw(Hs6^<92E1Ee2ovEc&?;r!kVx;q*B}O+m@pN z44*?7o=H~x`+WZS%C7BoTnjua!+xxp%M`IOM*oqX#@_wf-R$@4|I4s$DB()Td;70a zt6_Kf`??oze!l$iXLs|n_08|k9bbOlKIANa=h~Hb_tpNE|NrB7{m-;-GyXby1Wyb) zZ@0hCH-DMkEUWOpw|DxTTd?Tg$Nu_1-3FhROXXZsRS4cEwf(k^SHjmK+yA>2zAD5W z`?S(4L5MY=BzyYZ=kCXy*I$m~k>p`dRAH{Z;wSPsL89zmcl^}Lo@IS*{}fz><9MQ{ zY?Phb6U!76G~3>Ixwl%Wg-N16-~D}M7E>hoPdRql%-&X1aj3`FXCXt%S#2}z)n!u@ z=U=y;oh(%TzLEEv?5@PCt_`pLi7#T1x-Rd*u(j;$mQyE%JW}iTaXH+JxM_Xy&8Gdk zb9OtgO0MZoQsz(Im&1BtR(5gj-#K>nvcD~7tSDG^=IfpJO)1_!mB+erUbvdv{^Pfh zVU6fIzp{DxqWjF>?riqZn!c?6OS(uymDTyb=983O-Tr>=YR9CcH}}(Ad>z!v6FvT4 zSy>dIl94t`FsA{Y0>BXPG@b6Z(p_T$-}bU9FcB8 zY+oK74?A4u?BBYv^x^K7lgbF~b|N-dvH$=$84WO(-JCGN6dhF>pJ@?D;u`)Ygl+|{aG*ACD2 zYz;NG6Ry0z<*6IvEfI&G&-V$>I6L=cYlxgu+3nT)9RJ+V>TG!Y_%Z9R{dbZtXa(;r zJG=bU-*sD9?f$x!t!dBRDJ*Qh;Jx?k=&gmEe#hAjZz9^2W0O2`@)rQE3jeL;XB3C ze5Y4jY?yah!(rdy{f{*q>{c$iysx%rarCWCiy5k`tKVB!XK9^UUAx=XuJ+ZoxBL(1 z{SAL!>abn4uKc5jJ^RIk*GaG_IF)krOV+HY-FnMUo!!OKH2Y$z?k?fS2@e&&#%ktW zNc#Qf%a=VrgFAl)c|Bm-x$SpX&MoHK-0FhGdkQPd4_@Bn{(t4_f9vOMi+kky#5|N~ z?mqSh&sHvde(GxRqeU|to-VQcznE#;^O}lDue}5OmM=G$#kpeJ+Rt1Hg}Y*cj^-S> zc(Oobdb5?V!R&1(MH+s~G=y`Wa?iZ{t19ZM(C0q|)=eCK{;{T6W%Kq|m3A>XFvi3% zu<-BNQ5Neqb@p;50YBf}!khj4-FcmN*W#IXIK$*;yEsE^W?E@A_?$VtgrTYA z+R2mgk6fRW2eDpAex%s;^oQDl$nzifw%+_3zQ3ow>X+QMwluAvS2wp`fE3*aQl~R; zDJ;o2qAvC5Zyk6t}*Q{c? zkty~6P-wn9|6C@CUbj!zi_*99gIvC06<5OViYZ?%Pvy3kd{OP_V^LvZU^wtd)WLLxzSYlU)`EyuNj|CbwpLOy%S9XRz87(L`~I}V zmJc1E&^W5qP{ouG$H*eB_TgJ$l88dy_x`>yw}ct!?>1Vv-Uwe!VztMb(ncHZCl_R?-{)_|`{ zSM=`84!!V&k>}4!wmNwR1_p+hE~XPEr&^gfmVI*NT40&8M57^BTJ2)`f__H^28IJM zq79FxF6F+?_GbIlnGMf0a^((e<5}!0=K>0xm`TtE2Mr<*sqqbt{0r=?1&^QUf*Oy> zU;zyVaHAa>y`Zq8wqsbq3C@8rKo8U+0|ge$QP<|>@BjNvv@P*Q)~w2=mHyjaU%y}Z zdhPam5!uF)CO2Ie4}6&s?Xgycf#Gz2Wz))c|6g5Q9UUG0`}c45>@2lxwPv;1*Y8)d zvw~W84vZo*j&1zdSN`tK&yuxgQ!b=jP7#C4$bI_#{eArBnZ&6+A6&Aqr@Pbfl;bwja9R@Q+R6{p|I^Bh-ikMr1k{APi{{@HitWRz^Vs~R!q zkRE&7?p?JutDIN0m-H>SZl1iW7_33y1w_*nT^|gmNUG&yZie^mT!O3CtjXEzkZ8W+9u0r)(bnH9I~BXd-m>Xm4yOv?k=dy1* zKE6yVKI%RHmCc=p7t}Px>tEz4^IpGl^~}*#ezSJZI<`p1eBRa_*0WN=mw%4gx1#P< z?UE%1enBgx+ti&47X^B63RVqXX0w>VD)!pDsp-5T2Y!C%KXsP<{`~cQY%^vvy?B)x z$dJ95p=-JSIo+A<6U+bW&t;n7$|b&xLGQ)s<+fhCHhKp#crp1LJza9ZWcjzMB}O-H zEaGcemX{-{7&6^biqAc8^S>p2Q*ZKJdhqn)$i()*G}!>w6U?0 zI~&CKMEm?DO>iU9qS4k~c7A=iK)(L&nK|d&8TVL7&)@5Fx~XFED>IEZU-|8|>4nzq%Hn2+{(t{psoQ4kvn=lakJPXF@9YB@ zR^GmC`=cp6yWqSy|GrWwZ}+vSZ`-EUu6=48 z?wzP+w%%0Ca$#=ugF+{lPHv zObIrPone$1w`uX8sP^Sz6_H`i@^6})7!Nhec)_p(WcZtr8dkl*6C?uPmbo4fC~UbB9^NwndnO>JKJym|Bb zSMTTFXPw`*>epS?Debcpj>d`a;uC%w;m7)5&ujCYeT=1xzio{dduJ8E@M`_NjqB?x zL{?8IN`LrocKlTpQ@eY!=U$L`wB*d%{Bx%!Xf#Y=3Yfok(@SHEkI`C>3x9|hNYDIO zanU%kFV9N;Wl{!{M)K!Jia|?N>ZTmm^f@*yoMGMKd(xcmF0EOASzwCWDt?86EzLU| z7Nx9seu^i5HUGzJht@Ei5X((cIIMkp$AQI)47qFWiaWm&sQVjSXQA*lJDv4G`7`m# zi7QvRPRf0BJ7e+Ubz7Hh=w=cyb<8+5ZBk~*hUE;q?uG@2&pY{U>ox0aHm(QV`ulz) zFjbemnwPfx{E>5?-+y~s_V@6zglkA|x;UiO9JzKPE(PSz0z*+9u2W zl?)$a_HSV_csMt@x9a8B_+nYkbyL@$@$fhozM{5f#xt!0r;TO)i_|il)N_A(Fz{FD zb=FsDeyQ^~PPPYr4#_R+a!bFPqWS$t|Irk#!#6&09jNX*&e<`iYRbuiskFrYu&Dha=Y}qEQsNo#@+hmwNF~O4ourQYh}TV{d_uB z^NYSuoPNlU>%iGrJ#HF8s*e}lz2?risOIdVPbK@WU(wnt!nNSz>1zkut>=2L|6Bd` zt@r$YYi{M0i9S4j?(+NH|Cs%gb=EU!MBkfb9^1h5;qPBpQHP7K6MiwTsxSO``8+d+ z{Oeq<1GZdO8}EhbOPE>+oxk=gV22b{~0e!Vt*rp;%YulLV~-JTMdlazDF@3Wtesl@iP;j5Ngxfwq`c6h(rQbp$S zaE8tlmZuj!3CRCWHoUbpjO%i}tL~X5n>*gyf*$;Q&-i2S@ss*2H!f%H|0TFgUGbTa z*p{THD*sm;I&HGTSZ>j85C4VpR8}&)@w}{DvU1W#cSfV_p}THahtK1Dx7DxwTB-&^ z_NCX{(_<|DDKt#s{B6|>;aR7K)PGtZmhKJZ`Mk4+xjtgo@8uky+;tTW zT$=VlOU?SP=HYeoD;*dYFf3d6YXZZ3ekVqT>HO0eKkj`JsWD>;(~Y}#YqztfZR%uV z2x9|bC&mQ~pn*)=Foy7TF*{3NUwiiKS=H|P$&QnKCr64v+6e&#Z*P@87SF%8XXob4 zn|Ciu+mvRMv8nRyuTl{PpOf3~*Zt-?Y>;Dm*5=?9_1Pc0k6G{Acx_twf6#zb!@MRY z1_lO@ix@yH5>i`V4XTY(8x434U(3%`5n` zYTtnTav+uk)KvgA`9NII&}{&N{`q6)&c!XUJ$_g|zCZr|hYeOsZgD*7EI%|!yWwC! z%-@R_{dS$3IbreQ+;_GN4O@d4dY|jn{JClVR&U8-CI{g)EleBg_J%MYX5?aESWwTk zVD))7#x+Zsc9fO=t}wB)1hsL$_+i$pzy8JX=*{^%-+qtSWA0}<>+An)>Uz>@`)8s= z_6q*r$5@Z$>bo%R*;{O4w3i`_HzX{x$>_;~dpCQ;SzgvU_^^SH-v=QDQsz8oVa# zITEcO!#JgW7hl7ru9J*$Ck`j7h`iZmxlM?xN0xzM%{iL}ci-~AXG9$?dM4cZa&`a7 z&t-GFIEv@7FYw`*ptyA%lL!ODfv7KxHbu(cm&yNow3s3E$@=r>;=B_t^8B|xu3uI) znXTY9ca`{pc`N~WzxCO>Z2jarDw&%n8!l#GV9>Vacd&RPe)iqw&3Akbs706vZ+Lfm z`rMyK=dVlN-*H5v>4P;(k-`BMH%6Uz)eQSqPh)00t8t*fBCE{gAlLEuw^kE_*^ixJ zVPS}Uwlv@i7*(*vwkSe)L@9%!1O_OMybJ4 z>%zR8-#;<}+Rc~!48Jeh>({1y)jwX?ZtKeZ@k%2)9V%#&GPi|A}g6&CjJ$70~r{&!x@f!|DT>&|L^ns zK!yTME(fbsi)PNtn9|?Yn$JJ$sJhX-wTJxQh5Tnzzoqr~?VDI8chRc*D@7b0T)AC4 zZ?aA)yTkF8pRx>9i*4321pSnfC{10wDKY4JHrLck#g&&X=exel9EvzZF|_GhGL&wYE-j-h%4z>}kAnFOqx zYh0xtRprX|-g(1fX{=yA{g7CPy5pTIEm}q97bXZfl>Yg+M}T3+mzfRv=Z~e|Us6~5 z+ZoEtiuCMxX`1P~O&%ciAzn<{;@KkQ^)@0b)`nAy6oz2Pw^?ODxb-2usD#xe^$xs?|RQa{$&2J_L7RJqJrUs`8k)fe-;S~ zU43nO@q<^vUE93^Ej{|%S2;;oGenrO8f^T2wMn!qvF6*MzdsLmTP-oPFVN%;i)LKo zp!D33e}QDhwB$>1&KJz@SMTJ^n{1^uTjhRzwK2=PIwo zrFlnMuE%Oheid2(suU78Ec*KX&VKn%Z_ao$xaU3Ro;+={vB-f*d$}L%sk`t>^gUC@ z$yXN-6j(g<{U|wC?R@(4UE=F6nWhV_m-YLg=TLU(&Kr>i-QI&6OBQ`(ImwyE)b{>g zXHf6b(B**)kqRGcSU0+hcDR}*h%h8f6>)gEtIlHe?pN8zV}5R)p8hQ}@XKv$_3vkA z-dX>1{~~6GPzkfN->WZjU7dIB#8D2Xn+F3}f2sBTcm2Eis$|w2w~mnZ*XcP*hE~r` zrx_gP6xU~TbUb=;^73M30dvyjI7(+5Y>|@4uRK*iy8k-%aC3N{sbn@#zG%5zFR z9+$k9YqCnoezGapk)^KiS*d!+&6R#@ePTWwX{k?8FmH^=h$`YHXs4vQAtS+68y z$(z(E!f-%l#*e!!4Rs$^$NzohmAwDttvkOMfzXlnttg|gy;MYy&Wc`&{X=vR7hT`kKGnwmc1B*!K8V>E`Uu4^Fjh{iWBC^ZK_jf6>JH zVm0RFvo1bTf8F_+Gw-C|s+waLUo`Vf`+2pqL5T-cPHQwQ4PiK|W4T^?_sr8_zOU+M z%;VJmeYkmB-Q8!~a-Zr=oNjNKKUaoTiX_f7ll!!G~2RrPDd6Yh_{)VYstO!VVl>@Tfm7p}0+VM6uAc-@nK zmUn+O`5iC(Dz56DdHtWcoj<-FdLxnkyPZ9S*KuN2>U`txb+>U0yYnh*A|lje#x zRQ0O;U6gd(RrpiuO0haM)mNe+*&fr+>y@6^v{t3eRQa#;nOEi0tiuf8*B&oj*{ zv%39Wa_R-g+z(*bu#3y#y?4pFbGALN@~?OQUSenV;o#4YSH#R;_A_Oa=gdgBIU)4; zmDyK66veNf?Zc=covT`D$a*2F>Xp#3kDGe`tteY(aFvyBk%ejc%XJIloUaIV=HICrLgx6ct=g?)@;vlds)*<%sWr}3O{rU&7)3-FbQUt5*edtu zSmZrbbN-JN2PK7acZ(x?fx71^+jGu8mP*~X_$AuE-nC}Y6tR+G zOXDnO-EUDJmxygF;ca*z(s^~Md!tTAe^>i?p{F-*eHL6Fe=CmZ@=|pT^Vnqz7!uw- zW8BdfWBzHae@u8@xPO)Zj-J1_e-#wnzVLO?Gsc|L9Ls00KQQkIX1)}Bj`>87tdAwX zgGk-+jn6|)+l9*OEns*h7+D|XFx{?!^Eu-VCl8OkUQI`ov&DlMRvud|<#W|!Wv;Zv zWn1BX(X=SOROd>QPu4dUFD~hyogcJ4b$K$U&wRP9cLEqToO;j1a(e%>v<;`{nZJCn z*U#hV#}}J_Ee~RN8F{mgJvQx#)y&H)MH_PUDp;>RjAh7ol>N9V=9SdhwfqXLWFKINNbmoxn#EZhqzU_K0zBBK%-*KTCcDDcinm(N3DZ-$0 z`#Zyz>rXD_Z#><3?PJJ}>^k%O8{HP`=AT%rf9JVqgZ&51xWw=Aq1X4TKKOot&2n!8 zQ-}S81=CaJO!~2zac1_FrC*}rPfw6CaT}tWh1kyU4zSEwoByMs>xp+ zEnTNXtvAkz*}p(g)^x+>&sS!aC%;ww9p)%Je?{_!zLy`POefcgF|jh#2n#&ebZ=I3 z&x&5PK)p3DZdv~q|JM{>UG?aZ6C(rH1E=|B(T7CSJnx-S-p9%Diaj?-_C0qHLye2)*w0U-x7-qXcI(!YSKFUXWj!6dd`4O6 zhlGh2rkS1qY1@!j%dj%^@YkhB7MGr_owD@8WbYa2Vqu>84(rzU8~uFs;9$_xwb>Jx z85S@k_2g@-XR-OFr)qvV6LstD>(e_~Puvf?G@*?KTPMx5l|Ya-9(&Y#Y^JBcgO`*W>GI@v?XHLhtQjvt&5%=I7P*bzfh{ z|NnKCuZ^j}u12sU{42u(eTnP;&RM_z<9)3zS_(OgK}|vphJ;uK2Bg4;#tFE#RpELN ze~X8e;d2;6(%E@0Zd;VCo%><#zb}e2lkdJg}KJ-0L=+uwVS&b^o8qv78U)1Q&{3U2iS^!sg(&j~5kIGE7>2 zI?d(xmqd1X1^d$x%U9_d=51A3$*}6Z@^T@y>lr8NEh-JR9L=!bG-ZX>&o0C5=8jfc z4VJ13@}HM*ImEeu+8POITn-iDPhao<_WD<@|B5>szqbG1OKw6m=E8R z+}`JQx7Fj)*6Dp-TY?`aTs*`wH>OU)UrqVnHx;e}?~lEhW>%@R(2^~TIhNaQhJ~lH zMF7LIg37P0yR%kHXfTL4)EnGq*>mYe{-!pj23Jjn-(UE{f6ra=ajx|?s{p%0TJi!V zpUk~~v;2FhQBW7G*>K9Rf0LKe&OZlTxD@72e7j(Ql?KD}AHms@DZd%+Y>ZpqT;!`B zuj|>zG$S|Owj+D)8i{(@Q-zG0g|iNJT)en(`82k#|6cW+I?-)@>cM&k*}4}|Z`%at zzP-mJ{BQaCqZWaWystJVX36+2%T3t4bMe>XEb6X|Ydqx{UNaq-q{Xm*<=d?p(Xsj8 zBA!?LSy%CYVz_m~g6oQM3#KM-*KA+Q)-iXf{F%=;FKadAxGhSrN|SStJd^$FdY`&h zugfxilYuzpjKaMdF3qa9oQO2rI=mz)U~T`-6L;h&PCuP3sc zzvWge?_TD6LU8hqBX1OC!&jf${>im$k?NW)li99vhD9@OFjLT}D}7LNd3j_+eiZ8j zTeA}5UXcR9Q+CA4{S%fGV?LAAj^IhpVQ)luxXie8k`Aelo zv+UD!bCXWB)>~`5Tq4cD+Q8HhI*g=sZ#w)@Me=`~X?Kyh#8Kci~hC7idPm=TR zEI(SgT%@7?gb0^|fAlW97hY5Bz}fWKXT64+h1ze*-r2C~*XG;^;IwxsO?|dKCZBwj1q*~vuuD@ijBF8FlXyXcdFaLehwy6m% zby`(y_ktlpoAtxj>+%27Qy}9C8y>u8Y>B&2U0QvpEb-Be1xJNiPRpJ(Ax1On$nxb>qFr zyD#5l${?nb=bg`fp8L=4fH~v!GPwiSmm2aj zM2Ismuri!saRC+k44^oNmX)aW*XqR}mCsH?hiiGFeT~l-fJRBdW4sKYN)1}zf``5s z;0p>J;&;^joxA;B)oWg!+1Gsj8gA`~=44=H(0=xBecaw%TeoiAzrVgAaq{eymdpOl zh${Ij>jJ7@!q_iY8TaRZZe8hbm=k6E_4pN~;ORRSG6XPeFq)xv2Q*pTlqhZ--0c(l zsEx^i@qm^l!{zR7=EHg!%fuFf>VOSZwG8sfH;(q$fhvLp3N@nG0ZhZHRiEF{?o)g*)Rp*mj1CO&T2D?I!>%qIb zyXCKa`%_Z$@2=w>Tl?rUk!rr4cA?L%Uw&?UI!Y$zV|XIlbEB;stPBlI4O;^kF3HN& zl*g5OEw_mmIrMhJ@hOIN8&+Ch3kp{nWZtj>|c~n%z zLeHntYUzSNP)tSGvVJ%!9$yo1+xQ{dyw17L@4vl1`|PwWwU7D#{B^Y{WqEhp=u_7E z-?1+5w%t8{^kUv}xl5{gQ~f@B7jG+0e(JCGtjO6-^|8Er=EX&)pL+OyU=LiGRu|-D zHnIHg^@?EqpSyMlahC1x@@P`}`G7gNI{<8HCToD*6YleuZ61G*&E6Nrmgg_&##Yu| z!L{g*^3y|$=k^xo@oSbJdpYIh%DFdwmY-jhTiqAdzP9Sco|=wR>MN;{=N zja==+TeGj9ZT|i2>}+dm>)jG&J7>;He$~Iy_4>N_=ir>_)!Fd6m7{|B@G{do_Mnv| zpnQR6CTE8A_4WHdUyIKF=ym((S&_w>K3Sldqy*DD|F5nN-@a|zx9{KiH*n9;bO`QQ zX0U#LGY2R?>ew#3ne}H{1`XD5X(` z!GZBWmIlM++TQ2$rp`PBntkD72wTSgAUVg)O&(fEFo8$mK^|n-@PzBZY5BPRwR898 zeA{pH`QMaA&>Rp~K<<;1EUzUFtJwVc`1Q==IY#BepB8Dn|M*&de@SG9()`S2J-c_6 zzrW{xZr*7$$T zvJRD*n##*x_3SQMaqF-C+f3J!_r3B;Jo|TUN^?leVhyOce=18phpAI`U-33U7x$CJ z9r1VK>kcTWKGKOh^RD3arNu{XRWKc&Z&kXRBjBz*7Xw3BD5Hoo!!3{fU!0F=UfX;5 z*jW+3rQJ*gwYPrlX%tUCt9fke;x6|6`E2w2dku=k4Eq;KByFFiY^QQrX};2=kY!7x z1YB=TdYx%JHIyN~=HpTJbMr*k75-diGYf7WF@`o$dEYJpD0u zFH?z(uYfGWWq!{m#-c}*-5IYiOx9>P>CX7=+qZk=->y^~3IF~6clDoGvlIVT7ys_Q zX=iV1YhOFdN~^r0=2AksV6~>PsAc{6oRMI^h{MtRr`7_&Zi~`Rg?q1) zxpHY<2xG>}nLdmi+dpXEkN6RA`}Myoe`9ylytX?%H;h5U-POM1@axT02UEOi)Mbz9 z?AH5%X{{7>k5=u6RvHkkh&39S_>Zdy;ib3OuTeZ`fq$w#t$>+apZ z^~{uwTRWLR#nBoD(Cjk90)_?sF*}Q%URxVId-iOL_uaEK-GXN<^H>=Us_Rpq-`e{6 zSn^%y3fJ8YGnq_|W^jGJ_4V}?ZBQ|#)d49wcW-$3j}bJ{4yrf76XK8wLIwgwDN>UR zy2g-beV`!;P<_b2z%b33vF7*N?duJA4jbfXp0&{Y^J|YtgJ!&`4Fki0rO9(d>SRId zR3VE5q2nD5kYNze05@bB6vP5mIS!00TnW!Vy!f%=;nV+rzPwWZfBf{~{Qu9@ulipF z?Udq5;1zW^b@ulB2}}^>;5DDu0vTEQ;(3H+-ia`FB{pT9Pgu=aU-2XNGiVbFSHjh2 zj52wved|{W9r^Zc!3^_&V*z;q*^CSftQ+iV8R{giGbU8CN+^SZ!$Duf;lk~H(6R!N z1GlspmYxS?EC!8+uOSTAxA9$_+0X-$<7&ufVgl6#pdkZDT!KOa5`+!*Oxz})V6`@)&pinq5+Pca@|wwYUt;j(<)|9^k|t1{IdtNqqs;BjV5i0~I}cq#OLIg^2; zJ7a*fEVca|RtkZ5CCA<|I#KZs=kgV+*=du!k7KjZwm zz51V6+t(Xse%Jjk&rDPPanfc+4^zSRbN=;}-($b7FMs@-`>?@k2Bz=%t`4i2c7Uqd z&D);a_aC>n_y1q5;3gWRtF|Mhgm80Rs4csH|!!GSSh z#xjOw^EfT4SwB4Z{rU6!dOQEhFLoLY`(682K6)88vvS?fPYvl(*OhFhV-a1(R{P}&^kpEfx?d@fc?_XiPe2YD3 zCyij*zmVpcJ?DcM|McJ5w@xn7zV@$uOKq&p!gtqZADwpdVvE3RiEUxumfQb*S(%cy zoHs$vCx8FnZGS(%yI;5R-Q*X`Hk1eKnRp}eZid9RYujqL78L$%WHG3pHt*w~-S6jY z4lj?pk#~RJ-~RePkN0~SOFui$s@)L(@7vbQj*jQ&V{hwie09L?QAI%F->nXeCPD|a z7+0_8Ee&8e)!UY+(J+T;L;Lw-kew*C9}aH5{PD+^$i3S?{P?|c?q);d_dnh*o!J{A zG5O<8&4%4qC$Fw#66Ig^Av47G$&tl;hpW~zth)W^^|N&a=6!EuPiQmTvAbr?YVdUz zgK;>+rMKdBcdII%-=9A>>|EU4p9ghZ9gh7yAI})lzqo4i1m=ay_2*^U|7~G75Ww&+ zH}UrGcWFi6Cv9K-?c2L=m-0+_qT_!*umAU4yZ5hJHg_O{>*jmggP3C4m@>BR)Mj|! zsPbF=C=WxFjs%xN$gy{PS$WdSr|zBj?^)ZglW(tpw1*q_{coyeQ2TJ^nr2njpC7Ah zzkmOyeVO~imR}2RX_Q}WyfT+Nc3O@cR{~QqpF$fGhbTi^qOev&_Zj9H3z;}r8zwL; z-L0?wcW>2GrGsW=JFC8GJ#9$5eDkPi!_SrT<%5kR=PzZdUZW;;3Kon-?iBSc|zHY`Af&Glh|X;Y$c(PR^YhH*Wk`lfEtRM(=dR|U!U+wX?GIM&`)h|t-t;Z<5;Foy-Lv-q%sN)O_3||5n zCG<1yJiK=8+P{DQ9P`hlTua$0#PsE&EUqn1nY*xnuU?7?=R1rd2-XqAIJ8HHi$63efR(Efy(1t z3tpUDU(NAq!lCKAlchBuxN$Yrv0Cywh{`Z9Y2RPoxh|Zm|@fB_%A=FGqR~g)fR!A9L6|9?_-@7!{m>wnhl=!nLN%iYt)wA z+$VqI*}l8)ecy}s{#I+4Y4TtTD<}?F1HLfU-0_Z%kw1_kvM#D#e8IPysSO2T{}m)& zZudI$T1BFL7bB=<*Jyb9Q_kV1Q^FTp2Fu6#IcK}g|E~MV%s6ke{ywpQ^Ku1ZG8~{5 zfye<>O;CsGr*=d2_jk1>@xT8ZoVTqo9@%_&ZgXXsx(iSqjySMlE!+HCgz`8Mk;cierma+_J1ylvf|jPk{|By-MO_c;~_au(B! z)l463e;u3K&i_8AW&a`uaI*!}ENIxN)v$N(-tW(|w||$nzw=k;#^;p(WgEZVe0TWx z*Y#!*GIe@zcf^P`%w_-Zl|gKJ>Dc*Ys?@4bb~f$D4q28a0~2i8V!H#0Z?{p_FbG+(e=FGRC$NW6Ap zXXWQ-=gytW11G+lDSs}PhA>#WFD}eo{CI8B`GkyZ?ac~LFxO9Q?OD6=p@Lt7l!Ke< ze-ml-cCQA5c^5DC&ARU_xq`FO;>%%vzeQ7S7jI2t7xP@+T^G9EfI*|-q)5ZTii34g z$NsKg!*s(=&eMEbZH>u_`BRUX{MRa*mF%v5c;c(&>pAD&`t?MVvFpnUzI}_CKKw0F zNt*QUz})SZ^uEQE&T#r`QQ4v#sl|HX&TKIjg7bA<`-n;S^CxglvN_-@A`k79|m*~lW%8d_YuODx! z3X6)*o_*9&y?$rx7nYFT$B;~BypZX_-uEF~3M=!4R<1Hu>UUyXGmB}$^!0D+8pq3Uaf{zqX7#{%V%+`C3K?MhE#{kev8j zF!%ZX7oWGE)u}CV*j~wCEXDd^iRX5^#LLVNPfpjn#4^p7(Im9|&Dk3~PRBy6)_nuH z#linM;}rkBpDL|3@Vl&^_+<9`sodeW?xwco3rz9+^mn_tbAjGxhE1~kJnHLj*)TkP zwfZU#XfRa7!C%zj3TQpij>exA7fJ+rzG$Dn?5TEsbuGiw?CP_TN3z?6_i#_B4drLu zFz-E6ho#KH(~U{}m)V_I#6#x>GB_}9(P-%Hm6n#4uB{d=SiC_xdpX0sZ@;}o=jX~z zOw6{cslLa{(jvR|an(16f4#Y1w^o03W^H8RSmb-uxR~|AN7j;v58oLUt(<#NqoMM! z>YoYDD+^D@syBW}Ra02Nkn}wtqtvVs7Fb}urAL+Vi!Wo2M0`fr$=_Sj(>CQ8?Q3M3 zk-0dR@$yUY8mkEHCjlZ1$fe$#QbvYra)y6eQdmS9)-(7_udo+wIB5YYy{hiAe<;-N z1+9Pt%_4!?$Dj-a%4rF2MGx$){%#l5Q~U3?y8k|{pMRgr$L@pY$@JYjzn`%BH@mue z7t4=72PfOVxeFS7VK@^HX+g2xc-E}m|1EC|iF&zBcopC@Niw`F%=-aWgDh@4K_ z&*qa0K`Iw8h^aBZvsvTfu=C@Mq79&~8bd@pYd{IBjn<#qg$%RaHSjNrV+1KZ5F>g3 zv=*Iv!|mO>=Z8igjc9oJ*?jjm`EY5y3;!Os`)=4d8xkM^48_wKes4Qm|G#YS`^|UT z|DC)2yN*HRz>|*BfLEy(PJR8-rFwPmglJcb{Iy?_o|@?2aL`#6=N7&Gw4E6D)^h)2 zDhJ}HVcd7a$85lm@+wILX;=2)<;+elDAea(&n3Ebd&Hz0 z*Uo1OMPB)^;@0WgE_all#@?B7?BRvqo|?PP+n-g;wPH8lJnWrSFqq<$C)M6UPOzpat zTneSlK1&(8q=U~+@Acj5-`sSmd)?oS2I(uW#Jp%p7GpY^k}K9_V-*;9f7b078w2a< z2V5FwA1dD(6?f!Ha+a*ff%*TwSTL{}OrJKnY_dpbR>Y5Q4gvE|tlAcO{w-1sP2g~4rBPIyHdOPm^EM9 z#;^~6GXhH1_P4r1@vZf1*DQ#KA|IJKBjZzbRF z>xXQVwr*P-&fAl}dUwGozt)0?ePDaA0JpJto^gdc#R%!W&D(hSN`3WxBa+VV9}!273QobvvnV8SSL!DhZ$M@dR-th zrA&o=Zu6FvL6byYbN;n*yDRrFV6nA|VzAIx^<6veT@`87KOZ+`;q$M|7eV8#XO?Wg zP`dc4;$N+3dF|c2uV)`zzqM$F@xw#AEzX4)r0%a3*pimg71*Gl-+bgShu&7cYAy$> zwO2%^E4yFf-1$@K>bV3V&s%e+i!SckFSEY%oW&mQD<@SQ|9)vn6Ab;dP(I~aPPgrC zzlkh|)BkOldu!6WI`fkgcihO%Qk6+lFBOgYmA@ul#F@d@(l z^}n%$v9EU#DID?ROW|*<*s_ z9n_RpSs?9rAEdQEy?fO~)_YS~rP0D$i@*N; zmABYu>iZ3@`<6T}xb1Yg-Sv8v`O2me zWn1>#_4ZY1&4>6)uRhgm=uKKWZ?<`PSy@?ivf5^l+va~umvdPB)Vu%PEU%4^d8Cf? z-U*XmKi!ajfv$4ltz|N-Gcrv0#7y}WX55;#>ydac!#j=CQxAJY8k9;_O>A9p+Bck` z>-+`LhF-be~V?f=@PJf+bKSumk;)?yT0MN?W?5R**_PlFD~8?P>``+afRf}l}rh04}`8J zM!O!~8IsGT@McnJvhB;bnExf8Uoc;Am$|aM{=y&8#SD+OveW7lBsGZ%#Ytxs1Q0Haw-*$$3X7l40TNf8FxtN?Vx~Sn`9O@)icjr`p zx2v3V&Y2L#168&B4rK;fcDF+^QWXp;Br>CR%n1(W7w+3S{cH4OLr;T`whR|lvQB!i zvkEMUx%+s#!3>@qJf%A-r??ldj1q0=@qPK^dV0~#$h3EVZ`{;ku$NS9-)Mv@R_$3aIe(k*;t3x$-^hKpa{gzvD)|4R zBN`XCU7fG7+413SZuR+#eCKpkfvP2js{U`=ZZoCH>Ad8*?-}PX-~Hl2)oalr3|tA3 zTHB2p6J8}Sa4&s%GwPL#+J4R(s^xnwZMp^?qcZqd<9tK|y7>b#rsa??a^Tpp-rnBc zeS5if1m55URS;i7u=Z0x&Ds~snQj>DyRc@`_e{u$4l`)n=x+$aGRYd)m`e6GD+ACV zl3D=6GVeX}xela&&t}>Cj`_!q>29Dc(;(M?OaplbRLgGo#`WOd-fH=?H|**^JmIf4 z53bkihSjYbws0lHF)@Mc*&D`C{{G(If@5Jn-dLLl)yElZn>q93k0>pMjjufSzKGnZ z7r(_NVyD~I?IC4bCPi#Xs`|Kk`>FZ+AMLPR6_u-M_da1pgyWwJ@m3es&b&Km)s=Y` zo=T72RxCg3vFGyb;AN{$CTz~w>$}|7_{=Uo_baFGtq%WI)Tz}I{czvbMXyw@vz4sA z^1h%s zBYHK%narhL8GTc`H(l@au~FN!a+V9@6~?aimBMa8eLGCHyXF~3h0Z!M^v zTIeqt{_T>e!zwesr>v7hPaj)$Z@Hu6)2_TjKD=$azPK~4SppgiIcLT%XMgK%$A1%P ze>wRavEO;}Hgz=xyKk-dcH}s?Nx{1D>=~b9*L@h@$n*yFe!95f!y@ZC>jy6PCPyD_ zPF()Wd`ISAwG$~^4>A4e$MZicTrUtOB8_GenestI5Jz39B(dO>8a#HtlWFP5rXT!-w& zJuGNAaqHrY5GT#&7VrOkZJHX+AibNv^}ODks+)JhMICAnC_jGR?VwlS<-dSo*<0P7 zU2Fb653F7D#%zte@IPfwzT#yp?iUuX+qU7gdz?t6fx*IMSz(JA4hF}aooi+6kT&Po z**~v0EN4jhslI-Vz}!W*xEZ6~ifm2{34N7$&FWu~$Q{cQAM^sWeSWz~%n=DxJ^rlu z%&gq~++OzD#<{-}ppo|82WF zS-vell%eQen8_LYYieA3?oM0vGM&lI-(me7wRg-KT*VbeX+j5TUT;{=_D6Bym#Mu< zYqIybLq8^Vv4(6_AeWT%^Da*zC@y00* zkpm&08D{mlSQ@;4U4Fhs{GDmZvLJ@iTT_xRPv*H5WcpO2;hy1ydCzBrGOV+oR>{yk zlU=|kH+$!%U@eC7DOUM;YFrM2R##6rUC~~q&5&Q`@brBtYeKSz_}p3ZEVUYTTxVe| z$mBY(X7cYi{j(`GZ||{w$cuU(%kYyg?#0_fm6hK#@0hjLF|j6WtuH;6yprcjnP+>* zSuaK(YvBN!pxq{MiLb13w3}z2xc2wdslbMHdoRBORa_q5tKC2UYx<~v(O5rk!m{)6 zS$|ioRtPUCtXd|)dZC@os%P5*hHGAoe_s0chXycoSI^Y?CD)MC-M;qckEIWn#lE{c z^XQ!wRo@yuU8~#8)G?3gqD0NVy=pU8{b2ojP37s|mZ=t5Pj)eJ*o6qxZf8gfZ8}At^5ka%&tzGJu@@aNMY?1qZ5iW(*43Mezo95s1H|2mv zY+k&qab{6kz+m?~=kS_|#h;&@ojZ5#-Fq`mt^o~fEeBN+FP1YINa)}2KfR+KR5`8L z51W5MAN>Qb?m@0vR&+BkY>47YNPc|m*fF>JajbVV-mrl?daD?E#7*86WM^mB*Z*H& zo@SK2DTWi=Ir^ZWnN<;L_ z+OqwVyULzvybPQi_(o*4%+g7#j=Y)b5IAFv@}13g4gJ-buWzsi=#=U0`Sk5$;M*|w z#er|`{h7T#qU{f8C{r(>;!fE97fcGHC3a^T9(!qv;Cq|VrN)G8wb z9OWCDxDuAfxW#<$K75Grmu}mmi4W)TMITMhS^mqspz+_QC&C&G|2Iy(e{&tfn#biq z3ofs`x@IB6wC!K#@7S@=YlYU5;?j-weR}h4PyM;_?upX=ci*jc?0T|jZu!Y6FFjSA z?`Rg)hrC^%>UDrcPHyQFQ&0?_Uc)eD`NA(Lho)Zhp9~r#{Wj}*YQtjT{k{c>tPg&D zRu5sg`Z&kL>-&yX%fmLeF-6?sV_3`gJK3Riv6Ra0`=_tHjc>oWqoMxFNdx;+55o6c znEETPLSy#J=Es4?t5Vz5XEEP>ajf7$w(N9ANjFb_Ey>B63|m>WG&lD$y_gP}kC}J( zPW6|olhsxGzvYQlgWD}vuYLLU^Zjd!`G5X>cInVOpLEIkYNOiY?BxubY99yc@A^>i zF5>2wmF-s-t54k8^Pt0>@zKOv7Fwlg4L08Qw6m9A+q_Jx;YI+%>A-ed)(1PSN}IaP zHadqaNs?KWYN2p%e!<>NbzOR2iX`^&<+tx;+WW}gOC!7b;lIx>UoK)e;t;Lmw3H>t zN%Gec2Cn>HSDVk@onJlwyc46yMYF#BeV?1S64(}{$cj4LQ*Gb-BGLZm)ekGPZkznv zR+MHnug1bGv!lH19kWJ|oz2N@w+{uYZ*r4A;PsX9$35+bOq;nBN~Z`lzcVepuD#fo z$LZ(P`ZZr~o7aA-`nLB=Nf1L`S&GS@=^BjUx?Bs=q07R`9-mvhUM{CjBJyG0`#V1h zs&3aL>=M4EG~RGvpdx^UL3`jw!py{>)$b(=tha6Rri@&t0C(wV7){ z9!FYR*VV(I#1d8_*KmL0l~{leg0$0YT!{ii_&p-|Xg}Z&UZ@$%8V1du~%Ly$f?5l{{Se z`iF1ak#on{XNTtW%bP#{|A2Y&$I?G?2flsGkg4Z)Fl#&Hw!!Mj%{{-~%Nd?sY*v?A zAHs|1ldrpcg;buI?msbUkPafH_`@w0kQ&)Nqr%81eO|fl_ zm;AG0k=4yTDf!VKE{e=t!<4}%UtL`ExW8aWr9o8Hp_B}+18$S#f;hcFD=iJ;E?asW zy(`AZr62eBPS#fSPxm)YH57Rsu*hq^tLKbm41W@~^J|$d$Z9nWV_?YkZr}bR>-e+m z-8*+|v2^7w@Z?&Mla(#xP`+_rhQaZ&00!3`?z(=qe1I%y-!a)*c5u;b?DWnN~@k$y?Pk*)T|-)#GUAL zowzl3`4y&n_{%&M^Ua@T&wqZNmD!n>3->cci7f2h7A38#CpPnbh-a0m*xQSjbtV}G zzP!os@tn(_s>HIM&$ooGKjfHv`Pr@9ofo`p_utx@w4_77%1G7QFPJZ|Y*yA{5$|W} z`*R+9Wqj92e3kG|t95Pll_N*oRrS4YFP+ozbjLdl29bsZF*0{;&u;JU&&oG665FZw zKQf_Db}oZ0do_uxTJ0|{e|YD0fsUYytT3O$iW_;YWr3^@f{c2r zW~6%Ex?6v!ySm&ZB__X~dJ#`Rkc( z+}N>km(bk=d zLG@mEVw3x4Cy@rDV%@N|G=IyKCr`KzSZ?$5I&b^Q%3^chz6)aiinJO+PV(>Z%8+qb zE3{?ajZaPgN>}u7AK9cM#S&QdOV`hSk9Vg9ON*jn}l5eAQeBK6AZd znf~eFy!{c)4%g&@mMT(hGbS@#*v%U=cfHmmqv`|I4^q~jPFnX{Nu(i@?f(Ay|C8fpo%~U?mixl3 zqFlN4y&@lCwyv#tv@%O|vz?{F+oVu=G1K+a7xO#VXg<5eeqrN#+ZpT^b~^9&mT#~- zv5BjeVW08o-Anzr4%i3Qy05U_dx`t`f}Qr;uRdJzMDl8-`okJG^YxomxBckji=MV= zfz|HHr|L@&zN*~elCx2K&TJ+Qy;Bi$qeT4sPEOfe6#K0DuJ~%$6vmHPYk96%RmJXN z0q^hoEJWWUV5)M7ae?4)jw@9pQo>141dby)@O_^!jGmn8-4ziX2}xbHXVss6ply=D(J8l zbn&u&?74fTGryN^zu99BS{cx%AH4K_lKEA`oRs71IZc@v@6EktlNFr5t2~?`$iHI! zhTrQ~y}mERvFpc{?Z=h}F??hf`ZB2}c+tK+>*_=lKhJI8+_!APi${K%7^|lC*@~NtnZLZ<6@oQ(_@7m{WW`_1$$@(7|~P zC*v}!tuIb5w$zNg_D^)x@msOqyP@;o)$n=nKZ{jOCKrkv@VOV*r!FvI&sPt*m_y5} z8(!}d<9fhfZNB>Kef!E!zt8K-@pCaSd|)|HI)5S4j_U94+Ba`MRD6G@V1B&HJW1$; zPuNt^0EXH8^K5Rdp8KPBulv^v2b#}*dT-r7Yhu$`iv|g=iVv2c`X^x;*8w@Z;M+D8 zf1VT`J-F<~&y4cLclOkNxR7(#PGEl)^-v2)yzDqy2?WRW5pTZaC%jBp1e#~G5_gDbK z=U|4`=Jo%zw$1YU_xJYu*_8}m=d*8*4G>(=aUypyXyQI?8N->FMx^@u%%y){mLE3+ zRj>`JK@87K8_TOR)gFWRNR@rT>uYPzo;|y7XFX`m8K_qN62_P_!?Y;x-X74gK)0oh zXPQQuN&YXf6m8hPsBGtB)BJyjV&K|F5)z_L#$h7=0K% zgMxtdf;($~?>~9je9Q0WcQY_B7>KhL{QYH}zxV4kY4D=DkEtOH;mz+EEA+sN3pWQc z9OI7LTUCnOmCiA$`#ZOM+P~QiM|U_ZU}j)o&|Age6MO@yz%QI!yN`>9fuS~pVVV7( ze}8|^|8mLanC~}m(oQWx?{WX!DoN7?P}Cv&B6t(ve%EPr0)E_w2E zRs55^ru}sZ%=Mt9Bi-j)Aikkif-lX&NJ)h z=>*U2UzK!x>Z2DG+BU8~S6g`XFNwQm+2Im5XMupr$t_D_y4`O|#xGv>=d9;zm8&nW zuX0)LZ{=a-8y0IXo-9ylKDl^F{<$~P=jm9i z{IT^z%{>3yIRS+yGE!utMLfNgg1Hv(1&B;6t@8@m`n)V1e43?U%ReK@&fCQnYl>u- zZsxcq;!(RuPgDG($k7=cG53S#pL??CT=K-aV?eiz(m&}4Y*w`gC+#f02i7W1M+ z>zB2y`KRB!U%*h5wA4;z;wQb%H!sd?Suv%hb8%l%yKSY)!uT`1r?yyEFIQ9xVVJ5f z-@C5=(6WS>e*z9)OvH1yZgbyIy)3^DyefMA3xR8Ninl~e2 zO*eD~Q|)*5J@yN+j3?@171fgb*MGA-{dewb-V#p2&{ zl~0yjQCE{s34ZtJqn}Bkyu-!+_GfsUOY}^BF))M$Gsf&LyIXN^wt4=$H*em2JLZ$- zJI(jl`q=&FY#KrquPxnEKkqZcw$$SdUlzy;-Q4**wtH1B$NjT=UeBAy$E9$wb+U!a zR2N~bhN>S5Q}1_jfdY6E*8%~?>)e7L+|KK~{}=u>wjt@${_IPv`fF3=4?dh?vUPjC z!Iyis-f!Rk(`$I{Rq7wMKlpmZ{ckR1#c3y3yt@9`=snX8y^kd-|GXtLSq&_%-D{iS z02;-;Aiw#AMYdvah6Y2!)ewda`|dMKl-H)})hX}EoU|;C>-?Md%NYK=XH>cWcXhGI z8QwE0nA3vI^83Q1}?w0(Lqm z5_Lp3F`m84#L&Rhuur4G&-igr{Nm`?F!S>1Gd_J?Cj?%e4a)EEHIJahD9{b~usR52 z4n!ElV!*nX8*C5*%b(x-|Nmaim(~;*1{OK+E8vd1Y|m|8P@f&txdeA88zv>4EUQ2H z)4Bel`No*qGkw;(B8vV+ZAiIO5WpH-9=H3|dXxD!?;p5$dm8!im*;G)m>W~N&!?ua zZ1d%RT7FCQC(hwf{(LFSrBG_q#4D@Kwofaba!zB_r=sVRW#u)5YYw`U?at~BVUW!V z-)VoZ*_u&=Va+BcjlYf2*RR%ZYCm85we!8)qua;bng6eNbW`egtbH5kH1R)A*!7e? z{z?7(A=F=F`G%YFs_zRl7IR&WoZ|ELSkn1bt$`prm3V)8+?jVcahu2AlD;XMzP5H3 z9ed^Qa^BzKSdEFY>uxEDI!wQH^hdf7WV? zn|@#OmD*nD=$(Dlx#)TIi=(e6M5pdaN`G!4oVaDr7Lkeb+ccF=YBxN*pdTHqa9Fr< zLD?~*XN`rQx4mG?Z7=apnJyGJgXu-YZcxNEd<|x3wdeR<^mkg}uZhc7u&F1 zdNWSwh35uxEl7R~I>%wb!>6aG$KKm#crbwB^g4z|W-D?ZmIg6oF4s;Mby>V>UG%#8yGMz8U!?1b;><8Vyt5Fwbycd@{Q>jzLxHX0OcG zlm3_3C-`()$=xq0>}NhJc%H@Q=*pIhpC{=rGT@a}&XkO}sPFRfxs;|rUyRH21NqCY z8>?<^_nC0QbDdNzWQ}LnIpz~xosK3SEJ)i9ACsWr4KE20!qN1sQC&I4#aXF)n`O1}DS9}gU&X~3R*7xH#t zpp)+mgjqj4!%)f&^#Fb z|3mW2e%}orZ+1VsE}j-IxI@Bj#Tq#mjk(|Xzs4zQb{&4*pugwG*}nWQ#)}y4<>mfZ zmHaJx{)wq4esC=*c60oI>xh1N&zcvrOl_P^|RMIE-VgC_ko z8dxlN0?lj}sKX%`Z7OrC0bFM8z?SVzLn+Uie^g~SnQmn4wX#wrVi34p)0vDa2 z^$4JH6um@6X?JQch#W`_TKDgrn8*I8wGr>5lYUm3Hr$NY^?A-JpuL{?%pBS9ZujHS zSu+lLhVH#;HQz<%>K*Ziw{Cu`3(ONP-tlX42Ye7x8rxD`$b6v}OjAM)sa+E)mn)SAYMBRjJpVTU)yzgu%DrK_s(*GZ(wE z%Cm1DFFH)+D9!b`{&UBn-HZ9!Ij_I)6PI6im%DDuXN_JB+d?C+gC;hTw~91Q1^BLd z{%w*jqd((~J1bcyo%)e;ddY6489S0xvYEITST`hb9k~1LRqc&fMi&1GKLU+9RoG{2 z_{ao&jjOVdNsZ~KI3%0M?exG0YUHMuT zp9c>we)RaK!o7Ak(~QEIC3O#cVhnd(VF9gIQ59*p_Et^goeI|h+YaGc2JO1r2ZYKQ zGVXfUP1TmUsu2JDzg5q!`oD|)+I|MIJq!>Hf3^GJ!klINeeP#HX1;CB<11M#eYkOb zX$)JcgsSbz6rW`bSAPa}^67WPGXd-BAzJ#sGb&yzRbxa+h@ z;n5c%!k}@1&;W+$r^2fDEUj5D6VvgrADZ9kZ~oi(8rG18qFk{oImf-GM)qMjn+T5 z9WxKFT=VGTp8R)W=lt9|+H{?c&k1I*Z`0=yRZ^I09m;rv`+8O5t`{n|8y{Lpb8#kI zz7rK7tIfv6aP4JmL(-o!Umt`Tw=Ay_clff+P*_0h_EgdR+zIZCi!{?-TIpwHg6BYZ z{qk4mDSY!u>X*ws{r8di4*#~rCG#ui%zI)}@5`vN{LK+n0p24j#m{@0T5hS@c*(M! zm^Nw8wSSU-BYo?(Tn_E=u>>_twEx>S6s~G4(*14A@O7im*5nyH9G`0xFZ`Bscr5xy zGflU2-@JgZvch)vo54Tg4)$lQ;g#-B<+hu(=K8bShfZcU`h0)qV(EQuw)S)N$E)np zcYdjx=YWUf7!c!YW>6WUZ`n}ax(WB0_{;vI|{MhqvZ9}hye|uW_(LpOLJoLI{?W%cJ%l)qY z+wo>}OAUz2mz7;_^K!bvOLn^W#rt z_kA`7hJ=86`Lf?$U#jk&yT%Z$Upt4pTIS!qH!|hbw$<~i)Q`_yd+md`z%8Hp^Nb7( z&#vFkEU^}U{{Eb2{*t|i?lUlKkooscHeK}Hxx(`+J~iDsZ~fHO_5F^^n^rx3{N0>^ z;egYR+p8vu|I>ReQC{YEC)LJOYgx`rtDOw&#C*f=jL4q zvfZ^m`uN0WAEfHlZ{>tuf3Wwh>Pm_J{o1qMEk6C^OtyamEa{LSoAIfWg|MaxKR44cLQs~|KvpE}H^u3b` zd|!Xh+VYN$_Kt7D56k#JFPR^^vvr!zwbwhp?_a&nyX|v%ZqX$7(`)iRe^UR)#?bKc zYrOHkjXicf`<2fJn^xB8TwAL5?N7wZyAR|lKWXeVD=w(NuBu*CJ#YFk28IJm{>tw8 zf2ZjauvIIvb!eyZ)9cw;fFLRtyllCZ&KiBQbiA$%AIuTi zKytcXY}NO><@Xgi%$J1hDSvs%NL;$8K}LanRWU<-{DwXH@%!#%ZN2sOo1CMF;!{Vj z)+xQ-)9=NfOLFF$!2HCal<&cNZnt%7pFH1L`uf^)mWORqxHP4MoThENF@gCBgJr-( z<{!VCCO(^Z_wL>E98TO|xt$O>fzynCYCry)CMM+Kx>s}ST-k50 z%Ava|TkZ*ir30T%G2esyKfVRex{j=`v#|gFF#Kw%EH~e3YJSm@jw!Q>E!N=ForJ*f#kc+hli-M$^GgkC&Pzyua~d+e;D0=N{f(BL9xv7ye!zH0R!)!0szs{?z{e_g7i_$@!DN zcKbLL9dYg7eDve@n5E@b?v7RKOd~)3I6M1z_p|q0u9ZyEM-K{r+MctdzR2R%$|>wcM=r}UlqK5fb-LF?j~ zNybqrOJ9D>ygy~-mN%lJ+e-2*(vu_~Jw5!R_<&`N%H5-mX_scy&Cw~Vnsv^qc24~? z{j6y|=_>Wp+_N@1=4UG(Sz&45P!+$=W~*@8|2Jnpr~G-E%;er!#;5zdb$|W@V`1O? z&oUAh?stlu=BkV=y=V1q>eMf~-lghy=Y^JUf0}-M&s(pxdkgm)-8Juhn0E5Yg_mM| zyRR`_`}Ft!kNf`@=Gkwue_1x^?6y-OPjmUhjOu?KPne%vJxTZRwm6fI+vDc_S$x9o z+qXs8zRPak)+11n~IY-XLEW6Pov@FNQ>MU1i#Iz}wOjq)7eop*jd7*4w z_U(sfwoLoF!e^!V!>4X#6GV@{SbSNDfA8Af3A&4)9a!-4>!h6Z(G%4ld%rj7W7;Zl zye|H0$BdM!+0PFse0@KoA^Y}$&CA|o)wj<#%Us=`YdL4djh{E>{@7rpzyiohYWA7;O1mNLlLj&(F^dEBz1Nk9+9Vb+TvbQqFn1y??KIDRtuh$&jj*Z`T@e zTN-3kZLMmW|EJMc4`(+e{@uHIbFpdnx9-oM z#ow+DpKHH&=Dj4NyY{x9o}KtIaf*NWxzMD4PN&@7oJs9E`(fhLd5_lbIWuF?*5GfaH)nkK-DYY0@Qc~`#>RK`;RikCW07~axbBvgU-5U( zwfon;t-V&1TYu&6_eqf#>(;&VO#NMX!}(>zDu6=)Nm%KRfo%&!g|$Pu0wP`}d{Z zr_Zmi+ov1%$E}uDex?CUL*OEH!xYO6Q{KmG|6Y9d*zahyI2P9@>-!57)Ahi`_J{8= zMHzCM(%*|88o$h6{i}Dc_=huF_wN1sP^d*^vWx=z3C36Vjeq^SqN>?+M56!p{y(Sp z?JX`T8<5mS`R%Y;39SXj2&$=I zVh8Rsfa*1v*n@lq1_p!}xYoicHbbz!-0zpr-sifXWEmI|7X8bU{r*d>>iFz%y?nd# z>5*!7Z=$$Cx*NJbe-C^2?#_;v^Y8Y3EdT$+Ab!*3w~zA~7#bo!lrM{RKN)@e__qB= zpM9J3^w83Cu`8qhom>5N=jpjmKj$(rFdPv0cW(BP!>@|oy^q^|+k4gHmy`C!o&Q+A zGi=?rEz9D5S>JaGt3Cf@uJ3cxIuTF>u30ZHKYz(RQO5MkS-&fnJuj(y`2O*_$W5UV zw|Cx+`@_k=!0`Cn_q0dP^1iD?9?Q-#*L@Wxyvx`){?morEdARTekL+7Fu3jfA6pjm z`CYv_)48|WySDyWd-rzPtNZO?s@2S7jK2NCJWCCg# zOB}=-3E(C)C>U`^47l}yh%8V`8`2^Hi~YN1zhhq=D8}_;|thr?;Ie4o5i>t9X$JrEd zBH(H5&rhj8SKQ5eubbg?1zu(^1x%vHLBe_HO4@cJgyb~YzD__2Zk3aAHp~4mKPrhwF zT=+iTc2bDT^)^|0!_ek~9q7|G>g*^{?OW?(Uv%((_mT zoUZfU%0DM%T2+ca{nJa0)IGQI>i&=0WqGzZ-b-u6N$1--`_;xjQR!!!%Gde$_r|ERH2h2Y8aJ|i}*mmBqu-D!> zlZ$TW%+y)DhUeD)`Y*BHriRI>8PAcOW^eUV{%BoYc;4~ojala3-p|f8^Yk-`{&aWU z57w(Z`4N6;NA5qjf75>X$L;Umzo-A*yu8ouZB~h8yxOVL3opF*=6DgtIRJ+-jZ#wPTn)0(~bN9tMz4r3D1a)e?LL;d`^2}asn1sb%hjJbZ?Uvy4bwll9c#=q zHu|2*y_`DfZbiZVDTSZX)$bbKyqdJkNBwowIlVHwy(Wggch=j_y;mPl6S_~Z)cn(F zsmZcO^Hnm}@8SyIOQ=lb6_y*$4B@8#n+ z=S*Lo#Q0M=R-xSGWBRrlBm23NeN=_h95*-o{r*|M|ttj=sEJgI#{= z|8Kb$m#LYpzAg35EZgiy>81;pU!Pmn#m!fpl=t^NzDG=Tc`PzwRxZKzj?KGU;Dvb*GfC*rR**%D*2zi+UsF> z;CgyH!r+*A@i)xNW|4=gdw26|R3zT>fsCk66e1wx5^( z?Rt^Abe8VVxS5-lPrKyNX0D^|%T*uSDBrxlcVW=QWyMCu%e~B}`7Jj(x%|?!iaC19 zuO;W6zHc;9|5?1!nfd!eqmTcQty{INI(*Hg?T_Dhx^CXHKWRrno#}@sIz`Xx`d;0C zS{Na7_^0dM@&$YW?j}qZ&TYP`&iD87BbRA8H&5KKem%2g346`LIg6?iubtIa74_Vf zt$wb&@~Tws#-h!kxAP0Q_xN~3E?@Jpe1_${nYBuqT_H0z-FN+4x<;49IQC%6{^@ty z?rd1P#IxG1v@H&sEzjH+P=hBugXZ z-{EOXO24?LC0cj=Oy>1`Ch~Xg%YsY)*6r=IYuImG99{Zr=hyPU{U`fE-!8fHW=_Pl z)qMPXa~5x$xiH&~_xll<=g&kw$5#6Byg&Stx4c=!a$9SG;ZmjOw>#6yw;o>4{da9> zz?uF}<@M&BBCgxxf1UhYx<~iN?fyHqq2F{@r1!si-z8+tS^s>So>bHt+0*aLt;_pT zI@Pv^oU+M$l>a`gB(~^Nj^Wl z6N~Z}?^f3~ohmbX%@ADWv689V=GvsUoBy7%ADMN@AI-8;aw z>aG{4Y>7HXYBD(_W)$EN>UevFO(=b7W;rZ@jx5wbr2uguD${isn; zSoXD9zl=6NI`H#m==<+iqpd^g^YioTcd#g)JOZie^^|Sy#_lS4d8}7jT3WhWH{WxC zO0ZD({*UI40!Ng7{5~}`bmOgGzkXf2cI{hJn~JZH#>qXKc6Gtztpk5#E&5O{X0_^R z?|$+2_4|HxJ)Wb`!OCs9xv&Z}4u{m50=LBe^n%(@;MNske#Vi_>F47FKW{*%;5uz>wBee!up6nV@yp9j!$&95LtK{*bO`W;np}^Y>$ubx|J!1?87D?*C}6 zqcQt@HK>`*$WZ_IJ?oe4a~}Ox+a>#Y@wv{wj{BDQh;Yl4{jOcyzV`9Fugi1$O04hJ z7wq#8v%QzI!FXQdCi}BV>g^AiHa?NK6kEFZ`rr6-=T5(~-C|x^B#{&2*|gQ+eT8<` zg^OEnY0Uf~4YJ|rx9yMD#;~n*DO|awC^UVU&C73GnX2{Q=9K>Rzua#mo@Z9vx!ri? zD(Cvu!c$LXE;8RKb5d+t=aGH)R6TYW+s$2PShak1>}JmZJD8+s-b3^lZVp{P1h$-Kk2VfA9JK*LW>gzSgYy%l(qR(DrTG*P7q$++0<8 zRz*DY-kb%!OCC;VI>7of`pn<;nKhr!nqU6*{q~cq&TKv#O_;Fo*+AP8I^VCkK z2p?tgfAaZR^lVnO&B?xhW4lg;2ku;wYP31;;qNu`qOP5LE0(tYW8~MC%{^h+@>lM6 z1+QMU{Nz{n_30s5v2(x7Evwe%yk>eTar=(z0*0$Mr&jyT%ipy9?}OXcvHLgL@0oOB zQl_fejyfaH4}aIzX)>JY+V5R?n`?g3-`$;)v!-*3{rGh?`uD5{CvV=IoHBFs=I#0M zvQt*?sqNm+T)(}mD=|zzZLt4XWl+}v@21ezWmDRxoltazec(5l)3oluH*+PZiZ>A z|Id2+J}6enZ|2PpQ~hD(U)``zliS)q{$l~p&qWOJ|D{ayBTfpx^; z-}etrZ7DJhP|aDLT2b_GoArySy3apm&pp+(e(DXzbvCC`*j|3kV|>Cd_{2W@-lBVd zycrX2{*7IA@$+h{z%WZE;ni=?96h6+9``ry_N-d(d;hNN4t-xU(citPB_3fSp-)Fo%e(6kj`gZ9#zePlOuYWVHzWOh0^2?`FuNj`bWA$<#&$p!v4f~~k z-d^YX%Jikv(u-aDmL5KFZOKyG_iw@quUmfk{$A_*+NAS`O^)e1PKgbgmY-F4@4iub z%H8+VA9^z;2>y91xjn*Y=f%}G^)A)>7RS|O`=7gHeRd_sRJMZr`FqXkOYdvheO2G0 zUpni{UH`lJmfr6_&aPuPymfxO%EP&LcS(I-Q-5)VOj+}@cGkZ^3@g5V_u2FR&)Qo| zGBZrGzv%s5Z>za$=Th5KUvI6t8oXxx9cBKgD_hsv+J3g~-q}CL^6ibMy3beDcGpE! z_a8XdUNC*ix6er@zgB)RXJF9y^K<_HpG%eQt>(G6f7_4zDo{VTIOPAo1$trO;q@Q8 z<3W8-1C`459hvtm=AW(mbXMMC%Y6X`f$!hrLyzfSI&i-yeo;@$#iCuo`7aOGrR00} z&b_>MqRlevKc1V;*w2ahUUGH%9Fg0c?AagXy?-B{zvv`?*}gK7X^h7lf3BVM)-S#8 z^-KNj^80?4?qNUqs&3zc`wf3}8p``^Dh}x1`EjE(diTMzY)ez$#M|EBX1=prkMVH9J&*-y041ai&>;K3Yi}{n^ke?@#jl>Tb-wR{)l{io%C`ym(VN+{H}}R>hP!?) zckNtNv2*XgILo)ZwZDGk_-!n=O1ZKxbl;)-593zm&*tCnky*lc;J(4_x6gxR{vG++ z61)YET*q1t~&*N`OQ8WM7zjglBst%E_V$D|<2`T&2cWp&$n7?JNGsR-K~?`{Xf^dzy0s^S@CXDzF%an&t_i4l6vfQ zV)(_nxQi7VgtmE4=Vb_G-p&%v^Hg7&FJE}e{C3aFY)d$ghnX)vTA{q=ay{>?!joM0 z?l-@9Y?3jLIW!?X%!1Dptx32K;2JL+J;@OP;K+kC({$@A-eRuj<{=NNd zKcp+_wHO%w9lH-2wgM%;h$-I+7I4abFh6tlhw7;ba>23*Oi{Yh1zp7~!JXHUG4?4{&G%oC2>&lHtZaH)-NFPc>9W|;ZuYSu2LUa{I^%92m# z{@kjWJE{F*k;Rhz%LADzTeTkK&-n90_20~rAdt@XtLr5jcjxg4Rf|kki(k7ed&alV z9@CeyO82MS`FCx7pw_2?rFl9t9pBgcFK01o;e3!kgC!bVWLG4gxaOTL zGC6I%K;R|QuKn6mwkbTG*t7oc9skV5r<-iZmjd2|8dhkdbmk_UZ%Fx_tS|JJ3F{V6XD^Ubn@tqSB`C7*Pe zFSKWdP{)48dgk}}jfDp*RDzqI?`Nz(yyw?%CU%9yHmSS6r4}yyJ2>x7yO;BW@9shQlb?%w-eorIPpmwqAGm+} z$E06BBsbpe+bh2LVYPX(a^DNLIolJxrT(x?UR&?KZl4`v{qdrns?xn_C!&wZOexu3rm_Uuh@ zL2r`jPnRQa_IAaD>DNleeca)DZKL^>ww=>sAGN%n)ctnb{?!wmPQMOhtUoN&8-M9Z zjrj$Tr`O3%U*!3B_pd0GYg04-wdr2G^;4SHJZW#I{+Z&f^BrS7Pn=qNdGo@g?5+R4 zeX^hCQ<}4}t##T%Plo!#K|S%8wxmYHu37ar=H}b1K+}Bt{3~e&=MPWoxqhEF-{APO z<>Jo2Zrr=Nf7Y(U_s-7cs=wajDXh8W3Mk4q^~4*k{Fm(;ciV2w{_rM2cd>*ULiYJv zzkQCXzpZ+3)%Wnd;(M2EPcD-T`DJt?>PDSh-%+8M+PG_Nzse>{)&&|AaR0pyazuap zqPq8|7`indr<;5)|L`Cz- zZmipR>v6-;_Se%|&(zSf-f`XjSJxhOW9;X@6Ew~34=<>E;`W)v_3CPPYmPXmyLMp9tsBpGy{+v@ zo^yeZzwln=^SR!xd%`7u%>MV>*ru-YZ$jubU#mHrFXaSpoOipY@Q{Q$?^K&-hJG*D z*{$C1`>ppiKceNM_bKrf)%ON3pVWPQ*7K*wB6*I%v6C!+ZN2(F%G|p2YxeK^8yFr> zUo!7C%lmJyLUJY>`bj)aId?fU-;-vZpyi* zqQ@K~{>WKOMn&$m0>(8J5q3XKbbiL}%RdI*F#;PaJsn{0wJm7!aqhH&X z7fdw&n*V3*y|}qYKYDlhWj*UYWU2f;KDkHuxtm4u9G}!4;r#romUsRy`}-$rIrBk6{o%c=-~IbPmP_4VcJOchA6^5Np28x< z4}Z-6E&DI^Z=S1sPj-UPF^ie=zpsA?sa`;9FCOGWy6E-HptU54f6x9tulVrh=5&3I zCWVfpT$bBGB}>CmM$j@1a1S0a3-ST9RO3OuMC;Y7{P*hr|1IZG;??8{QnAou_+b8T zUTJ0gzM7p^v$o!TYn$}axvNoxO;c#K{DK08KfU|YC06E~{26uc)@Mt{C5o+%T`eL! zeSBaU@l5@@cklk~QCKrUNs+aAF*B&AJ@eaklbK06hxjywAYE_E74`LA0$~CF*$&+Q zAzh#Saku$jlY4*OHL-kMEr0HO{g11A>RJD>G5pzk=HI^R@9)%we%sIae%j)H;{VB= zM<1Kt{Ptb=uZ2T0Z27^Xc_vGcVkKI{zpu56FDp!@qx@n`?btmp? zr$i^SZu&cY<>li)YqGc2|5~1KTk@~-mVql{KMO@|KoR=U(tUi`R`Wx&YNcwxogjrG^44f6yq1%S(bg= zHe2`hwSD`0Q?<)ZR(uRm+8wjO`~`>I4a2`y2V#BhPT5|yO}wyPJ-TUg`41mg{!D|~^W*oox3}fJx6Jh_`2D#5@662F_Y+O^S64mr zPUE)Lo@e*zS<2;mE<1eQ&PkYls-k3;&i5B4f3tor`4j&4Rl)Y;-BRy5trF80Y`=Ny z&Dz+dO3a6O0>5khzVdUL`*KG)FQl+PE4kldVS8S%t$Eje`MKZNzn0fb4~kD0I3bzoV&}BKtddbHTsHy=RMV&7ZKft96s*wXn%2bNqJBeHELv-@;bke7?yd^~vAN z(^jvtPE$X9JGA=#72injtlu#|bzf)%}Ug@^7RTz1OE<-6sHy{|$S&0i(#*!E<%dVS@5HgV@fw@3M)yz%_NeWSRe?#4py z>wmBBw^P!yTH^5lEc3B^@7C@E_kKt-d@wip{QcXvZ|y9Jt*~U_Q~dJMQfc$NoSYm5 zT_tW%CS8(HP{Qya|BvnNn4O!n(qDc3`gQHvwYl(&8XgvIX$8*5xvlHfxa!*#E;-x- zcWxm*x$Nk2btFKBI-nD&!9efz~_e$GtZFU7!cMiVro_d}Y20o0NO zO`e0NSD`JJ$Dh6*?9add??>rZ8BhshAX~rx?QDzRc6smA{vCS}{Nekv&vEZ7yOWt2 zKqC%P+i&grQGMy3m|^twpu2qk*ccAn_x zzp6h`5;(iQO3k=Vef9jgdrP%{r3HgVkczurs(vZge0JsOu0tQq85sVR-98^&c+j^lf8tM{?VJ&uyFMmU z_WQ4!GWYLq3Ja`VzK@S#!-Ie4daTXr)1T>S-CVVQXJp*#{O`*u>}NkV+00&Cvbb1> zkwNFf-}h%OxQ717-r2c!%lzkWZ~t6AZ~xn@lB(+8Z&z1)UEXzFEbLGI z_ioOYkLC;qF5Q7l1We~kPdsbAvpTo-Ro>f^k!8w%<1Q{f`)-Dq$<+4Phaa}DtV!p6 z5awO+;PH~bdv2f9-Iug=g?jeW+&4d@84?Wt+B$x!GV7nl`|(di;{6Tkv#uHHUMw?P zTs`S_)T#$x;+Yu^+;^VvJ?8Lz@!$VU1$SP#XgLiO(P#GU=iePR-JDMaw5)Z{e;JS< zD7k>^T?U2+`7@Z#&$F#|6ku`G2|KY<7F5mX@PSeZc#a)BXU>2$uYPz+WbEGuf4|?a zZS4O@LRZ~ONSN2em6PrgO@UztVt7=B1E>%OAk>a;!Y z?yorzEh_w)9t;ip6IXdCe|Y!qUHXv?iaXUSJsg=B{_tM@wtWlp;)e^Ji}>rA8UD3( zudJ{4;*q|xpOK-SUFOe^Z*TkK&F9-U_oRmJw|~97@Y~-Xm;3gAG-r75UOIk%)ouMp zZ&z3EJRtPhMt6Fpl93Rz>BkF8{@S*_ZZNDldfE8o>E@*1Z~K!!ffxSGykGH0O*=nd z?z-;I|A&A6sk3V%Eo8|L|m!bIm`#rN>%vAgP{p9NHk)<(O z_tV$E%9;>4)pq^S<)>#@ruv4g@pnr~ z)6e@>SL~|N%G{jv?9KA@r)B?M-~WGlb-nqYS1EnJFYoxbulV`7tvb*;&+IP8{wwp8 zFaQ1b^6`&dANd!@Us0H8o`3Jp%jNU`o#maW{CTgc>h}-k3}?3QXO{1-J~!`)+16#* zQ4PY$lA=>zS6ydmo$$$P|D*g;>vuAnwlW@11GWelszz&0B4e zO`5ds&9dfNOQB!8PloqDdLJ@B^NIWn$(u6A7xepYewm<~TK)IZ(u0fc<=wbfI&JED zW9i>&cMN|kIV}5Z`El;*kR4i}H5%OS-+$S*{Vwxr&)YjvHMP%}`F`HCE9|hP@3b`; zauOM(&(D83_U*kA_w=*RuKttDIIsL~U+wR2$0N50AKq%O_juxu9~1vg{CPoViht-j z(LC!IxBI-gn_qp~%=)%})5}*|xBU2YTL1rtcKeP!Pvd8XO`mw@@O_328{R&TZ+DV9 zaetv>_TRbJ-L;<|nIo>ZGHgNngcnQx#%_G>{A2guPj_|}d40`1e@4tq$^U=Y^`PyN zn^(Sif8*SZN!zyD@YSbt)&Kib32Fs0h;9Bq>))Q>+TS~Go8@iiWKTPFd*)idxNA}C zG7eh?-fesBwr^Knsk#51wW;gA_Sz-g%*`1?v?`mvcmKzpav@bP#bDG~9>5t|N zIy?8LfBCs?&Em+fbDq6E_e1zO^Shlp+}R%f0Ix@r{<+`o)3ZN+lD;qQ?~4`a9L=@E@-qQfi*7-BM!EifQmoRa(@C-WT5I0V_J_(O72L6^OL6K>aX)pKE0vEz`$@=vFPAskd+_I!PbF;3p`rI zzyM-{%=@#qff8|?N3kt^EELld-)Y628Mt0PJa8m_VA_4PmPYB z=Qr0}4>oo6zqe*fRxew=2dpBqezkW{93ulm{rN@vKc^LE+LuS42G#Em-b;S{eroEq z#2fW*e{S5(16peS>~A*6h>zxA2Seim%7*B{76@p|wqS7yiL2SqkAr$oGpp)yO20OL zzhD1rmj(esW`X(NivvEj=&tQCEJkH16k2LR$Hy#_`8j zVDszu`IjYD{QLV-=*X1U_ube3w%>o_?6UIsKX=~mw_CJ9$opOX?-eKhhxKvSYc@p) z)pzgwZ`zx`?`K-upTCfPSLoL{u3yd5m6IeNoz~x9^Yzu#KhdH8%UajIo~_&#;Z;BV z(>Bq#*Y9_izppczcjN!VJ@@VZC&vFhGF$%K%mNRiNFb`um`V zmp_*;dSad*qU(S9{`dFy?Ke67+Y?a#-_Al%_4#_8Cug3Xn!8!d@cE~6hk|!J&fk4T z{MWSqXAK|9aDG!v^tEOebku3u-~MiY+4FOAvmbXrR!GUs|MoQAc(sMe=baDdY&>>$ zwt4-pm&@zDozyM|9w5IX7-%scTXmtoN`8E+6Fbwq`XJd z_y2h+|NqBv`<;r#DRtW#=2V4+g`Il({?EVXZzMRlYAQ=wgeT6t>F6R*EN%Swz0dvY z>m(abhy4Gt@o%C<`k#rKcP4*t{qg(x{d#Rt*4I46%h#As$}NOg#GUUYMc1nSO4SOVe)N71S8gAta*_Y-X{*mJTrBItVtD?a+^@gS7nwv> zJlVcuTl}2w{{3D1`nU(fyx(_2cEsHH`)5ntoL` zEO;)pG3K8dhZ66_ZyjIrBhx(Nm`x}Ddv?tnl)O9t+MfFRe&dhb>skM;3oV~tUCHuK zjpL8)oc&K1r&a{SO|s;z|1at&5SEjh8@sP&W{pCJf!mkuYw8{!>+S9BJvwc>O28z| z&bd4G-&X|XXg0$|``5=rPSstre*NjtPe>~ytP1OohcPlRY>>QozY|o<>;DP$Yuy7X zK+enujp#y4MraS}9~-Dm3m#Vj^@M)hPI|o~e9!51-}g*C^Rgs$*X@tfa#T-$?K3|+ z=kU7iGuA}tO~^C*X>vD8@Gf7wFv9_xpVhfHDl5zQ?}(s9ESNq;WE4w?KV6*ZRrjVL$CGV=n%!-J|(`+Wb7#S@*uoI)3@(60vz( zcZqAu&Hr*1w5ZnL_`hjhFG0<2Z-GfZo^M*W&Y#Y;e){*W<@YY!_mr-Pvpzq4i%-rq zU6;IDH}+cXt^FUpH->?s;pW%vCi?o#`&DO(zkKiWu=h!9{C~4adMzjyoQd4Hq-{XEIyJjpWrpPrl|_q_kxey{v#n)&+X2JJlIU5j5mdHLbb zx}BW)t_%zjarNOEH-C$OD>}Io_siei*=g3fW1hy(DvQl)CZ1mY)98Bs-P7s!c9;IW zmEtt16SQ)s-u%P%yLIy_ey#r7zW?t14R7MC;-=byt0&pd)%}TjZvx5qa9buUq$uId{fO-niel-2LPBVQo$tQoUuE#B zCC^G`>b#uC^11Z%wY1{Hm$oje6*n&1DWGRiTE9H>!@I%)%SBt}hpV%zz0H5#q`$TF z*WwiWfJM(gc%9a>uUyITyBIY3vsdD4zVb__Cw=Enr4_HRkFWWkb%txai&cwr$&XgTH^RYT?}9 z_it9}+9sEs3Z56-S$McKOX<+FL!YbHF5ms+*7cXy%_jc7KXqzd-qv%M{^mcO9@;JN zkL^$H6Wyxptx<2ws`DM4C#i9sG1({c_xxU|^!xjGrko^q}8wQyq%KM4_W(u zW^3xl?_Ia0R!W5XHP!jvs*k#5vherW8Grw*tNa?g=T-8xSIsZy?caO$*f!&`dh;3$ z$zwnMlwY`MkYPVvUF}c%r^~C)mt5;C_w@R28lhG1y|kpf{QG8A4o|iB_UsWQS?@M5 z=uFwaw6aq2kM7AM_b;yu@m4})wBR4_h7}R!sXJycLq|T& zY})_+-rnCQpCr{jzjye)ozKqgo8@BFe%-tQ&-tC}zsdhwX7D-u_wRU6E^PSt13c2K zCi>|8U*7zCUpKk^n;m_9^8Wn0+FCDO-WTTbR0Ed`cQwqu1)IOGUn=ppD(LOLJbxdf z59SOYXP&;QE@A#%&Zgo=LjL2&Tcg>H5^wC*oPX*}b9A=wJyxiG+l-tyoohowK|}us z?l=Demmw{nGUS`DaqWh`N3YI)%g%qg@|kkr@2e-6W8*Mx84l43NWyX))fp_-*Kfqk?-(E0d{g=59e^$(GE7;?j z9dVwgUgB9&&We4e5h0)NN~CNoTB4cmv*A|D3gwtk{=ipDmnObS=y_`FP*=Nu$=MSJ zk`88+rnTHrWM8Cv?AK)@MG4{e8?uX(Wy~&|-_@mjRO&`~P|9!lpPhf_o-eDuviDLQ zQ?Z)lqp!QJ8GQCF(>eb~^Jlc(uL4e|Njpvc`5jLTIsSjzg)6CNr<7K!-<@aoU|H!N zQw#r>yDwH48t*Eu+qHfFE+fT_jHhSw7|NaTENc$W@?Tif*0lbIss5e&8xPq}*+042 z&o_Lh=~sy_MqcN4{c^55ByM%>$Gcf!x>r3f9V=WbQ!~+4Wp1fa&KzcDU73F}lfQoN zl{PmsGZTxxH_5^C*`y!U+Iy#5_f9l7++2RJI%)d3u%KVtHr4Na^g2v1>vTzuxs;yR z8FTi;T&Fj+o6k2m|E#_tCE62W@Z|Y9?%O>7#FD>luio)8PXEremu<_wYt`gkyDInT z@+l47^f?FPPAiw(+25yf^Zb_1pSM%~mHgQ|ZO?&{+S=^w>}qiSo03wuPvl=;U;Uh^ zPQMjS>WS`s_HohD6H|VaG$y~7SfPEHw>_~>ciEZmS}CHOlB@SmZI)LHu)A9$wlwpr z*>iO<^#XG z)AdsiZj+k%>CT4JHM=I>+4ruNefuxDl-R?{M{n=FCBrxAv3~M9qc45`7vBC}WW8gC zak%2sIL+N6al9|~CtrB-;C_SgY8O2trKjpY3g^aOKJ_Q_N3_6dUFVP!)erx~-V{rh zTKP%!uG7r*+1r_(9=)qO{hRKAj)vJ8`rBq0?YFs-Eo|iSd*}3Neoso6g|+AR?azIB zq|WzuUDsNH%j`HT# z{n}CX%WHo7yYfP16yNWYoqxGZbJbICH(#xY(^*;Ldi2_rZlV4AU7xxx zjF;H*>2dw5dm{2XI1@|i4+mY{f0pygmJ^ZBkAITb7Ipe`RcBrBpQcy$ML7f4>$a_` zH}_%fSy*GGcRkyC)|I`y&sr689JtQES>_+SHHR&0!$$8u<)1ly*Zkhi`*L}2QEB$l z(_yn_ZddIP%>-88|(&=)LlN^Yw=kJ_UI8U2<0aW_`>m?#kb5SD(83 zubKYyhje}a?|*w~I_59b0dFvm)UzKil<=^vfqO0#uzO(=0>+Rv}yfaE$L+|$<>;5^N zJL-D5sbcb1^S{@Zh1i{b^!z)+s?Xc+&&Yh&aOAfA-Sx9w{zm7o4qwl)ch&N%b$POr zT(fsxe)Kl{vi7ER&pZNepI=>k!`tso_zL?zBWL$lH@}7NFh9L_bJ$Vknz_#pChPp` z{r}+G5r?^}z2z{-3)~1m`~ZnZNslmifs&mwU_B&iW>HGJoOMt?iq$ z%abP@UGseZS}kv1C#fH|Zx@&LMKdqpzP;phdZ7|u6~onEx9`omWV7zOz1DBHnafp= zzs@)Bjl61kDgMZ};4+P=uIp02KKLXo9dbl_^SW;yFH3%JJeL&3*M2gvuJyr{g=HEy zd+yBU-oI#0@~#Wv|NFAqw*d^@ef4WSUsbpyMc$vUwPtN>d~|g5oA%?^ zChh3k&p2(xbeZX$8*co=>)rG z{`|@4M>M$kn6U8G{rP&10sq+;7@+lA%nC^T76Gc?_Rjr!WB%ftEE&)`bogisXt(2B z>+*HIs_WD*?S1!m=D+If|J(WH)!yVUnSbY(@3-fNb1Ea%et&+LpSQIB{;uiz_3y8J z%}$0_b2sj{Zd;%G#{SInDaI*}R{wqEznL{Z7(6Dm{rUT%uYr)pvFUsN>NLB(8^1qz z*vwvSetPD~`Km8#@`E39cs>jIdAq89iDbP`W#}eTt2n<8Zch`gEUO9Fw9m|9#@=bB z_rjlUXnX3d$KNb?;`GF`THm$I)bFTfAD;d2jFI9)pVA(q`U%HRYo9X6yRfE)?aAS+ zmHTfU6%uLdI;cHcu=f8>N!IMsmQLMwE}Wii>+|E3!|@XxrwG0C+3@yd5q!R*DZ_=ZyOiRxp=U-H~igIg@5a0PTc9S zxL0uEM9p*6=sy!@BtG~g$#u{C(HWj6QGu7*gyOc`&|t1*JG8BxzyIvP``oYJgQh

Mhmf7GV~$KE5H^RpQM3rPg~bkX}oj&uswQ1>3VTjZ|UWiR_D%MbNK#`>IoiuqPMi9 z-{Si_H^VOenSyZTj<6!#1l@-H>}&3pD5F=KmXm)IZu|C>O23x`XtFDU*A*v%fGdA zlG5J)*tu)k&dB6=jgn7WQ>@o6>a^EbBzpAluM=-Vr^OYYKCrh&bM@(yOh3z??o2dy z5;4!7#GUtjUvqTr_Dy}dzUgQXqxj=|$=ioVhL}G4rX_UWpDraQsKsq>r2+ZySn4n`MsZa%(D90w_|QWme%5_ z{>Sf^-E*rqeO+`x>(aFRO*6yz`M*|O3=P@#_shD?fh*$=T|FeA|77mul;F_sOWqzi zwdMAfWck{Y=T?|+-lIFC`Lyr)$u|@(C!LP=Rl68+;Lh*g|NgQo{-|E|>V9JK`r~{3x`}*p;>$B>%D*nyA7G!m*_vHOksb1IA zXgSx-%Y+m`RTDLOxCCUz&KQ*26{%@Q8UgYtq##h&uTy-|ddFNO4_euHLsmr&# z{wsT@pXZ%zxV>)j`_LZ_WpDLDXD`^}5NN*c_w8x}+X_F~SyRs+3eEez+HL==t)@#W z@4VjstaQ(d+0TU#mB^BUg%{H+7v9-a)%~-RSL>1EHOuyhJ^yE2zqL?re%kamK{lcW zwe{RdTT?r@DnI`-ZIE=Vw#(uwzmvY@eCFZbf=8D!-_@UX{(i&$eNcgS) z&*yyKe?Pyd?*01|zocpACw+Wej1AQuO9>|lsp@s8%``Z6B;!cNqm)UWYJHO71>M{o zO%IyPINoK)7|$#Tx#Qp}#;cc+66ojOzbR(| z?Ff4*JquW7o`W_fphyxo4E%jEy- z`2UOKGoSZJ8Z$95-I=6YBX{fnf+ZLGrRKNXH0fJhs8PBpe(oOY=$u03uQe=HC*Pf1 zzb)r{S^rk4J6@aQ>;HUQ=-i%ndzZ}Z{6|HsnB z%^LH~a%bu2ew>n{c(#Ch`x{kZHJ=6XOIlAnyU-_n^8HMi=Nu2uEjahzVp8>?f2;*| zs(*_*_QuXj`;zWV}oJ+tJW2SLI>xamzz9ja3u(W?WQKy~!=E z_oX8zO?bvMv+XIDzkmLEJzhLBPwr;YEZrcDw$Pi~B#y>5ZBTJL{b*xxzrg8(CEO{> zKC8a;Tun*2%rLPi`__-Q`Sri+MS9CF1z&00Bxsvr>|W>c?S0*M>%`e|nbG_=uekL} zT@^}M{pdwsPOtc;?+y8tW=e;n>dg+R%ywEcgI{BFZsfebXN=D;S+b<&$HR6LwH?%j3HrtjOrg3`PBC$HTPc-{VNK5xq6#+(VgY@2RRd&4)Wt+?lz z`B~L8``elfO@Ewq{lCqfvoQ4L!O+Nq+dXF<-0sK!aEjrQPgfFxj-EVt+G-3*oyVgrYy;c1ZPKUn zmNn;`Xh^yL>_phnTVX=Me47-VC(V^y)3|kQN@nFP2Yx<@X)~rzPv_&mbi3Z6WoEUb zOZ}YK33oT8T&@UY&W`phxmh@YcdO>j#m9Rh_a(LZYzbz+xh^6+XY19Jo2xG8Ts@v^ zx;%gGPoWg&T$#hT-_Nb{i#$KR{}WTMy*bz+-8|z{FLRWa z+5WdRT{q*MzC}#lFn!x$pGVrhi59OFZnNguMoiAQbW1fVx@(PTYrOp)<2UBf9`WTj zBBSR`omXaK@>2g^-mpKFUJ1*IK4L0J2~mfiEWQp&(4|t z@7t3jecO!vx@YnP6-;=mdQ+XvGTmuae|L)Twa@XT&f9M1xNz*+wMo$WQD^epVFeTFbG%DJj81PCk>T@mTqsJh>^+-eB{@X|j%1lO`N#RXh25LT+=8 z{z*Uil;gW9Hmg)85AdA^GNvA(^>t?ZV=u2Uyo-iTi6ZW)?VU-asr zOJ-%?&QGf=Ec`$F$NF|2H#3&T9F9-ro35{qpT8+j_AYzj+gn>ra+8c^hOLjBJYm9y zqN}S?Pd|!#cUycpmyycNman$%n8`?-T~*%6i%qLKZ_khwdACPOGsfw;{&MY8VL!7cXNfDnRLxr-to5rv+^(=xIAybo zv)gKiZOqx;&dH&n$$#HkZ}ClWcXi)wDr4cjn9Zf7{ifiOXQ$=_tiHP_#eDU0H~GK$ zEI+kwng}~Rb`{L-OIv+)O30k;Y2M1$*GvrT-nw|J_tE(+Jd;oA=y#i{&T=q2ktchR zMSf!Jd!8G-qN2R-_f$W7u)_0e>eH~*rGY6^(hf|!_T}V>1@0dsfAMitzd6!ldUB81 zqu@zC$0AEqW!yRE>^MGCaOR;DH@TO=o9q=1-8=a(&GYSa%R=EAhdKwdv(cYZqAdcG za^ngEFN@>#b--v351tq90%iQB(xO>Nvx*H#4l&UWuX<2h` z@9TAOrYl4D?&`nk_eHj2H`DW=2U<&>z0rzv{}G}-`@N25or>*K|CLK*{ya~tS*g%G zNp^pY<ZUirm=r&O2zba>q#ud6*DAmEmh!(=T!9G zxSU<)R#HuBO|FU4zB7_4?@t;qHs<_Sv(~elr#ySdHj^056})n@jQ_lyGyjaJs;8$* zS=jk`t(lqcTiaI29c1O0zEdzWr>w=t^OM4ccXPHCs~Jo>w<+RvTTWxb)IF|0MK%fU zSFn%H--uvq{fiy_;AQ8gpz`pP<%WuYXgLM6@Lxix$RKC3E&D^m>>1 z+`oq}E|<6X!SHhGmV4Zf+n0WSJ^AKh_jBKOyVaUVJ?AkJx>@pZ z&bs4wva@DQlKP(Ts+sB9B01|nFLu;6n;)&)mi*jrj`0bPl*>npcb%Fsb7p8rNQj4) zim2EGE)Uk9Oa3$otNW=eU-Dp%V}YE5f^>?rf^?GuC>wUh@z&&CTNC-dU*_i1o%WAZ z9RE3gyDV$XCn@9;HmfsnvHG{_PdgjZ3s))3SBU-}+j;fNmG}QIs6M!hzZ85tS(R(-AdbaJ_a*%R%QYWD9l=KcSC`HJIh`?_8Ky=7k>cbBXD zvansg?7P;?WY;)}wFaA4d=+17;=|3uvT3iM?cAlm}}bCx4xOrE+ytg2IHiiq{zDTJ^sD{iSdJ*XZB(gcI+|e|qrNB)w=r!#wn<2)t){WyNty5!ZBl~+%eZN0Q2Dna4QugXjH zPfpLBeEeIV^rsgy>}~JdR9<6y+RY_jV)yA@kJC!N^jg9e#hZprrU)(vl zyW1#nnay@(kC$)Sqw3qIx;^Y`bl5iimDq)i-s&;gEdhe8j#4SzyoiY5V7e)g;;`xA z%EmvFb1JeFz)-S@_j7xqzULOzkcH6Yu`B zG1c|k_K8E`w)u%~>HfWcHf##b{K4FI^Y@0ZfP#D3Gp==`Gly5DDeJAi zu_OAEoBYjFAc@(^9?g|md(>~gon-#&WSU6dVU{Pwo9o;@Uoqf+-Io*VeecD2w;O^| zY6|yv1tr_~^S<6NDK#}jBVDKRvFyz*kP(}&D?D7;7$A7{R8geQn|~}v!z#EZ@H)a$ zC@3IU{CQbGLE&I#V|un${6_kNl^@+VCC+bLek}iFTP@o>Df!P=W*kdm;Go(L0uJj1{B}rI~ID zuxwJCa93;BWaBMb);qMcf0$_+|G4&2agI@2$UG^ZRTh>%empZT09Q#7w@(G!fS&GA^{Nj|= zNx9mcn(Q|xD4smWGcCFH`?B(}zpV^p{E8Yq|&b97aoGUGvLpnsYKWFEw<0*pRkQIi+CJN--~;bJyaRo}GL)Iaa$R zOD{_J^3kJ5zgQ$6`!e&gTJFtFq5OA}eXGQ}FE%Q$=A=8uzmD0uaFytv!VeE;=r%|D z-<9|MaC7lim5}|v-|Y@xAGegZYK~p*t0kV3&GK$NF{_*)Ql@2j`Ef*{Zf>dAWzQN; zzjsT&iQNn`eG{5#;%goh%>UxcRjsi8Gwddry1q^=0e|0azwbBGD0Rh>xfX>^w#5NV z4=1H-$0Ta?iB9A6&D^qade!N-x>`@`CV>seiVr+7{Zmd-RQ*&l_iYBkN}f&{A^wk} z4ey(rc$R;1-Eo!Ghc_&O`0HFunKt=(LhQbRdB0YfoO!#Tz<97Jdu=`wp^#B>+q zliTi`+jv#{LUNIp*X;k(Ew7zucG$)@wK&E7c9-~V9am@3vqjp+%W}&+SMl$NjE#9M zaH7n+?AC!zkLP4{?_Yl7&7x>a)9YnI*Tlc?zq#yxq{QvU9B^*h^zcaIE%uuQj~wc} z%;s23h@Zr(&i7<_iuPO!p*1fr@%yShl4;I)Jn?M7BaaQsyzNaK>+0{_>VExjN6S6E zlX>fe+gnXzFS6WJ*!?!SZ1Wrooi({fC#D|1cd0Nk@R4qUPS#;z$$2k!P3hr#-}B9T zLD|&aiuXqn6YrM1-F<0s{@yFT+}W;ER~7|Ich+|Aebm!c?)F+W;P>gxdrKZ^Y}h8M zziX=DqqJWe>eusyn9ta0#XQ5izM|xI+1jko3B7_##QkJguWftHt&tGTt^DHSzsYNl zTQhHR+y)i@oG-&EB)9jhn~4y={vKlm>6Ge+M*bKN*gc>gPumR%T0SPSRMt>`U__ z6UNv%RtMPUSO}bGQvj7y(d)jxzP@}-^z=D%_LRN7b>xW3k@OgCEW zd(r)U2bfZ%gJA90+#4Gn-q~5~ot(sIe!^^tMwIYn-rinb-ri|#Y~4#2&J&*)8x}Tg z_H1d{y&@?MIgdLh3H0SKW~<*6Q?j0v@12z7z;?oHp2l{yO|cuFomjVi`<1KFQqpTL zdfz$rCa+OZ*~z)G^~>v1Z(quaSlN7F{VRX?^1rq94ij=sE>5_pHR0`%U5*E$6s)zZ zqF!_8f8pko6})o#XL5r61l~=x4&WB6_!`}^HLqX2?tF7%#nD?AZ*^|{p3s;x;qIkH zoOVjP<0iHXT-#bIb93d&_Tb>)!^%n_Oy3U7yOr?KG4@2L%6-OkCgCSSk28~9G6M3S z&S!lkDRjgCQf@_p{_i>~r|SnEF8pS9*TL+>GndcTY;KBiUf%QSO^UdPh>el{%M%lo zb2h#0+$wcbW@Xs|ONZ9EGS~Q6mj0bt&p5~Z!N;jJj4j*WnO@*D*{)l2*}=?h!XJ)J zi+=F`Xb*V@KMeLT|igh_YP+mj8y?sVu#3pRwE zcC+{*+PNvpjA@hOwq<_v&&{b-SR8zX%_&mlwpOK%#s!tzr9CHRoG-J}cJ1|_BB|_A zmvU0prHJL<>BAC^O*s?R+BT`odMzb2)yMk8Gq(xV-`;&~^yiLq+?IFoXz{v?B^xKQ zb-NTyUi4I4MBtjUb6aE1gj|)2pw^$q^yEvIE@>`3ck0|c^ZI{xD(|12XPtj-j^)G6 zY3F-pJT;y#meLF^2Tpv;Oq?rq!v5qjE7J+{C-s(QDePB~etpHE&a13@ZE*8#&!(LC zpwnxEnKwCp`x_X&9>gfiK6qE^^%aYEd^vpm3F{IcM66P4*tm$7Wz*h<-J#c37T#mu zXWzcII8^Frkm;%F6V3{^i+4ol&y^~6sgE=}6my|@V;nonruWNd?e^n6!FJQmt8DYN zl@}-XayTeUGu~Xg`q{c*VKqIsQ!E0sRw;U9H+o8D4?Apr42R04h<|{LopUi}} z^P7a(Q+{jSEO^wAvtMM6g~DzBlX-^fd@P&(UhZUW%=usP$U)(D{TvIUV&3q7SwLDwxn7}t&n|R+IIXU@}^s}gcT+K`;%vK05pZp@EAWd08 zI^}nx@NrIa`JGF*7dx0SZR&k}r0_<8jI-O#Uay3`jG)3)K^jzC9PVU3Sjhk`Y3tU_ z+_>6APH{r6&Dq=K1~2Ab`10DEou~S{gQKSHyIm!7<*q*!yOf+#m3QUho5K2+-TyTv z_D4aqP?t>-^XEzG#Q{|A{J5SfB8Jr?&O^xLY$y6+eF2`QyuGk+u78eZ0Kv^3Gi+ zzm?p4DHgMASL~V!-c4U$y9_x&e)awy3G6g zlXrd-DE*e!?R(uL-{%v*@mY%J(T&+przF1LAGFE1pZmtL&EbzW)yza=3kbtU?uqtbCkXQtnp_gi-ce_rdj?fkSXR$iNbJOBNiY=!gY#wxdem+;ESt*Q`z=67~G+s%Kg`P0tL-c|N_ z$&HpP*{T0EcWiuK^zquB)vwQquCbdeKf5yX;7V>|{yBZ#*4dkH-bg9F!}I2(4`_XIWmI^Ra&}`?Y1yR~&mYO|ja=<3vH^oM+4%vd=MWa@*=f{!N07T37!anXls~ zeCLncF-F@nZddL}rTktw@BPK>Q}3APyC3^!o7X!b@$!@trzY<-JbqrsYL>CSY4NYd zU}5uj`y*mj%}cj-tIKnna7mMU>%TuA`j`x!-u%YLG;tEM)x07}9i#GBRoN5XF0Xq0 zxBuCa`OyWRm|R~hojHBl9JQyqYN;_jC-=BS)x3IS|9@`UAH5L#5pZP-H7;9wg*t?|jZ(qP} zmD$hMR<|x;(AzSoNf9SFVIagp@Sp?|V?pDXO((F8dSjb#td^-xthUpRzt;G-P@ND!O_9_261NJC0Wk1$`~6|{rKPHwdbEda@r>G*wO4nSYS+zjeA+FZRZKGjCUJe z8dmX~@7i&_WcH)H_ zG-MTa`K{e>UodNW%JCz|PMwIWEEG*ujugFlK9B#$%UwS|%{{IE_Qk|`^ZKkZA+_4N zj27{;Egi|n>*vm!Rb%;d;@STFJ3jm0m%sb<=8^s2vIAE4W!#&k_JfPtvz1llS9rvX z_<#ac`~U0b*Yo9bpE&lPgJqK&ZP|9^>dljS z8X6TTahE14yVo2HKD@_p_uY)c;+(hm&*f^Lj#>E4ylKsfmAY&8Bo`KTS>8!%b#*Db zU7alVvYl%Rb(a zGhwYAsB!UQw&95xWfRW!Dtv!)_qDgY^q!`iyYr-^bc7E2cDX%cK2())!e9dLCf=7T zJ-xk`PqEUruDAotM$e9e{!y^_&B+L?vK=qNf!LKUh3?Yuga?0_w}WE zyzZ|LlRf3@t$sdr6yCL0=-2UijtbH#($3Z2-`(Awe}Ad>bSY`+*C!nhZ{J=1{@Rr* zU!;EAygKRj?0xno?^ge;|C@Aa$;se^*&koF>j{y z%k_^rPCA8L`*GK?Z1!Yd#@~kfbfQycRj=7~I9++W-k+++&ljifnDO^yt?KSl8?YvG_W_d7G;a^L_sD@$7lGTX%vV z-!(E{Gky2}yN+ei*}uQNwM;)35*{vm`B0PGo>v`@&%|>Xor|ed{gHpwbnB}W=@VcL zZx}Z|*6(>!{&3%X3CCYuOI}~Oa_!pPr>4(7?@X+ZpR(hny-QixH%Z@3y+QNe#yTtw z-+JHl)SvXZQZuXenl8-$@cezh)cv}X%k~SMdm@)2eL2|q^%b3n9U1?cS{E%(dv&H` zLHU2P)T)Z@^VXNXHC|IYG55Uft*yoE=a@ms0yRy{ld8ya*cM-z)w1k%@ME24C1?J1 zsjg(~$`aUGX=1y%sLSr{?axe`Y(HO#kdj)xO6qm~{e`*TUtjs~dEdE9OT~Y&eiPFE zk#dIf`l9G5Z_>VAdC^=Q@N@CD$sQmC~zRMk_oHFHPvs-XkZ$ zvdOXRwZ}F;Ue@Nx7EcvymX!TXE>uRRVW}DYIDL6-!INoPW?4K)9{c(bK z>BKWJi??jlXe`!Uk#swHhMH{V{OfZW|4Z|o?lZEFHMx~{crQ;RoH}FmrakS>o2#+jlX^+s~7hm`n~YibBrfO zhP3Fkrmnk~8dZ2xx$x16Y9k*jh1>g2_I39^KcTixmp7a%tGWFdPrdbX^g!24wVqn4`vK9}JFBOc{P^(j)-0)}*=7Z^9Jeu^d^U4gfUZGoe6X^H zuCDIX{3(-5D&O^6TvoVk!1dxzYfzSANU0epD(vr>lZ-?pC z*VZ$$53w?Dif+&0I+L_wTgY{R3tP+I-C4Uzi8JDQ$UUox)4m;lzWb3+bB^-F+Al8x z^+Y#D{NlNBb@%-|rx?l2n$nCn6>cY_1WWmv2wxWdUpM1W*?aTy;4}ZetUfHV`FMR@ zM90l5&nwMt=1uRs`0X4IKaY&YYklpBQ}6fB*m|KSNxeld#o>7~JHOCPkqzqq9E5(@n;?XVW&9oly&v zFWs~?|IE2>=Q8eHiJktoA@R~n6~pC@Z|A%@7dvk;tF6XNHNnd=*Zyqtss8q6;kcO4V|KJYvKTl96wa4+>3&UiaSLb7vyX~01?Okcs5-#JXGY_-h+5az~TDAITm#Eyq zwK2=vj#SqDymsZvlxg$sy*)Y|G#6OC$+l_sPQSDKvnSiV`Tge2dHV&&&vI_$7Smz5 zsc>8U#5MlyMRTRNu0Fp1EBM#>-|hDQFPwC?uM_%msj->;_ntLo&O#!2=Y(fzo|$@u zQLrz)W%-uhm)W*^gL_729|}$ipXsZ1Yp%t#!h#jDlh?*9S2HZSbz8qgVGZlWZ%y@m z%P*{J+iGdkA=+#i^tPhVh0FTtuj1ct=N=ZS+&A;$-FwUJkFWn6E5jZlCzEyjW=F|f zDIwN3_WOT$yxJxAGP+vu+82-8@Aut!sPWk>LuQlHhL8zwe_e?X=3nYnzj=y>oq;jK z(!b9-{`I`?|Ki{B=0Sk9oTJzEm4YY48pKYDnZ0m3{Jl3vF88{{S@+cIJxnRd*Um5g z_sGgrCF-)XLbRsYO}P~1b2c+>*01rDTh5tR$N#ut-OUaQ23NBtZBwDn*H^B1owz2w zS=RCTU5+5D-wUtJm;VzOvdrf8y%zoECk=heQONE4viHOM$HHOj*={P__7J+Zva=`3=k@B#PFD;!o_?|D zv1rtsV;lX>uHPT0xTgAhr6j0h0-g`pTB@F&5n5Id8ulSKDDA`A%gz?5JS%NXXM_|M zefW4b|3Qx9G3D7CwoP4rXhoJ+b)k?&8~^w&e{6hb9>!Sx2MM@pX+{juKNl zliv#7u>q~cc(>(htjG&0oc(5<jTnN8;#zj8%C&5ORP8eLl#bL-Djab;IsJ2P`z+t_&9Ra1DXMCS88 z>iWQD(J86D(kW=#@0;aTs~67*T_1Hky}CH$k11cr)l)G`=QFa&G*9rId`;%s)au;Q z>E5f1epu`+`|#*`v)DeXuLr_6`}_SXi2g9)h~28G*Ur6q&X6{By=dzp?&ASJlnB0BXrW*A3Up`$(}gANw6=+%Sq>YYGKu*b^W{kJ-)g9`u=bC zmYLtXFSg{i^MV4Q4==0*QbeYEaR%Q?nRB*Pz5IB1u|dXefhpEg=R2O=!~F9W$E0;e zMLV}Xl`7QfzPu&<%ew~~f4BGlKR@5ph9#?V+v2)gGIDB4OI7?&C`Fh_>Td7;_t<=X z&aw1_8RZJ`v%jvkFzlGk`S7He%CXE_|NcDqU2kusrI#*ceZH(E?%ACV6Eo|kImz~K zMHGrXMN`ZqSMrC~wj8&yyFL5x8Mm0+Lp?byexDC(gXt@#6DlW)o?gECVpffmWI=L> z!#U=zFAC`#uau6xS-1EE2jB7rwTmxOloNVR@T9j{I@kM$mR^5Z`}#t=sWdEwBGKVPft!} zUt1HoHS6m6`hTB4pMAOUxZLFWQ)e`Tm&KG`4gEGzA!F0F=iKo>4o#1l{Kt5)Zs*Uh zuC^^1z4MF8y&nI(pMEZwfgxpK_1Z66kJ-Q9^Eq$--)~#9udiBH|M95!`#qoiA{Cas zo30yOc0IQI>-+ovSI7T-bz@`ldE@1V$;Vl@6Jzq7cbtl z&wP&Hs>g9b#>dzjVoKM0#b?(@mdvmHc2numty@vsxj;Kei{99nO>e?5(`DqLt$SFXCGtKt?sw~fY8wWI6VajW*|&YpPdxRh=-jt= zyWdZfF4{6d@Qe8VAFkONxpybbESj!kka=l|#j)%2c8Wf(|9LuoTi)sTowApIEc#LS z_}I8LZyTaV_PS~d|yR)_AWsv2;*~zl;yB(H%e5!Nk#l^)>=NDa> zc>AaEzWu9`Z{CT$`my(>^J*)-m&TXa8-85+{?ab^arW_}5Bp^e5*m0OF5R=a=;*Mvi_A_-$&OA*BmS|Vr23nDl7Ka{oR-2S9DnF z@$TnGc3v?4b0&A$R<-Y|p4?3B`@dY4!#vqQY6eYf%UZw?W!45rPxT39IW zqnMtz*|@GRJU#8`id*-7t`%c&s9Se+ae))V4yXdx0V1;<_sWU#iby(JF zrOdUIwhul0P&||&faTcoay5Ao1`WZ-#)&ly2Y&cS$TJw!MM}=!-q6|ExiY55e!(Ik z28L6Oe}KD>X|Ei)tiVa$Ez&Bf-&*c(2{ zKK{K#er5IHAJ%R^+`ccjvRnE0oV5JDfBOQepG(WOmxqP$@vJ@^5xnTuj7Za+_vR^o zow;So+UmEr_pvW~cKh|l<3FDDF8lSX>N?lluNM6)uGno&_Y1yjVQ0b+kQ6E#{j0D< z|Ag!Jc^7M+tJ|)vmVfcR=&NLQ3;VgMooiFCPdiq=@B7~WvdJsr=6+ate}}D3=!TU> z?|q}Kb9&yJ?<;;{AhscG*7-+Ko$po#ADh1X*<&UK)u`j**N?pIwF5-rSsc?E9SB z(#yY(UAH$q#?H|5-tgbG=(*a(efyK8<4gWO*}kavy4cKK1*n6 z5NpZXnbE~A`Mf9BUflj$XWje8kG=2hlh@c5XV=a=05Zb%*!`kxukZ71C+9@gt*Z4u z|M6~83NI{3o?4{CrRAD@;CkRr1`$S|Gusae!DyS{hI$D zzTW39{{PT?`7Qf<+Y2r7%^4g%O7H(D_A_+t!DkPDn@h^ne7`3=e_u(>d2XlI%k|}M zRK9m#fA`F7UWR}#$JiMddiWU_B=#>V`uXXp_jKLpO(`e2_4g=D|EMC=`CME#YDdAt z&F5{+%iryJ&BmYhoq=IW$4A%i>X(E2FHBB4+9fJq^Wor{o5d6C7#un!;@!SK`nB%e zyLIc{om;o=+_`mp!iIIl#h-t_-*2CMOy`>bgM+3-e3xb0N8P*D$KH!P_BUQWlX3q= zR)z*8<9%1&9sLn^w>&bq+C9Cz{Cv;MiOGKw{mwtWay}{cuYT-|{o8n7)ob#1=Jc-A zN&X`?y=@jl!^g*p%d@I=9xpGwfAebXmyGh`6O)Ugd+ckE^=vSm@t1#&%H&liO;`3E zzr=n2`J-1Z5yu~|>6w3dlH%zj^-2s4j|}(4%v64!nR{1y+WVKDI{(&WUYwPe{A#Az z->Ugx}QiyBL`9dx4&R4Hm zmapCaTkpO&U-rAhreD`3-21gFbYBPqL&GJ5eKFwEcK6~9j0_r* zkFTGbumAX0+2tQa$-lnrUG!T}`TpPj_UZ5T{CZ_OSuOYeM&;dBb-QjPsjaZM{^3T` zHa^j?t?Hp^hEwwUkDInnp0J+d+g68D3y;=|A7gJQGX1ybR@C7ikA9z9*Z+M>@1DPV zt@nMt_xdaQcilLhWB0$F&3~7h^XJ|7ed0UV`Za8?zuIy9(@Vu|t2vTondh9=p6fIr zJMsPvn?paQ-DG}c|0*`5lwrY{9{conHaiuTuifjs=l_q#yZ8Ur&$ru=d}@Bw|0|zP zX(!b@T>Sf8^zO1;*QW)gFP=XSw4{`%V6t1SP2x^!B9^Lz$|uG>E@xj5E^?k;}5&fo55%K8oAH+H+u(wypX+b$wig=hKGj_q*TE{9Rx0cPexB z>&`Xv51rzVF+QQ!<39~YcWO-;@36eQ0RdGk7Xaqhvk zkBkhDk0+eDvGKFG&Id(fh*TUr;WPRHfgD(shs$6%Ey1hBK412T5{YB4aVD7y<5M(;;HR* z{XLKO>|SrTdeI^!_Q%?yQ{znPQf$N+7><4a)cl%FPtrW&UPtkwCu8xltuA?;Rd#}_nfs$)I+FkR zOa^o3yy<<Ib8AE_o>7O4bBYzsy9dNL=@HlO$^<+wyXmZc` zb*JVyFHvGBcxLwg*!Q+*%i<+lCRJ;N`8>{kbn)za;gC`WhR4gFpMLtYEYg0p)xMyv ziH!T6mY+|Z61hC-=*q|JZA{`s! z;IKd-tc|Oa(x2N*-G~F5z28PGe`#$>5 zv$-$&i+r!U+qs?By^?V6nY*sU1c#r1B?y}d2cxmxpa#4h`L zb$=p`8$QhVeNj2roo~Lyp4#8v{@8E*x;XOXwFg_WI#l}SerIGjb^eFZgzfF$j$8X) z-!5xi^=L)H%YOl{7am*N`!irwb>eb_t$NCH!GV@&R%0jzPWt%wA7@yy2UDSsZm!iPOmcZxy}`@ z$l$P3s{ZUOQ{CgyF0U2W#O<|u@$j+GE#vJ*&l7*2S(}(uJm+1Mg|K7#9FXx0k6%aZ zEK1$+u2ob!>_a01Lr?q{509`VAB8(vFlEKZ+W&LHqoYl8EUZNt7F_AEU$^U4`k&c(a-hWFb>xTQRGIH*HcVYo zf9qDety=8gX=~SU`pJpePXy&qXVv4|d)UkKH?2BpdbKv~kHXsI8U_vi$NiGlW&fI3 z?NZX*j)iMmCLS|)@_r*WwU+G|JHxRbU0)8Dt~cEmb&}I~pIP9Mt7~<(Jl?2Zf68P3 zC!16A!$lXB#tNJKKRop-GlNJqs9at0&N=7ZJo&7e<4g2*?w%@p@q$I|mV#EnnH6>~jJYc>But#mvi}{*Y!^SSY_qMYioLW$E;x8uNkYY9GyQ|l>Rx;-u*@LB{RdZ^=C?A-fOPB-73C( z(W6hBYH!vp(p$K{>|W&5qGx8GSM~k+aQVY-Mur1FR8wm}QD$?Df7XrZ3=Ci{sQd)g zq6^ma>`y-4mkY}1X6kla3=JQ>kN;5jpJ#LRa`C3!yO*zCy?pWJ-Fp{r-Wz*kN8#hf zXV13ZtLg@K>lQ6vRJ1^1zxvwW@6MfD*Vngh+qQGU>Md<;ZQHJeP26|q0W%|m#D0~Y z{9SQv-=@8`j*8Zml9o1~HTg;zsFt=9W@z}>J>yj4bdQtwq;5%1l?nd-_IQ7}jB$p2 z)ta{_E(*8z=iJ}-w`+Z^t-b%NEe}~34*aOiu8}-(+xhpo$7_{-ZA(7xCu6G>u`A!U zq#`@{aq9H=gXv5R26ctf^_Q3Vx_K_&{Q1_Z(&n~3O0U9?{|LHz5Y#8>zV{<&nfU4M z*XsYWn|VI7-~H3o^HKfIeTC#dAMNut9Q(29%+spJv;Ur36+HLclKfj2N^GXyy;>A= z=(_XS+uCcFo!h>LJO0|#=Q}T*&Q51yNT|6x^ER)vS;xoJ2K$fdv)2Uuv;DqL_ul-1 z{N_Jfm*}5nnX}XMc1jfE&NT1SQ;K_UJ2JMJa6?*U?e(WuiYtwFUYW_jAQ7Mb z=hv@a9}M>?oMw@Z=k-|m#Z}a-GD`3DFU8fllT95p=B1W!>VETKVCY$I@L`g7eC^jz z&1>9`s+_++%awn9ef@OR&4&Bby;S>;ZEud;V$8^3uvwdRcm;GL}X6Mm; zilQe_kG)0T1>V1La0czsP|@t&s*8MZA~SBIx(*8F~xT^qZ| zPWf@TR%Fz%*iM(d>apJT!VCR-U>m_JQTJUR>vMjK8XU}ETrcbd@1%3#pIqhquI zRLzJiS7bhY?9~P}TM45Vl_$5(U}*SQY*3dc86l~89lw?cH5|4Vk$($Y1X`#dPscY+v0 zLe2D#pQklG<=GXxxbE|pHM=(#PWf0mQ)^mxt?}RUOSOLpEMaAkxUV)}GUArQq&Snh z8K)jg&R5W7&@g`d+?3f{cVP;+3@!+XrWIPjG2-f*kl>Vt<9vhEGhs-xwG4^v2srMu3AL@0k8P9vzVH zp+P%k*~jVn@%u_{Zc_E0w&%kk?$Xlkr9b}tS>(zsu2=JI=ksUh=9b@maPUnCLxYgv zz8C*es$L0J1)Z2`hOM)kr~F{a>eCrj`AWy~^YZHc|NWkRX2#JvRt62$$KHm=4fZXq zKK^5F(x1#{CdJ=!zG;KIz**muYSzEweJuSkY*P5WyT-|B?|VLaZf0WWxqtk`%3E@$ zfAqcE-E*a=*sAnZ$m40c@%ulms?nHXqRnvN$8yn~M($tUU8^nkKc63_FK1eD;IaL` z^q;${9?n@luWFZgkN+%DhJ-)+T=kBKJifha`oVoXZ;$i;->sX!r|kIC^t|fV`|C{J ztTH#x+3{`HL972_HM6EZ+qh4)wlJK5VQF^F&Ug1r>XwJ@p3YczcZ>V}&s#UUd>1SF zy|P|fKc3Y{Vw(QmWh@7q2m_kZNJJL~m1 z;{JBV_&cIt*L<5}+4u4Gt!ksykHrOJZgMiD=GSB{N-(+Vshs@h=y@BpOWR*t7X5x% zFTMZ6&*z{?gF@-}SsFg`4U=zuNnhqS``?wz!RhB`YTIx6Tk-v!ZS}WzH#fWg`~2L# zUT2ql$=gy1c~GAXG-x8vz~FWIM@j-C!<6oiCl4?&Xox?a+{nrhpm$82nVVrjOppA` z#;wKI*B!iGul?V@c9+oxqY5jAhD%2K%$QGK+IuG>`{w4IX&16r&*z_DCm8`M?AcA3 zz1e@aIloTKfN)v_g(b&|CN`U<0oF++w<}NkB99COaB}?e*oN; zy!^vx!Ud4`g{=0gXl!neUt0sQPt|y^hS|%X?G*X#W5A{!KVTLy*C~ zsg0>IRsWv|O#IjRtpD!B2&c1Cj^A9*z_2u-Mw>bN^|svnJs+PE!9 zG2hOp&WqC&?w+{uD(&&B^p}UOesEB|yzJ-9b@q#wKNjD{5YTmO`sXcGcjaSd=lot= z@PnTpG%Op_d~^GOlS^04iV2=;w9F?iGivU~ZWuJ?arT+q^EpZ4a)Pj0av6J{Fr zyubQ);q=LG<=21AN*_(OSe?0lqzwD;X=AYux+j2N1 z9%%3FlTE($SAT7Cv#EOOr9#ep|C-!Go%Wlwn!oOzy=>?HCXIs;fp>5Ix&2_u1|$DF ztPCfzL9IiXyWB+=_b&YHyk710|MdG8WuNW%*Lr*2&)q7Ri6N|o15exQSm7G35~&AbpB2f1ylLO{#QHzR=a0 z6vhPspvL5kUH+2sU6ym}zxKXXU$^^p*L)Vb9lUbDh%lW@@T;e!Mc9Q9NaV3qwPa1!&aRH0%4^`Ca#GA6LyZ zel~UD7SBa9<{z(*G64E5oW4p%3wYvf41$1f=L&D6`Su%lRmSa z12oR`qG$itu*aulF8>hwwj(a@f5qYN|G&Py`1xLSNc{2jA5=xE)?F>^e|ow3(U+Q; znJ2FY7kP?i#c;FtE?a!<{rXoeN9MMx$Fb%ezA&rG?H5Bp%CYHcT*pek&#m9so8SN1 z-S7AB$o=(S9y3edik5mOWo-6`$@ghhP4xpEudVGT=cPCn|J>!W*MHNq*mEBhwyYA~ zQTIJLHl1(F!H9>Q;rnt6x&j^V+cPk5UHcJzbI&G+Z4JpPq(`}d{%^!vvip7fW$ zzkT8-Rt5)7iTxj^JuCMyyI=I8oPV47{)_we|9eo)e_}_R%m16lw0{1+m~Fm!G6O@` zy&tfC&*V9*3;}k>)GfIg7UcB!7l|=A%#@h_M2DealVP3Qq|HnPbyuVoA9XtR#qV+T z@^BUghm(@_29~FynE-s(D3oM*Dp!6^vsg^e{!NeKYRGm?aRIft@&Tyq-dAhn+9*a zS~hFyE&uzL9v()Ewm+Teclp*99o5&Tq;D;~z2v|f-Ou-CS>>WXNBMh@ZcAYSqSXZ0xC-Kl_>(8a`Hg{*qKre+hEgtB11xpC6c(|Nr@CbC&R; zJ-$84$9^b=&V8^!tM;nvOvx#87nwOoSHrV)}|GY+gn1PUj6aw!aA9re7y%}FKxOfaE^^R;g6H?zNvGT zUatML-oNhOH-p#t$DZ5I)$(1sT}L>z#+O%p-p8+*kzS$d7F)EptP-xhWjS|gs=NmS z!((xYl}~i$zMDMX?qlU)gV*_e*B|db{(GhH@_$9X1rebOKFrO_d zF*BFj|CQRs1&X&^Klh?(mm)!}^Z8;gzgHDa+m>G2x_Y%L1H-ZR%rC#Y7EM!Ai3v8$ayJ<>YHN$pQ`$}db+tpYVL z_Y3rb(lWA}JkK#P^qh}|CH(2UAh#aV7xw^($D4t(fI;0%haxeCgg;5Db`B?0C zPU_W@G|5=0DXgo6cgf{G7Fs#~+qIC)=ci>)`Lmy~6L`7%%j&b%v)+EpX{){+b9-^D z+A-^dJu{E>&$$||UVKKi_r7a1zvubRs@27AwMq;<@e)VgugjU3Tr_QE^>L%Nqd}L- zO%#o5ZEqb@WeR!0lHdA5r*!(RTYnbcl>48yWRa3^Xii0JTd-+H`kVN<9q+CtuRm^@<+na%Md5ve z)UA8Hs;aM?4LElF-OqceO7|EeEdnR=X$9QhB5~~f-0v)pnUCq`JU%|X&hKQT-rq|1 z_5A8KrE=@{^}1hGRr+-KFDqBSRq*-O)><=?R{5DWPhPk#HqXoc!pU6!km}ve*1V7J zoX*(hzFl&rbo_6=h)rdSGE3I4^V&JFZtuG5FE(#}FY3C_+fUK^=dQFm){SXazTZ1S z8G7Pvj-6Mv%wCb{Tbj1(+`El?w)4FcsoC;Wwsc?I)^}HTc`1cS+Llg_P5dr9Kjy!W zxHFGsTfV={t-Zha3U5c%bgia7!*|I`vY%JY z<70R%UKXmp{E5z8iTM1Qa@oUwHO@+XnZ^^acDK!=I=8#I#SyDkA6^o^h@a_mj=#=h z>-5d9g*z7*?t3m<5caxr{*`@JU)$CHo6;B@DWo(bNQOqK`zeShGJ z%j9w|?db2XwjBE|vT}}lYGTcE#doopTKDgz85uD?7JqqlrlnfCq-lJ*OjhjHptbgQ zpU(;T67%$t$n@1)oa?T-+%wG%lTNGYU)jr88oTJ;wCSI|I^CUj;B`UCG5#}?1Mf3l z|8&z2SU-&s~?eCOEqa3LFkZ~K`U zk6qtmb)I*nRO>$Vf8ipJcg(Q6oGrs$dp_gdQyKmhuNaQ$TRnbmZmF%>bl{ZFdLAC{ z-%k?D*7pgoYWV2b`ee<$<+q}jEob6u_~<|VBRE$=+wcZ;f==MJbx|Xa4#R;TsmV2v zJ~k()X@5*Vj7y*S^wrw!D>aQIy~+)D|EgYR$93S8zT?LD#Ky?L$f!c4U0*gPWoI{6uTj?{>dg_uc=zqcTM(;ZKD~0$W&~eA3^=k6LY?ey^WB=bD(r@1>kqyNaiK z&gsxQYvh#?zQ*$6!}vgJRsP+J4}7owXLQ2A?pS~BpQh6XUa>wt&Rwk~^O*g39jn=6 zp1r62Q(VHA>Lt16u9mb>_q%+dWA3E>yMYgW+vZEANXS1XUx@fmOxJviK&SZ4c4Dy}+~C$a><;LqSe+_XGxa=Z&v@77{Rr`R~;I^{}z{rmcUhU-076X;Z5X|M0po^Vak$o%gvq?{MAKXWe(d zx#;E{%T&=>7kl2_oSJs)l(gu#TVL;f*~IOby(#$lA@S~wwtMeo&0gg<<>PN9=GB+x zm%dy3Pg-8&?U@5CtG()P1V_Y#gqU@hUGWrW72Wptm#9`__r|U3c6uAvbPHcx+AI26 z_VI7w9kWUf_D-ERF*@=0(h1*p?{5;H5d5sVtD$#I_+_b@{-F6DwXVAq%fu8jE_NTi zGw+^$MBy{D9=p>APF?-6?se0bME{-t=D*(?F3&pk;{TtF?Z+PMxO?XHk3ywgO-VTu6}td^`r83r*Bb$Z@xFgZ2Qs>Tg&y=jqPdQOQngX@6+cPv&?)yal+9@dHl!h z*M_Hmi)9PDu|2u^%fh*m6B0rnc6Xe5bbD`l^`C9L9ZgaK)xpjC_G{mdt>N$Q`pfmR zZ>gQi2AL@fKR#}+*G$(hjsLw!dHa{&OEtdjF8}<;GIiE+jyoR9#g^YUc$>|?erAe% zlUVXbi`&f~{k3anG>VoyGpkASXqs9+;dPAeyE&$x@|-=SrbxY7;^tU+U2N0J#{2Ci z8{^;UUgzQYS{Z$-JWl@N(s(uQ$Kgjf{|D*Gbgffwamma4?j881{QQfElbV-pTtB$o z+L^q|{bgKrh)txPV#dSnqj%(b>Z^M1PnV3?+xYB@Ncgt7dA}4IS0DJkyLj3rf3uYr zHa+uy{Vm~-ftMjO_v7j6tUK=i&X~OC=+#3%Du2GbE!QKT^+)K;fkQte_RE-M&RCrk z&cXc0>84x{Kf{6iJjARgWMKnz$mhxA|NJUu=JB?NlFl(OFfe$!`njxgN@xNAI*ca) literal 14527 zcmeAS@N?(olHy`uVBq!ia0y~yV3cBDU=rtGVqjo6vz%=m1A|4Ir;B4q#jUqie&IbgbA?J=s(4voeY&I592i+tZ*ho2irQ(TN8OHf1U8&Pn8);BZJN z#W1H&*i>y%qWXh|raqMh9ZmrbMNf6b+WOF|v9DJy-L3ud-IM6^$8Dy*diCnqI{$Mk zgP-5t|DTJSJNw3lLnCrmFGkn= zaCcPKd6oM9-rj4ai;A=RA1*5YWO(<-{!Om=-5dSb-XGUq-19${t-Z-FLPU?V+jXv7 z-H*iNxf$%;R<_@6B+J+Rc=+w@?d^GYf8DEo&&l=ovHbr9@tKc%B#mYG+E@A=`n~Wi z|0%IwS0BtZ5O01gA>Xz1va#{E=Uv{9B(&H2``@&GELr{ih>*hcFFluDeL11r&m&_| zaJ)}8YGT>DJ3k+F>tEsvD^Z$mmV3*jGY0 zudh=$h1D+DAK{y8F<gx7}`IIX4 zK2>J_vid>84!t)CuIjgP|NQv4#qYnHbjhQ073VwOzx-BM#qs)1T48TB*ZX;o6fWt# zYCbI|IXPpkccB7d-cr2>I7;WDH!}{dVf2ofEgZt(xY3OKD4#fM$zz^_k$Cr(E}YsY_)p zc&!@s^RWEC5Bp8HbCp8h#^(>zw@1}j@@+y6MWl!bjDO08hD!W}sV7B#2-(Vo(sQpD7 zWUR)b$jxbWan^?A1~1-Rv{tu{tA1-*ZB=a*9?Uk^cBbMuZLa9Qcz*}eRMk=N@< z;Z_$TEy~_RY>alDF0ZvXgt^2i{@vg2_m{uBGfg*oneS}17cSEizi8*qv8%PpT$wei zM!IXmCGn~Dt`aR9vNf8vx|)hC+^2M@L}Y67yLl74S9b1{=;Ux)JVS5hE0_BHN9!hj zaF6{_dS-^?{bc^`w~t>&Fr`o7 zcNRPpU$`+|<=?Hv?)+=L6HU!do=DI*#6GviV#K9Q&{!ZDH>{KcghM<6i=1q_iA0o4ZDTMqnSSw?s*kU&I38l0!^$o&1)!{b}Nt z;1;_bwfuN|q@;k%`gLy&GNYHD%w%XWDUrH-GH1D8^|$}JwfC)GR^P4Jm(Jz>Ysy`l z-FEXg)f~Pb>i_b?wQYL&IV=nK9NccM6y7;y;$~~*^l-Ox=X&JJQvQ61JjQ?9xbDWW zkAKCIuD{zJ>i^Qha_whnX~q@I7f$A^_N%^cSfKg%cSxJxg_a@UkX zgH(0z<$Yi57*;UfSU-86weD)t7p=e@m6IpI7)N;Mm7GJ&%vu*&DCsF3D*2 zkv&4`U;TeyDlHE%H2XwZdbwMQ zYQClKg;R~n$7lBi*ev}Uo%vQxW%ta<)!X*`(mQ{1@5{H>p6v{Op;#AN)vY*lBt z;-y_u#B%*_&t>8_{(n}ZPp$6$T-?sFUnu)?*Xh;g-}s7$b@iuR zJf>LPo$+^mcI5Bw=#=04%eU;>u_xoJ%y~P8D-vo}oNkdNC)ZA{*jw_)!qk1qg(d%g z)|Fo?Z3=5EwK2$iasBe7q9e<aQ>*^(Rge8KHQ9IGhSXaVv!Z?` z@$N4yd$<4es`oM{liujtObI{o|4eOUS;W_Q3|AQ5-rH2F(e%vLBbom=e;|8)!RK0) zOD!+nbTV%)PmNt1e?8yk%e7THJN?!kR~N3o8(gw`&94KqQXYo)nO1IjdffJ9y?v0b zt%>#b2K@@!rolV{C@kA#l4R*f$Bw> zj}&6(&a1GUnH=`+<)v4PxOeJv?iX79xyx&{|MKPD+UwQ#Pl&1)WYixfW{i0M?9e3$r)_LLXurprM;{YlNg^^>3Pv#IM75o%LvE3^6V^yB>f7DX|3A{W1%-7;;xDsuq)g2^}i=9U#% zebkfnIc2d!@$v4jDOaqO_xawN zXUod${&x2M^xA~{XMTNen0J3WcYnsJ3oE}$-t6Y&S@)1E1A{&19>3Y<`F@_hOZ7|c?D}8Nk{QMa+cBH+% zC8`}}cXKhjoeIO;HBNeWzw3m$OqKq%?)&ES^Lnw{WZW2Eq=;rs_gK<(>Qq;kSGsHK z<;cKu&Q_u#B6BQ@(@suW`eP15$tISsA1&sxOjnsZXUS!!x}POCjcWWDtRkD%P4`e= z>MeRGDD2&uHEW_it;~EaB09bD-rkgB?nTi_!5OxuVO!HvY~D_nG;gRBsOq}s{OdQ* z0_9nD+z!icH64>%#WL4M&r)0K{hgIM`(u4xFS)!()w`$fz}ySZgOirTKTf*y+*bFL z@Z9n<4)>^a*OMlectnGFXM|8-d+2TyngazLHE*Ct6D;*v%5TfCo5fE`0vl}@2j7m zjZauI`FB$1-|KVz{Ju-Rxp(;hd!p;TJ15KfJfHfP|6N|}8?UpwGSL1=P7}*#*Z&u- z9M$JX?5*N8byN}JwF!7#@-*w`=Vt$jez%i^{mWj5mA$;wwj?D!TK%MXfB31*cZ_Qk zUro{6Ce*deGe_e~>7(*#Uv*QfSIJ*`dGX`>_C%uwziXZmTf3r`7{#eaMQ+iUAJf%! z?r%-hsZPJSpVH3RRK1yzf8B4MT|`<;&y9|g=j#qSFBE?9uC~ywQc^{RSD&O@dYLj^@291uKELFmYL=ss zDWgoHG8_eVCpuRqGTaD#QmvCSE zx!RJF-)}x%VvTjlF^Wgc*`)f)?>~tCC`YfV9#1Dh%hJQ2+F~!$#>n zQ=#Jf4-XH|4hs5^$@qeWp@fOSL7icNFvEqDdGlUftv)x$@^Bk}{>@jMH8u=ZKV2`U zon5qOk!FjubzVr${0(7!Vm~G@lzf`2)^B_7(#51pPfm6(=XrnA?$GJw)z-G`mn$9S zUVFK7-P-LwmD}={KYQ;t*DCwknz+4H&gud0OQcMzzO1^sI`o3udOo9FpASnKFS@L5 zQMHw?*g__DcNs5tHq%^(+MKx|Zk2C?rrW3Qk>6SDbNRWI$>Mlv)2u%M&1`AsgHmI! zIx73}gyq*8ww&fU&m_=sZeGTeaJ|;;9P+pKp8U7+@1;1-*O#}=e5&qtH1$=ghK21C zjdeNOEVAn(^SsP$xE&PM&Gk@OA5+xQ-v9Pu$@S=3vweSF?C|5S{20Z?Y5&yuoyod$ z|85EBY1?o+T;O*t(EFORuhi-Mk%Rp`FRvKb*zCDh8q`)$8SyZZp($?pLw~m%soS}! zA&)Q0O1o4%om4*8*6`H1d+}n2ruH~VvpV@Kk9(_}_ASd`mGj|_g8T1ocyUJlUC8nC z#@u`V<_WA*3+HywxLcm}JmZ>?%w~B|lyq2KWSYy+;0KMH1%0olEQz_cKK}mpeEXVp z3|2o^Onw#qYudAYe}6q*%zEKu_OU+c<(FR0OrPHz$Y6Ez!okV;CRQE{%j`1t-H!>* zWmv9U!gYynUY7jb&du+-q_-{>_9}N;E_JM(XMLD@F8g^8^^H=#YnkRQ2v+DZI_s5L zda3L~Pf3zUUXojR=-25>`Xog++Ud_;w60>>t~u)(jn_E&zgn&=#WVMh!6~nI0sf*t z%be#fxg3(#XSQqg^2sX}Ioi1BEI+-k?9!80rt39qWG^PXc(OTA%y>`P3l&q=TM>$j zC#=i!UX;@$@w8-b=G-m*?j{meS3d=`ytm?98T~ynd%9nhbE{Zs5?HH<#M~EVQz|r< z+KUM4ul}rg?MaGz`O^2viC-9I&b8fp?8vFDliytyrI_u z8SqrfL0wozQ1_*gXU3Erd~)xDZrhrron^tVu@#EfH>y`&WC)X}IY-#DgC9m0-*+E@+E}xvuiLYPgoO@S$ zdH2_w&T*O1>aX57sx!tJZq9)QY_G?-pLmd^9B|YwofAGj+H4ZSl|E z=J&_ts>FAZ&{-d(Ud~*rb?)ml--zB+pQ2v>(6{={p&PG%j+*y(rZi&-*M$IA$O-gbQWDf7^h_a3V{CvSSWJVE5`Vq=km{&M2`QkuRWt92@VU1eF8E1Ui7-8(@!=cG-^bm$EIwCcr?YgaP;k$gUIr^xkL6#!l&s_2Rrz|| zq(@Cog{|Kf*4AG1{Ik#S*!1lZ&!6xH@12wbRr&Vz_WQbf9M4Him^SU%V!uZPPH95jxxtU|Qs(PxYmey(MsLgEY$`wfN6EWpw`vKO+FXrw*{d$M z@k%ccZt#0%r5n4egflx*EjmN~1q-Mo38z_?fYkZFxGZoZMSCCo?gGSu-GqQp~>MFO-?%PUNJvBXFUplv9{*?L$rKd0cS~oec z=C1eL0DEz(mj-`McK9amUfYvpvn#ooV|~o0b(_^=(+s{pU%Vx7mGG3W>hmijE~hNq zmi>IS--`L%b9r7|wM$A{&$iggq=)1C+df_8&)GKmB_<{^?tg#f+{HDi7HRejFG7w_*G}Gs7USL5JUf21 zMtkfudbD@f<?@UOcsRS=Zt|4rd{Vi5nP#|ksnZ-WtJWsJ5^1kJ zQ$7`G95Q*jO8WiOeVbb^GMlWaK3%6cXZi)r6H&{>)C83?P5QINmIz&J(+p4B6Mje6 z)U@?)@7h&=^dD`xu+r}(3q#4JnWBpEA3B*3t&qw4bMEc2R5dNVyv$eHJkQ6=>)wXM z!@It|78Vx1z9x2e&Cf3N>MsX485c|rJ+bunyro?$iZ-X7p0+vteBG`R$sVQ)C$+BV zP4p0*I#pD3>bWki<(n7HX)n>z(6A_ec4m_5{6}*bE}Rs)a{O_LP|T!~qDg+-Kc8Ms zJze0(@FL}7Td2{?B_*AgSMIqJ3GFt#44NYh>P~?B11i(CSf;bg71NDuDrRy}_r72u z$7?geyYDV5)7ZPlF9%L2mp6Af6wr`=IM%L?BpQIlLpMNcK`)p6Y zyPdohD+9Oz&*Q)Qjz(Ja?|*(&oO-nEuKq#xr3-{hR+WaWj|&bBbrtvKjf?#K|JQNb8|8VQ z#jn}?es-}?{{N}hAwN&<`RV39VU~Jx%I-SZzWb? z>w;k2i5s#)Q$t02t!!?5UuSorm!o-N{+*F-_x3*hqAui)`urDmv4WCc z;?%!yP71!GwDg$9lnY&oY{CnLOSrsVoIY$Z_tdHXKfd(Xf35q!aQQOR7a#MQ)&E~h zIxwkvkDvVUqtd3nJ$W+a#y8^t8-!Ll2^8~MDDq!^INgbda50EiB;(9 z>y#-IJ(!kUzSIBs%lvmgf2})nMda}{%^3CV+LbF}(rXsacv;@>Y3tA9>ahI4hMb>8 zp38$gRRWh=%GZiqD1Q;W-S_$K7>1Hnkr{k~=869EBa5H4&GGwVzHi04gA66BDl_;5 z&sHy}-da-MdF)80O#d;t7ge3VDz4~F^fpdE&nY-}iGJTv@okXyG=mkVLNE7%$+?*1 zkLkz0R%XQ{Jin6YCSS5j@{jjpCv}FoDL(N>3Iq&)kliB5wu_<*6C(Hhrek|23b!%@!oMB94qG{QlLptYI&%g4)Xm$4){gO@0 z|1a%0vto_fqSG_(pS3kK4*sb=U+|wXufi-*zO7PvF3-fRZZ^he#-xRWNncETedM>w zH@0REb&%2Pe@q1#Eh!kg_uRbZ`{t)MY)+r^+;r{X>^WCmLHfGtq54WQx*lrjt-kZi zaMKpCPkYo#D|$EYI`PLzJ(}~FNgl(dEg-fv$03tE1sHplNnXNcusFEOu`;j8M6bbb zTO%fUYX^hXO}B=u$4Q?wN>+8VtT59nY4R%-w9kH=m9*_s=c-MWH@kdRo5+SuJv`Ok zmFwXtUY7(hD^}xwOAAXUiyu0Z?J4KBY^rT!bWPW%4SXzV3xhcxgiD26FOB+E$~W)W zah-?hpG3<33p7T)5b3!QB7I$9bAqdS^Kt`oB?IocO+ug$JU6fIyT5sT-bYQ2GfvAN z9NTZQ&RKYKXxY6I>*{&>{K5RLGrsT(&S>>>^u2KX*w_3V*~Z8hA+uR(b7S_GI36gt1Q)ibt=m(bFs`Ri2R{vChKetFJHSibEC()Z>!b5JPKN- z>Tpx~rmcfY&BDq1Z_GLN)m1%pV$5Rhg;G~JIpbeEF*luXEVb<0lAvvAu0?wtPz1$0e8&-6K zR4};+EH4zC+UmE^4bHf*w6OG7W5+3{|Ul6=PnA zZ2B?%*wxietIs~16{?*qCkzsc`Z4v`RqoH3&CM&qx#zxOu3K7|9i!e-urS!;VZ79J z73tNd9_}*#q{ww;b*o>g!2e4-tZqi6@m&|5VLN|TR#cKK$dE}a@lxU-#wK(IxaH}f ze%nDx94onDx7oUH@3hpk9n_Z;)~@N5UJxnBV8zN@cKukZ-vYVUDalgPm#ucIdbV#< zmucqXEw?(?2JMt8j|iCMdwSLBwhMYCTv|E4kE_llxF%e)@XMBI3i6S=ekIa5L)?m0 z^4s#ln|TrD?XkcA+H78D?X>%X=86sWz1f@ns*0lpZ?*azbmv`Cxb}65>Z0tBYVn1! zFGOOlct~Ae<#(oI-Qm5ywjzo-jv$i^9b=@ovmLt((qrl+aQ)cUc=eXDg~4Zqj%+P_ zdx>*lETq|RC4TONW2_fWnqiVzX1%L-)OWq)xUh0v@axPNAE#Eo(&)`4OX^JP)t20+eTq@sbDd=WU*0k6P4m~4PrDu~fCS|BU)u2|WnR7&SXzGnr5&b= zgcohSpqcW~x_9;4D#`SmKz?zntFeE)AHQOWGmEQO&F(JEv7EleG&eQw zr_3JL25~D^`G3m_BYPXZ=%L5m?|E_F7A6;71mVfcexg%zO!v)n0FYqcI4Jka6*5GHeI&A&7 z%PXGm+IG+A>CJs}XYIExeYGZXbJf>ZvE`+cd|$18yPd_!MZLa9>h8~nJ(3q+3d`(` zYPXc>TNk^#t<`kpWviK2f|)OzbYJXN{^~d#E)+reaFYMDgA+)CIxAy9JnnBxl-8D{~bjaATZ@*a4{uU*b>|0in zV)`OX`_l>Zf^Tl-QEXZr@A3oj((DJZI`D&G?I1p8oBTq5hla-fWEj z`<=}|c85qjP9PhSL#Bi;1AQf`~~;!AA5`1En2I^aC%SQ^!cZ%et!=CdF4|^@b)v- zu5WIv*=v=_w13%q-h?n0Yxm959xk-_&8U2fAvmEn>sLf>6aV)eJbi2nf@`Pqt`&xi zx-6J1cyu}2y_3EBij97m6)Np|Q6X}CRbb7z>$;}Wb+5ByuV3G>Zf#Ml_l`mfq4~lMe%DH@By%53dVQ-)x*gOpzqaG-%O$TT zy?(XH2~<*t&h>Ly9lPuM;?qBOpRSzw_+Gzx-@Yf$|0?C#^=*#~KV#3ZaD_0h&5GNq z&)+lKp1yNa{?6V{uFKEOeY;yZ#Zmp|oy&|L3k~b`DK+@n`PPXZ_PZABzsGNn_fn_D zN49#aT$-vK{^EI$r2M%*39r7rogZn~W#qV~v-sZp?|*7;c-&^$W-(p-tU`&A$*EIs zill_gw|j4Ld%1La+^&+BLTfLa=eMt@e|2SL^!8lix3f@z??%JvH{xN6orRw*4&1-*sY25Vm!^6YB zWR2fOuGmp_spUrLrggJkv@cnq!}hw*PjbqsRGFJ5>sEg+XT0(|TV3d6)vM0So)X6= zfBm>3@K;0px)0rreuqwGKD_O%lM-7R^YzAy%=9Ib&ac|mI(1cn{7sXC3ol8?+P`=r zZ1Vn~t(x9t&lsQ5OO~v;XQH@q`Kh-jn>K3A<#{&m^;+)#Ts`Ry>h&d7 zGMabdi!Aj!|8$KO?Q}MC-%4@d!>9b5+ zF!}xk8KrYeS9{O2ni+2$DVx4|LTPGT)yZw2!>u+}nJ>E|eZ^VuUfDN>l27i-ohQ!m z4xesNT6E9usn+?$^JfPIG5xbYZOhU4nT=(wU+Ww{@0f70-E+j*v&7ObYF>Z3Gko(e z)_?WW9$EJ=aQMwF`WN(p+5P3z^D9Mz0!mgr`IJ}m@=jwq^RNA!%`6HoB}|}R{Hrd% z6Capfq)3Cw`4Emcm}8QC&3f(@$+(%`CGj(k-T(NqscO~a?Ws8uP@%k(t7oFWCPoRQ z2{|s0x_(l7@e&^W)2g$Q8Rt6GUO%}jFsN<%(@C#S9cp_2J9@?o1#S)_u9u&rjx5(Y zeLc$Ku9Q8i!}5g7o~J%+idnT!rv7ijf4;XpF_&00wzQU{W)_!Cjh=gD?Zse*60Uvc z=1qBcb;pxkn-;vdaY4F$-v8&j;&x4r4E<=A_SAoU)=WuO!v(@6T<;cgXdYf&c=GFS zo2*%@KBZqiKkNEQuUBGLj>{j&X-qfTBQ-r{e|^#0-F1ij2#cCeZ z7XEnB>!Leb-_#xQKYY<_??R5rH`eg4j6Mpo-)im=p7qC6uRrZyUu0Ei|B;dTMM@vY zMJh|mn^g~UF9_y%@#N%(OMg|RiWFXWbyk&MQJUx)zUdd6W1F}GtO>?})c9I14Cb(c zNwbqD_L=CVF*H`$vtHY0qF2K7)owvzyp*_Aqt&Y5w@V9cgTsvZzA z0}eZvOpect(VlC2P^sjbgYAyq*ZETBZhzkCJqu{5S>r$XHtT|QFIzzE_A+qa zrL8sRTvw6YrIia7JUBDc*n67J(dFC=CabRKKmJl>hsw(*Ds#m?onC%=+QZAN7fuS5 z>~*oyjD1w1rC&a6sS;BvLSJ9m`+vg0y|=I3`Nv?zYH0E;K=p;n&Je{NDlfKV zoD>2TkE$6m{cLg~dX{(frcRwc*^gUXx6O~iDzfR=5zpmCzUKWgTDp%*qBayvd?C$QDWW2;*-T`tD~g-_`h48o%{5V+upxB-@co> z+wD`3;q8qJo!M;fh7~&GE%woUtIhNxq(;j z#;u(*cgN;w`C?nFH0592ns0xx^qag&c~5@glv9SgTHi6Rl6F3;{pd=I-&W5WmTUl(i-bb&OSC16GKCx)^((74q%NI7Y@rG^n$gSp2EB|)OYpqgAlb_@9 zQ!Olh%QqD@l?aJs?RcB`%kuS;H@~lbUq3bO`qh)&=jIhGdi~Bneg7&~rNuvVyO?)< zpU9_C-t)7I!Ro5g>F_m6KC(%bYFvGha?h%Bx`~>z;HT3Pd;k6vHgb#c-^^nK3T3W(MKm( zm2g#oM=ScBC`KWD$3oOHjzkHKoDLvcsOJ?6Wsm;UxP zQJXj4|H*T~FY$H%TKDX^uNPDC_^f&JgSAfTka24V_4ST8dJijJXU6cXcU~T~WZm+@ zg~BDPTwhg5ftsgLM@)KWPn|k<>QvM0Z#i?7uS7|OTRm8C&;RuEqg{frx8gm@Ry^8u zfz#@$&?=L>nI1Evm+#rL$F1<>{o3zy>lt~gFYP#Fx5wCsv$aFdUi5BlL0;_a2MiZh zhP5f>O`G!UzE+u5)7yCk)&E>CX@1Czxuut}*faOUC%;>zFIeVgO%zu5tNC(v<23JW zWlp)3jr)eit-Tgd^-rBh` zTW1_Ajh8iSQvwyD^A>Uht?2o0XE4=6ZtjkS9eaO&W4(O4P33~7hT!ELCa)ZBg=C9) z2~6^4X1C>^%TQwE==1p56PZP)mrUNdvv7XRr^1*&clsYctNC(qjb(BAxp~4h`O;R7 z&{8mx3DnWW(jlJ5)NP_CeWkO>FYchvuYg~A1@0e{=CzK70FVu5K^$y#Kpy$0x;C=kDqAQ=D?_>)I`P z*=beRJ^pF3{Vxm9FI6huXJ7g1;g8-cN*8~{{(C<6QPQQCzs?F}EvP%IUz7D$ zYmn6S?U#0as_$F=QSg?0bG>!ViuqQ7m%kXu7Yn&Qs=KH8%(~ju{{Qn^*V+Ax*Is^Y zx+?fB#FhV^&-iouq4VD>ozoWYjCt+C#Tm1=@b$O1)+Qn!FRu^x|6h}N%l-AXH@~v} zRQ$KDX7qpjD=cdI*OJfm)+?qfS6i3Avnl=c+HRE4v zcdIV_Wo7B4-upT_GxpnwuI0L+f1`KUb4hfqxX%3a)2$s#m!^KNaNGa$AV&Y~{KMKKdJH`#;NwS?xzWG&0Px2EFb(#tcImroNH2@4Iqn8SH^S*PVv zUkll%!uLFE61#t!l%5w0^-&K!TC|lh;%(%*IgY3Kju}1P`>FPqNAcmEk*>{bO5xmd zYn(%+r_Wl3ynLlb>$#_Ke@{u0f9B*Q@t`M-w=W-H_tlv$*l@Lem(}6bbK2KQzn^+u zMm^aTdDY6H>kWbU7OlAb3gt@ju*yu{*~PG?(eD+{daH16_-mS7G z%2jt#z}mTCV!Ef)r!QJmY(IZm(W2nxduAH<%UM6Wy>;?({$uqIJ53%f=i1IS*MVJm zTDIo9RX3DQe^~WBg&9C-N{?jda#LdmP$UtM$ ze}$_j-*!H2%VyrN=_B*@Oe6cL_iw4PCVzdrcV6w1g&gYyKY#Hv6k(jZ$IavMrO?a% z&%NA^)qeYNa2bD!ox_(iFU{;9{&cS0HUGt(pI4s0RF0QzJul&)F5F`B?(eHtFC(?( z&r}5zcs_af=GgkT@*8q1&#b$<`=ccDi2p^I$p;bRt!x=>6{-8BW;)KamS7mUX(B90(6|Os<)F z$M&v~lD771H^+n9@7Hzvi#wSDe1S>8kLL9>x-*LxLA4=}m5N>wNv-qu$iJd!ysd z1iHn?)croUchPP4e!1Ms+veKpcm2^>ao8$QSjEii+-}vBz|6vrd#%ek4lbP(?b=>k zG%w>W+kC?YKQ${^n~DjqUs}$+`+HgW>&@+ZE^YI>aWEL+>H6xa_0JYUzS>)$Nv4D?8;m5Q~w1_UzaGl{b~-&1x*KM z!I?8>E)h2M-B@p}5o6~&Szrtn;`g}cY5ke#*$UFN>SSuRn04DbeZ5W$NSH&uD#XYFU{Nc z;)vhfU+aZe?^v5>BH^(7)+J3_+qv0IdG~g$Ub16BK+MA0l1I&HRxg+5oz2SMWL>@H z(Y9NV*?F`%cej<%$#Z4SXze=lXxl7^inY<(rFOeq_&$~W;O^AAdggss7_C?*`+0hL zF0;BQuJ5c4TEh?p>Mmc~wojPTkncl%#N$&k2;o;9^tgfu9 zWq-l)YNcPCa(u}jWl zPCIt|^t`DvCwa{dPL^P2zp%2b^wPCszEM98a_34<@@Cp%_x}Ckm4cUxHI41MuHGuB z+HpS9k2!Jiy?=MgzMnH(xhLdI*_plmD$A#S(VEAc#m~1O_-)y@CtC|Svu6FfwJ$I% z>$&s%Qq}1%)YtC6vhShev+df&^El2nxv4*Oe!`L7bnf5GBHkZr9f_>D=X?57Jhbz9 zLcz{xS9-FwkaaFgx69lX(N&(o$yOijG^17a{S7R;0cz{~Yb@Gmrst??%Q|<fAhwNsZ^^O1Mmta_-s`o#$ov_*A>05udUp&=G5x!}>pooS$5?*gi^&9{GCZ*x&Q@ zb;{FsmDUScF>V1@jSGSq?mK>5*;rn*`2C!oeZF%#^sMBL7V5mZc9HSOS!L!rk7_p1 z@X<7d=`pRE>kj#@JCqXcIB9jl-qi_nU;m1_{?&9{_Uf4HLU}TMN1n4Rm~1-N&rN#A zlU>^$9a9ALoJ{kItzPbWvTN5G0V~EADWS`SFS6TGd=HJ!PI{)B7c9!&dq-}{TYjAaWUJG<3~G; z_l2e}F_?Z_Z|)vjyOJiqIKO1kWbbRAz4!QeP0xE56{kd}Y=SlH(^_33} zG)`RKcPV>%#OFJAe%c(p5~Me2%B-aMesOa0R*vfbdo~&Q&pCF)R&Q!rONE2j84?HRA1(qVH~*RyxKP5=&~z zR)wq2d~N8ie^9ZWzvJDt<)D>!N6)a{jd>KaYwP*YZ?CUfAO9hi`MBYz|M%Jdul&C6 zGqXD7R)_4xK+n6Slf8pxojAx7;E~Cl=l?do_Nt^#{yUM)hrTjNSshPbR^@wGDr&CD zdq?wc+^=4274A&2-GAhzORdfG_p8J-&Hi3BtIz&;=-EB}{OYtDeRb2C8%}+`^mz93 zJ?T%>o-E&LmY}WMHTlMyA614fk2MySE&gWv;%FUXn-a&Y?+0S_E%hhctP<Dg=JDp>y=TtN`}8|nVy^AC>JLZi3Wc22B~98pcJF_(N9C2uHjj(k^W%O!X5WAJ zgpT%^y3#8dk2e;btyQnAiuuF5-sfV`@8!!Fr+ypFMC((96rlBicjaWY#UxjL#ZboKgCD8}nIMYQI%)}0#D-S&1`40F$D zJ}HTMv}@zscQ@oLcXvlENli}+>VBeS>s2atK~r|bzV&QJiST2V&DJM zYcIc_CR!6)_ILH{<@Xkfb?WSzbai^&JnIiSAcdecP7S{n3mffWu)4_xCYM7vVpcAo zp`7N(&G%lWIJaF-G{`<_Tz)X8ZQ}JSJ`+4=X|XPt{GBzk#CXph&~RB^%FkCqo42tR zFUm?Nbvhzo_44(TsewH_>(8iOpL+CK=^}}VcjQY;)pA{XcCDOT^GtDtuvMhF*R+SJ zpi!<34}Sj>`(1i!#hO=Bgp9X+>fG?BQbze%*4CdICmkXgV`|xTLLY}7ZI8_NG-o|y zFExMFn}b=wd*8gD%vc()UfvddeCeyxAFuO&dw=0vq7i3o=_`Xxdy}e{X3ez;KDV=Y zPT+-;!G^xoUyt@MN3T4#+O{b!pldEu+5hCD=4+doio)#XgPD|tC*OO)LdS^2cRyk{?dxo>bfV&PS%y)pXZ1Sv)K%d>-k2U6ntk2L~QNO+L zu4LRa?{%jOuW$OzY5#Z6dzJi^cV=JRYw`ESnst89uYTXE6Z-h-vG&q?LXR`nnD>O} zmrN=VG6K14y8XUWFOU2^!p^f`vgJF_sHNiGZXW#xziFkDjQ0G^Jkhv7TlLl5!0r~1 zAgDhAo<(JZOap-y!$C$*p-nm#kZi=G|I8~_CCePtEqTbmz`)??>gTe~DWM4f!N^e# diff --git a/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc b/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc index 66ae154d58c..16dd3cee47f 100644 --- a/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc +++ b/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc @@ -135,6 +135,9 @@ case-sensitivity. Select \uicontrol {Show Non-matching Lines} to hide the lines that match the filter. + Press \key {Ctrl+F} to \l{Finding and Replacing}{search} for a string from + the output. + To increase or decrease the output text size, select \inlineimage plus.png (\uicontrol {Zoom In}) or \inlineimage minus.png (\uicontrol {Zoom Out}), or press \key Ctrl++ or \key Ctrl+-. @@ -197,5 +200,5 @@ \image qtcreator-cmake-clean-steps.png The build errors and warnings are parsed and displayed in the - \uicontrol Issues output pane. + \l Issues output pane. */ diff --git a/doc/qtcreator/src/cmake/creator-projects-cmake.qdoc b/doc/qtcreator/src/cmake/creator-projects-cmake.qdoc index da691f6f03a..80f0e326ea8 100644 --- a/doc/qtcreator/src/cmake/creator-projects-cmake.qdoc +++ b/doc/qtcreator/src/cmake/creator-projects-cmake.qdoc @@ -57,18 +57,19 @@ a \c CMakeLists.txt configuration file in a project. Project information is also automatically refreshed when you build the project. - The \uicontrol {File System} section in the sidebar \uicontrol Projects view - displays information from the file system. \QC cannot determine whether the - files are part of the project. For example, header files that \QC finds in - the project directories but that are not mentioned in the CMakeLists.txt - files are listed here. + \image qtcreator-projects-view-edit.png "CMake project in Projects view" - \image qtcreator-projects-view-cmake.png "File System section in Projects view" + If \QC cannot load the CMake project, the \l Projects view shows a + \uicontrol {} project node to avoid scanning the file + system and load the project faster. The node shows the same files + as the \l {File System} view. Select \uicontrol Build > + \uicontrol {Clear CMake Configuration}, and then select \uicontrol Build + > \uicontrol {Run CMake} to reconfigure the project. \section1 Adding CMake Tools \QC requires CMake's \l{https://cmake.org/cmake/help/latest/manual/cmake-file-api.7.html} - {file-based API}. Please make sure to use CMake version 3.14, or later. + {file-based API}, and therefore you'll need CMake version 3.14, or later. To view and specify settings for CMake: @@ -144,6 +145,8 @@ \endlist + Warnings and errors are displayed in the \l {Issues} output pane. + \section1 Adding External Libraries to CMake Projects Through external libraries, \QC can support code completion and syntax From 32e1d2f2d0ae2cd835307e96d35cd1ea68a893ee Mon Sep 17 00:00:00 2001 From: Johanna Vanhatapio Date: Mon, 1 Nov 2021 13:53:45 +0200 Subject: [PATCH 24/57] Doc: Describe dragging external assets Fixes: QDS-5244 Change-Id: Ib8ba9c9a7142f650e7dabac411641061129dbc70 Reviewed-by: Mahmoud Badri Reviewed-by: Leena Miettinen --- .../src/qtdesignstudio-importing-2d.qdoc | 25 ++++++++++++- .../qtdesignstudio-3d-importing.qdoc | 35 +++++++++++++++---- .../src/views/qtquick-library.qdoc | 10 ++++-- 3 files changed, 59 insertions(+), 11 deletions(-) diff --git a/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc index 176bcc03319..6214adf509a 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc @@ -30,6 +30,28 @@ \title Importing 2D Assets + You can import 2D assets, such as images, fonts, and sound files, to \QDS to + use them in your projects. + + To import an asset, drag-and-drop the external file containing the asset from, + for example, File Explorer on Windows, to \uicontrol {Form Editor}, + \uicontrol Navigator, or \uicontrol {Text Editor}. Alternatively, select + \l Library > \uicontrol Assets > \inlineimage plus.png + and follow the instructions in the \uicontrol {Asset Import} dialog. You can + also multiselect several external asset files to drag-and-drop them to + \QDS simultaneously. + + The imported images will appear in \uicontrol Library > \uicontrol Assets. + If you initiate the import by dragging the assets to \uicontrol {Form Editor}, + they are also added to your projects as image components, and you can view + them in \uicontrol {Form Editor} and \uicontrol Navigator. If you drag an + external font file to \uicontrol {Form Editor}, it will be added to your + project as a text component. Other imported assets, such as sound files, + will only appear in \uicontrol Library > \uicontrol Assets, and you can then + drag-and-drop them to a suitable view. + + \section1 Importing Designs From Other Design Tools + \image studio-imported-assets.png "UI imported into Qt Design Studio" \QB enables you to export assets and then import them to a \QDS project @@ -45,7 +67,7 @@ information about the options you have, see \l {Creating Projects}. - To import designs to \QDS projects: + To import assets exported in \QB to \QDS projects: \list 1 \li Select \uicontrol File > \uicontrol {New File or Project} > @@ -107,4 +129,5 @@ design tool and export the assets again. \include qtbridge-tutorial-links.qdocinc qtsketchbridge tutorials + */ diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc index 624d7f5ecb9..ae12772cf4d 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc @@ -43,17 +43,27 @@ For more information about exporting 3D graphics, see \l{Exporting 3D Assets}. - During the import, you can optimize the files for \QDS. You can remove - components from meshes to reduce the cache size, find and fix issues in - the files, optimize graphs and meshes, and so on. The available options - depend on whether you are importing files that you created with Qt 3D Studio - or with other 3D graphics tools. See the tooltips in the options dialog - for more information about a particular option. - \image studio-import-3d.png To import 3D assets to \QDS projects: + \list 1 + \li Drag-and-drop an external file containing the 3D asset from, + for example, File Explorer (on Windows), to \uicontrol {3D Editor}. + \li In the \uicontrol {3D Scene Options} tab, select options for + importing the file. + \li Select \uicontrol Import to import the 3D graphics file. + \li When the import is done, select \uicontrol Close. + \endlist + + The 3D asset you dragged-and-dropped to \uicontrol {3D Editor} has now + been added to your scene, and you can see it in the \uicontrol {3D Editor} + view and in \uicontrol Navigator. It is also available in + \uicontrol Library > \uicontrol Components > \uicontrol {My 3D Components}. + + Alternatively, you can initiate the import dialog from the + \uicontrol Library view: + \list 1 \li In the \l{Design Views}{Design mode}, select \l Library > \uicontrol Assets > \inlineimage plus.png @@ -67,6 +77,17 @@ \li When the import is done, select \uicontrol Close. \endlist + The 3D asset now appears in \uicontrol Library > \uicontrol Components > + \uicontrol {My 3D Components}. You can add it to the scene by + drag-and-dropping it to \uicontrol {3D Editor}. + + During the import, you can optimize the files for \QDS. You can remove + components from meshes to reduce the cache size, find and fix issues in + the files, optimize graphs and meshes, and so on. The available options + depend on whether you are importing files that you created with Qt 3D Studio + or with other 3D graphics tools. See the tooltips in the options dialog + for more information about a particular option. + The 3D asset you added to the project now appears in \uicontrol Library > \uicontrol Components > \uicontrol {My 3D Components}. You can add it to your UI by dragging-and-dropping it to \l {3D Editor}. diff --git a/doc/qtdesignstudio/src/views/qtquick-library.qdoc b/doc/qtdesignstudio/src/views/qtquick-library.qdoc index b1d03a72e67..adf66688b16 100644 --- a/doc/qtdesignstudio/src/views/qtquick-library.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-library.qdoc @@ -119,9 +119,13 @@ \section1 Assets \uicontrol Library > \uicontrol {Assets} displays the images and other files - that you add to the project folder by selecting \inlineimage plus.png - . To add assets to your UI, drag-and-drop them to \l Navigator or - \l {Form Editor}. + that you add to the project folder by dragging-and-dropping external asset + files to \QDS or by selecting \inlineimage plus.png + . For more information about importing assets to \QDS, see + \l {Importing 2D Assets} and \l {Importing 3D Assets}. + + To add assets to your UI, drag-and-drop them from \uicontrol Library > + \uicontrol Assets to \l Navigator, \l {Form Editor}, or \l {3D Editor}. To add multiple assets to your UI simultaneously, multiselect them first by holding \key Ctrl and clicking the asset files you wish to select. From 73f10666bc72e606e6bb0a5981b8be15f9fb2174 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 8 Nov 2021 16:31:59 +0100 Subject: [PATCH 25/57] Utils: Fix compile on macOS 10.13 Change-Id: I63b44dbc17211dab7d7115959a046437a0430c77 Reviewed-by: Qt CI Bot Reviewed-by: Eike Ziller --- src/libs/utils/theme/theme_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/utils/theme/theme_mac.mm b/src/libs/utils/theme/theme_mac.mm index d1d623e3a80..499e83282d8 100644 --- a/src/libs/utils/theme/theme_mac.mm +++ b/src/libs/utils/theme/theme_mac.mm @@ -51,7 +51,7 @@ void forceMacOSLightAquaApperance() bool currentAppearanceIsDark() { -#if __has_builtin(__builtin_available) +#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) if (__builtin_available(macOS 10.14, *)) { auto appearance = [NSApp.effectiveAppearance bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]]; From 0079b64b69584583494f2c6ee3c5949fd093fa10 Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Tue, 26 Oct 2021 18:31:27 +0300 Subject: [PATCH 26/57] Android: don't recreate a new AvdManger Change-Id: Icc4f2bb2df34aa3497441d6fbd64c6c8fe1394b3 Reviewed-by: Alessandro Portale --- src/plugins/android/androiddevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/android/androiddevice.cpp b/src/plugins/android/androiddevice.cpp index 600c285edf8..7638d0b402f 100644 --- a/src/plugins/android/androiddevice.cpp +++ b/src/plugins/android/androiddevice.cpp @@ -428,7 +428,7 @@ void AndroidDeviceManager::updateDevicesList() void AndroidDeviceManager::updateDevicesListOnce() { if (!m_avdsFutureWatcher.isRunning() && m_androidConfig.adbToolPath().exists()) { - m_avdsFutureWatcher.setFuture((new AndroidAvdManager)->avdList()); + m_avdsFutureWatcher.setFuture(m_avdManager.avdList()); m_devicesFutureWatcher.setFuture(Utils::runAsync([this]() { return m_androidConfig.connectedDevices(); })); From 3857ef8258ca76329080cf8b22dcce271b280eed Mon Sep 17 00:00:00 2001 From: Vikas Pachdha Date: Tue, 9 Nov 2021 13:31:25 +0100 Subject: [PATCH 27/57] Fix unzip tool not being resolved Change-Id: Idf77ef0e1c0b18c6dccbcf7b5666203dcfda65ab Reviewed-by: hjk --- src/libs/utils/archive.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/utils/archive.cpp b/src/libs/utils/archive.cpp index 2bbc8eb9eb8..b5521103443 100644 --- a/src/libs/utils/archive.cpp +++ b/src/libs/utils/archive.cpp @@ -136,6 +136,7 @@ static Utils::optional unzipTool(const FilePath &src, const FilePath &dest const QString destStr = dest.toString(); const QString args = result.command.arguments().replace("%{src}", srcStr).replace("%{dest}", destStr); result.command.setArguments(args); + return result; } } return {}; From f9f26570c9ac434d5783599a02bb888296d249d8 Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Sun, 31 Oct 2021 14:28:45 +0100 Subject: [PATCH 28/57] Debugger: Add even more std and Qt char and int types Make more stdint, quint and char types known to the debugger. Task-number: QTCREATORBUG-26501 Change-Id: I1e757af2a495142fa37fe2b7cefec56690adbf08 Reviewed-by: hjk --- share/qtcreator/debugger/dumper.py | 34 +++++++++++++++++++++++++-- src/plugins/debugger/watchdata.cpp | 9 +++++-- src/plugins/debugger/watchhandler.cpp | 24 ++++++++++++++----- 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 7bdb028eba3..3838e139654 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -1135,12 +1135,18 @@ class DumperBase(): if displayFormat != DisplayFormat.Raw and p: if innerType.name in ( 'char', + 'int8_t', + 'qint8', 'wchar_t', 'unsigned char', 'uint8_t', + 'quint8', 'signed char', 'CHAR', - 'WCHAR' + 'WCHAR', + 'char8_t', + 'char16_t', + 'char32_t' ): self.putCharArrayHelper(p, n, innerType, self.currentItemFormat(), makeExpandable=False) @@ -1406,11 +1412,17 @@ class DumperBase(): if innerType.name not in ( 'char', 'signed char', + 'int8_t', + 'qint8', 'unsigned char', 'uint8_t', + 'quint8', 'wchar_t', 'CHAR', - 'WCHAR' + 'WCHAR', + 'char8_t', + 'char16_t', + 'char32_t' ): self.putDerefedPointer(value) return @@ -3628,15 +3640,33 @@ class DumperBase(): res = { 'bool': 'int:1', 'char': 'int:1', + 'int8_t': 'int:1', + 'qint8': 'int:1', 'signed char': 'int:1', + 'char8_t': 'uint:1', 'unsigned char': 'uint:1', 'uint8_t': 'uint:1', + 'quint8': 'uint:1', 'short': 'int:2', + 'int16_t': 'int:2', + 'qint16': 'int:2', 'unsigned short': 'uint:2', + 'char16_t': 'uint:2', + 'uint16_t': 'uint:2', + 'quint16': 'uint:2', 'int': 'int:4', + 'int32_t': 'int:4', + 'qint32': 'int:4', 'unsigned int': 'uint:4', + 'char32_t': 'uint:4', + 'uint32_t': 'uint:4', + 'quint32': 'uint:4', 'long long': 'int:8', + 'int64_t': 'int:8', + 'qint64': 'int:8', 'unsigned long long': 'uint:8', + 'uint64_t': 'uint:8', + 'quint64': 'uint:8', 'float': 'float:4', 'double': 'float:8', 'QChar': 'uint:2' diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp index 49a75cc86f0..cf49aa250d4 100644 --- a/src/plugins/debugger/watchdata.cpp +++ b/src/plugins/debugger/watchdata.cpp @@ -48,7 +48,11 @@ bool isIntType(const QString &type) case 'b': return type == "bool"; case 'c': - return type == "char"; + return type.startsWith("char") && + ( type == "char" + || type == "char8_t" + || type == "char16_t" + || type == "char32_t" ); case 'i': return type.startsWith("int") && ( type == "int" @@ -63,7 +67,8 @@ bool isIntType(const QString &type) case 'p': return type == "ptrdiff_t"; case 'q': - return type == "qint16" || type == "quint16" + return type == "qint8" || type == "quint8" + || type == "qint16" || type == "quint16" || type == "qint32" || type == "quint32" || type == "qint64" || type == "quint64" || type == "qlonglong" || type == "qulonglong"; diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 2b5373a042f..1e347e67220 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -717,22 +717,34 @@ static QString formattedValue(const WatchItem *item) // Append quoted, printable character also for decimal. // FIXME: This is unreliable. - if (item->type.endsWith("char") || item->type.endsWith("int8_t")) { + const QString type = item->type; + if (type == "char8_t" || type.endsWith("char") || type.endsWith("int8_t")) { bool ok; const int code = item->value.toInt(&ok); - bool isUnsigned = item->type == "unsigned char" || item->type == "uchar" || item->type == "uint8_t"; + bool isUnsigned = type == "char8_t" + || type == "unsigned char" + || type == "uchar" + || type == "uint8_t"; if (ok) return reformatCharacter(code, 1, !isUnsigned); - } else if (item->type.endsWith("wchar_t")) { + } else if (type == "qint8" || type == "quint8") { + bool ok = false; + const int code = item->value.toInt(&ok); + bool isUnsigned = type == "quint8"; + if (ok) + return reformatCharacter(code, 1, !isUnsigned); + } else if (type == "char32_t" || type.endsWith("wchar_t")) { bool ok; const int code = item->value.toInt(&ok); + bool isUnsigned = type == "char32_t"; if (ok) - return reformatCharacter(code, 4, false); - } else if (item->type.endsWith("QChar")) { + return reformatCharacter(code, 4, !isUnsigned); + } else if (type == "char16_t" || type.endsWith("QChar")) { bool ok; const int code = item->value.toInt(&ok); + bool isUnsigned = type == "char16_t"; if (ok) - return reformatCharacter(code, 2, false); + return reformatCharacter(code, 2, !isUnsigned); } if (format == HexadecimalIntegerFormat From 072d658166193409aa64a9d6b2112a9a0d9915c7 Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Fri, 5 Nov 2021 15:20:24 +0200 Subject: [PATCH 29/57] Android: fix missing argument in UI string Change-Id: I9a02be25429b444704eb6864d59b2f4311ae75ea Reviewed-by: Alessandro Portale --- src/plugins/android/androiddeployqtstep.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index 1915955d242..71b324b8b7b 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -168,7 +168,8 @@ bool AndroidDeployQtStep::init() if (!info.isValid()) { const IDevice *dev = DeviceKitAspect::device(kit()).data(); if (!dev) { - reportWarningOrError(tr("The deployment device \"%1\" is invalid."), Task::Error); + reportWarningOrError(tr("The deployment device \"%1\" is invalid.").arg(""), + Task::Error); return false; } From 7e035d9436beffca83b18ea62c261f26d81fda5f Mon Sep 17 00:00:00 2001 From: Samuel Ghinet Date: Tue, 9 Nov 2021 15:12:35 +0200 Subject: [PATCH 30/57] Fix warning when creating hidden wizards QDS uses hidden wizards as backend for the New Project dialog. When creating a hidden wizard we shouldn't add window support for it. Change-Id: I28e8848f654f2fdee4e00a4906aa3d82b96ee786 Reviewed-by: Miikka Heikkinen Reviewed-by: Thomas Hartmann Reviewed-by: Eike Ziller --- src/plugins/coreplugin/iwizardfactory.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/coreplugin/iwizardfactory.cpp b/src/plugins/coreplugin/iwizardfactory.cpp index 988c4bdd958..ea4ec09e774 100644 --- a/src/plugins/coreplugin/iwizardfactory.cpp +++ b/src/plugins/coreplugin/iwizardfactory.cpp @@ -291,9 +291,10 @@ Wizard *IWizardFactory::runWizard(const FilePath &path, QWidget *parent, Id plat s_reopenData.reopen(); }); s_inspectWizardAction->setEnabled(true); - if (showWizard) + if (showWizard) { wizard->show(); - Core::ICore::registerWindow(wizard, Core::Context("Core.NewWizard")); + Core::ICore::registerWindow(wizard, Core::Context("Core.NewWizard")); + } } else { s_isWizardRunning = false; ICore::updateNewItemDialogState(); From 047292cf46279f77903c2c69c210bcf73e6e958f Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Mon, 8 Nov 2021 10:38:45 +0100 Subject: [PATCH 31/57] QmlDesigner: Add translation font icons Change-Id: Ie6ca22bd51997e8a0d9aadd73dd44935e824bb73 Reviewed-by: Brook Cronin Reviewed-by: Thomas Hartmann --- .../imports/StudioTheme/InternalConstants.qml | 166 +++++++++--------- .../imports/StudioTheme/icons.ttf | Bin 20464 -> 21896 bytes .../components/componentcore/theme.h | 8 + 3 files changed, 95 insertions(+), 79 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml index 0dff2cba8ba..8b2e6698bd9 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml @@ -23,7 +23,7 @@ ** ****************************************************************************/ -import QtQuick 2.10 +import QtQuick 2.15 QtObject { readonly property int width: 1920 @@ -95,84 +95,92 @@ QtObject { readonly property string distributeSpacingHorizontal: "\u005A" readonly property string distributeSpacingVertical: "\u005B" readonly property string distributeTop: "\u005C" - readonly property string edit: "\u005D" - readonly property string eyeDropper: "\u005E" - readonly property string flowAction: "\u005F" - readonly property string flowTransition: "\u0060" - readonly property string fontStyleBold: "\u0061" - readonly property string fontStyleItalic: "\u0062" - readonly property string fontStyleStrikethrough: "\u0063" - readonly property string fontStyleUnderline: "\u0064" - readonly property string gradient: "\u0065" - readonly property string gridView: "\u0066" - readonly property string idAliasOff: "\u0067" - readonly property string idAliasOn: "\u0068" - readonly property string infinity: "\u0069" - readonly property string keyframe: "\u006A" - readonly property string linkTriangle: "\u006B" - readonly property string linked: "\u006C" - readonly property string listView: "\u006D" - readonly property string lockOff: "\u006E" - readonly property string lockOn: "\u006F" - readonly property string mergeCells: "\u0070" - readonly property string minus: "\u0071" - readonly property string mirror: "\u0072" - readonly property string orientation: "\u0073" - readonly property string paddingEdge: "\u0074" - readonly property string paddingFrame: "\u0075" - readonly property string pasteStyle: "\u0076" - readonly property string pause: "\u0077" - readonly property string pin: "\u0078" - readonly property string play: "\u0079" - readonly property string plus: "\u007A" - readonly property string promote: "\u007B" - readonly property string readOnly: "\u007C" - readonly property string redo: "\u007D" - readonly property string rotationFill: "\u007E" - readonly property string rotationOutline: "\u007F" - readonly property string search: "\u0080" - readonly property string sectionToggle: "\u0081" - readonly property string splitColumns: "\u0082" - readonly property string splitRows: "\u0083" - readonly property string startNode: "\u0084" - readonly property string testIcon: "\u0085" - readonly property string textAlignBottom: "\u0086" - readonly property string textAlignCenter: "\u0087" - readonly property string textAlignJustified: "\u0088" - readonly property string textAlignLeft: "\u0089" - readonly property string textAlignMiddle: "\u008A" - readonly property string textAlignRight: "\u008B" - readonly property string textAlignTop: "\u008C" - readonly property string textBulletList: "\u008D" - readonly property string textFullJustification: "\u008E" - readonly property string textNumberedList: "\u008F" - readonly property string tickIcon: "\u0090" - readonly property string transparent: "\u0091" - readonly property string triState: "\u0092" - readonly property string triangleArcA: "\u0093" - readonly property string triangleArcB: "\u0094" - readonly property string triangleCornerA: "\u0095" - readonly property string triangleCornerB: "\u0096" - readonly property string unLinked: "\u0097" - readonly property string undo: "\u0098" - readonly property string unpin: "\u0099" - readonly property string upDownIcon: "\u009A" - readonly property string upDownSquare2: "\u009B" - readonly property string visibilityOffBroken: "\u009C" // visibilityOff - readonly property string visibilityOff: "\u009D" // visibilityOff2 - readonly property string visibilityOn: "\u009E" - readonly property string wildcard: "\u009F" - readonly property string wizardsAutomotive: "\u00A0" - readonly property string wizardsDesktop: "\u00A1" - readonly property string wizardsGeneric: "\u00A2" - readonly property string wizardsMcuEmpty: "\u00A3" - readonly property string wizardsMcuGraph: "\u00A4" - readonly property string wizardsMobile: "\u00A5" - readonly property string wizardsUnknown: "\u00A6" - readonly property string zoomAll: "\u00A7" - readonly property string zoomIn: "\u00A8" - readonly property string zoomOut: "\u00A9" - readonly property string zoomSelection: "\u00AA" + readonly property string download: "\u005D" + readonly property string edit: "\u005E" + readonly property string eyeDropper: "\u005F" + readonly property string favorite: "\u0060" + readonly property string flowAction: "\u0061" + readonly property string flowTransition: "\u0062" + readonly property string fontStyleBold: "\u0063" + readonly property string fontStyleItalic: "\u0064" + readonly property string fontStyleStrikethrough: "\u0065" + readonly property string fontStyleUnderline: "\u0066" + readonly property string gradient: "\u0067" + readonly property string gridView: "\u0068" + readonly property string idAliasOff: "\u0069" + readonly property string idAliasOn: "\u006A" + readonly property string infinity: "\u006B" + readonly property string keyframe: "\u006C" + readonly property string linkTriangle: "\u006D" + readonly property string linked: "\u006E" + readonly property string listView: "\u006F" + readonly property string lockOff: "\u0070" + readonly property string lockOn: "\u0071" + readonly property string mergeCells: "\u0072" + readonly property string minus: "\u0073" + readonly property string mirror: "\u0074" + readonly property string orientation: "\u0075" + readonly property string paddingEdge: "\u0076" + readonly property string paddingFrame: "\u0077" + readonly property string pasteStyle: "\u0078" + readonly property string pause: "\u0079" + readonly property string pin: "\u007A" + readonly property string play: "\u007B" + readonly property string plus: "\u007C" + readonly property string promote: "\u007D" + readonly property string readOnly: "\u007E" + readonly property string redo: "\u007F" + readonly property string rotationFill: "\u0080" + readonly property string rotationOutline: "\u0081" + readonly property string search: "\u0082" + readonly property string sectionToggle: "\u0083" + readonly property string splitColumns: "\u0084" + readonly property string splitRows: "\u0085" + readonly property string startNode: "\u0086" + readonly property string testIcon: "\u0087" + readonly property string textAlignBottom: "\u0088" + readonly property string textAlignCenter: "\u0089" + readonly property string textAlignJustified: "\u008A" + readonly property string textAlignLeft: "\u008B" + readonly property string textAlignMiddle: "\u008C" + readonly property string textAlignRight: "\u008D" + readonly property string textAlignTop: "\u008E" + readonly property string textBulletList: "\u008F" + readonly property string textFullJustification: "\u0090" + readonly property string textNumberedList: "\u0091" + readonly property string tickIcon: "\u0092" + readonly property string translationCreateFiles: "\u0093" + readonly property string translationCreateReport: "\u0094" + readonly property string translationExport: "\u0095" + readonly property string translationImport: "\u0096" + readonly property string translationSelectLanguages: "\u0097" + readonly property string translationTest: "\u0098" + readonly property string transparent: "\u0099" + readonly property string triState: "\u009A" + readonly property string triangleArcA: "\u009B" + readonly property string triangleArcB: "\u009C" + readonly property string triangleCornerA: "\u009D" + readonly property string triangleCornerB: "\u009E" + readonly property string unLinked: "\u009F" + readonly property string undo: "\u00A0" + readonly property string unpin: "\u00A1" + readonly property string upDownIcon: "\u00A2" + readonly property string upDownSquare2: "\u00A3" + readonly property string visibilityOffBroken: "\u00A4" // visibilityOff + readonly property string visibilityOff: "\u00A5" // visibilityOff2 + readonly property string visibilityOn: "\u00A6" + readonly property string wildcard: "\u00A7" + readonly property string wizardsAutomotive: "\u00A8" + readonly property string wizardsDesktop: "\u00A9" + readonly property string wizardsGeneric: "\u00AA" + readonly property string wizardsMcuEmpty: "\u00AB" + readonly property string wizardsMcuGraph: "\u00AC" + readonly property string wizardsMobile: "\u00AD" + readonly property string wizardsUnknown: "\u00AE" + readonly property string zoomAll: "\u00AF" + readonly property string zoomIn: "\u00B0" + readonly property string zoomOut: "\u00B1" + readonly property string zoomSelection: "\u00B2" readonly property font iconFont: Qt.font({ "family": controlIcons.name, diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf index 403bb7205ade2b259d1d70370c82fe762623eb09..24141fcc8376a2d55af938a1c3c46f06e288f1b5 100644 GIT binary patch delta 2118 zcmew`pRr>#V?6^S0|NsuLjwadLx7uGi0^dMmSP5m&>RK^1{wcgeWS>ZR6hm=#s~%m zhJ@tY!~(Ax7YzmmrZ)@>j84gAB?=6ROqC1_ECvh=3@qu1#RdQWGcYqSgr+bsFmR;j zRHiNL<&$S%U`=3Pa1zK!O-xbzoN$|gf#D7V1A|#cMrwT`*Vq3O85kHv7#J8-GIC2Q zL=$+785kIMFfcG0<>V(P%01HG#lXN~!oa|&lbcvk!0?FSGy?;p1p@d%1q=*KFADODOL7Fdl^GbkA{ZFBIl-P|WMGJQ+1nh?Z}XLboB0I;0|Ud|b$#a{ zG*jRCNsP9PQzzRo#xic2Jcn@++y8$I;tULv9hlO&=QAu~UGOG6O?9h-P5u0aML=AgY&vp=t6*W?jaKlf_y3>Ys7zao2Fq z;NHh0z~jIZ#|Jz@{U z)x^8RPe`yyG)bJ1w2};x%#m!mdsH~`@rmkjYZf2@x zW^5!bW^Tu5Y$PVj$i{A_rmn1{X3J=zrp>6tCd(+o2BPH|#f;3EYm9B#m@+*6Hn?T7 zGRetvbMz!R84GYKr&^^1sSvv4x9GEZP)V`ZMi#LCIi%E-vDIYCOF(TL%HAoB}mb_Pxc21a2; zR$*0EVO2%OFXfE2|4x_vI}IinYnj>qO?~ih>izqS*$*~%N>351XJMHC--7u(vpfSY zgE)gCgDwMusvM)J2%EB!n!2K(qBx_XnyHDIxuCitgOQo3iJB6dsEE0!vZ%7DvZ=AD zu_&{FOLR$)b)v*SFUCJp|ITA9XU_Al`sc~`r!FG0Hu9sFyoZPUA-+71pb~py=91Na z(xqvz~8e>lRQ9f`1^}->Az?Qp2ox+VaqKnB&2Q-VQ&_~&D8yO3EUfhc7uJv zr2SV0q|d{H$x>gxUr%p>zCI}ZGchp#w`P9Aw248PL5qQbRZ&UJRM5oCno(3)iA_{c zM9f&x$jnsGM6F(%(bU*TOjJ;WjZs-pSy0)Wx$@69U3&-JkMBjKrG=O|g{7p0zkSiO zxBGV{&MvO@sGSaDwXTD`wD7-HK`ALg#%f_{dk5WrtvYs0^Zo@huD!tkvfPpw%e5Iz z>tU7~v#T2m8soCu{$GAvZEc+0Fdh zrY<6GtY%`a%*Lq1&c?2&rYk5TpC?SD!C zZZlVE%}t6>zss7W^Y6a4Eu#w;*S|d?-*~oha&F;cT*Jheq{FDFo%~8bU<)7LKbEAq zTC3DAg0(Q3C(W(bTBXLU05OSCm2sYIOr2>zL&km>Jj^xEc5vgc&3mR2dkA z6$KR;6-5;pK{PZ)s;Zldn~O8E$BMJ7v#Xnfcv;LMf8H=X{p-cF4T2d>86E%aXLS7g z-&8_2K}=LjOALmX<^ISrZ_WJkkm=oj20y>QetxgaL}lZ}|9yn15Yy6PVAw2ev_?SP zl+hGi7celeFi0}ahq7521Q>5a*=!7wObV0VIq9lrF`Q&zW?*FDWME-1V$6oJSs4@< zcS6~03`UG^Haj^hF|u1Q=rR~G7*5W0vEa1OH8j*UGB7fnY~UI&`M*o!e+Fg-2LCe*3=ACU zIhARw)z_jJ7+4(`7;Hl_QWH}Y&$ZoWU|_hzz`$UZk&#-T$o2LAL1abvI|rCtPBE-_n>Sx21zF6$*0_P)pHn5GB7hRvT!o6Fc>lBLD{Sf z3XFT8Y&HfX#`l}$Jd_wYjTlTBbQug83?{pKT5uVe>KYp88W|WFPHylBn0&*tadL#0 mB4h97DlaL<%}czUStft+m)I;Bz{$LMNAOWbZg^xVUIYL%l&(Yo diff --git a/src/plugins/qmldesigner/components/componentcore/theme.h b/src/plugins/qmldesigner/components/componentcore/theme.h index 2ef1f82cbb6..159824b1f77 100644 --- a/src/plugins/qmldesigner/components/componentcore/theme.h +++ b/src/plugins/qmldesigner/components/componentcore/theme.h @@ -103,8 +103,10 @@ public: distributeSpacingHorizontal, distributeSpacingVertical, distributeTop, + download, edit, eyeDropper, + favorite, flowAction, flowTransition, fontStyleBold, @@ -155,6 +157,12 @@ public: textFullJustification, textNumberedList, tickIcon, + translationCreateFiles, + translationCreateReport, + translationExport, + translationImport, + translationSelectLanguages, + translationTest, transparent, triState, triangleArcA, From 05d74d000e2d49b65bc655a74f553f9d6284c2ce Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 8 Nov 2021 17:41:32 +0100 Subject: [PATCH 32/57] Doc: Update information about Git Commit and Amend commit views Describe the options in the views and add a screenshot. Task-number: QTCREATORBUG-26278 Change-Id: I434af29f8486b7fa523cca151243a53019e92a42 Reviewed-by: Orgad Shaneh --- doc/qtcreator/images/qtcreator-git-amend.png | Bin 0 -> 3870 bytes doc/qtcreator/images/qtcreator-vcs-commit.png | Bin 40767 -> 16442 bytes doc/qtcreator/src/vcs/creator-vcs-git.qdoc | 33 +++++++++++++++--- 3 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 doc/qtcreator/images/qtcreator-git-amend.png diff --git a/doc/qtcreator/images/qtcreator-git-amend.png b/doc/qtcreator/images/qtcreator-git-amend.png new file mode 100644 index 0000000000000000000000000000000000000000..2aa74da5eb7b5e4f6b195ee5eb35f90c1b131ce1 GIT binary patch literal 3870 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 be%c#x-Vj{RHhCHY0|SGntDnm{r-UW|P84Ec literal 0 HcmV?d00001 diff --git a/doc/qtcreator/images/qtcreator-vcs-commit.png b/doc/qtcreator/images/qtcreator-vcs-commit.png index 79ef8bc53ab8df86d312b85eff2ea480a815b4f3..fbd1ae73a9e49cbbe98b454e06dfc4aa58dc52f2 100644 GIT binary patch literal 16442 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 diff --git a/doc/qtcreator/src/vcs/creator-vcs-git.qdoc b/doc/qtcreator/src/vcs/creator-vcs-git.qdoc index 5359c964f67..18b9bcc6891 100644 --- a/doc/qtcreator/src/vcs/creator-vcs-git.qdoc +++ b/doc/qtcreator/src/vcs/creator-vcs-git.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -203,7 +203,20 @@ commit page containing a text editor where you can enter your commit message and a checkable list of modified files to be included. - \image qtcreator-vcs-commit.png + \image qtcreator-vcs-commit.png "Committing changes with Git" + + \uicontrol {General Information} displays the names of the + repository and branch for the commit. + + In \uicontrol {Commit Information}, you can edit information about the + author of the commit. To bypass re-commit and commit message hooks, + select \uicontrol {Bypass hooks}. If signoffs are used for your project, + select \uicontrol {Sign off} to add a \e signed-off-by trailer by the + author at the end of the commit log message. + + In \uicontrol Description, edit the commit message. + + In \uicontrol Files, select the files to include in the commit. When you have finished filling out the commit page information, click on \uicontrol Commit to start committing. @@ -223,10 +236,22 @@ \section2 Amending Commits - To apply latest changes to the last commit, select - \uicontrol {Amend Last Commit}. You can also edit the commit message. + To apply latest changes to the last commit, select \uicontrol Tools > + \uicontrol Git > \uicontrol {Local Repository} > + \uicontrol {Amend Last Commit}. + + \image qtcreator-git-amend.png "Amending a Git commit" + + To view the commit in its current form, before amending, select + \uicontrol {Show HEAD}. + + To view a diff of the changes in the selected files, select + \uicontrol {Diff Selected Files}. + + Select \uicontrol Commit to amend the commit. To amend an earlier comment in a series of related commits, select + \uicontrol Tools > \uicontrol Git > \uicontrol {Local Repository} > \uicontrol {Fixup Previous Commit}. This operation is done using interactive rebase. In case of conflicts, a merge tool is suggested. From 5e5ff9fa0d9a6b370ead2b1750376c6e077d8796 Mon Sep 17 00:00:00 2001 From: Tuomo Pelkonen Date: Tue, 9 Nov 2021 15:20:34 +0200 Subject: [PATCH 33/57] Avoid QmlPuppet crash when translation database is locked Task-number: QDS-5365 Change-Id: I0be2aaa4d64334273ce03f5bb692b8ed8597c266 Reviewed-by: Thomas Hartmann --- .../qml2puppet/instances/nodeinstanceserver.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp index 1b0fdd5a418..682b825eed2 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp @@ -1395,13 +1395,17 @@ void NodeInstanceServer::setTranslationLanguage(const QString &language) static QPointer multilanguageTranslator; if (!MultiLanguage::databaseFilePath().isEmpty() && QFileInfo::exists(QString::fromUtf8(MultiLanguage::databaseFilePath()))) { - if (!multilanguageLink) { - multilanguageLink = std::make_unique(); - multilanguageTranslator = multilanguageLink->translator().release(); - QCoreApplication::installTranslator(multilanguageTranslator); + try { + if (!multilanguageLink) { + multilanguageLink = std::make_unique(); + multilanguageTranslator = multilanguageLink->translator().release(); + QCoreApplication::installTranslator(multilanguageTranslator); + } + if (multilanguageTranslator) + multilanguageTranslator->setLanguage(language); + } catch (std::exception &e) { + qWarning() << "QmlPuppet is unable to initialize MultiLanguage translator:" << e.what(); } - if (multilanguageTranslator) - multilanguageTranslator->setLanguage(language); } } From e7d682e1b0600c538d12e4350069d8e8ba1f8ca6 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 9 Nov 2021 15:45:43 +0100 Subject: [PATCH 34/57] Update change log for 6.0 Change-Id: I3eb8f028ee9eef063101ac6938db7956333e9084 Reviewed-by: Leena Miettinen --- dist/changes-6.0.0.md | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/dist/changes-6.0.0.md b/dist/changes-6.0.0.md index fdf1c71ca57..475250748ce 100644 --- a/dist/changes-6.0.0.md +++ b/dist/changes-6.0.0.md @@ -29,16 +29,24 @@ Editing * Added option for saving open files automatically after refactoring (QTCREATORBUG-25924) * Added information about source to tooltip on diagnostics -* Fixed `Insert Definition` for templates with value parameters - (QTCREATORBUG-26113) +* Added highlighting color option for namespaces (QTCREATORBUG-16580) +* Made pure virtual functions optional in `Create implementations for all member + functions` (QTCREATORBUG-26468) +* Fixed `Insert Definition` for template types (QTCREATORBUG-26113, + QTCREATORBUG-26397) +* Fixed that `Find References` did not work for some template and namespace + combinations (QTCREATORBUG-26520) * Fixed canceling of C++ parsing on configuration change (QTCREATORBUG-24890) * Fixed crash when checking for refactoring actions (QTCREATORBUG-26316) * Fixed wrong target compiler option (QTCREATORBUG-25615) * Fixed parentheses matching (QTCREATORBUG-26400) +* Fixed documentation comment generation for template types (QTCREATORBUG-9620) * Clangd * Added warning for older `clangd` versions * Added support for completion and function hint + * Added option for `Insert header files on completion` * Improved location of generated `compile_commands.json` (QTCREATORBUG-26431) + * Fixed missing reparsing after refactorings (QTCREATORBUG-26523) ### QML @@ -66,6 +74,7 @@ Projects (QTCREATORBUG-26422) * Fixed that re-detecting compilers removed compilers from kits (QTCREATORBUG-25697) +* Fixed GitHub action created by Qt Creator plugin wizard for Qt 6 ### CMake @@ -79,6 +88,7 @@ Projects QTCREATORBUG-26238, QTCREATORBUG-21452, QTCREATORBUG-25644, QTCREATORBUG-25782) * Fixed that generated files were selected for analyzing (QTCREATORBUG-25125) +* Fixed importing of Qt projects (QTCREATORBUG-25767) ### qmake @@ -88,6 +98,11 @@ Projects * Fixed that headers were not shown as part of the project (QTCREATORBUG-26356) +### Conan + +* Added `QT_CREATOR_CONAN_BUILD_POLICY` used for `BUILD` property of + `conan_cmake_run` + Debugging --------- @@ -97,6 +112,11 @@ Debugging * Fixed variable expansion for `Additional Startup Commands` (QTCREATORBUG-26382) +### CDB + +* Added hint for missing Qt debug information +* Improved pretty printing for Qt 6 without debug information + Version Control Systems ----------------------- @@ -117,9 +137,16 @@ Test Integration Platforms --------- +### Windows + +* Added support for MSVC 2022 + ### macOS * Changed prebuilt binaries to universal Intel + ARM +* Made dark theme the default in dark system mode +* Fixed issues with dark system mode (QTCREATORBUG-21520, QTCREATORBUG-26427, + QTCREATORBUG-26428) ### Android @@ -127,11 +154,16 @@ Platforms selector (QTCREATORBUG-23991) * Added details to device settings (QTCREATORBUG-23991) * Added filter field for Android SDK manager +* Fixed that NDK 22 and later could not be added ### WebAssembly * Fixed running applications (QTCREATORBUG-25905, QTCREATORBUG-26189) +### MCU + +* Added preliminary support for SDK 2.0 + ### Docker * Various improvements @@ -147,6 +179,7 @@ André Pönitz Artem Sokolovskii Artur Shepilko Assam Boudjelthia +BogDan Vatra Christiaan Janssen Christian Kandeler Christian Stenger @@ -160,6 +193,7 @@ Ivan Komissarov Jaroslaw Kobus Johanna Vanhatapio Jonas Karlsson +Jonas Singe Kai Köhne Kama Wójcik Knud Dollereder @@ -171,9 +205,11 @@ Marco Bubke Martin Kampas Miikka Heikkinen Miina Puuronen +Oliver Wolff Orgad Shaneh Petar Perisin Piotr Mikolajczyk +Robert Löhning Samuel Ghinet Shantanu Tushar Tapani Mattila @@ -181,6 +217,7 @@ Tasuku Suzuki Thiago Macieira Thomas Hartmann Tim Jenssen +Tomi Korpipaa Tony Leinonen Tor Arne Vestbø Tuomo Pelkonen From a850b1b866a5dfbaffdcf26fa7816c5a41305bbf Mon Sep 17 00:00:00 2001 From: Samuel Ghinet Date: Tue, 9 Nov 2021 18:58:15 +0200 Subject: [PATCH 35/57] Implement the New Project creation wizard for QDS Task-number: QDS-4490 Change-Id: Ie8073e8838ec14a7f11ad972acc6fca4456adf58 Reviewed-by: Alessandro Portale Reviewed-by: Qt CI Bot --- .../newprojectdialog/NewProjectDialog.qml | 192 ++++++++ .../newprojectdialog/image/style-basic.png | Bin 0 -> 10544 bytes .../newprojectdialog/image/style-default.png | Bin 0 -> 4603 bytes .../newprojectdialog/image/style-error.png | Bin 0 -> 1310 bytes .../newprojectdialog/image/style-fusion.png | Bin 0 -> 9161 bytes .../newprojectdialog/image/style-imagine.png | Bin 0 -> 10792 bytes .../newprojectdialog/image/style-macos.png | Bin 0 -> 4600 bytes .../image/style-material_dark.png | Bin 0 -> 9703 bytes .../image/style-material_light.png | Bin 0 -> 10683 bytes .../image/style-universal_dark.png | Bin 0 -> 9786 bytes .../image/style-universal_light.png | Bin 0 -> 10742 bytes .../image/style-universal_system.png | Bin 0 -> 9786 bytes .../imports/NewProjectDialog/Details.qml | 453 ++++++++++++++++++ .../imports/NewProjectDialog/DialogValues.qml | 83 ++++ .../NewProjectDialog/NewProjectView.qml | 198 ++++++++ .../imports/NewProjectDialog/Styles.qml | 183 +++++++ .../imports/NewProjectDialog/qmldir | 4 + .../imports/ProjectType/DefaultProject.qml | 48 ++ .../imports/ProjectType/qmldir | 1 + .../imports/StudioControls/Section.qml | 3 + src/plugins/CMakeLists.txt | 2 +- src/plugins/coreplugin/icore.cpp | 27 +- src/plugins/coreplugin/icore.h | 2 - src/plugins/coreplugin/mainwindow.cpp | 11 +- .../jsonwizard/jsonprojectpage.h | 3 +- src/plugins/studiowelcome/CMakeLists.txt | 10 +- src/plugins/studiowelcome/createproject.cpp | 77 +++ src/plugins/studiowelcome/createproject.h | 77 +++ .../newprojectdialogimageprovider.cpp | 99 ++++ .../newprojectdialogimageprovider.h | 50 ++ src/plugins/studiowelcome/newprojectmodel.cpp | 106 ++++ src/plugins/studiowelcome/newprojectmodel.h | 145 ++++++ src/plugins/studiowelcome/qdsnewdialog.cpp | 343 +++++++++++++ src/plugins/studiowelcome/qdsnewdialog.h | 170 +++++++ src/plugins/studiowelcome/screensizemodel.h | 111 +++++ src/plugins/studiowelcome/studiowelcome.pro | 10 + src/plugins/studiowelcome/studiowelcome.qbs | 10 + .../studiowelcome/studiowelcomeplugin.cpp | 5 + src/plugins/studiowelcome/stylemodel.cpp | 130 +++++ src/plugins/studiowelcome/stylemodel.h | 96 ++++ src/plugins/studiowelcome/wizardfactories.cpp | 113 +++++ src/plugins/studiowelcome/wizardfactories.h | 66 +++ src/plugins/studiowelcome/wizardhandler.cpp | 249 ++++++++++ src/plugins/studiowelcome/wizardhandler.h | 96 ++++ 44 files changed, 3164 insertions(+), 9 deletions(-) create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/NewProjectDialog.qml create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/image/style-basic.png create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/image/style-default.png create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/image/style-error.png create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/image/style-fusion.png create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/image/style-imagine.png create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/image/style-macos.png create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/image/style-material_dark.png create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/image/style-material_light.png create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/image/style-universal_dark.png create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/image/style-universal_light.png create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/image/style-universal_system.png create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/DialogValues.qml create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/NewProjectView.qml create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Styles.qml create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/qmldir create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/imports/ProjectType/DefaultProject.qml create mode 100644 share/qtcreator/qmldesigner/newprojectdialog/imports/ProjectType/qmldir create mode 100644 src/plugins/studiowelcome/createproject.cpp create mode 100644 src/plugins/studiowelcome/createproject.h create mode 100644 src/plugins/studiowelcome/newprojectdialogimageprovider.cpp create mode 100644 src/plugins/studiowelcome/newprojectdialogimageprovider.h create mode 100644 src/plugins/studiowelcome/newprojectmodel.cpp create mode 100644 src/plugins/studiowelcome/newprojectmodel.h create mode 100644 src/plugins/studiowelcome/qdsnewdialog.cpp create mode 100644 src/plugins/studiowelcome/qdsnewdialog.h create mode 100644 src/plugins/studiowelcome/screensizemodel.h create mode 100644 src/plugins/studiowelcome/stylemodel.cpp create mode 100644 src/plugins/studiowelcome/stylemodel.h create mode 100644 src/plugins/studiowelcome/wizardfactories.cpp create mode 100644 src/plugins/studiowelcome/wizardfactories.h create mode 100644 src/plugins/studiowelcome/wizardhandler.cpp create mode 100644 src/plugins/studiowelcome/wizardhandler.h diff --git a/share/qtcreator/qmldesigner/newprojectdialog/NewProjectDialog.qml b/share/qtcreator/qmldesigner/newprojectdialog/NewProjectDialog.qml new file mode 100644 index 00000000000..86234bf5bae --- /dev/null +++ b/share/qtcreator/qmldesigner/newprojectdialog/NewProjectDialog.qml @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick.Window + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import StudioTheme as StudioTheme +import StudioControls as SC + +import NewProjectDialog + +Item { + width: DialogValues.dialogWidth + height: DialogValues.dialogHeight + + Rectangle { // the main dialog panel + anchors.fill: parent + color: DialogValues.darkPaneColor + + ColumnLayout { + anchors.fill: parent + + Layout.alignment: Qt.AlignHCenter + spacing: 0 + + Item { // Header Item + Layout.fillWidth: true + implicitHeight: 218 + + Column { + anchors.fill: parent + + Item { width: parent.width; height: 74 } // spacer + + Text { + text: qsTr("Welcome to Qt Design Studio. Let's Create Something Wonderful!") + font.pixelSize: 32 + width: parent.width + height: 47 + lineHeight: 49 + lineHeightMode: Text.FixedHeight + color: DialogValues.textColor + horizontalAlignment: Text.AlignHCenter + } + + Item { width: parent.width; height: 11 } // spacer + + Text { + width: parent.width + text: qsTr("Get started by selecting from Presets or start from empty screen. You may also include your design file.") + color: DialogValues.textColor + font.pixelSize: DialogValues.paneTitlePixelSize + lineHeight: DialogValues.paneTitleLineHeight + lineHeightMode: Text.FixedHeight + horizontalAlignment: Text.AlignHCenter + } + } + } // Header Item + + Item { // Content Item + Layout.fillWidth: true + Layout.fillHeight: true + + RowLayout { + x: 35 + width: parent.width - 70 + height: parent.height + spacing: 0 + + Rectangle { // Left pane + color: DialogValues.lightPaneColor + Layout.fillWidth: true + Layout.fillHeight: true + Layout.minimumWidth: 379 // figured out this number visually + Layout.minimumHeight: 326 // figured out this number visually + + Column { + x: DialogValues.defaultPadding // left padding + width: parent.width - DialogValues.defaultPadding * 2 // right padding + height: parent.height + + Text { + text: qsTr("Presets") + width: parent.width + font.weight: Font.DemiBold + font.pixelSize: DialogValues.paneTitlePixelSize + lineHeight: DialogValues.paneTitleLineHeight + lineHeightMode: Text.FixedHeight + color: DialogValues.textColor + } + + NewProjectView { + id: projectViewId + x: 10 // left padding + width: parent.width - 64 // right padding + height: DialogValues.projectViewHeight + loader: projectDetailsLoader + } + + Item { height: 5; width: parent.width } + + Text { + id: descriptionText + text: dialogBox.projectDescription + font.pixelSize: DialogValues.defaultPixelSize + lineHeight: DialogValues.defaultLineHeight + lineHeightMode: Text.FixedHeight + leftPadding: 14 + width: projectViewId.width + color: DialogValues.textColor + wrapMode: Text.WordWrap + maximumLineCount: 4 + elide: Text.ElideRight + } + } + } // Left pane + + Loader { + id: projectDetailsLoader + // we need to specify width because the loaded item needs to use parent sizes + width: DialogValues.loadedPanesWidth + Layout.fillHeight: true + source: "" + } + } // RowLayout + } //Content Item + + Item { // Footer + implicitHeight: DialogValues.footerHeight + implicitWidth: parent.width + RowLayout { + anchors.fill: parent + spacing: DialogValues.defaultPadding + + Item { Layout.fillWidth: true } + + SC.AbstractButton { + implicitWidth: DialogValues.dialogButtonWidth + width: DialogValues.dialogButtonWidth + visible: true + buttonIcon: qsTr("Cancel") + iconSize: DialogValues.defaultPixelSize + iconFont: StudioTheme.Constants.font + + onClicked: { + dialogBox.reject(); + } + } + + SC.AbstractButton { + implicitWidth: DialogValues.dialogButtonWidth + width: DialogValues.dialogButtonWidth + visible: true + buttonIcon: qsTr("Create") + iconSize: DialogValues.defaultPixelSize + enabled: dialogBox.fieldsValid + iconFont: StudioTheme.Constants.font + + onClicked: { + dialogBox.accept(); + } + } + Item { implicitWidth: 35 - DialogValues.defaultPadding } + } // RowLayout + } // Footer + } // ColumnLayout + } // Rectangle +} diff --git a/share/qtcreator/qmldesigner/newprojectdialog/image/style-basic.png b/share/qtcreator/qmldesigner/newprojectdialog/image/style-basic.png new file mode 100644 index 0000000000000000000000000000000000000000..53d03e476b4068441abae0a9422ae041e399d43c GIT binary patch literal 10544 zcmeAS@N?(olHy`uVBq!ia0y~yU^v0Rz{tkI#=yX!aQ4xR>+o$_vty2!S@v=F)Jnl8W zH=&hV-0Rz$o2-kL?0(#5E%fNoqbF}}Zr)V=J+E1D(Z`$V^H1LY|F8VyMCJA;r>E;H z-i`nFX?n}L*xjd=&#%+^|L3_qZ(GN)dA8LlcXyR$Im*?1a8&L%n80Ev(WAiDEO;cr zph<$qO`!Q8N0NbrBM%!`a-;r<1Qt&IrafP;MRU#D|MS`GPv36mpSFI#XYu*B?Ita( zjuLB9?CX9!Z2$F3*}d;XBQtwR!vE!sXA0T={C>axfA{D3`oE=>-|v<`y|B=^=*Ne| zpAVY(OYDE&tA1~*+@V;*ap*wWgL8AO!yi3!r@Kbuz$C}&Qa*aw}1Y}-cH&-WOgM+7e<);)$+o~->ZEL*m zHJ|@5?O1y9Cp$MK=T!S4sHv-&xrBov~r(OLVwmweR zIPFZpC*8lS4`E5wOSdyeO=D2EuOJj-~PWV-#_`? z-QBN$@BQ^^wbc)GpBW3TWnNno8MG}Ya%J4!T~E%;4DOCeJ2%JEb;*ub9$VAo>;G(w z6m)*2z%gx6&{8ie2k)s`OY<&FP;_46(kYbXImi+XWn7+Qf9e!t5d3xp`M*gz_3L!!C%W?}9Hc^EI`wD}L5f^Y`oZ zORK~6x$ZrEIz4_G8?Tf{uaxN(CI^+YT^4)=tBanWTdOBDE%p7qy;eIm+66E7oBH^8 zzxT$Zqf3&H_jygYx3~KBM|Qai2e&?%mDjkP($39^{2_1AmwKq`2PZ?b;!%!6Cc2I0 z&GO})jXP_9m&v{f2!Xk?!1afJPF8*lIfy~5+_%OdvI?Tr$8_h*OK z5&Z>WYom7MUs~d6ly*j9tJ;p@BepxrA~ZY>RVVazlvc>^Z%Z;*^2157<%6T4o{%9^ zO5(AuzdR8hpZe?nIJ4_L|M8VC#^l7o`}edqu5;n%e5KT5^dTq{0rtF9fs z?#guoULTpm_GNE(bse1Wh(%G1Bc}er#9E%5{J7^+1br zm3H?YPE6i&Y<=^GnKs{FYrF9^KTVRv$n>xh0l6T6iJ_JfZ@7&l9MOx9PsV#v_!nJ2 z@jK_-I&L|G9n_cdZgW zZq}q?y+Mv=6Sue?i|d5o<$fzgKfd}fuO|B5%|-v;v~*5h;(7U*QR=A>(H-}mv24h^ zy`l8AnCO*fHFAyO=i4}Z#0(S<@Z5TI)O*W)rTL$q+$el?>!Y06f*ysFY;3pp)&5qw z(Ys)-qmRy``?C-3&i<~~`QF|k>)4e^a(k=1cYYFG>OEb3j_HkuYYx;^mfzl8bF4t*-^#ClIlc5t{QpV!3JWi-EEcc4XZl_<_?_Tio$QZkES_O^ z-mJNLHfKj><7?$Re>0~}(64uVX`irQ-sa59Y1dWDm#r!NUvs-mHfH}}u}h0mU%PN$ zUbFMc%INc7C2lTw7jpfb?UJ;$w=Qj~Wmmn}(kZ;u|9-{W$e`7JYohG)YkAxzq%amT z8wW1DVfX(}vFe=qd>y8@ciML8g&p;pHp#7b_9>t1vfsaiFOM-_#rnx%Ud_6 zTRU4sKk$<2t4NJd`R-}oWUWum{$CT!#wYb=R+HYeqW+M8ri-iht`|JQF)570$>tD) zUE!maH3f55L~YGeR`s%f^GoU2$u~EPuOwaYDS3FvHRv|)kI&D~@66k!eD|MNUqp4v zqU`TxWp^r8#wok$9^X^>d1-!)y>f@(lW)5sj`zuOb2`4bDEA^saPpoXkJM!E@I3Rj z|D$kuZuQrKn?+V1q^-I?P0YS+mV8X7b7iRe|L;5OK3=*OIpO2ExvSz9FIyA0*KLuk zvG+9Dn)S|6RgZoG{_t?mK2#mqN5`qg<=Lz0tjB znw+xa^}~N(-rUSG<&*hwq4d(+Wh|C8KQ?@Mc{%)6>5CQD7RCK#GphU~Qo8Zc@2{7y ze<^cmRJhn@6SEs+^0v!+I`{H#f9Z2=$4B8MsjIIUWqwk*`JTh`b>^&QC#AHdV!Cl_ z#L~CEzO=jMXVJ~=_49q^+Z`^wCA;i+hJly*-O$zHuTAYA-!Zc5wm8lmu*gN}1YWeIsMVtGDsk6k3-rnCIZvDCF zUiJIj@a%(y_xfwM1!S;n3=wV?R54Z2Haegic`<>7vv8O7`i&*!&7wYk-40HfcsN0I zJEQ9MH`^ygH+P!FxNm7}xcADCN9}hqq?zFn(A~lEa7W}3nZ|6{XGxMub{^{Q5_+3M z^XG>j%`!LSOxY-ZNucoZ9+rm_ny&~htNj1>ef{fM?6;SCPk%Byf8WIVov-Y;W++VX z{VbKU@PpOue*1qK?J;>%%lG!Ew3&DdO!_bJWQSjT-Os1GOJ^1AoBz*rlEkHyO-hBV z?}W6Uc-}17sUZH*t0+5BlCxJKapt>oTEDmMim(%%+oY2u6|e1d=g=vem2dXDYQ>!| ze08gGZ~R66HI{}Fj+6E#bREwwUYA#T`062FZkZ2po4bA$hxlyEuMcOpeU$G#U3YTk zI)yGtqcu#%DGDEMtq^Xk5LWk{cGP>?i8Yb_CugW1*Gjawo}K>l{KxZ+Sw%aGE9#{S z+$N|rE6ipTf8%!HT*H@^&#K#1Y^Rl~Ztk6JcDYIOM8lz^!*0DxuN+SOviZAZf^3Lo z;dQ^Q0uws^{*FyeTzjkZY3I7TsWVrb$UM)wS;>3kWAFu=@JE)f52e2=m|uC|>aO4C zzdyfqz_>}pb4#Oyl8AKCg2va%Aq?;C{M1kfGc-I}TRE3@^Y0diuX*MtW?Nl#?dvaM z(FoYk(Ia7bNpn~KRSD*w^CvBxYi*j=^D5Ug z?n_;kwOM$}yNj!*m%P2^yY|Gs+UioXHPgGj3l0mcb=y_)^OL9_fA+$4^9?>IUfuBU zaLDuTPp8KhGL-~>t&iNC*6UNSY3YPkeaXM^-)6T>6I40L-Fl*pZL^_w$y&XzM@|oC zuSz_6S32p(G4tEoa<6K}E{mTz?e6P+0$(a5ue^EOxBvX#vsd2Vv#nkqrEJ&!{VDg6 zO9C~;-S5c z>EF}B&UxlN`Sbd#nu)}vl!GGcgf_BlJn*$-;}7Yi4KI%6OuE`6p|t7AHSfP4$`|NO zi;pph)p0)3ZB}tMmgAx4!|Rr3vLt-I9fvf)CaCBu8GSwdtF1lsv!sqk`H>GweEVEy zv)6C7H+X(3p<_m7-2HzI`|Zn)`d-(Q`DFf5Y0h(Taoq%SmmWPaY1G!GHLYBi4qQzLVCrW5c)L?reTu@e z?o^M@yCUY-|NA*rFX+B?63?WZopKX=X1<>+V_EF!_kGUs{b_$@+sxR%U|YdAY3PPEb7@Z@lZ!lEUzK=U1F! z8W*~L9Jsf7!VR7oif=faHk?)1SMacjuf!|y|D=C;>8e~7PbW^=uh8NCQHbAj9ea`Y zv^C#PA9C$pC*~8I?OJeG;fzeU@;Uq6cdr(+)P38!D>UwM*R7A+*Znzbx$j2jYo9f$ zH_JkQpJJOVsB+UgFVHTmAFQ}slPkXW2(?yL#_osj3nN?xxGJs|Geg-fpfLL%l-cLuK4{_54|;l z?|0u8brDpa8EVvY$1HYDxJ=}x-4@FAjZOPK`S{OOE0oLKe6y_jrrnpO+d@7413_4ht)+U!>Q z__ybCJ^vFYCN7>6bTVeH>1@N~Wm@wURE}2%>Sk>07gUK%t>44CpzQa#-Iwl*SUM~` z#x1 zC=B@7H8r$?ar@fX-+k{&HyWM1y7sw#gol;=zm`e*yWD!-b*~M-&v|O=CH+fRym}N) zdI`j6o28Wgd*8R)?JI}Tp~yz(cD`43kJwLicyS)$ zy?S>+{DudTnGc?L{C^i?az(80YuNh8*Vm%;yyx%x=ry5G_?UOBdylA}>BN_5Q@q30 zMlFqB#;c|5v1w<7h}*{88yg&%-#4{#-4}7>+F@-SykBF=2E{)GYr9=z0*#k#vw6vK zZ{LqcJJy}cuPU5;rO#L8?3YYqm0f8)I#FA0?2I}4#oMuF;iAi@W*L>v$|`%o@cQ0H`vJZRqj_3Oeuj)sS9=Xmv_-mykHbE_i~v*IsXVrA;s1 zV7bnBS7%GPxn-};8a}bqJ(myPdUC2N&@bmj!Lu)!bKBNEZ+RB6I`VOh!DczP2`T=W z$IpHWYjD`@bF(N`g>Q>v>}Px*6uuio7!aW5a1l>YrWfo0NN5AoCbUn+kT zGyP|4Jk`FYc#ZR-E2d{FAAdFf!tH%VCXMl8h)}PB=8|sL+3DLpKR+54LT5ue(Kd@8ne{#o;StaqI zFVc6+SfzSGO(SjM`Rt!jrV9_2Y-B3gsBm`c+#FuE$$wG1$rA+D)yKTwd2qrrjzeE` zE^lm)v1M)kYk$_P&`x#D6H`VlrnS@OEBXqxIQn|AnaXmD>HG-&Cw#p2-sE~d%Xvj_ zXJ}T=wX5CrrD$$iq~Uj7^T^K|50njQw(^e%|b4|6w{45Q4v1n%3^nZ z&6phTe5%`|Io1KY@$gUhb5&Dw&XXcUNqn z7p*_|eAq)FbL z2<9)VLRWkJ`}1?E&5kJfomB$ejy#Fp0?Wz+Ss87PFPhM`FXg0A<@J{jH_0<8oO3JF zQ%TAyKQqIyN^sxoE3dAuo|#oFjx=SnZb;3;HD(IP=9Q{Zreq zY(D#v4_YlU$AdQXyPs?IIFskdm$r5XUtB(SJKO1_MwmmpEQU+!DxRKp0FCgnPh&a3 zlg|6rRbA!W;_H6KO%h7ik~S>hkyK!Mos<$RV^p zloI;kM1%_WpXKxGeoft_Hff8A`J!zcFC)cPIC}~ycPNH79rWAgy1?#pe(rSr_-l`> z*LZ47H9Op-aL2VqSjOADQ>G|pSBYm{sj@ETq?Wy`AD0Q#Px_-PBx*SMkFQ-=Lc7Mf zRQcn&iH5nm!+M$zd=uZk>tUN=SiyOxMAx7mg)1`-m#|3fU=Wi0nRMcw>g(y}m;d1U zR4}oboqt;4<71gem417qeevx7QvO8UKTobzD=b=kA_QJtQ)HUj zRkQGm=#sdWkg7QEmwK9CYS>&J%D=g?a`HTW!RD<_^HO5|A8ek#;;Qqb6B9}d?sX`B z5L#iyTc&LN=T=xvqN{+tb>mTu&{b3JeO>9|a+9UV#nrXYF=(L^tL&9G^Iy!$3|fD0 zskeBj6KEtjN?J?6IQ`t3=hs#QI=jkUTJFDIC2`h^5o!L;nAWo z<$jUx=;#}qZa z1oY&BJz}j&U-3$rTxg8hk`cJ~_h!Qdh5c6L@7Az9oU>zx#apYRhO0ysIVL&j$RxV% z;Qm--}cLdFYoWimu_4Un=a4d__Bqu{{ZvW zw?~wBgm$=mNG<5O(foOX$KPLHgKsK465=pTJvC)Ptj@a1kB?M?Zj|0xdiz~%*X1=VGUsJ7Nmgewt?cutG7hZoZ3Qtck);+BpFS1Ukf6n18 z2EQApE2VxgjG z^nGWX*U7bc9W^br6XZDbGh~05H(Lihxh1de#~7Dt_#xtfoqp9>!+Y9SR`u*z|6j)W z!-qriKCjs~|NU^7-^)y`K}Y=bgk=q$Fr5-W-xTtH{ zj8c_#2b|_u6gr6uM{?LyeOaN$Z4k(0sSvtCJ*h{bEyQ0WMva3Za$W27NEWyAZN`=xr2dFyu-rN2CKzL}BSzCpAc$SA`i)`c z#YL@iY^%dqB_}W@9XLPNI{f#NU@vaL9RXfNmi6c6Sb9wp)eg&;YdN)5;DorZWZr!) zb5n88waV_3PQHFG<(TIn@ao9vX}a3R>F1_AI@+BrYo)r8!&2d^^G)63D;(XYvTU8S zE%&yTs3eHOsr<~?l{W+cA?9PH9=j`6SP8Ctysf<`_OX`FV&f~8ZQ!yx~jP3hW#_``Q0@Nk-of-$K{BWg6D<>VJsCBKW|X&n7``i)k87HA9fgT<~l9g z5Xr}tw8P_EyG7i`xy2t^cV-vxrTr?~>h{3Ot-mtJ=+5MeyfbQqLbuEi>C}=k-0^$f zey{cS_By)>)Y;d0i;2(N#xK@!%y4s?`@yL0rL*p&<&+=Pe3Ex}*VMe$EVJt9(%HwkQEXVy8sGI;rywr*+pH@=rSCLK|bRkT_o_UPuC(+}Rc za?PuHrK!GmSH$1H3Fcwf3g=6nIm7X3ZyVFTb$2I;1{)+_HGh53^+120NJ06x-tMNm z5sm3-JmDOxWw<`Xsr^p&2>h|{=?;^FId>8w3bwR5InO$C_|PP^(p}Rd4t`hJ5+dw8 zizQ2$!|(F?r(tGA?`yjDsA@}Hs__#O7Q0e^C#Q;YTC<3-ce(kJ%J6P?{SU{O-u?Xi zy#DHA8ScX-daq>#n42OFPEmZcifiwm^aLgK&9zV5e-_1bi0GwmcN1{lbfzFtaf6ls zTad%7+f!e{=e?gy3twNmZ~ysQUw_wd>o+U<3b52qX?$y3a`KL<@${a1(xST`+&1EN z`tV$Qdc_w@n};tROZ6yRKe{{ID5;%CQpvXZ+mwro-Lrj9+}N0G%6d# zRXD@@`&k*q1G7xCzgSxS+vhUxhP!okc5K4+a$+Z&uima7Ef# zi>aomdJS)*l~T#+X}ZCS6#qErBqbHuPfmV(tatmBILXyQdRDtKCn;#mUNEU6hhO}# zg8IJ)?FWwtS1V|+NB(GJg&s&<-lJ)mA$0V1g2hR%4=f3+jvq#q4Pt9k}j8_JAhgc+^g}jf9 z=4$nMv9tL36`{nr8!zqHvr;fddS1uLe@g@+j>hl*SGn?AMCnd_@350K@nY)EvvjXE zX8&IQ|KHwhFB4-GrhFex;{*w5omW+z=dZAdNJTarQ{|ba;x<8rp}f_)_}A|D6aTPs zd2M{8x+G)cqm_KE-7Y8h&NMn*oadw*B3+(-$IGNZu+y*Cq3+5O_h11PuSI(G_1oS| z()?UI$@n_+N+FL$|K7|0)8M|dCT@ip8&4r``OAbzK#XRaci(mGp+N#~gU1DmQ88y16bIW>u92)g7z{TN8Vhm|gfjDO7 zyZ_HUIDMAjH{BaN+vDA*?@(MB?c~&yX3h}pY2LKNQ#MxT-uC--)u*2<;P=RS@0QJC z$iln6?nKl5vw10@kC#pSCfAv1?KXj9v&sC8-i#NnrY<}i&AWbKHfylkgbpRnbz(1HA5m+(ye-bm*6uR>eO z>~-HZ2g`*yC*xn(18Ptq7W;UzXMSjlXZq?>vOv+}-=Cko3KM5-IHCOV{gR!ZGdx&6 zt-W$#25aYsS*526C!SvD@#@9J#ckRPTxJ#}@0ztU&ChLu$5g{6g+I@DxH^(NSdv6{ zM7jwmpST+LHAGTM$gx#5Z@J(RjwBYtCW#&eH-Tml$Dm2Vk;hFyx#J*6Lc&p`hE3^K z$=Ouv;%8gTo)|VsD9uw4csM(MU*TGbZyq)K|6SU7`thy9PaYk8|73#ox24fX?H@-i z-xzW7=NILNRXg;;e(eA8Xop?;|Cg8JV{;!RvluSnY?@Onw0yl~;x4tbQ6BGi?7Ou7 zzr#w&;ArVZn-U}KYzhucd~rWK?(@z$Hibc*43&K{c8i$BHpy6(c(q{)v^J#Vx!qIBMBPg_`BxT628a`8k@Gm-$ZL z^;P=BC(-jSO}A!V_Pe$=USHO#Y?^KL_ZL5#+4!fXPuH8g>+7r2M?5D#xwO>VO~6^I z!!hRZJkh)d&V2h#Gpy))6=r~ zzqo6KOnRv7ep2oFti*=RdN!B#9pp&jsBQ{~-gs^5dNJ+5pjq29mWC}1e7tN^@pU~( z!=fcyGOk9c`Oj2ZdTQF_nd|s%rBi<0u8oWhsJmhMb*E17GQY`TeI9qKzfIEfFPZ%J zxBZ04>i$xWJP-W^?#*Z1o_#$}(yC;~m#)`~FYmG6am=>n-J6@mDc|Po+>~`StMd2S z@)EP|SszTZuf@##_BZI9wf2@Pk&^=#AAj+Cj#cTYrV{5{3LME?bIP)1r|bV;A@=CC zaeB!qvG1KfShjaXYBT-nxBnNx{N??f`##S%^&R?J`}$f?T}dJPlLxbU71+E@H%=|V zOvoD#CWBJBBPf|GcN}ba>|=2*;nHF?+bn~RS;FhhB7QSx*C!Z6Fv~WB*4eqRIKJEU zdR@!AySuYl{MYR}C~)$}gJyovsy}<-C+Do+`*d`7PhP+O-!0K4Z;T|Aq$+~e@B6jt z$%%>1pPrtcKB3RUR!hrED{PHMzs;wPg8~;D*q3@uP2zQt(HFWjRU`0G#k)H@Rcn8J z;gmE^Gm%h|k~B*3I59;t*lA5K(l$4Z=jEteI>6_u5hRaI5h)zvjMHMO<1b#-<1_4N%64ULVBO-)VB&CM+> zEv>DsZEbDs?d=^M9i5$>U0q$>-QB&ty?uRs{r&wDCQO((apI&&lO|7|JY~w1sZ*y; zn>KCw^yxEZ%$PZI=B!z>X3w5IXU?3tbLY;RH*fy@`3n{-Sh#TEqD6}qFJ8Q4$&#f@ zmo8hjY{iNdD_5>uwQAMs)vMR6S+jQS+I8#JtzW->!-fqTH*VatY18J-o40J)vUTg$ zZQHhO-@bjvjvYI9?%cI&*Y4fB_w3oTckkYP`}XbMzyH920|yTtJap*L;lqcI9656I z=+R@xjvYUK{KSb9Cr_R{b?VgV)2GjzIdk^x*>mU4oj-s6!i5VLFJ8QK>C)xPm#CC@-W zpTB(h^7ZT2@87@w{Q2|OuV24^|Nism&;S4b)7K|%VqjnpDhcune){z3CsZI7xOgW6 z1K$Qu7srr_TW{}X)`UKt%U)nLw|0)-@tfAk%eR#sVQpL_7II8UOUoeSTPll4WQw?> zgUgmC(Is12udyyYp)`SI)BWQ2mgmdP+5WDYey28ml7mxMiIrLYbJqqgCue~Zwr4(9 zAD5o={<-D(&wu9E&#Qjdz*ztH>;A&(egC$uuT4E*Z=Ziv+}D91VIH7Q8=sYP?x{PuTL=U`Tq<4%q&6>d54 zK0o4na>5NMq0-9_{sufwRW>rl`d_~H!Nz+rmI_C=%{+3FL zmcR4<`o$S5?RS>Go;bg`pa0tDh0X3I;yoSv6XRZ#$DWzt$Zwi2`|H7iU+MYtE=^hU zd-v13XBu+L^T^wjx?dYax%+y7VJE&i@M=i;_P->)AQFgoU z>HBs#eG9j7c`!{jEX3mDyNmn6(_GDSx%}&1WL&6tdv3Ry#QU7c`ty6-rONtcHkx|G zY*18cS-9-YamH!N0w*2?Is^OXTf#u z^Xi2ik2|;(_ViEWxqKnOSZPLqhQtvWH-W?s12=)>nHolGYBWzw--5ZG|!j1vkt3K|XzFurKx735yA zY}vkV9+US!-|jj;|4?|4^SxXD9ajlwSO6DZ4f-^e4;{nxSs)63@Lk z?mq98>xWp9c_Ld3zs+5Hn=?hRyF*(c{dd$3Nx>c#`$HTj)8C(Q+W)Nl&jntALzN-H zmrd?A@f@5}8I)-GFStE1QY?8}p#3^mSA8WJCcD0;5!;d!_pn>fTK9U^O2Y{SQRQbI zbN}hTneo(T{&}y~&zn@Nlnhub1;W2>IT)HH{`Aj2vGkIsg5g<{&zSA@4YyXFxk0)DYN=C8RsNlg zI;XQP_B)TNz=S7Uk4jb|0J`$R<(Kcm6Ls02{u9;YHyN# zZQ7zbdRb;nc$2HC*0Fu*1))hz5vP_f+LK(E$jb8jy*|(0?_2FY&X~9$AXHnRN3lJ! zkD(>vgwqkG1Bwlnd_N2rTAW*)r|$Zbq_g1Fs$|plS$Z$n7oPvRH9+;t_Nw(;S>|PC zG?_cacYk1dn;po}8URLjJZjfUC#63(JYAvq{#R6Yfn9^bYiE{Z9?R=a=XS4eWx2Rk zfXQZ+X7{2j=eC4%nocc-4=h@C7>lzB9A^}F_>uPH#Kv=*R%Xh1>`0Jy;aI`hEV{Ns z<%kdK!2+KLTA-vqb@BYt^6gq`NgU!D&MZ%Ap6yszy7cX}pk>VLr*3YN53xD&y!1%Y z_x#=Ui>;l6&$FHqP&~NNU!~V2cU6S`7R#Rz3ycqi{p&E%40};hULIC%(e}Ja_1I|( z)!h>2i?+@T61^{WrhV=NUTrz0D?gK}R!lK!a??F9=W^z4uYI8wGfjkhFMV`c=Ir6N zbPAVN{ifzDL&<Sbip# z+SYFtVwrciuEBuqpUMeMk*b&3&==GMp<$2{1 zVI7P8Kb|bt&ssFUTzN_Eud_Xw8Ee$M%APOY{9V_)scR|2b;pv#C-?LF_3M@QX72y` z<;ZRGD|x5aNE*pzoyeVV<`(DsUf;esWmV6jwcFqAOuhY!^Y^>z@*hVe-kW)pJ$qpK zKhCuHW4gY+^v=!Ir)HhqET;4No~1yRUNc9*G41zu|IX~;T>8JJ_RpMk)@FO`avwjQ zZ&%*0ypu;L?t8_S?At5mmfKc7KmK)l|K6v|XQ#6q=aJf^{b-xzqBpmf|2TO3)IQzb zeJ>84HT5YDoe^8R<7nw>v2+%N2~0H_S=|Z}yk47*zIw^vl-GP=(L^VW7BG5ptX*M$ z!yWF%nxOApo{|YXq8tC~vk4rT$9dhn+17al|n;BTmwTmzi=wuzF+mt-2S)w#x%?FPb*b-gsuE^?cJ?6_jkE^Ue#I46>H)0 zBI@|!Eu!45P74FhC2!Lgm=bBM^ySQ=SBcH?oVs_+YCnGT{Jp%s_{xr#|F_&UuR6p0 z+ey6d&sAz` z$^X7>Rj+oi|M_odRvgDI)U~Z}r(yN)I_Jwp`y`^zh-|XW1!H)dw<$X?0B}4_gdwD@h`KVJ+&(Fe5ZTK^$?r4ZC{M%yW1TP z9!#8l{ongP@7GI5*r&hls=oK*+eP~Wz+Y#EpEM@cmC}qu|HGxAG*5TEnEA^ z=buTOS10Yu?dah5T$A!rEX?&}nCzm{H=MfkqE_j~e(!a)I5lO{%Mz>UcGpzCl%_xD zJhsO{Krup~;*9W_O)JL0FKrj0!*p5 z%{YqeTiV<2<(A#CS5h(lf197@*Uon$k0g$M7R!Dr%v7MP^8Lk`cz^jh74?7EPS>U0 zss7k(AJeDzH+5n7>etPJ7R5VQUkI&tcdKnlQMcdodSB_QH%Gs}yJb@Hbx-qQasQi7 zVqUqpwyYM>S(R=juuA@;xb2tEOZq2h-mlKS6Z3yndi%Nm9~QDkUwBf;%_lwGM%4RJ zXlG04bDwaH1q}a>Zmf}4OcpD9zq|D4hqH&%wW`DZ-Ci$M|M9M8qj&8WiG!;@r#SLh zUJ&M+bozDN7dB0szxu`RB7Pj)yZZgSy|srX3GQCD_V2&VefL`@$KKzaaWL8|=lCA; za&7(d7GnPs4n? zd9FI~2E^%{3pq0B_y64=<@_kWPv+nO} z={AT_xE#gdbl&v$oyh#@Sq0nb!hTOwH2$tH{naPy+uO@(N5p(e=E>XkZv0i?qY^hG zQ$OW%uIkCl@ssCT{8nEU|C8OQnnhw~>c8@f$=TsLHR(EXMuti;b@ALrAFuhC%|1J= z>wvf3a_>^!Fx}$!M_zOb?~<3@k@e-<%GbNecIE*C%I(<;JcziaT(&wDzfY%S0jCif--&elw zY8N>3v+DfP{Vsch6j&-w%={kor*TDHo2n?U;sxc_Lk|P=IonIxltpJ^7W z8=aPl!^QKz#o!1pOtue=L zYH0Gyf^e$a*{cYnO>dAC;Jco5Ue;HL!}FHGbpbt%?ee(L78Ezj&a-N7 zuzq|MUJ@uc_*5S=s{jaO9FfcGMc)I$ztaD0e0stmiz_b7W literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/newprojectdialog/image/style-error.png b/share/qtcreator/qmldesigner/newprojectdialog/image/style-error.png new file mode 100644 index 0000000000000000000000000000000000000000..aeb03a574ed4dae6ea2122bb598c7806d20db008 GIT binary patch literal 1310 zcmeAS@N?(olHy`uVBq!ia0y~yU|7t+z;J_unSp^}L-^ti3=E7*0(?ST4}t*$0|O%? zBNG!7Gcz*_3kxeND;padJ3BiE2L~r7CpR}Y4-XG7FE2kozo4L?kdTnDu&{`Th^VNj zxVX54goKool(e+8jEsz|tgM`zoPvUaqN1X*va*VbimIxrnwpxHmX@}*wvLXDuCA`W zzP^EhfuW(Hk&%(Hv9XDXiK(fng@uKsrKPpCwVj=vgM)*kqob3Ple4q4o12@vySs;n zho`5fkB^V9udlzqe_&u>P*6}vNJwaCXhcLrWMpJiR8(|ybWBW4Y;0^|Vq#KKQgU)~ zYHDg)T3SX%Ms{{~etv#oVPR2GQE_o`X=!OiMMY(0WmQ#Gb#--peSKqNV^dR8b8~Y` zOG{f@TW4oyS65eecXv-uPj7E;e}Dgk2@@txoH%LHq{)*fPnj}h`t<2DX3Us5bLQ;X zv**m2Gk5OX`Sa&5Sg>H>!i9?$FJ7`_$swQBY1)oa$QS-W=a zx^?R|Y}l}IF1vhZu{TIuTbtax#U42@xQZh^?JpC_S~9H@h&VkcihraQVKnAEL~Me zNhvVmaoCskfFiMgUhQ7{&P#2-V)yIaR%1(Z=;d#|?b4~S#IW}9^Z+OA3CEu7yzlZd z(B<)THTI2mtr>qp9xFUMtF@qT!xV%?$ zR^ct%U9L%8X>+vAj&v-Nygyy?(MDgB$3-^;w6BYt*->>tp!=EVnHd&29Xpk|(tNf` zEc&7~!?5``@2)Dz}fBnH$bJX8bK>?L|rBb34o*=N>h#v!2p= zS@rNS?R64@;SP^8`iy&cwH6faJ>bk4_J z$0L~2bG}IQFOt0fw4!JEg`T-`i%Oa#gNM?XhWnf)^^+xo zr^Y3nlbN=$zTIe>)|A5J_0xA$bDplqZa1zopr04)tUg#Z8m literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/newprojectdialog/image/style-fusion.png b/share/qtcreator/qmldesigner/newprojectdialog/image/style-fusion.png new file mode 100644 index 0000000000000000000000000000000000000000..882256b30d48596d171bc48eb14b33d135a312d0 GIT binary patch literal 9161 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 DaLU~g literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/newprojectdialog/image/style-material_dark.png b/share/qtcreator/qmldesigner/newprojectdialog/image/style-material_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..53247a422fdd8c56355e7a2d5d616054de54e448 GIT binary patch literal 9703 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 M)78&qol`;+0E$dF2LJ#7 literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/newprojectdialog/image/style-material_light.png b/share/qtcreator/qmldesigner/newprojectdialog/image/style-material_light.png new file mode 100644 index 0000000000000000000000000000000000000000..63c6b7b79f0d38d099bd9d7132d63d9be9694af8 GIT binary patch literal 10683 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 C*%yca literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/newprojectdialog/image/style-universal_dark.png b/share/qtcreator/qmldesigner/newprojectdialog/image/style-universal_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..fc21300336ea48e5d43acc825a6e4563a780aac8 GIT binary patch literal 9786 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 literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/newprojectdialog/image/style-universal_light.png b/share/qtcreator/qmldesigner/newprojectdialog/image/style-universal_light.png new file mode 100644 index 0000000000000000000000000000000000000000..735219f0bb68983bf48e63d2d6ce57b33ddd3793 GIT binary patch literal 10742 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 literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/newprojectdialog/image/style-universal_system.png b/share/qtcreator/qmldesigner/newprojectdialog/image/style-universal_system.png new file mode 100644 index 0000000000000000000000000000000000000000..fc21300336ea48e5d43acc825a6e4563a780aac8 GIT binary patch literal 9786 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 literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml new file mode 100644 index 00000000000..c7ed3ec8d64 --- /dev/null +++ b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml @@ -0,0 +1,453 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick.Window +import QtQuick.Controls + +import QtQuick +import QtQuick.Layouts +import StudioControls as SC +import StudioTheme as StudioTheme + +Item { + width: DialogValues.detailsPaneWidth + + Component.onCompleted: { + dialogBox.detailsLoaded = true; + } + + Component.onDestruction: { + dialogBox.detailsLoaded = false; + } + + Rectangle { + color: DialogValues.darkPaneColor + anchors.fill: parent + + Item { + x: DialogValues.detailsPanePadding // left padding + width: parent.width - DialogValues.detailsPanePadding * 2 // right padding + + Column { + anchors.fill: parent + spacing: DialogValues.defaultPadding + + Text { + text: qsTr("Details") + width: parent.width; + font.weight: Font.DemiBold + font.pixelSize: DialogValues.paneTitlePixelSize + lineHeight: DialogValues.paneTitleLineHeight + lineHeightMode: Text.FixedHeight + color: DialogValues.textColor + } + + SC.TextField { + id: projectNameTextField + actionIndicatorVisible: false + translationIndicatorVisible: false + text: dialogBox.projectName + width: parent.width + color: DialogValues.textColor + selectByMouse: true + + font.pixelSize: DialogValues.paneTitlePixelSize + } + + Binding { + target: dialogBox + property: "projectName" + value: projectNameTextField.text + } + + Item { width: parent.width; height: DialogValues.narrowSpacing(11) } + + RowLayout { // Project location + width: parent.width + + SC.TextField { + Layout.fillWidth: true + id: projectLocationTextField + actionIndicatorVisible: false + translationIndicatorVisible: false + text: dialogBox.projectLocation + color: DialogValues.textColor + selectByMouse: true + font.pixelSize: DialogValues.defaultPixelSize + } + + Binding { + target: dialogBox + property: "projectLocation" + value: projectLocationTextField.text + } + + SC.AbstractButton { + implicitWidth: 30 + iconSize: 20 + visible: true + buttonIcon: "…" + iconFont: StudioTheme.Constants.font + + onClicked: { + var newLocation = dialogBox.chooseProjectLocation() + if (newLocation) + projectLocationTextField.text = newLocation + } + } // SC.AbstractButton + } // Project location RowLayout + + Item { width: parent.width; height: DialogValues.narrowSpacing(7) } + + RowLayout { // StatusMessage + width: parent.width + spacing: 0 + + Image { + id: statusIcon + asynchronous: false + } + + Text { + id: statusMessage + text: dialogBox.statusMessage + font.pixelSize: DialogValues.defaultPixelSize + lineHeight: DialogValues.defaultLineHeight + lineHeightMode: Text.FixedHeight + color: DialogValues.textColor + wrapMode: Text.Wrap + elide: Text.ElideRight + maximumLineCount: 3 + Layout.fillWidth: true + + states: [ + State { + name: "warning" + when: dialogBox.statusType === "warning" + PropertyChanges { + target: statusMessage + color: DialogValues.textWarning + } + PropertyChanges { + target: statusIcon + source: "image://newprojectdialog_library/status-warning" + } + }, + + State { + name: "error" + when: dialogBox.statusType === "error" + PropertyChanges { + target: statusMessage + color: DialogValues.textError + } + PropertyChanges { + target: statusIcon + source: "image://newprojectdialog_library/status-error" + } + } + ] + } // Text + } // RowLayout + + SC.CheckBox { + id: defaultLocationCheckbox + actionIndicatorVisible: false + text: qsTr("Use as default project location") + checked: false + font.pixelSize: DialogValues.defaultPixelSize + } + + Binding { + target: dialogBox + property: "saveAsDefaultLocation" + value: defaultLocationCheckbox.checked + } + + Rectangle { width: parent.width; height: 1; color: DialogValues.dividerlineColor } + + SC.ComboBox { // Screen Size ComboBox + id: screenSizeComboBox + actionIndicatorVisible: false + currentIndex: 1 + model: screenSizeModel + textRole: "display" + width: parent.width + font.pixelSize: DialogValues.defaultPixelSize + + onActivated: (index) => { + // NOTE: item 0 is activated when the screenSizeModel is reset + dialogBox.setScreenSizeIndex(index); + + var r = screenSizeModel.screenSizes(index); + widthTextField.text = r.width; + heightTextField.text = r.height; + } + + Connections { + target: screenSizeModel + function onModelReset() { + screenSizeComboBox.activated(screenSizeComboBox.currentIndex) + } + } + } // Screen Size ComboBox + + GridLayout { // orientation + width + height + width: parent.width + height: 85 + + columns: 4 + rows: 2 + + columnSpacing: 10 + rowSpacing: 10 + + // header items + Text { + text: qsTr("Width") + font.pixelSize: DialogValues.defaultPixelSize + lineHeight: DialogValues.defaultLineHeight + lineHeightMode: Text.FixedHeight + color: DialogValues.textColor + } + + Text { + text: qsTr("Height") + font.pixelSize: DialogValues.defaultPixelSize + lineHeight: DialogValues.defaultLineHeight + lineHeightMode: Text.FixedHeight + color: DialogValues.textColor + } + + Item { Layout.fillWidth: true } + + Text { + text: qsTr("Orientation") + font.pixelSize: DialogValues.defaultPixelSize + lineHeight: DialogValues.defaultLineHeight + lineHeightMode: Text.FixedHeight + color: DialogValues.textColor + } + + // content items + SC.TextField { + id: widthTextField + actionIndicatorVisible: false + translationIndicatorVisible: false + implicitWidth: 50 + color: DialogValues.textColor + selectByMouse: true + validator: IntValidator { bottom: 1; top: 100000; } + font.pixelSize: DialogValues.defaultPixelSize + + onTextChanged: { + var height = heightTextField.text ? parseInt(heightTextField.text) : 0 + var width = text ? parseInt(text) : 0 + + if (width >= height) + orientationButton.setHorizontal() + else + orientationButton.setVertical() + } + } // Width Text Field + + Binding { + target: dialogBox + property: "customWidth" + value: widthTextField.text + } + + SC.TextField { + id: heightTextField + actionIndicatorVisible: false + translationIndicatorVisible: false + implicitWidth: 50 + color: DialogValues.textColor + selectByMouse: true + validator: IntValidator { bottom: 1; top: 100000; } + font.pixelSize: DialogValues.defaultPixelSize + + onTextChanged: { + var height = text ? parseInt(text) : 0 + var width = widthTextField.text ? parseInt(widthTextField.text) : 0 + + if (width >= height) + orientationButton.setHorizontal() + else + orientationButton.setVertical() + } + } // Height Text Field + + Binding { + target: dialogBox + property: "customHeight" + value: heightTextField.text + } + + Item { Layout.fillWidth: true } + + Button { + id: orientationButton + implicitWidth: 100 + implicitHeight: 50 + + checked: false + hoverEnabled: false + background: Rectangle { + width: parent.width + height: parent.height + color: "transparent" + + Row { + Item { + width: orientationButton.width / 2 + height: orientationButton.height + Rectangle { + id: horizontalBar + color: "white" + width: parent.width + height: orientationButton.height / 2 + anchors.verticalCenter: parent.verticalCenter + } + } + + Item { + width: orientationButton.width / 4 + height: orientationButton.height + } + + Rectangle { + id: verticalBar + width: orientationButton.width / 4 + height: orientationButton.height + color: "white" + } + } + } + + onClicked: { + if (widthTextField.text && heightTextField.text) { + [widthTextField.text, heightTextField.text] = [heightTextField.text, widthTextField.text]; + + checked = !checked + } + } + + function setHorizontal() { + checked = false + horizontalBar.color = DialogValues.textColorInteraction + verticalBar.color = "white" + } + + function setVertical() { + checked = true + horizontalBar.color = "white" + verticalBar.color = DialogValues.textColorInteraction + } + } // Orientation button + + } // GridLayout: orientation + width + height + + Rectangle { width: parent.width; height: 1; color: DialogValues.dividerlineColor } + + SC.Section { + width: parent.width + caption: qsTr("Advanced") + captionPixelSize: DialogValues.defaultPixelSize + captionColor: DialogValues.darkPaneColor + captionTextColor: DialogValues.textColor + leftPadding: 0 + expanded: true + visible: dialogBox.haveVirtualKeyboard || dialogBox.haveTargetQtVersion + + Column { + spacing: DialogValues.defaultPadding + width: parent.width + + /* We need a spacer of -10 in order to have actual 18px spacing between + * section bottom and the checkbox. Otherwise, with Column spacing set to + * 18, without a spacer, the default space to the first item would be 10, + * for some reason. */ + Item { width: parent.width; height: -10 } + + SC.CheckBox { + id: useQtVirtualKeyboard + actionIndicatorVisible: false + text: qsTr("Use Qt Virtual Keyboard") + font.pixelSize: DialogValues.defaultPixelSize + checked: dialogBox.useVirtualKeyboard + visible: dialogBox.haveVirtualKeyboard + } + + RowLayout { // Target Qt Version + width: parent.width + visible: dialogBox.haveTargetQtVersion + + Text { + text: "Target Qt Version:" + font.pixelSize: DialogValues.defaultPixelSize + lineHeight: DialogValues.defaultLineHeight + lineHeightMode: Text.FixedHeight + color: DialogValues.textColor + } + + SC.ComboBox { // Target Qt Version ComboBox + id: qtVersionComboBox + actionIndicatorVisible: false + implicitWidth: 70 + Layout.alignment: Qt.AlignRight + currentIndex: 1 + font.pixelSize: DialogValues.defaultPixelSize + + model: ListModel { + ListElement { + name: "Qt 5" + } + ListElement { + name: "Qt 6" + } + } + + width: parent.width + + onActivated: (index) => { + dialogBox.setTargetQtVersion(index) + } + } // Target Qt Version ComboBox + + } // RowLayout + } // Column + } // SC.Section + + Binding { + target: dialogBox + property: "useVirtualKeyboard" + value: useQtVirtualKeyboard.checked + } + + } // Column + } // Item + } +} diff --git a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/DialogValues.qml b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/DialogValues.qml new file mode 100644 index 00000000000..5bcfadaa785 --- /dev/null +++ b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/DialogValues.qml @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +pragma Singleton +import QtQml + +import StudioTheme as StudioTheme + +QtObject { + readonly property int dialogWidth: 1522 + readonly property int dialogHeight: 994 + readonly property int projectViewMinimumWidth: 600 + readonly property int projectViewMinimumHeight: projectViewHeight + readonly property int dialogContentHeight: projectViewHeight + 300 // i.e. dialog without header and footer + readonly property int loadedPanesWidth: detailsPaneWidth + stylesPaneWidth + readonly property int detailsPaneWidth: 330 + detailsPanePadding * 2 + readonly property int stylesPaneWidth: styleImageWidth + stylesPanePadding * 2 + styleImageBorderWidth * 2 // i.e. 240px + readonly property int detailsPanePadding: 18 + readonly property int stylesPanePadding: 18 + readonly property int defaultPadding: 18 + + readonly property int styleImageWidth: 200 + readonly property int styleImageBorderWidth: 2 + readonly property int footerHeight: 73 + readonly property int projectItemWidth: 144 + readonly property int projectItemHeight: 144 + readonly property int projectViewHeight: projectItemHeight * 2 + projectViewHeaderHeight + readonly property int projectViewHeaderHeight: 38 + + readonly property int dialogButtonWidth: 100 + + readonly property int loadedPanesHeight: dialogContentHeight + readonly property int detailsPaneHeight: dialogContentHeight + + readonly property string darkPaneColor: StudioTheme.Values.themeBackgroundColorNormal + readonly property string lightPaneColor: StudioTheme.Values.themeBackgroundColorAlternate + + readonly property string textColor: StudioTheme.Values.themeTabInactiveText + readonly property string textColorInteraction: StudioTheme.Values.themeInteraction + readonly property string dividerlineColor: StudioTheme.Values.themeTextColorDisabled + readonly property string textError: StudioTheme.Values.themeError + readonly property string textWarning: StudioTheme.Values.themeWarning + + readonly property real defaultPixelSize: 14 + readonly property real defaultLineHeight: 21 + readonly property real viewHeaderPixelSize: 16 + readonly property real viewHeaderLineHeight: 24 + readonly property real paneTitlePixelSize: 18 + readonly property real paneTitleLineHeight: 27 + + // for a spacer item + function narrowSpacing(value, layoutSpacing = DialogValues.defaultPadding) { + /* e.g. if we want narrow spacing value = 11, then for the spacer item residing inside a + layout with spacing set to 18, we need to realize the fact that by adding the spacer + item, we already have 18 * 2 spacing added implicitly (i.e. spacing before the spacer + item and spacing after it). So we have to subtract 2 x layout spacing before setting + our own, narrower, spacing. + */ + return -layoutSpacing -layoutSpacing + value + } +} diff --git a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/NewProjectView.qml b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/NewProjectView.qml new file mode 100644 index 00000000000..049b955420c --- /dev/null +++ b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/NewProjectView.qml @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick.Window +import QtQuick.Controls + +import QtQuick +import QtQuick.Layouts +import StudioTheme as StudioTheme + +GridView { + id: projectView + + required property Item loader + + header: TabBar { + id: tabBar + width: parent.width + height: DialogValues.projectViewHeaderHeight + + background: Rectangle { + color: DialogValues.lightPaneColor + } + + Repeater { + model: categoryModel + + TabButton { + padding: 0 + + width: headerText.contentWidth + 36 + + background: Item { // TabButton background + Rectangle { // bottom strip + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + width: headerText.contentWidth + height: 6 + radius: 10 + color: tabBar.currentIndex === index ? DialogValues.textColorInteraction + : "transparent" + } + } // TabButton background + + implicitHeight: headerText.height + DialogValues.defaultPadding - 7 + + contentItem: Item { + Column { + anchors.fill: parent + + Text { + id: headerText + color: tabBar.currentIndex == index ? DialogValues.textColorInteraction + : DialogValues.textColor + text: name + width: parent.width + font.weight: Font.DemiBold + font.pixelSize: DialogValues.viewHeaderPixelSize + lineHeight: DialogValues.viewHeaderLineHeight + lineHeightMode: Text.FixedHeight + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + Item { width: parent.width; height: 11; } + } // Column + } // Item + + onClicked: { + projectModel.setPage(index) + projectView.currentIndex = 0 + projectView.currentIndexChanged() + } + } // TabButton + } // Repeater + } // Header - TabBar + + cellWidth: DialogValues.projectItemWidth + cellHeight: DialogValues.projectItemHeight + + boundsBehavior: Flickable.StopAtBounds + + children: [ + Rectangle { + color: DialogValues.darkPaneColor + anchors.fill: parent + z: -1 + } + ] + + model: projectModel + + // called by onModelReset and when user clicks on an item, or when the header item is changed. + onCurrentIndexChanged: { + dialogBox.selectedProject = projectView.currentIndex + var source = dialogBox.currentProjectQmlPath() + loader.source = source + } + + Connections { + target: projectModel + + // called when data is set (setWizardFactories) + function onModelReset() { + currentIndex = 0 + currentIndexChanged() + } + } + + delegate: ItemDelegate { + id: delegate + + width: DialogValues.projectItemWidth + height: DialogValues.projectItemHeight + + function fontIconCode(index) { + var code = projectModel.fontIconCode(index) + return code ? code : StudioTheme.Constants.wizardsUnknown + } + + Column { + width: parent.width + height: parent.height + + Label { + id: projectTypeIcon + text: fontIconCode(index) + color: DialogValues.textColor + width: parent.width + height: DialogValues.projectItemHeight / 2 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignBottom + renderType: Text.NativeRendering + font.pixelSize: 65 + font.family: StudioTheme.Constants.iconFont.family + } + + Text { + id: projectTypeLabel + color: DialogValues.textColor + + text: name + font.pixelSize: DialogValues.defaultPixelSize + lineHeight: DialogValues.defaultLineHeight + lineHeightMode: Text.FixedHeight + width: parent.width + height: DialogValues.projectItemHeight / 2 + wrapMode: Text.Wrap + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignTop + } + } // Column + + MouseArea { + anchors.fill: parent + onClicked: { + delegate.GridView.view.currentIndex = index + } + } + + states: [ + State { + when: delegate.GridView.isCurrentItem + PropertyChanges { + target: projectTypeLabel + color: DialogValues.textColorInteraction + } + + PropertyChanges { + target: projectTypeIcon + color: DialogValues.textColorInteraction + } + } // State + ] + } // ItemDelegate +} // GridView diff --git a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Styles.qml b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Styles.qml new file mode 100644 index 00000000000..a1ef6696f3a --- /dev/null +++ b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Styles.qml @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick.Window +import QtQuick.Controls + +import QtQuick +import QtQuick.Layouts + +import StudioControls as SC + +Item { + width: DialogValues.stylesPaneWidth + + Component.onCompleted: { + dialogBox.stylesLoaded = true; + + /* + * TODO: roleNames is called before the backend model (in the proxy class StyleModel) is + * loaded, which may be buggy. But I found no way to force refresh the model, so as to + * reload the role names afterwards. setting styleModel.dynamicRoles doesn't appear to do + * anything. + */ + } + + Component.onDestruction: { + dialogBox.stylesLoaded = false; + } + + Rectangle { + color: DialogValues.lightPaneColor + anchors.fill: parent + + Item { + x: DialogValues.stylesPanePadding // left padding + width: parent.width - DialogValues.stylesPanePadding * 2 // right padding + height: parent.height + + ColumnLayout { + anchors.fill: parent + spacing: 5 + + Text { + id: styleTitleText + text: qsTr("Style") + width: parent.width; + font.weight: Font.DemiBold + font.pixelSize: DialogValues.paneTitlePixelSize + lineHeight: DialogValues.paneTitleLineHeight + lineHeightMode: Text.FixedHeight + color: DialogValues.textColor + + function refresh() { + text = qsTr("Style") + " (" + styleModel.rowCount() + ")" + } + } + + SC.ComboBox { // Style Filter ComboBox + actionIndicatorVisible: false + currentIndex: 0 + textRole: "text" + valueRole: "value" + font.pixelSize: DialogValues.defaultPixelSize + + model: ListModel { + ListElement { text: qsTr("All"); value: "all" } + ListElement { text: qsTr("Light"); value: "light" } + ListElement { text: qsTr("Dark"); value: "dark" } + } + + implicitWidth: parent.width + + onActivated: (index) => { + styleModel.filter(currentValue.toLowerCase()); + styleTitleText.refresh(); + } + } // Style Filter ComboBox + + ListView { + id: stylesList + Layout.fillWidth: true + Layout.fillHeight: true + clip: true + model: styleModel + + focus: true + boundsBehavior: Flickable.StopAtBounds + + highlightFollowsCurrentItem: false + + onCurrentIndexChanged: { + if (styleModel.rowCount() > 0) + dialogBox.styleIndex = stylesList.currentIndex; + } + + delegate: ItemDelegate { + id: delegateId + height: styleImage.height + DialogValues.styleImageBorderWidth + styleText.height + 1 + width: stylesList.width + + Rectangle { + anchors.fill: parent + color: DialogValues.lightPaneColor + + Column { + spacing: 0 + anchors.fill: parent + + Rectangle { + border.color: index == stylesList.currentIndex ? DialogValues.textColorInteraction : "transparent" + border.width: index == stylesList.currentIndex ? DialogValues.styleImageBorderWidth : 0 + color: "transparent" + width: parent.width + height: parent.height - styleText.height + + Image { + id: styleImage + asynchronous: false + source: "image://newprojectdialog_library/" + styleModel.iconId(model.index) + width: 200 + height: 262 + x: DialogValues.styleImageBorderWidth + y: DialogValues.styleImageBorderWidth + } + } // Rectangle + + Text { + id: styleText + text: model.display + font.pixelSize: DialogValues.defaultPixelSize + lineHeight: DialogValues.defaultLineHeight + height: 18 + lineHeightMode: Text.FixedHeight + horizontalAlignment: Text.AlignHCenter + width: parent.width + color: DialogValues.textColor + } + } // Column + } // Rectangle + + MouseArea { + anchors.fill: parent + onClicked: { + stylesList.currentIndex = index + } + } + } + + Connections { + target: styleModel + function onModelReset() { + stylesList.currentIndex = dialogBox.styleIndex; + stylesList.currentIndexChanged(); + styleTitleText.refresh(); + } + } + } // ListView + } // ColumnLayout + } // Parent Item + } // Rectangle +} diff --git a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/qmldir b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/qmldir new file mode 100644 index 00000000000..d7c1562164f --- /dev/null +++ b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/qmldir @@ -0,0 +1,4 @@ +singleton DialogValues 1.0 DialogValues.qml +Details 1.0 Details.qml +Styles 1.0 Styles.qml +NewProjectView 1.0 NewProjectView.qml diff --git a/share/qtcreator/qmldesigner/newprojectdialog/imports/ProjectType/DefaultProject.qml b/share/qtcreator/qmldesigner/newprojectdialog/imports/ProjectType/DefaultProject.qml new file mode 100644 index 00000000000..05bc5fff042 --- /dev/null +++ b/share/qtcreator/qmldesigner/newprojectdialog/imports/ProjectType/DefaultProject.qml @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick.Window +import QtQuick.Controls + +import QtQuick +import QtQuick.Layouts + +import newprojectdialog + +Item { + anchors.fill: parent + + Row { + anchors.fill: parent + + Details { + height: parent.height + } + + Styles { + height: parent.height + } + } +} diff --git a/share/qtcreator/qmldesigner/newprojectdialog/imports/ProjectType/qmldir b/share/qtcreator/qmldesigner/newprojectdialog/imports/ProjectType/qmldir new file mode 100644 index 00000000000..6f3c69e9d42 --- /dev/null +++ b/share/qtcreator/qmldesigner/newprojectdialog/imports/ProjectType/qmldir @@ -0,0 +1 @@ +DefaultProject 1.0 DefaultProject.qml diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Section.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Section.qml index 23ee5615700..a6dbcfe11da 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Section.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/Section.qml @@ -30,6 +30,9 @@ import StudioTheme 1.0 as StudioTheme Item { id: section property alias caption: label.text + property alias captionPixelSize: label.font.pixelSize + property alias captionColor: header.color + property alias captionTextColor: label.color property int leftPadding: 8 property int topPadding: 4 property int rightPadding: 0 diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index e61b8ab4338..800cd3b775d 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -57,7 +57,6 @@ add_subdirectory(scxmleditor) add_subdirectory(subversion) add_subdirectory(compilationdatabaseprojectmanager) add_subdirectory(languageclient) -add_subdirectory(studiowelcome) # Level 6: add_subdirectory(cmakeprojectmanager) @@ -93,6 +92,7 @@ if (WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(qmldesigner_builddir ${PROJECT_BINARY_DIR}/qmldsgnr) endif() add_subdirectory(qmldesigner ${qmldesigner_builddir}) +add_subdirectory(studiowelcome) add_subdirectory(qnx) add_subdirectory(webassembly) add_subdirectory(mcusupport) diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index c118533426a..82a715f59e2 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -165,9 +166,13 @@ namespace Core { // The Core Singleton static ICore *m_instance = nullptr; static MainWindow *m_mainwindow = nullptr; -std::function ICore::m_newDialogFactory = [](QWidget *parent) { + +static NewDialog *defaultDialogFactory(QWidget *parent) +{ return new NewDialogWidget(parent); -}; +} + +static std::function m_newDialogFactory = defaultDialogFactory; /*! Returns the pointer to the instance. Only use for connecting to signals. @@ -253,7 +258,23 @@ void ICore::showNewItemDialog(const QString &title, const QVariantMap &extraVariables) { QTC_ASSERT(!isNewItemDialogRunning(), return); - NewDialog *newDialog = ICore::m_newDialogFactory(dialogParent()); + + /* This is a workaround for QDS: In QDS, we currently have a "New Project" dialog box but we do + * not also have a "New file" dialog box (yet). Therefore, when requested to add a new file, we + * need to use QtCreator's dialog box. In QDS, if `factories` contains project wizard factories + * (even though it may contain file wizard factories as well), then we consider it to be a + * request for "New Project". Otherwise, if we only have file wizard factories, we defer to + * QtCreator's dialog and request "New File" + */ + auto dialogFactory = m_newDialogFactory; + bool haveProjectWizards = Utils::anyOf(factories, [](IWizardFactory *f) { + return f->kind() == IWizardFactory::ProjectWizard; + }); + + if (!haveProjectWizards) + dialogFactory = defaultDialogFactory; + + NewDialog *newDialog = dialogFactory(dialogParent()); connect(newDialog->widget(), &QObject::destroyed, m_instance, &ICore::updateNewItemDialogState); newDialog->setWizardFactories(factories, defaultLocation, extraVariables); newDialog->setWindowTitle(title); diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index 589cf49765e..93cf5c71f17 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -180,8 +180,6 @@ public: private: static void updateNewItemDialogState(); - - static std::function m_newDialogFactory; }; } // namespace Core diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 59ba9b08abc..83d5a257a57 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -102,6 +102,14 @@ namespace Internal { enum { debugMainWindow = 0 }; +static bool isQtDesignStudio() +{ + QSettings *settings = Core::ICore::settings(); + const QString qdsStandaloneEntry = "QML/Designer/StandAloneMode"; //entry from qml settings + + return settings->value(qdsStandaloneEntry, false).toBool(); +} + MainWindow::MainWindow() : AppMainWindow() , m_coreImpl(new ICore(this)) @@ -519,7 +527,8 @@ void MainWindow::registerDefaultActions() // New File Action QIcon icon = QIcon::fromTheme(QLatin1String("document-new"), Utils::Icons::NEWFILE.icon()); - m_newAction = new QAction(icon, tr("&New File or Project..."), this); + QString newActionText = isQtDesignStudio() ? tr("&New Project...") : tr("&New File or Project..."); + m_newAction = new QAction(icon, newActionText, this); cmd = ActionManager::registerAction(m_newAction, Constants::NEW); cmd->setDefaultKeySequence(QKeySequence::New); mfile->addAction(cmd, Constants::G_FILE_NEW); diff --git a/src/plugins/projectexplorer/jsonwizard/jsonprojectpage.h b/src/plugins/projectexplorer/jsonwizard/jsonprojectpage.h index b362b988945..ced13950aac 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonprojectpage.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonprojectpage.h @@ -25,12 +25,13 @@ #pragma once +#include "../projectexplorer_export.h" #include namespace ProjectExplorer { // Documentation inside. -class JsonProjectPage : public Utils::ProjectIntroPage +class PROJECTEXPLORER_EXPORT JsonProjectPage : public Utils::ProjectIntroPage { Q_OBJECT diff --git a/src/plugins/studiowelcome/CMakeLists.txt b/src/plugins/studiowelcome/CMakeLists.txt index 2ae3bdcc9a0..3d290d6486b 100644 --- a/src/plugins/studiowelcome/CMakeLists.txt +++ b/src/plugins/studiowelcome/CMakeLists.txt @@ -1,12 +1,20 @@ add_qtc_plugin(StudioWelcome CONDITION TARGET Qt5::QuickWidgets DEPENDS Qt5::QuickWidgets - PLUGIN_DEPENDS Core ProjectExplorer QtSupport + PLUGIN_DEPENDS Core ProjectExplorer QtSupport QmlDesigner DEFINES STUDIO_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/qml/" SOURCES studiowelcomeplugin.cpp studiowelcomeplugin.h + newprojectdialogimageprovider.cpp newprojectdialogimageprovider.h + newprojectmodel.cpp newprojectmodel.h examplecheckout.cpp examplecheckout.h studiowelcome_global.h + qdsnewdialog.cpp qdsnewdialog.h + wizardfactories.cpp wizardfactories.h + createproject.cpp createproject.h + wizardhandler.cpp wizardhandler.h + screensizemodel.h + stylemodel.h stylemodel.cpp studiowelcome.qrc "${PROJECT_SOURCE_DIR}/src/share/3rdparty/studiofonts/studiofonts.qrc" EXTRA_TRANSLATIONS diff --git a/src/plugins/studiowelcome/createproject.cpp b/src/plugins/studiowelcome/createproject.cpp new file mode 100644 index 00000000000..1b6dd93e9d7 --- /dev/null +++ b/src/plugins/studiowelcome/createproject.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "createproject.h" + +#include + +#include +#include + +using namespace StudioWelcome; + +void CreateProject::execute() +{ + m_wizard.run([&](QWizardPage *page) { + if (auto *p = dynamic_cast(page)) + processProjectPage(p); + else if (auto *p = dynamic_cast(page)) + processFieldPage(p); + }); +} + +void CreateProject::processProjectPage(ProjectExplorer::JsonProjectPage *page) +{ + page->setProjectName(m_projectName); + page->setFilePath(m_projectLocation); + + page->setUseAsDefaultPath(m_saveAsDefaultLocation); + page->fieldsUpdated(); +} + +void CreateProject::processFieldPage(ProjectExplorer::JsonFieldPage *page) +{ + if (page->jsonField("ScreenFactor")) + m_wizard.setScreenSizeIndex(m_screenSizeIndex); + + if (page->jsonField("TargetQtVersion") && m_targetQtVersionIndex > -1) + m_wizard.setTargetQtVersionIndex(m_targetQtVersionIndex); + + if (page->jsonField("ControlsStyle")) + m_wizard.setStyleIndex(m_styleIndex); + + if (page->jsonField("UseVirtualKeyboard")) + m_wizard.setUseVirtualKeyboard(m_useVirtualKeyboard); + + auto widthField = dynamic_cast(page->jsonField("CustomScreenWidth")); + auto heightField = dynamic_cast(page->jsonField("CustomScreenHeight")); + + if (widthField && heightField) { + if (!m_customWidth.isEmpty() && !m_customHeight.isEmpty()) { + widthField->setText(m_customWidth); + heightField->setText(m_customHeight); + } + } +} diff --git a/src/plugins/studiowelcome/createproject.h b/src/plugins/studiowelcome/createproject.h new file mode 100644 index 00000000000..9709bbee30e --- /dev/null +++ b/src/plugins/studiowelcome/createproject.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "wizardhandler.h" + +namespace ProjectExplorer { +class JsonProjectPage; +} + +namespace StudioWelcome { + +class CreateProject +{ +public: + CreateProject(WizardHandler &wizard): m_wizard{wizard} {} + + CreateProject &withName(const QString &name) { m_projectName = name; return *this; } + CreateProject &atLocation(const Utils::FilePath &location) { m_projectLocation = location; return *this; } + CreateProject &withScreenSizes(int screenSizeIndex, const QString &customWidth, const QString &customHeight) + { + m_screenSizeIndex = screenSizeIndex; + m_customWidth = customWidth; + m_customHeight = customHeight; + return *this; + } + + CreateProject &withStyle(int styleIndex) { m_styleIndex = styleIndex; return *this; } + CreateProject &useQtVirtualKeyboard(bool value) { m_useVirtualKeyboard = value; return *this; } + CreateProject &saveAsDefaultLocation(bool value) { m_saveAsDefaultLocation = value; return *this; } + CreateProject &withTargetQtVersion(int targetQtVersionIndex) + { m_targetQtVersionIndex = targetQtVersionIndex; return *this; } + + void execute(); + +private: + void processProjectPage(ProjectExplorer::JsonProjectPage *page); + void processFieldPage(ProjectExplorer::JsonFieldPage *page); + +private: + WizardHandler &m_wizard; + + QString m_projectName; + Utils::FilePath m_projectLocation; + int m_screenSizeIndex = -1; + QString m_customWidth; + QString m_customHeight; + int m_styleIndex = -1; + bool m_useVirtualKeyboard = false; + bool m_saveAsDefaultLocation = false; + int m_targetQtVersionIndex = -1; +}; + +} // StudioWelcome diff --git a/src/plugins/studiowelcome/newprojectdialogimageprovider.cpp b/src/plugins/studiowelcome/newprojectdialogimageprovider.cpp new file mode 100644 index 00000000000..2c7e454f5b0 --- /dev/null +++ b/src/plugins/studiowelcome/newprojectdialogimageprovider.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "newprojectdialogimageprovider.h" + +#include +#include +#include + +namespace StudioWelcome { + +namespace Internal { + +NewProjectDialogImageProvider::NewProjectDialogImageProvider() + : QQuickImageProvider(QQuickImageProvider::Pixmap) +{} + +QPixmap NewProjectDialogImageProvider::invalidStyleIcon() +{ + QString iconPath = Core::ICore::resourcePath("qmldesigner/newprojectdialog/image/style-error.png").toString(); + QString file = Utils::StyleHelper::dpiSpecificImageFile(iconPath); + return QPixmap{file}; +} + +QPixmap NewProjectDialogImageProvider::requestStatusPixmap(const QString &id, QSize *size, const QSize &requestedSize) +{ + QPixmap pixmap; + + if (id == "status-warning") { + static const QPixmap warning = Utils::Icons::WARNING.pixmap(); + pixmap = warning; + } else if (id == "status-error") { + static const QPixmap error = Utils::Icons::CRITICAL.pixmap(); + pixmap = error; + } + + if (requestedSize.isValid()) + return pixmap.scaled(requestedSize); + + return pixmap; +} + +QPixmap NewProjectDialogImageProvider::requestStylePixmap(const QString &id, QSize *size, const QSize &requestedSize) +{ + QString realPath = Core::ICore::resourcePath("qmldesigner/newprojectdialog/image/" + id).toString(); + + QPixmap pixmap{realPath}; + + if (size) { + size->setWidth(pixmap.width()); + size->setHeight(pixmap.height()); + } + + if (pixmap.isNull()) + pixmap = invalidStyleIcon(); + + if (requestedSize.isValid()) + return pixmap.scaled(requestedSize); + + return pixmap; +} + +QPixmap NewProjectDialogImageProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) +{ + if (id.startsWith("style-")) + return requestStylePixmap(id, size, requestedSize); + + if (id.startsWith("status-")) + return requestStatusPixmap(id, size, requestedSize); + + return QPixmap{}; +} + +} // namespace Internal + +} // namespace StudioWelcome + diff --git a/src/plugins/studiowelcome/newprojectdialogimageprovider.h b/src/plugins/studiowelcome/newprojectdialogimageprovider.h new file mode 100644 index 00000000000..f149d082c21 --- /dev/null +++ b/src/plugins/studiowelcome/newprojectdialogimageprovider.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +namespace StudioWelcome { + +namespace Internal { + +class NewProjectDialogImageProvider : public QQuickImageProvider +{ +public: + NewProjectDialogImageProvider(); + + QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override; + +private: + QPixmap requestStatusPixmap(const QString &id, QSize *size, const QSize &requestedSize); + QPixmap requestStylePixmap(const QString &id, QSize *size, const QSize &requestedSize); + + static QPixmap invalidStyleIcon(); +}; + +} // namespace Internal + +} // namespace StudioWelcome diff --git a/src/plugins/studiowelcome/newprojectmodel.cpp b/src/plugins/studiowelcome/newprojectmodel.cpp new file mode 100644 index 00000000000..07589a4c041 --- /dev/null +++ b/src/plugins/studiowelcome/newprojectmodel.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "newprojectmodel.h" + +using namespace StudioWelcome; + +/****************** BaseNewProjectModel ******************/ + +BaseNewProjectModel::BaseNewProjectModel(QObject *parent) + : QAbstractListModel(parent) +{} + +QHash BaseNewProjectModel::roleNames() const +{ + QHash roleNames; + roleNames[Qt::UserRole] = "name"; + return roleNames; +} + +void BaseNewProjectModel::setProjects(const ProjectsByCategory &projectsByCategory) +{ + beginResetModel(); + + for (auto &[id, category] : projectsByCategory) { + m_categories.push_back(category.name); + m_projects.push_back(category.items); + } + + endResetModel(); +} + +/****************** NewProjectCategoryModel ******************/ + +NewProjectCategoryModel::NewProjectCategoryModel(QObject *parent) + : BaseNewProjectModel(parent) +{} + +int NewProjectCategoryModel::rowCount(const QModelIndex &) const +{ + return static_cast(categories().size()); +} + +QVariant NewProjectCategoryModel::data(const QModelIndex &index, int role) const +{ + return categories().at(index.row()); +} + +/****************** NewProjectModel ******************/ + +NewProjectModel::NewProjectModel(QObject *parent) + : BaseNewProjectModel(parent) +{} + +int NewProjectModel::rowCount(const QModelIndex &) const +{ + if (projects().empty()) + return 0; + + return static_cast(projectsOfCurrentCategory().size()); +} + +QVariant NewProjectModel::data(const QModelIndex &index, int role) const +{ + return projectsOfCurrentCategory().at(index.row()).name; +} + +void NewProjectModel::setPage(int index) +{ + beginResetModel(); + + m_page = static_cast(index); + + endResetModel(); +} + +QString NewProjectModel::fontIconCode(int index) const +{ + Utils::optional projectItem = project(index); + if (!projectItem) + return ""; + + return projectItem->fontIconCode; +} diff --git a/src/plugins/studiowelcome/newprojectmodel.h b/src/plugins/studiowelcome/newprojectmodel.h new file mode 100644 index 00000000000..9e6cdd157b9 --- /dev/null +++ b/src/plugins/studiowelcome/newprojectmodel.h @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include +#include + +#include +#include + +namespace Utils { +class Wizard; +} + +namespace StudioWelcome { + +struct ProjectItem +{ + QString name; + QString categoryId; + QString description; + QUrl qmlPath; + QString fontIconCode; + std::function create; +}; + +inline QDebug &operator<<(QDebug &d, const ProjectItem &item) +{ + d << "name=" << item.name; + d << "; category = " << item.categoryId; + + return d; +} + +struct ProjectCategory +{ + QString id; + QString name; + std::vector items; +}; + +inline QDebug &operator<<(QDebug &d, const ProjectCategory &cat) +{ + d << "id=" << cat.id; + d << "; name=" << cat.name; + d << "; items=" << cat.items; + + return d; +} + +using ProjectsByCategory = std::map; + +/****************** BaseNewProjectModel ******************/ + +class BaseNewProjectModel : public QAbstractListModel +{ + using ProjectItems = std::vector>; + using Categories = std::vector; + +public: + explicit BaseNewProjectModel(QObject *parent = nullptr); + QHash roleNames() const override; + void setProjects(const ProjectsByCategory &projects); + +protected: + const ProjectItems &projects() const { return m_projects; } + const Categories &categories() const { return m_categories; } + +private: + ProjectItems m_projects; + Categories m_categories; +}; + +/****************** NewProjectCategoryModel ******************/ + +class NewProjectCategoryModel : public BaseNewProjectModel +{ +public: + explicit NewProjectCategoryModel(QObject *parent = nullptr); + int rowCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role) const override; +}; + +/****************** NewProjectModel ******************/ + +class NewProjectModel : public BaseNewProjectModel +{ + Q_OBJECT +public: + explicit NewProjectModel(QObject *parent = nullptr); + int rowCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role) const override; + + Q_INVOKABLE void setPage(int index); // called from QML when view's header item is clicked + Q_INVOKABLE QString fontIconCode(int index) const; + + int page() const { return static_cast(m_page); } + + Utils::optional project(size_t selection) const + { + if (projects().empty()) + return {}; + + if (m_page < projects().size()) { + const std::vector projectsOfCategory = projects().at(m_page); + if (selection < projectsOfCategory.size()) + return projects().at(m_page).at(selection); + } + return {}; + } + + bool empty() const { return projects().empty(); } + +private: + const std::vector projectsOfCurrentCategory() const + { return projects().at(m_page); } + +private: + size_t m_page = 0; +}; + +} // namespace StudioWelcome diff --git a/src/plugins/studiowelcome/qdsnewdialog.cpp b/src/plugins/studiowelcome/qdsnewdialog.cpp new file mode 100644 index 00000000000..b031a083bcf --- /dev/null +++ b/src/plugins/studiowelcome/qdsnewdialog.cpp @@ -0,0 +1,343 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include +#include + +#include "qdsnewdialog.h" + +#include +#include +#include +#include + +#include "createproject.h" +#include "wizardfactories.h" +#include "newprojectdialogimageprovider.h" + +using namespace StudioWelcome; + +namespace { + +/* + * NOTE: copied from projectexplorer/jsonwizard/jsonprojectpage.h +*/ +QString uniqueProjectName(const QString &path) +{ + const QDir pathDir(path); + //: File path suggestion for a new project. If you choose + //: to translate it, make sure it is a valid path name without blanks + //: and using only ascii chars. + const QString prefix = QObject::tr("UntitledProject"); + + QString name = prefix; + int i = 0; + while (pathDir.exists(name)) + name = prefix + QString::number(++i); + + return name; +} + +} + +/***********************/ + +QdsNewDialog::QdsNewDialog(QWidget *parent) + : m_dialog{new QQuickWidget(parent)} + , m_categoryModel{new NewProjectCategoryModel(this)} + , m_projectModel{new NewProjectModel(this)} + , m_screenSizeModel{new ScreenSizeModel(this)} + , m_styleModel{new StyleModel(this)} +{ + setParent(m_dialog); + + m_dialog->rootContext()->setContextProperties(QVector{ + {{"categoryModel"}, QVariant::fromValue(m_categoryModel.data())}, + {{"projectModel"}, QVariant::fromValue(m_projectModel.data())}, + {{"screenSizeModel"}, QVariant::fromValue(m_screenSizeModel.data())}, + {{"styleModel"}, QVariant::fromValue(m_styleModel.data())}, + {{"dialogBox"}, QVariant::fromValue(this)}, + }); + + m_dialog->setResizeMode(QQuickWidget::SizeRootObjectToView); // SizeViewToRootObject + m_dialog->engine()->addImageProvider(QStringLiteral("newprojectdialog_library"), + new Internal::NewProjectDialogImageProvider()); + QmlDesigner::Theme::setupTheme(m_dialog->engine()); + m_dialog->engine()->addImportPath(Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources/imports").toString()); + m_dialog->engine()->addImportPath(Core::ICore::resourcePath("qmldesigner/newprojectdialog/imports").toString()); + QString sourcesPath = qmlPath(); + m_dialog->setSource(QUrl::fromLocalFile(sourcesPath)); + + m_dialog->setWindowModality(Qt::ApplicationModal); + m_dialog->setWindowFlags(Qt::Dialog); + m_dialog->setAttribute(Qt::WA_DeleteOnClose); + m_dialog->setMinimumSize(1155, 804); + + QObject::connect(&m_wizard, &WizardHandler::deletingWizard, this, &QdsNewDialog::onDeletingWizard); + QObject::connect(&m_wizard, &WizardHandler::wizardCreated, this, &QdsNewDialog::onWizardCreated); + QObject::connect(&m_wizard, &WizardHandler::statusMessageChanged, this, &QdsNewDialog::onStatusMessageChanged); + QObject::connect(&m_wizard, &WizardHandler::projectCanBeCreated, this, &QdsNewDialog::onProjectCanBeCreatedChanged); + + QObject::connect(&m_wizard, &WizardHandler::wizardCreationFailed, this, [this]() { + QMessageBox::critical(m_dialog, "New project", "Failed to initialize data"); + reject(); + delete this; + }); + + QObject::connect(m_styleModel.data(), &StyleModel::modelAboutToBeReset, this, [this]() { + this->m_qmlStyleIndex = -1; + }); +} + +void QdsNewDialog::onDeletingWizard() +{ + m_screenSizeModel->setBackendModel(nullptr); + m_qmlScreenSizeIndex = -1; + m_screenSizeModel->reset(); + + m_styleModel->setBackendModel(nullptr); + m_qmlStyleIndex = -1; +} + +void QdsNewDialog::setProjectName(const QString &name) +{ + m_qmlProjectName = name; + m_wizard.setProjectName(name); +} + +void QdsNewDialog::setProjectLocation(const QString &location) +{ + m_qmlProjectLocation = Utils::FilePath::fromString(QDir::toNativeSeparators(location)); + m_wizard.setProjectLocation(m_qmlProjectLocation); +} + +void QdsNewDialog::onStatusMessageChanged(Utils::InfoLabel::InfoType type, const QString &message) +{ + switch (type) { + case Utils::InfoLabel::Warning: + m_qmlStatusType = "warning"; + break; + case Utils::InfoLabel::Error: + m_qmlStatusType = "error"; + break; + default: + m_qmlStatusType = "normal"; + break; + } + + emit statusTypeChanged(); + + m_qmlStatusMessage = message; + emit statusMessageChanged(); +} + +void QdsNewDialog::onProjectCanBeCreatedChanged(bool value) +{ + if (m_qmlFieldsValid == value) + return; + + m_qmlFieldsValid = value; + + emit fieldsValidChanged(); +} + +void QdsNewDialog::onWizardCreated(QStandardItemModel *screenSizeModel, QStandardItemModel *styleModel) +{ + m_screenSizeModel->setBackendModel(screenSizeModel); + m_styleModel->setBackendModel(styleModel); + + if (m_qmlDetailsLoaded) { + m_screenSizeModel->reset(); + emit haveVirtualKeyboardChanged(); + emit haveTargetQtVersionChanged(); + + setProjectName(m_qmlProjectName); + setProjectLocation(m_qmlProjectLocation.toString()); + } + + if (m_qmlStylesLoaded) + m_styleModel->reset(); +} + +QString QdsNewDialog::currentProjectQmlPath() const +{ + if (!m_currentProject || m_currentProject->qmlPath.isEmpty()) + return ""; + + return m_currentProject->qmlPath.toString(); +} + +void QdsNewDialog::setScreenSizeIndex(int index) +{ + m_wizard.setScreenSizeIndex(index); + m_qmlScreenSizeIndex = index; +} + +void QdsNewDialog::setTargetQtVersion(int index) +{ + m_wizard.setTargetQtVersionIndex(index); + m_qmlTargetQtVersionIndex = index; +} + +void QdsNewDialog::setStyleIndex(int index) +{ + if (!m_qmlStylesLoaded) + return; + + if (index == -1) { + m_qmlStyleIndex = index; + return; + } + + m_qmlStyleIndex = index; + int actualIndex = m_styleModel->actualIndex(m_qmlStyleIndex); + QTC_ASSERT(actualIndex >= 0, return); + + m_wizard.setStyleIndex(actualIndex); +} + +int QdsNewDialog::getStyleIndex() const +{ + /** + * m_wizard.styleIndex property is the wizard's (backend's) value of the style index. + * The initial value (saved in the wizard.json) is read from there. Any subsequent reads of + * the style index should use m_styleIndex, which is the QML's style index property. Setting + * the style index should update both the m_styleIndex and the backend. In this regard, the + * QdsNewDialog's m_styleIndex acts as some kind of cache. + */ + + if (!m_qmlStylesLoaded) + return -1; + + if (m_qmlStyleIndex == -1) { + int actualIndex = m_wizard.styleIndex(); + // Not nice, get sets the property... m_qmlStyleIndex acts like a cache. + m_qmlStyleIndex = m_styleModel->filteredIndex(actualIndex); + return m_qmlStyleIndex; + } + + return m_styleModel->actualIndex(m_qmlStyleIndex); +} + +void QdsNewDialog::setWizardFactories(QList factories_, + const Utils::FilePath &defaultLocation, + const QVariantMap &) +{ + Utils::Id platform = Utils::Id::fromSetting("Desktop"); + + WizardFactories factories{factories_, m_dialog, platform}; + + m_categoryModel->setProjects(factories.projectsGroupedByCategory()); // calls model reset + m_projectModel->setProjects(factories.projectsGroupedByCategory()); // calls model reset + + if (m_qmlSelectedProject > -1) + setSelectedProject(m_qmlSelectedProject); + + if (factories.empty()) + return; // TODO: some message box? + + const Core::IWizardFactory *first = factories.front(); + Utils::FilePath projectLocation = first->runPath(defaultLocation); + + m_qmlProjectName = uniqueProjectName(projectLocation.toString()); + emit projectNameChanged(); // So that QML knows to update the field + + m_qmlProjectLocation = Utils::FilePath::fromString(QDir::toNativeSeparators(projectLocation.toString())); + emit projectLocationChanged(); // So that QML knows to update the field + + if (m_qmlDetailsLoaded) + m_screenSizeModel->reset(); + + if (m_qmlStylesLoaded) + m_styleModel->reset(); +} + +QString QdsNewDialog::qmlPath() const +{ + return Core::ICore::resourcePath("qmldesigner/newprojectdialog/NewProjectDialog.qml").toString(); +} + +void QdsNewDialog::showDialog() +{ + m_dialog->show(); +} + +bool QdsNewDialog::getHaveVirtualKeyboard() const +{ + return m_wizard.haveVirtualKeyboard(); +} + +bool QdsNewDialog::getHaveTargetQtVersion() const +{ + return m_wizard.haveTargetQtVersion(); +} + +void QdsNewDialog::accept() +{ + CreateProject create{m_wizard}; + + create.withName(m_qmlProjectName) + .atLocation(m_qmlProjectLocation) + .withScreenSizes(m_qmlScreenSizeIndex, m_qmlCustomWidth, m_qmlCustomHeight) + .withStyle(m_qmlStyleIndex) + .useQtVirtualKeyboard(m_qmlUseVirtualKeyboard) + .saveAsDefaultLocation(m_qmlSaveAsDefaultLocation) + .withTargetQtVersion(m_qmlTargetQtVersionIndex) + .execute(); + + m_dialog->close(); +} + +void QdsNewDialog::reject() +{ + m_screenSizeModel->setBackendModel(nullptr); + m_styleModel->setBackendModel(nullptr); + m_wizard.destroyWizard(); + + m_dialog->close(); +} + +QString QdsNewDialog::chooseProjectLocation() +{ + Utils::FilePath newPath = Utils::FileUtils::getExistingDirectory(m_dialog, tr("Choose Directory"), + m_qmlProjectLocation); + + return QDir::toNativeSeparators(newPath.toString()); +} + +void QdsNewDialog::setSelectedProject(int selection) +{ + if (m_qmlSelectedProject != selection || m_projectPage != m_projectModel->page()) { + m_qmlSelectedProject = selection; + + m_currentProject = m_projectModel->project(m_qmlSelectedProject); + if (m_currentProject) { + setProjectDescription(m_currentProject->description); + + m_projectPage = m_projectModel->page(); + m_wizard.reset(m_currentProject.value(), m_qmlSelectedProject, m_qmlProjectLocation); + } + } +} diff --git a/src/plugins/studiowelcome/qdsnewdialog.h b/src/plugins/studiowelcome/qdsnewdialog.h new file mode 100644 index 00000000000..ede50bc97a7 --- /dev/null +++ b/src/plugins/studiowelcome/qdsnewdialog.h @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +#include +#include +#include + +#include "wizardhandler.h" +#include "newprojectmodel.h" +#include "screensizemodel.h" +#include "stylemodel.h" + +QT_BEGIN_NAMESPACE +class QStandardItemModel; +QT_END_NAMESPACE + +namespace StudioWelcome { +class QdsNewDialog : public QObject, public Core::NewDialog +{ + Q_OBJECT + +public: + Q_PROPERTY(int selectedProject MEMBER m_qmlSelectedProject WRITE setSelectedProject) + Q_PROPERTY(QString projectName MEMBER m_qmlProjectName WRITE setProjectName NOTIFY projectNameChanged) + Q_PROPERTY(QString projectLocation MEMBER m_qmlProjectLocation READ projectLocation WRITE setProjectLocation NOTIFY projectLocationChanged) + Q_PROPERTY(QString projectDescription MEMBER m_qmlProjectDescription READ projectDescription WRITE setProjectDescription NOTIFY projectDescriptionChanged) + Q_PROPERTY(QString customWidth MEMBER m_qmlCustomWidth) + Q_PROPERTY(QString customHeight MEMBER m_qmlCustomHeight) + Q_PROPERTY(int styleIndex MEMBER m_qmlStyleIndex READ getStyleIndex WRITE setStyleIndex) + Q_PROPERTY(bool useVirtualKeyboard MEMBER m_qmlUseVirtualKeyboard READ getUseVirtualKeyboard WRITE setUseVirtualKeyboard NOTIFY useVirtualKeyboardChanged) + Q_PROPERTY(bool haveVirtualKeyboard MEMBER m_qmlHaveVirtualKeyboard READ getHaveVirtualKeyboard NOTIFY haveVirtualKeyboardChanged) + Q_PROPERTY(bool haveTargetQtVersion MEMBER m_qmlHaveTargetQtVersion READ getHaveTargetQtVersion NOTIFY haveTargetQtVersionChanged) + Q_PROPERTY(bool saveAsDefaultLocation MEMBER m_qmlSaveAsDefaultLocation WRITE setSaveAsDefaultLocation) + Q_PROPERTY(QString statusMessage MEMBER m_qmlStatusMessage READ getStatusMessage NOTIFY statusMessageChanged) + Q_PROPERTY(QString statusType MEMBER m_qmlStatusType READ getStatusType NOTIFY statusTypeChanged) + Q_PROPERTY(bool fieldsValid MEMBER m_qmlFieldsValid READ getFieldsValid NOTIFY fieldsValidChanged) + + Q_PROPERTY(bool detailsLoaded MEMBER m_qmlDetailsLoaded) + Q_PROPERTY(bool stylesLoaded MEMBER m_qmlStylesLoaded) + + Q_INVOKABLE QString currentProjectQmlPath() const; + Q_INVOKABLE void setScreenSizeIndex(int index); // called when ComboBox item is "activated" + Q_INVOKABLE void setTargetQtVersion(int index); + + Q_INVOKABLE QString chooseProjectLocation(); + + explicit QdsNewDialog(QWidget *parent); + + QWidget *widget() override { return m_dialog; } + + void setWizardFactories(QList factories, const Utils::FilePath &defaultLocation, + const QVariantMap &extraVariables) override; + void setWindowTitle(const QString &title) override { m_dialog->setWindowTitle(title); } + void showDialog() override; + void setSelectedProject(int selection); + + void setStyleIndex(int index); + int getStyleIndex() const; + void setUseVirtualKeyboard(bool value) { m_qmlUseVirtualKeyboard = value; } + bool getUseVirtualKeyboard() const { return m_qmlUseVirtualKeyboard; } + + bool getFieldsValid() const { return m_qmlFieldsValid; } + bool getHaveVirtualKeyboard() const; + bool getHaveTargetQtVersion() const; + + void setSaveAsDefaultLocation(bool value) { m_qmlSaveAsDefaultLocation = value; } + + QString getStatusMessage() const { return m_qmlStatusMessage; } + QString getStatusType() const { return m_qmlStatusType; } + +public slots: + void accept(); + void reject(); + +signals: + void projectNameChanged(); + void projectLocationChanged(); + void projectDescriptionChanged(); + void useVirtualKeyboardChanged(); + void haveVirtualKeyboardChanged(); + void haveTargetQtVersionChanged(); + void statusMessageChanged(); + void statusTypeChanged(); + void fieldsValidChanged(); + +private slots: + void onStatusMessageChanged(Utils::InfoLabel::InfoType type, const QString &message); + void onProjectCanBeCreatedChanged(bool value); + +private: + QString qmlPath() const; + + void setProjectName(const QString &name); + void setProjectLocation(const QString &location); + QString projectLocation() const { return m_qmlProjectLocation.toString(); } + + void setProjectDescription(const QString &description) + { + m_qmlProjectDescription = description; + emit projectDescriptionChanged(); + } + + QString projectDescription() const { return m_qmlProjectDescription; } + +private slots: + void onDeletingWizard(); + void onWizardCreated(QStandardItemModel *screenSizeModel, QStandardItemModel *styleModel); + +private: + QQuickWidget *m_dialog = nullptr; + QPointer m_categoryModel; + QPointer m_projectModel; + QPointer m_screenSizeModel; + QPointer m_styleModel; + QString m_qmlProjectName; + Utils::FilePath m_qmlProjectLocation; + QString m_qmlProjectDescription; + int m_qmlSelectedProject = -1; + int m_qmlScreenSizeIndex = -1; + int m_qmlTargetQtVersionIndex = -1; + // m_qmlStyleIndex is like a cache, so it needs to be updated on get() + mutable int m_qmlStyleIndex = -1; + bool m_qmlUseVirtualKeyboard = false; + bool m_qmlHaveVirtualKeyboard = false; + bool m_qmlHaveTargetQtVersion = false; + bool m_qmlSaveAsDefaultLocation = false; + bool m_qmlFieldsValid = false; + QString m_qmlStatusMessage; + QString m_qmlStatusType; + + int m_projectPage = -1; // i.e. the page in the Presets View + + QString m_qmlCustomWidth; + QString m_qmlCustomHeight; + + bool m_qmlDetailsLoaded = false; + bool m_qmlStylesLoaded = false; + + Utils::optional m_currentProject; + + WizardHandler m_wizard; +}; + +} //namespace StudioWelcome diff --git a/src/plugins/studiowelcome/screensizemodel.h b/src/plugins/studiowelcome/screensizemodel.h new file mode 100644 index 00000000000..e01f17295c5 --- /dev/null +++ b/src/plugins/studiowelcome/screensizemodel.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include +#include +#include + +class ScreenSizeModel : public QAbstractListModel +{ + Q_OBJECT + +public: + explicit ScreenSizeModel(QObject *parent = nullptr) + : QAbstractListModel(parent) + {} + + Q_INVOKABLE QSize screenSizes(int index) const + { + constexpr auto invalid = QSize{0, 0}; + if (!m_backendModel) + return invalid; + + auto *item = m_backendModel->item(index, 0); + // Matches strings like "1024 x 768" or "1080 x 1920 (FullHD)" + QRegularExpression re{R"__(^(\d+)\s*x\s*(\d+).*)__"}; + + if (!item) + return invalid; + + auto m = re.match(item->text()); + if (!m.hasMatch()) + return invalid; + + bool ok = false; + int width = m.captured(1).toInt(&ok); + if (!ok) + return invalid; + + int height = m.captured(2).toInt(&ok); + if (!ok) + return invalid; + + return QSize{width, height}; + } + + int rowCount(const QModelIndex &parent = QModelIndex()) const override + { + if (m_backendModel) + return m_backendModel->rowCount(); + + return 0; + } + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override + { + if (m_backendModel) { + auto *item = m_backendModel->item(index.row(), index.column()); + return item->text(); + } + + return ""; + } + + QHash roleNames() const override + { + if (m_backendModel) + return m_backendModel->roleNames(); + + QHash roleNames; + roleNames[Qt::UserRole] = "name"; + return roleNames; + } + + void reset() { + beginResetModel(); + endResetModel(); + } + + void setBackendModel(QStandardItemModel *model) + { + m_backendModel = model; + } + +private: + QStandardItemModel *m_backendModel = nullptr; +}; + diff --git a/src/plugins/studiowelcome/studiowelcome.pro b/src/plugins/studiowelcome/studiowelcome.pro index e2ccee8576f..3cdee86f789 100644 --- a/src/plugins/studiowelcome/studiowelcome.pro +++ b/src/plugins/studiowelcome/studiowelcome.pro @@ -12,10 +12,20 @@ DEFINES += STUDIO_QML_PATH=\\\"$$PWD/qml/\\\" HEADERS += \ studiowelcome_global.h \ studiowelcomeplugin.h \ + newprojectdialogimageprovider.h \ + qdsnewdialog.h \ + wizardfactories.h \ + createproject.h \ + newprojectmodel.h \ examplecheckout.h SOURCES += \ studiowelcomeplugin.cpp \ + qdsnewdialog.cpp \ + wizardfactories.cpp \ + createproject.cpp \ + newprojectdialogimageprovider.cpp \ + newprojectmodel.cpp \ examplecheckout.cpp OTHER_FILES += \ diff --git a/src/plugins/studiowelcome/studiowelcome.qbs b/src/plugins/studiowelcome/studiowelcome.qbs index f2bec88af22..c630d83f01c 100644 --- a/src/plugins/studiowelcome/studiowelcome.qbs +++ b/src/plugins/studiowelcome/studiowelcome.qbs @@ -17,8 +17,18 @@ QtcPlugin { "studiowelcome_global.h", "studiowelcomeplugin.h", "studiowelcomeplugin.cpp", + "qdsnewdialog.cpp", + "qdsnewdialog.h", + "wizardfactories.cpp", + "wizardfactories.h", + "createproject.cpp", + "createproject.h", + "newprojectmodel.cpp", + "newprojectmodel.h", "examplecheckout.h", "examplecheckout.cpp", + "newprojectdialogimageprovider.h", + "newprojectdialogimageprovider.cpp", "studiowelcome.qrc", ] diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.cpp b/src/plugins/studiowelcome/studiowelcomeplugin.cpp index d1195675624..56ef7302842 100644 --- a/src/plugins/studiowelcome/studiowelcomeplugin.cpp +++ b/src/plugins/studiowelcome/studiowelcomeplugin.cpp @@ -26,6 +26,8 @@ #include "studiowelcomeplugin.h" #include "examplecheckout.h" +#include "qdsnewdialog.h" + #include #include #include @@ -368,6 +370,9 @@ void StudioWelcomePlugin::extensionsInitialized() s_view->setSource(QUrl("qrc:/qml/splashscreen/main.qml")); #endif + // disabled by default + Core::ICore::setNewDialogFactory([](QWidget *parent) { return new QdsNewDialog(parent); }); + QTC_ASSERT(s_view->rootObject(), qWarning() << "The StudioWelcomePlugin has a runtime depdendency on " "qt/qtquicktimeline."; diff --git a/src/plugins/studiowelcome/stylemodel.cpp b/src/plugins/studiowelcome/stylemodel.cpp new file mode 100644 index 00000000000..9aee4ff7d32 --- /dev/null +++ b/src/plugins/studiowelcome/stylemodel.cpp @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "stylemodel.h" + +#include "utils/algorithm.h" +#include "utils/qtcassert.h" + +#include + +StyleModel::StyleModel(QObject *parent) + : QAbstractListModel(parent) + , m_backendModel(nullptr) +{} + +QString StyleModel::iconId(int index) const +{ + if (!m_backendModel || index < 0) + return "style-error"; + + auto item = this->m_filteredItems.at(index); + QString styleName = item->text(); + QString id{"style-"}; + id += styleName.toLower().replace(' ', '_') + ".png"; + + return id; +} + +void StyleModel::filter(const QString &what) +{ + if (what.toLower() == "all") + m_filteredItems = this->filterItems(m_items, ""); + else if (what.toLower() == "light") + m_filteredItems = this->filterItems(m_items, "light"); + else if (what.toLower() == "dark") + m_filteredItems = this->filterItems(m_items, "dark"); + else + m_filteredItems.clear(); + + reset(); +} + +StyleModel::Items StyleModel::filterItems(const Items &items, const QString &kind) +{ + if (kind.isEmpty()) + return items; + + return Utils::filtered(items, [&kind](auto *item) { + QString pattern{"\\S "}; + pattern += kind; + + QRegularExpression re{pattern, QRegularExpression::CaseInsensitiveOption}; + return re.match(item->text()).hasMatch(); + }); +} + +int StyleModel::filteredIndex(int actualIndex) +{ + if (actualIndex < 0) + return actualIndex; + + QStandardItem *item = m_items.at(actualIndex); + // TODO: perhaps should add this kind of find to utils/algorithm.h + auto it = std::find(std::cbegin(m_filteredItems), std::cend(m_filteredItems), item); + if (it == std::cend(m_filteredItems)) + return -1; + + return std::distance(std::cbegin(m_filteredItems), it); +} + +int StyleModel::actualIndex(int filteredIndex) +{ + if (filteredIndex < 0) + return filteredIndex; + + QTC_ASSERT(filteredIndex < static_cast(m_filteredItems.size()), return -1); + + QStandardItem *item = m_filteredItems.at(filteredIndex); + auto it = std::find(std::cbegin(m_items), std::cend(m_items), item); + if (it == std::cend(m_items)) + return -1; + + auto result = std::distance(std::cbegin(m_items), it); + QTC_ASSERT(result >= 0, return -1); + QTC_ASSERT(result <= static_cast(m_items.size()), return -1); + + return result; +} + +void StyleModel::setBackendModel(QStandardItemModel *model) +{ + m_backendModel = model; + + if (m_backendModel) { + m_count = model->rowCount(); + m_roles = model->roleNames(); + m_items.clear(); + + for (int i = 0; i < m_count; ++i) + m_items.push_back(model->item(i, 0)); + + m_filteredItems = filterItems(m_items, ""); + } else { + m_count = 0; + m_items.clear(); + m_filteredItems.clear(); + } +} diff --git a/src/plugins/studiowelcome/stylemodel.h b/src/plugins/studiowelcome/stylemodel.h new file mode 100644 index 00000000000..6d6d09620d1 --- /dev/null +++ b/src/plugins/studiowelcome/stylemodel.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include +#include + +class StyleModel : public QAbstractListModel +{ + Q_OBJECT + +private: + using Items = std::vector; + +public: + explicit StyleModel(QObject *parent = nullptr); + + Q_INVOKABLE QString iconId(int index) const; + Q_INVOKABLE void filter(const QString &what = "all"); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override + { + if (m_backendModel) + return static_cast(m_filteredItems.size()); + + return 0; + } + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override + { + if (m_backendModel) { + auto *item = m_filteredItems.at(index.row()); + return item->text(); + } + + return ""; + } + + QHash roleNames() const override + { + if (m_backendModel) + return m_roles; + + /** + * TODO: roleNames is called before the backend model is loaded, which may be buggy. But I + * found no way to force refresh the model, so as to reload the role names afterwards. + */ + + QHash roleNames; + roleNames[Qt::UserRole] = "display"; + return roleNames; + } + + void reset() + { + beginResetModel(); + endResetModel(); + } + + int filteredIndex(int actualIndex); + int actualIndex(int filteredIndex); + void setBackendModel(QStandardItemModel *model); + +private: + static Items filterItems(const Items &items, const QString &kind); + +private: + QStandardItemModel *m_backendModel; + Items m_items, m_filteredItems; + int m_count = -1; + QHash m_roles; +}; + diff --git a/src/plugins/studiowelcome/wizardfactories.cpp b/src/plugins/studiowelcome/wizardfactories.cpp new file mode 100644 index 00000000000..a7cb20b0c62 --- /dev/null +++ b/src/plugins/studiowelcome/wizardfactories.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include +#include +#include + +#include "wizardfactories.h" + +namespace { +// TODO: should be extern, check coreplugin/dialogs/newdialogwidget.cpp +const char BLACKLISTED_CATEGORIES_KEY[] = "Core/NewDialog/BlacklistedCategories"; +} + +using namespace StudioWelcome; + +WizardFactories::WizardFactories(QList &factories, QWidget *wizardParent, const Utils::Id &platform) + : m_wizardParent{wizardParent} + , m_platform{platform} + , m_factories{factories} +{ + QVariant value = Core::ICore::settings()->value(BLACKLISTED_CATEGORIES_KEY); + m_blacklist = Utils::Id::fromStringList(value.toStringList()); + + sortByCategoryAndId(); + filter(); + m_projectItems = makeProjectItemsGroupedByCategory(); +} + +void WizardFactories::sortByCategoryAndId() +{ + Utils::sort(m_factories, [](Core::IWizardFactory *lhs, Core::IWizardFactory *rhs) { + if (lhs->category() == rhs->category()) + return lhs->id().toString() < rhs->id().toString(); + else + return lhs->category() < rhs->category(); + }); +} + +void WizardFactories::filter() +{ + QList acceptedFactories; + // TODO: perhaps I could use Utils::filtered here. + std::copy_if(std::begin(m_factories), std::end(m_factories), std::back_inserter(acceptedFactories), + [&](auto *wizard) { + return wizard->isAvailable(m_platform) + && wizard->kind() == Core::IWizardFactory::ProjectWizard + && !m_blacklist.contains(Utils::Id::fromString(wizard->category())); + }); + + m_factories = acceptedFactories; +} + +ProjectItem WizardFactories::makeProjectItem(Core::IWizardFactory *f, QWidget *parent, + const Utils::Id &platform) +{ + using namespace std::placeholders; + + return { + /*.name =*/f->displayName(), + /*.categoryId =*/f->category(), + /*. description =*/f->description(), + /*.qmlPath =*/f->detailsPageQmlPath(), + /*.fontIconCode =*/f->fontIcondCode(), + /*.create =*/ std::bind(&Core::IWizardFactory::runWizard, f, _1, parent, platform, + QVariantMap(), false), + }; +} + +std::map WizardFactories::makeProjectItemsGroupedByCategory() +{ + QMap categories; + + for (auto *f : std::as_const(m_factories)) { + if (!categories.contains(f->category())) { + categories[f->category()] = { + /*.id =*/ f->category(), + /*.name =*/ f->displayCategory(), + /*.items = */ + { + makeProjectItem(f, m_wizardParent, m_platform), + }, + }; + } else { + auto projectItem = makeProjectItem(f, m_wizardParent, m_platform); + categories[f->category()].items.push_back(projectItem); + } + } + + return categories.toStdMap(); +} diff --git a/src/plugins/studiowelcome/wizardfactories.h b/src/plugins/studiowelcome/wizardfactories.h new file mode 100644 index 00000000000..c41300ff091 --- /dev/null +++ b/src/plugins/studiowelcome/wizardfactories.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "newprojectmodel.h" + +#include + +namespace Core { +class IWizardFactory; +} + +namespace StudioWelcome { + +class WizardFactories +{ +public: + WizardFactories(QList &factories, QWidget *wizardParent, + const Utils::Id &platform); + + const Core::IWizardFactory *front() const { return m_factories.front(); } + const std::map &projectsGroupedByCategory() const + { return m_projectItems; } + + bool empty() const { return m_factories.empty(); } + +private: + void sortByCategoryAndId(); + void filter(); + + ProjectItem makeProjectItem(Core::IWizardFactory *f, QWidget *parent, const Utils::Id &platform); + std::map makeProjectItemsGroupedByCategory(); + +private: + QSet m_blacklist; + QWidget *m_wizardParent; + Utils::Id m_platform; + + QList m_factories; + std::map m_projectItems; +}; + +} // namespace StudioWelcome diff --git a/src/plugins/studiowelcome/wizardhandler.cpp b/src/plugins/studiowelcome/wizardhandler.cpp new file mode 100644 index 00000000000..fce7aa120f9 --- /dev/null +++ b/src/plugins/studiowelcome/wizardhandler.cpp @@ -0,0 +1,249 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include +#include + +#include "wizardhandler.h" + +#include +#include + +#include + +#include "utils/wizard.h" +#include + +using namespace StudioWelcome; + +void WizardHandler::reset(const ProjectItem &projectInfo, int projectSelection, const Utils::FilePath &location) +{ + m_projectItem = projectInfo; + m_projectLocation = location; + m_selectedProject = projectSelection; + + if (!m_wizard) { + setupWizard(); + } else { + QObject::connect(m_wizard, &QObject::destroyed, this, &WizardHandler::onWizardResetting); + + // DON'T SET `m_selectedProject = -1` --- we are switching now to a separate project. + emit deletingWizard(); + + m_wizard->deleteLater(); + } +} + +void WizardHandler::destroyWizard() +{ + emit deletingWizard(); + + m_selectedProject = -1; + m_wizard->deleteLater(); + m_wizard = nullptr; +} + +void WizardHandler::setupWizard() +{ + m_wizard = m_projectItem.create(m_projectLocation); + if (!m_wizard) { + emit wizardCreationFailed(); + return; + } + + initializeProjectPage(m_wizard->page(0)); + initializeFieldsPage(m_wizard->page(1)); + + auto *screenFactorModel = getScreenFactorModel(m_detailsPage); + auto *styleModel = getStyleModel(m_detailsPage); + + emit wizardCreated(screenFactorModel, styleModel); +} + +void WizardHandler::setProjectName(const QString &name) +{ + QTC_ASSERT(m_wizard, return); + + QWizardPage *projectPage = m_wizard->page(0); + auto *jpp = dynamic_cast(projectPage); + QTC_ASSERT(jpp, return); + + jpp->setProjectName(name); +} + +void WizardHandler::setProjectLocation(const Utils::FilePath &location) +{ + QTC_ASSERT(m_wizard, return); + + QWizardPage *projectPage = m_wizard->page(0); + auto *jpp = dynamic_cast(projectPage); + QTC_ASSERT(jpp, return); + + jpp->setFilePath(location); +} + +void WizardHandler::initializeProjectPage(QWizardPage *page) +{ + auto *jpp = dynamic_cast(page); + QTC_ASSERT(jpp, return); + + QObject::connect(jpp, &ProjectExplorer::JsonProjectPage::statusMessageChanged, this, &WizardHandler::statusMessageChanged); + QObject::connect(jpp, &ProjectExplorer::JsonProjectPage::completeChanged, this, &WizardHandler::onProjectIntroCompleteChanged); +} + +void WizardHandler::initializeFieldsPage(QWizardPage *page) +{ + auto fieldsPage = dynamic_cast(page); // required for page->jsonField + QTC_ASSERT(fieldsPage, return); + m_detailsPage = fieldsPage; + + fieldsPage->initializePage(); +} + +void WizardHandler::onProjectIntroCompleteChanged() +{ + auto *page = dynamic_cast(QObject::sender()); + QTC_ASSERT(page, return); + + emit projectCanBeCreated(page->isComplete()); +} + +QStandardItemModel *WizardHandler::getScreenFactorModel(ProjectExplorer::JsonFieldPage *page) +{ + auto *field = page->jsonField("ScreenFactor"); + if (!field) + return nullptr; + + auto *cbfield = dynamic_cast(field); + QTC_ASSERT(cbfield, return nullptr); + + return cbfield->model(); +} + +QStandardItemModel *WizardHandler::getStyleModel(ProjectExplorer::JsonFieldPage *page) +{ + auto *field = page->jsonField("ControlsStyle"); + if (!field) + return nullptr; + + auto *cbfield = dynamic_cast(field); + QTC_ASSERT(cbfield, return nullptr); + + return cbfield->model(); +} + +void WizardHandler::onWizardResetting() +{ + m_wizard = nullptr; + + // if have a wizard request pending => create new wizard + // note: we always have a wizard request pending here, unless the dialogbox was requested to be destroyed. + // if m_selectedProject != -1 => the wizard was destroyed as a result of reset to a different project type + if (m_selectedProject > -1) + setupWizard(); +} + +void WizardHandler::setScreenSizeIndex(int index) +{ + auto *field = m_detailsPage->jsonField("ScreenFactor"); + auto *cbfield = dynamic_cast(field); + QTC_ASSERT(cbfield, return); + + cbfield->selectRow(index); +} + +void WizardHandler::setTargetQtVersionIndex(int index) +{ + auto *field = m_detailsPage->jsonField("TargetQtVersion"); + auto *cbfield = dynamic_cast(field); + QTC_ASSERT(cbfield, return); + + cbfield->selectRow(index); +} + +bool WizardHandler::haveTargetQtVersion() const +{ + return m_wizard->hasField("TargetQtVersion"); +} + +void WizardHandler::setStyleIndex(int index) +{ + auto *field = m_detailsPage->jsonField("ControlsStyle"); + auto *cbfield = dynamic_cast(field); + QTC_ASSERT(cbfield, return); + + cbfield->selectRow(index); +} + +int WizardHandler::styleIndex() const +{ + auto *field = m_detailsPage->jsonField("ControlsStyle"); + auto *cbfield = dynamic_cast(field); + QTC_ASSERT(cbfield, return -1); + + return cbfield->selectedRow(); +} + +void WizardHandler::setUseVirtualKeyboard(bool value) +{ + auto *field = m_detailsPage->jsonField("UseVirtualKeyboard"); + auto *cbfield = dynamic_cast(field); + QTC_ASSERT(cbfield, return); + + cbfield->setChecked(value); +} + +bool WizardHandler::haveVirtualKeyboard() const +{ + return m_wizard->hasField("UseVirtualKeyboard"); +} + +void WizardHandler::run(const std::function &processPage) +{ + m_wizard->restart(); + + int nextId = 0; + do { + QWizardPage *page = m_wizard->currentPage(); + QTC_ASSERT(page, return); + + processPage(page); + + if (!page->validatePage() || !page->isComplete()) { + QMessageBox::warning(m_wizard, "New project", "Could not create the project because fields are invalid"); + return; + } + + nextId = m_wizard->nextId(); + m_wizard->next(); + } while (-1 != nextId); + + m_selectedProject = -1; + + // Note: don't call `emit deletingWizard()` here. + + // Note: QWizard::accept calls QObject::deleteLater on the wizard + m_wizard->accept(); +} diff --git a/src/plugins/studiowelcome/wizardhandler.h b/src/plugins/studiowelcome/wizardhandler.h new file mode 100644 index 00000000000..a828d595f66 --- /dev/null +++ b/src/plugins/studiowelcome/wizardhandler.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "newprojectmodel.h" + +#include +#include + +QT_BEGIN_NAMESPACE +class QWizard; +class QWizardPage; +class QStandardItemModel; +QT_END_NAMESPACE + +namespace ProjectExplorer { +class JsonFieldPage; +} + +namespace StudioWelcome { + +class WizardHandler: public QObject +{ + Q_OBJECT + +public: + //TODO: location should not be needed in reset() -- only when creating the project + void reset(const ProjectItem &projectInfo, int projectSelection, const Utils::FilePath &location); + void setScreenSizeIndex(int index); + void setTargetQtVersionIndex(int index); + bool haveTargetQtVersion() const; + void setStyleIndex(int index); + int styleIndex() const; + void destroyWizard(); + + void setUseVirtualKeyboard(bool value); + bool haveVirtualKeyboard() const; + + void setProjectName(const QString &name); + void setProjectLocation(const Utils::FilePath &location); + + void run(const std::function &processPage); + +signals: + void deletingWizard(); + void wizardCreated(QStandardItemModel *screenSizeModel, QStandardItemModel *styleModel); + void statusMessageChanged(Utils::InfoLabel::InfoType type, const QString &message); + void projectCanBeCreated(bool value); + void wizardCreationFailed(); + +private: + void setupWizard(); + void initializeProjectPage(QWizardPage *page); + void initializeFieldsPage(QWizardPage *page); + + QStandardItemModel *getScreenFactorModel(ProjectExplorer::JsonFieldPage *page); + QStandardItemModel *getStyleModel(ProjectExplorer::JsonFieldPage *page); + +private slots: + void onWizardResetting(); + void onProjectIntroCompleteChanged(); + +private: + Utils::Wizard *m_wizard = nullptr; + ProjectExplorer::JsonFieldPage *m_detailsPage = nullptr; + + int m_selectedProject = -1; + + ProjectItem m_projectItem; + Utils::FilePath m_projectLocation; +}; + +} // StudioWelcome From c8e4b32ee1a39a1ff93aa35e67c533888e63ddaf Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 10 Nov 2021 07:17:04 +0100 Subject: [PATCH 36/57] StudioWelcome: Fix build for qbs and qmake Amends a850b1b866a5dfb. Change-Id: I80da98f264020ab803c711d1bdf2eeb691fa60af Reviewed-by: Alessandro Portale --- src/plugins/studiowelcome/studiowelcome.pro | 9 +++++-- src/plugins/studiowelcome/studiowelcome.qbs | 24 ++++++++++++------- .../studiowelcome_dependencies.pri | 1 + 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/plugins/studiowelcome/studiowelcome.pro b/src/plugins/studiowelcome/studiowelcome.pro index 3cdee86f789..9b7e756a568 100644 --- a/src/plugins/studiowelcome/studiowelcome.pro +++ b/src/plugins/studiowelcome/studiowelcome.pro @@ -15,18 +15,23 @@ HEADERS += \ newprojectdialogimageprovider.h \ qdsnewdialog.h \ wizardfactories.h \ + wizardhandler.h \ createproject.h \ newprojectmodel.h \ - examplecheckout.h + examplecheckout.h \ + screensizemodel.h \ + stylemodel.h SOURCES += \ studiowelcomeplugin.cpp \ qdsnewdialog.cpp \ wizardfactories.cpp \ + wizardhandler.cpp \ createproject.cpp \ newprojectdialogimageprovider.cpp \ newprojectmodel.cpp \ - examplecheckout.cpp + examplecheckout.cpp \ + stylemodel.cpp OTHER_FILES += \ StudioWelcome.json.in diff --git a/src/plugins/studiowelcome/studiowelcome.qbs b/src/plugins/studiowelcome/studiowelcome.qbs index c630d83f01c..a0b81b872da 100644 --- a/src/plugins/studiowelcome/studiowelcome.qbs +++ b/src/plugins/studiowelcome/studiowelcome.qbs @@ -9,27 +9,33 @@ QtcPlugin { Depends { name: "Core" } Depends { name: "ProjectExplorer" } Depends { name: "QtSupport" } + Depends { name: "QmlDesigner" } Depends { name: "app_version_header" } cpp.defines: 'STUDIO_QML_PATH="' + FileInfo.joinPaths(sourceDirectory, "qml") + '"' files: [ - "studiowelcome_global.h", - "studiowelcomeplugin.h", - "studiowelcomeplugin.cpp", - "qdsnewdialog.cpp", - "qdsnewdialog.h", - "wizardfactories.cpp", - "wizardfactories.h", "createproject.cpp", "createproject.h", - "newprojectmodel.cpp", - "newprojectmodel.h", "examplecheckout.h", "examplecheckout.cpp", "newprojectdialogimageprovider.h", "newprojectdialogimageprovider.cpp", + "newprojectmodel.cpp", + "newprojectmodel.h", + "qdsnewdialog.cpp", + "qdsnewdialog.h", + "screensizemodel.h", + "studiowelcome_global.h", + "studiowelcomeplugin.h", + "studiowelcomeplugin.cpp", "studiowelcome.qrc", + "stylemodel.cpp", + "stylemodel.h", + "wizardfactories.cpp", + "wizardfactories.h", + "wizardhandler.cpp", + "wizardhandler.h", ] Group { diff --git a/src/plugins/studiowelcome/studiowelcome_dependencies.pri b/src/plugins/studiowelcome/studiowelcome_dependencies.pri index 51eb0d02565..bb8286bc7b3 100644 --- a/src/plugins/studiowelcome/studiowelcome_dependencies.pri +++ b/src/plugins/studiowelcome/studiowelcome_dependencies.pri @@ -6,5 +6,6 @@ QTC_LIB_DEPENDS += \ QTC_PLUGIN_DEPENDS += \ coreplugin \ projectexplorer \ + qmldesigner \ qtsupport From d511f1798adb8f67a3aef724cf90b6af277b8acb Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 9 Nov 2021 15:12:04 +0100 Subject: [PATCH 37/57] LanguageClient: add logging to the manager Change-Id: I953ffd8f281702c3032ce48cd620dcac983b5b25 Reviewed-by: Christian Kandeler --- src/plugins/languageclient/languageclientmanager.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/plugins/languageclient/languageclientmanager.cpp b/src/plugins/languageclient/languageclientmanager.cpp index 63a4f1c9da5..f4b4439dae9 100644 --- a/src/plugins/languageclient/languageclientmanager.cpp +++ b/src/plugins/languageclient/languageclientmanager.cpp @@ -53,6 +53,8 @@ using namespace LanguageServerProtocol; namespace LanguageClient { +static Q_LOGGING_CATEGORY(Log, "qtc.languageclient.manager", QtWarningMsg) + static LanguageClientManager *managerInstance = nullptr; LanguageClientManager::LanguageClientManager(QObject *parent) @@ -111,6 +113,7 @@ void LanguageClient::LanguageClientManager::addClient(Client *client) if (managerInstance->m_clients.contains(client)) return; + qCDebug(Log) << "add client: " << client->name() << client; managerInstance->m_clients << client; connect(client, &Client::finished, managerInstance, [client]() { clientFinished(client); }); connect(client, @@ -130,6 +133,7 @@ void LanguageClient::LanguageClientManager::addClient(Client *client) void LanguageClientManager::clientStarted(Client *client) { + qCDebug(Log) << "client started: " << client->name() << client; QTC_ASSERT(managerInstance, return); QTC_ASSERT(client, return); if (managerInstance->m_shuttingDown) @@ -150,6 +154,7 @@ void LanguageClientManager::clientFinished(Client *client) const QList &clientDocs = managerInstance->m_clientForDocument.keys(client); if (client->reset()) { + qCDebug(Log) << "restart unexpectedly finished client: " << client->name() << client; client->disconnect(managerInstance); client->log( tr("Unexpectedly finished. Restarting in %1 seconds.").arg(restartTimeoutS)); @@ -158,6 +163,7 @@ void LanguageClientManager::clientFinished(Client *client) client->deactivateDocument(document); return; } + qCDebug(Log) << "client finished unexpectedly: " << client->name() << client; client->log(tr("Unexpectedly finished.")); for (TextEditor::TextDocument *document : clientDocs) managerInstance->m_clientForDocument.remove(document); @@ -174,6 +180,7 @@ Client *LanguageClientManager::startClient(BaseSettings *setting, ProjectExplore QTC_ASSERT(setting, return nullptr); QTC_ASSERT(setting->isValid(), return nullptr); Client *client = setting->createClient(project); + qCDebug(Log) << "start client: " << client->name() << client; QTC_ASSERT(client, return nullptr); client->start(); managerInstance->m_clientsForSetting[setting->m_id].append(client); @@ -206,6 +213,7 @@ void LanguageClientManager::shutdownClient(Client *client) { if (!client) return; + qCDebug(Log) << "request client shutdown: " << client->name() << client; // reset the documents for that client already when requesting the shutdown so they can get // reassigned to another server right after this request to another server for (TextEditor::TextDocument *document : managerInstance->m_clientForDocument.keys(client)) @@ -220,6 +228,7 @@ void LanguageClientManager::deleteClient(Client *client) { QTC_ASSERT(managerInstance, return); QTC_ASSERT(client, return); + qCDebug(Log) << "delete client: " << client->name() << client; client->disconnect(); managerInstance->m_clients.removeAll(client); for (QVector &clients : managerInstance->m_clientsForSetting) @@ -237,6 +246,7 @@ void LanguageClientManager::shutdown() QTC_ASSERT(managerInstance, return); if (managerInstance->m_shuttingDown) return; + qCDebug(Log) << "shutdown manager"; managerInstance->m_shuttingDown = true; for (Client *client : qAsConst(managerInstance->m_clients)) shutdownClient(client); @@ -412,6 +422,7 @@ void LanguageClientManager::openDocumentWithClient(TextEditor::TextDocument *doc currentClient->deactivateDocument(document); managerInstance->m_clientForDocument[document] = client; if (client) { + qCDebug(Log) << "open" << document->filePath() << "with" << client->name() << client; if (!client->documentOpen(document)) client->openDocument(document); else From 401219bb07c8321492683d76450b64d1041f9d39 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Mon, 8 Nov 2021 15:27:06 +0100 Subject: [PATCH 38/57] QmlDesigner: Fix SVG paste action * Add support for line and polyline * Convert "none" color value to "transparent" * Fix group item if viewBox attribute not present Change-Id: Iafef04e58114d0a9859e0c08a951f953228ed518 Reviewed-by: Thomas Hartmann --- .../componentcore/svgpasteaction.cpp | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp b/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp index dac06f73e69..7c29fcd6429 100644 --- a/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp +++ b/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp @@ -603,7 +603,7 @@ double round(double value, int decimal_places) { } static const std::initializer_list tagAllowList{ - u"path", u"rect", u"polygon", u"circle", u"ellipse" + u"path", u"rect", u"line", u"polygon", u"polyline", u"circle", u"ellipse" }; // fillOpacity and strokeOpacity aren't actual QML properties, but get mapped anyways @@ -840,6 +840,8 @@ QVariant convertValue(const QByteArray &key, const QString &value) return value.toInt(); } else if (key == "opacity") { return value.toFloat(); + } else if ((key == "fillColor" || key == "strokeColor") && value == "none") { + return "transparent"; } return value; @@ -1015,6 +1017,28 @@ PropertyMap generateRectProperties(const QDomElement &e, const CSSRules &cssRule return properties; } +PropertyMap generateLineProperties(const QDomElement &e, const CSSRules &cssRules) +{ + QLineF line(e.attribute("x1").toFloat(), + e.attribute("y1").toFloat(), + e.attribute("x2").toFloat(), + e.attribute("y2").toFloat()); + + QPainterPath path(line.p1()); + path.lineTo(line.p2()); + + PropertyMap properties; + QTransform transform; + flattenTransformsAndStyles(e, cssRules, transform, properties); + + path = transform.map(path); + + if (!applyMinimumBoundingBox(path, properties)) + return {}; + + return properties; +} + PropertyMap generateEllipseProperties(const QDomElement &e, const CSSRules &cssRules) { const QPointF center(e.attribute("cx").toFloat(), e.attribute("cy").toFloat()); @@ -1085,7 +1109,7 @@ PropertyMap generatePolygonProperties(const QDomElement &e, const CSSRules &cssR for (int i = 0; i < pointList.length(); i += 2) polygon.push_back({pointList[i].toFloat(), pointList[i + 1].toFloat()}); - if (!polygon.isClosed() && polygon.size()) + if (e.tagName() != "polyline" && !polygon.isClosed() && polygon.size()) polygon.push_back(polygon.front()); QPainterPath path; @@ -1178,6 +1202,11 @@ QmlObjectNode SVGPasteAction::createQmlObjectNode(QmlDesigner::ModelNode &target round(tmp[2].toFloat(), 2), round(tmp[3].toFloat(), 2)); } + + viewBoxProperties.insert("clip", true); + } else { + viewBox.setWidth(round(rootElement.attribute("width").toFloat(), 2)); + viewBox.setHeight(round(rootElement.attribute("height").toFloat(), 2)); } viewBoxProperties.insert("x", viewBox.x()); @@ -1202,8 +1231,6 @@ QmlObjectNode SVGPasteAction::createQmlObjectNode(QmlDesigner::ModelNode &target depthFirstTraversal(node, processStyleAndCollectShapes); - viewBoxProperties.insert("clip", true); - ModelNode groupNode = createGroupNode(targetNode, viewBoxProperties); for (const QDomElement &e : shapeElements) { @@ -1213,7 +1240,9 @@ QmlObjectNode SVGPasteAction::createQmlObjectNode(QmlDesigner::ModelNode &target pathProperties = generatePathProperties(e, cssRules); else if (e.tagName() == "rect") pathProperties = generateRectProperties(e, cssRules); - else if (e.tagName() == "polygon") + else if (e.tagName() == "line") + pathProperties = generateLineProperties(e, cssRules); + else if (e.tagName() == "polygon" || e.tagName() == "polyline") pathProperties = generatePolygonProperties(e, cssRules); else if (e.tagName() == "circle" || e.tagName() == "ellipse") pathProperties = generateEllipseProperties(e, cssRules); From 397cbd77ab0080d42e5bb7cc99c12c5c3edc3b5c Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 9 Nov 2021 11:54:44 +0100 Subject: [PATCH 39/57] ClangCodeModel: Fix highlighting problem with template types With clangd, we mis-detected variables of template types as output parameters in certain contexts. Change-Id: I906abd489f987351793f4ef676e4af59cdfdbf97 Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangdclient.cpp | 10 ++++++++++ src/plugins/clangcodemodel/test/clangdtests.cpp | 1 + .../test/data/highlighting/highlighting.cpp | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index 09f9cedd191..fddf22e0096 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -252,6 +252,16 @@ public: QString theType = type(); if (theType.endsWith("const")) theType.chop(5); + + // We don't care about the "inner" type of templates. + const int openAngleBracketPos = theType.indexOf('<'); + if (openAngleBracketPos != -1) { + const int closingAngleBracketPos = theType.lastIndexOf('>'); + if (closingAngleBracketPos > openAngleBracketPos) { + theType = theType.left(openAngleBracketPos) + + theType.mid(closingAngleBracketPos + 1); + } + } const int xrefCount = theType.count("&&"); const int refCount = theType.count('&') - 2 * xrefCount; const int ptrRefCount = theType.count('*') + refCount; diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp index 927728d8754..82e63d49835 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.cpp +++ b/src/plugins/clangcodemodel/test/clangdtests.cpp @@ -1249,6 +1249,7 @@ void ClangdTestHighlighting::test_data() QTest::newRow("const argument to unnamed lambda") << 830 << 16 << 830 << 19 << QList{C_LOCAL} << 0; QTest::newRow("simple assignment") << 835 << 5 << 835 << 6 << QList{C_LOCAL} << 0; + QTest::newRow("simple return") << 841 << 12 << 841 << 15 << QList{C_LOCAL} << 0; } void ClangdTestHighlighting::test() diff --git a/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp b/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp index 652d9540c80..7f8faa1edc0 100644 --- a/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp +++ b/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp @@ -834,3 +834,9 @@ void assignmentTest() { struct S {} s; s = {}; } + +using FooPtrVector = std::vector; +FooPtrVector returnTest() { + FooPtrVector foo; + return foo; +} From 96f60fa123c38a28ac1855194aa83084c370fc0b Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Tue, 9 Nov 2021 20:10:39 +0100 Subject: [PATCH 40/57] StudioWelcome: Fix build, add target QmlDesigner as condition If QmlDesigner is not built, also StudioWelcome cannot, since it now depends on QmlDesigner. Amends: a850b1b866a5dfbaffdcf26fa7816c5a41305bbf Change-Id: I79edfbd0a3d6f922f7a7e03b64e02777b181b3bc Reviewed-by: Cristian Adam Reviewed-by: Eike Ziller --- src/plugins/studiowelcome/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/studiowelcome/CMakeLists.txt b/src/plugins/studiowelcome/CMakeLists.txt index 3d290d6486b..e1f899d2fd4 100644 --- a/src/plugins/studiowelcome/CMakeLists.txt +++ b/src/plugins/studiowelcome/CMakeLists.txt @@ -1,5 +1,5 @@ add_qtc_plugin(StudioWelcome - CONDITION TARGET Qt5::QuickWidgets + CONDITION TARGET Qt5::QuickWidgets AND TARGET QmlDesigner DEPENDS Qt5::QuickWidgets PLUGIN_DEPENDS Core ProjectExplorer QtSupport QmlDesigner DEFINES STUDIO_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/qml/" From f45e68d28d9f2cf1f4f74c51d6e03b8eadbfff1a Mon Sep 17 00:00:00 2001 From: Piotr Mikolajczyk Date: Fri, 5 Nov 2021 12:43:12 +0100 Subject: [PATCH 41/57] Fix to qmlpreview failing to upload files Return to correct function call order when preparing and uploading data to the device. (Manual pick from master) Change-Id: I0a78b6614765bfae5c3accd99c1c150540871aac Reviewed-by: Alessandro Portale --- src/plugins/android/androidqmlpreviewworker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/android/androidqmlpreviewworker.cpp b/src/plugins/android/androidqmlpreviewworker.cpp index bb95616eacd..5eb0c887d7c 100644 --- a/src/plugins/android/androidqmlpreviewworker.cpp +++ b/src/plugins/android/androidqmlpreviewworker.cpp @@ -209,8 +209,8 @@ void AndroidQmlPreviewWorker::start() } const bool previewStarted = ensureAvdIsRunning() && checkAndInstallPreviewApp() - && uploadPreviewArtefacts() && preparePreviewArtefacts() + && uploadPreviewArtefacts() && startPreviewApp(); previewStarted ? reportStarted() : reportStopped(); From 4303e62c50e6a6fa7057978f5dec1c3408613a8b Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 9 Nov 2021 14:15:38 +0100 Subject: [PATCH 42/57] Dumper: Fix passing fallback Qt version We nowadays have an additional token there. Change-Id: I65e5a55792802ae2ab7da6f7c6d8d1b109bf55a0 Reviewed-by: hjk --- share/qtcreator/debugger/dumper.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 3838e139654..99f3b966fb2 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -252,7 +252,8 @@ class DumperBase(): #DumperBase.warn('EXPANDED INAMES: %s' % self.expandedINames) #DumperBase.warn('WATCHERS: %s' % self.watchers) - def setFallbackQtVersion(self, version): + def setFallbackQtVersion(self, args): + version = int(args.get('version', '0x%x' % self.fallbackQtVersion), 16) self.warn("got fallback qt version %x" % version) self.fallbackQtVersion = version From f84f430caf9704754a10d4747977b2729f40376b Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Tue, 9 Nov 2021 15:35:52 +0100 Subject: [PATCH 43/57] Debugger: Set "PYTHONHOME" for Androids lldb as native path The correct path separators in this case make the difference beween breaking on a breakpoint or not. Change-Id: Ia33682e559ffe172a571bec6b78b32fca14d98f5 Reviewed-by: Christian Stenger --- src/plugins/debugger/debuggeritem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp index 85206926fb8..687149193f0 100644 --- a/src/plugins/debugger/debuggeritem.cpp +++ b/src/plugins/debugger/debuggeritem.cpp @@ -273,7 +273,7 @@ bool DebuggerItem::addAndroidLldbPythonEnv(const Utils::FilePath &lldbCmd, Utils const FilePath pythonBinDir = HostOsInfo::isAnyUnixHost() ? pythonDir.pathAppended("bin") : pythonDir; if (pythonBinDir.exists()) { - env.set("PYTHONHOME", pythonDir.path()); + env.set("PYTHONHOME", pythonDir.toUserOutput()); env.prependOrSetPath(pythonBinDir.path()); return true; } From a0fba5750849bab2f48f8bdb4a6c98329962f317 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 9 Nov 2021 10:25:50 +0100 Subject: [PATCH 44/57] LanguageClient: remove unused variable Change-Id: I0910a0b75fe727c40c0249437895eb9d3566f7a2 Reviewed-by: Christian Stenger --- src/plugins/languageclient/client.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 03b75680abd..e34b8dac844 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -937,7 +937,6 @@ void Client::handleCodeActionResponse(const CodeActionRequest::Response &respons void Client::executeCommand(const Command &command) { - const QString method(ExecuteCommandRequest::methodName); bool serverSupportsExecuteCommand = m_serverCapabilities.executeCommandProvider().has_value(); serverSupportsExecuteCommand = m_dynamicCapabilities .isRegistered(ExecuteCommandRequest::methodName) From a8afa5c65c883786bbb0b4ab6844177248eb29d4 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 10 Nov 2021 11:44:40 +0100 Subject: [PATCH 45/57] Debugger: Fix setting of Qt version fallback, again Change-Id: I6b6cd448884800cb6d08dbdce15cb99f4ea8ba2b Reviewed-by: Christian Stenger --- share/qtcreator/debugger/dumper.py | 4 ++-- src/plugins/debugger/cdb/cdbengine.cpp | 6 ++++-- src/plugins/debugger/gdb/gdbengine.cpp | 5 ++++- src/plugins/debugger/lldb/lldbengine.cpp | 8 ++++---- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 99f3b966fb2..fdf64d851fc 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -253,8 +253,8 @@ class DumperBase(): #DumperBase.warn('WATCHERS: %s' % self.watchers) def setFallbackQtVersion(self, args): - version = int(args.get('version', '0x%x' % self.fallbackQtVersion), 16) - self.warn("got fallback qt version %x" % version) + version = int(args.get('version', self.fallbackQtVersion)) + DumperBase.warn("got fallback qt version 0x%x" % version) self.fallbackQtVersion = version def resetPerStepCaches(self): diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index d685d550d01..0c4b42094d2 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -2832,8 +2832,10 @@ void CdbEngine::setupScripting(const DebuggerResponse &response) runCommand({command, ScriptCommand}); } - const QString qtVersion = QString::number(runParameters().fallbackQtVersion, 16); - runCommand({"theDumper.setFallbackQtVersion(0x" + qtVersion + ")", ScriptCommand}); + DebuggerCommand cmd0("theDumper.setFallbackQtVersion", ScriptCommand); + cmd0.arg("version", runParameters().fallbackQtVersion); + runCommand(cmd0); + runCommand({"theDumper.loadDumpers(None)", ScriptCommand, [this](const DebuggerResponse &response) { watchHandler()->addDumpers(response.data["result"]["dumpers"]); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 8f9f789a67f..5e9d337bbd6 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -4007,7 +4007,10 @@ void GdbEngine::setupEngine() if (!commands.isEmpty()) runCommand({commands}); - runCommand({"setFallbackQtVersion(0x" + QString::number(rp.fallbackQtVersion, 16) + ")"}); + DebuggerCommand cmd1("setFallbackQtVersion"); + cmd1.arg("version", rp.fallbackQtVersion); + runCommand(cmd1); + runCommand({"loadDumpers", CB(handlePythonSetup)}); // Reload peripheral register description. diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 49124aca320..e98c0598158 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -264,10 +264,6 @@ void LldbEngine::setupEngine() runCommand(cmd); } - DebuggerCommand cmd0("setFallbackQtVersion"); - cmd0.arg("version", "0x" + QString::number(rp.fallbackQtVersion, 16)); - runCommand(cmd0); - DebuggerCommand cmd1("loadDumpers"); cmd1.callback = [this](const DebuggerResponse &response) { watchHandler()->addDumpers(response.data["dumpers"]); @@ -343,6 +339,10 @@ void LldbEngine::setupEngine() cmd2.flags = Silent; runCommand(cmd2); + + DebuggerCommand cmd0("setFallbackQtVersion"); + cmd0.arg("version", rp.fallbackQtVersion); + runCommand(cmd0); } void LldbEngine::runEngine() From 335f85c525bde542c2d6b73f0a402265fc560287 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 10 Nov 2021 12:56:20 +0100 Subject: [PATCH 46/57] StudioWelcome: Fix qmake build on Linux with Qt5 Change-Id: I88fea1b3730e22866e1f365a6e605c375f5320c7 Reviewed-by: hjk --- src/plugins/studiowelcome/newprojectmodel.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/studiowelcome/newprojectmodel.h b/src/plugins/studiowelcome/newprojectmodel.h index 9e6cdd157b9..ec7cc005add 100644 --- a/src/plugins/studiowelcome/newprojectmodel.h +++ b/src/plugins/studiowelcome/newprojectmodel.h @@ -26,6 +26,7 @@ #pragma once #include +#include #include #include From d2ff57309be80d0d0ce4c333273ad749c206e041 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 10 Nov 2021 12:26:12 +0100 Subject: [PATCH 47/57] Client: make sure to reset project for client Change-Id: I23860ee07c4f5793ce3247f46e8d925eae2b2bea Reviewed-by: Christian Kandeler --- src/plugins/languageclient/client.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index e34b8dac844..b452341d0d3 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -952,7 +952,18 @@ ProjectExplorer::Project *Client::project() const void Client::setCurrentProject(ProjectExplorer::Project *project) { + if (m_project == project) + return; + if (m_project) + m_project->disconnect(this); m_project = project; + if (m_project) { + connect(m_project, &ProjectExplorer::Project::destroyed, this, [this]() { + // the project of the client should already be null since we expect the session and + // the language client manager to reset it before it gets deleted. + QTC_ASSERT(m_project == nullptr, projectClosed(m_project)); + }); + } } void Client::projectOpened(ProjectExplorer::Project *project) From bf7cc1fa02cd0d04495b33f813feb1b6c4575e3c Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Wed, 20 Oct 2021 22:50:38 +0200 Subject: [PATCH 48/57] qmlpreview: enable language combobox Change-Id: Ie1719d620608b94360a3831d138e1be25bae7b10 Reviewed-by: Tim Jenssen --- .../qmldesigner/qmlpreviewplugin/qmlpreviewactions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewactions.cpp b/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewactions.cpp index 04ac06ce392..bcdd87b749a 100644 --- a/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewactions.cpp +++ b/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewactions.cpp @@ -217,14 +217,13 @@ SwitchLanguageComboboxAction::SwitchLanguageComboboxAction(QObject *parent) QWidget *SwitchLanguageComboboxAction::createWidget(QWidget *parent) { QPointer comboBox = new QComboBox(parent); - // FIXME: this combobox does not work at the moment - comboBox->setDisabled(true); const QString toolTip(tr("Switch the language used by preview.")); comboBox->setToolTip(toolTip); comboBox->addItem(tr("Default")); auto refreshComboBoxFunction = [this, comboBox, toolTip] (ProjectExplorer::Project *project) { if (comboBox && project) { + comboBox->setDisabled(true); QString errorMessage; auto locales = project->availableQmlPreviewTranslations(&errorMessage); if (!errorMessage.isEmpty()) @@ -234,6 +233,7 @@ QWidget *SwitchLanguageComboboxAction::createWidget(QWidget *parent) comboBox->addItem(tr("Default")); comboBox->addItems(locales); m_previousLocales = locales; + comboBox->setEnabled(true); } } }; From 730a1e6e42d1e8c5cb4afc5bb9637078fba32b10 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 10 Nov 2021 15:24:57 +0100 Subject: [PATCH 49/57] StudioWelcome: Fix warnings regarding unused parameters Change-Id: I56d0a9c18c963d1a505e8d40daa058f66d984d77 Reviewed-by: Christian Kandeler --- src/plugins/studiowelcome/screensizemodel.h | 4 ++-- src/plugins/studiowelcome/stylemodel.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/studiowelcome/screensizemodel.h b/src/plugins/studiowelcome/screensizemodel.h index e01f17295c5..4e38f7acf85 100644 --- a/src/plugins/studiowelcome/screensizemodel.h +++ b/src/plugins/studiowelcome/screensizemodel.h @@ -67,7 +67,7 @@ public: return QSize{width, height}; } - int rowCount(const QModelIndex &parent = QModelIndex()) const override + int rowCount(const QModelIndex &/*parent*/) const override { if (m_backendModel) return m_backendModel->rowCount(); @@ -75,7 +75,7 @@ public: return 0; } - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override + QVariant data(const QModelIndex &index, int /*role*/) const override { if (m_backendModel) { auto *item = m_backendModel->item(index.row(), index.column()); diff --git a/src/plugins/studiowelcome/stylemodel.h b/src/plugins/studiowelcome/stylemodel.h index 6d6d09620d1..e311eded6fb 100644 --- a/src/plugins/studiowelcome/stylemodel.h +++ b/src/plugins/studiowelcome/stylemodel.h @@ -41,7 +41,7 @@ public: Q_INVOKABLE QString iconId(int index) const; Q_INVOKABLE void filter(const QString &what = "all"); - int rowCount(const QModelIndex &parent = QModelIndex()) const override + int rowCount(const QModelIndex &/*parent*/) const override { if (m_backendModel) return static_cast(m_filteredItems.size()); @@ -49,7 +49,7 @@ public: return 0; } - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override + QVariant data(const QModelIndex &index, int /*role*/) const override { if (m_backendModel) { auto *item = m_filteredItems.at(index.row()); From 9d6b8727ee56d6044c6506fd0b9c46ea05d3c161 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Wed, 10 Nov 2021 12:44:02 +0100 Subject: [PATCH 50/57] ClangCodeModel: Enable big object flags for building on Windows Fixes problems with debug builds that link too many symbols into the binary. Change-Id: I6e95d6abd99a4f2a9a78764d8155a6e7b7fa8571 Reviewed-by: Christian Kandeler --- src/plugins/clangcodemodel/CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/plugins/clangcodemodel/CMakeLists.txt b/src/plugins/clangcodemodel/CMakeLists.txt index ace1b99575c..e8f15a2303b 100644 --- a/src/plugins/clangcodemodel/CMakeLists.txt +++ b/src/plugins/clangcodemodel/CMakeLists.txt @@ -61,3 +61,14 @@ extend_qtc_plugin(ClangCodeModel test/clangdtests.cpp test/clangdtests.h test/data/clangtestdata.qrc ) + +if(MINGW) + set(big_obj_compile_option "-Wa,-mbig-obj") +elseif(MSVC) + set(big_obj_compile_option "/bigobj") +endif() + +extend_qtc_plugin(ClangCodeModel + CONDITION DEFINED big_obj_compile_option + PROPERTIES COMPILE_OPTIONS ${big_obj_compile_option} +) From b7bae45d128e41e187d46868980468fd2e88e7e0 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 10 Nov 2021 14:58:37 +0100 Subject: [PATCH 51/57] Doc: Rename "Using Other Build Systems" to "Build Systems" ...now that qmake is not the default anymore, but you can choose the build system when creating projects. Change-Id: I52098059e1d32ba2c43c48af7df9dd4c2daff09e Reviewed-by: Kai Koehne --- doc/qtcreator/src/overview/creator-only/creator-advanced.qdoc | 4 ++-- .../src/projects/creator-only/creator-projects-creating.qdoc | 2 +- .../src/projects/creator-only/creator-projects-other.qdoc | 2 +- .../src/projects/creator-only/creator-projects-overview.qdoc | 4 ++-- doc/qtcreator/src/qtcreator-toc.qdoc | 2 +- doc/qtcreator/src/qtcreator.qdoc | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/qtcreator/src/overview/creator-only/creator-advanced.qdoc b/doc/qtcreator/src/overview/creator-only/creator-advanced.qdoc index d383b808cf0..c5eb81598c3 100644 --- a/doc/qtcreator/src/overview/creator-only/creator-advanced.qdoc +++ b/doc/qtcreator/src/overview/creator-only/creator-advanced.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -57,7 +57,7 @@ applications for multiple desktop and \l{glossary-device}{device} platforms. - \li \l{Using Other Build Systems} + \li \l{Build Systems} \QC is integrated with cross-platform systems for build automation: qmake, Qbs, CMake, and Autotools. In addition, you can import diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc index 34eeb024b05..76a67382562 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc @@ -515,7 +515,7 @@ \li \l{Opening Projects} \li \l{Adding Libraries to Projects} \li \l{Adding New Custom Wizards} - \li \l{Using Other Build Systems} + \li \l{Build Systems} \endlist */ diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-other.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-other.qdoc index 635fbd19ba4..e69f953e44a 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-other.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-other.qdoc @@ -34,7 +34,7 @@ \page creator-project-other.html \nextpage creator-project-cmake.html - \title Using Other Build Systems + \title Build Systems Most \QC project wizards enable you to choose the build system to use for building the project: qmake, CMake, Meson, or Qbs. qmake is installed and diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-overview.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-overview.qdoc index f2534ba8d86..1b3174b1dc5 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-overview.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-overview.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -75,7 +75,7 @@ \section1 Related Topics \list - \li \l{Using Other Build Systems} + \li \l{Build Systems} \endlist */ diff --git a/doc/qtcreator/src/qtcreator-toc.qdoc b/doc/qtcreator/src/qtcreator-toc.qdoc index f1e06156fd0..421755c3153 100644 --- a/doc/qtcreator/src/qtcreator-toc.qdoc +++ b/doc/qtcreator/src/qtcreator-toc.qdoc @@ -212,7 +212,7 @@ \li \l {Embedded Platforms} \li \l {Mobile Platforms} \endlist - \li \l{Using Other Build Systems} + \li \l{Build Systems} \list \li \l{Setting Up CMake} \li \l{Setting Up Qbs} diff --git a/doc/qtcreator/src/qtcreator.qdoc b/doc/qtcreator/src/qtcreator.qdoc index cb53dc7b6c7..6a38a087760 100644 --- a/doc/qtcreator/src/qtcreator.qdoc +++ b/doc/qtcreator/src/qtcreator.qdoc @@ -113,7 +113,7 @@ \li \b {\l{Advanced Use}} \list \li \l{Supported Platforms} - \li \l{Using Other Build Systems} + \li \l{Build Systems} \li \l{Using Command Line Options} \li \l{Keyboard Shortcuts} \li \l{Using External Tools} From 305c91f42a7e81a135deed2714d611fa1155dac3 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 8 Nov 2021 16:28:40 +0200 Subject: [PATCH 52/57] QmlDesigner: Reset ComponentTextModifier when changing to doc model A dangling ComponentTextModifier would still handle signals, so delete it when it is no longer needed. Change-Id: I67a70cf8b5e304a627ef92f9b4b8beecdd63cf0f Reviewed-by: Thomas Hartmann --- .../qmldesigner/components/integration/designdocument.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp index 0c0268f4ca5..a5d904c495a 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp @@ -311,6 +311,7 @@ void DesignDocument::changeToDocumentModel() viewManager().detachViewsExceptRewriterAndComponetView(); m_inFileComponentModel.reset(); + m_inFileComponentTextModifier.reset(); viewManager().attachRewriterView(); viewManager().attachViewsExceptRewriterAndComponetView(); From dcf09bbf2c6f43cd83231fca07129e454dffa017 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 9 Nov 2021 14:51:48 +0200 Subject: [PATCH 53/57] QmlDesigner: Use disabled color for disabled add module button Fixes: QDS-5366 Change-Id: Ibfd761ad9c425c0a05a8668927121084dcfc5b64 Reviewed-by: Thomas Hartmann --- .../qmldesigner/itemLibraryQmlSources/LibraryHeader.qml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/LibraryHeader.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/LibraryHeader.qml index f5ad0eae3f2..36c823ec631 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/LibraryHeader.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/LibraryHeader.qml @@ -105,8 +105,11 @@ Item { verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter anchors.centerIn: parent - color: tabBar.currentIndex === index ? StudioTheme.Values.themeIconColorSelected - : StudioTheme.Values.themeIconColor + color: !plusButton.enabled + ? StudioTheme.Values.themeIconColorDisabled + : tabBar.currentIndex === index + ? StudioTheme.Values.themeIconColorSelected + : StudioTheme.Values.themeIconColor } HelperWidgets.ToolTipArea { From 9ba2d2758a71592a716da42e233587a715a0b073 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 8 Nov 2021 16:33:57 +0200 Subject: [PATCH 54/57] QmlDesigner: Adjust ComponentTextModifier offsets for whitespace change Whitespace change can also occur inside the subcomponent code when new nodes are added into subcomponent and the document is saved. Changed the text change handling to adjust for whitespace changes both before and inside the subcomponent code. The new handling is simpler and doesn't require subcomponent to have id to work. The downside is that non-whitespace changes before subcomponent code are no longer adjusted for, but that was just a hacky workaround for a small part of a much larger issue that needs to be tackled properly anyway (i.e. supporting arbitrary undo/redo/manual edits), so losing it is not a big deal. Fixes: QDS-5362 Change-Id: I1ca1084baf78709727b1b4726b4c034558063401 Reviewed-by: Thomas Hartmann --- .../model/componenttextmodifier.cpp | 67 ++++++++++--------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/model/componenttextmodifier.cpp b/src/plugins/qmldesigner/designercore/model/componenttextmodifier.cpp index f9255225058..6aca50c4334 100644 --- a/src/plugins/qmldesigner/designercore/model/componenttextmodifier.cpp +++ b/src/plugins/qmldesigner/designercore/model/componenttextmodifier.cpp @@ -111,7 +111,8 @@ void ComponentTextModifier::commitGroup() { m_originalModifier->commitGroup(); - int textLength = m_originalModifier->text().length(); + m_originalText = m_originalModifier->text(); + int textLength = m_originalText.length(); m_componentEndOffset += (textLength - m_startLength); m_startLength = textLength; } @@ -157,40 +158,42 @@ void ComponentTextModifier::handleOriginalTextChanged() { // Update offsets when original text changes, if necessary - // Detect and adjust for removal/addition of unrelated text before the subcomponent code, - // as that can happen even without user editing the text (e.g. whitespace removal at save time) - const QString currentText = m_originalModifier->text(); - if (m_originalText.left(m_componentStartOffset) != currentText.left(m_componentStartOffset)) { - // Subcomponent item id is the only reliable indicator for adjustment - const int idIndex = m_originalText.indexOf("id:", m_componentStartOffset); - if (idIndex != -1 && idIndex < m_componentEndOffset) { - int newLineIndex = m_originalText.indexOf('\n', idIndex); - if (newLineIndex != -1) { - const QString checkLine = m_originalText.mid(idIndex, newLineIndex - idIndex); - int lineIndex = currentText.indexOf(checkLine); - if (lineIndex != -1) { - // Paranoia check - This shouldn't happen except when modifying text manually, - // but it's possible something was inserted between id and start - // of the component, which would throw off the calculation, so check that - // the first line is still correct even with new offset. - const int diff = idIndex - lineIndex; - newLineIndex = m_originalText.indexOf('\n', m_componentStartOffset); - if (newLineIndex != -1) { - const QString firstLine = m_originalText.mid(m_componentStartOffset, - newLineIndex - m_componentStartOffset); - const int newStart = m_componentStartOffset - diff; - if (firstLine == currentText.mid(newStart, firstLine.size())) { - m_componentEndOffset -= diff; - m_componentStartOffset = newStart; - m_originalText = currentText; - } - } - } - } + // Adjust for removal/addition of whitespace in the document + // Check that non-whitespace portion of the text is the same and count the whitespace diff + const int oldLen = m_originalText.size(); + const int newLen = currentText.size(); + int newSpace = 0; + int oldSpace = 0; + int newIdx = 0; + for (int oldIdx = 0; oldIdx < oldLen; ++oldIdx) { + const QChar oldChar = m_originalText[oldIdx]; + if (oldIdx == m_componentStartOffset) + m_componentStartOffset += newSpace - oldSpace; + if (oldIdx == m_componentEndOffset) { + m_componentEndOffset += newSpace - oldSpace; + break; + } + + while (newIdx < newLen && currentText[newIdx].isSpace()) { + ++newSpace; + ++newIdx; + } + + if (oldChar.isSpace()) { + ++oldSpace; + continue; + } + + if (currentText[newIdx] != oldChar) { + // Non-whitespace difference, we can't determine a valid offset in this case + // TODO: Needs proper handling to deal with undo/redo/arbitrary edits somehow (QDS-5392) + break; + } else { + ++newIdx; } } - + m_originalText = currentText; emit textChanged(); } From af647841cfa8ba29d083f998a1b779c44f258ac9 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 10 Nov 2021 15:35:26 +0100 Subject: [PATCH 55/57] ClangCodeModel: Fix erroneous marking of lambda parameter ... as output argument when using clangd. Change-Id: I35ef2da235cb317bb7eb1f08b865ea62c27d3b76 Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangdclient.cpp | 2 ++ src/plugins/clangcodemodel/test/clangdtests.cpp | 2 ++ .../clangcodemodel/test/data/highlighting/highlighting.cpp | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index fddf22e0096..46c85f06cdf 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -2453,6 +2453,8 @@ static void semanticHighlighter(QFutureInterface &future, return true; } + if (it->kind() == "Lambda") + return false; if (it->kind().endsWith("Cast") && it->hasConstType()) return false; if (it->kind() == "Member" && it->arcanaContains("(") diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp index 82e63d49835..cc532cfda03 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.cpp +++ b/src/plugins/clangcodemodel/test/clangdtests.cpp @@ -1250,6 +1250,8 @@ void ClangdTestHighlighting::test_data() << QList{C_LOCAL} << 0; QTest::newRow("simple assignment") << 835 << 5 << 835 << 6 << QList{C_LOCAL} << 0; QTest::newRow("simple return") << 841 << 12 << 841 << 15 << QList{C_LOCAL} << 0; + QTest::newRow("lambda parameter") << 847 << 49 << 847 << 52 + << QList{C_PARAMETER, C_DECLARATION} << 0; } void ClangdTestHighlighting::test() diff --git a/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp b/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp index 7f8faa1edc0..7f0db946955 100644 --- a/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp +++ b/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp @@ -840,3 +840,9 @@ FooPtrVector returnTest() { FooPtrVector foo; return foo; } + +template inline void useContainer(const Container &, Func) {} +void testConstRefAutoLambdaArgs() +{ + useContainer(FooPtrVector(), [](const auto &arg) {}); +} From 8d47a2f1e953e0cbda78fa8a8687572c096857de Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 10 Nov 2021 17:51:27 +0100 Subject: [PATCH 56/57] CppEditor: Add more logging to semantic highlighter Change-Id: Ib862d0290700e4e3ed42e7359b3ac902d64ba650 Reviewed-by: David Schulz --- src/plugins/cppeditor/semantichighlighter.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/plugins/cppeditor/semantichighlighter.cpp b/src/plugins/cppeditor/semantichighlighter.cpp index ba8b81e7ff1..d1e4e678257 100644 --- a/src/plugins/cppeditor/semantichighlighter.cpp +++ b/src/plugins/cppeditor/semantichighlighter.cpp @@ -148,6 +148,7 @@ void SemanticHighlighter::run() connectWatcher(); m_revision = documentRevision(); + qCDebug(log) << "starting runner for document revision" << m_revision; m_watcher->setFuture(m_highlightingRunner()); } @@ -160,12 +161,17 @@ static Parentheses getClearedParentheses(const QTextBlock &block) void SemanticHighlighter::onHighlighterResultAvailable(int from, int to) { - if (documentRevision() != m_revision) - return; // outdated - if (!m_watcher || m_watcher->isCanceled()) - return; // aborted - qCDebug(log) << "onHighlighterResultAvailable()" << from << to; + if (documentRevision() != m_revision) { + qCDebug(log) << "ignoring results: revision changed from" << m_revision << "to" + << documentRevision(); + return; + } + if (!m_watcher || m_watcher->isCanceled()) { + qCDebug(log) << "ignoring results: future was canceled"; + return; + } + QElapsedTimer t; t.start(); From c97a1440341c963e24003335af2e1cc981827038 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 10 Nov 2021 10:48:35 +0100 Subject: [PATCH 57/57] CppEditor: Move static variable to function Following the principle of scope minimization. Also, we got a reproducible crash-on-exit with MSVC with the original code. Change-Id: I465f4376fa7928de9bb878aee5faac992f75bf08 Reviewed-by: Qt CI Bot Reviewed-by: David Schulz --- src/plugins/cppeditor/cppcodemodelsettings.cpp | 10 +++++++--- src/plugins/cppeditor/cppcodemodelsettings.h | 4 ---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/plugins/cppeditor/cppcodemodelsettings.cpp b/src/plugins/cppeditor/cppcodemodelsettings.cpp index cf57ee39730..e60d8464687 100644 --- a/src/plugins/cppeditor/cppcodemodelsettings.cpp +++ b/src/plugins/cppeditor/cppcodemodelsettings.cpp @@ -36,6 +36,9 @@ #include #include +#include +#include +#include #include using namespace Utils; @@ -356,11 +359,12 @@ static QVersionNumber getClangdVersion(const FilePath &clangdFilePath) QVersionNumber ClangdSettings::clangdVersion(const FilePath &clangdFilePath) { + static QHash> versionCache; const QDateTime timeStamp = clangdFilePath.lastModified(); - const auto it = m_versionCache.find(clangdFilePath); - if (it == m_versionCache.end()) { + const auto it = versionCache.find(clangdFilePath); + if (it == versionCache.end()) { const QVersionNumber version = getClangdVersion(clangdFilePath); - m_versionCache.insert(clangdFilePath, qMakePair(timeStamp, version)); + versionCache.insert(clangdFilePath, qMakePair(timeStamp, version)); return version; } if (it->first != timeStamp) { diff --git a/src/plugins/cppeditor/cppcodemodelsettings.h b/src/plugins/cppeditor/cppcodemodelsettings.h index 2f3de7dd6bc..7d3ecb27fae 100644 --- a/src/plugins/cppeditor/cppcodemodelsettings.h +++ b/src/plugins/cppeditor/cppcodemodelsettings.h @@ -29,10 +29,7 @@ #include -#include -#include #include -#include #include #include @@ -150,7 +147,6 @@ private: void saveSettings(); Data m_data; - static inline QHash> m_versionCache; }; inline bool operator==(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2)