From 80b5e8b9f0f789229526ef738c3200c1726fcc00 Mon Sep 17 00:00:00 2001 From: Sergey Belyashov Date: Tue, 18 Nov 2014 11:47:12 +0300 Subject: [PATCH 01/40] Update Russian translation Change-Id: I03664ff7d166638f7c59fa1e54a0df9545339bdf Reviewed-by: Denis Shienkov Reviewed-by: Oswald Buddenhagen --- share/qtcreator/translations/qtcreator_ru.ts | 73 +++++++++++++++----- 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/share/qtcreator/translations/qtcreator_ru.ts b/share/qtcreator/translations/qtcreator_ru.ts index 14bcfed4730..7788cc509bf 100644 --- a/share/qtcreator/translations/qtcreator_ru.ts +++ b/share/qtcreator/translations/qtcreator_ru.ts @@ -540,6 +540,10 @@ Do you want to uninstall the existing package next time? API Level of device is: %1. Уровень API устройства: %1. + + Android 5 devices are incompatible with deploying Qt to a temporary directory. + Устройства на базе Android 5 не поддерживают установку Qt во временный каталог. + Incompatible devices Несовместимые устройства @@ -857,6 +861,14 @@ Do you want to uninstall the existing package next time? Failed to forward C++ debugging ports. Не удалось пробросить порты отладки С++. + + Failed to forward ping pong ports. Reason: %1. + Не удалось пробросить порты ping pong: %1. + + + Failed to forward ping pong ports. + Не удалось пробросить порты ping pong. + Failed to forward QML debugging ports. Reason: %1. Не удалось пробросить порты отладки QML: %1. @@ -869,6 +881,10 @@ Do you want to uninstall the existing package next time? Failed to start the activity. Reason: %1. Не удалось запустить activity: %1. + + Failed to contact debugging port. + Не удалось подключиться к порту отладки. + "%1" terminated. «%1» завершён. @@ -1032,10 +1048,6 @@ Install an SDK of at least API version %1. Certificate alias: Алиас сертификата: - - Signing an APK that uses "Deploy local Qt libraries" is not allowed - Подписывание APK, использующего локальные библиотеки Qt, запрещено - Application Приложение @@ -1090,6 +1102,12 @@ The APK will not be usable on any other device. Deploy local Qt libraries to temporary directory Устанавливать Qt во временный каталог + + Signing an APK that uses "Deploy local Qt libraries" is not allowed. +Deploying local Qt libraries is incompatible with Android 5 + Подписывание APK, использующего локальные библиотеки Qt, запрещено. +Установка локальных библиотек Qt не поддерживается на Android 5 + AndroidConfig @@ -4200,10 +4218,6 @@ This wizard will guide you through the essential steps to deploy a ready-to-go d Meta+C,Meta+P Meta+C,Meta+P - - Paste Clipboard... - Вставить из буфера обмена... - Fetch Snippet... Получить фрагмент... @@ -10017,14 +10031,6 @@ This feature is only available for GDB. Populate source file view automatically Автоматически заполнять представление исходных текстов - - Close temporary views on debugger exit - Закрывать временные обзоры при завершении отладчика - - - Stopping and stepping in the debugger will automatically open source or disassembler views associated with the current location. Select this option to automatically close them when the debugger exits. - Остановка и пошаговая отладка автоматически открывают обзор исходников или дизассемблера соответствующий текущему положению. Включение этого параметра приведёт к их автоматическому закрытию при завершении отладки. - Switch to previous mode on debugger exit Переключаться в предыдущий режим при завершении отладчика @@ -10053,6 +10059,26 @@ This feature is only available for GDB. Show QML object tree Показывать дерево объектов QML + + Stopping and stepping in the debugger will automatically open views associated with the current location. + Остановка и пошаговая отладка автоматически открывают обзор кода соответствующий текущему положению. + + + Close temporary source views on debugger exit + Закрывать временные обзоры кода при завершении отладки + + + Select this option to close automatically opened source views when the debugger exits. + Включение закрытия автоматически открытых обзоров исходников при завершении отладки. + + + Close temporary memory views on debugger exit + Закрывать временные обзоры памяти при завершении отладки + + + Select this option to close automatically opened memory views when the debugger exits. + Включение закрытия автоматически открытых обзоров памяти при завершении отладки. + Set breakpoints using a full absolute path Задавать полный путь к точкам останова @@ -19862,6 +19888,10 @@ Ids must begin with a lowercase letter. The process terminated with exit code %1. Процесс завершился с кодом %1. + + [Only %1 MB of output shown] + [Отображено только %1 МБ вывода] + The commit message check failed. Do you want to submit this change list? Проверки сообщения о фиксации завершилась с ошибкой. Отправить указанные изменения? @@ -23166,6 +23196,17 @@ to project "%2". Сделать по умолчанию + + ProjectExplorer::LineEditValidator + + Line Edit Validator Expander + Расширитель валидатора строкового редактора + + + The text edit input to fix up. + Данные для исправления в текстовом редакторе. + + ProjectExplorer::LocalEnvironmentAspect From 9e501ee8f11486e4686e2a6f38d9993f78989f91 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 24 Nov 2014 16:52:07 +0100 Subject: [PATCH 02/40] Kits: Validate current displayname when changing it We used to validate the displayname set before the last change, which is not really useful:-) Task-number: QTCREATORBUG-13424 Change-Id: Ia71f82d0ab0c8d6392be8dbd8fccad7fb9230b2d Reviewed-by: Daniel Teske --- .../projectexplorer/kitmanagerconfigwidget.cpp | 12 +++++++----- src/plugins/projectexplorer/kitmanagerconfigwidget.h | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp index 4f93eb55fc9..ab986509b4a 100644 --- a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp @@ -141,7 +141,9 @@ KitManagerConfigWidget::~KitManagerConfigWidget() QString KitManagerConfigWidget::displayName() const { - return m_displayName; + if (m_cachedDisplayName.isEmpty()) + m_cachedDisplayName = m_modifiedKit->displayName(); + return m_cachedDisplayName; } void KitManagerConfigWidget::apply() @@ -175,7 +177,7 @@ void KitManagerConfigWidget::discard() } m_iconButton->setIcon(m_modifiedKit->icon()); m_nameEdit->setText(m_modifiedKit->unexpandedDisplayName()); - m_displayName = m_modifiedKit->displayName(); + m_cachedDisplayName.clear(); m_fileSystemFriendlyNameLineEdit->setText(m_modifiedKit->customFileSystemFriendlyName()); emit dirty(); } @@ -315,9 +317,9 @@ void KitManagerConfigWidget::setIcon() void KitManagerConfigWidget::setDisplayName() { int pos = m_nameEdit->cursorPosition(); + m_cachedDisplayName.clear(); m_modifiedKit->setUnexpandedDisplayName(m_nameEdit->text()); m_nameEdit->setCursorPosition(pos); - m_displayName = m_modifiedKit->displayName(); } void KitManagerConfigWidget::setFileSystemFriendlyName() @@ -339,11 +341,11 @@ void KitManagerConfigWidget::workingCopyWasUpdated(Kit *k) foreach (KitConfigWidget *w, m_widgets) w->refresh(); + m_cachedDisplayName.clear(); + if (k->unexpandedDisplayName() != m_nameEdit->text()) m_nameEdit->setText(k->unexpandedDisplayName()); - m_displayName = k->displayName(); - m_fileSystemFriendlyNameLineEdit->setText(k->customFileSystemFriendlyName()); m_iconButton->setIcon(k->icon()); updateVisibility(); diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.h b/src/plugins/projectexplorer/kitmanagerconfigwidget.h index 51651c75c36..e7b5dddc3ab 100644 --- a/src/plugins/projectexplorer/kitmanagerconfigwidget.h +++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.h @@ -109,7 +109,7 @@ private: bool m_hasUniqueName; QPixmap m_background; QList m_actions; - QString m_displayName; + mutable QString m_cachedDisplayName; }; } // namespace Internal From 4e97e835d8a0698531e584cd8e60cfbdb757f647 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 25 Nov 2014 15:50:14 +0100 Subject: [PATCH 03/40] Doc: add "Configuring Qt Creator" to the GS page This topic was added to the Getting Started section in the TOC earlier, and this patch adds it also to the page. Change-Id: I1f310046c85ca71619d057f4710b54e8f5f5c75e Reviewed-by: Alessandro Portale --- doc/src/overview/creator-getting-started.qdoc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/src/overview/creator-getting-started.qdoc b/doc/src/overview/creator-getting-started.qdoc index 0a1b407f593..80549b923c2 100644 --- a/doc/src/overview/creator-getting-started.qdoc +++ b/doc/src/overview/creator-getting-started.qdoc @@ -34,6 +34,7 @@ \row \li \inlineimage creator-gs-01.png \li \inlineimage creator-gs-02.png + \li \inlineimage creator_advanceduse.png \row \li \b {\l{IDE Overview}} @@ -44,9 +45,17 @@ If you have not used \QC before, and want to become familiar with the parts of the user interface, go to \l{User Interface}. + \li \b {\l{Configuring Qt Creator}} + + To make \QC behave more like your favorite code editor or IDE, + you can change the settings for keyboard shortcuts, color + schemes, generic highlighting, code snippets, and version + control systems. For an overview of the options you have, go to + \l{Configuring Qt Creator}. \row \li \inlineimage creator-gs-03.png \li \inlineimage creator-gs-04.png + \li \row \li \b {\l{Building and Running an Example}} @@ -59,6 +68,7 @@ Now you are ready to start developing your own applications. Pick a tutorial to follow in \l{Tutorials}. To start developing for mobile devices, select \l{Creating a Mobile Application}. + \li \endtable */ From e5c53d6d01a0109bb5c1c3f08d0536c08d8c7018 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 25 Nov 2014 12:42:26 +0100 Subject: [PATCH 04/40] Doc: modifying variable values for build and run environments Update screenshot. Task-number: QTCREATORBUG-13516 Change-Id: Ia2c5786f8fd7ce3f63fdc44940341f7fb3af1269 Reviewed-by: Kai Koehne Reviewed-by: hjk --- doc/images/qtcreator-kits.png | Bin 62550 -> 27905 bytes .../creator-projects-settings-build.qdoc | 21 ++++++++++++++++++ .../creator-projects-settings-run.qdoc | 3 +++ .../projects/creator-projects-targets.qdoc | 5 +++++ 4 files changed, 29 insertions(+) diff --git a/doc/images/qtcreator-kits.png b/doc/images/qtcreator-kits.png index ad7c6017174706cee50b631da331d07119ff752c..15243c74a4f1b681eb74eab263f9d1ad1798be9b 100644 GIT binary patch literal 27905 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 literal 62550 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 YY?g8MUGdWi3=9kmp00i_>zopr02s=KN&o-= diff --git a/doc/src/projects/creator-projects-settings-build.qdoc b/doc/src/projects/creator-projects-settings-build.qdoc index d4c4709d4ff..e0da2a7fe9a 100644 --- a/doc/src/projects/creator-projects-settings-build.qdoc +++ b/doc/src/projects/creator-projects-settings-build.qdoc @@ -181,6 +181,27 @@ development PCs. To share settings, incorporate them into the build system. For example, if you use qmake, make the changes in the \c{.pro} file. + \section2 Batch Editing + + To modify environment variable values for build or run environments, + select \gui {Batch Edit} in the build or run settings and enter environment + variables in the \gui {Edit Environment} dialog. + + To remove a variable value from the environment, enter the variable name. + For example, \c TEST sets the value of the \c TEST variable empty when + building or running the project. + + To add a variable value to the environment, enter the variable name and + value, separated by the equals sign. For example, the following line + prepends \c /opt/bin to the existing PATH: + + \c {PATH=/opt/bin:${PATH}} + + To add or remove several variables, place them on separate lines. The order + is important. If you remove a value on a line, you cannot refer to it on the + following lines. However, you can remove a value after you have referred to + it on an earlier line. + \section2 Clearing the System Environment To build with a clean system environment, select the \gui {Clear system diff --git a/doc/src/projects/creator-projects-settings-run.qdoc b/doc/src/projects/creator-projects-settings-run.qdoc index 5ffc53a4c84..b2e072dcb8a 100644 --- a/doc/src/projects/creator-projects-settings-run.qdoc +++ b/doc/src/projects/creator-projects-settings-run.qdoc @@ -82,6 +82,9 @@ fetches information about the \gui {Device Environment} from the device. Usually, it does not make sense to edit the device environment. + To modify the environment variable values for the run environment, select + \gui {Batch Edit}. For more information, see \l{Batch Editing}. + \section1 Specifying a Custom Executable to Run If you use CMake or the generic project type in \QC, or want diff --git a/doc/src/projects/creator-projects-targets.qdoc b/doc/src/projects/creator-projects-targets.qdoc index ea9e9c605f1..3b6926d48cb 100644 --- a/doc/src/projects/creator-projects-targets.qdoc +++ b/doc/src/projects/creator-projects-targets.qdoc @@ -91,6 +91,11 @@ if they are installed on the development PC, but were not detected automatically. For more information, see \l{Adding Compilers}. + \li In the \gui Environment field, select \gui Change to modify + environment variable values for build and run environments in + the \gui {Edit Environment Changes} dialog. For more information + about how to add and remove variable values, see \l{Batch Editing}. + \li In the \gui Debugger field, select the debugger to debug the project on the target platform. \QC automatically detects available debuggers and displays a suitable debugger in the field. You can From 6376d01e8bd0c26ba882fd29228041946c01780c Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 20 Nov 2014 17:15:32 +0100 Subject: [PATCH 05/40] Doc: Android 5 supports only bundling libraries in APK Change-Id: I1fb8387b38a93a343897cc4b2e5d36f542129b6a Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: BogDan Vatra --- doc/src/android/deploying-android.qdoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/src/android/deploying-android.qdoc b/doc/src/android/deploying-android.qdoc index b9602e0ced3..6024ec0ba65 100644 --- a/doc/src/android/deploying-android.qdoc +++ b/doc/src/android/deploying-android.qdoc @@ -53,6 +53,8 @@ To copy Qt libraries and files to the project directory and to bundle them as part of the APK, select the \gui {Bundle Qt libraries in APK} option. + \note Android 5 devices support only this option. + \section1 Using Ministro to Install Qt Libraries To minimize the size of your APK, you can package the application with an From a1f8bc4c5fe1f1098c5b6ee67d098d23d7c77f17 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 25 Nov 2014 15:42:26 +0100 Subject: [PATCH 06/40] ios: ensure that device and simulator scan with a developerPath Change-Id: Ifcc8d8f5c389c963ee1b6c2d2d2437bd5429f843 Reviewed-by: Fawzi Mohamed --- src/plugins/ios/iosconfigurations.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp index c980c34002f..8b0772ca676 100644 --- a/src/plugins/ios/iosconfigurations.cpp +++ b/src/plugins/ios/iosconfigurations.cpp @@ -362,8 +362,6 @@ void IosConfigurations::initialize() { QTC_CHECK(m_instance == 0); m_instance = new IosConfigurations(0); - m_instance->updateSimulators(); - QTimer::singleShot(10000, IosDeviceManager::instance(), SLOT(monitorAvailableDevices())); } bool IosConfigurations::ignoreAllDevices() @@ -422,10 +420,15 @@ void IosConfigurations::updateSimulators() void IosConfigurations::setDeveloperPath(const FileName &devPath) { + static bool hasDevPath = false; if (devPath != m_instance->m_developerPath) { m_instance->m_developerPath = devPath; m_instance->save(); - updateAutomaticKitList(); + if (!hasDevPath && !devPath.isEmpty()) { + hasDevPath = true; + QTimer::singleShot(1000, IosDeviceManager::instance(), SLOT(monitorAvailableDevices())); + m_instance->updateSimulators(); + } emit m_instance->updated(); } } From f395bc907691b4a4b577a04c55c6e1cb5c93a2f9 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 26 Nov 2014 14:40:53 +0100 Subject: [PATCH 07/40] Debugger: Fix reference dumping with LLDB-300.x The old code worked around some issue that is not present anymore and breaks now by itself. So remove the workaround. Change-Id: I41a017ced91198bdc4e822cfcc1c45580945a773 Reviewed-by: Christian Stenger --- share/qtcreator/debugger/lldbbridge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 7e4d4e5c811..933c89b5447 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -988,7 +988,7 @@ class Dumper(DumperBase): if value.GetType().IsReferenceType(): origType = value.GetTypeName(); type = value.GetType().GetDereferencedType().unqualified() - addr = int(value) & 0xFFFFFFFFFFFFFFFF + addr = value.GetLoadAddress() self.putItem(value.CreateValueFromAddress(None, addr, type)) self.putBetterType(origType) return From cb9727f0e910b82154616675874c4a452f2cfdca Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 26 Nov 2014 12:09:12 +0100 Subject: [PATCH 08/40] Doc: mention alternative build systems in yet more places Qbs is no longer experimental and wizards for creating Qbs projects are also available. Change-Id: I59e6888a8add3e9e77de69292758f31de5dda027 Reviewed-by: Christian Kandeler --- doc/src/overview/creator-advanced.qdoc | 5 +++-- doc/src/projects/creator-projects-creating.qdoc | 13 +++++++------ doc/src/projects/creator-projects-other.qdoc | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/doc/src/overview/creator-advanced.qdoc b/doc/src/overview/creator-advanced.qdoc index d3767fd756f..6c73d81ffcd 100644 --- a/doc/src/overview/creator-advanced.qdoc +++ b/doc/src/overview/creator-advanced.qdoc @@ -53,8 +53,9 @@ \li \l{Using Other Build Systems} \QC is integrated with cross-platform systems for build automation: - qmake and CMake. In addition, you can import generic projects that - do not use qmake or CMake, and specify that \QC ignores your build + qmake, Qbs, CMake, and Autotools. In addition, you can import + generic projects that do not use those systems, and specify that \QC + ignores your build system. \li \l{Using Command Line Options} diff --git a/doc/src/projects/creator-projects-creating.qdoc b/doc/src/projects/creator-projects-creating.qdoc index 5eebf271190..926770cdb65 100644 --- a/doc/src/projects/creator-projects-creating.qdoc +++ b/doc/src/projects/creator-projects-creating.qdoc @@ -50,7 +50,7 @@ the necessary files for you. You can add your own custom wizards to standardize the way subprojects and classes are added to a project. - The wizards create projects that use the Qt build tool, qmake. It is a + Most wizards create projects that use the Qt build tool, qmake. It is a cross-platform system for build automation that helps simplify the build process for development projects across different platforms. qmake automates the generation of build configurations so that only a few lines @@ -59,9 +59,11 @@ You can modify the build and run settings for qmake projects in the \gui Projects mode. - Alternatively, you can use the CMake build automation system and set up the - projects manually. In addition, you can import projects as - \e {generic projects} that do not use qmake or CMake. This enables you to + You can use wizards also to create plain C or C++ projects that use Qbs or + CMake, but do not use the Qt library. + + In addition, you can import projects as \e {generic projects} that do not + use qmake, Qbs, or CMake. This enables you to use \QC as a code editor and to fully control the steps and commands used to build the project. @@ -196,8 +198,7 @@ \li Plain C or C++ Project (Qbs Build) Plain C or C++ project that uses Qbs but does not use the Qt - library. This project type is listed if the experimental Qbs - plugin has been enabled in \gui Help > \gui {About Plugins}. + library. \endlist diff --git a/doc/src/projects/creator-projects-other.qdoc b/doc/src/projects/creator-projects-other.qdoc index b363458c971..86848e00931 100644 --- a/doc/src/projects/creator-projects-other.qdoc +++ b/doc/src/projects/creator-projects-other.qdoc @@ -30,7 +30,7 @@ \title Using Other Build Systems - \QC project wizards create projects that are configured to use qmake. Most + Most \QC project wizards create projects that are configured to use qmake. Most of the instructions in this manual apply to using qmake. However, \QC is also integrated to other build systems, as described in the the following sections: From d927a80f2b5b41643f244715214b9d9eee4abc4d Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 25 Nov 2014 16:37:31 +0100 Subject: [PATCH 09/40] TextEditor: Stop SnippetMode before invoking refactoring action Task-number: QTCREATORBUG-13519 Change-Id: I206d83251c717dde419394658b5fdea8e5da48d3 Reviewed-by: David Schulz --- src/plugins/texteditor/texteditor.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 1f6e6a4a95d..0de6b93ee08 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -7076,6 +7076,12 @@ void TextEditorWidget::inSnippetMode(bool *active) void TextEditorWidget::invokeAssist(AssistKind kind, IAssistProvider *provider) { + if (kind == QuickFix && d->m_snippetOverlay->isVisible()) { + d->m_snippetOverlay->setVisible(false); + d->m_snippetOverlay->mangle(); + d->m_snippetOverlay->clear(); + } + bool previousMode = overwriteMode(); setOverwriteMode(false); ensureCursorVisible(); From 9b0bdf981f5d81a004062cfbe308e75c64b3f186 Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed Date: Wed, 26 Nov 2014 17:07:45 +0100 Subject: [PATCH 10/40] qmljs: fix library path for builtins Change-Id: Ie43f7a3241ae8d253853a0b38781774a70cb6897 Reviewed-by: hjk Reviewed-by: Fawzi Mohamed --- src/libs/qmljs/qmljsplugindumper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/qmljs/qmljsplugindumper.cpp b/src/libs/qmljs/qmljsplugindumper.cpp index 63ad5f40ff4..1642d9d024b 100644 --- a/src/libs/qmljs/qmljsplugindumper.cpp +++ b/src/libs/qmljs/qmljsplugindumper.cpp @@ -93,10 +93,10 @@ void PluginDumper::scheduleMaybeRedumpBuiltins(const QmlJS::ModelManagerInterfac void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::ProjectInfo &info, bool force) { - if (info.qmlDumpPath.isEmpty() || (info.qtImportsPath.isEmpty() && info.qtQmlPath.isEmpty())) + const QString baseImportsPath = info.qtQmlPath.isEmpty() ? info.qtImportsPath : info.qtQmlPath; + if (info.qmlDumpPath.isEmpty() || baseImportsPath.isEmpty()) return; - const QString baseImportsPath = info.qtQmlPath.isEmpty() ? info.qtImportsPath : info.qtQmlPath; const QString importsPath = QDir::cleanPath(baseImportsPath); if (m_runningQmldumps.values().contains(importsPath)) return; @@ -109,7 +109,7 @@ void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::Projec return; } builtinInfo = LibraryInfo(LibraryInfo::Found); - m_modelManager->updateLibraryInfo(info.qtImportsPath, builtinInfo); + m_modelManager->updateLibraryInfo(baseImportsPath, builtinInfo); // prefer QTDIR/qml/builtins.qmltypes if available const QString builtinQmltypesPath = baseImportsPath + QLatin1String("/builtins.qmltypes"); From 9f272bcb8c1853027e92e769e257adbd8e2ce5f0 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 26 Nov 2014 17:12:39 +0100 Subject: [PATCH 11/40] Debugger: Also output dumper location in LLDB auto test Change-Id: I51a017ced91198bdc4e822cfcc1c45580945a773 Reviewed-by: Christian Stenger --- tests/auto/debugger/tst_dumpers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index c7b2ca77731..1c56f9031e8 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -935,6 +935,7 @@ void tst_Dumpers::initTestCase() } else if (m_debuggerEngine == CdbEngine) { setupCdb(&m_makeBinary, &m_env); } else if (m_debuggerEngine == LldbEngine) { + qDebug() << "Dumper dir : " << DUMPERDIR; QProcess debugger; QString cmd = QString::fromUtf8(m_debuggerBinary + " -v"); debugger.start(cmd); From 5cc3378858c62dfd9b0a6190b82b9f1762a20d0b Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 26 Nov 2014 13:45:22 +0100 Subject: [PATCH 12/40] CppEditor: Fix crash in InsertQtPropertyMembers for invalid code Change-Id: I8a3a3240033d23aa9e3df5276c4e6302d97f71b9 Reviewed-by: Erik Verbruggen --- src/plugins/cppeditor/cppquickfix_test.cpp | 5 +++++ src/plugins/cppeditor/cppquickfixes.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 70d2e1c267a..3269df3c0da 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -1467,6 +1467,11 @@ void CppEditorPlugin::test_quickfix_data() " }\n" " f1(*str);\n" "}\n"); + + QTest::newRow("InsertQtPropertyMembers_noTriggerInvalidCode") + << CppQuickFixFactoryPtr(new InsertQtPropertyMembers) + << _("class C { @Q_PROPERTY(typeid foo READ foo) };\n") + << _(); } void CppEditorPlugin::test_quickfix() diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 44e8e882780..36a0d41d5b5 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -4254,7 +4254,7 @@ void InsertQtPropertyMembers::match(const CppQuickFixInterface &interface, AST * const ast = path.last(); QtPropertyDeclarationAST *qtPropertyDeclaration = ast->asQtPropertyDeclaration(); - if (!qtPropertyDeclaration) + if (!qtPropertyDeclaration || !qtPropertyDeclaration->type_id) return; ClassSpecifierAST *klass = 0; From 0ef06c75233c73589e045760415e9de19c53c349 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 26 Nov 2014 17:18:47 +0100 Subject: [PATCH 13/40] Core: Normalize given filePath in DocumentModel TextDocument::open() sets a clean absolute path for the document, but DocumentModel::documentForFilePath() did not normalize before comparing. This resulted in the creation of multiple TextDocuments and Widgets for the same path. Was re-producible with: 1. Open the locator 2. Type "f a.cpp" and Enter 3. Go to 1. Point 2 lead to an EditorManager::openEditor() call with an unclean path. The second iteration triggered an QTC_ASSERT in CppModelManager. Regression introduced by: commit 292cf6c9e87d2c293be6eb2808530dbbd728c8b6 Algorithms for DocumentModel Change-Id: I82fbc39251e48c1c97d6933857de172818d73f13 Reviewed-by: Christian Kandeler Reviewed-by: Eike Ziller --- src/plugins/coreplugin/editormanager/documentmodel.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/coreplugin/editormanager/documentmodel.cpp b/src/plugins/coreplugin/editormanager/documentmodel.cpp index 27d79aef993..8c2825a06cf 100644 --- a/src/plugins/coreplugin/editormanager/documentmodel.cpp +++ b/src/plugins/coreplugin/editormanager/documentmodel.cpp @@ -330,8 +330,10 @@ QList DocumentModel::openedDocuments() IDocument *DocumentModel::documentForFilePath(const QString &filePath) { - Entry *e = Utils::findOrDefault(d->m_entries, Utils::equal(&Entry::fileName, filePath)); - return e ? e->document : 0; + const int index = d->indexOfFilePath(filePath); + if (index < 0) + return 0; + return d->m_entries.at(index)->document; } QList DocumentModel::editorsForFilePath(const QString &filePath) From 888191056592ee0832e1c3155dd822beaa4db552 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 27 Nov 2014 09:17:21 +0100 Subject: [PATCH 14/40] SSH: Delay channel close request to server in SessionRequested state. If closeChannel() is called in between our channel open request to the server and the corresponding reply, we cannot forward the close request to the server, as we don't have its channel id yet. So wait until we do. Our failure to correctly handle this sequence of events was the root cause for the following user-visible errors: - A (since-removed) Q_ASSERT in ~SshRemoteProcess() was hit. - The server closed the connection because we referred to an invalid channel ("Received ieof for nonexistent channel -1"). Commits 26920307f0 and 3027bcc952 are also related to this issue. Change-Id: I4994d85f5b21a72682f75389cdf8769738bd6768 Reviewed-by: hjk --- src/libs/ssh/sshchannel.cpp | 19 +++++++++++++------ src/libs/ssh/sshremoteprocess.cpp | 2 ++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/libs/ssh/sshchannel.cpp b/src/libs/ssh/sshchannel.cpp index 269cee765bc..6e060356b49 100644 --- a/src/libs/ssh/sshchannel.cpp +++ b/src/libs/ssh/sshchannel.cpp @@ -137,11 +137,11 @@ void AbstractSshChannel::flushSendBuffer() void AbstractSshChannel::handleOpenSuccess(quint32 remoteChannelId, quint32 remoteWindowSize, quint32 remoteMaxPacketSize) { - switch (m_state) { + const ChannelState oldState = m_state; + switch (oldState) { + case CloseRequested: // closeChannel() was called while we were in SessionRequested state case SessionRequested: break; // Ok, continue. - case CloseRequested: - return; // Late server reply; we requested a channel close in the meantime. default: throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR, "Unexpected SSH_MSG_CHANNEL_OPEN_CONFIRMATION packet."); @@ -163,7 +163,10 @@ void AbstractSshChannel::handleOpenSuccess(quint32 remoteChannelId, m_remoteWindowSize = remoteWindowSize; m_remoteMaxPacketSize = remoteMaxPacketSize; setChannelState(SessionEstablished); - handleOpenSuccessInternal(); + if (oldState == CloseRequested) + closeChannel(); + else + handleOpenSuccessInternal(); } void AbstractSshChannel::handleOpenFailure(const QString &reason) @@ -260,8 +263,12 @@ void AbstractSshChannel::closeChannel() setChannelState(Closed); } else { setChannelState(CloseRequested); - m_sendFacility.sendChannelEofPacket(m_remoteChannel); - m_sendFacility.sendChannelClosePacket(m_remoteChannel); + if (m_remoteChannel != NoChannel) { + m_sendFacility.sendChannelEofPacket(m_remoteChannel); + m_sendFacility.sendChannelClosePacket(m_remoteChannel); + } else { + QSSH_ASSERT(m_state == SessionRequested); + } } } } diff --git a/src/libs/ssh/sshremoteprocess.cpp b/src/libs/ssh/sshremoteprocess.cpp index bd8bd6dc9fb..37bc172e7cf 100644 --- a/src/libs/ssh/sshremoteprocess.cpp +++ b/src/libs/ssh/sshremoteprocess.cpp @@ -31,6 +31,7 @@ #include "sshremoteprocess.h" #include "sshremoteprocess_p.h" +#include "ssh_global.h" #include "sshincomingpacket_p.h" #include "sshsendfacility_p.h" @@ -85,6 +86,7 @@ SshRemoteProcess::SshRemoteProcess(quint32 channelId, Internal::SshSendFacility SshRemoteProcess::~SshRemoteProcess() { + QSSH_ASSERT(d->channelState() != Internal::AbstractSshChannel::SessionEstablished); close(); delete d; } From 28fb4cc01514d26e48f136d61113f6facfe14aca Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Fri, 5 Sep 2014 10:27:19 +0200 Subject: [PATCH 15/40] Qnx: Fix plugin unit test Change-Id: Ia5a16eba656190ee904f00290b23b5108e27d8b3 Reviewed-by: hjk --- src/plugins/qnx/qnxbaseconfiguration.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/qnx/qnxbaseconfiguration.cpp b/src/plugins/qnx/qnxbaseconfiguration.cpp index 2cd9c75f208..bbff2fb9dfe 100644 --- a/src/plugins/qnx/qnxbaseconfiguration.cpp +++ b/src/plugins/qnx/qnxbaseconfiguration.cpp @@ -136,7 +136,10 @@ bool QnxBaseConfiguration::isValid() const void QnxBaseConfiguration::ctor(const FileName &envScript) { - QTC_ASSERT(!envScript.isEmpty() && envScript.exists(), return); + QTC_ASSERT(!envScript.isEmpty(), return); +#if !defined(WITH_TESTS) + QTC_ASSERT(envScript.exists(), return); +#endif m_envFile = envScript; m_qnxEnv = QnxUtils::qnxEnvironmentFromEnvFile(m_envFile.toString()); foreach (const Utils::EnvironmentItem &item, m_qnxEnv) { From c5d86757a1ed7f07cf993bd64e43683475934a4b Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 27 Nov 2014 14:31:02 +0100 Subject: [PATCH 16/40] Debugger: Fix engine state after "unreasonable jump requests" After attempting to jump to an inaccessible location, the engine was still expecting a ^running, while in fact GDB was stopped. Add the right state transition. Change-Id: I69aec785a1e9d2a23771f74ae35064ae61405fa5 Reviewed-by: Christian Stenger --- src/plugins/debugger/gdb/gdbengine.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 54a429933df..8862f1ebc1b 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1292,6 +1292,14 @@ void GdbEngine::handleExecuteJumpToLine(const GdbResponse &response) // All is fine. Waiting for a *running // and the temporary breakpoint to be hit. notifyInferiorRunOk(); // Only needed for gdb < 7.0. + } else if (response.resultClass == GdbResultError) { + // Could be "Unreasonable jump request" or similar. + QString out = tr("Cannot jump. Stopped"); + QByteArray msg = response.data["msg"].data(); + if (!msg.isEmpty()) + out += QString::fromLatin1(". " + msg); + showStatusMessage(out); + notifyInferiorRunFailed(); } else if (response.resultClass == GdbResultDone) { // This happens on old gdb. Trigger the effect of a '*stopped'. showStatusMessage(tr("Jumped. Stopped")); From c7c8f88303f11896984bf3c317502bf1b66a2a3a Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 25 Nov 2014 10:49:47 +0100 Subject: [PATCH 17/40] Valgrind: Do not put html links in clipboard ...but plain, canonical and absolute paths if possible. Change-Id: Ib559f00a55646929b2e548e7e671c1cb5e1d4a79 Reviewed-by: hjk --- src/plugins/valgrind/memcheckerrorview.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/plugins/valgrind/memcheckerrorview.cpp b/src/plugins/valgrind/memcheckerrorview.cpp index 33dc3eab242..4be816acc69 100644 --- a/src/plugins/valgrind/memcheckerrorview.cpp +++ b/src/plugins/valgrind/memcheckerrorview.cpp @@ -137,7 +137,8 @@ static QString relativeToPath() } static QString errorLocation(const QModelIndex &index, const Error &error, - bool link = false, const QString &linkAttr = QString()) + bool link = false, bool absolutePath = false, + const QString &linkAttr = QString()) { if (!index.isValid()) return QString(); @@ -149,8 +150,9 @@ static QString errorLocation(const QModelIndex &index, const Error &error, } QTC_ASSERT(model, return QString()); + const QString relativePath = absolutePath ? QString() : relativeToPath(); return QCoreApplication::translate("Valgrind::Internal", "in %1"). - arg(makeFrameName(model->findRelevantFrame(error), relativeToPath(), + arg(makeFrameName(model->findRelevantFrame(error), relativePath, link, linkAttr)); } @@ -181,7 +183,9 @@ QWidget *MemcheckErrorDelegate::createDetailsWidget(const QFont & font, p.setBrush(QPalette::Text, p.highlightedText()); errorLabel->setPalette(p); errorLabel->setText(QString::fromLatin1("%1  %2") - .arg(error.what(), errorLocation(errorIndex, error, true, linkStyle), + .arg(error.what(), + errorLocation(errorIndex, error, /*link=*/ true, + /*absolutePath=*/ false, linkStyle), linkStyle)); connect(errorLabel, &QLabel::linkActivated, this, &MemcheckErrorDelegate::openLinkInEditor); @@ -265,17 +269,16 @@ void MemcheckErrorDelegate::copy() const Error error = m_detailsIndex.data(ErrorListModel::ErrorRole).value(); stream << error.what() << "\n"; - stream << " " << errorLocation(m_detailsIndex, error) << "\n"; - - const QString relativeTo = relativeToPath(); + stream << " " + << errorLocation(m_detailsIndex, error, /*link=*/ false, /*absolutePath=*/ true) + << "\n"; foreach (const Stack &stack, error.stacks()) { if (!stack.auxWhat().isEmpty()) stream << stack.auxWhat(); int i = 1; - foreach (const Frame &frame, stack.frames()) { - stream << " " << i++ << ": " << makeFrameName(frame, relativeTo) << "\n"; - } + foreach (const Frame &frame, stack.frames()) + stream << " " << i++ << ": " << makeFrameName(frame, QString(), false) << "\n"; } stream.flush(); From 804497c32cd1ad393661d0fa1f6ef63fb978ad0d Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 25 Nov 2014 14:22:33 +0100 Subject: [PATCH 18/40] Perforce: Limit log length even further MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... and cut at the right end. Change-Id: I89905baa86c89946d6d56aac82bca539bc705f55 Reviewed-by: Cristian Adam Reviewed-by: André Hartmann Reviewed-by: hjk --- src/plugins/perforce/perforceplugin.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp index 5976ed476e5..811a812c801 100644 --- a/src/plugins/perforce/perforceplugin.cpp +++ b/src/plugins/perforce/perforceplugin.cpp @@ -1185,11 +1185,10 @@ IEditor *PerforcePlugin::showOutputInEditor(const QString &title, << "Size= " << output.size() << " Type=" << editorType << debugCodec(codec); QString s = title; QString content = output; - const int maxSize = EditorManager::maxTextFileSize() - 1000; + const int maxSize = EditorManager::maxTextFileSize() / 2 - 1000; // ~25 MB, 600000 lines if (content.size() >= maxSize) { - content = tr("[Only %1 MB of output shown]").arg(maxSize / 1024 / 1024) + QLatin1Char('\n') - + content.right(maxSize); - + content = content.left(maxSize); + content += QLatin1Char('\n') + tr("[Only %1 MB of output shown]").arg(maxSize / 1024 / 1024); } IEditor *editor = EditorManager::openEditorWithContents(id, &s, content.toUtf8()); QTC_ASSERT(editor, return 0); From f2e7ec6e3f25feca9e11ef060110da6451fe93b7 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 27 Nov 2014 14:43:45 +0100 Subject: [PATCH 19/40] Debugger: Fix parsing of single-shot breakpoints from GDB response This can be manually triggered by entering e.g 'tbreak file.cpp:1' in the debugger input pane. Change-Id: I8212e82d258bb488fc1848e7d7e3e9ff5a3cae88 Reviewed-by: Christian Stenger --- src/plugins/debugger/gdb/gdbengine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 8862f1ebc1b..fcba0c320cd 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -2382,6 +2382,8 @@ void GdbEngine::updateResponse(BreakpointResponse &response, const GdbMi &bkpt) response.condition = child.data(); } else if (child.hasName("enabled")) { response.enabled = (child.data() == "y"); + } else if (child.hasName("disp")) { + response.oneShot = child.data() == "del"; } else if (child.hasName("pending")) { // Any content here would be interesting only if we did accept // spontaneously appearing breakpoints (user using gdb commands). From 0dc99f568a20d0e2de52877d60bafb688b4af052 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 25 Nov 2014 14:19:17 +0100 Subject: [PATCH 20/40] Debugger: Handle remote setup failure in remote state transitions Change-Id: I72886a309f1531c652186d529111d90ff3f98c37 Reviewed-by: Christian Stenger --- src/plugins/debugger/debuggerengine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 9c767602c22..ad1a86ea107 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -878,6 +878,7 @@ void DebuggerEngine::notifyEngineRemoteSetupFinished(const RemoteSetupResult &re } } else { + d->setRemoteSetupState(RemoteSetupFailed); showMessage(_("NOTE: REMOTE SETUP FAILED: ") + result.reason); } } From da3b7a6c4acea0e19feb49e204e59c12295f90b4 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 6 Nov 2014 14:16:29 +0100 Subject: [PATCH 21/40] Theming: Fix styling of TargetSettingsWidget If using the flat style also the TargetSettingsWidget should be flat. Change-Id: I16147c9868e3e949a4d9aa0fedf85358504bde9e Reviewed-by: Thorben Kroeger Reviewed-by: Orgad Shaneh --- .../projectexplorer/targetsettingswidget.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/plugins/projectexplorer/targetsettingswidget.cpp b/src/plugins/projectexplorer/targetsettingswidget.cpp index 6ea3ceaeac5..5afbcd2eb89 100644 --- a/src/plugins/projectexplorer/targetsettingswidget.cpp +++ b/src/plugins/projectexplorer/targetsettingswidget.cpp @@ -31,6 +31,8 @@ #include "targetsettingswidget.h" #include "ui_targetsettingswidget.h" +#include + #include using namespace ProjectExplorer::Internal; @@ -41,9 +43,15 @@ TargetSettingsWidget::TargetSettingsWidget(QWidget *parent) : m_targetSelector(new TargetSelector(this)) { ui->setupUi(this); - ui->header->setStyleSheet(QLatin1String("QWidget#header {" - "border-image: url(:/projectexplorer/images/targetseparatorbackground.png) 43 0 0 0 repeat;" - "}")); + + if (Utils::creatorTheme()->widgetStyle() == Utils::Theme::StyleFlat) { + ui->separator->setVisible(false); + ui->shadow->setVisible(false); + } else { + ui->header->setStyleSheet(QLatin1String("QWidget#header {" + "border-image: url(:/projectexplorer/images/targetseparatorbackground.png) 43 0 0 0 repeat;" + "}")); + } QHBoxLayout *headerLayout = new QHBoxLayout; headerLayout->setContentsMargins(5, 3, 0, 0); From b871b901badc972fe13a7bee7f186df59612b187 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Wed, 26 Nov 2014 12:43:29 +0100 Subject: [PATCH 22/40] ProjectExplorer: Fix crash on deleting kit from new dialog Task-number: QTCREATORBUG-13499 Change-Id: Ibcd591620469abf56270cc512de1583900ce78e3 Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/targetsetupwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/targetsetupwidget.cpp b/src/plugins/projectexplorer/targetsetupwidget.cpp index 8d1ef537fee..95c06fdb2dc 100644 --- a/src/plugins/projectexplorer/targetsetupwidget.cpp +++ b/src/plugins/projectexplorer/targetsetupwidget.cpp @@ -232,7 +232,7 @@ void TargetSetupWidget::manageKit() page->showKit(m_kit); Core::ICore::showOptionsDialog(Constants::PROJECTEXPLORER_SETTINGS_CATEGORY, Constants::KITS_SETTINGS_PAGE_ID, - this); + this->parentWidget()); } void TargetSetupWidget::setProjectPath(const QString &projectPath) From 796fdb82cb9835fed76de70dc7590419ff13a979 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 27 Nov 2014 13:19:29 +0100 Subject: [PATCH 23/40] Editor: Fix highlighting of xml values. Do not use the hardcoded value in the xml highlighter file. Task-number: QTCREATORBUG-13538 Change-Id: Ie79f46e2ab31caf01c0ab58097756141691761f0 Reviewed-by: Christian Stenger --- share/qtcreator/generic-highlighter/xml.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/generic-highlighter/xml.xml b/share/qtcreator/generic-highlighter/xml.xml index 3d92a563cd1..6bf68177513 100644 --- a/share/qtcreator/generic-highlighter/xml.xml +++ b/share/qtcreator/generic-highlighter/xml.xml @@ -134,7 +134,7 @@ - + From f8e8d14bd4bf505bcee7415cfc991cc8d90a2671 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 26 Nov 2014 18:44:38 +0100 Subject: [PATCH 24/40] QmlProfiler: Don't draw note markers for hidden categories Change-Id: I6a2104522896fafb70d09c5872cb9641f45db5f4 Task-number: QTCREATORBUG-13533 Reviewed-by: Kai Koehne --- src/plugins/qmlprofiler/timelinerenderer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/qmlprofiler/timelinerenderer.cpp b/src/plugins/qmlprofiler/timelinerenderer.cpp index 73e71388d1f..a80afadaa6d 100644 --- a/src/plugins/qmlprofiler/timelinerenderer.cpp +++ b/src/plugins/qmlprofiler/timelinerenderer.cpp @@ -338,6 +338,8 @@ void TimelineRenderer::drawNotes(QPainter *p) if (managerIndex == -1) continue; int modelIndex = m_profilerModelProxy->modelIndexFromManagerIndex(managerIndex); + if (m_profilerModelProxy->hidden(modelIndex)) + continue; int eventIndex = notes->timelineIndex(i); int row = m_profilerModelProxy->row(modelIndex, eventIndex); int rowHeight = m_profilerModelProxy->rowHeight(modelIndex, row); From 315fb0372e1cddbf33eea2fa1414f1d25ec65f90 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 27 Nov 2014 15:30:13 +0100 Subject: [PATCH 25/40] Debugger: Add more reference related autotests Change-Id: Iae638ca1fbd84c43c7d31b65e017792d1b6a1e0b Reviewed-by: Christian Stenger --- tests/auto/debugger/tst_dumpers.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 1c56f9031e8..9d55438e217 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -4845,7 +4845,8 @@ void tst_Dumpers::dumper_data() QTest::newRow("Reference") - << Data("#include \n" + << Data(fooData + + "#include \n" "#include \n" "using namespace std;\n" @@ -4869,7 +4870,13 @@ void tst_Dumpers::dumper_data() "const QString &b3 = a3;\n" "typedef QString &Ref3;\n" "const Ref3 d3 = const_cast(a3);\n" - "unused(&a3, &b3, &d3);\n") + "unused(&a3, &b3, &d3);\n\n" + + "Foo a4(12);\n" + "const Foo &b4 = a4;\n" + "typedef Foo &Ref4;\n" + "const Ref4 d4 = const_cast(a4);\n" + "unused(&a4, &b4, &d4);\n") + CoreProfile() @@ -4885,7 +4892,14 @@ void tst_Dumpers::dumper_data() + Check("a3", "\"hello\"", "@QString") + Check("b3", "\"hello\"", "@QString &") - + Check("d3", "\"hello\"", "Ref3"); + + Check("d3", "\"hello\"", "Ref3") + + + Check("a4", "", "Foo") + + Check("a4.a", "12", "int") + + Check("b4", "", "Foo &") + + Check("b4.a", "12", "int") + //+ Check("d4", "\"hello\"", "Ref4"); FIXME: We get "Foo &" instead + + Check("d4.a", "12", "int"); QTest::newRow("DynamicReference") @@ -4967,6 +4981,8 @@ void tst_Dumpers::dumper_data() << Data(fooData + "void testPassByReference(Foo &f) {\n" " BREAK;\n" + " int dummy = 2;\n" + " unused(&f, &dummy);\n" "}\n", "Foo f(12);\n" "testPassByReference(f);\n") From c58b029319d229c9af0cbe5696e042d9b5ed09c1 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 27 Nov 2014 15:48:11 +0100 Subject: [PATCH 26/40] CppEditor: Tests: Refactor out BaseQuickFixTestCase We will add another type of test case that allows us to test the list of offered operations. Change-Id: I528b3844181c139c8955091ac0bbcf6475fd8a4f Reviewed-by: Erik Verbruggen --- .../cppeditor/cppinsertvirtualmethods.cpp | 6 +- src/plugins/cppeditor/cppquickfix_test.cpp | 371 +++++++++--------- src/plugins/cppeditor/cppquickfix_test.h | 64 +-- 3 files changed, 230 insertions(+), 211 deletions(-) diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp index 60d6d517b81..fff21d928de 100644 --- a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp +++ b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp @@ -1637,7 +1637,7 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods() InsertVirtualMethods factory( new Tests::InsertVirtualMethodsDialogTest(implementationMode, insertVirtualKeyword)); - Tests::QuickFixTestCase(Tests::singleDocument(original, expected), &factory); + Tests::QuickFixOperationTest(Tests::singleDocument(original, expected), &factory); } /// Check: Insert in implementation file @@ -1683,7 +1683,7 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_implementationFile() InsertVirtualMethods factory(new Tests::InsertVirtualMethodsDialogTest( InsertVirtualMethodsDialog::ModeImplementationFile, true)); - Tests::QuickFixTestCase(testFiles, &factory); + Tests::QuickFixOperationTest(testFiles, &factory); } /// Check: Qualified names. @@ -1735,7 +1735,7 @@ void CppEditorPlugin::test_quickfix_InsertVirtualMethods_BaseClassInNamespace() InsertVirtualMethods factory(new Tests::InsertVirtualMethodsDialogTest( InsertVirtualMethodsDialog::ModeImplementationFile, true)); - Tests::QuickFixTestCase(testFiles, &factory); + Tests::QuickFixOperationTest(testFiles, &factory); } #endif // WITH_TESTS diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 3269df3c0da..2403cdd3b19 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -89,6 +89,89 @@ QList singleDocument(const QByteArray &original, << QuickFixTestDocument::create("file.cpp", original, expected); } +BaseQuickFixTestCase::BaseQuickFixTestCase(const QList &testDocuments, + const ProjectPart::HeaderPaths &headerPaths) + : m_testDocuments(testDocuments) + , m_cppCodeStylePreferences(0) + , m_restoreHeaderPaths(false) +{ + QVERIFY(succeededSoFar()); + m_succeededSoFar = false; + + // Check if there is exactly one cursor marker + unsigned cursorMarkersCount = 0; + foreach (const QuickFixTestDocument::Ptr document, m_testDocuments) { + if (document->hasCursorMarker()) + ++cursorMarkersCount; + } + QVERIFY2(cursorMarkersCount == 1, "Exactly one cursor marker is allowed."); + + // Write documents to disk + foreach (QuickFixTestDocument::Ptr document, m_testDocuments) + document->writeToDisk(); + + // Set appropriate include paths + if (!headerPaths.isEmpty()) { + m_restoreHeaderPaths = true; + m_headerPathsToRestore = m_modelManager->headerPaths(); + m_modelManager->setHeaderPaths(headerPaths); + } + + // Update Code Model + QSet filePaths; + foreach (const QuickFixTestDocument::Ptr &document, m_testDocuments) + filePaths << document->filePath(); + QVERIFY(parseFiles(filePaths)); + + // Open Files + foreach (QuickFixTestDocument::Ptr document, m_testDocuments) { + QVERIFY(openCppEditor(document->filePath(), &document->m_editor, + &document->m_editorWidget)); + closeEditorAtEndOfTestCase(document->m_editor); + + // Set cursor position + const int cursorPosition = document->hasCursorMarker() + ? document->m_cursorPosition : 0; + document->m_editor->setCursorPosition(cursorPosition); + + // Rehighlight + waitForRehighlightedSemanticDocument(document->m_editorWidget); + } + + // Enforce the default cpp code style, so we are independent of config file settings. + // This is needed by e.g. the GenerateGetterSetter quick fix. + m_cppCodeStylePreferences = CppToolsSettings::instance()->cppCodeStyle(); + QVERIFY(m_cppCodeStylePreferences); + m_cppCodeStylePreferencesOriginalDelegateId = m_cppCodeStylePreferences->currentDelegateId(); + m_cppCodeStylePreferences->setCurrentDelegate("qt"); + + // Find the document having the cursor marker + foreach (const QuickFixTestDocument::Ptr document, m_testDocuments) { + if (document->hasCursorMarker()){ + m_documentWithMarker = document; + break; + } + } + + QVERIFY(m_documentWithMarker); + m_succeededSoFar = true; +} + +BaseQuickFixTestCase::~BaseQuickFixTestCase() +{ + // Restore default cpp code style + if (m_cppCodeStylePreferences) + m_cppCodeStylePreferences->setCurrentDelegate(m_cppCodeStylePreferencesOriginalDelegateId); + + // Restore include paths + if (m_restoreHeaderPaths) + m_modelManager->setHeaderPaths(m_headerPathsToRestore); + + // Remove created files from file system + foreach (const QuickFixTestDocument::Ptr &testDocument, m_testDocuments) + QVERIFY(QFile::remove(testDocument->filePath())); +} + /// Leading whitespace is not removed, so we can check if the indetation ranges /// have been set correctly by the quick-fix. static QString &removeTrailingWhitespace(QString &input) @@ -113,81 +196,30 @@ static QString &removeTrailingWhitespace(QString &input) return input; } -/// The '@' in the originalSource is the position from where the quick-fix discovery is triggered. -/// Exactly one TestFile must contain the cursor position marker '@' in the originalSource. -QuickFixTestCase::QuickFixTestCase(const QList &theTestFiles, - CppQuickFixFactory *factory, - const ProjectPart::HeaderPaths &headerPaths, - int resultIndex, - const QByteArray &expectedFailMessage) - : m_testFiles(theTestFiles) - , m_cppCodeStylePreferences(0) - , m_restoreHeaderPaths(false) +QuickFixOperationTest::QuickFixOperationTest(const QList &testDocuments, + CppQuickFixFactory *factory, + const ProjectPart::HeaderPaths &headerPaths, + int operationIndex, + const QByteArray &expectedFailMessage) + : BaseQuickFixTestCase(testDocuments, headerPaths) { QVERIFY(succeededSoFar()); - // Check if there is exactly one cursor marker - unsigned cursorMarkersCount = 0; - foreach (const QuickFixTestDocument::Ptr testFile, m_testFiles) { - if (testFile->hasCursorMarker()) - ++cursorMarkersCount; - } - QVERIFY2(cursorMarkersCount == 1, "Exactly one cursor marker is allowed."); - - // Write files to disk - foreach (QuickFixTestDocument::Ptr testFile, m_testFiles) - testFile->writeToDisk(); - - // Set appropriate include paths - if (!headerPaths.isEmpty()) { - m_restoreHeaderPaths = true; - m_headerPathsToRestore = m_modelManager->headerPaths(); - m_modelManager->setHeaderPaths(headerPaths); - } - - // Update Code Model - QSet filePaths; - foreach (const QuickFixTestDocument::Ptr &testFile, m_testFiles) - filePaths << testFile->filePath(); - QVERIFY(parseFiles(filePaths)); - - // Open Files - foreach (QuickFixTestDocument::Ptr testFile, m_testFiles) { - QVERIFY(openCppEditor(testFile->filePath(), &testFile->m_editor, - &testFile->m_editorWidget)); - closeEditorAtEndOfTestCase(testFile->m_editor); - - // Set cursor position - const int cursorPosition = testFile->hasCursorMarker() - ? testFile->m_cursorPosition : 0; - testFile->m_editor->setCursorPosition(cursorPosition); - - // Rehighlight - waitForRehighlightedSemanticDocument(testFile->m_editorWidget); - } - - // Enforce the default cpp code style, so we are independent of config file settings. - // This is needed by e.g. the GenerateGetterSetter quick fix. - m_cppCodeStylePreferences = CppToolsSettings::instance()->cppCodeStyle(); - QVERIFY(m_cppCodeStylePreferences); - m_cppCodeStylePreferencesOriginalDelegateId = m_cppCodeStylePreferences->currentDelegateId(); - m_cppCodeStylePreferences->setCurrentDelegate("qt"); - - // Run the fix in the file having the cursor marker - QuickFixTestDocument::Ptr testFile; - foreach (const QuickFixTestDocument::Ptr file, m_testFiles) { - if (file->hasCursorMarker()) - testFile = file; - } - QVERIFY2(testFile, "No test file with cursor marker found"); - - if (QuickFixOperation::Ptr fix = getFix(factory, testFile->m_editorWidget, resultIndex)) - fix->perform(); - else + // Perform operation if there is one + CppQuickFixInterface quickFixInterface(m_documentWithMarker->m_editorWidget, ExplicitlyInvoked); + TextEditor::QuickFixOperations operations; + factory->match(quickFixInterface, operations); + if (operations.isEmpty()) { qDebug() << "Quickfix was not triggered"; + return; + } + + QVERIFY(operationIndex < operations.size()); + const QuickFixOperation::Ptr operation = operations.at(operationIndex); + operation->perform(); // Compare all files - foreach (const QuickFixTestDocument::Ptr testFile, m_testFiles) { + foreach (const QuickFixTestDocument::Ptr testFile, m_testDocuments) { // Check QString result = testFile->m_editorWidget->document()->toPlainText(); removeTrailingWhitespace(result); @@ -203,27 +235,14 @@ QuickFixTestCase::QuickFixTestCase(const QList &theTe } } -QuickFixTestCase::~QuickFixTestCase() +void QuickFixOperationTest::run(const QList &testDocuments, + CppQuickFixFactory *factory, + const QString &headerPath, + int operationIndex) { - // Restore default cpp code style - if (m_cppCodeStylePreferences) - m_cppCodeStylePreferences->setCurrentDelegate(m_cppCodeStylePreferencesOriginalDelegateId); - - // Restore include paths - if (m_restoreHeaderPaths) - m_modelManager->setHeaderPaths(m_headerPathsToRestore); - - // Remove created files from file system - foreach (const QuickFixTestDocument::Ptr &testDocument, m_testFiles) - QVERIFY(QFile::remove(testDocument->filePath())); -} - -void QuickFixTestCase::run(const QList &theTestFiles, - CppQuickFixFactory *factory, const QString &incPath, int resultIndex) -{ - ProjectPart::HeaderPaths hps; - hps += ProjectPart::HeaderPath(incPath, ProjectPart::HeaderPath::IncludePath); - QuickFixTestCase(theTestFiles, factory, hps, resultIndex); + ProjectPart::HeaderPaths headerPaths; + headerPaths += ProjectPart::HeaderPath(headerPath, ProjectPart::HeaderPath::IncludePath); + QuickFixOperationTest(testDocuments, factory, headerPaths, operationIndex); } /// Delegates directly to AddIncludeForUndefinedIdentifierOp for easier testing. @@ -242,16 +261,6 @@ private: const QString m_include; }; -/// Apply the factory on the source and get back the resultIndex'th result or a null pointer. -QSharedPointer QuickFixTestCase::getFix( - CppQuickFixFactory *factory, CppEditorWidget *editorWidget, int resultIndex) -{ - CppQuickFixInterface qfi(editorWidget, ExplicitlyInvoked); - TextEditor::QuickFixOperations results; - factory->match(qfi, results); - return results.isEmpty() ? QuickFixOperation::Ptr() : results.at(resultIndex); -} - } // namespace Tests } // namespace Internal @@ -1482,7 +1491,7 @@ void CppEditorPlugin::test_quickfix() if (expected.isEmpty()) expected = original; - QuickFixTestCase(singleDocument(original, expected), factory.data()); + QuickFixOperationTest(singleDocument(original, expected), factory.data()); } /// Checks: In addition to test_quickfix_GenerateGetterSetter_basicGetterWithPrefix @@ -1535,7 +1544,7 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAn testFiles << QuickFixTestDocument::create("file.cpp", original, expected); GenerateGetterSetter factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check if definition is inserted right after class for insert definition outside @@ -1578,7 +1587,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_afterClass() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory, ProjectPart::HeaderPaths(), 1); + QuickFixOperationTest(testFiles, &factory, ProjectPart::HeaderPaths(), 1); } /// Check from header file: If there is a source file, insert the definition in the source file. @@ -1610,7 +1619,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic1() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check from header file: If there is a source file, insert the definition in the source file. @@ -1647,7 +1656,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic2() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check from source file: Insert in source file, not header file. @@ -1677,7 +1686,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_basic3() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check from header file: If the class is in a namespace, the added function definition @@ -1711,7 +1720,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_namespace1() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check from header file: If the class is in namespace N and the source file has a @@ -1749,7 +1758,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_namespace2() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check definition insert inside class @@ -1767,7 +1776,8 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_insideClass() "};"; InsertDefFromDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory, ProjectPart::HeaderPaths(), 1); + QuickFixOperationTest(singleDocument(original, expected), &factory, ProjectPart::HeaderPaths(), + 1); } /// Check not triggering when definition exists @@ -1781,7 +1791,8 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_notTriggeringWhenDefinitio const QByteArray expected = original; InsertDefFromDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory, ProjectPart::HeaderPaths(), 1); + QuickFixOperationTest(singleDocument(original, expected), &factory, ProjectPart::HeaderPaths(), + 1); } /// Find right implementation file. @@ -1830,7 +1841,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_findRightImplementationFil testFiles << QuickFixTestDocument::create("file2.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Ignore generated functions declarations when looking at the surrounding @@ -1885,7 +1896,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_ignoreSurroundingGenerated testFiles << QuickFixTestDocument::create("file2.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check if whitespace is respected for operator functions @@ -1909,7 +1920,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_respectWsInOperatorNames1( "}\n"; InsertDefFromDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } /// Check if whitespace is respected for operator functions @@ -1933,7 +1944,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_respectWsInOperatorNames2( "}\n"; InsertDefFromDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } /// Check if a function like macro use is not separated by the function to insert @@ -1975,7 +1986,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile1() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check if a function like macro use is not separated by the function to insert @@ -2015,7 +2026,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile2() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check if insertion happens before syntactically erroneous statements at end of file. @@ -2052,7 +2063,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_erroneousStatementAtEndOfF testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Respect rvalue references @@ -2080,7 +2091,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_rvalueReference() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Find right implementation file. (QTCREATORBUG-10728) @@ -2119,7 +2130,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_findImplementationFile() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } void CppEditorPlugin::test_quickfix_InsertDefFromDecl_unicodeIdentifier() @@ -2163,7 +2174,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_unicodeIdentifier() #undef TEST_UNICODE_IDENTIFIER InsertDefFromDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } // Function for one of InsertDeclDef section cases @@ -2199,7 +2210,7 @@ void insertToSectionDeclFromDef(const QByteArray §ion, int sectionIndex) testFiles << QuickFixTestDocument::create("file.cpp", original, expected); InsertDeclFromDef factory; - QuickFixTestCase(testFiles, &factory, ProjectPart::HeaderPaths(), sectionIndex); + QuickFixOperationTest(testFiles, &factory, ProjectPart::HeaderPaths(), sectionIndex); } /// Check from source file: Insert in header file. @@ -2249,7 +2260,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onSimpleNam + "/afile.cpp", original, expected); AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Cursor is on a qualified name (1) @@ -2289,7 +2300,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onNameOfQua // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onBaseOfQualifiedName() @@ -2328,7 +2339,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onBaseOfQua // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onTemplateName() @@ -2367,7 +2378,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onTemplateN // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onTemplateNameInsideArguments() @@ -2406,7 +2417,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onTemplateN // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_withForwardDeclaration() @@ -2449,7 +2460,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_withForward // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_withForwardDeclaration2() @@ -2492,7 +2503,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_withForward // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_withForwardHeader() @@ -2537,7 +2548,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_withForward // Do not use the test factory, at least once we want to go through the "full stack". AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath(), 1); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath(), 1); } /// Check: Ignore *.moc includes @@ -2562,7 +2573,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_i + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert include at top for a sorted group @@ -2588,7 +2599,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_s + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert include in the middle for a sorted group @@ -2614,7 +2625,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_s + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert include at bottom for a sorted group @@ -2640,7 +2651,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_s + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: For an unsorted group the new include is appended @@ -2666,7 +2677,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_a + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert a local include at front if there are only global includes @@ -2693,7 +2704,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_f + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert a global include at back if there are only local includes @@ -2722,7 +2733,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_f + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Prefer group with longest matching prefix @@ -2752,7 +2763,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_p + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"prefixc.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Create a new include group if there are only include groups with a different include dir @@ -2779,7 +2790,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_n + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include dirs, sorted --> insert properly @@ -2807,7 +2818,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_m + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include dirs, unsorted --> append @@ -2835,7 +2846,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_m + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include types @@ -2861,7 +2872,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_m + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"z.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include types @@ -2887,7 +2898,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_m + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"a.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include types @@ -2913,7 +2924,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_m + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"lib/file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Include group with mixed include types @@ -2939,7 +2950,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_m + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert very first include @@ -2962,7 +2973,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_n + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert very first include after include guard @@ -2992,7 +3003,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_o + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert very first include if there is a c++ style comment on top @@ -3021,7 +3032,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_v + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: Insert very first include if there is a c style comment on top @@ -3054,7 +3065,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_v + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifierTestFactory factory(QLatin1String("\"file.h\"")); - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalIncludePath()); } /// Check: If a "Qt Class" was not found by the locator, check the header files in the Qt @@ -3078,7 +3089,7 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_c + "/file.cpp", original, expected); AddIncludeForUndefinedIdentifier factory; - QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalQtCoreIncludePath()); + QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalQtCoreIncludePath()); } @@ -3122,7 +3133,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCpp() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppInsideNS() @@ -3168,7 +3179,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppInsideNS() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Move definition outside class @@ -3202,7 +3213,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncOutside1() "void Foo::f4() {}\n"; MoveFuncDefOutside factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } /// Check: Move definition outside class @@ -3244,7 +3255,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncOutside2() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory, ProjectPart::HeaderPaths(), 1); + QuickFixOperationTest(testFiles, &factory, ProjectPart::HeaderPaths(), 1); } /// Check: Move definition from header to cpp (with namespace). @@ -3286,7 +3297,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppNS() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Move definition from header to cpp (with namespace + using). @@ -3330,7 +3341,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncToCppNSUsing() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Move definition outside class with Namespace @@ -3357,7 +3368,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_MemberFuncOutsideWithNs() "\n}\n"; MoveFuncDefOutside factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } /// Check: Move free function from header to cpp. @@ -3392,7 +3403,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_FreeFuncToCpp() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Move free function from header to cpp (with namespace). @@ -3430,7 +3441,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_FreeFuncToCppNS() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Move Ctor with member initialization list (QTCREATORBUG-9157). @@ -3470,7 +3481,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_CtorWithInitialization1() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Move Ctor with member initialization list (QTCREATORBUG-9462). @@ -3515,7 +3526,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_CtorWithInitialization2() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check if definition is inserted right after class for move definition outside @@ -3557,7 +3568,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_afterClass() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefOutside factory; - QuickFixTestCase(testFiles, &factory, ProjectPart::HeaderPaths(), 1); + QuickFixOperationTest(testFiles, &factory, ProjectPart::HeaderPaths(), 1); } /// Check if whitespace is respected for operator functions @@ -3579,7 +3590,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_respectWsInOperatorNames1 ; MoveFuncDefOutside factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } /// Check if whitespace is respected for operator functions @@ -3601,7 +3612,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_respectWsInOperatorNames2 ; MoveFuncDefOutside factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_macroUses() @@ -3633,7 +3644,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefOutside_macroUses() ; MoveFuncDefOutside factory; - QuickFixTestCase(singleDocument(original, expected), &factory, + QuickFixOperationTest(singleDocument(original, expected), &factory, ProjectPart::HeaderPaths(), 0, "QTCREATORBUG-12314"); } @@ -3666,7 +3677,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFunc() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefToDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncOutside() @@ -3691,7 +3702,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncOutside() "};\n\n\n"; MoveFuncDefToDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } /// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncToCppNS() @@ -3731,7 +3742,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncToCppNS() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefToDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncToCppNSUsing() @@ -3775,7 +3786,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncToCppNSUsing() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefToDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncOutsideWithNs() @@ -3802,7 +3813,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_MemberFuncOutsideWithNs() "};\n\n\n}\n"; MoveFuncDefToDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } /// Check: revert test_quickfix_MoveFuncDefOutside_FreeFuncToCpp() @@ -3834,7 +3845,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_FreeFuncToCpp() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefToDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: revert test_quickfix_MoveFuncDefOutside_FreeFuncToCppNS() @@ -3872,7 +3883,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_FreeFuncToCppNS() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefToDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: revert test_quickfix_MoveFuncDefOutside_CtorWithInitialization() @@ -3911,7 +3922,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_CtorWithInitialization() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); MoveFuncDefToDecl factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } /// Check: Definition should not be placed behind the variable. QTCREATORBUG-10303 @@ -3937,7 +3948,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_structWithAssignedVariable "} bar;\n"; MoveFuncDefToDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_macroUses() @@ -3967,7 +3978,7 @@ void CppEditorPlugin::test_quickfix_MoveFuncDefToDecl_macroUses() "};\n\n\n\n"; MoveFuncDefToDecl factory; - QuickFixTestCase(singleDocument(original, expected), &factory, + QuickFixOperationTest(singleDocument(original, expected), &factory, ProjectPart::HeaderPaths(), 0, "QTCREATORBUG-12314"); } @@ -4005,7 +4016,7 @@ void CppEditorPlugin::test_quickfix_AssignToLocalVariable_templates() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); AssignToLocalVariable factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_typeDeduction_data() @@ -4069,7 +4080,7 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_typeDeduction() } ExtractLiteralAsParameter factory; - QuickFixTestCase(singleDocument(original, expected), &factory); + QuickFixOperationTest(singleDocument(original, expected), &factory); } void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_freeFunction_separateFiles() @@ -4095,7 +4106,7 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_freeFunction_separ testFiles << QuickFixTestDocument::create("file.cpp", original, expected); ExtractLiteralAsParameter factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_memberFunction_separateFiles() @@ -4129,7 +4140,7 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_memberFunction_sep testFiles << QuickFixTestDocument::create("file.cpp", original, expected); ExtractLiteralAsParameter factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_notTriggeringForInvalidCode() @@ -4147,7 +4158,7 @@ void CppEditorPlugin::test_quickfix_ExtractLiteralAsParameter_notTriggeringForIn testFiles << QuickFixTestDocument::create("file.cpp", original, expected); ExtractLiteralAsParameter factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } void CppEditorPlugin::test_quickfix_ConvertQt4Connect_connectOutOfClass() @@ -4180,7 +4191,7 @@ void CppEditorPlugin::test_quickfix_ConvertQt4Connect_connectOutOfClass() testFiles << QuickFixTestDocument::create("file.cpp", original, expected); ConvertQt4Connect factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } void CppEditorPlugin::test_quickfix_ConvertQt4Connect_connectWithinClass_data() @@ -4227,7 +4238,7 @@ void CppEditorPlugin::test_quickfix_ConvertQt4Connect_connectWithinClass() prefix + expected + suffix); ConvertQt4Connect factory; - QuickFixTestCase(testFiles, &factory); + QuickFixOperationTest(testFiles, &factory); } } // namespace Internal diff --git a/src/plugins/cppeditor/cppquickfix_test.h b/src/plugins/cppeditor/cppquickfix_test.h index 72be61be4d1..43119cf94b8 100644 --- a/src/plugins/cppeditor/cppquickfix_test.h +++ b/src/plugins/cppeditor/cppquickfix_test.h @@ -44,13 +44,14 @@ namespace CppEditor { namespace Internal { namespace Tests { -/** - * Represents a test document before and after applying the quick fix. - * - * A TestDocument's source may contain an '@' character to denote - * the cursor position. This marker is removed before the Editor reads - * the document. - */ +/// +/// Represents a test document before and after applying the quick fix. +/// +/// A TestDocument's source may contain an '@' character to denote +/// the cursor position. This marker is removed before the Editor reads +/// the document. +/// + class QuickFixTestDocument : public TestDocument { public: @@ -60,37 +61,27 @@ public: const QByteArray &expectedSource); static Ptr create(const QByteArray &fileName, const QByteArray &source, - const QByteArray &expectedSource); + const QByteArray &expectedSource); public: QString m_expectedSource; }; -/** - * Encapsulates the whole process of setting up an editor, getting the - * quick-fix, applying it, and checking the result. - */ -class QuickFixTestCase : public TestCase +class BaseQuickFixTestCase : public TestCase { public: - QuickFixTestCase(const QList &theTestFiles, - CppQuickFixFactory *factory, - const CppTools::ProjectPart::HeaderPaths &includePaths = - CppTools::ProjectPart::HeaderPaths(), - int resultIndex = 0, - const QByteArray &expectedFailMessage = QByteArray()); - ~QuickFixTestCase(); + /// Exactly one QuickFixTestDocument must contain the cursor position marker '@'. + BaseQuickFixTestCase(const QList &testDocuments, + const CppTools::ProjectPart::HeaderPaths &headerPaths + = CppTools::ProjectPart::HeaderPaths()); - static void run(const QList &theTestFiles, - CppQuickFixFactory *factory, const QString &incPath, int resultIndex = 0); -private: - QSharedPointer getFix(CppQuickFixFactory *factory, - CppEditorWidget *editorWidget, - int resultIndex = 0); + ~BaseQuickFixTestCase(); + +protected: + QuickFixTestDocument::Ptr m_documentWithMarker; + QList m_testDocuments; private: - QList m_testFiles; - CppTools::CppCodeStylePreferences *m_cppCodeStylePreferences; QByteArray m_cppCodeStylePreferencesOriginalDelegateId; @@ -98,6 +89,23 @@ private: bool m_restoreHeaderPaths; }; +/// Tests a concrete QuickFixOperation of a given CppQuickFixFactory +class QuickFixOperationTest : public BaseQuickFixTestCase +{ +public: + QuickFixOperationTest(const QList &testDocuments, + CppQuickFixFactory *factory, + const CppTools::ProjectPart::HeaderPaths &headerPaths + = CppTools::ProjectPart::HeaderPaths(), + int operationIndex = 0, + const QByteArray &expectedFailMessage = QByteArray()); + + static void run(const QList &testDocuments, + CppQuickFixFactory *factory, + const QString &headerPath, + int operationIndex = 0); +}; + QList singleDocument(const QByteArray &original, const QByteArray &expected); From 2fc4acbc356cbb310663f6568a6e73a66b649a8e Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 27 Nov 2014 18:00:10 +0100 Subject: [PATCH 27/40] CppEditor: Avoid duplicate "Add #include XYZ" Task-number: QTCREATORBUG-13422 Change-Id: I3648bf44760fdac4e8e1e79652519136af6032c8 Reviewed-by: Erik Verbruggen --- src/plugins/cppeditor/cppeditorplugin.h | 1 + src/plugins/cppeditor/cppquickfix_test.cpp | 45 +++++++++++++++++++ src/plugins/cppeditor/cppquickfix_test.h | 11 +++++ src/plugins/cppeditor/cppquickfixes.cpp | 15 ++++++- .../data/include-data/QtCore/QDir | 3 ++ 5 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h index ffb9d2c9547..927d4ff9a0c 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppeditorplugin.h @@ -182,6 +182,7 @@ private slots: void test_quickfix_AddIncludeForUndefinedIdentifier_inserting_veryFirstIncludeCppStyleCommentOnTop(); void test_quickfix_AddIncludeForUndefinedIdentifier_inserting_veryFirstIncludeCStyleCommentOnTop(); void test_quickfix_AddIncludeForUndefinedIdentifier_inserting_checkQSomethingInQtIncludePaths(); + void test_quickfix_AddIncludeForUndefinedIdentifier_noDoubleQtHeaderInclude(); void test_quickfix_MoveFuncDefOutside_MemberFuncToCpp(); void test_quickfix_MoveFuncDefOutside_MemberFuncToCppInsideNS(); diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 2403cdd3b19..c32e96bf586 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -245,6 +245,26 @@ void QuickFixOperationTest::run(const QList &testDocu QuickFixOperationTest(testDocuments, factory, headerPaths, operationIndex); } +QuickFixOfferedOperationsTest::QuickFixOfferedOperationsTest( + const QList &testDocuments, + CppQuickFixFactory *factory, + const ProjectPart::HeaderPaths &headerPaths, + const QStringList &expectedOperations) + : BaseQuickFixTestCase(testDocuments, headerPaths) +{ + // Get operations + CppQuickFixInterface quickFixInterface(m_documentWithMarker->m_editorWidget, ExplicitlyInvoked); + TextEditor::QuickFixOperations actualOperations; + factory->match(quickFixInterface, actualOperations); + + // Convert to QStringList + QStringList actualOperationsAsStringList; + foreach (const QuickFixOperation::Ptr &operation, actualOperations) + actualOperationsAsStringList << operation->description(); + + QCOMPARE(actualOperationsAsStringList, expectedOperations); +} + /// Delegates directly to AddIncludeForUndefinedIdentifierOp for easier testing. class AddIncludeForUndefinedIdentifierTestFactory : public CppQuickFixFactory { @@ -3090,7 +3110,32 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_c AddIncludeForUndefinedIdentifier factory; QuickFixOperationTest::run(testFiles, &factory, TestIncludePaths::globalQtCoreIncludePath()); +} +void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_noDoubleQtHeaderInclude() +{ + QList testFiles; + + QByteArray original; + QByteArray expected; + + const QByteArray base = TestIncludePaths::directoryOfTestFile().toUtf8(); + + // This file makes the QDir definition available so that locator finds it. + original = expected = "#include \n" + "void avoidBeingRecognizedAsForwardingHeader();"; + testFiles << QuickFixTestDocument::create(base + "/fileUsingQDir.cpp", original, expected); + + original = expected = "@QDir dir;\n"; + testFiles << QuickFixTestDocument::create(base + "/fileWantsToUseQDir.cpp", original, expected); + + ProjectPart::HeaderPaths headerPaths; + headerPaths += ProjectPart::HeaderPath(TestIncludePaths::globalQtCoreIncludePath(), + ProjectPart::HeaderPath::IncludePath); + + AddIncludeForUndefinedIdentifier factory; + const QStringList expectedOperations = QStringList() << QLatin1String("Add #include "); + QuickFixOfferedOperationsTest(testFiles, &factory, headerPaths, expectedOperations); } /// Check: Move definition from header to cpp. diff --git a/src/plugins/cppeditor/cppquickfix_test.h b/src/plugins/cppeditor/cppquickfix_test.h index 43119cf94b8..2a7ea4c3b5b 100644 --- a/src/plugins/cppeditor/cppquickfix_test.h +++ b/src/plugins/cppeditor/cppquickfix_test.h @@ -106,6 +106,17 @@ public: int operationIndex = 0); }; +/// Tests the offered operations provided by a given CppQuickFixFactory +class QuickFixOfferedOperationsTest : public BaseQuickFixTestCase +{ +public: + QuickFixOfferedOperationsTest(const QList &testDocuments, + CppQuickFixFactory *factory, + const CppTools::ProjectPart::HeaderPaths &headerPaths + = CppTools::ProjectPart::HeaderPaths(), + const QStringList &expectedOperations = QStringList()); +}; + QList singleDocument(const QByteArray &original, const QByteArray &expected); diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 36a0d41d5b5..691d7687dec 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -1866,6 +1866,13 @@ Snapshot forwardingHeaders(const CppQuickFixInterface &interface) return result; } +bool looksLikeAQtClass(const QString &identifier) +{ + return identifier.size() > 2 + && identifier.at(0) == QLatin1Char('Q') + && identifier.at(1).isUpper(); +} + } // anonymous namespace void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interface, @@ -1884,6 +1891,7 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa const QString currentDocumentFilePath = interface.semanticInfo().doc->fileName(); const ProjectPart::HeaderPaths headerPaths = relevantHeaderPaths(currentDocumentFilePath); + bool qtHeaderFileIncludeOffered = false; // Find an include file through the locator if (CppClassesFilter *classesFilter @@ -1906,7 +1914,7 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa foreach (const QString &header, headerAndItsForwardingHeaders) { const QString include = findShortestInclude(currentDocumentFilePath, header, headerPaths); - if (!include.isEmpty()) { + if (include.size() > 2) { const QString headerFileName = QFileInfo(info->fileName()).fileName(); QTC_ASSERT(!headerFileName.isEmpty(), break); @@ -1916,6 +1924,9 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa else if (headerFileName.at(1).isUpper()) priority = 1; + if (looksLikeAQtClass(include.mid(1, include.size() - 2))) + qtHeaderFileIncludeOffered = true; + result.append(new AddIncludeForUndefinedIdentifierOp(interface, priority, include)); } @@ -1926,7 +1937,7 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa // The header file we are looking for might not be (yet) included in any file we have parsed. // As such, it will not be findable via locator. At least for Qt classes, check also for // headers with the same name. - if (className.size() > 2 && className.at(0) == QLatin1Char('Q') && className.at(1).isUpper()) { + if (!qtHeaderFileIncludeOffered && looksLikeAQtClass(className)) { const QString include = findQtIncludeWithSameName(className, headerPaths); if (!include.isEmpty()) result.append(new AddIncludeForUndefinedIdentifierOp(interface, 1, include)); diff --git a/tests/auto/cplusplus/preprocessor/data/include-data/QtCore/QDir b/tests/auto/cplusplus/preprocessor/data/include-data/QtCore/QDir index fef83a9cfe6..8710edd2d37 100644 --- a/tests/auto/cplusplus/preprocessor/data/include-data/QtCore/QDir +++ b/tests/auto/cplusplus/preprocessor/data/include-data/QtCore/QDir @@ -1 +1,4 @@ // comment + +class QDir {}; + From 488bf9179774c84136c12baa38fa70f7e3db3706 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 28 Nov 2014 11:29:00 +0100 Subject: [PATCH 28/40] CppTools: Always check for a valid BuiltinEditorDocumentParser* This fixes a crash if the include hierarchy sidebar is invoked with the clang code model. BuiltinEditorDocumentParser::get(editorFilePath) returns 0 in that case. Task-number: QTCREATORBUG-13553 Change-Id: I9292691c8156bdaaffcac1c3864201ba8a6cbdef Reviewed-by: Erik Verbruggen --- src/plugins/cppeditor/cppincludehierarchymodel.cpp | 10 +++++++--- src/plugins/cpptools/cppmodelmanager_test.cpp | 3 ++- src/plugins/cpptools/cppsourceprocessor_test.cpp | 2 +- src/plugins/designer/gotoslot_test.cpp | 9 +++++++-- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/plugins/cppeditor/cppincludehierarchymodel.cpp b/src/plugins/cppeditor/cppincludehierarchymodel.cpp index 3a9b6f7f728..ce0149aaa5e 100644 --- a/src/plugins/cppeditor/cppincludehierarchymodel.cpp +++ b/src/plugins/cppeditor/cppincludehierarchymodel.cpp @@ -40,6 +40,7 @@ #include #include +#include #include @@ -183,8 +184,9 @@ void CppIncludeHierarchyModel::fetchMore(const QModelIndex &parent) } if (item == m_includesItem) { - const Snapshot editorDocumentSnapshot - = BuiltinEditorDocumentParser::get(editorFilePath)->snapshot(); + auto *parser = BuiltinEditorDocumentParser::get(editorFilePath); + QTC_ASSERT(parser, return); + const Snapshot editorDocumentSnapshot = parser->snapshot(); buildHierarchyIncludes_helper(parentItem->filePath(), parentItem, editorDocumentSnapshot, &cyclic); } else { @@ -284,7 +286,9 @@ void CppIncludeHierarchyModel::buildHierarchyIncludes(const QString ¤tFile return; const QString editorFilePath = m_editor->document()->filePath(); - const Snapshot snapshot = BuiltinEditorDocumentParser::get(editorFilePath)->snapshot(); + auto *parser = BuiltinEditorDocumentParser::get(editorFilePath); + QTC_ASSERT(parser, return); + const Snapshot snapshot = parser->snapshot(); QSet cyclic; buildHierarchyIncludes_helper(currentFilePath, m_includesItem, snapshot, &cyclic); } diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp index dfc1ed0d0d7..b4065f13289 100644 --- a/src/plugins/cpptools/cppmodelmanager_test.cpp +++ b/src/plugins/cpptools/cppmodelmanager_test.cpp @@ -946,7 +946,8 @@ void CppToolsPlugin::test_modelmanager_precompiled_headers() QCOMPARE(Core::DocumentModel::openedDocuments().size(), 1); QVERIFY(mm->isCppEditor(editor)); - BuiltinEditorDocumentParser *parser = BuiltinEditorDocumentParser::get(fileName); + auto *parser = BuiltinEditorDocumentParser::get(fileName); + QVERIFY(parser); parser->setUsePrecompiledHeaders(true); parser->update(mm->workingCopy()); diff --git a/src/plugins/cpptools/cppsourceprocessor_test.cpp b/src/plugins/cpptools/cppsourceprocessor_test.cpp index f4a03a2501c..4d18d729a3b 100644 --- a/src/plugins/cpptools/cppsourceprocessor_test.cpp +++ b/src/plugins/cpptools/cppsourceprocessor_test.cpp @@ -143,7 +143,7 @@ void CppToolsPlugin::test_cppsourceprocessor_includes_cyclic() // Check editor snapshot const QString filePath = editor->document()->filePath(); - BuiltinEditorDocumentParser *parser = BuiltinEditorDocumentParser::get(filePath); + auto *parser = BuiltinEditorDocumentParser::get(filePath); QVERIFY(parser); Snapshot snapshot = parser->snapshot(); QCOMPARE(snapshot.size(), 3); // Configuration file included diff --git a/src/plugins/designer/gotoslot_test.cpp b/src/plugins/designer/gotoslot_test.cpp index fde64684332..54950c6907d 100644 --- a/src/plugins/designer/gotoslot_test.cpp +++ b/src/plugins/designer/gotoslot_test.cpp @@ -196,9 +196,14 @@ public: } // Compare - const Document::Ptr cppDocument = BuiltinEditorDocumentParser::get(cppFile)->document(); + BuiltinEditorDocumentParser *cppDocumentParser = BuiltinEditorDocumentParser::get(cppFile); + QVERIFY(cppDocumentParser); + const Document::Ptr cppDocument = cppDocumentParser->document(); QVERIFY(checkDiagsnosticMessages(cppDocument)); - const Document::Ptr hDocument = BuiltinEditorDocumentParser::get(hFile)->document(); + + BuiltinEditorDocumentParser *hDocumentParser = BuiltinEditorDocumentParser::get(hFile); + QVERIFY(hDocumentParser); + const Document::Ptr hDocument = hDocumentParser->document(); QVERIFY(checkDiagsnosticMessages(hDocument)); QVERIFY(documentContainsFunctionDefinition(cppDocument, From 9ccb6b81c982cebf6859d67d08683741df857842 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 28 Nov 2014 12:03:58 +0100 Subject: [PATCH 29/40] CppTools: Fix include hierarchy for clang code model This makes the editor document snapshot accessible through BaseEditorDocumentProcessor since we need it for the include hierarchy if the the clang code model is activated. Task-number: QTCREATORBUG-13553 Change-Id: I7214cc578d05fe5cad6e12b4d29fe6f840a88e8d Reviewed-by: Erik Verbruggen --- .../clangeditordocumentprocessor.cpp | 5 +++++ .../clangeditordocumentprocessor.h | 2 +- .../cppeditor/cppcodemodelinspectordialog.cpp | 6 +++--- .../cppeditor/cppincludehierarchymodel.cpp | 16 ++++++++-------- .../cpptools/baseeditordocumentprocessor.h | 1 + .../cpptools/builtineditordocumentprocessor.cpp | 5 +++++ .../cpptools/builtineditordocumentprocessor.h | 2 +- src/plugins/cpptools/cppsourceprocessor_test.cpp | 8 ++++---- 8 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 7c7823a3d82..e7ded2e40b5 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -160,6 +160,11 @@ CppTools::BaseEditorDocumentParser *ClangEditorDocumentProcessor::parser() return &m_parser; } +CPlusPlus::Snapshot ClangEditorDocumentProcessor::snapshot() +{ + return m_builtinProcessor.snapshot(); +} + bool ClangEditorDocumentProcessor::isParserRunning() const { return m_parserWatcher.isRunning(); diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index 0ceed0b10f4..7d24ffd9fd2 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -37,7 +37,6 @@ #include #include - #include namespace ClangCodeModel { @@ -55,6 +54,7 @@ public: void semanticRehighlight(bool force) Q_DECL_OVERRIDE; CppTools::SemanticInfo recalculateSemanticInfo() Q_DECL_OVERRIDE; CppTools::BaseEditorDocumentParser *parser() Q_DECL_OVERRIDE; + CPlusPlus::Snapshot snapshot() Q_DECL_OVERRIDE; bool isParserRunning() const Q_DECL_OVERRIDE; private slots: diff --git a/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp b/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp index d95680c6c55..9a3811cc2da 100644 --- a/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp +++ b/src/plugins/cppeditor/cppcodemodelinspectordialog.cpp @@ -35,7 +35,7 @@ #include #include -#include +#include #include #include #include @@ -1365,8 +1365,8 @@ void CppCodeModelInspectorDialog::refresh() if (editor) { const QString editorFilePath = editor->document()->filePath(); editorDocument = cmmi->editorDocument(editorFilePath); - if (auto *builtinDocumentParser = BuiltinEditorDocumentParser::get(editorFilePath)) { - const CPlusPlus::Snapshot editorSnapshot = builtinDocumentParser->snapshot(); + if (auto *documentProcessor = BaseEditorDocumentProcessor::get(editorFilePath)) { + const CPlusPlus::Snapshot editorSnapshot = documentProcessor->snapshot(); m_snapshotInfos->append(SnapshotInfo(editorSnapshot, SnapshotInfo::EditorSnapshot)); const QString editorSnapshotTitle = QString::fromLatin1("Current Editor's Snapshot (%1 Documents)") diff --git a/src/plugins/cppeditor/cppincludehierarchymodel.cpp b/src/plugins/cppeditor/cppincludehierarchymodel.cpp index ce0149aaa5e..8481c8cb0b2 100644 --- a/src/plugins/cppeditor/cppincludehierarchymodel.cpp +++ b/src/plugins/cppeditor/cppincludehierarchymodel.cpp @@ -33,7 +33,7 @@ #include "cppincludehierarchyitem.h" #include -#include +#include #include #include #include @@ -184,9 +184,9 @@ void CppIncludeHierarchyModel::fetchMore(const QModelIndex &parent) } if (item == m_includesItem) { - auto *parser = BuiltinEditorDocumentParser::get(editorFilePath); - QTC_ASSERT(parser, return); - const Snapshot editorDocumentSnapshot = parser->snapshot(); + auto *processor = BaseEditorDocumentProcessor::get(editorFilePath); + QTC_ASSERT(processor, return); + const Snapshot editorDocumentSnapshot = processor->snapshot(); buildHierarchyIncludes_helper(parentItem->filePath(), parentItem, editorDocumentSnapshot, &cyclic); } else { @@ -286,11 +286,11 @@ void CppIncludeHierarchyModel::buildHierarchyIncludes(const QString ¤tFile return; const QString editorFilePath = m_editor->document()->filePath(); - auto *parser = BuiltinEditorDocumentParser::get(editorFilePath); - QTC_ASSERT(parser, return); - const Snapshot snapshot = parser->snapshot(); + auto *documentProcessor = BaseEditorDocumentProcessor::get(editorFilePath); + QTC_ASSERT(documentProcessor, return); + const Snapshot editorDocumentSnapshot = documentProcessor->snapshot(); QSet cyclic; - buildHierarchyIncludes_helper(currentFilePath, m_includesItem, snapshot, &cyclic); + buildHierarchyIncludes_helper(currentFilePath, m_includesItem, editorDocumentSnapshot, &cyclic); } void CppIncludeHierarchyModel::buildHierarchyIncludes_helper(const QString &filePath, diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.h b/src/plugins/cpptools/baseeditordocumentprocessor.h index f507176cb74..866508eaab8 100644 --- a/src/plugins/cpptools/baseeditordocumentprocessor.h +++ b/src/plugins/cpptools/baseeditordocumentprocessor.h @@ -59,6 +59,7 @@ public: virtual void run() = 0; virtual void semanticRehighlight(bool force) = 0; virtual CppTools::SemanticInfo recalculateSemanticInfo() = 0; + virtual CPlusPlus::Snapshot snapshot() = 0; virtual BaseEditorDocumentParser *parser() = 0; virtual bool isParserRunning() const = 0; diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.cpp b/src/plugins/cpptools/builtineditordocumentprocessor.cpp index 3a3ee3eebb6..758c7083dbd 100644 --- a/src/plugins/cpptools/builtineditordocumentprocessor.cpp +++ b/src/plugins/cpptools/builtineditordocumentprocessor.cpp @@ -174,6 +174,11 @@ BaseEditorDocumentParser *BuiltinEditorDocumentProcessor::parser() return &m_parser; } +CPlusPlus::Snapshot BuiltinEditorDocumentProcessor::snapshot() +{ + return m_parser.snapshot(); +} + void BuiltinEditorDocumentProcessor::semanticRehighlight(bool force) { const auto source = createSemanticInfoSource(force); diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.h b/src/plugins/cpptools/builtineditordocumentprocessor.h index a0901181200..69f6148322b 100644 --- a/src/plugins/cpptools/builtineditordocumentprocessor.h +++ b/src/plugins/cpptools/builtineditordocumentprocessor.h @@ -37,7 +37,6 @@ #include "cpptools_global.h" #include "semantichighlighter.h" - namespace CppTools { class CPPTOOLS_EXPORT BuiltinEditorDocumentProcessor : public BaseEditorDocumentProcessor @@ -55,6 +54,7 @@ public: void semanticRehighlight(bool force) Q_DECL_OVERRIDE; CppTools::SemanticInfo recalculateSemanticInfo() Q_DECL_OVERRIDE; BaseEditorDocumentParser *parser() Q_DECL_OVERRIDE; + CPlusPlus::Snapshot snapshot() Q_DECL_OVERRIDE; bool isParserRunning() const Q_DECL_OVERRIDE; private: diff --git a/src/plugins/cpptools/cppsourceprocessor_test.cpp b/src/plugins/cpptools/cppsourceprocessor_test.cpp index 4d18d729a3b..70a98bed2c2 100644 --- a/src/plugins/cpptools/cppsourceprocessor_test.cpp +++ b/src/plugins/cpptools/cppsourceprocessor_test.cpp @@ -30,7 +30,7 @@ #include "cpptoolsplugin.h" -#include "builtineditordocumentparser.h" +#include "baseeditordocumentprocessor.h" #include "cppmodelmanager.h" #include "cppsourceprocessertesthelper.h" #include "cppsourceprocessor.h" @@ -143,9 +143,9 @@ void CppToolsPlugin::test_cppsourceprocessor_includes_cyclic() // Check editor snapshot const QString filePath = editor->document()->filePath(); - auto *parser = BuiltinEditorDocumentParser::get(filePath); - QVERIFY(parser); - Snapshot snapshot = parser->snapshot(); + auto *processor = BaseEditorDocumentProcessor::get(filePath); + QVERIFY(processor); + Snapshot snapshot = processor->snapshot(); QCOMPARE(snapshot.size(), 3); // Configuration file included // Check includes From 16c3745da475ceea0fd20c2bf32ab38c89682a16 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 27 Nov 2014 17:37:14 +0100 Subject: [PATCH 30/40] Doc: update QML emulation layer options A check box was divided into two radio buttons. Change-Id: I0439e038be2508a62811a5200c10a07367e85576 Reviewed-by: Tim Jenssen --- doc/src/qtquick/qtquick-modules-with-plugins.qdoc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/src/qtquick/qtquick-modules-with-plugins.qdoc b/doc/src/qtquick/qtquick-modules-with-plugins.qdoc index cc0586bed0b..f31fdaf2839 100644 --- a/doc/src/qtquick/qtquick-modules-with-plugins.qdoc +++ b/doc/src/qtquick/qtquick-modules-with-plugins.qdoc @@ -91,13 +91,14 @@ correctly from QML modules, the emulation layer must be built with the same Qt version as the QML modules. - By default, the emulation layer is provided by \QC and built with the same + By default, a fallback emulation layer is provided by \QC and built with the same Qt version as \QC. Therefore, your QML modules will mostly not work out of the box. To use an emulation layer that is built with the Qt - configured in the build and run kit for the project, deselect the - \gui {Always use the QML emulation layer provided by Qt Creator} check box. + configured in the build and run kit for the project, select \gui Tools > + \gui Options > \gui {Qt Quick} > \gui {Qt Quick Designer} > + \gui {Use QML emulation layer which is built by the selected Qt} radio button. \QC builds the emulation layer when you select the \gui Design mode. */ From 55a6050f37ad1ad60380782e87441d5467c569a1 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 28 Nov 2014 14:26:48 +0100 Subject: [PATCH 31/40] QmlProfiler: Use ClosedHandCursor for dragging categories It fits better to the OpenHandCursor we show when not dragging. Change-Id: I6d3d635b4d56dc0b6e5baa502722cac045e2e6e2 Reviewed-by: Alessandro Portale --- src/plugins/qmlprofiler/qml/CategoryLabel.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmlprofiler/qml/CategoryLabel.qml b/src/plugins/qmlprofiler/qml/CategoryLabel.qml index da26964af9f..c2dfee56e58 100644 --- a/src/plugins/qmlprofiler/qml/CategoryLabel.qml +++ b/src/plugins/qmlprofiler/qml/CategoryLabel.qml @@ -97,7 +97,7 @@ Item { id: dragArea anchors.fill: txt drag.target: dragger - cursorShape: dragging ? Qt.DragMoveCursor : Qt.OpenHandCursor + cursorShape: dragging ? Qt.ClosedHandCursor : Qt.OpenHandCursor } DropArea { From bf9a3b2020b033e8dc303fcb2b810d3b0051db25 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 26 Nov 2014 18:10:14 +0100 Subject: [PATCH 32/40] Debugger: Fix LLDB reference display for LLDB 320.x There is seemingly still no proper API for that, and the old hack broke. Use a new one. Change-Id: I9e638ca1fbd84c43c7d31b65e017792d1b6a1e0b Reviewed-by: Christian Stenger --- share/qtcreator/debugger/lldbbridge.py | 32 ++++++++++++++++++-------- tests/auto/debugger/tst_dumpers.cpp | 14 ++++++----- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 933c89b5447..6a381f9f81a 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -920,7 +920,6 @@ class Dumper(DumperBase): return False def putItem(self, value, tryDynamic=True): - #value = value.GetDynamicValue(lldb.eDynamicCanRunTarget) typeName = value.GetType().GetUnqualifiedType().GetName() if self.isGoodLldb: value.SetPreferDynamicValue(tryDynamic) @@ -965,10 +964,11 @@ class Dumper(DumperBase): realType = value.GetType() if hasattr(realType, 'GetCanonicalType'): baseType = realType.GetCanonicalType() - baseValue = value.Cast(baseType.unqualified()) - self.putItem(baseValue) - self.putBetterType(realType) - return + if baseType != realType: + baseValue = value.Cast(baseType.unqualified()) + self.putItem(baseValue) + self.putBetterType(realType) + return # Our turf now. if self.isGoodLldb: @@ -986,11 +986,24 @@ class Dumper(DumperBase): # References if value.GetType().IsReferenceType(): - origType = value.GetTypeName(); type = value.GetType().GetDereferencedType().unqualified() - addr = value.GetLoadAddress() - self.putItem(value.CreateValueFromAddress(None, addr, type)) - self.putBetterType(origType) + addr = value.GetValueAsUnsigned() + #warn("FROM: %s" % value) + #warn("ADDR: 0x%x" % addr) + #warn("TYPE: %s" % type) + # Works: + #item = self.currentThread().GetSelectedFrame().EvaluateExpression( + # "(%s*)0x%x" % (type, addr)).Dereference() + # Works: + item = value.CreateValueFromExpression(None, + "(%s*)0x%x" % (type, addr), lldb.SBExpressionOptions()).Dereference() + # Does not work: + #item = value.CreateValueFromAddress(None, addr, type) + # Does not work: + #item = value.Cast(type.GetPointerType()).Dereference() + #warn("TOOO: %s" % item) + self.putItem(item) + self.putBetterType(value.GetTypeName()) return # Pointers @@ -1534,7 +1547,6 @@ class Dumper(DumperBase): def selectThread(self, args): self.process.SetSelectedThreadByID(args['id']) self.reportData() - self.reportStack() def requestModuleSymbols(self, frame): self.handleCommand("target module list " + frame) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 9d55438e217..059d388080a 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -1441,7 +1441,10 @@ void tst_Dumpers::dumper_data() "public:\n" " Foo(int i = 0)\n" " : a(i), b(2)\n" - " {}\n" + " {\n" + " for (int j = 0; j < 6; ++j)\n" + " x[j] = 'a' + j;\n" + " }\n" " virtual ~Foo()\n" " {\n" " a = 5;\n" @@ -4845,12 +4848,12 @@ void tst_Dumpers::dumper_data() QTest::newRow("Reference") - << Data(fooData + - "#include \n" + << Data("#include \n" "#include \n" "using namespace std;\n" - "string fooxx() { return \"bababa\"; }\n", + "string fooxx() { return \"bababa\"; }\n" + + fooData, "int a1 = 43;\n" "const int &b1 = a1;\n" @@ -4888,7 +4891,7 @@ void tst_Dumpers::dumper_data() + Check("a2", "\"hello\"", "std::string") + Check("b2", "\"bababa\"", Pattern("(std::)?string &")) // Clang... + Check("c2", "\"world\"", "std::string") - + Check("d2", "\"hello\"", "Ref2") + + Check("d2", "\"hello\"", "Ref2") % NoLldbEngine + Check("a3", "\"hello\"", "@QString") + Check("b3", "\"hello\"", "@QString &") @@ -4901,7 +4904,6 @@ void tst_Dumpers::dumper_data() //+ Check("d4", "\"hello\"", "Ref4"); FIXME: We get "Foo &" instead + Check("d4.a", "12", "int"); - QTest::newRow("DynamicReference") << Data("struct BaseClass { virtual ~BaseClass() {} };\n" "struct DerivedClass : BaseClass {};\n", From b1dab6534069e78230f8469ba73da8e4d928ccee Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 28 Nov 2014 16:17:00 +0100 Subject: [PATCH 33/40] Update qbs submodule. To HEAD of 1.3 branch. Change-Id: I633185f4c62a2290367f5a232c5ca7f818a36377 Reviewed-by: Christian Kandeler --- src/shared/qbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/qbs b/src/shared/qbs index 21978bc41e5..be93bcdf9f0 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit 21978bc41e5ac9959cedc93cc9aacff4831ee2ef +Subproject commit be93bcdf9f0c50bcc88557e3f2568568f13ae0bd From 245ea90817014422bcce964d1b7aa8deeb7a981d Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Tue, 25 Nov 2014 18:23:15 +0100 Subject: [PATCH 34/40] Qt Quick Compiler Support: Only allow valid settings If the Qt Quick Compiler binary is not present in the binary tools directory of the Qt version, disable the checkbox. A warning will be added in the next minor version, sind we already have string freeze. QML debugging does not work when using the Qt Quick Compiler. So, in case the Qt Quick Compiler is checked, let's disable the QML debugging checkbox. Change-Id: I739b1f71dc53aca9cf00e6ffd15246184d89816b Reviewed-by: hjk Reviewed-by: Alessandro Portale --- src/plugins/qmakeprojectmanager/qmakestep.cpp | 19 ++++++++++--------- src/plugins/qtsupport/baseqtversion.cpp | 7 +++++++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 0d2f3836f1b..bc43f4bf8a6 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -66,7 +66,7 @@ const char QMAKE_BS_ID[] = "QtProjectManager.QMakeBuildStep"; const char QMAKE_ARGUMENTS_KEY[] = "QtProjectManager.QMakeBuildStep.QMakeArguments"; const char QMAKE_FORCED_KEY[] = "QtProjectManager.QMakeBuildStep.QMakeForced"; -const char QMAKE_USE_qtQuickCompiler[] = "QtProjectManager.QMakeBuildStep.UseqtQuickCompiler"; +const char QMAKE_USE_QTQUICKCOMPILER[] = "QtProjectManager.QMakeBuildStep.UseQtQuickCompiler"; const char QMAKE_QMLDEBUGLIBAUTO_KEY[] = "QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto"; const char QMAKE_QMLDEBUGLIB_KEY[] = "QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary"; } @@ -178,7 +178,7 @@ QStringList QMakeStep::deducedArguments() QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); arguments << QmakeBuildConfiguration::deduceArgumnetsForTargetAbi(targetAbi, version); - if (linkQmlDebuggingLibrary() && version) { + if (linkQmlDebuggingLibrary() && version && !useQtQuickCompiler()) { arguments << QLatin1String(Constants::QMAKEVAR_QUICK1_DEBUG); if (version->qtVersion().majorVersion >= 5) arguments << QLatin1String(Constants::QMAKEVAR_QUICK2_DEBUG); @@ -377,9 +377,6 @@ void QMakeStep::setLinkQmlDebuggingLibrary(bool enable) bool QMakeStep::useQtQuickCompiler() const { - const Core::Context languages = project()->projectLanguages(); - if (!languages.contains(ProjectExplorer::Constants::LANG_QMLJS)) - return false; return m_useQtQuickCompiler; } @@ -430,7 +427,7 @@ QVariantMap QMakeStep::toMap() const map.insert(QLatin1String(QMAKE_QMLDEBUGLIBAUTO_KEY), m_linkQmlDebuggingLibrary == DebugLink); map.insert(QLatin1String(QMAKE_QMLDEBUGLIB_KEY), m_linkQmlDebuggingLibrary == DoLink); map.insert(QLatin1String(QMAKE_FORCED_KEY), m_forced); - map.insert(QLatin1String(QMAKE_USE_qtQuickCompiler), m_useQtQuickCompiler); + map.insert(QLatin1String(QMAKE_USE_QTQUICKCOMPILER), m_useQtQuickCompiler); return map; } @@ -438,7 +435,7 @@ bool QMakeStep::fromMap(const QVariantMap &map) { m_userArgs = map.value(QLatin1String(QMAKE_ARGUMENTS_KEY)).toString(); m_forced = map.value(QLatin1String(QMAKE_FORCED_KEY), false).toBool(); - m_useQtQuickCompiler = map.value(QLatin1String(QMAKE_USE_qtQuickCompiler), false).toBool(); + m_useQtQuickCompiler = map.value(QLatin1String(QMAKE_USE_QTQUICKCOMPILER), false).toBool(); if (map.value(QLatin1String(QMAKE_QMLDEBUGLIBAUTO_KEY), false).toBool()) { m_linkQmlDebuggingLibrary = DebugLink; } else { @@ -524,6 +521,7 @@ void QMakeStepConfigWidget::qtVersionChanged() updateSummaryLabel(); updateEffectiveQMakeCall(); updateQmlDebuggingOption(); + updateQtQuickCompilerOption(); } void QMakeStepConfigWidget::qmakeBuildConfigChanged() @@ -561,11 +559,11 @@ void QMakeStepConfigWidget::useQtQuickCompilerChanged() { if (m_ignoreChange) return; -// m_ui->qtQuickCompilerCheckBox->setChecked(m_step->useQtQuickCompiler()); updateSummaryLabel(); updateEffectiveQMakeCall(); updateQtQuickCompilerOption(); + updateQmlDebuggingOption(); } void QMakeStepConfigWidget::qmakeArgumentsLineEdited() @@ -633,6 +631,7 @@ void QMakeStepConfigWidget::useQtQuickCompilerChecked(bool checked) updateSummaryLabel(); updateEffectiveQMakeCall(); + updateQmlDebuggingOption(); updateQtQuickCompilerOption(); } @@ -654,7 +653,9 @@ void QMakeStepConfigWidget::updateQmlDebuggingOption() { QString warningText; bool supported = QtSupport::BaseQtVersion::isQmlDebuggingSupported(m_step->target()->kit(), - &warningText); + &warningText) + && !m_step->useQtQuickCompiler(); + m_ui->qmlDebuggingLibraryCheckBox->setEnabled(supported); m_ui->debuggingLibraryLabel->setText(tr("Enable QML debugging:")); diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index bf89085e572..0038fa3eab6 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -1556,6 +1556,13 @@ bool BaseQtVersion::isQtQuickCompilerSupported(QString *reason) const return false; } + const QString qtQuickCompilerExecutable = + HostOsInfo::withExecutableSuffix(binPath().toString() + QLatin1String("/qtquickcompiler")); + if (!QFileInfo::exists(qtQuickCompilerExecutable)) { + // TODO: Add reason string in master + return false; + } + return true; } From 47f9622e727c0bdac1b9ed447338ac99af04dea4 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 21 Nov 2014 16:58:39 +0100 Subject: [PATCH 35/40] Fix QML watch expressions for v8 Fix syncing of watch expressions with Qt Quick 2. For v8/v4 we're utilizing the 'evaluate' command, which we have to re-send on every change to get updates. We therefore now call synchronizeWatchers() whenever the stack changes. Task-number: QTCREATORBUG-13473 Change-Id: I7356e9518a719839c5cbb6e518be18e665078e85 Reviewed-by: Ulf Hermann Reviewed-by: Robert Loehning --- src/plugins/debugger/qml/qmlengine.cpp | 2 ++ src/plugins/debugger/qml/qmlv8debuggerclient.cpp | 14 ++++---------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index bbadd161a94..7efd0ace733 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -1176,6 +1176,8 @@ void QmlEngine::updateCurrentContext() context = grandParentData->name; } + synchronizeWatchers(); + QmlJS::ConsoleManagerInterface *consoleManager = qmlConsoleManager(); if (consoleManager) consoleManager->setContext(tr("Context:") + QLatin1Char(' ') + context); diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp index 8b0c93cb8ef..1de81dbdbf6 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp @@ -135,7 +135,6 @@ public: QList debuggerCommands; //Cache - QStringList watchedExpressions; QList currentFrameScopes; QHash stackIndexLookup; @@ -722,9 +721,7 @@ QmlV8ObjectData extractData(const QVariant &data, const QVariant &refsVal) void QmlV8DebuggerClientPrivate::clearCache() { - watchedExpressions.clear(); currentFrameScopes.clear(); - evaluatingExpression.clear(); updateLocalsAndWatchers.clear(); } @@ -958,15 +955,12 @@ void QmlV8DebuggerClient::synchronizeWatchers(const QStringList &watchers) { SDEBUG(watchers); foreach (const QString &exp, watchers) { - if (!d->watchedExpressions.contains(exp)) { - StackHandler *stackHandler = d->engine->stackHandler(); - if (stackHandler->isContentsValid() && stackHandler->currentFrame().isUsable()) { - d->evaluate(exp, false, false, stackHandler->currentIndex()); - d->evaluatingExpression.insert(d->sequence, exp); - } + StackHandler *stackHandler = d->engine->stackHandler(); + if (stackHandler->isContentsValid() && stackHandler->currentFrame().isUsable()) { + d->evaluate(exp, false, false, stackHandler->currentIndex()); + d->evaluatingExpression.insert(d->sequence, exp); } } - d->watchedExpressions = watchers; } void QmlV8DebuggerClient::expandObject(const QByteArray &iname, quint64 objectId) From 95afdf6c3841427e193003a02389cff0a784b548 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 28 Nov 2014 15:28:15 +0100 Subject: [PATCH 36/40] Doc: QML_PUPPET_MODE env variable The variable was added for checking whether a QML plugin is run in Design mode or by an application. Task-number: QTCREATORBUG-12439 Change-Id: Iad99b7279c8191cb8b17ca81ff24fb9db731fdc9 Reviewed-by: Thomas Hartmann --- doc/src/qtquick/qtquick-modules-with-plugins.qdoc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/src/qtquick/qtquick-modules-with-plugins.qdoc b/doc/src/qtquick/qtquick-modules-with-plugins.qdoc index f31fdaf2839..99ee6b328dd 100644 --- a/doc/src/qtquick/qtquick-modules-with-plugins.qdoc +++ b/doc/src/qtquick/qtquick-modules-with-plugins.qdoc @@ -101,4 +101,10 @@ \gui {Use QML emulation layer which is built by the selected Qt} radio button. \QC builds the emulation layer when you select the \gui Design mode. + A plugin should behave differently depending on whether it is run by the + emulation layer or an application. For example, animations should not be run + in the \gui Design mode. You can use the value of the QML_PUPPET_MODE + environment variable to check whether the plugin is currently being run + by an application or edited in the \gui Design mode. + */ From 8fdce7cdacca881994685810dceaf14a949095a5 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 28 Nov 2014 16:30:25 +0100 Subject: [PATCH 37/40] Debugger: Disable QVariant(KeySequence) dumper for LLDB This triggers errors in LLDB error: main.o Parsing a die that is being parsed die: 0x00001ddf: DW_TAG_subprogram operator void *QMetaObject::Connection::* error: main.o Parsing a die that is being parsed die: 0x000100fa: DW_TAG_subprogram operator QObjectData *QScopedPointer >::* Change-Id: Iae6a8ca1fbd84c43c7d31b65e017792d1b6a1e0b Reviewed-by: Christian Stenger --- tests/auto/debugger/tst_dumpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 059d388080a..f055f9a3afc 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -3311,7 +3311,7 @@ void tst_Dumpers::dumper_data() //+ Check("var72", "", "@QVariant (QRegion)") FIXME + Check("var73", "", "@QVariant (QBitmap)") + Check("var74", "", "@QVariant (QCursor)") - + Check("var75", "", "@QVariant (QKeySequence)") + + Check("var75", "", "@QVariant (QKeySequence)") % NoLldbEngine // FIXME + Check("var76", "", "@QVariant (QPen)") + Check("var77", "", "@QVariant (QTextLength)") //+ Check("var78", Value5(""), "@QVariant (QTextFormat)") From b28d1525ebc8491c839412ce946fca5d6f22d38f Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 28 Nov 2014 17:07:56 +0100 Subject: [PATCH 38/40] ProjectExplorer: Move environment "Batch Edit" button up It was often enough below the visible area of the view and people did not notice it exists. Change-Id: Ie1427c3cb90b6d4a200a17cf51402aabc51de7e7 Reviewed-by: Jarek Kobus Reviewed-by: Eike Ziller --- src/plugins/projectexplorer/environmentwidget.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/plugins/projectexplorer/environmentwidget.cpp b/src/plugins/projectexplorer/environmentwidget.cpp index 10074936e92..094f9ecb749 100644 --- a/src/plugins/projectexplorer/environmentwidget.cpp +++ b/src/plugins/projectexplorer/environmentwidget.cpp @@ -128,13 +128,12 @@ EnvironmentWidget::EnvironmentWidget(QWidget *parent, QWidget *additionalDetails d->m_unsetButton->setText(tr("&Unset")); buttonLayout->addWidget(d->m_unsetButton); - QSpacerItem *verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); - buttonLayout->addItem(verticalSpacer); - d->m_batchEditButton = new QPushButton(this); d->m_batchEditButton->setText(tr("&Batch Edit...")); buttonLayout->addWidget(d->m_batchEditButton); + buttonLayout->addStretch(); + horizontalLayout->addLayout(buttonLayout); vbox2->addLayout(horizontalLayout); From 762a3e6e4cd8843d5c72e4c6d5acb820d991b3eb Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 27 Nov 2014 17:46:45 +0100 Subject: [PATCH 39/40] Qnx: Introduce QnxDeviceProcess This is helpful for more selective and direct process killing. Previously, all processes with a given name were killed, and in some cases stale awk and grep processes were left over. Change-Id: I4fb3999818062b8c1fdf7dca8a337ef9c158be9b Reviewed-by: Christian Kandeler --- src/plugins/qnx/qnxdeviceconfiguration.cpp | 56 ++++++++++++++++++++-- src/plugins/qnx/qnxdeviceconfiguration.h | 20 ++++++++ src/plugins/qnx/slog2inforunner.cpp | 7 +-- 3 files changed, 77 insertions(+), 6 deletions(-) diff --git a/src/plugins/qnx/qnxdeviceconfiguration.cpp b/src/plugins/qnx/qnxdeviceconfiguration.cpp index 3305959bcd5..2224a44e752 100644 --- a/src/plugins/qnx/qnxdeviceconfiguration.cpp +++ b/src/plugins/qnx/qnxdeviceconfiguration.cpp @@ -39,20 +39,62 @@ #include #include #include +#include #include #include #include #include -using namespace Qnx; -using namespace Qnx::Internal; +using namespace ProjectExplorer; +using namespace Utils; + +namespace Qnx { +namespace Internal { -namespace { const char QnxVersionKey[] = "QnxVersion"; const char DeployQtLibrariesActionId [] = "Qnx.Qnx.DeployQtLibrariesAction"; + +static int pidFileCounter = 0; + +QnxDeviceProcess::QnxDeviceProcess(const QSharedPointer &device, QObject *parent) + : SshDeviceProcess(device, parent) +{ + setEnvironment(Environment(OsTypeLinux)); + m_pidFile = QString::fromLatin1("/var/run/qtc.%1.pid").arg(++pidFileCounter); } +QString QnxDeviceProcess::fullCommandLine() const +{ + QStringList args = arguments(); + args.prepend(executable()); + QString cmd = QtcProcess::Arguments::createUnixArgs(args).toString(); + + QString fullCommandLine = QLatin1String( + "test -f /etc/profile && . /etc/profile ; " + "test -f $HOME/profile && . $HOME/profile ; " + ); + + if (!m_workingDir.isEmpty()) + fullCommandLine += QString::fromLatin1("cd %1 ; ").arg(QtcProcess::quoteArg(m_workingDir)); + + for (auto it = environment().constBegin(); it != environment().constEnd(); ++it) + fullCommandLine += QString::fromLatin1("%1='%2' ").arg(it.key()).arg(it.value()); + + fullCommandLine += QString::fromLatin1("%1 & echo $! > %2").arg(cmd).arg(m_pidFile); + + return fullCommandLine; +} + +void QnxDeviceProcess::doSignal(int sig) +{ + auto signaler = new SshDeviceProcess(device(), this); + QString cmd = QString::fromLatin1("kill -%2 `cat %1`").arg(m_pidFile).arg(sig); + connect(signaler, &SshDeviceProcess::finished, signaler, &QObject::deleteLater); + signaler->start(cmd, QStringList()); +} + + class QnxPortsGatheringMethod : public ProjectExplorer::PortsGatheringMethod { // TODO: The command is probably needlessly complicated because the parsing method @@ -196,6 +238,11 @@ ProjectExplorer::DeviceTester *QnxDeviceConfiguration::createDeviceTester() cons return new QnxDeviceTester; } +ProjectExplorer::DeviceProcess *QnxDeviceConfiguration::createProcess(QObject *parent) const +{ + return new QnxDeviceProcess(sharedFromThis(), parent); +} + QList QnxDeviceConfiguration::actionIds() const { QList actions = RemoteLinux::LinuxDevice::actionIds(); @@ -228,3 +275,6 @@ ProjectExplorer::DeviceProcessSignalOperation::Ptr QnxDeviceConfiguration::signa return ProjectExplorer::DeviceProcessSignalOperation::Ptr( new QnxDeviceProcessSignalOperation(sshParameters())); } + +} // namespace Internal +} // namespace Qnx diff --git a/src/plugins/qnx/qnxdeviceconfiguration.h b/src/plugins/qnx/qnxdeviceconfiguration.h index 9f95be2d84d..1fe3aedb53a 100644 --- a/src/plugins/qnx/qnxdeviceconfiguration.h +++ b/src/plugins/qnx/qnxdeviceconfiguration.h @@ -34,10 +34,29 @@ #define QNX_INTERNAL_QNXDEVICECONFIGURATION_H #include +#include namespace Qnx { namespace Internal { +class QnxDeviceProcess : public ProjectExplorer::SshDeviceProcess +{ +public: + QnxDeviceProcess(const QSharedPointer &device, QObject *parent); + + void setWorkingDirectory(const QString &directory) { m_workingDir = directory; } + + void interrupt() { doSignal(2); } + void terminate() { doSignal(15); } + void kill() { doSignal(9); } + QString fullCommandLine() const; + +private: + void doSignal(int sig); + QString m_pidFile; + QString m_workingDir; +}; + class QnxDeviceConfiguration : public RemoteLinux::LinuxDevice { Q_DECLARE_TR_FUNCTIONS(Qnx::Internal::QnxDeviceConfiguration) @@ -56,6 +75,7 @@ public: ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const; ProjectExplorer::DeviceTester *createDeviceTester() const; + ProjectExplorer::DeviceProcess *createProcess(QObject *parent) const; QList actionIds() const; QString displayNameForActionId(Core::Id actionId) const; diff --git a/src/plugins/qnx/slog2inforunner.cpp b/src/plugins/qnx/slog2inforunner.cpp index 5a33a467754..e24a5ee66a1 100644 --- a/src/plugins/qnx/slog2inforunner.cpp +++ b/src/plugins/qnx/slog2inforunner.cpp @@ -32,7 +32,8 @@ #include "slog2inforunner.h" -#include +#include "qnxdeviceconfiguration.h" + #include using namespace Qnx; @@ -48,13 +49,13 @@ Slog2InfoRunner::Slog2InfoRunner(const QString &applicationId, const RemoteLinux // We need to limit length of ApplicationId to 63 otherwise it would not match one in slog2info. m_applicationId.truncate(63); - m_testProcess = new ProjectExplorer::SshDeviceProcess(device, this); + m_testProcess = new QnxDeviceProcess(device, this); connect(m_testProcess, SIGNAL(finished()), this, SLOT(handleTestProcessCompleted())); m_launchDateTimeProcess = new ProjectExplorer::SshDeviceProcess(device, this); connect(m_launchDateTimeProcess, SIGNAL(finished()), this, SLOT(launchSlog2Info())); - m_logProcess = new ProjectExplorer::SshDeviceProcess(device, this); + m_logProcess = new QnxDeviceProcess(device, this); connect(m_logProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readLogStandardOutput())); connect(m_logProcess, SIGNAL(readyReadStandardError()), this, SLOT(readLogStandardError())); connect(m_logProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(handleLogError())); From d93afdeda502cbb8ebde0357fce1dc86387d60df Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 1 Dec 2014 13:46:48 +0100 Subject: [PATCH 40/40] Debugger: Add MSVC runtime module name for VC 12. Change-Id: I856ed20ad1df493dd430ebf1d0043e57bb9f14f4 Reviewed-by: hjk --- src/plugins/debugger/cdb/cdbengine.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index fc3c40f2310..103ee14a2a4 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -783,7 +783,9 @@ static QByteArray msvcRunTime(const Abi::OSFlavor flavour) case Abi::WindowsMsvc2010Flavor: return "MSVCR100"; case Abi::WindowsMsvc2012Flavor: - return "MSVCR110"; // #FIXME: VS2012 beta, will probably be 12 in final? + return "MSVCR110"; + case Abi::WindowsMsvc2013Flavor: + return "MSVCR120"; default: break; }