From 3d57758d61cab890217ef75611076397cdf0061e Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 24 Nov 2011 11:48:00 +0100 Subject: [PATCH 1/6] Transform always old code style settings Before, we didn't transform the code style settings if they were defaults (so no entries were written for them in the settings). In case someone changed global tab settings and didn't touch code style settings in 2.3, the code style settings were not transformed. Now, we transform them too so that legacy code style settings in 2.4 (named: "Old Creator") contains old global tab settings. We also take care of not creating legacy settings in case neither textTabPreferences nor CppTabPreferences nor CppCodeStyleSettings were saved (when creator 2.3 used only defaults or when it's a first run of creator 2.4 without old settings). Handle legacy transformation for qml too. Make a code bit more readable. Task-number: QTCREATORBUG-6614 Change-Id: I37b8dd4d1170f397b7d304c59575d9ae37884564 Reviewed-by: Leandro Melo Reviewed-by: Christian Kamm --- src/plugins/cpptools/cpptoolssettings.cpp | 92 +++++++++---------- src/plugins/qmljstools/qmljstoolssettings.cpp | 43 ++++++++- 2 files changed, 84 insertions(+), 51 deletions(-) diff --git a/src/plugins/cpptools/cpptoolssettings.cpp b/src/plugins/cpptools/cpptoolssettings.cpp index 85134f035b0..47d144ede53 100644 --- a/src/plugins/cpptools/cpptoolssettings.cpp +++ b/src/plugins/cpptools/cpptoolssettings.cpp @@ -53,25 +53,6 @@ using TextEditor::TabSettings; namespace CppTools { namespace Internal { -class LegacySettings -{ -public: - LegacySettings() - : m_legacyTransformed(false) - { } - void fromMap(const QString &prefix, const QVariantMap &map) - { - m_fallbackId = map.value(prefix + QLatin1String("CurrentFallback")).toString(); - m_legacyTransformed = map.value(prefix + QLatin1String("LegacyTransformed"), false).toBool(); - } - void toMap(const QString &prefix, QVariantMap *map) const - { - map->insert(prefix + QLatin1String("LegacyTransformed"), true); - } - QString m_fallbackId; - bool m_legacyTransformed; -}; - class CppToolsSettingsPrivate { public: @@ -176,40 +157,51 @@ CppToolsSettings::CppToolsSettings(QObject *parent) if (QSettings *s = Core::ICore::instance()->settings()) { d->m_globalCodeStyle->fromSettings(CppTools::Constants::CPP_SETTINGS_ID, s); - // legacy handling start (Qt Creator <= 2.3) - Internal::LegacySettings legacySettings; + // legacy handling start (Qt Creator Version < 2.4) + const bool legacyTransformed = + s->value(QLatin1String("CppCodeStyleSettings/LegacyTransformed"), false).toBool(); - TabSettings legacyTabSettings; - Utils::fromSettings(QLatin1String("TabPreferences"), - QLatin1String("Cpp"), s, &legacySettings); - if (legacySettings.m_fallbackId == QLatin1String("CppGlobal")) { - Utils::fromSettings(QLatin1String("TabPreferences"), - QLatin1String("Cpp"), s, &legacyTabSettings); - } else { - legacyTabSettings = textEditorSettings->codeStyle()->currentTabSettings(); - } + if (!legacyTransformed) { + // creator 2.4 didn't mark yet the transformation (first run of creator 2.4) - CppCodeStyleSettings legacyCodeStyleSettings; - Utils::fromSettings(QLatin1String("CodeStyleSettings"), - QLatin1String("Cpp"), s, &legacySettings); - if (!legacySettings.m_legacyTransformed - && legacySettings.m_fallbackId == QLatin1String("CppGlobal")) { - Utils::fromSettings(QLatin1String("CodeStyleSettings"), - QLatin1String("Cpp"), s, &legacyCodeStyleSettings); - // create custom code style out of old settings - QVariant v; - v.setValue(legacyCodeStyleSettings); - TextEditor::ICodeStylePreferences *oldCreator = pool->createCodeStyle( - QLatin1String("legacy"), legacyTabSettings, - v, tr("Old Creator")); - // change the current delegate and save - d->m_globalCodeStyle->setCurrentDelegate(oldCreator); - d->m_globalCodeStyle->toSettings(CppTools::Constants::CPP_SETTINGS_ID, s); + // we need to transform the settings only if at least one from + // below settings was already written - otherwise we use + // defaults like it would be the first run of creator 2.4 without stored settings + const QStringList groups = s->childGroups(); + const bool needTransform = groups.contains(QLatin1String("textTabPreferences")) || + groups.contains(QLatin1String("CppTabPreferences")) || + groups.contains(QLatin1String("CppCodeStyleSettings")); + if (needTransform) { + CppCodeStyleSettings legacyCodeStyleSettings; + if (groups.contains(QLatin1String("CppCodeStyleSettings"))) { + Utils::fromSettings(QLatin1String("CppCodeStyleSettings"), + QString(), s, &legacyCodeStyleSettings); + } - // mark old settings as transformed, - // we create only once "Old Creator" custom settings - Utils::toSettings(QLatin1String("CodeStyleSettings"), - QLatin1String("Cpp"), s, &legacySettings); + const QString currentFallback = s->value(QLatin1String("CppTabPreferences/CurrentFallback")).toString(); + TabSettings legacyTabSettings; + if (currentFallback == QLatin1String("CppGlobal")) { + // no delegate, global overwritten + Utils::fromSettings(QLatin1String("CppTabPreferences"), + QString(), s, &legacyTabSettings); + } else { + // delegating to global + legacyTabSettings = textEditorSettings->codeStyle()->currentTabSettings(); + } + + // create custom code style out of old settings + QVariant v; + v.setValue(legacyCodeStyleSettings); + TextEditor::ICodeStylePreferences *oldCreator = pool->createCodeStyle( + QLatin1String("legacy"), legacyTabSettings, + v, tr("Old Creator")); + + // change the current delegate and save + d->m_globalCodeStyle->setCurrentDelegate(oldCreator); + d->m_globalCodeStyle->toSettings(CppTools::Constants::CPP_SETTINGS_ID, s); + } + // mark old settings as transformed + s->setValue(QLatin1String("CppCodeStyleSettings/LegacyTransformed"), true); } // legacy handling stop } diff --git a/src/plugins/qmljstools/qmljstoolssettings.cpp b/src/plugins/qmljstools/qmljstoolssettings.cpp index efd867611b0..b50c97039b8 100644 --- a/src/plugins/qmljstools/qmljstoolssettings.cpp +++ b/src/plugins/qmljstools/qmljstoolssettings.cpp @@ -39,6 +39,7 @@ #include #include +#include #include #include @@ -108,8 +109,48 @@ QmlJSToolsSettings::QmlJSToolsSettings(QObject *parent) pool->loadCustomCodeStyles(); // load global settings (after built-in settings are added to the pool) - if (const QSettings *s = Core::ICore::instance()->settings()) { + if (QSettings *s = Core::ICore::instance()->settings()) { d->m_globalCodeStyle->fromSettings(QmlJSTools::Constants::QML_JS_SETTINGS_ID, s); + + // legacy handling start (Qt Creator Version < 2.4) + const bool legacyTransformed = + s->value(QLatin1String("QmlJSTabPreferences/LegacyTransformed"), false).toBool(); + + if (!legacyTransformed) { + // creator 2.4 didn't mark yet the transformation (first run of creator 2.4) + + // we need to transform the settings only if at least one from + // below settings was already written - otherwise we use + // defaults like it would be the first run of creator 2.4 without stored settings + const QStringList groups = s->childGroups(); + const bool needTransform = groups.contains(QLatin1String("textTabPreferences")) || + groups.contains(QLatin1String("QmlJSTabPreferences")); + + if (needTransform) { + const QString currentFallback = s->value(QLatin1String("QmlJSTabPreferences/CurrentFallback")).toString(); + TabSettings legacyTabSettings; + if (currentFallback == QLatin1String("QmlJSGlobal")) { + // no delegate, global overwritten + Utils::fromSettings(QLatin1String("QmlJSTabPreferences"), + QString(), s, &legacyTabSettings); + } else { + // delegating to global + legacyTabSettings = textEditorSettings->codeStyle()->currentTabSettings(); + } + + // create custom code style out of old settings + TextEditor::ICodeStylePreferences *oldCreator = pool->createCodeStyle( + QLatin1String("legacy"), legacyTabSettings, + QVariant(), tr("Old Creator")); + + // change the current delegate and save + d->m_globalCodeStyle->setCurrentDelegate(oldCreator); + d->m_globalCodeStyle->toSettings(QmlJSTools::Constants::QML_JS_SETTINGS_ID, s); + } + // mark old settings as transformed + s->setValue(QLatin1String("QmlJSTabPreferences/LegacyTransformed"), true); + } + // legacy handling stop } // mimetypes to be handled From a1e707f93d9d954005e0510718301017e4afd861 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 25 Nov 2011 11:46:05 +0100 Subject: [PATCH 2/6] Doc: Fix qdoc command formatting Change-Id: Ib1659da5f41c51675274bdd0780d060eb3a737be Reviewed-by: Leena Miettinen --- doc/src/linux-mobile/creator-projects-running-madde.qdocinc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/linux-mobile/creator-projects-running-madde.qdocinc b/doc/src/linux-mobile/creator-projects-running-madde.qdocinc index 947f5d7274e..c4d264abaf6 100644 --- a/doc/src/linux-mobile/creator-projects-running-madde.qdocinc +++ b/doc/src/linux-mobile/creator-projects-running-madde.qdocinc @@ -33,7 +33,7 @@ the device. Command-line output is visible in the \QC \gui {Application Output} view. - Choose \gui Projects > Maemo Run} to view the settings for deploying the + Choose \gui {Projects > Maemo Run} to view the settings for deploying the application on the connected device and creating the installation package. For more information, see \l{Specifying Run Settings for Maemo and MeeGo Harmattan Devices}. From f4ae2546618caa7c2932918dacc1b1d181e9919c Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Fri, 25 Nov 2011 13:40:10 +0100 Subject: [PATCH 3/6] Copy dependencies specified in manifest file. Change-Id: I7e97af90cb7cd4c93abe2330cfbd92581b2be22e Reviewed-by: Eike Ziller --- .../welcomescreen/widgets/ExampleDelegate.qml | 2 +- src/plugins/qtsupport/exampleslistmodel.cpp | 17 +++++++++++++---- src/plugins/qtsupport/exampleslistmodel.h | 3 ++- .../qtsupport/gettingstartedwelcomepage.cpp | 17 ++++++++++++++--- .../qtsupport/gettingstartedwelcomepage.h | 5 +++-- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/share/qtcreator/welcomescreen/widgets/ExampleDelegate.qml b/share/qtcreator/welcomescreen/widgets/ExampleDelegate.qml index 72a30ae622f..fb5769d6242 100644 --- a/share/qtcreator/welcomescreen/widgets/ExampleDelegate.qml +++ b/share/qtcreator/welcomescreen/widgets/ExampleDelegate.qml @@ -294,7 +294,7 @@ Item { script: { delegate.state = ""; if (model.hasSourceCode) - gettingStarted.openProject(model.projectPath, model.filesToOpen, model.docUrl) + gettingStarted.openProject(model.projectPath, model.filesToOpen, model.docUrl, model.dependencies) else gettingStarted.openSplitHelp(model.docUrl); } diff --git a/src/plugins/qtsupport/exampleslistmodel.cpp b/src/plugins/qtsupport/exampleslistmodel.cpp index 9c0d967fa3d..88820bea267 100644 --- a/src/plugins/qtsupport/exampleslistmodel.cpp +++ b/src/plugins/qtsupport/exampleslistmodel.cpp @@ -65,6 +65,7 @@ ExamplesListModel::ExamplesListModel(QObject *parent) : roleNames[Difficulty] = "difficulty"; roleNames[Type] = "type"; roleNames[HasSourceCode] = "hasSourceCode"; + roleNames[Dependencies] = "dependencies"; setRoleNames(roleNames); connect(QtVersionManager::instance(), SIGNAL(updateExamples(QString,QString,QString)), @@ -73,7 +74,7 @@ ExamplesListModel::ExamplesListModel(QObject *parent) : SLOT(helpInitialized())); } -static inline QString fixSTringForTags(const QString &string) +static inline QString fixStringForTags(const QString &string) { QString returnString = string; returnString.remove(QLatin1String("")); @@ -104,7 +105,9 @@ QList ExamplesListModel::parseExamples(QXmlStreamReader* reader, co } else if (reader->name() == QLatin1String("fileToOpen")) { item.filesToOpen.append(projectsOffset + '/' + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); } else if (reader->name() == QLatin1String("description")) { - item.description = fixSTringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); + item.description = fixStringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); + } else if (reader->name() == QLatin1String("dependency")) { + item.dependencies.append(projectsOffset + '/' + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); } else if (reader->name() == QLatin1String("tags")) { item.tags = reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(","); m_tags.append(item.tags); @@ -144,7 +147,9 @@ QList ExamplesListModel::parseDemos(QXmlStreamReader* reader, const } else if (reader->name() == QLatin1String("fileToOpen")) { item.filesToOpen.append(projectsOffset + '/' + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); } else if (reader->name() == QLatin1String("description")) { - item.description = fixSTringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); + item.description = fixStringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); + } else if (reader->name() == QLatin1String("dependency")) { + item.dependencies.append(projectsOffset + '/' + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); } else if (reader->name() == QLatin1String("tags")) { item.tags = reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(","); } @@ -183,7 +188,9 @@ QList ExamplesListModel::parseTutorials(QXmlStreamReader* reader, c } else if (reader->name() == QLatin1String("fileToOpen")) { item.filesToOpen.append(projectsOffset + '/' + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); } else if (reader->name() == QLatin1String("description")) { - item.description = fixSTringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); + item.description = fixStringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); + } else if (reader->name() == QLatin1String("dependency")) { + item.dependencies.append(projectsOffset + '/' + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement)); } else if (reader->name() == QLatin1String("tags")) { item.tags = reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(","); } @@ -362,6 +369,8 @@ QVariant ExamplesListModel::data(const QModelIndex &index, int role) const return item.tags; case Difficulty: return item.difficulty; + case Dependencies: + return item.dependencies; case HasSourceCode: return item.hasSourceCode; case Type: diff --git a/src/plugins/qtsupport/exampleslistmodel.h b/src/plugins/qtsupport/exampleslistmodel.h index 2c9fad97b70..12db413af3b 100644 --- a/src/plugins/qtsupport/exampleslistmodel.h +++ b/src/plugins/qtsupport/exampleslistmodel.h @@ -42,7 +42,7 @@ namespace QtSupport { namespace Internal { enum ExampleRoles { Name=Qt::UserRole, ProjectPath, Description, ImageUrl, - DocUrl, FilesToOpen, Tags, Difficulty, HasSourceCode, Type }; + DocUrl, FilesToOpen, Tags, Difficulty, HasSourceCode, Type, Dependencies }; enum InstructionalType { Example=0, Demo, Tutorial }; @@ -56,6 +56,7 @@ struct ExampleItem { QString docUrl; QStringList filesToOpen; QStringList tags; + QStringList dependencies; int difficulty; bool hasSourceCode; }; diff --git a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp index de33e6e959f..3f96fc4ca1a 100644 --- a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp +++ b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -254,7 +255,7 @@ QStringList GettingStartedWelcomePage::tagList() const return examplesModel()->tags(); } -QString GettingStartedWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileInfo, QStringList &filesToOpen) +QString GettingStartedWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileInfo, QStringList &filesToOpen, const QStringList& dependencies) { const QString projectDir = proFileInfo.canonicalPath(); QDialog d(Core::ICore::instance()->mainWindow()); @@ -309,6 +310,15 @@ QString GettingStartedWelcomePage::copyToAlternativeLocation(const QFileInfo& pr for (it = filesToOpen.begin(); it != filesToOpen.end(); ++it) it->replace(projectDir, targetDir); + foreach (const QString &dependency, dependencies) { + QString dirName = QDir(dependency).dirName(); + if (!Utils::FileUtils::copyRecursively(dependency, targetDir + QDir::separator()+ dirName, &error)) { + QMessageBox::warning(Core::ICore::instance()->mainWindow(), tr("Cannot Copy Project"), error); + // do not fail, just warn; + } + } + + return targetDir+ '/' + proFileInfo.fileName(); } else { QMessageBox::warning(Core::ICore::instance()->mainWindow(), tr("Cannot Copy Project"), error); @@ -320,7 +330,8 @@ QString GettingStartedWelcomePage::copyToAlternativeLocation(const QFileInfo& pr } -void GettingStartedWelcomePage::openProject(const QString &projectFile, const QStringList &additionalFilesToOpen, const QUrl &help) +void GettingStartedWelcomePage::openProject(const QString &projectFile, const QStringList &additionalFilesToOpen, + const QUrl &help, const QStringList &dependencies) { QString proFile = projectFile; if (proFile.isEmpty()) @@ -330,7 +341,7 @@ void GettingStartedWelcomePage::openProject(const QString &projectFile, const QS QFileInfo proFileInfo(proFile); // If the Qt is a distro Qt on Linux, it will not be writable, hence compilation will fail if (!proFileInfo.isWritable()) - proFile = copyToAlternativeLocation(proFileInfo, filesToOpen); + proFile = copyToAlternativeLocation(proFileInfo, filesToOpen, dependencies); // don't try to load help and files if loading the help request is being cancelled QString errorMessage; diff --git a/src/plugins/qtsupport/gettingstartedwelcomepage.h b/src/plugins/qtsupport/gettingstartedwelcomepage.h index 0c84f6420a9..02715e6219e 100644 --- a/src/plugins/qtsupport/gettingstartedwelcomepage.h +++ b/src/plugins/qtsupport/gettingstartedwelcomepage.h @@ -68,12 +68,13 @@ signals: public slots: void openSplitHelp(const QUrl &help); - void openProject(const QString& projectFile, const QStringList& additionalFilesToOpen, const QUrl& help); + void openProject(const QString& projectFile, const QStringList& additionalFilesToOpen, + const QUrl& help, const QStringList &dependencies); void updateTagsModel(); private: ExamplesListModel *examplesModel() const; - QString copyToAlternativeLocation(const QFileInfo &fileInfo, QStringList &filesToOpen); + QString copyToAlternativeLocation(const QFileInfo &fileInfo, QStringList &filesToOpen, const QStringList &dependencies); QDeclarativeEngine *m_engine; bool m_showExamples; }; From 6bc2516875f41945e540f9d0bc0b4c7a010d5415 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 25 Nov 2011 15:25:40 +0100 Subject: [PATCH 4/6] Unbreak focus behavior for search panel. With cc11186bad9229c231f2fbba176645f3a3c20327 starting a new search would not move focus to the search term. Change-Id: Ibf84e632e99902d4a06d998271b49ebe614b79d8 Reviewed-by: hjk --- src/plugins/find/searchresultwindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/find/searchresultwindow.cpp b/src/plugins/find/searchresultwindow.cpp index 27233ef9708..aed3329cfcc 100644 --- a/src/plugins/find/searchresultwindow.cpp +++ b/src/plugins/find/searchresultwindow.cpp @@ -213,6 +213,7 @@ SearchResultWindow::SearchResultWindow(QWidget *newSearchPanel) QScrollArea *newSearchArea = new QScrollArea(d->m_widget); newSearchArea->setFrameStyle(QFrame::NoFrame); newSearchArea->setWidget(newSearchPanel); + newSearchArea->setFocusProxy(newSearchPanel); d->m_widget->addWidget(newSearchArea); d->m_currentIndex = 0; From fe4c9053d81972fd161fdccb815ffaac6ef66984 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Fri, 25 Nov 2011 14:28:11 +0100 Subject: [PATCH 5/6] Squish: Update for label renamed in master Change-Id: I8ad167cca8c878efd67eca9ac48b4df237d31726 Reviewed-by: Christian Stenger --- tests/system/shared/hook_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/shared/hook_utils.py b/tests/system/shared/hook_utils.py index 300f5b8d634..8bfaffd48d0 100644 --- a/tests/system/shared/hook_utils.py +++ b/tests/system/shared/hook_utils.py @@ -19,7 +19,7 @@ def modifyRunSettingsForHookInto(projectName, port): if result: clickButton(waitForObject("{container=':Qt Creator.scrollArea_QScrollArea' text='Details' " "type='Utils::DetailsButton' unnamed='1' visible='1' " - "leftWidget={type='QLabel' text='Using Build Environment' unnamed='1' visible='1'}}")) + "leftWidget={type='QLabel' text~='Us(e|ing) Build Environment' unnamed='1' visible='1'}}")) envVarsTableView = waitForObject("{type='QTableView' visible='1' unnamed='1'}") model = envVarsTableView.model() for row in range(model.rowCount()): From 8500fa9f6ac5de53b6e669f9a4346b14ffcb6c4f Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 23 Nov 2011 09:38:31 +0100 Subject: [PATCH 6/6] Squish: Improve hook-into sub-processes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this patch it's possible to not only hook into the QmlApplicationViewer (although nothing else is currently done) and additionally to not only send the closing event to the sub-process. You can now define a function that will be executed on the sub-process. Both modified tests show an example how to use it. Change-Id: I39b9959f2cf1d519b8afeb0c479ac2d68ea20ca6 Reviewed-by: Bill King Reviewed-by: Robert Löhning --- tests/system/shared/qtquick.py | 36 ++++++++++++++++--- .../tst_qtquick_creation/test.py | 8 ++++- .../tst_qtquick_creation2/test.py | 28 +++++++++++++-- 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/tests/system/shared/qtquick.py b/tests/system/shared/qtquick.py index 6a0bf8cb413..f5a81eb4a85 100644 --- a/tests/system/shared/qtquick.py +++ b/tests/system/shared/qtquick.py @@ -83,7 +83,14 @@ def __chooseTargets__(targets=QtQuickConstants.Targets.DESKTOP): if mustCheck: test.fail("Failed to check target '%s'" % QtQuickConstants.getStringForTarget(current)) -def runAndCloseApp(withHookInto=False, executable=None, port=None): +# run and close a Qt Quick application +# withHookInto - if set to True the function tries to attach to the sub-process instead of simply pressing Stop inside Creator +# executable - must be defined when using hook-into +# port - must be defined when using hook-into +# function - can be a string holding a function name or a reference to the function itself - this function will be called on +# the sub-process when hooking-into has been successful - if its missing simply closing the Qt Quick app will be done +# ATTENTION! Make sure this function won't fail and the sub-process will end when the function returns +def runAndCloseApp(withHookInto=False, executable=None, port=None, function=None): global processStarted, processExited processStarted = processExited = False installLazySignalHandler("{type='ProjectExplorer::ApplicationLaucher'}", "processStarted()", "__handleProcessStarted__") @@ -102,7 +109,7 @@ def runAndCloseApp(withHookInto=False, executable=None, port=None): invokeMenuItem("File", "Exit") return False if withHookInto and not executable in ("", None): - __closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port) + __closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port, function) else: __closeSubprocessByPushingStop__() return True @@ -115,7 +122,7 @@ def __closeSubprocessByPushingStop__(): test.verify(playButton.enabled) test.compare(stopButton.enabled, False) -def __closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port): +def __closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port, function): global processExited ensureChecked(":Qt Creator_Core::Internal::OutputPaneToggleButton") output = waitForObject("{type='Core::OutputWindow' visible='1' windowTitle='Application Output Window'}", 20000) @@ -124,9 +131,28 @@ def __closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port): else: waitFor("'Listening on port %d for incoming connectionsdone' in str(output.plainText)" % port, 5000) attachToApplication(executable) - sendEvent("QCloseEvent", "{type='QmlApplicationViewer' unnamed='1' visible='1'}") + if function == None: + sendEvent("QCloseEvent", "{type='QmlApplicationViewer' unnamed='1' visible='1'}") + setApplicationContext(applicationContext("qtcreator")) + else: + try: + if isinstance(function, (str, unicode)): + globals()[function]() + else: + function() + except: + test.fatal("Function to execute on sub-process could not be found.", + "Using fallback of pushing STOP inside Creator.") + setApplicationContext(applicationContext("qtcreator")) + __closeSubprocessByPushingStop__() waitFor("processExited==True", 10000) - setApplicationContext(applicationContext("qtcreator")) + if not processExited: + test.warning("Sub-process seems not to have closed properly.") + try: + setApplicationContext(applicationContext("qtcreator")) + __closeSubprocessByPushingStop__() + except: + pass return True def runAndCloseQtQuickUI(): diff --git a/tests/system/suite_qtquick/tst_qtquick_creation/test.py b/tests/system/suite_qtquick/tst_qtquick_creation/test.py index ed2a15cef27..46e9d3a1ace 100644 --- a/tests/system/suite_qtquick/tst_qtquick_creation/test.py +++ b/tests/system/suite_qtquick/tst_qtquick_creation/test.py @@ -23,7 +23,7 @@ def main(): result = addExecutableAsAttachableAUT(projectName, 11223) allowAppThroughWinFW(workingDir, projectName) if result: - result = runAndCloseApp(True, projectName, 11223) + result = runAndCloseApp(True, projectName, 11223, "subprocessFunction") else: result = runAndCloseApp() removeExecutableAsAttachableAUT(projectName, 11223) @@ -35,6 +35,12 @@ def main(): invokeMenuItem("File", "Exit") +def subprocessFunction(): + helloWorldText = waitForObject("{container={type='QmlApplicationViewer' visible='1' unnamed='1'} " + "enabled='true' text='Hello World' type='Text' unnamed='1' visible='true'}") + test.log("Clicking 'Hello World' Text to close QmlApplicationViewer") + mouseClick(helloWorldText, 5, 5, 0, Qt.LeftButton) + def cleanup(): global workingDir # waiting for a clean exit - for a full-remove of the temp directory diff --git a/tests/system/suite_qtquick/tst_qtquick_creation2/test.py b/tests/system/suite_qtquick/tst_qtquick_creation2/test.py index 2f84aff6994..018b9ee10e6 100644 --- a/tests/system/suite_qtquick/tst_qtquick_creation2/test.py +++ b/tests/system/suite_qtquick/tst_qtquick_creation2/test.py @@ -12,10 +12,11 @@ def main(): # using a temporary directory won't mess up an eventually exisiting workingDir = tempDir() prepareTemplate(sourceExample) - createNewQtQuickApplication(workingDir, None, templateDir + "/qml/textselection.qml") + projectName = createNewQtQuickApplication(workingDir, None, templateDir + "/qml/textselection.qml") # wait for parsing to complete waitForSignal("{type='CppTools::Internal::CppModelManager' unnamed='1'}", "sourceFilesRefreshed(QStringList)", 30000) test.log("Building project") + result = modifyRunSettingsForHookInto(projectName, 11223) invokeMenuItem("Build","Build All") waitForSignal("{type='ProjectExplorer::BuildManager' unnamed='1'}", "buildQueueFinished(bool)", 300000) if not checkCompile(): @@ -23,10 +24,33 @@ def main(): else: checkLastBuild() test.log("Running project (includes build)") - if runAndCloseApp(): + if result: + result = addExecutableAsAttachableAUT(projectName, 11223) + allowAppThroughWinFW(workingDir, projectName) + if result: + result = runAndCloseApp(True, projectName, 11223, subprocessFunction) + else: + result = runAndCloseApp() + removeExecutableAsAttachableAUT(projectName, 11223) + deleteAppFromWinFW(workingDir, projectName) + else: + result = runAndCloseApp() + if result: logApplicationOutput() invokeMenuItem("File", "Exit") +def subprocessFunction(): + textEdit = waitForObject("{container={type='QmlApplicationViewer' unnamed='1' visible='1'} " + "enabled='true' type='TextEdit' unnamed='1' visible='true'}") + test.log("Test dragging") + dragItemBy(textEdit, 30, 30, 50, 50, 0, Qt.LeftButton) + test.log("Test editing") + textEdit.cursorPosition = 0 + type(textEdit, "This text is entered by Squish...") + type(textEdit, "") + test.log("Closing QmlApplicationViewer") + sendEvent("QCloseEvent", "{type='QmlApplicationViewer' unnamed='1' visible='1'}") + def prepareTemplate(sourceExample): global templateDir templateDir = tempDir()