From e7789de28c97b437f6c808751812d05e05886a75 Mon Sep 17 00:00:00 2001 From: Lorenz Haas Date: Sun, 21 Jun 2015 19:12:02 +0200 Subject: [PATCH 001/113] Beautifier: Add const wherever applicable Change-Id: Iba3e5793bfd0e4057074e2b04e6353ba09aa4a5f Reviewed-by: David Schulz --- src/plugins/beautifier/abstractsettings.cpp | 2 +- src/plugins/beautifier/beautifierplugin.cpp | 4 ++-- src/plugins/beautifier/clangformat/clangformat.cpp | 5 +++-- .../beautifier/clangformat/clangformatoptionspage.cpp | 2 +- src/plugins/beautifier/configurationdialog.cpp | 4 +--- src/plugins/beautifier/configurationeditor.cpp | 4 ++-- src/plugins/beautifier/configurationpanel.cpp | 4 ++-- src/plugins/beautifier/uncrustify/uncrustify.cpp | 3 ++- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/plugins/beautifier/abstractsettings.cpp b/src/plugins/beautifier/abstractsettings.cpp index b67e57cc75f..81e6193102f 100644 --- a/src/plugins/beautifier/abstractsettings.cpp +++ b/src/plugins/beautifier/abstractsettings.cpp @@ -82,7 +82,7 @@ bool AbstractSettings::styleExists(const QString &key) const bool AbstractSettings::styleIsReadOnly(const QString &key) { - QFileInfo fi(m_styleDir.absoluteFilePath(key + m_ending)); + const QFileInfo fi(m_styleDir.absoluteFilePath(key + m_ending)); if (!fi.exists()) { // newly added style which was not saved yet., thus it is not read only. //TODO In a later version when we have predefined styles in Core::ICore::resourcePath() diff --git a/src/plugins/beautifier/beautifierplugin.cpp b/src/plugins/beautifier/beautifierplugin.cpp index bcfb73ec5f0..960a2fdca64 100644 --- a/src/plugins/beautifier/beautifierplugin.cpp +++ b/src/plugins/beautifier/beautifierplugin.cpp @@ -142,7 +142,7 @@ QString BeautifierPlugin::format(const QString &text, const Command &command, switch (command.processing()) { case Command::FileProcessing: { // Save text to temporary file - QFileInfo fi(fileName); + const QFileInfo fi(fileName); Utils::TempFileSaver sourceFile(QDir::tempPath() + QLatin1String("/qtc_beautifier_XXXXXXXX.") + fi.suffix()); sourceFile.setAutoRemove(true); @@ -396,7 +396,7 @@ void BeautifierPlugin::formatCurrentFileContinue(QObject *watcher) // Restore folded blocks const QTextDocument *doc = textEditor->document(); foreach (const int blockId, foldedBlocks) { - QTextBlock block = doc->findBlockByNumber(qMax(0, blockId)); + const QTextBlock block = doc->findBlockByNumber(qMax(0, blockId)); if (block.isValid()) TextDocumentLayout::doFoldOrUnfold(block, false); } diff --git a/src/plugins/beautifier/clangformat/clangformat.cpp b/src/plugins/beautifier/clangformat/clangformat.cpp index e277c86a317..79eee4a1356 100644 --- a/src/plugins/beautifier/clangformat/clangformat.cpp +++ b/src/plugins/beautifier/clangformat/clangformat.cpp @@ -112,11 +112,12 @@ void ClangFormat::formatFile() void ClangFormat::formatSelectedText() { - TextEditor::TextEditorWidget *widget = TextEditor::TextEditorWidget::currentTextEditorWidget(); + const TextEditor::TextEditorWidget *widget + = TextEditor::TextEditorWidget::currentTextEditorWidget(); if (!widget) return; - QTextCursor tc = widget->textCursor(); + const QTextCursor tc = widget->textCursor(); if (tc.hasSelection()) { const int offset = tc.selectionStart(); const int length = tc.selectionEnd() - offset; diff --git a/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp b/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp index f271a2ffa2c..32fb362f05a 100644 --- a/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp +++ b/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp @@ -69,7 +69,7 @@ ClangFormatOptionsPageWidget::~ClangFormatOptionsPageWidget() void ClangFormatOptionsPageWidget::restore() { ui->command->setPath(m_settings->command()); - int textIndex = ui->predefinedStyle->findText(m_settings->predefinedStyle()); + const int textIndex = ui->predefinedStyle->findText(m_settings->predefinedStyle()); if (textIndex != -1) ui->predefinedStyle->setCurrentIndex(textIndex); ui->formatEntireFileFallback->setChecked(m_settings->formatEntireFileFallback()); diff --git a/src/plugins/beautifier/configurationdialog.cpp b/src/plugins/beautifier/configurationdialog.cpp index 572a7182331..9d010419d36 100644 --- a/src/plugins/beautifier/configurationdialog.cpp +++ b/src/plugins/beautifier/configurationdialog.cpp @@ -137,9 +137,7 @@ QString ConfigurationDialog::value() const void ConfigurationDialog::updateOkButton() { const QString key = ui->name->text().simplified(); - bool exists = false; - if (m_settings && key != m_currentKey) - exists = m_settings->styleExists(key); + const bool exists = m_settings && key != m_currentKey && m_settings->styleExists(key); ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!(key.isEmpty() || exists)); } diff --git a/src/plugins/beautifier/configurationeditor.cpp b/src/plugins/beautifier/configurationeditor.cpp index f435409cfa7..a9b113569c5 100644 --- a/src/plugins/beautifier/configurationeditor.cpp +++ b/src/plugins/beautifier/configurationeditor.cpp @@ -139,7 +139,7 @@ void ConfigurationEditor::setCommentExpression(const QRegExp &rx) bool ConfigurationEditor::eventFilter(QObject *object, QEvent *event) { if (event->type() == QEvent::ShortcutOverride) { - QKeyEvent *key = static_cast(event); + const QKeyEvent *key = static_cast(event); if (key->key() == Qt::Key_Escape) { event->accept(); m_completer->popup()->hide(); @@ -176,7 +176,7 @@ void ConfigurationEditor::keyPressEvent(QKeyEvent *event) QPlainTextEdit::keyPressEvent(event); const int cursorPosition = textCursor().position(); - QTextCursor cursor = cursorForTextUnderCursor(); + const QTextCursor cursor = cursorForTextUnderCursor(); const QString prefix = cursor.selectedText(); if (!isShortcut && (prefix.length() < 2 || cursorPosition != cursor.position())) { diff --git a/src/plugins/beautifier/configurationpanel.cpp b/src/plugins/beautifier/configurationpanel.cpp index cd8a148aca0..01162eeda80 100644 --- a/src/plugins/beautifier/configurationpanel.cpp +++ b/src/plugins/beautifier/configurationpanel.cpp @@ -65,7 +65,7 @@ void ConfigurationPanel::setSettings(AbstractSettings *settings) void ConfigurationPanel::setCurrentConfiguration(const QString &text) { - int textIndex = ui->configurations->findText(text); + const int textIndex = ui->configurations->findText(text); if (textIndex != -1) ui->configurations->setCurrentIndex(textIndex); } @@ -117,7 +117,7 @@ void ConfigurationPanel::populateConfigurations(const QString &key) const QString currentText = (!key.isEmpty()) ? key : ui->configurations->currentText(); ui->configurations->clear(); ui->configurations->addItems(m_settings->styles()); - int textIndex = ui->configurations->findText(currentText); + const int textIndex = ui->configurations->findText(currentText); if (textIndex != -1) ui->configurations->setCurrentIndex(textIndex); updateButtons(); diff --git a/src/plugins/beautifier/uncrustify/uncrustify.cpp b/src/plugins/beautifier/uncrustify/uncrustify.cpp index a501a6c209f..10cbbd9860d 100644 --- a/src/plugins/beautifier/uncrustify/uncrustify.cpp +++ b/src/plugins/beautifier/uncrustify/uncrustify.cpp @@ -130,7 +130,8 @@ void Uncrustify::formatSelectedText() return; } - TextEditor::TextEditorWidget *widget = TextEditor::TextEditorWidget::currentTextEditorWidget(); + const TextEditor::TextEditorWidget *widget + = TextEditor::TextEditorWidget::currentTextEditorWidget(); if (!widget) return; From ee5abe6bfcab18f0444a92d1356530c92f0f84a3 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 22 Jun 2015 18:08:44 +0200 Subject: [PATCH 002/113] Analyzer: Move towards less global state Make startTool() explicit as selectAction(Id) + startAction(Id). Change-Id: I695112bd8419021a781234121a55440b5dc381be Reviewed-by: Ulf Hermann --- src/plugins/analyzerbase/analyzermanager.cpp | 25 ++++++++++---------- src/plugins/analyzerbase/analyzermanager.h | 3 +-- src/plugins/qmlprofiler/qmlprofilertool.cpp | 2 +- src/plugins/valgrind/callgrindtool.cpp | 3 +-- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/plugins/analyzerbase/analyzermanager.cpp b/src/plugins/analyzerbase/analyzermanager.cpp index 995203ca2f6..03782f31d0e 100644 --- a/src/plugins/analyzerbase/analyzermanager.cpp +++ b/src/plugins/analyzerbase/analyzermanager.cpp @@ -155,7 +155,7 @@ public: void handleToolFinished(); void saveToolSettings(Id toolId); void loadToolSettings(Id toolId); - void startTool(); + void startCurrentTool(); void selectToolboxAction(const QString &item); void modeChanged(IMode *mode); void resetLayout(); @@ -241,7 +241,8 @@ void AnalyzerManagerPrivate::setupActions() m_startAction = new QAction(tr("Start"), m_menu); m_startAction->setIcon(QIcon(QLatin1String(ANALYZER_CONTROL_START_ICON))); ActionManager::registerAction(m_startAction, "Analyzer.Start"); - connect(m_startAction, &QAction::triggered, this, &AnalyzerManagerPrivate::startTool); + connect(m_startAction, &QAction::triggered, + this, &AnalyzerManagerPrivate::startCurrentTool); m_stopAction = new QAction(tr("Stop"), m_menu); m_stopAction->setEnabled(false); @@ -420,7 +421,7 @@ bool AnalyzerManagerPrivate::showPromptDialog(const QString &title, const QStrin return messageBox.clickedStandardButton() == QDialogButtonBox::Yes; } -void AnalyzerManagerPrivate::startTool() +void AnalyzerManagerPrivate::startCurrentTool() { QTC_ASSERT(m_currentAction, return); m_currentAction->startTool(); @@ -539,9 +540,8 @@ void AnalyzerManagerPrivate::addAction(AnalyzerAction *action) rebuildToolBox(); connect(action, &QAction::triggered, this, [this, action] { - AnalyzerManager::showMode(); selectAction(action); - startTool(); + action->startTool(); }); } @@ -647,16 +647,15 @@ QDockWidget *AnalyzerManager::createDockWidget(Core::Id toolId, return dockWidget; } -void AnalyzerManager::selectTool(Id actionId) +void AnalyzerManager::selectAction(Id actionId, bool alsoRunIt) { - foreach (AnalyzerAction *action, d->m_actions) - if (action->actionId() == actionId) + foreach (AnalyzerAction *action, d->m_actions) { + if (action->actionId() == actionId) { d->selectAction(action); -} - -void AnalyzerManager::startTool() -{ - d->startTool(); + if (alsoRunIt) + action->startTool(); + } + } } FancyMainWindow *AnalyzerManager::mainWindow() diff --git a/src/plugins/analyzerbase/analyzermanager.h b/src/plugins/analyzerbase/analyzermanager.h index 786589b0733..a5c309a46ef 100644 --- a/src/plugins/analyzerbase/analyzermanager.h +++ b/src/plugins/analyzerbase/analyzermanager.h @@ -74,8 +74,7 @@ public: static Utils::FancyMainWindow *mainWindow(); static void showMode(); - static void selectTool(Core::Id actionId); - static void startTool(); + static void selectAction(Core::Id actionId, bool alsoRunIt = false); static void stopTool(); // Convenience functions. diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 2ea39855a0e..f565557200a 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -541,7 +541,7 @@ void QmlProfilerTool::showLoadDialog() if (ModeManager::currentMode()->id() != MODE_ANALYZE) AnalyzerManager::showMode(); - AnalyzerManager::selectTool(QmlProfilerRemoteActionId); + AnalyzerManager::selectAction(QmlProfilerRemoteActionId); QString filename = QFileDialog::getOpenFileName(ICore::mainWindow(), tr("Load QML Trace"), QString(), tr("QML traces (*%1)").arg(QLatin1String(TraceFileExtension))); diff --git a/src/plugins/valgrind/callgrindtool.cpp b/src/plugins/valgrind/callgrindtool.cpp index b792cd2dd1e..b17abe0c3ce 100644 --- a/src/plugins/valgrind/callgrindtool.cpp +++ b/src/plugins/valgrind/callgrindtool.cpp @@ -891,8 +891,7 @@ void CallgrindToolPrivate::handleShowCostsOfFunction() m_toggleCollectFunction = qualifiedFunctionName + QLatin1String("()"); - AnalyzerManager::selectTool(CallgrindLocalActionId); - AnalyzerManager::startTool(); + AnalyzerManager::selectAction(CallgrindLocalActionId, /* alsoRunIt = */ true); } void CallgrindToolPrivate::slotRequestDump() From e228c11a21f2ad3213cf367966f6c47a06ce7b5e Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Mon, 22 Jun 2015 12:29:40 +0300 Subject: [PATCH 003/113] Debugger: Remove false soft assertion on Windows Some libraries do not provide full names. For example: frame={level=\"1\",addr=\"0x2b669230\",func=\"*__GI_abort\",file=\"abort.c \",fullname=\"\",line=\"117\",from=\"D:/sysroot/octeon17/lib32/libc.so. 6\",language=\"c\"} Change-Id: Ibd273d451844d467395d8d7708b87f2cfc7a139e Reviewed-by: Christian Stenger Reviewed-by: hjk --- src/plugins/debugger/gdb/gdbengine.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 5d20589e022..0edf1070e31 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1811,7 +1811,8 @@ QString GdbEngine::cleanupFullName(const QString &fileName) // Gdb running on windows often delivers "fullnames" which // (a) have no drive letter and (b) are not normalized. if (Abi::hostAbi().os() == Abi::WindowsOS) { - QTC_ASSERT(!fileName.isEmpty(), return QString()); + if (fileName.isEmpty()) + return QString(); QFileInfo fi(fileName); if (fi.isReadable()) cleanFilePath = QDir::cleanPath(fi.absoluteFilePath()); From e232648d79081446bcdd128f17cc7918659c72e0 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 18 Jun 2015 18:17:27 +0200 Subject: [PATCH 004/113] OS X: Fix deployment of tools - clangbackend missed deployment - Fixed libclang location to be in Frameworks, and deploy missing dylib link - Fixed deployment of buildoutputparser Change-Id: I2b1fbd552bd0da6fef154fe1b6dac0a53b320483 Reviewed-by: Christian Stenger --- scripts/deployqtHelper_mac.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/deployqtHelper_mac.sh b/scripts/deployqtHelper_mac.sh index 638cc2f0069..120a4d030a9 100755 --- a/scripts/deployqtHelper_mac.sh +++ b/scripts/deployqtHelper_mac.sh @@ -57,7 +57,9 @@ fi if [ $LLVM_INSTALL_DIR ]; then if [ "$LLVM_INSTALL_DIR"/lib/libclang.dylib -nt "$1/Contents/PlugIns"/libclang.dylib ]; then echo "- Copying libclang" - cp -f "$LLVM_INSTALL_DIR"/lib/libclang.dylib "$1/Contents/PlugIns/" || exit 1 + mkdir -p "$1/Contents/Frameworks" || exit 1 + # use recursive copy to make it copy symlinks as symlinks + cp -Rf "$LLVM_INSTALL_DIR"/lib/libclang.*dylib "$1/Contents/Frameworks/" || exit 1 cp -Rf "$LLVM_INSTALL_DIR"/lib/clang "$1/Contents/Resources/cplusplus/" || exit 1 fi _CLANG_CODEMODEL_LIB="$1/Contents/PlugIns/libClangCodeModel_debug.dylib" @@ -66,7 +68,8 @@ if [ $LLVM_INSTALL_DIR ]; then fi # this will just fail when run a second time on libClangCodeModel xcrun install_name_tool -delete_rpath "$LLVM_INSTALL_DIR/lib" "$_CLANG_CODEMODEL_LIB" || true - xcrun install_name_tool -add_rpath "@loader_path/" "$_CLANG_CODEMODEL_LIB" || true + xcrun install_name_tool -add_rpath "@loader_path/../Frameworks" "$_CLANG_CODEMODEL_LIB" || true + clangbackendArgument="-executable=$1/Contents/Resources/clangbackend" fi #### macdeployqt @@ -93,7 +96,8 @@ if [ ! -d "$1/Contents/Frameworks/QtCore.framework" ]; then "-executable=$1/Contents/Resources/ios/iostool" \ "-executable=$1/Contents/Resources/ios/iossim" \ "-executable=$1/Contents/Resources/ios/iossim_1_8_2" \ - "-executable=$1/Contents/MacOS/buildoutputparser" \ + "-executable=$1/Contents/Resources/buildoutputparser" \ + "-executable=$1/Contents/Resources/cpaster" \ "-executable=$qbsapp" \ "-executable=$qbsapp-config" \ "-executable=$qbsapp-config-ui" \ @@ -101,6 +105,6 @@ if [ ! -d "$1/Contents/Frameworks/QtCore.framework" ]; then "-executable=$qbsapp-setup-android" \ "-executable=$qbsapp-setup-qt" \ "-executable=$qbsapp-setup-toolchains" \ - "$qmlpuppetArgument" "$qml2puppetArgument" || exit 1 + "$qmlpuppetArgument" "$qml2puppetArgument" "$clangbackendArgument" || exit 1 fi From 4e2905f880ae84a9a3e72c4c73e5317b87ff6c55 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 19 Jun 2015 14:23:07 +0200 Subject: [PATCH 005/113] Cpaster frontend: Fix deployment On OS X we may not set QMAKE_RPATH because otherwise the default rpath to the Qt libs is removed. Install the tool on Windows and Linux. Add the plugins path to the rpath on Linux. Also make the rpath when building relative instead of absolute on Linux. Change-Id: Ieb6a79d9f9f922d117736ae7b4ae65c784ade5c9 Reviewed-by: Kai Koehne Reviewed-by: Christian Stenger --- scripts/deployqt.py | 3 ++- src/plugins/cpaster/frontend/frontend.pro | 10 ++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/scripts/deployqt.py b/scripts/deployqt.py index 1932a28134a..da122efc34f 100755 --- a/scripts/deployqt.py +++ b/scripts/deployqt.py @@ -91,7 +91,8 @@ def fix_rpaths_helper(chrpath_bin, install_dir, dirpath, filenames): for filename in filenames: fpath = os.path.join(dirpath, filename) relpath = os.path.relpath(install_dir+'/lib/qtcreator', dirpath) - command = [chrpath_bin, '-r', '$ORIGIN/'+relpath, fpath] + relpluginpath = os.path.relpath(install_dir+'/lib/qtcreator/plugins', dirpath) + command = [chrpath_bin, '-r', '$ORIGIN/'+relpath+':$ORIGIN/'+relpluginpath, fpath] print fpath, ':', command try: subprocess.check_call(command) diff --git a/src/plugins/cpaster/frontend/frontend.pro b/src/plugins/cpaster/frontend/frontend.pro index ea810e3a607..4f0f39b45cc 100644 --- a/src/plugins/cpaster/frontend/frontend.pro +++ b/src/plugins/cpaster/frontend/frontend.pro @@ -1,4 +1,3 @@ -TEMPLATE = app TARGET=cpaster QTC_LIB_DEPENDS += \ @@ -7,16 +6,11 @@ QTC_LIB_DEPENDS += \ QTC_PLUGIN_DEPENDS += \ coreplugin -include(../../../../qtcreator.pri) -include(../../../rpath.pri) +include(../../../qtcreatortool.pri) -CONFIG += console -CONFIG -= app_bundle QT += network -QMAKE_RPATHDIR *= $$IDE_PLUGIN_PATH - -DESTDIR=$$IDE_LIBEXEC_PATH +linux-*: QMAKE_LFLAGS += -Wl,-z,origin \'-Wl,-rpath,\$\$ORIGIN/$$relative_path($$IDE_PLUGIN_PATH, $$DESTDIR)\' HEADERS = ../protocol.h \ ../cpasterconstants.h \ From e50aafafe3d643efecdbce3ca93dc59104d73650 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 19 Jun 2015 14:43:41 +0200 Subject: [PATCH 006/113] CppEditor: Fix semantic highlighting when zooming ...for the not visible documents. First reset the extra additional formats, then set the new ones, not the other way around. Task-number: QTCREATORBUG-14579 Change-Id: Iae465bd9a7bb0a397fd4917df45955713aaf87c5 Reviewed-by: Orgad Shaneh Reviewed-by: David Schulz --- .../clangcodemodel/clangeditordocumentprocessor.cpp | 6 ++++++ .../clangcodemodel/clangeditordocumentprocessor.h | 1 + src/plugins/cppeditor/cppeditordocument.cpp | 1 + src/plugins/cpptools/baseeditordocumentprocessor.h | 1 + .../cpptools/builtineditordocumentprocessor.cpp | 8 ++++++++ src/plugins/cpptools/builtineditordocumentprocessor.h | 1 + src/plugins/cpptools/semantichighlighter.cpp | 10 ---------- src/plugins/cpptools/semantichighlighter.h | 4 +--- 8 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 368236c7666..8480dfbace2 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -167,6 +167,12 @@ void ClangEditorDocumentProcessor::recalculateSemanticInfoDetached(bool force) m_builtinProcessor.recalculateSemanticInfoDetached(force); } +void ClangEditorDocumentProcessor::semanticRehighlight() +{ + m_semanticHighlighter.updateFormatMapFromFontSettings(); + m_semanticHighlighter.run(); +} + CppTools::SemanticInfo ClangEditorDocumentProcessor::recalculateSemanticInfo() { return m_builtinProcessor.recalculateSemanticInfo(); diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index 508c235d1fe..d62ff455d12 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -56,6 +56,7 @@ public: // BaseEditorDocumentProcessor interface void run() override; + void semanticRehighlight() override; void recalculateSemanticInfoDetached(bool force) override; CppTools::SemanticInfo recalculateSemanticInfo() override; CppTools::BaseEditorDocumentParser *parser() override; diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp index dec8995138a..3d33e1f3f9c 100644 --- a/src/plugins/cppeditor/cppeditordocument.cpp +++ b/src/plugins/cppeditor/cppeditordocument.cpp @@ -169,6 +169,7 @@ void CppEditorDocument::applyFontSettings() } } TextDocument::applyFontSettings(); // rehighlights and updates additional formats + m_processor->semanticRehighlight(); } void CppEditorDocument::invalidateFormatterCache() diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.h b/src/plugins/cpptools/baseeditordocumentprocessor.h index 908cd9782a8..8054d866e58 100644 --- a/src/plugins/cpptools/baseeditordocumentprocessor.h +++ b/src/plugins/cpptools/baseeditordocumentprocessor.h @@ -60,6 +60,7 @@ public: // Function interface to implement virtual void run() = 0; + virtual void semanticRehighlight() = 0; virtual void recalculateSemanticInfoDetached(bool force) = 0; virtual CppTools::SemanticInfo recalculateSemanticInfo() = 0; virtual CPlusPlus::Snapshot snapshot() = 0; diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.cpp b/src/plugins/cpptools/builtineditordocumentprocessor.cpp index af0efebc8f7..12bfe1531c3 100644 --- a/src/plugins/cpptools/builtineditordocumentprocessor.cpp +++ b/src/plugins/cpptools/builtineditordocumentprocessor.cpp @@ -182,6 +182,14 @@ void BuiltinEditorDocumentProcessor::recalculateSemanticInfoDetached(bool force) m_semanticInfoUpdater.updateDetached(source); } +void BuiltinEditorDocumentProcessor::semanticRehighlight() +{ + if (m_semanticHighlighter && m_semanticInfoUpdater.semanticInfo().doc) { + m_semanticHighlighter->updateFormatMapFromFontSettings(); + m_semanticHighlighter->run(); + } +} + SemanticInfo BuiltinEditorDocumentProcessor::recalculateSemanticInfo() { const auto source = createSemanticInfoSource(false); diff --git a/src/plugins/cpptools/builtineditordocumentprocessor.h b/src/plugins/cpptools/builtineditordocumentprocessor.h index 9e18020975d..396ba1bf1a7 100644 --- a/src/plugins/cpptools/builtineditordocumentprocessor.h +++ b/src/plugins/cpptools/builtineditordocumentprocessor.h @@ -52,6 +52,7 @@ public: // BaseEditorDocumentProcessor interface void run() override; void recalculateSemanticInfoDetached(bool force) override; + void semanticRehighlight() override; CppTools::SemanticInfo recalculateSemanticInfo() override; BaseEditorDocumentParser *parser() override; CPlusPlus::Snapshot snapshot() override; diff --git a/src/plugins/cpptools/semantichighlighter.cpp b/src/plugins/cpptools/semantichighlighter.cpp index 13199596293..c7e93f944ef 100644 --- a/src/plugins/cpptools/semantichighlighter.cpp +++ b/src/plugins/cpptools/semantichighlighter.cpp @@ -54,10 +54,6 @@ SemanticHighlighter::SemanticHighlighter(TextEditor::TextDocument *baseTextDocum , m_revision(0) { QTC_CHECK(m_baseTextDocument); - - connect(baseTextDocument, &TextEditor::TextDocument::fontSettingsChanged, - this, &SemanticHighlighter::onDocumentFontSettingsChanged); - updateFormatMapFromFontSettings(); } @@ -92,12 +88,6 @@ void SemanticHighlighter::run() m_watcher->setFuture(m_highlightingRunner()); } -void SemanticHighlighter::onDocumentFontSettingsChanged() -{ - updateFormatMapFromFontSettings(); - run(); -} - void SemanticHighlighter::onHighlighterResultAvailable(int from, int to) { if (documentRevision() != m_revision) diff --git a/src/plugins/cpptools/semantichighlighter.h b/src/plugins/cpptools/semantichighlighter.h index 6cc81b9ba0c..d00db6e9dad 100644 --- a/src/plugins/cpptools/semantichighlighter.h +++ b/src/plugins/cpptools/semantichighlighter.h @@ -73,12 +73,11 @@ public: ~SemanticHighlighter(); void setHighlightingRunner(HighlightingRunner highlightingRunner); + void updateFormatMapFromFontSettings(); void run(); private slots: - void onDocumentFontSettingsChanged(); - void onHighlighterResultAvailable(int from, int to); void onHighlighterFinished(); @@ -87,7 +86,6 @@ private: void disconnectWatcher(); unsigned documentRevision() const; - void updateFormatMapFromFontSettings(); private: TextEditor::TextDocument *m_baseTextDocument; From c990c3c37f368c075f092086388159e42f3a3783 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Thu, 18 Jun 2015 10:40:12 +0200 Subject: [PATCH 007/113] Doc: Reformatting No text change Change-Id: I95233f9fbb832e356781c2bbfe6350c7f95dd6b0 Reviewed-by: Leena Miettinen --- doc/src/editors/creator-coding-edit-mode.qdoc | 121 +++++++++--------- 1 file changed, 62 insertions(+), 59 deletions(-) diff --git a/doc/src/editors/creator-coding-edit-mode.qdoc b/doc/src/editors/creator-coding-edit-mode.qdoc index 9e02fd6a4fd..6793f96cfd5 100644 --- a/doc/src/editors/creator-coding-edit-mode.qdoc +++ b/doc/src/editors/creator-coding-edit-mode.qdoc @@ -30,8 +30,8 @@ \title Working in Edit Mode - This section describes how to use the \uicontrol Edit mode. For more information - about using the sidebar, see \l{Browsing Project Contents}. + This section describes how to use the \uicontrol Edit mode. For more + information about using the sidebar, see \l{Browsing Project Contents}. \section1 Using the Editor Toolbar @@ -41,30 +41,30 @@ \image qtcreator-editortoolbar-symbols.png - Use the toolbar to navigate between open files and symbols in use. - To browse backward or forward through your location history, click + Use the toolbar to navigate between open files and symbols in use. To browse + backward or forward through your location history, click \inlineimage qtcreator-back.png (\uicontrol {Go Back}) and \inlineimage qtcreator-forward.png (\uicontrol {Go Forward}). - To go to any open file, select it from the \uicontrol{Open files} drop-down menu (1). - Right-click the menu title and select \uicontrol {Copy Full Path} to - copy the path and name of the current file to the clipboard. + To go to any open file, select it from the \uicontrol {Open files} drop-down + menu (1). Right-click the menu title and select \uicontrol {Copy Full Path} + to copy the path and name of the current file to the clipboard. To jump to any symbol used in the current file, select it from the - \uicontrol Symbols drop-down menu (2). By default, the symbols are displayed in the - order in which they appear in the file. Right-click the menu title and - select \uicontrol {Sort Alphabetically} to arrange the symbols in alphabetic - order. + \uicontrol Symbols drop-down menu (2). By default, the symbols are displayed + in the order in which they appear in the file. Right-click the menu title + and select \uicontrol {Sort Alphabetically} to arrange the symbols in + alphabetic order. To jump to a line and column in the current file, select the line and column - indicator (3) or press \key {Ctrl+L} (or \key {Cmd+L} on OS X) to open - the locator. Enter the line number and column number in the locator, - separated by a colon (:). + indicator (3) or press \key {Ctrl+L} (or \key {Cmd+L} on OS X) to open the + locator. Enter the line number and column number in the locator, separated + by a colon (:). To show the file encoding of the current file on the editor toolbar (4), - select \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Display > - \uicontrol {Display file encoding}. + select \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > + \uicontrol Display > \uicontrol {Display file encoding}. \note Other convenient ways of navigating in \QC are provided by the \l{Searching with the Locator}{locator}, \l{Keyboard Shortcuts} @@ -82,15 +82,16 @@ \list \li To split the editor view into a top and bottom view, select - \uicontrol Window > \uicontrol Split, press \key{Ctrl+E, 2}, or select the - \inlineimage qtcreator-split-button.png + \uicontrol Window > \uicontrol Split, press \key {Ctrl+E, 2}, or + select the \inlineimage qtcreator-split-button.png (\uicontrol Split) button and then select \uicontrol Split. Split command creates views below the currently active editor view. \li To split the editor view into adjacent views, select - \uicontrol Window > \uicontrol{Split Side by Side}, press \key{Ctrl+E, 3}, or - select \uicontrol {Split > Split Side by Side}. + \uicontrol Window > \uicontrol {Split Side by Side}, press + \key {Ctrl+E, 3}, or select \uicontrol Split > + \uicontrol {Split Side by Side}. Side by side split command creates views to the right of the currently active editor view. @@ -104,16 +105,17 @@ \endlist - To move between split views and detached editor windows, select \uicontrol Window - > \uicontrol{Go to Next Split or Window} or press \key{Ctrl+E, O}. + To move between split views and detached editor windows, select + \uicontrol Window > \uicontrol {Go to Next Split or Window} or press + \key {Ctrl+E, O}. To remove a split view, place the cursor within the view you want to - remove and select \uicontrol Window > \uicontrol{Remove Current Split}, press - \key{Ctrl+E, 0}, or select the + remove and select \uicontrol Window > \uicontrol {Remove Current Split}, + press \key {Ctrl+E, 0}, or select the \inlineimage qtcreator-remove-split-button.png - (\uicontrol {Remove Split}) button. To remove all but the currently selected split - view, - select \uicontrol Window > \uicontrol{Remove All Splits} or press \key{Ctrl+E, 1}. + (\uicontrol {Remove Split}) button. To remove all but the currently selected + split view, select \uicontrol Window > \uicontrol {Remove All Splits} or + press \key {Ctrl+E, 1}. \section1 Using Bookmarks @@ -132,8 +134,8 @@ \image qtcreator-togglebookmark.png To add a note to a bookmark, right-click the bookmark and select - \uicontrol{Edit Bookmark}. To view the note, move the mouse pointer over the - bookmark. + \uicontrol {Edit Bookmark}. To view the note, move the mouse pointer over + the bookmark. To go to previous bookmark in the current session, press \key {Ctrl+,}. @@ -142,40 +144,42 @@ \section1 Moving to Symbol Definition or Declaration You can move directly to the definition or the declaration of a symbol by - holding the \key Ctrl key and clicking the symbol. If you have multiple splits - opened, you can open the link in the next split by holding \key Ctrl and - \key Alt while clicking the symbol. + holding the \key Ctrl key and clicking the symbol. If you have multiple + splits opened, you can open the link in the next split by holding \key Ctrl + and \key Alt while clicking the symbol. - To enable this moving function, select \uicontrol Tools > \uicontrol{Options} > - \uicontrol{Text Editor} > \uicontrol Behavior > \uicontrol{Enable mouse navigation}. + To enable this moving function, select \uicontrol Tools > + \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Behavior > + \uicontrol {Enable mouse navigation}. You can also select the symbol and press \key F2, or right-click the symbol - and select \uicontrol {Follow Symbol Under Cursor} to move to its definition or - declaration. This feature is supported for namespaces, classes, functions, - variables, include statements, and macros. + and select \uicontrol {Follow Symbol Under Cursor} to move to its definition + or declaration. This feature is supported for namespaces, classes, + functions, variables, include statements, and macros. To switch between the definition and declaration of a function, place the - cursor on either and press \key {Shift+F2} or right-click and select \uicontrol - {Switch Between Function Declaration/Definition}. For example, this allows - you to navigate from anywhere within a function body directly to the function - declaration. + cursor on either and press \key {Shift+F2} or right-click and select + \uicontrol {Switch Between Function Declaration/Definition}. For example, + this allows you to navigate from anywhere within a function body directly to + the function declaration. Links are opened in the same split by default. To open links in the next - split, prepend \key {Ctrl+E} to the shortcut. For example, press \key {Ctrl+E,F2} - to follow the symbol in the next split. If necessary, the view is - automatically split. To change the default behavior, select \uicontrol Tools > - \uicontrol{Options} > \uicontrol{Text Editor} > \uicontrol Display, and then select - \uicontrol{Always Open Links in Next Split}. Additional symbols are displayed and - switching between definition and declaration is done in another split. - If you change the default behavior, the shortcuts for opening link targets - in the next split are used to open them in the current split. + split, prepend \key {Ctrl+E} to the shortcut. For example, press + \key {Ctrl+E,F2} to follow the symbol in the next split. If necessary, the + view is automatically split. To change the default behavior, select + \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > + \uicontrol Display, and then select + \uicontrol {Always Open Links in Next Split}. Additional symbols are + displayed and switching between definition and declaration is done in + another split. If you change the default behavior, the shortcuts for opening + link targets in the next split are used to open them in the current split. \section1 Reparsing Externally Changed Files If source files are modified from outside \QC, the opened files will be - reparsed automatically. For all other files, you can use \uicontrol{Tools} > - \uicontrol{C++} > \uicontrol{Reparse Externally Changed Files} to update the code - model. + reparsed automatically. For all other files, you can use \uicontrol Tools > + \uicontrol {C++} > \uicontrol {Reparse Externally Changed Files} to update + the code model. \section1 Inspecting the Code Model @@ -185,14 +189,13 @@ inspection. To view information about the C++ code model in the - \uicontrol {C++ Code Model Inspector} dialog and write it to a log file, select - \uicontrol Tools > \uicontrol C++ > \uicontrol {Inspect C++ Code Model} or press - \key {Ctrl+Shift+F12}. + \uicontrol {C++ Code Model Inspector} dialog and write it to a log file, + select \uicontrol Tools > \uicontrol {C++} > + \uicontrol {Inspect C++ Code Model} or press \key {Ctrl+Shift+F12}. \QC generates the code model inspection log file in a temporary folder. - \QC underlines semantic errors in olive in the C++ code editor. To - check the correct paths for includes that are not resolved or that are - resolved to the wrong file, select \uicontrol {Project Parts} > - \uicontrol {Include Paths}. + \QC underlines semantic errors in olive in the C++ code editor. To check the + correct paths for includes that are not resolved or that are resolved to the + wrong file, select \uicontrol {Project Parts} > \uicontrol {Include Paths}. */ From 582661a5bd1f2f0eeab90fa043ec866b68fbf020 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 19 Jun 2015 14:37:17 +0200 Subject: [PATCH 008/113] TaskManager: Remove the explicit use of Core::Id::toUniqueIdentifier() Directly comparing the Ids gives the same effect of a stable (but unpredictable) sort. Change-Id: Iaf54a127b02f2a89eeff9b6d008575bb899ef926 Reviewed-by: Daniel Teske --- src/plugins/projectexplorer/task.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/projectexplorer/task.cpp b/src/plugins/projectexplorer/task.cpp index eabf8063e18..2f83d14e512 100644 --- a/src/plugins/projectexplorer/task.cpp +++ b/src/plugins/projectexplorer/task.cpp @@ -137,9 +137,9 @@ bool operator<(const Task &a, const Task &b) // Can't happen return true; } else { - if (a.category.uniqueIdentifier() < b.category.uniqueIdentifier()) + if (a.category < b.category) return true; - if (b.category.uniqueIdentifier() < a.category.uniqueIdentifier()) + if (b.category < a.category) return false; return a.taskId < b.taskId; } From e0c5ff03ec3c23691d88318f75b9c993ca594054 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 22 Jun 2015 17:38:34 +0200 Subject: [PATCH 009/113] Vcs: Do not crash when stopping running commands Drop the connect once the editor gets killed. Remove the QSignalMapper and replace it with a lambda to facilitate that change. Task-number: QTCREATORBUG-14613 Change-Id: I1a5990bf37af88092933143ebb78dd5ceb9c1222 Reviewed-by: Orgad Shaneh --- src/plugins/git/gitclient.cpp | 2 +- src/plugins/vcsbase/vcsbaseclient.cpp | 62 ++++++++++----------------- src/plugins/vcsbase/vcsbaseclient.h | 3 +- 3 files changed, 24 insertions(+), 43 deletions(-) diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 762e056f7f6..dab7251a34e 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -596,7 +596,7 @@ static inline void msgCannotRun(const QStringList &args, const QString &workingD const char *GitClient::stashNamePrefix = "stash@{"; -GitClient::GitClient() : VcsBase::VcsBaseClientImpl(this, new GitSettings), +GitClient::GitClient() : VcsBase::VcsBaseClientImpl(new GitSettings), m_cachedGitVersion(0), m_disableEditor(false) { diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp index 36df6fb2f00..750e7f96c32 100644 --- a/src/plugins/vcsbase/vcsbaseclient.cpp +++ b/src/plugins/vcsbase/vcsbaseclient.cpp @@ -56,6 +56,17 @@ #include #include +static void commandFinished(VcsBase::VcsBaseEditorWidget *editor, VcsBase::VcsCommand *cmd) +{ + if (!cmd->lastExecutionSuccess()) { + editor->reportCommandFinished(false, cmd->lastExecutionExitCode(), cmd->cookie()); + } else if (cmd->cookie().type() == QVariant::Int) { + const int line = cmd->cookie().toInt(); + if (line >= 0) + editor->gotoLine(line); + } +} + /*! \class VcsBase::VcsBaseClient @@ -80,27 +91,14 @@ namespace VcsBase { class VcsBaseClientImplPrivate { public: - VcsBaseClientImplPrivate(VcsBaseClientImpl *client, VcsBaseClientSettings *settings); + VcsBaseClientImplPrivate(VcsBaseClientSettings *settings); ~VcsBaseClientImplPrivate(); - void bindCommandToEditor(VcsCommand *cmd, VcsBaseEditorWidget *editor); - VcsBaseClientSettings *m_clientSettings; - QSignalMapper *m_cmdFinishedMapper; }; -void VcsBaseClientImplPrivate::bindCommandToEditor(VcsCommand *cmd, VcsBaseEditorWidget *editor) -{ - editor->setCommand(cmd); - QObject::connect(cmd, &VcsCommand::finished, - m_cmdFinishedMapper, static_cast(&QSignalMapper::map)); - m_cmdFinishedMapper->setMapping(cmd, editor); -} - -VcsBaseClientImplPrivate::VcsBaseClientImplPrivate(VcsBaseClientImpl *client, - VcsBaseClientSettings *settings) : - m_clientSettings(settings), - m_cmdFinishedMapper(new QSignalMapper(client)) +VcsBaseClientImplPrivate::VcsBaseClientImplPrivate(VcsBaseClientSettings *settings) : + m_clientSettings(settings) { m_clientSettings->readSettings(Core::ICore::settings()); } @@ -110,14 +108,11 @@ VcsBaseClientImplPrivate::~VcsBaseClientImplPrivate() delete m_clientSettings; } -VcsBaseClientImpl::VcsBaseClientImpl(VcsBaseClientImpl *client, VcsBaseClientSettings *settings) : - d(new VcsBaseClientImplPrivate(client, settings)) +VcsBaseClientImpl::VcsBaseClientImpl(VcsBaseClientSettings *settings) : + d(new VcsBaseClientImplPrivate(settings)) { connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested, this, &VcsBaseClientImpl::saveSettings); - - connect(d->m_cmdFinishedMapper, static_cast(&QSignalMapper::mapped), - this, &VcsBaseClientImpl::commandFinishedGotoLine); } VcsBaseClientImpl::~VcsBaseClientImpl() @@ -141,8 +136,11 @@ VcsCommand *VcsBaseClientImpl::createCommand(const QString &workingDirectory, { auto cmd = new VcsCommand(workingDirectory, processEnvironment()); cmd->setDefaultTimeoutS(vcsTimeoutS()); - if (editor) - d->bindCommandToEditor(cmd, editor); + if (editor) { + connect(editor, &QObject::destroyed, cmd, &VcsCommand::abort); + connect(cmd, &VcsCommand::finished, + editor, [editor, cmd]() { commandFinished(editor, cmd); }); + } if (mode == VcsWindowOutputBind) { cmd->addFlags(VcsCommand::ShowStdOut); if (editor) // assume that the commands output is the important thing @@ -278,22 +276,6 @@ void VcsBaseClientImpl::saveSettings() settings().writeSettings(Core::ICore::settings()); } -void VcsBaseClientImpl::commandFinishedGotoLine(QWidget *editorObject) -{ - VcsBaseEditorWidget *editor = qobject_cast(editorObject); - VcsCommand *cmd = qobject_cast(d->m_cmdFinishedMapper->mapping(editor)); - if (editor && cmd) { - if (!cmd->lastExecutionSuccess()) { - editor->reportCommandFinished(false, cmd->lastExecutionExitCode(), cmd->cookie()); - } else if (cmd->cookie().type() == QVariant::Int) { - const int line = cmd->cookie().toInt(); - if (line >= 0) - editor->gotoLine(line); - } - d->m_cmdFinishedMapper->removeMappings(cmd); - } -} - class VcsBaseClientPrivate { public: @@ -319,7 +301,7 @@ VcsBaseClient::StatusItem::StatusItem(const QString &s, const QString &f) : { } VcsBaseClient::VcsBaseClient(VcsBaseClientSettings *settings) : - VcsBaseClientImpl(this, settings), + VcsBaseClientImpl(settings), d(new VcsBaseClientPrivate) { qRegisterMetaType(); diff --git a/src/plugins/vcsbase/vcsbaseclient.h b/src/plugins/vcsbase/vcsbaseclient.h index 50827a1384b..03a87ea4587 100644 --- a/src/plugins/vcsbase/vcsbaseclient.h +++ b/src/plugins/vcsbase/vcsbaseclient.h @@ -68,7 +68,7 @@ class VCSBASE_EXPORT VcsBaseClientImpl : public QObject Q_OBJECT public: - explicit VcsBaseClientImpl(VcsBaseClientImpl *client, VcsBaseClientSettings *settings); + explicit VcsBaseClientImpl(VcsBaseClientSettings *settings); ~VcsBaseClientImpl(); VcsBaseClientSettings &settings() const; @@ -130,7 +130,6 @@ protected: private: void saveSettings(); - void commandFinishedGotoLine(QWidget*); VcsBaseClientImplPrivate *d; }; From 6f29d0c53d9e0d1cfe6eac4e651b98014f96914a Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 22 Jun 2015 17:10:45 +0200 Subject: [PATCH 010/113] Fix crash in Form class wizard Run parents initializePage, not the one from our grandparent. Task-number: QTCREATORBUG-14620 Change-Id: I1ec2d424c0e6fd6d7dea1050d5d8f6b8f00d27d5 Reviewed-by: Tobias Hunger --- src/plugins/designer/cpp/formclasswizarddialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/designer/cpp/formclasswizarddialog.cpp b/src/plugins/designer/cpp/formclasswizarddialog.cpp index afd5a3ebc50..9f8924b872c 100644 --- a/src/plugins/designer/cpp/formclasswizarddialog.cpp +++ b/src/plugins/designer/cpp/formclasswizarddialog.cpp @@ -72,7 +72,7 @@ bool FormClassWizardDialog::validateCurrentPage() void FormClassWizardDialog::initializePage(int id) { - QWizard::initializePage(id); + Core::BaseFileWizard::initializePage(id); // Switching from form to class page: store XML template and set a suitable // class name in the class page based on the form base class if (id == ClassPageId) { From 048fbbe5ddead44dc073b9a62cc53e2d977edc40 Mon Sep 17 00:00:00 2001 From: Montel Laurent Date: Tue, 23 Jun 2015 11:23:11 +0200 Subject: [PATCH 011/113] Fix switch session. When we use action->text() in some theme we have a "&" for activating it with keyboard. So session can't work when we search session name. Change-Id: I3511a740121b5eefb790faa6bf5f92b8f5c8d429 Reviewed-by: Daniel Teske --- src/plugins/projectexplorer/projectexplorer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 7f297bbc653..ded797906da 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -3216,6 +3216,7 @@ void ProjectExplorerPluginPrivate::updateSessionMenu() const QString activeSession = SessionManager::activeSession(); foreach (const QString &session, SessionManager::sessions()) { QAction *act = ag->addAction(session); + act->setData(session); act->setCheckable(true); if (session == activeSession) act->setChecked(true); @@ -3226,7 +3227,7 @@ void ProjectExplorerPluginPrivate::updateSessionMenu() void ProjectExplorerPluginPrivate::setSession(QAction *action) { - QString session = action->text(); + QString session = action->data().toString(); if (session != SessionManager::activeSession()) SessionManager::loadSession(session); } From 12461c4110cb47732b4a40dcb92d36fa8ed16ea2 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 23 Jun 2015 11:25:36 +0200 Subject: [PATCH 012/113] ModeManager: Remove one use of Id::fromUniqueIdentifier and Co. Change-Id: I9013d5de89e40fc60a5f021088fb7213eea3dc03 Reviewed-by: Eike Ziller --- src/plugins/coreplugin/modemanager.cpp | 21 +++++++-------------- src/plugins/coreplugin/modemanager.h | 1 - 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/plugins/coreplugin/modemanager.cpp b/src/plugins/coreplugin/modemanager.cpp index a4565c34138..a9b7e59d8fd 100644 --- a/src/plugins/coreplugin/modemanager.cpp +++ b/src/plugins/coreplugin/modemanager.cpp @@ -44,13 +44,11 @@ #include +#include #include #include #include -#include -#include - namespace Core { /*! @@ -70,7 +68,6 @@ struct ModeManagerPrivate QMap m_actions; QVector m_modes; QVector m_modeCommands; - QSignalMapper *m_signalMapper; Context m_addedContexts; int m_oldCurrent; bool m_modeSelectorVisible; @@ -96,7 +93,6 @@ ModeManager::ModeManager(Internal::MainWindow *mainWindow, d = new ModeManagerPrivate(); d->m_mainWindow = mainWindow; d->m_modeStack = modeStack; - d->m_signalMapper = new QSignalMapper(this); d->m_oldCurrent = -1; d->m_actionBar = new Internal::FancyActionBar(modeStack); d->m_modeStack->addCornerWidget(d->m_actionBar); @@ -105,7 +101,6 @@ ModeManager::ModeManager(Internal::MainWindow *mainWindow, connect(d->m_modeStack, SIGNAL(currentAboutToShow(int)), SLOT(currentTabAboutToChange(int))); connect(d->m_modeStack, SIGNAL(currentChanged(int)), SLOT(currentTabChanged(int))); - connect(d->m_signalMapper, SIGNAL(mapped(int)), this, SLOT(slotActivateMode(int))); } void ModeManager::init() @@ -139,12 +134,6 @@ IMode *ModeManager::mode(Id id) return 0; } -void ModeManager::slotActivateMode(int id) -{ - m_instance->activateMode(Id::fromUniqueIdentifier(id)); - ICore::raiseWindow(d->m_modeStack); -} - void ModeManager::activateMode(Id id) { const int index = indexOf(id); @@ -190,8 +179,12 @@ void ModeManager::objectAdded(QObject *obj) currentCmd->setKeySequence(currentCmd->defaultKeySequence()); } - d->m_signalMapper->setMapping(action, mode->id().uniqueIdentifier()); - connect(action, SIGNAL(triggered()), d->m_signalMapper, SLOT(map())); + Id id = mode->id(); + connect(action, &QAction::triggered, [id] { + m_instance->activateMode(id); + ICore::raiseWindow(d->m_modeStack); + }); + connect(mode, SIGNAL(enabledStateChanged(bool)), m_instance, SLOT(enabledStateChanged())); } diff --git a/src/plugins/coreplugin/modemanager.h b/src/plugins/coreplugin/modemanager.h index 77d2e31f6c6..4b34fab385b 100644 --- a/src/plugins/coreplugin/modemanager.h +++ b/src/plugins/coreplugin/modemanager.h @@ -75,7 +75,6 @@ signals: void currentModeChanged(Core::IMode *mode, Core::IMode *oldMode = 0); private slots: - void slotActivateMode(int id); void objectAdded(QObject *obj); void aboutToRemoveObject(QObject *obj); void currentTabAboutToChange(int index); From 9553309a7faab0ef3673ba85f24883ceb3f2ad82 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 23 Jun 2015 11:44:12 +0200 Subject: [PATCH 013/113] Device support: Remove one use of Id::fromUniqueIdentifier and Co. Change-Id: I4771079ff5c78c12780308fd32923fd3fad137cc Reviewed-by: Christian Kandeler --- .../devicesupport/devicesettingswidget.cpp | 12 ++++-------- .../devicesupport/devicesettingswidget.h | 4 +--- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp index 3e125ecacb6..ec31a2dab8d 100644 --- a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.cpp @@ -47,7 +47,6 @@ #include #include -#include #include #include @@ -95,12 +94,9 @@ DeviceSettingsWidget::DeviceSettingsWidget(QWidget *parent) m_deviceManager(DeviceManager::cloneInstance()), m_deviceManagerModel(new DeviceManagerModel(m_deviceManager, this)), m_nameValidator(new NameValidator(m_deviceManager, this)), - m_additionalActionsMapper(new QSignalMapper(this)), m_configWidget(0) { initGui(); - connect(m_additionalActionsMapper, SIGNAL(mapped(int)), - SLOT(handleAdditionalActionRequest(int))); connect(m_deviceManager, SIGNAL(deviceUpdated(Core::Id)), SLOT(handleDeviceUpdated(Core::Id))); } @@ -302,8 +298,8 @@ void DeviceSettingsWidget::currentDeviceChanged(int index) foreach (Id actionId, device->actionIds()) { QPushButton * const button = new QPushButton(device->displayNameForActionId(actionId)); m_additionalActionButtons << button; - connect(button, SIGNAL(clicked()), m_additionalActionsMapper, SLOT(map())); - m_additionalActionsMapper->setMapping(button, actionId.uniqueIdentifier()); + connect(button, &QAbstractButton::clicked, this, + [this, actionId] { handleAdditionalActionRequest(actionId); }); m_ui->buttonsLayout->insertWidget(m_ui->buttonsLayout->count() - 1, button); } @@ -322,12 +318,12 @@ void DeviceSettingsWidget::clearDetails() m_ui->autoDetectionValueLabel->clear(); } -void DeviceSettingsWidget::handleAdditionalActionRequest(int actionId) +void DeviceSettingsWidget::handleAdditionalActionRequest(Id actionId) { const IDevice::Ptr device = m_deviceManager->mutableDevice(currentDevice()->id()); QTC_ASSERT(device, return); updateDeviceFromUi(); - device->executeAction(Id::fromUniqueIdentifier(actionId), this); + device->executeAction(actionId, this); // Widget must be set up from scratch, because the action could have changed random attributes. currentDeviceChanged(currentIndex()); diff --git a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.h b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.h index 564457a71ae..9a21dea44af 100644 --- a/src/plugins/projectexplorer/devicesupport/devicesettingswidget.h +++ b/src/plugins/projectexplorer/devicesupport/devicesettingswidget.h @@ -38,7 +38,6 @@ #include QT_BEGIN_NAMESPACE -class QSignalMapper; class QPushButton; QT_END_NAMESPACE @@ -69,11 +68,11 @@ private slots: void deviceNameEditingFinished(); void setDefaultDevice(); void testDevice(); - void handleAdditionalActionRequest(int actionId); void handleProcessListRequested(); private: void initGui(); + void handleAdditionalActionRequest(Core::Id actionId); void displayCurrent(); void setDeviceInfoWidgetsEnabled(bool enable); IDevice::ConstPtr currentDevice() const; @@ -88,7 +87,6 @@ private: DeviceManagerModel * const m_deviceManagerModel; NameValidator * const m_nameValidator; QList m_additionalActionButtons; - QSignalMapper * const m_additionalActionsMapper; IDeviceWidget *m_configWidget; }; From 8c583cb382951e8c3f7fea3e7117ade538424398 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 16 Jun 2015 15:07:08 +0200 Subject: [PATCH 014/113] TreeModel: Add a few more soft asserts This establishes an additional invariant, namely that items that are not part of a model have m_model == 0, even if their destruction is imminent. Change-Id: I0bad7fff57d21ddcefe06953cd0da8c2897baa4a Reviewed-by: Christian Stenger Reviewed-by: Eike Ziller --- src/libs/utils/treemodel.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/libs/utils/treemodel.cpp b/src/libs/utils/treemodel.cpp index 6159fcfd4e4..424bc49a246 100644 --- a/src/libs/utils/treemodel.cpp +++ b/src/libs/utils/treemodel.cpp @@ -622,6 +622,8 @@ TreeItem::TreeItem(const QStringList &displays, int flags) TreeItem::~TreeItem() { + QTC_CHECK(m_parent == 0); + QTC_CHECK(m_model == 0); removeChildren(); delete m_displays; } @@ -851,6 +853,10 @@ TreeModel::TreeModel(TreeItem *root, QObject *parent) TreeModel::~TreeModel() { + QTC_ASSERT(m_root, return); + QTC_ASSERT(m_root->m_parent == 0, return); + QTC_ASSERT(m_root->m_model == this, return); + m_root->m_model = 0; delete m_root; } @@ -966,7 +972,13 @@ int TreeModel::topLevelItemCount() const void TreeModel::setRootItem(TreeItem *item) { - delete m_root; + QTC_CHECK(m_root); + if (m_root) { + QTC_CHECK(m_root->m_parent == 0); + QTC_CHECK(m_root->m_model == this); + m_root->m_model = 0; + delete m_root; + } m_root = item; item->setModel(this); emit layoutChanged(); @@ -1049,6 +1061,7 @@ TreeItem *TreeModel::takeItem(TreeItem *item) QModelIndex idx = indexForItem(parent); beginRemoveRows(idx, pos, pos); item->m_parent = 0; + item->m_model = 0; parent->m_children.removeAt(pos); endRemoveRows(); return item; From b646c37f0ed3af9b6297a684e8a5406d28063a63 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 23 Jun 2015 13:25:38 +0200 Subject: [PATCH 015/113] Device support: Replace use of Id::toUniqueIdentifier. Was paired with QVariant::value which relied on the unique dentifier being exactly the internal representation of the Id. Change-Id: Ib660b4b640bcef2803e2e050045d2189d6352d40 Reviewed-by: Tobias Hunger --- .../devicesupport/devicefactoryselectiondialog.cpp | 2 +- .../projectexplorer/devicesupport/devicemanagermodel.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/projectexplorer/devicesupport/devicefactoryselectiondialog.cpp b/src/plugins/projectexplorer/devicesupport/devicefactoryselectiondialog.cpp index ef655f5cbcc..8b29c56dd35 100644 --- a/src/plugins/projectexplorer/devicesupport/devicefactoryselectiondialog.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicefactoryselectiondialog.cpp @@ -87,7 +87,7 @@ Core::Id DeviceFactorySelectionDialog::selectedId() const QList selected = ui->listWidget->selectedItems(); if (selected.isEmpty()) return Core::Id(); - return selected.at(0)->data(Qt::UserRole).value(); + return Core::Id::fromSetting(selected.at(0)->data(Qt::UserRole)); } } // namespace Internal diff --git a/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp b/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp index 5a7f282bd2a..c371a437a8a 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp @@ -169,7 +169,7 @@ QVariant DeviceManagerModel::data(const QModelIndex &index, int role) const return QVariant(); const IDevice::ConstPtr dev = device(index.row()); if (role == Qt::UserRole) - return dev->id().uniqueIdentifier(); + return dev->id().toSetting(); QString name; if (d->deviceManager->defaultDevice(dev->type()) == dev) name = tr("%1 (default for %2)").arg(dev->displayName(), dev->displayType()); From 1c119185d068018b3d383f4f00f693299ba6313e Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 23 Jun 2015 13:15:17 +0200 Subject: [PATCH 016/113] Tasks: Remove other uses of Id::uniqueIdentifier() Ids can be compared and tested for default-constructedness without. Change-Id: I410c8a3922faa32fa27a090ea8fba7562a9a0231 Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/taskmodel.cpp | 8 ++++---- src/plugins/projectexplorer/taskwindow.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/projectexplorer/taskmodel.cpp b/src/plugins/projectexplorer/taskmodel.cpp index d3605c03471..bcfbcf802ac 100644 --- a/src/plugins/projectexplorer/taskmodel.cpp +++ b/src/plugins/projectexplorer/taskmodel.cpp @@ -85,7 +85,7 @@ bool TaskModel::hasFile(const QModelIndex &index) const void TaskModel::addCategory(Core::Id categoryId, const QString &categoryName) { - QTC_ASSERT(categoryId.uniqueIdentifier(), return); + QTC_ASSERT(categoryId.isValid(), return); CategoryData data; data.displayName = categoryName; m_categories.insert(categoryId, data); @@ -93,12 +93,12 @@ void TaskModel::addCategory(Core::Id categoryId, const QString &categoryName) QList TaskModel::tasks(Core::Id categoryId) const { - if (categoryId.uniqueIdentifier() == 0) + if (!categoryId.isValid()) return m_tasks; QList taskList; foreach (const Task &t, m_tasks) { - if (t.category.uniqueIdentifier() == categoryId.uniqueIdentifier()) + if (t.category == categoryId) taskList.append(t); } return taskList; @@ -170,7 +170,7 @@ void TaskModel::clearTasks(Core::Id categoryId) { typedef QHash::ConstIterator IdCategoryConstIt; - if (categoryId.uniqueIdentifier() == 0) { + if (!categoryId.isValid()) { if (m_tasks.count() == 0) return; beginRemoveRows(QModelIndex(), 0, m_tasks.count() -1); diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index a7e34151254..d069a50f6df 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -384,7 +384,7 @@ void TaskWindow::clearTasks(Core::Id categoryId) void TaskWindow::setCategoryVisibility(Core::Id categoryId, bool visible) { - if (categoryId.uniqueIdentifier() == 0) + if (!categoryId.isValid()) return; QList categories = d->m_filter->filteredCategories(); From 43e93009a3fa3126cdf5c73be32d935d30a6cdd2 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 23 Jun 2015 13:29:31 +0200 Subject: [PATCH 017/113] Linux: Fix deployment of libclang We need the versioned name of the library now, so copy all libclang.so* while keeping symlinks as symlinks. Change-Id: Ia2cc5e82be0848a3c9b0cb3055e150e6b1a151c9 Reviewed-by: Christian Stenger --- scripts/deployqt.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/scripts/deployqt.py b/scripts/deployqt.py index da122efc34f..f7bf539f2f1 100755 --- a/scripts/deployqt.py +++ b/scripts/deployqt.py @@ -216,20 +216,31 @@ def copy_translations(install_dir, qt_tr_dir): print translation, '->', tr_dir shutil.copy(translation, tr_dir) +def copyPreservingLinks(source, destination): + if os.path.islink(source): + linkto = os.readlink(source) + destFilePath = destination + if os.path.isdir(destination): + destFilePath = os.path.join(destination, os.path.basename(source)) + os.symlink(linkto, destFilePath) + else: + shutil.copy(source, destination) + def copy_libclang(install_dir, llvm_install_dir): - libsource = "" + libsources = [] libtarget = "" if sys.platform.startswith("win"): - libsource = os.path.join(llvm_install_dir, 'bin', 'libclang.dll') + libsources = [os.path.join(llvm_install_dir, 'bin', 'libclang.dll')] libtarget = os.path.join(install_dir, 'bin') else: - libsource = os.path.join(llvm_install_dir, 'lib', 'libclang.so') + libsources = glob(os.path.join(llvm_install_dir, 'lib', 'libclang.so*')) libtarget = os.path.join(install_dir, 'lib', 'qtcreator') resourcesource = os.path.join(llvm_install_dir, 'lib', 'clang') resourcetarget = os.path.join(install_dir, 'share', 'qtcreator', 'cplusplus', 'clang') print "copying libclang..." - print libsource, '->', libtarget - shutil.copy(libsource, libtarget) + for libsource in libsources: + print libsource, '->', libtarget + copyPreservingLinks(libsource, libtarget) print resourcesource, '->', resourcetarget if (os.path.exists(resourcetarget)): shutil.rmtree(resourcetarget) From aa20f1819df95570179f0ec4901c2b2baca6b3df Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 23 Jun 2015 11:54:03 +0200 Subject: [PATCH 018/113] Kits: Replace use of Id::fromUniqueId() and Id::toUniqueId() ... with fromSetting() and toSetting(), respectively. Arguably not strictly needed in this particular case, but emphasizing that uniqueId is discouraged to be used. Change-Id: I635f2cae8944912299d6331768fa88c96fc3089d Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/kitinformationconfigwidget.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/projectexplorer/kitinformationconfigwidget.cpp b/src/plugins/projectexplorer/kitinformationconfigwidget.cpp index 1aaa02a0672..c146bddd668 100644 --- a/src/plugins/projectexplorer/kitinformationconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitinformationconfigwidget.cpp @@ -228,7 +228,7 @@ DeviceTypeInformationConfigWidget::DeviceTypeInformationConfigWidget(Kit *workin = ExtensionSystem::PluginManager::getObjects(); foreach (IDeviceFactory *factory, factories) { foreach (Id id, factory->availableCreationIds()) - m_comboBox->addItem(factory->displayNameForId(id), id.uniqueIdentifier()); + m_comboBox->addItem(factory->displayNameForId(id), id.toSetting()); } m_comboBox->setToolTip(toolTip()); @@ -263,7 +263,7 @@ void DeviceTypeInformationConfigWidget::refresh() if (!devType.isValid()) m_comboBox->setCurrentIndex(-1); for (int i = 0; i < m_comboBox->count(); ++i) { - if (m_comboBox->itemData(i).toInt() == devType.uniqueIdentifier()) { + if (m_comboBox->itemData(i) == devType.toSetting()) { m_comboBox->setCurrentIndex(i); break; } @@ -277,7 +277,7 @@ void DeviceTypeInformationConfigWidget::makeReadOnly() void DeviceTypeInformationConfigWidget::currentTypeChanged(int idx) { - Id type = idx < 0 ? Id() : Id::fromUniqueIdentifier(m_comboBox->itemData(idx).toInt()); + Id type = idx < 0 ? Id() : Id::fromSetting(m_comboBox->itemData(idx)); DeviceTypeKitInformation::setDeviceTypeId(m_kit, type); } From d8cd6145c56fe5b6dc26db46cb487bb87e990066 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 23 Jun 2015 14:58:45 +0200 Subject: [PATCH 019/113] WS only change Change-Id: I3d2992e73e5625a227d8a78a52fb9e9f786a40a1 Reviewed-by: Leena Miettinen --- doc/api/coding-style.qdoc | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/doc/api/coding-style.qdoc b/doc/api/coding-style.qdoc index a8498b68bf2..8605afab185 100644 --- a/doc/api/coding-style.qdoc +++ b/doc/api/coding-style.qdoc @@ -50,7 +50,7 @@ \l{Patterns and Practices}. \li Document interfaces. Right now we use qdoc, but changing to doxygen is being considered. - \endlist + \endlist \section1 Submitting Code @@ -561,14 +561,15 @@ void someFunction() { ... } - } // namespace MyPlugin - \endcode + } // namespace MyPlugin + \endcode \li As an exception, if there is only a single class declaration inside the namespace, all can go on a single line: - \code - namespace MyPlugin { class MyClass; } - \endcode + + \code + namespace MyPlugin { class MyClass; } + \endcode \li Do not use using-directives in header files. @@ -1181,25 +1182,25 @@ your class. \li To improve code readability, always check whether a preprocessor - variable is defined before probing its value (\c{-Wundef}). + variable is defined before probing its value (\c {-Wundef}). \code - #if defined(Foo) && Foo == 0 + #if defined(Foo) && Foo == 0 -NOT- - #if Foo == 0 + #if Foo == 0 - -NOT- + -NOT- - #if Foo - 0 == 0 - \endcode + #if Foo - 0 == 0 + \endcode - \li When checking for a preprocessor define using the \c{defined} + \li When checking for a preprocessor define using the \c {defined} operator, always include the variable name in parentheses. \code - #if defined(Foo) + #if defined(Foo) -NOT- From 0f8c181eae62f303c37385f5dd0bbd3f57e4ada3 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Thu, 18 Jun 2015 14:59:42 +0200 Subject: [PATCH 020/113] Doc: Reformat, fix some markups Text is unchanged, but the markup has seen some changes. A couple of \c were added around code constructs where that was missing and the \uicontrol cleanups were applied. Change-Id: I0f9e840f831d777a82665316a7d42b94eb1f8574 Reviewed-by: Leena Miettinen --- doc/src/editors/creator-editors.qdoc | 1140 ++++++++++++++------------ 1 file changed, 600 insertions(+), 540 deletions(-) diff --git a/doc/src/editors/creator-editors.qdoc b/doc/src/editors/creator-editors.qdoc index 926dd1a8f23..124be5bb69d 100644 --- a/doc/src/editors/creator-editors.qdoc +++ b/doc/src/editors/creator-editors.qdoc @@ -31,8 +31,7 @@ \title Semantic Highlighting \QC understands the C++, QML, and JavaScript languages as code, not as plain - text. - It reads the source code, analyzes it, and highlights it based on the + text. It reads the source code, analyzes it, and highlights it based on the semantic checks that it does for the following code elements: \list @@ -48,10 +47,11 @@ \endlist To specify the color scheme to use for semantic highlighting, select - \uicontrol {Tools > Options > Text Editor > Fonts & Color}. + \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > + \uicontrol {Fonts & Color}. - \QC supports syntax highlighting also for other types of files than - C++, QML, or JavaScript. + \QC supports syntax highlighting also for other types of files than C++, + QML, or JavaScript. \section1 Generic Highlighting @@ -65,9 +65,9 @@ If you have a Unix installation that comes with the Kate Editor, you might already have the definition files installed. Typically, the files are located in a read-only directory, and therefore, you cannot manage them. \QC - can try to locate them and use them as fallback files, when the - primary location does not contain the definition for the current file type. - You can also specify the directory that contains preinstalled highlight + can try to locate them and use them as fallback files, when the primary + location does not contain the definition for the current file type. You can + also specify the directory that contains preinstalled highlight definition files as the primary location. When you open a file for editing and the editor cannot find the highlight @@ -78,8 +78,8 @@ \list 1 - \li Select \uicontrol {Tools > Options > Text Editor > Generic - Highlighter}. + \li Select \uicontrol Tools > \uicontrol Options > + \uicontrol {Text Editor} > \uicontrol {Generic Highlighter}. \image qtcreator-generic-highlighter.png "Generic Highlighter options" @@ -113,27 +113,27 @@ \section1 Highlighting and Folding Blocks Use block highlighting to visually separate parts of the code that belong - together. For example, when you place the cursor within the braces, - the code enclosed in braces is highlighted. + together. For example, when you place the cursor within the braces, the code + enclosed in braces is highlighted. \image qtcreator-blockhighlighting.png - To enable block highlighting, select \uicontrol Tools > \uicontrol{Options} > - \uicontrol{Text Editor} > \uicontrol Display > \uicontrol{Highlight blocks}. + To enable block highlighting, select \uicontrol Tools > + \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Display > + \uicontrol {Highlight blocks}. - Use the folding markers to collapse and expand blocks of code within - braces. Click the folding marker to collapse or expand a block. In the - figure above, the folding markers are located between the line number and - the text pane. + Use the folding markers to collapse and expand blocks of code within braces. + Click the folding marker to collapse or expand a block. In the figure above, + the folding markers are located between the line number and the text pane. - To show the folding markers, select \uicontrol Tools > \uicontrol{Options} > - \uicontrol{Text Editor} > \uicontrol Display > \uicontrol{Display folding markers}. This - option is enabled by default. + To show the folding markers, select \uicontrol Tools > \uicontrol Options > + \uicontrol {Text Editor} > \uicontrol Display > + \uicontrol {Display folding markers}. This option is enabled by default. - When the cursor is on a brace, the matching brace is animated - by default. To turn off the animation and just highlight the block and - the braces, select \uicontrol {Tools > Options > Text Editor > Display} and - deselect \uicontrol {Animate matching parentheses}. + When the cursor is on a brace, the matching brace is animated by default. To + turn off the animation and just highlight the block and the braces, select + \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > + \uicontrol Display and deselect \uicontrol {Animate matching parentheses}. */ @@ -148,9 +148,9 @@ As you write code, \QC checks code syntax. When \QC spots a syntax error in your code it underlines it and shows error details when you move the mouse - pointer over the error. - Similarly, when you are working on an instance of a JavaScript object - notation (JSON) entity, \QC underlines errors in JSON data structure. + pointer over the error. Similarly, when you are working on an instance of a + JavaScript object notation (JSON) entity, \QC underlines errors in JSON data + structure. \list @@ -194,15 +194,16 @@ \section1 Checking JavaScript and QML Syntax - To run the checks, select \uicontrol {Tools > QML/JS > Run Checks} or press - \key Ctrl+Shift+C. The results are shown in the \uicontrol {QML Analysis} - filter of the \uicontrol {Issues} output pane. + To run the checks, select \uicontrol Tools > \uicontrol {QML/JS} > + \uicontrol {Run Checks} or press \key {Ctrl+Shift+C}. The results are shown + in the \uicontrol {QML Analysis} filter of the \uicontrol Issues output + pane. \section1 List of JavaScript and QML Checks - Many of the JavaScript checks are similar to the ones in Douglas - Crockford's JSLint tool and are explained well on + Many of the JavaScript checks are similar to the ones in Douglas Crockford's + JSLint tool and are explained well on \l{http://www.jslint.com/lint.html}{the JSLint website}. \table @@ -293,19 +294,19 @@ \row \li M16 \li Error - \li Invalid property name 'name' + \li Invalid property name \c name \li \row \li M17 \li Error - \li 'Name' does not have members + \li \c Name does not have members \li \row \li M18 \li Error - \li 'Field' is not a member of 'object' + \li \c Field is not a member of \c object \li \row @@ -316,31 +317,30 @@ assignment in parentheses. \row - \li M20 - \li Warning - \li Unterminated non-empty case block - \li Case blocks should either be empty or end in a flow control - statement such as 'break', 'return' or 'continue'. - Alternatively you can indicate intentional fall through by - ending with a '// fall through' comment. + \li M20 + \li Warning + \li Unterminated non-empty case block + \li Case blocks should either be empty or end in a flow control + statement such as \c break, \c return or \c continue. + Alternatively you can indicate intentional fall through by ending + with a \c {// fall through} comment. \row \li M23 \li Warning - \li Do not use 'eval' + \li Do not use \c eval \li \row - \li M28 - \li Warning - \li Unreachable - \li Indicates that the underlined statement will never be - executed. + \li M28 + \li Warning + \li Unreachable + \li Indicates that the underlined statement will never be executed. \row \li M29 \li Warning - \li Do not use 'with' + \li Do not use \c with \li \row @@ -358,85 +358,85 @@ \row \li M103 \li Warning - \li 'Name' is already a formal parameter + \li \c Name is already a formal parameter \li \row \li M104 \li Warning - \li 'Name' is already a function + \li \c Name is already a function \li \row \li M105 \li Warning - \li Var 'name' is used before its declaration + \li Var \c name is used before its declaration \li \row \li M106 \li Warning - \li 'Name' is already a var + \li \c Name is already a var \li \row - \li M107 - \li Warning - \li 'Name' is declared more than once - \li Variables declared in a function are always visible everywhere - in the function, even when declared in nested blocks or - 'for' statement conditions. Redeclaring a variable has no - effect. + \li M107 + \li Warning + \li \c Name is declared more than once + \li Variables declared in a function are always visible everywhere in + the function, even when declared in nested blocks or \c for + statement conditions. Redeclaring a variable has no effect. \row \li M108 \li Warning - \li Function 'name' is used before its declaration + \li Function \c name is used before its declaration \li \row \li M109 \li Warning - \li Do not use 'Boolean' as a constructor + \li Do not use \c Boolean as a constructor \li \row \li M110 \li Warning - \li Do not use 'String' as a constructor + \li Do not use \c String as a constructor \li \row \li M111 \li Warning - \li Do not use 'Object' as a constructor + \li Do not use \c Object as a constructor \li \row \li M112 \li Warning - \li Do not use 'Array' as a constructor + \li Do not use \c Array as a constructor \li \row \li M113 \li Warning - \li Do not use 'Function' as a constructor + \li Do not use \c Function as a constructor \li \row - \li M114 - \li Hint - \li The 'function' keyword and the opening parenthesis should be separated by a single space + \li M114 + \li Hint + \li The \c function keyword and the opening parenthesis should be + separated by a single space \li \row - \li M115 - \li Warning - \li Do not use stand-alone blocks - \li Blocks do not affect variable scoping. Thus blocks that are - not associated to 'if', 'while', etc. have no effect and - should be avoided. + \li M115 + \li Warning + \li Do not use stand-alone blocks + \li Blocks do not affect variable scoping. Thus blocks that are not + associated to \c if, \c while, etc. have no effect and should be + avoided. \row \li M116 @@ -470,19 +470,20 @@ \target m126 \row - \li M126 - \li Warning - \li == and != may perform type coercion, use === or !== to avoid it - \li The non-strict equality comparison is allowed to convert its - arguments to a common type. That can lead to unexpected - results such as \c {' \t\r\n' == 0} being true. Use the - strict equality operators === and !== and be explicit about - conversions you require. + \li M126 + \li Warning + \li \c == and \c != may perform type coercion, use \c === or \c !== to + avoid it + \li The non-strict equality comparison is allowed to convert its + arguments to a common type. That can lead to unexpected results such + as \c {' \t\r\n' == 0} being true. Use the strict equality operators + \c === and \c !== and be explicit about conversions you require. \row - \li M127 - \li Warning - \li Expression statements should be assignments, calls or delete expressions only + \li M127 + \li Warning + \li Expression statements should be assignments, calls or delete + expressions only \li \row @@ -509,10 +510,10 @@ \li This QML type is not supported in the Qt Quick Designer \li \row - \li M205 - \li Warning - \li Reference to parent QML type cannot be resolved correctly by the - Qt Quick Designer + \li M205 + \li Warning + \li Reference to parent QML type cannot be resolved correctly by the Qt + Quick Designer \li \row @@ -529,22 +530,22 @@ \li \row - \li M208 - \li Error - \li This type (%1) is not supported as a root element by \QMLD. + \li M208 + \li Error + \li This type (type name) is not supported as a root element by \QMLD. \li \row - \li M220 - \li Error - \li This type (%1) is not supported as a root element of a Qt Quick UI - form. + \li M220 + \li Error + \li This type (type name) is not supported as a root element of a Qt + Quick UI form. \li \row - \li M221 - \li Error - \li This type (%1) is not supported in a Qt Quick UI form. + \li M221 + \li Error + \li This type (type name) is not supported in a Qt Quick UI form. \li \row @@ -587,48 +588,50 @@ \row \li M301 \li Error - \li Could not resolve the prototype 'name' of 'object' + \li Could not resolve the prototype \c name of \c object \li \row \li M302 \li Error - \li Could not resolve the prototype 'name' + \li Could not resolve the prototype \c name \li \row \li M303 \li Error - \li Prototype cycle, the last non-repeated component is 'name' + \li Prototype cycle, the last non-repeated component is \c name \li \row \li M304 \li Error - \li Invalid property type 'name' + \li Invalid property type \c name \li \row - \li M305 - \li Warning - \li == and != perform type coercion, use === or !== to avoid it - \li See \l{m126}{M126}. + \li M305 + \li Warning + \li \c == and \c != perform type coercion, use \c === or \c !== to + avoid it + \li See \l{m126}{M126}. \row - \li M306 - \li Warning - \li Calls of functions that start with an uppercase letter should use 'new' - \li By convention, functions that start with an uppercase letter - are constructor functions that should only be used with 'new'. + \li M306 + \li Warning + \li Calls of functions that start with an uppercase letter should use + \c new + \li By convention, functions that start with an uppercase letter + are constructor functions that should only be used with \c new. \row - \li M307 - \li Warning - \li Use 'new' only with functions that start with an uppercase letter + \li M307 + \li Warning + \li Use \c new only with functions that start with an uppercase letter \li \row \li M308 \li Warning - \li Do not use 'Number' as a constructor + \li Do not use \c Number as a constructor \li \row @@ -644,15 +647,15 @@ \li \row - \li M311 - \li Hint - \li Use 'type' instead of 'var' or 'variant' to improve performance + \li M311 + \li Hint + \li Use \c type instead of \c var or \c variant to improve performance \li \row \li M312 \li Error - \li Missing property 'number' + \li Missing property \c number \li \row @@ -670,19 +673,19 @@ \row \li M315 \li Error - \li 'Value' value expected + \li \c Value value expected \li \row \li M316 \li Error - \li Maximum number value is 'number' + \li Maximum number value is \c number \li \row \li M317 \li Error - \li Minimum number value is 'number' + \li Minimum number value is \c number \li \row @@ -706,30 +709,30 @@ \row \li M321 \li Error - \li Minimum string value length is 'number' + \li Minimum string value length is \c number \li \row \li M322 \li Error - \li Maximum string value length is 'number' + \li Maximum string value length is \c number \li \row \li M323 \li Error - \li 'Number' elements expected in array value + \li \c Number elements expected in array value \li \row - \li M324 - \li Warning - \li Using Qt Quick 1 code model instead of Qt Quick 2 - \li The code model might be corrupt or the QML emulation layer might - have been built with a different Qt version than the one selected - in the build and run kit. For more information, see - \l {Resetting the Code Model} and - \l {Running QML Modules in Qt Quick Designer}. + \li M324 + \li Warning + \li Using Qt Quick 1 code model instead of Qt Quick 2 + \li The code model might be corrupt or the QML emulation layer might + have been built with a different Qt version than the one selected in + the build and run kit. For more information, see + \l {Resetting the Code Model} and + \l {Running QML Modules in Qt Quick Designer}. \endtable @@ -777,11 +780,11 @@ To open the list of suggestions at any time, press \key {Ctrl+Space}. If only one option is available, \QC inserts it automatically. - When completion is invoked manually, \QC completes the common prefix - of the list of suggestions. This is especially useful for classes with - several similarly named members. To disable this functionality, uncheck - \uicontrol{Autocomplete common prefix} in the code completion preferences. - Select \uicontrol Tools > \uicontrol{Options} > \uicontrol{Text Editor} + When completion is invoked manually, \QC completes the common prefix of the + list of suggestions. This is especially useful for classes with several + similarly named members. To disable this functionality, uncheck + \uicontrol {Autocomplete common prefix} in the code completion preferences. + Select \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Completion. By default, code completion considers only the first letter case-sensitive. @@ -790,8 +793,8 @@ \section2 Summary of Available Types - The following table lists available types for code completion and icon - used for each. + The following table lists available types for code completion and icon used + for each. \table \header @@ -858,12 +861,11 @@ \section2 Completing Code Snippets - Code snippets can consist of multiple - variables that you specify values for. Select an item in the list and press - \key Tab or \key Enter to complete the code. Press \key Tab to - move between the variables and specify values for them. When you specify a - value for a variable, all instances of the variable within the snippet - are renamed. + Code snippets can consist of multiple variables that you specify values for. + Select an item in the list and press \key Tab or \key Enter to complete the + code. Press \key Tab to move between the variables and specify values for + them. When you specify a value for a variable, all instances of the variable + within the snippet are renamed. \image qmldesigner-code-completion.png "Completing QML code" @@ -871,7 +873,8 @@ Code snippets specify C++ or QML code constructs. You can add, modify, and remove snippets in the snippet editor. To open the editor, select - \uicontrol {Tools > Options > Text Editor > Snippets}. + \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > + \uicontrol Snippets. \image qtcreator-edit-code-snippets.png "Snippet options" @@ -891,10 +894,10 @@ \section3 Adding and Editing Snippets Select a snippet in the list to edit it in the snippet editor. To add a new - snippet, select \uicontrol Add. Specify a trigger and, if the trigger is already - in use, an optional variant, which appear in the list of suggestions when - you write code. Also specify a text string or C++ or QML code construct in - the snippet editor, depending on the snippet category. + snippet, select \uicontrol Add. Specify a trigger and, if the trigger is + already in use, an optional variant, which appear in the list of suggestions + when you write code. Also specify a text string or C++ or QML code construct + in the snippet editor, depending on the snippet category. The snippet editor provides you with: @@ -944,27 +947,27 @@ or add. However, when you use the snippets, the code editor marks any errors by underlining them in red. - To discard the changes you made to a built-in snippet, select \uicontrol {Revert - Built-in}. + To discard the changes you made to a built-in snippet, select + \uicontrol {Revert Built-in}. \section3 Removing Snippets - Several similar built-in snippets might be provided for different use - cases. To make the list of suggestions shorter when you write code, remove - the built-in snippets that you do not need. If you need them later, you - can restore them. + Several similar built-in snippets might be provided for different use cases. + To make the list of suggestions shorter when you write code, remove the + built-in snippets that you do not need. If you need them later, you can + restore them. To remove snippets, select a snippet in the list, and then select - \uicontrol Remove. To restore the removed snippets, select \uicontrol {Restore Removed - Built-ins}. + \uicontrol Remove. To restore the removed snippets, select + \uicontrol {Restore Removed Built-ins}. \section3 Resetting Snippets To remove all added snippets and to restore all removed snippets, select \uicontrol {Reset All}. - \note If you now select \uicontrol OK or \uicontrol Apply, you permanently lose all - your own snippets. + \note If you now select \uicontrol OK or \uicontrol Apply, you permanently + lose all your own snippets. */ @@ -999,60 +1002,64 @@ \list 1 - \li Select \uicontrol Tools > \uicontrol Options > \uicontrol{Code Pasting}. + \li Select \uicontrol Tools > \uicontrol Options > + \uicontrol {Code Pasting}. \image qtcreator-code-pasting-options.png "Code Pasting options" - \li In the \uicontrol {Default protocol} field, select a code pasting service - to use by default. + \li In the \uicontrol {Default protocol} field, select a code pasting + service to use by default. \li In the \uicontrol Username field, enter your username. - \li In the \uicontrol {Expires after} field, specify the time to keep the - pasted snippet on the server. + \li In the \uicontrol {Expires after} field, specify the time to keep + the pasted snippet on the server. - \li Select the \uicontrol {Copy-paste URL to clipboard} check box to copy the - URL of the post on the code pasting service to the clipboard when - you paste a post. + \li Select the \uicontrol {Copy-paste URL to clipboard} check box to + copy the URL of the post on the code pasting service to the + clipboard when you paste a post. \li Select the \uicontrol {Display Output pane after sending a post} to - display the URL in the \uicontrol {General Messages} output pane when you - paste a post. + display the URL in the \uicontrol {General Messages} output pane + when you paste a post. \endlist - Select \uicontrol Fileshare to specify the path to a shared - network drive. The code snippets are copied to the drive as simple files. - You have to delete obsolete files from the drive manually. + Select \uicontrol Fileshare to specify the path to a shared network drive. + The code snippets are copied to the drive as simple files. You have to + delete obsolete files from the drive manually. \section1 Using Code Pasting Services - To paste a snippet of code onto the server, select \uicontrol{Tools} > - \uicontrol{Code Pasting} > \uicontrol{Paste Snippet} or press \key{Alt+C,Alt+P}. - By default, \QC copies the URL of the snippet to the clipboard and displays - the URL in the \uicontrol {General Messages} output pane. + To paste a snippet of code onto the server, select \uicontrol Tools > + \uicontrol {Code Pasting} > \uicontrol {Paste Snippet} or press + \key {Alt+C,Alt+P}. By default, \QC copies the URL of the snippet to the + clipboard and displays the URL in the \uicontrol {General Messages} output + pane. - To paste any content that you copied to the clipboard, select \uicontrol Tools > - \uicontrol {Code Pasting} > \uicontrol {Paste Snippet}. + To paste any content that you copied to the clipboard, select + \uicontrol Tools > \uicontrol {Code Pasting} > \uicontrol {Paste Snippet}. To paste content from the \l{Comparing Files}{diff editor}, right-click a chunk and select \uicontrol {Send Chunk to CodePaster} in the context menu. - To fetch a snippet of code from the server, select \uicontrol{Tools} > - \uicontrol{Code Pasting} > \uicontrol{Fetch Snippet} or press \key{Alt+C,Alt+F}. Select - the snippet to fetch from the list. + To fetch a snippet of code from the server, select \uicontrol Tools > + \uicontrol {Code Pasting} > \uicontrol {Fetch Snippet} or press + \key {Alt+C,Alt+F}. Select the snippet to fetch from the list. To fetch the content stored at an URL, select \uicontrol Tools > \uicontrol {Code Pasting} > \uicontrol {Fetch from URL}. For example, you might ask colleagues to review a change that you plan to submit to a version control system. If you use the Git version control - system, you can create a \e{diff} view by selecting \uicontrol{Tools > Git > - Diff Repository}. You can then upload its contents to the server by choosing - \uicontrol{Tools} > \uicontrol{Code Pasting} > \uicontrol{Paste Snippet}. The reviewers can - retrieve the code snippet by selecting \uicontrol{Tools > Code Pasting > - Fetch Snippet}. If they have the project currently opened in \QC, they can - apply and test the change by choosing \uicontrol{Tools > Git > Apply Patch}. + system, you can create a \e{diff} view by selecting \uicontrol Tools > + \uicontrol Git > \uicontrol {Diff Repository}. You can then upload its + contents to the server by choosing \uicontrol Tools > + \uicontrol {Code Pasting} > \uicontrol {Paste Snippet}. The reviewers can + retrieve the code snippet by selecting \uicontrol Tools > + \uicontrol {Code Pasting} > \uicontrol {Fetch Snippet}. If they have the + project currently opened in \QC, they can apply and test the change by + choosing \uicontrol Tools > \uicontrol Git > \uicontrol {Apply Patch}. */ @@ -1065,26 +1072,31 @@ \title Using Text Editing Macros - To record a text editing macro, select \uicontrol {Tools > Text Editing Macros > Record Macro} - or press \key {Alt+(}. To stop recording, select \uicontrol {Tools > Text Editing Macros > - Stop Recording Macro} or press \key {Alt+)}. + To record a text editing macro, select \uicontrol Tools > + \uicontrol {Text Editing Macros} > \uicontrol {Record Macro} + or press \key {Alt+(}. To stop recording, select \uicontrol Tools > + \uicontrol {Text Editing Macros} > \uicontrol {Stop Recording Macro} or + press \key {Alt+)}. \note The macro recorder does not support code completion. - To play the last macro, select \uicontrol {Tools > Text Editing Macros > Play Last Macro} or + To play the last macro, select \uicontrol Tools > + \uicontrol {Text Editing Macros} > \uicontrol {Play Last Macro} or press \key {Alt+R}. - To save the last macro, select \uicontrol {Tools > Text Editing Macros > Save Last Macro}. + To save the last macro, select \uicontrol Tools > + \uicontrol {Text Editing Macros} > \uicontrol {Save Last Macro}. - To assign a keyboard shortcut to a text editing macro, select \uicontrol {Tools > - Options > Environment > Keyboard}. For more information, see + To assign a keyboard shortcut to a text editing macro, select + \uicontrol Tools > \uicontrol Options > \uicontrol Environment > + \uicontrol Keyboard. For more information, see \l{Configuring Keyboard Shortcuts}. You can also use the \c rm locator filter to run a macro. For more information, see \l{Searching with the Locator}. - To view and remove saved macros, select \uicontrol {Tools > Options > Text - Editor > Macros}. + To view and remove saved macros, select \uicontrol Tools > + \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Macros. */ @@ -1097,44 +1109,45 @@ \title Using FakeVim Mode - In the \uicontrol{FakeVim} mode, you can run the main editor in a manner similar - to the Vim editor. To run the editor in the \uicontrol{FakeVim} mode, select - \uicontrol{Edit} > \uicontrol{Advanced} > \uicontrol{Use Vim-style Editing} or press - \key{Alt+V,Alt+V}. + In the \uicontrol FakeVim mode, you can run the main editor in a manner + similar to the Vim editor. To run the editor in the \uicontrol FakeVim + mode, select \uicontrol Edit > \uicontrol Advanced > + \uicontrol {Use Vim-style Editing} or press \key {Alt+V,Alt+V}. - In the \uicontrol{FakeVim} mode, most keystrokes in the main editor will be + In the \uicontrol FakeVim mode, most keystrokes in the main editor will be intercepted and interpreted in a way that resembles Vim. Documentation for - Vim is not included in \QC. For more information on using Vim, - see \l{http://www.vim.org/docs.php}{Documentation} on the Vim web site. + Vim is not included in \QC. For more information on using Vim, see + \l{http://www.vim.org/docs.php}{Documentation} on the Vim web site. - To map commands entered on the \uicontrol{FakeVim} command line to actions of the - \QC core, select \uicontrol{Tools} > \uicontrol{Options} > \uicontrol{FakeVim} > - \uicontrol{Ex Command Mapping}. + To map commands entered on the \uicontrol FakeVim command line to actions + of the \QC core, select \uicontrol Tools > \uicontrol Options > + \uicontrol FakeVim > \uicontrol {Ex Command Mapping}. - To map \e {user commands} to keyboard shortcuts, select \uicontrol{Tools > Options - > FakeVim > User Command Mapping}. The user command mapped to the shortcut + To map \e {user commands} to keyboard shortcuts, select \uicontrol Tools > + \uicontrol Options > \uicontrol FakeVim > + \uicontrol {User Command Mapping}. The user command mapped to the shortcut is executed by FakeVim as if you were typing it (as when replaying a macro). - To make changes to the Vim-style settings, select \uicontrol{Tools} > - \uicontrol{Options} > \uicontrol FakeVim > \uicontrol{General}. + To make changes to the Vim-style settings, select \uicontrol Tools > + \uicontrol Options > \uicontrol FakeVim > \uicontrol General. \image qtcreator-fakevim-options.png "FakeVim options" To preselect the indentation settings specified for the text editor, select - \uicontrol {Copy Text Editor Settings}. To preselect the Qt coding style, select - \uicontrol {Set Qt Style}. To preselect a simple indentation style, select - \uicontrol {Set Plain Style}. You can then change any of the preselected settings. + \uicontrol {Copy Text Editor Settings}. To preselect the Qt coding style, + select \uicontrol {Set Qt Style}. To preselect a simple indentation style, + select \uicontrol {Set Plain Style}. You can then change any of the + preselected settings. - To use a Vim-style color scheme, select \uicontrol {Tools > Options > - Text Editor > Fonts & Color}. In the \uicontrol {Color Scheme} list, select - \uicontrol {Vim (dark)}. + To use a Vim-style color scheme, select \uicontrol Tools > + \uicontrol Options > \uicontrol {Text Editor} > \uicontrol {Fonts & Color}. + In the \uicontrol {Color Scheme} list, select \uicontrol {Vim (dark)}. - To quit the FakeVim mode, unselect \uicontrol{Tools} > \uicontrol{Options} > - \uicontrol{FakeVim} > \uicontrol {Use FakeVim} or press \key{Alt+V,Alt+V}. + To quit the FakeVim mode, unselect \uicontrol Tools > \uicontrol Options > + \uicontrol FakeVim > \uicontrol {Use FakeVim} or press \key {Alt+V,Alt+V}. - You can temporarily escape FakeVim mode to access the normal \QC - keyboard shortcuts like \key{Ctrl-R} for \uicontrol{Run} by pressing - \key{,} first. + You can temporarily escape FakeVim mode to access the normal \QC keyboard + shortcuts like \key {Ctrl-R} for \uicontrol Run by pressing \key {,} first. */ @@ -1146,9 +1159,9 @@ \title Indenting Text or Code - When you type text or code, it is indented automatically according to the selected - text editor or code style options. Select a block to indent it when you - press \key Tab. Press \key {Shift+Tab} to decrease the indentation. You + When you type text or code, it is indented automatically according to the + selected text editor or code style options. Select a block to indent it when + you press \key Tab. Press \key {Shift+Tab} to decrease the indentation. You can disable automatic indentation. You can specify indentation for: @@ -1173,10 +1186,10 @@ \list 1 - \li Select \uicontrol {Tools > Options > C++}. + \li Select \uicontrol Tools > \uicontrol Options > \uicontrol {C++}. - \li In the \uicontrol {Current settings} field, select the settings to modify - and click \uicontrol Copy. + \li In the \uicontrol {Current settings} field, select the settings to + modify and click \uicontrol Copy. \image qtcreator-options-code-style-cpp.png "C++ Code Style options" @@ -1211,8 +1224,8 @@ You can use the live preview to see how the options change the indentation. - To specify different settings for a particular project, select \uicontrol {Projects > - Code Style Settings}. + To specify different settings for a particular project, select + \uicontrol Projects > \uicontrol {Code Style Settings}. \section1 Indenting QML Files @@ -1220,10 +1233,11 @@ \list 1 - \li Select \uicontrol {Tools > Options >Qt Quick}. + \li Select \uicontrol Tools > \uicontrol Options > + \uicontrol {Qt Quick}. - \li In the \uicontrol {Current settings} field, select the settings to modify - and click \uicontrol Copy. + \li In the \uicontrol {Current settings} field, select the settings to + modify and click \uicontrol Copy. \image qtcreator-options-code-style-qml.png "QML Code Style options" @@ -1238,18 +1252,19 @@ You can specify how to interpret the \key Tab key presses and how to align continuation lines. - To specify different settings for a particular project, select \uicontrol {Projects > - Code Style Settings}. + To specify different settings for a particular project, select + \uicontrol Projects > \uicontrol {Code Style Settings}. \section1 Indenting Other Text Files - To specify indentation settings for text files that do not contain C++ or QML code (such - as Python code files), select \uicontrol {Tools > Options > Text Editor > Behavior}. + To specify indentation settings for text files that do not contain C++ or + QML code (such as Python code files), select \uicontrol Tools > + \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Behavior. \image qtcreator-indentation.png "Text Editor Behavior options" - To specify different settings for a particular project, select \uicontrol Projects - > \uicontrol Editor. + To specify different settings for a particular project, select + \uicontrol Projects > \uicontrol Editor. You can specify how to interpret the \key Tab and \key Backspace key presses and how to align continuation lines. @@ -1276,39 +1291,41 @@ \section2 Specifying Tabs and Indentation - You can specify tab policy and tab size in the \uicontrol Typing group. In the - \uicontrol {Tab policy} field, select whether to use only spaces or only tabs for - indentation, or to use a mixture of them. + You can specify tab policy and tab size in the \uicontrol Typing group. In + the \uicontrol {Tab policy} field, select whether to use only spaces or + only tabs for indentation, or to use a mixture of them. By default, the tab length in code editor is 8 spaces and the indent size is 4 spaces. You can specify the tab length and indent size separately for each project and for different types of files. You can have continuation lines aligned with the previous line. In the - \uicontrol {Align continuation lines} field, select \uicontrol {Not at all} to disable - automatic alignment and indent continuation lines to the logical depth. - To always use spaces for alignment, select \uicontrol {With Spaces}. To follow the - \uicontrol {Tab policy}, select \uicontrol {With Regular Indent}. + \uicontrol {Align continuation lines} field, select + \uicontrol {Not at all} to disable automatic alignment and indent + continuation lines to the logical depth. To always use spaces for alignment, + select \uicontrol {With Spaces}. To follow the \uicontrol {Tab policy}, + select \uicontrol {With Regular Indent}. \section2 Specifying Typing Options - When you type text or code, it is indented automatically according to the selected - text editor or code style options. Specify typing options in the + When you type text or code, it is indented automatically according to the + selected text editor or code style options. Specify typing options in the \uicontrol Typing group. To disable automatic indentation, deselect the \uicontrol {Enable automatic indentation} check box. You can specify how the indentation is decreased when you press - \uicontrol Backspace in the \uicontrol {Backspace indentation} field. To go back one - space at a time, select \uicontrol None. To decrease indentation in leading white - space by one level, select \uicontrol {Follows Previous Indents}. To move back one - tab length if the character to the left of the cursor is a space, select + \uicontrol Backspace in the \uicontrol {Backspace indentation} field. To go + back one space at a time, select \uicontrol None. To decrease indentation + in leading white space by one level, select + \uicontrol {Follows Previous Indents}. To move back one tab length if the + character to the left of the cursor is a space, select \uicontrol Unindents. You can specify whether the \key Tab key automatically indents text when you press it. To automatically indent text, select \uicontrol Always in the - \uicontrol {Tab key performs auto-indent} field. To only indent text when the - cursor is located within leading white space, select \uicontrol {In Leading White - Space}. + \uicontrol {Tab key performs auto-indent} field. To only indent text when + the cursor is located within leading white space, select \uicontrol {In + Leading White Space}. \section1 Specifying Settings for Content @@ -1336,10 +1353,10 @@ \section1 Specifying Alignment - To align continuation lines to tokens after assignments, such as = or - +=, select the \uicontrol {Align after assignments} check box. You can specify - additional settings for aligning continuation lines in the \uicontrol General - tab. + To align continuation lines to tokens after assignments, such as \c = or + \c +=, select the \uicontrol {Align after assignments} check box. You can + specify additional settings for aligning continuation lines in the + \uicontrol General tab. You can also add spaces to conditional statements, so that they are not aligned with the following line. Usually, this only affects \c if @@ -1349,12 +1366,12 @@ \section1 Binding Pointers and References - To bind pointers (*) and references (&) in types and declarations to + To bind pointers (\c *) and references (\c &) in types and declarations to identifiers, type names, or left or right \c const or \c volatile keywords, select the check boxes in the \uicontrol {Pointers and References} tab. - The * and & characters are automatically bound to identifiers of pointers to - functions and pointers to arrays. + The \c * and \c & characters are automatically bound to identifiers of + pointers to functions and pointers to arrays. \image qtcreator-pointers-references.png "Pointers and References options" @@ -1373,8 +1390,8 @@ \list 1 - \li Press \key Ctrl+F or select \uicontrol Edit > \uicontrol Find/Replace > - \uicontrol{Find/Replace}. + \li Press \key {Ctrl+F} or select \uicontrol Edit > + \uicontrol {Find/Replace} > \uicontrol {Find/Replace}. \li Enter the text you are looking for. @@ -1384,7 +1401,7 @@ (\uicontrol {Find Next}), or press \key F3. To go to the previous occurrence click \inlineimage qtcreator-previous.png - (\uicontrol {Find Previous}), or press \key Shift+F3. + (\uicontrol {Find Previous}), or press \key {Shift+F3}. \endlist @@ -1396,14 +1413,13 @@ \li To make your search case sensitive, select \uicontrol {Case Sensitive}. - \li To search only whole words, select - \uicontrol {Whole Words Only}. + \li To search only whole words, select \uicontrol {Whole Words Only}. \li To search using regular expressions, select - \uicontrol {Regular Expressions}. - Regular expressions used in \QC are modeled on Perl regular - expressions. For more information on using regular expressions, see - the documentation for the QRegExp Class. + \uicontrol {Regular Expressions}. Regular expressions used in \QC + are modeled on Perl regular expressions. For more information on + using regular expressions, see the documentation for the + QRegularExpression Class. \endlist @@ -1416,36 +1432,37 @@ \list \li To replace the selected occurrence and move to the next one, - click \uicontrol {Find Next} - or press \key Ctrl+=. + click \uicontrol {Find Next} or press \key {Ctrl+=}. \li To replace the selected occurrence and move to the previous one, - click \uicontrol {Find Previous} - . + click \uicontrol {Find Previous}. - \li To replace all occurrences in the file, click \uicontrol{Replace All}. + \li To replace all occurrences in the file, click + \uicontrol {Replace All}. \endlist - The \uicontrol{Preserve Case when Replacing} option can be selected to preserve - the case of the original text when replacing. This option is not compatible - with the \uicontrol {Regular Expressions} search option, and will thus be - disabled when regular expressions are used. When the option is used, the - case of the occurrence will be conserved, according to the following rules: + The \uicontrol {Preserve Case when Replacing} option can be selected to + preserve the case of the original text when replacing. This option is not + compatible with the \uicontrol {Regular Expressions} search option, and will + thus be disabled when regular expressions are used. When the option is used, + the case of the occurrence will be conserved, according to the following + rules: \list - \li All upper-case occurrences are replaced with the upper-case new text. - - \li All lower-case occurrences are replaced with the lower-case new text. + \li All upper-case occurrences are replaced with the upper-case new + text. + \li All lower-case occurrences are replaced with the lower-case new + text. \li Capitalized occurrences are replaced with the capitalized new text. \li Other occurrences are replaced with the new text as entered. - \li If an occurrence and the new text have the same prefix or suffix, - then the case of the prefix and/or suffix are preserved, and the - other rules are applied on the rest of the occurrence only. + \li If an occurrence and the new text have the same prefix or suffix, + then the case of the prefix and/or suffix are preserved, and the + other rules are applied on the rest of the occurrence only. \endlist @@ -1455,24 +1472,26 @@ \list 1 - \li Press \key Ctrl+Shift+F or select \uicontrol Edit > \uicontrol Find/Replace > - \uicontrol{Advanced Find} > \uicontrol{Open Advanced Find}. + \li Press \key {Ctrl+Shift+F} or select \uicontrol Edit > + \uicontrol {Find/Replace} > \uicontrol {Advanced Find} > + \uicontrol {Open Advanced Find}. \li Select the scope of your search: \list - \li \uicontrol{All Projects} searches files matching the defined file - pattern in all currently open projects. + \li \uicontrol {All Projects} searches files matching the + defined file pattern in all currently open projects. - For example, to search for \tt previewer only in \tt .cpp - and \tt .h files, enter in \uicontrol{File pattern} - \tt *.cpp,*.h. + For example, to search for \c previewer only in \c {.cpp} + and \c {.h} files, enter in \uicontrol {File pattern} + \c {*.cpp,*.h}. \image qtcreator-search-allprojects.png - \li \uicontrol{Current Project} searches files matching the defined - file pattern only in the project you are currently editing. + \li \uicontrol {Current Project} searches files matching the + defined file pattern only in the project you are currently + editing. \li \uicontrol {Files on File System} recursively searches files matching the defined file pattern in the selected directory. @@ -1498,7 +1517,8 @@ \li To go to an occurrence, double-click it. \li To repeat the search after you have made changes to the - listed files, for example, select \uicontrol {Search Again}. + listed files, for example, select + \uicontrol {Search Again}. \endlist @@ -1507,8 +1527,8 @@ The search results are stored in the search history from which you can select earlier searches. - \note You can use \uicontrol{Advanced Find} also to search for symbols. For more - information, see \l{Finding Symbols}. + \note You can use \uicontrol {Advanced Find} also to search for symbols. For + more information, see \l{Finding Symbols}. */ @@ -1547,11 +1567,12 @@ \list - \li \uicontrol {Tools > C++ > Find Usages} + \li \uicontrol Tools > \uicontrol {C++} > \uicontrol {Find Usages} - \li \uicontrol {Tools > QML/JS > Find Usages} + \li \uicontrol Tools > \uicontrol {QML/JS} > + \uicontrol {Find Usages} - \li \key Ctrl+Shift+U + \li \key {Ctrl+Shift+U} \endlist @@ -1568,15 +1589,16 @@ \endlist - \note You can also select \uicontrol{Edit > Find/Replace > Advanced Find > - C++ Symbols} to search for classes, functions, enums, and declarations - either from files listed as part of the project or from all files that - are used by the code, such as include files. + \note You can also select \uicontrol Edit > \uicontrol {Find/Replace} > + \uicontrol {Advanced Find} > \uicontrol {C++ Symbols} to search for + classes, functions, enums, and declarations either from files listed as + part of the project or from all files that are used by the code, such as + include files. \image qtcreator-search-cpp-symbols.png - \li The \uicontrol{Search Results} pane opens and shows the location and - number of instances of the symbol in the current project. + \li The \uicontrol {Search Results} pane opens and shows the location + and number of instances of the symbol in the current project. \image qtcreator-refactoring-find.png @@ -1589,17 +1611,16 @@ \li To go directly to an instance, double-click the instance in the \uicontrol {Search Results} pane. - \li To move between instances, click - \inlineimage qtcreator-forward.png - and - \inlineimage qtcreator-back.png - in the \uicontrol{Search Results} pane. + \li To move between instances, click \inlineimage qtcreator-forward.png + and \inlineimage qtcreator-back.png + in the \uicontrol {Search Results} pane. \li To expand and collapse the list of all instances, click \inlineimage qtcreator-expand.png . - \li To clear the search results, click \inlineimage qtcreator-clear.png + \li To clear the search results, click + \inlineimage qtcreator-clear.png . \endlist @@ -1611,18 +1632,20 @@ \list 1 \li In the editor, place the cursor on the symbol you would like to - change and select \uicontrol Tools > \uicontrol C++ > - \uicontrol{Rename Symbol Under Cursor} or \uicontrol Tools > \uicontrol QML/JS > - \uicontrol{Rename Symbol Under Cursor}. Alternatively, press - \key Ctrl+Shift+R. + change and select \uicontrol Tools > \uicontrol {C++} > + \uicontrol {Rename Symbol Under Cursor} or + \uicontrol Tools > \uicontrol {QML/JS} > + \uicontrol {Rename Symbol Under Cursor}. Alternatively, press + \key {Ctrl+Shift+R}. - The \uicontrol{Search Results} pane opens and shows the location and - number of instances of the symbol in the current project. + The \uicontrol {Search Results} pane opens and shows the location + and number of instances of the symbol in the current project. \image qtcreator-refactoring-replace.png \li To replace all selected instances, enter the name of the new symbol - in the \uicontrol{Replace with} text box and click \uicontrol Replace. + in the \uicontrol {Replace with} text box and click + \uicontrol Replace. To omit an instance, uncheck the check-box next to the instance. @@ -1632,9 +1655,9 @@ \endlist - \note Renaming local symbols does not open the \uicontrol{Search Results} pane. - The instances of the symbol are highlighted in code and you can edit the - symbol. All instances of the local symbol are changed as you type. + \note Renaming local symbols does not open the \uicontrol {Search Results} + pane. The instances of the symbol are highlighted in code and you can edit + the symbol. All instances of the local symbol are changed as you type. \section1 Column Editing @@ -1644,19 +1667,19 @@ \section1 Applying Refactoring Actions - \QC allows you to quickly and conveniently apply actions to refactor - your code by selecting them in a context menu. The actions available depend - on the position of the cursor in the code editor and on whether you are - writing C++ or QML code. + \QC allows you to quickly and conveniently apply actions to refactor your + code by selecting them in a context menu. The actions available depend on + the position of the cursor in the code editor and on whether you are writing + C++ or QML code. To apply refactoring actions to C++ code, right-click an operand, conditional statement, string, or name to open a context menu. In QML code, click an item ID or name. - In the context menu, select \uicontrol {Refactoring} and then select a refactoring - action. + In the context menu, select \uicontrol {Refactoring} and then select a + refactoring action. - You can also press \uicontrol {Alt+Enter} to open a context menu that contains + You can also press \key {Alt+Enter} to open a context menu that contains refactoring actions available in the current cursor position. \section2 Refactoring C++ Code @@ -1690,33 +1713,33 @@ \li Description \li Activation \row - \li Add Curly Braces - \li Adds curly braces to an if statement that does not contain a - compound statement. For example, rewrites + \li Add Curly Braces + \li Adds curly braces to an if statement that does not contain a + compound statement. For example, rewrites \code if (a) b; \endcode - as + as \code if (a) { b; } \endcode - \li if + \li \c if \row - \li Move Declaration out of Condition - \li Moves a declaration out of an if or while condition to simplify the - condition. For example, rewrites + \li Move Declaration out of Condition + \li Moves a declaration out of an if or while condition to simplify + the condition. For example, rewrites \code if (Type name = foo()) {} \endcode - as + as \code Type name = foo; @@ -1724,23 +1747,23 @@ \endcode \li Name of the introduced variable \row - \li Rewrite Condition Using || - \li Rewrites the expression according to De Morgan's laws. For example, - rewrites: + \li Rewrite Condition Using || + \li Rewrites the expression according to De Morgan's laws. For + example, rewrites: \code !a && !b \endcode - as + as \code !(a || b) \endcode - \li && + \li \c && \row - \li Rewrite Using \e operator - \li Rewrites an expression negating it and using the inverse operator. For - example, rewrites: + \li Rewrite Using \e operator + \li Rewrites an expression negating it and using the inverse + operator. For example, rewrites: \list @@ -1748,7 +1771,7 @@ a op b \endcode - as + as \code !(a invop b) @@ -1758,7 +1781,7 @@ (a op b) \endcode - as + as \code !(a invop b) @@ -1768,7 +1791,7 @@ !(a op b) \endcode - as + as \code (a invob b) @@ -1776,16 +1799,16 @@ \endlist - \li <= < > >= == != + \li \c {<=}, \c {<}, \c {>}, \c {>=}, \c {==} or \c {!=} \row - \li Split Declaration - \li Splits a simple declaration into several declarations. For example, - rewrites: + \li Split Declaration + \li Splits a simple declaration into several declarations. For + example, rewrites: \code int *a, b; \endcode - as + as \code int *a; @@ -1793,14 +1816,16 @@ \endcode \li Type name or variable name \row - \li Split if Statement - \li Splits an if statement into several statements. For example, rewrites: + \li Split if Statement + \li Splits an if statement into several statements. For example, + rewrites: + \code if (something && something_else) { } \endcode - as + as \code if (something) { @@ -1809,14 +1834,14 @@ } \endcode - and + and \code if (something || something_else) x; \endcode - with + with \code if (something) @@ -1825,20 +1850,21 @@ x; \endcode - \li && || + \li \c && or \c || \row - \li Swap Operands - \li Rewrites an expression in the inverse order using the inverse operator. - For example, rewrites: + \li Swap Operands + \li Rewrites an expression in the inverse order using the inverse + operator. For example, rewrites: \code a op b \endcode - as + as \code b flipop a \endcode - \li <= < > >= == != && || + \li \c {<=}, \c {<}, \c {>}, \c {>=}, \c {==}, \c {!=}, \c {&&} + or \c {||} \row \li Convert to Decimal \li Converts an integer literal to decimal representation @@ -1852,9 +1878,10 @@ \li Converts an integer literal to octal representation \li Numeric literal \row - \li Convert to Objective-C String Literal - \li Converts a string literal to an Objective-C string literal - if the file type is Objective-C(++). For example, rewrites the following strings + \li Convert to Objective-C String Literal + \li Converts a string literal to an Objective-C string literal if + the file type is Objective-C(++). For example, rewrites the + following strings \code "abcd" @@ -1862,38 +1889,39 @@ QLatin1Literal("abcd") \endcode - as + as \code @"abcd" \endcode \li String literal \row - \li Enclose in QLatin1Char() - \li Sets the encoding for a character to Latin-1, unless the character is - already enclosed in QLatin1Char, QT_TRANSLATE_NOOP, tr, trUtf8, - QLatin1Literal, or QLatin1String. For example, rewrites + \li Enclose in QLatin1Char() + \li Sets the encoding for a character to Latin-1, unless the + character is already enclosed in QLatin1Char, QT_TRANSLATE_NOOP, + tr, trUtf8, QLatin1Literal, or QLatin1String. For example, + rewrites \code 'a' \endcode - as + as \code QLatin1Char('a') \endcode \li String literal \row - \li Enclose in QLatin1String() - \li Sets the encoding for a string to Latin-1, unless the string is - already enclosed in QLatin1Char, QT_TRANSLATE_NOOP, tr, trUtf8, - QLatin1Literal, or QLatin1String. For example, rewrites + \li Enclose in QLatin1String() + \li Sets the encoding for a string to Latin-1, unless the string is + already enclosed in QLatin1Char, QT_TRANSLATE_NOOP, tr, trUtf8, + QLatin1Literal, or QLatin1String. For example, rewrites \code "abcd" \endcode - as + as \code QLatin1String("abcd") @@ -1902,9 +1930,10 @@ \li String literal \row - \li Mark as Translatable - \li Marks a string translatable. For example, rewrites \c "abcd" with - one of the following options, depending on which of them is available: + \li Mark as Translatable + \li Marks a string translatable. For example, rewrites \c "abcd" + with one of the following options, depending on which of them is + available: \code tr("abcd") @@ -1915,12 +1944,15 @@ \li String literal \row - \li Add Definition in ... - \li Inserts a definition stub for a function declaration either in the header file - (inside or outside the class) or in the implementation file. For free functions, inserts - the definition after the declaration of the function or in the implementation file. - Qualified names are minimized when possible, instead of always being fully expanded. - For example, rewrites + \li Add Definition in ... + \li Inserts a definition stub for a function declaration either in + the header file (inside or outside the class) or in the + implementation file. For free functions, inserts the definition + after the declaration of the function or in the implementation + file. Qualified names are minimized when possible, instead of + always being fully expanded. + + For example, rewrites \code Class Foo { @@ -1928,7 +1960,7 @@ }; \endcode - as (inside class) + as (inside class) \code Class Foo { @@ -1938,7 +1970,7 @@ }; \endcode - as (outside class) + as (outside class) \code Class Foo { @@ -1951,7 +1983,7 @@ } \endcode - as (in implementation file) + as (in implementation file) \code // Header file @@ -1968,68 +2000,72 @@ \li Function name \row - \li Add 'Function' Declaration - \li Inserts the member function declaration that matches the member function - definition into the class declaration. The function can be public, - protected, private, public slot, protected slot, or private slot. - \li Function name + \li Add \c Function Declaration + \li Inserts the member function declaration that matches the member + function definition into the class declaration. The function can + be \c {public}, \c {protected}, \c {private}, \c {public slot}, + \c {protected slot}, or \c {private slot}. + \li Function name \row \li Switch with Next/Previous Parameter \li Moves a parameter down or up one position in a parameter list. \li Parameter in the declaration or definition of a function \row - \li Extract Function - \li Moves the selected code to a new function and replaces the block of - code with a call to the new function. Enter a name for the function in - the \uicontrol {Extract Function Refactoring} dialog. - \li Block of code selected + \li Extract Function + \li Moves the selected code to a new function and replaces the block + of code with a call to the new function. Enter a name for the + function in the \uicontrol {Extract Function Refactoring} + dialog. + \li Block of code selected \row - \li Extract Constant as Function Parameter - \li Replaces the selected literal and all its occurrences with the function parameter - \c{newParameter}. The parameter \c{newParameter} will have the original literal as the - default value. - \li Block of code selected + \li Extract Constant as Function Parameter + \li Replaces the selected literal and all its occurrences with the + function parameter \c{newParameter}. The parameter + \c{newParameter} will have the original literal as the default + value. + \li Block of code selected \row - \li Add Local Declaration - \li - Adds the type of an assignee, if the type of the right-hand side of the assignment - is known. For example, rewrites + \li Add Local Declaration + \li Adds the type of an assignee, if the type of the right-hand + side of the assignment is known. For example, rewrites \code a = foo(); \endcode - as + as \code Type a = foo(); \endcode - where Type is the return type of \c {foo()} + where Type is the return type of \c {foo()} \li Assignee \row - \li Convert to Camel Case - \li Converts a symbol name to camel case, where elements of the name are joined - without delimiter characters and the initial character of each element is - capitalized. For example, rewrites \c an_example_symbol - as \c anExampleSymbol and \c AN_EXAMPLE_SYMBOL as \c AnExampleSymbol - \li Identifier + \li Convert to Camel Case + \li Converts a symbol name to camel case, where elements of the name + are joined without delimiter characters and the initial + character of each element is capitalized. For example, rewrites + \c an_example_symbol as \c anExampleSymbol and + \c AN_EXAMPLE_SYMBOL as \c AnExampleSymbol + \li Identifier \row - \li Complete Switch Statement - \li Adds all possible cases to a switch statement of the type \c enum - \li Switch + \li Complete Switch Statement + \li Adds all possible cases to a switch statement of the type + \c enum + \li \c switch \row - \li Generate Missing Q_PROPERTY Members - \li Adds missing members to a Q_PROPERTY: + \li Generate Missing Q_PROPERTY Members + \li Adds missing members to a \c Q_PROPERTY: \list \li \c read function \li \c write function, if there is a WRITE \li \c {onChanged} signal, if there is a NOTIFY \li data member with the name \c {m_} \endlist - \li Q_PROPERTY + \li \c Q_PROPERTY \row \li Apply Changes \li Keeps function declarations and definitions synchronized by @@ -2037,44 +2073,45 @@ edit a function signature and by applying the changes to the matching code. \li Function signature. When this action is available, a light bulb - icon appears: - \inlineimage qml-toolbar-indicator.png + icon appears: \inlineimage qml-toolbar-indicator.png \row \li Add #include for undeclared or forward declared identifier - \li Adds an #include directive to the current file to make the + \li Adds an \c {#include} directive to the current file to make the definition of a symbol available. \li Undeclared identifier \row \li Reformat Pointers or References \li Reformats declarations with pointers or references according - to the code style settings for the current project. In case no - project is open, the current global code style settings are used. - For example, rewrites: + to the code style settings for the current project. In case no + project is open, the current global code style settings are + used. + + For example, rewrites: \code char*s; \endcode - as + as \code char *s; \endcode - When applied to selections, all suitable declarations in the selection are - rewritten. + When applied to selections, all suitable declarations in the + selection are rewritten. \li Declarations with pointers or references and selections - containing such declarations + containing such declarations \row - \li Create Getter and Setter Member Functions - \li Creates either both getter and setter member functions for member variables or - only a getter or setter. - \li Member variable in class definition + \li Create Getter and Setter Member Functions + \li Creates either both getter and setter member functions for + member variables or only a getter or setter. + \li Member variable in class definition \row \li Move Function Definition - \li Moves a function definition to the implementation file, outside the class or back to its declaration. For example, rewrites: - + \li Moves a function definition to the implementation file, outside + the class or back to its declaration. For example, rewrites: \code class Foo { @@ -2085,7 +2122,7 @@ }; \endcode - as + as \code class Foo { @@ -2100,8 +2137,8 @@ \li Function signature \row \li Move All Function Definitions - \li Moves all function definitions to the implementation file or outside the class. For example, rewrites: - + \li Moves all function definitions to the implementation file or + outside the class. For example, rewrites: \code class Foo { @@ -2116,7 +2153,8 @@ }; \endcode - as + as + \code class Foo { @@ -2136,22 +2174,29 @@ \li Class name \row \li Assign to Local Variable - \li Adds a local variable which stores the return value of a function call or a new expression. For example, rewrites: + \li Adds a local variable which stores the return value of a + function call or a new expression. For example, rewrites: \code QString s; s.loLatin1(); \endcode - as + + as + \code QString s; QByteArray latin1 = s.toLatin1(); \endcode - and + + and + \code new Foo; \endcode - as + + as + \code Foo * localFoo = new Foo; \endcode @@ -2172,83 +2217,97 @@ \li Class or base class name \row \li Optimize for-Loop - \li Rewrites post increment operators as pre increment operators and post decrement - operators as pre decrement operators. It also moves other than string or numeric - literals and id expressions from the condition of a for loop to its initializer. - For example, rewrites: + \li Rewrites post increment operators as pre increment operators and + post decrement operators as pre decrement operators. It also + moves other than string or numeric literals and id expressions + from the condition of a for loop to its initializer. For + example, rewrites: \code for (int i = 0; i < 3 * 2; i++) \endcode - as + + as + \code for (int i = 0, total = 3 * 2; i < total; ++i) \endcode - \li for + \li \c for \row \li Escape String Literal as UTF-8 - \li Escapes non-ASCII characters in a string literal to hexadecimal escape sequences. - String Literals are handled as UTF-8. + \li Escapes non-ASCII characters in a string literal to hexadecimal + escape sequences. String Literals are handled as UTF-8. \li String literal \row \li Unescape String Literal as UTF-8 - \li Unescapes octal or hexadecimal escape sequences in a string literal. - String Literals are handled as UTF-8. + \li Unescapes octal or hexadecimal escape sequences in a string + literal. String Literals are handled as UTF-8. \li String literal \row \li Convert to Stack Variable - \li Converts the selected pointer to a stack variable. For example, rewrites: + \li Converts the selected pointer to a stack variable. For example, + rewrites: + \code QByteArray *foo = new QByteArray("foo"); foo->append("bar"); \endcode - as + + as + \code QByteArray foo = "foo"; foo.append("bar"); \endcode - This operation is limited to work only within function scope. - Also, the coding style for pointers and references is not respected yet. + + This operation is limited to work only within function scope. + Also, the coding style for pointers and references is not + respected yet. \li Pointer Variable \row \li Convert to Pointer - \li Converts the selected stack variable to a pointer. For example, rewrites: + \li Converts the selected stack variable to a pointer. For example, + rewrites: + \code QByteArray foo = "foo"; foo.append("bar"); \endcode - as + + as + \code QByteArray *foo = new QByteArray("foo"); foo->append("bar"); \endcode - This operation is limited to work only within function scope. - Also, the coding style for pointers and references is not respected yet. + + This operation is limited to work only within function scope. + Also, the coding style for pointers and references is not + respected yet. \li Stack Variable - \row - \li Convert connect() to Qt 5 Style - \li Converts a Qt 4 \c QObject::connect() to Qt 5 style. - \li \c QObject::connect() (Qt 4 style) + \row + \li Convert connect() to Qt 5 Style + \li Converts a Qt 4 QObject::connect() to Qt 5 style. + \li QObject::connect() (Qt 4 style) \endtable - \section2 Refactoring QML Code + \section2 Refactoring QML Code - You can apply the following types of refactoring actions to QML code: + You can apply the following types of refactoring actions to QML code: - \list + \list \li Rename IDs \li Split initializers - \li Move a QML type into a separate file to reuse it in other - .qml files + \li Move a QML type into a separate file to reuse it in other .qml files - \endlist + \endlist The following table summarizes the refactoring actions for QML code. The action is available when the cursor is in the position described in the @@ -2261,18 +2320,19 @@ \li Activation \row - \li Move Component into 'filename.qml' + \li Move Component into \c filename.qml \li Moves a QML type into a separate file \li QML type name \row - \li Split Initializer - \li Reformats a one-line type into a multi-line type. For example, - rewrites + \li Split Initializer + \li Reformats a one-line type into a multi-line type. For example, + rewrites + \code Item { x: 10; y: 20; width: 10 } \endcode - as + as \code Item { @@ -2284,15 +2344,15 @@ \li QML type property \row - \li Wrap in Loader - \li Wraps the type in a Component type and loads it dynamically in - a Loader type. This is usually done to improve startup time. - \li QML type name + \li Wrap in Loader + \li Wraps the type in a Component type and loads it dynamically in a + Loader type. This is usually done to improve startup time. + \li QML type name \row - \li Add a message suppression comment - \li Prepends the line with an annotation comment that stops the message - from being generated. - \li Error, warning or hint from static analysis + \li Add a message suppression comment + \li Prepends the line with an annotation comment that stops the + message from being generated. + \li Error, warning or hint from static analysis \endtable */ @@ -2314,7 +2374,7 @@ \list - \li Press \key Ctrl+K (\key Cmd+K on OS X). + \li Press \key {Ctrl+K} (\key {Cmd+K} on OS X). \li Select \uicontrol Tools > \uicontrol Locate. @@ -2329,15 +2389,15 @@ \list 1 - \li Activate the locator by pressing \key Ctrl+K. + \li Activate the locator by pressing \key {Ctrl+K}. - \li Enter \tt{main.cpp}. + \li Enter \c {main.cpp}. \image qtcreator-locator-open.png \li Press \key Enter. - The main.cpp file opens in the editor. + The \c {main.cpp} file opens in the editor. \li To move to a line in the file, enter the line number in the locator. @@ -2360,9 +2420,9 @@ \list - \li To match any number of any or no characters, enter \b{*}. + \li To match any number of any or no characters, enter \c{*}. - \li To match a single instance of any character, enter \b{?}. + \li To match a single instance of any character, enter \c{?}. \endlist @@ -2373,32 +2433,32 @@ \list - \li Locating any open document (o) + \li Locating any open document (\c {o}) - \li Locating files anywhere on your file system (f) + \li Locating files anywhere on your file system (\c {f}) - \li Locating files belonging to your project (p), such as source, header - resource, and .ui files, or to any project (a) + \li Locating files belonging to your project (\c {p}), such as source, + header resource, and \c {.ui} files, or to any project (\c {a}) - \li Locating class (c), enum, and function (m) definitions in your - project or anywhere referenced from your project (:) + \li Locating class (\c {c}), enum, and function (m) definitions in your + project or anywhere referenced from your project (\c {:}) - \li Locating symbols in the current document (.) + \li Locating symbols in the current document (\c {.}) \li Locating a specific line and column in the document displayed in - your editor (l) + your editor (\c {l}) - \li Opening help topics, including Qt documentation (?) + \li Opening help topics, including Qt documentation (\c {?}) - \li Performing web searches (r) + \li Performing web searches (\c {r}) - \li Running text editing macros that you record and save (rm). For more - information, see \l{Using Text Editing Macros} + \li Running text editing macros that you record and save (\c {rm}). For + more information, see \l{Using Text Editing Macros} - \li Executing shell commands (!) + \li Executing shell commands (\c {!}) - \li Executing version control system commands (git). For more information, see - \l{Using Version Control Systems} + \li Executing version control system commands (\c {git}). For more + information, see \l{Using Version Control Systems} \endlist @@ -2412,7 +2472,7 @@ \li Activate the locator. - \li Enter \tt{\b{: QDataStream}} (: (colon) followed by a + \li Enter \c{: QDataStream} (\c{:} (colon) followed by a \key Space and the symbol name (QDataStream)). The locator lists the results. @@ -2434,16 +2494,16 @@ \list - \li Going to a line and column in the current file (l). + \li Going to a line and column in the current file (\c {l}). - \li Going to an open file (o). + \li Going to an open file (\c {o}). - \li Going to a file in any open project (a). + \li Going to a file in any open project (\c {a}). \endlist If locator does not find some files, you can add them to the \c DISTFILES - variable in the .pro file to include them into the distribution tarball + variable in the \c .pro file to include them into the distribution tarball of your project and thus make them known to \QC as well. \section1 Configuring Locator Filters @@ -2457,8 +2517,8 @@ \list 1 \li In the locator, click \inlineimage qtcreator-locator-magnify.png - (\uicontrol {Options}) and select \uicontrol Configure to open the \uicontrol Locator - options. + (\uicontrol Options) and select \uicontrol Configure to open the + \uicontrol Locator options. \li Select a filter, and then select \uicontrol Edit. @@ -2474,7 +2534,7 @@ \section2 Adding Web Search Engines - You can use the \uicontrol {Web Search (\c r)} locator filter to perform + You can use the \uicontrol {Web Search (r)} locator filter to perform web searches. URLs and search commands for Bing, Google, Yahoo! Search, cplusplus.com, and Wikipedia are configured by default. @@ -2487,16 +2547,16 @@ \list 1 - \li Select \uicontrol {Tools > Options > Environment > Locator > - Web Search (prefix: r) > - Edit}. + \li Select \uicontrol Tools > \uicontrol Options > + \uicontrol Environment > \uicontrol Locator > + \uicontrol {Web Search (prefix: r)} > \uicontrol Edit. \li Select \uicontrol Add to add a new entry to the list. \image qtcreator-add-online-doc.png "Filter Configuration dialog" \li Double-click the new entry to specify a URL and a search command. - For example, http://www.google.com/search?q=%1. + For example, \c {http://www.google.com/search?q=%1}. \li Click \uicontrol OK. @@ -2512,8 +2572,8 @@ \list 1 - \li In the locator, select \uicontrol {Options > Configure} to open the - \uicontrol Locator options. + \li In the locator, select \uicontrol Options > + \uicontrol Configure to open the \uicontrol Locator options. \image qtcreator-locator-customize.png @@ -2529,7 +2589,7 @@ recursively. \li Define the file pattern as a comma separated list. For example, - to search all .h and .cpp files, enter \b{*.h,*.cpp} + to search all \c {.h} and \c {.cpp} files, enter \c{*.h,*.cpp} \li Specify the prefix string. @@ -2540,29 +2600,29 @@ \endlist - \li Click OK. + \li Click \uicontrol OK. \endlist \section1 Configuring Locator Cache - The locator searches the files matching your file pattern in the - directories you have selected and caches that information. The cache for - all default filters is updated as you write your code. By default, - \QC updates the filters created by you once an hour. + The locator searches the files matching your file pattern in the directories + you have selected and caches that information. The cache for all default + filters is updated as you write your code. By default, \QC updates the + filters created by you once an hour. - To update the cached information manually, select \uicontrol {Options > Refresh} - in the locator. + To update the cached information manually, select \uicontrol Options > + \uicontrol Refresh in the locator. To set a new cache update time: \list 1 - \li Select \uicontrol {Tools > Options > Environment > Locator}. + \li Select \uicontrol Tools > \uicontrol Options > + \uicontrol Environment > \uicontrol Locator. \li In \uicontrol {Refresh interval}, define new time in minutes. \endlist */ - From 56f9729a103fb0774d6f673f0ccb3b30c6146a4b Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 23 Jun 2015 12:26:27 +0200 Subject: [PATCH 021/113] Git: Remove last user of Core::Id::fromUniqueIdentifier Change-Id: I049a89a17341205275f68b22fe18234c756dec78 Reviewed-by: Orgad Shaneh --- src/plugins/git/gitplugin.cpp | 119 ++++++++++++++++++---------------- src/plugins/git/gitplugin.h | 13 +++- 2 files changed, 74 insertions(+), 58 deletions(-) diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index e59b17a4527..b3f433dce56 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -241,11 +241,21 @@ QAction *GitPlugin::createRepositoryAction(ActionContainer *ac, QAction *GitPlugin::createRepositoryAction(ActionContainer *ac, const QString &text, Id id, const Context &context, bool addToLocator, - const char *pluginSlot, const QKeySequence &keys) + const std::function &callback, const QKeySequence &keys) { QAction *action = createRepositoryAction(ac, text, id, context, addToLocator, keys); - connect(action, SIGNAL(triggered()), this, pluginSlot); - action->setData(id.uniqueIdentifier()); + connect(action, &QAction::triggered, this, callback); + return action; +} + +QAction *GitPlugin::createChangeRelatedRepositoryAction(ActionContainer *ac, + const QString &text, Id id, + const Context &context, bool addToLocator, + const std::function &callback, + const QKeySequence &keys) +{ + QAction *action = createRepositoryAction(ac, text, id, context, addToLocator, keys); + connect(action, &QAction::triggered, this, [callback, id] { callback(id); }); return action; } @@ -360,18 +370,16 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) gitContainer->addMenu(localRepositoryMenu); createRepositoryAction(localRepositoryMenu, tr("Diff"), "Git.DiffRepository", - context, true, SLOT(diffRepository())); + context, true, [this] { diffRepository(); }); createRepositoryAction(localRepositoryMenu, tr("Log"), "Git.LogRepository", - context, true, - SLOT(logRepository())); + context, true, [this] { logRepository(); }); createRepositoryAction(localRepositoryMenu, tr("Reflog"), "Git.ReflogRepository", - context, true, - SLOT(reflogRepository())); + context, true, [this] { reflogRepository(); }); createRepositoryAction(localRepositoryMenu, tr("Clean..."), "Git.CleanRepository", - context, true, SLOT(cleanRepository())); + context, true, [this] { cleanRepository(); }); createRepositoryAction(localRepositoryMenu, tr("Status"), "Git.StatusRepository", context, true, &GitClient::status); @@ -380,75 +388,75 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) localRepositoryMenu->addSeparator(context); createRepositoryAction(localRepositoryMenu, tr("Commit..."), "Git.Commit", - context, true, SLOT(startCommit()), + context, true, [this] { startCommit(); }, QKeySequence(UseMacShortcuts ? tr("Meta+G,Meta+C") : tr("Alt+G,Alt+C"))); createRepositoryAction(localRepositoryMenu, tr("Amend Last Commit..."), "Git.AmendCommit", - context, true, SLOT(startAmendCommit())); + context, true, [this] { startAmendCommit(); }); m_fixupCommitAction = createRepositoryAction(localRepositoryMenu, tr("Fixup Previous Commit..."), "Git.FixupCommit", - context, true, SLOT(startFixupCommit())); + context, true, [this] { startFixupCommit(); }); // -------------- localRepositoryMenu->addSeparator(context); createRepositoryAction(localRepositoryMenu, tr("Reset..."), "Git.Reset", - context, true, SLOT(resetRepository())); + context, true, [this] { resetRepository(); }); m_interactiveRebaseAction = createRepositoryAction(localRepositoryMenu, tr("Interactive Rebase..."), "Git.InteractiveRebase", - context, true, SLOT(startRebase())); + context, true, [this] { startRebase(); }); m_submoduleUpdateAction = createRepositoryAction(localRepositoryMenu, tr("Update Submodules"), "Git.SubmoduleUpdate", - context, true, SLOT(updateSubmodules())); + context, true, [this] { updateSubmodules(); }); m_abortMergeAction = createRepositoryAction(localRepositoryMenu, tr("Abort Merge"), "Git.MergeAbort", - context, true, SLOT(continueOrAbortCommand())); + context, true, [this] { continueOrAbortCommand(); }); m_abortRebaseAction = createRepositoryAction(localRepositoryMenu, tr("Abort Rebase"), "Git.RebaseAbort", - context, true, SLOT(continueOrAbortCommand())); + context, true, [this] { continueOrAbortCommand(); }); m_abortCherryPickAction = createRepositoryAction(localRepositoryMenu, tr("Abort Cherry Pick"), "Git.CherryPickAbort", - context, true, SLOT(continueOrAbortCommand())); + context, true, [this] { continueOrAbortCommand(); }); m_abortRevertAction = createRepositoryAction(localRepositoryMenu, tr("Abort Revert"), "Git.RevertAbort", - context, true, SLOT(continueOrAbortCommand())); + context, true, [this] { continueOrAbortCommand(); }); m_continueRebaseAction = createRepositoryAction(localRepositoryMenu, tr("Continue Rebase"), "Git.RebaseContinue", - context, true, SLOT(continueOrAbortCommand())); + context, true, [this] { continueOrAbortCommand(); }); m_continueCherryPickAction = createRepositoryAction(localRepositoryMenu, tr("Continue Cherry Pick"), "Git.CherryPickContinue", - context, true, SLOT(continueOrAbortCommand())); + context, true, [this] { continueOrAbortCommand(); }); m_continueRevertAction = createRepositoryAction(localRepositoryMenu, tr("Continue Revert"), "Git.RevertContinue", - context, true, SLOT(continueOrAbortCommand())); + context, true, [this] { continueOrAbortCommand(); }); // -------------- localRepositoryMenu->addSeparator(context); createRepositoryAction(localRepositoryMenu, tr("Branches..."), "Git.BranchList", - context, true, SLOT(branchList())); + context, true, [this] { branchList(); }); // -------------- localRepositoryMenu->addSeparator(context); @@ -465,12 +473,12 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) "Git.ApplyCurrentFilePatch", context, true); - connect(m_applyCurrentFilePatchAction, SIGNAL(triggered()), this, - SLOT(applyCurrentFilePatch())); + connect(m_applyCurrentFilePatchAction, &QAction::triggered, + this, &GitPlugin::applyCurrentFilePatch); createRepositoryAction(patchMenu, tr("Apply from File..."), "Git.ApplyPatch", - context, true, SLOT(promptApplyPatch())); + context, true, [this] { promptApplyPatch(); }); // "Stash" menu ActionContainer *stashMenu = ActionManager::createMenu("Git.StashMenu"); @@ -479,27 +487,27 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) createRepositoryAction(stashMenu, tr("Stashes..."), "Git.StashList", - context, false, SLOT(stashList())); + context, false, [this] { stashList(); }); stashMenu->addSeparator(context); QAction *action = createRepositoryAction(stashMenu, tr("Stash"), "Git.Stash", - context, true, SLOT(stash())); + context, true, [this] { stash(); }); action->setToolTip(tr("Saves the current state of your work and resets the repository.")); action = createRepositoryAction(stashMenu, tr("Stash Unstaged Files"), "Git.StashUnstaged", - context, true, SLOT(stashUnstaged())); + context, true, [this] { stashUnstaged(); }); action->setToolTip(tr("Saves the current state of your unstaged files and resets the repository " "to its staged state.")); action = createRepositoryAction(stashMenu, tr("Take Snapshot..."), "Git.StashSnapshot", - context, true, SLOT(stashSnapshot())); + context, true, [this] { stashSnapshot(); }); action->setToolTip(tr("Saves the current state of your work.")); stashMenu->addSeparator(context); action = createRepositoryAction(stashMenu, tr("Stash Pop"), "Git.StashPop", - context, true, SLOT(stashPop())); + context, true, [this] { stashPop(); }); action->setToolTip(tr("Restores changes saved to the stash list using \"Stash\".")); @@ -513,13 +521,13 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) gitContainer->addMenu(remoteRepositoryMenu); createRepositoryAction(remoteRepositoryMenu, tr("Fetch"), "Git.Fetch", - context, true, SLOT(fetch())); + context, true, [this] { fetch(); }); createRepositoryAction(remoteRepositoryMenu, tr("Pull"), "Git.Pull", - context, true, SLOT(pull())); + context, true, [this] { pull(); }); createRepositoryAction(remoteRepositoryMenu, tr("Push"), "Git.Push", - context, true, SLOT(push())); + context, true, [this] { push(); }); // -------------- remoteRepositoryMenu->addSeparator(context); @@ -542,30 +550,31 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) createRepositoryAction(remoteRepositoryMenu, tr("Manage Remotes..."), "Git.RemoteList", - context, false, SLOT(remoteList())); + context, false, [this] { remoteList(); }); /* \"Remote Repository" menu */ // -------------- /* Actions only in locator */ - createRepositoryAction(0, tr("Show..."), "Git.Show", - context, true, SLOT(startChangeRelatedAction())); + const auto startChangeRelated = [this](Id id) { startChangeRelatedAction(id); }; + createChangeRelatedRepositoryAction(0, tr("Show..."), "Git.Show", + context, true, startChangeRelated); - createRepositoryAction(0, tr("Revert..."), "Git.Revert", - context, true, SLOT(startChangeRelatedAction())); + createChangeRelatedRepositoryAction(0, tr("Revert..."), "Git.Revert", + context, true, startChangeRelated); - createRepositoryAction(0, tr("Cherry Pick..."), "Git.CherryPick", - context, true, SLOT(startChangeRelatedAction())); + createChangeRelatedRepositoryAction(0, tr("Cherry Pick..."), "Git.CherryPick", + context, true, startChangeRelated); - createRepositoryAction(0, tr("Checkout..."), "Git.Checkout", - context, true, SLOT(startChangeRelatedAction())); + createChangeRelatedRepositoryAction(0, tr("Checkout..."), "Git.Checkout", + context, true, startChangeRelated); createRepositoryAction(0, tr("Rebase..."), "Git.Rebase", - context, true, SLOT(branchList())); + context, true, [this] { branchList(); }); createRepositoryAction(0, tr("Merge..."), "Git.Merge", - context, true, SLOT(branchList())); + context, true, [this] { branchList(); }); /* \Actions only in locator */ @@ -590,7 +599,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) gitToolsMenu->addSeparator(context); createRepositoryAction(gitToolsMenu, tr("Git Gui"), "Git.GitGui", - context, true, SLOT(gitGui())); + context, true, [this] { gitGui(); }); // -------------- gitToolsMenu->addSeparator(context); @@ -603,7 +612,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) m_mergeToolAction = createRepositoryAction(gitToolsMenu, tr("Merge Tool"), "Git.MergeTool", - context, true, SLOT(startMergeTool())); + context, true, [this] { startMergeTool(); }); /* \"Git Tools" menu */ @@ -611,7 +620,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) gitContainer->addSeparator(context); createRepositoryAction(gitContainer, tr("Actions on Commits..."), "Git.ChangeActions", - context, false, SLOT(startChangeRelatedAction())); + context, false, [this] { startChangeRelatedAction("Git.ChangeActions"); }); m_createRepositryAction = new QAction(tr("Create Repository..."), this); Command *createRepositoryCommand = ActionManager::registerAction( @@ -624,7 +633,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) m_submitCurrentAction = new QAction(VcsBaseSubmitEditor::submitIcon(), tr("Commit"), this); Command *command = ActionManager::registerAction(m_submitCurrentAction, Constants::SUBMIT_CURRENT, submitContext); command->setAttribute(Command::CA_UpdateText); - connect(m_submitCurrentAction, SIGNAL(triggered()), this, SLOT(submitCurrentLog())); + connect(m_submitCurrentAction, &QAction::triggered, this, &GitPlugin::submitCurrentLog); m_diffSelectedFilesAction = new QAction(VcsBaseSubmitEditor::diffIcon(), tr("Diff &Selected Files"), this); ActionManager::registerAction(m_diffSelectedFilesAction, Constants::DIFF_SELECTED, submitContext); @@ -635,10 +644,10 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) m_redoAction = new QAction(tr("&Redo"), this); ActionManager::registerAction(m_redoAction, Core::Constants::REDO, submitContext); - connect(VcsManager::instance(), SIGNAL(repositoryChanged(QString)), - this, SLOT(updateContinueAndAbortCommands())); - connect(VcsManager::instance(), SIGNAL(repositoryChanged(QString)), - this, SLOT(updateBranches(QString)), Qt::QueuedConnection); + connect(VcsManager::instance(), &VcsManager::repositoryChanged, + this, &GitPlugin::updateContinueAndAbortCommands); + connect(VcsManager::instance(), &VcsManager::repositoryChanged, + this, &GitPlugin::updateBranches, Qt::QueuedConnection); Utils::MimeDatabase::addMimeTypes(QLatin1String(RC_GIT_MIME_XML)); @@ -804,14 +813,12 @@ void GitPlugin::startRebase() m_gitClient->interactiveRebase(topLevel, dialog.commit(), false); } -void GitPlugin::startChangeRelatedAction() +void GitPlugin::startChangeRelatedAction(const Id &id) { const VcsBasePluginState state = currentState(); if (!state.hasTopLevel()) return; - QAction *action = qobject_cast(sender()); - Id id = action ? Id::fromUniqueIdentifier(action->data().toInt()) : Id(); ChangeSelectionDialog dialog(state.topLevel(), id, ICore::mainWindow()); int result = dialog.exec(); diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index d2219a535be..4f053539cef 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -33,6 +33,8 @@ #include "gitsettings.h" +#include + #include #include @@ -40,6 +42,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE class QFile; class QAction; @@ -108,7 +112,7 @@ private slots: void undoUnstagedFileChanges(); void resetRepository(); void startRebase(); - void startChangeRelatedAction(); + void startChangeRelatedAction(const Core::Id &id); void stageFile(); void unstageFile(); void gitkForCurrentFile(); @@ -178,8 +182,13 @@ private: QAction *createRepositoryAction(Core::ActionContainer *ac, const QString &text, Core::Id id, const Core::Context &context, - bool addToLocator, const char *pluginSlot, + bool addToLocator, const std::function &callback, const QKeySequence &keys = QKeySequence()); + QAction *createChangeRelatedRepositoryAction(Core::ActionContainer *ac, + const QString &text, Core::Id id, + const Core::Context &context, + bool addToLocator, const std::function &callback, + const QKeySequence &keys = QKeySequence()); QAction *createRepositoryAction(Core::ActionContainer *ac, const QString &text, Core::Id id, const Core::Context &context, From f8bc4938603c2f7a277477a4e46870907117fa6b Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 23 Jun 2015 15:21:22 +0200 Subject: [PATCH 022/113] Doc: Polish creating plugins Change-Id: If0692c978e566797391b1a553a76343e605cd2b8 Reviewed-by: Leena Miettinen --- doc/api/creating-plugins.qdoc | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/doc/api/creating-plugins.qdoc b/doc/api/creating-plugins.qdoc index 41b4ce8a3d8..f0e23100063 100644 --- a/doc/api/creating-plugins.qdoc +++ b/doc/api/creating-plugins.qdoc @@ -20,29 +20,31 @@ \page creating-plugins.html \title Creating Plugins - At its very core, \QC consists of a plugin loader that loads - and runs a set of plugins, which then actually provide the functionality - that you know from \QC the IDE. So, even the main application window - and menus are all provided by plugins. Plugins can use different means - to provide other plugins access to their functionality and to allow them - to extend certain aspects of the application. + At its very core, \QC consists of a plugin loader that loads and runs a set + of plugins, which then actually provide the functionality that you know from + \QC the IDE. So, even the main application window and menus are all provided + by plugins. Plugins can use different means to provide other plugins access + to their functionality and to allow them to extend certain aspects of the + application. - For example the "Core" plugin, which is the very basic plugin that must be + For example the \c Core plugin, which is the very basic plugin that must be present for \QC to run at all, provides the main window itself, and API for adding menu items, modes, editor types, navigation panels and many other things. - The "TextEditor" plugin provides a framework and base implementation for - different text editors with highlighting, completion and folding, that - is then used by other plugins to add more specialized text editor types - to \QC, like for editing C/C++ or .pro files. + + The \c TextEditor plugin provides a framework and base implementation for + different text editors with highlighting, completion and folding, that is + then used by other plugins to add more specialized text editor types to \QC, + like for editing C/C++ or \c {.pro} files. After reading this guide you will know what a basic plugin consists of, how to write a plugin specification file, what the lifecycle of a plugin is, - what the general principles for extending existing plugins' - functionality and providing interfaces for other plugins are, and will - be able to write your first plugin. + what the general principles for extending existing plugins' functionality + and providing interfaces for other plugins are, and will be able to write + your first plugin. \section1 Basics + \list \li \l{Getting and Building Qt Creator} \li \l{Creating Your First Plugin} @@ -51,6 +53,7 @@ \endlist \section1 Design Principles + \list \li \l{The Plugin Manager, the Object Pool, and Registered Objects} \li \l{Aggregations} @@ -58,6 +61,7 @@ \endlist \section1 Creating 3rd-Party Plugins + \list \li \l{A Note on Binary Compatibility} \li \l{Creating User-Installable Plugins} From 94756d42c204130909568fa981383be4b16680ff Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 23 Jun 2015 15:21:55 +0200 Subject: [PATCH 023/113] WS only change Change-Id: I922969db94e005fdbcdae74f0b6c78b1707f85e6 Reviewed-by: Leena Miettinen --- doc/api/creating-plugins.qdoc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/api/creating-plugins.qdoc b/doc/api/creating-plugins.qdoc index f0e23100063..aaa9a009a06 100644 --- a/doc/api/creating-plugins.qdoc +++ b/doc/api/creating-plugins.qdoc @@ -46,24 +46,24 @@ \section1 Basics \list - \li \l{Getting and Building Qt Creator} - \li \l{Creating Your First Plugin} - \li \l{Plugin Meta Data} - \li \l{Plugin Life Cycle} + \li \l{Getting and Building Qt Creator} + \li \l{Creating Your First Plugin} + \li \l{Plugin Meta Data} + \li \l{Plugin Life Cycle} \endlist \section1 Design Principles \list - \li \l{The Plugin Manager, the Object Pool, and Registered Objects} - \li \l{Aggregations} - \li \l{Extending and Providing Interfaces} + \li \l{The Plugin Manager, the Object Pool, and Registered Objects} + \li \l{Aggregations} + \li \l{Extending and Providing Interfaces} \endlist \section1 Creating 3rd-Party Plugins \list - \li \l{A Note on Binary Compatibility} - \li \l{Creating User-Installable Plugins} + \li \l{A Note on Binary Compatibility} + \li \l{Creating User-Installable Plugins} \endlist */ From 995e3d9802fe3e281e0a417175b5391df454c5a2 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Tue, 23 Jun 2015 17:55:55 +0300 Subject: [PATCH 024/113] Git: Suppress output for submodule status It is internal, no reason to expose it. Change-Id: I7612cfa58cefa22b63635cab66498186b390da8b Reviewed-by: Tobias Hunger --- src/plugins/git/gitclient.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index dab7251a34e..2730fa108ad 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -1739,7 +1739,8 @@ QStringList GitClient::synchronousSubmoduleStatus(const QString &workingDirector // get submodule status arguments << QLatin1String("submodule") << QLatin1String("status"); - if (!vcsFullySynchronousExec(workingDirectory, arguments, &outputTextData, &errorText)) { + if (!vcsFullySynchronousExec(workingDirectory, arguments, &outputTextData, &errorText, + silentFlags)) { msgCannotRun(tr("Cannot retrieve submodule status of \"%1\": %2") .arg(QDir::toNativeSeparators(workingDirectory), commandOutputFromLocal8Bit(errorText)), errorMessage); From a73ad816a36cb2bb2391f68f1c79b01d6e6f7ec5 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 18 Jun 2015 15:14:06 +0200 Subject: [PATCH 025/113] QMakeProjectManager: Introduce member initialization. Change-Id: I69df0c22a215b2df12f63fdc47082e9797fc02ac Reviewed-by: Daniel Teske --- .../qmakeprojectmanager/addlibrarywizard.cpp | 2 +- .../qmakeprojectmanager/addlibrarywizard.h | 24 +++++------ .../desktopqmakerunconfiguration.cpp | 9 +---- .../desktopqmakerunconfiguration.h | 32 +++++++-------- .../qmakeprojectmanager/externaleditors.cpp | 3 +- .../qmakeprojectmanager/externaleditors.h | 2 +- .../librarydetailscontroller.cpp | 12 ------ .../librarydetailscontroller.h | 21 +++++----- .../qmakeprojectmanager/makefileparse.h | 14 ++----- src/plugins/qmakeprojectmanager/makestep.cpp | 8 ++-- src/plugins/qmakeprojectmanager/makestep.h | 12 +++--- .../profilecompletionassist.cpp | 3 -- .../profilecompletionassist.h | 1 - .../qmakeprojectmanager/profileeditor.cpp | 5 --- .../profilehoverhandler.cpp | 2 +- .../qmakeprojectmanager/profilehoverhandler.h | 2 +- .../qmakebuildconfiguration.cpp | 12 +----- .../qmakebuildconfiguration.h | 10 ++--- .../qmakeprojectmanager/qmakebuildinfo.h | 2 +- .../qmakekitconfigwidget.cpp | 3 +- .../qmakekitconfigwidget.h | 4 +- .../qmakeprojectmanager/qmakenodes.cpp | 20 ++-------- src/plugins/qmakeprojectmanager/qmakenodes.h | 36 +++++------------ .../qmakeprojectmanager/qmakeproject.cpp | 11 +---- .../qmakeprojectmanager/qmakeproject.h | 24 +++++------ .../qmakeprojectconfigwidget.cpp | 3 +- .../qmakeprojectconfigwidget.h | 2 +- .../qmakeprojectmanager.cpp | 7 ---- .../qmakeprojectmanager/qmakeprojectmanager.h | 7 ++-- .../qmakeprojectmanagerplugin.cpp | 6 --- .../qmakeprojectmanagerplugin.h | 33 ++++++++------- src/plugins/qmakeprojectmanager/qmakestep.cpp | 16 ++------ src/plugins/qmakeprojectmanager/qmakestep.h | 40 +++++++------------ 33 files changed, 137 insertions(+), 251 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp b/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp index c499e2e38a9..3b176e1db06 100644 --- a/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp +++ b/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp @@ -190,7 +190,7 @@ AddLibraryWizard::LibraryKind LibraryTypePage::libraryKind() const ///////////// DetailsPage::DetailsPage(AddLibraryWizard *parent) - : QWizardPage(parent), m_libraryWizard(parent), m_libraryDetailsController(0) + : QWizardPage(parent), m_libraryWizard(parent) { m_libraryDetailsWidget = new Ui::LibraryDetailsWidget(); m_libraryDetailsWidget->setupUi(this); diff --git a/src/plugins/qmakeprojectmanager/addlibrarywizard.h b/src/plugins/qmakeprojectmanager/addlibrarywizard.h index 624eff7e6dd..ab92fa98da2 100644 --- a/src/plugins/qmakeprojectmanager/addlibrarywizard.h +++ b/src/plugins/qmakeprojectmanager/addlibrarywizard.h @@ -93,9 +93,9 @@ public: signals: private: - LibraryTypePage *m_libraryTypePage; - DetailsPage *m_detailsPage; - SummaryPage *m_summaryPage; + LibraryTypePage *m_libraryTypePage = nullptr; + DetailsPage *m_detailsPage = nullptr; + SummaryPage *m_summaryPage = nullptr; QString m_proFile; }; @@ -109,10 +109,10 @@ public: AddLibraryWizard::LibraryKind libraryKind() const; private: - QRadioButton *m_internalRadio; - QRadioButton *m_externalRadio; - QRadioButton *m_systemRadio; - QRadioButton *m_packageRadio; + QRadioButton *m_internalRadio = nullptr; + QRadioButton *m_externalRadio = nullptr; + QRadioButton *m_systemRadio = nullptr; + QRadioButton *m_packageRadio = nullptr; }; class DetailsPage : public QWizardPage @@ -126,8 +126,8 @@ public: private: AddLibraryWizard *m_libraryWizard; - Ui::LibraryDetailsWidget *m_libraryDetailsWidget; - LibraryDetailsController *m_libraryDetailsController; + Ui::LibraryDetailsWidget *m_libraryDetailsWidget = nullptr; + LibraryDetailsController *m_libraryDetailsController = nullptr; }; class SummaryPage : public QWizardPage @@ -138,9 +138,9 @@ public: virtual void initializePage(); QString snippet() const; private: - AddLibraryWizard *m_libraryWizard; - QLabel *m_summaryLabel; - QLabel *m_snippetLabel; + AddLibraryWizard *m_libraryWizard = nullptr; + QLabel *m_summaryLabel = nullptr; + QLabel *m_snippetLabel = nullptr; QString m_snippet; }; diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp index d9a2515f5a9..37c66380cb9 100644 --- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp @@ -83,9 +83,7 @@ static Utils::FileName pathFromId(Core::Id id) DesktopQmakeRunConfiguration::DesktopQmakeRunConfiguration(Target *parent, Core::Id id) : LocalApplicationRunConfiguration(parent, id), - m_proFilePath(pathFromId(id)), - m_runMode(ApplicationLauncher::Gui), - m_isUsingDyldImageSuffix(false) + m_proFilePath(pathFromId(id)) { addExtraAspect(new ProjectExplorer::LocalEnvironmentAspect(this)); @@ -174,10 +172,7 @@ void DesktopQmakeRunConfiguration::ctor() DesktopQmakeRunConfigurationWidget::DesktopQmakeRunConfigurationWidget(DesktopQmakeRunConfiguration *qmakeRunConfiguration, QWidget *parent) : QWidget(parent), - m_qmakeRunConfiguration(qmakeRunConfiguration), - m_ignoreChange(false), - m_usingDyldImageSuffix(0), - m_isShown(false) + m_qmakeRunConfiguration(qmakeRunConfiguration) { QVBoxLayout *vboxTopLayout = new QVBoxLayout(this); vboxTopLayout->setMargin(0); diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h index d1e23c20372..6778ec6d0a8 100644 --- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h +++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h @@ -128,11 +128,11 @@ private: Utils::FileName m_proFilePath; // Full path to the Application Pro File // Cached startup sub project information - ProjectExplorer::ApplicationLauncher::Mode m_runMode; - bool m_isUsingDyldImageSuffix; + ProjectExplorer::ApplicationLauncher::Mode m_runMode = ProjectExplorer::ApplicationLauncher::Gui; + bool m_isUsingDyldImageSuffix = false; QString m_userWorkingDirectory; - bool m_parseSuccess; - bool m_parseInProgress; + bool m_parseSuccess = false; + bool m_parseInProgress = false; }; class DesktopQmakeRunConfigurationWidget : public QWidget @@ -165,19 +165,19 @@ private slots: void usingDyldImageSuffixChanged(bool); private: - DesktopQmakeRunConfiguration *m_qmakeRunConfiguration; - bool m_ignoreChange; - QLabel *m_disabledIcon; - QLabel *m_disabledReason; - QLabel *m_executableLineLabel; - Utils::PathChooser *m_workingDirectoryEdit; - QLineEdit *m_argumentsLineEdit; - QCheckBox *m_useTerminalCheck; - QCheckBox *m_useQvfbCheck; - QCheckBox *m_usingDyldImageSuffix; - QLineEdit *m_qmlDebugPort; + DesktopQmakeRunConfiguration *m_qmakeRunConfiguration = nullptr; + bool m_ignoreChange = false; + QLabel *m_disabledIcon = nullptr; + QLabel *m_disabledReason = nullptr; + QLabel *m_executableLineLabel = nullptr; + Utils::PathChooser *m_workingDirectoryEdit = nullptr; + QLineEdit *m_argumentsLineEdit = nullptr; + QCheckBox *m_useTerminalCheck = nullptr; + QCheckBox *m_useQvfbCheck = nullptr; + QCheckBox *m_usingDyldImageSuffix = nullptr; + QLineEdit *m_qmlDebugPort = nullptr; Utils::DetailsWidget *m_detailsContainer; - bool m_isShown; + bool m_isShown = false; }; class DesktopQmakeRunConfigurationFactory : public QmakeRunConfigurationFactory diff --git a/src/plugins/qmakeprojectmanager/externaleditors.cpp b/src/plugins/qmakeprojectmanager/externaleditors.cpp index e77bee6c852..58d3b80f083 100644 --- a/src/plugins/qmakeprojectmanager/externaleditors.cpp +++ b/src/plugins/qmakeprojectmanager/externaleditors.cpp @@ -210,8 +210,7 @@ DesignerExternalEditor::DesignerExternalEditor(QObject *parent) : ExternalQtEditor(designerIdC, QLatin1String(designerDisplayName), QLatin1String(Designer::Constants::FORM_MIMETYPE), - parent), - m_terminationMapper(0) + parent) { } diff --git a/src/plugins/qmakeprojectmanager/externaleditors.h b/src/plugins/qmakeprojectmanager/externaleditors.h index d5c4e6aefeb..b922dcdce78 100644 --- a/src/plugins/qmakeprojectmanager/externaleditors.h +++ b/src/plugins/qmakeprojectmanager/externaleditors.h @@ -139,7 +139,7 @@ private: typedef QMap ProcessCache; ProcessCache m_processCache; - QSignalMapper *m_terminationMapper; + QSignalMapper *m_terminationMapper = nullptr; }; } // namespace Internal diff --git a/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp b/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp index 3dfb8fd040b..286745f94c4 100644 --- a/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp +++ b/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp @@ -54,19 +54,7 @@ LibraryDetailsController::LibraryDetailsController( Ui::LibraryDetailsWidget *libraryDetails, const QString &proFile, QObject *parent) : QObject(parent), - m_platforms(AddLibraryWizard::LinuxPlatform - | AddLibraryWizard::MacPlatform - | AddLibraryWizard::WindowsMinGWPlatform - | AddLibraryWizard::WindowsMSVCPlatform), - m_linkageType(AddLibraryWizard::NoLinkage), - m_macLibraryType(AddLibraryWizard::NoLibraryType), m_proFile(proFile), - m_ignoreGuiSignals(false), - m_includePathChanged(false), - m_linkageRadiosVisible(true), - m_macLibraryRadiosVisible(true), - m_includePathVisible(true), - m_windowsGroupVisible(true), m_libraryDetailsWidget(libraryDetails) { switch (Utils::HostOsInfo::hostOs()) { diff --git a/src/plugins/qmakeprojectmanager/librarydetailscontroller.h b/src/plugins/qmakeprojectmanager/librarydetailscontroller.h index af99a145110..41a6591bf00 100644 --- a/src/plugins/qmakeprojectmanager/librarydetailscontroller.h +++ b/src/plugins/qmakeprojectmanager/librarydetailscontroller.h @@ -104,21 +104,24 @@ private: void showLinkageType(AddLibraryWizard::LinkageType linkageType); void showMacLibraryType(AddLibraryWizard::MacLibraryType libType); - AddLibraryWizard::Platforms m_platforms; - AddLibraryWizard::LinkageType m_linkageType; - AddLibraryWizard::MacLibraryType m_macLibraryType; + AddLibraryWizard::Platforms m_platforms = AddLibraryWizard::LinuxPlatform + | AddLibraryWizard::MacPlatform + | AddLibraryWizard::WindowsMinGWPlatform + | AddLibraryWizard::WindowsMSVCPlatform; + AddLibraryWizard::LinkageType m_linkageType = AddLibraryWizard::NoLinkage; + AddLibraryWizard::MacLibraryType m_macLibraryType = AddLibraryWizard::NoLibraryType; QString m_proFile; CreatorPlatform m_creatorPlatform; - bool m_ignoreGuiSignals; - bool m_includePathChanged; + bool m_ignoreGuiSignals = false; + bool m_includePathChanged = false; - bool m_linkageRadiosVisible; - bool m_macLibraryRadiosVisible; - bool m_includePathVisible; - bool m_windowsGroupVisible; + bool m_linkageRadiosVisible = true; + bool m_macLibraryRadiosVisible = true; + bool m_includePathVisible = true; + bool m_windowsGroupVisible = true; Ui::LibraryDetailsWidget *m_libraryDetailsWidget; }; diff --git a/src/plugins/qmakeprojectmanager/makefileparse.h b/src/plugins/qmakeprojectmanager/makefileparse.h index a5690929aa7..a7da0746fb7 100644 --- a/src/plugins/qmakeprojectmanager/makefileparse.h +++ b/src/plugins/qmakeprojectmanager/makefileparse.h @@ -75,16 +75,10 @@ private: class QmakeBuildConfig { public: - QmakeBuildConfig() - : explicitDebug(false), - explicitRelease(false), - explicitBuildAll(false), - explicitNoBuildAll(false) - {} - bool explicitDebug; - bool explicitRelease; - bool explicitBuildAll; - bool explicitNoBuildAll; + bool explicitDebug = false; + bool explicitRelease = false; + bool explicitBuildAll = false; + bool explicitNoBuildAll = false; }; MakefileState m_state; diff --git a/src/plugins/qmakeprojectmanager/makestep.cpp b/src/plugins/qmakeprojectmanager/makestep.cpp index cd64af84f83..b6991cf1bf3 100644 --- a/src/plugins/qmakeprojectmanager/makestep.cpp +++ b/src/plugins/qmakeprojectmanager/makestep.cpp @@ -63,8 +63,7 @@ const char CLEAN_KEY[] = "Qt4ProjectManager.MakeStep.Clean"; } MakeStep::MakeStep(BuildStepList *bsl) : - AbstractProcessStep(bsl, Core::Id(MAKESTEP_BS_ID)), - m_clean(false) + AbstractProcessStep(bsl, Core::Id(MAKESTEP_BS_ID)) { ctor(); } @@ -79,8 +78,7 @@ MakeStep::MakeStep(BuildStepList *bsl, MakeStep *bs) : } MakeStep::MakeStep(BuildStepList *bsl, Core::Id id) : - AbstractProcessStep(bsl, id), - m_clean(false) + AbstractProcessStep(bsl, id) { ctor(); } @@ -314,7 +312,7 @@ void MakeStep::setUserArguments(const QString &arguments) } MakeStepConfigWidget::MakeStepConfigWidget(MakeStep *makeStep) - : BuildStepConfigWidget(), m_ui(new Internal::Ui::MakeStep), m_makeStep(makeStep), m_bc(0), m_ignoreChange(false) + : BuildStepConfigWidget(), m_ui(new Internal::Ui::MakeStep), m_makeStep(makeStep) { m_ui->setupUi(this); diff --git a/src/plugins/qmakeprojectmanager/makestep.h b/src/plugins/qmakeprojectmanager/makestep.h index a334ff4f62f..7586d989f92 100644 --- a/src/plugins/qmakeprojectmanager/makestep.h +++ b/src/plugins/qmakeprojectmanager/makestep.h @@ -109,8 +109,8 @@ private: void ctor(); void setMakeCommand(const QString &make); QStringList automaticallyAddedArguments() const; - bool m_clean; - bool m_scriptTarget; + bool m_clean = false; + bool m_scriptTarget = false; QString m_makeFileToCheck; QString m_userArgs; QString m_makeCmd; @@ -136,11 +136,11 @@ private slots: private: void setSummaryText(const QString &text); - Internal::Ui::MakeStep *m_ui; - MakeStep *m_makeStep; + Internal::Ui::MakeStep *m_ui = nullptr; + MakeStep *m_makeStep = nullptr; QString m_summaryText; - ProjectExplorer::BuildConfiguration *m_bc; - bool m_ignoreChange; + ProjectExplorer::BuildConfiguration *m_bc = nullptr; + bool m_ignoreChange = false; }; } // QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/profilecompletionassist.cpp b/src/plugins/qmakeprojectmanager/profilecompletionassist.cpp index 36407376d4f..297043116fe 100644 --- a/src/plugins/qmakeprojectmanager/profilecompletionassist.cpp +++ b/src/plugins/qmakeprojectmanager/profilecompletionassist.cpp @@ -317,9 +317,6 @@ static const char *const functionKeywords[] = { // ------------------------------- // ProFileCompletionAssistProvider // ------------------------------- -ProFileCompletionAssistProvider::ProFileCompletionAssistProvider() -{} - void ProFileCompletionAssistProvider::init() { for (uint i = 0; i < sizeof variableKeywords / sizeof variableKeywords[0] - 1; i++) diff --git a/src/plugins/qmakeprojectmanager/profilecompletionassist.h b/src/plugins/qmakeprojectmanager/profilecompletionassist.h index 2ef25165a73..8ea39767666 100644 --- a/src/plugins/qmakeprojectmanager/profilecompletionassist.h +++ b/src/plugins/qmakeprojectmanager/profilecompletionassist.h @@ -43,7 +43,6 @@ class ProFileCompletionAssistProvider : public TextEditor::CompletionAssistProvi Q_OBJECT public: - ProFileCompletionAssistProvider(); void init(); ~ProFileCompletionAssistProvider(); diff --git a/src/plugins/qmakeprojectmanager/profileeditor.cpp b/src/plugins/qmakeprojectmanager/profileeditor.cpp index e57ef27cc67..41a0d303bb3 100644 --- a/src/plugins/qmakeprojectmanager/profileeditor.cpp +++ b/src/plugins/qmakeprojectmanager/profileeditor.cpp @@ -58,11 +58,6 @@ namespace Internal { class ProFileEditorWidget : public TextEditorWidget { -public: - ProFileEditorWidget() - { - } - protected: virtual Link findLinkAt(const QTextCursor &, bool resolveTarget = true, bool inNextSplit = false) override; diff --git a/src/plugins/qmakeprojectmanager/profilehoverhandler.cpp b/src/plugins/qmakeprojectmanager/profilehoverhandler.cpp index 7f094f64a0e..f7d875778a7 100644 --- a/src/plugins/qmakeprojectmanager/profilehoverhandler.cpp +++ b/src/plugins/qmakeprojectmanager/profilehoverhandler.cpp @@ -45,7 +45,7 @@ namespace QmakeProjectManager { namespace Internal { ProFileHoverHandler::ProFileHoverHandler(const TextEditor::Keywords &keywords) - : m_manualKind(UnknownManual), m_keywords(keywords) + : m_keywords(keywords) { } diff --git a/src/plugins/qmakeprojectmanager/profilehoverhandler.h b/src/plugins/qmakeprojectmanager/profilehoverhandler.h index 9b13c3c490b..1271c2931a7 100644 --- a/src/plugins/qmakeprojectmanager/profilehoverhandler.h +++ b/src/plugins/qmakeprojectmanager/profilehoverhandler.h @@ -66,7 +66,7 @@ private: const QString &keyword); QString m_docFragment; - ManualKind m_manualKind; + ManualKind m_manualKind = UnknownManual; const TextEditor::Keywords m_keywords; }; diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp index 92af58f4ace..f9a76f9c1cb 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp @@ -106,12 +106,7 @@ QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target) } QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, Core::Id id) : - BuildConfiguration(target, id), - m_shadowBuild(true), - m_isEnabled(false), - m_qmakeBuildConfiguration(0), - m_subNodeBuild(0), - m_fileNodeBuild(0) + BuildConfiguration(target, id) { ctor(); } @@ -119,10 +114,7 @@ QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, Core::Id id) : QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, QmakeBuildConfiguration *source) : BuildConfiguration(target, source), m_shadowBuild(source->m_shadowBuild), - m_isEnabled(false), - m_qmakeBuildConfiguration(source->m_qmakeBuildConfiguration), - m_subNodeBuild(0), // temporary value, so not copied - m_fileNodeBuild(0) + m_qmakeBuildConfiguration(source->m_qmakeBuildConfiguration) { cloneSteps(source); ctor(); diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h index f47c5514512..ee9582273d5 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h @@ -144,11 +144,11 @@ private: }; LastKitState m_lastKitState; - bool m_shadowBuild; - bool m_isEnabled; - QtSupport::BaseQtVersion::QmakeBuildConfigs m_qmakeBuildConfiguration; - QmakeProjectManager::QmakeProFileNode *m_subNodeBuild; - ProjectExplorer::FileNode *m_fileNodeBuild; + bool m_shadowBuild = true; + bool m_isEnabled = false; + QtSupport::BaseQtVersion::QmakeBuildConfigs m_qmakeBuildConfiguration = 0; + QmakeProjectManager::QmakeProFileNode *m_subNodeBuild = nullptr; + ProjectExplorer::FileNode *m_fileNodeBuild = nullptr; friend class Internal::QmakeProjectConfigWidget; friend class QmakeBuildConfigurationFactory; diff --git a/src/plugins/qmakeprojectmanager/qmakebuildinfo.h b/src/plugins/qmakeprojectmanager/qmakebuildinfo.h index 87f8fe17ce3..fd5debe8feb 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildinfo.h +++ b/src/plugins/qmakeprojectmanager/qmakebuildinfo.h @@ -46,7 +46,7 @@ class QmakeBuildInfo : public ProjectExplorer::BuildInfo public: QmakeBuildInfo(const QmakeBuildConfigurationFactory *f) : ProjectExplorer::BuildInfo(f) { } - ProjectExplorer::BuildConfiguration::BuildType type; + ProjectExplorer::BuildConfiguration::BuildType type = ProjectExplorer::BuildConfiguration::Unknown; QString additionalArguments; QString makefile; QMakeStepConfig config; diff --git a/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.cpp b/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.cpp index 1f4001d9b42..9db367b6605 100644 --- a/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.cpp +++ b/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.cpp @@ -41,8 +41,7 @@ namespace Internal { QmakeKitConfigWidget::QmakeKitConfigWidget(ProjectExplorer::Kit *k, const ProjectExplorer::KitInformation *ki) : ProjectExplorer::KitConfigWidget(k, ki), - m_lineEdit(new QLineEdit), - m_ignoreChange(false) + m_lineEdit(new QLineEdit) { refresh(); // set up everything according to kit m_lineEdit->setToolTip(toolTip()); diff --git a/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.h b/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.h index 7f2cfcb4c02..bc2a255a14e 100644 --- a/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.h +++ b/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.h @@ -61,8 +61,8 @@ private slots: private: int findQtVersion(const int id) const; - QLineEdit *m_lineEdit; - bool m_ignoreChange; + QLineEdit *m_lineEdit = nullptr; + bool m_ignoreChange = false; }; } // namespace Internal diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp index 7de13272d18..3a0511c73e1 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -306,8 +306,7 @@ QmakePriFileNode::QmakePriFileNode(QmakeProject *project, QmakeProFileNode *qmak m_project(project), m_qmakeProFileNode(qmakeProFileNode), m_projectFilePath(filePath), - m_projectDir(filePath.toFileInfo().absolutePath()), - m_includedInExactParse(true) + m_projectDir(filePath.toFileInfo().absolutePath()) { Q_ASSERT(project); m_qmakePriFile = new QmakePriFile(this); @@ -335,19 +334,13 @@ struct InternalNode QList virtualfolders; QMap subnodes; FileNameList files; - FileType type; - int priority; + FileType type = UnknownFileType; + int priority = 0; QString displayName; QString typeName; QString fullPath; QIcon icon; - InternalNode() - { - type = UnknownFileType; - priority = 0; - } - ~InternalNode() { qDeleteAll(virtualfolders); @@ -1597,12 +1590,7 @@ bool QmakeProFileNode::isDeployable() const */ QmakeProFileNode::QmakeProFileNode(QmakeProject *project, const FileName &filePath) - : QmakePriFileNode(project, this, filePath), - m_validParse(false), - m_parseInProgress(true), - m_projectType(InvalidProject), - m_readerExact(0), - m_readerCumulative(0) + : QmakePriFileNode(project, this, filePath) { // The slot is a lambda, so that QmakeProFileNode does not need to be // a qobject. The lifetime of the m_parserFutureWatcher is shorter diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h index 149b3806d56..e6a6a02b279 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.h +++ b/src/plugins/qmakeprojectmanager/qmakenodes.h @@ -219,7 +219,7 @@ private: QMap > m_files; QSet m_recursiveEnumerateFiles; QSet m_watchedFolders; - bool m_includedInExactParse; + bool m_includedInExactParse = true; // managed by QmakeProFileNode friend class QmakeProjectManager::QmakeProFileNode; @@ -277,7 +277,7 @@ private: class QMAKEPROJECTMANAGER_EXPORT TargetInformation { public: - bool valid; + bool valid = false; QString target; QString destDir; QString buildDir; @@ -295,19 +295,9 @@ public: return !(*this == other); } - TargetInformation() - : valid(false) - {} - - TargetInformation(const TargetInformation &other) - : valid(other.valid), - target(other.target), - destDir(other.destDir), - buildDir(other.buildDir), - buildTarget(other.buildTarget) - { - } + TargetInformation() = default; + TargetInformation(const TargetInformation &other) = default; }; struct QMAKEPROJECTMANAGER_EXPORT InstallsItem { @@ -322,12 +312,6 @@ struct QMAKEPROJECTMANAGER_EXPORT InstallsList { QList items; }; -struct QMAKEPROJECTMANAGER_EXPORT ProjectVersion { - int major; - int minor; - int patch; -}; - // Implements ProjectNode for qmake .pro files class QMAKEPROJECTMANAGER_EXPORT QmakeProFileNode : public QmakePriFileNode { @@ -413,12 +397,12 @@ private: static TargetInformation targetInformation(QtSupport::ProFileReader *reader, QtSupport::ProFileReader *readerBuildPass, const QString &buildDir, const QString &projectFilePath); static InstallsList installsList(const QtSupport::ProFileReader *reader, const QString &projectFilePath, const QString &projectDir); - bool m_isDeployable; + bool m_isDeployable = false; - bool m_validParse; - bool m_parseInProgress; + bool m_validParse = false; + bool m_parseInProgress = true; - QmakeProjectType m_projectType; + QmakeProjectType m_projectType = InvalidProject; QmakeVariablesHash m_varValues; QMap m_uitimestamps; @@ -430,8 +414,8 @@ private: // Async stuff QFutureWatcher m_parseFutureWatcher; - QtSupport::ProFileReader *m_readerExact; - QtSupport::ProFileReader *m_readerCumulative; + QtSupport::ProFileReader *m_readerExact = nullptr; + QtSupport::ProFileReader *m_readerCumulative = nullptr; }; } // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 41f7afdbf3a..9d54d2eafdd 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -311,18 +311,9 @@ bool QmakeProjectFile::reload(QString *errorString, ReloadFlag flag, ChangeType QmakeProject::QmakeProject(QmakeManager *manager, const QString &fileName) : m_manager(manager), - m_rootProjectNode(0), m_fileInfo(new QmakeProjectFile(fileName, this)), m_projectFiles(new QmakeProjectFiles), - m_qmakeVfs(new QMakeVfs), - m_qmakeGlobals(0), - m_qmakeGlobalsRefCnt(0), - m_asyncUpdateFutureInterface(0), - m_pendingEvaluateFuturesCount(0), - m_asyncUpdateState(Base), - m_cancelEvaluate(false), - m_centralizedFolderWatcher(0), - m_activeTarget(0) + m_qmakeVfs(new QMakeVfs) { setId(Constants::QMAKEPROJECT_ID); setProjectContext(Core::Context(QmakeProjectManager::Constants::PROJECT_ID)); diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.h b/src/plugins/qmakeprojectmanager/qmakeproject.h index ccedabd2425..6d6b85d03d4 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.h +++ b/src/plugins/qmakeprojectmanager/qmakeproject.h @@ -185,35 +185,35 @@ private: bool matchesKit(const ProjectExplorer::Kit *kit); QmakeManager *m_manager; - QmakeProFileNode *m_rootProjectNode; + QmakeProFileNode *m_rootProjectNode = 0; - Internal::QmakeProjectFile *m_fileInfo; + Internal::QmakeProjectFile *m_fileInfo = nullptr; // Current configuration QString m_oldQtIncludePath; QString m_oldQtLibsPath; // cached lists of all of files - Internal::QmakeProjectFiles *m_projectFiles; + Internal::QmakeProjectFiles *m_projectFiles = nullptr; - QMakeVfs *m_qmakeVfs; + QMakeVfs *m_qmakeVfs = nullptr; // cached data during project rescan - ProFileGlobals *m_qmakeGlobals; - int m_qmakeGlobalsRefCnt; + ProFileGlobals *m_qmakeGlobals = nullptr; + int m_qmakeGlobalsRefCnt = 0; QTimer m_asyncUpdateTimer; - QFutureInterface *m_asyncUpdateFutureInterface; - int m_pendingEvaluateFuturesCount; - AsyncUpdateState m_asyncUpdateState; - bool m_cancelEvaluate; + QFutureInterface *m_asyncUpdateFutureInterface = nullptr; + int m_pendingEvaluateFuturesCount = 0; + AsyncUpdateState m_asyncUpdateState = Base; + bool m_cancelEvaluate = false; QList m_partialEvaluate; QFuture m_codeModelFuture; - Internal::CentralizedFolderWatcher *m_centralizedFolderWatcher; + Internal::CentralizedFolderWatcher *m_centralizedFolderWatcher = nullptr; - ProjectExplorer::Target *m_activeTarget; + ProjectExplorer::Target *m_activeTarget = nullptr; friend class Internal::QmakeProjectFile; friend class Internal::QmakeProjectConfigWidget; diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp index 5f01755cf76..358dcae5fb3 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp @@ -47,8 +47,7 @@ using namespace ProjectExplorer; QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc) : NamedWidget(), - m_buildConfiguration(bc), - m_ignoreChange(false) + m_buildConfiguration(bc) { m_defaultShadowBuildDir = QmakeBuildConfiguration::shadowBuildDirectory(bc->target()->project()->projectFilePath().toString(), diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h index 951f49f05a9..09d15a48466 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h +++ b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h @@ -73,7 +73,7 @@ private: QmakeBuildConfiguration *m_buildConfiguration; Utils::DetailsWidget *m_detailsContainer; QString m_defaultShadowBuildDir; - bool m_ignoreChange; + bool m_ignoreChange = false; }; } // namespace Internal diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp index d8614bf7c8c..c6a2cee5b7a 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp @@ -58,13 +58,6 @@ using namespace TextEditor; namespace QmakeProjectManager { -QmakeManager::QmakeManager() - : m_contextNode(0), - m_contextProject(0), - m_contextFile(0) -{ -} - QmakeManager::~QmakeManager() { } diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h index e09aab99254..c098c737cda 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h @@ -54,7 +54,6 @@ class QMAKEPROJECTMANAGER_EXPORT QmakeManager : public ProjectExplorer::IProject Q_OBJECT public: - QmakeManager(); ~QmakeManager(); void registerProject(QmakeProject *project); @@ -95,9 +94,9 @@ private: void addLibrary(const QString &fileName, TextEditor::BaseTextEditor *editor = 0); void runQMake(ProjectExplorer::Project *p, ProjectExplorer::Node *node); - ProjectExplorer::Node *m_contextNode; - ProjectExplorer::Project *m_contextProject; - ProjectExplorer::FileNode *m_contextFile; + ProjectExplorer::Node *m_contextNode = nullptr; + ProjectExplorer::Project *m_contextProject = nullptr; + ProjectExplorer::FileNode *m_contextFile = nullptr; }; } // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp index 8e5789b12f6..318eb172f6a 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp @@ -76,12 +76,6 @@ using namespace QmakeProjectManager::Internal; using namespace QmakeProjectManager; using namespace ProjectExplorer; -QmakeProjectManagerPlugin::QmakeProjectManagerPlugin() - : m_qmakeProjectManager(0), m_previousStartupProject(0), m_previousTarget(0) -{ - -} - QmakeProjectManagerPlugin::~QmakeProjectManagerPlugin() { } diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.h b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.h index a052e462855..2d673a9af72 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.h +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.h @@ -59,7 +59,6 @@ class QmakeProjectManagerPlugin : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "QmakeProjectManager.json") public: - QmakeProjectManagerPlugin(); ~QmakeProjectManagerPlugin(); bool initialize(const QStringList &arguments, QString *errorMessage); void extensionsInitialized(); @@ -78,23 +77,23 @@ private slots: #endif private: - QmakeManager *m_qmakeProjectManager; - QmakeProject *m_previousStartupProject; - ProjectExplorer::Target *m_previousTarget; + QmakeManager *m_qmakeProjectManager = nullptr; + QmakeProject *m_previousStartupProject = nullptr; + ProjectExplorer::Target *m_previousTarget = nullptr; - QAction *m_runQMakeAction; - QAction *m_runQMakeActionContextMenu; - Utils::ParameterAction *m_buildSubProjectContextMenu; - QAction *m_subProjectRebuildSeparator; - QAction *m_rebuildSubProjectContextMenu; - QAction *m_cleanSubProjectContextMenu; - QAction *m_buildFileContextMenu; - Utils::ParameterAction *m_buildSubProjectAction; - Utils::ParameterAction *m_rebuildSubProjectAction; - Utils::ParameterAction *m_cleanSubProjectAction; - Utils::ParameterAction *m_buildFileAction; - QAction *m_addLibraryAction; - QAction *m_addLibraryActionContextMenu; + QAction *m_runQMakeAction = nullptr; + QAction *m_runQMakeActionContextMenu = nullptr; + Utils::ParameterAction *m_buildSubProjectContextMenu = nullptr; + QAction *m_subProjectRebuildSeparator = nullptr; + QAction *m_rebuildSubProjectContextMenu = nullptr; + QAction *m_cleanSubProjectContextMenu = nullptr; + QAction *m_buildFileContextMenu = nullptr; + Utils::ParameterAction *m_buildSubProjectAction = nullptr; + Utils::ParameterAction *m_rebuildSubProjectAction = nullptr; + Utils::ParameterAction *m_cleanSubProjectAction = nullptr; + Utils::ParameterAction *m_buildFileAction = nullptr; + QAction *m_addLibraryAction = nullptr; + QAction *m_addLibraryActionContextMenu = nullptr; Core::Context m_projectContext; }; diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 0f69f809c97..3945e9a2e51 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -75,22 +75,13 @@ const char QMAKE_QMLDEBUGLIB_KEY[] = "QtProjectManager.QMakeBuildStep.LinkQmlDeb } QMakeStep::QMakeStep(BuildStepList *bsl) : - AbstractProcessStep(bsl, Core::Id(QMAKE_BS_ID)), - m_forced(false), - m_needToRunQMake(false), - m_linkQmlDebuggingLibrary(DebugLink), - m_useQtQuickCompiler(false), - m_separateDebugInfo(false) + AbstractProcessStep(bsl, Core::Id(QMAKE_BS_ID)) { ctor(); } QMakeStep::QMakeStep(BuildStepList *bsl, Core::Id id) : - AbstractProcessStep(bsl, id), - m_forced(false), - m_linkQmlDebuggingLibrary(DebugLink), - m_useQtQuickCompiler(false), - m_separateDebugInfo(false) + AbstractProcessStep(bsl, id) { ctor(); } @@ -457,8 +448,7 @@ bool QMakeStep::fromMap(const QVariantMap &map) //// QMakeStepConfigWidget::QMakeStepConfigWidget(QMakeStep *step) - : BuildStepConfigWidget(), m_ui(new Internal::Ui::QMakeStep), m_step(step), - m_ignoreChange(false) + : BuildStepConfigWidget(), m_ui(new Internal::Ui::QMakeStep), m_step(step) { m_ui->setupUi(this); diff --git a/src/plugins/qmakeprojectmanager/qmakestep.h b/src/plugins/qmakeprojectmanager/qmakestep.h index 0f3fb7be4ba..1b799be6a53 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.h +++ b/src/plugins/qmakeprojectmanager/qmakestep.h @@ -91,25 +91,15 @@ public: static TargetArchConfig targetArchFor(const ProjectExplorer::Abi &targetAbi, const QtSupport::BaseQtVersion *version); static OsType osTypeFor(const ProjectExplorer::Abi &targetAbi, const QtSupport::BaseQtVersion *version); - - QMakeStepConfig() - : archConfig(NoArch), - osType(NoOsType), - linkQmlDebuggingQQ1(false), - linkQmlDebuggingQQ2(false), - useQtQuickCompiler(false), - separateDebugInfo(false) - {} - QStringList toArguments() const; // Actual data - TargetArchConfig archConfig; - OsType osType; - bool linkQmlDebuggingQQ1; - bool linkQmlDebuggingQQ2; - bool useQtQuickCompiler; - bool separateDebugInfo; + TargetArchConfig archConfig = NoArch; + OsType osType = NoOsType; + bool linkQmlDebuggingQQ1 = false; + bool linkQmlDebuggingQQ2 = false; + bool useQtQuickCompiler = false; + bool separateDebugInfo = false; }; @@ -192,13 +182,13 @@ private: void ctor(); // last values - bool m_forced; - bool m_needToRunQMake; // set in init(), read in run() + bool m_forced = false; + bool m_needToRunQMake = false; // set in init(), read in run() QString m_userArgs; - QmlLibraryLink m_linkQmlDebuggingLibrary; - bool m_useQtQuickCompiler; - bool m_scriptTemplate; - bool m_separateDebugInfo; + QmlLibraryLink m_linkQmlDebuggingLibrary = DebugLink; + bool m_useQtQuickCompiler = false; + bool m_scriptTemplate = false; + bool m_separateDebugInfo = false; }; @@ -239,11 +229,11 @@ private: void setSummaryText(const QString &); - Internal::Ui::QMakeStep *m_ui; - QMakeStep *m_step; + Internal::Ui::QMakeStep *m_ui = nullptr; + QMakeStep *m_step = nullptr; QString m_summaryText; QString m_additionalSummaryText; - bool m_ignoreChange; + bool m_ignoreChange = false; }; } // namespace QmakeProjectManager From 1a0a7312f1b1359b122ee62a092d5f7fd79ab2fc Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 24 Jun 2015 07:18:49 +0200 Subject: [PATCH 026/113] CppEditor: Fix accessing null pointer... ...when executing FakeVim plugin unit tests. Introduced with e50aafafe3d643efecdbce3ca93dc59104d73650 Change-Id: I8db057921d5adbcbe262a4dc0fee40378477694a Reviewed-by: Orgad Shaneh --- src/plugins/cppeditor/cppeditordocument.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp index 3d33e1f3f9c..77bffc7338c 100644 --- a/src/plugins/cppeditor/cppeditordocument.cpp +++ b/src/plugins/cppeditor/cppeditordocument.cpp @@ -169,7 +169,8 @@ void CppEditorDocument::applyFontSettings() } } TextDocument::applyFontSettings(); // rehighlights and updates additional formats - m_processor->semanticRehighlight(); + if (m_processor) + m_processor->semanticRehighlight(); } void CppEditorDocument::invalidateFormatterCache() From 2c07175be555eefab1763ff54e335a540c9834ae Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 23 Jun 2015 15:56:45 +0200 Subject: [PATCH 027/113] TextEditor: Avoid using Core::Id::uniqueIdentifier ... by using Core::Ids instead of ExtraSelectionKind enum. Change-Id: I664ff2a4a03eddd8fe1150929203a1727c12dc84 Reviewed-by: David Schulz --- src/plugins/cppeditor/cppeditor.cpp | 2 +- src/plugins/texteditor/texteditor.cpp | 44 +++++++++++++-------------- src/plugins/texteditor/texteditor.h | 28 ++++++++--------- 3 files changed, 34 insertions(+), 40 deletions(-) diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index cf309c2969e..a19081e5240 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -229,7 +229,7 @@ void CppEditorWidget::finalizeInitializationAfterDuplication(TextEditorWidget *o if (cppEditorWidget->isSemanticInfoValidExceptLocalUses()) updateSemanticInfo(cppEditorWidget->semanticInfo()); d->m_cppEditorOutline->update(); - const ExtraSelectionKind selectionKind = CodeWarningsSelection; + const Id selectionKind = CodeWarningsSelection; setExtraSelections(selectionKind, cppEditorWidget->extraSelections(selectionKind)); } diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 53d737c0709..31e44ca8682 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -150,6 +150,8 @@ using namespace Utils; namespace TextEditor { namespace Internal { +enum { NExtraSelectionKinds = 12 }; + typedef QString (TransformationMethod)(const QString &); static QString QString_toUpper(const QString &str) @@ -414,8 +416,8 @@ public: void highlightSearchResults(const QTextBlock &block, TextEditorOverlay *overlay); QTimer m_delayedUpdateTimer; - void setExtraSelections(int kind, const QList &selections); - QHash> m_extraSelections; + void setExtraSelections(Core::Id kind, const QList &selections); + QHash> m_extraSelections; // block selection mode bool m_inBlockSelectionMode; @@ -555,8 +557,7 @@ TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent) m_cursorPositionLabelAction = m_toolBar->addWidget(m_cursorPositionLabel); m_fileEncodingLabelAction = m_toolBar->addWidget(m_fileEncodingLabel); - - m_extraSelections.reserve(TextEditorWidget::NExtraSelectionKinds); + m_extraSelections.reserve(NExtraSelectionKinds); } } // namespace Internal @@ -619,6 +620,18 @@ QString TextEditorWidget::convertToPlainText(const QString &txt) static const char kTextBlockMimeType[] = "application/vnd.qtcreator.blocktext"; +Id TextEditorWidget::SnippetPlaceholderSelection("TextEdit.SnippetPlaceHolderSelection"); +Id TextEditorWidget::CurrentLineSelection("TextEdit.CurrentLineSelection"); +Id TextEditorWidget::ParenthesesMatchingSelection("TextEdit.ParenthesesMatchingSelection"); +Id TextEditorWidget::CodeWarningsSelection("TextEdit.CodeWarningsSelection"); +Id TextEditorWidget::CodeSemanticsSelection("TextEdit.CodeSemanticsSelection"); +Id TextEditorWidget::UndefinedSymbolSelection("TextEdit.UndefinedSymbolSelection"); +Id TextEditorWidget::UnusedSymbolSelection("TextEdit.UnusedSymbolSelection"); +Id TextEditorWidget::OtherSelection("TextEdit.OtherSelection"); +Id TextEditorWidget::ObjCSelection("TextEdit.ObjCSelection"); +Id TextEditorWidget::DebuggerExceptionSelection("TextEdit.DebuggerExceptionSelection"); +Id TextEditorWidget::FakeVimSelection("TextEdit.FakeVimSelection"); + TextEditorWidget::TextEditorWidget(QWidget *parent) : QPlainTextEdit(parent) { @@ -2615,7 +2628,7 @@ void TextEditorWidgetPrivate::documentAboutToBeReloaded() // remove extra selections (loads of QTextCursor objects) m_extraSelections.clear(); - m_extraSelections.reserve(TextEditorWidget::NExtraSelectionKinds); + m_extraSelections.reserve(NExtraSelectionKinds); q->QPlainTextEdit::setExtraSelections(QList()); // clear all overlays @@ -6085,8 +6098,7 @@ void TextEditorWidget::deleteStartOfWordCamelCase() setTextCursor(c); } -// kind can be either a value from the ExtraSelectionKind enum, or an unique Core::Id identifier. -void TextEditorWidgetPrivate::setExtraSelections(int kind, const QList &selections) +void TextEditorWidgetPrivate::setExtraSelections(Id kind, const QList &selections) { if (selections.isEmpty() && m_extraSelections[kind].isEmpty()) return; @@ -6124,28 +6136,14 @@ void TextEditorWidgetPrivate::setExtraSelections(int kind, const QList &selections) +void TextEditorWidget::setExtraSelections(Id kind, const QList &selections) { d->setExtraSelections(kind, selections); } -QList TextEditorWidget::extraSelections(ExtraSelectionKind kind) const -{ - return d->m_extraSelections[kind]; -} - -void TextEditorWidget::setExtraSelections(Id kind, const QList &selections) -{ - // Private Core:Id identifiers from the 0-1000 range cannot be used here, they conflict with ExtraSelectionKind - QTC_ASSERT(kind.uniqueIdentifier() >= NExtraSelectionKinds, return); - d->setExtraSelections(kind.uniqueIdentifier(), selections); -} - QList TextEditorWidget::extraSelections(Id kind) const { - // Private Core:Id identifiers from the 0-1000 range cannot be used here, they conflict with ExtraSelectionKind - QTC_ASSERT(kind.uniqueIdentifier() >= NExtraSelectionKinds, return QList()); - return d->m_extraSelections[kind.uniqueIdentifier()]; + return d->m_extraSelections.value(kind); } QString TextEditorWidget::extraSelectionTooltip(int pos) const diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index 183163232a1..97f5de56f64 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -328,22 +328,18 @@ public: void ensureCursorVisible(); - enum ExtraSelectionKind { - CurrentLineSelection, - ParenthesesMatchingSelection, - CodeWarningsSelection, - CodeSemanticsSelection, - UndefinedSymbolSelection, - UnusedSymbolSelection, - FakeVimSelection, - OtherSelection, - SnippetPlaceholderSelection, - ObjCSelection, - DebuggerExceptionSelection, - NExtraSelectionKinds - }; - void setExtraSelections(ExtraSelectionKind kind, const QList &selections); - QList extraSelections(ExtraSelectionKind kind) const; + static Core::Id FakeVimSelection; + static Core::Id SnippetPlaceholderSelection; + static Core::Id CurrentLineSelection; + static Core::Id ParenthesesMatchingSelection; + static Core::Id CodeWarningsSelection; + static Core::Id CodeSemanticsSelection; + static Core::Id UndefinedSymbolSelection; + static Core::Id UnusedSymbolSelection; + static Core::Id OtherSelection; + static Core::Id ObjCSelection; + static Core::Id DebuggerExceptionSelection; + void setExtraSelections(Core::Id kind, const QList &selections); QList extraSelections(Core::Id kind) const; QString extraSelectionTooltip(int pos) const; From 1d286eedb19ad4c350aab8307b7deb9764fbfbb1 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 24 Jun 2015 10:28:32 +0200 Subject: [PATCH 028/113] ActionManager: Remove remaining uses of Id::uniqueIdentifier() Change-Id: I36a1324d3ba2e56740eaa48cd4140b5d925417cd Reviewed-by: Eike Ziller --- src/plugins/coreplugin/actionmanager/actionmanager.cpp | 2 +- src/plugins/coreplugin/actionmanager/command.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index 2a6c517f61a..528d7b02260 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -398,7 +398,7 @@ QDebug operator<<(QDebug d, const Context &context) { d << "CONTEXT: "; foreach (Id id, context) - d << " " << id.uniqueIdentifier() << " " << id.toString(); + d << " " << id.toString(); return d; } diff --git a/src/plugins/coreplugin/actionmanager/command.cpp b/src/plugins/coreplugin/actionmanager/command.cpp index afe18114638..d9db3c57faf 100644 --- a/src/plugins/coreplugin/actionmanager/command.cpp +++ b/src/plugins/coreplugin/actionmanager/command.cpp @@ -305,8 +305,7 @@ static QString msgActionWarning(QAction *newAction, Id id, QAction *oldAction) << ": Action "; if (oldAction) str << oldAction->objectName() << '/' << oldAction->text(); - str << " is already registered for context " << id.uniqueIdentifier() << ' ' - << id.toString() << '.'; + str << " is already registered for context " << id.toString() << '.'; return msg; } From 649acd35f501220947c9e47a9c2dcace876fefc4 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 23 Jun 2015 17:12:38 +0200 Subject: [PATCH 029/113] WS only change Change-Id: I35fb56a500ed6694514c092ed46ab11ef5d8e0df Reviewed-by: Leena Miettinen --- doc/api/qtcreator-ui-text.qdoc | 106 +++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 45 deletions(-) diff --git a/doc/api/qtcreator-ui-text.qdoc b/doc/api/qtcreator-ui-text.qdoc index ea8c34b9566..4f447d1a7fe 100644 --- a/doc/api/qtcreator-ui-text.qdoc +++ b/doc/api/qtcreator-ui-text.qdoc @@ -278,50 +278,54 @@ \table \header - \li Features of Languages or Writing Systems - \li Impact on Implementation + \li Features of Languages or Writing Systems + + \li Impact on Implementation \row - \li Word order - \li Different languages have different word order rules. + \li Word order + + \li Different languages have different word order rules. Do not use run-time concatenation. Use complete phrases and "%1" formatting instead. For example, use: - \c{tr("Foo failed: %1").arg(message)} + \c{tr("Foo failed: %1").arg(message)} instead of \c {tr("Foo failed: ") + message} \row - \li Singular vs. plural vs. dual forms - \li Some languages do not have plural form (for example, Chinese - and Japanese), whereas some have a different form for dual. + \li Singular vs. plural vs. dual forms - Allow room for text expansion in the layout design. Some - languages need more space to indicate plurality or duality to - convey the needed information. + \li Some languages do not have plural form (for example, Chinese + and Japanese), whereas some have a different form for dual. - For example, use + Allow room for text expansion in the layout design. Some + languages need more space to indicate plurality or duality to + convey the needed information. - \c {tr("%n files found", 0, number)} + For example, use - instead of + \c {tr("%n files found", 0, number)} - \c {tr("%1 files found").arg(number)} + instead of + + \c {tr("%1 files found").arg(number)} \row - \li Gender - \li Some languages have gender (feminine, masculine, neutral), - whereas some do not (for example, Finnish) or do not use it - extensively (for example, English). + \li Gender + + \li Some languages have gender (feminine, masculine, neutral), + whereas some do not (for example, Finnish) or do not use it + extensively (for example, English). Do not reuse text strings. The same term may not work in another context due to the gender of the base word. - Articles have a grammatical gender in some languages and - sentences cannot be as easily constructed as in English. Avoid - following types of constructs: + Articles have a grammatical gender in some languages and + sentences cannot be as easily constructed as in English. Avoid + following types of constructs: - \c {tr("%1 failed").arg(someCondition ? "the operation" : "opening a file")} + \c {tr("%1 failed").arg(someCondition ? "the operation" : "opening a file")} \endtable \section1 Common Qt Creator Terms @@ -339,16 +343,22 @@ \table \header - \li UI Text - \li Usage - \li Conventions + \li UI Text + + \li Usage + + \li Conventions + \row - \li Context menu - \li Opens when users right-click on the screen. Contents depend on - the context. - \image qtcreator-context-menu.png "Context menu" - \li You can add menu items that are relevant in a particular - context. Follow the conventions for naming menu items. + \li Context menu + + \li Opens when users right-click on the screen. Contents depend on + the context. + \image qtcreator-context-menu.png "Context menu" + + \li You can add menu items that are relevant in a particular + context. Follow the conventions for naming menu items. + \row \li Dialog \li User interface element that usually contains a number of @@ -361,20 +371,26 @@ button in the \uicontrol Documentation options opens the \uicontrol {Add Documentation} dialog. \row - \li Locator - \li Allows you to browse not only files, but any items defined by - locator filters. - \image qtcreator-locator.png "Locator" - \li You can add locator filters. Check that the filter is not - already in use and give the filter a descriptive name. + \li Locator + + \li Allows you to browse not only files, but any items defined by + locator filters. + \image qtcreator-locator.png "Locator" + + \li You can add locator filters. Check that the filter is not + already in use and give the filter a descriptive name. + \row - \li Menu - \li Contains menu items that represent commands or options and that - are logically grouped and displayed. A menu can also contain - submenus. - \image qtcreator-menu.png "Menu" - \li You can create new menus. Use short, but descriptive names that - are consistent with existing menu names. Use unambigious names. + \li Menu + + \li Contains menu items that represent commands or options and that + are logically grouped and displayed. A menu can also contain + submenus. + \image qtcreator-menu.png "Menu" + + \li You can create new menus. Use short, but descriptive names that + are consistent with existing menu names. Use unambigious names. + \row \li Menu item \li Represents a command or an option for users to choose. From 5d51bd932442f6601fb930d2009ab548c6bfe9ea Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 18 Jun 2015 13:04:38 +0200 Subject: [PATCH 030/113] Clang: Ensure end command is send before waiting for process finish This reverts CmbIpc: Remove workaround 287a26308319a872f63088dd2aa2d8561f7f27ac since the bug still exists. However, we use waitForBytesWritten() instead of QCoreApplication::processEvents() since this seems to be fine (QAbstractSocket::waitForBytesWritten is not called on Windows). The bug was: 1. Open a bigger project, like qtcreator.pro. 2. After 2 seconds, quit it. ==> The Qt Creator window is gone but the Qt Creator process waits until the clangbackend process is finished. Change-Id: I25c475d2a6db94a1c3a8d827a41f8c0b2624eaea Reviewed-by: Marco Bubke --- src/libs/clangbackendipc/connectionclient.cpp | 7 +++++++ src/libs/clangbackendipc/connectionclient.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libs/clangbackendipc/connectionclient.cpp b/src/libs/clangbackendipc/connectionclient.cpp index 4636ef22759..10384f6a52b 100644 --- a/src/libs/clangbackendipc/connectionclient.cpp +++ b/src/libs/clangbackendipc/connectionclient.cpp @@ -95,10 +95,17 @@ bool ConnectionClient::isConnected() const return localSocket.state() == QLocalSocket::ConnectedState; } +void ConnectionClient::ensureCommandIsWritten() +{ + while (localSocket.bytesToWrite() > 0) + localSocket.waitForBytesWritten(); +} + void ConnectionClient::sendEndCommand() { serverProxy_.end(); localSocket.flush(); + ensureCommandIsWritten(); } void ConnectionClient::resetProcessAliveTimer() diff --git a/src/libs/clangbackendipc/connectionclient.h b/src/libs/clangbackendipc/connectionclient.h index 01f48d75b49..a3dd243a844 100644 --- a/src/libs/clangbackendipc/connectionclient.h +++ b/src/libs/clangbackendipc/connectionclient.h @@ -97,7 +97,7 @@ private: void disconnectProcessFinished() const; void connectStandardOutputAndError() const; - void waitUntilSocketIsFlushed() const; + void ensureCommandIsWritten(); private: mutable std::unique_ptr process_; From b7c025a5dd6c3b2b84341f52920c2cc6ceda3295 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 24 Jun 2015 09:43:09 +0200 Subject: [PATCH 031/113] Clang: Respect QT_NO_*KEYWORDS in qt5-qobjectdefs-injected.h Change-Id: I299db813c13f273a40e447c5fdde8ff8757480ba Reviewed-by: Marco Bubke --- .../cplusplus/qt5-qobjectdefs-injected.h | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h b/share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h index 22f6f0ca2f0..946ec33bd16 100644 --- a/share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h +++ b/share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h @@ -30,16 +30,24 @@ #define QT_NO_META_MACROS -#define signals public __attribute__((annotate("qt_signal"))) -#define slots __attribute__((annotate("qt_slot"))) -#define Q_SIGNALS signals -#define Q_SLOTS slots +#if defined(QT_NO_KEYWORDS) +# define QT_NO_EMIT +#else +# ifndef QT_NO_SIGNALS_SLOTS_KEYWORDS +# define signals public __attribute__((annotate("qt_signal"))) +# define slots __attribute__((annotate("qt_slot"))) +# endif +#endif +#define Q_SIGNALS public __attribute__((annotate("qt_signal"))) +#define Q_SLOTS slots __attribute__((annotate("qt_slot"))) #define Q_SIGNAL __attribute__((annotate("qt_signal"))) #define Q_SLOT __attribute__((annotate("qt_slot"))) -# define Q_PRIVATE_SLOT(d, signature) +#define Q_PRIVATE_SLOT(d, signature) #define Q_EMIT -#define emit +#ifndef QT_NO_EMIT +# define emit +#endif #define Q_CLASSINFO(name, value) #define Q_PLUGIN_METADATA(x) #define Q_INTERFACES(x) From 4eafa2e02be4e659f8bb5f6ab020844174e82f47 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 24 Jun 2015 09:43:20 +0200 Subject: [PATCH 032/113] Clang: Handle Q_ENUM() and Q_FLAG() in qt5-qobjectdefs-injected.h Q_ENUM() and Q_FLAG() were added in Qt 5.5.0. This fixes among others red/wiggly underlines of these macro's uses. Change-Id: I059ebcc32cc271f4960b11e722e23c314c5ceac7 Reviewed-by: Marco Bubke --- share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h b/share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h index 946ec33bd16..cc7ca503bd7 100644 --- a/share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h +++ b/share/qtcreator/cplusplus/qt5-qobjectdefs-injected.h @@ -57,6 +57,8 @@ #define Q_OVERRIDE(text) #define Q_ENUMS(x) #define Q_FLAGS(x) +#define Q_ENUM(x) +#define Q_FLAG(x) #define Q_SCRIPTABLE #define Q_INVOKABLE From b105917b97feb9a3e3a179b29b19c4ce5fc04fb4 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Mon, 22 Jun 2015 16:53:22 +0200 Subject: [PATCH 033/113] Clang: Quote project part arguments for easier debugging Now we can copy paste to the shell and make tests there more easily. Change-Id: Ic17ea23c4040583ba3af9e60ae73b242a574ab9b Reviewed-by: Marco Bubke --- src/libs/clangbackendipc/projectpartcontainer.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libs/clangbackendipc/projectpartcontainer.cpp b/src/libs/clangbackendipc/projectpartcontainer.cpp index 692b755eb0a..9472eea063c 100644 --- a/src/libs/clangbackendipc/projectpartcontainer.cpp +++ b/src/libs/clangbackendipc/projectpartcontainer.cpp @@ -82,12 +82,19 @@ bool operator<(const ProjectPartContainer &first, const ProjectPartContainer &se return first.projectPartId_ < second.projectPartId_; } +static Utf8String quotedArguments(const Utf8StringVector &arguments) +{ + const Utf8String quote = Utf8String::fromUtf8("\""); + const Utf8String joined = arguments.join(quote + QString::fromUtf8(" ") + quote); + return quote + joined + quote; +} + QDebug operator<<(QDebug debug, const ProjectPartContainer &container) { debug.nospace() << "ProjectPartContainer(" << container.projectPartId() << "," - << container.arguments() + << quotedArguments(container.arguments()) << ")"; return debug; From 7c9ffe4ab87aa36942ec27f15b41a1a437a7d996 Mon Sep 17 00:00:00 2001 From: Nikita Baryshnikov Date: Wed, 24 Jun 2015 11:49:37 +0300 Subject: [PATCH 034/113] ProFileHoverHandler: fix context help for variables and functions Change-Id: I56aafb31f8e3a9df2677b98db03f82010b2564ca Reviewed-by: Eike Ziller --- src/plugins/qmakeprojectmanager/profilehoverhandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/profilehoverhandler.cpp b/src/plugins/qmakeprojectmanager/profilehoverhandler.cpp index f7d875778a7..bf4904e1239 100644 --- a/src/plugins/qmakeprojectmanager/profilehoverhandler.cpp +++ b/src/plugins/qmakeprojectmanager/profilehoverhandler.cpp @@ -61,7 +61,7 @@ void ProFileHoverHandler::identifyMatch(TextEditor::TextEditorWidget *editorWidg identifyQMakeKeyword(block.text(), pos - block.position()); if (m_manualKind != UnknownManual) { - QUrl url(QString::fromLatin1("qthelp://com.trolltech.qmake/qdoc/qmake-%1-reference.html#%2") + QUrl url(QString::fromLatin1("qthelp://org.qt-project.qmake/qmake/qmake-%1-reference.html#%2") .arg(manualName()).arg(m_docFragment)); setLastHelpItemIdentified(TextEditor::HelpItem(url.toString(), m_docFragment, TextEditor::HelpItem::QMakeVariableOfFunction)); @@ -134,7 +134,7 @@ void ProFileHoverHandler::identifyDocFragment(ProFileHoverHandler::ManualKind ma m_docFragment.replace(QLatin1Char('_'), QLatin1Char('-')); if (m_manualKind == FunctionManual) { - QUrl url(QString::fromLatin1("qthelp://com.trolltech.qmake/qdoc/qmake-%1-reference.html").arg(manualName())); + QUrl url(QString::fromLatin1("qthelp://org.qt-project.qmake/qmake/qmake-%1-reference.html").arg(manualName())); const QByteArray html = Core::HelpManager::fileData(url); Utils::HtmlDocExtractor htmlExtractor; From 3c1b1496d43d41e6a628b14abe0172f34a866151 Mon Sep 17 00:00:00 2001 From: Nikita Baryshnikov Date: Tue, 23 Jun 2015 18:13:00 +0300 Subject: [PATCH 035/113] ImageViewer: fix crash steps to reproduce: - open 'TestQtcCrash.jpg' - truncate -s 0 ./TestQtcCrash.jpg - write valid image back to 'TestQtcCrash.jpg' Change-Id: I76aed9379098c323f8434e0ab53b6561996fa281 Reviewed-by: Eike Ziller --- src/plugins/imageviewer/imageviewerfile.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/plugins/imageviewer/imageviewerfile.cpp b/src/plugins/imageviewer/imageviewerfile.cpp index 479dfa94f9a..663f94a1f7b 100644 --- a/src/plugins/imageviewer/imageviewerfile.cpp +++ b/src/plugins/imageviewer/imageviewerfile.cpp @@ -97,7 +97,6 @@ Core::IDocument::OpenResult ImageViewerFile::open(QString *errorString, const QS Core::IDocument::OpenResult ImageViewerFile::openImpl(QString *errorString, const QString &fileName) { cleanUp(); - m_type = TypeInvalid; if (!QFileInfo(fileName).isReadable()) return OpenResult::ReadError; @@ -112,14 +111,16 @@ Core::IDocument::OpenResult ImageViewerFile::openImpl(QString *errorString, cons #ifndef QT_NO_SVG if (format.startsWith("svg")) { - m_type = TypeSvg; m_tempSvgItem = new QGraphicsSvgItem(fileName); QRectF bound = m_tempSvgItem->boundingRect(); if (bound.width() == 0 && bound.height() == 0) { + delete m_tempSvgItem; + m_tempSvgItem = 0; if (errorString) *errorString = tr("Failed to read SVG image."); return OpenResult::CannotHandle; } + m_type = TypeSvg; emit imageSizeChanged(QSize()); } else #endif @@ -133,14 +134,15 @@ Core::IDocument::OpenResult ImageViewerFile::openImpl(QString *errorString, cons m_isPaused = false; // force update setPaused(true); } else { - m_type = TypePixmap; m_pixmap = new QPixmap(fileName); if (m_pixmap->isNull()) { if (errorString) *errorString = tr("Failed to read image."); delete m_pixmap; + m_pixmap = 0; return OpenResult::CannotHandle; } + m_type = TypePixmap; emit imageSizeChanged(m_pixmap->size()); } @@ -242,10 +244,14 @@ void ImageViewerFile::updateVisibility() void ImageViewerFile::cleanUp() { delete m_pixmap; + m_pixmap = 0; delete m_movie; + m_movie = 0; #ifndef QT_NO_SVG delete m_tempSvgItem; + m_tempSvgItem = 0; #endif + m_type = TypeInvalid; } bool ImageViewerFile::save(QString *errorString, const QString &fileName, bool autoSave) From f8a8c6cac3f7e1955025e72dde451e00c10a1077 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 23 Jun 2015 12:53:30 +0200 Subject: [PATCH 036/113] SSH: Do not tie key exchange methods to specific host key algorithms. Contrary to what I believed, all key exchange methods are compatible with all types of host key (at least for everything we support). Task-number: QTCREATORBUG-14621 Change-Id: Iacae3d36170b9841cceb3705780a64aeb15e10b9 Reviewed-by: Benjamin Zeller Reviewed-by: Christian Kandeler --- src/libs/ssh/sshbotanconversions_p.h | 11 ++++-- src/libs/ssh/sshincomingpacket.cpp | 54 +++++++++++++++++----------- src/libs/ssh/sshincomingpacket_p.h | 3 +- src/libs/ssh/sshkeyexchange.cpp | 46 ++++++++---------------- 4 files changed, 58 insertions(+), 56 deletions(-) diff --git a/src/libs/ssh/sshbotanconversions_p.h b/src/libs/ssh/sshbotanconversions_p.h index 31dc4899a72..75182881b91 100644 --- a/src/libs/ssh/sshbotanconversions_p.h +++ b/src/libs/ssh/sshbotanconversions_p.h @@ -118,11 +118,16 @@ inline const char *botanHMacAlgoName(const QByteArray &rfcAlgoName) inline quint32 botanHMacKeyLen(const QByteArray &rfcAlgoName) { - Q_ASSERT(rfcAlgoName == SshCapabilities::HMacSha1 - || rfcAlgoName == SshCapabilities::HMacSha256); if (rfcAlgoName == SshCapabilities::HMacSha1) return 20; - return 32; + if (rfcAlgoName == SshCapabilities::HMacSha256) + return 32; + if (rfcAlgoName == SshCapabilities::HMacSha384) + return 48; + if (rfcAlgoName == SshCapabilities::HMacSha512) + return 64; + throw SshClientException(SshInternalError, SSH_TR("Unexpected hashing algorithm \"%1\"") + .arg(QString::fromLatin1(rfcAlgoName))); } } // namespace Internal diff --git a/src/libs/ssh/sshincomingpacket.cpp b/src/libs/ssh/sshincomingpacket.cpp index f2101e54dea..1742c335a4a 100644 --- a/src/libs/ssh/sshincomingpacket.cpp +++ b/src/libs/ssh/sshincomingpacket.cpp @@ -30,6 +30,7 @@ #include "sshincomingpacket_p.h" +#include "ssh_global.h" #include "sshbotanconversions_p.h" #include "sshcapabilities_p.h" @@ -169,7 +170,32 @@ SshKeyExchangeInit SshIncomingPacket::extractKeyExchangeInitData() const return exchangeData; } -SshKeyExchangeReply SshIncomingPacket::extractKeyExchangeReply(const QByteArray &pubKeyAlgo) const +static void getHostKeySpecificReplyData(SshKeyExchangeReply &replyData, + const QByteArray &hostKeyAlgo, const QByteArray &input) +{ + quint32 offset = 0; + if (hostKeyAlgo == SshCapabilities::PubKeyDss || hostKeyAlgo == SshCapabilities::PubKeyRsa) { + // DSS: p and q, RSA: e and n + replyData.parameters << SshPacketParser::asBigInt(input, &offset); + replyData.parameters << SshPacketParser::asBigInt(input, &offset); + + // g and y + if (hostKeyAlgo == SshCapabilities::PubKeyDss) { + replyData.parameters << SshPacketParser::asBigInt(input, &offset); + replyData.parameters << SshPacketParser::asBigInt(input, &offset); + } + } else { + QSSH_ASSERT_AND_RETURN(hostKeyAlgo == SshCapabilities::PubKeyEcdsa); + if (SshPacketParser::asString(input, &offset) + != hostKeyAlgo.mid(11)) { // Without "ecdsa-sha2-" prefix. + throw SshPacketParseException(); + } + replyData.q = SshPacketParser::asString(input, &offset); + } +} + +SshKeyExchangeReply SshIncomingPacket::extractKeyExchangeReply(const QByteArray &kexAlgo, + const QByteArray &hostKeyAlgo) const { Q_ASSERT(isComplete()); Q_ASSERT(type() == SSH_MSG_KEXDH_REPLY); @@ -179,35 +205,23 @@ SshKeyExchangeReply SshIncomingPacket::extractKeyExchangeReply(const QByteArray quint32 topLevelOffset = TypeOffset + 1; replyData.k_s = SshPacketParser::asString(m_data, &topLevelOffset); quint32 k_sOffset = 0; - if (SshPacketParser::asString(replyData.k_s, &k_sOffset) != pubKeyAlgo) + if (SshPacketParser::asString(replyData.k_s, &k_sOffset) != hostKeyAlgo) throw SshPacketParseException(); + getHostKeySpecificReplyData(replyData, hostKeyAlgo, replyData.k_s.mid(k_sOffset)); - if (pubKeyAlgo == SshCapabilities::PubKeyDss || pubKeyAlgo == SshCapabilities::PubKeyRsa) { - - // DSS: p and q, RSA: e and n - replyData.parameters << SshPacketParser::asBigInt(replyData.k_s, &k_sOffset); - replyData.parameters << SshPacketParser::asBigInt(replyData.k_s, &k_sOffset); - - // g and y - if (pubKeyAlgo == SshCapabilities::PubKeyDss) { - replyData.parameters << SshPacketParser::asBigInt(replyData.k_s, &k_sOffset); - replyData.parameters << SshPacketParser::asBigInt(replyData.k_s, &k_sOffset); - } - + if (kexAlgo == SshCapabilities::DiffieHellmanGroup1Sha1) { replyData.f = SshPacketParser::asBigInt(m_data, &topLevelOffset); } else { - Q_ASSERT(pubKeyAlgo == SshCapabilities::PubKeyEcdsa); - if (SshPacketParser::asString(replyData.k_s, &k_sOffset) != pubKeyAlgo.mid(11)) // Without "ecdsa-sha2-" prefix. - throw SshPacketParseException(); - replyData.q = SshPacketParser::asString(replyData.k_s, &k_sOffset); + QSSH_ASSERT_AND_RETURN_VALUE(kexAlgo.startsWith(SshCapabilities::EcdhKexNamePrefix), + SshKeyExchangeReply()); replyData.q_s = SshPacketParser::asString(m_data, &topLevelOffset); } const QByteArray fullSignature = SshPacketParser::asString(m_data, &topLevelOffset); quint32 sigOffset = 0; - if (SshPacketParser::asString(fullSignature, &sigOffset) != pubKeyAlgo) + if (SshPacketParser::asString(fullSignature, &sigOffset) != hostKeyAlgo) throw SshPacketParseException(); replyData.signatureBlob = SshPacketParser::asString(fullSignature, &sigOffset); - if (pubKeyAlgo == SshCapabilities::PubKeyEcdsa) { + if (hostKeyAlgo == SshCapabilities::PubKeyEcdsa) { // Botan's PK_Verifier wants the signature in this format. quint32 blobOffset = 0; const Botan::BigInt r = SshPacketParser::asBigInt(replyData.signatureBlob, &blobOffset); diff --git a/src/libs/ssh/sshincomingpacket_p.h b/src/libs/ssh/sshincomingpacket_p.h index 9ea9d80278a..d2d17eed6ed 100644 --- a/src/libs/ssh/sshincomingpacket_p.h +++ b/src/libs/ssh/sshincomingpacket_p.h @@ -164,7 +164,8 @@ public: void reset(); SshKeyExchangeInit extractKeyExchangeInitData() const; - SshKeyExchangeReply extractKeyExchangeReply(const QByteArray &pubKeyAlgo) const; + SshKeyExchangeReply extractKeyExchangeReply(const QByteArray &kexAlgo, + const QByteArray &hostKeyAlgo) const; SshDisconnect extractDisconnect() const; SshUserAuthBanner extractUserAuthBanner() const; SshUserAuthInfoRequestPacket extractUserAuthInfoRequest() const; diff --git a/src/libs/ssh/sshkeyexchange.cpp b/src/libs/ssh/sshkeyexchange.cpp index c553ecc8b22..62071e4fc70 100644 --- a/src/libs/ssh/sshkeyexchange.cpp +++ b/src/libs/ssh/sshkeyexchange.cpp @@ -30,6 +30,7 @@ #include "sshkeyexchange_p.h" +#include "ssh_global.h" #include "sshbotanconversions_p.h" #include "sshcapabilities_p.h" #include "sshsendfacility_p.h" @@ -115,28 +116,8 @@ bool SshKeyExchange::sendDhInitPacket(const SshIncomingPacket &serverKexInit) m_kexAlgoName = SshCapabilities::findBestMatch(SshCapabilities::KeyExchangeMethods, kexInitParams.keyAlgorithms.names); - const QList &commonHostKeyAlgos - = SshCapabilities::commonCapabilities(SshCapabilities::PublicKeyAlgorithms, - kexInitParams.serverHostKeyAlgorithms.names); - const bool ecdh = m_kexAlgoName.startsWith(SshCapabilities::EcdhKexNamePrefix); - foreach (const QByteArray &possibleHostKeyAlgo, commonHostKeyAlgos) { - if (ecdh && possibleHostKeyAlgo == SshCapabilities::PubKeyEcdsa) { - m_serverHostKeyAlgo = possibleHostKeyAlgo; - break; - } - if (!ecdh && (possibleHostKeyAlgo == SshCapabilities::PubKeyDss - || possibleHostKeyAlgo == SshCapabilities::PubKeyRsa)) { - m_serverHostKeyAlgo = possibleHostKeyAlgo; - break; - } - } - if (m_serverHostKeyAlgo.isEmpty()) { - throw SshServerException(SSH_DISCONNECT_KEY_EXCHANGE_FAILED, - "Invalid combination of key exchange and host key algorithms.", - QCoreApplication::translate("SshConnection", - "No matching host key algorithm available for key exchange algorithm \"%1\".") - .arg(QString::fromLatin1(m_kexAlgoName))); - } + m_serverHostKeyAlgo = SshCapabilities::findBestMatch(SshCapabilities::PublicKeyAlgorithms, + kexInitParams.serverHostKeyAlgorithms.names); determineHashingAlgorithm(kexInitParams, true); determineHashingAlgorithm(kexInitParams, false); @@ -152,7 +133,7 @@ bool SshKeyExchange::sendDhInitPacket(const SshIncomingPacket &serverKexInit) kexInitParams.compressionAlgorithmsServerToClient.names); AutoSeeded_RNG rng; - if (ecdh) { + if (m_kexAlgoName.startsWith(SshCapabilities::EcdhKexNamePrefix)) { m_ecdhKey.reset(new ECDH_PrivateKey(rng, EC_Group(botanKeyExchangeAlgoName(m_kexAlgoName)))); m_sendFacility.sendKeyEcdhInitPacket(convertByteArray(m_ecdhKey->public_value())); } else { @@ -169,7 +150,7 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, { const SshKeyExchangeReply &reply - = dhReply.extractKeyExchangeReply(m_serverHostKeyAlgo); + = dhReply.extractKeyExchangeReply(m_kexAlgoName, m_serverHostKeyAlgo); if (m_dhKey && (reply.f <= 0 || reply.f >= m_dhKey->group_p())) { throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_KEY_EXCHANGE_FAILED, "Server sent invalid f."); @@ -187,6 +168,7 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, DH_KA_Operation dhOp(*m_dhKey); SecureVector encodedF = BigInt::encode(reply.f); encodedK = dhOp.agree(encodedF, encodedF.size()); + m_dhKey.reset(nullptr); } else { Q_ASSERT(m_ecdhKey); concatenatedData // Q_C. @@ -194,7 +176,9 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, concatenatedData += AbstractSshPacket::encodeString(reply.q_s); ECDH_KA_Operation ecdhOp(*m_ecdhKey); encodedK = ecdhOp.agree(convertByteArray(reply.q_s), reply.q_s.count()); + m_ecdhKey.reset(nullptr); } + const BigInt k = BigInt::decode(encodedK); m_k = AbstractSshPacket::encodeMpInt(k); // Roundtrip, as Botan encodes BigInts somewhat differently. concatenatedData += m_k; @@ -228,13 +212,13 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, RSA_PublicKey * const rsaKey = new RSA_PublicKey(reply.parameters.at(1), reply.parameters.at(0)); sigKey.reset(rsaKey); - } else if (m_serverHostKeyAlgo == SshCapabilities::PubKeyEcdsa) { - const PointGFp point = OS2ECP(convertByteArray(reply.q), reply.q.count(), - m_ecdhKey->domain().get_curve()); - ECDSA_PublicKey * const ecdsaKey = new ECDSA_PublicKey(m_ecdhKey->domain(), point); - sigKey.reset(ecdsaKey); } else { - Q_ASSERT(!"Impossible: Neither DSS nor RSA nor ECDSA!"); + QSSH_ASSERT_AND_RETURN(m_serverHostKeyAlgo == SshCapabilities::PubKeyEcdsa); + const EC_Group domain("secp256r1"); + const PointGFp point = OS2ECP(convertByteArray(reply.q), reply.q.count(), + domain.get_curve()); + ECDSA_PublicKey * const ecdsaKey = new ECDSA_PublicKey(domain, point); + sigKey.reset(ecdsaKey); } const byte * const botanH = convertByteArray(m_h); @@ -248,8 +232,6 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, checkHostKey(reply.k_s); m_sendFacility.sendNewKeysPacket(); - m_dhKey.reset(nullptr); - m_ecdhKey.reset(nullptr); } QByteArray SshKeyExchange::hashAlgoForKexAlgo() const From 83957912fe4206b3f805c34dbea7ba2a14daa9c5 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 24 Jun 2015 13:31:41 +0200 Subject: [PATCH 037/113] Clang: Fix compilation with clang Change-Id: I7c81e5d06564c43fb6ac2ee5d538ad6b7565c73c Reviewed-by: Nikolai Kosjar --- src/libs/clangbackendipc/projectpartcontainer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/clangbackendipc/projectpartcontainer.cpp b/src/libs/clangbackendipc/projectpartcontainer.cpp index 9472eea063c..50b4bcc6a40 100644 --- a/src/libs/clangbackendipc/projectpartcontainer.cpp +++ b/src/libs/clangbackendipc/projectpartcontainer.cpp @@ -85,7 +85,7 @@ bool operator<(const ProjectPartContainer &first, const ProjectPartContainer &se static Utf8String quotedArguments(const Utf8StringVector &arguments) { const Utf8String quote = Utf8String::fromUtf8("\""); - const Utf8String joined = arguments.join(quote + QString::fromUtf8(" ") + quote); + const Utf8String joined = arguments.join(quote + Utf8String::fromUtf8(" ") + quote); return quote + joined + quote; } From e670d9f341ccb516f5a69cd41e9a5dc8279f7cb0 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 23 Jun 2015 12:43:21 +0200 Subject: [PATCH 038/113] CDB: Print non extension output when verbose log is enabled. Change-Id: I0fb308794220d08be43b81ed2d56fd558411e650 Reviewed-by: Christian Stenger --- src/plugins/debugger/cdb/cdbengine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 27fd6f79314..3b26d2be832 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -2499,6 +2499,8 @@ void CdbEngine::parseOutputLine(QByteArray line) currentCommand->response.command.constData(), currentCommand->token, currentCommand->response.builtinReply.size(), m_builtinCommandQueue.size() - 1); QTC_ASSERT(token == currentCommand->token, return; ); + if (boolSetting(VerboseLog)) + showMessage(QLatin1String(currentCommand->response.builtinReply.join(' ')), LogMisc); if (currentCommand->handler) { currentCommand->handler(currentCommand->response); } From 3b7410f8dd7c2dc595f5bc6240907fae59e23f61 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 23 Jun 2015 09:09:08 +0200 Subject: [PATCH 039/113] CDB: Stop locals progress indicator when command failed. Change-Id: I37d986c249f2706a474c7d517090d98e7bd19f22 Reviewed-by: Christian Stenger --- src/plugins/debugger/cdb/cdbengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 3b26d2be832..3d62895d7d7 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -1778,8 +1778,8 @@ void CdbEngine::handleRegistersExt(const CdbResponse &response) void CdbEngine::handleLocals(const CdbResponse &response, bool partialUpdate) { + watchHandler()->notifyUpdateFinished(); if (response.success) { - watchHandler()->notifyUpdateFinished(); if (boolSetting(VerboseLog)) showMessage(QLatin1String("Locals: ") + QString::fromLatin1(response.extensionReply), LogDebug); From b4db657cb5fd9024e1410438e9b6b314a86d180f Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 18 Jun 2015 12:08:07 +0200 Subject: [PATCH 040/113] CppTools: Remove invalid QTC_CHECK Quitting Qt Creator before the project was loaded from the project manager triggers the assert because the updateProjectInfo() call was not yet made by the project manager. Change-Id: I23c660971e48d007d1bae00ecf8ed5c2ad3d4071 Reviewed-by: Christian Stenger Reviewed-by: Marco Bubke --- src/plugins/cpptools/cppmodelmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index a529c464fab..01132b9ebbc 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -988,14 +988,14 @@ void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project) // Save paths const ProjectInfo projectInfo = d->m_projectToProjectsInfo.value(project, ProjectInfo()); - QTC_CHECK(projectInfo.isValid()); projectFilePaths = pathsOfAllProjectParts(projectInfo); d->m_projectToProjectsInfo.remove(project); recalculateFileToProjectParts(); } - emit projectPartsRemoved(projectFilePaths); + if (!projectFilePaths.isEmpty()) + emit projectPartsRemoved(projectFilePaths); delayedGC(); } From 79251408eac8bea12dd4437c4898d5d898905d87 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 24 Jun 2015 15:21:29 +0200 Subject: [PATCH 041/113] CDB: Fix expanding watchers. Discard old watchers only when entering a new frame. Change-Id: I4a0ac6af7c6970f7a0d4c58636bf9f51ecab9505 Reviewed-by: Christian Stenger --- src/plugins/debugger/cdb/cdbengine.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 3d62895d7d7..558ff461cc8 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -1396,9 +1396,10 @@ void CdbEngine::doUpdateLocals(const UpdateParameters &updateParameters) str << '"'; } } - if (!partialUpdate || isWatch) { - // Perform watches synchronization + // Perform watches synchronization only for full updates + if (!partialUpdate) str << blankSeparator << "-W"; + if (!partialUpdate || isWatch) { const WatcherHash watcherHash = WatchHandler::watcherNames(); if (!watcherHash.isEmpty()) { const WatcherHash::const_iterator cend = watcherHash.constEnd(); From 7b401a15570f9935ceccee805ef5e1071b97aaa8 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 23 Jun 2015 16:59:42 +0200 Subject: [PATCH 042/113] Doc: Polish qtcreator-documentation.qdoc Add a couple of \c's in places and reformat the text where necessary. Change-Id: Ib4083af1e9deadcc1c12e94f6ccb77c0432d7ff5 Reviewed-by: Leena Miettinen --- doc/api/qtcreator-documentation.qdoc | 81 +++++++++++----------------- 1 file changed, 31 insertions(+), 50 deletions(-) diff --git a/doc/api/qtcreator-documentation.qdoc b/doc/api/qtcreator-documentation.qdoc index 0d9fc3d3937..91374ec64ec 100644 --- a/doc/api/qtcreator-documentation.qdoc +++ b/doc/api/qtcreator-documentation.qdoc @@ -24,10 +24,10 @@ \title Writing Documentation When you add plugins or contribute new features to \QC, you probably want - other people to know about them and to be able to use them. Therefore, - you should also contribute documentation for them. Follow the guidelines in - this section to make sure that your documentation fits in well with the rest - of the \QC documentation. + other people to know about them and to be able to use them. Therefore, you + should also contribute documentation for them. Follow the guidelines in this + section to make sure that your documentation fits in well with the rest of + the \QC documentation. When you contribute a plugin, you should write documentation both for the developers who use \QC and for the ones who develop it. @@ -35,7 +35,6 @@ Write the following user documentation for addition to the \QC Manual: \list - \li Overview topic, which describes the purpose of your plugin from the viewpoint of \QC users @@ -43,58 +42,52 @@ \li Reference topics, which contain information that developers occasionally need to look up (optional) - \endlist Write the following developer documentation for addition to the Extending \QC Manual: \list - \li Overview topic, which describes the architecture and use cases for your plugin from the viewpoint of \QC developers \li API documentation, which is generated from code comments - \endlist \section1 Configuring the Documentation Project \QC documentation is written by using QDoc. For more information about using - QDoc, see the \l{http://doc.qt.io/qt-5/qdoc-index.html} - {QDoc Manual}. + QDoc, see the \l{http://doc.qt.io/qt-5/qdoc-index.html}{QDoc Manual}. - QDoc finds the new topics automatically, when you place them as .qdoc files - in the correct folder. However, to make the topics accessible to readers, - you must also add them to the table of contents and fix the next page and - previous page links to them from other topics. + QDoc finds the new topics automatically, when you place them as \c {.qdoc} + files in the correct folder. However, to make the topics accessible to + readers, you must also add them to the table of contents and fix the next + page and previous page links to them from other topics. \section2 Creating Folders and Files These instructions apply only to the \QC Manual. Add API documentation directly to the code source files. However, you can write an API overview - also as a separate .qdoc file. + also as a separate \c {.qdoc} file. Create a subfolder for your documentation in the \QC project folder in the \c {doc\src} folder. Create a separate file for each topic. The easiest way is probably to copy an existing file, save it as a new file, - and modify it. This way, you already have samples of the necessary bits - and pieces in place, such as topic start and end commands, copyright - statement, links to next and previous topics, and topic title. + and modify it. This way, you already have samples of the necessary bits and + pieces in place, such as topic start and end commands, copyright statement, + links to next and previous topics, and topic title. \section2 Integrating Topics to Documentation - You must integrate your new topics to the \QC Manual and Extending - \QC Manual by adding links to them to the table of contents and to other + You must integrate your new topics to the \QC Manual and Extending \QC + Manual by adding links to them to the table of contents and to other relevant topics. To link to the topic, you can use the topic title. For example: \code - \l{Integrating Topics to Documentation} - \endcode This does not work if topic titles are not unique. Also, if you change the @@ -105,7 +98,7 @@ When you add new topics to a document, you must also change the navigation links of the topics around them. This is very error prone when done - manually, and therefore we have a script called \c fixnavi.pl for it. For + manually, and therefore we have a script called \c {fixnavi.pl} for it. For the script to work, you must add the \c {\nextpage} and \c {\previouspage} commands to the topic, with dummy values (for example, \c {\nextpage=anything.html}). @@ -121,23 +114,20 @@ To run the script, enter the following command in the doc folder: \list - \li nmake fixnavi (on Windows) \li make fixnavi (on Linux) - \endlist \section1 Writing Text Follow the guidelines for - \l{http://wiki.qt.io/Writing_Qt_Documentation} - {writing Qt documentation}. + \l{http://wiki.qt.io/Writing_Qt_Documentation}{writing Qt documentation}. The documentation must be grammatically correct English and use the standard form of written language. Do not use dialect or slang words. Use idiomatic - language, that is, expressions that are characteristic for English. - If possible, ask a native English speaker for a review. + language, that is, expressions that are characteristic for English. If + possible, ask a native English speaker for a review. \section2 Capitalizing Headings @@ -159,11 +149,11 @@ \section2 Taking Screen Shots - \QC has the native look and feel on Windows, Linux, and OS X, and - therefore, screen shots can end up looking very different, depending on who - takes them and which system they use. To try to preserve a consistent look - and feel in the \QC Manual, observe the guidelines listed in this section - when taking screen shots. + \QC has the native look and feel on Windows, Linux, and OS X, and therefore, + screen shots can end up looking very different, depending on who takes them + and which system they use. To try to preserve a consistent look and feel in + the \QC Manual, observe the guidelines listed in this section when taking + screen shots. To make the images look similar regardless of the operating system they were taken on, you are asked to adjust their size to 75%. This makes the screen @@ -173,7 +163,6 @@ place example values also in the text. \list - \li Use the screen resolution of 1024x768 (this is available on all screens). @@ -194,7 +183,6 @@ \li Before you submit the images to the repository, optimize them to save space. - \endlist \section2 Optimizing Images @@ -210,10 +198,9 @@ it. You can use a web service, such as \l{https://tinypng.com}, or an image - optimization tool to shrink the images. For example, you - can use the Radical Image Optimization Tool (RIOT) on Windows (very - efficient) or ImageOptim on OS X (much less efficient), or some other tool - available on Linux. + optimization tool to shrink the images. For example, you can use the Radical + Image Optimization Tool (RIOT) on Windows (very efficient) or ImageOptim on + OS X (much less efficient), or some other tool available on Linux. With ImageOptim, you simply drag and drop the image files to the application. The following section describes the settings to use for RIOT. @@ -227,7 +214,6 @@ Open your images in RIOT and use the following settings for them: \list - \li Color reduction: Optimal 256 colors palette \li Reduce colors to: 256 @@ -237,7 +223,6 @@ \li Color quantization algorithm: NeuQuant neural-net (slow) \li External optimizers: OptiPNG o3 - \endlist Compare the initial and optimized images to check that image quality is @@ -264,7 +249,6 @@ qdocconf file: \list - \li \c {include ($QT_INSTALL_DOCS/global/qt-html-templates-offline.qdocconf)} for help files \li \c {include ($QT_INSTALL_DOCS/global/qt-html-templates-online.qdocconf)} @@ -285,27 +269,25 @@ commands from the project folder (after running qmake): \list - \li nmake docs (on Windows) - \li make docs (on Linux and OS X) + \li make docs (on Linux and OS X) \endlist The \QC Manual HTML files are generated in the \c {doc/html} directory. The Extending \QC Manual files are generated in the - \c {doc/html-dev} directory. The help files (.qch) are generated in the + \c {doc/html-dev} directory. The help files (\c {.qch}) are generated in the \c {share/doc/qtcreator} directory in the \QC build directory on Windows and Linux, and in the \c {bin/Qt Creator.app/Contents/Resources/app} directory on OS X. You can view the HTML files in a browser and the help files in - the \QC \uicontrol Help mode. For more information about adding the help files to - \QC, see + the \QC \uicontrol Help mode. For more information about adding the help + files to \QC, see \l{http://doc.qt.io/qtcreator/creator-help.html#adding-external-documentation} {Adding External Documentation}. Besides \c docs, you have the following options: \list - \li html_docs - build \QC Manual in help format, but do not generate a help file @@ -324,7 +306,6 @@ \li html_docs_online - build \QC Manual in online format \li dev_html_docs_online - build Extending \QC Manual in online format - \endlist */ From 38104bf0d4a71aafe32000850e8b4ce2f219980d Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 23 Jun 2015 15:45:36 +0200 Subject: [PATCH 043/113] Doc: Polish first-plugin.qdoc * Use \uicontrol and \c more * Break lines * No text change, but some formatting changes Change-Id: Ic2d19c2dda6c239e26ce2765c63b9d3f58645485 Reviewed-by: Leena Miettinen --- doc/api/first-plugin.qdoc | 307 ++++++++++++++++++++------------------ 1 file changed, 164 insertions(+), 143 deletions(-) diff --git a/doc/api/first-plugin.qdoc b/doc/api/first-plugin.qdoc index 2684271b48d..da223a6e13d 100644 --- a/doc/api/first-plugin.qdoc +++ b/doc/api/first-plugin.qdoc @@ -21,28 +21,29 @@ \title Creating Your First Plugin This section describes how to create a \QC plugin by using the plugin - template provided by \QC, and get the first impression of what - a plugin consists of and what its general structure is. + template provided by \QC, and get the first impression of what a plugin + consists of and what its general structure is. \section1 Creating a Plugin Project - \QC comes with a wizard for \QC plugins, that creates a - runable, \e minimal plugin for you. We strongly suggest that you - use two different \QC instances for developing and testing - your plugin with. Otherwise your plugin will also be loaded in your - development environment, which can make that unstable while your - plugin is still unstable. You can just create a copy of your \QC - build and use one for actually developing, and the other for testing - your plugin with. + \QC comes with a wizard for \QC plugins, that creates a runable, \e minimal + plugin for you. We strongly suggest that you use two different \QC instances + for developing and testing your plugin with. Otherwise your plugin will also + be loaded in your development environment, which can make that unstable + while your plugin is still unstable. You can just create a copy of your \QC + build and use one for actually developing, and the other for testing your + plugin with. - You need to make sure that you use the same \QC version that you want - to develop for to create the plugin. Because of the - \l{Binary and Source Compatibility} rules of \QC, the \QC plugin wizard - creates a plugin that might only compile and run with the same \QC - version that it was created with. + You need to make sure that you use the same \QC version that you want to + develop for to create the plugin. Because of the \l{Binary and Source + Compatibility} rules of \QC, the \QC plugin wizard creates a plugin that + might only compile and run with the same \QC version that it was created + with. \list 1 - \li Select \uicontrol{File > New File or Project > Library > Qt Creator Plugin > Choose}. + \li Select \uicontrol File > \uicontrol {New File or Project} > + \uicontrol Library > \uicontrol {Qt Creator Plugin} > + \uicontrol Choose. \image firstplugin-wizard.png "Choose the \QC Plugin Wizard" @@ -50,65 +51,73 @@ \image firstplugin-nameandpath.png "Choose Name and Place of the Project" - \li Give your project a name and specify in which path - this project will be created. The actual plugin's name can be different - from the project name. You will choose that name later in the wizard. + \li Give your project a name and specify in which path this project will + be created. The actual plugin's name can be different from the + project name. You will choose that name later in the wizard. Continue to the next page. The \uicontrol{Kit Selection} dialog opens. \image firstplugin-kitselection.png "Choose the kit to build and run your project with" - \li Select the \l{glossary-buildandrun-kit}{kit} to build and run your project with. - For a \QC plugin this needs to be a kit with \uicontrol{Desktop} device type, - and a Qt version that is compatible with the Qt version that your - \QC was built with (in the best case the exact same build). - If you use an incompatible Qt version to build your plugin, you - will get errors while \QC tries to load your plugin. - Continue to the next page. + \li Select the \l{glossary-buildandrun-kit}{kit} to build and run your + project with. For a \QC plugin this needs to be a kit with + \uicontrol Desktop device type, and a Qt version that is compatible + with the Qt version that your \QC was built with (in the best case + the exact same build). If you use an incompatible Qt version to + build your plugin, you will get errors while \QC tries to load your + plugin. Continue to the next page. The \uicontrol{Plugin Information} dialog opens. \image firstplugin-pluginsetup.png "Specify Your Plugin Details" - \li In the \uicontrol{Plugin name} field, type \uicontrol{Example}. The name of the plugin - is used as its identifier, and also is the base for the file names and - classes in the code. + \li In the \uicontrol {Plugin name} field, type \uicontrol Example. The + name of the plugin is used as its identifier, and also is the base + for the file names and classes in the code. \li The values of the following fields are mainly informational, and are shown in the detailed view in \QC's plugin overview - (\uicontrol{Help > About Plugins}, or \uicontrol{Qt Creator > About Plugins} - on Mac). + (\uicontrol Help > \uicontrol {About Plugins}, or + \uicontrol {Qt Creator} > \uicontrol {About Plugins} on Mac). \list - \li \uicontrol{Vendor name} is a short one-word name of the company - or organization that created the plugin. This is also used for - the path name where the plugin will be deployed to. - \li \uicontrol{Copyright} is a one-line, short copyright string. - \li \uicontrol{License} is a multi-line license text (but shouldn't be pages over pages long, - since the interface doesn't allow nice reading of long texts). - \li \uicontrol{Description} is a relatively short, but - possibly multi-line description of what the plugin does. - \li \uicontrol{URL} is a website where the user can find more - information about the plugin and/or organization providing it. + \li \uicontrol {Vendor name} is a short one-word name of the + company or organization that created the plugin. This is + also used for the path name where the plugin will be + deployed to. + + \li \uicontrol Copyright is a one-line, short copyright string. + + \li \uicontrol License is a multi-line license text (but + shouldn't be pages over pages long, since the interface + doesn't allow nice reading of long texts). + + \li \uicontrol{Description} is a relatively short, but possibly + multi-line description of what the plugin does. + + \li \uicontrol URL is a website where the user can find more + information about the plugin and/or organization providing + it. \endlist - \li Set the \uicontrol{Qt Creator sources} and \uicontrol{Qt Creator build} fields to - the source and build directory of the \QC - instance you want to use to test your plugin with, respectively. - If you don't do that correctly you will get compile errors for your - plugin, and your plugin might not show up in \QC at all. + \li Set the \uicontrol {Qt Creator sources} and + \uicontrol{Qt Creator build} fields to the source and build + directory of the \QC instance you want to use to test your plugin + with, respectively. If you don't do that correctly you will get + compile errors for your plugin, and your plugin might not show up in + \QC at all. - \li In the \uicontrol{Deploy into} list, select \uicontrol{Qt Creator build}. This sets - your .pro file up to deploy your plugin directly into your \QC build's - plugin directory (requires you to have write permissions there). - The other option, \uicontrol{Local user settings}, sets your .pro file up to - deploy your plugin into \QC's user plugin path - (for example \c{~/.config/QtProject/qtcreator/plugins} on Unix systems). - We choose \uicontrol{Qt Creator build} because we use a self-compiled + \li In the \uicontrol {Deploy into} list, select + \uicontrol {Qt Creator build}. This sets your \c {.pro} file up to + deploy your plugin directly into your \QC build's plugin directory + (requires you to have write permissions there). The other option, + \uicontrol {Local user settings}, sets your \c {.pro} file up to + deploy your plugin into \QC's user plugin path (for example + \c {~/.config/QtProject/qtcreator/plugins} on Unix systems). We + choose \uicontrol {Qt Creator build} because we use a self-compiled \QC, and want the plugin to be only loaded by that \QC - instance. - Continue to the next page. + instance. Continue to the next page. The \uicontrol{Project Management} dialog opens. @@ -121,30 +130,32 @@ \section1 Building and Running the Plugin - If you passed the correct \QC source and build paths in the project - wizard, your plugin should just build fine when pressing the build button. - When you try to run your project, \QC will ask you for the executable to run and - you are presented the following dialog: + If you passed the correct \QC source and build paths in the project wizard, + your plugin should just build fine when pressing the build button. When you + try to run your project, \QC will ask you for the executable to run and you + are presented the following dialog: \image firstplugin-runsettings.png "Specify the Executable to Run" - Select the path to the \QC executable from the build that you specified - in the \uicontrol{Qt Creator build} setting in the project wizard and click \uicontrol OK. - \QC starts up, and you can verify that your plugin successfully loaded - by looking for a menu entry \uicontrol{Tools > Example} and by looking for - the plugin in the \uicontrol{About Plugins} dialog. + Select the path to the \QC executable from the build that you specified in + the \uicontrol {Qt Creator build} setting in the project wizard and click + \uicontrol OK. \QC starts up, and you can verify that your plugin + successfully loaded by looking for a menu entry \uicontrol Tools > + \uicontrol Example and by looking for the plugin in the + \uicontrol {About Plugins} dialog. \image firstplugin-menuitem.png "Menu Registered by the Plugin" \section1 File Structure - The plugin wizard creates a set of basic files that a plugin needs or should have. - We will have a look at some of them in detail in the following sections, here is a short - overview: + The plugin wizard creates a set of basic files that a plugin needs or should + have. We will have a look at some of them in detail in the following + sections, here is a short overview: \table \header \li File + \li Role \row \li \c{Example.json.in} @@ -164,22 +175,25 @@ \li Header defining constants used by the plugin code. \row \li \c{exampleplugin.h/.cpp} + \li C++ header and source files that define the plugin class that will be instanciated and run by \QC's plugin manager. \endtable \section1 qmake Project - The qmake project file \c{example.pro} defines how your plugin should be compiled. - \QC plugins need to have a specific setup there, in addition to telling qmake - which files need to be compiled (or handled by \c moc or \c uic). - Let us have a look at what the project wizard generated for you in detail. + The qmake project file \c {example.pro} defines how your plugin should be + compiled. \QC plugins need to have a specific setup there, in addition to + telling qmake which files need to be compiled (or handled by \c moc or + \c uic). Let us have a look at what the project wizard generated for you in + detail. \snippet exampleplugin/example.pro 1 - The first section of the .pro file lets the compiler pass an \c EXAMPLE_LIBRARY define to the - compiled code, which is used in the \c{example_global.h} header, but is not really of interest - for now. You should not need to change that section of the .pro file. + The first section of the .pro file lets the compiler pass an + \c EXAMPLE_LIBRARY define to the compiled code, which is used in the + \c {example_global.h} header, but is not really of interest for now. You + should not need to change that section of the \c {.pro} file. \snippet exampleplugin/example.pro 2 @@ -189,75 +203,79 @@ \snippet exampleplugin/example.pro 3 - To compile and deploy your plugin, the project needs access to the \QC sources and - build. This section contains the logic that looks for the information about - the location of the sources and build in the \c{QTC_SOURCE} and \c{QTC_BUILD} - environment variables. If these are not defined, it uses the defaults you - set in the project wizard. + To compile and deploy your plugin, the project needs access to the \QC + sources and build. This section contains the logic that looks for the + information about the location of the sources and build in the + \c {QTC_SOURCE} and \c {QTC_BUILD} environment variables. If these are not + defined, it uses the defaults you set in the project wizard. So, if someone else opens your plugin project on their machine, they do not - need to edit the .pro file, but instead they should set the \c{QTC_SOURCE} and - \c{QTC_BUILD} environment variables correctly for the plugin's build environment. + need to edit the .pro file, but instead they should set the \c {QTC_SOURCE} + and \c {QTC_BUILD} environment variables correctly for the plugin's build + environment. - You should not need to change this section, except perhaps to adapt the defaults. + You should not need to change this section, except perhaps to adapt the + defaults. \snippet exampleplugin/example.pro 4 - \QC plugins can either be installed into the \QC installation's plugin directory - (requires write access there), or to a user specific plugin directory. - The \c USE_USER_DESTDIR switch in the .pro file defines which method is used for building - the plugin (which is independent from what you can later use for distributing your - plugin to other users). + \QC plugins can either be installed into the \QC installation's plugin + directory (requires write access there), or to a user specific plugin + directory. The \c USE_USER_DESTDIR switch in the .pro file defines which + method is used for building the plugin (which is independent from what you + can later use for distributing your plugin to other users). \snippet exampleplugin/example.pro 5 - This section defines the name and dependencies of your plugin. - The \c{QTC_PLUGIN_NAME} variable defines the name of your plugin, and the name of the - dynamic library that is created for it. The \c{QTC_LIB_DEPENDS} variable is a list of - library names of the \QC utility libraries that your plugin depends on. - Typical values would be \c{aggregation}, \c{extensionsystem} and \c{utils}. - The \c{QTC_PLUGIN_DEPENDS} variable defines the \QC plugins that your plugin depends on. - Almost all \QC plugins will depend on the \c{coreplugin}. The \c{QTC_PLUGIN_RECOMMENDS} - variable defines the \QC plugins that your plugin optionally depends on. For more information, - see \l{Optional Dependencies}. + This section defines the name and dependencies of your plugin. The + \c {QTC_PLUGIN_NAME} variable defines the name of your plugin, and the name + of the dynamic library that is created for it. The \c {QTC_LIB_DEPENDS} + variable is a list of library names of the \QC utility libraries that your + plugin depends on. Typical values would be \c aggregation, + \c extensionsystem and \c utils. The \c {QTC_PLUGIN_DEPENDS} variable + defines the \QC plugins that your plugin depends on. Almost all \QC plugins + will depend on the \c coreplugin. The \c {QTC_PLUGIN_RECOMMENDS} variable + defines the \QC plugins that your plugin optionally depends on. For more + information, see \l{Optional Dependencies}. \snippet exampleplugin/example.pro 6 - The included file \c{qtcreatorplugin.pri} makes sure that you build a plugin that is suitable - for use in \QC, by using the information you gave above. + The included file \c{qtcreatorplugin.pri} makes sure that you build a plugin + that is suitable for use in \QC, by using the information you gave above. - For more information about qmake, and writing .pro files in general, + For more information about qmake, and writing \c {.pro} files in general, see the \l{qmake Manual}. \section1 Plugin Meta Data Template - The .json file is a JSON file that contains information that is needed by - the plugin manager to find your plugin and resolve its dependencies before actually - loading your plugin's library file. We will only have a short look at it here. - For more information, see \l{Plugin Meta Data}. + The \c {.json} file is a JSON file that contains information that is needed + by the plugin manager to find your plugin and resolve its dependencies + before actually loading your plugin's library file. We will only have a + short look at it here. For more information, see \l{Plugin Meta Data}. The wizard doesn't actually create a .json file directly, but instead a - .json.in file. qmake uses this to generate the actual plugin .json meta data - file, replacing variables like \c{QTCREATOR_VERSION} with their actual values. - Therefore you need to escape all backslashes and quotes in the .json.in file - (i.e. you need to write \c{\\} to get a backslash and \c{\"} to get a quote - in the generated plugin JSON meta data). + \c {.json.in} file. qmake uses this to generate the actual plugin .json + meta data file, replacing variables like \c {QTCREATOR_VERSION} with their + actual values. Therefore you need to escape all backslashes and quotes in + the \c {.json.in} file (i.e. you need to write \c {\} to get a backslash + and \c{\"} to get a quote in the generated plugin JSON meta data). \snippet exampleplugin/Example.json.in 1 - The first items in the meta data that is created by the wizard - define the name of your plugin, its version, and with what version of this plugin - the current version is binary compatible with. + The first items in the meta data that is created by the wizard define the + name of your plugin, its version, and with what version of this plugin the + current version is binary compatible with. \snippet exampleplugin/Example.json.in 2 - After that you'll find the information about the plugin - that you gave in the project wizard. + After that you'll find the information about the plugin that you gave in the + project wizard. \snippet exampleplugin/Example.json.in 3 - The \c{$$dependencyList} variable is automatically replaced by the dependency information - in \c{QTC_PLUGIN_DEPENDS} and \c{QTC_PLUGIN_RECOMMENDS} from your plugin's .pro file. + The \c {$$dependencyList} variable is automatically replaced by the + dependency information in \c {QTC_PLUGIN_DEPENDS} and + \c {QTC_PLUGIN_RECOMMENDS} from your plugin's \c {.pro} file. \section1 Plugin Class @@ -267,28 +285,29 @@ \section2 Header File - The header file \c{exampleplugin.h} defines the interface of the plugin class. + The header file \c {exampleplugin.h} defines the interface of the plugin + class. \snippet exampleplugin/exampleplugin.h namespaces - The plugin is defined in a \c{Example::Internal} namespace, which conforms to - the coding rules for \l{coding-rules-namespacing}{namespacing} + The plugin is defined in a \c {Example::Internal} namespace, which conforms + to the coding rules for \l{coding-rules-namespacing}{namespacing} in \QC sources. \snippet exampleplugin/exampleplugin.h base class All \QC plugins must be derived from \l{ExtensionSystem::IPlugin} and - are QObjects. The \c{Q_PLUGIN_METADATA} macro is necessary to create a valid Qt plugin. - The \c IID given in the macro must be \c{org.qt-project.Qt.QtCreatorPlugin}, to identify it - as a \QC plugin, and \c FILE must point to the plugin's meta data file as described - in \l{Plugin Meta Data}. + are QObjects. The \c {Q_PLUGIN_METADATA} macro is necessary to create a + valid Qt plugin. The \c IID given in the macro must be + \c {org.qt-project.Qt.QtCreatorPlugin}, to identify it as a \QC plugin, and + \c FILE must point to the plugin's meta data file as described in + \l{Plugin Meta Data}. \snippet exampleplugin/exampleplugin.h plugin functions The base class defines basic functions that are called during the life cycle - of a plugin, which are here implemented for your new plugin. - These functions and their roles are described in detail in - \l{The Plugin Life Cycle}. + of a plugin, which are here implemented for your new plugin. These functions + and their roles are described in detail in \l{The Plugin Life Cycle}. \snippet exampleplugin/exampleplugin.h slot @@ -297,34 +316,36 @@ \section2 Source File - The source file contains the actual implementation of the plugin, which registers - a new menu and menu item, and opens a message box when that item is triggered. + The source file contains the actual implementation of the plugin, which + registers a new menu and menu item, and opens a message box when that item + is triggered. - All the necessary header files from the plugin code itself, - from the Core plugin, and from Qt are included in the beginning of the file. - The setup of the menu and menu item - is done in the plugin's \c{initialize} function, which is the first thing called - after the plugin constructor. In that function, the plugin can be sure that the basic - setup of plugin's that it depends on has been done, for example the Core plugin's - \c{ActionManager} instance has been created. + All the necessary header files from the plugin code itself, from the \c + Core plugin, and from Qt are included in the beginning of the file. The + setup of the menu and menu item is done in the plugin's \c initialize + function, which is the first thing called after the plugin constructor. In + that function, the plugin can be sure that the basic setup of plugin's that + it depends on has been done, for example the Core plugin's \c ActionManager + instance has been created. For more information about implementing the plugin interface, see the \l{ExtensionSystem::IPlugin} API documentation and \l{Plugin Life Cycle}. \snippet exampleplugin/exampleplugin.cpp add action - This part of the code creates a new \c{QAction}, registers it as a new - \c{Command} in the action manager, and connects it to the plugin's slot. - The action manager provides a central place where the user can assign and - change keyboard shortcuts, and manages cases where for example a menu item should be - directed to different plugins under different circumstances, as well as a few - other things. This is described in more detail in \l{Menus and Menu Items}. + This part of the code creates a new \c QAction, registers it as a new + \c Command in the action manager, and connects it to the plugin's slot. The + action manager provides a central place where the user can assign and change + keyboard shortcuts, and manages cases where for example a menu item should + be directed to different plugins under different circumstances, as well as a + few other things. This is described in more detail in + \l{Menus and Menu Items}. \snippet exampleplugin/exampleplugin.cpp add menu - Here a new menu item is created, the created command added to it, and the menu - added to the \uicontrol{Tools} menu in the menu bar. Again, this is covered in more - detail in \l{Menus and Menu Items}. + Here a new menu item is created, the created command added to it, and the + menu added to the \uicontrol Tools menu in the menu bar. Again, this is + covered in more detail in \l{Menus and Menu Items}. \snippet exampleplugin/exampleplugin.cpp slot implementation From 637f7dc0beb4442b31164f7480bcc948ae752cb5 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 23 Jun 2015 15:50:23 +0200 Subject: [PATCH 044/113] Doc: Polish getting-and-building.qdoc Some more \c, some cleanups, mostly linebreaks. No text change. Change-Id: I16ea8985dba698461ff6cba33d6fa92daf9980ea Reviewed-by: Leena Miettinen --- doc/api/getting-and-building.qdoc | 34 ++++++++++++++++++------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/doc/api/getting-and-building.qdoc b/doc/api/getting-and-building.qdoc index fe459c1240e..0bbf0291b0b 100644 --- a/doc/api/getting-and-building.qdoc +++ b/doc/api/getting-and-building.qdoc @@ -26,33 +26,38 @@ \endcode There are several reasons why you might want to do your own build of \QC, - like using the most current development version and being able to tweak - \QC at one or the other place. It is also necessary if you want to - create your own \QC plugin. + like using the most current development version and being able to tweak \QC + at one or the other place. It is also necessary if you want to create your + own \QC plugin. \section1 Getting Qt - Prebuilt \QC packages usually use the latest stable release of Qt. - You can see the exact minimum requirement at the top of \QC's qtcreator.pro. + Prebuilt \QC packages usually use the latest stable release of Qt. You can + see the exact minimum requirement at the top of \QC's \c {qtcreator.pro}. (You can find the current version in our source repository here: \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/qtcreator.pro#n4}.) - You can get prebuilt Qt packages from \l{https://download.qt.io}{Qt Downloads}. - If you want to use Qt as provided by your Linux distribution, you need to make sure that all - Qt development packages and private header packages are also installed. + You can get prebuilt Qt packages from + \l{https://download.qt.io}{Qt Downloads}. If you want to use Qt as provided + by your Linux distribution, you need to make sure that all Qt development + packages and private header packages are also installed. \section1 Getting and Building \QC - You can get the \QC sources for a specific version either by using one of the - released source bundles, or from the Git repository - \l{https://code.qt.io/cgit/qt-creator/qt-creator.git}. If you intend to contribute to \QC - itself, you should use the repository from our Gerrit review tool as described - in: \l{https://wiki.qt.io/Setting_up_Gerrit}{Setting up Gerrit}. + You can get the \QC sources for a specific version either by using one of + the released source bundles, or from the Git repository + \l{https://code.qt.io/cgit/qt-creator/qt-creator.git}. If you intend to + contribute to \QC itself, you should use the repository from our Gerrit + review tool as described in: + \l{https://wiki.qt.io/Setting_up_Gerrit}{Setting up Gerrit}. We strongly encourage you to do out-of-source builds of \QC (also called shadow-builds). - After you put the \QC sources somewhere (lets call the path \c{}) + + After you put the \QC sources somewhere (lets call the path + \c {}) you build it on Linux and Mac with + \code cd /.. mkdir qtcreator-build @@ -60,5 +65,6 @@ /bin/qmake -r make \endcode + or the corresponding commands on Windows systems. */ From a382d5259d5e6084dcc991ecd318b77525ff5377 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 23 Jun 2015 15:46:26 +0200 Subject: [PATCH 045/113] WS only change Change-Id: If1c12117f79bee1e45c4b2ff64ebe14ad41f1288 Reviewed-by: Leena Miettinen --- doc/api/first-plugin.qdoc | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/doc/api/first-plugin.qdoc b/doc/api/first-plugin.qdoc index da223a6e13d..995f15a51b6 100644 --- a/doc/api/first-plugin.qdoc +++ b/doc/api/first-plugin.qdoc @@ -56,7 +56,7 @@ project name. You will choose that name later in the wizard. Continue to the next page. - The \uicontrol{Kit Selection} dialog opens. + The \uicontrol {Kit Selection} dialog opens. \image firstplugin-kitselection.png "Choose the kit to build and run your project with" @@ -68,7 +68,7 @@ build your plugin, you will get errors while \QC tries to load your plugin. Continue to the next page. - The \uicontrol{Plugin Information} dialog opens. + The \uicontrol {Plugin Information} dialog opens. \image firstplugin-pluginsetup.png "Specify Your Plugin Details" @@ -119,7 +119,7 @@ \QC, and want the plugin to be only loaded by that \QC instance. Continue to the next page. - The \uicontrol{Project Management} dialog opens. + The \uicontrol {Project Management} dialog opens. \image firstplugin-summary.png "Summary of Created Files" @@ -158,26 +158,30 @@ \li Role \row - \li \c{Example.json.in} - \li Plugin meta data template. QMake creates an \c{Example.json} + \li \c {Example.json.in} + + \li Plugin meta data template. QMake creates an \c {Example.json} from this file, which is compiled into the plugin as meta data. The meta data is read by \QC to find out about the plugin. \row - \li \c{example.pro} + \li \c {example.pro} + \li Project file, used by QMake to generate a Makefile that then is used to build the plugin. \row - \li \c{example_global.h} + \li \c {example_global.h} + \li Contains macro definitions that are useful when this plugin should export symbols to other plugins. \row - \li \c{exampleconstants.h} + \li \c {exampleconstants.h} + \li Header defining constants used by the plugin code. \row \li \c{exampleplugin.h/.cpp} \li C++ header and source files that define the plugin class that will be - instanciated and run by \QC's plugin manager. + instanciated and run by \QC's plugin manager. \endtable \section1 qmake Project @@ -279,7 +283,7 @@ \section1 Plugin Class - The files \c{exampleplugin.h} and \c{exampleplugin.cpp} define the plugin + The files \c {exampleplugin.h} and \c {exampleplugin.cpp} define the plugin implementation of your little plugin. We'll concentrate on some highlights here, and give pointers to more detailed information for the various parts. From d7c3572a4b1325f92ec4bdfed49bdc014f62f702 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 23 Jun 2015 16:53:45 +0200 Subject: [PATCH 046/113] WS only change Change-Id: Ic9f9b4ab36729c7a4a756892af1b98a51ad3be0a Reviewed-by: Leena Miettinen --- doc/api/qtcreator-dev.qdoc | 42 +++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/doc/api/qtcreator-dev.qdoc b/doc/api/qtcreator-dev.qdoc index 094cc3915ad..36de2d00681 100644 --- a/doc/api/qtcreator-dev.qdoc +++ b/doc/api/qtcreator-dev.qdoc @@ -76,10 +76,13 @@ While this gives you complete control over the wizard, it also requires you to write most of the UI and the logic yourself. \list - \li \l{Creating Plugins} - \li \l{Qt Creator Coding Rules} - \li \l{Creating Wizards in Code} - \li \l{User Interface Text Guidelines} + \li \l{Creating Plugins} + + \li \l{Qt Creator Coding Rules} + + \li \l{Creating Wizards in Code} + + \li \l{User Interface Text Guidelines} \endlist \section1 Supporting Additional File Types @@ -125,10 +128,13 @@ a basis to build on, taking away some of the pain of implementing a text editor from the ground up. \list - \li \l{Creating Plugins} - \li \l{Qt Creator Coding Rules} - \li \l{Text Editors} - \li \l{CodeAssist} {Providing Code Assist} + \li \l{Creating Plugins} + + \li \l{Qt Creator Coding Rules} + + \li \l{Text Editors} + + \li \l{CodeAssist} {Providing Code Assist} \endlist \section2 Other Custom Editors @@ -136,9 +142,11 @@ You can also add a completely custom editor to gain complete control over its appearance and behavior. \list - \li \l{Creating Plugins} - \li \l{Qt Creator Coding Rules} - \li \l{Editors} + \li \l{Creating Plugins} + + \li \l{Qt Creator Coding Rules} + + \li \l{Editors} \endlist \section1 Running External Tools @@ -228,12 +236,12 @@ \list \li \l{Developing Qt Creator Plugins} \list - \li \l{Creating Plugins} - \li \l{Menus and Menu Items} - \li \l{Creating Wizards in Code} - \li \l{Editors} - \li \l{Text Editors} - \li \l{Options Pages} + \li \l{Creating Plugins} + \li \l{Menus and Menu Items} + \li \l{Creating Wizards in Code} + \li \l{Editors} + \li \l{Text Editors} + \li \l{Options Pages} \endlist \li Reference \list From 1b0e5d787a3bc2d5916c85f9d9f7d01a5a6c75ee Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Thu, 25 Jun 2015 10:43:57 +0300 Subject: [PATCH 047/113] VCS: Abort previous command for the same editor Broken by e0c5ff03ec3c23691d88318f75b9c993ca594054. Task-number: QTCREATORBUG-14630 Change-Id: I123d86b45c6fbc05c7f4cfb52c0be705f75abb75 Reviewed-by: Eike Ziller Reviewed-by: Tobias Hunger --- src/plugins/vcsbase/vcsbaseclient.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp index 750e7f96c32..3a0256e5f3f 100644 --- a/src/plugins/vcsbase/vcsbaseclient.cpp +++ b/src/plugins/vcsbase/vcsbaseclient.cpp @@ -137,6 +137,7 @@ VcsCommand *VcsBaseClientImpl::createCommand(const QString &workingDirectory, auto cmd = new VcsCommand(workingDirectory, processEnvironment()); cmd->setDefaultTimeoutS(vcsTimeoutS()); if (editor) { + editor->setCommand(cmd); connect(editor, &QObject::destroyed, cmd, &VcsCommand::abort); connect(cmd, &VcsCommand::finished, editor, [editor, cmd]() { commandFinished(editor, cmd); }); From aff02184d45c10da6c3de3c6523fac7646e922b2 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Fri, 12 Jun 2015 15:36:04 +0200 Subject: [PATCH 048/113] Android M: Support new logcat output Change-Id: I64ae6493b45b3f1cac82e7f5e1ae77ec3b910bc9 Task-number: QTCREATORBUG-14534 Reviewed-by: BogDan Vatra Reviewed-by: Daniel Teske --- src/plugins/android/androidanalyzesupport.cpp | 6 +- src/plugins/android/androiddebugsupport.cpp | 8 +-- src/plugins/android/androidruncontrol.cpp | 16 +++--- src/plugins/android/androidruncontrol.h | 4 +- src/plugins/android/androidrunner.cpp | 55 ++++++++++++++----- src/plugins/android/androidrunner.h | 5 +- 6 files changed, 61 insertions(+), 33 deletions(-) diff --git a/src/plugins/android/androidanalyzesupport.cpp b/src/plugins/android/androidanalyzesupport.cpp index 9b80e3ce3c8..6978424218b 100644 --- a/src/plugins/android/androidanalyzesupport.cpp +++ b/src/plugins/android/androidanalyzesupport.cpp @@ -105,15 +105,13 @@ AndroidAnalyzeSupport::AndroidAnalyzeSupport(AndroidRunConfiguration *runConfig, }); connect(runner, &AndroidRunner::remoteErrorOutput, - [this, runControl](const QByteArray &output) { - const QString msg = QString::fromUtf8(output); + [this, runControl](const QString &msg) { runControl->logApplicationMessage(msg, Utils::StdErrFormatSameLine); m_outputParser.processOutput(msg); }); connect(runner, &AndroidRunner::remoteOutput, - [this, runControl](const QByteArray &output) { - const QString msg = QString::fromUtf8(output); + [this, runControl](const QString &msg) { runControl->logApplicationMessage(msg, Utils::StdOutFormatSameLine); m_outputParser.processOutput(msg); }); diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp index 3d29386dde2..0dfe144ea81 100644 --- a/src/plugins/android/androiddebugsupport.cpp +++ b/src/plugins/android/androiddebugsupport.cpp @@ -171,15 +171,15 @@ AndroidDebugSupport::AndroidDebugSupport(AndroidRunConfiguration *runConfig, }); connect(m_runner, &AndroidRunner::remoteErrorOutput, - [this](const QByteArray &output) { + [this](const QString &output) { QTC_ASSERT(m_runControl, return); - m_runControl->showMessage(QString::fromUtf8(output), AppError); + m_runControl->showMessage(output, AppError); }); connect(m_runner, &AndroidRunner::remoteOutput, - [this](const QByteArray &output) { + [this](const QString &output) { QTC_ASSERT(m_runControl, return); - m_runControl->showMessage(QString::fromUtf8(output), AppOutput); + m_runControl->showMessage(output, AppOutput); }); } diff --git a/src/plugins/android/androidruncontrol.cpp b/src/plugins/android/androidruncontrol.cpp index 15c15b4675c..8a0bf3155a4 100644 --- a/src/plugins/android/androidruncontrol.cpp +++ b/src/plugins/android/androidruncontrol.cpp @@ -60,10 +60,10 @@ void AndroidRunControl::start() emit started(); disconnect(m_runner, 0, this, 0); - connect(m_runner, SIGNAL(remoteErrorOutput(QByteArray)), - SLOT(handleRemoteErrorOutput(QByteArray))); - connect(m_runner, SIGNAL(remoteOutput(QByteArray)), - SLOT(handleRemoteOutput(QByteArray))); + connect(m_runner, SIGNAL(remoteErrorOutput(QString)), + SLOT(handleRemoteErrorOutput(QString))); + connect(m_runner, SIGNAL(remoteOutput(QString)), + SLOT(handleRemoteOutput(QString))); connect(m_runner, SIGNAL(remoteProcessFinished(QString)), SLOT(handleRemoteProcessFinished(QString))); appendMessage(tr("Starting remote process."), Utils::NormalMessageFormat); @@ -84,14 +84,14 @@ void AndroidRunControl::handleRemoteProcessFinished(const QString &error) emit finished(); } -void AndroidRunControl::handleRemoteOutput(const QByteArray &output) +void AndroidRunControl::handleRemoteOutput(const QString &output) { - appendMessage(QString::fromUtf8(output), Utils::StdOutFormatSameLine); + appendMessage(output, Utils::StdOutFormatSameLine); } -void AndroidRunControl::handleRemoteErrorOutput(const QByteArray &output) +void AndroidRunControl::handleRemoteErrorOutput(const QString &output) { - appendMessage(QString::fromUtf8(output), Utils::StdErrFormatSameLine); + appendMessage(output, Utils::StdErrFormatSameLine); } bool AndroidRunControl::isRunning() const diff --git a/src/plugins/android/androidruncontrol.h b/src/plugins/android/androidruncontrol.h index 085bb2d1306..cc0b815f01b 100644 --- a/src/plugins/android/androidruncontrol.h +++ b/src/plugins/android/androidruncontrol.h @@ -54,8 +54,8 @@ public: private slots: void handleRemoteProcessFinished(const QString &error); - void handleRemoteOutput(const QByteArray &output); - void handleRemoteErrorOutput(const QByteArray &output); + void handleRemoteOutput(const QString &output); + void handleRemoteErrorOutput(const QString &output); private: diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp index d833578a795..6409db30f87 100644 --- a/src/plugins/android/androidrunner.cpp +++ b/src/plugins/android/androidrunner.cpp @@ -209,6 +209,21 @@ AndroidRunner::AndroidRunner(QObject *parent, } } } + + m_logCatRegExp = QRegExp(QLatin1String("[0-9\\-]*" // date + "\\s+" + "[0-9\\-:.]*"// time + "\\s*" + "(\\d*)" // pid 1. capture + "\\s+" + "\\d*" // unknown + "\\s+" + "(\\w)" // message type 2. capture + "\\s+" + "(.*): " // source 3. capture + "(.*)" // message 4. capture + "[\\n\\r]*" + )); } AndroidRunner::~AndroidRunner() @@ -526,21 +541,35 @@ void AndroidRunner::logcatProcess(const QByteArray &text, QByteArray &buffer, bo buffer.clear(); } - QByteArray pid(QString::fromLatin1("%1):").arg(m_processPID).toLatin1()); - foreach (QByteArray line, lines) { - if (!line.contains(pid)) + QString pidString = QString::number(m_processPID); + foreach (const QByteArray &msg, lines) { + const QString line = QString::fromUtf8(msg).trimmed(); + if (!line.contains(pidString)) continue; - if (line.endsWith('\r')) - line.chop(1); - line.append('\n'); - if (onlyError || line.startsWith("F/") - || line.startsWith("E/") - || line.startsWith("D/Qt") - || line.startsWith("W/")) - emit remoteErrorOutput(line); - else - emit remoteOutput(line); + if (m_logCatRegExp.exactMatch(line)) { + // Android M + if (m_logCatRegExp.cap(1) == pidString) { + const QString &messagetype = m_logCatRegExp.cap(2); + QString output = line.mid(m_logCatRegExp.pos(2)); + if (onlyError + || messagetype == QLatin1String("F") + || messagetype == QLatin1String("E") + || messagetype == QLatin1String("W") + || messagetype == QLatin1String("D")) + emit remoteErrorOutput(output); + else + emit remoteOutput(output); + } + } else { + if (onlyError || line.startsWith(_("F/")) + || line.startsWith(_("E/")) + || line.startsWith(_("D/Qt")) + || line.startsWith(_("W/"))) + emit remoteErrorOutput(line); + else + emit remoteOutput(line); + } } } diff --git a/src/plugins/android/androidrunner.h b/src/plugins/android/androidrunner.h index 1750bba43b4..8f6c40d5739 100644 --- a/src/plugins/android/androidrunner.h +++ b/src/plugins/android/androidrunner.h @@ -73,8 +73,8 @@ signals: void remoteProcessStarted(int gdbServerPort, int qmlPort); void remoteProcessFinished(const QString &errString = QString()); - void remoteOutput(const QByteArray &output); - void remoteErrorOutput(const QByteArray &output); + void remoteOutput(const QString &output); + void remoteErrorOutput(const QString &output); private slots: void checkPID(); @@ -120,6 +120,7 @@ private: bool m_isBusyBox; QStringList m_selector; QMutex m_mutex; + QRegExp m_logCatRegExp; DebugHandShakeType m_handShakeMethod; QTcpSocket *m_socket; bool m_customPort; From f886c70199fec29c53198cf3107d733c28c8ff14 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 25 Jun 2015 09:10:25 +0200 Subject: [PATCH 049/113] Debugger: Be more robust in case of unexpected non-ASCII output Also correct typo in function name. Task-number: QTCREATORBUG-14629 Change-Id: I193efc3a002f83b0091f93e087f2feb19dc4f5c1 Reviewed-by: Christian Stenger --- share/qtcreator/debugger/gdbbridge.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index 4622b22ff7b..7c6de9c3a17 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -26,7 +26,7 @@ from dumper import * # ####################################################################### -def savePrint(output): +def safePrint(output): try: print(output) except: @@ -47,7 +47,7 @@ def registerCommand(name, func): def __init__(self): super(Command, self).__init__(name, gdb.COMMAND_OBSCURE) def invoke(self, args, from_tty): - savePrint(func(args)) + safePrint(func(args)) Command() @@ -130,7 +130,7 @@ class ScanStackCommand(gdb.Command): def invoke(self, args, from_tty): if len(args) == 0: args = 20 - savePrint(scanStack(gdb.parse_and_eval("$sp"), int(args))) + safePrint(scanStack(gdb.parse_and_eval("$sp"), int(args))) ScanStackCommand() @@ -438,7 +438,7 @@ class Dumper(DumperBase): self.output.append(',partial="%d"' % isPartial) - print(''.join(self.output)) + safePrint(''.join(self.output)) def enterSubItem(self, item): if not item.iname: @@ -1619,7 +1619,7 @@ class Dumper(DumperBase): frame = frame.older() i += 1 - print(''.join(self.output)) + safePrint(''.join(self.output)) def createResolvePendingBreakpointsHookBreakpoint(self, args): class Resolver(gdb.Breakpoint): From 60a8442d8c9b8062fd79e5f9ccf5f07cfe9e33c4 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 24 Jun 2015 08:26:35 +0200 Subject: [PATCH 050/113] Debugger: Rework start parameter completion. It's again a linear process now, with explicit entrance point for all users. Task-number: QTCREATORBUG-14618 Change-Id: I96c08947270ce34d7bc6c8be1d7f350dbfa14794 Reviewed-by: Kai Koehne Reviewed-by: Orgad Shaneh Reviewed-by: Christian Stenger --- src/plugins/debugger/cdb/cdbengine.cpp | 6 +- src/plugins/debugger/debuggerdialogs.cpp | 12 +- src/plugins/debugger/debuggerdialogs.h | 2 +- src/plugins/debugger/debuggerengine.cpp | 16 - src/plugins/debugger/debuggerengine.h | 15 +- src/plugins/debugger/debuggerplugin.cpp | 47 +- src/plugins/debugger/debuggerruncontrol.cpp | 641 ++++++++++-------- src/plugins/debugger/debuggerruncontrol.h | 9 +- src/plugins/debugger/gdb/gdbengine.cpp | 2 +- .../debugger/gdb/startgdbserverdialog.cpp | 4 +- src/plugins/debugger/qml/qmlcppengine.cpp | 14 +- src/plugins/debugger/qml/qmlcppengine.h | 2 +- 12 files changed, 395 insertions(+), 375 deletions(-) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 558ff461cc8..bcaa80a0841 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -267,14 +267,14 @@ static inline bool validMode(DebuggerStartMode sm) } // Accessed by RunControlFactory -DebuggerEngine *createCdbEngine(const DebuggerRunParameters &rp, QString *errorMessage) +DebuggerEngine *createCdbEngine(const DebuggerRunParameters &rp, QStringList *errors) { if (HostOsInfo::isWindowsHost()) { if (validMode(rp.startMode)) return new CdbEngine(rp); - *errorMessage = QLatin1String("Internal error: Invalid start parameters passed for thee CDB engine."); + errors->append(QLatin1String("Internal error: Invalid start parameters passed for thee CDB engine.")); } else { - *errorMessage = QString::fromLatin1("Unsupported debug mode"); + errors->append(QString::fromLatin1("Unsupported debug mode")); } return 0; } diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp index 34b59bbb4f6..9e6417e0ed5 100644 --- a/src/plugins/debugger/debuggerdialogs.cpp +++ b/src/plugins/debugger/debuggerdialogs.cpp @@ -358,7 +358,7 @@ void StartApplicationDialog::updateState() d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(okEnabled); } -bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp) +bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp, Kit **kit) { const bool attachRemote = rp->startMode == AttachToRemoteServer; const QString settingsGroup = QLatin1String("DebugMode"); @@ -409,11 +409,6 @@ bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp) settings->endGroup(); } - Kit *kit = dialog.d->kitChooser->currentKit(); - QTC_ASSERT(kit, return false); - bool res = fillParametersFromKit(rp, kit); - QTC_ASSERT(res, return false); - rp->executable = newParameters.localExecutable; const QString inputAddress = dialog.d->serverAddressEdit->text(); if (!inputAddress.isEmpty()) @@ -430,10 +425,13 @@ bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp) rp->serverStartScript = newParameters.serverStartScript; rp->debugInfoLocation = newParameters.debugInfoLocation; - IDevice::ConstPtr dev = DeviceKitInformation::device(kit); + Kit *k = dialog.d->kitChooser->currentKit(); + IDevice::ConstPtr dev = DeviceKitInformation::device(k); bool isLocal = !dev || (dev->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); if (!attachRemote) rp->startMode = isLocal ? StartExternal : StartRemoteProcess; + if (kit) + *kit = k; return true; } diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h index 5503944df78..ac262c962af 100644 --- a/src/plugins/debugger/debuggerdialogs.h +++ b/src/plugins/debugger/debuggerdialogs.h @@ -85,7 +85,7 @@ public: explicit StartApplicationDialog(QWidget *parent); ~StartApplicationDialog(); - static bool run(QWidget *parent, DebuggerRunParameters *rp); + static bool run(QWidget *parent, DebuggerRunParameters *rp, ProjectExplorer::Kit **kit); private slots: void historyIndexChanged(int); diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 9f68494136e..2ecefdc7078 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -92,22 +92,6 @@ enum { debug = 0 }; #include #endif -/////////////////////////////////////////////////////////////////////// -// -// DebuggerRunParameters -// -/////////////////////////////////////////////////////////////////////// - -DebuggerRunParameters::DebuggerRunParameters() - : isSnapshot(false), - testCase(0) -{} - -void DebuggerRunParameters::initialize(const DebuggerStartParameters &sp) -{ - DebuggerStartParameters::operator=(sp); -} - // VariableManager Prefix const char PrefixDebugExecutable[] = "DebuggedExecutable"; diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 84808627bcf..251126214fa 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -83,9 +83,7 @@ class ThreadId; class DebuggerRunParameters : public DebuggerStartParameters { public: - DebuggerRunParameters(); - - void initialize(const DebuggerStartParameters &sp); + DebuggerRunParameters() {} QString coreFile; QString overrideStartScript; // Used in attach to core and remote debugging @@ -98,13 +96,13 @@ public: QString serverStartScript; QString localMountDir; ProjectExplorer::IDevice::ConstPtr device; - bool isSnapshot; // Set if created internally. + bool isSnapshot = false; // Set if created internally. // Used by AttachCrashedExternal. QString crashParameter; // For Debugger testing. - int testCase; + int testCase = 0; }; class UpdateParameters @@ -427,12 +425,9 @@ private: DebuggerEnginePrivate *d; }; -DebuggerEngine *createEngine(DebuggerEngineType et, const DebuggerRunParameters &rp, QString *errorMessage); - -bool fillParametersFromKit(DebuggerStartParameters *sp, const ProjectExplorer::Kit *kit, QString *errorMessage = 0); - -DebuggerRunControl *createAndScheduleRun(const DebuggerRunParameters &rp); +DebuggerEngine *createEngine(DebuggerEngineType et, const DebuggerRunParameters &rp, QStringList *errors); +DebuggerRunControl *createAndScheduleRun(const DebuggerRunParameters &rp, const ProjectExplorer::Kit *kit); } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 74f194b475c..d531fe44467 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -957,7 +957,7 @@ public: DebuggerMainWindow *m_mainWindow; Id m_previousMode; - QList m_scheduledStarts; + QVector> m_scheduledStarts; ProxyAction *m_visibleStartAction; ProxyAction *m_hiddenStopAction; @@ -1183,13 +1183,11 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it, } } } - if (!fillParametersFromKit(&rp, kit, errorMessage)) - return false; if (rp.startMode == StartExternal) { rp.displayName = tr("Executable file \"%1\"").arg(rp.executable); rp.startMessage = tr("Debugging file %1.").arg(rp.executable); } - m_scheduledStarts.append(rp); + m_scheduledStarts.append(QPair(rp, kit)); return true; } // -wincrashevent :. A handle used for @@ -1204,8 +1202,6 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it, return false; } DebuggerRunParameters rp; - if (!fillParametersFromKit(&rp, findUniversalCdbKit(), errorMessage)) - return false; rp.startMode = AttachCrashedExternal; rp.crashParameter = it->section(QLatin1Char(':'), 0, 0); rp.attachPID = it->section(QLatin1Char(':'), 1, 1).toULongLong(); @@ -1216,7 +1212,7 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it, "does not match the pattern :.").arg(*it, option); return false; } - m_scheduledStarts.append(rp); + m_scheduledStarts.append(QPair(rp, findUniversalCdbKit())); return true; } @@ -1320,8 +1316,9 @@ void DebuggerPluginPrivate::onCurrentProjectChanged(Project *project) void DebuggerPluginPrivate::startAndDebugApplication() { DebuggerRunParameters rp; - if (StartApplicationDialog::run(ICore::dialogParent(), &rp)) - createAndScheduleRun(rp); + Kit *kit; + if (StartApplicationDialog::run(ICore::dialogParent(), &rp, &kit)) + createAndScheduleRun(rp, kit); } void DebuggerPluginPrivate::attachCore() @@ -1349,8 +1346,6 @@ void DebuggerPluginPrivate::attachCore() QString display = dlg.useLocalCoreFile() ? dlg.localCoreFile() : dlg.remoteCoreFile(); DebuggerRunParameters rp; - bool res = fillParametersFromKit(&rp, dlg.kit()); - QTC_ASSERT(res, return); rp.masterEngineType = DebuggerKitInformation::engineType(dlg.kit()); rp.executable = dlg.localExecutableFile(); rp.coreFile = dlg.localCoreFile(); @@ -1358,7 +1353,7 @@ void DebuggerPluginPrivate::attachCore() rp.startMode = AttachCore; rp.closeMode = DetachAtClose; rp.overrideStartScript = dlg.overrideStartScript(); - createAndScheduleRun(rp); + createAndScheduleRun(rp, dlg.kit()); } void DebuggerPluginPrivate::startRemoteCdbSession() @@ -1367,8 +1362,6 @@ void DebuggerPluginPrivate::startRemoteCdbSession() DebuggerRunParameters rp; Kit *kit = findUniversalCdbKit(); QTC_ASSERT(kit, return); - bool res = fillParametersFromKit(&rp, kit); - QTC_ASSERT(res, return); rp.startMode = AttachToRemoteServer; rp.closeMode = KillAtClose; StartRemoteCdbDialog dlg(ICore::dialogParent()); @@ -1380,17 +1373,18 @@ void DebuggerPluginPrivate::startRemoteCdbSession() return; rp.remoteChannel = dlg.connection(); setConfigValue(connectionKey, rp.remoteChannel); - createAndScheduleRun(rp); + createAndScheduleRun(rp, kit); } void DebuggerPluginPrivate::attachToRemoteServer() { DebuggerRunParameters rp; + Kit *kit; rp.startMode = AttachToRemoteServer; - if (StartApplicationDialog::run(ICore::dialogParent(), &rp)) { + if (StartApplicationDialog::run(ICore::dialogParent(), &rp, &kit)) { rp.closeMode = KillAtClose; rp.serverStartScript.clear(); - createAndScheduleRun(rp); + createAndScheduleRun(rp, kit); } } @@ -1488,15 +1482,13 @@ DebuggerRunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit, } DebuggerRunParameters rp; - bool res = fillParametersFromKit(&rp, kit); - QTC_ASSERT(res, return 0); rp.attachPID = process.pid; rp.displayName = tr("Process %1").arg(process.pid); rp.executable = process.exe; rp.startMode = AttachExternal; rp.closeMode = DetachAtClose; rp.continueAfterAttach = contAfterAttach; - return createAndScheduleRun(rp); + return createAndScheduleRun(rp, kit); } void DebuggerPlugin::attachExternalApplication(RunControl *rc) @@ -1511,9 +1503,7 @@ void DebuggerPlugin::attachExternalApplication(RunControl *rc) if (const RunConfiguration *runConfiguration = rc->runConfiguration()) if (const Target *target = runConfiguration->target()) kit = target->kit(); - bool res = fillParametersFromKit(&rp, kit); - QTC_ASSERT(res, return); - createAndScheduleRun(rp); + createAndScheduleRun(rp, kit); } void DebuggerPluginPrivate::attachToQmlPort() @@ -1536,8 +1526,6 @@ void DebuggerPluginPrivate::attachToQmlPort() Kit *kit = dlg.kit(); QTC_ASSERT(kit, return); - bool res = fillParametersFromKit(&rp, kit); - QTC_ASSERT(res, return); setConfigValue("LastQmlServerPort", dlg.port()); setConfigValue("LastProfile", kit->id().toSetting()); @@ -1568,8 +1556,7 @@ void DebuggerPluginPrivate::attachToQmlPort() rp.projectSourceDirectory = !projects.isEmpty() ? projects.first()->projectDirectory().toString() : QString(); rp.projectSourceFiles = sourceFiles; - rp.sysRoot = SysRootKitInformation::sysRoot(kit).toString(); - createAndScheduleRun(rp); + createAndScheduleRun(rp, kit); } void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &value) @@ -1582,8 +1569,8 @@ void DebuggerPluginPrivate::enableReverseDebuggingTriggered(const QVariant &valu void DebuggerPluginPrivate::runScheduled() { - foreach (const DebuggerRunParameters &rp, m_scheduledStarts) - createAndScheduleRun(rp); + for (int i = 0, n = m_scheduledStarts.size(); i != n; ++i) + createAndScheduleRun(m_scheduledStarts.at(i).first, m_scheduledStarts.at(i).second); } void DebuggerPluginPrivate::editorOpened(IEditor *editor) @@ -3375,7 +3362,7 @@ void DebuggerPluginPrivate::testUnloadProject() void DebuggerPluginPrivate::testRunProject(const DebuggerRunParameters &rp, const TestCallBack &cb) { m_testCallbacks.append(cb); - RunControl *rc = createAndScheduleRun(rp); + RunControl *rc = createAndScheduleRun(rp, 0); connect(rc, &RunControl::finished, this, &DebuggerPluginPrivate::testRunControlFinished); } diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index c06ab172b7d..3181c6570df 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -69,15 +69,16 @@ enum { debug = 0 }; namespace Debugger { namespace Internal { -DebuggerEngine *createCdbEngine(const DebuggerRunParameters &rp, QString *error); +DebuggerEngine *createCdbEngine(const DebuggerRunParameters &rp, QStringList *error); DebuggerEngine *createGdbEngine(const DebuggerRunParameters &rp); DebuggerEngine *createPdbEngine(const DebuggerRunParameters &rp); DebuggerEngine *createQmlEngine(const DebuggerRunParameters &rp); -DebuggerEngine *createQmlCppEngine(const DebuggerRunParameters &rp, QString *error); +DebuggerEngine *createQmlCppEngine(const DebuggerRunParameters &rp, QStringList *error); DebuggerEngine *createLldbEngine(const DebuggerRunParameters &rp); } // namespace Internal + static const char *engineTypeName(DebuggerEngineType et) { switch (et) { @@ -136,6 +137,9 @@ QString DebuggerRunControl::displayName() const void DebuggerRunControl::start() { + TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_DEBUGINFO); + TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_RUNTIME); + QTC_ASSERT(m_engine, return); // User canceled input dialog asking for executable when working on library project. if (m_engine->runParameters().startMode == StartInternal @@ -273,14 +277,294 @@ void DebuggerRunControl::abortDebugger() m_engine->abortDebugger(); } +/////////////////////////////////////////////////////////////////////// +// +// DebuggerRunControlCreator +// +/////////////////////////////////////////////////////////////////////// + + +namespace Internal { + +class DebuggerRunControlCreator +{ +public: + DebuggerRunControlCreator() {} + + // Life cycle: Initialize from StartParameters, enrich by automatically + // detectable pieces, construct an Engine and a RunControl. + void initialize(const DebuggerStartParameters &sp); + void enrich(const RunConfiguration *runConfig, const Kit *kit); + void createRunControl(RunMode runMode = DebugRunMode); + QString fullError() const { return m_errors.join(QLatin1Char('\n')); } + + // Result. + DebuggerRunParameters m_rp; + + // Scratch data. + const Kit *m_kit = 0; + const RunConfiguration *m_runConfig = 0; + DebuggerRunConfigurationAspect *m_debuggerAspect = 0; + Target *m_target = 0; + Project *m_project = 0; + + QStringList m_errors; + DebuggerRunControl *m_runControl = 0; +}; + +void DebuggerRunControlCreator::initialize(const DebuggerStartParameters &sp) +{ + m_rp.DebuggerStartParameters::operator=(sp); +} + +void DebuggerRunControlCreator::enrich(const RunConfiguration *runConfig, const Kit *kit) +{ + QTC_ASSERT(!m_kit, return); + QTC_ASSERT(!m_runConfig, return); + + // Find RunConfiguration. + if (!m_runConfig) + m_runConfig = runConfig; + + if (!m_runConfig) + m_runConfig = m_rp.runConfiguration; + + // Extract as much as possible from available RunConfiguration. + if (auto localRc = qobject_cast(m_runConfig)) { + m_rp.executable = localRc->executable(); + m_rp.processArgs = localRc->commandLineArguments(); + m_rp.useTerminal = localRc->runMode() == ApplicationLauncher::Console; + // Normalize to work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch'...) + m_rp.workingDirectory = FileUtils::normalizePathName(localRc->workingDirectory()); + } + + // Find a Kit and Target. Either could be missing. + if (m_runConfig) + m_target = m_runConfig->target(); + + if (!m_kit) + m_kit = kit; + + if (!m_kit) { + if (m_target) + m_kit = m_target->kit(); + } + + // We might have get an executable from a local PID. + if (m_rp.executable.isEmpty()) { + foreach (const DeviceProcessItem &p, DeviceProcessList::localProcesses()) + if (p.pid == m_rp.attachPID) + m_rp.executable = p.exe; + } + + if (!m_kit) { + // This code can only be reached when starting via the command line + // (-debug pid or executable) or attaching from runconfiguration + // without specifying a kit. Try to find a kit via ABI. + QList abis; + if (m_rp.toolChainAbi.isValid()) { + abis.push_back(m_rp.toolChainAbi); + } else if (!m_rp.executable.isEmpty()) { + abis = Abi::abisOfBinary(FileName::fromString(m_rp.executable)); + } + + if (!abis.isEmpty()) { + // Try exact abis. + m_kit = KitManager::find(std::function([abis](const Kit *k) -> bool { + if (const ToolChain *tc = ToolChainKitInformation::toolChain(k)) + return abis.contains(tc->targetAbi()) && DebuggerKitInformation::isValidDebugger(k); + return false; + })); + if (!m_kit) { + // Or something compatible. + m_kit = KitManager::find(std::function([abis](const Kit *k) -> bool { + if (const ToolChain *tc = ToolChainKitInformation::toolChain(k)) + foreach (const Abi &a, abis) + if (a.isCompatibleWith(tc->targetAbi()) && DebuggerKitInformation::isValidDebugger(k)) + return true; + return false; + })); + } + } + } + + if (!m_kit) + m_kit = KitManager::defaultKit(); + + // We really should have a kit now. + if (!m_kit) { + m_errors.append(DebuggerKitInformation::tr("No kit found.")); + return; + } + + if (m_runConfig) { + auto envAspect = m_runConfig->extraAspect(); + if (envAspect) + m_rp.environment = envAspect->environment(); + } + + if (m_runConfig) + m_debuggerAspect = m_runConfig->extraAspect(); + + if (m_target) + m_project = m_target->project(); + + // validate debugger if C++ debugging is enabled + if (m_rp.languages & CppLanguage) { + const QList tasks = DebuggerKitInformation::validateDebugger(m_kit); + if (!tasks.isEmpty()) { + foreach (const Task &t, tasks) + m_errors.append(t.description); + return; + } + } + + m_rp.cppEngineType = DebuggerKitInformation::engineType(m_kit); + m_rp.sysRoot = SysRootKitInformation::sysRoot(m_kit).toString(); + m_rp.debuggerCommand = DebuggerKitInformation::debuggerCommand(m_kit).toString(); + + if (auto toolChain = ToolChainKitInformation::toolChain(m_kit)) { + m_rp.toolChainAbi = toolChain->targetAbi(); + } + + if (m_target) { + if (const BuildConfiguration *buildConfig = m_target->activeBuildConfiguration()) + m_rp.projectBuildDirectory = buildConfig->buildDirectory().toString(); + } + + if (m_project) { + m_rp.projectSourceDirectory = m_project->projectDirectory().toString(); + m_rp.projectSourceFiles = m_project->files(Project::ExcludeGeneratedFiles); + } + + m_rp.device = DeviceKitInformation::device(m_kit); + + if (m_debuggerAspect) { + m_rp.multiProcess = m_debuggerAspect->useMultiProcess(); + + if (m_debuggerAspect->useCppDebugger()) + m_rp.languages |= CppLanguage; + + if (m_debuggerAspect->useQmlDebugger()) { + if (m_rp.device && m_rp.device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) { + QTcpServer server; + const bool canListen = server.listen(QHostAddress::LocalHost) + || server.listen(QHostAddress::LocalHostIPv6); + if (!canListen) { + m_errors.append(DebuggerPlugin::tr("Not enough free ports for QML debugging.") + QLatin1Char(' ')); + return; + } + m_rp.qmlServerAddress = server.serverAddress().toString(); + m_rp.qmlServerPort = server.serverPort(); + m_rp.languages |= QmlLanguage; + + // Makes sure that all bindings go through the JavaScript engine, so that + // breakpoints are actually hit! + const QString optimizerKey = _("QML_DISABLE_OPTIMIZER"); + if (!m_rp.environment.hasKey(optimizerKey)) + m_rp.environment.set(optimizerKey, _("1")); + + QtcProcess::addArg(&m_rp.processArgs, QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(m_rp.qmlServerPort)); + } + } + } + + if (m_rp.displayName.isEmpty() && m_runConfig) + m_rp.displayName = m_runConfig->displayName(); + + if (m_rp.masterEngineType == NoEngineType) { + if (m_rp.executable.endsWith(_(".py")) + || m_rp.executable == _("/usr/bin/python") + || m_rp.executable == _("/usr/bin/python3")) { + m_rp.masterEngineType = PdbEngineType; + } + } + + if (!boolSetting(AutoEnrichParameters)) { + const QString sysroot = m_rp.sysRoot; + if (m_rp.debugInfoLocation.isEmpty()) + m_rp.debugInfoLocation = sysroot + QLatin1String("/usr/lib/debug"); + if (m_rp.debugSourceLocation.isEmpty()) { + QString base = sysroot + QLatin1String("/usr/src/debug/"); + m_rp.debugSourceLocation.append(base + QLatin1String("qt5base/src/corelib")); + m_rp.debugSourceLocation.append(base + QLatin1String("qt5base/src/gui")); + m_rp.debugSourceLocation.append(base + QLatin1String("qt5base/src/network")); + } + } + + if (m_rp.masterEngineType == NoEngineType && m_debuggerAspect) { + const bool useCppDebugger = m_debuggerAspect->useCppDebugger() && (m_rp.languages & CppLanguage); + const bool useQmlDebugger = m_debuggerAspect->useQmlDebugger() && (m_rp.languages & QmlLanguage); + if (useQmlDebugger) { + if (useCppDebugger) + m_rp.masterEngineType = QmlCppEngineType; + else + m_rp.masterEngineType = QmlEngineType; + } + } + + if (m_rp.masterEngineType == NoEngineType) + m_rp.masterEngineType = m_rp.cppEngineType; + + if (m_rp.device && m_rp.connParams.port == 0) + m_rp.connParams = m_rp.device->sshParameters(); + + // Could have been set from command line. + if (m_rp.remoteChannel.isEmpty()) + m_rp.remoteChannel = m_rp.connParams.host + QLatin1Char(':') + QString::number(m_rp.connParams.port); + + if (m_rp.startMode == NoStartMode) + m_rp.startMode = StartInternal; +} + +// Re-used for Combined C++/QML engine. +DebuggerEngine *createEngine(DebuggerEngineType et, const DebuggerRunParameters &rp, QStringList *errors) +{ + switch (et) { + case GdbEngineType: + return createGdbEngine(rp); + case CdbEngineType: + return createCdbEngine(rp, errors); + case PdbEngineType: + return createPdbEngine(rp); + case QmlEngineType: + return createQmlEngine(rp); + case LldbEngineType: + return createLldbEngine(rp); + case QmlCppEngineType: + return createQmlCppEngine(rp, errors); + default: + if (errors) + errors->append(DebuggerPlugin::tr("Unknown debugger type \"%1\"").arg(_(engineTypeName(et)))); + } + return 0; +} + +void DebuggerRunControlCreator::createRunControl(RunMode runMode) +{ + if (runMode == DebugRunModeWithBreakOnMain) + m_rp.breakOnMain = true; + + DebuggerEngine *engine = createEngine(m_rp.masterEngineType, m_rp, &m_errors); + if (!engine) { + m_errors.append(DebuggerPlugin::tr("Unable to create a debugger engine of the type \"%1\""). + arg(_(engineTypeName(m_rp.masterEngineType)))); + m_rp.startMode = NoStartMode; + return; + } + + m_runControl = new DebuggerRunControl(const_cast(m_runConfig), engine); + + if (!m_runControl) + m_rp.startMode = NoStartMode; +} + //////////////////////////////////////////////////////////////////////// // // DebuggerRunControlFactory // //////////////////////////////////////////////////////////////////////// -namespace Internal { - class DebuggerRunControlFactory : public IRunControlFactory { public: @@ -289,7 +573,20 @@ public: {} RunControl *create(RunConfiguration *runConfig, - RunMode mode, QString *errorMessage) override; + RunMode mode, QString *errorMessage) override + { + QTC_ASSERT(runConfig, return 0); + QTC_ASSERT(mode == DebugRunMode || mode == DebugRunModeWithBreakOnMain, return 0); + + // We cover only local setup here. Remote setups are handled by the + // RunControl factories in the target specific plugins. + DebuggerRunControlCreator creator; + creator.enrich(runConfig, 0); + creator.createRunControl(mode); + if (errorMessage) + *errorMessage = creator.fullError(); + return creator.m_runControl; + } bool canRun(RunConfiguration *runConfig, RunMode mode) const override { @@ -303,307 +600,69 @@ public: } }; -} // namespace Internal - -bool fillParametersFromRunConfiguration - (DebuggerStartParameters *sp, const RunConfiguration *runConfig, QString *errorMessage) -{ - QTC_ASSERT(runConfig, return false); - EnvironmentAspect *environmentAspect = runConfig->extraAspect(); - QTC_ASSERT(environmentAspect, return false); - - Target *target = runConfig->target(); - Kit *kit = target ? target->kit() : KitManager::defaultKit(); - if (!fillParametersFromKit(sp, kit, errorMessage)) - return false; - sp->environment = environmentAspect->environment(); - - if (target) { - if (const Project *project = target->project()) { - sp->projectSourceDirectory = project->projectDirectory().toString(); - if (const BuildConfiguration *buildConfig = target->activeBuildConfiguration()) - sp->projectBuildDirectory = buildConfig->buildDirectory().toString(); - sp->projectSourceFiles = project->files(Project::ExcludeGeneratedFiles); - } - } - - DebuggerRunConfigurationAspect *debuggerAspect = runConfig->extraAspect(); - QTC_ASSERT(debuggerAspect, return false); - sp->multiProcess = debuggerAspect->useMultiProcess(); - - if (debuggerAspect->useCppDebugger()) - sp->languages |= CppLanguage; - - if (debuggerAspect->useQmlDebugger()) { - const IDevice::ConstPtr device = DeviceKitInformation::device(runConfig->target()->kit()); - QTC_ASSERT(device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE, return sp); - QTcpServer server; - const bool canListen = server.listen(QHostAddress::LocalHost) - || server.listen(QHostAddress::LocalHostIPv6); - if (!canListen) { - if (errorMessage) - *errorMessage = DebuggerPlugin::tr("Not enough free ports for QML debugging.") + QLatin1Char(' '); - return sp; - } - sp->qmlServerAddress = server.serverAddress().toString(); - sp->qmlServerPort = server.serverPort(); - sp->languages |= QmlLanguage; - - // Makes sure that all bindings go through the JavaScript engine, so that - // breakpoints are actually hit! - const QString optimizerKey = _("QML_DISABLE_OPTIMIZER"); - if (!sp->environment.hasKey(optimizerKey)) - sp->environment.set(optimizerKey, _("1")); - - QtcProcess::addArg(&sp->processArgs, QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(sp->qmlServerPort)); - } - - sp->startMode = StartInternal; - sp->displayName = runConfig->displayName(); - - return true; -} - -namespace Internal { - -bool fillParametersFromLocalRunConfiguration - (DebuggerRunParameters *rp, const RunConfiguration *runConfig, QString *errorMessage) -{ - if (!fillParametersFromRunConfiguration(rp, runConfig, errorMessage)) - return false; - - auto rc = qobject_cast(runConfig); - QTC_ASSERT(rc, return false); - // Normalize to work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch'...) - rp->workingDirectory = FileUtils::normalizePathName(rc->workingDirectory()); - - rp->executable = rc->executable(); - if (rp->executable.isEmpty()) - return false; - - rp->processArgs = rc->commandLineArguments(); - rp->useTerminal = rc->runMode() == ApplicationLauncher::Console; - - return true; -} - -RunControl *DebuggerRunControlFactory::create - (RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) -{ - QTC_ASSERT(runConfiguration, return 0); - QTC_ASSERT(mode == DebugRunMode || mode == DebugRunModeWithBreakOnMain, return 0); - - // We cover only local setup here. Remote setups are handled by the - // RunControl factories in the target specific plugins. - DebuggerRunParameters rp; - bool res = fillParametersFromLocalRunConfiguration(&rp, runConfiguration, errorMessage); - if (rp.startMode == NoStartMode) - return 0; - - QTC_ASSERT(res, return 0); - - if (mode == DebugRunModeWithBreakOnMain) - rp.breakOnMain = true; - - rp.runConfiguration = runConfiguration; - return createDebuggerRunControlInternal(rp, errorMessage); -} - QObject *createDebuggerRunControlFactory(QObject *parent) { return new DebuggerRunControlFactory(parent); } -DebuggerRunControl *createDebuggerRunControlInternal(const DebuggerRunParameters &rp0, QString *errorMessage) +//////////////////////////////////////////////////////////////////////// +// +// Externally visible helper. +// +//////////////////////////////////////////////////////////////////////// + +/** + * Used for direct "special" starts from actions in the debugger plugin. + */ +DebuggerRunControl *createAndScheduleRun(const DebuggerRunParameters &rp, const Kit *kit) { - QTC_ASSERT(rp0.runConfiguration, return 0); - const Target *target = rp0.runConfiguration->target(); - QTC_ASSERT(target, return 0); - - DebuggerRunParameters rp = rp0; - TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_DEBUGINFO); - TaskHub::clearTasks(Debugger::Constants::TASK_CATEGORY_DEBUGGER_RUNTIME); - - if (!boolSetting(AutoEnrichParameters)) { - const QString sysroot = rp.sysRoot; - if (rp.debugInfoLocation.isEmpty()) - rp.debugInfoLocation = sysroot + QLatin1String("/usr/lib/debug"); - if (rp.debugSourceLocation.isEmpty()) { - QString base = sysroot + QLatin1String("/usr/src/debug/"); - rp.debugSourceLocation.append(base + QLatin1String("qt5base/src/corelib")); - rp.debugSourceLocation.append(base + QLatin1String("qt5base/src/gui")); - rp.debugSourceLocation.append(base + QLatin1String("qt5base/src/network")); - } - } - - if (rp.masterEngineType == NoEngineType) { - if (rp.executable.endsWith(_(".py")) - || rp.executable == _("/usr/bin/python") - || rp.executable == _("/usr/bin/python3")) { - rp.masterEngineType = PdbEngineType; - } else { - if (!fillParametersFromKit(&rp, target->kit(), errorMessage)) - return 0; - auto aspect = rp.runConfiguration->extraAspect(); - const bool useCppDebugger = aspect->useCppDebugger() && (rp.languages & CppLanguage); - const bool useQmlDebugger = aspect->useQmlDebugger() && (rp.languages & QmlLanguage); - if (useQmlDebugger) { - if (useCppDebugger) - rp.masterEngineType = QmlCppEngineType; - else - rp.masterEngineType = QmlEngineType; - } else { - rp.masterEngineType = rp.cppEngineType; - } - } - } - - rp.device = DeviceKitInformation::device(target->kit()); - if (rp.device && rp.connParams.port == 0) - rp.connParams = rp.device->sshParameters(); - - // Could have been set from command line. - if (rp.remoteChannel.isEmpty()) - rp.remoteChannel = rp.connParams.host + QLatin1Char(':') + QString::number(rp.connParams.port); - - QString error; - DebuggerEngine *engine = createEngine(rp.masterEngineType, rp, &error); - if (!engine) { - Core::ICore::showWarningWithOptions(DebuggerRunControl::tr("Debugger"), error); - if (errorMessage) - *errorMessage = error; - return 0; - } - return new DebuggerRunControl(rp.runConfiguration, engine); -} - -DebuggerRunControl *createAndScheduleRun(const DebuggerRunParameters &rp) -{ - QString errorMessage; - DebuggerRunControl *rc = createDebuggerRunControlInternal(rp, &errorMessage); - if (!rc) { - ProjectExplorerPlugin::showRunErrorMessage(errorMessage); + DebuggerRunControlCreator creator; + creator.m_rp = rp; + creator.enrich(0, kit); + creator.createRunControl(); + if (!creator.m_runControl) { + ProjectExplorerPlugin::showRunErrorMessage(creator.fullError()); return 0; } Internal::showMessage(rp.startMessage, 0); - ProjectExplorerPlugin::startRunControl(rc, DebugRunMode); - return rc; -} - -static QString executableForPid(qint64 pid) -{ - foreach (const DeviceProcessItem &p, DeviceProcessList::localProcesses()) - if (p.pid == pid) - return p.exe; - return QString(); -} - -bool fillParametersFromKit(DebuggerStartParameters *sp, const Kit *kit, QString *errorMessage /* = 0 */) -{ - if (!kit) { - // This code can only be reached when starting via the command line - // (-debug pid or executable) or attaching from runconfiguration - // without specifying a kit. Try to find a kit via ABI. - QList abis; - if (sp->toolChainAbi.isValid()) { - abis.push_back(sp->toolChainAbi); - } else { - // Try via executable. - if (sp->executable.isEmpty() - && (sp->startMode == AttachExternal || sp->startMode == AttachCrashedExternal)) { - sp->executable = executableForPid(sp->attachPID); - } - if (!sp->executable.isEmpty()) - abis = Abi::abisOfBinary(FileName::fromString(sp->executable)); - } - if (!abis.isEmpty()) { - // Try exact abis. - kit = KitManager::find(std::function([abis](const Kit *k) -> bool { - if (const ToolChain *tc = ToolChainKitInformation::toolChain(k)) { - return abis.contains(tc->targetAbi()) - && DebuggerKitInformation::isValidDebugger(k); - } - return false; - })); - if (!kit) { - // Or something compatible. - kit = KitManager::find(std::function([abis](const Kit *k) -> bool { - if (const ToolChain *tc = ToolChainKitInformation::toolChain(k)) - foreach (const Abi &a, abis) - if (a.isCompatibleWith(tc->targetAbi()) && DebuggerKitInformation::isValidDebugger(k)) - return true; - return false; - })); - } - } - if (!kit) - kit = KitManager::defaultKit(); - } - - // Verify that debugger and profile are valid - if (!kit) { - sp->startMode = NoStartMode; - if (errorMessage) - *errorMessage = DebuggerKitInformation::tr("No kit found."); - return false; - } - // validate debugger if C++ debugging is enabled - if (sp->languages & CppLanguage) { - const QList tasks = DebuggerKitInformation::validateDebugger(kit); - if (!tasks.isEmpty()) { - sp->startMode = NoStartMode; - if (errorMessage) { - foreach (const Task &t, tasks) { - if (errorMessage->isEmpty()) - errorMessage->append(QLatin1Char('\n')); - errorMessage->append(t.description); - } - } - return false; - } - } - sp->cppEngineType = DebuggerKitInformation::engineType(kit); - sp->sysRoot = SysRootKitInformation::sysRoot(kit).toString(); - sp->debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString(); - - ToolChain *tc = ToolChainKitInformation::toolChain(kit); - if (tc) - sp->toolChainAbi = tc->targetAbi(); - - return true; -} - -DebuggerEngine *createEngine(DebuggerEngineType et, - const DebuggerRunParameters &rp, QString *errorMessage) -{ - switch (et) { - case GdbEngineType: - return createGdbEngine(rp); - case CdbEngineType: - return createCdbEngine(rp, errorMessage); - case PdbEngineType: - return createPdbEngine(rp); - case QmlEngineType: - return createQmlEngine(rp); - case LldbEngineType: - return createLldbEngine(rp); - case QmlCppEngineType: - return createQmlCppEngine(rp, errorMessage); - default: - break; - } - *errorMessage = DebuggerPlugin::tr("Unable to create a debugger engine of the type \"%1\""). - arg(_(engineTypeName(et))); - return 0; + ProjectExplorerPlugin::startRunControl(creator.m_runControl, DebugRunMode); + return creator.m_runControl; // Only used for tests. } } // namespace Internal +/** + * Main entry point for target plugins. + */ DebuggerRunControl *createDebuggerRunControl(const DebuggerStartParameters &sp, QString *errorMessage) { - DebuggerRunParameters rp; - rp.initialize(sp); - return createDebuggerRunControlInternal(rp, errorMessage); + DebuggerRunControlCreator creator; + creator.initialize(sp); + creator.enrich(sp.runConfiguration, 0); + creator.createRunControl(); + if (errorMessage) + *errorMessage = creator.fullError(); + if (!creator.m_runControl) { + Core::ICore::showWarningWithOptions(DebuggerRunControl::tr("Debugger"), creator.fullError()); + return 0; + } + return creator.m_runControl; +} + +/** + * Helper for 3rd party plugins in need to reproduce the enrichment process. + */ +bool fillParametersFromRunConfiguration(DebuggerStartParameters *sp, const RunConfiguration *runConfig, + QString *errorMessage) +{ + DebuggerRunControlCreator creator; + creator.initialize(*sp); + creator.enrich(runConfig, 0); + creator.createRunControl(); + if (errorMessage) + *errorMessage = creator.fullError(); + *sp = creator.m_rp; + return creator.m_errors.isEmpty(); } } // namespace Debugger diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h index 0bc345e7338..0fb933811ec 100644 --- a/src/plugins/debugger/debuggerruncontrol.h +++ b/src/plugins/debugger/debuggerruncontrol.h @@ -43,8 +43,8 @@ class DebuggerStartParameters; class DebuggerRunControl; namespace Internal { -class DebuggerRunParameters; -DebuggerRunControl *createDebuggerRunControlInternal(const DebuggerRunParameters &, QString *); +class DebuggerEngine; +class DebuggerRunControlCreator; } DEBUGGER_EXPORT DebuggerRunControl *createDebuggerRunControl(const DebuggerStartParameters &sp, @@ -54,8 +54,6 @@ DEBUGGER_EXPORT bool fillParametersFromRunConfiguration(DebuggerStartParameters const ProjectExplorer::RunConfiguration *runConfig, QString *errorMessage); -namespace Internal { class DebuggerEngine; } - class DEBUGGER_EXPORT DebuggerRunControl : public ProjectExplorer::RunControl { @@ -92,8 +90,7 @@ signals: private: void handleFinished(); - friend DebuggerRunControl *Debugger::Internal::createDebuggerRunControlInternal( - const Internal::DebuggerRunParameters &rp, QString *errorMessage); + friend class Internal::DebuggerRunControlCreator; DebuggerRunControl(ProjectExplorer::RunConfiguration *runConfig, Internal::DebuggerEngine *engine); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 0edf1070e31..f5dc8efa93b 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3526,7 +3526,7 @@ void GdbEngine::handleMakeSnapshot(const DebuggerResponse &response, const QStri } rp.displayName = function + _(": ") + QDateTime::currentDateTime().toString(); rp.isSnapshot = true; - createAndScheduleRun(rp); + createAndScheduleRun(rp, 0); } else { QByteArray msg = response.data["msg"].data(); AsynchronousMessageBox::critical(tr("Snapshot Creation Error"), diff --git a/src/plugins/debugger/gdb/startgdbserverdialog.cpp b/src/plugins/debugger/gdb/startgdbserverdialog.cpp index 0dd3290cd3d..c9acf9e8978 100644 --- a/src/plugins/debugger/gdb/startgdbserverdialog.cpp +++ b/src/plugins/debugger/gdb/startgdbserverdialog.cpp @@ -213,8 +213,6 @@ void GdbServerStarter::attach(int port) } DebuggerRunParameters rp; - bool res = fillParametersFromKit(&rp, d->kit); - QTC_ASSERT(res, return); rp.masterEngineType = GdbEngineType; rp.connParams.port = port; rp.remoteChannel = rp.connParams.host + QLatin1Char(':') + QString::number(rp.connParams.port); @@ -222,7 +220,7 @@ void GdbServerStarter::attach(int port) rp.executable = localExecutable; rp.startMode = AttachToRemoteServer; rp.closeMode = KillAtClose; - createAndScheduleRun(rp); + createAndScheduleRun(rp, d->kit); } void GdbServerStarter::handleProcessClosed(int status) diff --git a/src/plugins/debugger/qml/qmlcppengine.cpp b/src/plugins/debugger/qml/qmlcppengine.cpp index 69d905acf4d..160720465ae 100644 --- a/src/plugins/debugger/qml/qmlcppengine.cpp +++ b/src/plugins/debugger/qml/qmlcppengine.cpp @@ -60,10 +60,9 @@ enum { debug = 0 }; } \ } while (0) -DebuggerEngine *createQmlCppEngine(const DebuggerRunParameters &sp, - QString *errorMessage) +DebuggerEngine *createQmlCppEngine(const DebuggerRunParameters &sp, QStringList *errors) { - QmlCppEngine *newEngine = new QmlCppEngine(sp, errorMessage); + QmlCppEngine *newEngine = new QmlCppEngine(sp, errors); if (newEngine->cppEngine()) return newEngine; delete newEngine; @@ -77,14 +76,17 @@ DebuggerEngine *createQmlCppEngine(const DebuggerRunParameters &sp, // //////////////////////////////////////////////////////////////////////// -QmlCppEngine::QmlCppEngine(const DebuggerRunParameters &rp, QString *errorMessage) +QmlCppEngine::QmlCppEngine(const DebuggerRunParameters &rp, QStringList *errors) : DebuggerEngine(rp) { setObjectName(QLatin1String("QmlCppEngine")); m_qmlEngine = new QmlEngine(rp, this); - m_cppEngine = createEngine(rp.cppEngineType, rp, errorMessage); + QStringList innerErrors; + m_cppEngine = createEngine(rp.cppEngineType, rp, &innerErrors); if (!m_cppEngine) { - *errorMessage = tr("The slave debugging engine required for combined QML/C++-Debugging could not be created: %1").arg(*errorMessage); + errors->append(tr("The slave debugging engine required for combined " + "QML/C++-Debugging could not be created: %1") + .arg(innerErrors.join(QLatin1Char('\n')))); return; } m_cppEngine->setMasterEngine(this); diff --git a/src/plugins/debugger/qml/qmlcppengine.h b/src/plugins/debugger/qml/qmlcppengine.h index dfb1f2b86b3..9985b747783 100644 --- a/src/plugins/debugger/qml/qmlcppengine.h +++ b/src/plugins/debugger/qml/qmlcppengine.h @@ -43,7 +43,7 @@ class QmlCppEngine : public DebuggerEngine Q_OBJECT public: - QmlCppEngine(const DebuggerRunParameters &sp, QString *errorMessage); + QmlCppEngine(const DebuggerRunParameters &sp, QStringList *errors); ~QmlCppEngine(); bool canDisplayTooltip() const; From 051172131311f31bb88086d2271e734e2d7a1231 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 24 Jun 2015 12:32:28 +0200 Subject: [PATCH 051/113] Core: Make Id and Feature more separate Remove Id from the public interfaces of Feature and FeatureSet and disallow implicit conversions from Id to Feature. Change-Id: I33ba692ce82552f0c2b867c6c57b9c8547264243 Reviewed-by: Daniel Teske --- src/plugins/coreplugin/featureprovider.h | 30 +++++++++---------- src/plugins/designer/cpp/formclasswizard.cpp | 2 +- .../customwizard/customwizardparameters.cpp | 6 ++-- .../jsonwizard/jsonkitspage.cpp | 4 +-- .../projectexplorer/jsonwizard/jsonkitspage.h | 2 +- .../projectexplorer/kitinformation.cpp | 2 +- .../customwidgetwizard/customwidgetwizard.cpp | 2 +- .../wizards/guiappwizard.cpp | 2 +- .../wizards/librarywizard.cpp | 2 +- .../wizards/subdirsprojectwizard.cpp | 2 +- src/plugins/qtsupport/baseqtversion.cpp | 4 +-- 11 files changed, 27 insertions(+), 31 deletions(-) diff --git a/src/plugins/coreplugin/featureprovider.h b/src/plugins/coreplugin/featureprovider.h index 8155653fa10..61690966791 100644 --- a/src/plugins/coreplugin/featureprovider.h +++ b/src/plugins/coreplugin/featureprovider.h @@ -55,32 +55,30 @@ public: class CORE_EXPORT Feature : public Id { public: - Feature(Id id) : Id(id) {} + Feature() = default; + template Feature(const char(&ch)[N]) : Id(ch) { } + + static Feature fromString(const QString &str) { return Feature(Id::fromString(str)); } + static Feature fromName(const QByteArray &ba) { return Feature(Id::fromName(ba)); } + +private: + explicit Feature(const Id id) : Id(id) { } }; class CORE_EXPORT FeatureSet : private QSet { public: - FeatureSet() {} - - FeatureSet(Id id) + explicit FeatureSet(Feature id) { if (id.isValid()) insert(id); } - FeatureSet(const FeatureSet &other) : QSet(other) {} + FeatureSet() = default; + FeatureSet(const FeatureSet &other) = default; + FeatureSet &operator=(const FeatureSet &other) = default; - FeatureSet &operator=(const FeatureSet &other) - { - QSet::operator=(other); - return *this; - } - - bool isEmpty() const - { - return QSet::isEmpty(); - } + using QSet::isEmpty; bool contains(const Feature &feature) const { @@ -144,7 +142,7 @@ public: { FeatureSet features; foreach (const QString &i, list) - features |= Feature(Id::fromString(i)); + features |= Feature::fromString(i); return features; } }; diff --git a/src/plugins/designer/cpp/formclasswizard.cpp b/src/plugins/designer/cpp/formclasswizard.cpp index e728b4c2caa..558d92d6d1a 100644 --- a/src/plugins/designer/cpp/formclasswizard.cpp +++ b/src/plugins/designer/cpp/formclasswizard.cpp @@ -43,7 +43,7 @@ namespace Internal { FormClassWizard::FormClassWizard() { - setRequiredFeatures(Core::Feature(QtSupport::Constants::FEATURE_QWIDGETS)); + setRequiredFeatures(Core::FeatureSet(QtSupport::Constants::FEATURE_QWIDGETS)); } QString FormClassWizard::headerSuffix() const diff --git a/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp b/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp index a9a93bf8686..86e9c3658e9 100644 --- a/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp +++ b/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp @@ -461,10 +461,8 @@ static inline FeatureSet readRequiredFeatures(const QXmlStreamReader &reader) QString value = reader.attributes().value(QLatin1String(featuresRequiredC)).toString(); QStringList stringList = value.split(QLatin1Char(','), QString::SkipEmptyParts); FeatureSet features; - foreach (const QString &string, stringList) { - Feature feature(Id::fromString(string)); - features |= feature; - } + foreach (const QString &string, stringList) + features |= Feature::fromString(string); return features; } diff --git a/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp index 647384cec80..c8ec2532b89 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp @@ -167,7 +167,7 @@ QVector JsonKitsPage::parseFeatures(const QVar foreach (const QVariant &element, data.toList()) { if (element.type() == QVariant::String) { - result.append({ Id::fromString(element.toString()), QVariant(true) }); + result.append({ Feature::fromString(element.toString()), QVariant(true) }); } else if (element.type() == QVariant::Map) { const QVariantMap obj = element.toMap(); const QString feature = obj.value(QLatin1String(KEY_FEATURE)).toString(); @@ -177,7 +177,7 @@ QVector JsonKitsPage::parseFeatures(const QVar return QVector(); } - result.append({ Id::fromString(feature), obj.value(QLatin1String(KEY_CONDITION), true) }); + result.append({ Feature::fromString(feature), obj.value(QLatin1String(KEY_CONDITION), true) }); } else { if (errorMessage) *errorMessage = tr("Feature list element is not a string or object."); diff --git a/src/plugins/projectexplorer/jsonwizard/jsonkitspage.h b/src/plugins/projectexplorer/jsonwizard/jsonkitspage.h index c2e56112268..1f21b80aedf 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonkitspage.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonkitspage.h @@ -57,7 +57,7 @@ public: class ConditionalFeature { public: - ConditionalFeature() : feature(Core::Id()) { } + ConditionalFeature() = default; ConditionalFeature(const Core::Feature &f, const QVariant &c) : feature(f), condition(c) { } diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp index 0d4a5eb9842..19ef2a939b2 100644 --- a/src/plugins/projectexplorer/kitinformation.cpp +++ b/src/plugins/projectexplorer/kitinformation.cpp @@ -346,7 +346,7 @@ Core::FeatureSet DeviceTypeKitInformation::availableFeatures(const Kit *k) const Core::Id id = DeviceTypeKitInformation::deviceTypeId(k); Core::FeatureSet result; if (id.isValid()) - result |= Core::Feature(Core::Id::fromString(QString::fromLatin1("DeviceType.") + id.toString())); + result |= Core::Feature::fromString(QString::fromLatin1("DeviceType.") + id.toString()); return result; } diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwizard.cpp b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwizard.cpp index d0308aff001..480d585e545 100644 --- a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwizard.cpp +++ b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwizard.cpp @@ -52,7 +52,7 @@ CustomWidgetWizard::CustomWidgetWizard() setDisplayName(tr("Qt Custom Designer Widget")); setDescription(tr("Creates a Qt Custom Designer Widget or a Custom Widget Collection.")); setIcon(QIcon(QLatin1String(":/wizards/images/gui.png"))); - setRequiredFeatures(Core::Feature(QtSupport::Constants::FEATURE_QWIDGETS)); + setRequiredFeatures(Core::FeatureSet(QtSupport::Constants::FEATURE_QWIDGETS)); } Core::BaseFileWizard *CustomWidgetWizard::create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const diff --git a/src/plugins/qmakeprojectmanager/wizards/guiappwizard.cpp b/src/plugins/qmakeprojectmanager/wizards/guiappwizard.cpp index f0092950ad6..b0921cc9e1f 100644 --- a/src/plugins/qmakeprojectmanager/wizards/guiappwizard.cpp +++ b/src/plugins/qmakeprojectmanager/wizards/guiappwizard.cpp @@ -83,7 +83,7 @@ GuiAppWizard::GuiAppWizard() "Includes a Qt Designer-based main window.\n\n" "Preselects a desktop Qt for building the application if available.")); setIcon(QIcon(QLatin1String(":/wizards/images/gui.png"))); - setRequiredFeatures(Core::Feature(QtSupport::Constants::FEATURE_QWIDGETS)); + setRequiredFeatures(Core::FeatureSet(QtSupport::Constants::FEATURE_QWIDGETS)); } Core::BaseFileWizard *GuiAppWizard::create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const diff --git a/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp b/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp index 3e10554ba59..b35b10311cd 100644 --- a/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp +++ b/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp @@ -56,7 +56,7 @@ LibraryWizard::LibraryWizard() "
  • a shared C++ library for use with QPluginLoader and runtime (Plugins)
  • " "
  • a shared or static C++ library for use with another project at linktime
  • ")); setIcon(QIcon(QLatin1String(":/wizards/images/lib.png"))); - setRequiredFeatures(Core::Feature(QtSupport::Constants::FEATURE_QT)); + setRequiredFeatures(Core::FeatureSet(QtSupport::Constants::FEATURE_QT)); } Core::BaseFileWizard *LibraryWizard::create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const diff --git a/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizard.cpp b/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizard.cpp index 07c46b2d0dd..01038647bff 100644 --- a/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizard.cpp +++ b/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizard.cpp @@ -51,7 +51,7 @@ SubdirsProjectWizard::SubdirsProjectWizard() setDescription(tr("Creates a qmake-based subdirs project. This allows you to group " "your projects in a tree structure.")); setIcon(QIcon(QLatin1String(":/wizards/images/gui.png"))); - setRequiredFeatures(Core::Feature(QtSupport::Constants::FEATURE_QT)); + setRequiredFeatures(Core::FeatureSet(QtSupport::Constants::FEATURE_QT)); } Core::BaseFileWizard *SubdirsProjectWizard::create(QWidget *parent, diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index bca68d01341..e642c83f818 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -102,9 +102,9 @@ FeatureSet QtVersionNumber::features() const result |= Feature(Constants::FEATURE_QT); if (majorVersion >= 0) { QString featureMajor = QString::fromLatin1(Constants::FEATURE_QT) + QString::number(majorVersion); - result |= Feature(Id::fromString(featureMajor)); + result |= Feature::fromString(featureMajor); for (int i = 0; i <= minorVersion; ++i) - result |= Feature(Id::fromString(featureMajor + QLatin1Char('.') + QString::number(i))); + result |= Feature::fromString(featureMajor + QLatin1Char('.') + QString::number(i)); } return result; } From 0e0f8b318e7bc2133f248084d22b8d723be03296 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 25 Jun 2015 12:53:59 +0200 Subject: [PATCH 052/113] Clang: Filter out connection errors The connections server needs some time to start and so the first connect can be fail. Don't print an error in that case. Change-Id: I38fe5401cd47a4ad1a552dcbdfafcc851e5dd7cf Reviewed-by: Nikolai Kosjar --- src/libs/clangbackendipc/connectionclient.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libs/clangbackendipc/connectionclient.cpp b/src/libs/clangbackendipc/connectionclient.cpp index 10384f6a52b..0b803b8a407 100644 --- a/src/libs/clangbackendipc/connectionclient.cpp +++ b/src/libs/clangbackendipc/connectionclient.cpp @@ -155,8 +155,6 @@ void ConnectionClient::restartProcessIfTimerIsNotResettedAndSocketIsEmpty() bool ConnectionClient::connectToLocalSocket() { - QThread::msleep(30); - for (int counter = 0; counter < 1000; counter++) { localSocket.connectToServer(connectionName()); bool isConnected = localSocket.waitForConnected(20); @@ -198,9 +196,10 @@ void ConnectionClient::killProcess() } } -void ConnectionClient::printLocalSocketError(QLocalSocket::LocalSocketError /*socketError*/) +void ConnectionClient::printLocalSocketError(QLocalSocket::LocalSocketError socketError) { - qWarning() << "ClangCodeModel ConnectionClient LocalSocket Error:" << localSocket.errorString(); + if (socketError != QLocalSocket::ServerNotFoundError) + qWarning() << "ClangCodeModel ConnectionClient LocalSocket Error:" << localSocket.errorString(); } void ConnectionClient::printStandardOutput() From 22b28fe49fbd55c878c7d398c52eb06d5bc81b53 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sat, 20 Jun 2015 22:39:11 +0300 Subject: [PATCH 053/113] Changelog: Remove false limitation The real problem is currently addressed. Change-Id: I85e341340ec5dce5424b4cc40b29fe480fe64f12 Reviewed-by: Nikolai Kosjar --- dist/changes-3.5.0.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dist/changes-3.5.0.md b/dist/changes-3.5.0.md index f2424ffb103..ea202cf0726 100644 --- a/dist/changes-3.5.0.md +++ b/dist/changes-3.5.0.md @@ -93,10 +93,7 @@ C++ Support * Partially fixed STL containers (QTCREATORBUG-8937, QTCREATORBUG-8922) * GCC implementation of `std::map`, `std::unique_ptr` (and other pointer wrappers) and `std::vector` are known to work - * Known limitations: - * MSVC implementation is not supported - * types that contain a typedef for `pointer` are not supported - (For example: `std::unique_ptr`) + * MSVC implementation is not supported QML Support From 4de821a8a44268c07a2a2bfa73620b1df29f0c76 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 15 Jun 2015 12:45:25 +0200 Subject: [PATCH 054/113] Clang: Remove INCLUDEPATH export from sqlite Change-Id: I9775737c291d1e62ffc6dd6bbce4272a4d33a1fc Reviewed-by: Nikolai Kosjar --- src/libs/sqlite/sqlite_dependencies.pri | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/sqlite/sqlite_dependencies.pri b/src/libs/sqlite/sqlite_dependencies.pri index cb383c8e63c..b55ba604116 100644 --- a/src/libs/sqlite/sqlite_dependencies.pri +++ b/src/libs/sqlite/sqlite_dependencies.pri @@ -1,3 +1,2 @@ QTC_LIB_NAME = Sqlite -INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/3rdparty/sqlite INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/sqlite From 705ac153423e91b236094507777586f641805d31 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 24 Jun 2015 15:56:47 +0200 Subject: [PATCH 055/113] Move some code from QtVersionNumber to FeatureSet Change-Id: I35f187606c3922809673d44ea2e1f15e91a9e62b Reviewed-by: Daniel Teske --- src/plugins/coreplugin/featureprovider.cpp | 39 ++++++++++++++++++++-- src/plugins/coreplugin/featureprovider.h | 4 +++ src/plugins/qtsupport/baseqtversion.cpp | 10 +----- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/plugins/coreplugin/featureprovider.cpp b/src/plugins/coreplugin/featureprovider.cpp index 3b32e59e151..4e4bc061b8a 100644 --- a/src/plugins/coreplugin/featureprovider.cpp +++ b/src/plugins/coreplugin/featureprovider.cpp @@ -86,8 +86,7 @@ \brief The FeatureSet class is a set of available or required feature sets. This class behaves similarly to QFlags. However, instead of enums, Features - relies on string ids - and is therefore extendable. + relies on string ids and is therefore extendable. \sa Core::Feature \sa Core::IWizard @@ -106,3 +105,39 @@ Returns true if all \a features are available. */ + +Core::Feature Core::Feature::versionedFeature(const QByteArray &prefix, int major, int minor) +{ + if (major < 0) + return Feature::fromName(prefix); + + QByteArray result = prefix + '.'; + result += QString::number(major).toLatin1(); + + if (minor < 0) + return Feature::fromName(result); + return Feature::fromName(result + '.' + QString::number(minor).toLatin1()); +} + +Core::FeatureSet Core::FeatureSet::versionedFeatures(const QByteArray &prefix, int major, int minor) +{ + FeatureSet result; + result |= Feature::fromName(prefix); + + if (major < 0) + return result; + + const QByteArray majorStr = QString::number(major).toLatin1(); + const QByteArray featureMajor = prefix + majorStr; + const QByteArray featureDotMajor = prefix + '.' + majorStr; + + result |= Feature::fromName(featureMajor) | Feature::fromName(featureDotMajor); + + for (int i = 0; i <= minor; ++i) { + const QByteArray minorStr = QString::number(i).toLatin1(); + result |= Feature::fromName(featureMajor + '.' + minorStr) + | Feature::fromName(featureDotMajor + '.' + minorStr); + } + + return result; +} diff --git a/src/plugins/coreplugin/featureprovider.h b/src/plugins/coreplugin/featureprovider.h index 61690966791..fc16ac6bdc6 100644 --- a/src/plugins/coreplugin/featureprovider.h +++ b/src/plugins/coreplugin/featureprovider.h @@ -61,6 +61,8 @@ public: static Feature fromString(const QString &str) { return Feature(Id::fromString(str)); } static Feature fromName(const QByteArray &ba) { return Feature(Id::fromName(ba)); } + static Feature versionedFeature(const QByteArray &prefix, int major = -1, int minor = -1); + private: explicit Feature(const Id id) : Id(id) { } }; @@ -78,6 +80,8 @@ public: FeatureSet(const FeatureSet &other) = default; FeatureSet &operator=(const FeatureSet &other) = default; + static FeatureSet versionedFeatures(const QByteArray &prefix, int major, int minor = -1); + using QSet::isEmpty; bool contains(const Feature &feature) const diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index e642c83f818..3363ca6a328 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -98,15 +98,7 @@ QtVersionNumber::QtVersionNumber() FeatureSet QtVersionNumber::features() const { - FeatureSet result; - result |= Feature(Constants::FEATURE_QT); - if (majorVersion >= 0) { - QString featureMajor = QString::fromLatin1(Constants::FEATURE_QT) + QString::number(majorVersion); - result |= Feature::fromString(featureMajor); - for (int i = 0; i <= minorVersion; ++i) - result |= Feature::fromString(featureMajor + QLatin1Char('.') + QString::number(i)); - } - return result; + return FeatureSet::versionedFeatures(Constants::FEATURE_QT, majorVersion, minorVersion); } bool QtVersionNumber::operator <(const QtVersionNumber &b) const From 57d652743e0d7ce2980a7d0f638c6824a19e50a4 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 24 Jun 2015 16:09:07 +0200 Subject: [PATCH 056/113] Qt: Update features for Qt 5.5 * Add QtVersionNumber::matches to match against a Qt version to make the code setting the features easier to follow. * Use versionedFeatures instead of adding new string constants for the latest and greatest Qt Quick and Qt Quick Controls. * Fix Qt-version-to-features mapping as discussed in QTCREATORBUG-14575 * Simplify code in qmljsbundleprovider.cpp: It should do the same thing as the old one. Change-Id: Iba24e9d299a2a2e5d6e4de7cd1e95707a574678e Reviewed-by: Daniel Teske --- .../wizards/librarywizard.cpp | 2 +- .../wizards/subdirsprojectwizard.cpp | 2 +- .../wizards/testwizard.cpp | 2 +- .../qmljstools/qmljsbundleprovider.cpp | 6 +- src/plugins/qtsupport/baseqtversion.cpp | 78 ++++++++++++------- src/plugins/qtsupport/baseqtversion.h | 3 + src/plugins/qtsupport/qtsupportconstants.h | 19 +---- src/plugins/winrt/winrtqtversion.cpp | 2 +- 8 files changed, 61 insertions(+), 53 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp b/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp index b35b10311cd..f509bdd8775 100644 --- a/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp +++ b/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp @@ -56,7 +56,7 @@ LibraryWizard::LibraryWizard() "
  • a shared C++ library for use with QPluginLoader and runtime (Plugins)
  • " "
  • a shared or static C++ library for use with another project at linktime
  • ")); setIcon(QIcon(QLatin1String(":/wizards/images/lib.png"))); - setRequiredFeatures(Core::FeatureSet(QtSupport::Constants::FEATURE_QT)); + setRequiredFeatures(Core::FeatureSet(Core::Feature::versionedFeature(QtSupport::Constants::FEATURE_QT_PREFIX))); } Core::BaseFileWizard *LibraryWizard::create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const diff --git a/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizard.cpp b/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizard.cpp index 01038647bff..3741e3c10cf 100644 --- a/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizard.cpp +++ b/src/plugins/qmakeprojectmanager/wizards/subdirsprojectwizard.cpp @@ -51,7 +51,7 @@ SubdirsProjectWizard::SubdirsProjectWizard() setDescription(tr("Creates a qmake-based subdirs project. This allows you to group " "your projects in a tree structure.")); setIcon(QIcon(QLatin1String(":/wizards/images/gui.png"))); - setRequiredFeatures(Core::FeatureSet(QtSupport::Constants::FEATURE_QT)); + setRequiredFeatures(Core::FeatureSet(Core::Feature::versionedFeature(QtSupport::Constants::FEATURE_QT_PREFIX))); } Core::BaseFileWizard *SubdirsProjectWizard::create(QWidget *parent, diff --git a/src/plugins/qmakeprojectmanager/wizards/testwizard.cpp b/src/plugins/qmakeprojectmanager/wizards/testwizard.cpp index 579f7f98caf..7aa03dc2621 100644 --- a/src/plugins/qmakeprojectmanager/wizards/testwizard.cpp +++ b/src/plugins/qmakeprojectmanager/wizards/testwizard.cpp @@ -57,7 +57,7 @@ TestWizard::TestWizard() "and that there are no regressions.")); setIcon(QIcon(QLatin1String(":/wizards/images/console.png"))); setRequiredFeatures(Core::Feature(QtSupport::Constants::FEATURE_QT_CONSOLE) | - Core::Feature(QtSupport::Constants::FEATURE_QT)); + Core::Feature::versionedFeature(QtSupport::Constants::FEATURE_QT_PREFIX)); } Core::BaseFileWizard *TestWizard::create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const diff --git a/src/plugins/qmljstools/qmljsbundleprovider.cpp b/src/plugins/qmljstools/qmljsbundleprovider.cpp index 760004caf77..78a7f78aef0 100644 --- a/src/plugins/qmljstools/qmljsbundleprovider.cpp +++ b/src/plugins/qmljstools/qmljsbundleprovider.cpp @@ -131,9 +131,7 @@ void BasicBundleProvider::mergeBundlesForKit(ProjectExplorer::Kit *kit QString qtQmlPath = qtVersion->qmakeProperty("QT_INSTALL_QML"); Core::FeatureSet features = qtVersion->availableFeatures(); - if (features.contains(Core::Feature(QtSupport::Constants::FEATURE_QT_QUICK)) - || features.contains(Core::Feature(QtSupport::Constants::FEATURE_QT_QUICK_1)) - || features.contains(Core::Feature(QtSupport::Constants::FEATURE_QT_QUICK_1_1))) { + if (features.contains(Core::Feature::versionedFeature(QtSupport::Constants::FEATURE_QT_QUICK_PREFIX))) { myReplacements.insert(QLatin1String("$(CURRENT_DIRECTORY)"), qtImportsPath); QDir qtQuick1Bundles(qtImportsPath); qtQuick1Bundles.setNameFilters(QStringList(QLatin1String("*-bundle.json"))); @@ -158,7 +156,7 @@ void BasicBundleProvider::mergeBundlesForKit(ProjectExplorer::Kit *kit bundles.mergeBundleForLanguage(Dialect::Qml, qtQuick1Bundle); bundles.mergeBundleForLanguage(Dialect::QmlQtQuick1, qtQuick1Bundle); } - if (features.contains(Core::Feature(QtSupport::Constants::FEATURE_QT_QUICK_2))) { + if (features.contains(Core::Feature::versionedFeature(QtSupport::Constants::FEATURE_QT_QUICK_PREFIX, 2))) { myReplacements.insert(QLatin1String("$(CURRENT_DIRECTORY)"), qtQmlPath); QDir qtQuick2Bundles(qtQmlPath); qtQuick2Bundles.setNameFilters(QStringList(QLatin1String("*-bundle.json"))); diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index 3363ca6a328..b4825cbf679 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -98,7 +98,24 @@ QtVersionNumber::QtVersionNumber() FeatureSet QtVersionNumber::features() const { - return FeatureSet::versionedFeatures(Constants::FEATURE_QT, majorVersion, minorVersion); + return FeatureSet::versionedFeatures(Constants::FEATURE_QT_PREFIX, majorVersion, minorVersion); +} + +bool QtVersionNumber::matches(int major, int minor, int patch) const +{ + if (major < 0) + return true; + if (major != majorVersion) + return false; + + if (minor < 0) + return true; + if (minor != minorVersion) + return false; + + if (patch < 0) + return true; + return (patch == patchVersion); } bool QtVersionNumber::operator <(const QtVersionNumber &b) const @@ -355,59 +372,62 @@ FeatureSet BaseQtVersion::availableFeatures() const { FeatureSet features = qtVersion().features(); // Qt Version features - features |= (FeatureSet(Constants::FEATURE_QWIDGETS) - | FeatureSet(Constants::FEATURE_QT_WEBKIT) - | FeatureSet(Constants::FEATURE_QT_CONSOLE)); + features |= (Feature(Constants::FEATURE_QWIDGETS) + | Feature(Constants::FEATURE_QT_WEBKIT) + | Feature(Constants::FEATURE_QT_CONSOLE)); if (qtVersion() < QtVersionNumber(4, 7, 0)) return features; - features |= FeatureSet(Constants::FEATURE_QT_QUICK); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_1); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 1, 0); - if (qtVersion() < QtVersionNumber(4, 7, 1)) + if (qtVersion().matches(4, 7, 0)) return features; - features |= FeatureSet(Constants::FEATURE_QT_QUICK_1_1); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 1, 1); - if (qtVersion() < QtVersionNumber(5, 0, 0)) + if (qtVersion().matches(4)) return features; - features |= FeatureSet(Constants::FEATURE_QT_QUICK_2); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_2_0); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 2, 0); - if (qtVersion() < QtVersionNumber(5, 1, 0)) + if (qtVersion().matches(5, 0)) return features; - features |= FeatureSet(Constants::FEATURE_QT_QUICK_2_1); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_CONTROLS); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_CONTROLS_1); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_CONTROLS_1_0); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 2, 1); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_CONTROLS_PREFIX, 1, 0); - if (qtVersion() < QtVersionNumber(5, 2, 0)) + if (qtVersion().matches(5, 1)) return features; - features |= FeatureSet(Constants::FEATURE_QT_QUICK_2_2); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_CONTROLS_1_1); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 2, 2); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_CONTROLS_PREFIX, 1, 1); - if (qtVersion() < QtVersionNumber(5, 3, 0)) + if (qtVersion().matches(5, 2)) return features; - features |= FeatureSet(Constants::FEATURE_QT_QUICK_2_3); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_CONTROLS_1_2); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 2, 3); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_CONTROLS_PREFIX, 1, 2); - if (qtVersion() < QtVersionNumber(5, 4, 0)) + if (qtVersion().matches(5, 3)) return features; - features |= FeatureSet(Constants::FEATURE_QT_QUICK_2_4); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_CONTROLS_1_3); - features |= FeatureSet(Constants::FEATURE_QT_QUICK_UI_FILES); + features |= Feature(Constants::FEATURE_QT_QUICK_UI_FILES); - if (qtVersion() < QtVersionNumber(5, 5, 0)) + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 2, 4); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_CONTROLS_PREFIX, 1, 3); + + if (qtVersion().matches(5, 4)) return features; - features |= FeatureSet(Constants::FEATURE_QT_3D); - features |= FeatureSet(Constants::FEATURE_QT_CANVAS3D); + features |= Feature(Constants::FEATURE_QT_3D); + features |= Feature(Constants::FEATURE_QT_CANVAS3D); + + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_PREFIX, 2, 5); + features |= FeatureSet::versionedFeatures(Constants::FEATURE_QT_QUICK_CONTROLS_PREFIX, 1, 4); + + if (qtVersion().matches(5, 5)) + return features; return features; } diff --git a/src/plugins/qtsupport/baseqtversion.h b/src/plugins/qtsupport/baseqtversion.h index 1df47a217ad..57d0aaaf690 100644 --- a/src/plugins/qtsupport/baseqtversion.h +++ b/src/plugins/qtsupport/baseqtversion.h @@ -73,6 +73,9 @@ public: int majorVersion; int minorVersion; int patchVersion; + + bool matches(int major = -1, int minor = -1, int patch = -1) const; + bool operator <(const QtVersionNumber &b) const; bool operator <=(const QtVersionNumber &b) const; bool operator >(const QtVersionNumber &b) const; diff --git a/src/plugins/qtsupport/qtsupportconstants.h b/src/plugins/qtsupport/qtsupportconstants.h index 38e0f0589fa..4df20c25b0c 100644 --- a/src/plugins/qtsupport/qtsupportconstants.h +++ b/src/plugins/qtsupport/qtsupportconstants.h @@ -50,24 +50,11 @@ static const char QTVERSIONID[] = "Id"; static const char QTVERSIONNAME[] = "Name"; //Qt Features -const char FEATURE_QT[] = "QtSupport.Wizards.FeatureQt"; +const char FEATURE_QT_PREFIX[] = "QtSupport.Wizards.FeatureQt"; const char FEATURE_QWIDGETS[] = "QtSupport.Wizards.FeatureQWidgets"; -const char FEATURE_QT_QUICK[] = "QtSupport.Wizards.FeatureQtQuick"; +const char FEATURE_QT_QUICK_PREFIX[] = "QtSupport.Wizards.FeatureQtQuick"; const char FEATURE_QMLPROJECT[] = "QtSupport.Wizards.FeatureQtQuickProject"; -const char FEATURE_QT_QUICK_1[] = "QtSupport.Wizards.FeatureQtQuick.1"; -const char FEATURE_QT_QUICK_1_1[] = "QtSupport.Wizards.FeatureQtQuick.1.1"; -const char FEATURE_QT_QUICK_2[] = "QtSupport.Wizards.FeatureQtQuick.2"; -const char FEATURE_QT_QUICK_2_0[] = "QtSupport.Wizards.FeatureQtQuick.2.0"; -const char FEATURE_QT_QUICK_2_1[] = "QtSupport.Wizards.FeatureQtQuick.2.1"; -const char FEATURE_QT_QUICK_2_2[] = "QtSupport.Wizards.FeatureQtQuick.2.2"; -const char FEATURE_QT_QUICK_2_3[] = "QtSupport.Wizards.FeatureQtQuick.2.3"; -const char FEATURE_QT_QUICK_2_4[] = "QtSupport.Wizards.FeatureQtQuick.2.4"; -const char FEATURE_QT_QUICK_CONTROLS[] = "QtSupport.Wizards.FeatureQtQuick.Controls"; -const char FEATURE_QT_QUICK_CONTROLS_1[] = "QtSupport.Wizards.FeatureQtQuick.Controls.1"; -const char FEATURE_QT_QUICK_CONTROLS_1_0[] = "QtSupport.Wizards.FeatureQtQuick.Controls.1.0"; -const char FEATURE_QT_QUICK_CONTROLS_1_1[] = "QtSupport.Wizards.FeatureQtQuick.Controls.1.1"; -const char FEATURE_QT_QUICK_CONTROLS_1_2[] = "QtSupport.Wizards.FeatureQtQuick.Controls.1.2"; -const char FEATURE_QT_QUICK_CONTROLS_1_3[] = "QtSupport.Wizards.FeatureQtQuick.Controls.1.3"; +const char FEATURE_QT_QUICK_CONTROLS_PREFIX[] = "QtSupport.Wizards.FeatureQtQuick.Controls"; const char FEATURE_QT_QUICK_UI_FILES[] = "QtSupport.Wizards.FeatureQtQuick.UiFiles"; const char FEATURE_QT_WEBKIT[] = "QtSupport.Wizards.FeatureQtWebkit"; const char FEATURE_QT_3D[] = "QtSupport.Wizards.FeatureQt3d"; diff --git a/src/plugins/winrt/winrtqtversion.cpp b/src/plugins/winrt/winrtqtversion.cpp index b49c8bff4e4..07728e68452 100644 --- a/src/plugins/winrt/winrtqtversion.cpp +++ b/src/plugins/winrt/winrtqtversion.cpp @@ -69,7 +69,7 @@ Core::FeatureSet WinRtQtVersion::availableFeatures() const Core::FeatureSet features = QtSupport::BaseQtVersion::availableFeatures(); features |= Core::FeatureSet(QtSupport::Constants::FEATURE_MOBILE); features.remove(Core::Feature(QtSupport::Constants::FEATURE_QT_CONSOLE)); - features.remove(Core::Feature(QtSupport::Constants::FEATURE_QT_QUICK_1)); + features.remove(Core::Feature::versionedFeature(QtSupport::Constants::FEATURE_QT_QUICK_CONTROLS_PREFIX, 1)); features.remove(Core::Feature(QtSupport::Constants::FEATURE_QT_WEBKIT)); return features; } From 040a0f2d30ca62ec08bff022d27a33103554d593 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 24 Jun 2015 16:14:45 +0200 Subject: [PATCH 057/113] JsonWizard: Allow for variables in features passed to KitsPage Change-Id: I8c0d6b8b6e46d2de7cd4b088c7c98c2efe57427f Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp | 6 +++--- src/plugins/projectexplorer/jsonwizard/jsonkitspage.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp index c8ec2532b89..af2641351c2 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonkitspage.cpp @@ -145,7 +145,7 @@ FeatureSet JsonKitsPage::evaluate(const QVectorexpander())) - features |= f.feature; + features |= Feature::fromString(wiz->expander()->expand(f.feature)); } return features; } @@ -167,7 +167,7 @@ QVector JsonKitsPage::parseFeatures(const QVar foreach (const QVariant &element, data.toList()) { if (element.type() == QVariant::String) { - result.append({ Feature::fromString(element.toString()), QVariant(true) }); + result.append({ element.toString(), QVariant(true) }); } else if (element.type() == QVariant::Map) { const QVariantMap obj = element.toMap(); const QString feature = obj.value(QLatin1String(KEY_FEATURE)).toString(); @@ -177,7 +177,7 @@ QVector JsonKitsPage::parseFeatures(const QVar return QVector(); } - result.append({ Feature::fromString(feature), obj.value(QLatin1String(KEY_CONDITION), true) }); + result.append({ feature, obj.value(QLatin1String(KEY_CONDITION), true) }); } else { if (errorMessage) *errorMessage = tr("Feature list element is not a string or object."); diff --git a/src/plugins/projectexplorer/jsonwizard/jsonkitspage.h b/src/plugins/projectexplorer/jsonwizard/jsonkitspage.h index 1f21b80aedf..ac9dd50a221 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonkitspage.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonkitspage.h @@ -58,10 +58,10 @@ public: class ConditionalFeature { public: ConditionalFeature() = default; - ConditionalFeature(const Core::Feature &f, const QVariant &c) : feature(f), condition(c) + ConditionalFeature(const QString &f, const QVariant &c) : feature(f), condition(c) { } - Core::Feature feature; + QString feature; QVariant condition; }; static QVector parseFeatures(const QVariant &data, From d41c634be0ec8edfb2c946b72ccce7f7c640c6fd Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 24 Jun 2015 16:15:14 +0200 Subject: [PATCH 058/113] QtQuickWizards: Fix versions and make minimum Qt version work Task-number: QTCREATORBUG-14575 Change-Id: I9ace40e71b8b1d1f753966bb73f0269c4f918afa Reviewed-by: Tobias Hunger --- .../projects/qmake/qtquickapplication/wizard.json | 11 +++-------- .../qmake/qtquickcontrolsapplication/wizard.json | 14 +++++--------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/share/qtcreator/templates/wizards/projects/qmake/qtquickapplication/wizard.json b/share/qtcreator/templates/wizards/projects/qmake/qtquickapplication/wizard.json index 6e14d9b695a..d633eddf6bf 100644 --- a/share/qtcreator/templates/wizards/projects/qmake/qtquickapplication/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qmake/qtquickapplication/wizard.json @@ -15,7 +15,8 @@ { "key": "ProFileName", "value": "%{JS: Util.fileName('%{ProjectDirectory}/%{ProjectName}', 'pro')}" }, { "key": "MainCppFileName", "value": "%{JS: 'main.' + Util.preferredSuffix('text/x-c++src')}" }, { "key": "QtQuickVersion", "value": "%{JS: %{QtVersion}.qtQuickVersion}" }, - { "key": "QtQuickWindowVersion", "value": "%{JS: %{QtVersion}.qtQuickWindowVersion}" } + { "key": "QtQuickWindowVersion", "value": "%{JS: %{QtVersion}.qtQuickWindowVersion}" }, + { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" } ], "pages": @@ -86,13 +87,7 @@ "typeId": "Kits", "data": { "projectFilePath": "%{ProFileName}", - "requiredFeatures": - [ - "QtSupport.Wizards.FeatureQt", - { "feature": "QtSupport.Wizards.FeatureQtQuick.2.3", "condition": "%{JS: '%{QtQuickVersion}' === '2.3'}" }, - { "feature": "QtSupport.Wizards.FeatureQtQuick.2.4", "condition": "%{JS: '%{QtQuickVersion}' === '2.4'}" }, - { "feature": "QtSupport.Wizards.FeatureQtQuick.2.5", "condition": "%{JS: '%{QtQuickVersion}' === '2.5'}" } - ] + "requiredFeatures": [ "QtSupport.Wizards.FeatureQt", "%{QtQuickFeature}" ] } }, { diff --git a/share/qtcreator/templates/wizards/projects/qmake/qtquickcontrolsapplication/wizard.json b/share/qtcreator/templates/wizards/projects/qmake/qtquickcontrolsapplication/wizard.json index 13567e55f13..7738f28e5ac 100644 --- a/share/qtcreator/templates/wizards/projects/qmake/qtquickcontrolsapplication/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qmake/qtquickcontrolsapplication/wizard.json @@ -17,7 +17,8 @@ { "key": "QtQuickVersion", "value": "%{JS: %{QtVersion}.qtQuickVersion}" }, { "key": "QtQuickControlsVersion", "value": "%{JS: %{QtVersion}.qtQuickControlsVersion}" }, { "key": "QtQuickDialogsVersion", "value": "%{JS: %{QtVersion}.qtQuickDialogsVersion}" }, - { "key": "QtQuickLayoutsVersion", "value": "%{JS: %{QtVersion}.qtQuickLayoutsVersion}" } + { "key": "QtQuickLayoutsVersion", "value": "%{JS: %{QtVersion}.qtQuickLayoutsVersion}" }, + { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" } ], "pages": @@ -46,7 +47,7 @@ "value": "{ 'qtQuickVersion': '2.5', - 'qtQuickControlsVersion': '1.3', + 'qtQuickControlsVersion': '1.4', 'qtQuickDialogsVersion': '1.2', 'qtQuickLayoutsVersion': '1.2' }", @@ -57,7 +58,7 @@ "value": "{ 'qtQuickVersion': '2.4', - 'qtQuickControlsVersion': '1.2', + 'qtQuickControlsVersion': '1.3', 'qtQuickDialogsVersion': '1.2', 'qtQuickLayoutsVersion': '1.1' }", @@ -103,12 +104,7 @@ "typeId": "Kits", "data": { "projectFilePath": "%{ProFileName}", - "requiredFeatures": - [ - "QtSupport.Wizards.FeatureQt", - { "feature": "QtSupport.Wizards.FeatureQtQuick.Controls.1.2", "condition": "%{JS: '%{QtQuickControlsVersion' === '1.2' }" }, - { "feature": "QtSupport.Wizards.FeatureQtQuick.Controls.1.3", "condition": "%{JS: '%{QtQuickControlsVersion' === '1.3' }" } - ] + "requiredFeatures": [ "QtSupport.Wizards.FeatureQt", "%{QtQuickFeature}" ] } }, { From dcccb4cb8d863bb3f4bed2b52136e29efe117519 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 25 Jun 2015 13:46:22 +0200 Subject: [PATCH 059/113] CppTools: Use CompilerOptionsBuilder as an object Makes the client code more readable. Change-Id: Ie98ba93c758643039d3ebdc7550b1c4ac9473298 Reviewed-by: Marco Bubke Reviewed-by: Christian Kandeler --- src/plugins/clangcodemodel/clangutils.cpp | 56 +++++++++--------- src/plugins/cpptools/cppprojects.cpp | 71 ++++++++++++----------- src/plugins/cpptools/cppprojects.h | 29 ++++----- 3 files changed, 83 insertions(+), 73 deletions(-) diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index bc2e3341931..fd9e908db7c 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -139,49 +139,53 @@ static bool maybeIncludeBorlandExtensions() */ QStringList createClangOptions(const ProjectPart::Ptr &pPart, ProjectFile::Kind fileKind) { - QStringList result; if (pPart.isNull()) - return result; + return QStringList(); + + CompilerOptionsBuilder optionsBuilder(pPart); if (verboseRunLog().isDebugEnabled()) - result << QLatin1String("-v"); + optionsBuilder.add(QLatin1String("-v")); - const bool objcExt = pPart->languageExtensions & ProjectPart::ObjectiveCExtensions; - result << CompilerOptionsBuilder::createLanguageOption(fileKind, objcExt); - result << CompilerOptionsBuilder::createOptionsForLanguage( - pPart->languageVersion, - pPart->languageExtensions, - maybeIncludeBorlandExtensions()); - result << CompilerOptionsBuilder::createDefineOptions(pPart->toolchainDefines); - result << CompilerOptionsBuilder::createDefineOptions(pPart->projectDefines); + optionsBuilder.addLanguageOption(fileKind); + optionsBuilder.addOptionsForLanguage(maybeIncludeBorlandExtensions()); + optionsBuilder.addToolchainAndProjectDefines(); static const QString resourceDir = getResourceDir(); if (!resourceDir.isEmpty()) { - result << QLatin1String("-nostdlibinc"); - result << (QLatin1String("-I") + resourceDir); - result << QLatin1String("-undef"); + optionsBuilder.add(QLatin1String("-nostdlibinc")); + optionsBuilder.add(QLatin1String("-I") + resourceDir); + optionsBuilder.add(QLatin1String("-undef")); } - result << CompilerOptionsBuilder::createHeaderPathOptions(pPart->headerPaths, isBlacklisted); + optionsBuilder.addHeaderPathOptions(isBlacklisted); // Inject header file static const QString injectedHeader = ICore::instance()->resourcePath() + QLatin1String("/cplusplus/qt%1-qobjectdefs-injected.h"); -// if (qtVersion == ProjectPart::Qt4) -// opts << QLatin1String("-include") << injectedHeader.arg(QLatin1Char('4')); - if (pPart->qtVersion == ProjectPart::Qt5) - result << QLatin1String("-include") << injectedHeader.arg(QLatin1Char('5')); - if (!pPart->projectConfigFile.isEmpty()) - result << QLatin1String("-include") << pPart->projectConfigFile; +// if (pPart->qtVersion == ProjectPart::Qt4) { +// builder.addOption(QLatin1String("-include")); +// builder.addOption(injectedHeader.arg(QLatin1Char('4'))); +// } - result << QLatin1String("-fmessage-length=0"); - result << QLatin1String("-fdiagnostics-show-note-include-stack"); - result << QLatin1String("-fmacro-backtrace-limit=0"); - result << QLatin1String("-fretain-comments-from-system-headers"); + if (pPart->qtVersion == ProjectPart::Qt5) { + optionsBuilder.add(QLatin1String("-include")); + optionsBuilder.add(injectedHeader.arg(QLatin1Char('5'))); + } + + if (!pPart->projectConfigFile.isEmpty()) { + optionsBuilder.add(QLatin1String("-include")); + optionsBuilder.add(pPart->projectConfigFile); + } + + optionsBuilder.add(QLatin1String("-fmessage-length=0")); + optionsBuilder.add(QLatin1String("-fdiagnostics-show-note-include-stack")); + optionsBuilder.add(QLatin1String("-fmacro-backtrace-limit=0")); + optionsBuilder.add(QLatin1String("-fretain-comments-from-system-headers")); // TODO: -Xclang -ferror-limit -Xclang 0 ? - return result; + return optionsBuilder.options(); } /// @return Option to speed up parsing with precompiled header diff --git a/src/plugins/cpptools/cppprojects.cpp b/src/plugins/cpptools/cppprojects.cpp index ee5ae0156ab..1a8ecacb040 100644 --- a/src/plugins/cpptools/cppprojects.cpp +++ b/src/plugins/cpptools/cppprojects.cpp @@ -501,9 +501,23 @@ void ProjectPartBuilder::createProjectPart(const QStringList &theSources, } -QStringList CompilerOptionsBuilder::createHeaderPathOptions( - const ProjectPart::HeaderPaths &headerPaths, - IsBlackListed isBlackListed, const QString &toolchainType) +CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart::Ptr &projectPart) + : m_projectPart(projectPart) +{ +} + +QStringList CompilerOptionsBuilder::options() const +{ + return m_options; +} + +void CompilerOptionsBuilder::add(const QString &option) +{ + m_options.append(option); +} + +void CompilerOptionsBuilder::addHeaderPathOptions(IsBlackListed isBlackListed, + const QString &toolchainType) { typedef ProjectPart::HeaderPath HeaderPath; const QString defaultPrefix @@ -511,7 +525,7 @@ QStringList CompilerOptionsBuilder::createHeaderPathOptions( QStringList result; - foreach (const HeaderPath &headerPath , headerPaths) { + foreach (const HeaderPath &headerPath , m_projectPart->headerPaths) { if (headerPath.path.isEmpty()) continue; @@ -533,14 +547,12 @@ QStringList CompilerOptionsBuilder::createHeaderPathOptions( result.append(prefix + headerPath.path); } - return result; + m_options.append(result); } -QStringList CompilerOptionsBuilder::createDefineOptions(const QByteArray &defines, - bool toolchainDefines, - const QString &toolchainType) +void CompilerOptionsBuilder::addToolchainAndProjectDefines(const QString &toolchainType) { - QByteArray extendedDefines = defines; + QByteArray extendedDefines = m_projectPart->toolchainDefines + m_projectPart->projectDefines; QStringList result; // In gcc headers, lots of built-ins are referenced that clang does not understand. @@ -559,17 +571,6 @@ QStringList CompilerOptionsBuilder::createDefineOptions(const QByteArray &define if (def.startsWith("#define __cplusplus")) continue; - // TODO: verify if we can pass compiler-defined macros when also passing -undef. - if (toolchainDefines) { - //### FIXME: the next 3 check shouldn't be needed: we probably don't want to get the compiler-defined defines in. - if (!def.startsWith("#define ")) - continue; - if (def.startsWith("#define _")) - continue; - if (def.startsWith("#define OBJC_NEW_PROPERTIES")) - continue; - } - // gcc 4.9 has: // #define __has_include(STR) __has_include__(STR) // #define __has_include_next(STR) __has_include_next__(STR) @@ -590,7 +591,7 @@ QStringList CompilerOptionsBuilder::createDefineOptions(const QByteArray &define result.append(arg); } - return result; + m_options.append(result); } static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt) @@ -668,24 +669,26 @@ static QStringList createLanguageOptionMsvc(ProjectFile::Kind fileKind) return opts; } -QStringList CompilerOptionsBuilder::createLanguageOption(ProjectFile::Kind fileKind, bool objcExt, - const QString &toolchainType) +void CompilerOptionsBuilder::addLanguageOption(ProjectFile::Kind fileKind, + const QString &toolchainType) { - return toolchainType == QLatin1String("msvc") ? createLanguageOptionMsvc(fileKind) - : createLanguageOptionGcc(fileKind, objcExt); + const bool objcExt = m_projectPart->languageExtensions & ProjectPart::ObjectiveCExtensions; + const QStringList options = toolchainType == QLatin1String("msvc") + ? createLanguageOptionMsvc(fileKind) + : createLanguageOptionGcc(fileKind, objcExt); + m_options.append(options); } -QStringList CompilerOptionsBuilder::createOptionsForLanguage( - ProjectPart::LanguageVersion languageVersion, - ProjectPart::LanguageExtensions languageExtensions, - bool checkForBorlandExtensions, - const QString &toolchainType) +void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtensions, + const QString &toolchainType) { QStringList opts; if (toolchainType == QLatin1String("msvc")) - return opts; - bool gnuExtensions = languageExtensions & ProjectPart::GnuExtensions; - switch (languageVersion) { + return; + + const ProjectPart::LanguageExtensions languageExtensions = m_projectPart->languageExtensions; + const bool gnuExtensions = languageExtensions & ProjectPart::GnuExtensions; + switch (m_projectPart->languageVersion) { case ProjectPart::C89: opts << (gnuExtensions ? QLatin1String("-std=gnu89") : QLatin1String("-std=c89")); break; @@ -718,5 +721,5 @@ QStringList CompilerOptionsBuilder::createOptionsForLanguage( if (checkForBorlandExtensions && (languageExtensions & ProjectPart::BorlandExtensions)) opts << QLatin1String("-fborland-extensions"); - return opts; + m_options.append(opts); } diff --git a/src/plugins/cpptools/cppprojects.h b/src/plugins/cpptools/cppprojects.h index 0851803511c..7e1162498ab 100644 --- a/src/plugins/cpptools/cppprojects.h +++ b/src/plugins/cpptools/cppprojects.h @@ -214,21 +214,24 @@ private: class CPPTOOLS_EXPORT CompilerOptionsBuilder { public: + CompilerOptionsBuilder(const ProjectPart::Ptr &projectPart); + + QStringList options() const; + + void add(const QString &option); + typedef std::function IsBlackListed; - static QStringList createHeaderPathOptions(const ProjectPart::HeaderPaths &headerPaths, - IsBlackListed isBlackListed = IsBlackListed(), - const QString &toolchainType = QLatin1String("clang")); + void addHeaderPathOptions(IsBlackListed isBlackListed = IsBlackListed(), + const QString &toolchainType = QLatin1String("clang")); + void addToolchainAndProjectDefines(const QString &toolchainType = QLatin1String("clang")); + void addLanguageOption(ProjectFile::Kind fileKind, + const QString &toolchainType = QLatin1String("clang")); + void addOptionsForLanguage(bool checkForBorlandExtensions = true, + const QString &toolchainType = QLatin1String("clang")); - static QStringList createDefineOptions(const QByteArray &defines, - bool toolchainDefines = false, - const QString &toolchainType = QLatin1String("clang")); - - static QStringList createLanguageOption(ProjectFile::Kind fileKind, bool objcExt, - const QString &toolchainType = QLatin1String("clang")); - static QStringList createOptionsForLanguage(ProjectPart::LanguageVersion languageVersion, - ProjectPart::LanguageExtensions languageExtensions, - bool checkForBorlandExtensions = true, - const QString &toolchainType = QLatin1String("clang")); +private: + ProjectPart::Ptr m_projectPart; + QStringList m_options; }; } // namespace CppTools From 2eb3bda5a85b6919bdfe7719a77d4b0877fdbec8 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 18 Jun 2015 18:08:48 +0200 Subject: [PATCH 060/113] Clang: Indicate lines from ClangBackEnd ...with a prefix. Change-Id: I6e23e00254d7b7316057514d1234cde66ab44a0d Reviewed-by: Nikolai Kosjar --- .../clangbackendipc/clangbackendipc-lib.pri | 7 +- src/libs/clangbackendipc/connectionclient.cpp | 8 +- src/libs/clangbackendipc/connectionclient.h | 4 + src/libs/clangbackendipc/lineprefixer.cpp | 61 +++++++++ src/libs/clangbackendipc/lineprefixer.h | 55 ++++++++ tests/unit/unittest/lineprefixertest.cpp | 120 ++++++++++++++++++ tests/unit/unittest/unittest.pro | 3 +- 7 files changed, 251 insertions(+), 7 deletions(-) create mode 100644 src/libs/clangbackendipc/lineprefixer.cpp create mode 100644 src/libs/clangbackendipc/lineprefixer.h create mode 100644 tests/unit/unittest/lineprefixertest.cpp diff --git a/src/libs/clangbackendipc/clangbackendipc-lib.pri b/src/libs/clangbackendipc/clangbackendipc-lib.pri index f49e3ab2197..50c5974d4e8 100644 --- a/src/libs/clangbackendipc/clangbackendipc-lib.pri +++ b/src/libs/clangbackendipc/clangbackendipc-lib.pri @@ -35,8 +35,8 @@ SOURCES += $$PWD/ipcserverinterface.cpp \ $$PWD/translationunitdoesnotexistcommand.cpp \ $$PWD/codecompletionchunk.cpp \ $$PWD/projectpartcontainer.cpp \ - $$PWD/projectpartsdonotexistcommand.cpp - + $$PWD/projectpartsdonotexistcommand.cpp \ + $$PWD/lineprefixer.cpp HEADERS += \ $$PWD/ipcserverinterface.h \ @@ -66,6 +66,7 @@ HEADERS += \ $$PWD/projectpartcontainer.h \ $$PWD/projectpartsdonotexistcommand.h \ $$PWD/container_common.h \ - $$PWD/clangbackendipc_global.h + $$PWD/clangbackendipc_global.h \ + $$PWD/lineprefixer.h contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols diff --git a/src/libs/clangbackendipc/connectionclient.cpp b/src/libs/clangbackendipc/connectionclient.cpp index 0b803b8a407..90a6d4a4718 100644 --- a/src/libs/clangbackendipc/connectionclient.cpp +++ b/src/libs/clangbackendipc/connectionclient.cpp @@ -54,7 +54,9 @@ QString connectionName() ConnectionClient::ConnectionClient(IpcClientInterface *client) : serverProxy_(client, &localSocket), - isAliveTimerResetted(false) + isAliveTimerResetted(false), + stdErrPrefixer("ClangBackEnd-StdErr: "), + stdOutPrefixer("ClangBackEnd: ") { processAliveTimer.setInterval(10000); @@ -204,12 +206,12 @@ void ConnectionClient::printLocalSocketError(QLocalSocket::LocalSocketError sock void ConnectionClient::printStandardOutput() { - qWarning() << "ClangBackEnd:" << process_->readAllStandardOutput(); + QTextStream(stdout) << stdOutPrefixer.prefix(process_->readAllStandardOutput()); } void ConnectionClient::printStandardError() { - qWarning() << "ClangBackEnd Error:" << process_->readAllStandardError(); + QTextStream(stderr) << stdErrPrefixer.prefix(process_->readAllStandardError()); } void ConnectionClient::finishProcess() diff --git a/src/libs/clangbackendipc/connectionclient.h b/src/libs/clangbackendipc/connectionclient.h index a3dd243a844..eaf4b227bf8 100644 --- a/src/libs/clangbackendipc/connectionclient.h +++ b/src/libs/clangbackendipc/connectionclient.h @@ -32,6 +32,7 @@ #define CLANGBACKEND_CONNECTIONCLIENT_H #include "ipcserverproxy.h" +#include "lineprefixer.h" #include @@ -106,6 +107,9 @@ private: QTimer processAliveTimer; QString processPath_; bool isAliveTimerResetted; + + LinePrefixer stdErrPrefixer; + LinePrefixer stdOutPrefixer; }; } // namespace ClangBackEnd diff --git a/src/libs/clangbackendipc/lineprefixer.cpp b/src/libs/clangbackendipc/lineprefixer.cpp new file mode 100644 index 00000000000..0c8c9faa5b4 --- /dev/null +++ b/src/libs/clangbackendipc/lineprefixer.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "lineprefixer.h" + +namespace ClangBackEnd { + +LinePrefixer::LinePrefixer(const QByteArray &prefix) + : m_prefix(prefix) + , m_previousIsEndingWithNewLine(true) +{} + +QByteArray LinePrefixer::prefix(const QByteArray &text) +{ + QByteArray output = text; + + if (m_previousIsEndingWithNewLine) + output.prepend(m_prefix); + + if (output.endsWith('\n')) { + m_previousIsEndingWithNewLine = true; + output.chop(1); + } else { + m_previousIsEndingWithNewLine = false; + } + + output.replace("\n", "\n" + m_prefix); + if (m_previousIsEndingWithNewLine) + output.append('\n'); + + return output; +} + +} // namespace ClangBackEnd diff --git a/src/libs/clangbackendipc/lineprefixer.h b/src/libs/clangbackendipc/lineprefixer.h new file mode 100644 index 00000000000..ae8183a0e14 --- /dev/null +++ b/src/libs/clangbackendipc/lineprefixer.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + + +#ifndef PRINTLINESWITHPREFIX_H +#define PRINTLINESWITHPREFIX_H + +#include +#include +#include + +namespace ClangBackEnd { + +class LinePrefixer +{ +public: + LinePrefixer() = delete; + LinePrefixer(const QByteArray &m_prefix); + QByteArray prefix(const QByteArray &text); + +private: + QByteArray m_prefix; + bool m_previousIsEndingWithNewLine; +}; + +} // namespace ClangBackEnd + +#endif // PRINTLINESWITHPREFIX_H diff --git a/tests/unit/unittest/lineprefixertest.cpp b/tests/unit/unittest/lineprefixertest.cpp new file mode 100644 index 00000000000..6f205e924de --- /dev/null +++ b/tests/unit/unittest/lineprefixertest.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt.io/licensing +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://www.qt.io/licensing. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include +#include + +#include +#include +#include + +namespace { + +QByteArray runPrefixer(QList inputChunks) +{ + QByteArray actualOutput; + ClangBackEnd::LinePrefixer prefixer("PREFIX "); + foreach (const QByteArray &chunk, inputChunks) + actualOutput += prefixer.prefix(chunk); + return actualOutput; +} + +TEST(LinePrefixer, OneChunkEndsWithNewline) +{ + const QList inputChunks { "hello\n" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX hello\n")); +} + +TEST(LinePrefixer, OneChunkEndsWithoutNewline) +{ + const QList inputChunks { "hello" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX hello")); +} + +TEST(LinePrefixer, OneChunkStartsWithNewline) +{ + const QList inputChunks { "\nhello" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX \n" + "PREFIX hello")); +} + +TEST(LinePrefixer, OneChunkStartsAndEndsWithNewline) +{ + const QList inputChunks { "\nhello\n" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX \n" + "PREFIX hello\n")); +} + +TEST(LinePrefixer, OneChunkEndsWithExtraNewline) +{ + const QList inputChunks { "hello\n\n" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX hello\n" + "PREFIX \n")); +} + +TEST(LinePrefixer, OneChunkEndsWithTwoExtraNewlines) +{ + const QList inputChunks { "hello\n\n\n" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX hello\n" + "PREFIX \n" + "PREFIX \n")); +} + +TEST(LinePrefixer, ChunkWithoutNewlineAndChunkWithNewline) +{ + const QList inputChunks { "hello", "\n" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX hello\n")); +} + +TEST(LinePrefixer, ChunkWithoutNewlineAndChunkWithTwoNewlines) +{ + const QList inputChunks { "hello", "\n\n" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX hello\n" + "PREFIX \n")); +} + +TEST(LinePrefixer, ChunkWithTwoNewlinesAndChunkWithoutNewline) +{ + const QList inputChunks { "\n\n", "hello" }; + ASSERT_THAT(Utf8String::fromByteArray(runPrefixer(inputChunks)), + Utf8String::fromUtf8("PREFIX \n" + "PREFIX \n" + "PREFIX hello")); +} + +} // anonymous namespace diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index a7cab75de44..8bdec64110a 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -56,7 +56,8 @@ SOURCES += main.cpp \ projecttest.cpp \ clangipcservertest.cpp \ translationunitstest.cpp \ - completionchunkstotextconvertertest.cpp + completionchunkstotextconvertertest.cpp \ + lineprefixertest.cpp HEADERS += \ gtest-qt-printing.h \ From a100e844886a51b0aede2901656e112fea91d442 Mon Sep 17 00:00:00 2001 From: Lorenz Haas Date: Sun, 21 Jun 2015 11:50:18 +0200 Subject: [PATCH 061/113] ChangeLog: Added information about refactoring actions Change-Id: I45d88cdb86dc72ba9b30e71ba0c193a736b8d532 Reviewed-by: Leena Miettinen Reviewed-by: Eike Ziller --- dist/changes-3.5.0.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dist/changes-3.5.0.md b/dist/changes-3.5.0.md index ea202cf0726..e47ebdbfa0e 100644 --- a/dist/changes-3.5.0.md +++ b/dist/changes-3.5.0.md @@ -79,8 +79,10 @@ QML Profiler C++ Support * Added separate icon for structs +* Added support for setting the access specifier of an extracted function (QTCREATORBUG-12127) * Fixed *Convert to Stack Variable* refactoring action for empty initializer lists (QTCREATORBUG-14279) +* Fixed misplaced newlines of refactoring actions (QTCREATORBUG-13872) * Fixed expanding items in class view with double-click (QTCREATORBUG-2536) * Fixed code folding issues after missing closing braces From 73ee83509f50146706e0efde065ba9436b4c778e Mon Sep 17 00:00:00 2001 From: Lorenz Haas Date: Sun, 21 Jun 2015 11:53:18 +0200 Subject: [PATCH 062/113] ChangeLog: Added new Beautifier/Uncrustify option Change-Id: I25b50387782e1e1e8469bd2ca6841c6547dc9792 Reviewed-by: Leena Miettinen Reviewed-by: Eike Ziller --- dist/changes-3.5.0.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dist/changes-3.5.0.md b/dist/changes-3.5.0.md index e47ebdbfa0e..bd15c164f29 100644 --- a/dist/changes-3.5.0.md +++ b/dist/changes-3.5.0.md @@ -118,6 +118,10 @@ Todo * Added option to excluding file patterns from parsing +Beautifier + +* Added option to format only selected lines with Uncrustify (`--frag`) + Platform Specific Windows From 6af260205a4898075b927fae2f40433c2b6fbf04 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 25 Jun 2015 11:20:20 +0200 Subject: [PATCH 063/113] Debugger: Mark two strings in the CdbEngine translatable ... after some re-wording. Change-Id: Ibc8f0c58b56689c3f1af863db3c796db07bf3670 Reviewed-by: Leena Miettinen Reviewed-by: Christian Stenger --- src/plugins/debugger/cdb/cdbengine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index bcaa80a0841..069634d81fe 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -272,9 +272,9 @@ DebuggerEngine *createCdbEngine(const DebuggerRunParameters &rp, QStringList *er if (HostOsInfo::isWindowsHost()) { if (validMode(rp.startMode)) return new CdbEngine(rp); - errors->append(QLatin1String("Internal error: Invalid start parameters passed for thee CDB engine.")); + errors->append(CdbEngine::tr("Internal error: Invalid start parameters passed for the CDB engine.")); } else { - errors->append(QString::fromLatin1("Unsupported debug mode")); + errors->append(CdbEngine::tr("Unsupported CDB host system.")); } return 0; } From d4cddfb1404955d356189f794811199ac0a3ec1b Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 26 Jun 2015 12:24:52 +0200 Subject: [PATCH 064/113] Fix RemoteLinux debugging. Make double sure we use "target extended-remote". Change-Id: I4e96d1d6a9dc5393318409503adb835afb229fd2 Reviewed-by: hjk --- src/plugins/remotelinux/remotelinuxdebugsupport.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp index f9bf98e4917..d785010dc58 100644 --- a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp +++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp @@ -102,6 +102,7 @@ DebuggerStartParameters LinuxDeviceDebugSupport::startParameters(const AbstractR } if (aspect->useCppDebugger()) { params.multiProcess = true; + aspect->setUseMultiProcess(true); // TODO: One should suffice. params.languages |= CppLanguage; QStringList args = runConfig->arguments(); if (aspect->useQmlDebugger()) From eeb77ee8275f28dca90dd47d7b2d9a3826e5d308 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 26 Jun 2015 13:57:22 +0200 Subject: [PATCH 065/113] Fix installer config for IFW 2.0 Change-Id: I6edbe34f311863019f6150bf0b2ce6400e836755 Reviewed-by: Kai Koehne --- dist/installer/ifw/config/config-linux.xml.in | 2 +- dist/installer/ifw/config/config-mac.xml.in | 2 +- dist/installer/ifw/config/config-windows.xml.in | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/installer/ifw/config/config-linux.xml.in b/dist/installer/ifw/config/config-linux.xml.in index ecc965eec00..b0a1c70f03e 100644 --- a/dist/installer/ifw/config/config-linux.xml.in +++ b/dist/installer/ifw/config/config-linux.xml.in @@ -8,7 +8,7 @@ logo.png watermark.png - QtCreatorUninstaller + QtCreatorUninstaller @homeDir@/qtcreator-{version} /opt/qtcreator-{version} diff --git a/dist/installer/ifw/config/config-mac.xml.in b/dist/installer/ifw/config/config-mac.xml.in index 72bdd23dedc..ed7a6dfdb73 100644 --- a/dist/installer/ifw/config/config-mac.xml.in +++ b/dist/installer/ifw/config/config-mac.xml.in @@ -8,7 +8,7 @@ logo.png background.png - Uninstall Qt Creator + Uninstall Qt Creator @homeDir@/Applications/Qt Creator {version} true diff --git a/dist/installer/ifw/config/config-windows.xml.in b/dist/installer/ifw/config/config-windows.xml.in index fce2db2a021..d7dada04943 100644 --- a/dist/installer/ifw/config/config-windows.xml.in +++ b/dist/installer/ifw/config/config-windows.xml.in @@ -8,7 +8,7 @@ logo.png watermark.png - QtCreatorUninst + QtCreatorUninst @rootDir@/Qt/qtcreator-{version} From 59b57518f33de9f66419541433f93295b5442ed8 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Mon, 15 Jun 2015 12:48:49 +0200 Subject: [PATCH 066/113] DebuggerRunParameters: Remove remoteSourcesDir, [remote|local]MountPoint Those variables are unused except for debugging output since more than 1 year. ed1483741e54d3c2303322cea92861ca68f272f7 Change-Id: I052fd042901401641c784eb66ab017a8f31f844e Reviewed-by: hjk --- src/plugins/debugger/debuggerengine.h | 3 --- src/plugins/debugger/debuggerplugin.cpp | 5 ----- 2 files changed, 8 deletions(-) diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 251126214fa..13ddc1c7820 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -88,13 +88,10 @@ public: QString coreFile; QString overrideStartScript; // Used in attach to core and remote debugging QString startMessage; // First status message shown. - QByteArray remoteSourcesDir; - QString remoteMountPoint; QMap sourcePathMap; QString debugInfoLocation; // Gdb "set-debug-file-directory". QStringList debugSourceLocation; // Gdb "directory" QString serverStartScript; - QString localMountDir; ProjectExplorer::IDevice::ConstPtr device; bool isSnapshot = false; // Set if created internally. diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index d531fe44467..a8d0fd4b854 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -2302,11 +2302,6 @@ static QString formatStartParameters(DebuggerRunParameters &sp) << sp.qmlServerPort << '\n'; if (!sp.remoteChannel.isEmpty()) { str << "Remote: " << sp.remoteChannel << '\n'; - if (!sp.remoteSourcesDir.isEmpty()) - str << "Remote sources: " << sp.remoteSourcesDir << '\n'; - if (!sp.remoteMountPoint.isEmpty()) - str << "Remote mount point: " << sp.remoteMountPoint - << " Local: " << sp.localMountDir << '\n'; } str << "Sysroot: " << sp.sysRoot << '\n'; str << "Debug Source Location: " << sp.debugSourceLocation.join(QLatin1Char(':')) << '\n'; From 36173e25ff767498e8bedbc67bef5d9ea880423f Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 26 Jun 2015 14:40:35 +0200 Subject: [PATCH 067/113] Doc: add UI Forms tutorial Based on the Qt Quick Controls UI Forms example. Change-Id: Iec42b7559161f980e4f482c63bfc40a22f5e77f8 Reviewed-by: Tim Jenssen --- doc/config/qtcreator-project.qdocconf | 1 + .../uiforms/CustomerModelSingleton.qml | 130 +++++ doc/examples/uiforms/CustomerTableView.qml | 68 +++ doc/examples/uiforms/History.qml | 73 +++ doc/examples/uiforms/HistoryTableView.qml | 72 +++ doc/examples/uiforms/MainForm.ui.qml | 86 +++ doc/examples/uiforms/Notes.qml | 74 +++ doc/examples/uiforms/NotesForm.ui.qml | 93 ++++ doc/examples/uiforms/Settings.qml | 86 +++ doc/examples/uiforms/SettingsForm.ui.qml | 152 ++++++ doc/examples/uiforms/deployment.pri | 27 + doc/examples/uiforms/main.cpp | 56 ++ doc/examples/uiforms/main.qml | 130 +++++ doc/examples/uiforms/qml.qrc | 14 + doc/examples/uiforms/uiforms.pro | 15 + ...ldesigner-uiforms-example-about-dialog.png | Bin 0 -> 6137 bytes .../qmldesigner-uiforms-example-main-view.png | Bin 0 -> 28577 bytes ...ldesigner-uiforms-example-settings-tab.png | Bin 0 -> 24326 bytes doc/images/qmldesigner-uiforms-example.png | Bin 0 -> 13441 bytes .../qmldesigner-uiforms-reset-height.png | Bin 0 -> 3095 bytes doc/src/overview/creator-tutorials.qdoc | 8 + .../projects/creator-projects-overview.qdoc | 2 +- doc/src/qtcreator.qdoc | 1 + .../qtquick/creator-mobile-app-tutorial.qdoc | 2 +- doc/src/qtquick/qtquick-app-tutorial.qdoc | 3 + doc/src/qtquick/qtquick-uiforms-tutorial.qdoc | 516 ++++++++++++++++++ 26 files changed, 1607 insertions(+), 2 deletions(-) create mode 100644 doc/examples/uiforms/CustomerModelSingleton.qml create mode 100644 doc/examples/uiforms/CustomerTableView.qml create mode 100644 doc/examples/uiforms/History.qml create mode 100644 doc/examples/uiforms/HistoryTableView.qml create mode 100644 doc/examples/uiforms/MainForm.ui.qml create mode 100644 doc/examples/uiforms/Notes.qml create mode 100644 doc/examples/uiforms/NotesForm.ui.qml create mode 100644 doc/examples/uiforms/Settings.qml create mode 100644 doc/examples/uiforms/SettingsForm.ui.qml create mode 100644 doc/examples/uiforms/deployment.pri create mode 100644 doc/examples/uiforms/main.cpp create mode 100644 doc/examples/uiforms/main.qml create mode 100644 doc/examples/uiforms/qml.qrc create mode 100644 doc/examples/uiforms/uiforms.pro create mode 100644 doc/images/qmldesigner-uiforms-example-about-dialog.png create mode 100644 doc/images/qmldesigner-uiforms-example-main-view.png create mode 100644 doc/images/qmldesigner-uiforms-example-settings-tab.png create mode 100644 doc/images/qmldesigner-uiforms-example.png create mode 100644 doc/images/qmldesigner-uiforms-reset-height.png create mode 100644 doc/src/qtquick/qtquick-uiforms-tutorial.qdoc diff --git a/doc/config/qtcreator-project.qdocconf b/doc/config/qtcreator-project.qdocconf index 598bd327358..fbe1054e0df 100644 --- a/doc/config/qtcreator-project.qdocconf +++ b/doc/config/qtcreator-project.qdocconf @@ -7,6 +7,7 @@ sourcedirs = $SRCDIR/src imagedirs = $SRCDIR/images $SRCDIR/templates/images outputdir = $OUTDIR exampledirs = $SRCDIR/examples +examples.fileextensions += *.qml HTML.extraimages = images/commercial.png qhp.QtCreator.extraFiles = images/commercial.png diff --git a/doc/examples/uiforms/CustomerModelSingleton.qml b/doc/examples/uiforms/CustomerModelSingleton.qml new file mode 100644 index 00000000000..1a80ea083e8 --- /dev/null +++ b/doc/examples/uiforms/CustomerModelSingleton.qml @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +pragma Singleton + +import QtQuick 2.0 + +ListModel { + property QtObject selection + ListElement { + customerId: "15881123" + firstName: "Julia" + title: "Ms." + lastName: "Jefferson" + email: "Julia@example.com" + address: "Spandia Avenue, Suite 610" + city: "Toronto" + zipCode: "92334" + phoneNumber: "0803-033330" + notes: "Very demanding customer." + history: "21.4.2014|Order|coffee~23.4.2014|Order|poster~29.4.2014|Invoice|poster 40$~05.5.2014|Overdue Notice|poster 40$" + } + + ListElement { + customerId: "29993496" + firstName: "Tim" + lastName: "Northington" + title: "Mr." + email: "Northington@example.com" + address: "North Fifth Street 55" + city: "San Jose" + zipCode: "95112" + phoneNumber: "09000-3330" + notes: "Very good customer." + history: "18.4.2014|Order|orange juice~23.4.2014|Order|chair~24.4.2014|Complaint|Chair is broken." + } + + ListElement { + customerId: "37713567" + firstName: "Daniel" + lastName: "Krumm" + title: "Mr." + email: "Krumm@example.com" + address: "Waterfront 14" + city: "Berlin" + zipCode: "12334" + phoneNumber: "0708093330" + notes: "This customer has a lot of Complaints." + history: "15.4.2014|Order|table~25.4.2014|Return|table~28.4.2014|Complaint|Table had wrong color." + } + + ListElement { + customerId: "45817387" + firstName: "Sandra" + lastName: "Booth" + title: "Ms." + email: "Sandrab@example.com" + address: "Folsom Street 23" + city: "San Francisco" + zipCode: "94103" + phoneNumber: "0103436370" + notes: "This customer is not paying." + history: "22.4.2014|Order|coffee~23.4.2014|Order|smartphone~29.4.2014|Invoice|smartphone 200$~05.5.2014|Overdue Notice|smartphone 200$" + } + + ListElement { + customerId: "588902396" + firstName: "Lora" + lastName: "Beckner" + title: "Ms." + email: "LoraB@example.com" + address: " W Wilson Apt 3" + city: "Los Angeles" + zipCode: "90086" + phoneNumber: "0903436360" + notes: "This customer usually pays late." + history: "17.4.2014|Order|soft drink~23.4.2014|Order|computer~29.4.2014|Invoice|computer 1200$~07.5.2014|Overdue Notice|computer 1200$" + } + + ListElement { + customerId: "78885693" + firstName: "Vanessa" + lastName: "Newbury" + title: "Ms." + email: "VanessaN@example.com" + address: "Madison Ave. 277" + city: "New York" + zipCode: "10016" + phoneNumber: "0503053530" + notes: "Deliveries sometime do not arrive on time." + history: "19.4.2014|Order|coffee~23.4.2014|Order|bicycle~29.4.2014|Invoice|bicycle 500$~06.5.2014|Overdue Notice|bicycle 500$" + } +} diff --git a/doc/examples/uiforms/CustomerTableView.qml b/doc/examples/uiforms/CustomerTableView.qml new file mode 100644 index 00000000000..a938fc59ebf --- /dev/null +++ b/doc/examples/uiforms/CustomerTableView.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtQuick.Controls 1.3 +import QtQuick.Layouts 1.1 + +TableView { + id: tableView + + property int columnWidth: width / 3 - 1 + Layout.minimumWidth: splitView1.width * 2 / 5 + + TableViewColumn { + role: "customerId" + title: qsTr("Customer Id") + width: tableView.columnWidth + } + + TableViewColumn { + role: "firstName" + title: qsTr("First Name") + width: tableView.columnWidth + } + + TableViewColumn { + role: "lastName" + title: qsTr("Last Name") + width: tableView.columnWidth + } +} diff --git a/doc/examples/uiforms/History.qml b/doc/examples/uiforms/History.qml new file mode 100644 index 00000000000..dfa1bfc0724 --- /dev/null +++ b/doc/examples/uiforms/History.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import my.customermodel.singleton 1.0 + +HistoryTableView { + + function readData() { + CustomerModel.selection.forEach(function (rowIndex) { + + var history = CustomerModel.get(rowIndex).history + var entries = history.split("~") + + model.clear() + + var index + for (index = 0; index < entries.length; index++) { + var entry = entries[index] + var data = entry.split("|") + model.append({ + date: data[0], + type: data[1], + text: data[2] + }) + } + }) + } + + Connections { + target: CustomerModel.selection + onSelectionChanged: readData() + } + + Component.onCompleted: readData() +} diff --git a/doc/examples/uiforms/HistoryTableView.qml b/doc/examples/uiforms/HistoryTableView.qml new file mode 100644 index 00000000000..4a33087f3f6 --- /dev/null +++ b/doc/examples/uiforms/HistoryTableView.qml @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtQuick.Controls 1.3 +import QtQuick.Layouts 1.1 + +TableView { + id: tableView + + property int columnWidth: width / 3 + + anchors.fill: parent + + TableViewColumn { + role: "date" + title: qsTr("Date") + width: tableView.columnWidth + } + + TableViewColumn { + role: "type" + title: qsTr("Type") + width: tableView.columnWidth + } + + TableViewColumn { + role: "text" + title: qsTr("Description") + width: tableView.columnWidth + } + + model: ListModel { + } +} diff --git a/doc/examples/uiforms/MainForm.ui.qml b/doc/examples/uiforms/MainForm.ui.qml new file mode 100644 index 00000000000..d0beed79871 --- /dev/null +++ b/doc/examples/uiforms/MainForm.ui.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtQuick.Controls 1.2 +import QtQuick.Layouts 1.1 + +Item { + property alias tableView1: tableView1 + + SplitView { + id: splitView1 + anchors.fill: parent + + CustomerTableView { + id: tableView1 + } + + TabView { + id: tabView1 + width: 360 + height: 300 + + Tab { + id: tab1 + source: "Settings.qml" + title: "Customer Settings" + } + + Tab { + id: tab2 + x: -3 + y: 5 + source: "Notes.qml" + title: "Customer Notes" + } + + Tab { + id: tab3 + x: -7 + y: -7 + source: "History.qml" + title: "Customer History" + } + } + } + +} + diff --git a/doc/examples/uiforms/Notes.qml b/doc/examples/uiforms/Notes.qml new file mode 100644 index 00000000000..be6a5d75ec5 --- /dev/null +++ b/doc/examples/uiforms/Notes.qml @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import my.customermodel.singleton 1.0 + +NotesForm { + id: form + + function readData() { + CustomerModel.selection.forEach(function (rowIndex) { + form.textArea1.text = CustomerModel.get(rowIndex).notes + }) + + save.enabled = true + cancel.enabled = true + form.textArea1.enabled = true + } + + function writeData() { + CustomerModel.selection.forEach(function (rowIndex) { + var data = CustomerModel.get(rowIndex) + data.notes = form.textArea1.text + CustomerModel.set(rowIndex, data) + }) + } + + cancel.onClicked: readData() + save.onClicked: writeData() + + Connections { + target: CustomerModel.selection + onSelectionChanged: form.readData() + } + + Component.onCompleted: readData() +} diff --git a/doc/examples/uiforms/NotesForm.ui.qml b/doc/examples/uiforms/NotesForm.ui.qml new file mode 100644 index 00000000000..edbde598a92 --- /dev/null +++ b/doc/examples/uiforms/NotesForm.ui.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtQuick.Layouts 1.0 +import QtQuick.Controls 1.2 + +Item { + id: content + width: 400 + height: 400 + property alias textArea1: textArea1 + property alias cancel: cancel + property alias save: save + + ColumnLayout { + id: columnLayout1 + height: 100 + anchors.right: parent.right + anchors.rightMargin: 12 + anchors.left: parent.left + anchors.leftMargin: 12 + anchors.top: parent.top + anchors.topMargin: 12 + + TextArea { + id: textArea1 + Layout.fillHeight: true + Layout.fillWidth: true + } + } + + RowLayout { + id: rowLayout1 + width: 100 + anchors.right: parent.right + anchors.rightMargin: 12 + anchors.bottom: parent.bottom + anchors.bottomMargin: 12 + + Button { + id: save + text: qsTr("Save") + Layout.fillHeight: true + Layout.fillWidth: true + } + + Button { + id: cancel + text: qsTr("Cancel") + Layout.fillHeight: true + Layout.fillWidth: true + } + } +} + diff --git a/doc/examples/uiforms/Settings.qml b/doc/examples/uiforms/Settings.qml new file mode 100644 index 00000000000..a0b70e161ea --- /dev/null +++ b/doc/examples/uiforms/Settings.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import my.customermodel.singleton 1.0 + +SettingsForm { + id: form + anchors.fill: parent + + function readData() { + + form.title.model = ["Mr.", "Ms."] + + CustomerModel.selection.forEach(function (rowIndex) { + form.firstName.text = CustomerModel.get(rowIndex).firstName + form.lastName.text = CustomerModel.get(rowIndex).lastName + form.customerId.text = CustomerModel.get(rowIndex).customerId + form.title.currentIndex = form.title.find(CustomerModel.get(rowIndex).title) + }) + + save.enabled = true + cancel.enabled = true + gridLayout1.enabled = true + } + + function writeData() { + CustomerModel.selection.forEach(function (rowIndex) { + var notes = CustomerModel.get(rowIndex).notes + CustomerModel.set(rowIndex, { + firstName: form.firstName.text, + lastName: form.lastName.text, + customerId: form.customerId.text, + title: form.title.currentText, + notes: notes + }) + }) + } + + cancel.onClicked: readData() + save.onClicked: writeData() + + Connections { + target: CustomerModel.selection + onSelectionChanged: form.readData() + } + + Component.onCompleted: readData() +} diff --git a/doc/examples/uiforms/SettingsForm.ui.qml b/doc/examples/uiforms/SettingsForm.ui.qml new file mode 100644 index 00000000000..5a86c8c7fd1 --- /dev/null +++ b/doc/examples/uiforms/SettingsForm.ui.qml @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtQuick.Controls 1.2 +import QtQuick.Layouts 1.0 + +Item { + id: content + + property alias customerId: customerId + property alias lastName: lastName + property alias firstName: firstName + property alias gridLayout1: gridLayout1 + property alias rowLayout1: rowLayout1 + + property alias save: save + property alias cancel: cancel + property alias title: title + + GridLayout { + id: gridLayout1 + rows: 4 + columns: 3 + rowSpacing: 8 + columnSpacing: 8 + anchors.right: parent.right + anchors.rightMargin: 12 + anchors.left: parent.left + anchors.leftMargin: 12 + anchors.top: parent.top + anchors.topMargin: 12 + + Label { + id: label1 + text: qsTr("Title") + } + + Label { + id: label2 + text: qsTr("First Name") + } + + Label { + id: label3 + text: qsTr("Last Name") + } + + + ComboBox { + id: title + } + + + TextField { + id: firstName + text: "" + Layout.fillHeight: true + Layout.fillWidth: true + placeholderText: qsTr("First Name") + } + + + + TextField { + id: lastName + Layout.fillHeight: true + Layout.fillWidth: true + placeholderText: qsTr("Last Name") + } + + + + + Label { + id: label4 + text: qsTr("Customer Id") + Layout.fillWidth: true + Layout.fillHeight: true + } + + TextField { + id: customerId + width: 0 + height: 0 + Layout.fillHeight: true + Layout.fillWidth: true + Layout.columnSpan: 3 + placeholderText: qsTr("Customer Id") + } + } + + RowLayout { + id: rowLayout1 + anchors.right: parent.right + anchors.rightMargin: 12 + anchors.bottom: parent.bottom + anchors.bottomMargin: 12 + + Button { + id: save + text: qsTr("Save") + Layout.fillHeight: true + Layout.fillWidth: true + } + + Button { + id: cancel + text: qsTr("Cancel") + Layout.fillHeight: true + Layout.fillWidth: true + } + } +} + diff --git a/doc/examples/uiforms/deployment.pri b/doc/examples/uiforms/deployment.pri new file mode 100644 index 00000000000..5441b63dc85 --- /dev/null +++ b/doc/examples/uiforms/deployment.pri @@ -0,0 +1,27 @@ +android-no-sdk { + target.path = /data/user/qt + export(target.path) + INSTALLS += target +} else:android { + x86 { + target.path = /libs/x86 + } else: armeabi-v7a { + target.path = /libs/armeabi-v7a + } else { + target.path = /libs/armeabi + } + export(target.path) + INSTALLS += target +} else:unix { + isEmpty(target.path) { + qnx { + target.path = /tmp/$${TARGET}/bin + } else { + target.path = /opt/$${TARGET}/bin + } + export(target.path) + } + INSTALLS += target +} + +export(INSTALLS) diff --git a/doc/examples/uiforms/main.cpp b/doc/examples/uiforms/main.cpp new file mode 100644 index 00000000000..86f9268177b --- /dev/null +++ b/doc/examples/uiforms/main.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QUrl resourceUrl(QStringLiteral("qrc:/CustomerModelSingleton.qml")); + qmlRegisterSingletonType(resourceUrl, "my.customermodel.singleton", 1, 0, "CustomerModel"); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + + return app.exec(); +} diff --git a/doc/examples/uiforms/main.qml b/doc/examples/uiforms/main.qml new file mode 100644 index 00000000000..0d6830d5e51 --- /dev/null +++ b/doc/examples/uiforms/main.qml @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.4 +import QtQuick.Controls 1.2 +import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.1 +import my.customermodel.singleton 1.0 + +ApplicationWindow { + visible: true + width: 640 + height: 480 + title: qsTr("Qt Quick UI Forms") + + menuBar: MenuBar { + Menu { + title: qsTr("&File") + MenuItem { + text: qsTr("E&xit") + onTriggered: Qt.quit(); + } + } + Menu { + title: qsTr("&Edit") + MenuItem { + action: cutAction + } + MenuItem { + action: copyAction + } + MenuItem { + action: pasteAction + } + } + Menu { + title: qsTr("&Help") + MenuItem { + text: qsTr("About...") + onTriggered: aboutDialog.open() + } + } + } + + Action { + id: copyAction + text: qsTr("&Copy") + shortcut: StandardKey.Copy + iconName: "edit-copy" + enabled: (!!activeFocusItem && !!activeFocusItem["copy"]) + onTriggered: activeFocusItem.copy() + } + + Action { + id: cutAction + text: qsTr("Cu&t") + shortcut: StandardKey.Cut + iconName: "edit-cut" + enabled: (!!activeFocusItem && !!activeFocusItem["cut"]) + onTriggered: activeFocusItem.cut() + } + + Action { + id: pasteAction + text: qsTr("&Paste") + shortcut: StandardKey.Paste + iconName: "edit-paste" + enabled: (!!activeFocusItem && !!activeFocusItem["paste"]) + onTriggered: activeFocusItem.paste() + } + + MainForm { + anchors.fill: parent + Layout.minimumWidth: 800 + Layout.minimumHeight: 480 + Layout.preferredWidth: 768 + Layout.preferredHeight: 480 + tableView1.model: CustomerModel + + Component.onCompleted: CustomerModel.selection = tableView1.selection + } + + MessageDialog { + id: aboutDialog + icon: StandardIcon.Information + title: qsTr("About") + text: "Qt Quick UI Forms" + informativeText: qsTr("This example demonstrates how to separate the " + + "implementation of an application from the UI " + + "using ui.qml files.") + } +} + diff --git a/doc/examples/uiforms/qml.qrc b/doc/examples/uiforms/qml.qrc new file mode 100644 index 00000000000..a459cec0380 --- /dev/null +++ b/doc/examples/uiforms/qml.qrc @@ -0,0 +1,14 @@ + + + main.qml + MainForm.ui.qml + CustomerModelSingleton.qml + Settings.qml + SettingsForm.ui.qml + Notes.qml + NotesForm.ui.qml + History.qml + HistoryTableView.qml + CustomerTableView.qml + + diff --git a/doc/examples/uiforms/uiforms.pro b/doc/examples/uiforms/uiforms.pro new file mode 100644 index 00000000000..d11099c2b53 --- /dev/null +++ b/doc/examples/uiforms/uiforms.pro @@ -0,0 +1,15 @@ +TEMPLATE = app + +QT += qml quick widgets + +SOURCES += main.cpp + +RESOURCES += qml.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Default rules for deployment. +include(deployment.pri) + +DISTFILES += diff --git a/doc/images/qmldesigner-uiforms-example-about-dialog.png b/doc/images/qmldesigner-uiforms-example-about-dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..0cf6e33210ca928a69464eb9b43ecdfe6f86bf6b GIT binary patch literal 6137 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 literal 0 HcmV?d00001 diff --git a/doc/images/qmldesigner-uiforms-example-main-view.png b/doc/images/qmldesigner-uiforms-example-main-view.png new file mode 100644 index 0000000000000000000000000000000000000000..099611c10fe367d7ac8de67d98ac8528539e4286 GIT binary patch literal 28577 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 VDgJcn77J+mil?ie%Q~loCIB4M=OF+9 literal 0 HcmV?d00001 diff --git a/doc/images/qmldesigner-uiforms-reset-height.png b/doc/images/qmldesigner-uiforms-reset-height.png new file mode 100644 index 0000000000000000000000000000000000000000..99d748a72db1447dfdf26ece0c73f1c3478389f2 GIT binary patch literal 3095 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 U`68vuz`(%Z>FVdQ&MBb@0LJPoM*si- literal 0 HcmV?d00001 diff --git a/doc/src/overview/creator-tutorials.qdoc b/doc/src/overview/creator-tutorials.qdoc index e14391bf8c3..26c3817aee9 100644 --- a/doc/src/overview/creator-tutorials.qdoc +++ b/doc/src/overview/creator-tutorials.qdoc @@ -51,6 +51,14 @@ Learn how to create a Qt Quick application using Qt Quick Controls for Android and iOS devices. + \li \l{Using Qt Quick UI Forms} + + Learn how to develop a Qt Quick application by using UI forms. + UI forms are split into \e .qml and \e .js files that contain the + business logic, and \e .ui.qml files that only contain the purely + declarative description of the UI. Note that some of the described + features are only available in the commercial version of \QC. + \endlist */ diff --git a/doc/src/projects/creator-projects-overview.qdoc b/doc/src/projects/creator-projects-overview.qdoc index 013243fccca..e7751703dbf 100644 --- a/doc/src/projects/creator-projects-overview.qdoc +++ b/doc/src/projects/creator-projects-overview.qdoc @@ -24,7 +24,7 @@ /*! \contentspage {Qt Creator Manual} - \previouspage creator-mobile-app-tutorial.html + \previouspage {Using Qt Quick UI Forms} \page creator-project-managing.html \nextpage creator-project-creating.html diff --git a/doc/src/qtcreator.qdoc b/doc/src/qtcreator.qdoc index 9b2c51c174c..d1917e537e6 100644 --- a/doc/src/qtcreator.qdoc +++ b/doc/src/qtcreator.qdoc @@ -139,6 +139,7 @@ \li \l{Creating a Qt Quick Application} \li \l{Creating a Qt Widget Based Application} \li \l{Creating a Mobile Application} + \li \l{Using Qt Quick UI Forms} \endlist \endlist \li \l{Managing Projects} diff --git a/doc/src/qtquick/creator-mobile-app-tutorial.qdoc b/doc/src/qtquick/creator-mobile-app-tutorial.qdoc index 56f84210f8b..27c1fc60cd5 100644 --- a/doc/src/qtquick/creator-mobile-app-tutorial.qdoc +++ b/doc/src/qtquick/creator-mobile-app-tutorial.qdoc @@ -26,7 +26,7 @@ \contentspage {Qt Creator Manual} \previouspage creator-writing-program.html \page creator-mobile-app-tutorial.html - \nextpage creator-project-managing.html + \nextpage {Using Qt Quick UI Forms} \title Creating a Mobile Application diff --git a/doc/src/qtquick/qtquick-app-tutorial.qdoc b/doc/src/qtquick/qtquick-app-tutorial.qdoc index 204ce69bdae..919eade1af7 100644 --- a/doc/src/qtquick/qtquick-app-tutorial.qdoc +++ b/doc/src/qtquick/qtquick-app-tutorial.qdoc @@ -43,6 +43,9 @@ For more information about using \QMLD, see \l{Developing Qt Quick Applications}. + For tutorials that describe using Qt Quick Controls, see + \l{Qt Quick Text Editor Guide} and \l{Qt Quick Controls - UI Forms}. + \section1 Creating the Project \list 1 diff --git a/doc/src/qtquick/qtquick-uiforms-tutorial.qdoc b/doc/src/qtquick/qtquick-uiforms-tutorial.qdoc new file mode 100644 index 00000000000..3736777ddb3 --- /dev/null +++ b/doc/src/qtquick/qtquick-uiforms-tutorial.qdoc @@ -0,0 +1,516 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qt Creator +** +** +** GNU Free Documentation License +** +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of this +** file. +** +** +****************************************************************************/ +/*! + \contentspage {Qt Creator Manual} + \previouspage creator-mobile-app-tutorial.html + \example uiforms + \nextpage creator-project-managing.html + + \title Using Qt Quick UI Forms + + \commercial + + This tutorial describes how to develop an application that uses \e ui.qml + files to separate the application logic from the UI. The tutorial uses \QMLD + to implement a simplified version of the \l{Qt Quick Controls - UI Forms} + {UI Forms example}, which provides an interface to a customer database and + is purely written in QML and JavaScript. + + \note Some of the described features are only available in the commercial + version of \QC. + + \image qmldesigner-uiforms-example.png + + \e {UI forms} consist of \e .qml and \e .js files that implement the + business logic, and corresponding \e .ui.qml files that only contain the + purely declarative description of the UI. The \e .ui.qml files should be + edited only in the \uicontrol Design mode of \QC. However, \QMLD does not + fully support all QML controls, such as the TableView, so you sometimes need + to edit UI forms also in the \uicontrol Edit mode. You can keep this to the + minimum by creating custom QML types that you edit in the \uicontrol Edit + mode. + + \section1 Creating the UI Forms Project + + \list 1 + + \li Select \uicontrol File > \uicontrol {New File or Project} > + \uicontrol Application > \uicontrol {Qt Quick Controls Application} + > \uicontrol Choose. + + \li In the \uicontrol Name field, type \b uiforms. + + \li In the \uicontrol {Create in} field, enter the path for the project + files and then click \uicontrol Next (or \uicontrol Continue on + OS X). + + \li In the \uicontrol {Minimal required Qt version} field, select + \uicontrol {Qt 5.4}, or later. + + \li Select \l{glossary-buildandrun-kit}{kits} for your project and click + \uicontrol{Next}. + + \note Kits are listed if they have been specified in + \uicontrol Tools > \uicontrol Options > \uicontrol {Build & Run} > + \uicontrol Kits (on Windows and Linux) or in \uicontrol {Qt Creator} + > \uicontrol Preferences \uicontrol {Build & Run} > \uicontrol Kits + (on OS X). + + \li Review the project settings, and click \uicontrol Finish (or + \uicontrol Done on OS X). + + \endlist + + \QC generates a default UI file, \e MainForm.ui.qml, that you can modify to + create the main view of the application. + + \section1 Creating the UI Forms Main View + + The main view of the application displays a customer list in a table view + and detailed information about the selected customer in a tab view. + + \image qmldesigner-uiforms-example-main-view.png + + To create the main view: + + \list 1 + + \li In the \uicontrol Projects view (1), double-click the + \e MainForm.ui.qml file to open it in \QMLD. + + \li In the \uicontrol Navigator (2), select the \uicontrol RowLayout and + press \key Delete to delete it. + + \li In \uicontrol Library > \uicontrol {QML Types} (3), select + \uicontrol SplitView and drag and drop it to the \uicontrol Item in + the navigator. + + \li Select the split view in the navigator, then select the + \uicontrol Layout tab in \uicontrol Properties (4), and then click + the \inlineimage qmldesigner-anchor-fill-screen.png + (\uicontrol {Fill to Parent}) button to anchor the split view to the + item. + + \li Drag and drop a \uicontrol TableView and a \uicontrol {Tab View} + from the library to the split view in the navigator. + + \li Select the \inlineimage qmldesigner-export-item-button.png + (\uicontrol Export) button in the navigator to export the table view + as a property. + + \li Right-click \uicontrol TabView to open the context menu and select + \uicontrol {Add Tab} to create a Tab element. + + \QC creates the element as a separate QML file with the name that + you enter in the dialog. By default, the element is called + \uicontrol Tab. + + \li Select the tab in the navigator and enter \b {Customer Settings} in + the \uicontrol Title field in the properties. + + \li Press \key Ctrl+C to copy the tab to the clipboard, and then press + \key Ctrl+V twice to create two more tabs that you name + \b {Customer Notes} and \b {Customer History}. \QC uses the \l Tab + type in the \e MainForm.ui.qml file. You will create separate UI + forms for the tab contents later. + + \endlist + + \section2 Editing the Table View + + \QMLD does not support adding columns to TableView types, and therefore, you + must use the code editor to add them. To keep editing the \e MainForm.ui.qml + file in the \uicontrol Edit mode to the minimum, move the TableView type to + a separate QML file called \e CustomerTableView.qml: + + \list 1 + + \li Click \uicontrol Edit to open \e MainForm.ui.qml in \uicontrol Edit + mode. + + \li To move the TableView type to a separate QML file, right-click it + and select \uicontrol Refactoring > + \uicontrol {Move Component into Separate File}. + + \li Add the code from the \l {uiforms/CustomerTableView.qml} + {CustomerTableView.qml} example file to the file that \QC creates + for you. + + \endlist + + \section1 Implementing the Application Logic for the Main View + + The new project wizard adds boilerplate code to the \e main.qml file to + create menu items and push buttons. Modify the boilerplate code by removing + obsolete code and by adding new code. You removed the push buttons from the + UI Form, so you also need to remove the corresponding code from + \e main.qml (or the application cannot be built). + + You will want to keep the dialog box and menu bar, but change their + contents, as instructed later. + + Edit the \e main.qml file in the code editor, as described in the following + sections. + + \section2 Specifying Main View Size + + The wizard creates an ApplicationWindow type and a MainForm type that + specify the application main view. Enter the application name as the + value of the \c title property. + + Clean up the MainForm code by removing the obsolete lines that call + functions when buttons are clicked: + + \badcode + MainForm { + anchors.fill: parent + button1.onClicked: messageDialog.show(qsTr("Button 1 pressed")) + button2.onClicked: messageDialog.show(qsTr("Button 2 pressed")) + } + \endcode + + Remove the \c width and \c height properties from the ApplicationWindow + type and use a Layout type in the MainForm type to set the minimum and + preferred size of the main view. + + To use the Layouts, import QtQuick Layouts: + + \quotefromfile uiforms/main.qml + \skipto QtQuick.Layouts + \printline Layouts + + Then specify the following properties for the MainForm: + + \skipto MainForm + \printuntil Layout.preferredHeight + + \section2 Creating the Table View Model + + Use a list model to display customer data in the table view. Because the + list model is accessed from several different \e .qml files, access it + through a singleton type defined in \e CustomerModelSingleton.qml and + registered in \e main.cpp. This way, you do not have to rely on the QML + context scoping rules to access the list model. + + \list 1 + + \li In the \uicontrol Projects view, right-click \uicontrol qml.qrc and + select \uicontrol {Add New} > \uicontrol Qt > + \uicontrol {QML File (Qt Quick 2)} to create the + \e CustomerModelSingleton.qml file and to add it to the project. + + \li Copy the implementation from \l{uiforms/CustomerModelSingleton.qml} + {CustomerModelSingleton.qml}. + + \li Add the following code to the MainForm in \e main.qml to access the + list model: + + \quotefromfile uiforms/main.qml + \skipto tableView1.model: CustomerModel + \printuntil tableView1.selection + + \li To register the singleton type in the \e main.cpp file, include the + Qt QML module and call the \c qmlRegisterSingletonType() function in + the initialization function: + + \quotefromfile uiforms/main.cpp + \dots + \skipto QtQml + \printuntil "CustomerModel"); + + \li To use the registered singleton type in \e main.qml, you must import + the singleton type: + + \quotefromfile uiforms/main.qml + \skipto my.customermodel.singleton + \printline 1.0 + + \endlist + + \section1 Creating Tabs + + You can use the new file wizard to create UI forms that specify tab + contents and functionality. You set the QML files as sources for the tabs + in the \e MainForm.ui.qml file and modify the corresponding UI forms in the + \uicontrol Design mode. + + \section2 Creating UI Forms for Tab Contents + + To create UI forms for the tab contents: + + \list 1 + + \li Select \uicontrol File > \uicontrol {New File or Project} > + \uicontrol Qt > \uicontrol {QtQuick UI File} > \uicontrol Choose. + + \li In the \uicontrol {Component name} field, enter \b Settings. + + \li Click \uicontrol Next. + + \li Click \uicontrol Finish to create the UI form, + \e SettingsForm.ui.qml, and a corresponding QML file, + \e Settings.qml. + + \endlist + + Create the UI form, \e NotesForm.ui.qml, and the corresponding QML file, + \e Notes.qml, for the notes tab in the same way. You will not need an + \e ui.qml file for the history tab, so you will create the QML file for it + later. + + \section2 Creating the Settings Tab + + The \uicontrol {Customer Settings} tab contains information about the + selected user. + + \image qmldesigner-uiforms-example-settings-tab.png + + To create the tab contents: + + \list 1 + + \li Double-click \e SettingsForm.ui.qml in the \uicontrol Projects + view to open it for editing in the \uicontrol Design mode. + + \li Select \uicontrol Item in the \uicontrol Navigator and enter + \b content in the \uicontrol Id field in \uicontrol Properties. + + \li In \uicontrol Library, select \uicontrol Imports > + \uicontrol {Add Import} and import Qt Quick Controls and Layouts to + make the QML types in those modules visible in the library. + + \li Drag and drop a \uicontrol {Grid Layout} from the library to the + \b content item in the navigator. + + \li Select \uicontrol Layout > \uicontrol Top, \uicontrol Left, and + \uicontrol Right buttons to anchor the grid layout to the parent. + + \li In the \uicontrol Margin fields for the anchors, set the margins + to \b 12. + + \li In \uicontrol Properties, set \uicontrol {Column spacing} and + \uicontrol {Row spacing} to \b 8, \uicontrol Columns to \b 3, and + \uicontrol Rows to \b 4. If you add more fields, add the necessary + amount of rows. + + \li Drag and drop four \uicontrol Label controls, a + \uicontrol {Combo Box}, and three \uicontrol {Text Field} controls + from the library to the navigator. + + \li Use the down arrow in the navigator to move one label down to the + position above the last text field. + + \li In the properties, change the label text for each field in the + \uicontrol Text field. You need the following labels: \b Title, + \b {First Name}, \b {Last Name}, and \b {Customer Id}. + + \li In the properties, change the placeholder text for each text field + in the \uicontrol {Placeholder text} field to be the same as the + field label. + + \li Select the customer ID text field, then select \uicontrol Layout + in properties and set \uicontrol {Column span} to 3 and check + \uicontrol {Fill width} to make the ID field span the length of + the grid layout. + + \li Drag and drop a \uicontrol {Row Layout} from the library to the + \b content item in the navigator and click on it. + + \li Reset the height of the row layout in properties. + + \image qmldesigner-uiforms-reset-height.png + + \li Select \uicontrol Layout > \uicontrol Bottom and \uicontrol Right + buttons to anchor the row layout to the parent. + + \li In the \uicontrol Margin fields for the anchors, set the margins + to \b 12. + + \li Drag and drop two \uicontrol Button controls from the library to the + row layout in the navigator. + + \li In the properties, change the button labels in the \uicontrol Text + field to \b Save and \b Cancel. + + \li Select \uicontrol Layout and > \uicontrol {Fill width} and + \uicontrol {Fill height} in properties for each button to have the + buttons fill the row layout. + + \li In the navigator, select \uicontrol Export for each field to export + the field IDs as properties. The following items should be exported, + so that they can be referred to in \e Settings.qml: + + \quotefromfile uiforms/SettingsForm.ui.qml + \skipto property + \printuntil title + + \endlist + + \section2 Creating the Notes Tab + + The \uicontrol {Customer Notes} tab contains a text area for entering notes + about the selected customer and buttons for saving or canceling the changes. + + To create the tab contents: + + \list 1 + + \li Double-click \e NotesForm.ui.qml in the \uicontrol Projects + view to open it for editing in the \uicontrol Design mode. + + \li Select \uicontrol Item in the \uicontrol Navigator and enter + \b content in the \uicontrol Id field in \uicontrol Properties. + + \li In \uicontrol Library, select \uicontrol Imports > + \uicontrol {Add Import} and import Qt Quick Controls and Layouts. + + \li Drag and drop a \uicontrol {Column Layout} from the library to the + \b content item in the navigator. + + \li Select \uicontrol Layout > \uicontrol Top, \uicontrol Left, and + \uicontrol Right buttons to anchor the grid layout to the parent + and set the margins to \b 12. + + \li Drag and drop a \uicontrol {Text Area} from the library to the + column layout. + + \li Select \uicontrol Layout and > \uicontrol {Fill width} and + \uicontrol {Fill height} in properties to have the text area fill + the column layout. + + \li Create the \uicontrol Save and \uicontrol Cancel buttons as + instructed in \l {Creating the Settings Tab}. You can also copy and + paste the row layout from SettingsForm.ui.qml. + + \li In the navigator, select \uicontrol Export for each field to export + the field IDs as properties. The following items should be exported, + so that they can be referred to in \e Notes.qml: + + \quotefromfile uiforms/NotesForm.ui.qml + \skipto property + \printuntil save + + \endlist + + \section2 Creating the History Tab + + The \uicontrol {Customer History} tab contains a table view that displays + the transactions performed by the customer. Create a custom HistoryTableView + type that you can edit in the \uicontrol Edit mode. For the history tab, you + do not need an \e ui.qml file at all. + + To create the history tab: + + \list 1 + + \li In the \uicontrol Projects view, right-click \uicontrol qml.qrc and + select \uicontrol {Add New} > \uicontrol Qt > + \uicontrol {QML File (Qt Quick 2)} to create the + \e HistoryTableView.qml file and to add it to the project. + + \li Copy the implementation from \l{uiforms/HistoryTableView.qml} + {HistoryTableView.qml}. + + \li Add the code from the example \l{uiforms/History.qml}{History.qml} + file to your \e History.qml file to access the code model. + + \endlist + + \section1 Adding Tab Functionality + + Add functions for displaying data from the customer model in the tabs. You + have already created the files that you need. You now need to copy the + implementation for the settings tab from the \l {uiforms/Settings.qml} + {Settings.qml} file and for the notes tab from the \l {uiforms/Notes.qml} + {Notes.qml} file. + + To display the tab contents in the main view, set the QML files as sources + for the tabs in the \uicontrol Design mode. Select the settings tab in the + \uicontrol Navigator and specify for example \e Settings.qml in the + \uicontrol Source field in the \uicontrol Properties view. Similarly, + specify the sources for the notes and history tabs. + + You can then remove the \e Tab.qml file that the wizard generated but that + you no longer need by selecting \uicontrol {Remove File} in the context + menu. + + \section1 Creating Menus + + The wizard adds a menu bar to the \e main.qml file that contains a + \uicontrol File menu with the \uicontrol Open and \uicontrol Exit menu + items. Keep the menu and the \uicontrol Exit menu item, and add the + \uicontrol Edit and \uicontrol Help menus with standard menu items. + + The wizard creates the following code: + + \badcode + menuBar: MenuBar { + Menu { + title: qsTr("&File") + MenuItem { + text: qsTr("&Open") + onTriggered: messageDialog.show(qsTr("Open action triggered")); + } + MenuItem { + text: qsTr("E&xit") + onTriggered: Qt.quit(); + } + } + } + \endcode + + Remove the \uicontrol Open menu item and add the following code to create + the new menus: + + \quotefromfile uiforms/main.qml + \skipto menuBar + \printuntil activeFocusItem.paste + \printuntil } + + \section1 Creating Dialogs + + \image qmldesigner-uiforms-example-about-dialog.png + + The wizard creates a message box in the \e main.qml file that you should + turn into an \uicontrol About dialog for the purpose of this example: + + \badcode + MessageDialog { + id: messageDialog + title: qsTr("May I have your attention, please?") + + function show(caption) { + messageDialog.text = caption; + messageDialog.open(); + } + \endcode + + Modify the code created by the wizard to add an icon and some text: + + \quotefromfile uiforms/main.qml + \skipto MessageDialog + \printuntil } + + Enable access to the \uicontrol About dialog from the \uicontrol Help menu + that you create next. + + \section1 Running the Application + + The application is complete and ready to be run on the desktop or deployed + to a device. To run the application, press \key {Ctrl+R}. +*/ From eb848eb89fdb17a1719cc4096386ae3f001f3b28 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 26 Jun 2015 14:12:33 +0200 Subject: [PATCH 068/113] Valgrind: Introduce Frame::filePath(). Change-Id: I40d1b7f739ea905bbcca1a388bada3e077b7c137 Reviewed-by: hjk --- src/plugins/valgrind/memcheckerrorview.cpp | 4 +- src/plugins/valgrind/memchecktool.cpp | 4 +- src/plugins/valgrind/xmlprotocol/error.cpp | 4 +- .../valgrind/xmlprotocol/errorlistmodel.cpp | 9 ++--- src/plugins/valgrind/xmlprotocol/frame.cpp | 20 +++++++--- src/plugins/valgrind/xmlprotocol/frame.h | 6 ++- .../valgrind/xmlprotocol/modelhelpers.cpp | 4 +- src/plugins/valgrind/xmlprotocol/parser.cpp | 2 +- .../valgrind/xmlprotocol/stackmodel.cpp | 6 +-- tests/auto/valgrind/memcheck/parsertests.cpp | 20 +++++----- tests/auto/valgrind/memcheck/testrunner.cpp | 40 +++++++++---------- 11 files changed, 63 insertions(+), 56 deletions(-) diff --git a/src/plugins/valgrind/memcheckerrorview.cpp b/src/plugins/valgrind/memcheckerrorview.cpp index 85d71a62e1a..05348a5a519 100644 --- a/src/plugins/valgrind/memcheckerrorview.cpp +++ b/src/plugins/valgrind/memcheckerrorview.cpp @@ -83,9 +83,9 @@ static QString makeFrameName(const Frame &frame, const QString &relativeTo, bool link = true, const QString &linkAttr = QString()) { const QString d = frame.directory(); - const QString f = frame.file(); + const QString f = frame.fileName(); const QString fn = frame.functionName(); - const QString fullPath = d + QLatin1Char('/') + f; + const QString fullPath = frame.filePath(); QString path; if (!d.isEmpty() && !f.isEmpty()) diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp index 04d4085e2e6..84f9f6b5bee 100644 --- a/src/plugins/valgrind/memchecktool.cpp +++ b/src/plugins/valgrind/memchecktool.cpp @@ -299,11 +299,11 @@ public: //find the first frame belonging to the project if (!m_projectFiles.isEmpty()) { foreach (const Frame &frame, frames) { - if (frame.directory().isEmpty() || frame.file().isEmpty()) + if (frame.directory().isEmpty() || frame.fileName().isEmpty()) continue; //filepaths can contain "..", clean them: - const QString f = QFileInfo(frame.directory() + QLatin1Char('/') + frame.file()).absoluteFilePath(); + const QString f = QFileInfo(frame.filePath()).absoluteFilePath(); if (m_projectFiles.contains(f)) return frame; } diff --git a/src/plugins/valgrind/xmlprotocol/error.cpp b/src/plugins/valgrind/xmlprotocol/error.cpp index 7ba728f8d59..5794e7dc46d 100644 --- a/src/plugins/valgrind/xmlprotocol/error.cpp +++ b/src/plugins/valgrind/xmlprotocol/error.cpp @@ -238,8 +238,8 @@ QString Error::toXml() const stream << " " << frame.functionName() << "\n"; if (!frame.directory().isEmpty()) stream << " " << frame.directory() << "\n"; - if (!frame.file().isEmpty()) - stream << " " << frame.file() << "\n"; + if (!frame.fileName().isEmpty()) + stream << " " << frame.fileName() << "\n"; if (frame.line() != -1) stream << " " << frame.line() << ""; stream << " \n"; diff --git a/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp b/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp index ba7cf71348b..6c23993097b 100644 --- a/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp +++ b/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp @@ -111,16 +111,13 @@ Frame ErrorListModel::Private::findRelevantFrame(const Error &error) const QString ErrorListModel::Private::formatAbsoluteFilePath(const Error &error) const { - const Frame f = findRelevantFrame(error); - if (!f.directory().isEmpty() && !f.file().isEmpty()) - return f.directory() + QLatin1Char('/') + f.file(); - return QString(); + return findRelevantFrame(error).filePath(); } QString ErrorListModel::Private::formatLocation(const Error &error) const { const Frame frame = findRelevantFrame(error); - const QString file = frame.file(); + const QString file = frame.fileName(); if (!frame.functionName().isEmpty()) return frame.functionName(); if (!file.isEmpty()) { @@ -185,7 +182,7 @@ QVariant ErrorListModel::Private::errorData(int row, int column, int role) const case AbsoluteFilePathRole: return formatAbsoluteFilePath(error); case FileRole: - return findRelevantFrame(error).file(); + return findRelevantFrame(error).fileName(); case LineRole: { const qint64 line = findRelevantFrame(error).line(); return line > 0 ? line : QVariant(); diff --git a/src/plugins/valgrind/xmlprotocol/frame.cpp b/src/plugins/valgrind/xmlprotocol/frame.cpp index fe916fa5995..e29ddf1ec76 100644 --- a/src/plugins/valgrind/xmlprotocol/frame.cpp +++ b/src/plugins/valgrind/xmlprotocol/frame.cpp @@ -48,7 +48,7 @@ public: return ip == other.ip && object == other.object && functionName == other.functionName - && file == other.file + && fileName == other.fileName && directory == other.directory && line == other.line; } @@ -56,7 +56,7 @@ public: quint64 ip; QString object; QString functionName; - QString file; + QString fileName; QString directory; int line; }; @@ -126,14 +126,14 @@ void Frame::setFunctionName(const QString &functionName) d->functionName = functionName; } -QString Frame::file() const +QString Frame::fileName() const { - return d->file; + return d->fileName; } -void Frame::setFile(const QString &file) +void Frame::setFileName(const QString &file) { - d->file = file; + d->fileName = file; } QString Frame::directory() const @@ -146,6 +146,14 @@ void Frame::setDirectory(const QString &directory) d->directory = directory; } +QString Frame::filePath() const +{ + QString f; + if (!directory().isEmpty()) + f.append(directory()).append(QLatin1Char('/')); + return f.append(fileName()); +} + int Frame::line() const { return d->line; diff --git a/src/plugins/valgrind/xmlprotocol/frame.h b/src/plugins/valgrind/xmlprotocol/frame.h index 697e25f2149..d184748d548 100644 --- a/src/plugins/valgrind/xmlprotocol/frame.h +++ b/src/plugins/valgrind/xmlprotocol/frame.h @@ -59,12 +59,14 @@ public: QString functionName() const; void setFunctionName(const QString &functionName); - QString file() const; - void setFile(const QString &file); + QString fileName() const; + void setFileName(const QString &fileName); QString directory() const; void setDirectory(const QString &directory); + QString filePath() const; + int line() const; void setLine(int line); diff --git a/src/plugins/valgrind/xmlprotocol/modelhelpers.cpp b/src/plugins/valgrind/xmlprotocol/modelhelpers.cpp index 3b01e69b475..754e99922f2 100644 --- a/src/plugins/valgrind/xmlprotocol/modelhelpers.cpp +++ b/src/plugins/valgrind/xmlprotocol/modelhelpers.cpp @@ -43,8 +43,8 @@ namespace XmlProtocol { QString toolTipForFrame(const Frame &frame) { QString location; - if (!frame.file().isEmpty()) { - location = frame.directory() + QLatin1Char('/') + frame.file(); + if (!frame.fileName().isEmpty()) { + location = frame.filePath(); if (frame.line() > 0) location += QLatin1Char(':') + QString::number(frame.line()); } diff --git a/src/plugins/valgrind/xmlprotocol/parser.cpp b/src/plugins/valgrind/xmlprotocol/parser.cpp index 95114578bdd..9ace7559445 100644 --- a/src/plugins/valgrind/xmlprotocol/parser.cpp +++ b/src/plugins/valgrind/xmlprotocol/parser.cpp @@ -517,7 +517,7 @@ Frame Parser::Private::parseFrame() else if (name == QLatin1String("dir")) frame.setDirectory(blockingReadElementText()); else if (name == QLatin1String("file")) - frame.setFile( blockingReadElementText()); + frame.setFileName(blockingReadElementText()); else if (name == QLatin1String("line")) frame.setLine(parseInt64(blockingReadElementText(), QLatin1String("error/frame/line"))); else if (reader.isStartElement()) diff --git a/src/plugins/valgrind/xmlprotocol/stackmodel.cpp b/src/plugins/valgrind/xmlprotocol/stackmodel.cpp index 9ae8beb48e2..5d806eca870 100644 --- a/src/plugins/valgrind/xmlprotocol/stackmodel.cpp +++ b/src/plugins/valgrind/xmlprotocol/stackmodel.cpp @@ -60,7 +60,7 @@ public: static QString makeName(const Frame &frame) { const QString d = frame.directory(); - const QString f = frame.file(); + const QString f = frame.fileName(); const QString fn = frame.functionName(); if (!fn.isEmpty()) return fn; @@ -123,7 +123,7 @@ QVariant StackModel::data(const QModelIndex &index, int role) const case DirectoryColumn: return frame.directory(); case FileColumn: - return frame.file(); + return frame.fileName(); case LineColumn: if (frame.line() > 0) return frame.line(); @@ -139,7 +139,7 @@ QVariant StackModel::data(const QModelIndex &index, int role) const case FunctionNameRole: return frame.functionName(); case FileRole: - return frame.file(); + return frame.fileName(); case DirectoryRole: return frame.directory(); case LineRole: diff --git a/tests/auto/valgrind/memcheck/parsertests.cpp b/tests/auto/valgrind/memcheck/parsertests.cpp index 61db42836dd..9a6dc218d1a 100644 --- a/tests/auto/valgrind/memcheck/parsertests.cpp +++ b/tests/auto/valgrind/memcheck/parsertests.cpp @@ -70,7 +70,7 @@ QT_END_NAMESPACE void dumpFrame(const Frame &f) { - qDebug() << f.instructionPointer() << f.directory() << f.file() << f.functionName() + qDebug() << f.instructionPointer() << f.directory() << f.fileName() << f.functionName() << f.line() << f.object(); } @@ -168,14 +168,14 @@ void ParserTests::testHelgrindSample1() frame11.setObject(QLatin1String("/usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so")); frame11.setFunctionName(QLatin1String("QMutex::lock()")); frame11.setDirectory(QLatin1String("/build/buildd/valgrind-3.6.0~svn20100212/helgrind")); - frame11.setFile(QLatin1String("hg_intercepts.c")); + frame11.setFileName(QLatin1String("hg_intercepts.c")); frame11.setLine(1988); Frame frame12; frame12.setInstructionPointer(0x72E57EE); frame12.setObject(QLatin1String("/home/frank/local/qt4-4.6.3-shared-debug/lib/libQtCore.so.4.6.3")); frame12.setFunctionName(QLatin1String("QMutexLocker::relock()")); frame12.setDirectory(QLatin1String("/home/frank/source/tarballs/qt-4.6.3-build/src/corelib/../../include/QtCore/../../src/corelib/thread")); - frame12.setFile(QLatin1String("qmutex.h")); + frame12.setFileName(QLatin1String("qmutex.h")); frame12.setLine(120); stack1.setFrames(QVector() << frame11 << frame12); @@ -186,14 +186,14 @@ void ParserTests::testHelgrindSample1() frame21.setObject(QLatin1String("/usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so")); frame21.setFunctionName(QLatin1String("QMutex::lock()")); frame21.setDirectory(QLatin1String("/build/buildd/valgrind-3.6.0~svn20100212/helgrind")); - frame21.setFile(QLatin1String("hg_intercepts.c")); + frame21.setFileName(QLatin1String("hg_intercepts.c")); frame21.setLine(1989); Frame frame22; frame22.setInstructionPointer(0x72E57EE); frame22.setObject(QLatin1String("/home/frank/local/qt4-4.6.3-shared-debug/lib/libQtCore.so.4.6.3")); frame22.setFunctionName(QLatin1String("QMutexLocker::relock()")); frame22.setDirectory(QLatin1String("/home/frank/source/tarballs/qt-4.6.3-build/src/corelib/../../include/QtCore/../../src/corelib/thread")); - frame22.setFile(QLatin1String("qmutex.h")); + frame22.setFileName(QLatin1String("qmutex.h")); frame22.setLine(121); stack2.setFrames(QVector() << frame21 << frame22); @@ -204,14 +204,14 @@ void ParserTests::testHelgrindSample1() frame31.setObject(QLatin1String("/usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so")); frame31.setFunctionName(QLatin1String("QMutex::lock()")); frame31.setDirectory(QLatin1String("/build/buildd/valgrind-3.6.0~svn20100212/helgrind")); - frame31.setFile(QLatin1String("hg_intercepts.c")); + frame31.setFileName(QLatin1String("hg_intercepts.c")); frame31.setLine(1990); Frame frame32; frame32.setInstructionPointer(0x72E57EE); frame32.setObject(QLatin1String("/home/frank/local/qt4-4.6.3-shared-debug/lib/libQtCore.so.4.6.3")); frame32.setFunctionName(QLatin1String("QMutexLocker::relock()")); frame32.setDirectory(QLatin1String("/home/frank/source/tarballs/qt-4.6.3-build/src/corelib/../../include/QtCore/../../src/corelib/thread")); - frame32.setFile(QLatin1String("qmutex.h")); + frame32.setFileName(QLatin1String("qmutex.h")); frame32.setLine(122); stack3.setFrames(QVector() << frame31 << frame32); @@ -260,7 +260,7 @@ void ParserTests::testMemcheckSample1() f1.setObject(QLatin1String("/usr/lib/libQtGui.so.4.7.0")); f1.setFunctionName(QLatin1String("QFrame::frameStyle() const")); f1.setDirectory(QLatin1String("/build/buildd/qt4-x11-4.7.0/src/gui/widgets")); - f1.setFile(QLatin1String("qframe.cpp")); + f1.setFileName(QLatin1String("qframe.cpp")); f1.setLine(252); Frame f2; f2.setInstructionPointer(0x118F2AF7); @@ -270,13 +270,13 @@ void ParserTests::testMemcheckSample1() f3.setObject(QLatin1String("/usr/lib/libQtGui.so.4.7.0")); f3.setFunctionName(QLatin1String("QWidget::event(QEvent*)")); f3.setDirectory(QLatin1String("/build/buildd/qt4-x11-4.7.0/src/gui/kernel")); - f3.setFile(QLatin1String("qwidget.cpp")); + f3.setFileName(QLatin1String("qwidget.cpp")); f3.setLine(8273); Frame f4; f4.setInstructionPointer(0x6A2B6EB); f4.setObject(QLatin1String("/usr/lib/libQtGui.so.4.7.0")); f4.setDirectory(QLatin1String("/build/buildd/qt4-x11-4.7.0/src/gui/kernel")); - f4.setFile(QLatin1String("qapplication.cpp")); + f4.setFileName(QLatin1String("qapplication.cpp")); f4.setFunctionName(QLatin1String("QApplicationPrivate::notify_helper(QObject*, QEvent*)")); f4.setLine(4396); Stack s1; diff --git a/tests/auto/valgrind/memcheck/testrunner.cpp b/tests/auto/valgrind/memcheck/testrunner.cpp index 32c48cf426a..cf11e6bfed5 100644 --- a/tests/auto/valgrind/memcheck/testrunner.cpp +++ b/tests/auto/valgrind/memcheck/testrunner.cpp @@ -180,7 +180,7 @@ void TestRunner::testLeak1() QCOMPARE(frame.line(), 5 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDirForApp("leak1")); } } @@ -214,7 +214,7 @@ void TestRunner::testLeak2() QCOMPARE(frame.line(), 7 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDirForApp("leak2")); } else { QCOMPARE(frame.functionName(), QLatin1String("(below main)")); @@ -252,7 +252,7 @@ void TestRunner::testLeak3() QCOMPARE(frame.line(), 7 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDirForApp("leak3")); } else { QCOMPARE(frame.functionName(), QLatin1String("(below main)")); @@ -293,7 +293,7 @@ void TestRunner::testLeak4() QCOMPARE(frame.line(), 6 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } { @@ -302,7 +302,7 @@ void TestRunner::testLeak4() QCOMPARE(frame.line(), 14 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -332,7 +332,7 @@ void TestRunner::testLeak4() QCOMPARE(frame.line(), 14 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -361,7 +361,7 @@ void TestRunner::uninit1() QCOMPARE(frame.line(), 4 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } //BEGIN second stack @@ -375,7 +375,7 @@ void TestRunner::uninit1() QCOMPARE(frame.line(), 2 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -406,7 +406,7 @@ void TestRunner::uninit2() QCOMPARE(frame.line(), 4 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } //BEGIN second stack @@ -420,7 +420,7 @@ void TestRunner::uninit2() QCOMPARE(frame.line(), 2 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -439,7 +439,7 @@ void TestRunner::uninit2() QCOMPARE(frame.line(), 4 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -470,7 +470,7 @@ void TestRunner::uninit3() QCOMPARE(frame.line(), 4 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } //BEGIN second stack @@ -484,7 +484,7 @@ void TestRunner::uninit3() QCOMPARE(frame.line(), 2 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -503,7 +503,7 @@ void TestRunner::uninit3() QCOMPARE(frame.line(), 4 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -562,7 +562,7 @@ void TestRunner::syscall() QCOMPARE(frame.line(), 2 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -595,7 +595,7 @@ void TestRunner::free1() QCOMPARE(frame.line(), 7 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -615,7 +615,7 @@ void TestRunner::free1() QCOMPARE(frame.line(), 6 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -649,7 +649,7 @@ void TestRunner::free2() QCOMPARE(frame.line(), 6 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -673,7 +673,7 @@ void TestRunner::free2() QCOMPARE(frame.line(), 5 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } @@ -733,7 +733,7 @@ void TestRunner::overlap() QCOMPARE(frame.line(), 6 + HEADER_LENGTH); QCOMPARE(frame.object(), binary); - QCOMPARE(frame.file(), QLatin1String("main.cpp")); + QCOMPARE(frame.fileName(), QLatin1String("main.cpp")); QCOMPARE(QDir::cleanPath(frame.directory()), srcDir); } } From f84169b51ebd02ddaff8d207e647e3d51853f2ba Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 26 Jun 2015 15:38:24 +0200 Subject: [PATCH 069/113] Doc: update the Qt Quick Application tutorial To match the changes in the application templates and the Qt Quick Designer UI. Use the \example command to create an HTML of the example QML file. Change-Id: I4da7d5f3f14ae7a1e9597204cb9dbcd54c4127cd Reviewed-by: Tim Jenssen --- doc/examples/transitions/main.qml | 37 +++++-- doc/examples/transitions/states.png | Bin 3400 -> 0 bytes doc/examples/transitions/states.svg | 93 ++++++++++++++++++ .../qmldesigner-tutorial-design-mode.png | Bin 106183 -> 28779 bytes doc/images/qmldesigner-tutorial-page.png | Bin 20942 -> 6643 bytes doc/images/qmldesigner-tutorial-project.png | Bin 101706 -> 23673 bytes .../qmldesigner-tutorial-topleftrect.png | Bin 111316 -> 23840 bytes doc/images/qmldesigner-tutorial-user-icon.png | Bin 93107 -> 23325 bytes doc/images/qmldesigner-tutorial.png | Bin 5881 -> 5014 bytes doc/src/overview/creator-tutorials.qdoc | 2 +- doc/src/qtquick/qtquick-app-tutorial.qdoc | 80 +++++++-------- doc/src/widgets/qtdesigner-app-tutorial.qdoc | 2 +- 12 files changed, 158 insertions(+), 56 deletions(-) delete mode 100644 doc/examples/transitions/states.png create mode 100644 doc/examples/transitions/states.svg diff --git a/doc/examples/transitions/main.qml b/doc/examples/transitions/main.qml index 8769546257d..c4ccfe0c5eb 100644 --- a/doc/examples/transitions/main.qml +++ b/doc/examples/transitions/main.qml @@ -1,24 +1,41 @@ -import QtQuick 2.1 -import QtQuick.Window 2.1 +import QtQuick 2.5 +import QtQuick.Controls 1.4 -Window { +ApplicationWindow { id: page visible: true width: 360 height: 360 color: "#343434" + title: qsTr("Transitions") + + menuBar: MenuBar { + Menu { + title: qsTr("File") + MenuItem { + text: qsTr("&Open") + onTriggered: console.log("Open action triggered"); + } + MenuItem { + text: qsTr("Exit") + onTriggered: Qt.quit(); + } + } + } Image { id: icon x: 10 y: 20 - source: "states.png" + source: "states.svg" } Rectangle { id: topLeftRect - width: 64 - height: 64 + x: 10 + y: 20 + width: 44 + height: 44 color: "#00000000" radius: 6 opacity: 1 @@ -37,8 +54,8 @@ Window { Rectangle { id: middleRightRect - width: 64 - height: 64 + width: 44 + height: 44 color: "#00000000" radius: 6 anchors.right: parent.right @@ -55,8 +72,8 @@ Window { Rectangle { id: bottomLeftRect - width: 64 - height: 64 + width: 44 + height: 44 color: "#00000000" radius: 6 border.width: 1 diff --git a/doc/examples/transitions/states.png b/doc/examples/transitions/states.png deleted file mode 100644 index 707d5c4e85d82959740b243a8a36d5071c277299..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3400 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 diff --git a/doc/examples/transitions/states.svg b/doc/examples/transitions/states.svg new file mode 100644 index 00000000000..566acfada01 --- /dev/null +++ b/doc/examples/transitions/states.svg @@ -0,0 +1,93 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/doc/images/qmldesigner-tutorial-design-mode.png b/doc/images/qmldesigner-tutorial-design-mode.png index 1cd9f9e7756b127f01eaf1f09f590252b41ca4a4..0733593ae4e3b7d87c3d740709fdcc0e2454cb15 100644 GIT binary patch literal 28779 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ð9l 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 YJeSfWw{w}d? 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 diff --git a/doc/images/qmldesigner-tutorial-page.png b/doc/images/qmldesigner-tutorial-page.png index 8148788ae1795dd36a5986fa9deaae9d08239b60..7adecac391f1fa03119ff71f9fc4f2f9ad6389db 100644 GIT binary patch literal 6643 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 Hl+XkKjCJ9E literal 20942 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

    9J8^fiTm&@}7my{p4 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 diff --git a/doc/images/qmldesigner-tutorial-project.png b/doc/images/qmldesigner-tutorial-project.png index f03bb501dd0d9bfc1fcea173239c2a67dd2a15a9..5f395a639e0ae300cda88c969794a210784d0925 100644 GIT binary patch literal 23673 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⪻%mo+c@W2OD=@BO6m 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 literal 101706 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⋘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�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 -a*Ufa~A*c+#_>;x<%rmCAL|A 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 diff --git a/doc/images/qmldesigner-tutorial-topleftrect.png b/doc/images/qmldesigner-tutorial-topleftrect.png index d4b90ec9be7ae8ca7830d98444ddcaf4c8f40bb5..853602ddcf036ea4df2e13be521b218a7337af30 100644 GIT binary patch literal 23840 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 N@O1TaS?83{1OR_NX3PKp literal 111316 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ⅆO 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

    THfj6b${RPh^m?OqJN(CDaBoP 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 diff --git a/doc/images/qmldesigner-tutorial-user-icon.png b/doc/images/qmldesigner-tutorial-user-icon.png index cf678c7b4fba60b9161caa30366305d3791d2d00..972b73c79fd7cc6e7547d7d0484d0634f8097ffc 100644 GIT binary patch literal 23325 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 literal 93107 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 z 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 ASO5S3 diff --git a/doc/images/qmldesigner-tutorial.png b/doc/images/qmldesigner-tutorial.png index a4afab78681b2c9c5025d9ca8f6201599a21cf7d..af60348eb17fd0ecb0976aab39087c7daf625f39 100644 GIT binary patch literal 5014 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 diff --git a/doc/src/overview/creator-tutorials.qdoc b/doc/src/overview/creator-tutorials.qdoc index 26c3817aee9..3ad43aa4fbc 100644 --- a/doc/src/overview/creator-tutorials.qdoc +++ b/doc/src/overview/creator-tutorials.qdoc @@ -26,7 +26,7 @@ \contentspage {Qt Creator Manual} \previouspage creator-build-example-application.html \page creator-tutorials.html - \nextpage creator-qml-application.html + \nextpage {Creating a Qt Quick Application} \title Tutorials diff --git a/doc/src/qtquick/qtquick-app-tutorial.qdoc b/doc/src/qtquick/qtquick-app-tutorial.qdoc index 919eade1af7..f6c24cfe7da 100644 --- a/doc/src/qtquick/qtquick-app-tutorial.qdoc +++ b/doc/src/qtquick/qtquick-app-tutorial.qdoc @@ -25,7 +25,7 @@ /*! \contentspage {Qt Creator Manual} \previouspage creator-tutorials.html - \page creator-qml-application.html + \example transitions \nextpage creator-writing-program.html \title Creating a Qt Quick Application @@ -53,20 +53,19 @@ \li Select \uicontrol{File > New File or Project > Application > Qt Quick Application > Choose}. - \li In the \uicontrol{Name} field, type \b {Transitions}. + \li In the \uicontrol{Name} field, type \e {Transitions}. \li In the \uicontrol {Create in} field, enter the path for the project files. For example, \c {C:\Qt\examples}, and then click \uicontrol{Next} (on Windows and Linux) or \uicontrol Continue (on OS X). - \li In the \uicontrol {Qt Quick component set} field, select - \uicontrol {Qt Quick 2.1}. + \li In the \uicontrol {Minimal required Qt version} field, select the Qt + version to develop with. - \note This selection determines the set of files that the wizard + \note This page determines the set of files that the wizard generates and their contents. The instructions in this tutorial - might not apply if you select some other component set, such as Qt - Quick 2.4. The wizard indicates which Qt version each component set - requires at minimum. + might not apply if you select the \uicontrol {With .ui.qml file} + check box. \li Select \l{glossary-buildandrun-kit}{kits} for running and building your project, and then click \uicontrol{Next}. @@ -96,7 +95,7 @@ The main view of the application displays a Qt logo in the top left corner of the screen and two empty rectangles. - To use the states.png image in your application, you must copy it to the + To use the states.svg image in your application, you must copy it to the project directory (same subdirectory as the QML file) from the examples directory in the Qt installation directory. For example: \c {C:\Qt\Examples\Qt-5.4\declarative\animation\states}. The image appears @@ -112,10 +111,10 @@ \image qmldesigner-tutorial-design-mode.png "Transitions project in Design Mode" - \li In the \uicontrol Navigator, select \uicontrol MouseArea and - \uicontrol Text and press \key Delete to delete them. + \li In the \uicontrol Navigator, select \uicontrol Label and press + \key Delete to delete it. - \li Select \uicontrol Window to edit its properties. + \li Select \uicontrol ApplicationWindow to edit its properties. \image qmldesigner-tutorial-page.png "Page properties" @@ -124,12 +123,17 @@ \li In the \uicontrol Id field, enter \e page, to be able to reference the window from other places. + \li In the \uicontrol Title field, type \e Transitions. + + \li In the \uicontrol Size field, set \uicontrol W and \uicontrol H + to \e 330. + \li In the \uicontrol Color field, set the window background color - to #343434. + to \e #343434. \endlist - \li In \uicontrol Library > \uicontrol Resources, select states.png and + \li In \uicontrol Library > \uicontrol Resources, select states.svg and drag and drop it to the canvas. \image qmldesigner-tutorial-user-icon.png "Image properties" @@ -138,15 +142,17 @@ \li In the \uicontrol Id field, enter \e icon. - \li In the \uicontrol Position field, set \uicontrol X to 10 and \uicontrol Y to 20. + \li In the \uicontrol Position field, set \uicontrol X to \e 10 and + \uicontrol Y to \e 20. \endlist \li Right-click the resource file, qml.qrc, in the \uicontrol Projects - view, and select \uicontrol {Open in Editor} to add states.png to + view, and select \uicontrol {Open in Editor} to add states.svg to the resource file for deployment. - \li Click \uicontrol Add and select states.png. + \li Click \uicontrol Add > \uicontrol {Add File} and select + \e states.svg. \li In the \uicontrol Design mode, \uicontrol Library view, \uicontrol {QML Types} tab, select \uicontrol Rectangle, @@ -158,26 +164,21 @@ \li In the \uicontrol Id field, enter \e topLeftRect. - \li In the \uicontrol Size field, set \uicontrol W and \uicontrol H to 64, for the - rectangle size to match the image size. + \li In the \uicontrol Size field, set \uicontrol W and \uicontrol H + to \e 44, for the rectangle size to match the image size. \li In the \uicontrol Color field, click the \inlineimage qmldesigner-transparent-button.png (\uicontrol Transparent) button to make the rectangle transparent. - \li In the \uicontrol Border field, set the border color to #808080. + \li In the \uicontrol Border field, set the border color to + \e #808080. \li In the \uicontrol Rectangle group, \uicontrol Border field, set the border - width to 1. + width to \e 1. - \note If the \uicontrol Border field does not appear after you set the - border color, try setting the border color to solid by clicking - the - \inlineimage qmldesigner-solid-color-button.png - (\uicontrol {Solid Color}) button. - - \li In the \uicontrol Radius field, select 6 to create rounded corners for - the rectangle. + \li In the \uicontrol Radius field, select \e 6 to create rounded + corners for the rectangle. \li Click \uicontrol {Layout}, and then click the top and left anchor buttons to anchor the rectangle to the top left corner of the @@ -185,8 +186,8 @@ \image qmldesigner-tutorial-topleftrect-layout.png "Layout tab" - \li In the \uicontrol Margin field, select 20 for the top anchor and 10 - for the left anchor. + \li In the \uicontrol Margin field, select \e 20 for the top anchor + and \e 10 for the left anchor. \endlist @@ -238,8 +239,8 @@ then the right anchor button to anchor the rectangle to the middle right margin of the screen. - \li In the \uicontrol Margin field, select 10 for the right anchor and 0 - for the vertical center anchor. + \li In the \uicontrol Margin field, select \e 10 for the right + anchor and \e 0 for the vertical center anchor. \li In the code editor, add a pointer to a clicked expression to the mouse area. The following expression sets the state to @@ -260,8 +261,8 @@ \li In \uicontrol {Layout}, select the bottom and left anchor buttons to anchor the rectangle to the bottom left margin of the screen. - \li In the \uicontrol Margin field, select 20 for the bottom anchor and 10 - for the left anchor. + \li In the \uicontrol Margin field, select \e 20 for the bottom + anchor and \e 10 for the left anchor. \li In the code editor, add a pointer to a clicked expression to the mouse area. The following expression sets the state to @@ -373,13 +374,4 @@ \endlist Click the rectangles to view the animated transitions. - - \section1 Example Code - - When you have completed the steps, the main.qml file should look as follows: - - \quotefromfile transitions/main.qml - \skipto Window { - \printuntil /^\}/ - */ diff --git a/doc/src/widgets/qtdesigner-app-tutorial.qdoc b/doc/src/widgets/qtdesigner-app-tutorial.qdoc index f15590829c4..6bf53205e67 100644 --- a/doc/src/widgets/qtdesigner-app-tutorial.qdoc +++ b/doc/src/widgets/qtdesigner-app-tutorial.qdoc @@ -24,7 +24,7 @@ /*! \contentspage {Qt Creator Manual} - \previouspage creator-qml-application.html + \previouspage {Creating a Qt Quick Application} \page creator-writing-program.html \nextpage creator-mobile-app-tutorial.html From 1538dca81aca4f82afef72340d91efc967face5b Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 26 Jun 2015 13:06:08 +0200 Subject: [PATCH 070/113] Debugger: Continue DebuggerStartParameter cleanup - Move sysRoot, debuggerCommand, targetAbi to DebuggerRunParameters, they are always the one coming from the kit. - Move projectSource{Directory,Files} to DebuggerRunParameters, they are alway coming from the runConfiguration's project - Pass RunConfiguration always as separate parameter, that's what related code does. Change-Id: I9965a052237af53fa2d170701bc88b552cab12ed Reviewed-by: Joerg Bornemann Reviewed-by: Christian Kandeler --- src/plugins/android/androiddebugsupport.cpp | 16 +---- src/plugins/android/androidrunner.cpp | 2 +- .../baremetal/baremetalruncontrolfactory.cpp | 30 +++------ src/plugins/debugger/debuggerengine.h | 13 ++++ src/plugins/debugger/debuggerplugin.cpp | 7 +-- src/plugins/debugger/debuggerruncontrol.cpp | 47 +++++++------- src/plugins/debugger/debuggerruncontrol.h | 4 +- .../debugger/debuggerstartparameters.h | 63 +++++-------------- .../debugger/gdb/remotegdbserveradapter.cpp | 6 +- src/plugins/ios/iosdebugsupport.cpp | 25 ++------ src/plugins/qnx/qnxattachdebugsupport.cpp | 7 +-- src/plugins/qnx/qnxruncontrolfactory.cpp | 26 +------- .../remotelinux/remotelinuxdebugsupport.cpp | 27 ++------ .../remotelinuxruncontrolfactory.cpp | 5 +- src/plugins/valgrind/memcheckengine.cpp | 28 +-------- src/plugins/winrt/winrtdebugsupport.cpp | 9 +-- 16 files changed, 90 insertions(+), 225 deletions(-) diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp index 0dfe144ea81..d4911d4f160 100644 --- a/src/plugins/android/androiddebugsupport.cpp +++ b/src/plugins/android/androiddebugsupport.cpp @@ -89,17 +89,10 @@ RunControl *AndroidDebugSupport::createDebugRunControl(AndroidRunConfiguration * params.startMode = AttachToRemoteServer; params.displayName = AndroidManager::packageName(target); params.remoteSetupNeeded = true; - params.runConfiguration = runConfig; - DebuggerRunConfigurationAspect *aspect - = runConfig->extraAspect(); + auto aspect = runConfig->extraAspect(); if (aspect->useCppDebugger()) { - params.languages |= CppLanguage; Kit *kit = target->kit(); - params.sysRoot = SysRootKitInformation::sysRoot(kit).toString(); - params.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString(); - if (ToolChain *tc = ToolChainKitInformation::toolChain(kit)) - params.toolChainAbi = tc->targetAbi(); params.executable = target->activeBuildConfiguration()->buildDirectory().toString() + QLatin1String("/app_process"); params.skipExecutableValidation = true; params.remoteChannel = runConfig->remoteChannel(); @@ -108,25 +101,20 @@ RunControl *AndroidDebugSupport::createDebugRunControl(AndroidRunConfiguration * params.solibSearchPath.append(qtSoPaths(version)); } if (aspect->useQmlDebugger()) { - params.languages |= QmlLanguage; QTcpServer server; QTC_ASSERT(server.listen(QHostAddress::LocalHost) || server.listen(QHostAddress::LocalHostIPv6), return 0); params.qmlServerAddress = server.serverAddress().toString(); - params.remoteSetupNeeded = true; //TODO: Not sure if these are the right paths. - params.projectSourceDirectory = target->project()->projectDirectory().toString(); Kit *kit = target->kit(); QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit); if (version) { const QString qmlQtDir = version->versionInfo().value(QLatin1String("QT_INSTALL_QML")); params.additionalSearchDirectories = QStringList(qmlQtDir); } - params.projectSourceFiles = target->project()->files(Project::ExcludeGeneratedFiles); - params.projectBuildDirectory = target->activeBuildConfiguration()->buildDirectory().toString(); } - DebuggerRunControl * const debuggerRunControl = createDebuggerRunControl(params, errorMessage); + DebuggerRunControl * const debuggerRunControl = createDebuggerRunControl(params, runConfig, errorMessage); new AndroidDebugSupport(runConfig, debuggerRunControl); return debuggerRunControl; } diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp index 6409db30f87..c525440c0f4 100644 --- a/src/plugins/android/androidrunner.cpp +++ b/src/plugins/android/androidrunner.cpp @@ -543,7 +543,7 @@ void AndroidRunner::logcatProcess(const QByteArray &text, QByteArray &buffer, bo QString pidString = QString::number(m_processPID); foreach (const QByteArray &msg, lines) { - const QString line = QString::fromUtf8(msg).trimmed(); + const QString line = QString::fromUtf8(msg).trimmed() + QLatin1Char('\n'); if (!line.contains(pidString)) continue; if (m_logCatRegExp.exactMatch(line)) { diff --git a/src/plugins/baremetal/baremetalruncontrolfactory.cpp b/src/plugins/baremetal/baremetalruncontrolfactory.cpp index e2dea237d49..7dd2fb7edfe 100644 --- a/src/plugins/baremetal/baremetalruncontrolfactory.cpp +++ b/src/plugins/baremetal/baremetalruncontrolfactory.cpp @@ -119,32 +119,19 @@ RunControl *BareMetalRunControlFactory::create( DebuggerStartParameters sp; - if (const ToolChain *tc = ToolChainKitInformation::toolChain(kit)) - sp.toolChainAbi = tc->targetAbi(); - - if (const Project *project = target->project()) { - sp.projectSourceDirectory = project->projectDirectory().toString(); - sp.projectSourceFiles = project->files(Project::ExcludeGeneratedFiles); - - if (const BuildConfiguration *bc = target->activeBuildConfiguration()) { - sp.projectBuildDirectory = bc->buildDirectory().toString(); - if (const BuildStepList *bsl = bc->stepList(BareMetalGdbCommandsDeployStep::stepId())) { - foreach (const BuildStep *bs, bsl->steps()) { - const auto ds = qobject_cast(bs); - if (ds) { - if (!sp.commandsAfterConnect.endsWith("\n")) - sp.commandsAfterConnect.append("\n"); - sp.commandsAfterConnect.append(ds->gdbCommands().toLatin1()); - } + if (const BuildConfiguration *bc = target->activeBuildConfiguration()) { + if (const BuildStepList *bsl = bc->stepList(BareMetalGdbCommandsDeployStep::stepId())) { + foreach (const BuildStep *bs, bsl->steps()) { + if (auto ds = qobject_cast(bs)) { + if (!sp.commandsAfterConnect.endsWith("\n")) + sp.commandsAfterConnect.append("\n"); + sp.commandsAfterConnect.append(ds->gdbCommands().toLatin1()); } } } } sp.executable = bin; - sp.sysRoot = SysRootKitInformation::sysRoot(kit).toString(); - sp.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString(); - sp.languages |= CppLanguage; sp.processArgs = rc->arguments(); sp.startMode = AttachToRemoteServer; sp.displayName = rc->displayName(); @@ -156,8 +143,7 @@ RunControl *BareMetalRunControlFactory::create( if (p->startupMode() == GdbServerProvider::StartupOnNetwork) sp.remoteSetupNeeded = true; - sp.runConfiguration = rc; - DebuggerRunControl *runControl = createDebuggerRunControl(sp, errorMessage); + DebuggerRunControl *runControl = createDebuggerRunControl(sp, rc, errorMessage); if (runControl && sp.remoteSetupNeeded) { const auto debugSupport = new BareMetalDebugSupport(dev, runControl); Q_UNUSED(debugSupport); diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 13ddc1c7820..4a09e07a0a9 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -85,6 +85,14 @@ class DebuggerRunParameters : public DebuggerStartParameters public: DebuggerRunParameters() {} + DebuggerEngineType masterEngineType = NoEngineType; + DebuggerEngineType cppEngineType = NoEngineType; + + DebuggerLanguages languages = AnyLanguage; + bool breakOnMain = false; + bool multiProcess = false; // Whether to set detach-on-fork off. + + QString debuggerCommand; QString coreFile; QString overrideStartScript; // Used in attach to core and remote debugging QString startMessage; // First status message shown. @@ -93,7 +101,12 @@ public: QStringList debugSourceLocation; // Gdb "directory" QString serverStartScript; ProjectExplorer::IDevice::ConstPtr device; + QString sysRoot; bool isSnapshot = false; // Set if created internally. + ProjectExplorer::Abi toolChainAbi; + + QString projectSourceDirectory; + QStringList projectSourceFiles; // Used by AttachCrashedExternal. QString crashParameter; diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index a8d0fd4b854..261bbfb2a84 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -2290,19 +2290,14 @@ static QString formatStartParameters(DebuggerRunParameters &sp) str << "PID: " << sp.attachPID << ' ' << sp.crashParameter << '\n'; if (!sp.projectSourceDirectory.isEmpty()) { str << "Project: " << QDir::toNativeSeparators(sp.projectSourceDirectory); - if (!sp.projectBuildDirectory.isEmpty()) - str << " (built: " << QDir::toNativeSeparators(sp.projectBuildDirectory) - << ')'; - str << '\n'; str << "Addtional Search Directories:" << sp.additionalSearchDirectories.join(QLatin1Char(' ')) << '\n'; } if (!sp.qmlServerAddress.isEmpty()) str << "QML server: " << sp.qmlServerAddress << ':' << sp.qmlServerPort << '\n'; - if (!sp.remoteChannel.isEmpty()) { + if (!sp.remoteChannel.isEmpty()) str << "Remote: " << sp.remoteChannel << '\n'; - } str << "Sysroot: " << sp.sysRoot << '\n'; str << "Debug Source Location: " << sp.debugSourceLocation.join(QLatin1Char(':')) << '\n'; return rc; diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index 3181c6570df..36f7b1b3267 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -295,7 +295,7 @@ public: // detectable pieces, construct an Engine and a RunControl. void initialize(const DebuggerStartParameters &sp); void enrich(const RunConfiguration *runConfig, const Kit *kit); - void createRunControl(RunMode runMode = DebugRunMode); + void createRunControl(RunMode runMode); QString fullError() const { return m_errors.join(QLatin1Char('\n')); } // Result. @@ -326,9 +326,6 @@ void DebuggerRunControlCreator::enrich(const RunConfiguration *runConfig, const if (!m_runConfig) m_runConfig = runConfig; - if (!m_runConfig) - m_runConfig = m_rp.runConfiguration; - // Extract as much as possible from available RunConfiguration. if (auto localRc = qobject_cast(m_runConfig)) { m_rp.executable = localRc->executable(); @@ -398,17 +395,22 @@ void DebuggerRunControlCreator::enrich(const RunConfiguration *runConfig, const } if (m_runConfig) { - auto envAspect = m_runConfig->extraAspect(); - if (envAspect) + if (auto envAspect = m_runConfig->extraAspect()) m_rp.environment = envAspect->environment(); } - if (m_runConfig) - m_debuggerAspect = m_runConfig->extraAspect(); + if (ToolChain *tc = ToolChainKitInformation::toolChain(m_kit)) + m_rp.toolChainAbi = tc->targetAbi(); if (m_target) m_project = m_target->project(); + if (m_project && m_rp.projectSourceDirectory.isEmpty()) + m_rp.projectSourceDirectory = m_project->projectDirectory().toString(); + + if (m_project && m_rp.projectSourceFiles.isEmpty()) + m_rp.projectSourceFiles = m_project->files(Project::ExcludeGeneratedFiles); + // validate debugger if C++ debugging is enabled if (m_rp.languages & CppLanguage) { const QList tasks = DebuggerKitInformation::validateDebugger(m_kit); @@ -422,22 +424,15 @@ void DebuggerRunControlCreator::enrich(const RunConfiguration *runConfig, const m_rp.cppEngineType = DebuggerKitInformation::engineType(m_kit); m_rp.sysRoot = SysRootKitInformation::sysRoot(m_kit).toString(); m_rp.debuggerCommand = DebuggerKitInformation::debuggerCommand(m_kit).toString(); - - if (auto toolChain = ToolChainKitInformation::toolChain(m_kit)) { - m_rp.toolChainAbi = toolChain->targetAbi(); - } - - if (m_target) { - if (const BuildConfiguration *buildConfig = m_target->activeBuildConfiguration()) - m_rp.projectBuildDirectory = buildConfig->buildDirectory().toString(); - } + m_rp.device = DeviceKitInformation::device(m_kit); if (m_project) { m_rp.projectSourceDirectory = m_project->projectDirectory().toString(); m_rp.projectSourceFiles = m_project->files(Project::ExcludeGeneratedFiles); } - m_rp.device = DeviceKitInformation::device(m_kit); + if (m_runConfig) + m_debuggerAspect = m_runConfig->extraAspect(); if (m_debuggerAspect) { m_rp.multiProcess = m_debuggerAspect->useMultiProcess(); @@ -446,6 +441,7 @@ void DebuggerRunControlCreator::enrich(const RunConfiguration *runConfig, const m_rp.languages |= CppLanguage; if (m_debuggerAspect->useQmlDebugger()) { + m_rp.languages |= QmlLanguage; if (m_rp.device && m_rp.device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) { QTcpServer server; const bool canListen = server.listen(QHostAddress::LocalHost) @@ -456,7 +452,6 @@ void DebuggerRunControlCreator::enrich(const RunConfiguration *runConfig, const } m_rp.qmlServerAddress = server.serverAddress().toString(); m_rp.qmlServerPort = server.serverPort(); - m_rp.languages |= QmlLanguage; // Makes sure that all bindings go through the JavaScript engine, so that // breakpoints are actually hit! @@ -495,6 +490,7 @@ void DebuggerRunControlCreator::enrich(const RunConfiguration *runConfig, const if (m_rp.masterEngineType == NoEngineType && m_debuggerAspect) { const bool useCppDebugger = m_debuggerAspect->useCppDebugger() && (m_rp.languages & CppLanguage); const bool useQmlDebugger = m_debuggerAspect->useQmlDebugger() && (m_rp.languages & QmlLanguage); + if (useQmlDebugger) { if (useCppDebugger) m_rp.masterEngineType = QmlCppEngineType; @@ -619,7 +615,7 @@ DebuggerRunControl *createAndScheduleRun(const DebuggerRunParameters &rp, const DebuggerRunControlCreator creator; creator.m_rp = rp; creator.enrich(0, kit); - creator.createRunControl(); + creator.createRunControl(DebugRunMode); if (!creator.m_runControl) { ProjectExplorerPlugin::showRunErrorMessage(creator.fullError()); return 0; @@ -634,12 +630,15 @@ DebuggerRunControl *createAndScheduleRun(const DebuggerRunParameters &rp, const /** * Main entry point for target plugins. */ -DebuggerRunControl *createDebuggerRunControl(const DebuggerStartParameters &sp, QString *errorMessage) +DebuggerRunControl *createDebuggerRunControl(const DebuggerStartParameters &sp, + RunConfiguration *runConfig, + QString *errorMessage, + RunMode runMode) { DebuggerRunControlCreator creator; creator.initialize(sp); - creator.enrich(sp.runConfiguration, 0); - creator.createRunControl(); + creator.enrich(runConfig, 0); + creator.createRunControl(runMode); if (errorMessage) *errorMessage = creator.fullError(); if (!creator.m_runControl) { @@ -658,7 +657,7 @@ bool fillParametersFromRunConfiguration(DebuggerStartParameters *sp, const RunCo DebuggerRunControlCreator creator; creator.initialize(*sp); creator.enrich(runConfig, 0); - creator.createRunControl(); + creator.createRunControl(DebugRunMode); if (errorMessage) *errorMessage = creator.fullError(); *sp = creator.m_rp; diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h index 0fb933811ec..479c545e37b 100644 --- a/src/plugins/debugger/debuggerruncontrol.h +++ b/src/plugins/debugger/debuggerruncontrol.h @@ -48,7 +48,9 @@ class DebuggerRunControlCreator; } DEBUGGER_EXPORT DebuggerRunControl *createDebuggerRunControl(const DebuggerStartParameters &sp, - QString *errorMessage); + ProjectExplorer::RunConfiguration *runConfig, + QString *errorMessage, + ProjectExplorer::RunMode runMode = ProjectExplorer::DebugRunMode); DEBUGGER_EXPORT bool fillParametersFromRunConfiguration(DebuggerStartParameters *sp, const ProjectExplorer::RunConfiguration *runConfig, diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h index b36b10e8437..4ab295396a6 100644 --- a/src/plugins/debugger/debuggerstartparameters.h +++ b/src/plugins/debugger/debuggerstartparameters.h @@ -72,78 +72,49 @@ public: class DEBUGGER_EXPORT DebuggerStartParameters { public: - DebuggerStartParameters() - : masterEngineType(NoEngineType), - cppEngineType(NoEngineType), - runConfiguration(0), - attachPID(-1), - useTerminal(false), - breakOnMain(false), - continueAfterAttach(false), - multiProcess(false), - languages(AnyLanguage), - qmlServerAddress(QLatin1String("127.0.0.1")), - qmlServerPort(Constants::QML_DEFAULT_DEBUG_SERVER_PORT), - remoteSetupNeeded(false), - useContinueInsteadOfRun(false), - startMode(NoStartMode), - closeMode(KillAtClose), - useCtrlCStub(false), - skipExecutableValidation(false) - {} + DebuggerStartParameters() {} - DebuggerEngineType masterEngineType; - DebuggerEngineType cppEngineType; - QString sysRoot; - QString deviceSymbolsRoot; - QString debuggerCommand; - ProjectExplorer::Abi toolChainAbi; - QPointer runConfiguration; + DebuggerStartMode startMode = NoStartMode; + DebuggerCloseMode closeMode = KillAtClose; - QString platform; QString executable; QString displayName; // Used in the Snapshots view. QString processArgs; Utils::Environment environment; QString workingDirectory; - qint64 attachPID; - bool useTerminal; - bool breakOnMain; - bool continueAfterAttach; - bool multiProcess; - DebuggerLanguages languages; + qint64 attachPID = InvalidPid; + QStringList solibSearchPath; + bool useTerminal = false; // Used by Qml debugging. QString qmlServerAddress; quint16 qmlServerPort; - QString projectSourceDirectory; - QStringList additionalSearchDirectories; - QString projectBuildDirectory; - QStringList projectSourceFiles; - // Used by remote debugging. + // Used by general remote debugging. QString remoteChannel; QSsh::SshConnectionParameters connParams; - bool remoteSetupNeeded; + bool remoteSetupNeeded = false; // Used by baremetal plugin QByteArray commandsForReset; // commands used for resetting the inferior - bool useContinueInsteadOfRun; // if connected to a hw debugger run is not possible but continue is used + bool useContinueInsteadOfRun = false; // if connected to a hw debugger run is not possible but continue is used QByteArray commandsAfterConnect; // additional commands to post after connection to debug target // Used by Valgrind QVector expectedSignals; - QStringList solibSearchPath; - DebuggerStartMode startMode; - DebuggerCloseMode closeMode; - // For QNX debugging QString remoteExecutable; - bool useCtrlCStub; + bool useCtrlCStub = false; // Used by Android to avoid false positives on warnOnRelease - bool skipExecutableValidation; + bool skipExecutableValidation = false; + QStringList additionalSearchDirectories; + + // Used by iOS. + QString platform; + QString deviceSymbolsRoot; + bool continueAfterAttach = false; }; } // namespace Debugger diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp index 9f1bed9d6a0..617f087791c 100644 --- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp +++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp @@ -58,11 +58,11 @@ namespace Internal { // /////////////////////////////////////////////////////////////////////// -GdbRemoteServerEngine::GdbRemoteServerEngine(const DebuggerRunParameters &startParameters) - : GdbEngine(startParameters), m_startAttempted(false) +GdbRemoteServerEngine::GdbRemoteServerEngine(const DebuggerRunParameters &runParameters) + : GdbEngine(runParameters), m_startAttempted(false) { if (HostOsInfo::isWindowsHost()) - m_gdbProc.setUseCtrlCStub(startParameters.useCtrlCStub); // This is only set for QNX/BlackBerry + m_gdbProc.setUseCtrlCStub(runParameters.useCtrlCStub); // This is only set for QNX/BlackBerry connect(&m_uploadProc, static_cast(&QProcess::error), this, &GdbRemoteServerEngine::uploadProcError); diff --git a/src/plugins/ios/iosdebugsupport.cpp b/src/plugins/ios/iosdebugsupport.cpp index 00708c64fd4..d6c2ebab011 100644 --- a/src/plugins/ios/iosdebugsupport.cpp +++ b/src/plugins/ios/iosdebugsupport.cpp @@ -77,8 +77,6 @@ RunControl *IosDebugSupport::createDebugRunControl(IosRunConfiguration *runConfi IDevice::ConstPtr device = DeviceKitInformation::device(target->kit()); if (device.isNull()) return 0; - QmakeProject *project = static_cast(target->project()); - Kit *kit = target->kit(); DebuggerStartParameters params; if (device->type() == Core::Id(Ios::Constants::IOS_DEVICE_TYPE)) { @@ -116,20 +114,12 @@ RunControl *IosDebugSupport::createDebugRunControl(IosRunConfiguration *runConfi } params.displayName = runConfig->applicationName(); params.remoteSetupNeeded = true; - if (!params.breakOnMain) - params.continueAfterAttach = true; - params.runConfiguration = runConfig; + params.continueAfterAttach = true; - DebuggerRunConfigurationAspect *aspect - = runConfig->extraAspect(); + auto aspect = runConfig->extraAspect(); bool cppDebug = aspect->useCppDebugger(); bool qmlDebug = aspect->useQmlDebugger(); if (cppDebug) { - params.languages |= CppLanguage; - params.sysRoot = SysRootKitInformation::sysRoot(kit).toString(); - params.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString(); - if (ToolChain *tc = ToolChainKitInformation::toolChain(kit)) - params.toolChainAbi = tc->targetAbi(); params.executable = runConfig->localExecutable().toString(); params.remoteChannel = QLatin1String("connect://localhost:0"); @@ -161,16 +151,11 @@ RunControl *IosDebugSupport::createDebugRunControl(IosRunConfiguration *runConfi ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT); } } - if (qmlDebug) { - params.languages |= QmlLanguage; - params.projectSourceDirectory = project->projectDirectory().toString(); - params.projectSourceFiles = project->files(QmakeProject::ExcludeGeneratedFiles); - params.projectBuildDirectory = project->rootQmakeProjectNode()->buildDir(); - if (!cppDebug) - params.startMode = AttachToRemoteServer; + if (qmlDebug && !cppDebug) { + params.startMode = AttachToRemoteServer; } - DebuggerRunControl * const debuggerRunControl = createDebuggerRunControl(params, errorMessage); + DebuggerRunControl *debuggerRunControl = createDebuggerRunControl(params, runConfig, errorMessage); if (debuggerRunControl) new IosDebugSupport(runConfig, debuggerRunControl, cppDebug, qmlDebug); return debuggerRunControl; diff --git a/src/plugins/qnx/qnxattachdebugsupport.cpp b/src/plugins/qnx/qnxattachdebugsupport.cpp index 65f62f4e60d..dac8912da41 100644 --- a/src/plugins/qnx/qnxattachdebugsupport.cpp +++ b/src/plugins/qnx/qnxattachdebugsupport.cpp @@ -116,15 +116,10 @@ void QnxAttachDebugSupport::attachToProcess() sp.attachPID = m_process.pid; sp.startMode = Debugger::AttachToRemoteServer; sp.closeMode = Debugger::DetachAtClose; - sp.masterEngineType = Debugger::GdbEngineType; sp.connParams.port = m_pdebugPort; sp.remoteChannel = m_device->sshParameters().host + QLatin1Char(':') + QString::number(m_pdebugPort); sp.displayName = tr("Remote: \"%1:%2\" - Process %3").arg(sp.connParams.host).arg(m_pdebugPort).arg(m_process.pid); - sp.debuggerCommand = Debugger::DebuggerKitInformation::debuggerCommand(m_kit).toString(); - sp.projectSourceDirectory = m_projectSourceDirectory; sp.executable = m_localExecutablePath; - if (ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(m_kit)) - sp.toolChainAbi = tc->targetAbi(); sp.useCtrlCStub = true; QnxQtVersion *qtVersion = dynamic_cast(QtSupport::QtKitInformation::qtVersion(m_kit)); @@ -132,7 +127,7 @@ void QnxAttachDebugSupport::attachToProcess() sp.solibSearchPath = QnxUtils::searchPaths(qtVersion); QString errorMessage; - Debugger::DebuggerRunControl * const runControl = Debugger::createDebuggerRunControl(sp, &errorMessage); + Debugger::DebuggerRunControl *runControl = Debugger::createDebuggerRunControl(sp, 0, &errorMessage); if (!errorMessage.isEmpty()) { handleError(errorMessage); stopPDebug(); diff --git a/src/plugins/qnx/qnxruncontrolfactory.cpp b/src/plugins/qnx/qnxruncontrolfactory.cpp index 9a08cc545d6..2e943e0a1ba 100644 --- a/src/plugins/qnx/qnxruncontrolfactory.cpp +++ b/src/plugins/qnx/qnxruncontrolfactory.cpp @@ -73,14 +73,7 @@ static DebuggerStartParameters createDebuggerStartParameters(QnxRunConfiguration return params; params.startMode = AttachToRemoteServer; - params.debuggerCommand = DebuggerKitInformation::debuggerCommand(k).toString(); - params.sysRoot = SysRootKitInformation::sysRoot(k).toString(); params.useCtrlCStub = true; - params.runConfiguration = runConfig; - - if (ToolChain *tc = ToolChainKitInformation::toolChain(k)) - params.toolChainAbi = tc->targetAbi(); - params.executable = runConfig->localExecutableFilePath(); params.remoteExecutable = runConfig->remoteExecutableFilePath(); params.remoteChannel = device->sshParameters().host + QLatin1String(":-1"); @@ -89,26 +82,13 @@ static DebuggerStartParameters createDebuggerStartParameters(QnxRunConfiguration params.closeMode = KillAtClose; params.processArgs = runConfig->arguments().join(QLatin1Char(' ')); - DebuggerRunConfigurationAspect *aspect - = runConfig->extraAspect(); + auto aspect = runConfig->extraAspect(); if (aspect->useQmlDebugger()) { - params.languages |= QmlLanguage; params.qmlServerAddress = device->sshParameters().host; params.qmlServerPort = 0; // QML port is handed out later } - if (aspect->useCppDebugger()) - params.languages |= CppLanguage; - - if (const Project *project = runConfig->target()->project()) { - params.projectSourceDirectory = project->projectDirectory().toString(); - if (const BuildConfiguration *buildConfig = runConfig->target()->activeBuildConfiguration()) - params.projectBuildDirectory = buildConfig->buildDirectory().toString(); - params.projectSourceFiles = project->files(Project::ExcludeGeneratedFiles); - } - - QnxQtVersion *qtVersion = - dynamic_cast(QtSupport::QtKitInformation::qtVersion(k)); + auto qtVersion = dynamic_cast(QtSupport::QtKitInformation::qtVersion(k)); if (qtVersion) params.solibSearchPath = QnxUtils::searchPaths(qtVersion); @@ -178,7 +158,7 @@ RunControl *QnxRunControlFactory::create(RunConfiguration *runConfig, RunMode mo return new QnxRunControl(rc); case DebugRunMode: { const DebuggerStartParameters params = createDebuggerStartParameters(rc); - DebuggerRunControl * const runControl = createDebuggerRunControl(params, errorMessage); + DebuggerRunControl *runControl = createDebuggerRunControl(params, runConfig, errorMessage); if (!runControl) return 0; diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp index d785010dc58..769b0a2929e 100644 --- a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp +++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp @@ -87,42 +87,25 @@ DebuggerStartParameters LinuxDeviceDebugSupport::startParameters(const AbstractR const IDevice::ConstPtr device = DeviceKitInformation::device(k); QTC_ASSERT(device, return params); + params.startMode = AttachToRemoteServer; params.closeMode = KillAndExitMonitorAtClose; - params.sysRoot = SysRootKitInformation::sysRoot(k).toString(); - params.debuggerCommand = DebuggerKitInformation::debuggerCommand(k).toString(); - if (ToolChain *tc = ToolChainKitInformation::toolChain(k)) - params.toolChainAbi = tc->targetAbi(); + params.remoteSetupNeeded = true; + params.displayName = runConfig->displayName(); - DebuggerRunConfigurationAspect *aspect - = runConfig->extraAspect(); + auto aspect = runConfig->extraAspect(); if (aspect->useQmlDebugger()) { - params.languages |= QmlLanguage; params.qmlServerAddress = device->sshParameters().host; params.qmlServerPort = 0; // port is selected later on } if (aspect->useCppDebugger()) { - params.multiProcess = true; - aspect->setUseMultiProcess(true); // TODO: One should suffice. - params.languages |= CppLanguage; + aspect->setUseMultiProcess(true); QStringList args = runConfig->arguments(); if (aspect->useQmlDebugger()) args.prepend(QString::fromLatin1("-qmljsdebugger=port:%qml_port%,block")); params.processArgs = Utils::QtcProcess::joinArgs(args, Utils::OsTypeLinux); - params.startMode = AttachToRemoteServer; params.executable = runConfig->localExecutableFilePath(); params.remoteChannel = device->sshParameters().host + QLatin1String(":-1"); params.remoteExecutable = runConfig->remoteExecutableFilePath(); - } else { - params.startMode = AttachToRemoteServer; - } - params.remoteSetupNeeded = true; - params.displayName = runConfig->displayName(); - - if (const Project *project = target->project()) { - params.projectSourceDirectory = project->projectDirectory().toString(); - if (const BuildConfiguration *buildConfig = target->activeBuildConfiguration()) - params.projectBuildDirectory = buildConfig->buildDirectory().toString(); - params.projectSourceFiles = project->files(Project::ExcludeGeneratedFiles); } return params; diff --git a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp index 69a94478dc0..e933918b7d7 100644 --- a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp +++ b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp @@ -104,10 +104,7 @@ RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Ru } DebuggerStartParameters params = LinuxDeviceDebugSupport::startParameters(rc); - if (mode == DebugRunModeWithBreakOnMain) - params.breakOnMain = true; - params.runConfiguration = runConfig; - DebuggerRunControl * const runControl = createDebuggerRunControl(params, errorMessage); + DebuggerRunControl * const runControl = createDebuggerRunControl(params, runConfig, errorMessage); if (!runControl) return 0; LinuxDeviceDebugSupport * const debugSupport = diff --git a/src/plugins/valgrind/memcheckengine.cpp b/src/plugins/valgrind/memcheckengine.cpp index c11d307b0da..158006f724b 100644 --- a/src/plugins/valgrind/memcheckengine.cpp +++ b/src/plugins/valgrind/memcheckengine.cpp @@ -156,39 +156,17 @@ void MemcheckWithGdbRunControl::startDebugger() { const qint64 valgrindPid = runner()->valgrindProcess()->pid(); const AnalyzerStartParameters &mySp = startParameters(); + Debugger::DebuggerStartParameters sp; - - RunConfiguration *rc = runConfiguration(); - const Target *target = rc->target(); - QTC_ASSERT(target, return); - - const Kit *kit = target->kit(); - QTC_ASSERT(kit, return); - - if (const ToolChain *tc = ToolChainKitInformation::toolChain(kit)) - sp.toolChainAbi = tc->targetAbi(); - - if (const Project *project = target->project()) { - sp.projectSourceDirectory = project->projectDirectory().toString(); - sp.projectSourceFiles = project->files(Project::ExcludeGeneratedFiles); - - if (const BuildConfiguration *bc = target->activeBuildConfiguration()) - sp.projectBuildDirectory = bc->buildDirectory().toString(); - } - sp.executable = mySp.debuggee; - sp.sysRoot = SysRootKitInformation::sysRoot(kit).toString(); - sp.debuggerCommand = Debugger::DebuggerKitInformation::debuggerCommand(kit).toString(); - sp.languages |= Debugger::CppLanguage; sp.startMode = Debugger::AttachToRemoteServer; sp.displayName = QString::fromLatin1("VGdb %1").arg(valgrindPid); sp.remoteChannel = QString::fromLatin1("| vgdb --pid=%1").arg(valgrindPid); sp.useContinueInsteadOfRun = true; - sp.expectedSignals << "SIGTRAP"; - sp.runConfiguration = rc; + sp.expectedSignals.append("SIGTRAP"); QString errorMessage; - RunControl *gdbRunControl = Debugger::createDebuggerRunControl(sp, &errorMessage); + RunControl *gdbRunControl = Debugger::createDebuggerRunControl(sp, runConfiguration(), &errorMessage); QTC_ASSERT(gdbRunControl, return); connect(gdbRunControl, &RunControl::finished, gdbRunControl, &RunControl::deleteLater); diff --git a/src/plugins/winrt/winrtdebugsupport.cpp b/src/plugins/winrt/winrtdebugsupport.cpp index c81b94a4542..85b56b91c44 100644 --- a/src/plugins/winrt/winrtdebugsupport.cpp +++ b/src/plugins/winrt/winrtdebugsupport.cpp @@ -75,14 +75,8 @@ RunControl *WinRtDebugSupport::createDebugRunControl(WinRtRunConfiguration *runC using namespace Debugger; DebuggerStartParameters params; params.startMode = AttachExternal; - params.languages |= CppLanguage; - params.breakOnMain = mode == DebugRunModeWithBreakOnMain; // The first Thread needs to be resumed manually. params.commandsAfterConnect = "~0 m"; - Kit *kit = runConfig->target()->kit(); - params.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString(); - if (ToolChain *tc = ToolChainKitInformation::toolChain(kit)) - params.toolChainAbi = tc->targetAbi(); QFileInfo debuggerHelper(QCoreApplication::applicationDirPath() + QLatin1String("/winrtdebughelper.exe")); @@ -125,9 +119,8 @@ RunControl *WinRtDebugSupport::createDebugRunControl(WinRtRunConfiguration *runC return 0; } server.close(); - params.runConfiguration = runConfig; Debugger::DebuggerRunControl *debugRunControl - = createDebuggerRunControl(params, errorMessage); + = createDebuggerRunControl(params, runConfig, errorMessage, mode); runner->setRunControl(debugRunControl); new WinRtDebugSupport(debugRunControl, runner); return debugRunControl; From c209eb9fbbbdac177dca0ec5cfb3454fcb8fc262 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Mon, 15 Jun 2015 12:39:19 +0200 Subject: [PATCH 071/113] AnalyerRunControl: Don't store the runconfiguration There is no gurantee that the runconfiguration stays alive after creation. Change-Id: Ia520cc33a89ec56ad6a9b928f841eb4551732ae0 Reviewed-by: hjk --- src/plugins/analyzerbase/analyzerruncontrol.cpp | 3 +-- src/plugins/analyzerbase/analyzerruncontrol.h | 5 ----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/plugins/analyzerbase/analyzerruncontrol.cpp b/src/plugins/analyzerbase/analyzerruncontrol.cpp index 6748220743e..48f6103bccc 100644 --- a/src/plugins/analyzerbase/analyzerruncontrol.cpp +++ b/src/plugins/analyzerbase/analyzerruncontrol.cpp @@ -53,7 +53,6 @@ AnalyzerRunControl::AnalyzerRunControl(const AnalyzerStartParameters &sp, { setIcon(QLatin1String(":/images/analyzer_start_small.png")); - m_runConfig = runConfiguration; m_sp = sp; connect(this, &AnalyzerRunControl::finished, @@ -101,7 +100,7 @@ bool AnalyzerRunControl::isRunning() const QString AnalyzerRunControl::displayName() const { - return m_runConfig ? m_runConfig->displayName() : m_sp.displayName; + return m_sp.displayName; } } // namespace Analyzer diff --git a/src/plugins/analyzerbase/analyzerruncontrol.h b/src/plugins/analyzerbase/analyzerruncontrol.h index 8b294c4c85f..8d436af6e88 100644 --- a/src/plugins/analyzerbase/analyzerruncontrol.h +++ b/src/plugins/analyzerbase/analyzerruncontrol.h @@ -68,9 +68,6 @@ public: virtual void pause() {} virtual void unpause() {} - /// The active run configuration for this engine, might be zero. - ProjectExplorer::RunConfiguration *runConfiguration() const { return m_runConfig; } - /// The start parameters for this engine. const AnalyzerStartParameters &startParameters() const { return m_sp; } @@ -98,8 +95,6 @@ signals: private: bool supportsReRunning() const { return false; } - - ProjectExplorer::RunConfiguration *m_runConfig; AnalyzerStartParameters m_sp; }; } // namespace Analyzer From 859f1eed96a5b7fa13ecfb72b583799095adc524 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Sat, 27 Jun 2015 16:12:27 +0200 Subject: [PATCH 072/113] SSH: Use better member name and fix wrong comment. No functional changes. Change-Id: I94f30dc1d48b5a1508d704530bfa6d8af18de89e Reviewed-by: Christian Kandeler --- src/libs/ssh/sshincomingpacket.cpp | 8 ++++---- src/libs/ssh/sshincomingpacket_p.h | 4 ++-- src/libs/ssh/sshkeyexchange.cpp | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libs/ssh/sshincomingpacket.cpp b/src/libs/ssh/sshincomingpacket.cpp index 1742c335a4a..998661719f0 100644 --- a/src/libs/ssh/sshincomingpacket.cpp +++ b/src/libs/ssh/sshincomingpacket.cpp @@ -176,13 +176,13 @@ static void getHostKeySpecificReplyData(SshKeyExchangeReply &replyData, quint32 offset = 0; if (hostKeyAlgo == SshCapabilities::PubKeyDss || hostKeyAlgo == SshCapabilities::PubKeyRsa) { // DSS: p and q, RSA: e and n - replyData.parameters << SshPacketParser::asBigInt(input, &offset); - replyData.parameters << SshPacketParser::asBigInt(input, &offset); + replyData.hostKeyParameters << SshPacketParser::asBigInt(input, &offset); + replyData.hostKeyParameters << SshPacketParser::asBigInt(input, &offset); // g and y if (hostKeyAlgo == SshCapabilities::PubKeyDss) { - replyData.parameters << SshPacketParser::asBigInt(input, &offset); - replyData.parameters << SshPacketParser::asBigInt(input, &offset); + replyData.hostKeyParameters << SshPacketParser::asBigInt(input, &offset); + replyData.hostKeyParameters << SshPacketParser::asBigInt(input, &offset); } } else { QSSH_ASSERT_AND_RETURN(hostKeyAlgo == SshCapabilities::PubKeyEcdsa); diff --git a/src/libs/ssh/sshincomingpacket_p.h b/src/libs/ssh/sshincomingpacket_p.h index d2d17eed6ed..0b8cb183032 100644 --- a/src/libs/ssh/sshincomingpacket_p.h +++ b/src/libs/ssh/sshincomingpacket_p.h @@ -62,10 +62,10 @@ struct SshKeyExchangeInit struct SshKeyExchangeReply { QByteArray k_s; - QList parameters; // DSS: p, q, g, y. RSA: e, n. + QList hostKeyParameters; // DSS: p, q, g, y. RSA: e, n. + QByteArray q; // For ECDSA host keys only. Botan::BigInt f; // For DH only. QByteArray q_s; // For ECDH only. - QByteArray q; // For ECDH only. QByteArray signatureBlob; }; diff --git a/src/libs/ssh/sshkeyexchange.cpp b/src/libs/ssh/sshkeyexchange.cpp index 62071e4fc70..2853ea76d72 100644 --- a/src/libs/ssh/sshkeyexchange.cpp +++ b/src/libs/ssh/sshkeyexchange.cpp @@ -203,14 +203,14 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, QScopedPointer sigKey; if (m_serverHostKeyAlgo == SshCapabilities::PubKeyDss) { - const DL_Group group(reply.parameters.at(0), reply.parameters.at(1), - reply.parameters.at(2)); + const DL_Group group(reply.hostKeyParameters.at(0), reply.hostKeyParameters.at(1), + reply.hostKeyParameters.at(2)); DSA_PublicKey * const dsaKey - = new DSA_PublicKey(group, reply.parameters.at(3)); + = new DSA_PublicKey(group, reply.hostKeyParameters.at(3)); sigKey.reset(dsaKey); } else if (m_serverHostKeyAlgo == SshCapabilities::PubKeyRsa) { RSA_PublicKey * const rsaKey - = new RSA_PublicKey(reply.parameters.at(1), reply.parameters.at(0)); + = new RSA_PublicKey(reply.hostKeyParameters.at(1), reply.hostKeyParameters.at(0)); sigKey.reset(rsaKey); } else { QSSH_ASSERT_AND_RETURN(m_serverHostKeyAlgo == SshCapabilities::PubKeyEcdsa); From 1ef9137c0d9594272d291112b3bb375711949165 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Sat, 27 Jun 2015 16:38:56 +0200 Subject: [PATCH 073/113] Let users create devices again. This partially reverts commit b646c37f0. Change-Id: I708f791afb8cab4c9b0864b557f2a22e4b0fce84 Reviewed-by: hjk --- .../devicesupport/devicefactoryselectiondialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/devicesupport/devicefactoryselectiondialog.cpp b/src/plugins/projectexplorer/devicesupport/devicefactoryselectiondialog.cpp index 8b29c56dd35..ef655f5cbcc 100644 --- a/src/plugins/projectexplorer/devicesupport/devicefactoryselectiondialog.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicefactoryselectiondialog.cpp @@ -87,7 +87,7 @@ Core::Id DeviceFactorySelectionDialog::selectedId() const QList selected = ui->listWidget->selectedItems(); if (selected.isEmpty()) return Core::Id(); - return Core::Id::fromSetting(selected.at(0)->data(Qt::UserRole)); + return selected.at(0)->data(Qt::UserRole).value(); } } // namespace Internal From 28e163de974d5bb2cec11cd98fa223def2170433 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 29 Jun 2015 10:56:15 +0200 Subject: [PATCH 074/113] SSH: Fix exit code of tests. The test apps now return != 0 in case of an error. Change-Id: I2380bc4b8e0c85e68d79f90ccc39ad9419851b04 Reviewed-by: Christian Kandeler --- tests/manual/ssh/errorhandling/main.cpp | 14 ++++---- .../ssh/remoteprocess/remoteprocesstest.cpp | 36 +++++++++---------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/tests/manual/ssh/errorhandling/main.cpp b/tests/manual/ssh/errorhandling/main.cpp index 983617bcdc9..f5fa4088b5a 100644 --- a/tests/manual/ssh/errorhandling/main.cpp +++ b/tests/manual/ssh/errorhandling/main.cpp @@ -38,6 +38,8 @@ #include #include +#include + using namespace QSsh; class Test : public QObject { @@ -117,27 +119,27 @@ private slots: void handleConnected() { qDebug("Error: Received unexpected connected() signal."); - qApp->quit(); + qApp->exit(EXIT_FAILURE); } void handleDisconnected() { qDebug("Error: Received unexpected disconnected() signal."); - qApp->quit(); + qApp->exit(EXIT_FAILURE); } void handleDataAvailable(const QString &msg) { qDebug("Error: Received unexpected dataAvailable() signal. " "Message was: '%s'.", qPrintable(msg)); - qApp->quit(); + qApp->exit(EXIT_FAILURE); } void handleError(QSsh::SshError error) { if (m_testSet.isEmpty()) { qDebug("Error: Received error %d, but no test was running.", error); - qApp->quit(); + qApp->exit(EXIT_FAILURE); } const TestItem testItem = m_testSet.takeFirst(); @@ -151,7 +153,7 @@ private slots: } } else { qDebug("Received unexpected error %d.", error); - qApp->quit(); + qApp->exit(EXIT_FAILURE); } } @@ -159,7 +161,7 @@ private slots: { if (m_testSet.isEmpty()) { qDebug("Error: timeout, but no test was running."); - qApp->quit(); + qApp->exit(EXIT_FAILURE); } const TestItem testItem = m_testSet.takeFirst(); qDebug("Error: The following test timed out: %s", testItem.description); diff --git a/tests/manual/ssh/remoteprocess/remoteprocesstest.cpp b/tests/manual/ssh/remoteprocess/remoteprocesstest.cpp index abe8a67091e..5619edf242d 100644 --- a/tests/manual/ssh/remoteprocess/remoteprocesstest.cpp +++ b/tests/manual/ssh/remoteprocess/remoteprocesstest.cpp @@ -82,14 +82,14 @@ void RemoteProcessTest::handleConnectionError() ? m_sshConnection->errorString() : m_remoteRunner->lastConnectionErrorString(); std::cerr << "Error: Connection failure (" << qPrintable(error) << ")." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } void RemoteProcessTest::handleProcessStarted() { if (m_started) { std::cerr << "Error: Received started() signal again." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } else { m_started = true; if (m_state == TestingCrash) { @@ -109,11 +109,11 @@ void RemoteProcessTest::handleProcessStdout() if (!m_started) { std::cerr << "Error: Remote output from non-started process." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } else if (m_state != TestingSuccess && m_state != TestingTerminal) { std::cerr << "Error: Got remote standard output in state " << m_state << "." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } else { m_remoteStdout += m_remoteRunner->readAllStandardOutput(); } @@ -124,11 +124,11 @@ void RemoteProcessTest::handleProcessStderr() if (!m_started) { std::cerr << "Error: Remote error output from non-started process." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } else if (m_state == TestingSuccess) { std::cerr << "Error: Unexpected remote standard error output." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } else { m_remoteStderr += m_remoteRunner->readAllStandardError(); } @@ -140,7 +140,7 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) case SshRemoteProcess::NormalExit: if (!m_started) { std::cerr << "Error: Process exited without starting." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } switch (m_state) { @@ -149,13 +149,13 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) if (exitCode != 0) { std::cerr << "Error: exit code is " << exitCode << ", expected zero." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } if (m_remoteStdout.isEmpty()) { std::cerr << "Error: Command did not produce output." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } @@ -171,12 +171,12 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) if (exitCode == 0) { std::cerr << "Error: exit code is zero, expected non-zero." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } if (m_remoteStderr.isEmpty()) { std::cerr << "Error: Command did not produce error output." << std::flush; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } @@ -191,7 +191,7 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) if (m_remoteRunner->processExitCode() == 0) { std::cerr << "Error: Successful exit from process that was " "supposed to crash." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } else { // Some shells (e.g. mksh) don't report "killed", but just a non-zero exit code. handleSuccessfulCrashTest(); @@ -202,13 +202,13 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) if (exitCode != 0) { std::cerr << "Error: exit code is " << exitCode << ", expected zero." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } if (m_remoteStdout.isEmpty()) { std::cerr << "Error: Command did not produce output." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } std::cout << "Ok.\nTesting I/O device functionality... " << std::flush; @@ -256,7 +256,7 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) } else { std::cerr << "Error: Process failed to start." << std::endl; } - qApp->quit(); + qApp->exit(EXIT_FAILURE); break; case SshRemoteProcess::CrashExit: switch (m_state) { @@ -268,7 +268,7 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) break; default: std::cerr << "Error: Unexpected crash." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); return; } } @@ -277,7 +277,7 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus) void RemoteProcessTest::handleTimeout() { std::cerr << "Error: Timeout waiting for progress." << std::endl; - qApp->quit(); + qApp->exit(EXIT_FAILURE); } void RemoteProcessTest::handleConnected() @@ -305,7 +305,7 @@ void RemoteProcessTest::handleReadyRead() if (data != testString()) { std::cerr << "Testing of QIODevice functionality failed: Expected '" << qPrintable(testString()) << "', got '" << qPrintable(data) << "'." << std::endl; - qApp->exit(1); + qApp->exit(EXIT_FAILURE); } SshRemoteProcessRunner * const killer = new SshRemoteProcessRunner(this); killer->run("pkill -9 cat", m_sshParams); From 1faf2bd1ef5f3928e0db3e92e240d8c9378c77fa Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 28 Jun 2015 23:21:02 +0300 Subject: [PATCH 075/113] C++: Fix resolving of using in enclosing scope Use-case: namespace Ns { namespace Nested { struct Foo { void func(); int bar; }; } } using namespace Ns::Nested; namespace Ns { void Foo::func() { bar; // bar not highlighted } } Change-Id: I6e667d63eb40511d65532c4d6d317aa4028a87a4 Reviewed-by: Nikolai Kosjar --- src/libs/cplusplus/LookupContext.cpp | 2 +- src/plugins/cpptools/cppcompletion_test.cpp | 23 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 38093f8b47b..2314d449971 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -1021,7 +1021,7 @@ LookupScope *LookupScope::lookupType(const Name *name, Block *block) LookupScope *LookupScope::findType(const Name *name) { ProcessedSet processed; - return d->lookupType_helper(name, &processed, /*searchInEnclosingScope =*/ false, d); + return d->lookupType_helper(name, &processed, /*searchInEnclosingScope =*/ true, d); } LookupScope *Internal::LookupScopePrivate::findBlock_helper( diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index 3bf0904c652..c743e0ed7de 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -1551,6 +1551,29 @@ void CppToolsPlugin::test_completion_data() << QLatin1String("C") << QLatin1String("m")); + QTest::newRow("type_and_using_declaration: type in nested namespace and using in global") << _( + "namespace Ns {\n" + "namespace Nested {\n" + "struct Foo\n" + "{\n" + " void func();\n" + " int m_bar;\n" + "};\n" + "}\n" + "}\n" + "\n" + "using namespace Ns::Nested;\n" + "\n" + "namespace Ns\n" + "{\n" + "void Foo::func()\n" + "{\n" + " @\n" + "}\n" + "}\n" + ) << _("m_") << (QStringList() + << QLatin1String("m_bar")); + QTest::newRow("instantiate_template_with_anonymous_class") << _( "template \n" "struct S\n" From f8544bbc42e8afcdc6202905225fcbb20e42252f Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 28 Jun 2015 22:28:44 +0300 Subject: [PATCH 076/113] C++: Resolve function-scope typedef inside lambda Use-case: struct Foo { int bar; }; void func() { typedef Foo F; []() { F f; f.bar; // bar not highlighted }; } Change-Id: Ifaee2d125931d993acad69f03031a675c6180858 Reviewed-by: Nikolai Kosjar --- src/libs/cplusplus/TypeResolver.cpp | 7 +++++++ src/plugins/cpptools/cppcompletion_test.cpp | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/libs/cplusplus/TypeResolver.cpp b/src/libs/cplusplus/TypeResolver.cpp index c837c0f9389..1be33f1410d 100644 --- a/src/libs/cplusplus/TypeResolver.cpp +++ b/src/libs/cplusplus/TypeResolver.cpp @@ -154,6 +154,13 @@ QList TypeResolver::typedefsFromScopeUpToFunctionScope(const Name *n } } enclosingBlockScope = block->enclosingScope(); + if (enclosingBlockScope) { + // For lambda, step beyond the function to its enclosing block + if (Function *enclosingFunction = enclosingBlockScope->asFunction()) { + if (!enclosingFunction->name()) + enclosingBlockScope = enclosingBlockScope->enclosingScope(); + } + } } return results; } diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index c743e0ed7de..2bbeb4f2944 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -2547,6 +2547,21 @@ void CppToolsPlugin::test_completion_data() ) << _("ar") << (QStringList() << QLatin1String("arg1")); + QTest::newRow("local_typedef_access_in_lambda") << _( + "struct Foo { int bar; };\n" + "\n" + "void func()\n" + "{\n" + " typedef Foo F;\n" + " []() {\n" + " F f;\n" + " @\n" + " };\n" + "}\n" + ) << _("f.") << (QStringList() + << QLatin1String("Foo") + << QLatin1String("bar")); + QTest::newRow("default_arguments_for_class_templates_and_base_class_QTCREATORBUG-12605") << _( "struct Foo { int foo; };\n" "template \n" From 70bc5e842c8ec11f17a8bcde4615eedb0a5cccaa Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 26 Jun 2015 10:50:06 +0200 Subject: [PATCH 077/113] CppTools: Add toolchain type to project part and use it Making CompilerOptionsBuilder to use the toolchain from the project part simplifies its public API, but following the code paths initiated by ClangCodeModel and ClangStaticAnalyzer gets harder, so better enable the separation of those by making CompilerOptionsBuilder a base class. Change-Id: I0a6bb3f8323ba09b88135a7f9d1ef967331a8ff0 Reviewed-by: Christian Kandeler --- src/plugins/clangcodemodel/clangutils.cpp | 128 +++++++++++----------- src/plugins/cpptools/cppprojects.cpp | 120 ++++++++++---------- src/plugins/cpptools/cppprojects.h | 29 +++-- 3 files changed, 142 insertions(+), 135 deletions(-) diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index fd9e908db7c..582ed43d782 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -58,20 +58,6 @@ namespace Utils { Q_LOGGING_CATEGORY(verboseRunLog, "qtc.clangcodemodel.verboserun") -namespace { -bool isBlacklisted(const QString &path) -{ - static QStringList blacklistedPaths = QStringList() - << QLatin1String("lib/gcc/i686-apple-darwin"); - - foreach (const QString &blacklisted, blacklistedPaths) - if (path.contains(blacklisted)) - return true; - - return false; -} -} // anonymous namespace - UnsavedFiles createUnsavedFiles(WorkingCopy workingCopy) { // TODO: change the modelmanager to hold one working copy, and amend it every time we ask for one. @@ -132,6 +118,72 @@ static bool maybeIncludeBorlandExtensions() #endif } +class LibClangOptionsBuilder : public CompilerOptionsBuilder +{ +public: + static QStringList build(const ProjectPart::Ptr &pPart, ProjectFile::Kind fileKind) + { + if (pPart.isNull()) + return QStringList(); + + LibClangOptionsBuilder optionsBuilder(pPart); + + if (verboseRunLog().isDebugEnabled()) + optionsBuilder.add(QLatin1String("-v")); + + optionsBuilder.addLanguageOption(fileKind); + optionsBuilder.addOptionsForLanguage(maybeIncludeBorlandExtensions()); + optionsBuilder.addToolchainAndProjectDefines(); + + static const QString resourceDir = getResourceDir(); + if (!resourceDir.isEmpty()) { + optionsBuilder.add(QLatin1String("-nostdlibinc")); + optionsBuilder.add(QLatin1String("-I") + resourceDir); + optionsBuilder.add(QLatin1String("-undef")); + } + + optionsBuilder.addHeaderPathOptions(); + + // Inject header file + static const QString injectedHeader = ICore::instance()->resourcePath() + + QLatin1String("/cplusplus/qt%1-qobjectdefs-injected.h"); + +// if (pPart->qtVersion == ProjectPart::Qt4) { +// builder.addOption(QLatin1String("-include")); +// builder.addOption(injectedHeader.arg(QLatin1Char('4'))); +// } + + if (pPart->qtVersion == ProjectPart::Qt5) { + optionsBuilder.add(QLatin1String("-include")); + optionsBuilder.add(injectedHeader.arg(QLatin1Char('5'))); + } + + if (!pPart->projectConfigFile.isEmpty()) { + optionsBuilder.add(QLatin1String("-include")); + optionsBuilder.add(pPart->projectConfigFile); + } + + optionsBuilder.add(QLatin1String("-fmessage-length=0")); + optionsBuilder.add(QLatin1String("-fdiagnostics-show-note-include-stack")); + optionsBuilder.add(QLatin1String("-fmacro-backtrace-limit=0")); + optionsBuilder.add(QLatin1String("-fretain-comments-from-system-headers")); + // TODO: -Xclang -ferror-limit -Xclang 0 ? + + return optionsBuilder.options(); + } + +private: + LibClangOptionsBuilder(const CppTools::ProjectPart::Ptr &projectPart) + : CompilerOptionsBuilder(projectPart) + { + } + + bool excludeHeaderPath(const QString &path) const override + { + return path.contains(QLatin1String("lib/gcc/i686-apple-darwin")); + } +}; + /** * @brief Creates list of command-line arguments required for correct parsing * @param pPart Null if file isn't part of any project @@ -139,53 +191,7 @@ static bool maybeIncludeBorlandExtensions() */ QStringList createClangOptions(const ProjectPart::Ptr &pPart, ProjectFile::Kind fileKind) { - if (pPart.isNull()) - return QStringList(); - - CompilerOptionsBuilder optionsBuilder(pPart); - - if (verboseRunLog().isDebugEnabled()) - optionsBuilder.add(QLatin1String("-v")); - - optionsBuilder.addLanguageOption(fileKind); - optionsBuilder.addOptionsForLanguage(maybeIncludeBorlandExtensions()); - optionsBuilder.addToolchainAndProjectDefines(); - - static const QString resourceDir = getResourceDir(); - if (!resourceDir.isEmpty()) { - optionsBuilder.add(QLatin1String("-nostdlibinc")); - optionsBuilder.add(QLatin1String("-I") + resourceDir); - optionsBuilder.add(QLatin1String("-undef")); - } - - optionsBuilder.addHeaderPathOptions(isBlacklisted); - - // Inject header file - static const QString injectedHeader = ICore::instance()->resourcePath() - + QLatin1String("/cplusplus/qt%1-qobjectdefs-injected.h"); - -// if (pPart->qtVersion == ProjectPart::Qt4) { -// builder.addOption(QLatin1String("-include")); -// builder.addOption(injectedHeader.arg(QLatin1Char('4'))); -// } - - if (pPart->qtVersion == ProjectPart::Qt5) { - optionsBuilder.add(QLatin1String("-include")); - optionsBuilder.add(injectedHeader.arg(QLatin1Char('5'))); - } - - if (!pPart->projectConfigFile.isEmpty()) { - optionsBuilder.add(QLatin1String("-include")); - optionsBuilder.add(pPart->projectConfigFile); - } - - optionsBuilder.add(QLatin1String("-fmessage-length=0")); - optionsBuilder.add(QLatin1String("-fdiagnostics-show-note-include-stack")); - optionsBuilder.add(QLatin1String("-fmacro-backtrace-limit=0")); - optionsBuilder.add(QLatin1String("-fretain-comments-from-system-headers")); - // TODO: -Xclang -ferror-limit -Xclang 0 ? - - return optionsBuilder.options(); + return LibClangOptionsBuilder::build(pPart, fileKind); } /// @return Option to speed up parsing with precompiled header diff --git a/src/plugins/cpptools/cppprojects.cpp b/src/plugins/cpptools/cppprojects.cpp index 1a8ecacb040..0792f206611 100644 --- a/src/plugins/cpptools/cppprojects.cpp +++ b/src/plugins/cpptools/cppprojects.cpp @@ -113,6 +113,7 @@ void ProjectPart::evaluateToolchain(const ToolChain *tc, } toolchainDefines = tc->predefinedMacros(commandLineFlags); + toolchainType = tc->type(); updateLanguageFeatures(); } @@ -516,12 +517,27 @@ void CompilerOptionsBuilder::add(const QString &option) m_options.append(option); } -void CompilerOptionsBuilder::addHeaderPathOptions(IsBlackListed isBlackListed, - const QString &toolchainType) +QString CompilerOptionsBuilder::defineLineToDefineOption(const QByteArray &defineLine) +{ + QByteArray str = defineLine.mid(8); + int spaceIdx = str.indexOf(' '); + const QString option = defineOption(); + const bool hasValue = spaceIdx != -1; + QString arg = option + QLatin1String(str.left(hasValue ? spaceIdx : str.size()) + '='); + if (hasValue) + arg += QLatin1String(str.mid(spaceIdx + 1)); + return arg; +} + +void CompilerOptionsBuilder::addDefine(const QByteArray &defineLine) +{ + m_options.append(defineLineToDefineOption(defineLine)); +} + +void CompilerOptionsBuilder::addHeaderPathOptions() { typedef ProjectPart::HeaderPath HeaderPath; - const QString defaultPrefix - = QLatin1String(toolchainType == QLatin1String("msvc") ? "/I" : "-I"); + const QString defaultPrefix = includeOption(); QStringList result; @@ -529,7 +545,7 @@ void CompilerOptionsBuilder::addHeaderPathOptions(IsBlackListed isBlackListed, if (headerPath.path.isEmpty()) continue; - if (isBlackListed && isBlackListed(headerPath.path)) + if (excludeHeaderPath(headerPath.path)) continue; QString prefix; @@ -550,45 +566,18 @@ void CompilerOptionsBuilder::addHeaderPathOptions(IsBlackListed isBlackListed, m_options.append(result); } -void CompilerOptionsBuilder::addToolchainAndProjectDefines(const QString &toolchainType) +void CompilerOptionsBuilder::addToolchainAndProjectDefines() { QByteArray extendedDefines = m_projectPart->toolchainDefines + m_projectPart->projectDefines; QStringList result; - // In gcc headers, lots of built-ins are referenced that clang does not understand. - // Therefore, prevent the inclusion of the header that references them. Of course, this - // will break if code actually requires stuff from there, but that should be the less common - // case. - if (toolchainType == QLatin1String("mingw") || toolchainType == QLatin1String("gcc")) - extendedDefines += "#define _X86INTRIN_H_INCLUDED\n"; - foreach (QByteArray def, extendedDefines.split('\n')) { - if (def.isEmpty()) + if (def.isEmpty() || excludeDefineLine(def)) continue; - // This is a quick fix for QTCREATORBUG-11501. - // TODO: do a proper fix, see QTCREATORBUG-11709. - if (def.startsWith("#define __cplusplus")) - continue; - - // gcc 4.9 has: - // #define __has_include(STR) __has_include__(STR) - // #define __has_include_next(STR) __has_include_next__(STR) - // The right-hand sides are gcc built-ins that clang does not understand, and they'd - // override clang's own (non-macro, it seems) definitions of the symbols on the left-hand - // side. - if (toolchainType == QLatin1String("gcc") && def.contains("has_include")) - continue; - - QByteArray str = def.mid(8); - int spaceIdx = str.indexOf(' '); - const QString option = QLatin1String(toolchainType == QLatin1String("msvc") ? "/D" : "-D"); - const bool hasValue = spaceIdx != -1; - QString arg = option + QLatin1String(str.left(hasValue ? spaceIdx : str.size()) + '='); - if (hasValue) - arg += QLatin1String(str.mid(spaceIdx + 1)); - if (!result.contains(arg)) - result.append(arg); + const QString defineOption = defineLineToDefineOption(def); + if (!result.contains(defineOption)) + result.append(defineOption); } m_options.append(result); @@ -651,41 +640,16 @@ static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objc return opts; } -static QStringList createLanguageOptionMsvc(ProjectFile::Kind fileKind) -{ - QStringList opts; - switch (fileKind) { - case ProjectFile::CHeader: - case ProjectFile::CSource: - opts << QLatin1String("/TC"); - break; - case ProjectFile::CXXHeader: - case ProjectFile::CXXSource: - opts << QLatin1String("/TP"); - break; - default: - break; - } - return opts; -} - -void CompilerOptionsBuilder::addLanguageOption(ProjectFile::Kind fileKind, - const QString &toolchainType) +void CompilerOptionsBuilder::addLanguageOption(ProjectFile::Kind fileKind) { const bool objcExt = m_projectPart->languageExtensions & ProjectPart::ObjectiveCExtensions; - const QStringList options = toolchainType == QLatin1String("msvc") - ? createLanguageOptionMsvc(fileKind) - : createLanguageOptionGcc(fileKind, objcExt); + const QStringList options = createLanguageOptionGcc(fileKind, objcExt); m_options.append(options); } -void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtensions, - const QString &toolchainType) +void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtensions) { QStringList opts; - if (toolchainType == QLatin1String("msvc")) - return; - const ProjectPart::LanguageExtensions languageExtensions = m_projectPart->languageExtensions; const bool gnuExtensions = languageExtensions & ProjectPart::GnuExtensions; switch (m_projectPart->languageVersion) { @@ -723,3 +687,29 @@ void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtension m_options.append(opts); } + +QString CompilerOptionsBuilder::includeOption() const +{ + return QLatin1String("-I"); +} + +QString CompilerOptionsBuilder::defineOption() const +{ + return QLatin1String("-D"); +} + +bool CompilerOptionsBuilder::excludeDefineLine(const QByteArray &defineLine) const +{ + // This is a quick fix for QTCREATORBUG-11501. + // TODO: do a proper fix, see QTCREATORBUG-11709. + if (defineLine.startsWith("#define __cplusplus")) + return true; + + return false; +} + +bool CompilerOptionsBuilder::excludeHeaderPath(const QString &headerPath) const +{ + Q_UNUSED(headerPath); + return false; +} diff --git a/src/plugins/cpptools/cppprojects.h b/src/plugins/cpptools/cppprojects.h index 7e1162498ab..e2dd1db2a23 100644 --- a/src/plugins/cpptools/cppprojects.h +++ b/src/plugins/cpptools/cppprojects.h @@ -130,6 +130,7 @@ public: // fields QString projectConfigFile; // currently only used by the Generic Project Manager QByteArray projectDefines; QByteArray toolchainDefines; + QString toolchainType; QList headerPaths; QStringList precompiledHeaders; LanguageVersion languageVersion; @@ -215,22 +216,32 @@ class CPPTOOLS_EXPORT CompilerOptionsBuilder { public: CompilerOptionsBuilder(const ProjectPart::Ptr &projectPart); + virtual ~CompilerOptionsBuilder() {} QStringList options() const; + // Add custom options void add(const QString &option); + void addDefine(const QByteArray &defineLine); - typedef std::function IsBlackListed; - void addHeaderPathOptions(IsBlackListed isBlackListed = IsBlackListed(), - const QString &toolchainType = QLatin1String("clang")); - void addToolchainAndProjectDefines(const QString &toolchainType = QLatin1String("clang")); - void addLanguageOption(ProjectFile::Kind fileKind, - const QString &toolchainType = QLatin1String("clang")); - void addOptionsForLanguage(bool checkForBorlandExtensions = true, - const QString &toolchainType = QLatin1String("clang")); + // Add options based on project part + void addHeaderPathOptions(); + void addToolchainAndProjectDefines(); + virtual void addLanguageOption(ProjectFile::Kind fileKind); + virtual void addOptionsForLanguage(bool checkForBorlandExtensions = true); + +protected: + virtual bool excludeDefineLine(const QByteArray &defineLine) const; + virtual bool excludeHeaderPath(const QString &headerPath) const; + + virtual QString defineOption() const; + virtual QString includeOption() const; + + const ProjectPart::Ptr m_projectPart; private: - ProjectPart::Ptr m_projectPart; + QString defineLineToDefineOption(const QByteArray &defineLine); + QStringList m_options; }; From a77e32800c2bdfdccfcd6dfcacc48d3fa610daea Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sat, 20 Jun 2015 22:37:53 +0300 Subject: [PATCH 078/113] C++: Ignore explicit template instantiations Defined in section 14.7.2 of the standard. Fixes completion for std::string. The following explicit instantiation appears in bits/basic_string.tcc: extern template class basic_string; This is wrongfully considered a specialization for a forward declaration (like `template<> class basic_string` is). Introduce a new Symbol type for explicit instantiations. Use-case: template struct Foo { T bar; }; template class Foo; void func() { Foo foo; foo.bar; // bar not highlighted } Change-Id: I9e35c8c32f6b78fc87b4f4f1fc903b42cfbd2c2b Reviewed-by: Nikolai Kosjar --- src/libs/3rdparty/cplusplus/AST.h | 2 +- src/libs/3rdparty/cplusplus/Bind.cpp | 27 ++++++---- .../cplusplus/CPlusPlusForwardDeclarations.h | 1 + src/libs/3rdparty/cplusplus/Control.cpp | 16 ++++-- src/libs/3rdparty/cplusplus/Control.h | 3 ++ src/libs/3rdparty/cplusplus/Matcher.cpp | 11 ++++ src/libs/3rdparty/cplusplus/Matcher.h | 1 + src/libs/3rdparty/cplusplus/Symbol.cpp | 3 ++ src/libs/3rdparty/cplusplus/Symbol.h | 7 ++- src/libs/3rdparty/cplusplus/SymbolVisitor.h | 1 + src/libs/3rdparty/cplusplus/Symbols.cpp | 52 +++++++++++++++++++ src/libs/3rdparty/cplusplus/Symbols.h | 33 ++++++++++++ src/libs/3rdparty/cplusplus/Templates.cpp | 14 +++++ src/libs/3rdparty/cplusplus/Templates.h | 2 + src/libs/3rdparty/cplusplus/Type.cpp | 3 ++ src/libs/3rdparty/cplusplus/Type.h | 3 ++ src/libs/3rdparty/cplusplus/TypeVisitor.h | 1 + src/libs/cplusplus/LookupContext.cpp | 6 +++ src/libs/cplusplus/LookupContext.h | 1 + src/plugins/cpptools/cppcompletion_test.cpp | 15 ++++++ .../auto/cplusplus/semantic/tst_semantic.cpp | 20 +++++++ 21 files changed, 208 insertions(+), 14 deletions(-) diff --git a/src/libs/3rdparty/cplusplus/AST.h b/src/libs/3rdparty/cplusplus/AST.h index b8cda42b59c..c44d9b4a814 100644 --- a/src/libs/3rdparty/cplusplus/AST.h +++ b/src/libs/3rdparty/cplusplus/AST.h @@ -3348,7 +3348,7 @@ public: DeclarationAST *declaration; public: // annotations - Template *symbol; + Scope *symbol; public: TemplateDeclarationAST() diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp index c135de16730..0deb19dd544 100644 --- a/src/libs/3rdparty/cplusplus/Bind.cpp +++ b/src/libs/3rdparty/cplusplus/Bind.cpp @@ -2367,11 +2367,15 @@ bool Bind::visit(ParameterDeclarationAST *ast) bool Bind::visit(TemplateDeclarationAST *ast) { - Template *templ = control()->newTemplate(ast->firstToken(), 0); - templ->setStartOffset(tokenAt(ast->firstToken()).utf16charsBegin()); - templ->setEndOffset(tokenAt(ast->lastToken() - 1).utf16charsEnd()); - ast->symbol = templ; - Scope *previousScope = switchScope(templ); + Scope *scope = 0; + if (ast->less_token) + scope = control()->newTemplate(ast->firstToken(), 0); + else + scope = control()->newExplicitInstantiation(ast->firstToken(), 0); + scope->setStartOffset(tokenAt(ast->firstToken()).utf16charsBegin()); + scope->setEndOffset(tokenAt(ast->lastToken() - 1).utf16charsEnd()); + ast->symbol = scope; + Scope *previousScope = switchScope(scope); for (DeclarationListAST *it = ast->template_parameter_list; it; it = it->next) { this->declaration(it->value); @@ -2380,12 +2384,17 @@ bool Bind::visit(TemplateDeclarationAST *ast) this->declaration(ast->declaration); (void) switchScope(previousScope); - if (Symbol *decl = templ->declaration()) { - templ->setSourceLocation(decl->sourceLocation(), translationUnit()); - templ->setName(decl->name()); + Symbol *decl = 0; + if (Template *templ = scope->asTemplate()) + decl = templ->declaration(); + else if (ExplicitInstantiation *inst = scope->asExplicitInstantiation()) + decl = inst->declaration(); + if (decl) { + scope->setSourceLocation(decl->sourceLocation(), translationUnit()); + scope->setName(decl->name()); } - _scope->addMember(templ); + _scope->addMember(scope); return false; } diff --git a/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h b/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h index 9b1c5a30cf7..54f9db96dac 100644 --- a/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h +++ b/src/libs/3rdparty/cplusplus/CPlusPlusForwardDeclarations.h @@ -112,6 +112,7 @@ class Function; class Namespace; class NamespaceAlias; class Template; +class ExplicitInstantiation; class BaseClass; class Block; class Class; diff --git a/src/libs/3rdparty/cplusplus/Control.cpp b/src/libs/3rdparty/cplusplus/Control.cpp index afdd6790560..463a2f88f69 100644 --- a/src/libs/3rdparty/cplusplus/Control.cpp +++ b/src/libs/3rdparty/cplusplus/Control.cpp @@ -366,9 +366,16 @@ public: Template *newTemplate(unsigned sourceLocation, const Name *name) { - Template *ns = new Template(translationUnit, sourceLocation, name); - symbols.push_back(ns); - return ns; + Template *templ = new Template(translationUnit, sourceLocation, name); + symbols.push_back(templ); + return templ; + } + + ExplicitInstantiation *newExplicitInstantiation(unsigned sourceLocation, const Name *name) + { + ExplicitInstantiation *inst = new ExplicitInstantiation(translationUnit, sourceLocation, name); + symbols.push_back(inst); + return inst; } NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name) @@ -692,6 +699,9 @@ Namespace *Control::newNamespace(unsigned sourceLocation, const Name *name) Template *Control::newTemplate(unsigned sourceLocation, const Name *name) { return d->newTemplate(sourceLocation, name); } +ExplicitInstantiation *Control::newExplicitInstantiation(unsigned sourceLocation, const Name *name) +{ return d->newExplicitInstantiation(sourceLocation, name); } + NamespaceAlias *Control::newNamespaceAlias(unsigned sourceLocation, const Name *name) { return d->newNamespaceAlias(sourceLocation, name); } diff --git a/src/libs/3rdparty/cplusplus/Control.h b/src/libs/3rdparty/cplusplus/Control.h index 85b8c3d3d7c..bb2bf9cd108 100644 --- a/src/libs/3rdparty/cplusplus/Control.h +++ b/src/libs/3rdparty/cplusplus/Control.h @@ -120,6 +120,9 @@ public: /// Creates a new Template symbol. Template *newTemplate(unsigned sourceLocation, const Name *name = 0); + /// Creates a new ExplicitInstantiation symbol. + ExplicitInstantiation *newExplicitInstantiation(unsigned sourceLocation, const Name *name = 0); + /// Creates a new Namespace symbol. NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name = 0); diff --git a/src/libs/3rdparty/cplusplus/Matcher.cpp b/src/libs/3rdparty/cplusplus/Matcher.cpp index 7a3c21cafc9..379ed595869 100644 --- a/src/libs/3rdparty/cplusplus/Matcher.cpp +++ b/src/libs/3rdparty/cplusplus/Matcher.cpp @@ -218,6 +218,17 @@ bool Matcher::match(const Template *type, const Template *otherType) return true; } +bool Matcher::match(const ExplicitInstantiation *type, const ExplicitInstantiation *otherType) +{ + if (type == otherType) + return true; + + if (! Matcher::match(type->name(), otherType->name(), this)) + return false; + + return true; +} + bool Matcher::match(const ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType) { if (type == otherType) diff --git a/src/libs/3rdparty/cplusplus/Matcher.h b/src/libs/3rdparty/cplusplus/Matcher.h index 1a9d9d35116..4d2b40b64d1 100644 --- a/src/libs/3rdparty/cplusplus/Matcher.h +++ b/src/libs/3rdparty/cplusplus/Matcher.h @@ -61,6 +61,7 @@ public: virtual bool match(const Enum *type, const Enum *otherType); virtual bool match(const Namespace *type, const Namespace *otherType); virtual bool match(const Template *type, const Template *otherType); + virtual bool match(const ExplicitInstantiation *type, const ExplicitInstantiation *otherType); virtual bool match(const ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType); virtual bool match(const Class *type, const Class *otherType); virtual bool match(const ObjCClass *type, const ObjCClass *otherType); diff --git a/src/libs/3rdparty/cplusplus/Symbol.cpp b/src/libs/3rdparty/cplusplus/Symbol.cpp index ae20b14bb75..0ddd4ffbb2a 100644 --- a/src/libs/3rdparty/cplusplus/Symbol.cpp +++ b/src/libs/3rdparty/cplusplus/Symbol.cpp @@ -361,6 +361,9 @@ bool Symbol::isNamespace() const bool Symbol::isTemplate() const { return asTemplate() != 0; } +bool Symbol::isExplicitInstantiation() const +{ return asExplicitInstantiation() != 0; } + bool Symbol::isClass() const { return asClass() != 0; } diff --git a/src/libs/3rdparty/cplusplus/Symbol.h b/src/libs/3rdparty/cplusplus/Symbol.h index 919268b14b6..cbed45f4612 100644 --- a/src/libs/3rdparty/cplusplus/Symbol.h +++ b/src/libs/3rdparty/cplusplus/Symbol.h @@ -135,7 +135,7 @@ public: /// Returns true if this Symbol is an Enum. bool isEnum() const; - /// Returns true if this Symbol is an Function. + /// Returns true if this Symbol is a Function. bool isFunction() const; /// Returns true if this Symbol is a Namespace. @@ -144,6 +144,9 @@ public: /// Returns true if this Symbol is a Template. bool isTemplate() const; + /// Returns true if this Symbol is an ExplicitInstantiation. + bool isExplicitInstantiation() const; + /// Returns true if this Symbol is a Class. bool isClass() const; @@ -203,6 +206,7 @@ public: virtual const Function *asFunction() const { return 0; } virtual const Namespace *asNamespace() const { return 0; } virtual const Template *asTemplate() const { return 0; } + virtual const ExplicitInstantiation *asExplicitInstantiation() const { return 0; } virtual const NamespaceAlias *asNamespaceAlias() const { return 0; } virtual const Class *asClass() const { return 0; } virtual const Block *asBlock() const { return 0; } @@ -229,6 +233,7 @@ public: virtual Function *asFunction() { return 0; } virtual Namespace *asNamespace() { return 0; } virtual Template *asTemplate() { return 0; } + virtual ExplicitInstantiation *asExplicitInstantiation() { return 0; } virtual NamespaceAlias *asNamespaceAlias() { return 0; } virtual Class *asClass() { return 0; } virtual Block *asBlock() { return 0; } diff --git a/src/libs/3rdparty/cplusplus/SymbolVisitor.h b/src/libs/3rdparty/cplusplus/SymbolVisitor.h index 4311672eca8..5331525e9fa 100644 --- a/src/libs/3rdparty/cplusplus/SymbolVisitor.h +++ b/src/libs/3rdparty/cplusplus/SymbolVisitor.h @@ -51,6 +51,7 @@ public: virtual bool visit(Function *) { return true; } virtual bool visit(Namespace *) { return true; } virtual bool visit(Template *) { return true; } + virtual bool visit(ExplicitInstantiation *) { return true; } virtual bool visit(Class *) { return true; } virtual bool visit(Block *) { return true; } virtual bool visit(ForwardClassDeclaration *) { return true; } diff --git a/src/libs/3rdparty/cplusplus/Symbols.cpp b/src/libs/3rdparty/cplusplus/Symbols.cpp index f8a8440c097..3c632f1cd7f 100644 --- a/src/libs/3rdparty/cplusplus/Symbols.cpp +++ b/src/libs/3rdparty/cplusplus/Symbols.cpp @@ -481,10 +481,12 @@ void Enum::visitSymbol0(SymbolVisitor *visitor) Template::Template(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name) : Scope(translationUnit, sourceLocation, name) + , _isExplicitInstantiation(false) { } Template::Template(Clone *clone, Subst *subst, Template *original) : Scope(clone, subst, original) + , _isExplicitInstantiation(original->_isExplicitInstantiation) { } Template::~Template() @@ -537,6 +539,56 @@ bool Template::match0(const Type *otherType, Matcher *matcher) const return false; } +ExplicitInstantiation::ExplicitInstantiation(TranslationUnit *translationUnit, + unsigned sourceLocation, const Name *name) + : Scope(translationUnit, sourceLocation, name) +{ } + +ExplicitInstantiation::ExplicitInstantiation(Clone *clone, Subst *subst, ExplicitInstantiation *original) + : Scope(clone, subst, original) +{ } + +ExplicitInstantiation::~ExplicitInstantiation() +{ } + +Symbol *ExplicitInstantiation::declaration() const +{ + if (isEmpty()) + return 0; + + if (Symbol *s = memberAt(memberCount() - 1)) { + if (s->isClass() || s->isForwardClassDeclaration() || + s->isTemplate() || s->isExplicitInstantiation() || + s->isFunction() || s->isDeclaration()) { + return s; + } + } + + return 0; +} + +FullySpecifiedType ExplicitInstantiation::type() const +{ return FullySpecifiedType(const_cast(this)); } + +void ExplicitInstantiation::visitSymbol0(SymbolVisitor *visitor) +{ + if (visitor->visit(this)) { + for (unsigned i = 0; i < memberCount(); ++i) { + visitSymbol(memberAt(i), visitor); + } + } +} + +void ExplicitInstantiation::accept0(TypeVisitor *visitor) +{ visitor->visit(this); } + +bool ExplicitInstantiation::match0(const Type *otherType, Matcher *matcher) const +{ + if (const ExplicitInstantiation *otherTy = otherType->asExplicitInstantiationType()) + return matcher->match(this, otherTy); + return false; +} + Namespace::Namespace(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name) : Scope(translationUnit, sourceLocation, name) , _isInline(false) diff --git a/src/libs/3rdparty/cplusplus/Symbols.h b/src/libs/3rdparty/cplusplus/Symbols.h index 257bdb86826..f2d92c23f2b 100644 --- a/src/libs/3rdparty/cplusplus/Symbols.h +++ b/src/libs/3rdparty/cplusplus/Symbols.h @@ -423,8 +423,41 @@ protected: virtual void visitSymbol0(SymbolVisitor *visitor); virtual void accept0(TypeVisitor *visitor); virtual bool match0(const Type *otherType, Matcher *matcher) const; + +private: + bool _isExplicitInstantiation; }; +class CPLUSPLUS_EXPORT ExplicitInstantiation : public Scope, public Type +{ +public: + ExplicitInstantiation(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name); + ExplicitInstantiation(Clone *clone, Subst *subst, ExplicitInstantiation *original); + virtual ~ExplicitInstantiation(); + + Symbol *declaration() const; + + // Symbol's interface + virtual FullySpecifiedType type() const; + + virtual const ExplicitInstantiation *asExplicitInstantiation() const + { return this; } + + virtual ExplicitInstantiation *asExplicitInstantiation() + { return this; } + + // Type's interface + virtual const ExplicitInstantiation *asExplicitInstantiationType() const + { return this; } + + virtual ExplicitInstantiation *asExplicitInstantiationType() + { return this; } + +protected: + virtual void visitSymbol0(SymbolVisitor *visitor); + virtual void accept0(TypeVisitor *visitor); + virtual bool match0(const Type *otherType, Matcher *matcher) const; +}; class CPLUSPLUS_EXPORT Namespace: public Scope, public Type { diff --git a/src/libs/3rdparty/cplusplus/Templates.cpp b/src/libs/3rdparty/cplusplus/Templates.cpp index 2aaefe416ff..41e462a3b87 100644 --- a/src/libs/3rdparty/cplusplus/Templates.cpp +++ b/src/libs/3rdparty/cplusplus/Templates.cpp @@ -125,6 +125,12 @@ void CloneType::visit(Template *type) _type = templ; } +void CloneType::visit(ExplicitInstantiation *type) +{ + ExplicitInstantiation *inst = _clone->symbol(type, _subst)->asExplicitInstantiation(); + _type = inst; +} + void CloneType::visit(Class *type) { Class *klass = _clone->symbol(type, _subst)->asClass(); @@ -291,6 +297,14 @@ bool CloneSymbol::visit(Template *symbol) return false; } +bool CloneSymbol::visit(ExplicitInstantiation *symbol) +{ + ExplicitInstantiation *inst = new ExplicitInstantiation(_clone, _subst, symbol); + _symbol = inst; + _control->addSymbol(inst); + return false; +} + bool CloneSymbol::visit(Class *symbol) { Class *klass = new Class(_clone, _subst, symbol); diff --git a/src/libs/3rdparty/cplusplus/Templates.h b/src/libs/3rdparty/cplusplus/Templates.h index 9db69084f71..e39f79a7a66 100644 --- a/src/libs/3rdparty/cplusplus/Templates.h +++ b/src/libs/3rdparty/cplusplus/Templates.h @@ -85,6 +85,7 @@ protected: virtual void visit(Function *type); virtual void visit(Namespace *type); virtual void visit(Template *type); + virtual void visit(ExplicitInstantiation *type); virtual void visit(Class *type); virtual void visit(Enum *type); virtual void visit(ForwardClassDeclaration *type); @@ -152,6 +153,7 @@ protected: virtual bool visit(Function *symbol); virtual bool visit(Namespace *symbol); virtual bool visit(Template *symbol); + virtual bool visit(ExplicitInstantiation *symbol); virtual bool visit(Class *symbol); virtual bool visit(Block *symbol); virtual bool visit(ForwardClassDeclaration *symbol); diff --git a/src/libs/3rdparty/cplusplus/Type.cpp b/src/libs/3rdparty/cplusplus/Type.cpp index bad4d42eebd..69ffb5030a8 100644 --- a/src/libs/3rdparty/cplusplus/Type.cpp +++ b/src/libs/3rdparty/cplusplus/Type.cpp @@ -68,6 +68,9 @@ bool Type::isNamespaceType() const bool Type::isTemplateType() const { return asTemplateType() != 0; } +bool Type::isExplicitInstantiationType() const +{ return asExplicitInstantiationType() != 0; } + bool Type::isClassType() const { return asClassType() != 0; } diff --git a/src/libs/3rdparty/cplusplus/Type.h b/src/libs/3rdparty/cplusplus/Type.h index 958ba15efdd..2661628f76a 100644 --- a/src/libs/3rdparty/cplusplus/Type.h +++ b/src/libs/3rdparty/cplusplus/Type.h @@ -43,6 +43,7 @@ public: bool isFunctionType() const; bool isNamespaceType() const; bool isTemplateType() const; + bool isExplicitInstantiationType() const; bool isClassType() const; bool isEnumType() const; bool isForwardClassDeclarationType() const; @@ -64,6 +65,7 @@ public: virtual const Function *asFunctionType() const { return 0; } virtual const Namespace *asNamespaceType() const { return 0; } virtual const Template *asTemplateType() const { return 0; } + virtual const ExplicitInstantiation *asExplicitInstantiationType() const { return 0; } virtual const Class *asClassType() const { return 0; } virtual const Enum *asEnumType() const { return 0; } virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const { return 0; } @@ -85,6 +87,7 @@ public: virtual Function *asFunctionType() { return 0; } virtual Namespace *asNamespaceType() { return 0; } virtual Template *asTemplateType() { return 0; } + virtual ExplicitInstantiation *asExplicitInstantiationType() { return 0; } virtual Class *asClassType() { return 0; } virtual Enum *asEnumType() { return 0; } virtual ForwardClassDeclaration *asForwardClassDeclarationType() { return 0; } diff --git a/src/libs/3rdparty/cplusplus/TypeVisitor.h b/src/libs/3rdparty/cplusplus/TypeVisitor.h index b3a24b15723..86568dcebca 100644 --- a/src/libs/3rdparty/cplusplus/TypeVisitor.h +++ b/src/libs/3rdparty/cplusplus/TypeVisitor.h @@ -51,6 +51,7 @@ public: virtual void visit(Function *) {} virtual void visit(Namespace *) {} virtual void visit(Template *) {} + virtual void visit(ExplicitInstantiation *) {} virtual void visit(Class *) {} virtual void visit(Enum *) {} virtual void visit(ForwardClassDeclaration *) {} diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 2314d449971..d1ad7226718 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -1830,6 +1830,12 @@ bool CreateBindings::visit(Template *templ) return false; } +bool CreateBindings::visit(ExplicitInstantiation *inst) +{ + Q_UNUSED(inst); + return false; +} + bool CreateBindings::visit(Namespace *ns) { LookupScope *previous = enterLookupScopeBinding(ns); diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index 0308388a3d5..8d4016dbbbb 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -178,6 +178,7 @@ protected: void process(Symbol *root); virtual bool visit(Template *templ); + virtual bool visit(ExplicitInstantiation *inst); virtual bool visit(Namespace *ns); virtual bool visit(Class *klass); virtual bool visit(ForwardClassDeclaration *klass); diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index 2bbeb4f2944..b4140d90656 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -796,6 +796,21 @@ void CppToolsPlugin::test_completion_data() << QLatin1String("Data") << QLatin1String("dataMember")); + QTest::newRow("explicit_instantiation") << _( + "template\n" + "struct Foo { T bar; };\n" + "\n" + "template class Foo;\n" + "\n" + "void func()\n" + "{\n" + " Foo foo;\n" + " @\n" + "}\n" + ) << _("foo.") << (QStringList() + << QLatin1String("Foo") + << QLatin1String("bar")); + QTest::newRow("use_global_identifier_as_base_class: derived as global and base as global") << _( "struct Global\n" "{\n" diff --git a/tests/auto/cplusplus/semantic/tst_semantic.cpp b/tests/auto/cplusplus/semantic/tst_semantic.cpp index 5ed6ed916cb..4717c5fc228 100644 --- a/tests/auto/cplusplus/semantic/tst_semantic.cpp +++ b/tests/auto/cplusplus/semantic/tst_semantic.cpp @@ -166,6 +166,7 @@ private slots: void pointer_to_function_1(); void template_instance_1(); + void explicit_instantiation_1(); void expression_under_cursor_1(); @@ -523,6 +524,25 @@ void tst_Semantic::template_instance_1() QCOMPARE(genDecl, QString::fromLatin1("void (const int &)")); } +void tst_Semantic::explicit_instantiation_1() +{ + QSharedPointer doc = document("template class basic_string;"); + QCOMPARE(doc->errorCount, 0U); + QCOMPARE(doc->globals->memberCount(), 1U); + + ExplicitInstantiation *inst = doc->globals->memberAt(0)->asExplicitInstantiation(); + QVERIFY(inst); + + ForwardClassDeclaration *fwd = inst->memberAt(0)->asForwardClassDeclaration(); + QVERIFY(fwd); + + QVERIFY(inst->name()->match(fwd->name())); + + Overview oo; + const QString name = oo.prettyName(inst->name()); + QCOMPARE(name, QString::fromLatin1("basic_string")); +} + void tst_Semantic::expression_under_cursor_1() { const QString plainText = "void *ptr = foo(10, bar"; From 9a2020914dc738f9391eae360fd55e7396971ba4 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 29 Jun 2015 09:07:47 +0200 Subject: [PATCH 079/113] Debugger: Remove fillParametersFromRunConfiguration Its use case is now covered by the generic createDebuggerRunControl. Change-Id: I2bd04351a51f3f8aae8407c2b7921a4566c17d56 Reviewed-by: Benjamin Zeller Reviewed-by: Christian Stenger --- src/plugins/debugger/debuggerruncontrol.cpp | 16 ---------------- src/plugins/debugger/debuggerruncontrol.h | 4 ---- 2 files changed, 20 deletions(-) diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index 36f7b1b3267..b2e41532aa9 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -648,20 +648,4 @@ DebuggerRunControl *createDebuggerRunControl(const DebuggerStartParameters &sp, return creator.m_runControl; } -/** - * Helper for 3rd party plugins in need to reproduce the enrichment process. - */ -bool fillParametersFromRunConfiguration(DebuggerStartParameters *sp, const RunConfiguration *runConfig, - QString *errorMessage) -{ - DebuggerRunControlCreator creator; - creator.initialize(*sp); - creator.enrich(runConfig, 0); - creator.createRunControl(DebugRunMode); - if (errorMessage) - *errorMessage = creator.fullError(); - *sp = creator.m_rp; - return creator.m_errors.isEmpty(); -} - } // namespace Debugger diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h index 479c545e37b..00b27b6165b 100644 --- a/src/plugins/debugger/debuggerruncontrol.h +++ b/src/plugins/debugger/debuggerruncontrol.h @@ -52,10 +52,6 @@ DEBUGGER_EXPORT DebuggerRunControl *createDebuggerRunControl(const DebuggerStart QString *errorMessage, ProjectExplorer::RunMode runMode = ProjectExplorer::DebugRunMode); -DEBUGGER_EXPORT bool fillParametersFromRunConfiguration(DebuggerStartParameters *sp, - const ProjectExplorer::RunConfiguration *runConfig, - QString *errorMessage); - class DEBUGGER_EXPORT DebuggerRunControl : public ProjectExplorer::RunControl { From 8529f084af9f5f812a269a6a1071890733bec33a Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 29 Jun 2015 14:36:21 +0200 Subject: [PATCH 080/113] Remove obsolete documentation. The v8 tab has been removed and QML_DISABLE_OPTIMIZER has been removed from qtdeclarative a long time ago. Change-Id: Ifaa20c4d02b5d6aad857d68a1cc5a0654710399d Reviewed-by: Leena Miettinen Reviewed-by: Kai Koehne --- doc/src/analyze/qtquick-profiler.qdoc | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/doc/src/analyze/qtquick-profiler.qdoc b/doc/src/analyze/qtquick-profiler.qdoc index e917afc9668..eb6e000a365 100644 --- a/doc/src/analyze/qtquick-profiler.qdoc +++ b/doc/src/analyze/qtquick-profiler.qdoc @@ -534,30 +534,5 @@ \uicontrol {Copy Table} or \uicontrol {Copy Row} in the context menu. JavaScript events are shown in the \uicontrol Events view only for applications - that use Qt Quick 2 and are compiled with Qt 5.3 or later. For applications - that use Qt Quick 2 and are built with Qt 5.0 or 5.1, you can view - information about JavaScript events in the separate \uicontrol V8 view. - - \section2 Viewing More Data - - The QML JavaScript engine optimizes trivial bindings. The QML Profiler - may not receive all information about optimized bindings, and therefore, - it may display the text \uicontrol {} and the message - \uicontrol {Source code not available} in the \uicontrol Callers and \uicontrol {Callees} - panes. - - To inspect the optimized bindings, turn off the QML optimizer by setting - the environment variable QML_DISABLE_OPTIMIZER to 1. To set the environment - variable for the current project in the project settings: - - \list 1 - - \li Select \uicontrol {Projects > Run}. - - \li In \uicontrol {Run Environment}, click \uicontrol Add. - - \li Add the QML_DISABLE_OPTIMIZER variable and set its value to 1. - - \endlist - + that use Qt Quick 2 and are compiled with Qt 5.3 or later. */ From 6b2917a208b45c6ec0431346502bac7268f944e3 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 29 Jun 2015 15:36:06 +0200 Subject: [PATCH 081/113] SSH: Give better name to member variable. No functional changes. Change-Id: Ie75fd001c90c2eaaf3c085c92e9ab2279e1fff98 Reviewed-by: Christian Kandeler --- src/libs/ssh/sshbotanconversions_p.h | 2 +- src/libs/ssh/sshcapabilities.cpp | 4 ++-- src/libs/ssh/sshcapabilities_p.h | 2 +- src/libs/ssh/sshincomingpacket.cpp | 4 ++-- src/libs/ssh/sshkeyexchange.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libs/ssh/sshbotanconversions_p.h b/src/libs/ssh/sshbotanconversions_p.h index 75182881b91..3257eaf04a4 100644 --- a/src/libs/ssh/sshbotanconversions_p.h +++ b/src/libs/ssh/sshbotanconversions_p.h @@ -96,7 +96,7 @@ inline const char *botanEmsaAlgoName(const QByteArray &rfcAlgoName) return "EMSA1(SHA-1)"; if (rfcAlgoName == SshCapabilities::PubKeyRsa) return "EMSA3(SHA-1)"; - if (rfcAlgoName == SshCapabilities::PubKeyEcdsa) + if (rfcAlgoName == SshCapabilities::PubKeyEcdsa256) return "EMSA1_BSI(SHA-256)"; throw SshClientException(SshInternalError, SSH_TR("Unexpected host key algorithm \"%1\"") .arg(QString::fromLatin1(rfcAlgoName))); diff --git a/src/libs/ssh/sshcapabilities.cpp b/src/libs/ssh/sshcapabilities.cpp index 2677768c3ab..60dc3e8659b 100644 --- a/src/libs/ssh/sshcapabilities.cpp +++ b/src/libs/ssh/sshcapabilities.cpp @@ -65,9 +65,9 @@ const QList SshCapabilities::KeyExchangeMethods = QList( const QByteArray SshCapabilities::PubKeyDss("ssh-dss"); const QByteArray SshCapabilities::PubKeyRsa("ssh-rsa"); -const QByteArray SshCapabilities::PubKeyEcdsa("ecdsa-sha2-nistp256"); +const QByteArray SshCapabilities::PubKeyEcdsa256("ecdsa-sha2-nistp256"); const QList SshCapabilities::PublicKeyAlgorithms = QList() - << SshCapabilities::PubKeyEcdsa + << SshCapabilities::PubKeyEcdsa256 << SshCapabilities::PubKeyRsa << SshCapabilities::PubKeyDss; diff --git a/src/libs/ssh/sshcapabilities_p.h b/src/libs/ssh/sshcapabilities_p.h index a893ccecbe3..bd7ce8a0634 100644 --- a/src/libs/ssh/sshcapabilities_p.h +++ b/src/libs/ssh/sshcapabilities_p.h @@ -50,7 +50,7 @@ public: static const QByteArray PubKeyDss; static const QByteArray PubKeyRsa; - static const QByteArray PubKeyEcdsa; + static const QByteArray PubKeyEcdsa256; static const QList PublicKeyAlgorithms; static const QByteArray CryptAlgo3DesCbc; diff --git a/src/libs/ssh/sshincomingpacket.cpp b/src/libs/ssh/sshincomingpacket.cpp index 998661719f0..e4d86d13de1 100644 --- a/src/libs/ssh/sshincomingpacket.cpp +++ b/src/libs/ssh/sshincomingpacket.cpp @@ -185,7 +185,7 @@ static void getHostKeySpecificReplyData(SshKeyExchangeReply &replyData, replyData.hostKeyParameters << SshPacketParser::asBigInt(input, &offset); } } else { - QSSH_ASSERT_AND_RETURN(hostKeyAlgo == SshCapabilities::PubKeyEcdsa); + QSSH_ASSERT_AND_RETURN(hostKeyAlgo == SshCapabilities::PubKeyEcdsa256); if (SshPacketParser::asString(input, &offset) != hostKeyAlgo.mid(11)) { // Without "ecdsa-sha2-" prefix. throw SshPacketParseException(); @@ -221,7 +221,7 @@ SshKeyExchangeReply SshIncomingPacket::extractKeyExchangeReply(const QByteArray if (SshPacketParser::asString(fullSignature, &sigOffset) != hostKeyAlgo) throw SshPacketParseException(); replyData.signatureBlob = SshPacketParser::asString(fullSignature, &sigOffset); - if (hostKeyAlgo == SshCapabilities::PubKeyEcdsa) { + if (hostKeyAlgo == SshCapabilities::PubKeyEcdsa256) { // Botan's PK_Verifier wants the signature in this format. quint32 blobOffset = 0; const Botan::BigInt r = SshPacketParser::asBigInt(replyData.signatureBlob, &blobOffset); diff --git a/src/libs/ssh/sshkeyexchange.cpp b/src/libs/ssh/sshkeyexchange.cpp index 2853ea76d72..25da1805c8b 100644 --- a/src/libs/ssh/sshkeyexchange.cpp +++ b/src/libs/ssh/sshkeyexchange.cpp @@ -213,7 +213,7 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, = new RSA_PublicKey(reply.hostKeyParameters.at(1), reply.hostKeyParameters.at(0)); sigKey.reset(rsaKey); } else { - QSSH_ASSERT_AND_RETURN(m_serverHostKeyAlgo == SshCapabilities::PubKeyEcdsa); + QSSH_ASSERT_AND_RETURN(m_serverHostKeyAlgo == SshCapabilities::PubKeyEcdsa256); const EC_Group domain("secp256r1"); const PointGFp point = OS2ECP(convertByteArray(reply.q), reply.q.count(), domain.get_curve()); From c39977f24525bfeb5115e6aac13829aa8610da4d Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 29 Jun 2015 15:37:48 +0200 Subject: [PATCH 082/113] SSH: Fix composition of ECDH key exchange signature. We need to pad the encoded integers to the full width, so the signature will have the correct length. Change-Id: Ic844a5996ed3d8a121847d09aae1a7782ee2c24c Reviewed-by: Christian Kandeler --- src/libs/ssh/sshcapabilities.cpp | 8 ++++++++ src/libs/ssh/sshcapabilities_p.h | 2 ++ src/libs/ssh/sshincomingpacket.cpp | 12 ++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/libs/ssh/sshcapabilities.cpp b/src/libs/ssh/sshcapabilities.cpp index 60dc3e8659b..725f01c1a0e 100644 --- a/src/libs/ssh/sshcapabilities.cpp +++ b/src/libs/ssh/sshcapabilities.cpp @@ -130,5 +130,13 @@ QByteArray SshCapabilities::findBestMatch(const QList &myCapabilitie return commonCapabilities(myCapabilities, serverCapabilities).first(); } +int SshCapabilities::ecdsaIntegerWidthInBytes(const QByteArray &ecdsaAlgo) +{ + if (ecdsaAlgo == PubKeyEcdsa256) + return 32; + throw SshClientException(SshInternalError, SSH_TR("Unexpected ecdsa algorithm \"%1\"") + .arg(QString::fromLatin1(ecdsaAlgo))); +} + } // namespace Internal } // namespace QSsh diff --git a/src/libs/ssh/sshcapabilities_p.h b/src/libs/ssh/sshcapabilities_p.h index bd7ce8a0634..88e26067980 100644 --- a/src/libs/ssh/sshcapabilities_p.h +++ b/src/libs/ssh/sshcapabilities_p.h @@ -76,6 +76,8 @@ public: const QList &serverCapabilities); static QByteArray findBestMatch(const QList &myCapabilities, const QList &serverCapabilities); + + static int ecdsaIntegerWidthInBytes(const QByteArray &ecdsaAlgo); }; } // namespace Internal diff --git a/src/libs/ssh/sshincomingpacket.cpp b/src/libs/ssh/sshincomingpacket.cpp index e4d86d13de1..ea46d2066be 100644 --- a/src/libs/ssh/sshincomingpacket.cpp +++ b/src/libs/ssh/sshincomingpacket.cpp @@ -194,6 +194,11 @@ static void getHostKeySpecificReplyData(SshKeyExchangeReply &replyData, } } +static QByteArray &padToWidth(QByteArray &data, int targetWidth) +{ + return data.prepend(QByteArray(targetWidth - data.count(), 0)); +} + SshKeyExchangeReply SshIncomingPacket::extractKeyExchangeReply(const QByteArray &kexAlgo, const QByteArray &hostKeyAlgo) const { @@ -226,8 +231,11 @@ SshKeyExchangeReply SshIncomingPacket::extractKeyExchangeReply(const QByteArray quint32 blobOffset = 0; const Botan::BigInt r = SshPacketParser::asBigInt(replyData.signatureBlob, &blobOffset); const Botan::BigInt s = SshPacketParser::asBigInt(replyData.signatureBlob, &blobOffset); - replyData.signatureBlob = convertByteArray(Botan::BigInt::encode(r)); - replyData.signatureBlob += convertByteArray(Botan::BigInt::encode(s)); + const int width = SshCapabilities::ecdsaIntegerWidthInBytes(hostKeyAlgo); + QByteArray encodedR = convertByteArray(Botan::BigInt::encode(r)); + replyData.signatureBlob = padToWidth(encodedR, width); + QByteArray encodedS = convertByteArray(Botan::BigInt::encode(s)); + replyData.signatureBlob += padToWidth(encodedS, width); } replyData.k_s.prepend(m_data.mid(TypeOffset + 1, 4)); return replyData; From 48fd79cb0b7366ce695a99496373d4627f13b9fa Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 23 Jun 2015 14:35:59 +0200 Subject: [PATCH 083/113] Squish: Fix suite_QMLS Change-Id: I2e9fffd35571c4aef62dc27330425f4bf6ac9a68 Reviewed-by: Robert Loehning --- tests/system/suite_QMLS/tst_QMLS07/test.py | 2 +- tests/system/suite_QMLS/tst_QMLS08/test.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/system/suite_QMLS/tst_QMLS07/test.py b/tests/system/suite_QMLS/tst_QMLS07/test.py index 55e75ff978c..eaf86465c80 100644 --- a/tests/system/suite_QMLS/tst_QMLS07/test.py +++ b/tests/system/suite_QMLS/tst_QMLS07/test.py @@ -31,7 +31,7 @@ source("../shared/qmls.py") def main(): - editorArea = startQtCreatorWithNewAppAtQMLEditor(tempDir(), "SampleApp", "Rectangle {") + editorArea = startQtCreatorWithNewAppAtQMLEditor(tempDir(), "SampleApp", "Window {") if not editorArea: return type(editorArea, "") diff --git a/tests/system/suite_QMLS/tst_QMLS08/test.py b/tests/system/suite_QMLS/tst_QMLS08/test.py index 6ee4837b98e..31cd705f55e 100644 --- a/tests/system/suite_QMLS/tst_QMLS08/test.py +++ b/tests/system/suite_QMLS/tst_QMLS08/test.py @@ -45,7 +45,7 @@ def verifyNextLineIndented(editorArea, expectedIndentation): def verifyIndentation(editorArea): #verify indentation - if not placeCursorToLine(editorArea, "id: rect"): + if not placeCursorToLine(editorArea, "id: wdw"): invokeMenuItem("File", "Save All") invokeMenuItem("File", "Exit") return False @@ -60,13 +60,13 @@ def main(): if not editorArea: return # prepare code for test - insert unindented code - lines = ['id: rect', 'property bool random: true', 'Text{', - 'anchors.bottom:parent.bottom', 'text: rect.random ? getRandom() : "I\'m fixed."', + lines = ['id: wdw', 'property bool random: true', 'Text {', + 'anchors.bottom: parent.bottom', 'text: wdw.random ? getRandom() : "I\'m fixed."', '', 'function getRandom(){', 'var result="I\'m random: ";', 'var chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";', 'for(var i=0;i<8;++i)', 'result += chars.charAt(Math.floor(Math.random() * chars.length));', 'return result + ".";'] - if not placeCursorToLine(editorArea, "Rectangle {"): + if not placeCursorToLine(editorArea, "Window {"): invokeMenuItem("File", "Exit") return type(editorArea, "") From 22c95e302445f10757deb03718d6ed81ff08ea3a Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Mon, 29 Jun 2015 13:16:59 +0200 Subject: [PATCH 084/113] CppTools: Re-introduce gcc 4.9 __has_include fix Now the ClangCodeModel makes also use of this. Change-Id: I3d547dffe48e35d3b3d03063bc1a640283d670c1 Reviewed-by: Christian Kandeler --- src/plugins/cpptools/cppprojects.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/plugins/cpptools/cppprojects.cpp b/src/plugins/cpptools/cppprojects.cpp index 0792f206611..17e197c1cfe 100644 --- a/src/plugins/cpptools/cppprojects.cpp +++ b/src/plugins/cpptools/cppprojects.cpp @@ -705,6 +705,16 @@ bool CompilerOptionsBuilder::excludeDefineLine(const QByteArray &defineLine) con if (defineLine.startsWith("#define __cplusplus")) return true; + // gcc 4.9 has: + // #define __has_include(STR) __has_include__(STR) + // #define __has_include_next(STR) __has_include_next__(STR) + // The right-hand sides are gcc built-ins that clang does not understand, and they'd + // override clang's own (non-macro, it seems) definitions of the symbols on the left-hand + // side. + const bool isGccToolchain = m_projectPart->toolchainType == QLatin1String("gcc"); + if (isGccToolchain && defineLine.contains("has_include")) + return true; + return false; } From 30157677476281e90810148f741ecf39df29baf8 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 29 Jun 2015 20:01:47 +0200 Subject: [PATCH 085/113] Journald: Fix reading of entries logged into journald * Do not use 100% CPU * Do use the correct machine_id Task-number: QTCREATORBUG-14356 Change-Id: Ib6ae9036be83f4f3bb9f7834a1590b492d9a33e1 Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/journaldwatcher.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/plugins/projectexplorer/journaldwatcher.cpp b/src/plugins/projectexplorer/journaldwatcher.cpp index 29af127bf64..1ea4587addc 100644 --- a/src/plugins/projectexplorer/journaldwatcher.cpp +++ b/src/plugins/projectexplorer/journaldwatcher.cpp @@ -157,8 +157,10 @@ const QByteArray &JournaldWatcher::machineId() static QByteArray id; if (id.isEmpty()) { sd_id128 sdId; - if (sd_id128_get_machine(&sdId) == 0) - id = QByteArray(reinterpret_cast(sdId.bytes), 16); + if (sd_id128_get_machine(&sdId) == 0) { + id.resize(32); + sd_id128_to_string(sdId, id.data()); + } } return id; } @@ -209,6 +211,9 @@ void JournaldWatcher::handleEntry() if (!d->m_notifier) return; + if (sd_journal_process(d->m_journalContext) != SD_JOURNAL_APPEND) + return; + LogEntry logEntry; forever { logEntry = d->retrieveEntry(); @@ -225,6 +230,7 @@ void JournaldWatcher::handleEntry() quint64 pidNum = pid.isEmpty() ? 0 : QString::fromLatin1(pid).toInt(); QString message = QString::fromUtf8(logEntry.value(QByteArrayLiteral("MESSAGE"))); + message.append(QLatin1Char('\n')); // Add newline. emit journaldOutput(pidNum, message); } From d710e73084c4ccb408b64a20ef938c380694ef9f Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 23 Jun 2015 15:47:14 +0200 Subject: [PATCH 086/113] Squish: Fix tst_APTW03 Change-Id: I88383be83b518de6363a53bb6102f1f302fac1cf Reviewed-by: Robert Loehning --- tests/system/suite_APTW/tst_APTW03/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/suite_APTW/tst_APTW03/test.py b/tests/system/suite_APTW/tst_APTW03/test.py index ce58243a01d..72e5b217efa 100644 --- a/tests/system/suite_APTW/tst_APTW03/test.py +++ b/tests/system/suite_APTW/tst_APTW03/test.py @@ -56,7 +56,7 @@ def handleInsertVirtualFunctions(expected): "Verifying whether all expected functions have been found.") selectFromCombo("{container={title='Insertion options:' type='QGroupBox' unnamed='1' " - " visible='1'} type='QComboBox' unnamed='1' visible='1'}", + " visible='1'} occurrence='2' type='QComboBox' unnamed='1' visible='1'}", "Insert definitions in implementation file") clickButton("{text='OK' type='QPushButton' unnamed='1' visible='1'}") From 7743664957f3a9e857d72530e475d13844bd4037 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 24 Jun 2015 16:00:47 +0200 Subject: [PATCH 087/113] Installers/OS X: Remove hack that is no longer necessary There were a few Qt versions where the menu nib was missing from the installer, but no longer. Change-Id: I2ab95237cb5e0d2b72d7086f8a784a35e0c935a1 Reviewed-by: Kai Koehne --- qtcreator.pro | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/qtcreator.pro b/qtcreator.pro index c78f6bec4f4..3078c34be1b 100644 --- a/qtcreator.pro +++ b/qtcreator.pro @@ -128,14 +128,9 @@ installer.depends = bindist_installer installer.commands = python -u $$PWD/scripts/packageIfw.py -i \"$(IFW_PATH)\" -v $${QTCREATOR_VERSION} -a \"$${INSTALLER_ARCHIVE}\" "$$INSTALLER_NAME" macx { - # this should be very temporary: - MENU_NIB = $$(MENU_NIB_FILE) - isEmpty(MENU_NIB): MENU_NIB = "FATAT_SET_MENU_NIB_FILE_ENV" - copy_menu_nib_installer.commands = cp -R \"$$MENU_NIB\" \"$${INSTALLER_NAME}.app/Contents/Resources\" - codesign_installer.commands = codesign -s \"$(SIGNING_IDENTITY)\" $(SIGNING_FLAGS) \"$${INSTALLER_NAME}.app\" dmg_installer.commands = hdiutil create -srcfolder "$${INSTALLER_NAME}.app" -volname \"Qt Creator\" -format UDBZ "$${BASENAME}-installer.dmg" -ov -scrub -size 1g -verbose - QMAKE_EXTRA_TARGETS += codesign_installer dmg_installer copy_menu_nib_installer + QMAKE_EXTRA_TARGETS += codesign_installer dmg_installer } win32 { From 2182ded57be0bd91ab4459e622c2ac8fbef90e65 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Mon, 29 Jun 2015 10:36:29 +0300 Subject: [PATCH 088/113] ProjectExplorer: Use Core::Id as RunMode "enum values" This provides a way for third-party plugins to implement run modes without the need to add a value to the central enum or using manual workarounds like RunMode(*(int*)&someUniqueObject). Instead of centrally defined enum values this uses Core::Id that could be defined anywhere. Change-Id: Ic350e3d8dbb8042c61b2d4ffec993ca151f53099 Reviewed-by: Daniel Teske Reviewed-by: Eike Ziller --- .../analyzerbase/analyzerstartparameters.h | 5 +- src/plugins/analyzerbase/ianalyzertool.h | 6 +-- src/plugins/android/androidanalyzesupport.cpp | 4 +- src/plugins/android/androidanalyzesupport.h | 2 +- src/plugins/android/androidruncontrol.cpp | 4 +- src/plugins/android/androidrunfactories.cpp | 27 +++++------ src/plugins/android/androidrunfactories.h | 4 +- src/plugins/android/androidrunner.cpp | 6 +-- src/plugins/android/androidrunner.h | 4 +- .../baremetal/baremetalruncontrolfactory.cpp | 9 ++-- .../baremetal/baremetalruncontrolfactory.h | 4 +- src/plugins/debugger/debuggerplugin.cpp | 16 +++---- src/plugins/debugger/debuggerruncontrol.cpp | 13 ++++-- src/plugins/debugger/debuggerruncontrol.h | 2 +- src/plugins/ios/iosanalyzesupport.cpp | 2 +- src/plugins/ios/iosruncontrol.cpp | 2 +- src/plugins/ios/iosrunfactories.cpp | 16 ++++--- src/plugins/ios/iosrunfactories.h | 4 +- .../localapplicationruncontrol.cpp | 8 ++-- .../localapplicationruncontrol.h | 6 +-- .../projectexplorer/projectexplorer.cpp | 46 +++++++++---------- src/plugins/projectexplorer/projectexplorer.h | 13 +++--- .../projectexplorerconstants.h | 22 +++------ .../projectexplorer/runconfiguration.cpp | 8 ++-- .../projectexplorer/runconfiguration.h | 10 ++-- .../pythoneditor/pythoneditorplugin.cpp | 14 +++--- src/plugins/qmlprofiler/qmlprofilerplugin.cpp | 4 +- .../qmlprofilerruncontrolfactory.cpp | 6 +-- .../qmlprofilerruncontrolfactory.h | 4 +- src/plugins/qmlprofiler/qmlprofilertool.cpp | 2 +- src/plugins/qnx/qnxattachdebugsupport.cpp | 2 +- src/plugins/qnx/qnxruncontrolfactory.cpp | 33 ++++++------- src/plugins/qnx/qnxruncontrolfactory.h | 4 +- .../remotelinux/remotelinuxanalyzesupport.cpp | 8 ++-- .../remotelinux/remotelinuxanalyzesupport.h | 4 +- .../remotelinux/remotelinuxruncontrol.cpp | 2 +- .../remotelinuxruncontrolfactory.cpp | 31 ++++++------- .../remotelinuxruncontrolfactory.h | 4 +- src/plugins/valgrind/callgrindtool.h | 2 + src/plugins/valgrind/memchecktool.h | 5 ++ src/plugins/valgrind/valgrindplugin.cpp | 11 ++--- src/plugins/valgrind/valgrindplugin.h | 1 + .../valgrind/valgrindruncontrolfactory.cpp | 8 ++-- .../valgrind/valgrindruncontrolfactory.h | 4 +- src/plugins/winrt/winrtdebugsupport.cpp | 2 +- src/plugins/winrt/winrtdebugsupport.h | 2 +- src/plugins/winrt/winrtruncontrol.cpp | 4 +- src/plugins/winrt/winrtruncontrol.h | 2 +- src/plugins/winrt/winrtrunfactories.cpp | 31 ++++++------- src/plugins/winrt/winrtrunfactories.h | 4 +- 50 files changed, 218 insertions(+), 219 deletions(-) diff --git a/src/plugins/analyzerbase/analyzerstartparameters.h b/src/plugins/analyzerbase/analyzerstartparameters.h index e03f2e92d2a..3eab41f734c 100644 --- a/src/plugins/analyzerbase/analyzerstartparameters.h +++ b/src/plugins/analyzerbase/analyzerstartparameters.h @@ -36,10 +36,11 @@ #include +#include #include #include -#include #include +#include namespace Analyzer { @@ -49,7 +50,7 @@ namespace Analyzer { class ANALYZER_EXPORT AnalyzerStartParameters { public: - ProjectExplorer::RunMode runMode; + Core::Id runMode = ProjectExplorer::Constants::NO_RUN_MODE; QSsh::SshConnectionParameters connParams; ProjectExplorer::ApplicationLauncher::Mode localRunMode = ProjectExplorer::ApplicationLauncher::Gui; diff --git a/src/plugins/analyzerbase/ianalyzertool.h b/src/plugins/analyzerbase/ianalyzertool.h index b87414bffda..f7be88476fb 100644 --- a/src/plugins/analyzerbase/ianalyzertool.h +++ b/src/plugins/analyzerbase/ianalyzertool.h @@ -86,8 +86,8 @@ public: void setToolId(Core::Id id) { m_toolId = id; } void setToolMode(ToolMode mode) { m_toolMode = mode; } - ProjectExplorer::RunMode runMode() const { return m_runMode; } - void setRunMode(ProjectExplorer::RunMode mode) { m_runMode = mode; } + Core::Id runMode() const { return m_runMode; } + void setRunMode(Core::Id mode) { m_runMode = mode; } bool isRunnable(QString *reason = 0) const; /// Creates all widgets used by the tool. @@ -119,7 +119,7 @@ protected: Core::Id m_actionId; Core::Id m_toolId; ToolMode m_toolMode; - ProjectExplorer::RunMode m_runMode; + Core::Id m_runMode; WidgetCreator m_widgetCreator; RunControlCreator m_runControlCreator; ToolStarter m_customToolStarter; diff --git a/src/plugins/android/androidanalyzesupport.cpp b/src/plugins/android/androidanalyzesupport.cpp index 6978424218b..ff0dd9af9e6 100644 --- a/src/plugins/android/androidanalyzesupport.cpp +++ b/src/plugins/android/androidanalyzesupport.cpp @@ -52,7 +52,7 @@ namespace Android { namespace Internal { RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(AndroidRunConfiguration *runConfig, - RunMode runMode) + Core::Id runMode) { Target *target = runConfig->target(); AnalyzerStartParameters params; @@ -61,7 +61,7 @@ RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(AndroidRunConfigurati params.sysroot = SysRootKitInformation::sysRoot(target->kit()).toString(); // TODO: Not sure if these are the right paths. params.workingDirectory = target->project()->projectDirectory().toString(); - if (runMode == QmlProfilerRunMode) { + if (runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { QTcpServer server; QTC_ASSERT(server.listen(QHostAddress::LocalHost) || server.listen(QHostAddress::LocalHostIPv6), return 0); diff --git a/src/plugins/android/androidanalyzesupport.h b/src/plugins/android/androidanalyzesupport.h index 469dc7193d9..610be9a1e46 100644 --- a/src/plugins/android/androidanalyzesupport.h +++ b/src/plugins/android/androidanalyzesupport.h @@ -51,7 +51,7 @@ public: Analyzer::AnalyzerRunControl *runControl); static ProjectExplorer::RunControl *createAnalyzeRunControl(AndroidRunConfiguration *runConfig, - ProjectExplorer::RunMode runMode); + Core::Id runMode); private: QmlDebug::QmlOutputParser m_outputParser; diff --git a/src/plugins/android/androidruncontrol.cpp b/src/plugins/android/androidruncontrol.cpp index 8a0bf3155a4..41893846e2d 100644 --- a/src/plugins/android/androidruncontrol.cpp +++ b/src/plugins/android/androidruncontrol.cpp @@ -42,8 +42,8 @@ namespace Android { namespace Internal { AndroidRunControl::AndroidRunControl(AndroidRunConfiguration *rc) - : RunControl(rc, NormalRunMode) - , m_runner(new AndroidRunner(this, rc, NormalRunMode)) + : RunControl(rc, ProjectExplorer::Constants::NORMAL_RUN_MODE) + , m_runner(new AndroidRunner(this, rc, ProjectExplorer::Constants::NORMAL_RUN_MODE)) , m_running(false) { setIcon(QLatin1String(ProjectExplorer::Constants::ICON_RUN_SMALL)); diff --git a/src/plugins/android/androidrunfactories.cpp b/src/plugins/android/androidrunfactories.cpp index 7e8673aa6a0..a0a5e1cf3f9 100644 --- a/src/plugins/android/androidrunfactories.cpp +++ b/src/plugins/android/androidrunfactories.cpp @@ -56,35 +56,30 @@ AndroidRunControlFactory::AndroidRunControlFactory(QObject *parent) { } -bool AndroidRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool AndroidRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { - if (mode != NormalRunMode && mode != DebugRunMode && mode != QmlProfilerRunMode) + if (mode != ProjectExplorer::Constants::NORMAL_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN + && mode != ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { return false; + } return qobject_cast(runConfiguration); } RunControl *AndroidRunControlFactory::create(RunConfiguration *runConfig, - RunMode mode, QString *errorMessage) + Core::Id mode, QString *errorMessage) { Q_ASSERT(canRun(runConfig, mode)); AndroidRunConfiguration *rc = qobject_cast(runConfig); Q_ASSERT(rc); - switch (mode) { - case NormalRunMode: + if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) return new AndroidRunControl(rc); - case DebugRunMode: + if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE || mode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) return AndroidDebugSupport::createDebugRunControl(rc, errorMessage); - case QmlProfilerRunMode: + if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) return AndroidAnalyzeSupport::createAnalyzeRunControl(rc, mode); - case NoRunMode: - case DebugRunModeWithBreakOnMain: - case CallgrindRunMode: - case MemcheckRunMode: - case MemcheckWithGdbRunMode: - case ClangStaticAnalyzerMode: - case PerfProfilerRunMode: - QTC_CHECK(false); // The other run modes are not supported - } + QTC_CHECK(false); // The other run modes are not supported return 0; } diff --git a/src/plugins/android/androidrunfactories.h b/src/plugins/android/androidrunfactories.h index ec3503c1518..b2940fd93c0 100644 --- a/src/plugins/android/androidrunfactories.h +++ b/src/plugins/android/androidrunfactories.h @@ -53,9 +53,9 @@ public: explicit AndroidRunControlFactory(QObject *parent = 0); bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode) const; + Core::Id mode) const; ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, + Core::Id mode, QString *errorMessage); }; diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp index c525440c0f4..c530d008cfb 100644 --- a/src/plugins/android/androidrunner.cpp +++ b/src/plugins/android/androidrunner.cpp @@ -125,21 +125,21 @@ static int socketHandShakePort = MIN_SOCKET_HANDSHAKE_PORT; AndroidRunner::AndroidRunner(QObject *parent, AndroidRunConfiguration *runConfig, - ProjectExplorer::RunMode runMode) + Core::Id runMode) : QThread(parent), m_handShakeMethod(SocketHandShake), m_socket(0), m_customPort(false) { m_tries = 0; Debugger::DebuggerRunConfigurationAspect *aspect = runConfig->extraAspect(); - const bool debuggingMode = runMode == ProjectExplorer::DebugRunMode; + const bool debuggingMode = (runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE || runMode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN); m_useCppDebugger = debuggingMode && aspect->useCppDebugger(); m_useQmlDebugger = debuggingMode && aspect->useQmlDebugger(); QString channel = runConfig->remoteChannel(); QTC_CHECK(channel.startsWith(QLatin1Char(':'))); m_localGdbServerPort = channel.mid(1).toUShort(); QTC_CHECK(m_localGdbServerPort); - m_useQmlProfiler = runMode == ProjectExplorer::QmlProfilerRunMode; + m_useQmlProfiler = runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE; if (m_useQmlDebugger || m_useQmlProfiler) { QTcpServer server; QTC_ASSERT(server.listen(QHostAddress::LocalHost) diff --git a/src/plugins/android/androidrunner.h b/src/plugins/android/androidrunner.h index 8f6c40d5739..8bf90f4e8a2 100644 --- a/src/plugins/android/androidrunner.h +++ b/src/plugins/android/androidrunner.h @@ -33,7 +33,7 @@ #include "androidconfigurations.h" -#include +#include #include #include @@ -58,7 +58,7 @@ class AndroidRunner : public QThread public: AndroidRunner(QObject *parent, AndroidRunConfiguration *runConfig, - ProjectExplorer::RunMode runMode); + Core::Id runMode); ~AndroidRunner(); QString displayName() const; diff --git a/src/plugins/baremetal/baremetalruncontrolfactory.cpp b/src/plugins/baremetal/baremetalruncontrolfactory.cpp index 7dd2fb7edfe..8a4cb36278e 100644 --- a/src/plugins/baremetal/baremetalruncontrolfactory.cpp +++ b/src/plugins/baremetal/baremetalruncontrolfactory.cpp @@ -71,17 +71,20 @@ BareMetalRunControlFactory::~BareMetalRunControlFactory() { } -bool BareMetalRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool BareMetalRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { - if (mode != NormalRunMode && mode != DebugRunMode && mode != DebugRunModeWithBreakOnMain) + if (mode != ProjectExplorer::Constants::NORMAL_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) { return false; + } const QByteArray idStr = runConfiguration->id().name(); return runConfiguration->isEnabled() && idStr.startsWith(BareMetalRunConfiguration::IdPrefix); } RunControl *BareMetalRunControlFactory::create( - RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) + RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) { QTC_ASSERT(canRun(runConfiguration, mode), return 0); diff --git a/src/plugins/baremetal/baremetalruncontrolfactory.h b/src/plugins/baremetal/baremetalruncontrolfactory.h index 68f5e15645a..55d8f4d98ea 100644 --- a/src/plugins/baremetal/baremetalruncontrolfactory.h +++ b/src/plugins/baremetal/baremetalruncontrolfactory.h @@ -47,9 +47,9 @@ class BareMetalRunControlFactory : public ProjectExplorer::IRunControlFactory public: explicit BareMetalRunControlFactory(QObject *parent = 0); ~BareMetalRunControlFactory(); - bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, ProjectExplorer::RunMode mode) const; + bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, Core::Id mode) const; ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, + Core::Id mode, QString *errorMessage); }; diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 261bbfb2a84..a79bef2e8c5 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -810,7 +810,7 @@ public slots: void handleExecStep() { if (currentEngine()->state() == DebuggerNotReady) { - ProjectExplorerPlugin::runStartupProject(DebugRunModeWithBreakOnMain); + ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN); } else { currentEngine()->resetLocation(); if (boolSetting(OperateByInstruction)) @@ -823,7 +823,7 @@ public slots: void handleExecNext() { if (currentEngine()->state() == DebuggerNotReady) { - ProjectExplorerPlugin::runStartupProject(DebugRunModeWithBreakOnMain); + ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN); } else { currentEngine()->resetLocation(); if (boolSetting(OperateByInstruction)) @@ -1306,7 +1306,7 @@ void DebuggerPluginPrivate::onCurrentProjectChanged(Project *project) m_continueAction->setEnabled(false); m_exitAction->setEnabled(false); QString whyNot; - const bool canRun = ProjectExplorerPlugin::canRun(project, DebugRunMode, &whyNot); + const bool canRun = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE, &whyNot); m_startAction->setEnabled(canRun); m_startAction->setToolTip(whyNot); m_debugWithoutDeployAction->setEnabled(canRun); @@ -1978,7 +1978,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) m_localsAndExpressionsWindow->setShowLocals(false); } else if (state == DebuggerFinished) { Project *project = SessionManager::startupProject(); - const bool canRun = ProjectExplorerPlugin::canRun(project, DebugRunMode); + const bool canRun = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE); // We don't want to do anything anymore. m_interruptAction->setEnabled(false); m_continueAction->setEnabled(false); @@ -2080,7 +2080,7 @@ void DebuggerPluginPrivate::updateDebugActions() Project *project = SessionManager::startupProject(); QString whyNot; - const bool canRun = ProjectExplorerPlugin::canRun(project, DebugRunMode, &whyNot); + const bool canRun = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE, &whyNot); m_startAction->setEnabled(canRun); m_startAction->setToolTip(whyNot); m_debugWithoutDeployAction->setEnabled(canRun); @@ -2089,7 +2089,7 @@ void DebuggerPluginPrivate::updateDebugActions() if (m_snapshotHandler->currentIndex() < 0) { QString toolTip; const bool canRunAndBreakMain - = ProjectExplorerPlugin::canRun(project, DebugRunModeWithBreakOnMain, &toolTip); + = ProjectExplorerPlugin::canRun(project, ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN, &toolTip); m_stepAction->setEnabled(canRunAndBreakMain); m_nextAction->setEnabled(canRunAndBreakMain); if (canRunAndBreakMain) { @@ -2592,11 +2592,11 @@ void DebuggerPluginPrivate::extensionsInitialized() debuggerIcon.addFile(QLatin1String(":/projectexplorer/images/debugger_start.png")); act->setIcon(debuggerIcon); act->setText(tr("Start Debugging")); - connect(act, &QAction::triggered, [] { ProjectExplorerPlugin::runStartupProject(DebugRunMode); }); + connect(act, &QAction::triggered, [] { ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE); }); act = m_debugWithoutDeployAction = new QAction(this); act->setText(tr("Start Debugging Without Deployment")); - connect(act, &QAction::triggered, [] { ProjectExplorerPlugin::runStartupProject(DebugRunMode, true); }); + connect(act, &QAction::triggered, [] { ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DEBUG_RUN_MODE, true); }); act = m_startAndDebugApplicationAction = new QAction(this); act->setText(tr("Start and Debug External Application...")); diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index b2e41532aa9..b02ddb7291c 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -70,6 +70,9 @@ namespace Debugger { namespace Internal { DebuggerEngine *createCdbEngine(const DebuggerRunParameters &rp, QStringList *error); +const auto *DebugRunMode = ProjectExplorer::Constants::DEBUG_RUN_MODE; +const auto *DebugRunModeWithBreakOnMain = ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN; + DebuggerEngine *createGdbEngine(const DebuggerRunParameters &rp); DebuggerEngine *createPdbEngine(const DebuggerRunParameters &rp); DebuggerEngine *createQmlEngine(const DebuggerRunParameters &rp); @@ -295,7 +298,7 @@ public: // detectable pieces, construct an Engine and a RunControl. void initialize(const DebuggerStartParameters &sp); void enrich(const RunConfiguration *runConfig, const Kit *kit); - void createRunControl(RunMode runMode); + void createRunControl(Core::Id runMode = DebugRunMode); QString fullError() const { return m_errors.join(QLatin1Char('\n')); } // Result. @@ -536,7 +539,7 @@ DebuggerEngine *createEngine(DebuggerEngineType et, const DebuggerRunParameters return 0; } -void DebuggerRunControlCreator::createRunControl(RunMode runMode) +void DebuggerRunControlCreator::createRunControl(Core::Id runMode) { if (runMode == DebugRunModeWithBreakOnMain) m_rp.breakOnMain = true; @@ -569,7 +572,7 @@ public: {} RunControl *create(RunConfiguration *runConfig, - RunMode mode, QString *errorMessage) override + Core::Id mode, QString *errorMessage) override { QTC_ASSERT(runConfig, return 0); QTC_ASSERT(mode == DebugRunMode || mode == DebugRunModeWithBreakOnMain, return 0); @@ -584,7 +587,7 @@ public: return creator.m_runControl; } - bool canRun(RunConfiguration *runConfig, RunMode mode) const override + bool canRun(RunConfiguration *runConfig, Core::Id mode) const override { return (mode == DebugRunMode || mode == DebugRunModeWithBreakOnMain) && qobject_cast(runConfig); @@ -633,7 +636,7 @@ DebuggerRunControl *createAndScheduleRun(const DebuggerRunParameters &rp, const DebuggerRunControl *createDebuggerRunControl(const DebuggerStartParameters &sp, RunConfiguration *runConfig, QString *errorMessage, - RunMode runMode) + Core::Id runMode) { DebuggerRunControlCreator creator; creator.initialize(sp); diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h index 00b27b6165b..f7b8e850382 100644 --- a/src/plugins/debugger/debuggerruncontrol.h +++ b/src/plugins/debugger/debuggerruncontrol.h @@ -50,7 +50,7 @@ class DebuggerRunControlCreator; DEBUGGER_EXPORT DebuggerRunControl *createDebuggerRunControl(const DebuggerStartParameters &sp, ProjectExplorer::RunConfiguration *runConfig, QString *errorMessage, - ProjectExplorer::RunMode runMode = ProjectExplorer::DebugRunMode); + Core::Id runMode = ProjectExplorer::Constants::DEBUG_RUN_MODE); class DEBUGGER_EXPORT DebuggerRunControl : public ProjectExplorer::RunControl diff --git a/src/plugins/ios/iosanalyzesupport.cpp b/src/plugins/ios/iosanalyzesupport.cpp index 9f5bb0000d6..ce593c9b94d 100644 --- a/src/plugins/ios/iosanalyzesupport.cpp +++ b/src/plugins/ios/iosanalyzesupport.cpp @@ -84,7 +84,7 @@ RunControl *IosAnalyzeSupport::createAnalyzeRunControl(IosRunConfiguration *runC if (device.isNull()) return 0; AnalyzerStartParameters params; - params.runMode = QmlProfilerRunMode; + params.runMode = ProjectExplorer::Constants::QML_PROFILER_RUN_MODE; params.sysroot = SysRootKitInformation::sysRoot(target->kit()).toString(); params.debuggee = runConfig->localExecutable().toUserOutput(); params.debuggeeArgs = Utils::QtcProcess::joinArgs(runConfig->commandLineArguments()); diff --git a/src/plugins/ios/iosruncontrol.cpp b/src/plugins/ios/iosruncontrol.cpp index 3144574e3e4..7edeb14661f 100644 --- a/src/plugins/ios/iosruncontrol.cpp +++ b/src/plugins/ios/iosruncontrol.cpp @@ -41,7 +41,7 @@ namespace Ios { namespace Internal { IosRunControl::IosRunControl(IosRunConfiguration *rc) - : RunControl(rc, NormalRunMode) + : RunControl(rc, ProjectExplorer::Constants::NORMAL_RUN_MODE) , m_runner(new IosRunner(this, rc, false, false)) , m_running(false) { diff --git a/src/plugins/ios/iosrunfactories.cpp b/src/plugins/ios/iosrunfactories.cpp index f2671539050..a160e3d53dd 100644 --- a/src/plugins/ios/iosrunfactories.cpp +++ b/src/plugins/ios/iosrunfactories.cpp @@ -159,16 +159,20 @@ IosRunControlFactory::IosRunControlFactory(QObject *parent) } bool IosRunControlFactory::canRun(RunConfiguration *runConfiguration, - RunMode mode) const + Core::Id mode) const { - if (mode != NormalRunMode && mode != DebugRunMode && mode != QmlProfilerRunMode - && mode != DebugRunModeWithBreakOnMain) + if (mode != ProjectExplorer::Constants::NORMAL_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN + && mode != ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { return false; + } + return qobject_cast(runConfiguration); } RunControl *IosRunControlFactory::create(RunConfiguration *runConfig, - RunMode mode, QString *errorMessage) + Core::Id mode, QString *errorMessage) { Q_ASSERT(canRun(runConfig, mode)); IosRunConfiguration *rc = qobject_cast(runConfig); @@ -181,9 +185,9 @@ RunControl *IosRunControlFactory::create(RunConfiguration *runConfig, activeRunControl->stop(); m_activeRunControls.remove(devId); } - if (mode == NormalRunMode) + if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) res = new Ios::Internal::IosRunControl(rc); - else if (mode == QmlProfilerRunMode) + else if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) res = IosAnalyzeSupport::createAnalyzeRunControl(rc, errorMessage); else res = IosDebugSupport::createDebugRunControl(rc, errorMessage); diff --git a/src/plugins/ios/iosrunfactories.h b/src/plugins/ios/iosrunfactories.h index 51b566c294d..79238c741c2 100644 --- a/src/plugins/ios/iosrunfactories.h +++ b/src/plugins/ios/iosrunfactories.h @@ -81,9 +81,9 @@ public: explicit IosRunControlFactory(QObject *parent = 0); bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode) const override; + Core::Id mode) const override; ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, + Core::Id mode, QString *errorMessage) override; private: mutable QMap > m_activeRunControls; diff --git a/src/plugins/projectexplorer/localapplicationruncontrol.cpp b/src/plugins/projectexplorer/localapplicationruncontrol.cpp index a1596b34b99..1ce1869c7c7 100644 --- a/src/plugins/projectexplorer/localapplicationruncontrol.cpp +++ b/src/plugins/projectexplorer/localapplicationruncontrol.cpp @@ -48,12 +48,12 @@ LocalApplicationRunControlFactory::~LocalApplicationRunControlFactory() { } -bool LocalApplicationRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool LocalApplicationRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { - return mode == NormalRunMode && qobject_cast(runConfiguration); + return mode == Constants::NORMAL_RUN_MODE && qobject_cast(runConfiguration); } -RunControl *LocalApplicationRunControlFactory::create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) +RunControl *LocalApplicationRunControlFactory::create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) { Q_UNUSED(errorMessage) QTC_ASSERT(canRun(runConfiguration, mode), return 0); @@ -72,7 +72,7 @@ RunControl *LocalApplicationRunControlFactory::create(RunConfiguration *runConfi // ApplicationRunControl -LocalApplicationRunControl::LocalApplicationRunControl(RunConfiguration *rc, RunMode mode) +LocalApplicationRunControl::LocalApplicationRunControl(RunConfiguration *rc, Core::Id mode) : RunControl(rc, mode), m_runMode(ApplicationLauncher::Console), m_running(false) { setIcon(QLatin1String(Constants::ICON_RUN_SMALL)); diff --git a/src/plugins/projectexplorer/localapplicationruncontrol.h b/src/plugins/projectexplorer/localapplicationruncontrol.h index dca6a02dd36..40cd52439fa 100644 --- a/src/plugins/projectexplorer/localapplicationruncontrol.h +++ b/src/plugins/projectexplorer/localapplicationruncontrol.h @@ -43,8 +43,8 @@ class LocalApplicationRunControlFactory : public IRunControlFactory public: LocalApplicationRunControlFactory (); ~LocalApplicationRunControlFactory(); - bool canRun(RunConfiguration *runConfiguration, RunMode mode) const; - RunControl* create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage); + bool canRun(RunConfiguration *runConfiguration, Core::Id mode) const; + RunControl* create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage); }; } // namespace Internal @@ -53,7 +53,7 @@ class PROJECTEXPLORER_EXPORT LocalApplicationRunControl : public RunControl { Q_OBJECT public: - LocalApplicationRunControl(RunConfiguration *runConfiguration, RunMode mode); + LocalApplicationRunControl(RunConfiguration *runConfiguration, Core::Id mode); ~LocalApplicationRunControl(); void start(); StopResult stop(); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index ded797906da..3bfd73b1e16 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -203,12 +203,12 @@ public: void deploy(QList); int queue(QList, QList stepIds); void updateContextMenuActions(); - void executeRunConfiguration(RunConfiguration *, RunMode mode); + void executeRunConfiguration(RunConfiguration *, Core::Id mode); QPair buildSettingsEnabledForSession(); QPair buildSettingsEnabled(Project *pro); void addToRecentProjects(const QString &fileName, const QString &displayName); - void startRunControl(RunControl *runControl, RunMode runMode); + void startRunControl(RunControl *runControl, Core::Id runMode); void updateActions(); void updateContext(); @@ -350,9 +350,9 @@ public: QString m_lastOpenDirectory; QPointer m_delayedRunConfiguration; - QList> m_delayedRunConfigurationForRun; + QList> m_delayedRunConfigurationForRun; bool m_shouldHaveRunConfiguration; - RunMode m_runMode; + Core::Id m_runMode; QString m_projectFilterString; MiniProjectTargetSelector * m_targetSelector; ProjectExplorerSettings m_projectExplorerSettings; @@ -373,7 +373,7 @@ public: ProjectExplorerPluginPrivate::ProjectExplorerPluginPrivate() : m_shouldHaveRunConfiguration(false), - m_runMode(NoRunMode), + m_runMode(Constants::NO_RUN_MODE), m_projectsMode(0), m_kitManager(0), m_toolChainManager(0), @@ -1901,7 +1901,7 @@ void ProjectExplorerPluginPrivate::buildStateChanged(Project * pro) } // NBS TODO implement more than one runner -static IRunControlFactory *findRunControlFactory(RunConfiguration *config, RunMode mode) +static IRunControlFactory *findRunControlFactory(RunConfiguration *config, Core::Id mode) { return ExtensionSystem::PluginManager::getObject( [&config, &mode](IRunControlFactory *factory) { @@ -1909,7 +1909,7 @@ static IRunControlFactory *findRunControlFactory(RunConfiguration *config, RunMo }); } -void ProjectExplorerPluginPrivate::executeRunConfiguration(RunConfiguration *runConfiguration, RunMode runMode) +void ProjectExplorerPluginPrivate::executeRunConfiguration(RunConfiguration *runConfiguration, Core::Id runMode) { if (!runConfiguration->isConfigured()) { QString errorMessage; @@ -1947,18 +1947,18 @@ void ProjectExplorerPlugin::showRunErrorMessage(const QString &errorMessage) QMessageBox::critical(ICore::mainWindow(), errorMessage.isNull() ? tr("Unknown error") : tr("Could Not Run"), errorMessage); } -void ProjectExplorerPlugin::startRunControl(RunControl *runControl, RunMode runMode) +void ProjectExplorerPlugin::startRunControl(RunControl *runControl, Core::Id runMode) { dd->startRunControl(runControl, runMode); } -void ProjectExplorerPluginPrivate::startRunControl(RunControl *runControl, RunMode runMode) +void ProjectExplorerPluginPrivate::startRunControl(RunControl *runControl, Core::Id runMode) { m_outputPane->createNewOutputWindow(runControl); m_outputPane->flash(); // one flash for starting m_outputPane->showTabFor(runControl); - bool popup = (runMode == NormalRunMode && dd->m_projectExplorerSettings.showRunOutput) - || ((runMode == DebugRunMode || runMode == DebugRunModeWithBreakOnMain) + bool popup = (runMode == Constants::NORMAL_RUN_MODE && dd->m_projectExplorerSettings.showRunOutput) + || ((runMode == Constants::DEBUG_RUN_MODE || runMode == Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) && m_projectExplorerSettings.showDebugOutput); m_outputPane->setBehaviorOnOutput(runControl, popup ? AppOutputPane::Popup : AppOutputPane::Flash); runControl->start(); @@ -2001,13 +2001,13 @@ void ProjectExplorerPluginPrivate::buildQueueFinished(bool success) } m_delayedRunConfiguration = 0; m_shouldHaveRunConfiguration = false; - m_runMode = NoRunMode; + m_runMode = Constants::NO_RUN_MODE; } void ProjectExplorerPluginPrivate::runConfigurationConfigurationFinished() { RunConfiguration *rc = qobject_cast(sender()); - RunMode runMode = NoRunMode; + Core::Id runMode = Constants::NO_RUN_MODE; for (int i = 0; i < m_delayedRunConfigurationForRun.size(); ++i) { if (m_delayedRunConfigurationForRun.at(i).first == rc) { runMode = m_delayedRunConfigurationForRun.at(i).second; @@ -2015,7 +2015,7 @@ void ProjectExplorerPluginPrivate::runConfigurationConfigurationFinished() break; } } - if (runMode != NoRunMode && rc->isConfigured()) + if (runMode != Constants::NO_RUN_MODE && rc->isConfigured()) executeRunConfiguration(rc, runMode); } @@ -2368,12 +2368,12 @@ void ProjectExplorerPluginPrivate::cleanSession() void ProjectExplorerPluginPrivate::handleRunProject() { - m_instance->runStartupProject(NormalRunMode); + m_instance->runStartupProject(Constants::NORMAL_RUN_MODE); } void ProjectExplorerPluginPrivate::runProjectWithoutDeploy() { - m_instance->runStartupProject(NormalRunMode, true); + m_instance->runStartupProject(Constants::NORMAL_RUN_MODE, true); } void ProjectExplorerPluginPrivate::runProjectContextMenu() @@ -2381,7 +2381,7 @@ void ProjectExplorerPluginPrivate::runProjectContextMenu() Node *node = ProjectTree::currentNode(); ProjectNode *projectNode = node ? node->asProjectNode() : 0; if (projectNode == ProjectTree::currentProject()->rootProjectNode() || !projectNode) { - m_instance->runProject(ProjectTree::currentProject(), NormalRunMode); + m_instance->runProject(ProjectTree::currentProject(), Constants::NORMAL_RUN_MODE); } else { QAction *act = qobject_cast(sender()); if (!act) @@ -2389,7 +2389,7 @@ void ProjectExplorerPluginPrivate::runProjectContextMenu() RunConfiguration *rc = act->data().value(); if (!rc) return; - m_instance->runRunConfiguration(rc, NormalRunMode); + m_instance->runRunConfiguration(rc, Constants::NORMAL_RUN_MODE); } } @@ -2493,7 +2493,7 @@ static bool hasDeploySettings(Project *pro) }); } -void ProjectExplorerPlugin::runProject(Project *pro, RunMode mode, const bool forceSkipDeploy) +void ProjectExplorerPlugin::runProject(Project *pro, Core::Id mode, const bool forceSkipDeploy) { if (!pro) return; @@ -2503,13 +2503,13 @@ void ProjectExplorerPlugin::runProject(Project *pro, RunMode mode, const bool fo runRunConfiguration(rc, mode, forceSkipDeploy); } -void ProjectExplorerPlugin::runStartupProject(RunMode runMode, bool forceSkipDeploy) +void ProjectExplorerPlugin::runStartupProject(Core::Id runMode, bool forceSkipDeploy) { runProject(SessionManager::startupProject(), runMode, forceSkipDeploy); } void ProjectExplorerPlugin::runRunConfiguration(RunConfiguration *rc, - RunMode runMode, + Core::Id runMode, const bool forceSkipDeploy) { if (!rc->isEnabled()) @@ -2680,7 +2680,7 @@ void ProjectExplorerPluginPrivate::updateDeployActions() emit m_instance->updateRunActions(); } -bool ProjectExplorerPlugin::canRun(Project *project, RunMode runMode, QString *whyNot) +bool ProjectExplorerPlugin::canRun(Project *project, Core::Id runMode, QString *whyNot) { if (!project) { if (whyNot) @@ -2747,7 +2747,7 @@ void ProjectExplorerPluginPrivate::slotUpdateRunActions() { Project *project = SessionManager::startupProject(); QString whyNot; - const bool state = ProjectExplorerPlugin::canRun(project, NormalRunMode, &whyNot); + const bool state = ProjectExplorerPlugin::canRun(project, Constants::NORMAL_RUN_MODE, &whyNot); m_runAction->setEnabled(state); m_runAction->setToolTip(whyNot); m_runWithoutDeployAction->setEnabled(state); diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h index e548268f712..61d86e65aaa 100644 --- a/src/plugins/projectexplorer/projectexplorer.h +++ b/src/plugins/projectexplorer/projectexplorer.h @@ -33,6 +33,7 @@ #include "projectexplorer_export.h" #include "projectexplorerconstants.h" +#include "runconfiguration.h" #include @@ -88,7 +89,7 @@ public: static void setProjectExplorerSettings(const Internal::ProjectExplorerSettings &pes); static Internal::ProjectExplorerSettings projectExplorerSettings(); - static void startRunControl(RunControl *runControl, RunMode runMode); + static void startRunControl(RunControl *runControl, Core::Id runMode); static void showRunErrorMessage(const QString &errorMessage); // internal public for FlatModel @@ -97,10 +98,10 @@ public: static bool coreAboutToClose(); static QList > recentProjects(); - static bool canRun(Project *pro, RunMode runMode, QString *whyNot = 0); - static void runProject(Project *pro, RunMode, const bool forceSkipDeploy = false); - static void runStartupProject(RunMode runMode, bool forceSkipDeploy = false); - static void runRunConfiguration(RunConfiguration *rc, RunMode runMode, + static bool canRun(Project *pro, Core::Id runMode, QString *whyNot = 0); + static void runProject(Project *pro, Core::Id, const bool forceSkipDeploy = false); + static void runStartupProject(Core::Id runMode, bool forceSkipDeploy = false); + static void runRunConfiguration(RunConfiguration *rc, Core::Id runMode, const bool forceSkipDeploy = false); static void addExistingFiles(FolderNode *projectNode, const QStringList &filePaths); @@ -128,7 +129,7 @@ signals: // or the file list of a specific project has changed. void fileListChanged(); - void aboutToExecuteProject(ProjectExplorer::Project *project, RunMode runMode); + void aboutToExecuteProject(ProjectExplorer::Project *project, Core::Id runMode); void recentProjectsChanged(); void settingsChanged(); diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h index 37a346332ca..c6ec2b89cf8 100644 --- a/src/plugins/projectexplorer/projectexplorerconstants.h +++ b/src/plugins/projectexplorer/projectexplorerconstants.h @@ -267,22 +267,14 @@ const char SHOW_FILE_FILTER_DEFAULT[] = "*.c; *.cc; *.cpp; *.cp; *.cxx; *.c++; * const char PAGE_ID_PREFIX[] = "PE.Wizard.Page."; const char GENERATOR_ID_PREFIX[] = "PE.Wizard.Generator."; +// RunMode +const char NO_RUN_MODE[]="RunConfiguration.NoRunMode"; +const char NORMAL_RUN_MODE[]="RunConfiguration.NormalRunMode"; +const char QML_PROFILER_RUN_MODE[]="RunConfiguration.QmlProfilerRunMode"; +const char DEBUG_RUN_MODE[]="RunConfiguration.DebugRunMode"; +const char DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN[]="RunConfiguration.DebugRunModeWithBreakOnMain"; + } // namespace Constants - -// Run modes -enum RunMode { - NoRunMode, - NormalRunMode, - DebugRunMode, - DebugRunModeWithBreakOnMain, - QmlProfilerRunMode, - CallgrindRunMode, - MemcheckRunMode, - MemcheckWithGdbRunMode, - ClangStaticAnalyzerMode, - PerfProfilerRunMode -}; - } // namespace ProjectExplorer #endif // PROJECTEXPLORERCONSTANTS_H diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 12f044677e4..8c3fdf8254c 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -51,7 +51,7 @@ #include #endif -using namespace ProjectExplorer; +namespace ProjectExplorer { /*! \class ProjectExplorer::ProcessHandle @@ -515,7 +515,7 @@ IRunConfigurationAspect *IRunControlFactory::createRunConfigurationAspect(RunCon than it needs to be. */ -RunControl::RunControl(RunConfiguration *runConfiguration, RunMode mode) +RunControl::RunControl(RunConfiguration *runConfiguration, Core::Id mode) : m_runMode(mode), m_runConfiguration(runConfiguration), m_outputFormatter(0) { if (runConfiguration) { @@ -537,7 +537,7 @@ Utils::OutputFormatter *RunControl::outputFormatter() return m_outputFormatter; } -RunMode RunControl::runMode() const +Core::Id RunControl::runMode() const { return m_runMode; } @@ -663,3 +663,5 @@ void RunControl::appendMessage(const QString &msg, Utils::OutputFormat format) { emit appendMessage(this, msg, format); } + +} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index 43890d3ad99..ff511a84a79 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -253,8 +253,8 @@ public: explicit IRunControlFactory(QObject *parent = 0); virtual ~IRunControlFactory(); - virtual bool canRun(RunConfiguration *runConfiguration, RunMode mode) const = 0; - virtual RunControl *create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) = 0; + virtual bool canRun(RunConfiguration *runConfiguration, Core::Id mode) const = 0; + virtual RunControl *create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) = 0; virtual IRunConfigurationAspect *createRunConfigurationAspect(RunConfiguration *rc); }; @@ -283,7 +283,7 @@ public: AsynchronousStop // Stop sequence has been started }; - RunControl(RunConfiguration *runConfiguration, RunMode mode); + RunControl(RunConfiguration *runConfiguration, Core::Id mode); virtual ~RunControl(); virtual void start() = 0; @@ -304,7 +304,7 @@ public: bool sameRunConfiguration(const RunControl *other) const; Utils::OutputFormatter *outputFormatter(); - RunMode runMode() const; + Core::Id runMode() const; public slots: void bringApplicationToForeground(qint64 pid); @@ -328,7 +328,7 @@ protected: private: QString m_displayName; - RunMode m_runMode; + Core::Id m_runMode; QString m_icon; const QPointer m_runConfiguration; Utils::OutputFormatter *m_outputFormatter; diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp index 4484ed14a9c..eab59f24f62 100644 --- a/src/plugins/pythoneditor/pythoneditorplugin.cpp +++ b/src/plugins/pythoneditor/pythoneditorplugin.cpp @@ -406,7 +406,7 @@ private: class PythonRunControl : public RunControl { public: - PythonRunControl(PythonRunConfiguration *runConfiguration, RunMode mode); + PythonRunControl(PythonRunConfiguration *runConfiguration, Core::Id mode); void start(); StopResult stop(); @@ -1098,16 +1098,16 @@ bool PythonProjectNode::renameFile(const QString &filePath, const QString &newFi class PythonRunControlFactory : public IRunControlFactory { public: - bool canRun(RunConfiguration *runConfiguration, RunMode mode) const; - RunControl *create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage); + bool canRun(RunConfiguration *runConfiguration, Core::Id mode) const; + RunControl *create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage); }; -bool PythonRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool PythonRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { - return mode == NormalRunMode && dynamic_cast(runConfiguration); + return mode == ProjectExplorer::Constants::NORMAL_RUN_MODE && dynamic_cast(runConfiguration); } -RunControl *PythonRunControlFactory::create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) +RunControl *PythonRunControlFactory::create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) { Q_UNUSED(errorMessage) QTC_ASSERT(canRun(runConfiguration, mode), return 0); @@ -1116,7 +1116,7 @@ RunControl *PythonRunControlFactory::create(RunConfiguration *runConfiguration, // PythonRunControl -PythonRunControl::PythonRunControl(PythonRunConfiguration *rc, RunMode mode) +PythonRunControl::PythonRunControl(PythonRunConfiguration *rc, Core::Id mode) : RunControl(rc, mode), m_running(false) { setIcon(QLatin1String(ProjectExplorer::Constants::ICON_RUN_SMALL)); diff --git a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp index 283e1f3b836..adb1db87dc1 100644 --- a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp @@ -71,7 +71,7 @@ bool QmlProfilerPlugin::initialize(const QStringList &arguments, QString *errorS action->setWidgetCreator(widgetCreator); action->setRunControlCreator(runControlCreator); action->setToolPreparer([tool] { return tool->prepareTool(); }); - action->setRunMode(ProjectExplorer::QmlProfilerRunMode); + action->setRunMode(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); action->setText(tr("QML Profiler")); action->setToolTip(description); action->setMenuGroup(Constants::G_ANALYZER_TOOLS); @@ -84,7 +84,7 @@ bool QmlProfilerPlugin::initialize(const QStringList &arguments, QString *errorS action->setRunControlCreator(runControlCreator); action->setCustomToolStarter([tool] { tool->startRemoteTool(); }); action->setToolPreparer([tool] { return tool->prepareTool(); }); - action->setRunMode(ProjectExplorer::QmlProfilerRunMode); + action->setRunMode(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); action->setText(tr("QML Profiler (External)")); action->setToolTip(description); action->setMenuGroup(Constants::G_ANALYZER_REMOTE_TOOLS); diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp index a5ea4fa0032..6fc364d347f 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp @@ -57,9 +57,9 @@ QmlProfilerRunControlFactory::QmlProfilerRunControlFactory(QObject *parent) : { } -bool QmlProfilerRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool QmlProfilerRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { - return mode == QmlProfilerRunMode + return mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE && (qobject_cast(runConfiguration)); } @@ -83,7 +83,7 @@ static AnalyzerStartParameters createQmlProfilerStartParameters(RunConfiguration return sp; } -RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) +RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) { QTC_ASSERT(canRun(runConfiguration, mode), return 0); diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.h b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.h index f5513c98cae..269895b36cd 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.h +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.h @@ -45,10 +45,10 @@ public: explicit QmlProfilerRunControlFactory(QObject *parent = 0); // IRunControlFactory implementation - bool canRun(RunConfiguration *runConfiguration, ProjectExplorer::RunMode mode) const; + bool canRun(RunConfiguration *runConfiguration, Core::Id mode) const; ProjectExplorer::RunControl *create(RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, + Core::Id mode, QString *errorMessage); }; diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index f565557200a..c0518cc613e 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -486,7 +486,7 @@ void QmlProfilerTool::startRemoteTool() sp.analyzerPort = port; AnalyzerRunControl *rc = createRunControl(sp, 0); - ProjectExplorerPlugin::startRunControl(rc, QmlProfilerRunMode); + ProjectExplorerPlugin::startRunControl(rc, ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); } void QmlProfilerTool::logState(const QString &msg) diff --git a/src/plugins/qnx/qnxattachdebugsupport.cpp b/src/plugins/qnx/qnxattachdebugsupport.cpp index dac8912da41..3bb3f271a98 100644 --- a/src/plugins/qnx/qnxattachdebugsupport.cpp +++ b/src/plugins/qnx/qnxattachdebugsupport.cpp @@ -135,7 +135,7 @@ void QnxAttachDebugSupport::attachToProcess() } connect(runControl, &Debugger::DebuggerRunControl::stateChanged, this, &QnxAttachDebugSupport::handleDebuggerStateChanged); - ProjectExplorer::ProjectExplorerPlugin::startRunControl(runControl, ProjectExplorer::DebugRunMode); + ProjectExplorer::ProjectExplorerPlugin::startRunControl(runControl, ProjectExplorer::Constants::DEBUG_RUN_MODE); } void QnxAttachDebugSupport::handleDebuggerStateChanged(Debugger::DebuggerState state) diff --git a/src/plugins/qnx/qnxruncontrolfactory.cpp b/src/plugins/qnx/qnxruncontrolfactory.cpp index 2e943e0a1ba..ee5c37044c1 100644 --- a/src/plugins/qnx/qnxruncontrolfactory.cpp +++ b/src/plugins/qnx/qnxruncontrolfactory.cpp @@ -95,7 +95,7 @@ static DebuggerStartParameters createDebuggerStartParameters(QnxRunConfiguration return params; } -static AnalyzerStartParameters createAnalyzerStartParameters(const QnxRunConfiguration *runConfig, RunMode mode) +static AnalyzerStartParameters createAnalyzerStartParameters(const QnxRunConfiguration *runConfig, Core::Id mode) { AnalyzerStartParameters params; Target *target = runConfig->target(); @@ -125,10 +125,13 @@ QnxRunControlFactory::QnxRunControlFactory(QObject *parent) { } -bool QnxRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool QnxRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { - if (mode != NormalRunMode && mode != DebugRunMode && mode != QmlProfilerRunMode) + if (mode != ProjectExplorer::Constants::NORMAL_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE + && mode != ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { return false; + } if (!runConfiguration->isEnabled() || !runConfiguration->id().name().startsWith(Constants::QNX_QNX_RUNCONFIGURATION_PREFIX)) { @@ -141,22 +144,22 @@ bool QnxRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mo if (dev.isNull()) return false; - if (mode == DebugRunMode || mode == QmlProfilerRunMode) + if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE || mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) return rc->portsUsedByDebuggers() <= dev->freePorts().count(); return true; } -RunControl *QnxRunControlFactory::create(RunConfiguration *runConfig, RunMode mode, QString *errorMessage) +RunControl *QnxRunControlFactory::create(RunConfiguration *runConfig, Core::Id mode, QString *errorMessage) { Q_ASSERT(canRun(runConfig, mode)); QnxRunConfiguration *rc = qobject_cast(runConfig); Q_ASSERT(rc); - switch (mode) { - case NormalRunMode: + if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) return new QnxRunControl(rc); - case DebugRunMode: { + + if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE) { const DebuggerStartParameters params = createDebuggerStartParameters(rc); DebuggerRunControl *runControl = createDebuggerRunControl(params, runConfig, errorMessage); if (!runControl) @@ -167,21 +170,15 @@ RunControl *QnxRunControlFactory::create(RunConfiguration *runConfig, RunMode mo return runControl; } - case QmlProfilerRunMode: { + + if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { const AnalyzerStartParameters params = createAnalyzerStartParameters(rc, mode); AnalyzerRunControl *runControl = AnalyzerManager::createRunControl(params, runConfig); QnxAnalyzeSupport * const analyzeSupport = new QnxAnalyzeSupport(rc, runControl); connect(runControl, SIGNAL(finished()), analyzeSupport, SLOT(handleProfilingFinished())); return runControl; } - case PerfProfilerRunMode: - case NoRunMode: - case CallgrindRunMode: - case MemcheckRunMode: - case MemcheckWithGdbRunMode: - case ClangStaticAnalyzerMode: - case DebugRunModeWithBreakOnMain: - QTC_ASSERT(false, return 0); - } + + QTC_CHECK(false); return 0; } diff --git a/src/plugins/qnx/qnxruncontrolfactory.h b/src/plugins/qnx/qnxruncontrolfactory.h index afd6e6a585e..f3753f49b85 100644 --- a/src/plugins/qnx/qnxruncontrolfactory.h +++ b/src/plugins/qnx/qnxruncontrolfactory.h @@ -46,9 +46,9 @@ public: explicit QnxRunControlFactory(QObject *parent = 0); bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode) const; + Core::Id mode) const; ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, QString *errorMessage); + Core::Id mode, QString *errorMessage); }; } // namespace Internal diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp index ea2020e15e6..a7316280e94 100644 --- a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp +++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp @@ -56,9 +56,9 @@ namespace Internal { class RemoteLinuxAnalyzeSupportPrivate { public: - RemoteLinuxAnalyzeSupportPrivate(AnalyzerRunControl *rc, RunMode runMode) + RemoteLinuxAnalyzeSupportPrivate(AnalyzerRunControl *rc, Core::Id runMode) : runControl(rc), - qmlProfiling(runMode == QmlProfilerRunMode), + qmlProfiling(runMode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE), qmlPort(-1) { } @@ -75,7 +75,7 @@ public: using namespace Internal; AnalyzerStartParameters RemoteLinuxAnalyzeSupport::startParameters(const RunConfiguration *runConfig, - RunMode runMode) + Core::Id runMode) { AnalyzerStartParameters params; params.runMode = runMode; @@ -88,7 +88,7 @@ AnalyzerStartParameters RemoteLinuxAnalyzeSupport::startParameters(const RunConf } RemoteLinuxAnalyzeSupport::RemoteLinuxAnalyzeSupport(AbstractRemoteLinuxRunConfiguration *runConfig, - AnalyzerRunControl *engine, RunMode runMode) + AnalyzerRunControl *engine, Core::Id runMode) : AbstractRemoteLinuxRunSupport(runConfig, engine), d(new RemoteLinuxAnalyzeSupportPrivate(engine, runMode)) { diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.h b/src/plugins/remotelinux/remotelinuxanalyzesupport.h index 20ff11d802d..b5e3694af48 100644 --- a/src/plugins/remotelinux/remotelinuxanalyzesupport.h +++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.h @@ -53,10 +53,10 @@ class REMOTELINUX_EXPORT RemoteLinuxAnalyzeSupport : public AbstractRemoteLinuxR Q_OBJECT public: static Analyzer::AnalyzerStartParameters startParameters(const ProjectExplorer::RunConfiguration *runConfig, - ProjectExplorer::RunMode runMode); + Core::Id runMode); RemoteLinuxAnalyzeSupport(AbstractRemoteLinuxRunConfiguration *runConfig, - Analyzer::AnalyzerRunControl *engine, ProjectExplorer::RunMode runMode); + Analyzer::AnalyzerRunControl *engine, Core::Id runMode); ~RemoteLinuxAnalyzeSupport(); protected: diff --git a/src/plugins/remotelinux/remotelinuxruncontrol.cpp b/src/plugins/remotelinux/remotelinuxruncontrol.cpp index 4d359f82673..7525ba93b23 100644 --- a/src/plugins/remotelinux/remotelinuxruncontrol.cpp +++ b/src/plugins/remotelinux/remotelinuxruncontrol.cpp @@ -57,7 +57,7 @@ public: }; RemoteLinuxRunControl::RemoteLinuxRunControl(RunConfiguration *rc) - : RunControl(rc, NormalRunMode), d(new RemoteLinuxRunControlPrivate) + : RunControl(rc, ProjectExplorer::Constants::NORMAL_RUN_MODE), d(new RemoteLinuxRunControlPrivate) { setIcon(QLatin1String(ProjectExplorer::Constants::ICON_RUN_SMALL)); diff --git a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp index e933918b7d7..3053e39027f 100644 --- a/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp +++ b/src/plugins/remotelinux/remotelinuxruncontrolfactory.cpp @@ -63,10 +63,12 @@ RemoteLinuxRunControlFactory::~RemoteLinuxRunControlFactory() { } -bool RemoteLinuxRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool RemoteLinuxRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { - if (mode != NormalRunMode && mode != DebugRunMode && mode != DebugRunModeWithBreakOnMain - && mode != QmlProfilerRunMode) { + if (mode != ProjectExplorer::Constants::NORMAL_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE + && mode != ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN + && mode != ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { return false; } @@ -76,16 +78,16 @@ bool RemoteLinuxRunControlFactory::canRun(RunConfiguration *runConfiguration, Ru || id.name().startsWith(RemoteLinuxRunConfiguration::IdPrefix)); } -RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, RunMode mode, +RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Core::Id mode, QString *errorMessage) { QTC_ASSERT(canRun(runConfig, mode), return 0); - switch (mode) { - case NormalRunMode: + if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) return new RemoteLinuxRunControl(runConfig); - case DebugRunMode: - case DebugRunModeWithBreakOnMain: { + + if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE + || mode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) { IDevice::ConstPtr dev = DeviceKitInformation::device(runConfig->target()->kit()); if (!dev) { *errorMessage = tr("Cannot debug: Kit has no device."); @@ -112,7 +114,8 @@ RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Ru connect(runControl, SIGNAL(finished()), debugSupport, SLOT(handleDebuggingFinished())); return runControl; } - case QmlProfilerRunMode: { + + if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) { AnalyzerStartParameters params = RemoteLinuxAnalyzeSupport::startParameters(runConfig, mode); auto * const rc = qobject_cast(runConfig); QTC_ASSERT(rc, return 0); @@ -120,16 +123,8 @@ RunControl *RemoteLinuxRunControlFactory::create(RunConfiguration *runConfig, Ru (void) new RemoteLinuxAnalyzeSupport(rc, runControl, mode); return runControl; } - case PerfProfilerRunMode: - case NoRunMode: - case CallgrindRunMode: - case MemcheckRunMode: - case MemcheckWithGdbRunMode: - case ClangStaticAnalyzerMode: - QTC_ASSERT(false, return 0); - } - QTC_ASSERT(false, return 0); + QTC_CHECK(false); return 0; } diff --git a/src/plugins/remotelinux/remotelinuxruncontrolfactory.h b/src/plugins/remotelinux/remotelinuxruncontrolfactory.h index b8a8aa34504..fb8828248e9 100644 --- a/src/plugins/remotelinux/remotelinuxruncontrolfactory.h +++ b/src/plugins/remotelinux/remotelinuxruncontrolfactory.h @@ -43,9 +43,9 @@ public: ~RemoteLinuxRunControlFactory(); bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode) const; + Core::Id mode) const; ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, QString *errorMessage); + Core::Id mode, QString *errorMessage); }; } // namespace Internal diff --git a/src/plugins/valgrind/callgrindtool.h b/src/plugins/valgrind/callgrindtool.h index 0018ecab2aa..0ef8905c6ba 100644 --- a/src/plugins/valgrind/callgrindtool.h +++ b/src/plugins/valgrind/callgrindtool.h @@ -41,6 +41,8 @@ const char CallgrindLocalActionId[] = "Callgrind.Local"; const char CallgrindRemoteActionId[] = "Callgrind.Remote"; class ValgrindRunControl; +const char CALLGRIND_RUN_MODE[] = "CallgrindTool.CallgrindRunMode"; + class CallgrindToolPrivate; class CallgrindTool : public QObject diff --git a/src/plugins/valgrind/memchecktool.h b/src/plugins/valgrind/memchecktool.h index 6e9cdaae1c8..2f0f593e7d9 100644 --- a/src/plugins/valgrind/memchecktool.h +++ b/src/plugins/valgrind/memchecktool.h @@ -50,6 +50,10 @@ class Error; } namespace Valgrind { + +const char MEMCHECK_RUN_MODE[] = "MemcheckTool.MemcheckRunMode"; +const char MEMCHECK_WITH_GDB_RUN_MODE[] = "MemcheckTool.MemcheckWithGdbRunMode"; + namespace Internal { class FrameFinder; @@ -57,6 +61,7 @@ class MemcheckErrorView; class MemcheckRunControl; class ValgrindBaseSettings; + class MemcheckErrorFilterProxyModel : public QSortFilterProxyModel { Q_OBJECT diff --git a/src/plugins/valgrind/valgrindplugin.cpp b/src/plugins/valgrind/valgrindplugin.cpp index f8efdf33527..f92b648230e 100644 --- a/src/plugins/valgrind/valgrindplugin.cpp +++ b/src/plugins/valgrind/valgrindplugin.cpp @@ -54,7 +54,6 @@ #include #include -#include #include @@ -166,7 +165,7 @@ void ValgrindPlugin::extensionsInitialized() action->setWidgetCreator(mcWidgetCreator); action->setRunControlCreator(mcRunControlCreator); action->setToolMode(DebugMode); - action->setRunMode(ProjectExplorer::MemcheckRunMode); + action->setRunMode(MEMCHECK_RUN_MODE); action->setText(tr("Valgrind Memory Analyzer")); action->setToolTip(memcheckToolTip); action->setMenuGroup(Analyzer::Constants::G_ANALYZER_TOOLS); @@ -182,7 +181,7 @@ void ValgrindPlugin::extensionsInitialized() action->setRunControlCreator(std::bind(&MemcheckWithGdbTool::createRunControl, mcgTool, _1, _2)); action->setToolMode(DebugMode); - action->setRunMode(ProjectExplorer::MemcheckWithGdbRunMode); + action->setRunMode(MEMCHECK_WITH_GDB_RUN_MODE); action->setText(tr("Valgrind Memory Analyzer with GDB")); action->setToolTip(tr("Valgrind Analyze Memory with GDB uses the " "Memcheck tool to find memory leaks.\nWhen a problem is detected, " @@ -197,7 +196,7 @@ void ValgrindPlugin::extensionsInitialized() action->setWidgetCreator(cgWidgetCreator); action->setRunControlCreator(cgRunControlCreator); action->setToolMode(ReleaseMode); - action->setRunMode(CallgrindRunMode); + action->setRunMode(CALLGRIND_RUN_MODE); action->setText(tr("Valgrind Function Profiler")); action->setToolTip(callgrindToolTip); action->setMenuGroup(Analyzer::Constants::G_ANALYZER_TOOLS); @@ -216,7 +215,7 @@ void ValgrindPlugin::extensionsInitialized() ValgrindRunControl *rc = mcTool->createRunControl(sp, 0); QTC_ASSERT(rc, return); rc->setCustomStart(); - ProjectExplorerPlugin::startRunControl(rc, MemcheckRunMode); + ProjectExplorerPlugin::startRunControl(rc, MEMCHECK_RUN_MODE); }); action->setText(tr("Valgrind Memory Analyzer (External Remote Application)")); action->setToolTip(memcheckToolTip); @@ -234,7 +233,7 @@ void ValgrindPlugin::extensionsInitialized() ValgrindRunControl *rc = cgTool->createRunControl(sp, 0); QTC_ASSERT(rc, return); rc->setCustomStart(); - ProjectExplorerPlugin::startRunControl(rc, CallgrindRunMode); + ProjectExplorerPlugin::startRunControl(rc, CALLGRIND_RUN_MODE); }); action->setText(tr("Valgrind Function Profiler (External Remote Application)")); diff --git a/src/plugins/valgrind/valgrindplugin.h b/src/plugins/valgrind/valgrindplugin.h index 912c3ce5023..a53152903ff 100644 --- a/src/plugins/valgrind/valgrindplugin.h +++ b/src/plugins/valgrind/valgrindplugin.h @@ -34,6 +34,7 @@ #include #include +#include namespace Valgrind { namespace Internal { diff --git a/src/plugins/valgrind/valgrindruncontrolfactory.cpp b/src/plugins/valgrind/valgrindruncontrolfactory.cpp index 23b393d2bb8..32f214b2ece 100644 --- a/src/plugins/valgrind/valgrindruncontrolfactory.cpp +++ b/src/plugins/valgrind/valgrindruncontrolfactory.cpp @@ -31,6 +31,8 @@ #include "valgrindruncontrolfactory.h" #include "valgrindsettings.h" #include "valgrindplugin.h" +#include "callgrindtool.h" +#include "memchecktool.h" #include #include @@ -62,13 +64,13 @@ ValgrindRunControlFactory::ValgrindRunControlFactory(QObject *parent) : { } -bool ValgrindRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool ValgrindRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id mode) const { Q_UNUSED(runConfiguration); - return mode == CallgrindRunMode || mode == MemcheckRunMode || mode == MemcheckWithGdbRunMode; + return mode == CALLGRIND_RUN_MODE || mode == MEMCHECK_RUN_MODE || mode == MEMCHECK_WITH_GDB_RUN_MODE; } -RunControl *ValgrindRunControlFactory::create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) +RunControl *ValgrindRunControlFactory::create(RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) { Q_UNUSED(errorMessage); diff --git a/src/plugins/valgrind/valgrindruncontrolfactory.h b/src/plugins/valgrind/valgrindruncontrolfactory.h index 2b04b33b46f..6c306325396 100644 --- a/src/plugins/valgrind/valgrindruncontrolfactory.h +++ b/src/plugins/valgrind/valgrindruncontrolfactory.h @@ -45,10 +45,10 @@ public: explicit ValgrindRunControlFactory(QObject *parent = 0); // IRunControlFactory implementation - bool canRun(RunConfiguration *runConfiguration, ProjectExplorer::RunMode mode) const; + bool canRun(RunConfiguration *runConfiguration, Core::Id mode) const; ProjectExplorer::RunControl *create(RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, + Core::Id mode, QString *errorMessage); ProjectExplorer::IRunConfigurationAspect *createRunConfigurationAspect(ProjectExplorer::RunConfiguration *rc); }; diff --git a/src/plugins/winrt/winrtdebugsupport.cpp b/src/plugins/winrt/winrtdebugsupport.cpp index 85b56b91c44..0f25380fc82 100644 --- a/src/plugins/winrt/winrtdebugsupport.cpp +++ b/src/plugins/winrt/winrtdebugsupport.cpp @@ -68,7 +68,7 @@ void WinRtDebugSupport::finish() } RunControl *WinRtDebugSupport::createDebugRunControl(WinRtRunConfiguration *runConfig, - RunMode mode, + Core::Id mode, QString *errorMessage) { // FIXME: This is just working for local debugging; diff --git a/src/plugins/winrt/winrtdebugsupport.h b/src/plugins/winrt/winrtdebugsupport.h index 4b5d8d5cf3e..f92281beb27 100644 --- a/src/plugins/winrt/winrtdebugsupport.h +++ b/src/plugins/winrt/winrtdebugsupport.h @@ -47,7 +47,7 @@ class WinRtDebugSupport : public QObject Q_OBJECT public: static ProjectExplorer::RunControl *createDebugRunControl(WinRtRunConfiguration *runConfig, - ProjectExplorer::RunMode mode, + Core::Id mode, QString *errorMessage); ~WinRtDebugSupport(); diff --git a/src/plugins/winrt/winrtruncontrol.cpp b/src/plugins/winrt/winrtruncontrol.cpp index 6e0b41d0f4e..fed9db96350 100644 --- a/src/plugins/winrt/winrtruncontrol.cpp +++ b/src/plugins/winrt/winrtruncontrol.cpp @@ -48,13 +48,13 @@ using ProjectExplorer::DeviceKitInformation; using ProjectExplorer::IDevice; using ProjectExplorer::RunControl; -using ProjectExplorer::RunMode; +using Core::Id; using ProjectExplorer::Target; namespace WinRt { namespace Internal { -WinRtRunControl::WinRtRunControl(WinRtRunConfiguration *runConfiguration, RunMode mode) +WinRtRunControl::WinRtRunControl(WinRtRunConfiguration *runConfiguration, Core::Id mode) : RunControl(runConfiguration, mode) , m_runConfiguration(runConfiguration) , m_state(StoppedState) diff --git a/src/plugins/winrt/winrtruncontrol.h b/src/plugins/winrt/winrtruncontrol.h index 9b63fe89c32..ed25928687b 100644 --- a/src/plugins/winrt/winrtruncontrol.h +++ b/src/plugins/winrt/winrtruncontrol.h @@ -54,7 +54,7 @@ class WinRtRunControl : public ProjectExplorer::RunControl { Q_OBJECT public: - explicit WinRtRunControl(WinRtRunConfiguration *runConfiguration, ProjectExplorer::RunMode mode); + explicit WinRtRunControl(WinRtRunConfiguration *runConfiguration, Core::Id mode); void start(); StopResult stop(); diff --git a/src/plugins/winrt/winrtrunfactories.cpp b/src/plugins/winrt/winrtrunfactories.cpp index 14336fb5306..859ca9c1b44 100644 --- a/src/plugins/winrt/winrtrunfactories.cpp +++ b/src/plugins/winrt/winrtrunfactories.cpp @@ -137,7 +137,7 @@ WinRtRunControlFactory::WinRtRunControlFactory() } bool WinRtRunControlFactory::canRun(RunConfiguration *runConfiguration, - RunMode mode) const + Core::Id mode) const { if (!runConfiguration) return false; @@ -145,35 +145,32 @@ bool WinRtRunControlFactory::canRun(RunConfiguration *runConfiguration, if (!device) return false; - switch (mode) { - case DebugRunMode: - case DebugRunModeWithBreakOnMain: + if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE + || mode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) { if (device->type() != Constants::WINRT_DEVICE_TYPE_LOCAL) return false; - // fall through - case NormalRunMode: return qobject_cast(runConfiguration); - default: - return false; } + + if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) + return qobject_cast(runConfiguration); + + return false; } RunControl *WinRtRunControlFactory::create( - RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) + RunConfiguration *runConfiguration, Core::Id mode, QString *errorMessage) { WinRtRunConfiguration *rc = qobject_cast(runConfiguration); QTC_ASSERT(rc, return 0); - switch (mode) { - case NormalRunMode: + if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) return new WinRtRunControl(rc, mode); - case DebugRunMode: - case DebugRunModeWithBreakOnMain: + + if (mode == ProjectExplorer::Constants::DEBUG_RUN_MODE || mode == ProjectExplorer::Constants::DEBUG_RUN_MODE_WITH_BREAK_ON_MAIN) return WinRtDebugSupport::createDebugRunControl(rc, mode, errorMessage); - default: - break; - } - *errorMessage = tr("Unsupported run mode %1.").arg(mode); + + *errorMessage = tr("Unsupported run mode %1.").arg(mode.toString()); return 0; } diff --git a/src/plugins/winrt/winrtrunfactories.h b/src/plugins/winrt/winrtrunfactories.h index 0e310e88d78..b77868bab34 100644 --- a/src/plugins/winrt/winrtrunfactories.h +++ b/src/plugins/winrt/winrtrunfactories.h @@ -64,9 +64,9 @@ class WinRtRunControlFactory : public ProjectExplorer::IRunControlFactory public: WinRtRunControlFactory(); bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode) const; + Core::Id mode) const; ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, - ProjectExplorer::RunMode mode, QString *errorMessage); + Core::Id mode, QString *errorMessage); QString displayName() const; }; From ccb930e29246e9fd4b56bebcb9e1b9ee29e0ee94 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 30 Jun 2015 08:25:19 +0200 Subject: [PATCH 089/113] Make sure all pages fit into installer wizard height Copy the hard-coded heights from the Qt installer. Otherwise the Qt Account page texts do not fit the default height, and the text is cut off at the bottom. Change-Id: I290a69ce6cbb57f4f63ff54728a9400253407ffb Reviewed-by: Eike Ziller --- dist/installer/ifw/config/config-linux.xml.in | 1 + dist/installer/ifw/config/config-mac.xml.in | 1 + dist/installer/ifw/config/config-windows.xml.in | 1 + 3 files changed, 3 insertions(+) diff --git a/dist/installer/ifw/config/config-linux.xml.in b/dist/installer/ifw/config/config-linux.xml.in index b0a1c70f03e..21cd64a425b 100644 --- a/dist/installer/ifw/config/config-linux.xml.in +++ b/dist/installer/ifw/config/config-linux.xml.in @@ -8,6 +8,7 @@ logo.png watermark.png + 520 QtCreatorUninstaller @homeDir@/qtcreator-{version} diff --git a/dist/installer/ifw/config/config-mac.xml.in b/dist/installer/ifw/config/config-mac.xml.in index ed7a6dfdb73..e3ecc20ed92 100644 --- a/dist/installer/ifw/config/config-mac.xml.in +++ b/dist/installer/ifw/config/config-mac.xml.in @@ -8,6 +8,7 @@ logo.png background.png + 560 Uninstall Qt Creator @homeDir@/Applications/Qt Creator {version} diff --git a/dist/installer/ifw/config/config-windows.xml.in b/dist/installer/ifw/config/config-windows.xml.in index d7dada04943..33c29dd5941 100644 --- a/dist/installer/ifw/config/config-windows.xml.in +++ b/dist/installer/ifw/config/config-windows.xml.in @@ -8,6 +8,7 @@ logo.png watermark.png + 560 QtCreatorUninst @rootDir@/Qt/qtcreator-{version} From b9b1f89ea9cad6dce4dfec051ae30e6458fde9dc Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 29 Jun 2015 14:49:40 +0200 Subject: [PATCH 090/113] Doc: update the mobile application tutorial Update text to match the template and UI. Use the \example command instead of \page to have qdoc generate HTML files from the example files. This requires also adding the .pro file. Add an SVG image to the sources and link to it from the text. Change-Id: Ib90798386ee082c9ea2a405b33a4f2a5996a9d2a Reviewed-by: Tim Jenssen --- doc/config/qtcreator-project.qdocconf | 2 +- doc/examples/accelbubble/Bluebubble.svg | 10 +++ doc/examples/accelbubble/accelbubble.pro | 14 +++ doc/examples/accelbubble/main.qml | 32 +++---- .../qtquick/creator-mobile-app-tutorial.qdoc | 89 ++++++++----------- doc/src/qtquick/qtquick-uiforms-tutorial.qdoc | 2 +- doc/src/widgets/qtdesigner-app-tutorial.qdoc | 2 +- 7 files changed, 80 insertions(+), 71 deletions(-) create mode 100644 doc/examples/accelbubble/Bluebubble.svg create mode 100644 doc/examples/accelbubble/accelbubble.pro diff --git a/doc/config/qtcreator-project.qdocconf b/doc/config/qtcreator-project.qdocconf index fbe1054e0df..7b1976f0c64 100644 --- a/doc/config/qtcreator-project.qdocconf +++ b/doc/config/qtcreator-project.qdocconf @@ -7,7 +7,7 @@ sourcedirs = $SRCDIR/src imagedirs = $SRCDIR/images $SRCDIR/templates/images outputdir = $OUTDIR exampledirs = $SRCDIR/examples -examples.fileextensions += *.qml +examples.fileextensions += *.qml *.svg HTML.extraimages = images/commercial.png qhp.QtCreator.extraFiles = images/commercial.png diff --git a/doc/examples/accelbubble/Bluebubble.svg b/doc/examples/accelbubble/Bluebubble.svg new file mode 100644 index 00000000000..d9c406c478a --- /dev/null +++ b/doc/examples/accelbubble/Bluebubble.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/doc/examples/accelbubble/accelbubble.pro b/doc/examples/accelbubble/accelbubble.pro new file mode 100644 index 00000000000..8dcac29df2b --- /dev/null +++ b/doc/examples/accelbubble/accelbubble.pro @@ -0,0 +1,14 @@ +TEMPLATE = app + +QT += qml quick widgets + +SOURCES += main.cpp + +RESOURCES += qml.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Default rules for deployment. +include(deployment.pri) + diff --git a/doc/examples/accelbubble/main.qml b/doc/examples/accelbubble/main.qml index 10d7aa99080..02cc2f653d0 100644 --- a/doc/examples/accelbubble/main.qml +++ b/doc/examples/accelbubble/main.qml @@ -35,8 +35,8 @@ ** **************************************************************************/ -import QtQuick 2.2 -import QtQuick.Controls 1.1 +import QtQuick 2.5 +import QtQuick.Controls 1.4 import QtSensors 5.0 @@ -47,6 +47,20 @@ ApplicationWindow { height: 480 visible: true + menuBar: MenuBar { + Menu { + title: qsTr("File") + MenuItem { + text: qsTr("&Open") + onTriggered: console.log("Open action triggered"); + } + MenuItem { + text: qsTr("Exit") + onTriggered: Qt.quit(); + } + } + } + Image { id: bubble source: "Bluebubble.svg" @@ -105,18 +119,4 @@ ApplicationWindow { function calcRoll(x, y, z) { return -(Math.atan(x / Math.sqrt(y * y + z * z)) * 57.2957795); } - - menuBar: MenuBar { - Menu { - title: qsTr("File") - MenuItem { - text: qsTr("&Open") - onTriggered: console.log("Open action triggered"); - } - MenuItem { - text: qsTr("Exit") - onTriggered: Qt.quit(); - } - } - } } diff --git a/doc/src/qtquick/creator-mobile-app-tutorial.qdoc b/doc/src/qtquick/creator-mobile-app-tutorial.qdoc index 27c1fc60cd5..2110e822d58 100644 --- a/doc/src/qtquick/creator-mobile-app-tutorial.qdoc +++ b/doc/src/qtquick/creator-mobile-app-tutorial.qdoc @@ -25,7 +25,7 @@ /*! \contentspage {Qt Creator Manual} \previouspage creator-writing-program.html - \page creator-mobile-app-tutorial.html + \example accelbubble \nextpage {Using Qt Quick UI Forms} \title Creating a Mobile Application @@ -61,17 +61,23 @@ \list 1 - \li Select \uicontrol File > \uicontrol {New File or Project} > \uicontrol Application > - \uicontrol {Qt Quick Application} > \uicontrol Choose. + \li Select \uicontrol File > \uicontrol {New File or Project} > + \uicontrol Application > \uicontrol {Qt Quick Controls Application} + > \uicontrol Choose. - \li In the \uicontrol{Name} field, type \b{accelbubble}. + \li In the \uicontrol Name field, type \e {accelbubble}. - \li In the \uicontrol {Create in} field, enter the path for the project files. - For example, \c {C:\Qt\examples}, and then click \uicontrol{Next} (or - \uicontrol Continue on OS X). + \li In the \uicontrol {Create in} field, enter the path for the project + files, and then click \uicontrol Next (or \uicontrol Continue on + OS X). - \li In the \uicontrol {Qt Quick component set} field, select - \uicontrol {Qt Quick Controls 1.1}. + \li In the \uicontrol {Minimal required Qt version} field, select the Qt + version to develop with. + + \note This page determines the set of files that the wizard + generates and their contents. The instructions in this tutorial + might not apply if you select the \uicontrol {With .ui.qml file} + check box. \li Select \l{glossary-buildandrun-kit}{kits} for Android ARM and iPhone OS, and click \uicontrol{Next}. @@ -97,11 +103,8 @@ The main view of the application displays an SVG bubble image at the center of the main window. - To use the Bluebubble.svg used by the Qt Sensors example, Accel Bubble, in - your project, you must copy it to the project directory (same subdirectory - as the QML file) from the examples directory in the Qt installation - directory. For example: - \c {C:\Qt\Qt5.2.0\5.2.0\msvc2010\examples\sensors\accelbubble\content}. + To use \l{accelbubble/Bluebubble.svg}{Bluebubble.svg} in your project, + copy it to the project directory (same subdirectory as the QML file). The image appears in \uicontrol Resources. You can also use any other image or a QML type, instead. @@ -110,20 +113,21 @@ \li In the \uicontrol Projects view, double-click the main.qml file to open it in the code editor. - \li Modify the properties of the ApplicationWindow type to specify the - application name, give the ApplicationWindow an id, and to set it - visible, as illustrated by the following code snippet: - - \quotefromfile accelbubble/main.qml - \skipto ApplicationWindow - \printuntil visible - \skipto /^\}/ - \printuntil } - \li Click \uicontrol Design to open the file in \QMLD. - \li In the \uicontrol Navigator, select \uicontrol Label and press \key Delete - to delete it. + \li In the \uicontrol Navigator, select \uicontrol Label and press + \key Delete to delete it. + + \li Select \uicontrol ApplicationWindow to edit its properties. + + \list a + + \li In the \uicontrol Id field, enter \e mainWindow, to be able to + reference the window from other places. + + \li In the \uicontrol Title field, type \e {Accelerate Bubble}. + + \endlist \li In \uicontrol Library > \uicontrol Resources, select Bluebubble.svg and drag and drop it to the canvas. @@ -132,34 +136,23 @@ able to reference the image from other places. \li In the code editor, add the following new properties to the image to - position the image at the center of ApplicationWindow when the + position the image at the center of the application window when the application starts: \quotefromfile accelbubble/main.qml \skipto Image \printuntil bubble.width - \li Set the x and y position of the image based on the new - properties: + \li Set the x and y position of the image based on the new properties: \dots \printuntil centerY \skipto /^\}/ \printuntil } + \endlist - Here is how the accelbubble.qml file looks after you made the changes: - - \quotefromfile accelbubble/main.qml - \skipto import QtQuick - \printuntil 1.1 - \codeline - \skipto ApplicationWindow - \printuntil true - \skipto Image - \printuntil y: - \skipto /^\}/ - \printuntil } + For an example, see \l{accelbubble/main.qml}{main.qml}. \section1 Moving the Bubble @@ -275,19 +268,11 @@ If you are using a device running Android v4.2.2, it should prompt you to verify the connection to allow USB debugging from the PC it is connected - to. To avoid such prompts every time you connect the device, check - "Always allow from the computer" and select \uicontrol OK. + to. To avoid such prompts every time you connect the device, select the + \uicontrol {Always allow from the computer} check box, and then select + \uicontrol OK. \li To run the application on the device, press \key {Ctrl+R}. \endlist - - \section1 Example Code - - When you have completed the steps, the main.qml file should look as follows: - - \quotefromfile accelbubble/main.qml - \skipto import - \printuntil /^\}/ - */ diff --git a/doc/src/qtquick/qtquick-uiforms-tutorial.qdoc b/doc/src/qtquick/qtquick-uiforms-tutorial.qdoc index 3736777ddb3..39e01d0b7a2 100644 --- a/doc/src/qtquick/qtquick-uiforms-tutorial.qdoc +++ b/doc/src/qtquick/qtquick-uiforms-tutorial.qdoc @@ -17,7 +17,7 @@ ****************************************************************************/ /*! \contentspage {Qt Creator Manual} - \previouspage creator-mobile-app-tutorial.html + \previouspage {Creating a Mobile Application} \example uiforms \nextpage creator-project-managing.html diff --git a/doc/src/widgets/qtdesigner-app-tutorial.qdoc b/doc/src/widgets/qtdesigner-app-tutorial.qdoc index 6bf53205e67..1a4affebfdd 100644 --- a/doc/src/widgets/qtdesigner-app-tutorial.qdoc +++ b/doc/src/widgets/qtdesigner-app-tutorial.qdoc @@ -26,7 +26,7 @@ \contentspage {Qt Creator Manual} \previouspage {Creating a Qt Quick Application} \page creator-writing-program.html - \nextpage creator-mobile-app-tutorial.html + \nextpage {Creating a Mobile Application} \title Creating a Qt Widget Based Application From 028709876ab97698971ef210c7adbd61df485d66 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 30 Jun 2015 10:16:11 +0200 Subject: [PATCH 091/113] ClangBackendIPC: Fix qbs build on Windows. Change-Id: I3dee9256cf9b49b3a5651d8534aec630c2d1ae5d Reviewed-by: Nikolai Kosjar --- src/libs/clangbackendipc/clangbackendipc.qbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/clangbackendipc/clangbackendipc.qbs b/src/libs/clangbackendipc/clangbackendipc.qbs index 0ffe8cacb2b..479d9b67650 100644 --- a/src/libs/clangbackendipc/clangbackendipc.qbs +++ b/src/libs/clangbackendipc/clangbackendipc.qbs @@ -6,7 +6,7 @@ QtcLibrary { Depends { name: "Qt.network" } Depends { name: "Sqlite" } - cpp.defines: base.concat("CLANGIPC_LIBRARY") + cpp.defines: base.concat("CLANGBACKENDIPC_LIBRARY") cpp.includePaths: base.concat(".") Group { From f0602e4ddd24192729c6cd7b3aa9825900f6fbf1 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Mon, 29 Jun 2015 18:21:42 +0200 Subject: [PATCH 092/113] Squish: Don't check for Resolution of "Invalid" bug report Change-Id: Iae6f066cf52f1e520a8f0dc3a24261387ae2ec10 Reviewed-by: Christian Stenger --- tests/system/suite_APTW/tst_APTW03/test.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/system/suite_APTW/tst_APTW03/test.py b/tests/system/suite_APTW/tst_APTW03/test.py index 72e5b217efa..fa843f79e16 100644 --- a/tests/system/suite_APTW/tst_APTW03/test.py +++ b/tests/system/suite_APTW/tst_APTW03/test.py @@ -88,11 +88,10 @@ def main(): targets = Targets.desktopTargetClasses() & ~Targets.DESKTOP_474_GCC checkedTargets, projectName, className = createNewQtPlugin(tempDir(), "SampleApp3", "MyPlugin", target=targets) - is12251Open = JIRA.isBugStillOpen(12251) virtualFunctionsAdded = False for kit, config in iterateBuildConfigs(len(checkedTargets), "Debug"): verifyBuildConfig(len(checkedTargets), kit, config, True, True) - if (virtualFunctionsAdded and is12251Open and platform.system() in ('Microsoft', 'Windows') + if (virtualFunctionsAdded and platform.system() in ('Microsoft', 'Windows') and "480" in Targets.getStringForTarget(checkedTargets[kit])): test.warning("Skipping building of Qt4.8 targets because of QTCREATORBUG-12251.") continue @@ -131,7 +130,7 @@ def main(): addReturn(editor, "QObject \*%s::create.*" % className, "0") virtualFunctionsAdded = True invokeMenuItem('File', 'Save All') - if (is12251Open and platform.system() in ('Microsoft', 'Windows') + if (platform.system() in ('Microsoft', 'Windows') # QTCREATORBUG-12251 and "480" in Targets.getStringForTarget(checkedTargets[kit])): test.warning("Skipping building of Qt4.8 targets because of QTCREATORBUG-12251.") continue From 6f852f1ecd468ec2067a0fa983a475d3db15b5fe Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 30 Jun 2015 13:28:06 +0200 Subject: [PATCH 093/113] Remove the "Not supported" option from the state widget It gets triggered accidentally when the updateDisplay() is triggered before the views are re-enabled after loading a trace. The V8 view is gone, so we don't need it anymore. Change-Id: If0eb96d47243f82ef66da9b3184b3b886d6f1457 Reviewed-by: Joerg Bornemann --- src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp b/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp index a6c8e47e322..05dc7503b03 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerstatewidget.cpp @@ -224,12 +224,6 @@ void QmlProfilerStateWidget::updateDisplay() return; } - // View is not supported for this kind of application - if (d->traceAvailable && d->loadingDone && !parentWidget()->isEnabled()) { - showText(tr("Not supported for this application")); - return; - } - // Application died before all data could be read if (!d->loadingDone && !d->emptyList && d->appKilled) { showText(tr("Application stopped before loading all data"), true); From 5a579e72f5310a013d89f4064f28463325ffad47 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 30 Jun 2015 14:39:00 +0200 Subject: [PATCH 094/113] QmlDesigner: Enabling support for Qt Quick 2.5 Change-Id: I13fde57a500af3aa7e94a9e30d29b481fbc21191 Reviewed-by: Robert Loehning --- .../qmldesigner/designercore/model/texttomodelmerger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 4ce998fc454..eee38122bd1 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -68,7 +68,7 @@ static inline QStringList supportedVersionsList() QStringList list; list << QStringLiteral("2.0") << QStringLiteral("2.1") << QStringLiteral("2.2") << QStringLiteral("2.3") - << QStringLiteral("2.4"); + << QStringLiteral("2.4") << QStringLiteral("2.5"); return list; } From 0b31635a3273d36e3b122cc0b1e9de837bba8f7b Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 30 Jun 2015 14:17:31 +0200 Subject: [PATCH 095/113] qbs project files: Qualify access to product properties in Export items. Such items behave "module-like" and one should therefore not count on them having access to the scope of their parent item. Change-Id: I8a323ae31218c6b1ee721ffaa65c04ccf08943bc Reviewed-by: Joerg Bornemann --- qbs/imports/QtcLibrary.qbs | 2 +- qbs/imports/QtcPlugin.qbs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qbs/imports/QtcLibrary.qbs b/qbs/imports/QtcLibrary.qbs index a4fc14bdd68..93b60110582 100644 --- a/qbs/imports/QtcLibrary.qbs +++ b/qbs/imports/QtcLibrary.qbs @@ -27,6 +27,6 @@ QtcProduct { Export { Depends { name: "cpp" } - cpp.includePaths: [libIncludeBase] + cpp.includePaths: [product.libIncludeBase] } } diff --git a/qbs/imports/QtcPlugin.qbs b/qbs/imports/QtcPlugin.qbs index a103f485728..6bbe1efcaa3 100644 --- a/qbs/imports/QtcPlugin.qbs +++ b/qbs/imports/QtcPlugin.qbs @@ -52,6 +52,6 @@ QtcProduct { Export { Depends { name: "ExtensionSystem" } Depends { name: "cpp" } - cpp.includePaths: [pluginIncludeBase] + cpp.includePaths: [product.pluginIncludeBase] } } From 3652ca52bc81be394bab81d93efa19328b7bcc2d Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 30 Jun 2015 15:40:30 +0200 Subject: [PATCH 096/113] ShellCommand: Do not crash when no binary is given Task-number: QTCREATORBUG-14643 Change-Id: I9c62904c271e2c2a94785dd8223b60d588da822b Reviewed-by: Christian Kandeler --- src/libs/utils/shellcommand.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libs/utils/shellcommand.cpp b/src/libs/utils/shellcommand.cpp index 47a58da50e5..44ce76feb9a 100644 --- a/src/libs/utils/shellcommand.cpp +++ b/src/libs/utils/shellcommand.cpp @@ -159,7 +159,10 @@ QString ShellCommand::displayName() const if (!d->m_jobs.isEmpty()) { const Internal::ShellCommandPrivate::Job &job = d->m_jobs.at(0); QString result = job.binary.toFileInfo().baseName(); - result[0] = result.at(0).toTitleCase(); + if (!result.isEmpty()) + result[0] = result.at(0).toTitleCase(); + else + result = tr("UNKNOWN"); if (!job.arguments.isEmpty()) result += QLatin1Char(' ') + job.arguments.at(0); From 75dc72879933545e7833ccfafc5e20035340eddb Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 30 Jun 2015 15:58:40 +0200 Subject: [PATCH 097/113] Git: Remove unused variable Change-Id: Ic5c6986cf2b8b6c1249e1b6e10ee12173583e614 Reviewed-by: Christian Kandeler --- src/plugins/git/gitplugin.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index 4f053539cef..5ed7b29e674 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -238,8 +238,6 @@ private: QString m_submitRepository; QString m_commitMessageFileName; bool m_submitActionTriggered; - - GitSettings m_settings; }; } // namespace Git From e2adf9b7bb20de1d9cc235c81495215ce542c69c Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 23 Jun 2015 14:39:27 +0200 Subject: [PATCH 098/113] Squish: Fix tst_HELP05 Additionally move Qt5Path helper class into classes.py as it's now used in more than one test suite. Change-Id: I0a1faed7fa8c082316c5568e4150091812af8979 Reviewed-by: Robert Loehning --- tests/system/shared/classes.py | 30 ++++++++++++++++++++++ tests/system/suite_HELP/tst_HELP05/test.py | 9 ++++--- tests/system/suite_WELP/tst_WELP03/test.py | 30 ---------------------- 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/tests/system/shared/classes.py b/tests/system/shared/classes.py index 7e8830d0902..ff013241c6f 100644 --- a/tests/system/shared/classes.py +++ b/tests/system/shared/classes.py @@ -172,3 +172,33 @@ class LibType: if libType == LibType.QT_PLUGIN: return "Qt Plugin" return None + +class Qt5Path: + DOCS = 0 + EXAMPLES = 1 + + @staticmethod + def getPaths(pathSpec): + if pathSpec == Qt5Path.DOCS: + path52 = "/doc" + path53 = "/Docs/Qt-5.3" + path54 = "/Docs/Qt-5.4" + elif pathSpec == Qt5Path.EXAMPLES: + path52 = "/examples" + path53 = "/Examples/Qt-5.3" + path54 = "/Examples/Qt-5.4" + else: + test.fatal("Unknown pathSpec given: %s" % str(pathSpec)) + return [] + if platform.system() in ('Microsoft', 'Windows'): + return ["C:/Qt/Qt5.2.1/5.2.1/msvc2010" + path52, + "C:/Qt/Qt5.3.1" + path53, "C:/Qt/Qt5.4.1" + path54] + elif platform.system() == 'Linux': + if __is64BitOS__(): + return map(os.path.expanduser, ["~/Qt5.2.1/5.2.1/gcc_64" + path52, + "~/Qt5.3.1" + path53, "~/Qt5.4.1" + path54]) + return map(os.path.expanduser, ["~/Qt5.2.1/5.2.1/gcc" + path52, + "~/Qt5.3.1" + path53, "~/Qt5.4.1" + path54]) + else: + return map(os.path.expanduser, ["~/Qt5.2.1/5.2.1/clang_64" + path52, + "~/Qt5.3.1" + path53]) diff --git a/tests/system/suite_HELP/tst_HELP05/test.py b/tests/system/suite_HELP/tst_HELP05/test.py index 5ec349e0d87..84325e251d1 100755 --- a/tests/system/suite_HELP/tst_HELP05/test.py +++ b/tests/system/suite_HELP/tst_HELP05/test.py @@ -52,14 +52,17 @@ def main(): startApplication("qtcreator" + SettingsPath) if not startedWithoutPluginError(): return - addHelpDocumentation([os.path.join(sdkPath, "Documentation", "qt.qch")]) + qchs = [] + for p in Qt5Path.getPaths(Qt5Path.DOCS): + qchs.append(os.path.join(p, "qtquick.qch")) + addHelpDocumentation(qchs) # create qt quick application createNewQtQuickApplication(tempDir(), "SampleApp") # verify Rectangle help - verifyInteractiveQMLHelp("Rectangle {", "QML Rectangle Element") + verifyInteractiveQMLHelp("Window {", "Window QML Type") # go back to edit mode switchViewTo(ViewConstants.EDIT) # verify MouseArea help - verifyInteractiveQMLHelp("MouseArea {", "QML MouseArea Element") + verifyInteractiveQMLHelp("MouseArea {", "MouseArea QML Type") # exit invokeMenuItem("File","Exit") diff --git a/tests/system/suite_WELP/tst_WELP03/test.py b/tests/system/suite_WELP/tst_WELP03/test.py index 3e15c8f4249..286be802dcd 100644 --- a/tests/system/suite_WELP/tst_WELP03/test.py +++ b/tests/system/suite_WELP/tst_WELP03/test.py @@ -31,36 +31,6 @@ source("../../shared/qtcreator.py") source("../../shared/suites_qtta.py") -class Qt5Path: - DOCS = 0 - EXAMPLES = 1 - - @staticmethod - def getPaths(pathSpec): - if pathSpec == Qt5Path.DOCS: - path52 = "/doc" - path53 = "/Docs/Qt-5.3" - path54 = "/Docs/Qt-5.4" - elif pathSpec == Qt5Path.EXAMPLES: - path52 = "/examples" - path53 = "/Examples/Qt-5.3" - path54 = "/Examples/Qt-5.4" - else: - test.fatal("Unknown pathSpec given: %s" % str(pathSpec)) - return [] - if platform.system() in ('Microsoft', 'Windows'): - return ["C:/Qt/Qt5.2.1/5.2.1/msvc2010" + path52, - "C:/Qt/Qt5.3.1" + path53, "C:/Qt/Qt5.4.1" + path54] - elif platform.system() == 'Linux': - if __is64BitOS__(): - return map(os.path.expanduser, ["~/Qt5.2.1/5.2.1/gcc_64" + path52, - "~/Qt5.3.1" + path53, "~/Qt5.4.1" + path54]) - return map(os.path.expanduser, ["~/Qt5.2.1/5.2.1/gcc" + path52, - "~/Qt5.3.1" + path53, "~/Qt5.4.1" + path54]) - else: - return map(os.path.expanduser, ["~/Qt5.2.1/5.2.1/clang_64" + path52, - "~/Qt5.3.1" + path53]) - def handlePackagingMessageBoxes(): if platform.system() == "Darwin": messageBox = "{type='QMessageBox' unnamed='1' visible='1'}" From 7f687783f3461b4aecb3bd2e905ef3f703c5cf66 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Fri, 26 Jun 2015 14:29:09 +0200 Subject: [PATCH 099/113] Squish: Fix tst_qml_indent Change-Id: I386312967e760017623b2f3d48f69ad38d9ff0d7 Reviewed-by: Robert Loehning --- tests/system/suite_editors/tst_qml_indent/test.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/system/suite_editors/tst_qml_indent/test.py b/tests/system/suite_editors/tst_qml_indent/test.py index 51b864d1a71..cee3d0a3c0b 100644 --- a/tests/system/suite_editors/tst_qml_indent/test.py +++ b/tests/system/suite_editors/tst_qml_indent/test.py @@ -64,8 +64,9 @@ def prepareQmlFile(): markText(editor, "End") else: markText(editor, "Ctrl+End") - # unmark the last line - type(editor, "") + # unmark the 2 last lines + for _ in range(2): + type(editor, "") type(editor, "") for j in range(10): type(editor, "") From ca815c3a3466b13acf21ed2640c22a02e7a540fb Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 23 Jun 2015 17:13:47 +0200 Subject: [PATCH 100/113] Doc: Remove section on Qt 4.7 We use Qt 5.x now, so no need to keep that. Change-Id: I8c84ad10ce5a8b7e166babd2bc3c4ed4a7d78da3 Reviewed-by: Leena Miettinen --- doc/api/qtcreator-ui-text.qdoc | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/doc/api/qtcreator-ui-text.qdoc b/doc/api/qtcreator-ui-text.qdoc index 4f447d1a7fe..a74c1d3afde 100644 --- a/doc/api/qtcreator-ui-text.qdoc +++ b/doc/api/qtcreator-ui-text.qdoc @@ -121,14 +121,8 @@ short, canonical HTML in the source tab of the rich text editor: \c {Note: text.} - In Qt 4.7, use only the \uicontrol Source tab of the Qt Designer rich text - editor. The automatic conversion performed by the rich text editor tab - generates a lot of redundant stylesheet information and uses hard-coded - fonts that look bad on other platforms and make translation in Qt Linguist - difficult. - - Qt Designer 4.8 has a feature that simplifies the rich text (on by - default), but still, you should verify by looking at the \uicontrol Source tab. + Qt Designer has a feature that simplifies the rich text (on by default), + but still, you should verify by looking at the \uicontrol Source tab. \section2 Writing Messages From adf4ab29f2a1e68d96398b57fa2936c807ea111a Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 1 Jul 2015 10:44:04 +0200 Subject: [PATCH 101/113] JsonWizard: Add some missing overrides Change-Id: Id0ac6cd5736b2ca1eaacb00c446eacc3dd7b4b34 Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/jsonwizard/jsonwizard.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizard.h b/src/plugins/projectexplorer/jsonwizard/jsonwizard.h index edc61009858..7809879b9f4 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizard.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizard.h @@ -98,8 +98,8 @@ signals: void allDone(const JsonWizard::GeneratorFiles &files); // emitted just after the wizard is done with the files. They are ready to be opened. public slots: - void accept(); - void reject(); + void accept() override; + void reject() override; private slots: void handleNewPages(int pageId); From 9c8eeaccd09d8bb16274855ba19f2ede44b2ce07 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 25 Jun 2015 12:52:16 +0200 Subject: [PATCH 102/113] TextEditor: Pass menuGroup as Core::Id around, not as char *. Will be used as that in the end, we can be clear about its true nature. Change-Id: I8928678eba12ecdbd32c291f3c02c5c89700ff76 Reviewed-by: David Schulz --- src/plugins/texteditor/texteditoractionhandler.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/texteditor/texteditoractionhandler.cpp b/src/plugins/texteditor/texteditoractionhandler.cpp index 036a1606d28..4d61da53d6c 100644 --- a/src/plugins/texteditor/texteditoractionhandler.cpp +++ b/src/plugins/texteditor/texteditoractionhandler.cpp @@ -63,7 +63,7 @@ public: uint optionalActions); QAction *registerActionHelper(Core::Id id, bool scriptable, const QString &title, - const QKeySequence &keySequence, const char *menueGroup, + const QKeySequence &keySequence, Core::Id menueGroup, Core::ActionContainer *container, std::function slot) { @@ -72,7 +72,7 @@ public: if (!keySequence.isEmpty()) command->setDefaultKeySequence(keySequence); - if (container && menueGroup) + if (container && menueGroup.isValid()) container->addAction(command, menueGroup); connect(result, &QAction::triggered, slot); @@ -84,7 +84,7 @@ public: bool scriptable = false, const QString &title = QString(), const QKeySequence &keySequence = QKeySequence(), - const char *menueGroup = 0, + Core::Id menueGroup = Core::Id(), Core::ActionContainer *container = 0) { return registerActionHelper(id, scriptable, title, keySequence, menueGroup, container, @@ -96,7 +96,7 @@ public: bool scriptable = false, const QString &title = QString(), const QKeySequence &keySequence = QKeySequence(), - const char *menueGroup = 0, + Core::Id menueGroup = Core::Id(), Core::ActionContainer *container = 0) { return registerActionHelper(id, scriptable, title, keySequence, menueGroup, container, @@ -108,7 +108,7 @@ public: bool scriptable = false, const QString &title = QString(), const QKeySequence &keySequence = QKeySequence(), - const char *menueGroup = 0, + Core::Id menueGroup = Core::Id(), Core::ActionContainer *container = 0) { return registerActionHelper(id, scriptable, title, keySequence, menueGroup, container, From 5088f07f397648258105195fa6e3424d0b3d47c1 Mon Sep 17 00:00:00 2001 From: Takumi ASAKI Date: Wed, 1 Jul 2015 13:18:49 +0900 Subject: [PATCH 103/113] TextEditor: Fix code completion and pasting in snippets. Fixes case 2 and 3 of QTCREATORBUG-14633. Task-number: QTCREATORBUG-14633 Change-Id: I19bf3c81c26f8a89a508591b0e7264251e0e6254 Reviewed-by: David Schulz --- src/plugins/texteditor/codeassist/assistproposalitem.cpp | 8 +++++--- src/plugins/texteditor/texteditor.cpp | 8 ++++++++ src/plugins/texteditor/texteditor.h | 2 ++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/plugins/texteditor/codeassist/assistproposalitem.cpp b/src/plugins/texteditor/codeassist/assistproposalitem.cpp index eaad6d3b083..38c102a7c9f 100644 --- a/src/plugins/texteditor/codeassist/assistproposalitem.cpp +++ b/src/plugins/texteditor/codeassist/assistproposalitem.cpp @@ -135,12 +135,14 @@ bool AssistProposalItem::prematurelyApplies(const QChar &c) const void AssistProposalItem::apply(TextEditorWidget *editorWidget, int basePosition) const { - if (data().canConvert()) + if (data().canConvert()) { applySnippet(editorWidget, basePosition); - else if (data().canConvert()) + } else if (data().canConvert()) { applyQuickFix(editorWidget, basePosition); - else + } else { applyContextualContent(editorWidget, basePosition); + editorWidget->encourageApply(); + } } void AssistProposalItem::applyContextualContent(TextEditorWidget *editorWidget, int basePosition) const diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 31e44ca8682..a1f074e3e3a 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -6349,6 +6349,13 @@ void TextEditorWidget::unCommentSelection() Utils::unCommentSelection(this, d->m_commentDefinition); } +void TextEditorWidget::encourageApply() +{ + if (!d->m_snippetOverlay->isVisible() || d->m_snippetOverlay->isEmpty()) + return; + d->m_snippetOverlay->updateEquivalentSelections(textCursor()); +} + void TextEditorWidget::showEvent(QShowEvent* e) { triggerPendingUpdates(); @@ -6584,6 +6591,7 @@ void TextEditorWidget::copy() void TextEditorWidget::paste() { QPlainTextEdit::paste(); + encourageApply(); } void TextEditorWidgetPrivate::collectToCircularClipboard() diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index 97f5de56f64..9dd8e3b117c 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -363,6 +363,8 @@ public: virtual void rewrapParagraph(); virtual void unCommentSelection(); + virtual void encourageApply(); + public slots: // Qt4-style connect used in EditorConfiguration virtual void setDisplaySettings(const TextEditor::DisplaySettings &); virtual void setMarginSettings(const TextEditor::MarginSettings &); From b36924c0e6afb5e7e4bf816e88a0f4d4aca51afa Mon Sep 17 00:00:00 2001 From: Takumi ASAKI Date: Wed, 1 Jul 2015 13:22:18 +0900 Subject: [PATCH 104/113] CppEditor: Fix inserting completion while in (local) rename mode Fixes case 1 of QTCREATORBUG-14633. Task-number: QTCREATORBUG-14633 Change-Id: I1f57b8f831613668b85948f4ec588c4cf441b633 Reviewed-by: David Schulz --- src/plugins/cppeditor/cppeditor.cpp | 8 ++++++++ src/plugins/cppeditor/cppeditor.h | 2 ++ src/plugins/cppeditor/cpplocalrenaming.cpp | 8 ++++++++ src/plugins/cppeditor/cpplocalrenaming.h | 2 ++ 4 files changed, 20 insertions(+) diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index a19081e5240..c04630a0793 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -723,6 +723,14 @@ FollowSymbolUnderCursor *CppEditorWidget::followSymbolUnderCursorDelegate() return d->m_followSymbolUnderCursor.data(); } +void CppEditorWidget::encourageApply() +{ + if (d->m_localRenaming.encourageApply()) + return; + + TextEditorWidget::encourageApply(); +} + void CppEditorWidget::abortDeclDefLink() { if (!d->m_declDefLink) diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index 41002e77790..489a04216d7 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -83,6 +83,8 @@ public: FollowSymbolUnderCursor *followSymbolUnderCursorDelegate(); // exposed for tests + void encourageApply() override; + public slots: void paste() override; void cut() override; diff --git a/src/plugins/cppeditor/cpplocalrenaming.cpp b/src/plugins/cppeditor/cpplocalrenaming.cpp index ab267df0b82..733005b8d66 100644 --- a/src/plugins/cppeditor/cpplocalrenaming.cpp +++ b/src/plugins/cppeditor/cpplocalrenaming.cpp @@ -210,6 +210,14 @@ bool CppLocalRenaming::handleKeyPressEvent(QKeyEvent *e) return true; } +bool CppLocalRenaming::encourageApply() +{ + if (!isActive()) + return false; + finishRenameChange(); + return true; +} + QTextEdit::ExtraSelection &CppLocalRenaming::renameSelection() { return m_selections[m_renameSelectionIndex]; diff --git a/src/plugins/cppeditor/cpplocalrenaming.h b/src/plugins/cppeditor/cpplocalrenaming.h index de6fd9ecf94..b23e4c5f5db 100644 --- a/src/plugins/cppeditor/cpplocalrenaming.h +++ b/src/plugins/cppeditor/cpplocalrenaming.h @@ -61,6 +61,8 @@ public: // to BaseTextEditorWidget::keyPressEvent() bool handleKeyPressEvent(QKeyEvent *e); + bool encourageApply(); + public slots: void updateSelectionsForVariableUnderCursor(const QList &selections); From 3bb12d01b4670b5c68d3aa8690df34d85020d56b Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 23 Jun 2015 16:53:04 +0200 Subject: [PATCH 105/113] Doc: Polish qtcreator-dev.qdoc Reformat the text, fix indentation of lists, use \QC macro where possible Change-Id: I0e7f60686aa6b32a6ca3807cbf917cade795fa62 Reviewed-by: Leena Miettinen --- doc/api/qtcreator-dev.qdoc | 262 ++++++++++++++++++------------------- 1 file changed, 126 insertions(+), 136 deletions(-) diff --git a/doc/api/qtcreator-dev.qdoc b/doc/api/qtcreator-dev.qdoc index 36de2d00681..efa6f46f3b6 100644 --- a/doc/api/qtcreator-dev.qdoc +++ b/doc/api/qtcreator-dev.qdoc @@ -20,132 +20,127 @@ \page extending-index.html \title Extending Qt Creator Manual - Qt Creator is a cross-platform integrated development environment (IDE) - tailored to the needs of Qt developers. + \QC is a cross-platform integrated development environment (IDE) tailored to + the needs of Qt developers. - Qt Creator is extensible in various ways. For example, Qt Creator - architecture is based on a plugin loader, which means that all - functionality beyond plugin - loading is implemented in plugins. However, you can extend and tweak - many parts of Qt Creator without the need to resort to coding in C++ and - implementing such a plugin. + \QC is extensible in various ways. For example, \QC architecture is based on + a plugin loader, which means that all functionality beyond plugin loading + is implemented in plugins. However, you can extend and tweak many parts of + \QC without the need to resort to coding in C++ and implementing such a + plugin. - This document gives you an overview of the various ways in which - you can extend Qt Creator, - depending on what you want to achieve, and points you to the relevant - documentation. + This document gives you an overview of the various ways in which you can + extend \QC, depending on what you want to achieve, and points you to the + relevant documentation. \section1 Generating Domain Specific Code and Templates If you regularly need to write the same code, be it little code snippets, - whole files or classes spread over multiple files, or complete projects, - you can create code snippets, templates, and wizards for that purpose. + whole files or classes spread over multiple files, or complete projects, you + can create code snippets, templates, and wizards for that purpose. \section2 Snippets - Typically, snippets consist of a few lines of code (although they - can also be plain text) that you regularly - want to insert into a bigger body of code, but do not want to type each - time. For example, \c while and \c for loops, \c if-else and \c try-catch - constructs, and class skeletons. Snippets are triggered in the same way as - normal code completion (see \l{Code Assist}{Providing Code Assist}). - Qt Creator contains a set of preconfigured snippets groups - to which you can add your own snippets. + Typically, snippets consist of a few lines of code (although they can also + be plain text) that you regularly want to insert into a bigger body of code, + but do not want to type each time. For example, \c while and \c for loops, + \c if-else and \c try-catch constructs, and class skeletons. Snippets are + triggered in the same way as normal code completion (see + \l{Code Assist}{Providing Code Assist}). + \QC contains a set of preconfigured snippets groups to which you can add + your own snippets. \list - \li \l{http://doc.qt.io/qtcreator/creator-completing-code.html#editing-code-snippets} - {Snippets User Interface} - \li \l{Snippets} {Adding Snippets Groups} + \li \l{http://doc.qt.io/qtcreator/creator-completing-code.html#editing-code-snippets} + {Snippets User Interface} + \li \l{Snippets}{Adding Snippets Groups} \endlist - \section2 File, Class and Project Templates + \section2 File and Project Templates - You can extend the wizards in \uicontrol {File > New File or Project} with your - own - file and project templates by writing XML definition files for them. + You can extend the wizards in \uicontrol File > + \uicontrol {New File or Project} with your own file and project templates by + writing JSON definition files for them. \list - \li \l{http://doc.qt.io/qtcreator/creator-project-wizards.html} - {Adding New Custom Wizards} - \li \l{User Interface Text Guidelines} + \li \l{http://doc.qt.io/qtcreator/creator-project-wizards.html} + {Adding New Custom Wizards} + \li \l{User Interface Text Guidelines} \endlist \section2 Custom Wizards - If the above methods for code snippets and templates are not sufficient - for your use case, you can create a custom Qt Creator plugin. - While this gives you complete control over the wizard, it - also requires you to write most of the UI and the logic yourself. + If the above methods for code snippets and templates are not sufficient for + your use case, you can create a custom \QC plugin. While this gives you + complete control over the wizard, it also requires you to write most of the + UI and the logic yourself. + \list \li \l{Creating Plugins} - \li \l{Qt Creator Coding Rules} - \li \l{Creating Wizards in Code} - \li \l{User Interface Text Guidelines} \endlist \section1 Supporting Additional File Types - If you have files with extensions or MIME types that Qt Creator does not - handle by default, you can edit the MIME type definitions, add highlight - definition files, and create your own text editors. + If you have files with extensions or MIME types that \QC does not handle by + default, you can edit the MIME type definitions, add highlight definition + files, and create your own text editors. \section2 MIME Types - You might find that Qt Creator could handle a particular file of yours if - it knew about the type of its contents. For example, C++ header or source - files with file extensions that are not known to Qt Creator. You can adapt - the MIME type definitions in Qt Creator to your specific setup, - by adding or removing file extensions and specifying magic headers. + You might find that \QC could handle a particular file of yours if it knew + about the type of its contents. For example, C++ header or source files + with file extensions that are not known to \QC. You can adapt the MIME type + definitions in \QC to your specific setup, by adding or removing file + extensions and specifying magic headers. + \list - \li \l{http://doc.qt.io/qtcreator/creator-mime-types.html} - {Editing MIME Types} - \li \l{http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html} - {MIME Type Specification Files} + \li \l{http://doc.qt.io/qtcreator/creator-mime-types.html} + {Editing MIME Types} + \li \l{http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html} + {MIME Type Specification Files} \endlist \section2 Text Highlighting and Indentation - For text files, Qt Creator provides an easy way to add highlighting and - indentation for file types that are not known to it by default. - Generic highlighting is based on highlight definition files that are - provided by the Kate Editor. You can download highlight definition files - for use with Qt Creator and create your own definition files. + For text files, \QC provides an easy way to add highlighting and indentation + for file types that are not known to it by default. Generic highlighting is + based on highlight definition files that are provided by the Kate Editor. + You can download highlight definition files for use with \QC and create + your own definition files. + \list - \li \l{http://doc.qt.io/qtcreator/creator-editor-options.html#generic-highlighting} - {Generic Highlighting} - \li \l{http://kate-editor.org/2005/03/24/writing-a-syntax-highlighting-file/} - {Writing a Syntax Highlighting File} + \li \l{http://doc.qt.io/qtcreator/creator-editor-options.html#generic-highlighting} + {Generic Highlighting} + \li \l{http://kate-editor.org/2005/03/24/writing-a-syntax-highlighting-file/} + {Writing a Syntax Highlighting File} \endlist \section2 Custom Text Editors If you need more advanced features than the MIME type and highlighting features described above, such as custom text completion or features that - rely on semantic analysis, you can extend Qt Creator with a text editor of - your own. Qt Creator provides a special API for text editors that gives you - a basis to build on, taking away some of the pain of implementing - a text editor from the ground up. + rely on semantic analysis, you can extend \QC with a text editor of your + own. \QC provides a special API for text editors that gives you a basis to + build on, taking away some of the pain of implementing a text editor from + the ground up. + \list \li \l{Creating Plugins} - \li \l{Qt Creator Coding Rules} - \li \l{Text Editors} - \li \l{CodeAssist} {Providing Code Assist} \endlist \section2 Other Custom Editors - You can also add a completely custom editor to gain complete - control over its appearance and behavior. + You can also add a completely custom editor to gain complete control over + its appearance and behavior. + \list \li \l{Creating Plugins} - \li \l{Qt Creator Coding Rules} - \li \l{Editors} \endlist @@ -153,82 +148,78 @@ Most software projects and development processes require various external tools. Several external tools, such as popular version control systems and - build tool chains are integrated into Qt Creator. However, it is impossible - for a single tool to cover all the use cases, and therefore you can - integrate additional tools to Qt Creator. + build tool chains are integrated into \QC. However, it is impossible for a + single tool to cover all the use cases, and therefore you can integrate + additional tools to \QC. \section2 Simple External Tools - In Qt Creator, you can specify tools that you can then run from a - menu or by using a keyboard shortcut that you assign. This allows you to - accomplish several things, with some limitations. You specify a command - to run, arguments and input for running it, and how to handle the output. - To specify the values, you can use a set of internal Qt Creator variables, - such as the file name of - the current document or project, or the currently selected text in - a text editor. If you find variables missing, please do not hesitate - to fill a feature suggestion. - The tool descriptions are saved as XML files that you can share. + In \QC, you can specify tools that you can then run from a menu or by using + a keyboard shortcut that you assign. This allows you to accomplish several + things, with some limitations. You specify a command to run, arguments and + input for running it, and how to handle the output. To specify the values, + you can use a set of internal \QC variables, such as the file name of the + current document or project, or the currently selected text in a text + editor. If you find variables missing, please do not hesitate to fill a + feature suggestion. The tool descriptions are saved as XML files that you + can share. + \list - \li \l{http://doc.qt.io/qtcreator/creator-editor-external.html} - {Using External Tools} - \li \l{External Tool Specification Files} + \li \l{http://doc.qt.io/qtcreator/creator-editor-external.html} + {Using External Tools} + \li \l{External Tool Specification Files} \endlist \section2 Complex External Tools When you plan to integrate more complex tools, carefully consider whether there really are advantages to be gained by tightly integrating the tool - into Qt Creator over loosely integrating it by mainly - providing a means of starting the tool with fitting parameters. + into \QC over loosely integrating it by mainly providing a means of starting + the tool with fitting parameters. \section3 Loosely Integrating Tools - If no interaction is needed between Qt Creator and the - external tool, just starting an external - application with its own user interface is preferable. That way - cluttering the Qt Creator UI is avoided, and the tool will be - available with a nice interface even without using Qt Creator - at all. + If no interaction is needed between \QC and the external tool, just starting + an external application with its own user interface is preferable. That way + cluttering the \QC UI is avoided, and the tool will be available with a + nice interface even without using \QC at all. Usually, you can use the external tool specification files to start the tool. If starting the tool and handling its output require more complex - logic, you can add a menu item to Qt Creator with a plugin. - If you need a way to configure the tool in Qt Creator, you can add an - \uicontrol Options page for it. + logic, you can add a menu item to \QC with a plugin. If you need a way to + configure the tool in \QC, you can add an \uicontrol Options page for it. + \list - \li \l{http://doc.qt.io/qtcreator/creator-editor-external.html} - {Using External Tools} - \li \l{External Tool Specification Files} - \li \l{Creating Plugins} - \li \l{Qt Creator Coding Rules} - \li \l{Menus and Menu Items} - \li \l{Options Pages} + \li \l{http://doc.qt.io/qtcreator/creator-editor-external.html}{Using External Tools} + \li \l{External Tool Specification Files} + \li \l{Creating Plugins} + \li \l{Qt Creator Coding Rules} + \li \l{Menus and Menu Items} + \li \l{Options Pages} \endlist \section3 Interacting with Tool Output - In some cases, running an external tool would not require tight - integration with Qt Creator, but investigating the output of the tool would - benefit from it. For example, some tools generate lists of issues in files - that are part of the project and some tools create output that is related - to the code. For these tools, it is useful to interactively switch between - the output and the corresponding code. + In some cases, running an external tool would not require tight integration + with \QC, but investigating the output of the tool would benefit from it. + For example, some tools generate lists of issues in files that are part of + the project and some tools create output that is related to the code. For + these tools, it is useful to interactively switch between the output and + the corresponding code. + + One way to handle that would be to let the tool create an output file, which + is then opened within \QC. You provide an editor (probably read-only) for + handling this file. For lists of issues, consider creating task list files + which are shown in the \uicontrol Issues output pane. - One way to handle that would be to let the tool create an output - file, which is then opened within Qt Creator. You provide - an editor (probably read-only) for handling this file. - For lists of issues, consider creating task list files which are shown in - the \uicontrol {Issues} output - pane. \list - \li \l{http://doc.qt.io/qtcreator/creator-task-lists.html} - {Showing Task List Files in the Issues Pane} - \li \l{Creating Plugins} - \li \l{Qt Creator Coding Rules} - \li \l{Menus and Menu Items} - \li \l{Options Pages} - \li \l{Editors} + \li \l{http://doc.qt.io/qtcreator/creator-task-lists.html} + {Showing Task List Files in the Issues Pane} + \li \l{Creating Plugins} + \li \l{Qt Creator Coding Rules} + \li \l{Menus and Menu Items} + \li \l{Options Pages} + \li \l{Editors} \endlist \section1 All Topics @@ -245,17 +236,16 @@ \endlist \li Reference \list - \li \l{http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html} - {MIME Type Specification Files} - \li \l{External Tool Specification Files} - \li \l{http://kate-editor.org/2005/03/24/writing-a-syntax-highlighting-file/} - {Highlight Definition Files} - \li \l{Qt Creator Variables} - \li \l{User Interface Text Guidelines} - \li \l{Writing Documentation} - \li \l{Qt Creator Coding Rules} - \li \l{Qt Creator API Reference} - \endlist - + \li \l{http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html} + {MIME Type Specification Files} + \li \l{External Tool Specification Files} + \li \l{http://kate-editor.org/2005/03/24/writing-a-syntax-highlighting-file/} + {Highlight Definition Files} + \li \l{Qt Creator Variables} + \li \l{User Interface Text Guidelines} + \li \l{Writing Documentation} + \li \l{Qt Creator Coding Rules} + \li \l{Qt Creator API Reference} + \endlist \endlist */ From df35fe0fd9e61eb1236d185697073f86b5d202b6 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Tue, 30 Jun 2015 17:38:47 +0200 Subject: [PATCH 106/113] Squish: Shorten tst_qml_indent Change-Id: I30dadda017415440609b03e97b45b03f4bac9bbf Reviewed-by: Christian Stenger --- tests/system/suite_editors/tst_qml_indent/test.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/system/suite_editors/tst_qml_indent/test.py b/tests/system/suite_editors/tst_qml_indent/test.py index cee3d0a3c0b..be0d8968f95 100644 --- a/tests/system/suite_editors/tst_qml_indent/test.py +++ b/tests/system/suite_editors/tst_qml_indent/test.py @@ -37,11 +37,8 @@ def main(): # using a temporary directory won't mess up a potentially existing createNewQtQuickApplication(tempDir(), "untitled") originalText = prepareQmlFile() - if not originalText: - invokeMenuItem("File", "Save All") - invokeMenuItem("File", "Exit") - return - testReIndent(originalText) + if originalText: + testReIndent(originalText) invokeMenuItem("File", "Save All") invokeMenuItem("File", "Exit") From 1f1e0e3b833eaa47cab1f5d61164f2635a91b49e Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 23 Jun 2015 15:18:05 +0200 Subject: [PATCH 107/113] Squish: Fix suite_CSUP Change-Id: I0fecbb1ea1853fca231b68de7bc28aceb4289065 Reviewed-by: Robert Loehning --- tests/system/suite_CSUP/tst_CSUP01/test.py | 2 +- tests/system/suite_CSUP/tst_CSUP03/test.py | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/system/suite_CSUP/tst_CSUP01/test.py b/tests/system/suite_CSUP/tst_CSUP01/test.py index 4769d78a571..137c958fd5a 100644 --- a/tests/system/suite_CSUP/tst_CSUP01/test.py +++ b/tests/system/suite_CSUP/tst_CSUP01/test.py @@ -63,7 +63,7 @@ def main(): "Step 2: Verifying if: .cpp file is opened in Edit mode.") # Step 3: Insert text "re" to new line in Editor mode and press Ctrl+Space. editorWidget = findObject(":Qt Creator_CppEditor::Internal::CPPEditorWidget") - if not placeCursorToLine(editorWidget, "QApplication app(argc, argv);"): + if not placeCursorToLine(editorWidget, "QGuiApplication app(argc, argv);"): earlyExit("Did not find first line in function block.") return type(editorWidget, "") diff --git a/tests/system/suite_CSUP/tst_CSUP03/test.py b/tests/system/suite_CSUP/tst_CSUP03/test.py index 2c6dc9b854e..074065babb8 100644 --- a/tests/system/suite_CSUP/tst_CSUP03/test.py +++ b/tests/system/suite_CSUP/tst_CSUP03/test.py @@ -30,10 +30,11 @@ source("../../shared/qtcreator.py") -inputDialog = "{type='QInputDialog' unnamed='1' visible='1'}" +inputDialog = "{type='QDialog' unnamed='1' visible='1' windowTitle='Extract Function Refactoring'}" def revertMainCpp(): invokeMenuItem('File', 'Revert "main.cpp" to Saved') + waitFor("object.exists(':Revert to Saved_QMessageBox')", 1000) clickButton(waitForObject(":Revert to Saved.Proceed_QPushButton")) def constructExpectedCode(original, codeLines, funcSuffix): @@ -109,9 +110,9 @@ def main(): markText(editor, "Right", 2) snooze(1) # avoid timing issue with the parser invokeContextMenuItem(editor, 'Refactor', 'Extract Function') - funcEdit = waitForObject("{buddy={text='Enter function name' type='QLabel' unnamed='1' " - "visible='1' window=%s} type='QLineEdit' unnamed='1' visible='1'}" - % inputDialog) + funcEdit = waitForObject("{buddy={text='Function name' type='QLabel' unnamed='1' " + "visible='1' window=%s} type='Utils::FancyLineEdit' " + "unnamed='1' visible='1'}" % inputDialog) replaceEditorContent(funcEdit, "myFunc%s" % funcSuffix) clickButton(waitForObject("{text='OK' type='QPushButton' unnamed='1' visible='1' window=%s}" % inputDialog)) From 66b17772a2c2887768da97b21cda2ccd0bacc237 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 23 Jun 2015 16:25:56 +0200 Subject: [PATCH 108/113] Doc: Polish qtcreator-api.qdoc Reformat the text, use consistent indentation for tables, use \QC macro where appropriate. Change-Id: I2502176cf0a0e1cd414ca088ac5bc800728a70d1 Reviewed-by: Leena Miettinen --- doc/api/qtcreator-api.qdoc | 275 +++++++++++++++++++------------------ 1 file changed, 141 insertions(+), 134 deletions(-) diff --git a/doc/api/qtcreator-api.qdoc b/doc/api/qtcreator-api.qdoc index 4ade5eb0e5a..2b37b458ac5 100644 --- a/doc/api/qtcreator-api.qdoc +++ b/doc/api/qtcreator-api.qdoc @@ -21,12 +21,11 @@ \title Qt Creator API Reference - The core of Qt Creator is - basically only a \l{ExtensionSystem}{plugin loader}. - All functionality is implemented in plugins. The basis of Qt Creator is - implemented in the \l{Core} {Core} Plugin. The plugin manager provides - simple means for plugin cooperation that allow plugins to provide - hooks for other plugin's extensions. + The core of \QC is basically only a \l{ExtensionSystem}{plugin loader}. All + functionality is implemented in plugins. The basis of \QC is implemented in + the \l{Core}{Core} Plugin. The plugin manager provides simple means for + plugin cooperation that allow plugins to provide hooks for other plugin's + extensions. \section1 Libraries @@ -35,88 +34,90 @@ There are a few core libraries used by many parts of Qt Creator. \table - \header - \li Library Name - \li Description + \header + \li Library Name + \li Description - \row - \li \l{Aggregation} - \li Adds functionality for "glueing" QObjects of different - types together, so you can "cast" between them. + \row + \li \l{Aggregation} + \li Adds functionality for "glueing" QObjects of different types + together, so you can "cast" between them. - \row - \li \l{ExtensionSystem} - \li Implements the plugin loader framework. Provides a base class for plugins and - basic mechanisms for plugin interaction like an object pool. + \row + \li \l{ExtensionSystem} + \li Implements the plugin loader framework. Provides a base class + for plugins and basic mechanisms for plugin interaction like an + object pool. - \row - \li \l{Utils} - \li General utility library. + \row + \li \l{Utils} + \li General utility library. - \row - \li \l{QmlJS} - \li QML and JavaScript language support library. + \row + \li \l{QmlJS} + \li QML and JavaScript language support library. \endtable \section2 Additional libraries \table - \header - \li Library Name - \li Description - - \row - \li \l{qtcreatorcdbext} - \li Windows CDB debugger extension - + \header + \li Library Name + \li Description + \row + \li \l{qtcreatorcdbext} + \li Windows CDB debugger extension \endtable \section1 Plugins - As already mentioned, Qt Creator is basically only a plugin loader framework + As already mentioned, \QC is basically only a plugin loader framework which gets its IDE functionality through plugins. The most important plugin - is the Core plugin which provides all the basic functionality needed + is the \c Core plugin which provides all the basic functionality needed later to integrate e.g. editors or mode windows. \table - \header - \li Plugin Name - \li Description + \header + \li Plugin Name + \li Description - \row - \li \l{Core} - \li The core plugin. Provides the main window and managers for editors, - actions, mode windows and files, just to mention the most important ones. + \row + \li \l{Core} + \li The core plugin. Provides the main window and managers for + editors, actions, mode windows and files, just to mention the + most important ones. - \row - \li \l{ProjectExplorer} - \li The project explorer plugin. Provides base classes for project handling. + \row + \li \l{ProjectExplorer} + \li The project explorer plugin. Provides base classes for project + handling. - \row - \li \l{Find} - \li Support for searching text in arbitrary widgets, and arbitrary other things. + \row + \li \l{Find} + \li Support for searching text in arbitrary widgets, and arbitrary + other things. - \row - \li \l{Locator} - \li Hooks for providing content for Locator. + \row + \li \l{Locator} + \li Hooks for providing content for Locator. - \row - \li \l{Debugger} - \li Debugging functionality. + \row + \li \l{Debugger} + \li Debugging functionality. - \row - \li \l{VcsBase} - \li Base classes for version control support. - - \row - \li \l{TextEditor} - \li This is where everything starts if you want to create a text editor. Besides - the base editor itself, this plugin contains APIs for supporting functionality - like \l{Snippets}{snippets}, highlighting, \l{CodeAssist}{code assist}, indentation - and style, and others. + \row + \li \l{VcsBase} + \li Base classes for version control support. + \row + \li \l{TextEditor} + \li This is where everything starts if you want to create a text + editor. Besides the base editor itself, this plugin contains + APIs for supporting functionality like \l{Snippets}{snippets}, + highlighting, \l{CodeAssist}{code assist}, indentation and + style, and others. \endtable */ @@ -154,95 +155,101 @@ \title Common Extension Tasks This section summarizes the API functions that you can use to add UI - components to Qt Creator. + components to \QC. \table - \header - \li Task - \li Details - \li API + \header + \li Task + \li Details + \li API - \row - \li Add a menu or menu item. - \li You can extend existing menus or create new ones. - \li \l{Core::ActionManager}, \l{Core::Command} + \row + \li Add a menu or menu item. + \li You can extend existing menus or create new ones. + \li \l{Core::ActionManager}, \l{Core::Command} - \row - \li Add a configurable keyboard shortcut. - \li Registering shortcuts makes it possible for users to configure them in - the common shortcut settings dialog. - \li \l{Core::ActionManager}, \l{Core::Command} + \row + \li Add a configurable keyboard shortcut. + \li Registering shortcuts makes it possible for users to configure + them in the common shortcut settings dialog. + \li \l{Core::ActionManager}, \l{Core::Command} - \row - \li Add a mode. - \li Modes correspond to complete screens of controls, specialized for a task. - \li \l{Core::IMode} + \row + \li Add a mode. + \li Modes correspond to complete screens of controls, specialized + for a task. + \li \l{Core::IMode} - \row - \li Add a new editor type. - \li Such as an editor for XML files. - \li \l{Core::IEditorFactory}, \l{Core::IEditor}, \l{Core::IDocument} + \row + \li Add a new editor type. + \li Such as an editor for XML files. + \li \l{Core::IEditorFactory}, \l{Core::IEditor}, \l{Core::IDocument} - \row - \li Add a new wizard. - \li You can extend the wizards in File > New File or Project with your own - file and project templates. - \li \l{Core::IWizard}, \l{Core::StandardFileWizard}, - \l{Core::BaseFileWizard}, \l{Core::BaseFileWizardParameters} + \row + \li Add a new wizard. + \li You can extend the wizards in File > New File or Project with + your own file and project templates. + \li \l{Core::IWizard}, \l{Core::StandardFileWizard}, + \l{Core::BaseFileWizard}, \l{Core::BaseFileWizardParameters} - \row - \li Add support for a new version control system. - \li Version control systems integrated in QtCreator are Bazaar, CVS, Git, - Mecurial, Perforce, and Subversion. - \li \l{Core::IVersionControl} + \row + \li Add support for a new version control system. + \li Version control systems integrated in \QC are Bazaar, CVS, Git, + Mecurial, Perforce, and Subversion. + \li \l{Core::IVersionControl} - \row - \li Add a view to the navigation sidebar. - \li The one which shows the project tree, filesystem, open documents or bookmarks. - \li \l{Core::INavigationWidgetFactory} + \row + \li Add a view to the navigation sidebar. + \li The one which shows the project tree, filesystem, open documents + or bookmarks. + \li \l{Core::INavigationWidgetFactory} - \row - \li Add an options page to the \uicontrol Options dialog. - \li Add a new page to existing or new category in Tools > Options. - \li \l{Core::IOptionsPage} + \row + \li Add an options page to the \uicontrol Options dialog. + \li Add a new page to existing or new category in + \uicontrol Tools > \uicontrol Options. + \li \l{Core::IOptionsPage} - \row - \li Add a find filter to the \uicontrol Find dialog. - \li Implement any kind of search term based search. - \li \l{Find::IFindFilter}, \l{Core::SearchResultWindow} + \row + \li Add a find filter to the \uicontrol Find dialog. + \li Implement any kind of search term based search. + \li \l{Find::IFindFilter}, \l{Core::SearchResultWindow} - \row - \li Add support for the find tool bar to a widget. - \li The widget that has focus is asked whether it supports text search. You can - add support for widgets under your control. - \li \l{Core::IFindSupport}, \l{Find::BaseTextFind} + \row + \li Add support for the find tool bar to a widget. + \li The widget that has focus is asked whether it supports text + search. You can add support for widgets under your control. + \li \l{Core::IFindSupport}, \l{Find::BaseTextFind} - \row - \li Add a completely new project type. - \li - \li + \row + \li Add a completely new project type. + \li + \li - \row - \li Add a new type of build step. - \li - \li + \row + \li Add a new type of build step. + \li + \li - \row - \li Add a new filter to the locator. - \li For a text typed in by the user you provide a list of things to show in the popup. - When the user selects an entry you are requested to do whatever you want. - \li \l{Core::ILocatorFilter}, \l{Core::LocatorFilterEntry}, \l{Locator::BaseFileFilter} + \row + \li Add a new filter to the locator. + \li For a text typed in by the user you provide a list of things to + show in the popup. When the user selects an entry you are + requested to do whatever you want. + \li \l{Core::ILocatorFilter}, \l{Core::LocatorFilterEntry}, + \l{Locator::BaseFileFilter} - \row - \li Show a progress indicator for a concurrently running task. - \li You can show a progress indicator for your tasks in the left hand tool bar, - and also in the application icon (on platforms that support it). - \li \l{Core::ProgressManager}, \l{Core::FutureProgress} + \row + \li Show a progress indicator for a concurrently running task. + \li You can show a progress indicator for your tasks in the left + hand tool bar, and also in the application icon (on platforms + that support it). + \li \l{Core::ProgressManager}, \l{Core::FutureProgress} - \row - \li - \li - \li + \row + \li + \li + \li \endtable */ From 7706a35b4a30c8b5d59dc4574bbfbcc9ef609de9 Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Tue, 30 Jun 2015 15:55:35 +0200 Subject: [PATCH 109/113] fix add new file with only one file Change-Id: I6ac06978af15a974b8a200eb2f5fee4787de4a37 Task-number: QTCREATORBUG-14648 Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/projectwizardpage.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/projectwizardpage.cpp b/src/plugins/projectexplorer/projectwizardpage.cpp index b2127f430ac..932943394f8 100644 --- a/src/plugins/projectexplorer/projectwizardpage.cpp +++ b/src/plugins/projectexplorer/projectwizardpage.cpp @@ -535,7 +535,10 @@ IVersionControl *ProjectWizardPage::currentVersionControl() void ProjectWizardPage::setFiles(const QStringList &fileNames) { - m_commonDirectory = Utils::commonPath(fileNames); + if (fileNames.count() == 1) + m_commonDirectory = QFileInfo(fileNames.first()).absolutePath(); + else + m_commonDirectory = Utils::commonPath(fileNames); QString fileMessage; { QTextStream str(&fileMessage); From 19253ded5ee3c2d5ed6fb6fc6bc92a5cb3198185 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 1 Jul 2015 12:31:27 +0200 Subject: [PATCH 110/113] Analyzer: Have one status label per tool. It does not make sense for all the analyzers to share a single status label, as they are unrelated to each other. Change-Id: I9cf885263853251f841ef96836860455905677ac Reviewed-by: hjk --- src/plugins/analyzerbase/analyzermanager.cpp | 21 +++++++++++++------- src/plugins/analyzerbase/analyzermanager.h | 4 ++-- src/plugins/valgrind/callgrindengine.cpp | 3 ++- src/plugins/valgrind/callgrindtool.cpp | 6 +++--- src/plugins/valgrind/memchecktool.cpp | 7 ++++--- 5 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/plugins/analyzerbase/analyzermanager.cpp b/src/plugins/analyzerbase/analyzermanager.cpp index 03782f31d0e..168e65fd2d8 100644 --- a/src/plugins/analyzerbase/analyzermanager.cpp +++ b/src/plugins/analyzerbase/analyzermanager.cpp @@ -173,10 +173,11 @@ public: ActionContainer *m_menu; QComboBox *m_toolBox; QStackedWidget *m_controlsStackWidget; - StatusLabel *m_statusLabel; + QStackedWidget *m_statusLabelsStackWidget; typedef QMap MainWindowSettingsMap; QHash > m_toolWidgets; QHash m_controlsWidgetFromTool; + QHash m_statusLabelsPerTool; MainWindowSettingsMap m_defaultSettings; // list of dock widgets to prevent memory leak @@ -198,7 +199,7 @@ AnalyzerManagerPrivate::AnalyzerManagerPrivate(AnalyzerManager *qq): m_menu(0), m_toolBox(new QComboBox), m_controlsStackWidget(new QStackedWidget), - m_statusLabel(new StatusLabel) + m_statusLabelsStackWidget(new QStackedWidget) { m_toolBox->setObjectName(QLatin1String("AnalyzerManagerToolBox")); connect(m_toolBox, static_cast(&QComboBox::activated), @@ -352,7 +353,7 @@ void AnalyzerManagerPrivate::createModeMainWindow() analyzeToolBarLayout->addWidget(new StyledSeparator); analyzeToolBarLayout->addWidget(m_toolBox); analyzeToolBarLayout->addWidget(m_controlsStackWidget); - analyzeToolBarLayout->addWidget(m_statusLabel); + analyzeToolBarLayout->addWidget(m_statusLabelsStackWidget); analyzeToolBarLayout->addStretch(); auto dock = new QDockWidget(tr("Analyzer Toolbar")); @@ -493,6 +494,9 @@ void AnalyzerManagerPrivate::selectAction(AnalyzerAction *action) QTC_CHECK(!m_controlsWidgetFromTool.contains(toolId)); m_controlsWidgetFromTool[toolId] = widget; m_controlsStackWidget->addWidget(widget); + StatusLabel * const toolStatusLabel = new StatusLabel; + m_statusLabelsPerTool[toolId] = toolStatusLabel; + m_statusLabelsStackWidget->addWidget(toolStatusLabel); } foreach (QDockWidget *widget, m_toolWidgets.value(toolId)) activateDock(Qt::DockWidgetArea(widget->property(INITIAL_DOCK_AREA).toInt()), widget); @@ -501,6 +505,7 @@ void AnalyzerManagerPrivate::selectAction(AnalyzerAction *action) QTC_CHECK(m_controlsWidgetFromTool.contains(toolId)); m_controlsStackWidget->setCurrentWidget(m_controlsWidgetFromTool.value(toolId)); + m_statusLabelsStackWidget->setCurrentWidget(m_statusLabelsPerTool.value(toolId)); m_toolBox->setCurrentIndex(toolboxIndex); updateRunActions(); @@ -669,14 +674,16 @@ void AnalyzerManagerPrivate::resetLayout() m_mainWindow->restoreSettings(m_defaultSettings.value(m_currentAction->toolId())); } -void AnalyzerManager::showStatusMessage(const QString &message, int timeoutMS) +void AnalyzerManager::showStatusMessage(Id toolId, const QString &message, int timeoutMS) { - d->m_statusLabel->showStatusMessage(message, timeoutMS); + StatusLabel * const statusLabel = d->m_statusLabelsPerTool.value(toolId); + QTC_ASSERT(statusLabel, return); + statusLabel->showStatusMessage(message, timeoutMS); } -void AnalyzerManager::showPermanentStatusMessage(const QString &message) +void AnalyzerManager::showPermanentStatusMessage(Id toolId, const QString &message) { - showStatusMessage(message, -1); + showStatusMessage(toolId, message, -1); } void AnalyzerManager::showMode() diff --git a/src/plugins/analyzerbase/analyzermanager.h b/src/plugins/analyzerbase/analyzermanager.h index a5c309a46ef..7b76e09a405 100644 --- a/src/plugins/analyzerbase/analyzermanager.h +++ b/src/plugins/analyzerbase/analyzermanager.h @@ -78,8 +78,8 @@ public: static void stopTool(); // Convenience functions. - static void showStatusMessage(const QString &message, int timeoutMS = 10000); - static void showPermanentStatusMessage(const QString &message); + static void showStatusMessage(Core::Id toolId, const QString &message, int timeoutMS = 10000); + static void showPermanentStatusMessage(Core::Id toolId, const QString &message); static void handleToolStarted(); static void handleToolFinished(); diff --git a/src/plugins/valgrind/callgrindengine.cpp b/src/plugins/valgrind/callgrindengine.cpp index 42273f69a35..a37d276606e 100644 --- a/src/plugins/valgrind/callgrindengine.cpp +++ b/src/plugins/valgrind/callgrindengine.cpp @@ -30,6 +30,7 @@ #include "callgrindengine.h" +#include "callgrindtool.h" #include "valgrindsettings.h" #include @@ -58,7 +59,7 @@ CallgrindRunControl::CallgrindRunControl(const AnalyzerStartParameters &sp, void CallgrindRunControl::showStatusMessage(const QString &msg) { - AnalyzerManager::showStatusMessage(msg); + AnalyzerManager::showStatusMessage(CallgrindToolId, msg); } QStringList CallgrindRunControl::toolArguments() const diff --git a/src/plugins/valgrind/callgrindtool.cpp b/src/plugins/valgrind/callgrindtool.cpp index b17abe0c3ce..a30898e6041 100644 --- a/src/plugins/valgrind/callgrindtool.cpp +++ b/src/plugins/valgrind/callgrindtool.cpp @@ -834,7 +834,7 @@ void CallgrindToolPrivate::engineFinished() if (data) showParserResults(data); else - AnalyzerManager::showStatusMessage(tr("Profiling aborted.")); + AnalyzerManager::showStatusMessage(CallgrindToolId, tr("Profiling aborted.")); setBusyCursor(false); } @@ -853,7 +853,7 @@ void CallgrindToolPrivate::showParserResults(const ParseData *data) } else { msg = tr("Parsing failed."); } - AnalyzerManager::showStatusMessage(msg); + AnalyzerManager::showStatusMessage(CallgrindToolId, msg); } void CallgrindToolPrivate::editorOpened(IEditor *editor) @@ -918,7 +918,7 @@ void CallgrindToolPrivate::loadExternalLogFile() return; } - AnalyzerManager::showStatusMessage(tr("Parsing Profile Data...")); + AnalyzerManager::showStatusMessage(CallgrindToolId, tr("Parsing Profile Data...")); QCoreApplication::processEvents(); Parser parser; diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp index 84f9f6b5bee..d6830df6e41 100644 --- a/src/plugins/valgrind/memchecktool.cpp +++ b/src/plugins/valgrind/memchecktool.cpp @@ -94,6 +94,7 @@ using namespace Valgrind::XmlProtocol; namespace Valgrind { namespace Internal { +const Core::Id MemcheckToolId = "Memcheck"; // ---------------------------- MemcheckErrorFilterProxyModel MemcheckErrorFilterProxyModel::MemcheckErrorFilterProxyModel(QObject *parent) @@ -355,7 +356,7 @@ QWidget *MemcheckTool::createWidgets() m_errorView->setObjectName(QLatin1String("Valgrind.MemcheckTool.ErrorView")); m_errorView->setWindowTitle(tr("Memory Issues")); - QDockWidget *errorDock = AnalyzerManager::createDockWidget("Memcheck", m_errorView); + QDockWidget *errorDock = AnalyzerManager::createDockWidget(MemcheckToolId, m_errorView); errorDock->show(); mw->splitDockWidget(mw->toolBarDockWidget(), errorDock, Qt::Vertical); @@ -575,7 +576,7 @@ MemcheckRunControl *MemcheckTool::createMemcheckRunControl(const AnalyzerStartPa void MemcheckTool::engineFinished() { const int issuesFound = updateUiAfterFinishedHelper(); - AnalyzerManager::showStatusMessage(issuesFound > 0 + AnalyzerManager::showStatusMessage(MemcheckToolId, issuesFound > 0 ? AnalyzerManager::tr("Memory Analyzer Tool finished, %n issues were found.", 0, issuesFound) : AnalyzerManager::tr("Memory Analyzer Tool finished, no issues were found.")); } @@ -583,7 +584,7 @@ void MemcheckTool::engineFinished() void MemcheckTool::loadingExternalXmlLogFileFinished() { const int issuesFound = updateUiAfterFinishedHelper(); - AnalyzerManager::showStatusMessage(issuesFound > 0 + AnalyzerManager::showStatusMessage(MemcheckToolId, issuesFound > 0 ? AnalyzerManager::tr("Log file processed, %n issues were found.", 0, issuesFound) : AnalyzerManager::tr("Log file processed, no issues were found.")); } From d7b3bf2879e48dfd26f3a70d519637b0245efba7 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 1 Jul 2015 12:39:02 +0200 Subject: [PATCH 111/113] Analyzer: Clear status label on tool start. Change-Id: Id0f675236d48ef366c55e618cd71489c0410a860 Reviewed-by: hjk --- src/plugins/analyzerbase/ianalyzertool.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/analyzerbase/ianalyzertool.cpp b/src/plugins/analyzerbase/ianalyzertool.cpp index 80698e8066f..7aa6ddbfc95 100644 --- a/src/plugins/analyzerbase/ianalyzertool.cpp +++ b/src/plugins/analyzerbase/ianalyzertool.cpp @@ -89,6 +89,7 @@ void AnalyzerAction::startTool() AnalyzerManager::showMode(); TaskHub::clearTasks(Constants::ANALYZERTASK_ID); + AnalyzerManager::showPermanentStatusMessage(toolId(), QString()); if (m_toolPreparer && !m_toolPreparer()) return; From ae9ce6981c33467118a2ccd8183423a2e0683214 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Mon, 22 Jun 2015 18:21:05 +0900 Subject: [PATCH 112/113] TextEditor: follow "Enable scroll wheel zooming" setting behavior When it is disabled, scroll wheel zooming should not work. Change-Id: Ie6a7e2620185ee4496830c614a6ccd48c9ec2427 Reviewed-by: Orgad Shaneh Reviewed-by: Jarek Kobus Reviewed-by: David Schulz --- src/plugins/texteditor/texteditor.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index a1f074e3e3a..b7f5302fef9 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -5436,7 +5436,14 @@ void TextEditorWidgetPrivate::handleBackspaceKey() void TextEditorWidget::wheelEvent(QWheelEvent *e) { d->clearVisibleFoldedBlock(); - if (scrollWheelZoomingEnabled() && e->modifiers() & Qt::ControlModifier) { + if (e->modifiers() & Qt::ControlModifier) { + if (!scrollWheelZoomingEnabled()) { + // When the setting is disabled globally, + // we have to skip calling QPlainTextEdit::wheelEvent() + // that changes zoom in it. + return; + } + const int delta = e->delta(); if (delta < 0) zoomOut(); From 5e2942a5bda66ec80a76b88113a17e7d9b69c504 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 16 Jun 2015 13:59:08 +0200 Subject: [PATCH 113/113] Clang: Use member instead of pointer It makes the resource allocation much more clear. Change-Id: Ib276e089dc3db551171373d72e9b54c9d87b4c8c Reviewed-by: Nikolai Kosjar --- .../clangcodemodel/clangcompletion.cpp | 13 ++++++------ src/plugins/clangcodemodel/clangcompletion.h | 10 ++++----- .../clangeditordocumentprocessor.cpp | 2 +- .../clangmodelmanagersupport.cpp | 21 +++++++++---------- .../clangcodemodel/clangmodelmanagersupport.h | 6 +++--- .../test/clangcodecompletion_test.cpp | 11 +++++----- 6 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/plugins/clangcodemodel/clangcompletion.cpp b/src/plugins/clangcodemodel/clangcompletion.cpp index 9d358231c66..25c18b905b6 100644 --- a/src/plugins/clangcodemodel/clangcompletion.cpp +++ b/src/plugins/clangcodemodel/clangcompletion.cpp @@ -299,10 +299,9 @@ namespace Internal { // ----------------------------- // ClangCompletionAssistProvider // ----------------------------- -ClangCompletionAssistProvider::ClangCompletionAssistProvider(IpcCommunicator::Ptr ipcCommunicator) +ClangCompletionAssistProvider::ClangCompletionAssistProvider(IpcCommunicator &ipcCommunicator) : m_ipcCommunicator(ipcCommunicator) { - QTC_CHECK(m_ipcCommunicator); } IAssistProvider::RunType ClangCompletionAssistProvider::runType() const @@ -642,7 +641,7 @@ const TextEditor::TextEditorWidget *ClangCompletionAssistInterface::textEditorWi } ClangCompletionAssistInterface::ClangCompletionAssistInterface( - IpcCommunicator::Ptr ipcCommunicator, + IpcCommunicator &ipcCommunicator, const TextEditorWidget *textEditorWidget, int position, const QString &fileName, @@ -661,7 +660,7 @@ ClangCompletionAssistInterface::ClangCompletionAssistInterface( m_unsavedFiles = Utils::createUnsavedFiles(mmi->workingCopy()); } -IpcCommunicator::Ptr ClangCompletionAssistInterface::ipcCommunicator() const +IpcCommunicator &ClangCompletionAssistInterface::ipcCommunicator() const { return m_ipcCommunicator; } @@ -1111,8 +1110,8 @@ void ClangCompletionAssistProcessor::sendFileContent(const QString &projectFileP : modifiedFileContent; const bool hasUnsavedContent = true; // TODO - IpcCommunicator::Ptr ipcCommunicator = m_interface->ipcCommunicator(); - ipcCommunicator->registerFilesForCodeCompletion( + IpcCommunicator &ipcCommunicator = m_interface->ipcCommunicator(); + ipcCommunicator.registerFilesForCodeCompletion( {FileContainer(filePath, projectFilePath, Utf8String::fromByteArray(unsavedContent), @@ -1129,7 +1128,7 @@ void ClangCompletionAssistProcessor::sendCompletionRequest(int position, const QString filePath = m_interface->fileName(); const QString projectFilePath = Utils::projectFilePathForFile(filePath); sendFileContent(projectFilePath, modifiedFileContent); - m_interface->ipcCommunicator()->completeCode(this, filePath, line, column, projectFilePath); + m_interface->ipcCommunicator().completeCode(this, filePath, line, column, projectFilePath); } TextEditor::IAssistProposal *ClangCompletionAssistProcessor::createProposal() const diff --git a/src/plugins/clangcodemodel/clangcompletion.h b/src/plugins/clangcodemodel/clangcompletion.h index 09f551a2f01..4d8ddfcf3fe 100644 --- a/src/plugins/clangcodemodel/clangcompletion.h +++ b/src/plugins/clangcodemodel/clangcompletion.h @@ -60,7 +60,7 @@ class ClangCompletionAssistProvider : public CppTools::CppCompletionAssistProvid Q_OBJECT public: - ClangCompletionAssistProvider(IpcCommunicator::Ptr ipcCommunicator); + ClangCompletionAssistProvider(IpcCommunicator &ipcCommunicator); IAssistProvider::RunType runType() const override; @@ -73,7 +73,7 @@ public: TextEditor::AssistReason reason) const override; private: - IpcCommunicator::Ptr m_ipcCommunicator; + IpcCommunicator &m_ipcCommunicator; }; class ClangAssistProposalItem : public TextEditor::AssistProposalItem @@ -117,7 +117,7 @@ private: class ClangCompletionAssistInterface: public TextEditor::AssistInterface { public: - ClangCompletionAssistInterface(ClangCodeModel::Internal::IpcCommunicator::Ptr ipcCommunicator, + ClangCompletionAssistInterface(ClangCodeModel::Internal::IpcCommunicator &ipcCommunicator, const TextEditor::TextEditorWidget *textEditorWidget, int position, const QString &fileName, @@ -126,7 +126,7 @@ public: const Internal::PchInfo::Ptr &pchInfo, const CPlusPlus::LanguageFeatures &features); - ClangCodeModel::Internal::IpcCommunicator::Ptr ipcCommunicator() const; + ClangCodeModel::Internal::IpcCommunicator &ipcCommunicator() const; const ClangCodeModel::Internal::UnsavedFiles &unsavedFiles() const; bool objcEnabled() const; const CppTools::ProjectPart::HeaderPaths &headerPaths() const; @@ -136,7 +136,7 @@ public: void setHeaderPaths(const CppTools::ProjectPart::HeaderPaths &headerPaths); // For tests private: - ClangCodeModel::Internal::IpcCommunicator::Ptr m_ipcCommunicator; + ClangCodeModel::Internal::IpcCommunicator &m_ipcCommunicator; ClangCodeModel::Internal::UnsavedFiles m_unsavedFiles; QStringList m_options; CppTools::ProjectPart::HeaderPaths m_headerPaths; diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 8480dfbace2..090a0cf06de 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -137,7 +137,7 @@ ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor() projectFilePath = projectPart->projectFile; // OK, Project Part is still loaded QTC_ASSERT(m_modelManagerSupport, return); - m_modelManagerSupport->ipcCommunicator()->unregisterFilesForCodeCompletion( + m_modelManagerSupport->ipcCommunicator().unregisterFilesForCodeCompletion( {ClangBackEnd::FileContainer(filePath(), projectFilePath)}); } diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 5a15dad80f3..b829c8fbaa1 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -58,8 +58,7 @@ static CppTools::CppModelManager *cppModelManager() } ModelManagerSupportClang::ModelManagerSupportClang() - : m_ipcCommunicator(new IpcCommunicator) - , m_completionAssistProvider(new ClangCompletionAssistProvider(m_ipcCommunicator)) + : m_completionAssistProvider(m_ipcCommunicator) { QTC_CHECK(!m_instance); m_instance = this; @@ -84,7 +83,7 @@ ModelManagerSupportClang::~ModelManagerSupportClang() CppTools::CppCompletionAssistProvider *ModelManagerSupportClang::completionAssistProvider() { - return m_completionAssistProvider.data(); + return &m_completionAssistProvider; } CppTools::BaseEditorDocumentProcessor *ModelManagerSupportClang::editorDocumentProcessor( @@ -98,7 +97,7 @@ void ModelManagerSupportClang::onCurrentEditorChanged(Core::IEditor *newCurrent) // If we switch away from a cpp editor, update the backend about // the document's unsaved content. if (m_previousCppEditor && m_previousCppEditor->document()->isModified()) { - m_ipcCommunicator->updateUnsavedFileFromCppEditorDocument( + m_ipcCommunicator.updateUnsavedFileFromCppEditorDocument( m_previousCppEditor->document()->filePath().toString()); } @@ -138,20 +137,20 @@ void ModelManagerSupportClang::onCppDocumentReloadFinished(bool success) return; Core::IDocument *document = qobject_cast(sender()); - m_ipcCommunicator->updateUnsavedFileIfNotCurrentDocument(document); + m_ipcCommunicator.updateUnsavedFileIfNotCurrentDocument(document); } void ModelManagerSupportClang::onCppDocumentContentsChanged() { Core::IDocument *document = qobject_cast(sender()); - m_ipcCommunicator->updateUnsavedFileIfNotCurrentDocument(document); + m_ipcCommunicator.updateUnsavedFileIfNotCurrentDocument(document); } void ModelManagerSupportClang::onAbstractEditorSupportContentsUpdated(const QString &filePath, const QByteArray &content) { QTC_ASSERT(!filePath.isEmpty(), return); - m_ipcCommunicator->updateUnsavedFile(filePath, content); + m_ipcCommunicator.updateUnsavedFile(filePath, content); } void ModelManagerSupportClang::onAbstractEditorSupportRemoved(const QString &filePath) @@ -159,7 +158,7 @@ void ModelManagerSupportClang::onAbstractEditorSupportRemoved(const QString &fil QTC_ASSERT(!filePath.isEmpty(), return); if (!cppModelManager()->cppEditorDocument(filePath)) { const QString projectFilePath = Utils::projectFilePathForFile(filePath); - m_ipcCommunicator->unregisterFilesForCodeCompletion( + m_ipcCommunicator.unregisterFilesForCodeCompletion( {ClangBackEnd::FileContainer(filePath, projectFilePath)}); } } @@ -169,12 +168,12 @@ void ModelManagerSupportClang::onProjectPartsUpdated(ProjectExplorer::Project *p QTC_ASSERT(project, return); const CppTools::ProjectInfo projectInfo = cppModelManager()->projectInfo(project); QTC_ASSERT(projectInfo.isValid(), return); - m_ipcCommunicator->registerProjectsParts(projectInfo.projectParts()); + m_ipcCommunicator.registerProjectsParts(projectInfo.projectParts()); } void ModelManagerSupportClang::onProjectPartsRemoved(const QStringList &projectFiles) { - m_ipcCommunicator->unregisterProjectPartsForCodeCompletion(projectFiles); + m_ipcCommunicator.unregisterProjectPartsForCodeCompletion(projectFiles); } ModelManagerSupportClang *ModelManagerSupportClang::instance() @@ -182,7 +181,7 @@ ModelManagerSupportClang *ModelManagerSupportClang::instance() return m_instance; } -IpcCommunicator::Ptr ModelManagerSupportClang::ipcCommunicator() +IpcCommunicator &ModelManagerSupportClang::ipcCommunicator() { return m_ipcCommunicator; } diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index 9ff74440f84..05ea7f74fe1 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -58,7 +58,7 @@ public: CppTools::BaseEditorDocumentProcessor *editorDocumentProcessor( TextEditor::TextDocument *baseTextDocument) override; - IpcCommunicator::Ptr ipcCommunicator(); + IpcCommunicator &ipcCommunicator(); public: // for tests static ModelManagerSupportClang *instance(); @@ -75,8 +75,8 @@ private: void onProjectPartsUpdated(ProjectExplorer::Project *project); void onProjectPartsRemoved(const QStringList &projectFiles); - IpcCommunicator::Ptr m_ipcCommunicator; - QScopedPointer m_completionAssistProvider; + IpcCommunicator m_ipcCommunicator; + ClangCompletionAssistProvider m_completionAssistProvider; QPointer m_previousCppEditor; }; diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp index 29b74815ddf..f5b000e5f53 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp @@ -241,13 +241,12 @@ class ChangeIpcSender public: ChangeIpcSender(IpcSenderInterface *ipcSender) { - m_previousSender = ModelManagerSupportClang::instance()->ipcCommunicator() - ->setIpcSender(ipcSender); + m_previousSender = ModelManagerSupportClang::instance()->ipcCommunicator().setIpcSender(ipcSender); } ~ChangeIpcSender() { - ModelManagerSupportClang::instance()->ipcCommunicator()->setIpcSender(m_previousSender); + ModelManagerSupportClang::instance()->ipcCommunicator().setIpcSender(m_previousSender); } private: @@ -941,9 +940,9 @@ void ClangCodeCompletionTest::testUpdateBackendAfterRestart() spy.senderLog.clear(); // Kill backend process... - IpcCommunicator::Ptr ipcCommunicator = ModelManagerSupportClang::instance()->ipcCommunicator(); - ipcCommunicator->killBackendProcess(); - QSignalSpy waitForReinitializedBackend(ipcCommunicator.data(), + IpcCommunicator &ipcCommunicator = ModelManagerSupportClang::instance()->ipcCommunicator(); + ipcCommunicator.killBackendProcess(); + QSignalSpy waitForReinitializedBackend(&ipcCommunicator, SIGNAL(backendReinitialized())); QVERIFY(waitForReinitializedBackend.wait());