diff options
author | Oswald Buddenhagen <oswald.buddenhagen@digia.com> | 2013-07-25 13:18:31 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@digia.com> | 2013-07-25 13:18:31 +0200 |
commit | 6896546ba5a6ae59416fe4f527294ba731235218 (patch) | |
tree | b5b5c8b554f6dcdf391459d996100dbb265e55d1 /src | |
parent | e2ce17ef00218af3db35118b036ebf19834b86e8 (diff) | |
parent | 1dd9a54ab63d267268b6262b11c7b0189370f174 (diff) | |
download | qt-creator-6896546ba5a6ae59416fe4f527294ba731235218.tar.gz |
Merge remote-tracking branch 'origin/2.8'
Conflicts:
src/plugins/cpptools/cppmodelmanager.cpp
Change-Id: I0e69dfad951eb81d8008f5ca05e8fb6999ae2c8a
Diffstat (limited to 'src')
55 files changed, 694 insertions, 303 deletions
diff --git a/src/app/main.cpp b/src/app/main.cpp index acccb28b49..c7317caa2f 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -517,12 +517,6 @@ int main(int argc, char **argv) // shutdown plugin manager on the exit QObject::connect(&app, SIGNAL(aboutToQuit()), &pluginManager, SLOT(shutdown())); -#ifdef WITH_TESTS - // Do this after the event loop has started - if (PluginManager::testRunRequested()) - QTimer::singleShot(100, &pluginManager, SLOT(startTests())); -#endif - const int r = app.exec(); cleanupCrashHandler(); return r; diff --git a/src/libs/QtcLibrary.qbs b/src/libs/QtcLibrary.qbs index 7c6be844c8..a90826df3b 100644 --- a/src/libs/QtcLibrary.qbs +++ b/src/libs/QtcLibrary.qbs @@ -8,6 +8,8 @@ DynamicLibrary { name: "Qt.test" } + targetName: Defaults.qtLibraryName(qbs, name) + cpp.defines: Defaults.defines(qbs) cpp.linkerFlags: { if (qbs.buildVariant == "release" && (qbs.toolchain.contains("gcc") || qbs.toolchain.contains("mingw"))) diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index c8c6d0aaf6..7ef2df36a9 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -818,6 +818,10 @@ void PluginManagerPrivate::nextDelayedInitialize() delayedInitializeTimer = 0; profilingSummary(); emit q->initializationDone(); +#ifdef WITH_TESTS + if (q->testRunRequested()) + q->startTests(); +#endif } else { delayedInitializeTimer->start(); } diff --git a/src/plugins/QtcPlugin.qbs b/src/plugins/QtcPlugin.qbs index a6ff01c0a2..fcd6533e99 100644 --- a/src/plugins/QtcPlugin.qbs +++ b/src/plugins/QtcPlugin.qbs @@ -7,16 +7,8 @@ Product { property string provider: 'QtProject' property var pluginspecreplacements property var pluginRecommends: [] - targetName: { - // see PluginSpecPrivate::loadLibrary() - if (qbs.debugInformation) { - if (qbs.targetOS.contains("windows")) - return name + "d"; - if (qbs.targetOS.contains("osx")) - return name + "_debug"; - } - return name; - } + + targetName: Defaults.qtLibraryName(qbs, name) Depends { name: "ExtensionSystem" } Depends { name: "pluginspec" } diff --git a/src/plugins/analyzerbase/analyzerbase.pro b/src/plugins/analyzerbase/analyzerbase.pro index f003999510..d768b6e5a6 100644 --- a/src/plugins/analyzerbase/analyzerbase.pro +++ b/src/plugins/analyzerbase/analyzerbase.pro @@ -16,8 +16,7 @@ SOURCES += \ analyzeroptionspage.cpp \ analyzerrunconfigwidget.cpp \ analyzerutils.cpp \ - startremotedialog.cpp \ - analyzerruncontrolfactory.cpp + startremotedialog.cpp HEADERS += \ ianalyzerengine.h \ @@ -32,8 +31,7 @@ HEADERS += \ analyzeroptionspage.h \ analyzerrunconfigwidget.h \ analyzerutils.h \ - startremotedialog.h \ - analyzerruncontrolfactory.h + startremotedialog.h RESOURCES += \ analyzerbase.qrc diff --git a/src/plugins/analyzerbase/analyzerbase.qbs b/src/plugins/analyzerbase/analyzerbase.qbs index 7a42610f1b..44658b96ab 100644 --- a/src/plugins/analyzerbase/analyzerbase.qbs +++ b/src/plugins/analyzerbase/analyzerbase.qbs @@ -26,8 +26,6 @@ QtcPlugin { "analyzerrunconfigwidget.h", "analyzerruncontrol.cpp", "analyzerruncontrol.h", - "analyzerruncontrolfactory.cpp", - "analyzerruncontrolfactory.h", "analyzersettings.cpp", "analyzersettings.h", "analyzerstartparameters.h", diff --git a/src/plugins/analyzerbase/analyzerplugin.cpp b/src/plugins/analyzerbase/analyzerplugin.cpp index 079c1f1af3..ba8b86e0cc 100644 --- a/src/plugins/analyzerbase/analyzerplugin.cpp +++ b/src/plugins/analyzerbase/analyzerplugin.cpp @@ -30,7 +30,6 @@ #include "analyzerplugin.h" #include "analyzermanager.h" -#include "analyzerruncontrolfactory.h" #include <projectexplorer/projectexplorer.h> #include <projectexplorer/taskhub.h> @@ -65,8 +64,6 @@ bool AnalyzerPlugin::initialize(const QStringList &arguments, QString *errorStri (void) new AnalyzerManager(this); - addAutoReleasedObject(new AnalyzerRunControlFactory()); - // Task integration. //: Category under which Analyzer tasks are listed in Issues view ProjectExplorer::ProjectExplorerPlugin::instance()->taskHub() diff --git a/src/plugins/android/android.qbs b/src/plugins/android/android.qbs index 5eb9dafccd..aa6f64237d 100644 --- a/src/plugins/android/android.qbs +++ b/src/plugins/android/android.qbs @@ -9,6 +9,7 @@ QtcPlugin { Depends { name: "ProjectExplorer" } Depends { name: "Qt4ProjectManager" } Depends { name: "Debugger" } + Depends { name: "QmlDebug" } Depends { name: "QtSupport" } Depends { name: "TextEditor" } Depends { name: "AnalyzerBase" } diff --git a/src/plugins/android/androidanalyzesupport.cpp b/src/plugins/android/androidanalyzesupport.cpp index 9d64682c4b..852075e6cf 100644 --- a/src/plugins/android/androidanalyzesupport.cpp +++ b/src/plugins/android/androidanalyzesupport.cpp @@ -32,11 +32,11 @@ #include "androidrunner.h" #include "androidmanager.h" -#include "analyzerbase/ianalyzertool.h" -#include "analyzerbase/ianalyzerengine.h" -#include "analyzerbase/analyzermanager.h" -#include "analyzerbase/analyzerruncontrol.h" -#include "analyzerbase/analyzerstartparameters.h" +#include <analyzerbase/ianalyzertool.h> +#include <analyzerbase/ianalyzerengine.h> +#include <analyzerbase/analyzermanager.h> +#include <analyzerbase/analyzerruncontrol.h> +#include <analyzerbase/analyzerstartparameters.h> #include <projectexplorer/target.h> #include <projectexplorer/project.h> @@ -63,7 +63,6 @@ RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(AndroidRunConfigurati AnalyzerStartParameters params; params.toolId = tool->id(); - params.startMode = StartQmlRemote; Target *target = runConfig->target(); params.displayName = AndroidManager::packageName(target); params.sysroot = SysRootKitInformation::sysRoot(target->kit()).toString(); @@ -74,6 +73,7 @@ RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(AndroidRunConfigurati QTC_ASSERT(server.listen(QHostAddress::LocalHost) || server.listen(QHostAddress::LocalHostIPv6), return 0); params.analyzerHost = server.serverAddress().toString(); + params.startMode = StartQmlRemote; } AnalyzerRunControl * const analyzerRunControl = new AnalyzerRunControl(tool, params, runConfig); @@ -84,7 +84,8 @@ RunControl *AndroidAnalyzeSupport::createAnalyzeRunControl(AndroidRunConfigurati AndroidAnalyzeSupport::AndroidAnalyzeSupport(AndroidRunConfiguration *runConfig, AnalyzerRunControl *runControl) : AndroidRunSupport(runConfig, runControl), - m_engine(0) + m_engine(0), + m_qmlPort(0) { if (runControl) { m_engine = runControl->engine(); @@ -93,6 +94,8 @@ AndroidAnalyzeSupport::AndroidAnalyzeSupport(AndroidRunConfiguration *runConfig, m_runner, SLOT(start())); } } + connect(&m_outputParser, SIGNAL(waitingForConnectionOnPort(quint16)), + SLOT(remoteIsRunning())); connect(m_runner, SIGNAL(remoteProcessStarted(int)), SLOT(handleRemoteProcessStarted(int))); connect(m_runner, SIGNAL(remoteProcessFinished(QString)), @@ -106,16 +109,17 @@ AndroidAnalyzeSupport::AndroidAnalyzeSupport(AndroidRunConfiguration *runConfig, void AndroidAnalyzeSupport::handleRemoteProcessStarted(int qmlPort) { - if (m_engine) - m_engine->notifyRemoteSetupDone(qmlPort); + m_qmlPort = qmlPort; } void AndroidAnalyzeSupport::handleRemoteOutput(const QByteArray &output) { + const QString msg = QString::fromUtf8(output); if (m_engine) - m_engine->logApplicationMessage(QString::fromUtf8(output), Utils::StdOutFormatSameLine); + m_engine->logApplicationMessage(msg, Utils::StdOutFormatSameLine); else AndroidRunSupport::handleRemoteOutput(output); + m_outputParser.processOutput(msg); } void AndroidAnalyzeSupport::handleRemoteErrorOutput(const QByteArray &output) @@ -126,5 +130,11 @@ void AndroidAnalyzeSupport::handleRemoteErrorOutput(const QByteArray &output) AndroidRunSupport::handleRemoteErrorOutput(output); } +void AndroidAnalyzeSupport::remoteIsRunning() +{ + if (m_engine) + m_engine->notifyRemoteSetupDone(m_qmlPort); +} + } // namespace Internal } // namespace Android diff --git a/src/plugins/android/androidanalyzesupport.h b/src/plugins/android/androidanalyzesupport.h index 8aad0f43c9..2c7aa0e065 100644 --- a/src/plugins/android/androidanalyzesupport.h +++ b/src/plugins/android/androidanalyzesupport.h @@ -31,6 +31,7 @@ #define ANDROIDANALYZESUPPORT_H #include "androidrunsupport.h" +#include <qmldebug/qmloutputparser.h> namespace Analyzer { class IAnalyzerEngine; @@ -62,8 +63,12 @@ private slots: void handleRemoteOutput(const QByteArray &output); void handleRemoteErrorOutput(const QByteArray &output); + void remoteIsRunning(); + private: Analyzer::IAnalyzerEngine *m_engine; + QmlDebug::QmlOutputParser m_outputParser; + int m_qmlPort; }; } // namespace Internal diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp index 82f5c6c9fd..4cffc35127 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp @@ -433,8 +433,6 @@ void AutotoolsProject::updateCppCodeModel() pinfo.appendProjectPart(part); modelManager->updateProjectInfo(pinfo); - modelManager->updateSourceFiles(m_files, - CppTools::CppModelManagerInterface::ForcedProgressNotification); setProjectLanguage(ProjectExplorer::Constants::LANG_CXX, !part->files.isEmpty()); } diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 785aab41d4..701f769b06 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -377,10 +377,8 @@ bool CMakeProject::parseCMakeLists() adder.maybeAdd(file); pinfo.appendProjectPart(part); - modelmanager->updateProjectInfo(pinfo); m_codeModelFuture.cancel(); - m_codeModelFuture = modelmanager->updateSourceFiles(m_files, - CppTools::CppModelManagerInterface::ForcedProgressNotification); + m_codeModelFuture = modelmanager->updateProjectInfo(pinfo); setProjectLanguage(ProjectExplorer::Constants::LANG_CXX, !part->files.isEmpty()); } diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro index a78e22c7fe..d646ca23b1 100644 --- a/src/plugins/cppeditor/cppeditor.pro +++ b/src/plugins/cppeditor/cppeditor.pro @@ -38,8 +38,11 @@ SOURCES += cppeditorplugin.cpp \ RESOURCES += cppeditor.qrc equals(TEST, 1) { + HEADERS += cppquickfix_test_utils.h + SOURCES += \ cppquickfix_test.cpp \ + cppquickfix_test_utils.cpp \ cppdoxygen_test.cpp \ fileandtokenactions_test.cpp \ followsymbol_switchmethoddecldef_test.cpp diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs index 079025a112..39533511cd 100644 --- a/src/plugins/cppeditor/cppeditor.qbs +++ b/src/plugins/cppeditor/cppeditor.qbs @@ -59,6 +59,8 @@ QtcPlugin { files: [ "cppdoxygen_test.cpp", "cppquickfix_test.cpp", + "cppquickfix_test_utils.cpp", + "cppquickfix_test_utils.h", "fileandtokenactions_test.cpp", "followsymbol_switchmethoddecldef_test.cpp" ] diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 0bd5554f22..351536db42 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -27,6 +27,8 @@ ** ****************************************************************************/ +#include "cppquickfix_test_utils.h" + #include "cppeditor.h" #include "cppeditorplugin.h" #include "cppquickfixassistant.h" @@ -3121,33 +3123,6 @@ void CppEditorPlugin::test_quickfix_AssignToLocalVariable_noSignatureMatch() data.run(&factory); } -/// Test dialog for insert virtual functions -class InsertVirtualMethodsDialogTest : public InsertVirtualMethodsDialog -{ -public: - InsertVirtualMethodsDialogTest(ImplementationMode mode, bool virt, QWidget *parent = 0) - : InsertVirtualMethodsDialog(parent) - { - setImplementationsMode(mode); - setInsertKeywordVirtual(virt); - } - - bool gather() - { - return true; - } - - ImplementationMode implementationMode() const - { - return m_implementationMode; - } - - bool insertKeywordVirtual() const - { - return m_insertKeywordVirtual; - } -}; - /// Check: Insert only declarations void CppEditorPlugin::test_quickfix_InsertVirtualMethods_onlyDecl() { diff --git a/src/plugins/cppeditor/cppquickfix_test_utils.cpp b/src/plugins/cppeditor/cppquickfix_test_utils.cpp new file mode 100644 index 0000000000..c42a66a257 --- /dev/null +++ b/src/plugins/cppeditor/cppquickfix_test_utils.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: 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 "cppquickfix_test_utils.h" + +#include "cppquickfixes.h" + +using namespace CppEditor::Internal; + +InsertVirtualMethodsDialogTest::InsertVirtualMethodsDialogTest(ImplementationMode mode, + bool insertVirtualKeyword, + QWidget *parent) + : InsertVirtualMethodsDialog(parent) +{ + setImplementationsMode(mode); + setInsertKeywordVirtual(insertVirtualKeyword); +} + +InsertVirtualMethodsDialog::ImplementationMode InsertVirtualMethodsDialogTest::implementationMode() const +{ + return m_implementationMode; +} + +bool InsertVirtualMethodsDialogTest::insertKeywordVirtual() const +{ + return m_insertKeywordVirtual; +} + +bool InsertVirtualMethodsDialogTest::gather() +{ + return true; +} diff --git a/src/plugins/cppeditor/cppquickfix_test_utils.h b/src/plugins/cppeditor/cppquickfix_test_utils.h new file mode 100644 index 0000000000..e8ca190b92 --- /dev/null +++ b/src/plugins/cppeditor/cppquickfix_test_utils.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: 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. +** +****************************************************************************/ + + +#ifndef CPPQUICKFIX_TEST_UTILS_H +#define CPPQUICKFIX_TEST_UTILS_H + +#include "cppquickfixes.h" + +/// Fake dialog of InsertVirtualMethodsDialog that does not pop up anything. +class InsertVirtualMethodsDialogTest : public CppEditor::Internal::InsertVirtualMethodsDialog +{ +public: + InsertVirtualMethodsDialogTest(ImplementationMode mode, bool insertVirtualKeyword, + QWidget *parent = 0); + + bool gather(); + ImplementationMode implementationMode() const; + bool insertKeywordVirtual() const; +}; + +#endif // CPPQUICKFIX_TEST_UTILS_H diff --git a/src/plugins/cppeditor/fileandtokenactions_test.cpp b/src/plugins/cppeditor/fileandtokenactions_test.cpp index 19d301a6b5..62faf9dda7 100644 --- a/src/plugins/cppeditor/fileandtokenactions_test.cpp +++ b/src/plugins/cppeditor/fileandtokenactions_test.cpp @@ -34,9 +34,11 @@ #include <cppeditor/cppeditor.h> #include <cppeditor/cppeditorplugin.h> #include <cppeditor/cppquickfixassistant.h> +#include <cppeditor/cppquickfixes.h> #include <cppeditor/cppquickfix.h> -#include <cpptools/cpptoolsplugin.h> +#include <cppeditor/cppquickfix_test_utils.h> #include <cpptools/cppmodelmanagerinterface.h> +#include <cpptools/cpptoolsplugin.h> #include <extensionsystem/pluginmanager.h> #include <projectexplorer/projectexplorer.h> #include <projectexplorer/project.h> @@ -468,7 +470,19 @@ void RunAllQuickFixesTokenAction::run(CPPEditorWidget *editorWidget) foreach (CppQuickFixFactory *quickFixFactory, quickFixFactories) { TextEditor::QuickFixOperations operations; - quickFixFactory->match(qfi, operations); + // Some Quick Fixes pop up a dialog and are therefore inappropriate for this test. + // Where possible, use a guiless version of the factory. + if (qobject_cast<InsertVirtualMethods *>(quickFixFactory)) { + QScopedPointer<CppQuickFixFactory> factoryProducingGuiLessOperations; + factoryProducingGuiLessOperations.reset( + new InsertVirtualMethods( + new InsertVirtualMethodsDialogTest( + InsertVirtualMethodsDialog::ModeOutsideClass, true))); + factoryProducingGuiLessOperations->match(qfi, operations); + } else { + quickFixFactory->match(qfi, operations); + } + foreach (QuickFixOperation::Ptr operation, operations) { qDebug() << " -- Performing Quick Fix" << operation->description(); operation->perform(); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index a88ce01cc3..82616e7be4 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -547,17 +547,24 @@ CppModelManager::ProjectInfo CppModelManager::projectInfo(ProjectExplorer::Proje return m_projects.value(project, ProjectInfo(project)); } -void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo) +QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &pinfo) { { // only hold the mutex for a limited scope, so the dumping afterwards can aquire it without deadlocking. QMutexLocker locker(&m_projectMutex); if (!pinfo.isValid()) - return; + return QFuture<void>(); ProjectExplorer::Project *project = pinfo.project().data(); ProjectInfo oldProjectInfo = m_projects.value(project); if (oldProjectInfo.isValid()) { + if (pinfo.defines() == oldProjectInfo.defines() + && pinfo.includePaths() == oldProjectInfo.includePaths() + && pinfo.frameworkPaths() == oldProjectInfo.frameworkPaths() + && pinfo.sourceFiles() == oldProjectInfo.sourceFiles()) { + return QFuture<void>(); + } + foreach (const ProjectPart::Ptr &projectPart, oldProjectInfo.projectParts()) { foreach (const ProjectFile &cxxFile, projectPart->files) { foreach (const QString &fileName, @@ -587,6 +594,8 @@ void CppModelManager::updateProjectInfo(const ProjectInfo &pinfo) dumpModelManagerConfiguration(); emit projectPartsUpdated(pinfo.project().data()); + + return updateSourceFiles(pinfo.sourceFiles(), ForcedProgressNotification); } QList<ProjectPart::Ptr> CppModelManager::projectPart(const QString &fileName) const diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index 8e51b5e373..5758cdb4b3 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -73,7 +73,7 @@ public: virtual QList<ProjectInfo> projectInfos() const; virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const; - virtual void updateProjectInfo(const ProjectInfo &pinfo); + virtual QFuture<void> updateProjectInfo(const ProjectInfo &pinfo); virtual QList<CppTools::ProjectPart::Ptr> projectPart(const QString &fileName) const; virtual CPlusPlus::Snapshot snapshot() const; diff --git a/src/plugins/cpptools/cppmodelmanager_test.cpp b/src/plugins/cpptools/cppmodelmanager_test.cpp index 7bd128d209..0c35d4099a 100644 --- a/src/plugins/cpptools/cppmodelmanager_test.cpp +++ b/src/plugins/cpptools/cppmodelmanager_test.cpp @@ -121,13 +121,13 @@ public: QCOMPARE(projectInfo.project().data(), project); ProjectPart::Ptr part(new ProjectPart); - projectInfo.appendProjectPart(part); part->cxxVersion = ProjectPart::CXX98; part->qtVersion = ProjectPart::Qt5; foreach (const QString &file, projectFiles) { ProjectFile projectFile(file, ProjectFile::classify(file)); part->files.append(projectFile); } + projectInfo.appendProjectPart(part); } ModelManagerTestHelper *modelManagerTestHelper; @@ -135,27 +135,68 @@ public: QStringList projectFiles; }; +/// Open and configure given project as example project and remove +/// generated *.user file on destruction. +/// +/// Requirement: No *.user file exists for the project. +class ExampleProjectConfigurator +{ +public: + ExampleProjectConfigurator(const QString &projectFile, + ProjectExplorer::ProjectExplorerPlugin *projectExplorer) + { + const QString projectUserFile = projectFile + QLatin1String(".user"); + QVERIFY(!QFileInfo(projectUserFile).exists()); + + // Open project + QString errorOpeningProject; + m_project = projectExplorer->openProject(projectFile, &errorOpeningProject); + QVERIFY(m_project); + QVERIFY(errorOpeningProject.isEmpty()); + + // Configure project + m_project->configureAsExampleProject(QStringList()); + + m_fileToRemove = projectUserFile; + } + + ~ExampleProjectConfigurator() + { + QVERIFY(!m_fileToRemove.isEmpty()); + QVERIFY(QFile::remove(m_fileToRemove)); + } + + ProjectExplorer::Project *project() const + { + return m_project; + } + +private: + ProjectExplorer::Project *m_project; + QString m_fileToRemove; +}; } // anonymous namespace -void CppToolsPlugin::test_modelmanager_paths() +/// Check: The preprocessor cleans include and framework paths. +void CppToolsPlugin::test_modelmanager_paths_are_clean() { ModelManagerTestHelper helper; CppModelManager *mm = CppModelManager::instance(); const TestDataDirectory testDataDir(QLatin1String("testdata")); - Project *project = helper.createProject(QLatin1String("test_modelmanager_paths")); + Project *project = helper.createProject(QLatin1String("test_modelmanager_paths_are_clean")); ProjectInfo pi = mm->projectInfo(project); QCOMPARE(pi.project().data(), project); ProjectPart::Ptr part(new ProjectPart); - pi.appendProjectPart(part); part->cxxVersion = ProjectPart::CXX98; part->qtVersion = ProjectPart::Qt5; part->defines = QByteArray("#define OH_BEHAVE -1\n"); part->includePaths = QStringList() << testDataDir.includeDir(false); part->frameworkPaths = QStringList() << testDataDir.frameworksDir(false); + pi.appendProjectPart(part); mm->updateProjectInfo(pi); @@ -168,6 +209,7 @@ void CppToolsPlugin::test_modelmanager_paths() QVERIFY(frameworkPaths.contains(testDataDir.frameworksDir())); } +/// Check: Frameworks headers are resolved. void CppToolsPlugin::test_modelmanager_framework_headers() { ModelManagerTestHelper helper; @@ -180,7 +222,6 @@ void CppToolsPlugin::test_modelmanager_framework_headers() QCOMPARE(pi.project().data(), project); ProjectPart::Ptr part(new ProjectPart); - pi.appendProjectPart(part); part->cxxVersion = ProjectPart::CXX98; part->qtVersion = ProjectPart::Qt5; part->defines = QByteArray("#define OH_BEHAVE -1\n"); @@ -189,6 +230,7 @@ void CppToolsPlugin::test_modelmanager_framework_headers() const QString &source = testDataDir.fileFromSourcesDir( QLatin1String("test_modelmanager_framework_headers.cpp")); part->files << ProjectFile(source, ProjectFile::CXXSource); + pi.appendProjectPart(part); mm->updateProjectInfo(pi); mm->updateSourceFiles(QStringList(source)).waitForFinished(); @@ -212,7 +254,9 @@ void CppToolsPlugin::test_modelmanager_framework_headers() } /// QTCREATORBUG-9056 -void CppToolsPlugin::test_modelmanager_refresh_1() +/// Check: If the project configuration changes, all project files and their +/// includes have to be reparsed. +void CppToolsPlugin::test_modelmanager_refresh_also_includes_of_project_files() { ModelManagerTestHelper helper; CppModelManager *mm = CppModelManager::instance(); @@ -224,20 +268,20 @@ void CppToolsPlugin::test_modelmanager_refresh_1() const QString testHeader(testDataDir.fileFromSourcesDir( QLatin1String("test_modelmanager_refresh.h"))); - Project *project = helper.createProject(QLatin1String("test_modelmanager_refresh_1")); + Project *project = helper.createProject( + QLatin1String("test_modelmanager_refresh_also_includes_of_project_files")); ProjectInfo pi = mm->projectInfo(project); QCOMPARE(pi.project().data(), project); ProjectPart::Ptr part(new ProjectPart); - pi.appendProjectPart(part); part->cxxVersion = ProjectPart::CXX98; part->qtVersion = ProjectPart::Qt5; part->defines = QByteArray("#define OH_BEHAVE -1\n"); part->includePaths = QStringList() << testDataDir.includeDir(false); part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource)); + pi.appendProjectPart(part); mm->updateProjectInfo(pi); - mm->updateSourceFiles(QStringList() << testCpp); QStringList refreshedFiles = helper.waitForRefreshedSourceFiles(); @@ -247,13 +291,16 @@ void CppToolsPlugin::test_modelmanager_refresh_1() QVERIFY(snapshot.contains(testHeader)); QVERIFY(snapshot.contains(testCpp)); - part->defines = QByteArray(); - mm->updateProjectInfo(pi); - snapshot = mm->snapshot(); - QVERIFY(!snapshot.contains(testHeader)); - QVERIFY(!snapshot.contains(testCpp)); + Document::Ptr headerDocumentBefore = snapshot.document(testHeader); + const QList<CPlusPlus::Macro> macrosInHeaderBefore = headerDocumentBefore->definedMacros(); + QCOMPARE(macrosInHeaderBefore.size(), 1); + QVERIFY(macrosInHeaderBefore.first().name() == "test_modelmanager_refresh_h"); - mm->updateSourceFiles(QStringList() << testCpp); + // Introduce a define that will enable another define once the document is reparsed. + part->defines = QByteArray("#define TEST_DEFINE 1\n"); + pi.clearProjectParts(); + pi.appendProjectPart(part); + mm->updateProjectInfo(pi); refreshedFiles = helper.waitForRefreshedSourceFiles(); QCOMPARE(refreshedFiles.size(), 1); @@ -261,10 +308,18 @@ void CppToolsPlugin::test_modelmanager_refresh_1() snapshot = mm->snapshot(); QVERIFY(snapshot.contains(testHeader)); QVERIFY(snapshot.contains(testCpp)); + + Document::Ptr headerDocumentAfter = snapshot.document(testHeader); + const QList<CPlusPlus::Macro> macrosInHeaderAfter = headerDocumentAfter->definedMacros(); + QCOMPARE(macrosInHeaderAfter.size(), 2); + QVERIFY(macrosInHeaderAfter.at(0).name() == "test_modelmanager_refresh_h"); + QVERIFY(macrosInHeaderAfter.at(1).name() == "TEST_DEFINE_DEFINED"); } /// QTCREATORBUG-9205 -void CppToolsPlugin::test_modelmanager_refresh_2() +/// Check: When reparsing the same files again, no errors occur +/// (The CppPreprocessor's already seen files are properly cleared!). +void CppToolsPlugin::test_modelmanager_refresh_several_times() { ModelManagerTestHelper helper; CppModelManager *mm = CppModelManager::instance(); @@ -275,17 +330,18 @@ void CppToolsPlugin::test_modelmanager_refresh_2() const QString testHeader2(testDataDir.file(QLatin1String("header.h"))); const QString testCpp(testDataDir.file(QLatin1String("source.cpp"))); - Project *project = helper.createProject(QLatin1String("test_modelmanager_refresh_2")); + Project *project = helper.createProject( + QLatin1String("test_modelmanager_refresh_several_times")); ProjectInfo pi = mm->projectInfo(project); QCOMPARE(pi.project().data(), project); ProjectPart::Ptr part(new ProjectPart); - pi.appendProjectPart(part); part->cxxVersion = ProjectPart::CXX98; part->qtVersion = ProjectPart::Qt5; part->files.append(ProjectFile(testHeader1, ProjectFile::CXXHeader)); part->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader)); part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource)); + pi.appendProjectPart(part); mm->updateProjectInfo(pi); @@ -293,8 +349,21 @@ void CppToolsPlugin::test_modelmanager_refresh_2() QStringList refreshedFiles; CPlusPlus::Document::Ptr document; + QByteArray defines = "#define FIRST_DEFINE"; for (int i = 0; i < 2; ++i) { - mm->updateSourceFiles(QStringList() << testHeader1 << testHeader2 << testCpp); + pi.clearProjectParts(); + ProjectPart::Ptr part(new ProjectPart); + // Simulate project configuration change by having different defines each time. + defines += "\n#define ANOTHER_DEFINE"; + part->defines = defines; + part->cxxVersion = ProjectPart::CXX98; + part->qtVersion = ProjectPart::Qt5; + part->files.append(ProjectFile(testHeader1, ProjectFile::CXXHeader)); + part->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader)); + part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource)); + pi.appendProjectPart(part); + + mm->updateProjectInfo(pi); refreshedFiles = helper.waitForRefreshedSourceFiles(); QCOMPARE(refreshedFiles.size(), 3); @@ -319,6 +388,40 @@ void CppToolsPlugin::test_modelmanager_refresh_2() } } +/// QTCREATORBUG-9581 +/// Check: If nothing has changes, nothing should be reindexed. +void CppToolsPlugin::test_modelmanager_refresh_test_for_changes() +{ + ModelManagerTestHelper helper; + CppModelManager *mm = CppModelManager::instance(); + + const TestDataDirectory testDataDir(QLatin1String("testdata_refresh")); + const QString testCpp(testDataDir.file(QLatin1String("source.cpp"))); + + Project *project = helper.createProject(QLatin1String("test_modelmanager_refresh_2")); + ProjectInfo pi = mm->projectInfo(project); + QCOMPARE(pi.project().data(), project); + + ProjectPart::Ptr part(new ProjectPart); + part->cxxVersion = ProjectPart::CXX98; + part->qtVersion = ProjectPart::Qt5; + part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource)); + pi.appendProjectPart(part); + + // Reindexing triggers a reparsing thread + QFuture<void> firstFuture = mm->updateProjectInfo(pi); + QVERIFY(firstFuture.isStarted() || firstFuture.isRunning()); + const QStringList refreshedFiles = helper.waitForRefreshedSourceFiles(); + QCOMPARE(refreshedFiles.size(), 1); + QVERIFY(refreshedFiles.contains(testCpp)); + + // No reindexing since nothing has changed + QFuture<void> subsequentFuture = mm->updateProjectInfo(pi); + QVERIFY(subsequentFuture.isCanceled() && subsequentFuture.isFinished()); +} + +/// Check: If a second project is opened, the code model is still aware of +/// files of the first project. void CppToolsPlugin::test_modelmanager_snapshot_after_two_projects() { QStringList refreshedFiles; @@ -328,14 +431,13 @@ void CppToolsPlugin::test_modelmanager_snapshot_after_two_projects() CppModelManager *mm = CppModelManager::instance(); // Project 1 - project1.create(QLatin1String("snapshot_after_two_projects.1"), + project1.create(QLatin1String("test_modelmanager_snapshot_after_two_projects.1"), QLatin1String("testdata_project1"), QStringList() << QLatin1String("foo.h") << QLatin1String("foo.cpp") << QLatin1String("main.cpp")); mm->updateProjectInfo(project1.projectInfo); - mm->updateSourceFiles(project1.projectFiles); refreshedFiles = helper.waitForRefreshedSourceFiles(); QCOMPARE(refreshedFiles.toSet(), project1.projectFiles.toSet()); const int snapshotSizeAfterProject1 = mm->snapshot().size(); @@ -344,14 +446,13 @@ void CppToolsPlugin::test_modelmanager_snapshot_after_two_projects() QVERIFY(mm->snapshot().contains(file)); // Project 2 - project2.create(QLatin1String("snapshot_after_two_projects.2"), + project2.create(QLatin1String("test_modelmanager_snapshot_after_two_projects.2"), QLatin1String("testdata_project2"), QStringList() << QLatin1String("bar.h") << QLatin1String("bar.cpp") << QLatin1String("main.cpp")); mm->updateProjectInfo(project2.projectInfo); - mm->updateSourceFiles(project2.projectFiles); refreshedFiles = helper.waitForRefreshedSourceFiles(); QCOMPARE(refreshedFiles.toSet(), project2.projectFiles.toSet()); @@ -365,6 +466,10 @@ void CppToolsPlugin::test_modelmanager_snapshot_after_two_projects() QVERIFY(mm->snapshot().contains(file)); } +/// Check: (1) For a project with a *.ui file an AbstractEditorSupport object +/// is added for the ui_* file. +/// Check: (2) The CppPreprocessor can successfully resolve the ui_* file +/// though it might not be actually generated in the build dir. void CppToolsPlugin::test_modelmanager_extraeditorsupport_uiFiles() { TestDataDirectory testDataDirectory(QLatin1String("testdata_guiproject1")); @@ -372,10 +477,8 @@ void CppToolsPlugin::test_modelmanager_extraeditorsupport_uiFiles() // Open project with *.ui file ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance(); - QString errorOpeningProject; - Project *project = pe->openProject(projectFile, &errorOpeningProject); - QVERIFY(errorOpeningProject.isEmpty()); - project->configureAsExampleProject(QStringList()); + ExampleProjectConfigurator exampleProjectConfigurator(projectFile, pe); + Project *project = exampleProjectConfigurator.project(); // Check working copy. // An AbstractEditorSupport object should have been added for the ui_* file. diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.h b/src/plugins/cpptools/cppmodelmanagerinterface.h index 07c945e19a..cf33a7aaba 100644 --- a/src/plugins/cpptools/cppmodelmanagerinterface.h +++ b/src/plugins/cpptools/cppmodelmanagerinterface.h @@ -215,7 +215,7 @@ public: virtual QList<ProjectInfo> projectInfos() const = 0; virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const = 0; - virtual void updateProjectInfo(const ProjectInfo &pinfo) = 0; + virtual QFuture<void> updateProjectInfo(const ProjectInfo &pinfo) = 0; virtual QList<ProjectPart::Ptr> projectPart(const QString &fileName) const = 0; virtual QStringList includePaths() = 0; diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index 62204fac96..09028beb6b 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -181,10 +181,11 @@ private slots: void test_format_pointerdeclaration_macros(); void test_format_pointerdeclaration_macros_data(); - void test_modelmanager_paths(); + void test_modelmanager_paths_are_clean(); void test_modelmanager_framework_headers(); - void test_modelmanager_refresh_1(); - void test_modelmanager_refresh_2(); + void test_modelmanager_refresh_also_includes_of_project_files(); + void test_modelmanager_refresh_several_times(); + void test_modelmanager_refresh_test_for_changes(); void test_modelmanager_snapshot_after_two_projects(); void test_modelmanager_extraeditorsupport_uiFiles(); void test_modelmanager_gc_if_last_cppeditor_closed(); diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index e231808957..92df0ebe88 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -285,9 +285,7 @@ void GenericProject::refresh(RefreshOptions options) pinfo.appendProjectPart(part); setProjectLanguage(ProjectExplorer::Constants::LANG_CXX, !part->files.isEmpty()); - modelManager->updateProjectInfo(pinfo); - m_codeModelFuture = modelManager->updateSourceFiles(filesToUpdate, - CppTools::CppModelManagerInterface::ForcedProgressNotification); + m_codeModelFuture = modelManager->updateProjectInfo(pinfo); } } diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp index 83d813b25c..06cb6ecccf 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp @@ -69,7 +69,6 @@ public: return -1; } - static DeviceManager *instance; static DeviceManager *clonedInstance; QList<IDevice::Ptr> devices; QHash<Core::Id, Core::Id> defaultDevices; @@ -77,7 +76,6 @@ public: Utils::PersistentSettingsWriter *writer; }; DeviceManager *DeviceManagerPrivate::clonedInstance = 0; -DeviceManager *DeviceManagerPrivate::instance = 0; } // namespace Internal @@ -86,7 +84,8 @@ using namespace Internal; DeviceManager *DeviceManager::instance() { - return DeviceManagerPrivate::instance; + static DeviceManager instance; + return &instance; } int DeviceManager::deviceCount() const @@ -242,7 +241,7 @@ void DeviceManager::addDevice(const IDevice::ConstPtr &_device) if (!defaultDevice(device->type())) d->defaultDevices.insert(device->type(), device->id()); - if (this == DeviceManagerPrivate::instance && d->clonedInstance) + if (this == DeviceManager::instance() && d->clonedInstance) d->clonedInstance->addDevice(device->clone()); if (pos >= 0) { @@ -338,11 +337,8 @@ const IDeviceFactory *DeviceManager::restoreFactory(const QVariantMap &map) DeviceManager::DeviceManager(bool isInstance) : d(new DeviceManagerPrivate) { - if (isInstance) { + if (isInstance) connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()), SLOT(save())); - QTC_CHECK(!DeviceManagerPrivate::instance); - DeviceManagerPrivate::instance = this; - } } DeviceManager::~DeviceManager() diff --git a/src/plugins/projectexplorer/environmentaspectwidget.cpp b/src/plugins/projectexplorer/environmentaspectwidget.cpp index 79ff5d6127..4234e8f63a 100644 --- a/src/plugins/projectexplorer/environmentaspectwidget.cpp +++ b/src/plugins/projectexplorer/environmentaspectwidget.cpp @@ -48,6 +48,7 @@ namespace ProjectExplorer { EnvironmentAspectWidget::EnvironmentAspectWidget(EnvironmentAspect *aspect, QWidget *additionalWidget) : RunConfigWidget(), m_aspect(aspect), + m_ignoreChange(false), m_additionalWidget(additionalWidget) { QTC_CHECK(m_aspect); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 0199c20c11..fbdb36aefe 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -334,7 +334,6 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er addAutoReleasedObject(new Internal::DesktopDeviceFactory); d->m_kitManager = new KitManager; // register before ToolChainManager - new DeviceManager; // Create DeviceManager singleton d->m_toolChainManager = new ToolChainManager; // Register KitInformation: diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index f816acd028..5b8ac5b790 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -600,9 +600,7 @@ void QbsProject::updateCppCodeModel(const qbs::ProjectData &prj) return; // Register update the code model: - modelmanager->updateProjectInfo(pinfo); - m_codeModelFuture = modelmanager->updateSourceFiles(allFiles, - CppTools::CppModelManagerInterface::ForcedProgressNotification); + m_codeModelFuture = modelmanager->updateProjectInfo(pinfo); } void QbsProject::updateQmlJsCodeModel(const qbs::ProjectData &prj) diff --git a/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h b/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h index 233941ed96..6c2f1e7931 100644 --- a/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h +++ b/src/plugins/qmlprofiler/abstractqmlprofilerrunner.h @@ -43,11 +43,12 @@ class AbstractQmlProfilerRunner : public QObject public: explicit AbstractQmlProfilerRunner(QObject *parent = 0) : QObject(parent) { } + virtual quint16 debugPort() const = 0; + +public slots: virtual void start() = 0; virtual void stop() = 0; - virtual quint16 debugPort() const = 0; - signals: void started(); void stopped(); diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp index a7883f506c..2a47feb46a 100644 --- a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp +++ b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp @@ -29,13 +29,62 @@ #include "localqmlprofilerrunner.h" #include "qmlprofilerplugin.h" +#include "qmlprofilerengine.h" + +#include <analyzerbase/analyzerstartparameters.h> +#include <projectexplorer/runconfiguration.h> +#include <qmlprojectmanager/qmlprojectrunconfiguration.h> +#include <projectexplorer/localapplicationrunconfiguration.h> +#include <projectexplorer/environmentaspect.h> using namespace QmlProfiler; using namespace QmlProfiler::Internal; +using namespace ProjectExplorer; + +LocalQmlProfilerRunner *LocalQmlProfilerRunner::createLocalRunner( + RunConfiguration *runConfiguration, + const Analyzer::AnalyzerStartParameters &sp, + QString *errorMessage, + QmlProfilerEngine *engine) +{ + QmlProjectManager::QmlProjectRunConfiguration *rc1 = + qobject_cast<QmlProjectManager::QmlProjectRunConfiguration *>(runConfiguration); + LocalApplicationRunConfiguration *rc2 = + qobject_cast<LocalApplicationRunConfiguration *>(runConfiguration); + QTC_ASSERT(rc1 || rc2, return 0); + ProjectExplorer::EnvironmentAspect *environment + = runConfiguration->extraAspect<ProjectExplorer::EnvironmentAspect>(); + QTC_ASSERT(environment, return 0); + Configuration conf; + if (rc1) { + // This is a "plain" .qmlproject. + conf.executable = rc1->observerPath(); + conf.executableArguments = rc1->viewerArguments(); + conf.workingDirectory = rc1->workingDirectory(); + conf.environment = environment->environment(); + } else { + // FIXME: Check. + conf.executable = rc2->executable(); + conf.executableArguments = rc2->commandLineArguments(); + conf.workingDirectory = rc2->workingDirectory(); + conf.environment = environment->environment(); + } + + conf.port = sp.analyzerPort; -LocalQmlProfilerRunner::LocalQmlProfilerRunner(const Configuration &configuration, QObject *parent) : - AbstractQmlProfilerRunner(parent), - m_configuration(configuration) + if (conf.executable.isEmpty()) { + if (errorMessage) + *errorMessage = tr("No executable file to launch."); + return 0; + } + return new LocalQmlProfilerRunner(conf, engine); +} + +LocalQmlProfilerRunner::LocalQmlProfilerRunner(const Configuration &configuration, + QmlProfilerEngine *engine) : + AbstractQmlProfilerRunner(engine), + m_configuration(configuration), + m_engine(engine) { connect(&m_launcher, SIGNAL(appendMessage(QString,Utils::OutputFormat)), this, SIGNAL(appendMessage(QString,Utils::OutputFormat))); @@ -48,6 +97,9 @@ LocalQmlProfilerRunner::~LocalQmlProfilerRunner() void LocalQmlProfilerRunner::start() { + if (m_engine->mode() != Analyzer::StartQml) + return; + QString arguments = QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(m_configuration.port); if (!m_configuration.executableArguments.isEmpty()) @@ -78,6 +130,9 @@ void LocalQmlProfilerRunner::spontaneousStop(int exitCode) void LocalQmlProfilerRunner::stop() { + if (m_engine->mode() != Analyzer::StartQml) + return; + if (QmlProfilerPlugin::debugOutput) qWarning("QmlProfiler: Stopping application ..."); diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.h b/src/plugins/qmlprofiler/localqmlprofilerrunner.h index 26a9b45161..37591917da 100644 --- a/src/plugins/qmlprofiler/localqmlprofilerrunner.h +++ b/src/plugins/qmlprofiler/localqmlprofilerrunner.h @@ -35,9 +35,13 @@ #include <utils/environment.h> #include <projectexplorer/applicationlauncher.h> +namespace ProjectExplorer { class RunConfiguration; } +namespace Analyzer { class AnalyzerStartParameters; } + namespace QmlProfiler { namespace Internal { +class QmlProfilerEngine; class LocalQmlProfilerRunner : public AbstractQmlProfilerRunner { Q_OBJECT @@ -51,7 +55,11 @@ public: Utils::Environment environment; }; - explicit LocalQmlProfilerRunner(const Configuration &configuration, QObject *parent = 0); + static LocalQmlProfilerRunner *createLocalRunner(ProjectExplorer::RunConfiguration *runConfiguration, + const Analyzer::AnalyzerStartParameters &sp, + QString *errorMessage, + QmlProfilerEngine *engine); + ~LocalQmlProfilerRunner(); // AbstractQmlProfilerRunner @@ -59,14 +67,16 @@ public: virtual void stop(); virtual quint16 debugPort() const; - bool hasExecutable() const { return !m_configuration.executable.isEmpty(); } - private slots: void spontaneousStop(int exitCode); private: + LocalQmlProfilerRunner(const Configuration &configuration, QmlProfilerEngine *engine); + +private: Configuration m_configuration; ProjectExplorer::ApplicationLauncher m_launcher; + QmlProfilerEngine *m_engine; }; } // namespace Internal diff --git a/src/plugins/qmlprofiler/qmlprofiler.pro b/src/plugins/qmlprofiler/qmlprofiler.pro index c2f6f05818..d644e47527 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.pro +++ b/src/plugins/qmlprofiler/qmlprofiler.pro @@ -20,7 +20,8 @@ SOURCES += \ qmlprofilerdatamodel.cpp \ qmlprofilerclientmanager.cpp \ qmlprofilerviewmanager.cpp \ - qmlprofilerstatewidget.cpp + qmlprofilerstatewidget.cpp \ + qmlprofilerruncontrolfactory.cpp HEADERS += \ qmlprofilerconstants.h \ @@ -40,7 +41,8 @@ HEADERS += \ qmlprofilerdatamodel.h \ qmlprofilerclientmanager.h \ qmlprofilerviewmanager.h \ - qmlprofilerstatewidget.h + qmlprofilerstatewidget.h \ + qmlprofilerruncontrolfactory.h RESOURCES += \ qml/qmlprofiler.qrc diff --git a/src/plugins/qmlprofiler/qmlprofiler.qbs b/src/plugins/qmlprofiler/qmlprofiler.qbs index cb136bf4d8..4550ec894f 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.qbs +++ b/src/plugins/qmlprofiler/qmlprofiler.qbs @@ -42,6 +42,8 @@ QtcPlugin { "qmlprofilereventview.h", "qmlprofilerplugin.cpp", "qmlprofilerplugin.h", + "qmlprofilerruncontrolfactory.cpp", + "qmlprofilerruncontrolfactory.h", "qmlprofilerstatemanager.cpp", "qmlprofilerstatemanager.h", "qmlprofilerstatewidget.cpp", diff --git a/src/plugins/qmlprofiler/qmlprofilerengine.cpp b/src/plugins/qmlprofiler/qmlprofilerengine.cpp index f1c9f84530..19395845b6 100644 --- a/src/plugins/qmlprofiler/qmlprofilerengine.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerengine.cpp @@ -64,64 +64,20 @@ namespace Internal { class QmlProfilerEngine::QmlProfilerEnginePrivate { public: - QmlProfilerEnginePrivate(QmlProfilerEngine *qq, const AnalyzerStartParameters &sp) : q(qq), m_runner(0), sp(sp) {} - ~QmlProfilerEnginePrivate() { delete m_runner; } + QmlProfilerEnginePrivate(QmlProfilerEngine *qq, const AnalyzerStartParameters &sp) : q(qq), sp(sp), m_running(false) {} bool attach(const QString &address, uint port); - AbstractQmlProfilerRunner *createRunner(ProjectExplorer::RunConfiguration *runConfiguration, - QObject *parent); QmlProfilerEngine *q; QmlProfilerStateManager *m_profilerState; - AbstractQmlProfilerRunner *m_runner; QTimer m_noDebugOutputTimer; QmlDebug::QmlOutputParser m_outputParser; const AnalyzerStartParameters sp; + bool m_running; }; -AbstractQmlProfilerRunner * -QmlProfilerEngine::QmlProfilerEnginePrivate::createRunner(ProjectExplorer::RunConfiguration *runConfiguration, - QObject *parent) -{ - AbstractQmlProfilerRunner *runner = 0; - if (!runConfiguration) // attaching - return 0; - - QmlProjectManager::QmlProjectRunConfiguration *rc1 = - qobject_cast<QmlProjectManager::QmlProjectRunConfiguration *>(runConfiguration); - LocalApplicationRunConfiguration *rc2 = - qobject_cast<LocalApplicationRunConfiguration *>(runConfiguration); - // Supports only local run configurations - if (!rc1 && !rc2) - return 0; - - ProjectExplorer::EnvironmentAspect *environment - = runConfiguration->extraAspect<ProjectExplorer::EnvironmentAspect>(); - QTC_ASSERT(environment, return 0); - LocalQmlProfilerRunner::Configuration conf; - if (rc1) { - // This is a "plain" .qmlproject. - conf.executable = rc1->observerPath(); - conf.executableArguments = rc1->viewerArguments(); - conf.workingDirectory = rc1->workingDirectory(); - conf.environment = environment->environment(); - } else { - // FIXME: Check. - conf.executable = rc2->executable(); - conf.executableArguments = rc2->commandLineArguments(); - conf.workingDirectory = rc2->workingDirectory(); - conf.environment = environment->environment(); - } - const ProjectExplorer::IDevice::ConstPtr device = - ProjectExplorer::DeviceKitInformation::device(runConfiguration->target()->kit()); - QTC_ASSERT(device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE, return 0); - conf.port = sp.analyzerPort; - runner = new LocalQmlProfilerRunner(conf, parent); - return runner; -} - // // QmlProfilerEngine // @@ -160,11 +116,6 @@ bool QmlProfilerEngine::start() { QTC_ASSERT(d->m_profilerState, return false); - if (d->m_runner) { - delete d->m_runner; - d->m_runner = 0; - } - d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppStarting); if (QmlProjectManager::QmlProjectRunConfiguration *rc = @@ -177,31 +128,14 @@ bool QmlProfilerEngine::start() } } - d->m_runner = d->createRunner(runConfiguration(), this); - - if (LocalQmlProfilerRunner *qmlRunner = qobject_cast<LocalQmlProfilerRunner *>(d->m_runner)) { - if (!qmlRunner->hasExecutable()) { - showNonmodalWarning(tr("No executable file to launch.")); - d->m_profilerState->setCurrentState(QmlProfilerStateManager::Idle); - AnalyzerManager::stopTool(); - return false; - } - } - - if (d->m_runner) { - connect(d->m_runner, SIGNAL(stopped()), this, SLOT(notifyRemoteFinished())); - connect(d->m_runner, SIGNAL(appendMessage(QString,Utils::OutputFormat)), - this, SLOT(logApplicationMessage(QString,Utils::OutputFormat))); - d->m_runner->start(); - d->m_noDebugOutputTimer.start(); - } else if (d->sp.startMode == StartQmlRemote) { + if (d->sp.startMode == StartQmlRemote || d->sp.startMode == StartLocal) { d->m_noDebugOutputTimer.start(); } else { emit processRunning(startParameters().analyzerPort); } d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning); - emit starting(this); + engineStarted(); return true; } @@ -242,7 +176,7 @@ void QmlProfilerEngine::notifyRemoteFinished(bool success) d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppKilled); AnalyzerManager::stopTool(); - emit finished(); + engineFinished(); break; } case QmlProfilerStateManager::AppStopped : @@ -262,10 +196,6 @@ void QmlProfilerEngine::cancelProcess() { QTC_ASSERT(d->m_profilerState, return); - // no process to be canceled? (there might be multiple engines, but only one runs a process) - if (!d->m_runner) - return; - switch (d->m_profilerState->currentState()) { case QmlProfilerStateManager::AppReadyToStop : { d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppStopped); @@ -282,10 +212,7 @@ void QmlProfilerEngine::cancelProcess() return; } } - - if (d->m_runner) - d->m_runner->stop(); - emit finished(); + engineFinished(); } void QmlProfilerEngine::logApplicationMessage(const QString &msg, Utils::OutputFormat format) @@ -314,7 +241,7 @@ void QmlProfilerEngine::wrongSetupMessageBox(const QString &errorMessage) // KILL d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying); AnalyzerManager::stopTool(); - emit finished(); + engineFinished(); } void QmlProfilerEngine::wrongSetupMessageBoxFinished(int button) @@ -348,10 +275,20 @@ void QmlProfilerEngine::processIsRunning(quint16 port) { d->m_noDebugOutputTimer.stop(); - if (port > 0) + if (port > 0 && mode() != StartQmlRemote) emit processRunning(port); - else if (d->m_runner) - emit processRunning(d->m_runner->debugPort()); +} + +void QmlProfilerEngine::engineStarted() +{ + d->m_running = true; + emit starting(this); +} + +void QmlProfilerEngine::engineFinished() +{ + d->m_running = false; + emit finished(); } //////////////////////////////////////////////////////////////// @@ -373,17 +310,12 @@ void QmlProfilerEngine::profilerStateChanged() { switch (d->m_profilerState->currentState()) { case QmlProfilerStateManager::AppReadyToStop : { - cancelProcess(); + if (d->m_running) + cancelProcess(); break; } case QmlProfilerStateManager::Idle : { - // When all the profiling is done, delete the profiler runner - // (a new one will be created at start) d->m_noDebugOutputTimer.stop(); - if (d->m_runner) { - delete d->m_runner; - d->m_runner = 0; - } break; } default: diff --git a/src/plugins/qmlprofiler/qmlprofilerengine.h b/src/plugins/qmlprofiler/qmlprofilerengine.h index 2a7d24998f..aea3c8bf8d 100644 --- a/src/plugins/qmlprofiler/qmlprofilerengine.h +++ b/src/plugins/qmlprofiler/qmlprofilerengine.h @@ -69,6 +69,8 @@ private slots: void wrongSetupMessageBox(const QString &errorMessage); void wrongSetupMessageBoxFinished(int); void processIsRunning(quint16 port = 0); + void engineStarted(); + void engineFinished(); private slots: void profilerStateChanged(); diff --git a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp index 4d49ff1d8a..70e016cf09 100644 --- a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp @@ -28,6 +28,7 @@ ****************************************************************************/ #include "qmlprofilerplugin.h" +#include "qmlprofilerruncontrolfactory.h" #include "qmlprofilertool.h" @@ -50,6 +51,8 @@ bool QmlProfilerPlugin::initialize(const QStringList &arguments, QString *errorS modes.append(StartMode(StartRemote)); AnalyzerManager::addTool(new QmlProfilerTool(this), modes); + addAutoReleasedObject(new QmlProfilerRunControlFactory()); + return true; } diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp new file mode 100644 index 0000000000..b956039d3c --- /dev/null +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: 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 "qmlprofilerruncontrolfactory.h" +#include "localqmlprofilerrunner.h" +#include "qmlprofilerengine.h" + +#include <analyzerbase/ianalyzertool.h> +#include <analyzerbase/analyzermanager.h> +#include <analyzerbase/analyzerstartparameters.h> +#include <analyzerbase/analyzerruncontrol.h> +#include <analyzerbase/analyzersettings.h> + +#include <projectexplorer/kitinformation.h> +#include <projectexplorer/target.h> + +#include <utils/qtcassert.h> + +using namespace Analyzer; +using namespace ProjectExplorer; + +namespace QmlProfiler { +namespace Internal { + +QmlProfilerRunControlFactory::QmlProfilerRunControlFactory(QObject *parent) : + IRunControlFactory(parent) +{ +} + +bool QmlProfilerRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +{ + if (mode != QmlProfilerRunMode) + return false; + IAnalyzerTool *tool = AnalyzerManager::toolFromRunMode(mode); + if (tool) + return tool->canRun(runConfiguration, mode); + return false; +} + +RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) +{ + IAnalyzerTool *tool = AnalyzerManager::toolFromRunMode(mode); + if (!tool) { + if (errorMessage) + *errorMessage = tr("No analyzer tool selected"); // never happens + return 0; + } + + QTC_ASSERT(canRun(runConfiguration, mode), return 0); + + AnalyzerStartParameters sp = tool->createStartParameters(runConfiguration, mode); + sp.toolId = tool->id(); + + // only desktop device is supported + const ProjectExplorer::IDevice::ConstPtr device = + ProjectExplorer::DeviceKitInformation::device(runConfiguration->target()->kit()); + QTC_ASSERT(device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE, return 0); + + AnalyzerRunControl *rc = new AnalyzerRunControl(tool, sp, runConfiguration); + QmlProfilerEngine *engine = qobject_cast<QmlProfilerEngine *>(rc->engine()); + if (!engine) { + delete rc; + return 0; + } + LocalQmlProfilerRunner *runner = LocalQmlProfilerRunner::createLocalRunner(runConfiguration, sp, errorMessage, engine); + if (!runner) + return 0; + connect(runner, SIGNAL(stopped()), engine, SLOT(notifyRemoteFinished())); + connect(runner, SIGNAL(appendMessage(QString,Utils::OutputFormat)), + engine, SLOT(logApplicationMessage(QString,Utils::OutputFormat))); + connect(engine, SIGNAL(starting(const Analyzer::IAnalyzerEngine*)), runner, + SLOT(start())); + connect(rc, SIGNAL(finished()), runner, SLOT(stop())); + return rc; +} + +IRunConfigurationAspect *QmlProfilerRunControlFactory::createRunConfigurationAspect(RunConfiguration *rc) +{ + Q_UNUSED(rc); + return new AnalyzerRunConfigurationAspect; +} + +} // namespace Internal +} // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.h b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.h new file mode 100644 index 0000000000..a7f6d9ffe3 --- /dev/null +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: 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. +** +****************************************************************************/ + +#ifndef QMLPROFILERRUNCONTROLFACTORY_H +#define QMLPROFILERRUNCONTROLFACTORY_H + +#include <projectexplorer/runconfiguration.h> + +namespace QmlProfiler { +namespace Internal { + +class QmlProfilerRunControlFactory : public ProjectExplorer::IRunControlFactory +{ + Q_OBJECT +public: + typedef ProjectExplorer::RunConfiguration RunConfiguration; + + explicit QmlProfilerRunControlFactory(QObject *parent = 0); + + // IRunControlFactory implementation + bool canRun(RunConfiguration *runConfiguration, ProjectExplorer::RunMode mode) const; + + ProjectExplorer::RunControl *create(RunConfiguration *runConfiguration, + ProjectExplorer::RunMode mode, + QString *errorMessage); + ProjectExplorer::IRunConfigurationAspect *createRunConfigurationAspect(ProjectExplorer::RunConfiguration *rc); +}; + +} // namespace Internal +} // namespace QmlProfiler + +#endif // QMLPROFILERRUNCONTROLFACTORY_H diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp index aad9c0f6e8..3b13e95071 100644 --- a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp +++ b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp @@ -219,7 +219,7 @@ void BlackBerryDeviceConfigurationWizardSshKeyPage::findMatchingPublicKey(const { const QString candidate = privateKeyPath + QLatin1String(".pub"); if (QFileInfo(candidate).exists()) - m_ui->publicKey->setText(candidate); + m_ui->publicKey->setText(QDir::toNativeSeparators(candidate)); else m_ui->publicKey->clear(); } @@ -239,7 +239,7 @@ void BlackBerryDeviceConfigurationWizardSshKeyPage::processSshKeys(bool success) return; m_ui->privateKey->setFileName(Utils::FileName::fromString(m_generatedPrivateKeyPath)); - m_ui->publicKey->setText(publicKeyPath); + m_ui->publicKey->setText(QDir::toNativeSeparators(publicKeyPath)); emit completeChanged(); } diff --git a/src/plugins/qnx/qnxanalyzesupport.cpp b/src/plugins/qnx/qnxanalyzesupport.cpp index ac7cea766c..0605d02579 100644 --- a/src/plugins/qnx/qnxanalyzesupport.cpp +++ b/src/plugins/qnx/qnxanalyzesupport.cpp @@ -56,6 +56,8 @@ QnxAnalyzeSupport::QnxAnalyzeSupport(QnxRunConfiguration *runConfig, connect(m_engine, SIGNAL(starting(const Analyzer::IAnalyzerEngine*)), SLOT(handleAdapterSetupRequested())); + connect(&m_outputParser, SIGNAL(waitingForConnectionOnPort(quint16)), + SLOT(remoteIsRunning())); } void QnxAnalyzeSupport::handleAdapterSetupRequested() @@ -82,13 +84,6 @@ void QnxAnalyzeSupport::startExecution() appRunner()->start(device(), command.toUtf8()); } -void QnxAnalyzeSupport::handleRemoteProcessStarted() -{ - QnxAbstractRunSupport::handleRemoteProcessStarted(); - if (m_engine) - m_engine->notifyRemoteSetupDone(m_qmlPort); -} - void QnxAnalyzeSupport::handleRemoteProcessFinished(bool success) { if (m_engine || state() == Inactive) @@ -127,8 +122,15 @@ void QnxAnalyzeSupport::handleError(const QString &error) } } +void QnxAnalyzeSupport::remoteIsRunning() +{ + if (m_engine) + m_engine->notifyRemoteSetupDone(m_qmlPort); +} + void QnxAnalyzeSupport::showMessage(const QString &msg, Utils::OutputFormat format) { if (state() != Inactive && m_engine) m_engine->logApplicationMessage(msg, format); + m_outputParser.processOutput(msg); } diff --git a/src/plugins/qnx/qnxanalyzesupport.h b/src/plugins/qnx/qnxanalyzesupport.h index 66fa580abd..69aa813ad8 100644 --- a/src/plugins/qnx/qnxanalyzesupport.h +++ b/src/plugins/qnx/qnxanalyzesupport.h @@ -34,6 +34,7 @@ #include <projectexplorer/projectexplorerconstants.h> #include <utils/outputformat.h> +#include <qmldebug/qmloutputparser.h> namespace Analyzer { class IAnalyzerEngine; } @@ -54,17 +55,19 @@ public slots: private slots: void handleAdapterSetupRequested(); - void handleRemoteProcessStarted(); void handleRemoteProcessFinished(bool success); void handleProgressReport(const QString &progressOutput); void handleRemoteOutput(const QByteArray &output); void handleError(const QString &error); + void remoteIsRunning(); + private: void startExecution(); void showMessage(const QString &, Utils::OutputFormat); Analyzer::IAnalyzerEngine *m_engine; + QmlDebug::QmlOutputParser m_outputParser; int m_qmlPort; }; diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index 3ea6828eb1..23e7b406c5 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -602,9 +602,7 @@ void Qt4Project::updateCppCodeModel() setProjectLanguage(ProjectExplorer::Constants::LANG_CXX, !allFiles.isEmpty()); - modelmanager->updateProjectInfo(pinfo); - m_codeModelFuture = modelmanager->updateSourceFiles(allFiles, - CppTools::CppModelManagerInterface::ForcedProgressNotification); + m_codeModelFuture = modelmanager->updateProjectInfo(pinfo); } void Qt4Project::updateQmlJSCodeModel() diff --git a/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp b/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp index 0ae6c72439..6424cb80c8 100644 --- a/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp +++ b/src/plugins/remotelinux/abstractremotelinuxrunsupport.cpp @@ -123,29 +123,10 @@ void AbstractRemoteLinuxRunSupport::handlePortListReady() startExecution(); } -void AbstractRemoteLinuxRunSupport::handleAppRunnerError(const QString &) -{ -} - -void AbstractRemoteLinuxRunSupport::handleRemoteOutput(const QByteArray &) -{ -} - -void AbstractRemoteLinuxRunSupport::handleRemoteErrorOutput(const QByteArray &) -{ -} - -void AbstractRemoteLinuxRunSupport::handleAppRunnerFinished(bool) -{ -} - -void AbstractRemoteLinuxRunSupport::handleProgressReport(const QString &) -{ -} - void AbstractRemoteLinuxRunSupport::handleAdapterSetupFailed(const QString &) { setFinished(); + reset(); } void AbstractRemoteLinuxRunSupport::handleAdapterSetupDone() @@ -157,8 +138,6 @@ void AbstractRemoteLinuxRunSupport::setFinished() { if (d->state == Inactive) return; - d->portsGatherer.disconnect(this); - d->appRunner.disconnect(this); if (d->state == Running) { const QString stopCommand = d->device->processSupport()->killProcessByNameCommandLine(d->remoteFilePath); @@ -197,6 +176,13 @@ const IDevice::ConstPtr AbstractRemoteLinuxRunSupport::device() const return d->device; } +void AbstractRemoteLinuxRunSupport::reset() +{ + d->portsGatherer.disconnect(this); + d->appRunner.disconnect(this); + d->state = Inactive; +} + DeviceApplicationRunner *AbstractRemoteLinuxRunSupport::appRunner() const { return &d->appRunner; diff --git a/src/plugins/remotelinux/abstractremotelinuxrunsupport.h b/src/plugins/remotelinux/abstractremotelinuxrunsupport.h index 3e8ee6276d..a7a954681b 100644 --- a/src/plugins/remotelinux/abstractremotelinuxrunsupport.h +++ b/src/plugins/remotelinux/abstractremotelinuxrunsupport.h @@ -84,13 +84,15 @@ protected: QString remoteFilePath() const; const ProjectExplorer::IDevice::ConstPtr device() const; + void reset(); + protected slots: virtual void handleRemoteSetupRequested(); - virtual void handleAppRunnerError(const QString &error); - virtual void handleRemoteOutput(const QByteArray &output); - virtual void handleRemoteErrorOutput(const QByteArray &output); - virtual void handleAppRunnerFinished(bool success); - virtual void handleProgressReport(const QString &progressOutput); + virtual void handleAppRunnerError(const QString &error) = 0; + virtual void handleRemoteOutput(const QByteArray &output) = 0; + virtual void handleRemoteErrorOutput(const QByteArray &output) = 0; + virtual void handleAppRunnerFinished(bool success) = 0; + virtual void handleProgressReport(const QString &progressOutput) = 0; private slots: void handlePortsGathererError(const QString &message); diff --git a/src/plugins/remotelinux/remotelinux.qbs b/src/plugins/remotelinux/remotelinux.qbs index 7e6ad2b0d2..15cf5ce44a 100644 --- a/src/plugins/remotelinux/remotelinux.qbs +++ b/src/plugins/remotelinux/remotelinux.qbs @@ -10,6 +10,7 @@ QtcPlugin { Depends { name: "Core" } Depends { name: "Debugger" } Depends { name: "ProjectExplorer" } + Depends { name: "QmlDebug" } Depends { name: "QtSupport" } Depends { name: "QtcSsh" } diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp index 3563053bce..40125ce206 100644 --- a/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp +++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.cpp @@ -41,6 +41,7 @@ #include <projectexplorer/kitinformation.h> #include <utils/qtcassert.h> +#include <qmldebug/qmloutputparser.h> #include <QPointer> @@ -64,6 +65,8 @@ public: const QPointer<IAnalyzerEngine> engine; bool qmlProfiling; int qmlPort; + + QmlDebug::QmlOutputParser outputParser; }; } // namespace Internal @@ -76,14 +79,11 @@ AnalyzerStartParameters RemoteLinuxAnalyzeSupport::startParameters(const RemoteL AnalyzerStartParameters params; if (runMode == QmlProfilerRunMode) params.startMode = StartQmlRemote; - params.debuggee = runConfig->remoteExecutableFilePath(); - params.debuggeeArgs = runConfig->arguments(); params.connParams = DeviceKitInformation::device(runConfig->target()->kit())->sshParameters(); params.analyzerCmdPrefix = runConfig->commandPrefix(); params.displayName = runConfig->displayName(); params.sysroot = SysRootKitInformation::sysRoot(runConfig->target()->kit()).toString(); params.analyzerHost = params.connParams.host; - params.analyzerPort = params.connParams.port; return params; } @@ -95,7 +95,8 @@ RemoteLinuxAnalyzeSupport::RemoteLinuxAnalyzeSupport(RemoteLinuxRunConfiguration { connect(d->engine, SIGNAL(starting(const Analyzer::IAnalyzerEngine*)), SLOT(handleRemoteSetupRequested())); - connect(d->engine, SIGNAL(finished()), SLOT(handleProfilingFinished())); + connect(&d->outputParser, SIGNAL(waitingForConnectionOnPort(quint16)), + SLOT(remoteIsRunning())); } RemoteLinuxAnalyzeSupport::~RemoteLinuxAnalyzeSupport() @@ -107,10 +108,14 @@ void RemoteLinuxAnalyzeSupport::showMessage(const QString &msg, Utils::OutputFor { if (state() != Inactive && d->engine) d->engine->logApplicationMessage(msg, format); + d->outputParser.processOutput(msg); } void RemoteLinuxAnalyzeSupport::handleRemoteSetupRequested() { + if (d->engine->mode() != Analyzer::StartQmlRemote) + return; + QTC_ASSERT(state() == Inactive, return); showMessage(tr("Checking available ports...\n"), Utils::NormalMessageFormat); @@ -154,15 +159,25 @@ void RemoteLinuxAnalyzeSupport::handleAppRunnerError(const QString &error) void RemoteLinuxAnalyzeSupport::handleAppRunnerFinished(bool success) { + // reset needs to be called first to ensure that the correct state is set. + reset(); if (!success) showMessage(tr("Failure running remote process."), Utils::NormalMessageFormat); + d->engine->notifyRemoteFinished(success); } void RemoteLinuxAnalyzeSupport::handleProfilingFinished() { + if (d->engine->mode() != Analyzer::StartQmlRemote) + return; setFinished(); } +void RemoteLinuxAnalyzeSupport::remoteIsRunning() +{ + d->engine->notifyRemoteSetupDone(d->qmlPort); +} + void RemoteLinuxAnalyzeSupport::handleRemoteOutput(const QByteArray &output) { QTC_ASSERT(state() == Inactive || state() == Running, return); @@ -191,12 +206,6 @@ void RemoteLinuxAnalyzeSupport::handleAdapterSetupFailed(const QString &error) showMessage(tr("Initial setup failed: %1").arg(error), Utils::NormalMessageFormat); } -void RemoteLinuxAnalyzeSupport::handleAdapterSetupDone() -{ - AbstractRemoteLinuxRunSupport::handleAdapterSetupDone(); - d->engine->notifyRemoteSetupDone(d->qmlPort); -} - void RemoteLinuxAnalyzeSupport::handleRemoteProcessStarted() { QTC_ASSERT(d->qmlProfiling, return); diff --git a/src/plugins/remotelinux/remotelinuxanalyzesupport.h b/src/plugins/remotelinux/remotelinuxanalyzesupport.h index cfbb1a7ff3..98f713828c 100644 --- a/src/plugins/remotelinux/remotelinuxanalyzesupport.h +++ b/src/plugins/remotelinux/remotelinuxanalyzesupport.h @@ -59,7 +59,6 @@ public: protected: void startExecution(); void handleAdapterSetupFailed(const QString &error); - void handleAdapterSetupDone(); private slots: void handleRemoteSetupRequested(); @@ -72,6 +71,8 @@ private slots: void handleRemoteProcessStarted(); void handleProfilingFinished(); + void remoteIsRunning(); + private: void showMessage(const QString &, Utils::OutputFormat); diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp index 1bbc26892a..2ccecb0e5f 100644 --- a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp +++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp @@ -198,14 +198,16 @@ void LinuxDeviceDebugSupport::handleAppRunnerFinished(bool success) else if (!success) d->engine->notifyInferiorIll(); - } else { + } else if (state() == StartingRunner){ d->engine->notifyEngineRemoteSetupFailed(tr("Debugging failed.")); } + reset(); } void LinuxDeviceDebugSupport::handleDebuggingFinished() { setFinished(); + reset(); } void LinuxDeviceDebugSupport::handleRemoteOutput(const QByteArray &output) diff --git a/src/plugins/valgrind/valgrind.pro b/src/plugins/valgrind/valgrind.pro index e3ebcb1e99..8d504b2ff5 100644 --- a/src/plugins/valgrind/valgrind.pro +++ b/src/plugins/valgrind/valgrind.pro @@ -29,7 +29,8 @@ HEADERS += \ memcheckengine.h \ memcheckerrorview.h \ suppressiondialog.h \ - valgrindtool.h + valgrindtool.h \ + valgrindruncontrolfactory.h SOURCES += \ valgrindplugin.cpp \ @@ -52,7 +53,8 @@ SOURCES += \ memcheckengine.cpp \ memcheckerrorview.cpp \ suppressiondialog.cpp \ - valgrindtool.cpp + valgrindtool.cpp \ + valgrindruncontrolfactory.cpp FORMS += \ valgrindconfigwidget.ui diff --git a/src/plugins/valgrind/valgrind.qbs b/src/plugins/valgrind/valgrind.qbs index aeb1ce262a..0f6d1a9a89 100644 --- a/src/plugins/valgrind/valgrind.qbs +++ b/src/plugins/valgrind/valgrind.qbs @@ -48,6 +48,8 @@ QtcPlugin { "valgrindplugin.h", "valgrindprocess.cpp", "valgrindprocess.h", + "valgrindruncontrolfactory.cpp", + "valgrindruncontrolfactory.h", "valgrindrunner.cpp", "valgrindrunner.h", "valgrindsettings.cpp", diff --git a/src/plugins/valgrind/valgrindplugin.cpp b/src/plugins/valgrind/valgrindplugin.cpp index 005d0a4c4f..88a0232b4d 100644 --- a/src/plugins/valgrind/valgrindplugin.cpp +++ b/src/plugins/valgrind/valgrindplugin.cpp @@ -32,6 +32,7 @@ #include "callgrindtool.h" #include "memchecktool.h" +#include "valgrindruncontrolfactory.h" #include <analyzerbase/analyzerconstants.h> #include <analyzerbase/analyzermanager.h> @@ -99,6 +100,8 @@ bool ValgrindPlugin::initialize(const QStringList &, QString *) AnalyzerManager::addTool(new MemcheckTool(this), modes); AnalyzerManager::addTool(new CallgrindTool(this), modes); + addAutoReleasedObject(new ValgrindRunControlFactory()); + return true; } diff --git a/src/plugins/analyzerbase/analyzerruncontrolfactory.cpp b/src/plugins/valgrind/valgrindruncontrolfactory.cpp index 9367ccacc7..4fbbb40ea0 100644 --- a/src/plugins/analyzerbase/analyzerruncontrolfactory.cpp +++ b/src/plugins/valgrind/valgrindruncontrolfactory.cpp @@ -1,7 +1,7 @@ -/************************************************************************** +/**************************************************************************** ** -** Copyright (C) 2013 Kläralvdalens Datakonsult AB, a KDAB Group company. -** Contact: Kläralvdalens Datakonsult AB (info@kdab.com) +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of Qt Creator. ** @@ -27,36 +27,38 @@ ** ****************************************************************************/ -#include "analyzerruncontrolfactory.h" -#include "analyzersettings.h" -#include "analyzerruncontrol.h" -#include "analyzermanager.h" -#include "ianalyzertool.h" -#include "analyzerstartparameters.h" +#include "valgrindruncontrolfactory.h" -#include <utils/qtcassert.h> +#include <analyzerbase/ianalyzertool.h> +#include <analyzerbase/analyzermanager.h> +#include <analyzerbase/analyzerstartparameters.h> +#include <analyzerbase/analyzerruncontrol.h> +#include <analyzerbase/analyzersettings.h> -#include <QAction> +#include <utils/qtcassert.h> +using namespace Analyzer; using namespace ProjectExplorer; -namespace Analyzer { +namespace Valgrind { namespace Internal { -AnalyzerRunControlFactory::AnalyzerRunControlFactory(QObject *parent) : +ValgrindRunControlFactory::ValgrindRunControlFactory(QObject *parent) : IRunControlFactory(parent) { } -bool AnalyzerRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +bool ValgrindRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const { + if (mode != CallgrindRunMode && mode != MemcheckRunMode) + return false; IAnalyzerTool *tool = AnalyzerManager::toolFromRunMode(mode); if (tool) return tool->canRun(runConfiguration, mode); return false; } -RunControl *AnalyzerRunControlFactory::create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) +RunControl *ValgrindRunControlFactory::create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) { IAnalyzerTool *tool = AnalyzerManager::toolFromRunMode(mode); if (!tool) { @@ -74,11 +76,11 @@ RunControl *AnalyzerRunControlFactory::create(RunConfiguration *runConfiguration return rc; } -IRunConfigurationAspect *AnalyzerRunControlFactory::createRunConfigurationAspect(RunConfiguration *rc) +IRunConfigurationAspect *ValgrindRunControlFactory::createRunConfigurationAspect(RunConfiguration *rc) { Q_UNUSED(rc); return new AnalyzerRunConfigurationAspect; } } // namespace Internal -} // namespace Analyzer +} // namespace Valgrind diff --git a/src/plugins/analyzerbase/analyzerruncontrolfactory.h b/src/plugins/valgrind/valgrindruncontrolfactory.h index 1a041c222d..74cd0d79a4 100644 --- a/src/plugins/analyzerbase/analyzerruncontrolfactory.h +++ b/src/plugins/valgrind/valgrindruncontrolfactory.h @@ -1,7 +1,7 @@ -/************************************************************************** +/**************************************************************************** ** -** Copyright (C) 2013 Kläralvdalens Datakonsult AB, a KDAB Group company. -** Contact: Kläralvdalens Datakonsult AB (info@kdab.com) +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of Qt Creator. ** @@ -27,24 +27,25 @@ ** ****************************************************************************/ -#ifndef ANALYZERRUNCONTROLFACTORY_H -#define ANALYZERRUNCONTROLFACTORY_H +#ifndef VALGRINDRUNCONTROLFACTORY_H +#define VALGRINDRUNCONTROLFACTORY_H -#include <analyzerbase/analyzerruncontrol.h> +#include <projectexplorer/runconfiguration.h> -namespace Analyzer { +namespace Valgrind { namespace Internal { -class AnalyzerRunControlFactory : public ProjectExplorer::IRunControlFactory +class ValgrindRunControlFactory : public ProjectExplorer::IRunControlFactory { Q_OBJECT public: typedef ProjectExplorer::RunConfiguration RunConfiguration; - explicit AnalyzerRunControlFactory(QObject *parent = 0); + explicit ValgrindRunControlFactory(QObject *parent = 0); // IRunControlFactory implementation bool canRun(RunConfiguration *runConfiguration, ProjectExplorer::RunMode mode) const; + ProjectExplorer::RunControl *create(RunConfiguration *runConfiguration, ProjectExplorer::RunMode mode, QString *errorMessage); @@ -52,6 +53,6 @@ public: }; } // namespace Internal -} // namespace Analyzer +} // namespace Valgrind -#endif // ANALYZERRUNCONTROLFACTORY_H +#endif // VALGRINDRUNCONTROLFACTORY_H diff --git a/src/shared/proparser/qmakevfs.h b/src/shared/proparser/qmakevfs.h index 045765a362..87f39ecbd5 100644 --- a/src/shared/proparser/qmakevfs.h +++ b/src/shared/proparser/qmakevfs.h @@ -32,10 +32,10 @@ #include "qmake_global.h" -# include <QIODevice> +# include <qiodevice.h> #ifndef PROEVALUATOR_FULL -# include <QHash> -# include <QString> +# include <qhash.h> +# include <qstring.h> # ifdef PROEVALUATOR_THREAD_SAFE # include <qmutex.h> # endif diff --git a/src/shared/qbs b/src/shared/qbs -Subproject 4051b5f9c81c40123c68ac5b7774d1dcb212348 +Subproject 7474cf4c7aca19b05a4a8cd8619b0de714517f7 |