From 6f6f970afb8a389e83b14bcb0842aa990969d6bb Mon Sep 17 00:00:00 2001 From: Marcel Krems Date: Wed, 23 Oct 2013 18:06:30 +0200 Subject: [PATCH 01/84] Fix calculation of compiler string for VS 2013. Change-Id: I451f21732f6c7d9cc7c205a126985f1dc1122578 Reviewed-by: Friedemann Kleint --- src/plugins/coreplugin/icore.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index 7564a59f027..a226c2b6094 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -415,7 +415,9 @@ static QString compilerString() #elif defined(Q_CC_GNU) return QLatin1String("GCC " ) + QLatin1String(__VERSION__); #elif defined(Q_CC_MSVC) - if (_MSC_VER >= 1500) // 1500: MSVC 2008, 1600: MSVC 2010, ... + if (_MSC_VER >= 1800) // 1800: MSVC 2013 (yearly release cycle) + return QLatin1String("MSVC ") + QString::number(2008 + ((_MSC_VER / 100) - 13)); + if (_MSC_VER >= 1500) // 1500: MSVC 2008, 1600: MSVC 2010, ... (2-year release cycle) return QLatin1String("MSVC ") + QString::number(2008 + 2 * ((_MSC_VER / 100) - 15)); #endif return QLatin1String(""); From a2c0b91ec5890584716175aa18310b158cf016ff Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 23 Oct 2013 14:53:51 +0200 Subject: [PATCH 02/84] QmlDesigner: Disable componentComplete for primitive creation Control are now in a qrc file and the component are registered as Qml types. We are using the primitive creation path in this case so we have to disable the componentComplete call. Change-Id: I52936b92d936acbfc21ba800ffca9123fcece864 Reviewed-by: Thomas Hartmann --- .../qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp index cf1455a9db4..9cb611272ae 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/objectnodeinstance.cpp @@ -1015,6 +1015,10 @@ QObject *ObjectNodeInstance::createCustomParserObject(const QString &nodeSource, QObject *ObjectNodeInstance::createPrimitive(const QString &typeName, int majorNumber, int minorNumber, QQmlContext *context) { + ComponentCompleteDisabler disableComponentComplete; + + Q_UNUSED(disableComponentComplete) + QObject *object = 0; QQmlType *type = QQmlMetaType::qmlType(typeName.toUtf8(), majorNumber, minorNumber); if (type) { From bc81930f17f5fe897fd0ede57169a52751b72f73 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 23 Oct 2013 14:13:06 +0200 Subject: [PATCH 03/84] Give preprocessor dialog button a tool tip. Change-Id: Iad756a8f18736da79cca63232eb00fcee8a2f38c Reviewed-by: David Schulz --- src/plugins/cppeditor/cppeditor.cpp | 20 ++++++++++++++++---- src/plugins/cppeditor/cppeditor.h | 3 +++ src/plugins/cppeditor/cppeditorplugin.cpp | 2 +- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 0604edde96e..fe072bde82a 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -518,6 +518,7 @@ CPPEditorWidget::CPPEditorWidget(QWidget *parent) , m_objcEnabled(false) , m_commentsSettings(CppTools::CppToolsSettings::instance()->commentsSettings()) , m_followSymbolUnderCursor(new FollowSymbolUnderCursor(this)) + , m_preprocessorButton(0) { qRegisterMetaType("CppTools::SemanticInfo"); @@ -647,10 +648,13 @@ void CPPEditorWidget::createToolBar(CPPEditor *editor) connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateUses())); connect(this, SIGNAL(textChanged()), this, SLOT(updateUses())); - QToolButton *hashButton = new QToolButton(this); - hashButton->setText(QLatin1String("#")); - connect(hashButton, SIGNAL(clicked()), this, SLOT(showPreProcessorWidget())); - editor->insertExtraToolBarWidget(TextEditor::BaseTextEditor::Left, hashButton); + m_preprocessorButton = new QToolButton(this); + m_preprocessorButton->setText(QLatin1String("#")); + Core::Command *cmd = Core::ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG); + connect(cmd, SIGNAL(keySequenceChanged()), this, SLOT(updatePreprocessorButtonTooltip())); + updatePreprocessorButtonTooltip(); + connect(m_preprocessorButton, SIGNAL(clicked()), this, SLOT(showPreProcessorWidget())); + editor->insertExtraToolBarWidget(TextEditor::BaseTextEditor::Left, m_preprocessorButton); editor->insertExtraToolBarWidget(TextEditor::BaseTextEditor::Left, m_outlineCombo); } @@ -1012,6 +1016,14 @@ void CPPEditorWidget::onContentsChanged(int position, int charsRemoved, int char updateUses(); } +void CPPEditorWidget::updatePreprocessorButtonTooltip() +{ + QTC_ASSERT(m_preprocessorButton, return); + Core::Command *cmd = Core::ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG); + QTC_ASSERT(cmd, return); + m_preprocessorButton->setToolTip(cmd->action()->toolTip()); +} + void CPPEditorWidget::jumpToOutlineElement(int index) { QModelIndex modelIndex = m_outlineCombo->view()->currentIndex(); diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index ae1f57e31b2..5546a20faea 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE class QComboBox; class QSortFilterProxyModel; +class QToolButton; QT_END_NAMESPACE namespace CPlusPlus { @@ -175,6 +176,7 @@ private Q_SLOTS: void onFunctionDeclDefLinkFound(QSharedPointer link); void onDocumentUpdated(); void onContentsChanged(int position, int charsRemoved, int charsAdded); + void updatePreprocessorButtonTooltip(); void updateSemanticInfo(const CppTools::SemanticInfo &semanticInfo); void highlightSymbolUsages(int from, int to); @@ -259,6 +261,7 @@ private: QScopedPointer m_followSymbolUnderCursor; QString m_preProcessorAdditions; + QToolButton *m_preprocessorButton; }; } // namespace Internal diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index b9c66de4a1c..d7dd630a431 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -210,7 +210,7 @@ bool CppEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err contextMenu->addAction(cmd); cppToolsMenu->addAction(cmd); - QAction *openPreprocessorDialog = new QAction(tr("Additional Preprocessor Directives"), this); + QAction *openPreprocessorDialog = new QAction(tr("Additional Preprocessor Directives..."), this); cmd = ActionManager::registerAction(openPreprocessorDialog, Constants::OPEN_PREPROCESSOR_DIALOG, context); cmd->setDefaultKeySequence(QKeySequence()); From 4de3b9484051483f6f0329f1ec0c3feef325045c Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Wed, 23 Oct 2013 22:07:46 +0300 Subject: [PATCH 04/84] Crossify normalizePathName Denoise usages get{Short|Long}PathName are now static. They're not used anywhere except in normalizePathName. Change-Id: Ief277b6d828faadd98ec7faa39dd682bfaa8805f Reviewed-by: Friedemann Kleint Reviewed-by: hjk Reviewed-by: Eike Ziller --- src/libs/utils/fileutils.cpp | 58 +++++++++++++++++++ src/libs/utils/fileutils.h | 1 + src/libs/utils/winutils.cpp | 48 --------------- src/plugins/cpptools/cpptoolsplugin.cpp | 10 +--- src/plugins/debugger/cdb/cdbengine.cpp | 6 +- src/plugins/debugger/debuggerrunner.cpp | 9 +-- .../projectexplorer/applicationlauncher.cpp | 15 +---- src/plugins/projectexplorer/msvcparser.cpp | 10 +--- .../projectexplorer/projectwelcomepage.cpp | 14 ++--- .../propertyeditorqmlbackend.cpp | 10 +--- .../qmlprojectrunconfiguration.cpp | 12 ++-- .../qtsupport/gettingstartedwelcomepage.cpp | 5 +- src/plugins/welcome/welcomeplugin.cpp | 13 +---- 13 files changed, 83 insertions(+), 128 deletions(-) diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp index 80ef5bc5ff3..ef3b5c5e778 100644 --- a/src/libs/utils/fileutils.cpp +++ b/src/libs/utils/fileutils.cpp @@ -38,6 +38,10 @@ #include #include +#ifdef Q_OS_WIN +#include +#endif + namespace Utils { /*! \class Utils::FileUtils @@ -237,6 +241,60 @@ bool FileUtils::makeWritable(const FileName &path) return QFile::setPermissions(fileName, QFile::permissions(fileName) | QFile::WriteUser); } +#ifdef Q_OS_WIN +static QString getShortPathName(const QString &name) +{ + if (name.isEmpty()) + return name; + + // Determine length, then convert. + const LPCTSTR nameC = reinterpret_cast(name.utf16()); // MinGW + const DWORD length = GetShortPathNameW(nameC, NULL, 0); + if (length == 0) + return name; + QScopedArrayPointer buffer(new TCHAR[length]); + GetShortPathNameW(nameC, buffer.data(), length); + const QString rc = QString::fromUtf16(reinterpret_cast(buffer.data()), length - 1); + return rc; +} + +static QString getLongPathName(const QString &name) +{ + if (name.isEmpty()) + return name; + + // Determine length, then convert. + const LPCTSTR nameC = reinterpret_cast(name.utf16()); // MinGW + const DWORD length = GetLongPathNameW(nameC, NULL, 0); + if (length == 0) + return name; + QScopedArrayPointer buffer(new TCHAR[length]); + GetLongPathNameW(nameC, buffer.data(), length); + const QString rc = QString::fromUtf16(reinterpret_cast(buffer.data()), length - 1); + return rc; +} +#endif // Q_OS_WIN + +// makes sure that capitalization of directories is canonical on Windows. +// This mimics the logic in QDeclarative_isFileCaseCorrect +QString FileUtils::normalizePathName(const QString &name) +{ +#ifdef Q_OS_WIN + QString canonicalName = getShortPathName(name); + if (canonicalName.isEmpty()) + return name; + canonicalName = getLongPathName(canonicalName); + if (canonicalName.isEmpty()) + return name; + // Upper case drive letter + if (canonicalName.size() > 2 && canonicalName.at(1) == QLatin1Char(':')) + canonicalName[0] = canonicalName.at(0).toUpper(); + return canonicalName; +#else // Filesystem is case-insensitive only on Windows + return name; +#endif +} + QByteArray FileReader::fetchQrc(const QString &fileName) { QTC_ASSERT(fileName.startsWith(QLatin1Char(':')), return QByteArray()); diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h index 0cf1db64b18..0b19a913fbd 100644 --- a/src/libs/utils/fileutils.h +++ b/src/libs/utils/fileutils.h @@ -98,6 +98,7 @@ public: static QString shortNativePath(const FileName &path); static QString fileSystemFriendlyName(const QString &name); static bool makeWritable(const FileName &path); + static QString normalizePathName(const QString &name); }; class QTCREATOR_UTILS_EXPORT FileReader diff --git a/src/libs/utils/winutils.cpp b/src/libs/utils/winutils.cpp index cf54a24d4f3..59daad82df9 100644 --- a/src/libs/utils/winutils.cpp +++ b/src/libs/utils/winutils.cpp @@ -129,54 +129,6 @@ QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t, return rc; } -QTCREATOR_UTILS_EXPORT QString getShortPathName(const QString &name) -{ - if (name.isEmpty()) - return name; - - // Determine length, then convert. - const LPCTSTR nameC = reinterpret_cast(name.utf16()); // MinGW - const DWORD length = GetShortPathNameW(nameC, NULL, 0); - if (length == 0) - return name; - QScopedArrayPointer buffer(new TCHAR[length]); - GetShortPathNameW(nameC, buffer.data(), length); - const QString rc = QString::fromUtf16(reinterpret_cast(buffer.data()), length - 1); - return rc; -} - -QTCREATOR_UTILS_EXPORT QString getLongPathName(const QString &name) -{ - if (name.isEmpty()) - return name; - - // Determine length, then convert. - const LPCTSTR nameC = reinterpret_cast(name.utf16()); // MinGW - const DWORD length = GetLongPathNameW(nameC, NULL, 0); - if (length == 0) - return name; - QScopedArrayPointer buffer(new TCHAR[length]); - GetLongPathNameW(nameC, buffer.data(), length); - const QString rc = QString::fromUtf16(reinterpret_cast(buffer.data()), length - 1); - return rc; -} - -// makes sure that capitalization of directories is canonical. -// This mimics the logic in QDeclarative_isFileCaseCorrect -QTCREATOR_UTILS_EXPORT QString normalizePathName(const QString &name) -{ - QString canonicalName = getShortPathName(name); - if (canonicalName.isEmpty()) - return name; - canonicalName = getLongPathName(canonicalName); - if (canonicalName.isEmpty()) - return name; - // Upper case drive letter - if (canonicalName.size() > 2 && canonicalName.at(1) == QLatin1Char(':')) - canonicalName[0] = canonicalName.at(0).toUpper(); - return canonicalName; -} - QTCREATOR_UTILS_EXPORT bool winIs64BitSystem() { SYSTEM_INFO systemInfo; diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp index ff69f7746ae..b7206450326 100644 --- a/src/plugins/cpptools/cpptoolsplugin.cpp +++ b/src/plugins/cpptools/cpptoolsplugin.cpp @@ -51,11 +51,9 @@ #include #include +#include #include #include -#ifdef Q_OS_WIN -#include -#endif #include #include @@ -352,11 +350,7 @@ QString correspondingHeaderOrSource(const QString &fileName, bool *wasHeader) foreach (const QString &candidateDir, candidateDirs) { foreach (const QString &candidateFileName, candidateFileNames) { const QString candidateFilePath = candidateDir + QLatin1Char('/') + candidateFileName; -#ifdef Q_OS_WIN - const QString normalized = Utils::normalizePathName(candidateFilePath); -#else - const QString normalized = candidateFilePath; -#endif + const QString normalized = Utils::FileUtils::normalizePathName(candidateFilePath); const QFileInfo candidateFi(normalized); if (candidateFi.isFile()) { m_headerSourceMapping[fi.absoluteFilePath()] = candidateFi.absoluteFilePath(); diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 52331b4e185..5376b4c9143 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -2879,11 +2879,7 @@ CdbEngine::NormalizedSourceFileName CdbEngine::sourceMapNormalizeFileNameFromDeb const QString fileName = cdbSourcePathMapping(QDir::toNativeSeparators(f), m_sourcePathMappings, DebuggerToSource); // Up/lower case normalization according to Windows. -#ifdef Q_OS_WIN - QString normalized = Utils::normalizePathName(fileName); -#else - QString normalized = fileName; -#endif + const QString normalized = Utils::FileUtils::normalizePathName(fileName); if (debugSourceMapping) qDebug(" sourceMapNormalizeFileNameFromDebugger %s->%s", qPrintable(fileName), qPrintable(normalized)); // Check if it really exists, that is normalize worked and QFileInfo confirms it. diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp index a7d33fdb5ec..74a1d7efbf8 100644 --- a/src/plugins/debugger/debuggerrunner.cpp +++ b/src/plugins/debugger/debuggerrunner.cpp @@ -43,7 +43,6 @@ #ifdef Q_OS_WIN # include "shared/peutils.h" -# include #endif #include // For LocalApplication* @@ -55,6 +54,7 @@ #include #include +#include #include #include #include @@ -344,12 +344,9 @@ static DebuggerStartParameters localStartParameters(RunConfiguration *runConfigu if (!fillParameters(&sp, kit, errorMessage)) return sp; sp.environment = environment->environment(); - sp.workingDirectory = rc->workingDirectory(); -#if defined(Q_OS_WIN) - // Work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch' ...) - sp.workingDirectory = normalizePathName(sp.workingDirectory); -#endif + // Normalize to work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch'...) + sp.workingDirectory = FileUtils::normalizePathName(rc->workingDirectory()); sp.executable = rc->executable(); if (sp.executable.isEmpty()) diff --git a/src/plugins/projectexplorer/applicationlauncher.cpp b/src/plugins/projectexplorer/applicationlauncher.cpp index a3667fbeceb..e04b94731d8 100644 --- a/src/plugins/projectexplorer/applicationlauncher.cpp +++ b/src/plugins/projectexplorer/applicationlauncher.cpp @@ -35,10 +35,8 @@ #include #include +#include #include -#ifdef Q_OS_WIN -#include -#endif #include @@ -131,19 +129,10 @@ ApplicationLauncher::~ApplicationLauncher() void ApplicationLauncher::setWorkingDirectory(const QString &dir) { -#ifdef Q_OS_WIN // Work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch' ...) - const QString fixedPath = Utils::normalizePathName(dir); -#else -# define fixedPath dir -#endif - + const QString fixedPath = Utils::FileUtils::normalizePathName(dir); d->m_guiProcess.setWorkingDirectory(fixedPath); d->m_consoleProcess.setWorkingDirectory(fixedPath); - -#ifndef Q_OS_WIN -# undef fixedPath -#endif } void ApplicationLauncher::setEnvironment(const Utils::Environment &env) diff --git a/src/plugins/projectexplorer/msvcparser.cpp b/src/plugins/projectexplorer/msvcparser.cpp index 0bc41b7b842..653d9e30f7c 100644 --- a/src/plugins/projectexplorer/msvcparser.cpp +++ b/src/plugins/projectexplorer/msvcparser.cpp @@ -31,9 +31,7 @@ #include "projectexplorerconstants.h" #include -#ifdef Q_OS_WIN -#include -#endif +#include static const char FILE_POS_PATTERN[] = "(cl|LINK|.+) : "; static const char ERROR_PATTERN[] = "[A-Z]+\\d\\d\\d\\d ?:"; @@ -58,11 +56,7 @@ static QPair parseFileName(const QString &input) } } } -#ifdef Q_OS_WIN - const QString normalized = Utils::normalizePathName(fileName); -#else - const QString normalized = fileName; -#endif + const QString normalized = Utils::FileUtils::normalizePathName(fileName); return qMakePair(Utils::FileName::fromUserInput(normalized), linenumber); } diff --git a/src/plugins/projectexplorer/projectwelcomepage.cpp b/src/plugins/projectexplorer/projectwelcomepage.cpp index db71fccfa86..fa2b24a9959 100644 --- a/src/plugins/projectexplorer/projectwelcomepage.cpp +++ b/src/plugins/projectexplorer/projectwelcomepage.cpp @@ -29,8 +29,6 @@ #include "projectwelcomepage.h" -#include - #include #include #include @@ -42,9 +40,8 @@ #include #include -#ifdef Q_OS_WIN -#include -#endif +#include +#include namespace ProjectExplorer { namespace Internal { @@ -225,12 +222,9 @@ void ProjectWelcomePage::facilitateQml(QQmlEngine *engine) QUrl ProjectWelcomePage::pageLocation() const { - QString resourcePath = Core::ICore::resourcePath(); -#ifdef Q_OS_WIN // normalize paths so QML doesn't freak out if it's wrongly capitalized on Windows - resourcePath = Utils::normalizePathName(resourcePath); -#endif - return QUrl::fromLocalFile(resourcePath + QLatin1String("/welcomescreen/develop.qml")); + const QString resourcePath = Utils::FileUtils::normalizePathName(Core::ICore::resourcePath()); + return QUrl::fromLocalFile(resourcePath + QLatin1String("/welcomescreen/develop.qml")); } ProjectWelcomePage::Id ProjectWelcomePage::id() const diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp index 05b2511778b..67376a966b9 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp @@ -44,9 +44,7 @@ #include -#ifdef Q_OS_WIN -#include -#endif +#include enum { debug = false @@ -95,12 +93,8 @@ static QObject *variantToQObject(const QVariant &value) static QString applicationDirPath() { -#ifdef Q_OS_WIN // normalize paths so QML doesn't freak out if it's wrongly capitalized on Windows - return Utils::normalizePathName(QCoreApplication::applicationDirPath()); -#else - return QCoreApplication::applicationDirPath(); -#endif + return Utils::FileUtils::normalizePathName(QCoreApplication::applicationDirPath()); } #ifdef Q_OS_MAC diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp index f133d802b9d..2d17f24d5b0 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp @@ -37,11 +37,13 @@ #include #include #include -#include #include #include #include +#include +#include + #ifdef Q_OS_WIN #include #endif @@ -159,13 +161,7 @@ QString QmlProjectRunConfiguration::workingDirectory() const is exactly like the capitalization on disk.*/ QString QmlProjectRunConfiguration::canonicalCapsPath(const QString &fileName) { - QString canonicalPath = QFileInfo(fileName).canonicalFilePath(); - -#if defined(Q_OS_WIN) - canonicalPath = Utils::normalizePathName(canonicalPath); -#endif - - return canonicalPath; + return Utils::FileUtils::normalizePathName(QFileInfo(fileName).canonicalFilePath()); } diff --git a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp index a514b0d3b0b..54d4ea1123d 100644 --- a/src/plugins/qtsupport/gettingstartedwelcomepage.cpp +++ b/src/plugins/qtsupport/gettingstartedwelcomepage.cpp @@ -241,11 +241,8 @@ QString ExamplesWelcomePage::title() const QUrl ExamplesWelcomePage::pageLocation() const { - QString resourcePath = Core::ICore::resourcePath(); -#ifdef Q_OS_WIN // normalize paths so QML doesn't freak out if it's wrongly capitalized on Windows - resourcePath = Utils::normalizePathName(resourcePath); -#endif + const QString resourcePath = Utils::FileUtils::normalizePathName(Core::ICore::resourcePath()); if (m_showExamples) return QUrl::fromLocalFile(resourcePath + QLatin1String("/welcomescreen/examples.qml")); else diff --git a/src/plugins/welcome/welcomeplugin.cpp b/src/plugins/welcome/welcomeplugin.cpp index 202645a5d43..da1aa21fb38 100644 --- a/src/plugins/welcome/welcomeplugin.cpp +++ b/src/plugins/welcome/welcomeplugin.cpp @@ -40,6 +40,7 @@ #include +#include #include #include #include @@ -208,22 +209,14 @@ void WelcomeMode::facilitateQml(QQmlEngine * /*engine*/) static QString applicationDirPath() { -#ifdef Q_OS_WIN // normalize paths so QML doesn't freak out if it's wrongly capitalized on Windows - return Utils::normalizePathName(QCoreApplication::applicationDirPath()); -#else - return QCoreApplication::applicationDirPath(); -#endif + return Utils::FileUtils::normalizePathName(QCoreApplication::applicationDirPath()); } static QString resourcePath() { -#ifdef Q_OS_WIN // normalize paths so QML doesn't freak out if it's wrongly capitalized on Windows - return Utils::normalizePathName(Core::ICore::resourcePath()); -#else - return Core::ICore::resourcePath(); -#endif + return Utils::FileUtils::normalizePathName(Core::ICore::resourcePath()); } void WelcomeMode::initPlugins() From 119548a0ffadee65fe6798cf4ed249b6cfcaab09 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 17 Oct 2013 14:52:10 +0200 Subject: [PATCH 05/84] Remove most leading/trailing blanks from translated messages. They are a hassle for translators and reviewers alike. Change-Id: I363138212b692cf75fe1605df8af3721315d37e1 Reviewed-by: hjk --- src/plugins/android/androiddeployqtstep.cpp | 2 +- src/plugins/android/androiddeploystep.cpp | 2 +- src/plugins/android/androidpackagecreationstep.cpp | 2 +- src/plugins/clearcase/settingspage.cpp | 3 ++- .../cmakeprojectmanager/cmakeopenprojectwizard.cpp | 9 +++++---- .../cmakeprojectmanager/cmakerunconfiguration.cpp | 7 ++++++- src/plugins/coreplugin/basefilewizard.cpp | 12 ++++++------ src/plugins/cppeditor/cppincludehierarchymodel.cpp | 4 ++-- src/plugins/debugger/debuggerdialogs.cpp | 2 +- src/plugins/debugger/debuggerengine.cpp | 4 ++-- src/plugins/debugger/debuggerrunner.cpp | 2 +- src/plugins/debugger/gdb/gdbengine.cpp | 6 +++--- src/plugins/debugger/lldb/lldbengine.cpp | 2 +- src/plugins/debugger/pdb/pdbengine.cpp | 2 +- src/plugins/debugger/qml/qmlengine.cpp | 2 +- src/plugins/debugger/qml/qmlinspectoragent.cpp | 3 ++- src/plugins/debugger/watchdata.cpp | 3 ++- src/plugins/debugger/watchwindow.cpp | 2 +- src/plugins/fakevim/fakevimhandler.cpp | 2 +- src/plugins/git/gerrit/gerritdialog.cpp | 2 +- src/plugins/git/gitclient.cpp | 4 ++-- src/plugins/projectexplorer/copytaskhandler.cpp | 4 ++-- .../projectexplorer/customparserconfigdialog.cpp | 2 +- .../devicesupport/desktopprocesssignaloperation.cpp | 12 +++++++----- src/plugins/projectexplorer/targetsettingspanel.cpp | 2 +- .../qmldesigner/components/debugview/debugview.cpp | 4 ++-- src/plugins/qmlprofiler/qmlprofilereventview.cpp | 2 +- .../qnx/blackberrydebugtokenrequestdialog.cpp | 2 +- .../qnx/blackberrydeviceconfigurationwidget.cpp | 2 +- .../qnx/blackberrydeviceconfigurationwizardpages.cpp | 6 ++++-- src/plugins/qnx/blackberrysetupwizard.cpp | 4 ++-- .../remotelinuxrunconfigurationfactory.cpp | 2 +- .../remotelinux/remotelinuxsignaloperation.cpp | 3 ++- src/plugins/valgrind/memcheck/memcheckrunner.cpp | 4 ++-- .../qtcreatorcrashhandler/crashhandlerdialog.cpp | 2 +- 35 files changed, 71 insertions(+), 57 deletions(-) diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index 405f317ef50..75e39a6f9ec 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -336,7 +336,7 @@ void AndroidDeployQtStep::runCommand(const QString &program, const QStringList & QString mainMessage = tr("Packaging Error: Command '%1 %2' failed.") .arg(program).arg(arguments.join(QLatin1String(" "))); if (buildProc.error() != QProcess::UnknownError) - mainMessage += tr(" Reason: %1").arg(buildProc.errorString()); + mainMessage += QLatin1Char(' ') + tr("Reason: %1").arg(buildProc.errorString()); else mainMessage += tr("Exit code: %1").arg(buildProc.exitCode()); emit addOutput(mainMessage, BuildStep::ErrorMessageOutput); diff --git a/src/plugins/android/androiddeploystep.cpp b/src/plugins/android/androiddeploystep.cpp index d8264898d87..dcdb8968ffc 100644 --- a/src/plugins/android/androiddeploystep.cpp +++ b/src/plugins/android/androiddeploystep.cpp @@ -239,7 +239,7 @@ bool AndroidDeployStep::runCommand(QProcess *buildProc, QString mainMessage = tr("Packaging Error: Command '%1 %2' failed.") .arg(program).arg(arguments.join(QLatin1String(" "))); if (buildProc->error() != QProcess::UnknownError) - mainMessage += tr(" Reason: %1").arg(buildProc->errorString()); + mainMessage += QLatin1Char(' ') + tr("Reason: %1").arg(buildProc->errorString()); else mainMessage += tr("Exit code: %1").arg(buildProc->exitCode()); writeOutput(mainMessage, BuildStep::ErrorMessageOutput); diff --git a/src/plugins/android/androidpackagecreationstep.cpp b/src/plugins/android/androidpackagecreationstep.cpp index 285f7b3ee56..6f4a068ea58 100644 --- a/src/plugins/android/androidpackagecreationstep.cpp +++ b/src/plugins/android/androidpackagecreationstep.cpp @@ -803,7 +803,7 @@ bool AndroidPackageCreationStep::runCommand(QProcess *buildProc QString mainMessage = tr("Packaging Error: Command '%1 %2' failed.") .arg(program).arg(arguments.join(QLatin1String(" "))); if (buildProc->error() != QProcess::UnknownError) - mainMessage += tr(" Reason: %1").arg(buildProc->errorString()); + mainMessage += QLatin1Char(' ') + tr("Reason: %1").arg(buildProc->errorString()); else mainMessage += tr("Exit code: %1").arg(buildProc->exitCode()); raiseError(mainMessage); diff --git a/src/plugins/clearcase/settingspage.cpp b/src/plugins/clearcase/settingspage.cpp index 983dac4845f..2dc0ad0019b 100644 --- a/src/plugins/clearcase/settingspage.cpp +++ b/src/plugins/clearcase/settingspage.cpp @@ -86,7 +86,8 @@ void SettingsPageWidget::setSettings(const ClearCaseSettings &s) } else { QString diffWarning = tr("In order to use External diff, 'diff' command needs to be accessible."); if (HostOsInfo::isWindowsHost()) { - diffWarning.append(tr(" DiffUtils is available for free download " + diffWarning += QLatin1Char(' '); + diffWarning.append(tr("DiffUtils is available for free download " "here. " "Please extract it to a directory in your PATH.")); } diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp index a68a919c1d3..f3a49624e9d 100644 --- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp @@ -455,7 +455,7 @@ ShadowBuildPage::ShadowBuildPage(CMakeOpenProjectWizard *cmakeWizard, bool chang QLabel *label = new QLabel(this); label->setWordWrap(true); if (change) - label->setText(tr("Please enter the directory in which you want to build your project. ")); + label->setText(tr("Please enter the directory in which you want to build your project.") + QLatin1Char(' ')); else label->setText(tr("Please enter the directory in which you want to build your project. " "Qt Creator recommends to not use the source directory for building. " @@ -507,13 +507,14 @@ void ChooseCMakePage::updateErrorText() } else { QString text = tr("Specify the path to the CMake executable. No CMake executable was found in the path."); if (!cmakeExecutable.isEmpty()) { + text += QLatin1Char(' '); QFileInfo fi(cmakeExecutable); if (!fi.exists()) - text += tr(" The CMake executable (%1) does not exist.").arg(cmakeExecutable); + text += tr("The CMake executable (%1) does not exist.").arg(cmakeExecutable); else if (!fi.isExecutable()) - text += tr(" The path %1 is not an executable.").arg(cmakeExecutable); + text += tr("The path %1 is not an executable.").arg(cmakeExecutable); else - text += tr(" The path %1 is not a valid CMake executable.").arg(cmakeExecutable); + text += tr("The path %1 is not a valid CMake executable.").arg(cmakeExecutable); } m_cmakeLabel->setText(text); } diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp index e256fbe4f0c..50e5a4d6afe 100644 --- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp @@ -193,7 +193,12 @@ QString CMakeRunConfiguration::defaultDisplayName() const { if (m_title.isEmpty()) return tr("Run CMake kit"); - return m_title + (m_enabled ? QString() : tr(" (disabled)")); + QString result = m_title; + if (!m_enabled) { + result += QLatin1Char(' '); + result += tr("(disabled)"); + } + return result; } QWidget *CMakeRunConfiguration::createConfigurationWidget() diff --git a/src/plugins/coreplugin/basefilewizard.cpp b/src/plugins/coreplugin/basefilewizard.cpp index bb26839348f..9ba83657a57 100644 --- a/src/plugins/coreplugin/basefilewizard.cpp +++ b/src/plugins/coreplugin/basefilewizard.cpp @@ -407,9 +407,9 @@ BaseFileWizard::OverwriteResult BaseFileWizard::promptOverwrite(GeneratedFiles * QStringList existingFiles; bool oddStuffFound = false; - static const QString readOnlyMsg = tr(" [read only]"); - static const QString directoryMsg = tr(" [folder]"); - static const QString symLinkMsg = tr(" [symbolic link]"); + static const QString readOnlyMsg = tr("[read only]"); + static const QString directoryMsg = tr("[folder]"); + static const QString symLinkMsg = tr("[symbolic link]"); foreach (const GeneratedFile &file, *files) { const QFileInfo fi(file.path()); @@ -432,17 +432,17 @@ BaseFileWizard::OverwriteResult BaseFileWizard::promptOverwrite(GeneratedFiles * do { if (fi.isDir()) { oddStuffFound = true; - fileNamesMsgPart += directoryMsg; + fileNamesMsgPart += QLatin1Char(' ') + directoryMsg; break; } if (fi.isSymLink()) { oddStuffFound = true; - fileNamesMsgPart += symLinkMsg; + fileNamesMsgPart += QLatin1Char(' ') + symLinkMsg; break; } if (!fi.isWritable()) { oddStuffFound = true; - fileNamesMsgPart += readOnlyMsg; + fileNamesMsgPart += QLatin1Char(' ') + readOnlyMsg; } } while (false); } diff --git a/src/plugins/cppeditor/cppincludehierarchymodel.cpp b/src/plugins/cppeditor/cppincludehierarchymodel.cpp index 7b6909f6179..7709bed2d57 100644 --- a/src/plugins/cppeditor/cppincludehierarchymodel.cpp +++ b/src/plugins/cppeditor/cppincludehierarchymodel.cpp @@ -117,11 +117,11 @@ QVariant CppIncludeHierarchyModel::data(const QModelIndex &index, int role) cons if (role == Qt::DisplayRole) { if ((item == m_includesItem && m_includesItem->childCount() == 0) || (item == m_includedByItem && m_includedByItem->childCount() == 0)) { - return QString(item->fileName() + tr(" (none)")); + return QString(item->fileName() + QLatin1Char(' ') + tr("(none)")); } if (item->isCyclic()) - return QString(item->fileName() + tr(" (cyclic)")); + return QString(item->fileName() + QLatin1Char(' ') + tr("(cyclic)")); return item->fileName(); } diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp index 13f292de991..8f80194ce8d 100644 --- a/src/plugins/debugger/debuggerdialogs.cpp +++ b/src/plugins/debugger/debuggerdialogs.cpp @@ -633,7 +633,7 @@ AddressDialog::AddressDialog(QWidget *parent) : setWindowTitle(tr("Select Start Address")); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); QHBoxLayout *hLayout = new QHBoxLayout; - hLayout->addWidget(new QLabel(tr("Enter an address: "))); + hLayout->addWidget(new QLabel(tr("Enter an address:") + QLatin1Char(' '))); hLayout->addWidget(m_lineEdit); QVBoxLayout *vLayout = new QVBoxLayout; vLayout->addLayout(hLayout); diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 59058769bf4..b473866ac05 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -1676,9 +1676,9 @@ QString DebuggerEngine::msgInterrupted() void DebuggerEngine::showStoppedBySignalMessageBox(QString meaning, QString name) { if (name.isEmpty()) - name = tr(" ", "name"); + name = QLatin1Char(' ') + tr("", "name") + QLatin1Char(' '); if (meaning.isEmpty()) - meaning = tr(" ", "meaning"); + meaning = QLatin1Char(' ') + tr("", "meaning") + QLatin1Char(' '); const QString msg = tr("

The inferior stopped because it received a " "signal from the Operating System.

" "" diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp index 74a1d7efbf8..59c2158dcff 100644 --- a/src/plugins/debugger/debuggerrunner.cpp +++ b/src/plugins/debugger/debuggerrunner.cpp @@ -382,7 +382,7 @@ static DebuggerStartParameters localStartParameters(RunConfiguration *runConfigu || server.listen(QHostAddress::LocalHostIPv6); if (!canListen) { if (errorMessage) - *errorMessage = DebuggerPlugin::tr("Not enough free ports for QML debugging. "); + *errorMessage = DebuggerPlugin::tr("Not enough free ports for QML debugging.") + QLatin1Char(' '); return sp; } sp.qmlServerAddress = server.serverAddress().toString(); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 7e8febf779c..f3755adcce2 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -296,7 +296,7 @@ QString GdbEngine::errorMessage(QProcess::ProcessError error) return tr("An error occurred when attempting to read from " "the gdb process. For example, the process may not be running."); default: - return tr("An unknown error in the gdb process occurred. "); + return tr("An unknown error in the gdb process occurred."); } } @@ -338,7 +338,7 @@ static inline QString msgWinException(const QByteArray &data, unsigned *exCodeIn const quint64 address = data.mid(addressPos).trimmed().toULongLong(0, 0); QString rc; QTextStream str(&rc); - str << GdbEngine::tr("An exception was triggered: "); + str << GdbEngine::tr("An exception was triggered:") << ' '; formatWindowsException(exCode, address, 0, 0, 0, str); str << '.'; return rc; @@ -5215,7 +5215,7 @@ void GdbEngine::handleBreakOnQFatal(const GdbResponse &response) void GdbEngine::notifyInferiorSetupFailed(const QString &msg) { - showStatusMessage(tr("Failed to start application: ") + msg); + showStatusMessage(tr("Failed to start application:") + QLatin1Char(' ') + msg); if (state() == EngineSetupFailed) { showMessage(_("INFERIOR START FAILED, BUT ADAPTER DIED ALREADY")); return; // Adapter crashed meanwhile, so this notification is meaningless. diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 9526e5e6081..f6316631232 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -812,7 +812,7 @@ QString LldbEngine::errorMessage(QProcess::ProcessError error) const return tr("An error occurred when attempting to read from " "the Lldb process. For example, the process may not be running."); default: - return tr("An unknown error in the Lldb process occurred. "); + return tr("An unknown error in the Lldb process occurred.") + QLatin1Char(' '); } } diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp index 702bd1cefa9..71453f46f05 100644 --- a/src/plugins/debugger/pdb/pdbengine.cpp +++ b/src/plugins/debugger/pdb/pdbengine.cpp @@ -596,7 +596,7 @@ QString PdbEngine::errorMessage(QProcess::ProcessError error) const return tr("An error occurred when attempting to read from " "the Pdb process. For example, the process may not be running."); default: - return tr("An unknown error in the Pdb process occurred. "); + return tr("An unknown error in the Pdb process occurred.") + QLatin1Char(' '); } } diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index 89929350c73..4308c42c48c 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -1167,7 +1167,7 @@ void QmlEngine::updateCurrentContext() QmlJS::ConsoleManagerInterface *consoleManager = qmlConsoleManager(); if (consoleManager) - consoleManager->setContext(tr("Context: ").append(context)); + consoleManager->setContext(tr("Context:") + QLatin1Char(' ') + context); } void QmlEngine::appendDebugOutput(QtMsgType type, const QString &message, diff --git a/src/plugins/debugger/qml/qmlinspectoragent.cpp b/src/plugins/debugger/qml/qmlinspectoragent.cpp index 68974bf9d46..c1e4f41b4f4 100644 --- a/src/plugins/debugger/qml/qmlinspectoragent.cpp +++ b/src/plugins/debugger/qml/qmlinspectoragent.cpp @@ -454,7 +454,8 @@ void QmlInspectorAgent::onResult(quint32 queryId, const QVariant &value, } else if (type == "SET_BINDING_R" || type == "RESET_BINDING_R" || type == "SET_METHOD_BODY_R") { - QString msg = QLatin1String(type) + tr("Success: "); + QString msg = QLatin1String(type) + tr("Success:"); + msg += QLatin1Char(' '); msg += value.toBool() ? QLatin1Char('1') : QLatin1Char('0'); if (!value.toBool()) emit automaticUpdateFailed(); diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp index 8cad1a3c13c..cead6220a3d 100644 --- a/src/plugins/debugger/watchdata.cpp +++ b/src/plugins/debugger/watchdata.cpp @@ -392,7 +392,8 @@ QString WatchData::toToolTip() const } if (val.size() > 1000) { val.truncate(1000); - val += tr(" ... "); + val += QLatin1Char(' '); + val += tr("... "); } formatToolTipRow(str, tr("Value"), val); if (address) diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index 1619cfeb2fc..7539387542f 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -649,7 +649,7 @@ void WatchTreeView::contextMenuEvent(QContextMenuEvent *ev) QString msg = (individualFormat == -1 && typeFormat != -1) ? tr("Use Format for Type (Currently %1)") .arg(alternativeFormats.at(typeFormat)) - : tr("Use Display Format Based on Type "); + : tr("Use Display Format Based on Type") + QLatin1Char(' '); clearIndividualFormatAction = formatMenu.addAction(spacer + msg); clearIndividualFormatAction->setCheckable(true); clearIndividualFormatAction->setChecked(individualFormat == -1); diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index ec71ccc050b..a2fa1f83093 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -5396,7 +5396,7 @@ bool FakeVimHandler::Private::handleExSetCommand(const ExCommand &cmd) if (!error.isEmpty()) showMessage(MessageError, error); } else { - showMessage(MessageError, FakeVimHandler::tr("Unknown option: ") + cmd.args); + showMessage(MessageError, FakeVimHandler::tr("Unknown option:") + QLatin1Char(' ') + cmd.args); } updateMiniBuffer(); updateEditor(); diff --git a/src/plugins/git/gerrit/gerritdialog.cpp b/src/plugins/git/gerrit/gerritdialog.cpp index 27f84d55beb..8859af24e7c 100644 --- a/src/plugins/git/gerrit/gerritdialog.cpp +++ b/src/plugins/git/gerrit/gerritdialog.cpp @@ -101,7 +101,7 @@ GerritDialog::GerritDialog(const QSharedPointer &p, , m_filterLineEdit(new Utils::FilterLineEdit) , m_repositoryChooser(new Utils::PathChooser) , m_buttonBox(new QDialogButtonBox(QDialogButtonBox::Close)) - , m_repositoryChooserLabel(new QLabel(tr("Apply in: "), this)) + , m_repositoryChooserLabel(new QLabel(tr("Apply in:") + QLatin1Char(' '), this)) , m_fetchRunning(false) { setWindowTitle(tr("Gerrit %1@%2").arg(p->user, p->host)); diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 70abaa0f6f1..ac047f0ac76 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -2706,7 +2706,7 @@ void GitClient::continuePreviousGitCommand(const QString &workingDirectory, == GitClient::StatusChanged; } if (!hasChanges) - msgBoxText.prepend(tr("No changes found. ")); + msgBoxText.prepend(tr("No changes found.") + QLatin1Char(' ')); QMessageBox msgBox(QMessageBox::Question, msgBoxTitle, msgBoxText, QMessageBox::NoButton, Core::ICore::mainWindow()); if (hasChanges || isRebase) @@ -2747,7 +2747,7 @@ QString GitClient::extendedShowDescription(const QString &workingDirectory, cons if (branchCount > 20) { const int leave = 10; //: Displayed after the untranslated message "Branches: branch1, branch2 'and %n more'" in git show. - moreBranches = tr(" and %n more", 0, branchCount - leave); + moreBranches = QLatin1Char(' ') + tr("and %n more", 0, branchCount - leave); branches.erase(branches.begin() + leave, branches.end()); } if (!branches.isEmpty()) { diff --git a/src/plugins/projectexplorer/copytaskhandler.cpp b/src/plugins/projectexplorer/copytaskhandler.cpp index 58c3f691ad2..1b641a7ce17 100644 --- a/src/plugins/projectexplorer/copytaskhandler.cpp +++ b/src/plugins/projectexplorer/copytaskhandler.cpp @@ -45,11 +45,11 @@ void CopyTaskHandler::handle(const ProjectExplorer::Task &task) switch (task.type) { case Task::Error: //: Task is of type: error - type = tr("error: "); + type = tr("error:") + QLatin1Char(' '); break; case Task::Warning: //: Task is of type: warning - type = tr("warning: "); + type = tr("warning:") + QLatin1Char(' '); break; default: break; diff --git a/src/plugins/projectexplorer/customparserconfigdialog.cpp b/src/plugins/projectexplorer/customparserconfigdialog.cpp index b45c745c8f9..2a6c0f72024 100644 --- a/src/plugins/projectexplorer/customparserconfigdialog.cpp +++ b/src/plugins/projectexplorer/customparserconfigdialog.cpp @@ -147,7 +147,7 @@ void CustomParserConfigDialog::changed() int pos = rx.indexIn(ui->errorMessage->text()); if (rx.isEmpty() || !rx.isValid() || pos < 0) { - QString error = QLatin1String("") + tr("Not applicable: "); + QString error = QLatin1String("") + tr("Not applicable:") + QLatin1Char(' '); if (rx.isEmpty()) error += tr("Pattern is empty."); else if (!rx.isValid()) diff --git a/src/plugins/projectexplorer/devicesupport/desktopprocesssignaloperation.cpp b/src/plugins/projectexplorer/devicesupport/desktopprocesssignaloperation.cpp index c2d736b3f51..719739bce28 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopprocesssignaloperation.cpp +++ b/src/plugins/projectexplorer/devicesupport/desktopprocesssignaloperation.cpp @@ -85,14 +85,16 @@ void DesktopProcessSignalOperation::appendMsgCannotKill(int pid, const QString & { if (!m_errorMessage.isEmpty()) m_errorMessage += QChar::fromLatin1('\n'); - m_errorMessage += tr("Cannot kill process with pid %1: %3 ").arg(pid).arg(why); + m_errorMessage += tr("Cannot kill process with pid %1: %3").arg(pid).arg(why); + m_errorMessage += QLatin1Char(' '); } void DesktopProcessSignalOperation::appendMsgCannotInterrupt(int pid, const QString &why) { if (!m_errorMessage.isEmpty()) m_errorMessage += QChar::fromLatin1('\n'); - m_errorMessage += tr("Cannot interrupt process with pid %1: %3 ").arg(pid).arg(why); + m_errorMessage += tr("Cannot interrupt process with pid %1: %3").arg(pid).arg(why); + m_errorMessage += QLatin1Char(' '); } void DesktopProcessSignalOperation::killProcessSilently(int pid) @@ -165,8 +167,8 @@ GDB 32bit | Api | Api | N/A | Win32 m_specialInterrupt == Win64Interrupt && creatorIs64Bit || m_specialInterrupt == Win32Interrupt && !creatorIs64Bit) { if (!DebugBreakProcess(inferior)) { - appendMsgCannotInterrupt(pid, tr("DebugBreakProcess failed: ") - + Utils::winErrorMessage(GetLastError())); + appendMsgCannotInterrupt(pid, tr("DebugBreakProcess failed:") + + QLatin1Char(' ') + Utils::winErrorMessage(GetLastError())); } } else if (m_specialInterrupt == Win32Interrupt || m_specialInterrupt == Win64Interrupt) { QString executable = QCoreApplication::applicationDirPath(); @@ -189,7 +191,7 @@ GDB 32bit | Api | Api | N/A | Win32 break; default: appendMsgCannotInterrupt(pid, QDir::toNativeSeparators(executable) - + tr(" could not break the process.")); + + QLatin1Char(' ') + tr("could not break the process.")); break; } } diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp index 504871cb5b6..95a99377a0e 100644 --- a/src/plugins/projectexplorer/targetsettingspanel.cpp +++ b/src/plugins/projectexplorer/targetsettingspanel.cpp @@ -418,7 +418,7 @@ Target *TargetSettingsPanelWidget::cloneTarget(Target *sourceTarget, Kit *k) if (!runconfigurationError.isEmpty()) { if (!error.isEmpty()) error.append(QLatin1Char('\n')); - error += tr("Run configurations ") + error += tr("Run configurations") + QLatin1Char(' ') + runconfigurationError.join(QLatin1String("\n")); } diff --git a/src/plugins/qmldesigner/components/debugview/debugview.cpp b/src/plugins/qmldesigner/components/debugview/debugview.cpp index 2b7823ccbe2..013b4a2f567 100644 --- a/src/plugins/qmldesigner/components/debugview/debugview.cpp +++ b/src/plugins/qmldesigner/components/debugview/debugview.cpp @@ -147,8 +147,8 @@ void DebugView::nodeIdChanged(const ModelNode &node, const QString &newId, const QString string; message.setString(&string); message << node; - message << tr("New Id: ") << newId << lineBreak; - message << tr("Old Id: ") << oldId << lineBreak; + message << tr("New Id:") << ' ' << newId << lineBreak; + message << tr("Old Id:") << ' ' << oldId << lineBreak; log(tr("Node id changed:"), string); } } diff --git a/src/plugins/qmlprofiler/qmlprofilereventview.cpp b/src/plugins/qmlprofiler/qmlprofilereventview.cpp index 01d8504510a..6790478a52a 100644 --- a/src/plugins/qmlprofiler/qmlprofilereventview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilereventview.cpp @@ -524,7 +524,7 @@ void QmlProfilerEventsMainView::parseModelProxy() QString toolTipText; if (event.eventType == Binding) { if (event.bindingType == (int)OptimizedBinding) { - typeString = typeString + tr(" (Opt)"); + typeString = typeString + QLatin1Char(' ') + tr("(Opt)"); toolTipText = tr("Binding is evaluated by the optimized engine."); } else if (event.bindingType == (int)V8Binding) { toolTipText = tr("Binding not optimized (e.g. has side effects or assignments,\n" diff --git a/src/plugins/qnx/blackberrydebugtokenrequestdialog.cpp b/src/plugins/qnx/blackberrydebugtokenrequestdialog.cpp index d4011d246b6..37d8a199e26 100644 --- a/src/plugins/qnx/blackberrydebugtokenrequestdialog.cpp +++ b/src/plugins/qnx/blackberrydebugtokenrequestdialog.cpp @@ -191,7 +191,7 @@ void BlackBerryDebugTokenRequestDialog::expandPath() void BlackBerryDebugTokenRequestDialog::debugTokenArrived(int status) { - QString errorString = tr("Failed to request debug token: "); + QString errorString = tr("Failed to request debug token:") + QLatin1Char(' '); switch (status) { case BlackBerryDebugTokenRequester::Success: diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwidget.cpp b/src/plugins/qnx/blackberrydeviceconfigurationwidget.cpp index 76c02a33031..cb762f41de0 100644 --- a/src/plugins/qnx/blackberrydeviceconfigurationwidget.cpp +++ b/src/plugins/qnx/blackberrydeviceconfigurationwidget.cpp @@ -165,7 +165,7 @@ void BlackBerryDeviceConfigurationWidget::uploadFinished(int status) { progressDialog->hide(); - QString errorString = tr("Failed to upload debug token: "); + QString errorString = tr("Failed to upload debug token:") + QLatin1Char(' '); switch (status) { case BlackBerryDebugTokenUploader::Success: diff --git a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp index 342a2bd93f3..96b4c48687c 100644 --- a/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp +++ b/src/plugins/qnx/blackberrydeviceconfigurationwizardpages.cpp @@ -290,7 +290,8 @@ void BlackBerryDeviceConfigurationWizardQueryPage::sshKeysGenerationFailed(const if (m_state != GeneratingSshKey) return; - QString message = tr("Failed generating SSH key needed for securing connection to a device. Error: "); + QString message = tr("Failed generating SSH key needed for securing connection to a device. Error:"); + message += QLatin1Char(' '); message.append(error); setState(Done, message); } @@ -310,7 +311,8 @@ void BlackBerryDeviceConfigurationWizardQueryPage::processSshKeys(const QByteArr if (! BlackBerryDeviceConnectionManager::instance()->hasValidSSHKeys()) { QString error; if (!BlackBerryDeviceConnectionManager::instance()->setSSHKeys(privateKey, publicKey, &error)) { - QString message = tr("Failed saving SSH key needed for securing connection to a device. Error: "); + QString message = tr("Failed saving SSH key needed for securing connection to a device. Error:"); + message += QLatin1Char(' '); message.append(error); setState(Done, message); return; diff --git a/src/plugins/qnx/blackberrysetupwizard.cpp b/src/plugins/qnx/blackberrysetupwizard.cpp index 43cc73a7c04..e5214b0a0f3 100644 --- a/src/plugins/qnx/blackberrysetupwizard.cpp +++ b/src/plugins/qnx/blackberrysetupwizard.cpp @@ -176,7 +176,7 @@ void BlackBerrySetupWizard::certificateCreated(int status) void BlackBerrySetupWizard::debugTokenArrived(int status) { - QString errorString = tr("Failed to request debug token: "); + QString errorString = tr("Failed to request debug token:") + QLatin1Char(' '); switch (status) { case BlackBerryDebugTokenRequester::Success: @@ -222,7 +222,7 @@ void BlackBerrySetupWizard::debugTokenArrived(int status) void BlackBerrySetupWizard::uploaderFinished(int status) { - QString errorString = tr("Failed to upload debug token: "); + QString errorString = tr("Failed to upload debug token:") + QLatin1Char(' '); switch (status) { case BlackBerryDebugTokenUploader::Success: diff --git a/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp index 015a2ea6d05..a4b26fef313 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp +++ b/src/plugins/remotelinux/remotelinuxrunconfigurationfactory.cpp @@ -102,7 +102,7 @@ QList RemoteLinuxRunConfigurationFactory::availableCreationIds(Target QString RemoteLinuxRunConfigurationFactory::displayNameForId(const Core::Id id) const { return QFileInfo(pathFromId(id)).completeBaseName() - + tr(" (on Remote Generic Linux Host)"); + + QLatin1Char(' ') + tr("(on Remote Generic Linux Host)"); } RunConfiguration *RemoteLinuxRunConfigurationFactory::doCreate(Target *parent, const Core::Id id) diff --git a/src/plugins/remotelinux/remotelinuxsignaloperation.cpp b/src/plugins/remotelinux/remotelinuxsignaloperation.cpp index bdfb67a787e..e3f96e27131 100644 --- a/src/plugins/remotelinux/remotelinuxsignaloperation.cpp +++ b/src/plugins/remotelinux/remotelinuxsignaloperation.cpp @@ -120,7 +120,8 @@ void RemoteLinuxSignalOperation::runnerProcessFinished() if (m_runner->processExitStatus() != QSsh::SshRemoteProcess::NormalExit) { m_errorMessage = m_runner->processErrorString(); } else if (m_runner->processExitCode() != 0) { - m_errorMessage = tr("Exit code is %1. stderr: ").arg(m_runner->processExitCode()) + m_errorMessage = tr("Exit code is %1. stderr:").arg(m_runner->processExitCode()) + + QLatin1Char(' ') + QString::fromLatin1(m_runner->readAllStandardError()); } finish(); diff --git a/src/plugins/valgrind/memcheck/memcheckrunner.cpp b/src/plugins/valgrind/memcheck/memcheckrunner.cpp index 6827f6b47d7..91033203f6d 100644 --- a/src/plugins/valgrind/memcheck/memcheckrunner.cpp +++ b/src/plugins/valgrind/memcheck/memcheckrunner.cpp @@ -168,14 +168,14 @@ bool MemcheckRunner::start() } bool check = d->xmlServer.listen(hostAddr); - if (!check) emit processErrorReceived( tr("XmlServer on %1: ").arg(ip) + d->xmlServer.errorString(), QProcess::FailedToStart ); + if (!check) emit processErrorReceived( tr("XmlServer on %1:").arg(ip) + QLatin1Char(' ') + d->xmlServer.errorString(), QProcess::FailedToStart ); QTC_ASSERT(check, return false); d->xmlServer.setMaxPendingConnections(1); const quint16 xmlPortNumber = d->xmlServer.serverPort(); connect(&d->xmlServer, SIGNAL(newConnection()), SLOT(xmlSocketConnected())); check = d->logServer.listen(hostAddr); - if (!check) emit processErrorReceived( tr("LogServer on %1: ").arg(ip) + d->logServer.errorString(), QProcess::FailedToStart ); + if (!check) emit processErrorReceived( tr("LogServer on %1:").arg(ip) + QLatin1Char(' ') + d->logServer.errorString(), QProcess::FailedToStart ); QTC_ASSERT(check, return false); d->logServer.setMaxPendingConnections(1); const quint16 logPortNumber = d->logServer.serverPort(); diff --git a/src/tools/qtcreatorcrashhandler/crashhandlerdialog.cpp b/src/tools/qtcreatorcrashhandler/crashhandlerdialog.cpp index 90b131f3139..f95755bbdd2 100644 --- a/src/tools/qtcreatorcrashhandler/crashhandlerdialog.cpp +++ b/src/tools/qtcreatorcrashhandler/crashhandlerdialog.cpp @@ -134,7 +134,7 @@ void CrashHandlerDialog::setApplicationInfo(const QString &signalName) QString revision; #ifdef IDE_REVISION - revision = tr(" from revision %1").arg(QString::fromLatin1(Core::Constants::IDE_REVISION_STR).left(10)); + revision = QLatin1Char(' ') + tr("from revision %1").arg(QString::fromLatin1(Core::Constants::IDE_REVISION_STR).left(10)); #endif const QString versionInformation = tr( "%1 %2%3, built on %4 at %5, based on Qt %6 (%7 bit)\n") From 37e3bedbe46815b8092caf4c561bc28cd4e1394a Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 23 Oct 2013 18:02:03 +0200 Subject: [PATCH 06/84] QmlJS: Fix autotest. Change-Id: I0f7aba021fd4893fb521251c9b4b9572c2beef44 Reviewed-by: Fawzi Mohamed --- tests/auto/qml/codemodel/check/tst_check.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qml/codemodel/check/tst_check.cpp b/tests/auto/qml/codemodel/check/tst_check.cpp index a2bdefba585..f4da84c6524 100644 --- a/tests/auto/qml/codemodel/check/tst_check.cpp +++ b/tests/auto/qml/codemodel/check/tst_check.cpp @@ -111,7 +111,7 @@ void tst_Check::test() QFETCH(QString, path); Snapshot snapshot; - Document::MutablePtr doc = Document::create(path, Document::QmlLanguage); + Document::MutablePtr doc = Document::create(path, Language::Qml); QFile file(doc->fileName()); file.open(QFile::ReadOnly | QFile::Text); doc->setSource(file.readAll()); From 4161a528a364716e8374f9be76ae757ea7dcf3ff Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 23 Oct 2013 14:48:32 +0200 Subject: [PATCH 07/84] Increase preference dialog height by 10% on Mac Widgets and layouts take more space on Mac than on the other platforms, and that results in developers designing pages that are too heigh for Mac even though they fit on other platforms. Since redesigning preference pages so they also fit on Mac all the time is not ideal, simply account for the larger needed space. Change-Id: Ib8483713f562436bc9a86063f345ae4e44473608 Reviewed-by: Erik Verbruggen --- src/plugins/coreplugin/dialogs/settingsdialog.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/src/plugins/coreplugin/dialogs/settingsdialog.cpp index bb6783bcda1..4593488c1b5 100644 --- a/src/plugins/coreplugin/dialogs/settingsdialog.cpp +++ b/src/plugins/coreplugin/dialogs/settingsdialog.cpp @@ -400,6 +400,8 @@ void SettingsDialog::createGui() mainGridLayout->setColumnStretch(1, 4); setLayout(mainGridLayout); setMinimumSize(1000, 550); + if (Utils::HostOsInfo::isMacHost()) + setMinimumHeight(minimumHeight() * 1.1); } SettingsDialog::~SettingsDialog() From 1daac296477402e37f7812a6224facf63cec6769 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 24 Oct 2013 11:34:01 +0200 Subject: [PATCH 08/84] Debugger: More QRegion dumper fixes Change-Id: I01aaba021fd4893fb521251c9b4b9572c2beef44 Reviewed-by: hjk --- share/qtcreator/debugger/qttypes.py | 1 + tests/auto/debugger/tst_dumpers.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index a80986ef744..eb336fa08e2 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -1482,6 +1482,7 @@ def qdump__QRegion(d, value): d.putIntItem("numRects", n) d.putSubItem("extents", d.createValue(pp + 2 * v, rectType)) d.putSubItem("innerRect", d.createValue(pp + 2 * v + rectType.sizeof, rectType)) + d.putIntItem("innerArea", d.extractInt(pp + 2 * v + 2 * rectType.sizeof)) # FIXME try: # Can fail if QVector debuginfo is missing. diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 0bcb04d4975..b518e189a30 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -2260,7 +2260,8 @@ void tst_Dumpers::dumper_data() % Check("region1.innerArea", "40000", "int") % Check("region1.innerRect", "200x200+100+100", "@QRect") % Check("region1.numRects", "1", "int") - % Check("region1.rects", "<1 items>", "@QVector<@QRect>") + // This seems to be 0(!) items on Linux, 1 on Mac + // % Check("region1.rects", "<1 items>", "@QVector<@QRect>") % Check("region2", "<2 items>", "@QRegion") % Check("region2.extents", "600x700+100+100", "@QRect") % Check("region2.innerArea", "200000", "int") From 5c28544a167dfcc86eb13072bfedd436843a870b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20N=C3=A4tterlund?= Date: Thu, 24 Oct 2013 08:03:11 +0200 Subject: [PATCH 09/84] QNX: Fix broken environment On systems where QNX_HOST (et al.) are already set by the QNX SDP installer, just appending to QNX_HOST collides with finding the Connect.jar package when connecting to a device. Change-Id: I5d3547396384fe5b421c4b601b52476a23cdfa89 Reviewed-by: Mehdi Fekari Reviewed-by: Nicolas Arnaud-Cormos --- src/plugins/qnx/blackberrydeviceconnection.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/qnx/blackberrydeviceconnection.cpp b/src/plugins/qnx/blackberrydeviceconnection.cpp index 9b809863706..3db96567a5e 100644 --- a/src/plugins/qnx/blackberrydeviceconnection.cpp +++ b/src/plugins/qnx/blackberrydeviceconnection.cpp @@ -62,8 +62,7 @@ BlackBerryDeviceConnection::BlackBerryDeviceConnection() : void BlackBerryDeviceConnection::connectDevice(const ProjectExplorer::IDevice::ConstPtr &device) { Utils::Environment env = Utils::Environment::systemEnvironment(); - foreach (const Utils::EnvironmentItem &item, BlackBerryConfigurationManager::instance().defaultQnxEnv()) - env.appendOrSet(item.name, item.value); + env.modify(BlackBerryConfigurationManager::instance().defaultQnxEnv()); m_process->setEnvironment(env.toStringList()); From 580791ff9f8457d7b40859bc030ed35fedd25c8b Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 23 Oct 2013 10:54:18 +0200 Subject: [PATCH 10/84] CppEditor: Do not return double entries in FunctionHelper::overrides() Change-Id: I568cdb842fd823067514dd4b2e983e6bd19eebca Reviewed-by: Erik Verbruggen --- src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp | 3 --- .../cppeditor/followsymbol_switchmethoddecldef_test.cpp | 3 --- 2 files changed, 6 deletions(-) diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp index 5f445898855..a9668bc3fcc 100644 --- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp +++ b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp @@ -263,9 +263,6 @@ QList FunctionHelper::overrides(Class *startClass, Function *function, const Name *referenceName = function->name(); QTC_ASSERT(referenceName && referenceType.isValid(), return result); - // Add itself - result << function; - // Find overrides CppEditor::Internal::CppClass cppClass = CppClass(startClass); cppClass.lookupDerived(startClass, snapshot); diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp index 19f33336ae2..6ad94d11b72 100644 --- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp +++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp @@ -1243,7 +1243,6 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_allOverri << QLatin1String("...searching overrides"); const QStringList finalResults = QStringList() << QLatin1String("A::virt") - << QLatin1String("A::virt") // TODO: Double entry << QLatin1String("B::virt") << QLatin1String("C::virt") << QLatin1String("CD1::virt") @@ -1283,7 +1282,6 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_possibleO << QLatin1String("...searching overrides"); const QStringList finalResults = QStringList() << QLatin1String("B::virt") - << QLatin1String("B::virt") // Double entry << QLatin1String("C::virt") << QLatin1String("CD1::virt") << QLatin1String("CD2::virt"); @@ -1312,7 +1310,6 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_possibleO << QLatin1String("B::f") << QLatin1String("...searching overrides"); const QStringList finalResults = QStringList() - << QLatin1String("B::f") << QLatin1String("B::f") << QLatin1String("D::f"); From dcb5062549e4fc0076d13e90dc3ff05b05fec443 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 23 Oct 2013 10:34:02 +0200 Subject: [PATCH 11/84] CppEditor: Clean up followsymbol_switchmethoddecldef_test.cpp with respect to test_FollowSymbolUnderCursor_virtualFunctionCall* functions: - Use same function names in test code - Shorten test code - Mimic GenericProposalWidget::showProposal() calls more completely VirtualFunctionTestAssistProvider::itemList() Change-Id: Ie1bae5f00d550a9a61981945de41daf6bfeee5ff Reviewed-by: Erik Verbruggen --- .../followsymbol_switchmethoddecldef_test.cpp | 67 +++++++++---------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp index 6ad94d11b72..c29ef854dd3 100644 --- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp +++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp @@ -95,9 +95,12 @@ public: BasicProposalItemListModel *model = dynamic_cast(imodel); if (!model) return immediateItems; + + // Mimic relevant GenericProposalWidget::showProposal() calls + model->removeDuplicates(); + model->reset(); if (model->isSortable(QString())) model->sort(QString()); - model->removeDuplicates(); for (int i = 0, size = model->size(); i < size; ++i) { const QString text = model->text(i); @@ -1232,9 +1235,7 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_allOverri "struct CD2 : C { void virt(); };\n" "void CD2::virt() {}\n" "\n" - "int f(A *o)\n" - "{\n" - " o->$@virt();\n" + "int f(A *o) { o->$@virt(); }\n" "}\n" ; @@ -1271,9 +1272,7 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_possibleO "struct CD2 : C { void virt(); };\n" "void CD2::virt() {}\n" "\n" - "int f(B *o)\n" - "{\n" - " o->$@virt();\n" + "int f(B *o) { o->$@virt(); }\n" "}\n" ; @@ -1294,24 +1293,24 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_possibleO void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_possibleOverrides2() { const QByteArray source = - "struct A { virtual void f(); };\n" - "void A::f() {}\n" + "struct A { virtual void virt(); };\n" + "void A::virt() {}\n" "\n" - "struct B : public A { void f(); };\n" - "void B::f() {}\n" + "struct B : public A { void virt(); };\n" + "void B::virt() {}\n" "\n" - "struct C : public B { void g() { f$@(); } }; \n" + "struct C : public B { void g() { virt$@(); } }; \n" "\n" - "struct D : public C { void f(); };\n" - "void D::f() {}\n" + "struct D : public C { void virt(); };\n" + "void D::virt() {}\n" ; const QStringList immediateResults = QStringList() - << QLatin1String("B::f") + << QLatin1String("B::virt") << QLatin1String("...searching overrides"); const QStringList finalResults = QStringList() - << QLatin1String("B::f") - << QLatin1String("D::f"); + << QLatin1String("B::virt") + << QLatin1String("D::virt"); TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults); test.run(); @@ -1321,12 +1320,12 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_possibleO void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_notOnQualified() { const QByteArray source = - "struct A { virtual void f(); };\n" - "void A::$f() {}\n" + "struct A { virtual void virt(); };\n" + "void A::$virt() {}\n" "\n" "struct B : public A {\n" - " void f();\n" - " void g() { A::@f(); }\n" + " void virt();\n" + " void g() { A::@virt(); }\n" "};\n" ; @@ -1338,11 +1337,11 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_notOnQual void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_notOnDeclaration() { const QByteArray source = - "struct A { virtual void f(); };\n" - "void A::f() {}\n" + "struct A { virtual void virt(); };\n" + "void A::virt() {}\n" "\n" - "struct B : public A { void f@(); };\n" - "void B::$f() {}\n" + "struct B : public A { void virt@(); };\n" + "void B::$virt() {}\n" ; TestCase test(TestCase::FollowSymbolUnderCursorAction, source); @@ -1353,11 +1352,11 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_notOnDecl void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_notOnDefinition() { const QByteArray source = - "struct A { virtual void f(); };\n" - "void A::f() {}\n" + "struct A { virtual void virt(); };\n" + "void A::virt() {}\n" "\n" - "struct B : public A { void $f(); };\n" - "void B::@f() {}\n" + "struct B : public A { void $virt(); };\n" + "void B::@virt() {}\n" ; TestCase test(TestCase::FollowSymbolUnderCursorAction, source); @@ -1367,13 +1366,13 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_notOnDefi void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_notOnNonPointerNonReference() { const QByteArray source = - "struct A { virtual void f(); };\n" - "void A::f() {}\n" + "struct A { virtual void virt(); };\n" + "void A::virt() {}\n" "\n" - "struct B : public A { void f(); };\n" - "void B::$f() {}\n" + "struct B : public A { void virt(); };\n" + "void B::$virt() {}\n" "\n" - "void client(B b) { b.@f(); }\n" + "void client(B b) { b.@virt(); }\n" ; TestCase test(TestCase::FollowSymbolUnderCursorAction, source); From 3e79d33d852b5fe72f6bf4b8b003b7231e5bdc18 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Mon, 21 Oct 2013 17:07:54 +0200 Subject: [PATCH 12/84] CppEditor: Trigger override search for reference types ...if the access token is T_DOT. Task-number: QTCREATORBUG-10286 Change-Id: I85621a8166d4f18b3099488ac0ac05a0d6982c43 Reviewed-by: Orgad Shaneh Reviewed-by: Erik Verbruggen --- src/plugins/cppeditor/cppeditorplugin.h | 2 + .../cppeditor/cppfollowsymbolundercursor.cpp | 58 +++++++++++++------ .../followsymbol_switchmethoddecldef_test.cpp | 34 +++++++++++ 3 files changed, 76 insertions(+), 18 deletions(-) diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h index 33e32593f4c..3a4eaa19f47 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppeditorplugin.h @@ -138,6 +138,8 @@ private slots: void test_FollowSymbolUnderCursor_virtualFunctionCall_allOverrides(); void test_FollowSymbolUnderCursor_virtualFunctionCall_possibleOverrides1(); void test_FollowSymbolUnderCursor_virtualFunctionCall_possibleOverrides2(); + void test_FollowSymbolUnderCursor_virtualFunctionCall_onDotMemberAccessOfReferenceTypes(); + void test_FollowSymbolUnderCursor_virtualFunctionCall_notOnDotMemberAccessOfNonReferenceType(); void test_FollowSymbolUnderCursor_virtualFunctionCall_notOnQualified(); void test_FollowSymbolUnderCursor_virtualFunctionCall_notOnDeclaration(); void test_FollowSymbolUnderCursor_virtualFunctionCall_notOnDefinition(); diff --git a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp index ad4a8c30121..9db42048d88 100644 --- a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp +++ b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp @@ -55,35 +55,57 @@ typedef BaseTextEditorWidget::Link Link; namespace { -bool lookupVirtualFunctionOverrides(const QString &expression, Function *function, Scope *scope, +bool lookupVirtualFunctionOverrides(TypeOfExpression &typeOfExpression, + const Document::Ptr &document, + const Function *function, + Scope *scope, const Snapshot &snapshot) { - if (expression.isEmpty() || !function || !scope || scope->isClass() || snapshot.isEmpty()) + if (!document || !function || !scope || scope->isClass() || snapshot.isEmpty()) + return false; + + ExpressionAST *expressionAST = typeOfExpression.expressionAST(); + if (!expressionAST) + return false; + CallAST *callAST = expressionAST->asCall(); + if (!callAST) + return false; + ExpressionAST *baseExpressionAST = callAST->base_expression; + if (!baseExpressionAST) return false; bool result = false; - Document::Ptr expressionDocument = documentForExpression(expression.toUtf8()); - if (ExpressionAST *expressionAST = extractExpressionAST(expressionDocument)) { - if (CallAST *callAST = expressionAST->asCall()) { - if (ExpressionAST *baseExpressionAST = callAST->base_expression) { - if (IdExpressionAST *idExpressionAST = baseExpressionAST->asIdExpression()) { - NameAST *name = idExpressionAST->name; - result = name && !name->asQualifiedName(); - } else if (MemberAccessAST *memberAccessAST = baseExpressionAST->asMemberAccess()) { - NameAST *name = memberAccessAST->member_name; - const bool nameIsQualified = name && name->asQualifiedName(); + if (IdExpressionAST *idExpressionAST = baseExpressionAST->asIdExpression()) { + NameAST *name = idExpressionAST->name; + const bool nameIsQualified = name && name->asQualifiedName(); + result = !nameIsQualified && FunctionHelper::isVirtualFunction(function, snapshot); + } else if (MemberAccessAST *memberAccessAST = baseExpressionAST->asMemberAccess()) { + NameAST *name = memberAccessAST->member_name; + const bool nameIsQualified = name && name->asQualifiedName(); + if (!nameIsQualified && FunctionHelper::isVirtualFunction(function, snapshot)) { + const Document::Ptr expressionDocument + = typeOfExpression.context().expressionDocument(); + QTC_ASSERT(expressionDocument, return false); + TranslationUnit *unit = expressionDocument->translationUnit(); + QTC_ASSERT(unit, return false); + const int accessTokenKind = unit->tokenKind(memberAccessAST->access_token); - TranslationUnit *unit = expressionDocument->translationUnit(); - QTC_ASSERT(unit, return false); - const int tokenKind = unit->tokenKind(memberAccessAST->access_token); - result = tokenKind == T_ARROW && !nameIsQualified; + if (accessTokenKind == T_ARROW) { + result = true; + } else if (accessTokenKind == T_DOT) { + const QList items = typeOfExpression.reference( + memberAccessAST->base_expression, document, scope); + if (!items.isEmpty()) { + const LookupItem item = items.first(); + if (Symbol *declaration = item.declaration()) + result = declaration->type()->isReferenceType(); } } } } - return result && FunctionHelper::isVirtualFunction(function, snapshot); + return result; } Link findMacroLink_helper(const QByteArray &name, Document::Ptr doc, const Snapshot &snapshot, @@ -530,7 +552,7 @@ BaseTextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor & // Consider to show a pop-up displaying overrides for the function Function *function = symbol->type()->asFunctionType(); - if (lookupVirtualFunctionOverrides(expression, function, scope, snapshot)) { + if (lookupVirtualFunctionOverrides(typeOfExpression, doc, function, scope, snapshot)) { Class *klass = symbolFinder->findMatchingClassDeclaration(function, snapshot); QTC_CHECK(klass); diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp index c29ef854dd3..887b3d85d08 100644 --- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp +++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp @@ -1316,6 +1316,40 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_possibleO test.run(); } +/// Check: Trigger on a.virt() if a is of type &A. +void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_onDotMemberAccessOfReferenceTypes() +{ + const QByteArray source = + "struct A { virtual void virt() = 0; };\n" + "void A::virt() {}\n" + "\n" + "void client(A &o) { o.$@virt(); }\n" + ; + + const QStringList immediateResults = QStringList() + << QLatin1String("A::virt") + << QLatin1String("...searching overrides"); + const QStringList finalResults = QStringList() + << QLatin1String("A::virt"); + + TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults); + test.run(); +} + +/// Check: Do not trigger on a.virt() if a is of type A. +void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_notOnDotMemberAccessOfNonReferenceType() +{ + const QByteArray source = + "struct A { virtual void virt(); };\n" + "void A::$virt() {}\n" + "\n" + "void client(A o) { o.@virt(); }\n" + ; + + TestCase test(TestCase::FollowSymbolUnderCursorAction, source); + test.run(); +} + /// Check: Do not trigger on qualified function calls. void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_notOnQualified() { From b1472eefae33a96af24028e1296701e9dc35e326 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 24 Oct 2013 09:41:52 +0200 Subject: [PATCH 13/84] CppEditor: Test also link targets for override list Affects test_FollowSymbolUnderCursor_virtualFunctionCall_* functions. Change-Id: I963ef81183792f85243d679dee69a41db00bed07 Reviewed-by: Erik Verbruggen --- .../cppvirtualfunctionproposalitem.h | 1 + .../followsymbol_switchmethoddecldef_test.cpp | 144 +++++++++++------- 2 files changed, 90 insertions(+), 55 deletions(-) diff --git a/src/plugins/cppeditor/cppvirtualfunctionproposalitem.h b/src/plugins/cppeditor/cppvirtualfunctionproposalitem.h index 7d09c9db2cd..44cf50dcc91 100644 --- a/src/plugins/cppeditor/cppvirtualfunctionproposalitem.h +++ b/src/plugins/cppeditor/cppvirtualfunctionproposalitem.h @@ -41,6 +41,7 @@ public: VirtualFunctionProposalItem(const TextEditor::BaseTextEditorWidget::Link &link, bool openInSplit = true); void apply(TextEditor::BaseTextEditor * /* editor */, int /* basePosition */) const; + TextEditor::BaseTextEditorWidget::Link link() const { return m_link; } // Exposed for tests private: TextEditor::BaseTextEditorWidget::Link m_link; diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp index 887b3d85d08..99be9591d59 100644 --- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp +++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp @@ -31,6 +31,7 @@ #include "cppeditorplugin.h" #include "cppelementevaluator.h" #include "cppvirtualfunctionassistprovider.h" +#include "cppvirtualfunctionproposalitem.h" #include #include @@ -59,6 +60,33 @@ using namespace CppTools; using namespace TextEditor; using namespace Core; +class OverrideItem { +public: + OverrideItem() : line(0) {} + OverrideItem(const QString &text, int line = 0) : text(text), line(line) {} + bool isValid() { return line != 0; } + + QString text; + int line; +}; +typedef QList OverrideItemList; +Q_DECLARE_METATYPE(OverrideItem) + +inline bool operator==(const OverrideItem &lhs, const OverrideItem &rhs) +{ + return lhs.text == rhs.text && lhs.line == rhs.line; +} + +namespace QTest { +template<> char *toString(const OverrideItem &data) +{ + QByteArray ba = "OverrideItem("; + ba += data.text.toLatin1() + ", " + QByteArray::number(data.line); + ba += ")"; + return qstrdup(ba.data()); +} +} + namespace { /// A fake virtual functions assist provider that runs processor->perform() already in configure() @@ -78,8 +106,8 @@ public: VirtualFunctionAssistProvider::configure(startClass, function, snapshot, openInNextSplit); IAssistProcessor *processor = createProcessor(); - IAssistInterface *assistInterface = m_editorWidget->createAssistInterface(FollowSymbol, - ExplicitlyInvoked); + IAssistInterface *assistInterface + = m_editorWidget->createAssistInterface(FollowSymbol, ExplicitlyInvoked); IAssistProposal *immediateProposal = processor->immediateProposal(assistInterface); IAssistProposal *finalProposal = processor->perform(assistInterface); @@ -89,12 +117,12 @@ public: return false; } - static QStringList itemList(IAssistProposalModel *imodel) + static OverrideItemList itemList(IAssistProposalModel *imodel) { - QStringList immediateItems; + OverrideItemList result; BasicProposalItemListModel *model = dynamic_cast(imodel); if (!model) - return immediateItems; + return result; // Mimic relevant GenericProposalWidget::showProposal() calls model->removeDuplicates(); @@ -103,16 +131,22 @@ public: model->sort(QString()); for (int i = 0, size = model->size(); i < size; ++i) { + VirtualFunctionProposalItem *item + = dynamic_cast(model->proposalItem(i)); + const QString text = model->text(i); - immediateItems.append(text); + const int line = item->link().targetLine; +// Uncomment for updating/generating reference data: +// qDebug("<< OverrideItem(QLatin1String(\"%s\"), %d)", qPrintable(text), line); + result << OverrideItem(text, line); } - return immediateItems; + return result; } public: - QStringList m_immediateItems; - QStringList m_finalItems; + OverrideItemList m_immediateItems; + OverrideItemList m_finalItems; private: CPPEditorWidget *m_editorWidget; @@ -202,11 +236,11 @@ public: }; TestCase(CppEditorAction action, const QByteArray &source, - const QStringList &expectedVirtualFunctionImmediateProposal = QStringList(), - const QStringList &expectedVirtualFunctionFinalProposal = QStringList()); + const OverrideItemList &expectedVirtualFunctionImmediateProposal = OverrideItemList(), + const OverrideItemList &expectedVirtualFunctionFinalProposal = OverrideItemList()); TestCase(CppEditorAction action, const QList theTestFiles, - const QStringList &expectedVirtualSymbolsImmediateProposal = QStringList(), - const QStringList &expectedVirtualSymbolsFinalProposal = QStringList()); + const OverrideItemList &expectedVirtualFunctionImmediateProposal = OverrideItemList(), + const OverrideItemList &expectedVirtualFunctionFinalProposal = OverrideItemList()); ~TestCase(); void run(bool expectedFail = false); @@ -223,18 +257,18 @@ private: private: CppEditorAction m_action; QList m_testFiles; - QStringList m_expectedVirtualSymbolsImmediateProposal; // for virtual functions - QStringList m_expectedVirtualSymbolsFinalProposals; // for virtual functions + OverrideItemList m_expectedVirtualFunctionImmediateProposal; + OverrideItemList m_expectedVirtualFunctionFinalProposals; }; /// Convenience function for creating a TestDocument. /// See TestDocument. TestCase::TestCase(CppEditorAction action, const QByteArray &source, - const QStringList &expectedVirtualFunctionImmediateProposal, - const QStringList &expectedVirtualFunctionFinalProposal) + const OverrideItemList &expectedVirtualFunctionImmediateProposal, + const OverrideItemList &expectedVirtualFunctionFinalProposal) : m_action(action) - , m_expectedVirtualSymbolsImmediateProposal(expectedVirtualFunctionImmediateProposal) - , m_expectedVirtualSymbolsFinalProposals(expectedVirtualFunctionFinalProposal) + , m_expectedVirtualFunctionImmediateProposal(expectedVirtualFunctionImmediateProposal) + , m_expectedVirtualFunctionFinalProposals(expectedVirtualFunctionFinalProposal) { m_testFiles << TestDocument::create(source, QLatin1String("file.cpp")); init(); @@ -245,12 +279,12 @@ TestCase::TestCase(CppEditorAction action, const QByteArray &source, /// Exactly one test document must be provided that contains '$', the target position marker. /// It can be the same document. TestCase::TestCase(CppEditorAction action, const QList theTestFiles, - const QStringList &expectedVirtualSymbolsImmediateProposal, - const QStringList &expectedVirtualSymbolsFinalProposal) + const OverrideItemList &expectedVirtualFunctionImmediateProposal, + const OverrideItemList &expectedVirtualFunctionFinalProposal) : m_action(action) , m_testFiles(theTestFiles) - , m_expectedVirtualSymbolsImmediateProposal(expectedVirtualSymbolsImmediateProposal) - , m_expectedVirtualSymbolsFinalProposals(expectedVirtualSymbolsFinalProposal) + , m_expectedVirtualFunctionImmediateProposal(expectedVirtualFunctionImmediateProposal) + , m_expectedVirtualFunctionFinalProposals(expectedVirtualFunctionFinalProposal) { init(); } @@ -368,8 +402,8 @@ void TestCase::run(bool expectedFail) // qDebug() << "Initial line:" << initialTestFile->editor->currentLine(); // qDebug() << "Initial column:" << initialTestFile->editor->currentColumn() - 1; - QStringList immediateVirtualSymbolResults; - QStringList finalVirtualSymbolResults; + OverrideItemList immediateVirtualSymbolResults; + OverrideItemList finalVirtualSymbolResults; // Trigger the action switch (m_action) { @@ -419,8 +453,8 @@ void TestCase::run(bool expectedFail) // qDebug() << immediateVirtualSymbolResults; // qDebug() << finalVirtualSymbolResults; - QCOMPARE(immediateVirtualSymbolResults, m_expectedVirtualSymbolsImmediateProposal); - QCOMPARE(finalVirtualSymbolResults, m_expectedVirtualSymbolsFinalProposals); + QCOMPARE(immediateVirtualSymbolResults, m_expectedVirtualFunctionImmediateProposal); + QCOMPARE(finalVirtualSymbolResults, m_expectedVirtualFunctionFinalProposals); } } // anonymous namespace @@ -1239,15 +1273,15 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_allOverri "}\n" ; - const QStringList immediateResults = QStringList() - << QLatin1String("A::virt") - << QLatin1String("...searching overrides"); - const QStringList finalResults = QStringList() - << QLatin1String("A::virt") - << QLatin1String("B::virt") - << QLatin1String("C::virt") - << QLatin1String("CD1::virt") - << QLatin1String("CD2::virt"); + const OverrideItemList immediateResults = OverrideItemList() + << OverrideItem(QLatin1String("A::virt"), 1) + << OverrideItem(QLatin1String("...searching overrides")); + const OverrideItemList finalResults = OverrideItemList() + << OverrideItem(QLatin1String("A::virt"), 1) + << OverrideItem(QLatin1String("B::virt"), 4) + << OverrideItem(QLatin1String("C::virt"), 7) + << OverrideItem(QLatin1String("CD1::virt"), 10) + << OverrideItem(QLatin1String("CD2::virt"), 13); TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults); test.run(); @@ -1276,14 +1310,14 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_possibleO "}\n" ; - const QStringList immediateResults = QStringList() - << QLatin1String("B::virt") - << QLatin1String("...searching overrides"); - const QStringList finalResults = QStringList() - << QLatin1String("B::virt") - << QLatin1String("C::virt") - << QLatin1String("CD1::virt") - << QLatin1String("CD2::virt"); + const OverrideItemList immediateResults = OverrideItemList() + << OverrideItem(QLatin1String("B::virt"), 4) + << OverrideItem(QLatin1String("...searching overrides")); + const OverrideItemList finalResults = OverrideItemList() + << OverrideItem(QLatin1String("B::virt"), 4) + << OverrideItem(QLatin1String("C::virt"), 7) + << OverrideItem(QLatin1String("CD1::virt"), 10) + << OverrideItem(QLatin1String("CD2::virt"), 13); TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults); test.run(); @@ -1305,12 +1339,12 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_possibleO "void D::virt() {}\n" ; - const QStringList immediateResults = QStringList() - << QLatin1String("B::virt") - << QLatin1String("...searching overrides"); - const QStringList finalResults = QStringList() - << QLatin1String("B::virt") - << QLatin1String("D::virt"); + const OverrideItemList immediateResults = OverrideItemList() + << OverrideItem(QLatin1String("B::virt"), 4) + << OverrideItem(QLatin1String("...searching overrides")); + const OverrideItemList finalResults = OverrideItemList() + << OverrideItem(QLatin1String("B::virt"), 4) + << OverrideItem(QLatin1String("D::virt"), 9); TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults); test.run(); @@ -1326,11 +1360,11 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_onDotMemb "void client(A &o) { o.$@virt(); }\n" ; - const QStringList immediateResults = QStringList() - << QLatin1String("A::virt") - << QLatin1String("...searching overrides"); - const QStringList finalResults = QStringList() - << QLatin1String("A::virt"); + const OverrideItemList immediateResults = OverrideItemList() + << OverrideItem(QLatin1String("A::virt"), 1) + << OverrideItem(QLatin1String("...searching overrides")); + const OverrideItemList finalResults = OverrideItemList() + << OverrideItem(QLatin1String("A::virt"), 1); TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults); test.run(); From f8653a59bc1f079b9f7fe399cfcce6a4e43cc3eb Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Mon, 21 Oct 2013 13:39:48 +0200 Subject: [PATCH 14/84] CppEditor: Selecting an override of a virtual function jumps to definition ...instead declaration (F2 on a virtual function call). Task-number: QTCREATORBUG-10287 Change-Id: Ib913bd4e777c7253659458ae17584354c7416d23 Reviewed-by: Orgad Shaneh Reviewed-by: Erik Verbruggen --- src/plugins/cppeditor/cppeditorplugin.h | 2 + .../cppvirtualfunctionassistprovider.cpp | 24 ++++-- .../followsymbol_switchmethoddecldef_test.cpp | 80 +++++++++++++++---- 3 files changed, 84 insertions(+), 22 deletions(-) diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h index 3a4eaa19f47..c9e6f5e873d 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppeditorplugin.h @@ -138,6 +138,8 @@ private slots: void test_FollowSymbolUnderCursor_virtualFunctionCall_allOverrides(); void test_FollowSymbolUnderCursor_virtualFunctionCall_possibleOverrides1(); void test_FollowSymbolUnderCursor_virtualFunctionCall_possibleOverrides2(); + void test_FollowSymbolUnderCursor_virtualFunctionCall_fallbackToDeclaration(); + void test_FollowSymbolUnderCursor_virtualFunctionCall_itemOrder(); void test_FollowSymbolUnderCursor_virtualFunctionCall_onDotMemberAccessOfReferenceTypes(); void test_FollowSymbolUnderCursor_virtualFunctionCall_notOnDotMemberAccessOfNonReferenceType(); void test_FollowSymbolUnderCursor_virtualFunctionCall_notOnQualified(); diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp index a9668bc3fcc..5c86bf455bc 100644 --- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp +++ b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp @@ -40,6 +40,8 @@ #include #include +#include + #include #include #include @@ -124,7 +126,7 @@ public: hintItem->setOrder(-1000); QList items; - items << itemFromSymbol(m_function, m_function); + items << itemFromSymbol(maybeDefinitionFor(m_function)); items << hintItem; return new VirtualFunctionProposal(interface->position(), new BasicProposalItemListModel(items), @@ -142,16 +144,28 @@ public: const QList overrides = FunctionHelper::overrides(m_startClass, m_function, m_snapshot); + if (overrides.isEmpty()) + return 0; + QList items; foreach (Symbol *symbol, overrides) - items << itemFromSymbol(symbol, m_function); + items << itemFromSymbol(maybeDefinitionFor(symbol)); + items.first()->setOrder(1000); // Ensure top position for function of static type return new VirtualFunctionProposal(interface->position(), new BasicProposalItemListModel(items), m_openInNextSplit); } - BasicProposalItem *itemFromSymbol(Symbol *symbol, Symbol *firstSymbol) const +private: + Symbol *maybeDefinitionFor(Symbol *symbol) + { + if (Function *definition = m_finder.findMatchingDefinition(symbol, m_snapshot)) + return definition; + return symbol; + } + + BasicProposalItem *itemFromSymbol(Symbol *symbol) const { const QString text = m_overview.prettyName(LookupContext::fullyQualifiedName(symbol)); const CPPEditorWidget::Link link = CPPEditorWidget::linkToSymbol(symbol); @@ -159,19 +173,17 @@ public: BasicProposalItem *item = new VirtualFunctionProposalItem(link, m_openInNextSplit); item->setText(text); item->setIcon(m_icons.iconForSymbol(symbol)); - if (symbol == firstSymbol) - item->setOrder(1000); // Ensure top position for function of static type return item; } -private: Class *m_startClass; Function *m_function; Snapshot m_snapshot; bool m_openInNextSplit; Overview m_overview; Icons m_icons; + CppTools::SymbolFinder m_finder; }; VirtualFunctionAssistProvider::VirtualFunctionAssistProvider() diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp index 99be9591d59..f9dc85b528e 100644 --- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp +++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp @@ -1274,14 +1274,14 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_allOverri ; const OverrideItemList immediateResults = OverrideItemList() - << OverrideItem(QLatin1String("A::virt"), 1) + << OverrideItem(QLatin1String("A::virt"), 2) << OverrideItem(QLatin1String("...searching overrides")); const OverrideItemList finalResults = OverrideItemList() - << OverrideItem(QLatin1String("A::virt"), 1) - << OverrideItem(QLatin1String("B::virt"), 4) - << OverrideItem(QLatin1String("C::virt"), 7) - << OverrideItem(QLatin1String("CD1::virt"), 10) - << OverrideItem(QLatin1String("CD2::virt"), 13); + << OverrideItem(QLatin1String("A::virt"), 2) + << OverrideItem(QLatin1String("B::virt"), 5) + << OverrideItem(QLatin1String("C::virt"), 8) + << OverrideItem(QLatin1String("CD1::virt"), 11) + << OverrideItem(QLatin1String("CD2::virt"), 14); TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults); test.run(); @@ -1311,13 +1311,13 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_possibleO ; const OverrideItemList immediateResults = OverrideItemList() - << OverrideItem(QLatin1String("B::virt"), 4) + << OverrideItem(QLatin1String("B::virt"), 5) << OverrideItem(QLatin1String("...searching overrides")); const OverrideItemList finalResults = OverrideItemList() - << OverrideItem(QLatin1String("B::virt"), 4) - << OverrideItem(QLatin1String("C::virt"), 7) - << OverrideItem(QLatin1String("CD1::virt"), 10) - << OverrideItem(QLatin1String("CD2::virt"), 13); + << OverrideItem(QLatin1String("B::virt"), 5) + << OverrideItem(QLatin1String("C::virt"), 8) + << OverrideItem(QLatin1String("CD1::virt"), 11) + << OverrideItem(QLatin1String("CD2::virt"), 14); TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults); test.run(); @@ -1340,11 +1340,59 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_possibleO ; const OverrideItemList immediateResults = OverrideItemList() - << OverrideItem(QLatin1String("B::virt"), 4) + << OverrideItem(QLatin1String("B::virt"), 5) << OverrideItem(QLatin1String("...searching overrides")); const OverrideItemList finalResults = OverrideItemList() - << OverrideItem(QLatin1String("B::virt"), 4) - << OverrideItem(QLatin1String("D::virt"), 9); + << OverrideItem(QLatin1String("B::virt"), 5) + << OverrideItem(QLatin1String("D::virt"), 10); + + TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults); + test.run(); +} + +/// Check: If no definition is found, fallback to the declaration. +void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_fallbackToDeclaration() +{ + const QByteArray source = + "struct A { virtual void virt(); };\n" + "\n" + "int f(A *o) { o->$@virt(); }\n" + ; + + const OverrideItemList immediateResults = OverrideItemList() + << OverrideItem(QLatin1String("A::virt"), 1) + << OverrideItem(QLatin1String("...searching overrides")); + const OverrideItemList finalResults = OverrideItemList() + << OverrideItem(QLatin1String("A::virt"), 1); + + TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults); + test.run(); +} + +/// Check: Ensure that the first entry in the final results is the same as the first in the +/// immediate results. +void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_itemOrder() +{ + const QByteArray source = + "struct C { virtual void virt() = 0; };\n" + "void C::virt() {}\n" + "\n" + "struct B : C { void virt(); };\n" + "void B::virt() {}\n" + "\n" + "struct A : B { void virt(); };\n" + "void A::virt() {}\n" + "\n" + "int f(C *o) { o->$@virt(); }\n" + ; + + const OverrideItemList immediateResults = OverrideItemList() + << OverrideItem(QLatin1String("C::virt"), 2) + << OverrideItem(QLatin1String("...searching overrides")); + const OverrideItemList finalResults = OverrideItemList() + << OverrideItem(QLatin1String("C::virt"), 2) + << OverrideItem(QLatin1String("A::virt"), 8) + << OverrideItem(QLatin1String("B::virt"), 5); TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults); test.run(); @@ -1361,10 +1409,10 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_onDotMemb ; const OverrideItemList immediateResults = OverrideItemList() - << OverrideItem(QLatin1String("A::virt"), 1) + << OverrideItem(QLatin1String("A::virt"), 2) << OverrideItem(QLatin1String("...searching overrides")); const OverrideItemList finalResults = OverrideItemList() - << OverrideItem(QLatin1String("A::virt"), 1); + << OverrideItem(QLatin1String("A::virt"), 2); TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults); test.run(); From 61c0de88c2f190b5f3901c9bf75f51fe652a1e99 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 23 Oct 2013 15:14:28 +0200 Subject: [PATCH 15/84] CppEditor: Simplify VirtualFunctionAssist{Processor,Provider} ...by extracting parameters to a dedicated struct. Change-Id: I2f3b83cbc62a8b4a91b44b3a729d0f0c578b53f2 Reviewed-by: Erik Verbruggen --- .../cppeditor/cppfollowsymbolundercursor.cpp | 10 +++- .../cppvirtualfunctionassistprovider.cpp | 59 ++++++++----------- .../cppvirtualfunctionassistprovider.h | 24 ++++---- .../followsymbol_switchmethoddecldef_test.cpp | 5 +- 4 files changed, 47 insertions(+), 51 deletions(-) diff --git a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp index 9db42048d88..adc4640eb14 100644 --- a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp +++ b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp @@ -556,11 +556,17 @@ BaseTextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor & Class *klass = symbolFinder->findMatchingClassDeclaration(function, snapshot); QTC_CHECK(klass); - if (m_virtualFunctionAssistProvider->configure(klass, function, snapshot, - inNextSplit)) { + VirtualFunctionAssistProvider::Parameters params; + params.startClass = klass; + params.function = function; + params.snapshot = snapshot; + params.openInNextSplit = inNextSplit; + + if (m_virtualFunctionAssistProvider->configure(params)) { m_widget->invokeAssist(TextEditor::FollowSymbol, m_virtualFunctionAssistProvider); } + return Link(); } diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp index 5c86bf455bc..dbcfa540a41 100644 --- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp +++ b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp @@ -109,16 +109,14 @@ private: class VirtualFunctionsAssistProcessor : public IAssistProcessor { public: - VirtualFunctionsAssistProcessor(const VirtualFunctionAssistProvider *provider) - : m_startClass(provider->startClass()) - , m_function(provider->function()) - , m_snapshot(provider->snapshot()) - , m_openInNextSplit(provider->openInNextSplit()) + VirtualFunctionsAssistProcessor(const VirtualFunctionAssistProvider::Parameters ¶ms) + : m_params(params) {} - IAssistProposal *immediateProposal(const TextEditor::IAssistInterface *interface) + IAssistProposal *immediateProposal(const TextEditor::IAssistInterface *assistInterface) { - QTC_ASSERT(m_function, return 0); + QTC_ASSERT(assistInterface, return 0); + QTC_ASSERT(m_params.function, return 0); BasicProposalItem *hintItem = new VirtualFunctionProposalItem(CPPEditorWidget::Link()); hintItem->setText(QCoreApplication::translate("VirtualFunctionsAssistProcessor", @@ -126,24 +124,22 @@ public: hintItem->setOrder(-1000); QList items; - items << itemFromSymbol(maybeDefinitionFor(m_function)); + items << itemFromSymbol(maybeDefinitionFor(m_params.function)); items << hintItem; - return new VirtualFunctionProposal(interface->position(), + return new VirtualFunctionProposal(assistInterface->position(), new BasicProposalItemListModel(items), - m_openInNextSplit); + m_params.openInNextSplit); } - IAssistProposal *perform(const IAssistInterface *interface) + IAssistProposal *perform(const IAssistInterface *assistInterface) { - if (!interface) - return 0; + QTC_ASSERT(assistInterface, return 0); + QTC_ASSERT(m_params.startClass, return 0); + QTC_ASSERT(m_params.function, return 0); + QTC_ASSERT(!m_params.snapshot.isEmpty(), return 0); - QTC_ASSERT(m_startClass, return 0); - QTC_ASSERT(m_function, return 0); - QTC_ASSERT(!m_snapshot.isEmpty(), return 0); - - const QList overrides = FunctionHelper::overrides(m_startClass, m_function, - m_snapshot); + const QList overrides + = FunctionHelper::overrides(m_params.startClass, m_params.function, m_params.snapshot); if (overrides.isEmpty()) return 0; @@ -152,15 +148,15 @@ public: items << itemFromSymbol(maybeDefinitionFor(symbol)); items.first()->setOrder(1000); // Ensure top position for function of static type - return new VirtualFunctionProposal(interface->position(), + return new VirtualFunctionProposal(assistInterface->position(), new BasicProposalItemListModel(items), - m_openInNextSplit); + m_params.openInNextSplit); } private: Symbol *maybeDefinitionFor(Symbol *symbol) { - if (Function *definition = m_finder.findMatchingDefinition(symbol, m_snapshot)) + if (Function *definition = m_finder.findMatchingDefinition(symbol, m_params.snapshot)) return definition; return symbol; } @@ -170,35 +166,26 @@ private: const QString text = m_overview.prettyName(LookupContext::fullyQualifiedName(symbol)); const CPPEditorWidget::Link link = CPPEditorWidget::linkToSymbol(symbol); - BasicProposalItem *item = new VirtualFunctionProposalItem(link, m_openInNextSplit); + BasicProposalItem *item = new VirtualFunctionProposalItem(link, m_params.openInNextSplit); item->setText(text); item->setIcon(m_icons.iconForSymbol(symbol)); return item; } - Class *m_startClass; - Function *m_function; - Snapshot m_snapshot; - bool m_openInNextSplit; + VirtualFunctionAssistProvider::Parameters m_params; Overview m_overview; Icons m_icons; CppTools::SymbolFinder m_finder; }; VirtualFunctionAssistProvider::VirtualFunctionAssistProvider() - : m_function(0) - , m_openInNextSplit(false) { } -bool VirtualFunctionAssistProvider::configure(Class *startClass, Function *function, - const Snapshot &snapshot, bool openInNextSplit) +bool VirtualFunctionAssistProvider::configure(const Parameters ¶meters) { - m_startClass = startClass; - m_function = function; - m_snapshot = snapshot; - m_openInNextSplit = openInNextSplit; + m_params = parameters; return true; } @@ -214,7 +201,7 @@ bool VirtualFunctionAssistProvider::supportsEditor(const Core::Id &editorId) con IAssistProcessor *VirtualFunctionAssistProvider::createProcessor() const { - return new VirtualFunctionsAssistProcessor(this); + return new VirtualFunctionsAssistProcessor(m_params); } enum VirtualType { Virtual, PureVirtual }; diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h index c634b4ed44f..2d91e298ee7 100644 --- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h +++ b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h @@ -35,6 +35,8 @@ #include #include +#include + namespace CppEditor { namespace Internal { @@ -43,22 +45,24 @@ class VirtualFunctionAssistProvider : public TextEditor::IAssistProvider public: VirtualFunctionAssistProvider(); - virtual bool configure(CPlusPlus::Class *startClass, CPlusPlus::Function *function, - const CPlusPlus::Snapshot &snapshot, bool openInNextSplit); - CPlusPlus::Class *startClass() const { return m_startClass; } - CPlusPlus::Function *function() const { return m_function; } - CPlusPlus::Snapshot snapshot() const { return m_snapshot; } - bool openInNextSplit() const { return m_openInNextSplit; } + struct Parameters { + Parameters() : startClass(0), function(0), openInNextSplit(false) {} + + CPlusPlus::Class *startClass; + CPlusPlus::Function *function; + CPlusPlus::Snapshot snapshot; + bool openInNextSplit; + }; + + virtual bool configure(const Parameters ¶meters); + Parameters params() const { return m_params; } bool isAsynchronous() const; bool supportsEditor(const Core::Id &editorId) const; TextEditor::IAssistProcessor *createProcessor() const; private: - CPlusPlus::Class *m_startClass; - CPlusPlus::Function *m_function; - CPlusPlus::Snapshot m_snapshot; - bool m_openInNextSplit; + Parameters m_params; }; class FunctionHelper diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp index f9dc85b528e..04b2c273bc0 100644 --- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp +++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp @@ -100,10 +100,9 @@ public: // Invoke the processor already here to calculate the proposals. Return false in order to // indicate that configure failed, so the actual code assist invocation leading to a pop-up // will not happen. - bool configure(CPlusPlus::Class *startClass, CPlusPlus::Function *function, - const CPlusPlus::Snapshot &snapshot, bool openInNextSplit) + bool configure(const VirtualFunctionAssistProvider::Parameters ¶ms) { - VirtualFunctionAssistProvider::configure(startClass, function, snapshot, openInNextSplit); + VirtualFunctionAssistProvider::configure(params); IAssistProcessor *processor = createProcessor(); IAssistInterface *assistInterface From 0c62b29f97cef5818ef189634406e651039ceb8a Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 23 Oct 2013 16:02:18 +0200 Subject: [PATCH 16/84] CppEditor: Fix position of virtual override list ...when using the mouse (Ctrl + Left click). Task-number: QTCREATORBUG-10479 Change-Id: I54a21c449d8bb8e608d383752beb3b31c9c81783 Reviewed-by: Erik Verbruggen --- src/plugins/cppeditor/cppfollowsymbolundercursor.cpp | 1 + .../cppeditor/cppvirtualfunctionassistprovider.cpp | 10 ++++------ .../cppeditor/cppvirtualfunctionassistprovider.h | 3 ++- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp index adc4640eb14..0132f592ad8 100644 --- a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp +++ b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp @@ -560,6 +560,7 @@ BaseTextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor & params.startClass = klass; params.function = function; params.snapshot = snapshot; + params.cursorPosition = cursor.position(); params.openInNextSplit = inNextSplit; if (m_virtualFunctionAssistProvider->configure(params)) { diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp index dbcfa540a41..76d6cc0d172 100644 --- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp +++ b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp @@ -113,9 +113,8 @@ public: : m_params(params) {} - IAssistProposal *immediateProposal(const TextEditor::IAssistInterface *assistInterface) + IAssistProposal *immediateProposal(const TextEditor::IAssistInterface *) { - QTC_ASSERT(assistInterface, return 0); QTC_ASSERT(m_params.function, return 0); BasicProposalItem *hintItem = new VirtualFunctionProposalItem(CPPEditorWidget::Link()); @@ -126,14 +125,13 @@ public: QList items; items << itemFromSymbol(maybeDefinitionFor(m_params.function)); items << hintItem; - return new VirtualFunctionProposal(assistInterface->position(), + return new VirtualFunctionProposal(m_params.cursorPosition, new BasicProposalItemListModel(items), m_params.openInNextSplit); } - IAssistProposal *perform(const IAssistInterface *assistInterface) + IAssistProposal *perform(const IAssistInterface *) { - QTC_ASSERT(assistInterface, return 0); QTC_ASSERT(m_params.startClass, return 0); QTC_ASSERT(m_params.function, return 0); QTC_ASSERT(!m_params.snapshot.isEmpty(), return 0); @@ -148,7 +146,7 @@ public: items << itemFromSymbol(maybeDefinitionFor(symbol)); items.first()->setOrder(1000); // Ensure top position for function of static type - return new VirtualFunctionProposal(assistInterface->position(), + return new VirtualFunctionProposal(m_params.cursorPosition, new BasicProposalItemListModel(items), m_params.openInNextSplit); } diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h index 2d91e298ee7..b5ff42d846b 100644 --- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h +++ b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.h @@ -46,11 +46,12 @@ public: VirtualFunctionAssistProvider(); struct Parameters { - Parameters() : startClass(0), function(0), openInNextSplit(false) {} + Parameters() : startClass(0), function(0), cursorPosition(-1), openInNextSplit(false) {} CPlusPlus::Class *startClass; CPlusPlus::Function *function; CPlusPlus::Snapshot snapshot; + int cursorPosition; bool openInNextSplit; }; From 170cf87c5ce2821d67029e98d3a5017221ac2720 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 23 Oct 2013 16:08:26 +0200 Subject: [PATCH 17/84] CppEditor: Underline text for a virtual function call link ...when using the mouse (Ctrl + Hover). Task-number: QTCREATORBUG-10480 Change-Id: Ifac5cf7859e724da910a2f7b2fcecd901eca5e13 Reviewed-by: Erik Verbruggen --- src/plugins/cppeditor/cppfollowsymbolundercursor.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp index 0132f592ad8..0b6cd23a6db 100644 --- a/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp +++ b/src/plugins/cppeditor/cppfollowsymbolundercursor.cpp @@ -568,7 +568,11 @@ BaseTextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor & m_virtualFunctionAssistProvider); } - return Link(); + // Ensure a valid link text, so the symbol name will be underlined on Ctrl+Hover. + Link link; + link.linkTextStart = beginOfToken; + link.linkTextEnd = endOfToken; + return link; } if (resolveTarget) { From 7bf30c46e97f43a93d06a1bb1ace10364b7e0659 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Wed, 23 Oct 2013 18:04:41 +0200 Subject: [PATCH 18/84] Squish: Updates for renamed objects and dialogs Change-Id: If12c82f7faadab67af31400a9688aec4088d4c1e Reviewed-by: Christian Stenger --- tests/system/objects.map | 10 +++++----- tests/system/shared/project.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/system/objects.map b/tests/system/objects.map index 92afa970b02..5eff1a358e2 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -152,7 +152,7 @@ :Qt Creator_Help::Internal::HelpViewer {type='Help::Internal::HelpViewer' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_HelpSelector_QComboBox {occurrence='3' type='QComboBox' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_Issues_Core::Internal::OutputPaneToggleButton {occurrence='1' type='Core::Internal::OutputPaneToggleButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} -:Qt Creator_ProFileEditorWidget {type='Qt4ProjectManager::Internal::ProFileEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} +:Qt Creator_ProFileEditorWidget {type='QmakeProjectManager::Internal::ProFileEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_PythonEditor::EditorWidget {type='PythonEditor::Internal::EditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_QDeclarativeView {type='QDeclarativeView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_QHelpContentWidget {type='QHelpContentWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} @@ -163,10 +163,10 @@ :Qt Creator_SystemSettings.Details_Utils::DetailsButton {occurrence='4' text='Details' type='Utils::DetailsButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_Utils::NavigationTreeView {type='Utils::NavigationTreeView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_Utils::NavigationTreeView::QExpandingLineEdit {container=':Qt Creator_Utils::NavigationTreeView' type='QExpandingLineEdit' unnamed='1' visible='1'} -:Qt Gui Application.Form file:_QLabel {name='formLabel' text='Form file:' type='QLabel' visible='1' window=':Qt Gui Application_Qt4ProjectManager::Internal::GuiAppWizardDialog'} -:Qt Gui Application.Header file:_QLabel {name='headerLabel' text='Header file:' type='QLabel' visible='1' window=':Qt Gui Application_Qt4ProjectManager::Internal::GuiAppWizardDialog'} -:Qt Gui Application.Source file:_QLabel {name='sourceLabel' text='Source file:' type='QLabel' visible='1' window=':Qt Gui Application_Qt4ProjectManager::Internal::GuiAppWizardDialog'} -:Qt Gui Application_Qt4ProjectManager::Internal::GuiAppWizardDialog {type='Qt4ProjectManager::Internal::GuiAppWizardDialog' unnamed='1' visible='1' windowTitle='Qt Gui Application'} +:Qt Gui Application.Form file:_QLabel {name='formLabel' text='Form file:' type='QLabel' visible='1' window=':Qt Gui Application_QmakeProjectManager::Internal::GuiAppWizardDialog'} +:Qt Gui Application.Header file:_QLabel {name='headerLabel' text='Header file:' type='QLabel' visible='1' window=':Qt Gui Application_QmakeProjectManager::Internal::GuiAppWizardDialog'} +:Qt Gui Application.Source file:_QLabel {name='sourceLabel' text='Source file:' type='QLabel' visible='1' window=':Qt Gui Application_QmakeProjectManager::Internal::GuiAppWizardDialog'} +:Qt Gui Application_QmakeProjectManager::Internal::GuiAppWizardDialog {type='QmakeProjectManager::Internal::GuiAppWizardDialog' unnamed='1' visible='1' windowTitle='Qt Widgets Application'} :QtSupport__Internal__QtVersionManager.QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' type='QLabel' unnamed='1' visible='1'} :QtSupport__Internal__QtVersionManager.errorLabel.QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='errorLabel' type='QLabel' visible='1'} :QtSupport__Internal__QtVersionManager.qmake_QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='qmakePath' type='QLabel' visible='1'} diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index f5aa4d3298d..3b821c37c86 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -175,7 +175,7 @@ def __verifyFileCreation__(path, expectedFiles): # param projectName is the name for the new project # param checks turns tests in the function on if set to True def createProject_Qt_GUI(path, projectName, checks = True): - template = "Qt Gui Application" + template = "Qt Widgets Application" available = __createProjectOrFileSelectType__(" Applications", template) __createProjectSetNameAndPath__(path, projectName, checks) checkedTargets = __selectQtVersionDesktop__(checks, available) From 46c1769e24d5cad7de89f62ec57244d4d5f2fe66 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 24 Oct 2013 11:34:01 +0200 Subject: [PATCH 19/84] Debugger: Show at least size for std::__1::unordered_map Change-Id: I51aaba021fd4893fb521251c9b4b9572c2beef44 Reviewed-by: hjk --- share/qtcreator/debugger/stdtypes.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py index d0fac283c0b..02f206c303b 100644 --- a/share/qtcreator/debugger/stdtypes.py +++ b/share/qtcreator/debugger/stdtypes.py @@ -494,6 +494,16 @@ def qdump__std__unordered_set(d, value): d.putSubItem(i, d.createValue(p + ptrSize, valueType)) p = d.dereference(p) +def qform__std____1__unordered_map(): + return mapForms() + +def qdump__std____1__unordered_map(d, value): + n = toInteger(value["__table_"]["__p2_"]["__first_"]) + d.putItemCount(n) + if d.isExpanded(): + with Children(d, 1): + d.putFields(value) + def qdump__std____debug__unordered_set(d, value): qdump__std__unordered_set(d, value) From fc4a953bb50c1e80c0bd9ef4f0c20c7ae929c4b5 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 24 Oct 2013 12:16:26 +0200 Subject: [PATCH 20/84] Debugger: Simplify LLDB communication protocol Produce proper JSON directly. Change-Id: I61aaba021fd4893fb521251c9b4b9572c2beef44 Reviewed-by: hjk --- share/qtcreator/debugger/lldbbridge.py | 27 +---------------- src/plugins/debugger/lldb/lldbengine.cpp | 38 ++++++++++++------------ 2 files changed, 20 insertions(+), 45 deletions(-) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index b6474089823..0906e3adc51 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -1699,32 +1699,7 @@ def doit(): for reader in readable: if reader == sys.stdin: line = sys.stdin.readline() - #warn("READING LINE '%s'" % line) - if line.startswith("db "): - line = line.replace("'", '"')[3:] - db.execute(convertHash(json.loads(line))) - - -def testit1(): - - db = Dumper() - - db.setupInferior({'cmd':'setupInferior','executable':sys.argv[2],'token':1}) - db.handleBreakpoints({'cmd':'handleBreakpoints','bkpts':[{'operation':'add', - 'modelid':'1','type':2,'ignorecount':0,'condition':'','function':'main', - 'oneshot':0,'enabled':1,'file':'','line':0}]}) - db.runEngine({'cmd':'runEngine','token':4}) - - while True: - readable, _, _ = select.select([sys.stdin], [], []) - for reader in readable: - if reader == sys.stdin: - line = sys.stdin.readline().strip() - #warn("READING LINE '%s'" % line) - if line.startswith("db "): - db.execute(eval(line[3:])) - else: - db.executeDebuggerCommand({'command':line}) + db.execute(convertHash(json.loads(line))) # Used in dumper auto test. diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index f6316631232..551d660a539 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -110,8 +110,8 @@ void LldbEngine::runCommand(const Command &command) QTC_ASSERT(m_lldbProc.state() == QProcess::Running, notifyEngineIll()); ++m_lastToken; QByteArray token = QByteArray::number(m_lastToken); - QByteArray cmd = "db {'cmd':'" + command.function + "'," - + command.args + "'token':" + token + "}\n"; + QByteArray cmd = "{\"cmd\":\"" + command.function + "\"," + + command.args + "\"token\":" + token + "}\n"; showMessage(_(token + cmd), LogInput); m_lldbProc.write(cmd); } @@ -156,7 +156,7 @@ void LldbEngine::setupEngine() m_lldbProc.start(_("python"), args); if (!m_lldbProc.waitForStarted()) { - const QString msg = tr("Unable to start LLDB '%1': %2") + const QString msg = tr("Unable to start LLDB \"%1\": %2") .arg(m_lldbCmd, m_lldbProc.errorString()); notifyEngineSetupFailed(); showMessage(_("ADAPTER START FAILED")); @@ -645,7 +645,7 @@ bool LldbEngine::setToolTipExpression(const QPoint &mousePos, } if (!hasLetterOrNumber(exp)) { - QToolTip::showText(m_toolTipPos, tr("'%1' contains no identifier.").arg(exp)); + QToolTip::showText(m_toolTipPos, tr("\"%1\" contains no identifier.").arg(exp)); return true; } @@ -665,7 +665,7 @@ bool LldbEngine::setToolTipExpression(const QPoint &mousePos, if (hasSideEffects(exp)) { QToolTip::showText(m_toolTipPos, - tr("Cowardly refusing to evaluate expression '%1' " + tr("Cowardly refusing to evaluate expression \"%1\" " "with potential side effects.").arg(exp)); return true; } @@ -794,7 +794,7 @@ QString LldbEngine::errorMessage(QProcess::ProcessError error) const switch (error) { case QProcess::FailedToStart: return tr("The LLDB process failed to start. Either the " - "invoked program '%1' is missing, or you may have insufficient " + "invoked program \"%1\" is missing, or you may have insufficient " "permissions to invoke the program.") .arg(m_lldbCmd); case QProcess::Crashed: @@ -856,12 +856,12 @@ void LldbEngine::requestUpdateWatchers() while (it.hasNext()) { it.next(); QHash hash; - hash["iname"] = "'watch." + QByteArray::number(it.value()) + '\''; - hash["exp"] = '\'' + it.key().toHex() + '\''; + hash["iname"] = "\"watch." + QByteArray::number(it.value()) + '"'; + hash["exp"] = '"' + it.key().toHex() + '"'; watcherData.append(Command::toData(hash)); } Command cmd("setWatchers"); - cmd.args.append("'watchers':" + Command::toData(watcherData) + ','); + cmd.args.append("\"watchers\":" + Command::toData(watcherData) + ','); runCommand(cmd); } @@ -1117,9 +1117,9 @@ DebuggerEngine *createLldbEngine(const DebuggerStartParameters &startParameters) const LldbEngine::Command &LldbEngine::Command::argHelper(const char *name, const QByteArray &data) const { - args.append('\''); + args.append('"'); args.append(name); - args.append("':"); + args.append("\":"); args.append(data); args.append(","); return *this; @@ -1144,7 +1144,7 @@ QByteArray LldbEngine::Command::toData(const QHash &valu it.next(); if (!res.isEmpty()) res.append(','); - res += '\'' + it.key() + "':" + it.value(); + res += '"' + it.key() + "\":" + it.value(); } return '{' + res + '}'; } @@ -1176,20 +1176,20 @@ const LldbEngine::Command &LldbEngine::Command::arg(const char *name, const QByt const LldbEngine::Command &LldbEngine::Command::arg(const char *name, const char *value) const { - args.append('\''); + args.append('"'); args.append(name); - args.append("':'"); + args.append("\":\""); args.append(value); - args.append("',"); + args.append("\","); return *this; } const LldbEngine::Command &LldbEngine::Command::beginList(const char *name) const { if (name) { - args += '\''; + args += '"'; args += name; - args += "':"; + args += "\":"; } args += '['; return *this; @@ -1205,9 +1205,9 @@ void LldbEngine::Command::endList() const const LldbEngine::Command &LldbEngine::Command::beginGroup(const char *name) const { if (name) { - args += '\''; + args += '"'; args += name; - args += "':"; + args += "\":"; } args += '{'; return *this; From de3f4a78e926779a1209c9f557d4b2630e53bbdd Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Thu, 24 Oct 2013 09:01:26 +0300 Subject: [PATCH 21/84] Add System encoding for Qt5 builds Workaround QTBUG-34283 Change-Id: Ia58c56a477d93722b21f17e54fc1acc89f1fb63f Reviewed-by: Eike Ziller --- src/plugins/texteditor/behaviorsettingswidget.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/texteditor/behaviorsettingswidget.cpp b/src/plugins/texteditor/behaviorsettingswidget.cpp index b21c709c219..044b2a328db 100644 --- a/src/plugins/texteditor/behaviorsettingswidget.cpp +++ b/src/plugins/texteditor/behaviorsettingswidget.cpp @@ -77,6 +77,13 @@ BehaviorSettingsWidget::BehaviorSettingsWidget(QWidget *parent) d->m_codecs.append(codec); } + // Qt5 doesn't list the system locale (QTBUG-34283), so add it manually + const QString system(QLatin1String("System")); + if (d->m_ui.encodingBox->findText(system) == -1) { + d->m_ui.encodingBox->insertItem(0, system); + d->m_codecs.prepend(QTextCodec::codecForLocale()); + } + connect(d->m_ui.autoIndent, SIGNAL(toggled(bool)), this, SLOT(slotTypingSettingsChanged())); connect(d->m_ui.smartBackspaceBehavior, SIGNAL(currentIndexChanged(int)), From 71080c8b8a9edef912d5fad99ad6563d079528b2 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 24 Oct 2013 12:42:00 +0200 Subject: [PATCH 22/84] Debugger: Fix std::map::iterator dumper for LLDB "Better" spaces in type names again... Change-Id: I21aafa021fd4893fb521251c9b4b9572c2beef44 Reviewed-by: hjk --- share/qtcreator/debugger/stdtypes.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py index 02f206c303b..98aada3e092 100644 --- a/share/qtcreator/debugger/stdtypes.py +++ b/share/qtcreator/debugger/stdtypes.py @@ -221,14 +221,13 @@ def qdump__std____cxx1998__map(d, value): qdump__std__map(d, value) def stdTreeIteratorHelper(d, value): - pnode = value["_M_node"] - node = pnode.dereference() + node = value["_M_node"].dereference() d.putNumChild(1) d.putEmptyValue() if d.isExpanded(): - dataType = d.templateArgument(value.type, 0) - nodeType = d.lookupType("std::_Rb_tree_node<%s>" % dataType) - data = pnode.cast(nodeType.pointer()).dereference()["_M_value_field"] + nodeTypeName = str(value.type).replace("_Rb_tree_iterator", "_Rb_tree_node", 1) + nodeType = d.lookupType(nodeTypeName) + data = node.cast(nodeType)["_M_value_field"] with Children(d): try: d.putSubItem("first", data["first"]) From 46bcfe657afd920201c29f05bb845999c81cfe86 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Thu, 24 Oct 2013 12:06:42 +0200 Subject: [PATCH 23/84] Squish: Removed code using Madde plugin We don't have a Madde plugin anymore Change-Id: Ic7a9fc33cdd967b642521655123c4b04158786fa Reviewed-by: Christian Stenger --- tests/system/shared/project.py | 10 +++---- tests/system/shared/utils.py | 6 ++-- .../tst_create_proj_wizard/test.py | 29 +++---------------- 3 files changed, 11 insertions(+), 34 deletions(-) diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index 3b821c37c86..16243564e8d 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -322,8 +322,7 @@ def createNewNonQtProject(workingDir=None, projectName=None, target=Targets.DESK # parameter target can be an OR'd value of Targets # parameter availableTargets should be the result of __createProjectOrFileSelectType__() # or use None as a fallback -def __chooseTargets__(targets=Targets.DESKTOP_474_GCC, availableTargets=None, - isMaddeDisabled=True): +def __chooseTargets__(targets=Targets.DESKTOP_474_GCC, availableTargets=None): if availableTargets != None: available = availableTargets else: @@ -333,10 +332,9 @@ def __chooseTargets__(targets=Targets.DESKTOP_474_GCC, availableTargets=None, if platform.system() in ('Windows', 'Microsoft'): available.remove(Targets.EMBEDDED_LINUX) available.append(Targets.DESKTOP_480_MSVC2010) - if isMaddeDisabled: - for target in filter(lambda x: x in available, - (Targets.MAEMO5, Targets.HARMATTAN)): - available.remove(target) + for target in filter(lambda x: x in available, + (Targets.MAEMO5, Targets.HARMATTAN)): + available.remove(target) checkedTargets = [] for current in available: mustCheck = targets & current == current diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index 335f6ce1873..3279980aab7 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -373,7 +373,7 @@ def __checkParentAccess__(filePath): # this function checks for all configured Qt versions inside # options dialog and returns a dict holding the kits as keys # and a list of information of its configured Qt -def getConfiguredKits(isMaddeDisabled=True): +def getConfiguredKits(): def __retrieveQtVersionName__(target, version): treeWidget = waitForObject(":QtSupport__Internal__QtVersionManager.qtdirList_QTreeWidget") return treeWidget.currentItem().text(0) @@ -393,8 +393,8 @@ def getConfiguredKits(isMaddeDisabled=True): iterateKits(True, True, __setQtVersionForKit__, kitsWithQtVersionName) # merge defined target names with their configured Qt versions and devices for kit, qtVersion in kitsWithQtVersionName.iteritems(): - if isMaddeDisabled and kit in ('Fremantle', 'Harmattan') and qtVersion == 'None': - test.log("Found Kit '%s' with unassigned Qt version (disabled Madde plugin)" % kit) + if kit in ('Fremantle', 'Harmattan') and qtVersion == 'None': + test.log("Found Kit '%s' with unassigned Qt version (disabled Madde plugin)" % kit) elif qtVersion in qtVersionNames: result[kit] = targetsQtVersions[qtVersionNames.index(qtVersion)].items()[0] else: diff --git a/tests/system/suite_general/tst_create_proj_wizard/test.py b/tests/system/suite_general/tst_create_proj_wizard/test.py index 21a8d29525a..77fee043a24 100644 --- a/tests/system/suite_general/tst_create_proj_wizard/test.py +++ b/tests/system/suite_general/tst_create_proj_wizard/test.py @@ -33,6 +33,7 @@ import re def main(): global tmpSettingsDir + global textChanged sourceExample = os.path.abspath(sdkPath + "/Examples/4.7/declarative/text/textselection") qmlFile = os.path.join("qml", "textselection.qml") if not neededFilePresent(os.path.join(sourceExample, qmlFile)): @@ -44,19 +45,7 @@ def main(): overrideInstallLazySignalHandler() installLazySignalHandler(":frame.templateDescription_QTextBrowser", "textChanged()","__handleTextChanged__") - performTest(templateDir, qmlFile, True) - enableMaddePlugin() - invokeMenuItem("File", "Exit") - waitForCleanShutdown() - copySettingsToTmpDir(tmpSettingsDir, ['QtCreator.ini']) - overrideStartApplication() - startApplication("qtcreator" + SettingsPath) - performTest(templateDir, qmlFile, False) - invokeMenuItem("File", "Exit") - -def performTest(templateDir, qmlFile, isMaddeDisabled): - global textChanged - kits = getConfiguredKits(isMaddeDisabled) + kits = getConfiguredKits() test.log("Collecting potential project types...") availableProjectTypes = [] invokeMenuItem("File", "New File or Project...") @@ -69,7 +58,7 @@ def performTest(templateDir, qmlFile, isMaddeDisabled): maddeTargets = Targets.getTargetsAsStrings([Targets.MAEMO5, Targets.HARMATTAN]) maddeInTargets = len(set(targets) & set(maddeTargets)) > 0 test.verify(comboBox.enabled, "Verifying whether combobox is enabled.") - test.compare(maddeInTargets, not isMaddeDisabled, "Verifying if kits are configured.") + test.verify(not maddeInTargets, "Verify there are no leftovers of Madde") test.compare(comboBox.currentText, "Desktop Templates") selectFromCombo(comboBox, "All Templates") for category in [item.replace(".", "\\.") for item in dumpItems(catModel, projects)]: @@ -133,17 +122,7 @@ def performTest(templateDir, qmlFile, isMaddeDisabled): test.fail("Found unexpected additional kit(s) %s on 'Kit Selection' page." % str(availableCheckboxes)) clickButton(waitForObject("{text='Cancel' type='QPushButton' unnamed='1' visible='1'}")) - -def enableMaddePlugin(): - invokeMenuItem("Help", "About Plugins...") - pluginsTW = waitForObject(":Installed Plugins.categoryWidget_QTreeWidget") - devSupport = ("{container=':Installed Plugins.categoryWidget_QTreeWidget' " - "column='0' text='Device Support' type='QModelIndex'}") - # children position + 1 because children will be counted beginning with 0 - maddePos = dumpItems(pluginsTW.model(), waitForObject(devSupport)).index('Madde') + 1 - mouseClick(waitForObject("{column='1' container=%s text='' type='QModelIndex' " - "occurrence='%d'}" % (devSupport, maddePos)), 5, 5, 0, Qt.LeftButton) - clickButton(":Installed Plugins.Close_QPushButton") + invokeMenuItem("File", "Exit") def __handleTextChanged__(*args): global textChanged From f52039640b4af99eb6a83120f0e2ff257469bf64 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Thu, 24 Oct 2013 13:35:00 +0200 Subject: [PATCH 24/84] File System View: Make keyboard navigation magical Ensuring that there's always a current index is hard work since the data comes in asynchronously and is unsorted at first. Task-number: QTCREATORBUG-10250 Change-Id: I2cd1420bb447ad7257f6200bcffc454a214932aa Reviewed-by: Orgad Shaneh --- .../foldernavigationwidget.cpp | 22 ++++++++++++++++++- .../projectexplorer/foldernavigationwidget.h | 1 + 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp index 6aad3a6b208..4e26ef1101b 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.cpp +++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp @@ -158,6 +158,8 @@ FolderNavigationWidget::FolderNavigationWidget(QWidget *parent) this, SLOT(slotOpenItem(QModelIndex))); connect(m_filterHiddenFilesAction, SIGNAL(toggled(bool)), this, SLOT(setHiddenFilesFilter(bool))); connect(m_toggleSync, SIGNAL(clicked(bool)), this, SLOT(toggleAutoSynchronization())); + connect(m_filterModel, SIGNAL(layoutChanged()), + this, SLOT(ensureCurrentIndex())); } void FolderNavigationWidget::toggleAutoSynchronization() @@ -225,10 +227,17 @@ bool FolderNavigationWidget::setCurrentDirectory(const QString &directory) setCurrentTitle(QString(), QString()); return false; } - m_listView->setRootIndex(m_filterModel->mapFromSource(index)); + QModelIndex oldRootIndex = m_listView->rootIndex(); + QModelIndex newRootIndex = m_filterModel->mapFromSource(index); + m_listView->setRootIndex(newRootIndex); const QDir current(QDir::cleanPath(newDirectory)); setCurrentTitle(current.dirName(), QDir::toNativeSeparators(current.absolutePath())); + if (oldRootIndex.parent() == newRootIndex) { // cdUp, so select the old directory + m_listView->setCurrentIndex(oldRootIndex); + m_listView->scrollTo(oldRootIndex, QAbstractItemView::EnsureVisible); + } + return !directory.isEmpty(); } @@ -365,6 +374,17 @@ bool FolderNavigationWidget::hiddenFilesFilter() const return m_filterHiddenFilesAction->isChecked(); } +void FolderNavigationWidget::ensureCurrentIndex() +{ + QModelIndex index = m_listView->currentIndex(); + if (!index.isValid() + || index.parent() != m_listView->rootIndex()) { + index = m_listView->rootIndex().child(0, 0); + m_listView->setCurrentIndex(index); + } + m_listView->scrollTo(index); +} + // --------------------FolderNavigationWidgetFactory FolderNavigationWidgetFactory::FolderNavigationWidgetFactory() { diff --git a/src/plugins/projectexplorer/foldernavigationwidget.h b/src/plugins/projectexplorer/foldernavigationwidget.h index 6b6aaed266e..f99a9262e8e 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.h +++ b/src/plugins/projectexplorer/foldernavigationwidget.h @@ -70,6 +70,7 @@ private slots: void setCurrentFile(const QString &filePath); void slotOpenItem(const QModelIndex &viewIndex); void setHiddenFilesFilter(bool filter); + void ensureCurrentIndex(); protected: virtual void contextMenuEvent(QContextMenuEvent *ev); From e7418a9c95b13a1360140d20aaf6a830dc9d6a78 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 24 Oct 2013 14:11:58 +0200 Subject: [PATCH 25/84] QmlDesigner.PropertyEditor: some adjustment to ComboBox style Change-Id: I52a80941e343ad9ad3cca7bc0bcdec8fe0a90156 Reviewed-by: Thomas Hartmann --- .../HelperWidgets/CustomComboBoxStyle.qml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/CustomComboBoxStyle.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/CustomComboBoxStyle.qml index 185ac8b7ce7..29f03abdcb5 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/CustomComboBoxStyle.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/CustomComboBoxStyle.qml @@ -67,12 +67,24 @@ ComboBoxStyle { opacity: 0.3 visible: control.activeFocus } + + Rectangle { + color: "#333" + width: 1 + anchors.right: imageItem.left + anchors.topMargin: 4 + anchors.bottomMargin: 4 + anchors.rightMargin: 6 + anchors.top: parent.top + anchors.bottom: parent.bottom + } + Image { id: imageItem source: "images/down-arrow.png" anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right - anchors.rightMargin: 8 + anchors.rightMargin: 10 opacity: control.enabled ? 0.7 : 0.5 } } From 4cd8f0b3e24d38dea758fdf796e6c816b9e5a11c Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 24 Oct 2013 14:12:54 +0200 Subject: [PATCH 26/84] QmlDesigner.PropertyEditor: adjust TabView style Styling the TabView in css is problematic and we want to keep the style in sync. So we use the old style here. Change-Id: I57ed39a03b4b4c59e9a996ca4e14d4d9fe9dfeb2 Reviewed-by: Thomas Hartmann --- .../HelperWidgets/TabView.qml | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/TabView.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/TabView.qml index 9a5bdbdb9cd..2f46721e2a8 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/TabView.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/TabView.qml @@ -40,26 +40,28 @@ Controls.TabView { frameOverlap: 0 frame: Item { } tab: Rectangle { - color: styleData.selected ? "#eee" : "#444" + color: styleData.selected ? "#eee" : "#414141" implicitWidth: root.width/root.count + 2 - implicitHeight: 21 + implicitHeight: 28 Text { id: text + font.bold: true anchors.centerIn: parent + anchors.verticalCenterOffset: -1 text: styleData.title renderType: Text.NativeRendering - color: styleData.selected ? "#000" : "#fff" + color: styleData.selected ? "#333" : "#fff" } + Rectangle { - anchors.fill: parent - opacity: 0.10 - gradient: Gradient { - GradientStop {color: '#fff' ; position: 0} - GradientStop {color: '#000' ; position: 1} - } + color: "#eee" + width: parent.width + height: 4 + anchors.bottom: parent.bottom } + Rectangle { - color: "#666" + color: "#333" width: parent.width height: 1 } From cc18936d1759e58633417d030f5812e88f0888bf Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 24 Oct 2013 14:16:31 +0200 Subject: [PATCH 27/84] QmlDesigner: adjustment of Section(View) Adjusting the item library and property editor, so they follow the same style for sections. Change-Id: I79d3560acff3b126056cf55b81fd21a531f9594c Reviewed-by: Thomas Hartmann --- .../HelperWidgets/Section.qml | 11 ++++++- .../itemlibrary/qml/SectionView.qml | 32 +++++++++++++++---- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/Section.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/Section.qml index c59fe14ad98..9380e844ce2 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/Section.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/HelperWidgets/Section.qml @@ -52,6 +52,9 @@ Item { anchors.verticalCenter: parent.verticalCenter color: "white" x: 22 + style: Text.Sunken + styleColor: "#292929" + font.bold: true } Image { @@ -103,9 +106,10 @@ Item { x: 8 y: header.height + 4 id: row + Behavior on opacity { NumberAnimation{easing.type: Easing.Linear ; duration: 80} } } - Behavior on height { NumberAnimation{easing.type: Easing.OutCubic ; duration: 60} } + Behavior on height { NumberAnimation{easing.type: Easing.OutCubic ; duration: 140} } states: [ State { @@ -114,6 +118,11 @@ Item { target: section height: header.height } + PropertyChanges { + target: row + opacity: 0 + + } } ] diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml index 5a43d7de750..bfc324ebe46 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml @@ -28,6 +28,7 @@ ****************************************************************************/ import QtQuick 2.1 +import QtQuick.Controls 1.0 as Controls // view displaying one item library section including its grid @@ -114,12 +115,27 @@ Column { width: parent.width height: style.sectionTitleHeight - color: style.sectionTitleBackgroundColor + gradient: Gradient { + GradientStop {color: '#555' ; position: 0} + GradientStop {color: '#444' ; position: 1} + } + + Rectangle { + color:"#333" + width: parent.width + height: 1 + } + + Rectangle { + color: "#333" + anchors.bottom: parent.bottom + width: parent.width + height: 1 + } Item { id: arrow - Rectangle { y: 0; x: 0; height: 1; width: 11; color: style.sectionArrowColor } Rectangle { y: 1; x: 1; height: 1; width: 9; color: style.sectionArrowColor } Rectangle { y: 2; x: 2; height: 1; width: 7; color: style.sectionArrowColor } Rectangle { y: 3; x: 3; height: 1; width: 5; color: style.sectionArrowColor } @@ -127,25 +143,26 @@ Column { Rectangle { y: 5; x: 5; height: 1; width: 1; color: style.sectionArrowColor } anchors.left: parent.left - anchors.leftMargin: 10 + anchors.leftMargin: 4 anchors.verticalCenter: parent.verticalCenter width: 11 height: 6 transformOrigin: Item.Center } - Text { + Controls.Label { id: text anchors.verticalCenter: parent.verticalCenter anchors.left: arrow.right - anchors.leftMargin: 12 + anchors.leftMargin: 4 text: sectionName // to be set by model color: style.sectionTitleTextColor elide: Text.ElideMiddle font.bold: true - renderType: Text.NativeRendering + style: Text.Sunken + styleColor: "#292929" } MouseArea { id: mouseArea @@ -161,6 +178,9 @@ Column { Item { id: gridFrame + Behavior on opacity { NumberAnimation{easing.type: Easing.Linear ; duration: 80} } + Behavior on height { NumberAnimation{easing.type: Easing.OutCubic ; duration: 140} } + function toggleExpanded() { state = ((state == "")? "shrunk":"") From 67bb1dd78368ae601f70c6f4ed09f28523943caa Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 24 Oct 2013 14:18:14 +0200 Subject: [PATCH 28/84] QmlDesigner: adjusting scrollbar Going for a simpler and cleaner design that works well with css. The old one looked broken. Change-Id: I034febcd2b9d9f395945ebad153934990c1e3d81 Reviewed-by: Thomas Hartmann --- .../components/itemlibrary/qml/ItemsView.qml | 1 + .../components/itemlibrary/qml/Scrollbar.qml | 21 +++++-------- .../components/resources/scrollbar.css | 31 +++++++------------ .../stateseditor/HorizontalScrollBar.qml | 10 ++---- 4 files changed, 21 insertions(+), 42 deletions(-) diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml index 793d7ea7f01..697d3a95a8c 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml @@ -223,6 +223,7 @@ content position out of scope regarding the scrollbar. */ anchors.bottom: parent.bottom anchors.bottomMargin: 1 anchors.right: parent.right + anchors.rightMargin: 2 width: (itemsFlickable.contentHeight > itemsFlickable.height)? 11:0 Scrollbar { diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml index 33bc50fc800..23adc86abb2 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml @@ -39,11 +39,11 @@ Item { property variant flickable function scroll(delta) { - handle.y = Math.max(0, Math.min(scrollHeight, handle.y + delta)) + handle.y = Math.max(2, Math.min(scrollHeight, handle.y + delta)) } function reset() { - handle.y = 0 + handle.y = 2 } // internal @@ -62,8 +62,7 @@ Item { anchors.bottom: parent.bottom anchors.bottomMargin: 3 anchors.horizontalCenter: parent.horizontalCenter - width: 6 - radius: 3 + width: 10 color: style.scrollbarColor border.width: 1 border.color: style.scrollbarBorderColor @@ -77,7 +76,7 @@ Item { flickable.contentY / (flickable.contentHeight - flickable.height), 1) else - handle.y = 0 + handle.y = 2 handle.updateFlickable = true } @@ -109,6 +108,7 @@ Item { Item { id: handle + y: 2 anchors.left: parent.left anchors.right: parent.right @@ -125,27 +125,20 @@ Item { width: parent.height height: parent.width y: -height - 2 - x: -2 rotation: 90 transformOrigin: Item.BottomLeft border.color: style.scrollbarBorderColor border.width: 1 - radius: 3 - - gradient: Gradient { - GradientStop { position: 0.15; color: style.scrollbarGradientStartColor } - GradientStop { position: 0.78; color: style.scrollbarGradientMiddleColor } - GradientStop { position: 0.80; color: style.scrollbarGradientEndColor } - } + color: style.sectionTitleBackgroundColor } MouseArea { anchors.fill: parent drag.target: parent drag.axis: "YAxis" - drag.minimumY: 0 + drag.minimumY: 2 drag.maximumY: scrollHeight } } diff --git a/src/plugins/qmldesigner/components/resources/scrollbar.css b/src/plugins/qmldesigner/components/resources/scrollbar.css index 34e8af8acbd..661c987cb93 100644 --- a/src/plugins/qmldesigner/components/resources/scrollbar.css +++ b/src/plugins/qmldesigner/components/resources/scrollbar.css @@ -1,26 +1,21 @@ QScrollBar:vertical { - border-image: url(:/qmldesigner/images/scrollbar-borderimage-vertical.png); - border-left: 0; - border-right: 0; - border-top: 3; - border-bottom: 3; + background-color: #444444; + border: 1px solid #333333; margin-top: 3; margin-bottom: 3; width: 10; } QScrollBar::handle:vertical { - background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, - stop: 0.20 #888888, - stop: 0.23 #656565, - stop: 0.85 #393939); + background-color: #656565; margin-top: -5; margin-bottom: -5; min-height: 18px; width: 8px; border: 1px solid #313131; - border-radius: 4px; border-width: 1; + margin-left: -1; + margin-right: -1; } QScrollBar::add-line:vertical { @@ -49,28 +44,24 @@ } QScrollBar:horizontal { - border-image: url(:/qmldesigner/images/scrollbar-borderimage-horizontal.png); - border-left: 3; - border-right: 3; - border-top: 0; - border-bottom: 0; + background-color: #444444; + border: 1px solid #333333; margin-left: 3; margin-right: 3; height: 10; } QScrollBar::handle:horizontal { - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0.20 #888888, - stop: 0.23 #656565, - stop: 0.85 #393939); + background-color: #656565; + margin-left: -5; margin-right: -5; min-width: 18px; height: 8px; border: 1px solid #313131; - border-radius: 4px; border-width: 1; + margin-top: -1; + margin-bottom: -1; } QScrollBar::add-line:horizontal { diff --git a/src/plugins/qmldesigner/components/stateseditor/HorizontalScrollBar.qml b/src/plugins/qmldesigner/components/stateseditor/HorizontalScrollBar.qml index a1077e7ead8..08479b6a70a 100644 --- a/src/plugins/qmldesigner/components/stateseditor/HorizontalScrollBar.qml +++ b/src/plugins/qmldesigner/components/stateseditor/HorizontalScrollBar.qml @@ -55,9 +55,8 @@ Item { Rectangle { id: groove width: parent.width - 4 - height: 6 + height: 10 color: "#444444" - radius: 3 border.width: 1 border.color: "#333333" anchors.right: parent.right @@ -95,13 +94,8 @@ Item { y:0 border.color: "#333333" border.width: 1 - radius: 3 - gradient: Gradient { - GradientStop { position: 0.20; color: "#888888" } - GradientStop { position: 0.23; color: "#656565" } - GradientStop { position: 0.85; color: "#393939" } - } + color: "#656565" MouseArea { property int dragging:0; From 0cdb0724c2ac1294f11a9d95e417e8c229841e4e Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 24 Oct 2013 14:13:37 +0200 Subject: [PATCH 29/84] QmlDesiger.PropertyEditor: adjust background color Change-Id: I403c37f2cda84980dfe441746f3c5bed7258a4ca Reviewed-by: Thomas Hartmann --- .../qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml | 2 +- .../qmldesigner/propertyEditorQmlSources/QtQuick/emptyPane.qml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml index 4090bb48146..ac06c060714 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml @@ -35,7 +35,7 @@ Rectangle { id: itemPane width: 320 height: 400 - color: "#404040" + color: "#4f4f4f" ScrollView { anchors.fill: parent diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/emptyPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/emptyPane.qml index 15f6a80781e..dd0b2834c58 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/emptyPane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/emptyPane.qml @@ -34,9 +34,10 @@ Rectangle { id: itemPane width: 320 height: 400 - color: "#404040" + color: "#4f4f4f" Section { + y: -1 anchors.left: parent.left anchors.right: parent.right From bec68f6f13f51054b10d742ea284d9c793d19318 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 24 Oct 2013 14:18:35 +0200 Subject: [PATCH 30/84] QmlDesigmer.ItemLibrary: minor adjustment to layout Change-Id: I444c342cb15473bfd65c3e2f364e285b21068319 Reviewed-by: Thomas Hartmann --- .../qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml index e5f29de94ce..c112ffa50fb 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml @@ -61,7 +61,7 @@ Item { property int textWidth: 95 property int textHeight: 15 - property int cellHorizontalMargin: 5 + property int cellHorizontalMargin: 4 property int cellVerticalSpacing: 7 property int cellVerticalMargin: 10 From 9351b1ce35e93bd2d9d956d72f1cf7cca630598f Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 24 Oct 2013 14:19:37 +0200 Subject: [PATCH 31/84] QmlDesigner.PropertyEditor: adjustment to layout of ItemPane * Adding some space above the TabWidget * Avoiding double black lines at the top Change-Id: I0aedf151b548a665445d4219609738b2ab23c0be Reviewed-by: Thomas Hartmann --- .../propertyEditorQmlSources/QtQuick/ItemPane.qml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml index ac06c060714..a37302673ac 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml @@ -41,6 +41,7 @@ Rectangle { anchors.fill: parent Column { + y: -1 width: itemPane.width Section { caption: qsTr("Type") @@ -146,6 +147,11 @@ Rectangle { } } + Item { + height: 4 + width: 4 + } + TabView { anchors.left: parent.left anchors.right: parent.right From 7a443ace0d5642382865bc1e46381e11a416949e Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 24 Oct 2013 14:22:48 +0200 Subject: [PATCH 32/84] CppEditor: Fix build with namespaced Qt. Change-Id: I30f872a57982c4de9fedec9c9e845bcf1fd0252b Reviewed-by: Nikolai Kosjar --- src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp index 04b2c273bc0..2a2c754e639 100644 --- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp +++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp @@ -77,6 +77,7 @@ inline bool operator==(const OverrideItem &lhs, const OverrideItem &rhs) return lhs.text == rhs.text && lhs.line == rhs.line; } +QT_BEGIN_NAMESPACE namespace QTest { template<> char *toString(const OverrideItem &data) { @@ -86,6 +87,7 @@ template<> char *toString(const OverrideItem &data) return qstrdup(ba.data()); } } +QT_END_NAMESPACE namespace { From cd3c084df35d08f094488aed6a9ae301b56a6667 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 24 Oct 2013 13:27:10 +0200 Subject: [PATCH 33/84] Debugger: Improve QSharedPointer dumper Make it work with LLDB, show simple values always directly. Change-Id: I463ef81183792f85243d679dee69a41db00bed07 Reviewed-by: hjk --- share/qtcreator/debugger/gdbbridge.py | 3 +++ share/qtcreator/debugger/lldbbridge.py | 3 +++ share/qtcreator/debugger/qttypes.py | 7 +++---- tests/auto/debugger/tst_dumpers.cpp | 4 ++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index 914cba7b160..8955c09612a 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -1362,6 +1362,9 @@ class Dumper(DumperBase): self.currentValuePriority = priority self.currentValueEncoding = None + def putSimpleValue(self, value, encoding = None, priority = 0): + self.putValue(value, encoding, priority) + def putValue(self, value, encoding = None, priority = 0): # Higher priority values override lower ones. if priority >= self.currentValuePriority: diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 0906e3adc51..2982546a87b 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -607,6 +607,9 @@ class Dumper(DumperBase): self.currentValuePriority = priority self.currentValueEncoding = None + def putSimpleValue(self, value, encoding = None, priority = 0): + self.putValue(value.GetValue(), encoding, priority) + def putValue(self, value, encoding = None, priority = 0): # Higher priority values override lower ones. if priority >= self.currentValuePriority: diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index eb336fa08e2..fb6e6b18f62 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -1970,16 +1970,15 @@ def qdump__QWeakPointer(d, value): d.check(strongref <= weakref) d.check(weakref <= 10*1000*1000) - if d.isSimpleType(val.dereference().type): - d.putNumChild(3) - d.putItem(val.dereference()) + innerType = d.templateArgument(value.type, 0) + if d.isSimpleType(innerType): + d.putSimpleValue(val.dereference()) else: d.putEmptyValue() d.putNumChild(3) if d.isExpanded(): with Children(d): - innerType = d.templateArgument(value.type, 0) d.putSubItem("data", val.dereference().cast(innerType)) d.putIntItem("weakref", weakref) d.putIntItem("strongref", strongref) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index b518e189a30..fba59c77c93 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -2395,11 +2395,11 @@ void tst_Dumpers::dumper_data() "QWeakPointer ptr3 = ptr;\n" "unused(&ptr, &ptr2, &ptr3);\n") % CoreProfile() - % Check("iptr", "", "@QSharedPointer") + % Check("iptr", "43", "@QSharedPointer") % Check("iptr.data", "43", "int") % Check("iptr.weakref", "4", "int") % Check("iptr.strongref", "1", "int") - % Check("ptr3", "43", "int") + % Check("ptr3", "43", "@QWeakPointer") % Check("ptr3.data", "43", "int"); QTest::newRow("QSharedPointer4") From 6d4cc2231a601c83c90a6041c74170b6aa414085 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 24 Oct 2013 15:24:31 +0200 Subject: [PATCH 34/84] Debugger: Handle _Rb_tree_const_iterator, too Change-Id: I01baa597976ec5f6e84c8c52aff6e617082b1a28 Reviewed-by: hjk --- share/qtcreator/debugger/stdtypes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py index 98aada3e092..017a02672ea 100644 --- a/share/qtcreator/debugger/stdtypes.py +++ b/share/qtcreator/debugger/stdtypes.py @@ -226,6 +226,7 @@ def stdTreeIteratorHelper(d, value): d.putEmptyValue() if d.isExpanded(): nodeTypeName = str(value.type).replace("_Rb_tree_iterator", "_Rb_tree_node", 1) + nodeTypeName = nodeTypeName.replace("_Rb_tree_const_iterator", "_Rb_tree_node", 1) nodeType = d.lookupType(nodeTypeName) data = node.cast(nodeType)["_M_value_field"] with Children(d): From 0b8f3c3e9d3392bf41a31caff8c47283a3929139 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 24 Oct 2013 15:05:02 +0200 Subject: [PATCH 35/84] Debugger: Continue LLDB event loop after exceptions Change-Id: I4d3547396384fe5b421c4b601b52476a23cdfa89 Reviewed-by: hjk --- share/qtcreator/debugger/lldbbridge.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 2982546a87b..e1416d18fa1 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -1702,7 +1702,11 @@ def doit(): for reader in readable: if reader == sys.stdin: line = sys.stdin.readline() - db.execute(convertHash(json.loads(line))) + try: + db.execute(convertHash(json.loads(line))) + except: + warn("EXCEPTION CAUGHT: %s" % sys.exc_info()[1]) + pass # Used in dumper auto test. From 01c8e98d0bf384d0eeadb946796ff405e6acd6fc Mon Sep 17 00:00:00 2001 From: El Mehdi Fekari Date: Tue, 8 Oct 2013 11:39:44 +0200 Subject: [PATCH 36/84] Qnx: Check device connection when debugging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the device connection verification code from BlackBerryRunControl class into BlackBerryApplicaitonRunner class. This will setup a device connection if the device is not connected when starting debugger. Task-number: QTCREATORBUG-10309 Change-Id: I57db0e60039bb05f8467e925e71cf710a0712791 Reviewed-by: Nicolas Arnaud-Cormos Reviewed-by: Tobias Nätterlund --- .../qnx/blackberryapplicationrunner.cpp | 86 ++++++++++++++----- src/plugins/qnx/blackberryapplicationrunner.h | 4 + src/plugins/qnx/blackberrydebugsupport.cpp | 2 +- .../qnx/blackberrydeviceconnectionmanager.cpp | 4 +- .../qnx/blackberrydeviceconnectionmanager.h | 1 + src/plugins/qnx/blackberryruncontrol.cpp | 34 +------- src/plugins/qnx/blackberryruncontrol.h | 6 -- 7 files changed, 75 insertions(+), 62 deletions(-) diff --git a/src/plugins/qnx/blackberryapplicationrunner.cpp b/src/plugins/qnx/blackberryapplicationrunner.cpp index 7e2ed840255..8178f2b3afc 100644 --- a/src/plugins/qnx/blackberryapplicationrunner.cpp +++ b/src/plugins/qnx/blackberryapplicationrunner.cpp @@ -32,6 +32,7 @@ #include "blackberryapplicationrunner.h" #include "blackberrydeployconfiguration.h" +#include "blackberrydeviceconnectionmanager.h" #include "blackberryrunconfiguration.h" #include "blackberrylogprocessrunner.h" #include "qnxconstants.h" @@ -94,28 +95,17 @@ BlackBerryApplicationRunner::BlackBerryApplicationRunner(bool debugMode, BlackBe void BlackBerryApplicationRunner::start() { - QStringList args; - args << QLatin1String("-launchApp"); - if (m_debugMode) - args << QLatin1String("-debugNative"); - args << QLatin1String("-device") << m_sshParams.host; - if (!m_sshParams.password.isEmpty()) - args << QLatin1String("-password") << m_sshParams.password; - args << QDir::toNativeSeparators(m_barPackage); - - if (!m_launchProcess) { - m_launchProcess = new QProcess(this); - connect(m_launchProcess, SIGNAL(readyReadStandardError()), this, SLOT(readStandardError())); - connect(m_launchProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readStandardOutput())); - connect(m_launchProcess, SIGNAL(finished(int,QProcess::ExitStatus)), - this, SLOT(startFinished(int,QProcess::ExitStatus))); - - m_launchProcess->setEnvironment(m_environment.toStringList()); + if (!BlackBerryDeviceConnectionManager::instance()->isConnected(m_device->id())) { + connect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(deviceConnected()), + this, SLOT(launchApplication())); + connect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(deviceDisconnected(Core::Id)), + this, SLOT(disconnectFromDeviceSignals(Core::Id))); + connect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(connectionOutput(Core::Id,QString)), + this, SLOT(displayConnectionOutput(Core::Id,QString))); + BlackBerryDeviceConnectionManager::instance()->connectDevice(m_device->id()); + } else { + launchApplication(); } - - m_launchProcess->start(m_deployCmd, args); - m_runningStateTimer->start(); - m_running = true; } void BlackBerryApplicationRunner::startLogProcessRunner() @@ -130,6 +120,17 @@ void BlackBerryApplicationRunner::startLogProcessRunner() m_logProcessRunner->start(); } +void BlackBerryApplicationRunner::displayConnectionOutput(Core::Id deviceId, const QString &msg) +{ + if (deviceId != m_device->id()) + return; + + if (msg.contains(QLatin1String("Info:"))) + emit output(msg, Utils::StdOutFormat); + else if (msg.contains(QLatin1String("Error:"))) + emit output(msg, Utils::StdErrFormat); +} + void BlackBerryApplicationRunner::startFinished(int exitCode, QProcess::ExitStatus exitStatus) { if (exitCode == 0 && exitStatus == QProcess::NormalExit && m_pid > -1) { @@ -214,6 +215,18 @@ void BlackBerryApplicationRunner::readStandardError() } } +void BlackBerryApplicationRunner::disconnectFromDeviceSignals(Core::Id deviceId) +{ + if (m_device->id() == deviceId) { + disconnect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(deviceConnected()), + this, SLOT(launchApplication())); + disconnect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(deviceDisconnected(Core::Id)), + this, SLOT(disconnectFromDeviceSignals(Core::Id))); + disconnect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(connectionOutput(Core::Id,QString)), + this, SLOT(displayConnectionOutput(Core::Id,QString))); + } +} + void BlackBerryApplicationRunner::setPid(qint64 pid) { m_pid = pid; @@ -224,6 +237,37 @@ void BlackBerryApplicationRunner::setApplicationId(const QString &applicationId) m_appId = applicationId; } +void BlackBerryApplicationRunner::launchApplication() +{ + // If original device connection fails before launching, this method maybe triggered + // if any other device is connected(?) + if (!BlackBerryDeviceConnectionManager::instance()->isConnected(m_device->id())) + return; + + QStringList args; + args << QLatin1String("-launchApp"); + if (m_debugMode) + args << QLatin1String("-debugNative"); + args << QLatin1String("-device") << m_sshParams.host; + if (!m_sshParams.password.isEmpty()) + args << QLatin1String("-password") << m_sshParams.password; + args << QDir::toNativeSeparators(m_barPackage); + + if (!m_launchProcess) { + m_launchProcess = new QProcess(this); + connect(m_launchProcess, SIGNAL(readyReadStandardError()), this, SLOT(readStandardError())); + connect(m_launchProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readStandardOutput())); + connect(m_launchProcess, SIGNAL(finished(int,QProcess::ExitStatus)), + this, SLOT(startFinished(int,QProcess::ExitStatus))); + + m_launchProcess->setEnvironment(m_environment.toStringList()); + } + + m_launchProcess->start(m_deployCmd, args); + m_runningStateTimer->start(); + m_running = true; +} + void BlackBerryApplicationRunner::startRunningStateTimer() { if (m_running) diff --git a/src/plugins/qnx/blackberryapplicationrunner.h b/src/plugins/qnx/blackberryapplicationrunner.h index 9f257066d4f..3ba06a4785c 100644 --- a/src/plugins/qnx/blackberryapplicationrunner.h +++ b/src/plugins/qnx/blackberryapplicationrunner.h @@ -82,6 +82,7 @@ private slots: void readStandardOutput(); void readStandardError(); + void disconnectFromDeviceSignals(Core::Id deviceId); void startRunningStateTimer(); void determineRunningState(); void readRunningStateStandardOutput(); @@ -89,8 +90,11 @@ private slots: void setPid(qint64 pid); void setApplicationId(const QString &applicationId); + void launchApplication(); void startLogProcessRunner(); + void displayConnectionOutput(Core::Id deviceId, const QString &output); + private: void reset(); diff --git a/src/plugins/qnx/blackberrydebugsupport.cpp b/src/plugins/qnx/blackberrydebugsupport.cpp index e0ae83c181e..cbd48c5b4f2 100644 --- a/src/plugins/qnx/blackberrydebugsupport.cpp +++ b/src/plugins/qnx/blackberrydebugsupport.cpp @@ -51,8 +51,8 @@ BlackBerryDebugSupport::BlackBerryDebugSupport(BlackBerryRunConfiguration *runCo this, SLOT(handleDebuggerStateChanged(Debugger::DebuggerState))); connect(m_runner, SIGNAL(started()), this, SLOT(handleStarted())); - connect(m_runner, SIGNAL(started()), m_runner, SLOT(checkSlog2Info())); connect(m_runner, SIGNAL(startFailed(QString)), this, SLOT(handleStartFailed(QString))); + connect(m_runner, SIGNAL(started()), m_runner, SLOT(checkSlog2Info())); connect(m_runner, SIGNAL(output(QString,Utils::OutputFormat)), this, SLOT(handleApplicationOutput(QString,Utils::OutputFormat))); diff --git a/src/plugins/qnx/blackberrydeviceconnectionmanager.cpp b/src/plugins/qnx/blackberrydeviceconnectionmanager.cpp index fa549d70db1..ad0c308295b 100644 --- a/src/plugins/qnx/blackberrydeviceconnectionmanager.cpp +++ b/src/plugins/qnx/blackberrydeviceconnectionmanager.cpp @@ -278,9 +278,11 @@ void BlackBerryDeviceConnectionManager::handleDeviceDisconnected() QTC_ASSERT(connection, return); QList disconnectedDevices = m_connections.values(connection); - foreach (Core::Id id, disconnectedDevices) + foreach (Core::Id id, disconnectedDevices) { ProjectExplorer::DeviceManager::instance()->setDeviceState(id, ProjectExplorer::IDevice::DeviceDisconnected); + emit deviceDisconnected(id); + } } void BlackBerryDeviceConnectionManager::handleDeviceAboutToConnect() diff --git a/src/plugins/qnx/blackberrydeviceconnectionmanager.h b/src/plugins/qnx/blackberrydeviceconnectionmanager.h index a211f505e98..b9a5e10909d 100644 --- a/src/plugins/qnx/blackberrydeviceconnectionmanager.h +++ b/src/plugins/qnx/blackberrydeviceconnectionmanager.h @@ -69,6 +69,7 @@ signals: void connectionOutput(Core::Id deviceId, const QString &output); void deviceAboutToConnect(Core::Id deviceId); void deviceConnected(); + void deviceDisconnected(Core::Id deviceId); public slots: void connectDevice(Core::Id deviceId); diff --git a/src/plugins/qnx/blackberryruncontrol.cpp b/src/plugins/qnx/blackberryruncontrol.cpp index f372452bc70..564329fa573 100644 --- a/src/plugins/qnx/blackberryruncontrol.cpp +++ b/src/plugins/qnx/blackberryruncontrol.cpp @@ -34,8 +34,6 @@ #include "blackberryrunconfiguration.h" #include "blackberrydeviceconnectionmanager.h" -#include - #include #include @@ -45,7 +43,6 @@ using namespace Qnx::Internal; BlackBerryRunControl::BlackBerryRunControl(BlackBerryRunConfiguration *runConfiguration) : ProjectExplorer::RunControl(runConfiguration, ProjectExplorer::NormalRunMode) { - m_device = BlackBerryDeviceConfiguration::device(runConfiguration->target()->kit()); m_runner = new BlackBerryApplicationRunner(false, runConfiguration, this); connect(m_runner, SIGNAL(started()), this, SIGNAL(started())); @@ -57,7 +54,7 @@ BlackBerryRunControl::BlackBerryRunControl(BlackBerryRunConfiguration *runConfig void BlackBerryRunControl::start() { - checkDeviceConnection(); + m_runner->start(); } ProjectExplorer::RunControl::StopResult BlackBerryRunControl::stop() @@ -79,32 +76,3 @@ void BlackBerryRunControl::handleStartFailed(const QString &message) { appendMessage(message, Utils::StdErrFormat); } - -void BlackBerryRunControl::handleDeviceConnected() -{ - m_runner->start(); -} - -void BlackBerryRunControl::displayConnectionOutput(Core::Id deviceId, const QString &output) -{ - if (deviceId != m_device->id()) - return; - - if (output.contains(QLatin1String("Info:"))) - appendMessage(output, Utils::StdOutFormat); - else if (output.contains(QLatin1String("Error:"))) - appendMessage(output, Utils::StdErrFormat); -} - -void BlackBerryRunControl::checkDeviceConnection() -{ - if (!BlackBerryDeviceConnectionManager::instance()->isConnected(m_device->id())) { - connect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(deviceConnected()), - this, SLOT(handleDeviceConnected())); - connect(BlackBerryDeviceConnectionManager::instance(), SIGNAL(connectionOutput(Core::Id,QString)), - this, SLOT(displayConnectionOutput(Core::Id,QString))); - BlackBerryDeviceConnectionManager::instance()->connectDevice(m_device->id()); - } else { - m_runner->start(); - } -} diff --git a/src/plugins/qnx/blackberryruncontrol.h b/src/plugins/qnx/blackberryruncontrol.h index 787add054b1..ab061407d00 100644 --- a/src/plugins/qnx/blackberryruncontrol.h +++ b/src/plugins/qnx/blackberryruncontrol.h @@ -32,8 +32,6 @@ #ifndef QNX_INTERNAL_BLACKBERRYRUNCONTROL_H #define QNX_INTERNAL_BLACKBERRYRUNCONTROL_H -#include "blackberrydeviceconfiguration.h" - #include namespace QmakeProjectManager { @@ -60,13 +58,9 @@ public: private slots: void handleStartFailed(const QString &message); - void handleDeviceConnected(); - void displayConnectionOutput(Core::Id deviceId, const QString &output); - void checkDeviceConnection(); private: BlackBerryApplicationRunner *m_runner; - BlackBerryDeviceConfiguration::ConstPtr m_device; }; } // namespace Internal From ac6aa54f6dad9c2f7c9886ebd46f6a1c3750032a Mon Sep 17 00:00:00 2001 From: El Mehdi Fekari Date: Thu, 24 Oct 2013 16:00:47 +0200 Subject: [PATCH 37/84] Qnx: Remove dead code Change-Id: Iceaa438d65c671a2d1eff5b400fe15d14280c1e3 Reviewed-by: Nicolas Arnaud-Cormos From 9b88e0db32c1e1861d11de9fe186ad360d3716cb Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 16 Oct 2013 17:18:07 +0200 Subject: [PATCH 38/84] Update file/directory names for Qt Quick 1 template Make the names in line with the Qt Quick 2 ones. Also, changing the directory/filename makes sure the update mechanism of Qt Creator doesn't update apps generated by the 2.x wizard any more, which might break stuff. Change-Id: I4621d5f35eae2102aeba7e77c5cd903511be249f Reviewed-by: Jarek Kobus --- .../{qtquickapp => qtquick1app}/app.pro | 4 +- .../{qtquickapp => qtquick1app}/main.cpp | 6 +-- .../qml/app/meego10/MainPage.qml | 0 .../qml/app/meego10/main.qml | 0 .../qml/app/qtquick10/main.qml | 0 .../qtquick1applicationviewer.cpp} | 42 ++++++++--------- .../qtquick1applicationviewer.h | 43 ++++++++++++++++++ .../qtquick1applicationviewer.pri | 11 +++++ .../qmlapplicationviewer.h | 45 ------------------- .../qmlapplicationviewer.pri | 11 ----- .../qt4projectmanager/wizards/qtquickapp.cpp | 32 +++++++++---- 11 files changed, 105 insertions(+), 89 deletions(-) rename share/qtcreator/templates/{qtquickapp => qtquick1app}/app.pro (88%) rename share/qtcreator/templates/{qtquickapp => qtquick1app}/main.cpp (63%) rename share/qtcreator/templates/{qtquickapp => qtquick1app}/qml/app/meego10/MainPage.qml (100%) rename share/qtcreator/templates/{qtquickapp => qtquick1app}/qml/app/meego10/main.qml (100%) rename share/qtcreator/templates/{qtquickapp => qtquick1app}/qml/app/qtquick10/main.qml (100%) rename share/qtcreator/templates/{qtquickapp/qmlapplicationviewer/qmlapplicationviewer.cpp => qtquick1app/qtquick1applicationviewer/qtquick1applicationviewer.cpp} (59%) create mode 100644 share/qtcreator/templates/qtquick1app/qtquick1applicationviewer/qtquick1applicationviewer.h create mode 100644 share/qtcreator/templates/qtquick1app/qtquick1applicationviewer/qtquick1applicationviewer.pri delete mode 100644 share/qtcreator/templates/qtquickapp/qmlapplicationviewer/qmlapplicationviewer.h delete mode 100644 share/qtcreator/templates/qtquickapp/qmlapplicationviewer/qmlapplicationviewer.pri diff --git a/share/qtcreator/templates/qtquickapp/app.pro b/share/qtcreator/templates/qtquick1app/app.pro similarity index 88% rename from share/qtcreator/templates/qtquickapp/app.pro rename to share/qtcreator/templates/qtquick1app/app.pro index e96d5e0c4be..19aef272818 100644 --- a/share/qtcreator/templates/qtquickapp/app.pro +++ b/share/qtcreator/templates/qtquick1app/app.pro @@ -25,7 +25,7 @@ SOURCES += main.cpp # target.path = # Please do not modify the following two lines. Required for deployment. -include(qmlapplicationviewer/qmlapplicationviewer.pri) -# REMOVE_NEXT_LINE (wizard will remove the include and append deployment.pri to qmlapplicationviewer.pri, instead) # +include(qtquick1applicationviewer/qtquick1applicationviewer.pri) +# REMOVE_NEXT_LINE (wizard will remove the include and append deployment.pri to qtquick1applicationviewer.pri, instead) # include(../shared/deployment.pri) qtcAddDeployment() diff --git a/share/qtcreator/templates/qtquickapp/main.cpp b/share/qtcreator/templates/qtquick1app/main.cpp similarity index 63% rename from share/qtcreator/templates/qtquickapp/main.cpp rename to share/qtcreator/templates/qtquick1app/main.cpp index 3cd4a57edc3..70b2e9ea7eb 100644 --- a/share/qtcreator/templates/qtquickapp/main.cpp +++ b/share/qtcreator/templates/qtquick1app/main.cpp @@ -1,13 +1,13 @@ -#include "qmlapplicationviewer.h" +#include "qtquick1applicationviewer.h" #include int main(int argc, char *argv[]) { QApplication app(argc, argv); - QmlApplicationViewer viewer; + QtQuick1ApplicationViewer viewer; viewer.addImportPath(QLatin1String("modules")); // ADDIMPORTPATH - viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto); // ORIENTATION + viewer.setOrientation(QtQuick1ApplicationViewer::ScreenOrientationAuto); // ORIENTATION viewer.setMainQmlFile(QLatin1String("qml/app/qtquick10/main.qml")); // MAINQML viewer.showExpanded(); diff --git a/share/qtcreator/templates/qtquickapp/qml/app/meego10/MainPage.qml b/share/qtcreator/templates/qtquick1app/qml/app/meego10/MainPage.qml similarity index 100% rename from share/qtcreator/templates/qtquickapp/qml/app/meego10/MainPage.qml rename to share/qtcreator/templates/qtquick1app/qml/app/meego10/MainPage.qml diff --git a/share/qtcreator/templates/qtquickapp/qml/app/meego10/main.qml b/share/qtcreator/templates/qtquick1app/qml/app/meego10/main.qml similarity index 100% rename from share/qtcreator/templates/qtquickapp/qml/app/meego10/main.qml rename to share/qtcreator/templates/qtquick1app/qml/app/meego10/main.qml diff --git a/share/qtcreator/templates/qtquickapp/qml/app/qtquick10/main.qml b/share/qtcreator/templates/qtquick1app/qml/app/qtquick10/main.qml similarity index 100% rename from share/qtcreator/templates/qtquickapp/qml/app/qtquick10/main.qml rename to share/qtcreator/templates/qtquick1app/qml/app/qtquick10/main.qml diff --git a/share/qtcreator/templates/qtquickapp/qmlapplicationviewer/qmlapplicationviewer.cpp b/share/qtcreator/templates/qtquick1app/qtquick1applicationviewer/qtquick1applicationviewer.cpp similarity index 59% rename from share/qtcreator/templates/qtquickapp/qmlapplicationviewer/qmlapplicationviewer.cpp rename to share/qtcreator/templates/qtquick1app/qtquick1applicationviewer/qtquick1applicationviewer.cpp index b29054eb0d1..d487e109f9c 100644 --- a/share/qtcreator/templates/qtquickapp/qmlapplicationviewer/qmlapplicationviewer.cpp +++ b/share/qtcreator/templates/qtquick1app/qtquick1applicationviewer/qtquick1applicationviewer.cpp @@ -1,13 +1,13 @@ /* - This file was generated by the Qt Quick Application wizard of Qt Creator. - QmlApplicationViewer is a convenience class containing mobile device specific - code such as screen orientation handling. Also QML paths and debugging are + This file was generated by the Qt Quick 1 Application wizard of Qt Creator. + QtQuick1ApplicationViewer is a convenience class containing mobile device + specific code such as screen orientation handling. Also QML paths are handled here. It is recommended not to modify this file, since newer versions of Qt Creator may offer an updated version of it. */ -#include "qmlapplicationviewer.h" +#include "qtquick1applicationviewer.h" #include #include @@ -18,14 +18,14 @@ #include // MEEGO_EDITION_HARMATTAN -class QmlApplicationViewerPrivate +class QtQuick1ApplicationViewerPrivate { QString mainQmlFile; - friend class QmlApplicationViewer; + friend class QtQuick1ApplicationViewer; static QString adjustPath(const QString &path); }; -QString QmlApplicationViewerPrivate::adjustPath(const QString &path) +QString QtQuick1ApplicationViewerPrivate::adjustPath(const QString &path) { #ifdef Q_OS_MAC if (!QDir::isAbsolutePath(path)) @@ -36,38 +36,40 @@ QString QmlApplicationViewerPrivate::adjustPath(const QString &path) return QString::fromLatin1("app/native/%1").arg(path); #elif !defined(Q_OS_ANDROID) QString pathInInstallDir = - QString::fromLatin1("%1/../%2").arg(QCoreApplication::applicationDirPath(), path); + QString::fromLatin1("%1/../%2").arg( + QCoreApplication::applicationDirPath(), path); if (QFileInfo(pathInInstallDir).exists()) return pathInInstallDir; pathInInstallDir = - QString::fromLatin1("%1/%2").arg(QCoreApplication::applicationDirPath(), path); + QString::fromLatin1("%1/%2").arg( + QCoreApplication::applicationDirPath(), path); if (QFileInfo(pathInInstallDir).exists()) return pathInInstallDir; #endif return path; } -QmlApplicationViewer::QmlApplicationViewer(QWidget *parent) +QtQuick1ApplicationViewer::QtQuick1ApplicationViewer(QWidget *parent) : QDeclarativeView(parent) - , d(new QmlApplicationViewerPrivate()) + , d(new QtQuick1ApplicationViewerPrivate()) { connect(engine(), SIGNAL(quit()), SLOT(close())); setResizeMode(QDeclarativeView::SizeRootObjectToView); } -QmlApplicationViewer::~QmlApplicationViewer() +QtQuick1ApplicationViewer::~QtQuick1ApplicationViewer() { delete d; } -QmlApplicationViewer *QmlApplicationViewer::create() +QtQuick1ApplicationViewer *QtQuick1ApplicationViewer::create() { - return new QmlApplicationViewer(); + return new QtQuick1ApplicationViewer(); } -void QmlApplicationViewer::setMainQmlFile(const QString &file) +void QtQuick1ApplicationViewer::setMainQmlFile(const QString &file) { - d->mainQmlFile = QmlApplicationViewerPrivate::adjustPath(file); + d->mainQmlFile = QtQuick1ApplicationViewerPrivate::adjustPath(file); #ifdef Q_OS_ANDROID setSource(QUrl(QLatin1String("assets:/")+d->mainQmlFile)); #else @@ -75,12 +77,12 @@ void QmlApplicationViewer::setMainQmlFile(const QString &file) #endif } -void QmlApplicationViewer::addImportPath(const QString &path) +void QtQuick1ApplicationViewer::addImportPath(const QString &path) { - engine()->addImportPath(QmlApplicationViewerPrivate::adjustPath(path)); + engine()->addImportPath(QtQuick1ApplicationViewerPrivate::adjustPath(path)); } -void QmlApplicationViewer::setOrientation(ScreenOrientation orientation) +void QtQuick1ApplicationViewer::setOrientation(ScreenOrientation orientation) { #if QT_VERSION < 0x050000 Qt::WidgetAttribute attribute; @@ -102,7 +104,7 @@ void QmlApplicationViewer::setOrientation(ScreenOrientation orientation) #endif // QT_VERSION < 0x050000 } -void QmlApplicationViewer::showExpanded() +void QtQuick1ApplicationViewer::showExpanded() { #if defined(Q_WS_SIMULATOR) || defined(Q_OS_QNX) showFullScreen(); diff --git a/share/qtcreator/templates/qtquick1app/qtquick1applicationviewer/qtquick1applicationviewer.h b/share/qtcreator/templates/qtquick1app/qtquick1applicationviewer/qtquick1applicationviewer.h new file mode 100644 index 00000000000..b9dc3a9fee4 --- /dev/null +++ b/share/qtcreator/templates/qtquick1app/qtquick1applicationviewer/qtquick1applicationviewer.h @@ -0,0 +1,43 @@ +/* + This file was generated by the Qt Quick 1 Application wizard of Qt Creator. + QtQuick1ApplicationViewer is a convenience class containing mobile device + specific code such as screen orientation handling. Also QML paths are + handled here. + It is recommended not to modify this file, since newer versions of Qt Creator + may offer an updated version of it. +*/ + +#ifndef QTQUICK1APPLICATIONVIEWER_H +#define QTQUICK1APPLICATIONVIEWER_H + +#include + +class QtQuick1ApplicationViewer : public QDeclarativeView +{ + Q_OBJECT + +public: + enum ScreenOrientation { + ScreenOrientationLockPortrait, + ScreenOrientationLockLandscape, + ScreenOrientationAuto + }; + + explicit QtQuick1ApplicationViewer(QWidget *parent = 0); + virtual ~QtQuick1ApplicationViewer(); + + static QtQuick1ApplicationViewer *create(); + + void setMainQmlFile(const QString &file); + void addImportPath(const QString &path); + + // Note that this will only have an effect on Fremantle. + void setOrientation(ScreenOrientation orientation); + + void showExpanded(); + +private: + class QtQuick1ApplicationViewerPrivate *d; +}; + +#endif // QTQUICK1APPLICATIONVIEWER_H diff --git a/share/qtcreator/templates/qtquick1app/qtquick1applicationviewer/qtquick1applicationviewer.pri b/share/qtcreator/templates/qtquick1app/qtquick1applicationviewer/qtquick1applicationviewer.pri new file mode 100644 index 00000000000..030edc1d018 --- /dev/null +++ b/share/qtcreator/templates/qtquick1app/qtquick1applicationviewer/qtquick1applicationviewer.pri @@ -0,0 +1,11 @@ +# This file was generated by the Qt Quick 1 Application wizard of Qt Creator. +# The code below adds the QtQuick1ApplicationViewer to the project. +# +# It is recommended not to modify this file, since newer versions of Qt Creator +# may offer an updated version of it. + +QT += declarative + +SOURCES += $$PWD/qtquick1applicationviewer.cpp +HEADERS += $$PWD/qtquick1applicationviewer.h +INCLUDEPATH += $$PWD diff --git a/share/qtcreator/templates/qtquickapp/qmlapplicationviewer/qmlapplicationviewer.h b/share/qtcreator/templates/qtquickapp/qmlapplicationviewer/qmlapplicationviewer.h deleted file mode 100644 index 183ff8bea63..00000000000 --- a/share/qtcreator/templates/qtquickapp/qmlapplicationviewer/qmlapplicationviewer.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - This file was generated by the Qt Quick Application wizard of Qt Creator. - QmlApplicationViewer is a convenience class containing mobile device specific - code such as screen orientation handling. Also QML paths and debugging are - handled here. - It is recommended not to modify this file, since newer versions of Qt Creator - may offer an updated version of it. -*/ - -#ifndef QMLAPPLICATIONVIEWER_H -#define QMLAPPLICATIONVIEWER_H - -#include - -class QmlApplicationViewer : public QDeclarativeView -{ - Q_OBJECT - -public: - enum ScreenOrientation { - ScreenOrientationLockPortrait, - ScreenOrientationLockLandscape, - ScreenOrientationAuto - }; - - explicit QmlApplicationViewer(QWidget *parent = 0); - virtual ~QmlApplicationViewer(); - - static QmlApplicationViewer *create(); - - void setMainQmlFile(const QString &file); - void addImportPath(const QString &path); - - // Note that this will only have an effect on Fremantle. - void setOrientation(ScreenOrientation orientation); - - void showExpanded(); - -private: - class QmlApplicationViewerPrivate *d; -}; - -QApplication *createApplication(int &argc, char **argv); - -#endif // QMLAPPLICATIONVIEWER_H diff --git a/share/qtcreator/templates/qtquickapp/qmlapplicationviewer/qmlapplicationviewer.pri b/share/qtcreator/templates/qtquickapp/qmlapplicationviewer/qmlapplicationviewer.pri deleted file mode 100644 index bac43a6d800..00000000000 --- a/share/qtcreator/templates/qtquickapp/qmlapplicationviewer/qmlapplicationviewer.pri +++ /dev/null @@ -1,11 +0,0 @@ -# This file was generated by the Qt Quick Application wizard of Qt Creator. -# The code below adds the QmlApplicationViewer to the project and handles the -# activation of QML debugging. -# It is recommended not to modify this file, since newer versions of Qt Creator -# may offer an updated version of it. - -QT += declarative - -SOURCES += $$PWD/qmlapplicationviewer.cpp -HEADERS += $$PWD/qmlapplicationviewer.h -INCLUDEPATH += $$PWD diff --git a/src/plugins/qt4projectmanager/wizards/qtquickapp.cpp b/src/plugins/qt4projectmanager/wizards/qtquickapp.cpp index b252083f895..5965088f250 100644 --- a/src/plugins/qt4projectmanager/wizards/qtquickapp.cpp +++ b/src/plugins/qt4projectmanager/wizards/qtquickapp.cpp @@ -29,6 +29,9 @@ #include "qtquickapp.h" +#include + +#include #include #include #include @@ -113,15 +116,25 @@ QString QtQuickApp::originsRoot() const switch (m_componentSet) { case QtQuickControls10: return templatesRoot() + QLatin1String("qtquick2controls/"); case QtQuick20Components: return templatesRoot() + QLatin1String("qtquick2app/"); - default: break; + case QtQuick10Components: return templatesRoot() + QLatin1String("qtquick1app/"); } - return templatesRoot() + QLatin1String("qtquickapp/"); + qWarning() << "QtQuickApp::originsRoot() - unhandled component set" + << m_componentSet; + return QString(); } QString QtQuickApp::mainWindowClassName() const { - return QLatin1String("QmlApplicationViewer"); + switch (m_componentSet) { + case QtQuickControls10: return QLatin1String("QtQuick2ControlsApplicationViewer"); + case QtQuick20Components: return QLatin1String("QtQuick2ApplicationViewer"); + case QtQuick10Components: return QLatin1String("QtQuick1ApplicationViewer"); + } + + qWarning() << "QtQuickApp::mainWindowClassName() - unhandled component set" + << m_componentSet; + return QString(); } bool QtQuickApp::adaptCurrentMainCppTemplateLine(QString &line) const @@ -174,12 +187,15 @@ bool QtQuickApp::useExistingMainQml() const QString QtQuickApp::appViewerBaseName() const { - if (m_componentSet == QtQuick20Components) { - return QLatin1String("qtquick2applicationviewer"); - } else if (m_componentSet == QtQuickControls10) { - return QLatin1String("qtquick2controlsapplicationviewer"); + switch (m_componentSet) { + case QtQuickControls10: return QLatin1String("qtquick2controlsapplicationviewer"); + case QtQuick20Components: return QLatin1String("qtquick2applicationviewer"); + case QtQuick10Components: return QLatin1String("qtquick1applicationviewer"); } - return QLatin1String("qmlapplicationviewer"); + + qWarning() << "QtQuickApp::appViewerBaseName() - unhandled component set" + << m_componentSet; + return QString(); } QString QtQuickApp::fileName(QtQuickApp::ExtendedFileType type) const From 9a57a41a7ad8d9f23ed37aca871edabd3abb729f Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 24 Oct 2013 15:09:36 +0200 Subject: [PATCH 39/84] Fix QDateTime dumper with various Qt versions and bitness Change-Id: Iba15c1b27dc83e8949fef5fd25de61cc2b20be30 Reviewed-by: hjk --- share/qtcreator/debugger/qttypes.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index fb6e6b18f62..f961fe4af57 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -235,8 +235,8 @@ def qdump__QDateTime(d, value): # This relies on the Qt4/Qt5 internal structure layout: # {sharedref(4), ... base = d.dereferenceValue(value) - dateBase = base + d.ptrSize() # Only QAtomicInt, but will be padded. if qtVersion >= 0x050200: + dateBase = base + d.ptrSize() # Only QAtomicInt, but will be padded. ms = d.extractInt64(dateBase) offset = d.extractInt(dateBase + 12) isValid = ms > 0 @@ -248,11 +248,14 @@ def qdump__QDateTime(d, value): # QDateTimePrivate: # - QAtomicInt ref; (padded on 64 bit) # - [QDate date;] - # - - uint jd in Qt 4, qint64 in Qt 5.0 and Qt 5.2; padded on 64 bit + # - - uint jd in Qt 4, qint64 in Qt 5.0 and Qt 5.1; padded on 64 bit # - [QTime time;] # - - uint mds; # - Spec spec; - dateSize = 4 if qtVersion < 0x050000 and d.is32bit() else 8 + dateSize = 8 if qtVersion >= 0x050000 else 4 # Qt5: qint64, Qt4 uint + # 4 byte padding after 4 byte QAtomicInt if we are on 64 bit and QDate is 64 bit + refPlusPadding = 8 if qtVersion >= 0x050000 and not d.is32bit() else 4 + dateBase = base + refPlusPadding timeBase = dateBase + dateSize mds = d.extractInt(timeBase) isValid = mds > 0 From 6c673a042f5fc9ec40dfa4430acc994924aa4ee8 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 24 Oct 2013 17:10:58 +0200 Subject: [PATCH 40/84] Debugger: Fix std::deque dumper with LLDB Change-Id: Idd3547396384fe5b421c4b601b52476a23cdfa89 Reviewed-by: hjk --- share/qtcreator/debugger/stdtypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py index 017a02672ea..428373ad320 100644 --- a/share/qtcreator/debugger/stdtypes.py +++ b/share/qtcreator/debugger/stdtypes.py @@ -116,7 +116,7 @@ def qdump__std__deque(d, value): for i in d.childRange(): d.putSubItem(i, pcur.dereference()) pcur += 1 - if pcur == plast: + if toInteger(pcur) == toInteger(plast): newnode = pnode + 1 pnode = newnode pfirst = newnode.dereference() From ab92c14bbedbc1acfc63d189989b1ee427411b6a Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 24 Oct 2013 17:38:57 +0200 Subject: [PATCH 41/84] Debugger: Fix std::complex dumper for LLDB Change-Id: I5ffb0f60039bb05f8467e925e71cf710a0712791 Reviewed-by: hjk --- share/qtcreator/debugger/gdbbridge.py | 15 +++++++++++++-- share/qtcreator/debugger/stdtypes.py | 5 ++--- tests/auto/debugger/tst_dumpers.cpp | 6 ++++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index 8955c09612a..2d0df4275a4 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -1215,7 +1215,14 @@ class Dumper(DumperBase): return toInteger(value.address) def createPointerValue(self, address, pointeeType): - return gdb.Value(address).cast(pointeeType.pointer()) + # This might not always work: + # a Python 3 based GDB due to the bug addressed in + # https://sourceware.org/ml/gdb-patches/2013-09/msg00571.html + try: + return gdb.Value(address).cast(pointeeType.pointer()) + except: + # Try _some_ fallback (good enough for the std::complex dumper) + return gdb.parse_and_eval("(%s*)%s" % (pointeeType, address)) def intSize(self): return 4 @@ -1227,7 +1234,11 @@ class Dumper(DumperBase): return self.lookupType('void*').sizeof == 4 def createValue(self, address, referencedType): - return gdb.Value(address).cast(referencedType.pointer()).dereference() + try: + return gdb.Value(address).cast(referencedType.pointer()).dereference() + except: + # Try _some_ fallback (good enough for the std::complex dumper) + return gdb.parse_and_eval("{%s}%s" % (referencedType, address)) def readRawMemory(self, addr, size): mem = gdb.selected_inferior().read_memory(addr, size) diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py index 428373ad320..4ca65badb0f 100644 --- a/share/qtcreator/debugger/stdtypes.py +++ b/share/qtcreator/debugger/stdtypes.py @@ -79,9 +79,8 @@ def qdump__std____1__array(d, value): def qdump__std__complex(d, value): innerType = d.templateArgument(value.type, 0) - base = value.address.cast(innerType.pointer()) - real = base.dereference() - imag = (base + 1).dereference() + real = value.cast(innerType) + imag = d.createValue(d.addressOf(value) + innerType.sizeof, innerType) d.putValue("(%f, %f)" % (real, imag)); d.putNumChild(2) if d.isExpanded(): diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index fba59c77c93..7b08bb3514c 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -2469,8 +2469,10 @@ void tst_Dumpers::dumper_data() QTest::newRow("StdComplex") << Data("#include \n", - "std::complex c(1, 2);\n") - % Check("c", "(1.000000, 2.000000)", "std::complex"); + "std::complex c(1, 2);\n" + "unused(&c);\n") + % Check("c", "(1.000000, 2.000000)", "std::complex") + % CheckType("c.real", "double"); QTest::newRow("CComplexGdb") << Data("#include \n", From 7f5366796c1881cb093c738aac70072bef8ae6d4 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 24 Oct 2013 18:46:07 +0200 Subject: [PATCH 42/84] Debugger: Fix display of vector extensions with LLDB Like char __attribute__ ((vector_size (8))) ... Change-Id: Ie93547396384fe5b421c4b601b52476a23cdfa89 Reviewed-by: hjk --- share/qtcreator/debugger/lldbbridge.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index e1416d18fa1..94d485609ee 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -962,6 +962,11 @@ class Dumper(DumperBase): qdump____c_style_array__(self, value) return + # Vectors like char __attribute__ ((vector_size (8))) + if typeClass == lldb.eTypeClassVector: + qdump____c_style_array__(self, value) + return + # References if value.GetType().IsReferenceType(): origType = value.GetTypeName(); From 357ea64797572c95ffc95665ae1020bb4ec02b36 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 24 Oct 2013 16:48:55 +0200 Subject: [PATCH 43/84] Message fixes in QML-Designer. Change-Id: I309b3b74b0760b8b1a89c0f85ffb52cc875e5d85 Reviewed-by: Friedemann Kleint --- .../propertyEditorQmlSources/QtQuick/ItemPane.qml | 4 ++-- .../components/componentcore/tabviewdesigneraction.cpp | 2 +- .../componentsplugin/Controls/ButtonSpecifics.qml | 2 +- .../componentsplugin/Controls/CheckBoxSpecifics.qml | 6 +++--- .../componentsplugin/Controls/TextAreaSpecifics.qml | 4 ++-- .../componentsplugin/Controls/TextFieldSpecifics.qml | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml index a37302673ac..c6193a4deda 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml @@ -96,12 +96,12 @@ Rectangle { anchors.left: parent.left anchors.right: parent.right - caption: qsTr("Visibilty") + caption: qsTr("Visibility") SectionLayout { rows: 2 Label { - text: qsTr("Visibilty") + text: qsTr("Visibility") } SecondColumnLayout { diff --git a/src/plugins/qmldesigner/components/componentcore/tabviewdesigneraction.cpp b/src/plugins/qmldesigner/components/componentcore/tabviewdesigneraction.cpp index 9a04a2cec3e..82411e6b989 100644 --- a/src/plugins/qmldesigner/components/componentcore/tabviewdesigneraction.cpp +++ b/src/plugins/qmldesigner/components/componentcore/tabviewdesigneraction.cpp @@ -151,7 +151,7 @@ void TabViewDesignerAction::addNewTab() QString newFilePath = directoryPath +QLatin1String("/") + tabName + QLatin1String(".qml"); if (QFileInfo(newFilePath).exists()) { - QMessageBox::warning(Core::ICore::mainWindow(), tr("Name Error"), tr("Component already exists.")); + QMessageBox::warning(Core::ICore::mainWindow(), tr("Naming Error"), tr("Component already exists.")); } else { bool fileCreated = createFile(newFilePath); diff --git a/src/plugins/qmldesigner/componentsplugin/Controls/ButtonSpecifics.qml b/src/plugins/qmldesigner/componentsplugin/Controls/ButtonSpecifics.qml index 4633c06fc34..f02154a92a9 100644 --- a/src/plugins/qmldesigner/componentsplugin/Controls/ButtonSpecifics.qml +++ b/src/plugins/qmldesigner/componentsplugin/Controls/ButtonSpecifics.qml @@ -135,7 +135,7 @@ Column { Label { text: qsTr("Focus on press") - toolTip: "Determines whether the check box gets focus if pressed." + toolTip: "Determines whether the button gets focus if pressed." } SecondColumnLayout { diff --git a/src/plugins/qmldesigner/componentsplugin/Controls/CheckBoxSpecifics.qml b/src/plugins/qmldesigner/componentsplugin/Controls/CheckBoxSpecifics.qml index 7ec2cfd91df..6384c65e012 100644 --- a/src/plugins/qmldesigner/componentsplugin/Controls/CheckBoxSpecifics.qml +++ b/src/plugins/qmldesigner/componentsplugin/Controls/CheckBoxSpecifics.qml @@ -44,7 +44,7 @@ Column { Label { text: qsTr("Text") - toolTip: qsTr("The text shown on the check button") + toolTip: qsTr("The text shown on the check box") } SecondColumnLayout { @@ -59,7 +59,7 @@ Column { Label { text: qsTr("Checked") - toolTip: qsTr("The state of the check button") + toolTip: qsTr("The state of the check box") } SecondColumnLayout { @@ -75,7 +75,7 @@ Column { Label { text: qsTr("Focus on press") - toolTip: "Determines whether the check box gets focus if pressed." + toolTip: qsTr("Determines whether the check box gets focus if pressed.") } SecondColumnLayout { diff --git a/src/plugins/qmldesigner/componentsplugin/Controls/TextAreaSpecifics.qml b/src/plugins/qmldesigner/componentsplugin/Controls/TextAreaSpecifics.qml index 9bd9a5c56cf..7c031333ee6 100644 --- a/src/plugins/qmldesigner/componentsplugin/Controls/TextAreaSpecifics.qml +++ b/src/plugins/qmldesigner/componentsplugin/Controls/TextAreaSpecifics.qml @@ -58,7 +58,7 @@ Column { Label { text: qsTr("Text") - toolTip: qsTr("The text shown on the button") + toolTip: qsTr("The text shown on the text area") } SecondColumnLayout { @@ -73,7 +73,7 @@ Column { Label { text: qsTr("Read only") - toolTip: qsTr("Determines whether the text field is read only.") + toolTip: qsTr("Determines whether the text area is read only.") } SecondColumnLayout { diff --git a/src/plugins/qmldesigner/componentsplugin/Controls/TextFieldSpecifics.qml b/src/plugins/qmldesigner/componentsplugin/Controls/TextFieldSpecifics.qml index 7bad9156255..4967a340210 100644 --- a/src/plugins/qmldesigner/componentsplugin/Controls/TextFieldSpecifics.qml +++ b/src/plugins/qmldesigner/componentsplugin/Controls/TextFieldSpecifics.qml @@ -44,7 +44,7 @@ Column { Label { text: qsTr("Text") - toolTip: qsTr("The text shown on the button") + toolTip: qsTr("The text shown on the text field") } SecondColumnLayout { From 63f2e9177c29e0c85a6c9e8d7fcb8bce30933c31 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Thu, 24 Oct 2013 18:56:29 +0200 Subject: [PATCH 44/84] Squish: Updated Debugger settings Change-Id: Ifb5a20fdb9596e4f5f69ec0b7bcc8367215d30b5 Reviewed-by: Christian Stenger --- .../unix/QtProject/qtcreator/debuggers.xml | 26 ++++++++++ .../unix/QtProject/qtcreator/profiles.xml | 29 +++++------ .../windows/QtProject/qtcreator/debuggers.xml | 50 +++++++++++++++++++ .../windows/QtProject/qtcreator/profiles.xml | 32 ++++++------ 4 files changed, 106 insertions(+), 31 deletions(-) create mode 100644 tests/system/settings/unix/QtProject/qtcreator/debuggers.xml create mode 100644 tests/system/settings/windows/QtProject/qtcreator/debuggers.xml diff --git a/tests/system/settings/unix/QtProject/qtcreator/debuggers.xml b/tests/system/settings/unix/QtProject/qtcreator/debuggers.xml new file mode 100644 index 00000000000..0f31f081d68 --- /dev/null +++ b/tests/system/settings/unix/QtProject/qtcreator/debuggers.xml @@ -0,0 +1,26 @@ + + + + + + DebuggerItem.0 + + + unknown-linux-generic-elf-unknown + + true + /usr/bin/gdb + System GDB at /usr/bin/gdb + 1 + {70e26273-2c0b-4534-bbc0-eb6ca670821a} + + + + DebuggerItem.Count + 1 + + + Version + 1 + + diff --git a/tests/system/settings/unix/QtProject/qtcreator/profiles.xml b/tests/system/settings/unix/QtProject/qtcreator/profiles.xml index 7eac69d2dfe..9c9cadcee98 100644 --- a/tests/system/settings/unix/QtProject/qtcreator/profiles.xml +++ b/tests/system/settings/unix/QtProject/qtcreator/profiles.xml @@ -1,6 +1,6 @@ - + Profile.0 @@ -8,7 +8,7 @@ false - /usr/bin/gdb + {70e26273-2c0b-4534-bbc0-eb6ca670821a} Desktop Device Desktop @@ -18,6 +18,7 @@ :///DESKTOP/// {4d9ea3ed-a7f0-4b0e-885f-da3b82931988} + Desktop 474 GCC false @@ -28,7 +29,7 @@ false - /usr/bin/gdb + {70e26273-2c0b-4534-bbc0-eb6ca670821a} Desktop Device Desktop @@ -38,6 +39,7 @@ :///DESKTOP/// {68d379f6-357c-42a6-83c6-7743840db4ea} + Qt Simulator false @@ -48,7 +50,7 @@ false - /usr/bin/gdb + {70e26273-2c0b-4534-bbc0-eb6ca670821a} {68a75dff-5ec6-40cb-884f-8f383ed2ebb2} Maemo5OsType @@ -58,6 +60,7 @@ :///DESKTOP/// {f559999e-8f5d-4246-9321-ea9d1c444c85} + Fremantle false @@ -68,10 +71,7 @@ false - - /usr/bin/gdb - 1 - + {70e26273-2c0b-4534-bbc0-eb6ca670821a} {1a0985cf-ad32-487c-8af8-85ee532ac19c} HarmattanOsType @@ -81,6 +81,7 @@ :///DESKTOP/// {744799ff-3430-41e1-ad7d-d76c50c1c621} + Harmattan false @@ -91,10 +92,7 @@ false - - /usr/bin/gdb - 1 - + {70e26273-2c0b-4534-bbc0-eb6ca670821a} {7c5a3673-e300-4286-9666-0f86d3e3dc38} GenericLinuxOsType @@ -104,6 +102,7 @@ :///DESKTOP/// {f16848fc-b615-43b5-b0cc-16a9f57fb573} + Embedded Linux false @@ -114,7 +113,7 @@ false - /usr/bin/gdb + {70e26273-2c0b-4534-bbc0-eb6ca670821a} Desktop Device Desktop @@ -124,6 +123,7 @@ :///DESKTOP/// {9c58fcfd-9e49-4a08-971f-a677dc9ce185} + Desktop 501 default false @@ -134,7 +134,7 @@ false - /usr/bin/gdb + {70e26273-2c0b-4534-bbc0-eb6ca670821a} Desktop Device Desktop @@ -144,6 +144,7 @@ :///DESKTOP/// {1dcb5509-1670-470d-80a5-8a988f36e4e2} + Desktop 480 GCC false diff --git a/tests/system/settings/windows/QtProject/qtcreator/debuggers.xml b/tests/system/settings/windows/QtProject/qtcreator/debuggers.xml new file mode 100644 index 00000000000..f9bac448c4a --- /dev/null +++ b/tests/system/settings/windows/QtProject/qtcreator/debuggers.xml @@ -0,0 +1,50 @@ + + + + + + DebuggerItem.0 + + + x86-windows-msvc2010-pe-64bit + + true + C:\Program Files\Debugging Tools for Windows (x64)\cdb.exe + Auto-detected CDB at C:\Program Files\Debugging Tools for Windows (x64)\cdb.exe + 4 + {811977c9-ea95-4616-bc28-c66d1935ff65} + + + + DebuggerItem.1 + + + true + C:\QtSDK\pythongdb\python_2.7based\gdb-i686-pc-mingw32.exe + Extracted from Kit Desktop 474 GCC + 1 + {44aee0bd-999d-4abe-82c6-5c7979e7cf01} + + + + DebuggerItem.2 + + + arm-linux-generic-elf-32bit + + true + C:\QtSDK\pythongdb\python_2.7based\gdb-arm-none-linux-gnueabi.exe + Extracted from Kit Fremantle + 1 + {5ad1d623-7300-41b4-ba32-99e11bfcb988} + + + + DebuggerItem.Count + 3 + + + Version + 1 + + diff --git a/tests/system/settings/windows/QtProject/qtcreator/profiles.xml b/tests/system/settings/windows/QtProject/qtcreator/profiles.xml index faa3216ef03..09cf47de68e 100644 --- a/tests/system/settings/windows/QtProject/qtcreator/profiles.xml +++ b/tests/system/settings/windows/QtProject/qtcreator/profiles.xml @@ -1,6 +1,6 @@ - + Profile.0 @@ -8,7 +8,7 @@ false - C:/QtSDK/pythongdb/python_2.7based/gdb-i686-pc-mingw32.exe + {44aee0bd-999d-4abe-82c6-5c7979e7cf01} Desktop Device Desktop @@ -18,6 +18,7 @@ :///DESKTOP/// {897290fe-c35a-4e5e-b5e2-d8e448e2aed1} + Desktop 474 GCC false @@ -28,7 +29,7 @@ false - C:/QtSDK/pythongdb/python_2.7based/gdb-i686-pc-mingw32.exe + {44aee0bd-999d-4abe-82c6-5c7979e7cf01} Desktop Device Desktop @@ -38,6 +39,7 @@ :///DESKTOP/// {0ce9f69f-0f60-4b04-8691-c328ee5bfe14} + Qt Simulator false @@ -48,7 +50,7 @@ false - C:/QtSDK/pythongdb/python_2.7based/gdb-arm-none-linux-gnueabi.exe + {5ad1d623-7300-41b4-ba32-99e11bfcb988} {0d112162-56a5-40cb-a911-e0545489da5c} Maemo5OsType @@ -58,6 +60,7 @@ :///DESKTOP/// {618722a5-c008-4869-9404-07f755973496} + Fremantle false @@ -68,10 +71,7 @@ false - - C:\QtSDK\pythongdb\python_2.7based\gdb-arm-none-linux-gnueabi.exe - 1 - + {5ad1d623-7300-41b4-ba32-99e11bfcb988} {3260da4e-2949-43b8-b464-1f34d0a47c04} HarmattanOsType @@ -81,6 +81,7 @@ :///DESKTOP/// {3800d54f-6c86-4cd1-88a9-7456bbef6dce} + Harmattan false @@ -91,10 +92,7 @@ false - - C:\Program Files\Debugging Tools for Windows (x64)\cdb.exe - 4 - + {811977c9-ea95-4616-bc28-c66d1935ff65} Desktop Device Desktop @@ -104,6 +102,7 @@ :///DESKTOP/// {9b35bbe6-25a7-4cce-ba07-487c795f5265} + Desktop 480 MSVC2010 false @@ -114,10 +113,7 @@ false - - C:\Program Files\Debugging Tools for Windows (x64)\cdb.exe - 4 - + {811977c9-ea95-4616-bc28-c66d1935ff65} Desktop Device Desktop @@ -127,6 +123,7 @@ :///DESKTOP/// {175f6238-a585-4e62-b2d3-d15e90296bb6} + Desktop 501 default false @@ -137,7 +134,7 @@ false - C:/QtSDK/pythongdb/python_2.7based/gdb-i686-pc-mingw32.exe + {44aee0bd-999d-4abe-82c6-5c7979e7cf01} Desktop Device Desktop @@ -147,6 +144,7 @@ :///DESKTOP/// {9dc9de67-fdc0-4ba6-877a-1463aacd3b3e} + Desktop 480 GCC false From d12527c212ef7c104b067149794d99c5559e4eaa Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 18 Oct 2013 15:47:29 +0200 Subject: [PATCH 45/84] Fix escape key logic when design mode has output panes open Task-number: QTCREATORBUG-9985 Change-Id: I6b22c92ac8f780b1a9469e9c2fd4a7cfecfef15f Reviewed-by: David Schulz --- .../editormanager/editormanager.cpp | 71 +++++++++++-------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 93a7c3c739d..073b89dc5b9 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -854,10 +854,13 @@ static void setFocusToEditorViewAndUnmaximizePanes(EditorView *view) void EditorManager::doEscapeKeyFocusMoveMagic() { // use cases to cover: - // 1. if app focus is in mode or external window without editor view (e.g. Projects, ext. Help) - // activate & raise the current editor view (can be external) - // if that is in edit mode - // activate edit mode and unmaximize output pane + // 1. if app focus is in mode or external window without editor view (e.g. Design, Projects, ext. Help) + // if there are extra views (e.g. output) + // hide them + // otherwise + // activate & raise the current editor view (can be external) + // if that is in edit mode + // activate edit mode and unmaximize output pane // 2. if app focus is in external window with editor view // hide find if necessary // 2. if app focus is in mode with editor view @@ -874,13 +877,40 @@ void EditorManager::doEscapeKeyFocusMoveMagic() // otherwise (i.e. mode is edit mode) // hide extra views (find, help, output) + QWidget *activeWindow = qApp->activeWindow(); + if (!activeWindow) + return; + QWidget *focus = qApp->focusWidget(); EditorView *editorView = currentEditorView(); - bool editorViewActive = (qApp->focusWidget() == editorView->focusWidget()); + bool editorViewActive = (focus && focus == editorView->focusWidget()); bool editorViewVisible = editorView->isVisible(); + + if (!( editorViewVisible && !editorViewActive && editorView->window() == activeWindow )) { + bool stuffHidden = false; + QWidget *findPane = FindToolBarPlaceHolder::getCurrent(); + if (findPane && findPane->isVisible() && findPane->window() == activeWindow) { + findPane->hide(); + stuffHidden = true; + } + QWidget *outputPane = OutputPanePlaceHolder::getCurrent(); + if (outputPane && outputPane->isVisible() && outputPane->window() == activeWindow) { + OutputPaneManager::instance()->slotHide(); + stuffHidden = true; + } + QWidget *rightPane = RightPanePlaceHolder::current(); + if (rightPane && rightPane->isVisible() && rightPane->window() == activeWindow) { + RightPaneWidget::instance()->setShown(false); + stuffHidden = true; + } + if (stuffHidden) + return; + } + if (!editorViewActive && editorViewVisible) { setFocusToEditorViewAndUnmaximizePanes(editorView); return; } + if (!editorViewActive && !editorViewVisible) { // assumption is that editorView is in main window then ModeManager::activateMode(Id(Constants::MODE_EDIT)); @@ -888,30 +918,13 @@ void EditorManager::doEscapeKeyFocusMoveMagic() setFocusToEditorViewAndUnmaximizePanes(editorView); return; } - if (editorViewActive) { - QTC_CHECK(editorViewVisible); - bool stuffHidden = false; - QWidget *findPane = FindToolBarPlaceHolder::getCurrent(); - if (findPane && findPane->isVisibleTo(editorView)) { - findPane->hide(); - stuffHidden = true; - } - QWidget *outputPane = OutputPanePlaceHolder::getCurrent(); - if (outputPane && outputPane->isVisibleTo(editorView)) { - OutputPaneManager::instance()->slotHide(); - stuffHidden = true; - } - QWidget *rightPane = RightPanePlaceHolder::current(); - if (rightPane && rightPane->isVisibleTo(editorView)) { - RightPaneWidget::instance()->setShown(false); - stuffHidden = true; - } - if (!stuffHidden && editorView->window() == ICore::mainWindow()) { - // we are in a editor view and there's nothing to hide, switch to edit - ModeManager::activateMode(Id(Constants::MODE_EDIT)); - // next call works only because editor views in main window are shared between modes - setFocusToEditorViewAndUnmaximizePanes(editorView); - } + + if (editorView->window() == ICore::mainWindow()) { + // we are in a editor view and there's nothing to hide, switch to edit + ModeManager::activateMode(Id(Constants::MODE_EDIT)); + QTC_CHECK(editorView->isVisible()); + // next call works only because editor views in main window are shared between modes + setFocusToEditorViewAndUnmaximizePanes(editorView); } } From 0f094e3251b9a3808a268de5f074d557ff3bcace Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Fri, 25 Oct 2013 11:55:10 +0200 Subject: [PATCH 46/84] Android: Don't use -silent for ant That command line option was new in 1.9.0. We can't yet depend on that. Change-Id: I5231a735da7248e1102db446d6207a6a3e9dd72b Reviewed-by: BogDan Vatra --- 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 6f4a068ea58..a72b9ac6951 100644 --- a/src/plugins/android/androidpackagecreationstep.cpp +++ b/src/plugins/android/androidpackagecreationstep.cpp @@ -613,7 +613,7 @@ bool AndroidPackageCreationStep::createPackage() emit addOutput(tr("Copy Qt app & libs to Android package ..."), MessageOutput); QStringList build; - build << QLatin1String("-silent"); + // build << QLatin1String("-silent"); //TODO depends on ant 1.9.0, enabled, not *now* build << QLatin1String("clean"); QFile::remove(m_gdbServerDestination.toString()); if (m_signPackageForRun) { From 9aea8087a19a4d21b40cdf51d2d66f2302cc8d34 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 24 Oct 2013 15:08:39 +0200 Subject: [PATCH 47/84] QbsProjectManager: Fix build config comparison. The current code compares a flat map against the tree-ified version, which will never be equal. Change-Id: I99d82d87635e5ccacc5a5709bced9a30f62d4018 Reviewed-by: Tobias Hunger --- src/plugins/qbsprojectmanager/qbsproject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 5bd01b39b54..c06c5a121b0 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -427,7 +427,7 @@ void QbsProject::parse(const QVariantMap &config, const Environment &env, const const qbs::Project ¤tProject = qbsProject(); if (!m_forceParsing && currentProject.isValid() - && currentProject.projectConfiguration() == params.buildConfiguration()) { + && currentProject.projectConfiguration() == params.finalBuildConfigurationTree()) { QHash usedEnv = currentProject.usedEnvironment(); bool canSkip = true; for (QHash::const_iterator i = usedEnv.constBegin(); From 3c7af78448c8902e3538399011d2da11a13f21cf Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 24 Oct 2013 15:10:04 +0200 Subject: [PATCH 48/84] QbsProjectManager: Fix overriding of properties. We have to mark the user-set properties appropriately; otherwise, properties in project files will not get overridden. Change-Id: I3bcb013fde2b76521a85c3283e2b158beaf40b26 Reviewed-by: Joerg Bornemann Reviewed-by: Tobias Hunger --- src/plugins/qbsprojectmanager/qbsproject.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index c06c5a121b0..1ba89d52190 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -416,7 +416,14 @@ void QbsProject::parse(const QVariantMap &config, const Environment &env, const QTC_ASSERT(!dir.isNull(), return); qbs::SetupProjectParameters params; - params.setBuildConfiguration(config); + QVariantMap baseConfig; + QVariantMap userConfig = config; + QString specialKey = QLatin1String(Constants::QBS_CONFIG_PROFILE_KEY); + baseConfig.insert(specialKey, userConfig.take(specialKey)); + specialKey = QLatin1String(Constants::QBS_CONFIG_VARIANT_KEY); + baseConfig.insert(specialKey, userConfig.take(specialKey)); + params.setBuildConfiguration(baseConfig); + params.setOverriddenValues(userConfig); qbs::ErrorInfo err = params.expandBuildConfiguration(m_manager->settings()); if (err.hasError()) { generateErrors(err); From 66bbfd9f9205f5d7a10ab023118ac3e698b29a56 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Fri, 25 Oct 2013 11:34:12 +0300 Subject: [PATCH 49/84] Locator: Wait for the process to start in execute filter finished() signal is insufficient Change-Id: I591b5b6494218c8fc8a16f4d79c91a844105233a Reviewed-by: Oswald Buddenhagen --- src/plugins/locator/executefilter.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/plugins/locator/executefilter.cpp b/src/plugins/locator/executefilter.cpp index 4b4ef46b0b6..20e940a1d78 100644 --- a/src/plugins/locator/executefilter.cpp +++ b/src/plugins/locator/executefilter.cpp @@ -168,6 +168,11 @@ void ExecuteFilter::runHeadCommand() m_process->setCommand(fullPath, d.arguments); m_process->start(); m_process->closeWriteChannel(); + if (!m_process->waitForStarted(1000)) { + MessageManager::write(tr("Could not start process: %1").arg(m_process->errorString())); + m_taskQueue.dequeue(); + runHeadCommand(); + } } } From 6578a9ba9fb8e135167519ed04e6045b37fd8b33 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Fri, 25 Oct 2013 10:45:42 +0200 Subject: [PATCH 50/84] Squish: Fix handleDebuggerWarnings() Change-Id: Ib4550e82e0acfa168003f64d91bf25af62a533fa Reviewed-by: Christian Stenger --- tests/system/shared/debugger.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/system/shared/debugger.py b/tests/system/shared/debugger.py index 9a883915792..d4fbfbd9c0f 100644 --- a/tests/system/shared/debugger.py +++ b/tests/system/shared/debugger.py @@ -49,11 +49,12 @@ def handleDebuggerWarnings(config, isMsvcBuild=False): except LookupError: pass # No warning. Fine. if "Release" in config and (isMsvcBuild or platform.system() == "Linux"): - message = waitForObject("{container=':Qt Creator.DebugModeWidget_QSplitter' name='qt_msgbox_label' type='QLabel' visible='1'}") + msgBox = "{type='QMessageBox' unnamed='1' visible='1' windowTitle='Warning'}" + message = waitForObject("{name='qt_msgbox_label' type='QLabel' visible='1' window=%s}" % msgBox) messageText = str(message.text) test.verify(messageText.startswith('This does not seem to be a "Debug" build.\nSetting breakpoints by file name and line number may fail.'), "Got warning: %s" % messageText) - clickButton("{container=':Qt Creator.DebugModeWidget_QSplitter' text='OK' type='QPushButton' unnamed='1' visible='1'}") + clickButton("{text='OK' type='QPushButton' unnamed='1' visible='1' window=%s}" % msgBox) def takeDebuggerLog(): invokeMenuItem("Window", "Views", "Debugger Log") From 1d052d308e3eb3a0e5928d4f531f29b71f6f8af6 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Fri, 25 Oct 2013 12:46:16 +0200 Subject: [PATCH 51/84] Squish: Stabilize setting "Run in Terminal" Change-Id: Icddb2852975ad72c9c6e70d71c07a89a390576fa Reviewed-by: Christian Stenger --- tests/system/suite_debugger/tst_cli_output_console/test.py | 1 + tests/system/suite_debugger/tst_debug_empty_main/test.py | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/system/suite_debugger/tst_cli_output_console/test.py b/tests/system/suite_debugger/tst_cli_output_console/test.py index 826049cf7b0..ee5302ad33d 100644 --- a/tests/system/suite_debugger/tst_cli_output_console/test.py +++ b/tests/system/suite_debugger/tst_cli_output_console/test.py @@ -73,6 +73,7 @@ def main(): test.log("Testing build configuration: " + config) test.log("Running application") + progressBarWait(15000) setRunInTerminal(len(checkedTargets), kit, False) runControlFinished = False clickButton(waitForObject(":*Qt Creator.Run_Core::Internal::FancyToolButton")) diff --git a/tests/system/suite_debugger/tst_debug_empty_main/test.py b/tests/system/suite_debugger/tst_debug_empty_main/test.py index a055bcd0a91..ab62d7dc87d 100644 --- a/tests/system/suite_debugger/tst_debug_empty_main/test.py +++ b/tests/system/suite_debugger/tst_debug_empty_main/test.py @@ -78,6 +78,7 @@ def main(): replaceEditorContent(editor, "") typeLines(editor, ["int main() {"]) invokeMenuItem("File", "Save All") + progressBarWait(15000) setRunInTerminal(1, 0, False) performDebugging(workingDir, projectName, [singleTarget]) invokeMenuItem("File", "Close All Projects and Editors") From 5ef35e4125635f2be72d0873e22e2e44a2394d9b Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Thu, 24 Oct 2013 13:33:52 +0200 Subject: [PATCH 52/84] Abi: Fix Abi constructor to not disallow certain abi combinations Change-Id: I58e51bb0756270cb7929c0edc0811342a67fbe31 Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/abi.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/projectexplorer/abi.cpp b/src/plugins/projectexplorer/abi.cpp index b0c45aa001a..219a6f47f37 100644 --- a/src/plugins/projectexplorer/abi.cpp +++ b/src/plugins/projectexplorer/abi.cpp @@ -315,14 +315,15 @@ Abi::Abi(const Architecture &a, const OS &o, m_osFlavor = UnknownFlavor; break; case ProjectExplorer::Abi::BsdOS: - m_osFlavor = FreeBsdFlavor; + if (m_osFlavor < FreeBsdFlavor || m_osFlavor > OpenBsdFlavor) + m_osFlavor = UnknownFlavor; break; case ProjectExplorer::Abi::MacOS: if (m_osFlavor < GenericMacFlavor || m_osFlavor > GenericMacFlavor) m_osFlavor = UnknownFlavor; break; case ProjectExplorer::Abi::UnixOS: - if (m_osFlavor < GenericUnixFlavor || m_osFlavor > GenericUnixFlavor) + if (m_osFlavor < GenericUnixFlavor || m_osFlavor > SolarisUnixFlavor) m_osFlavor = UnknownFlavor; break; case ProjectExplorer::Abi::WindowsOS: From a4aa2bc29b0d945984b1dc8564985010dbf881e8 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Thu, 24 Oct 2013 13:34:41 +0200 Subject: [PATCH 53/84] Abi: Remove traces of harmhattan and maemo support Change-Id: Ibacaf76e39e98c9d37d56e0bdedbbae07702e979 Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/abi.cpp | 13 ++----------- src/plugins/projectexplorer/abi.h | 2 -- .../qt4projectmanager/librarydetailscontroller.cpp | 1 - src/plugins/qt4projectmanager/qmakestep.cpp | 5 ----- src/plugins/qtsupport/baseqtversion.cpp | 10 ---------- 5 files changed, 2 insertions(+), 29 deletions(-) diff --git a/src/plugins/projectexplorer/abi.cpp b/src/plugins/projectexplorer/abi.cpp index 219a6f47f37..aafe96ccd95 100644 --- a/src/plugins/projectexplorer/abi.cpp +++ b/src/plugins/projectexplorer/abi.cpp @@ -311,7 +311,7 @@ Abi::Abi(const Architecture &a, const OS &o, m_osFlavor = UnknownFlavor; break; case ProjectExplorer::Abi::LinuxOS: - if (m_osFlavor < GenericLinuxFlavor || m_osFlavor > MaemoLinuxFlavor) + if (m_osFlavor < GenericLinuxFlavor || m_osFlavor > AndroidLinuxFlavor) m_osFlavor = UnknownFlavor; break; case ProjectExplorer::Abi::BsdOS: @@ -388,10 +388,6 @@ Abi::Abi(const QString &abiString) : m_osFlavor = NetBsdFlavor; else if (abiParts.at(2) == QLatin1String("openbsd") && m_os == BsdOS) m_osFlavor = OpenBsdFlavor; - else if (abiParts.at(2) == QLatin1String("maemo") && m_os == LinuxOS) - m_osFlavor = MaemoLinuxFlavor; - else if (abiParts.at(2) == QLatin1String("harmattan") && m_os == LinuxOS) - m_osFlavor = HarmattanLinuxFlavor; else if (abiParts.at(2) == QLatin1String("generic") && m_os == MacOS) m_osFlavor = GenericMacFlavor; else if (abiParts.at(2) == QLatin1String("generic") && m_os == UnixOS) @@ -638,10 +634,6 @@ QString Abi::toString(const OSFlavor &of) return QLatin1String("netbsd"); case ProjectExplorer::Abi::OpenBsdFlavor: return QLatin1String("openbsd"); - case ProjectExplorer::Abi::MaemoLinuxFlavor: - return QLatin1String("maemo"); - case ProjectExplorer::Abi::HarmattanLinuxFlavor: - return QLatin1String("harmattan"); case ProjectExplorer::Abi::GenericMacFlavor: return QLatin1String("generic"); case ProjectExplorer::Abi::GenericUnixFlavor: @@ -699,8 +691,7 @@ QList Abi::flavorsForOs(const Abi::OS &o) case BsdOS: return result << FreeBsdFlavor << OpenBsdFlavor << NetBsdFlavor << UnknownFlavor; case LinuxOS: - return result << GenericLinuxFlavor << HarmattanLinuxFlavor << MaemoLinuxFlavor - << AndroidLinuxFlavor << UnknownFlavor; + return result << GenericLinuxFlavor << AndroidLinuxFlavor << UnknownFlavor; case MacOS: return result << GenericMacFlavor << UnknownFlavor; case UnixOS: diff --git a/src/plugins/projectexplorer/abi.h b/src/plugins/projectexplorer/abi.h index 473918b9185..e7e7a9669ea 100644 --- a/src/plugins/projectexplorer/abi.h +++ b/src/plugins/projectexplorer/abi.h @@ -73,8 +73,6 @@ public: // Linux GenericLinuxFlavor, AndroidLinuxFlavor, - HarmattanLinuxFlavor, - MaemoLinuxFlavor, // Mac GenericMacFlavor, diff --git a/src/plugins/qt4projectmanager/librarydetailscontroller.cpp b/src/plugins/qt4projectmanager/librarydetailscontroller.cpp index 72536849664..3f79461f3cd 100644 --- a/src/plugins/qt4projectmanager/librarydetailscontroller.cpp +++ b/src/plugins/qt4projectmanager/librarydetailscontroller.cpp @@ -103,7 +103,6 @@ LibraryDetailsController::LibraryDetailsController( } } } - setPlatformsVisible(true); setLinkageGroupVisible(true); setMacLibraryGroupVisible(true); diff --git a/src/plugins/qt4projectmanager/qmakestep.cpp b/src/plugins/qt4projectmanager/qmakestep.cpp index 5331ece9729..0980c48982a 100644 --- a/src/plugins/qt4projectmanager/qmakestep.cpp +++ b/src/plugins/qt4projectmanager/qmakestep.cpp @@ -166,11 +166,6 @@ QStringList QMakeStep::deducedArguments() ProjectExplorer::Abi targetAbi; if (tc) targetAbi = tc->targetAbi(); - if ((HostOsInfo::isWindowsHost() || HostOsInfo::isMacHost()) - && (targetAbi.osFlavor() == ProjectExplorer::Abi::HarmattanLinuxFlavor - || targetAbi.osFlavor() == ProjectExplorer::Abi::MaemoLinuxFlavor)) { - arguments << QLatin1String("-unix"); - } // explicitly add architecture to CONFIG if ((targetAbi.os() == ProjectExplorer::Abi::MacOS) diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index ced6d1defed..7e08dc3493f 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -1475,16 +1475,6 @@ bool BaseQtVersion::isQmlDebuggingSupported(QString *reason) const if (!needsQmlDebuggingLibrary() || hasQmlDebuggingLibrary()) return true; - if (!qtAbis().isEmpty()) { - Abi abi = qtAbis().first(); - if (abi.osFlavor() == Abi::MaemoLinuxFlavor) { - if (reason) - reason->clear(); - // *reason = QCoreApplication::translate("BaseQtVersion", "Qml debugging on device not yet supported."); - return false; - } - } - if (!isValid()) { if (reason) *reason = QCoreApplication::translate("BaseQtVersion", "Invalid Qt version."); From 1567f4729f879b117bfaad74df90fd0214bf0dae Mon Sep 17 00:00:00 2001 From: David Kaspar Date: Wed, 23 Oct 2013 16:09:45 +0200 Subject: [PATCH 54/84] ProjectExplorer: Fixing style of read-only SysRootInformationConfigWidget Style of read-only SysRootInformationConfigWidget and QmakeKitConfigWidget was not matching. SysRootInformationConfigWidget was using lineEdit.setReadOnly(true) QmakeKitConfigWidget and even other *InformationConfigWidgets are using lineEdit.setEnabled(false) Therefore making SysRootInformationConfigWidget to use setEnabled(false) too. Change-Id: I637b7a7afe522b7a622975a1b37b2256a802ae1a Reviewed-by: Mehdi Fekari Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/kitinformationconfigwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/kitinformationconfigwidget.cpp b/src/plugins/projectexplorer/kitinformationconfigwidget.cpp index d3a43ba0967..7c5ac9bcad1 100644 --- a/src/plugins/projectexplorer/kitinformationconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitinformationconfigwidget.cpp @@ -89,7 +89,7 @@ void SysRootInformationConfigWidget::refresh() void SysRootInformationConfigWidget::makeReadOnly() { - m_chooser->setReadOnly(true); + m_chooser->setEnabled(false); } QWidget *SysRootInformationConfigWidget::mainWidget() const From c2705f1595f2b1db5d886b6d11e256f2322b96f4 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 25 Oct 2013 12:18:36 +0200 Subject: [PATCH 55/84] DebuggerItem: Make sure DebuggerItems have an Id The default constructor now sets an id on debuggerItem. fromMap was removed and a new constructor (taking a const QVariantMap &) was added in place of that. There are no more friends on the DebuggerItem class since those were only necessary to make sure the item has an Id when it gets added. Change-Id: Ia1a6c9ffea67a8e0a1e5685ef93f67df8686d4c9 Reviewed-by: hjk Reviewed-by: Tobias Hunger --- .../debugger/debuggerkitconfigwidget.cpp | 15 +++---- .../debugger/debuggerkitinformation.cpp | 39 +++++++++---------- src/plugins/debugger/debuggerkitinformation.h | 6 +-- 3 files changed, 24 insertions(+), 36 deletions(-) diff --git a/src/plugins/debugger/debuggerkitconfigwidget.cpp b/src/plugins/debugger/debuggerkitconfigwidget.cpp index 9d9f0b23a9a..8fbf67390a4 100644 --- a/src/plugins/debugger/debuggerkitconfigwidget.cpp +++ b/src/plugins/debugger/debuggerkitconfigwidget.cpp @@ -387,8 +387,7 @@ static void readDebuggers(const FileName &fileName, bool isSystem) if (!data.contains(key)) continue; const QVariantMap dbMap = data.value(key).toMap(); - DebuggerItem item; - item.fromMap(dbMap); + DebuggerItem item(dbMap); if (isSystem) { item.setAutoDetected(true); // SDK debuggers are always considered to be up-to-date, so no need to recheck them. @@ -660,14 +659,12 @@ void DebuggerItemManager::deregisterDebugger(const DebuggerItem &item) removeDebugger(item.id()); } -QVariant DebuggerItemManager::addDebugger(const DebuggerItem& item0) +QVariant DebuggerItemManager::addDebugger(const DebuggerItem &item) { - DebuggerItem item = item0; QTC_ASSERT(!item.command().isEmpty(), return QVariant()); QTC_ASSERT(!item.displayName().isEmpty(), return QVariant()); QTC_ASSERT(item.engineType() != NoEngineType, return QVariant()); - if (item.id().isNull()) - item.setId(QUuid::createUuid().toString()); + QTC_ASSERT(item.id().isValid(), return QVariant()); m_debuggers.append(item); m_model->addDebugger(item); return item.id(); @@ -821,11 +818,9 @@ void DebuggerItemModel::markCurrentDirty() sitem->setFont(font); } -void DebuggerItemModel::addDebugger(const DebuggerItem &item0) +void DebuggerItemModel::addDebugger(const DebuggerItem &item) { - DebuggerItem item = item0; - if (item.id().isNull()) - item.setId(QUuid::createUuid().toString()); + QTC_ASSERT(item.id().isValid(), return); QList row = describeItem(item); (item.isAutoDetected() ? m_autoRoot : m_manualRoot)->appendRow(row); emit debuggerAdded(item.id(), item.displayName()); diff --git a/src/plugins/debugger/debuggerkitinformation.cpp b/src/plugins/debugger/debuggerkitinformation.cpp index 30ca4f2c230..5436206bcba 100644 --- a/src/plugins/debugger/debuggerkitinformation.cpp +++ b/src/plugins/debugger/debuggerkitinformation.cpp @@ -34,6 +34,7 @@ #include #include +#include using namespace Debugger::Internal; using namespace ProjectExplorer; @@ -54,10 +55,27 @@ namespace Debugger { DebuggerItem::DebuggerItem() { + m_id = QUuid::createUuid().toString(); m_engineType = NoEngineType; m_isAutoDetected = false; } +DebuggerItem::DebuggerItem(const QVariantMap &data) +{ + m_command = FileName::fromUserInput(data.value(QLatin1String(DEBUGGER_INFORMATION_COMMAND)).toString()); + m_id = data.value(QLatin1String(DEBUGGER_INFORMATION_ID)).toString(); + m_displayName = data.value(QLatin1String(DEBUGGER_INFORMATION_DISPLAYNAME)).toString(); + m_isAutoDetected = data.value(QLatin1String(DEBUGGER_INFORMATION_AUTODETECTED), false).toBool(); + m_engineType = DebuggerEngineType(data.value(QLatin1String(DEBUGGER_INFORMATION_ENGINETYPE), + static_cast(NoEngineType)).toInt()); + + foreach (const QString &a, data.value(QLatin1String(DEBUGGER_INFORMATION_ABIS)).toStringList()) { + Abi abi(a); + if (abi.isValid()) + m_abis.append(abi); + } +} + void DebuggerItem::reinitializeFromFile() { QProcess proc; @@ -133,27 +151,6 @@ QVariantMap DebuggerItem::toMap() const return data; } -void DebuggerItem::fromMap(const QVariantMap &data) -{ - m_command = FileName::fromUserInput(data.value(QLatin1String(DEBUGGER_INFORMATION_COMMAND)).toString()); - m_id = data.value(QLatin1String(DEBUGGER_INFORMATION_ID)).toString(); - m_displayName = data.value(QLatin1String(DEBUGGER_INFORMATION_DISPLAYNAME)).toString(); - m_isAutoDetected = data.value(QLatin1String(DEBUGGER_INFORMATION_AUTODETECTED)).toBool(); - m_engineType = DebuggerEngineType(data.value(QLatin1String(DEBUGGER_INFORMATION_ENGINETYPE)).toInt()); - - m_abis.clear(); - foreach (const QString &a, data.value(QLatin1String(DEBUGGER_INFORMATION_ABIS)).toStringList()) { - Abi abi(a); - if (abi.isValid()) - m_abis.append(abi); - } -} - -void DebuggerItem::setId(const QVariant &id) -{ - m_id = id; -} - void DebuggerItem::setDisplayName(const QString &displayName) { m_displayName = displayName; diff --git a/src/plugins/debugger/debuggerkitinformation.h b/src/plugins/debugger/debuggerkitinformation.h index dfdf6350a4e..4a185d79e3d 100644 --- a/src/plugins/debugger/debuggerkitinformation.h +++ b/src/plugins/debugger/debuggerkitinformation.h @@ -50,13 +50,13 @@ class DEBUGGER_EXPORT DebuggerItem { public: DebuggerItem(); + DebuggerItem(const QVariantMap &data); bool canClone() const { return true; } bool isValid() const; QString engineTypeName() const; QVariantMap toMap() const; - void fromMap(const QVariantMap &data); void reinitializeFromFile(); QVariant id() const { return m_id; } @@ -83,10 +83,6 @@ public: QStringList abiNames() const; private: - friend class Debugger::Internal::DebuggerItemModel; - friend class DebuggerItemManager; - void setId(const QVariant &id); - QVariant m_id; QString m_displayName; DebuggerEngineType m_engineType; From deeeda162d1c05331c1988b683ddb0c0900bf8a8 Mon Sep 17 00:00:00 2001 From: jkobus Date: Fri, 25 Oct 2013 12:48:09 +0200 Subject: [PATCH 56/84] Remove unneeded space Change-Id: I7e7335bd8b3ef2816abe07a3c5dc6cf2b86afc3b Reviewed-by: Leena Miettinen --- share/qtcreator/templates/wizards/qtquick1-extension/wizard.xml | 2 +- share/qtcreator/templates/wizards/qtquick2-extension/wizard.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/share/qtcreator/templates/wizards/qtquick1-extension/wizard.xml b/share/qtcreator/templates/wizards/qtquick1-extension/wizard.xml index ce311f620e3..5f305c04417 100644 --- a/share/qtcreator/templates/wizards/qtquick1-extension/wizard.xml +++ b/share/qtcreator/templates/wizards/qtquick1-extension/wizard.xml @@ -51,7 +51,7 @@ leave room for the Qt 4 target page. - Custom QML Extension Plugin Parameters + Custom QML Extension Plugin Parameters diff --git a/share/qtcreator/templates/wizards/qtquick2-extension/wizard.xml b/share/qtcreator/templates/wizards/qtquick2-extension/wizard.xml index 16c624d21ab..8de803a7231 100644 --- a/share/qtcreator/templates/wizards/qtquick2-extension/wizard.xml +++ b/share/qtcreator/templates/wizards/qtquick2-extension/wizard.xml @@ -51,7 +51,7 @@ leave room for the Qt 4 target page. - Custom QML Extension Plugin Parameters + Custom QML Extension Plugin Parameters From c033fc3a345d7fd4d48bc555ba307109fbeddc51 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Thu, 24 Oct 2013 16:54:24 +0200 Subject: [PATCH 57/84] TaskView: Fix scrolling Broken by qtbase commit 934f06220391eb0e0ebf66a2eb037f48adb4c43c Change-Id: Iafbeab63cca8b6f328276eaf0a4d27a749b30087 Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/taskwindow.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index ce094aeff8e..34ab0c6d011 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -48,6 +48,7 @@ #include #include #include +#include namespace { const int ELLIPSIS_GRADIENT_WIDTH = 16; @@ -74,6 +75,8 @@ class TaskDelegate : public QStyledItemDelegate { Q_OBJECT + friend class TaskView; // for using Positions::minimumSize() + public: TaskDelegate(QObject * parent = 0); ~TaskDelegate(); @@ -126,11 +129,11 @@ private: int right() const { return m_totalWidth - ITEM_MARGIN; } int bottom() const { return m_bottom; } int firstLineHeight() const { return m_fontHeight + 1; } - int minimumHeight() const { return taskIconHeight() + 2 * ITEM_MARGIN; } + static int minimumHeight() { return taskIconHeight() + 2 * ITEM_MARGIN; } int taskIconLeft() const { return left(); } - int taskIconWidth() const { return TASK_ICON_SIZE; } - int taskIconHeight() const { return TASK_ICON_SIZE; } + static int taskIconWidth() { return TASK_ICON_SIZE; } + static int taskIconHeight() { return TASK_ICON_SIZE; } int taskIconRight() const { return taskIconLeft() + taskIconWidth(); } QRect taskIcon() const { return QRect(taskIconLeft(), top(), taskIconWidth(), taskIconHeight()); } @@ -169,6 +172,13 @@ TaskView::TaskView(QWidget *parent) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + + QFontMetrics fm(font()); + int vStepSize = fm.height() + 3; + if (vStepSize < TaskDelegate::Positions::minimumHeight()) + vStepSize = TaskDelegate::Positions::minimumHeight(); + + verticalScrollBar()->setSingleStep(vStepSize); } TaskView::~TaskView() From 7079a835a0fbef0e1b8bc43f801e52065ab34046 Mon Sep 17 00:00:00 2001 From: El Mehdi Fekari Date: Fri, 25 Oct 2013 15:02:56 +0200 Subject: [PATCH 58/84] Debugger: Add new debuggers from option page The asserts should be moved from the addDebugger() method which is called to add an 'empty' debugger when adding new one from the option page. Change-Id: Ic402db514d1e97f5fdc12d9bb9070bf29b2ab354 Reviewed-by: Friedemann Kleint Reviewed-by: hjk --- src/plugins/debugger/debuggerkitconfigwidget.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/debugger/debuggerkitconfigwidget.cpp b/src/plugins/debugger/debuggerkitconfigwidget.cpp index 8fbf67390a4..a3e0b611d31 100644 --- a/src/plugins/debugger/debuggerkitconfigwidget.cpp +++ b/src/plugins/debugger/debuggerkitconfigwidget.cpp @@ -647,6 +647,9 @@ void DebuggerItemManager::saveDebuggers() QVariant DebuggerItemManager::registerDebugger(const DebuggerItem &item) { + QTC_ASSERT(!item.command().isEmpty(), return QVariant()); + QTC_ASSERT(!item.displayName().isEmpty(), return QVariant()); + QTC_ASSERT(item.engineType() != NoEngineType, return QVariant()); if (findByCommand(item.command())) return item.id(); @@ -661,9 +664,6 @@ void DebuggerItemManager::deregisterDebugger(const DebuggerItem &item) QVariant DebuggerItemManager::addDebugger(const DebuggerItem &item) { - QTC_ASSERT(!item.command().isEmpty(), return QVariant()); - QTC_ASSERT(!item.displayName().isEmpty(), return QVariant()); - QTC_ASSERT(item.engineType() != NoEngineType, return QVariant()); QTC_ASSERT(item.id().isValid(), return QVariant()); m_debuggers.append(item); m_model->addDebugger(item); From 0190eb59f949d642585d624e3341d7b49ea56ab2 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 25 Oct 2013 13:35:31 +0200 Subject: [PATCH 59/84] Debugger: Show shadowed variables with LLDB Change-Id: If93547396384fe5b421c4b601b52476a23cdfa89 Reviewed-by: hjk --- share/qtcreator/debugger/lldbbridge.py | 32 +++++++++++++++--------- src/plugins/debugger/lldb/lldbengine.cpp | 7 +++--- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 94d485609ee..4a465c981f7 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -53,17 +53,17 @@ proc = subprocess.Popen(args=[sys.argv[1], '-P'], stdout=subprocess.PIPE, stderr (path, error) = proc.communicate() if error.startswith('lldb: invalid option -- P'): - sys.stdout.write('msg=\'Could not run "%s -P". Trying to find lldb.so from Xcode.\'@\n' % sys.argv[1]) + sys.stdout.write('msg=\'Could not run "%s -P". Trying to find lldb.so from Xcode.\'\n' % sys.argv[1]) proc = subprocess.Popen(args=['xcode-select', '--print-path'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (path, error) = proc.communicate() if len(error): path = '/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/' - sys.stdout.write('msg=\'Could not run "xcode-select --print-path"@\n') - sys.stdout.write('msg=\'Using hardcoded fallback at %s\'@\n' % path) + sys.stdout.write('msg=\'Could not run "xcode-select --print-path"\n') + sys.stdout.write('msg=\'Using hardcoded fallback at %s\'\n' % path) else: path = path.strip() + '/../SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/' - sys.stdout.write('msg=\'Using fallback at %s\'@\n' % path) + sys.stdout.write('msg=\'Using fallback at %s\'\n' % path) #sys.path.append(path) sys.path.insert(1, path.strip()) @@ -142,7 +142,7 @@ stateNames = ["invalid", "unloaded", "connected", "attaching", "launching", "sto def loggingCallback(args): s = args.strip() s = s.replace('"', "'") - sys.stdout.write('log="%s"@\n' % s) + sys.stdout.write('log="%s"\n' % s) def check(exp): if not exp: @@ -1223,13 +1223,22 @@ class Dumper(DumperBase): self.currentIName = 'local' self.put('data=[') self.anonNumber = 0 - for value in frame.GetVariables(True, True, False, False): + shadowed = {} + values = [v for v in frame.GetVariables(True, True, False, False) if v.IsValid()] + values.reverse() # To get shadowed vars numbered backwards. + for value in values: if self.dummyValue is None: self.dummyValue = value - with SubItem(self, value): - if value.IsValid(): - self.put('iname="%s",' % self.currentIName) - self.putItem(value) + name = value.name + if value.name in shadowed: + level = shadowed[name] + shadowed[name] = level + 1 + name += "@%s" % level + else: + shadowed[name] = 1 + with SubItem(self, name): + self.put('iname="%s",' % self.currentIName) + self.putItem(value) # 'watchers':[{'id':'watch.0','exp':'23'},...] if not self.dummyValue is None: @@ -1283,8 +1292,7 @@ class Dumper(DumperBase): self.report(result) def report(self, stuff): - sys.stdout.write(stuff) - sys.stdout.write("@\n") + sys.stdout.write(stuff + "\n") def interruptInferior(self, _ = None): if self.process is None: diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 551d660a539..46dfd62aef8 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -836,15 +836,14 @@ void LldbEngine::readLldbStandardError() void LldbEngine::readLldbStandardOutput() { QByteArray out = m_lldbProc.readAllStandardOutput(); - //showMessage(_("Lldb stdout: " + out)); - showMessage(_(out), LogDebug); + showMessage(_("Lldb stdout: " + out)); m_inbuffer.append(out); while (true) { - int pos = m_inbuffer.indexOf("@\n"); + int pos = m_inbuffer.indexOf('\n'); if (pos == -1) break; QByteArray response = m_inbuffer.left(pos).trimmed(); - m_inbuffer = m_inbuffer.mid(pos + 2); + m_inbuffer = m_inbuffer.mid(pos + 1); emit outputReady(response); } } From 26165d348df9fef2196c27120dbdc0f22a260096 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 25 Oct 2013 13:35:31 +0200 Subject: [PATCH 60/84] Debugger: Allow more fine-grained debugger specific tests This is now (additionally) on a per-entry level, resulting in less duplication. Change-Id: Ia93547396384fe5b421c4b601b52476a23cdfa89 Reviewed-by: hjk --- tests/auto/debugger/tst_dumpers.cpp | 189 +++++++++++++++------------- 1 file changed, 100 insertions(+), 89 deletions(-) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 7b08bb3514c..4c7965e3918 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -157,6 +157,9 @@ static QString toHex(const QString &str) } +struct GdbOnly {}; +struct LldbOnly {}; + struct Context { Context() : qtVersion(0) {} @@ -305,7 +308,22 @@ struct Type QByteArray type; }; -struct Check +enum DebuggerEngine +{ + DumpTestGdbEngine, + DumpTestCdbEngine, + DumpTestLldbEngine +}; + +struct CheckBase +{ + CheckBase() : useLldb(true), useGdb(true) {} + + mutable bool useLldb; + mutable bool useGdb; +}; + +struct Check : CheckBase { Check() {} @@ -320,6 +338,30 @@ struct Check expectedValue(value), expectedType(type) {} + bool matchesEngine(DebuggerEngine engine) const + { + return (engine == DumpTestLldbEngine && useLldb) + || (engine == DumpTestGdbEngine && useGdb); + } + + const Check &setForLldbOnly() const + { + clearUsed(); + useLldb = true; + return *this; + } + + const Check &setForGdbOnly() const + { + clearUsed(); + useGdb = true; + return *this; + } + + void clearUsed() const + { + useLldb = useGdb = false; + } QByteArray iname; Name expectedName; Value expectedValue; @@ -381,9 +423,6 @@ struct MacLibCppProfile : public Profile {} }; -struct GdbOnly {}; -struct LldbOnly {}; - struct GdbVersion { // Minimum and maximum are inclusive. @@ -454,7 +493,7 @@ public: const Data &operator%(const Check &check) const { - checks.insert("local." + check.iname, check); + checks.append(check); return *this; } @@ -532,7 +571,7 @@ public: mutable QByteArray profileExtra; mutable QByteArray includes; mutable QByteArray code; - mutable QMap checks; // IName -> Action + mutable QList checks; }; struct TempStuff @@ -549,13 +588,6 @@ struct TempStuff QString buildPath; }; -enum DebuggerEngine -{ - DumpTestGdbEngine, - DumpTestCdbEngine, - DumpTestLldbEngine -}; - Q_DECLARE_METATYPE(Data) class tst_Dumpers : public QObject @@ -997,26 +1029,36 @@ void tst_Dumpers::dumper() bool ok = true; foreach (const WatchData &item, list) { seenINames.insert(item.iname); - if (data.checks.contains(item.iname)) { - Check check = data.checks.take(item.iname); - if (!check.expectedName.matches(item.name.toLatin1(), context)) { - qDebug() << "INAME : " << item.iname; - qDebug() << "NAME ACTUAL : " << item.name.toLatin1(); - qDebug() << "NAME EXPECTED: " << check.expectedName.name; - ok = false; - } - if (!check.expectedValue.matches(item.value, context)) { - qDebug() << "INAME : " << item.iname; - qDebug() << "VALUE ACTUAL : " << item.value << toHex(item.value); - qDebug() << "VALUE EXPECTED: " - << check.expectedValue.value << toHex(check.expectedValue.value); - ok = false; - } - if (!check.expectedType.matches(item.type, context)) { - qDebug() << "INAME : " << item.iname; - qDebug() << "TYPE ACTUAL : " << item.type; - qDebug() << "TYPE EXPECTED: " << check.expectedType.type; - ok = false; + //qDebug() << "NUM CHECKS" << data.checks.size(); + for (int i = data.checks.size(); --i >= 0; ) { + Check check = data.checks.at(i); + //qDebug() << "CHECKS" << i << check.iname; + if ("local." + check.iname == item.iname) { + data.checks.removeAt(i); + if (check.matchesEngine(m_debuggerEngine)) { + //qDebug() << "USING MATCHING TEST FOR " << item.iname; + if (!check.expectedName.matches(item.name.toLatin1(), context)) { + qDebug() << "INAME : " << item.iname; + qDebug() << "NAME ACTUAL : " << item.name.toLatin1(); + qDebug() << "NAME EXPECTED: " << check.expectedName.name; + ok = false; + } + if (!check.expectedValue.matches(item.value, context)) { + qDebug() << "INAME : " << item.iname; + qDebug() << "VALUE ACTUAL : " << item.value << toHex(item.value); + qDebug() << "VALUE EXPECTED: " + << check.expectedValue.value << toHex(check.expectedValue.value); + ok = false; + } + if (!check.expectedType.matches(item.type, context)) { + qDebug() << "INAME : " << item.iname; + qDebug() << "TYPE ACTUAL : " << item.type; + qDebug() << "TYPE EXPECTED: " << check.expectedType.type; + ok = false; + } + } else { + qDebug() << "SKIPPING NON-MATCHING TEST FOR " << item.iname; + } } } } @@ -2190,7 +2232,7 @@ void tst_Dumpers::dumper_data() "QString dummy;\n" "QPoint s0, s;\n" "s = QPoint(100, 200);\n" - "unused(&s0, &s);\n") + "unused(&s0, &s, &dummy);\n") % CoreProfile() % Check("s0", "(0, 0)", "@QPoint") % Check("s", "(100, 200)", "@QPoint"); @@ -2200,7 +2242,8 @@ void tst_Dumpers::dumper_data() "#include // Dummy for namespace\n", "QString dummy;\n" "QPointF s0, s;\n" - "s = QPointF(100.5, 200.5);\n") + "s = QPointF(100.5, 200.5);\n" + "unused(&s0, &s, &dummy);\n") % CoreProfile() % Check("s0", "(0.0, 0.0)", "@QPointF") % Check("s", "(100.5, 200.5)", "@QPointF"); @@ -2210,8 +2253,9 @@ void tst_Dumpers::dumper_data() "#include // Dummy for namespace\n", "QString dummy;\n" "QRect rect0, rect;\n" - "rect = QRect(100, 100, 200, 200);\n") - % Check("rect", "0x0+0+0", "@QRect") + "rect = QRect(100, 100, 200, 200);\n" + "unused(&rect0, &rect, &dummy);\n") + % Check("rect0", "0x0+0+0", "@QRect") % Check("rect", "200x200+100+100", "@QRect"); QTest::newRow("QRectF") @@ -2219,8 +2263,9 @@ void tst_Dumpers::dumper_data() "#include // Dummy for namespace\n", "QString dummy;\n" "QRectF rect0, rect;\n" - "rect = QRectF(100.25, 100.25, 200.5, 200.5);\n") - % Check("rect", "0x0+0+0", "@QRectF") + "rect = QRectF(100.25, 100.25, 200.5, 200.5);\n" + "unused(&rect0, &rect, &dummy);\n") + % Check("rect0", "0.0x0.0+0.0+0.0", "@QRectF") % Check("rect", "200.5x200.5+100.25+100.25", "@QRectF"); QTest::newRow("QSize") @@ -2228,7 +2273,8 @@ void tst_Dumpers::dumper_data() "#include // Dummy for namespace\n", "QString dummy;\n" "QSize s0, s;\n" - "s = QSize(100, 200);\n") + "s = QSize(100, 200);\n" + "unused(&s0, &s, &dummy);\n") % CoreProfile() % Check("s0", "(-1, -1)", "@QSize") % Check("s", "(100, 200)", "@QSize"); @@ -2238,7 +2284,8 @@ void tst_Dumpers::dumper_data() "#include // Dummy for namespace\n", "QString dummy;\n" "QSizeF s0, s;\n" - "s = QSizeF(100.5, 200.5);\n") + "s = QSizeF(100.5, 200.5);\n" + "unused(&s0, &s, &dummy);\n") % CoreProfile() % Check("s0", "(-1.0, -1.0)", "@QSizeF") % Check("s", "(100.5, 200.5)", "@QSizeF"); @@ -2474,27 +2521,17 @@ void tst_Dumpers::dumper_data() % Check("c", "(1.000000, 2.000000)", "std::complex") % CheckType("c.real", "double"); - QTest::newRow("CComplexGdb") + QTest::newRow("CComplex") << Data("#include \n", "// Doesn't work when compiled as C++.\n" "double complex a = 0;\n" "double _Complex b = 0;\n" "unused(&a, &b);\n") % ForceC() - % GdbOnly() - % Check("a", "0 + 0 * I", "complex double") - % Check("b", "0 + 0 * I", "complex double"); - - QTest::newRow("CComplexLldb") - << Data("#include \n", - "// Doesn't work when compiled as C++.\n" - "double complex a = 0;\n" - "double _Complex b = 0;\n" - "unused(&a, &b);\n") - % ForceC() - % LldbOnly() - % Check("a", "0 + 0i", "_Complex double") - % Check("b", "0 + 0i", "_Complex double"); + % Check("a", "0 + 0 * I", "complex double").setForGdbOnly() + % Check("b", "0 + 0 * I", "complex double").setForGdbOnly() + % Check("a", "0 + 0i", "_Complex double").setForLldbOnly() + % Check("b", "0 + 0i", "_Complex double").setForLldbOnly(); QTest::newRow("StdDequeInt") << Data("#include \n", @@ -3974,7 +4011,7 @@ void tst_Dumpers::dumper_data() % Check("foo.9", "[9]", "", "Foo"); - QTest::newRow("BitfieldsGdb") + QTest::newRow("Bitfields") << Data("struct S\n" "{\n" " S() : x(0), y(0), c(0), b(0), f(0), d(0), i(0) {}\n" @@ -3987,38 +4024,17 @@ void tst_Dumpers::dumper_data() " int i;\n" "} s;\n" "unused(&s);\n") - % GdbOnly() % Check("s", "", "S") % Check("s.b", "false", "bool") - % Check("s.c", "false", "bool") + % Check("s.c", "false", "bool:1").setForLldbOnly() + % Check("s.c", "false", "bool").setForGdbOnly() % Check("s.d", "0", "double") % Check("s.f", "0", "float") % Check("s.i", "0", "int") - % Check("s.x", "0", "unsigned int") - % Check("s.y", "0", "unsigned int"); - - QTest::newRow("BitfieldsLldb") - << Data("struct S\n" - "{\n" - " S() : x(0), y(0), c(0), b(0), f(0), d(0), i(0) {}\n" - " unsigned int x : 1;\n" - " unsigned int y : 1;\n" - " bool c : 1;\n" - " bool b;\n" - " float f;\n" - " double d;\n" - " int i;\n" - "} s;\n" - "unused(&s);\n") - % LldbOnly() - % Check("s", "", "S") - % Check("s.b", "false", "bool") - % Check("s.c", "false", "bool:1") - % Check("s.d", "0", "double") - % Check("s.f", "0", "float") - % Check("s.i", "0", "int") - % Check("s.x", "0", "unsigned int:1") - % Check("s.y", "0", "unsigned int:1"); + % Check("s.x", "0", "unsigned int:1").setForLldbOnly() + % Check("s.x", "0", "unsigned int").setForGdbOnly() + % Check("s.y", "0", "unsigned int:1").setForLldbOnly() + % Check("s.y", "0", "unsigned int").setForGdbOnly(); QTest::newRow("Function") @@ -4036,14 +4052,9 @@ void tst_Dumpers::dumper_data() "Function func(\"x\", \"sin(x)\", 0, 1);\n" "func.max = 10;\n" "func.f = \"cos(x)\";\n" - "func.max = 4;\n" - "func.max = 5;\n" - "func.max = 6;\n" "func.max = 7;\n") % CoreProfile() % Check("func", "", "Function") - % Check("func.f", "sin(x)", "@QByteArray") - % Check("func.max", "1", "double") % Check("func.min", "0", "double") % Check("func.var", "\"x\"", "@QByteArray") % Check("func", "", "Function") From 76879bea289ed30fc04fcc43c457b9477552d0ed Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 25 Oct 2013 16:21:03 +0200 Subject: [PATCH 61/84] Debugger: Merge RValueReference{Gdb,Lldb} auto tests The GDB case is still wrong, but it the data GDB produces. Change-Id: I97c656a666b98da2f62b354b5d1c699301d67b23 Reviewed-by: hjk --- tests/auto/debugger/tst_dumpers.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 4c7965e3918..306458615f2 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -4336,19 +4336,14 @@ void tst_Dumpers::dumper_data() % Check("y2", "", "X") % Check("y3", "", "X"); - QTest::newRow("RValueReferenceGdb") + QTest::newRow("RValueReference") << Data(rvalueData) - % GdbOnly() - % Check("x1", "", "X &") - % Check("x2", "", "X &") - % Check("x3", "", "X &"); - - QTest::newRow("RValueReferenceLldb") - << Data(rvalueData) - % LldbOnly() - % Check("x1", "", "X &&") - % Check("x2", "", "X &&") - % Check("x3", "", "X &&"); + % Check("x1", "", "X &").setForGdbOnly() + % Check("x2", "", "X &").setForGdbOnly() + % Check("x3", "", "X &").setForGdbOnly() + % Check("x1", "", "X &&").setForLldbOnly() + % Check("x2", "", "X &&").setForLldbOnly() + % Check("x3", "", "X &&").setForLldbOnly(); QTest::newRow("SSE") << Data("#include \n" From 3d69918835e48f8d20ebbc9faa2912a0058212d4 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 25 Oct 2013 16:29:35 +0200 Subject: [PATCH 62/84] Debugger: Remove some GdbOnly test case markers The tests pass now uniformly. Change-Id: I45c656a666b98da2f62b354b5d1c699301d67b23 Reviewed-by: hjk --- tests/auto/debugger/tst_dumpers.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 306458615f2..7c4bee670ea 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -3433,8 +3433,6 @@ void tst_Dumpers::dumper_data() "value = QVariant(t, (void*)0);\n" "*(QString*)value.data() = QString(\"Some string\");\n") % CoreProfile() - % GdbOnly() - % Check("t", "@QVariant::String (10)", "@QVariant::Type") % Check("value", "\"Some string\"", "@QVariant (QString)"); QTest::newRow("QVariant1") @@ -3642,7 +3640,6 @@ void tst_Dumpers::dumper_data() "QVariant v = h;\n" "unused(&v);\n") % CoreProfile() - % GdbOnly() % Check("v", "<1 items>", "@QVariant (QVariantHash)") % Check("v.0", "[0]", "", "@QHashNode<@QString, @QVariant>") % Check("v.0.key", "\"one\"", "@QString") @@ -3655,7 +3652,6 @@ void tst_Dumpers::dumper_data() "QVariant v = h;\n" "unused(&v);\n") % CoreProfile() - % GdbOnly() % Check("v", "<1 items>", "@QVariant (QVariantMap)") % Check("v.0", "[0]", "", "@QMapNode<@QString, @QVariant>") % Check("v.0.key", "\"one\"", "@QString") @@ -3668,7 +3664,6 @@ void tst_Dumpers::dumper_data() "QVariant v = h;\n" "unused(&v);\n") % CoreProfile() - % GdbOnly() % Check("v", "<1 items>", "@QVariant (QVariantList)") % Check("v.0", "[0]", "\"one\"", "@QVariant (QString)"); From 4b8a1bc7e0370a19385c9542b2982d00a2a3fa68 Mon Sep 17 00:00:00 2001 From: Frantisek Vacek Date: Wed, 16 Oct 2013 17:04:34 +0200 Subject: [PATCH 63/84] 'make deployqt' fixed when non system Qt are used for QTC build Change-Id: I2904abcc540b4c9058bd8ba51b281e09b8b208e7 Reviewed-by: Oswald Buddenhagen Reviewed-by: Eike Ziller --- qtcreator.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qtcreator.pro b/qtcreator.pro index f2b368b8ce6..7271ab940c4 100644 --- a/qtcreator.pro +++ b/qtcreator.pro @@ -74,7 +74,7 @@ macx { } else { BINDIST_SOURCE = "$(INSTALL_ROOT)$$QTC_PREFIX" BINDIST_INSTALLER_SOURCE = "$$BINDIST_SOURCE/*" - deployqt.commands = python -u $$PWD/scripts/deployqt.py -i \"$(INSTALL_ROOT)$$QTC_PREFIX\" + deployqt.commands = python -u $$PWD/scripts/deployqt.py -i \"$(INSTALL_ROOT)$$QTC_PREFIX\" \"$(QMAKE)\" deployqt.depends = install win32 { deployartifacts.depends = install From bccc352bd719a6e9f6195087887ed097c88c14ee Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Fri, 25 Oct 2013 16:06:08 +0200 Subject: [PATCH 64/84] Squish: Update tst_git_clone Change-Id: I96eb7e951a98ecd1108d99ce08276dc7422027f5 Reviewed-by: Christian Stenger --- tests/system/suite_tools/tst_git_clone/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/suite_tools/tst_git_clone/test.py b/tests/system/suite_tools/tst_git_clone/test.py index 0bc5400bc09..6ccbfb760b4 100644 --- a/tests/system/suite_tools/tst_git_clone/test.py +++ b/tests/system/suite_tools/tst_git_clone/test.py @@ -79,7 +79,7 @@ def main(): replaceEditorContent(cloneDirEdit, cloneDir) clickButton(waitForObject(":Next_QPushButton")) test.compare(waitForObject(":Git Repository Clone.Result._QLabel").text, - "Checkout started...") + "Cloning started...") if button == "Cancel immediately": clickButton(":Git Repository Clone.Cancel_QPushButton") verifyCloneLog(targetDir, True) From c6faedf1c709f07cc52a2e1c8514a3702bd0c36a Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Sun, 27 Oct 2013 10:47:46 +0100 Subject: [PATCH 65/84] debugger: generalize is32bit() through ptrSize() That also makes lldb dumper actually test for bitness instead of assuming 64bit Change-Id: I6207bac04817e1f4700247dc00d2dfdace1e5100 Reviewed-by: hjk --- share/qtcreator/debugger/dumper.py | 3 +++ share/qtcreator/debugger/gdbbridge.py | 3 --- share/qtcreator/debugger/lldbbridge.py | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index cf37f4f965f..a0b1028ff47 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -261,6 +261,9 @@ class DumperBase: self.isGdb = False self.isLldb = False + def is32bit(self): + return self.ptrSize() == 4 + def computeLimit(self, size, limit): if limit is None: return size diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index 2d0df4275a4..ae096c907bb 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -1230,9 +1230,6 @@ class Dumper(DumperBase): def ptrSize(self): return self.lookupType('void*').sizeof - def is32bit(self): - return self.lookupType('void*').sizeof == 4 - def createValue(self, address, referencedType): try: return gdb.Value(address).cast(referencedType.pointer()).dereference() diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 4a465c981f7..c347c4ea096 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -494,9 +494,6 @@ class Dumper(DumperBase): break return qqVersion - def is32bit(self): - return False - def intSize(self): return 4 From bcfec55942e1479d60e6d376ac0b01c1db33e980 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 25 Oct 2013 17:11:14 +0200 Subject: [PATCH 66/84] Debugger: Add LLDB version for some GDB specific tests Change-Id: I9a3547396384fe5b421c4b601b52476a23cdfa89 Reviewed-by: hjk --- tests/auto/debugger/tst_dumpers.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 7c4bee670ea..2e6e1b3ed25 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -4892,6 +4892,7 @@ void tst_Dumpers::dumper_data() "int sharedPtr = 1;\n" "#endif\n" "unused(&ptrConst, &ref, &refConst, &ptrToPtr, &sharedPtr);\n") + % GdbOnly() % GdbVersion(70500) % BoostProfile() % Check("d", "", "Derived") @@ -4924,19 +4925,31 @@ void tst_Dumpers::dumper_data() // on -var-list-children on an anonymous union. mac/MI was fixed in 2006"); // The proposed fix has been reported to crash gdb steered from eclipse"); // http://sourceware.org/ml/gdb-patches/2011-12/msg00420.html - QTest::newRow("gdb10586mi") + QTest::newRow("gdb10586miGdb") << Data("struct Test {\n" " struct { int a; float b; };\n" " struct { int c; float d; };\n" "} v = {{1, 2}, {3, 4}};\n" "unused(&v);\n") + % GdbOnly() % Check("v", "", "Test") % Check("v.a", "1", "int"); - QTest::newRow("gdb10586eclipse") + QTest::newRow("gdb10586miLldb") + << Data("struct Test {\n" + " struct { int a; float b; };\n" + " struct { int c; float d; };\n" + "} v = {{1, 2}, {3, 4}};\n" + "unused(&v);\n") + % LldbOnly() + % Check("v", "", "Test") + % Check("v.#1.a", "1", "int"); + + QTest::newRow("gdb10586eclipseGdb") << Data("struct { int x; struct { int a; }; struct { int b; }; } v = {1, {2}, {3}};\n" "struct S { int x, y; } n = {10, 20};\n" "unused(&v, &n);\n") + % GdbOnly() % Check("v", "", "{...}") % Check("n", "", "S") % Check("v.a", "2", "int") @@ -4945,6 +4958,18 @@ void tst_Dumpers::dumper_data() % Check("n.x", "10", "int") % Check("n.y", "20", "int"); + QTest::newRow("gdb10586eclipseLldb") + << Data("struct { int x; struct { int a; }; struct { int b; }; } v = {1, {2}, {3}};\n" + "struct S { int x, y; } n = {10, 20};\n" + "unused(&v, &n);\n") + % LldbOnly() + % Check("v", "", "") + % Check("n", "", "S") + % Check("v.#1.a", "2", "int") + % Check("v.#2.b", "3", "int") + % Check("v.x", "1", "int") + % Check("n.x", "10", "int") + % Check("n.y", "20", "int"); QTest::newRow("stdint") << Data("#include \n", From 1ca3da6117118b72c59b7b71765b1a4829ba774b Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 28 Oct 2013 12:09:49 +0100 Subject: [PATCH 67/84] Dumpers: Fix dumper for QVariant holding QList for old GDB Change-Id: Id34806f06546ad9a6618f9b9431143465a988c1d Reviewed-by: hjk --- share/qtcreator/debugger/qttypes.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index f961fe4af57..318250e07e4 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -1898,8 +1898,12 @@ def qdump__QVariant(d, value): # User types. d_ptr = value["d"] typeCode = int(d_ptr["type"]) - exp = "((const char *(*)(int))%sQMetaType::typeName)(%d)" % (d.ns, typeCode) - type = str(d.parseAndEvaluate(exp)) + try: + exp = "((const char *(*)(int))%sQMetaType::typeName)(%d)" % (d.ns, typeCode) + type = str(d.parseAndEvaluate(exp)) + except: + exp = "%sQMetaType::typeName(%d)" % (d.ns, typeCode) + type = str(d.parseAndEvaluate(exp)) type = type[type.find('"') + 1 : type.rfind('"')] type = type.replace("Q", d.ns + "Q") # HACK! type = type.replace("uint", "unsigned int") # HACK! From a3c4fe1ff2d3231b1d4ded599241c11ec8acde59 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 28 Oct 2013 10:14:59 +0100 Subject: [PATCH 68/84] dumpers: Fix QHash dumper for Qt4 In Qt4 (u)int hashs are optimized and the key is inside an anonymous union, so, at least with LLDB, we cannot reference "key" directly as a child of the QHashNode Change-Id: Id7cac3d08fa85af599f2b2564a6b1f11b465c7b2 Reviewed-by: hjk --- share/qtcreator/debugger/qttypes.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 318250e07e4..1d18f8945cc 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -527,7 +527,10 @@ def qdump__QHash(d, value): it = nodePtr.dereference().cast(innerType) with SubItem(d, i): if isCompact: - d.putMapName(it["key"]) + # cannot reference "key" directly because it is inside + # anonymous union for (u)int key in Qt4 + keyAddress = d.addressOf(it) + d.ptrSize() # addr + QHashNode* + d.putMapName(d.createValue(keyAddress, keyType)) d.putItem(it["value"]) d.putType(valueType) else: From 8ab88c8d35c52078a03d2d2192756906709f9aff Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed Date: Mon, 28 Oct 2013 08:14:18 +0100 Subject: [PATCH 69/84] ios: actually open help when detecting non setup device Change-Id: I72d8c853c01a62d4e62ab0db382e9144f6f03fd6 Reviewed-by: Leena Miettinen Reviewed-by: Fawzi Mohamed --- src/plugins/ios/iosdevice.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/ios/iosdevice.cpp b/src/plugins/ios/iosdevice.cpp index d258d34991d..524eff47281 100644 --- a/src/plugins/ios/iosdevice.cpp +++ b/src/plugins/ios/iosdevice.cpp @@ -33,6 +33,7 @@ #include "iostoolhandler.h" #include #include +#include #include #include @@ -318,11 +319,12 @@ void IosDeviceManager::deviceInfo(IosToolHandler *, const QString &uid, mBox.setText(tr("An iOS device in user mode has been detected.")); mBox.setInformativeText(tr("Do you want to see how to set it up for development?")); mBox.setStandardButtons(QMessageBox::NoAll | QMessageBox::No | QMessageBox::Yes); - mBox.setDefaultButton(QMessageBox::No); + mBox.setDefaultButton(QMessageBox::Yes); int ret = mBox.exec(); switch (ret) { case QMessageBox::Yes: - // open doc + Core::HelpManager::handleHelpRequest( + QLatin1String("qthelp://org.qt-project.qtcreator/doc/creator-developing-ios.html")); break; case QMessageBox::No: newDev->m_ignoreDevice = true; From c726f3c47ed3b0cc8d882919a29a620767347604 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 28 Oct 2013 12:07:51 +0100 Subject: [PATCH 70/84] Dumpers: Fix standard types (C++11) for old gcc Change-Id: Ic208a45f6d0c7419d83dccd78b552c734421c953 Reviewed-by: hjk --- share/qtcreator/debugger/stdtypes.py | 51 +++++++++++++++++++++------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py index 4ca65badb0f..c29cbfed11a 100644 --- a/share/qtcreator/debugger/stdtypes.py +++ b/share/qtcreator/debugger/stdtypes.py @@ -442,21 +442,36 @@ def qform__std____debug__unordered_map(): return mapForms() def qdump__std__unordered_map(d, value): + keyType = d.templateArgument(value.type, 0) + valueType = d.templateArgument(value.type, 1) + allocatorType = d.templateArgument(value.type, 4) + pairType = d.templateArgument(allocatorType, 0) + ptrSize = d.ptrSize() try: + # gcc >= 4.7 size = value["_M_element_count"] start = value["_M_before_begin"]["_M_nxt"] + offset = 0 except: - size = value["_M_h"]["_M_element_count"] - start = value["_M_h"]["_M_bbegin"]["_M_node"]["_M_nxt"] + try: + # libc++ (Mac) + size = value["_M_h"]["_M_element_count"] + start = value["_M_h"]["_M_bbegin"]["_M_node"]["_M_nxt"] + offset = 0 + except: + # gcc 4.6.2 + size = value["_M_element_count"] + start = value["_M_buckets"].dereference() + # FIXME: Pointer-aligned? + offset = pairType.sizeof + d.putItemCount(size) + # We don't know where the data is + d.putNumChild(0) + return d.putItemCount(size) d.putNumChild(size) if d.isExpanded(): p = d.pointerValue(start) - keyType = d.templateArgument(value.type, 0) - valueType = d.templateArgument(value.type, 1) - allocatorType = d.templateArgument(value.type, 4) - pairType = d.templateArgument(allocatorType, 0) - ptrSize = d.ptrSize() if d.isMapCompact(keyType, valueType): with Children(d, size, childType=valueType): for i in d.childRange(): @@ -469,19 +484,29 @@ def qdump__std__unordered_map(d, value): else: with Children(d, size, childType=pairType): for i in d.childRange(): - d.putSubItem(i, d.createValue(p + ptrSize, pairType)) - p = d.dereference(p) + d.putSubItem(i, d.createValue(p + ptrSize - offset, pairType)) + p = d.dereference(p + offset) def qdump__std____debug__unordered_map(d, value): qdump__std__unordered_map(d, value) def qdump__std__unordered_set(d, value): try: + # gcc >= 4.7 size = value["_M_element_count"] start = value["_M_before_begin"]["_M_nxt"] + offset = 0 except: - size = value["_M_h"]["_M_element_count"] - start = value["_M_h"]["_M_bbegin"]["_M_node"]["_M_nxt"] + try: + # libc++ (Mac) + size = value["_M_h"]["_M_element_count"] + start = value["_M_h"]["_M_bbegin"]["_M_node"]["_M_nxt"] + offset = 0 + except: + # gcc 4.6.2 + size = value["_M_element_count"] + start = value["_M_buckets"].dereference() + offset = d.ptrSize() d.putItemCount(size) d.putNumChild(size) if d.isExpanded(): @@ -490,8 +515,8 @@ def qdump__std__unordered_set(d, value): with Children(d, size, childType=valueType): ptrSize = d.ptrSize() for i in d.childRange(): - d.putSubItem(i, d.createValue(p + ptrSize, valueType)) - p = d.dereference(p) + d.putSubItem(i, d.createValue(p + ptrSize - offset, valueType)) + p = d.dereference(p + offset) def qform__std____1__unordered_map(): return mapForms() From 48007785b0d4ace2463d1ca2f82ef42f7bbdb980 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Sun, 27 Oct 2013 10:48:10 +0100 Subject: [PATCH 71/84] debugger: Fix Qt4 QFile dumper Change-Id: Ifd2caaef4d0c286f2855175acb2dc1b835213c37 Reviewed-by: hjk --- share/qtcreator/debugger/qttypes.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 1d18f8945cc..09225f91e48 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -329,9 +329,10 @@ def qdump__QFile(d, value): fileNameAddress = d.addressOf(d_ptr.cast(ptype).dereference()["fileName"]) d.putNumChild(1) except: - # 176 and 280 are best guesses for Qt 5 - offset = 176 if d.is32bit() else 280 - #qt5 = d.qtVersion() >= 0x050000 + if d.qtVersion() >= 0x050000: + offset = 176 if d.is32bit() else 280 + else: + offset = 140 if d.is32bit() else 232 privAddress = d.dereference(d.addressOf(value) + d.ptrSize()) fileNameAddress = privAddress + offset d.putNumChild(0) From 7ba935c44b38a16290ef96e6475a09b4be77a468 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Sat, 26 Oct 2013 19:56:50 +0200 Subject: [PATCH 72/84] debugger: Fix QDir dumper for Qt4 64bit Also make the structure more self-explained Change-Id: Ia5080f4e07e2a8b7c6b18e1353a4cf1cf3488361 Reviewed-by: hjk --- share/qtcreator/debugger/qttypes.py | 51 ++++++++++++++++++----------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 09225f91e48..e28df11ea31 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -289,36 +289,49 @@ def qdump__QDir(d, value): privAddress = d.dereferenceValue(value) bit32 = d.is32bit() qt5 = d.qtVersion() >= 0x050000 - # value.d_ptr.d.dirEntry.m_filePath - value.d_ptr.d - offset = (32 if bit32 else 56) if qt5 else 36 - filePathAddress = privAddress + offset - #try: - # # Up to Qt 4.7 - # d.putStringValue(data["path"]) - #except: - # # Qt 4.8 and later. - # d.putStringValue(data["dirEntry"]["m_filePath"]) - d.putStringValueByAddress(filePathAddress) + # QDirPrivate: + # QAtomicInt ref + # QStringList nameFilters; + # QDir::SortFlags sort; + # QDir::Filters filters; + # // qt3support: + # QChar filterSepChar; + # bool matchAllDirs; + # // end qt3support + # QScopedPointer fileEngine; + # bool fileListsInitialized; + # QStringList files; + # QFileInfoList fileInfos; + # QFileSystemEntry dirEntry; + # QFileSystemEntry absoluteDirEntry; + qt3SupportAddition = 0 if qt5 else d.ptrSize() # qt5 doesn't have qt3support + filesOffset = (24 if bit32 else 40) + qt3SupportAddition + fileInfosOffset = filesOffset + d.ptrSize() + dirEntryOffset = fileInfosOffset + d.ptrSize() + # QFileSystemEntry: + # QString m_filePath + # QByteArray m_nativeFilePath + # qint16 m_lastSeparator + # qint16 m_firstDotInFileName + # qint16 m_lastDotInFileName + # + 2 byte padding + fileSystemEntrySize = 2 * d.ptrSize() + 8 + absoluteDirEntryOffset = dirEntryOffset + fileSystemEntrySize + d.putStringValueByAddress(privAddress + dirEntryOffset) if d.isExpanded(): with Children(d): d.call(value, "count") # Fill cache. #d.putCallItem("absolutePath", value, "absolutePath") #d.putCallItem("canonicalPath", value, "canonicalPath") with SubItem(d, "absolutePath"): - # value.d_ptr.d.absoluteDirEntry.m_filePath - value.d_ptr.d - offset = (48 if bit32 else 80) if qt5 else 36 typ = d.lookupType(d.ns + "QString") - d.putItem(d.createValue(privAddress + offset, typ)) + d.putItem(d.createValue(privAddress + absoluteDirEntryOffset, typ)) with SubItem(d, "entryInfoList"): - # value.d_ptr.d.fileInfos - value.d_ptr.d - offset = (28 if bit32 else 48) if qt5 else 32 typ = d.lookupType(d.ns + "QList<" + d.ns + "QFileInfo>") - d.putItem(d.createValue(privAddress + offset, typ)) + d.putItem(d.createValue(privAddress + fileInfosOffset, typ)) with SubItem(d, "entryList"): - # d.ptr.d.files - value.d_ptr.d - offset = (24 if bit32 else 40) if qt5 else 28 typ = d.lookupType(d.ns + "QStringList") - d.putItem(d.createValue(privAddress + offset, typ)) + d.putItem(d.createValue(privAddress + filesOffset, typ)) def qdump__QFile(d, value): From 7af8af01365255f8bc3efdaaf70ddce9da6ee540 Mon Sep 17 00:00:00 2001 From: hluk Date: Fri, 25 Oct 2013 18:25:59 +0200 Subject: [PATCH 73/84] FakeVim: Use current text cursor to find out line geometry Change-Id: If4581d2f38db8311138b871b67fdbe164dde1688 Reviewed-by: hjk --- src/plugins/fakevim/fakevimhandler.cpp | 27 ++++++++++---------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index a2fa1f83093..5caa0df6dd9 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -1576,7 +1576,6 @@ public: QTextBlock previousLine(const QTextBlock &block) const; // previous line (respects wrapped parts) int linesOnScreen() const; - int columnsOnScreen() const; int linesInDocument() const; // The following use all zero-based counting. @@ -3673,9 +3672,12 @@ bool FakeVimHandler::Private::handleMovement(const Input &input) setCursorPosition(&m_cursor, pos); handleStartOfLine(); } else if (g.gflag && input.is('m')) { - moveToStartOfLine(); - moveRight(qMin(columnsOnScreen() / 2, rightDist()) - 1); - setTargetColumn(); + const QPoint pos(EDITOR(viewport()->width()) / 2, EDITOR(cursorRect(m_cursor)).y()); + QTextCursor tc = EDITOR(cursorForPosition(pos)); + if (!tc.isNull()) { + m_cursor = tc; + setTargetColumn(); + } } else if (input.is('M')) { m_cursor = EDITOR(cursorForPosition(QPoint(0, EDITOR(height()) / 2))); handleStartOfLine(); @@ -6369,25 +6371,16 @@ int FakeVimHandler::Private::cursorLineOnScreen() const { if (!editor()) return 0; - QRect rect = EDITOR(cursorRect()); - return rect.y() / rect.height(); + const QRect rect = EDITOR(cursorRect(m_cursor)); + return rect.height() > 0 ? rect.y() / rect.height() : 0; } int FakeVimHandler::Private::linesOnScreen() const { if (!editor()) return 1; - QRect rect = EDITOR(cursorRect()); - return EDITOR(viewport()->height()) / rect.height(); -} - -int FakeVimHandler::Private::columnsOnScreen() const -{ - if (!editor()) - return 1; - QRect rect = EDITOR(cursorRect()); - // qDebug() << "WID: " << EDITOR(width()) << "RECT: " << rect; - return EDITOR(viewport()->width()) / rect.width(); + const int h = EDITOR(cursorRect(m_cursor)).height(); + return h > 0 ? EDITOR(viewport()->height()) / h : 1; } int FakeVimHandler::Private::cursorLine() const From 3a24b2d33239a4666b40c4f54e497f31e283e769 Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed Date: Wed, 23 Oct 2013 13:19:09 +0200 Subject: [PATCH 74/84] utils/function: expose also ref and cref ref and cref are also in tr1, and in functional, and are useful when when using functors allocated on the stack that should not be copied. Change-Id: I7e14560d88eaa9306e47c4bd71d011f406d1054a Reviewed-by: hjk --- src/libs/utils/function.cpp | 12 +++++++++++- src/libs/utils/function.h | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/libs/utils/function.cpp b/src/libs/utils/function.cpp index 68370976d87..45f02f776df 100644 --- a/src/libs/utils/function.cpp +++ b/src/libs/utils/function.cpp @@ -41,7 +41,7 @@ void functionUser(Utils::function generator, Utils::function c struct GenFunctor { - int operator()() { return 29; } + int operator()() const { return 29; } }; struct ConsumerFunctor @@ -49,6 +49,13 @@ struct ConsumerFunctor void operator()(int) {} }; +struct ConsumerFunctor2 +{ + ConsumerFunctor2() : i(0) { } + int i; + void operator()(int j) { i = j; } +}; + int generatorF() { return 42; @@ -64,6 +71,9 @@ void test() { functionUser(GenFunctor(), ConsumerFunctor()); functionUser(&generatorF, &consumerF); + ConsumerFunctor2 f2; + GenFunctor g2; + functionUser(Utils::cref(g2), Utils::ref(f2)); } } // end namespace diff --git a/src/libs/utils/function.h b/src/libs/utils/function.h index d6dbc2f9999..52938f385e4 100644 --- a/src/libs/utils/function.h +++ b/src/libs/utils/function.h @@ -39,9 +39,9 @@ # ifdef __GNUC__ # include # endif -namespace Utils { using std::tr1::function; } +namespace Utils { using std::tr1::function; using std::tr1::ref; using std::tr1::cref; } #else -namespace Utils { using std::function; } +namespace Utils { using std::function; using std::ref; using std::cref; } #endif #endif // QTC_FUNCTION_H From ab8999832a7ce3dbb5bd6d4a7e9b6c5bc1f322c2 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 25 Oct 2013 13:47:08 +0200 Subject: [PATCH 75/84] Debugger: Move classes into their own files Change-Id: I89853ffb4192b0da1f34d471e250d4ec32daa3da Reviewed-by: hjk --- src/plugins/android/androidconfigurations.cpp | 1 + src/plugins/debugger/debugger.pro | 8 + src/plugins/debugger/debugger.qbs | 4 + src/plugins/debugger/debuggeritem.cpp | 337 +++++ src/plugins/debugger/debuggeritem.h | 96 ++ src/plugins/debugger/debuggeritemmanager.cpp | 408 ++++++ src/plugins/debugger/debuggeritemmanager.h | 92 ++ src/plugins/debugger/debuggeritemmodel.cpp | 198 +++ src/plugins/debugger/debuggeritemmodel.h | 90 ++ .../debugger/debuggerkitconfigwidget.cpp | 1095 +---------------- .../debugger/debuggerkitconfigwidget.h | 85 +- .../debugger/debuggerkitinformation.cpp | 486 ++++---- src/plugins/debugger/debuggerkitinformation.h | 97 +- src/plugins/debugger/debuggeroptionspage.cpp | 350 ++++++ src/plugins/debugger/debuggeroptionspage.h | 90 ++ src/plugins/debugger/debuggerplugin.cpp | 2 + src/plugins/ios/iosconfigurations.cpp | 1 + src/plugins/qnx/blackberryconfiguration.cpp | 1 + 18 files changed, 1924 insertions(+), 1517 deletions(-) create mode 100644 src/plugins/debugger/debuggeritem.cpp create mode 100644 src/plugins/debugger/debuggeritem.h create mode 100644 src/plugins/debugger/debuggeritemmanager.cpp create mode 100644 src/plugins/debugger/debuggeritemmanager.h create mode 100644 src/plugins/debugger/debuggeritemmodel.cpp create mode 100644 src/plugins/debugger/debuggeritemmodel.h create mode 100644 src/plugins/debugger/debuggeroptionspage.cpp create mode 100644 src/plugins/debugger/debuggeroptionspage.h diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 80d1c9451ab..ee39135f5d6 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro index ce31216535b..7798cf0bfe1 100644 --- a/src/plugins/debugger/debugger.pro +++ b/src/plugins/debugger/debugger.pro @@ -24,9 +24,13 @@ HEADERS += \ debuggercore.h \ debuggerconstants.h \ debuggerinternalconstants.h \ + debuggeritem.h \ + debuggeritemmanager.h \ + debuggeritemmodel.h \ debuggerdialogs.h \ debuggerengine.h \ debuggermainwindow.h \ + debuggeroptionspage.h \ debuggerplugin.h \ debuggerprotocol.h \ debuggerrunconfigurationaspect.h \ @@ -80,12 +84,16 @@ SOURCES += \ debuggeractions.cpp \ debuggerdialogs.cpp \ debuggerengine.cpp \ + debuggeritem.cpp \ + debuggeritemmanager.cpp \ + debuggeritemmodel.cpp \ debuggermainwindow.cpp \ debuggerplugin.cpp \ debuggerprotocol.cpp \ debuggerrunconfigurationaspect.cpp \ debuggerrunner.cpp \ debuggerstreamops.cpp \ + debuggeroptionspage.cpp \ debuggerkitconfigwidget.cpp \ debuggerkitinformation.cpp \ disassembleragent.cpp \ diff --git a/src/plugins/debugger/debugger.qbs b/src/plugins/debugger/debugger.qbs index 9032e846608..709dc128c3c 100644 --- a/src/plugins/debugger/debugger.qbs +++ b/src/plugins/debugger/debugger.qbs @@ -40,9 +40,13 @@ QtcPlugin { "debuggerdialogs.cpp", "debuggerdialogs.h", "debuggerengine.cpp", "debuggerengine.h", "debuggerinternalconstants.h", + "debuggeritem.cpp", "debuggeritem.h", + "debuggeritemmanager.cpp", "debuggeritemmanager.h", + "debuggeritemmodel.cpp", "debuggeritemmodel.h", "debuggerkitconfigwidget.cpp", "debuggerkitconfigwidget.h", "debuggerkitinformation.cpp", "debuggerkitinformation.h", "debuggermainwindow.cpp", "debuggermainwindow.h", + "debuggeroptionspage.cpp", "debuggeroptionspage.h", "debuggerplugin.cpp", "debuggerplugin.h", "debuggerprotocol.cpp", "debuggerprotocol.h", "debuggerruncontrolfactory.h", diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp new file mode 100644 index 00000000000..9ac30bbb7d4 --- /dev/null +++ b/src/plugins/debugger/debuggeritem.cpp @@ -0,0 +1,337 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "debuggerkitinformation.h" +#include "debuggerkitconfigwidget.h" +#include "debuggeroptionspage.h" + +#include +#include + +#include +#include + +using namespace Debugger::Internal; +using namespace ProjectExplorer; +using namespace Utils; + +static const char DEBUGGER_INFORMATION_COMMAND[] = "Binary"; +static const char DEBUGGER_INFORMATION_DISPLAYNAME[] = "DisplayName"; +static const char DEBUGGER_INFORMATION_ID[] = "Id"; +static const char DEBUGGER_INFORMATION_ENGINETYPE[] = "EngineType"; +static const char DEBUGGER_INFORMATION_AUTODETECTED[] = "AutoDetected"; +static const char DEBUGGER_INFORMATION_ABIS[] = "Abis"; + +namespace Debugger { + +// -------------------------------------------------------------------------- +// DebuggerItem +// -------------------------------------------------------------------------- + +DebuggerItem::DebuggerItem() +{ + m_id = QUuid::createUuid().toString(); + m_engineType = NoEngineType; + m_isAutoDetected = false; +} + +DebuggerItem::DebuggerItem(const QVariantMap &data) +{ + m_command = FileName::fromUserInput(data.value(QLatin1String(DEBUGGER_INFORMATION_COMMAND)).toString()); + m_id = data.value(QLatin1String(DEBUGGER_INFORMATION_ID)).toString(); + m_displayName = data.value(QLatin1String(DEBUGGER_INFORMATION_DISPLAYNAME)).toString(); + m_isAutoDetected = data.value(QLatin1String(DEBUGGER_INFORMATION_AUTODETECTED), false).toBool(); + m_engineType = DebuggerEngineType(data.value(QLatin1String(DEBUGGER_INFORMATION_ENGINETYPE), + static_cast(NoEngineType)).toInt()); + + foreach (const QString &a, data.value(QLatin1String(DEBUGGER_INFORMATION_ABIS)).toStringList()) { + Abi abi(a); + if (abi.isValid()) + m_abis.append(abi); + } +} + +void DebuggerItem::reinitializeFromFile() +{ + QProcess proc; + proc.start(m_command.toString(), QStringList() << QLatin1String("--version")); + proc.waitForStarted(); + proc.waitForFinished(); + QByteArray ba = proc.readAll(); + if (ba.contains("gdb")) { + m_engineType = GdbEngineType; + const char needle[] = "This GDB was configured as \""; + // E.g. "--host=i686-pc-linux-gnu --target=arm-unknown-nto-qnx6.5.0". + // or "i686-linux-gnu" + int pos1 = ba.indexOf(needle); + if (pos1 != -1) { + pos1 += int(sizeof(needle)); + int pos2 = ba.indexOf('"', pos1 + 1); + QByteArray target = ba.mid(pos1, pos2 - pos1); + int pos3 = target.indexOf("--target="); + if (pos3 >= 0) + target = target.mid(pos3 + 9); + m_abis.append(Abi::abiFromTargetTriplet(QString::fromLatin1(target))); + } else { + // Fallback. + m_abis = Abi::abisOfBinary(m_command); // FIXME: Wrong. + } + return; + } + if (ba.contains("lldb") || ba.startsWith("LLDB")) { + m_engineType = LldbEngineType; + m_abis = Abi::abisOfBinary(m_command); + return; + } + if (ba.startsWith("Python")) { + m_engineType = PdbEngineType; + return; + } + m_engineType = NoEngineType; +} + +QString DebuggerItem::engineTypeName() const +{ + switch (m_engineType) { + case Debugger::NoEngineType: + return DebuggerOptionsPage::tr("Not recognized"); + case Debugger::GdbEngineType: + return QLatin1String("GDB"); + case Debugger::CdbEngineType: + return QLatin1String("CDB"); + case Debugger::LldbEngineType: + return QLatin1String("LLDB"); + default: + return QString(); + } +} + +QStringList DebuggerItem::abiNames() const +{ + QStringList list; + foreach (const Abi &abi, m_abis) + list.append(abi.toString()); + return list; +} + +QVariantMap DebuggerItem::toMap() const +{ + QVariantMap data; + data.insert(QLatin1String(DEBUGGER_INFORMATION_DISPLAYNAME), m_displayName); + data.insert(QLatin1String(DEBUGGER_INFORMATION_ID), m_id); + data.insert(QLatin1String(DEBUGGER_INFORMATION_COMMAND), m_command.toUserOutput()); + data.insert(QLatin1String(DEBUGGER_INFORMATION_ENGINETYPE), int(m_engineType)); + data.insert(QLatin1String(DEBUGGER_INFORMATION_AUTODETECTED), m_isAutoDetected); + data.insert(QLatin1String(DEBUGGER_INFORMATION_ABIS), abiNames()); + return data; +} + +void DebuggerItem::setDisplayName(const QString &displayName) +{ + m_displayName = displayName; +} + +void DebuggerItem::setEngineType(const DebuggerEngineType &engineType) +{ + m_engineType = engineType; +} + +void DebuggerItem::setCommand(const Utils::FileName &command) +{ + m_command = command; +} + +void DebuggerItem::setAutoDetected(bool isAutoDetected) +{ + m_isAutoDetected = isAutoDetected; +} + +void DebuggerItem::setAbis(const QList &abis) +{ + m_abis = abis; +} + +void DebuggerItem::setAbi(const Abi &abi) +{ + m_abis.clear(); + m_abis.append(abi); +} + +static DebuggerItem::MatchLevel matchSingle(const Abi &debuggerAbi, const Abi &targetAbi) +{ + if (debuggerAbi.architecture() != Abi::UnknownArchitecture + && debuggerAbi.architecture() != targetAbi.architecture()) + return DebuggerItem::DoesNotMatch; + + if (debuggerAbi.os() != Abi::UnknownOS + && debuggerAbi.os() != targetAbi.os()) + return DebuggerItem::DoesNotMatch; + + if (debuggerAbi.binaryFormat() != Abi::UnknownFormat + && debuggerAbi.binaryFormat() != targetAbi.binaryFormat()) + return DebuggerItem::DoesNotMatch; + + if (debuggerAbi.os() == Abi::WindowsOS) { + if (debuggerAbi.osFlavor() == Abi::WindowsMSysFlavor && targetAbi.osFlavor() != Abi::WindowsMSysFlavor) + return DebuggerItem::DoesNotMatch; + if (debuggerAbi.osFlavor() != Abi::WindowsMSysFlavor && targetAbi.osFlavor() == Abi::WindowsMSysFlavor) + return DebuggerItem::DoesNotMatch; + } + + if (debuggerAbi.wordWidth() == 64 && targetAbi.wordWidth() == 32) + return DebuggerItem::MatchesSomewhat; + if (debuggerAbi.wordWidth() != 0 && debuggerAbi.wordWidth() != targetAbi.wordWidth()) + return DebuggerItem::DoesNotMatch; + + return DebuggerItem::MatchesPerfectly; +} + +DebuggerItem::MatchLevel DebuggerItem::matchTarget(const Abi &targetAbi) const +{ + MatchLevel bestMatch = DoesNotMatch; + foreach (const Abi &debuggerAbi, m_abis) { + MatchLevel currentMatch = matchSingle(debuggerAbi, targetAbi); + if (currentMatch > bestMatch) + bestMatch = currentMatch; + } + return bestMatch; +} + +bool Debugger::DebuggerItem::isValid() const +{ + return m_engineType != NoEngineType; +} + +} // namespace Debugger; + +#ifdef WITH_TESTS + +# include +# include "debuggerplugin.h" + +void Debugger::DebuggerPlugin::testDebuggerMatching_data() +{ + QTest::addColumn("debugger"); + QTest::addColumn("target"); + QTest::addColumn("result"); + + QTest::newRow("Invalid data") + << QStringList() + << QString() + << int(DebuggerItem::DoesNotMatch); + QTest::newRow("Invalid debugger") + << QStringList() + << QString::fromLatin1("x86-linux-generic-elf-32bit") + << int(DebuggerItem::DoesNotMatch); + QTest::newRow("Invalid target") + << (QStringList() << QLatin1String("x86-linux-generic-elf-32bit")) + << QString() + << int(DebuggerItem::DoesNotMatch); + + QTest::newRow("Fuzzy match 1") + << (QStringList() << QLatin1String("unknown-unknown-unknown-unknown-0bit")) + << QString::fromLatin1("x86-linux-generic-elf-32bit") + << int(DebuggerItem::MatchesPerfectly); // Is this the expected behavior? + QTest::newRow("Fuzzy match 2") + << (QStringList() << QLatin1String("unknown-unknown-unknown-unknown-0bit")) + << QString::fromLatin1("arm-windows-msys-pe-64bit") + << int(DebuggerItem::MatchesPerfectly); // Is this the expected behavior? + + QTest::newRow("Architecture mismatch") + << (QStringList() << QLatin1String("x86-linux-generic-elf-32bit")) + << QString::fromLatin1("arm-linux-generic-elf-32bit") + << int(DebuggerItem::DoesNotMatch); + QTest::newRow("OS mismatch") + << (QStringList() << QLatin1String("x86-linux-generic-elf-32bit")) + << QString::fromLatin1("x86-macosx-generic-elf-32bit") + << int(DebuggerItem::DoesNotMatch); + QTest::newRow("Format mismatch") + << (QStringList() << QLatin1String("x86-linux-generic-elf-32bit")) + << QString::fromLatin1("x86-linux-generic-pe-32bit") + << int(DebuggerItem::DoesNotMatch); + + QTest::newRow("Linux perfect match") + << (QStringList() << QLatin1String("x86-linux-generic-elf-32bit")) + << QString::fromLatin1("x86-linux-generic-elf-32bit") + << int(DebuggerItem::MatchesPerfectly); + QTest::newRow("Linux match") + << (QStringList() << QLatin1String("x86-linux-generic-elf-64bit")) + << QString::fromLatin1("x86-linux-generic-elf-32bit") + << int(DebuggerItem::MatchesSomewhat); + + QTest::newRow("Windows perfect match 1") + << (QStringList() << QLatin1String("x86-windows-msvc2013-pe-64bit")) + << QString::fromLatin1("x86-windows-msvc2013-pe-64bit") + << int(DebuggerItem::MatchesPerfectly); + QTest::newRow("Windows perfect match 2") + << (QStringList() << QLatin1String("x86-windows-msvc2013-pe-64bit")) + << QString::fromLatin1("x86-windows-msvc2012-pe-64bit") + << int(DebuggerItem::MatchesPerfectly); + QTest::newRow("Windows match 1") + << (QStringList() << QLatin1String("x86-windows-msvc2013-pe-64bit")) + << QString::fromLatin1("x86-windows-msvc2013-pe-32bit") + << int(DebuggerItem::MatchesSomewhat); + QTest::newRow("Windows match 2") + << (QStringList() << QLatin1String("x86-windows-msvc2013-pe-64bit")) + << QString::fromLatin1("x86-windows-msvc2012-pe-32bit") + << int(DebuggerItem::MatchesSomewhat); + QTest::newRow("Windows mismatch on word size") + << (QStringList() << QLatin1String("x86-windows-msvc2013-pe-32bit")) + << QString::fromLatin1("x86-windows-msvc2013-pe-64bit") + << int(DebuggerItem::DoesNotMatch); + QTest::newRow("Windows mismatch on osflavor 1") + << (QStringList() << QLatin1String("x86-windows-msvc2013-pe-32bit")) + << QString::fromLatin1("x86-windows-msys-pe-64bit") + << int(DebuggerItem::DoesNotMatch); + QTest::newRow("Windows mismatch on osflavor 2") + << (QStringList() << QLatin1String("x86-windows-msys-pe-32bit")) + << QString::fromLatin1("x86-windows-msvc2010-pe-64bit") + << int(DebuggerItem::DoesNotMatch); +} + +void Debugger::DebuggerPlugin::testDebuggerMatching() +{ + QFETCH(QStringList, debugger); + QFETCH(QString, target); + QFETCH(int, result); + + DebuggerItem::MatchLevel expectedLevel = static_cast(result); + + QList debuggerAbis; + foreach (const QString &abi, debugger) + debuggerAbis << Abi(abi); + + DebuggerItem item; + item.setAbis(debuggerAbis); + + DebuggerItem::MatchLevel level = item.matchTarget(Abi(target)); + + QCOMPARE(expectedLevel, level); +} +#endif diff --git a/src/plugins/debugger/debuggeritem.h b/src/plugins/debugger/debuggeritem.h new file mode 100644 index 00000000000..9809da22c7b --- /dev/null +++ b/src/plugins/debugger/debuggeritem.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef DEBUGGER_DEBUGGERITEM_H +#define DEBUGGER_DEBUGGERITEM_H + +#include "debugger_global.h" +#include "debuggerconstants.h" + +#include + +#include + +#include +#include + +namespace Debugger { + +// ----------------------------------------------------------------------- +// DebuggerItem +// ----------------------------------------------------------------------- + +class DEBUGGER_EXPORT DebuggerItem +{ +public: + DebuggerItem(); + DebuggerItem(const QVariantMap &data); + + bool canClone() const { return true; } + bool isValid() const; + QString engineTypeName() const; + + QVariantMap toMap() const; + void reinitializeFromFile(); + + QVariant id() const { return m_id; } + + QString displayName() const { return m_displayName; } + void setDisplayName(const QString &displayName); + + DebuggerEngineType engineType() const { return m_engineType; } + void setEngineType(const DebuggerEngineType &engineType); + + Utils::FileName command() const { return m_command; } + void setCommand(const Utils::FileName &command); + + bool isAutoDetected() const { return m_isAutoDetected; } + void setAutoDetected(bool isAutoDetected); + + QList abis() const { return m_abis; } + void setAbis(const QList &abis); + void setAbi(const ProjectExplorer::Abi &abi); + + enum MatchLevel { DoesNotMatch, MatchesSomewhat, MatchesPerfectly }; + MatchLevel matchTarget(const ProjectExplorer::Abi &targetAbi) const; + + QStringList abiNames() const; + +private: + QVariant m_id; + QString m_displayName; + DebuggerEngineType m_engineType; + Utils::FileName m_command; + bool m_isAutoDetected; + QList m_abis; +}; + +} // namespace Debugger + +#endif // DEBUGGER_DEBUGGERITEM_H diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp new file mode 100644 index 00000000000..e9df26be1ef --- /dev/null +++ b/src/plugins/debugger/debuggeritemmanager.cpp @@ -0,0 +1,408 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "debuggeritemmanager.h" + +#include "debuggeritemmodel.h" +#include "debuggerkitinformation.h" + +#include + +#include +#include +#include +#include + +#include +#include +#include + +using namespace ProjectExplorer; +using namespace Utils; + +namespace Debugger { + +static const char DEBUGGER_COUNT_KEY[] = "DebuggerItem.Count"; +static const char DEBUGGER_DATA_KEY[] = "DebuggerItem."; +static const char DEBUGGER_LEGACY_FILENAME[] = "/qtcreator/profiles.xml"; +static const char DEBUGGER_FILE_VERSION_KEY[] = "Version"; +static const char DEBUGGER_FILENAME[] = "/qtcreator/debuggers.xml"; + +// -------------------------------------------------------------------------- +// DebuggerItemManager +// -------------------------------------------------------------------------- + +static DebuggerItemManager *m_instance = 0; + +static FileName userSettingsFileName() +{ + QFileInfo settingsLocation(Core::ICore::settings()->fileName()); + return FileName::fromString(settingsLocation.absolutePath() + QLatin1String(DEBUGGER_FILENAME)); +} + +static void readDebuggers(const FileName &fileName, bool isSystem) +{ + PersistentSettingsReader reader; + if (!reader.load(fileName)) + return; + QVariantMap data = reader.restoreValues(); + + // Check version + int version = data.value(QLatin1String(DEBUGGER_FILE_VERSION_KEY), 0).toInt(); + if (version < 1) + return; + + int count = data.value(QLatin1String(DEBUGGER_COUNT_KEY), 0).toInt(); + for (int i = 0; i < count; ++i) { + const QString key = QString::fromLatin1(DEBUGGER_DATA_KEY) + QString::number(i); + if (!data.contains(key)) + continue; + const QVariantMap dbMap = data.value(key).toMap(); + DebuggerItem item(dbMap); + if (isSystem) { + item.setAutoDetected(true); + // SDK debuggers are always considered to be up-to-date, so no need to recheck them. + } else { + // User settings. + if (item.isAutoDetected() && !item.isValid()) { + qWarning() << QString::fromLatin1("DebuggerItem \"%1\" (%2) dropped since it is not valid") + .arg(item.command().toString()).arg(item.id().toString()); + continue; + } + } + DebuggerItemManager::registerDebugger(item); + } +} + +QList DebuggerItemManager::m_debuggers; +Internal::DebuggerItemModel* DebuggerItemManager::m_model = 0; +PersistentSettingsWriter * DebuggerItemManager::m_writer = 0; + +DebuggerItemManager::DebuggerItemManager(QObject *parent) + : QObject(parent) +{ + m_instance = this; + m_writer = new PersistentSettingsWriter(userSettingsFileName(), QLatin1String("QtCreatorDebugger")); + m_model = new Debugger::Internal::DebuggerItemModel(this); + connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()), + this, SLOT(saveDebuggers())); +} + +QObject *DebuggerItemManager::instance() +{ + return m_instance; +} + +DebuggerItemManager::~DebuggerItemManager() +{ + disconnect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()), + this, SLOT(saveDebuggers())); + delete m_writer; +} + +QList DebuggerItemManager::debuggers() +{ + return m_debuggers; +} + +Internal::DebuggerItemModel *DebuggerItemManager::model() +{ + return m_model; +} + +void DebuggerItemManager::autoDetectCdbDebuggers() +{ + QList cdbs; + + QStringList programDirs; + programDirs.append(QString::fromLocal8Bit(qgetenv("ProgramFiles"))); + programDirs.append(QString::fromLocal8Bit(qgetenv("ProgramFiles(x86)"))); + programDirs.append(QString::fromLocal8Bit(qgetenv("ProgramW6432"))); + + foreach (const QString &dirName, programDirs) { + if (dirName.isEmpty()) + continue; + QDir dir(dirName); + // Windows SDK's starting from version 8 live in + // "ProgramDir\Windows Kits\" + const QString windowsKitsFolderName = QLatin1String("Windows Kits"); + if (dir.exists(windowsKitsFolderName)) { + QDir windowKitsFolder = dir; + if (windowKitsFolder.cd(windowsKitsFolderName)) { + // Check in reverse order (latest first) + const QFileInfoList kitFolders = + windowKitsFolder.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, + QDir::Time | QDir::Reversed); + foreach (const QFileInfo &kitFolderFi, kitFolders) { + const QString path = kitFolderFi.absoluteFilePath(); + const QFileInfo cdb32(path + QLatin1String("/Debuggers/x86/cdb.exe")); + if (cdb32.isExecutable()) + cdbs.append(FileName::fromString(cdb32.absoluteFilePath())); + const QFileInfo cdb64(path + QLatin1String("/Debuggers/x64/cdb.exe")); + if (cdb64.isExecutable()) + cdbs.append(FileName::fromString(cdb64.absoluteFilePath())); + } + } + } + + // Pre Windows SDK 8: Check 'Debugging Tools for Windows' + foreach (const QFileInfo &fi, dir.entryInfoList(QStringList(QLatin1String("Debugging Tools for Windows*")), + QDir::Dirs | QDir::NoDotAndDotDot)) { + FileName filePath(fi); + filePath.appendPath(QLatin1String("cdb.exe")); + if (!cdbs.contains(filePath)) + cdbs.append(filePath); + } + } + + foreach (const FileName &cdb, cdbs) { + if (findByCommand(cdb)) + continue; + DebuggerItem item; + item.setAutoDetected(true); + item.setAbis(Abi::abisOfBinary(cdb)); + item.setCommand(cdb); + item.setEngineType(CdbEngineType); + item.setDisplayName(uniqueDisplayName(tr("Auto-detected CDB at %1").arg(cdb.toUserOutput()))); + addDebugger(item); + } +} + +void DebuggerItemManager::autoDetectGdbOrLldbDebuggers() +{ + QStringList filters; + filters.append(QLatin1String("gdb-i686-pc-mingw32")); + filters.append(QLatin1String("gdb")); + filters.append(QLatin1String("lldb")); + filters.append(QLatin1String("lldb-*")); + +// DebuggerItem result; +// result.setAutoDetected(true); +// result.setDisplayName(tr("Auto-detected for Tool Chain %1").arg(tc->displayName())); + /* + // Check suggestions from the SDK. + Environment env = Environment::systemEnvironment(); + if (tc) { + tc->addToEnvironment(env); // Find MinGW gdb in toolchain environment. + QString path = tc->suggestedDebugger().toString(); + if (!path.isEmpty()) { + const QFileInfo fi(path); + if (!fi.isAbsolute()) + path = env.searchInPath(path); + result.command = FileName::fromString(path); + result.engineType = engineTypeFromBinary(path); + return maybeAddDebugger(result, false); + } + } + */ + + QFileInfoList suspects; + + QStringList path = Environment::systemEnvironment().path(); + foreach (const QString &base, path) { + QDir dir(base); + dir.setNameFilters(filters); + suspects += dir.entryInfoList(); + } + + foreach (const QFileInfo &fi, suspects) { + if (fi.exists()) { + FileName command = FileName::fromString(fi.absoluteFilePath()); + if (findByCommand(command)) + continue; + DebuggerItem item; + item.setCommand(command); + item.reinitializeFromFile(); + //: %1: Debugger engine type (GDB, LLDB, CDB...), %2: Path + item.setDisplayName(tr("System %1 at %2") + .arg(item.engineTypeName()).arg(QDir::toNativeSeparators(fi.absoluteFilePath()))); + item.setAutoDetected(true); + addDebugger(item); + } + } +} + +void DebuggerItemManager::readLegacyDebuggers() +{ + QFileInfo settingsLocation(Core::ICore::settings()->fileName()); + FileName legacyKits = FileName::fromString(settingsLocation.absolutePath() + QLatin1String(DEBUGGER_LEGACY_FILENAME)); + + PersistentSettingsReader reader; + if (!reader.load(legacyKits)) + return; + + foreach (const QVariant &v, reader.restoreValues()) { + QVariantMap data1 = v.toMap(); + QString kitName = data1.value(QLatin1String("PE.Profile.Name")).toString(); + QVariantMap data2 = data1.value(QLatin1String("PE.Profile.Data")).toMap(); + QVariant v3 = data2.value(DebuggerKitInformation::id().toString()); + QString fn; + if (v3.type() == QVariant::String) + fn = v3.toString(); + else + fn = v3.toMap().value(QLatin1String("Binary")).toString(); + if (fn.isEmpty()) + continue; + if (fn.startsWith(QLatin1Char('{'))) + continue; + if (fn == QLatin1String("auto")) + continue; + FileName command = FileName::fromUserInput(fn); + if (findByCommand(command)) + continue; + DebuggerItem item; + item.setCommand(command); + item.setAutoDetected(true); + item.reinitializeFromFile(); + item.setDisplayName(tr("Extracted from Kit %1").arg(kitName)); + addDebugger(item); + } +} + +const DebuggerItem *DebuggerItemManager::findByCommand(const FileName &command) +{ + foreach (const DebuggerItem &item, m_debuggers) + if (item.command() == command) + return &item; + + return 0; +} + +const DebuggerItem *DebuggerItemManager::findById(const QVariant &id) +{ + foreach (const DebuggerItem &item, m_debuggers) + if (item.id() == id) + return &item; + + return 0; +} + +void DebuggerItemManager::restoreDebuggers() +{ + // Read debuggers from SDK + QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName()); + readDebuggers(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(DEBUGGER_FILENAME)), true); + + // Read all debuggers from user file. + readDebuggers(userSettingsFileName(), false); + + // Auto detect current. + autoDetectCdbDebuggers(); + autoDetectGdbOrLldbDebuggers(); + + // Add debuggers from pre-3.x profiles.xml + readLegacyDebuggers(); +} + +void DebuggerItemManager::saveDebuggers() +{ + QTC_ASSERT(m_writer, return); + QVariantMap data; + data.insert(QLatin1String(DEBUGGER_FILE_VERSION_KEY), 1); + + int count = 0; + foreach (const DebuggerItem &item, m_debuggers) { + if (item.isValid()) { + QVariantMap tmp = item.toMap(); + if (tmp.isEmpty()) + continue; + data.insert(QString::fromLatin1(DEBUGGER_DATA_KEY) + QString::number(count), tmp); + ++count; + } + } + data.insert(QLatin1String(DEBUGGER_COUNT_KEY), count); + m_writer->save(data, Core::ICore::mainWindow()); + + // Do not save default debuggers as they are set by the SDK. +} + +QVariant DebuggerItemManager::registerDebugger(const DebuggerItem &item) +{ + if (findByCommand(item.command())) + return item.id(); + + return addDebugger(item); +} + +void DebuggerItemManager::deregisterDebugger(const DebuggerItem &item) +{ + if (findByCommand(item.command())) + removeDebugger(item.id()); +} + +QVariant DebuggerItemManager::addDebugger(const DebuggerItem &item) +{ + QTC_ASSERT(!item.command().isEmpty(), return QVariant()); + QTC_ASSERT(!item.displayName().isEmpty(), return QVariant()); + QTC_ASSERT(item.engineType() != NoEngineType, return QVariant()); + QTC_ASSERT(item.id().isValid(), return QVariant()); + m_debuggers.append(item); + m_model->addDebugger(item); + return item.id(); +} + +void DebuggerItemManager::removeDebugger(const QVariant &id) +{ + bool ok = false; + for (int i = 0, n = m_debuggers.size(); i != n; ++i) { + if (m_debuggers.at(i).id() == id) { + m_debuggers.removeAt(i); + ok = true; + break; + } + } + + QTC_ASSERT(ok, return); + m_model->removeDebugger(id); +} + +QString DebuggerItemManager::uniqueDisplayName(const QString &base) +{ + foreach (const DebuggerItem &item, m_debuggers) + if (item.displayName() == base) + return uniqueDisplayName(base + QLatin1String(" (1)")); + + return base; +} + +void DebuggerItemManager::setItemData(const QVariant &id, const QString &displayName, const FileName &fileName) +{ + for (int i = 0, n = m_debuggers.size(); i != n; ++i) { + DebuggerItem &item = m_debuggers[i]; + if (item.id() == id) { + item.setDisplayName(displayName); + item.setCommand(fileName); + item.reinitializeFromFile(); + emit m_model->updateDebugger(item.id()); + break; + } + } +} + +} // namespace Debugger; diff --git a/src/plugins/debugger/debuggeritemmanager.h b/src/plugins/debugger/debuggeritemmanager.h new file mode 100644 index 00000000000..057cfd58b12 --- /dev/null +++ b/src/plugins/debugger/debuggeritemmanager.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef DEBUGGER_DEBUGGERITEMMANAGER_H +#define DEBUGGER_DEBUGGERITEMMANAGER_H + +#include "debugger_global.h" +#include "debuggeritem.h" +#include "debuggeritemmodel.h" + +#include +#include +#include + +namespace Utils { class PersistentSettingsWriter; } + +namespace Debugger { + +// ----------------------------------------------------------------------- +// DebuggerItemManager +// ----------------------------------------------------------------------- + +class DEBUGGER_EXPORT DebuggerItemManager : public QObject +{ + Q_OBJECT + +public: + static QObject *instance(); + ~DebuggerItemManager(); + + static QList debuggers(); + static Debugger::Internal::DebuggerItemModel *model(); + + static QVariant registerDebugger(const DebuggerItem &item); + static void deregisterDebugger(const DebuggerItem &item); + + static const DebuggerItem *findByCommand(const Utils::FileName &command); + static const DebuggerItem *findById(const QVariant &id); + + static void restoreDebuggers(); + static QString uniqueDisplayName(const QString &base); + static void setItemData(const QVariant &id, const QString& displayName, const Utils::FileName &fileName); + + static void removeDebugger(const QVariant &id); + static QVariant addDebugger(const DebuggerItem &item); + +public slots: + void saveDebuggers(); + +private: + explicit DebuggerItemManager(QObject *parent = 0); + static void autoDetectGdbOrLldbDebuggers(); + static void autoDetectCdbDebuggers(); + static void readLegacyDebuggers(); + + static Utils::PersistentSettingsWriter *m_writer; + static QList m_debuggers; + static Debugger::Internal::DebuggerItemModel *m_model; + + friend class Internal::DebuggerItemModel; + friend class DebuggerPlugin; // Enable constrcutor for DebuggerPlugin +}; + +} // namespace Debugger + +#endif // DEBUGGER_DEBUGGERITEMMANAGER_H diff --git a/src/plugins/debugger/debuggeritemmodel.cpp b/src/plugins/debugger/debuggeritemmodel.cpp new file mode 100644 index 00000000000..635404684fb --- /dev/null +++ b/src/plugins/debugger/debuggeritemmodel.cpp @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "debuggeritemmodel.h" + +#include "debuggeritem.h" +#include "debuggeritemmanager.h" + +#include + +namespace Debugger { +namespace Internal { + +static QList describeItem(const DebuggerItem &item) +{ + QList row; + row.append(new QStandardItem(item.displayName())); + row.append(new QStandardItem(item.command().toUserOutput())); + row.append(new QStandardItem(item.engineTypeName())); + row.at(0)->setData(item.id()); + row.at(0)->setEditable(false); + row.at(1)->setEditable(false); + row.at(2)->setEditable(false); + row.at(0)->setSelectable(true); + row.at(1)->setSelectable(true); + row.at(2)->setSelectable(true); + return row; +} + +static QList createRow(const QString &display) +{ + QList row; + row.append(new QStandardItem(display)); + row.append(new QStandardItem()); + row.append(new QStandardItem()); + row.at(0)->setEditable(false); + row.at(1)->setEditable(false); + row.at(2)->setEditable(false); + row.at(0)->setSelectable(false); + row.at(1)->setSelectable(false); + row.at(2)->setSelectable(false); + return row; +} + +// -------------------------------------------------------------------------- +// DebuggerItemModel +// -------------------------------------------------------------------------- + +DebuggerItemModel::DebuggerItemModel(QObject *parent) + : QStandardItemModel(parent) +{ + setColumnCount(3); + + QList row = createRow(tr("Auto-detected")); + m_autoRoot = row.at(0); + appendRow(row); + + row = createRow(tr("Manual")); + m_manualRoot = row.at(0); + appendRow(row); +} + +QVariant DebuggerItemModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { + switch (section) { + case 0: + return tr("Name"); + case 1: + return tr("Path"); + case 2: + return tr("Type"); + } + } + return QVariant(); +} + +QStandardItem *DebuggerItemModel::currentStandardItem() const +{ + return findStandardItemById(m_currentDebugger); +} + +QStandardItem *DebuggerItemModel::findStandardItemById(const QVariant &id) const +{ + for (int i = 0, n = m_autoRoot->rowCount(); i != n; ++i) { + QStandardItem *sitem = m_autoRoot->child(i); + if (sitem->data() == id) + return sitem; + } + for (int i = 0, n = m_manualRoot->rowCount(); i != n; ++i) { + QStandardItem *sitem = m_manualRoot->child(i); + if (sitem->data() == id) + return sitem; + } + return 0; +} + +QModelIndex DebuggerItemModel::currentIndex() const +{ + QStandardItem *current = currentStandardItem(); + return current ? current->index() : QModelIndex(); +} + +QModelIndex DebuggerItemModel::lastIndex() const +{ + int n = m_manualRoot->rowCount(); + QStandardItem *current = m_manualRoot->child(n - 1); + return current ? current->index() : QModelIndex(); +} + +void DebuggerItemModel::markCurrentDirty() +{ + QStandardItem *sitem = currentStandardItem(); + QTC_ASSERT(sitem, return); + QFont font = sitem->font(); + font.setBold(true); + sitem->setFont(font); +} + +void DebuggerItemModel::addDebugger(const DebuggerItem &item) +{ + QTC_ASSERT(item.id().isValid(), return); + QList row = describeItem(item); + (item.isAutoDetected() ? m_autoRoot : m_manualRoot)->appendRow(row); + emit debuggerAdded(item.id(), item.displayName()); +} + +void DebuggerItemModel::removeDebugger(const QVariant &id) +{ + QStandardItem *sitem = findStandardItemById(id); + QTC_ASSERT(sitem, return); + QStandardItem *parent = sitem->parent(); + QTC_ASSERT(parent, return); + // This will trigger a change of m_currentDebugger via changing the + // view selection. + parent->removeRow(sitem->row()); + emit debuggerRemoved(id); +} + +void DebuggerItemModel::updateDebugger(const QVariant &id) +{ + QList debuggers = DebuggerItemManager::debuggers(); + for (int i = 0, n = debuggers.size(); i != n; ++i) { + DebuggerItem &item = debuggers[i]; + if (item.id() == id) { + QStandardItem *sitem = findStandardItemById(id); + QTC_ASSERT(sitem, return); + QStandardItem *parent = sitem->parent(); + QTC_ASSERT(parent, return); + int row = sitem->row(); + QFont font = sitem->font(); + font.setBold(false); + parent->child(row, 0)->setData(item.displayName(), Qt::DisplayRole); + parent->child(row, 0)->setFont(font); + parent->child(row, 1)->setData(item.command().toUserOutput(), Qt::DisplayRole); + parent->child(row, 1)->setFont(font); + parent->child(row, 2)->setData(item.engineTypeName(), Qt::DisplayRole); + parent->child(row, 2)->setFont(font); + emit debuggerUpdated(id, item.displayName()); + return; + } + } +} + +void DebuggerItemModel::setCurrentIndex(const QModelIndex &index) +{ + QStandardItem *sit = itemFromIndex(index); + m_currentDebugger = sit ? sit->data() : QVariant(); +} + +} // namespace Internal +} // namespace Debugger diff --git a/src/plugins/debugger/debuggeritemmodel.h b/src/plugins/debugger/debuggeritemmodel.h new file mode 100644 index 00000000000..bb53c708ab1 --- /dev/null +++ b/src/plugins/debugger/debuggeritemmodel.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef DEBUGGER_DEBUGGERITEMMODEL_H +#define DEBUGGER_DEBUGGERITEMMODEL_H + +#include "debuggeritem.h" + +#include +#include + +namespace Debugger { +namespace Internal { + +// ----------------------------------------------------------------------- +// DebuggerItemModel +//------------------------------------------------------------------------ + +class DebuggerItemModel : public QStandardItemModel +{ + Q_OBJECT + +public: + DebuggerItemModel(QObject *parent); + + QModelIndex currentIndex() const; + QModelIndex lastIndex() const; + void setCurrentIndex(const QModelIndex &index); + QVariant currentDebugger() const { return m_currentDebugger; } + void addDebugger(const DebuggerItem &item); + void removeDebugger(const QVariant &id); + void updateDebugger(const QVariant &id); + +public slots: + void markCurrentDirty(); + +signals: + void debuggerAdded(const QVariant &id, const QString &display); + void debuggerUpdated(const QVariant &id, const QString &display); + void debuggerRemoved(const QVariant &id); + +private: + // + // friend class Debugger::DebuggerKitInformation; + // friend class DebuggerKitConfigWidget; + // friend class DebuggerItemConfigWidget; + // friend class DebuggerOptionsPage; + // + + QStandardItem *currentStandardItem() const; + QStandardItem *findStandardItemById(const QVariant &id) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + + QVariant m_currentDebugger; + + QStandardItem *m_autoRoot; + QStandardItem *m_manualRoot; + QStringList removed; +}; + +} // namespace Internal +} // namespace Debugger + +#endif // DEBUGGER_DEBUGGERITEMMODEL_H diff --git a/src/plugins/debugger/debuggerkitconfigwidget.cpp b/src/plugins/debugger/debuggerkitconfigwidget.cpp index a3e0b611d31..85f4ded6418 100644 --- a/src/plugins/debugger/debuggerkitconfigwidget.cpp +++ b/src/plugins/debugger/debuggerkitconfigwidget.cpp @@ -29,6 +29,9 @@ #include "debuggerkitconfigwidget.h" +#include "debuggeritemmanager.h" +#include "debuggeritemmodel.h" + #include #include @@ -64,811 +67,10 @@ using namespace Utils; using namespace Debugger::Internal; namespace Debugger { - -static const char debuggingToolsWikiLinkC[] = "http://qt-project.org/wiki/Qt_Creator_Windows_Debugging"; - -static const char DEBUGGER_DATA_KEY[] = "DebuggerItem."; -static const char DEBUGGER_COUNT_KEY[] = "DebuggerItem.Count"; -static const char DEBUGGER_FILE_VERSION_KEY[] = "Version"; -static const char DEBUGGER_FILENAME[] = "/qtcreator/debuggers.xml"; -static const char DEBUGGER_LEGACY_FILENAME[] = "/qtcreator/profiles.xml"; - -// -------------------------------------------------------------------------- -// DebuggerKitInformation -// -------------------------------------------------------------------------- - -DebuggerKitInformation::DebuggerKitInformation() -{ - setObjectName(QLatin1String("DebuggerKitInformation")); - setId(DebuggerKitInformation::id()); - setPriority(28000); -} - -QVariant DebuggerKitInformation::defaultValue(Kit *k) const -{ - ToolChain *tc = ToolChainKitInformation::toolChain(k); - QTC_ASSERT(tc, return QVariant()); - - const Abi toolChainAbi = tc->targetAbi(); - foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) - foreach (const Abi targetAbi, item.abis()) - if (targetAbi.isCompatibleWith(toolChainAbi)) - return item.id(); - - return QVariant(); -} - -void DebuggerKitInformation::setup(Kit *k) -{ - // Get one of the available debugger matching the kit's toolchain. - const ToolChain *tc = ToolChainKitInformation::toolChain(k); - const Abi toolChainAbi = tc ? tc->targetAbi() : Abi::hostAbi(); - - // This can be anything (Id, binary path, "auto") - const QVariant rawId = k->value(DebuggerKitInformation::id()); - - enum { - NotDetected, DetectedAutomatically, DetectedByFile, DetectedById - } detection = NotDetected; - DebuggerEngineType autoEngine = NoEngineType; - FileName fileName; - - // With 3.0 we have: - // {75ecf347-f221-44c3-b613-ea1d29929cd4} - // Before we had: - // - // /data/dev/debugger/gdb-git/gdb/gdb - // 1 - // - // Or for force auto-detected CDB - // - // auto - // 4 - // - - if (rawId.isNull()) { - // Initial setup of a kit - detection = NotDetected; - } else if (rawId.type() == QVariant::String) { - detection = DetectedById; - } else { - QMap map = rawId.toMap(); - QString binary = map.value(QLatin1String("Binary")).toString(); - if (binary == QLatin1String("auto")) { - detection = DetectedAutomatically; - autoEngine = DebuggerEngineType(map.value(QLatin1String("EngineType")).toInt()); - } else { - detection = DetectedByFile; - fileName = FileName::fromUserInput(binary); - } - } - - const DebuggerItem *bestItem = 0; - DebuggerItem::MatchLevel bestLevel = DebuggerItem::DoesNotMatch; - foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) { - const DebuggerItem *goodItem = 0; - if (detection == DetectedById && item.id() == rawId) - goodItem = &item; - if (detection == DetectedByFile && item.command() == fileName) - goodItem = &item; - if (detection == DetectedAutomatically && item.engineType() == autoEngine) - goodItem = &item; - - if (goodItem) { - DebuggerItem::MatchLevel level = goodItem->matchTarget(toolChainAbi); - if (level > bestLevel) { - bestLevel = level; - bestItem = goodItem; - } - } - } - - // If we have an existing debugger with matching id _and_ - // matching target ABI we are fine. - if (bestItem) { - k->setValue(DebuggerKitInformation::id(), bestItem->id()); - return; - } - - // We didn't find an existing debugger that matched by whatever - // data we found in the kit (i.e. no id, filename, "auto") - // (or what we found did not match ABI-wise) - // Let's try to pick one with matching ABI. - QVariant bestId; - bestLevel = DebuggerItem::DoesNotMatch; - foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) { - DebuggerItem::MatchLevel level = item.matchTarget(toolChainAbi); - if (level > bestLevel) { - bestLevel = level; - bestId = item.id(); - } - } - - k->setValue(DebuggerKitInformation::id(), bestId); -} - - -// This handles the upgrade path from 2.8 to 3.0 -void DebuggerKitInformation::fix(Kit *k) -{ - // This can be Id, binary path, but not "auto" anymore. - const QVariant rawId = k->value(DebuggerKitInformation::id()); - - if (rawId.isNull()) // No debugger set, that is fine. - return; - - if (rawId.type() == QVariant::String) { - if (!DebuggerItemManager::findById(rawId)) { - qWarning("Unknown debugger id %s in kit %s", - qPrintable(rawId.toString()), qPrintable(k->displayName())); - k->setValue(DebuggerKitInformation::id(), QVariant()); - } - return; // All fine (now). - } - - QMap map = rawId.toMap(); - QString binary = map.value(QLatin1String("Binary")).toString(); - if (binary == QLatin1String("auto")) { - // This should not happen as "auto" is handled by setup() already. - QTC_CHECK(false); - k->setValue(DebuggerKitInformation::id(), QVariant()); - return; - } - - FileName fileName = FileName::fromUserInput(binary); - const DebuggerItem *item = DebuggerItemManager::findByCommand(fileName); - if (!item) { - qWarning("Debugger command %s invalid in kit %s", - qPrintable(binary), qPrintable(k->displayName())); - k->setValue(DebuggerKitInformation::id(), QVariant()); - return; - } - - k->setValue(DebuggerKitInformation::id(), item->id()); -} - -// Check the configuration errors and return a flag mask. Provide a quick check and -// a verbose one with a list of errors. - -enum DebuggerConfigurationErrors { - NoDebugger = 0x1, - DebuggerNotFound = 0x2, - DebuggerNotExecutable = 0x4, - DebuggerNeedsAbsolutePath = 0x8 -}; - -static unsigned debuggerConfigurationErrors(const Kit *k) -{ - QTC_ASSERT(k, return NoDebugger); - - const DebuggerItem *item = DebuggerKitInformation::debugger(k); - if (!item) - return NoDebugger; - - if (item->command().isEmpty()) - return NoDebugger; - - unsigned result = 0; - const QFileInfo fi = item->command().toFileInfo(); - if (!fi.exists() || fi.isDir()) - result |= DebuggerNotFound; - else if (!fi.isExecutable()) - result |= DebuggerNotExecutable; - - if (!fi.exists() || fi.isDir()) { - if (item->engineType() == NoEngineType) - return NoDebugger; - - // We need an absolute path to be able to locate Python on Windows. - if (item->engineType() == GdbEngineType) - if (const ToolChain *tc = ToolChainKitInformation::toolChain(k)) - if (tc->targetAbi().os() == Abi::WindowsOS && !fi.isAbsolute()) - result |= DebuggerNeedsAbsolutePath; - } - return result; -} - -const DebuggerItem *DebuggerKitInformation::debugger(const Kit *kit) -{ - QTC_ASSERT(kit, return 0); - const QVariant id = kit->value(DebuggerKitInformation::id()); - return DebuggerItemManager::findById(id); -} - -bool DebuggerKitInformation::isValidDebugger(const Kit *k) -{ - return debuggerConfigurationErrors(k) == 0; -} - -QList DebuggerKitInformation::validateDebugger(const Kit *k) -{ - QList result; - - const unsigned errors = debuggerConfigurationErrors(k); - if (!errors) - return result; - - QString path; - if (const DebuggerItem *item = debugger(k)) - path = item->command().toUserOutput(); - - const Core::Id id = ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM; - if (errors & NoDebugger) - result << Task(Task::Warning, tr("No debugger set up."), FileName(), -1, id); - - if (errors & DebuggerNotFound) - result << Task(Task::Error, tr("Debugger '%1' not found.").arg(path), - FileName(), -1, id); - if (errors & DebuggerNotExecutable) - result << Task(Task::Error, tr("Debugger '%1' not executable.").arg(path), FileName(), -1, id); - - if (errors & DebuggerNeedsAbsolutePath) { - const QString message = - tr("The debugger location must be given as an " - "absolute path (%1).").arg(path); - result << Task(Task::Error, message, FileName(), -1, id); - } - return result; -} - -KitConfigWidget *DebuggerKitInformation::createConfigWidget(Kit *k) const -{ - return new Internal::DebuggerKitConfigWidget(k, this); -} - -KitInformation::ItemList DebuggerKitInformation::toUserOutput(const Kit *k) const -{ - return ItemList() << qMakePair(tr("Debugger"), displayString(k)); -} - -FileName DebuggerKitInformation::debuggerCommand(const ProjectExplorer::Kit *k) -{ - const DebuggerItem *item = debugger(k); - QTC_ASSERT(item, return FileName()); - return item->command(); -} - -DebuggerEngineType DebuggerKitInformation::engineType(const ProjectExplorer::Kit *k) -{ - const DebuggerItem *item = debugger(k); - QTC_ASSERT(item, return NoEngineType); - return item->engineType(); -} - -QString DebuggerKitInformation::displayString(const Kit *k) -{ - const DebuggerItem *item = debugger(k); - if (!item) - return tr("No Debugger"); - QString binary = item->command().toUserOutput(); - QString name = tr("%1 Engine").arg(item->engineTypeName()); - return binary.isEmpty() ? tr("%1 ").arg(name) : tr("%1 using \"%2\"").arg(name, binary); -} - -void DebuggerKitInformation::setDebugger(Kit *k, const QVariant &id) -{ - // Only register reasonably complete debuggers. - QTC_ASSERT(DebuggerItemManager::findById(id), return); - k->setValue(DebuggerKitInformation::id(), id); -} - -Core::Id DebuggerKitInformation::id() -{ - return "Debugger.Information"; -} - -// -------------------------------------------------------------------------- -// DebuggerItemManager -// -------------------------------------------------------------------------- - -static DebuggerItemManager *m_instance = 0; - -static FileName userSettingsFileName() -{ - QFileInfo settingsLocation(Core::ICore::settings()->fileName()); - return FileName::fromString(settingsLocation.absolutePath() + QLatin1String(DEBUGGER_FILENAME)); -} - -static void readDebuggers(const FileName &fileName, bool isSystem) -{ - PersistentSettingsReader reader; - if (!reader.load(fileName)) - return; - QVariantMap data = reader.restoreValues(); - - // Check version - int version = data.value(QLatin1String(DEBUGGER_FILE_VERSION_KEY), 0).toInt(); - if (version < 1) - return; - - int count = data.value(QLatin1String(DEBUGGER_COUNT_KEY), 0).toInt(); - for (int i = 0; i < count; ++i) { - const QString key = QString::fromLatin1(DEBUGGER_DATA_KEY) + QString::number(i); - if (!data.contains(key)) - continue; - const QVariantMap dbMap = data.value(key).toMap(); - DebuggerItem item(dbMap); - if (isSystem) { - item.setAutoDetected(true); - // SDK debuggers are always considered to be up-to-date, so no need to recheck them. - } else { - // User settings. - if (item.isAutoDetected() && !item.isValid()) { - qWarning() << QString::fromLatin1("DebuggerItem \"%1\" (%2) dropped since it is not valid") - .arg(item.command().toString()).arg(item.id().toString()); - continue; - } - } - DebuggerItemManager::registerDebugger(item); - } -} - -QList DebuggerItemManager::m_debuggers; -DebuggerItemModel* DebuggerItemManager::m_model = 0; -PersistentSettingsWriter * DebuggerItemManager::m_writer = 0; - -DebuggerItemManager::DebuggerItemManager(QObject *parent) - : QObject(parent) -{ - m_instance = this; - m_writer = new PersistentSettingsWriter(userSettingsFileName(), QLatin1String("QtCreatorDebugger")); - m_model = new Debugger::Internal::DebuggerItemModel(this); - connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()), - this, SLOT(saveDebuggers())); -} - -QObject *DebuggerItemManager::instance() -{ - return m_instance; -} - -DebuggerItemManager::~DebuggerItemManager() -{ - disconnect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()), - this, SLOT(saveDebuggers())); - delete m_writer; -} - -QList DebuggerItemManager::debuggers() -{ - return m_debuggers; -} - -DebuggerItemModel *DebuggerItemManager::model() -{ - return m_model; -} - -void DebuggerItemManager::autoDetectCdbDebuggers() -{ - QList cdbs; - - QStringList programDirs; - programDirs.append(QString::fromLocal8Bit(qgetenv("ProgramFiles"))); - programDirs.append(QString::fromLocal8Bit(qgetenv("ProgramFiles(x86)"))); - programDirs.append(QString::fromLocal8Bit(qgetenv("ProgramW6432"))); - - foreach (const QString &dirName, programDirs) { - if (dirName.isEmpty()) - continue; - QDir dir(dirName); - // Windows SDK's starting from version 8 live in - // "ProgramDir\Windows Kits\" - const QString windowsKitsFolderName = QLatin1String("Windows Kits"); - if (dir.exists(windowsKitsFolderName)) { - QDir windowKitsFolder = dir; - if (windowKitsFolder.cd(windowsKitsFolderName)) { - // Check in reverse order (latest first) - const QFileInfoList kitFolders = - windowKitsFolder.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, - QDir::Time | QDir::Reversed); - foreach (const QFileInfo &kitFolderFi, kitFolders) { - const QString path = kitFolderFi.absoluteFilePath(); - const QFileInfo cdb32(path + QLatin1String("/Debuggers/x86/cdb.exe")); - if (cdb32.isExecutable()) - cdbs.append(FileName::fromString(cdb32.absoluteFilePath())); - const QFileInfo cdb64(path + QLatin1String("/Debuggers/x64/cdb.exe")); - if (cdb64.isExecutable()) - cdbs.append(FileName::fromString(cdb64.absoluteFilePath())); - } - } - } - - // Pre Windows SDK 8: Check 'Debugging Tools for Windows' - foreach (const QFileInfo &fi, dir.entryInfoList(QStringList(QLatin1String("Debugging Tools for Windows*")), - QDir::Dirs | QDir::NoDotAndDotDot)) { - FileName filePath(fi); - filePath.appendPath(QLatin1String("cdb.exe")); - if (!cdbs.contains(filePath)) - cdbs.append(filePath); - } - } - - foreach (const FileName &cdb, cdbs) { - if (findByCommand(cdb)) - continue; - DebuggerItem item; - item.setAutoDetected(true); - item.setAbis(Abi::abisOfBinary(cdb)); - item.setCommand(cdb); - item.setEngineType(CdbEngineType); - item.setDisplayName(uniqueDisplayName(tr("Auto-detected CDB at %1").arg(cdb.toUserOutput()))); - addDebugger(item); - } -} - -void DebuggerItemManager::autoDetectGdbOrLldbDebuggers() -{ - QStringList filters; - filters.append(QLatin1String("gdb-i686-pc-mingw32")); - filters.append(QLatin1String("gdb")); - filters.append(QLatin1String("lldb")); - filters.append(QLatin1String("lldb-*")); - -// DebuggerItem result; -// result.setAutoDetected(true); -// result.setDisplayName(tr("Auto-detected for Tool Chain %1").arg(tc->displayName())); - /* - // Check suggestions from the SDK. - Environment env = Environment::systemEnvironment(); - if (tc) { - tc->addToEnvironment(env); // Find MinGW gdb in toolchain environment. - QString path = tc->suggestedDebugger().toString(); - if (!path.isEmpty()) { - const QFileInfo fi(path); - if (!fi.isAbsolute()) - path = env.searchInPath(path); - result.command = FileName::fromString(path); - result.engineType = engineTypeFromBinary(path); - return maybeAddDebugger(result, false); - } - } - */ - - QFileInfoList suspects; - - QStringList path = Environment::systemEnvironment().path(); - foreach (const QString &base, path) { - QDir dir(base); - dir.setNameFilters(filters); - suspects += dir.entryInfoList(); - } - - foreach (const QFileInfo &fi, suspects) { - if (fi.exists()) { - FileName command = FileName::fromString(fi.absoluteFilePath()); - if (findByCommand(command)) - continue; - DebuggerItem item; - item.setCommand(command); - item.reinitializeFromFile(); - //: %1: Debugger engine type (GDB, LLDB, CDB...), %2: Path - item.setDisplayName(tr("System %1 at %2") - .arg(item.engineTypeName()).arg(QDir::toNativeSeparators(fi.absoluteFilePath()))); - item.setAutoDetected(true); - addDebugger(item); - } - } -} - -void DebuggerItemManager::readLegacyDebuggers() -{ - QFileInfo settingsLocation(Core::ICore::settings()->fileName()); - FileName legacyKits = FileName::fromString(settingsLocation.absolutePath() + QLatin1String(DEBUGGER_LEGACY_FILENAME)); - - PersistentSettingsReader reader; - if (!reader.load(legacyKits)) - return; - - foreach (const QVariant &v, reader.restoreValues()) { - QVariantMap data1 = v.toMap(); - QString kitName = data1.value(QLatin1String("PE.Profile.Name")).toString(); - QVariantMap data2 = data1.value(QLatin1String("PE.Profile.Data")).toMap(); - QVariant v3 = data2.value(DebuggerKitInformation::id().toString()); - QString fn; - if (v3.type() == QVariant::String) - fn = v3.toString(); - else - fn = v3.toMap().value(QLatin1String("Binary")).toString(); - if (fn.isEmpty()) - continue; - if (fn.startsWith(QLatin1Char('{'))) - continue; - if (fn == QLatin1String("auto")) - continue; - FileName command = FileName::fromUserInput(fn); - if (findByCommand(command)) - continue; - DebuggerItem item; - item.setCommand(command); - item.setAutoDetected(true); - item.reinitializeFromFile(); - item.setDisplayName(tr("Extracted from Kit %1").arg(kitName)); - addDebugger(item); - } -} - -const DebuggerItem *DebuggerItemManager::findByCommand(const FileName &command) -{ - foreach (const DebuggerItem &item, m_debuggers) - if (item.command() == command) - return &item; - - return 0; -} - -const DebuggerItem *DebuggerItemManager::findById(const QVariant &id) -{ - foreach (const DebuggerItem &item, m_debuggers) - if (item.id() == id) - return &item; - - return 0; -} - -void DebuggerItemManager::restoreDebuggers() -{ - // Read debuggers from SDK - QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName()); - readDebuggers(FileName::fromString(systemSettingsFile.absolutePath() + QLatin1String(DEBUGGER_FILENAME)), true); - - // Read all debuggers from user file. - readDebuggers(userSettingsFileName(), false); - - // Auto detect current. - autoDetectCdbDebuggers(); - autoDetectGdbOrLldbDebuggers(); - - // Add debuggers from pre-3.x profiles.xml - readLegacyDebuggers(); -} - -void DebuggerItemManager::saveDebuggers() -{ - QTC_ASSERT(m_writer, return); - QVariantMap data; - data.insert(QLatin1String(DEBUGGER_FILE_VERSION_KEY), 1); - - int count = 0; - foreach (const DebuggerItem &item, m_debuggers) { - if (item.isValid()) { - QVariantMap tmp = item.toMap(); - if (tmp.isEmpty()) - continue; - data.insert(QString::fromLatin1(DEBUGGER_DATA_KEY) + QString::number(count), tmp); - ++count; - } - } - data.insert(QLatin1String(DEBUGGER_COUNT_KEY), count); - m_writer->save(data, Core::ICore::mainWindow()); - - // Do not save default debuggers as they are set by the SDK. -} - -QVariant DebuggerItemManager::registerDebugger(const DebuggerItem &item) -{ - QTC_ASSERT(!item.command().isEmpty(), return QVariant()); - QTC_ASSERT(!item.displayName().isEmpty(), return QVariant()); - QTC_ASSERT(item.engineType() != NoEngineType, return QVariant()); - if (findByCommand(item.command())) - return item.id(); - - return addDebugger(item); -} - -void DebuggerItemManager::deregisterDebugger(const DebuggerItem &item) -{ - if (findByCommand(item.command())) - removeDebugger(item.id()); -} - -QVariant DebuggerItemManager::addDebugger(const DebuggerItem &item) -{ - QTC_ASSERT(item.id().isValid(), return QVariant()); - m_debuggers.append(item); - m_model->addDebugger(item); - return item.id(); -} - -void DebuggerItemManager::removeDebugger(const QVariant &id) -{ - bool ok = false; - for (int i = 0, n = m_debuggers.size(); i != n; ++i) { - if (m_debuggers.at(i).id() == id) { - m_debuggers.removeAt(i); - ok = true; - break; - } - } - - QTC_ASSERT(ok, return); - m_model->removeDebugger(id); -} - -QString DebuggerItemManager::uniqueDisplayName(const QString &base) -{ - foreach (const DebuggerItem &item, m_debuggers) - if (item.displayName() == base) - return uniqueDisplayName(base + QLatin1String(" (1)")); - - return base; -} - -void DebuggerItemManager::setItemData(const QVariant &id, const QString &displayName, const FileName &fileName) -{ - for (int i = 0, n = m_debuggers.size(); i != n; ++i) { - DebuggerItem &item = m_debuggers[i]; - if (item.id() == id) { - item.setDisplayName(displayName); - item.setCommand(fileName); - item.reinitializeFromFile(); - emit m_model->updateDebugger(item.id()); - break; - } - } -} - namespace Internal { -static QList describeItem(const DebuggerItem &item) -{ - QList row; - row.append(new QStandardItem(item.displayName())); - row.append(new QStandardItem(item.command().toUserOutput())); - row.append(new QStandardItem(item.engineTypeName())); - row.at(0)->setData(item.id()); - row.at(0)->setEditable(false); - row.at(1)->setEditable(false); - row.at(2)->setEditable(false); - row.at(0)->setSelectable(true); - row.at(1)->setSelectable(true); - row.at(2)->setSelectable(true); - return row; -} - -static QList createRow(const QString &display) -{ - QList row; - row.append(new QStandardItem(display)); - row.append(new QStandardItem()); - row.append(new QStandardItem()); - row.at(0)->setEditable(false); - row.at(1)->setEditable(false); - row.at(2)->setEditable(false); - row.at(0)->setSelectable(false); - row.at(1)->setSelectable(false); - row.at(2)->setSelectable(false); - return row; -} - class DebuggerItemConfigWidget; -// -------------------------------------------------------------------------- -// DebuggerItemModel -// -------------------------------------------------------------------------- - -DebuggerItemModel::DebuggerItemModel(QObject *parent) - : QStandardItemModel(parent) -{ - setColumnCount(3); - - QList row = createRow(tr("Auto-detected")); - m_autoRoot = row.at(0); - appendRow(row); - - row = createRow(tr("Manual")); - m_manualRoot = row.at(0); - appendRow(row); -} - -QVariant DebuggerItemModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { - switch (section) { - case 0: - return tr("Name"); - case 1: - return tr("Path"); - case 2: - return tr("Type"); - } - } - return QVariant(); -} - -QStandardItem *DebuggerItemModel::currentStandardItem() const -{ - return findStandardItemById(m_currentDebugger); -} - -QStandardItem *DebuggerItemModel::findStandardItemById(const QVariant &id) const -{ - for (int i = 0, n = m_autoRoot->rowCount(); i != n; ++i) { - QStandardItem *sitem = m_autoRoot->child(i); - if (sitem->data() == id) - return sitem; - } - for (int i = 0, n = m_manualRoot->rowCount(); i != n; ++i) { - QStandardItem *sitem = m_manualRoot->child(i); - if (sitem->data() == id) - return sitem; - } - return 0; -} - -QModelIndex DebuggerItemModel::currentIndex() const -{ - QStandardItem *current = currentStandardItem(); - return current ? current->index() : QModelIndex(); -} - -QModelIndex DebuggerItemModel::lastIndex() const -{ - int n = m_manualRoot->rowCount(); - QStandardItem *current = m_manualRoot->child(n - 1); - return current ? current->index() : QModelIndex(); -} - -void DebuggerItemModel::markCurrentDirty() -{ - QStandardItem *sitem = currentStandardItem(); - QTC_ASSERT(sitem, return); - QFont font = sitem->font(); - font.setBold(true); - sitem->setFont(font); -} - -void DebuggerItemModel::addDebugger(const DebuggerItem &item) -{ - QTC_ASSERT(item.id().isValid(), return); - QList row = describeItem(item); - (item.isAutoDetected() ? m_autoRoot : m_manualRoot)->appendRow(row); - emit debuggerAdded(item.id(), item.displayName()); -} - -void DebuggerItemModel::removeDebugger(const QVariant &id) -{ - QStandardItem *sitem = findStandardItemById(id); - QTC_ASSERT(sitem, return); - QStandardItem *parent = sitem->parent(); - QTC_ASSERT(parent, return); - // This will trigger a change of m_currentDebugger via changing the - // view selection. - parent->removeRow(sitem->row()); - emit debuggerRemoved(id); -} - -void DebuggerItemModel::updateDebugger(const QVariant &id) -{ - QList debuggers = DebuggerItemManager::debuggers(); - for (int i = 0, n = debuggers.size(); i != n; ++i) { - DebuggerItem &item = debuggers[i]; - if (item.id() == id) { - QStandardItem *sitem = findStandardItemById(id); - QTC_ASSERT(sitem, return); - QStandardItem *parent = sitem->parent(); - QTC_ASSERT(parent, return); - int row = sitem->row(); - QFont font = sitem->font(); - font.setBold(false); - parent->child(row, 0)->setData(item.displayName(), Qt::DisplayRole); - parent->child(row, 0)->setFont(font); - parent->child(row, 1)->setData(item.command().toUserOutput(), Qt::DisplayRole); - parent->child(row, 1)->setFont(font); - parent->child(row, 2)->setData(item.engineTypeName(), Qt::DisplayRole); - parent->child(row, 2)->setFont(font); - emit debuggerUpdated(id, item.displayName()); - return; - } - } -} - -void DebuggerItemModel::setCurrentIndex(const QModelIndex &index) -{ - QStandardItem *sit = itemFromIndex(index); - m_currentDebugger = sit ? sit->data() : QVariant(); -} - // ----------------------------------------------------------------------- // DebuggerKitConfigWidget // ----------------------------------------------------------------------- @@ -1002,296 +204,5 @@ void DebuggerKitConfigWidget::updateComboBox(const QVariant &id) m_comboBox->setCurrentIndex(0); } -// ----------------------------------------------------------------------- -// DebuggerItemConfigWidget -// ----------------------------------------------------------------------- - -class DebuggerItemConfigWidget : public QWidget -{ - Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::DebuggerItemConfigWidget) -public: - explicit DebuggerItemConfigWidget(); - void loadItem(); - void saveItem(); - void connectDirty(); - void disconnectDirty(); - -private: - QLineEdit *m_displayNameLineEdit; - QLabel *m_cdbLabel; - PathChooser *m_binaryChooser; - QLineEdit *m_abis; -}; - -DebuggerItemConfigWidget::DebuggerItemConfigWidget() -{ - m_displayNameLineEdit = new QLineEdit(this); - - m_binaryChooser = new PathChooser(this); - m_binaryChooser->setExpectedKind(PathChooser::ExistingCommand); - m_binaryChooser->setMinimumWidth(400); - - m_cdbLabel = new QLabel(this); - m_cdbLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); - m_cdbLabel->setOpenExternalLinks(true); - - m_abis = new QLineEdit(this); - m_abis->setEnabled(false); - - QFormLayout *formLayout = new QFormLayout(this); - formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); - formLayout->addRow(new QLabel(tr("Name:")), m_displayNameLineEdit); -// formLayout->addRow(new QLabel(tr("Type:")), m_engineTypeComboBox); - formLayout->addRow(m_cdbLabel); - formLayout->addRow(new QLabel(tr("Path:")), m_binaryChooser); - formLayout->addRow(new QLabel(tr("ABIs:")), m_abis); - - connectDirty(); -} - -void DebuggerItemConfigWidget::connectDirty() -{ - DebuggerItemModel *model = DebuggerItemManager::model(); - connect(m_displayNameLineEdit, SIGNAL(textChanged(QString)), - model, SLOT(markCurrentDirty())); - connect(m_binaryChooser, SIGNAL(changed(QString)), - model, SLOT(markCurrentDirty())); -} - -void DebuggerItemConfigWidget::disconnectDirty() -{ - DebuggerItemModel *model = DebuggerItemManager::model(); - disconnect(m_displayNameLineEdit, SIGNAL(textChanged(QString)), - model, SLOT(markCurrentDirty())); - disconnect(m_binaryChooser, SIGNAL(changed(QString)), - model, SLOT(markCurrentDirty())); -} - -void DebuggerItemConfigWidget::loadItem() -{ - DebuggerItemModel *model = DebuggerItemManager::model(); - const DebuggerItem *item = DebuggerItemManager::findById(model->m_currentDebugger); - if (!item) - return; - - disconnectDirty(); - m_displayNameLineEdit->setEnabled(!item->isAutoDetected()); - m_displayNameLineEdit->setText(item->displayName()); - - m_binaryChooser->setEnabled(!item->isAutoDetected()); - m_binaryChooser->setFileName(item->command()); - connectDirty(); - - QString text; - QString versionCommand; - if (item->engineType() == CdbEngineType) { -#ifdef Q_OS_WIN - const bool is64bit = winIs64BitSystem(); -#else - const bool is64bit = false; -#endif - const QString versionString = is64bit ? tr("64-bit version") : tr("32-bit version"); - //: Label text for path configuration. %2 is "x-bit version". - text = tr("

Specify the path to the " - "Windows Console Debugger executable" - " (%2) here.

"""). - arg(QLatin1String(debuggingToolsWikiLinkC), versionString); - versionCommand = QLatin1String("-version"); - } else { - versionCommand = QLatin1String("--version"); - } - - m_cdbLabel->setText(text); - m_cdbLabel->setVisible(!text.isEmpty()); - m_binaryChooser->setCommandVersionArguments(QStringList(versionCommand)); - - m_abis->setText(item->abiNames().join(QLatin1String(", "))); -} - -void DebuggerItemConfigWidget::saveItem() -{ - DebuggerItemModel *model = DebuggerItemManager::model(); - const DebuggerItem *item = DebuggerItemManager::findById(model->m_currentDebugger); - QTC_ASSERT(item, return); - DebuggerItemManager::setItemData(item->id(), m_displayNameLineEdit->text(), - m_binaryChooser->fileName()); -} - -// -------------------------------------------------------------------------- -// DebuggerOptionsPage -// -------------------------------------------------------------------------- - -DebuggerOptionsPage::DebuggerOptionsPage() -{ - m_model = 0; - m_debuggerView = 0; - m_container = 0; - m_addButton = 0; - m_cloneButton = 0; - m_delButton = 0; - - setId(ProjectExplorer::Constants::DEBUGGER_SETTINGS_PAGE_ID); - setDisplayName(tr("Debuggers")); - setCategory(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY); - setDisplayCategory(QCoreApplication::translate("ProjectExplorer", - ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_TR_CATEGORY)); - setCategoryIcon(QLatin1String(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY_ICON)); -} - -QWidget *DebuggerOptionsPage::createPage(QWidget *parent) -{ - m_configWidget = new QWidget(parent); - - m_addButton = new QPushButton(tr("Add"), m_configWidget); - m_cloneButton = new QPushButton(tr("Clone"), m_configWidget); - m_delButton = new QPushButton(tr("Remove"), m_configWidget); - - m_container = new DetailsWidget(m_configWidget); - m_container->setState(DetailsWidget::NoSummary); - m_container->setVisible(false); - - m_model = DebuggerItemManager::model(); - - m_debuggerView = new QTreeView(m_configWidget); - m_debuggerView->setModel(m_model); - m_debuggerView->setUniformRowHeights(true); - m_debuggerView->setSelectionMode(QAbstractItemView::SingleSelection); - m_debuggerView->setSelectionBehavior(QAbstractItemView::SelectRows); - m_debuggerView->expandAll(); - - QHeaderView *header = m_debuggerView->header(); - header->setStretchLastSection(false); - header->setResizeMode(0, QHeaderView::ResizeToContents); - header->setResizeMode(1, QHeaderView::ResizeToContents); - header->setResizeMode(2, QHeaderView::Stretch); - - QVBoxLayout *buttonLayout = new QVBoxLayout(); - buttonLayout->setSpacing(6); - buttonLayout->setContentsMargins(0, 0, 0, 0); - buttonLayout->addWidget(m_addButton); - buttonLayout->addWidget(m_cloneButton); - buttonLayout->addWidget(m_delButton); - buttonLayout->addItem(new QSpacerItem(10, 40, QSizePolicy::Minimum, QSizePolicy::Expanding)); - - QVBoxLayout *verticalLayout = new QVBoxLayout(); - verticalLayout->addWidget(m_debuggerView); - verticalLayout->addWidget(m_container); - - QHBoxLayout *horizontalLayout = new QHBoxLayout(m_configWidget); - horizontalLayout->addLayout(verticalLayout); - horizontalLayout->addLayout(buttonLayout); - - connect(m_debuggerView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - this, SLOT(debuggerSelectionChanged())); - - connect(m_addButton, SIGNAL(clicked()), this, SLOT(addDebugger()), Qt::QueuedConnection); - connect(m_cloneButton, SIGNAL(clicked()), this, SLOT(cloneDebugger()), Qt::QueuedConnection); - connect(m_delButton, SIGNAL(clicked()), this, SLOT(removeDebugger()), Qt::QueuedConnection); - - m_searchKeywords = tr("Debuggers"); - - m_itemConfigWidget = new DebuggerItemConfigWidget; - m_container->setWidget(m_itemConfigWidget); - - updateState(); - - return m_configWidget; -} - -void DebuggerOptionsPage::apply() -{ - m_itemConfigWidget->saveItem(); - debuggerModelChanged(); -} - -void DebuggerOptionsPage::cloneDebugger() -{ - const DebuggerItem *item = DebuggerItemManager::findById(m_model->currentDebugger()); - QTC_ASSERT(item, return); - DebuggerItem newItem; - newItem.setCommand(item->command()); - newItem.setEngineType(item->engineType()); - newItem.setAbis(item->abis()); - newItem.setDisplayName(DebuggerItemManager::uniqueDisplayName(tr("Clone of %1").arg(item->displayName()))); - newItem.setAutoDetected(false); - DebuggerItemManager::addDebugger(newItem); - m_debuggerView->setCurrentIndex(m_model->lastIndex()); -} - -void DebuggerOptionsPage::addDebugger() -{ - DebuggerItem item; - item.setEngineType(NoEngineType); - item.setDisplayName(DebuggerItemManager::uniqueDisplayName(tr("New Debugger"))); - item.setAutoDetected(false); - DebuggerItemManager::addDebugger(item); - m_debuggerView->setCurrentIndex(m_model->lastIndex()); -} - -void DebuggerOptionsPage::removeDebugger() -{ - QVariant id = m_model->currentDebugger(); - DebuggerItemManager::removeDebugger(id); - m_debuggerView->setCurrentIndex(m_model->lastIndex()); -} - -void DebuggerOptionsPage::finish() -{ - // Deleted by settingsdialog. - m_configWidget = 0; - - // Children of m_configWidget. - m_container = 0; - m_debuggerView = 0; - m_addButton = 0; - m_cloneButton = 0; - m_delButton = 0; -} - -bool DebuggerOptionsPage::matches(const QString &s) const -{ - return m_searchKeywords.contains(s, Qt::CaseInsensitive); -} - -void DebuggerOptionsPage::debuggerSelectionChanged() -{ - QTC_ASSERT(m_container, return); - - QModelIndex mi = m_debuggerView->currentIndex(); - mi = mi.sibling(mi.row(), 0); - m_model->setCurrentIndex(mi); - - m_itemConfigWidget->loadItem(); - m_container->setVisible(m_model->m_currentDebugger.isValid()); - updateState(); -} - -void DebuggerOptionsPage::debuggerModelChanged() -{ - QTC_ASSERT(m_container, return); - - m_itemConfigWidget->loadItem(); - m_container->setVisible(m_model->m_currentDebugger.isValid()); - m_debuggerView->setCurrentIndex(m_model->currentIndex()); - updateState(); -} - -void DebuggerOptionsPage::updateState() -{ - if (!m_cloneButton) - return; - - bool canCopy = false; - bool canDelete = false; - - if (const DebuggerItem *item = DebuggerItemManager::findById(m_model->m_currentDebugger)) { - canCopy = item->isValid() && item->canClone(); - canDelete = !item->isAutoDetected(); - canDelete = true; // Do we want to remove auto-detected items? - } - m_cloneButton->setEnabled(canCopy); - m_delButton->setEnabled(canDelete); -} - } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/debuggerkitconfigwidget.h b/src/plugins/debugger/debuggerkitconfigwidget.h index f2ab06695f5..c6a54332180 100644 --- a/src/plugins/debugger/debuggerkitconfigwidget.h +++ b/src/plugins/debugger/debuggerkitconfigwidget.h @@ -52,52 +52,6 @@ QT_END_NAMESPACE namespace Debugger { namespace Internal { -class DebuggerItemConfigWidget; -class DebuggerKitConfigWidget; - -// ----------------------------------------------------------------------- -// DebuggerItemModel -//------------------------------------------------------------------------ -class DebuggerItemModel : public QStandardItemModel -{ - Q_OBJECT - -public: - DebuggerItemModel(QObject *parent); - - QModelIndex currentIndex() const; - QModelIndex lastIndex() const; - void setCurrentIndex(const QModelIndex &index); - QVariant currentDebugger() const { return m_currentDebugger; } - void addDebugger(const DebuggerItem &item); - void removeDebugger(const QVariant &id); - void updateDebugger(const QVariant &id); - -public slots: - void markCurrentDirty(); - -signals: - void debuggerAdded(const QVariant &id, const QString &display); - void debuggerUpdated(const QVariant &id, const QString &display); - void debuggerRemoved(const QVariant &id); - -private: - friend class Debugger::DebuggerKitInformation; - friend class DebuggerKitConfigWidget; - friend class DebuggerItemConfigWidget; - friend class DebuggerOptionsPage; - - QStandardItem *currentStandardItem() const; - QStandardItem *findStandardItemById(const QVariant &id) const; - QVariant headerData(int section, Qt::Orientation orientation, int role) const; - - QVariant m_currentDebugger; - - QStandardItem *m_autoRoot; - QStandardItem *m_manualRoot; - QStringList removed; -}; - // ----------------------------------------------------------------------- // DebuggerKitConfigWidget // ----------------------------------------------------------------------- @@ -135,44 +89,7 @@ private: QPushButton *m_manageButton; }; -// -------------------------------------------------------------------------- -// DebuggerOptionsPage -// -------------------------------------------------------------------------- - -class DebuggerOptionsPage : public Core::IOptionsPage -{ - Q_OBJECT - -public: - DebuggerOptionsPage(); - - QWidget *createPage(QWidget *parent); - void apply(); - void finish(); - bool matches(const QString &) const; - -private slots: - void debuggerSelectionChanged(); - void debuggerModelChanged(); - void updateState(); - void cloneDebugger(); - void addDebugger(); - void removeDebugger(); - -private: - QWidget *m_configWidget; - QString m_searchKeywords; - - DebuggerItemModel *m_model; - DebuggerItemConfigWidget *m_itemConfigWidget; - QTreeView *m_debuggerView; - Utils::DetailsWidget *m_container; - QPushButton *m_addButton; - QPushButton *m_cloneButton; - QPushButton *m_delButton; -}; - } // namespace Internal } // namespace Debugger -#endif // DEBUGGER_DEBUGGERKITINFORMATION_H +#endif // DEBUGGER_DEBUGGERKITCONFIGWIDGET_H diff --git a/src/plugins/debugger/debuggerkitinformation.cpp b/src/plugins/debugger/debuggerkitinformation.cpp index 5436206bcba..7ee98c619db 100644 --- a/src/plugins/debugger/debuggerkitinformation.cpp +++ b/src/plugins/debugger/debuggerkitinformation.cpp @@ -28,309 +28,305 @@ ****************************************************************************/ #include "debuggerkitinformation.h" + +#include "debuggeritemmanager.h" #include "debuggerkitconfigwidget.h" -#include +#include "projectexplorer/toolchain.h" +#include "projectexplorer/projectexplorerconstants.h" + #include +#include -#include -#include +#include -using namespace Debugger::Internal; using namespace ProjectExplorer; using namespace Utils; -static const char DEBUGGER_INFORMATION_COMMAND[] = "Binary"; -static const char DEBUGGER_INFORMATION_DISPLAYNAME[] = "DisplayName"; -static const char DEBUGGER_INFORMATION_ID[] = "Id"; -static const char DEBUGGER_INFORMATION_ENGINETYPE[] = "EngineType"; -static const char DEBUGGER_INFORMATION_AUTODETECTED[] = "AutoDetected"; -static const char DEBUGGER_INFORMATION_ABIS[] = "Abis"; - namespace Debugger { // -------------------------------------------------------------------------- -// DebuggerItem +// DebuggerKitInformation // -------------------------------------------------------------------------- -DebuggerItem::DebuggerItem() +DebuggerKitInformation::DebuggerKitInformation() { - m_id = QUuid::createUuid().toString(); - m_engineType = NoEngineType; - m_isAutoDetected = false; + setObjectName(QLatin1String("DebuggerKitInformation")); + setId(DebuggerKitInformation::id()); + setPriority(28000); } -DebuggerItem::DebuggerItem(const QVariantMap &data) +QVariant DebuggerKitInformation::defaultValue(Kit *k) const { - m_command = FileName::fromUserInput(data.value(QLatin1String(DEBUGGER_INFORMATION_COMMAND)).toString()); - m_id = data.value(QLatin1String(DEBUGGER_INFORMATION_ID)).toString(); - m_displayName = data.value(QLatin1String(DEBUGGER_INFORMATION_DISPLAYNAME)).toString(); - m_isAutoDetected = data.value(QLatin1String(DEBUGGER_INFORMATION_AUTODETECTED), false).toBool(); - m_engineType = DebuggerEngineType(data.value(QLatin1String(DEBUGGER_INFORMATION_ENGINETYPE), - static_cast(NoEngineType)).toInt()); + ToolChain *tc = ToolChainKitInformation::toolChain(k); + QTC_ASSERT(tc, return QVariant()); - foreach (const QString &a, data.value(QLatin1String(DEBUGGER_INFORMATION_ABIS)).toStringList()) { - Abi abi(a); - if (abi.isValid()) - m_abis.append(abi); - } + const Abi toolChainAbi = tc->targetAbi(); + foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) + foreach (const Abi targetAbi, item.abis()) + if (targetAbi.isCompatibleWith(toolChainAbi)) + return item.id(); + + return QVariant(); } -void DebuggerItem::reinitializeFromFile() +void DebuggerKitInformation::setup(Kit *k) { - QProcess proc; - proc.start(m_command.toString(), QStringList() << QLatin1String("--version")); - proc.waitForStarted(); - proc.waitForFinished(); - QByteArray ba = proc.readAll(); - if (ba.contains("gdb")) { - m_engineType = GdbEngineType; - const char needle[] = "This GDB was configured as \""; - // E.g. "--host=i686-pc-linux-gnu --target=arm-unknown-nto-qnx6.5.0". - // or "i686-linux-gnu" - int pos1 = ba.indexOf(needle); - if (pos1 != -1) { - pos1 += int(sizeof(needle)); - int pos2 = ba.indexOf('"', pos1 + 1); - QByteArray target = ba.mid(pos1, pos2 - pos1); - int pos3 = target.indexOf("--target="); - if (pos3 >= 0) - target = target.mid(pos3 + 9); - m_abis.append(Abi::abiFromTargetTriplet(QString::fromLatin1(target))); + // Get one of the available debugger matching the kit's toolchain. + const ToolChain *tc = ToolChainKitInformation::toolChain(k); + const Abi toolChainAbi = tc ? tc->targetAbi() : Abi::hostAbi(); + + // This can be anything (Id, binary path, "auto") + const QVariant rawId = k->value(DebuggerKitInformation::id()); + + enum { + NotDetected, DetectedAutomatically, DetectedByFile, DetectedById + } detection = NotDetected; + DebuggerEngineType autoEngine = NoEngineType; + FileName fileName; + + // With 3.0 we have: + // {75ecf347-f221-44c3-b613-ea1d29929cd4} + // Before we had: + // + // /data/dev/debugger/gdb-git/gdb/gdb + // 1 + // + // Or for force auto-detected CDB + // + // auto + // 4 + // + + if (rawId.isNull()) { + // Initial setup of a kit + detection = NotDetected; + } else if (rawId.type() == QVariant::String) { + detection = DetectedById; + } else { + QMap map = rawId.toMap(); + QString binary = map.value(QLatin1String("Binary")).toString(); + if (binary == QLatin1String("auto")) { + detection = DetectedAutomatically; + autoEngine = DebuggerEngineType(map.value(QLatin1String("EngineType")).toInt()); } else { - // Fallback. - m_abis = Abi::abisOfBinary(m_command); // FIXME: Wrong. + detection = DetectedByFile; + fileName = FileName::fromUserInput(binary); } + } + + const DebuggerItem *bestItem = 0; + DebuggerItem::MatchLevel bestLevel = DebuggerItem::DoesNotMatch; + foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) { + const DebuggerItem *goodItem = 0; + if (detection == DetectedById && item.id() == rawId) + goodItem = &item; + if (detection == DetectedByFile && item.command() == fileName) + goodItem = &item; + if (detection == DetectedAutomatically && item.engineType() == autoEngine) + goodItem = &item; + + if (goodItem) { + DebuggerItem::MatchLevel level = goodItem->matchTarget(toolChainAbi); + if (level > bestLevel) { + bestLevel = level; + bestItem = goodItem; + } + } + } + + // If we have an existing debugger with matching id _and_ + // matching target ABI we are fine. + if (bestItem) { + k->setValue(DebuggerKitInformation::id(), bestItem->id()); return; } - if (ba.contains("lldb") || ba.startsWith("LLDB")) { - m_engineType = LldbEngineType; - m_abis = Abi::abisOfBinary(m_command); + + // We didn't find an existing debugger that matched by whatever + // data we found in the kit (i.e. no id, filename, "auto") + // (or what we found did not match ABI-wise) + // Let's try to pick one with matching ABI. + QVariant bestId; + bestLevel = DebuggerItem::DoesNotMatch; + foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) { + DebuggerItem::MatchLevel level = item.matchTarget(toolChainAbi); + if (level > bestLevel) { + bestLevel = level; + bestId = item.id(); + } + } + + k->setValue(DebuggerKitInformation::id(), bestId); +} + + +// This handles the upgrade path from 2.8 to 3.0 +void DebuggerKitInformation::fix(Kit *k) +{ + // This can be Id, binary path, but not "auto" anymore. + const QVariant rawId = k->value(DebuggerKitInformation::id()); + + if (rawId.isNull()) // No debugger set, that is fine. + return; + + if (rawId.type() == QVariant::String) { + if (!DebuggerItemManager::findById(rawId)) { + qWarning("Unknown debugger id %s in kit %s", + qPrintable(rawId.toString()), qPrintable(k->displayName())); + k->setValue(DebuggerKitInformation::id(), QVariant()); + } + return; // All fine (now). + } + + QMap map = rawId.toMap(); + QString binary = map.value(QLatin1String("Binary")).toString(); + if (binary == QLatin1String("auto")) { + // This should not happen as "auto" is handled by setup() already. + QTC_CHECK(false); + k->setValue(DebuggerKitInformation::id(), QVariant()); return; } - if (ba.startsWith("Python")) { - m_engineType = PdbEngineType; + + FileName fileName = FileName::fromUserInput(binary); + const DebuggerItem *item = DebuggerItemManager::findByCommand(fileName); + if (!item) { + qWarning("Debugger command %s invalid in kit %s", + qPrintable(binary), qPrintable(k->displayName())); + k->setValue(DebuggerKitInformation::id(), QVariant()); return; } - m_engineType = NoEngineType; + + k->setValue(DebuggerKitInformation::id(), item->id()); } -QString DebuggerItem::engineTypeName() const +// Check the configuration errors and return a flag mask. Provide a quick check and +// a verbose one with a list of errors. + +enum DebuggerConfigurationErrors { + NoDebugger = 0x1, + DebuggerNotFound = 0x2, + DebuggerNotExecutable = 0x4, + DebuggerNeedsAbsolutePath = 0x8 +}; + +static unsigned debuggerConfigurationErrors(const Kit *k) { - switch (m_engineType) { - case Debugger::NoEngineType: - return DebuggerOptionsPage::tr("Not recognized"); - case Debugger::GdbEngineType: - return QLatin1String("GDB"); - case Debugger::CdbEngineType: - return QLatin1String("CDB"); - case Debugger::LldbEngineType: - return QLatin1String("LLDB"); - default: - return QString(); + QTC_ASSERT(k, return NoDebugger); + + const DebuggerItem *item = DebuggerKitInformation::debugger(k); + if (!item) + return NoDebugger; + + if (item->command().isEmpty()) + return NoDebugger; + + unsigned result = 0; + const QFileInfo fi = item->command().toFileInfo(); + if (!fi.exists() || fi.isDir()) + result |= DebuggerNotFound; + else if (!fi.isExecutable()) + result |= DebuggerNotExecutable; + + if (!fi.exists() || fi.isDir()) { + if (item->engineType() == NoEngineType) + return NoDebugger; + + // We need an absolute path to be able to locate Python on Windows. + if (item->engineType() == GdbEngineType) + if (const ToolChain *tc = ToolChainKitInformation::toolChain(k)) + if (tc->targetAbi().os() == Abi::WindowsOS && !fi.isAbsolute()) + result |= DebuggerNeedsAbsolutePath; } + return result; } -QStringList DebuggerItem::abiNames() const +const DebuggerItem *DebuggerKitInformation::debugger(const Kit *kit) { - QStringList list; - foreach (const Abi &abi, m_abis) - list.append(abi.toString()); - return list; + QTC_ASSERT(kit, return 0); + const QVariant id = kit->value(DebuggerKitInformation::id()); + return DebuggerItemManager::findById(id); } -QVariantMap DebuggerItem::toMap() const +bool DebuggerKitInformation::isValidDebugger(const Kit *k) { - QVariantMap data; - data.insert(QLatin1String(DEBUGGER_INFORMATION_DISPLAYNAME), m_displayName); - data.insert(QLatin1String(DEBUGGER_INFORMATION_ID), m_id); - data.insert(QLatin1String(DEBUGGER_INFORMATION_COMMAND), m_command.toUserOutput()); - data.insert(QLatin1String(DEBUGGER_INFORMATION_ENGINETYPE), int(m_engineType)); - data.insert(QLatin1String(DEBUGGER_INFORMATION_AUTODETECTED), m_isAutoDetected); - data.insert(QLatin1String(DEBUGGER_INFORMATION_ABIS), abiNames()); - return data; + return debuggerConfigurationErrors(k) == 0; } -void DebuggerItem::setDisplayName(const QString &displayName) +QList DebuggerKitInformation::validateDebugger(const Kit *k) { - m_displayName = displayName; -} + QList result; -void DebuggerItem::setEngineType(const DebuggerEngineType &engineType) -{ - m_engineType = engineType; -} + const unsigned errors = debuggerConfigurationErrors(k); + if (!errors) + return result; -void DebuggerItem::setCommand(const Utils::FileName &command) -{ - m_command = command; -} + QString path; + if (const DebuggerItem *item = debugger(k)) + path = item->command().toUserOutput(); -void DebuggerItem::setAutoDetected(bool isAutoDetected) -{ - m_isAutoDetected = isAutoDetected; -} + const Core::Id id = ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM; + if (errors & NoDebugger) + result << Task(Task::Warning, tr("No debugger set up."), FileName(), -1, id); -void DebuggerItem::setAbis(const QList &abis) -{ - m_abis = abis; -} + if (errors & DebuggerNotFound) + result << Task(Task::Error, tr("Debugger '%1' not found.").arg(path), + FileName(), -1, id); + if (errors & DebuggerNotExecutable) + result << Task(Task::Error, tr("Debugger '%1' not executable.").arg(path), FileName(), -1, id); -void DebuggerItem::setAbi(const Abi &abi) -{ - m_abis.clear(); - m_abis.append(abi); -} - -static DebuggerItem::MatchLevel matchSingle(const Abi &debuggerAbi, const Abi &targetAbi) -{ - if (debuggerAbi.architecture() != Abi::UnknownArchitecture - && debuggerAbi.architecture() != targetAbi.architecture()) - return DebuggerItem::DoesNotMatch; - - if (debuggerAbi.os() != Abi::UnknownOS - && debuggerAbi.os() != targetAbi.os()) - return DebuggerItem::DoesNotMatch; - - if (debuggerAbi.binaryFormat() != Abi::UnknownFormat - && debuggerAbi.binaryFormat() != targetAbi.binaryFormat()) - return DebuggerItem::DoesNotMatch; - - if (debuggerAbi.os() == Abi::WindowsOS) { - if (debuggerAbi.osFlavor() == Abi::WindowsMSysFlavor && targetAbi.osFlavor() != Abi::WindowsMSysFlavor) - return DebuggerItem::DoesNotMatch; - if (debuggerAbi.osFlavor() != Abi::WindowsMSysFlavor && targetAbi.osFlavor() == Abi::WindowsMSysFlavor) - return DebuggerItem::DoesNotMatch; + if (errors & DebuggerNeedsAbsolutePath) { + const QString message = + tr("The debugger location must be given as an " + "absolute path (%1).").arg(path); + result << Task(Task::Error, message, FileName(), -1, id); } - - if (debuggerAbi.wordWidth() == 64 && targetAbi.wordWidth() == 32) - return DebuggerItem::MatchesSomewhat; - if (debuggerAbi.wordWidth() != 0 && debuggerAbi.wordWidth() != targetAbi.wordWidth()) - return DebuggerItem::DoesNotMatch; - - return DebuggerItem::MatchesPerfectly; + return result; } -DebuggerItem::MatchLevel DebuggerItem::matchTarget(const Abi &targetAbi) const +KitConfigWidget *DebuggerKitInformation::createConfigWidget(Kit *k) const { - MatchLevel bestMatch = DoesNotMatch; - foreach (const Abi &debuggerAbi, m_abis) { - MatchLevel currentMatch = matchSingle(debuggerAbi, targetAbi); - if (currentMatch > bestMatch) - bestMatch = currentMatch; - } - return bestMatch; + return new Internal::DebuggerKitConfigWidget(k, this); } -bool Debugger::DebuggerItem::isValid() const +KitInformation::ItemList DebuggerKitInformation::toUserOutput(const Kit *k) const { - return m_engineType != NoEngineType; + return ItemList() << qMakePair(tr("Debugger"), displayString(k)); } -} // namespace Debugger; - -#ifdef WITH_TESTS - -# include -# include "debuggerplugin.h" - -void Debugger::DebuggerPlugin::testDebuggerMatching_data() +FileName DebuggerKitInformation::debuggerCommand(const ProjectExplorer::Kit *k) { - QTest::addColumn("debugger"); - QTest::addColumn("target"); - QTest::addColumn("result"); - - QTest::newRow("Invalid data") - << QStringList() - << QString() - << int(DebuggerItem::DoesNotMatch); - QTest::newRow("Invalid debugger") - << QStringList() - << QString::fromLatin1("x86-linux-generic-elf-32bit") - << int(DebuggerItem::DoesNotMatch); - QTest::newRow("Invalid target") - << (QStringList() << QLatin1String("x86-linux-generic-elf-32bit")) - << QString() - << int(DebuggerItem::DoesNotMatch); - - QTest::newRow("Fuzzy match 1") - << (QStringList() << QLatin1String("unknown-unknown-unknown-unknown-0bit")) - << QString::fromLatin1("x86-linux-generic-elf-32bit") - << int(DebuggerItem::MatchesPerfectly); // Is this the expected behavior? - QTest::newRow("Fuzzy match 2") - << (QStringList() << QLatin1String("unknown-unknown-unknown-unknown-0bit")) - << QString::fromLatin1("arm-windows-msys-pe-64bit") - << int(DebuggerItem::MatchesPerfectly); // Is this the expected behavior? - - QTest::newRow("Architecture mismatch") - << (QStringList() << QLatin1String("x86-linux-generic-elf-32bit")) - << QString::fromLatin1("arm-linux-generic-elf-32bit") - << int(DebuggerItem::DoesNotMatch); - QTest::newRow("OS mismatch") - << (QStringList() << QLatin1String("x86-linux-generic-elf-32bit")) - << QString::fromLatin1("x86-macosx-generic-elf-32bit") - << int(DebuggerItem::DoesNotMatch); - QTest::newRow("Format mismatch") - << (QStringList() << QLatin1String("x86-linux-generic-elf-32bit")) - << QString::fromLatin1("x86-linux-generic-pe-32bit") - << int(DebuggerItem::DoesNotMatch); - - QTest::newRow("Linux perfect match") - << (QStringList() << QLatin1String("x86-linux-generic-elf-32bit")) - << QString::fromLatin1("x86-linux-generic-elf-32bit") - << int(DebuggerItem::MatchesPerfectly); - QTest::newRow("Linux match") - << (QStringList() << QLatin1String("x86-linux-generic-elf-64bit")) - << QString::fromLatin1("x86-linux-generic-elf-32bit") - << int(DebuggerItem::MatchesSomewhat); - - QTest::newRow("Windows perfect match 1") - << (QStringList() << QLatin1String("x86-windows-msvc2013-pe-64bit")) - << QString::fromLatin1("x86-windows-msvc2013-pe-64bit") - << int(DebuggerItem::MatchesPerfectly); - QTest::newRow("Windows perfect match 2") - << (QStringList() << QLatin1String("x86-windows-msvc2013-pe-64bit")) - << QString::fromLatin1("x86-windows-msvc2012-pe-64bit") - << int(DebuggerItem::MatchesPerfectly); - QTest::newRow("Windows match 1") - << (QStringList() << QLatin1String("x86-windows-msvc2013-pe-64bit")) - << QString::fromLatin1("x86-windows-msvc2013-pe-32bit") - << int(DebuggerItem::MatchesSomewhat); - QTest::newRow("Windows match 2") - << (QStringList() << QLatin1String("x86-windows-msvc2013-pe-64bit")) - << QString::fromLatin1("x86-windows-msvc2012-pe-32bit") - << int(DebuggerItem::MatchesSomewhat); - QTest::newRow("Windows mismatch on word size") - << (QStringList() << QLatin1String("x86-windows-msvc2013-pe-32bit")) - << QString::fromLatin1("x86-windows-msvc2013-pe-64bit") - << int(DebuggerItem::DoesNotMatch); - QTest::newRow("Windows mismatch on osflavor 1") - << (QStringList() << QLatin1String("x86-windows-msvc2013-pe-32bit")) - << QString::fromLatin1("x86-windows-msys-pe-64bit") - << int(DebuggerItem::DoesNotMatch); - QTest::newRow("Windows mismatch on osflavor 2") - << (QStringList() << QLatin1String("x86-windows-msys-pe-32bit")) - << QString::fromLatin1("x86-windows-msvc2010-pe-64bit") - << int(DebuggerItem::DoesNotMatch); + const DebuggerItem *item = debugger(k); + QTC_ASSERT(item, return FileName()); + return item->command(); } -void Debugger::DebuggerPlugin::testDebuggerMatching() +DebuggerEngineType DebuggerKitInformation::engineType(const ProjectExplorer::Kit *k) { - QFETCH(QStringList, debugger); - QFETCH(QString, target); - QFETCH(int, result); - - DebuggerItem::MatchLevel expectedLevel = static_cast(result); - - QList debuggerAbis; - foreach (const QString &abi, debugger) - debuggerAbis << Abi(abi); - - DebuggerItem item; - item.setAbis(debuggerAbis); - - DebuggerItem::MatchLevel level = item.matchTarget(Abi(target)); - - QCOMPARE(expectedLevel, level); + const DebuggerItem *item = debugger(k); + QTC_ASSERT(item, return NoEngineType); + return item->engineType(); } -#endif + +QString DebuggerKitInformation::displayString(const Kit *k) +{ + const DebuggerItem *item = debugger(k); + if (!item) + return tr("No Debugger"); + QString binary = item->command().toUserOutput(); + QString name = tr("%1 Engine").arg(item->engineTypeName()); + return binary.isEmpty() ? tr("%1 ").arg(name) : tr("%1 using \"%2\"").arg(name, binary); +} + +void DebuggerKitInformation::setDebugger(Kit *k, const QVariant &id) +{ + // Only register reasonably complete debuggers. + QTC_ASSERT(DebuggerItemManager::findById(id), return); + k->setValue(DebuggerKitInformation::id(), id); +} + +Core::Id DebuggerKitInformation::id() +{ + return "Debugger.Information"; +} + +} // namespace Debugger diff --git a/src/plugins/debugger/debuggerkitinformation.h b/src/plugins/debugger/debuggerkitinformation.h index 4a185d79e3d..3e03e19d2e7 100644 --- a/src/plugins/debugger/debuggerkitinformation.h +++ b/src/plugins/debugger/debuggerkitinformation.h @@ -32,6 +32,7 @@ #include "debugger_global.h" #include "debuggerconstants.h" +#include "debuggeritem.h" #include #include @@ -40,102 +41,6 @@ namespace Debugger { -namespace Internal { class DebuggerItemModel; } - -// ----------------------------------------------------------------------- -// DebuggerItem -// ----------------------------------------------------------------------- - -class DEBUGGER_EXPORT DebuggerItem -{ -public: - DebuggerItem(); - DebuggerItem(const QVariantMap &data); - - bool canClone() const { return true; } - bool isValid() const; - QString engineTypeName() const; - - QVariantMap toMap() const; - void reinitializeFromFile(); - - QVariant id() const { return m_id; } - - QString displayName() const { return m_displayName; } - void setDisplayName(const QString &displayName); - - DebuggerEngineType engineType() const { return m_engineType; } - void setEngineType(const DebuggerEngineType &engineType); - - Utils::FileName command() const { return m_command; } - void setCommand(const Utils::FileName &command); - - bool isAutoDetected() const { return m_isAutoDetected; } - void setAutoDetected(bool isAutoDetected); - - QList abis() const { return m_abis; } - void setAbis(const QList &abis); - void setAbi(const ProjectExplorer::Abi &abi); - - enum MatchLevel { DoesNotMatch, MatchesSomewhat, MatchesPerfectly }; - MatchLevel matchTarget(const ProjectExplorer::Abi &targetAbi) const; - - QStringList abiNames() const; - -private: - QVariant m_id; - QString m_displayName; - DebuggerEngineType m_engineType; - Utils::FileName m_command; - bool m_isAutoDetected; - QList m_abis; -}; - -// ----------------------------------------------------------------------- -// DebuggerItemManager -// ----------------------------------------------------------------------- - -class DEBUGGER_EXPORT DebuggerItemManager : public QObject -{ - Q_OBJECT - -public: - static QObject *instance(); - ~DebuggerItemManager(); - - static QList debuggers(); - static Debugger::Internal::DebuggerItemModel *model(); - - static QVariant registerDebugger(const DebuggerItem &item); - static void deregisterDebugger(const DebuggerItem &item); - - static const DebuggerItem *findByCommand(const Utils::FileName &command); - static const DebuggerItem *findById(const QVariant &id); - - static void restoreDebuggers(); - static QString uniqueDisplayName(const QString &base); - static void setItemData(const QVariant &id, const QString& displayName, const Utils::FileName &fileName); - - static void removeDebugger(const QVariant &id); - static QVariant addDebugger(const DebuggerItem &item); - -public slots: - void saveDebuggers(); - -private: - explicit DebuggerItemManager(QObject *parent = 0); - static void autoDetectGdbOrLldbDebuggers(); - static void autoDetectCdbDebuggers(); - static void readLegacyDebuggers(); - - static Utils::PersistentSettingsWriter *m_writer; - static QList m_debuggers; - static Debugger::Internal::DebuggerItemModel *m_model; - - friend class Internal::DebuggerItemModel; - friend class DebuggerPlugin; // Enable constrcutor for DebuggerPlugin -}; - class DEBUGGER_EXPORT DebuggerKitInformation : public ProjectExplorer::KitInformation { Q_OBJECT diff --git a/src/plugins/debugger/debuggeroptionspage.cpp b/src/plugins/debugger/debuggeroptionspage.cpp new file mode 100644 index 00000000000..893b28582b0 --- /dev/null +++ b/src/plugins/debugger/debuggeroptionspage.cpp @@ -0,0 +1,350 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "debuggeroptionspage.h" + +#include "debuggeritemmanager.h" +#include "debuggeritemmodel.h" + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Utils; + +namespace Debugger { +namespace Internal { + +static const char debuggingToolsWikiLinkC[] = "http://qt-project.org/wiki/Qt_Creator_Windows_Debugging"; + +// ----------------------------------------------------------------------- +// DebuggerItemConfigWidget +// ----------------------------------------------------------------------- + +class DebuggerItemConfigWidget : public QWidget +{ + Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::DebuggerItemConfigWidget) + +public: + explicit DebuggerItemConfigWidget(); + void loadItem(); + void saveItem(); + void connectDirty(); + void disconnectDirty(); + +private: + QLineEdit *m_displayNameLineEdit; + QLabel *m_cdbLabel; + PathChooser *m_binaryChooser; + QLineEdit *m_abis; +}; + +DebuggerItemConfigWidget::DebuggerItemConfigWidget() +{ + m_displayNameLineEdit = new QLineEdit(this); + + m_binaryChooser = new PathChooser(this); + m_binaryChooser->setExpectedKind(PathChooser::ExistingCommand); + m_binaryChooser->setMinimumWidth(400); + + m_cdbLabel = new QLabel(this); + m_cdbLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); + m_cdbLabel->setOpenExternalLinks(true); + + m_abis = new QLineEdit(this); + m_abis->setEnabled(false); + + QFormLayout *formLayout = new QFormLayout(this); + formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); + formLayout->addRow(new QLabel(tr("Name:")), m_displayNameLineEdit); +// formLayout->addRow(new QLabel(tr("Type:")), m_engineTypeComboBox); + formLayout->addRow(m_cdbLabel); + formLayout->addRow(new QLabel(tr("Path:")), m_binaryChooser); + formLayout->addRow(new QLabel(tr("ABIs:")), m_abis); + + connectDirty(); +} + +void DebuggerItemConfigWidget::connectDirty() +{ + DebuggerItemModel *model = DebuggerItemManager::model(); + connect(m_displayNameLineEdit, SIGNAL(textChanged(QString)), + model, SLOT(markCurrentDirty())); + connect(m_binaryChooser, SIGNAL(changed(QString)), + model, SLOT(markCurrentDirty())); +} + +void DebuggerItemConfigWidget::disconnectDirty() +{ + DebuggerItemModel *model = DebuggerItemManager::model(); + disconnect(m_displayNameLineEdit, SIGNAL(textChanged(QString)), + model, SLOT(markCurrentDirty())); + disconnect(m_binaryChooser, SIGNAL(changed(QString)), + model, SLOT(markCurrentDirty())); +} + +void DebuggerItemConfigWidget::loadItem() +{ + DebuggerItemModel *model = DebuggerItemManager::model(); + const DebuggerItem *item = DebuggerItemManager::findById(model->currentDebugger()); + if (!item) + return; + + disconnectDirty(); + m_displayNameLineEdit->setEnabled(!item->isAutoDetected()); + m_displayNameLineEdit->setText(item->displayName()); + + m_binaryChooser->setEnabled(!item->isAutoDetected()); + m_binaryChooser->setFileName(item->command()); + connectDirty(); + + QString text; + QString versionCommand; + if (item->engineType() == CdbEngineType) { +#ifdef Q_OS_WIN + const bool is64bit = winIs64BitSystem(); +#else + const bool is64bit = false; +#endif + const QString versionString = is64bit ? tr("64-bit version") : tr("32-bit version"); + //: Label text for path configuration. %2 is "x-bit version". + text = tr("

Specify the path to the " + "Windows Console Debugger executable" + " (%2) here.

"""). + arg(QLatin1String(debuggingToolsWikiLinkC), versionString); + versionCommand = QLatin1String("-version"); + } else { + versionCommand = QLatin1String("--version"); + } + + m_cdbLabel->setText(text); + m_cdbLabel->setVisible(!text.isEmpty()); + m_binaryChooser->setCommandVersionArguments(QStringList(versionCommand)); + + m_abis->setText(item->abiNames().join(QLatin1String(", "))); +} + +void DebuggerItemConfigWidget::saveItem() +{ + DebuggerItemModel *model = DebuggerItemManager::model(); + const DebuggerItem *item = DebuggerItemManager::findById(model->currentDebugger()); + QTC_ASSERT(item, return); + DebuggerItemManager::setItemData(item->id(), m_displayNameLineEdit->text(), + m_binaryChooser->fileName()); +} + +// -------------------------------------------------------------------------- +// DebuggerOptionsPage +// -------------------------------------------------------------------------- + +DebuggerOptionsPage::DebuggerOptionsPage() +{ + m_model = 0; + m_debuggerView = 0; + m_container = 0; + m_addButton = 0; + m_cloneButton = 0; + m_delButton = 0; + + setId(ProjectExplorer::Constants::DEBUGGER_SETTINGS_PAGE_ID); + setDisplayName(tr("Debuggers")); + setCategory(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY); + setDisplayCategory(QCoreApplication::translate("ProjectExplorer", + ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_TR_CATEGORY)); + setCategoryIcon(QLatin1String(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY_ICON)); +} + +QWidget *DebuggerOptionsPage::createPage(QWidget *parent) +{ + m_configWidget = new QWidget(parent); + + m_addButton = new QPushButton(tr("Add"), m_configWidget); + m_cloneButton = new QPushButton(tr("Clone"), m_configWidget); + m_delButton = new QPushButton(tr("Remove"), m_configWidget); + + m_container = new DetailsWidget(m_configWidget); + m_container->setState(DetailsWidget::NoSummary); + m_container->setVisible(false); + + m_model = DebuggerItemManager::model(); + + m_debuggerView = new QTreeView(m_configWidget); + m_debuggerView->setModel(m_model); + m_debuggerView->setUniformRowHeights(true); + m_debuggerView->setSelectionMode(QAbstractItemView::SingleSelection); + m_debuggerView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_debuggerView->expandAll(); + + QHeaderView *header = m_debuggerView->header(); + header->setStretchLastSection(false); + header->setResizeMode(0, QHeaderView::ResizeToContents); + header->setResizeMode(1, QHeaderView::ResizeToContents); + header->setResizeMode(2, QHeaderView::Stretch); + + QVBoxLayout *buttonLayout = new QVBoxLayout(); + buttonLayout->setSpacing(6); + buttonLayout->setContentsMargins(0, 0, 0, 0); + buttonLayout->addWidget(m_addButton); + buttonLayout->addWidget(m_cloneButton); + buttonLayout->addWidget(m_delButton); + buttonLayout->addItem(new QSpacerItem(10, 40, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + QVBoxLayout *verticalLayout = new QVBoxLayout(); + verticalLayout->addWidget(m_debuggerView); + verticalLayout->addWidget(m_container); + + QHBoxLayout *horizontalLayout = new QHBoxLayout(m_configWidget); + horizontalLayout->addLayout(verticalLayout); + horizontalLayout->addLayout(buttonLayout); + + connect(m_debuggerView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), + this, SLOT(debuggerSelectionChanged())); + + connect(m_addButton, SIGNAL(clicked()), this, SLOT(addDebugger()), Qt::QueuedConnection); + connect(m_cloneButton, SIGNAL(clicked()), this, SLOT(cloneDebugger()), Qt::QueuedConnection); + connect(m_delButton, SIGNAL(clicked()), this, SLOT(removeDebugger()), Qt::QueuedConnection); + + m_searchKeywords = tr("Debuggers"); + + m_itemConfigWidget = new DebuggerItemConfigWidget; + m_container->setWidget(m_itemConfigWidget); + + updateState(); + + return m_configWidget; +} + +void DebuggerOptionsPage::apply() +{ + m_itemConfigWidget->saveItem(); + debuggerModelChanged(); +} + +void DebuggerOptionsPage::cloneDebugger() +{ + const DebuggerItem *item = DebuggerItemManager::findById(m_model->currentDebugger()); + QTC_ASSERT(item, return); + DebuggerItem newItem; + newItem.setCommand(item->command()); + newItem.setEngineType(item->engineType()); + newItem.setAbis(item->abis()); + newItem.setDisplayName(DebuggerItemManager::uniqueDisplayName(tr("Clone of %1").arg(item->displayName()))); + newItem.setAutoDetected(false); + DebuggerItemManager::addDebugger(newItem); + m_debuggerView->setCurrentIndex(m_model->lastIndex()); +} + +void DebuggerOptionsPage::addDebugger() +{ + DebuggerItem item; + item.setEngineType(NoEngineType); + item.setDisplayName(DebuggerItemManager::uniqueDisplayName(tr("New Debugger"))); + item.setAutoDetected(false); + DebuggerItemManager::addDebugger(item); + m_debuggerView->setCurrentIndex(m_model->lastIndex()); +} + +void DebuggerOptionsPage::removeDebugger() +{ + QVariant id = m_model->currentDebugger(); + DebuggerItemManager::removeDebugger(id); + m_debuggerView->setCurrentIndex(m_model->lastIndex()); +} + +void DebuggerOptionsPage::finish() +{ + // Deleted by settingsdialog. + m_configWidget = 0; + + // Children of m_configWidget. + m_container = 0; + m_debuggerView = 0; + m_addButton = 0; + m_cloneButton = 0; + m_delButton = 0; +} + +bool DebuggerOptionsPage::matches(const QString &s) const +{ + return m_searchKeywords.contains(s, Qt::CaseInsensitive); +} + +void DebuggerOptionsPage::debuggerSelectionChanged() +{ + QTC_ASSERT(m_container, return); + + QModelIndex mi = m_debuggerView->currentIndex(); + mi = mi.sibling(mi.row(), 0); + m_model->setCurrentIndex(mi); + + m_itemConfigWidget->loadItem(); + m_container->setVisible(m_model->currentDebugger().isValid()); + updateState(); +} + +void DebuggerOptionsPage::debuggerModelChanged() +{ + QTC_ASSERT(m_container, return); + + m_itemConfigWidget->loadItem(); + m_container->setVisible(m_model->currentDebugger().isValid()); + m_debuggerView->setCurrentIndex(m_model->currentIndex()); + updateState(); +} + +void DebuggerOptionsPage::updateState() +{ + if (!m_cloneButton) + return; + + bool canCopy = false; + bool canDelete = false; + + if (const DebuggerItem *item = DebuggerItemManager::findById(m_model->currentDebugger())) { + canCopy = item->isValid() && item->canClone(); + canDelete = !item->isAutoDetected(); + canDelete = true; // Do we want to remove auto-detected items? + } + m_cloneButton->setEnabled(canCopy); + m_delButton->setEnabled(canDelete); +} + +} // namespace Internal +} // namespace Debugger diff --git a/src/plugins/debugger/debuggeroptionspage.h b/src/plugins/debugger/debuggeroptionspage.h new file mode 100644 index 00000000000..fd1782f4b47 --- /dev/null +++ b/src/plugins/debugger/debuggeroptionspage.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef DEBUGGER_DEBUGGEROPTIONSPAGE_H +#define DEBUGGER_DEBUGGEROPTIONSPAGE_H + +#include + +QT_BEGIN_NAMESPACE +class QPushButton; +class QTreeView; +class QWidget; +QT_END_NAMESPACE + +namespace Utils { class DetailsWidget; } + +namespace Debugger { +namespace Internal { + +class DebuggerItemModel; +class DebuggerItemConfigWidget; +class DebuggerKitConfigWidget; + +// -------------------------------------------------------------------------- +// DebuggerOptionsPage +// -------------------------------------------------------------------------- + +class DebuggerOptionsPage : public Core::IOptionsPage +{ + Q_OBJECT + +public: + DebuggerOptionsPage(); + + QWidget *createPage(QWidget *parent); + void apply(); + void finish(); + bool matches(const QString &) const; + +private slots: + void debuggerSelectionChanged(); + void debuggerModelChanged(); + void updateState(); + void cloneDebugger(); + void addDebugger(); + void removeDebugger(); + +private: + QWidget *m_configWidget; + QString m_searchKeywords; + + DebuggerItemModel *m_model; + DebuggerItemConfigWidget *m_itemConfigWidget; + QTreeView *m_debuggerView; + Utils::DetailsWidget *m_container; + QPushButton *m_addButton; + QPushButton *m_cloneButton; + QPushButton *m_delButton; +}; + +} // namespace Internal +} // namespace Debugger + +#endif // DEBUGGER_DEBUGGEROPTIONSPAGE_H diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index a01bdc9b636..67953afcfca 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -36,11 +36,13 @@ #include "debuggerkitconfigwidget.h" #include "debuggerdialogs.h" #include "debuggerengine.h" +#include "debuggeritemmanager.h" #include "debuggermainwindow.h" #include "debuggerrunner.h" #include "debuggerrunconfigurationaspect.h" #include "debuggerruncontrolfactory.h" #include "debuggerstringutils.h" +#include "debuggeroptionspage.h" #include "debuggerkitinformation.h" #include "memoryagent.h" #include "breakhandler.h" diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp index ebfca0293fc..1eaa690bc99 100644 --- a/src/plugins/ios/iosconfigurations.cpp +++ b/src/plugins/ios/iosconfigurations.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/src/plugins/qnx/blackberryconfiguration.cpp b/src/plugins/qnx/blackberryconfiguration.cpp index 78b01a30d88..cc45468e539 100644 --- a/src/plugins/qnx/blackberryconfiguration.cpp +++ b/src/plugins/qnx/blackberryconfiguration.cpp @@ -45,6 +45,7 @@ #include +#include #include #include From 5e1e8eaae01df4df7a3172791c3165303472bfe3 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 28 Oct 2013 12:51:35 +0100 Subject: [PATCH 76/84] Debugger: Add signals to DebuggerItemManager Change-Id: Icbd14a683d1a5ec53aa2d2337d43a86c26bccac9 Reviewed-by: hjk --- src/plugins/debugger/debuggeritem.cpp | 8 ++++++++ src/plugins/debugger/debuggeritem.h | 2 ++ src/plugins/debugger/debuggeritemmanager.cpp | 20 ++++++++++++++++---- src/plugins/debugger/debuggeritemmanager.h | 6 ++++++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp index 9ac30bbb7d4..33396b84bef 100644 --- a/src/plugins/debugger/debuggeritem.cpp +++ b/src/plugins/debugger/debuggeritem.cpp @@ -140,6 +140,14 @@ QStringList DebuggerItem::abiNames() const return list; } +bool DebuggerItem::operator==(const DebuggerItem &other) const +{ + return m_id == other.m_id + && m_isAutoDetected == other.m_isAutoDetected + && m_command == other.m_command + && m_abis == other.m_abis; +} + QVariantMap DebuggerItem::toMap() const { QVariantMap data; diff --git a/src/plugins/debugger/debuggeritem.h b/src/plugins/debugger/debuggeritem.h index 9809da22c7b..c2ef2a6fec7 100644 --- a/src/plugins/debugger/debuggeritem.h +++ b/src/plugins/debugger/debuggeritem.h @@ -82,6 +82,8 @@ public: QStringList abiNames() const; + bool operator==(const DebuggerItem &other) const; + private: QVariant m_id; QString m_displayName; diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp index e9df26be1ef..55ea0762447 100644 --- a/src/plugins/debugger/debuggeritemmanager.cpp +++ b/src/plugins/debugger/debuggeritemmanager.cpp @@ -344,16 +344,28 @@ void DebuggerItemManager::saveDebuggers() QVariant DebuggerItemManager::registerDebugger(const DebuggerItem &item) { - if (findByCommand(item.command())) - return item.id(); + if (const DebuggerItem *orig = findById(item.id())) { + QVariant id = orig->id(); + if (*orig == item) + return id; + removeDebugger(id); + addDebugger(item); + emit m_instance->debuggerUpdated(id); + return id; + } - return addDebugger(item); + QVariant id = addDebugger(item); + emit m_instance->debuggerAdded(id); + return id; } void DebuggerItemManager::deregisterDebugger(const DebuggerItem &item) { - if (findByCommand(item.command())) + if (findById(item.id())) { + emit m_instance->aboutToRemoveDebugger(item.id()); removeDebugger(item.id()); + emit m_instance->removeDebugger(item.id()); + } } QVariant DebuggerItemManager::addDebugger(const DebuggerItem &item) diff --git a/src/plugins/debugger/debuggeritemmanager.h b/src/plugins/debugger/debuggeritemmanager.h index 057cfd58b12..63936354d86 100644 --- a/src/plugins/debugger/debuggeritemmanager.h +++ b/src/plugins/debugger/debuggeritemmanager.h @@ -70,6 +70,12 @@ public: static void removeDebugger(const QVariant &id); static QVariant addDebugger(const DebuggerItem &item); +signals: + void debuggerAdded(const QVariant &id); + void aboutToRemoveDebugger(const QVariant &id); + void debuggerRemoved(const QVariant &id); + void debuggerUpdated(const QVariant &id); + public slots: void saveDebuggers(); From b17e8e3061aa449ae4cfd549228111c9c745b410 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 28 Oct 2013 14:05:12 +0100 Subject: [PATCH 77/84] Debugger: Rewrite logic to use signals on DebuggerItemManager Change-Id: I82e1cd3cca9cc2d79366e1af054640dadebf7871 Reviewed-by: hjk --- src/plugins/debugger/debuggeritemmanager.cpp | 43 ++++++------------- src/plugins/debugger/debuggeritemmanager.h | 4 +- src/plugins/debugger/debuggeritemmodel.cpp | 31 +++++++++++-- src/plugins/debugger/debuggeritemmodel.h | 17 +++----- .../debugger/debuggerkitconfigwidget.cpp | 29 +++++++------ .../debugger/debuggerkitconfigwidget.h | 6 +-- src/plugins/debugger/debuggeroptionspage.cpp | 28 ++++++------ 7 files changed, 79 insertions(+), 79 deletions(-) diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp index 55ea0762447..f5f0fead2ea 100644 --- a/src/plugins/debugger/debuggeritemmanager.cpp +++ b/src/plugins/debugger/debuggeritemmanager.cpp @@ -101,7 +101,6 @@ static void readDebuggers(const FileName &fileName, bool isSystem) } QList DebuggerItemManager::m_debuggers; -Internal::DebuggerItemModel* DebuggerItemManager::m_model = 0; PersistentSettingsWriter * DebuggerItemManager::m_writer = 0; DebuggerItemManager::DebuggerItemManager(QObject *parent) @@ -109,7 +108,6 @@ DebuggerItemManager::DebuggerItemManager(QObject *parent) { m_instance = this; m_writer = new PersistentSettingsWriter(userSettingsFileName(), QLatin1String("QtCreatorDebugger")); - m_model = new Debugger::Internal::DebuggerItemModel(this); connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()), this, SLOT(saveDebuggers())); } @@ -131,11 +129,6 @@ QList DebuggerItemManager::debuggers() return m_debuggers; } -Internal::DebuggerItemModel *DebuggerItemManager::model() -{ - return m_model; -} - void DebuggerItemManager::autoDetectCdbDebuggers() { QList cdbs; @@ -344,39 +337,28 @@ void DebuggerItemManager::saveDebuggers() QVariant DebuggerItemManager::registerDebugger(const DebuggerItem &item) { - if (const DebuggerItem *orig = findById(item.id())) { - QVariant id = orig->id(); - if (*orig == item) - return id; - removeDebugger(id); - addDebugger(item); - emit m_instance->debuggerUpdated(id); - return id; - } + QTC_ASSERT(!findById(item.id()), return item.id()); - QVariant id = addDebugger(item); - emit m_instance->debuggerAdded(id); - return id; + return addDebugger(item); } void DebuggerItemManager::deregisterDebugger(const DebuggerItem &item) { - if (findById(item.id())) { - emit m_instance->aboutToRemoveDebugger(item.id()); + QTC_ASSERT(!item.command().isEmpty(), return); + QTC_ASSERT(!item.displayName().isEmpty(), return); + QTC_ASSERT(item.engineType() != NoEngineType, return); + + if (findById(item.id())) removeDebugger(item.id()); - emit m_instance->removeDebugger(item.id()); - } } QVariant DebuggerItemManager::addDebugger(const DebuggerItem &item) { - QTC_ASSERT(!item.command().isEmpty(), return QVariant()); - QTC_ASSERT(!item.displayName().isEmpty(), return QVariant()); - QTC_ASSERT(item.engineType() != NoEngineType, return QVariant()); QTC_ASSERT(item.id().isValid(), return QVariant()); m_debuggers.append(item); - m_model->addDebugger(item); - return item.id(); + QVariant id = item.id(); + emit m_instance->debuggerAdded(id); + return id; } void DebuggerItemManager::removeDebugger(const QVariant &id) @@ -384,14 +366,15 @@ void DebuggerItemManager::removeDebugger(const QVariant &id) bool ok = false; for (int i = 0, n = m_debuggers.size(); i != n; ++i) { if (m_debuggers.at(i).id() == id) { + emit m_instance->aboutToRemoveDebugger(id); m_debuggers.removeAt(i); + emit m_instance->debuggerRemoved(id); ok = true; break; } } QTC_ASSERT(ok, return); - m_model->removeDebugger(id); } QString DebuggerItemManager::uniqueDisplayName(const QString &base) @@ -411,7 +394,7 @@ void DebuggerItemManager::setItemData(const QVariant &id, const QString &display item.setDisplayName(displayName); item.setCommand(fileName); item.reinitializeFromFile(); - emit m_model->updateDebugger(item.id()); + emit m_instance->debuggerUpdated(id); break; } } diff --git a/src/plugins/debugger/debuggeritemmanager.h b/src/plugins/debugger/debuggeritemmanager.h index 63936354d86..27ad45614bb 100644 --- a/src/plugins/debugger/debuggeritemmanager.h +++ b/src/plugins/debugger/debuggeritemmanager.h @@ -55,17 +55,16 @@ public: ~DebuggerItemManager(); static QList debuggers(); - static Debugger::Internal::DebuggerItemModel *model(); static QVariant registerDebugger(const DebuggerItem &item); static void deregisterDebugger(const DebuggerItem &item); + static void setItemData(const QVariant &id, const QString& displayName, const Utils::FileName &fileName); static const DebuggerItem *findByCommand(const Utils::FileName &command); static const DebuggerItem *findById(const QVariant &id); static void restoreDebuggers(); static QString uniqueDisplayName(const QString &base); - static void setItemData(const QVariant &id, const QString& displayName, const Utils::FileName &fileName); static void removeDebugger(const QVariant &id); static QVariant addDebugger(const DebuggerItem &item); @@ -87,7 +86,6 @@ private: static Utils::PersistentSettingsWriter *m_writer; static QList m_debuggers; - static Debugger::Internal::DebuggerItemModel *m_model; friend class Internal::DebuggerItemModel; friend class DebuggerPlugin; // Enable constrcutor for DebuggerPlugin diff --git a/src/plugins/debugger/debuggeritemmodel.cpp b/src/plugins/debugger/debuggeritemmodel.cpp index 635404684fb..8779b9ab693 100644 --- a/src/plugins/debugger/debuggeritemmodel.cpp +++ b/src/plugins/debugger/debuggeritemmodel.cpp @@ -84,6 +84,17 @@ DebuggerItemModel::DebuggerItemModel(QObject *parent) row = createRow(tr("Manual")); m_manualRoot = row.at(0); appendRow(row); + + foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) + addDebugger(item); + + QObject *manager = DebuggerItemManager::instance(); + connect(manager, SIGNAL(debuggerAdded(QVariant)), + this, SLOT(onDebuggerAdded(QVariant))); + connect(manager, SIGNAL(debuggerUpdated(QVariant)), + this, SLOT(onDebuggerUpdate(QVariant))); + connect(manager, SIGNAL(debuggerRemoved(QVariant)), + this, SLOT(onDebuggerRemoval(QVariant))); } QVariant DebuggerItemModel::headerData(int section, Qt::Orientation orientation, int role) const @@ -143,12 +154,28 @@ void DebuggerItemModel::markCurrentDirty() sitem->setFont(font); } +void DebuggerItemModel::onDebuggerAdded(const QVariant &id) +{ + const DebuggerItem *item = DebuggerItemManager::findById(id); + QTC_ASSERT(item, return); + addDebugger(*item); +} + +void DebuggerItemModel::onDebuggerUpdate(const QVariant &id) +{ + updateDebugger(id); +} + +void DebuggerItemModel::onDebuggerRemoval(const QVariant &id) +{ + removeDebugger(id); +} + void DebuggerItemModel::addDebugger(const DebuggerItem &item) { QTC_ASSERT(item.id().isValid(), return); QList row = describeItem(item); (item.isAutoDetected() ? m_autoRoot : m_manualRoot)->appendRow(row); - emit debuggerAdded(item.id(), item.displayName()); } void DebuggerItemModel::removeDebugger(const QVariant &id) @@ -160,7 +187,6 @@ void DebuggerItemModel::removeDebugger(const QVariant &id) // This will trigger a change of m_currentDebugger via changing the // view selection. parent->removeRow(sitem->row()); - emit debuggerRemoved(id); } void DebuggerItemModel::updateDebugger(const QVariant &id) @@ -182,7 +208,6 @@ void DebuggerItemModel::updateDebugger(const QVariant &id) parent->child(row, 1)->setFont(font); parent->child(row, 2)->setData(item.engineTypeName(), Qt::DisplayRole); parent->child(row, 2)->setFont(font); - emit debuggerUpdated(id, item.displayName()); return; } } diff --git a/src/plugins/debugger/debuggeritemmodel.h b/src/plugins/debugger/debuggeritemmodel.h index bb53c708ab1..f85097748ee 100644 --- a/src/plugins/debugger/debuggeritemmodel.h +++ b/src/plugins/debugger/debuggeritemmodel.h @@ -47,7 +47,7 @@ class DebuggerItemModel : public QStandardItemModel Q_OBJECT public: - DebuggerItemModel(QObject *parent); + DebuggerItemModel(QObject *parent = 0); QModelIndex currentIndex() const; QModelIndex lastIndex() const; @@ -60,19 +60,12 @@ public: public slots: void markCurrentDirty(); -signals: - void debuggerAdded(const QVariant &id, const QString &display); - void debuggerUpdated(const QVariant &id, const QString &display); - void debuggerRemoved(const QVariant &id); +private slots: + void onDebuggerAdded(const QVariant &id); + void onDebuggerUpdate(const QVariant &id); + void onDebuggerRemoval(const QVariant &id); private: - // - // friend class Debugger::DebuggerKitInformation; - // friend class DebuggerKitConfigWidget; - // friend class DebuggerItemConfigWidget; - // friend class DebuggerOptionsPage; - // - QStandardItem *currentStandardItem() const; QStandardItem *findStandardItemById(const QVariant &id) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; diff --git a/src/plugins/debugger/debuggerkitconfigwidget.cpp b/src/plugins/debugger/debuggerkitconfigwidget.cpp index 85f4ded6418..9ced9edf691 100644 --- a/src/plugins/debugger/debuggerkitconfigwidget.cpp +++ b/src/plugins/debugger/debuggerkitconfigwidget.cpp @@ -31,6 +31,7 @@ #include "debuggeritemmanager.h" #include "debuggeritemmodel.h" +#include "debuggerkitinformation.h" #include @@ -78,9 +79,6 @@ class DebuggerItemConfigWidget; DebuggerKitConfigWidget::DebuggerKitConfigWidget(Kit *workingCopy, const KitInformation *ki) : KitConfigWidget(workingCopy, ki) { - DebuggerItemModel *model = DebuggerItemManager::model(); - QTC_CHECK(model); - m_comboBox = new QComboBox; m_comboBox->setEnabled(true); m_comboBox->setToolTip(toolTip()); @@ -95,11 +93,12 @@ DebuggerKitConfigWidget::DebuggerKitConfigWidget(Kit *workingCopy, const KitInfo m_manageButton->setContentsMargins(0, 0, 0, 0); connect(m_manageButton, SIGNAL(clicked()), this, SLOT(manageDebuggers())); - connect(model, SIGNAL(debuggerAdded(QVariant,QString)), - this, SLOT(onDebuggerAdded(QVariant,QString))); - connect(model, SIGNAL(debuggerUpdated(QVariant,QString)), - this, SLOT(onDebuggerUpdated(QVariant,QString))); - connect(model, SIGNAL(debuggerRemoved(QVariant)), + QObject *manager = DebuggerItemManager::instance(); + connect(manager, SIGNAL(debuggerAdded(QVariant)), + this, SLOT(onDebuggerAdded(QVariant))); + connect(manager, SIGNAL(debuggerUpdated(QVariant)), + this, SLOT(onDebuggerUpdated(QVariant))); + connect(manager, SIGNAL(debuggerRemoved(QVariant)), this, SLOT(onDebuggerRemoved(QVariant))); } @@ -154,20 +153,22 @@ void DebuggerKitConfigWidget::currentDebuggerChanged(int) m_kit->setValue(DebuggerKitInformation::id(), id); } -void DebuggerKitConfigWidget::onDebuggerAdded(const QVariant &id, const QString &displayName) +void DebuggerKitConfigWidget::onDebuggerAdded(const QVariant &id) { - m_comboBox->setEnabled(true); - m_comboBox->addItem(displayName, id); + const DebuggerItem *item = DebuggerItemManager::findById(id); + QTC_ASSERT(item, return); + m_comboBox->addItem(item->displayName(), id); updateComboBox(id); } -void DebuggerKitConfigWidget::onDebuggerUpdated(const QVariant &id, const QString &displayName) +void DebuggerKitConfigWidget::onDebuggerUpdated(const QVariant &id) { - m_comboBox->setEnabled(true); + const DebuggerItem *item = DebuggerItemManager::findById(id); + QTC_ASSERT(item, return); const int pos = indexOf(id); if (pos < 0) return; - m_comboBox->setItemText(pos, displayName); + m_comboBox->setItemText(pos, item->displayName()); } void DebuggerKitConfigWidget::onDebuggerRemoved(const QVariant &id) diff --git a/src/plugins/debugger/debuggerkitconfigwidget.h b/src/plugins/debugger/debuggerkitconfigwidget.h index c6a54332180..e126f513f96 100644 --- a/src/plugins/debugger/debuggerkitconfigwidget.h +++ b/src/plugins/debugger/debuggerkitconfigwidget.h @@ -30,7 +30,7 @@ #ifndef DEBUGGER_DEBUGGERKITCONFIGWIDGET_H #define DEBUGGER_DEBUGGERKITCONFIGWIDGET_H -#include "debuggerkitinformation.h" +#include "debuggeritemmodel.h" #include #include @@ -75,8 +75,8 @@ public: private slots: void manageDebuggers(); void currentDebuggerChanged(int idx); - void onDebuggerAdded(const QVariant &id, const QString &displayName); - void onDebuggerUpdated(const QVariant &id, const QString &displayName); + void onDebuggerAdded(const QVariant &id); + void onDebuggerUpdated(const QVariant &id); void onDebuggerRemoved(const QVariant &id); private: diff --git a/src/plugins/debugger/debuggeroptionspage.cpp b/src/plugins/debugger/debuggeroptionspage.cpp index 893b28582b0..06b1c084cf2 100644 --- a/src/plugins/debugger/debuggeroptionspage.cpp +++ b/src/plugins/debugger/debuggeroptionspage.cpp @@ -63,7 +63,7 @@ class DebuggerItemConfigWidget : public QWidget Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::DebuggerItemConfigWidget) public: - explicit DebuggerItemConfigWidget(); + explicit DebuggerItemConfigWidget(DebuggerItemModel *model); void loadItem(); void saveItem(); void connectDirty(); @@ -74,10 +74,14 @@ private: QLabel *m_cdbLabel; PathChooser *m_binaryChooser; QLineEdit *m_abis; + DebuggerItemModel *m_model; }; -DebuggerItemConfigWidget::DebuggerItemConfigWidget() +DebuggerItemConfigWidget::DebuggerItemConfigWidget(DebuggerItemModel *model) : + m_model(model) { + QTC_CHECK(model); + m_displayNameLineEdit = new QLineEdit(this); m_binaryChooser = new PathChooser(this); @@ -104,26 +108,23 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget() void DebuggerItemConfigWidget::connectDirty() { - DebuggerItemModel *model = DebuggerItemManager::model(); connect(m_displayNameLineEdit, SIGNAL(textChanged(QString)), - model, SLOT(markCurrentDirty())); + m_model, SLOT(markCurrentDirty())); connect(m_binaryChooser, SIGNAL(changed(QString)), - model, SLOT(markCurrentDirty())); + m_model, SLOT(markCurrentDirty())); } void DebuggerItemConfigWidget::disconnectDirty() { - DebuggerItemModel *model = DebuggerItemManager::model(); disconnect(m_displayNameLineEdit, SIGNAL(textChanged(QString)), - model, SLOT(markCurrentDirty())); + m_model, SLOT(markCurrentDirty())); disconnect(m_binaryChooser, SIGNAL(changed(QString)), - model, SLOT(markCurrentDirty())); + m_model, SLOT(markCurrentDirty())); } void DebuggerItemConfigWidget::loadItem() { - DebuggerItemModel *model = DebuggerItemManager::model(); - const DebuggerItem *item = DebuggerItemManager::findById(model->currentDebugger()); + const DebuggerItem *item = DebuggerItemManager::findById(m_model->currentDebugger()); if (!item) return; @@ -163,8 +164,7 @@ void DebuggerItemConfigWidget::loadItem() void DebuggerItemConfigWidget::saveItem() { - DebuggerItemModel *model = DebuggerItemManager::model(); - const DebuggerItem *item = DebuggerItemManager::findById(model->currentDebugger()); + const DebuggerItem *item = DebuggerItemManager::findById(m_model->currentDebugger()); QTC_ASSERT(item, return); DebuggerItemManager::setItemData(item->id(), m_displayNameLineEdit->text(), m_binaryChooser->fileName()); @@ -203,7 +203,7 @@ QWidget *DebuggerOptionsPage::createPage(QWidget *parent) m_container->setState(DetailsWidget::NoSummary); m_container->setVisible(false); - m_model = DebuggerItemManager::model(); + m_model = new DebuggerItemModel(parent); m_debuggerView = new QTreeView(m_configWidget); m_debuggerView->setModel(m_model); @@ -243,7 +243,7 @@ QWidget *DebuggerOptionsPage::createPage(QWidget *parent) m_searchKeywords = tr("Debuggers"); - m_itemConfigWidget = new DebuggerItemConfigWidget; + m_itemConfigWidget = new DebuggerItemConfigWidget(m_model); m_container->setWidget(m_itemConfigWidget); updateState(); From fd8f2c6cdb4ffa39da6ef89461260e3001f23ad9 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 28 Oct 2013 17:47:37 +0100 Subject: [PATCH 78/84] Debugger: Make cancel work in DebuggerOptionsPage Change-Id: I09735507703e9a2c55aff68a25a4405cf12c9ab4 Reviewed-by: hjk --- src/plugins/debugger/debuggeritem.cpp | 13 +- src/plugins/debugger/debuggeritem.h | 6 + src/plugins/debugger/debuggeritemmanager.cpp | 4 +- src/plugins/debugger/debuggeritemmodel.cpp | 165 ++++++++++++++----- src/plugins/debugger/debuggeritemmodel.h | 17 +- src/plugins/debugger/debuggeroptionspage.cpp | 108 ++++++------ 6 files changed, 201 insertions(+), 112 deletions(-) diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp index 33396b84bef..0768d2ecdd6 100644 --- a/src/plugins/debugger/debuggeritem.cpp +++ b/src/plugins/debugger/debuggeritem.cpp @@ -61,6 +61,13 @@ DebuggerItem::DebuggerItem() m_isAutoDetected = false; } +DebuggerItem::DebuggerItem(const QVariant &id) +{ + m_id = id; + m_engineType = NoEngineType; + m_isAutoDetected = false; +} + DebuggerItem::DebuggerItem(const QVariantMap &data) { m_command = FileName::fromUserInput(data.value(QLatin1String(DEBUGGER_INFORMATION_COMMAND)).toString()); @@ -143,9 +150,9 @@ QStringList DebuggerItem::abiNames() const bool DebuggerItem::operator==(const DebuggerItem &other) const { return m_id == other.m_id + && m_displayName == other.m_displayName && m_isAutoDetected == other.m_isAutoDetected - && m_command == other.m_command - && m_abis == other.m_abis; + && m_command == other.m_command; } QVariantMap DebuggerItem::toMap() const @@ -233,7 +240,7 @@ DebuggerItem::MatchLevel DebuggerItem::matchTarget(const Abi &targetAbi) const bool Debugger::DebuggerItem::isValid() const { - return m_engineType != NoEngineType; + return !m_id.isNull(); } } // namespace Debugger; diff --git a/src/plugins/debugger/debuggeritem.h b/src/plugins/debugger/debuggeritem.h index c2ef2a6fec7..14219471e9f 100644 --- a/src/plugins/debugger/debuggeritem.h +++ b/src/plugins/debugger/debuggeritem.h @@ -42,6 +42,8 @@ namespace Debugger { +namespace Internal { class DebuggerItemModel; } + // ----------------------------------------------------------------------- // DebuggerItem // ----------------------------------------------------------------------- @@ -85,12 +87,16 @@ public: bool operator==(const DebuggerItem &other) const; private: + DebuggerItem(const QVariant &id); + QVariant m_id; QString m_displayName; DebuggerEngineType m_engineType; Utils::FileName m_command; bool m_isAutoDetected; QList m_abis; + + friend class Internal::DebuggerItemModel; }; } // namespace Debugger diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp index f5f0fead2ea..fcca5d8eac0 100644 --- a/src/plugins/debugger/debuggeritemmanager.cpp +++ b/src/plugins/debugger/debuggeritemmanager.cpp @@ -90,7 +90,7 @@ static void readDebuggers(const FileName &fileName, bool isSystem) // SDK debuggers are always considered to be up-to-date, so no need to recheck them. } else { // User settings. - if (item.isAutoDetected() && !item.isValid()) { + if (item.isAutoDetected() && (!item.isValid() || item.engineType() == NoEngineType)) { qWarning() << QString::fromLatin1("DebuggerItem \"%1\" (%2) dropped since it is not valid") .arg(item.command().toString()).arg(item.id().toString()); continue; @@ -321,7 +321,7 @@ void DebuggerItemManager::saveDebuggers() int count = 0; foreach (const DebuggerItem &item, m_debuggers) { - if (item.isValid()) { + if (item.isValid() && item.engineType() != NoEngineType) { QVariantMap tmp = item.toMap(); if (tmp.isEmpty()) continue; diff --git a/src/plugins/debugger/debuggeritemmodel.cpp b/src/plugins/debugger/debuggeritemmodel.cpp index 8779b9ab693..2adb8d75d4e 100644 --- a/src/plugins/debugger/debuggeritemmodel.cpp +++ b/src/plugins/debugger/debuggeritemmodel.cpp @@ -44,9 +44,12 @@ static QList describeItem(const DebuggerItem &item) row.append(new QStandardItem(item.command().toUserOutput())); row.append(new QStandardItem(item.engineTypeName())); row.at(0)->setData(item.id()); + row.at(0)->setData(item.abiNames(), Qt::UserRole + 2); row.at(0)->setEditable(false); row.at(1)->setEditable(false); + row.at(1)->setData(item.toMap()); row.at(2)->setEditable(false); + row.at(2)->setData(static_cast(item.engineType())); row.at(0)->setSelectable(true); row.at(1)->setSelectable(true); row.at(2)->setSelectable(true); @@ -86,7 +89,7 @@ DebuggerItemModel::DebuggerItemModel(QObject *parent) appendRow(row); foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) - addDebugger(item); + addDebuggerStandardItem(item, false); QObject *manager = DebuggerItemManager::instance(); connect(manager, SIGNAL(debuggerAdded(QVariant)), @@ -112,6 +115,87 @@ QVariant DebuggerItemModel::headerData(int section, Qt::Orientation orientation, return QVariant(); } +bool DebuggerItemModel::addDebuggerStandardItem(const DebuggerItem &item, bool changed) +{ + if (findStandardItemById(item.id())) + return false; + + QList row = describeItem(item); + foreach (QStandardItem *cell, row) { + QFont font = cell->font(); + font.setBold(changed); + cell->setFont(font); + } + (item.isAutoDetected() ? m_autoRoot : m_manualRoot)->appendRow(row); + return true; +} + +bool DebuggerItemModel::removeDebuggerStandardItem(const QVariant &id) +{ + QStandardItem *sitem = findStandardItemById(id); + QTC_ASSERT(sitem, return false); + QStandardItem *parent = sitem->parent(); + QTC_ASSERT(parent, return false); + // This will trigger a change of m_currentDebugger via changing the + // view selection. + parent->removeRow(sitem->row()); + return true; +} + +bool DebuggerItemModel::updateDebuggerStandardItem(const DebuggerItem &item, bool changed) +{ + QStandardItem *sitem = findStandardItemById(item.id()); + QTC_ASSERT(sitem, return false); + QStandardItem *parent = sitem->parent(); + QTC_ASSERT(parent, return false); + int row = sitem->row(); + QFont font = sitem->font(); + font.setBold(changed); + parent->child(row, 0)->setData(item.displayName(), Qt::DisplayRole); + parent->child(row, 0)->setFont(font); + parent->child(row, 1)->setData(item.command().toUserOutput(), Qt::DisplayRole); + parent->child(row, 1)->setFont(font); + parent->child(row, 2)->setData(item.engineTypeName(), Qt::DisplayRole); + parent->child(row, 2)->setData(static_cast(item.engineType())); + parent->child(row, 2)->setFont(font); + return true; +} + +DebuggerItem DebuggerItemModel::debuggerItem(QStandardItem *sitem) const +{ + DebuggerItem item = DebuggerItem(QVariant()); + if (sitem && sitem->parent()) { + item.setAutoDetected(sitem->parent() == m_autoRoot); + + QStandardItem *i = sitem->parent()->child(sitem->row(), 0); + item.m_id = i->data(); + item.setDisplayName(i->data(Qt::DisplayRole).toString()); + + QStringList abis = i->data(Qt::UserRole + 2).toStringList(); + QList abiList; + foreach (const QString &abi, abis) + abiList << ProjectExplorer::Abi(abi); + item.setAbis(abiList); + + i = sitem->parent()->child(sitem->row(), 1); + item.setCommand(Utils::FileName::fromUserInput(i->data(Qt::DisplayRole).toString())); + + i = sitem->parent()->child(sitem->row(), 2); + item.setEngineType(static_cast(i->data().toInt())); + } + return item; +} + +QList DebuggerItemModel::debuggerItems() const +{ + QList result; + for (int i = 0, n = m_autoRoot->rowCount(); i != n; ++i) + result << debuggerItem(m_autoRoot->child(i)); + for (int i = 0, n = m_manualRoot->rowCount(); i != n; ++i) + result << debuggerItem(m_manualRoot->child(i)); + return result; +} + QStandardItem *DebuggerItemModel::currentStandardItem() const { return findStandardItemById(m_currentDebugger); @@ -145,70 +229,62 @@ QModelIndex DebuggerItemModel::lastIndex() const return current ? current->index() : QModelIndex(); } -void DebuggerItemModel::markCurrentDirty() -{ - QStandardItem *sitem = currentStandardItem(); - QTC_ASSERT(sitem, return); - QFont font = sitem->font(); - font.setBold(true); - sitem->setFont(font); -} - void DebuggerItemModel::onDebuggerAdded(const QVariant &id) { const DebuggerItem *item = DebuggerItemManager::findById(id); QTC_ASSERT(item, return); - addDebugger(*item); + if (!addDebuggerStandardItem(*item, false)) + updateDebuggerStandardItem(*item, false); // already had it added, so just update it. } void DebuggerItemModel::onDebuggerUpdate(const QVariant &id) { - updateDebugger(id); + const DebuggerItem *item = DebuggerItemManager::findById(id); + QTC_ASSERT(item, return); + updateDebuggerStandardItem(*item, false); } void DebuggerItemModel::onDebuggerRemoval(const QVariant &id) { - removeDebugger(id); + removeDebuggerStandardItem(id); } void DebuggerItemModel::addDebugger(const DebuggerItem &item) { - QTC_ASSERT(item.id().isValid(), return); - QList row = describeItem(item); - (item.isAutoDetected() ? m_autoRoot : m_manualRoot)->appendRow(row); + addDebuggerStandardItem(item, true); } void DebuggerItemModel::removeDebugger(const QVariant &id) { - QStandardItem *sitem = findStandardItemById(id); - QTC_ASSERT(sitem, return); - QStandardItem *parent = sitem->parent(); - QTC_ASSERT(parent, return); - // This will trigger a change of m_currentDebugger via changing the - // view selection. - parent->removeRow(sitem->row()); + if (!removeDebuggerStandardItem(id)) // Nothing there! + return; + + if (DebuggerItemManager::findById(id)) + m_removedItems.append(id); } -void DebuggerItemModel::updateDebugger(const QVariant &id) +void DebuggerItemModel::updateDebugger(const DebuggerItem &item) { - QList debuggers = DebuggerItemManager::debuggers(); - for (int i = 0, n = debuggers.size(); i != n; ++i) { - DebuggerItem &item = debuggers[i]; - if (item.id() == id) { - QStandardItem *sitem = findStandardItemById(id); - QTC_ASSERT(sitem, return); - QStandardItem *parent = sitem->parent(); - QTC_ASSERT(parent, return); - int row = sitem->row(); - QFont font = sitem->font(); - font.setBold(false); - parent->child(row, 0)->setData(item.displayName(), Qt::DisplayRole); - parent->child(row, 0)->setFont(font); - parent->child(row, 1)->setData(item.command().toUserOutput(), Qt::DisplayRole); - parent->child(row, 1)->setFont(font); - parent->child(row, 2)->setData(item.engineTypeName(), Qt::DisplayRole); - parent->child(row, 2)->setFont(font); - return; + updateDebuggerStandardItem(item, true); +} + +void DebuggerItemModel::apply() +{ + foreach (const QVariant &id, m_removedItems) { + const DebuggerItem *item = DebuggerItemManager::findById(id); + QTC_CHECK(item); + DebuggerItemManager::deregisterDebugger(*item); + } + + foreach (const DebuggerItem &item, debuggerItems()) { + const DebuggerItem *managed = DebuggerItemManager::findById(item.id()); + if (managed) { + if (*managed == item) + continue; + else + DebuggerItemManager::setItemData(item.id(), item.displayName(), item.command()); + } else { + DebuggerItemManager::registerDebugger(item); } } } @@ -219,5 +295,10 @@ void DebuggerItemModel::setCurrentIndex(const QModelIndex &index) m_currentDebugger = sit ? sit->data() : QVariant(); } +DebuggerItem DebuggerItemModel::currentDebugger() const +{ + return debuggerItem(currentStandardItem()); +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/debuggeritemmodel.h b/src/plugins/debugger/debuggeritemmodel.h index f85097748ee..1f261696250 100644 --- a/src/plugins/debugger/debuggeritemmodel.h +++ b/src/plugins/debugger/debuggeritemmodel.h @@ -52,13 +52,13 @@ public: QModelIndex currentIndex() const; QModelIndex lastIndex() const; void setCurrentIndex(const QModelIndex &index); - QVariant currentDebugger() const { return m_currentDebugger; } + QVariant currentDebuggerId() const { return m_currentDebugger; } + DebuggerItem currentDebugger() const; void addDebugger(const DebuggerItem &item); void removeDebugger(const QVariant &id); - void updateDebugger(const QVariant &id); + void updateDebugger(const DebuggerItem &item); -public slots: - void markCurrentDirty(); + void apply(); private slots: void onDebuggerAdded(const QVariant &id); @@ -70,11 +70,20 @@ private: QStandardItem *findStandardItemById(const QVariant &id) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; + bool addDebuggerStandardItem(const DebuggerItem &item, bool changed); + bool removeDebuggerStandardItem(const QVariant &id); + bool updateDebuggerStandardItem(const DebuggerItem &item, bool changed); + + DebuggerItem debuggerItem(QStandardItem *sitem) const; + QList debuggerItems() const; + QVariant m_currentDebugger; QStandardItem *m_autoRoot; QStandardItem *m_manualRoot; QStringList removed; + + QList m_removedItems; }; } // namespace Internal diff --git a/src/plugins/debugger/debuggeroptionspage.cpp b/src/plugins/debugger/debuggeroptionspage.cpp index 06b1c084cf2..3c5aa436c60 100644 --- a/src/plugins/debugger/debuggeroptionspage.cpp +++ b/src/plugins/debugger/debuggeroptionspage.cpp @@ -64,10 +64,8 @@ class DebuggerItemConfigWidget : public QWidget public: explicit DebuggerItemConfigWidget(DebuggerItemModel *model); - void loadItem(); - void saveItem(); - void connectDirty(); - void disconnectDirty(); + void setItem(const DebuggerItem &item); + void apply(); private: QLineEdit *m_displayNameLineEdit; @@ -102,43 +100,19 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget(DebuggerItemModel *model) : formLayout->addRow(m_cdbLabel); formLayout->addRow(new QLabel(tr("Path:")), m_binaryChooser); formLayout->addRow(new QLabel(tr("ABIs:")), m_abis); - - connectDirty(); } -void DebuggerItemConfigWidget::connectDirty() +void DebuggerItemConfigWidget::setItem(const DebuggerItem &item) { - connect(m_displayNameLineEdit, SIGNAL(textChanged(QString)), - m_model, SLOT(markCurrentDirty())); - connect(m_binaryChooser, SIGNAL(changed(QString)), - m_model, SLOT(markCurrentDirty())); -} + m_displayNameLineEdit->setEnabled(!item.isAutoDetected()); + m_displayNameLineEdit->setText(item.displayName()); -void DebuggerItemConfigWidget::disconnectDirty() -{ - disconnect(m_displayNameLineEdit, SIGNAL(textChanged(QString)), - m_model, SLOT(markCurrentDirty())); - disconnect(m_binaryChooser, SIGNAL(changed(QString)), - m_model, SLOT(markCurrentDirty())); -} - -void DebuggerItemConfigWidget::loadItem() -{ - const DebuggerItem *item = DebuggerItemManager::findById(m_model->currentDebugger()); - if (!item) - return; - - disconnectDirty(); - m_displayNameLineEdit->setEnabled(!item->isAutoDetected()); - m_displayNameLineEdit->setText(item->displayName()); - - m_binaryChooser->setEnabled(!item->isAutoDetected()); - m_binaryChooser->setFileName(item->command()); - connectDirty(); + m_binaryChooser->setEnabled(!item.isAutoDetected()); + m_binaryChooser->setFileName(item.command()); QString text; QString versionCommand; - if (item->engineType() == CdbEngineType) { + if (item.engineType() == CdbEngineType) { #ifdef Q_OS_WIN const bool is64bit = winIs64BitSystem(); #else @@ -159,15 +133,18 @@ void DebuggerItemConfigWidget::loadItem() m_cdbLabel->setVisible(!text.isEmpty()); m_binaryChooser->setCommandVersionArguments(QStringList(versionCommand)); - m_abis->setText(item->abiNames().join(QLatin1String(", "))); + m_abis->setText(item.abiNames().join(QLatin1String(", "))); } -void DebuggerItemConfigWidget::saveItem() +void DebuggerItemConfigWidget::apply() { - const DebuggerItem *item = DebuggerItemManager::findById(m_model->currentDebugger()); - QTC_ASSERT(item, return); - DebuggerItemManager::setItemData(item->id(), m_displayNameLineEdit->text(), - m_binaryChooser->fileName()); + DebuggerItem item = m_model->currentDebugger(); + QTC_ASSERT(item.isValid(), return); + + item.setDisplayName(m_displayNameLineEdit->text()); + item.setCommand(m_binaryChooser->fileName()); + item.reinitializeFromFile(); + m_model->updateDebugger(item); } // -------------------------------------------------------------------------- @@ -253,21 +230,23 @@ QWidget *DebuggerOptionsPage::createPage(QWidget *parent) void DebuggerOptionsPage::apply() { - m_itemConfigWidget->saveItem(); - debuggerModelChanged(); + m_itemConfigWidget->apply(); + m_model->apply(); } void DebuggerOptionsPage::cloneDebugger() { - const DebuggerItem *item = DebuggerItemManager::findById(m_model->currentDebugger()); - QTC_ASSERT(item, return); + DebuggerItem item = m_model->currentDebugger(); + if (!item.isValid()) + return; + DebuggerItem newItem; - newItem.setCommand(item->command()); - newItem.setEngineType(item->engineType()); - newItem.setAbis(item->abis()); - newItem.setDisplayName(DebuggerItemManager::uniqueDisplayName(tr("Clone of %1").arg(item->displayName()))); + newItem.setCommand(item.command()); + newItem.setEngineType(item.engineType()); + newItem.setAbis(item.abis()); + newItem.setDisplayName(DebuggerItemManager::uniqueDisplayName(tr("Clone of %1").arg(item.displayName()))); newItem.setAutoDetected(false); - DebuggerItemManager::addDebugger(newItem); + m_model->addDebugger(newItem); m_debuggerView->setCurrentIndex(m_model->lastIndex()); } @@ -277,14 +256,14 @@ void DebuggerOptionsPage::addDebugger() item.setEngineType(NoEngineType); item.setDisplayName(DebuggerItemManager::uniqueDisplayName(tr("New Debugger"))); item.setAutoDetected(false); - DebuggerItemManager::addDebugger(item); + m_model->addDebugger(item); m_debuggerView->setCurrentIndex(m_model->lastIndex()); } void DebuggerOptionsPage::removeDebugger() { - QVariant id = m_model->currentDebugger(); - DebuggerItemManager::removeDebugger(id); + QVariant id = m_model->currentDebuggerId(); + m_model->removeDebugger(id); m_debuggerView->setCurrentIndex(m_model->lastIndex()); } @@ -314,8 +293,10 @@ void DebuggerOptionsPage::debuggerSelectionChanged() mi = mi.sibling(mi.row(), 0); m_model->setCurrentIndex(mi); - m_itemConfigWidget->loadItem(); - m_container->setVisible(m_model->currentDebugger().isValid()); + DebuggerItem item = m_model->currentDebugger(); + + m_itemConfigWidget->setItem(item); + m_container->setVisible(item.isValid()); updateState(); } @@ -323,8 +304,13 @@ void DebuggerOptionsPage::debuggerModelChanged() { QTC_ASSERT(m_container, return); - m_itemConfigWidget->loadItem(); - m_container->setVisible(m_model->currentDebugger().isValid()); + QVariant id = m_model->currentDebuggerId(); + const DebuggerItem *item = DebuggerItemManager::findById(id); + if (!item) + return; + + m_itemConfigWidget->setItem(*item); + m_container->setVisible(m_model->currentDebuggerId().isValid()); m_debuggerView->setCurrentIndex(m_model->currentIndex()); updateState(); } @@ -337,11 +323,11 @@ void DebuggerOptionsPage::updateState() bool canCopy = false; bool canDelete = false; - if (const DebuggerItem *item = DebuggerItemManager::findById(m_model->currentDebugger())) { - canCopy = item->isValid() && item->canClone(); - canDelete = !item->isAutoDetected(); - canDelete = true; // Do we want to remove auto-detected items? - } + DebuggerItem item = m_model->currentDebugger(); + + canCopy = item.isValid() && item.canClone(); + canDelete = !item.isAutoDetected(); + m_cloneButton->setEnabled(canCopy); m_delButton->setEnabled(canDelete); } From e5dc99da32f8a1292df83fcec6a201827c302885 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 28 Oct 2013 18:18:03 +0100 Subject: [PATCH 79/84] PathChooser: Grant direct access to lineEdit's history key Change-Id: I889b5cd0dbc27144253a9c82567eee59554725a3 Reviewed-by: Tobias Hunger --- src/libs/utils/pathchooser.cpp | 5 +++++ src/libs/utils/pathchooser.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp index 9305680ad58..d6e3a59301b 100644 --- a/src/libs/utils/pathchooser.cpp +++ b/src/libs/utils/pathchooser.cpp @@ -654,6 +654,11 @@ void PathChooser::installLineEditVersionToolTip(QLineEdit *le, const QStringList ef->setArguments(arguments); } +void PathChooser::setHistoryCompleter(const QString &historyKey) +{ + d->m_lineEdit->setHistoryCompleter(historyKey); +} + QStringList PathChooser::commandVersionArguments() const { return d->m_binaryVersionToolTipEventFilter ? diff --git a/src/libs/utils/pathchooser.h b/src/libs/utils/pathchooser.h index 2dc33c0c9d0..483c94e576f 100644 --- a/src/libs/utils/pathchooser.h +++ b/src/libs/utils/pathchooser.h @@ -128,6 +128,9 @@ public: // Install a tooltip on lineedits used for binaries showing the version. static void installLineEditVersionToolTip(QLineEdit *le, const QStringList &arguments); + // Enable a history completer with a history of entries. + void setHistoryCompleter(const QString &historyKey); + bool isReadOnly() const; void setReadOnly(bool b); From eaf99819eac1e2897de52acd21cf6af75f3db8ac Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 28 Oct 2013 18:19:38 +0100 Subject: [PATCH 80/84] DebuggerDialogs: Remember debugger path history Change-Id: I02e6b7ff5e2280cabb0f23de942941756f7bf3a0 Reviewed-by: Tobias Hunger --- src/plugins/debugger/debuggerdialogs.cpp | 4 ++-- src/plugins/debugger/debuggeroptionspage.cpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp index 8f80194ce8d..b1db49211d9 100644 --- a/src/plugins/debugger/debuggerdialogs.cpp +++ b/src/plugins/debugger/debuggerdialogs.cpp @@ -248,7 +248,7 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent) d->localExecutablePathChooser = new PathChooser(this); d->localExecutablePathChooser->setExpectedKind(PathChooser::File); d->localExecutablePathChooser->setPromptDialogTitle(tr("Select Executable")); - d->localExecutablePathChooser->lineEdit()->setHistoryCompleter(QLatin1String("LocalExecutable")); + d->localExecutablePathChooser->setHistoryCompleter(QLatin1String("LocalExecutable")); d->arguments = new FancyLineEdit(this); d->arguments->setHistoryCompleter(QLatin1String("CommandlineArguments")); @@ -256,7 +256,7 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent) d->workingDirectory = new PathChooser(this); d->workingDirectory->setExpectedKind(PathChooser::ExistingDirectory); d->workingDirectory->setPromptDialogTitle(tr("Select Working Directory")); - d->workingDirectory->lineEdit()->setHistoryCompleter(QLatin1String("WorkingDirectory")); + d->workingDirectory->setHistoryCompleter(QLatin1String("WorkingDirectory")); d->runInTerminalCheckBox = new QCheckBox(this); diff --git a/src/plugins/debugger/debuggeroptionspage.cpp b/src/plugins/debugger/debuggeroptionspage.cpp index 3c5aa436c60..884edf439fd 100644 --- a/src/plugins/debugger/debuggeroptionspage.cpp +++ b/src/plugins/debugger/debuggeroptionspage.cpp @@ -85,6 +85,7 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget(DebuggerItemModel *model) : m_binaryChooser = new PathChooser(this); m_binaryChooser->setExpectedKind(PathChooser::ExistingCommand); m_binaryChooser->setMinimumWidth(400); + m_binaryChooser->setHistoryCompleter(QLatin1String("DebuggerPaths")); m_cdbLabel = new QLabel(this); m_cdbLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); From ee4ed219b056e89f5b2f67a4863957db2c80dc3d Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sat, 26 Oct 2013 21:57:20 +0300 Subject: [PATCH 81/84] Debugger: Remove gdbProc() accessor Use member directly Change-Id: Id7b67458d40e4f5ae4893101afac423d14dfdba7 Reviewed-by: hjk --- src/plugins/debugger/gdb/gdbengine.cpp | 47 ++++++++++++-------------- src/plugins/debugger/gdb/gdbengine.h | 1 - 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index f3755adcce2..9341d1d74e2 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -277,7 +277,7 @@ QString GdbEngine::errorMessage(QProcess::ProcessError error) return tr("The gdb process failed to start. Either the " "invoked program \"%1\" is missing, or you may have insufficient " "permissions to invoke the program.\n%2") - .arg(m_gdb, gdbProc()->errorString()); + .arg(m_gdb, m_gdbProc->errorString()); case QProcess::Crashed: if (targetState() == DebuggerFinished) return tr("The gdb process crashed some time after starting " @@ -300,11 +300,6 @@ QString GdbEngine::errorMessage(QProcess::ProcessError error) } } -GdbProcess *GdbEngine::gdbProc() const -{ - return m_gdbProc; -} - #if 0 static void dump(const char *first, const char *middle, const QString & to) { @@ -794,7 +789,7 @@ void GdbEngine::handleResponse(const QByteArray &buff) void GdbEngine::readGdbStandardError() { - QByteArray err = gdbProc()->readAllStandardError(); + QByteArray err = m_gdbProc->readAllStandardError(); showMessage(_("UNEXPECTED GDB STDERR: " + err)); if (err == "Undefined command: \"bb\". Try \"help\".\n") return; @@ -810,7 +805,7 @@ void GdbEngine::readGdbStandardOutput() int newstart = 0; int scan = m_inbuffer.size(); - QByteArray out = gdbProc()->readAllStandardOutput(); + QByteArray out = m_gdbProc->readAllStandardOutput(); m_inbuffer.append(out); // This can trigger when a dialog starts a nested event loop. @@ -974,7 +969,7 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0) return; } - QTC_ASSERT(gdbProc()->state() == QProcess::Running, return); + QTC_ASSERT(m_gdbProc->state() == QProcess::Running, return); const int token = ++currentToken(); @@ -1055,7 +1050,7 @@ void GdbEngine::commandTimeout() if (mb->exec() == QMessageBox::Ok) { showMessage(_("KILLING DEBUGGER AS REQUESTED BY USER")); // This is an undefined state, so we just pull the emergency brake. - gdbProc()->kill(); + m_gdbProc->kill(); } else { showMessage(_("CONTINUE DEBUGGER AS REQUESTED BY USER")); } @@ -2044,9 +2039,9 @@ void GdbEngine::notifyAdapterShutdownOk() { QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); showMessage(_("INITIATE GDBENGINE SHUTDOWN IN STATE %1, PROC: %2") - .arg(lastGoodState()).arg(gdbProc()->state())); + .arg(lastGoodState()).arg(m_gdbProc->state())); m_commandsDoneCallback = 0; - switch (gdbProc()->state()) { + switch (m_gdbProc->state()) { case QProcess::Running: postCommand("-gdb-exit", GdbEngine::ExitRequest, CB(handleGdbExit)); break; @@ -2056,7 +2051,7 @@ void GdbEngine::notifyAdapterShutdownOk() break; case QProcess::Starting: showMessage(_("GDB NOT REALLY RUNNING; KILLING IT")); - gdbProc()->kill(); + m_gdbProc->kill(); notifyEngineShutdownFailed(); break; } @@ -2073,7 +2068,7 @@ void GdbEngine::handleGdbExit(const GdbResponse &response) QString::fromLocal8Bit(response.data["msg"].data())); qDebug() << (_("GDB WON'T EXIT (%1); KILLING IT").arg(msg)); showMessage(_("GDB WON'T EXIT (%1); KILLING IT").arg(msg)); - gdbProc()->kill(); + m_gdbProc->kill(); } } @@ -4758,7 +4753,7 @@ void GdbEngine::startGdb(const QStringList &args) foreach (int test, m_testCases) showMessage(_("ENABLING TEST CASE: " + QByteArray::number(test))); - gdbProc()->disconnect(); // From any previous runs + m_gdbProc->disconnect(); // From any previous runs const DebuggerStartParameters &sp = startParameters(); m_gdb = gdbBinary(sp); @@ -4783,19 +4778,19 @@ void GdbEngine::startGdb(const QStringList &args) } gdbArgs += args; - connect(gdbProc(), SIGNAL(error(QProcess::ProcessError)), + connect(m_gdbProc, SIGNAL(error(QProcess::ProcessError)), SLOT(handleGdbError(QProcess::ProcessError))); - connect(gdbProc(), SIGNAL(finished(int,QProcess::ExitStatus)), + connect(m_gdbProc, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(handleGdbFinished(int,QProcess::ExitStatus))); - connect(gdbProc(), SIGNAL(readyReadStandardOutput()), + connect(m_gdbProc, SIGNAL(readyReadStandardOutput()), SLOT(readGdbStandardOutput())); - connect(gdbProc(), SIGNAL(readyReadStandardError()), + connect(m_gdbProc, SIGNAL(readyReadStandardError()), SLOT(readGdbStandardError())); showMessage(_("STARTING ") + m_gdb + _(" ") + gdbArgs.join(_(" "))); - gdbProc()->start(m_gdb, gdbArgs); + m_gdbProc->start(m_gdb, gdbArgs); - if (!gdbProc()->waitForStarted()) { + if (!m_gdbProc->waitForStarted()) { handleGdbStartFailed(); const QString msg = errorMessage(QProcess::FailedToStart); handleAdapterStartFailed(msg); @@ -5009,7 +5004,7 @@ void GdbEngine::handleGdbError(QProcess::ProcessError error) case QProcess::WriteError: case QProcess::Timedout: default: - //gdbProc()->kill(); + //m_gdbProc->kill(); //notifyEngineIll(); showMessageBox(QMessageBox::Critical, tr("GDB I/O Error"), msg); break; @@ -5050,8 +5045,8 @@ void GdbEngine::abortDebugger() if (targetState() == DebuggerFinished) { // We already tried. Try harder. showMessage(_("ABORTING DEBUGGER. SECOND TIME.")); - QTC_ASSERT(gdbProc(), return); - gdbProc()->kill(); + QTC_ASSERT(m_gdbProc, return); + m_gdbProc->kill(); } else { // Be friendly the first time. This will change targetState(). showMessage(_("ABORTING DEBUGGER. FIRST TIME.")); @@ -5240,7 +5235,7 @@ void GdbEngine::handleAdapterCrashed(const QString &msg) notifyEngineIll(); // No point in being friendly here ... - gdbProc()->kill(); + m_gdbProc->kill(); if (!msg.isEmpty()) showMessageBox(QMessageBox::Critical, tr("Adapter crashed"), msg); @@ -5385,7 +5380,7 @@ bool GdbEngine::attemptQuickStart() const void GdbEngine::write(const QByteArray &data) { - gdbProc()->write(data); + m_gdbProc->write(data); } bool GdbEngine::prepareCommand() diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index fd278d51ae9..592be2b0a98 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -649,7 +649,6 @@ protected: // Convenience Functions // QString errorMessage(QProcess::ProcessError error); - GdbProcess *gdbProc() const; void showExecutionError(const QString &message); static QByteArray tooltipIName(const QString &exp); From 3fbbf1c9636b91d69e899eb2860b00011a17227a Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 28 Oct 2013 14:27:09 +0100 Subject: [PATCH 82/84] Valgrind: Fix wrong connect in auto test Change-Id: I588cb765fbe09e516b64af962ff5d86efc69f4fb Reviewed-by: hjk --- tests/auto/valgrind/memcheck/parsertests.h | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/tests/auto/valgrind/memcheck/parsertests.h b/tests/auto/valgrind/memcheck/parsertests.h index 0059564cae5..91e74c8a53e 100644 --- a/tests/auto/valgrind/memcheck/parsertests.h +++ b/tests/auto/valgrind/memcheck/parsertests.h @@ -103,10 +103,8 @@ public: this, SLOT(internalError(QString))); connect(parser, SIGNAL(status(Valgrind::XmlProtocol::Status)), this, SLOT(status(Valgrind::XmlProtocol::Status))); - connect(runner, SIGNAL(standardErrorReceived(QByteArray)), - this, SLOT(standardErrorReceived(QByteArray))); - connect(runner, SIGNAL(standardOutputReceived(QByteArray)), - this, SLOT(standardOutputReceived(QByteArray))); + connect(runner, SIGNAL(processOutputReceived(QByteArray,Utils::OutputFormat)), + this, SLOT(handleProcessOutput(QByteArray,Utils::OutputFormat))); connect(runner, SIGNAL(logMessageReceived(QByteArray)), this, SLOT(logMessageReceived(QByteArray))); connect(runner, SIGNAL(processErrorReceived(QString, QProcess::ProcessError)), @@ -123,14 +121,9 @@ public slots: { qDebug() << "internal error received:" << error; } - void standardErrorReceived(const QByteArray &err) + void handleProcessOutput(const QByteArray &out, Utils::OutputFormat format) { - Q_UNUSED(err); - // qDebug() << "STDERR received:" << err; // this can be a lot of text - } - void standardOutputReceived(const QByteArray &out) - { - qDebug() << "STDOUT received:" << out; + qDebug() << "Output received:" << format << out; } void status(const Valgrind::XmlProtocol::Status &status) { From ba4473aa45ce9ae038e8dae79b72901c96c68e8d Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Mon, 28 Oct 2013 19:35:01 +0200 Subject: [PATCH 83/84] Git: Disallow whitespace in topic on Push to Gerrit dialog Change-Id: I02416c8a55fcdfdea1cbe349f7e78204c0200fd9 Reviewed-by: Petar Perisin --- src/plugins/git/gerrit/gerritpushdialog.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/git/gerrit/gerritpushdialog.cpp b/src/plugins/git/gerrit/gerritpushdialog.cpp index 25bc5a10bcb..c1e5c0618c8 100644 --- a/src/plugins/git/gerrit/gerritpushdialog.cpp +++ b/src/plugins/git/gerrit/gerritpushdialog.cpp @@ -35,6 +35,7 @@ #include #include +#include namespace Gerrit { namespace Internal { @@ -135,6 +136,9 @@ GerritPushDialog::GerritPushDialog(const QString &workingDir, const QString &rev connect(m_ui->branchComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setChangeRange())); setRemoteBranches(); m_ui->reviewersLineEdit->setText(reviewerList); + + m_ui->topicLineEdit->setValidator(new QRegExpValidator(QRegExp(QLatin1String("^\\S+$")), this)); + m_valid = true; } From b926435576112005dd8ec5bd7d3588a54317ec0e Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 25 Oct 2013 10:59:22 +0200 Subject: [PATCH 84/84] CppEditor: Remove unneeded member. Change-Id: Icc2b2705a587482ac2a4215d05a012c4c15f6439 Reviewed-by: Nikolai Kosjar --- src/plugins/cppeditor/cppeditor.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index 5546a20faea..ba3b58cceef 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -260,7 +260,6 @@ private: CppTools::CommentsSettings m_commentsSettings; QScopedPointer m_followSymbolUnderCursor; - QString m_preProcessorAdditions; QToolButton *m_preprocessorButton; };
Signal name : %1