From 86d7e28db4053d771fba2819d88ffbf5cf0843e5 Mon Sep 17 00:00:00 2001 From: Petar Perisin Date: Fri, 26 Apr 2013 00:00:30 +0200 Subject: [PATCH 01/37] Git - added submoduleDataMap to handle submodule data Change-Id: I8462ed07f3d1edce5c7f5ab8c166ce8c68b6d4b3 Reviewed-by: Orgad Shaneh --- src/plugins/git/gerrit/gerritplugin.cpp | 16 +++---- src/plugins/git/gitclient.cpp | 60 ++++++++++++++++++++----- src/plugins/git/gitclient.h | 12 ++++- src/plugins/git/gitplugin.cpp | 3 +- 4 files changed, 69 insertions(+), 22 deletions(-) diff --git a/src/plugins/git/gerrit/gerritplugin.cpp b/src/plugins/git/gerrit/gerritplugin.cpp index 71637952f00..c1687fb7971 100644 --- a/src/plugins/git/gerrit/gerritplugin.cpp +++ b/src/plugins/git/gerrit/gerritplugin.cpp @@ -511,21 +511,19 @@ void GerritPlugin::fetch(const QSharedPointer &c } } - if (!verifiedRepository && QFile::exists(repository + QLatin1String("/.gitmodules"))) { - QMap submodules = gitClient->synchronousSubmoduleList(repository); - - QMap::const_iterator i = submodules.constBegin(); - while (i != submodules.constEnd()) { - QString remote = i.value(); + if (!verifiedRepository) { + Git::Internal::SubmoduleDataMap submodules = gitClient->submoduleList(repository); + foreach (const Git::Internal::SubmoduleData &submoduleData, submodules) { + QString remote = submoduleData.url; if (remote.endsWith(QLatin1String(".git"))) remote.chop(4); if (remote.contains(m_parameters->host) && remote.endsWith(change->project) - && QFile::exists(repository + QLatin1Char('/') + i.key())) { - repository = QDir::cleanPath(repository + QLatin1Char('/') + i.key()); + && QFile::exists(repository + QLatin1Char('/') + submoduleData.dir)) { + repository = QDir::cleanPath(repository + QLatin1Char('/') + + submoduleData.dir); verifiedRepository = true; break; } - ++i; } } diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 15befd0406a..ed2172c6057 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -1962,22 +1962,60 @@ QMap GitClient::synchronousRemotesList(const QString &workingDi return result; } -// function returns submodules in format path=url -QMap GitClient::synchronousSubmoduleList(const QString &workingDirectory) +SubmoduleDataMap GitClient::submoduleList(const QString &workingDirectory) { - QMap result; - if (!QFile::exists(workingDirectory + QLatin1String("/.gitmodules"))) + SubmoduleDataMap result; + QString gitmodulesFileName = workingDirectory + QLatin1String("/.gitmodules"); + if (!QFile::exists(gitmodulesFileName)) return result; - QSettings gitmodulesFile(workingDirectory + QLatin1String("/.gitmodules"), QSettings::IniFormat); + static QMap cachedSubmoduleData; - foreach (const QString &submoduleGroup, gitmodulesFile.childGroups()) { - gitmodulesFile.beginGroup(submoduleGroup); - result.insertMulti(gitmodulesFile.value(QLatin1String("path")).toString(), - gitmodulesFile.value(QLatin1String("url")).toString()); - gitmodulesFile.endGroup(); + if (cachedSubmoduleData.contains(workingDirectory)) + return cachedSubmoduleData.value(workingDirectory); + QStringList args(QLatin1String("-l")); + + QStringList allConfigs = readConfig(workingDirectory, args).split(QLatin1Char('\n')); + const QString submoduleLineStart = QLatin1String("submodule."); + foreach (const QString &configLine, allConfigs) { + if (!configLine.startsWith(submoduleLineStart)) + continue; + + int nameStart = submoduleLineStart.size(); + int nameEnd = configLine.indexOf(QLatin1Char('.'), nameStart); + + QString submoduleName = configLine.mid(nameStart, nameEnd - nameStart); + + SubmoduleData submoduleData; + if (result.contains(submoduleName)) + submoduleData = result[submoduleName]; + + if (configLine.mid(nameEnd, 5) == QLatin1String(".url=")) + submoduleData.url = configLine.mid(nameEnd + 5); + else if (configLine.mid(nameEnd, 8) == QLatin1String(".ignore=")) + submoduleData.ignore = configLine.mid(nameEnd + 8); + else + continue; + + result.insert(submoduleName, submoduleData); } + // if config found submodules + if (!result.isEmpty()) { + QSettings gitmodulesFile(gitmodulesFileName, QSettings::IniFormat); + + foreach (const QString &submoduleName, result.keys()) { + gitmodulesFile.beginGroup(QLatin1String("submodule \"") + + submoduleName + QLatin1Char('"')); + result[submoduleName].dir = gitmodulesFile.value(QLatin1String("path")).toString(); + QString ignore = gitmodulesFile.value(QLatin1String("ignore")).toString(); + if (!ignore.isEmpty() && result[submoduleName].ignore.isEmpty()) + result[submoduleName].ignore = ignore; + gitmodulesFile.endGroup(); + } + } + cachedSubmoduleData.insert(workingDirectory, result); + return result; } @@ -2172,7 +2210,7 @@ void GitClient::submoduleUpdate(const QString &workingDirectory) void GitClient::promptSubmoduleUpdate(const QString &workingDirectory) { - if (!QFile::exists(workingDirectory + QLatin1String("/.gitmodules"))) + if (submoduleList(workingDirectory).isEmpty()) return; if (QMessageBox::question(Core::ICore::mainWindow(), tr("Submodules Found"), diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index d71b47ac888..414efe65216 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -86,6 +86,16 @@ enum StashFlag { NoPrompt = 0x02 }; +class SubmoduleData +{ +public: + QString dir; + QString url; + QString ignore; +}; + +typedef QMap SubmoduleDataMap; + class GitClient : public QObject { Q_OBJECT @@ -200,7 +210,7 @@ public: QMap synchronousRemotesList(const QString &workingDirectory, QString *errorMessage = 0); - QMap synchronousSubmoduleList(const QString &workingDirectory); + SubmoduleDataMap submoduleList(const QString &workingDirectory); bool synchronousShow(const QString &workingDirectory, const QString &id, QString *output, QString *errorMessage); diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 55dcce53648..1eb1ec4215f 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -1323,8 +1323,9 @@ void GitPlugin::updateActions(VcsBase::VcsBasePlugin::ActionState as) foreach (QAction *repositoryAction, m_repositoryActions) repositoryAction->setEnabled(repositoryEnabled); + m_submoduleUpdateAction->setVisible(repositoryEnabled - && QFile::exists(currentState().topLevel() + QLatin1String("/.gitmodules"))); + && !m_gitClient->submoduleList(currentState().topLevel()).isEmpty()); updateContinueAndAbortCommands(); updateRepositoryBrowserAction(); From d007681b318d400779ea8a08fb25076dfdf5bd54 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 21 May 2013 12:43:21 +0200 Subject: [PATCH 02/37] Squish: Improve changePermission() Change-Id: I3ce1691afc2fad3949d216dee37b06a33e40f6f1 Reviewed-by: Robert Loehning --- tests/system/shared/fs_utils.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/system/shared/fs_utils.py b/tests/system/shared/fs_utils.py index 5a0c22ea15d..8a5c8e34511 100644 --- a/tests/system/shared/fs_utils.py +++ b/tests/system/shared/fs_utils.py @@ -50,9 +50,15 @@ def changeFilePermissions(dirPath, readPerm, writePerm, excludeFileNames=None): return False filePaths = [os.path.join(dirPath, fileName) for fileName in os.listdir(dirPath) if fileName not in excludeFileNames] + result = True for filePath in filter(os.path.isfile, filePaths): - os.chmod(filePath, permission) - return True + try: + os.chmod(filePath, permission) + except: + t,v = sys.exc_info()[:2] + test.log("Error: %s(%s)" % (str(t), str(v))) + result = False + return result def isWritable(pathToFile): if os.path.exists(pathToFile): From 7bb64a58f4799d600a88d153fec8e5bed7582dfd Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 22 May 2013 17:19:25 +0200 Subject: [PATCH 03/37] Squish: Move simpleFileName() into shared script Change-Id: I359af17fcbc67149fab4e291142523b436a43832 Reviewed-by: Robert Loehning --- tests/system/shared/utils.py | 3 +++ tests/system/suite_editors/tst_modify_readonly/test.py | 3 --- tests/system/suite_editors/tst_rename_macros/test.py | 3 --- tests/system/suite_editors/tst_revert_changes/test.py | 3 --- tests/system/suite_qtquick/tst_qml_outline/test.py | 3 --- 5 files changed, 3 insertions(+), 12 deletions(-) diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index 401acbe963d..2e8d5ce2dce 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -647,3 +647,6 @@ def readFile(filename): content = f.read() f.close() return content + +def simpleFileName(navigatorFileName): + return ".".join(navigatorFileName.split(".")[-2:]).replace("\\","") diff --git a/tests/system/suite_editors/tst_modify_readonly/test.py b/tests/system/suite_editors/tst_modify_readonly/test.py index 7d2a05f5aaa..d31b244b0c0 100644 --- a/tests/system/suite_editors/tst_modify_readonly/test.py +++ b/tests/system/suite_editors/tst_modify_readonly/test.py @@ -149,9 +149,6 @@ def checkUnsavedChangesContains(model, filePaths): test.compare(set(foundItems), set(filePaths), "Verifying whether modified (unsaved) files do match expected.") -def simpleFileName(navigatorFileName): - return ".".join(navigatorFileName.split(".")[-2:]).replace("\\","") - def cleanup(): global testFolder if testFolder: diff --git a/tests/system/suite_editors/tst_rename_macros/test.py b/tests/system/suite_editors/tst_rename_macros/test.py index a8c15e5ab12..d82b0f666dc 100644 --- a/tests/system/suite_editors/tst_rename_macros/test.py +++ b/tests/system/suite_editors/tst_rename_macros/test.py @@ -166,6 +166,3 @@ def revertChanges(files): "Maybe it has not been changed at all.") else: test.fail("Could not open %s for reverting changes" % simpleName) - -def simpleFileName(navigatorFileName): - return ".".join(navigatorFileName.split(".")[-2:]).replace("\\","") diff --git a/tests/system/suite_editors/tst_revert_changes/test.py b/tests/system/suite_editors/tst_revert_changes/test.py index d9dfdfcc533..670adcccde6 100644 --- a/tests/system/suite_editors/tst_revert_changes/test.py +++ b/tests/system/suite_editors/tst_revert_changes/test.py @@ -140,6 +140,3 @@ def compareFileToOriginal(fileName): origFile.close() test.compare(originalContent, currentContent, "Comparing original to reverted file content for '%s'" % fileName) - -def simpleFileName(navigatorFileName): - return ".".join(navigatorFileName.split(".")[-2:]).replace("\\","") diff --git a/tests/system/suite_qtquick/tst_qml_outline/test.py b/tests/system/suite_qtquick/tst_qml_outline/test.py index da41920494f..2580fcf6de8 100644 --- a/tests/system/suite_qtquick/tst_qml_outline/test.py +++ b/tests/system/suite_qtquick/tst_qml_outline/test.py @@ -147,6 +147,3 @@ def verifyOutline(outlinePseudoTree, datasetFileName): return test.passes("All nodes (%d) inside outline match expected nodes for '%s'." % (len(expected), fileName)) - -def simpleFileName(navigatorFileName): - return ".".join(navigatorFileName.split(".")[-2:]).replace("\\", "") From 0b225af84c6377416959ae2174823c8f1e9e7073 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 29 May 2013 08:45:13 +0200 Subject: [PATCH 04/37] Fix warnings about uninitialized variables in readonlyfilesdialog.cpp. readonlyfilesdialog.cpp:316:29: warning: 'type' may be used uninitialized in this function. readonlyfilesdialog.cpp:283:60: warning: 'result' may be used uninitialized in this function. Change-Id: Ib2456e64d981c5afcd3ba70cc7ef0427e98b9b4e Reviewed-by: David Schulz --- src/plugins/coreplugin/dialogs/readonlyfilesdialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/coreplugin/dialogs/readonlyfilesdialog.cpp b/src/plugins/coreplugin/dialogs/readonlyfilesdialog.cpp index e86b2b6b57b..66d86e973ae 100644 --- a/src/plugins/coreplugin/dialogs/readonlyfilesdialog.cpp +++ b/src/plugins/coreplugin/dialogs/readonlyfilesdialog.cpp @@ -248,7 +248,7 @@ int ReadOnlyFilesDialog::exec() if (QDialog::exec() != QDialog::Accepted) return RO_Cancel; - ReadOnlyResult result; + ReadOnlyResult result = RO_Cancel; QStringList failedToMakeWritable; foreach (ReadOnlyFilesDialogPrivate::ButtonGroupForFile buttengroup, d->buttonGroups) { result = static_cast(buttengroup.group->checkedId()); @@ -313,7 +313,7 @@ void ReadOnlyFilesDialog::setAll(int index) return; // Get the selected type from the select all combo box. - ReadOnlyFilesTreeColumn type; + ReadOnlyFilesTreeColumn type = NumberOfColumns; if (index == d->setAllIndexForOperation[MakeWritable]) type = MakeWritable; else if (index == d->setAllIndexForOperation[OpenWithVCS]) From 8390a321319f1fdf8c92ae40408ee6db02b75908 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 28 May 2013 15:17:20 +0200 Subject: [PATCH 05/37] Settings: Simplify some user code This is still way too much boiler plate code for the task at hand. Change-Id: Ia03bff3d6947ea6372e3f5d0217c116728742b74 Reviewed-by: Eike Ziller Reviewed-by: Friedemann Kleint --- .../classviewnavigationwidgetfactory.cpp | 14 ++--- src/plugins/coreplugin/generalsettings.cpp | 5 +- src/plugins/cpaster/codepastersettings.cpp | 18 +++--- src/plugins/cpaster/codepastersettings.h | 1 - .../cpptools/cppcodestylesettingspage.cpp | 9 +-- src/plugins/cpptools/cpptoolssettings.cpp | 2 +- src/plugins/cvs/cvsplugin.cpp | 6 +- src/plugins/debugger/debuggermainwindow.cpp | 4 -- src/plugins/designer/settingsmanager.cpp | 35 +++--------- src/plugins/find/searchresultwindow.cpp | 16 ++---- .../projectexplorer/projectexplorer.cpp | 56 +++++++++---------- .../qmljstools/qmljscodestylesettingspage.cpp | 6 +- src/plugins/qnx/blackberryconfiguration.cpp | 10 ++-- 13 files changed, 66 insertions(+), 116 deletions(-) diff --git a/src/plugins/classview/classviewnavigationwidgetfactory.cpp b/src/plugins/classview/classviewnavigationwidgetfactory.cpp index 7b19e0144f6..b3a4fb7e63c 100644 --- a/src/plugins/classview/classviewnavigationwidgetfactory.cpp +++ b/src/plugins/classview/classviewnavigationwidgetfactory.cpp @@ -108,14 +108,11 @@ void NavigationWidgetFactory::saveSettings(int position, QWidget *widget) NavigationWidget *pw = qobject_cast(widget); QTC_ASSERT(pw, return); - QSettings *settings = Core::ICore::settings(); - QTC_ASSERT(settings, return); - // .beginGroup is not used - to prevent simultaneous access QString group = settingsPrefix(position); - // save settings - settings->setValue(group, pw->flatMode()); + // Save settings + Core::ICore::settings()->setValue(group, pw->flatMode()); } void NavigationWidgetFactory::restoreSettings(int position, QWidget *widget) @@ -123,14 +120,11 @@ void NavigationWidgetFactory::restoreSettings(int position, QWidget *widget) NavigationWidget *pw = qobject_cast(widget); QTC_ASSERT(pw, return); - QSettings *settings = Core::ICore::settings(); - QTC_ASSERT(settings, return); - // .beginGroup is not used - to prevent simultaneous access QString group = settingsPrefix(position); - // load settings - pw->setFlatMode(settings->value(group, false).toBool()); + // Load settings + pw->setFlatMode(Core::ICore::settings()->value(group, false).toBool()); } } // namespace Internal diff --git a/src/plugins/coreplugin/generalsettings.cpp b/src/plugins/coreplugin/generalsettings.cpp index 2fba5d0ed3f..ead28c556a4 100644 --- a/src/plugins/coreplugin/generalsettings.cpp +++ b/src/plugins/coreplugin/generalsettings.cpp @@ -107,14 +107,12 @@ QWidget *GeneralSettings::createPage(QWidget *parent) m_widget = new QWidget(parent); m_page->setupUi(m_widget); - QSettings *settings = Core::ICore::settings(); - Q_UNUSED(settings) // Windows - fillLanguageBox(); m_page->colorButton->setColor(StyleHelper::requestedBaseColor()); m_page->reloadBehavior->setCurrentIndex(EditorManager::instance()->reloadSetting()); if (HostOsInfo::isAnyUnixHost()) { + QSettings *settings = Core::ICore::settings(); const QStringList availableTerminals = ConsoleProcess::availableTerminalEmulators(); const QString currentTerminal = ConsoleProcess::terminalEmulator(settings, false); const QString currentTerminalExplicit = ConsoleProcess::terminalEmulator(settings, true); @@ -128,6 +126,7 @@ QWidget *GeneralSettings::createPage(QWidget *parent) } if (HostOsInfo::isAnyUnixHost() && !HostOsInfo::isMacHost()) { + QSettings *settings = Core::ICore::settings(); m_page->externalFileBrowserEdit->setText(UnixUtils::fileBrowser(settings)); } else { m_page->externalFileBrowserLabel->hide(); diff --git a/src/plugins/cpaster/codepastersettings.cpp b/src/plugins/cpaster/codepastersettings.cpp index 63ff59648db..4f2e4558e60 100644 --- a/src/plugins/cpaster/codepastersettings.cpp +++ b/src/plugins/cpaster/codepastersettings.cpp @@ -52,11 +52,8 @@ CodePasterSettingsPage::CodePasterSettingsPage() setDisplayCategory(QCoreApplication::translate("CodePaster", Constants::CPASTER_SETTINGS_TR_CATEGORY)); - m_settings = Core::ICore::settings(); - if (m_settings) { - const QString keyRoot = QLatin1String(settingsGroupC) + QLatin1Char('/'); - m_host = m_settings->value(keyRoot + QLatin1String(serverKeyC), QString()).toString(); - } + const QString keyRoot = QLatin1String(settingsGroupC) + QLatin1Char('/'); + m_host = Core::ICore::settings()->value(keyRoot + QLatin1String(serverKeyC), QString()).toString(); } QWidget *CodePasterSettingsPage::createPage(QWidget *parent) @@ -83,12 +80,11 @@ QWidget *CodePasterSettingsPage::createPage(QWidget *parent) void CodePasterSettingsPage::apply() { - if (!m_settings) - return; - - m_settings->beginGroup(QLatin1String(settingsGroupC)); - m_settings->setValue(QLatin1String(serverKeyC), m_host); - m_settings->endGroup(); + QSettings *settings = Core::ICore::settings(); + const QString keyRoot = QLatin1String(settingsGroupC) + QLatin1Char('/'); + settings->beginGroup(QLatin1String(settingsGroupC)); + settings->setValue(QLatin1String(serverKeyC), m_host); + settings->endGroup(); } void CodePasterSettingsPage::serverChanged(const QString &host) diff --git a/src/plugins/cpaster/codepastersettings.h b/src/plugins/cpaster/codepastersettings.h index 22f342b61de..ebc58d45ab9 100644 --- a/src/plugins/cpaster/codepastersettings.h +++ b/src/plugins/cpaster/codepastersettings.h @@ -55,7 +55,6 @@ public slots: void serverChanged(const QString &host); private: - QSettings *m_settings; QString m_host; }; diff --git a/src/plugins/cpptools/cppcodestylesettingspage.cpp b/src/plugins/cpptools/cppcodestylesettingspage.cpp index 82033213558..01a0589eb5e 100644 --- a/src/plugins/cpptools/cppcodestylesettingspage.cpp +++ b/src/plugins/cpptools/cppcodestylesettingspage.cpp @@ -590,18 +590,15 @@ void CppCodeStyleSettingsPage::apply() CppCodeStylePreferences *originalCppCodeStylePreferences = CppToolsSettings::instance()->cppCodeStyle(); if (originalCppCodeStylePreferences->codeStyleSettings() != m_pageCppCodeStylePreferences->codeStyleSettings()) { originalCppCodeStylePreferences->setCodeStyleSettings(m_pageCppCodeStylePreferences->codeStyleSettings()); - if (s) - originalCppCodeStylePreferences->toSettings(QLatin1String(CppTools::Constants::CPP_SETTINGS_ID), s); + originalCppCodeStylePreferences->toSettings(QLatin1String(CppTools::Constants::CPP_SETTINGS_ID), s); } if (originalCppCodeStylePreferences->tabSettings() != m_pageCppCodeStylePreferences->tabSettings()) { originalCppCodeStylePreferences->setTabSettings(m_pageCppCodeStylePreferences->tabSettings()); - if (s) - originalCppCodeStylePreferences->toSettings(QLatin1String(CppTools::Constants::CPP_SETTINGS_ID), s); + originalCppCodeStylePreferences->toSettings(QLatin1String(CppTools::Constants::CPP_SETTINGS_ID), s); } if (originalCppCodeStylePreferences->currentDelegate() != m_pageCppCodeStylePreferences->currentDelegate()) { originalCppCodeStylePreferences->setCurrentDelegate(m_pageCppCodeStylePreferences->currentDelegate()); - if (s) - originalCppCodeStylePreferences->toSettings(QLatin1String(CppTools::Constants::CPP_SETTINGS_ID), s); + originalCppCodeStylePreferences->toSettings(QLatin1String(CppTools::Constants::CPP_SETTINGS_ID), s); } } } diff --git a/src/plugins/cpptools/cpptoolssettings.cpp b/src/plugins/cpptools/cpptoolssettings.cpp index 605487ffcba..2f034bac91d 100644 --- a/src/plugins/cpptools/cpptoolssettings.cpp +++ b/src/plugins/cpptools/cpptoolssettings.cpp @@ -172,7 +172,7 @@ CppToolsSettings::CppToolsSettings(QObject *parent) // load global settings (after built-in settings are added to the pool) QSettings *s = Core::ICore::settings(); - d->m_globalCodeStyle->fromSettings(QLatin1String(CppTools::Constants::CPP_SETTINGS_ID), Core::ICore::settings()); + d->m_globalCodeStyle->fromSettings(QLatin1String(CppTools::Constants::CPP_SETTINGS_ID), s); // legacy handling start (Qt Creator Version < 2.4) const bool legacyTransformed = diff --git a/src/plugins/cvs/cvsplugin.cpp b/src/plugins/cvs/cvsplugin.cpp index 00454c6089f..b3cadb5e173 100644 --- a/src/plugins/cvs/cvsplugin.cpp +++ b/src/plugins/cvs/cvsplugin.cpp @@ -233,8 +233,7 @@ bool CvsPlugin::initialize(const QStringList &arguments, QString *errorMessage) if (!ICore::mimeDatabase()->addMimeTypes(QLatin1String(":/trolltech.cvs/CVS.mimetypes.xml"), errorMessage)) return false; - if (QSettings *settings = ICore::settings()) - m_settings.fromSettings(settings); + m_settings.fromSettings(ICore::settings()); addAutoReleasedObject(new SettingsPage); @@ -1299,8 +1298,7 @@ void CvsPlugin::setSettings(const CvsSettings &s) { if (s != m_settings) { m_settings = s; - if (QSettings *settings = ICore::settings()) - m_settings.toSettings(settings); + m_settings.toSettings(ICore::settings()); cvsVersionControl()->emitConfigurationChanged(); } } diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp index aa8d22e74d0..5e7f8059267 100644 --- a/src/plugins/debugger/debuggermainwindow.cpp +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -552,8 +552,6 @@ QWidget *DebuggerMainWindow::createContents(IMode *mode) void DebuggerMainWindow::writeSettings() const { QSettings *settings = ICore::settings(); - QTC_ASSERT(settings, return); - settings->beginGroup(QLatin1String("DebugMode.CppMode")); QHashIterator it(d->m_dockWidgetActiveStateCpp); while (it.hasNext()) { @@ -574,8 +572,6 @@ void DebuggerMainWindow::writeSettings() const void DebuggerMainWindow::readSettings() { QSettings *settings = ICore::settings(); - QTC_ASSERT(settings, return); - d->m_dockWidgetActiveStateCpp.clear(); d->m_dockWidgetActiveStateQmlCpp.clear(); diff --git a/src/plugins/designer/settingsmanager.cpp b/src/plugins/designer/settingsmanager.cpp index 3710c3100a6..ba71a26bf41 100644 --- a/src/plugins/designer/settingsmanager.cpp +++ b/src/plugins/designer/settingsmanager.cpp @@ -37,61 +37,40 @@ using namespace Designer::Internal; -static inline QSettings *coreSettings() -{ - if (Core::ICore::instance()) - return Core::ICore::settings(); - return 0; -} - void SettingsManager::beginGroup(const QString &prefix) { - QSettings *settings = coreSettings(); - QTC_ASSERT(settings, return); - settings->beginGroup(addPrefix(prefix)); + Core::ICore::settings()->beginGroup(addPrefix(prefix)); } void SettingsManager::endGroup() { - QSettings *settings = coreSettings(); - QTC_ASSERT(settings, return); - settings->endGroup(); + Core::ICore::settings()->endGroup(); } bool SettingsManager::contains(const QString &key) const { - const QSettings *settings = coreSettings(); - QTC_ASSERT(settings, return false); - return settings->contains(addPrefix(key)); + return Core::ICore::settings()->contains(addPrefix(key)); } void SettingsManager::setValue(const QString &key, const QVariant &value) { - QSettings *settings = coreSettings(); - QTC_ASSERT(settings, return); - settings->setValue(addPrefix(key), value); + Core::ICore::settings()->setValue(addPrefix(key), value); } QVariant SettingsManager::value(const QString &key, const QVariant &defaultValue) const { - const QSettings *settings = coreSettings(); - QTC_ASSERT(settings, return QVariant()); - return settings->value(addPrefix(key), defaultValue); + return Core::ICore::settings()->value(addPrefix(key), defaultValue); } void SettingsManager::remove(const QString &key) { - QSettings *settings = coreSettings(); - QTC_ASSERT(settings, return); - settings->remove(addPrefix(key)); + Core::ICore::settings()->remove(addPrefix(key)); } QString SettingsManager::addPrefix(const QString &name) const { - const QSettings *settings = coreSettings(); - QTC_ASSERT(settings, return name); QString result = name; - if (settings->group().isEmpty()) + if (Core::ICore::settings()->group().isEmpty()) result.prepend(QLatin1String("Designer")); return result; } diff --git a/src/plugins/find/searchresultwindow.cpp b/src/plugins/find/searchresultwindow.cpp index 257f2966fe1..1a45816174f 100644 --- a/src/plugins/find/searchresultwindow.cpp +++ b/src/plugins/find/searchresultwindow.cpp @@ -521,11 +521,9 @@ void SearchResultWindow::handleExpandCollapseToolButton(bool checked) void SearchResultWindow::readSettings() { QSettings *s = Core::ICore::settings(); - if (s) { - s->beginGroup(QLatin1String(SETTINGSKEYSECTIONNAME)); - d->m_expandCollapseAction->setChecked(s->value(QLatin1String(SETTINGSKEYEXPANDRESULTS), d->m_initiallyExpand).toBool()); - s->endGroup(); - } + s->beginGroup(QLatin1String(SETTINGSKEYSECTIONNAME)); + d->m_expandCollapseAction->setChecked(s->value(QLatin1String(SETTINGSKEYEXPANDRESULTS), d->m_initiallyExpand).toBool()); + s->endGroup(); } /*! @@ -535,11 +533,9 @@ void SearchResultWindow::readSettings() void SearchResultWindow::writeSettings() { QSettings *s = Core::ICore::settings(); - if (s) { - s->beginGroup(QLatin1String(SETTINGSKEYSECTIONNAME)); - s->setValue(QLatin1String(SETTINGSKEYEXPANDRESULTS), d->m_expandCollapseAction->isChecked()); - s->endGroup(); - } + s->beginGroup(QLatin1String(SETTINGSKEYSECTIONNAME)); + s->setValue(QLatin1String(SETTINGSKEYEXPANDRESULTS), d->m_expandCollapseAction->isChecked()); + s->endGroup(); } /*! diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index ece65886ff3..e89ce949677 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -1274,37 +1274,35 @@ void ProjectExplorerPlugin::savePersistentSettings() } QSettings *s = Core::ICore::settings(); - if (s) { - s->setValue(QLatin1String("ProjectExplorer/StartupSession"), d->m_session->activeSession()); - s->remove(QLatin1String("ProjectExplorer/RecentProjects/Files")); + s->setValue(QLatin1String("ProjectExplorer/StartupSession"), d->m_session->activeSession()); + s->remove(QLatin1String("ProjectExplorer/RecentProjects/Files")); - QStringList fileNames; - QStringList displayNames; - QList >::const_iterator it, end; - end = d->m_recentProjects.constEnd(); - for (it = d->m_recentProjects.constBegin(); it != end; ++it) { - fileNames << (*it).first; - displayNames << (*it).second; - } - - s->setValue(QLatin1String("ProjectExplorer/RecentProjects/FileNames"), fileNames); - s->setValue(QLatin1String("ProjectExplorer/RecentProjects/DisplayNames"), displayNames); - - s->setValue(QLatin1String("ProjectExplorer/Settings/BuildBeforeDeploy"), d->m_projectExplorerSettings.buildBeforeDeploy); - s->setValue(QLatin1String("ProjectExplorer/Settings/DeployBeforeRun"), d->m_projectExplorerSettings.deployBeforeRun); - s->setValue(QLatin1String("ProjectExplorer/Settings/SaveBeforeBuild"), d->m_projectExplorerSettings.saveBeforeBuild); - s->setValue(QLatin1String("ProjectExplorer/Settings/ShowCompilerOutput"), d->m_projectExplorerSettings.showCompilerOutput); - s->setValue(QLatin1String("ProjectExplorer/Settings/ShowRunOutput"), d->m_projectExplorerSettings.showRunOutput); - s->setValue(QLatin1String("ProjectExplorer/Settings/ShowDebugOutput"), d->m_projectExplorerSettings.showDebugOutput); - s->setValue(QLatin1String("ProjectExplorer/Settings/CleanOldAppOutput"), d->m_projectExplorerSettings.cleanOldAppOutput); - s->setValue(QLatin1String("ProjectExplorer/Settings/MergeStdErrAndStdOut"), d->m_projectExplorerSettings.mergeStdErrAndStdOut); - s->setValue(QLatin1String("ProjectExplorer/Settings/WrapAppOutput"), d->m_projectExplorerSettings.wrapAppOutput); - s->setValue(QLatin1String("ProjectExplorer/Settings/UseJom"), d->m_projectExplorerSettings.useJom); - s->setValue(QLatin1String("ProjectExplorer/Settings/AutoRestoreLastSession"), d->m_projectExplorerSettings.autorestoreLastSession); - s->setValue(QLatin1String("ProjectExplorer/Settings/PromptToStopRunControl"), d->m_projectExplorerSettings.prompToStopRunControl); - s->setValue(QLatin1String("ProjectExplorer/Settings/MaxAppOutputLines"), d->m_projectExplorerSettings.maxAppOutputLines); - s->setValue(QLatin1String("ProjectExplorer/Settings/EnvironmentId"), d->m_projectExplorerSettings.environmentId.toByteArray()); + QStringList fileNames; + QStringList displayNames; + QList >::const_iterator it, end; + end = d->m_recentProjects.constEnd(); + for (it = d->m_recentProjects.constBegin(); it != end; ++it) { + fileNames << (*it).first; + displayNames << (*it).second; } + + s->setValue(QLatin1String("ProjectExplorer/RecentProjects/FileNames"), fileNames); + s->setValue(QLatin1String("ProjectExplorer/RecentProjects/DisplayNames"), displayNames); + + s->setValue(QLatin1String("ProjectExplorer/Settings/BuildBeforeDeploy"), d->m_projectExplorerSettings.buildBeforeDeploy); + s->setValue(QLatin1String("ProjectExplorer/Settings/DeployBeforeRun"), d->m_projectExplorerSettings.deployBeforeRun); + s->setValue(QLatin1String("ProjectExplorer/Settings/SaveBeforeBuild"), d->m_projectExplorerSettings.saveBeforeBuild); + s->setValue(QLatin1String("ProjectExplorer/Settings/ShowCompilerOutput"), d->m_projectExplorerSettings.showCompilerOutput); + s->setValue(QLatin1String("ProjectExplorer/Settings/ShowRunOutput"), d->m_projectExplorerSettings.showRunOutput); + s->setValue(QLatin1String("ProjectExplorer/Settings/ShowDebugOutput"), d->m_projectExplorerSettings.showDebugOutput); + s->setValue(QLatin1String("ProjectExplorer/Settings/CleanOldAppOutput"), d->m_projectExplorerSettings.cleanOldAppOutput); + s->setValue(QLatin1String("ProjectExplorer/Settings/MergeStdErrAndStdOut"), d->m_projectExplorerSettings.mergeStdErrAndStdOut); + s->setValue(QLatin1String("ProjectExplorer/Settings/WrapAppOutput"), d->m_projectExplorerSettings.wrapAppOutput); + s->setValue(QLatin1String("ProjectExplorer/Settings/UseJom"), d->m_projectExplorerSettings.useJom); + s->setValue(QLatin1String("ProjectExplorer/Settings/AutoRestoreLastSession"), d->m_projectExplorerSettings.autorestoreLastSession); + s->setValue(QLatin1String("ProjectExplorer/Settings/PromptToStopRunControl"), d->m_projectExplorerSettings.prompToStopRunControl); + s->setValue(QLatin1String("ProjectExplorer/Settings/MaxAppOutputLines"), d->m_projectExplorerSettings.maxAppOutputLines); + s->setValue(QLatin1String("ProjectExplorer/Settings/EnvironmentId"), d->m_projectExplorerSettings.environmentId.toByteArray()); } void ProjectExplorerPlugin::openProjectWelcomePage(const QString &fileName) diff --git a/src/plugins/qmljstools/qmljscodestylesettingspage.cpp b/src/plugins/qmljstools/qmljscodestylesettingspage.cpp index baf3b523d84..bb1fbe755b7 100644 --- a/src/plugins/qmljstools/qmljscodestylesettingspage.cpp +++ b/src/plugins/qmljstools/qmljscodestylesettingspage.cpp @@ -196,13 +196,11 @@ void QmlJSCodeStyleSettingsPage::apply() TextEditor::SimpleCodeStylePreferences *originalTabPreferences = QmlJSToolsSettings::globalCodeStyle(); if (originalTabPreferences->tabSettings() != m_pageTabPreferences->tabSettings()) { originalTabPreferences->setTabSettings(m_pageTabPreferences->tabSettings()); - if (s) - originalTabPreferences->toSettings(QLatin1String(QmlJSTools::Constants::QML_JS_SETTINGS_ID), s); + originalTabPreferences->toSettings(QLatin1String(QmlJSTools::Constants::QML_JS_SETTINGS_ID), s); } if (originalTabPreferences->currentDelegate() != m_pageTabPreferences->currentDelegate()) { originalTabPreferences->setCurrentDelegate(m_pageTabPreferences->currentDelegate()); - if (s) - originalTabPreferences->toSettings(QLatin1String(QmlJSTools::Constants::QML_JS_SETTINGS_ID), s); + originalTabPreferences->toSettings(QLatin1String(QmlJSTools::Constants::QML_JS_SETTINGS_ID), s); } } } diff --git a/src/plugins/qnx/blackberryconfiguration.cpp b/src/plugins/qnx/blackberryconfiguration.cpp index 34889388c0b..eceaee1916d 100644 --- a/src/plugins/qnx/blackberryconfiguration.cpp +++ b/src/plugins/qnx/blackberryconfiguration.cpp @@ -131,7 +131,7 @@ bool BlackBerryConfiguration::refresh() void BlackBerryConfiguration::loadCertificates() { - QSettings *settings = Core::ICore::instance()->settings(); + QSettings *settings = Core::ICore::settings(); settings->beginGroup(SettingsGroup); settings->beginGroup(CertificateGroup); @@ -158,7 +158,7 @@ void BlackBerryConfiguration::loadCertificates() void BlackBerryConfiguration::loadNdkSettings() { - QSettings *settings = Core::ICore::instance()->settings(); + QSettings *settings = Core::ICore::settings(); settings->beginGroup(SettingsGroup); setNdkPath(settings->value(NDKLocationKey).toString()); @@ -167,7 +167,7 @@ void BlackBerryConfiguration::loadNdkSettings() void BlackBerryConfiguration::saveCertificates() { - QSettings *settings = Core::ICore::instance()->settings(); + QSettings *settings = Core::ICore::settings(); settings->beginGroup(SettingsGroup); settings->beginGroup(CertificateGroup); @@ -194,7 +194,7 @@ void BlackBerryConfiguration::saveNdkSettings() if (m_config.ndkPath.isEmpty()) return; - QSettings *settings = Core::ICore::instance()->settings(); + QSettings *settings = Core::ICore::settings(); settings->beginGroup(SettingsGroup); settings->setValue(NDKLocationKey, m_config.ndkPath); settings->endGroup(); @@ -396,7 +396,7 @@ void BlackBerryConfiguration::saveSettings() void BlackBerryConfiguration::clearNdkSettings() { - QSettings *settings = Core::ICore::instance()->settings(); + QSettings *settings = Core::ICore::settings(); settings->beginGroup(SettingsGroup); settings->remove(NDKLocationKey); settings->endGroup(); From df5fb89800f80eabdcdbc9e86ae2cd578802bb5f Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Tue, 28 May 2013 20:22:01 +0300 Subject: [PATCH 06/37] PythonEditor: Remove pluginspec.in Missed in 9617005e1dd129849f84780b55cd8900b00419cc Change-Id: Ibd8eba395e138a448d7316aa64b70ff89ae60900 Reviewed-by: Oswald Buddenhagen --- src/plugins/pythoneditor/pythoneditor.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/pythoneditor/pythoneditor.pro b/src/plugins/pythoneditor/pythoneditor.pro index 9d33f9f8a22..614f7708830 100644 --- a/src/plugins/pythoneditor/pythoneditor.pro +++ b/src/plugins/pythoneditor/pythoneditor.pro @@ -3,7 +3,7 @@ include(../../qtcreatorplugin.pri) DEFINES += \ PYTHONEDITOR_LIBRARY -OTHER_FILES += PythonEditor.pluginspec.in \ +OTHER_FILES += \ pythoneditor.mimetypes.xml RESOURCES += \ From e794d16ff39c934a125c2dc43c70883c4fc30da6 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 29 May 2013 11:17:12 +0200 Subject: [PATCH 07/37] tr()-fixes: Add Q_OBJECT to CdbPathsPageWidget. It uses tr(). Change-Id: I2094c4a5465a8d3bc691000bfc1cae4c80712200 Reviewed-by: hjk --- src/plugins/debugger/cdb/cdboptionspage.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/debugger/cdb/cdboptionspage.cpp b/src/plugins/debugger/cdb/cdboptionspage.cpp index 2b25ede46ba..648a4cd746c 100644 --- a/src/plugins/debugger/cdb/cdboptionspage.cpp +++ b/src/plugins/debugger/cdb/cdboptionspage.cpp @@ -261,6 +261,7 @@ bool CdbOptionsPage::matches(const QString &s) const class CdbPathsPageWidget : public QWidget { + Q_OBJECT public: Utils::SavedActionSet group; @@ -346,3 +347,5 @@ bool CdbPathsPage::matches(const QString &searchKeyWord) const } // namespace Internal } // namespace Debugger + +#include "cdboptionspage.moc" From cccc39ccc7c1a79138c17747c1243ff097b21da7 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 29 May 2013 10:27:35 +0200 Subject: [PATCH 08/37] Version bump Change-Id: I740c2db6660713aa8db192464c96ce91d827b0e5 --- qtcreator.pri | 2 +- qtcreator.qbs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qtcreator.pri b/qtcreator.pri index efc264bc3da..5252de058c8 100644 --- a/qtcreator.pri +++ b/qtcreator.pri @@ -1,7 +1,7 @@ !isEmpty(QTCREATOR_PRI_INCLUDED):error("qtcreator.pri already included") QTCREATOR_PRI_INCLUDED = 1 -QTCREATOR_VERSION = 2.7.81 +QTCREATOR_VERSION = 2.7.82 isEqual(QT_MAJOR_VERSION, 5) { diff --git a/qtcreator.qbs b/qtcreator.qbs index e773619b38d..1cf9dee47f6 100644 --- a/qtcreator.qbs +++ b/qtcreator.qbs @@ -6,7 +6,7 @@ Project { property string ide_version_major: '2' property string ide_version_minor: '7' - property string ide_version_release: '81' + property string ide_version_release: '82' property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' + ide_version_release property string ide_app_path: qbs.targetOS == "mac" ? "" : "bin" property string ide_app_target: qbs.targetOS == "mac" ? "Qt Creator" : "qtcreator" From 61bf74be322e6c8ba701208ef21c5b7de0a1e124 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 May 2013 14:30:36 +0200 Subject: [PATCH 09/37] Debugger: Work on LLDB event handling Change-Id: Ie97c628ece272249c23aab6d5438555c051f5aa8 Reviewed-by: hjk --- share/qtcreator/dumper/lbridge.py | 141 ++++++++++++++++------- src/plugins/debugger/lldb/lldbengine.cpp | 6 +- 2 files changed, 107 insertions(+), 40 deletions(-) diff --git a/share/qtcreator/dumper/lbridge.py b/share/qtcreator/dumper/lbridge.py index 297b9b217d2..584d10f7a1a 100644 --- a/share/qtcreator/dumper/lbridge.py +++ b/share/qtcreator/dumper/lbridge.py @@ -325,7 +325,7 @@ lldb.SBType.unqualified = lambda self: self.GetUnqualifiedType() lldb.SBType.pointer = lambda self: self.GetPointerType() lldb.SBType.code = lambda self: self.GetTypeClass() lldb.SBType.sizeof = property(lambda self: self.GetByteSize()) -lldb.SBType.strip_typedefs = lambda self: self +lldb.SBType.strip_typedefs = lambda self: self.GetCanonicalType() def simpleEncoding(typeobj): code = typeobj.GetTypeClass() @@ -504,6 +504,7 @@ class Dumper: self.useLldbDumpers = False self.ns = "" self.autoDerefPointers = True + self.useLoop = True self.currentIName = None self.currentValuePriority = -100 @@ -517,6 +518,7 @@ class Dumper: self.currentChildType = None self.currentChildNumChild = None + self.executable_ = None self.charType_ = None self.intType_ = None self.sizetType_ = None @@ -564,12 +566,12 @@ class Dumper: def intType(self): if self.intType_ is None: - self.intType_ = self.target.GetModuleAtIndex(0).FindFirstType('int') + self.intType_ = self.target.FindFirstType('int') return self.intType_ def charType(self): if self.charType_ is None: - self.charType_ = self.target.GetModuleAtIndex(0).FindFirstType('char') + self.charType_ = self.target.FindFirstType('char') return self.charType_ def charPtrType(self): @@ -578,9 +580,11 @@ class Dumper: return self.charPtrType_ def voidPtrType(self): + return None return self.charPtrType() # FIXME def voidPtrSize(self): + return None return self.charPtrType().GetByteSize() def sizetType(self): @@ -676,43 +680,75 @@ class Dumper: return xrange(min(self.currentMaxNumChild, self.currentNumChild)) def lookupType(self, name): - #warn("LOOKUP: %s" % self.target.GetModuleAtIndex(0).FindFirstType(name)) - return self.target.GetModuleAtIndex(0).FindFirstType(name) + #warn("LOOKUP: %s" % self.target.FindFirstType(name)) + return self.target.FindFirstType(name) def setupInferior(self, args): - fileName = args['executable'] + executable = args['executable'] + self.executable_ = executable error = lldb.SBError() - self.target = self.debugger.CreateTarget(fileName, None, None, True, error) + self.target = self.debugger.CreateTarget(executable, None, None, True, error) if self.target.IsValid(): - self.report('state="inferiorsetupok",msg="%s",exe="%s"' % (error, fileName)) + self.report('state="inferiorsetupok",msg="%s",exe="%s"' % (error, executable)) else: - self.report('state="inferiorsetupfailed",msg="%s",exe="%s"' % (error, fileName)) + self.report('state="inferiorsetupfailed",msg="%s",exe="%s"' % (error, executable)) self.importDumpers() + if False: + self.process = self.target.LaunchSimple(None, None, os.getcwd()) + self.broadcaster = self.process.GetBroadcaster() + self.listener = lldb.SBListener('my listener') + rc = self.broadcaster.AddListener(self.listener, 15) + warn("ADD LISTENER: %s" % rc) + if True: + self.listener = self.target.GetDebugger().GetListener() + self.process = self.target.Launch(self.listener, None, None, + None, None, None, + None, 0, True, error) + self.broadcaster = self.process.GetBroadcaster() + rc = self.broadcaster.AddListener(self.listener, 15) + warn("ADD LISTENER: %s" % rc) + #self.process = self.target.Launch(self.listener, None, None, + # None, None, None, + # os.getcwd(), + # lldb.eLaunchFlagExec + # + lldb.eLaunchFlagDebug + # #+ lldb.eLaunchFlagDebug + # #+ lldb.eLaunchFlagStopAtEntry + # #+ lldb.eLaunchFlagDisableSTDIO + # #+ lldb.eLaunchFlagLaunchInSeparateProcessGroup + # , False, error) + #self.reportError(error) + warn("STATE AFTER LAUNCH: %s" % self.process.GetState()) + warn("STATE AFTER LAUNCH: %s" % stateNames[self.process.GetState()]) + def runEngine(self, _): error = lldb.SBError() #launchInfo = lldb.SBLaunchInfo(["-s"]) #self.process = self.target.Launch(self.listener, None, None, - # None, '/tmp/stdout.txt', None, + # None, None, None, # None, 0, True, error) - self.listener = lldb.SBListener("event_Listener") - self.process = self.target.Launch(self.listener, None, None, - None, None, None, - os.getcwd(), - lldb.eLaunchFlagExec - + lldb.eLaunchFlagDebug - #+ lldb.eLaunchFlagDebug - #+ lldb.eLaunchFlagStopAtEntry - #+ lldb.eLaunchFlagDisableSTDIO - #+ lldb.eLaunchFlagLaunchInSeparateProcessGroup - , False, error) - self.reportError(error) + #self.listener = lldb.SBListener("event_Listener") + #self.process = self.target.Launch(self.listener, None, None, + # None, None, None, + # os.getcwd(), + # lldb.eLaunchFlagExec + # + lldb.eLaunchFlagDebug + # #+ lldb.eLaunchFlagDebug + # #+ lldb.eLaunchFlagStopAtEntry + # #+ lldb.eLaunchFlagDisableSTDIO + # #+ lldb.eLaunchFlagLaunchInSeparateProcessGroup + # , False, error) self.pid = self.process.GetProcessID() self.report('pid="%s"' % self.pid) - self.report('state="enginerunok"') + self.report('state="enginerunandinferiorstopok"') + error = self.process.Continue() + #self.reportError(error) + #self.report('state="enginerunandinferiorstopok"') - s = threading.Thread(target=self.loop, args=[]) - s.start() + if self.useLoop: + s = threading.Thread(target=self.loop, args=[]) + s.start() def describeError(self, error): desc = lldb.SBStream() @@ -811,13 +847,15 @@ class Dumper: def readRawMemory(self, base, size): - error = lldb.SBError() + if size == 0: + return "" #warn("BASE: %s " % base) #warn("SIZE: %s " % size) base = int(base) & 0xFFFFFFFFFFFFFFFF size = int(size) & 0xFFFFFFFF #warn("BASEX: %s " % base) #warn("SIZEX: %s " % size) + error = lldb.SBError() contents = self.process.ReadMemory(base, size, error) return binascii.hexlify(contents) @@ -1010,9 +1048,10 @@ class Dumper: if state != self.eventState: self.report('state="%s"' % stateNames[state]) self.eventState = state - #if state == lldb.eStateExited: - # warn("PROCESS EXITED. %d: %s" - # % (self.process.GetExitStatus(), self.process.GetExitDescription())) + if state == lldb.eStateExited: + warn("PROCESS EXITED. %d: %s" + % (self.process.GetExitStatus(), self.process.GetExitDescription())) + self.report('state="inferiorexited"') if type == lldb.SBProcess.eBroadcastBitStateChanged: #if state == lldb.eStateStopped: self.reportData() @@ -1127,8 +1166,9 @@ class Dumper: def listModules(self, args): result = 'modules=[' - for module in self.target.modules: - result += '{file="%s"' % module.file.fullpath + for i in xrange(self.target.GetNumModules()): + module = self.target.GetModuleAtIndex(i) + result += '{file="%s"' % module.file.GetFullPath() result += ',name="%s"' % module.file.basename result += ',addrsize="%s"' % module.addr_size result += ',triple="%s"' % module.triple @@ -1146,8 +1186,9 @@ class Dumper: moduleName = args['module'] #file = lldb.SBFileSpec(moduleName) #module = self.target.FindModule(file) - for module in self.target.modules: - if module.file.fullpath == moduleName: + for i in xrange(self.target.GetNumModules()): + module = self.target.GetModuleAtIndex(i) + if module.file.GetFullPath() == moduleName: break result = 'symbols={module="%s"' % moduleName result += ',valid="%s"' % module.IsValid() @@ -1279,19 +1320,41 @@ class Dumper: def execute(self, args): getattr(self, args['cmd'])(args) self.report('token="%s"' % args['token']) - try: + if 'continuation' in args: cont = args['continuation'] self.report('continuation="%s"' % cont) - except: - pass currentDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) execfile(os.path.join(currentDir, "qttypes.py")) -def doit(): +def doit1(): db = Dumper() + db.useLoop = False + db.report('state="enginesetupok"') + + while True: + readable, _, _ = select.select([sys.stdin], [], [], 0.1) + event = lldb.SBEvent() + if db.listener and db.listener.PeekAtNextEvent(event): + db.listener.GetNextEvent(event) + db.handleEvent(event) + + if sys.stdin in readable: + line = raw_input() + if line.startswith("db "): + db.execute(eval(line[3:])) + + event = lldb.SBEvent() + if db.listener and db.listener.PeekAtNextEvent(event): + db.listener.GetNextEvent(event) + db.handleEvent(event) + +def doit2(): + + db = Dumper() + db.useLoop = True db.report('state="enginesetupok"') while True: @@ -1304,9 +1367,9 @@ def doit(): db.execute(eval(line[3:])) - def testit(): db = Dumper() + db.useLoop = False error = lldb.SBError() db.target = db.debugger.CreateTarget(sys.argv[2], None, None, True, error) @@ -1344,4 +1407,4 @@ def testit(): if len(sys.argv) > 2: testit() else: - doit() + doit2() diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 119382b8781..b9dcffa3066 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -985,8 +985,12 @@ void LldbEngine::refreshState(const GdbMi &reportedState) notifyInferiorSpontaneousStop(); else if (newState == "inferiorsetupok") notifyInferiorSetupOk(); - else if (newState == "enginerunok") + else if (newState == "enginerunandinferiorrunok") notifyEngineRunAndInferiorRunOk(); + else if (newState == "enginerunandinferiorstopok") + notifyEngineRunAndInferiorStopOk(); + else if (newState == "inferiorexited") + notifyInferiorExited(); } void LldbEngine::refreshLocation(const GdbMi &reportedLocation) From 14481df6709094ea63e130ce1dccda70760d9428 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 29 May 2013 12:14:49 +0200 Subject: [PATCH 10/37] Debugger: Handle application output in LLDB interface Change-Id: Ie97c628ece272249c23aab6d5438555c051f5aa1 Reviewed-by: hjk --- share/qtcreator/dumper/lbridge.py | 11 +++++++---- src/plugins/debugger/lldb/lldbengine.cpp | 14 ++++++++++++++ src/plugins/debugger/lldb/lldbengine.h | 3 ++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/share/qtcreator/dumper/lbridge.py b/share/qtcreator/dumper/lbridge.py index 584d10f7a1a..609504316c8 100644 --- a/share/qtcreator/dumper/lbridge.py +++ b/share/qtcreator/dumper/lbridge.py @@ -845,7 +845,6 @@ class Dumper: self.currentType = str(type) self.currentTypePriority = self.currentTypePriority + 1 - def readRawMemory(self, base, size): if size == 0: return "" @@ -1053,14 +1052,18 @@ class Dumper: % (self.process.GetExitStatus(), self.process.GetExitDescription())) self.report('state="inferiorexited"') if type == lldb.SBProcess.eBroadcastBitStateChanged: - #if state == lldb.eStateStopped: self.reportData() elif type == lldb.SBProcess.eBroadcastBitInterrupt: pass elif type == lldb.SBProcess.eBroadcastBitSTDOUT: - pass + # FIXME: Size? + msg = self.process.GetSTDOUT(1024) + self.report('output={channel="stdout",data="%s"}' + % binascii.hexlify(msg)) elif type == lldb.SBProcess.eBroadcastBitSTDERR: - pass + msg = self.process.GetSTDERR(1024) + self.report('output={channel="stdout",data="%s"}' + % binascii.hexlify(msg)) elif type == lldb.SBProcess.eBroadcastBitProfileData: pass diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index b9dcffa3066..4af3b763802 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -249,6 +249,8 @@ void LldbEngine::handleResponse(const QByteArray &response) refreshSymbols(item); else if (name == "bkpts") refreshBreakpoints(item); + else if (name == "output") + refreshOutput(item); else if (name == "disassembly") refreshDisassembly(item); else if (name == "memory") @@ -483,6 +485,18 @@ void LldbEngine::refreshMemory(const GdbMi &data) } } +void LldbEngine::refreshOutput(const GdbMi &output) +{ + QByteArray channel = output["channel"].data(); + QByteArray data = QByteArray::fromHex(output["data"].data()); + LogChannel ch = AppStuff; + if (channel == "stdout") + ch = AppOutput; + else if (channel == "stderr") + ch = AppError; + showMessage(QString::fromUtf8(data), ch); +} + void LldbEngine::refreshBreakpoints(const GdbMi &bkpts) { BreakHandler *handler = breakHandler(); diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index 818ee91ca64..82c58ea46d6 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -156,13 +156,14 @@ private: void refreshAll(const GdbMi &all); void refreshThreads(const GdbMi &threads); void refreshStack(const GdbMi &stack); - void refreshRegisters(const GdbMi &stack); + void refreshRegisters(const GdbMi ®isters); void refreshLocals(const GdbMi &vars); void refreshTypeInfo(const GdbMi &typeInfo); void refreshState(const GdbMi &state); void refreshLocation(const GdbMi &location); void refreshModules(const GdbMi &modules); void refreshSymbols(const GdbMi &symbols); + void refreshOutput(const GdbMi &output); void refreshBreakpoints(const GdbMi &bkpts); void runContinuation(const GdbMi &data); From 8934100a127631a9e66ad0fb3356ad815527f464 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 28 May 2013 15:57:45 +0200 Subject: [PATCH 11/37] QmlDesigner: Export RewriterException Change-Id: I292a974647cc720279ad678426db90f77816a777 Reviewed-by: Thomas Hartmann --- .../qmldesigner/designercore/include/rewritingexception.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/designercore/include/rewritingexception.h b/src/plugins/qmldesigner/designercore/include/rewritingexception.h index 51eadee4e6d..48abe9b96c6 100644 --- a/src/plugins/qmldesigner/designercore/include/rewritingexception.h +++ b/src/plugins/qmldesigner/designercore/include/rewritingexception.h @@ -34,7 +34,7 @@ namespace QmlDesigner { -class RewritingException: public Exception +class QMLDESIGNERCORE_EXPORT RewritingException: public Exception { public: RewritingException(int line, From c7dd854842e57d10b4781e8d592278351a778d55 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 28 May 2013 16:48:46 +0200 Subject: [PATCH 12/37] QmlDesigner: Add helper functions for translated text Change-Id: Ib5b5037f492f7f7ee448aebd5215d28e0ccae7f0 Reviewed-by: Thomas Hartmann --- .../designercore/include/qmlobjectnode.h | 4 +++ .../designercore/model/qmlobjectnode.cpp | 33 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/plugins/qmldesigner/designercore/include/qmlobjectnode.h b/src/plugins/qmldesigner/designercore/include/qmlobjectnode.h index 552b5b1fb2e..bbbecdbe6f5 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlobjectnode.h +++ b/src/plugins/qmldesigner/designercore/include/qmlobjectnode.h @@ -72,6 +72,8 @@ public: bool instanceHasBinding(const PropertyName &name) const; bool propertyAffectedByCurrentState(const PropertyName &name) const; QVariant modelValue(const PropertyName &name) const; + bool isTranslatableText(const PropertyName &name) const; + QString stripedTranslatableText(const PropertyName &name) const; QString expression(const PropertyName &name) const; bool isInBaseState() const; QmlPropertyChanges propertyChangeForCurrentState() const; @@ -98,6 +100,8 @@ public: static QVariant instanceValue(const ModelNode &modelNode, const PropertyName &name); + static QString generateTranslatableText(const QString& text); + protected: NodeInstance nodeInstance() const; QmlObjectNode nodeForInstance(const NodeInstance &instance) const; diff --git a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp index 0681f2f3f5a..42643ed82fb 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp @@ -175,6 +175,34 @@ QVariant QmlObjectNode::modelValue(const PropertyName &name) const return propertyChanges.modelNode().variantProperty(name).value(); } +bool QmlObjectNode::isTranslatableText(const PropertyName &name) const +{ + if (modelNode().metaInfo().isValid() && modelNode().metaInfo().hasProperty(name)) + if (modelNode().metaInfo().propertyTypeName(name) == "QString" || modelNode().metaInfo().propertyTypeName(name) == "string") { + if (modelNode().hasBindingProperty(name)) { + static QRegExp regularExpressionPatter("qsTr\\((\".*\")\\)"); + return regularExpressionPatter.exactMatch(modelNode().bindingProperty(name).expression()); + } + + return false; + } + + return false; +} + +QString QmlObjectNode::stripedTranslatableText(const PropertyName &name) const +{ + if (modelNode().hasBindingProperty(name)) { + static QRegExp regularExpressionPatter("qsTr\\(\"(.*)\"\\)"); + if (regularExpressionPatter.exactMatch(modelNode().bindingProperty(name).expression())) + return regularExpressionPatter.cap(1); + } else { + return modelNode().variantProperty(name).value().toString(); + } + + return QString(); +} + QString QmlObjectNode::expression(const PropertyName &name) const { if (!isValid()) @@ -387,6 +415,11 @@ QVariant QmlObjectNode::instanceValue(const ModelNode &modelNode, const Property return modelView->instanceForModelNode(modelNode).property(name); } +QString QmlObjectNode::generateTranslatableText(const QString &text) +{ + return QString("qsTr(\"%1\")").arg(text); +} + TypeName QmlObjectNode::instanceType(const PropertyName &name) const { return nodeInstance().instanceType(name); From 281c42c7614e12f6b2f5e444ca0818837c13fb05 Mon Sep 17 00:00:00 2001 From: hjk Date: Sat, 25 May 2013 02:48:52 +0200 Subject: [PATCH 13/37] BinEditor: Rename Editor->EditorWidget, Editable->Editor Closer to modern naming convention. Change-Id: I80875d865336495995e0a8ad05aaf49e22fa3fb0 Reviewed-by: David Schulz --- src/plugins/bineditor/bineditor.cpp | 136 +++++++++++----------- src/plugins/bineditor/bineditor.h | 6 +- src/plugins/bineditor/bineditorplugin.cpp | 122 +++++++++---------- src/plugins/bineditor/bineditorplugin.h | 6 +- 4 files changed, 136 insertions(+), 134 deletions(-) diff --git a/src/plugins/bineditor/bineditor.cpp b/src/plugins/bineditor/bineditor.cpp index 2037b4542d0..4fa6c608eb6 100644 --- a/src/plugins/bineditor/bineditor.cpp +++ b/src/plugins/bineditor/bineditor.cpp @@ -85,7 +85,7 @@ static QByteArray calculateHexPattern(const QByteArray &pattern) namespace BINEditor { -BinEditor::BinEditor(QWidget *parent) +BinEditorWidget::BinEditorWidget(QWidget *parent) : QAbstractScrollArea(parent) { m_bytesPerLine = 16; @@ -108,11 +108,11 @@ BinEditor::BinEditor(QWidget *parent) setFrameStyle(QFrame::Plain); } -BinEditor::~BinEditor() +BinEditorWidget::~BinEditorWidget() { } -void BinEditor::init() +void BinEditorWidget::init() { const int addressStringWidth = 2*m_addressBytes + (m_addressBytes - 1) / 2; @@ -162,7 +162,7 @@ void BinEditor::init() } -void BinEditor::addData(quint64 block, const QByteArray &data) +void BinEditorWidget::addData(quint64 block, const QByteArray &data) { QTC_ASSERT(data.size() == m_blockSize, return); const quint64 addr = block * m_blockSize; @@ -176,7 +176,7 @@ void BinEditor::addData(quint64 block, const QByteArray &data) } } -bool BinEditor::requestDataAt(int pos) const +bool BinEditorWidget::requestDataAt(int pos) const { int block = pos / m_blockSize; BlockMap::const_iterator it = m_modifiedData.find(block); @@ -187,27 +187,27 @@ bool BinEditor::requestDataAt(int pos) const return true; if (!m_requests.contains(block)) { m_requests.insert(block); - emit const_cast(this)-> + emit const_cast(this)-> dataRequested(editor(), m_baseAddr / m_blockSize + block); return true; } return false; } -bool BinEditor::requestOldDataAt(int pos) const +bool BinEditorWidget::requestOldDataAt(int pos) const { int block = pos / m_blockSize; BlockMap::const_iterator it = m_oldData.find(block); return it != m_oldData.end(); } -char BinEditor::dataAt(int pos, bool old) const +char BinEditorWidget::dataAt(int pos, bool old) const { int block = pos / m_blockSize; return blockData(block, old).at(pos - block*m_blockSize); } -void BinEditor::changeDataAt(int pos, char c) +void BinEditorWidget::changeDataAt(int pos, char c) { int block = pos / m_blockSize; BlockMap::iterator it = m_modifiedData.find(block); @@ -225,7 +225,7 @@ void BinEditor::changeDataAt(int pos, char c) emit dataChanged(editor(), m_baseAddr + pos, QByteArray(1, c)); } -QByteArray BinEditor::dataMid(int from, int length, bool old) const +QByteArray BinEditorWidget::dataMid(int from, int length, bool old) const { int end = from + length; int block = from / m_blockSize; @@ -239,7 +239,7 @@ QByteArray BinEditor::dataMid(int from, int length, bool old) const return data.mid(from - ((from / m_blockSize) * m_blockSize), length); } -QByteArray BinEditor::blockData(int block, bool old) const +QByteArray BinEditorWidget::blockData(int block, bool old) const { if (old) { BlockMap::const_iterator it = m_modifiedData.find(block); @@ -251,12 +251,12 @@ QByteArray BinEditor::blockData(int block, bool old) const ? it.value() : m_data.value(block, m_emptyBlock); } -void BinEditor::setFontSettings(const TextEditor::FontSettings &fs) +void BinEditorWidget::setFontSettings(const TextEditor::FontSettings &fs) { setFont(fs.toTextCharFormat(TextEditor::C_TEXT).font()); } -void BinEditor::setBlinkingCursorEnabled(bool enable) +void BinEditorWidget::setBlinkingCursorEnabled(bool enable) { if (enable && QApplication::cursorFlashTime() > 0) m_cursorBlinkTimer.start(QApplication::cursorFlashTime() / 2, this); @@ -266,17 +266,17 @@ void BinEditor::setBlinkingCursorEnabled(bool enable) updateLines(); } -void BinEditor::focusInEvent(QFocusEvent *) +void BinEditorWidget::focusInEvent(QFocusEvent *) { setBlinkingCursorEnabled(true); } -void BinEditor::focusOutEvent(QFocusEvent *) +void BinEditorWidget::focusOutEvent(QFocusEvent *) { setBlinkingCursorEnabled(false); } -void BinEditor::timerEvent(QTimerEvent *e) +void BinEditorWidget::timerEvent(QTimerEvent *e) { if (e->timerId() == m_autoScrollTimer.timerId()) { QRect visible = viewport()->rect(); @@ -314,7 +314,7 @@ void BinEditor::timerEvent(QTimerEvent *e) } -void BinEditor::setModified(bool modified) +void BinEditorWidget::setModified(bool modified) { int unmodifiedState = modified ? -1 : m_undoStack.size(); if (unmodifiedState == m_unmodifiedState) @@ -323,22 +323,22 @@ void BinEditor::setModified(bool modified) emit modificationChanged(m_undoStack.size() != m_unmodifiedState); } -bool BinEditor::isModified() const +bool BinEditorWidget::isModified() const { return (m_undoStack.size() != m_unmodifiedState); } -void BinEditor::setReadOnly(bool readOnly) +void BinEditorWidget::setReadOnly(bool readOnly) { m_readOnly = readOnly; } -bool BinEditor::isReadOnly() const +bool BinEditorWidget::isReadOnly() const { return m_readOnly; } -bool BinEditor::save(QString *errorString, const QString &oldFileName, const QString &newFileName) +bool BinEditorWidget::save(QString *errorString, const QString &oldFileName, const QString &newFileName) { if (oldFileName != newFileName) { QString tmpName; @@ -381,7 +381,7 @@ bool BinEditor::save(QString *errorString, const QString &oldFileName, const QSt return true; } -void BinEditor::setSizes(quint64 startAddr, int range, int blockSize) +void BinEditorWidget::setSizes(quint64 startAddr, int range, int blockSize) { int newBlockSize = blockSize; QTC_ASSERT((blockSize/m_bytesPerLine) * m_bytesPerLine == blockSize, @@ -423,12 +423,12 @@ void BinEditor::setSizes(quint64 startAddr, int range, int blockSize) viewport()->update(); } -void BinEditor::resizeEvent(QResizeEvent *) +void BinEditorWidget::resizeEvent(QResizeEvent *) { init(); } -void BinEditor::scrollContentsBy(int dx, int dy) +void BinEditorWidget::scrollContentsBy(int dx, int dy) { viewport()->scroll(isRightToLeft() ? -dx : dx, dy * m_lineHeight); const QScrollBar * const scrollBar = verticalScrollBar(); @@ -439,7 +439,7 @@ void BinEditor::scrollContentsBy(int dx, int dy) emit newRangeRequested(editor(), baseAddress()); } -void BinEditor::changeEvent(QEvent *e) +void BinEditorWidget::changeEvent(QEvent *e) { QAbstractScrollArea::changeEvent(e); if (e->type() == QEvent::ActivationChange) { @@ -451,7 +451,7 @@ void BinEditor::changeEvent(QEvent *e) } -void BinEditor::wheelEvent(QWheelEvent *e) +void BinEditorWidget::wheelEvent(QWheelEvent *e) { if (e->modifiers() & Qt::ControlModifier) { const int delta = e->delta(); @@ -466,7 +466,7 @@ void BinEditor::wheelEvent(QWheelEvent *e) -QRect BinEditor::cursorRect() const +QRect BinEditorWidget::cursorRect() const { int topLine = verticalScrollBar()->value(); int line = m_cursorPosition / m_bytesPerLine; @@ -481,7 +481,7 @@ QRect BinEditor::cursorRect() const return QRect(x, y, w, m_lineHeight); } -int BinEditor::posAt(const QPoint &pos) const +int BinEditorWidget::posAt(const QPoint &pos) const { int xoffset = horizontalScrollBar()->value(); int x = xoffset + pos.x() - m_margin - m_labelWidth; @@ -508,19 +508,19 @@ int BinEditor::posAt(const QPoint &pos) const return qMin(m_size, qMin(m_numLines, topLine + line) * m_bytesPerLine) + column; } -bool BinEditor::inTextArea(const QPoint &pos) const +bool BinEditorWidget::inTextArea(const QPoint &pos) const { int xoffset = horizontalScrollBar()->value(); int x = xoffset + pos.x() - m_margin - m_labelWidth; return (x > m_bytesPerLine * m_columnWidth + m_charWidth/2); } -void BinEditor::updateLines() +void BinEditorWidget::updateLines() { updateLines(m_cursorPosition, m_cursorPosition); } -void BinEditor::updateLines(int fromPosition, int toPosition) +void BinEditorWidget::updateLines(int fromPosition, int toPosition) { int topLine = verticalScrollBar()->value(); int firstLine = qMin(fromPosition, toPosition) / m_bytesPerLine; @@ -531,7 +531,7 @@ void BinEditor::updateLines(int fromPosition, int toPosition) viewport()->update(0, y, viewport()->width(), h); } -int BinEditor::dataIndexOf(const QByteArray &pattern, int from, bool caseSensitive) const +int BinEditorWidget::dataIndexOf(const QByteArray &pattern, int from, bool caseSensitive) const { int trailing = pattern.size(); if (trailing > m_blockSize) @@ -564,7 +564,7 @@ int BinEditor::dataIndexOf(const QByteArray &pattern, int from, bool caseSensiti return end == m_size ? -1 : -2; } -int BinEditor::dataLastIndexOf(const QByteArray &pattern, int from, bool caseSensitive) const +int BinEditorWidget::dataLastIndexOf(const QByteArray &pattern, int from, bool caseSensitive) const { int trailing = pattern.size(); if (trailing > m_blockSize) @@ -596,7 +596,7 @@ int BinEditor::dataLastIndexOf(const QByteArray &pattern, int from, bool caseSen } -int BinEditor::find(const QByteArray &pattern_arg, int from, +int BinEditorWidget::find(const QByteArray &pattern_arg, int from, QTextDocument::FindFlags findFlags) { if (pattern_arg.isEmpty()) @@ -633,7 +633,7 @@ int BinEditor::find(const QByteArray &pattern_arg, int from, return pos; } -int BinEditor::findPattern(const QByteArray &data, const QByteArray &dataHex, +int BinEditorWidget::findPattern(const QByteArray &data, const QByteArray &dataHex, int from, int offset, int *match) { if (m_searchPattern.isEmpty()) @@ -658,7 +658,7 @@ int BinEditor::findPattern(const QByteArray &data, const QByteArray &dataHex, } -void BinEditor::drawItems(QPainter *painter, int x, int y, const QString &itemString) +void BinEditorWidget::drawItems(QPainter *painter, int x, int y, const QString &itemString) { if (m_isMonospacedFont) { painter->drawText(x, y, itemString); @@ -668,7 +668,7 @@ void BinEditor::drawItems(QPainter *painter, int x, int y, const QString &itemSt } } -void BinEditor::drawChanges(QPainter *painter, int x, int y, const char *changes) +void BinEditorWidget::drawChanges(QPainter *painter, int x, int y, const char *changes) { const QBrush red(QColor(250, 150, 150)); for (int i = 0; i < m_bytesPerLine; ++i) { @@ -679,7 +679,7 @@ void BinEditor::drawChanges(QPainter *painter, int x, int y, const char *changes } } -QString BinEditor::addressString(quint64 address) +QString BinEditorWidget::addressString(quint64 address) { QChar *addressStringData = m_addressString.data(); const char *hex = "0123456789abcdef"; @@ -698,7 +698,7 @@ QString BinEditor::addressString(quint64 address) return m_addressString; } -void BinEditor::paintEvent(QPaintEvent *e) +void BinEditorWidget::paintEvent(QPaintEvent *e) { QPainter painter(viewport()); const int topLine = verticalScrollBar()->value(); @@ -930,12 +930,12 @@ void BinEditor::paintEvent(QPaintEvent *e) } -int BinEditor::cursorPosition() const +int BinEditorWidget::cursorPosition() const { return m_cursorPosition; } -void BinEditor::setCursorPosition(int pos, MoveMode moveMode) +void BinEditorWidget::setCursorPosition(int pos, MoveMode moveMode) { pos = qMin(m_size-1, qMax(0, pos)); int oldCursorPosition = m_cursorPosition; @@ -957,7 +957,7 @@ void BinEditor::setCursorPosition(int pos, MoveMode moveMode) } -void BinEditor::ensureCursorVisible() +void BinEditorWidget::ensureCursorVisible() { QRect cr = cursorRect(); QRect vr = viewport()->rect(); @@ -969,7 +969,7 @@ void BinEditor::ensureCursorVisible() } } -void BinEditor::mousePressEvent(QMouseEvent *e) +void BinEditorWidget::mousePressEvent(QMouseEvent *e) { if (e->button() != Qt::LeftButton) return; @@ -982,7 +982,7 @@ void BinEditor::mousePressEvent(QMouseEvent *e) } } -void BinEditor::mouseMoveEvent(QMouseEvent *e) +void BinEditorWidget::mouseMoveEvent(QMouseEvent *e) { if (!(e->buttons() & Qt::LeftButton)) return; @@ -998,7 +998,7 @@ void BinEditor::mouseMoveEvent(QMouseEvent *e) m_autoScrollTimer.start(100, this); } -void BinEditor::mouseReleaseEvent(QMouseEvent *) +void BinEditorWidget::mouseReleaseEvent(QMouseEvent *) { if (m_autoScrollTimer.isActive()) { m_autoScrollTimer.stop(); @@ -1006,13 +1006,13 @@ void BinEditor::mouseReleaseEvent(QMouseEvent *) } } -void BinEditor::selectAll() +void BinEditorWidget::selectAll() { setCursorPosition(0); setCursorPosition(m_size-1, KeepAnchor); } -void BinEditor::clear() +void BinEditorWidget::clear() { m_baseAddr = 0; m_data.clear(); @@ -1034,7 +1034,7 @@ void BinEditor::clear() viewport()->update(); } -bool BinEditor::event(QEvent *e) +bool BinEditorWidget::event(QEvent *e) { switch (e->type()) { case QEvent::KeyPress: @@ -1075,7 +1075,7 @@ bool BinEditor::event(QEvent *e) return QAbstractScrollArea::event(e); } -QString BinEditor::toolTip(const QHelpEvent *helpEvent) const +QString BinEditorWidget::toolTip(const QHelpEvent *helpEvent) const { // Selection if mouse is in, else 1 byte at cursor int selStart = selectionStart(); @@ -1257,7 +1257,7 @@ QString BinEditor::toolTip(const QHelpEvent *helpEvent) const return msg; } -void BinEditor::keyPressEvent(QKeyEvent *e) +void BinEditorWidget::keyPressEvent(QKeyEvent *e) { if (e == QKeySequence::SelectAll) { @@ -1356,7 +1356,7 @@ void BinEditor::keyPressEvent(QKeyEvent *e) e->accept(); } -void BinEditor::zoomIn(int range) +void BinEditorWidget::zoomIn(int range) { QFont f = font(); const int newSize = f.pointSize() + range; @@ -1366,12 +1366,12 @@ void BinEditor::zoomIn(int range) setFont(f); } -void BinEditor::zoomOut(int range) +void BinEditorWidget::zoomOut(int range) { zoomIn(-range); } -void BinEditor::copy(bool raw) +void BinEditorWidget::copy(bool raw) { int selStart = selectionStart(); int selEnd = selectionEnd(); @@ -1400,7 +1400,7 @@ void BinEditor::copy(bool raw) QApplication::clipboard()->setText(hexString); } -void BinEditor::highlightSearchResults(const QByteArray &pattern, QTextDocument::FindFlags findFlags) +void BinEditorWidget::highlightSearchResults(const QByteArray &pattern, QTextDocument::FindFlags findFlags) { if (m_searchPattern == pattern) return; @@ -1412,7 +1412,7 @@ void BinEditor::highlightSearchResults(const QByteArray &pattern, QTextDocument: viewport()->update(); } -void BinEditor::changeData(int position, uchar character, bool highNibble) +void BinEditorWidget::changeData(int position, uchar character, bool highNibble) { if (!requestDataAt(position)) return; @@ -1444,7 +1444,7 @@ void BinEditor::changeData(int position, uchar character, bool highNibble) } -void BinEditor::undo() +void BinEditorWidget::undo() { if (m_undoStack.isEmpty()) return; @@ -1464,7 +1464,7 @@ void BinEditor::undo() emit redoAvailable(true); } -void BinEditor::redo() +void BinEditorWidget::redo() { if (m_redoStack.isEmpty()) return; @@ -1483,7 +1483,7 @@ void BinEditor::redo() emit redoAvailable(false); } -void BinEditor::contextMenuEvent(QContextMenuEvent *event) +void BinEditorWidget::contextMenuEvent(QContextMenuEvent *event) { const int selStart = selectionStart(); const int byteCount = selectionEnd() - selStart + 1; @@ -1545,7 +1545,7 @@ void BinEditor::contextMenuEvent(QContextMenuEvent *event) delete contextMenu; } -void BinEditor::setupJumpToMenuAction(QMenu *menu, QAction *actionHere, +void BinEditorWidget::setupJumpToMenuAction(QMenu *menu, QAction *actionHere, QAction *actionNew, quint64 addr) { actionHere->setText(tr("Jump to Address 0x%1 in This Window") @@ -1558,7 +1558,7 @@ void BinEditor::setupJumpToMenuAction(QMenu *menu, QAction *actionHere, actionNew->setEnabled(false); } -void BinEditor::jumpToAddress(quint64 address) +void BinEditorWidget::jumpToAddress(quint64 address) { if (address >= m_baseAddr && address < m_baseAddr + m_size) setCursorPosition(address - m_baseAddr); @@ -1566,26 +1566,26 @@ void BinEditor::jumpToAddress(quint64 address) emit newRangeRequested(editor(), address); } -void BinEditor::setNewWindowRequestAllowed(bool c) +void BinEditorWidget::setNewWindowRequestAllowed(bool c) { m_canRequestNewWindow = c; } -void BinEditor::updateContents() +void BinEditorWidget::updateContents() { m_oldData = m_data; m_data.clear(); setSizes(baseAddress() + cursorPosition(), m_size, m_blockSize); } -QPoint BinEditor::offsetToPos(int offset) const +QPoint BinEditorWidget::offsetToPos(int offset) const { const int x = m_labelWidth + (offset % m_bytesPerLine) * m_columnWidth; const int y = (offset / m_bytesPerLine - verticalScrollBar()->value()) * m_lineHeight; return QPoint(x, y); } -void BinEditor::asFloat(int offset, float &value, bool old) const +void BinEditorWidget::asFloat(int offset, float &value, bool old) const { value = 0; const QByteArray data = dataMid(offset, sizeof(float), old); @@ -1594,7 +1594,7 @@ void BinEditor::asFloat(int offset, float &value, bool old) const value = *f; } -void BinEditor::asDouble(int offset, double &value, bool old) const +void BinEditorWidget::asDouble(int offset, double &value, bool old) const { value = 0; const QByteArray data = dataMid(offset, sizeof(double), old); @@ -1603,7 +1603,7 @@ void BinEditor::asDouble(int offset, double &value, bool old) const value = *f; } -void BinEditor::asIntegers(int offset, int count, quint64 &bigEndianValue, +void BinEditorWidget::asIntegers(int offset, int count, quint64 &bigEndianValue, quint64 &littleEndianValue, bool old) const { bigEndianValue = littleEndianValue = 0; @@ -1615,12 +1615,12 @@ void BinEditor::asIntegers(int offset, int count, quint64 &bigEndianValue, } } -bool BinEditor::isMemoryView() const +bool BinEditorWidget::isMemoryView() const { return editor()->property("MemoryView").toBool(); } -void BinEditor::setMarkup(const QList &markup) +void BinEditorWidget::setMarkup(const QList &markup) { m_markup = markup; viewport()->update(); diff --git a/src/plugins/bineditor/bineditor.h b/src/plugins/bineditor/bineditor.h index 9242a5b00f9..83ef6a346cb 100644 --- a/src/plugins/bineditor/bineditor.h +++ b/src/plugins/bineditor/bineditor.h @@ -55,7 +55,7 @@ class FontSettings; namespace BINEditor { -class BinEditor : public QAbstractScrollArea +class BinEditorWidget : public QAbstractScrollArea { Q_OBJECT Q_PROPERTY(bool modified READ isModified WRITE setModified DESIGNABLE false) @@ -63,8 +63,8 @@ class BinEditor : public QAbstractScrollArea Q_PROPERTY(QList markup READ markup WRITE setMarkup DESIGNABLE false) Q_PROPERTY(bool newWindowRequestAllowed READ newWindowRequestAllowed WRITE setNewWindowRequestAllowed DESIGNABLE false) public: - BinEditor(QWidget *parent = 0); - ~BinEditor(); + BinEditorWidget(QWidget *parent = 0); + ~BinEditorWidget(); quint64 baseAddress() const { return m_baseAddr; } diff --git a/src/plugins/bineditor/bineditorplugin.cpp b/src/plugins/bineditor/bineditorplugin.cpp index f6e401dae7e..a805e66f6c9 100644 --- a/src/plugins/bineditor/bineditorplugin.cpp +++ b/src/plugins/bineditor/bineditorplugin.cpp @@ -70,15 +70,17 @@ using namespace BINEditor::Internal; class BinEditorFind : public Find::IFindSupport { Q_OBJECT + public: - BinEditorFind(BinEditor *editor) + BinEditorFind(BinEditorWidget *widget) { - m_editor = editor; + m_widget = widget; m_incrementalStartPos = m_contPos = -1; } ~BinEditorFind() {} bool supportsReplace() const { return false; } + Find::FindFlags supportedFindFlags() const { return Find::FindBackward | Find::FindCaseSensitively; @@ -91,21 +93,21 @@ public: virtual void highlightAll(const QString &txt, Find::FindFlags findFlags) { - m_editor->highlightSearchResults(txt.toLatin1(), Find::textDocumentFlagsForFindFlags(findFlags)); + m_widget->highlightSearchResults(txt.toLatin1(), Find::textDocumentFlagsForFindFlags(findFlags)); } - void clearResults() { m_editor->highlightSearchResults(QByteArray()); } + void clearResults() { m_widget->highlightSearchResults(QByteArray()); } QString currentFindString() const { return QString(); } QString completedFindString() const { return QString(); } int find(const QByteArray &pattern, int pos, Find::FindFlags findFlags) { if (pattern.isEmpty()) { - m_editor->setCursorPosition(pos); + m_widget->setCursorPosition(pos); return pos; } - return m_editor->find(pattern, pos, Find::textDocumentFlagsForFindFlags(findFlags)); + return m_widget->find(pattern, pos, Find::textDocumentFlagsForFindFlags(findFlags)); } Result findIncremental(const QString &txt, Find::FindFlags findFlags) { @@ -114,25 +116,25 @@ public: resetIncrementalSearch(); // Because we don't search for nibbles. m_lastPattern = pattern; if (m_incrementalStartPos < 0) - m_incrementalStartPos = m_editor->selectionStart(); + m_incrementalStartPos = m_widget->selectionStart(); if (m_contPos == -1) m_contPos = m_incrementalStartPos; int found = find(pattern, m_contPos, findFlags); Result result; if (found >= 0) { result = Found; - m_editor->highlightSearchResults(pattern, Find::textDocumentFlagsForFindFlags(findFlags)); + m_widget->highlightSearchResults(pattern, Find::textDocumentFlagsForFindFlags(findFlags)); m_contPos = -1; } else { if (found == -2) { result = NotYetFound; m_contPos += findFlags & Find::FindBackward - ? -BinEditor::SearchStride : BinEditor::SearchStride; + ? -BinEditorWidget::SearchStride : BinEditorWidget::SearchStride; } else { result = NotFound; m_contPos = -1; - m_editor->highlightSearchResults(QByteArray(), 0); + m_widget->highlightSearchResults(QByteArray(), 0); } } return result; @@ -142,9 +144,9 @@ public: QByteArray pattern = txt.toLatin1(); bool wasReset = (m_incrementalStartPos < 0); if (m_contPos == -1) { - m_contPos = m_editor->cursorPosition(); + m_contPos = m_widget->cursorPosition(); if (findFlags & Find::FindBackward) - m_contPos = m_editor->selectionStart()-1; + m_contPos = m_widget->selectionStart()-1; } int found = find(pattern, m_contPos, findFlags); Result result; @@ -153,11 +155,11 @@ public: m_incrementalStartPos = found; m_contPos = -1; if (wasReset) - m_editor->highlightSearchResults(pattern, Find::textDocumentFlagsForFindFlags(findFlags)); + m_widget->highlightSearchResults(pattern, Find::textDocumentFlagsForFindFlags(findFlags)); } else if (found == -2) { result = NotYetFound; m_contPos += findFlags & Find::FindBackward - ? -BinEditor::SearchStride : BinEditor::SearchStride; + ? -BinEditorWidget::SearchStride : BinEditorWidget::SearchStride; } else { result = NotFound; m_contPos = -1; @@ -167,7 +169,7 @@ public: } private: - BinEditor *m_editor; + BinEditorWidget *m_widget; int m_incrementalStartPos; int m_contPos; // Only valid if last result was NotYetFound. QByteArray m_lastPattern; @@ -178,13 +180,13 @@ class BinEditorDocument : public Core::IDocument { Q_OBJECT public: - BinEditorDocument(BinEditor *parent) : + BinEditorDocument(BinEditorWidget *parent) : Core::IDocument(parent) { - m_editor = parent; - connect(m_editor, SIGNAL(dataRequested(Core::IEditor*,quint64)), + m_widget = parent; + connect(m_widget, SIGNAL(dataRequested(Core::IEditor*,quint64)), this, SLOT(provideData(Core::IEditor*,quint64))); - connect(m_editor, SIGNAL(newRangeRequested(Core::IEditor*,quint64)), + connect(m_widget, SIGNAL(newRangeRequested(Core::IEditor*,quint64)), this, SLOT(provideNewRange(Core::IEditor*,quint64))); } ~BinEditorDocument() {} @@ -198,9 +200,9 @@ public: QTC_ASSERT(!autoSave, return true); // bineditor does not support autosave - it would be a bit expensive const QString fileNameToUse = fileName.isEmpty() ? m_fileName : fileName; - if (m_editor->save(errorString, m_fileName, fileNameToUse)) { + if (m_widget->save(errorString, m_fileName, fileNameToUse)) { m_fileName = fileNameToUse; - m_editor->editor()->setDisplayName(QFileInfo(fileNameToUse).fileName()); + m_widget->editor()->setDisplayName(QFileInfo(fileNameToUse).fileName()); emit changed(); return true; } else { @@ -210,7 +212,7 @@ public: void rename(const QString &newName) { m_fileName = newName; - m_editor->editor()->setDisplayName(QFileInfo(fileName()).fileName()); + m_widget->editor()->setDisplayName(QFileInfo(fileName()).fileName()); emit changed(); } @@ -230,8 +232,8 @@ public: if (file.open(QIODevice::ReadOnly)) { file.close(); m_fileName = fileName; - m_editor->setSizes(offset, file.size()); - m_editor->editor()->setDisplayName(QFileInfo(fileName).fileName()); + m_widget->setSizes(offset, file.size()); + m_widget->editor()->setDisplayName(QFileInfo(fileName).fileName()); return true; } QString errStr = tr("Cannot open %1: %2").arg( @@ -249,14 +251,14 @@ private slots: return; QFile file(m_fileName); if (file.open(QIODevice::ReadOnly)) { - int blockSize = m_editor->dataBlockSize(); + int blockSize = m_widget->dataBlockSize(); file.seek(block * blockSize); QByteArray data = file.read(blockSize); file.close(); const int dataSize = data.size(); if (dataSize != blockSize) data += QByteArray(blockSize - dataSize, 0); - m_editor->addData(block, data); + m_widget->addData(block, data); } else { QMessageBox::critical(Core::ICore::mainWindow(), tr("File Error"), tr("Cannot open %1: %2").arg( @@ -280,10 +282,10 @@ public: QString suggestedFileName() const { return QString(); } - bool isModified() const { return m_editor->isMemoryView() ? false : m_editor->isModified(); } + bool isModified() const { return m_widget->isMemoryView() ? false : m_widget->isModified(); } bool isFileReadOnly() const { - if (m_editor->isMemoryView() || m_fileName.isEmpty()) + if (m_widget->isMemoryView() || m_fileName.isEmpty()) return false; const QFileInfo fi(m_fileName); return !fi.isWritable(); @@ -306,19 +308,19 @@ public: } private: - BinEditor *m_editor; + BinEditorWidget *m_widget; QString m_fileName; }; -class BinEditorInterface : public Core::IEditor +class BinEditor : public Core::IEditor { Q_OBJECT public: - BinEditorInterface(BinEditor *editor) + BinEditor(BinEditorWidget *widget) { - setWidget(editor); - m_editor = editor; - m_file = new BinEditorDocument(m_editor); + setWidget(widget); + m_widget = widget; + m_file = new BinEditorDocument(m_widget); m_context.add(Core::Constants::K_DEFAULT_BINARY_EDITOR_ID); m_context.add(Constants::C_BINEDITOR); m_addressEdit = new QLineEdit; @@ -339,19 +341,19 @@ public: m_toolBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); m_toolBar->addWidget(w); - connect(m_editor, SIGNAL(cursorPositionChanged(int)), this, + connect(m_widget, SIGNAL(cursorPositionChanged(int)), this, SLOT(updateCursorPosition(int))); connect(m_file, SIGNAL(changed()), this, SIGNAL(changed())); connect(m_addressEdit, SIGNAL(editingFinished()), this, SLOT(jumpToAddress())); - updateCursorPosition(m_editor->cursorPosition()); + updateCursorPosition(m_widget->cursorPosition()); } - ~BinEditorInterface() { - delete m_editor; + ~BinEditor() { + delete m_widget; } bool createNew(const QString & /* contents */ = QString()) { - m_editor->clear(); + m_widget->clear(); m_file->setFilename(QString()); return true; } @@ -366,20 +368,20 @@ public: QWidget *toolBar() { return m_toolBar; } - bool isTemporary() const { return m_editor->isMemoryView(); } + bool isTemporary() const { return m_widget->isMemoryView(); } private slots: void updateCursorPosition(int position) { - m_addressEdit->setText(QString::number(m_editor->baseAddress() + position, 16)); + m_addressEdit->setText(QString::number(m_widget->baseAddress() + position, 16)); } void jumpToAddress() { - m_editor->jumpToAddress(m_addressEdit->text().toULongLong(0, 16)); - updateCursorPosition(m_editor->cursorPosition()); + m_widget->jumpToAddress(m_addressEdit->text().toULongLong(0, 16)); + updateCursorPosition(m_widget->cursorPosition()); } private: - BinEditor *m_editor; + BinEditorWidget *m_widget; QString m_displayName; BinEditorDocument *m_file; QToolBar *m_toolBar; @@ -408,9 +410,9 @@ QString BinEditorFactory::displayName() const Core::IEditor *BinEditorFactory::createEditor(QWidget *parent) { - BinEditor *editor = new BinEditor(parent); - m_owner->initializeEditor(editor); - return editor->editor(); + BinEditorWidget *widget = new BinEditorWidget(parent); + m_owner->initializeEditor(widget); + return widget->editor(); } QStringList BinEditorFactory::mimeTypes() const @@ -433,7 +435,7 @@ BinEditorWidgetFactory::BinEditorWidgetFactory(QObject *parent) : QWidget *BinEditorWidgetFactory::createWidget(QWidget *parent) { - return new BinEditor(parent); + return new BinEditorWidget(parent); } ///////////////////////////////// BinEditorPlugin ////////////////////////////////// @@ -467,11 +469,11 @@ QAction *BinEditorPlugin::registerNewAction(Core::Id id, return rc; } -void BinEditorPlugin::initializeEditor(BinEditor *editor) +void BinEditorPlugin::initializeEditor(BinEditorWidget *widget) { - BinEditorInterface *editorInterface = new BinEditorInterface(editor); - QObject::connect(editor, SIGNAL(modificationChanged(bool)), editorInterface, SIGNAL(changed())); - editor->setEditor(editorInterface); + BinEditor *editor = new BinEditor(widget); + QObject::connect(widget, SIGNAL(modificationChanged(bool)), editor, SIGNAL(changed())); + widget->setEditor(editor); m_context.add(Constants::C_BINEDITOR); if (!m_undoAction) { @@ -483,17 +485,17 @@ void BinEditorPlugin::initializeEditor(BinEditor *editor) // Font settings TextEditor::TextEditorSettings *settings = TextEditor::TextEditorSettings::instance(); - editor->setFontSettings(settings->fontSettings()); + widget->setFontSettings(settings->fontSettings()); connect(settings, SIGNAL(fontSettingsChanged(TextEditor::FontSettings)), - editor, SLOT(setFontSettings(TextEditor::FontSettings))); + widget, SLOT(setFontSettings(TextEditor::FontSettings))); - QObject::connect(editor, SIGNAL(undoAvailable(bool)), this, SLOT(updateActions())); - QObject::connect(editor, SIGNAL(redoAvailable(bool)), this, SLOT(updateActions())); + QObject::connect(widget, SIGNAL(undoAvailable(bool)), this, SLOT(updateActions())); + QObject::connect(widget, SIGNAL(redoAvailable(bool)), this, SLOT(updateActions())); Aggregation::Aggregate *aggregate = new Aggregation::Aggregate; - BinEditorFind *binEditorFind = new BinEditorFind(editor); + BinEditorFind *binEditorFind = new BinEditorFind(widget); aggregate->add(binEditorFind); - aggregate->add(editor); + aggregate->add(widget); } bool BinEditorPlugin::initialize(const QStringList &arguments, QString *errorMessage) @@ -515,9 +517,9 @@ void BinEditorPlugin::extensionsInitialized() void BinEditorPlugin::updateCurrentEditor(Core::IEditor *editor) { - BinEditor *binEditor = 0; + BinEditorWidget *binEditor = 0; if (editor) - binEditor = qobject_cast(editor->widget()); + binEditor = qobject_cast(editor->widget()); if (m_currentEditor == binEditor) return; m_currentEditor = binEditor; diff --git a/src/plugins/bineditor/bineditorplugin.h b/src/plugins/bineditor/bineditorplugin.h index 7c383d2ff75..0adf0f62b43 100644 --- a/src/plugins/bineditor/bineditorplugin.h +++ b/src/plugins/bineditor/bineditorplugin.h @@ -40,7 +40,7 @@ #include namespace BINEditor { -class BinEditor; +class BinEditorWidget; class BinEditorWidgetFactory : public QObject { @@ -67,7 +67,7 @@ public: void extensionsInitialized(); // Connect editor to settings changed signals. - void initializeEditor(BinEditor *editor); + void initializeEditor(BinEditorWidget *editor); private slots: void undoAction(); @@ -92,7 +92,7 @@ private: Core::IEditor *createEditor(QWidget *parent); BinEditorFactory *m_factory; - QPointer m_currentEditor; + QPointer m_currentEditor; }; class BinEditorFactory : public Core::IEditorFactory From 0b724400aa07249a844d40821d85acd89f2709df Mon Sep 17 00:00:00 2001 From: Sergey Shambir Date: Sun, 26 May 2013 18:15:24 +0400 Subject: [PATCH 14/37] CppTools: fixed wrong flags check. Change-Id: I682e78c352066ddd05e96199fd8ead088e3e9f52 Reviewed-by: Erik Verbruggen --- src/plugins/cpptools/cppmodelmanagerinterface.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.cpp b/src/plugins/cpptools/cppmodelmanagerinterface.cpp index 0de4f6e425a..c6b535d98d9 100644 --- a/src/plugins/cpptools/cppmodelmanagerinterface.cpp +++ b/src/plugins/cpptools/cppmodelmanagerinterface.cpp @@ -79,25 +79,25 @@ void ProjectPart::evaluateToolchain(const ToolChain *tc, ToolChain::CompilerFlags c = (cxxflags == cflags) ? cxx : tc->compilerFlags(cflags); - if (c | ToolChain::StandardC11) + if (c & ToolChain::StandardC11) cVersion = C11; - else if (c | ToolChain::StandardC99) + else if (c & ToolChain::StandardC99) cVersion = C99; else cVersion = C89; - if (cxx | ToolChain::StandardCxx11) + if (cxx & ToolChain::StandardCxx11) cxxVersion = CXX11; else cxxVersion = CXX98; - if (cxx | ToolChain::BorlandExtensions) + if (cxx & ToolChain::BorlandExtensions) cxxExtensions |= BorlandExtensions; - if (cxx | ToolChain::GnuExtensions) + if (cxx & ToolChain::GnuExtensions) cxxExtensions |= GnuExtensions; - if (cxx | ToolChain::MicrosoftExtensions) + if (cxx & ToolChain::MicrosoftExtensions) cxxExtensions |= MicrosoftExtensions; - if (cxx | ToolChain::OpenMP) + if (cxx & ToolChain::OpenMP) cxxExtensions |= OpenMP; cWarningFlags = tc->warningFlags(cflags); From 2485b7618384d9271fd1ff65954ab01c8c1eb536 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 29 May 2013 14:56:18 +0200 Subject: [PATCH 15/37] SVN: Always use internal diff command This unbreaks svn diff views for users with custom diff commands set up in their subversion configuration. Task-number: QTCREATORBUG-9303 Change-Id: Ie3a726f08ad39770b63e2432755467df429067f8 Reviewed-by: Tobias Hunger --- src/plugins/subversion/subversionplugin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index 047210732b0..1565adf1280 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -572,6 +572,7 @@ void SubversionPlugin::svnDiff(const Subversion::Internal::SubversionDiffParamet QFileInfo(p.files.front()).fileName() : p.diffName; QStringList args(QLatin1String("diff")); + args.append(QLatin1String("--internal-diff")); args.append(p.arguments); args << p.files; From 56477d86ce12a5bf4b49674de032c2b18ce67162 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 28 May 2013 12:25:25 +0200 Subject: [PATCH 16/37] Debugger: Adjust wording of symbol server dialog. Change-Id: I7bbfbe2a95ddb6bcfa8fcb3aca8fc9a602c20bea Reviewed-by: Robert Loehning Reviewed-by: David Schulz --- src/plugins/debugger/shared/symbolpathsdialog.ui | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/plugins/debugger/shared/symbolpathsdialog.ui b/src/plugins/debugger/shared/symbolpathsdialog.ui index 4059bb31acd..c74d985f2d6 100644 --- a/src/plugins/debugger/shared/symbolpathsdialog.ui +++ b/src/plugins/debugger/shared/symbolpathsdialog.ui @@ -44,11 +44,7 @@ - <html><head/><body> -<p>The debugger is not configured to use the public Microsoft Symbol Server.<br>This is recommended for retrieval of the symbols of the operating system libraries.</p> -<p><span style=" font-style:italic;">Note:</span> It is recommended, that if you use the Microsoft Symbol Server, to also use a local symbol cache.<br>Also, a fast internet connection is required for this to work smoothly,<br>and a delay might occur when connecting for the first time, when caching the symbols for the first time.</p> -<p>Would you like to set it up?</p> -</body></html> + <html><head/><body><p>The debugger is not configured to use the public Microsoft Symbol Server.<br/>This is recommended for retrieval of the symbols of the operating system libraries.</p><p><span style=" font-style:italic;">Note:</span> It is recommended, that if you use the Microsoft Symbol Server, to also use a local symbol cache.<br/>A fast internet connection is required for this to work smoothly,<br/>and a delay might occur when connecting for the first time and caching the symbols.</p><p>What would you like to set up?</p></body></html> Qt::RichText From e2591965938b83aa8c27daf090a2b2a2f746df57 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Tue, 28 May 2013 13:43:05 +0200 Subject: [PATCH 17/37] Squish: Update handleDebuggerWarnings() Change-Id: Ifd0a9270f84abe15603cbf80ef18eb7450436c74 Reviewed-by: David Schulz --- tests/system/shared/debugger.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/system/shared/debugger.py b/tests/system/shared/debugger.py index 29b79c77618..849fab459dd 100644 --- a/tests/system/shared/debugger.py +++ b/tests/system/shared/debugger.py @@ -33,14 +33,14 @@ def handleDebuggerWarnings(config, isMsvcBuild=False): if isMsvcBuild: try: popup = waitForObject("{name='msgLabel' text?='*' type='QLabel' visible='1' window=':Dialog_Debugger::Internal::SymbolPathsDialog'}", 10000) - symServerNotConfiged = ("\n

The debugger is not configured to use the public " - "Microsoft Symbol Server.
" - "This is recommended for retrieval of the symbols of the operating system libraries.

\n" - "

Note: It is recommended, that if you use the Microsoft Symbol Server, " - "to also use a local symbol cache.
" - "Also, a fast internet connection is required for this to work smoothly,
" - "and a delay might occur when connecting for the first time, when caching the symbols for the first time.

\n" - "

Would you like to set it up?

\n") + symServerNotConfiged = ("

The debugger is not configured to use the public " + "Microsoft Symbol Server.
" + "This is recommended for retrieval of the symbols of the operating system libraries.

" + "

Note: It is recommended, that if you use the Microsoft Symbol Server, " + "to also use a local symbol cache.
" + "A fast internet connection is required for this to work smoothly,
" + "and a delay might occur when connecting for the first time and caching the symbols.

" + "

What would you like to set up?

") if popup.text == symServerNotConfiged: test.log("Creator warned about the debugger not being configured to use the public Microsoft Symbol Server.") else: From 0f51591ce5d5006a9381e1785a2c4d93db5a1815 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 29 May 2013 15:07:12 +0300 Subject: [PATCH 18/37] Fix getBundleInformation call. getBundleInformation must be called synchronously Change-Id: Iebe00295e1ef0679fdd6f9b849672d72f5ea998a Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Daniel Teske --- src/plugins/android/androidpackagecreationstep.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/android/androidpackagecreationstep.cpp b/src/plugins/android/androidpackagecreationstep.cpp index ac0e50b2925..76b29b402a3 100644 --- a/src/plugins/android/androidpackagecreationstep.cpp +++ b/src/plugins/android/androidpackagecreationstep.cpp @@ -346,7 +346,7 @@ void AndroidPackageCreationStep::checkRequiredLibrariesForRun() QMetaObject::invokeMethod(this, "setQtLibs",Qt::BlockingQueuedConnection, Q_ARG(QStringList, m_qtLibsWithDependencies)); - QMetaObject::invokeMethod(this, "getBundleInformation"); + QMetaObject::invokeMethod(this, "getBundleInformation", Qt::BlockingQueuedConnection); QStringList prebundledLibraries; foreach (const AndroidManager::Library &qtLib, m_availableQtLibs) { From d7f96e3201ed8c2fd769caf7f6d6937a970c628e Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Wed, 22 May 2013 17:24:15 +0200 Subject: [PATCH 19/37] Android Deploy Options: Clean up ui Task-number: QTCREATORBUG-9208 Change-Id: I1b1864908a24af3cd7c576831656267a6390b583 Reviewed-by: BogDan Vatra --- src/plugins/android/androiddeploystep.cpp | 69 +++--- src/plugins/android/androiddeploystep.h | 13 +- .../android/androiddeploystepwidget.cpp | 35 +-- src/plugins/android/androiddeploystepwidget.h | 5 +- .../android/androiddeploystepwidget.ui | 206 +++++++----------- src/plugins/android/androidmanager.cpp | 10 +- .../android/androidpackagecreationwidget.cpp | 6 +- src/plugins/android/androidrunner.cpp | 4 +- 8 files changed, 152 insertions(+), 196 deletions(-) diff --git a/src/plugins/android/androiddeploystep.cpp b/src/plugins/android/androiddeploystep.cpp index 222da0e35c3..c11ced5f1e4 100644 --- a/src/plugins/android/androiddeploystep.cpp +++ b/src/plugins/android/androiddeploystep.cpp @@ -83,10 +83,9 @@ void AndroidDeployStep::ctor() setDefaultDisplayName(tr("Deploy to Android device")); m_deployAction = NoDeploy; - m_useLocalQtLibs = false; if (QtSupport::BaseQtVersion *qt = QtSupport::QtKitInformation::qtVersion(target()->kit())) if (qt->qtVersion() >= QtSupport::QtVersionNumber(5, 0, 0)) - m_useLocalQtLibs = true; + m_deployAction = BundleLibraries; } bool AndroidDeployStep::init() @@ -118,7 +117,6 @@ bool AndroidDeployStep::init() m_apkPathDebug = AndroidManager::apkPath(target(), AndroidManager::DebugBuild).toString(); m_apkPathRelease = AndroidManager::apkPath(target(), AndroidManager::ReleaseBuildSigned).toString(); m_buildDirectory = static_cast(target()->project())->rootQt4ProjectNode()->buildDir(); - m_runQASIPackagePath = m_QASIPackagePath; m_runDeployAction = m_deployAction; ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit()); if (!tc || tc->type() != QLatin1String(Constants::ANDROID_TOOLCHAIN_TYPE)) { @@ -148,15 +146,15 @@ AndroidDeployStep::AndroidDeployAction AndroidDeployStep::deployAction() return m_deployAction; } -bool AndroidDeployStep::useLocalQtLibs() -{ - return m_useLocalQtLibs; -} - bool AndroidDeployStep::fromMap(const QVariantMap &map) { - m_useLocalQtLibs = map.value(QLatin1String(USE_LOCAL_QT_KEY), false).toBool(); m_deployAction = AndroidDeployAction(map.value(QLatin1String(DEPLOY_ACTION_KEY), NoDeploy).toInt()); + QVariant useLocalQt = map.value(QLatin1String(USE_LOCAL_QT_KEY)); + if (useLocalQt.isValid()) { // old settings + if (useLocalQt.toBool() && m_deployAction == NoDeploy) + m_deployAction = BundleLibraries; + } + if (m_deployAction == InstallQASI) m_deployAction = NoDeploy; return ProjectExplorer::BuildStep::fromMap(map); @@ -165,7 +163,6 @@ bool AndroidDeployStep::fromMap(const QVariantMap &map) QVariantMap AndroidDeployStep::toMap() const { QVariantMap map = ProjectExplorer::BuildStep::toMap(); - map.insert(QLatin1String(USE_LOCAL_QT_KEY), m_useLocalQtLibs); map.insert(QLatin1String(DEPLOY_ACTION_KEY), m_deployAction); return map; } @@ -184,7 +181,7 @@ void AndroidDeployStep::cleanLibsOnDevice() QProcess *process = new QProcess(this); QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber); arguments << QLatin1String("shell") << QLatin1String("rm") << QLatin1String("-r") << QLatin1String("/data/local/tmp/qt"); - connect(process, SIGNAL(finished(int)), this, SLOT(cleanLibsFinished())); + connect(process, SIGNAL(finished(int)), this, SLOT(processFinished())); const QString adb = AndroidConfigurations::instance().adbToolPath().toString(); Core::MessageManager::instance()->printToOutputPane(adb + QLatin1String(" ") + arguments.join(QLatin1String(" ")), @@ -194,7 +191,7 @@ void AndroidDeployStep::cleanLibsOnDevice() delete process; } -void AndroidDeployStep::cleanLibsFinished() +void AndroidDeployStep::processFinished() { QProcess *process = qobject_cast(sender()); QTC_ASSERT(process, return); @@ -204,6 +201,31 @@ void AndroidDeployStep::cleanLibsFinished() process->deleteLater(); } +void AndroidDeployStep::installQASIPackage(const QString &packagePath) +{ + const QString targetArch = AndroidManager::targetArch(target()); + const QString targetSDK = AndroidManager::targetSDK(target()); + int deviceAPILevel = targetSDK.mid(targetSDK.indexOf(QLatin1Char('-')) + 1).toInt(); + QString deviceSerialNumber = AndroidConfigurations::instance().getDeployDeviceSerialNumber(&deviceAPILevel, targetArch); + if (!deviceSerialNumber.length()) { + Core::MessageManager::instance()->printToOutputPane(tr("Could not run adb. No device found."), Core::MessageManager::NoModeSwitch); + return; + } + + QProcess *process = new QProcess(this); + QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber); + arguments << QLatin1String("install") << QLatin1String("-r ") << packagePath; + + connect(process, SIGNAL(finished(int)), this, SLOT(processFinished())); + const QString adb = AndroidConfigurations::instance().adbToolPath().toString(); + Core::MessageManager::instance()->printToOutputPane(adb + QLatin1String(" ") + + arguments.join(QLatin1String(" ")), + Core::MessageManager::NoModeSwitch); + process->start(adb, arguments); + if (!process->waitForFinished(500)) + delete process; +} + void AndroidDeployStep::setDeployAction(AndroidDeployStep::AndroidDeployAction deploy) { m_deployAction = deploy; @@ -211,18 +233,6 @@ void AndroidDeployStep::setDeployAction(AndroidDeployStep::AndroidDeployAction d AndroidManager::updateDeploymentSettings(target()); } -void AndroidDeployStep::setDeployQASIPackagePath(const QString &package) -{ - m_QASIPackagePath = package; - setDeployAction(InstallQASI); -} - -void AndroidDeployStep::setUseLocalQtLibs(bool useLocal) -{ - m_useLocalQtLibs = useLocal; - AndroidManager::updateDeploymentSettings(target()); -} - bool AndroidDeployStep::runCommand(QProcess *buildProc, const QString &program, const QStringList &arguments) { @@ -453,17 +463,6 @@ bool AndroidDeployStep::deployPackage() AndroidPackageCreationStep::removeDirectory(tempPath); } - if (m_runDeployAction == InstallQASI) { - if (!runCommand(deployProc, AndroidConfigurations::instance().adbToolPath().toString(), - AndroidDeviceInfo::adbSelector(m_deviceSerialNumber) - << QLatin1String("install") << QLatin1String("-r ") << m_runQASIPackagePath)) { - raiseError(tr("Qt Android smart installer installation failed")); - disconnect(deployProc, 0, this, 0); - deployProc->deleteLater(); - return false; - } - emit resetDelopyAction(); - } deployProc->setWorkingDirectory(m_androidDirPath.toString()); writeOutput(tr("Installing package onto %1.").arg(m_deviceSerialNumber)); diff --git a/src/plugins/android/androiddeploystep.h b/src/plugins/android/androiddeploystep.h index 0fa090aa54a..ad922c46e1d 100644 --- a/src/plugins/android/androiddeploystep.h +++ b/src/plugins/android/androiddeploystep.h @@ -75,9 +75,10 @@ class AndroidDeployStep : public ProjectExplorer::BuildStep public: enum AndroidDeployAction { - NoDeploy, + NoDeploy, // use ministro DeployLocal, - InstallQASI + InstallQASI, // unused old value + BundleLibraries }; public: @@ -89,28 +90,25 @@ public: int deviceAPILevel(); AndroidDeployAction deployAction(); - bool useLocalQtLibs(); bool fromMap(const QVariantMap &map); QVariantMap toMap() const; void cleanLibsOnDevice(); + void installQASIPackage(const QString &packagePath); public slots: void setDeployAction(AndroidDeployAction deploy); - void setDeployQASIPackagePath(const QString &package); - void setUseLocalQtLibs(bool useLocal); signals: void done(); void error(); - void resetDelopyAction(); private slots: bool deployPackage(); void handleBuildOutput(); void handleBuildError(); - void cleanLibsFinished(); + void processFinished(); private: AndroidDeployStep(ProjectExplorer::BuildStepList *bc, @@ -140,7 +138,6 @@ private: QString m_QASIPackagePath; AndroidDeployAction m_deployAction; - bool m_useLocalQtLibs; // members to transfer data from init() to run QString m_packageName; diff --git a/src/plugins/android/androiddeploystepwidget.cpp b/src/plugins/android/androiddeploystepwidget.cpp index 45a8373b742..482051342cd 100644 --- a/src/plugins/android/androiddeploystepwidget.cpp +++ b/src/plugins/android/androiddeploystepwidget.cpp @@ -47,21 +47,26 @@ AndroidDeployStepWidget::AndroidDeployStepWidget(AndroidDeployStep *step) : { ui->setupUi(this); - ui->useLocalQtLibs->setChecked(m_step->useLocalQtLibs()); switch (m_step->deployAction()) { + case AndroidDeployStep::NoDeploy: + ui->ministroOption->setChecked(true); + break; case AndroidDeployStep::DeployLocal: - ui->deployQtLibs->setChecked(true); + ui->temporaryQtOption->setChecked(true); + break; + case AndroidDeployStep::BundleLibraries: + ui->bundleQtOption->setChecked(true); break; default: - ui->devicesQtLibs->setChecked(true); + ui->ministroOption->setChecked(true); break; } - connect(m_step, SIGNAL(resetDelopyAction()), SLOT(resetAction())); - connect(ui->devicesQtLibs, SIGNAL(clicked()), SLOT(resetAction())); - connect(ui->deployQtLibs, SIGNAL(clicked()), SLOT(setDeployLocalQtLibs())); + connect(ui->ministroOption, SIGNAL(clicked()), SLOT(setMinistro())); + connect(ui->temporaryQtOption, SIGNAL(clicked()), SLOT(setDeployLocalQtLibs())); + connect(ui->bundleQtOption, SIGNAL(clicked()), SLOT(setBundleQtLibs())); + connect(ui->chooseButton, SIGNAL(clicked()), SLOT(setQASIPackagePath())); - connect(ui->useLocalQtLibs, SIGNAL(stateChanged(int)), SLOT(useLocalQtLibsStateChanged(int))); connect(ui->cleanLibsPushButton, SIGNAL(clicked()), SLOT(cleanLibsOnDevice())); } @@ -80,9 +85,8 @@ QString AndroidDeployStepWidget::summaryText() const return displayName(); } -void AndroidDeployStepWidget::resetAction() +void AndroidDeployStepWidget::setMinistro() { - ui->devicesQtLibs->setChecked(true); m_step->setDeployAction(AndroidDeployStep::NoDeploy); } @@ -91,19 +95,20 @@ void AndroidDeployStepWidget::setDeployLocalQtLibs() m_step->setDeployAction(AndroidDeployStep::DeployLocal); } +void AndroidDeployStepWidget::setBundleQtLibs() +{ + m_step->setDeployAction(AndroidDeployStep::BundleLibraries); +} + void AndroidDeployStepWidget::setQASIPackagePath() { QString packagePath = QFileDialog::getOpenFileName(this, tr("Qt Android Smart Installer"), QDir::homePath(), tr("Android package (*.apk)")); - if (packagePath.length()) - m_step->setDeployQASIPackagePath(packagePath); + if (!packagePath.isEmpty()) + m_step->installQASIPackage(packagePath); } -void AndroidDeployStepWidget::useLocalQtLibsStateChanged(int state) -{ - m_step->setUseLocalQtLibs(state == Qt::Checked); -} void AndroidDeployStepWidget::cleanLibsOnDevice() { diff --git a/src/plugins/android/androiddeploystepwidget.h b/src/plugins/android/androiddeploystepwidget.h index 90db7d43420..8c05d0aa629 100644 --- a/src/plugins/android/androiddeploystepwidget.h +++ b/src/plugins/android/androiddeploystepwidget.h @@ -49,10 +49,11 @@ public: ~AndroidDeployStepWidget(); private slots: - void resetAction(); + void setMinistro(); void setDeployLocalQtLibs(); + void setBundleQtLibs(); + void setQASIPackagePath(); - void useLocalQtLibsStateChanged(int); void cleanLibsOnDevice(); private: diff --git a/src/plugins/android/androiddeploystepwidget.ui b/src/plugins/android/androiddeploystepwidget.ui index 4458c494081..96ed9eb5330 100644 --- a/src/plugins/android/androiddeploystepwidget.ui +++ b/src/plugins/android/androiddeploystepwidget.ui @@ -6,8 +6,8 @@ 0 0 - 560 - 145 + 678 + 155
@@ -19,138 +19,88 @@ Form - - - - - Use Qt libraries from device - - - Use Qt libraries from device - - - true + + + + + Qt Deployment + + + + + Use the external Ministro application to download and maintain Qt libraries. + + + Use Ministro service to install Qt + + + true + + + + + + + Push local Qt libraries to device. You must have Qt libraries compiled for that platform. +The APK will not be usable on any other device. + + + Deploy local Qt libraries to temporary directory + + + + + + + Creates a standalone APK. + + + Bundle Qt libraries in APK + + + + - - - - - - Push local Qt libraries to device. -You must have Qt libraries compiled for that platform - - - Deploy local Qt libraries - - - - - - - Check this option to force the application to use local Qt libraries instead of system libraries. - - - Use local Qt libraries - - - - - - - Clean Libs on Device - - - - - - - - - - - Choose and install Ministro system wide Qt shared libraries. -This option is useful when you want to try your application on devices which don't have Android Market (e.g. Android Emulator). - - - Install Ministro, system-wide Qt shared libraries installer - - - - - - - false - - - Choose APK - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical + + + + Advanced Actions - - - 20 - 41 - - - + + + + + Clean Temporary Libraries Directory on Device + + + + + + + Install Ministro from APK + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + - - - installQASI - toggled(bool) - chooseButton - setEnabled(bool) - - - 119 - 68 - - - 272 - 64 - - - - - deployQtLibs - clicked(bool) - useLocalQtLibs - setChecked(bool) - - - 138 - 43 - - - 343 - 44 - - - - + diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index c712a0b06de..b17e044b80b 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -319,8 +319,7 @@ bool AndroidManager::bundleQt(ProjectExplorer::Target *target) AndroidRunConfiguration *androidRunConfiguration = qobject_cast(runConfiguration); if (androidRunConfiguration != 0) { AndroidDeployStep *deployStep = androidRunConfiguration->deployStep(); - return deployStep->deployAction() == AndroidDeployStep::NoDeploy - && deployStep->useLocalQtLibs(); + return deployStep->deployAction() == AndroidDeployStep::BundleLibraries; } return false; @@ -340,9 +339,10 @@ bool AndroidManager::updateDeploymentSettings(ProjectExplorer::Target *target) return false; AndroidDeployStep *deployStep = androidRunConfiguration->deployStep(); - bool useLocalLibs = deployStep->useLocalQtLibs(); - bool deployQtLibs = deployStep->deployAction() != AndroidDeployStep::NoDeploy; - bool bundleQtLibs = useLocalLibs && !deployQtLibs; + AndroidDeployStep::AndroidDeployAction deployAction = deployStep->deployAction(); + bool useLocalLibs = deployAction == AndroidDeployStep::DeployLocal + || deployAction == AndroidDeployStep::BundleLibraries; + bool bundleQtLibs = deployAction == AndroidDeployStep::BundleLibraries; QDomDocument doc; if (!openManifest(target, doc)) diff --git a/src/plugins/android/androidpackagecreationwidget.cpp b/src/plugins/android/androidpackagecreationwidget.cpp index ac667ee1660..5bb28769559 100644 --- a/src/plugins/android/androidpackagecreationwidget.cpp +++ b/src/plugins/android/androidpackagecreationwidget.cpp @@ -234,7 +234,8 @@ void AndroidPackageCreationWidget::setQtLibs(QModelIndex, QModelIndex) { AndroidManager::setQtLibs(m_step->target(), m_qtLibsModel->checkedItems()); AndroidDeployStep * const deployStep = AndroidGlobal::buildStep(m_step->target()->activeDeployConfiguration()); - if (deployStep->useLocalQtLibs()) + if (deployStep->deployAction() == AndroidDeployStep::DeployLocal + || deployStep->deployAction() == AndroidDeployStep::BundleLibraries) AndroidManager::updateDeploymentSettings(m_step->target()); } @@ -242,7 +243,8 @@ void AndroidPackageCreationWidget::setPrebundledLibs(QModelIndex, QModelIndex) { AndroidManager::setPrebundledLibs(m_step->target(), m_prebundledLibs->checkedItems()); AndroidDeployStep * const deployStep = AndroidGlobal::buildStep(m_step->target()->activeDeployConfiguration()); - if (deployStep->useLocalQtLibs()) + if (deployStep->deployAction() == AndroidDeployStep::DeployLocal + || deployStep->deployAction() == AndroidDeployStep::BundleLibraries) AndroidManager::updateDeploymentSettings(m_step->target()); } diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp index 471c380f3bc..a005e10fde6 100644 --- a/src/plugins/android/androidrunner.cpp +++ b/src/plugins/android/androidrunner.cpp @@ -74,7 +74,9 @@ AndroidRunner::AndroidRunner(QObject *parent, } ProjectExplorer::Target *target = runConfig->target(); AndroidDeployStep *ds = runConfig->deployStep(); - if ((m_useLocalQtLibs = ds->useLocalQtLibs())) { + m_useLocalQtLibs = ds->deployAction() == AndroidDeployStep::DeployLocal + || ds->deployAction() == AndroidDeployStep::BundleLibraries; + if (m_useLocalQtLibs) { m_localLibs = AndroidManager::loadLocalLibs(target, ds->deviceAPILevel()); m_localJars = AndroidManager::loadLocalJars(target, ds->deviceAPILevel()); m_localJarsInitClasses = AndroidManager::loadLocalJarsInitClasses(target, ds->deviceAPILevel()); From cc611e076f1a7901be2cc8ebae877d7aa4730294 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 29 May 2013 14:54:47 +0200 Subject: [PATCH 20/37] Debugger: Pass autoderef pointers down to LLDB machinery Change-Id: I282e78c352066ddd05e96199fd8ead088e3e9f56 Reviewed-by: hjk --- share/qtcreator/dumper/lbridge.py | 1 + src/plugins/debugger/lldb/lldbengine.cpp | 25 +++++++++++++++++++----- src/plugins/debugger/lldb/lldbengine.h | 4 ++-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/share/qtcreator/dumper/lbridge.py b/share/qtcreator/dumper/lbridge.py index 609504316c8..4c33702b2de 100644 --- a/share/qtcreator/dumper/lbridge.py +++ b/share/qtcreator/dumper/lbridge.py @@ -504,6 +504,7 @@ class Dumper: self.useLldbDumpers = False self.ns = "" self.autoDerefPointers = True + self.useDynamicType = True self.useLoop = True self.currentIName = None diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 4af3b763802..1680a182962 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -84,6 +84,17 @@ LldbEngine::LldbEngine(const DebuggerStartParameters &startParameters) m_lastAgentId = 0; m_lastToken = 0; setObjectName(QLatin1String("LldbEngine")); + + connect(debuggerCore()->action(AutoDerefPointers), SIGNAL(valueChanged(QVariant)), + SLOT(updateLocals())); + connect(debuggerCore()->action(CreateFullBacktrace), SIGNAL(triggered()), + SLOT(updateAll())); + connect(debuggerCore()->action(UseDebuggingHelpers), SIGNAL(valueChanged(QVariant)), + SLOT(updateLocals())); + connect(debuggerCore()->action(UseDynamicType), SIGNAL(valueChanged(QVariant)), + SLOT(updateLocals())); + connect(debuggerCore()->action(IntelFlavor), SIGNAL(valueChanged(QVariant)), + SLOT(updateAll())); } LldbEngine::~LldbEngine() @@ -654,6 +665,10 @@ bool LldbEngine::setToolTipExpression(const QPoint &mousePos, return false; } +void LldbEngine::updateAll() +{ + updateLocals(); +} ////////////////////////////////////////////////////////////////////// // @@ -677,6 +692,11 @@ void LldbEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags & { Q_UNUSED(data); Q_UNUSED(flags); + updateLocals(); +} + +void LldbEngine::updateLocals() +{ WatchHandler *handler = watchHandler(); Command cmd("updateData"); @@ -873,11 +893,6 @@ QByteArray LldbEngine::currentOptions() const return result; } -void LldbEngine::updateAll() -{ - runCommand("reportData"); -} - void LldbEngine::refreshLocals(const GdbMi &vars) { //const bool partial = response.cookie.toBool(); diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index 82c58ea46d6..fe44c1940ad 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -153,6 +153,8 @@ private: Q_SLOT void readLldbStandardError(); Q_SLOT void handleResponse(const QByteArray &data); Q_SLOT void runEngine2(); + Q_SLOT void updateAll(); + Q_SLOT void updateLocals(); void refreshAll(const GdbMi &all); void refreshThreads(const GdbMi &threads); void refreshStack(const GdbMi &stack); @@ -167,8 +169,6 @@ private: void refreshBreakpoints(const GdbMi &bkpts); void runContinuation(const GdbMi &data); - void updateAll(); - typedef void (LldbEngine::*LldbCommandContinuation)(); QByteArray currentOptions() const; From 31634a07f435cf69a56b6d7a4002108df7027d6f Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 29 May 2013 14:55:57 +0200 Subject: [PATCH 21/37] Debugger: Cleanup LLDB python startup code Change-Id: I682e78c352066ddd05e96199fd8ead088e3e9f55 Reviewed-by: hjk --- share/qtcreator/dumper/lbridge.py | 84 +++++++++++-------------------- 1 file changed, 30 insertions(+), 54 deletions(-) diff --git a/share/qtcreator/dumper/lbridge.py b/share/qtcreator/dumper/lbridge.py index 4c33702b2de..452d9d44161 100644 --- a/share/qtcreator/dumper/lbridge.py +++ b/share/qtcreator/dumper/lbridge.py @@ -689,63 +689,34 @@ class Dumper: self.executable_ = executable error = lldb.SBError() self.target = self.debugger.CreateTarget(executable, None, None, True, error) + self.listener = self.target.GetDebugger().GetListener() + self.process = self.target.Launch(self.listener, None, None, + None, None, None, + None, 0, True, error) + self.broadcaster = self.process.GetBroadcaster() + rc = self.broadcaster.AddListener(self.listener, 15) + if rc != 15: + warn("ADDING LISTENER FAILED: %s" % rc) + + self.importDumpers() + if self.target.IsValid(): self.report('state="inferiorsetupok",msg="%s",exe="%s"' % (error, executable)) else: self.report('state="inferiorsetupfailed",msg="%s",exe="%s"' % (error, executable)) - self.importDumpers() - if False: - self.process = self.target.LaunchSimple(None, None, os.getcwd()) - self.broadcaster = self.process.GetBroadcaster() - self.listener = lldb.SBListener('my listener') - rc = self.broadcaster.AddListener(self.listener, 15) - warn("ADD LISTENER: %s" % rc) - if True: - self.listener = self.target.GetDebugger().GetListener() - self.process = self.target.Launch(self.listener, None, None, - None, None, None, - None, 0, True, error) - self.broadcaster = self.process.GetBroadcaster() - rc = self.broadcaster.AddListener(self.listener, 15) - warn("ADD LISTENER: %s" % rc) - #self.process = self.target.Launch(self.listener, None, None, - # None, None, None, - # os.getcwd(), - # lldb.eLaunchFlagExec - # + lldb.eLaunchFlagDebug - # #+ lldb.eLaunchFlagDebug - # #+ lldb.eLaunchFlagStopAtEntry - # #+ lldb.eLaunchFlagDisableSTDIO - # #+ lldb.eLaunchFlagLaunchInSeparateProcessGroup - # , False, error) - #self.reportError(error) - warn("STATE AFTER LAUNCH: %s" % self.process.GetState()) warn("STATE AFTER LAUNCH: %s" % stateNames[self.process.GetState()]) def runEngine(self, _): error = lldb.SBError() - #launchInfo = lldb.SBLaunchInfo(["-s"]) - #self.process = self.target.Launch(self.listener, None, None, - # None, None, None, - # None, 0, True, error) - #self.listener = lldb.SBListener("event_Listener") - #self.process = self.target.Launch(self.listener, None, None, - # None, None, None, - # os.getcwd(), - # lldb.eLaunchFlagExec - # + lldb.eLaunchFlagDebug - # #+ lldb.eLaunchFlagDebug - # #+ lldb.eLaunchFlagStopAtEntry - # #+ lldb.eLaunchFlagDisableSTDIO - # #+ lldb.eLaunchFlagLaunchInSeparateProcessGroup - # , False, error) self.pid = self.process.GetProcessID() self.report('pid="%s"' % self.pid) - self.report('state="enginerunandinferiorstopok"') + self.consumeEvents() error = self.process.Continue() - #self.reportError(error) - #self.report('state="enginerunandinferiorstopok"') + self.consumeEvents() + self.reportError(error) + + self.report('state="enginerunandinferiorrunok"') if self.useLoop: s = threading.Thread(target=self.loop, args=[]) @@ -1271,6 +1242,10 @@ class Dumper: def updateData(self, args): self.expandedINames = set(args['expanded'].split(',')) + self.autoDerefPointers = int(args['autoderef']) + self.useDynamicType = int(args['dyntype']) + # Keep always True for now. + #self.passExceptions = args['pe'] self.reportData() def disassemble(self, args): @@ -1328,6 +1303,13 @@ class Dumper: cont = args['continuation'] self.report('continuation="%s"' % cont) + def consumeEvents(self): + event = lldb.SBEvent() + if self.listener and self.listener.PeekAtNextEvent(event): + self.listener.GetNextEvent(event) + self.handleEvent(event) + + currentDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) execfile(os.path.join(currentDir, "qttypes.py")) @@ -1339,21 +1321,15 @@ def doit1(): db.report('state="enginesetupok"') while True: - readable, _, _ = select.select([sys.stdin], [], [], 0.1) - event = lldb.SBEvent() - if db.listener and db.listener.PeekAtNextEvent(event): - db.listener.GetNextEvent(event) - db.handleEvent(event) + db.consumeEvents() + readable, _, _ = select.select([sys.stdin], [], [], 0.1) if sys.stdin in readable: line = raw_input() if line.startswith("db "): db.execute(eval(line[3:])) - event = lldb.SBEvent() - if db.listener and db.listener.PeekAtNextEvent(event): - db.listener.GetNextEvent(event) - db.handleEvent(event) + db.consumeEvents() def doit2(): From b75209d653ffc9906b2e2b90e0ca63a809755b3a Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 29 May 2013 15:38:49 +0200 Subject: [PATCH 22/37] Debugger: Cleaner shutdown of LLDB/python machinery Change-Id: I482e78c352066ddd05e96199fd8ead088e3e9f58 Reviewed-by: hjk --- share/qtcreator/dumper/lbridge.py | 23 ++++++++++++++--------- src/plugins/debugger/lldb/lldbengine.cpp | 10 +++++++++- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/share/qtcreator/dumper/lbridge.py b/share/qtcreator/dumper/lbridge.py index 452d9d44161..bb2f8bb84b1 100644 --- a/share/qtcreator/dumper/lbridge.py +++ b/share/qtcreator/dumper/lbridge.py @@ -525,6 +525,7 @@ class Dumper: self.sizetType_ = None self.charPtrType_ = None self.voidType_ = None + self.isShuttingDown_ = False def extractTemplateArgument(self, typename, index): level = 0 @@ -1020,9 +1021,12 @@ class Dumper: self.report('state="%s"' % stateNames[state]) self.eventState = state if state == lldb.eStateExited: - warn("PROCESS EXITED. %d: %s" + if self.isShuttingDown_: + self.report('state="inferiorshutdownok"') + else: + self.report('state="inferiorexited"') + self.report('exited={status="%s",desc="%s"}' % (self.process.GetExitStatus(), self.process.GetExitDescription())) - self.report('state="inferiorexited"') if type == lldb.SBProcess.eBroadcastBitStateChanged: self.reportData() elif type == lldb.SBProcess.eBroadcastBitInterrupt: @@ -1190,8 +1194,13 @@ class Dumper: def executeStep(self, _ = None): self.currentThread().StepInto() + def shutdownInferior(self, _ = None): + self.isShuttingDown_ = True + self.process.Kill() + def quit(self, _ = None): - self.debugger.Terminate() + self.report('state="engineshutdownok"') + self.process.Kill() def executeStepI(self, _ = None): self.currentThread().StepInstruction(lldb.eOnlyThisThread) @@ -1229,12 +1238,8 @@ class Dumper: command = args['command'] self.debugger.GetCommandInterpreter().HandleCommand(command, result) success = result.Succeeded() - if success: - output = result.GetOutput() - error = '' - else: - output = '' - error = str(result.GetError()) + output = result.GetOutput() + error = str(result.GetError()) self.report('success="%d",output="%s",error="%s"' % (success, output, error)) def setOptions(self, args): diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 1680a182962..5f0397b80a1 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -119,7 +119,7 @@ void LldbEngine::runCommand(const Command &command) void LldbEngine::shutdownInferior() { QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()); - notifyInferiorShutdownOk(); + runCommand(Command("shutdownInferior")); } void LldbEngine::shutdownEngine() @@ -1018,6 +1018,14 @@ void LldbEngine::refreshState(const GdbMi &reportedState) notifyEngineRunAndInferiorRunOk(); else if (newState == "enginerunandinferiorstopok") notifyEngineRunAndInferiorStopOk(); + else if (newState == "inferiorshutdownok") + notifyInferiorShutdownOk(); + else if (newState == "inferiorshutdownfailed") + notifyInferiorShutdownFailed(); + else if (newState == "engineshutdownok") + notifyEngineShutdownOk(); + else if (newState == "engineshutdownfailed") + notifyEngineShutdownFailed(); else if (newState == "inferiorexited") notifyInferiorExited(); } From 8ae4602a5fce6dff53c4948bd5e475e659762f4d Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 27 May 2013 16:42:42 +0200 Subject: [PATCH 23/37] Doc: update Android deployment options Change-Id: Ie3102b4abaa496e4a08cc728effcae6362a845f4 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Daniel Teske --- doc/images/qtcreator-deploy-android.png | Bin 30627 -> 26380 bytes doc/src/android/deploying-android.qdoc | 18 +++++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/doc/images/qtcreator-deploy-android.png b/doc/images/qtcreator-deploy-android.png index 01ad85c999d07dcdf7daa059f0f222f269dcbf93..253fbdfa4e0e9bf943644a26e25443d29f9e5634 100755 GIT binary patch literal 26380 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%0Ah?Q!R?uR5Xb4>DBSdbebqW!F8%dhS84 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 literal 30627 zcmeAS@N?(olHy`uVBq!ia0y~yU>8&=_N5Y zD^-6nw$3S5>+mpmE;DQ8%5!&vyu&uBoX(8Qes+9~r02G$AFHze?J z?X1#sXDpi&Sd=|fl%CHiR@}39f3 B2TjeYMM>8dYmB(U)>S@=K1^0d+YBNC0opT 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 W`<3TXj2IXg7(8A5T-G@yGywohZhZFu diff --git a/doc/src/android/deploying-android.qdoc b/doc/src/android/deploying-android.qdoc index 918e419e661..4003ea457e5 100644 --- a/doc/src/android/deploying-android.qdoc +++ b/doc/src/android/deploying-android.qdoc @@ -92,8 +92,8 @@ \image qtcreator-deploy-android.png "Deploy configurations" To copy Qt libraries and files to the project directory and to bundle them - as part of the APK, select the \gui {Use Qt libraries from device} option - and the \gui {Use local Qt libraries} check box. This is the default option + as part of the APK, select the \gui {Bundle Qt libraries in APK} option. + This is the default option when developing with Qt 5. \section1 Using Ministro to Install Qt Libraries @@ -111,7 +111,7 @@ created by \QC. To use Ministro to install the Qt libraries, select the - \gui {Use Qt libraries from device} option (without any other options). + \gui {Use Ministro service to install Qt} option. This is the default option when developing with Qt 4. @@ -128,11 +128,16 @@ during development. Select \gui Projects > \gui Run > \gui {Deploy configurations} > - \gui Details, and then select the \gui {Deploy local Qt libraries} option - and the \gui {Use local Qt libraries} check box to deploy Qt libraries to + \gui Details, and then select the + \gui {Deploy local Qt libraries to temporary directory} option to deploy + Qt libraries to the \c{/data/local/tmp/qt} folder on the device and to run the application against them. + To deploy new Qt libraries to the device, select + \gui {Clean Temporary Libraries Directory on Device}. The next time you + deploy the application, Qt libraries are copied to the device again. + \section1 Installing Ministro The easiest way to install Ministro is to do it on the device via Google @@ -143,8 +148,7 @@ from the Google Market or from the \l{http://necessitas.kde.org/necessitas/ministro.php}{Ministro} home page. - Then select the \gui {Install Ministro, system-wide Qt shared - libraries installer} option in \gui Projects > \gui Run > + Then select \gui {Install Ministro from APK} in \gui Projects > \gui Run > \gui {Deploy configurations} > \gui Details. You can use this option also to install any Android package (.apk). From b462f37742103a553a684a4628e709526dade04e Mon Sep 17 00:00:00 2001 From: hjk Date: Sat, 25 May 2013 03:47:40 +0200 Subject: [PATCH 24/37] BinEditor: Code cosmetics Change-Id: I59836b26094d86699dc36e36167b025fadb7ca37 Reviewed-by: Christian Kandeler Reviewed-by: hjk --- src/plugins/bineditor/bineditor.cpp | 8 +++++ src/plugins/bineditor/bineditor.h | 1 + src/plugins/bineditor/bineditorplugin.cpp | 42 ++++++++++------------- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/plugins/bineditor/bineditor.cpp b/src/plugins/bineditor/bineditor.cpp index 4fa6c608eb6..4f8c109c3db 100644 --- a/src/plugins/bineditor/bineditor.cpp +++ b/src/plugins/bineditor/bineditor.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -106,6 +107,13 @@ BinEditorWidget::BinEditorWidget(QWidget *parent) m_canRequestNewWindow = false; setFocusPolicy(Qt::WheelFocus); setFrameStyle(QFrame::Plain); + + // Font settings + TextEditor::TextEditorSettings *settings = TextEditor::TextEditorSettings::instance(); + setFontSettings(settings->fontSettings()); + connect(settings, SIGNAL(fontSettingsChanged(TextEditor::FontSettings)), + this, SLOT(setFontSettings(TextEditor::FontSettings))); + } BinEditorWidget::~BinEditorWidget() diff --git a/src/plugins/bineditor/bineditor.h b/src/plugins/bineditor/bineditor.h index 83ef6a346cb..a75c10175cb 100644 --- a/src/plugins/bineditor/bineditor.h +++ b/src/plugins/bineditor/bineditor.h @@ -62,6 +62,7 @@ class BinEditorWidget : public QAbstractScrollArea Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly DESIGNABLE false) Q_PROPERTY(QList markup READ markup WRITE setMarkup DESIGNABLE false) Q_PROPERTY(bool newWindowRequestAllowed READ newWindowRequestAllowed WRITE setNewWindowRequestAllowed DESIGNABLE false) + public: BinEditorWidget(QWidget *parent = 0); ~BinEditorWidget(); diff --git a/src/plugins/bineditor/bineditorplugin.cpp b/src/plugins/bineditor/bineditorplugin.cpp index a805e66f6c9..f4887a5a834 100644 --- a/src/plugins/bineditor/bineditorplugin.cpp +++ b/src/plugins/bineditor/bineditorplugin.cpp @@ -58,8 +58,6 @@ #include #include #include -#include -#include #include #include @@ -77,9 +75,10 @@ public: m_widget = widget; m_incrementalStartPos = m_contPos = -1; } - ~BinEditorFind() {} bool supportsReplace() const { return false; } + QString currentFindString() const { return QString(); } + QString completedFindString() const { return QString(); } Find::FindFlags supportedFindFlags() const { @@ -96,12 +95,13 @@ public: m_widget->highlightSearchResults(txt.toLatin1(), Find::textDocumentFlagsForFindFlags(findFlags)); } - void clearResults() { m_widget->highlightSearchResults(QByteArray()); } - QString currentFindString() const { return QString(); } - QString completedFindString() const { return QString(); } + void clearResults() + { + m_widget->highlightSearchResults(QByteArray()); + } - - int find(const QByteArray &pattern, int pos, Find::FindFlags findFlags) { + int find(const QByteArray &pattern, int pos, Find::FindFlags findFlags) + { if (pattern.isEmpty()) { m_widget->setCursorPosition(pos); return pos; @@ -341,13 +341,15 @@ public: m_toolBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); m_toolBar->addWidget(w); - connect(m_widget, SIGNAL(cursorPositionChanged(int)), this, - SLOT(updateCursorPosition(int))); - connect(m_file, SIGNAL(changed()), this, SIGNAL(changed())); - connect(m_addressEdit, SIGNAL(editingFinished()), this, - SLOT(jumpToAddress())); + widget->setEditor(this); + + connect(m_widget, SIGNAL(cursorPositionChanged(int)), SLOT(updateCursorPosition(int))); + connect(m_file, SIGNAL(changed()), SIGNAL(changed())); + connect(m_addressEdit, SIGNAL(editingFinished()), SLOT(jumpToAddress())); + connect(m_widget, SIGNAL(modificationChanged(bool)), SIGNAL(changed())); updateCursorPosition(m_widget->cursorPosition()); } + ~BinEditor() { delete m_widget; } @@ -411,8 +413,10 @@ QString BinEditorFactory::displayName() const Core::IEditor *BinEditorFactory::createEditor(QWidget *parent) { BinEditorWidget *widget = new BinEditorWidget(parent); + BinEditor *editor = new BinEditor(widget); + m_owner->initializeEditor(widget); - return widget->editor(); + return editor; } QStringList BinEditorFactory::mimeTypes() const @@ -471,10 +475,6 @@ QAction *BinEditorPlugin::registerNewAction(Core::Id id, void BinEditorPlugin::initializeEditor(BinEditorWidget *widget) { - BinEditor *editor = new BinEditor(widget); - QObject::connect(widget, SIGNAL(modificationChanged(bool)), editor, SIGNAL(changed())); - widget->setEditor(editor); - m_context.add(Constants::C_BINEDITOR); if (!m_undoAction) { m_undoAction = registerNewAction(Core::Constants::UNDO, this, SLOT(undoAction()), tr("&Undo")); @@ -483,12 +483,6 @@ void BinEditorPlugin::initializeEditor(BinEditorWidget *widget) m_selectAllAction = registerNewAction(Core::Constants::SELECTALL, this, SLOT(selectAllAction())); } - // Font settings - TextEditor::TextEditorSettings *settings = TextEditor::TextEditorSettings::instance(); - widget->setFontSettings(settings->fontSettings()); - connect(settings, SIGNAL(fontSettingsChanged(TextEditor::FontSettings)), - widget, SLOT(setFontSettings(TextEditor::FontSettings))); - QObject::connect(widget, SIGNAL(undoAvailable(bool)), this, SLOT(updateActions())); QObject::connect(widget, SIGNAL(redoAvailable(bool)), this, SLOT(updateActions())); From 49d48760d6120bc54e2837e77fabcadda2fd07a4 Mon Sep 17 00:00:00 2001 From: hjk Date: Sat, 25 May 2013 03:10:12 +0200 Subject: [PATCH 25/37] BinEditor/Debugger: Simplify signal and slot signatures The IEditor parameter was never used. Change-Id: Id374d9404701131d6c3ee02ed43fdbf3e3ed8af8 Reviewed-by: David Schulz --- src/plugins/bineditor/bineditor.cpp | 12 ++++----- src/plugins/bineditor/bineditor.h | 6 ++--- src/plugins/bineditor/bineditorplugin.cpp | 14 +++++----- src/plugins/debugger/memoryagent.cpp | 31 +++++++---------------- src/plugins/debugger/memoryagent.h | 7 +++-- 5 files changed, 29 insertions(+), 41 deletions(-) diff --git a/src/plugins/bineditor/bineditor.cpp b/src/plugins/bineditor/bineditor.cpp index 4f8c109c3db..25b12f0cc6e 100644 --- a/src/plugins/bineditor/bineditor.cpp +++ b/src/plugins/bineditor/bineditor.cpp @@ -196,7 +196,7 @@ bool BinEditorWidget::requestDataAt(int pos) const if (!m_requests.contains(block)) { m_requests.insert(block); emit const_cast(this)-> - dataRequested(editor(), m_baseAddr / m_blockSize + block); + dataRequested(m_baseAddr / m_blockSize + block); return true; } return false; @@ -230,7 +230,7 @@ void BinEditorWidget::changeDataAt(int pos, char c) } } - emit dataChanged(editor(), m_baseAddr + pos, QByteArray(1, c)); + emit dataChanged(m_baseAddr + pos, QByteArray(1, c)); } QByteArray BinEditorWidget::dataMid(int from, int length, bool old) const @@ -442,9 +442,9 @@ void BinEditorWidget::scrollContentsBy(int dx, int dy) const QScrollBar * const scrollBar = verticalScrollBar(); const int scrollPos = scrollBar->value(); if (dy <= 0 && scrollPos == scrollBar->maximum()) - emit newRangeRequested(editor(), baseAddress() + m_size); + emit newRangeRequested(baseAddress() + m_size); else if (dy >= 0 && scrollPos == scrollBar->minimum()) - emit newRangeRequested(editor(), baseAddress()); + emit newRangeRequested(baseAddress()); } void BinEditorWidget::changeEvent(QEvent *e) @@ -1058,7 +1058,7 @@ bool BinEditorWidget::event(QEvent *e) const QScrollBar * const scrollBar = verticalScrollBar(); const int maximum = scrollBar->maximum(); if (maximum && scrollBar->value() >= maximum - 1) { - emit newRangeRequested(editor(), baseAddress() + m_size); + emit newRangeRequested(baseAddress() + m_size); return true; } break; @@ -1571,7 +1571,7 @@ void BinEditorWidget::jumpToAddress(quint64 address) if (address >= m_baseAddr && address < m_baseAddr + m_size) setCursorPosition(address - m_baseAddr); else - emit newRangeRequested(editor(), address); + emit newRangeRequested(address); } void BinEditorWidget::setNewWindowRequestAllowed(bool c) diff --git a/src/plugins/bineditor/bineditor.h b/src/plugins/bineditor/bineditor.h index a75c10175cb..81b4b330453 100644 --- a/src/plugins/bineditor/bineditor.h +++ b/src/plugins/bineditor/bineditor.h @@ -139,11 +139,11 @@ Q_SIGNALS: void redoAvailable(bool); void cursorPositionChanged(int position); - void dataRequested(Core::IEditor *editor, quint64 block); + void dataRequested(quint64 block); void newWindowRequested(quint64 address); - void newRangeRequested(Core::IEditor *, quint64 address); + void newRangeRequested(quint64 address); void addWatchpointRequested(quint64 address, uint size); - void dataChanged(Core::IEditor *, quint64 address, const QByteArray &data); + void dataChanged(quint64 address, const QByteArray &data); protected: void scrollContentsBy(int dx, int dy); diff --git a/src/plugins/bineditor/bineditorplugin.cpp b/src/plugins/bineditor/bineditorplugin.cpp index f4887a5a834..dbfd7e219e4 100644 --- a/src/plugins/bineditor/bineditorplugin.cpp +++ b/src/plugins/bineditor/bineditorplugin.cpp @@ -184,10 +184,10 @@ public: Core::IDocument(parent) { m_widget = parent; - connect(m_widget, SIGNAL(dataRequested(Core::IEditor*,quint64)), - this, SLOT(provideData(Core::IEditor*,quint64))); - connect(m_widget, SIGNAL(newRangeRequested(Core::IEditor*,quint64)), - this, SLOT(provideNewRange(Core::IEditor*,quint64))); + connect(m_widget, SIGNAL(dataRequested(quint64)), + this, SLOT(provideData(quint64))); + connect(m_widget, SIGNAL(newRangeRequested(quint64)), + this, SLOT(provideNewRange(quint64))); } ~BinEditorDocument() {} @@ -246,7 +246,8 @@ public: } private slots: - void provideData(Core::IEditor *, quint64 block) { + void provideData(quint64 block) + { if (m_fileName.isEmpty()) return; QFile file(m_fileName); @@ -266,7 +267,8 @@ private slots: } } - void provideNewRange(Core::IEditor *, quint64 offset) { + void provideNewRange(quint64 offset) + { open(0, m_fileName, offset); } diff --git a/src/plugins/debugger/memoryagent.cpp b/src/plugins/debugger/memoryagent.cpp index 0d045a4679a..5289b502728 100644 --- a/src/plugins/debugger/memoryagent.cpp +++ b/src/plugins/debugger/memoryagent.cpp @@ -129,24 +129,12 @@ void MemoryAgent::updateMemoryView(quint64 address, quint64 length) void MemoryAgent::connectBinEditorWidget(QWidget *w) { - connect(w, - SIGNAL(dataRequested(Core::IEditor*,quint64)), - SLOT(fetchLazyData(Core::IEditor*,quint64))); - connect(w, - SIGNAL(newWindowRequested(quint64)), - SLOT(createBinEditor(quint64))); - connect(w, - SIGNAL(newRangeRequested(Core::IEditor*,quint64)), - SLOT(provideNewRange(Core::IEditor*,quint64))); - connect(w, - SIGNAL(dataChanged(Core::IEditor*,quint64,QByteArray)), - SLOT(handleDataChanged(Core::IEditor*,quint64,QByteArray))); - connect(w, - SIGNAL(dataChanged(Core::IEditor*,quint64,QByteArray)), - SLOT(handleDataChanged(Core::IEditor*,quint64,QByteArray))); - connect(w, - SIGNAL(addWatchpointRequested(quint64,uint)), - SLOT(handleWatchpointRequest(quint64,uint))); + connect(w, SIGNAL(dataRequested(quint64)), SLOT(fetchLazyData(quint64))); + connect(w, SIGNAL(newWindowRequested(quint64)), SLOT(createBinEditor(quint64))); + connect(w, SIGNAL(newRangeRequested(quint64)), SLOT(provideNewRange(quint64))); + connect(w, SIGNAL(dataChanged(quint64,QByteArray)), SLOT(handleDataChanged(quint64,QByteArray))); + connect(w, SIGNAL(dataChanged(quint64,QByteArray)), SLOT(handleDataChanged(quint64,QByteArray))); + connect(w, SIGNAL(addWatchpointRequested(quint64,uint)), SLOT(handleWatchpointRequest(quint64,uint))); } bool MemoryAgent::doCreateBinEditor(quint64 addr, unsigned flags, @@ -222,7 +210,7 @@ void MemoryAgent::createBinEditor(quint64 addr) createBinEditor(addr, 0, QList(), QPoint(), QString(), 0); } -void MemoryAgent::fetchLazyData(IEditor *, quint64 block) +void MemoryAgent::fetchLazyData(quint64 block) { m_engine->fetchMemory(this, sender(), BinBlockSize * block, BinBlockSize); } @@ -235,15 +223,14 @@ void MemoryAgent::addLazyData(QObject *editorToken, quint64 addr, MemoryView::binEditorAddData(w, addr, ba); } -void MemoryAgent::provideNewRange(IEditor *, quint64 address) +void MemoryAgent::provideNewRange(quint64 address) { QWidget *w = qobject_cast(sender()); QTC_ASSERT(w, return); MemoryView::setBinEditorRange(w, address, DataRange, BinBlockSize); } -void MemoryAgent::handleDataChanged(IEditor *, - quint64 addr, const QByteArray &data) +void MemoryAgent::handleDataChanged(quint64 addr, const QByteArray &data) { m_engine->changeMemory(this, sender(), addr, data); } diff --git a/src/plugins/debugger/memoryagent.h b/src/plugins/debugger/memoryagent.h index f44df5d2f1e..5046e0753ab 100644 --- a/src/plugins/debugger/memoryagent.h +++ b/src/plugins/debugger/memoryagent.h @@ -95,10 +95,9 @@ public slots: void closeViews(); private slots: - void fetchLazyData(Core::IEditor *, quint64 block); - void provideNewRange(Core::IEditor *editor, quint64 address); - void handleDataChanged(Core::IEditor *editor, quint64 address, - const QByteArray &data); + void fetchLazyData(quint64 block); + void provideNewRange(quint64 address); + void handleDataChanged(quint64 address, const QByteArray &data); void handleWatchpointRequest(quint64 address, uint size); void updateMemoryView(quint64 address, quint64 length); void engineStateChanged(Debugger::DebuggerState s); From 8906b4a4c8c0cae5bd5694aed2ff420a88e0cf20 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 29 May 2013 16:24:17 +0200 Subject: [PATCH 26/37] Debugger: Make thread switching work in LLDB interface Change-Id: I332e78c352066ddd05e96199fd8ead088e3e9f58 Reviewed-by: hjk --- share/qtcreator/dumper/lbridge.py | 7 ++++--- src/plugins/debugger/lldb/lldbengine.cpp | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/share/qtcreator/dumper/lbridge.py b/share/qtcreator/dumper/lbridge.py index bb2f8bb84b1..0f9589c2394 100644 --- a/share/qtcreator/dumper/lbridge.py +++ b/share/qtcreator/dumper/lbridge.py @@ -1167,7 +1167,7 @@ class Dumper: #module = self.target.FindModule(file) for i in xrange(self.target.GetNumModules()): module = self.target.GetModuleAtIndex(i) - if module.file.GetFullPath() == moduleName: + if module.file.fullpath == moduleName: break result = 'symbols={module="%s"' % moduleName result += ',valid="%s"' % module.IsValid() @@ -1227,8 +1227,9 @@ class Dumper: self.currentThread().SetSelectedFrame(args['index']) self.reportData() - def selectThread(self, thread): - self.handleCommand("thread select " + thread) + def selectThread(self, args): + self.process.SetSelectedThreadByID(args['id']) + self.reportData() def requestModuleSymbols(self, frame): self.handleCommand("target module list " + frame) diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 5f0397b80a1..2b3af11a484 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -821,7 +821,7 @@ void LldbEngine::readLldbStandardError() qDebug() << "\nLLDB STDERR" << err; //qWarning() << "Unexpected lldb stderr:" << err; showMessage(_("Lldb stderr: " + err)); - //handleOutput(err); + m_lldbProc.kill(); } void LldbEngine::readLldbStandardOutput() From 9072db09abe173e417c348a9ac4135e866b5b4c5 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 29 May 2013 16:06:07 +0200 Subject: [PATCH 27/37] Debugger: Fix module listing Change-Id: I342e78c352066ddd05e96199fd8ead088e3e9f58 Reviewed-by: hjk --- share/qtcreator/dumper/lbridge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/dumper/lbridge.py b/share/qtcreator/dumper/lbridge.py index 0f9589c2394..5487d635965 100644 --- a/share/qtcreator/dumper/lbridge.py +++ b/share/qtcreator/dumper/lbridge.py @@ -1147,7 +1147,7 @@ class Dumper: result = 'modules=[' for i in xrange(self.target.GetNumModules()): module = self.target.GetModuleAtIndex(i) - result += '{file="%s"' % module.file.GetFullPath() + result += '{file="%s"' % module.file.fullpath result += ',name="%s"' % module.file.basename result += ',addrsize="%s"' % module.addr_size result += ',triple="%s"' % module.triple From 6567a673942a3450a6516fb461abdc0bdafc6674 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 29 May 2013 15:27:05 +0200 Subject: [PATCH 28/37] Fix possible crash in target We need to make sure to remove RCs we delete from the lists held in the updateDefaultRunConfigurations method. Change-Id: Icf7908af3554e682af6ba9101058cb210e35f999 Reviewed-by: Daniel Teske --- src/plugins/projectexplorer/target.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp index f6fb277c5a9..d18d7fd4644 100644 --- a/src/plugins/projectexplorer/target.cpp +++ b/src/plugins/projectexplorer/target.cpp @@ -658,8 +658,10 @@ void Target::updateDefaultRunConfigurations() } // Do actual changes: - foreach (RunConfiguration *rc, toRemove) + foreach (RunConfiguration *rc, toRemove) { removeRunConfiguration(rc); + existingConfigured.removeOne(rc); // make sure to also remove them from existingConfigured! + } if (removeExistingUnconfigured) { foreach (RunConfiguration *rc, existingUnconfigured) From 400806181625a0a167ef924bf11719f4e46ae2df Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 29 May 2013 13:08:17 +0200 Subject: [PATCH 29/37] Qbs: Update to new way of Qbs announcing warnings Change-Id: Ie707a24d5a081c058f838410c1223201ca4021b3 Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/taskhub.h | 8 ++++++-- src/plugins/qbsprojectmanager/qbsbuildstep.cpp | 10 ---------- src/plugins/qbsprojectmanager/qbsbuildstep.h | 1 - src/plugins/qbsprojectmanager/qbslogsink.cpp | 16 ++++++++++++++++ src/plugins/qbsprojectmanager/qbslogsink.h | 6 ++++++ src/shared/qbs | 2 +- 6 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/plugins/projectexplorer/taskhub.h b/src/plugins/projectexplorer/taskhub.h index 1355705e61f..90f77abd75e 100644 --- a/src/plugins/projectexplorer/taskhub.h +++ b/src/plugins/projectexplorer/taskhub.h @@ -45,10 +45,13 @@ public: TaskHub(); virtual ~TaskHub(); +public slots: void addCategory(const Core::Id &categoryId, const QString &displayName, bool visible = true); - void addTask(Task task); + void addTask(ProjectExplorer::Task task); void clearTasks(const Core::Id &categoryId = Core::Id()); - void removeTask(const Task &task); + void removeTask(const ProjectExplorer::Task &task); + +public: void updateTaskFileName(unsigned int id, const QString &fileName); void updateTaskLineNumber(unsigned int id, int line); void taskMarkClicked(unsigned int id); @@ -58,6 +61,7 @@ public: void requestPopup(); QIcon taskTypeIcon(ProjectExplorer::Task::TaskType t) const; + signals: void categoryAdded(const Core::Id &categoryId, const QString &displayName, bool visible); void taskAdded(const ProjectExplorer::Task &task); diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp index 9e944c94227..10522cebe18 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp +++ b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp @@ -135,8 +135,6 @@ void QbsBuildStep::run(QFutureInterface &fi) this, SLOT(handleProgress(int))); connect(m_job, SIGNAL(reportCommandDescription(QString,QString)), this, SLOT(handleCommandDescriptionReport(QString,QString))); - connect(m_job, SIGNAL(reportWarning(qbs::Error)), - this, SLOT(handleWarningReport(qbs::Error))); connect(m_job, SIGNAL(reportProcessResult(qbs::ProcessResult)), this, SLOT(handleProcessResultReport(qbs::ProcessResult))); } @@ -246,14 +244,6 @@ void QbsBuildStep::handleProgress(int value) m_fi->setProgressValue(m_progressBase + value); } -void QbsBuildStep::handleWarningReport(const qbs::Error &error) -{ - foreach (const qbs::ErrorData &data, error.entries()) { - createTaskAndOutput(ProjectExplorer::Task::Warning, data.description(), - data.codeLocation().fileName(), data.codeLocation().line()); - } -} - void QbsBuildStep::handleCommandDescriptionReport(const QString &highlight, const QString &message) { Q_UNUSED(highlight); diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.h b/src/plugins/qbsprojectmanager/qbsbuildstep.h index 9d5e1da3945..0d1ce0691b1 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildstep.h +++ b/src/plugins/qbsprojectmanager/qbsbuildstep.h @@ -78,7 +78,6 @@ private slots: void buildingDone(bool success); void handleTaskStarted(const QString &desciption, int max); void handleProgress(int value); - void handleWarningReport(const qbs::Error &error); void handleCommandDescriptionReport(const QString &highlight, const QString &message); void handleProcessResultReport(const qbs::ProcessResult &result); diff --git a/src/plugins/qbsprojectmanager/qbslogsink.cpp b/src/plugins/qbsprojectmanager/qbslogsink.cpp index 03cfe0fdf66..624f5139175 100644 --- a/src/plugins/qbsprojectmanager/qbslogsink.cpp +++ b/src/plugins/qbsprojectmanager/qbslogsink.cpp @@ -32,6 +32,9 @@ #include #include +#include +#include +#include #include #include @@ -46,6 +49,9 @@ namespace Internal { QbsLogSink::QbsLogSink(QObject *parent) : QObject(parent) { + ProjectExplorer::TaskHub *hub = ProjectExplorer::ProjectExplorerPlugin::instance()->taskHub(); + connect(this, SIGNAL(newTask(ProjectExplorer::Task)), + hub, SLOT(addTask(ProjectExplorer::Task)), Qt::QueuedConnection); } void QbsLogSink::sendMessages() @@ -62,6 +68,16 @@ void QbsLogSink::sendMessages() mm->printToOutputPane(msg); } +void QbsLogSink::doPrintWarning(const qbs::Error &warning) +{ + foreach (const qbs::ErrorData &data, warning.entries()) + emit newTask(ProjectExplorer::Task(ProjectExplorer::Task::Warning, + data.description(), + Utils::FileName::fromString(data.codeLocation().fileName()), + data.codeLocation().line(), + ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)); +} + void QbsLogSink::doPrintMessage(qbs::LoggerLevel level, const QString &message, const QString &tag) { Q_UNUSED(tag); diff --git a/src/plugins/qbsprojectmanager/qbslogsink.h b/src/plugins/qbsprojectmanager/qbslogsink.h index cfbfc1b1d00..fe40101e884 100644 --- a/src/plugins/qbsprojectmanager/qbslogsink.h +++ b/src/plugins/qbsprojectmanager/qbslogsink.h @@ -30,6 +30,8 @@ #ifndef QBSLOGSINK_H #define QBSLOGSINK_H +#include + #include #include @@ -45,10 +47,14 @@ class QbsLogSink : public QObject, public qbs::ILogSink public: QbsLogSink(QObject *parent = 0); +signals: + void newTask(const ProjectExplorer::Task &task); + private slots: void sendMessages(); private: + void doPrintWarning(const qbs::Error &warning); void doPrintMessage(qbs::LoggerLevel level, const QString &message, const QString &tag); QStringList m_messages; diff --git a/src/shared/qbs b/src/shared/qbs index 32ae53690c0..5df624fa588 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit 32ae53690c01e5269ac2a9ad0dadf549ce04ee3f +Subproject commit 5df624fa5884ba7ca9d1d0666484ad24c1c0b70b From 0b91475b6d2a7752763a5c5146ef80905cb6a40a Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 29 May 2013 15:23:44 +0200 Subject: [PATCH 30/37] QmlDesigner.Instances: fix for Mac OS and Qt 4 The QSharedMemory implementations of Qt5 and Qt4 on Mac seem to be incompatible. We seem to have the same bug casually for Linux. Until we solve the real issue this serves as a quick fix. Change-Id: I686e3e94b6bb777b96f8c68cac6036c18b8d070d Reviewed-by: Marco Bubke --- .../designercore/instances/nodeinstanceserverproxy.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp index c5fb89d1e80..5ddff4a7ed5 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp @@ -158,6 +158,10 @@ NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceV QProcessEnvironment enviroment = QProcessEnvironment::systemEnvironment(); +#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) && (defined(Q_OS_MAC) || defined(Q_OS_LINUX)) + enviroment.insert(QLatin1String("DESIGNER_DONT_USE_SHARED_MEMORY"), QLatin1String("1")); +#endif + if (QFileInfo(applicationPath).exists()) { m_qmlPuppetEditorProcess = new QProcess; m_qmlPuppetEditorProcess->setProcessEnvironment(enviroment); From 74038300553faa003ecb29e20f143b6b62fc692c Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 29 May 2013 13:05:34 +0200 Subject: [PATCH 31/37] QmlDesigner.Instances: fixing spelling mistake Change-Id: I26f822fac1702e83f8f39747106c0fd3ebc22202 Reviewed-by: Marco Bubke --- .../designercore/instances/nodeinstanceserverproxy.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp index 5ddff4a7ed5..a3dedd831a7 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp @@ -156,7 +156,7 @@ NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceV if (!envImportPath.isEmpty()) applicationPath = envImportPath; - QProcessEnvironment enviroment = QProcessEnvironment::systemEnvironment(); + QProcessEnvironment environment = QProcessEnvironment::systemEnvironment(); #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) && (defined(Q_OS_MAC) || defined(Q_OS_LINUX)) enviroment.insert(QLatin1String("DESIGNER_DONT_USE_SHARED_MEMORY"), QLatin1String("1")); @@ -164,7 +164,7 @@ NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceV if (QFileInfo(applicationPath).exists()) { m_qmlPuppetEditorProcess = new QProcess; - m_qmlPuppetEditorProcess->setProcessEnvironment(enviroment); + m_qmlPuppetEditorProcess->setProcessEnvironment(environment); m_qmlPuppetEditorProcess->setObjectName("EditorProcess"); connect(m_qmlPuppetEditorProcess.data(), SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus))); connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), m_qmlPuppetEditorProcess.data(), SLOT(kill())); @@ -175,7 +175,7 @@ NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceV if (runModus == NormalModus) { m_qmlPuppetPreviewProcess = new QProcess; - m_qmlPuppetPreviewProcess->setProcessEnvironment(enviroment); + m_qmlPuppetPreviewProcess->setProcessEnvironment(environment); m_qmlPuppetPreviewProcess->setObjectName("PreviewProcess"); connect(m_qmlPuppetPreviewProcess.data(), SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus))); connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), m_qmlPuppetPreviewProcess.data(), SLOT(kill())); @@ -184,7 +184,7 @@ NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceV m_qmlPuppetPreviewProcess->start(applicationPath, QStringList() << socketToken << "previewmode" << "-graphicssystem raster"); m_qmlPuppetRenderProcess = new QProcess; - m_qmlPuppetRenderProcess->setProcessEnvironment(enviroment); + m_qmlPuppetRenderProcess->setProcessEnvironment(environment); m_qmlPuppetRenderProcess->setObjectName("RenderProcess"); connect(m_qmlPuppetRenderProcess.data(), SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus))); connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), m_qmlPuppetRenderProcess.data(), SLOT(kill())); From a05e63d7b0d277a1fc99761311e6a007789147ac Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Mon, 27 May 2013 10:17:43 +0200 Subject: [PATCH 32/37] QmlDesigner.Controls: updating sheets for Controls Updating sheets for QtQuick.Controls: * Adding enabled to Button * Adding translation to CheckBox * Adding translation to RadioButton Change-Id: I7d312c19e14cd7d653f0878cbae8af66641aa7f7 Reviewed-by: Thomas Hartmann --- .../componentsplugin/Controls/ButtonSpecifics.qml | 15 +++++++++++++++ .../Controls/CheckBoxSpecifics.qml | 1 + .../Controls/RadioButtonSpecifics.qml | 1 + 3 files changed, 17 insertions(+) diff --git a/src/plugins/qmldesigner/componentsplugin/Controls/ButtonSpecifics.qml b/src/plugins/qmldesigner/componentsplugin/Controls/ButtonSpecifics.qml index 3fa325c1890..95101e35996 100644 --- a/src/plugins/qmldesigner/componentsplugin/Controls/ButtonSpecifics.qml +++ b/src/plugins/qmldesigner/componentsplugin/Controls/ButtonSpecifics.qml @@ -86,6 +86,21 @@ QWidget { } } + QWidget { + layout: HorizontalLayout { + Label { + text: qsTr("Enabled") + toolTip: qsTr("Determines whether the button is enabled or not.") + } + CheckBox { + text: backendValues.enabled.value + backendValue: backendValues.enabled + baseStateFlag: isBaseState + checkable: true + } + } + } + QWidget { layout: HorizontalLayout { Label { diff --git a/src/plugins/qmldesigner/componentsplugin/Controls/CheckBoxSpecifics.qml b/src/plugins/qmldesigner/componentsplugin/Controls/CheckBoxSpecifics.qml index 12486b9067b..412fdeb95bf 100644 --- a/src/plugins/qmldesigner/componentsplugin/Controls/CheckBoxSpecifics.qml +++ b/src/plugins/qmldesigner/componentsplugin/Controls/CheckBoxSpecifics.qml @@ -42,6 +42,7 @@ GroupBox { LineEdit { backendValue: backendValues.text baseStateFlag: isBaseState + translation: true } } } diff --git a/src/plugins/qmldesigner/componentsplugin/Controls/RadioButtonSpecifics.qml b/src/plugins/qmldesigner/componentsplugin/Controls/RadioButtonSpecifics.qml index d006c3d9634..25ed160c0f4 100644 --- a/src/plugins/qmldesigner/componentsplugin/Controls/RadioButtonSpecifics.qml +++ b/src/plugins/qmldesigner/componentsplugin/Controls/RadioButtonSpecifics.qml @@ -43,6 +43,7 @@ GroupBox { LineEdit { backendValue: backendValues.text baseStateFlag: isBaseState + translation: true } } } From 8762dd2ea94e4a2f371b9f1667d8b14352264e6b Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed Date: Tue, 21 May 2013 15:42:02 +0200 Subject: [PATCH 33/37] qmljstools: reset code model after update of exported cpp types Task-number: QTCREATORBUG-9105 Change-Id: Id0021902985da8e5e7faec23766bb37541d041c0 Reviewed-by: Thomas Hartmann --- src/plugins/qmljstools/qmljsmodelmanager.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp index 5893c972d71..07e9ec06c12 100644 --- a/src/plugins/qmljstools/qmljsmodelmanager.cpp +++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp @@ -925,6 +925,7 @@ void ModelManager::updateCppQmlTypes(QFutureInterface &interface, FindExportedCppTypes finder(snapshot); + bool hasNewInfo = false; typedef QPair DocScanPair; foreach (const DocScanPair &pair, documents) { if (interface.isCanceled()) @@ -934,7 +935,7 @@ void ModelManager::updateCppQmlTypes(QFutureInterface &interface, const bool scan = pair.second; const QString fileName = doc->fileName(); if (!scan) { - newData.remove(fileName); + hasNewInfo = hasNewInfo || newData.remove(fileName) > 0; continue; } @@ -943,9 +944,11 @@ void ModelManager::updateCppQmlTypes(QFutureInterface &interface, QList exported = finder.exportedTypes(); QHash contextProperties = finder.contextProperties(); if (exported.isEmpty() && contextProperties.isEmpty()) { - newData.remove(fileName); + hasNewInfo = hasNewInfo || newData.remove(fileName) > 0; } else { CppData &data = newData[fileName]; + // currently we have no simple way to compare, so we assume the worse + hasNewInfo = true; data.exportedTypes = exported; data.contextProperties = contextProperties; } @@ -955,6 +958,9 @@ void ModelManager::updateCppQmlTypes(QFutureInterface &interface, QMutexLocker locker(&qmlModelManager->m_cppDataMutex); qmlModelManager->m_cppDataHash = newData; + if (hasNewInfo) + // one could get away with re-linking the cpp types... + QMetaObject::invokeMethod(qmlModelManager, "resetCodeModel"); } ModelManager::CppDataHash ModelManager::cppData() const From 2b903b46d37dc54e39b43faffffc60a33a2b9974 Mon Sep 17 00:00:00 2001 From: Petar Perisin Date: Wed, 29 May 2013 22:01:10 +0200 Subject: [PATCH 34/37] Git - added dummy locator actions for Merge, Rebase, Show, Cherry Pick, Revert and Checkout. Task-number: QTCREATORBUG-9405 Change-Id: I9a10d93382248ca86fe566bf1dccf4d390601aaf Reviewed-by: Orgad Shaneh Reviewed-by: Tobias Hunger --- src/plugins/git/gitplugin.cpp | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 1eb1ec4215f..665c332b210 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -233,7 +233,8 @@ ActionCommandPair { QAction *action = new QAction(text, this); Core::Command *command = Core::ActionManager::registerAction(action, id, context); - ac->addAction(command); + if (ac) + ac->addAction(command); m_repositoryActions.push_back(action); if (addToLocator) m_commandLocator->appendCommand(command); @@ -439,7 +440,7 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) globalcontext, false, SLOT(resetRepository())); createRepositoryAction(localRepositoryMenu, - tr("Interactive Rebase..."), Core::Id("Git.Rebase"), + tr("Interactive Rebase..."), Core::Id("Git.InteractiveRebase"), globalcontext, true, SLOT(startRebase())); createRepositoryAction(localRepositoryMenu, @@ -591,6 +592,29 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) // -------------- + /* Actions only in locator */ + createRepositoryAction(0, tr("Show..."), Core::Id("Git.Show"), + globalcontext, true, SLOT(startChangeRelatedAction())); + + createRepositoryAction(0, tr("Revert..."), Core::Id("Git.Revert"), + globalcontext, true, SLOT(startChangeRelatedAction())); + + createRepositoryAction(0, tr("Cherry Pick..."), Core::Id("Git.CherryPick"), + globalcontext, true, SLOT(startChangeRelatedAction())); + + createRepositoryAction(0, tr("Checkout..."), Core::Id("Git.Checkout"), + globalcontext, true, SLOT(startChangeRelatedAction())); + + createRepositoryAction(0, tr("Rebase..."), Core::Id("Git.Rebase"), + globalcontext, true, SLOT(branchList())); + + createRepositoryAction(0, tr("Merge..."), Core::Id("Git.Merge"), + globalcontext, true, SLOT(branchList())); + + /* \Actions only in locator */ + + // -------------- + /* "Git Tools" menu */ Core::ActionContainer *gitToolsMenu = Core::ActionManager::createMenu(Core::Id("Git.GitToolsMenu")); gitToolsMenu->menu()->setTitle(tr("Git &Tools")); From b45fbc57f03c0048f4b78d79db7274e65a924bcf Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 29 May 2013 12:11:34 +0200 Subject: [PATCH 35/37] Fix qbs build. Referring to non-existing files causes an error now. Change-Id: I51aed8dfdcc92779158b284b849a34f259997e7c Reviewed-by: Joerg Bornemann --- src/plugins/projectexplorer/projectexplorer.qbs | 2 -- src/plugins/texteditor/texteditor.qbs | 1 - 2 files changed, 3 deletions(-) diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs index 05f971036fe..fbadafac3b7 100644 --- a/src/plugins/projectexplorer/projectexplorer.qbs +++ b/src/plugins/projectexplorer/projectexplorer.qbs @@ -310,8 +310,6 @@ QtcPlugin { "images/targetleftbutton.png", "images/targetpanel_bottom.png", "images/targetpanel_gradient.png", - "images/targetremovebutton.png", - "images/targetremovebuttondark.png", "images/targetrightbutton.png", "images/targetrunselected.png", "images/targetseparatorbackground.png", diff --git a/src/plugins/texteditor/texteditor.qbs b/src/plugins/texteditor/texteditor.qbs index ed32f2e26f7..b20ee44f0b2 100644 --- a/src/plugins/texteditor/texteditor.qbs +++ b/src/plugins/texteditor/texteditor.qbs @@ -187,7 +187,6 @@ QtcPlugin { "ifunctionhintproposalmodel.h", "igenericproposalmodel.cpp", "igenericproposalmodel.h", - "ikeywords.h", "keywordscompletionassist.cpp", "keywordscompletionassist.h", "quickfixassistprocessor.cpp", From 87bd3ead552e4b1e5c99ca6778303036a9960a57 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 29 May 2013 16:53:23 +0200 Subject: [PATCH 36/37] Add 2.8 changes file Change-Id: I47121fcce1c063a6a0af82ebac080f843d2d157f Reviewed-by: Leena Miettinen Reviewed-by: Eike Ziller --- dist/changes-2.8.0 | 231 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 dist/changes-2.8.0 diff --git a/dist/changes-2.8.0 b/dist/changes-2.8.0 new file mode 100644 index 00000000000..87cfd4e83ad --- /dev/null +++ b/dist/changes-2.8.0 @@ -0,0 +1,231 @@ +Qt Creator version 2.8 contains bug fixes and new features. + +There is a total of about 1250 changes by 60 individual contributors. + +The most important changes are listed in this document. For a complete +list of changes, see the Git log for the Qt Creator sources that +you can check out from the public Git repository. For example: + +git clone git://gitorious.org/qt-creator/qt-creator.git +git log --cherry-pick --pretty=oneline v2.7.1..origin/2.8 + +General + * Moved progress information from mode selector to the bottom-right + of the main window + * Added option to hide detailed progress information and show + summary progress bar instead + * Added "-block" command line option that opens files in a running + Qt Creator and blocks the command line until the editors are closed + * Made mode selector hideable (Window > Show Mode Selector) + +Editing + * Added option to open extra editor windows (Window > Split New Window) + * Fixed that mouse cursor was hidden when pressing modifier key + * Added support for jumping to column with locator and Go to Line menu + * Added that clicking on line and column display opens locator with line and column filter + (QTCREATORBUG-8811) + * Added option to show file encoding next to line and column display + (QTCREATORBUG-8376) + +Managing Projects + * Fixed opening projects created with wizard even if version control + creation fails (QTCREATORBUG-8892) + +Compilers + * Fixed detection of PowerPC ABI + * Fixed detection of ARM-based Windows CE ABI + * Fixed compile output parsers cutting off last character (QTCREATORBUG-9032) + * Added support for new warnings and errors in compile output from GCC 4.8 + +Devices + * Fixed setting default device (QTCREATORBUG-7812) + * Added support for configuring Desktop device + (for example free ports for debugging) + +QMake Projects + * Added support for OBJECTIVE_HEADERS + +CMake Projects + * Fixed sorting of build targets + * Fixed CXXFLAGS detection when Ninja is used (QTCREATORBUG-9047) + +Qbs Projects + * Fixed defines that are passed to the C++ code model + * Added install build step + * Fixed several issues with project tree + * Added run configuration for products in the project + * Added building of single files + +Autotools Projects + * Added parsing of defines and C++ flags from Makefile + +Generic Projects + * Added filtering for files to add instead of only filtering for files to ignore when + importing projects (QTCREATORBUG-8805) + +Debugging + * GDB + * Added option to load system GDB pretty printers + * Made adding tasks for missing debug info packages optional + (QTCREATORBUG-8949) + * CDB + * Fixed stepping out of disassembled function + * Added warning when debugging release build + * Fixed and added nice display of several data types + (QPixmap, QChar, 64bit integers in containers, QString in QVariant) + * Fixed that debugger would sometimes stop at disabled breakpoints (QTCREATORBUG-9295) + * LLDB + * Added experimental support + * QML + * Fixed that a fixed port was used instead of using port from device settings + * Added support for IPv6 + +Analyzer + * Fixed that a fixed port was used instead of using port from device settings + * Added support for IPv6 + * Fixed attaching profiler to QML applications to use kits + +C++ Support + * Added refactoring action that moves function definition from header to + source (QTCREATORBUG-516) + * Added refactoring action that assigns a function return value or new expression + to local variable (QTCREATORBUG-9052) + * Added refactoring action that adds implementations for pure virtual methods + * Fixed parsing of try-catch in constructor initializer (QTCREATORBUG-9064) + * Fixed handling of non-arguments in function parameter scope (QTCREATORBUG-8316) + * Fixed crash when adding include for undefined identifier in file that + has no other include (QTCREATORBUG-8799) + * Fixed that system headers were not reparsed when project configuration + changes (QTCREATORBUG-9056) + * Fixed highlighting for template parameters for function calls + * Improved support for anonymous classes + (QTCREATORBUG-6497, QTCREATORBUG-8963, QTCREATORBUG-3610, QTCREATORBUG-7579) + * Fixed support for typedef of templated typedefs (QTCREATORBUG-8375) + * Fixed code completion with 'using' declaration inside functions (QTCREATORBUG-2668) + * Fixed highlighting of types when there is 'using Namespace::TypeName' (QTCREATORBUG-7903) + +Python Support + * Added an editor with highlighter and indenter + * Added file and class wizards + +Diff Viewer + * Enabled by default + * Added folding of skipped lines + * Added folding of files + * Added jumping to original file on double-click + * Added file list combo box + +Version Control Systems + * Added "Select All" to clean dialog + * Git + * Added new side-by-side diff viewer + * Added support for interactive rebase + * Added support for updating submodules + * Added support for checking out commit + * Added continue and abort for operations in progress + (rebase, cherry-pick etc.) + * Added support for fixing up previous commit + * Moved all change related actions to a single dialog + * Improved stash handling + * Added dialog for pushing to Gerrit + * Added tags to branches dialog + * Added ability to save repository location for Gerrit + * Added graph toggle button for log viewer + * ClearCase + * Removed useless hijack button for dynamic view + +FakeVim + * Fixed movement between views with Ctrl+W, Arrow + * Added setting for .vimrc location (QTCREATORBUG-8748) + * Fixed z., zz, zb and z- commands + * Added support for Vim macro recording + +Platform Specific + +Linux + * Made crash handler for debug builds optional + +Qt Support + * Fixed that Qt Creator preferred Qt 4 qmake over the system default + (QTCREATORBUG-9068) + +QNX + * Added warning for too big icons and splash screens + * Added more application permissions to bar descriptor editor + * Added check for device development mode before deploying + * Fixed certificate marshalling with newer BlackBerry NDKs + * Added auto-detection of device PIN for new debug tokens (QTCREATORBUG-9062) + * Enabled QML debugging for pure QNX devices + * Fixed that key generation locked up UI (QTCREATORBUG-9078) + * Added option to sign packages when creating them + +Android + * Fixed that Android device would show up even when no Android SDK + was configured + * Added support for mixed C++/QML debugging + * Added support for QML profiling + * Added more sanity checks for package names (QTCREATORBUG-9200) + * Added visual editor for Android manifest files + +Credits for these changes go to: + +Aaron McCarthy +Adrien Bustany +Alan Alpert +Alessandro Portale +Andreas Holzammer +André Hartmann +André Pönitz +Andrey M. Tokarev +Aurindam Jana +Christian Kandeler +Christian Stenger +Christian Strømme +Daniel Teske +David Schulz +Debao Zhang +Dmitry Savchenko +Eike Ziller +El Mehdi Fekari +Erik Verbruggen +Eskil Abrahamsen Blomfeldt +Fawzi Mohamed +Friedemann Kleint +Lukas Holecek +Hugues Delorme +Jaroslaw Kobus +Jesper K. Pedersen +Jörg Bornemann +J-P Nurmi +Kai Köhne +Knut Petter Svendsen +Laurent Montel +Leena Miettinen +Lorenz Haas +Lukas Holecek +Marc Mutz +Marco Bubke +Martin T. H. Sandsmark +Michal Klocek +Mitch Curtis +Montel Laurent +Morten Johan Sørvig +Nikolai Kosjar +Orgad Shaneh +Oswald Buddenhagen +Pawel Faron +Petar Perisin +Przemyslaw Gorszkowski +Rafael Roquetto +Robert Löhning +Sergey Belyashov +Sergey Shambir +Shane Peelar +Thiago Macieira +Thomas Hartmann +Tim Jenssen +Timo Jyrinki +Tobias Hunger +Tobias Nätterlund +Tor Arne Vestbø +Victor Ostashevsky From b0aa436fa5694f943b79d64626e3dd18df554d4a Mon Sep 17 00:00:00 2001 From: Laurent Montel Date: Thu, 30 May 2013 11:46:58 +0200 Subject: [PATCH 37/37] Fix compile on linux + qt < 5 Change-Id: Iadb7df3cdb32180f78dace7bc11c7c673399c65b Reviewed-by: Nicolas Arnaud-Cormos --- .../designercore/instances/nodeinstanceserverproxy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp index a3dedd831a7..f366abbb012 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp @@ -159,7 +159,7 @@ NodeInstanceServerProxy::NodeInstanceServerProxy(NodeInstanceView *nodeInstanceV QProcessEnvironment environment = QProcessEnvironment::systemEnvironment(); #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) && (defined(Q_OS_MAC) || defined(Q_OS_LINUX)) - enviroment.insert(QLatin1String("DESIGNER_DONT_USE_SHARED_MEMORY"), QLatin1String("1")); + environment.insert(QLatin1String("DESIGNER_DONT_USE_SHARED_MEMORY"), QLatin1String("1")); #endif if (QFileInfo(applicationPath).exists()) {