From 77a140c58114f1abdf37b3c74309d3ad32257766 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 7 Oct 2022 12:05:37 +0200 Subject: [PATCH 01/42] QtcProcess: Introduce TextChannelMode and textOnChannel signals This is alternative to setStd[Out/Err](Line)Callback() methods. In this way there may be many clients connected to textOnStandard[Output/Error]() signals. This should also simplify handling the lifetime of user callback. Change-Id: If82baa1f3f9c432ed431926619b9bbf11d770a84 Reviewed-by: Reviewed-by: hjk --- src/libs/utils/processenums.h | 16 +++++ src/libs/utils/qtcprocess.cpp | 51 +++++++++++++-- src/libs/utils/qtcprocess.h | 13 ++-- .../auto/utils/qtcprocess/tst_qtcprocess.cpp | 63 ++++++++++++++++++- 4 files changed, 134 insertions(+), 9 deletions(-) diff --git a/src/libs/utils/processenums.h b/src/libs/utils/processenums.h index 661f2c61ff7..8091dabeefa 100644 --- a/src/libs/utils/processenums.h +++ b/src/libs/utils/processenums.h @@ -37,6 +37,21 @@ enum class EventLoopMode { On // Avoid }; +enum class Channel { + Output, + Error +}; + +enum class TextChannelMode { + // Keep | Emit | Emit + // raw | text | content + // data | sig | + // -----+------+-------- + Off, // yes | no | - + SingleLine, // no | yes | Single lines + MultiLine // yes | yes | All the available data +}; + enum class ProcessResult { // Finished successfully. Unless an ExitCodeInterpreter is set // this corresponds to a return code 0. @@ -53,6 +68,7 @@ enum class ProcessResult { }; using ExitCodeInterpreter = std::function; +using TextChannelCallback = std::function; } // namespace Utils diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 18abb0de20f..7ddce617637 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -187,6 +187,7 @@ public: QTextCodec *codec = nullptr; // Not owner std::unique_ptr codecState; std::function outputCallback; + TextChannelMode m_textChannelMode = TextChannelMode::Off; bool emitSingleLines = true; bool keepRawData = true; @@ -1831,32 +1832,74 @@ void QtcProcess::runBlocking(EventLoopMode eventLoopMode) } } -void QtcProcess::setStdOutCallback(const std::function &callback) +void QtcProcess::setStdOutCallback(const TextChannelCallback &callback) { d->m_stdOut.outputCallback = callback; d->m_stdOut.emitSingleLines = false; } -void QtcProcess::setStdOutLineCallback(const std::function &callback) +void QtcProcess::setStdOutLineCallback(const TextChannelCallback &callback) { d->m_stdOut.outputCallback = callback; d->m_stdOut.emitSingleLines = true; d->m_stdOut.keepRawData = false; } -void QtcProcess::setStdErrCallback(const std::function &callback) +void QtcProcess::setStdErrCallback(const TextChannelCallback &callback) { d->m_stdErr.outputCallback = callback; d->m_stdErr.emitSingleLines = false; } -void QtcProcess::setStdErrLineCallback(const std::function &callback) +void QtcProcess::setStdErrLineCallback(const TextChannelCallback &callback) { d->m_stdErr.outputCallback = callback; d->m_stdErr.emitSingleLines = true; d->m_stdErr.keepRawData = false; } +void QtcProcess::setTextChannelMode(Channel channel, TextChannelMode mode) +{ + const TextChannelCallback outputCb = [this](const QString &text) { + GuardLocker locker(d->m_guard); + emit textOnStandardOutput(text); + }; + const TextChannelCallback errorCb = [this](const QString &text) { + GuardLocker locker(d->m_guard); + emit textOnStandardError(text); + }; + const TextChannelCallback callback = (channel == Channel::Output) ? outputCb : errorCb; + ChannelBuffer *buffer = channel == Channel::Output ? &d->m_stdOut : &d->m_stdErr; + QTC_ASSERT(buffer->m_textChannelMode == TextChannelMode::Off, qWarning() + << "QtcProcess::setTextChannelMode(): Changing text channel mode for" + << (channel == Channel::Output ? "Output": "Error") + << "channel while it was previously set for this channel."); + buffer->m_textChannelMode = mode; + switch (mode) { + case TextChannelMode::Off: + buffer->outputCallback = {}; + buffer->emitSingleLines = true; + buffer->keepRawData = true; + break; + case TextChannelMode::SingleLine: + buffer->outputCallback = callback; + buffer->emitSingleLines = true; + buffer->keepRawData = false; + break; + case TextChannelMode::MultiLine: + buffer->outputCallback = callback; + buffer->emitSingleLines = false; + buffer->keepRawData = true; + break; + } +} + +TextChannelMode QtcProcess::textChannelMode(Channel channel) const +{ + ChannelBuffer *buffer = channel == Channel::Output ? &d->m_stdOut : &d->m_stdErr; + return buffer->m_textChannelMode; +} + void QtcProcessPrivate::slotTimeout() { if (!m_waitingForUser && (++m_hangTimerCount > m_maxHangTimerCount)) { diff --git a/src/libs/utils/qtcprocess.h b/src/libs/utils/qtcprocess.h index 37a639dba6b..e553b397ee6 100644 --- a/src/libs/utils/qtcprocess.h +++ b/src/libs/utils/qtcprocess.h @@ -148,10 +148,13 @@ public: void setTimeOutMessageBoxEnabled(bool); void setExitCodeInterpreter(const ExitCodeInterpreter &interpreter); - void setStdOutCallback(const std::function &callback); - void setStdOutLineCallback(const std::function &callback); - void setStdErrCallback(const std::function &callback); - void setStdErrLineCallback(const std::function &callback); + void setStdOutCallback(const TextChannelCallback &callback); + void setStdOutLineCallback(const TextChannelCallback &callback); + void setStdErrCallback(const TextChannelCallback &callback); + void setStdErrLineCallback(const TextChannelCallback &callback); + + void setTextChannelMode(Channel channel, TextChannelMode mode); + TextChannelMode textChannelMode(Channel channel) const; bool readDataFromProcess(QByteArray *stdOut, QByteArray *stdErr, int timeoutS = 30); @@ -182,6 +185,8 @@ signals: void done(); // On Starting | Running -> NotRunning state transition void readyReadStandardOutput(); void readyReadStandardError(); + void textOnStandardOutput(const QString &text); + void textOnStandardError(const QString &text); private: friend QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug str, const QtcProcess &r); diff --git a/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp b/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp index 037729a389b..7a3ba45ec46 100644 --- a/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp +++ b/tests/auto/utils/qtcprocess/tst_qtcprocess.cpp @@ -112,7 +112,10 @@ private slots: void exitCode(); void runBlockingStdOut_data(); void runBlockingStdOut(); + void runBlockingSignal_data(); + void runBlockingSignal(); void lineCallback(); + void lineSignal(); void waitForStartedAfterStarted(); void waitForStartedAfterStarted2(); void waitForStartedAndFinished(); @@ -937,13 +940,46 @@ void tst_QtcProcess::runBlockingStdOut() QVERIFY2(readLastLine, "Last line was read."); } +void tst_QtcProcess::runBlockingSignal_data() +{ + runBlockingStdOut_data(); +} + +void tst_QtcProcess::runBlockingSignal() +{ + QFETCH(bool, withEndl); + QFETCH(int, timeOutS); + QFETCH(ProcessResult, expectedResult); + + SubProcessConfig subConfig(ProcessTestApp::RunBlockingStdOut::envVar(), withEndl ? "true" : "false"); + QtcProcess process; + subConfig.setupSubProcess(&process); + + process.setTimeoutS(timeOutS); + bool readLastLine = false; + process.setTextChannelMode(Channel::Output, TextChannelMode::MultiLine); + connect(&process, &QtcProcess::textOnStandardOutput, + this, [&readLastLine, &process](const QString &out) { + if (out.startsWith(s_runBlockingStdOutSubProcessMagicWord)) { + readLastLine = true; + process.kill(); + } + }); + process.runBlocking(); + + // See also QTCREATORBUG-25667 for why it is a bad idea to use QtcProcess::runBlocking + // with interactive cli tools. + QCOMPARE(process.result(), expectedResult); + QVERIFY2(readLastLine, "Last line was read."); +} + void tst_QtcProcess::lineCallback() { SubProcessConfig subConfig(ProcessTestApp::LineCallback::envVar(), {}); QtcProcess process; subConfig.setupSubProcess(&process); - QStringList lines = QString(s_lineCallbackData).split('|'); + const QStringList lines = QString(s_lineCallbackData).split('|'); int lineNumber = 0; process.setStdErrLineCallback([lines, &lineNumber](const QString &actual) { QString expected = lines.at(lineNumber); @@ -960,6 +996,31 @@ void tst_QtcProcess::lineCallback() QCOMPARE(lineNumber, lines.size()); } +void tst_QtcProcess::lineSignal() +{ + SubProcessConfig subConfig(ProcessTestApp::LineCallback::envVar(), {}); + QtcProcess process; + subConfig.setupSubProcess(&process); + + const QStringList lines = QString(s_lineCallbackData).split('|'); + int lineNumber = 0; + process.setTextChannelMode(Channel::Error, TextChannelMode::SingleLine); + connect(&process, &QtcProcess::textOnStandardError, + this, [lines, &lineNumber](const QString &actual) { + QString expected = lines.at(lineNumber); + expected.replace("\r\n", "\n"); + // Omit some initial lines generated by Qt, e.g. + // Warning: Ignoring WAYLAND_DISPLAY on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway. + if (lineNumber == 0 && actual != expected) + return; + ++lineNumber; + QCOMPARE(actual, expected); + }); + process.start(); + process.waitForFinished(); + QCOMPARE(lineNumber, lines.size()); +} + void tst_QtcProcess::waitForStartedAfterStarted() { SubProcessConfig subConfig(ProcessTestApp::SimpleTest::envVar(), {}); From 63faccdb7c62327ae80df852ac9e8504a137e810 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 7 Oct 2022 17:25:44 +0200 Subject: [PATCH 02/42] Utils: Implement ls-based subdir iteration Needed when 'find' does not work as expected. Change-Id: Ifbe762590ad2a6339152ed728e4d72820b4eae91 Reviewed-by: Marcus Tillmanns Reviewed-by: hjk --- src/libs/utils/fileutils.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp index ae83517440b..b4b952166fd 100644 --- a/src/libs/utils/fileutils.cpp +++ b/src/libs/utils/fileutils.cpp @@ -648,6 +648,24 @@ static bool iterateWithFind(const FilePath &filePath, return true; } +static void findUsingLs(const QString ¤t, + const FileFilter &filter, + const std::function &runInShell, + QStringList *found) +{ + const RunResult result = runInShell({"ls", {"-1", "-p", "--", current}}); + const QStringList entries = QString::fromUtf8(result.stdOut).split('\n', Qt::SkipEmptyParts); + for (QString entry : entries) { + const QChar last = entry.back(); + if (last == '/') { + entry.chop(1); + if (filter.iteratorFlags.testFlag(QDirIterator::Subdirectories)) + findUsingLs(current + '/' + entry, filter, runInShell, found); + } + found->append(entry); + } +} + void FileUtils::iterateUnixDirectory(const FilePath &filePath, const FileFilter &filter, bool *useFind, @@ -665,9 +683,8 @@ void FileUtils::iterateUnixDirectory(const FilePath &filePath, } // if we do not have find - use ls as fallback - // FIXME: Recursion into subdirectories not implemented! - const RunResult result = runInShell({"ls", {"-1", "-b", "--", filePath.path()}}); - const QStringList entries = QString::fromUtf8(result.stdOut).split('\n', Qt::SkipEmptyParts); + QStringList entries; + findUsingLs(filePath.path(), filter, runInShell, &entries); FileUtils::iterateLsOutput(filePath, entries, filter, callBack); } From 9e2ec17f3630133ca51b8a29891cc95c0a28e13d Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 10 Oct 2022 09:14:04 +0200 Subject: [PATCH 03/42] Meson: Convert to Tr::tr Change-Id: I37e8a8c559464f7d55e17a5ca08e8d8d9760a4d6 Reviewed-by: Alessandro Portale --- share/qtcreator/translations/qtcreator_de.ts | 56 +------------ share/qtcreator/translations/qtcreator_ja.ts | 35 +------- share/qtcreator/translations/qtcreator_ru.ts | 82 +------------------ .../mesonprojectmanager/arrayoptionlineedit.h | 1 - .../mesonprojectmanager/buildoptionsmodel.h | 3 +- src/plugins/mesonprojectmanager/infoparser.h | 1 + .../mesonprojectmanager/mesonactionsmanager.h | 5 +- .../mesonbuildsettingswidget.cpp | 15 ++-- .../mesonprojectmanager/mesonbuildsystem.cpp | 3 +- .../mesonprojectmanager/mesonprocess.cpp | 12 +-- .../mesonprojectmanager/mesonproject.cpp | 25 +++--- .../mesonprojectimporter.cpp | 6 +- .../mesontoolkitaspect.cpp | 11 +-- .../mesonprojectmanager/mesontoolkitaspect.h | 2 - .../nativefilegenerator.cpp | 2 - .../mesonprojectmanager/ninjabuildstep.cpp | 19 ++--- .../ninjatoolkitaspect.cpp | 13 +-- .../mesonprojectmanager/ninjatoolkitaspect.h | 2 - src/plugins/mesonprojectmanager/settings.cpp | 11 +-- src/plugins/mesonprojectmanager/settings.h | 4 - .../mesonprojectmanager/toolitemsettings.cpp | 5 +- .../mesonprojectmanager/toolkitaspectwidget.h | 2 - .../mesonprojectmanager/toolsmodel.cpp | 5 +- src/plugins/mesonprojectmanager/toolsmodel.h | 2 +- .../toolssettingsaccessor.cpp | 8 +- .../mesonprojectmanager/toolssettingspage.cpp | 3 +- .../mesonprojectmanager/toolssettingspage.h | 6 -- .../toolssettingswidget.cpp | 13 +-- .../mesonprojectmanager/toolssettingswidget.h | 8 +- .../mesonprojectmanager/tooltreeitem.cpp | 19 ++--- .../mesonprojectmanager/tooltreeitem.h | 3 +- 31 files changed, 104 insertions(+), 278 deletions(-) diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index 12fcd683b25..d5304ecd54e 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -47917,7 +47917,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e - MesonBuildSettingsWidget + Meson Apply Configuration Changes Konfigurationsänderungen anwenden @@ -47926,9 +47926,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Filter Filter - - - MesonBuildStepConfigWidget Tool arguments: Toolparameter: @@ -48420,7 +48417,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e - MesonProjectManager::Internal::MesonActionsManager + Meson Configure Konfigurieren @@ -48433,24 +48430,15 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Build "%1" "%1" erstellen - - - MesonProjectManager::Internal::MesonBuildSettingsWidget Meson Meson - - - MesonProjectManager::Internal::MesonBuildStepConfigWidget Build MesonProjectManager::MesonBuildStepConfigWidget display name. Erstellen - - - MesonProjectManager::Internal::BuidOptionsModel Key Schlüssel @@ -48459,9 +48447,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Value Wert - - - MesonProjectManager::Internal::MesonProcess Configuring "%1". Konfiguriere "%1" @@ -48502,48 +48487,18 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Executable does not exist: %1 Ausführbare Datei existiert nicht: %1 - - - MesonProjectManager::Internal::MesonProject No compilers set in kit. Im Kit sind keine Compiler eingerichtet. - - - MesonProjectManager::Internal::NinjaBuildStep - - Meson - Meson - - - - MesonProjectManager::Internal::GeneralSettingsPage General Allgemein - - - MesonProjectManager::Internal::MesonToolKitAspect - - Meson - Meson - Unconfigured Nicht konfiguriert - - - MesonProjectManager::Internal::NinjaToolKitAspect - - Unconfigured - Nicht konfiguriert - - - - MesonProjectManager::Internal::ToolsSettingsPage Name Name @@ -48573,13 +48528,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Kopie von %1 - - MesonProjectManager::MesonToolManager - - Meson - Meson - - Nim::NimToolChain diff --git a/share/qtcreator/translations/qtcreator_ja.ts b/share/qtcreator/translations/qtcreator_ja.ts index 3f12196f92b..0333577d9a2 100644 --- a/share/qtcreator/translations/qtcreator_ja.ts +++ b/share/qtcreator/translations/qtcreator_ja.ts @@ -45835,7 +45835,7 @@ Output: - MesonProjectManager::Internal::MesonBuildSettingsWidget + Meson Apply Configuration Changes 設定の変更を適用 @@ -45844,9 +45844,6 @@ Output: Filter フィルタ - - - MesonProjectManager::Internal::ToolItemSettings Name: 名前: @@ -45855,9 +45852,6 @@ Output: Path: パス: - - - MesonProjectManager::Internal::ToolsSettingsWidget Clone 複製 @@ -49749,7 +49743,7 @@ Stepping into the module or setting breakpoints by file and line is expected to - MesonProjectManager::Internal::MesonActionsManager + Meson Configure 設定する @@ -49762,16 +49756,10 @@ Stepping into the module or setting breakpoints by file and line is expected to Build "%1" "%1" のビルド - - - MesonProjectManager::Internal::BuidOptionsModel Value - - - MesonProjectManager::Internal::MesonProcess Process timed out. プロセスがタイムアウトしました。 @@ -49780,9 +49768,6 @@ Stepping into the module or setting breakpoints by file and line is expected to Executable does not exist: %1 実行ファイル が存在しません: %1 - - - MesonProjectManager::Internal::NinjaBuildStep Build MesonProjectManager::MesonBuildStepConfigWidget display name. @@ -49796,30 +49781,14 @@ Stepping into the module or setting breakpoints by file and line is expected to Targets: ターゲット: - - - MesonProjectManager::Internal::GeneralSettingsPage General 一般 - - - MesonProjectManager::Internal::MesonToolKitAspect Unconfigured 未設定 - - - MesonProjectManager::Internal::NinjaToolKitAspect - - Unconfigured - 未設定 - - - - MesonProjectManager::Internal::ToolsSettingsPage Name 名前 diff --git a/share/qtcreator/translations/qtcreator_ru.ts b/share/qtcreator/translations/qtcreator_ru.ts index 1e5357c56a2..f96dfc30724 100644 --- a/share/qtcreator/translations/qtcreator_ru.ts +++ b/share/qtcreator/translations/qtcreator_ru.ts @@ -26527,7 +26527,7 @@ Error: %5 - MesonBuildStepConfigWidget + Meson Form @@ -26540,9 +26540,6 @@ Error: %5 Targets: Цели: - - - MesonProjectManager::Internal::BuidOptionsModel Key Ключ @@ -26551,20 +26548,10 @@ Error: %5 Value Значение - - - MesonProjectManager::Internal::GeneralSettingsPage General Основное - - - MesonProjectManager::Internal::GeneralSettingsWidget - - Form - - Automatically run Meson when needed. Запускать Meson по необходимости. @@ -26581,9 +26568,6 @@ Error: %5 Ninja verbose mode Ninja в подробном режиме - - - MesonProjectManager::Internal::MesonActionsManager Configure Configure @@ -26596,17 +26580,10 @@ Error: %5 Build "%1" Сборка «%1» - - - MesonProjectManager::Internal::MesonBuildSettingsWidget Meson Meson - - Form - - Apply Configuration Changes Применить изменения @@ -26625,17 +26602,11 @@ Useful if build directory is corrupted or when rebuilding with a newer version o Filter Фильтр - - - MesonProjectManager::Internal::MesonBuildStepConfigWidget Build MesonProjectManager::MesonBuildStepConfigWidget display name. Сборка - - - MesonProjectManager::Internal::MesonProcess Configuring "%1". Настройка «%1». @@ -26680,9 +26651,6 @@ Useful if build directory is corrupted or when rebuilding with a newer version o Command is not executable: %1 Команда не запускается: %1 - - - MesonProjectManager::Internal::MesonProject No Meson tool set. Программа Meson не указана. @@ -26695,9 +26663,6 @@ Useful if build directory is corrupted or when rebuilding with a newer version o No compilers set in kit. У комплекта не заданы компиляторы. - - - MesonProjectManager::Internal::MesonToolKitAspect Meson Tool Утилита Meson @@ -26710,28 +26675,14 @@ Useful if build directory is corrupted or when rebuilding with a newer version o Cannot validate this meson executable. Невозможно проверить эту программу Meson. - - Meson - Meson - Unconfigured Не настроено - - - MesonProjectManager::Internal::NinjaBuildStep Meson Build Сборка Meson - - Meson - Meson - - - - MesonProjectManager::Internal::NinjaToolKitAspect Ninja Tool Утилита Ninja @@ -26748,17 +26699,6 @@ Useful if build directory is corrupted or when rebuilding with a newer version o Ninja Ninja - - Unconfigured - Не настроено - - - - MesonProjectManager::Internal::ToolItemSettings - - Form - - Name: Имя: @@ -26767,9 +26707,6 @@ Useful if build directory is corrupted or when rebuilding with a newer version o Path: Путь: - - - MesonProjectManager::Internal::ToolTreeItem Meson executable path does not exist. Не найден путь к программе Meson. @@ -26782,9 +26719,6 @@ Useful if build directory is corrupted or when rebuilding with a newer version o Meson executable path is not executable. Путь к программе Meson не исполняемый. - - - MesonProjectManager::Internal::ToolsSettingsPage Name Имя @@ -26821,13 +26755,6 @@ Useful if build directory is corrupted or when rebuilding with a newer version o Cannot get tool version. Не удалось получить версию инструмента. - - - MesonProjectManager::Internal::ToolsSettingsWidget - - Form - - Add Добавить @@ -26849,13 +26776,6 @@ Useful if build directory is corrupted or when rebuilding with a newer version o Сделать по умолчанию - - MesonProjectManager::MesonToolManager - - Meson - Meson - - MimeTypeDialog diff --git a/src/plugins/mesonprojectmanager/arrayoptionlineedit.h b/src/plugins/mesonprojectmanager/arrayoptionlineedit.h index c37d0acf268..1915e93b261 100644 --- a/src/plugins/mesonprojectmanager/arrayoptionlineedit.h +++ b/src/plugins/mesonprojectmanager/arrayoptionlineedit.h @@ -13,7 +13,6 @@ namespace Internal { class RegexHighlighter : public QSyntaxHighlighter { - Q_OBJECT const QRegularExpression m_regex{R"('([^']+)'+|([^', ]+)[, ]*)"}; QTextCharFormat m_format; diff --git a/src/plugins/mesonprojectmanager/buildoptionsmodel.h b/src/plugins/mesonprojectmanager/buildoptionsmodel.h index 3b951c65460..189bbca1543 100644 --- a/src/plugins/mesonprojectmanager/buildoptionsmodel.h +++ b/src/plugins/mesonprojectmanager/buildoptionsmodel.h @@ -3,7 +3,7 @@ #pragma once -#include "mesoninfoparser.h" +#include "buildoptions.h" #include #include @@ -66,6 +66,7 @@ public: } inline BuildOption::Type type() { return m_currentValue->type(); } }; + using CancellableOptionsList = std::vector>; class BuidOptionsModel final : public Utils::TreeModel<> { diff --git a/src/plugins/mesonprojectmanager/infoparser.h b/src/plugins/mesonprojectmanager/infoparser.h index 725e31a5e7c..e4feb311c63 100644 --- a/src/plugins/mesonprojectmanager/infoparser.h +++ b/src/plugins/mesonprojectmanager/infoparser.h @@ -3,6 +3,7 @@ #pragma once +#include "common.h" #include "mesoninfo.h" #include "mesonpluginconstants.h" diff --git a/src/plugins/mesonprojectmanager/mesonactionsmanager.h b/src/plugins/mesonprojectmanager/mesonactionsmanager.h index 2e84eaa1011..8cf00599f2c 100644 --- a/src/plugins/mesonprojectmanager/mesonactionsmanager.h +++ b/src/plugins/mesonprojectmanager/mesonactionsmanager.h @@ -3,6 +3,8 @@ #pragma once +#include "mesonprojectmanagertr.h" + #include namespace MesonProjectManager { @@ -12,7 +14,8 @@ class MesonActionsManager : public QObject { Q_OBJECT Utils::ParameterAction buildTargetContextAction{ - tr("Build"), tr("Build \"%1\""), Utils::ParameterAction::AlwaysEnabled /*handled manually*/ + Tr::tr("Build"), Tr::tr("Build \"%1\""), + Utils::ParameterAction::AlwaysEnabled /*handled manually*/ }; QAction configureActionMenu; QAction configureActionContextMenu; diff --git a/src/plugins/mesonprojectmanager/mesonbuildsettingswidget.cpp b/src/plugins/mesonprojectmanager/mesonbuildsettingswidget.cpp index 8bd682a7bc4..9757006d61b 100644 --- a/src/plugins/mesonprojectmanager/mesonbuildsettingswidget.cpp +++ b/src/plugins/mesonprojectmanager/mesonbuildsettingswidget.cpp @@ -5,6 +5,7 @@ #include "mesonbuildconfiguration.h" #include "mesonbuildsystem.h" +#include "mesonprojectmanagertr.h" #include @@ -25,19 +26,19 @@ using namespace Utils; namespace MesonProjectManager::Internal { MesonBuildSettingsWidget::MesonBuildSettingsWidget(MesonBuildConfiguration *buildCfg) - : ProjectExplorer::NamedWidget{tr("Meson")} + : ProjectExplorer::NamedWidget(Tr::tr("Meson")) , m_progressIndicator(ProgressIndicatorSize::Large) { - auto configureButton = new QPushButton(tr("Apply Configuration Changes")); + auto configureButton = new QPushButton(Tr::tr("Apply Configuration Changes")); configureButton->setEnabled(false); configureButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); - auto wipeButton = new QPushButton(tr("Wipe Project")); + auto wipeButton = new QPushButton(Tr::tr("Wipe Project")); wipeButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); wipeButton->setIcon(Utils::Icons::WARNING.icon()); - wipeButton->setToolTip(tr("Wipes build directory and reconfigures using previous command " - "line options.\nUseful if build directory is corrupted or when " - "rebuilding with a newer version of Meson.")); + wipeButton->setToolTip(Tr::tr("Wipes build directory and reconfigures using previous command " + "line options.\nUseful if build directory is corrupted or when " + "rebuilding with a newer version of Meson.")); auto container = new DetailsWidget; @@ -62,7 +63,7 @@ MesonBuildSettingsWidget::MesonBuildSettingsWidget(MesonBuildConfiguration *buil using namespace Layouting; Column { - Form { tr("Parameters"), parametersLineEdit, br, }, + Form { Tr::tr("Parameters"), parametersLineEdit, br, }, buildDirWidget, optionsFilterLineEdit, optionsTreeView, diff --git a/src/plugins/mesonprojectmanager/mesonbuildsystem.cpp b/src/plugins/mesonprojectmanager/mesonbuildsystem.cpp index 5aa27323f9f..0154ee18403 100644 --- a/src/plugins/mesonprojectmanager/mesonbuildsystem.cpp +++ b/src/plugins/mesonprojectmanager/mesonbuildsystem.cpp @@ -6,6 +6,7 @@ #include "kithelper.h" #include "machinefilemanager.h" #include "mesonbuildconfiguration.h" +#include "mesonprojectmanagertr.h" #include "mesontoolkitaspect.h" #include "settings.h" @@ -82,7 +83,7 @@ void MesonBuildSystem::parsingCompleted(bool success) UNLOCK(true); emitBuildSystemUpdated(); } else { - TaskHub::addTask(BuildSystemTask(Task::Error, tr("Meson build: Parsing failed"))); + TaskHub::addTask(BuildSystemTask(Task::Error, Tr::tr("Meson build: Parsing failed"))); UNLOCK(false); emitBuildSystemUpdated(); } diff --git a/src/plugins/mesonprojectmanager/mesonprocess.cpp b/src/plugins/mesonprojectmanager/mesonprocess.cpp index ffd23761b04..b7b40f568ec 100644 --- a/src/plugins/mesonprojectmanager/mesonprocess.cpp +++ b/src/plugins/mesonprojectmanager/mesonprocess.cpp @@ -3,7 +3,7 @@ #include "mesonprocess.h" -#include "mesonoutputparser.h" +#include "mesonprojectmanagertr.h" #include #include @@ -44,7 +44,7 @@ bool MesonProcess::run(const Command &command, setupProcess(command, env, captureStdo); m_future.setProgressRange(0, 1); Core::ProgressManager::addTimedTask(m_future, - tr("Configuring \"%1\".").arg(projectName), + Tr::tr("Configuring \"%1\".").arg(projectName), "Meson.Configure", 10); emit started(); @@ -121,7 +121,7 @@ void MesonProcess::setupProcess(const Command &command, m_process->setWorkingDirectory(command.workDir()); m_process->setEnvironment(env); Core::MessageManager::writeFlashing( - tr("Running %1 in %2.").arg(command.toUserOutput()).arg(command.workDir().toUserOutput())); + Tr::tr("Running %1 in %2.").arg(command.toUserOutput()).arg(command.workDir().toUserOutput())); m_process->setCommand(command.cmdLine()); } @@ -132,15 +132,15 @@ bool MesonProcess::sanityCheck(const Command &command) const //Should only reach this point if Meson exe is removed while a Meson project is opened ProjectExplorer::TaskHub::addTask( ProjectExplorer::BuildSystemTask{ProjectExplorer::Task::TaskType::Error, - tr("Executable does not exist: %1") + Tr::tr("Executable does not exist: %1") .arg(exe.toUserOutput())}); return false; } if (!exe.toFileInfo().isExecutable()) { ProjectExplorer::TaskHub::addTask( ProjectExplorer::BuildSystemTask{ProjectExplorer::Task::TaskType::Error, - tr("Command is not executable: %1") - .arg(exe.toUserOutput())}); + Tr::tr("Command is not executable: %1") + .arg(exe.toUserOutput())}); return false; } return true; diff --git a/src/plugins/mesonprojectmanager/mesonproject.cpp b/src/plugins/mesonprojectmanager/mesonproject.cpp index a8857ba94df..ec007b6ace1 100644 --- a/src/plugins/mesonprojectmanager/mesonproject.cpp +++ b/src/plugins/mesonprojectmanager/mesonproject.cpp @@ -4,6 +4,7 @@ #include "mesonproject.h" #include "mesonpluginconstants.h" +#include "mesonprojectmanagertr.h" #include "mesontoolkitaspect.h" #include "ninjatoolkitaspect.h" @@ -13,11 +14,13 @@ #include #include +using namespace ProjectExplorer; + namespace MesonProjectManager { namespace Internal { MesonProject::MesonProject(const Utils::FilePath &path) - : ProjectExplorer::Project{Constants::Project::MIMETYPE, path} + : Project{Constants::Project::MIMETYPE, path} { setId(Constants::Project::ID); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); @@ -26,33 +29,33 @@ MesonProject::MesonProject(const Utils::FilePath &path) setHasMakeInstallEquivalent(true); } -ProjectExplorer::Tasks MesonProject::projectIssues(const ProjectExplorer::Kit *k) const +Tasks MesonProject::projectIssues(const Kit *k) const { - ProjectExplorer::Tasks result = Project::projectIssues(k); + Tasks result = Project::projectIssues(k); if (!MesonToolKitAspect::isValid(k)) result.append( - createProjectTask(ProjectExplorer::Task::TaskType::Error, tr("No Meson tool set."))); + createProjectTask(Task::TaskType::Error, Tr::tr("No Meson tool set."))); if (!NinjaToolKitAspect::isValid(k)) result.append( - createProjectTask(ProjectExplorer::Task::TaskType::Error, tr("No Ninja tool set."))); - if (ProjectExplorer::ToolChainKitAspect::toolChains(k).isEmpty()) - result.append(createProjectTask(ProjectExplorer::Task::TaskType::Warning, - tr("No compilers set in kit."))); + createProjectTask(Task::TaskType::Error, Tr::tr("No Ninja tool set."))); + if (ToolChainKitAspect::toolChains(k).isEmpty()) + result.append(createProjectTask(Task::TaskType::Warning, + Tr::tr("No compilers set in kit."))); return result; } -ProjectExplorer::ProjectImporter *MesonProject::projectImporter() const +ProjectImporter *MesonProject::projectImporter() const { if (m_projectImporter) m_projectImporter = std::make_unique(projectFilePath()); return m_projectImporter.get(); } -ProjectExplorer::DeploymentKnowledge MesonProject::deploymentKnowledge() const +DeploymentKnowledge MesonProject::deploymentKnowledge() const { // TODO in next releases - return ProjectExplorer::DeploymentKnowledge::Bad; + return DeploymentKnowledge::Bad; } } // namespace Internal diff --git a/src/plugins/mesonprojectmanager/mesonprojectimporter.cpp b/src/plugins/mesonprojectmanager/mesonprojectimporter.cpp index 3fbf32abe25..291ddf8b7b0 100644 --- a/src/plugins/mesonprojectmanager/mesonprojectimporter.cpp +++ b/src/plugins/mesonprojectmanager/mesonprojectimporter.cpp @@ -5,13 +5,11 @@ #include -namespace { -static Q_LOGGING_CATEGORY(mInputLog, "qtc.meson.import", QtWarningMsg); -} - namespace MesonProjectManager { namespace Internal { +static Q_LOGGING_CATEGORY(mInputLog, "qtc.meson.import", QtWarningMsg); + MesonProjectImporter::MesonProjectImporter(const Utils::FilePath &path) : QtSupport::QtProjectImporter{path} {} diff --git a/src/plugins/mesonprojectmanager/mesontoolkitaspect.cpp b/src/plugins/mesonprojectmanager/mesontoolkitaspect.cpp index 41522288b11..69f0fef118f 100644 --- a/src/plugins/mesonprojectmanager/mesontoolkitaspect.cpp +++ b/src/plugins/mesonprojectmanager/mesontoolkitaspect.cpp @@ -3,6 +3,7 @@ #include "mesontoolkitaspect.h" +#include "mesonprojectmanagertr.h" #include "toolkitaspectwidget.h" #include @@ -16,8 +17,8 @@ MesonToolKitAspect::MesonToolKitAspect() { setObjectName(QLatin1String("MesonKitAspect")); setId(TOOL_ID); - setDisplayName(tr("Meson Tool")); - setDescription(tr("The Meson tool to use when building a project with Meson.
" + setDisplayName(Tr::tr("Meson Tool")); + setDescription(Tr::tr("The Meson tool to use when building a project with Meson.
" "This setting is ignored when using other build systems.")); setPriority(9000); } @@ -28,7 +29,7 @@ ProjectExplorer::Tasks MesonToolKitAspect::validate(const ProjectExplorer::Kit * const auto tool = mesonTool(k); if (tool && !tool->isValid()) tasks << ProjectExplorer::BuildSystemTask{ProjectExplorer::Task::Warning, - tr("Cannot validate this meson executable.")}; + Tr::tr("Cannot validate this meson executable.")}; return tasks; } @@ -52,8 +53,8 @@ ProjectExplorer::KitAspect::ItemList MesonToolKitAspect::toUserOutput( { const auto tool = mesonTool(k); if (tool) - return {{tr("Meson"), tool->name()}}; - return {{tr("Meson"), tr("Unconfigured")}}; + return {{Tr::tr("Meson"), tool->name()}}; + return {{Tr::tr("Meson"), Tr::tr("Unconfigured")}}; } ProjectExplorer::KitAspectWidget *MesonToolKitAspect::createConfigWidget(ProjectExplorer::Kit *k) const diff --git a/src/plugins/mesonprojectmanager/mesontoolkitaspect.h b/src/plugins/mesonprojectmanager/mesontoolkitaspect.h index 9f5c37f4bbe..71246b7ee8f 100644 --- a/src/plugins/mesonprojectmanager/mesontoolkitaspect.h +++ b/src/plugins/mesonprojectmanager/mesontoolkitaspect.h @@ -13,8 +13,6 @@ namespace Internal { class MesonToolKitAspect final : public ProjectExplorer::KitAspect { - Q_DECLARE_TR_FUNCTIONS(MesonProjectManager::Internal::MesonToolKitAspect) - public: MesonToolKitAspect(); diff --git a/src/plugins/mesonprojectmanager/nativefilegenerator.cpp b/src/plugins/mesonprojectmanager/nativefilegenerator.cpp index d434a07815f..f4e969b99a3 100644 --- a/src/plugins/mesonprojectmanager/nativefilegenerator.cpp +++ b/src/plugins/mesonprojectmanager/nativefilegenerator.cpp @@ -3,8 +3,6 @@ #include "nativefilegenerator.h" -#include "kithelper.h" - #include #include #include diff --git a/src/plugins/mesonprojectmanager/ninjabuildstep.cpp b/src/plugins/mesonprojectmanager/ninjabuildstep.cpp index a09b82c5999..4466106b0f5 100644 --- a/src/plugins/mesonprojectmanager/ninjabuildstep.cpp +++ b/src/plugins/mesonprojectmanager/ninjabuildstep.cpp @@ -6,6 +6,7 @@ #include "mesonbuildconfiguration.h" #include "mesonbuildsystem.h" #include "mesonpluginconstants.h" +#include "mesonprojectmanagertr.h" #include "mesonoutputparser.h" #include "ninjatoolkitaspect.h" #include "settings.h" @@ -32,8 +33,8 @@ namespace Internal { const char TARGETS_KEY[] = "MesonProjectManager.BuildStep.BuildTargets"; const char TOOL_ARGUMENTS_KEY[] = "MesonProjectManager.BuildStep.AdditionalArguments"; -NinjaBuildStep::NinjaBuildStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id) - : ProjectExplorer::AbstractProcessStep{bsl, id} +NinjaBuildStep::NinjaBuildStep(BuildStepList *bsl, Id id) + : AbstractProcessStep{bsl, id} { if (m_targetName.isEmpty()) setBuildTarget(defaultBuildTarget()); @@ -43,16 +44,14 @@ NinjaBuildStep::NinjaBuildStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id setUseEnglishOutput(); connect(target(), &ProjectExplorer::Target::parsingFinished, this, &NinjaBuildStep::update); - connect(&Settings::instance()->verboseNinja, - &BaseAspect::changed, - this, - &NinjaBuildStep::commandChanged); + connect(&Settings::instance()->verboseNinja, &BaseAspect::changed, + this, &NinjaBuildStep::commandChanged); } QWidget *NinjaBuildStep::createConfigWidget() { auto widget = new QWidget; - setDisplayName(tr("Build", "MesonProjectManager::MesonBuildStepConfigWidget display name.")); + setDisplayName(Tr::tr("Build", "MesonProjectManager::MesonBuildStepConfigWidget display name.")); auto buildTargetsList = new QListWidget(widget); buildTargetsList->setMinimumHeight(200); @@ -67,8 +66,8 @@ QWidget *NinjaBuildStep::createConfigWidget() auto formLayout = new QFormLayout(widget); formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); formLayout->setContentsMargins(0, 0, 0, 0); - formLayout->addRow(tr("Tool arguments:"), toolArguments); - formLayout->addRow(tr("Targets:"), wrapper); + formLayout->addRow(Tr::tr("Tool arguments:"), toolArguments); + formLayout->addRow(Tr::tr("Targets:"), wrapper); auto updateDetails = [this] { ProcessParameters param; @@ -188,7 +187,7 @@ MesonBuildStepFactory::MesonBuildStepFactory() { registerStep(Constants::MESON_BUILD_STEP_ID); setSupportedProjectType(Constants::Project::ID); - setDisplayName(NinjaBuildStep::tr("Meson Build")); + setDisplayName(Tr::tr("Meson Build")); } void MesonProjectManager::Internal::NinjaBuildStep::setBuildTarget(const QString &targetName) diff --git a/src/plugins/mesonprojectmanager/ninjatoolkitaspect.cpp b/src/plugins/mesonprojectmanager/ninjatoolkitaspect.cpp index 1b5bf53ba5b..2bf7551ed80 100644 --- a/src/plugins/mesonprojectmanager/ninjatoolkitaspect.cpp +++ b/src/plugins/mesonprojectmanager/ninjatoolkitaspect.cpp @@ -3,6 +3,7 @@ #include "ninjatoolkitaspect.h" +#include "mesonprojectmanagertr.h" #include "toolkitaspectwidget.h" #include @@ -16,9 +17,9 @@ NinjaToolKitAspect::NinjaToolKitAspect() { setObjectName(QLatin1String("NinjaKitAspect")); setId(TOOL_ID); - setDisplayName(tr("Ninja Tool")); - setDescription(tr("The Ninja tool to use when building a project with Meson.
" - "This setting is ignored when using other build systems.")); + setDisplayName(Tr::tr("Ninja Tool")); + setDescription(Tr::tr("The Ninja tool to use when building a project with Meson.
" + "This setting is ignored when using other build systems.")); setPriority(9000); } @@ -28,7 +29,7 @@ ProjectExplorer::Tasks NinjaToolKitAspect::validate(const ProjectExplorer::Kit * const auto tool = ninjaTool(k); if (tool && !tool->isValid()) tasks << ProjectExplorer::BuildSystemTask{ProjectExplorer::Task::Warning, - tr("Cannot validate this Ninja executable.")}; + Tr::tr("Cannot validate this Ninja executable.")}; return tasks; } @@ -52,8 +53,8 @@ ProjectExplorer::KitAspect::ItemList NinjaToolKitAspect::toUserOutput( { const auto tool = ninjaTool(k); if (tool) - return {{tr("Ninja"), tool->name()}}; - return {{tr("Ninja"), tr("Unconfigured")}}; + return {{Tr::tr("Ninja"), tool->name()}}; + return {{Tr::tr("Ninja"), Tr::tr("Unconfigured")}}; } ProjectExplorer::KitAspectWidget *NinjaToolKitAspect::createConfigWidget(ProjectExplorer::Kit *k) const diff --git a/src/plugins/mesonprojectmanager/ninjatoolkitaspect.h b/src/plugins/mesonprojectmanager/ninjatoolkitaspect.h index 7a4eed9e030..f70ad05363a 100644 --- a/src/plugins/mesonprojectmanager/ninjatoolkitaspect.h +++ b/src/plugins/mesonprojectmanager/ninjatoolkitaspect.h @@ -13,8 +13,6 @@ namespace Internal { class NinjaToolKitAspect final : public ProjectExplorer::KitAspect { - Q_DECLARE_TR_FUNCTIONS(MesonProjectManager::Internal::NinjaToolKitAspect) - public: NinjaToolKitAspect(); diff --git a/src/plugins/mesonprojectmanager/settings.cpp b/src/plugins/mesonprojectmanager/settings.cpp index 6a983f194a9..6de23e55542 100644 --- a/src/plugins/mesonprojectmanager/settings.cpp +++ b/src/plugins/mesonprojectmanager/settings.cpp @@ -4,6 +4,7 @@ #include "settings.h" #include "mesonpluginconstants.h" +#include "mesonprojectmanagertr.h" #include @@ -16,12 +17,12 @@ Settings::Settings() setAutoApply(false); autorunMeson.setSettingsKey("meson.autorun"); - autorunMeson.setLabelText(tr("Autorun Meson")); - autorunMeson.setToolTip(tr("Automatically run Meson when needed.")); + autorunMeson.setLabelText(Tr::tr("Autorun Meson")); + autorunMeson.setToolTip(Tr::tr("Automatically run Meson when needed.")); verboseNinja.setSettingsKey("ninja.verbose"); - verboseNinja.setLabelText(tr("Ninja verbose mode")); - verboseNinja.setToolTip(tr("Enables verbose mode by default when invoking Ninja.")); + verboseNinja.setLabelText(Tr::tr("Ninja verbose mode")); + verboseNinja.setToolTip(Tr::tr("Enables verbose mode by default when invoking Ninja.")); registerAspect(&autorunMeson); registerAspect(&verboseNinja); @@ -36,7 +37,7 @@ Settings *Settings::instance() GeneralSettingsPage::GeneralSettingsPage() { setId(Constants::SettingsPage::GENERAL_ID); - setDisplayName(tr("General")); + setDisplayName(Tr::tr("General")); setDisplayCategory("Meson"); setCategory(Constants::SettingsPage::CATEGORY); setCategoryIconPath(Constants::Icons::MESON_BW); diff --git a/src/plugins/mesonprojectmanager/settings.h b/src/plugins/mesonprojectmanager/settings.h index e9c920b382c..4022b6af9f4 100644 --- a/src/plugins/mesonprojectmanager/settings.h +++ b/src/plugins/mesonprojectmanager/settings.h @@ -12,8 +12,6 @@ namespace Internal { class Settings : public Utils::AspectContainer { - Q_DECLARE_TR_FUNCTIONS(MesonProjectManager::Internal::Settings) - public: Settings(); @@ -25,8 +23,6 @@ public: class GeneralSettingsPage final : public Core::IOptionsPage { - Q_DECLARE_TR_FUNCTIONS(MesonProjectManager::Internal::GeneralSettingsPage) - public: GeneralSettingsPage(); }; diff --git a/src/plugins/mesonprojectmanager/toolitemsettings.cpp b/src/plugins/mesonprojectmanager/toolitemsettings.cpp index 918231b198f..cfb3e13772e 100644 --- a/src/plugins/mesonprojectmanager/toolitemsettings.cpp +++ b/src/plugins/mesonprojectmanager/toolitemsettings.cpp @@ -3,6 +3,7 @@ #include "toolitemsettings.h" +#include "mesonprojectmanagertr.h" #include "tooltreeitem.h" #include @@ -26,8 +27,8 @@ ToolItemSettings::ToolItemSettings(QWidget *parent) using namespace Layouting; Form { - tr("Name:"), m_mesonNameLineEdit, br, - tr("Path:"), m_mesonPathChooser, br, + Tr::tr("Name:"), m_mesonNameLineEdit, br, + Tr::tr("Path:"), m_mesonPathChooser, br, }.attachTo(this, WithoutMargins); connect(m_mesonPathChooser, &PathChooser::rawPathChanged, this, &ToolItemSettings::store); diff --git a/src/plugins/mesonprojectmanager/toolkitaspectwidget.h b/src/plugins/mesonprojectmanager/toolkitaspectwidget.h index 8b389aa0318..818704483c7 100644 --- a/src/plugins/mesonprojectmanager/toolkitaspectwidget.h +++ b/src/plugins/mesonprojectmanager/toolkitaspectwidget.h @@ -3,7 +3,6 @@ #pragma once #include "mesontoolkitaspect.h" -#include "mesonwrapper.h" #include "ninjatoolkitaspect.h" #include @@ -18,7 +17,6 @@ namespace Internal { class ToolKitAspectWidget final : public ProjectExplorer::KitAspectWidget { - Q_DECLARE_TR_FUNCTIONS(MesonProjectManager::Internal::ToolKitAspect) public: enum class ToolType { Meson, Ninja }; diff --git a/src/plugins/mesonprojectmanager/toolsmodel.cpp b/src/plugins/mesonprojectmanager/toolsmodel.cpp index 9c1407387ef..d816cd3df17 100644 --- a/src/plugins/mesonprojectmanager/toolsmodel.cpp +++ b/src/plugins/mesonprojectmanager/toolsmodel.cpp @@ -4,6 +4,7 @@ #include "toolsmodel.h" #include "tooltreeitem.h" +#include "mesonprojectmanagertr.h" #include "mesontools.h" #include @@ -15,7 +16,7 @@ namespace Internal { ToolsModel::ToolsModel() { - setHeader({tr("Name"), tr("Location")}); + setHeader({Tr::tr("Name"), Tr::tr("Location")}); rootItem()->appendChild( new Utils::StaticTreeItem({ProjectExplorer::Constants::msgAutoDetected()}, {ProjectExplorer::Constants::msgAutoDetectedToolTip()})); @@ -39,7 +40,7 @@ void ToolsModel::updateItem(const Utils::Id &itemId, const QString &name, const void ToolsModel::addMesonTool() { - manualGroup()->appendChild(new ToolTreeItem{uniqueName(tr("New Meson or Ninja tool"))}); + manualGroup()->appendChild(new ToolTreeItem{uniqueName(Tr::tr("New Meson or Ninja tool"))}); } void ToolsModel::removeMesonTool(ToolTreeItem *item) diff --git a/src/plugins/mesonprojectmanager/toolsmodel.h b/src/plugins/mesonprojectmanager/toolsmodel.h index b37dca1015c..d580b10b1f5 100644 --- a/src/plugins/mesonprojectmanager/toolsmodel.h +++ b/src/plugins/mesonprojectmanager/toolsmodel.h @@ -17,9 +17,9 @@ class ToolTreeItem; class ToolsModel final : public Utils::TreeModel { - Q_DECLARE_TR_FUNCTIONS(MesonProjectManager::Internal::ToolsSettingsPage) public: ToolsModel(); + ToolTreeItem *mesoneToolTreeItem(const QModelIndex &index) const; void updateItem(const Utils::Id &itemId, const QString &name, const Utils::FilePath &exe); void addMesonTool(); diff --git a/src/plugins/mesonprojectmanager/toolssettingsaccessor.cpp b/src/plugins/mesonprojectmanager/toolssettingsaccessor.cpp index 54f293f819a..8ee88d64d44 100644 --- a/src/plugins/mesonprojectmanager/toolssettingsaccessor.cpp +++ b/src/plugins/mesonprojectmanager/toolssettingsaccessor.cpp @@ -4,6 +4,7 @@ #include "toolssettingsaccessor.h" #include "mesonpluginconstants.h" +#include "mesonprojectmanagertr.h" #include #include @@ -18,18 +19,15 @@ namespace MesonProjectManager { namespace Internal { -namespace { -inline QString entryName(int index) +static QString entryName(int index) { using namespace Constants; return QString("%1%2").arg(ToolsSettings::ENTRY_KEY).arg(index); } -} // namespace ToolsSettingsAccessor::ToolsSettingsAccessor() : UpgradingSettingsAccessor("QtCreatorMesonTools", - QCoreApplication::translate("MesonProjectManager::MesonToolManager", - "Meson"), + Tr::tr("Meson"), Core::Constants::IDE_DISPLAY_NAME) { setBaseFilePath(Core::ICore::userResourcePath(Constants::ToolsSettings::FILENAME)); diff --git a/src/plugins/mesonprojectmanager/toolssettingspage.cpp b/src/plugins/mesonprojectmanager/toolssettingspage.cpp index 3579dc15fbe..39c60a00fce 100644 --- a/src/plugins/mesonprojectmanager/toolssettingspage.cpp +++ b/src/plugins/mesonprojectmanager/toolssettingspage.cpp @@ -4,6 +4,7 @@ #include "toolssettingspage.h" #include "mesonpluginconstants.h" +#include "mesonprojectmanagertr.h" #include "toolssettingswidget.h" namespace MesonProjectManager { @@ -12,7 +13,7 @@ namespace Internal { ToolsSettingsPage::ToolsSettingsPage() { setId(Constants::SettingsPage::TOOLS_ID); - setDisplayName(tr("Tools")); + setDisplayName(Tr::tr("Tools")); setCategory(Constants::SettingsPage::CATEGORY); setWidgetCreator([]() { return new ToolsSettingsWidget; }); } diff --git a/src/plugins/mesonprojectmanager/toolssettingspage.h b/src/plugins/mesonprojectmanager/toolssettingspage.h index c0f0a11fd84..2bdfce1024b 100644 --- a/src/plugins/mesonprojectmanager/toolssettingspage.h +++ b/src/plugins/mesonprojectmanager/toolssettingspage.h @@ -5,17 +5,11 @@ #include -#include - namespace MesonProjectManager { namespace Internal { -class MesonTools; - class ToolsSettingsPage final : public Core::IOptionsPage { - Q_DECLARE_TR_FUNCTIONS(MesonProjectManager::Internal::ToolsSettingsPage) - public: ToolsSettingsPage(); }; diff --git a/src/plugins/mesonprojectmanager/toolssettingswidget.cpp b/src/plugins/mesonprojectmanager/toolssettingswidget.cpp index e7bda909709..2a744db1dbb 100644 --- a/src/plugins/mesonprojectmanager/toolssettingswidget.cpp +++ b/src/plugins/mesonprojectmanager/toolssettingswidget.cpp @@ -3,6 +3,7 @@ #include "toolssettingswidget.h" +#include "mesonprojectmanagertr.h" #include "toolsmodel.h" #include "tooltreeitem.h" @@ -33,19 +34,19 @@ ToolsSettingsWidget::ToolsSettingsWidget() m_mesonDetails->setVisible(false); m_mesonDetails->setWidget(m_itemSettings); - auto addButton = new QPushButton(tr("Add")); + auto addButton = new QPushButton(Tr::tr("Add")); - m_cloneButton = new QPushButton(tr("Clone")); + m_cloneButton = new QPushButton(Tr::tr("Clone")); m_cloneButton->setEnabled(false); - m_removeButton = new QPushButton(tr("Remove")); + m_removeButton = new QPushButton(Tr::tr("Remove")); m_removeButton->setEnabled(false); - auto makeDefaultButton = new QPushButton(tr("Make Default")); + auto makeDefaultButton = new QPushButton(Tr::tr("Make Default")); makeDefaultButton->setEnabled(false); makeDefaultButton->setVisible(false); - makeDefaultButton->setToolTip(tr("Set as the default Meson executable to use " - "when creating a new kit or when no value is set.")); + makeDefaultButton->setToolTip(Tr::tr("Set as the default Meson executable to use " + "when creating a new kit or when no value is set.")); using namespace Layouting; diff --git a/src/plugins/mesonprojectmanager/toolssettingswidget.h b/src/plugins/mesonprojectmanager/toolssettingswidget.h index f6ef2f28d6f..0fd08a8f903 100644 --- a/src/plugins/mesonprojectmanager/toolssettingswidget.h +++ b/src/plugins/mesonprojectmanager/toolssettingswidget.h @@ -8,23 +8,21 @@ #include -#include - namespace Utils { class DetailsWidget; } namespace MesonProjectManager::Internal { class ToolTreeItem; + class ToolsSettingsWidget final : public Core::IOptionsPageWidget { - Q_DECLARE_TR_FUNCTIONS(MesonProjectManager::Internal::ToolsSettingsWidget) - void apply() final; - public: explicit ToolsSettingsWidget(); ~ToolsSettingsWidget(); private: + void apply() final; + void cloneMesonTool(); void removeMesonTool(); void currentMesonToolChanged(const QModelIndex &newCurrent); diff --git a/src/plugins/mesonprojectmanager/tooltreeitem.cpp b/src/plugins/mesonprojectmanager/tooltreeitem.cpp index 60f0772592a..8de706d0613 100644 --- a/src/plugins/mesonprojectmanager/tooltreeitem.cpp +++ b/src/plugins/mesonprojectmanager/tooltreeitem.cpp @@ -3,6 +3,8 @@ #include "tooltreeitem.h" +#include "mesonprojectmanagertr.h" + #include #include @@ -27,12 +29,12 @@ ToolTreeItem::ToolTreeItem(const MesonTools::Tool_t &tool) , m_autoDetected{tool->autoDetected()} , m_id{tool->id()} { - m_tooltip = tr("Version: %1").arg(tool->version().toQString()); + m_tooltip = Tr::tr("Version: %1").arg(tool->version().toQString()); self_check(); } ToolTreeItem::ToolTreeItem(const ToolTreeItem &other) - : m_name{tr("Clone of %1").arg(other.m_name)} + : m_name{Tr::tr("Clone of %1").arg(other.m_name)} , m_executable{other.m_executable} , m_autoDetected{false} , m_id{Utils::Id::fromString(QUuid::createUuid().toString())} @@ -63,14 +65,11 @@ QVariant ToolTreeItem::data(int column, int role) const } case Qt::ToolTipRole: { if (!m_pathExists) - return QCoreApplication::translate("MesonProjectManager::Internal::ToolTreeItem", - "Meson executable path does not exist."); + return Tr::tr("Meson executable path does not exist."); if (!m_pathIsFile) - return QCoreApplication::translate("MesonProjectManager::Internal::ToolTreeItem", - "Meson executable path is not a file."); + return Tr::tr("Meson executable path is not a file."); if (!m_pathIsExecutable) - return QCoreApplication::translate("MesonProjectManager::Internal::ToolTreeItem", - "Meson executable path is not executable."); + return Tr::tr("Meson executable path is not executable."); return m_tooltip; } case Qt::DecorationRole: { @@ -103,9 +102,9 @@ void ToolTreeItem::self_check() void ToolTreeItem::update_tooltip(const Version &version) { if (version.isValid) - m_tooltip = tr("Version: %1").arg(version.toQString()); + m_tooltip = Tr::tr("Version: %1").arg(version.toQString()); else - m_tooltip = tr("Cannot get tool version."); + m_tooltip = Tr::tr("Cannot get tool version."); } void ToolTreeItem::update_tooltip() diff --git a/src/plugins/mesonprojectmanager/tooltreeitem.h b/src/plugins/mesonprojectmanager/tooltreeitem.h index 6e8592bf6f2..dded93c061d 100644 --- a/src/plugins/mesonprojectmanager/tooltreeitem.h +++ b/src/plugins/mesonprojectmanager/tooltreeitem.h @@ -4,7 +4,6 @@ #pragma once #include "mesontools.h" -#include "toolssettingspage.h" #include #include @@ -20,11 +19,11 @@ namespace Internal { class ToolTreeItem final : public Utils::TreeItem { - Q_DECLARE_TR_FUNCTIONS(MesonProjectManager::Internal::ToolsSettingsPage) public: ToolTreeItem(const QString &name); ToolTreeItem(const MesonTools::Tool_t &tool); ToolTreeItem(const ToolTreeItem &other); + QVariant data(int column, int role) const override; inline bool isAutoDetected() const noexcept { return m_autoDetected; } inline QString name() const noexcept { return m_name; } From c09351e101443889fce34e0113f9bb31f3394ba8 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 10 Oct 2022 10:55:32 +0200 Subject: [PATCH 04/42] Squish: Provide error message for license issues Change-Id: I1b3ca3aba19df2fbc2accd9ecf9e4ec2d862c6d8 Reviewed-by: David Schulz --- src/plugins/squish/squishfilehandler.cpp | 2 +- src/plugins/squish/squishsettings.cpp | 2 +- src/plugins/squish/squishtools.cpp | 8 +++++++- src/plugins/squish/squishtools.h | 3 ++- src/plugins/squish/squishwizardpages.cpp | 7 ++++++- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/plugins/squish/squishfilehandler.cpp b/src/plugins/squish/squishfilehandler.cpp index 5bc9a5be21b..0417aa0ef80 100644 --- a/src/plugins/squish/squishfilehandler.cpp +++ b/src/plugins/squish/squishfilehandler.cpp @@ -74,7 +74,7 @@ public: auto squishTools = SquishTools::instance(); connect(squishTools, &SquishTools::queryFinished, this, - [this] (const QString &out) { + [this] (const QString &out, const QString &) { SquishServerSettings s; s.setFromXmlOutput(out); QApplication::restoreOverrideCursor(); diff --git a/src/plugins/squish/squishsettings.cpp b/src/plugins/squish/squishsettings.cpp index 93f37e9d70c..f560e9bd6b3 100644 --- a/src/plugins/squish/squishsettings.cpp +++ b/src/plugins/squish/squishsettings.cpp @@ -393,7 +393,7 @@ SquishServerSettingsWidget::SquishServerSettingsWidget(QWidget *parent) // query settings SquishTools *squishTools = SquishTools::instance(); connect(squishTools, &SquishTools::queryFinished, this, - [this, progress] (const QString &out) { + [this, progress] (const QString &out, const QString &) { m_serverSettings.setFromXmlOutput(out); m_originalSettings.setFromXmlOutput(out); repopulateApplicationView(); diff --git a/src/plugins/squish/squishtools.cpp b/src/plugins/squish/squishtools.cpp index ca0a4ba600e..614ac1f1e82 100644 --- a/src/plugins/squish/squishtools.cpp +++ b/src/plugins/squish/squishtools.cpp @@ -521,6 +521,7 @@ void SquishTools::startSquishServer(Request request) { if (m_shutdownInitiated) return; + m_licenseIssues = false; QTC_ASSERT(m_perspective.perspectiveMode() != SquishPerspective::NoMode, return); m_request = request; if (m_serverProcess.state() != QProcess::NotRunning) { @@ -683,7 +684,9 @@ void SquishTools::onRunnerFinished() { qCDebug(LOG) << "Runner finished"; if (m_request == RunnerQueryRequested) { - emit queryFinished(m_fullRunnerOutput); + const QString error = m_licenseIssues ? Tr::tr("Could not get Squish license from server.") + : QString(); + emit queryFinished(m_fullRunnerOutput, error); setState(RunnerStopped); m_fullRunnerOutput.clear(); return; @@ -894,6 +897,9 @@ void SquishTools::onRunnerErrorOutput() "squishserver settings.\n" "(Tools > Squish > Server Settings...)") .arg(m_suiteConf.aut())); + } else if (trimmed.startsWith("Couldn't get license") + || trimmed.contains("UNLICENSED version of Squish")) { + m_licenseIssues = true; } } } diff --git a/src/plugins/squish/squishtools.h b/src/plugins/squish/squishtools.h index 505bd726f6f..72825514e44 100644 --- a/src/plugins/squish/squishtools.h +++ b/src/plugins/squish/squishtools.h @@ -77,7 +77,7 @@ signals: void squishTestRunStarted(); void squishTestRunFinished(); void resultOutputCreated(const QByteArray &output); - void queryFinished(const QString &output); + void queryFinished(const QString &output, const QString &error); void configChangesFailed(QProcess::ProcessError error); void configChangesWritten(); void localsUpdated(const QString &output); @@ -163,6 +163,7 @@ private: int m_autId = 0; bool m_shutdownInitiated = false; bool m_closeRunnerOnEndRecord = false; + bool m_licenseIssues = false; }; } // namespace Internal diff --git a/src/plugins/squish/squishwizardpages.cpp b/src/plugins/squish/squishwizardpages.cpp index 43559d1d7b5..b40a037cf45 100644 --- a/src/plugins/squish/squishwizardpages.cpp +++ b/src/plugins/squish/squishwizardpages.cpp @@ -127,7 +127,7 @@ void SquishToolkitsPage::fetchServerSettings() QTC_ASSERT(squishTools, return); connect(squishTools, &SquishTools::queryFinished, this, - [this] (const QString &out) { + [this] (const QString &out, const QString &error) { SquishServerSettings s; s.setFromXmlOutput(out); QApplication::restoreOverrideCursor(); @@ -143,6 +143,11 @@ void SquishToolkitsPage::fetchServerSettings() } } m_hiddenLineEdit->setText(s.mappedAuts.keys().join('\n')); + + if (!error.isEmpty()) { + m_errorLabel->setText(error); + m_errorLabel->setVisible(true); + } }); QApplication::setOverrideCursor(Qt::WaitCursor); squishTools->queryServerSettings(); From c6244ac8dfdabc29085ef8d66285db0300f6e9e1 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Mon, 10 Oct 2022 12:28:18 +0200 Subject: [PATCH 05/42] Meson: Fix .ts context names Change-Id: If69784dcacfdb5974adc9b457e360c9b4b584102 Reviewed-by: hjk --- share/qtcreator/translations/qtcreator_de.ts | 4 ++-- share/qtcreator/translations/qtcreator_ja.ts | 4 ++-- share/qtcreator/translations/qtcreator_ru.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index d5304ecd54e..7cdbf1fbbab 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -47917,7 +47917,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e
- Meson + MesonProjectManager Apply Configuration Changes Konfigurationsänderungen anwenden @@ -48417,7 +48417,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e - Meson + MesonProjectManager Configure Konfigurieren diff --git a/share/qtcreator/translations/qtcreator_ja.ts b/share/qtcreator/translations/qtcreator_ja.ts index 0333577d9a2..a91ab237a68 100644 --- a/share/qtcreator/translations/qtcreator_ja.ts +++ b/share/qtcreator/translations/qtcreator_ja.ts @@ -45835,7 +45835,7 @@ Output: - Meson + MesonProjectManager Apply Configuration Changes 設定の変更を適用 @@ -49743,7 +49743,7 @@ Stepping into the module or setting breakpoints by file and line is expected to - Meson + MesonProjectManager Configure 設定する diff --git a/share/qtcreator/translations/qtcreator_ru.ts b/share/qtcreator/translations/qtcreator_ru.ts index f96dfc30724..42b2c4089a3 100644 --- a/share/qtcreator/translations/qtcreator_ru.ts +++ b/share/qtcreator/translations/qtcreator_ru.ts @@ -26527,7 +26527,7 @@ Error: %5 - Meson + MesonProjectManager Form From ab9fd18af82d70cd0a00dbc6400bf1730b98b402 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 29 Sep 2022 15:07:40 +0200 Subject: [PATCH 06/42] QtSupport: Parallelize qt info fetching Change-Id: Idd3748f4a3a85b46db10ac0eb4f15567fcf4e896 Reviewed-by: hjk --- src/plugins/qtsupport/baseqtversion.cpp | 58 ++++++++++++++----------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index d550d4c9ccf..632e0935cd0 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include @@ -1271,25 +1272,24 @@ void QtVersionPrivate::updateVersionInfo() m_data.hostDataPath = fileProperty("QT_HOST_DATA"); m_data.hostPrefixPath = fileProperty("QT_HOST_PREFIX"); - // Now check for a qt that is configured with a prefix but not installed - if (!m_data.hostBinPath.isReadableDir()) - m_data.installed = false; + struct CheckDir + { + FilePath *path; + bool *isReadable; + }; - // Framework builds for Qt 4.8 don't use QT_INSTALL_HEADERS - // so we don't check on mac - if (!HostOsInfo::isMacHost()) { - if (!m_data.headerPath.isReadableDir()) - m_data.installed = false; - } + QList checkDirs = { + {&m_data.hostBinPath, &m_data.installed}, + {&m_data.docsPath, &m_data.hasDocumentation}, + {&m_data.examplesPath, &m_data.hasExamples}, + {&m_data.demosPath, &m_data.hasDemos}, + }; + if (m_data.binPath.osType() != OsTypeMac) + checkDirs.push_back({&m_data.headerPath, &m_data.installed}); - if (m_data.docsPath.isReadableDir()) - m_data.hasDocumentation = true; - - if (m_data.examplesPath.isReadableDir()) - m_data.hasExamples = true; - - if (m_data.demosPath.isReadableDir()) - m_data.hasDemos = true; + QtConcurrent::map(checkDirs, [](CheckDir &checkDir) { + *checkDir.isReadable = checkDir.path->isReadableDir(); + }).waitForFinished(); m_data.qtVersionString = qmakeProperty("QT_VERSION"); @@ -2227,17 +2227,23 @@ static Abi scanQtBinaryForBuildStringAndRefineAbi(const FilePath &library, Abis QtVersion::qtAbisFromLibrary(const FilePaths &coreLibraries) { - Abis res; - for (const FilePath &library : coreLibraries) { - for (const Abi &abi : Abi::abisOfBinary(library)) { - Abi tmp = abi; + auto filePathToAbiList = [](const FilePath &library) { // Fetch all abis from all libraries ... + Abis abis = Abi::abisOfBinary(library); + for (Abi &abi : abis) { if (abi.osFlavor() == Abi::UnknownFlavor) - tmp = scanQtBinaryForBuildStringAndRefineAbi(library, abi); - if (!res.contains(tmp)) - res.append(tmp); + abi = scanQtBinaryForBuildStringAndRefineAbi(library, abi); } - } - return res; + return abis; + }; + + auto uniqueAbis = [](Abis &result, const Abis &abis) { // ... merge the results into one list ... + for (const Abi &abi : abis) { + if (!result.contains(abi)) + result.append(abi); + } + }; + + return QtConcurrent::blockingMappedReduced(coreLibraries, filePathToAbiList, uniqueAbis); } void QtVersion::resetCache() const From a0f356aed6795b09091472eaaed9872b6abc5514 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 10 Oct 2022 11:08:46 +0200 Subject: [PATCH 07/42] qbs build: Do not build QmlDesigner & friends Too much maintenance effort for not enough gain. Change-Id: Ica385bcc93da0dbc7af8e15c07fdd33580de29a7 Reviewed-by: Christian Stenger --- .../assetexporterplugin.qbs | 66 - .../componentsplugin/componentsplugin.qbs | 70 - src/plugins/qmldesigner/qmldesigner.qbs | 12 +- src/plugins/qmldesigner/qmldesignerplugin.qbs | 1167 ----------------- .../qmlpreviewplugin/qmlpreviewplugin.qbs | 41 - .../qtquickplugin/qtquickplugin.qbs | 41 - src/plugins/studiowelcome/studiowelcome.qbs | 56 +- tests/unit/unit.qbs | 9 +- tests/unit/unittest/unittest.qbs | 149 --- 9 files changed, 8 insertions(+), 1603 deletions(-) delete mode 100644 src/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.qbs delete mode 100644 src/plugins/qmldesigner/componentsplugin/componentsplugin.qbs delete mode 100644 src/plugins/qmldesigner/qmldesignerplugin.qbs delete mode 100644 src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewplugin.qbs delete mode 100644 src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qbs delete mode 100644 tests/unit/unittest/unittest.qbs diff --git a/src/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.qbs b/src/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.qbs deleted file mode 100644 index a8bc03685f3..00000000000 --- a/src/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.qbs +++ /dev/null @@ -1,66 +0,0 @@ -import qbs - -QtcProduct { - name: "assetexporterplugin" - condition: QmlDesigner.present - type: ["dynamiclibrary"] - installDir: qtc.ide_plugin_path + '/' + installDirName - property string installDirName: qbs.targetOS.contains("macos") ? "QmlDesigner" : "qmldesigner" - - Depends { name: "Core" } - Depends { name: "ProjectExplorer" } - Depends { name: "QmlDesigner"; required: false } - Depends { name: "Utils" } - Depends { - name: "Qt" - submodules: [ - "quick-private" - ] - } - - cpp.includePaths: base.concat([ - "./", - "../designercore/include", - "../../../../share/qtcreator/qml/qmlpuppet/interfaces", - "../../../../share/qtcreator/qml/qmlpuppet/types" - ]) - - Properties { - condition: qbs.targetOS.contains("unix") - cpp.internalVersion: "" - } - - Group { - name: "plugin metadata" - files: ["assetexporterplugin.json"] - fileTags: ["qt_plugin_metadata"] - } - - files: [ - "assetexportdialog.cpp", - "assetexportdialog.h", - "assetexportdialog.ui", - "assetexporter.cpp", - "assetexporter.h", - "assetexporterplugin.cpp", - "assetexporterplugin.h", - "assetexporterplugin.qrc", - "assetexporterview.cpp", - "assetexporterview.h", - "assetexportpluginconstants.h", - "componentexporter.cpp", - "componentexporter.h", - "exportnotification.cpp", - "exportnotification.h", - "filepathmodel.cpp", - "filepathmodel.h", - "dumpers/assetnodedumper.cpp", - "dumpers/assetnodedumper.h", - "dumpers/itemnodedumper.cpp", - "dumpers/itemnodedumper.h", - "dumpers/nodedumper.cpp", - "dumpers/nodedumper.h", - "dumpers/textnodedumper.cpp", - "dumpers/textnodedumper.h" - ] -} diff --git a/src/plugins/qmldesigner/componentsplugin/componentsplugin.qbs b/src/plugins/qmldesigner/componentsplugin/componentsplugin.qbs deleted file mode 100644 index 194591a2732..00000000000 --- a/src/plugins/qmldesigner/componentsplugin/componentsplugin.qbs +++ /dev/null @@ -1,70 +0,0 @@ -import qbs - -QtcProduct { - name: "componentsplugin" - condition: QmlDesigner.present - type: ["dynamiclibrary"] - installDir: qtc.ide_plugin_path + '/' + installDirName - property string installDirName: qbs.targetOS.contains("macos") ? "QmlDesigner" : "qmldesigner" - - Depends { name: "Core" } - Depends { name: "QmlDesigner"; required: false } - Depends { name: "Utils" } - Depends { name: "Qt.qml" } - - cpp.defines: base.concat("COMPONENTS_LIBRARY") - cpp.includePaths: base.concat([ - "..", - "../components/componentcore", - "../components/debugview", - "../components/edit3d", - "../components/formeditor", - "../components/integration", - "../components/itemlibrary", - "../components/navigator", - "../components/propertyeditor", - "../components/stateseditor", - "../components/stateseditornew", - "../designercore", - "../designercore/include", - "../../../../share/qtcreator/qml/qmlpuppet/interfaces", - "../../../../share/qtcreator/qml/qmlpuppet/types", - ]) - Properties { - condition: qbs.targetOS.contains("unix") - cpp.internalVersion: "" - } - - Group { - name: "controls" - files: ["Controls/*.qml"] - } - - Group { - name: "images" - files: ["images/*.png"] - } - - Group { - name: "plugin metadata" - files: ["componentsplugin.json"] - fileTags: ["qt_plugin_metadata"] - } - - files: [ - "addtabdesigneraction.cpp", - "addtabdesigneraction.h", - "addtabtotabviewdialog.ui", - "addtabtotabviewdialog.cpp", - "addtabtotabviewdialog.h", - "components.metainfo", - "componentsplugin.cpp", - "componentsplugin.h", - "componentsplugin.qrc", - "entertabdesigneraction.cpp", - "entertabdesigneraction.h", - "tabviewindexmodel.cpp", - "tabviewindexmodel.h", - "../designercore/include/iwidgetplugin.h", - ] -} diff --git a/src/plugins/qmldesigner/qmldesigner.qbs b/src/plugins/qmldesigner/qmldesigner.qbs index c0dad85750e..98b6b9a4ee3 100644 --- a/src/plugins/qmldesigner/qmldesigner.qbs +++ b/src/plugins/qmldesigner/qmldesigner.qbs @@ -1,12 +1,6 @@ import qbs -Project { - name: "QML designer projects" - references: [ - "qmldesignerplugin.qbs", - "qtquickplugin/qtquickplugin.qbs", - "componentsplugin/componentsplugin.qbs", - "qmlpreviewplugin/qmlpreviewplugin.qbs", - "assetexporterplugin/assetexporterplugin.qbs" - ] +Product { + name: "QmlDesigner" + files: ["*", "**/*"] } diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs deleted file mode 100644 index 6ebaaa8ef3f..00000000000 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ /dev/null @@ -1,1167 +0,0 @@ -import qbs 1.0 -import qbs.FileInfo - -Project { - name: "QmlDesigner" - - QtcPlugin { - condition: Qt.quickwidgets.present && Qt.svg.present - fileName: FileInfo.fileName(filePath) - - Depends { - name: "Qt"; versionAtLeast: "6.2"; required: false - submodules: ["core-private", "quickwidgets", "xml", "svg"] - } - Depends { name: "AdvancedDockingSystem" } - Depends { name: "Core" } - Depends { name: "Nanotrace"; required: false } - Depends { name: "QmlJS" } - Depends { name: "QmlEditorWidgets" } - Depends { name: "TextEditor" } - Depends { name: "QmlJSEditor" } - Depends { name: "QmakeProjectManager" } - Depends { name: "QmlProjectManager" } - Depends { name: "ProjectExplorer" } - Depends { name: "LanguageUtils" } - Depends { name: "QtSupport" } - Depends { name: "app_version_header" } - Depends { name: "Sqlite" } - - cpp.defines: base.concat([ - "QMLDESIGNER_LIBRARY", - "TIMELINE_QML_PATH=\"" + FileInfo.joinPaths(path, "components", - "timelineeditor", "qml") + "\"" - ]) - cpp.enableExceptions: true - cpp.includePaths: base.concat([ - ".", - "designercore", - "designercore/include", - "designercore/instances", - "designercore/projectstorage", - "../../../share/qtcreator/qml/qmlpuppet/interfaces", - "../../../share/qtcreator/qml/qmlpuppet/container", - "../../../share/qtcreator/qml/qmlpuppet/commands", - "../../../share/qtcreator/qml/qmlpuppet/types", - "components", - "components/annotationeditor", - "components/assetslibrary", - "components/bindingeditor", - "components/componentcore", - "components/curveeditor", - "components/connectioneditor", - "components/debugview", - "components/integration", - "components/propertyeditor", - "components/edit3d", - "components/eventlist", - "components/formeditor", - "components/itemlibrary", - "components/navigator", - "components/pluginmanager", - "components/stateseditor", - "components/stateseditornew", - "components/texteditor", - "components/timelineeditor", - "components/listmodeleditor", - "components/materialbrowser", - "components/materialeditor", - ]) - - Properties { - condition: qbs.targetOS.contains("unix") && !qbs.targetOS.contains("bsd") - cpp.dynamicLibraries: base.concat("rt") - } - - Export { - Depends { name: "QmlJS" } - cpp.includePaths: base.concat([ - exportingProduct.sourceDirectory, - exportingProduct.sourceDirectory + "/components/componentcore", - exportingProduct.sourceDirectory + "/components/edit3d", - exportingProduct.sourceDirectory + "/components/formeditor", - exportingProduct.sourceDirectory + "/components/integration", - exportingProduct.sourceDirectory + "/designercore", - exportingProduct.sourceDirectory + "/designercore/include", - qtc.export_data_base + "/qml/qmlpuppet/interfaces", - ]) - } - - Group { - prefix: "designercore/filemanager/" - files: [ - "addarraymembervisitor.cpp", - "addarraymembervisitor.h", - "addobjectvisitor.cpp", - "addobjectvisitor.h", - "addpropertyvisitor.cpp", - "addpropertyvisitor.h", - "astobjecttextextractor.cpp", - "astobjecttextextractor.h", - "changeimportsvisitor.cpp", - "changeimportsvisitor.h", - "changeobjecttypevisitor.cpp", - "changeobjecttypevisitor.h", - "changepropertyvisitor.cpp", - "changepropertyvisitor.h", - "firstdefinitionfinder.cpp", - "firstdefinitionfinder.h", - "moveobjectbeforeobjectvisitor.cpp", - "moveobjectbeforeobjectvisitor.h", - "moveobjectvisitor.cpp", - "moveobjectvisitor.h", - "objectlengthcalculator.cpp", - "objectlengthcalculator.h", - "qmlrefactoring.cpp", - "qmlrefactoring.h", - "qmlrewriter.cpp", - "qmlrewriter.h", - "removepropertyvisitor.cpp", - "removepropertyvisitor.h", - "removeuiobjectmembervisitor.cpp", - "removeuiobjectmembervisitor.h", - ] - } - - Group { - prefix: "../../../share/qtcreator/qml/qmlpuppet/" - files: [ - "commands/changeauxiliarycommand.cpp", - "commands/changeauxiliarycommand.h", - "commands/changebindingscommand.cpp", - "commands/changebindingscommand.h", - "commands/changefileurlcommand.cpp", - "commands/changefileurlcommand.h", - "commands/changeidscommand.cpp", - "commands/changeidscommand.h", - "commands/changenodesourcecommand.cpp", - "commands/changenodesourcecommand.h", - "commands/changestatecommand.cpp", - "commands/changestatecommand.h", - "commands/changevaluescommand.cpp", - "commands/changevaluescommand.h", - "commands/captureddatacommand.h", - "commands/scenecreatedcommand.h", - "commands/childrenchangedcommand.cpp", - "commands/childrenchangedcommand.h", - "commands/clearscenecommand.cpp", - "commands/clearscenecommand.h", - "commands/completecomponentcommand.cpp", - "commands/completecomponentcommand.h", - "commands/componentcompletedcommand.cpp", - "commands/componentcompletedcommand.h", - "commands/createinstancescommand.cpp", - "commands/createinstancescommand.h", - "commands/createscenecommand.cpp", - "commands/createscenecommand.h", - "commands/debugoutputcommand.cpp", - "commands/debugoutputcommand.h", - "commands/endpuppetcommand.cpp", - "commands/endpuppetcommand.h", - "commands/informationchangedcommand.cpp", - "commands/informationchangedcommand.h", - "commands/nanotracecommand.cpp", - "commands/nanotracecommand.h", - "commands/pixmapchangedcommand.cpp", - "commands/pixmapchangedcommand.h", - "commands/puppetalivecommand.cpp", - "commands/puppetalivecommand.h", - "commands/removeinstancescommand.cpp", - "commands/removeinstancescommand.h", - "commands/removepropertiescommand.cpp", - "commands/removepropertiescommand.h", - "commands/removesharedmemorycommand.cpp", - "commands/removesharedmemorycommand.h", - "commands/reparentinstancescommand.cpp", - "commands/reparentinstancescommand.h", - "commands/statepreviewimagechangedcommand.cpp", - "commands/statepreviewimagechangedcommand.h", - "commands/synchronizecommand.h", - "commands/changepreviewimagesizecommand.cpp", - "commands/changepreviewimagesizecommand.h", - "commands/changelanguagecommand.cpp", - "commands/changelanguagecommand.h", - "commands/tokencommand.cpp", - "commands/tokencommand.h", - "commands/valueschangedcommand.cpp", - "commands/valueschangedcommand.h", - "commands/changeselectioncommand.cpp", - "commands/changeselectioncommand.h", - "commands/update3dviewstatecommand.cpp", - "commands/update3dviewstatecommand.h", - "commands/puppettocreatorcommand.cpp", - "commands/puppettocreatorcommand.h", - "commands/inputeventcommand.cpp", - "commands/inputeventcommand.h", - "commands/view3dactioncommand.cpp", - "commands/view3dactioncommand.h", - "commands/requestmodelnodepreviewimagecommand.cpp", - "commands/requestmodelnodepreviewimagecommand.h", - "container/addimportcontainer.cpp", - "container/addimportcontainer.h", - "container/idcontainer.cpp", - "container/idcontainer.h", - "container/imagecontainer.cpp", - "container/imagecontainer.h", - "container/informationcontainer.cpp", - "container/informationcontainer.h", - "container/instancecontainer.cpp", - "container/instancecontainer.h", - "container/mockuptypecontainer.cpp", - "container/mockuptypecontainer.h", - "container/propertyabstractcontainer.cpp", - "container/propertyabstractcontainer.h", - "container/propertybindingcontainer.cpp", - "container/propertybindingcontainer.h", - "container/propertyvaluecontainer.cpp", - "container/propertyvaluecontainer.h", - "container/reparentcontainer.cpp", - "container/reparentcontainer.h", - "container/sharedmemory.h", - "interfaces/commondefines.h", - "interfaces/nodeinstanceclientinterface.h", - "interfaces/nodeinstanceserverinterface.cpp", - "interfaces/nodeinstanceserverinterface.h", - "types/enumeration.h", - ] - } - - Group { - name: "SharedMemory (Unix)" - condition: qbs.targetOS.contains("unix") - files: [ - "../../../share/qtcreator/qml/qmlpuppet/container/sharedmemory_unix.cpp", - ] - } - - Group { - name: "SharedMemory (Generic)" - condition: !qbs.targetOS.contains("unix") - files: [ - "../../../share/qtcreator/qml/qmlpuppet/container/sharedmemory_qt.cpp", - ] - } - - Group { - prefix: "designercore/" - files: [ - "rewritertransaction.cpp", - "rewritertransaction.h", - "exceptions/exception.cpp", - "exceptions/invalidargumentexception.cpp", - "exceptions/invalididexception.cpp", - "exceptions/invalidmetainfoexception.cpp", - "exceptions/invalidmodelnodeexception.cpp", - "exceptions/invalidmodelstateexception.cpp", - "exceptions/invalidpropertyexception.cpp", - "exceptions/invalidqmlsourceexception.cpp", - "exceptions/invalidreparentingexception.cpp", - "exceptions/invalidslideindexexception.cpp", - "exceptions/notimplementedexception.cpp", - "exceptions/removebasestateexception.cpp", - "exceptions/rewritingexception.cpp", - "include/abstractproperty.h", - "include/abstractview.h", - "include/anchorline.h", - "include/annotation.h", - "include/basetexteditmodifier.h", - "include/bindingproperty.h", - "include/componenttextmodifier.h", - "include/customnotifications.h", - "include/enumerationmetainfo.h", - "include/exception.h", - "include/forwardview.h", - "include/import.h", - "include/invalidargumentexception.h", - "include/invalididexception.h", - "include/invalidmetainfoexception.h", - "include/invalidmodelnodeexception.h", - "include/invalidmodelstateexception.h", - "include/invalidpropertyexception.h", - "include/invalidqmlsourceexception.h", - "include/invalidreparentingexception.h", - "include/invalidslideindexexception.h", - "include/itemlibraryinfo.h", - "include/mathutils.h", - "include/metainfo.h", - "include/metainforeader.h", - "include/model.h", - "include/modelmerger.h", - "include/modelnode.h", - "include/modelnodepositionstorage.h", - "include/nodeabstractproperty.h", - "include/nodeinstance.h", - "include/nodeinstanceview.h", - "include/nodelistproperty.h", - "include/nodemetainfo.h", - "include/nodehints.h", - "include/nodeproperty.h", - "include/notimplementedexception.h", - "include/plaintexteditmodifier.h", - "include/propertycontainer.h", - "include/propertymetainfo.h", - "include/propertynode.h", - "include/propertyparser.h", - "include/qmlanchors.h", - "include/qmlchangeset.h", - "include/qmlitemnode.h", - "include/qmlvisualnode.h", - "include/qml3dnode.h", - "include/qmlmodelnodefacade.h", - "include/qmlobjectnode.h", - "include/qmlstate.h", - "include/qmlconnections.h", - "include/removebasestateexception.h", - "include/documentmessage.h", - "include/rewriterview.h", - "include/rewritingexception.h", - "include/signalhandlerproperty.h", - "include/stylesheetmerger.h", - "include/subcomponentmanager.h", - "include/textmodifier.h", - "include/variantproperty.h", - "include/qmltimelinekeyframegroup.h", - "include/qmltimeline.h", - "instances/nodeinstance.cpp", - "instances/nodeinstanceserverproxy.cpp", - "instances/nodeinstanceserverproxy.h", - "instances/nodeinstanceview.cpp", - "instances/puppetbuildprogressdialog.cpp", - "instances/puppetbuildprogressdialog.h", - "instances/puppetbuildprogressdialog.ui", - "instances/puppetcreator.cpp", - "instances/puppetcreator.h", - "instances/puppetdialog.cpp", - "instances/puppetdialog.h", - "instances/puppetdialog.ui", - "instances/connectionmanagerinterface.cpp", - "instances/connectionmanagerinterface.h", - "instances/baseconnectionmanager.cpp", - "instances/baseconnectionmanager.h", - "instances/connectionmanager.cpp", - "instances/connectionmanager.h", - "instances/capturingconnectionmanager.cpp", - "instances/capturingconnectionmanager.h", - "instances/interactiveconnectionmanager.cpp", - "instances/interactiveconnectionmanager.h", - "instances/qprocessuniqueptr.h", - "metainfo/itemlibraryinfo.cpp", - "metainfo/metainfo.cpp", - "metainfo/metainforeader.cpp", - "metainfo/nodemetainfo.cpp", - "metainfo/nodehints.cpp", - "metainfo/subcomponentmanager.cpp", - "model/abstractproperty.cpp", - "model/abstractview.cpp", - "model/anchorline.cpp", - "model/annotation.cpp", - "model/basetexteditmodifier.cpp", - "model/bindingproperty.cpp", - "model/componenttextmodifier.cpp", - "model/import.cpp", - "model/internalbindingproperty.cpp", - "model/internalbindingproperty.h", - "model/internalnode.cpp", - "model/internalnode_p.h", - "model/internalnodeabstractproperty.cpp", - "model/internalnodeabstractproperty.h", - "model/internalnodelistproperty.cpp", - "model/internalnodelistproperty.h", - "model/internalnodeproperty.cpp", - "model/internalnodeproperty.h", - "model/internalproperty.cpp", - "model/internalproperty.h", - "model/internalsignalhandlerproperty.cpp", - "model/internalsignalhandlerproperty.h", - "model/internalvariantproperty.cpp", - "model/internalvariantproperty.h", - "model/model.cpp", - "model/model_p.h", - "model/modelmerger.cpp", - "model/modelnode.cpp", - "model/modelnodepositionrecalculator.cpp", - "model/modelnodepositionrecalculator.h", - "model/modelnodepositionstorage.cpp", - "model/modeltotextmerger.cpp", - "model/modeltotextmerger.h", - "model/nodeabstractproperty.cpp", - "model/nodelistproperty.cpp", - "model/nodeproperty.cpp", - "model/plaintexteditmodifier.cpp", - "model/propertycontainer.cpp", - "model/propertynode.cpp", - "model/propertyparser.cpp", - "model/qmlanchors.cpp", - "model/qmlchangeset.cpp", - "model/qmlitemnode.cpp", - "model/qmlvisualnode.cpp", - "model/qml3dnode.cpp", - "model/qmlmodelnodefacade.cpp", - "model/qmlobjectnode.cpp", - "model/qmlstate.cpp", - "model/qmlconnections.cpp", - "model/qmltextgenerator.cpp", - "model/qmltextgenerator.h", - "model/rewriteaction.cpp", - "model/rewriteaction.h", - "model/rewriteactioncompressor.cpp", - "model/rewriteactioncompressor.h", - "model/documentmessage.cpp", - "model/rewriterview.cpp", - "model/signalhandlerproperty.cpp", - "model/stylesheetmerger.cpp", - "model/textmodifier.cpp", - "model/texttomodelmerger.cpp", - "model/texttomodelmerger.h", - "model/variantproperty.cpp", - "model/qmltimelinekeyframegroup.cpp", - "model/qmltimeline.cpp", - "pluginmanager/widgetpluginmanager.cpp", - "pluginmanager/widgetpluginmanager.h", - "pluginmanager/widgetpluginpath.cpp", - "pluginmanager/widgetpluginpath.h", - "include/asynchronousexplicitimagecache.h", - "include/asynchronousimagecache.h", - "include/synchronousimagecache.h", - "include/imagecacheauxiliarydata.h", - "include/asynchronousimagecacheinterface.h", - "imagecache/explicitimagecacheimageprovider.cpp", - "imagecache/explicitimagecacheimageprovider.h", - "imagecache/imagecachecollector.cpp", - "imagecache/imagecachecollector.h", - "imagecache/imagecachefontcollector.cpp", - "imagecache/imagecachefontcollector.h", - "imagecache/asynchronousexplicitimagecache.cpp", - "imagecache/asynchronousimagecache.cpp", - "imagecache/asynchronousimagefactory.cpp", - "imagecache/asynchronousimagefactory.h", - "imagecache/imagecachecollectorinterface.h", - "imagecache/imagecacheconnectionmanager.cpp", - "imagecache/imagecacheconnectionmanager.h", - "imagecache/imagecachedispatchcollector.h", - "imagecache/imagecachegeneratorinterface.h", - "imagecache/imagecachegenerator.cpp", - "imagecache/imagecachegenerator.h", - "imagecache/imagecachestorageinterface.h", - "imagecache/imagecachestorage.h", - "imagecache/meshimagecachecollector.cpp", - "imagecache/meshimagecachecollector.h", - "imagecache/smallimagecacheprovider.cpp", - "imagecache/smallimagecacheprovider.h", - "imagecache/synchronousimagecache.cpp", - "imagecache/timestampproviderinterface.h", - "imagecache/timestampprovider.h", - "imagecache/timestampprovider.cpp", - ] - } - - Group { - prefix: "designercore/projectstorage/" - files: [ - "directorypathcompressor.h", - "filestatus.h", - "filestatuscache.cpp", - "filestatuscache.h", - "filesystem.cpp", - "filesystem.h", - "filesysteminterface.h", - "nonlockingmutex.h", - "projectstorage.cpp", - "projectstorage.h", - "projectstoragefwd.h", - "projectstorageinfotypes.h", - "projectstorageinterface.h", - "projectstoragepathwatcher.h", - "projectstoragepathwatcherinterface.h", - "projectstoragepathwatchernotifierinterface.h", - "projectstoragepathwatchertypes.h", - "projectstorageprinting.h", - "projectstoragetypes.h", - "projectstorageupdater.cpp", - "projectstorageupdater.h", - "qmldocumentparser.cpp", - "qmldocumentparser.h", - "qmldocumentparserinterface.h", - "qmltypesparser.cpp", - "qmltypesparser.h", - "qmltypesparserinterface.h", - "sourcepath.h", - "sourcepathcache.h", - "sourcepathcachetypes.h", - "sourcepathview.h", - "storagecache.h", - "storagecacheentry.h", - "storagecachefwd.h", - ] - } - - Group { - prefix: "components/" - files: [ - "assetslibrary/assetslibrary.qrc", - "assetslibrary/assetslibraryview.cpp", - "assetslibrary/assetslibraryview.h", - "assetslibrary/assetslibrarywidget.cpp", - "assetslibrary/assetslibrarywidget.h", - "assetslibrary/assetslibrarymodel.cpp", - "assetslibrary/assetslibrarymodel.h", - "assetslibrary/assetslibraryiconprovider.cpp", - "assetslibrary/assetslibraryiconprovider.h", - "assetslibrary/assetslibrarydir.cpp", - "assetslibrary/assetslibrarydir.h", - "assetslibrary/assetslibrarydirsmodel.cpp", - "assetslibrary/assetslibrarydirsmodel.h", - "assetslibrary/assetslibraryfilesmodel.cpp", - "assetslibrary/assetslibraryfilesmodel.h", - "componentcore/addimagesdialog.cpp", - "componentcore/addimagesdialog.h", - "componentcore/abstractaction.cpp", - "componentcore/abstractaction.h", - "componentcore/abstractactiongroup.cpp", - "componentcore/abstractactiongroup.h", - "componentcore/actioninterface.h", - "componentcore/addsignalhandlerdialog.cpp", - "componentcore/addsignalhandlerdialog.h", - "componentcore/addsignalhandlerdialog.ui", - "componentcore/componentcore_constants.h", - "componentcore/crumblebar.cpp", - "componentcore/crumblebar.h", - "componentcore/designeractionmanager.cpp", - "componentcore/designeractionmanager.h", - "componentcore/designeractionmanagerview.cpp", - "componentcore/designeractionmanagerview.h", - "componentcore/findimplementation.cpp", - "componentcore/findimplementation.h", - "componentcore/formatoperation.cpp", - "componentcore/formatoperation.h", - "componentcore/layoutingridlayout.cpp", - "componentcore/layoutingridlayout.h", - "componentcore/theme.cpp", - "componentcore/theme.h", - "componentcore/modelnodecontextmenu.cpp", - "componentcore/modelnodecontextmenu.h", - "componentcore/modelnodecontextmenu_helper.cpp", - "componentcore/modelnodecontextmenu_helper.h", - "componentcore/modelnodeoperations.cpp", - "componentcore/modelnodeoperations.h", - "componentcore/navigation2d.cpp", - "componentcore/navigation2d.h", - "componentcore/selectioncontext.cpp", - "componentcore/selectioncontext.h", - "componentcore/qmldesignericonprovider.cpp", - "componentcore/qmldesignericonprovider.h", - "componentcore/componentcore.qrc", - "componentcore/zoomaction.cpp", - "componentcore/zoomaction.h", - "componentcore/hdrimage.cpp", - "componentcore/hdrimage.h", - "componentcore/svgpasteaction.cpp", - "componentcore/svgpasteaction.h", - "componentcore/viewmanager.cpp", - "componentcore/viewmanager.h", - "texteditor/texteditorstatusbar.cpp", - "texteditor/texteditorstatusbar.h", - "componentcore/changestyleaction.cpp", - "componentcore/changestyleaction.h", - "texteditor/texteditorview.cpp", - "texteditor/texteditorview.h", - "texteditor/texteditorwidget.cpp", - "texteditor/texteditorwidget.h", - "debugview/debugview.cpp", - "debugview/debugview.h", - "debugview/debugviewwidget.cpp", - "debugview/debugviewwidget.h", - "debugview/debugviewwidget.ui", - "edit3d/edit3dview.cpp", - "edit3d/edit3dview.h", - "edit3d/edit3dviewconfig.h", - "edit3d/backgroundcolorselection.cpp", - "edit3d/backgroundcolorselection.h", - "edit3d/edit3dwidget.cpp", - "edit3d/edit3dwidget.h", - "edit3d/edit3dcanvas.cpp", - "edit3d/edit3dcanvas.h", - "edit3d/edit3dactions.cpp", - "edit3d/edit3dactions.h", - "edit3d/edit3dvisibilitytogglesmenu.cpp", - "edit3d/edit3dvisibilitytogglesmenu.h", - "edit3d/edit3d.qrc", - "formeditor/abstractcustomtool.cpp", - "formeditor/abstractcustomtool.h", - "formeditor/abstractformeditortool.cpp", - "formeditor/abstractformeditortool.h", - "formeditor/anchorindicator.cpp", - "formeditor/anchorindicator.h", - "formeditor/anchorindicatorgraphicsitem.cpp", - "formeditor/anchorindicatorgraphicsitem.h", - "formeditor/backgroundaction.cpp", - "formeditor/backgroundaction.h", - "formeditor/bindingindicator.cpp", - "formeditor/bindingindicator.h", - "formeditor/bindingindicatorgraphicsitem.cpp", - "formeditor/bindingindicatorgraphicsitem.h", - "formeditor/contentnoteditableindicator.cpp", - "formeditor/contentnoteditableindicator.h", - "formeditor/controlelement.cpp", - "formeditor/controlelement.h", - "formeditor/dragtool.cpp", - "formeditor/dragtool.h", - "formeditor/formeditor.qrc", - "formeditor/formeditorannotationicon.cpp", - "formeditor/formeditorannotationicon.h", - "formeditor/formeditorgraphicsview.cpp", - "formeditor/formeditorgraphicsview.h", - "formeditor/formeditoritem.cpp", - "formeditor/formeditoritem.h", - "formeditor/formeditorscene.cpp", - "formeditor/formeditorscene.h", - "formeditor/formeditorview.cpp", - "formeditor/formeditorview.h", - "formeditor/formeditorwidget.cpp", - "formeditor/formeditorwidget.h", - "formeditor/itemutilfunctions.cpp", - "formeditor/itemutilfunctions.h", - "formeditor/layeritem.cpp", - "formeditor/layeritem.h", - "formeditor/lineeditaction.cpp", - "formeditor/lineeditaction.h", - "formeditor/movemanipulator.cpp", - "formeditor/movemanipulator.h", - "formeditor/movetool.cpp", - "formeditor/movetool.h", - "formeditor/onedimensionalcluster.cpp", - "formeditor/onedimensionalcluster.h", - "formeditor/resizecontroller.cpp", - "formeditor/resizecontroller.h", - "formeditor/resizehandleitem.cpp", - "formeditor/resizehandleitem.h", - "formeditor/resizeindicator.cpp", - "formeditor/resizeindicator.h", - "formeditor/resizemanipulator.cpp", - "formeditor/resizemanipulator.h", - "formeditor/resizetool.cpp", - "formeditor/resizetool.h", - "formeditor/rotationtool.cpp", - "formeditor/rotationtool.h", - "formeditor/rotationindicator.cpp", - "formeditor/rotationindicator.h", - "formeditor/rotationcontroller.cpp", - "formeditor/rotationcontroller.h", - "formeditor/rotationhandleitem.cpp", - "formeditor/rotationhandleitem.h", - "formeditor/rotationmanipulator.cpp", - "formeditor/rotationmanipulator.h", - "formeditor/rubberbandselectionmanipulator.cpp", - "formeditor/rubberbandselectionmanipulator.h", - "formeditor/scaleitem.cpp", - "formeditor/scaleitem.h", - "formeditor/scalemanipulator.cpp", - "formeditor/scalemanipulator.h", - "formeditor/seekerslider.cpp", - "formeditor/seekerslider.h", - "formeditor/selectionindicator.cpp", - "formeditor/selectionindicator.h", - "formeditor/selectionrectangle.cpp", - "formeditor/selectionrectangle.h", - "formeditor/selectiontool.cpp", - "formeditor/selectiontool.h", - "formeditor/singleselectionmanipulator.cpp", - "formeditor/singleselectionmanipulator.h", - "formeditor/snapper.cpp", - "formeditor/snapper.h", - "formeditor/snappinglinecreator.cpp", - "formeditor/snappinglinecreator.h", - "formeditor/toolbox.cpp", - "formeditor/toolbox.h", - "formeditor/formeditortoolbutton.cpp", - "formeditor/formeditortoolbutton.h", - "formeditor/transitiontool.cpp", - "formeditor/transitiontool.h", - "integration/componentaction.cpp", - "integration/componentaction.h", - "integration/componentview.cpp", - "integration/componentview.h", - "integration/designdocument.cpp", - "integration/designdocument.h", - "integration/designdocumentview.cpp", - "integration/designdocumentview.h", - "integration/stackedutilitypanelcontroller.cpp", - "integration/stackedutilitypanelcontroller.h", - "integration/utilitypanelcontroller.cpp", - "integration/utilitypanelcontroller.h", - "itemlibrary/assetimportupdatedialog.cpp", - "itemlibrary/assetimportupdatedialog.h", - "itemlibrary/assetimportupdatedialog.ui", - "itemlibrary/assetimportupdatetreeitem.cpp", - "itemlibrary/assetimportupdatetreeitem.h", - "itemlibrary/assetimportupdatetreeitemdelegate.cpp", - "itemlibrary/assetimportupdatetreeitemdelegate.h", - "itemlibrary/assetimportupdatetreemodel.cpp", - "itemlibrary/assetimportupdatetreemodel.h", - "itemlibrary/assetimportupdatetreeview.cpp", - "itemlibrary/assetimportupdatetreeview.h", - "itemlibrary/itemlibrary.qrc", - "itemlibrary/itemlibraryaddimportmodel.cpp", - "itemlibrary/itemlibraryaddimportmodel.h", - "itemlibrary/itemlibraryassetimportdialog.cpp", - "itemlibrary/itemlibraryassetimportdialog.h", - "itemlibrary/itemlibraryassetimportdialog.ui", - "itemlibrary/itemlibraryassetimporter.cpp", - "itemlibrary/itemlibraryassetimporter.h", - "itemlibrary/itemlibrarycategoriesmodel.cpp", - "itemlibrary/itemlibrarycategoriesmodel.h", - "itemlibrary/itemlibrarycategory.cpp", - "itemlibrary/itemlibrarycategory.h", - "itemlibrary/itemlibraryimageprovider.cpp", - "itemlibrary/itemlibraryimageprovider.h", - "itemlibrary/itemlibraryimport.cpp", - "itemlibrary/itemlibraryimport.h", - "itemlibrary/itemlibraryitem.cpp", - "itemlibrary/itemlibraryitem.h", - "itemlibrary/itemlibraryitemsmodel.cpp", - "itemlibrary/itemlibraryitemsmodel.h", - "itemlibrary/itemlibrarymodel.cpp", - "itemlibrary/itemlibrarymodel.h", - "itemlibrary/itemlibraryview.cpp", - "itemlibrary/itemlibraryview.h", - "itemlibrary/itemlibrarywidget.cpp", - "itemlibrary/itemlibrarywidget.h", - "itemlibrary/itemlibraryiconimageprovider.cpp", - "itemlibrary/itemlibraryiconimageprovider.h", - "materialbrowser/materialbrowsermodel.cpp", - "materialbrowser/materialbrowsermodel.h", - "materialbrowser/materialbrowserbundlemodel.cpp", - "materialbrowser/materialbrowserbundlemodel.h", - "materialbrowser/bundlematerial.cpp", - "materialbrowser/bundlematerial.h", - "materialbrowser/bundlematerialcategory.cpp", - "materialbrowser/bundlematerialcategory.h", - "materialbrowser/materialbrowserview.cpp", - "materialbrowser/materialbrowserview.h", - "materialbrowser/materialbrowserwidget.cpp", - "materialbrowser/materialbrowserwidget.h", - "materialbrowser/bundleimporter.cpp", - "materialbrowser/bundleimporter.h", - "materialeditor/materialeditorcontextobject.cpp", - "materialeditor/materialeditorcontextobject.h", - "materialeditor/materialeditordynamicpropertiesproxymodel.cpp", - "materialeditor/materialeditordynamicpropertiesproxymodel.h", - "materialeditor/materialeditorqmlbackend.cpp", - "materialeditor/materialeditorqmlbackend.h", - "materialeditor/materialeditortransaction.cpp", - "materialeditor/materialeditortransaction.h", - "materialeditor/materialeditorview.cpp", - "materialeditor/materialeditorview.h", - "materialeditor/materialeditor.qrc", - "navigator/iconcheckboxitemdelegate.cpp", - "navigator/iconcheckboxitemdelegate.h", - "navigator/nameitemdelegate.cpp", - "navigator/nameitemdelegate.h", - "navigator/navigator.qrc", - "navigator/navigatorsearchwidget.cpp", - "navigator/navigatorsearchwidget.h", - "navigator/navigatortreemodel.cpp", - "navigator/navigatortreemodel.h", - "navigator/navigatortreeview.cpp", - "navigator/navigatortreeview.h", - "navigator/navigatorview.cpp", - "navigator/navigatorview.h", - "navigator/navigatorwidget.cpp", - "navigator/navigatorwidget.h", - "navigator/choosefrompropertylistdialog.cpp", - "navigator/choosefrompropertylistdialog.h", - "navigator/choosefrompropertylistdialog.ui", - "navigator/previewtooltip.cpp", - "navigator/previewtooltip.h", - "navigator/previewtooltip.ui", - "propertyeditor/aligndistribute.cpp", - "propertyeditor/aligndistribute.h", - "propertyeditor/colorpalettebackend.cpp", - "propertyeditor/colorpalettebackend.h", - "propertyeditor/designerpropertymap.cpp", - "propertyeditor/designerpropertymap.h", - "propertyeditor/dynamicpropertiesproxymodel.cpp", - "propertyeditor/dynamicpropertiesproxymodel.h", - "propertyeditor/fileresourcesmodel.cpp", - "propertyeditor/fileresourcesmodel.h", - "propertyeditor/itemfiltermodel.cpp", - "propertyeditor/itemfiltermodel.h", - "propertyeditor/gradientmodel.cpp", - "propertyeditor/gradientmodel.h", - "propertyeditor/gradientpresetcustomlistmodel.cpp", - "propertyeditor/gradientpresetcustomlistmodel.h", - "propertyeditor/gradientpresetdefaultlistmodel.cpp", - "propertyeditor/gradientpresetdefaultlistmodel.h", - "propertyeditor/gradientpresetitem.cpp", - "propertyeditor/gradientpresetitem.h", - "propertyeditor/gradientpresetlistmodel.cpp", - "propertyeditor/gradientpresetlistmodel.h", - "propertyeditor/propertyeditorcontextobject.cpp", - "propertyeditor/propertyeditorcontextobject.h", - "propertyeditor/propertyeditorimageprovider.cpp", - "propertyeditor/propertyeditorimageprovider.h", - "propertyeditor/propertyeditortransaction.cpp", - "propertyeditor/propertyeditortransaction.h", - "propertyeditor/propertyeditorvalue.cpp", - "propertyeditor/propertyeditorvalue.h", - "propertyeditor/propertyeditorview.cpp", - "propertyeditor/propertyeditorview.h", - "propertyeditor/propertyeditorwidget.cpp", - "propertyeditor/propertyeditorwidget.h", - "propertyeditor/propertyeditorqmlbackend.cpp", - "propertyeditor/propertyeditorqmlbackend.h", - "propertyeditor/quick2propertyeditorview.cpp", - "propertyeditor/quick2propertyeditorview.h", - "propertyeditor/qmlanchorbindingproxy.cpp", - "propertyeditor/qmlanchorbindingproxy.h", - "propertyeditor/qmlmodelnodeproxy.cpp", - "propertyeditor/qmlmodelnodeproxy.h", - "propertyeditor/tooltip.cpp", - "propertyeditor/tooltip.h", - "resources/resources_qmldesigner_components.qrc", - "stateseditor/stateseditorimageprovider.cpp", - "stateseditor/stateseditorimageprovider.h", - "stateseditor/stateseditormodel.cpp", - "stateseditor/stateseditormodel.h", - "stateseditor/stateseditorview.cpp", - "stateseditor/stateseditorview.h", - "stateseditor/stateseditorwidget.cpp", - "stateseditor/stateseditorwidget.h", - ] - } - - Group { - name: "new states editor" - prefix: "components/stateseditornew/" - Qt.core.generatedHeadersDir: product.buildDirectory + "/qt.headers/stateseditornew" - files: [ - "propertychangesmodel.cpp", - "propertychangesmodel.h", - "propertymodel.cpp", - "propertymodel.h", - "stateseditorimageprovider.cpp", - "stateseditorimageprovider.h", - "stateseditormodel.cpp", - "stateseditormodel.h", - "stateseditorview.cpp", - "stateseditorview.h", - "stateseditorwidget.cpp", - "stateseditorwidget.h", - ] - } - - Group { - name: "extension" - prefix: "components/" - files: [ - "annotationeditor/annotationcommenttab.cpp", - "annotationeditor/annotationcommenttab.h", - "annotationeditor/annotationcommenttab.ui", - "annotationeditor/annotationeditor.cpp", - "annotationeditor/annotationeditor.h", - "annotationeditor/annotationeditor.qrc", - "annotationeditor/annotationlist.cpp", - "annotationeditor/annotationlist.h", - "annotationeditor/annotationlistwidget.cpp", - "annotationeditor/annotationlistwidget.h", - "annotationeditor/globalannotationeditor.cpp", - "annotationeditor/globalannotationeditor.h", - "annotationeditor/globalannotationdialog.cpp", - "annotationeditor/globalannotationdialog.h", - "annotationeditor/annotationeditordialog.cpp", - "annotationeditor/annotationeditordialog.h", - "annotationeditor/annotationeditorwidget.cpp", - "annotationeditor/annotationeditorwidget.h", - "annotationeditor/annotationeditorwidget.ui", - "annotationeditor/defaultannotations.cpp", - "annotationeditor/defaultannotations.h", - "annotationeditor/annotationtableview.cpp", - "annotationeditor/annotationtableview.h", - "annotationeditor/annotationtabwidget.cpp", - "annotationeditor/annotationtabwidget.h", - "bindingeditor/bindingeditor.cpp", - "bindingeditor/bindingeditor.h", - "bindingeditor/actioneditor.cpp", - "bindingeditor/actioneditor.h", - "bindingeditor/abstracteditordialog.cpp", - "bindingeditor/abstracteditordialog.h", - "bindingeditor/actioneditordialog.cpp", - "bindingeditor/actioneditordialog.h", - "bindingeditor/bindingeditordialog.cpp", - "bindingeditor/bindingeditordialog.h", - "bindingeditor/bindingeditorwidget.cpp", - "bindingeditor/bindingeditorwidget.h", - "bindingeditor/connectionvisitor.cpp", - "bindingeditor/connectionvisitor.h", - "bindingeditor/signallist.cpp", - "bindingeditor/signallist.h", - "bindingeditor/signallistdialog.cpp", - "bindingeditor/signallistdialog.h", - "bindingeditor/signallistdelegate.cpp", - "bindingeditor/signallistdelegate.h", - "colortool/colortool.cpp", - "colortool/colortool.h", - "connectioneditor/addnewbackenddialog.h", - "connectioneditor/addnewbackenddialog.cpp", - "connectioneditor/addnewbackenddialog.ui", - "connectioneditor/backendmodel.h", - "connectioneditor/backendmodel.cpp", - "connectioneditor/delegates.h", - "connectioneditor/delegates.cpp", - "connectioneditor/bindingmodel.cpp", - "connectioneditor/bindingmodel.h", - "connectioneditor/connectioneditor.qrc", - "connectioneditor/connectionmodel.cpp", - "connectioneditor/connectionmodel.h", - "connectioneditor/connectionview.cpp", - "connectioneditor/connectionview.h", - "connectioneditor/connectionviewwidget.cpp", - "connectioneditor/connectionviewwidget.h", - "connectioneditor/connectionviewwidget.ui", - "connectioneditor/dynamicpropertiesmodel.cpp", - "connectioneditor/dynamicpropertiesmodel.h", - "connectioneditor/selectiondynamicpropertiesproxymodel.cpp", - "connectioneditor/selectiondynamicpropertiesproxymodel.h", - "connectioneditor/stylesheet.css", - "curveeditor/curveeditorview.cpp", - "curveeditor/curveeditorview.h", - "curveeditor/animationcurve.cpp", - "curveeditor/animationcurve.h", - "curveeditor/curveeditor.cpp", - "curveeditor/curveeditor.h", - "curveeditor/curveeditor.qrc", - "curveeditor/curveeditormodel.cpp", - "curveeditor/curveeditormodel.h", - "curveeditor/curveeditortoolbar.cpp", - "curveeditor/curveeditortoolbar.h", - "curveeditor/curveeditorstyle.h", - "curveeditor/curvesegment.cpp", - "curveeditor/curvesegment.h", - "curveeditor/keyframe.cpp", - "curveeditor/keyframe.h", - "curveeditor/treeitem.cpp", - "curveeditor/treeitem.h", - "curveeditor/detail/axis.cpp", - "curveeditor/detail/axis.h", - "curveeditor/detail/colorcontrol.cpp", - "curveeditor/detail/colorcontrol.h", - "curveeditor/detail/curveeditorstyledialog.cpp", - "curveeditor/detail/curveeditorstyledialog.h", - "curveeditor/detail/curveitem.cpp", - "curveeditor/detail/curveitem.h", - "curveeditor/detail/graphicsscene.cpp", - "curveeditor/detail/graphicsscene.h", - "curveeditor/detail/graphicsview.cpp", - "curveeditor/detail/graphicsview.h", - "curveeditor/detail/handleitem.cpp", - "curveeditor/detail/handleitem.h", - "curveeditor/detail/keyframeitem.cpp", - "curveeditor/detail/keyframeitem.h", - "curveeditor/detail/playhead.cpp", - "curveeditor/detail/playhead.h", - "curveeditor/detail/selectableitem.cpp", - "curveeditor/detail/selectableitem.h", - "curveeditor/detail/selectionmodel.cpp", - "curveeditor/detail/selectionmodel.h", - "curveeditor/detail/selector.cpp", - "curveeditor/detail/selector.h", - "curveeditor/detail/shortcut.cpp", - "curveeditor/detail/shortcut.h", - "curveeditor/detail/treeitemdelegate.cpp", - "curveeditor/detail/treeitemdelegate.h", - "curveeditor/detail/treemodel.cpp", - "curveeditor/detail/treemodel.h", - "curveeditor/detail/treeview.cpp", - "curveeditor/detail/treeview.h", - "curveeditor/detail/curveeditorutils.cpp", - "curveeditor/detail/curveeditorutils.h", - "eventlist/assigneventdialog.cpp", - "eventlist/assigneventdialog.h", - "eventlist/connectsignaldialog.cpp", - "eventlist/connectsignaldialog.h", - "eventlist/eventlist.cpp", - "eventlist/eventlist.h", - "eventlist/eventlistactions.cpp", - "eventlist/eventlistactions.h", - "eventlist/eventlistdelegate.cpp", - "eventlist/eventlistdelegate.h", - "eventlist/eventlistdialog.cpp", - "eventlist/eventlistdialog.h", - "eventlist/eventlistplugin.qrc", - "eventlist/eventlistpluginview.cpp", - "eventlist/eventlistpluginview.h", - "eventlist/eventlistutils.cpp", - "eventlist/eventlistutils.h", - "eventlist/eventlistview.cpp", - "eventlist/eventlistview.h", - "eventlist/filterlinewidget.cpp", - "eventlist/filterlinewidget.h", - "eventlist/nodelistdelegate.cpp", - "eventlist/nodelistdelegate.h", - "eventlist/nodelistview.cpp", - "eventlist/nodelistview.h", - "eventlist/nodeselectionmodel.cpp", - "eventlist/nodeselectionmodel.h", - "eventlist/shortcutwidget.cpp", - "eventlist/shortcutwidget.h", - "pathtool/controlpoint.cpp", - "pathtool/controlpoint.h", - "pathtool/cubicsegment.cpp", - "pathtool/cubicsegment.h", - "pathtool/pathitem.cpp", - "pathtool/pathitem.h", - "pathtool/pathselectionmanipulator.cpp", - "pathtool/pathselectionmanipulator.h", - "pathtool/pathtool.cpp", - "pathtool/pathtool.h", - "pathtool/pathtoolview.cpp", - "pathtool/pathtoolview.h", - "previewtooltip/previewimagetooltip.cpp", - "previewtooltip/previewimagetooltip.h", - "previewtooltip/previewimagetooltip.ui", - "previewtooltip/previewtooltipbackend.cpp", - "previewtooltip/previewtooltipbackend.h", - "richtexteditor/hyperlinkdialog.cpp", - "richtexteditor/hyperlinkdialog.h", - "richtexteditor/hyperlinkdialog.ui", - "richtexteditor/richtexteditor.cpp", - "richtexteditor/richtexteditor.h", - "richtexteditor/richtexteditor.ui", - "richtexteditor/richtexteditorproxy.cpp", - "richtexteditor/richtexteditorproxy.h", - "sourcetool/sourcetool.cpp", - "sourcetool/sourcetool.h", - "texttool/textedititem.cpp", - "texttool/textedititem.h", - "texttool/textedititemwidget.cpp", - "texttool/textedititemwidget.h", - "texttool/texttool.cpp", - "texttool/texttool.h", - "timelineeditor/canvas.cpp", - "timelineeditor/canvas.h", - "timelineeditor/canvasstyledialog.cpp", - "timelineeditor/canvasstyledialog.h", - "timelineeditor/easingcurve.cpp", - "timelineeditor/easingcurve.h", - "timelineeditor/easingcurvedialog.cpp", - "timelineeditor/easingcurvedialog.h", - "timelineeditor/preseteditor.cpp", - "timelineeditor/preseteditor.h", - "timelineeditor/setframevaluedialog.cpp", - "timelineeditor/setframevaluedialog.h", - "timelineeditor/splineeditor.cpp", - "timelineeditor/splineeditor.h", - "timelineeditor/timeline.qrc", - "timelineeditor/timelineabstracttool.cpp", - "timelineeditor/timelineabstracttool.h", - "timelineeditor/timelineactions.cpp", - "timelineeditor/timelineactions.h", - "timelineeditor/timelineanimationform.cpp", - "timelineeditor/timelineanimationform.h", - "timelineeditor/timelineanimationform.ui", - "timelineeditor/timelineconstants.h", - "timelineeditor/timelinecontext.cpp", - "timelineeditor/timelinecontext.h", - "timelineeditor/timelinecontrols.cpp", - "timelineeditor/timelinecontrols.h", - "timelineeditor/timelineform.cpp", - "timelineeditor/timelineform.h", - "timelineeditor/timelineform.ui", - "timelineeditor/timelinegraphicslayout.cpp", - "timelineeditor/timelinegraphicslayout.h", - "timelineeditor/timelinegraphicsscene.cpp", - "timelineeditor/timelinegraphicsscene.h", - "timelineeditor/timelineicons.h", - "timelineeditor/timelineitem.cpp", - "timelineeditor/timelineitem.h", - "timelineeditor/timelinemovableabstractitem.cpp", - "timelineeditor/timelinemovableabstractitem.h", - "timelineeditor/timelinemovetool.cpp", - "timelineeditor/timelinemovetool.h", - "timelineeditor/timelineplaceholder.cpp", - "timelineeditor/timelineplaceholder.h", - "timelineeditor/timelinepropertyitem.cpp", - "timelineeditor/timelinepropertyitem.h", - "timelineeditor/timelinesectionitem.cpp", - "timelineeditor/timelinesectionitem.h", - "timelineeditor/timelineselectiontool.cpp", - "timelineeditor/timelineselectiontool.h", - "timelineeditor/timelinesettingsdialog.cpp", - "timelineeditor/timelinesettingsdialog.h", - "timelineeditor/timelinesettingsdialog.ui", - "timelineeditor/timelinesettingsmodel.cpp", - "timelineeditor/timelinesettingsmodel.h", - "timelineeditor/timelinetoolbar.cpp", - "timelineeditor/timelinetoolbar.h", - "timelineeditor/timelinetoolbutton.cpp", - "timelineeditor/timelinetoolbutton.h", - "timelineeditor/timelinetooldelegate.cpp", - "timelineeditor/timelineutils.cpp", - "timelineeditor/timelineutils.h", - "timelineeditor/timelineview.cpp", - "timelineeditor/timelineview.h", - "timelineeditor/timelinewidget.cpp", - "timelineeditor/timelinewidget.h", - "listmodeleditor/listmodeleditordialog.cpp", - "listmodeleditor/listmodeleditordialog.h", - "listmodeleditor/listmodeleditormodel.cpp", - "listmodeleditor/listmodeleditormodel.h", - "transitioneditor/transitioneditorview.cpp", - "transitioneditor/transitioneditorview.h", - "transitioneditor/transitioneditorwidget.cpp", - "transitioneditor/transitioneditorwidget.h", - "transitioneditor/transitioneditortoolbar.cpp", - "transitioneditor/transitioneditortoolbar.h", - "transitioneditor/transitioneditorgraphicsscene.cpp", - "transitioneditor/transitioneditorgraphicsscene.h", - "transitioneditor/transitioneditorgraphicslayout.cpp", - "transitioneditor/transitioneditorgraphicslayout.h", - "transitioneditor/transitioneditorsectionitem.cpp", - "transitioneditor/transitioneditorsectionitem.h", - "transitioneditor/transitioneditorpropertyitem.cpp", - "transitioneditor/transitioneditorpropertyitem.h", - "transitioneditor/transitioneditorsettingsdialog.cpp", - "transitioneditor/transitioneditorsettingsdialog.h", - "transitioneditor/transitioneditorsettingsdialog.ui", - "transitioneditor/transitionform.cpp", - "transitioneditor/transitionform.h", - "transitioneditor/transitionform.ui", - "transitioneditor/transitioneditor.qrc" - ] - } - - files: [ - "generateresource.cpp", - "generateresource.h", - "designersettings.cpp", - "designersettings.h", - "designmodecontext.cpp", - "designmodecontext.h", - "designmodewidget.cpp", - "designmodewidget.h", - "documentmanager.cpp", - "documentmanager.h", - "documentwarningwidget.cpp", - "documentwarningwidget.h", - "editorproxy.h", - "editorproxy.cpp", - "openuiqmlfiledialog.cpp", - "openuiqmlfiledialog.h", - "qmldesignerconstants.h", - "qmldesignericons.h", - "qmldesignerplugin.cpp", - "qmldesignerplugin.h", - "qmldesignerprojectmanager.cpp", - "qmldesignerprojectmanager.h", - "settingspage.cpp", - "settingspage.h", - "settingspage.ui", - "shortcutmanager.cpp", - "shortcutmanager.h", - "designermcumanager.cpp", - "designermcumanager.h", - "richtexteditordialog.cpp", - "richtexteditordialog.h", - ] - } -} diff --git a/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewplugin.qbs b/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewplugin.qbs deleted file mode 100644 index 05e809d4331..00000000000 --- a/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewplugin.qbs +++ /dev/null @@ -1,41 +0,0 @@ -import qbs - -QtcProduct { - name: "qmlpreviewplugin" - condition: QmlDesigner.present - type: ["dynamiclibrary"] - installDir: qtc.ide_plugin_path + '/' + installDirName - property string installDirName: qbs.targetOS.contains("macos") ? "QmlDesigner" : "qmldesigner" - - cpp.defines: base.concat("QMLPREVIEW_LIBRARY") - cpp.includePaths: base.concat("../designercore/include") - Properties { - condition: qbs.targetOS.contains("unix") - cpp.internalVersion: "" - } - - Depends { name: "Core" } - Depends { name: "ProjectExplorer" } - Depends { name: "QmlDesigner"; required: false } - Depends { name: "Qt.qml" } - Depends { name: "Utils" } - - Group { - name: "images" - files: ["images/*.png"] - } - - Group { - name: "plugin metadata" - files: ["qmlpreviewplugin.json"] - fileTags: ["qt_plugin_metadata"] - } - - files: [ - "qmlpreviewactions.cpp", - "qmlpreviewactions.h", - "qmlpreviewplugin.cpp", - "qmlpreviewplugin.h", - "qmlpreviewplugin.qrc", - ] -} diff --git a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qbs b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qbs deleted file mode 100644 index 09245f424c4..00000000000 --- a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qbs +++ /dev/null @@ -1,41 +0,0 @@ -import qbs - -QtcProduct { - name: "qtquickplugin" - type: ["dynamiclibrary"] - installDir: qtc.ide_plugin_path + '/' + installDirName - property string installDirName: qbs.targetOS.contains("macos") ? "QmlDesigner" : "qmldesigner" - - Depends { name: "Qt.qml" } - - cpp.defines: base.concat("QTQUICK_LIBRARY") - cpp.includePaths: base.concat("../designercore/include") - Properties { - condition: qbs.targetOS.contains("unix") - cpp.internalVersion: "" - } - - Group { - name: "sources" - files: ["sources/*.qml"] - } - - Group { - name: "images" - files: ["images/*.png"] - } - - Group { - name: "plugin metadata" - files: ["qtquickplugin.json"] - fileTags: ["qt_plugin_metadata"] - } - - files: [ - "quick.metainfo", - "qtquickplugin.cpp", - "qtquickplugin.h", - "qtquickplugin.qrc", - "../designercore/include/iwidgetplugin.h", - ] -} diff --git a/src/plugins/studiowelcome/studiowelcome.qbs b/src/plugins/studiowelcome/studiowelcome.qbs index 085d1015bd6..f1035511d57 100644 --- a/src/plugins/studiowelcome/studiowelcome.qbs +++ b/src/plugins/studiowelcome/studiowelcome.qbs @@ -1,58 +1,6 @@ import qbs.FileInfo -QtcPlugin { +Product { name: "StudioWelcome" - condition: QmlDesigner.present - - Depends { name: "Qt"; submodules: ["qml", "qml-private", "quick", "quickwidgets"] } - Depends { name: "Utils" } - - Depends { name: "Core" } - Depends { name: "ProjectExplorer" } - Depends { name: "QtSupport" } - Depends { name: "QmlDesigner"; required: false } - Depends { name: "QmlProjectManager" } - Depends { name: "app_version_header" } - - cpp.defines: 'STUDIO_QML_PATH="' + FileInfo.joinPaths(sourceDirectory, "qml") + '"' - - files: [ - "createproject.cpp", - "createproject.h", - "examplecheckout.h", - "examplecheckout.cpp", - "newprojectdialogimageprovider.h", - "newprojectdialogimageprovider.cpp", - "presetmodel.cpp", - "presetmodel.h", - "qdsnewdialog.cpp", - "qdsnewdialog.h", - "screensizemodel.h", - "studiowelcome_global.h", "studiowelcometr.h", - "studiowelcomeplugin.h", - "studiowelcomeplugin.cpp", - "studiowelcome.qrc", - "stylemodel.cpp", - "stylemodel.h", - "wizardfactories.cpp", - "wizardfactories.h", - "wizardhandler.cpp", - "wizardhandler.h", - "userpresets.cpp", - "userpresets.h" - ] - - Group { - name: "studiofonts" - prefix: "../../share/3rdparty/studiofonts/" - files: "studiofonts.qrc" - } - - Qt.core.resourceFileBaseName: "StudioWelcome_qml" - Qt.core.resourceSourceBase: "." - Group { - name: "Qml Files" - fileTags: "qt.core.resource_data" - files: "qml/**" - } + files: ["*", "**/*"] } diff --git a/tests/unit/unit.qbs b/tests/unit/unit.qbs index f6c9dc3e9d3..b263b933f8f 100644 --- a/tests/unit/unit.qbs +++ b/tests/unit/unit.qbs @@ -1,7 +1,4 @@ -Project { - name: "C++ unit tests" - condition: project.withAutotests - references: [ - "unittest/unittest.qbs", - ] +Product { + name: "QmlDesigner unit tests" + files: ["*", "**/*"] } diff --git a/tests/unit/unittest/unittest.qbs b/tests/unit/unittest/unittest.qbs deleted file mode 100644 index ad869430ae1..00000000000 --- a/tests/unit/unittest/unittest.qbs +++ /dev/null @@ -1,149 +0,0 @@ -import qbs.File -import qbs.FileInfo - -Project { - name: "Unit test & helper products" - - QtcProduct { - name: "Unit test" - condition: (qtc_gtest_gmock.hasRepo || qtc_gtest_gmock.externalLibsPresent) - && QmlDesigner.present - - type: ["application", "autotest"] - consoleApplication: true - destinationDirectory: FileInfo.joinPaths(project.buildDirectory, - FileInfo.relativePath(project.ide_source_tree, sourceDirectory)) - install: false - - Depends { name: "QmlDesigner"; required: false } - - Depends { name: "sqlite_sources" } - Depends { name: "Core" } - Depends { name: "CPlusPlus" } - - Depends { name: "Qt"; submodules: ["network", "widgets", "testlib"] } - - Depends { name: "pkgconfig"; required: false } - Depends { name: "benchmark"; required: false } - - Depends { name: "qtc_gtest_gmock"; required: false } - - sqlite_sources.buildSharedLib: true - - cpp.defines: { - var defines = [ - "QT_NO_CAST_TO_ASCII", - "QT_RESTRICTED_CAST_FROM_ASCII", - "QT_USE_FAST_OPERATOR_PLUS", - "QT_USE_FAST_CONCATENATION", - "UNIT_TESTS", - "DONT_CHECK_MESSAGE_COUNTER", - 'QTC_RESOURCE_DIR="' + path + "/../../../share/qtcreator" + '"', - 'TESTDATA_DIR="' + FileInfo.joinPaths(sourceDirectory, "data") + '"', - 'RELATIVE_DATA_PATH="' + FileInfo.relativePath(destinationDirectory, - FileInfo.joinPaths(project.sourceDirectory, "share", "qtcreator")) + '"', - ]; - var absLibExecPath = FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix, - qtc.ide_libexec_path); - var relLibExecPath = FileInfo.relativePath(destinationDirectory, absLibExecPath); - defines.push('TEST_RELATIVE_LIBEXEC_PATH="' + relLibExecPath + '"'); - return defines; - } - cpp.cxxFlags: { - var flags = []; - if (qbs.toolchain.contains("msvc")) - flags.push("-w34100", "/bigobj", "/wd4267", "/wd4141", "/wd4146"); - if (qbs.toolchain.contains("gcc") && !qbs.toolchain.contains("clang")) - flags.push("-Wno-noexcept-type"); - if (qbs.toolchain.contains("clang")) { - flags.push("-Wno-inconsistent-missing-override", "-Wno-self-move", - "-Wno-self-assign-overloaded"); - flags.push("-Wno-unused-command-line-argument"); // gtest puts -lpthread on compiler command line - if (!qbs.hostOS.contains("darwin") - && Utilities.versionCompare(cpp.compilerVersion, "10") >= 0) { - flags.push("-Wno-deprecated-copy", "-Wno-constant-logical-operand"); - } - } - if (qbs.toolchain.contains("gcc")) - flags.push("-Wno-unused-parameter"); - return flags; - } - cpp.cxxLanguageVersion: "c++17" - cpp.includePaths: [ - ".", - "../mockup", - "../../../src/libs", - "../../../src/libs/3rdparty", - "../../../src/plugins", - "../../../share/qtcreator/qml/qmlpuppet/types", - ] - cpp.rpaths: [ - FileInfo.joinPaths(project.buildDirectory, qtc.ide_library_path), - FileInfo.joinPaths(project.buildDirectory, qtc.ide_plugin_path) - ] - - files: [ - "compare-operators.h", - "conditionally-disabled-tests.h", - "createtablesqlstatementbuilder-test.cpp", - "dynamicastmatcherdiagnosticcontainer-matcher.h", - "eventspy.cpp", - "eventspy.h", - "fakeprocess.cpp", - "fakeprocess.h", - "google-using-declarations.h", - "googletest.h", - "gtest-creator-printing.cpp", - "gtest-creator-printing.h", - "gtest-llvm-printing.h", - "gtest-qt-printing.cpp", - "gtest-qt-printing.h", - "matchingtext-test.cpp", - "mockfutureinterface.h", - "mockmutex.h", - "mockqfilesystemwatcher.h", - "mocksqlitestatement.h", - "mocksqlitetransactionbackend.h", - "mocksyntaxhighligher.h", - "mocktimer.cpp", - "mocktimer.h", - "processevents-utilities.cpp", - "processevents-utilities.h", - "sizedarray-test.cpp", - "smallstring-test.cpp", - "spydummy.cpp", - "spydummy.h", - "sqlitecolumn-test.cpp", - "sqlitedatabase-test.cpp", - "sqlitedatabasebackend-test.cpp", - "sqlitedatabasemock.h", - "sqliteindex-test.cpp", - "sqlitereadstatementmock.cpp", - "sqlitereadstatementmock.h", - "sqlitestatement-test.cpp", - "sqlitetable-test.cpp", - "sqliteteststatement.h", - "sqlitetransaction-test.cpp", - "sqlitevalue-test.cpp", - "sqlitewritestatementmock.cpp", - "sqlitewritestatementmock.h", - "sqlstatementbuilder-test.cpp", - "unittest-utility-functions.h", - "unittests-main.cpp", - ] - - Group { - name: "benchmark test" - condition: benchmark.present - files: "smallstring-benchmark.cpp" - } - - Group { - name: "data" - files: [ - "data/*", - ] - fileTags: [] - } - } -} From 213c879882307e6326a4dc1c718d8c232312a4a0 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Wed, 5 Oct 2022 20:46:48 +0200 Subject: [PATCH 08/42] CMakePM: Skip default build types for CMakePresets If a preset has a build directory set, that build directory and build type should be displayed in the initial configuration dialog. Change-Id: I884471cb4d482c92ab091a4043d642828318b4d2 Reviewed-by: Alessandro Portale --- .../cmakebuildconfiguration.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 9afa4b8e21b..91de7766c7d 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -1953,6 +1954,22 @@ CMakeBuildConfigurationFactory::CMakeBuildConfigurationFactory() FilePath path = forSetup ? Project::projectDirectory(projectPath) : projectPath; + // Skip the default shadow build directories for build types if we have presets + const CMakeConfigItem presetItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(k); + if (!presetItem.isNull()) { + const QString presetName = presetItem.expandedValue(k); + const auto project = qobject_cast(SessionManager::startupProject()); + + PresetsDetails::ConfigurePreset configurePreset + = Utils::findOrDefault(project->presetsData().configurePresets, + [&presetName] (const PresetsDetails::ConfigurePreset &preset) { + return preset.name == presetName; + }); + + if (configurePreset.binaryDir) + return result; + } + for (int type = BuildTypeDebug; type != BuildTypeLast; ++type) { BuildInfo info = createBuildInfo(BuildType(type)); if (forSetup) { From e54fb7ab649521824486e4596e09d2ba164077ba Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 10 Oct 2022 16:04:17 +0200 Subject: [PATCH 09/42] Replace missing qAsConst with std::as_const() Patch missing leftovers after recent batch patch. Amends 8eb4d52342fe3a6ede1c1dce3174d95bfa0cea88 Change-Id: I5469b8c10e6844cd1911f719ce3dddbb42697f95 Reviewed-by: hjk --- src/plugins/beautifier/abstractsettings.cpp | 2 +- src/plugins/bookmarks/bookmarkmanager.cpp | 2 +- src/plugins/coreplugin/dialogs/ioptionspage.cpp | 2 +- src/plugins/fakevim/fakevimhandler.cpp | 4 ++-- src/plugins/help/docsettingspage.cpp | 2 +- src/plugins/help/generalsettingspage.cpp | 2 +- src/plugins/qbsprojectmanager/qbsprojectimporter.cpp | 2 +- .../customwidgetwizard/plugingenerator.cpp | 2 +- src/plugins/qmakeprojectmanager/makefileparse.cpp | 2 +- .../qmakeprojectmanager/qmakebuildconfiguration.cpp | 2 +- src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp | 6 +++--- src/plugins/qmakeprojectmanager/qmakeproject.cpp | 8 ++++---- src/plugins/resourceeditor/qrceditor/resourcefile.cpp | 6 +++--- src/plugins/resourceeditor/resourcenode.cpp | 2 +- src/plugins/todo/todoitemsprovider.cpp | 4 ++-- 15 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/plugins/beautifier/abstractsettings.cpp b/src/plugins/beautifier/abstractsettings.cpp index 4875e13ec50..9541172d63b 100644 --- a/src/plugins/beautifier/abstractsettings.cpp +++ b/src/plugins/beautifier/abstractsettings.cpp @@ -258,7 +258,7 @@ void AbstractSettings::save() return; // remove old files and possible subfolder - for (const QString &key : qAsConst(m_stylesToRemove)) { + for (const QString &key : std::as_const(m_stylesToRemove)) { const QFileInfo fi(styleFileName(key)); QFile::remove(fi.absoluteFilePath()); if (fi.absoluteDir() != m_styleDir) diff --git a/src/plugins/bookmarks/bookmarkmanager.cpp b/src/plugins/bookmarks/bookmarkmanager.cpp index 121ea783190..e503ce87c99 100644 --- a/src/plugins/bookmarks/bookmarkmanager.cpp +++ b/src/plugins/bookmarks/bookmarkmanager.cpp @@ -748,7 +748,7 @@ QString BookmarkManager::bookmarkToString(const Bookmark *b) void BookmarkManager::saveBookmarks() { QStringList list; - for (const Bookmark *bookmark : qAsConst(m_bookmarksList)) + for (const Bookmark *bookmark : std::as_const(m_bookmarksList)) list << bookmarkToString(bookmark); SessionManager::setValue(QLatin1String("Bookmarks"), list); diff --git a/src/plugins/coreplugin/dialogs/ioptionspage.cpp b/src/plugins/coreplugin/dialogs/ioptionspage.cpp index 7378b330148..32c2b3d5981 100644 --- a/src/plugins/coreplugin/dialogs/ioptionspage.cpp +++ b/src/plugins/coreplugin/dialogs/ioptionspage.cpp @@ -259,7 +259,7 @@ bool IOptionsPage::matches(const QRegularExpression ®exp) const m_keywordsInitialized = true; } - for (const QString &keyword : qAsConst(m_keywords)) + for (const QString &keyword : std::as_const(m_keywords)) if (keyword.contains(regexp)) return true; return false; diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 86eaa8efa12..72d396729aa 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -6070,13 +6070,13 @@ bool FakeVimHandler::Private::handleExMapCommand(const ExCommand &cmd0) // :map //qDebug() << "MAPPING: " << modes << lhs << rhs; switch (type) { case Unmap: - for (char c : qAsConst(modes)) + for (char c : std::as_const(modes)) MappingsIterator(&g.mappings, c, key).remove(); break; case Map: Q_FALLTHROUGH(); case Noremap: { const Inputs inputs(rhs, type == Noremap, silent); - for (char c : qAsConst(modes)) + for (char c : std::as_const(modes)) MappingsIterator(&g.mappings, c).setInputs(key, inputs, unique); break; } diff --git a/src/plugins/help/docsettingspage.cpp b/src/plugins/help/docsettingspage.cpp index b532c3b0fdf..757db9043fc 100644 --- a/src/plugins/help/docsettingspage.cpp +++ b/src/plugins/help/docsettingspage.cpp @@ -250,7 +250,7 @@ void DocSettingsPageWidget::addDocumentation() QSet values = Utils::toSet(m_filesToUnregister.values(nameSpace)); values.remove(filePath); m_filesToUnregister.remove(nameSpace); - for (const QString &value : qAsConst(values)) + for (const QString &value : std::as_const(values)) m_filesToUnregister.insert(nameSpace, value); } } diff --git a/src/plugins/help/generalsettingspage.cpp b/src/plugins/help/generalsettingspage.cpp index 47ba717fd73..459face1180 100644 --- a/src/plugins/help/generalsettingspage.cpp +++ b/src/plugins/help/generalsettingspage.cpp @@ -425,7 +425,7 @@ void GeneralSettingsPage::updateFontSizeSelector() // try to maintain selection or select closest. if (!pointSizes.empty()) { QString n; - for (int pointSize : qAsConst(pointSizes)) + for (int pointSize : std::as_const(pointSizes)) m_widget->sizeComboBox->addItem(n.setNum(pointSize), QVariant(pointSize)); const int closestIndex = closestPointSizeIndex(m_font.pointSize()); if (closestIndex != -1) diff --git a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp index 7ef50a4e30c..06d6e6376e7 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp @@ -181,7 +181,7 @@ Kit *QbsProjectImporter::createKit(void *directoryData) const tcData << findOrCreateToolChains({bgData->cxxCompilerPath, Constants::CXX_LANGUAGE_ID}); if (!bgData->cCompilerPath.isEmpty()) tcData << findOrCreateToolChains({bgData->cCompilerPath, Constants::C_LANGUAGE_ID}); - for (const ToolChainData &tc : qAsConst(tcData)) { + for (const ToolChainData &tc : std::as_const(tcData)) { if (!tc.tcs.isEmpty()) ToolChainKitAspect::setToolChain(k, tc.tcs.first()); } diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/plugingenerator.cpp b/src/plugins/qmakeprojectmanager/customwidgetwizard/plugingenerator.cpp index 634b73507cf..c3475fd1334 100644 --- a/src/plugins/qmakeprojectmanager/customwidgetwizard/plugingenerator.cpp +++ b/src/plugins/qmakeprojectmanager/customwidgetwizard/plugingenerator.cpp @@ -247,7 +247,7 @@ QList PluginGenerator::generatePlugin(const GenerationPara // Copy icons that are not in the plugin source base directory yet (that is, // probably all), add them to the resource file QString iconFiles; - for (QString icon : qAsConst(pluginIcons)) { + for (QString icon : std::as_const(pluginIcons)) { const QFileInfo qfi(icon); if (qfi.dir() != slashLessBaseDir) { const QString newIcon = baseDir + qfi.fileName(); diff --git a/src/plugins/qmakeprojectmanager/makefileparse.cpp b/src/plugins/qmakeprojectmanager/makefileparse.cpp index a01eb0e5afd..c24450a5105 100644 --- a/src/plugins/qmakeprojectmanager/makefileparse.cpp +++ b/src/plugins/qmakeprojectmanager/makefileparse.cpp @@ -348,7 +348,7 @@ void MakeFileParse::parseCommandLine(const QString &command, const QString &proj ProcessArgs::addArg(&m_unparsedArguments, qa.variable + qa.op + qa.value); if (!afterAssignments.isEmpty()) { ProcessArgs::addArg(&m_unparsedArguments, QLatin1String("-after")); - for (const QMakeAssignment &qa : qAsConst(afterAssignments)) + for (const QMakeAssignment &qa : std::as_const(afterAssignments)) ProcessArgs::addArg(&m_unparsedArguments, qa.variable + qa.op + qa.value); } } diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp index b809ae17402..899ed4e4a4f 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp @@ -276,7 +276,7 @@ void QmakeBuildConfiguration::updateProblemLabel() if (!issues.isEmpty()) { QString text = QLatin1String(""); - for (const ProjectExplorer::Task &task : qAsConst(issues)) { + for (const ProjectExplorer::Task &task : std::as_const(issues)) { QString type; switch (task.type) { case ProjectExplorer::Task::Error: diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index 100016cb021..6df3ff16fe7 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -281,7 +281,7 @@ void QmakePriFile::extractSources( QHash proToResult, QmakePriFileEvalResult *fallback, QVector sourceFiles, FileType type, bool cumulative) { - for (const ProFileEvaluator::SourceFile &source : qAsConst(sourceFiles)) { + for (const ProFileEvaluator::SourceFile &source : std::as_const(sourceFiles)) { auto *result = proToResult.value(source.proFileId); if (!result) result = fallback; @@ -447,7 +447,7 @@ bool QmakePriFile::deploysFolder(const QString &folder) const if (!f.endsWith(slash)) f.append(slash); - for (const QString &wf : qAsConst(m_watchedFolders)) { + for (const QString &wf : std::as_const(m_watchedFolders)) { if (f.startsWith(wf) && (wf.endsWith(slash) || (wf.length() < f.length() && f.at(wf.length()) == slash))) @@ -1644,7 +1644,7 @@ void QmakeProFile::applyEvaluate(const QmakeEvalResultPtr &result) return; } - for (const QString &error : qAsConst(result->errors)) + for (const QString &error : std::as_const(result->errors)) QmakeBuildSystem::proFileParseError(error, filePath()); // we are changing what is executed in that case diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index f2fc741156c..605c4c19bb2 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -718,7 +718,7 @@ void QmakeBuildSystem::asyncUpdate() project()->updateExtraProjectFiles(docUpdater); rootProFile()->asyncUpdate(); } else { - for (QmakeProFile *file : qAsConst(m_partialEvaluate)) + for (QmakeProFile *file : std::as_const(m_partialEvaluate)) file->asyncUpdate(); } @@ -1024,7 +1024,7 @@ void CentralizedFolderWatcher::unwatchFolders(const QList &folders, Qma // where a given directory watcher actual comes from... QStringList toRemove; - for (const QString &rwf : qAsConst(m_recursiveWatchedFolders)) { + for (const QString &rwf : std::as_const(m_recursiveWatchedFolders)) { if (rwf.startsWith(folder)) { // So the rwf is a subdirectory of a folder we aren't watching // but maybe someone else wants us to watch @@ -1043,7 +1043,7 @@ void CentralizedFolderWatcher::unwatchFolders(const QList &folders, Qma } } - for (const QString &tr : qAsConst(toRemove)) + for (const QString &tr : std::as_const(toRemove)) m_recursiveWatchedFolders.remove(tr); } } @@ -1056,7 +1056,7 @@ void CentralizedFolderWatcher::folderChanged(const QString &folder) void CentralizedFolderWatcher::onTimer() { - for (const QString &folder : qAsConst(m_changedFolders)) + for (const QString &folder : std::as_const(m_changedFolders)) delayedFolderChanged(folder); m_changedFolders.clear(); } diff --git a/src/plugins/resourceeditor/qrceditor/resourcefile.cpp b/src/plugins/resourceeditor/qrceditor/resourcefile.cpp index 04f55ec7d03..74e543a5da5 100644 --- a/src/plugins/resourceeditor/qrceditor/resourcefile.cpp +++ b/src/plugins/resourceeditor/qrceditor/resourcefile.cpp @@ -356,7 +356,7 @@ bool ResourceFile::renameFile(const QString &fileName, const QString &newFileNam entries.at(0)->checkExistence(); if (entries.at(0)->exists()) { - for (File *file : qAsConst(entries)) + for (File *file : std::as_const(entries)) file->setExists(true); success = Core::FileUtils::renameFile(Utils::FilePath::fromString(entries.at(0)->name), Utils::FilePath::fromString(newFileName)); @@ -364,7 +364,7 @@ bool ResourceFile::renameFile(const QString &fileName, const QString &newFileNam if (success) { const bool exists = QFile::exists(newFileName); - for (File *file : qAsConst(entries)) { + for (File *file : std::as_const(entries)) { file->name = newFileName; file->setExists(exists); } @@ -715,7 +715,7 @@ bool ResourceModel::iconFileExtension(const QString &path) } } - for (const QString &ext : qAsConst(ext_list)) { + for (const QString &ext : std::as_const(ext_list)) { if (path.endsWith(ext, Qt::CaseInsensitive)) return true; } diff --git a/src/plugins/resourceeditor/resourcenode.cpp b/src/plugins/resourceeditor/resourcenode.cpp index f90ccbef008..4c2df2c2bed 100644 --- a/src/plugins/resourceeditor/resourcenode.cpp +++ b/src/plugins/resourceeditor/resourcenode.cpp @@ -321,7 +321,7 @@ void ResourceTopLevelNode::addInternalNodes() QString parentFolderName; PrefixFolderLang folderId(prefix, QString(), lang); QStringList currentPathList; - for (const QString &pathElement : qAsConst(pathList)) { + for (const QString &pathElement : std::as_const(pathList)) { currentPathList << pathElement; const QString folderName = currentPathList.join(QLatin1Char('/')); folderId = PrefixFolderLang(prefix, folderName, lang); diff --git a/src/plugins/todo/todoitemsprovider.cpp b/src/plugins/todo/todoitemsprovider.cpp index 52803e839f0..04014c96415 100644 --- a/src/plugins/todo/todoitemsprovider.cpp +++ b/src/plugins/todo/todoitemsprovider.cpp @@ -47,7 +47,7 @@ TodoItemsModel *TodoItemsProvider::todoItemsModel() void TodoItemsProvider::settingsChanged(const Settings &newSettings) { if (newSettings.keywords != m_settings.keywords) { - for (TodoItemsScanner *scanner : qAsConst(m_scanners)) + for (TodoItemsScanner *scanner : std::as_const(m_scanners)) scanner->setParams(newSettings.keywords); } @@ -92,7 +92,7 @@ void TodoItemsProvider::createScanners() if (QmlJS::ModelManagerInterface::instance()) m_scanners << new QmlJsTodoItemsScanner(m_settings.keywords, this); - for (TodoItemsScanner *scanner : qAsConst(m_scanners)) { + for (TodoItemsScanner *scanner : std::as_const(m_scanners)) { connect(scanner, &TodoItemsScanner::itemsFetched, this, &TodoItemsProvider::itemsFetched, Qt::QueuedConnection); } From 05acf3e6f42853d65372aeb3dbb4ca647e6b9e9c Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Wed, 5 Oct 2022 21:08:54 +0200 Subject: [PATCH 10/42] CMakePM: Do not display duplicated build paths for presets If we configure a project with presets, build all the configurations, then delete the CMakeLists.txt.user file to re-configure the presets, we shouldn't get two entries in the initial configuration dialog. Change-Id: I9bb234aa54fcce193dbd07dd3aa77e91f639b179 Reviewed-by: Alessandro Portale --- .../cmakeprojectmanager/cmakeprojectimporter.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index 4be73541a80..e870b787bc9 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -131,6 +131,20 @@ FilePaths CMakeProjectImporter::importCandidates() const FilePath configPresetDir = m_presetsTempDir.filePath(configPreset.name); configPresetDir.createDir(); candidates << configPresetDir; + + // If the binaryFilePath exists, do not try to import the existing build, so that + // we don't have duplicates, one from the preset and one from the previous configuration. + if (configPreset.binaryDir) { + Environment env = Environment::systemEnvironment(); + CMakePresets::Macros::expand(configPreset, env, projectDirectory()); + + QString binaryDir = configPreset.binaryDir.value(); + CMakePresets::Macros::expand(configPreset, env, projectDirectory(), binaryDir); + + const FilePath binaryFilePath = FilePath::fromString(binaryDir); + candidates.removeIf( + [&binaryFilePath] (const FilePath &path) { return path == binaryFilePath; }); + } } const FilePaths finalists = Utils::filteredUnique(candidates); From 0c2a86b63f928a416b256e110330cef87fec85ba Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 10 Oct 2022 16:51:04 +0200 Subject: [PATCH 11/42] Doc: Describe new preferences for refactoring actions Task-number: QTCREATORBUG-27876 Change-Id: I37513cc641db034eaf1737eee4f25c5ba6b7fd82 Reviewed-by: Christian Kandeler --- ...tcreator-refactoring-options-templates.png | Bin 10299 -> 9582 bytes .../src/editors/creator-quick-fixes.qdoc | 10 ++++++++++ 2 files changed, 10 insertions(+) diff --git a/doc/qtcreator/images/qtcreator-refactoring-options-templates.png b/doc/qtcreator/images/qtcreator-refactoring-options-templates.png index e84c7cf58248fd3a30ae282aac343c8fa50aa968..a5e53b37bc9ef718abcda1be5de8d532adbd3ad2 100644 GIT binary patch literal 9582 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 diff --git a/doc/qtcreator/src/editors/creator-quick-fixes.qdoc b/doc/qtcreator/src/editors/creator-quick-fixes.qdoc index 282f656a983..0dee251e3a0 100644 --- a/doc/qtcreator/src/editors/creator-quick-fixes.qdoc +++ b/doc/qtcreator/src/editors/creator-quick-fixes.qdoc @@ -145,6 +145,9 @@ removed. The real Type must contain the given Type. For example, \c int matches \c int32_t but not \c vector, and \c vector matches \c {std::pmr::vector} but not \c {std::optional>}. + + To return non-trivial objects by using a \c const reference, select the + \uicontrol {Return non-value types by const reference} check box. \endif \section1 Summary of Refactoring Actions @@ -721,6 +724,13 @@ Foo * localFoo = new Foo; \endcode + By default, \QC uses the \c auto variable type when creating the + variable. To label the variable with its actual type, select + \uicontrol Edit > \uicontrol Preferences > \uicontrol C++ > + \uicontrol {Quick Fixes}, and then deselect the + \uicontrol {Use type "auto" when creating new variables} check + box. + \li Function call or class name \row \li Insert Virtual Functions of Base Classes From 2e38cb68489326142f78d3c5c022b5a2ae866762 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 10 Oct 2022 17:11:51 +0200 Subject: [PATCH 12/42] Utils: Add an offset parameter to the content writing FilePath function Use QFile::seek to implement locally and a dd seek based poor man's implementation on RL and docker. Change-Id: I241d1c34c00e991845d132ad8edefa1377ba1311 Reviewed-by: Christian Kandeler --- src/libs/utils/filepath.cpp | 14 +++++++++----- src/libs/utils/filepath.h | 11 +++++++---- src/plugins/docker/dockerdevice.cpp | 11 +++++++++-- src/plugins/docker/dockerdevice.h | 4 +++- .../devicesupport/desktopdevice.cpp | 6 ++++-- .../projectexplorer/devicesupport/desktopdevice.h | 4 +++- .../devicesupport/devicemanager.cpp | 6 ++++-- .../projectexplorer/devicesupport/idevice.cpp | 8 +++++--- .../projectexplorer/devicesupport/idevice.h | 7 +++++-- src/plugins/remotelinux/linuxdevice.cpp | 11 +++++++++-- src/plugins/remotelinux/linuxdevice.h | 4 +++- tests/auto/utils/fsengine/tst_fsengine.cpp | 6 ++++-- 12 files changed, 65 insertions(+), 27 deletions(-) diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index 02335910ec9..3aa7e4a11d6 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -586,28 +586,32 @@ void FilePath::asyncFileContents(const Continuation &cont, const QByteArray &data) const +void FilePath::asyncWriteFileContents(const Continuation &cont, + const QByteArray &data, + qint64 offset) const { if (needsDevice()) { QTC_ASSERT(s_deviceHooks.asyncWriteFileContents, return); - s_deviceHooks.asyncWriteFileContents(cont, *this, data); + s_deviceHooks.asyncWriteFileContents(cont, *this, data, offset); return; } - cont(writeFileContents(data)); + cont(writeFileContents(data, offset)); } bool FilePath::needsDevice() const diff --git a/src/libs/utils/filepath.h b/src/libs/utils/filepath.h index 325eaeabf2d..d4b1f714b24 100644 --- a/src/libs/utils/filepath.h +++ b/src/libs/utils/filepath.h @@ -118,7 +118,7 @@ public: FilePaths dirEntries(const FileFilter &filter, QDir::SortFlags sort = QDir::NoSort) const; FilePaths dirEntries(QDir::Filters filters) const; std::optional fileContents(qint64 maxSize = -1, qint64 offset = 0) const; - bool writeFileContents(const QByteArray &data) const; + bool writeFileContents(const QByteArray &data, qint64 offset = 0) const; bool operator==(const FilePath &other) const; bool operator!=(const FilePath &other) const; @@ -180,7 +180,9 @@ public: void asyncFileContents(const Continuation &> &cont, qint64 maxSize = -1, qint64 offset = 0) const; - void asyncWriteFileContents(const Continuation &cont, const QByteArray &data) const; + void asyncWriteFileContents(const Continuation &cont, + const QByteArray &data, + qint64 offset = 0) const; // Prefer not to use // Using needsDevice() in "user" code is likely to result in code that @@ -259,7 +261,7 @@ public: const std::function &, // Abort on 'false' return. const FileFilter &)> iterateDirectory; std::function(const FilePath &, qint64, qint64)> fileContents; - std::function writeFileContents; + std::function writeFileContents; std::function lastModified; std::function permissions; std::function setPermissions; @@ -276,7 +278,8 @@ public: std::function &> &, const FilePath &, qint64, qint64)> asyncFileContents; - std::function &, const FilePath &, const QByteArray &)> asyncWriteFileContents; + std::function &, const FilePath &, const QByteArray &, qint64)> + asyncWriteFileContents; std::function ensureReachable; }; diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index 8ab4bb9f8e6..38a30aa76f3 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -910,10 +910,17 @@ std::optional DockerDevice::fileContents(const FilePath &filePath, return d->fileContents(filePath, limit, offset); } -bool DockerDevice::writeFileContents(const FilePath &filePath, const QByteArray &data) const +bool DockerDevice::writeFileContents(const FilePath &filePath, + const QByteArray &data, + qint64 offset) const { QTC_ASSERT(handlesFile(filePath), return {}); - return d->runInShellSuccess({"dd", {"of=" + filePath.path()}}, data); + CommandLine cmd({"dd", {"of=" + filePath.path()}}); + if (offset != 0) { + cmd.addArg("bs=1"); + cmd.addArg(QString("seek=%1").arg(offset)); + } + return d->runInShellSuccess(cmd, data); } Environment DockerDevice::systemEnvironment() const diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h index 7de2a762829..4e7840b9282 100644 --- a/src/plugins/docker/dockerdevice.h +++ b/src/plugins/docker/dockerdevice.h @@ -105,7 +105,9 @@ public: std::optional fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) const override; - bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override; + bool writeFileContents(const Utils::FilePath &filePath, + const QByteArray &data, + qint64 offset) const override; QDateTime lastModified(const Utils::FilePath &filePath) const override; qint64 fileSize(const Utils::FilePath &filePath) const override; QFileDevice::Permissions permissions(const Utils::FilePath &filePath) const override; diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp index baee2cd84eb..105e80e34f1 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp @@ -278,10 +278,12 @@ std::optional DesktopDevice::fileContents(const FilePath &filePath, return filePath.fileContents(limit, offset); } -bool DesktopDevice::writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const +bool DesktopDevice::writeFileContents(const FilePath &filePath, + const QByteArray &data, + qint64 offset) const { QTC_ASSERT(handlesFile(filePath), return {}); - return filePath.writeFileContents(data); + return filePath.writeFileContents(data, offset); } } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.h b/src/plugins/projectexplorer/devicesupport/desktopdevice.h index b310c73b7d3..a2a17237ac3 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopdevice.h +++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.h @@ -56,7 +56,9 @@ public: std::optional fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) const override; - bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override; + bool writeFileContents(const Utils::FilePath &filePath, + const QByteArray &data, + qint64 offset) const override; qint64 fileSize(const Utils::FilePath &filePath) const override; QFile::Permissions permissions(const Utils::FilePath &filePath) const override; bool setPermissions(const Utils::FilePath &filePath, QFile::Permissions) const override; diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp index c0ae7a1726e..febcc6436eb 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp @@ -544,10 +544,12 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_uniqueasyncFileContents(cont, filePath, maxSize, offset); }; - deviceHooks.writeFileContents = [](const FilePath &filePath, const QByteArray &data) { + deviceHooks.writeFileContents = [](const FilePath &filePath, + const QByteArray &data, + qint64 offset) { auto device = DeviceManager::deviceForPath(filePath); QTC_ASSERT(device, return false); - return device->writeFileContents(filePath, data); + return device->writeFileContents(filePath, data, offset); }; deviceHooks.lastModified = [](const FilePath &filePath) { diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index 7b723a2fcee..9c391de5aed 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -384,19 +384,21 @@ void IDevice::asyncFileContents(const Continuation> &c cont(fileContents(filePath, limit, offset)); } -bool IDevice::writeFileContents(const FilePath &filePath, const QByteArray &data) const +bool IDevice::writeFileContents(const FilePath &filePath, const QByteArray &data, qint64 offset) const { Q_UNUSED(filePath); Q_UNUSED(data); + Q_UNUSED(offset); QTC_CHECK(false); return {}; } void IDevice::asyncWriteFileContents(const Continuation &cont, const FilePath &filePath, - const QByteArray &data) const + const QByteArray &data, + qint64 offset) const { - cont(writeFileContents(filePath, data)); + cont(writeFileContents(filePath, data, offset)); } QDateTime IDevice::lastModified(const FilePath &filePath) const diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h index 3e144a9e502..58d0892fc65 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.h +++ b/src/plugins/projectexplorer/devicesupport/idevice.h @@ -243,7 +243,9 @@ public: virtual std::optional fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) const; - virtual bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const; + virtual bool writeFileContents(const Utils::FilePath &filePath, + const QByteArray &data, + qint64 offset) const; virtual QDateTime lastModified(const Utils::FilePath &filePath) const; virtual QFile::Permissions permissions(const Utils::FilePath &filePath) const; virtual bool setPermissions(const Utils::FilePath &filePath, QFile::Permissions) const; @@ -262,7 +264,8 @@ public: qint64 offset) const; virtual void asyncWriteFileContents(const Continuation &cont, const Utils::FilePath &filePath, - const QByteArray &data) const; + const QByteArray &data, + qint64 offset) const; virtual bool ensureReachable(const Utils::FilePath &other) const; diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index cf7fe54810a..2d2d8684d69 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -1318,10 +1318,17 @@ std::optional LinuxDevice::fileContents(const FilePath &filePath, return result.stdOut; } -bool LinuxDevice::writeFileContents(const FilePath &filePath, const QByteArray &data) const +bool LinuxDevice::writeFileContents(const FilePath &filePath, + const QByteArray &data, + qint64 offset) const { QTC_ASSERT(handlesFile(filePath), return {}); - return d->runInShellSuccess({"dd", {"of=" + filePath.path()}}, data); + CommandLine cmd({"dd", {"of=" + filePath.path()}}); + if (offset != 0) { + cmd.addArg("bs=1"); + cmd.addArg(QString("seek=%1").arg(offset)); + } + return d->runInShellSuccess(cmd, data); } static FilePaths dirsToCreate(const FilesToTransfer &files) diff --git a/src/plugins/remotelinux/linuxdevice.h b/src/plugins/remotelinux/linuxdevice.h index 0d4748cb308..1cecc12f2e7 100644 --- a/src/plugins/remotelinux/linuxdevice.h +++ b/src/plugins/remotelinux/linuxdevice.h @@ -58,7 +58,9 @@ public: std::optional fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) const override; - bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override; + bool writeFileContents(const Utils::FilePath &filePath, + const QByteArray &data, + qint64 offset) const override; QDateTime lastModified(const Utils::FilePath &filePath) const override; Utils::ProcessInterface *createProcessInterface() const override; ProjectExplorer::FileTransferInterface *createFileTransferInterface( diff --git a/tests/auto/utils/fsengine/tst_fsengine.cpp b/tests/auto/utils/fsengine/tst_fsengine.cpp index c487711561e..09cbe4ac0ec 100644 --- a/tests/auto/utils/fsengine/tst_fsengine.cpp +++ b/tests/auto/utils/fsengine/tst_fsengine.cpp @@ -134,8 +134,10 @@ void tst_fsengine::initTestCase() qint64 offset) { return FilePath::fromString(filePath.path()).asyncFileContents(cont, maxSize, offset); }; - deviceHooks.writeFileContents = [](const FilePath &filePath, const QByteArray &data) { - return FilePath::fromString(filePath.path()).writeFileContents(data); + deviceHooks.writeFileContents = [](const FilePath &filePath, + const QByteArray &data, + qint64 offset) { + return FilePath::fromString(filePath.path()).writeFileContents(data, offset); }; deviceHooks.lastModified = [](const FilePath &filePath) { return FilePath::fromString(filePath.path()).lastModified(); From a43619386b064196521cd8f38584e2c9bcc552cc Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 10 Oct 2022 11:15:12 +0200 Subject: [PATCH 13/42] Nim: Inline nimcodestylepreferenceswidget.ui Change-Id: I4590e6666bd37b428c443ef78731202100040a58 Reviewed-by: Alessandro Portale --- src/plugins/nim/CMakeLists.txt | 2 +- src/plugins/nim/nim.qbs | 2 +- .../nimcodestylepreferencesfactory.cpp | 4 - .../nimcodestylepreferenceswidget.cpp | 53 +++++++----- .../settings/nimcodestylepreferenceswidget.h | 11 +-- .../settings/nimcodestylepreferenceswidget.ui | 81 ------------------- .../nim/settings/nimcodestylesettingspage.cpp | 1 + 7 files changed, 39 insertions(+), 115 deletions(-) delete mode 100644 src/plugins/nim/settings/nimcodestylepreferenceswidget.ui diff --git a/src/plugins/nim/CMakeLists.txt b/src/plugins/nim/CMakeLists.txt index b658568b9c3..a7320e46184 100644 --- a/src/plugins/nim/CMakeLists.txt +++ b/src/plugins/nim/CMakeLists.txt @@ -25,7 +25,7 @@ add_qtc_plugin(Nim project/nimtoolchain.cpp project/nimtoolchain.h project/nimtoolchainfactory.cpp project/nimtoolchainfactory.h settings/nimcodestylepreferencesfactory.cpp settings/nimcodestylepreferencesfactory.h - settings/nimcodestylepreferenceswidget.cpp settings/nimcodestylepreferenceswidget.h settings/nimcodestylepreferenceswidget.ui + settings/nimcodestylepreferenceswidget.cpp settings/nimcodestylepreferenceswidget.h settings/nimcodestylesettingspage.cpp settings/nimcodestylesettingspage.h settings/nimsettings.cpp settings/nimsettings.h suggest/client.cpp suggest/client.h diff --git a/src/plugins/nim/nim.qbs b/src/plugins/nim/nim.qbs index 171b853c56a..42bc669518a 100644 --- a/src/plugins/nim/nim.qbs +++ b/src/plugins/nim/nim.qbs @@ -60,7 +60,7 @@ QtcPlugin { prefix: "settings/" files: [ "nimcodestylepreferencesfactory.h", "nimcodestylepreferencesfactory.cpp", - "nimcodestylepreferenceswidget.h", "nimcodestylepreferenceswidget.cpp", "nimcodestylepreferenceswidget.ui", + "nimcodestylepreferenceswidget.h", "nimcodestylepreferenceswidget.cpp", "nimcodestylesettingspage.h", "nimcodestylesettingspage.cpp", "nimsettings.h", "nimsettings.cpp", ] diff --git a/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp b/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp index 1930a25f42d..f17f4c7ad30 100644 --- a/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp +++ b/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp @@ -11,9 +11,6 @@ #include -#include -#include - using namespace TextEditor; namespace Nim { @@ -44,7 +41,6 @@ TextEditor::CodeStyleEditorWidget *NimCodeStylePreferencesFactory::createEditor( { Q_UNUSED(project) auto result = new NimCodeStylePreferencesWidget(preferences, parent); - result->layout()->setContentsMargins(0, 0, 0, 0); return result; } diff --git a/src/plugins/nim/settings/nimcodestylepreferenceswidget.cpp b/src/plugins/nim/settings/nimcodestylepreferenceswidget.cpp index 1817d0f01a6..fdce33cc9c6 100644 --- a/src/plugins/nim/settings/nimcodestylepreferenceswidget.cpp +++ b/src/plugins/nim/settings/nimcodestylepreferenceswidget.cpp @@ -2,20 +2,25 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "nimcodestylepreferenceswidget.h" -#include "ui_nimcodestylepreferenceswidget.h" #include "../nimconstants.h" #include "../editor/nimeditorfactory.h" #include + #include #include #include +#include #include +#include +#include +#include #include #include #include -#include + +#include using namespace TextEditor; @@ -24,11 +29,22 @@ namespace Nim { NimCodeStylePreferencesWidget::NimCodeStylePreferencesWidget(ICodeStylePreferences *preferences, QWidget *parent) : TextEditor::CodeStyleEditorWidget(parent) , m_preferences(preferences) - , m_ui(new Ui::NimCodeStylePreferencesWidget()) { - m_ui->setupUi(this); - m_ui->tabPreferencesWidget->setPreferences(preferences); - m_ui->previewTextEdit->setPlainText(Nim::Constants::C_NIMCODESTYLEPREVIEWSNIPPET); + auto tabPreferencesWidget = new SimpleCodeStylePreferencesWidget; + tabPreferencesWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + tabPreferencesWidget->setPreferences(preferences); + + m_previewTextEdit = new SnippetEditorWidget; + m_previewTextEdit->setPlainText(Nim::Constants::C_NIMCODESTYLEPREVIEWSNIPPET); + + using namespace Utils::Layouting; + Row { + Column { + tabPreferencesWidget, + st, + }, + m_previewTextEdit, + }.attachTo(this, WithoutMargins); decorateEditor(TextEditorSettings::fontSettings()); connect(TextEditorSettings::instance(), &TextEditorSettings::fontSettingsChanged, @@ -42,43 +58,38 @@ NimCodeStylePreferencesWidget::NimCodeStylePreferencesWidget(ICodeStylePreferenc updatePreview(); } -NimCodeStylePreferencesWidget::~NimCodeStylePreferencesWidget() -{ - delete m_ui; - m_ui = nullptr; -} +NimCodeStylePreferencesWidget::~NimCodeStylePreferencesWidget() = default; void NimCodeStylePreferencesWidget::decorateEditor(const FontSettings &fontSettings) { - m_ui->previewTextEdit->textDocument()->setFontSettings(fontSettings); - NimEditorFactory::decorateEditor(m_ui->previewTextEdit); + m_previewTextEdit->textDocument()->setFontSettings(fontSettings); + NimEditorFactory::decorateEditor(m_previewTextEdit); } void NimCodeStylePreferencesWidget::setVisualizeWhitespace(bool on) { - DisplaySettings displaySettings = m_ui->previewTextEdit->displaySettings(); + DisplaySettings displaySettings = m_previewTextEdit->displaySettings(); displaySettings.m_visualizeWhitespace = on; - m_ui->previewTextEdit->setDisplaySettings(displaySettings); + m_previewTextEdit->setDisplaySettings(displaySettings); } void NimCodeStylePreferencesWidget::updatePreview() { - QTextDocument *doc = m_ui->previewTextEdit->document(); + QTextDocument *doc = m_previewTextEdit->document(); const TabSettings &ts = m_preferences ? m_preferences->currentTabSettings() : TextEditorSettings::codeStyle()->tabSettings(); - m_ui->previewTextEdit->textDocument()->setTabSettings(ts); + m_previewTextEdit->textDocument()->setTabSettings(ts); QTextBlock block = doc->firstBlock(); - QTextCursor tc = m_ui->previewTextEdit->textCursor(); + QTextCursor tc = m_previewTextEdit->textCursor(); tc.beginEditBlock(); while (block.isValid()) { - m_ui->previewTextEdit->textDocument()->indenter()->indentBlock(block, QChar::Null, ts); + m_previewTextEdit->textDocument()->indenter()->indentBlock(block, QChar::Null, ts); block = block.next(); } tc.endEditBlock(); } -} // namespace Nim - +} // Nim diff --git a/src/plugins/nim/settings/nimcodestylepreferenceswidget.h b/src/plugins/nim/settings/nimcodestylepreferenceswidget.h index 34e401537fc..4a6f34a30f3 100644 --- a/src/plugins/nim/settings/nimcodestylepreferenceswidget.h +++ b/src/plugins/nim/settings/nimcodestylepreferenceswidget.h @@ -3,18 +3,15 @@ #pragma once -#include #include namespace TextEditor { -class ICodeStylePreferences; class FontSettings; -} +class SnippetEditorWidget; +} // TextEditor namespace Nim { -namespace Ui { class NimCodeStylePreferencesWidget; } - class NimCodeStylePreferencesWidget : public TextEditor::CodeStyleEditorWidget { Q_OBJECT @@ -29,7 +26,7 @@ private: void updatePreview(); TextEditor::ICodeStylePreferences *m_preferences; - Ui::NimCodeStylePreferencesWidget *m_ui; + TextEditor::SnippetEditorWidget *m_previewTextEdit; }; -} // namespace Nim +} // Nim diff --git a/src/plugins/nim/settings/nimcodestylepreferenceswidget.ui b/src/plugins/nim/settings/nimcodestylepreferenceswidget.ui deleted file mode 100644 index fc9f33e57aa..00000000000 --- a/src/plugins/nim/settings/nimcodestylepreferenceswidget.ui +++ /dev/null @@ -1,81 +0,0 @@ - - - Nim::NimCodeStylePreferencesWidget - - - - 0 - 0 - 138 - 112 - - - - - - - - - - - 0 - 0 - - - - - - - - import QtQuick 1.0 - -Rectangle { - width: 360 - height: 360 - Text { - anchors.centerIn: parent - text: "Hello World" - } - MouseArea { - anchors.fill: parent - onClicked: { - Qt.quit(); - } - } -} - - - - - - - - Qt::Vertical - - - - 20 - 267 - - - - - - - - - TextEditor::SimpleCodeStylePreferencesWidget - QWidget -
texteditor/simplecodestylepreferenceswidget.h
- 1 -
- - TextEditor::SnippetEditorWidget - QPlainTextEdit -
texteditor/snippets/snippeteditor.h
-
-
- - -
- diff --git a/src/plugins/nim/settings/nimcodestylesettingspage.cpp b/src/plugins/nim/settings/nimcodestylesettingspage.cpp index 9306b170b49..fe24473ec24 100644 --- a/src/plugins/nim/settings/nimcodestylesettingspage.cpp +++ b/src/plugins/nim/settings/nimcodestylesettingspage.cpp @@ -38,6 +38,7 @@ public: auto layout = new QVBoxLayout(this); layout->addWidget(editor); + layout->setContentsMargins(0, 0, 0, 0); } private: From c4957f9fdbdf6b751cbb407b0328ba8f837f595e Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 10 Oct 2022 14:36:17 +0200 Subject: [PATCH 14/42] BareMetal: Convert to Tr::tr Change-Id: I7ac423c13d95b33cad332d2ce9fafb4f658980bc Reviewed-by: Alessandro Portale Reviewed-by: --- share/qtcreator/translations/qtcreator_cs.ts | 58 +-- share/qtcreator/translations/qtcreator_da.ts | 114 ----- share/qtcreator/translations/qtcreator_de.ts | 266 +--------- share/qtcreator/translations/qtcreator_fr.ts | 58 +-- share/qtcreator/translations/qtcreator_hr.ts | 116 +---- share/qtcreator/translations/qtcreator_ja.ts | 479 +----------------- share/qtcreator/translations/qtcreator_pl.ts | 120 +---- share/qtcreator/translations/qtcreator_ru.ts | 308 +---------- share/qtcreator/translations/qtcreator_uk.ts | 249 +-------- .../baremetal/baremetaldebugsupport.cpp | 14 +- src/plugins/baremetal/baremetaldebugsupport.h | 16 +- src/plugins/baremetal/baremetaldevice.cpp | 16 +- src/plugins/baremetal/baremetaldevice.h | 8 +- .../baremetaldeviceconfigurationwidget.cpp | 13 +- .../baremetaldeviceconfigurationwidget.h | 10 +- .../baremetaldeviceconfigurationwizard.cpp | 16 +- .../baremetaldeviceconfigurationwizard.h | 10 +- ...aremetaldeviceconfigurationwizardpages.cpp | 17 +- .../baremetaldeviceconfigurationwizardpages.h | 10 +- .../baremetalgdbcommandsdeploystep.cpp | 4 +- src/plugins/baremetal/baremetalplugin.cpp | 13 +- src/plugins/baremetal/baremetalplugin.h | 8 +- .../baremetal/baremetalrunconfiguration.cpp | 28 +- .../baremetal/baremetalrunconfiguration.h | 6 +- .../baremetal/debugserverproviderchooser.cpp | 11 +- .../baremetal/debugserverproviderchooser.h | 8 +- .../baremetal/debugserverprovidermanager.cpp | 8 +- .../baremetal/debugserverprovidermanager.h | 6 +- .../debugserverproviderssettingspage.cpp | 49 +- .../debugserverproviderssettingspage.h | 6 +- .../gdb/eblinkgdbserverprovider.cpp | 51 +- .../gdb/eblinkgdbserverprovider.h | 8 +- .../debugservers/gdb/gdbserverprovider.cpp | 39 +- .../debugservers/gdb/gdbserverprovider.h | 12 +- .../gdb/genericgdbserverprovider.cpp | 21 +- .../gdb/genericgdbserverprovider.h | 8 +- .../gdb/jlinkgdbserverprovider.cpp | 62 ++- .../debugservers/gdb/jlinkgdbserverprovider.h | 11 +- .../gdb/openocdgdbserverprovider.cpp | 25 +- .../gdb/openocdgdbserverprovider.h | 11 +- .../gdb/stlinkutilgdbserverprovider.cpp | 43 +- .../gdb/stlinkutilgdbserverprovider.h | 11 +- .../uvsc/jlinkuvscserverprovider.cpp | 48 +- .../uvsc/jlinkuvscserverprovider.h | 8 +- .../uvsc/simulatoruvscserverprovider.cpp | 18 +- .../uvsc/simulatoruvscserverprovider.h | 8 +- .../uvsc/stlinkuvscserverprovider.cpp | 60 ++- .../uvsc/stlinkuvscserverprovider.h | 8 +- .../baremetal/debugservers/uvsc/uvproject.cpp | 8 +- .../baremetal/debugservers/uvsc/uvproject.h | 9 +- .../debugservers/uvsc/uvprojectwriter.cpp | 8 +- .../debugservers/uvsc/uvprojectwriter.h | 8 +- .../debugservers/uvsc/uvscserverprovider.cpp | 31 +- .../debugservers/uvsc/uvscserverprovider.h | 2 - .../debugservers/uvsc/uvtargetdevicemodel.cpp | 12 +- .../debugservers/uvsc/uvtargetdevicemodel.h | 8 +- .../uvsc/uvtargetdeviceselection.cpp | 28 +- .../uvsc/uvtargetdeviceselection.h | 8 +- .../uvsc/uvtargetdeviceviewer.cpp | 37 +- .../debugservers/uvsc/uvtargetdeviceviewer.h | 8 +- .../debugservers/uvsc/uvtargetdrivermodel.cpp | 12 +- .../debugservers/uvsc/uvtargetdrivermodel.h | 8 +- .../uvsc/uvtargetdriverselection.cpp | 14 +- .../uvsc/uvtargetdriverselection.h | 8 +- .../uvsc/uvtargetdriverviewer.cpp | 23 +- .../debugservers/uvsc/uvtargetdriverviewer.h | 8 +- .../debugservers/uvsc/xmlnodevisitor.h | 8 +- .../debugservers/uvsc/xmlproject.cpp | 8 +- .../baremetal/debugservers/uvsc/xmlproject.h | 8 +- .../debugservers/uvsc/xmlprojectwriter.cpp | 8 +- .../debugservers/uvsc/xmlprojectwriter.h | 8 +- .../debugservers/uvsc/xmlproperty.cpp | 8 +- .../baremetal/debugservers/uvsc/xmlproperty.h | 8 +- .../debugservers/uvsc/xmlpropertygroup.cpp | 8 +- src/plugins/baremetal/iarewparser.cpp | 6 +- src/plugins/baremetal/iarewparser.h | 10 +- src/plugins/baremetal/iarewtoolchain.cpp | 25 +- src/plugins/baremetal/iarewtoolchain.h | 8 +- .../baremetal/idebugserverprovider.cpp | 25 +- src/plugins/baremetal/keilparser.cpp | 12 +- src/plugins/baremetal/keilparser.h | 10 +- src/plugins/baremetal/keiltoolchain.cpp | 26 +- src/plugins/baremetal/keiltoolchain.h | 15 +- src/plugins/baremetal/sdccparser.cpp | 12 +- src/plugins/baremetal/sdccparser.h | 10 +- src/plugins/baremetal/sdcctoolchain.cpp | 30 +- src/plugins/baremetal/sdcctoolchain.h | 15 +- 87 files changed, 505 insertions(+), 2500 deletions(-) diff --git a/share/qtcreator/translations/qtcreator_cs.ts b/share/qtcreator/translations/qtcreator_cs.ts index 2af0850b712..a3d4cdd06d9 100644 --- a/share/qtcreator/translations/qtcreator_cs.ts +++ b/share/qtcreator/translations/qtcreator_cs.ts @@ -56809,7 +56809,7 @@ Tento průvodce vás provede základními kroky, které jsou nutné pro nasazen
- BareMetal::BareMetalDeviceConfigurationWidget + BareMetal Form Formulář @@ -56826,13 +56826,6 @@ Tento průvodce vás provede základními kroky, které jsou nutné pro nasazen GDB commands: Příkazy GDB: - - - BareMetal::Internal::BareMetalDeviceConfigurationWizardSetupPage - - Form - Formulář - Name: Název: @@ -56841,18 +56834,6 @@ Tento průvodce vás provede základními kroky, které jsou nutné pro nasazen localhost localhost - - GDB port: - Port GDB: - - - GDB host: - Hostitel GDB: - - - GDB commands: - Příkazy GDB: - load monitor reset @@ -57779,53 +57760,27 @@ Soubory ve zdrojovém adresáři balíčku pro Android jsou zkopírovány do adr - BareMetal::Internal::BareMetalDevice + BareMetal Bare Metal Bare Metal - - - BareMetal::BareMetalDeviceConfigurationFactory Bare Metal Device Zařízení Bare Metal - - - BareMetal::BareMetalDeviceConfigurationWizard New Bare Metal Device Configuration Setup Zřízení nového nastavení zařízení Bare Metal - - - BareMetal::BareMetalDeviceConfigurationWizardSetupPage Set up GDB Server or Hardware Debugger Nastavit server GDB nebo hardwarový ladicí program - - Bare Metal Device - Zařízení Bare Metal - - - - BareMetal::Internal::BareMetalGdbCommandsDeployStepWidget - - GDB commands: - Příkazy GDB: - - - - BareMetal::BareMetalGdbCommandsDeployStep GDB commands Příkazy GDB - - - BareMetal::BareMetalRunConfiguration %1 (via GDB server or hardware debugger) %1 (pomocí serveru GDB nebo hardwarového ladicího programu) @@ -57835,16 +57790,10 @@ Soubory ve zdrojovém adresáři balíčku pro Android jsou zkopírovány do adr Bare Metal run configuration default run name Spustit na serveru GDB nebo hardwarovém ladicím programu - - - BareMetal::Internal::BareMetalRunConfigurationFactory %1 (on GDB server or hardware debugger) %1 (na serveru GDB nebo hardwarovém ladicím programu) - - - BareMetal::BareMetalRunConfigurationWidget Executable: Spustitelný soubor: @@ -57865,9 +57814,6 @@ Soubory ve zdrojovém adresáři balíčku pro Android jsou zkopírovány do adr Unknown Neznámý - - - BareMetal::Internal::BareMetalRunControlFactory Cannot debug: Kit has no device. Nelze ladit: Kit nemá žádné zařízení. diff --git a/share/qtcreator/translations/qtcreator_da.ts b/share/qtcreator/translations/qtcreator_da.ts index 34b1c9bd369..cf54251fc42 100644 --- a/share/qtcreator/translations/qtcreator_da.ts +++ b/share/qtcreator/translations/qtcreator_da.ts @@ -2340,16 +2340,10 @@ Advarsel: dette er en eksperimentel facilitet og kan lede til at test-eksekverba Enter GDB commands to reset the hardware. The MCU should be halted after these commands. Indtast GDB-kommandoer for at nulstille hardwaren. MCU'en bør standses efter disse kommandoer. - - - BareMetal::GdbServerProvider Clone of %1 Klon af %1 - - - BareMetal::Internal::BareMetalCustomRunConfiguration Unknown Ukendt @@ -2366,9 +2360,6 @@ Advarsel: dette er en eksperimentel facilitet og kan lede til at test-eksekverba Custom Executable Brugerdefineret eksekverbar - - - BareMetal::Internal::BareMetalDebugSupport Cannot debug: Kit has no device. Kan ikke fejlrette: kit har ingen enhed. @@ -2385,37 +2376,22 @@ Advarsel: dette er en eksperimentel facilitet og kan lede til at test-eksekverba Cannot debug: Could not find executable for "%1". Kan ikke fejlrette: kunne ikke finde eksekverbar for "%1". - - - BareMetal::Internal::BareMetalDevice Bare Metal Bare Metal - - - BareMetal::Internal::BareMetalDeviceConfigurationFactory Bare Metal Device Bare Metal-enhed - - - BareMetal::Internal::BareMetalDeviceConfigurationWidget GDB server provider: GDB-serverudbyder: - - - BareMetal::Internal::BareMetalDeviceConfigurationWizard New Bare Metal Device Configuration Setup Ny Bare Metal-enhed konfigurationsopsætning - - - BareMetal::Internal::BareMetalDeviceConfigurationWizardSetupPage Set up GDB Server or Hardware Debugger Opsæt GDB-server eller hardware-fejlretter @@ -2424,38 +2400,14 @@ Advarsel: dette er en eksperimentel facilitet og kan lede til at test-eksekverba Name: Navn: - - GDB server provider: - GDB-serverudbyder: - - - Bare Metal Device - Bare Metal-enhed - - - - BareMetal::Internal::BareMetalGdbCommandsDeployStep GDB commands GDB-kommandoer - - - BareMetal::Internal::BareMetalGdbCommandsDeployStepWidget GDB commands: GDB-kommandoer: - - - BareMetal::Internal::BareMetalRunConfiguration - - Unknown - Ukendt - - - - BareMetal::Internal::DefaultGdbServerProviderConfigWidget Host: Vært: @@ -2468,16 +2420,10 @@ Advarsel: dette er en eksperimentel facilitet og kan lede til at test-eksekverba Reset commands: Nulstil-kommandoer: - - - BareMetal::Internal::DefaultGdbServerProviderFactory Default Standard - - - BareMetal::Internal::GdbServerProviderChooser Manage... Håndter... @@ -2486,17 +2432,10 @@ Advarsel: dette er en eksperimentel facilitet og kan lede til at test-eksekverba None Ingen - - - BareMetal::Internal::GdbServerProviderConfigWidget Enter the name of the GDB server provider. Indtast navnet på GDB-serverudbyderen. - - Name: - Navn: - Choose the desired startup mode of the GDB server provider. Vælg den ønskede opstart-tilstand af GDB-serverudbyderen. @@ -2517,9 +2456,6 @@ Advarsel: dette er en eksperimentel facilitet og kan lede til at test-eksekverba Startup in Pipe Mode Opstart i pipe-tilstand - - - BareMetal::Internal::GdbServerProviderModel Name Navn @@ -2536,9 +2472,6 @@ Advarsel: dette er en eksperimentel facilitet og kan lede til at test-eksekverba The following providers were already configured:<br>&nbsp;%1<br>They were not configured again. Følgende udbydere var allerede konfigureret:<br>&nbsp;%1<br>De blev ikke konfigureret igen. - - - BareMetal::Internal::GdbServerProvidersSettingsPage Add Tilføj @@ -2555,13 +2488,6 @@ Advarsel: dette er en eksperimentel facilitet og kan lede til at test-eksekverba GDB Server Providers GDB-serverudbydere - - Bare Metal - Bare Metal - - - - BareMetal::Internal::HostWidget Enter TCP/IP hostname of the GDB server provider, like "localhost" or "192.0.2.1". Indtast TCP/IP-værtsnavn af GDB-serverudbyderen, såsom "localhost" eller "192.0.2.1". @@ -2570,13 +2496,6 @@ Advarsel: dette er en eksperimentel facilitet og kan lede til at test-eksekverba Enter TCP/IP port which will be listened by the GDB server provider. Indtast TCP/IP-port som skal lyttes på af GDB-serverudbyderen. - - - BareMetal::Internal::OpenOcdGdbServerProviderConfigWidget - - Host: - Vært: - Executable file: Eksekverbar fil: @@ -2593,32 +2512,10 @@ Advarsel: dette er en eksperimentel facilitet og kan lede til at test-eksekverba Additional arguments: Yderligere argumenter: - - Init commands: - Init-kommandoer: - - - Reset commands: - Nulstil-kommandoer: - - - - BareMetal::Internal::OpenOcdGdbServerProviderFactory OpenOCD OpenOCD - - - BareMetal::Internal::StLinkUtilGdbServerProviderConfigWidget - - Host: - Vært: - - - Executable file: - Eksekverbar fil: - Specify the verbosity level (0..99). Angiv detaljeniveauet (0..99). @@ -2651,14 +2548,6 @@ Advarsel: dette er en eksperimentel facilitet og kan lede til at test-eksekverba Version: Version: - - Init commands: - Init-kommandoer: - - - Reset commands: - Nulstil-kommandoer: - ST-LINK/V1 ST-LINK/V1 @@ -2667,9 +2556,6 @@ Advarsel: dette er en eksperimentel facilitet og kan lede til at test-eksekverba ST-LINK/V2 ST-LINK/V2 - - - BareMetal::Internal::StLinkUtilGdbServerProviderFactory ST-LINK Utility ST-LINK-redskab diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index 7cdbf1fbbab..675304a58f2 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -23474,7 +23474,7 @@ Bitte schließen Sie alle laufenden Instanzen Ihrer Anwendung vor dem Erstellen. - BareMetal::Internal::BareMetalDeviceConfigurationWizardSetupPage + BareMetal Set up Debug Server or Hardware Debugger Debug-Server oder Hardware-Debugger einrichten @@ -23885,7 +23885,7 @@ Möchten Sie das vorhandene Paket deinstallieren? - BareMetal::Internal::BareMetalDevice + BareMetal Bare Metal Bare Metal @@ -23894,9 +23894,6 @@ Möchten Sie das vorhandene Paket deinstallieren? Bare Metal Device Bare-Metal-Gerät - - - BareMetal::Internal::BareMetalGdbCommandsDeployStepWidget GDB commands: GDB-Kommandos: @@ -26963,30 +26960,14 @@ Bitte installieren Sie ein Android-SDK der API-Version %1 oder neuer.Enter GDB commands to reset the hardware. The MCU should be halted after these commands. Geben Sie GDB-Kommandos ein, um die Hardware zurückzusetzen. Die MCU sollte danach angehalten sein. - - - BareMetal::Internal::BareMetalDeviceConfigurationWidget - - Debug server provider: - Debug-Server-Provider: - - - - BareMetal::Internal::BareMetalDeviceConfigurationWizard New Bare Metal Device Configuration Setup Einrichtung der Konfiguration für neues Bare-Metal-Gerät - - - BareMetal::Internal::BareMetalGdbCommandsDeployStep GDB commands GDB-Kommandos - - - BareMetal::Internal::BareMetalRunConfiguration Unknown Unbekannt @@ -31414,11 +31395,7 @@ Senden selbst auch Zeit benötigt. - BareMetal::Internal::BareMetalCustomRunConfiguration - - Unknown - Unbekannt - + BareMetal The remote executable must be set in order to run a custom remote run configuration. Die entfernte ausführbare Datei muss eingestellt sein um eine benutzerdefinierte enternte Ausführungskonfiguration zu verwenden. @@ -31427,9 +31404,6 @@ Senden selbst auch Zeit benötigt. Custom Executable Benutzerdefinierte ausführbare Datei - - - BareMetal::Internal::BareMetalDebugSupport Cannot debug: Kit has no device. Kann nicht debuggen: Das Kit hat kein Gerät. @@ -31458,9 +31432,6 @@ Senden selbst auch Zeit benötigt. Unable to create an uVision project options template. Es kann keine uVision-Projekteinstellungsvorlage erzeugt werden. - - - BareMetal::Internal::GdbServerProviderConfigWidget Choose the desired startup mode of the GDB server provider. Wählen Sie den gewünschten Startmodus des GDB-Server-Providers. @@ -31473,10 +31444,6 @@ Senden selbst auch Zeit benötigt. Peripheral description files (*.svd) Peripherie-Beschreibungsdatei (*.svd) - - Select Peripheral Description File - Wählen Sie eine Peripherie-Beschreibungsdateien - Peripheral description file: Peripherie-Beschreibungsdatei: @@ -31489,9 +31456,6 @@ Senden selbst auch Zeit benötigt. Startup in Pipe Mode Im Pipe-Modus starten - - - BareMetal::Internal::HostWidget Enter TCP/IP hostname of the debug server, like "localhost" or "192.0.2.1". Geben Sie den TCP/IP-Hostnamen des Debug-Servers ein, etwa "localhost" oder "192.0.2.1". @@ -31500,9 +31464,6 @@ Senden selbst auch Zeit benötigt. Enter TCP/IP port which will be listened by the debug server. Geben Sie den TCP/IP-Port ein, an dem der Debug-Server Verbindungen annehmen wird. - - - BareMetal::Internal::OpenOcdGdbServerProviderConfigWidget Host: Host: @@ -31531,17 +31492,6 @@ Senden selbst auch Zeit benötigt. Reset commands: Kommandos zum Zurücksetzen: - - - BareMetal::Internal::StLinkUtilGdbServerProviderConfigWidget - - Host: - Host: - - - Executable file: - Ausführbare Datei: - Specify the verbosity level (0..99). Geben Sie den Detailgrad an (0..99). @@ -31574,14 +31524,6 @@ Senden selbst auch Zeit benötigt. Version: Version: - - Init commands: - Kommandos zum Einrichten: - - - Reset commands: - Kommandos zum Zurücksetzen: - ST-LINK/V1 ST-LINK/V1 @@ -44363,7 +44305,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e - BareMetal::Internal::DebugServerProviderChooser + BareMetal Manage... Verwalten... @@ -44372,9 +44314,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e None Keine - - - BareMetal::Internal::DebugServerProviderModel Not recognized Nicht erkannt @@ -44399,9 +44338,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e The following providers were already configured:<br>&nbsp;%1<br>They were not configured again. Die folgenden Provider wurden bereits konfiguriert:<br>&nbsp;%1<br>Sie wurden nicht noch einmal konfiguriert. - - - BareMetal::Internal::DebugServerProvidersSettingsPage Add Hinzufügen @@ -44422,13 +44358,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Clone of %1 Kopie von %1 - - Bare Metal - Bare Metal - - - - BareMetal::Internal::GdbServerProvider EBlink EBlink @@ -44445,25 +44374,10 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e ST-LINK Utility ST-LINK-Werkzeug - - - BareMetal::Internal::EBlinkGdbServerProviderConfigWidget - - Host: - Host: - - - Executable file: - Ausführbare Datei: - Script file: Skriptdatei: - - Verbosity level: - Detailgrad: - Type: Typ: @@ -44472,14 +44386,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Speed: Geschwindigkeit: - - Init commands: - Kommandos zum Einrichten: - - - Reset commands: - Kommandos zum Zurücksetzen: - SWD SWD @@ -44488,13 +44394,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e JTAG JTAG - - - BareMetal::Internal::JLinkGdbServerProviderConfigWidget - - Host: - Host: - JLink GDB Server (JLinkGDBServerCL.exe) JLink GDB-Server (JLinkGDBServerCL.exe) @@ -44503,10 +44402,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e JLink GDB Server (JLinkGDBServer) JLink GDB-Server (JLinkGDBServer) - - Executable file: - Ausführbare Datei: - Default Vorgabe @@ -44527,21 +44422,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Device: Geräte: - - Additional arguments: - Zusätzliche Argumente: - - - Init commands: - Kommandos zum Einrichten: - - - Reset commands: - Kommandos zum Zurücksetzen: - - - - BareMetal::Internal::UvscServerProvider uVision Simulator uVision Simulator @@ -44550,25 +44430,10 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e uVision St-Link uVision St-Link - - - BareMetal::Internal::StLinkUvscAdapterOptionsWidget Port: Port: - - Speed: - Geschwindigkeit: - - - JTAG - JTAG - - - SWD - SWD - 9MHz 9MHz @@ -44641,20 +44506,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e 5kHz 5kHz - - - BareMetal::Internal::UvscServerProviderConfigWidget - - Host: - Host: - - - - BareMetal::Internal::Uv::DeviceSelectionModel - - Name - Name - Version Version @@ -44663,9 +44514,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Vendor Anbieter - - - BareMetal::Internal::Uv::DeviceSelectionMemoryModel ID ID @@ -44678,23 +44526,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Size Größe - - - BareMetal::Internal::Uv::DeviceSelectionAlgorithmModel - - Name - Name - - - - BareMetal::Internal::Uv::DeviceSelectorToolPanel - - Manage... - Verwalten... - - - - BareMetal::Internal::Uv::DeviceSelectorDetailsPanel Vendor: Anbieter: @@ -44711,42 +44542,14 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Memory: Speicher: - - Peripheral description files (*.svd) - Peripherie-Beschreibungsdatei (*.svd) - Select Peripheral Description File Wählen Sie eine Peripherie-Beschreibungsdatei - - Peripheral description file: - Peripherie-Beschreibungsdatei: - - - - BareMetal::Internal::Uv::DriverSelectionModel Path Pfad - - - BareMetal::Internal::Uv::DriverSelectionCpuDllModel - - Name - Name - - - - BareMetal::Internal::Uv::DriverSelectorToolPanel - - Manage... - Verwalten... - - - - BareMetal::Internal::IarToolChainConfigWidget &Compiler path: &Compiler-Pfad: @@ -44759,20 +44562,10 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e &ABI: &ABI: - - - BareMetal::Internal::IDebugServerProviderConfigWidget Enter the name of the debugger server provider. Geben Sie den Namen des Debug-Server-Providers ein. - - Name: - Name: - - - - SdccToolChain SDCC %1 (%2, %3) SDCC %1 (%2, %3) @@ -44782,17 +44575,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e SDCC - - BareMetal::Internal::SdccToolChainConfigWidget - - &Compiler path: - &Compiler-Pfad: - - - &ABI: - &ABI: - - Beautifier::Internal::ArtisticStyle @@ -48174,23 +47956,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e - BareMetal::Internal::JLinkUvscAdapterOptionsWidget - - Port: - Port: - - - Speed: - Geschwindigkeit: - - - JTAG - JTAG - - - SWD - SWD - + BareMetal 50MHz 50MHz @@ -48235,13 +48001,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e 200kHz 200kHz - - 100kHz - 100kHz - - - - KeilToolChain KEIL %1 (%2, %3) KEIL %1 (%2, %3) @@ -48251,21 +48010,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e KEIL - - BareMetal::Internal::KeilToolChainConfigWidget - - &Compiler path: - &Compiler-Pfad: - - - Platform codegen flags: - Plattformspezifische Optionen für codegen: - - - &ABI: - &ABI: - - Beautifier::Internal diff --git a/share/qtcreator/translations/qtcreator_fr.ts b/share/qtcreator/translations/qtcreator_fr.ts index b0f6629fdf9..8b00b472e09 100644 --- a/share/qtcreator/translations/qtcreator_fr.ts +++ b/share/qtcreator/translations/qtcreator_fr.ts @@ -54923,7 +54923,7 @@ Cet assistant vous guidera à travers les étapes essentielles pour déployez un - BareMetal::BareMetalDeviceConfigurationWidget + BareMetal Form Formulaire @@ -54940,13 +54940,6 @@ Cet assistant vous guidera à travers les étapes essentielles pour déployez un GDB commands: Commandes GDB : - - - BareMetal::Internal::BareMetalDeviceConfigurationWizardSetupPage - - Form - Formulaire - Name: Nom : @@ -54955,18 +54948,6 @@ Cet assistant vous guidera à travers les étapes essentielles pour déployez un localhost localhost - - GDB port: - Port GDB : - - - GDB host: - Hôte GDB : - - - GDB commands: - Commandes GDB : - load monitor reset @@ -55834,53 +55815,27 @@ réinitialisation du moniteur - BareMetal::Internal::BareMetalDevice + BareMetal Bare Metal Bare Metal - - - BareMetal::BareMetalDeviceConfigurationFactory Bare Metal Device Périphérique Bare Metal - - - BareMetal::BareMetalDeviceConfigurationWizard New Bare Metal Device Configuration Setup Nouveau paramètres de configuration du périphérique Bare Metal - - - BareMetal::BareMetalDeviceConfigurationWizardSetupPage Set up GDB Server or Hardware Debugger Définir un serveur GDB ou un débogueur hardware - - Bare Metal Device - Périphérique Bare Metal - - - - BareMetal::Internal::BareMetalGdbCommandsDeployStepWidget - - GDB commands: - Commandes GDB : - - - - BareMetal::BareMetalGdbCommandsDeployStep GDB commands Commandes GDB - - - BareMetal::BareMetalRunConfiguration %1 (via GDB server or hardware debugger) %1 (via le serveur GDB ou le débogueur hardware) @@ -55890,16 +55845,10 @@ réinitialisation du moniteur Bare Metal run configuration default run name Exécuter sur un serveur GDB ou un débogueur hardware - - - BareMetal::Internal::BareMetalRunConfigurationFactory %1 (on GDB server or hardware debugger) %1 (via le serveur GDB ou le débogueur hardware) - - - BareMetal::BareMetalRunConfigurationWidget Executable: Exécutable : @@ -55920,9 +55869,6 @@ réinitialisation du moniteur Unknown Inconnue - - - BareMetal::Internal::BareMetalRunControlFactory Cannot debug: Kit has no device. Impossible de déboguer : le kit n'a pas de périphérique. diff --git a/share/qtcreator/translations/qtcreator_hr.ts b/share/qtcreator/translations/qtcreator_hr.ts index 6097f03ad6f..deff7f29d7d 100644 --- a/share/qtcreator/translations/qtcreator_hr.ts +++ b/share/qtcreator/translations/qtcreator_hr.ts @@ -15273,7 +15273,7 @@ Check the test environment. - BareMetal::Internal::BareMetalCustomRunConfiguration + BareMetal Unknown Nepoznato @@ -15286,9 +15286,6 @@ Check the test environment. The remote executable must be set in order to run a custom remote run configuration. - - - BareMetal::Internal::BareMetalDebugSupport Cannot debug: Kit has no device. @@ -15305,37 +15302,22 @@ Check the test environment. Cannot debug: Could not find executable for "%1". - - - BareMetal::Internal::BareMetalDevice Bare Metal - - - BareMetal::Internal::BareMetalDeviceConfigurationFactory Bare Metal Device - - - BareMetal::Internal::BareMetalDeviceConfigurationWidget GDB server provider: - - - BareMetal::Internal::BareMetalDeviceConfigurationWizard New Bare Metal Device Configuration Setup - - - BareMetal::Internal::BareMetalDeviceConfigurationWizardSetupPage Set up GDB Server or Hardware Debugger @@ -15344,45 +15326,18 @@ Check the test environment. Name: Naziv: - - GDB server provider: - - - - Bare Metal Device - - - - - BareMetal::Internal::BareMetalGdbCommandsDeployStepWidget GDB commands: - - - BareMetal::Internal::BareMetalGdbCommandsDeployStep GDB commands - - - BareMetal::Internal::BareMetalRunConfiguration - - Unknown - Nepoznato - - - - BareMetal::Internal::DefaultGdbServerProviderFactory Default Standardno - - - BareMetal::Internal::DefaultGdbServerProviderConfigWidget Host: @@ -15395,24 +15350,14 @@ Check the test environment. Reset commands: - - - BareMetal::GdbServerProvider Clone of %1 Klon od %1 - - - BareMetal::Internal::GdbServerProviderConfigWidget Enter the name of the GDB server provider. - - Name: - Naziv: - Choose the desired startup mode of the GDB server provider. @@ -15433,9 +15378,6 @@ Check the test environment. Startup in Pipe Mode - - - BareMetal Enter GDB commands to reset the board and to write the nonvolatile memory. @@ -15444,9 +15386,6 @@ Check the test environment. Enter GDB commands to reset the hardware. The MCU should be halted after these commands. - - - BareMetal::Internal::HostWidget Enter TCP/IP hostname of the GDB server provider, like "localhost" or "192.0.2.1". @@ -15455,9 +15394,6 @@ Check the test environment. Enter TCP/IP port which will be listened by the GDB server provider. - - - BareMetal::Internal::GdbServerProviderChooser Manage... @@ -15466,9 +15402,6 @@ Check the test environment. None Bez - - - BareMetal::Internal::GdbServerProviderModel Name Naziv @@ -15485,9 +15418,6 @@ Check the test environment. The following providers were already configured:<br>&nbsp;%1<br>They were not configured again. - - - BareMetal::Internal::GdbServerProvidersSettingsPage Add Dodaj @@ -15504,24 +15434,10 @@ Check the test environment. GDB Server Providers - - Bare Metal - - - - - BareMetal::Internal::OpenOcdGdbServerProviderFactory OpenOCD - - - BareMetal::Internal::OpenOcdGdbServerProviderConfigWidget - - Host: - - Executable file: @@ -15538,32 +15454,10 @@ Check the test environment. Additional arguments: Dodatni argumenti: - - Init commands: - - - - Reset commands: - - - - - BareMetal::Internal::StLinkUtilGdbServerProviderFactory ST-LINK Utility - - - BareMetal::Internal::StLinkUtilGdbServerProviderConfigWidget - - Host: - - - - Executable file: - - Specify the verbosity level (0..99). @@ -15596,14 +15490,6 @@ Check the test environment. Version: Verzija: - - Init commands: - - - - Reset commands: - - ST-LINK/V1 diff --git a/share/qtcreator/translations/qtcreator_ja.ts b/share/qtcreator/translations/qtcreator_ja.ts index a91ab237a68..d6b1ea9665f 100644 --- a/share/qtcreator/translations/qtcreator_ja.ts +++ b/share/qtcreator/translations/qtcreator_ja.ts @@ -858,7 +858,7 @@ - BareMetal::Internal::BareMetalDeviceConfigurationWizardSetupPage + BareMetal Set up Debug Server or Hardware Debugger デバッグサーバーまたはハードウェアデバッガをセットアップ @@ -867,10 +867,6 @@ Name: 名前: - - Debug server provider: - デバッグサーバーを選択: - GDB server provider: GDB サーバープロバイダ: @@ -12181,40 +12177,19 @@ in the system's browser for manual download. - BareMetal::Internal::BareMetalDevice + BareMetal Bare Metal ベアメタル - - Bare Metal Device - ベアメタルデバイス - - - - BareMetal::Internal::BareMetalGdbCommandsDeployStepWidget GDB commands: GDB コマンド: - - - BareMetal::Internal::BareMetalRunConfigurationFactory %1 (on GDB server or hardware debugger) %1 (GDB サーバーあるいはハードウェアデバッガ経由) - - - BareMetal::Internal::BareMetalRunControlFactory - - Cannot debug: Local executable is not set. - デバッグエラー: ローカル実行ファイルが設定されていません。 - - - Cannot debug: Could not find executable for "%1". - デバッグエラー: "%1" に実行ファイルが見つかりませんでした。 - Cannot debug: Kit has no device. デバッグエラー: キットにデバイスがありません。 @@ -34900,28 +34875,15 @@ API バージョンが %1 以上の SDK をインストールしてください - BareMetal::Internal::BareMetalDeviceConfigurationFactory - - Bare Metal Device - ベアメタルデバイス - - - - BareMetal::Internal::BareMetalDeviceConfigurationWizard + BareMetal New Bare Metal Device Configuration Setup 新しいベアメタルデバイスの設定 - - - BareMetal::Internal::BareMetalGdbCommandsDeployStep GDB commands GDB コマンド - - - BareMetal::Internal::BareMetalRunConfiguration %1 (via GDB server or hardware debugger) %1 (GDB サーバーあるいはハードウェアデバッガ経由) @@ -34935,9 +34897,6 @@ API バージョンが %1 以上の SDK をインストールしてください Unknown 不明 - - - BareMetal::Internal::BareMetalRunConfigurationWidget Executable: 実行ファイル: @@ -34950,10 +34909,6 @@ API バージョンが %1 以上の SDK をインストールしてください Working directory: 作業ディレクトリ: - - Unknown - 不明 - Core::BaseFileWizardFactory @@ -37774,10 +37729,6 @@ Only desktop kits are supported. Make sure the currently active kit is a desktop BareMetal - - Bare Metal - ベアメタル - Enter GDB commands to reset the board and to write the nonvolatile memory. ボードのリセットと不揮発メモリに書き込むための GDB コマンドを入力してください。 @@ -37786,24 +37737,10 @@ Only desktop kits are supported. Make sure the currently active kit is a desktop Enter GDB commands to reset the hardware. The MCU should be halted after these commands. ハードウェアリセットコマンドを入力してください。実行後に MCU が停止するコマンドを入力してください。 - - - BareMetal::Internal::BareMetalCustomRunConfigWidget - - Executable: - 実行ファイル: - Work directory: 作業ディレクトリ: - - - BareMetal::Internal::BareMetalCustomRunConfiguration - - Unknown - 不明 - Custom Executable カスタム実行ファイル @@ -37816,9 +37753,6 @@ Only desktop kits are supported. Make sure the currently active kit is a desktop Custom Executable (on GDB server or hardware debugger) カスタム実行ファイル (GDB サーバーあるいはハードウェアデバッガ経由) - - - BareMetal::Internal::BareMetalDebugSupport Debugging failed. デバッグに失敗しました。 @@ -37831,35 +37765,18 @@ Only desktop kits are supported. Make sure the currently active kit is a desktop Starting GDB server... GDB サーバー起動中... - - Cannot debug: Kit has no device. - デバッグエラー: キットにデバイスがありません。 - No debug server provider found for %1 デバッグ・サーバー・プロバイダが見つかりませんでした。%1 - - - BareMetal::Internal::BareMetalDeviceConfigurationWidget - - GDB server provider: - GDB サーバープロバイダ: - Debug server provider: サーバー・プロバイダーをデバッグする: - - - BareMetal::Internal::DefaultGdbServerProviderFactory Default 既定 - - - BareMetal::Internal::DefaultGdbServerProviderConfigWidget Host: ホスト: @@ -37872,24 +37789,14 @@ Only desktop kits are supported. Make sure the currently active kit is a desktop Reset commands: リセットコマンド: - - - BareMetal::GdbServerProvider Clone of %1 %1 を複製 - - - BareMetal::Internal::GdbServerProviderConfigWidget Enter the name of the GDB server provider. GDB サーバープロバイダの名前を入力してください。 - - Name: - 名前: - Choose the desired startup mode of the GDB server provider. GDB サーバープロバイダーに適切な起動モードを選択してください。 @@ -37922,9 +37829,6 @@ Only desktop kits are supported. Make sure the currently active kit is a desktop Startup in Pipe Mode パイプモードで起動 - - - BareMetal::Internal::HostWidget Enter TCP/IP hostname of the GDB server provider, like "localhost" or "192.0.2.1". GDB サーバープロバイダの TCP/IP ホスト名を入力してください。例: "localhost" や "192.0.2.1". @@ -37941,28 +37845,14 @@ Only desktop kits are supported. Make sure the currently active kit is a desktop Enter TCP/IP port which will be listened by the debug server. デバッグ サーバーが待ち受けに使用している TCP/IP ポート番号を入力してください。 - - - BareMetal::Internal::GdbServerProviderChooser Manage... 管理... - - None - なし - - - - BareMetal::Internal::GdbServerProviderModel Name 名前 - - Type - タイプ - Duplicate Providers Detected 重複したプロバイダの検出 @@ -37971,9 +37861,6 @@ Only desktop kits are supported. Make sure the currently active kit is a desktop The following providers were already configured:<br>&nbsp;%1<br>They were not configured again. 以下のプロバイダは既に設定済みです。<br>&nbsp;%1<br>重複した設定は行いません。 - - - BareMetal::Internal::GdbServerProvidersSettingsPage GDB Server Providers GDB サーバープロバイダ @@ -37990,20 +37877,10 @@ Only desktop kits are supported. Make sure the currently active kit is a desktop Remove 削除 - - - BareMetal::Internal::OpenOcdGdbServerProviderFactory OpenOCD OpenOCD - - - BareMetal::Internal::OpenOcdGdbServerProviderConfigWidget - - Host: - ホスト: - Executable file: 実行ファイル: @@ -38020,32 +37897,10 @@ Only desktop kits are supported. Make sure the currently active kit is a desktop Additional arguments: 追加の引数: - - Init commands: - 初期化コマンド: - - - Reset commands: - リセットコマンド: - - - - BareMetal::Internal::StLinkUtilGdbServerProviderFactory ST-LINK Utility ST-LINK ユーティリティ - - - BareMetal::Internal::StLinkUtilGdbServerProviderConfigWidget - - Host: - ホスト: - - - Executable file: - 実行ファイル: - Specify the verbosity level (0..99). 詳細レベル(0..99)を指定してください。 @@ -38078,14 +37933,6 @@ Only desktop kits are supported. Make sure the currently active kit is a desktop Version: バージョン: - - Init commands: - 初期化コマンド: - - - Reset commands: - リセットコマンド: - ST-LINK/V1 ST-LINK/V1 @@ -47073,25 +46920,15 @@ The name of the release build configuration created by default for a qmake proje - BareMetalDeployConfiguration + BareMetal Deploy to BareMetal Device ベアメタルデバイスにデプロイ - - - BareMetal::Internal::DebugServerProviderChooser - - Manage... - 管理... - None しない - - - BareMetal::Internal::DebugServerProviderModel Not recognized 不明 @@ -47116,10 +46953,6 @@ The name of the release build configuration created by default for a qmake proje UVSC 対応プロバイダーエンジン (KEIL uVision と併用)。 - - Name - 名前 - Type @@ -47128,44 +46961,10 @@ The name of the release build configuration created by default for a qmake proje Engine エンジン - - Duplicate Providers Detected - 重複したプロバイダの検出 - - - The following providers were already configured:<br>&nbsp;%1<br>They were not configured again. - 以下のプロバイダは既に設定済みです。<br>&nbsp;%1<br>重複した設定は行いません。 - - - - BareMetal::Internal::DebugServerProvidersSettingsPage - - Add - 追加 - - - Clone - 複製 - - - Remove - 削除 - Debug Server Providers サーバー・プロバイダーをデバッグする - - Clone of %1 - %1 を複製 - - - Bare Metal - ベアメタル - - - - BareMetal::Internal::GdbServerProvider EBlink EBlink @@ -47178,25 +46977,6 @@ The name of the release build configuration created by default for a qmake proje JLink JLink - - OpenOCD - OpenOCD - - - ST-LINK Utility - ST-LINK ユーティリティ - - - - BareMetal::Internal::EBlinkGdbServerProviderConfigWidget - - Host: - ホスト: - - - Executable file: - 実行ファイル: - Script file: スクリプトファイル: @@ -47205,10 +46985,6 @@ The name of the release build configuration created by default for a qmake proje Specify the verbosity level (0 to 7). 詳細レベル (0 ~ 7) を指定してください。 - - Verbosity level: - 詳細レベル: - Connect under reset (hotplug). リセット状態での接続(ホットプラグ)。 @@ -47249,25 +47025,6 @@ The name of the release build configuration created by default for a qmake proje Auto shutdown: 自動シャットダウン: - - Init commands: - 初期化コマンド: - - - Reset commands: - リセットコマンド: - - - SWD - SWD - - - JTAG - JTAG - - - - BareMetalDebugSupport Cannot debug: Local executable is not set. デバッグエラー: ローカル実行ファイルが設定されていません。 @@ -47284,40 +47041,6 @@ The name of the release build configuration created by default for a qmake proje Unable to create a uVision project template. uVision プロジェクトのテンプレートを作成できません。 - - - BareMetal::Internal::GenericGdbServerProviderConfigWidget - - Host: - ホスト: - - - Extended mode: - 拡張モード: - - - Init commands: - 初期化コマンド: - - - Reset commands: - リセットコマンド: - - - - BareMetal::Internal::JLinkGdbServerProviderConfigWidget - - Host: - ホスト: - - - Executable file: - 実行ファイル: - - - Default - 既定 - JTAG JTAG @@ -47330,21 +47053,6 @@ The name of the release build configuration created by default for a qmake proje Device: デバイス: - - Additional arguments: - 追加の引数: - - - Init commands: - 初期化コマンド: - - - Reset commands: - リセットコマンド: - - - - BareMetal::Internal::UvscServerProvider uVision JLink uVision JLink @@ -47357,32 +47065,14 @@ The name of the release build configuration created by default for a qmake proje uVision St-Link uVision St-Link - - - BareMetal::Internal::JLinkUvscServerProviderConfigWidget Adapter options: アダプタオプション: - - - BareMetal::Internal::JLinkUvscAdapterOptionsWidget Port: ポート: - - Speed: - 速度: - - - JTAG - JTAG - - - SWD - SWD - 50MHz 50MHz @@ -47431,9 +47121,6 @@ The name of the release build configuration created by default for a qmake proje 100kHz 100kHz - - - BareMetal::Internal::SimulatorUvscServerProviderConfigWidget Limit speed to real-time. 速度をリアルタイムに制限する。 @@ -47442,32 +47129,6 @@ The name of the release build configuration created by default for a qmake proje Limit speed to real-time: 速度をリアルタイムに制限する: - - - BareMetal::Internal::StLinkUvscServerProviderConfigWidget - - Adapter options: - アダプタオプション: - - - - BareMetal::Internal::StLinkUvscAdapterOptionsWidget - - Port: - ポート: - - - Speed: - 速度: - - - JTAG - JTAG - - - SWD - SWD - 9MHz 9MHz @@ -47520,10 +47181,6 @@ The name of the release build configuration created by default for a qmake proje 125kHz 125kHz - - 100kHz - 100kHz - 50kHz 50kHz @@ -47540,13 +47197,6 @@ The name of the release build configuration created by default for a qmake proje 5kHz 5kHz - - - BareMetal::Internal::UvscServerProviderConfigWidget - - Host: - ホスト: - Choose Keil Toolset Configuration File Keil Toolset の設定ファイルを選択する @@ -47580,11 +47230,7 @@ The name of the release build configuration created by default for a qmake proje - BareMetal::Internal::Uv::DeviceSelectionModel - - Name - 名前 - + BareMetal Version バージョン @@ -47593,9 +47239,6 @@ The name of the release build configuration created by default for a qmake proje Vendor ベンダー - - - BareMetal::Internal::Uv::DeviceSelectionMemoryModel ID ID @@ -47608,13 +47251,6 @@ The name of the release build configuration created by default for a qmake proje Size サイズ - - - BareMetal::Internal::Uv::DeviceSelectionAlgorithmModel - - Name - 名前 - FLASH Start FLASH スタート @@ -47631,9 +47267,6 @@ The name of the release build configuration created by default for a qmake proje RAM Size RAM サイズ - - - BareMetal::Internal::Uv::DeviceSelectionAlgorithmView Algorithm path. アルゴリズムのパス。 @@ -47654,16 +47287,6 @@ The name of the release build configuration created by default for a qmake proje RAM: RAM: - - - BareMetal::Internal::Uv::DeviceSelectorToolPanel - - Manage... - 管理... - - - - BareMetal::Internal::Uv::DeviceSelectorDetailsPanel Vendor: ベンダー: @@ -47684,63 +47307,22 @@ The name of the release build configuration created by default for a qmake proje Flash algorithm: FLASH アルゴリズム: - - Peripheral description files (*.svd) - ペリフェラル説明ファイル (*.svd) - - - Select Peripheral Description File - ペリフェラル説明ファイルを選択する - - - Peripheral description file: - ペリフェラル説明ファイル: - - - - BareMetal::Internal::Uv::DeviceSelector Target device not selected. ターゲットデバイスが選択されていません。 - - - BareMetal::Internal::Uv::DeviceSelectionDialog Available Target Devices 使用可能なターゲットデバイス - - - BareMetal::Internal::Uv::DriverSelectionModel Path パス - - - BareMetal::Internal::Uv::DriverSelectionCpuDllModel - - Name - 名前 - - - - BareMetal::Internal::Uv::DriverSelectionCpuDllView Debugger CPU library (depends on a CPU core). デバッガ CPU ライブラリ(CPU コアに依存)。 - - - BareMetal::Internal::Uv::DriverSelectorToolPanel - - Manage... - 管理... - - - - BareMetal::Internal::Uv::DriverSelectorDetailsPanel Debugger driver library. デバッガドライバライブラリ。 @@ -47753,23 +47335,14 @@ The name of the release build configuration created by default for a qmake proje CPU library: CPU ライブラリ: - - - BareMetal::Internal::Uv::DriverSelector Target driver not selected. ターゲットドライバーが選択されていません。 - - - BareMetal::Internal::Uv::DriverSelectionDialog Available Target Drivers 使用可能なターゲットドライバー - - - IarToolChain IAREW %1 (%2, %3) IAREW %1 (%2, %3) @@ -47778,9 +47351,6 @@ The name of the release build configuration created by default for a qmake proje IAREW IAREW - - - BareMetal::Internal::IarToolChainConfigWidget &Compiler path: コンパイラのパス(&C): @@ -47793,20 +47363,10 @@ The name of the release build configuration created by default for a qmake proje &ABI: &ABI: - - - BareMetal::Internal::IDebugServerProviderConfigWidget Enter the name of the debugger server provider. デバッガ サーバー プロバイダの名前を入力してください。 - - Name: - 名前: - - - - KeilToolChain KEIL %1 (%2, %3) KEIL %1 (%2, %3) @@ -47815,24 +47375,6 @@ The name of the release build configuration created by default for a qmake proje KEIL KEIL - - - BareMetal::Internal::KeilToolChainConfigWidget - - &Compiler path: - コンパイラのパス(&C): - - - Platform codegen flags: - プラットフォーム用コード生成オプション: - - - &ABI: - &ABI: - - - - SdccToolChain SDCC %1 (%2, %3) SDCC %1 (%2, %3) @@ -47842,17 +47384,6 @@ The name of the release build configuration created by default for a qmake proje SDCC - - BareMetal::Internal::SdccToolChainConfigWidget - - &Compiler path: - コンパイラのパス(&C): - - - &ABI: - &ABI: - - Bazaar diff --git a/share/qtcreator/translations/qtcreator_pl.ts b/share/qtcreator/translations/qtcreator_pl.ts index 5cd55977b44..ba482c9d0ff 100644 --- a/share/qtcreator/translations/qtcreator_pl.ts +++ b/share/qtcreator/translations/qtcreator_pl.ts @@ -26284,7 +26284,7 @@ Zdalny: %4 - BareMetal::Internal::BareMetalDeviceConfigurationWizardSetupPage + BareMetal Set up GDB Server or Hardware Debugger Ustaw serwer GDB lub debugger sprzętowy @@ -27062,21 +27062,15 @@ Czy odinstalować istniejący pakiet? - BareMetal::Internal::BareMetalDevice + BareMetal Bare Metal Bare Metal - - - BareMetal::Internal::BareMetalGdbCommandsDeployStepWidget GDB commands: Komendy GDB: - - - BareMetal::Internal::BareMetalRunConfigurationFactory %1 (on GDB server or hardware debugger) %1 (na serwerze GDB lub debuggerze sprzętowym) @@ -29876,37 +29870,14 @@ Zainstaluj SDK o wersji %1 lub wyższej. Enter GDB commands to reset the hardware. The MCU should be halted after these commands. Wprowadź komendy GDB resetujące sprzęt. MCU powinien zostać zatrzymany po tych komendach. - - - BareMetal::Internal::BareMetalDeviceConfigurationFactory - - Bare Metal Device - Urządzenie Bare Metal - - - - BareMetal::Internal::BareMetalDeviceConfigurationWidget - - GDB server provider: - Dostawca serwera GDB: - - - - BareMetal::Internal::BareMetalDeviceConfigurationWizard New Bare Metal Device Configuration Setup Nowa konfiguracja urządzenia Bare Metal - - - BareMetal::Internal::BareMetalGdbCommandsDeployStep GDB commands Komendy GDB - - - BareMetal::Internal::BareMetalRunConfiguration %1 (via GDB server or hardware debugger) %1 (poprzez serwer GDB lub debugger sprzętowy) @@ -29916,9 +29887,6 @@ Zainstaluj SDK o wersji %1 lub wyższej. Bare Metal run configuration default run name Uruchom na serwerze GDB lub debuggerze sprzętowym - - - BareMetal::Internal::BareMetalRunConfigurationWidget Executable: Plik wykonywalny: @@ -33396,18 +33364,11 @@ Pliki z katalogu źródłowego pakietu Android są kopiowane do katalogu budowan - BareMetal::Internal::BareMetalCustomRunConfigWidget - - Executable: - Plik wykonywalny: - + BareMetal Work directory: Katalog roboczy: - - - BareMetal::Internal::BareMetalCustomRunConfiguration The remote executable must be set in order to run a custom remote run configuration. W celu uruchomienia własnej, zdalnej konfiguracji uruchamiania, należy ustawić zdalny plik wykonywalny. @@ -33416,9 +33377,6 @@ Pliki z katalogu źródłowego pakietu Android są kopiowane do katalogu budowan Custom Executable (on GDB server or hardware debugger) Własny plik wykonywalny (na serwerze GDB lub debuggerze sprzętowym) - - - BareMetal::Internal::BareMetalDebugSupport Cannot debug: Kit has no device. Nie można debugować: brak urządzenia w zestawie narzędzi. @@ -33431,16 +33389,10 @@ Pliki z katalogu źródłowego pakietu Android są kopiowane do katalogu budowan Cannot debug: Could not find executable for "%1". Nie można debugować: nie można odnaleźć pliku wykonywalnego dla "%1". - - - BareMetal::Internal::DefaultGdbServerProviderFactory Default Domyślny - - - BareMetal::Internal::DefaultGdbServerProviderConfigWidget Host: Host: @@ -33453,24 +33405,14 @@ Pliki z katalogu źródłowego pakietu Android są kopiowane do katalogu budowan Reset commands: Komendy resetujące: - - - BareMetal::GdbServerProvider Clone of %1 Klon %1 - - - BareMetal::Internal::GdbServerProviderConfigWidget Enter the name of the GDB server provider. Podaj nazwę dostawcy serwera GDB. - - Name: - Nazwa: - Choose the desired startup mode of the GDB server provider. Wybierz tryb startowy dostarczyciela serwera GDB. @@ -33491,9 +33433,6 @@ Pliki z katalogu źródłowego pakietu Android są kopiowane do katalogu budowan Startup in Pipe Mode Start w trybie potokowym - - - BareMetal::Internal::HostWidget Enter TCP/IP hostname of the GDB server provider, like "localhost" or "192.0.2.1". Podaj nazwę TCP/IP hosta dostawcy serwera GDB, np. "localhost" lub "192.0.2.1". @@ -33502,9 +33441,6 @@ Pliki z katalogu źródłowego pakietu Android są kopiowane do katalogu budowan Enter TCP/IP port which will be listened by the GDB server provider. Podaj port TCP/IP, na którym będzie nasłuchiwał dostawca serwera GDB. - - - BareMetal::Internal::GdbServerProviderChooser Manage... Zarządzaj... @@ -33513,9 +33449,6 @@ Pliki z katalogu źródłowego pakietu Android są kopiowane do katalogu budowan None Brak - - - BareMetal::Internal::GdbServerProviderModel Name Nazwa @@ -33532,9 +33465,6 @@ Pliki z katalogu źródłowego pakietu Android są kopiowane do katalogu budowan The following providers were already configured:<br>&nbsp;%1<br>They were not configured again. Następujący dostawcy zostali już skonfigurowani:<br>&nbsp;%1<br>Nie zostali oni ponownie skonfigurowani. - - - BareMetal::Internal::GdbServerProvidersSettingsPage Add Dodaj @@ -33551,24 +33481,10 @@ Pliki z katalogu źródłowego pakietu Android są kopiowane do katalogu budowan GDB Server Providers Dostawcy serwera GDB - - Bare Metal - Bare Metal - - - - BareMetal::Internal::OpenOcdGdbServerProviderFactory OpenOCD OpenOCD - - - BareMetal::Internal::OpenOcdGdbServerProviderConfigWidget - - Host: - Host: - Executable file: Plik wykonywalny: @@ -33585,32 +33501,10 @@ Pliki z katalogu źródłowego pakietu Android są kopiowane do katalogu budowan Additional arguments: Dodatkowe argumenty: - - Init commands: - Komendy inicjalizujące: - - - Reset commands: - Komendy resetujące: - - - - BareMetal::Internal::StLinkUtilGdbServerProviderFactory ST-LINK Utility Narzędzie ST-LINK - - - BareMetal::Internal::StLinkUtilGdbServerProviderConfigWidget - - Host: - Host: - - - Executable file: - Plik wykonywalny: - Specify the verbosity level (0..99). Poziom gadatliwości (0..99). @@ -33643,14 +33537,6 @@ Pliki z katalogu źródłowego pakietu Android są kopiowane do katalogu budowan Version: Wersja: - - Init commands: - Komendy inicjalizujące: - - - Reset commands: - Komendy resetujące: - ST-LINK/V1 ST-LINK/V1 diff --git a/share/qtcreator/translations/qtcreator_ru.ts b/share/qtcreator/translations/qtcreator_ru.ts index 42b2c4089a3..b3ccca5111a 100644 --- a/share/qtcreator/translations/qtcreator_ru.ts +++ b/share/qtcreator/translations/qtcreator_ru.ts @@ -3402,9 +3402,6 @@ Warning: this is an experimental feature and might lead to failing to execute th Enter GDB commands to reset the hardware. The MCU should be halted after these commands. Введите команды GDB для аппаратного сброса. После этих команд процессор должен быть остановлен. - - - BareMetal::Internal::BareMetalCustomRunConfiguration Unknown Неизвестно @@ -3417,9 +3414,6 @@ Warning: this is an experimental feature and might lead to failing to execute th Custom Executable Особая программа - - - BareMetal::Internal::BareMetalDebugSupport Cannot debug: Kit has no device. Отладка невозможна: отсутствует устройство в комплекте. @@ -3448,70 +3442,30 @@ Warning: this is an experimental feature and might lead to failing to execute th Unable to create an uVision project options template. Не удалось создать шаблон проекта настроек uVision. - - - BareMetal::Internal::BareMetalDevice - - Bare Metal - Голое железо - Bare Metal Device Устройство на голом железе - - - BareMetal::Internal::BareMetalDeviceConfigurationWidget Debug server provider: Тип сервера отладки: - - - BareMetal::Internal::BareMetalDeviceConfigurationWizard New Bare Metal Device Configuration Setup Настройка новой конфигурации голого устройства - - - BareMetal::Internal::BareMetalDeviceConfigurationWizardSetupPage Set up Debug Server or Hardware Debugger Настройка сервера отладки или аппаратного отладчика - - Name: - Название: - - - Debug server provider: - Тип сервера отладки: - - - - BareMetal::Internal::BareMetalGdbCommandsDeployStep GDB commands Команды GDB - - - BareMetal::Internal::BareMetalGdbCommandsDeployStepWidget GDB commands: Команды GDB: - - - BareMetal::Internal::BareMetalRunConfiguration - - Unknown - Неизвестно - - - - BareMetal::Internal::DebugServerProviderChooser Manage... Управление... @@ -3520,9 +3474,6 @@ Warning: this is an experimental feature and might lead to failing to execute th None Нет - - - BareMetal::Internal::DebugServerProviderModel Not recognized Не определён @@ -3547,10 +3498,6 @@ Warning: this is an experimental feature and might lead to failing to execute th UVSC-совместимый провайдер отладчика (используется совместно с KEIL uVision). - - Name - Имя - Type Тип @@ -3567,9 +3514,6 @@ Warning: this is an experimental feature and might lead to failing to execute th The following providers were already configured:<br>&nbsp;%1<br>They were not configured again. Следующие провайдеры уже настроены:<br>&nbsp;%1<br>Повторно настраиваться не будут. - - - BareMetal::Internal::DebugServerProvidersSettingsPage Add Добавить @@ -3594,9 +3538,6 @@ Warning: this is an experimental feature and might lead to failing to execute th Bare Metal Bare Metal - - - BareMetal::Internal::EBlinkGdbServerProviderConfigWidget Host: Хост: @@ -3673,9 +3614,6 @@ Warning: this is an experimental feature and might lead to failing to execute th JTAG JTAG - - - BareMetal::Internal::GdbServerProvider EBlink EBlink @@ -3692,9 +3630,6 @@ Warning: this is an experimental feature and might lead to failing to execute th ST-LINK Utility Утилита ST-LINK - - - BareMetal::Internal::GdbServerProviderConfigWidget Choose the desired startup mode of the GDB server provider. Выберите желаемый метод запуска сервера GDB. @@ -3723,9 +3658,6 @@ Warning: this is an experimental feature and might lead to failing to execute th Startup in Pipe Mode Запуск в локальном режиме (pipe) - - - BareMetal::Internal::HostWidget Enter TCP/IP hostname of the debug server, like "localhost" or "192.0.2.1". Введите TCP/IP имя сервера отладки, например: «localhost» или «192.0.2.1». @@ -3734,9 +3666,6 @@ Warning: this is an experimental feature and might lead to failing to execute th Enter TCP/IP port which will be listened by the debug server. Введите порт TCP/IP, который будет прослушиваться сервером отладки. - - - BareMetal::Internal::IDebugServerProviderConfigWidget Enter the name of the debugger server provider. Введите имя провайдера сервера отладки. @@ -3745,9 +3674,6 @@ Warning: this is an experimental feature and might lead to failing to execute th Name: Имя: - - - BareMetal::Internal::IarToolChainConfigWidget &Compiler path: Путь к &компилятору: @@ -3760,13 +3686,6 @@ Warning: this is an experimental feature and might lead to failing to execute th &ABI: &ABI: - - - BareMetal::Internal::JLinkGdbServerProviderConfigWidget - - Host: - Хост: - JLink GDB Server (JLinkGDBServerCL.exe) JLink сервер GDB (JLinkGDBServerCL.exe) @@ -3775,10 +3694,6 @@ Warning: this is an experimental feature and might lead to failing to execute th JLink GDB Server (JLinkGDBServer) JLink сервер GDB (JLinkGDBServer) - - Executable file: - Исполняемый файл: - Default По умолчанию @@ -3811,33 +3726,10 @@ Warning: this is an experimental feature and might lead to failing to execute th Additional arguments: Дополнительные параметры: - - Init commands: - Команды инициализации: - - - Reset commands: - Команды сброса: - - - - BareMetal::Internal::JLinkUvscAdapterOptionsWidget Port: Порт: - - Speed: - Скорость: - - - JTAG - JTAG - - - SWD - SWD - 50MHz 50 МГц @@ -3886,39 +3778,10 @@ Warning: this is an experimental feature and might lead to failing to execute th 100kHz 100 кГц - - - BareMetal::Internal::JLinkUvscServerProviderConfigWidget Adapter options: Параметры адаптера: - - - BareMetal::Internal::KeilToolChainConfigWidget - - &Compiler path: - Путь к &компилятору: - - - Platform codegen flags: - Флаги генерации кода для платформы: - - - &ABI: - &ABI: - - - - BareMetal::Internal::OpenOcdGdbServerProviderConfigWidget - - Host: - Хост: - - - Executable file: - Исполняемый файл: - Root scripts directory: Корень каталога скриптов: @@ -3927,32 +3790,6 @@ Warning: this is an experimental feature and might lead to failing to execute th Configuration file: Файл конфигурации: - - Additional arguments: - Дополнительные параметры: - - - Init commands: - Команды инициализации: - - - Reset commands: - Команды сброса: - - - - BareMetal::Internal::SdccToolChainConfigWidget - - &Compiler path: - Путь к &компилятору: - - - &ABI: - &ABI: - - - - BareMetal::Internal::SimulatorUvscServerProviderConfigWidget Limit speed to real-time. Ограничить скорость реальным временем. @@ -3961,25 +3798,10 @@ Warning: this is an experimental feature and might lead to failing to execute th Limit speed to real-time: Ограничить скорость: - - - BareMetal::Internal::StLinkUtilGdbServerProviderConfigWidget - - Host: - Хост: - - - Executable file: - Исполняемый файл: - Specify the verbosity level (0..99). Укажите уровень информативности (0...99). - - Verbosity level: - Уровень информативности: - Continue listening for connections after disconnect. Продолжать ожидание подключений после отключения. @@ -4004,14 +3826,6 @@ Warning: this is an experimental feature and might lead to failing to execute th Version: Версия: - - Init commands: - Команды инициализации: - - - Reset commands: - Команды сброса: - ST-LINK/V1 ST-LINK/V1 @@ -4020,25 +3834,6 @@ Warning: this is an experimental feature and might lead to failing to execute th ST-LINK/V2 ST-LINK/V2 - - - BareMetal::Internal::StLinkUvscAdapterOptionsWidget - - Port: - Порт: - - - Speed: - Скорость: - - - JTAG - JTAG - - - SWD - SWD - 9MHz 9 МГц @@ -4091,10 +3886,6 @@ Warning: this is an experimental feature and might lead to failing to execute th 125kHz 125 кГц - - 100kHz - 100 кГц - 50kHz 50 кГц @@ -4111,16 +3902,6 @@ Warning: this is an experimental feature and might lead to failing to execute th 5kHz 5 кГц - - - BareMetal::Internal::StLinkUvscServerProviderConfigWidget - - Adapter options: - Параметры адаптера: - - - - BareMetal::Internal::Uv::DeviceSelectionAlgorithmModel Name Название @@ -4141,9 +3922,6 @@ Warning: this is an experimental feature and might lead to failing to execute th RAM Size RAM Объём - - - BareMetal::Internal::Uv::DeviceSelectionAlgorithmView Algorithm path. Путь к алгоритму. @@ -4164,16 +3942,10 @@ Warning: this is an experimental feature and might lead to failing to execute th RAM: RAM: - - - BareMetal::Internal::Uv::DeviceSelectionDialog Available Target Devices Доступные устройства - - - BareMetal::Internal::Uv::DeviceSelectionMemoryModel ID ID @@ -4186,13 +3958,6 @@ Warning: this is an experimental feature and might lead to failing to execute th Size Размер - - - BareMetal::Internal::Uv::DeviceSelectionModel - - Name - Название - Version Версия @@ -4201,16 +3966,10 @@ Warning: this is an experimental feature and might lead to failing to execute th Vendor Поставщик - - - BareMetal::Internal::Uv::DeviceSelector Target device not selected. Устройство не выбрано. - - - BareMetal::Internal::Uv::DeviceSelectorDetailsPanel Vendor: Поставщик: @@ -4231,63 +3990,22 @@ Warning: this is an experimental feature and might lead to failing to execute th Flash algorithm: Алгоритм прошивания: - - Peripheral description files (*.svd) - Файлы описания устройств (*.svd) - - - Select Peripheral Description File - Выбор файла описания внешнего устройства - - - Peripheral description file: - Файл описания устройства: - - - - BareMetal::Internal::Uv::DeviceSelectorToolPanel - - Manage... - Управление... - - - - BareMetal::Internal::Uv::DriverSelectionCpuDllModel - - Name - Название - - - - BareMetal::Internal::Uv::DriverSelectionCpuDllView Debugger CPU library (depends on a CPU core). Библиотека поддержки процессора для отладчика (зависит от ядра процессора). - - - BareMetal::Internal::Uv::DriverSelectionDialog Available Target Drivers Доступные драйвера - - - BareMetal::Internal::Uv::DriverSelectionModel Path Путь - - - BareMetal::Internal::Uv::DriverSelector Target driver not selected. Драйвер не выбран. - - - BareMetal::Internal::Uv::DriverSelectorDetailsPanel Debugger driver library. Библиотека драйвера отладчика. @@ -4300,16 +4018,6 @@ Warning: this is an experimental feature and might lead to failing to execute th CPU library: Библиотека процессора: - - - BareMetal::Internal::Uv::DriverSelectorToolPanel - - Manage... - Управление... - - - - BareMetal::Internal::UvscServerProvider uVision Simulator Симулятор uVision @@ -4322,13 +4030,6 @@ Warning: this is an experimental feature and might lead to failing to execute th uVision JLink uVision JLink - - - BareMetal::Internal::UvscServerProviderConfigWidget - - Host: - Хост: - Choose Keil Toolset Configuration File Выбор файла конфигурации инструментария Keil @@ -4345,9 +4046,6 @@ Warning: this is an experimental feature and might lead to failing to execute th Target driver: Драйвер: - - - BareMetalDeployConfiguration Deploy to BareMetal Device Развёртывание на устройство на голом железе @@ -23728,7 +23426,7 @@ Add, modify, and remove document filters, which determine the documentation set - IarToolChain + BareMetal IAREW %1 (%2, %3) IAREW %1 (%2, %3) @@ -25092,7 +24790,7 @@ Error: %5 - KeilToolChain + BareMetal KEIL %1 (%2, %3) KEIL %1 (%2, %3) @@ -44893,7 +44591,7 @@ Row: %4, Column: %5 - SdccToolChain + BareMetal SDCC %1 (%2, %3) SDCC %1 (%2, %3) diff --git a/share/qtcreator/translations/qtcreator_uk.ts b/share/qtcreator/translations/qtcreator_uk.ts index 8ab54dce9bf..a454b5e8d4d 100644 --- a/share/qtcreator/translations/qtcreator_uk.ts +++ b/share/qtcreator/translations/qtcreator_uk.ts @@ -36314,7 +36314,7 @@ This wizard will guide you through the essential steps to deploy a ready-to-go d - BareMetal::BareMetalDeviceConfigurationWidget + BareMetal Form Форма @@ -36323,25 +36323,6 @@ This wizard will guide you through the essential steps to deploy a ready-to-go d GDB host: Вузол GDB: - - GDB port: - Порт GDB: - - - GDB commands: - Команди GDB: - - - - BareMetal::Internal::BareMetalDeviceConfigurationWizardSetupPage - - Form - Форма - - - Set up GDB Server or Hardware Debugger - Налаштування сервера GDB або апаратного зневаджувача - Name: Назва: @@ -36350,34 +36331,10 @@ This wizard will guide you through the essential steps to deploy a ready-to-go d GDB server provider: Постачальник сервера GDB: - - Init commands: - Команди ініціалізації: - - - Reset commands: - Команди скидання: - - - Bare Metal Device - Голий пристрій - localhost localhost - - GDB port: - Порт GDB: - - - GDB host: - Вузол GDB: - - - GDB commands: - Команди GDB: - load monitor reset @@ -37410,95 +37367,27 @@ Do you want to uninstall the existing package next time? - BareMetal::Internal::BareMetalDevice + BareMetal Bare Metal Голе залізо - - - BareMetal::BareMetalDeviceConfigurationFactory Bare Metal Device Голий пристрій - - - BareMetal::BareMetalDeviceConfigurationWizard - - New Bare Metal Device Configuration Setup - Налаштування нової конфігурації голого пристрою - - - - BareMetal::BareMetalDeviceConfigurationWizardSetupPage Set up GDB Server or Hardware Debugger Налаштування сервера GDB або апаратного зневаджувача - - Bare Metal Device - Голий пристрій - - - - BareMetal::Internal::BareMetalGdbCommandsDeployStepWidget GDB commands: Команди GDB: - - - BareMetal::BareMetalGdbCommandsDeployStep - - GDB commands - Команди GDB - - - - BareMetal::BareMetalRunConfiguration - - %1 (via GDB server or hardware debugger) - %1 (через сервер GDB або апаратний зневаджувач) - - - Run on GDB server or hardware debugger - Bare Metal run configuration default run name - Виконати на сервері GDB або апаратному зневаджувачі - - - - BareMetal::Internal::BareMetalRunConfigurationFactory %1 (on GDB server or hardware debugger) %1 (через сервер GDB або апаратний зневаджувач) - - - BareMetal::BareMetalRunConfigurationWidget - - Executable: - Виконуваний модуль: - - - Arguments: - Аргументи: - - - <default> - <типово> - - - Working directory: - Робоча тека: - - - Unknown - Невідомо - - - - BareMetal::Internal::BareMetalRunControlFactory Cannot debug: Local executable is not set. Неможливо зневадити: локальний виконуваний модуль не задано. @@ -41067,57 +40956,14 @@ Install an SDK of at least API version %1. Enter GDB commands to reset the hardware. The MCU should be halted after these commands. Введіть команди GDB для апаратного скидання. Мікроконтролер має бути зупинено після цих команд. - - Bare Metal - Голе залізо - - - - BareMetal::Internal::BareMetalDeviceConfigurationFactory - - Bare Metal Device - Голий пристрій - - - - BareMetal::Internal::BareMetalDeviceConfigurationWidget - - GDB host: - Вузол GDB: - - - GDB port: - Порт GDB: - - - Init commands: - Команди ініціалізації: - - - Reset commands: - Команди скидання: - - - GDB server provider: - Постачальник сервера GDB: - - - - BareMetal::Internal::BareMetalDeviceConfigurationWizard New Bare Metal Device Configuration Setup Налаштування нової конфігурації голого пристрою - - - BareMetal::Internal::BareMetalGdbCommandsDeployStep GDB commands Команди GDB - - - BareMetal::Internal::BareMetalRunConfiguration %1 (via GDB server or hardware debugger) %1 (через сервер GDB або апаратний зневаджувач) @@ -41127,17 +40973,10 @@ Install an SDK of at least API version %1. Bare Metal run configuration default run name Виконати на сервері GDB або апаратному зневаджувачі - - - BareMetal::Internal::BareMetalRunConfigurationWidget Executable: Виконуваний модуль: - - Arguments: - Аргументи: - <default> <типово> @@ -45881,22 +45720,11 @@ Affected are breakpoints %1 - BareMetal::Internal::BareMetalCustomRunConfigWidget - - Executable: - Виконуваний модуль: - - - Arguments: - Аргументи: - + BareMetal Work directory: Робоча тека: - - - BareMetal::Internal::BareMetalCustomRunConfiguration The remote executable must be set in order to run a custom remote run configuration. Має бути заданий віддалений виконуваний модуль, щоб виконати користувацьку віддалену конфігурацію запуску. @@ -45905,9 +45733,6 @@ Affected are breakpoints %1 Custom Executable (on GDB server or hardware debugger) Виконуваний модуль (через сервер GDB або апаратний зневаджувач) - - - BareMetal::Internal::BareMetalDebugSupport Debugging failed. Збій зневадження. @@ -45920,16 +45745,10 @@ Affected are breakpoints %1 Starting GDB server... Запуск сервера GDB... - - - BareMetal::Internal::DefaultGdbServerProviderFactory Default Типовий - - - BareMetal::Internal::DefaultGdbServerProviderConfigWidget Host: Вузол: @@ -45942,24 +45761,14 @@ Affected are breakpoints %1 Reset commands: Команди скидання: - - - BareMetal::GdbServerProvider Clone of %1 Клон %1 - - - BareMetal::Internal::GdbServerProviderConfigWidget Enter the name of the GDB server provider. Введіть назву постачальника сервера GDB. - - Name: - Назва: - Choose the desired startup mode of the GDB server provider. Оберіть бажаний режим запуску постачальника сервера GDB. @@ -45980,9 +45789,6 @@ Affected are breakpoints %1 Startup in Pipe Mode Запуск в режимі конвеєра - - - BareMetal::Internal::HostWidget Enter TCP/IP hostname of the GDB server provider, like "localhost" or "192.0.2.1". Введіть назву вузла постачальника сервера GDB (напр., "localhost" або "192.0.2.1"). @@ -45991,9 +45797,6 @@ Affected are breakpoints %1 Enter TCP/IP port which will be listened by the GDB server provider. Введіть порт, на якому буде слухати постачальник сервера GDB. - - - BareMetal::Internal::GdbServerProviderChooser Manage... Управління... @@ -46002,9 +45805,6 @@ Affected are breakpoints %1 None Немає - - - BareMetal::Internal::GdbServerProviderModel Name Назва @@ -46025,9 +45825,6 @@ Affected are breakpoints %1 The following providers were already configured:<br>&nbsp;%1<br>They were not configured again. Наступні постачальники вже сконфігуровано:<br>&nbsp;%1<br>Їх не буде сконфігуровано знову. - - - BareMetal::Internal::GdbServerProvidersSettingsPage GDB Server Providers Постачальники сервера GDB @@ -46044,20 +45841,10 @@ Affected are breakpoints %1 Remove Видалити - - - BareMetal::Internal::OpenOcdGdbServerProviderFactory OpenOCD OpenOCD - - - BareMetal::Internal::OpenOcdGdbServerProviderConfigWidget - - Host: - Вузол: - Executable file: Виконуваний файл: @@ -46074,32 +45861,10 @@ Affected are breakpoints %1 Additional arguments: Додаткові аргументи: - - Init commands: - Команди ініціалізації: - - - Reset commands: - Команди скидання: - - - - BareMetal::Internal::StLinkUtilGdbServerProviderFactory ST-LINK Utility Утиліта ST-LINK - - - BareMetal::Internal::StLinkUtilGdbServerProviderConfigWidget - - Host: - Вузол: - - - Executable file: - Виконуваний файл: - Specify the verbosity level (0..99). Вкажіть рівень деталізації (0..99). @@ -46132,14 +45897,6 @@ Affected are breakpoints %1 Version: Версія: - - Init commands: - Команди ініціалізації: - - - Reset commands: - Команди скидання: - ST-LINK/V1 ST-LINK/V1 diff --git a/src/plugins/baremetal/baremetaldebugsupport.cpp b/src/plugins/baremetal/baremetaldebugsupport.cpp index 7149c42bb85..1f29fab0a4f 100644 --- a/src/plugins/baremetal/baremetaldebugsupport.cpp +++ b/src/plugins/baremetal/baremetaldebugsupport.cpp @@ -2,7 +2,9 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "baremetaldebugsupport.h" + #include "baremetaldevice.h" +#include "baremetaltr.h" #include "debugserverprovidermanager.h" #include "idebugserverprovider.h" @@ -27,24 +29,21 @@ using namespace Debugger; using namespace ProjectExplorer; using namespace Utils; -namespace BareMetal { -namespace Internal { - -// BareMetalDebugSupport +namespace BareMetal::Internal { BareMetalDebugSupport::BareMetalDebugSupport(RunControl *runControl) : Debugger::DebuggerRunTool(runControl) { const auto dev = qSharedPointerCast(device()); if (!dev) { - reportFailure(tr("Cannot debug: Kit has no device.")); + reportFailure(Tr::tr("Cannot debug: Kit has no device.")); return; } const QString providerId = dev->debugServerProviderId(); IDebugServerProvider *p = DebugServerProviderManager::findProvider(providerId); if (!p) { - reportFailure(tr("No debug server provider found for %1").arg(providerId)); + reportFailure(Tr::tr("No debug server provider found for %1").arg(providerId)); return; } @@ -67,5 +66,4 @@ void BareMetalDebugSupport::start() DebuggerRunTool::start(); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetaldebugsupport.h b/src/plugins/baremetal/baremetaldebugsupport.h index 161ea346bec..655b6666f45 100644 --- a/src/plugins/baremetal/baremetaldebugsupport.h +++ b/src/plugins/baremetal/baremetaldebugsupport.h @@ -5,21 +5,10 @@ #include -namespace ProjectExplorer { -class RunControl; -} - -namespace BareMetal { -namespace Internal { - -class IDebugServerProvider; - -// BareMetalDebugSupport +namespace BareMetal::Internal { class BareMetalDebugSupport final : public Debugger::DebuggerRunTool { - Q_OBJECT - public: explicit BareMetalDebugSupport(ProjectExplorer::RunControl *runControl); @@ -27,5 +16,4 @@ private: void start() final; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetaldevice.cpp b/src/plugins/baremetal/baremetaldevice.cpp index 236a941e242..7b79b990fdf 100644 --- a/src/plugins/baremetal/baremetaldevice.cpp +++ b/src/plugins/baremetal/baremetaldevice.cpp @@ -2,10 +2,12 @@ // Copyright (C) 2016 Denis Shienkov // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -#include "baremetalconstants.h" #include "baremetaldevice.h" + +#include "baremetalconstants.h" #include "baremetaldeviceconfigurationwidget.h" #include "baremetaldeviceconfigurationwizard.h" +#include "baremetaltr.h" #include "debugserverprovidermanager.h" #include "idebugserverprovider.h" @@ -13,8 +15,7 @@ using namespace ProjectExplorer; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { const char debugServerProviderIdKeyC[] = "IDebugServerProviderId"; @@ -22,7 +23,7 @@ const char debugServerProviderIdKeyC[] = "IDebugServerProviderId"; BareMetalDevice::BareMetalDevice() { - setDisplayType(tr("Bare Metal")); + setDisplayType(Tr::tr("Bare Metal")); setDefaultDisplayName(defaultDisplayName()); setOsType(Utils::OsTypeOther); } @@ -36,7 +37,7 @@ BareMetalDevice::~BareMetalDevice() QString BareMetalDevice::defaultDisplayName() { - return tr("Bare Metal Device"); + return Tr::tr("Bare Metal Device"); } QString BareMetalDevice::debugServerProviderId() const @@ -100,7 +101,7 @@ IDeviceWidget *BareMetalDevice::createWidget() BareMetalDeviceFactory::BareMetalDeviceFactory() : IDeviceFactory(Constants::BareMetalOsType) { - setDisplayName(BareMetalDevice::tr("Bare Metal Device")); + setDisplayName(Tr::tr("Bare Metal Device")); setCombinedIcon(":/baremetal/images/baremetaldevicesmall.png", ":/baremetal/images/baremetaldevice.png"); setConstructionFunction(&BareMetalDevice::create); @@ -112,5 +113,4 @@ BareMetalDeviceFactory::BareMetalDeviceFactory() }); } -} //namespace Internal -} //namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetaldevice.h b/src/plugins/baremetal/baremetaldevice.h index 337bab662a7..6fcc1972b39 100644 --- a/src/plugins/baremetal/baremetaldevice.h +++ b/src/plugins/baremetal/baremetaldevice.h @@ -7,8 +7,7 @@ #include #include -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { class IDebugServerProvider; @@ -16,8 +15,6 @@ class IDebugServerProvider; class BareMetalDevice final : public ProjectExplorer::IDevice { - Q_DECLARE_TR_FUNCTIONS(BareMetal::Internal::BareMetalDevice) - public: using Ptr = QSharedPointer; using ConstPtr = QSharedPointer; @@ -52,5 +49,4 @@ public: BareMetalDeviceFactory(); }; -} //namespace Internal -} //namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetaldeviceconfigurationwidget.cpp b/src/plugins/baremetal/baremetaldeviceconfigurationwidget.cpp index 0153388a2f9..390893b8ee9 100644 --- a/src/plugins/baremetal/baremetaldeviceconfigurationwidget.cpp +++ b/src/plugins/baremetal/baremetaldeviceconfigurationwidget.cpp @@ -3,8 +3,9 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "baremetaldevice.h" -#include "baremetaldeviceconfigurationwidget.h" +#include "baremetaldeviceconfigurationwidget.h" +#include "baremetaltr.h" #include "debugserverproviderchooser.h" #include @@ -12,10 +13,7 @@ #include -namespace BareMetal { -namespace Internal { - -// BareMetalDeviceConfigurationWidget +namespace BareMetal::Internal { BareMetalDeviceConfigurationWidget::BareMetalDeviceConfigurationWidget( const ProjectExplorer::IDevice::Ptr &deviceConfig) @@ -30,7 +28,7 @@ BareMetalDeviceConfigurationWidget::BareMetalDeviceConfigurationWidget( m_debugServerProviderChooser = new DebugServerProviderChooser(true, this); m_debugServerProviderChooser->populate(); m_debugServerProviderChooser->setCurrentProviderId(dev->debugServerProviderId()); - formLayout->addRow(tr("Debug server provider:"), m_debugServerProviderChooser); + formLayout->addRow(Tr::tr("Debug server provider:"), m_debugServerProviderChooser); connect(m_debugServerProviderChooser, &DebugServerProviderChooser::providerChanged, this, &BareMetalDeviceConfigurationWidget::debugServerProviderChanged); @@ -48,5 +46,4 @@ void BareMetalDeviceConfigurationWidget::updateDeviceFromUi() debugServerProviderChanged(); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetaldeviceconfigurationwidget.h b/src/plugins/baremetal/baremetaldeviceconfigurationwidget.h index 23be5e98d47..81ac8d410f4 100644 --- a/src/plugins/baremetal/baremetaldeviceconfigurationwidget.h +++ b/src/plugins/baremetal/baremetaldeviceconfigurationwidget.h @@ -6,18 +6,13 @@ #include -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { class DebugServerProviderChooser; -// BareMetalDeviceConfigurationWidget - class BareMetalDeviceConfigurationWidget final : public ProjectExplorer::IDeviceWidget { - Q_OBJECT - public: explicit BareMetalDeviceConfigurationWidget(const ProjectExplorer::IDevicePtr &deviceConfig); @@ -28,5 +23,4 @@ private: DebugServerProviderChooser *m_debugServerProviderChooser = nullptr; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetaldeviceconfigurationwizard.cpp b/src/plugins/baremetal/baremetaldeviceconfigurationwizard.cpp index ac86d737f38..e3524cd5214 100644 --- a/src/plugins/baremetal/baremetaldeviceconfigurationwizard.cpp +++ b/src/plugins/baremetal/baremetaldeviceconfigurationwizard.cpp @@ -2,25 +2,22 @@ // Copyright (C) 2016 Denis Shienkov // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +#include "baremetaldeviceconfigurationwizard.h" + #include "baremetalconstants.h" #include "baremetaldevice.h" -#include "baremetaldeviceconfigurationwizard.h" #include "baremetaldeviceconfigurationwizardpages.h" +#include "baremetaltr.h" -#include - -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { enum PageId { SetupPageId }; -// BareMetalDeviceConfigurationWizard - BareMetalDeviceConfigurationWizard::BareMetalDeviceConfigurationWizard(QWidget *parent) : Utils::Wizard(parent), m_setupPage(new BareMetalDeviceConfigurationWizardSetupPage(this)) { - setWindowTitle(tr("New Bare Metal Device Configuration Setup")); + setWindowTitle(Tr::tr("New Bare Metal Device Configuration Setup")); setPage(SetupPageId, m_setupPage); m_setupPage->setCommitPage(true); } @@ -36,5 +33,4 @@ ProjectExplorer::IDevice::Ptr BareMetalDeviceConfigurationWizard::device() const return dev; } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetaldeviceconfigurationwizard.h b/src/plugins/baremetal/baremetaldeviceconfigurationwizard.h index 8290de81bae..ab7d6062c26 100644 --- a/src/plugins/baremetal/baremetaldeviceconfigurationwizard.h +++ b/src/plugins/baremetal/baremetaldeviceconfigurationwizard.h @@ -6,17 +6,12 @@ #include #include -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { class BareMetalDeviceConfigurationWizardSetupPage; -// BareMetalDeviceConfigurationWizard - class BareMetalDeviceConfigurationWizard final : public Utils::Wizard { - Q_OBJECT - public: explicit BareMetalDeviceConfigurationWizard(QWidget *parent = nullptr); @@ -26,5 +21,4 @@ private: BareMetalDeviceConfigurationWizardSetupPage *m_setupPage = nullptr; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.cpp b/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.cpp index 57451c1cc85..b7b5163056b 100644 --- a/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.cpp +++ b/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.cpp @@ -2,9 +2,10 @@ // Copyright (C) 2016 Denis Shienkov // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -#include "baremetaldevice.h" #include "baremetaldeviceconfigurationwizardpages.h" +#include "baremetaldevice.h" +#include "baremetaltr.h" #include "debugserverproviderchooser.h" #include @@ -14,24 +15,21 @@ #include #include -namespace BareMetal { -namespace Internal { - -// BareMetalDeviceConfigurationWizardSetupPage +namespace BareMetal::Internal { BareMetalDeviceConfigurationWizardSetupPage::BareMetalDeviceConfigurationWizardSetupPage( QWidget *parent) : QWizardPage(parent) { - setTitle(tr("Set up Debug Server or Hardware Debugger")); + setTitle(Tr::tr("Set up Debug Server or Hardware Debugger")); const auto formLayout = new QFormLayout(this); formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); m_nameLineEdit = new QLineEdit(this); - formLayout->addRow(tr("Name:"), m_nameLineEdit); + formLayout->addRow(Tr::tr("Name:"), m_nameLineEdit); m_debugServerProviderChooser = new DebugServerProviderChooser(false, this); m_debugServerProviderChooser->populate(); - formLayout->addRow(tr("Debug server provider:"), m_debugServerProviderChooser); + formLayout->addRow(Tr::tr("Debug server provider:"), m_debugServerProviderChooser); connect(m_nameLineEdit, &QLineEdit::textChanged, this, &BareMetalDeviceConfigurationWizardSetupPage::completeChanged); @@ -59,5 +57,4 @@ QString BareMetalDeviceConfigurationWizardSetupPage::debugServerProviderId() con return m_debugServerProviderChooser->currentProviderId(); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.h b/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.h index 978b5d70166..2bc70a5c79f 100644 --- a/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.h +++ b/src/plugins/baremetal/baremetaldeviceconfigurationwizardpages.h @@ -10,17 +10,12 @@ QT_BEGIN_NAMESPACE class QLineEdit; QT_END_NAMESPACE -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { class DebugServerProviderChooser; -// BareMetalDeviceConfigurationWizardSetupPage - class BareMetalDeviceConfigurationWizardSetupPage final : public QWizardPage { - Q_OBJECT - public: explicit BareMetalDeviceConfigurationWizardSetupPage(QWidget *parent = nullptr); @@ -34,5 +29,4 @@ private: DebugServerProviderChooser *m_debugServerProviderChooser = nullptr; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetalgdbcommandsdeploystep.cpp b/src/plugins/baremetal/baremetalgdbcommandsdeploystep.cpp index 6e6ea56a1e1..14f2eb2aaf1 100644 --- a/src/plugins/baremetal/baremetalgdbcommandsdeploystep.cpp +++ b/src/plugins/baremetal/baremetalgdbcommandsdeploystep.cpp @@ -22,7 +22,7 @@ BareMetalGdbCommandsDeployStepWidget::BareMetalGdbCommandsDeployStepWidget(BareM fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); setLayout(fl); m_commands = new QPlainTextEdit(this); - fl->addRow(tr("GDB commands:"), m_commands); + fl->addRow(Tr::tr("GDB commands:"), m_commands); m_commands->setPlainText(m_step.gdbCommands()); connect(m_commands, &QPlainTextEdit::textChanged, this, &BareMetalGdbCommandsDeployStepWidget::update); } @@ -82,7 +82,7 @@ Core::Id BareMetalGdbCommandsDeployStep::stepId() QString BareMetalGdbCommandsDeployStep::displayName() { - return tr("GDB commands"); + return Tr::tr("GDB commands"); } void BareMetalGdbCommandsDeployStep::updateGdbCommands(const QString &newCommands) diff --git a/src/plugins/baremetal/baremetalplugin.cpp b/src/plugins/baremetal/baremetalplugin.cpp index a285f151f42..a6b7f994ed0 100644 --- a/src/plugins/baremetal/baremetalplugin.cpp +++ b/src/plugins/baremetal/baremetalplugin.cpp @@ -2,11 +2,13 @@ // Copyright (C) 2016 Denis Shienkov // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +#include "baremetalplugin.h" + #include "baremetalconstants.h" #include "baremetaldebugsupport.h" #include "baremetaldevice.h" -#include "baremetalplugin.h" #include "baremetalrunconfiguration.h" +#include "baremetaltr.h" #include "debugserverprovidermanager.h" #include "debugserverproviderssettingspage.h" @@ -27,8 +29,7 @@ using namespace ProjectExplorer; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { class BareMetalDeployConfigurationFactory : public DeployConfigurationFactory { @@ -36,8 +37,7 @@ public: BareMetalDeployConfigurationFactory() { setConfigBaseId("BareMetal.DeployConfiguration"); - setDefaultDisplayName(QCoreApplication::translate("BareMetalDeployConfiguration", - "Deploy to BareMetal Device")); + setDefaultDisplayName(Tr::tr("Deploy to BareMetal Device")); addSupportedTargetDeviceType(Constants::BareMetalOsType); } }; @@ -87,5 +87,4 @@ void BareMetalPlugin::extensionsInitialized() DebugServerProviderManager::instance()->restoreProviders(); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetalplugin.h b/src/plugins/baremetal/baremetalplugin.h index baf688fdd3d..9e6cda59abe 100644 --- a/src/plugins/baremetal/baremetalplugin.h +++ b/src/plugins/baremetal/baremetalplugin.h @@ -6,10 +6,7 @@ #include -namespace BareMetal { -namespace Internal { - -// BareMetalPlugin +namespace BareMetal::Internal { class BareMetalPlugin final : public ExtensionSystem::IPlugin { @@ -34,5 +31,4 @@ private slots: #endif // WITH_TESTS }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetalrunconfiguration.cpp b/src/plugins/baremetal/baremetalrunconfiguration.cpp index 8b16aadb533..3edc38de9e4 100644 --- a/src/plugins/baremetal/baremetalrunconfiguration.cpp +++ b/src/plugins/baremetal/baremetalrunconfiguration.cpp @@ -1,9 +1,11 @@ // Copyright (C) 2016 Tim Sander // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -#include "baremetalconstants.h" #include "baremetalrunconfiguration.h" +#include "baremetalconstants.h" +#include "baremetaltr.h" + #include #include #include @@ -13,22 +15,19 @@ using namespace ProjectExplorer; using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // RunConfigurations class BareMetalRunConfiguration final : public RunConfiguration { - Q_DECLARE_TR_FUNCTIONS(BareMetal::Internal::BareMetalRunConfiguration) - public: explicit BareMetalRunConfiguration(Target *target, Id id) : RunConfiguration(target, id) { const auto exeAspect = addAspect(target, ExecutableAspect::RunDevice); exeAspect->setDisplayStyle(StringAspect::LabelDisplay); - exeAspect->setPlaceHolderText(tr("Unknown")); + exeAspect->setPlaceHolderText(Tr::tr("Unknown")); addAspect(macroExpander()); addAspect(macroExpander(), nullptr); @@ -44,15 +43,13 @@ public: class BareMetalCustomRunConfiguration final : public RunConfiguration { - Q_DECLARE_TR_FUNCTIONS(BareMetal::Internal::BareMetalCustomRunConfiguration) - public: explicit BareMetalCustomRunConfiguration(Target *target, Id id) : RunConfiguration(target, id) { const auto exeAspect = addAspect(target, ExecutableAspect::RunDevice); exeAspect->setSettingsKey("BareMetal.CustomRunConfig.Executable"); - exeAspect->setPlaceHolderText(tr("Unknown")); + exeAspect->setPlaceHolderText(Tr::tr("Unknown")); exeAspect->setDisplayStyle(StringAspect::PathChooserDisplay); exeAspect->setHistoryCompleter("BareMetal.CustomRunConfig.History"); exeAspect->setExpectedKind(PathChooser::Any); @@ -60,7 +57,8 @@ public: addAspect(macroExpander()); addAspect(macroExpander(), nullptr); - setDefaultDisplayName(RunConfigurationFactory::decoratedTargetName(tr("Custom Executable"), target)); + setDefaultDisplayName(RunConfigurationFactory::decoratedTargetName( + Tr::tr("Custom Executable"), target)); } public: @@ -71,8 +69,8 @@ Tasks BareMetalCustomRunConfiguration::checkForIssues() const { Tasks tasks; if (aspect()->executable().isEmpty()) { - tasks << createConfigurationIssue(tr("The remote executable must be set in order to run " - "a custom remote run configuration.")); + tasks << createConfigurationIssue(Tr::tr("The remote executable must be set in order to " + "run a custom remote run configuration.")); } return tasks; } @@ -89,12 +87,10 @@ BareMetalRunConfigurationFactory::BareMetalRunConfigurationFactory() // BaseMetalCustomRunConfigurationFactory BareMetalCustomRunConfigurationFactory::BareMetalCustomRunConfigurationFactory() - : FixedRunConfigurationFactory(BareMetalCustomRunConfiguration::tr("Custom Executable"), true) + : FixedRunConfigurationFactory(Tr::tr("Custom Executable"), true) { registerRunConfiguration("BareMetal"); addSupportedTargetDeviceType(BareMetal::Constants::BareMetalOsType); } -} // namespace Internal -} // namespace BareMetal - +} // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetalrunconfiguration.h b/src/plugins/baremetal/baremetalrunconfiguration.h index f050dde41d3..1d8e7d03fee 100644 --- a/src/plugins/baremetal/baremetalrunconfiguration.h +++ b/src/plugins/baremetal/baremetalrunconfiguration.h @@ -5,8 +5,7 @@ #include -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { class BareMetalRunConfigurationFactory final : public ProjectExplorer::RunConfigurationFactory @@ -22,5 +21,4 @@ public: BareMetalCustomRunConfigurationFactory(); }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugserverproviderchooser.cpp b/src/plugins/baremetal/debugserverproviderchooser.cpp index 1f51f0adbd4..76c8bb4bcaf 100644 --- a/src/plugins/baremetal/debugserverproviderchooser.cpp +++ b/src/plugins/baremetal/debugserverproviderchooser.cpp @@ -3,6 +3,7 @@ #include "baremetalconstants.h" +#include "baremetaltr.h" #include "debugserverproviderchooser.h" #include "debugserverprovidermanager.h" #include "idebugserverprovider.h" @@ -14,8 +15,7 @@ #include #include -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // DebugServerProviderChooser @@ -25,7 +25,7 @@ DebugServerProviderChooser::DebugServerProviderChooser( { m_chooser = new QComboBox(this); m_chooser->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - m_manageButton = new QPushButton(tr("Manage..."), this); + m_manageButton = new QPushButton(Tr::tr("Manage..."), this); m_manageButton->setEnabled(useManageButton); m_manageButton->setVisible(useManageButton); @@ -83,7 +83,7 @@ void DebugServerProviderChooser::populate() { const QSignalBlocker blocker(m_chooser); m_chooser->clear(); - m_chooser->addItem(tr("None")); + m_chooser->addItem(Tr::tr("None")); for (const IDebugServerProvider *p : DebugServerProviderManager::providers()) { if (!providerMatches(p)) @@ -92,5 +92,4 @@ void DebugServerProviderChooser::populate() } } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugserverproviderchooser.h b/src/plugins/baremetal/debugserverproviderchooser.h index dd537318f8b..938e6bf1831 100644 --- a/src/plugins/baremetal/debugserverproviderchooser.h +++ b/src/plugins/baremetal/debugserverproviderchooser.h @@ -10,13 +10,10 @@ class QComboBox; class QPushButton; QT_END_NAMESPACE -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { class IDebugServerProvider; -// DebugServerProviderChooser - class DebugServerProviderChooser final : public QWidget { Q_OBJECT @@ -42,5 +39,4 @@ private: QPushButton *m_manageButton = nullptr; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugserverprovidermanager.cpp b/src/plugins/baremetal/debugserverprovidermanager.cpp index 2ed256e47ae..e857e50620e 100644 --- a/src/plugins/baremetal/debugserverprovidermanager.cpp +++ b/src/plugins/baremetal/debugserverprovidermanager.cpp @@ -24,10 +24,7 @@ #include #include -#include - -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { const char dataKeyC[] = "DebugServerProvider."; const char countKeyC[] = "DebugServerProvider.Count"; @@ -199,5 +196,4 @@ void DebugServerProviderManager::deregisterProvider(IDebugServerProvider *provid delete provider; } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugserverprovidermanager.h b/src/plugins/baremetal/debugserverprovidermanager.h index adc12f0cda5..eb5f929a790 100644 --- a/src/plugins/baremetal/debugserverprovidermanager.h +++ b/src/plugins/baremetal/debugserverprovidermanager.h @@ -10,8 +10,7 @@ namespace Utils { class PersistentSettingsWriter; } -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { class BareMetalPlugin; class BareMetalPluginPrivate; @@ -59,5 +58,4 @@ private: friend class IDebugServerProvider; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugserverproviderssettingspage.cpp b/src/plugins/baremetal/debugserverproviderssettingspage.cpp index 47ce9549edf..5947102c6eb 100644 --- a/src/plugins/baremetal/debugserverproviderssettingspage.cpp +++ b/src/plugins/baremetal/debugserverproviderssettingspage.cpp @@ -1,10 +1,11 @@ // Copyright (C) 2016 Denis Shienkov // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -#include "baremetalconstants.h" - -#include "debugserverprovidermanager.h" #include "debugserverproviderssettingspage.h" + +#include "baremetalconstants.h" +#include "baremetaltr.h" +#include "debugserverprovidermanager.h" #include "idebugserverprovider.h" #include @@ -32,8 +33,7 @@ using namespace Debugger; using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // DebugServerProviderNode @@ -47,11 +47,11 @@ static QString engineTypeName(DebuggerEngineType engineType) { switch (engineType) { case NoEngineType: - return DebugServerProviderModel::tr("Not recognized"); + return Tr::tr("Not recognized"); case GdbEngineType: - return DebugServerProviderModel::tr("GDB"); + return Tr::tr("GDB"); case UvscEngineType: - return DebugServerProviderModel::tr("UVSC"); + return Tr::tr("UVSC"); default: return {}; } @@ -61,13 +61,13 @@ static QString engineTypeDescription(DebuggerEngineType engineType) { switch (engineType) { case NoEngineType: - return DebugServerProviderModel::tr("Not recognized"); + return Tr::tr("Not recognized"); case GdbEngineType: - return DebugServerProviderModel::tr("GDB compatible provider engine\n" \ - "(used together with the GDB debuggers)."); + return Tr::tr("GDB compatible provider engine\n" \ + "(used together with the GDB debuggers)."); case UvscEngineType: - return DebugServerProviderModel::tr("UVSC compatible provider engine\n" \ - "(used together with the KEIL uVision)."); + return Tr::tr("UVSC compatible provider engine\n" \ + "(used together with the KEIL uVision)."); default: return {}; } @@ -114,7 +114,7 @@ public: DebugServerProviderModel::DebugServerProviderModel() { - setHeader({tr("Name"), tr("Type"), tr("Engine")}); + setHeader({Tr::tr("Name"), Tr::tr("Type"), Tr::tr("Engine")}); const DebugServerProviderManager *manager = DebugServerProviderManager::instance(); @@ -175,8 +175,8 @@ void DebugServerProviderModel::apply() if (!skippedProviders.isEmpty()) { QMessageBox::warning(Core::ICore::dialogParent(), - tr("Duplicate Providers Detected"), - tr("The following providers were already configured:
" + Tr::tr("Duplicate Providers Detected"), + Tr::tr("The following providers were already configured:
" " %1
" "They were not configured again.") .arg(skippedProviders.join(",
 "))); @@ -254,8 +254,6 @@ void DebugServerProviderModel::removeProvider(IDebugServerProvider *provider) class DebugServerProvidersSettingsWidget final : public Core::IOptionsPageWidget { - Q_DECLARE_TR_FUNCTIONS(BareMetal::Internal::DebugServerProvidersSettingsPage) - public: DebugServerProvidersSettingsWidget(); @@ -284,9 +282,9 @@ DebugServerProvidersSettingsWidget::DebugServerProvidersSettingsWidget() m_providerView->setUniformRowHeights(true); m_providerView->header()->setStretchLastSection(false); - m_addButton = new QPushButton(tr("Add"), this); - m_cloneButton = new QPushButton(tr("Clone"), this); - m_delButton = new QPushButton(tr("Remove"), this); + m_addButton = new QPushButton(Tr::tr("Add"), this); + m_cloneButton = new QPushButton(Tr::tr("Clone"), this); + m_delButton = new QPushButton(Tr::tr("Remove"), this); m_container = new Utils::DetailsWidget(this); m_container->setState(Utils::DetailsWidget::NoSummary); @@ -310,7 +308,7 @@ DebugServerProvidersSettingsWidget::DebugServerProvidersSettingsWidget() horizontalLayout->addLayout(verticalLayout); horizontalLayout->addWidget(m_container); - const auto groupBox = new QGroupBox(tr("Debug Server Providers"), this); + const auto groupBox = new QGroupBox(Tr::tr("Debug Server Providers"), this); groupBox->setLayout(horizontalLayout); const auto topLayout = new QVBoxLayout(this); @@ -351,7 +349,7 @@ DebugServerProvidersSettingsWidget::DebugServerProvidersSettingsWidget() if (id.startsWith(f->id())) { IDebugServerProvider *p = f->create(); p->fromMap(old->toMap()); - p->setDisplayName(tr("Clone of %1").arg(old->displayName())); + p->setDisplayName(Tr::tr("Clone of %1").arg(old->displayName())); p->resetId(); addProviderToModel(p); } @@ -432,10 +430,9 @@ QModelIndex DebugServerProvidersSettingsWidget::currentIndex() const DebugServerProvidersSettingsPage::DebugServerProvidersSettingsPage() { setId(Constants::DEBUG_SERVER_PROVIDERS_SETTINGS_ID); - setDisplayName(DebugServerProvidersSettingsWidget::tr("Bare Metal")); + setDisplayName(Tr::tr("Bare Metal")); setCategory(ProjectExplorer::Constants::DEVICE_SETTINGS_CATEGORY); setWidgetCreator([] { return new DebugServerProvidersSettingsWidget; }); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugserverproviderssettingspage.h b/src/plugins/baremetal/debugserverproviderssettingspage.h index 999af0d2e7e..fc1633de53f 100644 --- a/src/plugins/baremetal/debugserverproviderssettingspage.h +++ b/src/plugins/baremetal/debugserverproviderssettingspage.h @@ -15,8 +15,7 @@ QT_END_NAMESPACE namespace Utils { class DetailsWidget; } -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { class DebugServerProviderNode; class DebugServerProvidersSettingsWidget; @@ -66,5 +65,4 @@ public: DebugServerProvidersSettingsPage(); }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/gdb/eblinkgdbserverprovider.cpp b/src/plugins/baremetal/debugservers/gdb/eblinkgdbserverprovider.cpp index 943eb71143c..4cb7949e638 100644 --- a/src/plugins/baremetal/debugservers/gdb/eblinkgdbserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/gdb/eblinkgdbserverprovider.cpp @@ -4,6 +4,7 @@ #include "eblinkgdbserverprovider.h" #include +#include #include #include @@ -16,13 +17,10 @@ #include #include #include -#include -#include using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { const char executableFileKeyC[] = "ExecutableFile"; const char verboseLevelKeyC[] = "VerboseLevel"; @@ -44,7 +42,7 @@ EBlinkGdbServerProvider::EBlinkGdbServerProvider() setInitCommands(defaultInitCommands()); setResetCommands(defaultResetCommands()); setChannel("127.0.0.1", 2331); - setTypeDisplayName(GdbServerProvider::tr("EBlink")); + setTypeDisplayName(Tr::tr("EBlink")); setConfigurationWidgetCreator([this] { return new EBlinkGdbServerProviderConfigWidget(this); }); } @@ -208,7 +206,7 @@ bool EBlinkGdbServerProvider::operator==(const IDebugServerProvider &other) cons EBlinkGdbServerProviderFactory::EBlinkGdbServerProviderFactory() { setId(Constants::GDBSERVER_EBLINK_PROVIDER_ID); - setDisplayName(GdbServerProvider::tr("EBlink")); + setDisplayName(Tr::tr("EBlink")); setCreator([] { return new EBlinkGdbServerProvider; }); } @@ -221,52 +219,52 @@ EBlinkGdbServerProviderConfigWidget::EBlinkGdbServerProviderConfigWidget( Q_ASSERT(p); m_gdbHostWidget = new HostWidget(this); - m_mainLayout->addRow(tr("Host:"), m_gdbHostWidget); + m_mainLayout->addRow(Tr::tr("Host:"), m_gdbHostWidget); m_executableFileChooser = new PathChooser; m_executableFileChooser->setExpectedKind(Utils::PathChooser::ExistingCommand); - m_mainLayout->addRow(tr("Executable file:"), m_executableFileChooser); + m_mainLayout->addRow(Tr::tr("Executable file:"), m_executableFileChooser); m_scriptFileChooser = new Utils::PathChooser; m_scriptFileChooser->setExpectedKind(Utils::PathChooser::File); m_scriptFileChooser->setPromptDialogFilter("*.script"); - m_mainLayout->addRow(tr("Script file:"), m_scriptFileChooser); + m_mainLayout->addRow(Tr::tr("Script file:"), m_scriptFileChooser); m_verboseLevelSpinBox = new QSpinBox; m_verboseLevelSpinBox->setRange(0, 7); m_verboseLevelSpinBox->setMaximumWidth(80); - m_verboseLevelSpinBox->setToolTip(tr("Specify the verbosity level (0 to 7).")); - m_mainLayout->addRow(tr("Verbosity level:"), m_verboseLevelSpinBox); + m_verboseLevelSpinBox->setToolTip(Tr::tr("Specify the verbosity level (0 to 7).")); + m_mainLayout->addRow(Tr::tr("Verbosity level:"), m_verboseLevelSpinBox); m_resetOnConnectCheckBox = new QCheckBox; - m_resetOnConnectCheckBox->setToolTip(tr("Connect under reset (hotplug).")); - m_mainLayout->addRow(tr("Connect under reset:"), m_resetOnConnectCheckBox); + m_resetOnConnectCheckBox->setToolTip(Tr::tr("Connect under reset (hotplug).")); + m_mainLayout->addRow(Tr::tr("Connect under reset:"), m_resetOnConnectCheckBox); m_interfaceTypeComboBox = new QComboBox; - m_interfaceTypeComboBox->setToolTip(tr("Interface type.")); - m_mainLayout->addRow(tr("Type:"), m_interfaceTypeComboBox); + m_interfaceTypeComboBox->setToolTip(Tr::tr("Interface type.")); + m_mainLayout->addRow(Tr::tr("Type:"), m_interfaceTypeComboBox); m_interfaceSpeedSpinBox = new QSpinBox; m_interfaceSpeedSpinBox->setRange(120, 8000); m_interfaceSpeedSpinBox->setMaximumWidth(120); - m_interfaceSpeedSpinBox->setToolTip(tr("Specify the speed of the interface (120 to 8000) in kilohertz (kHz).")); - m_mainLayout->addRow(tr("Speed:"), m_interfaceSpeedSpinBox); + m_interfaceSpeedSpinBox->setToolTip(Tr::tr("Specify the speed of the interface (120 to 8000) in kilohertz (kHz).")); + m_mainLayout->addRow(Tr::tr("Speed:"), m_interfaceSpeedSpinBox); m_notUseCacheCheckBox = new QCheckBox; - m_notUseCacheCheckBox->setToolTip(tr("Do not use EBlink flash cache.")); - m_mainLayout->addRow(tr("Disable cache:"), m_notUseCacheCheckBox); + m_notUseCacheCheckBox->setToolTip(Tr::tr("Do not use EBlink flash cache.")); + m_mainLayout->addRow(Tr::tr("Disable cache:"), m_notUseCacheCheckBox); m_shutDownAfterDisconnectCheckBox = new QCheckBox; m_shutDownAfterDisconnectCheckBox->setEnabled(false); - m_shutDownAfterDisconnectCheckBox->setToolTip(tr("Shut down EBlink server after disconnect.")); - m_mainLayout->addRow(tr("Auto shutdown:"), m_shutDownAfterDisconnectCheckBox); + m_shutDownAfterDisconnectCheckBox->setToolTip(Tr::tr("Shut down EBlink server after disconnect.")); + m_mainLayout->addRow(Tr::tr("Auto shutdown:"), m_shutDownAfterDisconnectCheckBox); m_initCommandsTextEdit = new QPlainTextEdit(this); m_initCommandsTextEdit->setToolTip(defaultInitCommandsTooltip()); - m_mainLayout->addRow(tr("Init commands:"), m_initCommandsTextEdit); + m_mainLayout->addRow(Tr::tr("Init commands:"), m_initCommandsTextEdit); m_resetCommandsTextEdit = new QPlainTextEdit(this); m_resetCommandsTextEdit->setToolTip(defaultResetCommandsTooltip()); - m_mainLayout->addRow(tr("Reset commands:"), m_resetCommandsTextEdit); + m_mainLayout->addRow(Tr::tr("Reset commands:"), m_resetCommandsTextEdit); populateInterfaceTypes(); addErrorLabel(); @@ -316,9 +314,9 @@ EBlinkGdbServerProviderConfigWidget::interfaceTypeFromWidget() const void EBlinkGdbServerProviderConfigWidget::populateInterfaceTypes() { - m_interfaceTypeComboBox->insertItem(EBlinkGdbServerProvider::SWD, tr("SWD"), + m_interfaceTypeComboBox->insertItem(EBlinkGdbServerProvider::SWD, Tr::tr("SWD"), EBlinkGdbServerProvider::SWD); - m_interfaceTypeComboBox->insertItem(EBlinkGdbServerProvider::JTAG, tr("JTAG"), + m_interfaceTypeComboBox->insertItem(EBlinkGdbServerProvider::JTAG, Tr::tr("JTAG"), EBlinkGdbServerProvider::JTAG); } @@ -368,5 +366,4 @@ void EBlinkGdbServerProviderConfigWidget::discard() GdbServerProviderConfigWidget::discard(); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/gdb/eblinkgdbserverprovider.h b/src/plugins/baremetal/debugservers/gdb/eblinkgdbserverprovider.h index 770e7ed1292..7432bc3c982 100644 --- a/src/plugins/baremetal/debugservers/gdb/eblinkgdbserverprovider.h +++ b/src/plugins/baremetal/debugservers/gdb/eblinkgdbserverprovider.h @@ -12,8 +12,7 @@ QT_END_NAMESPACE namespace Utils { class PathChooser; } -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // EBlinkGdbServerProvider @@ -71,8 +70,6 @@ public: class EBlinkGdbServerProviderConfigWidget final : public GdbServerProviderConfigWidget { - Q_OBJECT - public: explicit EBlinkGdbServerProviderConfigWidget( EBlinkGdbServerProvider *provider); @@ -101,6 +98,5 @@ private: QPlainTextEdit *m_resetCommandsTextEdit = nullptr; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp b/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp index b098aecbc1b..da3f8bcaca7 100644 --- a/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -22,8 +23,7 @@ using namespace Debugger; using namespace ProjectExplorer; using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { const char startupModeKeyC[] = "Mode"; const char peripheralDescriptionFileKeyC[] = "PeripheralDescriptionFile"; @@ -144,13 +144,11 @@ bool GdbServerProvider::aboutToRun(DebuggerRunTool *runTool, const FilePath bin = FilePath::fromString(exeAspect->executable.path()); if (bin.isEmpty()) { - errorMessage = BareMetalDebugSupport::tr( - "Cannot debug: Local executable is not set."); + errorMessage = Tr::tr("Cannot debug: Local executable is not set."); return false; } if (!bin.exists()) { - errorMessage = BareMetalDebugSupport::tr( - "Cannot debug: Could not find executable for \"%1\".") + errorMessage = Tr::tr("Cannot debug: Could not find executable for \"%1\".") .arg(bin.toString()); return false; } @@ -201,17 +199,17 @@ GdbServerProviderConfigWidget::GdbServerProviderConfigWidget( : IDebugServerProviderConfigWidget(provider) { m_startupModeComboBox = new QComboBox(this); - m_startupModeComboBox->setToolTip(tr("Choose the desired startup mode " - "of the GDB server provider.")); - m_mainLayout->addRow(tr("Startup mode:"), m_startupModeComboBox); + m_startupModeComboBox->setToolTip(Tr::tr("Choose the desired startup mode " + "of the GDB server provider.")); + m_mainLayout->addRow(Tr::tr("Startup mode:"), m_startupModeComboBox); m_peripheralDescriptionFileChooser = new PathChooser(this); m_peripheralDescriptionFileChooser->setExpectedKind(PathChooser::File); m_peripheralDescriptionFileChooser->setPromptDialogFilter( - tr("Peripheral description files (*.svd)")); + Tr::tr("Peripheral description files (*.svd)")); m_peripheralDescriptionFileChooser->setPromptDialogTitle( - tr("Select Peripheral Description File")); - m_mainLayout->addRow(tr("Peripheral description file:"), + Tr::tr("Select Peripheral Description File")); + m_mainLayout->addRow(Tr::tr("Peripheral description file:"), m_peripheralDescriptionFileChooser); populateStartupModes(); @@ -264,9 +262,9 @@ static QString startupModeName(GdbServerProvider::StartupMode m) { switch (m) { case GdbServerProvider::StartupOnNetwork: - return GdbServerProviderConfigWidget::tr("Startup in TCP/IP Mode"); + return Tr::tr("Startup in TCP/IP Mode"); case GdbServerProvider::StartupOnPipe: - return GdbServerProviderConfigWidget::tr("Startup in Pipe Mode"); + return Tr::tr("Startup in Pipe Mode"); default: return {}; } @@ -299,16 +297,14 @@ void GdbServerProviderConfigWidget::setFromProvider() QString GdbServerProviderConfigWidget::defaultInitCommandsTooltip() { - return QCoreApplication::translate("BareMetal", - "Enter GDB commands to reset the board " - "and to write the nonvolatile memory."); + return Tr::tr("Enter GDB commands to reset the board " + "and to write the nonvolatile memory."); } QString GdbServerProviderConfigWidget::defaultResetCommandsTooltip() { - return QCoreApplication::translate("BareMetal", - "Enter GDB commands to reset the hardware. " - "The MCU should be halted after these commands."); + return Tr::tr("Enter GDB commands to reset the hardware. " + "The MCU should be halted after these commands."); } // GdbServerProviderRunner @@ -325,5 +321,4 @@ GdbServerProviderRunner::GdbServerProviderRunner(ProjectExplorer::RunControl *ru }); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.h b/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.h index 3d707dbb299..8bf7211db1e 100644 --- a/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.h +++ b/src/plugins/baremetal/debugservers/gdb/gdbserverprovider.h @@ -7,23 +7,18 @@ #include -#include - QT_BEGIN_NAMESPACE class QComboBox; QT_END_NAMESPACE namespace Utils { class PathChooser; } -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // GdbServerProvider class GdbServerProvider : public IDebugServerProvider { - Q_DECLARE_TR_FUNCTIONS(BareMetal::Internal::GdbServerProvider) - public: enum StartupMode { StartupOnNetwork, @@ -75,8 +70,6 @@ protected: class GdbServerProviderConfigWidget : public IDebugServerProviderConfigWidget { - Q_OBJECT - public: explicit GdbServerProviderConfigWidget(GdbServerProvider *provider); void apply() override; @@ -107,5 +100,4 @@ public: const Utils::CommandLine &commandLine); }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/gdb/genericgdbserverprovider.cpp b/src/plugins/baremetal/debugservers/gdb/genericgdbserverprovider.cpp index fe25e567663..9bff7203d72 100644 --- a/src/plugins/baremetal/debugservers/gdb/genericgdbserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/gdb/genericgdbserverprovider.cpp @@ -4,6 +4,7 @@ #include "genericgdbserverprovider.h" #include +#include #include #include @@ -13,8 +14,7 @@ #include #include -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // GenericGdbServerProvider @@ -22,7 +22,7 @@ GenericGdbServerProvider::GenericGdbServerProvider() : GdbServerProvider(Constants::GDBSERVER_GENERIC_PROVIDER_ID) { setChannel("localhost", 3333); - setTypeDisplayName(GdbServerProvider::tr("Generic")); + setTypeDisplayName(Tr::tr("Generic")); setConfigurationWidgetCreator([this] { return new GenericGdbServerProviderConfigWidget(this); }); } @@ -36,7 +36,7 @@ QSet GenericGdbServerProvider::supportedStartupM GenericGdbServerProviderFactory::GenericGdbServerProviderFactory() { setId(Constants::GDBSERVER_GENERIC_PROVIDER_ID); - setDisplayName(GdbServerProvider::tr("Generic")); + setDisplayName(Tr::tr("Generic")); setCreator([] { return new GenericGdbServerProvider; }); } @@ -49,17 +49,17 @@ GenericGdbServerProviderConfigWidget::GenericGdbServerProviderConfigWidget( Q_ASSERT(provider); m_hostWidget = new HostWidget(this); - m_mainLayout->addRow(tr("Host:"), m_hostWidget); + m_mainLayout->addRow(Tr::tr("Host:"), m_hostWidget); m_useExtendedRemoteCheckBox = new QCheckBox(this); - m_useExtendedRemoteCheckBox->setToolTip("Use GDB target extended-remote"); - m_mainLayout->addRow(tr("Extended mode:"), m_useExtendedRemoteCheckBox); + m_useExtendedRemoteCheckBox->setToolTip(Tr::tr("Use GDB target extended-remote")); + m_mainLayout->addRow(Tr::tr("Extended mode:"), m_useExtendedRemoteCheckBox); m_initCommandsTextEdit = new QPlainTextEdit(this); m_initCommandsTextEdit->setToolTip(defaultInitCommandsTooltip()); - m_mainLayout->addRow(tr("Init commands:"), m_initCommandsTextEdit); + m_mainLayout->addRow(Tr::tr("Init commands:"), m_initCommandsTextEdit); m_resetCommandsTextEdit = new QPlainTextEdit(this); m_resetCommandsTextEdit->setToolTip(defaultResetCommandsTooltip()); - m_mainLayout->addRow(tr("Reset commands:"), m_resetCommandsTextEdit); + m_mainLayout->addRow(Tr::tr("Reset commands:"), m_resetCommandsTextEdit); addErrorLabel(); setFromProvider(); @@ -108,5 +108,4 @@ void GenericGdbServerProviderConfigWidget::setFromProvider() m_resetCommandsTextEdit->setPlainText(p->resetCommands()); } -} // namespace Internal -} // namespace ProjectExplorer +} // ProjectExplorer::Internal diff --git a/src/plugins/baremetal/debugservers/gdb/genericgdbserverprovider.h b/src/plugins/baremetal/debugservers/gdb/genericgdbserverprovider.h index 45d8b9c22d3..168d33b3370 100644 --- a/src/plugins/baremetal/debugservers/gdb/genericgdbserverprovider.h +++ b/src/plugins/baremetal/debugservers/gdb/genericgdbserverprovider.h @@ -10,8 +10,7 @@ class QCheckBox; class QPlainTextEdit; QT_END_NAMESPACE -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // GenericGdbServerProvider @@ -39,8 +38,6 @@ public: class GenericGdbServerProviderConfigWidget final : public GdbServerProviderConfigWidget { - Q_OBJECT - public: explicit GenericGdbServerProviderConfigWidget( GenericGdbServerProvider *provider); @@ -57,5 +54,4 @@ private: QPlainTextEdit *m_resetCommandsTextEdit = nullptr; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/gdb/jlinkgdbserverprovider.cpp b/src/plugins/baremetal/debugservers/gdb/jlinkgdbserverprovider.cpp index f40082a5c06..f8fecc9c869 100644 --- a/src/plugins/baremetal/debugservers/gdb/jlinkgdbserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/gdb/jlinkgdbserverprovider.cpp @@ -4,6 +4,7 @@ #include "jlinkgdbserverprovider.h" #include +#include #include #include @@ -21,8 +22,7 @@ using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { const char executableFileKeyC[] = "ExecutableFile"; const char jlinkDeviceKeyC[] = "JLinkDevice"; @@ -40,7 +40,7 @@ JLinkGdbServerProvider::JLinkGdbServerProvider() setInitCommands(defaultInitCommands()); setResetCommands(defaultResetCommands()); setChannel("localhost", 2331); - setTypeDisplayName(GdbServerProvider::tr("JLink")); + setTypeDisplayName(Tr::tr("JLink")); setConfigurationWidgetCreator([this] { return new JLinkGdbServerProviderConfigWidget(this); }); } @@ -166,7 +166,7 @@ bool JLinkGdbServerProvider::operator==(const IDebugServerProvider &other) const JLinkGdbServerProviderFactory::JLinkGdbServerProviderFactory() { setId(Constants::GDBSERVER_JLINK_PROVIDER_ID); - setDisplayName(GdbServerProvider::tr("JLink")); + setDisplayName(Tr::tr("JLink")); setCreator([] { return new JLinkGdbServerProvider; }); } @@ -179,58 +179,58 @@ JLinkGdbServerProviderConfigWidget::JLinkGdbServerProviderConfigWidget( Q_ASSERT(provider); m_hostWidget = new HostWidget(this); - m_mainLayout->addRow(tr("Host:"), m_hostWidget); + m_mainLayout->addRow(Tr::tr("Host:"), m_hostWidget); m_executableFileChooser = new Utils::PathChooser; m_executableFileChooser->setExpectedKind(Utils::PathChooser::ExistingCommand); m_executableFileChooser->setCommandVersionArguments({"--version"}); if (HostOsInfo::hostOs() == OsTypeWindows) { - m_executableFileChooser->setPromptDialogFilter(tr("JLink GDB Server (JLinkGDBServerCL.exe)")); + m_executableFileChooser->setPromptDialogFilter(Tr::tr("JLink GDB Server (JLinkGDBServerCL.exe)")); m_executableFileChooser->lineEdit()->setPlaceholderText("JLinkGDBServerCL.exe"); } else { - m_executableFileChooser->setPromptDialogFilter(tr("JLink GDB Server (JLinkGDBServer)")); + m_executableFileChooser->setPromptDialogFilter(Tr::tr("JLink GDB Server (JLinkGDBServer)")); m_executableFileChooser->lineEdit()->setPlaceholderText("JLinkGDBServer"); } - m_mainLayout->addRow(tr("Executable file:"), m_executableFileChooser); + m_mainLayout->addRow(Tr::tr("Executable file:"), m_executableFileChooser); // Host interface settings. m_hostInterfaceWidget = new QWidget(this); m_hostInterfaceComboBox = new QComboBox(m_hostInterfaceWidget); m_hostInterfaceAddressLabel = new QLabel(m_hostInterfaceWidget); - m_hostInterfaceAddressLabel->setText(tr("IP Address")); + m_hostInterfaceAddressLabel->setText(Tr::tr("IP Address")); m_hostInterfaceAddressLineEdit = new QLineEdit(m_hostInterfaceWidget); const auto hostInterfaceLayout = new QHBoxLayout(m_hostInterfaceWidget); hostInterfaceLayout->setContentsMargins(0, 0, 0, 0); hostInterfaceLayout->addWidget(m_hostInterfaceComboBox); hostInterfaceLayout->addWidget(m_hostInterfaceAddressLabel); hostInterfaceLayout->addWidget(m_hostInterfaceAddressLineEdit); - m_mainLayout->addRow(tr("Host interface:"), m_hostInterfaceWidget); + m_mainLayout->addRow(Tr::tr("Host interface:"), m_hostInterfaceWidget); // Target interface settings. m_targetInterfaceWidget = new QWidget(this); m_targetInterfaceComboBox = new QComboBox(m_targetInterfaceWidget); m_targetInterfaceSpeedLabel = new QLabel(m_targetInterfaceWidget); - m_targetInterfaceSpeedLabel->setText(tr("Speed")); + m_targetInterfaceSpeedLabel->setText(Tr::tr("Speed")); m_targetInterfaceSpeedComboBox = new QComboBox(m_targetInterfaceWidget); const auto targetInterfaceLayout = new QHBoxLayout(m_targetInterfaceWidget); targetInterfaceLayout->setContentsMargins(0, 0, 0, 0); targetInterfaceLayout->addWidget(m_targetInterfaceComboBox); targetInterfaceLayout->addWidget(m_targetInterfaceSpeedLabel); targetInterfaceLayout->addWidget(m_targetInterfaceSpeedComboBox); - m_mainLayout->addRow(tr("Target interface:"), m_targetInterfaceWidget); + m_mainLayout->addRow(Tr::tr("Target interface:"), m_targetInterfaceWidget); m_jlinkDeviceLineEdit = new QLineEdit(this); - m_mainLayout->addRow(tr("Device:"), m_jlinkDeviceLineEdit); + m_mainLayout->addRow(Tr::tr("Device:"), m_jlinkDeviceLineEdit); m_additionalArgumentsTextEdit = new QPlainTextEdit(this); - m_mainLayout->addRow(tr("Additional arguments:"), m_additionalArgumentsTextEdit); + m_mainLayout->addRow(Tr::tr("Additional arguments:"), m_additionalArgumentsTextEdit); m_initCommandsTextEdit = new QPlainTextEdit(this); m_initCommandsTextEdit->setToolTip(defaultInitCommandsTooltip()); - m_mainLayout->addRow(tr("Init commands:"), m_initCommandsTextEdit); + m_mainLayout->addRow(Tr::tr("Init commands:"), m_initCommandsTextEdit); m_resetCommandsTextEdit = new QPlainTextEdit(this); m_resetCommandsTextEdit->setToolTip(defaultResetCommandsTooltip()); - m_mainLayout->addRow(tr("Reset commands:"), m_resetCommandsTextEdit); + m_mainLayout->addRow(Tr::tr("Reset commands:"), m_resetCommandsTextEdit); populateHostInterfaces(); populateTargetInterfaces(); @@ -297,26 +297,26 @@ void JLinkGdbServerProviderConfigWidget::discard() void JLinkGdbServerProviderConfigWidget::populateHostInterfaces() { - m_hostInterfaceComboBox->addItem(tr("Default")); - m_hostInterfaceComboBox->addItem(tr("USB"), "USB"); - m_hostInterfaceComboBox->addItem(tr("TCP/IP"), "IP"); + m_hostInterfaceComboBox->addItem(Tr::tr("Default")); + m_hostInterfaceComboBox->addItem(Tr::tr("USB"), "USB"); + m_hostInterfaceComboBox->addItem(Tr::tr("TCP/IP"), "IP"); } void JLinkGdbServerProviderConfigWidget::populateTargetInterfaces() { - m_targetInterfaceComboBox->addItem(tr("Default")); - m_targetInterfaceComboBox->addItem(tr("JTAG"), "JTAG"); - m_targetInterfaceComboBox->addItem(tr("Compact JTAG"), "cJTAG"); - m_targetInterfaceComboBox->addItem(tr("SWD"), "SWD"); - m_targetInterfaceComboBox->addItem(tr("Renesas RX FINE"), "FINE"); - m_targetInterfaceComboBox->addItem(tr("ICSP"), "ICSP"); + m_targetInterfaceComboBox->addItem(Tr::tr("Default")); + m_targetInterfaceComboBox->addItem(Tr::tr("JTAG"), "JTAG"); + m_targetInterfaceComboBox->addItem(Tr::tr("Compact JTAG"), "cJTAG"); + m_targetInterfaceComboBox->addItem(Tr::tr("SWD"), "SWD"); + m_targetInterfaceComboBox->addItem(Tr::tr("Renesas RX FINE"), "FINE"); + m_targetInterfaceComboBox->addItem(Tr::tr("ICSP"), "ICSP"); } void JLinkGdbServerProviderConfigWidget::populateTargetSpeeds() { - m_targetInterfaceSpeedComboBox->addItem(tr("Default")); - m_targetInterfaceSpeedComboBox->addItem(tr("Auto"), "auto"); - m_targetInterfaceSpeedComboBox->addItem(tr("Adaptive"), "adaptive"); + m_targetInterfaceSpeedComboBox->addItem(Tr::tr("Default")); + m_targetInterfaceSpeedComboBox->addItem(Tr::tr("Auto"), "auto"); + m_targetInterfaceSpeedComboBox->addItem(Tr::tr("Adaptive"), "adaptive"); const QStringList fixedSpeeds = {"1", "5", "10", "20", "30", "50", "100", "200", "300", "400", "500", "600", "750", "800", "900", "1000", "1334", @@ -324,7 +324,7 @@ void JLinkGdbServerProviderConfigWidget::populateTargetSpeeds() "6000", "8000", "9600", "12000", "15000", "20000", "25000", "30000", "40000", "50000"}; for (const auto &fixedSpeed : fixedSpeeds) - m_targetInterfaceSpeedComboBox->addItem(tr("%1 kHz").arg(fixedSpeed), fixedSpeed); + m_targetInterfaceSpeedComboBox->addItem(Tr::tr("%1 kHz").arg(fixedSpeed), fixedSpeed); } void JLinkGdbServerProviderConfigWidget::setHostInterface(const QString &newIface) @@ -388,7 +388,6 @@ void JLinkGdbServerProviderConfigWidget::setFromProvider() m_hostInterfaceAddressLineEdit->setText(p->m_jlinkHostAddr); m_hostWidget->setChannel(p->channel()); m_initCommandsTextEdit->setPlainText(p->initCommands()); - m_jlinkDeviceLineEdit->setText( p->m_jlinkDevice); m_jlinkDeviceLineEdit->setText(p->m_jlinkDevice); m_resetCommandsTextEdit->setPlainText(p->resetCommands()); @@ -399,5 +398,4 @@ void JLinkGdbServerProviderConfigWidget::setFromProvider() updateAllowedControls(); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/gdb/jlinkgdbserverprovider.h b/src/plugins/baremetal/debugservers/gdb/jlinkgdbserverprovider.h index 953f6e7de04..6cc33f14854 100644 --- a/src/plugins/baremetal/debugservers/gdb/jlinkgdbserverprovider.h +++ b/src/plugins/baremetal/debugservers/gdb/jlinkgdbserverprovider.h @@ -11,8 +11,7 @@ QT_END_NAMESPACE namespace Utils { class PathChooser; } -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // JLinkGdbServerProvider @@ -62,11 +61,8 @@ public: class JLinkGdbServerProviderConfigWidget final : public GdbServerProviderConfigWidget { - Q_OBJECT - public: - explicit JLinkGdbServerProviderConfigWidget( - JLinkGdbServerProvider *provider); + explicit JLinkGdbServerProviderConfigWidget(JLinkGdbServerProvider *provider); private: void apply() final; @@ -103,5 +99,4 @@ private: QPlainTextEdit *m_resetCommandsTextEdit = nullptr; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/gdb/openocdgdbserverprovider.cpp b/src/plugins/baremetal/debugservers/gdb/openocdgdbserverprovider.cpp index 6879d8a5346..97cad3cad1c 100644 --- a/src/plugins/baremetal/debugservers/gdb/openocdgdbserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/gdb/openocdgdbserverprovider.cpp @@ -4,6 +4,7 @@ #include "openocdgdbserverprovider.h" #include +#include #include #include @@ -19,8 +20,7 @@ using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { const char executableFileKeyC[] = "ExecutableFile"; const char rootScriptsDirKeyC[] = "RootScriptsDir"; @@ -35,7 +35,7 @@ OpenOcdGdbServerProvider::OpenOcdGdbServerProvider() setInitCommands(defaultInitCommands()); setResetCommands(defaultResetCommands()); setChannel("localhost", 3333); - setTypeDisplayName(GdbServerProvider::tr("OpenOCD")); + setTypeDisplayName(Tr::tr("OpenOCD")); setConfigurationWidgetCreator([this] { return new OpenOcdGdbServerProviderConfigWidget(this); }); } @@ -164,7 +164,7 @@ bool OpenOcdGdbServerProvider::operator==(const IDebugServerProvider &other) con OpenOcdGdbServerProviderFactory::OpenOcdGdbServerProviderFactory() { setId(Constants::GDBSERVER_OPENOCD_PROVIDER_ID); - setDisplayName(GdbServerProvider::tr("OpenOCD")); + setDisplayName(Tr::tr("OpenOCD")); setCreator([] { return new OpenOcdGdbServerProvider; }); } @@ -177,31 +177,31 @@ OpenOcdGdbServerProviderConfigWidget::OpenOcdGdbServerProviderConfigWidget( Q_ASSERT(provider); m_hostWidget = new HostWidget(this); - m_mainLayout->addRow(tr("Host:"), m_hostWidget); + m_mainLayout->addRow(Tr::tr("Host:"), m_hostWidget); m_executableFileChooser = new Utils::PathChooser; m_executableFileChooser->setExpectedKind(Utils::PathChooser::ExistingCommand); m_executableFileChooser->setCommandVersionArguments({"--version"}); - m_mainLayout->addRow(tr("Executable file:"), m_executableFileChooser); + m_mainLayout->addRow(Tr::tr("Executable file:"), m_executableFileChooser); m_rootScriptsDirChooser = new Utils::PathChooser; m_rootScriptsDirChooser->setExpectedKind(Utils::PathChooser::Directory); - m_mainLayout->addRow(tr("Root scripts directory:"), m_rootScriptsDirChooser); + m_mainLayout->addRow(Tr::tr("Root scripts directory:"), m_rootScriptsDirChooser); m_configurationFileChooser = new Utils::PathChooser; m_configurationFileChooser->setExpectedKind(Utils::PathChooser::File); m_configurationFileChooser->setPromptDialogFilter("*.cfg"); - m_mainLayout->addRow(tr("Configuration file:"), m_configurationFileChooser); + m_mainLayout->addRow(Tr::tr("Configuration file:"), m_configurationFileChooser); m_additionalArgumentsLineEdit = new QLineEdit(this); - m_mainLayout->addRow(tr("Additional arguments:"), m_additionalArgumentsLineEdit); + m_mainLayout->addRow(Tr::tr("Additional arguments:"), m_additionalArgumentsLineEdit); m_initCommandsTextEdit = new QPlainTextEdit(this); m_initCommandsTextEdit->setToolTip(defaultInitCommandsTooltip()); - m_mainLayout->addRow(tr("Init commands:"), m_initCommandsTextEdit); + m_mainLayout->addRow(Tr::tr("Init commands:"), m_initCommandsTextEdit); m_resetCommandsTextEdit = new QPlainTextEdit(this); m_resetCommandsTextEdit->setToolTip(defaultResetCommandsTooltip()); - m_mainLayout->addRow(tr("Reset commands:"), m_resetCommandsTextEdit); + m_mainLayout->addRow(Tr::tr("Reset commands:"), m_resetCommandsTextEdit); addErrorLabel(); setFromProvider(); @@ -274,5 +274,4 @@ void OpenOcdGdbServerProviderConfigWidget::setFromProvider() m_resetCommandsTextEdit->setPlainText(p->resetCommands()); } -} // namespace Internal -} // namespace ProjectExplorer +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/gdb/openocdgdbserverprovider.h b/src/plugins/baremetal/debugservers/gdb/openocdgdbserverprovider.h index 1e99ab31b17..06050e33339 100644 --- a/src/plugins/baremetal/debugservers/gdb/openocdgdbserverprovider.h +++ b/src/plugins/baremetal/debugservers/gdb/openocdgdbserverprovider.h @@ -11,8 +11,7 @@ QT_END_NAMESPACE namespace Utils { class PathChooser; } -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // OpenOcdGdbServerProvider @@ -59,11 +58,8 @@ public: class OpenOcdGdbServerProviderConfigWidget final : public GdbServerProviderConfigWidget { - Q_OBJECT - public: - explicit OpenOcdGdbServerProviderConfigWidget( - OpenOcdGdbServerProvider *provider); + explicit OpenOcdGdbServerProviderConfigWidget(OpenOcdGdbServerProvider *provider); private: void apply() final; @@ -81,5 +77,4 @@ private: QPlainTextEdit *m_resetCommandsTextEdit = nullptr; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/gdb/stlinkutilgdbserverprovider.cpp b/src/plugins/baremetal/debugservers/gdb/stlinkutilgdbserverprovider.cpp index c297685235d..5f51e49d6a8 100644 --- a/src/plugins/baremetal/debugservers/gdb/stlinkutilgdbserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/gdb/stlinkutilgdbserverprovider.cpp @@ -4,9 +4,10 @@ #include "stlinkutilgdbserverprovider.h" #include +#include #include -#include +#include #include #include #include @@ -19,8 +20,7 @@ using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { const char executableFileKeyC[] = "ExecutableFile"; const char verboseLevelKeyC[] = "VerboseLevel"; @@ -36,7 +36,7 @@ StLinkUtilGdbServerProvider::StLinkUtilGdbServerProvider() setInitCommands(defaultInitCommands()); setResetCommands(defaultResetCommands()); setChannel("localhost", 4242); - setTypeDisplayName(GdbServerProvider::tr("ST-LINK Utility")); + setTypeDisplayName(Tr::tr("ST-LINK Utility")); setConfigurationWidgetCreator([this] { return new StLinkUtilGdbServerProviderConfigWidget(this); }); } @@ -151,7 +151,7 @@ bool StLinkUtilGdbServerProvider::operator==(const IDebugServerProvider &other) StLinkUtilGdbServerProviderFactory::StLinkUtilGdbServerProviderFactory() { setId(Constants::GDBSERVER_STLINK_UTIL_PROVIDER_ID); - setDisplayName(GdbServerProvider::tr("ST-LINK Utility")); + setDisplayName(Tr::tr("ST-LINK Utility")); setCreator([] { return new StLinkUtilGdbServerProvider; }); } @@ -164,36 +164,36 @@ StLinkUtilGdbServerProviderConfigWidget::StLinkUtilGdbServerProviderConfigWidget Q_ASSERT(p); m_hostWidget = new HostWidget(this); - m_mainLayout->addRow(tr("Host:"), m_hostWidget); + m_mainLayout->addRow(Tr::tr("Host:"), m_hostWidget); m_executableFileChooser = new Utils::PathChooser; m_executableFileChooser->setExpectedKind(Utils::PathChooser::ExistingCommand); - m_mainLayout->addRow(tr("Executable file:"), m_executableFileChooser); + m_mainLayout->addRow(Tr::tr("Executable file:"), m_executableFileChooser); m_verboseLevelSpinBox = new QSpinBox; m_verboseLevelSpinBox->setRange(0, 99); - m_verboseLevelSpinBox->setToolTip(tr("Specify the verbosity level (0..99).")); - m_mainLayout->addRow(tr("Verbosity level:"), m_verboseLevelSpinBox); + m_verboseLevelSpinBox->setToolTip(Tr::tr("Specify the verbosity level (0..99).")); + m_mainLayout->addRow(Tr::tr("Verbosity level:"), m_verboseLevelSpinBox); m_extendedModeCheckBox = new QCheckBox; - m_extendedModeCheckBox->setToolTip(tr("Continue listening for connections " + m_extendedModeCheckBox->setToolTip(Tr::tr("Continue listening for connections " "after disconnect.")); - m_mainLayout->addRow(tr("Extended mode:"), m_extendedModeCheckBox); + m_mainLayout->addRow(Tr::tr("Extended mode:"), m_extendedModeCheckBox); m_resetBoardCheckBox = new QCheckBox; - m_resetBoardCheckBox->setToolTip(tr("Reset board on connection.")); - m_mainLayout->addRow(tr("Reset on connection:"), m_resetBoardCheckBox); + m_resetBoardCheckBox->setToolTip(Tr::tr("Reset board on connection.")); + m_mainLayout->addRow(Tr::tr("Reset on connection:"), m_resetBoardCheckBox); m_transportLayerComboBox = new QComboBox; - m_transportLayerComboBox->setToolTip(tr("Transport layer type.")); - m_mainLayout->addRow(tr("Version:"), m_transportLayerComboBox); + m_transportLayerComboBox->setToolTip(Tr::tr("Transport layer type.")); + m_mainLayout->addRow(Tr::tr("Version:"), m_transportLayerComboBox); m_initCommandsTextEdit = new QPlainTextEdit(this); m_initCommandsTextEdit->setToolTip(defaultInitCommandsTooltip()); - m_mainLayout->addRow(tr("Init commands:"), m_initCommandsTextEdit); + m_mainLayout->addRow(Tr::tr("Init commands:"), m_initCommandsTextEdit); m_resetCommandsTextEdit = new QPlainTextEdit(this); m_resetCommandsTextEdit->setToolTip(defaultResetCommandsTooltip()); - m_mainLayout->addRow(tr("Reset commands:"), m_resetCommandsTextEdit); + m_mainLayout->addRow(Tr::tr("Reset commands:"), m_resetCommandsTextEdit); populateTransportLayers(); addErrorLabel(); @@ -273,13 +273,13 @@ void StLinkUtilGdbServerProviderConfigWidget::setTransportLayer( void StLinkUtilGdbServerProviderConfigWidget::populateTransportLayers() { m_transportLayerComboBox->insertItem( - m_transportLayerComboBox->count(), tr("ST-LINK/V1"), + m_transportLayerComboBox->count(), Tr::tr("ST-LINK/V1"), StLinkUtilGdbServerProvider::ScsiOverUsb); m_transportLayerComboBox->insertItem( - m_transportLayerComboBox->count(), tr("ST-LINK/V2"), + m_transportLayerComboBox->count(), Tr::tr("ST-LINK/V2"), StLinkUtilGdbServerProvider::RawUsb); m_transportLayerComboBox->insertItem( - m_transportLayerComboBox->count(), tr("Keep unspecified"), + m_transportLayerComboBox->count(), Tr::tr("Keep unspecified"), StLinkUtilGdbServerProvider::UnspecifiedTransport); } @@ -299,5 +299,4 @@ void StLinkUtilGdbServerProviderConfigWidget::setFromProvider() m_resetCommandsTextEdit->setPlainText(p->resetCommands()); } -} // namespace Internal -} // namespace ProjectExplorer +} // ProjectExplorer::Internal diff --git a/src/plugins/baremetal/debugservers/gdb/stlinkutilgdbserverprovider.h b/src/plugins/baremetal/debugservers/gdb/stlinkutilgdbserverprovider.h index b8721dc7547..c6c72e01342 100644 --- a/src/plugins/baremetal/debugservers/gdb/stlinkutilgdbserverprovider.h +++ b/src/plugins/baremetal/debugservers/gdb/stlinkutilgdbserverprovider.h @@ -12,8 +12,7 @@ QT_END_NAMESPACE namespace Utils { class PathChooser; } -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // StLinkUtilGdbServerProvider @@ -63,11 +62,8 @@ public: class StLinkUtilGdbServerProviderConfigWidget final : public GdbServerProviderConfigWidget { - Q_OBJECT - public: - explicit StLinkUtilGdbServerProviderConfigWidget( - StLinkUtilGdbServerProvider *provider); + explicit StLinkUtilGdbServerProviderConfigWidget(StLinkUtilGdbServerProvider *provider); private: void apply() final; @@ -90,5 +86,4 @@ private: QPlainTextEdit *m_resetCommandsTextEdit = nullptr; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/uvsc/jlinkuvscserverprovider.cpp b/src/plugins/baremetal/debugservers/uvsc/jlinkuvscserverprovider.cpp index 6a9ead2ca9f..17ef097e8c3 100644 --- a/src/plugins/baremetal/debugservers/uvsc/jlinkuvscserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/jlinkuvscserverprovider.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -25,8 +26,7 @@ using namespace Debugger; using namespace ProjectExplorer; using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { using namespace Uv; @@ -155,7 +155,7 @@ bool JLinkUvscAdapterOptions::operator==(const JLinkUvscAdapterOptions &other) c JLinkUvscServerProvider::JLinkUvscServerProvider() : UvscServerProvider(Constants::UVSC_JLINK_PROVIDER_ID) { - setTypeDisplayName(UvscServerProvider::tr("uVision JLink")); + setTypeDisplayName(Tr::tr("uVision JLink")); setConfigurationWidgetCreator([this] { return new JLinkUvscServerProviderConfigWidget(this); }); setSupportedDrivers({"Segger\\JL2CM3.dll"}); } @@ -192,8 +192,7 @@ FilePath JLinkUvscServerProvider::optionsFilePath(DebuggerRunTool *runTool, Uv::ProjectOptionsWriter writer(&ofs); const JLinkUvProjectOptions projectOptions(this); if (!writer.write(&projectOptions)) { - errorMessage = BareMetalDebugSupport::tr( - "Unable to create a uVision project options template."); + errorMessage = Tr::tr("Unable to create a uVision project options template."); return {}; } return optionsPath; @@ -204,7 +203,7 @@ FilePath JLinkUvscServerProvider::optionsFilePath(DebuggerRunTool *runTool, JLinkUvscServerProviderFactory::JLinkUvscServerProviderFactory() { setId(Constants::UVSC_JLINK_PROVIDER_ID); - setDisplayName(UvscServerProvider::tr("uVision JLink")); + setDisplayName(Tr::tr("uVision JLink")); setCreator([] { return new JLinkUvscServerProvider; }); } @@ -217,7 +216,7 @@ JLinkUvscServerProviderConfigWidget::JLinkUvscServerProviderConfigWidget( Q_ASSERT(p); m_adapterOptionsWidget = new JLinkUvscAdapterOptionsWidget; - m_mainLayout->addRow(tr("Adapter options:"), m_adapterOptionsWidget); + m_mainLayout->addRow(Tr::tr("Adapter options:"), m_adapterOptionsWidget); setFromProvider(); @@ -265,10 +264,10 @@ JLinkUvscAdapterOptionsWidget::JLinkUvscAdapterOptionsWidget(QWidget *parent) { const auto layout = new QHBoxLayout; layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(new QLabel(tr("Port:"))); + layout->addWidget(new QLabel(Tr::tr("Port:"))); m_portBox = new QComboBox; layout->addWidget(m_portBox); - layout->addWidget(new QLabel(tr("Speed:"))); + layout->addWidget(new QLabel(Tr::tr("Speed:"))); m_speedBox = new QComboBox; layout->addWidget(m_speedBox); setLayout(layout); @@ -324,26 +323,25 @@ JLinkUvscAdapterOptions::Speed JLinkUvscAdapterOptionsWidget::speedAt(int index) void JLinkUvscAdapterOptionsWidget::populatePorts() { - m_portBox->addItem(tr("JTAG"), JLinkUvscAdapterOptions::JTAG); - m_portBox->addItem(tr("SWD"), JLinkUvscAdapterOptions::SWD); + m_portBox->addItem(Tr::tr("JTAG"), JLinkUvscAdapterOptions::JTAG); + m_portBox->addItem(Tr::tr("SWD"), JLinkUvscAdapterOptions::SWD); } void JLinkUvscAdapterOptionsWidget::populateSpeeds() { m_speedBox->clear(); - m_speedBox->addItem(tr("50MHz"), JLinkUvscAdapterOptions::Speed_50MHz); - m_speedBox->addItem(tr("33MHz"), JLinkUvscAdapterOptions::Speed_33MHz); - m_speedBox->addItem(tr("25MHz"), JLinkUvscAdapterOptions::Speed_25MHz); - m_speedBox->addItem(tr("20MHz"), JLinkUvscAdapterOptions::Speed_20MHz); - m_speedBox->addItem(tr("10MHz"), JLinkUvscAdapterOptions::Speed_10MHz); - m_speedBox->addItem(tr("5MHz"), JLinkUvscAdapterOptions::Speed_5MHz); - m_speedBox->addItem(tr("3MHz"), JLinkUvscAdapterOptions::Speed_3MHz); - m_speedBox->addItem(tr("2MHz"), JLinkUvscAdapterOptions::Speed_2MHz); - m_speedBox->addItem(tr("1MHz"), JLinkUvscAdapterOptions::Speed_1MHz); - m_speedBox->addItem(tr("500kHz"), JLinkUvscAdapterOptions::Speed_500kHz); - m_speedBox->addItem(tr("200kHz"), JLinkUvscAdapterOptions::Speed_200kHz); - m_speedBox->addItem(tr("100kHz"), JLinkUvscAdapterOptions::Speed_100kHz); + m_speedBox->addItem(Tr::tr("50MHz"), JLinkUvscAdapterOptions::Speed_50MHz); + m_speedBox->addItem(Tr::tr("33MHz"), JLinkUvscAdapterOptions::Speed_33MHz); + m_speedBox->addItem(Tr::tr("25MHz"), JLinkUvscAdapterOptions::Speed_25MHz); + m_speedBox->addItem(Tr::tr("20MHz"), JLinkUvscAdapterOptions::Speed_20MHz); + m_speedBox->addItem(Tr::tr("10MHz"), JLinkUvscAdapterOptions::Speed_10MHz); + m_speedBox->addItem(Tr::tr("5MHz"), JLinkUvscAdapterOptions::Speed_5MHz); + m_speedBox->addItem(Tr::tr("3MHz"), JLinkUvscAdapterOptions::Speed_3MHz); + m_speedBox->addItem(Tr::tr("2MHz"), JLinkUvscAdapterOptions::Speed_2MHz); + m_speedBox->addItem(Tr::tr("1MHz"), JLinkUvscAdapterOptions::Speed_1MHz); + m_speedBox->addItem(Tr::tr("500kHz"), JLinkUvscAdapterOptions::Speed_500kHz); + m_speedBox->addItem(Tr::tr("200kHz"), JLinkUvscAdapterOptions::Speed_200kHz); + m_speedBox->addItem(Tr::tr("100kHz"), JLinkUvscAdapterOptions::Speed_100kHz); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/uvsc/jlinkuvscserverprovider.h b/src/plugins/baremetal/debugservers/uvsc/jlinkuvscserverprovider.h index f611eaa4994..9fa2c3cda7f 100644 --- a/src/plugins/baremetal/debugservers/uvsc/jlinkuvscserverprovider.h +++ b/src/plugins/baremetal/debugservers/uvsc/jlinkuvscserverprovider.h @@ -9,8 +9,7 @@ QT_BEGIN_NAMESPACE class QComboBox; QT_END_NAMESPACE -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // JLinkUvscAdapterOptions @@ -66,8 +65,6 @@ public: class JLinkUvscAdapterOptionsWidget; class JLinkUvscServerProviderConfigWidget final : public UvscServerProviderConfigWidget { - Q_OBJECT - public: explicit JLinkUvscServerProviderConfigWidget(JLinkUvscServerProvider *provider); @@ -107,5 +104,4 @@ private: QComboBox *m_speedBox = nullptr; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/uvsc/simulatoruvscserverprovider.cpp b/src/plugins/baremetal/debugservers/uvsc/simulatoruvscserverprovider.cpp index d1837ca24ce..e6e2150b2c5 100644 --- a/src/plugins/baremetal/debugservers/uvsc/simulatoruvscserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/simulatoruvscserverprovider.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -23,8 +24,7 @@ using namespace Debugger; using namespace ProjectExplorer; using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { using namespace Uv; @@ -60,7 +60,7 @@ public: SimulatorUvscServerProvider::SimulatorUvscServerProvider() : UvscServerProvider(Constants::UVSC_SIMULATOR_PROVIDER_ID) { - setTypeDisplayName(UvscServerProvider::tr("uVision Simulator")); + setTypeDisplayName(Tr::tr("uVision Simulator")); setConfigurationWidgetCreator([this] { return new SimulatorUvscServerProviderConfigWidget(this); }); setDriverSelection(defaultSimulatorDriverSelection()); } @@ -96,8 +96,7 @@ FilePath SimulatorUvscServerProvider::optionsFilePath(DebuggerRunTool *runTool, Uv::ProjectOptionsWriter writer(&ofs); const SimulatorUvProjectOptions projectOptions(this); if (!writer.write(&projectOptions)) { - errorMessage = BareMetalDebugSupport::tr( - "Unable to create a uVision project options template."); + errorMessage = Tr::tr("Unable to create a uVision project options template."); return {}; } return optionsPath; @@ -108,7 +107,7 @@ FilePath SimulatorUvscServerProvider::optionsFilePath(DebuggerRunTool *runTool, SimulatorUvscServerProviderFactory::SimulatorUvscServerProviderFactory() { setId(Constants::UVSC_SIMULATOR_PROVIDER_ID); - setDisplayName(UvscServerProvider::tr("uVision Simulator")); + setDisplayName(Tr::tr("uVision Simulator")); setCreator([] { return new SimulatorUvscServerProvider; }); } @@ -121,8 +120,8 @@ SimulatorUvscServerProviderConfigWidget::SimulatorUvscServerProviderConfigWidget Q_ASSERT(p); m_limitSpeedCheckBox = new QCheckBox; - m_limitSpeedCheckBox->setToolTip(tr("Limit speed to real-time.")); - m_mainLayout->addRow(tr("Limit speed to real-time:"), m_limitSpeedCheckBox); + m_limitSpeedCheckBox->setToolTip(Tr::tr("Limit speed to real-time.")); + m_mainLayout->addRow(Tr::tr("Limit speed to real-time:"), m_limitSpeedCheckBox); setFromProvider(); @@ -152,5 +151,4 @@ void SimulatorUvscServerProviderConfigWidget::setFromProvider() m_limitSpeedCheckBox->setChecked(p->m_limitSpeed); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/uvsc/simulatoruvscserverprovider.h b/src/plugins/baremetal/debugservers/uvsc/simulatoruvscserverprovider.h index ac9448b6aa3..619ea11ee4a 100644 --- a/src/plugins/baremetal/debugservers/uvsc/simulatoruvscserverprovider.h +++ b/src/plugins/baremetal/debugservers/uvsc/simulatoruvscserverprovider.h @@ -9,8 +9,7 @@ QT_BEGIN_NAMESPACE class QCheckBox; QT_END_NAMESPACE -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // SimulatorUvscServerProvider @@ -48,8 +47,6 @@ public: class SimulatorUvscServerProviderConfigWidget final : public UvscServerProviderConfigWidget { - Q_OBJECT - public: explicit SimulatorUvscServerProviderConfigWidget(SimulatorUvscServerProvider *provider); @@ -62,5 +59,4 @@ private: QCheckBox *m_limitSpeedCheckBox = nullptr; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/uvsc/stlinkuvscserverprovider.cpp b/src/plugins/baremetal/debugservers/uvsc/stlinkuvscserverprovider.cpp index 0a41099fb1c..fec0d55cd76 100644 --- a/src/plugins/baremetal/debugservers/uvsc/stlinkuvscserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/stlinkuvscserverprovider.cpp @@ -7,6 +7,7 @@ #include "uvprojectwriter.h" #include +#include #include #include @@ -25,8 +26,7 @@ using namespace Debugger; using namespace ProjectExplorer; using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { using namespace Uv; @@ -111,7 +111,7 @@ bool StLinkUvscAdapterOptions::operator==(const StLinkUvscAdapterOptions &other) StLinkUvscServerProvider::StLinkUvscServerProvider() : UvscServerProvider(Constants::UVSC_STLINK_PROVIDER_ID) { - setTypeDisplayName(UvscServerProvider::tr("uVision St-Link")); + setTypeDisplayName(Tr::tr("uVision St-Link")); setConfigurationWidgetCreator([this] { return new StLinkUvscServerProviderConfigWidget(this); }); setSupportedDrivers({"STLink\\ST-LINKIII-KEIL_SWO.dll"}); } @@ -148,8 +148,7 @@ FilePath StLinkUvscServerProvider::optionsFilePath(DebuggerRunTool *runTool, Uv::ProjectOptionsWriter writer(&ofs); const StLinkUvProjectOptions projectOptions(this); if (!writer.write(&projectOptions)) { - errorMessage = BareMetalDebugSupport::tr( - "Unable to create a uVision project options template."); + errorMessage = Tr::tr("Unable to create a uVision project options template."); return {}; } return optionsPath; @@ -160,7 +159,7 @@ FilePath StLinkUvscServerProvider::optionsFilePath(DebuggerRunTool *runTool, StLinkUvscServerProviderFactory::StLinkUvscServerProviderFactory() { setId(Constants::UVSC_STLINK_PROVIDER_ID); - setDisplayName(UvscServerProvider::tr("uVision St-Link")); + setDisplayName(Tr::tr("uVision St-Link")); setCreator([] { return new StLinkUvscServerProvider; }); } @@ -173,7 +172,7 @@ StLinkUvscServerProviderConfigWidget::StLinkUvscServerProviderConfigWidget( Q_ASSERT(p); m_adapterOptionsWidget = new StLinkUvscAdapterOptionsWidget; - m_mainLayout->addRow(tr("Adapter options:"), m_adapterOptionsWidget); + m_mainLayout->addRow(Tr::tr("Adapter options:"), m_adapterOptionsWidget); setFromProvider(); @@ -221,10 +220,10 @@ StLinkUvscAdapterOptionsWidget::StLinkUvscAdapterOptionsWidget(QWidget *parent) { const auto layout = new QHBoxLayout; layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(new QLabel(tr("Port:"))); + layout->addWidget(new QLabel(Tr::tr("Port:"))); m_portBox = new QComboBox; layout->addWidget(m_portBox); - layout->addWidget(new QLabel(tr("Speed:"))); + layout->addWidget(new QLabel(Tr::tr("Speed:"))); m_speedBox = new QComboBox; layout->addWidget(m_speedBox); setLayout(layout); @@ -280,8 +279,8 @@ StLinkUvscAdapterOptions::Speed StLinkUvscAdapterOptionsWidget::speedAt(int inde void StLinkUvscAdapterOptionsWidget::populatePorts() { - m_portBox->addItem(tr("JTAG"), StLinkUvscAdapterOptions::JTAG); - m_portBox->addItem(tr("SWD"), StLinkUvscAdapterOptions::SWD); + m_portBox->addItem(Tr::tr("JTAG"), StLinkUvscAdapterOptions::JTAG); + m_portBox->addItem(Tr::tr("SWD"), StLinkUvscAdapterOptions::SWD); } void StLinkUvscAdapterOptionsWidget::populateSpeeds() @@ -290,27 +289,26 @@ void StLinkUvscAdapterOptionsWidget::populateSpeeds() const auto port = portAt(m_portBox->currentIndex()); if (port == StLinkUvscAdapterOptions::JTAG) { - m_speedBox->addItem(tr("9MHz"), StLinkUvscAdapterOptions::Speed_9MHz); - m_speedBox->addItem(tr("4.5MHz"), StLinkUvscAdapterOptions::Speed_4_5MHz); - m_speedBox->addItem(tr("2.25MHz"), StLinkUvscAdapterOptions::Speed_2_25MHz); - m_speedBox->addItem(tr("1.12MHz"), StLinkUvscAdapterOptions::Speed_1_12MHz); - m_speedBox->addItem(tr("560kHz"), StLinkUvscAdapterOptions::Speed_560kHz); - m_speedBox->addItem(tr("280kHz"), StLinkUvscAdapterOptions::Speed_280kHz); - m_speedBox->addItem(tr("140kHz"), StLinkUvscAdapterOptions::Speed_140kHz); + m_speedBox->addItem(Tr::tr("9MHz"), StLinkUvscAdapterOptions::Speed_9MHz); + m_speedBox->addItem(Tr::tr("4.5MHz"), StLinkUvscAdapterOptions::Speed_4_5MHz); + m_speedBox->addItem(Tr::tr("2.25MHz"), StLinkUvscAdapterOptions::Speed_2_25MHz); + m_speedBox->addItem(Tr::tr("1.12MHz"), StLinkUvscAdapterOptions::Speed_1_12MHz); + m_speedBox->addItem(Tr::tr("560kHz"), StLinkUvscAdapterOptions::Speed_560kHz); + m_speedBox->addItem(Tr::tr("280kHz"), StLinkUvscAdapterOptions::Speed_280kHz); + m_speedBox->addItem(Tr::tr("140kHz"), StLinkUvscAdapterOptions::Speed_140kHz); } else if (port == StLinkUvscAdapterOptions::SWD) { - m_speedBox->addItem(tr("4MHz"), StLinkUvscAdapterOptions::Speed_4MHz); - m_speedBox->addItem(tr("1.8MHz"), StLinkUvscAdapterOptions::Speed_1_8MHz); - m_speedBox->addItem(tr("950kHz"), StLinkUvscAdapterOptions::Speed_950kHz); - m_speedBox->addItem(tr("480kHz"), StLinkUvscAdapterOptions::Speed_480kHz); - m_speedBox->addItem(tr("240kHz"), StLinkUvscAdapterOptions::Speed_240kHz); - m_speedBox->addItem(tr("125kHz"), StLinkUvscAdapterOptions::Speed_125kHz); - m_speedBox->addItem(tr("100kHz"), StLinkUvscAdapterOptions::Speed_100kHz); - m_speedBox->addItem(tr("50kHz"), StLinkUvscAdapterOptions::Speed_50kHz); - m_speedBox->addItem(tr("25kHz"), StLinkUvscAdapterOptions::Speed_25kHz); - m_speedBox->addItem(tr("15kHz"), StLinkUvscAdapterOptions::Speed_15kHz); - m_speedBox->addItem(tr("5kHz"), StLinkUvscAdapterOptions::Speed_5kHz); + m_speedBox->addItem(Tr::tr("4MHz"), StLinkUvscAdapterOptions::Speed_4MHz); + m_speedBox->addItem(Tr::tr("1.8MHz"), StLinkUvscAdapterOptions::Speed_1_8MHz); + m_speedBox->addItem(Tr::tr("950kHz"), StLinkUvscAdapterOptions::Speed_950kHz); + m_speedBox->addItem(Tr::tr("480kHz"), StLinkUvscAdapterOptions::Speed_480kHz); + m_speedBox->addItem(Tr::tr("240kHz"), StLinkUvscAdapterOptions::Speed_240kHz); + m_speedBox->addItem(Tr::tr("125kHz"), StLinkUvscAdapterOptions::Speed_125kHz); + m_speedBox->addItem(Tr::tr("100kHz"), StLinkUvscAdapterOptions::Speed_100kHz); + m_speedBox->addItem(Tr::tr("50kHz"), StLinkUvscAdapterOptions::Speed_50kHz); + m_speedBox->addItem(Tr::tr("25kHz"), StLinkUvscAdapterOptions::Speed_25kHz); + m_speedBox->addItem(Tr::tr("15kHz"), StLinkUvscAdapterOptions::Speed_15kHz); + m_speedBox->addItem(Tr::tr("5kHz"), StLinkUvscAdapterOptions::Speed_5kHz); } } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/uvsc/stlinkuvscserverprovider.h b/src/plugins/baremetal/debugservers/uvsc/stlinkuvscserverprovider.h index 481ab83c1ed..5adf5fca214 100644 --- a/src/plugins/baremetal/debugservers/uvsc/stlinkuvscserverprovider.h +++ b/src/plugins/baremetal/debugservers/uvsc/stlinkuvscserverprovider.h @@ -9,8 +9,7 @@ QT_BEGIN_NAMESPACE class QComboBox; QT_END_NAMESPACE -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // StLinkUvscAdapterOptions @@ -69,8 +68,6 @@ public: class StLinkUvscAdapterOptionsWidget; class StLinkUvscServerProviderConfigWidget final : public UvscServerProviderConfigWidget { - Q_OBJECT - public: explicit StLinkUvscServerProviderConfigWidget(StLinkUvscServerProvider *provider); @@ -110,5 +107,4 @@ private: QComboBox *m_speedBox = nullptr; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp b/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp index 8f09294ec3c..0fad93729ae 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp @@ -21,9 +21,7 @@ using namespace Debugger; using namespace ProjectExplorer; using namespace Utils; -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { const char kProjectSchema[] = "2.1"; @@ -238,6 +236,4 @@ ProjectOptions::ProjectOptions(const UvscServerProvider *provider) m_debugOpt->appendProperty("uTrg", int(!useSimulator)); } -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // namespace BareMetal::Internal::Uv diff --git a/src/plugins/baremetal/debugservers/uvsc/uvproject.h b/src/plugins/baremetal/debugservers/uvsc/uvproject.h index 8152c447e38..201a3e3a044 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvproject.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvproject.h @@ -10,8 +10,7 @@ namespace Debugger { class DebuggerRunTool; } -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { class UvscServerProvider; @@ -49,6 +48,6 @@ protected: Gen::Xml::PropertyGroup *m_debugOpt = nullptr; }; -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // Uv + +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/uvsc/uvprojectwriter.cpp b/src/plugins/baremetal/debugservers/uvsc/uvprojectwriter.cpp index ff212793ae4..b2e9cee6399 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvprojectwriter.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvprojectwriter.cpp @@ -3,9 +3,7 @@ #include "uvprojectwriter.h" -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { // ProjectWriter @@ -51,6 +49,4 @@ void ProjectOptionsWriter::visitProjectOptionsEnd( writer()->writeEndElement(); } -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal::Uv diff --git a/src/plugins/baremetal/debugservers/uvsc/uvprojectwriter.h b/src/plugins/baremetal/debugservers/uvsc/uvprojectwriter.h index 32e4cb0fa12..f0c8a13fa15 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvprojectwriter.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvprojectwriter.h @@ -5,9 +5,7 @@ #include "xmlprojectwriter.h" -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { // ProjectWriter @@ -35,6 +33,4 @@ private: void visitProjectOptionsEnd(const Gen::Xml::ProjectOptions *projectOptions) final; }; -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal::Uv diff --git a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp index c3630807725..28d80726bf4 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp @@ -1,15 +1,16 @@ // Copyright (C) 2020 Denis Shienkov // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +#include "uvscserverprovider.h" + #include "uvproject.h" #include "uvprojectwriter.h" #include "uvtargetdeviceviewer.h" #include "uvtargetdriverviewer.h" -#include "uvscserverprovider.h" - #include #include +#include #include #include @@ -30,8 +31,7 @@ using namespace Debugger; using namespace ProjectExplorer; using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { using namespace Uv; @@ -174,10 +174,10 @@ bool UvscServerProvider::aboutToRun(DebuggerRunTool *runTool, QString &errorMess const FilePath bin = exeAspect->executable; if (bin.isEmpty()) { - errorMessage = BareMetalDebugSupport::tr("Cannot debug: Local executable is not set."); + errorMessage = Tr::tr("Cannot debug: Local executable is not set."); return false; } else if (!bin.exists()) { - errorMessage = BareMetalDebugSupport::tr( + errorMessage = Tr::tr( "Cannot debug: Could not find executable for \"%1\".").arg(bin.toString()); return false; } @@ -236,8 +236,7 @@ FilePath UvscServerProvider::projectFilePath(DebuggerRunTool *runTool, QString & Uv::ProjectWriter writer(&ofs); const Uv::Project project(this, runTool); if (!writer.write(&project)) { - errorMessage = BareMetalDebugSupport::tr( - "Unable to create a uVision project template."); + errorMessage = Tr::tr("Unable to create a uVision project template."); return {}; } return projectPath; @@ -262,16 +261,16 @@ UvscServerProviderConfigWidget::UvscServerProviderConfigWidget(UvscServerProvide : IDebugServerProviderConfigWidget(provider) { m_hostWidget = new HostWidget; - m_mainLayout->addRow(tr("Host:"), m_hostWidget); + m_mainLayout->addRow(Tr::tr("Host:"), m_hostWidget); m_toolsIniChooser = new PathChooser; m_toolsIniChooser->setExpectedKind(PathChooser::File); m_toolsIniChooser->setPromptDialogFilter("tools.ini"); - m_toolsIniChooser->setPromptDialogTitle(tr("Choose Keil Toolset Configuration File")); - m_mainLayout->addRow(tr("Tools file path:"), m_toolsIniChooser); + m_toolsIniChooser->setPromptDialogTitle(Tr::tr("Choose Keil Toolset Configuration File")); + m_mainLayout->addRow(Tr::tr("Tools file path:"), m_toolsIniChooser); m_deviceSelector = new DeviceSelector; - m_mainLayout->addRow(tr("Target device:"), m_deviceSelector); + m_mainLayout->addRow(Tr::tr("Target device:"), m_deviceSelector); m_driverSelector = new DriverSelector(provider->supportedDrivers()); - m_mainLayout->addRow(tr("Target driver:"), m_driverSelector); + m_mainLayout->addRow(Tr::tr("Target driver:"), m_driverSelector); setFromProvider(); @@ -371,7 +370,8 @@ UvscServerProviderRunner::UvscServerProviderRunner(ProjectExplorer::RunControl * void UvscServerProviderRunner::start() { - const QString msg = RunControl::tr("Starting %1 ...").arg(m_process.commandLine().displayName()); + const QString msg = Tr::tr("Starting %1 ...") + .arg(m_process.commandLine().displayName()); appendMessage(msg, NormalMessageFormat); m_process.start(); @@ -382,5 +382,4 @@ void UvscServerProviderRunner::stop() m_process.terminate(); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.h b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.h index 469ac421eea..266cf27d172 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.h @@ -28,8 +28,6 @@ class DriverSelector; class UvscServerProvider : public IDebugServerProvider { - Q_DECLARE_TR_FUNCTIONS(BareMetal::Internal::UvscServerProvider) - public: enum ToolsetNumber { UnknownToolsetNumber = -1, diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp index 32b1d3fad66..017d410f56a 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp @@ -3,6 +3,8 @@ #include "uvtargetdevicemodel.h" +#include + #include #include @@ -12,9 +14,7 @@ using namespace Utils; -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { static QString extractPacksPath(const FilePath &toolsIniFile) { @@ -188,7 +188,7 @@ public: DeviceSelectionModel::DeviceSelectionModel(QObject *parent) : TreeModel(parent) { - setHeader({tr("Name"), tr("Version"), tr("Vendor")}); + setHeader({Tr::tr("Name"), Tr::tr("Version"), Tr::tr("Vendor")}); } void DeviceSelectionModel::fillAllPacks(const FilePath &toolsIniFile) @@ -478,6 +478,4 @@ DeviceSelection DeviceSelectionView::buildSelection(const DeviceSelectionItem *i return selection; } -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal::Uv diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h index d450595a73f..b171cede316 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h @@ -13,9 +13,7 @@ QT_BEGIN_NAMESPACE class QXmlStreamReader; QT_END_NAMESPACE -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { // DeviceSelectionModel @@ -56,6 +54,4 @@ private: DeviceSelection buildSelection(const DeviceSelectionItem *item) const; }; -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal::Uv diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.cpp index 66cc3aaafcb..8f46069721b 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.cpp @@ -3,6 +3,8 @@ #include "uvtargetdeviceselection.h" +#include + #include #include #include @@ -11,9 +13,7 @@ using namespace Utils; -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { // Software package data keys. constexpr char packageDescrKeyC[] = "PackageDescription"; @@ -243,7 +243,7 @@ private: DeviceSelectionMemoryModel::DeviceSelectionMemoryModel(DeviceSelection &selection, QObject *parent) : TreeModel(parent), m_selection(selection) { - setHeader({tr("ID"), tr("Start"), tr("Size")}); + setHeader({Tr::tr("ID"), Tr::tr("Start"), Tr::tr("Size")}); refresh(); } @@ -347,7 +347,7 @@ DeviceSelectionAlgorithmModel::DeviceSelectionAlgorithmModel(DeviceSelection &se QObject *parent) : TreeModel(parent), m_selection(selection) { - setHeader({tr("Name"), tr("FLASH Start"), tr("FLASH Size"), tr("RAM Start"), tr("RAM Size")}); + setHeader({Tr::tr("Name"), Tr::tr("FLASH Start"), Tr::tr("FLASH Size"), Tr::tr("RAM Start"), Tr::tr("RAM Size")}); refresh(); } @@ -373,27 +373,27 @@ DeviceSelectionAlgorithmView::DeviceSelectionAlgorithmView(DeviceSelection &sele const auto layout = new QGridLayout; layout->setContentsMargins(0, 0, 0, 0); m_comboBox = new QComboBox; - m_comboBox->setToolTip(tr("Algorithm path.")); + m_comboBox->setToolTip(Tr::tr("Algorithm path.")); m_comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); m_comboBox->setModel(model); layout->addWidget(m_comboBox, 0, 0, 1, 0); // Add FLASH area settings. - const auto flashLabel = new QLabel(tr("FLASH:")); + const auto flashLabel = new QLabel(Tr::tr("FLASH:")); layout->addWidget(flashLabel, 1, 0); const auto flashStartEdit = new QLineEdit; - flashStartEdit->setToolTip(tr("Start address.")); + flashStartEdit->setToolTip(Tr::tr("Start address.")); layout->addWidget(flashStartEdit, 1, 1); const auto flashSizeEdit = new QLineEdit; - flashSizeEdit->setToolTip(tr("Size.")); + flashSizeEdit->setToolTip(Tr::tr("Size.")); layout->addWidget(flashSizeEdit, 1, 2); // Add RAM area settings. - const auto ramLabel = new QLabel(tr("RAM:")); + const auto ramLabel = new QLabel(Tr::tr("RAM:")); layout->addWidget(ramLabel, 2, 0); const auto ramStartEdit = new QLineEdit; - ramStartEdit->setToolTip(tr("Start address.")); + ramStartEdit->setToolTip(Tr::tr("Start address.")); layout->addWidget(ramStartEdit, 2, 1); const auto ramSizeEdit = new QLineEdit; - ramSizeEdit->setToolTip(tr("Size.")); + ramSizeEdit->setToolTip(Tr::tr("Size.")); layout->addWidget(ramSizeEdit, 2, 2); setLayout(layout); @@ -431,6 +431,4 @@ void DeviceSelectionAlgorithmView::refresh() qobject_cast(m_comboBox->model())->refresh(); } -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal::Uv diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.h index 11eb8a35bac..6db74052d39 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.h @@ -10,9 +10,7 @@ QT_BEGIN_NAMESPACE class QComboBox; QT_END_NAMESPACE -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { // DeviceSelection @@ -142,8 +140,6 @@ private: QComboBox *m_comboBox = nullptr; }; -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal::Uv Q_DECLARE_METATYPE(BareMetal::Internal::Uv::DeviceSelection) diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp index 93f4f2a72fc..88e52e7df61 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp @@ -1,9 +1,12 @@ // Copyright (C) 2020 Denis Shienkov // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +#include "uvtargetdeviceviewer.h" + #include "uvproject.h" // for buildPackageId() #include "uvtargetdevicemodel.h" -#include "uvtargetdeviceviewer.h" + +#include #include @@ -16,9 +19,7 @@ #include #include -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { // DeviceSelectorToolPanel @@ -27,7 +28,7 @@ DeviceSelectorToolPanel::DeviceSelectorToolPanel(QWidget *parent) { const auto layout = new QHBoxLayout; layout->setContentsMargins(0, 0, 0, 0); - const auto button = new QPushButton(tr("Manage...")); + const auto button = new QPushButton(Tr::tr("Manage...")); layout->addWidget(button); setLayout(layout); connect(button, &QPushButton::clicked, this, &DeviceSelectorToolPanel::clicked); @@ -52,24 +53,24 @@ DeviceSelectorDetailsPanel::DeviceSelectorDetailsPanel(DeviceSelection &selectio const auto layout = new QFormLayout; m_vendorEdit = new QLineEdit; m_vendorEdit->setReadOnly(true); - layout->addRow(tr("Vendor:"), m_vendorEdit); + layout->addRow(Tr::tr("Vendor:"), m_vendorEdit); m_packageEdit = new QLineEdit; m_packageEdit->setReadOnly(true); - layout->addRow(tr("Package:"), m_packageEdit); + layout->addRow(Tr::tr("Package:"), m_packageEdit); m_descEdit = new QPlainTextEdit; m_descEdit->setReadOnly(true); - layout->addRow(tr("Description:"), m_descEdit); + layout->addRow(Tr::tr("Description:"), m_descEdit); m_memoryView = new DeviceSelectionMemoryView(m_selection); - layout->addRow(tr("Memory:"), m_memoryView); + layout->addRow(Tr::tr("Memory:"), m_memoryView); m_algorithmView = new DeviceSelectionAlgorithmView(m_selection); - layout->addRow(tr("Flash algorithm:"), m_algorithmView); + layout->addRow(Tr::tr("Flash algorithm:"), m_algorithmView); m_peripheralDescriptionFileChooser = new Utils::PathChooser(this); m_peripheralDescriptionFileChooser->setExpectedKind(Utils::PathChooser::File); m_peripheralDescriptionFileChooser->setPromptDialogFilter( - tr("Peripheral description files (*.svd)")); + Tr::tr("Peripheral description files (*.svd)")); m_peripheralDescriptionFileChooser->setPromptDialogTitle( - tr("Select Peripheral Description File")); - layout->addRow(tr("Peripheral description file:"), + Tr::tr("Select Peripheral Description File")); + layout->addRow(Tr::tr("Peripheral description file:"), m_peripheralDescriptionFileChooser); setLayout(layout); @@ -142,8 +143,8 @@ Utils::FilePath DeviceSelector::toolsIniFile() const void DeviceSelector::setSelection(const DeviceSelection &selection) { m_selection = selection; - const auto summary = m_selection.name.isEmpty() - ? tr("Target device not selected.") : m_selection.name; + const QString summary = m_selection.name.isEmpty() + ? Tr::tr("Target device not selected.") : m_selection.name; setSummaryText(summary); setExpandable(!m_selection.name.isEmpty()); @@ -163,7 +164,7 @@ DeviceSelection DeviceSelector::selection() const DeviceSelectionDialog::DeviceSelectionDialog(const Utils::FilePath &toolsIniFile, QWidget *parent) : QDialog(parent), m_model(new DeviceSelectionModel(this)), m_view(new DeviceSelectionView(this)) { - setWindowTitle(tr("Available Target Devices")); + setWindowTitle(Tr::tr("Available Target Devices")); const auto layout = new QVBoxLayout; layout->setContentsMargins(0, 0, 0, 0); @@ -194,6 +195,4 @@ DeviceSelection DeviceSelectionDialog::selection() const return m_selection; } -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal::Uv diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.h index 00b53fdf232..dae289f8c6d 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.h @@ -18,9 +18,7 @@ QT_END_NAMESPACE namespace Utils { class PathChooser; } -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { class DeviceSelectionModel; class DeviceSelectionView; @@ -108,6 +106,4 @@ private: DeviceSelectionView *m_view = nullptr; }; -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal::Uv diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.cpp index 50cbf216d6f..6bdc67ab592 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.cpp @@ -3,14 +3,14 @@ #include "uvtargetdrivermodel.h" +#include + #include #include using namespace Utils; -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { constexpr char cpuDllKey[] = "CPUDLL"; constexpr char driverKey[] = "TDRV"; @@ -106,7 +106,7 @@ public: DriverSelectionModel::DriverSelectionModel(QObject *parent) : TreeModel(parent) { - setHeader({tr("Path")}); + setHeader({Tr::tr("Path")}); } void DriverSelectionModel::fillDrivers(const FilePath &toolsIniFile, @@ -181,6 +181,4 @@ void DriverSelectionView::currentChanged(const QModelIndex ¤t, const QMode emit driverSelected(selection); } -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal::Uv diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.h index b9a075688e1..0d1f1bf1f50 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.h @@ -9,9 +9,7 @@ #include #include -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { // DriverSelectionModel @@ -41,6 +39,4 @@ private: void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) final; }; -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal::Uv diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverselection.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverselection.cpp index 1803dacb959..c3356eee64a 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverselection.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverselection.cpp @@ -3,15 +3,15 @@ #include "uvtargetdriverselection.h" +#include + #include #include #include using namespace Utils; -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { // Driver data keys. constexpr char driverIndexKeyC[] = "DriverIndex"; @@ -79,7 +79,7 @@ private: DriverSelectionCpuDllModel::DriverSelectionCpuDllModel(DriverSelection &selection, QObject *parent) : TreeModel(parent), m_selection(selection) { - setHeader({tr("Name")}); + setHeader({Tr::tr("Name")}); refresh(); } @@ -104,7 +104,7 @@ DriverSelectionCpuDllView::DriverSelectionCpuDllView(DriverSelection &selection, const auto layout = new QHBoxLayout; layout->setContentsMargins(0, 0, 0, 0); m_comboBox = new QComboBox; - m_comboBox->setToolTip(tr("Debugger CPU library (depends on a CPU core).")); + m_comboBox->setToolTip(Tr::tr("Debugger CPU library (depends on a CPU core).")); m_comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); m_comboBox->setModel(model); layout->addWidget(m_comboBox); @@ -125,6 +125,4 @@ void DriverSelectionCpuDllView::refresh() qobject_cast(m_comboBox->model())->refresh(); } -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal::Uv diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverselection.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverselection.h index fdd62a8354a..bfb254446f6 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverselection.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverselection.h @@ -10,9 +10,7 @@ QT_BEGIN_NAMESPACE class QComboBox; QT_END_NAMESPACE -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { // DriverSelection @@ -65,8 +63,6 @@ private: QComboBox *m_comboBox = nullptr; }; -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal::Uv Q_DECLARE_METATYPE(BareMetal::Internal::Uv::DriverSelection) diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.cpp index d33e35bb64f..581b204f199 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.cpp @@ -1,10 +1,11 @@ // Copyright (C) 2020 Denis Shienkov // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -#include "uvproject.h" // for targetUVisionPath() #include "uvtargetdrivermodel.h" #include "uvtargetdriverviewer.h" +#include + #include #include #include @@ -14,9 +15,7 @@ #include #include -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { // DriverSelectorToolPanel @@ -25,7 +24,7 @@ DriverSelectorToolPanel::DriverSelectorToolPanel(QWidget *parent) { const auto layout = new QHBoxLayout; layout->setContentsMargins(0, 0, 0, 0); - const auto button = new QPushButton(tr("Manage...")); + const auto button = new QPushButton(Tr::tr("Manage...")); layout->addWidget(button); setLayout(layout); connect(button, &QPushButton::clicked, this, &DriverSelectorToolPanel::clicked); @@ -49,10 +48,10 @@ DriverSelectorDetailsPanel::DriverSelectorDetailsPanel(DriverSelection &selectio const auto layout = new QFormLayout; m_dllEdit = new QLineEdit;; m_dllEdit->setReadOnly(true); - m_dllEdit->setToolTip(tr("Debugger driver library.")); - layout->addRow(tr("Driver library:"), m_dllEdit); + m_dllEdit->setToolTip(Tr::tr("Debugger driver library.")); + layout->addRow(Tr::tr("Driver library:"), m_dllEdit); m_cpuDllView = new DriverSelectionCpuDllView(m_selection); - layout->addRow(tr("CPU library:"), m_cpuDllView); + layout->addRow(Tr::tr("CPU library:"), m_cpuDllView); setLayout(layout); refresh(); @@ -111,7 +110,7 @@ void DriverSelector::setSelection(const DriverSelection &selection) { m_selection = selection; const auto summary = m_selection.name.isEmpty() - ? tr("Target driver not selected.") : m_selection.name; + ? Tr::tr("Target driver not selected.") : m_selection.name; setSummaryText(summary); setExpandable(!m_selection.name.isEmpty()); @@ -134,7 +133,7 @@ DriverSelectionDialog::DriverSelectionDialog(const Utils::FilePath &toolsIniFile : QDialog(parent), m_model(new DriverSelectionModel(this)), m_view(new DriverSelectionView(this)) { - setWindowTitle(tr("Available Target Drivers")); + setWindowTitle(Tr::tr("Available Target Drivers")); const auto layout = new QVBoxLayout; layout->setContentsMargins(0, 0, 0, 0); @@ -165,6 +164,4 @@ DriverSelection DriverSelectionDialog::selection() const return m_selection; } -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal::Uv diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.h index 35b32c97581..779d6a7b53a 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.h @@ -15,9 +15,7 @@ QT_BEGIN_NAMESPACE class QLineEdit; QT_END_NAMESPACE -namespace BareMetal { -namespace Internal { -namespace Uv { +namespace BareMetal::Internal::Uv { class DriverSelectionModel; class DriverSelectionView; @@ -102,6 +100,4 @@ private: DriverSelectionView *m_view = nullptr; }; -} // namespace Uv -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal::Uv diff --git a/src/plugins/baremetal/debugservers/uvsc/xmlnodevisitor.h b/src/plugins/baremetal/debugservers/uvsc/xmlnodevisitor.h index f3806c76fb7..c1fd8519746 100644 --- a/src/plugins/baremetal/debugservers/uvsc/xmlnodevisitor.h +++ b/src/plugins/baremetal/debugservers/uvsc/xmlnodevisitor.h @@ -5,9 +5,7 @@ #include -namespace BareMetal { -namespace Gen { -namespace Xml { +namespace BareMetal::Gen::Xml { class Project; class ProjectOptions; @@ -34,6 +32,4 @@ public: virtual void visitPropertyGroupEnd(const PropertyGroup *propertyGroup) = 0; }; -} // namespace Xml -} // namespace Gen -} // namespace BareMetal +} // BareMetal::Gen::Xml diff --git a/src/plugins/baremetal/debugservers/uvsc/xmlproject.cpp b/src/plugins/baremetal/debugservers/uvsc/xmlproject.cpp index c260f37c51c..f36c1ccb6d1 100644 --- a/src/plugins/baremetal/debugservers/uvsc/xmlproject.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/xmlproject.cpp @@ -4,9 +4,7 @@ #include "xmlnodevisitor.h" #include "xmlproject.h" -namespace BareMetal { -namespace Gen { -namespace Xml { +namespace BareMetal::Gen::Xml { // Project @@ -32,6 +30,4 @@ void ProjectOptions::accept(INodeVisitor *visitor) const visitor->visitProjectOptionsEnd(this); } -} // namespace Xml -} // namespace Gen -} // namespace BareMetal +} // BareMetal::Gen::Xml diff --git a/src/plugins/baremetal/debugservers/uvsc/xmlproject.h b/src/plugins/baremetal/debugservers/uvsc/xmlproject.h index 7acbcfc100f..5d3385d8690 100644 --- a/src/plugins/baremetal/debugservers/uvsc/xmlproject.h +++ b/src/plugins/baremetal/debugservers/uvsc/xmlproject.h @@ -7,9 +7,7 @@ #include -namespace BareMetal { -namespace Gen { -namespace Xml { +namespace BareMetal::Gen::Xml { // Project @@ -27,6 +25,4 @@ public: void accept(INodeVisitor *visitor) const final; }; -} // namespace Xml -} // namespace Gen -} // namespace BareMetal +} // BareMetal::Gen::Xml diff --git a/src/plugins/baremetal/debugservers/uvsc/xmlprojectwriter.cpp b/src/plugins/baremetal/debugservers/uvsc/xmlprojectwriter.cpp index b04b953778f..7053e399ba2 100644 --- a/src/plugins/baremetal/debugservers/uvsc/xmlprojectwriter.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/xmlprojectwriter.cpp @@ -8,9 +8,7 @@ #include -namespace BareMetal { -namespace Gen { -namespace Xml { +namespace BareMetal::Gen::Xml { // ProjectWriter @@ -114,6 +112,4 @@ QXmlStreamWriter *ProjectOptionsWriter::writer() const return m_writer.get(); } -} // namespace Xml -} // namespace Gen -} // namespace BareMetal +} // BareMetal::Gen::Xml diff --git a/src/plugins/baremetal/debugservers/uvsc/xmlprojectwriter.h b/src/plugins/baremetal/debugservers/uvsc/xmlprojectwriter.h index 8e0fbe2cfa5..569adf3b5b4 100644 --- a/src/plugins/baremetal/debugservers/uvsc/xmlprojectwriter.h +++ b/src/plugins/baremetal/debugservers/uvsc/xmlprojectwriter.h @@ -7,9 +7,7 @@ #include -namespace BareMetal { -namespace Gen { -namespace Xml { +namespace BareMetal::Gen::Xml { // ProjectWriter @@ -59,6 +57,4 @@ private: std::unique_ptr m_writer; }; -} // namespace Xml -} // namespace Gen -} // namespace BareMetal +} // BareMetal::Gen::Xml diff --git a/src/plugins/baremetal/debugservers/uvsc/xmlproperty.cpp b/src/plugins/baremetal/debugservers/uvsc/xmlproperty.cpp index b1221f61560..0f613dac3de 100644 --- a/src/plugins/baremetal/debugservers/uvsc/xmlproperty.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/xmlproperty.cpp @@ -4,9 +4,7 @@ #include "xmlnodevisitor.h" #include "xmlproperty.h" -namespace BareMetal { -namespace Gen { -namespace Xml { +namespace BareMetal::Gen::Xml { Property::Property(QByteArray name, QVariant value) { @@ -35,6 +33,4 @@ void Property::accept(INodeVisitor *visitor) const visitor->visitPropertyEnd(this); } -} // namespace Xml -} // namespace Gen -} // namespace BareMetal +} // BareMetal::Gen::Xml diff --git a/src/plugins/baremetal/debugservers/uvsc/xmlproperty.h b/src/plugins/baremetal/debugservers/uvsc/xmlproperty.h index bb7c0ef75e1..c9da23883c7 100644 --- a/src/plugins/baremetal/debugservers/uvsc/xmlproperty.h +++ b/src/plugins/baremetal/debugservers/uvsc/xmlproperty.h @@ -7,9 +7,7 @@ #include -namespace BareMetal { -namespace Gen { -namespace Xml { +namespace BareMetal::Gen::Xml { class INodeVisitor; @@ -55,6 +53,4 @@ private: std::vector> m_children; }; -} // namespace Xml -} // namespace Gen -} // namespace BareMetal +} // BareMetal::Gen::Xml diff --git a/src/plugins/baremetal/debugservers/uvsc/xmlpropertygroup.cpp b/src/plugins/baremetal/debugservers/uvsc/xmlpropertygroup.cpp index 39bed14701e..6b1f594073b 100644 --- a/src/plugins/baremetal/debugservers/uvsc/xmlpropertygroup.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/xmlpropertygroup.cpp @@ -4,9 +4,7 @@ #include "xmlnodevisitor.h" #include "xmlpropertygroup.h" -namespace BareMetal { -namespace Gen { -namespace Xml { +namespace BareMetal::Gen::Xml { PropertyGroup::PropertyGroup(QByteArray name) { @@ -28,6 +26,4 @@ void PropertyGroup::accept(INodeVisitor *visitor) const visitor->visitPropertyGroupEnd(this); } -} // namespace Xml -} // namespace Gen -} // namespace BareMetal +} // BareMetal::Gen::Xml diff --git a/src/plugins/baremetal/iarewparser.cpp b/src/plugins/baremetal/iarewparser.cpp index e837298140f..a334acff8f1 100644 --- a/src/plugins/baremetal/iarewparser.cpp +++ b/src/plugins/baremetal/iarewparser.cpp @@ -11,8 +11,7 @@ using namespace ProjectExplorer; using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // Helpers: @@ -222,8 +221,7 @@ void IarParser::flush() m_lines = 0; } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal // Unit tests: diff --git a/src/plugins/baremetal/iarewparser.h b/src/plugins/baremetal/iarewparser.h index 5d27f2466e7..8df76280ce0 100644 --- a/src/plugins/baremetal/iarewparser.h +++ b/src/plugins/baremetal/iarewparser.h @@ -6,15 +6,10 @@ #include #include -namespace BareMetal { -namespace Internal { - -// IarParser +namespace BareMetal::Internal { class IarParser final : public ProjectExplorer::OutputTaskParser { - Q_OBJECT - public: explicit IarParser(); static Utils::Id id(); @@ -43,5 +38,4 @@ private: QStringList m_descriptionParts; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/iarewtoolchain.cpp b/src/plugins/baremetal/iarewtoolchain.cpp index 7337fafd5c8..6972a92bd9b 100644 --- a/src/plugins/baremetal/iarewtoolchain.cpp +++ b/src/plugins/baremetal/iarewtoolchain.cpp @@ -1,11 +1,12 @@ // Copyright (C) 2019 Denis Shienkov // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -#include "baremetalconstants.h" - -#include "iarewparser.h" #include "iarewtoolchain.h" +#include "baremetalconstants.h" +#include "baremetaltr.h" +#include "iarewparser.h" + #include #include #include @@ -30,8 +31,7 @@ using namespace ProjectExplorer; using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // Helpers: @@ -259,7 +259,7 @@ static QString buildDisplayName(Abi::Architecture arch, Utils::Id language, { const auto archName = Abi::toString(arch); const auto langName = ToolChainManager::displayNameOfLanguageId(language); - return IarToolChain::tr("IAREW %1 (%2, %3)").arg(version, langName, archName); + return Tr::tr("IAREW %1 (%2, %3)").arg(version, langName, archName); } // IarToolChain @@ -267,7 +267,7 @@ static QString buildDisplayName(Abi::Architecture arch, Utils::Id language, IarToolChain::IarToolChain() : ToolChain(Constants::IAREW_TOOLCHAIN_TYPEID) { - setTypeDisplayName(Internal::IarToolChain::tr("IAREW")); + setTypeDisplayName(Tr::tr("IAREW")); setTargetAbiKey("TargetAbi"); setCompilerCommandKey("CompilerPath"); } @@ -401,7 +401,7 @@ FilePath IarToolChain::makeCommand(const Environment &env) const IarToolChainFactory::IarToolChainFactory() { - setDisplayName(IarToolChain::tr("IAREW")); + setDisplayName(Tr::tr("IAREW")); setSupportedToolChainType(Constants::IAREW_TOOLCHAIN_TYPEID); setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID, ProjectExplorer::Constants::CXX_LANGUAGE_ID}); @@ -545,11 +545,11 @@ IarToolChainConfigWidget::IarToolChainConfigWidget(IarToolChain *tc) : { m_compilerCommand->setExpectedKind(PathChooser::ExistingCommand); m_compilerCommand->setHistoryCompleter("PE.IAREW.Command.History"); - m_mainLayout->addRow(tr("&Compiler path:"), m_compilerCommand); + m_mainLayout->addRow(Tr::tr("&Compiler path:"), m_compilerCommand); m_platformCodeGenFlagsLineEdit = new QLineEdit(this); m_platformCodeGenFlagsLineEdit->setText(ProcessArgs::joinArgs(tc->extraCodeModelFlags())); - m_mainLayout->addRow(tr("Platform codegen flags:"), m_platformCodeGenFlagsLineEdit); - m_mainLayout->addRow(tr("&ABI:"), m_abiWidget); + m_mainLayout->addRow(Tr::tr("Platform codegen flags:"), m_platformCodeGenFlagsLineEdit); + m_mainLayout->addRow(Tr::tr("&ABI:"), m_abiWidget); m_abiWidget->setEnabled(false); @@ -639,5 +639,4 @@ void IarToolChainConfigWidget::handlePlatformCodeGenFlagsChange() handleCompilerCommandChange(); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/iarewtoolchain.h b/src/plugins/baremetal/iarewtoolchain.h index 1306f35ecb2..b6240de23f6 100644 --- a/src/plugins/baremetal/iarewtoolchain.h +++ b/src/plugins/baremetal/iarewtoolchain.h @@ -21,15 +21,12 @@ class PathChooser; namespace ProjectExplorer { class AbiWidget; } -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // IarToolChain class IarToolChain final : public ProjectExplorer::ToolChain { - Q_DECLARE_TR_FUNCTIONS(IarToolChain) - public: MacroInspectionRunner createMacroInspectionRunner() const final; @@ -105,5 +102,4 @@ private: ProjectExplorer::Macros m_macros; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/idebugserverprovider.cpp b/src/plugins/baremetal/idebugserverprovider.cpp index 16850d6e0da..6ce5d768b23 100644 --- a/src/plugins/baremetal/idebugserverprovider.cpp +++ b/src/plugins/baremetal/idebugserverprovider.cpp @@ -1,14 +1,15 @@ // Copyright (C) 2019 Denis Shienkov // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -#include "baremetaldevice.h" -#include "debugserverprovidermanager.h" #include "idebugserverprovider.h" +#include "baremetaldevice.h" +#include "baremetaltr.h" +#include "debugserverprovidermanager.h" + #include #include -#include #include #include #include @@ -18,8 +19,7 @@ using namespace Debugger; using namespace ProjectExplorer; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { const char idKeyC[] = "Id"; const char displayNameKeyC[] = "DisplayName"; @@ -255,8 +255,8 @@ IDebugServerProviderConfigWidget::IDebugServerProviderConfigWidget( m_mainLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); m_nameLineEdit = new QLineEdit(this); - m_nameLineEdit->setToolTip(tr("Enter the name of the debugger server provider.")); - m_mainLayout->addRow(tr("Name:"), m_nameLineEdit); + m_nameLineEdit->setToolTip(Tr::tr("Enter the name of the debugger server provider.")); + m_mainLayout->addRow(Tr::tr("Name:"), m_nameLineEdit); setFromProvider(); @@ -315,12 +315,12 @@ HostWidget::HostWidget(QWidget *parent) : QWidget(parent) { m_hostLineEdit = new QLineEdit(this); - m_hostLineEdit->setToolTip(tr("Enter TCP/IP hostname of the debug server, " - "like \"localhost\" or \"192.0.2.1\".")); + m_hostLineEdit->setToolTip(Tr::tr("Enter TCP/IP hostname of the debug server, " + "like \"localhost\" or \"192.0.2.1\".")); m_portSpinBox = new QSpinBox(this); m_portSpinBox->setRange(0, 65535); - m_portSpinBox->setToolTip(tr("Enter TCP/IP port which will be listened by " - "the debug server.")); + m_portSpinBox->setToolTip(Tr::tr("Enter TCP/IP port which will be listened by " + "the debug server.")); const auto layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(m_hostLineEdit); @@ -345,5 +345,4 @@ QUrl HostWidget::channel() const return url; } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/keilparser.cpp b/src/plugins/baremetal/keilparser.cpp index 2b3267782ad..11554cf2547 100644 --- a/src/plugins/baremetal/keilparser.cpp +++ b/src/plugins/baremetal/keilparser.cpp @@ -11,8 +11,7 @@ using namespace ProjectExplorer; using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // Helpers: @@ -243,8 +242,7 @@ void KeilParser::flush() m_lines = 0; } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal // Unit tests: @@ -253,8 +251,7 @@ void KeilParser::flush() #include #include -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { void BareMetalPlugin::testKeilOutputParsers_data() { @@ -523,7 +520,6 @@ void BareMetalPlugin::testKeilOutputParsers() outputLines); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal #endif // WITH_TESTS diff --git a/src/plugins/baremetal/keilparser.h b/src/plugins/baremetal/keilparser.h index 49bdc5aec54..bc0deb49b4d 100644 --- a/src/plugins/baremetal/keilparser.h +++ b/src/plugins/baremetal/keilparser.h @@ -6,15 +6,10 @@ #include #include -namespace BareMetal { -namespace Internal { - -// KeilParser +namespace BareMetal::Internal { class KeilParser final : public ProjectExplorer::OutputTaskParser { - Q_OBJECT - public: explicit KeilParser(); static Utils::Id id(); @@ -40,5 +35,4 @@ private: QStringList m_snippets; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/keiltoolchain.cpp b/src/plugins/baremetal/keiltoolchain.cpp index 387049f29a4..4e25a84edb8 100644 --- a/src/plugins/baremetal/keiltoolchain.cpp +++ b/src/plugins/baremetal/keiltoolchain.cpp @@ -3,6 +3,7 @@ #include "baremetalconstants.h" +#include "baremetaltr.h" #include "keilparser.h" #include "keiltoolchain.h" @@ -32,8 +33,7 @@ using namespace ProjectExplorer; using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // Helpers: @@ -373,7 +373,7 @@ static Abi::BinaryFormat guessFormat(Abi::Architecture arch) static Abi guessAbi(const Macros ¯os) { - const auto arch = guessArchitecture(macros); + const Abi::Architecture arch = guessArchitecture(macros); return {arch, Abi::OS::BareMetalOS, Abi::OSFlavor::GenericFlavor, guessFormat(arch), guessWordWidth(macros, arch)}; } @@ -381,10 +381,9 @@ static Abi guessAbi(const Macros ¯os) static QString buildDisplayName(Abi::Architecture arch, Utils::Id language, const QString &version) { - const auto archName = Abi::toString(arch); - const auto langName = ToolChainManager::displayNameOfLanguageId(language); - return KeilToolChain::tr("KEIL %1 (%2, %3)") - .arg(version, langName, archName); + const QString archName = Abi::toString(arch); + const QString langName = ToolChainManager::displayNameOfLanguageId(language); + return Tr::tr("KEIL %1 (%2, %3)").arg(version, langName, archName); } static void addDefaultCpuArgs(const FilePath &compiler, QStringList &extraArgs) @@ -406,7 +405,7 @@ static void addDefaultCpuArgs(const FilePath &compiler, QStringList &extraArgs) KeilToolChain::KeilToolChain() : ToolChain(Constants::KEIL_TOOLCHAIN_TYPEID) { - setTypeDisplayName(tr("KEIL")); + setTypeDisplayName(Tr::tr("KEIL")); setTargetAbiKey("TargetAbi"); setCompilerCommandKey("CompilerPath"); } @@ -527,7 +526,7 @@ FilePath KeilToolChain::makeCommand(const Environment &env) const KeilToolChainFactory::KeilToolChainFactory() { - setDisplayName(KeilToolChain::tr("KEIL")); + setDisplayName(Tr::tr("KEIL")); setSupportedToolChainType(Constants::KEIL_TOOLCHAIN_TYPEID); setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID, ProjectExplorer::Constants::CXX_LANGUAGE_ID}); @@ -701,11 +700,11 @@ KeilToolChainConfigWidget::KeilToolChainConfigWidget(KeilToolChain *tc) : { m_compilerCommand->setExpectedKind(PathChooser::ExistingCommand); m_compilerCommand->setHistoryCompleter("PE.KEIL.Command.History"); - m_mainLayout->addRow(tr("&Compiler path:"), m_compilerCommand); + m_mainLayout->addRow(Tr::tr("&Compiler path:"), m_compilerCommand); m_platformCodeGenFlagsLineEdit = new QLineEdit(this); m_platformCodeGenFlagsLineEdit->setText(ProcessArgs::joinArgs(tc->extraCodeModelFlags())); - m_mainLayout->addRow(tr("Platform codegen flags:"), m_platformCodeGenFlagsLineEdit); - m_mainLayout->addRow(tr("&ABI:"), m_abiWidget); + m_mainLayout->addRow(Tr::tr("Platform codegen flags:"), m_platformCodeGenFlagsLineEdit); + m_mainLayout->addRow(Tr::tr("&ABI:"), m_abiWidget); m_abiWidget->setEnabled(false); @@ -798,5 +797,4 @@ void KeilToolChainConfigWidget::handlePlatformCodeGenFlagsChange() handleCompilerCommandChange(); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/keiltoolchain.h b/src/plugins/baremetal/keiltoolchain.h index 4c427b75b15..9d45dafe2b3 100644 --- a/src/plugins/baremetal/keiltoolchain.h +++ b/src/plugins/baremetal/keiltoolchain.h @@ -14,22 +14,16 @@ class QPushButton; class QTextEdit; QT_END_NAMESPACE -namespace Utils { -class FilePath; -class PathChooser; -} +namespace Utils { class PathChooser; } namespace ProjectExplorer { class AbiWidget; } -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // KeilToolChain class KeilToolChain final : public ProjectExplorer::ToolChain { - Q_DECLARE_TR_FUNCTIONS(KeilToolChain) - public: MacroInspectionRunner createMacroInspectionRunner() const final; @@ -83,8 +77,6 @@ private: class KeilToolChainConfigWidget final : public ProjectExplorer::ToolChainConfigWidget { - Q_OBJECT - public: explicit KeilToolChainConfigWidget(KeilToolChain *tc); @@ -104,5 +96,4 @@ private: ProjectExplorer::Macros m_macros; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/sdccparser.cpp b/src/plugins/baremetal/sdccparser.cpp index 07cd5b377eb..df677ff819e 100644 --- a/src/plugins/baremetal/sdccparser.cpp +++ b/src/plugins/baremetal/sdccparser.cpp @@ -11,8 +11,7 @@ using namespace ProjectExplorer; using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // Helpers: @@ -137,8 +136,7 @@ void SdccParser::flush() m_lines = 0; } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal // Unit tests: @@ -147,8 +145,7 @@ void SdccParser::flush() #include #include -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { void BareMetalPlugin::testSdccOutputParsers_data() { @@ -310,7 +307,6 @@ void BareMetalPlugin::testSdccOutputParsers() outputLines); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal #endif // WITH_TESTS diff --git a/src/plugins/baremetal/sdccparser.h b/src/plugins/baremetal/sdccparser.h index 0fb59727a77..e13f96f8019 100644 --- a/src/plugins/baremetal/sdccparser.h +++ b/src/plugins/baremetal/sdccparser.h @@ -6,15 +6,10 @@ #include #include -namespace BareMetal { -namespace Internal { - -// SdccParser +namespace BareMetal::Internal { class SdccParser final : public ProjectExplorer::OutputTaskParser { - Q_OBJECT - public: explicit SdccParser(); static Utils::Id id(); @@ -30,5 +25,4 @@ private: int m_lines = 0; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/sdcctoolchain.cpp b/src/plugins/baremetal/sdcctoolchain.cpp index 0fc7eb0f925..38ef6c54770 100644 --- a/src/plugins/baremetal/sdcctoolchain.cpp +++ b/src/plugins/baremetal/sdcctoolchain.cpp @@ -1,11 +1,12 @@ // Copyright (C) 2019 Denis Shienkov // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -#include "baremetalconstants.h" - -#include "sdccparser.h" #include "sdcctoolchain.h" +#include "baremetalconstants.h" +#include "baremetaltr.h" +#include "sdccparser.h" + #include #include #include @@ -31,8 +32,7 @@ using namespace ProjectExplorer; using namespace Utils; -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // Helpers: @@ -163,7 +163,7 @@ static Abi::BinaryFormat guessFormat(Abi::Architecture arch) static Abi guessAbi(const Macros ¯os) { - const auto arch = guessArchitecture(macros); + const Abi::Architecture arch = guessArchitecture(macros); return {arch, Abi::OS::BareMetalOS, Abi::OSFlavor::GenericFlavor, guessFormat(arch), guessWordWidth(macros)}; } @@ -171,10 +171,9 @@ static Abi guessAbi(const Macros ¯os) static QString buildDisplayName(Abi::Architecture arch, Utils::Id language, const QString &version) { - const auto archName = Abi::toString(arch); - const auto langName = ToolChainManager::displayNameOfLanguageId(language); - return SdccToolChain::tr("SDCC %1 (%2, %3)") - .arg(version, langName, archName); + const QString archName = Abi::toString(arch); + const QString langName = ToolChainManager::displayNameOfLanguageId(language); + return Tr::tr("SDCC %1 (%2, %3)").arg(version, langName, archName); } static Utils::FilePath compilerPathFromEnvironment(const QString &compilerName) @@ -188,7 +187,7 @@ static Utils::FilePath compilerPathFromEnvironment(const QString &compilerName) SdccToolChain::SdccToolChain() : ToolChain(Constants::SDCC_TOOLCHAIN_TYPEID) { - setTypeDisplayName(Internal::SdccToolChain::tr("SDCC")); + setTypeDisplayName(Tr::tr("SDCC")); setTargetAbiKey("TargetAbi"); setCompilerCommandKey("CompilerPath"); } @@ -277,7 +276,7 @@ FilePath SdccToolChain::makeCommand(const Environment &env) const SdccToolChainFactory::SdccToolChainFactory() { - setDisplayName(SdccToolChain::tr("SDCC")); + setDisplayName(Tr::tr("SDCC")); setSupportedToolChainType(Constants::SDCC_TOOLCHAIN_TYPEID); setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID}); setToolchainConstructor([] { return new SdccToolChain; }); @@ -413,8 +412,8 @@ SdccToolChainConfigWidget::SdccToolChainConfigWidget(SdccToolChain *tc) : { m_compilerCommand->setExpectedKind(PathChooser::ExistingCommand); m_compilerCommand->setHistoryCompleter("PE.SDCC.Command.History"); - m_mainLayout->addRow(tr("&Compiler path:"), m_compilerCommand); - m_mainLayout->addRow(tr("&ABI:"), m_abiWidget); + m_mainLayout->addRow(Tr::tr("&Compiler path:"), m_compilerCommand); + m_mainLayout->addRow(Tr::tr("&ABI:"), m_abiWidget); m_abiWidget->setEnabled(false); @@ -486,5 +485,4 @@ void SdccToolChainConfigWidget::handleCompilerCommandChange() emit dirty(); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal diff --git a/src/plugins/baremetal/sdcctoolchain.h b/src/plugins/baremetal/sdcctoolchain.h index 9403d54d078..59c59c358c9 100644 --- a/src/plugins/baremetal/sdcctoolchain.h +++ b/src/plugins/baremetal/sdcctoolchain.h @@ -13,22 +13,16 @@ class QPushButton; class QTextEdit; QT_END_NAMESPACE -namespace Utils { -class FilePath; -class PathChooser; -} +namespace Utils { class PathChooser; } namespace ProjectExplorer { class AbiWidget; } -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { // SdccToolChain class SdccToolChain final : public ProjectExplorer::ToolChain { - Q_DECLARE_TR_FUNCTIONS(SdccToolChain) - public: MacroInspectionRunner createMacroInspectionRunner() const final; @@ -74,8 +68,6 @@ private: class SdccToolChainConfigWidget final : public ProjectExplorer::ToolChainConfigWidget { - Q_OBJECT - public: explicit SdccToolChainConfigWidget(SdccToolChain *tc); @@ -93,5 +85,4 @@ private: ProjectExplorer::Macros m_macros; }; -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal From 7eac686f2957c23521da2efb8679da497ef6dc15 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 10 Oct 2022 15:17:51 +0200 Subject: [PATCH 15/42] BareMetal: Remove unused baremetalgdbcommandsdeploystep.{h,cpp} Change-Id: I57cc268714844cf5f342f4ea169a1c0c32e8b9f9 Reviewed-by: Alessandro Portale Reviewed-by: --- .../baremetalgdbcommandsdeploystep.cpp | 104 ------------------ .../baremetalgdbcommandsdeploystep.h | 61 ---------- 2 files changed, 165 deletions(-) delete mode 100644 src/plugins/baremetal/baremetalgdbcommandsdeploystep.cpp delete mode 100644 src/plugins/baremetal/baremetalgdbcommandsdeploystep.h diff --git a/src/plugins/baremetal/baremetalgdbcommandsdeploystep.cpp b/src/plugins/baremetal/baremetalgdbcommandsdeploystep.cpp deleted file mode 100644 index 14f2eb2aaf1..00000000000 --- a/src/plugins/baremetal/baremetalgdbcommandsdeploystep.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (C) 2016 Tim Sander -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 - -#include "baremetalgdbcommandsdeploystep.h" - -#include - -using namespace ProjectExplorer; - -namespace BareMetal { -namespace Internal { - -const char GdbCommandsKey[] = "BareMetal.GdbCommandsStep.Commands"; - -// BareMetalGdbCommandsDeployStepWidget - -BareMetalGdbCommandsDeployStepWidget::BareMetalGdbCommandsDeployStepWidget(BareMetalGdbCommandsDeployStep &step) - : BuildStepConfigWidget(&step), m_step(step) -{ - const auto fl = new QFormLayout(this); - fl->setContentsMargins(0, 0, 0, 0); - fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); - setLayout(fl); - m_commands = new QPlainTextEdit(this); - fl->addRow(Tr::tr("GDB commands:"), m_commands); - m_commands->setPlainText(m_step.gdbCommands()); - connect(m_commands, &QPlainTextEdit::textChanged, this, &BareMetalGdbCommandsDeployStepWidget::update); -} - -void BareMetalGdbCommandsDeployStepWidget::update() -{ - m_step.updateGdbCommands(m_commands->toPlainText()); -} - -QString BareMetalGdbCommandsDeployStepWidget::displayName() const -{ - return QLatin1String("") + m_step.displayName() + QLatin1String(""); -} - -QString BareMetalGdbCommandsDeployStepWidget::summaryText() const -{ - return displayName(); -} - -// BareMetalGdbCommandsDeployStep - -BareMetalGdbCommandsDeployStep::BareMetalGdbCommandsDeployStep(BuildStepList *bsl) - : BuildStep(bsl, stepId()) -{ - setDefaultDisplayName(displayName()); -} - -void BareMetalGdbCommandsDeployStep::doRun() -{ - emit finished(true); -} - -bool BareMetalGdbCommandsDeployStep::fromMap(const QVariantMap &map) -{ - if (!BuildStep::fromMap(map)) - return false; - m_gdbCommands = map.value(QLatin1String(GdbCommandsKey)).toString(); - return true; -} - -QVariantMap BareMetalGdbCommandsDeployStep::toMap() const -{ - QVariantMap map = BuildStep::toMap(); - map.insert(QLatin1String(GdbCommandsKey),m_gdbCommands); - return map; -} - -BuildStepConfigWidget *BareMetalGdbCommandsDeployStep::createConfigWidget() -{ - return new BareMetalGdbCommandsDeployStepWidget(*this); -} - -Core::Id BareMetalGdbCommandsDeployStep::stepId() -{ - return Core::Id("BareMetal.GdbCommandsDeployStep"); -} - -QString BareMetalGdbCommandsDeployStep::displayName() -{ - return Tr::tr("GDB commands"); -} - -void BareMetalGdbCommandsDeployStep::updateGdbCommands(const QString &newCommands) -{ - m_gdbCommands = newCommands; -} - -QString BareMetalGdbCommandsDeployStep::gdbCommands() const -{ - return m_gdbCommands; -} - -bool BareMetalGdbCommandsDeployStep::init() -{ - return true; -} - -} // namespace Internal -} // namespace BareMetal diff --git a/src/plugins/baremetal/baremetalgdbcommandsdeploystep.h b/src/plugins/baremetal/baremetalgdbcommandsdeploystep.h deleted file mode 100644 index 9621202cc18..00000000000 --- a/src/plugins/baremetal/baremetalgdbcommandsdeploystep.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2016 Tim Sander -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -#include -#include - -namespace BareMetal { -namespace Internal { - -// BareMetalGdbCommandsDeployStep - -class BareMetalGdbCommandsDeployStep final : public ProjectExplorer::BuildStep -{ - Q_OBJECT - -public: - explicit BareMetalGdbCommandsDeployStep(ProjectExplorer::BuildStepList *bsl); - - bool fromMap(const QVariantMap &map) final; - QVariantMap toMap() const final; - - ProjectExplorer::BuildStepConfigWidget *createConfigWidget() final; - - static Core::Id stepId(); - static QString displayName(); - - void updateGdbCommands(const QString &newCommands); - QString gdbCommands() const; - -private: - bool init() final; - void doRun() final; - - QString m_gdbCommands; -}; - -// BareMetalGdbCommandsDeployStepWidget - -class BareMetalGdbCommandsDeployStepWidget final - : public ProjectExplorer::BuildStepConfigWidget -{ - Q_OBJECT - -public: - explicit BareMetalGdbCommandsDeployStepWidget(BareMetalGdbCommandsDeployStep &step); - void update(); - -private: - QString displayName() const; - QString summaryText() const; - - BareMetalGdbCommandsDeployStep &m_step; - QPlainTextEdit *m_commands = nullptr; -}; - -} // namespace Internal -} // namespace BareMetal From 19f2a95e1c203153c88516cc89691d3c6b51f785 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 10 Oct 2022 09:58:54 +0200 Subject: [PATCH 16/42] Nim: Convert to Tr::tr Change-Id: Iad4641479d566347ef9acdfb0a04f37907ac4a2d Reviewed-by: Alessandro Portale Reviewed-by: --- share/qtcreator/translations/qtcreator_da.ts | 78 +-------- share/qtcreator/translations/qtcreator_de.ts | 81 ++------- share/qtcreator/translations/qtcreator_hr.ts | 103 +----------- share/qtcreator/translations/qtcreator_ja.ts | 159 +----------------- share/qtcreator/translations/qtcreator_pl.ts | 73 +------- share/qtcreator/translations/qtcreator_ru.ts | 121 +------------ src/plugins/nim/editor/nimeditorfactory.cpp | 3 +- src/plugins/nim/editor/nimhighlighter.cpp | 2 +- src/plugins/nim/editor/nimindenter.cpp | 2 +- .../nim/editor/nimtexteditorwidget.cpp | 11 +- src/plugins/nim/nimconstants.h | 7 +- src/plugins/nim/nimplugin.cpp | 3 +- .../nim/project/nimblebuildconfiguration.cpp | 22 +-- src/plugins/nim/project/nimblebuildstep.cpp | 5 +- src/plugins/nim/project/nimblebuildsystem.cpp | 2 - src/plugins/nim/project/nimbleproject.cpp | 5 +- src/plugins/nim/project/nimbleproject.h | 2 +- .../nim/project/nimblerunconfiguration.cpp | 9 +- src/plugins/nim/project/nimbletaskstep.cpp | 17 +- .../nim/project/nimbuildconfiguration.cpp | 9 +- src/plugins/nim/project/nimbuildsystem.cpp | 1 - .../nim/project/nimcompilerbuildstep.cpp | 31 ++-- .../nim/project/nimcompilercleanstep.cpp | 21 ++- .../nim/project/nimoutputtaskparser.cpp | 4 +- src/plugins/nim/project/nimproject.cpp | 7 +- .../nim/project/nimrunconfiguration.cpp | 7 +- src/plugins/nim/project/nimtoolchain.cpp | 5 +- src/plugins/nim/project/nimtoolchain.h | 2 - .../nim/project/nimtoolchainfactory.cpp | 7 +- .../nimcodestylepreferencesfactory.cpp | 20 ++- .../settings/nimcodestylepreferencesfactory.h | 2 - .../nim/settings/nimcodestylesettingspage.cpp | 10 +- src/plugins/nim/settings/nimsettings.cpp | 13 +- src/plugins/nim/settings/nimsettings.h | 4 +- 34 files changed, 132 insertions(+), 716 deletions(-) diff --git a/share/qtcreator/translations/qtcreator_da.ts b/share/qtcreator/translations/qtcreator_da.ts index cf54251fc42..f11aa1e9c35 100644 --- a/share/qtcreator/translations/qtcreator_da.ts +++ b/share/qtcreator/translations/qtcreator_da.ts @@ -21036,21 +21036,15 @@ Fejl: %5
- Nim::NimBuildConfigurationFactory + Nim Build Byg - - - Nim::NimBuildConfigurationWidget Build directory: Bygmappe: - - - Nim::NimCompilerBuildStepConfigWidget Target: Mål: @@ -21079,16 +21073,10 @@ Fejl: %5 Release Udgivelse - - - Nim::NimCompilerBuildStepFactory Nim Compiler Build Step Nim-kompiler byggetrin - - - Nim::NimCompilerCleanStep Nim Clean Step Nim renstrin @@ -21109,24 +21097,15 @@ Fejl: %5 Clean step completed successfully. Renstrin fuldført. - - - Nim::NimCompilerCleanStepConfigWidget Working directory: Arbejdsmappe: - - - Nim::NimPlugin Nim SnippetProvider Nim - - - Nim::NimProject Scanning for Nim files Skanner efter Nim-filer @@ -21139,9 +21118,6 @@ Fejl: %5 Nim compiler does not exist. Nim-kompiler findes ikke. - - - Nim::NimSettings Global Settings @@ -21151,9 +21127,6 @@ Fejl: %5 Nim Nim - - - Nim::NimToolChainConfigWidget &Compiler path: &Kompilersti: @@ -21162,62 +21135,22 @@ Fejl: %5 &Compiler version: &Kompiler-version: - - - Nim::NimToolChainFactory - - Nim - Nim - - - - NimBuildConfigurationWidget General Generelt - - - NimCodeStylePreferencesFactory - - Nim - Nim - - - - NimCodeStyleSettingsPage Code Style Kodestil - - Nim - Nim - - - - NimCompilerBuildStep - - Nim Compiler Build Step - Nim-kompiler byggetrin - - - - NimCompilerBuildStepConfigWidget Nim build step Nim-byggetrin - - - NimCompilerCleanStepFactory Nim Compiler Clean Step Nim-kompiler renstrin - - - NimCompilerCleanStepWidget Nim clean step Nim renstrin @@ -42742,19 +42675,12 @@ Vil du overskrive dem? - Nim::NimRunConfiguration + Nim Current Build Target Aktuelle byggemål - - Nim::NimCodeStyleSettingsPage - - Nim - Nim - - ProjectExplorer::BuildStepList diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index 675304a58f2..704edc9a2e9 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -35294,7 +35294,7 @@ Möchten Sie sie überschreiben? - Nim::NimCompilerBuildStepConfigWidget + Nim Target: Ziel: @@ -35771,21 +35771,15 @@ Siehe auch die Einstellungen für Google Test. - NimCompilerBuildStep + Nim Nim Compiler Build Step Nim-Compiler Build-Schritt - - - NimCompilerBuildStepConfigWidget Nim build step Nim-Build-Schritt - - - NimCodeStyleSettingsPage Code Style Coding-Stil @@ -35794,16 +35788,6 @@ Siehe auch die Einstellungen für Google Test. Nim Nim - - - NimCodeStylePreferencesFactory - - Nim - Nim - - - - Nim::NimCompilerCleanStep Nim Clean Step Nim-Schritt zur Bereinigung @@ -35832,18 +35816,11 @@ Siehe auch die Einstellungen für Google Test. Nim Compiler Clean Step Nim-Compiler-Schritt zur Bereinigung - - - Nim::NimSettings Global Settings Global - - Nim - Nim - ProjectExplorer::CustomExecutableRunConfiguration @@ -37741,15 +37718,12 @@ Ablaufdatum: %3 - Nim::NimPlugin + Nim Nim SnippetProvider Nim - - - Nim::NimProject No Nim compiler set. Es ist kein Nim-Compiler eingerichtet. @@ -37758,9 +37732,6 @@ Ablaufdatum: %3 Nim compiler does not exist. Der Nim-Compiler existiert nicht. - - - Nim::NimToolChainConfigWidget &Compiler path: &Compiler-Pfad: @@ -40861,7 +40832,7 @@ Möchten Sie sie überschreiben? - Nim::NimRunConfiguration + Nim Current Build Target Aktuelles Build-Ziel @@ -41922,11 +41893,7 @@ Die Dateien aus dem Quellverzeichnis des Android-Pakets werden in das Verzeichni - Nim::NimCompilerBuildStep - - Nim Compiler Build Step - Nim-Compiler Build-Schritt - + Nim ProjectExplorer::MakeStep @@ -42198,7 +42165,7 @@ Die Dateien aus dem Quellverzeichnis des Android-Pakets werden in das Verzeichni - Nim::NimToolsSettingsWidget + Nim Nimsuggest Nimsuggest @@ -42821,15 +42788,11 @@ Die Dateien aus dem Quellverzeichnis des Android-Pakets werden in das Verzeichni - NimToolsSettingsPage + Nim Tools Werkzeuge - - Nim - Nim - PerfProfiler @@ -43865,7 +43828,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e - Nim::NimbleBuildStepWidget + Nim Arguments: Argumente: @@ -46401,26 +46364,12 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e - Nim::NimbleBuildConfiguration + Nim General Allgemein - - Nim::NimBuildConfiguration - - General - Allgemein - - - - Nim::CodeStyleSettings - - Nim - Nim - - ProjectExplorer::Internal::AddRunConfigDialog @@ -47462,11 +47411,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e - Nim::ToolSettingsPage - - Nim - Nim - + Nim ProjextExplorer::Internal::KitOptionsPageWidget @@ -48273,11 +48218,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e - Nim::NimToolChain - - Nim - Nim - + Nim ProjectExplorer::Internal::BuildEnvironmentWidget diff --git a/share/qtcreator/translations/qtcreator_hr.ts b/share/qtcreator/translations/qtcreator_hr.ts index deff7f29d7d..84c83f75ccc 100644 --- a/share/qtcreator/translations/qtcreator_hr.ts +++ b/share/qtcreator/translations/qtcreator_hr.ts @@ -5128,7 +5128,7 @@ Greška: %5 - Nim::NimCompilerBuildStepConfigWidget + Nim Target: Odredište: @@ -5149,24 +5149,14 @@ Greška: %5 None Bez - - Debug - Ukloni greške - Release Objavi - - - Nim::NimCompilerCleanStepConfigWidget Working directory: Radni direktorij: - - - Nim::NimToolsSettingsWidget Nimsuggest Nimsuggest @@ -27012,42 +27002,27 @@ Rok upotrebe: %3 - NimBuildConfigurationWidget + Nim General Opće - - - NimCompilerBuildStep Nim Compiler Build Step - - - NimCompilerBuildStepConfigWidget Nim build step - - - NimCompilerCleanStepFactory Nim Compiler Clean Step - - - NimCompilerCleanStepWidget Nim clean step - - - NimCodeStyleSettingsPage Code Style Stil kodiranja @@ -27056,35 +27031,15 @@ Rok upotrebe: %3 Nim Nim - - - NimToolsSettingsPage Tools Alati - - Nim - Nim - - - - NimCodeStylePreferencesFactory - - Nim - Nim - - - - Nim::NimPlugin Nim SnippetProvider Nim - - - Nim::NimBuildConfigurationFactory Debug Uklanjanje grešaka @@ -27093,27 +27048,10 @@ Rok upotrebe: %3 Profile Profil - - Release - Objavljivanje - - - - Nim::NimBuildConfigurationWidget Build directory: Direktorij gradnje: - - - Nim::NimCompilerBuildStep - - Nim Compiler Build Step - - - - - Nim::NimCompilerCleanStep Nim Clean Step @@ -27134,9 +27072,6 @@ Rok upotrebe: %3 Clean step completed successfully. - - - Nim::NimProject Scanning for Nim files Traženje Nim datoteka @@ -27149,23 +27084,10 @@ Rok upotrebe: %3 Nim compiler does not exist. Nim kompajler ne postoji. - - - Nim::NimRunConfiguration Current Build Target Trenutačno odredište gradnje - - - Nim::NimToolChainFactory - - Nim - Nim - - - - Nim::NimToolChainConfigWidget &Compiler path: Staza za &kompajler: @@ -27174,32 +27096,11 @@ Rok upotrebe: %3 &Compiler version: Verzija &kompajlera: - - - Nim::NimCodeStyleSettingsPage - - Nim - Nim - - - - Nim::NimSettings Global Settings Globalno - - Nim - Nim - - - - Nim::NimToolsSettingsPage - - Nim - Nim - Perforce::Internal::PerforceChecker diff --git a/share/qtcreator/translations/qtcreator_ja.ts b/share/qtcreator/translations/qtcreator_ja.ts index d6b1ea9665f..428aef36a76 100644 --- a/share/qtcreator/translations/qtcreator_ja.ts +++ b/share/qtcreator/translations/qtcreator_ja.ts @@ -44262,7 +44262,7 @@ Android パッケージソースディレクトリのファイルはビルドデ - Nim::NimCompilerBuildStepConfigWidget + Nim Form フォーム @@ -44295,13 +44295,6 @@ Android パッケージソースディレクトリのファイルはビルドデ Release リリース - - - Nim::NimCompilerCleanStepConfigWidget - - Form - フォーム - Working directory: 作業ディレクトリ: @@ -44586,49 +44579,31 @@ Output: - NimRunConfiguration + Nim Current Build Target 現在のビルドターゲット - - - NimBuildConfigurationWidget General 一般 - - - NimCompilerBuildStep Nim Compiler Build Step Nim コンパイラビルドステップ - - - NimCompilerBuildStepConfigWidget Nim build step Nim ビルドステップ - - - NimCompilerCleanStepFactory Nim Compiler Clean Step Nim コンパイラクリーンステップ - - - NimCompilerCleanStepWidget Nim clean step Nim クリーンステップ - - - NimCodeStyleSettingsPage Code Style コードスタイル @@ -44637,44 +44612,14 @@ Output: Nim Nim - - - NimCodeStylePreferencesFactory - - Nim - Nim - - - - NimSnippetProvider - - Nim - Nim - - - - Nim::NimBuildConfigurationFactory Build ビルド - - - Nim::NimBuildConfigurationWidget Build directory: ビルドディレクトリ: - - - Nim::NimCompilerBuildStepFactory - - Nim Compiler Build Step - Nim コンパイラビルドステップ - - - - Nim::NimCompilerCleanStep Nim Clean Step Nim クリーンステップ @@ -44683,10 +44628,6 @@ Output: Build directory "%1" does not exist. ビルドディレクトリ "%1" が存在しません。 - - Working directory: - 作業ディレクトリ: - Failed to delete the cache directory. キャッシュディレクトリの削除に失敗しました。 @@ -44699,16 +44640,10 @@ Output: Clean step completed successfully. クリーンステップが正常に完了しました。 - - - Nim::NimProjectManager Failed opening project "%1": Project is not a file. プロジェクト "%1" が開けません: プロジェクトがファイルではありません。 - - - Nim::NimRunControl %1 crashed %1 がクラッシュしました @@ -44717,18 +44652,11 @@ Output: %1 exited with code %2 %1 は終了コード %2 で終了しました - - - Nim::NimSettings Global Settings グローバル - - Nim - Nim - QmakeProjectManager @@ -45709,7 +45637,7 @@ Output: - Nim::NimToolsSettingsWidget + Nim Path パス @@ -49342,96 +49270,17 @@ Stepping into the module or setting breakpoints by file and line is expected to - NimToolsSettingsPage - - Nim - Nim - - - - Nim::NimPlugin + Nim Nim SnippetProvider Nim - - - Nim::NimbleBuildConfiguration - - General - 一般 - - - - Nim::NimBuildConfiguration - - General - 一般 - - - - Nim::NimCompilerBuildStep - - Nim build step - Nim ビルドステップ - - - Target: - ターゲット: - - - Default arguments: - デフォルト引数: - - - Extra arguments: - 追加引数: - - - Command: - コマンド: - - - Nim Compiler Build Step - Nim コンパイラビルドステップ - - - - Nim::NimRunConfiguration - - Current Build Target - 現在のビルドターゲット - - - - Nim::NimToolChain - - Nim - Nim - - - - Nim::NimToolChainConfigWidget &Compiler path: コンパイラのパス(&C): - - Nim::CodeStyleSettings - - Nim - Nim - - - - Nim::ToolSettingsPage - - Nim - Nim - - Perforce::Internal::PerforceDiffConfig diff --git a/share/qtcreator/translations/qtcreator_pl.ts b/share/qtcreator/translations/qtcreator_pl.ts index ba482c9d0ff..5f8b7b600a2 100644 --- a/share/qtcreator/translations/qtcreator_pl.ts +++ b/share/qtcreator/translations/qtcreator_pl.ts @@ -37874,7 +37874,7 @@ Czy nadpisać go? - Nim::NimCompilerBuildStepConfigWidget + Nim Form Formularz @@ -37907,13 +37907,6 @@ Czy nadpisać go? Release Release - - - Nim::NimCompilerCleanStepConfigWidget - - Form - Formularz - Working directory: Katalog roboczy: @@ -38469,49 +38462,31 @@ Komunikat: - NimRunConfiguration + Nim Current Build Target Bieżący cel budowania - - - NimBuildConfigurationWidget General Ogólne - - - NimCompilerBuildStep Nim Compiler Build Step Krok budowania kompilatora Nim - - - NimCompilerBuildStepConfigWidget Nim build step Krok budowania Nim - - - NimCompilerCleanStepFactory Nim Compiler Clean Step Krok czyszczenia kompilatora Nim - - - NimCompilerCleanStepWidget Nim clean step Krok czyszczenia Nim - - - NimCodeStyleSettingsPage Code Style Styl kodu @@ -38520,37 +38495,14 @@ Komunikat: Nim Nim - - - NimCodeStylePreferencesFactory - - Nim - Nim - - - - Nim::NimBuildConfigurationFactory Build - - - Nim::NimBuildConfigurationWidget Build directory: Katalog budowania: - - - Nim::NimCompilerBuildStepFactory - - Nim Compiler Build Step - Krok budowania kompilatora Nim - - - - Nim::NimCompilerCleanStep Nim Clean Step Krok czyszczenia Nim @@ -38571,18 +38523,11 @@ Komunikat: Clean step completed successfully. Krok czyszczenia poprawnie zakończony. - - - Nim::NimSettings Global Settings Globalne - - Nim - Nim - ProjectExplorer::Internal::CustomExecutableConfigurationWidget @@ -41422,7 +41367,7 @@ Termin wygaśnięcia: %3 - Nim::NimProject + Nim Scanning for Nim files Skanowanie w poszukiwaniu plików Nim @@ -41435,16 +41380,6 @@ Termin wygaśnięcia: %3 Nim compiler does not exist Brak kompilatora Nim - - - Nim::NimToolChainFactory - - Nim - Nim - - - - Nim::NimToolChainConfigWidget &Compiler path: Ścieżka do &kompilatora: @@ -42111,7 +42046,7 @@ Błąd: %5 - Nim::NimPlugin + Nim Nim SnippetProvider diff --git a/share/qtcreator/translations/qtcreator_ru.ts b/share/qtcreator/translations/qtcreator_ru.ts index b3ccca5111a..77d2c6d7cdb 100644 --- a/share/qtcreator/translations/qtcreator_ru.ts +++ b/share/qtcreator/translations/qtcreator_ru.ts @@ -26906,28 +26906,19 @@ If set to false, the target will be moved straight to the current mouse position - Nim::CodeStyleSettings + Nim Nim Nim - - - Nim::NimBuildConfiguration General Основное - - - Nim::NimCompilerBuildStep Nim Compiler Build Step Этап сборки компилятора Nim - - - Nim::NimCompilerBuildStepConfigWidget Target: Цель: @@ -26956,9 +26947,6 @@ If set to false, the target will be moved straight to the current mouse position Release Выпуск - - - Nim::NimCompilerCleanStep Nim Clean Step Этап очистки компилятора Nim @@ -26987,17 +26975,11 @@ If set to false, the target will be moved straight to the current mouse position Nim Compiler Clean Step Этап очистки компилятора Nim - - - Nim::NimPlugin Nim SnippetProvider Nim - - - Nim::NimProject No Nim compiler set. Компилятор Nim не задан. @@ -27006,35 +26988,15 @@ If set to false, the target will be moved straight to the current mouse position Nim compiler does not exist. Компилятор Nim отсутствует. - - - Nim::NimRunConfiguration Current Build Target Цель текущей сборки - - - Nim::NimSettings Global Settings Общие - - Nim - Nim - - - - Nim::NimToolChain - - Nim - Nim - - - - Nim::NimToolChainConfigWidget &Compiler path: Путь к &компилятору: @@ -27043,9 +27005,6 @@ If set to false, the target will be moved straight to the current mouse position &Compiler version: &Версия компилятора: - - - Nim::NimToolsSettingsWidget Nimsuggest Nimsuggest @@ -27054,23 +27013,10 @@ If set to false, the target will be moved straight to the current mouse position Path Путь - - - Nim::NimbleBuildConfiguration - - General - Основное - - - - Nim::NimbleBuildStep Nimble Build Сборка Nimble - - - Nim::NimbleBuildStepWidget Form @@ -27083,9 +27029,6 @@ If set to false, the target will be moved straight to the current mouse position Reset to Default Сбросить на умолчальные - - - Nim::NimbleTaskStep Nimble task %1 not found. Не удалось найти задачу Nimble %1. @@ -27094,13 +27037,6 @@ If set to false, the target will be moved straight to the current mouse position Nimble Task Задача Nimble - - - Nim::NimbleTaskStepWidget - - Form - - Task arguments: Параметры задачи: @@ -27109,77 +27045,22 @@ If set to false, the target will be moved straight to the current mouse position Tasks: Задачи: - - - Nim::NimbleTestConfiguration Nimble Test Тест Nimble - - - Nim::ToolSettingsPage - - Nim - Nim - - - - NimCodeStylePreferencesFactory - - Nim - Nim - - - - NimCodeStyleSettingsPage Code Style Стиль кода - - Nim - Nim - - - - NimCompilerBuildStep - - Nim Compiler Build Step - Этап сборки компилятора Nim - - - - NimCompilerBuildStepConfigWidget Nim build step Этап сборки Nim - - - NimToolsSettingsPage Tools Инструменты - - Nim - Nim - - - - NimbleBuildStep - - Nimble Build - Сборка Nimble - - - - NimbleTaskStep - - Nimble Task - Задача Nimble - NoShowCheckbox diff --git a/src/plugins/nim/editor/nimeditorfactory.cpp b/src/plugins/nim/editor/nimeditorfactory.cpp index 66a7f49ca07..b514b7e186a 100644 --- a/src/plugins/nim/editor/nimeditorfactory.cpp +++ b/src/plugins/nim/editor/nimeditorfactory.cpp @@ -7,7 +7,6 @@ #include "nimcompletionassistprovider.h" #include "../nimconstants.h" -#include "../nimplugin.h" #include "nimtexteditorwidget.h" #include @@ -55,4 +54,4 @@ void NimEditorFactory::decorateEditor(TextEditorWidget *editor) editor->textDocument()->setIndenter(new NimIndenter(editor->textDocument()->document())); } -} +} // Nim diff --git a/src/plugins/nim/editor/nimhighlighter.cpp b/src/plugins/nim/editor/nimhighlighter.cpp index 577d83dcac2..2ded9a5ccfb 100644 --- a/src/plugins/nim/editor/nimhighlighter.cpp +++ b/src/plugins/nim/editor/nimhighlighter.cpp @@ -92,4 +92,4 @@ int NimHighlighter::highlightLine(const QString &text, int initialState) return lexer.state(); } -} +} // Nim diff --git a/src/plugins/nim/editor/nimindenter.cpp b/src/plugins/nim/editor/nimindenter.cpp index 4bc879382ee..4d209a64474 100644 --- a/src/plugins/nim/editor/nimindenter.cpp +++ b/src/plugins/nim/editor/nimindenter.cpp @@ -151,4 +151,4 @@ QString NimIndenter::rightTrimmed(const QString &str) return QString(); } -} +} // Nim diff --git a/src/plugins/nim/editor/nimtexteditorwidget.cpp b/src/plugins/nim/editor/nimtexteditorwidget.cpp index a2357323fb3..0a3862fb8ff 100644 --- a/src/plugins/nim/editor/nimtexteditorwidget.cpp +++ b/src/plugins/nim/editor/nimtexteditorwidget.cpp @@ -15,12 +15,11 @@ #include #include -using namespace Nim; -using namespace Suggest; +using namespace Nim::Suggest; -namespace { +namespace Nim { -std::unique_ptr writeDirtyFile(const TextEditor::TextDocument *doc) +static std::unique_ptr writeDirtyFile(const TextEditor::TextDocument *doc) { auto result = std::make_unique("qtcnim.XXXXXX.nim"); QTC_ASSERT(result->open(), return nullptr); @@ -30,8 +29,6 @@ std::unique_ptr writeDirtyFile(const TextEditor::TextDocument *d return result; } -} - NimTextEditorWidget::NimTextEditorWidget(QWidget *parent) : TextEditorWidget(parent) { @@ -87,3 +84,5 @@ void NimTextEditorWidget::onFindLinkFinished(Suggest::NimSuggestClientRequest *r const Line &line = m_request->lines().front(); m_callback(Utils::Link{Utils::FilePath::fromString(line.abs_path), line.row, line.column}); } + +} // Nim diff --git a/src/plugins/nim/nimconstants.h b/src/plugins/nim/nimconstants.h index 5b0c4d17eba..d8821cf3600 100644 --- a/src/plugins/nim/nimconstants.h +++ b/src/plugins/nim/nimconstants.h @@ -30,7 +30,6 @@ const char C_NIMBLEBUILDSTEP_ARGUMENTS[] = "Nim.NimbleBuildStep.Arguments"; // NimbleTaskStep const char C_NIMBLETASKSTEP_ID[] = "Nim.NimbleTaskStep"; -const char C_NIMBLETASKSTEP_DISPLAY[] = QT_TRANSLATE_NOOP("NimbleTaskStep", "Nimble Task"); const QString C_NIMBLETASKSTEP_TASKNAME = QStringLiteral("Nim.NimbleTaskStep.TaskName"); const QString C_NIMBLETASKSTEP_TASKARGS = QStringLiteral("Nim.NimbleTaskStep.TaskArgs"); @@ -48,16 +47,12 @@ const char C_NIMPARSE_ID[] = "Nim.NimParse"; const char C_NIMLANGUAGE_ID[] = "Nim"; const char C_NIMCODESTYLESETTINGSPAGE_ID[] = "Nim.NimCodeStyleSettings"; -const char C_NIMCODESTYLESETTINGSPAGE_DISPLAY[] = QT_TRANSLATE_NOOP("NimCodeStyleSettingsPage", "Code Style"); const char C_NIMCODESTYLESETTINGSPAGE_CATEGORY[] = "Z.Nim"; -const char C_NIMCODESTYLESETTINGSPAGE_CATEGORY_DISPLAY[] = QT_TRANSLATE_NOOP("NimCodeStyleSettingsPage", "Nim"); const char C_NIMTOOLSSETTINGSPAGE_ID[] = "Nim.NimToolsSettings"; -const char C_NIMTOOLSSETTINGSPAGE_DISPLAY[] = QT_TRANSLATE_NOOP("NimToolsSettingsPage", "Tools"); const char C_NIMTOOLSSETTINGSPAGE_CATEGORY[] = "Z.Nim"; -const char C_NIMTOOLSSETTINGSPAGE_CATEGORY_DISPLAY[] = QT_TRANSLATE_NOOP("NimToolsSettingsPage", "Nim"); -const char C_NIMLANGUAGE_NAME[] = QT_TRANSLATE_NOOP("NimCodeStylePreferencesFactory", "Nim"); +const char C_NIMLANGUAGE_NAME[] = QT_TRANSLATE_NOOP("Nim", "Nim"); const char C_NIMGLOBALCODESTYLE_ID[] = "NimGlobal"; const QString C_NIMSNIPPETSGROUP_ID = QStringLiteral("Nim.NimSnippetsGroup"); diff --git a/src/plugins/nim/nimplugin.cpp b/src/plugins/nim/nimplugin.cpp index b1b5329432b..eeac1db145d 100644 --- a/src/plugins/nim/nimplugin.cpp +++ b/src/plugins/nim/nimplugin.cpp @@ -4,6 +4,7 @@ #include "nimplugin.h" #include "nimconstants.h" +#include "nimtr.h" #include "editor/nimeditorfactory.h" #include "project/nimblerunconfiguration.h" #include "project/nimblebuildconfiguration.h" @@ -94,7 +95,7 @@ bool NimPlugin::initialize(const QStringList &arguments, QString *errorMessage) ToolChainManager::registerLanguage(Constants::C_NIMLANGUAGE_ID, Constants::C_NIMLANGUAGE_NAME); TextEditor::SnippetProvider::registerGroup(Constants::C_NIMSNIPPETSGROUP_ID, - tr("Nim", "SnippetProvider"), + Tr::tr("Nim", "SnippetProvider"), &NimEditorFactory::decorateEditor); ProjectManager::registerProjectType(Constants::C_NIM_PROJECT_MIMETYPE); diff --git a/src/plugins/nim/project/nimblebuildconfiguration.cpp b/src/plugins/nim/project/nimblebuildconfiguration.cpp index f4d48be2e5e..5946f511a8e 100644 --- a/src/plugins/nim/project/nimblebuildconfiguration.cpp +++ b/src/plugins/nim/project/nimblebuildconfiguration.cpp @@ -4,9 +4,7 @@ #include "nimblebuildconfiguration.h" #include "nimconstants.h" -//#include "nimblebuildstep.h" -#include "nimbleproject.h" -#include "nimblebuildsystem.h" +#include "nimtr.h" #include #include @@ -14,20 +12,16 @@ #include #include #include -#include -#include -#include -#include - -using namespace Nim; using namespace ProjectExplorer; using namespace Utils; -NimbleBuildConfiguration::NimbleBuildConfiguration(Target *target, Utils::Id id) +namespace Nim { + +NimbleBuildConfiguration::NimbleBuildConfiguration(Target *target, Id id) : BuildConfiguration(target, id) { - setConfigWidgetDisplayName(tr("General")); + setConfigWidgetDisplayName(Tr::tr("General")); setConfigWidgetHasFrame(true); setBuildDirectorySettingsKey("Nim.NimbleBuildConfiguration.BuildDirectory"); appendInitialBuildStep(Constants::C_NIMBLEBUILDSTEP_ID); @@ -82,8 +76,10 @@ NimbleBuildConfigurationFactory::NimbleBuildConfigurationFactory() return info; }; return QList{ - oneBuild(BuildConfiguration::Debug, BuildConfiguration::tr("Debug")), - oneBuild(BuildConfiguration::Release, BuildConfiguration::tr("Release")) + oneBuild(BuildConfiguration::Debug, Tr::tr("Debug")), + oneBuild(BuildConfiguration::Release, Tr::tr("Release")) }; }); } + +} // Nim diff --git a/src/plugins/nim/project/nimblebuildstep.cpp b/src/plugins/nim/project/nimblebuildstep.cpp index 089d7813f24..ad0fe90a38b 100644 --- a/src/plugins/nim/project/nimblebuildstep.cpp +++ b/src/plugins/nim/project/nimblebuildstep.cpp @@ -6,6 +6,7 @@ #include "nimconstants.h" #include "nimbuildsystem.h" #include "nimoutputtaskparser.h" +#include "nimtr.h" #include #include @@ -19,8 +20,6 @@ namespace Nim { class NimbleBuildStep : public AbstractProcessStep { - Q_DECLARE_TR_FUNCTIONS(Nim::NimbleBuilStep) - public: NimbleBuildStep(BuildStepList *parentList, Id id); @@ -77,7 +76,7 @@ QString NimbleBuildStep::defaultArguments() const NimbleBuildStepFactory::NimbleBuildStepFactory() { registerStep(Constants::C_NIMBLEBUILDSTEP_ID); - setDisplayName(NimbleBuildStep::tr("Nimble Build")); + setDisplayName(Tr::tr("Nimble Build")); setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); setSupportedConfiguration(Constants::C_NIMBLEBUILDCONFIGURATION_ID); setRepeatable(true); diff --git a/src/plugins/nim/project/nimblebuildsystem.cpp b/src/plugins/nim/project/nimblebuildsystem.cpp index 973d05b85f6..ae8f7a7e583 100644 --- a/src/plugins/nim/project/nimblebuildsystem.cpp +++ b/src/plugins/nim/project/nimblebuildsystem.cpp @@ -4,8 +4,6 @@ #include "nimblebuildsystem.h" #include "nimbuildsystem.h" -#include "nimbleproject.h" -#include "nimproject.h" #include "../nimconstants.h" #include diff --git a/src/plugins/nim/project/nimbleproject.cpp b/src/plugins/nim/project/nimbleproject.cpp index 9bf886b0c51..cbb61d3b64e 100644 --- a/src/plugins/nim/project/nimbleproject.cpp +++ b/src/plugins/nim/project/nimbleproject.cpp @@ -9,9 +9,10 @@ #include #include -using namespace Nim; using namespace ProjectExplorer; +namespace Nim { + NimbleProject::NimbleProject(const Utils::FilePath &fileName) : ProjectExplorer::Project(Constants::C_NIMBLE_MIMETYPE, fileName) { @@ -46,4 +47,4 @@ void NimbleProject::setExcludedFiles(const QStringList &excludedFiles) m_excludedFiles = excludedFiles; } - +} // Nim diff --git a/src/plugins/nim/project/nimbleproject.h b/src/plugins/nim/project/nimbleproject.h index 202c3136ad9..76231f1d536 100644 --- a/src/plugins/nim/project/nimbleproject.h +++ b/src/plugins/nim/project/nimbleproject.h @@ -28,4 +28,4 @@ protected: QStringList m_excludedFiles; }; -} +} // Nim diff --git a/src/plugins/nim/project/nimblerunconfiguration.cpp b/src/plugins/nim/project/nimblerunconfiguration.cpp index 77b9ffa31d2..a3744d0a379 100644 --- a/src/plugins/nim/project/nimblerunconfiguration.cpp +++ b/src/plugins/nim/project/nimblerunconfiguration.cpp @@ -5,6 +5,7 @@ #include "nimbuildsystem.h" #include "nimconstants.h" +#include "nimtr.h" #include #include @@ -23,8 +24,6 @@ namespace Nim { class NimbleRunConfiguration : public RunConfiguration { - Q_DECLARE_TR_FUNCTIONS(Nim::NimbleRunConfiguration) - public: NimbleRunConfiguration(Target *target, Utils::Id id) : RunConfiguration(target, id) @@ -61,8 +60,6 @@ NimbleRunConfigurationFactory::NimbleRunConfigurationFactory() class NimbleTestConfiguration : public RunConfiguration { - Q_DECLARE_TR_FUNCTIONS(Nim::NimbleTestConfiguration) - public: NimbleTestConfiguration(ProjectExplorer::Target *target, Utils::Id id) : RunConfiguration(target, id) @@ -74,8 +71,8 @@ public: ->setDefaultWorkingDirectory(project()->projectDirectory()); addAspect(); - setDisplayName(tr("Nimble Test")); - setDefaultDisplayName(tr("Nimble Test")); + setDisplayName(Tr::tr("Nimble Test")); + setDefaultDisplayName(Tr::tr("Nimble Test")); } }; diff --git a/src/plugins/nim/project/nimbletaskstep.cpp b/src/plugins/nim/project/nimbletaskstep.cpp index 6a858f32812..2376dcb4987 100644 --- a/src/plugins/nim/project/nimbletaskstep.cpp +++ b/src/plugins/nim/project/nimbletaskstep.cpp @@ -5,7 +5,7 @@ #include "nimconstants.h" #include "nimblebuildsystem.h" -#include "nimbleproject.h" +#include "nimtr.h" #include #include @@ -32,8 +32,6 @@ namespace Nim { class NimbleTaskStep final : public AbstractProcessStep { - Q_DECLARE_TR_FUNCTIONS(Nim::NimbleTaskStep) - public: NimbleTaskStep(BuildStepList *parentList, Id id); @@ -59,8 +57,9 @@ private: NimbleTaskStep::NimbleTaskStep(BuildStepList *parentList, Id id) : AbstractProcessStep(parentList, id) { - setDefaultDisplayName(tr(Constants::C_NIMBLETASKSTEP_DISPLAY)); - setDisplayName(tr(Constants::C_NIMBLETASKSTEP_DISPLAY)); + const QString display = Tr::tr("Nimble Task"); + setDefaultDisplayName(display); + setDisplayName(display); setCommandLineProvider([this] { QString args = m_taskName->value() + " " + m_taskArgs->value(); @@ -75,7 +74,7 @@ NimbleTaskStep::NimbleTaskStep(BuildStepList *parentList, Id id) m_taskArgs = addAspect(); m_taskArgs->setSettingsKey(Constants::C_NIMBLETASKSTEP_TASKARGS); m_taskArgs->setDisplayStyle(StringAspect::LineEditDisplay); - m_taskArgs->setLabelText(tr("Task arguments:")); + m_taskArgs->setLabelText(Tr::tr("Task arguments:")); } QWidget *NimbleTaskStep::createConfigWidget() @@ -89,7 +88,7 @@ QWidget *NimbleTaskStep::createConfigWidget() using namespace Layouting; auto widget = Form { m_taskArgs, - tr("Tasks:"), taskList + Tr::tr("Tasks:"), taskList }.emerge(WithoutMargins); auto buildSystem = dynamic_cast(this->buildSystem()); @@ -215,7 +214,7 @@ bool NimbleTaskStep::validate() auto matchName = [this](const NimbleTask &task) { return task.name == m_taskName->value(); }; if (!Utils::contains(nimbleBuildSystem->tasks(), matchName)) { - emit addTask(BuildSystemTask(Task::Error, tr("Nimble task %1 not found.") + emit addTask(BuildSystemTask(Task::Error, Tr::tr("Nimble task %1 not found.") .arg(m_taskName->value()))); emitFaultyConfigurationMessage(); return false; @@ -229,7 +228,7 @@ bool NimbleTaskStep::validate() NimbleTaskStepFactory::NimbleTaskStepFactory() { registerStep(Constants::C_NIMBLETASKSTEP_ID); - setDisplayName(NimbleTaskStep::tr("Nimble Task")); + setDisplayName(Tr::tr("Nimble Task")); setSupportedStepLists({ProjectExplorer::Constants::BUILDSTEPS_BUILD, ProjectExplorer::Constants::BUILDSTEPS_CLEAN, ProjectExplorer::Constants::BUILDSTEPS_DEPLOY}); diff --git a/src/plugins/nim/project/nimbuildconfiguration.cpp b/src/plugins/nim/project/nimbuildconfiguration.cpp index 4196b57854b..8b556d83d3e 100644 --- a/src/plugins/nim/project/nimbuildconfiguration.cpp +++ b/src/plugins/nim/project/nimbuildconfiguration.cpp @@ -3,8 +3,8 @@ #include "nimbuildconfiguration.h" #include "nimcompilerbuildstep.h" -#include "nimproject.h" +#include "../nimtr.h" #include "../nimconstants.h" #include @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,7 @@ static FilePath defaultBuildDirectory(const Kit *k, NimBuildConfiguration::NimBuildConfiguration(Target *target, Utils::Id id) : BuildConfiguration(target, id) { - setConfigWidgetDisplayName(tr("General")); + setConfigWidgetDisplayName(Tr::tr("General")); setConfigWidgetHasFrame(true); setBuildDirectorySettingsKey("Nim.NimBuildConfiguration.BuildDirectory"); @@ -90,8 +91,8 @@ NimBuildConfigurationFactory::NimBuildConfigurationFactory() return info; }; return QList{ - oneBuild(BuildConfiguration::Debug, BuildConfiguration::tr("Debug")), - oneBuild(BuildConfiguration::Release, BuildConfiguration::tr("Release")) + oneBuild(BuildConfiguration::Debug, Tr::tr("Debug")), + oneBuild(BuildConfiguration::Release, Tr::tr("Release")) }; }); } diff --git a/src/plugins/nim/project/nimbuildsystem.cpp b/src/plugins/nim/project/nimbuildsystem.cpp index 5033080a020..67af305fcd8 100644 --- a/src/plugins/nim/project/nimbuildsystem.cpp +++ b/src/plugins/nim/project/nimbuildsystem.cpp @@ -4,7 +4,6 @@ #include "nimbuildsystem.h" #include "nimconstants.h" -#include "nimproject.h" #include "nimbleproject.h" #include diff --git a/src/plugins/nim/project/nimcompilerbuildstep.cpp b/src/plugins/nim/project/nimcompilerbuildstep.cpp index 958b9388a2a..31b335ebb7a 100644 --- a/src/plugins/nim/project/nimcompilerbuildstep.cpp +++ b/src/plugins/nim/project/nimcompilerbuildstep.cpp @@ -4,16 +4,17 @@ #include "nimcompilerbuildstep.h" #include "nimbuildconfiguration.h" -#include "nimbuildsystem.h" #include "nimconstants.h" #include "nimoutputtaskparser.h" -#include "nimtoolchain.h" +#include "nimtr.h" -#include #include #include #include +#include +#include #include +#include #include #include @@ -30,12 +31,12 @@ using namespace Utils; namespace Nim { -NimCompilerBuildStep::NimCompilerBuildStep(BuildStepList *parentList, Utils::Id id) +NimCompilerBuildStep::NimCompilerBuildStep(BuildStepList *parentList, Id id) : AbstractProcessStep(parentList, id) { setCommandLineProvider([this] { return commandLine(); }); - connect(project(), &ProjectExplorer::Project::fileListChanged, + connect(project(), &Project::fileListChanged, this, &NimCompilerBuildStep::updateTargetNimFile); } @@ -51,8 +52,8 @@ QWidget *NimCompilerBuildStep::createConfigWidget() { auto widget = new QWidget; - setDisplayName(tr("Nim build step")); - setSummaryText(tr("Nim build step")); + setDisplayName(Tr::tr("Nim build step")); + setSummaryText(Tr::tr("Nim build step")); auto targetComboBox = new QComboBox(widget); @@ -63,15 +64,15 @@ QWidget *NimCompilerBuildStep::createConfigWidget() commandTextEdit->setMinimumSize(QSize(0, 0)); auto defaultArgumentsComboBox = new QComboBox(widget); - defaultArgumentsComboBox->addItem(tr("None")); - defaultArgumentsComboBox->addItem(tr("Debug")); - defaultArgumentsComboBox->addItem(tr("Release")); + defaultArgumentsComboBox->addItem(Tr::tr("None")); + defaultArgumentsComboBox->addItem(Tr::tr("Debug")); + defaultArgumentsComboBox->addItem(Tr::tr("Release")); auto formLayout = new QFormLayout(widget); - formLayout->addRow(tr("Target:"), targetComboBox); - formLayout->addRow(tr("Default arguments:"), defaultArgumentsComboBox); - formLayout->addRow(tr("Extra arguments:"), additionalArgumentsLineEdit); - formLayout->addRow(tr("Command:"), commandTextEdit); + formLayout->addRow(Tr::tr("Target:"), targetComboBox); + formLayout->addRow(Tr::tr("Default arguments:"), defaultArgumentsComboBox); + formLayout->addRow(Tr::tr("Extra arguments:"), additionalArgumentsLineEdit); + formLayout->addRow(Tr::tr("Command:"), commandTextEdit); auto updateUi = [=] { const CommandLine cmd = commandLine(); @@ -211,7 +212,7 @@ void NimCompilerBuildStep::updateTargetNimFile() NimCompilerBuildStepFactory::NimCompilerBuildStepFactory() { registerStep(Constants::C_NIMCOMPILERBUILDSTEP_ID); - setDisplayName(NimCompilerBuildStep::tr("Nim Compiler Build Step")); + setDisplayName(Tr::tr("Nim Compiler Build Step")); setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); setSupportedConfiguration(Constants::C_NIMBUILDCONFIGURATION_ID); setRepeatable(false); diff --git a/src/plugins/nim/project/nimcompilercleanstep.cpp b/src/plugins/nim/project/nimcompilercleanstep.cpp index 6ed7aa920b4..6eb22ce4e25 100644 --- a/src/plugins/nim/project/nimcompilercleanstep.cpp +++ b/src/plugins/nim/project/nimcompilercleanstep.cpp @@ -5,6 +5,7 @@ #include "nimbuildconfiguration.h" #include "../nimconstants.h" +#include "../nimtr.h" #include @@ -21,10 +22,8 @@ namespace Nim { class NimCompilerCleanStep final : public BuildStep { - Q_DECLARE_TR_FUNCTIONS(Nim::NimCompilerCleanStep) - public: - NimCompilerCleanStep(BuildStepList *parentList, Utils::Id id); + NimCompilerCleanStep(BuildStepList *parentList, Id id); private: bool init() final; @@ -34,14 +33,14 @@ private: bool removeCacheDirectory(); bool removeOutFilePath(); - Utils::FilePath m_buildDir; + FilePath m_buildDir; }; -NimCompilerCleanStep::NimCompilerCleanStep(BuildStepList *parentList, Utils::Id id) +NimCompilerCleanStep::NimCompilerCleanStep(BuildStepList *parentList, Id id) : BuildStep(parentList, id) { auto workingDirectory = addAspect(); - workingDirectory->setLabelText(tr("Working directory:")); + workingDirectory->setLabelText(Tr::tr("Working directory:")); workingDirectory->setDisplayStyle(StringAspect::LineEditDisplay); setSummaryUpdater([this, workingDirectory] { @@ -62,24 +61,24 @@ bool NimCompilerCleanStep::init() void NimCompilerCleanStep::doRun() { if (!m_buildDir.exists()) { - emit addOutput(tr("Build directory \"%1\" does not exist.").arg(m_buildDir.toUserOutput()), OutputFormat::ErrorMessage); + emit addOutput(Tr::tr("Build directory \"%1\" does not exist.").arg(m_buildDir.toUserOutput()), OutputFormat::ErrorMessage); emit finished(false); return; } if (!removeCacheDirectory()) { - emit addOutput(tr("Failed to delete the cache directory."), OutputFormat::ErrorMessage); + emit addOutput(Tr::tr("Failed to delete the cache directory."), OutputFormat::ErrorMessage); emit finished(false); return; } if (!removeOutFilePath()) { - emit addOutput(tr("Failed to delete the out file."), OutputFormat::ErrorMessage); + emit addOutput(Tr::tr("Failed to delete the out file."), OutputFormat::ErrorMessage); emit finished(false); return; } - emit addOutput(tr("Clean step completed successfully."), OutputFormat::NormalMessage); + emit addOutput(Tr::tr("Clean step completed successfully."), OutputFormat::NormalMessage); emit finished(true); } @@ -115,7 +114,7 @@ NimCompilerCleanStepFactory::NimCompilerCleanStepFactory() setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN); setSupportedConfiguration(Constants::C_NIMBUILDCONFIGURATION_ID); setRepeatable(false); - setDisplayName(NimCompilerCleanStep::tr("Nim Clean Step")); + setDisplayName(Tr::tr("Nim Clean Step")); } } // Nim diff --git a/src/plugins/nim/project/nimoutputtaskparser.cpp b/src/plugins/nim/project/nimoutputtaskparser.cpp index 37858b62e7e..f27ad121dd3 100644 --- a/src/plugins/nim/project/nimoutputtaskparser.cpp +++ b/src/plugins/nim/project/nimoutputtaskparser.cpp @@ -10,7 +10,7 @@ using namespace Utils; namespace Nim { -NimParser::Result NimParser::handleLine(const QString &lne, Utils::OutputFormat) +NimParser::Result NimParser::handleLine(const QString &lne, OutputFormat) { const QString line = lne.trimmed(); static const QRegularExpression regex("(.+.nim)\\((\\d+), (\\d+)\\) (.+)"); @@ -44,7 +44,7 @@ NimParser::Result NimParser::handleLine(const QString &lne, Utils::OutputFormat) return {Status::Done, linkSpecs}; } -} // namespace Nim +} // Nim #ifdef WITH_TESTS diff --git a/src/plugins/nim/project/nimproject.cpp b/src/plugins/nim/project/nimproject.cpp index 6df37bca328..83d21ce234e 100644 --- a/src/plugins/nim/project/nimproject.cpp +++ b/src/plugins/nim/project/nimproject.cpp @@ -4,6 +4,7 @@ #include "nimproject.h" #include "../nimconstants.h" +#include "../nimtr.h" #include "nimbuildsystem.h" #include "nimtoolchain.h" @@ -31,11 +32,11 @@ Tasks NimProject::projectIssues(const Kit *k) const Tasks result = Project::projectIssues(k); auto tc = dynamic_cast(ToolChainKitAspect::toolChain(k, Constants::C_NIMLANGUAGE_ID)); if (!tc) { - result.append(createProjectTask(Task::TaskType::Error, tr("No Nim compiler set."))); + result.append(createProjectTask(Task::TaskType::Error, Tr::tr("No Nim compiler set."))); return result; } if (!tc->compilerCommand().exists()) - result.append(createProjectTask(Task::TaskType::Error, tr("Nim compiler does not exist."))); + result.append(createProjectTask(Task::TaskType::Error, Tr::tr("Nim compiler does not exist."))); return result; } @@ -64,4 +65,4 @@ void NimProject::setExcludedFiles(const QStringList &excludedFiles) m_excludedFiles = excludedFiles; } -} // namespace Nim +} // Nim diff --git a/src/plugins/nim/project/nimrunconfiguration.cpp b/src/plugins/nim/project/nimrunconfiguration.cpp index 2be3eadef5f..0396eed359b 100644 --- a/src/plugins/nim/project/nimrunconfiguration.cpp +++ b/src/plugins/nim/project/nimrunconfiguration.cpp @@ -5,6 +5,7 @@ #include "nimbuildconfiguration.h" #include "../nimconstants.h" +#include "../nimtr.h" #include #include @@ -21,8 +22,6 @@ namespace Nim { class NimRunConfiguration final : public RunConfiguration { - Q_DECLARE_TR_FUNCTIONS(Nim::NimRunConfiguration) - public: NimRunConfiguration(Target *target, Utils::Id id) : RunConfiguration(target, id) @@ -33,8 +32,8 @@ public: addAspect(macroExpander(), envAspect); addAspect(); - setDisplayName(tr("Current Build Target")); - setDefaultDisplayName(tr("Current Build Target")); + setDisplayName(Tr::tr("Current Build Target")); + setDefaultDisplayName(Tr::tr("Current Build Target")); setUpdater([this, target] { auto buildConfiguration = qobject_cast(target->activeBuildConfiguration()); diff --git a/src/plugins/nim/project/nimtoolchain.cpp b/src/plugins/nim/project/nimtoolchain.cpp index 4a893f975b2..c62de76b337 100644 --- a/src/plugins/nim/project/nimtoolchain.cpp +++ b/src/plugins/nim/project/nimtoolchain.cpp @@ -2,14 +2,15 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "nimtoolchain.h" + #include "nimconstants.h" #include "nimtoolchainfactory.h" +#include "nimtr.h" #include #include #include -#include #include using namespace ProjectExplorer; @@ -26,7 +27,7 @@ NimToolChain::NimToolChain(Utils::Id typeId) , m_version(std::make_tuple(-1,-1,-1)) { setLanguage(Constants::C_NIMLANGUAGE_ID); - setTypeDisplayName(tr("Nim")); + setTypeDisplayName(Tr::tr("Nim")); setTargetAbiNoSignal(Abi::hostAbi()); setCompilerCommandKey("Nim.NimToolChain.CompilerCommand"); } diff --git a/src/plugins/nim/project/nimtoolchain.h b/src/plugins/nim/project/nimtoolchain.h index f5e10ae62e4..8ef087fe8a1 100644 --- a/src/plugins/nim/project/nimtoolchain.h +++ b/src/plugins/nim/project/nimtoolchain.h @@ -10,8 +10,6 @@ namespace Nim { class NimToolChain : public ProjectExplorer::ToolChain { - Q_DECLARE_TR_FUNCTIONS(Nim::NimToolChain) - public: NimToolChain(); explicit NimToolChain(Utils::Id typeId); diff --git a/src/plugins/nim/project/nimtoolchainfactory.cpp b/src/plugins/nim/project/nimtoolchainfactory.cpp index e3e9feb9e1e..bf14c9ca5c2 100644 --- a/src/plugins/nim/project/nimtoolchainfactory.cpp +++ b/src/plugins/nim/project/nimtoolchainfactory.cpp @@ -5,6 +5,7 @@ #include "nimconstants.h" #include "nimtoolchain.h" +#include "nimtr.h" #include @@ -23,7 +24,7 @@ namespace Nim { NimToolChainFactory::NimToolChainFactory() { - setDisplayName(NimToolChain::tr("Nim")); + setDisplayName(Tr::tr("Nim")); setSupportedToolChainType(Constants::C_NIMTOOLCHAIN_TYPEID); setSupportedLanguages({Constants::C_NIMLANGUAGE_ID}); setToolchainConstructor([] { return new NimToolChain; }); @@ -77,9 +78,9 @@ NimToolChainConfigWidget::NimToolChainConfigWidget(NimToolChain *tc) const auto gnuVersionArgs = QStringList("--version"); m_compilerCommand->setExpectedKind(PathChooser::ExistingCommand); m_compilerCommand->setCommandVersionArguments(gnuVersionArgs); - m_mainLayout->addRow(tr("&Compiler path:"), m_compilerCommand); + m_mainLayout->addRow(Tr::tr("&Compiler path:"), m_compilerCommand); m_compilerVersion->setReadOnly(true); - m_mainLayout->addRow(tr("&Compiler version:"), m_compilerVersion); + m_mainLayout->addRow(Tr::tr("&Compiler version:"), m_compilerVersion); // Fill fillUI(); diff --git a/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp b/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp index f17f4c7ad30..59f534d816c 100644 --- a/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp +++ b/src/plugins/nim/settings/nimcodestylepreferencesfactory.cpp @@ -4,13 +4,17 @@ #include "nimcodestylepreferencesfactory.h" #include "nimcodestylepreferenceswidget.h" -#include "../nimconstants.h" #include "../editor/nimindenter.h" +#include "../nimconstants.h" +#include "../nimtr.h" #include #include +#include +#include + using namespace TextEditor; namespace Nim { @@ -26,16 +30,16 @@ Utils::Id NimCodeStylePreferencesFactory::languageId() QString NimCodeStylePreferencesFactory::displayName() { - return tr(Constants::C_NIMLANGUAGE_NAME); + return Tr::tr(Constants::C_NIMLANGUAGE_NAME); } -TextEditor::ICodeStylePreferences *NimCodeStylePreferencesFactory::createCodeStyle() const +ICodeStylePreferences *NimCodeStylePreferencesFactory::createCodeStyle() const { - return new TextEditor::SimpleCodeStylePreferences(); + return new SimpleCodeStylePreferences(); } -TextEditor::CodeStyleEditorWidget *NimCodeStylePreferencesFactory::createEditor( - TextEditor::ICodeStylePreferences *preferences, +CodeStyleEditorWidget *NimCodeStylePreferencesFactory::createEditor( + ICodeStylePreferences *preferences, ProjectExplorer::Project *project, QWidget *parent) const { @@ -44,7 +48,7 @@ TextEditor::CodeStyleEditorWidget *NimCodeStylePreferencesFactory::createEditor( return result; } -TextEditor::Indenter *NimCodeStylePreferencesFactory::createIndenter(QTextDocument *doc) const +Indenter *NimCodeStylePreferencesFactory::createIndenter(QTextDocument *doc) const { return new NimIndenter(doc); } @@ -59,4 +63,4 @@ QString NimCodeStylePreferencesFactory::previewText() const return QLatin1String(Nim::Constants::C_NIMCODESTYLEPREVIEWSNIPPET); } -} +} // Nim diff --git a/src/plugins/nim/settings/nimcodestylepreferencesfactory.h b/src/plugins/nim/settings/nimcodestylepreferencesfactory.h index f45a6acafac..c0686236fcd 100644 --- a/src/plugins/nim/settings/nimcodestylepreferencesfactory.h +++ b/src/plugins/nim/settings/nimcodestylepreferencesfactory.h @@ -9,8 +9,6 @@ namespace Nim { class NimCodeStylePreferencesFactory : public TextEditor::ICodeStylePreferencesFactory { - Q_DECLARE_TR_FUNCTIONS(Nim::NimCodeStylePreferencesFactory) - public: NimCodeStylePreferencesFactory(); diff --git a/src/plugins/nim/settings/nimcodestylesettingspage.cpp b/src/plugins/nim/settings/nimcodestylesettingspage.cpp index fe24473ec24..30bc0698f57 100644 --- a/src/plugins/nim/settings/nimcodestylesettingspage.cpp +++ b/src/plugins/nim/settings/nimcodestylesettingspage.cpp @@ -2,10 +2,10 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "nimcodestylesettingspage.h" -#include "nimcodestylepreferencesfactory.h" -#include "nimsettings.h" #include "../nimconstants.h" +#include "../nimtr.h" +#include "nimsettings.h" #include #include @@ -20,8 +20,6 @@ namespace Nim { class NimCodeStyleSettingsWidget : public Core::IOptionsPageWidget { - Q_DECLARE_TR_FUNCTIONS(Nim::CodeStyleSettings) - public: NimCodeStyleSettingsWidget() { @@ -51,9 +49,9 @@ private: NimCodeStyleSettingsPage::NimCodeStyleSettingsPage() { setId(Nim::Constants::C_NIMCODESTYLESETTINGSPAGE_ID); - setDisplayName(tr(Nim::Constants::C_NIMCODESTYLESETTINGSPAGE_DISPLAY)); + setDisplayName(Tr::tr("Code Style")); setCategory(Nim::Constants::C_NIMCODESTYLESETTINGSPAGE_CATEGORY); - setDisplayCategory(NimCodeStyleSettingsWidget::tr("Nim")); + setDisplayCategory(Tr::tr("Nim")); setCategoryIconPath(":/nim/images/settingscategory_nim.png"); setWidgetCreator([] { return new NimCodeStyleSettingsWidget; }); } diff --git a/src/plugins/nim/settings/nimsettings.cpp b/src/plugins/nim/settings/nimsettings.cpp index c0be992ef47..d85d1a80e9c 100644 --- a/src/plugins/nim/settings/nimsettings.cpp +++ b/src/plugins/nim/settings/nimsettings.cpp @@ -2,9 +2,10 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "nimsettings.h" -#include "nimcodestylepreferencesfactory.h" #include "../nimconstants.h" +#include "../nimtr.h" +#include "nimcodestylepreferencesfactory.h" #include @@ -34,7 +35,7 @@ NimSettings::NimSettings() nimSuggestPath.setSettingsKey("Command"); nimSuggestPath.setDisplayStyle(StringAspect::PathChooserDisplay); nimSuggestPath.setExpectedKind(PathChooser::ExistingCommand); - nimSuggestPath.setLabelText(tr("Path:")); + nimSuggestPath.setLabelText(Tr::tr("Path:")); readSettings(Core::ICore::settings()); } @@ -61,14 +62,14 @@ void NimSettings::InitializeCodeStyleSettings() m_globalCodeStyle = new SimpleCodeStylePreferences(); m_globalCodeStyle->setDelegatingPool(pool); - m_globalCodeStyle->setDisplayName(tr("Global", "Settings")); + m_globalCodeStyle->setDisplayName(Tr::tr("Global", "Settings")); m_globalCodeStyle->setId(Nim::Constants::C_NIMGLOBALCODESTYLE_ID); pool->addCodeStyle(m_globalCodeStyle); TextEditorSettings::registerCodeStyle(Nim::Constants::C_NIMLANGUAGE_ID, m_globalCodeStyle); auto nimCodeStyle = new SimpleCodeStylePreferences(); nimCodeStyle->setId("nim"); - nimCodeStyle->setDisplayName(tr("Nim")); + nimCodeStyle->setDisplayName(Tr::tr("Nim")); nimCodeStyle->setReadOnly(true); TabSettings nimTabSettings; @@ -110,9 +111,9 @@ void NimSettings::TerminateCodeStyleSettings() NimToolsSettingsPage::NimToolsSettingsPage(NimSettings *settings) { setId(Nim::Constants::C_NIMTOOLSSETTINGSPAGE_ID); - setDisplayName(NimSettings::tr(Nim::Constants::C_NIMTOOLSSETTINGSPAGE_DISPLAY)); + setDisplayName(Tr::tr("Tools")); setCategory(Nim::Constants::C_NIMTOOLSSETTINGSPAGE_CATEGORY); - setDisplayCategory(NimSettings::tr("Nim")); + setDisplayCategory(Tr::tr("Nim")); setCategoryIconPath(":/nim/images/settingscategory_nim.png"); setSettings(settings); diff --git a/src/plugins/nim/settings/nimsettings.h b/src/plugins/nim/settings/nimsettings.h index 25e3d201341..a27efa2f4b3 100644 --- a/src/plugins/nim/settings/nimsettings.h +++ b/src/plugins/nim/settings/nimsettings.h @@ -12,8 +12,6 @@ namespace Nim { class NimSettings : public Utils::AspectContainer { - Q_DECLARE_TR_FUNCTIONS(Nim::NimSettings) - public: NimSettings(); ~NimSettings(); @@ -33,5 +31,5 @@ public: explicit NimToolsSettingsPage(NimSettings *settings); }; -} // namespace Nim +} // Nim From f50260837c90e19e0820b00bae800a81d0c54514 Mon Sep 17 00:00:00 2001 From: Ari Parkkila Date: Mon, 10 Oct 2022 14:45:51 +0300 Subject: [PATCH 17/42] Fix Boot2Qt Device dark theme on Windows Fixes: QTCREATORBUG-28254 Change-Id: Ie146579d2e52b3336d326c69f864a3beecadee69 Reviewed-by: hjk Reviewed-by: --- src/plugins/boot2qt/qdbdevice.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/boot2qt/qdbdevice.cpp b/src/plugins/boot2qt/qdbdevice.cpp index f6e95a6e1b3..603536c2b54 100644 --- a/src/plugins/boot2qt/qdbdevice.cpp +++ b/src/plugins/boot2qt/qdbdevice.cpp @@ -252,6 +252,8 @@ QdbLinuxDeviceFactory::QdbLinuxDeviceFactory() setConstructionFunction(&QdbDevice::create); setCreator([] { QdbDeviceWizard wizard(Core::ICore::dialogParent()); + if (!creatorTheme()->preferredStyles().isEmpty()) + wizard.setWizardStyle(QWizard::ModernStyle); if (wizard.exec() != QDialog::Accepted) return IDevice::Ptr(); return wizard.device(); From b7c1e707383519785d2446e24541a1fc2bbbbbde Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Tue, 11 Oct 2022 08:29:44 +0200 Subject: [PATCH 18/42] Fix: QtConcurrent build fix Change-Id: I17df4132e6c0aaee35d9d92e5dc8651f553a58b7 Reviewed-by: Christian Stenger --- src/plugins/qtsupport/baseqtversion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index 632e0935cd0..3f55802ed44 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -2243,7 +2243,7 @@ Abis QtVersion::qtAbisFromLibrary(const FilePaths &coreLibraries) } }; - return QtConcurrent::blockingMappedReduced(coreLibraries, filePathToAbiList, uniqueAbis); + return QtConcurrent::blockingMappedReduced(coreLibraries, filePathToAbiList, uniqueAbis); } void QtVersion::resetCache() const From df2038421eb92c0ee3ed9d308f570d4fada1ee83 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 10 Oct 2022 17:42:34 +0200 Subject: [PATCH 19/42] MesonProcess: Remove unused methods, signals and fields Change-Id: Ic1a25e3800b6938fc3cea23a02f582f1e73c058f Reviewed-by: Orgad Shaneh --- .../mesonprojectmanager/mesonprocess.cpp | 24 ------------------- .../mesonprojectmanager/mesonprocess.h | 10 -------- 2 files changed, 34 deletions(-) diff --git a/src/plugins/mesonprojectmanager/mesonprocess.cpp b/src/plugins/mesonprojectmanager/mesonprocess.cpp index b7b40f568ec..da6afe8656e 100644 --- a/src/plugins/mesonprojectmanager/mesonprocess.cpp +++ b/src/plugins/mesonprojectmanager/mesonprocess.cpp @@ -36,9 +36,7 @@ bool MesonProcess::run(const Command &command, { if (!sanityCheck(command)) return false; - m_currentCommand = command; m_stdo.clear(); - m_processWasCanceled = false; m_future = decltype(m_future){}; ProjectExplorer::TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); setupProcess(command, env, captureStdo); @@ -47,7 +45,6 @@ bool MesonProcess::run(const Command &command, Tr::tr("Configuring \"%1\".").arg(projectName), "Meson.Configure", 10); - emit started(); m_elapsed.start(); m_process->start(); m_cancelTimer.start(500); @@ -55,26 +52,6 @@ bool MesonProcess::run(const Command &command, return true; } -QProcess::ProcessState MesonProcess::state() const -{ - return m_process->state(); -} - -void MesonProcess::reportCanceled() -{ - m_future.reportCanceled(); -} - -void MesonProcess::reportFinished() -{ - m_future.reportFinished(); -} - -void MesonProcess::setProgressValue(int p) -{ - m_future.setProgressValue(p); -} - void MesonProcess::handleProcessDone() { if (m_process->result() != ProcessResult::FinishedWithSuccess) { @@ -100,7 +77,6 @@ void MesonProcess::checkForCancelled() { if (m_future.isCanceled()) { m_cancelTimer.stop(); - m_processWasCanceled = true; m_process->close(); } } diff --git a/src/plugins/mesonprojectmanager/mesonprocess.h b/src/plugins/mesonprojectmanager/mesonprocess.h index 87063288103..2738fa98142 100644 --- a/src/plugins/mesonprojectmanager/mesonprocess.h +++ b/src/plugins/mesonprojectmanager/mesonprocess.h @@ -29,17 +29,9 @@ public: const QString &projectName, bool captureStdo = false); - QProcess::ProcessState state() const; - - // Update progress information: - void reportCanceled(); - void reportFinished(); - void setProgressValue(int p); - const QByteArray &stdOut() const { return m_stdo; } const QByteArray &stdErr() const { return m_stderr; } signals: - void started(); void finished(int exitCode, QProcess::ExitStatus exitStatus); void readyReadStandardOutput(const QByteArray &data); @@ -55,12 +47,10 @@ private: std::unique_ptr m_process; QFutureInterface m_future; - bool m_processWasCanceled = false; QTimer m_cancelTimer; QElapsedTimer m_elapsed; QByteArray m_stdo; QByteArray m_stderr; - Command m_currentCommand; }; } // namespace Internal From 862a3923f47c348c8629fdd2ce1b38f33a3999aa Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 10 Oct 2022 16:25:18 +0200 Subject: [PATCH 20/42] Add to changes-9.0.0.md Change-Id: Iebf7add3fcae2524530abc6ab46b7a243943e168 Reviewed-by: Leena Miettinen Reviewed-by: Eike Ziller --- dist/changelog/changes-9.0.0.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dist/changelog/changes-9.0.0.md b/dist/changelog/changes-9.0.0.md index db596733412..792cc6cb565 100644 --- a/dist/changelog/changes-9.0.0.md +++ b/dist/changelog/changes-9.0.0.md @@ -97,6 +97,7 @@ Debugging * Added warning for missing QML debugging functionality for mobile and embedded devices * Fixed display of strings with characters more than 2 bytes long +* Improved type name lookup performance for heavily templated code Version Control Systems ----------------------- @@ -137,11 +138,13 @@ Platforms * Added option for SSH port to wizard * Added fallback for devices without `base64` +* Added experimental support to user remote linux build devices (QTCREATORBUG-28242) ### Docker * Added option for `docker` command * Added detection of Python +* Added option to auto-detect in PATH plus additional directories * Improved device wizard Credits for these changes go to: From f5f3bbcc59144ea3b5152678f2001ac87c471efa Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 10 Oct 2022 15:59:26 +0200 Subject: [PATCH 21/42] Use more Utils::isMainThread() Change-Id: Ia3c6f6dca53c5d7487b0813de16f06c52af47aa5 Reviewed-by: Eike Ziller --- src/libs/extensionsystem/pluginmanager.cpp | 5 ++-- src/libs/qmljs/qmljsmodelmanagerinterface.cpp | 3 +-- src/libs/utils/processreaper.cpp | 3 ++- src/libs/utils/qtcprocess.cpp | 26 +++++++------------ src/libs/utils/singleton.cpp | 5 ++-- src/plugins/cppeditor/stringtable.cpp | 2 +- src/plugins/projectexplorer/projectnodes.cpp | 10 +++---- src/plugins/projectexplorer/taskhub.cpp | 4 +-- .../projectexplorer/windebuginterface.cpp | 3 ++- .../instances/nodeinstanceview.cpp | 16 +++++------- .../resourceeditor/resourceeditorplugin.cpp | 2 -- src/tools/processlauncher/CMakeLists.txt | 2 ++ src/tools/processlauncher/processlauncher.qbs | 2 ++ 13 files changed, 37 insertions(+), 46 deletions(-) diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index 01811c33c54..5937a6d639d 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef WITH_TESTS #include @@ -851,7 +852,7 @@ bool PluginManager::finishScenario() // Waits until the running scenario is fully initialized void PluginManager::waitForScenarioFullyInitialized() { - if (QThread::currentThread() == qApp->thread()) { + if (isMainThread()) { qWarning("The waitForScenarioFullyInitialized() function can't be called from main thread."); return; } @@ -1378,7 +1379,7 @@ void PluginManagerPrivate::shutdown() #ifdef WITH_TESTS if (PluginManager::isScenarioRunning("TestModelManagerInterface")) { qDebug() << "Point 2: Expect the next call to Point 3 triggers a crash"; - QThread::currentThread()->sleep(5); + QThread::sleep(5); } #endif if (!allObjects.isEmpty()) { diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp index c39c48415dc..fc31c30e1b7 100644 --- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp +++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp @@ -7,7 +7,6 @@ #include "qmljsinterpreter.h" #include "qmljsmodelmanagerinterface.h" #include "qmljsplugindumper.h" -#include "qmljstypedescriptionreader.h" #include "qmljsdialect.h" #include "qmljsviewercontext.h" #include "qmljsutils.h" @@ -989,7 +988,7 @@ void ModelManagerInterface::parseLoop(QSet &scannedPaths, ExtensionSystem::PluginManager::waitForScenarioFullyInitialized(); if (ExtensionSystem::PluginManager::finishScenario()) { qDebug() << "Point 1: Shutdown triggered"; - QThread::currentThread()->sleep(2); + QThread::sleep(2); qDebug() << "Point 3: If Point 2 was already reached, expect a crash now"; } } diff --git a/src/libs/utils/processreaper.cpp b/src/libs/utils/processreaper.cpp index 8f247ba3094..2638b09b1ed 100644 --- a/src/libs/utils/processreaper.cpp +++ b/src/libs/utils/processreaper.cpp @@ -4,6 +4,7 @@ #include "processreaper.h" #include "processutils.h" #include "qtcassert.h" +#include "threadutils.h" #include #include @@ -224,7 +225,7 @@ ProcessReaper::ProcessReaper() ProcessReaper::~ProcessReaper() { - QTC_CHECK(QThread::currentThread() == qApp->thread()); + QTC_CHECK(isMainThread()); QMutexLocker locker(&s_instanceMutex); instance()->m_private->waitForFinished(); m_thread.quit(); diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 7ddce617637..f0f6170f882 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -12,6 +12,7 @@ #include "processreaper.h" #include "processutils.h" #include "terminalprocess_p.h" +#include "threadutils.h" #include #include @@ -62,25 +63,25 @@ public: timer.start(); auto cleanup = qScopeGuard([this, &timer] { const qint64 currentNsecs = timer.nsecsElapsed(); - const bool isMainThread = QThread::currentThread() == qApp->thread(); + const bool mainThread = isMainThread(); const int hitThisAll = m_hitThisAll.fetch_add(1) + 1; const int hitAllAll = m_hitAllAll.fetch_add(1) + 1; - const int hitThisMain = isMainThread + const int hitThisMain = mainThread ? m_hitThisMain.fetch_add(1) + 1 : m_hitThisMain.load(); - const int hitAllMain = isMainThread + const int hitAllMain = mainThread ? m_hitAllMain.fetch_add(1) + 1 : m_hitAllMain.load(); const qint64 totalThisAll = toMs(m_totalThisAll.fetch_add(currentNsecs) + currentNsecs); const qint64 totalAllAll = toMs(m_totalAllAll.fetch_add(currentNsecs) + currentNsecs); - const qint64 totalThisMain = toMs(isMainThread + const qint64 totalThisMain = toMs(mainThread ? m_totalThisMain.fetch_add(currentNsecs) + currentNsecs : m_totalThisMain.load()); - const qint64 totalAllMain = toMs(isMainThread + const qint64 totalAllMain = toMs(mainThread ? m_totalAllMain.fetch_add(currentNsecs) + currentNsecs : m_totalAllMain.load()); printMeasurement(QLatin1String(m_functionName), hitThisAll, toMs(currentNsecs), - totalThisAll, hitAllAll, totalAllAll, isMainThread, + totalThisAll, hitAllAll, totalAllAll, mainThread, hitThisMain, totalThisMain, hitAllMain, totalAllMain); }); return std::invoke(std::forward(function), std::forward(args)...); @@ -1212,7 +1213,7 @@ void QtcProcess::setRemoteProcessHooks(const DeviceProcessHooks &hooks) static bool askToKill(const QString &command) { #ifdef QT_GUI_LIB - if (QThread::currentThread() != QCoreApplication::instance()->thread()) + if (!isMainThread()) return true; const QString title = QtcProcess::tr("Process Not Responding"); QString msg = command.isEmpty() ? @@ -1775,13 +1776,6 @@ void QtcProcess::setWriteData(const QByteArray &writeData) d->m_setup.m_writeData = writeData; } -#ifdef QT_GUI_LIB -static bool isGuiThread() -{ - return QThread::currentThread() == QCoreApplication::instance()->thread(); -} -#endif - void QtcProcess::runBlocking(EventLoopMode eventLoopMode) { // Attach a dynamic property with info about blocking type @@ -1802,7 +1796,7 @@ void QtcProcess::runBlocking(EventLoopMode eventLoopMode) timer.setInterval(1000); timer.start(); #ifdef QT_GUI_LIB - if (isGuiThread()) + if (isMainThread()) QApplication::setOverrideCursor(Qt::WaitCursor); #endif QEventLoop eventLoop(this); @@ -1812,7 +1806,7 @@ void QtcProcess::runBlocking(EventLoopMode eventLoopMode) d->m_eventLoop = nullptr; timer.stop(); #ifdef QT_GUI_LIB - if (isGuiThread()) + if (isMainThread()) QApplication::restoreOverrideCursor(); #endif } diff --git a/src/libs/utils/singleton.cpp b/src/libs/utils/singleton.cpp index 474b6bd0e81..cbf7aa21789 100644 --- a/src/libs/utils/singleton.cpp +++ b/src/libs/utils/singleton.cpp @@ -3,10 +3,9 @@ #include "qtcassert.h" #include "singleton.h" +#include "threadutils.h" -#include #include -#include #include @@ -45,7 +44,7 @@ SingletonStaticData &Singleton::staticData(std::type_index index) // only. void Singleton::deleteAll() { - QTC_ASSERT(QThread::currentThread() == qApp->thread(), return); + QTC_ASSERT(isMainThread(), return); QList oldList; { QMutexLocker locker(&s_mutex); diff --git a/src/plugins/cppeditor/stringtable.cpp b/src/plugins/cppeditor/stringtable.cpp index 737c3dd3d0a..6f0ef89b18a 100644 --- a/src/plugins/cppeditor/stringtable.cpp +++ b/src/plugins/cppeditor/stringtable.cpp @@ -119,7 +119,7 @@ void StringTablePrivate::GC(QFutureInterface &futureInterface) #ifdef WITH_TESTS if (ExtensionSystem::PluginManager::isScenarioRunning("TestStringTable")) { if (ExtensionSystem::PluginManager::finishScenario()) - QThread::currentThread()->sleep(5); + QThread::sleep(5); } #endif diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index 68d482264af..27223f066ed 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -3,11 +3,9 @@ #include "projectnodes.h" -#include "buildconfiguration.h" #include "buildsystem.h" #include "project.h" #include "projectexplorerconstants.h" -#include "projecttree.h" #include "target.h" #include @@ -21,14 +19,12 @@ #include #include #include +#include #include #include #include #include -#include -#include -#include #include @@ -445,7 +441,7 @@ QString FolderNode::displayName() const */ QIcon FolderNode::icon() const { - QTC_CHECK(QThread::currentThread() == QCoreApplication::instance()->thread()); + QTC_CHECK(isMainThread()); // Instantiating the Icon provider is expensive. if (auto strPtr = std::get_if(&m_icon)) { @@ -1063,7 +1059,7 @@ DirectoryIcon::DirectoryIcon(const QString &overlay) */ QIcon DirectoryIcon::icon() const { - QTC_CHECK(QThread::currentThread() == QCoreApplication::instance()->thread()); + QTC_CHECK(isMainThread()); const auto it = m_cache.find(m_overlay); if (it != m_cache.end()) return it.value(); diff --git a/src/plugins/projectexplorer/taskhub.cpp b/src/plugins/projectexplorer/taskhub.cpp index e05d7322428..3bb63b42b8c 100644 --- a/src/plugins/projectexplorer/taskhub.cpp +++ b/src/plugins/projectexplorer/taskhub.cpp @@ -9,10 +9,10 @@ #include #include #include +#include #include #include -#include using namespace Utils; @@ -131,7 +131,7 @@ void TaskHub::addTask(Task::TaskType type, const QString &description, Utils::Id void TaskHub::addTask(Task task) { - if (QThread::currentThread() != qApp->thread()) { + if (!isMainThread()) { QMetaObject::invokeMethod(qApp, [task = std::move(task)] { TaskHub::addTask(task); }); diff --git a/src/plugins/projectexplorer/windebuginterface.cpp b/src/plugins/projectexplorer/windebuginterface.cpp index a27d3500959..8952f532468 100644 --- a/src/plugins/projectexplorer/windebuginterface.cpp +++ b/src/plugins/projectexplorer/windebuginterface.cpp @@ -6,6 +6,7 @@ #ifdef Q_OS_WIN #include +#include #include #include @@ -146,7 +147,7 @@ void WinDebugInterface::emitReadySignal() void WinDebugInterface::dispatchDebugOutput() { // Called in the thread this object was created in, not in the WinDebugInterfaceThread. - QTC_ASSERT(QThread::currentThread() == QCoreApplication::instance()->thread(), return); + QTC_ASSERT(Utils::isMainThread(), return); static size_t maxMessagesToSend = 100; std::vector> output; diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index dfc5667199b..9ccabce38f5 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -29,7 +29,6 @@ #include "nodeabstractproperty.h" #include "nodeinstanceserverproxy.h" #include "nodelistproperty.h" -#include "nodeproperty.h" #include "pixmapchangedcommand.h" #include "puppettocreatorcommand.h" #include "qml3dnode.h" @@ -84,19 +83,18 @@ #include #include #include +#include #include -#include -#include -#include -#include -#include #include #include +#include +#include +#include #include -#include -#include +#include +#include enum { debug = false @@ -261,7 +259,7 @@ void NodeInstanceView::modelAttached(Model *model) // If model gets attached on non-main thread of the application, do not attempt to monitor // file changes. Such models are typically short lived for specific purpose, and timers // will not work at all, if the thread is not based on QThread. - if (QThread::currentThread() == qApp->thread()) { + if (Utils::isMainThread()) { m_generateQsbFilesTimer.stop(); m_qsbTargets.clear(); updateQsbPathToFilterMap(); diff --git a/src/plugins/resourceeditor/resourceeditorplugin.cpp b/src/plugins/resourceeditor/resourceeditorplugin.cpp index ddfaa7d27a4..e96bf888cbe 100644 --- a/src/plugins/resourceeditor/resourceeditorplugin.cpp +++ b/src/plugins/resourceeditor/resourceeditorplugin.cpp @@ -28,10 +28,8 @@ #include #include #include -#include #include -#include #include #include #include diff --git a/src/tools/processlauncher/CMakeLists.txt b/src/tools/processlauncher/CMakeLists.txt index 25b3b461ee2..6efcafbc005 100644 --- a/src/tools/processlauncher/CMakeLists.txt +++ b/src/tools/processlauncher/CMakeLists.txt @@ -21,6 +21,8 @@ add_qtc_executable(qtcreator_processlauncher ${UTILSDIR}/qtcassert.h ${UTILSDIR}/singleton.cpp ${UTILSDIR}/singleton.h + ${UTILSDIR}/threadutils.cpp + ${UTILSDIR}/threadutils.h ) if (MSVC) diff --git a/src/tools/processlauncher/processlauncher.qbs b/src/tools/processlauncher/processlauncher.qbs index f56ff489cb5..757d50f9bb6 100644 --- a/src/tools/processlauncher/processlauncher.qbs +++ b/src/tools/processlauncher/processlauncher.qbs @@ -40,6 +40,8 @@ QtcTool { "qtcassert.h", "singleton.cpp", "singleton.h", + "threadutils.cpp", + "threadutils.h", ] } } From ecd9053587beeee87b4a0e3e5a1435891651972c Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 11 Oct 2022 09:28:43 +0200 Subject: [PATCH 22/42] tst_qtcprocess: Remove 30 seconds timeout overload The default is 60. Change-Id: I22585a62648376c771f6f3e4165dc4a1bef25892 Reviewed-by: Eike Ziller --- tests/auto/utils/qtcprocess/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/auto/utils/qtcprocess/CMakeLists.txt b/tests/auto/utils/qtcprocess/CMakeLists.txt index 4040548b334..7e9d1119ccc 100644 --- a/tests/auto/utils/qtcprocess/CMakeLists.txt +++ b/tests/auto/utils/qtcprocess/CMakeLists.txt @@ -5,7 +5,6 @@ file(RELATIVE_PATH TEST_RELATIVE_LIBEXEC_PATH "/${RELATIVE_TEST_PATH}" "/${IDE_L add_qtc_test(tst_qtcprocess CONDITION Qt5_VERSION VERSION_GREATER_EQUAL 6.2.0 - TIMEOUT 30 DEFINES "TEST_RELATIVE_LIBEXEC_PATH=\"${TEST_RELATIVE_LIBEXEC_PATH}\"" "PROCESS_TESTAPP=\"${CMAKE_CURRENT_BINARY_DIR}/processtestapp\"" DEPENDS Utils app_version From e5e90ad9310f6f662e4eae8dbf2c5b7f8a279168 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 28 Sep 2022 08:50:41 +0200 Subject: [PATCH 23/42] More change log Change-Id: I0fc654e83ededc5b82e4ca5a8b4805f9e80d946c Reviewed-by: Leena Miettinen --- dist/changelog/changes-9.0.0.md | 41 +++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/dist/changelog/changes-9.0.0.md b/dist/changelog/changes-9.0.0.md index 792cc6cb565..f871a0926f5 100644 --- a/dist/changelog/changes-9.0.0.md +++ b/dist/changelog/changes-9.0.0.md @@ -16,7 +16,16 @@ General * Added change log browser `Help > Change Log` (`Qt Creator > Change Log` on macOS) * Added option for showing locator as a centered popup -* Added non-menu actions to locator `t` filter +* Locator `t` filter + * Added non-menu actions + * Added fuzzy matching + +Help +---- + +* Added support for dark themes to Qt documentation (QTCREATORBUG-26557) +* Fixed that Qt 6 documentation was shown for Qt 5 based projects + (QTCREATORBUG-10331) Editing ------- @@ -27,6 +36,7 @@ Editing * Added `Create Cursors at Selected Line Ends` * Improved UI for multiple markers on the same line (QTCREATORBUG-27415) * Fixed performance issue with large selections +* Fixed saving files with non-breaking spaces (QTCREATORBUG-17875) * Fixed `Rewrap Paragraph` for Doxygen comments (QTCREATORBUG-9739) * Fixed MIME type matching for generic highlighting with MIME type aliases @@ -34,14 +44,18 @@ Editing * Moved code style editor from dialog directly into the preferences page * Added `Show Preprocessed Source` +* Added `Follow Symbol Under Cursor to Type` * Added `Follow Symbol` for QRC files in string literals (QTCREATORBUG-28087) * Added option for returning only non-value types by const reference (QTCREATORBUG-25790) +* Added option for using `auto` in `Assign to Local Variable` refactoring + action (QTCREATORBUG-28099) * Fixed that selection was not considered for refactoring actions (QTCREATORBUG-27886) * Clangd * Added option for using single Clangd instance for the whole session (QTCREATORBUG-26526) + * Added option for indexing priority (`--background-index-priority`) * Added option for maximum number of completion results (default 100) (QTCREATORBUG-27152) * Added option for document specific preprocessor directives @@ -51,6 +65,8 @@ Editing (QTCREATORBUG-27594) * Built-in * Added support for structured bindings (QTCREATORBUG-27975) + * Fixed that document specific preprocessor directives were not used after + session load (QTCREATORBUG-22584) * ClangFormat * Moved settings back to top level preferences page @@ -69,6 +85,10 @@ Editing * Made `Fit to Screen` sticky and added option for the default (QTCREATORBUG-27816) +### Diff Viewer + +* Fixed that calculating differences blocked Qt Creator + Projects -------- @@ -81,16 +101,23 @@ Projects * Moved settings from `Kits` and `Build & Run` into their own `CMake` category * Turned `Package manager auto setup` off by default -* Added support for CMake configure presets (QTCREATORBUG-24555) +* Added support for CMake configure and build presets, including conditions and + toolchain files (QTCREATORBUG-24555) * Added option for changing environment for configure step * Added option for hiding subfolders in source groups (QTCREATORBUG-27432) * Fixed that `PATH` environment variable was not completely set up during first CMake run +* Fixed issues with importing builds using Visual C++ generator ### Qbs * Fixed that `qbs.sysroot` was not considered +### Qmake + +* Added workaround for `mkspec`s that add compiler flags to `QMAKE_CXX` + (QTCREATORBUG-28201) + Debugging --------- @@ -110,6 +137,7 @@ Test Integration ---------------- * Added support for Squish + ([Documentation](https://doc-snapshots.qt.io/qtcreator-9.0/creator-squish.html)) * Catch 2 * Fixed handling of exceptions (QTCREATORBUG-28131) @@ -145,7 +173,14 @@ Platforms * Added option for `docker` command * Added detection of Python * Added option to auto-detect in PATH plus additional directories +* Added option for overwriting `ENTRYPOINT` of docker container +* Added automatic mounting of source and build directory before building * Improved device wizard + * Added sorting of images + * Added option to hide images without tag + * Added double-click for selecting image +* Fixed interrupting and pausing of GDB +* Fixed running `ctest` on device Credits for these changes go to: -------------------------------- @@ -168,7 +203,9 @@ Fawzi Mohamed Florian Koch Henning Gruendl Jaroslaw Kobus +Leena Miettinen Lucie Gérard +Marc Mutz Marco Bubke Marcus Tillmanns Miikka Heikkinen From ae58d373b02a4a1e3391aa7f6df17d103db1a060 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Wed, 5 Oct 2022 15:42:14 +0200 Subject: [PATCH 24/42] Add FSEngine FilePath Cache To speed up file dialogs we introduce a 1 minute cache for the FilePathInfo. A new version of "IDevice::iterateDirectories" allows implementations to provide the FilePathInfo directly. DockerDevice implements fetching the filePathInfo during iterateDirectories which greatly improves the speed again. Change-Id: I24ac16adb2478cbf16a22012e72fcb8910dcdac5 Reviewed-by: hjk --- src/libs/utils/CMakeLists.txt | 2 + src/libs/utils/filepath.cpp | 80 +++++++-- src/libs/utils/filepath.h | 25 ++- src/libs/utils/filepathinfo.h | 56 ++++++ src/libs/utils/fileutils.cpp | 169 +++++++++++++++--- src/libs/utils/fileutils.h | 13 +- src/libs/utils/fsengine/fileiconprovider.cpp | 60 ++++++- src/libs/utils/fsengine/filepathinfocache.h | 68 +++++++ src/libs/utils/fsengine/fsengine_impl.cpp | 52 +++--- src/plugins/docker/dockerdevice.cpp | 109 ++++++----- src/plugins/docker/dockerdevice.h | 10 +- .../devicesupport/devicemanager.cpp | 18 +- .../projectexplorer/devicesupport/idevice.cpp | 33 +++- .../projectexplorer/devicesupport/idevice.h | 8 +- 14 files changed, 579 insertions(+), 124 deletions(-) create mode 100644 src/libs/utils/filepathinfo.h create mode 100644 src/libs/utils/fsengine/filepathinfocache.h diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt index 2cd8223d83e..1d7099bc3a9 100644 --- a/src/libs/utils/CMakeLists.txt +++ b/src/libs/utils/CMakeLists.txt @@ -48,6 +48,7 @@ add_qtc_library(Utils fileinprojectfinder.cpp fileinprojectfinder.h filenamevalidatinglineedit.cpp filenamevalidatinglineedit.h filepath.cpp filepath.h + filepathinfo.h filesearch.cpp filesearch.h filesystemmodel.cpp filesystemmodel.h filesystemwatcher.cpp filesystemwatcher.h @@ -264,6 +265,7 @@ extend_qtc_library(Utils fsengine/fixedlistfsengine.h fsengine/fsenginehandler.cpp fsengine/fsenginehandler.h + fsengine/filepathinfocache.h ) if (WIN32) diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index 3aa7e4a11d6..80035ac504f 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -513,8 +513,7 @@ FilePaths FilePath::dirEntries(QDir::Filters filters) const // either of the specified \a nameFilters. // An empty \nameFilters list matches every name. -void FilePath::iterateDirectory(const std::function &callBack, - const FileFilter &filter) const +void FilePath::iterateDirectory(const IterateDirCallback &callBack, const FileFilter &filter) const { if (needsDevice()) { QTC_ASSERT(s_deviceHooks.iterateDirectory, return); @@ -529,8 +528,25 @@ void FilePath::iterateDirectory(const std::function } } +void FilePath::iterateDirectory(const IterateDirWithInfoCallback &callBack, + const FileFilter &filter) const +{ + if (needsDevice()) { + QTC_ASSERT(s_deviceHooks.iterateDirectoryWithInfo, return); + s_deviceHooks.iterateDirectoryWithInfo(*this, callBack, filter); + return; + } + + QDirIterator it(path(), filter.nameFilters, filter.fileFilters, filter.iteratorFlags); + while (it.hasNext()) { + const FilePath path = FilePath::fromString(it.next()); + if (!callBack(path, path.filePathInfo())) + return; + } +} + void FilePath::iterateDirectories(const FilePaths &dirs, - const std::function &callBack, + const IterateDirCallback &callBack, const FileFilter &filter) { for (const FilePath &dir : dirs) @@ -601,6 +617,38 @@ bool FilePath::writeFileContents(const QByteArray &data, qint64 offset) const return res == data.size(); } +FilePathInfo FilePath::filePathInfo() const +{ + if (needsDevice()) { + QTC_ASSERT(s_deviceHooks.filePathInfo, return {}); + return s_deviceHooks.filePathInfo(*this); + } + + FilePathInfo result; + + QFileInfo fi(path()); + result.fileSize = fi.size(); + result.lastModified = fi.lastModified(); + result.fileFlags = (FilePathInfo::FileFlag) fi.permissions().toInt(); + + if (fi.isDir()) + result.fileFlags |= FilePathInfo::DirectoryType; + if (fi.isFile()) + result.fileFlags |= FilePathInfo::FileType; + if (fi.exists()) + result.fileFlags |= FilePathInfo::ExistsFlag; + if (fi.isSymbolicLink()) + result.fileFlags |= FilePathInfo::LinkType; + if (fi.isBundle()) + result.fileFlags |= FilePathInfo::BundleType; + if (fi.isHidden()) + result.fileFlags |= FilePathInfo::HiddenFlag; + if (fi.isRoot()) + result.fileFlags |= FilePathInfo::RootFlag; + + return result; +} + void FilePath::asyncWriteFileContents(const Continuation &cont, const QByteArray &data, qint64 offset) const @@ -1834,17 +1882,18 @@ FileFilter::FileFilter(const QStringList &nameFilters, { } -QStringList FileFilter::asFindArguments() const +QStringList FileFilter::asFindArguments(const QString &path) const { QStringList arguments; const QDir::Filters filters = fileFilters; - if (filters & QDir::NoSymLinks) - arguments.prepend("-H"); - else - arguments.prepend("-L"); - arguments.append({"-mindepth", "1"}); + if (iteratorFlags.testFlag(QDirIterator::FollowSymlinks)) + arguments << "-L"; + else + arguments << "-H"; + + arguments << path; if (!iteratorFlags.testFlag(QDirIterator::Subdirectories)) arguments.append({"-maxdepth", "1"}); @@ -1854,14 +1903,23 @@ QStringList FileFilter::asFindArguments() const if (!(filters & QDir::Hidden)) filterOptions << "!" << "-name" << ".*"; + QStringList typesToList; + QStringList filterFilesAndDirs; - if (filters & QDir::Dirs) + if (filters.testFlag(QDir::Dirs)) filterFilesAndDirs << "-type" << "d"; - if (filters & QDir::Files) { + if (filters.testFlag(QDir::Files)) { if (!filterFilesAndDirs.isEmpty()) filterFilesAndDirs << "-o"; filterFilesAndDirs << "-type" << "f"; } + + if (!filters.testFlag(QDir::NoSymLinks)) { + if (!filterFilesAndDirs.isEmpty()) + filterFilesAndDirs << "-o"; + filterFilesAndDirs << "-type" << "l"; + } + if (!filterFilesAndDirs.isEmpty()) filterOptions << "(" << filterFilesAndDirs << ")"; diff --git a/src/libs/utils/filepath.h b/src/libs/utils/filepath.h index d4b1f714b24..f03d89d4d8b 100644 --- a/src/libs/utils/filepath.h +++ b/src/libs/utils/filepath.h @@ -5,6 +5,7 @@ #include "utils_global.h" +#include "filepathinfo.h" #include "osspecificaspects.h" #include @@ -36,7 +37,7 @@ public: const QDir::Filters fileFilters = QDir::NoFilter, const QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags); - QStringList asFindArguments() const; + QStringList asFindArguments(const QString &path) const; const QStringList nameFilters; const QDir::Filters fileFilters = QDir::NoFilter; @@ -119,6 +120,7 @@ public: FilePaths dirEntries(QDir::Filters filters) const; std::optional fileContents(qint64 maxSize = -1, qint64 offset = 0) const; bool writeFileContents(const QByteArray &data, qint64 offset = 0) const; + FilePathInfo filePathInfo() const; bool operator==(const FilePath &other) const; bool operator!=(const FilePath &other) const; @@ -151,10 +153,17 @@ public: [[nodiscard]] Environment deviceEnvironment() const; [[nodiscard]] FilePath onDevice(const FilePath &deviceTemplate) const; [[nodiscard]] FilePath withNewPath(const QString &newPath) const; - void iterateDirectory(const std::function &callBack, + + using IterateDirCallback = std::function; + using IterateDirWithInfoCallback + = std::function; + + void iterateDirectory(const IterateDirCallback &callBack, const FileFilter &filter) const; + void iterateDirectory(const IterateDirWithInfoCallback &callBack, const FileFilter &filter) const; + static void iterateDirectories(const FilePaths &dirs, - const std::function &callBack, + const IterateDirCallback &callBack, const FileFilter &filter); enum PathAmending { AppendToPath, PrependToPath }; @@ -258,8 +267,13 @@ public: std::function symLinkTarget; std::function mapToDevicePath; std::function &, // Abort on 'false' return. - const FileFilter &)> iterateDirectory; + const FilePath::IterateDirCallback &, // Abort on 'false' return. + const FileFilter &)> + iterateDirectory; + std::function + iterateDirectoryWithInfo; std::function(const FilePath &, qint64, qint64)> fileContents; std::function writeFileContents; std::function lastModified; @@ -271,6 +285,7 @@ public: std::function bytesAvailable; std::function deviceDisplayName; std::function isSameDevice; + std::function filePathInfo; template using Continuation = std::function; diff --git a/src/libs/utils/filepathinfo.h b/src/libs/utils/filepathinfo.h new file mode 100644 index 00000000000..7f05e678343 --- /dev/null +++ b/src/libs/utils/filepathinfo.h @@ -0,0 +1,56 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +namespace Utils { + +struct FilePathInfo +{ + // Copy of QAbstractFileEngine::FileFlags so we don't need to include private headers. + enum FileFlag { + //perms (overlaps the QFile::Permission) + ReadOwnerPerm = 0x4000, // 0x100 + WriteOwnerPerm = 0x2000, // 0x80 + ExeOwnerPerm = 0x1000, // 0x40 + ReadUserPerm = 0x0400, + WriteUserPerm = 0x0200, + ExeUserPerm = 0x0100, + ReadGroupPerm = 0x0040, // 0x20 + WriteGroupPerm = 0x0020, // 0x10 + ExeGroupPerm = 0x0010, // 0x8 + ReadOtherPerm = 0x0004, // 0x4 + WriteOtherPerm = 0x0002, // 0x2 + ExeOtherPerm = 0x0001, // 0x1 + + //types + LinkType = 0x10000, // 0xa000 + FileType = 0x20000, // 0x8000 + DirectoryType = 0x40000, // 0x4000 + BundleType = 0x80000, + + //flags + HiddenFlag = 0x0100000, + LocalDiskFlag = 0x0200000, // 0x6000 + ExistsFlag = 0x0400000, + RootFlag = 0x0800000, + Refresh = 0x1000000, + + //masks + PermsMask = 0x0000FFFF, + TypesMask = 0x000F0000, + FlagsMask = 0x0FF00000, + FileInfoAll = FlagsMask | PermsMask | TypesMask + }; + + Q_DECLARE_FLAGS(FileFlags, FileFlag) + + + qint64 fileSize = 0; + FileFlags fileFlags; + QDateTime lastModified; +}; + +} // namespace Utils diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp index b4b952166fd..cb893ff4a46 100644 --- a/src/libs/utils/fileutils.cpp +++ b/src/libs/utils/fileutils.cpp @@ -620,32 +620,137 @@ void FileUtils::iterateLsOutput(const FilePath &base, } } +FilePathInfo::FileFlags fileInfoFlagsfromStatRawModeHex(const QString &hexString) +{ + bool ok = false; + uint mode = hexString.toUInt(&ok, 16); + + QTC_ASSERT(ok, return {}); + + FilePathInfo::FileFlags result; + + if (mode & 0x100) // S_IRUSR + result |= FilePathInfo::ReadOwnerPerm; + if (mode & 0x80) // S_IWUSR + result |= FilePathInfo::WriteOwnerPerm; + if (mode & 0x40) // S_IXUSR + result |= FilePathInfo::ExeOwnerPerm; + if (mode & 0x20) // S_IRGRP + result |= FilePathInfo::ReadGroupPerm; + if (mode & 0x10) // S_IWGRP + result |= FilePathInfo::WriteGroupPerm; + if (mode & 0x8) // S_IXGRP + result |= FilePathInfo::ExeGroupPerm; + if (mode & 0x4) // S_IROTH + result |= FilePathInfo::ReadOtherPerm; + if (mode & 0x2) // S_IWOTH + result |= FilePathInfo::WriteOtherPerm; + if (mode & 0x1) // S_IXOTH + result |= FilePathInfo::ExeOtherPerm; + if (mode & 0xa000) // S_IFLNK + result |= FilePathInfo::LinkType; + if (mode & 0x8000) // S_IFREG + result |= FilePathInfo::FileType; + if (mode & 0x4000) // S_IFDIR + result |= FilePathInfo::DirectoryType; + if (mode & 0x6000) // S_IFBLK + result |= FilePathInfo::LocalDiskFlag; + + if (result != 0) // There is no Exist flag, but if anything was set before, it must exist. + result |= FilePathInfo::ExistsFlag; + + return result; +} + +FilePathInfo FileUtils::filePathInfoFromTriple(const QString &infos) +{ + const QStringList parts = infos.split(' ', Qt::SkipEmptyParts); + if (parts.size() != 3) + return {}; + + FilePathInfo::FileFlags flags = fileInfoFlagsfromStatRawModeHex(parts[0]); + + const QDateTime dt = QDateTime::fromSecsSinceEpoch(parts[1].toLongLong(), Qt::UTC); + qint64 size = parts[2].toLongLong(); + return {size, flags, dt}; +} + +bool iterateWithFind(const FilePath &filePath, + const FileFilter &filter, + const std::function &runInShell, + const std::function callBack, + const QString &extraArguments) +{ + QTC_CHECK(filePath.isAbsolutePath()); + const QStringList arguments = filter.asFindArguments(filePath.path()); + + CommandLine cmdLine{"find", arguments}; + if (!extraArguments.isEmpty()) + cmdLine.addArgs(extraArguments, CommandLine::Raw); + + const RunResult result = runInShell(cmdLine); + const QString out = QString::fromUtf8(result.stdOut); + if (result.exitCode != 0) { + // Find returns non-zero exit code for any error it encounters, even if it finds some files. + + if (!out.startsWith('"' + filePath.path())) { + if (!filePath.exists()) // File does not exist, so no files to find. + return true; + + // If the output does not start with the path we are searching in, find has failed. + // Possibly due to unknown options. + return false; + } + } + + QStringList entries = out.split("\n", Qt::SkipEmptyParts); + // Remove the first line, it is always the directory we are searching in. + // as long as we do not specify "mindepth > 0" + entries.pop_front(); + for (const QString &entry : entries) { + if (!callBack(entry)) + break; + } + + return true; +} + // returns whether 'find' could be used. static bool iterateWithFind(const FilePath &filePath, const FileFilter &filter, const std::function &runInShell, - const std::function &callBack) + const FilePath::IterateDirCallback &callBack) { - QTC_CHECK(filePath.isAbsolutePath()); - QStringList arguments{filePath.path()}; - arguments << filter.asFindArguments(); + const auto toFilePath = [&filePath, &callBack](const QString &entry){ + return callBack(filePath.withNewPath(entry)); + }; - const RunResult result = runInShell({"find", arguments}); - if (!result.stdErr.isEmpty()) { - // missing find, unknown option e.g. "find: unknown predicate `-L'\n" - // qDebug() << "find error: " << result.stdErr; - return false; - } + return iterateWithFind(filePath, filter, runInShell, toFilePath, {}); +} - const QString out = QString::fromUtf8(result.stdOut); - const QStringList entries = out.split("\n", Qt::SkipEmptyParts); - for (const QString &entry : entries) { - const FilePath fp = FilePath::fromString(entry); - // Call back returning 'false' indicates a request to abort iteration. - if (!callBack(fp.onDevice(filePath))) - break; - } - return true; +// returns whether 'find' could be used. +static bool iterateWithFind(const FilePath &filePath, + const FileFilter &filter, + const std::function &runInShell, + const FilePath::IterateDirWithInfoCallback &callBack) +{ + // TODO: Using stat -L will always return the link target, not the link itself. + // We may wan't to add the information that it is a link at some point. + const QString infoArgs(R"(-exec echo -n \"{}\"" " \; -exec stat -L -c "%f %Y %s" "{}" \;)"); + + const auto toFilePathAndInfo = [&filePath, &callBack](const QString &entry) { + const QString fileName = entry.mid(1, entry.lastIndexOf('\"') - 1); + const QString infos = entry.mid(fileName.length() + 3); + + const FilePathInfo fi = FileUtils::filePathInfoFromTriple(infos); + if (!fi.fileFlags) + return true; + + const FilePath fp = filePath.withNewPath(fileName); + return callBack(fp, fi); + }; + + return iterateWithFind(filePath, filter, runInShell, toFilePathAndInfo, infoArgs); } static void findUsingLs(const QString ¤t, @@ -670,7 +775,7 @@ void FileUtils::iterateUnixDirectory(const FilePath &filePath, const FileFilter &filter, bool *useFind, const std::function &runInShell, - const std::function &callBack) + const FilePath::IterateDirCallback &callBack) { QTC_ASSERT(callBack, return); @@ -688,6 +793,30 @@ void FileUtils::iterateUnixDirectory(const FilePath &filePath, FileUtils::iterateLsOutput(filePath, entries, filter, callBack); } +void FileUtils::iterateUnixDirectory(const FilePath &filePath, + const FileFilter &filter, + bool *useFind, + const std::function &runInShell, + const FilePath::IterateDirWithInfoCallback &callBack) +{ + QTC_ASSERT(callBack, return); + + // We try to use 'find' first, because that can filter better directly. + // Unfortunately, it's not installed on all devices by default. + if (useFind && *useFind) { + if (iterateWithFind(filePath, filter, runInShell, callBack)) + return; + *useFind = false; // remember the failure for the next time and use the 'ls' fallback below. + } + + // if we do not have find - use ls as fallback + QStringList entries; + findUsingLs(filePath.path(), filter, runInShell, &entries); + FileUtils::iterateLsOutput(filePath, entries, filter, [&callBack](const FilePath & filePath){ + return callBack(filePath, filePath.filePathInfo()); + }); +} + /*! Copies the directory specified by \a srcFilePath recursively to \a tgtFilePath. \a tgtFilePath will contain the target directory, which will be created. Example usage: diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h index 5a1c5e1f075..fe3a388bb0b 100644 --- a/src/libs/utils/fileutils.h +++ b/src/libs/utils/fileutils.h @@ -35,7 +35,7 @@ class CommandLine; struct QTCREATOR_UTILS_EXPORT RunResult { - int exitCode = 0; + int exitCode = -1; QByteArray stdOut; QByteArray stdErr; }; @@ -97,10 +97,19 @@ public: const FileFilter &filter, bool *useFind, const std::function &runInShell, - const std::function &callBack); + const FilePath::IterateDirCallback &callBack); + + static void iterateUnixDirectory( + const FilePath &base, + const FileFilter &filter, + bool *useFind, + const std::function &runInShell, + const FilePath::IterateDirWithInfoCallback &callBack); static qint64 bytesAvailableFromDFOutput(const QByteArray &dfOutput); + static FilePathInfo filePathInfoFromTriple(const QString &infos); + #ifdef QT_WIDGETS_LIB static void setDialogParentGetter(const std::function &getter); diff --git a/src/libs/utils/fsengine/fileiconprovider.cpp b/src/libs/utils/fsengine/fileiconprovider.cpp index b397cc9447b..12ca91e2a2b 100644 --- a/src/libs/utils/fsengine/fileiconprovider.cpp +++ b/src/libs/utils/fsengine/fileiconprovider.cpp @@ -121,27 +121,22 @@ QIcon FileIconProviderImplementation::icon(IconType type) const return QFileIconProvider::icon(type); } -QIcon FileIconProviderImplementation::icon(const QFileInfo &fi) const -{ - return icon(FilePath::fromString(fi.filePath())); -} - QString FileIconProviderImplementation::type(const QFileInfo &fi) const { const FilePath fPath = FilePath::fromString(fi.filePath()); if (fPath.needsDevice()) { - if (fPath.isDir()) { + if (fi.isDir()) { #ifdef Q_OS_WIN return QGuiApplication::translate("QAbstractFileIconProvider", "File Folder", "Match Windows Explorer"); #else return QGuiApplication::translate("QAbstractFileIconProvider", "Folder", "All other platforms"); #endif } - if (fPath.isExecutableFile()) { + if (fi.isExecutable()) { return "Program"; } - return QFileIconProvider::type(fi); + return "File"; } return QFileIconProvider::type(fi); } @@ -169,6 +164,55 @@ static const QIcon &dirIcon() return icon; } +QIcon FileIconProviderImplementation::icon(const QFileInfo &fi) const +{ + qCDebug(fileIconProvider) << "FileIconProvider::icon" << fi.absoluteFilePath(); + + const FilePath filePath = FilePath::fromString(fi.filePath()); + + if (filePath.isEmpty()) + return unknownFileIcon(); + + // Check if its one of the virtual devices directories + if (filePath.path().startsWith( + FilePath::specialPath(FilePath::SpecialPathComponent::RootPath))) { + // If the filepath does not need a device, it is a virtual device directory + if (!filePath.needsDevice()) + return dirIcon(); + } + + bool isDir = fi.isDir(); + + // Check for cached overlay icons by file suffix. + const QString filename = !isDir ? fi.fileName() : QString(); + if (!filename.isEmpty()) { + const std::optional icon = getIcon(m_filenameCache, filename); + if (icon) + return *icon; + } + + const QString suffix = !isDir ? fi.suffix() : QString(); + if (!suffix.isEmpty()) { + const std::optional icon = getIcon(m_suffixCache, suffix); + if (icon) + return *icon; + } + + if (filePath.needsDevice()) + return isDir ? dirIcon() : unknownFileIcon(); + + // Get icon from OS (and cache it based on suffix!) + QIcon icon; + if (HostOsInfo::isWindowsHost() || HostOsInfo::isMacHost()) + icon = QFileIconProvider::icon(filePath.toFileInfo()); + else // File icons are unknown on linux systems. + icon = isDir ? QFileIconProvider::icon(filePath.toFileInfo()) : unknownFileIcon(); + + if (!isDir && !suffix.isEmpty()) + m_suffixCache.insert(suffix, icon); + return icon; +} + QIcon FileIconProviderImplementation::icon(const FilePath &filePath) const { qCDebug(fileIconProvider) << "FileIconProvider::icon" << filePath.absoluteFilePath(); diff --git a/src/libs/utils/fsengine/filepathinfocache.h b/src/libs/utils/fsengine/filepathinfocache.h new file mode 100644 index 00000000000..e0b7094cbfe --- /dev/null +++ b/src/libs/utils/fsengine/filepathinfocache.h @@ -0,0 +1,68 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "../filepath.h" + +#include +#include +#include + +namespace Utils::Internal { + +class FilePathInfoCache +{ +public: + struct CachedData + { + FilePathInfo filePathInfo; + QDateTime timeout; + }; + + using RetrievalFunction = CachedData (*)(const FilePath &); + +public: + FilePathInfoCache() + : m_cache(50000) + {} + + CachedData cached(const FilePath &filePath, const RetrievalFunction &retrievalFunction) + { + QMutexLocker lk(&m_mutex); + CachedData *data = m_cache.object(filePath); + + // If the cache entry is too old, don't use it ... + if (data && data->timeout < QDateTime::currentDateTime()) + data = nullptr; + + // If no data was found, retrieve it and store it in the cache ... + if (!data) { + data = new CachedData; + *data = retrievalFunction(filePath); + m_cache.insert(filePath, data); + } + + // Return a copy of the data, so it cannot be deleted by the cache + return *data; + } + + void cache(const FilePath &path, CachedData *data) + { + QMutexLocker lk(&m_mutex); + m_cache.insert(path, data); + } + + void cache(const QList> &fileDataList) + { + QMutexLocker lk(&m_mutex); + for (const auto &[path, data] : fileDataList) + m_cache.insert(path, new CachedData(data)); + } + +private: + QMutex m_mutex; + QCache m_cache; +}; + +} // namespace Utils::Internal diff --git a/src/libs/utils/fsengine/fsengine_impl.cpp b/src/libs/utils/fsengine/fsengine_impl.cpp index 02ffe3a58f4..f8277195b28 100644 --- a/src/libs/utils/fsengine/fsengine_impl.cpp +++ b/src/libs/utils/fsengine/fsengine_impl.cpp @@ -4,6 +4,7 @@ #include "fsengine_impl.h" #include "diriterator.h" +#include "filepathinfocache.h" #include "../filepath.h" #include "../qtcassert.h" @@ -15,6 +16,15 @@ namespace Utils { namespace Internal { +FilePathInfoCache g_filePathInfoCache; + +FilePathInfoCache::CachedData createCacheData(const FilePath &filePath) { + FilePathInfoCache::CachedData data; + data.filePathInfo = filePath.filePathInfo(); + data.timeout = QDateTime::currentDateTime().addSecs(60); + return data; +}; + FSEngineImpl::FSEngineImpl(FilePath filePath) : m_filePath(std::move(filePath)) {} @@ -30,6 +40,10 @@ bool FSEngineImpl::open(QIODeviceBase::OpenMode openMode, std::optionalopen(), return false); @@ -38,10 +52,10 @@ bool FSEngineImpl::open(QIODevice::OpenMode openMode) bool write = openMode & QIODevice::WriteOnly; bool append = openMode & QIODevice::Append; - if (!write && !m_filePath.exists()) + if (!write && !exists) return false; - if (openMode & QIODevice::NewOnly && m_filePath.exists()) + if (openMode & QIODevice::NewOnly && exists) return false; if (read || append) { @@ -88,7 +102,7 @@ bool FSEngineImpl::syncToDisk() qint64 FSEngineImpl::size() const { - return m_filePath.fileSize(); + return g_filePathInfoCache.cached(m_filePath, createCacheData).filePathInfo.fileSize; } qint64 FSEngineImpl::pos() const @@ -175,8 +189,12 @@ QStringList FSEngineImpl::entryList(QDir::Filters filters, const QStringList &fi { QStringList result; m_filePath.iterateDirectory( - [&result](const FilePath &p) { + [&result](const FilePath &p, const FilePathInfo &fi) { result.append(p.toFSPathString()); + g_filePathInfoCache + .cache(p, + new FilePathInfoCache::CachedData{fi, + QDateTime::currentDateTime().addSecs(60)}); return true; }, {filterNames, filters}); @@ -185,22 +203,8 @@ QStringList FSEngineImpl::entryList(QDir::Filters filters, const QStringList &fi QAbstractFileEngine::FileFlags FSEngineImpl::fileFlags(FileFlags type) const { - FileFlags result{0}; - - if (type & FileInfoAll && m_filePath.exists()) { - result |= QAbstractFileEngine::ExistsFlag; - - if (type & DirectoryType && m_filePath.isDir()) - result |= QAbstractFileEngine::DirectoryType; - if (type & FileType && m_filePath.isFile()) - result |= QAbstractFileEngine::FileType; - - if (type & PermsMask) { - result |= FileFlags::fromInt(m_filePath.permissions().toInt()); - } - } - - return result; + Q_UNUSED(type); + return {g_filePathInfoCache.cached(m_filePath, createCacheData).filePathInfo.fileFlags.toInt()}; } bool FSEngineImpl::setPermissions(uint /*perms*/) @@ -265,7 +269,7 @@ bool FSEngineImpl::setFileTime(const QDateTime &newDate, FileTime time) QDateTime FSEngineImpl::fileTime(FileTime time) const { Q_UNUSED(time) - return m_filePath.lastModified(); + return g_filePathInfoCache.cached(m_filePath, createCacheData).filePathInfo.lastModified; } void FSEngineImpl::setFileName(const QString &file) @@ -289,8 +293,12 @@ QAbstractFileEngine::Iterator *FSEngineImpl::beginEntryList(QDir::Filters filter { FilePaths paths{m_filePath.pathAppended(".")}; m_filePath.iterateDirectory( - [&paths](const FilePath &p) { + [&paths](const FilePath &p, const FilePathInfo &fi) { paths.append(p); + FilePathInfoCache::CachedData *data + = new FilePathInfoCache::CachedData{fi, + QDateTime::currentDateTime().addSecs(60)}; + g_filePathInfoCache.cache(p, data); return true; }, {filterNames, filters}); diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index 38a30aa76f3..401e98d59c4 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -67,12 +67,11 @@ #include #include - #include #ifdef Q_OS_UNIX -#include #include +#include #endif using namespace Core; @@ -92,13 +91,13 @@ public: : m_settings(settings) , m_containerId(containerId) , m_devicePath(devicePath) - { - } + {} private: void setupShellProcess(QtcProcess *shellProcess) final { - shellProcess->setCommand({m_settings->dockerBinaryPath.filePath(), {"container", "start", "-i", "-a", m_containerId}}); + shellProcess->setCommand({m_settings->dockerBinaryPath.filePath(), + {"container", "start", "-i", "-a", m_containerId}}); } CommandLine createFallbackCommand(const CommandLine &cmdLine) @@ -162,7 +161,8 @@ public: DockerDeviceData m_data; DockerSettings *m_settings; - struct TemporaryMountInfo { + struct TemporaryMountInfo + { FilePath path; FilePath containerPath; }; @@ -327,11 +327,9 @@ Tasks DockerDevice::validate() const return result; } - DockerDevice::DockerDevice(DockerSettings *settings, const DockerDeviceData &data) : d(new DockerDevicePrivate(this, settings, data)) { - setDisplayType(Tr::tr("Docker")); setOsType(OsTypeOtherUnix); setDefaultDisplayName(Tr::tr("Docker Image")); @@ -421,7 +419,11 @@ CommandLine DockerDevicePrivate::withDockerExecCmd(const CommandLine &cmd, bool void DockerDevicePrivate::stopCurrentContainer() { - if (!m_settings || m_container.isEmpty() || !DockerApi::isDockerDaemonAvailable(false).value_or(false)) + if (!m_settings) + return; + if (m_container.isEmpty()) + return; + if (!DockerApi::isDockerDaemonAvailable(false).value_or(false)) return; m_shell.reset(); @@ -589,8 +591,7 @@ void DockerDevice::fromMap(const QVariantMap &map) data.tag = map.value(DockerDeviceDataTagKey).toString(); data.imageId = map.value(DockerDeviceDataImageIdKey).toString(); data.size = map.value(DockerDeviceDataSizeKey).toString(); - data.useLocalUidGid = map.value(DockerDeviceUseOutsideUser, HostOsInfo::isLinuxHost()) - .toBool(); + data.useLocalUidGid = map.value(DockerDeviceUseOutsideUser, HostOsInfo::isLinuxHost()).toBool(); data.mounts = map.value(DockerDeviceMappedPaths).toStringList(); data.keepEntryPoint = map.value(DockerDeviceKeepEntryPoint).toBool(); d->setData(data); @@ -623,26 +624,24 @@ bool DockerDevice::canAutoDetectPorts() const PortsGatheringMethod DockerDevice::portsGatheringMethod() const { - return { - [this](QAbstractSocket::NetworkLayerProtocol protocol) -> CommandLine { - // We might encounter the situation that protocol is given IPv6 - // but the consumer of the free port information decides to open - // an IPv4(only) port. As a result the next IPv6 scan will - // report the port again as open (in IPv6 namespace), while the - // same port in IPv4 namespace might still be blocked, and - // re-use of this port fails. - // GDBserver behaves exactly like this. + return {[this](QAbstractSocket::NetworkLayerProtocol protocol) -> CommandLine { + // We might encounter the situation that protocol is given IPv6 + // but the consumer of the free port information decides to open + // an IPv4(only) port. As a result the next IPv6 scan will + // report the port again as open (in IPv6 namespace), while the + // same port in IPv4 namespace might still be blocked, and + // re-use of this port fails. + // GDBserver behaves exactly like this. - Q_UNUSED(protocol) + Q_UNUSED(protocol) - // /proc/net/tcp* covers /proc/net/tcp and /proc/net/tcp6 - return {filePath("sed"), - "-e 's/.*: [[:xdigit:]]*:\\([[:xdigit:]]\\{4\\}\\).*/\\1/g' /proc/net/tcp*", - CommandLine::Raw}; - }, + // /proc/net/tcp* covers /proc/net/tcp and /proc/net/tcp6 + return {filePath("sed"), + "-e 's/.*: [[:xdigit:]]*:\\([[:xdigit:]]\\{4\\}\\).*/\\1/g' /proc/net/tcp*", + CommandLine::Raw}; + }, - &Port::parseFromSedOutput - }; + &Port::parseFromSedOutput}; }; DeviceProcessList *DockerDevice::createProcessListModel(QObject *) const @@ -714,12 +713,12 @@ bool DockerDevice::handlesFile(const FilePath &filePath) const if (filePath.scheme() == u"device" && filePath.host() == id().toString()) return true; - if (filePath.scheme() == Constants::DOCKER_DEVICE_SCHEME - && filePath.host() == d->dockerImageId()) + const bool isDockerScheme = filePath.scheme() == Constants::DOCKER_DEVICE_SCHEME; + + if (isDockerScheme && filePath.host() == d->dockerImageId()) return true; - if (filePath.scheme() == Constants::DOCKER_DEVICE_SCHEME - && filePath.host() == QString(d->repoAndTag())) + if (isDockerScheme && filePath.host() == QString(d->repoAndTag())) return true; return false; @@ -875,7 +874,8 @@ QFileDevice::Permissions DockerDevice::permissions(const FilePath &filePath) con return perm; } -bool DockerDevice::setPermissions(const FilePath &filePath, QFileDevice::Permissions permissions) const +bool DockerDevice::setPermissions(const FilePath &filePath, + QFileDevice::Permissions permissions) const { Q_UNUSED(permissions) QTC_ASSERT(handlesFile(filePath), return {}); @@ -894,7 +894,16 @@ bool DockerDevice::ensureReachable(const FilePath &other) const } void DockerDevice::iterateDirectory(const FilePath &filePath, - const std::function &callBack, + const FilePath::IterateDirCallback &callBack, + const FileFilter &filter) const +{ + QTC_ASSERT(handlesFile(filePath), return); + auto runInShell = [this](const CommandLine &cmd) { return d->runInShell(cmd); }; + FileUtils::iterateUnixDirectory(filePath, filter, &d->m_useFind, runInShell, callBack); +} + +void DockerDevice::iterateDirectory(const FilePath &filePath, + const FilePath::IterateDirWithInfoCallback &callBack, const FileFilter &filter) const { QTC_ASSERT(handlesFile(filePath), return); @@ -923,6 +932,13 @@ bool DockerDevice::writeFileContents(const FilePath &filePath, return d->runInShellSuccess(cmd, data); } +FilePathInfo DockerDevice::filePathInfo(const FilePath &filePath) const +{ + QTC_ASSERT(handlesFile(filePath), return {}); + const RunResult stat = d->runInShell({"stat", {"-L", "-c", "%f %Y %s", filePath.path()}}); + return FileUtils::filePathInfoFromTriple(QString::fromLatin1(stat.stdOut)); +} + Environment DockerDevice::systemEnvironment() const { return d->environment(); @@ -973,8 +989,7 @@ void DockerDevicePrivate::fetchSystemEnviroment() proc.waitForFinished(); const QString remoteOutput = proc.cleanedStdOut(); - m_cachedEnviroment = Environment(remoteOutput.split('\n', Qt::SkipEmptyParts), - q->osType()); + m_cachedEnviroment = Environment(remoteOutput.split('\n', Qt::SkipEmptyParts), q->osType()); const QString remoteError = proc.cleanedStdErr(); if (!remoteError.isEmpty()) @@ -1078,6 +1093,7 @@ public: m_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); using namespace Layouting; + Column { Stack { statusLabel, @@ -1085,17 +1101,16 @@ public: }, m_log, errorLabel, - Row { - showUnnamedContainers, - m_buttons - }, - }.attachTo(this); + Row{showUnnamedContainers, m_buttons}, + } + .attachTo(this); connect(m_buttons, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(m_buttons, &QDialogButtonBox::rejected, this, &QDialog::reject); m_buttons->button(QDialogButtonBox::Ok)->setEnabled(false); - CommandLine cmd{m_settings->dockerBinaryPath.filePath(), {"images", "--format", "{{.ID}}\\t{{.Repository}}\\t{{.Tag}}\\t{{.Size}}"}}; + CommandLine cmd{m_settings->dockerBinaryPath.filePath(), + {"images", "--format", "{{.ID}}\\t{{.Repository}}\\t{{.Tag}}\\t{{.Size}}"}}; m_log->append(Tr::tr("Running \"%1\"\n").arg(cmd.toUserOutput())); m_process = new QtcProcess(this); @@ -1146,7 +1161,8 @@ public: { const QModelIndexList selectedRows = m_view->selectionModel()->selectedRows(); QTC_ASSERT(selectedRows.size() == 1, return {}); - DockerImageItem *item = m_model.itemForIndex(m_proxyModel->mapToSource(selectedRows.front())); + DockerImageItem *item = m_model.itemForIndex( + m_proxyModel->mapToSource(selectedRows.front())); QTC_ASSERT(item, return {}); auto device = DockerDevice::create(m_settings, *item); @@ -1201,10 +1217,9 @@ void DockerDeviceFactory::shutdownExistingDevices() bool DockerDevicePrivate::addTemporaryMount(const FilePath &path, const FilePath &containerPath) { - bool alreadyAdded = anyOf(m_temporaryMounts, - [containerPath](const TemporaryMountInfo &info) { - return info.containerPath == containerPath; - }); + bool alreadyAdded = anyOf(m_temporaryMounts, [containerPath](const TemporaryMountInfo &info) { + return info.containerPath == containerPath; + }); if (alreadyAdded) return false; diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h index 4e7840b9282..8398ee4e235 100644 --- a/src/plugins/docker/dockerdevice.h +++ b/src/plugins/docker/dockerdevice.h @@ -100,7 +100,10 @@ public: bool renameFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const override; Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override; void iterateDirectory(const Utils::FilePath &filePath, - const std::function &callBack, + const Utils::FilePath::IterateDirCallback &callBack, + const Utils::FileFilter &filter) const override; + void iterateDirectory(const Utils::FilePath &filePath, + const Utils::FilePath::IterateDirWithInfoCallback &callBack, const Utils::FileFilter &filter) const override; std::optional fileContents(const Utils::FilePath &filePath, qint64 limit, @@ -108,6 +111,7 @@ public: bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data, qint64 offset) const override; + Utils::FilePathInfo filePathInfo(const Utils::FilePath &filePath) const override; QDateTime lastModified(const Utils::FilePath &filePath) const override; qint64 fileSize(const Utils::FilePath &filePath) const override; QFileDevice::Permissions permissions(const Utils::FilePath &filePath) const override; @@ -132,10 +136,6 @@ protected: QVariantMap toMap() const final; private: - void iterateWithFind(const Utils::FilePath &filePath, - const std::function &callBack, - const Utils::FileFilter &filter) const; - void aboutToBeRemoved() const final; class DockerDevicePrivate *d = nullptr; diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp index febcc6436eb..c5a7f4e8102 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp @@ -521,10 +521,18 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique &callBack, + const FilePath::IterateDirCallback &callBack, const FileFilter &filter) { auto device = DeviceManager::deviceForPath(filePath); - QTC_ASSERT(device, return); + QTC_ASSERT(device, return ); + device->iterateDirectory(filePath, callBack, filter); + }; + + deviceHooks.iterateDirectoryWithInfo = [](const FilePath &filePath, + const FilePath::IterateDirWithInfoCallback &callBack, + const FileFilter &filter) { + auto device = DeviceManager::deviceForPath(filePath); + QTC_ASSERT(device, return ); device->iterateDirectory(filePath, callBack, filter); }; @@ -552,6 +560,12 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_uniquewriteFileContents(filePath, data, offset); }; + deviceHooks.filePathInfo = [](const FilePath &filePath) -> FilePathInfo { + auto device = DeviceManager::deviceForPath(filePath); + QTC_ASSERT(device, return {}); + return device->filePathInfo(filePath); + }; + deviceHooks.lastModified = [](const FilePath &filePath) { auto device = DeviceManager::deviceForPath(filePath); QTC_ASSERT(device, return QDateTime()); diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index 9c391de5aed..294be9f18a0 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -356,7 +356,7 @@ FilePath IDevice::symLinkTarget(const FilePath &filePath) const } void IDevice::iterateDirectory(const FilePath &filePath, - const std::function &callBack, + const FilePath::IterateDirCallback &callBack, const FileFilter &filter) const { Q_UNUSED(filePath); @@ -365,6 +365,15 @@ void IDevice::iterateDirectory(const FilePath &filePath, QTC_CHECK(false); } +void IDevice::iterateDirectory(const FilePath &filePath, + const FilePath::IterateDirWithInfoCallback &callBack, + const FileFilter &filter) const +{ + iterateDirectory(filePath, [callBack](const FilePath &path) { + return callBack(path, path.filePathInfo()); + }, filter); +} + std::optional IDevice::fileContents(const FilePath &filePath, qint64 limit, qint64 offset) const @@ -393,6 +402,28 @@ bool IDevice::writeFileContents(const FilePath &filePath, const QByteArray &data return {}; } +FilePathInfo IDevice::filePathInfo(const Utils::FilePath &filePath) const +{ + bool exists = filePath.exists(); + if (!exists) + return {}; + + FilePathInfo result { + filePath.fileSize(), + {FilePathInfo::ExistsFlag}, + filePath.lastModified(), + }; + + if (filePath.isDir()) + result.fileFlags |= FilePathInfo::DirectoryType; + if (filePath.isFile()) + result.fileFlags |= FilePathInfo::FileType; + if (filePath.isRootPath()) + result.fileFlags |= FilePathInfo::RootFlag; + + return result; +} + void IDevice::asyncWriteFileContents(const Continuation &cont, const FilePath &filePath, const QByteArray &data, diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h index 58d0892fc65..57f2ba0a3c7 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.h +++ b/src/plugins/projectexplorer/devicesupport/idevice.h @@ -238,14 +238,20 @@ public: const Utils::FilePaths &dirs) const; virtual Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const; virtual void iterateDirectory(const Utils::FilePath &filePath, - const std::function &callBack, + const Utils::FilePath::IterateDirCallback &callBack, const Utils::FileFilter &filter) const; + + virtual void iterateDirectory(const Utils::FilePath &filePath, + const Utils::FilePath::IterateDirWithInfoCallback &callBack, + const Utils::FileFilter &filter) const; + virtual std::optional fileContents(const Utils::FilePath &filePath, qint64 limit, qint64 offset) const; virtual bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data, qint64 offset) const; + virtual Utils::FilePathInfo filePathInfo(const Utils::FilePath &filePath) const; virtual QDateTime lastModified(const Utils::FilePath &filePath) const; virtual QFile::Permissions permissions(const Utils::FilePath &filePath) const; virtual bool setPermissions(const Utils::FilePath &filePath, QFile::Permissions) const; From 7c623f99d80defa83fb32afb7a8e99c439e11ca8 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Tue, 11 Oct 2022 09:50:45 +0300 Subject: [PATCH 25/42] Git: Fix pattern for commit hash matching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Avoid matching mid-word. * Avoid matching after "mode ". * Change to raw string literals. Fixes: QTCREATORBUG-24768 Fixes: QTCREATORBUG-28268 Change-Id: I68abbf3de7928c60e0fe2d944adedaa6db94b1a4 Reviewed-by: André Hartmann --- src/plugins/git/giteditor.cpp | 2 +- src/plugins/vcsbase/vcsoutputformatter.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp index 415d1622983..b24f64e7e8d 100644 --- a/src/plugins/git/giteditor.cpp +++ b/src/plugins/git/giteditor.cpp @@ -29,7 +29,7 @@ #include #include -#define CHANGE_PATTERN "[a-f0-9]{7,40}" +#define CHANGE_PATTERN "\\b[a-f0-9]{7,40}\\b" using namespace Core; using namespace Utils; diff --git a/src/plugins/vcsbase/vcsoutputformatter.cpp b/src/plugins/vcsbase/vcsoutputformatter.cpp index 0085a8d06ea..d4ad653d910 100644 --- a/src/plugins/vcsbase/vcsoutputformatter.cpp +++ b/src/plugins/vcsbase/vcsoutputformatter.cpp @@ -21,10 +21,10 @@ namespace VcsBase { VcsOutputLineParser::VcsOutputLineParser() : m_regexp( - "(https?://\\S*)" // https://codereview.org/c/1234 - "|(v[0-9]+\\.[0-9]+\\.[0-9]+[\\-A-Za-z0-9]*)" // v0.1.2-beta3 - "|([0-9a-f]{6,}(?:\\.{2,3}[0-9a-f]{6,}" // 789acf or 123abc..456cde - "|\\^+|~\\d+)?)") // or 789acf^ or 123abc~99 + R"((https?://\S*))" // https://codereview.org/c/1234 + R"(|\b(v[0-9]+\.[0-9]+\.[0-9]+[\-A-Za-z0-9]*))" // v0.1.2-beta3 + R"(|\b(? Date: Tue, 11 Oct 2022 11:41:03 +0200 Subject: [PATCH 26/42] Core: Restore some more object names Change-Id: I318eda7cfabf840e2fde3d11e77b489a99c43f62 Reviewed-by: Eike Ziller --- src/plugins/coreplugin/find/findtoolbar.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/coreplugin/find/findtoolbar.cpp b/src/plugins/coreplugin/find/findtoolbar.cpp index d6cc32d53e2..ab207391bdb 100644 --- a/src/plugins/coreplugin/find/findtoolbar.cpp +++ b/src/plugins/coreplugin/find/findtoolbar.cpp @@ -65,6 +65,7 @@ FindToolBar::FindToolBar(CurrentDocumentFind *currentDocumentFind) m_findLabel->setText(QCoreApplication::translate("Core::Internal::FindWidget", "Find:", nullptr)); m_findEdit = new FancyLineEdit; + m_findEdit->setObjectName("findEdit"); m_findEdit->setMinimumWidth(100); m_findEdit->setAttribute(Qt::WA_MacShowFocusRect, false); @@ -90,6 +91,7 @@ FindToolBar::FindToolBar(CurrentDocumentFind *currentDocumentFind) m_findButtonLayout->addWidget(m_close); m_replaceEdit = new FancyLineEdit(this); + m_replaceEdit->setObjectName("replaceEdit"); m_replaceEdit->setMinimumWidth(100); m_replaceEdit->setAttribute(Qt::WA_MacShowFocusRect, false); m_replaceEdit->setFiltering(true); From 52672b5f6c066703e7c934545714d37c2da7404e Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Thu, 22 Sep 2022 22:17:19 +0900 Subject: [PATCH 27/42] SessionDialog: rename Switch To to Open and reorder buttons To be consistent with the SessionNameInputDialog that has the button "... and Open" to switch to a session. Buttons should be ordered by like a typical file menu - new - open(ex- switch to) - save(rename/clone) - close(delete) Change-Id: I875446352100500eaae4b0ecef4faa6442aef539 Reviewed-by: Leena Miettinen Reviewed-by: Eike Ziller --- doc/qtcreator/src/howto/creator-sessions.qdoc | 2 +- share/qtcreator/translations/qtcreator_cs.ts | 4 ++-- share/qtcreator/translations/qtcreator_da.ts | 4 ++-- share/qtcreator/translations/qtcreator_de.ts | 4 ++-- share/qtcreator/translations/qtcreator_fr.ts | 4 ++-- share/qtcreator/translations/qtcreator_hr.ts | 4 ++-- share/qtcreator/translations/qtcreator_ja.ts | 4 ++-- share/qtcreator/translations/qtcreator_pl.ts | 4 ++-- share/qtcreator/translations/qtcreator_ru.ts | 4 ++-- share/qtcreator/translations/qtcreator_sl.ts | 4 ++-- share/qtcreator/translations/qtcreator_uk.ts | 4 ++-- .../qtcreator/translations/qtcreator_zh_CN.ts | 4 ++-- .../qtcreator/translations/qtcreator_zh_TW.ts | 4 ++-- src/plugins/projectexplorer/sessiondialog.cpp | 22 +++++++++---------- src/plugins/projectexplorer/sessiondialog.h | 2 +- 15 files changed, 37 insertions(+), 37 deletions(-) diff --git a/doc/qtcreator/src/howto/creator-sessions.qdoc b/doc/qtcreator/src/howto/creator-sessions.qdoc index 63ac5a7a938..d7e45fcd411 100644 --- a/doc/qtcreator/src/howto/creator-sessions.qdoc +++ b/doc/qtcreator/src/howto/creator-sessions.qdoc @@ -76,7 +76,7 @@ \endlist - To switch between sessions, select \uicontrol {Switch To}. + To switch between sessions, select \uicontrol {Open}. \if defined(qtcreator) When you launch \QC, a list of existing sessions is displayed in the diff --git a/share/qtcreator/translations/qtcreator_cs.ts b/share/qtcreator/translations/qtcreator_cs.ts index a3d4cdd06d9..3ffa42b5276 100644 --- a/share/qtcreator/translations/qtcreator_cs.ts +++ b/share/qtcreator/translations/qtcreator_cs.ts @@ -10999,8 +10999,8 @@ se projektu '%2' nepodařilo přidat. &Smazat - &Switch To - &Přepnout na sezení + &Open + &Otevřít <a href="qthelp://org.qt-project.qtcreator/doc/creator-project-managing-sessions.html">What is a Session?</a> diff --git a/share/qtcreator/translations/qtcreator_da.ts b/share/qtcreator/translations/qtcreator_da.ts index f11aa1e9c35..df9db029fb9 100644 --- a/share/qtcreator/translations/qtcreator_da.ts +++ b/share/qtcreator/translations/qtcreator_da.ts @@ -24405,8 +24405,8 @@ til projektet "%2". &Slet - &Switch To - &Skift til + &Open + &Åbn Restore last session on startup diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index 704edc9a2e9..1fd70e622cb 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -6605,8 +6605,8 @@ konnte dem Projekt "%2" nicht hinzugefügt werden. <a href="qthelp://org.qt-project.qtcreator/doc/creator-project-managing-sessions.html">Was ist eine Sitzung?</a> - &Switch To - &Verwenden + &Open + &Öffnen diff --git a/share/qtcreator/translations/qtcreator_fr.ts b/share/qtcreator/translations/qtcreator_fr.ts index 8b00b472e09..99135b4a43a 100644 --- a/share/qtcreator/translations/qtcreator_fr.ts +++ b/share/qtcreator/translations/qtcreator_fr.ts @@ -11390,8 +11390,8 @@ francis : voila une nouvelle suggestion :) &Supprimer - &Switch To - &Basculer vers + &Open + &Ouvrir New session name diff --git a/share/qtcreator/translations/qtcreator_hr.ts b/share/qtcreator/translations/qtcreator_hr.ts index 84c83f75ccc..3053522bea0 100644 --- a/share/qtcreator/translations/qtcreator_hr.ts +++ b/share/qtcreator/translations/qtcreator_hr.ts @@ -5947,8 +5947,8 @@ Greška: %5 &Ukloni - &Switch To - &Prebaci na + &Open + &Otvori Restore last session on startup diff --git a/share/qtcreator/translations/qtcreator_ja.ts b/share/qtcreator/translations/qtcreator_ja.ts index 428aef36a76..43f860bf2f1 100644 --- a/share/qtcreator/translations/qtcreator_ja.ts +++ b/share/qtcreator/translations/qtcreator_ja.ts @@ -4609,8 +4609,8 @@ Add, modify, and remove document filters, which determine the documentation set セッションのリネーム - &Switch To - 切り替え(&S) + &Open + 開く(&O) diff --git a/share/qtcreator/translations/qtcreator_pl.ts b/share/qtcreator/translations/qtcreator_pl.ts index 5f8b7b600a2..0538eed8015 100644 --- a/share/qtcreator/translations/qtcreator_pl.ts +++ b/share/qtcreator/translations/qtcreator_pl.ts @@ -958,8 +958,8 @@ &Usuń - &Switch To - &Przełącz sesję + &Open + &Otwórz <a href="qthelp://org.qt-project.qtcreator/doc/creator-project-managing-sessions.html">What is a Session?</a> diff --git a/share/qtcreator/translations/qtcreator_ru.ts b/share/qtcreator/translations/qtcreator_ru.ts index 77d2c6d7cdb..4ed61f06aa2 100644 --- a/share/qtcreator/translations/qtcreator_ru.ts +++ b/share/qtcreator/translations/qtcreator_ru.ts @@ -95,8 +95,8 @@ Сбросить - &Switch To - &Активировать + &Open + &Открыть Restore last workspace on startup diff --git a/share/qtcreator/translations/qtcreator_sl.ts b/share/qtcreator/translations/qtcreator_sl.ts index a73fc184003..753a55b51f6 100644 --- a/share/qtcreator/translations/qtcreator_sl.ts +++ b/share/qtcreator/translations/qtcreator_sl.ts @@ -7537,8 +7537,8 @@ enojen »Vstopi« za oddajo signala pa vas bo privedel neposredno do ustrezne pr - &Switch To - P&reklopi na + &Open + &Odpri diff --git a/share/qtcreator/translations/qtcreator_uk.ts b/share/qtcreator/translations/qtcreator_uk.ts index a454b5e8d4d..e86e108f6e3 100644 --- a/share/qtcreator/translations/qtcreator_uk.ts +++ b/share/qtcreator/translations/qtcreator_uk.ts @@ -15576,8 +15576,8 @@ to project '%2'. Ви&далити - &Switch To - &Перемкнутись до + &Open + &Відкрити New session name diff --git a/share/qtcreator/translations/qtcreator_zh_CN.ts b/share/qtcreator/translations/qtcreator_zh_CN.ts index 1b3cc3f8eb3..d28eabcb22d 100644 --- a/share/qtcreator/translations/qtcreator_zh_CN.ts +++ b/share/qtcreator/translations/qtcreator_zh_CN.ts @@ -10526,8 +10526,8 @@ SOURCES *= .../ide/main/bin/dumper/dumper.cpp 删除(&D) - &Switch To - 切换到(&S) + &Open + 打开(&S) New session name diff --git a/share/qtcreator/translations/qtcreator_zh_TW.ts b/share/qtcreator/translations/qtcreator_zh_TW.ts index 7e2757f30ce..f2d9c06bfa3 100644 --- a/share/qtcreator/translations/qtcreator_zh_TW.ts +++ b/share/qtcreator/translations/qtcreator_zh_TW.ts @@ -6980,8 +6980,8 @@ Add, modify, and remove document filters, which determine the documentation set 刪除(&D) - &Switch To - 切換至(&S) + &Open + 開啟(&S) New session name diff --git a/src/plugins/projectexplorer/sessiondialog.cpp b/src/plugins/projectexplorer/sessiondialog.cpp index e7a7983cb42..285836cab39 100644 --- a/src/plugins/projectexplorer/sessiondialog.cpp +++ b/src/plugins/projectexplorer/sessiondialog.cpp @@ -119,17 +119,17 @@ SessionDialog::SessionDialog(QWidget *parent) : QDialog(parent) auto createNewButton = new QPushButton(tr("&New")); + m_openButton = new QPushButton(tr("&Open")); m_renameButton = new QPushButton(tr("&Rename")); m_cloneButton = new QPushButton(tr("C&lone")); m_deleteButton = new QPushButton(tr("&Delete")); - m_switchButton = new QPushButton(tr("&Switch To")); m_autoLoadCheckBox = new QCheckBox(tr("Restore last session on startup")); auto buttonBox = new QDialogButtonBox(this); buttonBox->setStandardButtons(QDialogButtonBox::Close); - m_switchButton->setDefault(true); + m_openButton->setDefault(true); // FIXME: Simplify translator's work. auto whatsASessionLabel = new QLabel( @@ -144,10 +144,10 @@ SessionDialog::SessionDialog(QWidget *parent) : QDialog(parent) sessionView, Column { createNewButton, + m_openButton, m_renameButton, m_cloneButton, m_deleteButton, - m_switchButton, st } }, @@ -158,14 +158,14 @@ SessionDialog::SessionDialog(QWidget *parent) : QDialog(parent) connect(createNewButton, &QAbstractButton::clicked, sessionView, &SessionView::createNewSession); + connect(m_openButton, &QAbstractButton::clicked, + sessionView, &SessionView::switchToCurrentSession); + connect(m_renameButton, &QAbstractButton::clicked, + sessionView, &SessionView::renameCurrentSession); connect(m_cloneButton, &QAbstractButton::clicked, sessionView, &SessionView::cloneCurrentSession); connect(m_deleteButton, &QAbstractButton::clicked, sessionView, &SessionView::deleteSelectedSessions); - connect(m_switchButton, &QAbstractButton::clicked, - sessionView, &SessionView::switchToCurrentSession); - connect(m_renameButton, &QAbstractButton::clicked, - sessionView, &SessionView::renameCurrentSession); connect(sessionView, &SessionView::sessionActivated, sessionView, &SessionView::switchToCurrentSession); @@ -191,20 +191,20 @@ bool SessionDialog::autoLoadSession() const void SessionDialog::updateActions(const QStringList &sessions) { if (sessions.isEmpty()) { - m_deleteButton->setEnabled(false); + m_openButton->setEnabled(false); m_renameButton->setEnabled(false); m_cloneButton->setEnabled(false); - m_switchButton->setEnabled(false); + m_deleteButton->setEnabled(false); return; } const bool defaultIsSelected = sessions.contains("default"); const bool activeIsSelected = Utils::anyOf(sessions, [](const QString &session) { return session == SessionManager::activeSession(); }); - m_deleteButton->setEnabled(!defaultIsSelected && !activeIsSelected); + m_openButton->setEnabled(sessions.size() == 1); m_renameButton->setEnabled(sessions.size() == 1 && !defaultIsSelected); m_cloneButton->setEnabled(sessions.size() == 1); - m_switchButton->setEnabled(sessions.size() == 1); + m_deleteButton->setEnabled(!defaultIsSelected && !activeIsSelected); } } // ProjectExplorer::Internal diff --git a/src/plugins/projectexplorer/sessiondialog.h b/src/plugins/projectexplorer/sessiondialog.h index ccb8a51e8b5..3296afd158f 100644 --- a/src/plugins/projectexplorer/sessiondialog.h +++ b/src/plugins/projectexplorer/sessiondialog.h @@ -27,10 +27,10 @@ public: private: void updateActions(const QStringList &sessions); + QPushButton *m_openButton; QPushButton *m_renameButton; QPushButton *m_cloneButton; QPushButton *m_deleteButton; - QPushButton *m_switchButton; QCheckBox *m_autoLoadCheckBox; }; From 0e2409b0d605f1429c38e0cdbe7fa7443e0c1dbf Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 10 Oct 2022 18:44:04 +0200 Subject: [PATCH 28/42] Doc: Describe image viewer Set as Default option Task-number: QTCREATORBUG-27876 Change-Id: Ibe2b7f39c23b60df13debab7de21d7e999f51448 Reviewed-by: Reviewed-by: Eike Ziller --- .../images/qtcreator-image-viewer.png | Bin 6395 -> 8711 bytes .../src/user-interface/creator-ui.qdoc | 4 ++++ 2 files changed, 4 insertions(+) diff --git a/doc/qtcreator/images/qtcreator-image-viewer.png b/doc/qtcreator/images/qtcreator-image-viewer.png index d953d15aa62dc697d885e5ae57f6bcba99b8dda7..81ef75a2ed7b366d4e11da4b09ea52fef6727252 100644 GIT binary patch literal 8711 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 I=akR{0B6y0_W%F@ literal 6395 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 Date: Fri, 7 Oct 2022 15:08:33 +0200 Subject: [PATCH 29/42] CMakePM: Allow presets without buildDirectory CMakePresets v3 relax the requirement of having the buildDirectory specified. This way Qt Creator should use its own mechanism of specifying the build directory. Change-Id: I6ba69e6a03cdc058e7b8fa540a6fc564356aba63 Reviewed-by: Alessandro Portale --- .../cmakebuildconfiguration.cpp | 15 ++-------- .../cmakeprojectimporter.cpp | 29 +++++++++++++++---- .../cmakeprojectimporter.h | 4 +++ tests/manual/cmakepresets/CMakePresets.json | 2 +- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 91de7766c7d..c6736d4a9a9 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -1956,19 +1956,8 @@ CMakeBuildConfigurationFactory::CMakeBuildConfigurationFactory() // Skip the default shadow build directories for build types if we have presets const CMakeConfigItem presetItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(k); - if (!presetItem.isNull()) { - const QString presetName = presetItem.expandedValue(k); - const auto project = qobject_cast(SessionManager::startupProject()); - - PresetsDetails::ConfigurePreset configurePreset - = Utils::findOrDefault(project->presetsData().configurePresets, - [&presetName] (const PresetsDetails::ConfigurePreset &preset) { - return preset.name == presetName; - }); - - if (configurePreset.binaryDir) - return result; - } + if (!presetItem.isNull()) + return result; for (int type = BuildTypeDebug; type != BuildTypeLast; ++type) { BuildInfo info = createBuildInfo(BuildType(type)); diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index e870b787bc9..bbea21567ee 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -453,14 +453,12 @@ QList CMakeProjectImporter::examineDirectory(const FilePath &importPath, if (configurePreset.toolset && configurePreset.toolset.value().value) data->toolset = configurePreset.toolset.value().value.value(); - QString binaryDir = importPath.toString(); if (configurePreset.binaryDir) { - binaryDir = configurePreset.binaryDir.value(); + QString binaryDir = configurePreset.binaryDir.value(); CMakePresets::Macros::expand(configurePreset, env, projectDirectory(), binaryDir); + data->buildDirectory = Utils::FilePath::fromString(binaryDir); } - data->buildDirectory = Utils::FilePath::fromString(binaryDir); - CMakePresets::Macros::updateToolchainFile(configurePreset, env, projectDirectory(), @@ -566,9 +564,24 @@ QList CMakeProjectImporter::examineDirectory(const FilePath &importPath, return result; } +void CMakeProjectImporter::ensureBuildDirectory(DirectoryData &data, const Kit *k) const +{ + if (!data.buildDirectory.isEmpty()) + return; + + const auto cmakeBuildType = CMakeBuildConfigurationFactory::buildTypeFromByteArray( + data.cmakeBuildType); + auto buildInfo = CMakeBuildConfigurationFactory::createBuildInfo(cmakeBuildType); + + data.buildDirectory = CMakeBuildConfiguration::shadowBuildDirectory(projectFilePath(), + k, + buildInfo.typeName, + buildInfo.buildType); +} + bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const { - const DirectoryData *data = static_cast(directoryData); + DirectoryData *data = static_cast(directoryData); CMakeTool *cm = CMakeKitAspect::cmakeTool(k); if (!cm || cm->cmakeExecutable() != data->cmakeBinary) @@ -600,6 +613,8 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const auto presetConfigItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(k); if (data->cmakePreset != presetConfigItem.expandedValue(k)) return false; + + ensureBuildDirectory(*data, k); } qCDebug(cmInputLog) << k->displayName() @@ -609,7 +624,7 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const Kit *CMakeProjectImporter::createKit(void *directoryData) const { - const DirectoryData *data = static_cast(directoryData); + DirectoryData *data = static_cast(directoryData); return QtProjectImporter::createTemporaryKit(data->qt, [&data, this](Kit *k) { const CMakeToolData cmtd = findOrCreateCMakeTool(data->cmakeBinary); @@ -629,6 +644,8 @@ Kit *CMakeProjectImporter::createKit(void *directoryData) const CMakeConfigurationKitAspect::setCMakePreset(k, data->cmakePreset); } + if (!data->cmakePreset.isEmpty()) + ensureBuildDirectory(*data, k); SysRootKitAspect::setSysRoot(k, data->sysroot); diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.h b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.h index f4f66d47faa..2aefe036fcd 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.h @@ -14,6 +14,8 @@ class CMakeTool; namespace Internal { +struct DirectoryData; + class CMakeProjectImporter : public QtSupport::QtProjectImporter { public: @@ -39,6 +41,8 @@ private: void cleanupTemporaryCMake(ProjectExplorer::Kit *k, const QVariantList &vl); void persistTemporaryCMake(ProjectExplorer::Kit *k, const QVariantList &vl); + void ensureBuildDirectory(DirectoryData &data, const ProjectExplorer::Kit *k) const; + Internal::PresetsData m_presetsData; Utils::TemporaryDirectory m_presetsTempDir; }; diff --git a/tests/manual/cmakepresets/CMakePresets.json b/tests/manual/cmakepresets/CMakePresets.json index 5e9d149b8bb..976f44832ac 100644 --- a/tests/manual/cmakepresets/CMakePresets.json +++ b/tests/manual/cmakepresets/CMakePresets.json @@ -10,7 +10,6 @@ "name": "mingw", "displayName": "MinGW 11.2.0", "generator": "Ninja", - "binaryDir": "${sourceDir}/build-${presetName}-release", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "CMAKE_PREFIX_PATH": "c:/Qt/6.3.2/mingw_64" @@ -29,6 +28,7 @@ }, { "name": "mingw-make", + "binaryDir": "${sourceDir}/build-${presetName}-release", "displayName": "MinGW 11.2.0 Makefiles", "generator": "MinGW Makefiles", "inherits" : "mingw" From c1667f9bea8299f318a3e6d017dc6d63acfa816c Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Mon, 10 Oct 2022 19:33:48 +0200 Subject: [PATCH 30/42] CMakePM: Allow default build configurations for presets Restrict the build types only if CMAKE_BUILD_TYPE or CMAKE_CONFIGURATION_TYPES cache variables are set. Change-Id: Ib88dcd5d4a0fca86f86e95815edff1116f896324 Reviewed-by: Alessandro Portale --- .../cmakebuildconfiguration.cpp | 2 ++ .../cmakeprojectimporter.cpp | 27 ++++++++++++++++--- tests/manual/cmakepresets/CMakePresets.json | 7 +++-- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index c6736d4a9a9..7dd6dc2f973 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -1985,6 +1985,8 @@ CMakeBuildConfigurationFactory::BuildType CMakeBuildConfigurationFactory::buildT return BuildTypeRelWithDebInfo; if (bt == "minsizerel") return BuildTypeMinSizeRel; + if (bt == "profile") + return BuildTypeProfile; return BuildTypeNone; } diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index bbea21567ee..60c11157239 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -467,9 +467,6 @@ QList CMakeProjectImporter::examineDirectory(const FilePath &importPath, const CMakeConfig cache = configurePreset.cacheVariables ? configurePreset.cacheVariables.value() : CMakeConfig(); - data->cmakeBuildType = cache.valueOf("CMAKE_BUILD_TYPE"); - if (data->cmakeBuildType.isEmpty()) - data->cmakeBuildType = "Debug"; data->sysroot = cache.filePathValueOf("CMAKE_SYSROOT"); @@ -497,7 +494,29 @@ QList CMakeProjectImporter::examineDirectory(const FilePath &importPath, // ToolChains: data->toolChains = extractToolChainsFromCache(config); - result.push_back(static_cast(data.release())); + QByteArrayList buildConfigurationTypes = {cache.valueOf("CMAKE_BUILD_TYPE")}; + if (buildConfigurationTypes.front().isEmpty()) { + buildConfigurationTypes.clear(); + QByteArray buildConfigurationTypesString = cache.valueOf("CMAKE_CONFIGURATION_TYPES"); + if (!buildConfigurationTypesString.isEmpty()) { + buildConfigurationTypes = buildConfigurationTypesString.split(';'); + } else { + for (int type = CMakeBuildConfigurationFactory::BuildTypeDebug; + type != CMakeBuildConfigurationFactory::BuildTypeLast; + ++type) { + BuildInfo info = CMakeBuildConfigurationFactory::createBuildInfo( + CMakeBuildConfigurationFactory::BuildType(type)); + buildConfigurationTypes << info.typeName.toUtf8(); + } + } + } + for (const auto &buildType : buildConfigurationTypes) { + DirectoryData *newData = new DirectoryData(*data); + newData->cmakeBuildType = buildType; + + result.emplace_back(newData); + } + return result; } diff --git a/tests/manual/cmakepresets/CMakePresets.json b/tests/manual/cmakepresets/CMakePresets.json index 976f44832ac..e4fd4feeae9 100644 --- a/tests/manual/cmakepresets/CMakePresets.json +++ b/tests/manual/cmakepresets/CMakePresets.json @@ -11,7 +11,6 @@ "displayName": "MinGW 11.2.0", "generator": "Ninja", "cacheVariables": { - "CMAKE_BUILD_TYPE": "Release", "CMAKE_PREFIX_PATH": "c:/Qt/6.3.2/mingw_64" }, "condition": { @@ -31,7 +30,11 @@ "binaryDir": "${sourceDir}/build-${presetName}-release", "displayName": "MinGW 11.2.0 Makefiles", "generator": "MinGW Makefiles", - "inherits" : "mingw" + "inherits" : "mingw", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_PREFIX_PATH": "c:/Qt/6.3.2/mingw_64" + } }, { "name": "visualc", From b81e295f580415392f3b8047aac70408cebc97ce Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Tue, 11 Oct 2022 09:24:46 +0300 Subject: [PATCH 31/42] Toolchain: Support also concatenated syntax for MSVC included file For example: /FIC:/Projects/test/config.h Change-Id: I18dcda6593effa58ece019ce40bca7860cebfc8c Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/gcctoolchain.cpp | 2 +- src/plugins/projectexplorer/msvctoolchain.cpp | 2 +- src/plugins/projectexplorer/toolchain.cpp | 16 +++++++++++++--- src/plugins/projectexplorer/toolchain.h | 4 +++- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index e4581419faf..dae5d277fd2 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -566,7 +566,7 @@ WarningFlags GccToolChain::warningFlags(const QStringList &cflags) const QStringList GccToolChain::includedFiles(const QStringList &flags, const QString &directoryPath) const { - return ToolChain::includedFiles("-include", flags, directoryPath); + return ToolChain::includedFiles("-include", flags, directoryPath, PossiblyConcatenatedFlag::No); } QStringList GccToolChain::gccPrepareArguments(const QStringList &flags, diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index e3f506c0595..d86a0ce116c 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -1113,7 +1113,7 @@ WarningFlags MsvcToolChain::warningFlags(const QStringList &cflags) const QStringList MsvcToolChain::includedFiles(const QStringList &flags, const QString &directoryPath) const { - return ToolChain::includedFiles("/FI", flags, directoryPath); + return ToolChain::includedFiles("/FI", flags, directoryPath, PossiblyConcatenatedFlag::Yes); } ToolChain::BuiltInHeaderPathsRunner MsvcToolChain::createBuiltInHeaderPathsRunner( diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp index cca95c8158a..fbbc748d8e9 100644 --- a/src/plugins/projectexplorer/toolchain.cpp +++ b/src/plugins/projectexplorer/toolchain.cpp @@ -468,13 +468,23 @@ Utils::LanguageVersion ToolChain::languageVersion(const Utils::Id &language, con QStringList ToolChain::includedFiles(const QString &option, const QStringList &flags, - const QString &directoryPath) + const QString &directoryPath, + PossiblyConcatenatedFlag possiblyConcatenated) { QStringList result; for (int i = 0; i < flags.size(); ++i) { - if (flags[i] == option && i + 1 < flags.size()) { - QString includeFile = flags[++i]; + QString includeFile; + const QString flag = flags[i]; + if (possiblyConcatenated == PossiblyConcatenatedFlag::Yes + && flag.startsWith(option) + && flag.size() > option.size()) { + includeFile = flag.mid(option.size()); + } + if (includeFile.isEmpty() && flag == option && i + 1 < flags.size()) + includeFile = flags[++i]; + + if (!includeFile.isEmpty()) { if (!QFileInfo(includeFile).isAbsolute()) includeFile = directoryPath + "/" + includeFile; result.append(QDir::cleanPath(includeFile)); diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index fb9c622246a..807e0c5671c 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -185,9 +185,11 @@ protected: // Make sure to call this function when deriving! virtual bool fromMap(const QVariantMap &data); + enum class PossiblyConcatenatedFlag { No, Yes }; static QStringList includedFiles(const QString &option, const QStringList &flags, - const QString &directoryPath); + const QString &directoryPath, + PossiblyConcatenatedFlag possiblyConcatenated); private: ToolChain(const ToolChain &) = delete; From f1fe30ee16a8a965ed8c81b76afcb3b47b980a67 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 11 Oct 2022 13:45:12 +0200 Subject: [PATCH 32/42] Help: Restore some more object names Change-Id: I4742d855bc69be3622f823a3d3efe256ad027dc5 Reviewed-by: hjk --- src/plugins/help/docsettingspage.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/help/docsettingspage.cpp b/src/plugins/help/docsettingspage.cpp index 757db9043fc..9cb3289081f 100644 --- a/src/plugins/help/docsettingspage.cpp +++ b/src/plugins/help/docsettingspage.cpp @@ -150,6 +150,7 @@ DocSettingsPageWidget::DocSettingsPageWidget() auto filterLineEdit = new Utils::FancyLineEdit(groupBox); m_docsListView = new QListView(groupBox); + m_docsListView->setObjectName("docsListView"); m_docsListView->setSelectionMode(QAbstractItemView::ExtendedSelection); m_docsListView->setUniformItemSizes(true); @@ -158,7 +159,9 @@ DocSettingsPageWidget::DocSettingsPageWidget() treeLayout->addWidget(m_docsListView); auto addButton = new QPushButton(groupBox); + addButton->setObjectName("addButton"); auto removeButton = new QPushButton(groupBox); + removeButton->setObjectName("removeButton"); auto buttonLayout = new QVBoxLayout(); buttonLayout->addWidget(addButton); From 4b42f05439417f76619c0d667cf691592d0fe388 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 11 Oct 2022 13:36:20 +0200 Subject: [PATCH 33/42] Doc: Update Help mode screenshots to show help in dark mode Use \image alt text more consistently. Task-number: QTCREATORBUG-27876 Change-Id: Icc655eb5d05cfdcb16f9eedc836de710ee1ad59d Reviewed-by: Eike Ziller --- .../qtcreator-context-sensitive-help.png | Bin 60197 -> 33370 bytes .../images/qtcreator-help-filters.png | Bin 58899 -> 19219 bytes .../images/qtcreator-help-search.png | Bin 44058 -> 34664 bytes doc/qtcreator/src/howto/creator-help.qdoc | 4 ++-- 4 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/qtcreator/images/qtcreator-context-sensitive-help.png b/doc/qtcreator/images/qtcreator-context-sensitive-help.png index 5b732f0bdbf0e7c309de40a8ffd07146d0135ace..b6c7679164b76682b719783084512143e23b4b9a 100644 GIT binary patch literal 33370 zcmeAS@N?(olHy`uVBq!ia0y~yVAf_}V6xy~Vqjo+%J8s@fuTv!)5S5Q;?~=}+*3ra z&V4a=>%QIB)_kokS3Abe(@k3j&fX=l=xp}WFK+JP7a8Y%n0;! zd9kHr@d7nA$A!{OE*B?UKa(P4{rN>^-{1LK`+A+V;!Nw$e_!uiofSUU z>iy;Cf4=>?85aKb*4EYMUape=|9AZ=|K0@w8X{b+P76i0)pR*KEClnK8UrDM2?=1i z0F5b4(l>S~+kZaQI(M_%nOl_y|Los+V%CXeKW^D?(%W<8PRsU-Jlh{eN7hZ(O}(CW zZTGS%BJC#4k7a&c5t5%>BfdDj@c5#Pzh7iGT{*7%-FC~qslTpW`gct1K{9W?QrhCy zf3pHLM7$~`BI3@k`q;aqbejL;N7Fi)Q#NNG+iHB$tT-d#oz}7_m%Ke2rn_14iTBCu zoN!Q#``Y;)^C_kLSKlxF*!ppnF<*3IsQ~lh01Xiy9dWj2!V8=@BLbQyl~~KOiM_99 z-D?u1HgTVSNL!=kaaXneH&gy!OVvn_kZ5&UIAw9;&SECRc~=(aditOB%N8$t_a)z3 zQqwEnx~sW@N$h6*(TjgdFWp|TXGvRifP9lO2e=4V#r(VHLLFdZ~YP#JnQnAlJGMXpWhX3RJ)_! zYqhY(--+G#KV$2zS-;nR?-2Z0A8>FU`~G|puGXf;m*+P(a>uMOUt>M#U%|=qPU0M2 zy`=W8?a|BIb=rT$|5K{(53$}4HQXKRotJQ{dBWbtR(s9Oljm8s@E5JywM5SGYlK$w zl36kvFHHPcU$<-H)0}<151p5PIayw_#kkq_%z=Mz`cLL*URdycGl%S!74~xi!i)cZ z<$H22bAOuG`R4oPT&+$A4;Xbfo()$!);leHE1xN(Bqs#UpR#^gI)nXX*`;fCJ;^>GKl#eh+k0MD{}9;uOTZ_Tzoo{g ztLZ53gIm!T&wZ(%Yh=Q`T6g);3k%kMTd(kqx$9MZ-u`>aL4O@x|NIrxQEYHp7;x&w z0VBJKVy6zQDZ9ROpO@y`4eLHW`{1Lt(>p7?G;l?e&wK0cx-dXP zG(X|lQPay0S#p2xly5E3@A|jHGv$A;_aq~S;wK(uk0axF&dC4OJfgA0YMc1I;MBhJ z)m!GCS>%22yzaGcHJYKjcr5SpPHpt?GP{3FaHX4~^WmlYW*)RX^Jd<}0IQe^4(p!= z8@H|A`LAmEzvfH2P6sqZxY(v`ZTxv$_L5vHk8NY-+}TNcjQ8kPC$cSnmvGNB=l|7H zl4@&K?0zP0U+wJv$oN&=v{1FWBgt!X5w6xrXAT@Pw|=^f{b!zimUiW>fQ#l*n_tT0*)|vM ziz(Aw{BUp3zdeum0|Tul`{o-OaJ4#}Y-|kF==$+TXZFXfcfK}y|2Uuv&RXyi1k3}K zE^Ka)LdNN2bK_sTRwpoT>4v2|$qAdnXPCB5O5OSQ+ign@kTZ@;NPv_Z7cK*qV z0u@cL0LV}_w}S@^47gaC7l#y7K4@eIv$eN>IwqYjQ~&pC^6|dC-)?2Q_wT!P_ipWy z)vu?9$Nh{-f9|cn*QD}O%DFc;w-gtzGAep{)Cck&sc&>u;zu(gKbSKqV&dIUW zZ#EuJF>&y#Eqamib*^>!sV!$F{=6l7{D4N}Jl)G#?zyX+czyoyT{nyQ-Y*~ff2w+$ zr;2iOy~wqzS95P}O1-ru)AG&Ei0gC9?^#~bIXzu}dVKIYrRM&&#>ih!C2yn}ZupyK z`Qhq%zAyY+mM>RdYrMN=)~B5<_Lo=uGz{n1$uh06F;hQBQ$JrKqR=^BXz#l>Z)%R} z7%A>g6Xwx=C#k=%kyqBrJr+^68he{l)+9 z0e?#759{?;S87iYGG%Ah_Wpb7LC(xD>#X3Z83{$-B6mI5wSRxb;nmgaq-`n!jy>P1 z>OJj*rsu!X8LQ`czwo|ude$_~pQcZ>CjC}rdv;y_@PWF&uTTH~^!oJvzi;>Nt9YQz z`k&=p-Ol%C_UsLQYJFPft_H6&TR$I&7-by^&mbxtdsO@9X zGY3*ueDql*)c2${*6ZKPuTLiX*L|LS|Ie@M`}O8GrN;K#|J(6L%Xt5vr~2Iw6BAM+ zjjW@O)y#Z6dzA(AI})fwM8@BGO_V<$fV2D zTCV-SYGmNQzb^UZ^wfm&;)x=c%r@MTP5%{lZ{y(uKWsl_NBt62O}yo-BEGhjTYTT= zbJj(Yn^k=5Qg>FIm}C8Jhx0VG{Z1!d&6K?1YkpT`#);!gt=1MhKKLRyL-ODA*g1`o ziyoEPRKHUA$F}yb-kYq$ z*2n42o_6`D?e{y$k~i*_-`CxL>WpdjH4oO4LI)3=x_aP}EhtddZoRXAw?pvM)P!Re zSC%Bs{}S`x@q5R^!|P7!oHZ`k6|*(#Y8$WglWjW|NzAzOQ={^`-QQg~udna_^Xqz2 z!teR@3uhP_%zX2@`e$Bh=dWz5UrVQMSP|&KDZN8TEs@!K|C979KfJFjoVI^550B59 z*Y~R5@BMl$`fjI?xq)_q+>hc8GXv+HHHC{V^f2ZoxcB`K^?4?1S+qofP0hL2D6Z_m z0Y=Wo(?{?9U3aSGk5>Hh=ku!l4jJ6C$kUwvkt;dj({#Ngm3F^>XTHC^t$y;yrgd*N z{h4E1{q5e~>ePKl)~OUL3wZJH*mW)HO#b`s{l9n1&n}uPAT1oo$K$?8e`-R)t<9-> z8c)uD*vxO2u{P);n_1?Y()wTLzS`FmAL+gR{6R{J=uh>PJ$x&eJ5HYWx;5!qrgxFc zkpp$IQuQK#f8GC|ByppBU-8Ss{Pt5OyJn^Dif#(2ou+v8*5tSir%Ke*3xk+<|4y|Q zOIs`a!_-xBjW*}`H>+A~f4x}z@t5f3zBQ8~d2-IoFnkmzq*b7PNsyyB>G{M567wx3 z(!_$xh2meY-CucA+*CBAZmS>5yDg!LTN^WLywfyo!FgilM<azuo%}bg>yeocbO*D>6 zDMfl3iV4O4_$eQf^!`TX#z>dr7R&(`hts=U<e(kokky9^=l6P`tI;l>PCy9bA8pT%|&)nUwxp!?|VM=sa`v+T&JFXSeGmH+o#q-TzN2dS5H*>$PeW%NHHpJ-Ip;`~w^_y6{Wi|Nk zSgLk|0>NTNgi`vRCdnHgA0L0ZFHo{?|Nncs{@;JS|KI+zoZA2Q_Wr-0rq?U8eLF1w&tRjmt53D#1}4df zV~Z!e`+7#Irsl`P_NVCzhW3fpMW@c4Igs)sa834`8ynxb+%nt{`ERDz3)RAqqvd)R z)LKqiK7F-%{kCOKm-{?dU^6>?TYmApWzToX`c%kFk~y$L_f^%3+=GJV@p~@re}9kf z*Q_&tK65Rf&GK%}CBBJArU+R+7R?a}YWk}kzHUnXS7CpfjU_LG%0+@U399tRJ@bCP z)bEVO5|61Wx4hp?_xW@D{}1{9?*k^z+~lFQWb)P2Bw<-SUpI7(s^<@5e0+)qePns_r z|La+7{vLJv`M(~xgG%b+goHG)y^=hWS29V?=&@w`qP;fI!~DDVu@a`vpC{J~6dlq{ zkc;qQK5cMaD>bcoo0D5*Le}}YJ7>)kKX4%FQPx7atW`6^ww?=JeTGNp?Ro7Fjx3WZ zjSURmO6ou5)#E&0akBaQOQ{>v&rEVu+jnGkaG#Uc+!;PKo^OBsd2X-2(WLWpq<>1x z_Pn`MJN1Q?&n!1PrQ~Tbxj?Ei;b~UF%Xzwwd3}27A0O+zX5r)7@3gCZS>3mUo#ww^ z|9%=YcV~;KiAl<56Rz)POz-Q=l)Rx|_w%&$_x=C)|G)pg>CWk2Kd1kHJHP$!!R-2< z_x~OLPY>Sz2k*Xjp^5WQaiV+_$Vc2rat=L{{MqK zSA~Acp2{EZ?5~(lcxma%H<2et_1qEu9?n&=!OLo+#9n01q&$p?C;rbP@w?9(Pu}yC zh^{-erDx`;n$C{)_icQ4E@kiohV*u!SkI zEwhb2COtzn?%Gmz=FRy!Q9D0;fBLh9eZI`R$fm4s{wZfYGo5;;v9Q^tGo#P$7uo^4P3Uc__e#1Z@2UtbRVbx2+( zeCx1k{JTzJbvD1P*VOesZ>@LrOg%opZ+8=z=36PZtWkt5$S9n&Nlmt;L?H9h08kG`hS0sh7FI z_bDZ}d+vwN-#vNHloPXeK3(d3%v-VkceLj&@yoxq2mE{;|HtXe>X`cm!k<;HZh4lz zGC(yiVbk?VCRL#;PMnF^Kb3>|^l9~}e}c8o8pj>77kD}K$FyG}CSR|YtY5rn#)8n)-!0Xn5Q~A@697sDqH$JOJ)?9AE zixa|oU(ekXpjqm-GgebZkD=ku+zLYj9v-cCE(RBMgr^wY)4XQA$-sc2p=LfN#>2y~;DCA@4-a$mDO5Yp+}9cKF8s^rrncUj*`;|(j>e`mix{rPzO zb+hLWrd_%EYI^zivTyZwZrXCl$@_jK2m>OJS5>QlqOVD!<@ zV0Ntfr;LQw2m2Nm&x@F|>eiii_x5h{lWcnGm%mFuWO2u=$VE2=pq`nQ%{=+V^<4WG z`_K0J-7UZJo?!J6O_H> zg4xD%tMboHXSl(?ChOl>)*Cw>A6mE5PJU9n`8xxqSiUmW*t2Kn1|8%nkrdSL?9JUY zZPw?xt`7xn9k1SP{k<$dgy+n?q`ozLpb+*l*zo#~>fM=BC76XngBAsU>sS&o{h?=c zmT&Z|A1xL)FRm<2+iF#~W^u4@?Bu1wZ{4tlR7&Z&;5@3 z@!}Hq>)w~YV*5B*m4X&t2njiRckjBi&V<~c@IbLh#VxY4a}Uniy?cAG>4vI{);~|i z>#(sgG&HK}9B$*aeyqPJ>|}b_ipEY4%{-I8PcC+@Gq5}v{b{xEqfM`UO6#hwJ(ZfF z_cZ&JV?1|MQ`}RwT|rVaf{j-;y7rn$9o)QEysCUbJgbG^hd2+0hDGx$iqjID+juxD zu5P^^H@hY+RqDnO^**h075{${!egT6Xk< zY+rGC`Ma&f+sw}Ou8iEDeVldmt#!WNdVBLsrS*5;KgnDiUGT28#OQoYqS*=APv8AP zXnDtBYqIlEZP z>TSiB7wNofkKM8{IO@c6!4>td)?B<8ZkD#`*P`CtahBC)S?PO|i^`^(*FV(DZ;k!B zZHU+nrfh*vmqgx%<@R`JbB)-0fpf%}MAy>h#)t+UhB*8g)N~ zoOUfP@5t`n^9AGkSFEeqEmb&vx^PBcb83s&P{bmOXivoWQ_*?!X_u zhZbFrekJKm{?*7aIosgaj+FW9(-tsymsyHV zS$c2T(HUYi!IxJoxwnW$H(ZS>JCwf=qV?{4$V~kXTrt9W3a&_DPivHEr-+Jt+;vUL&d$D z&%eLs@iAt*zEd+#;!4b}0QsyEQg4vQ4w#KV!lWUh?X2a{aem-$L&TcYn}W5_&l=<>9)5 z11CGS&-50z3{&);>pC~>#PYhykCPRdyI-fod zA3rXsc&{}6(O$NOMj>YH)5`-B5*iv+%?u>Z7aiOAX2C=~Py0`kkBd4bxn)AHzXWxvc3;bq3^tCAdws+Fy-|7qtRNl8f z$rO>02sxy&WO7ETTC8iY@vg7R?q3eEJ@aPr&PsUrZENBBAAZZsxg-q?c0WCLE__bo zejCXdRst_?#Z|amDzE4-pLg^CLxt2)2ZIgl*7uC$kN>*1@Y!wyg98VYJ{^de9r$_v z7jsv&{>Gd4lH0Dm63=wMxv8`9XsJ zyP?5>1B>)Nblb3h{&e8insjrWD|d`P=6>GaBP3x9tT~nI> z%~c|zia)ZqN^VB=l$u1{ziMl~?GzVUaOYj?lm}ry4hnOoPy2OQBSq&^fN^C)L*r4q z-b0%iKX>Kbsh|F#GT~iq<=k}UiPFnwxg2_B>ZrE1vG=Pze@@Pw&j%h^Nlx4FAiDF+ zJFCCnGpGFz6#Qwj;lSRd2l-Fb#?9JQp83|4p+G-nBF~$3%dPqB_O|)d95}$n@h|Yi zmrr{y9p7+l^HHDV>$4->nCCJa*gIkAWcF>Z1CFl?^^?%C=6|fsArX;yVW0O#9`;*z z6653f>_8Rz)Ps8`tiH8IT2U7iyKEe8%l<^(Z$5RZaKTycJ>B&_Yzzqr%pWsFZ1{N$ z3>X+RQkgf;GyIsjd{Mz_4^~r~R4uw%Mu=&s?gPVr65KkYHe#GN&<8 zXxX%q^rQp^5TDJgfg5BgtQ7$gQ;*}(xt>#(@LF8H*2nc3C?_y7FtAO#seJIs!Zqr> z&l@e*zqnTP{L}8flG43pZ)UXmoSu`xJbS~RA5YF6>K5Mna<1^3rJvQ-S=(j$Jvv`{ z&M(ro_m}3%`&+l~FAuh@HwHCV7#bQyPai0oYq9gS<73A)<+e8p4ZmHT@O{nh?^na) zh5t^PZ!|Yar0D6A(r9%JG1HZGaboAbBdfpK9B-8Zk%hn-O+3Y^8DL&vTyF{ygp5e)3Og+J~IG=QvNt zGEYv6-?Aus@{-8lb86AE3ubL%%9oH(Z*pNXOU)8xU`XL)o2DuB*T_xr_B$`7tku_4 zP92%P@Yq~omrj?pE=P|XShXlQYEkOzHHKc1r$4D5-l7&ZGjX$)^W!tW(qQn>Xj4&!-+{byg5Jj@!#KnW8a+_YwBL?@Y(+_V5{-}ABQh9 zZ(S{KSN8GnUhPwwY}dYBTexk`UGB_XQyw~NrzTx0s*ll1Nmys*yCF;J)i$G$`}Uh& zUNHJYF})w)c>PRZQNm35EeHT2@Yyh>$WgC{EgGn442Lx8AwO zDJcO|m7nZ)+7+~QQEbSY87&9Dtqt%w&DCR>woGEi%DiWbYPIJ?%<2@iG>*Q#`~0fQ z`>w~WV!Iu4Tl>`B3Ayb4F`M4C-r1_vex7;ugRbclFK)dmnX=_w_ZCBuQ-1f1WKVm& z`gHBnrvr1|teZM{j@TZBnSqx>_BuS_VLp5S)FNY?$ez}=@7r1fk*xb%hgZ8Svp)>_}yS1m6u z3qRfeh<#G#tUY(t`q%`YVxwF*!eRnpw*;YLdU;4&>`{gNT)uUe( z)hJH%clC&>&%C|UZfS|>(#>m^DL=m@wdv*B9NW`kO>5$={^~5AV4oTJxGpw4Ka;ms z>D+O_A7SkOHJs$1Hkm&Ee)Da%)rQpl@0IU~|Gc_2TWhY4#=Y&g-aKhi;-2u1`I640 z=4rp}XWp^xJyfEc?r@>peaWoNPtWrQJ4H6y7<|4i!OXoaGLB7cXX*_Go)~81a~sax zjGue$ccb~`9R?YCy3d|!6|CJ={Il!l_Pf)LN!nM|C%sZvU-Y#4`uh2n*=2gW{&p7E zn(FcV{E|+UI5Zx(n=|-Z;>+ex15-Y0|eom9>`g zfBs3_f9}6c;+yi-IsAGJnNbJ*PepwEv&w4o-*+Fn8fUu6e>pbcmG`9b#~-cKZdF;< z$DeR%v0tFlT_G1CxqqfKb8}-(!b0uFzpFpzm;AqJKUG-b`Ri%d66X5OHhX_#WAec! zmF9&nzp8KAcV1+!cZc<5Zlj-C(i3@}s{H%$xZnQI3FYEv=e!qa2HxE!eg9HQ>9VCu zwb$1Pse0zUL-g)neL1CK zC-oZ-%n&zteaou!X5MS@;;(G^o|9uYuYT=eu`X@<&8@rN&e^C~{`z5V>VkRy{BQnK zNa@qNwshqh<0ZOl57zgt`Sk3?Bg4Abhz-ZCm`1a&eZMm`|D5>M7xU^Te&>BT;iudD z!=gQFOFXum-ybZb{p$$dzs&1hAMM}kYwVe}Kl1JU1vlkC-_|&FJL&57|Amv5eBQ@@ zV)g!|dLqlW@a11(ZfZA(^_tSfp zw&izf?JV7MD#-oGnIhBTLvtTz$E*FaVZNNBeR_f4hsTq%H`h-T)iq`pUaMVuV^6QY z@ttK=E5h?RS#r#>xMYCMXwwQjgE!U1nUfg%G^1h6F#*)eRb1#}o z%SLQ6VoY(Z4!IJkePPW;-KV!-pWXO7`H%9$J(o7N%>8bsFmr?Tg(q?v@0AVA|2nOh z{L2i~zfL$H5t06YNj^*K)BzvP>YA^wObg9|8JM}ZC;w-*s&EryzP&m9yzzOP&AGRe zPfxo$bE?HUOa0?njSmx78=D(k-{NHb=xPabLY~J0zx*@P8c*`o{XD(<+WLGS!+WpJ zGh1KZrX#^n{JhKXlkcPfxNipWfbh_v@FF-SVX- zyfMtP@BR6_Y}@gYZn@~nPxqC@md4DI_#F6KzWiJLp7Qd&|CgQazp5TDaaFJ8PUXUK z;r_!C7KtoN*Th+ly*Lr_esd#DyBv+?BIk|t@)dkO@#qaH! z75E@{}TsV-* zJ9F~H_o5Q5CR4m+ZA(N?1#HYF-p_^}=DhU&%3k*Wj}FbfvaPdG^wfbf;=*U=#{Xg~TM_suRQl*iNzm&6f<>S4T+gEa_ zCa&e){cKsyu88k$Yo|%RTPiifNY~qZp%?RuOp&m@>67*@l$=qJ9NVbUKZE{uFD8P%e9Re6HM#A-IefOYb+7uH z=)>L8)AP4|+FNCPc8h^<`hkg{R{YN@iJ`QoS<^)7Od-;t)B0}@%ffzOyxf{va zsYf=vy-*Ukw6DQiwYPERy=^)3Qr_KG+@iyqlk;~O_c`l6v-h_arafX$O8ELND6-WC zG$zTwyt;xp+b-ki0lzI%cQi`gjGgARGf?lb-igUxP1E0o{j+)cogiF)&1eYsr_AH++@d85ta=fm)6X;9c+}_od42Z68-`5czsJ z&sg@!)QNvz-EM#NH1Nl@&j+rA3!S}tcW1bqx>|qfQ(IRFi31MLuWfw1EbL>=nxeF< zsSmGhzh|}W0^7BZ*X+~XG^J;JjXS|8$o$#%hu!+zSNGzl$Vr!uN^jF2 z&F+rzE|y!of6r|8r=X#wnbCQ&)~f~||s%!oGJaLQ=I_donwx8Ji)u@{Sv z$=W4#hwIq(DeOuBTTYT3ZI#6WBRr%qiX{Eu2-;kkE=IJMS(oc0azqv5wXPf)`(Ee!^ zlJC2FYGSuXecpIf_FQ#WNp6}D^XIR@hhpzaH@|Nc`S|MH-Rgzq?%P*H{H^G1TxB;WmPF}R*>bH8J59zB|K|X;?Bk12=sWad+T4t)ZcL)e_!v~n=$RXP~P9! zJ2y+UmfZWFA;?!Q$b9$!!>PWH!fMy9TzRBA)%oq2$fB&H2R2oxfA5^UTh7Eees#*O z$Lko=6S8=8?2c<2v56%nT+=@A+|z3R`B#^mdK=%qyA$}H?eHF(4YFl&GZv+S++%U9 zPgdRh%tO_w&ZTF0c79xB!8YyoDcA1CwOQ5`ha_8THhg*CY7(@2+Dzy6|L;_aDk~G* znxw*^?hwB;Z|6$6`a=g8*gnKg zNDh{~vFYyfUu%j|vZKU*gS!l$BIJ!sHW+U2Q)WB%`M@RTC1-mZ8QItvewrIN??1Oy zcQfzG_jlec?bQF~ef!+f)R33g+8NUmQiYgT>oD*BZ5z8wA|ZicLOk>5=)l95ma!c_ zAa(1_i5YLxgEp^z-C??V^~vrzJ6Gqwef4?TvNi8n@5%gU2K5acJSA`ZnQL2{_cC{` zeBsiGS$nOYztnf?ZC4goO|Q#df3aDD~>l&#uC)=ZQn1ypUwP@y~)y76&JuoA`&vN0d*+#m)Qj2GP{JQt8mG{Cu z$>7-z=1T|eWIy@Uw~uGtbjyisTPHF}M|}HxK9Sqia6?S42(x!y!l|0`EB1Vt`Z(nw z!wl(bUF-K>>D-XHo$ts21A~T3Mh2->^F$|2x^z(@q@}O#@I58#veZ?#Ys#0-yY{n@ zJ9NWA2cBb`hiWgZ?r!Xq`gMJ4^y{}4GW$HFvn4+-{Z@5%m)8w{trdT-mm2NZ-?wVk z{_WeoNk#KVtSK{}YUL(c{qoPX?|QLT_xGKD+kCz9ZR4d{y@&5!zPdfXV_EG}4vV=w z>qIv$JfYwDZ1aURPqSlwo-mPL_su!P{wbpo7icUoMr+@``-d;>VP-f1N~K+*%%9V` zq-Ta(T z7I^>hh}<#R@b_w|M1`>B+$^{5#@$!6zg{lkD_Q()>-UVqb@MhJl{@z1*F53&U9Y~W z=OjGby2wiG=FAODRlDVH|Ij$wzS?%xQO_Bt-(-sTy8klq{FtY*0yDi-u!yP*StlOcZc!%FdNG;OnbBR?!Q^bj1QFbFTJoYOh`+EZCTvT z!y6}0VS5(NGGC%q+UN9vKVH-4HM;h*u|3bQp1H0u^KJ0W3su<&pfk zW}IL8flciC%oyp2A1nA&n3;KcBqFXPf7CW)TV}&<|8L^2n}>tnv#)53yl(SYYxb1` zZyar(-+I~2&?@bdEn;L)@J#w-m#M+o1+$aFudT?wG5?BRmWX^{)=kgs>-Yor^ z7ZrL%Z@I~;56>5^oqs#<#D+%KGPS>f9{1g!{V#a@yQh(n&FsOwGjpFV{=og$r{-(q zw|~!X{mwaA;k`X{`P=7x9xt<`*uKs9{p0u1?MEeMeE(28bG@CP&dKIaXRY+|Qa?BT zs4jnhtMK5A{5|KZi8=YqJ*R4&eZ4C+wlX(x@9#3@xWpsEk=|V$A!~z{r8v1y z{Su~h;DCWa>oVu*dh;@NpZ5A+wPEMVBkqc>&1=dX^}el~ly>Aob!19S%IW-~P1AyI zh6l%`EUCVp@@?^i+1B6Rt?RFvzdbqOpTI0ZGi9E(Mp60iHzjAa=Yd)d2?-JrUFOC6 zRoT*R-ncBgbbe=k)WzIS#gT{R=yrzxWYzxTfPreUNl3pXTy@TYpvhm-X)IX$7gQ2M#DqZS2gs zTl4ws_BJk1>A*Ja%z<0Kzvtwe)yH1ZxcpW^f&pX;8{33(X6p+(9y)COnEiR%TXrc~ zX5+_+(_3w&#Wbf@Z`&Hb?QsgPZCI;c^aBQi4R2PwzLEadSF&c)QayjEiJ=8QxW6IiDk|e%Wlo?yI1u| z@8|Se-G_e5eeP@2;mtYOHt(3!;T7LttEJ zj4%W9=~D+{RHKUb8T(hYR3s)GHQ6AXd++c^@B0VlY!^xmHvaVT=g+ir7cIHPrRCB( zr~j#XKF#D_(w3ZM+R@@>KHKKc``@!#KlE-J&(asoLH0+_T+x~Rvh1*kn&A>3KJPQv z_PXw>y}r*+p_+Mh-V4FjRc1Ch6LS-U?iVRV&r8s}_LTJiQ=t(9kI(V9rQG{}UGf(5 zxBXg@WnQ$rxAU{^@2C84|EyXW%00_&-Uvtyqx^*xPMGVNuS{5T?WtRaT_IO zP1B6XTXWiM?NQ<7z4F#;&kC+T8ob=Habxu@HNWiDdyi+N{4!C0vDI5{?)sdJvahU{ zHy&}?HNCgra6?t0vbBS0@#i;RczwdQD`lNOQ)n)dnb0OJ`8P0EbI&fxMYA_oH(xc3 z-`u$N`t8!Z-5Y$rorqj=`}+!mh;3}odhM4bC-B%Yu}!;iAneZ8OO*>V?!Uae{BlR5 zr1Ru+9ZL*zD`pr@$~gOFn$)=~o78TcTNPHEwqW7`jg%exa_)v1-kh-2Rby4-+Zlqh z-b>90&nllItHHMI*@DkyCt{>;K!^PsUzaa4p6tF&=vv7AZx(keyuWX{qW9wUr6aB4 z&vfn>T@-(6v~2nP$2+I!35m(fol~4Xn`7q9TaRWi_ge=3bqhemw8)2J_vYzn0z6{>NdF zuXlcFqi)unyr+-#y$rctO3g4=(p+u8#VHZd$D=ccUF?F9`h}+}r)~~8lw7vw6mP~( z$2BKj%(7g#_P%V_YR6288y%+Y=YB3qTGsV;#=xXQPlxp3gm zMWgSc6Hd;oJAZLySM1euh0B)f&a+y+_S?C|ZBaj&(!}>zm7O(vTaaSJ%zgC0nFUjt z{1*mEG2D6nRQ!HktvZOOWmJ1yT`TO8IewJc=2+>Mx~hZk!kW=t&4?^Ds^N`F*c zwp40{ns9u~*{NpV+q_Dp7?{0fn7g@pR82NCSS~d&Set1nm)3r5!HdNc9wi=rZ+EBo z+lN_#UOZ>aHZ+PbXIqsNU0?N+`S5`=23I##PO5spS+%!Ob>+%q2aKEyHypkE{^j;J zr!MHIPci-KH^1oQ`hz!SsA(;eZuQ9kHTautHi#G+)EoUXHeM?+Td-^MwXW{QrDhwp zBq!{YZDna_lDIKv=V!UQ+s-C^p2luuvf;_%35_#9vWczAPnoT`%3Ujh^XP#dpY_h) zdH!E%Fxw!*<0$qj?!;}rwQn{wg}y(#`|M8cAn7AsQI}6MPwv?`^^``+Asd5_>dN)r zZGzi<%HL%DvVF(fKd;O4?CqwRiCMn+X@Bk>&|e(RU1vbJwHNAW7Z)L){3t3Iou7(B;oA!zuB`urXxqeBF z>X{?u(t_3AGduG;rrWklt9ze1ut#FX>;`*=D#ebI8c&>3eeS=Qp@H$Q zOPHK)VBq2j%VKBFQkAii>1v!QxQTHhds|~_=aVAU>LcQywI)2ES(^$u2~gS2@BviU zdL29P?{DyYA<$$d0|PTNq$Xhialti+0RyN$28n|3fddSn2Csnu0}qeZr2}qLVoxq@ zT$^QA@o3VGOGkxeeL?jW1E{_VV_^P#&s}AGo6QwaYlsb8qp=zosDIhIiWg)J*a|LV zuA5~aj-1@?S0W=K8a=f?@C2g&sgur>kid|doABU;rwW*Gm)lVtK@|@Ye?(TxU*ZzIhHDnXJ&hGzU z&CK7k!mKZ)oi)6A_C@nX&d1^F!>`F~mrX67W4GHn)jZquYSli~Ey@xS-<^^Y0?x6S z6sNec+wIM|^<`z~UDUj1b1u+zwFgJ}8MH^rx3 zUS2*~Vn#&Aa#O#K6Jbi_ecM+oJ=z<-l1(fwoHuXgA(7;S!rBj^+qUW1zisq(UYIiR z;y&XkFTWk1x47j#)9%Md@9kk*{v%CH#i+gU=}|}%e~TcT|Wz%oI7OQ*n6C8J|C5>Xv`^JP$f){BgJa&FOzK zMRt|B?0GYDofE6^$HRsj9Mtx0vR>#@vp!!!f~~DFH6dYk*!@3_&%f4Jf3tE_dlJrf z&cV>&^P=eP$_Cf7J-1c{OLjczTqFANK__Ec!u;QNo`W0LuX%Jut=cmMyr z`S<;qpYLSx=*&AMky%w|RQZ(2A(U1FX! zM|ga`WS^a7%5U@Gz~Arp=ks%(Uf5{+YwJzHDP?()GC zEhQp$v3=WI-u8d;{R1pBPkz)?X3n;{bbYI-yZVl`xw*Wj*7N2*zw_s*a`e~IMc2-{ z*K_Upo%T3yj&fk3b)ukntoIG#d?=OwLap2#(JEdQDfBW`5Z`JYn z1{)lLpNp_Y-YPryyY%L};^$@hyjMG;%;o={v~E0mvTbilws zL!NnZ@SkPAv*iL#{rdWPX|bv`*UveYTt5$9e|Dna$?LNd7o)6Ch@BF6V%6HouY5nQ zin7eS+bw)KFY(@yQfu`mk5|S2Pf}v8{yJ0oFq@ij`S*7>dTgdnZtT=8Esa#1S)6-% zTiMNE-f13|-M@CtdXwNkU3zz>km3ZT;Pa(FUrA_dO?nu;akXczqjmf)!=wAZIvh7K zJzK}3UGld7>xM1m_7^^%xO@LrYPrwN?~|9$vD&rNecpuJo$e8QbJdT>nS6}7t#lVB z9h|3SnT>OFWF%&*i@ter<tiLTa;vI_%9+_{kUT_)595)jV>&^7Wrybo4whxEjjL0i>$uQS+{KO*C`*j>6HDqyua_a z?}_a@3znQJ*t#ujbzj}fM&>H!;6}K7wTQ^#MiK|PqiHS1LHeYy3RL6Z=N={&|{f32>i!%Ok%sGFcB(~^%YtFvy z{}y-q%GW+!HhrE!#=i0`XO0{=WytnSYvTRw)3n5^jf);{ZeJU##Nub6ey(DP>E@`( zs}=fYRc_njc~W|FbF`qW@fQ6}%a-bAN=0nCYyQUlX8G%k7v=UMPmTI#2fOb!(PDeH zK1bdPw2qfCD?#Y*uHWx=-%UJzv|BuS;)Xfy`#()&PrJkM^RMOl?PsHdKlv{OFA1XR~Q=X zZ=CrmOjWsm-Riv-p5n~hk`ZZ!26u%ct->p0+JH_|tfgZEn_dKSsPb>LuTA3iY`~Cjg7d^c`ziOGj z?cFy1i0czq*lgIhPQ7XII?&t%^N|C04!Up6xwFGizPW#DUV>lFNvR-{JSP*=6W+Uw zjJC|Vabr)XpWKXzJx^bS?45mg>!r!M=CNn8?sRUE3<}LRO}aHtpa0C&O$97|*Hy0` z;FGt@VLgz-#JqaP^G4mXDoa{D6T0&zc!*VIqGY&HUl&&XQd`t2}8Hn_1$c zCA$1J3MW|D+Q2JI*w`d)9Jrv*v!=o);$45~(^q>Z*zotHKVoKUYh2p;^V{pIHT>Ea z4|J`FmypPR#s=zJcbOSf&iBtgKJD)_>Gca2@vPbLEA%8=+f_z3Hqa)P8GGK;9F5i1 zeV38Z!QZfT&B~|?UpoJk#BHe9m-_$dxp$}MuGRfzDVBXsx_HXWOC9-r+ZQb?Ke%+; zpSk&*=eIm7u?~{BCBPQO_Y1VJ<@$lF^mCj19DG7Pv9L`mW)}Wf^ghM5_E$;C*=b_l zC3noDrJ25*oMsidrRsE@^Es2^Klz8Y$@tA&yd`t}is-EH4a@G%G)i2bBr#hfyuw)` zqVk0}8(TmO^Xw?ovsR3TfhUC}A~y2)=o~-Gz}-1zvx$v+ulLLw#(O_Z%?v!%HEXGz zuJHEDYlXHd^5~paI=`F$MYvs@RZC-H!T}8x1Fp_SSC#{MtLrXnew%#f08?^Po7T_A z5v%-Kr>mK7_#|7S)7N;C?cM(W{~o#R4`Kc-+3Iw%^dM+tXPEVTh}SzVP$*~K z=iV7r{C}~>`OD9Z&mJjP%1SG$O>hX_9Fm`q^62^f17bQ64_;m0`~6<@kAv>u#s3V< zk26JPwFk2tV?11(;2=HY$%FL~8vAp!6W04q7j}zx~$7VL$KOYW@>&N{$>0kHh zvHbrZ?)JYf%K!f;|No-=-;4799?JiFz;6HJ-}n9h@4l~le`%@r{h#N`?f!gN+%0Zj z^ZzgZz1r`0+vTb}!ayTvhYu_$;eGS#^?Lb0DOTpi0f$__yte=U{QsZr^}n}+_9y*6 zUH?W_P;;R|M$h;{@;&e!_D^p9?SoIDF5#wf8B?}?`z-x zo~~E>y_sLH?jd(Ps8RlSt&72dduMtZ12t5G?EZXkzPNt>&)NHb?%w~~`sdH?_&-iI zZ|wgr|NkYt{%iRBnor^NAI0lGrq_QBaT?|Nq|q|8l<6Lp?*?nF6nWeYXE!%-Q_+Y5c#XM-D$(?>5KhP_k0G zkiq1IC-dun|J|H^erk84sqD+ww`RTlz2U9fwryKYm)vFiEje}dtW)(29N=~z&lxRk zKJD@=@^OJbPR}oS@MpT(LdGeJL^-oN!#yQ*I_v&^jsL%ugaE2CZFbP{c=Tf^|^^_InSOk*w7yJcJ_zxt!;94@Ad@vKfB@0zGihIXwsvt zv6WRrSMtySjntqg+uVOHp3vx_{p;(`^Y!<7>)zhqUw>wXVfmfH_Eqshy1)N@ufK4+ z`rVh8#!oX6rm5@Ru6=js-PzpdIlGPOW1~!6|D5jZ>a5#a_#|e&xXNZJL!Z~3dYd<0 ziQJ|0R$|7dCqBP-SaN-j;j3Uw*p&BkBA- z7cXB{W?S}Zy2_i=!CL3$yquaIG-Y9jfv^+WUCir`87C#^Ha^cvN&uys)G6%GGW-2cpV4&g`?F9h_f1yoqfo!*dk>bG zr|t?naNv;i(g3bNm6hI2agQRx-d&%d=*%Z$apCsu?5B0LucPlz`o3$`udn?7Kky4N zSAV~IdAZ--;7m3(Lxa#&J%Ju;8+T@=corY3G2HNgyA#ybH`q|r*C^@tL}P|{chMQ2 z*j1(m{!g5&mgXIbR#u67*c+t5sws3~(u3(e#!=1v=66db&#J2b_ovd(Aawt~kMjRN zR^R_U@5S|#lb36qJ21t@K+}k8rJ+IOhr|1LJ{<^)d|!0){>Ft@yBlvVo&c)8BqA0C zZ4Idvd~#`(%h&7Yb}!wrc)~n|)>`d*2lgz@lb$Ilam!WHX`=d?Q_113+t%D!|La%P z*K^1F?S6U4)vtebz5eg||6h0C|NE{}SiQ9fv~c^>-2->N>q=RyPd)Qp_}k;xA+J7v z=T1zRRuO45E$Wb$w($LqjGxCDlid~Xdae&k*}QS_geOmey8@mpb^av7Re5Uqw}Zls zFQ&h^zP|43>i0FzFGc6i{qfA)AGAQ2SAzNU_ucCZHv}0QycRd!S9*HSRsI&9HfLgw-f-Jy|IuCU7In@N zGa_^L7U`ZYS=GvYUCZgIj`9EebEU^s?{elxM%oC^H+1(pDRNP>@_BO6-(TE7N{R<*=qTIrcR;sp#xVWA`HxZ#F>i^r_Rf- z+`MO{k%57mjONndCwnJ+I+a_=o#OQO*Yo;+>6Q9VK0eOh^YhvD$r3kOIwu<#e2~0x z#Iqw@kjF<})#$PRD$$iYlM+{6%A9s&^_%0%cDRXFEb`jZxKlc`TH>m3=(Z%Ymd0KV zw#`jH6TY1hG2F1p(7;Vnb7_QL+#ZedJEp5_X!-RORB7y~_;@%x-uBxu>3lWA4VuBr zu3bBK#OA=EA4Wbin<}PuHQrp59Mz|2@~n#5%GXByKJ!wqdYC2ky$tkF5O zcfz_-P0Kj%^qrUAaV(BJA6fkN)~CM4K#irrc0V34@01Oa^Z3ZUdC3+1nG?*N%F6f8 zx^N(GU#id5EiY%VN1RzP*Ywvj!;bJwi5bQX8s1mG8%i)uIdCA!O_8~~hCgoO`y(bs zd(WKRDg185izx;Ei`*2I&5wLOu&HRr9s7Aq;Ofus=5)Q<@SxpK*1CLhF$grQv}oP4 z)tO{Yuee^D`Q%fb=Bky zvrbmpxhd;e9)(_69vHDHsn1^P)#aO2dydNS+T6b+JMq@j*&g=7@v%?*-9Mkt;r!-u z@<@JQ@V*mA&PN6wP6=(TlwxfSdinGqyZoOA&E1E#@BjO+`hDz=YunGAww6CTolnw# z@AUS%lg;W+&bfQ;oqk7OvStb>gRNe_Z(Hf>YbtDMDv$f;E2z)CHFNWuLJc*o(nZUb zmEHNl84+%2GjVIi`AGtWXU=~<)6ppUr!qmrYbmH_vM84 z_NR0EuLZw9df>^<_)iZwcYY2GdY}5_VgwTIwz}Wv8DFcTqrVLQ}gCYU1CB*V`74c z*F_#422ckTbPg13Hpp!ud=3h9q7irq&%l6-m6;jT2008qjR&;nk*%#UPyZe^$T=W8G;*1DFJAa?OR$yIzG=6XGMS~Z9*c^e;KOXWvc z&emn-x}s6r-h96r^I*;E+(ln&x~-0jFPi-Jl@+M9F9J4AlR3KZ`YF5R9W6@*nS;~T zWtp~1@d^hW(^$)O%*VUu$jLcNvwX{==5pjYT{D&bxK%9Y+6B|Vbp^)_Hr$!^@Nj$l zbCH?H4rqvgT|B+9_49!{7L%p#bMaV5?e{WO7kK(}g4v2?g8HSG>nx2Yonb1LIV5}d zKvBezU9Voh=9jVf@a=Z~>GQjGSNzNz2m2gnJ%~3ePXL<&repup;n8 z3tQUGDGQSX*_N4Q_fBZDZfks+^`Y?663_IK)K5=NR!)VQqV+e<<88(K>7DXM2CB2~ zO#;KY&h%NuvbsS0nuQ*?Sm;^9@RR_*(Bb^We)s+TV>_n*#{ ze5@x>J2^pw3%pB(ZQ8;*&soX08 z;`T)NJu1Ifxm>5}@7L=~`>ss+wJ9u5m4|t80AyhK#DO**$xW%Jr=2@@F2C;c?7Ta# zFD!K4x^-*OuX&cm%YIC=j(_FhyR!c6*6T?Ks}t|--EqbAdd%lHo6olu?@y_#cxHUw z#yI1`f;snPJE1|$CYqAq+|DPu_|=OS9H*~^hR2G|`?+;}t?!avpBhlI043zpH6lSl z@AG#&WPAI!KRm8-Y1zLM6O|3&3H|h)11bx)7Cbz(g~w;om!r2&z+7&y!RJf%%}uH4 zi@c{aM!H_})l9UtwUv-)ZE9o$Rl`3g9XL|`1UjLt1QKCisHA|~BdtUl8ObDYEs zeNLZwZi**=Eccu1m67m%&*#3>d{48Bk3pN04;}z#xEdif|G76dr~5lGPo8!1ee0V* zE;e|^ychB0!NKP6bulw98~`2Ca%tMS#*=D@Jo=d@=gW(WckkZ4|Kpf>kkpJTmQ`O? zd{NM4_Ffqeb7w&0;t4@6tDcD`)?mo3)kE&a2+KOu7X|o<5>-Dw}m>IAi zRAA-st}!rWU(xt<2lLM_GioAa+1OGZc~9Kv@l#XtTX=l!);}Wr)n6{UyYAfg`PAecB!1aobYJ5(qL!*6%#v7ol@FeR8bml`f}~A{oO$w zkH5{!ZCtiy>AQWqcR#b9_qW&d)I|gHx804I(c5<4y}VMl*1I~KP-@9wq&JX{NNzd4RJuej8OOHp!-@pG^$asV2WcBkiEQR$~%4B7y`_8dgTEHeIW~6;>sb9~D`c4Cb z->;?~6*W8Uz2ISdd$`NiNCW26S6gl5-->t}743`V(K*ld%&p|giqM48^HG1I7MGi9 z+bvlU^yeD0aGuRE-r%Dl-E73?pv}Db``#IBVxlE+Q7q!*gpU-j^#-+iY1 zZI`3IXr%1OP4By@es<~K4-Y?=rTXr_64|)7!-8p_Z2v2Voc6if=G^}~wRh*WIS%z_ zW@_Kb^}W>hXxY29`5uNBHh)knshuIRyDFpmV!XT^;v+%SWA#-9fEs<{Eo+G_gwlyqL$+pvVYAKoqF zIht8+bEk0zU%QCUGjBt2Pi{fJS2=fIdt6cMd%rgC#`WnH&vTq6_loDl?60~bwpeLa z;O(pVPCp%z`}Vw-4r=%jA^5H}#BCN2>qqw3H$RWb7$3E>628A%F569U?w1!ain~<>95DxE$Ce^rSi+_Wo1>Ry}x!QC)i&;vW#isN)O!&?zLa8?@5@Q zDK$e#WTW+K3-7Frm)A*Wa(;9_a9`DzeUbH=wgowk28ZpBZMhxxXJMbgQI)-4Sr6>F zXJPhY^|IM3--Z8qRj1tlX2!DWvTRNBg|?q&F~==n^qO}f%1Y;^+{FHPnLpduH~P#l z2sCOra`?%$6PcG+FU(o7ZsppUhKrYN3$wBQurN7cq4$*XzuqfY54x@KUg%$7lAD&0 zP?zp?{(#f#V-gW}1U*h4Skx4HZC2QVV=}d0W_jH|AoR_Qm$^7QB|SmYO6=Xd%}&qQ z#ImnSMEu;mqR_dRv*d8?F843SMh?ec%+8lIuWO3gyxecLUFE9~4dy3i-K$oCmOQJ= z=lu{qexQVL>WPahT-cU<)bX7y+2ho9ocFQ2V(sFJMBYxB)*fr7UmtgL1fDqYdVgWf zl#j;`xAV7en|tHHq;FAZl9Czu% z2N)QP7?`=^r`=IW|JdZ>oct|fa*UAjr?;iK%d!*xC91vmlAYf9{w(Ku=~t__ix;{( z*q@rFB^+OEb0uq|yJ@SZ%Dc5{!uP|^`b2#%4ZGjoanR~YQ7v~?gO8- zp_-L2MaFJ}$$s-Yyj$4)Ljn#SU|{e%b|7ra{`!y3)AwpGdbQ_YfGJxT-%3iMsa@k^6SJl1PAtY+d z`(}pi^4gyrf|qBD{8fU4jTEK z?&y-Ouh(O|r@(dX)L*kVFfw@QvZe95TW!(*?xq;(`dMD45@hu%G`g{a`Y4#0@ksm@dX^S4dG#CUSYz_%y8fU+au$ThM?Jh z2GBx)9etHo)kTq@?k{}JB zQ9fLT8m8_D2Dcg+7?`zNszGyU-qZDRb8=#K7Cl`NxELmPI(g^2U9aEm{eExz{kq>h zk!5dgC>Fyd7uV(9-1M|3Sg!ib#)Hl5$)J^Xpgq;c4<28&YSrcC{?Wg_9ufABsr`EO za2s#1Hn=XT)`UCef!*3)>Aw0dUF>A8JpeRI(4!&Lqb9p zgU_DlM>>UFuj}*hDEw!8c74Ix*q>7kj&L&=Y?zVme?qqJo%D`w(8P|zLf)KLpk@1g zIY$pLFmxp*JhCW#hvSvk0~sTJSe@sL^&ns^PP9w^s39kCtr5D zESP>RtX#V+c)8!s-WB?{nq(tn76Y6K42`d+#?eXh`aD zsyg+Q~R8ebY3j zg9jM6thrW3KjC)V`RM6+iOsKArk*q1Fd>IEJ?s7Pl6JK~L+JV*t+NM=dK!w-b9OFn~rABqTnBEz)eQDUtw}5Rf4Ts0>5?Gd2c^ z9c*ELKWyxl-<9uvfIUH?(ds%@6WE-;`?Fc z6W1T?Y2ksWKUF1isYoYv&c!KO*%_BU7$+}FPI#u|elf+hc3?;8v}z%N>%Au-Q;6W^x2-B{<7)W3`PUz%{dc=78kv$-e_nXwe6^&(OC@@ zLxYAOqYbn3_obd$`$EI+p?lo}eS8s1-?AtB*#(M^$&LBW_S zB|-U$je+;_lFEc@iyVA^hpVdVoRkG^k78qE2w-HJ_RY5MZKqt+!O!5Fz`&!Ueste$ z!*u^O2cQBy>5q~VK!;6%_EVu2z>x6AS~|CZYfSJs4Ky-9r7TDTE~x( z2rU*rdPP!lcM{)koBDMB_vb2GV+0va-8*n(wOrMUg~ps+A*b6xMX+dELbudy{qnqg zy(W*u1cm@5HnFAg$NOZhD?U8v6jo>YEMN2C;2duWHnxCYY}?B2?pn4?Kf-60jcauJ z$#4J8y*qtq-dpxnvaPo^?@f>1ZMym9W&O=j>AxGZTsLo7-JYCqFiR-#_Jz&I^ENEs zcq~5tK70Apf4OPdb?38f?p)s(ryL~PUj4i0(#4FkbFOFoy?6bxm3TMV`yI@HQtJX^S}k#Wkt#<^CdtH6Ca(^9D_p2eHgcKwbO zo)i(jHPPnpw=)hrXSOcwxZ2Dn7MOd!&2`xv*0p~3*^^^eDy-Hq3iA}o6rT9%we_C3 zWzV})C54a4cwaekqbmCO>t_iG3=$Dj8d;0>_sQ8-z1?~}uK29!rb^4T{8A<_R;^wq z#2Nfr#2rtuM?vAjPVdf5#zPaZtS3~J{?~t5MGqz{% zn^z{;ddC#{WF?d(_%Ow~b!6AJOY=04_rp8R+0sDuQ= zlnsr%vQ}R@)#q`nxccw!Z~59U7xz|w-=#dM`E1dzFPU3st(kE+$AE`t!57{&OP_vx z{_Xwt73Cc%ncM$< z-|u&SetuSEFsuId=73UU;f)Q65)usGo!IhXO*Y@H&Ux8sVsLwYjb*gpYIb+U!&iF> zJ=KNd4<*0qQdZWz@UCHE=l#jGYWrm0T{;VHU@d4o`QefI{-0+h{!Z$t?yT#Tu?(7Y zn8`cUm2)Ae`oGcOB3ZfRaGI%%7=uPf<4K96J&kK)cZYrYxRiZTxqO_Kw$~v$P>SIV zxZ@smBhk2zlR@On0hbL)Zi=d3R3G>I+yC8CwsMUJq-s2Hz^Jp)_TP`kfox{k*Vdez ztX^JHk}>^M7br48jkTq@36E@xPW7E+=C#jw z8XtPH=l{&}HP3FQ&*#;zeL6KfC3YS=H2-Hx&#>`x$}62?o*#E(BcH5QNpGZC{ymvE zt^O4!9xm2^w5%31%{!6Rdhp3o=jd%Y7t^Xh#~|AXX!@xgI#R932&v+onJ35S?R*%h z;v@ZL6V|SrFi|%-fd9t3AKE1OJp+uT< z@smYw&g`-ddXxwn zkz9UOX}fdOJ5}%E*}q#MHH>I(!m9R2t!HA{e*f-pLn;fcTL(f!i%)kniSY0&kl|VL z?10?!((5x9?=hBUSg?s_%?I!RxB+abtic8aUETio_5UinU%i^;!F>Ckvi;FT-*O_J zcwB9?eS2)qxp)6^d9R&$mK$_%-ObG@PgcC*y;kyn+uOhM8clEbYHDX)dz!@vZa4>Q zV=H@gWu@KnD_3=Uj5eHmd-iHlNS?;&Ihi*jzOr3k$J6~P$39@~k-cZEx~JvrU$ZWw zbNbDw`sCj9gnPTd?P|7$MoZ?7v?W=Gl`ikP<1y9t^0pOk&tB`=XVteWa@Vp&+up3> z1{eMe5)o2t&-jAfq-RKf5Bj(kD*7}hA^ZB;+qbTy7-oK&aw5>9xW=GLIaWBAp@A_g;VQrU?jH{~KFfN&{pH#9`|Ce`ZC~~E>bG?V4lwKxH#)d? z!a|=vuU7cf99^_!=8vmhYWswEK;1&*@PJ!Kpf$wcBn)j*fG10sL6RUA1Gu{cVi{~;^gi2Ydw2SF)0De@ z&i?6sw@zlO3mZY|tr!I3QU6JEL`_$}PPe*UYBh67_{&~{ zb?;xi&e*an_0xx{rG6EHizkD#2l$YxI}=Z3FmHYor?pS?b7Df{F>uU+GH%zgB`1Sl zy%LKG3BT^r=QPW?V&mco_YxL8w~CwlK;wy=vC>kG$(t6vuDSQD$-DV>uT1NeuUa29 zmMn}1?Y~?b2rf_$A7C)pFz0UCiql8d_noQ?fBnMfFVIR1_4SkUk7(#XTr7FhJMOgD2HM0+4m};K(PS8oXQ{MIZJw z*wy^$((5%DFJ7MUv^LxuWTyE3`MqrmZ?0Wgty^wVsDC5R=FINxjGwX+_@~5ztENwe z8$@PDT)9!Vv$%R0+q8vq7#R!=Ku3>7vsK`14DYE`N%MCid?#^bH zq(JF4FaPD<{%y;gy&<|g@?uAF?u+tezKdVI%U|3^|&y7TYv#XLTbJg*+R zFi+@sP?GmDt;o;36OHz`b9%v(9{bfZqP<+x!heQ;G0WB4`YXXS)z|)Jviq|wvpJ3) zc=J#C?-sM^Iu}%hx6QGf<_0Q0z!BLbIm5Ur!)=w#>rKs}r)q+i%(0lfzArg{+Pak$ zuf%u)Zl0Z$b#?#oDO$I`UAwjSQl3(g$R*)@N7&MSPjlH{75yAMFaRoMrmkw-sXX-} zo7gpl`(1i%)my*ccxbq|bzbht_SD5%*C;8_tW&7gkt1rV^4ykYAw`K0M zO8YAp@qlH22c*K3i0E^doqB(+r}?|D#-M-(xuYoX$oi1QT#_@an_-%tUOKo%QLp+E zcVpzLw57chVP&liKMyE{%$UC-veA)fe27fa%tMR zJC&u}uXXeGmaf_6_q9zfaP_%&r>nP_hesPr^S#M5e^yfVJwH2QiJ^gS>$6-p?yz86 z?>*n7L4_heci8;UH?E*U@qRU^Q1scp;&H+H?RwyjD&v%Cs7>%Ai=?u14&K_FIMF=u zL}dN)?AUdUFSRAuuHCF#U{$*Q$jPec=hkIcFJ^GfTpD~%>H2{!-E*!of)jXxgVc^uCypg2m6e|`9?BRWjbBJ#}Y&PGO%CmBOF zHSYa#$$R-6CCfy?#S`usEXotPB(u0jx^;_|ikU&G$Rz=tiz`b&dmg}g8yf5MmrUx+ zPcIBzehO4<9l0(MQ8n|2+Z1gjVf#HC;OdK^LP?v!VW!lL4-XHoKfTLC85U8hSJ$(0 zi^*7*z3~xq4V&&(qy%dJf_kF=z}ri&$5p@ex#lW0aT&P6VqjqQmSqrryip|U*_oM} zjkGo`x_aosLT7L>43f-EXlCQx^e6M&9LvuT*{#>(x?zc@OG)y}^_b$`r~bvy&&{15 z2r8Eh7#MhToS7$QT+4ka4ogyyqz$TGK~*FukweC3nVA_-idIl!VgQHuf=4`S7B1iX z`_neI;$6=U$dy|eUgc%qmYebH7o>I7(3qN%FmuC-jem=tmqC|1EQsOBdAqCB*EfE{ z43o+(JC>~r-I>DY-u-)f+jncdt9#b|{xt9HwLkMzmECm>#Y?4(`9s{-J?(EajSxL! z#oK*n>7_T@%2uyTi{8H`>uuR-wchsMR@Z+2wp_n;`|{F#R=W1T*Ic@o5k7nW=H=TT zZ!ompVFganY-|z{jXZCztPHO8Te&(~LiV7LbJUiU->Fv**r-mjy0#^7=l+ey;XuE&w_U)x>f3IGY9khJ?_ENiW zWd@!#DfhgleAqhyJQ?lqRANS^liQTj_VY5NW+b_~t-AKDPJ5ZEsM57hJZIJvL>|3r zbosW(Oz(7&qT2S%@I{ef7fyfBU2SpgX`~cGLc&ht4Ui=8^lEr~ula@+AyCI{d*jVj zPmZisSrGa*#3L8kwajhbrvhnXR2pwM*vx)@j^*bU7Z*pq zy1piIa~rR;Sbl=13J){0MlEx8X62uqe}C()TAh7Ksckka_{yy&N zmM7sef4&UZ`RSB)JCCH&+NCBNrhwgjeD8#F9Sfgad7Ye4_HWwc+4*PvXLiP~O?hBtu|27wKO--<}o`H-!{wj%$jA()MVbRTDx}Y z(#Fsw6MwAT@k>?FoQG$@A6_3xXOWeccx0IvLUuGpPTWu+D12*se*BFCpy6P{4GvGI z%=Q2eJl;HV;EuYl1f#C`J648<#-k#f*=J`MDr>#=4%#;PfKF+dzf)cMqS{n|G(5JQ3)sSREu#}LPUVq@gCG!n$&%T@Us*PFb^`=AN zk3z3X|GK+jnjOE7JhSm^Q{{9a@93b(=O!$YW-#{le_i8#am^w@Q-%f`DfrYAXc}bN z%EripTE#Cm+?UABi3oXnB5WC(nvPM*y1P=B-{i0HJbvKLLbvlL*Ibwm+MUIq(bjlU zzgoYpVohYo>R$^Vdxe}a*^vBg&bOz^Za(>Scgr@tYVW_fx_b4VeDkJ8#wnW{*T!zo z%MPA=bjiu!AgLLv1C~`(Zkk#oa%t6t8|x%nr?hPN!gEG?;vD^(@y9flyiRHB0u7wW zFdOS;-RBD4z;oGXQPOewdGD@n6xGd1xF@sOh>h*Q-U*D%o6oGgeDZ9$sFt4aecyZe z?{8jSm-5KmV&;!ci*DD&sO?)6e9)&R^60Ov&T2gBhYv6;h%hwBwz#ygcBeVlO08Mv z59EYPC!UAb0F`nx9)><^5oG4RR`^Cs;3K$Q1xkIA_qkt2O`mjSYkuqcKG7FOi&LMi zUoRibrg7I2R*8vjc=G6&C#>!e5-DyldbcnMCi~H+h6j8)FP3(a0qxuAkm?ChQ6cvR z7{E0+C^v&T1v|cBn_!!=s*^CU};pJnXLvz;fl~x4Tnr3CMunGB+!SFIGpuZYbWlM3a8MNsamyvm>#^mspz<1=$3@Q_ zaM>?cnRxW|nr9|fR&PoGRSEX{rXtLACU?M-X^Lfx8Uqpx;eF_C>~y}f#6ep+9( z=>4m6LYNtNbi$wB%3lBX6+8dFg1XnI*q`&t8}5ma10C6Q^FYX60ZFf=);q<;*ETM_ zxjN~mB&dclHTbypU^9DnW2DXBwB)l*A6+G<967+im5~q{yshl((b?{TJUWi+4Gb7G z_?d-o?s_&WJBE34#gCs)7ayxxciec-O2&?uv)s zYP>EhU23*r!P28>csl$}=PI_9rR&xz?&w;mx$UOJ zw`8f#V+Xdpt#~bE94tNKx<^T~pYkQiPIOWiCwN-yrIvX>YLo(AIE#D%ux+sN5r?oLv1eDGUHXM?gaddiI zoN3vq6*jzHNeK+DRZ^};4$Rk%>k^&m`C;Yf16wRpI6oa=@?U(xbj7O$cQ-o7MfB*- ztW0QRF@38wu@ZE`FIyN7voV|M{<|gbzwLT$|NZ71evnbEHA<`Xr)m{EU##Si=39Me z590<+3zg;j#e*`B-~6(3+qNnGDPO;9Ejrlp-O26ffnB@)m>XN|{^_!)8l2$QSg@sS zeE#oDK*;JMj7Q#H>2_IkBIQRyMcu zNExMYz%tG0-Ho=tu8Nx9Gy1b?^}0#np71fFpQamZ)!)xAJ^sUHr#Pqw2r8)#s&C4x zD0(;{@zcL|2ZJo@&!-***}%ZSbLPQE#dhLUu|@0n+}-;Y&2+&8K4e6=DY+oDF$@@Ht?ckOG;&5Jh5Ir9GWhQ)i@ zH1011&2iQ*p1{B`L9*3sL+twd)`ibj9OAJC_39-U9F|Jo_yYU zxDQe&2JB=r%eb&$*ib)e<%-spEb z^3xQXVcn#cY-ty7?JYZX#<2Ax=*&cBP>(og-=}}#+urPZd~BlmlWLIRC-yd;y?^ua z@+p1CO8gvp+pEjZoqi^w7VUqtDOUY;?o_eQ(bd2C)}Mb z%;(ge+?4$8)xokY>;~@fJC*7rFTIY7`>%0DS?BWJwV$~w(oX!jeCA8Hp#$%kr28+= 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

*pSAI0?7ET=6DEMhlE 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 W7$4YBaF2n3fx*+&&t;ucLK6UOiCL%s diff --git a/doc/qtcreator/images/qtcreator-help-filters.png b/doc/qtcreator/images/qtcreator-help-filters.png index ab60d0edd812864c4a16c7c6b634c06bceb47183..6a7128513e3d55ddf7348d7135f61a9da2c73be2 100644 GIT binary patch literal 19219 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 a{EKbIrvv1?E;BGNFnGH9xvXo-U3d6}R5(<=m6% zTKoQX$NO5l_nJwU8FvLr&UvwH@uUm79DF->E|->B;NRWeB4BFip4Oo>VH@k?V+pGp zj9gPM)L!cKad&8ZAiAm0qvyhk_YcpW-21U6DxOEn&2{2~=l5P$FNfYvMU|?YAZk?(fzE8xB?W={`2j@*a`-MTGJPZjS zih+TdK?2M;z`(!;W*9IuFoGF83~UU{V3q^}hz(-?N@G}dn|tmxmlta%L<>F-(7%28 znxg9Quw~&-6BrCYDi|ah*6}p#5NC#%(y-B-;bV8$od@&He=a|w`@iqq`R{2*Q==!< zHCaUOzI(FFy85hcF3fngdeQ_q82rGkHhDL>h*;irV7H0WRz@R zS{t9m@QIIc{qY5-;$XUuonf$0+BbVI$hjb=d^yG-!Dv_La;`~y(&ZBj5~`d+_wQ%V zmxP&PC)waq6aCSGm$$*vb4BDT`?>@7vvU#!3?KpVE0ci%suWw`V1yqm04~Hc8zgS# zW9umXYzT4&gFyx}gEI>xC~M6bSndfhwSa>dY%Ey3fsug+tTq7@BOsOp!vPQliWNw> z!joZQQU-vyLJqV57X$_18EH&Xp z`^>x^wBK=C@>kqy?i~i7Em4;h`xkA$(U-V|_dxNy&vTxhp8kIK`+cvzt`dCEV|+ep z8z^lvh;cs@Pze6~`g&w{)h_j*8*j_hC*Is>cKx@H<-6?{k5@;(bvRwy$f)r_`Cg#g zx=TWakhIjGn#aKNch25Z|JFY(S@Om>@omSaI}9vwl70t6KhK;R!O<$~$#&p1!v>fC z3A+u%CNoxC-+iwY93l}yYzHp?bxZlzbZ?Pq*_vBxPt@cJy=nXZz-=SjBR&6f-jYx| z7*-@R1aaEl{U-IndDm?NMq5J$#k+aAd~832p@G|A#inrWtgP-_<)v?3Z(8rV)x)R7 z$GGY$^Mm8!l9%p<{&!mvG%Gjei#;T^+p-v9&dz6l-tPWO>T$C-8>4?q^Y^=+4$W)_ zPOSD%NST)>-luwiVM_5g%jY464C?n2Y}$Trm)ra5#oF)3|M!=x>hC(J^}lWM-@P9- zKTS5XX)oPSwf@|d*qO2Mvm8(A<`&G~yFBdYy)Uy@q`7`i%J{k^FY;&Y>ssE){!3$` z-uk~`kXv2f)ijy!S27zY1M)abXIrq|{?*aeD?*Z{TSA37Z=GH0dTH$`%jyh8Ml z@t3Y##k1+syZgJY+D#W+7Wm$#jpf|e`VIfuTsM5aV!g6(O-0Z{Kdw-tJg3LIvtsuB zUh-&;`s-rZ*p%2^t0pO?=sHSI-~W|O{gqn%rE9gD*ZSHT%!*z)V&RVx?Tn>^!wT>R*+$xp`0(6@h&S6^NA$X;Xnvv<#V85j&0BpN0fGxY7# znzB~?et>;g;=#-6%O-HoUp;Z#q$~a5_0ENN>-Vdk+O>PjD>jEcoOh)e{(BysdZu-C z{p9LU)z5shzF+DH5IV+QQGTqhE+`?~e7@WNYm%j#-u3UexHggb^F+I4TU3@iypF6e z*ZtD|ICSfG`TX=dEk6v6v)U1els|$pmbJybt1#2B-xje zE9$3d2kEQ-X1}(7OHuCIyFm}tN|G6z{7;>l$$f$KrCw>M>S~7F?ryJgPdr^(-@T=( z)cvFt@4en%3|)(sU)tOu{kA{YIdS%ssZ(FL`gGQ_w(@I){J&SXCw%H(N7jFJ>|(v_ zkaS_s5_D8qoD7jYiCz^<$ho`X885w(A2PXDg3LRJTSe% z?SJIW&W*eH@4SjQoW477YOFNF;kGO5+`lQFJ?mp4vfu&pB z1_lWRo&z6v9M-&@_3df*)9-dH9@$2_uUbU>_Yjo4C}@7?Lac%3J?4b%wfssfCwSI; zTz}<8(#gDylVU?o*5YM>o70bv z$ybxN99i}4*W=iK?5b~_{xdUxiq6M53~&7Y-%@nAcjmSF>x;e7e~Xt|OKY&3Kije4 zU)r;_gQuP?y}3`>_9E}m#hPNfq*!EToV&O8(u*Fie>?mAR-}Z7ezJF)`A2x`8o9Hp zTK7p?B~?m2kD6UC6)wuhR940Ir||U86>h5RyUYW2dk8x`Nd%8!f&lam=Wpg9fEto6G zeBlVgA2E>565o7YhsRkg)eJd|_ovQT-+Sqe;&#E4KU@9OuYVCH)i zjy!)Wd;Q)i>=7H2j%w5dh^O;6>@tv2WZ3omMsojCH3kNqS#k`~pfWzYdYAg8J8#R> z1@CRVa}BeMU$~epJC1|#5CgbwNwDE~=x?)19<%j$PMefj_E>br*GwTqXUeY?Z3 z!v5`}Ob2E53l}GTop@>6(p?tsu1)=Mbp5KY3_m`){#1C-r~Ur$Oo-V`+-x}vVaL7% z2+RMz#XL*2;znXS?}N`f_q%UCZS!nK^1c86zTdBWKKJ{b;{IRZd+mO`Sj_(C@PT;M z0}nuJP;{8Fw7>S} z>G*Ya$zIOizkXhs_s>?2cixHJ_y4{t+x>TAf9;#S?`z*Pvda`)bQNEDJ*)fHxp>tB zk4zZuSACusfA_=W_`hG&{r^8{V&Belli>h|M8m^>N0J#9Outk8ey>Nb+^YZ8OgwM6 z7ad?&v3|p0e)~VaUa#M8=(aZ?e|P4MfaCujN{8G2o9eu-<~-xse=X)YHwu2eT)sYf z`?~s|h}!bs{m!{-N@sdKt^d$0UvttsuITew^Y`2D*S$)*${f1>YX6aKxwo&}>)IaZ zF7WctKQSJL11}^R!tMVov;X~U{{DyWm&cXe54(W9$#L28oSU0m_lAA7d_Jf6 z-LBW`Ci~m%Ec7@tyRQB!|NbwBzAZf;y)kM2F}Fv&`4!Ed7}i%D)ponau)?mZ`c%c$ z)p4Ow=U!c19eU-$ojZ4Ox8Gf6B{0chO}GBOh`piG(QBu@5|W(2Xz{9P_xpVhRy@+} z?S3WtS6gzyCdMCo^Yg-*8?Nr(|9kuT*OwTk{CkkZ;C6@M%Lnzil{H@vZ?F4XmA?Dd zqHXOq2ZW3n)MJ0Icy?>@udk;!s?=w`+j@}U%P9tnc$Ra=y0UgJSh{e>Nk+aP3etTTD{Epr4H3*An6VKPz9{l(F z?PXu{L!ak;-*a}h`TVL^D@%_v^BiMXQN7gU*OMnpeoYI%=Xq1~@818%%=djf#H}B4 zJM{0=1^RWHy#C%Vx$L`qPSL4@?D91a8rk=~&CU0Yxf6Z=SJ>CE+&_=)|0PddxZv&b zKdY{Ozp*&={`8aOvB}H}HviOjvbg`yQ?>V$>+hpNuj+Ku)hF>?nkw+#>tkHRB{qlU zdb|!(K~WhY(J=4N5$%xc-!qrb{dOvR-=>7qmrNNx>bw5yt+}*y>i)Tg45nB2|Crjs z_+lrcM@sEfeU89wVSyX>F$NUcZNF1=dTMyw&qw0>Z}g;w=wG=lzVAcp^w_eQn;6|? z3SGWx+dg{w`~T;??Im`#4;Zzlm&@N>(xy76Yp-`ExY>kL$+ST80e2s@MFmUi(|FA&br72VeiE`0BNGYE{+W@7|Se@Hos~uW;pD zN_>dCe)z|@0}Lhk3|gSXaO^Ha$p6moqV+3(#Rst|eE2$ld(qMOtA*>h*Oi*t&N64c z`QGcZ^-Xc@-yR7JRY?q!7z%r;FDu=C3>WDXup+VC{odrGMV$*Z)>*mods>b71wF zI?K>hGoX<%V0Xxb{vyFwWt!^Gu71pUjFG%f8$9S51$5Rl8WMuKoCJzf)x{SNAB?CSOtgzs~N|8)c4q>-i-sJi9983MX%8jy0DGWlj`DtZs0xC;a=7{nhI34zWJ z?J{2;Ie&Y5b**$N^8%&fkdD4zssV5RYF&%JZD4BV(8~~ZJ9KV$HG>fI0xPa7-P-GR z99n<=>Gb$@Wh;5^N;SC4Pc_|=!_bpf9R7RR{W%j~?Kk_W)nmF%g6T>9VzHX`=gZH% zY0=;9`+bsl(1I&x4Hh@4)jcnry0?Mxg)c|IRDBbk1CX>ld&NnEE0@C=cP+KN|8-rt zt|apV^J5nK(|@TS$=~|v_V!8h+aCRS$$#?Ee_jQa74>WmGKx#=9-gm#S3LRptN5?G z7BL3gxAqcy{eDXMp2xDDFZ{j=DA+q)lynLRi1IkM@6iTPEtVGtzd5q+P1yhL{q2r+ zhLu153H#dw+8+GA=eg~1`T9M4j6uz-uC8F%`d2r6`ln$70m+P?Z);ny%um#@3LnHR8b+`ROf3R@t{pI`Tb znj7B#{Ly&6{@%aUT0Di^4|$mE4liqGd(bq4t+}D!=F^Ew0t!=?FE}6mHYoi2%=0yF zwvJzSFRD2=|KH2`YMU8WioaS5^4B^x)36;o-tSn&XfXSRv}8lX2X#G#+Lv8lgO~&U z$gZ1Ob?;I>ACJfC@=20SB0c8~TdP+%D?ah$U~KYYdthqaA1;^hcl!U&hVk`_XNj!H z;|KtkQakz?SNu+nD(5+H$&lfZLV_lXhsc-8^&54cbbppFJ-GFn|AnM~r;PVc`lGMR z<6zI@AXE@vE3ko&F{oa_UA8o2(ZBGkoQ$s~GkWw{z1#Zx--CnBdHZ~HHMZ5iJg(W2 z6po5Pd@#8x@Ox6|v+{kP=Vr+=e4V`D*}w4fPFsJisK1)M^zPMf z#pi9eZ*fSS8Pf6p_r33SqE8mL#jI|t=(V6Q$*NPj*3`*vVEhp#PLAT;+~CnS7qfXcOCnAD}2%MvZo6@ z-x=J01WMXUrvDBeWzcDIJRn;CDBN@wYX+xeL#W^S{C}!%`Ix@d*G)33sorsGaetfi z-c5hfoMRc(DD#kOE3BS){mt4%9XdIB?NDl#wVzO=CG+%z_A(G|}3ir&;^ zDQ?KttE&5SG(7xoyBO2zPd8WRFRfc)2bEXzKv&X3#rZoSl@)h>I2 zUTKA?M{-8+&Re%5V2{=AO$FzBJ@>?1+Pipr$j_TAY}gK5_3;3Ddfxy_)&w+Er=Gh4!6!`gw-gp`N!JncKmo({;85r$D9C z8g|C(zfPD&vnM>0UA{>`;>#uG63q<Tb{7p_+$lXkb)go8VFsQ@|r_bH<-~Zpc z*4b)ac7AqQceTGt20LfYzWcUozW-O&+C!Y`Gw#a1%DsECTWIOJeX~NX_s;sDKJ%OV z-mvJB?Pn4mtQSh~;dOWkvb2Vs(fkKv?gpU`mTOpeJbEv>obsfq1@_xrQ%v&GkU?dq;K{ZX?@YSj*@;;+n~b9E;v?m2ljvF9aDd*#7CvXJccSASK`u!&$*_uKm1vIBx^vi+08tdHP$Hzx_VG-B{bTqniAe4&>yLiD?TnBa%llRs~1 zG|C6PnfNXKMM)8}!Nn}!>6Ie44M2T82?p?R7u$jxj4!T7&aOgqJj{>>mp<1tf(Dl! zF7`Ton4u-`b80fE8_vM6p+ZA~dBW;9Z$iJ->#k5vo$s0LKIJ)^!iQ4@T z;%>wc#O@GvVFwFC?-It2WsHB<9_6V210JB_aqvi!{vW>~`Lpju+3s9zqxjh@yC2%` z2wc;+$TVmSj^2$h)`2!OJgM>L3X79q}+ksm#uJ`!M zc$~x89M<1l6t+gb)t`f{!9{7RL_-saME3HcZ!4vQ3qPn$Dt%9${@#nmz?rexYY zsn21ET6>Mx{LY7``t?7p@BciP+;4lWzkQxW!~Nc$vdxE$;{-R0@E+Lpb^V&9b!*PY zS1&uHDE(R4YP!z?1y4|CR>BlCB&3?kVE1X_=~dMY5r5D7rRP6>_@hgJ@_KQzVzFd#G0E}4kvu&NpW9ut(N1Wkn~B#$~Fg16{seO zhEr?~p8utj{jA@b@Ej=h-1Xv7_vy#=Hp~M3jrTRaGiV6vv;RH6W$U~CmVNJ>BRaY_ z{T5D3+uVyVK#k2|b^T@L3(OZburD~m(DC;Bw{ICNzk76l_5N!-<=pG30vbF6rPU_J zf-C#KG4wD>JdkMcVrw`d4|m1AFAN48JAUdoT-;(`8RBoVKmDVQ!>Y>;Ggwb>GJ0*< z7uh7q=c1Gd>aa66FiL1MZ`kj9w^w;DUxVVW%cdHC3S^DvxzBE|S*-bsmpf6;l|z6N zG#U&VfY~9zu=Mf!jh;tpkM=I!Csd$ydFi%#A*ggj6Pv@yJojs$A=|6weY+SHCW6L@ z8yFh|%@{b>n_K8TzR?pW#Za32`_1Nl<=0aM;`h~5PVJRofSJJKV0`8MS8iiI%_Y;> z9FBenx$+BHl0R@)J%=p=OlWZq!=jfbkcxut627Sw=Y$tds1UsNQfnq?#5r;cTf&88 zhAE5ziVo-NzHOc_x;XC5-tYIku7%&RU~6uG1ZYnwe}nFW-IG3V?Ytg5m*Z{FMt{c~}S(?ZTx zrq?_#o^o7z^f{HKXQo%Ae*-AV9bj0q=0eN*_;lS@FXwqAZofU(B`y7y+w&{CVzwWi z9c{HX?Doy5gA6}Pxzo*xrcUc%lxSfLcyy2RP2j10kB%Mu!f+*uL+9U-=|@R8fL!SWO_8h6KehxXo<7@@zQ|c#J43vPas83-s_rsK2dsa56{%SXn#YGhv&c! zKjvSMgkRK}yKSF(P_)ns*PqoH3}Ft9CX zXH%GY-`H_wjp=Rwuf5GP*|uEMarh|l!&~jlPjl{cMy}`Phl*OJ{SM%mAm@}|_UF8h ze3Zeogk^gj{_unHR0HDyh6DySQ|<|uKK^?$@2Yvf+5WyG`bzA}YOBDP zuhgdBD}1jx*E;;4#_MbO4CYb{(1D%?7pYw43(U3_$Ji9Yp3l4WF0%C5xw$$!o<5J# zJ5cR)Xy@uD2f@R0%njf&L6pbAysMyw*P$-`R|3PTJ7tfz)Rnz|BDyJof#KL;2A_Xl zCod87^kKGolIh^7611PUK|FL()B$zwWWQg6MaEXUw$!sdSg5V`cH6)9Bhh(t96oTL zySdiLkb&WG9z$HkspFo`{@wQ(R4)HkS#e!ESu0QGjL8BOq09$t3LDI?cb*eW3N)=| zD7oRgsCRL}53gM&0gDvptUYBFTG~JD_VdX?b6(k`xP0=lYP5d3_WvbOSM`AKyj~Uq zeoJ%Pg|h3WT=9DUh1W6ui2)SCJT+1QZ&`NTwAgjI zK}_#-sCB)Gdq75$Lgie>>P|!3&&v%xGu{Vh`i4oLX2^5VOJ+F5)1dh8S31Ly6&22x z#Y}ysyL@a>%9_;c%X>i7snt9Byz{apo6>hYy7Ry|aG#?Y!@&v4i@EkOR%l#cRVguF zGFP(095fZWU_V>J<5j(E_nPMQ|Mabf4AX>X=8YVddKU%BQqbDQ7PZOcV-(-^dlyc0kEKjix9GV4Ec zUNdYmQeQtqn75%kzsJjCyXsA`tUvly0WAECpvvg4DZ}b%Qy70dDZL*0m0{w!b60Dw zy?eL*VW?_7KX1dv6$SUDzDlR&)ofg%YRqvX^TykLMuXB)x!Ip4T-6L%qt_jhmr%WJ z=}my?r}u{v8+o zA{?mw-ECv+o}#+@3@*2B@h$K#^X&cWwfMB-f8$);v!5@rw$%sxQxSdPm-=O;v+5Cj zm1^ZkSrKEl1w|ix=kqq$>+N{;#KiCDr?Pxm3H`nwe*^oMG3v_sUOX+wu-y0lmH(}5 z4!n0ll^fqKJg|sSgX5Lv|2-F287_!37o0o1`~B`?H;T@#yW4MDl*4QJ`{?ho_g2ey zO6~i)>Ui04o5HJN)zepb9y%Of(yw)+l~I8ugTa=8m2E*$-FXI%-d`8j`MFQJvQUnp zdiSKqW&Tbpo*%4;jd8kTDKO#3zD7kuwgZ>Cug#fKw8UdQk3*oT)_K27ONL|%TT>Wv`dCdP^vT_08@tFkFr)C(PEU|_q=yx_ zt&?F3_gXD!cq%c2@f$(d(a~)6Gnli+mW12GW3jg(w$MsJqE2>S_bmMkz zn8Vqsbw`xpMLoxan=R|(SBs|!S1;N5zWPV!lHvz9tmk)pe>rE@M?33Nw>}*SEnmj_ zZQZr|pH4Wf*nV(>>Z_7#jjX#37?=$hW^c3o;gJ4&=Ibk`PkLLw`noOR_VM-G=kLw) z;c-|S*{~?H=2OLN3yysSVhalDoVU6!v=DV}U@9~XjPNZx9_9e4W$VAGe|}{zV#e@KbgBB+{P0dgVcv$@ zvlaNR9b;tRxyB%|_TS8H=eDg-`{r`W{gmD0TYhK!^B6uo`(x9mv5loOuK!Wln}mfg zN_GdGPq1e6zInS=1muTi1BTb%!OV*4l4gs|s*1E4<#> zex`yybI-agwK|Uuu~#p39KJSrpGyC?(xz!^KHGu{)d$5(H)uO{S#Px1XZ!g#%Mr`} z+{wGWesO+!-lEGO(ZKkjWPjd?{uA3?xc#-rvY&ppYWii-fDIRUp8D%H3UjwGO0+Sq zu;7Tuu3h?Od;ac{>MvI1teN7DlOCOGyu+}@zPNgu_ABjzd&{ml$ycZSGJBc(p-c9W z*MXIG>tsF#ncH`6dBM)eF4g}!<=uBHhDFR8@xlw-YVVwDImWi&QLcFY&MWCc8`A6e z9k!*uyR)jj_3sv@<$>BK4 zcadR&heU%OuS3B;dF>rFMVod{ZD789!N>1f;Pj`f|Nmk=`L%HUrs-@4LLVNw#a&b} z)uhBSp~Pt}tK!*z0Z$kFzfh3)#NJ^(ufv)p@|TmWvL0`5-I~vN=EZ_X0t+@U3iO?Q z)P3bc!?>RfLRF?>0|u;+E``>3$Wi1*E5x9k5{Wga!Z_44r)>4qhH|#|7{duR2MsZ12XIprG)*Znfl=ar>j4i)9}1)?f#Jv# zpGN)jf93tZUcPE$f6ZrB@AE6uR|~G#ynWLQ+r=3+>MLyyXRg?yr4Bdc0D}$_^M%;1 z(5+kl<$a7wHeDSX=3x`Ka?7$AQEfLY4I)>9>|y|o4{$OYsIet{p6y@rd;Xu!$ybgg zN;T9RjNNQ|FJ5hpKih$b`8Tu|-u)K-XKrpX1E?)%V8_;AqQuE;V8XoM8pFR6?s~tU zlwNXx%BbiX;jIz^(vX-Ek{+%tTanw@}{?4K3u$9N* ztsz6ChM(5o^yQyFy_Rk`WXKS?VRD&NAFJ1@+-qiK3{fxG@3MmJXnywl{{MYlHi55# zw>s26)sFvZ1hWC;qkkXTB^oZqvMY3zoPV<0(B6N=%D9l*u8I!lG%sCbZQab^s&3j; ze=Aou_VNLSCA>c$={Tf$@2}?CYPho4?t6xuX-Z0*!Y6i6FM4r9R#Dil;H|c+=YM^F zz#yPJ?(5+d%NNXJWlK0B&h+{D3G>DAB~$7bewugjaFae~W|eZ7+W855TS}YK&;0zi zcIW@Sg1dg6cyOtd=T9j^$+;c#6-{_{8Q(7Zt^Fu=r>z1D2gs7c&)W^{J1TkF9E(0r zX1}<6c@Lw+$*B#iU5+kUG*iRL^9N8H z&bo>1LCg1hpN`l6j8tFQd$jA%zV`VMJ3e2ld2G77%zn>nJ06D29Nq(-dz7`$-Py*sa-LDcfX!fa(ZpJ?X(=vslP1w-}`wg zw?2w3f9JI=_1wXbZ>h(V7(8mt82*FITYR>Fr=ja%>9!UcPfQ@{oR-S zNH*ag!ls-|4Mh+ zT>X2CQ^M=-tk_87efp1FQ{z8IK*l*57$sIQ{;)qSA;MzOgds_-@}<`+1h>FaP|_e^WOUzkYW1b~#)BWPYPfIliCQa83D4=4XcO_v?Ot-~az_8ry+Cu08j{|9*Qr zm2pGe-B*$gKfYf$A@={l^7o5hX;vnQ3jN)-`|Y+UmW|%b2{{|eBX9qe zW4L=|TiWUm!qR^Qme1xnIq$EH`csMA=!@@u)I@(Z`*_{)*WL4}jxlRi_57^fS?U{; zw(Vq||LJW~;(4VK5<9Qws0MIOE4sb^@t(K)kI#L$|Mr4;{Pmihk2ZM8ojf)B`Td<& zUw0Vn;@PCHxpK49%Xe#UCm&y|+c8J?mFtOJ);(OS_H~-T>Lk5*g zH>4Xp7SG?lH=}w1`+?xkOn!3jW5VMqpKi;&owws*TWf2pUNr-YY)lfvooUsPQYr54 zxgV~5eERgnUm?{fCCzI)7DW8dH(#9;a^;2fiEYtJ$E_koMVU8rME^fp_T|s}Lz9-q zecms)Gx)9b$=}JVC%La#y0l~~%U0X{f6MirckY|8E&SB8^0JOv@r6#SVgln18P#q( zdujXfQme}oX2f@8U#gq?L)&m|&_C0t?@4Fh?daVu)4O-9R5O92T z$J`|!!(}1BadCvdGQ=j&l{CIXYD*pIStsX{>sgYM^&lk)7Te31-G4oMb?TuxJZNpcH zG%UUNPyW)o*2m44rag7B>fX!oY5uG$=fkJDb1_^pyMH%bGa>j@+ovbiuhKSuUjF`2 z>y*03OVc^0D$F~V^>XDW(K)H>>;1c&5ALy<`7giXvmrxrHbc%uo4fPo=II?-t^J_x z36E@OnA4m3TcDA1pQDe4hYeS(8M=}`b;WEG zsR&ZJ?fs~tYrp&+!2@mI1(w^Nh(5OZ$;x?WUxkb8J+wV&DdUuDdMQxmq-9FGVztbF2AeeA69-7-E;)vt#R z?fq`CH1heTbN4c1AFap=%~^Jx_u$%3?yjoQb7mcpPA_ScUVWD_cFMigdS*8#%?sIc zpklh9-II8!mFt@url$0>|4wUen7_(~&B2JF@6q=v>2*6EaV`CqzxV4kP&4iB-znG4 z7^XTkd|`-Ldo)z0;NRg3Cm1^7|5wH|My`2RHbJTXiGafU@}3Fu4a-|zOh{>2CU{Z! zPxi+D&zf{^xlP`f^GW;J$12Vx*WON;pxafvNnLEkB;7w-wMxC&nAbOL4DjRpmDsU- z^Xq3l&Np89AKQ8P_op=#8=t*wwijL)p!~83916P`Pc;2gkDBRpFCqK&%$pG=-e+$I zcK`5+6yBlQZTwd@W8wMpQ&-g}K8u?llKO6m?ib;;eX*X)|LAOrmwnAq_?WNb>bbve zvo7ynxPw+u&HwX6J$Bnu%f;K5 z+$?zFc;MOfnhJ*5c9-V#Y~IMYL225jVu{NQv*!MM*I>N)%$Dri*=(m>n`@U@ZC=Wx zV|6BRgZ1W!*`|#TDh=5((qH7CxUl&4(?F)FpMJzk-V=|qn^NiSO*t(dVNk_ZDgUw%WR=?jnwSEEnfvcOIZAjQGTiblWJK;r?wf~ZB;wixo zP3~Dg-{i8h{9exc66?I{{c-BKpI0AdQ;^{cxx}0>PjBMaY0JLrZ@6rj*HIuH_^sA} zA!_CP_e-uYt33So&Sb&6z@5LgUt`yZ;qbA2uRgD0QDktO#iuJBZTH{tA2OQ#xujr) z1@8(GiLAeSZX|9`Ivu*9bxnezfo9Y3pPJ{^N98Rpezr>CpZo*OwX$DX`m(P{aHmVw zA8#tV|HilBWy!Ip!8Unf|K~JUdd)h0H!|bSPmROsg`ajf3!U0rsT{ud>**s-UHevD zm*_UIP+b$5{BEM(_PY^|zBvtsQ@7oX4|tul*1ySe_3~dIe%$}{?E%-zBCdC@G$a^Q zAAMilZ{;Psd)4xu+Y$`!0<+l;Ogws!;ro);2Skroa_+O@e<~9F^zY}ig%&Hn%%6Mi z^L2BE)?|i9b3VRI+Y@|3T*8_`_Y1eu8V_4D1|k0VSfjJ{3}$PvL|Y_y`Iuv@Kvec(Y22*hR-+ih;|hHk9jDt;7N(w2mjr+uU*AL z%^5PC_gQdHxOwUQJf)h(%els%nI_sh8-vEt7rTPS(+wEljkp606QJ#QHU?$~CEY;g5BdxY3tW1*%}~?%L6~87$PtK zwq=lLaK3wV!yZqA)=cfAkv~`Kh&)h9UiK%)>f$3!qqRHjR?pe)m6~?zn%3Ub%S)bR zPX^C9Fc>UiOZXJD++X2b@k_Ph-`jk>?=Tz@zS?~{q139c%}=D5pQmB*kE!w+m+pTR zGhUa-k(y4C4XbpYD}jrzH-Azga|hQqHJBkG@hThl1d9N^jUd)4(R&rWHnM88>D z_Sr*m?`aPCQ`Zlco=cMGUt{i|6EJhaj~kmlpIf4SN~U|^t>)4V)eI#q{ZsAvg}uDX zyp6Rr-{)>kyBj*KcgE^3YAo8F;N2lS4o?LXsu;8+87#NhiXN{l@SAlxpU=E>e^p|c zW(3#mS3Vu>!Ya{we#oEp;Ao0FHSN^*niUPf+8gAmbE?) zbi1hgDNATiAh>&VfFWcatH!mzmn0a9D-K+eV-C2)Ji)rfXPI^3=g7<7*lcqSOxRYr zdYkelU-yY6IxO5GQ_C%8ho4_$HKTIVY=tM{*21sei~5H@bxQ;#LI&moP6^GD%mUii zBNm*0(Z>{jG>cV!duzGX&N|**+{(*5rt64DESPsR=U368tmv%r>vsi%>f9fh-;GXU z==gIGWCkcfHG38|?*b+CNAKKrzF1JH|LWL`N0)i}1%qr>W=vCzNof77SMe#fM|qVI z$BpyvQ(mX7{}xiWja8{0G#~<6XMVsTo$2c}MuXW`&q`JoiAq18pSxT4Gz!EWN*BErv2&E?*v4u@xcJ$?0Y#}rHjppsVKjW*B#oD^ZpZoki>8sD* zeL2cfal@8FFJc8@wlw6hRTV03@N*A2U~9zisnY!p!;J35qB;gK8T`<$E(2S_j@}_<{%~w7eR_j+5^14ra(tr5%x>y?mw9xDsJ2pboXad8o7mO#SRy|{xWAS6n%Bp5LGleb7sux+-#8vMu z2>Mx?$+mM_p4sVXEo=KCJs(Q-GVi{rJ#XEYV@aR{1&WRg8#aZoMTJk!_kE7u?$6>y9wY zC=Tn|%rG3@6)J9vAPr zyV`cf{M^KiZvPTM4l!WZ`}{#O|Gx|Ec3(g%dgaX$bgnZRID5^R_HWD8nC<4#t4z+> z-!8j-<#FuJ2Yl|UIG&rDPjmfxg@aLR#abE75F-wYLXJy~_TBZ{ECNWS4==qcSisY*@k5u75jE8{Jr z-S3;{S50I%C6T}Ytr2wOm=`?yw|?g{sii;kcfDA&_xruyD;DONZC(6BKN>zSyJ*Ykc%P|}HFfUN9_j$MDF`p>YmiPO9f6LT0;DP4K0}MO|89H9s zOMbomc}G2x=w*hMEBj}C-7jDGAGXG$fl*=>qej60-)}bi+dl&JE5URB49o^B%nN3H z^+1O~Q51~-?#$*|yHOAug7*#Gxi@ajKSuj=#i z-gPMVNi6vVstq9l;BcR};nH`nvioJXa}VeKMo1h`;Axn3wxA=bNIWq0Q8|{FfkL4P?7t2nbE>+8MapT8z zI=S}6vTzT0NHv7)&Y#^g*J07!2@GpkY^rS@ZvVI{yF5`uky? zdqJ@P-LxFBrKa>>qw)6rPg|t<>kq%lnyR+m-f3^BG1Rxs^1@F_!98Xu)U7jO!@G(D zVV9PAl?X~Oe2lpo^5gOKwOcpM{BH0`G+Tc=ci>Nb`@-D&JO_N^cm6vvyMM->zuQBt z-sYSAd+aZ_v+B9)$>_NuZL{|mDYGpQXLC6D%UyV#EhqB@|F80&7$h3f*bZF$b?#VK zEF_wuLGlWceITEc!{W!#!W@2{JRSUal}3*GEj zDFzL)6{cU2d~CG&)yeV$1`M8Uld{jx{-2)Kf4}Cp_N0*KMt4`J~t6E`Rmrn(ykdv-ftDKNKqZHt_(%mm>@- z_%}c*WN1(*c3w2F8X?Rhn}*_KNtR-_wK7bTb^9Gxc_G@$G!h^toQw! zX?}lC-RHIYvzL|spFVl=-dC;nR&2Wa^@6TML!30j+TT-G^_#gpvMXnLIZY?xgjGQ9 zlKuspp!j!CnfOobsk>t^IOrS22B@d_rD#$L|b=kgp|w7mMe8{bQZbVr-lD zCE>((`{(D@-{13d+1JTgJPi}&{=D0pb^Y@H*DHhV|Eui{Ox^wZwM2v67Y3QsJdy1- zSxH}o75;NFO3h#tU}s$I|D$;R?>kSn{tDl_E`wppqx#>s@2|@}Y<=$|-&R&;1_lE@ z7N>?y8sdh}mMjUhSDPKCA(H%f`#W(dhLwC*c^quEJosqAp+50nzq;81Zf1pchPSio z@9bOpvU3vGjH}#t8{b@sT<>~t>+BT*3(V_ZT|NH(N9e>56{{JT6jMblkGSnUjFNq zHjk@(I<@>xVf(N0q@*MUxdq!8Pbf9^e5g~_I5FveR`fhc7ybvU>p`0l8h$+v+P>?T zLV_&Ql79|;RCJ)hDz^Bhl^F}TrRw#R}app z`TSvnzlDwTziht?H*YX3F)e@o&wLr9?=SXA4D(E8XEHpoPMC9Rr`y9@x#Hiq&hGzx zL{NHN{Z6mRn~&%GKc?=tKUu4C_2g3pzwh4<`hM8ZiOs=taThpeIxxf3{_W1AN*+-X@t>p3l z-@p9$RR)cz>;07Z5<{j+IPo*^9AR!LOJtZO+3+g3%uKs0(}9tJf$ikw|BvtM|9D-# z_t&QBvR^k&xAM%bdA|JIzoVD^%{0nXcp8HK>({>YzPkVQ_4WIIy;{BXM8JB`Ru*PH ziw75+`QOIdGq5GF9Aq$g;SjvI`fsH5)ni?+>!*r^MyY|Ce+%UQOwX@<*uU;yvvRb4 z{QpK%t(D^WJ8M46{x3Mb{{Q`WbM1l*HV4is(MSI~{c9dgaOSgo)S;ZW>*X?8>#{io zhd8U>Zk@jBLTGsG(tn}G(|r8=R=v$ye`;~jsz0wZKufsY1VA;h!~Y*QgYExcTbI9b zNnA#!JEp>&&BuuU_B(lmc}sUwu~b4he^}-EV-KpYOOD2b9fqP8NNO) z_AWz6AgmK%P;q6Juk*#G_+OW%w-xDJV4kqp;I*n?Phj+W+yW;C-}3J+(>L+naJR^ zM*FC}p<&_Yv*y-p4!JisBsS0bnSQiORO|Vzt=ZaqOzZfdjnJMIj2$iCH<`!g&t`mV z%f@i*41u&c{g(a`69?_O9Pp50 z@GNr|bI9-h+j!e_L6J<=zpqvPn+~6t`K$fe@h*2JwguZHF9BeHJPG&HX@-Im0sE0*Qt_@2)Y( z?EU)h_jWniTh*Uq%kr($s`ruIFX&120*Ruwql_yY_R^ zh4=uyN4*kq=@o^n%n35R{GcZDlGs?&ztwCGSH44*c_(nTGNf)UEX!nga$}Je+ku&L zIuaQq8jhwjC<*4ff3%3+!q~B>_Du8U7xP;yHkVwvCf&3B;l8E?j2o&L`fNV#*;4#q zk8r=qF7A7^kF+n(QTIFkm+eFts1uo>!_%N~rSwU?zH`GY35GQGLkv1$%mST1Tz;gl z{dsTN5r&T5zm?A$N~TyEELg<2LW*fiVH9`m+~uVwzp$}rgVv20xUnfr{oQuRY&oN@ z6ibX|kNfo5@-dff7W_8^_1tGXwCyYs-`?W(^VON7Pfhq3xg;AVggR`P1nOHnPGvX~ zA+7j8&1C9wjYpgB{4-gwO;p47+8Tkw3Jrs(jf$Ns3IL*L~WWjqd-KFoLdw?aU{`T;v=9TYepGaF<;2YmToZ29}9 zba5ubmlJnuD)P2E9=NBGu>N7Z&8l*?2N$jiU;d}?z&ol;4m^kkI@RX@1Mh)to`-pI zZktrGHB5zWl>i;wve%5^)!oS3Q%}ve&92q?QF`7Xhck(J!qT_t>%5KKrzzYMl{c+i zd2#-PDVK$rHzYJe6CvpApf3j)mT1-APSJU%Jav9n)l|pt3@PnD*c86;d<-m{Cnv>F z1?i?AVBk4WzW?{#dZril_kZ8}?zWEoK*qoN4~)kdQl=d+W;i~7r|oM!XpgYL(1hXt zul4_b**5%JY?rBQ&UWAh;VWlCk2?$K(Hb7ySS8WU`qG^9A`&=NgY@GcX)u;$dKL&}IJ69slQ1 zJ>!@8>ho)gHcBvTW_RG%IR*;pwu68E{OJ(iVUfpuAnDf?P38}vI^#d{3;S1-x80~> zn0CktG*mFp$b4%~?&@@<#C==06&5D>?$X@Qetm_vL06D|vX)40oNLLAD>09=u2_Yw zDl>oDd*%4HS7+aU^_6`ge`UiziS}d$8DBPo4gAueL$Dn94?Hqvs0}PFEqT0w$6=5;4O*~Ta0kKmnJK!wCne)DDeQz5rk1AffHMscV`E6G> z%`_=nmpgT9yV>ux=f8RtJz7*2s(jqY(L{3h<=TZxN8j!%S{0X2cro&1r&5;h)6{dm zH=iE2d|o2>OX%*hlG-_^is$JnES?;({n*Z~i2Q9|%sv}=tv_dZZOy#GbARUEU|#Tg z-W{&^-)(tKtLE*i_RMVLdVTgOf9$=e8s#&y?ZZRbf}=O`JXhmzwPZV35&g@MFa1M) z{?GQ!NsadwOA2?lGlCYlH@HY;G6y`hUbKiY;MM-6%_Yx`UrPKhTYt80Tj;#4*{ACd zEAPDA%V>~#F2+Or)}-JQ$!1o^rYDMJO7SLEXYxC|IN%^#D?6t{Y42H~2~ir>dCDu6 ztbLTrsu`thU8G?y^DKAcl;nV4T~}9UFf^I2ESUDBICFK$PfNAgchl8l=Kk1o%D!tJ z7k}-UC;K}u_^t@>{Q2sP`L(rtcjXs;dn$jf$#`1*A_Gv33|dYp#g?#7mHT%_wf0@{ z=O;g(-Fk+P`98y$-ESLqH7i;r>|4Z`A!m`8!57Y%&fcUo1#-&>~@ieIDy1v!C z=4-^TPDb~eE91s@*J5;5EU3E5ub#5=!)5V5AuUhyx9-jm z(Y1ZG=*+LfV!!5iFW3KD5Vmq&dA0$A_ne={%Xyzh@Ek}oV>o{Ar%T;)xqnF(&q3>< zQmfxgOkS)TzbF5@aCmO!vIBoE9n)CJeSYWrS?j#4pFdn8@!HRgKlM-EX(2O)!r%25 zB#u;HwSToVQRGvk?G^sLn(RW%0+KBnJsP(yOilCMq{ z(>H1Pqc})tA5s;&URM62IJtDs$^HZ4?;oCNyT0m+<@s&XYc06XcQCF{NPll%c=Kob z@61<$hQFDEKk04#d*s^V*z3Xye~lPi=Px(W+V2zd{W3$y%ZmpXrhNKQntj@} zrk?k}oxa1<-&QCDn19~0QBt5diNSz@*_h$EO^iZZ=;4}8*G0YuX79an?(P|e7BA_l zAkoztPtS6{Unc#e`@5%B{LW3k-_@irG8;HBFIe)w*KqmVvZ%uX3WXW##igd~^>_Py zwtJ_NsIh5kzgUNiTWi3)tm5|;lJ3SV9(LQNF=hxbO$l8W>RKGe!?;SQ+_XhN;d$5W zHU?4q^+oRk3|TzvQm+aqyqEa=lg+qXm?`APLmew+wgueG0@-=%ofXU&zQ2wYKgY?Y z5Onfo>)vjTeG&c)`PTk`VmPW4xMs!=if4P5sZ@^4O%i*=HFHf5gqde0j6MakuN zpC55tX>-!{I0MfqhK#TIRSj&-4ZRCq?F`x9&f}0Gv22pSf}a%z4f0G|s?U95DEztf z;+1(OB2$}ZJLb%iUFvw?n#MUPHU}yH$Sj6U(MsGWxY!OzZjsuz=R$#hb=Is!jt9~h zmo_)d-Mk|_#)RXBjY2``qt9A@HNxarWF~xGI6L4A$DZfXr(*I23ij>&b2zf#m})M= zzZaj~?f$-AK1+&W^-}w3&pI{y9~A^O%4sL;wGBTRwZ>hNgoIjj z&E3+3S9fcYS8e9@7Un7RlVYd8%X0clX_w;)i1yY-h7=scKA8_5B*UoIN2+D`xuw#tmQN4u-ZonI*hgHEy2m z!^IN%lhZV2uw9w4WV7fyMuEI0{gtPeF@DXTP?G-FKXz$<(#a>ZZO%s zs#1|rF#qbdgB!mv=v)C%Hn$YJ2BV%YX%d56p9xt4b$mTtMk{PcRNI&};6yLx<@VvEYx~Wk0}h;K0$FHJ4i@0#?)< zThPc@@qYUKR}u_+m-aDwEZu+oR_s9rmdF2QOEK)sPP+c*@m>RlqTJOI4R4xvCx7H& zKEQBAisg;jZD}pzY5O1PIQWJ5*l|w~yrJBF=SA;SFKwF*6B$JIYUloK}f&Zyz7%(q|})we5h)E zY}9888aw=Ql0jqL&ttCYXV%W!@$;wp8QG}NztvjT=1sYr_wxGZWUJ3ey@+@$raLK-;c*JXlo$3N4lwuI|NF6h-`BP3 z^C}*7$9-9J(TG9i(j|{q`u|%c+eMlf85mxyW(=rFyuS7n!;1QyjT<<45B&T6zW$Wv z@;imcWxpT!^K<_H%Kui3pfwzUUHg?^fX3)pnHe@@@HPbfUp}wum96CS`St(oe!saK z&ivt$bNFNr6~oZ~eIO5k4(+^P@acJna^H^M?{*7+-Cz3p+SAk1wY@J~H)QCrLA3M> zcp5JKdOojuUEaU&(3|D=YfC@xuQD_=ym3`uGCvx!(3?v zYRmH+V$euk|KvyN^w?#*2VO3pzwdtC@0WX5$<6=&=Xw06Nz-|bGWcw<;-2-*$Kv@h zo8;${Ix|lDR4=@I>w-_?&!xSALE?G$Hm~!V?RR?9yOb{htL{z9o5#eK;KI`|D`3yT zC!a5_`I>B>UTZgfSE2Bt-qV*Pf1bVmH?Y|>Kl$b1P26v)|B5gC@%}mcZJj+g@6WYc zb@QPFL&MS(hOjjeA20UTeUWS4zV~hJ@8c`HYTgyk4~`C5%AU`V^wr)vx9j2+<{O)e z4y(!rzsv*eh;02b#amjRc|vSOiSAF{oCW`^*Y<)c{tL_-w(vCUS^K|R_v>|r4G~v3 zq#N|!T7eqh5)E8z4|T|I&Is}k*QW}iB> zVryL1^E@?M=cT;1E4xCce0tVezIcE7tx2cC*R8p`Ye_SsggUc;cjL|q*_#||e@wX* zaXZUb()Yk;tI2o0*4*!q>^b|=O*y(|+kwQsPbW{hu8c1Fnsqw*boQd?qtjK>H&!ux zvD^B0kLL1y3x&h>o&0J1sff$WrDoZ&!$Ns0Lm$L6|EjkWTd{WKpB+0jmvf1}+wk?l z^JSaVZA4=)T$!`|QDITn*0n;*uSL8+HQ)BO%+mLN)Rki2)%=XrsF@bo9RcDUpGJd4e>9>BIBC?|t7_eaOe(pZ^fUnKMy}u*y3>bGD=7LAQ4iRp(+Z zc{)d!&Eox2R^c;c^WDB`X|7pknAu+iujsW((6o-tY%AEfHqt!((wBF4giEIj>8^{P zG3)k@_RG2IleGAYz0S|RuCkB$;>OLn>U>^LJ>TsVNM9N+{au*ZK#T2wpibL^;w>9B z>o3Jd1x1{ld`x<+;TfJw{}N_z-fFsT-L$(!C!byw^N)%XR%c6|DbFOLp--9DXIqAa%k!_>3(oy{_@md_oA!&Y)O)w@IiLQ@#4)Nwm9a=wG8DTRjv5!;NbVqq=V6Shv4a z@#5{}H``XsyV!Y2H&Q3y8gp(R!grkrpSZfUG|ul8D_6;T{@+ZwSTJWs_Ow-ZktYQG(TM= zE2^>6Y3tF+)2h5)tLm?KAJ%wM{A5M&tmPg&4k-eQ3>M`)zH()cWUk58RX=X7{^H_fzV?q^Xr`AHo!4x$W;;-2=3RG!9pv4KzxMxl)a|?T|4RSbR~MZ5Yu{$a|DLvek89}11I+xO zvj)#ghhe2enNyy}NJPrY8Zm~I>yH?DsaR1Uj>4r<` zu{Rms%nR@Rp8fd3|2qt4wto`)yS0z8W1G(Dqx)ZMfAYcjrQ6r53?Y?PN9)U3uYO}= zTz+2QZ$Bdg&w*8;s{;SqzOU?G`S14IZL4nDNoJ)KoL8>b;$bSA{kHdJTGCJLb4*WM zjy~DUAlYbJbfWiO#L6v)n588fq>e@%+WSg^;V$!n@3U%|@|JfQKku*1x-Ih5mf_es zn-mUa13yKFZQE9hGKI*52OrnxID1W1(Lr=oY}8B#-zs4yk!{*V+v3_8TJtg&3oKw` zTX5w4i@%R9#Oa%8RL|$BohM%G`gP8%P43(-e2eEG`0m{8&^M_c-b|XVa`3~t%=+2p44eH_B*iW)sthdbp3RuSq3>x7w(lf#?W(6 zAtAkHxwKrc8OIGVm2W6`-QvvOPO_YJ!k zC(K*9L~3pHtrUR*Ugm(h_Pcfr$qff%R^4}IQ!wHQ_T;!wV9DNnLx*`*^E8!_Un#z0@2{ z^{>rZ9-3W}EV9AUYQdrO^Ex@_%oc<$V_aJ`-O1m5&c&<$dN@>Bt}$*{!!?VCnZf%! zLr>GM{5;TTnFGI5!>dDGPRbnK6^^nU|Bo{q2r^^P+VlKQ@%d7>zj8Gn4l;*w+!8_*vXY(G$2GuNvNuu@kzi*!Biv=yqSyE`o(88C@knrdBzv+n&4H-5p z;cb|8`}wBRdeXbV>vEb+85kHE7#mdYFn{>--2VTU%l`Inw_Lu`owyRVe&_%L1889n z=)AmB)jvNyU8TLCzWC4gLaBiK#DsiV!*Zz$%RaOIT-qCGw4BjYTvB7UUr5C5ZqS5w zgpJM5CzJR8II6#c-(U*=?F(#->rEm|L$stCBK}5mKRw0Wc=U3!mv_0T(59kH(73HD z+nlRYn&&C*ezNO3?_tow5efczb-!MM1`qGBOEB2~ed&Mod9Di2ffoS@49jk_J_=pm zmfhu-Klj$Umdq7f7OIDC)C$^n(<-dSppLPzZ0A|sTu8^5`|`{Z-P?ZIi}#;efAg8_dPy7W*b6Cg76J2}a<4FY z-+bw1+|r$Uc9-Sk8*8r_4|mrV>fz#*lIcX zWpXsm?3Du@v2~zg!6Ku&pQq!C=j;C!*ITnW@GyQV$<;s3kWzVywS2*ri3SWOb+tlo zKYIG*1j7^Qqv?*XmNI%&>^)d0d0eWepYg@XNry_s4+Q<3T>MJ>?o{&~+Oh_yRh#&I^R;Dkba#iIexn}zfAQ@22OIKB zYxx)4%9yz7LUhQJ{$DYjujH8nY&dS@ZZl7N*zp>@C%LaTg$2D6G+}sj%-*TQGWG}f@_ib0!@!VU>KIPjN$1Yv7>dDQ`*Z31b-MATt*?JzX zS_bOH=~*=Gdpzx#XT-uSmzZZuHbfm|d-h&midkW*@#1#z_@E&Fg?Tr*IOpChOY^vs z?)b_|GqwIkV*B1T6Ylq|%wZ_0zJDw1^q+%%QHhsrKQGIeak<*ZR^eIyl9-sBZC6iB zHPx4z&9n01e8+pQPV`PYw?zNQG)1S?OIEfxl_!@UEVZ&yKlLCkV$$YYQ`MYSn@)W` zXLixLm2bkPgjm%0_uRSWY@VOfV~4P-FElt9MebSF|kKAnZ zo!@)Yecgh*h4zy#@y}R3YiZe+w)0okKdG6i?Qy!$Zr8)&lj0F|tK9`m)qY&x|8J|5 z&;pwS!3@5EpZ~7jF#poQr+>{EZmTVxo}T+YZYBR+29M7lF5J7bIHYtc!=)Y44KJ?W zx+Zdxf7{ht>3cRZnaycl`loPV-;^y=n(B8s1U_3>?D#b0w1cjlmK4M1D@hq%3#5wI z6&9HW{o8eD>a3z`Yg*3*)@h&8iYf6g`mA)1>+wSN)a-vL+P0>lckWCnWnTVlOE*_t z+NQT*SA1R+XG{zFb0@q0iBqZeZ)47y1ABrwP4j>F{Pp_9AJpflwQKId{_T~G*Vb-( zWtVq1k)bxpflVRs)yLN-y&sEjRK2k+^Xf0-?a{F;ouLoUifKkcKNR5N4Tz6`aCWC=~mylb$=5hM_fXg-uI1t#S;V$SV%Rv z9FLds{BeUJWz}C>t6Rt4>UEgC62E0O+iC8KRNpSAaFx4iG}6y+-^aXrU3 zmWfL==-CyymTK?ct2jCN-3GfWW!6<&)1x9zK6>{3jX)xg!(DEZHQpCOKxa7_u_o(-^@-|%UO_6zc>bchWEgL3@+F5>L7h`5HSf=P;xs1`^*zajy z7&sm`&y{QFxe*c~SJ1<#FwxD3WkuwRj^%}O=KuFnbWmNDazWAIVAhfFTUuF{uO8a= z#7kSc;g`^=Ga{yax}0`5wfxU!{F-lU#iYU+V-%zK=ftZPhR}Z}re0qg$T4AG&G$J6 zSNxrnF104*=KX*dcEU_78&2>X(8}j&$Ygk9$Z#^yuTC~#ii_~lmzR877$$lww&bud z$v7{!XEuA3IPbs7pQ_mo%$<28KZZx-sho6H-&FTFug^zMG&`PU@;b(FBsHc-g`7N~kgzfE!2cIq^XFe+HR6y+=wMr*S$FvVglmi% zbJ(_IEb>&|a(6!8{@D&c3uV=$ceK>V-p`rHQeM3;p{elkQBmnG;|XpRQUR6=b{z_7 zF8bFL@UEoFTRY^={F4_YAMRYEpmuv+bzsj_4`UG@=BzVKk~7#$B6#zeL=Dq_P7Qm( zDB!)$U_~&;@lEeLCF0^Tc^qDx46DleT-1IlCh+9FCuaY6W`6qcU{j_;cFhy5tGXZ3 zh5j_mbiKX%GuQR1We>f=A~?>>7rCl?_1~Wp;ug~`H!$fWGB0T7y)yGyx&fO)*#B!u zTRu4@eEhQD(xup5(4@zWv+p%yotAuBEBSYC>!nrq_d2fozxByAsn^Yn9PK6!x?IP3 zc$P5*+t@NN@Emv)#Tl`(rdU)feU{W-sdXzkloh2j7UeCFa$ef&)LnPfv)XC;gWT`e zzppL)ZorUi%H}Z7Om^0b{}1okez6BN(+VXUEVxv|S3sIIng_wnnjN!3*GQ#b+M4sZ zKsd6Z(jOet>%4uEKYn`-KW#2zl{Ll@+{lgrQ~CTz2KH>1TG= zR_{)>f4Ab_zu?)K;a!Y}8K#&2M%W{DSE5tb zbnXwv9aqhmdV82Z|DIr*l={}FTEWh=ilIuJ33T<+;(Ug8y^-5G3V05b==_RlRsYIx zf^ES9_JqS(-to6)@?MM#i+b7k>GdX_uU)27t1M(zc=9*cS1icncX-I^b<^mx0`J{v zc^sh8CQ$QNqMljdHAeSRtMzq1qkvT$TQWnC`}Ci?E^G!ZqX4g1?!Lfq;_SC$53WS~ z>)Om<8EE*^#_XStxgSdZu4?Vqg#rs6s9G?(rfHm0y?4dI)`+2qV}fmSaQe2phWsM) zrC<(-n8UW90M;H@xaFA@!^ecntnR$!cP`n~YQjf#uYNj_d7q(0?_eDJffu|V*l$H$ z{&SnFu2jMK;L%;p4QI8D(#m=5OurX`CaS>;=#OSGEUB!R7MA>Bk$>ca%R+NM3WL^D zgC?;jxEVyg{p;#HL3)N&cAgT?fkj3PpFf|O$q5RP0}K=RbR{nLFiJQwU&wj+;6qpP z#X~74yIADUdZm>nK~`vcsPG)9_|Cw>>#*ei@@G{KLAM`4cMAz*9h!f6HDmVIwI;uA zg=L?LP`D9cWFh`!nU%P)#O%wxZf4Q1)7Sn#*=MN!!nFe>QPmYFYScLxQIB{h+YW%%UJ3hYJi6lOnIY zK4~2s@j7RwRr%ENvW7J$q$L}wmV>vI=vXletgg>q7*naZp`t1v^W{1>HV3`jH9;?g zlwRKXc#x^VeP^?bx*i#t@Nqrgwdn#2D&uF}o^-$W@b#OQWZeY(`fdpZ{PN{- zcp;L;B47tjHnAV~+ZNxPU7z3o&9(YpeEr_%`|p1DnR4r)0p5tu1;nbT<$t3w0TLliv8`HoZqH*@b#>fCVCXrEnPg;NdpEL9R|9fD3^hZ*5^XASkuQqSKeDG2eY6+ohe?b+cfDjJ6 zd;n5Fyqwzb7^#HV9HzO=W&an>gA6Sx#TqOc_v5TtGy-bG*%m~t@L%Z*4&(}(7d!A>?r%+A*IB%Dc9&muvK)`F zp0AC;_4~Ufyx1z}89&WY&ur&6oAeuMKiM4iuq5ujsXpOU$>A0e{oha11y<*>NJ+9k z`>t4hGvx8Vzx=En#r^1%sFJj_M#q?v`rjB z{_nQ?eWpF{&gbLxkMsVYzC7zxi* z9}&E={cz)~FAP7L*=K!Y5Q$3&bl7iFa(lm`M8h*%hT!0PI+UQ2SMz(d{=0oYp;WM@`uM!PvcfWQEN{#hq??12e`-Spt3KcO zvH6aLqWPs7qld6Q)9bC*+MODjraxd2nYqwndPOkv*AomU6dk_t_|3gpcHAbQCaX@I zcQXU;DF%Te&_e8MYz}9CJ~sKk|NGm(mh;^6w;$(!caFJk-q(7a;!VE$^7;>+VG7v- z9c(%l5LGPOP_f}<)8aPkyv%u1M7*?ZH_T*Q5t@?_RD&qv@OcIW0uDc5k~|p1DltL*|Fg-FmX15|Y9D2E(8Gx4-Mm z`276je&54?&G%h;s}b;;ndd&kgtlpGzWrOIc!JkwuBo{otPp+Y3f6Ji% z+Tl9Cmq*9UU%+>SVM5j3Ei>=WZw8M?fEuf*4Cm}EyZ+VR+jsiPg!p=Wwg#6&p#47w zen>Vn2`pg#-fwj06Qd=wq62KN(0PU*%?+i${wja7_@i1~lO1->KnQZkE@)ve19L$4 z+4Z-TQyA+09Wb8zb^n}&5hpZ!<)J@rtWsn&y;d*3ju z$YMw`&D5Qut_o_$dsinQ4T%ab7^}Si~->UY8zK@%-@bbs@4@UmlV7IxQ zWYF-d*m{BU!-wTTjsF{i=RbU3`}pGCoPYXe43~53&xUUfy&a#REwrgo?G>AsNysgY zEic07)EJj=-YctZpX+*rZ*3OCt&2kY%FLarr)Aba+#1E^Q26p?)2aOrZL8zHsGt9^ zxM7NF#I@`cW&!twPq<8jCL8}lD&B<3K*ihjm3WG`wUPP(?p?b+hBNWSI(05An)Z8b z3PY6imHoTUEZOqsz{_p&yQi|N={_p00o8O221RTM{kGHoKFvI@5g~XcjceYs zDF`0iwqUsnhX=VhZY7YV(gDoB#9}=gy1L+Ec?S5|o((7Due#YA3=ZvWG=|!HFIA#-MT~ z6tsG2^1ZxXPw1grpw@~>1p9%HY|l0@CTpzS$>(6RrTk#vVcG2_{%^RJPL;cHhT)1< z*;bpPTjmT4y*FHEG^k=uyY()K`)dWK6z>lD ze~N9z+wND*Uw*8c_au^~UhTl&;|x598TM4Y-ut~a@$_m#&?dnJ;b(kxqi?@@%739I zJNH|wk!ko=uF%cbR=YjrUOjc^Y3UW8XREI*;y%LM-WK%p|DXK(dK=h7xvRb$N_`%0 zVZN(gVRzJY`F-F1#ZLWfV^I39bM5ipAD^cP)<-$X&we%kq+{Ku-@m@U3t9R6`HSGC z?vL^-MSKFD#`kKZTX@I$-Q8`a!d!4cQ-1$@?(ccEzG|QL7rd{XZ}W3OpgF@elLhw< z9k^$e^v+~~?{n@?-qO28cCaMFihsiEhAM_x|NO%KbjW(#cxZum*-S2-jKjK-x_f^B|ecui)O=tMEYT}&Z_x{G8GqCfnHDUN`&CZq} zQfC@eD_We5c)Ld$m3G>GW$!hZ(-y z1Fg_p>MNEFU7>lhe9p(aqP0_9rM>n!NdN15^6P3w3#Ulxb~mp3hrVs!{?Tu53~180 zRXtpEe{SdgwS`BYeUa?tDKb41yywUFxH<33>UQlFQ`!Gfvqb&K+kK1%=Mw&?q?Rk6 zd_TuzUGnN3U%hNL910fR6td!BOkirr9RH0w!V4W&bw4P#|CIAoc#g!vH8cNwNDZ{w zSh_!xK}mJ5&dt)Fr9U&}_vfwMZK##_D)79ki{)ga$A7HlI?7Ymcb^m5e#d^+T#ekL z=0$4luV)?6T-Px9_#4I*b&K?P8a`}X`NKW-<7D|?-X?ZGf9-fMJ>bRr*mVgf!(Lk- z`;)Y>njz}acK5Z$)9$}wtB>d1SIJ~|MDX0yS7ufF9S_FyzC66EEKBPO^8=a4&8cZm zcpUy%c}BJ$!?|>O>5t)eZ@uyM zdm6cW+n%?YzZBmbW0;C zONH%ATRt<#C*@aOUAm#*U{&YL}mvWn5gdbzgPD0fv-Tl}q;G?{+S`zV_?q@AEU} zxkd{CzYDEXv>B@6gEM%N8FXXHJE3Nr|n)bV>-&^Lf$5XykyZ)csx@{F= z&)45ub!n54U|iWTt?j@5=fA(ZPsRFG_4zu+;*Aq_&Cc_Tm~r~xg$oH$4I9q5HoVN* z(A(>J`34ie)jAWV#OB_ma^|51AoByPnLD%5h>n;|Fnhi1)tU6DI;o^6a)G&tGo zwj$*B4nc;;91XLhf9YS8^d{A|?k_vaApLi})1ENF)QnTpE?u>M?Hl#=W$X@t>F+nPKZvUIT;j^`rE5km zSIL$Qiw)m09XRt#`ri9D;{P7qSpV<2`Ie)9T<*jkV=~Q&?ib7wX7Js0Ciqj>#gf^} zA8b(F<9_}!M?+9~m*`td7L7-zZ0lE4*L?1_@7$Z6SvcYB+23C`WbdteI3=x?JCtwL zM*h$9oz{~Y+>+feAo!{ShF?97-CWU4H*KXx#`2VGIe(VH> z0u_sA_33YGO65dSG#4*ezHE)$viz4t4~{gxyk=wV$8*piH9za%f&F_YzlwCZRGxa_ z?yi09b5dtc;bz#%?X@dLc*V+{0*Y_1*IkuwO#Hd<@6`V>mOn%UOQxLvrOY6v&hX}r zcc8?L^0W5O0{=|nQ+JEmE$~;aWPi=-_;Xi<@+Mb2JmkCcQg!0%oncWolf|dSpR&J{ zeS1~H^NT7q-$Qzh=1*Shc{)ucZqc8k`>($$a@^)4uT(xo>6KUU--jXdA8!3MdFO<4 zv-=botn9aLOWVGsz@O=WJEP>Q{4yq$>ei!6cJsgA$a5p$VTRtGw5yr_>=Ye#pFcYJ zqhkG2-yKeE;!Gyk6+_7r#ZJzbeDOoB!tgvgBrK z)Fk-~O@=9E{Hr$Vf0q06*|g-(@0v%gf|sp#XVo{ez1?OZ!{o4rA*Gt(k8?~}31h&h7_0es; zDD(f*RW6JHS#Gl#GVba8{U{O3aO1+0*=OS~Dx0k`Tbm%lc;V|x(b;$J9qKzK;g^5z zcmDr3`uYFYr?DPrVP5LI`8|^Z|IU}n3|X(@_vgejMsPA-`02d&KGTA&3v#|?FfAzW ztrlj`wU6%>VEF5v!}_1?>(U?RWp4;9=(A-w#pSTYHlb0`L2|upF~7s)<+BUK_pEJU zC~&?anP^|b->~V!rD%p7{Hc$oi+@^YIzK8-wwhs@7}Jux)u*PV&c2>!e$Ur5{Oj#^ zhgvOyHvf8iubkf@T_J7K#_NlU6Q9-UD>@ua+rq{0{asl9$;E+A4S$5H{2-?0!zk$j|3B&ovmvzok8M(+3dCYtqh{OC$NZgew-O| zs*mlJKEtCIYV+mZdR}mD=#pn-N?@Gba8&2()?el6FQ?~!J^iaGx^8bKv*G8b*PpL* z-Cw`{}kU~Inhy7^5T8{%a5jQ;cocG{KV}Z%bVHvO@3~f zp%r~Yjv-cjO1ap!ts9~lW~{7T%y{MVzq7gtYriv`xVy30jPdr*-&W0M-tgUism>6S zcK)&Uzqg;h2s6xEbNx8uQ|a#NT&8>NwhT|#A79{m;FkIR6^C}$-FvLN=ib(PIa{Zh zF$Ub(e0%$`dmGIU*X?WTtIt%qyMBw07wh!abL;NhUvMeDcj0U1*A+Z3syG_1RWk_X zDs1QNSi9wu9K-Id%5)iu;^81KUnrnI)6C8-m0iRWlsPI*>9eZkxbe z<^^ZZs(T9ug|qC+=RUve_9pAXx4zZOge(3hy=UAZnY;4Twt%A>=RTC#!~HJC?x*^$ znO{1uZFtJ3BRO;BnaL$?-@AG8Vt4;gf7?+M6+bCb=H>R#IK~|Xiv6*=CdzA-QvY0> zf8A;EaZ9!>Q;g~EX$;jmD_JCx%AzZEgPa4Y_7-r%1&wEWG_1YZ^!g!3u_A< z=JZ>BkhqZJx3{cl@yxvUVhn}4Rc#&9uis|VnYvy5|Bq=$PNf_$Tu|j|JLCKV(S~#D z-TU+FUaALLvu*jD&@e68VY1feG;yZ8-HHy^uN?Mlzj7n{Rqc!O*JbusUWq@vu6g3R zEL)?UHGD7Z{_|>;?J3C%+7!27-m_h5;*D#Cp6%h>p|;gWG?}B}aGl_d3W?v(<~AxW zTww3BqF<2t*scou2kL?ip)5=Zaf}UbXS;GUUAVLEIw@OT(!f%(c0ik$VLx~_wvqQvlti+ zrZa4KW4}uyd_Tt-IsR3#cTL6RukKwtb?UBwz;AEgoLm2+@7}z{%S8?ffHgQU@Q5?a z4z6?#E4s5}Kd<@DR=J_*B*|YXgPu=;$=H9UBaKP$D-%1lRHax$#8FS?t*ye3O`)5G?^ zK_!}-E@{F-f^Q*1L5<taQ{ zGmJrNR~TN1G0dK(w*2$iTU-r#3{hbWW=^7_s=db7J8Sopid~t%+lZ%FJF|SI!}-lj z6Y}L=$U00F@0{ZHJRo7UCc~MfHgC|K8~xM9+Y83ld5b*FrViXIDBSE3hq zNA7iegcNvpSndQZ5n*a!xZ%#Iuxtl2t6Asr?c4M+Cf{>n&=k zkdN0Q3+xyTPUODMv^lxaCJU`Bd3!Uo+r)S7kF)!xM=(Y(GAcxDQ$Awqdrs|)D5HSy z-fqs)liQS^>BfotWoIpTdnmJcncD9F9>!0+g0TT}r(N>aW|$gaSv%{8JUAnWg0o`5 z@vplkHvHZ9TbCgy?Tuxvw}ihUi^d7YKr`O+AHQyGyK}?br;l4)?}ubn^s3`>45kVz zB(^TG@~NJ>CVBxVe>1&55FZ^oEB$roeCP)1Le<%`?F89d9mh%vL4u~(Gnlcm|-8i z{K0+S&Eeb(*JZx)e}4CwtKp|}!!L7b1_lOj0g!XnxxtF1VUy4WNv12^p5b@uPfz?; zwSL2cU&WjaE%(i}xs>u98J66$@^=6ocP+rc!N3!J+xNg-rUU6KlWU90mWp`-#zq>$oBg+CgW+~x! zMLNEZyyQ$(`~`)MH3@s6 zi@tUrc=K_=t*f!c9|P~+z9qXaau-LA_3i`Oc5602f1&C6EL8LIO%cWhkev(y4DDeI zIet%hBRTcIY=7ug6*bW#x2wvIG2qiSF5_Rekwq)HBX`L^d?K{bQG7yg@i7f122dn2 zC@}CXL@$2cEzpfKP1Ss}WS@X}%kB>CqS?Ft%ssgI?6mIHT&R5wJOz;LKF)}jBFMH7 zTL85z_!cKwvVGnA%97cE6N z7(i2)3=IqxORzQXPM&Um&ln&U$M$A{M>ixy#-ik$5YzKt)S! zPV(gWMUz|Z{5TSKFN*t|Dg)b&vuUrr6&;T1scbY)s!^N1X>p^KIpcN_%~l3Q21sqe z#K36qLaxC@`a~{slJ?p?><9AR-u1lkq3o5e^6swf=bAoqHaO-*`#<*Vdm6Y~;6AfL z7_-{tFPmCl$Td`)&-0$RY^Cu2o8N`B86Z`k0>iVtph~tl{(bA))4ePcs-d29U^t`B zu%UKyhU0?&NB0&Ah_`|K!2k-sHw?Ed1-BplVh_qH3=E*~Xj25svM?|)95#TPkRXAG z%IAg)ZXP{Qb!VpqTgko8O-1>ycO`~fAKd)?-(88Rt6zo8x1DoHgikT|uJnfEQ4qg6 zFsxaLQI&RH*}HZ+!vytr+c}ooId2h{4Yd<0>7Or%u&IaP#+*~qnARZq zx5P-SShq5|b#ZCcycLsIFAh5Rl&j&%s!iA7q55C~H-ogi(24DpGks(8!&*LWe8G21 z>EPBUMM3c$(n^U(M0fhe{yX>JW*T>_p2(Nb87}f0u7q5lx$sR{_OzoPGA{o-<$Hj0 zHQyvPm#-myn^xC2dq3fLvi%zu@3rmO=MqDcZ_Qm{dv^JRE0g$-w*8OLm-XOm1c#Ua z1A8okg`Ift?akA+KXY`P#>y3zb?Q~(uW9kSwmbR!OnFsVHYZ~8=`dI)(=y=RIi6k7 z*S}BLtTVZan_=#e{1lgZqwdTqPll2*-SUY1bsbCkI>NeIf(tbcEr`6@2ye`k3Nw_Y zSuHL^u4q$xP%Bzg#Tb|p?y@qpJ-sfv z{(k6LsKpHo2R1ZL-}+V~TucG1s)50Q0hHW99Hb0^BHVD*lFekdL_|M#c;Dgs&QpH= zdTTiKc*839-`nL^8Gm0Od&YVvEamI?GemrokDanQo+YiH{pz}Rv%33V-Mi+^;Bvis zE7x+?tKEXoxyDRC#jWBdc^Cc*FBj9N$>LD^qyZeuVV7*#ZP6X!or_{(ZGY@ z#_L$-pJw`-SH3>mm24*#s}ZfTV_Lu8tJ4|IDm^>qZCiQzzNF3VoQ0=boAz-{e!)C# z)+;OHDR=YEZjzA8wTj=*X|b1K$2XZ*pK5sy`d#)cW6jS#ZNA(yLkyY;8CV?r86R|H z`sALEx;KlRHIhkd$1=^;?JuKuy}8G=@a^Q6eJO_(H$L0C_TH7I#`@|9k z7kl6N+$Nt_+6*qgQqrP>_KM~UO<-EE_i2_O%Yjpz4WJ{c|39w(Bi)uL(U$0K_E}wm z@q!w|o0y_wvRg$NVi~rqVaRFG(h`zMUnl&#;~ZZ5@VxqM#V_W@lR9&k=Ae`}iH^3r}9E-C@nwR%Ey%P&(<&A-RSc zo9{{tPLW@o4~A*5y!ik3|37u81DqOu<%8RXnscW8TlMf6s5i{&!Sd~eqPgA1>D#Y0 z6>~N)=GmUNGfm-d_@K}3!joyqvSRDgeY-S@I3c}`!v;Kz29InRI?X2BW=pB*esHiX z`@Nsji|xVrlEtBWO2y{*Gw>8ud)>EO%fXO(;Ate^~ZGky1f~1Uhn_m zU%lqztH0G*KjpfUCE5}>7+4(cCp&EJZrogbX2DyL)Dv>f(*Rm=f;vvoUUnVEnLzgP-fowU6)h>pp%}{Piq8 zMDCBjqIad<{+Z|cH~rnLG1FBkG%s{f{nz|?Ipxw(5=`?~UHeyjn&Xzjwi>v(cuzd*jSREIAtXbgX04@y*xRq&y2|*2IQPx$~>7 z)9u-%r8f@tJvzzcdPRr_lt3C7G6Wg=ejdH@ZOvTUbInaU@jcBxUkqx!r{9g9TED+U z;bfl2n#_#V=35gU+`s4f^$kb%dU)j{!uUXO)fD2kR>e_O0HL^f}V3b>jEC(ihI>R%n0m4!eHo zhuqPx^OC@Ux4@erC(3Tdv6c*NhFuI9Gt=&IgoZpZIv1n7bz&#^X?ZOB;8a6$9y0f7aKdEQJ5uKciLdQh+CK1Jw%bD~6>B12mq zli%~Uqu@eeIfH7T;lmY@f;SeoBRBQFK6-v-PBnu_`&&hammNnH9gc2Nx_txWdPgRO zhZiC_E<6xz*z0%o`%RXb{dcBXKjU)vxMjZI&Q0Gxdm4hX>30T|?+hxp9P*?mIBGVr z-~PM!*R*SMrx{2ejZQ!KljVTI_T^vZUe2v%D7)0L^2^RGoED)jPkj#*l{-$${Q^qu z9E=lKHl3ck=9OH-tcm5qk8IyFz9{C&sNa56VqV?zIp1FDtG9q6grlJ_pJ^SZlDbC{ zN5j#z3|E%N9ZN6qTDc(L`3r@)(>gyKT+YxM)bwcg1nGzS*GJc0FWULhwo9Fx!&clG zUZQN6dXqUol}%{QUFHRXkB&IMUUp*}^Y7@o-haL#tLC$_el3!Yv#YHCD93Q|N8QoI zu`ChN~hBpmYH(%0Oc^ki>hyfQ126E`UlKP(cT>jK`Tl=bOZZH%SlP$Zh35Uqv?!LUr_(<-YnPe)*hPblOU8wEojl%UBCvBeh??2PUP5Pg+(M z^!%laq&<_ONS4)1pUDwxZ2q@>uk;jTc*J~nj#^^urbR)?NsIxNvwg3d`eau!Jy5s* zd2;{1`~SN@6~T>3Xa8`zF>K*tIQ}gutNNPX(dUki(>5GyRJHoQx#jBK(4YK@FPoCu zj?7};UIiNL*{fVpb~d;gJkgOJ_`b_0h^3)@{ZX5WZ!uCc4_wK$ZY>H3WBBxEp?=u& zC)Er^saGvLkH)==5oYk6*DTI$vX0@$_WIxT;JAw3q{v{!(lD3*T$A$_qzXJw3atV^ zwY`NobE4VA9F1O|EwSO!T`3DT{c*IO`i-IEYJ=>?`s-D};jWL)-apB8V9C?fO`tlR z;lL{f#szH*se8)K*fRLe%R3bNVVe-s0p7rLiN6Yr3;KN$|3ps>TFwyg>XUqi#YfM4 z9%%DLfr0OZ+Jlm!sFw2G#R*#=Lq1#+INn@z&Z|k%&tJ>>T!?}Bj$2IS2{{H^77y8( z788~kvuM?aW2gy!I?G|#p~Y@rkIZg3d}7VBeYxNs5rY6j^&WPGi)=;~E^NIV zayi?-y;Etav;I2GFb$q%TNi)4{f%M9A^s}4c;2+loI6TWmR#ui_RQ_@yyx?O^q!u+ zrJ7;VQl7~Mv-8X+E!Z%BhXj+#XPGrG>%mquFg#Fu(DFfcOZ0rc3$Bb3&<bB94}T({%G;%-?ZxJ^#b*lX}@=$O*nJx zO8bPgaP~D1(_29LK;6RzrQiK}r>^QVZ9d+d6<&T;m7yg6%}3cMk-Iq;R_xD@{}#VP zDuIqpK17CU#t2>wO#2 z_*P)J7Q}Glbpp5vJ44=@_s@+GHdfK+Q+4moxibA|+sWj@qdCFT_e+*+5DcfpL55_%a%rUEKV9%N{nWzZH%b=$NT>C zBqfF;?7J*|5A8~EjY?j%X>(?s`R3nDknn3@h%jb+a3jtq_x!DuKWdI$7rJJ#!R2|q zlEsow@=ljnkMeYy^5=bBCdTup+Wo_uS;F5>E!bUJ%Wrww$WxF(ZlBoa2mf*x`h^t2=L~*1GC9c4JoIC`)>1#l1y`QhUnqDq`QD5WhL~yX+;3%e z)E)rG#{&m0hW2=|9|_I;CKfHT8!n&BbbO-&>)UBMfcthIJNNE^cI~7KpDI=}d=XG6 zO?lKX|D3>rKe47P8qtg&e5YnJz2x#=`O0VEMkdGzRhV4)-O}sYaUZ+FzcGAgI0CQl zl$+RZuiXpn?e#={gbszi)vSG9a$Ale_=n^9$Fr3`Tf4h)t~JxFaxOJ4l4XXp$8h^k$@>A*A4k?S9%T=Y-85!Q2z&}2+l-^}~u_MS6Ib#F{Q zfSRZwbHcafi;sYHRnjSow{^5e4hV0fV% zEb%{V=@m_eDZBo#OZnAYlAg@faQaihLNz@O@DM8l%Yk3HOn&Oik22~{`?m_xiWE^m zZ$ ze-#w5Qje2ovNr!c|E2!~;R9W=%(G&7=G;}DCdX`*zohzI?p~)qPcP1XeuE8CTre;t*s?UF z{=ewD^OtMFw~Bzbuh#9fSoiL2!`qLp3zvF0<>J@64C`WTi=PPQKi^(v?QOHW^yitEuWda)FF5mAY-i!e z6UyT2c{M(qY2CGaliuWtXNP*{9X-6DbJ?yhOH@NeW6!>hH)UXGc*@mqUdG}D(}B3h zQlLS`qknS3_I%yAl7}m(r0Kzq$-jQx5a3i^HzW7eC-cYWFxThIN;R}G+omol{8#P4 zlsox;pS9~^=Lx(Cxh{9>a&UeEM}uVo=j*HKNosdby6`tJ1iXHA{80J&IenW>8m=ih z`ttNf;mQ9${k#lHnF*{3uHg(aFMA*vj-55qNylOxY;zwd-rM_4U!(f6 z^>(HSCg(SOc)hRnRZ@qVpVrTZM$y}s878Ip^j=H9Y*Wk9!cZV-^^1>zfq~Ir62pei zmm^)ekVo!YQAh4i@t)GX{5h)Pe2Q2ZYrYEah3U$>%3_l_8aUjON__usXaD1p63)?l zh-dGdHvaQRHOr){L_VpkTC90#Id9g3-m`BqzVvoqmDzJPM{6tpQ2~Yb%d_In?bI&2 zXOwYn?a%Ax$A0Xu$i2?paEZg@<;71rxf8vehnP@@krIp|~tT8r^W#1B3*iP=o8dRLeAL5|^nm`JL~ zQ$cTSYnOit4AZn27G0Rqb+oHuUdrL@&dco;q6dRNpDAL`6=2Ak7$kk^Wx?FU>&73i zubX#&S0dBL*eCt!ceq6umR0Wid)4{Yo*EVxi_7aG4qiA8njU0I_zA9=kF7XyL-b(t z+iUmcwp_?xe(#Fr=QnZ2@WJ?GNn&qqGm zOuG0@fZ?dw7f!}c(gn8S`|AP={_bRHxblWj)-{LDBp5I|wkXKpt zZNCNEm9_jk80J~c7Ge0s(Xnc>omMS70|ThVl_0^C!0(ZC_HpjAM-r!OY;2=#CzN+p z+8b>?@!(L=p)K3jn15Tp-Eqn4;|+Gx3#wjUe(pK5%7Sf6FayiUg>fv`wgj+ocXBK} z#F4U``Dy#QL;n~V9w=}$u-daJ1(4?RT*8FeI8!pIQ9yE_zvU_>rx9xXsOGTDW+h5iB$!|w(&bx^(i}-5Y zK_xar!hP0;#7}~$+nF5Bz2E)ZWVY|$$M0LVu9#+|+VZ2xE6Tb?%;Wa};Rc?%o8^8}-J9 z^W!&!p1tO;E<2rzf7b8$>y#dw^Lo22?p^G^{PxAxea{Z9f0<)7i6LSJ++eYtOb>*k z!x%PQ`B%-+#?4TzovUzPbnTp!PX{iXIljzD!{Z{S6NAsI>RjeTQS-ZIr9Z8k(`UQp zA4MDXzBDK6hwn$VgwN~WcL@9a{ClK%*7H53R_D80Dzt7Ne3Dwca&y`G&)=>s-4qS# zT!AN@w|F%O?2Es{ERg=$(dn!j!~FU`q7291BD&bKkCg=TU*2AFbFb*4d+NdGH$Ofy z>(e%H7aO#mVxC@kI&3ZB67Ghs2=?<=qgOG!$cZyPH+iPaPq}lml{zO}E{WZfBz(*z zNB2Z@6MTwg>t2pC=NQu&RiuKiz?(Kx3ZJzd{r2G+Z2aubf;&dsdUK+S=I@lfvS)6E zaM|?FdpdkQr-@wRSd?~n>z6xMh2Xwf^WFCVmX&N-@4Ih2oK<0GJDx&&$h924Yz#V39=X7KHEg7O?+?qX`TPzq zytgPOCKr5uR59D`T=^A&xoKb3>R!%X+nRY)(ZQPC?h`w>nE{@L&e+SYaFOlSwu?_7 z3#}Bt++Mj|=ZqUlm!O-W;~d{CXNDurip~vP=Qb-T9y*@p7x&Bd;O)&X%T#nv&2Hdi zbb`9HS({-?afLS8rO?fz*>_#f<-a}EE@7_st>98yc6e%aifCl-?r^`| zyZ#)mdvtT{>2$yN`fbGr^zURyhC&w=fY&c=V3<&|Md|+Z^>^Mxmz6Lku%5h{o|M0@ z6;!D^Fnl>CTYjhT_q>hgk2h?S{infneClO`?*eW6>ShP5R{s2WlQQH^J)a3M zh-$9a&TZ)}$hf~YJEX|%EMMoV6CIDvExZ>W{cTtM>FtqaYcB|a9LtmRfBzTn{a>C; z_P5*1KI75*`v1SDYclAdjtLw!D$Reb%CK$w;@>^r^%$Ogn{bD}z{C8j62r89Wy7|0 z3@#yCr!!12zVFBRB*x}bT64`6o41=EII}vKsLFG5-j)dV(rDZ^CsKavM9pV{e|wKD zU!@^?HOL#>I$%-vpLa+3clnQl{B;JWtQ@*wU8B4r*{LeKtDme<&0k$$=I8${$J%b^ z7TIfhVa^Oay9GcKr9D~OAI3grCeSZvf_On6@p z?P8f}bNz%4RY=Rl+}Etu+y8VsbgpgYQjBTkXCX<|xAK^_C6}(N@y)+{me=0p;jO!8 zGmC!b*GU$vnNst1Wqn}j4~MDWI&NKkH(fs}Pd<)?fhpk!SHs-N-~Q~I&ft;0@^;0Z zE7Gw{3S0{{bFA}38Mf)GRw_5wcUf`^fB4JlaPR&S?tL8+XObXZh-Q$nt-5mY`}aN1 zZQsx3UiN^AwIR9DaI0-LXPTTy%Ffs`3SSLsy`!16zfLjicUdo#ed@+5UtNhG+slJ& ztAE{|>sbE!mt4`b)F4NOEp{P4XHQ(SH}cz@GZ(U1|85S*a5L~xcm02J;lE3{al3E* zoy3pFn3bC9M&LHwQeN%vp?sGX7hn4$nSr`oMK~=om z&25~wJ~AB$`1$>8YbzIn_5C@l?U0FrNX8o$qJ~#2HakUo-?QT0<`cL*MdDdlUO=AW zj-N|*uhF|TS(Trpr(g zXZ=jBLCxR%pWv2ebJD~-EjHyb|G%V*-dx5_NSUa|O2tIcwW`Kz)l zrB0nV!sPHi-^A|Gg{$YLF)%PNJy^iWP#Mi|ghYk?7;l~I$P_A?+&+B^ zXnmTz^V|2=ia!S1erGsR&9fJpEh9r&&xBjLr zSjEo)S`HV3x$7KPoT%NSYti|tGi2tg_;-vKtd?Gh zd$F(IYu334Mh8$S%)rsW3@NR>iVU~yfBvP|n}G==0qQtzNR5&yDBY0-X|8}qZ7fvE z{EkHE)-%=BXCp*GBS0WMpdlUj`byA>P)LuNZzIExkNx#~Zh&Vqzh-%34dstYovQV_s$;CI{MDZAe9`~8cfVV=~2qb~?k2dwuVW z-54MviUmJd4)E7~XkPxE=kbzYhA$TxbeR&0wbrlk@@xCJ{o%6mKwp$r&+AIRzPCS) z+`0Jrx*o{YAlJ*NF%}$`Etjz_dlUP<>UxgZZSLRZNALfAS1xUNQIo;Sv_X&IP3Zc@ zn%R&Qqk)hq2i727{&o7ZY^TSE-oEnmJD`nTEfr&$kN z-~X@F`B&|>dFQG({deNPvO1vX%N}dEt5!33n6dwVr2j8T^U?pg?`zWQU%kID`S12T z!~y|aqc~q5Jr6l=%kWW-`TdfW>t3lr=OG%Ll^LRz{eP--plQqTIp7{vp0q%8rYiro z=<0GIr~PxQPIs(-w084@8m5E^w}XG3ds)U9(7%v_Yn6M-G0@5Y9eMNe`Ae1CbJs91 zB!sdw%=~BG`0wrUe>0k!zr`|SJpbSjWC*G^A# zY9vi>Fa7@ErS!_L+VbsNx>oV-d!rX0$-uyr@TRy??9^{T&_eDAzP=+bbQz?AUazQE z*fHtQwKG>Y1%1!q%sxD6eQa-M&Jy-NYsyRx$LrgU^;J zr#`=V%jwpMy!mF)u}j2w6r+z@ocQ*_TM5*ci(m&YEZ;DTX~Dxyldk`Iu5xKv+wo$E|$J&le&a`_%!4Gu*M2j*+9scsOTE0uz_webQt1kQc z_jW$2_hMRbIQ`Y~hhLT!o(T7T^g{{M2$RWR6hIy;dtd3ebGzxLlOfg?Tkk7+N7k8c z48QuRj+rmdi9vzEh*3aP(514GX~D9WH_ucp6Mj_{`uD>evE^4DZuVu!c)UQ*=*ADF zZH(aYvRI5|N#)><-4)sOYz1I2u)!+H%D zE8oMjPO3=VvogHqx^LZs%e=Ez=+)GCNpIV(=X#xg`CQ%j)pzV>a4>ABU@Um}%JuD= zbC(Pk2yX0)+^R8&^#hMRTgV*$s5}Q@*T+A~GnXoD_!)F&?;DT&`5z4z6e@o%)Cf6f z2Cm!>a4;O_PR^>n7Ie-=Plj8N!7QO z9oFzA_?s966dj^mS03qFS$1f@Ynt-mWs|48GoRnxp1-Xmdi%km@6*mrV{!PMpu})s z(Z(mgw}m;2>oUDu#|cV6Z@L+Ne0Y35=l|pB_IvD^5{g&lhF=Y1C}F&?iD^Tj)}u9r zX{{%w?I{(@nYktJBxEth!aY*l;o6&aX~!jIWNxd>xKU~KcfOAJld5Gea|FWYmh#H` zurN3<^spN<+NZ6k?RZ<+XHf^rtp}MN z;B7As26LCWDdEaTs$3t=S-K-`FQZ?rsg%#(hAR_6MYjM$w)yw^v@eoXm5fjD)kE0f7 zCy;ff?E&zdl|JKwP?MQ&MYetDdU$r4LQ2dunH5&W{}PW{H(&KV@N|y#Wl7kIT}FfD z3@al4J>H*qvi9hwY`=V?AEFJ*JoFgWq-|K5Gw&$}L+_!Y9Z!BqZ)btDE?5p2g)vDCQBK23E*> zOCH+Qo>t8ju!ZBo8U~l$OrJXb-;icvI1K9HGB89KGH#G)Im!qw=Rx69kigmy!}vkE z8(ac|L=GH`V~luW%di%*$o=Efx62dxdc)$+?_IU_vDvkVt@8wSb<`d7e#$1F!l3w2>1WH2KHcgIS@nCGH59rQG9SJc(m}lXe4dfoPu~Ma3$4vRMf@yt z3k+&KmcGts@}hrLSD&w!4|7uxWl+@9*ex6tVKYF<- z)LG7K)jcTPSvPs>`kQ?Z4=Xav+xg+dOy%CW`~Kz3srwi;<>$?{rz;md`f#Xs;n@xI z*4s^9a&J%FzY|Zj&3~6Y`E%`^4DV~58T}49wNVw1lgvOzr3f&r7Gj$65t`3EbD{Y> zR`5ghUFHk*Yi2#qn6$6nJa)C(t-7Xv#RwaBt^|C`a z`cnMn4_#vO_sJNifu}gQ1sVF3)aN}f-I~BCV7)TPD)aBw)m?i)r}HpGtn@t)*;4+X z_|pQ~l_DC(2!(bK}yZ*W#+Vrk_8GuZ!noI`E3!Uhv+9q=TDd+io?_ zu)e z-crc&CxvN2>K!*(?a;Mf-!D^n_p$iCz=E{$_uq1M>4rFN;z@nEVY1vL zd#*6s@&YI0hW$(qoI6jlI=C7hF4?zm!|w1e0t+6THN5!h{)Rmht}VUzB5Lvq;m=vF zC%N3x|E07Z+@HhsEh}Z7Mpe`|0Tu^C|2uP&w(StNoBb>En@ky~hEiZK$aylm`TA$E zbe4w2N7HWI*m&ueq9{WV|He5P{fmO%lvM9359^*S&SToOI#Ao|MUE1~m9~>S^9tJM zeal#~jdMrj){Ku2SRE|=ugonni)C1``S;#-a9f0ffk*n`t}S!7a{o|dIU#sw_HM)Z z>&*U1rDZB#DSxU`dv?R-lkeLWa#Hy1cK281DA=Xo-Gw zmA%`;;?RGW^=S?>D+6fc0y_GykbIz1tAjaN=Ij24DGdS)CwcY?Wh(zEUt^}iTVTyA zwJC1R3I&E;($frH25|&zXYep}xan-kvf{zc8M*q3pk6Pi$H((n;=-Rd^@Thu7C+FN zwB(!`t3#Dcz&3XCIhrEx3wU2zh3_i}onsfWW`z#JDPHZI`ET!g)bcx&T$=by@g~cf zr=B*`H;J+|czj>2(cA{}_2C^HKJ!*-&S!1sbNp81WXm^c;_^FB+QXl1C{Ih>{HD_N zs4c_OwoYb~sgIj~nQSWHnoxCX<_Yt$V6-t+`d9?cYF$2($Ex2lt(PB(^?8#(ns=s;0 z{IgvQc4ku#>K^?)PbYHD74Zvg9fF1YdBM~7vzKqXSyUYYS@>{ZHf-U8&b3sdvyUr3 z&2H#^T$cA_{Mo0RM@e!|O@2b=FcW_F83So{0Q9*{jMMt-M zU9+^JvY=bF%rN-M^M$&xW%;c)zMQ;LeA8m%vu^NG_%hH^_{XylOX0g%9d7UFwGK+^YH6a8@JnIuk;OSR^`duIAs)vB$7)WQx7Z{{;>h_=~$fiG7rTAV?5^DXJ+ zN_`UPVn;TfhL`k{il?h@js{hRL1n&Q-tCA=Hqo)ZrS|Md=wj6^YtJkaxBmNWBBV-f zV2H><>hx}fEs1A6_`a0i;s3@{)3cumGwcifwP8w2SFmZX+MBD~-$4FlU|`&kHM`-m zXUxX4S1!eWg=}`pQD&}b{jhjf{kTrsAiZYyF~iq!4Dr_PWyTDTiNbceomF! zgY$2$*#_?gUt3)9$hguAlvsS1WoDe+Alk6Ttu(?*(cvcN^1FK#SU|(&4DCS-pnGIq zR|yxKeZqItaYFJft-jk9>{Vusp6qWY1c2-51_p`Af9wD0+kGm|uXy_JRD&feLs>x% z&!%~DS&-#!3``1#JB8Kv{q5iXzxV&Q5AOEA_gTlcF&wxS!m#4^LWsK^7*a0(Ki)5I z&UE1BwflAz?|e$YTx7nhbq%wy#(lHlL5(_uq7R+{Pyz3h>qxXs)hd z=9}}Z4I59}*S!e0|9LJo3wbJUA16b4{GWg7@9K`PeCon-wvs2~wq)OPC%3n8H+DLm zd7SKU{Z!QP+&LR>&3UI1vHS5ih_fuNFdewDeOvwe;Ar`(qpRchy|~&ikLkds8!wEa zK+BHKEG^r4HHOLI`?j(-@v_@D9)FdPyVsRLCd{Vz;Y4G1xt$fdUNvQ}i{{~0Km>}xI6j_eNii?^$F4ho zuVeFIX_#wvZpA{g$!j4kO5@mz7odY{7!6A8PzIm0MDGu7N-H?ToEX+@Vp#E`@a$CH zujVE9xf||k7wQBYUM0*{v-mrggV$W`ZF5_wJ-hAl%-;)ytymg57ICV**ga#z_S1Zx785$GyTTZfob*{8=GmWo@YOk;+c{>! zwpP&jmcO_g_SZanc>mYo_^OvDAGfX7k7E#FI>lVOAig;dFqlMW*LPpEewhbVKEFhdiS?oxLxt8EI z@8aC?Z1IE>UuCvW6P{+ka-dGhr+xQ@>9ekUyUlWE$?4p!MzQzQ1#&m?UfGj$`&USn zY}ez*^(y-7`@eJYl`<}P-fza(EmykLp!5W&BeG^cgMoPC-*fY8K0KMLZ(H~0N8MfK z2HB8q=E(*u2eh~vIXL<@ZV--PoA??C#SI^+<)U z9Y=%x-`W44p4lC@d(I5VU?#W}IlLE-2Z*;_P?wQ>RXgRmNRVdVmff4_VAvwN(UbC{kXrI0lei^ z=+mqG!@m0SFFl+6{PAK?=XZ{uzn1+IInW?4SRZ=?g9Yz~{a5z;GThKkhOD5T584E1 zHr3Jb=PogxdU-ZRlod>x{;KuV+`}DUha5;0 zV$g01VX*in7JPeinU)jo{&}_p%4ev;W;W51-xClnk!61RA&T zDuY{=3>*!$A`E45mfdm}VMAGht5$F%&DrVq=JDFi3Ff8O=C$vfDm^9o#hPa^J`>uf zPF5&YvkhmM^Jm5KE9O-#(ym3Wzg@UC|46D-kJas*?($5|4ct&*5McN%!vycm&P;;# zX6L$?iDZ76WHzIiqv3(eUj;T!2K#e&U!6Yc`;*^w4`}cT6c#K8q_`PsCq%SQ%~wAjE9addV= z_N3#Hle>2WW^-1jSgMOaM~ws+Zg54&WVJ$Ut$NUwbEXCBw_jxh#Wc8o;rJ|ufFiYfD!pR)vHOaGKjo~QD|daJ8LxNTtG6aw=iJ{_xAEh(d$-&eV!r2B z{=9PYQ;iC=S7Q&^#hY>6@9-RZyE@6;$;Y=n*>R>I$G(lhLdQaA@pcA|l5I+7`*z;j zAz_hM;n!4lsHY+{K&$KS6UVbF+ZZDG?tb`jVP256YRYWqrMX*|GbL}|8^4fo+GX{> zy<#S-cyg6F!IJ|Hr~WOLj)U$;x*A)&G4Af|s(CLh(;nYE)XiWa!ldA`t)gvJ@YSLV zekbmWGKEYLHY=8zz2x%`r_V0)gsxu8et-Fv3X6x?88M&iHGje-75;*z(CauGtl#ZO zp2~XQSxDU5DRcZD=O3P$5)u<<&6KEH8Qtn!{cG-3;XIbdJo2E~As$ABMUgD8&$2em z7M~tysLD9u`4yIiOb3&#?>~PLWKevg&dIKIRZjTVw`*#WDTh~;2tF4+lNR7E1S;gX z#TeR<8_^803^xu;g%86o><10Qe-zU8j!^%~y78UYttaauD<#+NU0Am5W|3+br1#Z; zwCsF$mbs+xU$ultul$d~yFaIDD>KMMA{NQENf}4g9=cr=_C1WFX}*swXu9&zZNzltwcC)w33U8T2t$i4 z&%{L?yYrWN^uJ1~n?Ld2mC7YGX0ODKWwAIjtXa*_adO>)H=M!wf(%FJEN*A8Rp0ii zYs2rNw_OYwudgo#LM!ba=wg^k4x;gTN*s*7e?1x<)5fNT>2UC@%kU z?YYE-IHm&|%OrE-SM1%vzF=+qKbfGXKNjqG+Vo;II2$yuaxoa+oX^dWJiY$Uh4pox z=AOR7@YMIf%PqB1*A~rVn&NV_CAh&Qpg5_P=lU z&-*=d`u>~}N%-o828IYx#t&bY%NIS1tAn@TA?wt@Vy%@|MvPH?8*#h_P^iv{_gg>Ww$$p)xTx)qp#^_ zX?U0WHb?&#J7hD*g9ls<`u__)y`FDjU0qal-ZuZ|4|ThLNA>GI-m8AUx8&udpVw{b z|2&qje;s}Q*WUNF@6XIMJ}n5HFbL}1&%3=q`z;60jwiXId>$73kVh-RsGsT)(t@7V$@9t$KYXplrA4X{L%dqWi(Esn^#zugkvK zH(|zOM@T?fTwprT^3VRyk9PliKQHCieV*-azT@k)=)api?aSWWNczrT@l6umermBu zTL*1Fo!TF7l~GYPC*t!P_{kwRFTQ{rk)xO%srFTfVWXNSYlFv}GdGMOyC)7fiZQ(Z z{~|iR_SMt0rvEFK&-=9G{u+iK>6;}Vr0Q4S+#$}a&UD~i^w~$D$a^&}!46xv;koAO z^TfQTY){Ws{yMi!_3Vw8+iyxiVkqG(>w)O^)?Z85G#PB%t}sL)jV!?qTlm`ZMqZ1d z1G?h!!2<3E{lD__Z9cENJ}YB>bl%RRe}0$Oe=lFf@Z%wWeZ}mfO{@)ex%!8q@a#2v zef0dwpWhfXxR$@l6k}

g-DU^!6#XZ`%2AC})M{cT-oO3`_*902T1FkNcbF5(_d$1SA`Q9QE`2{oPK_a}HJLqinQ61Yf~f)w z`L7QB;%-RSvnhJ!k-U7pz4Y?;8{QpuV2A?j^`Uj2dVUN@v z%vw^kOSO$5qL^_*_0tlUYq~%8{qp%-^Y6>k8K-9dnSOqL+#H6C?DM}k8!7}=P4SDW zfBWjxcX3dS{Q2O73Q*6XVbAT;HZyGZ`P+OvV*CA0GE-yS-|O{vby#P#+y9(wZ+PB~ zbI;$m`Ttk%|D}C-%3pENataF$CWpmKMCaP>-x|%`u=cgMsywJ=)%rTTiD5&{-SY+J zHQ^i#(-(eIP&@i{=ZA0KL~KGrZEWqOV@JEozKU>pulkK0>jCeec`NX=Z@RRY&JNr zcGPCZl*eM+wyYe74KhI+1XoM%StYt!nE^DbkvDyb+58jc?`PH9?lzVA_-JdaKEtA! zb>4B0zhqe1D}8tK(9qeu*ml}NvnhL5ovWN6b=a`_>faY0TcMw|AY?g% zMqgV5qsG&Xj|I3nb)#2)+_!mCLcc#dDEzt)$Qs7POz7wPB(Xh+g`sWhdWJt<&GBNO z9grMr<}+MK4i{n!C_HX3H-E>=ccQi|8WqJNn}3=6JYQZa`lHah`chTsOvRNo?|Ecp zPhOf__KlZOh&f2ESAn6c@=@ueq-}M*@BhC9HHaS^U|?)WoXhk;SFD_SPUeTS?q*$v zGc_9)&;Hu%cI5E^Q9-%OKF`A^pXy&SJ85gi{G#ebKO_$}FD`A~b#^90#@P$ECeCqQ zF8pMd(j_xS^V8zGiywj}JdT_@ee;*;zW>Xa!HrDN!kuez3@;ST&)@UeQMC2r^#C{N zs(so&^UluL9Qn4bitE%p?Nv+m+H#99#LCVLXUIr&m0c{z+3?A)(}Ur~O*Sruq&l!k z4#y1_g*!HX|h6@T~2I>Yo7u4D7B9D`w|8 zALx00YTB>+1x5}Z?zT+S-V^!beMIhyi}SV#EZEE0@UHL3%i>lBSE&UyQcndIG(At+ zwzq|Wk%57UfiYk+>i)=>;O}K8SQ~b1$T_nuQI_e!<@x`5|8%^jzT6CCkm`JQU84?LGJH<;{81d=FHMG0c_i{G}azsb09?ns~0sB;Ny3^Ntj2 zMz8#+xc67Y?pvS`YdEY58pX_7b>QFZ&YyppbPKn><%rq*B=`PV6CKH3Rqlqs4r``_ z4_pq57ClVqo1aUDu(PDb76m;tZd|p=X}|vgTQB zo+TRbUO-_zqs(u64Nz~2!GS?0jqw3T5@frxjfTdv1=~PpAZMc$pWDJ{=!mTqo((1uozR#N~MQ?1dWthJ$;;AjThIL@z5da?m zxhDX5Bjy6wMoibPJF^mJMDKLmsVcLglvN?$LBM8HsP)HtukY02ACn^d) zKKHQVpAUn`J41~fbAQC{d8PKCQPIKcrjw`yG@KO}e$BaXUc{)(gQelHK6lNAgX}Ee z7UF?dkJs&fS5?{^zBQ?m=|LGUw)B4X{%qRE)WiEZ)r|S}=j{KR_cnsU zg5g>!>w@QR?oDE8$h;u`=b(IE>@VZY_&@jmJ>gyMf4}g!EVmHD{!9FA{r|Wk^nU3C zHd!Kz-|XLv;I8|ci3~4<@9$P&Eco=q^Yi=XcHe(4&16t#xOa(FpWz=sa+?N%bcEA9(L>`KUml<7gfe_;ghL@9>bpq(4w4ncZL;G5SPfj5p8f`miV@xznWnQ+mD%( z-Q&L+b6;oZWSFoRGy^N6#W*1wa(Y?82G)j@{e6Gm_cIizH|~3w-v56&_wl;dx$gh( z#{Q~nxSU_33|ff^jsk`o-3$dRHxlmqF&1ev*#BQ8y!pP>w|F_5Z`@Ju2=9Tfu=;iCpnLx`U++EI{4$mvI zu7B2~Ar!+1>g&F_uIZrpyZ);8nUxEU_sf5;ZsPs@|EKx>n@f6jusbaM$|(<863DlK zApm4-eS+oQCr_`hlUi2yah4WCUQEwZNB!sGc}J2GCa{Bhgsq$YZ{PPx%=ydNI)-|^ z2`9^beUZNF%BVb#DP`C9XL>Vi+Kj)RtOTFc@ctMq60?)Vi9sgv- z{Fo(d6aL9g{Hx3m7SFIpP=|q|A@z|*&pOE}`cIVbdgYy<14?;J{~YWs&aq76 zWI5o(>LAY}3Ql$w9uXZ31#jwao%&aM?&8h;!VKl$49mb^)T7V9v(Wx;*L1(fvHRO5 z>NmZB%$+hY-0)|du=)RXy}5s3A`xv25rW_JSr1&CI3fJwt?P3SZBU)@|5WWWegX6#VeBOHe-}?J@SvUUQ zuX}Xk?)n@4-})J#oyiCdo{M|m@B962;=6bI84S{YN>BU4y}s@wznsOc{l)+1GCkO) z*Q3hdxAz|}|G(e$|Ig;veg1v_|3CA6KhOHx{aE1HcrFQSf5P3wXZzGApS=~PoWJ|eu}JLrbn@}`x7NS&1sU4z+uvmkW#$oOXnP(1YqP!ap8w|W_W$4a z`(E+?zw(A&4=yeB&VcR!Ut`L1@$cRHe`Eb+d)a36|EgQYy;_gqUCz3%u@{cUC37}J z=kGOL_*=g#G011$UTy~C@A)_WOW*(U+3u)K{pEGcQ@ZBd-Lqw@=uPo+{|^auKHGVA zt-aO%Z>pi?=YQJYx@B{H&!5)M@flTrTl?>AUhZ~^=i1w6mc|=S%X+dfNbrBR`*kI_ z|K4c}28L_$_WwTi^G{+h2)XPdDSav9-`whV*8flMt7A%7dLf>{W7qq8vaSp}cK%nn zxRzOGddK(g+rC#-S6BRY-~XUFVL%J7@T7<_2fWp4zbf)ccv&p1Is_d>G%+TGRSx z``*+e?e&S%?2dkT%*L@WRDdD<+#E*+9T$cfJO2N^_j#Vm#Uo6$@2l@SGt78d?|7E= z_xrM|;S5K#d6viRHtdX(3t$ZR&-&s|?!K(ar{t>_{oI`P@7&fcKKrCkt?_wW&67R# zX{S0{@4qJdHCaBpqf+*VC+-MOe&Kt#+H`SN&5Ky&vPt}ls(xMx_7-Lc)voGK{I7O$ z&dKy`3-bMT#(vyz|Mv^w-~YJXd;F>|r=FYoBQ&x%^>1L=mYQ{D`m6ix`xxKfk7rD{ zVXw`=9m8nw`R_}v1McVQA4}hV;k!7wC`Tj5G&}G9-4$tP7fUSMeqA#XW@*_8fPhdQl-wS3)>GAA&etcG6=svmH zl1!!r*%Q~5{)i6y@M%u>>u!am%vT)$yf{$Bx_4{C+q1oGGS+(08`Gy7YY83S?R_j}>RQfPjoHsbHiy31 zFW{-qeQHSy3BjKjDE}V2b6{oL3=xFRGU=oyqVbW0C-amA-yP=Zc9J+g>iy zuWMDAXr8@?H({bS!#n*&bK->biy0TRFsRFkd1zhQ|Co2D|IHAgsy%yL|E&Awepv3A z;QOgZ?Snid_lrj!DLA=5s#Gdhslxx?hW^9%6d8_OFJH;z@TY@!)`hd}u{9I?Yk!{h z7Gjutw(rQ&AD%vSQPqFjBx~>d_Tl_-viVK8*S$~E;%9UJOqBi6`tncjSwrTv2I+UC zi~j#SU;l5jR9E z@Ag~$e?FQ2Tf%?Mqva1jDP`E%K3#U=oVYH7Q`hrrM|Yi?{IT{M!<2ca6&>=+AE|V< zC9y6@T^2Bz@zwnFyFc%x9=P!GQOB{P^_q`c|Ed0~%vO&%dH<2lx3rT?3;vh8{muyU zU?^$p6?JY{~cjQ~$5nR+s3tf8+E|#k=+?I<#GuPRnOG@ILj&-~0b-i~sEH{$Kg?bo{&%dOrbpx&Z2WJ`PM>TyXQg8Rhwl1o>@|et5Y1{qA^Ax)ebKZ)Y z_wQEBmGBk!^-q0U@Ayx8_kH$V?lT(ZxBOl2%`xHOm-)Z0Ea%zzo`=!sW>_S{lQ;5= zAHL{rzw_ulgW36NL5AcF^-mYf&RU<#vGAjHlD_JmpWIb@d^d-h-<>i0_~8|dHb&7m zW@o?7{l>yw8?-_@cT&WK6H@mtlssJJ%23i1_wK# zaPXzge}AHHC#h=@ER=W0Ytz0VUmo)Y9^e;1CZoGZJTFR=| zF~E#*I?I8iTX(E|Tz>A%5M($S(JfdlShu0-<-LEi8@|dfo)~@ae}K~8FIV>+=lPMO zytV#D-Sr(^+YTK1QT{+_-?zK%$G-hMBvPNed&!NTKkPRLF|XnNz2DgG&3;zxI{t=J z{{$Jho{2H=*Z#WP_IGx~|Lu2+`%gVNqnogqZT4hO|9|4gU+H|^wa)eCrst3Oui7#s z)Lziu!l0A6keOjaOKF2?(*M&37v(eQZT#=No&CUyE#mus9M#u4yeIq9nY~OO*z13^ zf8TQMuQl(5`G3=6emZb8Tu*)eMgP(xRT0p(1DPP6SsttmI!??69H(8lfA9aiVJ*X% zUOT1*`to;gys*umd;FD*0AmAWh;W1c8+pbJ{O~32H}t>tgAVuwH;fo$l)lx!_{N~X z02>!K{=NV6f%T9k8Uw@c{hvR)0e7Mp7#P0If5%wyuRE{yq3-dzS4X$cWdFXty5gX} zyy^d{;+J+8ZDs_$Tl&-dRal~ekH9xTenti@8{Y=%}sju-I{8TRTDb( z?%K?*_tjmuqxk9NSm~6#`xcz2nJqE@)zaL}zu)w!$2JQ;M-;`aLcA9wEifBf|Q z|BpSbcklauymsP`-}N=;@BjZGYmod@?$3l@^?%v_?h(JIWp5q7?H@;6QB2+9KkDy{ zW^A(SKmY#Io&$drW`CRUY-WDx=lrRcOOEVYQ`BXnchqLK$p1H&?lzx(d9T#3CUX8w z>+)wt7R6U*)-Rnee)m_<|8<^~3x8(KtP9;+v9dbz4ePVXoA}MrzrOn%A7ejb`=8C` z(_dUVyZPsL*X{EP=FQcfpZ96UnSF8b0cmCD|1JIaO#0;?m95s3m)2OvcCEjtsrOT}Pjoxccp2 zPe1?v<@8-s<{MS!?f%QUeV)mGyZcj2@A({z_TTrp_IcgMeVdQn`*^Rn`u^X#&-tG= zc~zcw`=`S&*q&eOiVVvUzc<+)wypWj>G|K3=>=lh)Mm-1)!hsw>~>9;5U z@z3ou+GbvxXY#EnI=}v5ZuyV&|DRml-*q#KPntJZd-@A) z-#t4^=D&!ov^UyZtZ{qhj!9>Wc|W+uxa#$Lmhhi9o&_U0go9>DJPeyc&qTdNOIy>JVTO8ETvl{ z*=k8S^ur|Nhkf)ZhPce`#&m(Jps6*Oz-f zz1e)e?1abukG=UN55C`?x!BFoapm4UpU+vJE)Xkt&Az+jLHN&(*aF7I4|cmnYQ@Xn zSQ@-;x%#|{q{D5zZ;$KE_xIY{=i$q17rg1<@_ALOIOCrx$7#Cj{{HsXy7<|d`+x7= z|NAO@|DyWL%J=v7`l?CXFut=U;KSF(*aBNt9mB}Q`ZW)^w-mg&v2o^1Nu?Q=_Mi5a zKJET!sasj)n~lf)=31GWntna1U$;@OuA{uq_S65rkHzC`A|&Fs<=yp)KR(a4TB<60 zf!x1S+OGQrrEbapIVc~p`l|iE$M(yD-FNT*|L^w}pX`iUSx13yJgoOirR!_I8VMv! z|E5!1T>LbTy@Yq~k4N2?FJIpO=c)e5Lw9!+Hvjv3kiTw2(bH3x(l)hh^vP7;yi%l0 zQFwRmZL>ui`zJYZf7vLu+xz!Et1l=1|JpD2JO91yo}{B)LcY8_JbS)gi?%L*mvd+C z-{Sed=hX9MrY>CH%<%Ni&f@HAYkuB5U-!*=|7UBHh^)qG^J_kxd|&&%dW-4v@2m4d zU&R!LovZ)fWPA85S88V+$eDZA#P8pC;TOm5J)ah{2G)J?sy)ZK^~dV+?+(~E0z5mBi{fwSFzvfvKHa&QAH9Wrd$HVs1ji(F#EC2uaQT*TUo$hwOZ=Ro$ zw%~9(zwo{Z{L4~rwlX>IKc!W<$GyaVp~2<*f6m_j^ELke*X{fN=F08-eXe|;vwY^$ zcKNy;si&u%xje%(t5$v03 z;!j#?@1_F`HzivfBcH5aAIH{o-{-})o!Qs*(rwo+{AyV9@kVQ`*r#9jKEK<&-sG!T zgV3HCNz+5#T=O@3+$tWYP_U3g@Mh_zchmLb&3Z4NoUCsAmTSMs+|?H%XU=cDqW5RV zDYoee;#`e^J1b{n2QtpEEpdHwU%b zqIs16-{n>>@9W(4{r5@#|ECuh7mKV~tk~bvV>3sj%lp!HXYEYk(1`7Mv1i{Xy_Y_7 z=IQp`Uw1uxlBJ#~C>?P`eVeuDZq~dF#y6H4mY-wWG*n8@$(w2Y;BD|CN+ftmD1N`eo+%nqx~I-~ada z{<^ubJI)(?epOPY*tg7idYU*FPhd%NK+e}!SC6EmZE3Qb)c*4K{r~^s|6YxMdt;-r z{f;+xetlS8-2d14>&5f-f1N)w=7C2DJgk-YwOx$dL@Z}ejEqoDVOShe=5DM zFRjfy@#X!$zrX*#=>OMoEm-HJ{=Y~1L3hGK{(pIS*+soXv{p}Zi+H-YT-_q4*&WF% zqJI6j`Ve7}k{dHI3-UNM1OYPSyPz#K@e(lO>2bM%t z;TWeklRm8f{d`gEqF?N-+nfGQJ$3#Z-$~P7T@mbECxh*zwSNB9OL_1zJYOK7D9-1P zmP&StTH;0by3AFnafg;V#aUdZI-woAoll})*%maDW}oVWMf zw#Vlmw_d8t6b}9I^L+ihd)t%h#7iH4$aDXur7WcQ-tOPoS9iZ#))joRjsM(vO(kJ_*US}P?vGmQ^Qn>VR{jsCnpe#$Oz zzPH;aV^d)u93$8J-gGlBhR5( zm(nJQ*9Fc}-7H(wW%KvTKL2-LTDvp$ zn$5;VareEoH*>oRX)beiRQj~(&Aq+RM|(7mw+fYJHd^`DP4_8VcqA@r!Ik{|_Tu_+ zOMF8X%DoZtQ7X)HKPcUozj@8-1xYGZ;oc}LVE_?cqqPx6`Sv6Qwk4z?v0$;exbS|M{p1OvC0F9;-5F?&gMSab7i8)q=?zCEx_qPIjs2!COv6&d-vq_m&nq^3+9N5r;LpAHf9GZ1 zKC$t<`lcX}m&@({zPxZDVBSfKnGes*nX+J2AiD^agjf7oNAXpJ8`F&w%@vU=5K=B%YNRU9HbOJ{T;_lL*-SIA3a;@D{Y>)BqZjM z@vcQ27hhOE{oIq$Xm`o$mJ6Sp*UPox`?}47GPf_jz^nc@Ewmw4Da>B`zH621qz8Sc zWsZJ|t=R46f7fAF%5;eZCI)FCuhK+MmUr?rD)+M1Crm&38{{*Yf|ZK*pH3}5YtQyG zJMo~exp!em+Kz%k!>K!${OQ(gja^}MRw-~N+{PwaI;oq%Z%D$2)gD*|4yG z%Oo}L%QD-~^i4f=^{eowpnMBS^VMfwIKNqN?ckjhVdIT%=O=&q9bynZeP)*N_v;p$ zwtd%({d(i*@zzb8o0sN=y|YnPRuhwJdVS&4k825eQa`?4J?-%0fl&11m*t#CXZWhm zdpZ3|y~jD#M@x=BOj`AFQrFD$Q)URxl=sSbP&xg}`!{cNeDf4ed-*=~Ve#}os@1}} zvCM08cb4zg$7?iC>HX=c{rVvP^5&QSzTBSweDb>PChs>lODcD$*zdj&oO|N!!N^9j z7s(3`Uh;S;Qu}%K{XKPmtt_8#7+JIiH0iEgc-zr$%hJV{PyRf+t1(mU*yh;iOS*T-%g1A_f$QnZ?$#y+{(${8ic>+Wj@beAt_Y0d{Jz! z!tN=%B4-}{UU)^q>A~x>-`5_zWAf(p>gkOYTk_7AJ7(_nUUg*c{CLkPw?2J3t^e8c zqKWzOIU#fGZ2})3z7TXv^Q_*?r7z_Bja~`IM?1b}sYrYvnAiFF{k=KmOacNn|Nnem zHo4PItX4*z|DIs-#p0MNzk4{6GJNNq{9LM|`)kcrDfQP}yKf6j&b;g%c=*nTn7c*h ztEc_A7Qh8A3c2FB*0S%`c{{1j`oZTAP3FaOOqISYl)u1V*%~HRtM0I2u8r@{H1QIzmKU%bgCbk+www^yRIYo7(@p6PGpx*NY^cFTOjD80htnciid-Tb;%A+62d z*B;XA{t>(V-S%tCwk?ZeTU5fhdyDRFo2d8YI_CSIRQ8wL^`3lx>77e*9eh%ySw1U5 zcRjaXwEghSrAPOh{#n@+8(_6bhimtPYYl;m7cAIP!MJ-tLu>#D9MIFyNDvnRfeqYT zH&`LyP1B`IZ#I2g=_|nE7@(f<^wiY$6w8b$jFI!Evc73zDr;2WXo_l$-KLVdIneCn zr;wlndKwAh98C%wZtR}?D6a@ZYDvR`bn+XJKDZ!+5`UIlIUYkj4Xg3DaE{PxGB^7R-12-QC^a)mp_~D6c)EBC&xR zVgOTFrrC}OlK1x4+uI(S(WDUX$EAD0J<4A9r*K- z*_%IxBX(Qv>t#QUOx}Ngb#-ZdWs^%`@3R%1IjnSXI{i2(A>fcxAH-r4RVA^Hnew$CMk#gR; zk#B-{l&$8*?%JNO9`)x`_`XlKve*B8z5k!~$5a2kpgvo{6smnhuerH7I$JaU|Brje zpSNwhw*AWfKuDmjNOnCDWWWFPpP6?1{vDWEDOesbZ^pmNpS8B6xXfCWyrpzYR;|d{ zdHc>?KRf?je5$#1{jVOIbr%~CI7Ww0ndUujYIs~_Yf;Pzq5rq{|Gixg3GpSqA&sj{ zr^ZU8S1d3rd6!(6RR3q&sweAy{5Wp^FQTrj%;Uz>+>Pt>M1m*8-kTB0F*SO7+C2%K z|Hq3nK75tTS~#(Oe!JiOB-y_&z8dZ3-}mpJ`}Vw}Y^%?oT+9FESF`*JSv!lAt7nWa zT|caT%a)79F(CHFQn{acOx7_AJWn(?cDqeju|MUEg3!$ce6Aa(+ALkxUpV2g-ap6a zS+N?@(-~U-XuJ2z{k?U4U)m<_+9gxBbZP}`b$YXC-)X5+#dD16Y|h#D8Gowq(>bM@ ze!0TQ=KRXLd$YdxbZvSl#l^ds@6Dv!D(oj4qJM^^PIu&06my(o_hP>A-b*d~8@O2< z-=5LqG&Gps{-rGAe|w5larT7RW9v@elIxh!9#AJMANi+wo7wJ=s;aj3_LDn}?Ck!% z|Nrm3O~{dE_b(H}E~%|@xH{{co>YQFs?G8mjqfHGd$f;tI|&KL%2*k0i#mNaP5kyR zuh)4I@3tk1pA@)tz34-4e_kX{;-@)T_hTa4V)x8j?FP!$6JmwpJ3f^CSTgCHURAbz z_F|jeI*kDnFHO^p&Rq1qTYuk==k@=dAJP8*N&o*QYebUEExh6C*l}K|idR=Rw(RDX zkG=gqWtKkB78F%Ba>C+vQ*PqvzHYwV^!g=nzX!$*b8*Z#nFi_H%e-FqtP_1gzJ)Adcx z?D`p-c8`P2I;7|E0{PmVUz@uX%Q#(pCLLSsxH{$a!GaR?1A3ZsdyKp4$78m6{=>)%Q?3*}IMDcT$pxm`C$CpJT};1x^^_jx$`cGYyqz z224_!eq@o;sydT@k2ZHteKTo#?4NJV`=)*I6YG|=e4`XKZ{|;rwoIubdTBR23Ma|i zZ}NNZpOy!zA)+q5Su|guc)ji%JyWd{dS7g9uQIl_MSAb+e#BsWUfJfM#{T=R0?v=l zS(-@nbY6K>?)f_9SH;SSPaf(C-Fj0q-Fce(@e^}$57;Q1&M~*+db*G0k6u%(*E!Z^ zP|a6v*c5xKHMZyY{24#>xNF=#9z0Mpht=@y(+M*;oI53&ROd{&7hR)2%YVy+?pUtp zyIHJf+PU8<B*Ei(`T~s2-etzW(25lhd=( zw6~h?xWJG(!{o-SXOfB(*rPFl6y?zMnsXb%d1d7^cZ=B-O{r&yx>;G@gjmpR{aga(|`zGne z#Uo;ycIsNrf4}J2o-=of_ONb}s*LAjm63KVE1dU!li}N+dYN;-d^}pK?rUpl)B{Nc9MJRj*O~rp z+Sdm&%Xqq9uq^&^^0ojdWJExPrT|Nsqa)*P2Z#t<2vY>12#>ax5@j#%?PG3I;CRK- z7#nb_C01*y97mJF3gM6$vDel_ZcaSRcE7^r-;c+u!`H{{EJ|HAbD`DiYiq45J}8)a zRUdq}E%@gnaryf@7jMdaT^4ns*f3zB_lHjPu%A=qtKV$Ay88Ns{i=WTZkN5iy{DeT z-dBO6=|Oqon@!o*^==*9Xee!-SMzS?^S1W(&YVlRJRi^QtNk5U_w(t;j~_vmrQM-> z+k+#&9(i>yeV%N^w-4{`{x;9K;W0h@nVz(H-mUH1%TG_s?YIBea`noqtJY;9MVHnd z){Fkenlqw#%xh?m$ zxBlKQ&t~WE`*4Wcy-!B5>14`Wt0~vl-P>LMb*t0W$)8?-|8BYZ%Pbq;8(Tk{z5ZfW zm2vCAn#tMU_Wpl;$9Ap#?ln<=&lsQo_T|mp{p;U5+&_3~ovpvkMytD=+fzSp`^Vhg zQSt3e)-NkB7d{?vrsIzuZ<=`8vG=iit4!^8zp4KJ z_qvQlh3~s}kDcJ#m$j>55~Ng-L>^*>gTY3Z-bRie|x+8#PUt`_4kAQbJeVj_dE_|NQF%>K}cz<@K4*zfB-A{^iZs7j=T~ z*i7SU4SsH_{Ps@fC|aG_58ar2B+@-Tf`CfC+U}b-q)*4 z8YN#cxO30w>C4Xi6%xle-*4ZVf6L;kvQO>Kd1Ctb&&!?lJMVqH_W#q|&x`&#u;1I2 z5!?QJaee%vWfxB_^ZNf%b?%$^H~M-XSXsAS@?8D@eyQ&pr&cBREeBJ?x#TS0IEiYk zZxxDJVYD^%-y5}bo{gs```g`|^(Kj}=+T>`miCfqp0lwlBA2zX#NWxu`V*U#FQK3z;c{_WlE`2M_l zt^8ka@=E_DiS0h3xuNe>ec6MZ&)Ys3EKLyi<=;Oe?#J_$lS>u(H=OPhk-Csp(QqL4 z(b3c8ce>~Ny;%E8>@nLawe@=LoQro%7ry=R+{DHue^>2aym``B#hmQT>z*8&uYJ{! zX&-y<@6{(&|8t+(Un+R>>FM}?M*Wg|zun6AxBqMM(cSAzhrf>1tSSHg)y2)+%zd;+ ztT*=39RV?oB^$fXxf_}vyP=xC`5ODpv+?nJqprM9y6!2J<;38*;q>}pR{R>=I%}( zzn!J`DjuILzhAq3zx{dTPhDTtqwXi^RK^EuZ%sbD>P+1XsqItqYhOq2|9;Ne-~RIK z!v~J<(v_;uo>QJyRFw5=?WQ+Lcc;AMt9Ztjc;Sib`OD6;b-wri`EOdg{t&_v>ul{w{Kv zE${F9-`IMB)vo$AW~t)OgG9o)*K+<0XPWAq^YPl0-^q_V;)Fjj-U!?F|0zoei^oTM zw{y0i)^~=NZR^eN_i`!-MefZos9yx*@yM^A|55z2Bp(^2qb8Q%E{za6$g9Zrc2nZv;P@Yh#3R?eTUYhu)vjm8DKF>FzPqD# z^{1S*=gpIo*VljFeShwpIWo&~HhgjLIrz`z_419}jja*NdB19G{~B!FUHj^a<}0(m zx$-t99*OItcGaf*;oGk}Pkz46S-nT$n~JLTPW*FAZbNN?+w4O|ncOLiVzuJw=jZ+X zR=%(J$qDb>-{0uIEH}L7z2IWBNMZr~*1H0zdRc5kEp15Q6_^;ur zwKkJfB|YNrJvx=nx3GTJmv3HQQ$9Q}daIEXQKY{-vP|c(zt4KXzlr-9-$}@Fm)PB? z|H^u?>BWH`vWGQS=i5C$u3tI#j-aLb*}2Ml%iczvicxH`oHj*a_l(NjHQNLq^6kux zGE5UWm*F|{P4cmxN0%pZnMl9NU2xLq%_Qr)JHpBq?h$hmnDui{`uBfVSI_sU^pMS6 z^hCnWeHKUCr^?s%?z=2@pRrhWargFPH&hQ!&)@sy(&FWBrsX|4Yb8ZXoE`PsFMWV_qmU~n8#H#Ekw@=-f>*#eR0);b0NtTf3ItuH2>PDqa5W z)ym_WUzP+sUHp&PrvW~ zdA6CE*}DAgspsVzC&zZE&)IWVq%85n!aX`mZ>UaCzVob3{8yU#QPI?dY_2AY`*mFp z%j;hJzL5MY^F*q~U6nWy=lHh|*ZvEgwQs%f>QjQt&Hj3JZa;jl+g#$u@YR^RKFHvjyw4cr&m)_(0}kCdu1h@GdtBUsk! zhKxtoETi5_a;*uiYOeXWw=F(k%_#T#(5eg8j4v+Ld^)-H={-(?(^sGF{PoLUH6t?K zZ0`JpF?TQAzx{gs{*MpaPUN-!nth+P@~t@FrI4ml7x?qFaA4m#&;;y5 zjZ?RC#WL*Q|H;#vy!y12=B8S9B}3)vrJ2*t^hkbExj4P3rpAW*^qv_L`M!KeJtw2H z{%EJ9VT56_Etj3dks~)%Rnwlxt*$LDovc0Comb8G%?G8~ZBv(K>&%i9+%av9`S_=WbF^=g$8D*eYPGQcvia*P>?5Cq&(qjCy}edQE#%It)JirchQuca zf871>TYtYo*&)|yJ%v?QudCnPn5Vwo{ha6Go2;x$S-t;RUb2~fl!JlYX3MGlkB)Q( zznipv->+NR>uYrR8K=DPU$Zab?tlqQy zM;`wIOu8p;oueLpeTHLJ&pYq-`M-a?$f#Q8?X~V*)2|s5S8EHXto+YCbK38Xtg3pu zU&P#fxj**BnV8tjwxcXBKWha(e){r6iDEV1=I6;5_M7OGch69eJu#_sdx6W+-TVFo zZEp`g7p8yTX4}+ zQ10s9_Ipb1v8TD>!JVvIlVdgf#gO_v+j8&oISR0pHXYE@$UUUDI&3{?%-6~>K^)S@ zy0Y)hCk`$zZ!vIh>W1nWJ&X8&%P#qx7AmJ57xSF>v_>aEoTKU5y6F9>ueasiy=|U* zlWA+CS^nKyclXZSckOESJeJ)K-aWCOVrC_XbG$0ZdU7|GQD%%_jme}U%krx*Xk|% zb;yTe?{HD9@sgJUw+l`g0%1_Z)+|dY`apMS^0$} zZBBG0+a0S{XDZa6TyPd{)fav8%1L0#QN8M*wRbnd%##?#e&2gRA>oS-joDEe9HPnqyztPSDuBr2L+J z$(}mf^SY+eXITjCOF_fgE7-~s9~Aw5^O;FUEU(@o=136V{JpUq zu3gvK#pcI$MSfJ<#Dmo`_1n(PSn2W`}3-K>Ey2u{{L+MUVU}r zCB9YPcNMKU=6wCm|2K7M@3emhcn5Et-ze4p?tNTvbL##(^G-is#qY=0*+2E-ZsV&v z4<}3)DN}qPknqs(?4hlXml+?6IxNof#ZaPSR?5cZUw-}CaV%`b)ElZZToyH|ZJc#R z0ajem~45?&gMkD5GBxw|{W!r9P0aDR8=q}1k<4m(P(&s4p* z?$9N`;wf0w*@S&3nIQ&3obILXN+}_l@`da}2J3y8Bs-S)PG= z=ZuL;{Gve{%fx$^mzd7Kui6@0be(_Rfdl1RYLr^ko&_?we=*ePvYV--^s`B)f9W)y zGQ(-rJEdDred)-KS-yPz3*STWlN|i#-^$Eeb^hg&+Y3JLj<>4&_b~0md#8ZZ_u5gr zEo+aO=jZ5eo0lce{Wg2YtQAc+{|Bhw{pfYV+s@zjZi;*P4}A-t#eA!kwte&c``7;8 z+!X+56)z_f_%x9t&z8^PKS8Rqe_rve$#@zH5U1>cYp`+%-E7>R-F=t=r?j~1oyQy!a^h089I+1)XDfq$#`#EEZ& zPJheD*yqhzw$s1!45PWH)b1x<>o4}L)A{JVd0w6P-bpKzHu9?Zb7VivU39lKbK-0! z_m5^XMbFgFoqFjNcUVAs9LL6PuDYMUH}Q3>J>wSC&TPlOc=ErBQf{7|I%S+P=e{VN z*qe9n%Gdw@(#z*4zCN~BSoBZaop+YY553!*cmG4y5A{2;nXkUfMI^hbOkRBAu&eZU zz9rvy=YTR(zW3`Q(+F+4)~L=Smp|bs8O9(RDW`>x{;)==o1C zXT0;=Wc6pIRpbckygU+pTuy-2Lwp^p>t}l$jVa_k8I6j(-{F-P6u!Nc{b{ zx#r2N25Gn4SrLIY2QB|Eja0brx_-LZdDHWkB%;gAUojL&pE&#}?c>W{-cP=~MswS3(FJC9zeCxhGqr_){*_*waL}oet`4av5rks-f z^xUbMi*CJgU#9lquoj~Dkpzq5x>rJyLi%38@2BX)h@1k zRT=4&a~UTq;%Q6 zH;?9D^(nh}agoxSOK}SqDS>L&s3$vjxylI$-TeD+Q`NcLK3C_ia|_NHR_@4nE^T>3 zZH3~SLu*+#`&Zs{ZAn;ib>kksy5`m-H@_K&yR4UN@>Xz3D&Xv&`146(nGpl~N<(FP zrR4Tr4e!S@yyQE1EhoGFd9NC=f1jc9{MbcvHRX&q?KAp)+V_3&lvp-*zmGk45BAKM zm?SQ1zbMv9D~+Ww)~2jbPKVpEb&JKDMU&Dee>vmf)t-6Ub=~T3?{?=_@jgqRJ|*TZ zt5ai0*~xQPO@GV3N)g~oS@%x#{7k{KS3~b!TRYQG=Vp7)jKDwDokwPbB&{)&u@}E# zyK8s&sqb>{eAdO>4R}0J-+az$>5~g4SvY0x^t_X9Fk`j$g(E4`3)blc_8pQuIu$6tf zmsoAf=Jwgu@3QxQy6^JmwEndlU-YLv{dt+af_2}6tSgq>JF6#YS>5@1anD?Rs~Z#e z=FIHpF-Uy_YOzf-*v;cJ|GNI2e_z%%vPnKTd9wTR-#-O4j9H9j57n;4=pBPecRkx=4=pnO>~nP6g_;1#H>Sz!ai zrY#1$3%)xWav!%9JDV*2EUKVk!T&FN+$Lw0-pgv4wKi`3HjdpXrT1)0qH4i<&+FBH zIxMf18r&L{#$B$aKS}-BxruMBe;v1f+Bfs_WBt$zD>Wk>&F2rfh#;^iPJ9qh&*rK#c^t;UB0SflW5jL*}t(uN{RObcFSt>9lCft zW%`4KrrkY1|4eyv;_PNmo;#QNMbpJ^U1Tt_(s=E*snq9-ukfUIYY$7x?RK&LpJyr| zdP;81<=o=b{Z_|MI-IduI@cT&ZnIA5al2_gC{Juuk+e@b-IEY;r+xjEXvtikeQ&lE zr)WjKGaohLA@ODbJ~2%Uflh9 z>cYaa(CYunvKRbs*UebG;{MSGY&R1w8QRs%jZAu*^t(5v?BwO2p{cKaGp9UwRN7{C z(}%6BQDFt|jicww3me?5!cC@}So>s>pq42Hb()KHCu7*|*}GX9)Jk5Igtug$W8F04OrTQQk`u{mv-1=e7< zNv6q738yx7FJL*z)!5OKGCiWK*!gp;*9LDU{oWoi)85#y^_4}>&vE^=eRF4P_VIJE zx69wOSh-l2hnBs4wK7D@x-9gC5d-@c+ub#vpLi~v^k$NM+LJXt>Ei3{POmal;MCOj zJ$+SFQmD<^@z(y0#+Q_K87ebpYEg>k#__^fCir$I4RzI?5cT!X|PHxLt z#q<5cojVe{XPggyXnMJ*bg^;!U#`A*m%`?`%VvFJ5f@i@V|g-3Zt`sDly7FXX;ZFM zR{9+}znpU}uV@Un|B_41Tba{287w6)cz4Ba%e}v`?y%b(K7~)aO3U9fa6PzLGUG$f z^H*lk2Q5MjIZHB5uq4d=7M(V$a7Jv_s~TnY-6}Vpp4|HSM9RZB2F{wBJG=EbFEHEy zt!>F%)-%&ucLlRn^0LG?m-@0acIVvM!)ngtk@@}I-q~ikjJyr83LCsPPf-2wV_Mim z+t*xgE*ZUbAmPzj4Rq(cA z?!Q-k^KGqDYGkacqiu5^z4}-%_r|{77ygsm=bNnSvgis_-(c#0|HYbBlR3*6K?N?T zoLuSpI6PnaSoM!LxqmOgwcJq1p{c6+NESgUEa$i5z+Wc_VC-I)inoFI$@9$5$nrJQc z?B=bHw|3lgDzGhGeA{l<<&6$!m&oU}W{U@NF8lCd?mYMQ`aiQ?%rN}6f4Ac6mThsh z{e4T%8O*inoqDUe^!FQS&fObKUqvKi(@E^4zvw;L4;oN@rBK zQ$Ec9dS;f~a}K4)vNgPa(;d$Euh&w3_1m&%Lq}wKgk3D)!K&y%h+B% z9(?%2{`}s%X&kQ$_La8;p1Y|Tr@rUwr>6$HCFFEgeS1CsfB))q)29uw2lNDPs5Zwg z;*YW|c=jbCr|#^H7ZGn3eigW}wDgZ2ms(Dcq}iF2N4gu{y!)7);ZPy_1oD?K9mi-5{ne+00!X{PAnnvBhDJ z8icAY8nTo{a@9>=QzM?bCv;Ya`S}y8KEIy-KWg2+s<+#W9)`T!o6UXg%94uXeeT&( zZw}qs^X+oXPrb@^`4i=xJoo2$s!Yx=k*$AyrTtM$>~5*k<&itS&68GU-rW#eh#v|hGQ zq!v`ggHrO>)ajGe|2t^Tj-6y~nZ0Vmz0YSFocBJA+#7j|sc+47m+rlj$^({f^o}ww zdoeFWevW+o$pf(&*_F%b85QY`X4z`NM2 zw|8BiuVd2zJ#hO**KBtLr$(pzp)V^l?Av`gSM_b*op-Zv^^_NG7oH09u(d{bnY_z4 z`t{(El=8e^sSmdt`5b%0=6SW-r>+AN?Y?q||LqX>)XEaKxz7r28m&mZ;Tqh!ci-)e zALkubKA`vQUF!|iwbEubH(MCX4i=X#+?F=ow)*?W{aiXFpO|heeS7oi{=X;ZYlxn{ z>dU!lMXbaTmm8`(cB{?1vvXIRwT@PbfZHKwHm5-A`akyiY&Vz2oZ)!G$t9>&Liac zox@T;?e14SW?NtUwZd;%;+s#qgCG5z{fcwmueIAwZg%-8wQ;NNJZZ+p*ac>3m_u4` zW@)$E2mXyID>?LP|G$i|XJ_4R#}|h1&&mGzVPO?ddYS9JbKj z5VNe)O%(t9*x<3~XW50@V@)J-kC(@T4UFnPhEc&3BRpMtP}S${!%CWahJsg z?kmUMDBUmTXv>f;(@Z-$`-I+^tq&LuE^JpbnN=eD_lVJ9mPGgT-BB&Eo2=f;S*@*; zJ^$7v+^nXh-#g=~X-%f(jivYAIMs;@yGNYSIH9K%tCs(+`)PUM`&$X(D;D2qjs0-> zRZ#n_qwg2-2yI?qQ?THTMx>Ewl#!Ber?p1OT?IK19$F^=dD6N_1vFWr@1fRa^Lkx&jGy)m(r(;@Bb9Kv}8GV>}{ol zUAAA$o*no-Q`j|LDL3Tu?@jiq+nXjvr@dWtPh8eg;D)O9{i9w=7ab-?_@;@x6>y%w z>2xfpebEgsKK6w*BL5e-@u*I@m^7<+(>o^XmdLppkIM~rIGSY~aW6^p+_HM#-t*A* zZBMPc*<{VKiM~gh+!ubmB+LxT7y;TFyCw6_*2Fc`O;mJl_rEXo;Ei79y~yPKKLRG~ zjZ?n8C5k(AL(%CgO)Jhjv?m<37r3E%_O7%r`>b z>o+c2qI-JoI&QGPxi_4CvZRsqQ6$69n@2kz7@R1mRTu02AzHM_`*&N{tO=`U->`X| zUY>QvL-iEPVy&{xD-9RFSQ0bMf3a@rq^l48uX@(l%N2{9xtiKwdfPOy?BBlj63tlN zCml~-)vWvF_QjpO)+pKS;EVqGPnEB;+%br=e^}mlKrcXh<7xd~p>>aw9GL{%i;nlq znYzmKn1*0kq1KN#Nk#mjk9D5P%f6X(RPR`^^_dMFW?Nuu9D`l9UhVgZe-(Oj_sgBT zHo9-Svt2oOAGm1?82~YW4uJeL$36g(CuGVZz2uGaeg5OyqS|83@^5mLHLj_CG;Qqy z#xusBz62%Y2|heD(>k@dbg8(y=l-vklbA%A-ZaJBRs9}wcgqIvb9b5fLsxf~+{&LR zc_p!I<;u^!GH-(F*X5Oe|7KhL?NFL?%$uYa@7Q=7V!3=~mMt>-C$)n0=F!RxIxM1> z7HvL#tMqmGn>(%5j7PRspWml`eH}Y5sA=_K_m#k3FO^Sc749h;_5gTH%T z9oJiZ-DYR)albp<3hUnYRO?*ujua~ui zRMd{%lVTM>!wKM#3kT3x1=x7VPy}dAJ7@p{QVoHswk+7>ov<{O_C89rOV{P9WJ^dr+=`x(6v5Su$QU29wGv*uF? z(~n8~V1UhCbe?O7Rp5A)QD$lMHNkEF?VksKew_a6xc%0+$2oh#e*O9JBs%Hg(ht(h zeZ@NW@>!kI)BkuZ^mm^BnzZ+OO#iK{sQfBa^S)&9&DP!WU6B^=HfG4}Hn`rz%<^~n zbJJNNt3QV+U&;AewG}?60a``>DyA&bz^m-ci4SE0`vkNNIuviOPfRM>RP~(WIJaDa zk$8pdR<(nCZbHx0Dmk(u9o(#TXKeA}d;8r*=d<#qrdpT(4s%cIoe7e%fBn;4(9!bp z^R+528=Q2vEZ*M1E#=_G zo_g0~TVLnCOs7kGODzs3PtSOMe=XZ$r<={CyK>jP34d-O*%7&X%V)MXOpX^WB~IUv zu2fht!zS_BkslU9Od_8q8l-ndB|p99Vef0Td&T2bepa@eN`a>utt{^!EtoGM=4Z$o zzadfSO?jY#(v8-)hboUA6xq8wPSR?Nq%&vgmKo3H+!Fb_@UCdF$k*KxcNC<3td6y> zH}+l=o3nr7X}wCT{i}Rx>l=7t_ME$*Hv1$f36)Ci=5X=&(Xf!AyvT#!J+rLSwcyg{ zSe5lY`yPK)Ii}~W9&$xyKllHcc@gib^Mvx}uedm0%y^Tm@uIm$7*^js8_VP%Y*n%g zR5UY1`aIJRG!A-V7$&+S?X8}ad92Gid*$hnd4}(75*%h9Qx@!cq5z7ks6}s-4%=>- zy20UUqQK^j9Hj~Ez#o$M*NW9MVFDJ|k%&tJ`&owJ<#bwix}%Wp@{U7Z_pQ}@KxuSKPD*H?Qw zInvzv=FJgRTzkM~F?67O!@*}gk}FHVBW<~7^}3CecLgfF$~vQ*bt`$^#GdOCD|c)C zD^?H@GBQp(vFua<|M|1M8@qqnh{hS~hMQXz-&p_PhpUMBjm%Y<{so1MhvrSzd1knC zr(;_FNJ5Hw^LHYe{Pxj^FZ)} zMg2|_jpsy{O#_u*j}r_ZB|3 zie0sQuKEH80jO&N$`bRn_Qjp8xZ?G~QuWInv#P4UjG#7rqr!@>H(K`=Megl3{C~P( z(s$Fa>1VWOSN)`X2$YA}; z*G_KNi(2m;V*Se5=k83C>pSKtmRW31PME&wjgVh);k{!u{4aNboWJ1NrqfMtqor}gA5jUYRxdcx@qSFxu!Cos136oal37vQ+n=Bp*36C$rD#a z4V9lIdET3;1FGonwJ84pk4!tRJ*ii>ulrN3MthgAN|5}@WnbzuPJNWMWK1#S&rRm_ zUS{~>xXrrzh8w((eU9z0-|^dJLKnl7eV0E^%Wq}vJfIhFd!zUHr^VuW;g_y+%(ak= zd!JqKglRY9T$xi=d0!%UCBi4qJ{vlDu1483ukU85#~0&6AK8>1qP4g@b*|&Xd4hfScOG7tWxU*P$wuyIa!zn$MNxOO9JepIoTB-+M#q#kV^r zUfivxx8#fZc}atI{a*$dwHNP67FX|U*|*zoUiyu!gH=^c4@b}W=R&CJZ+y^%YTJ5im(ohSKCh**zPX-lHt(}hb`mXtkw zJA+$~WsPNx*Q`HNPAO%GcAW0Gd-m|p$G+*}wppRU^BL0~?6(z972mr1)sm~Z%TurF zG#}E~{p0UN=gsFUKd`LhoBO<=cK37d7rS4ZfK%s{&Nqwpa4cJXUH1F#j(-+yHmoHzn`775 z7p0!!JX3y%**4zkKD6QUdvkZLsNcRQ=G_LjldA%hQ{)Sdr`;RV{@}#<@KoHLgE#NKTV;JO;g$=R_Kfs~wx7-ae>Wv}uGQ$Y%8Yz7$vACFdu)(j z!aw16UurmO%fX#T$G67kPkcCL%$)H5g81v3vs5_E=dE6?8>x_{B3vJ`Du8rOn z_l@)Ze|lE^im&4FS0nXHH&iFBUOg-I@5bWN)#c}7Po#*?U0uD&ZNK*^&XT{*kvn&- zdanEH?!ouqMJwl*z4nl`yBZWZ-%QVSH+j8h0;iV=MX&pPOlQT07dhXb3j1-(oG`kv^d58PChw}}f1QuN zzW(`6&}PAZGa@doUU5Rs8`O*Do^Jwi?~24XL1((mC&tz&pQ>S&^4--}mozi6X~W{p zvAT!!BIlO#&kft(_q=RT_M=Oug6x(oiUoxQOIf4TOZa+^Yo~csQPz9(>SI~&k-9T- zE@Zuj7s`5%H?^qiJs!$I*Lz4DX{nmToDFJ_G{!Di_H=iIr;1dD(CU*ti)52Hj2ury zyb2JBKKW2#O8+DID;*14jG}ys{jTlxcC``#w{@;Xna$v7i7uZTDfD(#{*})qb)hqV z{bNYJKk;lzmv>5V-3O19+eer~KUN4sqVbB!{%*-t7yMXHnlw7J<(5~cr`FDw=y85A z|Hr(SU-@UfVkkJfGv`i1pOB%ltDM%7q_=uf{x7raAd@TdHjRz%Gk&^s7@t{umN1d8P=*HQ;y^^l=7dF>O zowfB0Yqt+o|M<7!OrSydbjE8r*IRD>{4IBBX^H6sj!COO?|dbFQU0yS$sS2oXPdfd z{V|uVH!2;Qo+)VnvdnAMrOnb}dy7L}-rW3g<=N5{#6CEC@IE*keZ-V9SA)-LZ#nh! z9Bx1+$t%^d_YpypvIHP=&ZMD9>kjW`CWf zZf>_Vll^qv&8@k=%U1AS+1q@y)6DMcm8hAInZU&}i{phLQE*ohyypqjgM%vL0XDC$@lpAX65KFdD!pkA-x2gWkb_j~GJRQwg1n^{^G zxx4J{xw)boO$sZ{x@`Y`Y$JEMy~yT*JINPq$`aSHvUB|MKc8)~GVJ+Uw-q;Eea-6L z;2rk-uJiJ%`OamE53i;QusFV5&UUm%i20<>(vO?x)r$yDF|NJm<;0?W#mV~DZWWh9 zdlbv8!(>_(_n*`|=$tJk`T3{j&55(qCrj*DDzAM`Z_8rFl#+mJy(zC}yqK+~ayPo& z*ru$r?BCri1Fb2x5zB8sJ5^WOH@R^}sh4#=sOWGESiPZp{+px-i=!qr2irO~+;?s4 zND$w~{alni_{+Ph)E5`hphH?&!C%_T!p{U=d7o6!oMZ4(LVn*losDH1|GMeze)96q zDx5Wm;)(J~xcC+xu8lFqwj!+ChF!rS{dBr^r?&X~w(a;tdpPvs+eY;z^tLv{$;Y;pG9 z#qY`eFGN=R^LCZpD*tA`zFH|Pc&10j)>7Lks`;$LkKgO01 z)Yk#6>*zsDfi{&hO-T^HRr32*s92Df){7UDKAj3Uds}|qUbV1z>FK&X@l#j#tzO)* zEbmT0@1B=3w{Ck|G|rMf*#ydyI(C~_tN!f>|dRx2HZ z6xf?U=Vqn~3-^17b)bS8m_cd1W6vkV+f zv(D>%%GCB#TJ_mz{{y|V6~}B?$~}I z?AOrs*TJ(TjsjO$Abm35`YT>9a*xUW;}GU}pVR^}u0J;A!f}4NuP4n_#rn-bJ7u|9 z90jgu>^~jRR)6$?wEAT62jKQs(}HWs;@_vXcoa8oy4gCt*-di7)5u70ZcdmUv~$;? z<%j-ga4tAunw-2iPj;)ODl^-w5?lDXo1=--zrHqq^XetYiMM=8s@H%29D76LMYUU8 zH;c&DIQ#pqIj@5G>kcZ%Dfs`?_ic~8w)Xyp%Fklpa&61Hf1v3lP_^wSz{7&Q+;$XT zIp_eImInC%R1<*e40vfxqP8n8Wiww?z5i#la^1aW<#Vk*oOHfx>1Oe#^VRcBi-p7f ze|6t%ly7$HU)SQQ2QjDH`L8BhY}Wo%w(muP^Q(PZY^stDO>s7VbPmO_bUHi`1tFq z&GsufETR0iCXViN-fsFm;pEmUZx#N4TAWP_+BSL{YTt8#l<_C_WtqIR%8K@FGDxe6 zZiY>k)ZSG6yk*9lNjDoe90t|50xYIC-WwHWF5R}kPekFTrJj?w+Y-$}&KEzrUj|Cd zD@``sbo1%q=}b9-7Auk_a^BCKU~;F<4(bHwh=9j8R2{i|73+Sj z{VE|basKITr(*nazbapzUKRQ+uWDW1n~A#L-=3I~?=p4gR^$9j^Bz26YOz(1Jd<2B zzh3xlR^Rj8Hyl?eHJc_CKkN)SSDupCd(gQt-*{^5C2jX~2}mHjZ8)u@srzP9arx~P z*Zs>PK+QcK=eT8`du4LGV`q8y#cDZE_wSpRaN2hI`B3>eGF+j-vx8o(@w>aRul8Ma z{kvzs_ny5Y*rc%H9i#!66{5cJ^n(+v?8eLebeNhzqtH$FmquRd=Zp;NzPxnf-OutD zqx1K3>zzHCJbn56m$DWW9odK5dJkH)``?|r(oSKnb?Hu}hmY^9+&NkN$0=c{m`Pd2 z;(Fmc4xI1a{f@np_2j7JTx)fyInpmTzHa}$ploNgQRZ2-B@?x|FCS;(Fsgm}j7j^l za!u-ck^g%P%&&?^GlQxrLuHQX&mL_!-79S_mLe%(A+f^PRHiiFQts4); zZoKqyx5l}SH}5uiFS)hz;z5?|7&)%*jc>h0Gp0Lk^Ok$hr+DJfp{dDR?zq<+61ySQ zXK}>JeEBaYXtzlrX4cx%dN$opuf)D%3OsXgrPE@!o>-;bzw5-e-+CpizVq_Zs_8a{ z?ag)KyZJefoRJMXF?D)ui*ef=?K5kOa-u8~GA3T^*$*0;7P!HBXz9&OZw~F1dU9rk zhLpx3y^VKe%Q!>4rBWP<8;?(V*H;71fuJ%IwCnjHe|?3s*r{4h)!jA^941U~Of2hs z`)-5xuRx7%RsP)yX)KPQ=I*Wev73$>drvwN(a0TGCio=r=`xqH@?^I`J9j;q zWLO>}`&9iRMy|28uwY-3~iUKIZJ2m3pMJW%V-l<*ZGh5y-~asEDjZ zTMMo}m;;_60f{++O6G#hCh(y;yEanTl4b{IG4F}7J339LcN@CPcBq^0R@oL)J}I$% z!;3RE!5ei=`Ii$jhqn~1VzIP@* z6uJC?Ra)&(oj9vfQ|t}BIpH!s7k9s&y3l#H;gkTk?#y#5eJ{%2iZujnZ#c-i>EM#& znjco1kK8)?O?u~>Ny|U4K6T|g`-uZbU-RT{n#lt$lyy^SFkR5JK&(@;(oX33xy*AN z8%}3jb(&W6M#!e*;FO6eXJ;tP*z`t8!*P?70=US$3z?yvbiiAAu`8sReRAh6CFes0 z>K?z%%iN+|%+pdBdcWPt_{Xua+fn_Ppy)dm{q_QWFLC`)F0iGdY%8DRh8az zVKG*A_dnM)AuM5D;JS0qSLM6Z-$*Dv))TUe2U3!ESGpO+C1Y(CukLxi^24mmox3j1 zJY2_mTz}DygMPuj)lJ>p0^jDO81|n$%WG6UTh7?)^&T7bhtDs!oNMD+*Qy@$^5Ct; z%`6RbctC4Z90j(N+(?}$iadzF`nt&cG?}#Nv#jo)I9R5!dq#e~-de@~YtMoDd)1q| z4U3nvmO7-KG3kl5`hAH7l!y;H=!ljXCYkGU>3v(Hz2Wqv)al{z)wwl)a@VcBy=(EC zqO5l@pX#0!zj}JcdHVU-3Hdp4kF@>gEa6)8?9Rih*;hl?=Ry-0qCJ!z?vePJNDSwsdMQYMWw3RHJd)?9j%s~xtL4$VWnH# zx;)istFu428-#C9dh$w&4>Wb)81VPT(YlsS^XqN4-+h`r_G~(8=v$G=2Wkv*G+9lH zHIkp4zsdWV%0s@n641uOvkl(+yS_cC(DYAB6-#cq%sL%%*jbj-y1X|BvmNcd)@-Ue zZP?-sK1YnjbXsguz69U#hC@?dD*n2+nne-3^R7u@Mc^BuQ-^yub;r-#RFYk_S_xul zg2Jaw+|`bT{NF7;E)dw=qOF_&nttJETF|z+yH0me$;>4iysJ{r7=TAi90P=t-9QB+ zr1zoci`s;REO`PK(TA3Df@&*}t{bT@yY}y_TJfx`?OEEZOMcGQGlOg2pTAqPU%cK9 z78j7Q3-BcMlFW>XACLI!4wzbfs}kY%J9}|Ii~Mspc3zpCHSd_BEra(~7j>++FP!wM z<5Y2b`1+MSpPuek_rH7fjgd-}_sxm&PVf9?`-KGcWpDECi#w^<6B9YZPRwO8Yut@% z_g2pSbNEik{KIWNJgDp@gO-{cfq z_nDxy=f;VW_7?R$=t*%8d-%?yfBWKlwl}k6v}Qz=vRb-kqJGeGy=E9TlKIb_F zF1}{nZE$3x`9{-Ce4x{8K)VN&cAqHld34}H%7Pk+tXe0|<$fOPI|JQ|_}#gJrSzZl zHQqg}{j@Mu{qvVq5jHPwd^z-mBYxRY?c+UG|J065f;x8T2|cZKBI)AqvJF$;-ry)J zlmb^Vpk(bGHGS!7nyiiF0qdAiE59>Ff5-JJ3_CeZC?1`2}a;kFOV& zZ+o%xkj>(l;0mXmyQW5jt%+2hvO3zZsB|f_+7Z35b?eTBtz7c#)w7qOJ7Z!WmT*3O z74=Wz&PPR#H;c|n8+$YEj#e(dvUKi|X|MMgF4oqu!qXXPu~!TGqNP=IY>`{|gC&rb zA*>_9DG~UIH^bzm)vwOfHqJwR=gPLib|U<>ns>W%U8lEpcVFw=8=R~Wma+Pf@_u5S zc<;XcEly>Y3TMe}-IZqW(UG*|Bytng_%hn|G;QE|&gq*H`&~Ov z3+o`wjAzfFXlsSGBY9MXr7sAn#kPB)1bbGN~G++khw>`KQ?qf7!%7Du{l;a?fLs^kLj1L z9fyWx88wqLiuN?-8~k6~03KursJ)pwaf(>k$(_6Z2W zK=W#hyRW$a5@=Qympd~@>$INgMmA`JS89EDeD&Kloyn8$cWpYo((+gNvBrjlr=RO> zm}-1=w|e`JU&87u`&QVL&-fz`uCjy6O?UHjUJEKq**E#(?jp;?iLdTXl-v7<`Ds!i z|3Ph)T?IQ2-F({g#-3g3_|#1XwK^OcTMTS#Qx!EYE3Xdw?t9l~TBAO!wC`T}@#A*! zl%M~Ob{m!{%Dc6)Ch^?we0bhNp?Q5e$Dxjc1uZJ2Z2a@96kc(-`)yKQeW3Hmy+C=Z zo2PysnEmMV{dvOo7Ccb2+28%b{+PtJf5A;&D;& zD*iW2js^k=;v8=-^}Sj2$g8mIBjcf4ft`V;TP+_>O4L0wch3T4&@u*4{ib)eFM0af z+q>A=_=-ZcY%k6T6gunKEBW$5znehp@m|S~dxV>9dSrd0y!tGXtx9`NOw7~OP6I`0 zhTzTAHC5-eu5NUdx^$z|>eru_|7@oI_B%h@cH6N<_Oqrw_m_Vl`lD%e;B%cP?>tw% zD7fza89at#Rgh+9bYRNH=2)@xd4U??+l5YFHGSPuRI2T^Zkls07&qenJY`*&Xs#xOmHRpD>`>p0L17+(2bXx-@z_K-BU-v^hL!CKEQu`7PyWDuc z$iZa;_wCltUCo+R<$H}vGK`_6=T^;M&bzgrX}kijLY-04!ylhMEn@eLI_2rHpP=)7 zk~=EqF7!2<45>kuzA1lbf0_4m?RnovZ-q^NT~2b_mh84=vP8nx-8;P*GMw7|%3XIn zi&5x42^z%dvN^Vj>H3pZJ>ogNPF_)WTfCFt~17`uKtYq+WUfEI_KPsiC)to=jr7dp7%JG-E$>Y z^uMJ57w1e#Tw6*W!c+pV*ysc=P-(2ENbI1gC8E&n>}(dC}Q zZ-RoKOIt>OgNLQ;Wb$3<*UT$C*+Y)`9KNx1vp%G`$#WzqQCzv~@}dVx=XWtd2CNl+ z#411=x{!h|bH*BTDYJ-*-A15h*BpKD0(=F~G+Kc52Jh68z6B}Eem%IeQdo3f(Th(z zxpU6?e0_Iv;X#JoELw9cPDVZOJu7?dZ9k~#_-ye>CjF$~_g8%XRpzZapE&)(vX|QC zU-yB==}*AN$?c6|b!C@=^}&*=M+yu^LM$(|M_z z(W80~xq4#L^kUYfeDBJ5_AF%nlSwZpvZPvcobc_6ZJPb$odAoY>?ysE>}&gaSD8z> z-JcLs@`|^`d-K*Cs*U`YeIKpy+@s04Orxwb#N)=(E1gCk7bIWqNtl!xwWsLJipiTe zn-o?A-*nxZQQ#Xj_lGrW@Abb90n0acuK>5nvlMn4aP5rqt-sRs-7L8~-08hlTS2DY z${7>+ezhdIdAexorXA6Kk_K8&L;xc0ZT7r0Z|szOroRE~V(D zlcuhY?tJ=+?Z(oGb$XxIxD=KC1)V1?`?_56^a6qA`~!Lczc+$LyswnKd9-hmz)#SI zg(d}#s3S444}%kp7YRE|%szI^?XFdk<9VAyHp-v|r~r%U)L4s-JI0@)d>jhry-%9Z zRkP3g!9{&g1qe3Gp$s~Az*5!-9i;({+CYmPlDjCN{b zi2|U}E04=Z&jcMnKC0ve-lIxppOQamS#s00cijQc=%_c73|Ky|xp8rRODxa41WnE5 z?~3fXLOb3py{WqL!+|MGvsx;6c(jC!t<2^Ya58e0Z!rjZ==!Pa8EC3;TgvpLusxlS zx=N-h!wJthCO_>&XV2f&rmtK6YJ;%#Laiqyd$;iJ<~T9IPN-;6NJ?wXn?o0m1e|@d z>D3LB*7g_kwU19qeVC`XA9Qs1f^#2tYeXN_(cst6u=WxQX`R;N5u9|UJB8a&k> zS#Q4i^w1l0_r?{|ne%Qpyw4M2-VU9za6gMYWdYiKT)#~lw)=SLPgzSyPvM7v^Ww#) z?&|H1*dz2R{q^S4{PjN$OK%Ez=e=;o#H8sdw#uUKd^g%^WEw73S$vdX?yZ}x2CYjs ztDKlr(8C}FDp2Q6dY_~^F=K(}8Byb|Z|~pWK8J+0jHBB+@YwsL8_72p2wGhPpF#p3 zq?7pFm!oz$Q+tu7euc_io3|(QDpej^PbroDw!6bdbmrdE*VCW93hRl9eb~Ucx%-Vn z*t&H*(ksuztU4@Qx;(S7G6~dN-n#StQJ&C@>LsTt&?k%{LOcV%H+G^4Tps7+U`3$Mo9lX`AP+6zKcAMGpHIL58N;d%($AH-z zyFYsH8|y6Mg-?!%1cE0=zFc;^R9u?epR+UHeOb-^jz?_P;3YEaB)2_R>8|v7_c?!2 z?Aebs;?^9YDI45!^lT=c`q`)BP*_}aRUk>>>E`Z>jeq)?K*bu13|UoN{(yZWdkGw1ss_b=CO zzi)z$Gd+y$0S&~1Yg9O6hY5JTM*!RWC)5hiZolcS6RHXqf86)NRX9$P7d)VUK(F%V zQc){#kMa$Z-T-T_2b9wnCR`L?XMuE=#@K`-{fBIJbWyB>G`?4Vmx1kxc$7g zTYa+cy8A~X>}tGBlHPnxcy{QHM}OrJ$SjJ2QSH-bhnVh{KZu>94s&7e{B zfa4Uejma3wubOH0@!Ev{&kFn}GE6AirIMPr%Ks3rKI4%_1&&t{We?xACyDh{ z>&!Y1-o@tl|7B&b+SONku5y@0?~Th9EIavXPxXr}zY?ZbZQ?GUpwc*Rw~m>KNyNk% zLDOPAnt7V_K5$&QJ8_=Un?+2{v(k3#Zv6w=Wzuv&uPb)OQj@xCpZk@Xik6*^_UuS# zjmmJZpWfmz!~96z@vi2AFNQZ&D>BY1CEMAnS{HrJ0hNHsM{l;4nKbn9o!T`qM^?D@ za?6tH*9C3I^)8;(3P$32gSue17&)^7NA@^K1V5_28)i&gB*|t78pS!F_b^5L@FC4*54p{J zTK?*Bxv=cs5NomCV#cEK>)OukX2}{0d&Dl!37);ke#`EpzD0H7&C)5&p2vTDC{63! z+WpqN=%y<445kT<-Pa{=r5H;-ldODmXlAlo+Iy`Z9;dH{zT7MR>|CrtQE7Y1I=#0m zZuy_SYU*(0?A4{QKaOWcC76JdcHQ*Ak5oO7!5G}&nU;6v#OH|?Wq!qOEwOH^#Wqbz zp8jAV_p%<9>|-nkr=*HIa!wLu5|litxAD!hwr9JiBurvgY5 zkXbc@#mXdwX@lQyUE{MBXY@=<_f2eu%xfo1x4E`=qg}(S61)=`plV!!qv<{?Y~&g| z834KMgbCc$2aUWwgbdCcbb#zhC{WUxee6y8l~wLLP5w!Kh82Vn45ql-0EK#IruT=FFF55Z15=U!YW}nqw zST5@fEl~pw-*9EC-Sc2#O{yWRa9#VPT#`GegG~f9&I7LZ=EbfF*V`?q`UG@r0!NcV z#>Jvi*E1b^52{zDZ!$0S_#OL1?VDNh8PM7y0T#y#N*lP@CobU#_u?yyTs!~$qz8P^ zq5owYxgjit4cxGa1<0NZM{vs;)SLh@ur$1{NWJ-VWtr}7En9Hq)|vM{L41Yn&D5{6 z)VIIC!RaW#vUTQ*Z+vBqx6IP6?5$-7E#^scIs@vMLDn}y(j;i;1$00iM^jchVmtD_ z+{NIbXg*;Q7P=UpTWiDYH`kfpcS#)o-p!|-lEL#>j=ss_nY+4fF4+TL4c)U2|7z&4 z*%6@C(30LwrtayxXF=AtMLhj>^Lh5K$BDdg)_Hm<*?(RgdduIwc53On(5mp)LA*^0 zE7smvIzu#HX?IKS3b)DY7SE4Jo1xHi^ZK;}=wM0w@nY+XriGcQn({$4wTo{aH96BF z7`Y&zezJVZ^rpR0I-435II^PmcW+8R)AZ>;S0Ou#wolDXDW805 z_knk1lVX>2{$`o>Ao}g2u-iHbI}0A1(!1p4o3g}HSHWol!>T*W1cRQHzhHk;(B>>R zsa@vWi@MjGax9->_$p7FmfZJ!&f%G-_tmVDa1s8eUbpGXvR*M+hL1(}!u3p!x6GIr zJvG)t)#7egoWa&}?}IMrU443$F=XH3zdNU0SBgIQGrVQrO^>&ibe`PxdjIdo?{MFh z^Y7P+&QB7nSk2j!mvOzwb@z&|KZ?&DOnm!D`(*fy@JkZOd|aQIR!?fqZ8cvM>{kE8 zb;gTL>o0pvyZXDGfnl1U@hfqUTv45D@&7AloeW$bYowhNddj2v$puqG-`zJHKR8cx zNvV1}DSFTJS?`S;ci%DVJkw>e@}gdUt9kb1t=@am*z?-zpFgsDIcfd1$}TjJCi4)i^FwJkgDL-Jk;@TcH<`UpDi{5JpXcYRb zd+nsM#O3<0e|byFIGq%48Oi9p3NpX)BQ|9Di4!q*9cwR$p8FNcw&k?Se(qbW3}ueH z*K`KmSo-P9?Y*w=a?i1P9ecN6UBva{Qv1)G%R5_K>Rr9WI8jPHvSnVz<&^f%u~%Yd zcGXPJ=-(2yP$cNu295hm7Z~5FnXVz|ZmT-`eN!1@!`th67n@TV-8LRezs#zsd~uzU zqU^0n-}=jn&(=R;=-PMQYJzoU(c7NOb!A|)er@=&n`>YHMZHL zz_5jTK`aAA9Ll?($H34~)>yqD*6#nG?)pEU;~5w>B%5q6-@^T7S=rAwo9+KUT_4ZD zaG>wvoqHGcHf%OjW?)EYblA;siAc$Nxi1qIzRwV6V7TG-_LA<# zPwxw7B{Oy{kJ`N@d#CxO6MVZD&3?M`r+&=B-G00o)1T^m=ql5co^Li+-~OP)7H$TH zH?zuK-r;{7w&Ps#Myt0;G29asD*k=D%?;&TfDFR_#e9>aN)yqZfU2R&)=2U zE;}(*%{m_xrW+D}>K&?83bREYsyDKnSFURmb8tY?dRTG&CKt9oIoU!oj4PkgzhI{ogRD>c(OZ!HzoKiwm?5TyI) z&Ru5CPCJBuea-)tyI<*;p|WDep6AD2^ZV}RC{>CoDRR%X3i7_!wymvXwcmuF)`7dX z{F~h`emzL(M32mVOYOy5rqsHH9t)o;eo_AN%~LZbdQS(X+yj1Zj9)!ARVuxHw0>Tu zqT)=$%WGEF?pS{M?Agre?vE<9VowIG%PV_c5T)>`+v2XkvX#^3JrLsVDDdBO_qfP& zHqY$ShKnbC{5#{t`Q;bg4zphW(i^gGbK-+Fq7H#D85lM=L$L5$CWZq{jb)6WM7kiB;Q}~|F)mZP#mdmYnzX3w<@{|zs*Bw8 zKYJUT7vI^xb45cLBSS-J*7QHkVd?AdNb^orzg*t$;ta`SVXI>AbhFK$a_WUtY8%AR zHDSAFn2Xl$(Xh{Qt)6Xoixp(W2DP`BmhW70aPi`QzMaZ{4G(}Fc|ho|-e$)CT^GzV z#2t1sFdR6RJ^jbj7AQxmxOA=m(Hz+{;=E{R_7U!YQVuS4PS zzn^0-=xs=OTlD4Ga_Nuvf1aGN%>UfFdouTq{#f?)pj6IG>+M@3W#-1+og?cn?O&Yt z`TouN+Y>E?{>NAE-y>NY|1M*Owe320*#oS;J5BxC3ZLnIT{J=Y&Y#-Ssx61C4}Zxo zesyHVxgx9GJ33DlmnOPz?cVR?cP{VPorUk}O0Qnu(CK|{(N^zN`Nc`nOJmzik1t9) z(U&!y_tohX*RA&)<93!s2BlxrYbaZJP0zpY{L$3=f0T=kRj8l+S@{3;|7Es+FZ^4q ze`kt~y}fs><+gL5FJIQaJR#dQS9`;U!_^n3CC%0>uDdqv=gTiouKX)h*(>s>!`<-q zwaX<17gn8<_&zx#TVv(HZ8x?F-AnxX(I>~wvN-@p; z?d9Lf7sWqbRXMyOM6TTCqQg%{pXDpedID`fx+m34G89zPJo;$o+$lcC!d`p7>k81* zuuSxtyvIa-OSj3^RhE}Rqs=p>8e8tjxvDv9-fNwW_51%nP+Mp;qxE(8Z>ukIE2sX* z{B}6}hEB7Awv;0|6mY&Mf?WMuX_Rcx8^=@qV z--!$AHZxSeU9@FtgvMK+)3cxb;{K<$lmG!rdmN<~n z^{-$ZPjZO=mx)%lR(f_-8_m3ZlhNNw`}d^XN>{j7rA^{L!@l<1kyVe2uYY{yxO&b> z^SJNq;-4PZ6o1 z_<*eb+P+Qm3QkU(SoF2;j*RDRt?cPdxv%6~L*}iy8Ks^2c9PkYD+=|d)7~ww)6^1^ z{aXlMVT zJTaeB)eFCH9o~3V-T7UYMts0iPdgj=nz^$=S5Az$Up_Dav}9F3KUOK+t*y}uO9wfMSp!JVIbdz&mR|9-u^JpSI5tm%(B z-p(rXJXYqgJ7vAy-zKeE-@~65u85suID292uE!V41C4$c-pzQj#alDZrbK$qqS!;5Gl;EOeyl=;Z}t*cbj(mE51jIYL)XRm(U`t+RW z&WHJrVqz_4EPWmR(`wVb-9hW}j8FW$o$#*Pd%0JY{lxEkbLM7<@7R7THTSoKyR9Bm zLU-Bz{3Cbl?AG6E*(B-DoU|(E2)I7*ex~SWe%RWQaoYsn*|*)7FIVrspywkBiZ=#^ zgm7^V2n*b9V`ONUnlb(7!PocYZA43L|K{0S88se0z4!X|>d){0O{w|v;py9Zr+20~ zBz0N}iRSJ8_2~QFmtxD->MWh@%AEJTijObcK0M29foAbfgSjbbPpThJe$V=riGd;e zk{)-&*R!A2tUuLjFe_f}OsZ|_+fTp$#R!{7FO2A}hv_uW!1 zp7*Q5m;HTlK`!S_VPfCC84DV=2drK`(f6(WQwxoS^3k3)e1WQx`@5yvZ!|Q1G|%gQ z@H%64ZQ;)8FR%aWem|u!OzLcgxU%H)%pdvxkM3?>sBwvDzOQ-P)cx6V3=G%S$3A-M z^|w;@k(yng+GpoG-eTV;?{(Wf!}OAQV%7ye%RM>bZ_0Y#M`cb9e53VlvGJmYtPLxU z&tJX%)I@ey+4hhFE42(v4{%KXaOcjC-`jFp6Vt6%yG#m5{IcoR(K+i><-R6wH39b( z7~UE=?cQR4YU=|(vndz4d1?(OFI3tn#+NOwUiIi#>*~eRnRa&c-0NDqA;#Z^@79H0 z3HHpIdatYop~alp)_dNZUjDc1xUW3p((8}^=&in__b_?q(ZxHCRtN7kdSvoVy(n|xAn1I zPKpxkteN7P&w`jwsr~f7x@2HA|G)wbNX!;!zr%=|F}6DF8*V| z6Qz1g{q`JbA6q~1kmw%CmH$*~=TAJj;p6>;+1;C)YTX{)z4*=c)63P*FNa?}?Z5Q$ z(aP+1zh`?fFl>w4T@mlGAh0InkY2Kxy~*s=(YNd_KP#>K>EXF>#bv#;jU}sB&dRk? zO1tvxeA~|LtyPl>FMRdAYoU>+yWZ*2m)iObO|wv5U;Nf>Q6c$lVA2E)Y>%^=Ws8XqatAx~QSDx=WM4>zNa79WJUF;tUPC zSM{n3`M3_0gw0t!d)ej=|MhiJC$7Hr%T(cexr>3}M{Gjy2mcPq&kXmi_MaA7rgnZA zGlRqK1+fXUp=~=RP;th<;IJFi;{tWFe0)J|KyH_{Wt{VFPptH6KWfk8>-$0H?Toka z@+)k9ss4X=?2Bp#xc&EgZEVy-A)E7c4*RB zDG8H*X4J3q6u#MYDM_n&(8*^uh6=_B)>NjWJKRLzwbANl!Co^j;Fs81e7#@OZUL@5R4w zalb!Cum5YY-md@r_Bz$Ko4-}Pzx%xA-1|S*Zq2PU@%r^N{$HwE;+vAUTdx<@^ZBi> zII0~t&%5vEY8Q@=%g>5RHd)08z3ZQN>CmA=JD<<9uI%{J6;iw8SoZxtr`~DVyx;S= zt)PD2o#67rd%j%q{(rmvcYgezN8Hl;3H}$c%-p-U03(mx=I@LT-5|AvcU(?t# z`@@#Yev=>1|NnFT{~yQg^%mUO^W(H~*6rTu$FC|YoxWiAp^^Vi-S4;StFEs8WfZ&p z-yiM$|Lf=N%)YICdz$V4KcAn<37?XA@mJIMoA|t4JCyc+%idphzxKPVO~r=;jm+z7 zo@&3}@tDtYnuzD~^+JkA=6^GZnOIkQr1`|-h5GeBPyadkYIptjcX#Xm9IyX#fSF&y zf8n3%?{~}B$M4^lE%mzTq}HpIYgaK%WKB2Ezo&EIzkSfj#yxM2a%!d4zx(y`@&Ds( z{Qr+>Utb%2-Ie$Dw%qFbzwdoNX1=emV7|ukc~z_I+b7+~nsMmh{@=Uz|DJVy&$G?* z|GqgL_svLhO$@80-S0P>?SCBPKXtS1a>S8Lk)MA>?A!$(F^l&;5Pf;wea}V9=W{M= z)gI`m`N%F;@qk&p*!_liyI}psXYc;6|NnJ=-LK2@_kBDj9sl=L`1_lim+$yp|9X4f zYR-caQosBEf3*LX@AYYu?&Q!b!O@{S6H`mf?-U#s-}j+4{{Pqb>B%co-rw6B|LfB9 zdtcX;m&#Ur*tYuF|ECj;-~XQbwYXUSt<=`?H#Zcg)Es0L@6l1}p8s3_)t6=Fdsl9g zZ=x}rn=sFmE3tE`QNo&)9yYG?&QC-?@#9b z&+`_qd{>#iKYvx{KG)lEpzxRGo5sISH+q}J%SlQv9lhSMtUG(rr*?p-bc6jb1iDl zua5h-Y5KQEU1I!uE8f+=oL;vwH|A4;K;$zojj(sTmGV>a#hJbwwSN5ddi?(S|8<_z z|8ai`i;sMmymR-x&-1=}+&TAh`TTubwxrBCZhp69@}4O!ov$YH82)!$9Jt#2Oj-U+ z+kNI{+Uu&Prx%P3?rIh7yj-m2KXJ4E8RMM~uCOwFeXV@Yqt0&c&u6o@=iQB(7}R*;XQ=t{ zz5kaspZGXixuV-gROxi?U-$Yi?uV>C8Sip*a6HM>R`)Eu&aGinxr>?o(=YY9%F1Um)BpW@|9@Y@C+T}1+MZqh+V(mA-~XD* z!-wbF{GGbK!t;G%gpl0dbLIPrD=Qxjzt-bYYSR1t|LcmMAK4dp;=4d&!p`ovX_uJ$KeyNa-o842vy_Y8 zy+=Y>*?*Q3VwFd!$P;>yshiQCr_FAT?8uw-ao0UeR$7pR$tn?!dH`KEea3t zn^k=9bxf^T?{W6LVwW;K;|?1GmRHx^YbJEA{%O&1;+}l@&)mC3&QmmBKK*mR_UQKK zk4}HNSbZ;k&ZE;`|9CskN^=qO%vky3LsP@04}IqKT517XC+sn)w?De^2s(QB7x(@T+>egRo4QOZm~zX3n=^X7LyD#9LXkr^jbhKO7j~=vz+SJgT&20< zm-eg7#uLB(Uar2q<(|a-%(;F07q8mxdpvuU{iMVDLf*a)i1qznn;vKN@*}(51)+(i zvP;(9$=G0h?cs*9H4bH9h|o__Ucsd3nR*W^!)(k@R9 z+)u8wmaYA8q50|DwEOGMoqauFQhm1huhf)R0xRO>KiaA0-`}@)R)4L_x%D-io2S}#8D~!Xd75GBnDQ}L%;UPL zk~Gt`rE^4gEK56iO<-bt`McAs6XpL-Ha>T&AZ!1#`YD2ukK|PZoS3wZr0WSuPqAi&r~4PDm1=!o z##;aJ`*Vq7FPnC)3X6NP=;o%wKVPm{ZhGRyvQUTg3lC#VP3ouZ@n8C;y7Tdtz&piT z4*AM_Q4NKJfpdy{vds3v1Kn@_az-q9^1rd7{&CF2eRW5yC#Al=G_A!kEd901euLTO zoaQ2De|~$+x-oQ*um9ijY$jcqm+np$(tLX!%f8?7d|vgcgRcMovLyd}`rdt!>6wjx zw2%7=M5;Wv!L4+@T?rHd2j%-$t^C;Z`I*XvN7~=#79Lw2ckTC+{)z>yMAnA>cl-XoZ(SF(>eNqpk>WYs+Qn(_YQab*-6z})GA|hBIZe`7uF}jB^`+&+zQ@Pw zZ?Ac_=T`ZZ2(J%+cS^d8z5n<*R-x!0g@0FbLUj6un!;@u``cs}ioAJzn`(eV( zdydLe{z&CHL^|oKFg(u9uZ|W!{pQb+HiK2nx+*TAH#WX@;NBm&f8Mr^oEh&w>Ap_c zc`v@^&6ms9_Sft?c&UBHoTpX$b5{3v{Amn{)w#a=#iH&kW?dEkqq0iNQ%dIlJd@7S zlsezyr`m`4|1Q@XSx22{+%v_+QuSR{#7xVW09Wj5` z?znnW(``Xr?GfvmJE1z8VkExn9*W+-KrimwJvrWB=83EG1phyqVdf$xG*$LK*Q1HD z_s#O|{Mc;&d$W`7rq^q09CP-)j4suw*O{Xnc0^~@>(rh16a;Qg+4b)1@_(Ph&1$}V ze=4Y=zkcuBB%%FlHouG(w#(~2vFZBOpS2EryKXeU53m0ko*JLR82NLbig|Md-;;Pt zv0YQYMCb3_y3OflkmAB)o2nPI1f6)~QCZUcvVX_?r%P2%?UUS8vgzCLF0n?jEZa8T zgoO^={rb%BS3Lb)Ah3A#wdp^zZynklT-ti#7_V4F;B)sjllAA{=iXQ-Ek8>yL^eZ^ z>#uh3m#cyMH}2;CwCen#kG~IW&Fgv-w9WO&joA&qeJ}0weX~2?DRCt?s8rl@{`kfz zT>3>X!kzWkcHB56=GI<+Y?HWK!-;RYLd>%=xwlM+j%o7kR&SHBtND>E|9i%d{@HI* z7yb`P+W2Sf44p9l>m4yy!md1Cvc)we__Ou8+L<<1PZpQYNxLU?>r>&Ii;BMQ_CD*- z+3o1&n?DM=-w)KkmVJ8F^w+G@e!Q4`(crkl8Mlm! z+oE?ie~Y`ht1mSF*RtvWpOD;VN*Cvz{IGn|eo?o`MyXkS3qBl|u^DiQC2b zSE0-nTf5bZ7R_5HxHBwPVbhtOGnaJVSM9WE_|=x3m8Tx>T+Q(H++6Fer(@!_-R(HM zVa=Y(&h^)8nkUsijR=}m-~6iE?e+Ri-5%E+cc}ll(O>s zidL5hRBkbu%fDb+{NdEE5#<+@kG8J;do*Iwjc<%s4pz+yd8%CGnj8E5!onx3@0DbU z=L;;_*3bR&(Z4BjUSFEx>Q}~Zn-rOot`_{yH2cl659@<0C+;o`3bPehTpsXVUupZB z-23fqKMuGqE(Te6f38EyzohGN&z`^k__qEHaGs`5cueh{;Uind8u+2F^hllEA#gKOcRil=1}q$ICT5|zi(@U z6(pDOh`G3ND7GAvn#gT;Z3>T4^32>j75A21-*@efK#_v}Znu<9=NW7+(-NCba45E1 zh)~{i_&BR-^N9$iYpri~6mItnBJLSZl zB`@5oy>5row$ozUU-Yhg;t=PxXwIr-Pd++4xhr4wWFr4twuypH9Ev9EI`+KXZ~x~* z{eHFz*)C4S{U3XyQ*O?DbLoTq|L6Z}{{Ozee~uU5lcg%BG*2qrj8gn```)*0=HFJt z%2z#^JyY)Ig>`mUuC+(SoHPIjT*fJZ$bhf2Tjk@z>-+I}w$*vNUM|b8|9!jZ=y9;mT`W~4Rid?B_Wk?y`u>H<_v&BFZol__$=weJ z@2vlGf<1qOuus>Xx+l%@HY)nQH^0lD@|XYh_R$sd?#p|<+c?3Y^|ZL~)-F0w|nC~0* ztaJX4yYK6^ACc$&Q2TxNecPFcU~20=VR>(w!RiH;t`DVa7Wqw#ObuH4RrBN<5wHgr zYEG_+n?Ez#d8wA*&%N`1rIqDuE}AsMppb31XkNm~hx@)uy*g`@UaD3RyQ!%2M4huh z?tfpgC!Flv+bc3NU)sK}>~~A4)a)$sGV<6K))Dik=;G=;PtTthbl2aHtm@f6Q+4k> zubL;#*5zt1_FNXZa{Qe4^AP??(8Ofnbz%p*{-&~bY)n&J=SO|}dA0WfM`cH>!ndG5 zZ3?#-Z>Ua>+m(G?uTb=U(P`cPU;O{4Jks_#(h9CLB~@ zf}`vT+r;W_*K3U@t~$tQ%sB3Gq+!Pw|LTsO=M^8m{kp#2u}rV}xb?k{AN%WLHvEXb z|La;RG)+$8nY30^>Gbps+|?J)-LHLeVf~cj{eRw_Y5_PwZ&j&D6eNgk-)^sT+I@1&0D_Se^OZ$9#=W_O;gR) z(D2$9&hoo{y;{BAr=(TpgtzCE;7N{~cts}$AJBEu5aEc<+&@WwfAy0K3*BQ}wtbTS zPPOhShj$#EWUbENyi{UE>^}YIb=&8xKU4i9MjQxZ=lfU_c4N`KRxvgvVEFTcILy?$=M$qOkBMrSVj zS@VL6ABPm4)s86>8x~J^^s93k&xMD{V2?9RG}P%j5v&d7%!+Vv1C_gqEdn4%vOwHv z)X{Tcmg1*ZYeoIvPVQZqzqk79Ma4b#HoK~}Z!rnVk34$j&92`U8GFK>U7P*FT{>od zboguIm2%UU=e^CUlHXe$zFFPo-mX*2Wt>1}`?4xMKVlm2$Fs7KMKRl;e zDG5ejex=)6c6z&R5a}zaS7VA#ob!)GVOxKPjoEZ=aBXrSK;Y&g{pqJCH8g%oF-f`U zayL%moW!?;>3<8jmLHv))+ML*_p_Dgo5@EPN6uTMu4qvzxbx)=?LS{j8IPt;)+)We zHgf-3zEtCYIWl%i;U*8yE}WWhJ~>5d_nh1o0j7z9PR?#mPV~QzJ5i+b=Gx<>3QF$I z4kgB_O82F5&K$n&aDD0hvmgUkb689Ze_U{H+0?S{YvcMq{kv23{cd*aiH~M~GOyXfK{~`PeFfn~PT)th?TR>Q&-Z_PFZ`MVB|)hkngf zK3C4zvu$JL)zl|@qBw6ySiAI@3e7n9Zk@yHn{ME`^@_Sn-Z5RppsTx0o>;D}SuOYU z+Fu{}g4b+{mz|y{ZBmkP{kwv7qU*KY<)*GrmL;#B_nd17H_ydoY1->t=K968)m%8- z<*H|W@0qpR52cV=^(?E~(CFzoA@oZlW^&?QR21%vQ~Es9&ff&-1Ii?ddr?|9dC?_BvNPVyj|UO zC~>xB3#f*VnjDd0{prBdoos&Tr}y5pRkE)t|05|Kt5|gPTUqZTmRWs!HUFAD$~gaa zmBh_HpSWn3vgZbm-n>;;dhF)L;j69W-B^6y_WJ)f_J6-zHqW`Sq3-XmD6fjA+VMYU zUEkxDwddKa>?I;MOgyWuuJ*hC=~%Z}{D&&b3EX#=oXA{0ciV;y2hZ!gOrQ7jm0J0g z5QR;Li#Li!m>#*RtYjU{;hodQk{-ey7L( zIoD@jV`Z0p(f0Nqf8I~SGw$tE_}=YSZn+bxW7N|lz%((}<=(E+)fYCn-P2yTC)nJmg;QmPM3o2THpV9F8pz6a4 z@c^N2AC9AOF5d+rXD@$Uc~DSvUDEGkEACxfH2bC-$3jo{l!p=vZ+q+Qbb0UtRLjbA zl>fZ@zOLMW&3T4{mXMBE4`_(Wa-FqIM(%v@r|E{x-?CahxyT147+3@(wMo`>oV2d*Gw5OPGAG(x%Wv3Q?IE{Zz~o(d0BNd`1P*(U2(}N)g@oAwaut0H?gynDYN0~$T1IpnZD2Ti^UN& zerJ{mf=&vbuB|=2^4`C1+xLIlx?VRdm{l;+i_2~Q``Y)$Dr=|5aVmN1e3Gh|xZBY) zc$vbJ0M(`MuRqcJb5?9(wOmeU;10i|mqX)HPK&>_T-Lsvwe`f&Rl8Yg^!Mfb-uC+G zeOBvtPA7i+`K({_dG>m(nlqcuo!>EE)$j49)AyK^t}FF_<;l9)<@@%?w$(q*-cfc^ zkJnh-XR2YeM0M>IckN_(srB663Z>KU-pVR=$us<><>!}mLArejSI$qDR%}rdo2Ysx>GCpPsfntO4mm#ge9qcGsV{%u&$N>|Ho64? zbA+yMQuq{^KG&43V~%KGM~-atxraj8%)FX;dUH>@CMj&6`ot~aiNzb1D2)wze;*un zP2t>fK|m)^?2+icvfp1H>6Yyik#wo+c1m%4RebJd#m%MR9u1$KPLH=-+tD*mYUN$w zP5Ere(iyjZXp1jA!l8JDS?PYkVct*gt?zy0OHAsVD{!WlHOgbx%|nltg$Pa0GLm+g z=FlzZ_=L$$dE;R<%f1u4&NT%b?pX8Z!pp*WQ_2o<9xQldGV7R<^s~6xs!ftg^XDsW zatVtmIQUw%z$r;r@6I1KdnHTPCui9vUS{~dS?|^_wUhN1U8i?x|9aG|&pJ^(uAl8% zi*4$9(Z}q6@BSvzk^zwY(PXCC?0y^g-G zRUO&!JR(cL|DlIs(Pq{1j}F~>0ypQ}Tl_hKm1*M1x6@v)<<$`H*z<4dYx8;4_fn_t zdpaxop4OhI)E`*KXlfBEJarU}gRZr<<# z^~bL0yXe_{da9@(6soge&lIhW6RbQZFWGKh-x{#hVxhb31*OK==~l|8ze=%1X?!^Q zY30-EU6&pN?T>Ofckz$##TU;M6*nD`;eMI7``Oy*ai5-r@Bd{gdS1Y=L&uV}PnE}c z+Lw(lr8U?UzMrnG`Mxgg;90QO`%XME5Ubzt?~3^J4NnBViM|p|TIal?wOfB*1k;qW zi=EqgPFT&_ez8xa>`wmGW%=)l_DU?MGL&uHS}Hf&-0{htV)wlNSN&^>*M_}L?WlSC zZ9AtD_xmp69otS+N}KQf`APd}W6e3^Z%?k>*;JY(FKbk5@?3A~ZiDI>oWYmHUDnO> z7LZhIsd7(gjEbyyUjNP8_0ydRYW>{PY&NB3N3Y^!R#5TL*}W&W;-R#^{okHt{0rjh zZyl24KFA(0zw}!6vagI+z}<0e9L-5ktqp4FVD0obf_lNAh83u71#WGC+Jge%HUqdN zdtrj$&rptq_aMTP+fJmLKQxlgS*MMm?j#onctyP@W(#rZq4VjhA#ii zoH!I)+@ggWPlU_Ald-rMdCR(yWg1`Zw^tKio}boiY;?7nUytFqqKn>-h~Q2AC+tD$ zFJ!Eab}?HKa%EUC82h&nh+xD&xy_&9`y;JVJ zHOLGRg-y*dr^F*RO_^KqYEs!gxp~`bFG=RjQgT{d7Wz5t=9FV5N7zmT*KhHwi?*5FBG3o!hO={xe84D=h}U%3yUOXt#mnFwB*E%HQN_AoM_|@XIa{^=jdJs1JJM$sE4L@qI=HfO^hoQ z?p#sYq&GF~9p}X4j8N%}jR6nOb-l$iptqJE@oA$FO}|GclK(zOWm83`8{{7&sltvKkkbNM`d%~Ia4(i5k4-{toDwmWuj&bp&TwwJ>`Kds_j z6sg6eTNJiU{OVHE+gn@rbxpY(U0bFj5IN!dnHXuUt8x?f7yh0*+j{%cZztL31WWIi zId=B9edLr|wZA8un*N^p=d%6ZVE%l~*l#;GCHU~a>EpXF=kA{0s~;9KODA8-c)qRn zJNu{EM_ze)?02oHERWo|=|;q_6?)55Sbl3&bca=ncnlY_qYAd>g2lnd4Ha` zui07gNqM*ZPlt-Kc{K^;-==S^E`O5$WaIiemD9z~_x)C`|NXUc->&n&f8UDz|NZL| zceAwmPUY{m_iHcjD31TrTbL43sNVAFgv9FmmhPexPpg)6Su|(A59wINWh{`V{Y{xW zUv=S~nQikQo&MUiw%y#0`$M+K#K+yQv}B&EMz}u;dR2A1=JIwSjkld^&&He2|M;}3 z(z#4K%Y||JhV5&kzuw$v@LByzy?)WJvNiVwgFfiq(DsU&wARPpj`Q1Hd6hjpZ-kZ< zzxsLE{_o}YHP5Z@?tNN%{rRq@yDPaSvYQ=ixn+JYbGx?dJCUS}t`lX^yW4*TUO&1; zB&PbAZmr^7L5C+I38s&i1;jj9z30}B!o|ItgO>QLc2C*8c3I_d7tUu~V$XACJ=pXw zdfUAPdv@C{K7V8G{5=a(Uvi4v`#JG=-4$Os`@b9Y->!*L2@hWSsr})B8KWgtP-wZ+{Zhc3!ooQ=~Fq(=YSS)ZofT>t0*UeZ8(w@aEgj z_7jO2z8aRzk60$=@2}mSmZG`&_qW^C?kQKj>WnI9ZmXz&Sb42r-Jgrfj<}U!qod$6ob&{@auN73Xq3zn)O_o9l^TJilF0ebe%v5lJ_nyx&qV z^Ywn;pU(R(7c;kOubjE}&)VDdWcXI>2 zsrR_^CzfZ*3n&6*JD4q8xp?Luk5b8r26^drOo0ufB7n` zRF|D1dTZjN`~?dyXXTyJ|Npclx%!rn@U{uQ@UK!yV?{O_~B{ z{`ockdmo|d>lSit!_I>9(=C(FTE;IwyVWCWGWV1(mVfW+yq+Yp+HtGontj3{{ysMy z<}FIz`0$9-tT26}HeWp@chBt=$NBfO&M4pY+uJG9AbA8S55ILN>3*9&+1U*+}R z%l&P?hFtbPzV6qZ1qrfB?e;T#S30PiR5(6EHe$ZaC&|m=E@gioEqu>^)VtiTXvx2< ztNf>8eY{yFimtsER8jo@;HfvuuCqqnS+w`is+~%AKSeKRd81IYLS6rFr1V5yhW5Ho zXZ=&yRh5^w{8_wDVN+TP_bJnD&-Ld%(YVWRu4Lx6{iykth$qgB(-*$q!gxLZh4^N* zN~TWDX`=RJFYW!i1vk&q{yb%I_UyCg=9e19dA>EDyk=?y@4;tZ4Axq(|6RFI-Ligh zw!Qkr@0SYZ*_>K>`Xu{ALmn4ByUbNd6K5-LdXX&u`^No0XYcn|D7h=~b>DYm-oJ$} zrzdrKSO2sp3+y{$>MU0JdmZmI-Pn~V;c)@Q$V?{n=F zt6yl?=9icAb-E}=%ZL93O!;}fpIolJ(zGf+|E#|7)Yi!9%PY-ZA77_%wq1KA-&#H4 zy;+;R1vpP~e?Plx)6w_gT3U?nLf0eQ6`veY{OLpTp&t z0h4ah`>DU)u8CdH`eO3@KTkjtTcBAKWx0&N#uGE|U$M5{VEF97tiL)d?45pXjL~21 z9)Hb3DZK5@liTwmzLp#6?h}u6b+MQz`t4la*N!;{H$Lxu$2f7XnEorH3r>p*|83Gg z{dH4SiT$GvnxcR~NP_6>sziw+j-nl&w9L96S@hYek9jbddFjxaFkHd#ki zaKGp(NVvXy_Mwk|PtCkDUsm^0SKjp{_Y5v1v81@~n*H`(NKMU^?dgk)Kja^&)8;k~ zxNI|TdF1+EYn}II$er!$-7IRH_Wxj-u+Z8iMK1QArro@mm-+v%;{5v6`F=JfmNl}I zV`Y=%q}S{do>RUmVcw#7HwqTyq~?V1k0*YF}-y?H}LWU09HO_gaTb?2?kuJ$vuWd~|*CHD1XQ75lKf z^o8GZw={KZ>OFR6?Y^wfSN{51T5Ijt-T(7o=0ux!Zbe^juG#*y=(*R|Ba;(ULl<7% zeRbItKi=J^@0ux{ox1t^)qIxguU<~LZ}ely*Mzm!3wM0+^xwDV{7nhJPd6OzEqoYq zMysPIQMl`bWBF1~%g*wJOS*i%VQ?uVdL@(NFvC%K#FPW4N#{QD#5`k_af#@*7_mVI6OI_=xq#|M=b zcb~}E_0;wex68G6DW{|FJkhMx6{yUZZo!{FkH^I=B@DVK24dap~Qdc^DE_|9or`^TRgM+i;}vq^j^15u}Njo_jZ~8 zyqfNq(sC?hv2@18Gj12Udjw|1xRh0xf443>#gq4F<>_03*4FvIml*Fcc4dipyXx86 zO`7eQE_~bOm0l_a&iu zj&9-;wHI8r4>dNCpJ;k{b@02V8iu=A{wlCUANM`yC#zI14VrXcy!PM`rRV#XyzaR1 zDCFd(j}F|s7dWNNZYvG7Q(}+KKQS>iH&&s@uQ9TuvDECl_WB!rpG{p-)ayI}tefO;NA1EP_a`P-j&w_0%h2viSAWsu&@I+cBLs03BTH1u!~I>^vg;FL7qm9s zog%o`fm?c_?Tl^Ax=m}3U*A$Gcb_BPEb`H^WScLMFN4HRJUp(oC3@ZRq*=^ZO2j4w@)^E2MpR-6_ z*l2Y?pbb2Ra>2yo#`is+&sE1RjhoHoa?AiUs3X8M(J_UG89a|GAc;i~JTwAYHlZjW zdDsEGKEjt*DZX|`@dKCi%=aup5msAnuKpcx_0YQHlRB~%hMTk5W4OUHg&7PTd!9b< zITgKAcJ}Q{Tsq&*sV(I@&o4dEclWVR*FJBY@+L#eq`50>-Re`h?+>;r*T`c<`LYsp!C8*N$#C z1&4%FvqK8|=_%gpkH}hoyrTNH#?}UuU+vYdDW&ac&(YTVo8l5T!VwVSqc=@zrf zoh1e9yj`|wuAQNJ{H5H?X|2aPWTa2;G2X~nUwmo1(u+lFmb}Qiv`FdAsgs=bwjIiw z-o-ueb}c*V{CPrIa+zj2ghQ#kW}owOTAedM9tP#+vD7 zeTbbTHL-c^c88Saq;vk?)-vmMEu869qSNlW;_6;m8Kvmdxt=SuBxcOf6WEz`GJ$2{ z<)+NzkQC9|E^e8gdf3y^ZKZ2Utk&5(!b-%>0x?L|em*rFmDRX2u~=gIpNUre0{9*S#mh=?@vkr8` z=p7C^A{kS?Jf`7QdilfUNw$#{+MG{2OKQ8`741!U{jm2E(;q3 zlwJ4C?tfYP#Hl*z@b%SMJL9Zf_;P=Vy__u?@yP7Sy9MHXv3yEKv-c^sToCb?@r->X zXzr!naRs~W*DJwA%C>*MTt08}x#v#!UpH{K{Pt6~w7>Tb-{|JmC|vtmEL&dI=)=YY zP>`(M$dY=blIQlqectc1ckcexc|!L8N=XSbBQ_=FmJ2E$4OQCNRw=0ZA7Nf$$fIxM z#NnG!!}>4Tgyrv#hBJaOrIg5`a8VgL`FvT zk0*7^P_=>6TOu~pvr0)R{eR(Z&jb^_UVPq`eb>T;ikoWW5lU^ICi-T)oainWIe8O@ zK4?UhL$T#o#|ioR=;c=|x0jw>*?*_Z@A}bd&2EP$iZ{01JmbW;&8lXi{3p?GOu=rZ%|K8Di`ju%%&o#b@+tv@sX1d?T`o7#m;~o9!!gli_ z=Y4%WvE(tUf0o46`K+KE6Xor)uJCS@T$<}SH3Mbqg_lZ8!>+z^ZQkU$DsQXze6v|P zE@c(rzZIJMPS(Emi@nx&L*!7+{xzCPFVezI^QZcDdMOue__|>J)dg|C-q-l8;9R7; zF1zzYXSOAOzDM-VQw$l$yJ|F!OB8&s>X3Q4wkUb^pVsH5-|Ms8bD|3JZvJx;k}eI} ze|;~9(saLf4_uC_8%XCUH1nvuPuah}1yn?sD0al~F5ukyYO`zJ?uegSO*_M4W2d+( zZ2G*qwrY)}x#hWp>jLN7cBWc(R8Hh&S~g{wm!wWvhQ$Pl9NVrK%?YV5Usb%`buBI> zb2Y=4HPV(DYIi3jUOO`gKLM@_1;5ktAs>90-QQ_No+ zogbRrn^tk#di(QU!I{4ItFAomx3>$Ozbx7CUf{bYTkaZU6bVGSo3I>`N|N5rYG{7` zZT_#c!$rA~cNGs!TrM&3`aK@)a@L^cAAW6|{a9c}^>1(_xu?w|JJQKjlS`jZV_VM`69a$s_b75OPOLt7VWR7kec3$%m4%mMXMdLo%{>18ZprmW zY66ljZVI1NY#O8vACsMEx?ZJyU-`|n%U6~BU#`8vdgV0-Yil&8)vl*cvX+WlUW*Dm zzHI7Lg$o{z#abo;v7r;+oS(RIYtp4VJ6FAkp6oa^eRJ5Qo>cuwXO_t=pZwA_p0jM( zw_PDTDnUEWJeuuGks7_jcXUm!7VR|GgF5y;w?&U-{FiiGSxh^G}Vn z+_dBQiM?DCdxI^v?tWLh$H#|T?Pa(2@#LEV9X;UEyxQ%F$x*ARLXFP(Z9(70uV?ZFvx5dHI=t(HeC{x465T zJyU$WOfD#0nW=Vtsb^&Ct9uF7qBie&_iPhV-}|ZT>;AIVYN4zxkG@?94ZYh~TK7q0 zV*ly=QXSvd%jpYPvfh_j5Y8|9WA?J>BYP?@PgLhR(Kg931>AzPIpNTK)z;BP@AS0w zN*#9&=U?j;xT!mP@#4w*q&_R%o_9(u^y)Frh{6Z#BC7xpgn2Ib5mb1g~~yXQh79xF6jDBlir#zitm96J z!qkiVT`!;ORI+V35jr)bWWl4dwJ#RQPAf9H-J<)RH+AUL#UI{%)6wzR zp?%ZrcPJ!tHwkb5m^)imn^9`3%M-W|< zJ3jevG^_E%OCejwhbD)9{5Y8>F!My$KgCbw`+wifS2U?OIhRc-`Nj{0P0ieU6^o`A zEMEIXE+g>s;wsT2CTm`$XoOi>W!7?T=`bqV^h2llRZ41v!Itf;O50^m%wmtaa(~@k zwkQ{OS>7!#xF+(-$eS*x*_61zRnqGrThxMi0zZFze0<+I<3rW2m&+Yfc%-#m^vS>jhY1mX-kF9sKjqdp^KYE?>?)F=btTp>8 zy*H(tzkhzAt?hpD_?P8WzE)vt3 z=<03~y>9uU-nUn)IStdVF47bD*>3;mVZVUXo-=dJUUlr*@H*o80nUvxW397{;%hBV z?%cB7Mk3?>HkmmS!@kMIM6CYUw`S|C|0bW`TvfjO^Pb-824>wqcdyCR$4;5{k2=!F4sK! z2`AoIp1$+#O{ZVhW#9XUWLNBtwN?MQYIA+O>tfOE?lqUqs}&l(g&d!Vbbl>;yDa}) zlg(7$j~fF@1*gbZyYVU6f4@`wU*D-o9XA)hzjVei z&agLY*D8mU!?wG;BR?h=N4s%NeEc}~(#%V@`c_|cm6TGN9Ve;%E9~Ocgnuu-Px$b6 z=eLd?H_zJogcB!t^Owj)HU;o1?f-Cy`@g(X^YlBJ%}!7DU7Yc7YQWjg-j+O~>Dhvn z?>ElmsVzIBdVF#FiH{$*z3^!}y|$v9MKH2lv+Rz_{~MJPFV1pK{<`kCf{{~p+X=p{ z3MN}-udVM`6XZ3`_ix#+rObw|J&x}lUiNcrPwn0Q^~0KDcdA_MEVfU%Gy^n${Cv9U zGRI(#T`#gG9#;z79TFPKEvtFlPLB&*8(Poo;&-A5GN=(k*-)}t?MQm$@uhS7ZEwg=S92CWs<%SmW}0v8RQ?4IZ%U}T@cFd<6S`z~ zhY4nQFO%*X`AyPFex^#hy)WCet#*3Cklrqy|Fz+SXz1Lx$1Poc-F#-v$s9VkjxO=UB8QaONY`YM&VWWs^SGfJz$3?abJEEelwma=TauV=&Mvl zAiuM&pe1|QZtq-yo2lz7LQT6r&ti)@B6#!W8s!`FcR6rhj)V4?e`f2H`jmB)C z(SqdO6Jo;rzXSE9CSFWYFltLxxm7oR>n->8Eq7aU4f;zMCki@cyb{=%a_x)d6Zdbc zpYLapmzlh)?rGuEnZi-_)i&Q2%v^M9d;G_RHqM`}xV?4dn|5~I?-w?c*m}j3c6)C! z$l1gL>QQ`jeNryJ@5PaBU#>PmOW%$1Dsr`dc5q%jal*p&#;3xkt<@Hu;r-g>tG+Vn zDy0hZm-jvRCGpVp*akrpP$;RfPdx3wZOwA1if^ahiz^fMmk3@{$`_3kbb1mIxj_Ot zJaeHy;AY&q^j51WZ?r2`G0BPCvdVt5sYFyTFiLL!!iiQ5C$6SmPx4jl-~lab=@D>B z?mof(@0A++#O^7};+{0z-yZFEfExy0tV0`^|N5?1a`@gzAO!j=quk>9i<08|<*{mTOM2~SO7rn?7 znW%o-Qu=HdRBu4F%fD0h|9*a*Z=ZdA{@n7zuiOkFI?bckEx+_OwX&?Em{;lesjL#e z39|a1GL(v*nnhOyC;l(YzM5_b3Qfh5O{*iG^w+)Zo4fjX+~=E@%ht^cK7M?yz|WML z%iGUZ^S%9Up0WAUai=-mwRg14YJ)ZAv_}Z^*_`TlV{gUca?Bw`KvJ>gn#e>~e!GvB zjwwIOHEP#1ufaa1|Aw;|JYTd{O!*n&reJiayC+ehXnlu{_gs|)!n>R%EAE^b zxwqW`(kQ#5t#taIsDjZfiQ4zo_a{fs;!lIMjphkNI_aboGhE>E?Gcy!<)~l;9tU_Q zIx%(PWS4@bunZ#=?Qc)C<>k+CxVV8=QrRkQ`os9x)lFD==gfujFoPZ{eY*bs#*LjH zjhmV06#SjPb7QcEee~VQj^8)$Zo8KD?NUnluRCWR+N^a~d~SB{62b+FAVlwc1q^#WnccJ7VWFgmY-TJ@uI5Vm`iE# zMz<%&`|S;%hNmA&OYjk>yq%N2RM~8|?!5HZyJptD7CW=QHfPsE zIo#dL&*#Cb5J^ekKxIRi>~`7 zUsP3djw(}KSA8k-Q1-@spEuTtweD$~HR0~9^Kp)=rrPRfgw5CLTl>e=*0pidlG}w> zJN};Xd(k`5F~x+bEd0o z>8r@f;_OJ9%s{WR=lU6xyps$ke9B3wIy`fBjFiAm%_pT_7CvY8d3e%c(kJg}`&_yY zGp+M|{k-zNX{PCtyOZ^fwN|X(_IY8@E@j6KnS(b!2W-)aOv#(1ZnOPgO=`y)Jn`iGHF%fHlV>|_icGxyy?DdtYZYt`PwFnFH+3qW@a{T)?%nB? zhHWSE<^`u+VvywWx0awE_5=&J@=9di`&EqguJZ{k__vN!Em_nmnCPuFV?X#Q~f z9~Yl;!6NKr;>C=V{deQlpD%XeX^)7vqrhjGko^5|(CfhtzY~O#rV-=^l zKw4t3VMmV|-$d2A2PcxAud9~-es_E1A}`A?0h0>;-19xPfA)2;FG|0+iq0&)|6yWU zN6h{6HvR8Q^{jG4&3$LjDSO^8#%v;6oVK8>!B18BRgv5(@tq~SYWl(Q8{Vtw{9VTO zhUbas(ilGB^&42D7cP5VoHY5&=I+Y2O$$X97|$>Z6o|Y(seof@oK+!n>h-g_>9yP1 zUtY+X_m1cCI>nw7eD9wbN{2a@f#!agZ9#KCn=6f7pUiHKy}BpVY%W*tiG$Y`cf8qo ze)DOOJ?u&|zfLU;KDBf1UPXVOsvFl{@+q-v8n;_>uhOzyGj08wIa!YL`%gsq**J(U z+_ki=_r%{BdmF1JGB+N7_UTSxvPj|E4e5JMWULYRdAD8P>f@vSUCvLYDDWPO+!xfk z#BYXU#5@vVh=hI2t;x_A-cV6~&xO^evhQ3D0RHg|N0vh)Sy2N>`@@3q3X2P-^ zcTa1_1e%J!Tv~1%VaBijtzB}4SpJM%ZCUz7hU#YEiKtm>W@mI~uVdSLqRqGaW7<+4 zF>4bU51wstjVB&*%kE@Pnz^`RPS4UgR`1i8Csw!Zk=t`(&{jdq zu-TLAwyYH2xo`f#Rgb=|7L4pzbBp&;={!rvve@E@H`l4$X?*!fsd`6PuRH70D=l-L z`5o7C37fNg!L_d&vaa-5>f6TW9ACJ->jv9?&e(LFnCR_O*)3lL+cc?@mrX}zQp z`{MK0`});2FC5}8>u|Xo_F&@XgH7#id4=LK%(~ag_Z8Z+OJ-c`zj-;4cV_k-{+PaJ z8<(#M7VMrQo3-QHqF!s$=m{l)cX^c-Z*)!(T^bN|s?|$pSgXXAcn zw%5-onazD&J~}&s$EM}Pp?zUzUF8HU{{%Tk^LM-nh+;~a+VSRE*u@fImpqr!g)2JW z2}By!zO4RMvmHLW*7f7Tu|~0tE3<_&1Uc7c3K{b%h5vRu8^-;$+UUmaU8PP_-W*d} zJ?CkgSY~t9WN!6qN;e)FD6xCBCYt20=$6%OGpYX8CjZpRLAzMRf9AZr0~c%DyI0jt zKh4OpIw?NIB&nn3!TP)+ft?;Nl`bebO+I*`<4@|HZkg3im|HVEEq&a}RubffC@)2g}{FW{&Gm%i%1z*Sz*QlLFx-Ab(+u8z?; zJL4wbe-ym`ap+oso9~wBy-?n?Ur#seTAbB0rCG0S%BH`*s!+7EW!;Y^!N}_6Rjcp3 zy%ccK{N}aAToccSalbqSnjAF0_r3$^v`OQ4 zaT9Jo5&!eJ{r-QS)8GEu{5db;u7+BTj^-?P<;}GuF-Kg|uD;Bz^fn<1a8?;|UHI@Fc~*?e)J8 z^4BFOJhs07laKwcZ9-mqF#|}cFR#+`-P$dOg1Q5)Z>>4P+}3zPrr`vrMItDrq@-RW zb2L7(`DtEVPojcRqgaOn_Y3yM6B(NXE9-V9aX0;WcsP0YYVo#4(28JCTcs%4K+{kUgns>;{x?Y&oZ%zlaFtDHYho3`= zNomI%ofD_cHfiiRacZti#Jc5k&u&cSVV(#Y>{4FAy6~gxlPi@u_EtBVV)HMX3rIp_ zob5SW+$Q&(kYH14hB?NlEfKuxooS+AM^7TCN!rn~jBBF2{iYi`b3e~p93udkm94z+ z>zAywwRzpL-J7>A-KE_JYQnL9xiIgxS^loEhqHx4*5I+h2Y;w_E$Tsk#0-nW;z4&OP#N{k0|C^CEVhR>|9z z@w;MT<>pVJ-p`IsRsMbX$d%M^@ePtKq(M0m)ulrQ7Sm z&MwYuIb6tX9=wQm`E1tuzDm1H+1Y|m!tJ9aCN|4G+66b-P$_%qo7*dPoVstT)XiP_ zUG~1&@~1acmc>2E*X}QxxzNH*!AOeJ#qLA6xn)Pp5|ikr{G1lvPQ3&ehmcUGlSU8wGX9$mdT!H|1Jc%v!xu7X)s8ITdkndqnu| zxmE&|F@lkSc?w#VA$K^>z7U=G_XZ~@7bZ7jE&oJ+PQIGoF1P9OmhBe1{Pd>e>F?JL zh)&Ml#@^~!z(4WuO{I=CmxP}enss@|UsxcxGv6fbgnr29KS6x{M{h>C+^fz}b6z1^ zeDdQ9#iE)$x>l1P7HQv;b#%EF+a>!w`IWM3_m-@6`1!rhHZOl0W4nA-zyGe?dsY^-vN#8`*>1Ui+d+3) z-KARvzE|hu`3JU$M_UKJhDITl)DMBS{`l?m09yk?gNp3P$ zS6rTX$uQrEDYUiXZkxw``?yCd&$(`FpJtldB_cd2JT?A8N!8as?9urRC(iK;9zA{H z@8!c+8c(d)DSlJuL~*iiQv{Dv^NEZrf{|Yy2+tRGnO0xD`WWYm6~68YpDx`CIO2MQ z`$b^su}z9wv{r3>mEUlJQ%?8oTz`j3_s$b9BV#>_*3@j2%s=`&tZeb3RXlq9^P>b? z7afl_RXiSJzwy1R*dklWEZnC8T5&W>HFVV*{|%E}lQw)!>xjAb?4I1zxF>qc z_*~pLT-+{qov0P+;87~?KCx}LNson?(9NEwikrN*>q&$vY|@ODsgOHvRH5u~z_5nD z_xf5b`JxOzra9rJiiQq057_3j{C<2X{l%gitfES{@2p(?Nzl?py4n3nSunejGPw8Y z;&zyS%Z9qFeq}#ym$K>0DtW?NPcWY2)7N{$I8l3*)$RV`jxU?fma~N#%$Er^xG_J< z<=e5_!b;cQ=wCFtuqfO`?n9LwcmUB?UP)PCr?pF2c<@)L48hjrdGKMerH3m*O|{R= za^uE1EY^2h?DSWk2NnH|Vz9DaN=@l?Xyn29w~DO-JFlMp`s%{9BCY4AU+!{9Id8m{ zspGZ4&2qNzu&2iiSY)3pob!>BQ{>F`Eh{6YJh)|jmHqc3k=6IF?2~tVcV?O4z8L)* zRpztzO%1oH`CnpNn%sTjy#4<_{PjPaFL3#`JxQy3xAXar1kg}{j?1wPJyUPH|GH*p zm7vv^LP)!A+W?#>Iho_IG&hex_{HiOH*lm2y|zFhWi4$Ckq z`SYW2=hB}bvp@q2!WoBMp3MLEW%+rV&u9AU|0KWQ>fQas?BBod`_C^og4AdVMe93q zl5|@p)qiM~mpJ$1T=~Akj`jRAZa1(BQdU0*{+OqGf&K_Fhn|oMV-P}3l=uJZxJ&PNTDbHV4 z`K24=%n^)KS@Cgih?Ddone$2}hbBdbybFz-ufARTqbMkmHh}WwC*J1ieAjGt>-C-Z zId5O+?H6r=mT!-}xs)hBu~c5l_7m^nV_Xycm#zLDSM%|xcwEInnJH_OnDgrcUHqbX?95qQjxA%DDCorDBDX~DR`Km; zec8Xm+pqt6bn0WCvHbq>%O7@eDTTKf-uTE9t59^MRmT0vmV{q-xIhgHur3Cr_m;cb z);6Db+!|Gx0Zr!o` z65zLV>3&P?87g|~WNyx1>V0nUs~rn&FLu4zlx_NT+1eRAk-K#TEMMk^?K~y?X6;jJ z^SgS#f^V}6>||7GpZ+?v^I7H5UpLlm=9|d8XZ3^KHm8ehdB6kIH!ttzk1u(2RPAb5 z#l+9SOtU2Qqh^NlKi!b+apl5>#>bPE^KOt*xoVN!$NkFpM#<%g>NZySZ71ACpG`YH z@!qnRkXREZDp;I6tdav)TOUkEC z?ue9kcyi^A!UIFY3O>-XxeP18p9kXaK2a!|cu7<#no)=~FYQ4_<-}^YC%;y-{d!uJ zY2qr_C-W{>RLMW-k6|2i-OVk*pU>F0>(@PO+W+rebJGd_`q$luj!(K|s>E%|6+f%q zc-9qxn|u?aS)*KHZ-s@={b%t<_I2)M2X07nP*Sl)jcMZkPyO|Ef1jVf^)>zZ-3_|} zeSSm)?Q(f?$z7W1X3oOsS@(D*c5mujzdh!ExZZW`lct#(8zkpMJukl$75ltw&8F?w zHrd?W=vK=x(Ga`>Fyo9siyr z%?G`(W9G+-?ReJsR z?y~lN*a}4#w+tUaqKEWm-0EZkXDT;^BIY$cfoZ|NV(fPpow^fdUwin@KELHF6gy6Q zy0mQ9&(zSA8yzyz9;vT2HJ@GERB>t1lv#7-8C|9wNm6)v^TU^Ib5^`sJ?C=SwV!R~ z>Y(Wa1*1o4(mG1t=jn1(dVailv)0o4sKCv$#i!0hDHi1@Z2gdKHQ`~=YAH9?iNbbz z%MD+KPE)klo2#x>H#JyKfAy^Rd2`tzPRm%b=fqNZ!^)Yz8f51$dTMT(lB}>^<7v^1 zAKbb(xJ+&53(roO7kkEd3h&a4sfp8m7TUj#{-nL%OMmW;#!auEP1|gD`*2BysegG} z=5+zLl=kwi#U?Kd?{0s0CG~Bi-^+lXOF)B8Et=p3$1g)NT==%hxu%@go)f$5f$fF5 zMT^2CUwz+mu{RGqOXHAowQ| zPs%F(zR<65_w?``i?Z}Cd533g$dNOB&2Ma=d(WVh_iEgeB)^;FDZBX6I_erSM;`vALwly7fwM z$jei`3Y#9;ux?$~9=f<}!cO1mTBpK}oBi;8VU_&w)~>ZSCmfG|6yiY`ZyN|y zzTS0{XZ9zF&I9is@G|R8vS^&d+TGE?<-%9Vt2-;F;Y8*1N2!;S%V+RDW?v<^ljnbE z%*if{f#sr6yh_u(Uv%k9Ox#+&YWu0X zc`poBCoU7h7=yUayjE@1C%%n!1s|;Qbz9$rR3C@>t>et)uN#`C-aaZ9Vr!McFni6% z7XqNgSb|IwH!9A!Rk`--XRoYz>(YN7assACC^%Sd~%y{DO0g7pNx*)~_Zq(cf-kQTRiCzdqylpJKn; z#id2WSSHyV@2<8B+%fzsl7a?#Fp-B#(ezQ zkBY8y$M43eeogt4d&ud`#&!Eoy#G|Y;{TnTW~V1#H&5PY#tmNdJS)gWk4bk@Gmo40 zg_}-KS_(@iD(p<_SR-@zVDfTrRi){YT_xLB`)Mx!e~Y!PR~+R;+|Sn$k(W}bo-AKG3!E`juX4`Lpx-?2ps=?{;ZjT{wI+) zA6h}<0vx@{O7cHe&z5n~3z}6m(KM+|S-7p?grrQmOZ0QsJ|&}%$H7xCpl$K@|2+71 zR6pj!_4~B}0zV(-*9L-W1Lr3NUz|*p!r7v>IHa&|{Vkl)2wp5C=#-%)_*47;kLTCx z|E-CwFT2OPTKZ^9zv@zNm$GX&rp`WiRB&ezXjQA;3$xp+ls5F}cbx0|98s=zp+3(H z9DOYUv(#L~YQJQczlpK^KI{CvZN*>bSlO*}douajvP{+ZFojPie=N&?n>6uqtWK9k ziZ+9C%ZaMV7Ui9B$L}ll&CY$$p>zCbaZmDb3D8Pb0Vy%1Zn>IA#Z4zZ>0j<{YdLYV zPi*DcJm!gppw1!3!iml)E!RNpPK8e;%AXz|pZ}m%tgu-TG|eu-rsOZDv^)C#^Gkt+ zXT6V3wGZ7IxpL9hS9xDzuO95E&0pQUaH~$L?xUBrYT4Q^3z@oq?cRN`ZD(5jjO|?D zL7hZ}Pb(CP=6l~<9pUgKvGMDUCgl#EtqLrl8C08FaVcL@mR&kLeJRTd^9>!h<0j^= zj;WbDqv}VN%*3-&AC!Newv)O0{;T?yX?yl1oU(O)b*(wN`*JteJtInTed39>G&w`cr_aAIZl`g4p$`b|mISxBK zsauh}THWQ^n^3vqUPrev^;S;QJ?HIdb)@*Xb4aYsp;u;m!|NZU|N3+?=qoF4QR-t~ zMKy!CuPe0bw+Gg*o25{6bHyx^*OAPXueWx*N#XO$+_G~`Lff;e9WrZGrrgV6I@~B0 zn(C}PcTY4cs6TehK%jDp;LdF!UmAnXGU@ic%kMjJ>i!$q-L>b;mDcLM_*WGdzR;Ne zZNzfEvi@to3Z0e3M2-m%gdJ{Ux6eK{L@gMV2+ORrx#fL}QC@e_Cyoix~9$za6nX z$h9{;yY(5Di`~r%Cglzpt=r}Mo2v~9$NI$74{tm%(bdl{ zS9jX$om0i%ZMi34xxqy1?B$;7q}6AcM6K=!&s&`*7`aqie7!6~a_)}+J@L!C^-Nr! zsI9)g%k4>$m6JbJ_e*~(Z@a>@c!gcJues9hi<3FarbH~* zmZNR|c=L?YX|wmu?K!S=`}e`0`;*GsPn_HFiHEn|*8WxgRCApuG(r5fLeUI0Uq9)C?d>NfK6DqfymI^B$3lsM)7cx7^VVOl`Wo58 z98P$1TMSjYz zu6SKB4``uAg+BEfrUqYC3!M$Hh z2SGXoK!=&ux;^>j&^>1=FB6;M8gZ9(d|NK0Uk>}^5dF5y^y)87Tb8IJ0z2z|IGWe! z?s@g|<1;SMAT;QhlZ+J|GEs}CC9P1~(_?q}%bOc%$J-jk-cEll`O9af{=OjJ@YloWHf7Z|0ka$)JYZ+PU-U|NVSEuez_&A-iaEY3GS| zQbsvSJoiA`s4_}Q9v$ffZHhm`EY(!^p;`XK-)rIEodY1fybkt1Px{ZR`<3~Ok=Le&A~YB5S3oK^3-BKqWCW%EgE&QD$+S69Odvu<+A*L&Ui`!p7wbUJD8v?BWCzvDtN zfxCG`T=Md7r&(*uZoHX$ZzW`dqoLAM9o_Zu&CA-WML~=IoiaX|=(vbwd2Te?8vJY< z-}L;d^_$lu{#|qb|D&9K-nE8_r!PEtb>myKzrsopEXb>(Ntv%Gca)OsOy_PdmQM$#vT2)7!MKEL*XO zO?;yB-^@qqeAnjl8pow`-3d$o#N#w4Rh2WfYATD=C&8NyIc&RU6;6K4Q|5b+xA^o? zafbWdIs2HGOj!xPrJzh-B55d^Y0rq@pZoziT~6VsMHWV2@Wk5 zCG&_QVm4(=x|?`j9WUIk73$vD`=TiHD}gscgK@yZ>K8y_8bXhJUZDzCM$X zyXrYTZF+j~rY~BV%_k}~HvHYXQ18N_19`U?^)DQ9OW|Mk)}cG$wXa^xoZ7X2!bLyN znYwoWEU;xQZhRAs`Im}2C9MA|^hB#}@qEFE9I1?poWFE7TYVLB5cQaFRi2w8b3?l8 zf`479Dfh%qzdL1I|GMYFp?z%~Z;oz>$bKJkJS4#7)!}o_I%!&hk@^ulphb9b)ep0n zbU*#EvReA^DhsIGQ8eLkIaYOFDcAR#`|Hh;VR9i?^!=|pgN}siu=%;{o0oL#`^ff+B^}%2*YEFqzw-1w=9$UA z|Gl$LRon8us6_aF!fOdL373E0>;Hd$KEIytumR8E4O>lry2x!1-&wI_X61pRj|?53 zHs;>DywH2X*@ST8yrP)z8W#Q6uNLcF3Tj-wk5#yNEpyWi1;L-yApb>W^U6)!dz^K( z`XbkPPHX&DvhR7iZBLx-306M8-fbNwnT}JJNzzYTcn(ytbLtk{BDW^$8W|QGo|MX z516@KXN{7$;d}8K(lq(5E}>4jWCf#+9*_kJMIRzhrR|Kfxv)t1!$qr(n6|iS!`YLf67cRmuubJhfja~a}6{dddz_5uz^6O)x34-5t7G_I;8L%HsE2NxLkIk zcYWEjoVL#f0+OJ>a!A<&Dn*ke+7cx|&V<+|(b1Eb+;QUj`*$o`eqYZ1wyrSa`#a}n zKQ3R|`bPqyO+fN+TjvRBew#E^wVYR~e8&$Yfvj+0n`oFLB4}Co)a%vTdTu4K!JtBT z)5iU_8w{O86R-7dmp8a5vHQI~qt)eO%<;jlX7}neG+)f~db{yckKNMO_jklStvGY| zsRwUl{%Hk44r#E<4S8JTmWbcv-sSN#qMbXv@wDagwB>7Z+VYCGm&`Iwk6B*VdsIxx zJzFEw?t&gDP8v@zZ(Ge@&Nt_U&fB;7t((J}Yj1cQQ%cwVX1Dit(apNI-+H&PZ*R!t zt|?w|Hmgj_aA}YKElW}7Cl$P@p`hR}>+RT69>!t1`S4BSSKDOfXbKN%f#1N4U-Ic4sUqrlH%L`>W0Fnd(GUcdh+w$Gb_z5k=_AnjUC+fD);{n3!WWM z&%B>;`}NkiS~2Or4&66?S!KF-x= z-`sk*?@GrTfhC`ko=M(05|(!^Q|UOH_5D@bD|cP3 zGK}@SoXLAIvdGY!A!}FQe&(y`8#|p+PIt#Np4j-;aMxEQcb(F%^(W(Gz#&rNQg(MH z-`XtwO&>okJ1#kG>CDN=!CJ}tz~+aA zciUQcFZAG)U*Pye)Afnj#uKZab*;TKOR=c??1LL-pj^v5ac;zuIq_SWw_1ogozz=+ zdEI`Ol((CBEehK^PJ}J8j*a9!82Jjc3UqS!iLKUAPvq`&$?EFF=QB+FnkN3$)PnDs z>FtZ)B<*H!K`A|zxz$l8yYIx+MzLQxQR#9StM9IBGyOY7j!8G_>o%^5#q|Zed$QK= zeD26Tak==!|67ydpPYNg{8a3y-^$}}&UU}=zcOD}e$8$1n^E)AU9}D$muO485u$(H z`(TK1{ISKERb@GsQyx2Xzj|8LW*7Xddws}dhc}Q$-HW2ah2j|xUDA$=SuDG{Y-YEV zQ{aPz8N$36O=c3q;-_6f6sb)BGov4-vZx@n}uIJSnC&jkd03>Eaz9) z94oWU<^mZHugXMzxmI#{`y~D7FWaiHH0wa|()Lw$;_K~^62_}*OHQcpih(wJ9yZ{4 zt*^9u^{EYpCNIhk34()WgXw2b+YGeK7*rmC*Drue7f>mqU1!>`$FMO361k6h9T8x9tY$xp7OXqbG5(XhtLG1cN|fP$oA59T4E~L@pP) ziu0`X*3!FY_LbU1ESa

DTNFUkcVUfriRB8c)~;cy~=*IoD`=>5iJq)pJvMU#I{5 zC!SuNlhMl=-KG|vURIaU5o3F=ZS%u)aBEo6#H=GGz`N;mA)mCb%eIL7uWR-TRQBe+ z=;#p#o$>Fa@X4t&$+CUwz0}9E?iy^@FE%^B=eep_=;^{=@9z|K6+SJL{Jdd9h1atc z+c-|H4ZgnNfpOl2t8-Hg1YVj5u8DU|I`XPy&g-8H;yPUCpPyQ(Vp6j`YNgi0D_bh$ zWRkw#@v|x28NAQrbMU@5XLRy3y5Cr*9$S}nPiyu!cTkOB`t~9B^SCc3TKQsj@0r&% z6Fgq5XcE<-b0CCGS0k)UW~1GqWk(k8G`2Pq)!H;Cep~E9GuNr6J33@u`3u_@Zuplo zo{F3Tsl9cyaXdA{Ok@kciHB;TBCVK0kyb1G{wj)<_|eX_MXuEe@tC;I4_ z<`baGQc72UQ=ifcCiB$-mU02NWhN%?I~FHk8Mge}zg;tr7HT_3*h^<`;Z%Cw$rj{& z|E;CjX*Yq$>0ZX)TTb|a+h z%qmxKeaR=h?~79B-@G4R*?(UanArR^{Q64s;~!S|?K0VIGkfyVa8GHMbIy%#*YlP( zim{bl=BsEFGgGQI$YqaWiOw&2_~=dc)BUSvJYSRZ7uLur>X=ihu~&ep`t5Xu@Q>1e zdk!RBcIfuIkUsP3%IOTN9Gceri*WF0w$*0(8m^=Kd0RwT_`ILd=`7;kOkGm+mmQ6& zUT(FlNhwIaOfJbVxbsBS!K8|vaT~tg;tm(inE3qqMNQuIYT(qqFj2wi+HbMU>`nGj z^UrShv|v$POB;Idg%pajA z#}H_@?QFGG3FjusH(AGg`(DejKL5C@>YQto)`u(G6OuNRItW1WsK8G9MzL#`FFq<1 zoXH$v%UyN!(X$H8y{;DxKRt9;e5<^v*vzNvG)n?0(8$u5e0;^_&cH)n40JWsT}k-2H!E5ttPpZGuyg4}8tL^mKigI6pnRs-LRoPp{xKx>42YyhTI$P4nG3o?n7zDHOelI%6Fy=#pZ3yD|G=xu*P- z=$*4xIM^QK)bBFcFSC{*mVfhUC2&BnC~bF4Y1UWWdgF=6Z_a4u$X6wj=DX)a>f(hD z*>{PozVq|1s<-hNhmAH%}5 z#`lez1Mj_shx1?VEh|2`yKPwWMd|sP9HT4O1)N~VaK!An+9>wW&SJ%@<3&I6&P{6+ z>rI-tdVTBtr4yZ>?D%ebZg;E*X!jF`qQK7GPpjJgta)0c$8WhKOgdxY)SwvYHHvZ> ziK~1QPjGMPU>9{UT$i>nykckE4*qkWTzHSvdA)vG^()H6>B+1EZHv73vP5lheDdLG zz}~Zr=5o6q@oesf1@QN6FJ~XKOTWDRPe{hqsJlgblg@@kc^w`?GiUA9vNT&8s}!d7M>*p81a4jxUfnMCUB>h{ z|J$9p#m~3>T^;(fbe`JJ*;kA$*1mgL@@>txrSp8X`#)c77H|^oI`Qt7DbH*R=83l# z-dB8h<*cPrKi@6TY+}o`Bi%iTHVsvu1b+V5Tm8;!g89bX-`2~V|8qp!^U=Sli+`Ix zT^`mi{&J^m)rq6`3vvtfi!A=1ob3Mo?vhL4%wLaG&G`QRLejh$({{bScYL-{PS*)- z?b%jtv!==G2fdwiumm*10G_CEXPaofP3lMa)Krbk#RZ&4u6D?*)@?g+_2=r>onJ3l zmtKFgj6*5BVj{PZ-^1%NtDPrnGCzp00_8t&FFLvN#5U`j%olv!=Xpqccu{wBrQZTq zm5xKJ);j8JI#>Va9>*2CD=XTU{m7l^|Ldc2_uOwCYhsT7Jl)c=)qSU)EO;e{rpb~rbYKJFX*No*q%v0vKmE+yQ@%6%kqGy3+*7tcP zn%+|5n6sy>b33vzE>Cp)%KyK*s4mCv`fJ_1oaPf3Zz&zW_(wBS?ZqAm_qP@Nj-WG! zz;2IK-o)v2W6Gr`k8keU{!Y*`E?Q#Zd*E&79jq9 zeG_2pcCmVa-Q%?OM?3a4zqC)7{p{VXSqn9;Nn|YUiCr#x@x+a7T<1i#=vriNjf;Hi z_5a|z=NyW``)(NT`}<>Gn_=lp$%!-bUG@mhjI<94z4ZCRrYW0@l$92n-1gsFrMxL1 zWxb8^rKmM8l*;M?Qw=k3+UQvx`g449mimr%QM20FI@7M2<-MJ~+jhfCX$FR_JGOCs zew%Xmw=C-tKkT%>?Xi3ClicXo8~=`pR?cNRyLD}IPTd*%1&c4fK2hTg?)xw5z$@8BYMv+hABA@)J`0;YVi48$nHg}9}zTstO zVAzoCYBx`gcbWe2&pQ9(ecOyatAAZ1rck{k=+(21Wxmf29SS~OzS{nRIWHUg{@Lkg z`+tTO@pNZRcs6PB;>O!oZtUEq!#tsD%{M(A-T7Qk?;g9g+H7yMp1%B9hkI8qnxOpA4`HnS{N7@-o#BTcGq01dfojjxAf7CRUtp82`qEt z+MBXAG(~w+SlQCYV(ZtwnYAvy@7dOt*2t8_!B;a@ukI16Hd`YTQvLnUrdK64)Ax%1 z<+A6_+nIB7Uc$1A*;+GJzo=&bTS2J8Xr3FM`XRt@yQa^`)oBPO%FX2Z=xryzokH5 zr0dPC4LMpNDO<~R?WOb;1D31KY1y!H!;S5)Yt-)drcC@RtYs{BUU_9kWp1{3tjNx< zX1ilv++82V(5uAEz_8%N?SK@2nYmHiGsE9)TBN<~#8u8^`s?Q`4xRWk^y$fL%}qf* zkF4VrPOaA1bUVap;^ogb|K6SQ;92B{KV@+|vvt-NJUt%x#AT~t7Y_piL;tE1mm~iDH^D}N+JYv{>%y}Xs z14F=*+}0b;Zxu>{-?(qPF+X=6r-&p21H-%&v6%{dS^+5x3=ASO6*$0xu6dzPzR0g! zts1#^UWA(f*kGGbSHALM=T#6D^ENA0OCMNxf~Bhm6kRs@u6btDO=l)=e0%t$`F_jJ zH!MC-ZGo=mS}i;zmd`Kp5zzQ#SG3)tdTOmrY~GHWt8X3;zj^bg?*IMV3=HQzCfts1dO=Nf4RoFp)oOqWJaYlVh^%_sxp2h^wy7>`#|pzWMa(=;y0m zzB#m~derEve5dedHme7NU( zSI*q8`_BBUo1^!x`?~PwUse^X!=kg#d_B4R>F&yRmA5q3SH6C8C#~cCX(^uQTY_7d z85jyCbbw>od3b}w`RRpU)@l_Q*M+!F+k5@6ch9%GFAj%W9(LXQuHpFmw}qdTzBzW3H}@TB zU%_MjR}U1s48K>OaO*V7tL~rQba$Q7?8oMd<;y3zPFviyH>~DXzSg1>oz;csK0Z2r zp85ChPKPoLO4pr&S57Kap6q9~^68`4>RV?Q_-S98>2%Xi)J*!VT#wgI z<2L=|tt;Q(ow9u6_G^Kap4pZSzgB%(aJyphysDzT`&#*&P1z4C$BNv1z4zb7`x)T@ zPuz-4*NW_Iv0Zi_?BNFtB0DEaEc9CH^z`I@Bh{A@1&PVmX3sXZ-7dV-IWelv{gSxs z<*73RFHW(yS$Lu|aH@KQt9En-o5GnLGW+LEzdCtkSD2ZzZ*=l{olWGY$h_^Gd|u6Z2_xmlWe+G`bW{KVPck|UoeNNdfWB>S^VMtrSQjrv!mQ6 zE>0Da6|ubARCoQ}bb+6|E^?8JFD!bTF?)BkZugp+a;J%)SZ{c~>cmo~r@ur+qK>47 zgc!VT6*G+G7LCmH@{isAY}?uyyR>e)PrQ8k>zCc%-f8c-e6DMa?nUF+lBjj!JFUM* z)$WY@d{O(p`4-m7m*pVy7%Vbe|Jg4)a%kn;jA^e`xpZG0`F!?3@RJbN_FWb}*3jdk9!<@M z3DMi3k^W|{l6{nlxm$#357Vk>Ci!ohJ%Y@3PMxU&DYtfV)w4=F=2(Jx3f(>eDWFsf zN$Dc*#M0Mq>R*1E*Sy;F_YW;=>;1J?sx__e{@J_cK+!Z`vF(4#7#S9vU};oZd;(nZ zfb-v<6p_lpS}V;zpRPVR^zqhh?`oUh7IS0c?plTWri(wjd--W?<%guK^Ly;dMStdL z-rl*d+GDHou{7y3vy1L^^_&WSV%PkB!S?Olo?(yn#L7=So+|x{^XI{nNrv3BnHd}= z27)r|b|+kg(cB{k*8D!^{#2uA{=sq|p7hO2L+_o+^8Pzlcee2x>8(n~{WSU?A7f}x zS`2dd`^`$x>3j7z@0VZR{rl0^BYXDo-CL!5*(<&FQ|8aSdHd#?eapOOWxf66t!m9p zj@G83&1&|!HRWY<<)&ury#AnCa?||qY3#2jYq|E#Q?Qk0U~qMt2r6XUUGutxr6l*- zeYLsNk^eC)boGW6-Xeb{yXtPLJk6iEdeL0=rX`2oafo6ujXvyT9mx7b;Fr=tzus9 zXRWnr72`j>>7dfeJsX|6>$>*zI)REhP+8`xCmqRi{Qlw-8lU1eo-4A=oN0S|V}9k^ zjMP)Nqt;yyp4h6)y*D;{r(72ggT|+AqL%*tY0WQBpE^7zszE&~F~kR$MxL(KA+5K*jO!>RHOMzl`=plqC9Td*?6a4cvG>*V{7HLRI&T;4 znl<_M@i{Vy#rsz8|Cehvw@W(mr`{aJqxO$By}s6ea<`+%PfM+$9s3}Q;Kcmi$(1)6u12&J$d0sP$QsXR#!}F^i-V% z(_N+*g?P^^KeB!Ap%ur9!&$DDz3TJ%wq@&jtFtfD&0qgn?YWQbE2rV!?p~F&X|c!V z$R$SAT)iFhUvG-uB>BSZ&EVqN#?#eox9X2Bo!5FvPInfaaO-n@W%w|z(R(lvl;x0Egxs?kE`xmG&QQT zxFU4={vW?z-Un+j~ zPyaf1wfjU)5lPp&9M^ZZet%Nhe=uA+=*c%8Q1kLbMAx3p2J3nr3u%119RB3!*OyB? zP7!Qg*2#r$E3W-MA#1tiz8&Vt8nd^qy_#PcnX)!TBQL`2IUB6;BC8RjC@Xnn0(%Ran-moo` zU&QKfS@G`rlXKM~Ef!sOQo3f(2gRbuOof0a>WfbJZgfRd~k;(Y;6T;A_ex^DYz?M%0cj0})Q<&(LZnwO$DzH zWz23$TYc!YNYnzD>I=(GXzN~|oOOG%Y<+bX`~9lf@~i!{lh>teKV4+Iy?p0l)-E1M zqnXFk_1%t_w_}ZdYj2C)ZNo2r&v51T%^ABqv^QcoX7w$Bya zd3ag=Dy4Ag{Tsm}4$vOUn{K84`}Jq-YGwBwT)Is%f8U#&NvGFs{w}}m`q6p+xfY%P z<>O7A{D<#!+1>4_E2;Z)Rz9z2s^p(9dBSzcw@f~!-l=;w{U84g@0b-||2=;0Sh-}U zV{&_%+@fU~vsXPj{QU9p;FMA|<)YTzt4`@E9%quFPa z*DW~_v@MFa;&GSE%eyZgx6f`Ay;HvUQR!->aHXxGd%LxYa?~bw$?QIE*X1K72`UgO z%DQxVFPw-^Gr z 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 diff --git a/doc/qtcreator/src/howto/creator-help.qdoc b/doc/qtcreator/src/howto/creator-help.qdoc index 34eac194209..b6208c34c65 100644 --- a/doc/qtcreator/src/howto/creator-help.qdoc +++ b/doc/qtcreator/src/howto/creator-help.qdoc @@ -41,13 +41,13 @@ The following image displays the context sensitive help in the \uicontrol Edit mode. - \image qtcreator-context-sensitive-help.png + \image qtcreator-context-sensitive-help.png "Context-sensitive help in Edit mode" If the help HTML file does not use a style sheet, you can change the font family, style, and size in \uicontrol Edit > \uicontrol Preferences > \uicontrol Help > \uicontrol General. - \image qtcreator-help-options.png "Help General preferences" + \image qtcreator-help-options.png "General tab in Help preferences" You can set the default zoom level in the \uicontrol Zoom field. When viewing help pages, you can use the mouse scroll wheel to zoom them. To From bcadbe666b719581814291ab28d7c490d06a85cc Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 6 Oct 2022 13:03:23 +0200 Subject: [PATCH 34/42] Docker: Fix mount arguments Previously when trying to mount paths that contained spaces or colons docker create would fail as the -v/--volume syntax does not support these. Switching to "--mount" and using the "type=bind" syntax allows to escape the necessary characters. Change-Id: If969173505dbf1b36a67dc8b398c58b78941519a Reviewed-by: hjk --- src/plugins/docker/dockerdevice.cpp | 94 +++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 20 deletions(-) diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index 401e98d59c4..87815a7b3fd 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -149,6 +149,7 @@ public: CommandLine withDockerExecCmd(const CommandLine &cmd, bool interactive = false); bool prepareForBuild(const Target *target); + Tasks validateMounts() const; bool createContainer(); void startContainer(); @@ -157,6 +158,8 @@ public: bool addTemporaryMount(const FilePath &path, const FilePath &containerPath); + QStringList createMountArgs() const; + DockerDevice *const q; DockerDeviceData m_data; DockerSettings *m_settings; @@ -314,15 +317,22 @@ IDeviceWidget *DockerDevice::createWidget() } Tasks DockerDevice::validate() const +{ + return d->validateMounts(); +} + +Tasks DockerDevicePrivate::validateMounts() const { Tasks result; - if (d->data().mounts.isEmpty()) { - result << Task(Task::Error, - Tr::tr("The docker device has not set up shared directories." - "This will not work for building."), - {}, - -1, - {}); + + for (const QString &mount : m_data.mounts) { + const FilePath path = FilePath::fromUserInput(mount); + if (!path.isDir()) { + const QString message = Tr::tr("Path \"%1\" is not a directory or does not exist.") + .arg(mount); + + result.append(Task(Task::Error, message, {}, -1, {})); + } } return result; } @@ -460,6 +470,60 @@ bool DockerDevicePrivate::prepareForBuild(const Target *target) && ensureReachable(target->activeBuildConfiguration()->buildDirectory()); } +QString escapeMountPathUnix(const FilePath &fp) +{ + return fp.nativePath().replace('\"', "\"\""); +} + +QString escapeMountPathWin(const FilePath &fp) +{ + QString result = fp.nativePath().replace('\"', "\"\"").replace('\\', '/'); + if (result.size() >= 2 && result[1] == ':') + result = "/" + result[0] + "/" + result.mid(3); + return result; +} + +QStringList toMountArg(const DockerDevicePrivate::TemporaryMountInfo &mi) +{ + QString escapedPath; + QString escapedContainerPath; + + if (HostOsInfo::isWindowsHost()) { + escapedPath = escapeMountPathWin(mi.path); + escapedContainerPath = escapeMountPathWin(mi.containerPath); + } else { + escapedPath = escapeMountPathUnix(mi.path); + escapedContainerPath = escapeMountPathUnix(mi.containerPath); + } + + const QString mountArg = QString(R"(type=bind,"source=%1","destination=%2")") + .arg(escapedPath) + .arg(escapedContainerPath); + + return QStringList{"--mount", mountArg}; +} + +bool isValidMountInfo(const DockerDevicePrivate::TemporaryMountInfo &mi) +{ + return !mi.path.isEmpty() && !mi.containerPath.isEmpty() && mi.path.isAbsolutePath() + && mi.containerPath.isAbsolutePath(); +} + +QStringList DockerDevicePrivate::createMountArgs() const +{ + QStringList cmds; + QList mounts = m_temporaryMounts; + for (const QString &m : m_data.mounts) + mounts.append({FilePath::fromUserInput(m), FilePath::fromUserInput(m)}); + + for (const TemporaryMountInfo &mi : mounts) { + if (isValidMountInfo(mi)) + cmds += toMountArg(mi); + } + + return cmds; +} + bool DockerDevicePrivate::createContainer() { if (!m_settings) @@ -483,28 +547,18 @@ bool DockerDevicePrivate::createContainer() if (m_data.useLocalUidGid) dockerCreate.addArgs({"-u", QString("%1:%2").arg(getuid()).arg(getgid())}); #endif - - for (QString mount : std::as_const(m_data.mounts)) { - if (mount.isEmpty()) - continue; - mount = q->mapToDevicePath(FilePath::fromUserInput(mount)); - dockerCreate.addArgs({"-v", mount + ':' + mount}); - } FilePath dumperPath = FilePath::fromString("/tmp/qtcreator/debugger"); addTemporaryMount(Core::ICore::resourcePath("debugger/"), dumperPath); q->setDebugDumperPath(dumperPath); - for (const auto &[path, containerPath] : std::as_const(m_temporaryMounts)) { - if (path.isEmpty()) - continue; - dockerCreate.addArgs({"-v", path.nativePath() + ':' + containerPath.nativePath()}); - } + dockerCreate.addArgs(createMountArgs()); + if (!m_data.keepEntryPoint) dockerCreate.addArgs({"--entrypoint", "/bin/sh"}); dockerCreate.addArg(m_data.repoAndTag()); - qCDebug(dockerDeviceLog) << "RUNNING: " << dockerCreate.toUserOutput(); + qCDebug(dockerDeviceLog).noquote() << "RUNNING: " << dockerCreate.toUserOutput(); QtcProcess createProcess; createProcess.setCommand(dockerCreate); createProcess.runBlocking(); From 39258f5522da2bda12c5c26b699d1656d654802a Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 10 Oct 2022 11:37:16 +0200 Subject: [PATCH 35/42] QtcProcess: Get rid of setResult() This isn't meant to be called publicly. Change-Id: I1a5e5325ac268e1bbfcc34c529cfc3c7e628243c Reviewed-by: hjk --- src/libs/utils/qtcprocess.cpp | 5 ----- src/libs/utils/qtcprocess.h | 1 - 2 files changed, 6 deletions(-) diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index f0f6170f882..e2e67b7d8da 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -1296,11 +1296,6 @@ ProcessResult QtcProcess::result() const return d->m_result; } -void QtcProcess::setResult(const ProcessResult &result) -{ - d->m_result = result; -} - ProcessResultData QtcProcess::resultData() const { return d->m_resultData; diff --git a/src/libs/utils/qtcprocess.h b/src/libs/utils/qtcprocess.h index e553b397ee6..2754e407f5b 100644 --- a/src/libs/utils/qtcprocess.h +++ b/src/libs/utils/qtcprocess.h @@ -159,7 +159,6 @@ public: bool readDataFromProcess(QByteArray *stdOut, QByteArray *stdErr, int timeoutS = 30); ProcessResult result() const; - void setResult(const ProcessResult &result); QByteArray allRawOutput() const; QString allOutput() const; From d74c5301ff91a9b058edaa89e0f5d95ecd288426 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Tue, 11 Oct 2022 13:09:15 +0200 Subject: [PATCH 36/42] Linuxdevice: Add FilePathInfo functions ::filePathInfo and iterateDirectory(..., IterateDirWithInfoCallback, ...) allow for faster info retrieval by the fsengine, making the listing of large directories like /bin a lot faster. Change-Id: I2a21e019e05f5bb08459483747ba2be4530929f4 Reviewed-by: hjk --- src/plugins/remotelinux/linuxdevice.cpp | 18 +++++++++++++++++- src/plugins/remotelinux/linuxdevice.h | 6 +++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index 2d2d8684d69..60959d99291 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -1288,7 +1288,7 @@ bool LinuxDevice::setPermissions(const FilePath &filePath, QFileDevice::Permissi } void LinuxDevice::iterateDirectory(const FilePath &filePath, - const std::function &callBack, + const FilePath::IterateDirCallback &callBack, const FileFilter &filter) const { QTC_ASSERT(handlesFile(filePath), return); @@ -1296,6 +1296,22 @@ void LinuxDevice::iterateDirectory(const FilePath &filePath, FileUtils::iterateUnixDirectory(filePath, filter, &d->m_useFind, runInShell, callBack); } +void LinuxDevice::iterateDirectory(const FilePath &filePath, + const FilePath::IterateDirWithInfoCallback &callBack, + const FileFilter &filter) const +{ + QTC_ASSERT(handlesFile(filePath), return); + auto runInShell = [this](const CommandLine &cmd) { return d->runInShell(cmd); }; + FileUtils::iterateUnixDirectory(filePath, filter, &d->m_useFind, runInShell, callBack); +} + +FilePathInfo LinuxDevice::filePathInfo(const FilePath &filePath) const +{ + QTC_ASSERT(handlesFile(filePath), return {}); + const RunResult stat = d->runInShell({"stat", {"-L", "-c", "%f %Y %s", filePath.path()}}); + return FileUtils::filePathInfoFromTriple(QString::fromLatin1(stat.stdOut)); +} + std::optional LinuxDevice::fileContents(const FilePath &filePath, qint64 limit, qint64 offset) const diff --git a/src/plugins/remotelinux/linuxdevice.h b/src/plugins/remotelinux/linuxdevice.h index 1cecc12f2e7..2e9aeee3616 100644 --- a/src/plugins/remotelinux/linuxdevice.h +++ b/src/plugins/remotelinux/linuxdevice.h @@ -53,7 +53,10 @@ public: bool renameFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const override; Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override; void iterateDirectory(const Utils::FilePath &filePath, - const std::function &callBack, + const Utils::FilePath::IterateDirCallback &callBack, + const Utils::FileFilter &filter) const override; + void iterateDirectory(const Utils::FilePath &filePath, + const Utils::FilePath::IterateDirWithInfoCallback &callBack, const Utils::FileFilter &filter) const override; std::optional fileContents(const Utils::FilePath &filePath, qint64 limit, @@ -61,6 +64,7 @@ public: bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data, qint64 offset) const override; + Utils::FilePathInfo filePathInfo(const Utils::FilePath &filePath) const override; QDateTime lastModified(const Utils::FilePath &filePath) const override; Utils::ProcessInterface *createProcessInterface() const override; ProjectExplorer::FileTransferInterface *createFileTransferInterface( From 5c4441a7607456785cddef741b08a736be3e7538 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Fri, 7 Oct 2022 09:19:47 +0200 Subject: [PATCH 37/42] Squish: Move some helper functions Allow to reuse them. Change-Id: Ia13f7f6c7a40066fd7ae46389adc7c9228161a4a Reviewed-by: David Schulz Reviewed-by: Christian Stenger --- src/plugins/squish/squishfilehandler.cpp | 1 + src/plugins/squish/squishsettings.cpp | 14 +++++++++ src/plugins/squish/squishsettings.h | 4 +++ src/plugins/squish/squishtesttreeview.cpp | 38 +++++------------------ src/plugins/squish/suiteconf.cpp | 29 +++++++++++++++++ src/plugins/squish/suiteconf.h | 2 ++ 6 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/plugins/squish/squishfilehandler.cpp b/src/plugins/squish/squishfilehandler.cpp index 0417aa0ef80..4bfe8eea299 100644 --- a/src/plugins/squish/squishfilehandler.cpp +++ b/src/plugins/squish/squishfilehandler.cpp @@ -5,6 +5,7 @@ #include "opensquishsuitesdialog.h" #include "squishconstants.h" +#include "squishplugin.h" #include "squishsettings.h" #include "squishtesttreemodel.h" #include "squishtools.h" diff --git a/src/plugins/squish/squishsettings.cpp b/src/plugins/squish/squishsettings.cpp index f560e9bd6b3..d6dc68d91ae 100644 --- a/src/plugins/squish/squishsettings.cpp +++ b/src/plugins/squish/squishsettings.cpp @@ -86,6 +86,20 @@ SquishSettings::SquishSettings() }); } +Utils::FilePath SquishSettings::scriptsPath(Language language) const +{ + Utils::FilePath scripts = squishPath.filePath().pathAppended("scriptmodules"); + switch (language) { + case Language::Python: scripts = scripts.pathAppended("python"); break; + case Language::Perl: scripts = scripts.pathAppended("perl"); break; + case Language::JavaScript: scripts = scripts.pathAppended("javascript"); break; + case Language::Ruby: scripts = scripts.pathAppended("ruby"); break; + case Language::Tcl: scripts = scripts.pathAppended("tcl"); break; + } + + return scripts.isReadableDir() ? scripts : Utils::FilePath(); +} + SquishSettingsPage::SquishSettingsPage(SquishSettings *settings) { setId("A.Squish.General"); diff --git a/src/plugins/squish/squishsettings.h b/src/plugins/squish/squishsettings.h index 432aa53758b..1f411cde60a 100644 --- a/src/plugins/squish/squishsettings.h +++ b/src/plugins/squish/squishsettings.h @@ -17,6 +17,8 @@ QT_END_NAMESPACE namespace Squish { namespace Internal { +enum class Language; + class SquishServerSettings : public Utils::AspectContainer { public: @@ -39,6 +41,8 @@ class SquishSettings : public Utils::AspectContainer public: SquishSettings(); + Utils::FilePath scriptsPath(Language language) const; + Utils::StringAspect squishPath; Utils::StringAspect licensePath; Utils::StringAspect serverHost; diff --git a/src/plugins/squish/squishtesttreeview.cpp b/src/plugins/squish/squishtesttreeview.cpp index 7b43830f179..a2745882ff7 100644 --- a/src/plugins/squish/squishtesttreeview.cpp +++ b/src/plugins/squish/squishtesttreeview.cpp @@ -161,28 +161,12 @@ void SquishTestTreeItemDelegate::setEditorData(QWidget *editor, const QModelInde static_cast(editor)->setText(index.data().toString()); } -static Utils::FilePath scriptsPath(const Utils::FilePath &squishPath, Language language) -{ - Utils::FilePath scripts = squishPath.pathAppended("scriptmodules"); - switch (language) { - case Language::Python: scripts = scripts.pathAppended("python"); break; - case Language::Perl: scripts = scripts.pathAppended("perl"); break; - case Language::JavaScript: scripts = scripts.pathAppended("javascript"); break; - case Language::Ruby: scripts = scripts.pathAppended("ruby"); break; - case Language::Tcl: scripts = scripts.pathAppended("tcl"); break; - } - - return scripts; -} - -static bool copyScriptTemplates(const SuiteConf &suiteConf, - const Utils::FilePath &destination) +static bool copyScriptTemplates(const SuiteConf &suiteConf, const Utils::FilePath &destination) { const SquishSettings *s = SquishPlugin::squishSettings(); QTC_ASSERT(s, return false); // copy template files - Utils::FilePath squishPath = s->squishPath.filePath(); - Utils::FilePath scripts = scriptsPath(squishPath, suiteConf.language()); + const Utils::FilePath squishPath = s->squishPath.filePath(); bool ok = destination.ensureWritableDir(); QTC_ASSERT(ok, return false); @@ -191,24 +175,16 @@ static bool copyScriptTemplates(const SuiteConf &suiteConf, const QString extension = suiteConf.scriptExtension(); const QString testStr = scripted ? QString("script_som_template") : QString("script_template"); + const Utils::FilePath scripts = s->scriptsPath(suiteConf.language()); const Utils::FilePath test = scripts.pathAppended(testStr + extension); const Utils::FilePath testFile = destination.pathAppended("test" + extension); + QTC_ASSERT(testFile.exists(), return false); ok = test.copyFile(testFile); QTC_ASSERT(ok, return false); - if (scripted) { - const Utils::FilePath destinationObjectMap = destination.parentDir() - .pathAppended("shared/scripts/names" + extension); - if (destinationObjectMap.exists()) - return true; - - const Utils::FilePath objectMap = scripts.pathAppended("objectmap_template" + extension); - ok = destinationObjectMap.parentDir().ensureWritableDir(); - QTC_ASSERT(ok, return false); - ok = objectMap.copyFile(destinationObjectMap); - QTC_ASSERT(ok, return false); - } - return true; + if (scripted) + ok = suiteConf.ensureObjectMapExists(); + return ok; } void SquishTestTreeItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, diff --git a/src/plugins/squish/suiteconf.cpp b/src/plugins/squish/suiteconf.cpp index 94b78900ec1..d1a97e0847a 100644 --- a/src/plugins/squish/suiteconf.cpp +++ b/src/plugins/squish/suiteconf.cpp @@ -3,6 +3,9 @@ #include "suiteconf.h" +#include "squishplugin.h" +#include "squishsettings.h" + #include #include @@ -284,5 +287,31 @@ SuiteConf SuiteConf::readSuiteConf(const Utils::FilePath &suiteConfPath) return suiteConf; } +bool SuiteConf::ensureObjectMapExists() const +{ + if (m_objectMapStyle != "script") { + const Utils::FilePath objectMap = objectMapPath(); + bool ok = objectMap.parentDir().ensureWritableDir(); + ok |= objectMap.ensureExistingFile(); + return ok; + } + + const Utils::FilePath scripts = SquishPlugin::squishSettings()->scriptsPath(language()); + QTC_ASSERT(scripts.exists(), return false); + + const QString extension = scriptExtension(); + const Utils::FilePath destinationObjectMap = m_filePath.parentDir() + .pathAppended("shared/scripts/names" + extension); + if (destinationObjectMap.exists()) // do not overwrite existing + return true; + + const Utils::FilePath objectMap = scripts.pathAppended("objectmap_template" + extension); + bool ok = destinationObjectMap.parentDir().ensureWritableDir(); + QTC_ASSERT(ok, return false); + ok = objectMap.copyFile(destinationObjectMap); + QTC_ASSERT(ok, return false); + return ok; +} + } // namespace Internal } // namespace Squish diff --git a/src/plugins/squish/suiteconf.h b/src/plugins/squish/suiteconf.h index 8c96f71ed5f..25e30fa1845 100644 --- a/src/plugins/squish/suiteconf.h +++ b/src/plugins/squish/suiteconf.h @@ -36,6 +36,8 @@ public: void addTestCase(const QString &testCase); QStringList usedTestCases() const; + + bool ensureObjectMapExists() const; private: void setLanguage(const QString &language); From 5f4612dd07362c6da07e4ba3d7ffe4133b26043b Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 5 Oct 2022 11:05:19 +0200 Subject: [PATCH 38/42] Squish: Fix handling of object map Fix resolving the path to the object map and if no object map exists yet create it. As on it fix a typo inside the writing of the file. Change-Id: I832a2f71bbf5c5d4947e3edba8f79a00a3b6a536 Reviewed-by: David Schulz Reviewed-by: --- src/plugins/squish/objectsmapdocument.cpp | 2 +- src/plugins/squish/squishfilehandler.cpp | 16 +++++++++------- src/plugins/squish/suiteconf.cpp | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/plugins/squish/objectsmapdocument.cpp b/src/plugins/squish/objectsmapdocument.cpp index 31958ba3003..32d0804efa2 100644 --- a/src/plugins/squish/objectsmapdocument.cpp +++ b/src/plugins/squish/objectsmapdocument.cpp @@ -226,7 +226,7 @@ Core::IDocument::OpenResult ObjectsMapDocument::openImpl(QString *error, bool ObjectsMapDocument::writeFile(const Utils::FilePath &fileName) const { - if (fileName.endsWith("object.map")) { + if (fileName.endsWith("objects.map")) { Utils::FileSaver saver(fileName); return saver.write(contents()) && saver.finalize(); } diff --git a/src/plugins/squish/squishfilehandler.cpp b/src/plugins/squish/squishfilehandler.cpp index 4bfe8eea299..99ee316bf2b 100644 --- a/src/plugins/squish/squishfilehandler.cpp +++ b/src/plugins/squish/squishfilehandler.cpp @@ -465,13 +465,15 @@ void SquishFileHandler::openObjectsMap(const QString &suiteName) const SuiteConf conf = SuiteConf::readSuiteConf(m_suites.value(suiteName)); const Utils::FilePath objectsMapPath = conf.objectMapPath(); - if (objectsMapPath.exists()) { - if (!Core::EditorManager::openEditor(objectsMapPath, Constants::OBJECTSMAP_EDITOR_ID)) { - QMessageBox::critical(Core::ICore::dialogParent(), - Tr::tr("Error"), - Tr::tr("Failed to open objects.map file at \"%1\".") - .arg(objectsMapPath.toUserOutput())); - } + QTC_ASSERT(!objectsMapPath.isEmpty(), return); + + QTC_ASSERT(conf.ensureObjectMapExists(), return); + + if (!Core::EditorManager::openEditor(objectsMapPath, Constants::OBJECTSMAP_EDITOR_ID)) { + QMessageBox::critical(Core::ICore::dialogParent(), + Tr::tr("Error"), + Tr::tr("Failed to open objects.map file at \"%1\".") + .arg(objectsMapPath.toUserOutput())); } } diff --git a/src/plugins/squish/suiteconf.cpp b/src/plugins/squish/suiteconf.cpp index d1a97e0847a..787f14698ea 100644 --- a/src/plugins/squish/suiteconf.cpp +++ b/src/plugins/squish/suiteconf.cpp @@ -189,7 +189,7 @@ Utils::FilePath SuiteConf::objectMapPath() const if (m_objectMapStyle == "script") return suiteDir.resolvePath("shared/scripts/names" + scriptExtension()); - return suiteDir.resolvePath(m_objectMap); + return suiteDir.resolvePath(m_objectMap.isEmpty() ? QString{"objects.map"} : m_objectMap); } QString SuiteConf::scriptExtension() const From 82b2b2cae98b353208a6eb39740ab7274ef752e3 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Tue, 11 Oct 2022 16:08:14 +0300 Subject: [PATCH 39/42] VCS: Fix misuses of parentDir().absolutePath() absolutePath() *is* the parent directory. Change-Id: I59f2c4ae65b265270d432f381258b95c65e53581 Reviewed-by: hjk --- src/plugins/bazaar/bazaarplugin.cpp | 2 +- src/plugins/clearcase/clearcaseplugin.cpp | 10 +++++----- src/plugins/git/gitplugin.cpp | 2 +- src/plugins/perforce/perforceplugin.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/plugins/bazaar/bazaarplugin.cpp b/src/plugins/bazaar/bazaarplugin.cpp index cbef03141ad..0867e24f994 100644 --- a/src/plugins/bazaar/bazaarplugin.cpp +++ b/src/plugins/bazaar/bazaarplugin.cpp @@ -942,7 +942,7 @@ bool BazaarPluginPrivate::vcsMove(const FilePath &from, const FilePath &to) { const QFileInfo fromInfo = from.toFileInfo(); const QFileInfo toInfo = to.toFileInfo(); - return m_client.synchronousMove(from.parentDir().absoluteFilePath(), + return m_client.synchronousMove(from.absolutePath(), fromInfo.absoluteFilePath(), toInfo.absoluteFilePath()); } diff --git a/src/plugins/clearcase/clearcaseplugin.cpp b/src/plugins/clearcase/clearcaseplugin.cpp index 459ac361fbd..8f316a09c51 100644 --- a/src/plugins/clearcase/clearcaseplugin.cpp +++ b/src/plugins/clearcase/clearcaseplugin.cpp @@ -2392,7 +2392,7 @@ IVersionControl::OpenSupportMode ClearCasePluginPrivate::openSupportMode(const F bool ClearCasePluginPrivate::vcsOpen(const FilePath &filePath) { - return vcsOpen(filePath.parentDir().absolutePath(), filePath.fileName()); + return vcsOpen(filePath.absolutePath(), filePath.fileName()); } IVersionControl::SettingsFlags ClearCasePluginPrivate::settingsFlags() const @@ -2405,22 +2405,22 @@ IVersionControl::SettingsFlags ClearCasePluginPrivate::settingsFlags() const bool ClearCasePluginPrivate::vcsAdd(const FilePath &filePath) { - return vcsAdd(filePath.parentDir().absolutePath(), filePath.fileName()); + return vcsAdd(filePath.absolutePath(), filePath.fileName()); } bool ClearCasePluginPrivate::vcsDelete(const FilePath &filePath) { - return vcsDelete(filePath.parentDir().absoluteFilePath(), filePath.fileName()); + return vcsDelete(filePath.absoluteFilePath(), filePath.fileName()); } bool ClearCasePluginPrivate::vcsMove(const FilePath &from, const FilePath &to) { - return vcsMove(from.parentDir().absolutePath(), from.fileName(), to.fileName()); + return vcsMove(from.absolutePath(), from.fileName(), to.fileName()); } void ClearCasePluginPrivate::vcsAnnotate(const FilePath &filePath, int line) { - vcsAnnotateHelper(filePath.parentDir().absolutePath(), filePath.fileName(), QString(), line); + vcsAnnotateHelper(filePath.absolutePath(), filePath.fileName(), QString(), line); } QString ClearCasePluginPrivate::vcsOpenText() const diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index f2e277a7552..0972ac8b36f 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -1841,7 +1841,7 @@ bool GitPluginPrivate::vcsMove(const FilePath &from, const FilePath &to) { const QFileInfo fromInfo = from.toFileInfo(); const QFileInfo toInfo = to.toFileInfo(); - return m_gitClient.synchronousMove(from.parentDir().absolutePath(), fromInfo.absoluteFilePath(), toInfo.absoluteFilePath()); + return m_gitClient.synchronousMove(from.absolutePath(), fromInfo.absoluteFilePath(), toInfo.absoluteFilePath()); } bool GitPluginPrivate::vcsCreateRepository(const FilePath &directory) diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp index 15202625682..770ad3ebca5 100644 --- a/src/plugins/perforce/perforceplugin.cpp +++ b/src/plugins/perforce/perforceplugin.cpp @@ -1172,7 +1172,7 @@ bool PerforcePluginPrivate::vcsMove(const FilePath &from, const FilePath &to) { const QFileInfo fromInfo = from.toFileInfo(); const QFileInfo toInfo = to.toFileInfo(); - return vcsMove(from.parentDir().absolutePath(), fromInfo.absoluteFilePath(), toInfo.absoluteFilePath()); + return vcsMove(from.absolutePath(), fromInfo.absoluteFilePath(), toInfo.absoluteFilePath()); } bool PerforcePluginPrivate::vcsCreateRepository(const FilePath &) From c50891611aaab863b239dc1081c1a6201b8d43e9 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 11 Oct 2022 15:50:42 +0200 Subject: [PATCH 40/42] FilePath: Fix absoluteFilePath to behave like absolutePath Change-Id: Ibb2cba32c40ec9febab5f20c78156481525c8904 Reviewed-by: hjk --- src/libs/utils/filepath.cpp | 4 +- tests/auto/utils/fileutils/tst_fileutils.cpp | 46 ++++++++++++++------ 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index 80035ac504f..8110cd9d34c 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -785,9 +785,9 @@ FilePath FilePath::absolutePath() const FilePath FilePath::absoluteFilePath() const { if (isAbsolutePath()) - return *this; + return cleanPath(); if (!needsDevice() && isEmpty()) - return *this; + return cleanPath(); return FilePath::currentWorkingPath().resolvePath(*this); } diff --git a/tests/auto/utils/fileutils/tst_fileutils.cpp b/tests/auto/utils/fileutils/tst_fileutils.cpp index 0522b320575..0248fb44891 100644 --- a/tests/auto/utils/fileutils/tst_fileutils.cpp +++ b/tests/auto/utils/fileutils/tst_fileutils.cpp @@ -46,8 +46,8 @@ private slots: void relativePath_data(); void relativePath(); - void absoluteFilePath_data(); - void absoluteFilePath(); + void absolute_data(); + void absolute(); void fromToString_data(); void fromToString(); @@ -379,26 +379,46 @@ void tst_fileutils::schemeAndHostLength() QCOMPARE(actual, result); } -void tst_fileutils::absoluteFilePath_data() +void tst_fileutils::absolute_data() { QTest::addColumn("path"); - QTest::addColumn("result"); + QTest::addColumn("absoluteFilePath"); + QTest::addColumn("absolutePath"); - QTest::newRow("absolute1") << FilePath::fromString("/") << FilePath::fromString("/"); - QTest::newRow("absolute2") << FilePath::fromString("C:/a/b") << FilePath::fromString("C:/a/b"); - QTest::newRow("absolute3") << FilePath::fromString("/a/b") << FilePath::fromString("/a/b"); - QTest::newRow("default-constructed") << FilePath() << FilePath(); + QTest::newRow("absolute1") << FilePath::fromString("/") + << FilePath::fromString("/") + << FilePath::fromString("/"); + QTest::newRow("absolute2") << FilePath::fromString("C:/a/b") + << FilePath::fromString("C:/a/b") + << FilePath::fromString("C:/a"); + QTest::newRow("absolute3") << FilePath::fromString("/a/b") + << FilePath::fromString("/a/b") + << FilePath::fromString("/a"); + QTest::newRow("absolute4") << FilePath::fromString("/a/b/..") + << FilePath::fromString("/a") + << FilePath::fromString("/"); + QTest::newRow("absolute5") << FilePath::fromString("/a/b/c/../d") + << FilePath::fromString("/a/b/d") + << FilePath::fromString("/a/b"); + QTest::newRow("absolute6") << FilePath::fromString("/a/../b/c/d") + << FilePath::fromString("/b/c/d") + << FilePath::fromString("/b/c"); + QTest::newRow("default-constructed") << FilePath() << FilePath() << FilePath(); QTest::newRow("relative") << FilePath::fromString("a/b") - << FilePath::fromString(QDir::currentPath() + "/a/b"); + << FilePath::fromString(QDir::currentPath() + "/a/b") + << FilePath::fromString(QDir::currentPath() + "/a"); QTest::newRow("qrc") << FilePath::fromString(":/foo/bar.txt") - << FilePath::fromString(":/foo/bar.txt"); + << FilePath::fromString(":/foo/bar.txt") + << FilePath::fromString(":/foo"); } -void tst_fileutils::absoluteFilePath() +void tst_fileutils::absolute() { QFETCH(FilePath, path); - QFETCH(FilePath, result); - QCOMPARE(path.absoluteFilePath(), result); + QFETCH(FilePath, absoluteFilePath); + QFETCH(FilePath, absolutePath); + QCOMPARE(path.absoluteFilePath(), absoluteFilePath); + QCOMPARE(path.absolutePath(), absolutePath); } void tst_fileutils::toString_data() From aa4f5249a5820675234de935e9fb34e5357fa566 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Tue, 11 Oct 2022 17:29:45 +0300 Subject: [PATCH 41/42] Utils: Remove unused include Change-Id: Ifa40f55444d31d74707b247d6bb471114cc9bb0c Reviewed-by: Jarek Kobus --- src/libs/utils/globalfilechangeblocker.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/utils/globalfilechangeblocker.cpp b/src/libs/utils/globalfilechangeblocker.cpp index 0c516b7f7a4..dba609303f2 100644 --- a/src/libs/utils/globalfilechangeblocker.cpp +++ b/src/libs/utils/globalfilechangeblocker.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "globalfilechangeblocker.h" -#include "qtcassert.h" #include From 693db6eef60327651b9ae9daf6f48835bfb73d66 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 11 Oct 2022 16:31:53 +0200 Subject: [PATCH 42/42] UnifiedDiffEditor: Fix '+' on added lines Amends 15fd4a075461a21cb28410f036aefc48b87316d3 Change-Id: If74b5437be241303de1e157b7980ef10ef6c060c Reviewed-by: Orgad Shaneh --- src/plugins/diffeditor/unifieddiffeditorwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp index b6a40b18ed0..e182417a831 100644 --- a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp +++ b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp @@ -332,7 +332,7 @@ QString UnifiedDiffData::setChunk(const DiffEditorInput &input, const ChunkData for (int j = 0; j < buffer[side].count(); j++) { const TextLineData &lineData = buffer[side].at(j); const QString line = DiffUtils::makePatchLine( - '-', + side == LeftSide ? '-' : '+', lineData.text, lastChunk, chunkIndex == chunkData.rows.count() && j == buffer[side].count() - 1);