From 954feb48b816e7abe6686443d45d7b5131fedd0d Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 13 Mar 2015 14:04:34 +0100 Subject: [PATCH 01/61] Cdbext: Fix adding watchers. Change-Id: I65a34460237308d76a202ac08d3b2180f532c934 Reviewed-by: Christian Stenger --- src/libs/qtcreatorcdbext/symbolgroup.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libs/qtcreatorcdbext/symbolgroup.cpp b/src/libs/qtcreatorcdbext/symbolgroup.cpp index b8810d59222..38d9afe5c0e 100644 --- a/src/libs/qtcreatorcdbext/symbolgroup.cpp +++ b/src/libs/qtcreatorcdbext/symbolgroup.cpp @@ -785,8 +785,10 @@ bool WatchesSymbolGroup::addWatch(CIDebugSymbols *s, std::string iname, const st if (isWatchIname(iname)) iname.erase(0, std::strlen(WatchesSymbolGroup::watchInamePrefix) + 1); // Already in? - if (root()->childByIName(iname.c_str())) - return true; + if (AbstractSymbolGroupNode *watcherNode = root()->childByIName(iname.c_str())) { + if (!removeSymbol(watcherNode, errorMessage)) + return false; + } // Resolve the expressions, but still display the original name obtained to // avoid cycles re-adding symbols SymbolGroupNode *node = addSymbol(std::string(), fixWatchExpression(s, expression), From 4b6ee5881a2d7ff327288795959efa6630b11d13 Mon Sep 17 00:00:00 2001 From: Nikita Baryshnikov Date: Wed, 25 Feb 2015 00:28:54 +0300 Subject: [PATCH 02/61] PluginManager: share ExecuteOnDestruction with utils Change-Id: I895d0ae48c36030e58aea1676873bd285680a661 Reviewed-by: Eike Ziller --- src/libs/extensionsystem/pluginmanager.cpp | 14 ++---- src/libs/utils/executeondestruction.h | 50 +++++++++++++++++++ src/libs/utils/utils-lib.pri | 3 +- src/libs/utils/utils.qbs | 1 + .../editormanager/editormanager.cpp | 11 ++-- 5 files changed, 61 insertions(+), 18 deletions(-) create mode 100644 src/libs/utils/executeondestruction.h diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index 5c2fd958d31..5f2785236d0 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -52,6 +52,7 @@ #include #include +#include #include #ifdef WITH_TESTS @@ -1059,16 +1060,6 @@ static TestPlan generateCustomTestPlan(IPlugin *plugin, const QList & return testPlan; } -class ExecuteOnDestruction -{ -public: - ExecuteOnDestruction(std::function code) : destructionCode(code) {} - ~ExecuteOnDestruction() { if (destructionCode) destructionCode(); } - -private: - const std::function destructionCode; -}; - void PluginManagerPrivate::startTests() { if (PluginManager::hasError()) { @@ -1084,7 +1075,8 @@ void PluginManagerPrivate::startTests() continue; // plugin not loaded const QList testObjects = plugin->createTestObjects(); - ExecuteOnDestruction deleteTestObjects([&]() { qDeleteAll(testObjects); }); + Utils::ExecuteOnDestruction deleteTestObjects([&]() { qDeleteAll(testObjects); }); + Q_UNUSED(deleteTestObjects) const bool hasDuplicateTestObjects = testObjects.size() != testObjects.toSet().size(); QTC_ASSERT(!hasDuplicateTestObjects, continue); diff --git a/src/libs/utils/executeondestruction.h b/src/libs/utils/executeondestruction.h new file mode 100644 index 00000000000..985df09e0ba --- /dev/null +++ b/src/libs/utils/executeondestruction.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef EXECUTEONDESTRUCTION_H +#define EXECUTEONDESTRUCTION_H + +#include + +namespace Utils { + +class ExecuteOnDestruction +{ +public: + ExecuteOnDestruction(std::function code) : destructionCode(code) {} + ~ExecuteOnDestruction() { if (destructionCode) destructionCode(); } + +private: + const std::function destructionCode; +}; + +} // Utils + +#endif // EXECUTEONDESTRUCTION_H diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri index 71151b6971e..fd7ced8e255 100644 --- a/src/libs/utils/utils-lib.pri +++ b/src/libs/utils/utils-lib.pri @@ -187,7 +187,8 @@ HEADERS += \ $$PWD/theme/theme.h \ $$PWD/theme/theme_p.h \ $$PWD/progressindicator.h \ - $$PWD/fadingindicator.h + $$PWD/fadingindicator.h \ + $$PWD/executeondestruction.h FORMS += $$PWD/filewizardpage.ui \ $$PWD/projectintropage.ui \ diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs index 9453e08902d..a31e35d7416 100644 --- a/src/libs/utils/utils.qbs +++ b/src/libs/utils/utils.qbs @@ -72,6 +72,7 @@ QtcLibrary { "environmentmodel.h", "execmenu.cpp", "execmenu.h", + "executeondestruction.h", "fadingindicator.cpp", "fadingindicator.h", "faketooltip.cpp", diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 95721873f41..076aac930f1 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -65,6 +65,7 @@ #include #include +#include #include #include #include @@ -2379,6 +2380,9 @@ IEditor *EditorManager::openEditorWithContents(Id editorId, EditorManager::gotoOtherSplit(); QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + Utils::ExecuteOnDestruction appRestoreCursor(&QApplication::restoreOverrideCursor); + Q_UNUSED(appRestoreCursor) + const QString title = makeTitleUnique(titlePattern); @@ -2392,20 +2396,16 @@ IEditor *EditorManager::openEditorWithContents(Id editorId, if (!title.isEmpty()) edt->document()->setPreferredDisplayName(title); - QApplication::restoreOverrideCursor(); activateEditor(edt, flags); return edt; } } edt = EditorManagerPrivate::createEditor(editorId, title); - if (!edt) { - QApplication::restoreOverrideCursor(); + if (!edt) return 0; - } if (!edt->document()->setContents(contents)) { - QApplication::restoreOverrideCursor(); delete edt; edt = 0; return 0; @@ -2418,7 +2418,6 @@ IEditor *EditorManager::openEditorWithContents(Id editorId, edt->document()->setPreferredDisplayName(title); EditorManagerPrivate::addEditor(edt); - QApplication::restoreOverrideCursor(); activateEditor(edt, flags); return edt; } From 9f545843d39926199124b21212d52e402129a5d5 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 13 Mar 2015 15:59:42 +0100 Subject: [PATCH 03/61] Search & Replace: Save some horizontal space Invoking global search & replace would greatly increase the main window's minimum size, so arrange the search and the replace parts vertically. Task-number: QTCREATORBUG-8770 Change-Id: Ia8ae8554a6c089e56b918192dc7ae33cf3e9a615 Reviewed-by: David Schulz --- .../coreplugin/find/searchresultwidget.cpp | 62 +++++++++++-------- .../coreplugin/find/searchresultwidget.h | 1 + 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/plugins/coreplugin/find/searchresultwidget.cpp b/src/plugins/coreplugin/find/searchresultwidget.cpp index 0ee63e7f919..1917d6ce4d4 100644 --- a/src/plugins/coreplugin/find/searchresultwidget.cpp +++ b/src/plugins/coreplugin/find/searchresultwidget.cpp @@ -104,11 +104,24 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) : topWidget->setLineWidth(1); } topWidget->setAutoFillBackground(true); - QHBoxLayout *topLayout = new QHBoxLayout(topWidget); - topLayout->setMargin(2); + auto topLayout = new QVBoxLayout(topWidget); + topLayout->setContentsMargins(2, 2, 2, 2); + topLayout->setSpacing(2); topWidget->setLayout(topLayout); layout->addWidget(topWidget); + auto topFindWidget = new QWidget(topWidget); + auto topFindLayout = new QHBoxLayout(topFindWidget); + topFindLayout->setMargin(0); + topFindWidget->setLayout(topFindLayout); + topLayout->addWidget(topFindWidget); + + m_topReplaceWidget = new QWidget(topWidget); + auto topReplaceLayout = new QHBoxLayout(m_topReplaceWidget); + topReplaceLayout->setMargin(0); + m_topReplaceWidget->setLayout(topReplaceLayout); + topLayout->addWidget(m_topReplaceWidget); + m_messageWidget = new QFrame; pal.setColor(QPalette::WindowText, creatorTheme()->color(Theme::CanceledSearchTextColor)); m_messageWidget->setPalette(pal); @@ -138,7 +151,7 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) : m_infoBarDisplay.setTarget(layout, 2); m_infoBarDisplay.setInfoBar(&m_infoBar); - m_descriptionContainer = new QWidget(topWidget); + m_descriptionContainer = new QWidget(topFindWidget); QHBoxLayout *descriptionLayout = new QHBoxLayout(m_descriptionContainer); m_descriptionContainer->setLayout(descriptionLayout); descriptionLayout->setMargin(0); @@ -150,28 +163,28 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) : m_searchTerm->setVisible(false); descriptionLayout->addWidget(m_label); descriptionLayout->addWidget(m_searchTerm); - m_cancelButton = new QToolButton(topWidget); + m_cancelButton = new QToolButton(topFindWidget); m_cancelButton->setText(tr("Cancel")); m_cancelButton->setToolButtonStyle(Qt::ToolButtonTextOnly); connect(m_cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); - m_searchAgainButton = new QToolButton(topWidget); + m_searchAgainButton = new QToolButton(topFindWidget); m_searchAgainButton->setToolTip(tr("Repeat the search with same parameters.")); m_searchAgainButton->setText(tr("Search again")); m_searchAgainButton->setToolButtonStyle(Qt::ToolButtonTextOnly); m_searchAgainButton->setVisible(false); connect(m_searchAgainButton, SIGNAL(clicked()), this, SLOT(searchAgain())); - m_replaceLabel = new QLabel(tr("Replace with:"), topWidget); - m_replaceTextEdit = new WideEnoughLineEdit(topWidget); + m_replaceLabel = new QLabel(tr("Replace with:"), m_topReplaceWidget); + m_replaceTextEdit = new WideEnoughLineEdit(m_topReplaceWidget); m_replaceTextEdit->setMinimumWidth(120); m_replaceTextEdit->setEnabled(false); m_replaceTextEdit->setTabOrder(m_replaceTextEdit, m_searchResultTreeView); - m_replaceButton = new QToolButton(topWidget); + m_replaceButton = new QToolButton(m_topReplaceWidget); m_replaceButton->setToolTip(tr("Replace all occurrences.")); m_replaceButton->setText(tr("Replace")); m_replaceButton->setToolButtonStyle(Qt::ToolButtonTextOnly); m_replaceButton->setEnabled(false); - m_preserveCaseCheck = new QCheckBox(topWidget); + m_preserveCaseCheck = new QCheckBox(m_topReplaceWidget); m_preserveCaseCheck->setText(tr("Preserve case")); m_preserveCaseCheck->setEnabled(false); @@ -180,22 +193,21 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) : connect(m_preserveCaseCheck, SIGNAL(clicked(bool)), plugin, SLOT(setPreserveCase(bool))); } - m_matchesFoundLabel = new QLabel(topWidget); + m_matchesFoundLabel = new QLabel(topFindWidget); updateMatchesFoundLabel(); - topLayout->addWidget(m_descriptionContainer); - topLayout->addWidget(m_cancelButton); - topLayout->addWidget(m_searchAgainButton); - topLayout->addWidget(m_replaceLabel); - topLayout->addWidget(m_replaceTextEdit); - topLayout->addWidget(m_replaceButton); - topLayout->addWidget(m_preserveCaseCheck); - topLayout->addStretch(2); - topLayout->addWidget(m_matchesFoundLabel); - topWidget->setMinimumHeight(m_cancelButton->sizeHint().height() - + topLayout->contentsMargins().top() + topLayout->contentsMargins().bottom() - + topWidget->lineWidth()); + topFindLayout->addWidget(m_descriptionContainer); + topFindLayout->addWidget(m_cancelButton); + topFindLayout->addWidget(m_searchAgainButton); + topFindLayout->addStretch(2); + topFindLayout->addWidget(m_matchesFoundLabel); + topReplaceLayout->addWidget(m_replaceLabel); + topReplaceLayout->addWidget(m_replaceTextEdit); + topReplaceLayout->addWidget(m_replaceButton); + topReplaceLayout->addWidget(m_preserveCaseCheck); + topReplaceLayout->addStretch(2); setShowReplaceUI(false); + setSupportPreserveCase(true); connect(m_searchResultTreeView, SIGNAL(jumpToSearchResult(SearchResultItem)), this, SLOT(handleJumpToSearchResult(SearchResultItem))); @@ -306,15 +318,13 @@ QString SearchResultWidget::textToReplace() const void SearchResultWidget::setSupportPreserveCase(bool enabled) { m_preserveCaseSupported = enabled; + m_preserveCaseCheck->setVisible(m_preserveCaseSupported); } void SearchResultWidget::setShowReplaceUI(bool visible) { m_searchResultTreeView->model()->setShowReplaceUI(visible); - m_replaceLabel->setVisible(visible); - m_replaceTextEdit->setVisible(visible); - m_replaceButton->setVisible(visible); - m_preserveCaseCheck->setVisible(visible && m_preserveCaseSupported); + m_topReplaceWidget->setVisible(visible); m_isShowingReplaceUI = visible; } diff --git a/src/plugins/coreplugin/find/searchresultwidget.h b/src/plugins/coreplugin/find/searchresultwidget.h index 6314f5e2ff2..2546f16d9e9 100644 --- a/src/plugins/coreplugin/find/searchresultwidget.h +++ b/src/plugins/coreplugin/find/searchresultwidget.h @@ -132,6 +132,7 @@ private: InfoBar m_infoBar; InfoBarDisplay m_infoBarDisplay; bool m_isShowingReplaceUI; + QWidget *m_topReplaceWidget; QLabel *m_replaceLabel; QLineEdit *m_replaceTextEdit; QToolButton *m_replaceButton; From 467c441c937c0b220e61f8a2977559ec225cf781 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 16 Mar 2015 09:10:36 +0100 Subject: [PATCH 04/61] Debugger: Fix using the same watcher number twice. Counting the watcher number in a global scope, so they don't get reinitialized incorrectly with a new engine. Change-Id: Ifd9efb320e2c0f20b2e2845348a98961f72bf28c Reviewed-by: Christian Stenger Reviewed-by: hjk --- src/plugins/debugger/watchhandler.cpp | 10 +++++----- src/plugins/debugger/watchhandler.h | 2 -- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 1b6e7fc38ba..a97f0726dac 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -69,6 +69,7 @@ enum { debugModel = 0 }; #define MODEL_DEBUG(s) do { if (debugModel) qDebug() << s; } while (0) static QHash theWatcherNames; +static int theWatcherCount = 0; static QHash theTypeFormats; static QHash theIndividualFormats; static int theUnprintableBase = -1; @@ -861,7 +862,7 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role theWatcherNames.remove(item->d.exp); item->d.exp = exp; item->d.name = QString::fromLatin1(exp); - theWatcherNames[exp] = m_handler->m_watcherCounter++; + theWatcherNames[exp] = theWatcherCount++; m_handler->saveWatchers(); if (engine()->state() == DebuggerNotReady) { item->d.setAllUnneeded(); @@ -1154,7 +1155,6 @@ void WatchModel::setCurrentItem(const QByteArray &iname) WatchHandler::WatchHandler(DebuggerEngine *engine) { m_engine = engine; - m_watcherCounter = sessionValue("Watchers").toStringList().count(); m_model = new WatchModel(this); m_contentsValid = false; m_contentsValid = true; // FIXME @@ -1318,7 +1318,7 @@ void WatchHandler::watchExpression(const QString &exp0, const QString &name) WatchData data; data.exp = exp.toLatin1(); data.name = name.isEmpty() ? exp : name; - theWatcherNames[data.exp] = m_watcherCounter++; + theWatcherNames[data.exp] = theWatcherCount++; saveWatchers(); if (exp.isEmpty()) @@ -1443,7 +1443,7 @@ void WatchHandler::clearWatches() m_model->m_watchRoot->removeChildren(); theWatcherNames.clear(); - m_watcherCounter = 0; + theWatcherCount = 0; updateWatchersWindow(); saveWatchers(); } @@ -1539,7 +1539,7 @@ void WatchHandler::loadSessionData() { loadFormats(); theWatcherNames.clear(); - m_watcherCounter = 0; + theWatcherCount = 0; QVariant value = sessionValue("Watchers"); m_model->m_watchRoot->removeChildren(); foreach (const QString &exp, value.toStringList()) diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index 338a443203e..a01e555b250 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -257,8 +257,6 @@ private: DebuggerEngine *m_engine; // Not owned. SeparatedView *m_separatedView; // Owned. - int m_watcherCounter; - bool m_contentsValid; bool m_resetLocationScheduled; }; From 40dd2481784488105f28bfefa31375ae8ec20e0b Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 6 Mar 2015 09:14:40 +0100 Subject: [PATCH 05/61] Debugger: Show progress indicator while updating locals. Change-Id: I4b26cbe71f5936f367f9add2b3a6c812446835d8 Reviewed-by: Christian Stenger Reviewed-by: hjk --- src/plugins/debugger/cdb/cdbengine.cpp | 2 ++ src/plugins/debugger/gdb/gdbengine.cpp | 2 ++ src/plugins/debugger/lldb/lldbengine.cpp | 2 ++ src/plugins/debugger/pdb/pdbengine.cpp | 1 + src/plugins/debugger/watchhandler.cpp | 11 +++++++++++ src/plugins/debugger/watchhandler.h | 4 ++++ src/plugins/debugger/watchwindow.cpp | 6 ++++++ 7 files changed, 28 insertions(+) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 0c7ef6663a5..2beaa27b500 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -1500,6 +1500,7 @@ void CdbEngine::updateLocals(bool newFrame) // Required arguments: frame str << blankSeparator << frameIndex; + watchHandler()->updateRequested(); postExtensionCommand("locals", arguments, 0, [this, newFrame](const CdbResponse &r) { handleLocals(r, newFrame); }); } @@ -1859,6 +1860,7 @@ void CdbEngine::handleRegistersExt(const CdbResponse &response) void CdbEngine::handleLocals(const CdbResponse &response, bool newFrame) { if (response.success) { + watchHandler()->updateFinished(); if (boolSetting(VerboseLog)) showMessage(QLatin1String("Locals: ") + QString::fromLatin1(response.extensionReply), LogDebug); WatchHandler *handler = watchHandler(); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 1eb2c4099e8..3ba9d509285 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3755,6 +3755,7 @@ void GdbEngine::handleVarAssign(const DebuggerResponse &) void GdbEngine::updateLocals() { watchHandler()->resetValueCache(); + watchHandler()->updateRequested(); updateLocalsPython(UpdateParameters()); } @@ -4767,6 +4768,7 @@ void GdbEngine::updateLocalsPython(const UpdateParameters ¶ms) void GdbEngine::handleStackFramePython(const DebuggerResponse &response, bool partial) { + watchHandler()->updateFinished(); if (response.resultClass == ResultDone) { QByteArray out = response.consoleStreamOutput; while (out.endsWith(' ') || out.endsWith('\n')) diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 4e0f538a382..a9fbab5d990 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -912,6 +912,7 @@ void LldbEngine::doUpdateLocals(UpdateParameters params) m_lastDebuggableCommand = cmd; m_lastDebuggableCommand.args.replace("\"passexceptions\":0", "\"passexceptions\":1"); + watchHandler()->updateRequested(); runCommand(cmd); reloadRegisters(); @@ -1009,6 +1010,7 @@ void LldbEngine::refreshLocals(const GdbMi &vars) } handler->purgeOutdatedItems(toDelete); + handler->updateFinished(); DebuggerToolTipManager::updateEngine(this); } diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp index 36a5a1f4a58..ee5afb470dd 100644 --- a/src/plugins/debugger/pdb/pdbengine.cpp +++ b/src/plugins/debugger/pdb/pdbengine.cpp @@ -664,6 +664,7 @@ void PdbEngine::updateLocals() //m_lastDebuggableCommand = cmd; //m_lastDebuggableCommand.args.replace("\"passexceptions\":0", "\"passexceptions\":1"); + watchHandler()->updateRequested(); runCommand(cmd); } diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index a97f0726dac..dcf621f738c 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -1177,6 +1177,7 @@ void WatchHandler::cleanup() m_model->m_expandedINames.clear(); theWatcherNames.remove(QByteArray()); m_model->reinitialize(); + emit m_model->updateFinished(); m_separatedView->hide(); } @@ -1271,6 +1272,16 @@ void WatchHandler::resetValueCache() }); } +void WatchHandler::updateRequested() +{ + emit m_model->updateRequested(); +} + +void WatchHandler::updateFinished() +{ + emit m_model->updateFinished(); +} + void WatchHandler::purgeOutdatedItems(const QSet &inames) { foreach (const QByteArray &iname, inames) { diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index a01e555b250..03ecdbf7696 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -177,6 +177,8 @@ signals: void itemIsExpanded(const QModelIndex &idx); void inameIsExpanded(const QByteArray &iname); void columnAdjustmentRequested(); + void updateRequested(); + void updateFinished(); }; class WatchHandler : public QObject @@ -242,6 +244,8 @@ public: void removeItemByIName(const QByteArray &iname); void removeAllData(bool includeInspectData = false); void resetValueCache(); + void updateRequested(); + void updateFinished(); void purgeOutdatedItems(const QSet &inames); private: diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index 12503058e55..90c376b8286 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -952,6 +952,12 @@ void WatchTreeView::setModel(QAbstractItemModel *model) this, &QAbstractItemView::setCurrentIndex); connect(watchModel, &WatchModelBase::itemIsExpanded, this, &WatchTreeView::handleItemIsExpanded); + if (m_type == LocalsType) { + connect(watchModel, &WatchModelBase::updateRequested, + this, &WatchTreeView::showProgressIndicator); + connect(watchModel, &WatchModelBase::updateFinished, + this, &WatchTreeView::hideProgressIndicator); + } } void WatchTreeView::rowActivated(const QModelIndex &index) From 779f55ff3796165785231aff9d00565aa378c48d Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 16 Mar 2015 11:25:19 +0100 Subject: [PATCH 06/61] Debugger: Report LLDB breakpoint address after resolving Task-number: QTCREATORBUG-14086 Change-Id: I7dcdc62196671583505a2e011ed04fbdd3227de6 Reviewed-by: Christian Stenger --- share/qtcreator/debugger/lldbbridge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index c9b8eb2d6ce..0460a4d689f 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -1388,7 +1388,7 @@ class Dumper(DumperBase): result += ',ignorecount="%s"' % loc.GetIgnoreCount() result += ',file="%s"' % lineEntry.GetFileSpec() result += ',line="%s"' % lineEntry.GetLine() - result += ',addr="%s"},' % loc.GetLoadAddress() + result += ',addr="%s"},' % addr.GetFileAddress() result += ']' if lineEntry is not None: result += ',file="%s"' % lineEntry.GetFileSpec() From 089f1b1bb3b69689aee444e478792a631b13f735 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 16 Mar 2015 10:43:01 +0100 Subject: [PATCH 07/61] ExternalTools: fix capitalization of UI strings Change-Id: I4ac7710070dd525ffddecc2012ab75cc84a3d26e Reviewed-by: Eike Ziller --- src/plugins/coreplugin/dialogs/externaltoolconfig.cpp | 2 +- src/plugins/coreplugin/dialogs/externaltoolconfig.ui | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp index 93073a76a42..30ea54670e3 100644 --- a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp +++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp @@ -657,5 +657,5 @@ void ExternalToolConfig::updateEnvironmentLabel() QString shortSummary = m_environment.join(QLatin1String("; ")); QFontMetrics fm(ui->environmentLabel->font()); shortSummary = fm.elidedText(shortSummary, Qt::ElideRight, ui->environmentLabel->width()); - ui->environmentLabel->setText(shortSummary.isEmpty() ? tr("No Changes to apply") : shortSummary); + ui->environmentLabel->setText(shortSummary.isEmpty() ? tr("No changes to apply.") : shortSummary); } diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.ui b/src/plugins/coreplugin/dialogs/externaltoolconfig.ui index 39beea46397..1c8a76c30e1 100644 --- a/src/plugins/coreplugin/dialogs/externaltoolconfig.ui +++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.ui @@ -231,7 +231,7 @@ - No Changes to apply. + No changes to apply. From c874e1dd73c2f152a5ff0b593d7f0c49d2f48a09 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Fri, 13 Mar 2015 15:40:57 +0100 Subject: [PATCH 08/61] QmakeProjectManager: Fix node addition order First add the nodes, then add the subnodes. This is the correct fix for Change-Id: I50834ba7e0221623abe2954c88c47322677c142d Task-number: QTCREATORBUG-14134 Reviewed-by: Christian Stenger Reviewed-by: Eike Ziller Reviewed-by: Orgad Shaneh --- src/plugins/projectexplorer/projectmodels.cpp | 4 ++-- src/plugins/qmakeprojectmanager/qmakenodes.cpp | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp index ade67e94900..b699f900395 100644 --- a/src/plugins/projectexplorer/projectmodels.cpp +++ b/src/plugins/projectexplorer/projectmodels.cpp @@ -427,7 +427,7 @@ void FlatModel::recursiveAddFileNodes(FolderNode *startNode, QList *list QList FlatModel::childNodes(FolderNode *parentNode, const QSet &blackList) const { - qCDebug(logger()) << "FlatModel::childNodes for " << parentNode->displayName(); + qCDebug(logger()) << " FlatModel::childNodes for " << parentNode->path(); QList nodeList; if (parentNode->nodeType() == SessionNodeType) { @@ -442,7 +442,7 @@ QList FlatModel::childNodes(FolderNode *parentNode, const QSet &bl recursiveAddFileNodes(parentNode, &nodeList, blackList + nodeList.toSet()); } Utils::sort(nodeList, sortNodes); - qCDebug(logger()) << " found" << nodeList.size() << "nodes"; + qCDebug(logger()) << " found" << nodeList.size() << "nodes"; return nodeList; } diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp index 673a27ebe36..b3886fe6c0e 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -2105,6 +2105,7 @@ void QmakeProFileNode::applyEvaluate(EvalResult *evalResult) QList toAdd; QList toRemove; + QList toUpdate; QList::const_iterator existingIt = existingProjectNodes.constBegin(); FileNameList::const_iterator newExactIt = result->newProjectFilesExact.constBegin(); @@ -2208,8 +2209,8 @@ void QmakeProFileNode::applyEvaluate(EvalResult *evalResult) QmakePriFileNode *qmakePriFileNode = new QmakePriFileNode(m_project, this, nodeToAdd); qmakePriFileNode->setParentFolderNode(this); // Needed for loop detection qmakePriFileNode->setIncludedInExactParse(fileExact != 0 && includedInExactParse()); - qmakePriFileNode->update(result->priFileResults[nodeToAdd]); toAdd << qmakePriFileNode; + toUpdate << qmakePriFileNode; } else { QmakeProFileNode *qmakeProFileNode = new QmakeProFileNode(m_project, nodeToAdd); qmakeProFileNode->setParentFolderNode(this); // Needed for loop detection @@ -2235,6 +2236,9 @@ void QmakeProFileNode::applyEvaluate(EvalResult *evalResult) if (!toAdd.isEmpty()) addProjectNodes(toAdd); + foreach (QmakePriFileNode *qmakePriFileNode, toUpdate) + qmakePriFileNode->update(result->priFileResults[qmakePriFileNode->path()]); + QmakePriFileNode::update(result->priFileResults[m_projectFilePath]); m_validParse = (result->state == EvalResult::EvalOk); From 5a1400c5f026feeeabbceba15e6fdfc0358955c2 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 16 Mar 2015 11:49:31 +0100 Subject: [PATCH 09/61] Valgrind: capitalize tool names in messages That is the way Valgrind.org writes them and the way we write them in the docs. Change-Id: Ib3775cb0a10e6946221d8aa842111d069231d36c Reviewed-by: hjk --- src/plugins/valgrind/valgrindplugin.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/valgrind/valgrindplugin.cpp b/src/plugins/valgrind/valgrindplugin.cpp index a3bf8b2176b..654dcfd7b59 100644 --- a/src/plugins/valgrind/valgrindplugin.cpp +++ b/src/plugins/valgrind/valgrindplugin.cpp @@ -115,14 +115,14 @@ bool ValgrindPlugin::initialize(const QStringList &, QString *) AnalyzerAction *action = 0; QString callgrindToolTip = tr("Valgrind Function Profile uses the " - "\"callgrind\" tool to record function calls when a program runs."); + "Callgrind tool to record function calls when a program runs."); QString memcheckToolTip = tr("Valgrind Analyze Memory uses the " - "\"memcheck\" tool to find memory leaks."); + "Memcheck tool to find memory leaks."); QString memcheckWithGdbToolTip = tr( - "Valgrind Analyze Memory with GDB uses the \"memcheck\" tool to find memory leaks.\n" - "When a problem is detected, the application is interrupted and can be debugged"); + "Valgrind Analyze Memory with GDB uses the Memcheck tool to find memory leaks.\n" + "When a problem is detected, the application is interrupted and can be debugged."); MemcheckTool *mcTool = m_memcheckTool; auto mcWidgetCreator = [mcTool] { return mcTool->createWidgets(); }; From deae570c5da2b923e8d6a70c955324b70559535f Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 16 Mar 2015 10:21:54 +0100 Subject: [PATCH 10/61] ProjectExplorer: fix punctuation of messages Change-Id: I76d5d516ffc8e184607a8a22fb8c8838eb3ebb1d Reviewed-by: Daniel Teske --- src/plugins/projectexplorer/projectexplorer.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 78ccc8d2692..5d6ebf31bc1 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -1247,7 +1247,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er // not be used in the Run/Build configuration pages. Utils::MacroExpander *expander = Utils::globalMacroExpander(); expander->registerFileVariables(Constants::VAR_CURRENTPROJECT_PREFIX, - tr("Current project's main file"), + tr("Current project's main file."), [this]() -> QString { Utils::FileName projectFilePath; if (Project *project = ProjectTree::currentProject()) @@ -1470,7 +1470,7 @@ void ProjectExplorerPlugin::extensionsInitialized() ProjectExplorerPlugin::openProject(fileName, &errorMessage); if (!errorMessage.isEmpty()) QMessageBox::critical(ICore::mainWindow(), - tr("Failed to open project"), errorMessage); + tr("Failed to open project."), errorMessage); return 0; }); @@ -2460,13 +2460,13 @@ QPair ProjectExplorerPluginPrivate::buildSettingsEnabledForSessio result.first = true; if (!SessionManager::hasProjects()) { result.first = false; - result.second = tr("No project loaded"); + result.second = tr("No project loaded."); } else if (BuildManager::isBuilding()) { result.first = false; - result.second = tr("A build is in progress"); + result.second = tr("A build is in progress."); } else if (!hasBuildSettings(0)) { result.first = false; - result.second = tr("Project has no build settings"); + result.second = tr("Project has no build settings."); } else { foreach (Project *project, SessionManager::projectOrder(0)) { if (project From 7450a09af3dfd5a6687a805be359dd7d54569cd9 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 11 Mar 2015 16:24:01 +0100 Subject: [PATCH 11/61] Plugin view: Fix sorting Broke after moving to Utils::TreeModel. Use QSortFilterProxyModel on top of TreeModel (can later be used for filtering as well). Additionally we need to make sure to report changes only for the changed column now, because otherwise QSortFilterProxyModel thinks that the change could make re-sorting necessary, and does that in a non-stable way. Change-Id: I9fd12c55a45aba4c05f8e318ae8ea9a4ab9f3310 Task-number: QTCREATORBUG-14107 Reviewed-by: Robert Loehning Reviewed-by: hjk --- src/libs/extensionsystem/pluginview.cpp | 16 +++++++++++----- src/libs/extensionsystem/pluginview.h | 5 +++++ src/libs/utils/treemodel.cpp | 8 ++++++++ src/libs/utils/treemodel.h | 1 + 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/libs/extensionsystem/pluginview.cpp b/src/libs/extensionsystem/pluginview.cpp index 21646f1d6ee..97b87f84db9 100644 --- a/src/libs/extensionsystem/pluginview.cpp +++ b/src/libs/extensionsystem/pluginview.cpp @@ -41,8 +41,9 @@ #include #include #include -#include #include +#include +#include /*! \class ExtensionSystem::PluginView @@ -153,8 +154,8 @@ public: { if (column == LoadedColumn && role == Qt::CheckStateRole) { m_spec->setEnabled(data.toBool()); - update(); - parent()->update(); + updateColumn(column); + parent()->updateColumn(column); emit m_view->pluginSettingsChanged(m_spec); return true; } @@ -280,13 +281,17 @@ PluginView::PluginView(QWidget *parent) m_categoryView->setColumnWidth(LoadedColumn, 40); m_categoryView->header()->setDefaultSectionSize(120); m_categoryView->header()->setMinimumSectionSize(35); + m_categoryView->header()->setSortIndicator(0, Qt::AscendingOrder); m_categoryView->setActivationMode(DoubleClickActivation); m_categoryView->setSelectionMode(QAbstractItemView::SingleSelection); m_categoryView->setSelectionBehavior(QAbstractItemView::SelectRows); m_model = new TreeModel(this); m_model->setHeader(QStringList() << tr("Name") << tr("Load") << tr("Version") << tr("Vendor")); - m_categoryView->setModel(m_model); + + m_sortModel = new QSortFilterProxyModel(this); + m_sortModel->setSourceModel(m_model); + m_categoryView->setModel(m_sortModel); QGridLayout *gridLayout = new QGridLayout(this); gridLayout->setContentsMargins(2, 2, 2, 2); @@ -325,7 +330,8 @@ PluginSpec *PluginView::currentPlugin() const PluginSpec *PluginView::pluginForIndex(const QModelIndex &index) const { - auto item = dynamic_cast(m_model->itemFromIndex(index)); + const QModelIndex &sourceIndex = m_sortModel->mapToSource(index); + auto item = dynamic_cast(m_model->itemFromIndex(sourceIndex)); return item ? item->m_spec: 0; } diff --git a/src/libs/extensionsystem/pluginview.h b/src/libs/extensionsystem/pluginview.h index e3ffc30897d..4cf31c9176c 100644 --- a/src/libs/extensionsystem/pluginview.h +++ b/src/libs/extensionsystem/pluginview.h @@ -37,6 +37,10 @@ #include #include +QT_BEGIN_NAMESPACE +class QSortFilterProxyModel; +QT_END_NAMESPACE + namespace Utils { class TreeItem; class TreeModel; @@ -71,6 +75,7 @@ private: Utils::TreeView *m_categoryView; Utils::TreeModel *m_model; + QSortFilterProxyModel *m_sortModel; friend class CollectionItem; friend class PluginItem; diff --git a/src/libs/utils/treemodel.cpp b/src/libs/utils/treemodel.cpp index 3013fac07d3..249c5e875e2 100644 --- a/src/libs/utils/treemodel.cpp +++ b/src/libs/utils/treemodel.cpp @@ -733,6 +733,14 @@ void TreeItem::update() } } +void TreeItem::updateColumn(int column) +{ + if (m_model) { + QModelIndex idx = index(); + m_model->dataChanged(idx.sibling(idx.row(), column), idx.sibling(idx.row(), column)); + } +} + TreeItem *TreeItem::firstChild() const { return m_children.isEmpty() ? 0 : m_children.first(); diff --git a/src/libs/utils/treemodel.h b/src/libs/utils/treemodel.h index 6e654fdfaab..23d2f1bea06 100644 --- a/src/libs/utils/treemodel.h +++ b/src/libs/utils/treemodel.h @@ -89,6 +89,7 @@ public: void insertChild(int pos, TreeItem *item); void removeChildren(); void update(); + void updateColumn(int column); void expand(); TreeItem *firstChild() const; TreeItem *lastChild() const; From f5498e9fdfd6a9032e54d9c416ebc991bf1f2b33 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 16 Mar 2015 11:33:15 +0100 Subject: [PATCH 12/61] VcsBase: Add comments for translators Change-Id: Ib805a1fe610fb9b6995ce628cf004cd0398e0bf3 Reviewed-by: Tobias Hunger --- src/plugins/vcsbase/wizard/vcsconfigurationpage.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/vcsbase/wizard/vcsconfigurationpage.cpp b/src/plugins/vcsbase/wizard/vcsconfigurationpage.cpp index 98137c1bd5a..c12703e661f 100644 --- a/src/plugins/vcsbase/wizard/vcsconfigurationpage.cpp +++ b/src/plugins/vcsbase/wizard/vcsconfigurationpage.cpp @@ -80,6 +80,7 @@ bool VcsConfigurationPageFactory::validateData(Id typeId, const QVariant &data, QTC_ASSERT(canCreate(typeId), return false); if (data.isNull() || data.type() != QVariant::Map) { + //: Do not translate "VcsConfiguration", because it is the id of a page. *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonWizard", "\"data\" must be a JSON object for \"VcsConfiguration\" pages."); return false; @@ -88,6 +89,7 @@ bool VcsConfigurationPageFactory::validateData(Id typeId, const QVariant &data, QVariantMap tmp = data.toMap(); const QString vcsId = tmp.value(QLatin1String("vcsId")).toString(); if (vcsId.isEmpty()) { + //: Do not translate "VcsConfiguration", because it is the id of a page. *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonWizard", "\"VcsConfiguration\" page requires a \"vcsId\" set."); return false; @@ -145,14 +147,17 @@ void VcsConfigurationPage::initializePage() { if (!d->m_versionControlId.isEmpty()) { auto jw = qobject_cast(wizard()); - if (!jw) + if (!jw) { + //: Do not translate "VcsConfiguration", because it is the id of a page. emit reportError(tr("No version control set on \"VcsConfiguration\" page.")); + } const QString vcsId = jw ? jw->expander()->expand(d->m_versionControlId) : d->m_versionControlId; d->m_versionControl = VcsManager::versionControl(Id::fromString(vcsId)); if (!d->m_versionControl) { emit reportError( + //: Do not translate "VcsConfiguration", because it is the id of a page. tr("\"vcsId\" (\"%1\") is invalid for \"VcsConfiguration\" page. " "Possible values are: %2.") .arg(vcsId) From 51edafece5b4a2bbf163d131ae606e38af00f895 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 16 Mar 2015 13:14:28 +0100 Subject: [PATCH 13/61] Debugger: Rename WatchItem::{color->valueColor} It's the color of the value field, not of the whole item. Change-Id: I1dd63ae21469ec784aefa278d379f819280067d9 Reviewed-by: Christian Stenger --- src/plugins/debugger/debuggertooltipmanager.cpp | 6 +++--- src/plugins/debugger/watchhandler.cpp | 4 ++-- src/plugins/debugger/watchhandler.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/plugins/debugger/debuggertooltipmanager.cpp b/src/plugins/debugger/debuggertooltipmanager.cpp index 5eb5c59883e..fc1bd3626b5 100644 --- a/src/plugins/debugger/debuggertooltipmanager.cpp +++ b/src/plugins/debugger/debuggertooltipmanager.cpp @@ -208,7 +208,7 @@ public: QString value; QString type; QString expression; - QColor color; + QColor valueColor; bool expandable; QByteArray iname; }; @@ -219,7 +219,7 @@ ToolTipWatchItem::ToolTipWatchItem(WatchItem *item) value = item->displayValue(); type = item->displayType(); iname = item->d.iname; - color = item->color(); + valueColor = item->valueColor(); expandable = item->d.hasChildren; expression = item->expression(); foreach (TreeItem *child, item->children()) @@ -303,7 +303,7 @@ QVariant ToolTipWatchItem::data(int column, int role) const case Qt::ForegroundRole: if (model() && static_cast(model())->m_enabled) { if (column == 1) - return color; + return valueColor; return QVariant(); } return QColor(140, 140, 140); diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index dcf621f738c..1c00848b928 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -721,7 +721,7 @@ QString WatchItem::displayType() const return result; } -QColor WatchItem::color() const +QColor WatchItem::valueColor() const { static const QColor red(200, 0, 0); static const QColor gray(140, 140, 140); @@ -783,7 +783,7 @@ QVariant WatchItem::data(int column, int role) const case Qt::ForegroundRole: if (column == 1) - return color(); + return valueColor(); case LocalsExpressionRole: return expression(); diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index 03ecdbf7696..d97dffd4703 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -73,7 +73,7 @@ public: QVariant editValue() const; int editType() const; - QColor color() const; + QColor valueColor() const; int requestedFormat() const; void showInEditorHelper(QString *contents, int depth) const; From 70c475c8470f8ff6a889dfa936606452a954f1c1 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Fri, 6 Mar 2015 08:35:55 +0200 Subject: [PATCH 14/61] Project: Exclude project directory from include path Some environments include the project directory by default, and some don't (e.g. qbs). In order to avoid compilation errors on the environments that don't, unconditionally exclude the project directory. Change-Id: I8552a269735b42efff1839fb18ce863eed711b7a Reviewed-by: Oswald Buddenhagen Reviewed-by: Eike Ziller --- qtcreator.pri | 4 +++- src/qtcreatorplugin.pri | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/qtcreator.pri b/qtcreator.pri index 04a2cf76e5b..7c8cd355729 100644 --- a/qtcreator.pri +++ b/qtcreator.pri @@ -107,7 +107,9 @@ for(dir, QTC_PLUGIN_DIRS) { INCLUDEPATH += $$dir } -CONFIG += depend_includepath +CONFIG += \ + depend_includepath \ + no_include_pwd LIBS += -L$$IDE_LIBRARY_PATH diff --git a/src/qtcreatorplugin.pri b/src/qtcreatorplugin.pri index a478f498aa3..5381b6de835 100644 --- a/src/qtcreatorplugin.pri +++ b/src/qtcreatorplugin.pri @@ -62,6 +62,7 @@ isEmpty(USE_USER_DESTDIR) { DESTDIR = "$$DESTDIRBASE/QtProject/$$DESTDIRAPPNAME/plugins/$$QTCREATOR_VERSION" } LIBS += -L$$DESTDIR +INCLUDEPATH += $$OUT_PWD # copy the plugin spec isEmpty(TARGET) { From fb4af50bf6b883bde026b9121bbc8519322367f8 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 16 Mar 2015 13:36:35 +0100 Subject: [PATCH 15/61] Debugger: Add delay before showing progress indicator. Change-Id: I70dc3997800649e6920c6a6bece9aef98f2b2146 Reviewed-by: Christian Stenger --- src/plugins/debugger/watchhandler.cpp | 7 ++++++- src/plugins/debugger/watchhandler.h | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 1c00848b928..8d9e900313e 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -55,6 +55,7 @@ #include #include +#include #include #include @@ -1160,6 +1161,9 @@ WatchHandler::WatchHandler(DebuggerEngine *engine) m_contentsValid = true; // FIXME m_resetLocationScheduled = false; m_separatedView = new SeparatedView; + m_requestUpdateTimer = new QTimer(this); + m_requestUpdateTimer->setSingleShot(true); + connect(m_requestUpdateTimer, &QTimer::timeout, m_model, &WatchModel::updateRequested); } WatchHandler::~WatchHandler() @@ -1274,11 +1278,12 @@ void WatchHandler::resetValueCache() void WatchHandler::updateRequested() { - emit m_model->updateRequested(); + m_requestUpdateTimer->start(80); } void WatchHandler::updateFinished() { + m_requestUpdateTimer->stop(); emit m_model->updateFinished(); } diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index d97dffd4703..4f898c39331 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -38,6 +38,10 @@ #include #include +QT_BEGIN_NAMESPACE +class QTimer; +QT_END_NAMESPACE + namespace Debugger { namespace Internal { @@ -260,6 +264,7 @@ private: WatchModel *m_model; // Owned. DebuggerEngine *m_engine; // Not owned. SeparatedView *m_separatedView; // Owned. + QTimer *m_requestUpdateTimer; // Owned. bool m_contentsValid; bool m_resetLocationScheduled; From 31b3855a8cca7e678f7b3fd5f6de99a33febe03c Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 16 Mar 2015 12:38:31 +0100 Subject: [PATCH 16/61] BareMetal: fix language in messages Change-Id: Ic1c39dc3b7a9b45d8e96b1bd215f0379892730c4 Reviewed-by: Denis Shienkov Reviewed-by: Eike Ziller --- src/plugins/baremetal/gdbserverprovider.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/baremetal/gdbserverprovider.cpp b/src/plugins/baremetal/gdbserverprovider.cpp index 5f49c5d0853..7bce6c7af4b 100644 --- a/src/plugins/baremetal/gdbserverprovider.cpp +++ b/src/plugins/baremetal/gdbserverprovider.cpp @@ -356,14 +356,14 @@ void GdbServerProviderConfigWidget::setFromProvider() QString GdbServerProviderConfigWidget::defaultInitCommandsTooltip() { return QCoreApplication::translate("BareMetal", - "Enter GDB commands to reset of the board, " + "Enter GDB commands to reset the board, " "and to write the nonvolatile memory."); } QString GdbServerProviderConfigWidget::defaultResetCommandsTooltip() { return QCoreApplication::translate("BareMetal", - "Enter GDB commands to hardware reset. " + "Enter GDB commands to reset the hardware. " "The MCU should be halted after this commands."); } From 7d6fd6ce5ed965529cb709c8a7bbfa56ee15f65e Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 16 Mar 2015 13:21:02 +0100 Subject: [PATCH 17/61] Debugger: inline DebuggerPluginPrivate::updateWatchersWindow ... into its only caller. Change-Id: I5521bc92351eecea5154070d0ee0f229edafc51b Reviewed-by: Christian Stenger --- src/plugins/debugger/debuggerplugin.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 76c7a0add5d..1a14e3f9700 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -748,7 +748,6 @@ public: void fontSettingsChanged(const FontSettings &settings); void updateState(DebuggerEngine *engine); - void updateWatchersWindow(bool showWatch, bool showReturn); void onCurrentProjectChanged(Project *project); void sessionLoaded(); @@ -1948,12 +1947,6 @@ void DebuggerPluginPrivate::setInitialState() action(ExpandStack)->setEnabled(false); } -void DebuggerPluginPrivate::updateWatchersWindow(bool showWatch, bool showReturn) -{ - m_watchersWindow->setVisible(showWatch); - m_returnWindow->setVisible(showReturn); -} - void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) { QTC_ASSERT(engine, return); @@ -3140,7 +3133,8 @@ void updateState(DebuggerEngine *engine) void updateWatchersWindow(bool showWatch, bool showReturn) { - dd->updateWatchersWindow(showWatch, showReturn); + dd->m_watchersWindow->setVisible(showWatch); + dd->m_returnWindow->setVisible(showReturn); } QIcon locationMarkIcon() From ceb034938022eade31b398249ae348c722131c08 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 16 Mar 2015 14:26:43 +0100 Subject: [PATCH 18/61] ProjectExplorer: fix one more capitalization issue Change-Id: I92f6e0044ce240e21a3f5865888268bb2bd61de0 Reviewed-by: Daniel Teske --- 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 1d92e031f4f..c4653bbb0e5 100644 --- a/src/plugins/projectexplorer/kitinformationconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitinformationconfigwidget.cpp @@ -413,7 +413,7 @@ void KitEnvironmentConfigWidget::refresh() QString shortSummary = Utils::EnvironmentItem::toStringList(changes).join(QLatin1String("; ")); QFontMetrics fm(m_summaryLabel->font()); shortSummary = fm.elidedText(shortSummary, Qt::ElideRight, m_summaryLabel->width()); - m_summaryLabel->setText(shortSummary.isEmpty() ? tr("No Changes to apply") : shortSummary); + m_summaryLabel->setText(shortSummary.isEmpty() ? tr("No changes to apply.") : shortSummary); if (m_editor) m_editor->setPlainText(Utils::EnvironmentItem::toStringList(changes).join(QLatin1Char('\n'))); } From 6a3d376cb2087d8b12f040056001302843f1d09d Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 16 Mar 2015 14:10:48 +0100 Subject: [PATCH 19/61] JsonWizard: use double quotes for emphasis Change-Id: I1b30fc146764517ef00949b9f5ecc3266c03fc78 Reviewed-by: Tobias Hunger --- .../jsonwizard/jsonfieldpage.cpp | 24 +++++++++---------- .../jsonwizard/jsonsummarypage.cpp | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp index 0f6e9edcecc..334d73004d4 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp @@ -148,14 +148,14 @@ JsonFieldPage::Field *JsonFieldPage::Field::parse(const QVariant &input, QString const QString type = tmp.value(QLatin1String(TYPE_KEY)).toString(); if (type.isEmpty()) { *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", - "Field '%1' has no type.").arg(name); + "Field \"%1\" has no type.").arg(name); return 0; } Field *data = createFieldData(type); if (!data) { *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", - "Field '%1' has unsupported type '%2'.") + "Field \"%1\" has unsupported type \"%2\".") .arg(name).arg(type); return 0; } @@ -171,7 +171,7 @@ JsonFieldPage::Field *JsonFieldPage::Field::parse(const QVariant &input, QString QVariant dataVal = tmp.value(QLatin1String(DATA_KEY)); if (!data->parseData(dataVal, errorMessage)) { *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", - "When parsing Field '%1': %2") + "When parsing Field \"%1\": %2") .arg(name).arg(*errorMessage); delete data; return 0; @@ -278,7 +278,7 @@ bool JsonFieldPage::SpacerField::parseData(const QVariant &data, QString *errorM if (!ok) { *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", - "'factor' is no integer value."); + "\"factor\" is no integer value."); return false; } @@ -518,9 +518,9 @@ bool JsonFieldPage::PathChooserField::parseData(const QVariant &data, QString *e m_kind = PathChooser::Any; } else { *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", - "kind '%1' is not one of the supported 'existingDirectory', " - "'directory', 'file', 'saveFile', 'existingCommand', " - "'command', 'any'.") + "kind \"%1\" is not one of the supported \"existingDirectory\", " + "\"directory\", \"file\", \"saveFile\", \"existingCommand\", " + "\"command\", \"any\".") .arg(kindStr); return false; } @@ -664,7 +664,7 @@ QPair parseComboBoxItem(const QVariant &item, QString *errorMe QString value = tmp.value(QLatin1String("value"), QString()).toString(); if (key.isNull() || key.isEmpty()) { *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", - "No 'key' found in ComboBox items."); + "No \"key\" found in ComboBox items."); return qMakePair(QString(), QString()); } if (value.isNull()) @@ -690,25 +690,25 @@ bool JsonFieldPage::ComboBoxField::parseData(const QVariant &data, QString *erro m_index = tmp.value(QLatin1String("index"), 0).toInt(&ok); if (!ok) { *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", - "ComboBox 'index' is not an integer value."); + "ComboBox \"index\" is not an integer value."); return false; } m_disabledIndex = tmp.value(QLatin1String("disabledIndex"), -1).toInt(&ok); if (!ok) { *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", - "ComboBox 'disabledIndex' is not an integer value."); + "ComboBox \"disabledIndex\" is not an integer value."); return false; } QVariant value = tmp.value(QLatin1String("items")); if (value.isNull()) { *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", - "ComboBox 'items' missing."); + "ComboBox \"items\" missing."); return false; } if (value.type() != QVariant::List) { *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", - "ComboBox 'items' is not a list."); + "ComboBox \"items\" is not a list."); return false; } diff --git a/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.cpp index b186169d1e3..e0e3f900b02 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.cpp @@ -150,7 +150,7 @@ void JsonSummaryPage::triggerCommit(const JsonWizard::GeneratorFiles &files) QString errorMessage; if (!runVersionControl(coreFiles, &errorMessage)) { QMessageBox::critical(wizard(), tr("Failed to Commit to Version Control"), - tr("Error message from Version Control System: '%1'.") + tr("Error message from Version Control System: \"%1\".") .arg(errorMessage)); } } From 1de7c954efa8ed563f02be36df21f86adb3ed485 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 16 Mar 2015 13:08:25 +0100 Subject: [PATCH 20/61] ToolChain: Make toolchain combobox in kits active again Task-number: QTCREATORBUG-14138 Change-Id: I33656e75456832e53cf0b68d319213ea51f3907a Reviewed-by: Christian Stenger --- src/plugins/projectexplorer/kitinformationconfigwidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/projectexplorer/kitinformationconfigwidget.cpp b/src/plugins/projectexplorer/kitinformationconfigwidget.cpp index c4653bbb0e5..52f35255e51 100644 --- a/src/plugins/projectexplorer/kitinformationconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitinformationconfigwidget.cpp @@ -166,6 +166,8 @@ void ToolChainInformationConfigWidget::refresh() foreach (ToolChain *tc, ToolChainManager::toolChains()) m_comboBox->addItem(tc->displayName(), tc->id()); + m_comboBox->setEnabled(m_comboBox->count() > 1); + m_comboBox->setCurrentIndex(indexOf(ToolChainKitInformation::toolChain(m_kit))); m_ignoreChanges = false; } From 972a306d5604b56bbdd555d9e9d8dda33b72975c Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 16 Mar 2015 14:06:37 +0100 Subject: [PATCH 21/61] DocumentManager: Treat documents without path as temporary Treat documents without path as temporary when trying to come up with a directory to open the file dialog in. Task-number: QTCREATORBUG-14131 Change-Id: I266fe6608b7c98b479f86412a0892413e1b99bb2 Reviewed-by: Eike Ziller --- src/plugins/coreplugin/documentmanager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp index 165b44b04fa..73b035eda34 100644 --- a/src/plugins/coreplugin/documentmanager.cpp +++ b/src/plugins/coreplugin/documentmanager.cpp @@ -1257,8 +1257,9 @@ void readSettings() QString DocumentManager::fileDialogInitialDirectory() { - if (EditorManager::currentDocument() && !EditorManager::currentDocument()->isTemporary()) - return QFileInfo(EditorManager::currentDocument()->filePath().toString()).absolutePath(); + IDocument *doc = EditorManager::currentDocument(); + if (doc && !doc->isTemporary() && !doc->filePath().isEmpty()) + return doc->filePath().toFileInfo().absolutePath(); if (!d->m_defaultLocationForNewFiles.isEmpty()) return d->m_defaultLocationForNewFiles; return d->m_lastVisitedDirectory; From 85f10dcaaa2ddeddffb9d6dc1ba98139f4c2c935 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 16 Mar 2015 15:40:49 +0100 Subject: [PATCH 22/61] ToolChains: Fix enabling the toolchain combobox in the Kits page Change-Id: I96b44e2febf070f4eea4a5b5878382dd8b374564 Reviewed-by: Daniel Teske --- .../kitinformationconfigwidget.cpp | 27 +++++++------------ .../kitinformationconfigwidget.h | 2 +- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/plugins/projectexplorer/kitinformationconfigwidget.cpp b/src/plugins/projectexplorer/kitinformationconfigwidget.cpp index 52f35255e51..1aaa02a0672 100644 --- a/src/plugins/projectexplorer/kitinformationconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitinformationconfigwidget.cpp @@ -127,10 +127,10 @@ void SysRootInformationConfigWidget::pathWasChanged() ToolChainInformationConfigWidget::ToolChainInformationConfigWidget(Kit *k, const KitInformation *ki) : KitConfigWidget(k, ki), - m_ignoreChanges(false) + m_ignoreChanges(false), + m_isReadOnly(false) { m_comboBox = new QComboBox; - m_comboBox->setEnabled(false); m_comboBox->setToolTip(toolTip()); refresh(); @@ -166,7 +166,12 @@ void ToolChainInformationConfigWidget::refresh() foreach (ToolChain *tc, ToolChainManager::toolChains()) m_comboBox->addItem(tc->displayName(), tc->id()); - m_comboBox->setEnabled(m_comboBox->count() > 1); + if (m_comboBox->count() == 0) { + m_comboBox->addItem(tr(""), QString()); + m_comboBox->setEnabled(false); + } else { + m_comboBox->setEnabled(m_comboBox->count() > 1 && !m_isReadOnly); + } m_comboBox->setCurrentIndex(indexOf(ToolChainKitInformation::toolChain(m_kit))); m_ignoreChanges = false; @@ -174,6 +179,7 @@ void ToolChainInformationConfigWidget::refresh() void ToolChainInformationConfigWidget::makeReadOnly() { + m_isReadOnly = true; m_comboBox->setEnabled(false); } @@ -201,21 +207,6 @@ void ToolChainInformationConfigWidget::currentToolChainChanged(int idx) ToolChainKitInformation::setToolChain(m_kit, ToolChainManager::findToolChain(id)); } -void ToolChainInformationConfigWidget::updateComboBox() -{ - // remove unavailable tool chain: - int pos = indexOf(0); - if (pos >= 0) - m_comboBox->removeItem(pos); - - if (m_comboBox->count() == 0) { - m_comboBox->addItem(tr(""), QString()); - m_comboBox->setEnabled(false); - } else { - m_comboBox->setEnabled(true); - } -} - int ToolChainInformationConfigWidget::indexOf(const ToolChain *tc) { const QString id = tc ? tc->id() : QString(); diff --git a/src/plugins/projectexplorer/kitinformationconfigwidget.h b/src/plugins/projectexplorer/kitinformationconfigwidget.h index 40b47152f5c..d9a055be7d1 100644 --- a/src/plugins/projectexplorer/kitinformationconfigwidget.h +++ b/src/plugins/projectexplorer/kitinformationconfigwidget.h @@ -104,12 +104,12 @@ private slots: void currentToolChainChanged(int idx); private: - void updateComboBox(); int indexOf(const ToolChain *tc); QComboBox *m_comboBox; QPushButton *m_manageButton; bool m_ignoreChanges; + bool m_isReadOnly; }; // -------------------------------------------------------------------------- From 9e2501c3a2f1136357f2be828be42c30b7b29637 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 16 Mar 2015 15:40:37 +0100 Subject: [PATCH 23/61] DiffEditor: use sentence style capitalization for labels Change-Id: I3d8142d934b126bf13cab4729f6ed3f46cadbcea Reviewed-by: Tobias Hunger --- src/plugins/diffeditor/diffeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/diffeditor/diffeditor.cpp b/src/plugins/diffeditor/diffeditor.cpp index 498945f8da3..bd514fd9133 100644 --- a/src/plugins/diffeditor/diffeditor.cpp +++ b/src/plugins/diffeditor/diffeditor.cpp @@ -326,7 +326,7 @@ QWidget *DiffEditor::toolBar() m_contextLabel = new QLabel(m_toolBar); - m_contextLabel->setText(tr("Context Lines:")); + m_contextLabel->setText(tr("Context lines:")); m_contextLabel->setContentsMargins(6, 0, 6, 0); m_toolBar->addWidget(m_contextLabel); From 51513afa6191c06bb6f947113f02518400063707 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 16 Mar 2015 16:03:50 +0100 Subject: [PATCH 24/61] QMakeProjectManager: add full stop to end of message Change-Id: Ie7e8ed6ba3f42e357e2443e7c107aa37d2f23d6d Reviewed-by: Daniel Teske --- src/plugins/qmakeprojectmanager/qmakenodes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp index b3886fe6c0e..4c66f67b2ae 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -2383,7 +2383,7 @@ FileNameList QmakeProFileNode::subDirsPaths(QtSupport::ProFileReader *reader, } } else { if (errors) - errors->append(QCoreApplication::translate("QmakeProFileNode", "Could not find .pro file for sub dir \"%1\" in \"%2\"") + errors->append(QCoreApplication::translate("QmakeProFileNode", "Could not find .pro file for subdirectory \"%1\" in \"%2\".") .arg(subDirVar).arg(realDir)); } } From 2bf615249583680e4203764c7bba0f36fecf4513 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 16 Mar 2015 15:34:45 +0100 Subject: [PATCH 25/61] Debugger: fix UI text capitalization and punctuation Added full stops to ends of messages. Used book-style capitalization for message box titles. Wrote "operating system" in lower case. Change-Id: I8cee1a1c7f4ae55952daa507395845feae203ab9 Reviewed-by: hjk --- src/plugins/debugger/debuggerengine.cpp | 8 ++++---- src/plugins/debugger/terminal.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index ef7c3fd72ce..c2a826b3902 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -1204,7 +1204,7 @@ void DebuggerEngine::notifyDebuggerProcessFinished(int exitCode, notifyEngineIll(); // Initiate shutdown sequence const QString msg = exitStatus == QProcess::CrashExit ? tr("The %1 process terminated.") : - tr("The %2 process terminated unexpectedly (exitCode %1)").arg(exitCode); + tr("The %2 process terminated unexpectedly (exit code %1).").arg(exitCode); AsynchronousMessageBox::critical(tr("Unexpected %1 Exit").arg(backendName), msg.arg(backendName)); break; @@ -1712,7 +1712,7 @@ bool DebuggerEngine::isDying() const QString DebuggerEngine::msgStopped(const QString &reason) { - return reason.isEmpty() ? tr("Stopped.") : tr("Stopped: \"%1\"").arg(reason); + return reason.isEmpty() ? tr("Stopped.") : tr("Stopped: \"%1\".").arg(reason); } QString DebuggerEngine::msgStoppedBySignal(const QString &meaning, @@ -1739,11 +1739,11 @@ void DebuggerEngine::showStoppedBySignalMessageBox(QString meaning, QString name if (meaning.isEmpty()) meaning = QLatin1Char(' ') + tr("", "meaning") + QLatin1Char(' '); const QString msg = tr("

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

" + "signal from the operating system.

" "" "
Signal name : %1
Signal meaning : %2
") .arg(name, meaning); - AsynchronousMessageBox::information(tr("Signal received"), msg); + AsynchronousMessageBox::information(tr("Signal Received"), msg); } void DebuggerEngine::showStoppedByExceptionMessageBox(const QString &description) diff --git a/src/plugins/debugger/terminal.cpp b/src/plugins/debugger/terminal.cpp index e133f365724..ee576d45d7c 100644 --- a/src/plugins/debugger/terminal.cpp +++ b/src/plugins/debugger/terminal.cpp @@ -90,7 +90,7 @@ void Terminal::setup() return; } if (!S_ISCHR(s.st_mode)) { - error(tr("Terminal: Slave is no character device")); + error(tr("Terminal: Slave is no character device.")); return; } From b5869e97e99fa1af343b805b26652e8f2d949c42 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Mon, 16 Mar 2015 16:14:00 +0100 Subject: [PATCH 26/61] Fix crash on FlatModel::added with empty list Change-Id: I6a5970eb9ccd76e730203c2d95dbd4e4dbb4af8a Reviewed-by: hjk --- src/plugins/projectexplorer/projectmodels.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp index b699f900395..5986f548763 100644 --- a/src/plugins/projectexplorer/projectmodels.cpp +++ b/src/plugins/projectexplorer/projectmodels.cpp @@ -617,6 +617,12 @@ void FlatModel::added(FolderNode* parentNode, const QList &newNodeList) qCDebug(logger()) << "FlatModel::added" << parentNode->path() << newNodeList.size() << "nodes"; QModelIndex parentIndex = indexForNode(parentNode); // Old list + + if (newNodeList.isEmpty()) { + qCDebug(logger()) << " newNodeList empty"; + return; + } + QHash >::const_iterator it = m_childNodes.constFind(parentNode); if (it == m_childNodes.constEnd()) { if (!parentIndex.isValid()) { From da1c4df7b165506092640a5233b8ce993a0fc7b4 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 16 Mar 2015 16:05:01 +0100 Subject: [PATCH 27/61] GenericHighlighter: add full stops to end of messages Start messages with an initial capital letter. Change-Id: Ie22a5ecffd8a7dc9dc2bb45d9e3a03eb30775744 Reviewed-by: Orgad Shaneh --- .../texteditor/generichighlighter/highlightdefinition.cpp | 6 +++--- src/plugins/texteditor/generichighlighter/highlighter.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/texteditor/generichighlighter/highlightdefinition.cpp b/src/plugins/texteditor/generichighlighter/highlightdefinition.cpp index 37bd044f724..f40b8de20e1 100644 --- a/src/plugins/texteditor/generichighlighter/highlightdefinition.cpp +++ b/src/plugins/texteditor/generichighlighter/highlightdefinition.cpp @@ -48,13 +48,13 @@ QSharedPointer createHelper(const QString &name, Container &container) { if (name.isEmpty()) { throw HighlighterException( - QCoreApplication::translate("GenericHighlighter", "Element name is empty")); + QCoreApplication::translate("GenericHighlighter", "Element name is empty.")); } if (container.contains(name)) { throw HighlighterException( QCoreApplication::translate("GenericHighlighter", - "Duplicate element name \"%1\"").arg(name)); + "Duplicate element name \"%1\".").arg(name)); } return container.insert(name, QSharedPointer(new Element)).value(); @@ -68,7 +68,7 @@ findHelper(const QString &name, const Container &container) if (it == container.end()) { throw HighlighterException( QCoreApplication::translate("GenericHighlighter", - "name \"%1\" not found").arg(name)); + "Name \"%1\" not found.").arg(name)); } return it.value(); diff --git a/src/plugins/texteditor/generichighlighter/highlighter.cpp b/src/plugins/texteditor/generichighlighter/highlighter.cpp index 49c8a5b5e4e..b2cde3ac275 100644 --- a/src/plugins/texteditor/generichighlighter/highlighter.cpp +++ b/src/plugins/texteditor/generichighlighter/highlighter.cpp @@ -396,7 +396,7 @@ void Highlighter::changeContext(const QString &contextName, for (int i = 0; i < list.size(); ++i) { if (m_contexts.isEmpty()) { throw HighlighterException( - QCoreApplication::translate("GenericHighlighter", "Reached empty context")); + QCoreApplication::translate("GenericHighlighter", "Reached empty context.")); } m_contexts.pop_back(); } From ec14e8bb0c9217efe89c83939ad437cc945ac4ce Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 13 Mar 2015 10:22:47 +0100 Subject: [PATCH 28/61] AndroidManifestWidget: Hide the marks column in source mode We don't need to set breakpoints and cannot set bookmarks. So, let's save the space. Change-Id: I7ff21464f2af104d7a4a7906acfb6c2917c8f7b2 Reviewed-by: Daniel Teske --- src/plugins/android/androidmanifesteditorwidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/android/androidmanifesteditorwidget.cpp b/src/plugins/android/androidmanifesteditorwidget.cpp index 9d69516c36b..f88c79af5f4 100644 --- a/src/plugins/android/androidmanifesteditorwidget.cpp +++ b/src/plugins/android/androidmanifesteditorwidget.cpp @@ -1440,5 +1440,6 @@ AndroidManifestTextEditorWidget::AndroidManifestTextEditorWidget(AndroidManifest setTextDocument(TextEditor::TextDocumentPtr(new AndroidManifestDocument(parent))); textDocument()->setMimeType(QLatin1String(Constants::ANDROID_MANIFEST_MIME_TYPE)); setupGenericHighlighter(); + setMarksVisible(false); } From ac01185f5e6b2a9e08cce638e3e847dcadeb768f Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 16 Mar 2015 14:53:19 +0100 Subject: [PATCH 29/61] BareMetal: use book-style capitalization for combobox items Change-Id: Ia2f57eb721cd761ba7c71e58a9b37a3c3fbcc043 Reviewed-by: Eike Ziller Reviewed-by: Denis Shienkov --- src/plugins/baremetal/gdbserverprovider.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/baremetal/gdbserverprovider.cpp b/src/plugins/baremetal/gdbserverprovider.cpp index 7bce6c7af4b..f43504e9720 100644 --- a/src/plugins/baremetal/gdbserverprovider.cpp +++ b/src/plugins/baremetal/gdbserverprovider.cpp @@ -317,10 +317,10 @@ void GdbServerProviderConfigWidget::populateStartupModes() m_startupModeComboBox->insertItem( idx, (m == GdbServerProvider::NoStartup) - ? tr("No startup") + ? tr("No Startup") : ((m == GdbServerProvider::StartupOnNetwork) - ? tr("Startup in TCP/IP mode") - : tr("Startup in Pipe mode")), + ? tr("Startup in TCP/IP Mode") + : tr("Startup in Pipe Mode")), m); } } From 7c4bf23b09b58d49b6b983020bd9818bb6a1adf1 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 16 Mar 2015 14:54:06 +0100 Subject: [PATCH 30/61] BareMetal: use proper product name for ST-LINK Utility In translatable UI strings. Change-Id: I0890ce916bdcf4939d008cbcfd7af5044ddb8d9a Reviewed-by: Denis Shienkov Reviewed-by: Eike Ziller --- src/plugins/baremetal/stlinkutilgdbserverprovider.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/baremetal/stlinkutilgdbserverprovider.cpp b/src/plugins/baremetal/stlinkutilgdbserverprovider.cpp index daf70f6d672..c4e20522401 100644 --- a/src/plugins/baremetal/stlinkutilgdbserverprovider.cpp +++ b/src/plugins/baremetal/stlinkutilgdbserverprovider.cpp @@ -98,7 +98,7 @@ QString StLinkUtilGdbServerProvider::defaultResetCommands() QString StLinkUtilGdbServerProvider::typeDisplayName() const { - return StLinkUtilGdbServerProviderFactory::tr("STLink-Util"); + return StLinkUtilGdbServerProviderFactory::tr("ST-LINK Utility"); } QString StLinkUtilGdbServerProvider::channel() const @@ -221,7 +221,7 @@ GdbServerProviderConfigWidget *StLinkUtilGdbServerProvider::configurationWidget( StLinkUtilGdbServerProviderFactory::StLinkUtilGdbServerProviderFactory() { setId(QLatin1String(Constants::STLINK_UTIL_PROVIDER_ID)); - setDisplayName(tr("STLink-Util")); + setDisplayName(tr("ST-LINK Utility")); } GdbServerProvider *StLinkUtilGdbServerProviderFactory::create() @@ -377,10 +377,10 @@ void StLinkUtilGdbServerProviderConfigWidget::setTransportLayer( void StLinkUtilGdbServerProviderConfigWidget::populateTransportLayers() { m_transportLayerComboBox->insertItem( - m_transportLayerComboBox->count(), tr("STLINKv1"), + m_transportLayerComboBox->count(), tr("ST-LINK/V1"), StLinkUtilGdbServerProvider::ScsiOverUsb); m_transportLayerComboBox->insertItem( - m_transportLayerComboBox->count(), tr("STLINKv2"), + m_transportLayerComboBox->count(), tr("ST-LINK/V2"), StLinkUtilGdbServerProvider::RawUsb); } From d45441926a2e82cf63895492fb0975e2d3b42bb5 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 17 Mar 2015 08:05:50 +0100 Subject: [PATCH 31/61] Macros -> Text Editing Macros Otherwise people might expect to much from it. Change-Id: I2023db821dd1f1fc2773c947c29479082cd8c5fc Reviewed-by: Leena Miettinen --- doc/src/editors/creator-editors.qdoc | 8 ++++---- src/plugins/macros/macrolocatorfilter.cpp | 2 +- src/plugins/macros/macrosplugin.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/src/editors/creator-editors.qdoc b/doc/src/editors/creator-editors.qdoc index 40d09d6cfb0..8d150f31a01 100644 --- a/doc/src/editors/creator-editors.qdoc +++ b/doc/src/editors/creator-editors.qdoc @@ -1056,16 +1056,16 @@ \title Using Text Editing Macros - To record a text editing macro, select \uicontrol {Tools > Macros > Record Macro} - or press \key {Alt+(}. To stop recording, select \uicontrol {Tools > Macros > + To record a text editing macro, select \uicontrol {Tools > Text Editing Macros > Record Macro} + or press \key {Alt+(}. To stop recording, select \uicontrol {Tools > Text Editing Macros > Stop Recording Macro} or press \key {Alt+)}. \note The macro recorder does not support code completion. - To play the last macro, select \uicontrol {Tools > Macros > Play Last Macro} or + To play the last macro, select \uicontrol {Tools > Text Editing Macros > Play Last Macro} or press \key {Alt+R}. - To save the last macro, select \uicontrol {Tools > Macros > Save Last Macro}. + To save the last macro, select \uicontrol {Tools > Text Editing Macros > Save Last Macro}. To assign a keyboard shortcut to a text editing macro, select \uicontrol {Tools > Options > Environment > Keyboard}. For more information, see diff --git a/src/plugins/macros/macrolocatorfilter.cpp b/src/plugins/macros/macrolocatorfilter.cpp index 0a0c9264d85..d4a85fb3474 100644 --- a/src/plugins/macros/macrolocatorfilter.cpp +++ b/src/plugins/macros/macrolocatorfilter.cpp @@ -45,7 +45,7 @@ MacroLocatorFilter::MacroLocatorFilter(): m_icon(QPixmap(QLatin1String(":/macros/images/macro.png"))) { setId("Macros"); - setDisplayName(tr("Macros")); + setDisplayName(tr("Text Editing Macros")); setShortcutString(QLatin1String("rm")); } diff --git a/src/plugins/macros/macrosplugin.cpp b/src/plugins/macros/macrosplugin.cpp index 519cc9a6788..7a6c378c929 100644 --- a/src/plugins/macros/macrosplugin.cpp +++ b/src/plugins/macros/macrosplugin.cpp @@ -77,7 +77,7 @@ bool MacrosPlugin::initialize(const QStringList &arguments, QString *errorMessag Core::ActionContainer *mtools = Core::ActionManager::actionContainer(Core::Constants::M_TOOLS); Core::ActionContainer *mmacrotools = Core::ActionManager::createMenu(Constants::M_TOOLS_MACRO); QMenu *menu = mmacrotools->menu(); - menu->setTitle(tr("&Macros")); + menu->setTitle(tr("Text Editing &Macros")); menu->setEnabled(true); mtools->addMenu(mmacrotools); From d23334bb84255ed9ea14f903745ede4258f01de6 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 16 Mar 2015 14:52:13 +0100 Subject: [PATCH 32/61] QMLDesigner: fix punctuation of a tooltip Change-Id: I008b3ad8efad56578953741f94bba4ade5f45d63 Reviewed-by: Eike Ziller --- .../propertyEditorQmlSources/QtQuick/LayoutPoperties.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/LayoutPoperties.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/LayoutPoperties.qml index 07432ae39f0..e9ba8193d85 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/LayoutPoperties.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/LayoutPoperties.qml @@ -231,7 +231,7 @@ SectionLayout { Label { text: qsTr("Preferred size") - tooltip: qsTr("Preferred height of an item in a layout. If the preferred height is -1 it will be ignored") + tooltip: qsTr("Preferred height of an item in a layout. If the preferred height is -1, it will be ignored.") } SecondColumnLayout { From b1e839c21ba69099023d48e83b7288a720e79817 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Wed, 25 Feb 2015 11:16:49 +0200 Subject: [PATCH 33/61] Tests: Cleanup project files for Utils tests Change-Id: I75ad17d12994376d88117570250a6c45e7495fea Reviewed-by: Christian Stenger --- .../ansiescapecodehandler.pro | 8 +------ tests/auto/utils/treemodel/treemodel.pro | 2 -- .../tcpportsgatherer/tcpportsgatherer.pro | 24 +++---------------- 3 files changed, 4 insertions(+), 30 deletions(-) diff --git a/tests/auto/utils/ansiescapecodehandler/ansiescapecodehandler.pro b/tests/auto/utils/ansiescapecodehandler/ansiescapecodehandler.pro index b891412fa43..03c65f58849 100644 --- a/tests/auto/utils/ansiescapecodehandler/ansiescapecodehandler.pro +++ b/tests/auto/utils/ansiescapecodehandler/ansiescapecodehandler.pro @@ -1,10 +1,4 @@ QTC_LIB_DEPENDS += utils include(../../qttest.pri) -UTILSDIR = $$IDE_SOURCE_TREE/src/libs/ - -DEFINES += QTCREATOR_UTILS_LIB - -SOURCES += \ - $$UTILSDIR/utils/ansiescapecodehandler.cpp \ - tst_ansiescapecodehandler.cpp +SOURCES += tst_ansiescapecodehandler.cpp diff --git a/tests/auto/utils/treemodel/treemodel.pro b/tests/auto/utils/treemodel/treemodel.pro index 647f63ce500..b1e3ed08240 100644 --- a/tests/auto/utils/treemodel/treemodel.pro +++ b/tests/auto/utils/treemodel/treemodel.pro @@ -2,5 +2,3 @@ QTC_LIB_DEPENDS += utils include(../../qttest.pri) SOURCES += tst_treemodel.cpp - -HEADERS += $$IDE_SOURCE_TREE/src/libs/utils/treemodel.h diff --git a/tests/manual/utils/tcpportsgatherer/tcpportsgatherer.pro b/tests/manual/utils/tcpportsgatherer/tcpportsgatherer.pro index 23298e08c85..7531e0526b6 100644 --- a/tests/manual/utils/tcpportsgatherer/tcpportsgatherer.pro +++ b/tests/manual/utils/tcpportsgatherer/tcpportsgatherer.pro @@ -1,26 +1,8 @@ -TEMPLATE = app -TARGET = tcpportsgatherer - -QT = core widgets network +QTC_LIB_DEPENDS += utils +include(../../../auto/qttest.pri) +QT += network CONFIG += console CONFIG -= app_bundle -QTC_LIB_DEPENDS += utils -include(../../../auto/qttest.pri) -include(../../../../src/rpath.pri) - - -UTILSDIR = ../../../../src/libs/utils - -DEFINES += QTCREATOR_UTILS_STATIC_LIB - -HEADERS += \ - $${UTILSDIR}/portlist.h \ - $${UTILSDIR}/tcpportsgatherer.h -SOURCES += \ - $${UTILSDIR}/portlist.cpp \ - $${UTILSDIR}/tcpportsgatherer.cpp - -win32:LIBS += -liphlpapi -lws2_32 SOURCES += main.cpp From 8d89c2eda0cb68120f2c52bffcb5946e0b2da6be Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 16 Mar 2015 11:35:53 +0100 Subject: [PATCH 34/61] Doc: Require GDB 7.5 (released Aug 2012) with Python 2.7 or 3.3+ The formerly required 7.4.1+x does not produce valid stack traces through its Python interface, which we nowadays want to use. The version requirement for GDBserver (7.0+) is not affected, but the general advice is still to use a GDBserver version matching the version of GDB if possible. Change-Id: Icb08544c56f4ba8c16ca77938b87be8a680ac563 Reviewed-by: Eike Ziller Reviewed-by: Leena Miettinen --- doc/src/debugger/creator-debugger-setup.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/debugger/creator-debugger-setup.qdoc b/doc/src/debugger/creator-debugger-setup.qdoc index 3ea650a4d80..6aa9ad9bc73 100644 --- a/doc/src/debugger/creator-debugger-setup.qdoc +++ b/doc/src/debugger/creator-debugger-setup.qdoc @@ -113,8 +113,8 @@ Starting with version 3.1, \QC requires the Python scripting extension. GDB builds without Python scripting are not supported - anymore and will not work. The minimal supported version is GDB 7.4.1, - using Python version 2.6, 2.7, or 3.x. + anymore and will not work. The minimal supported version is GDB 7.5 + using Python version 2.7, or 3.3, or newer. For remote debugging using GDB and GDB server, the minimal supported version of GDB server on the target device is 7.0. From 3cd9bbb550671c33307bcc04a87e59832aced178 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 17 Mar 2015 10:57:11 +0100 Subject: [PATCH 35/61] Tests: Fix building Change-Id: I381bb020b75fbc7e43bff6bd2fef5982ed114c14 Reviewed-by: hjk --- tests/auto/valgrind/memcheck/memcheck.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/valgrind/memcheck/memcheck.pro b/tests/auto/valgrind/memcheck/memcheck.pro index 977beb79377..89ac9529618 100644 --- a/tests/auto/valgrind/memcheck/memcheck.pro +++ b/tests/auto/valgrind/memcheck/memcheck.pro @@ -2,6 +2,8 @@ TEMPLATE = subdirs parsertests.file = parsertests.pro +# avoid race conditions when compiling shadowbuild and having more than one compile job +modeldemo.depends = parsertests modeldemo.file = modeldemo.pro testapps.depends = modeldemo parsertests From 4dc36974a8d85569612a68544f8edeacc8622b48 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Wed, 18 Feb 2015 16:01:58 +0100 Subject: [PATCH 36/61] Android: Adding libraries to subdirs projects Task-number: QTCREATORBUG-11625 Change-Id: I1017546463e819fc05846af74582cb9f5739ff08 Reviewed-by: BogDan Vatra --- .../androidextralibrarylistmodel.cpp | 75 +++++++++++++------ .../androidextralibrarylistmodel.h | 19 +++-- .../qmakeandroidbuildapkwidget.cpp | 2 +- .../qmakeprojectmanager/qmakenodes.cpp | 6 +- src/plugins/qmakeprojectmanager/qmakenodes.h | 2 +- 5 files changed, 67 insertions(+), 37 deletions(-) diff --git a/src/plugins/qmakeandroidsupport/androidextralibrarylistmodel.cpp b/src/plugins/qmakeandroidsupport/androidextralibrarylistmodel.cpp index 8d70d4df595..b8f2caa6c55 100644 --- a/src/plugins/qmakeandroidsupport/androidextralibrarylistmodel.cpp +++ b/src/plugins/qmakeandroidsupport/androidextralibrarylistmodel.cpp @@ -30,23 +30,33 @@ ****************************************************************************/ #include "androidextralibrarylistmodel.h" +#include "qmakeandroidrunconfiguration.h" + +#include + #include #include #include + using namespace QmakeAndroidSupport; using namespace Internal; +using QmakeProjectManager::QmakeProject; -AndroidExtraLibraryListModel::AndroidExtraLibraryListModel(QmakeProjectManager::QmakeProject *project, +AndroidExtraLibraryListModel::AndroidExtraLibraryListModel(ProjectExplorer::Target *target, QObject *parent) - : QAbstractItemModel(parent) - , m_project(project) + : QAbstractItemModel(parent), + m_target(target) { - QmakeProjectManager::QmakeProFileNode *node = m_project->rootQmakeProjectNode(); - proFileUpdated(node, node->validParse(), node->parseInProgress()); - connect(m_project, SIGNAL(proFileUpdated(QmakeProjectManager::QmakeProFileNode*,bool,bool)), - this, SLOT(proFileUpdated(QmakeProjectManager::QmakeProFileNode*,bool,bool))); + activeRunConfigurationChanged(); + + auto project = static_cast(target->project()); + connect(project, &QmakeProject::proFileUpdated, + this, &AndroidExtraLibraryListModel::proFileUpdated); + + connect(target, &ProjectExplorer::Target::activeRunConfigurationChanged, + this, &AndroidExtraLibraryListModel::activeRunConfigurationChanged); } QModelIndex AndroidExtraLibraryListModel::index(int row, int column, const QModelIndex &) const @@ -79,24 +89,21 @@ QVariant AndroidExtraLibraryListModel::data(const QModelIndex &index, int role) }; } -void AndroidExtraLibraryListModel::proFileUpdated(QmakeProjectManager::QmakeProFileNode *node, bool success, bool parseInProgress) +void AndroidExtraLibraryListModel::activeRunConfigurationChanged() { - QmakeProjectManager::QmakeProFileNode *root = m_project->rootQmakeProjectNode(); - if (node != root) + const QmakeProjectManager::QmakeProFileNode *node = activeNode(); + if (!node || node->parseInProgress()) { + emit enabledChanged(false); return; + } m_scope = QLatin1String("contains(ANDROID_TARGET_ARCH,") + node->singleVariableValue(QmakeProjectManager::AndroidArchVar) + QLatin1Char(')'); - if (parseInProgress) { - emit enabledChanged(false); - return; - } - bool enabled; beginResetModel(); - if (success && root->projectType() == QmakeProjectManager::ApplicationTemplate) { + if (node->validParse() && node->projectType() == QmakeProjectManager::ApplicationTemplate) { m_entries = node->variableValue(QmakeProjectManager::AndroidExtraLibs); enabled = true; } else { @@ -109,27 +116,47 @@ void AndroidExtraLibraryListModel::proFileUpdated(QmakeProjectManager::QmakeProF emit enabledChanged(enabled); } +QmakeProjectManager::QmakeProFileNode *AndroidExtraLibraryListModel::activeNode() const +{ + ProjectExplorer::RunConfiguration *rc = m_target->activeRunConfiguration(); + QmakeAndroidRunConfiguration *qarc = qobject_cast(rc); + if (!qarc) + return 0; + auto project = static_cast(m_target->project()); + return project->rootQmakeProjectNode()->findProFileFor(qarc->proFilePath()); +} + +void AndroidExtraLibraryListModel::proFileUpdated(QmakeProjectManager::QmakeProFileNode *node) +{ + if (node != activeNode()) + return; + activeRunConfigurationChanged(); +} + bool AndroidExtraLibraryListModel::isEnabled() const { - QmakeProjectManager::QmakeProFileNode *root = m_project->rootQmakeProjectNode(); - if (root->parseInProgress()) + QmakeProjectManager::QmakeProFileNode *node = activeNode(); + if (!node) return false; - if (root->projectType() != QmakeProjectManager::ApplicationTemplate) + if (node->parseInProgress()) + return false; + if (node->projectType() != QmakeProjectManager::ApplicationTemplate) return false; return true; } void AndroidExtraLibraryListModel::addEntries(const QStringList &list) { - if (m_project->rootQmakeProjectNode()->projectType() != QmakeProjectManager::ApplicationTemplate) + QmakeProjectManager::QmakeProFileNode *node = activeNode(); + if (!node || node->projectType() != QmakeProjectManager::ApplicationTemplate) return; beginInsertRows(QModelIndex(), m_entries.size(), m_entries.size() + list.size()); foreach (const QString &path, list) - m_entries += QLatin1String("$$PWD/") + QDir(m_project->projectDirectory().toString()).relativeFilePath(path); + m_entries += QLatin1String("$$PWD/") + + node->path().toFileInfo().absoluteDir().relativeFilePath(path); - QmakeProjectManager::QmakeProFileNode *node = m_project->rootQmakeProjectNode(); node->setProVariable(QLatin1String("ANDROID_EXTRA_LIBS"), m_entries, m_scope, QmakeProjectManager::Internal::ProWriter::ReplaceValues | QmakeProjectManager::Internal::ProWriter::MultiLine); @@ -144,7 +171,8 @@ bool greaterModelIndexByRow(const QModelIndex &a, const QModelIndex &b) void AndroidExtraLibraryListModel::removeEntries(QModelIndexList list) { - if (list.isEmpty() || m_project->rootQmakeProjectNode()->projectType() != QmakeProjectManager::ApplicationTemplate) + QmakeProjectManager::QmakeProFileNode *node = activeNode(); + if (list.isEmpty() || !node || node->projectType() != QmakeProjectManager::ApplicationTemplate) return; std::sort(list.begin(), list.end(), greaterModelIndexByRow); @@ -163,6 +191,5 @@ void AndroidExtraLibraryListModel::removeEntries(QModelIndexList list) endRemoveRows(); } - QmakeProjectManager::QmakeProFileNode *node = m_project->rootQmakeProjectNode(); node->setProVariable(QLatin1String("ANDROID_EXTRA_LIBS"), m_entries, m_scope); } diff --git a/src/plugins/qmakeandroidsupport/androidextralibrarylistmodel.h b/src/plugins/qmakeandroidsupport/androidextralibrarylistmodel.h index f810a363875..7b8c9321958 100644 --- a/src/plugins/qmakeandroidsupport/androidextralibrarylistmodel.h +++ b/src/plugins/qmakeandroidsupport/androidextralibrarylistmodel.h @@ -35,11 +35,13 @@ #include #include -namespace QmakeProjectManager { -class QmakeProject; -class QmakeProFileNode; +namespace ProjectExplorer { +class RunConfiguration; +class Target; } +namespace QmakeProjectManager { class QmakeProFileNode; } + namespace QmakeAndroidSupport { namespace Internal { @@ -47,7 +49,7 @@ class AndroidExtraLibraryListModel : public QAbstractItemModel { Q_OBJECT public: - explicit AndroidExtraLibraryListModel(QmakeProjectManager::QmakeProject *project, + explicit AndroidExtraLibraryListModel(ProjectExplorer::Target *target, QObject *parent = 0); QModelIndex index(int row, int column, const QModelIndex &parent) const; @@ -64,11 +66,12 @@ public: signals: void enabledChanged(bool); -private slots: - void proFileUpdated(QmakeProjectManager::QmakeProFileNode *node, bool success, bool parseInProgress); - private: - QmakeProjectManager::QmakeProject *m_project; + void proFileUpdated(QmakeProjectManager::QmakeProFileNode *node); + void activeRunConfigurationChanged(); + QmakeProjectManager::QmakeProFileNode *activeNode() const; + + ProjectExplorer::Target *m_target; QStringList m_entries; QString m_scope; }; diff --git a/src/plugins/qmakeandroidsupport/qmakeandroidbuildapkwidget.cpp b/src/plugins/qmakeandroidsupport/qmakeandroidbuildapkwidget.cpp index 186f1918d62..518f801c9a7 100644 --- a/src/plugins/qmakeandroidsupport/qmakeandroidbuildapkwidget.cpp +++ b/src/plugins/qmakeandroidsupport/qmakeandroidbuildapkwidget.cpp @@ -84,7 +84,7 @@ QmakeAndroidBuildApkWidget::QmakeAndroidBuildApkWidget(QmakeAndroidBuildApkStep oldFilesWarningIcon->setVisible(oldFiles); oldFilesWarningLabel->setVisible(oldFiles); - m_extraLibraryListModel = new AndroidExtraLibraryListModel(static_cast(m_step->project()), this); + m_extraLibraryListModel = new AndroidExtraLibraryListModel(m_step->target(), this); m_ui->androidExtraLibsListView->setModel(m_extraLibraryListModel); connect(m_ui->createAndroidTemplatesButton, SIGNAL(clicked()), diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp index 4c66f67b2ae..9a10b03850b 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -1527,13 +1527,13 @@ namespace { }; } -const QmakeProFileNode *QmakeProFileNode::findProFileFor(const FileName &fileName) const +QmakeProFileNode *QmakeProFileNode::findProFileFor(const FileName &fileName) const { if (fileName == path()) - return this; + return const_cast(this); foreach (ProjectNode *pn, subProjectNodes()) if (QmakeProFileNode *qmakeProFileNode = dynamic_cast(pn)) - if (const QmakeProFileNode *result = qmakeProFileNode->findProFileFor(fileName)) + if (QmakeProFileNode *result = qmakeProFileNode->findProFileFor(fileName)) return result; return 0; } diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h index 3b501d245ec..2a005c4a351 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.h +++ b/src/plugins/qmakeprojectmanager/qmakenodes.h @@ -357,7 +357,7 @@ public: static QString uiHeaderFile(const QString &uiDir, const Utils::FileName &formFile); QHash uiFiles() const; - const QmakeProFileNode *findProFileFor(const Utils::FileName &string) const; + QmakeProFileNode *findProFileFor(const Utils::FileName &string) const; TargetInformation targetInformation() const; InstallsList installsList() const; From ddac471a8ea70fdcc30651d257bfd50ac914a6a7 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 17 Mar 2015 09:59:17 +0100 Subject: [PATCH 37/61] Compile output: Do not do scroll wheel zooming That was the behavior before the fix for QTBUG-30845 (which introduced scroll wheel zooming for read-only QPlainTextEdit). Change-Id: I216ed6c827d8dc966af3af67158e9c275c9fa949 Task-number: QTCREATORBUG-11017 Reviewed-by: Daniel Teske --- src/plugins/projectexplorer/compileoutputwindow.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/projectexplorer/compileoutputwindow.cpp b/src/plugins/projectexplorer/compileoutputwindow.cpp index e3f9e599ec8..707bc15fb47 100644 --- a/src/plugins/projectexplorer/compileoutputwindow.cpp +++ b/src/plugins/projectexplorer/compileoutputwindow.cpp @@ -87,6 +87,13 @@ private slots: } protected: + void wheelEvent(QWheelEvent *ev) + { + // from QPlainTextEdit, but without scroll wheel zooming + QAbstractScrollArea::wheelEvent(ev); + updateMicroFocus(); + } + void mouseDoubleClickEvent(QMouseEvent *ev) { int line = cursorForPosition(ev->pos()).block().blockNumber(); From 71855e6bbca7c668443753481109606557412363 Mon Sep 17 00:00:00 2001 From: Daniel Teske Date: Mon, 16 Mar 2015 19:12:27 +0100 Subject: [PATCH 38/61] Fix crash with kits that have no toolchain Change-Id: I3f041b9a7fe60ab5adf4ab3054f53713b78e1ab6 Task-number: QTCREATORBUG-14150 Reviewed-by: Robert Loehning --- src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp index 762323c4e14..b2d660d596f 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp @@ -191,8 +191,12 @@ QList QmakeProjectImporter::import(const FileName &importPath, bool ToolChain *tc = ToolChainKitInformation::toolChain(k); if (kitSpec.isEmpty() && kitVersion) kitSpec = kitVersion->mkspecFor(tc); - QMakeStepConfig::TargetArchConfig kitTargetArch = QMakeStepConfig::targetArchFor(tc->targetAbi(), kitVersion); - QMakeStepConfig::OsType kitOsType = QMakeStepConfig::osTypeFor(tc->targetAbi(), kitVersion); + QMakeStepConfig::TargetArchConfig kitTargetArch = QMakeStepConfig::NoArch; + QMakeStepConfig::OsType kitOsType = QMakeStepConfig::NoOsType; + if (tc) { + kitTargetArch = QMakeStepConfig::targetArchFor(tc->targetAbi(), kitVersion); + kitOsType = QMakeStepConfig::osTypeFor(tc->targetAbi(), kitVersion); + } qCDebug(logs) << k->displayName() << "version:" << (kitVersion == version) << "spec:" << (kitSpec == parsedSpec) From f1ea415581b7e32f92e8cd8dadced4049d8f1065 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Tue, 17 Mar 2015 12:00:26 +0100 Subject: [PATCH 39/61] ProjectExplorer: Don't display alien dir separators on Windows In case you opened more than one project with the same name, it shows the full path incl. dir separators in the first-level tabs in the project mode. Change-Id: Idbf5dfe6ef0c20eecf3a3473011bb2d9b1794cea Reviewed-by: Orgad Shaneh --- src/plugins/projectexplorer/doubletabwidget.cpp | 6 ++++++ src/plugins/projectexplorer/doubletabwidget.h | 4 +--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/plugins/projectexplorer/doubletabwidget.cpp b/src/plugins/projectexplorer/doubletabwidget.cpp index 55817378855..36e93cfb887 100644 --- a/src/plugins/projectexplorer/doubletabwidget.cpp +++ b/src/plugins/projectexplorer/doubletabwidget.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -573,3 +574,8 @@ bool DoubleTabWidget::event(QEvent *event) } return QWidget::event(event); } + +QString DoubleTabWidget::Tab::displayName() const +{ + return nameIsUnique ? name : QDir::toNativeSeparators(fullName); +} diff --git a/src/plugins/projectexplorer/doubletabwidget.h b/src/plugins/projectexplorer/doubletabwidget.h index 4e2e70ec79b..92c23ac54ec 100644 --- a/src/plugins/projectexplorer/doubletabwidget.h +++ b/src/plugins/projectexplorer/doubletabwidget.h @@ -80,9 +80,7 @@ private: bool nameIsUnique; QStringList subTabs; int currentSubTab; - QString displayName() const { - return nameIsUnique ? name : fullName; - } + QString displayName() const; }; void updateNameIsUniqueAdd(Tab *tab); void updateNameIsUniqueRemove(const Tab &tab); From 9851484b317b5e29a048d15c45afed877642ea21 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 17 Mar 2015 13:26:20 +0100 Subject: [PATCH 40/61] Debugger: Remove new watch window timer from public interface Change-Id: Ic9d3df22d917e5644d6302a6af06aa8eadea8b5a Reviewed-by: Christian Stenger --- src/plugins/debugger/cdb/cdbengine.cpp | 4 ++-- src/plugins/debugger/gdb/gdbengine.cpp | 4 ++-- src/plugins/debugger/lldb/lldbengine.cpp | 4 ++-- src/plugins/debugger/pdb/pdbengine.cpp | 2 +- src/plugins/debugger/watchhandler.cpp | 16 +++++++++------- src/plugins/debugger/watchhandler.h | 11 +++-------- src/plugins/debugger/watchwindow.cpp | 2 +- 7 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 2beaa27b500..657972e8994 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -1500,7 +1500,7 @@ void CdbEngine::updateLocals(bool newFrame) // Required arguments: frame str << blankSeparator << frameIndex; - watchHandler()->updateRequested(); + watchHandler()->notifyUpdateStarted(); postExtensionCommand("locals", arguments, 0, [this, newFrame](const CdbResponse &r) { handleLocals(r, newFrame); }); } @@ -1860,7 +1860,7 @@ void CdbEngine::handleRegistersExt(const CdbResponse &response) void CdbEngine::handleLocals(const CdbResponse &response, bool newFrame) { if (response.success) { - watchHandler()->updateFinished(); + watchHandler()->notifyUpdateFinished(); if (boolSetting(VerboseLog)) showMessage(QLatin1String("Locals: ") + QString::fromLatin1(response.extensionReply), LogDebug); WatchHandler *handler = watchHandler(); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 3ba9d509285..040d1e7152c 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3755,7 +3755,7 @@ void GdbEngine::handleVarAssign(const DebuggerResponse &) void GdbEngine::updateLocals() { watchHandler()->resetValueCache(); - watchHandler()->updateRequested(); + watchHandler()->notifyUpdateStarted(); updateLocalsPython(UpdateParameters()); } @@ -4768,7 +4768,7 @@ void GdbEngine::updateLocalsPython(const UpdateParameters ¶ms) void GdbEngine::handleStackFramePython(const DebuggerResponse &response, bool partial) { - watchHandler()->updateFinished(); + watchHandler()->notifyUpdateFinished(); if (response.resultClass == ResultDone) { QByteArray out = response.consoleStreamOutput; while (out.endsWith(' ') || out.endsWith('\n')) diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index a9fbab5d990..de7399b034a 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -912,7 +912,7 @@ void LldbEngine::doUpdateLocals(UpdateParameters params) m_lastDebuggableCommand = cmd; m_lastDebuggableCommand.args.replace("\"passexceptions\":0", "\"passexceptions\":1"); - watchHandler()->updateRequested(); + watchHandler()->notifyUpdateStarted(); runCommand(cmd); reloadRegisters(); @@ -1010,7 +1010,7 @@ void LldbEngine::refreshLocals(const GdbMi &vars) } handler->purgeOutdatedItems(toDelete); - handler->updateFinished(); + handler->notifyUpdateFinished(); DebuggerToolTipManager::updateEngine(this); } diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp index ee5afb470dd..c4bb9acd689 100644 --- a/src/plugins/debugger/pdb/pdbengine.cpp +++ b/src/plugins/debugger/pdb/pdbengine.cpp @@ -664,7 +664,7 @@ void PdbEngine::updateLocals() //m_lastDebuggableCommand = cmd; //m_lastDebuggableCommand.args.replace("\"passexceptions\":0", "\"passexceptions\":1"); - watchHandler()->updateRequested(); + watchHandler()->notifyUpdateStarted(); runCommand(cmd); } diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 8d9e900313e..abb86fc645f 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -228,6 +228,7 @@ public: WatchItem *m_tooltipRoot; // Not owned. QSet m_expandedINames; + QTimer m_requestUpdateTimer; TypeFormatList builtinTypeFormatList(const WatchData &data) const; QStringList dumperTypeFormatList(const WatchData &data) const; @@ -257,6 +258,10 @@ WatchModel::WatchModel(WatchHandler *handler) root->appendChild(m_tooltipRoot = new WatchItem("tooltip", tr("Tooltip"))); setRootItem(root); + m_requestUpdateTimer.setSingleShot(true); + connect(&m_requestUpdateTimer, &QTimer::timeout, + this, &WatchModel::updateStarted); + connect(action(SortStructMembers), &SavedAction::valueChanged, this, &WatchModel::reinsertAllData); connect(action(ShowStdNamespace), &SavedAction::valueChanged, @@ -1161,9 +1166,6 @@ WatchHandler::WatchHandler(DebuggerEngine *engine) m_contentsValid = true; // FIXME m_resetLocationScheduled = false; m_separatedView = new SeparatedView; - m_requestUpdateTimer = new QTimer(this); - m_requestUpdateTimer->setSingleShot(true); - connect(m_requestUpdateTimer, &QTimer::timeout, m_model, &WatchModel::updateRequested); } WatchHandler::~WatchHandler() @@ -1276,14 +1278,14 @@ void WatchHandler::resetValueCache() }); } -void WatchHandler::updateRequested() +void WatchHandler::notifyUpdateStarted() { - m_requestUpdateTimer->start(80); + m_model->m_requestUpdateTimer.start(80); } -void WatchHandler::updateFinished() +void WatchHandler::notifyUpdateFinished() { - m_requestUpdateTimer->stop(); + m_model->m_requestUpdateTimer.stop(); emit m_model->updateFinished(); } diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index 4f898c39331..1faaabb542d 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -38,10 +38,6 @@ #include #include -QT_BEGIN_NAMESPACE -class QTimer; -QT_END_NAMESPACE - namespace Debugger { namespace Internal { @@ -181,7 +177,7 @@ signals: void itemIsExpanded(const QModelIndex &idx); void inameIsExpanded(const QByteArray &iname); void columnAdjustmentRequested(); - void updateRequested(); + void updateStarted(); void updateFinished(); }; @@ -248,8 +244,8 @@ public: void removeItemByIName(const QByteArray &iname); void removeAllData(bool includeInspectData = false); void resetValueCache(); - void updateRequested(); - void updateFinished(); + void notifyUpdateStarted(); + void notifyUpdateFinished(); void purgeOutdatedItems(const QSet &inames); private: @@ -264,7 +260,6 @@ private: WatchModel *m_model; // Owned. DebuggerEngine *m_engine; // Not owned. SeparatedView *m_separatedView; // Owned. - QTimer *m_requestUpdateTimer; // Owned. bool m_contentsValid; bool m_resetLocationScheduled; diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index 90c376b8286..6ff501c61e3 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -953,7 +953,7 @@ void WatchTreeView::setModel(QAbstractItemModel *model) connect(watchModel, &WatchModelBase::itemIsExpanded, this, &WatchTreeView::handleItemIsExpanded); if (m_type == LocalsType) { - connect(watchModel, &WatchModelBase::updateRequested, + connect(watchModel, &WatchModelBase::updateStarted, this, &WatchTreeView::showProgressIndicator); connect(watchModel, &WatchModelBase::updateFinished, this, &WatchTreeView::hideProgressIndicator); From 9975fe431ac3e1deb0cf7e2581f87faab5e041a3 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 17 Mar 2015 15:45:48 +0100 Subject: [PATCH 41/61] Qbs: write Qbs with an initial capital letter In the UI and docs. Change-Id: I193b4599d0c915b2829b12c212718c91cb7f0793 Reviewed-by: Jake Petroules --- share/qtcreator/templates/wizards/plaincapp/qbs/wizard.xml | 2 +- share/qtcreator/templates/wizards/plaincppapp/qbs/wizard.xml | 2 +- src/plugins/qbsprojectmanager/qbsconstants.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/templates/wizards/plaincapp/qbs/wizard.xml b/share/qtcreator/templates/wizards/plaincapp/qbs/wizard.xml index f5aa9ca836d..bc6ef59d23f 100644 --- a/share/qtcreator/templates/wizards/plaincapp/qbs/wizard.xml +++ b/share/qtcreator/templates/wizards/plaincapp/qbs/wizard.xml @@ -33,7 +33,7 @@ ../common/console.png - Creates a plain C project using qbs. + Creates a plain C project using Qbs. Plain C Project (Qbs Build); Non-Qt Project diff --git a/share/qtcreator/templates/wizards/plaincppapp/qbs/wizard.xml b/share/qtcreator/templates/wizards/plaincppapp/qbs/wizard.xml index 34103f51365..67a4e4f66b7 100644 --- a/share/qtcreator/templates/wizards/plaincppapp/qbs/wizard.xml +++ b/share/qtcreator/templates/wizards/plaincppapp/qbs/wizard.xml @@ -33,7 +33,7 @@ ../common/console.png - Creates a plain (non-Qt) C++ project using qbs. + Creates a plain (non-Qt) C++ project using Qbs. Plain C++ Project (Qbs Build); Non-Qt Project diff --git a/src/plugins/qbsprojectmanager/qbsconstants.h b/src/plugins/qbsprojectmanager/qbsconstants.h index f988f466354..0f76d4963df 100644 --- a/src/plugins/qbsprojectmanager/qbsconstants.h +++ b/src/plugins/qbsprojectmanager/qbsconstants.h @@ -53,7 +53,7 @@ const char CPP_XCODESDKVERSION[] = "cpp.xcodeSdkVersion"; // Settings page const char QBS_SETTINGS_CATEGORY[] = "YM.qbs"; -const char QBS_SETTINGS_TR_CATEGORY[] = QT_TRANSLATE_NOOP("QbsProjectManager", "qbs"); +const char QBS_SETTINGS_TR_CATEGORY[] = QT_TRANSLATE_NOOP("QbsProjectManager", "Qbs"); const char QBS_SETTINGS_CATEGORY_ICON[] = ":/projectexplorer/images/build.png"; const char QBS_PROPERTIES_KEY_FOR_KITS[] = "QbsProjectManager.qbs-properties"; From 693e1b72273c7c9ca7e5e4edadbb3337dd65f4ae Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 16 Mar 2015 13:27:35 +0100 Subject: [PATCH 42/61] Squish: Improve tst_default_settings Change-Id: I6aebbf300e9e86729c0b00bee3bb9b6d4bf87854 Reviewed-by: Robert Loehning --- tests/system/suite_general/tst_default_settings/test.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/system/suite_general/tst_default_settings/test.py b/tests/system/suite_general/tst_default_settings/test.py index 8b2551fded8..06f033ce325 100644 --- a/tests/system/suite_general/tst_default_settings/test.py +++ b/tests/system/suite_general/tst_default_settings/test.py @@ -144,7 +144,10 @@ def __kitFunc__(it, foundQt, foundCompNames): test.compare(it, "Desktop (default)", "Verifying whether default Desktop kit has been created.") if foundQt: test.compare(qtVersionStr, foundQt, "Verifying if Qt versions match.") - compilerCombo = waitForObject(":Compiler:_QComboBox") + compilerCombo = findObject(":Compiler:_QComboBox") + test.compare(compilerCombo.enabled, compilerCombo.count > 1, + "Verifying whether compiler combo is enabled/disabled correctly.") + test.verify(str(compilerCombo.currentText) in foundCompNames, "Verifying if one of the found compilers had been set.") if currentSelectedTreeItem: From 5d719865850f0fa553fbc72d69b6939731247206 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 16 Mar 2015 17:07:50 +0100 Subject: [PATCH 43/61] ActionManager: Remove fallback path for Qt Creator 3.1 settings Change-Id: I2fe0c76e0ed30b69da9fdba5d9b9de6b46d647d8 Reviewed-by: David Schulz --- .../actionmanager/actionmanager.cpp | 45 ------------------- .../coreplugin/actionmanager/actionmanager.h | 1 - .../actionmanager/actionmanager_p.h | 2 - src/plugins/coreplugin/coreplugin.cpp | 2 +- 4 files changed, 1 insertion(+), 49 deletions(-) diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index f189e4b7c2e..f6e4c9900c5 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -51,7 +51,6 @@ namespace { } static const char kKeyboardSettingsKey[] = "KeyboardShortcuts"; -static const char kKeyboardSettingsTransferredKey[] = "OldSettingsTransferred"; using namespace Core; using namespace Core::Internal; @@ -364,12 +363,6 @@ bool ActionManager::isPresentationModeEnabled() return d->m_presentationModeEnabled; } -void ActionManager::initialize(QObject *parent) -{ - new ActionManager(parent); - d->initialize(); -} - void ActionManager::saveSettings(QSettings *settings) { d->saveSettings(settings); @@ -488,44 +481,6 @@ void ActionManagerPrivate::readUserSettings(Id id, Action *cmd) settings->endGroup(); } -static const char oldSettingsGroup[] = "KeyBindings"; -static const char oldIdKey[] = "ID"; -static const char oldSequenceKey[] = "Keysequence"; - -void ActionManagerPrivate::initialize() -{ - // TODO remove me after some period after 3.1 - // TODO also remove the old settings after some period after 3.1 - // settings->remove(QLatin1String(oldSettingsGroup)); - // settings->contains(QLatin1String(kKeyboardSettingsKey) + QLatin1Char('/') - // + QLatin1String(kKeyboardSettingsTransferredKey)) - // check if settings in old style (pre 3.1) exist - QSettings *settings = ICore::settings(); - if (settings->contains(QLatin1String(kKeyboardSettingsKey) + QLatin1Char('/') - + QLatin1String(kKeyboardSettingsTransferredKey))) { - return; - } - // move old settings style to new settings style - QMap shortcutMap; - const int shortcuts = settings->beginReadArray(QLatin1String(oldSettingsGroup)); - for (int i = 0; i < shortcuts; ++i) { - settings->setArrayIndex(i); - const QKeySequence key(settings->value(QLatin1String(oldSequenceKey)).toString()); - const Id id = Id::fromSetting(settings->value(QLatin1String(oldIdKey))); - shortcutMap.insert(id, key); - } - settings->endArray(); - // write settings in new style - settings->beginGroup(QLatin1String(kKeyboardSettingsKey)); - settings->setValue(QLatin1String(kKeyboardSettingsTransferredKey), true); - QMapIterator it(shortcutMap); - while (it.hasNext()) { - it.next(); - settings->setValue(it.key().toString(), it.value().toString()); - } - settings->endGroup(); -} - void ActionManagerPrivate::saveSettings(QSettings *settings) { settings->beginGroup(QLatin1String(kKeyboardSettingsKey)); diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.h b/src/plugins/coreplugin/actionmanager/actionmanager.h index 7e924af38c9..e65ef5fe73e 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager.h @@ -86,7 +86,6 @@ signals: private: ActionManager(QObject *parent = 0); ~ActionManager(); - static void initialize(QObject *parent); static void saveSettings(QSettings *settings); static void setContext(const Context &context); diff --git a/src/plugins/coreplugin/actionmanager/actionmanager_p.h b/src/plugins/coreplugin/actionmanager/actionmanager_p.h index fa106014e44..8718108693c 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager_p.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager_p.h @@ -64,8 +64,6 @@ public: explicit ActionManagerPrivate(); ~ActionManagerPrivate(); - void initialize(); - void setContext(const Context &context); bool hasContext(int context) const; diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp index 43731dd3723..e710af2a640 100644 --- a/src/plugins/coreplugin/coreplugin.cpp +++ b/src/plugins/coreplugin/coreplugin.cpp @@ -170,7 +170,7 @@ void CorePlugin::parseArguments(const QStringList &arguments) bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage) { - ActionManager::initialize(this); + new ActionManager(this); Theme::initialPalette(); // Initialize palette before setting it qsrand(QDateTime::currentDateTime().toTime_t()); parseArguments(arguments); From d0835af5f9390ad78bd4ddaec20d04648a74d97e Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 16 Mar 2015 17:19:24 +0100 Subject: [PATCH 44/61] ActionManager: Avoid losing shortcuts when actions are unregistered Since the action for this ID might be unregistered temporarily, and re- registered under different circumstances. Change-Id: I6c4ef3ddf814487cc9b63ff979ebb1539cdf7c81 Task-number: QTCREATORBUG-8108 Reviewed-by: David Schulz --- .../actionmanager/actionmanager.cpp | 28 +++++++++++-------- .../coreplugin/actionmanager/actionmanager.h | 2 +- .../actionmanager/actionmanager_p.h | 3 +- src/plugins/coreplugin/mainwindow.cpp | 2 +- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index f6e4c9900c5..2a6c517f61a 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -326,6 +326,7 @@ void ActionManager::unregisterAction(QAction *action, Id id) a->removeOverrideAction(action); if (a->isEmpty()) { // clean up + d->saveSettings(a); ICore::mainWindow()->removeAction(a->action()); // ActionContainers listen to the commands' destroyed signals delete a->action(); @@ -363,9 +364,9 @@ bool ActionManager::isPresentationModeEnabled() return d->m_presentationModeEnabled; } -void ActionManager::saveSettings(QSettings *settings) +void ActionManager::saveSettings() { - d->saveSettings(settings); + d->saveSettings(); } void ActionManager::setContext(const Context &context) @@ -481,18 +482,21 @@ void ActionManagerPrivate::readUserSettings(Id id, Action *cmd) settings->endGroup(); } -void ActionManagerPrivate::saveSettings(QSettings *settings) +void ActionManagerPrivate::saveSettings(Action *cmd) +{ + const QString settingsKey = QLatin1String(kKeyboardSettingsKey) + QLatin1Char('/') + + cmd->id().toString(); + QKeySequence key = cmd->keySequence(); + if (key != cmd->defaultKeySequence()) + ICore::settings()->setValue(settingsKey, key.toString()); + else + ICore::settings()->remove(settingsKey); +} + +void ActionManagerPrivate::saveSettings() { - settings->beginGroup(QLatin1String(kKeyboardSettingsKey)); const IdCmdMap::const_iterator cmdcend = m_idCmdMap.constEnd(); for (IdCmdMap::const_iterator j = m_idCmdMap.constBegin(); j != cmdcend; ++j) { - const Id id = j.key(); - Action *cmd = j.value(); - QKeySequence key = cmd->keySequence(); - if (key != cmd->defaultKeySequence()) - settings->setValue(id.toString(), key.toString()); - else - settings->remove(id.toString()); + saveSettings(j.value()); } - settings->endGroup(); } diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.h b/src/plugins/coreplugin/actionmanager/actionmanager.h index e65ef5fe73e..a25f7beb349 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager.h @@ -86,7 +86,7 @@ signals: private: ActionManager(QObject *parent = 0); ~ActionManager(); - static void saveSettings(QSettings *settings); + static void saveSettings(); static void setContext(const Context &context); friend class Core::Internal::CorePlugin; // initialization diff --git a/src/plugins/coreplugin/actionmanager/actionmanager_p.h b/src/plugins/coreplugin/actionmanager/actionmanager_p.h index 8718108693c..3792dc7b2ef 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager_p.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager_p.h @@ -67,7 +67,8 @@ public: void setContext(const Context &context); bool hasContext(int context) const; - void saveSettings(QSettings *settings); + void saveSettings(); + void saveSettings(Action *cmd); void showShortcutPopup(const QString &shortcut); bool hasContext(const Context &context) const; diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index e7423ae3d03..aa3ee201fea 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -985,7 +985,7 @@ void MainWindow::writeSettings() settings->endGroup(); DocumentManager::saveSettings(); - ActionManager::saveSettings(settings); + ActionManager::saveSettings(); EditorManagerPrivate::saveSettings(); m_navigationWidget->saveSettings(settings); } From 887d8809c9f3505134ad29458c1e0949e8485e39 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 17 Mar 2015 11:25:36 +0100 Subject: [PATCH 45/61] Binary editor: Support ctrl+(page)up/down Only scroll without changing the cursor position when pressing ctrl. Task-number: QTCREATORBUG-11386 Change-Id: I850da6f42696d6b5d9db488562aa56903c4ce970 Reviewed-by: David Schulz --- src/plugins/bineditor/bineditor.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/plugins/bineditor/bineditor.cpp b/src/plugins/bineditor/bineditor.cpp index e1ee3f2fb2a..d39995eaac7 100644 --- a/src/plugins/bineditor/bineditor.cpp +++ b/src/plugins/bineditor/bineditor.cpp @@ -1279,12 +1279,19 @@ void BinEditorWidget::keyPressEvent(QKeyEvent *e) MoveMode moveMode = e->modifiers() & Qt::ShiftModifier ? KeepAnchor : MoveAnchor; + bool ctrlPressed = e->modifiers() & Qt::ControlModifier; switch (e->key()) { case Qt::Key_Up: - setCursorPosition(m_cursorPosition - m_bytesPerLine, moveMode); + if (ctrlPressed) + verticalScrollBar()->triggerAction(QScrollBar::SliderSingleStepSub); + else + setCursorPosition(m_cursorPosition - m_bytesPerLine, moveMode); break; case Qt::Key_Down: - setCursorPosition(m_cursorPosition + m_bytesPerLine, moveMode); + if (ctrlPressed) + verticalScrollBar()->triggerAction(QScrollBar::SliderSingleStepAdd); + else + setCursorPosition(m_cursorPosition + m_bytesPerLine, moveMode); break; case Qt::Key_Right: setCursorPosition(m_cursorPosition + 1, moveMode); @@ -1297,12 +1304,13 @@ void BinEditorWidget::keyPressEvent(QKeyEvent *e) int line = qMax(0, m_cursorPosition / m_bytesPerLine - verticalScrollBar()->value()); verticalScrollBar()->triggerAction(e->key() == Qt::Key_PageUp ? QScrollBar::SliderPageStepSub : QScrollBar::SliderPageStepAdd); - setCursorPosition((verticalScrollBar()->value() + line) * m_bytesPerLine + m_cursorPosition % m_bytesPerLine, moveMode); + if (!ctrlPressed) + setCursorPosition((verticalScrollBar()->value() + line) * m_bytesPerLine + m_cursorPosition % m_bytesPerLine, moveMode); } break; case Qt::Key_Home: { int pos; - if (e->modifiers() & Qt::ControlModifier) + if (ctrlPressed) pos = 0; else pos = m_cursorPosition/m_bytesPerLine * m_bytesPerLine; @@ -1310,7 +1318,7 @@ void BinEditorWidget::keyPressEvent(QKeyEvent *e) } break; case Qt::Key_End: { int pos; - if (e->modifiers() & Qt::ControlModifier) + if (ctrlPressed) pos = m_size; else pos = m_cursorPosition/m_bytesPerLine * m_bytesPerLine + 15; From 6f7e7a8b93bfa20e4bf4b006ba6bfdf8125db8d5 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 18 Mar 2015 09:31:05 +0100 Subject: [PATCH 46/61] iOS: Fix compile Change-Id: Iae4696b2d0fff84286f3953d3382f52262d72a6b Reviewed-by: Eike Ziller --- src/tools/3rdparty/iossim/iphonesimulator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/3rdparty/iossim/iphonesimulator.h b/src/tools/3rdparty/iossim/iphonesimulator.h index 3e1d1f33d01..f2044e73ead 100644 --- a/src/tools/3rdparty/iossim/iphonesimulator.h +++ b/src/tools/3rdparty/iossim/iphonesimulator.h @@ -6,7 +6,7 @@ */ #import -#import +#import "dvtiphonesimulatorremoteclient/dvtiphonesimulatorremoteclient.h" #import "version.h" @interface iPhoneSimulator : NSObject { From 3bf81efbe73ac2a731c7f34f54022738f71b805b Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 16 Mar 2015 14:48:13 +0100 Subject: [PATCH 47/61] QML: Remove Apply on Save functionality The feature has been actually been disabled since commit ac771eb552e4, but now it's time to also remove the dead code ... Fixing the feature and bringing it out of the experimental state would require quite some effort that apparently nobody is willing to spend. So it's better to remove it. The enablers in the qmldebug library, as well as the QmlJSDelta utility class in qmljs library, are left in though. Change-Id: Idf98a2f946d0db86bef2f20d2349d6ffedba219c Reviewed-by: Kai Koehne --- doc/images/qml-observer-bar-reload.png | Bin 708 -> 0 bytes doc/src/debugger/qtquick-debugging.qdoc | 11 - src/plugins/debugger/debugger.qbs | 1 - src/plugins/debugger/debuggeractions.cpp | 5 - src/plugins/debugger/debuggeractions.h | 3 +- src/plugins/debugger/debuggerconstants.h | 1 - src/plugins/debugger/debuggerplugin.cpp | 8 - src/plugins/debugger/qml/qml.pri | 2 - src/plugins/debugger/qml/qmlengine.h | 1 + .../debugger/qml/qmlinspectoradapter.cpp | 193 ----- .../debugger/qml/qmlinspectoradapter.h | 20 - .../debugger/qml/qmllivetextpreview.cpp | 743 ------------------ src/plugins/debugger/qml/qmllivetextpreview.h | 121 --- 13 files changed, 2 insertions(+), 1107 deletions(-) delete mode 100644 doc/images/qml-observer-bar-reload.png delete mode 100644 src/plugins/debugger/qml/qmllivetextpreview.cpp delete mode 100644 src/plugins/debugger/qml/qmllivetextpreview.h diff --git a/doc/images/qml-observer-bar-reload.png b/doc/images/qml-observer-bar-reload.png deleted file mode 100644 index 3c05180d01834c67fb5e0860641a3dbfadddb052..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 708 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4kiW$h6xih%orFLI14-?iy0XBj({-ZRBb+K z1_lQ95>H=O_B$*>oJP{;YF-+Fg;oF&M`xzJ**g#rCGD~t&8CJZzq|U&=*zf7$ z7@{$;H)yvPv!lq~&Bixdeao)9-%v~1%CV9~TT~@girfCsC8hfl^>XbTqA%XK!NJM# zlTmkyMB(C-LQW#zX3pIy_PBWQihF*1Bthis`V(Hzgz4Ml>T%-}{?Zk1;QZdD9?zi8y zKg(p6N3Go!wN}N`s7>;DjF@Cwpx*SQjG>{j$7ilxSZ-^kUU}HysSU${M;2-=0bYwW zr1;vMI2b*tf)!-~Yy~pT10!;mo9#_Rjjl*4I+c?+JEsnt1w|&gI5pJ_hTlUL|tn z>vkztOWr+l+W*<2eG^18W`*g9J-x6kcl{Kv{`Ps*9}^Bc*~L3BIQ-$^6Fh7n!^5_T znPEdrUViQNr}I)DRSUB?UdS;smh@E<_F7po$(Gm2WBcv7`setSettingsKey(qmlInspectorGroup, QLatin1String("QmlInspector.ShowAppOnTop")); item->setDefaultValue(false); insertItem(ShowAppOnTop, item); - - item = new SavedAction(this); - item->setSettingsKey(qmlInspectorGroup, QLatin1String("QmlInspector.FromQml")); - item->setDefaultValue(false); - insertItem(QmlUpdateOnSave, item); } DebuggerSettings::~DebuggerSettings() diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h index 2b3202fcd5a..843d0dfadb4 100644 --- a/src/plugins/debugger/debuggeractions.h +++ b/src/plugins/debugger/debuggeractions.h @@ -185,8 +185,7 @@ enum DebuggerActionCode // QML Tools ShowQmlObjectTree, - ShowAppOnTop, - QmlUpdateOnSave + ShowAppOnTop }; } // namespace Internal diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h index 0bfb5f749b2..800e81bac15 100644 --- a/src/plugins/debugger/debuggerconstants.h +++ b/src/plugins/debugger/debuggerconstants.h @@ -63,7 +63,6 @@ const char RESET[] = "Debugger.Reset"; const char OPERATE_BY_INSTRUCTION[] = "Debugger.OperateByInstruction"; const char OPERATE_NATIVE_MIXED[] = "Debugger.OperateNativeMixed"; const char QML_SHOW_APP_ON_TOP[] = "Debugger.QmlShowAppOnTop"; -const char QML_UPDATE_ON_SAVE[] = "Debugger.QmlUpdateOnSave"; const char QML_SELECTTOOL[] = "Debugger.QmlSelectTool"; const char QML_ZOOMTOOL[] = "Debugger.QmlZoomTool"; diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 1a14e3f9700..67961981538 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -958,9 +958,6 @@ public slots: bool parseArguments(const QStringList &args, QString *errorMessage); void parseCommandLineArguments(); - void updateQmlActions() { - action(QmlUpdateOnSave)->setEnabled(boolSetting(ShowQmlObjectTree)); - } public: DebuggerMainWindow *m_mainWindow; @@ -2957,11 +2954,6 @@ void DebuggerPluginPrivate::extensionsInitialized() connect(action(SettingsDialog), &QAction::triggered, [] { ICore::showOptionsDialog(DEBUGGER_COMMON_SETTINGS_ID); }); - // QML Actions - connect(action(ShowQmlObjectTree), &SavedAction::valueChanged, - this, &DebuggerPluginPrivate::updateQmlActions); - updateQmlActions(); - // Toolbar QWidget *toolbarContainer = new QWidget; diff --git a/src/plugins/debugger/qml/qml.pri b/src/plugins/debugger/qml/qml.pri index a8ec530a7c1..3dd714070d4 100644 --- a/src/plugins/debugger/qml/qml.pri +++ b/src/plugins/debugger/qml/qml.pri @@ -8,7 +8,6 @@ HEADERS += \ $$PWD/interactiveinterpreter.h \ $$PWD/qmlv8debuggerclientconstants.h \ $$PWD/qmlinspectoragent.h \ - $$PWD/qmllivetextpreview.h \ $$PWD/qmlinspectoradapter.h SOURCES += \ @@ -20,5 +19,4 @@ SOURCES += \ $$PWD/qmlv8debuggerclient.cpp \ $$PWD/interactiveinterpreter.cpp \ $$PWD/qmlinspectoragent.cpp \ - $$PWD/qmllivetextpreview.cpp \ $$PWD/qmlinspectoradapter.cpp diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h index 5993399699c..60fd23dd2cf 100644 --- a/src/plugins/debugger/qml/qmlengine.h +++ b/src/plugins/debugger/qml/qmlengine.h @@ -40,6 +40,7 @@ #include #include #include +#include QT_FORWARD_DECLARE_CLASS(QTextDocument) diff --git a/src/plugins/debugger/qml/qmlinspectoradapter.cpp b/src/plugins/debugger/qml/qmlinspectoradapter.cpp index 0eb3c88c919..cec5d2f1eaa 100644 --- a/src/plugins/debugger/qml/qmlinspectoradapter.cpp +++ b/src/plugins/debugger/qml/qmlinspectoradapter.cpp @@ -32,7 +32,6 @@ #include "qmladapter.h" #include "qmlinspectoragent.h" -#include "qmllivetextpreview.h" #include #include #include @@ -48,8 +47,6 @@ #include #include #include -#include -#include #include #include @@ -75,13 +72,11 @@ QmlInspectorAdapter::QmlInspectorAdapter(QmlAdapter *debugAdapter, , m_targetToSync(NoTarget) , m_debugIdToSelect(-1) , m_currentSelectedDebugId(-1) - , m_listeningToEditorManager(false) , m_toolsClientConnected(false) , m_inspectorToolsContext("Debugger.QmlInspector") , m_selectAction(new QAction(this)) , m_zoomAction(new QAction(this)) , m_showAppOnTopAction(action(ShowAppOnTop)) - , m_updateOnSaveAction(action(QmlUpdateOnSave)) , m_engineClientConnected(false) { if (!m_engine->isMasterEngine()) @@ -143,11 +138,9 @@ QmlInspectorAdapter::QmlInspectorAdapter(QmlAdapter *debugAdapter, m_selectAction->setCheckable(true); m_zoomAction->setCheckable(true); m_showAppOnTopAction->setCheckable(true); - m_updateOnSaveAction->setCheckable(true); m_selectAction->setEnabled(false); m_zoomAction->setEnabled(false); m_showAppOnTopAction->setEnabled(false); - m_updateOnSaveAction->setEnabled(false); connect(m_selectAction, SIGNAL(triggered(bool)), SLOT(onSelectActionTriggered(bool))); @@ -155,8 +148,6 @@ QmlInspectorAdapter::QmlInspectorAdapter(QmlAdapter *debugAdapter, SLOT(onZoomActionTriggered(bool))); connect(m_showAppOnTopAction, SIGNAL(triggered(bool)), SLOT(onShowAppOnTopChanged(bool))); - connect(m_updateOnSaveAction, SIGNAL(triggered(bool)), - SLOT(onUpdateOnSaveChanged(bool))); } QmlInspectorAdapter::~QmlInspectorAdapter() @@ -225,9 +216,6 @@ void QmlInspectorAdapter::toolsClientStateChanged(QmlDebugClient::State state) Core::ActionManager::registerAction(m_showAppOnTopAction, Core::Id(Constants::QML_SHOW_APP_ON_TOP), m_inspectorToolsContext); - Core::ActionManager::registerAction(m_updateOnSaveAction, - Core::Id(Constants::QML_UPDATE_ON_SAVE), - m_inspectorToolsContext); Core::ICore::addAdditionalContext(m_inspectorToolsContext); @@ -246,8 +234,6 @@ void QmlInspectorAdapter::toolsClientStateChanged(QmlDebugClient::State state) Core::ActionManager::unregisterAction(m_zoomAction, Core::Id(Constants::QML_ZOOMTOOL)); Core::ActionManager::unregisterAction(m_showAppOnTopAction, Core::Id(Constants::QML_SHOW_APP_ON_TOP)); - Core::ActionManager::unregisterAction(m_updateOnSaveAction, - Core::Id(Constants::QML_UPDATE_ON_SAVE)); Core::ICore::removeAdditionalContext(m_inspectorToolsContext); @@ -256,7 +242,6 @@ void QmlInspectorAdapter::toolsClientStateChanged(QmlDebugClient::State state) m_selectAction->setCheckable(false); m_zoomAction->setCheckable(false); m_showAppOnTopAction->setCheckable(false); - m_updateOnSaveAction->setCheckable(false); } } @@ -271,7 +256,6 @@ void QmlInspectorAdapter::engineClientStateChanged(QmlDebugClient::State state) setActiveEngineClient(client); } else if (m_engineClientConnected && client == m_engineClient) { m_engineClientConnected = false; - deletePreviews(); } } @@ -293,85 +277,6 @@ void QmlInspectorAdapter::onObjectFetched(const ObjectReference &ref) } } -void QmlInspectorAdapter::createPreviewForEditor(Core::IEditor *newEditor) -{ - if (!m_engineClientConnected) - return; - - if (!newEditor || newEditor->document()->id() - != QmlJSEditor::Constants::C_QMLJSEDITOR_ID) - return; - - QString filename = newEditor->document()->filePath().toString(); - QmlJS::ModelManagerInterface *modelManager = - QmlJS::ModelManagerInterface::instance(); - if (modelManager) { - QmlJS::Document::Ptr doc = modelManager->snapshot().document(filename); - if (!doc) { - if (filename.endsWith(QLatin1String(".qml")) || filename.endsWith(QLatin1String(".js"))) { - // add to list of docs that we have to update when - // snapshot figures out that there's a new document - m_pendingPreviewDocumentNames.append(filename); - } - return; - } - if (!doc->qmlProgram() && !filename.endsWith(QLatin1String(".js"))) - return; - - QmlJS::Document::Ptr initdoc = m_loadedSnapshot.document(filename); - if (!initdoc) - initdoc = doc; - - if (m_textPreviews.contains(filename)) { - QmlLiveTextPreview *preview = m_textPreviews.value(filename); - preview->associateEditor(newEditor); - } else { - QmlLiveTextPreview *preview - = new QmlLiveTextPreview(doc, initdoc, this, this); - - preview->setApplyChangesToQmlInspector(action(QmlUpdateOnSave)->isChecked()); - connect(preview, SIGNAL(reloadRequest()), - this, SLOT(onReload())); - - m_textPreviews.insert(newEditor->document()->filePath().toString(), preview); - preview->associateEditor(newEditor); - preview->updateDebugIds(); - } - } -} - -void QmlInspectorAdapter::removePreviewForEditor(Core::IEditor *editor) -{ - if (QmlLiveTextPreview *preview - = m_textPreviews.value(editor->document()->filePath().toString())) { - preview->unassociateEditor(editor); - } -} - -void QmlInspectorAdapter::updatePendingPreviewDocuments(QmlJS::Document::Ptr doc) -{ - int idx = -1; - idx = m_pendingPreviewDocumentNames.indexOf(doc->fileName()); - - if (idx == -1) - return; - - QList editors - = Core::DocumentModel::editorsForFilePath(doc->fileName()); - - if (editors.isEmpty()) - return; - - m_pendingPreviewDocumentNames.removeAt(idx); - - Core::IEditor *editor = editors.takeFirst(); - createPreviewForEditor(editor); - QmlLiveTextPreview *preview - = m_textPreviews.value(editor->document()->filePath().toString()); - foreach (Core::IEditor *editor, editors) - preview->associateEditor(editor); -} - void QmlInspectorAdapter::onSelectActionTriggered(bool checked) { QTC_ASSERT(toolsClient(), return); @@ -402,16 +307,6 @@ void QmlInspectorAdapter::onShowAppOnTopChanged(bool checked) toolsClient()->showAppOnTop(checked); } -void QmlInspectorAdapter::onUpdateOnSaveChanged(bool checked) -{ - QTC_ASSERT(toolsClient(), return); - for (QHash::const_iterator it - = m_textPreviews.constBegin(); - it != m_textPreviews.constEnd(); ++it) { - it.value()->setApplyChangesToQmlInspector(checked); - } -} - void QmlInspectorAdapter::setActiveEngineClient(BaseEngineDebugClient *client) { if (m_engineClient == client) @@ -420,54 +315,6 @@ void QmlInspectorAdapter::setActiveEngineClient(BaseEngineDebugClient *client) m_engineClient = client; m_agent->setEngineClient(m_engineClient); m_engineClientConnected = true; - - if (m_engineClient && - m_engineClient->state() == QmlDebugClient::Enabled) { - QmlJS::ModelManagerInterface *modelManager - = QmlJS::ModelManagerInterface::instance(); - if (modelManager) { - QmlJS::Snapshot snapshot = modelManager->snapshot(); - for (QHash::const_iterator it - = m_textPreviews.constBegin(); - it != m_textPreviews.constEnd(); ++it) { - QmlJS::Document::Ptr doc = snapshot.document(it.key()); - it.value()->resetInitialDoc(doc); - } - - initializePreviews(); - } - } -} - -void QmlInspectorAdapter::initializePreviews() -{ - QmlJS::ModelManagerInterface *modelManager - = QmlJS::ModelManagerInterface::instance(); - if (modelManager) { - m_loadedSnapshot = modelManager->snapshot(); - - if (!m_listeningToEditorManager) { - m_listeningToEditorManager = true; - QObject *em = Core::EditorManager::instance(); - connect(em, SIGNAL(editorAboutToClose(Core::IEditor*)), - this, SLOT(removePreviewForEditor(Core::IEditor*))); - connect(em, SIGNAL(editorOpened(Core::IEditor*)), - this, SLOT(createPreviewForEditor(Core::IEditor*))); - connect(modelManager, - SIGNAL(documentChangedOnDisk(QmlJS::Document::Ptr)), - this, SLOT(updatePendingPreviewDocuments(QmlJS::Document::Ptr))); - } - - // initial update - foreach (Core::IDocument *document, Core::DocumentModel::openedDocuments()) { - QList editors = Core::DocumentModel::editorsForDocument(document); - createPreviewForEditor(editors.takeFirst()); - QmlLiveTextPreview *preview - = m_textPreviews.value(document->filePath().toString()); - foreach (Core::IEditor *editor, editors) - preview->associateEditor(editor); - } - } } void QmlInspectorAdapter::showConnectionStateMessage(const QString &message) @@ -500,60 +347,20 @@ void QmlInspectorAdapter::selectObject(const ObjectReference &obj, agent()->selectObjectInTree(obj.debugId()); } -void QmlInspectorAdapter::deletePreviews() -{ - qDeleteAll(m_textPreviews); - m_textPreviews.clear(); -} - void QmlInspectorAdapter::enableTools(const bool enable) { if (!m_toolsClientConnected) return; m_selectAction->setEnabled(enable); m_showAppOnTopAction->setEnabled(enable); - m_updateOnSaveAction->setEnabled(enable); // only enable zoom action for Qt 4.x/old client // (zooming is integrated into selection tool in Qt 5). if (!qobject_cast(m_toolsClient)) m_zoomAction->setEnabled(enable); } -void QmlInspectorAdapter::onReload() -{ - QHash changesHash; - for (QHash::const_iterator it - = m_textPreviews.constBegin(); - it != m_textPreviews.constEnd(); ++it) { - if (it.value()->hasUnsynchronizableChange()) { - QFileInfo info = QFileInfo(it.value()->fileName()); - QFile changedFile(it.value()->fileName()); - QByteArray fileContents; - if (changedFile.open(QFile::ReadOnly)) - fileContents = changedFile.readAll(); - changedFile.close(); - changesHash.insert(info.fileName(), - fileContents); - } - } - if (m_toolsClient) - m_toolsClient->reload(changesHash); -} - void QmlInspectorAdapter::onReloaded() { - QmlJS::ModelManagerInterface *modelManager = - QmlJS::ModelManagerInterface::instance(); - if (modelManager) { - QmlJS::Snapshot snapshot = modelManager->snapshot(); - m_loadedSnapshot = snapshot; - for (QHash::const_iterator it - = m_textPreviews.constBegin(); - it != m_textPreviews.constEnd(); ++it) { - QmlJS::Document::Ptr doc = snapshot.document(it.key()); - it.value()->resetInitialDoc(doc); - } - } m_agent->reloadEngines(); } diff --git a/src/plugins/debugger/qml/qmlinspectoradapter.h b/src/plugins/debugger/qml/qmlinspectoradapter.h index a39f196aba6..9c487f439c7 100644 --- a/src/plugins/debugger/qml/qmlinspectoradapter.h +++ b/src/plugins/debugger/qml/qmlinspectoradapter.h @@ -35,9 +35,6 @@ #include #include -#include - -namespace Core { class IEditor; } namespace QmlDebug { class BaseEngineDebugClient; @@ -50,10 +47,8 @@ namespace Debugger { namespace Internal { class DebuggerEngine; -class WatchTreeView; class QmlAdapter; class QmlInspectorAgent; -class QmlLiveTextPreview; class QmlInspectorAdapter : public QObject { @@ -84,15 +79,9 @@ private slots: void selectObjectsFromToolsClient(const QList &debugIds); void onObjectFetched(const QmlDebug::ObjectReference &ref); - void createPreviewForEditor(Core::IEditor *newEditor); - void removePreviewForEditor(Core::IEditor *editor); - void updatePendingPreviewDocuments(QmlJS::Document::Ptr doc); - void onSelectActionTriggered(bool checked); void onZoomActionTriggered(bool checked); void onShowAppOnTopChanged(bool checked); - void onUpdateOnSaveChanged(bool checked); - void onReload(); void onReloaded(); void onDestroyedObject(int); void jumpToObjectDefinitionInEditor(const QmlDebug::FileReference &objSource, int debugId = -1); @@ -100,14 +89,12 @@ private slots: private: void setActiveEngineClient(QmlDebug::BaseEngineDebugClient *client); - void initializePreviews(); void showConnectionStateMessage(const QString &message); enum SelectionTarget { NoTarget, ToolTarget, EditorTarget }; void selectObject( const QmlDebug::ObjectReference &objectReference, SelectionTarget target); - void deletePreviews(); void enableTools(const bool enable); @@ -124,19 +111,12 @@ private: int m_currentSelectedDebugId; QString m_currentSelectedDebugName; - // Qml/JS editor integration - bool m_listeningToEditorManager; - QHash m_textPreviews; - QmlJS::Snapshot m_loadedSnapshot; //the snapshot loaded by the viewer - QStringList m_pendingPreviewDocumentNames; - // toolbar bool m_toolsClientConnected; Core::Context m_inspectorToolsContext; QAction *m_selectAction; QAction *m_zoomAction; QAction *m_showAppOnTopAction; - QAction *m_updateOnSaveAction; bool m_engineClientConnected; }; diff --git a/src/plugins/debugger/qml/qmllivetextpreview.cpp b/src/plugins/debugger/qml/qmllivetextpreview.cpp deleted file mode 100644 index fb6cf9540ca..00000000000 --- a/src/plugins/debugger/qml/qmllivetextpreview.cpp +++ /dev/null @@ -1,743 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms and -** conditions see http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "qmllivetextpreview.h" - -#include "qmlinspectoradapter.h" -#include "qmlinspectoragent.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace QmlDebug; -using namespace QmlJS; -using namespace QmlJS::AST; - -namespace Debugger { -namespace Internal { - -const char INFO_OUT_OF_SYNC[] = "Debugger.Inspector.OutOfSyncWarning"; - -/*! - Associates the UiObjectMember* to their QDeclarativeDebugObjectReference. - */ -class MapObjectWithDebugReference : public Visitor -{ -public: - typedef QList DebugIdList; - MapObjectWithDebugReference() : activated(0) {} - virtual void endVisit(UiObjectDefinition *ast); - virtual void endVisit(UiObjectBinding *ast); - virtual bool visit(UiObjectDefinition *ast); - virtual bool visit(UiObjectBinding *ast); - - QHash, DebugIdList> ids; - QString filename; - QHash result; - QSet lookupObjects; - -private: - void process(UiObjectMember *ast); - void process(UiObjectBinding *ast); -private: - int activated; -}; - -class UpdateInspector : public Delta { -private: - static inline QString stripQuotes(const QString &str) - { - if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"'))) - || (str.startsWith(QLatin1Char('\'')) - && str.endsWith(QLatin1Char('\'')))) - return str.mid(1, str.length() - 2); - - return str; - } - - static inline QString deEscape(const QString &value) - { - QString result = value; - - result.replace(QLatin1String("\\\\"), QLatin1String("\\")); - result.replace(QLatin1String("\\\""), QLatin1String("\"")); - result.replace(QLatin1String("\\\t"), QLatin1String("\t")); - result.replace(QLatin1String("\\\r"), QLatin1String("\\\r")); - result.replace(QLatin1String("\\\n"), QLatin1String("\n")); - - return result; - } - - static QString cleanExpression(const QString &expression, - UiScriptBinding *scriptBinding) - { - QString trimmedExpression = expression.trimmed(); - - if (ExpressionStatement *expStatement - = cast(scriptBinding->statement)) { - if (expStatement->semicolonToken.isValid()) - trimmedExpression.chop(1); - } - - return deEscape(stripQuotes(trimmedExpression)); - } - - static bool isLiteralValue(ExpressionNode *expr) - { - if (cast(expr)) - return true; - else if (cast(expr)) - return true; - else if (UnaryPlusExpression *plusExpr - = cast(expr)) - return isLiteralValue(plusExpr->expression); - else if (UnaryMinusExpression *minusExpr - = cast(expr)) - return isLiteralValue(minusExpr->expression); - else if (cast(expr)) - return true; - else if (cast(expr)) - return true; - else - return false; - } - - static inline bool isLiteralValue(UiScriptBinding *script) - { - if (!script || !script->statement) - return false; - - ExpressionStatement *exprStmt - = cast(script->statement); - if (exprStmt) - return isLiteralValue(exprStmt->expression); - else - return false; - } - - static QVariant castToLiteral(const QString &expression, - UiScriptBinding *scriptBinding) - { - const QString cleanedValue = cleanExpression(expression, scriptBinding); - QVariant castedExpression; - - ExpressionStatement *expStatement - = cast(scriptBinding->statement); - - switch (expStatement->expression->kind) { - case Node::Kind_NumericLiteral: - case Node::Kind_UnaryPlusExpression: - case Node::Kind_UnaryMinusExpression: - castedExpression = QVariant(cleanedValue).toReal(); - break; - case Node::Kind_StringLiteral: - castedExpression = QVariant(cleanedValue).toString(); - break; - case Node::Kind_TrueLiteral: - case Node::Kind_FalseLiteral: - castedExpression = QVariant(cleanedValue).toBool(); - break; - default: - castedExpression = cleanedValue; - break; - } - - return castedExpression; - } - -protected: - virtual void updateMethodBody(DebugId debugId, - UiObjectMember *parentDefinition, - UiScriptBinding *scriptBinding, - const QString &methodName, - const QString &methodBody) - { - Q_UNUSED(scriptBinding); - Q_UNUSED(parentDefinition); - appliedChangesToViewer = true; - if (m_inspectorAdapter->engineClient()) - m_inspectorAdapter->engineClient()->setMethodBody(debugId, - methodName, methodBody); - } - - virtual void updateScriptBinding(DebugId debugId, - UiObjectMember *parentDefinition, - UiScriptBinding *scriptBinding, - const QString &propertyName, - const QString &scriptCode) - { - if (unsyncronizableChanges - == QmlLiveTextPreview::NoUnsyncronizableChanges) { - if (propertyName == QLatin1String("id")) { - unsyncronizableElementName = propertyName; - unsyncronizableChanges - = QmlLiveTextPreview::AttributeChangeWarning; - unsyncronizableChangeLine - = parentDefinition->firstSourceLocation().startLine; - unsyncronizableChangeColumn - = parentDefinition->firstSourceLocation().startColumn; - } - } - - QVariant expr = scriptCode; - const bool isLiteral = isLiteralValue(scriptBinding); - if (isLiteral) - expr = castToLiteral(scriptCode, scriptBinding); - appliedChangesToViewer = true; - if (m_inspectorAdapter->engineClient()) - m_inspectorAdapter->engineClient()->setBindingForObject( - debugId, propertyName, expr, - isLiteral, document()->fileName(), - scriptBinding->firstSourceLocation().startLine); - } - - virtual void resetBindingForObject(int debugId, const QString &propertyName) - { - appliedChangesToViewer = true; - if (m_inspectorAdapter->engineClient()) - m_inspectorAdapter->engineClient()->resetBindingForObject(debugId, propertyName); - } - - virtual void removeObject(int debugId) - { - appliedChangesToViewer = true; - if (m_inspectorAdapter->toolsClient()) - m_inspectorAdapter->toolsClient()->destroyQmlObject(debugId); - } - - virtual void createObject(const QString &qmlText, DebugId ref, - const QStringList &importList, - const QString &filename, - int order) - { - appliedChangesToViewer = true; - referenceRefreshRequired = true; - if (m_inspectorAdapter->toolsClient()) - m_inspectorAdapter->toolsClient()->createQmlObject(qmlText, ref, importList, filename, order); - } - - virtual void reparentObject(int debugId, int newParent) - { - appliedChangesToViewer = true; - if (m_inspectorAdapter->toolsClient()) - m_inspectorAdapter->toolsClient()->reparentQmlObject(debugId, newParent); - } - - void notifyUnsyncronizableElementChange(UiObjectMember *parent) - { - if (unsyncronizableChanges == QmlLiveTextPreview::NoUnsyncronizableChanges) { - UiObjectDefinition *parentDefinition = cast(parent); - if (parentDefinition && parentDefinition->qualifiedTypeNameId - && !parentDefinition->qualifiedTypeNameId->name.isEmpty()) - { - unsyncronizableElementName - = parentDefinition->qualifiedTypeNameId->name.toString(); - unsyncronizableChanges - = QmlLiveTextPreview::ElementChangeWarning; - unsyncronizableChangeLine - = parentDefinition->firstSourceLocation().startLine; - unsyncronizableChangeColumn - = parentDefinition->firstSourceLocation().startColumn; - } - } - } - -public: - UpdateInspector(QmlInspectorAdapter *inspectorAdapter) - : appliedChangesToViewer(false) - , referenceRefreshRequired(false) - , unsyncronizableChanges(QmlLiveTextPreview::NoUnsyncronizableChanges) - , m_inspectorAdapter(inspectorAdapter) - { - } - - bool appliedChangesToViewer; - bool referenceRefreshRequired; - QString unsyncronizableElementName; - QmlLiveTextPreview::UnsyncronizableChangeType unsyncronizableChanges; - unsigned unsyncronizableChangeLine; - unsigned unsyncronizableChangeColumn; - QmlInspectorAdapter *m_inspectorAdapter; - -}; - -bool MapObjectWithDebugReference::visit(UiObjectDefinition *ast) -{ - if (lookupObjects.contains(ast)) - activated++; - return true; -} - -bool MapObjectWithDebugReference::visit(UiObjectBinding *ast) -{ - if (lookupObjects.contains(ast)) - activated++; - return true; -} - -void MapObjectWithDebugReference::endVisit(UiObjectDefinition *ast) -{ - process(ast); - if (lookupObjects.contains(ast)) - activated--; -} - -void MapObjectWithDebugReference::endVisit(UiObjectBinding *ast) -{ - process(ast); - if (lookupObjects.contains(ast)) - activated--; -} - -void MapObjectWithDebugReference::process(UiObjectMember *ast) -{ - if (lookupObjects.isEmpty() || activated) { - SourceLocation loc = ast->firstSourceLocation(); - QHash, DebugIdList>::const_iterator it - = ids.constFind(qMakePair(loc.startLine, loc.startColumn)); - if (it != ids.constEnd()) - result[ast].append(*it); - } -} - -void MapObjectWithDebugReference::process(UiObjectBinding *ast) -{ - if (lookupObjects.isEmpty() || activated) { - SourceLocation loc = ast->qualifiedTypeNameId->identifierToken; - QHash, DebugIdList>::const_iterator it - = ids.constFind(qMakePair(loc.startLine, loc.startColumn)); - if (it != ids.constEnd()) - result[ast].append(*it); - } -} - -/*! - * Manages a Qml/JS document for the inspector - */ -QmlLiveTextPreview::QmlLiveTextPreview(const Document::Ptr &doc, - const Document::Ptr &initDoc, - QmlInspectorAdapter *inspectorAdapter, - QObject *parent) - : QObject(parent) - , m_previousDoc(doc) - , m_initialDoc(initDoc) - , m_applyChangesToQmlInspector(true) - , m_inspectorAdapter(inspectorAdapter) - , m_nodeForOffset(0) - , m_updateNodeForOffset(false) - , m_changesUnsynchronizable(false) - , m_contentsChanged(false) -{ - QTC_CHECK(doc->fileName() == initDoc->fileName()); - - ModelManagerInterface *modelManager - = ModelManagerInterface::instance(); - if (modelManager) { - connect(modelManager, SIGNAL(documentChangedOnDisk(QmlJS::Document::Ptr)), - SLOT(documentChanged(QmlJS::Document::Ptr))); - } - connect(m_inspectorAdapter->agent(), SIGNAL(objectTreeUpdated()), - SLOT(updateDebugIds())); - connect(this, - SIGNAL(fetchObjectsForLocation(QString,int,int)), - m_inspectorAdapter->agent(), - SLOT(fetchContextObjectsForLocation(QString,int,int))); - connect(m_inspectorAdapter->agent(), SIGNAL(automaticUpdateFailed()), - SLOT(onAutomaticUpdateFailed())); -} - -QmlLiveTextPreview::~QmlLiveTextPreview() -{ - removeOutofSyncInfo(); -} - -void QmlLiveTextPreview::associateEditor(Core::IEditor *editor) -{ - QTC_ASSERT(editor, return); - using namespace TextEditor; - if (editor->document()->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID) { - QTC_ASSERT(QLatin1String(editor->widget()->metaObject()->className()) == - QLatin1String("QmlJSEditor::Internal::QmlJSEditorWidget"), - return); - - TextEditorWidget *editWidget - = qobject_cast(editor->widget()); - QTC_ASSERT(editWidget, return); - - if (!m_editors.contains(editWidget)) { - m_editors << editWidget; - if (m_inspectorAdapter) { - connect(editWidget, SIGNAL(textChanged()), SLOT(editorContentsChanged())); - connect(editWidget, - SIGNAL(selectedElementsChanged(QList,QString)), - SLOT(changeSelectedElements(QList,QString))); - } - } - } -} - -void QmlLiveTextPreview::unassociateEditor(Core::IEditor *oldEditor) -{ - using namespace TextEditor; - if (oldEditor && oldEditor->document()->id() - == QmlJSEditor::Constants::C_QMLJSEDITOR_ID) { - TextEditorWidget *editWidget - = qobject_cast(oldEditor->widget()); - QTC_ASSERT(editWidget, return); - - if (m_editors.contains(editWidget)) { - m_editors.removeOne(editWidget); - disconnect(editWidget, 0, this, 0); - } - } -} - -void QmlLiveTextPreview::resetInitialDoc(const Document::Ptr &doc) -{ - m_initialDoc = doc; - m_previousDoc = doc; - m_createdObjects.clear(); - m_debugIds.clear(); - m_docWithUnappliedChanges.clear(); - m_changesUnsynchronizable = false; - removeOutofSyncInfo(); -} - -const QString QmlLiveTextPreview::fileName() -{ - return m_previousDoc->fileName(); -} - -void QmlLiveTextPreview::setApplyChangesToQmlInspector(bool applyChanges) -{ - if (applyChanges && !m_applyChangesToQmlInspector) { - if (m_docWithUnappliedChanges) { - m_applyChangesToQmlInspector = true; - documentChanged(m_docWithUnappliedChanges); - } - } - - m_applyChangesToQmlInspector = applyChanges; -} - -void QmlLiveTextPreview::updateDebugIds() -{ - if (!m_initialDoc->qmlProgram()) - return; - - DebugIdHash::const_iterator it - = m_inspectorAdapter->agent()->debugIdHash().constFind( - qMakePair(m_initialDoc->fileName(), 0)); - if (it != m_inspectorAdapter->agent()->debugIdHash().constEnd()) { - // Map all the object that comes from the document as it has been loaded - // by the server. - const Document::Ptr &doc = m_initialDoc; - - MapObjectWithDebugReference visitor; - visitor.ids = (*it); - visitor.filename = doc->fileName(); - doc->qmlProgram()->accept(&visitor); - - m_debugIds = visitor.result; - if (doc != m_previousDoc) { - Delta delta; - m_debugIds = delta(doc, m_previousDoc, m_debugIds); - } - } - - const Document::Ptr &doc = m_previousDoc; - if (!doc->qmlProgram()) - return; - - // Map the root nodes of the document. - if (doc->qmlProgram()->members && doc->qmlProgram()->members->member) { - UiObjectMember *root = doc->qmlProgram()->members->member; - QHashIterator rIds(m_inspectorAdapter->agent()->rootObjectIds()); - QList r; - while (rIds.hasNext()) { - rIds.next(); - if (rIds.value() == doc->componentName()) - r += rIds.key(); - } - if (!r.isEmpty()) - m_debugIds[root] += r; - } - - // Map the node of the later created objects. - for (QHash >::const_iterator it - = m_createdObjects.constBegin(); - it != m_createdObjects.constEnd(); ++it) { - - const Document::Ptr &doc = it.key(); - - DebugIdHash::const_iterator id_it = m_inspectorAdapter->agent()->debugIdHash().constFind( - qMakePair(doc->fileName(), doc->editorRevision())); - if (id_it == m_inspectorAdapter->agent()->debugIdHash().constEnd()) - continue; - - MapObjectWithDebugReference visitor; - visitor.ids = *id_it; - visitor.filename = doc->fileName(); - visitor.lookupObjects = it.value(); - doc->qmlProgram()->accept(&visitor); - - Delta::DebugIdMap debugIds = visitor.result; - if (doc != m_previousDoc) { - Delta delta; - debugIds = delta(doc, m_previousDoc, debugIds); - } - for (Delta::DebugIdMap::const_iterator it2 = debugIds.constBegin(); - it2 != debugIds.constEnd(); ++it2) { - m_debugIds[it2.key()] += it2.value(); - } - } - if (m_updateNodeForOffset) - changeSelectedElements(m_lastOffsets, QString()); -} - -void QmlLiveTextPreview::changeSelectedElements(const QList offsetObjects, - const QString &wordAtCursor) -{ - if (m_editors.isEmpty() || !m_previousDoc) - return; - - QList offsets; - foreach (UiObjectMember *member, offsetObjects) - offsets << member->firstSourceLocation().offset; - - if (!changeSelectedElements(offsets, wordAtCursor) && m_initialDoc && offsetObjects.count()) { - m_updateNodeForOffset = true; - emit fetchObjectsForLocation(m_initialDoc->fileName(), - offsetObjects.first()->firstSourceLocation().startLine, - offsetObjects.first()->firstSourceLocation().startColumn); - } -} - -bool QmlLiveTextPreview::changeSelectedElements(const QList offsets, - const QString &wordAtCursor) -{ - m_updateNodeForOffset = false; - m_lastOffsets = offsets; - ObjectReference objectRefUnderCursor; - objectRefUnderCursor - = m_inspectorAdapter->agent()->objectForName(wordAtCursor); - - QList selectedReferences; - bool containsReferenceUnderCursor = false; - - foreach (int offset, offsets) { - if (offset >= 0) { - QList list = objectReferencesForOffset(offset); - - if (!containsReferenceUnderCursor - && objectRefUnderCursor.isValid()) { - foreach (int id, list) { - if (id == objectRefUnderCursor.debugId()) { - containsReferenceUnderCursor = true; - break; - } - } - } - - selectedReferences << list; - } - } - - // fallback: use ref under cursor if nothing else is found - if (selectedReferences.isEmpty() - && !containsReferenceUnderCursor - && objectRefUnderCursor.isValid()) { - selectedReferences << objectRefUnderCursor.debugId(); - } - - if (selectedReferences.isEmpty()) - return false; - emit selectedItemsChanged(selectedReferences); - return true; -} - -void QmlLiveTextPreview::documentChanged(Document::Ptr doc) -{ - if (doc->fileName() != m_previousDoc->fileName()) - return; - - // Changes to be applied when changes were made from the editor. - // m_contentsChanged ensures that the changes were made by the user in - // the editor before starting with the comparisons. - if (!m_contentsChanged) - return; - - if (m_applyChangesToQmlInspector) { - m_docWithUnappliedChanges.clear(); - - if (doc && m_previousDoc && doc->fileName() == m_previousDoc->fileName()) { - if (doc->fileName().endsWith(QLatin1String(".js"))) { - showSyncWarning(JSChangeWarning, QString(), 0, 0); - m_previousDoc = doc; - return; - } - if (doc->qmlProgram() && m_previousDoc->qmlProgram()) { - UpdateInspector delta(m_inspectorAdapter); - m_debugIds = delta(m_previousDoc, doc, m_debugIds); - - if (delta.referenceRefreshRequired) - m_inspectorAdapter->agent()->queryEngineContext(); - - - if (delta.unsyncronizableChanges != NoUnsyncronizableChanges) { - showSyncWarning(delta.unsyncronizableChanges, - delta.unsyncronizableElementName, - delta.unsyncronizableChangeLine, - delta.unsyncronizableChangeColumn); - m_previousDoc = doc; - return; - } - m_previousDoc = doc; - if (!delta.newObjects.isEmpty()) - m_createdObjects[doc] += delta.newObjects; - if (m_inspectorAdapter->toolsClient()) - m_inspectorAdapter->toolsClient()->clearComponentCache(); - } - } - } else { - m_docWithUnappliedChanges = doc; - } - m_contentsChanged = false; -} - -void QmlLiveTextPreview::editorContentsChanged() -{ - m_contentsChanged = true; -} - -void QmlLiveTextPreview::onAutomaticUpdateFailed() -{ - showSyncWarning(AutomaticUpdateFailed, QString(), UINT_MAX, UINT_MAX); -} - -QList QmlLiveTextPreview::objectReferencesForOffset(quint32 offset) -{ - QList result; - QHashIterator > iter(m_debugIds); - UiObjectMember *possibleNode = 0; - while (iter.hasNext()) { - iter.next(); - UiObjectMember *member = iter.key(); - quint32 startOffset = member->firstSourceLocation().offset; - quint32 endOffset = member->lastSourceLocation().offset; - if (startOffset <= offset && offset <= endOffset) { - if (!possibleNode) - possibleNode = member; - if (possibleNode->firstSourceLocation().offset <= startOffset && - endOffset <= possibleNode->lastSourceLocation().offset) - possibleNode = member; - } - } - if (possibleNode) { - if (possibleNode != m_nodeForOffset) { - //We have found a better match, set flag so that we can - //query again to check if this is the best match for the offset - m_updateNodeForOffset = true; - m_nodeForOffset = possibleNode; - } - result = m_debugIds.value(possibleNode); - } - return result; -} - -void QmlLiveTextPreview::showSyncWarning( - UnsyncronizableChangeType unsyncronizableChangeType, - const QString &elementName, unsigned line, unsigned column) -{ - QString errorMessage; - switch (unsyncronizableChangeType) { - case AttributeChangeWarning: - errorMessage = tr("The %1 attribute at line %2, column %3 cannot be " - "changed without reloading the QML application. ") - .arg(elementName, QString::number(line), QString::number(column)); - break; - case ElementChangeWarning: - errorMessage = tr("The %1 element at line %2, column %3 cannot be " - "changed without reloading the QML application. ") - .arg(elementName, QString::number(line), QString::number(column)); - break; - case JSChangeWarning: - errorMessage = tr("The changes in JavaScript cannot be applied " - "without reloading the QML application. "); - break; - case AutomaticUpdateFailed: - errorMessage = tr("The changes made cannot be applied without " - "reloading the QML application. "); - break; - case QmlLiveTextPreview::NoUnsyncronizableChanges: - default: - return; - } - - m_changesUnsynchronizable = true; - errorMessage.append(tr("You can continue debugging, but behavior can be unexpected.")); - - // Clear infobars if present before showing the same. Otherwise multiple infobars - // will be shown in case the user changes and saves the file multiple times. - removeOutofSyncInfo(); - - foreach (TextEditor::TextEditorWidget *editor, m_editors) { - if (editor) { - Core::InfoBar *infoBar = editor->textDocument()->infoBar(); - Core::InfoBarEntry info(Core::Id(INFO_OUT_OF_SYNC), errorMessage); - BaseToolsClient *toolsClient = m_inspectorAdapter->toolsClient(); - if (toolsClient && toolsClient->supportReload()) - info.setCustomButtonInfo(tr("Reload QML"), [this]() { - removeOutofSyncInfo(); - emit reloadRequest(); - }); - infoBar->addInfo(info); - } - } -} - -void QmlLiveTextPreview::removeOutofSyncInfo() -{ - foreach (TextEditor::TextEditorWidget *editor, m_editors) { - if (editor) { - Core::InfoBar *infoBar = editor->textDocument()->infoBar(); - infoBar->removeInfo(Core::Id(INFO_OUT_OF_SYNC)); - } - } -} - -} // namespace Internal -} // namespace Debugger diff --git a/src/plugins/debugger/qml/qmllivetextpreview.h b/src/plugins/debugger/qml/qmllivetextpreview.h deleted file mode 100644 index 4102d79ac4b..00000000000 --- a/src/plugins/debugger/qml/qmllivetextpreview.h +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms and -** conditions see http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef QMLLIVETEXTPREVIEW_H -#define QMLLIVETEXTPREVIEW_H - -#include -#include - -namespace Core { class IEditor; } - -namespace QmlJS { class ModelManagerInterface; } - -namespace Debugger { -namespace Internal { - -class UpdateInspector; -class QmlInspectorAdapter; - -class QmlLiveTextPreview : public QObject -{ - Q_OBJECT - -public: - QmlLiveTextPreview(const QmlJS::Document::Ptr &doc, - const QmlJS::Document::Ptr &initDoc, - QmlInspectorAdapter *inspectorAdapter, - QObject *parent = 0); - ~QmlLiveTextPreview(); - - void associateEditor(Core::IEditor *editor); - void unassociateEditor(Core::IEditor *editor); - void resetInitialDoc(const QmlJS::Document::Ptr &doc); - const QString fileName(); - bool hasUnsynchronizableChange() { return m_changesUnsynchronizable; } - -signals: - void selectedItemsChanged(const QList &debugIds); - void fetchObjectsForLocation(const QString &file, - int lineNumber, int columnNumber); - void reloadRequest(); - -public slots: - void setApplyChangesToQmlInspector(bool applyChanges); - void updateDebugIds(); - -private slots: - void changeSelectedElements(const QList offsets, - const QString &wordAtCursor); - void documentChanged(QmlJS::Document::Ptr doc); - void editorContentsChanged(); - void onAutomaticUpdateFailed(); - -private: - enum UnsyncronizableChangeType { - NoUnsyncronizableChanges, - AttributeChangeWarning, - ElementChangeWarning, - JSChangeWarning, - AutomaticUpdateFailed - }; - - bool changeSelectedElements(const QList offsets, const QString &wordAtCursor); - QList objectReferencesForOffset(quint32 offset); - void showSyncWarning(UnsyncronizableChangeType unsyncronizableChangeType, - const QString &elementName, - unsigned line, unsigned column); - void removeOutofSyncInfo(); - -private: - QHash > m_debugIds; - QHash > m_createdObjects; - - QmlJS::Document::Ptr m_previousDoc; - QmlJS::Document::Ptr m_initialDoc; //the document that was loaded by the server - - QList > m_editors; - - bool m_applyChangesToQmlInspector; - QmlJS::Document::Ptr m_docWithUnappliedChanges; - QmlInspectorAdapter *m_inspectorAdapter; - QList m_lastOffsets; - QmlJS::AST::UiObjectMember *m_nodeForOffset; - bool m_updateNodeForOffset; - bool m_changesUnsynchronizable; - bool m_contentsChanged; - - friend class UpdateInspector; -}; - -} // namespace Internal -} // namespace Debugger - -#endif // QMLLIVETEXTPREVIEW_H From 6960da702a257c98729e3248c6bbb9c6c68cb013 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 17 Mar 2015 15:59:39 +0100 Subject: [PATCH 48/61] Debugger: Fix display of array base address Change-Id: I858d38a1f52cd7247f1b57d686c3c065e5a0fb61 Reviewed-by: Christian Stenger --- share/qtcreator/debugger/dumper.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index a7bca8fd297..fc977fc9389 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -910,6 +910,10 @@ class DumperBase: innerType = value[0].type ts = innerType.sizeof #self.putAddress(value.address) + try: + self.putValue("@0x%x" % self.addressOf(value), priority = -1) + except: + self.putEmptyValue() self.putType(arrayType) self.putNumChild(1) From b0f3157d25538ea87d37f8bc8ec33e2c89b24a17 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 18 Mar 2015 13:25:55 +0100 Subject: [PATCH 49/61] Debugger: Auto-detect gdb on windows Task-number: QTCREATORBUG-14157 Change-Id: I3e556a44832fea06f6a57882b0470dcd9c22b0aa Reviewed-by: Robert Loehning --- src/plugins/debugger/debuggeritemmanager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp index cc04db5bc9d..4b97b40e289 100644 --- a/src/plugins/debugger/debuggeritemmanager.cpp +++ b/src/plugins/debugger/debuggeritemmanager.cpp @@ -200,8 +200,11 @@ void DebuggerItemManager::autoDetectGdbOrLldbDebuggers() { QStringList filters; filters.append(QLatin1String("gdb-i686-pc-mingw32")); + filters.append(QLatin1String("gdb-i686-pc-mingw32.exe")); filters.append(QLatin1String("gdb")); + filters.append(QLatin1String("gdb.exe")); filters.append(QLatin1String("lldb")); + filters.append(QLatin1String("lldb.exe")); filters.append(QLatin1String("lldb-*")); // DebuggerItem result; From 510667ec2e500e36b8750c302cc2093cff0f369b Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 2 Mar 2015 11:15:17 +0100 Subject: [PATCH 50/61] Journald: Only emit signals for PIDs running on the current machine Change-Id: Ie4ea04b3505a5f3a9ba1b32eeb1e74fc28353737 Reviewed-by: Tobias Hunger --- .../projectexplorer/journaldwatcher.cpp | 24 ++++++++++++++----- src/plugins/projectexplorer/journaldwatcher.h | 4 ++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/plugins/projectexplorer/journaldwatcher.cpp b/src/plugins/projectexplorer/journaldwatcher.cpp index 05a2f15796c..29af127bf64 100644 --- a/src/plugins/projectexplorer/journaldwatcher.cpp +++ b/src/plugins/projectexplorer/journaldwatcher.cpp @@ -33,7 +33,6 @@ #include #include -#include #include #include @@ -153,6 +152,17 @@ JournaldWatcher *JournaldWatcher::instance() return m_instance; } +const QByteArray &JournaldWatcher::machineId() +{ + static QByteArray id; + if (id.isEmpty()) { + sd_id128 sdId; + if (sd_id128_get_machine(&sdId) == 0) + id = QByteArray(reinterpret_cast(sdId.bytes), 16); + } + return id; +} + bool JournaldWatcher::subscribe(QObject *subscriber, const Subscription &subscription) { // Check that we do not have that subscriber yet: @@ -196,8 +206,7 @@ JournaldWatcher::JournaldWatcher() void JournaldWatcher::handleEntry() { - // process events: - if (!d->m_notifier || sd_journal_process(d->m_journalContext) == SD_JOURNAL_NOP) + if (!d->m_notifier) return; LogEntry logEntry; @@ -209,12 +218,15 @@ void JournaldWatcher::handleEntry() foreach (const JournaldWatcherPrivate::SubscriberInformation &info, d->m_subscriptions) info.subscription(logEntry); - QByteArray tmp = logEntry.value(QByteArrayLiteral("_PID")); - quint64 pid = tmp.isEmpty() ? 0 : QString::fromLatin1(tmp).toInt(); + if (logEntry.value(QByteArrayLiteral("_MACHINE_ID")) != machineId()) + continue; + + const QByteArray pid = logEntry.value(QByteArrayLiteral("_PID")); + quint64 pidNum = pid.isEmpty() ? 0 : QString::fromLatin1(pid).toInt(); QString message = QString::fromUtf8(logEntry.value(QByteArrayLiteral("MESSAGE"))); - emit journaldOutput(pid, message); + emit journaldOutput(pidNum, message); } } diff --git a/src/plugins/projectexplorer/journaldwatcher.h b/src/plugins/projectexplorer/journaldwatcher.h index 9f266ef97e3..98ef53e0516 100644 --- a/src/plugins/projectexplorer/journaldwatcher.h +++ b/src/plugins/projectexplorer/journaldwatcher.h @@ -31,6 +31,8 @@ #ifndef JOURNALDWATCHER_H #define JOURNALDWATCHER_H +#include +#include #include #include @@ -51,6 +53,8 @@ public: static JournaldWatcher *instance(); + static const QByteArray &machineId(); + static bool subscribe(QObject *subscriber, const Subscription &subscription); static void unsubscribe(QObject *subscriber); From 90c9093a49da4b0ed79255333a38312eaaceff63 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 18 Mar 2015 10:09:44 +0100 Subject: [PATCH 51/61] Debugger: Make display encoding of std::string selectable Task-number: QTCREATORBUG-14119 Change-Id: I17434490a1a0a8374ee0c178c45a032af283e7a5 Reviewed-by: Christian Stenger --- share/qtcreator/debugger/dumper.py | 16 +++++++--------- share/qtcreator/debugger/stdtypes.py | 24 ++++++++++++++---------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index fc977fc9389..252f84f9888 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -583,12 +583,15 @@ class DumperBase: elided, shown = self.computeLimit(size, limit) return elided, self.readMemory(data, shown) - def putStdStringHelper(self, data, size, charSize): + def putStdStringHelper(self, data, size, charSize, format = None): bytelen = size * charSize elided, shown = self.computeLimit(bytelen, self.displayStringLimit) mem = self.readMemory(data, shown) if charSize == 1: - encodingType = Hex2EncodedLatin1 + if format == 1 or format == 2: + encodingType = Hex2EncodedLatin1 + else: + encodingType = Hex2EncodedUtf8 displayType = DisplayLatin1String elif charSize == 2: encodingType = Hex4EncodedLittleEndian @@ -600,10 +603,9 @@ class DumperBase: self.putNumChild(0) self.putValue(mem, encodingType, elided=elided) - format = self.currentItemFormat() - if format == 1: + if format == 1 or format == 3: self.putDisplay(StopDisplay) - elif format == 2: + elif format == 2 or format == 4: self.putField("editformat", displayType) elided, shown = self.computeLimit(bytelen, 100000) self.putField("editvalue", self.readMemory(data, shown)) @@ -619,10 +621,6 @@ class DumperBase: def byteArrayData(self, value): return self.byteArrayDataHelper(self.extractPointer(value)) - def putByteArrayValueByAddress(self, addr): - elided, data = self.encodeByteArrayHelper(addr, self.displayStringLimit) - self.putValue(data, Hex2EncodedLatin1, elided=elided) - def putByteArrayValue(self, value): elided, data = self.encodeByteArrayHelper(self.extractPointer(value), self.displayStringLimit) self.putValue(data, Hex2EncodedLatin1, elided=elided) diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py index 5445e20b8e7..88e60f52281 100644 --- a/share/qtcreator/debugger/stdtypes.py +++ b/share/qtcreator/debugger/stdtypes.py @@ -398,14 +398,14 @@ def qdump__std____debug__stack(d, value): qdump__std__stack(d, value) def qform__std__string(): - return "Inline,In Separate Window" + return "Latin1 String,Latin1 String in Separate Window,UTF-8 String,UTF-8 String in Separate Window" def qdump__std__string(d, value): - qdump__std__stringHelper1(d, value, 1) + qdump__std__stringHelper1(d, value, 1, d.currentItemFormat()) -def qdump__std__stringHelper1(d, value, charSize): +def qdump__std__stringHelper1(d, value, charSize, format): if d.isQnxTarget(): - qdump__std__stringHelper1__QNX(d, value, charSize) + qdump__std__stringHelper1__QNX(d, value, charSize, format) return data = value["_M_dataplus"]["_M_p"] @@ -418,9 +418,9 @@ def qdump__std__stringHelper1(d, value, charSize): refcount = int(sizePtr[-1]) & 0xffffffff d.check(refcount >= -1) # Can be -1 accoring to docs. d.check(0 <= size and size <= alloc and alloc <= 100*1000*1000) - d.putStdStringHelper(sizePtr, size, charSize) + d.putStdStringHelper(sizePtr, size, charSize, format) -def qdump__std__stringHelper1__QNX(d, value, charSize): +def qdump__std__stringHelper1__QNX(d, value, charSize, format): size = value['_Mysize'] alloc = value['_Myres'] _BUF_SIZE = 16 / charSize @@ -432,7 +432,7 @@ def qdump__std__stringHelper1__QNX(d, value, charSize): refcount = int(sizePtr[-1]) d.check(refcount >= -1) # Can be -1 accoring to docs. d.check(0 <= size and size <= alloc and alloc <= 100*1000*1000) - d.putStdStringHelper(sizePtr, size, charSize) + d.putStdStringHelper(sizePtr, size, charSize, format) def qdump__std____1__string(d, value): @@ -446,7 +446,7 @@ def qdump__std____1__string(d, value): # Short/internal. size = firstByte / 2 data = base + 1 - d.putStdStringHelper(data, size, 1) + d.putStdStringHelper(data, size, 1, d.currentItemFormat()) d.putType("std::string") @@ -786,13 +786,17 @@ def qedit__string(d, expr, value): def qdump__string(d, value): qdump__std__string(d, value) +def qform__std__wstring(): + return "Inline String,String in Separate Window" + def qdump__std__wstring(d, value): charSize = d.lookupType('wchar_t').sizeof - qdump__std__stringHelper1(d, value, charSize) + # HACK: Shift format by 4 to account for latin1 and utf8 + qdump__std__stringHelper1(d, value, charSize, d.currentItemFormat()) def qdump__std__basic_string(d, value): innerType = d.templateArgument(value.type, 0) - qdump__std__stringHelper1(d, value, innerType.sizeof) + qdump__std__stringHelper1(d, value, innerType.sizeof, d.currentItemFormat()) def qdump__std____1__basic_string(d, value): innerType = str(d.templateArgument(value.type, 0)) From 50ea4ab03f170272fbef0654cd9fe80bdb0527db Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 18 Mar 2015 09:24:51 +0100 Subject: [PATCH 52/61] Debugger: Allow inline UTF-8 display for QByteArray Change-Id: I0db0f605ccfac21127556f4ebaab801cf5393ab9 Reviewed-by: Christian Stenger --- share/qtcreator/debugger/qttypes.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index de17b64283e..cff457ae44c 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -53,19 +53,25 @@ def qdump__QAtomicPointer(d, value): d.putSubItem("_q_value", q.dereference()) def qform__QByteArray(): - return "Inline,As Latin1 in Separate Window,As UTF-8 in Separate Window" + return "Latin1 String,Latin1 String in Separate Window,UTF-8 String,UTF-8 String in Separate Window" def qdump__QByteArray(d, value): - d.putByteArrayValue(value) data, size, alloc = d.byteArrayData(value) d.putNumChild(size) + elided, p = d.encodeByteArrayHelper(d.extractPointer(value), d.displayStringLimit) format = d.currentItemFormat() - if format == 1: + if format == 1 or format is None: d.putDisplay(StopDisplay) + d.putValue(p, Hex2EncodedLatin1, elided=elided) elif format == 2: + d.putValue(p, Hex2EncodedLatin1, elided=elided) d.putField("editformat", DisplayLatin1String) d.putField("editvalue", d.encodeByteArray(value, limit=100000)) elif format == 3: + d.putDisplay(StopDisplay) + d.putValue(p, Hex2EncodedUtf8, elided=elided) + elif format == 4: + d.putValue(p, Hex2EncodedUtf8, elided=elided) d.putField("editformat", DisplayUtf8String) d.putField("editvalue", d.encodeByteArray(value, limit=100000)) if d.isExpanded(): From 1b60a88dd54acf376d1506c34673e262560d3eb4 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 18 Mar 2015 14:26:59 +0100 Subject: [PATCH 53/61] Doc: new Valgrind Memory Analyzer with GDB option Update screenshot. Change-Id: Ib2591d1d2c594d098d2265cd7cbc18f05f12d5ca Reviewed-by: hjk --- doc/images/qtcreator-analyze-menu.png | Bin 12118 -> 9707 bytes doc/src/analyze/creator-valgrind.qdoc | 11 +++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/images/qtcreator-analyze-menu.png b/doc/images/qtcreator-analyze-menu.png index 71ceb4e8cddd483bb3e37a549acaa00eb77269d7..f497fd09ed7a0f1e467c2ef0eeb724205f6086fe 100644 GIT binary patch literal 9707 zcmeAS@N?(olHy`uVBq!ia0y~yU_8jcz|hLU%)r1Pa(lA~0|PTdfKQ0)|NsC0{Q2|s z>({@3|2}x|;Q90CT4~>B&z}9@<==w`51zRC^V+p*EG#T%&YXGs_U-@w{~{W`T)A>Z zEd1TBUAun#{2ATyLqGHTq{)-ty?^KJ?H$_i!zAasRsMH}qVKMy-#sgTOr1K_zxKz0 z0|$Qp{;jR8m7Sga>;M16j-QDgKVH0i+1S{akeE`Kc+bp>b-|h;8QZQs(J!5SWo@T#amUF=zplLc z-gDsYlD43C+2o&yKG4j>%kK z9*n>hPbI z<{wjf+7ncSf{p!zt-N2p`WF~bt5N;4Ve-O{Ki)cKecy5R=r$RBZe9_k1HvLH6OP5F z{rdk-Zi<>*tb*yxqZ>Q}5?fz8KJWGSM`|6MV3=B%kJY5_^DsH`*mFp86 zE^&N*kzsG~o4x~0f8D~Ojxue%vhBN=MrY3f$r(^tT)5$q$)qHPrkMgBhOpp2@dhVzF^Lf>Z zKMVDqizz&r%31vSWv1G}wc&Yt4{a1EWXXFF$XI*JrL$+t&76adaSjC=7C%4m zr%zz>o2s+eqok)W{1abG&!Zjd^M8c8oy=HtqK+*;b8S2SY@aNhIa_AjD)ed5%wc(R zeBpi3g9og5?(Hs2e)e(Z!H8SB)2`p!S@}kyPM~?sX@wG_%^CCl{8<}o_v~D1hQLD2 z@b0RkhEJ{6g@>)ziF9G^byj&I*7cVC;)A2h+r=&yIcP{du~@nzMKVA|;YPA^Bm3P* z`Kt?-$eVu+@2-<0IO2InmLzzSE-h&Ao39<_u zx47>J^2>5Gkzx^%IF&I=v(P6=&~VYI80lii_z6p2&E5WGvQ9+kzvh(YDedmkNsia= z>7Kr&eA!$_;o;-EkM1n}wP|~1%%tdV&vKeu<}K*iarC6x-{q#C9!)yf77_b?U76d# zDX*%&7Rq1P``3Q%w9k7O6;EqT_3C8e&H8Q1vNcv*s^pPG*5rh;zoL=DIz;kJHqdV*AKa8@bb$-)S3?nLSFMFha%ROzPW-4{o`~0y- z`rCpnSzA98I-bqm8LIy#zF*PozQpB-u&439AD^tY^Ry2Un>{OW@5CL}H`njl>k<_c zl=wrz^s(>e_xs+N>qT8p73=)|b?&-veZN;s2>t!@{HLdzc~-v&&pr|7+_*2wS8VOE z&Rt8Va-8h2s0Lipa=;%iLs9jMI;HuV1$K`}Q@aYj>~(F49SExOX{_tKdY{N%JXwHx-{%vO9$-2!9MzFkEp# zsKcq-rCMHN)Xt2|4X?-m}EH7Gb`b@FZ4?armmJbYi;C2AP07N<5nKH&UfswAtU zZv2tO2m9u^Wm`%8xwOLgs&-LN(v&NgiVsfsS{3Vjb$8*iv*|^zrNo|!zw~jo-M?np zlcUbv4Ewf(?b#I^*`HgR@53IJBmu?Uj-4Jx zY%XgK3Ep)mk105wYH;i7F5z5rj?cLZw|q8~eOTBpz+kb!sP@{Wz%FYKqqb!yEf~GM z_-qV2pST>qY2vqGzApQ&8?*YRD}9jRJ@4(%e5Yta#uPpkp>^{ax(XedFY-Uio7f}N zyrNAmzuIx8b#ACefzb?pkG(0+ALSX$3SJRne5(CZ{+uMIW?{$m*V`8yY*(EBr+CMm zXt@Xf4=Nn$JD@SsFmTfK6^)#VjLs)mB4@Bq4rablaW*<-vS9{C<(vivIWAqE9KN}R z#f&~(zULE!HCi;eZ7-W|x#{k4@Nps&TV~vX^KUMEcrI_S}z38T$PqZLTcPy1a`eXnpPElBL$%dUkVlOQlQ>9W8#%H>3a9 z?;e|s16&g6#3 zrHXYXTWhBOSlZkD^4pvH!q=UI4Sxh3e|fLi`xAHA;gG}0ypv3CM5Wn9OxCzja4FSb z|C=DwJv+>0XKhM;So5v)+=HKI-`wk;_EdWLEv_#S&0kjT3%Yu8LSu{W`={mme~L-% zk&%ka-QUgh;J)mG!+mR7bhVQ#n&qX~5+;}2Qg|fE=6LtE9T z;q2Ueh7gq|JzvsQrt)F4WA(teeQ1I>Kr(Z!5 z(hJY82zqLKwQS+MJb{Zp!w;MI_c+SWNDDgiMWmU1-mJ7BmWqypGwbcF&n~feWytpY z%+ndh<>#(hp18KN*kIphWig2p-93tZkB)zze|XPVYonLea~{oVE0`Sfxp39zUo1sW z3!fJke7?Khzp6>QU@5oG&JPyP&i|b~Yg2fkXvd?92Zxk0zlp7GeatSjW47K=JBO%) z@5I`ccuiC{FzDa#)PZYeQhb73(yfh>-IBU2NByKZpNPIY$$m4ZH2Sl0;Q2E@<-6q{ zSMbcbe?vuVS!esbw)8!s_oa_sxZiyz!EDWuv-#5POMlicS#&YE_xhEZx?{-(o8G(p zyl>Q1X3D=v%}W354EY~NKTZAB z?)mcZ-irlueA<^uzq&U4@KT>iwx0_xu{X{?)|R!`+s4{I@3X1ziuUYGhpW#!FaGhH z%$w4jo@B%Jmwk^-+RF<V^4zlf^2GPM+okkxaz47dsr{rk8(Vp5NQTqXp#AH!xb#~Kp4f{n zHk?t}ZxMfXSxMn^9SMmksbznXA_}KS#k>lZ`fmMpk!`W9x#eeYAUxR|f79_^{JBPO>OKs(RBozNdlbcJa>9jLSV*c=Xebmm&S>#VuW&)|P#{ zv;1C2m<7#M;G1lJ>SxrR6ZXBKKCjk2JQ{udV8lBc$;E~*7S4ZgZDWxa=h=d^(3YH5 z@0gH>!S@z*rReWaZi#-e=Mk%zj@6RIca+yP8@K$lyse}m=oR|ADdG0^39Zqeh1Tay zKA4dIl;uPm$5NSP3)PcN*#3Kl@rZ8N$Y>}sNAuaE9i==POd?F48yF2|w5)WVkPs`t zA}CxfT=&!Vj6;V8ha+P^kkqNhQ=Pn~1{p~KZM^0a*wXYZ&5RDt-nV;)YU;0V8+Z#1 zGLk;bzo4PO%`;6RBCDsL8~s@0&9E`{o4BHi(zaKJZ*JQh>g&tn_o&V^8OvlMmmMsh=xq64sma%P5$>3q~k9;xT`02y#)0`H+2v+s` zsBb-2eWIM2vJ%_eN5Q>kli&Y7lOK`E({-@JGW=buX?j?EX57lKdm(oNc+Ld8IW*O9 zfyLL`vgh_Ur0X|d_FYg=oaW{{+247sltI2(1;fs(ud@zIFlD`U6cl?qXVrOzi}!d; zBG0OBnJcbQsbBoh$}g_^v$Mj-sgew`+u2u|uh&b{Sbs9()5p^NkEWflRrlvjaSGC! zko2v;Kk-Ap<>w`O-Y7|sygTm10Tlr8V>wBPJJ zu=Hzpt?=8;YHwm*@SJOwj#2-4y!^bWeyq*uy%xH+_FmTBa#>qzQPJ~5PZq6t5mR`0 zFVAzorlQYJjvQXTNTNaebG7i>&1=&eee&MVIvo&j@Fi!$^FL0rx*l27{c`7b-1{To zd@pxU;pwT`HzwUR>ouHRe%gMvsk36q??)U6}`=W%^weo!5?^}w0d-$*H-FLZt@iVKIelM(E7Na5g z;*8U#FM$oN7Z=-=pESR`Cty>+?@gR;GuBR57EtR5`n!$o?eid0@xQD7@i%Sy!mpdA z^f*m%v0&=0U28Nqxo$OB@NgNEV{l>C&Z3N&AuX$4ytRIo?!Co5BwhY>=xZjai%FZ$ zq;f{CKUEZeP;b_@btWa7T*FtVKMUwS$)^3yIIqtz%XQhSwOeP+Qw*>_z9`{M@)=PM ziKN$S%dQpLst5bso_OAu<8PLumEM8(3)ji7^6U|)Il1zEhwziSaE3f^L?7n2^} z-{0`xvwFss$7fiU*b5#ivXqk)7GXUlW*yLfq}gT8ft@SgT*;2)NRcUcdwzXsQKtE# zyD=6TCyuiOS6d4_-Ms#R^mqR-2hp#3%NN97t#`U`z~@BjPC41dVyR-H-=_U+n#JMB z#NoI7mJ=VZx4~k=6-%sBmqsm`bcDsYalz6JTMq}MUtF51eD4Ckb*I47QZ+Rx%kaFJ z3#(oA1h#7^6u0dwX*MX>lFObND&N^N<*H}*m)kBEOD;4$kX&+BMTW<|d6U*;-wEdX zCfV=G?~zX~~cqjeEX`u^JELtz8b*P>Vndfq*-Y@8` z%*Q6JIM?mU5`jz`)fpd}AJ$*kxXAZ!nec3PtDWi2@h>`ED}6O@_n&EAUx zxm#Yp_*K0{RxKbz^AzX0RZIT<_<6ssd|GYjV%bnm_2lS{jsmi|$`{{vm5aPxV{16S zNl=;PahLF)bkU_O!hXdI|IAer(0E*G+SSn{Jn`*y@xt3>1{-JX&V6a?nKN(77TK16 z*^}(FwEZkf%$I%EUo>Sw;wlMqFBT!)cMoz-NBFyyzq=u+zBBd8k*p=s(-!xhTIp+N zG+*@Q(~Dm{=f9aCCY^fubbX_OL{h@(8J)WK)s}qkIPqpS=33*w3iqAA?2(k|-&-ZMmSz60*+J{$Qy0J4xY{hzfbG7TL@sODHvN*e zQ&Ts8Wo_kA(ETj{G`?%>%C8 z{k7y&)PnV&uPoUuy7Y5(`x%FTfLCTe-b>4V7ACuwkTqhRn z-F)|V?S5S!gE{%<+wKMLldO0&FC=n8QXsGA%UveZ7F7Ib^_|9VcdJEaYeaaA*p;L< zJxiaz6Fqml(dx2w)poq{K4b5Bx0{<;)?Q`%zbs$)w2Nonk}f94%y%+d8k|F}_wWW- z3v98Srjf$AX{`u{RP^SH6CxQ{@)Mi7tbU&r<}7TozioYc#?HfqI`O-339E!(mgH8ZUj?Afx^L6LPCi$<5oM2-BU z6h_W7;zCzke8p5}Nrc!noPM-P=d{rNx0c&aFqBSv$aej!{MxrW&s%QaYkz*{^Lxef zpI5GAIoiE{wWW~EskqMY3j3Uvt(<>9-8yphO5>Z46ZJis!VN_|&mX_7{xMki>suDS zs`%o6Uo`H_(#xp`3183_@!iJOGr<4WGUlU4SQ`b?j2tGcxg@Z0zmCI)r9vtnLZu{6 z$pz^seth?^J#0qwqn#Q18g=)bTw1MMr@Ef~p{-LwWpVjd9v$!1g8%)FtT=SdGK=~5 z!wxUSRdbVnJzM%jTRvR4+)YYAFpQ@-aK)iEt*J+sS&A*1w@v3@sMUvyGnRNXGA+_^ ztjoOatM#ov{q=tjg9Qu+!^0VyLc$vqu8Jynl;+Ad<*sM{!vCc%q(Ncp)>aNSx4>2X zix`_2oBsQ=asizd^eo;>}#Q)B(}vU zPOE*=e6V{T&&T#mKQVzRt1k&&-RcT5MfUHR+9k6K+OAco>%FPYSn>bm#Dbgd|L(Z> zFOJi#e_ni$RiWdYja$g|X{tLK-<1COl`r^y`%h=Ls>G5nf(_?<6l$M*4~@L|^;%MD zjZvU<)_*bKJ$2lHvC-2Wux+}Y*z`oBOGqp_*t6;4=Oz6%;>y8MlPagliFTY2PoHo9%CB0&cRarBx_)cMzZoBsSG?Kc!rH{h%JGk11Qb1iO|L&K zPIpu;JVaYn#*IVoU3NQ-)KNcDltFSsX zaLR+KKQGE{9Zr}$I=`k!AvH8cBje^To8Z{M(){zs=l^<>y7BzXk2R(8jpx40ys9j7 z{xU&oi_Ra_>wow+$xpjp8Fqm?P$9McBNun!_KCi}O|L&JeqMWVm0PQT;F^mmijS1z5@^t3Hp&a*Cv?U(oE+t*tzPEM7Z_BL$& zjqFK+Cr^cc-F3)?)s%DH;r@BgEqg*|Kdl< zoi4wx+@A3lts+(*x+=e6?{1bnSEo~Fg|vfqwLiQ6_k&c-*W>mHauV+~7^35xrOLj# zo|?i_vTjjzb#rK#l7>)Gnsv~rbY-1p_Rh$I3qEol%)dBOXIhCEkIx?pGi36GwCQk~vbAhAk>nHFAWuc<*NYoVx3+@Y`iv zidQUhQ{;c_aS1s%$t*Qs%7XuOUw#X{&YR8GEAud-FKhLhgknSM>>E=9E3UqLd-_7! z^Gu`90s8NhT!Q9ZV$Higf2;G?Kd*xIR@)rCF#EJkn80GqvwnY$*2PyZn)&?2dbZoU zx8De=zWChuNbjn1ZO?Ysp4%ZEY51*LX7{~>&GA34*3H%ky>lW-SJ340Hy@!TjYhlc zZ!G*DTI#5`EBy8h^=UG^_H0kT-~7?NO)dSI;nQx{#7T9B*8ShQ-7%s*A}{mVTwAHt z8_)io6p|RVrs8o(--nv3Cl9TjSKD{zkQRTSy=NdOs^9NlGXLyb+eJtBeYoK^uSxmH zIX(9dS&2EDQzkfWI?LV1WY)s>EOhCtdv;GwFnH&`zT?5hliqo#6umNcJr zNwdm(p4Vq(Jh!3fhIZViH;Y%Ut9l~FKPzv=NgJNOcN~QNsI_-b$oZ!1*t%vP>)cbF znwDJ_zT#|W?z9M>eX;tui0TeL`(HZ2-}2AisQtG>t<2Kt&6$l%dOCrQ3@i>Cx%ra| z?r80_b5=K37AhT9AO1@+wD9qE&qW;`!wrCssn3MKyi z_ttc-edyuQf4mq%h-w z)a$M@^H@?gJUhhDw5!c%(u1$pQe5U=J3lp~z^I?$pp=C8l67Ainbv)BF%G=%6x#If z_r-KWuV0a0-`2e0t{1R*npk(JGUH0r9o6O^$|V{v+&KDddfbby?#<^~P!*ZRza^(> z<{9(b?+-dNbaMA!IqvVGQ!y>+kJjVhrQeSHO}19qzO{S1Z}+>bxd}OmZOVp+Uh;6n zT}$h~`J3knli@qHa#^=|2lg5?bB0y^n8dwl*Ado>DifFJe|P$+Auag)tWHFAUT^Fb z{W%#AZ$~T7*8115bH%Dix%Kf9x_>h37w=nBF1LL_xBTmKf_yWsIv6DG>siI}_uJz3 zNeX6npWDT2vPehnY?`6fwrlE9yW>9_J5x4HetYcN(zY6A;Z@Je^|sdh%`!47Exoj_ zJ%@GT4!hISBMzOFeYYgkukm%kKi_53zp0(-Un1ENr1(Ra`{hsd&h9Ncz12UTJj}iR z$lRhEif0*&J^xK%O1Iij>Sl5Cgv;*E(+_3;$Qi8tyD#jk#-)=}QlFI_lJn;OwEW7A z<@Ysrhge>ps`YM8qu2!TeH=zpjZ<%z$*oTan)=}M=f%_eo@|=G-_Usa&oiGcnqSzj z^fQisGSUrygLQ(5vt^zZ2}i>J48{?AM1{pEj@|LG$;xnIY$>%w&xFdY2ftKneK zA^2s^EFQI63vxCb^S(bN{hQ*Yf7-qUu{U35ObqzJGjm_O_0Pu0_@}2nv|gT8-ahBc zP31RN!!~c7J8{R^{lZt0lvH+0a2k8>7ka+dQc`<8=h4Morf$x6rix9E6j9qT?@j5& z$G_!mzD9R;w=GZp^XNv~s%!hBnwRK4ysmx2b9MTgBfT+k-->2G3N)=+R-h|0f9<S@5oL)D!t!#QE1caeJ$DA%Z%roOL_7)F;#R&!%_ps|C_J>Op-qJ?1Sr!Hz^*= zC%1Cw=WYp`^kPe91joAH5hs>?bmA4*m;AU%wOw)Rn$<#jA6ecll)Y+kY`y;H*cWq) zYH}Xi?$Jt!k3QEjAzL7Neb0gD)F=0{6?^CA%qW}uR9Qpb@KAValcVIM)@xx>OXix- z^ti<;&;Cnp>cxe3+?~JP6xBPowEeB$wM(aNIs}wWYRyu-wEYd=*#lQnw~ODtm$Wb_ zV|HA0@ArrbtKMBK*C+1n6VK&%*u?8@q?woX!{V056rUO+vpKcDI?N4!CLNAQo))`w8mbc>u3nz}Z$Z$a^~FoC>|CSvd+WP{=F4Rt zvu&F5$I^28uQeXxyeq%jcwKyOTUfk7;m^laUH1&1)CXOfVE0x->+;)Bf9_*CdDk{} z`p-TSlbUSY%K2;l-oEDooIU$EHWpnCOtY1YH}RO(qI_hU>fJPL{|N5q!Ik?sHm zbo${pv1#kBHt&lPjsM~|KXCbRvlnavXXeS9Tv{%>p^LRV?CGkmhjxpV26UQhqPHZk+f zrP68qv2XoHCsjn9FnH$DdLUh&_t)YUfN zfYK}Z`AYJ#>YVT1oOSKc*z%=g8VB2IKINrHtKJyx@t=G>aMptVH(z@+@u%z68ouoQ zcsf(7gR^e$^|MUBAG?~iu4SLj`ABTS4nx^YSGU&)1#g!K& z6&1Ig`Ixs^peUe7>T`ry$LBYVEqk0^G{^t_*RArM({XXcB=*=I)yHx-UQfIp`A{<{ zHhyzZ({7bWx#Mm}HqN;rk^8N+HZ)!<_NCX2^2^DS7X11X>g=)R@3fO&buA7tnkLpB z)PJrht0{12YT2rb&Z$lR(${-4YW;btrPWhQ7d`tU zcyK|eC7 zjpIAa!^QWy2OJEUmmwmuRP_t@!~QklCAT79c&)iCE}vgebw5noouzutm*VY$d+f`) zJ;6?|{w3UK?_&5*OR;@uw{Fnu@cH`|8N(z~WBKO9te_3}t%&jQn@%xSF5 z@$P#LMkGo-{mhu4%vSrAKk(ayF4Nne!24B7L&gB&Fb;ivnmp;oNVv!39h-A;pBXu>x6%6Tb9YeMCXHw4hC7q zoNTU!_u5acNXt5YAs}2_SE2su)vKmkl4rB|H5c}*xc;K!ikg6ngTQ=_X4CxER^Qy) zdzBUbZ>he0CFDl*tOpSmym>~BHA*dhFPts5>MHza`E%$V*VQA(T8=-w{9u_-i=Tve zpWq=+1098W)^w*AjfxL0$q$oi>5K=@i|%uJL%uy znLhbD=+~r2-;rvV?ILh2a8hDS^liU@ r3I}}=nPuC|9(=dr{BU3ShkEPkw=>*&<6IdS7#KWV{an^LB{Ts5`9=As literal 12118 zcmeAS@N?(olHy`uVBq!ia0y~yVEn?sz|hRW%)r3l6Cqj3z`)E9;1lBd|NsBL|Ni~` z^XLEHKRM}Qf!O9TjYPw%E~S;FHcKL4-F0Vsrk{^*d!t%;#~4QCnvY0q~!PS z-+Fp_BC%hSl9DnqGT*;{FDfcpR9Kjom-qGSSEH=&?iJsgn_K40o%8qi_bF4RynOYl zzrTO_^y$97eo2W5j~+ex_WEu?LBXVn6WiL_et&)U`^RTTM+a9o*K_C33keDR`0zp^ z_Uq1$R1Z(D8{hx+CirxBcYk<%^~L8;-~aym^y}B#fB#oM`E}>Rm++YU#J2f|7WWut z|9E%r)RSvx9)16p84`5<=oj#wi( z4xd}xvj6V8ozp7!z5aRX+0V1{_CCz5@3VK$yLIQ@^1A#~fA_W5 zp7-v(wBqQKr;jdQ*|qfPwrK(RO%toLno?uu?K)kWmGa}|m5D3&PtS|$j5N7@Vr%i# z9}g}Zw2RET_w3D!(;ICIIu_I=7+U)rxcK+N)3?{JU$0$seD}V6lj>_*3-UT={+PP+ z(aBkrmEO*8p8ScO{yV7hK-=7n8#k;^% Ry}w7*{oBK=B(MUen#(_p881dxP3Jt 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 \uicontrol {Valgrind Memory Analyzer}. + \li Select \uicontrol Analyze > \uicontrol {Valgrind Memory Analyzer}, + or \uicontrol {Valgrind Memory Analyzer with GDB} if you want to + debug the found problems. \li Select the \inlineimage qtcreator-analyze-start-button.png "Start button" From ec9f3ee79e5bd2bb96094194c8a5594df3d78e47 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 18 Mar 2015 15:28:44 +0100 Subject: [PATCH 54/61] Doc: new "Stash Unstaged Files" Git function Change-Id: Ia828f07279cde4d57b2550937a94f13edfe996b2 Reviewed-by: Orgad Shaneh --- doc/src/howto/creator-vcs.qdoc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/src/howto/creator-vcs.qdoc b/doc/src/howto/creator-vcs.qdoc index 5c9842e0ee1..6c050c52a4d 100644 --- a/doc/src/howto/creator-vcs.qdoc +++ b/doc/src/howto/creator-vcs.qdoc @@ -524,7 +524,9 @@ To stash all local changes, select \uicontrol Tools > \uicontrol Git > \uicontrol {Local Repository} > \uicontrol Stash > \uicontrol Stash. The working copy is reset - to the state it had after the last commit. + to the state it had after the last commit. To save the current state of your + unstaged files and reset the repository to its staged state, select + \uicontrol {Stash Unstaged Files}. To display a dialog that shows all known stashes with options to restore, display or delete them, select \uicontrol Stashes. From 4514dbfd8c18db8482ea449635ddb16d72325b5a Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Wed, 18 Mar 2015 16:04:10 +0100 Subject: [PATCH 55/61] ImageViewer: Add up-to-date mimetypes (and add webp mimetype) The list of mimetypes was missing new types like tga, dds and webp. Just ask QImageReader::supportedMimeTypes() for the supported types, which is also easier to maintain. Task-number: QTBUG-45061 Change-Id: I80573da868088915b8d746c56374786e5e36903c Reviewed-by: hjk Reviewed-by: Eike Ziller --- .../imageviewer/ImageViewer.mimetypes.xml | 9 ++++++ src/plugins/imageviewer/imageviewer.qrc | 1 + .../imageviewer/imageviewerfactory.cpp | 29 +++++-------------- src/plugins/imageviewer/imageviewerplugin.cpp | 3 ++ 4 files changed, 20 insertions(+), 22 deletions(-) create mode 100644 src/plugins/imageviewer/ImageViewer.mimetypes.xml diff --git a/src/plugins/imageviewer/ImageViewer.mimetypes.xml b/src/plugins/imageviewer/ImageViewer.mimetypes.xml new file mode 100644 index 00000000000..499b38acb49 --- /dev/null +++ b/src/plugins/imageviewer/ImageViewer.mimetypes.xml @@ -0,0 +1,9 @@ + + + + + WebP Image file + + + + diff --git a/src/plugins/imageviewer/imageviewer.qrc b/src/plugins/imageviewer/imageviewer.qrc index 94f8b076316..662722baf7a 100644 --- a/src/plugins/imageviewer/imageviewer.qrc +++ b/src/plugins/imageviewer/imageviewer.qrc @@ -8,5 +8,6 @@ images/background.png images/pause-small.png images/play-small.png + ImageViewer.mimetypes.xml diff --git a/src/plugins/imageviewer/imageviewerfactory.cpp b/src/plugins/imageviewer/imageviewerfactory.cpp index 1746cb3ac9f..06009c49b36 100644 --- a/src/plugins/imageviewer/imageviewerfactory.cpp +++ b/src/plugins/imageviewer/imageviewerfactory.cpp @@ -47,29 +47,14 @@ ImageViewerFactory::ImageViewerFactory(QObject *parent) : setId(Constants::IMAGEVIEWER_ID); setDisplayName(qApp->translate("OpenWith::Editors", Constants::IMAGEVIEWER_DISPLAY_NAME)); - QMap possibleMimeTypes; - possibleMimeTypes.insert("bmp", "image/bmp"); - possibleMimeTypes.insert("gif", "image/gif"); - possibleMimeTypes.insert("ico", "image/x-icon"); - possibleMimeTypes.insert("jpeg","image/jpeg"); - possibleMimeTypes.insert("jpg", "image/jpeg"); - possibleMimeTypes.insert("mng", "video/x-mng"); - possibleMimeTypes.insert("pbm", "image/x-portable-bitmap"); - possibleMimeTypes.insert("pgm", "image/x-portable-graymap"); - possibleMimeTypes.insert("png", "image/png"); - possibleMimeTypes.insert("ppm", "image/x-portable-pixmap"); - possibleMimeTypes.insert("svg", "image/svg+xml"); - possibleMimeTypes.insert("tif", "image/tiff"); - possibleMimeTypes.insert("tiff","image/tiff"); - possibleMimeTypes.insert("xbm", "image/xbm"); - possibleMimeTypes.insert("xpm", "image/xpm"); + const QList supportedMimeTypes = QImageReader::supportedMimeTypes(); + foreach (const QByteArray &format, supportedMimeTypes) + addMimeType(format.constData()); - QList supportedFormats = QImageReader::supportedImageFormats(); - foreach (const QByteArray &format, supportedFormats) { - const char *value = possibleMimeTypes.value(format); - if (value) - addMimeType(value); - } +#if (QT_VERSION < QT_VERSION_CHECK(5, 5, 0)) && !QT_NO_SVGRENDERER + // Workaround for https://codereview.qt-project.org/108693 + addMimeType("image/svg+xml"); +#endif } Core::IEditor *ImageViewerFactory::createEditor() diff --git a/src/plugins/imageviewer/imageviewerplugin.cpp b/src/plugins/imageviewer/imageviewerplugin.cpp index 20a1cfcf43c..dc72bd05537 100644 --- a/src/plugins/imageviewer/imageviewerplugin.cpp +++ b/src/plugins/imageviewer/imageviewerplugin.cpp @@ -38,6 +38,7 @@ #include #include #include +#include namespace ImageViewer { namespace Internal { @@ -49,6 +50,8 @@ bool ImageViewerPlugin::initialize(const QStringList &arguments, QString *errorM Q_UNUSED(arguments) Q_UNUSED(errorMessage) + Utils::MimeDatabase::addMimeTypes(QLatin1String(":/imageviewer/ImageViewer.mimetypes.xml")); + m_factory = new ImageViewerFactory(this); addAutoReleasedObject(m_factory); return true; From 13d425b972cfa25a9f87e326cec22028a4bf0f42 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 18 Mar 2015 13:28:45 +0100 Subject: [PATCH 56/61] Debugger: Re-enable watchers after ending a debugger run In that state one should be able to remove them. Change-Id: I9c1383decb087971cdc01607c32801f6ac22f99d Reviewed-by: Christian Stenger --- src/plugins/debugger/debuggerplugin.cpp | 2 + src/plugins/debugger/watchhandler.cpp | 77 +++++++++---------------- src/plugins/debugger/watchhandler.h | 1 + 3 files changed, 31 insertions(+), 49 deletions(-) diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 67961981538..aff64de8f8d 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -1820,6 +1820,8 @@ void DebuggerPluginPrivate::connectEngine(DebuggerEngine *engine) m_watchersView->setModel(engine->watchModel()); m_inspectorView->setModel(engine->watchModel()); + engine->watchHandler()->resetWatchers(); + mainWindow()->setEngineDebugLanguages(engine->startParameters().languages); } diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index abb86fc645f..cb9dcf77a02 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -863,22 +863,7 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role case Qt::EditRole: switch (idx.column()) { case 0: { - QByteArray exp = value.toByteArray(); - if (!exp.isEmpty()) { - theWatcherNames.remove(item->d.exp); - item->d.exp = exp; - item->d.name = QString::fromLatin1(exp); - theWatcherNames[exp] = theWatcherCount++; - m_handler->saveWatchers(); - if (engine()->state() == DebuggerNotReady) { - item->d.setAllUnneeded(); - item->d.setValue(QString(QLatin1Char(' '))); - item->d.setHasChildren(false); - } else { - engine()->updateWatchData(item->d); - } - } - m_handler->updateWatchersWindow(); + m_handler->watchExpression(value.toString()); break; } case 1: // Change value @@ -922,8 +907,9 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role Qt::ItemFlags WatchItem::flags(int column) const { QTC_ASSERT(model(), return Qt::ItemFlags()); - if (!watchModel()->contentIsValid() && !d.isInspect()) - return Qt::ItemFlags(); + DebuggerEngine *engine = watchModel()->engine(); + QTC_ASSERT(engine, return Qt::ItemFlags()); + const DebuggerState state = engine->state(); // Enabled, editable, selectable, checkable, and can be used both as the // source of a drag and drop operation and as a drop target. @@ -931,14 +917,12 @@ Qt::ItemFlags WatchItem::flags(int column) const const Qt::ItemFlags notEditable = Qt::ItemIsSelectable | Qt::ItemIsEnabled; const Qt::ItemFlags editable = notEditable | Qt::ItemIsEditable; - // Disable editing if debuggee is positively running except for Inspector data - DebuggerEngine *engine = watchModel()->engine(); - const bool isRunning = engine && engine->state() == InferiorRunOk; - if (isRunning && engine && !engine->hasCapability(AddWatcherWhileRunningCapability) && - !d.isInspect()) - return notEditable; - if (d.isWatcher()) { + if (state != InferiorStopOk + && state != DebuggerNotReady + && state != DebuggerFinished + && !engine->hasCapability(AddWatcherWhileRunningCapability)) + return Qt::ItemFlags(); if (column == 0 && d.iname.count('.') == 1) return editable; // Watcher names are editable. @@ -950,6 +934,8 @@ Qt::ItemFlags WatchItem::flags(int column) const return editable; // Watcher values are sometimes editable. } } else if (d.isLocal()) { + if (state != InferiorStopOk && !engine->hasCapability(AddWatcherWhileRunningCapability)) + return Qt::ItemFlags(); if (column == 1 && d.valueEditable) return editable; // Locals values are sometimes editable. } else if (d.isInspect()) { @@ -1182,6 +1168,7 @@ void WatchHandler::cleanup() { m_model->m_expandedINames.clear(); theWatcherNames.remove(QByteArray()); + saveWatchers(); m_model->reinitialize(); emit m_model->updateFinished(); m_separatedView->hide(); @@ -1250,16 +1237,12 @@ void WatchModel::reexpandItems() void WatchHandler::insertData(const WatchData &data) { m_model->insertDataItem(data); - m_contentsValid = true; - updateWatchersWindow(); } void WatchHandler::insertDataList(const QList &list) { for (int i = 0, n = list.size(); i != n; ++i) m_model->insertDataItem(list.at(i)); - m_contentsValid = true; - updateWatchersWindow(); } void WatchHandler::removeAllData(bool includeInspectData) @@ -1278,13 +1261,22 @@ void WatchHandler::resetValueCache() }); } +void WatchHandler::resetWatchers() +{ + loadSessionData(); +} + void WatchHandler::notifyUpdateStarted() { m_model->m_requestUpdateTimer.start(80); + m_contentsValid = false; + updateWatchersWindow(); } void WatchHandler::notifyUpdateFinished() { + m_contentsValid = true; + updateWatchersWindow(); m_model->m_requestUpdateTimer.stop(); emit m_model->updateFinished(); } @@ -1323,25 +1315,19 @@ QByteArray WatchHandler::watcherName(const QByteArray &exp) void WatchHandler::watchExpression(const QString &exp0, const QString &name) { - QString exp = exp0; - - QTC_ASSERT(m_engine, return); // Do not insert the same entry more then once. - if (theWatcherNames.value(exp.toLatin1())) + QByteArray exp = exp0.toLatin1(); + if (exp.isEmpty() || theWatcherNames.contains(exp)) return; - // FIXME: 'exp' can contain illegal characters - exp.replace(QLatin1Char('#'), QString()); + theWatcherNames[exp] = theWatcherCount++; WatchData data; - data.exp = exp.toLatin1(); - data.name = name.isEmpty() ? exp : name; - theWatcherNames[data.exp] = theWatcherCount++; + data.exp = exp; + data.name = name.isEmpty() ? exp0 : name; + data.iname = watcherName(exp); saveWatchers(); - if (exp.isEmpty()) - data.setAllUnneeded(); - data.iname = watcherName(data.exp); if (m_engine->state() == DebuggerNotReady) { data.setAllUnneeded(); data.setValue(QString(QLatin1Char(' '))); @@ -1471,14 +1457,8 @@ void WatchHandler::updateWatchersWindow() emit m_model->columnAdjustmentRequested(); // Force show/hide of watchers and return view. - static int previousShowWatch = -1; - static int previousShowReturn = -1; - int showWatch = !m_model->m_watchRoot->children().isEmpty(); + int showWatch = !theWatcherNames.isEmpty(); int showReturn = !m_model->m_returnRoot->children().isEmpty(); - if (showWatch == previousShowWatch && showReturn == previousShowReturn) - return; - previousShowWatch = showWatch; - previousShowReturn = showReturn; Internal::updateWatchersWindow(showWatch, showReturn); } @@ -1764,7 +1744,6 @@ void WatchHandler::editTypeFormats(bool includeLocals, const QByteArray &iname) void WatchHandler::scheduleResetLocation() { m_contentsValid = false; - //m_contentsValid = true; // FIXME m_resetLocationScheduled = true; } diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index 1faaabb542d..e99e449319d 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -244,6 +244,7 @@ public: void removeItemByIName(const QByteArray &iname); void removeAllData(bool includeInspectData = false); void resetValueCache(); + void resetWatchers(); void notifyUpdateStarted(); void notifyUpdateFinished(); void purgeOutdatedItems(const QSet &inames); From e8f8aaa263b778adee2a3568bff9b7d1cc8e4d05 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 18 Mar 2015 16:48:57 +0100 Subject: [PATCH 57/61] Debugger: Fix dumper format choosing with GDB ... and further unify GDB and LLDB code paths. Change-Id: Id89f3804c53190c4888082891fd3c3c55eceac84 Reviewed-by: Christian Stenger --- share/qtcreator/debugger/dumper.py | 23 +++++++++++------------ share/qtcreator/debugger/gdbbridge.py | 6 ++++++ share/qtcreator/debugger/lldbbridge.py | 10 ++++++---- src/plugins/debugger/gdb/gdbengine.cpp | 4 ++-- src/plugins/debugger/lldb/lldbengine.cpp | 8 +++++++- src/plugins/debugger/lldb/lldbengine.h | 1 + tests/auto/debugger/tst_dumpers.cpp | 2 +- 7 files changed, 34 insertions(+), 20 deletions(-) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 252f84f9888..6fa45a43c74 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -1706,7 +1706,7 @@ class DumperBase: except: pass - def setupDumper(self, _ = {}): + def setupDumpers(self, _ = {}): self.qqDumpers = {} self.qqFormats = {} self.qqEditable = {} @@ -1719,27 +1719,26 @@ class DumperBase: item = dic[name] self.registerDumper(name, item) - return self.reportDumpers() - - def reportDumpers(self, _ = {}): - result = "dumpers=[" + msg = "dumpers=[" for key, value in self.qqFormats.items(): if key in self.qqEditable: - result += '{type="%s",formats="%s",editable="true"},' % (key, value) + msg += '{type="%s",formats="%s",editable="true"},' % (key, value) else: - result += '{type="%s",formats="%s"},' % (key, value) - result += ']' - return result + msg += '{type="%s",formats="%s"},' % (key, value) + msg += ']' + self.reportDumpers(msg) - def reloadDumper(self, args): + def reportDumpers(self, msg): + raise NotImplementedError # Pure + + def reloadDumpers(self, args): for mod in self.dumpermodules: m = sys.modules[mod] if sys.version_info[0] >= 3: importlib.reload(m) else: reload(m) - - self.setupDumper(args) + self.setupDumpers(args) def addDumperModule(self, args): path = args['path'] diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index e60e3a6e922..089c4ae4610 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -1660,6 +1660,12 @@ class Dumper(DumperBase): matplotQuit() gdb.execute("quit") + def loadDumpers(self, args): + self.setupDumpers() + + def reportDumpers(self, msg): + print(msg) + def profile1(self, args): """Internal profiling""" import tempfile diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 0460a4d689f..4d814223880 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -1670,10 +1670,12 @@ class Dumper(DumperBase): result += ',offset="%s"},' % (addr - base) self.report(result + ']') - def loadDumperFiles(self, args): + def loadDumpers(self, args): self.reportToken(args) - result = self.setupDumper() - self.report(result) + self.setupDumpers() + + def reportDumpers(self, msg): + self.report(msg) def fetchMemory(self, args): address = args['address'] @@ -1721,7 +1723,7 @@ class Tester(Dumper): self.expandedINames = set(expandedINames) self.passExceptions = True - self.loadDumperFiles({}) + self.loadDumpers({}) error = lldb.SBError() self.target = self.debugger.CreateTarget(binary, None, None, True, error) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 040d1e7152c..d4ecc5fd908 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -4273,7 +4273,7 @@ void GdbEngine::startGdb(const QStringList &args) if (!commands.isEmpty()) postCommand(commands.toLocal8Bit(), flags); - runCommand(DebuggerCommand("setupDumper", flags, CB(handlePythonSetup))); + runCommand(DebuggerCommand("loadDumpers", flags, CB(handlePythonSetup))); } void GdbEngine::handleGdbStartFailed() @@ -4303,7 +4303,7 @@ void GdbEngine::loadInitScript() void GdbEngine::reloadDebuggingHelpers() { - runCommand("reloadDumper"); + runCommand("reloadDumpers"); reloadLocals(); } diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index de7399b034a..863d13968f2 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -303,7 +303,7 @@ void LldbEngine::setupInferior() runCommand(cmd); } - DebuggerCommand cmd1("loadDumperFiles"); + DebuggerCommand cmd1("loadDumpers"); runCommand(cmd1); } @@ -1160,6 +1160,12 @@ void LldbEngine::reloadRegisters() runCommand("reportRegisters"); } +void LldbEngine::reloadDebuggingHelpers() +{ + runCommand("reloadDumpers"); + updateAll(); +} + void LldbEngine::fetchDisassembler(DisassemblerAgent *agent) { QPointer p(agent); diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index 9e02351c732..31c404e4249 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -116,6 +116,7 @@ private: void reloadRegisters(); void reloadSourceFiles() {} void reloadFullStack(); + void reloadDebuggingHelpers(); void fetchDisassembler(Internal::DisassemblerAgent *); void refreshDisassembly(const GdbMi &data); diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 1f6c947ca73..8b1328619de 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -1240,7 +1240,7 @@ void tst_Dumpers::dumper() cmds += "python sys.path.insert(1, '" + dumperDir + "')\n" "python sys.path.append('" + uninstalledData + "')\n" "python from gdbbridge import *\n" - "python theDumper.setupDumper()\n" + "python theDumper.setupDumpers()\n" "run " + nograb + "\n" "python theDumper.showData({'fancy':1,'forcens':1,'autoderef':1," "'dyntype':1,'passExceptions':1,'expanded':[" + expandedq + "]})\n"; From 81a70627a42c56297dfd2154f855da7609c42743 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 19 Mar 2015 07:21:23 +0100 Subject: [PATCH 58/61] Tests: Dumper: Add current data tag to tmp build dir name. Change-Id: I91c26bcb70a10ed00c32f8bf18f16e0ac449c5b6 Reviewed-by: Christian Stenger Reviewed-by: hjk --- tests/auto/debugger/tst_dumpers.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 8b1328619de..22710817cd9 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -799,7 +799,9 @@ public: struct TempStuff { - TempStuff() : buildTemp(QLatin1String("qt_tst_dumpers_")) + TempStuff(const char *tag) : buildTemp(QLatin1String("qt_tst_dumpers_") + + QLatin1String(tag) + + QLatin1Char('_')) { buildPath = QDir::currentPath() + QLatin1Char('/') + buildTemp.path(); buildTemp.setAutoRemove(false); @@ -971,7 +973,7 @@ void tst_Dumpers::initTestCase() void tst_Dumpers::init() { - t = new TempStuff(); + t = new TempStuff(QTest::currentDataTag()); } void tst_Dumpers::cleanup() From e44378e942b82dfad136d5203536f635fea15ccf Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 18 Mar 2015 16:24:14 +0100 Subject: [PATCH 59/61] Debugger: Adjust watcher column size to locals content Change-Id: Iec6b4478862578397ee2b3953cd06730bd0db121 Reviewed-by: Christian Stenger --- src/libs/utils/basetreeview.cpp | 35 +++++++++++++++++++-------- src/libs/utils/basetreeview.h | 2 ++ src/plugins/debugger/watchhandler.cpp | 14 +++++++++++ 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/libs/utils/basetreeview.cpp b/src/libs/utils/basetreeview.cpp index 326f407cf4e..e38326d3f37 100644 --- a/src/libs/utils/basetreeview.cpp +++ b/src/libs/utils/basetreeview.cpp @@ -133,18 +133,14 @@ public: } } - int suggestedColumnSize(int column) const - { - QHeaderView *h = q->header(); - QTC_ASSERT(h, return -1); - QAbstractItemModel *m = q->model(); - QTC_ASSERT(m, return -1); - QModelIndex a = q->indexAt(QPoint(1, 1)); + void considerItems(int column, QModelIndex start, int *minimum, bool single) const + { + QModelIndex a = start; a = a.sibling(a.row(), column); QFontMetrics fm = q->fontMetrics(); - int minimum = fm.width(m->headerData(column, Qt::Horizontal).toString()); const int ind = q->indentation(); + QAbstractItemModel *m = q->model(); for (int i = 0; i < 100 && a.isValid(); ++i) { const QString s = m->data(a).toString(); int w = fm.width(s) + 10; @@ -152,10 +148,29 @@ public: for (QModelIndex b = a.parent(); b.isValid(); b = b.parent()) w += ind; } - if (w > minimum) - minimum = w; + if (w > *minimum) + *minimum = w; + if (single) + break; a = q->indexBelow(a); } + } + + int suggestedColumnSize(int column) const + { + QHeaderView *h = q->header(); + QTC_ASSERT(h, return -1); + QAbstractItemModel *m = q->model(); + QTC_ASSERT(m, return -1); + + QFontMetrics fm = q->fontMetrics(); + int minimum = fm.width(m->headerData(column, Qt::Horizontal).toString()) + 2 * fm.width(QLatin1Char('m')); + considerItems(column, q->indexAt(QPoint(1, 1)), &minimum, false); + + QVariant extraIndices = m->data(QModelIndex(), BaseTreeView::ExtraIndicesForColumnWidth); + foreach (const QModelIndex &a, extraIndices.value()) + considerItems(column, a, &minimum, true); + return minimum; } diff --git a/src/libs/utils/basetreeview.h b/src/libs/utils/basetreeview.h index 777f1f51291..2023a14d3ac 100644 --- a/src/libs/utils/basetreeview.h +++ b/src/libs/utils/basetreeview.h @@ -48,6 +48,8 @@ class QTCREATOR_UTILS_EXPORT BaseTreeView : public TreeView Q_OBJECT public: + enum { ExtraIndicesForColumnWidth = 12734 }; + BaseTreeView(QWidget *parent = 0); ~BaseTreeView(); diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index cb9dcf77a02..107d59fc05a 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -201,6 +201,7 @@ public: static QString nameForFormat(int format); TypeFormatList typeFormatList(const WatchData &value) const; + QVariant data(const QModelIndex &idx, int role) const; bool setData(const QModelIndex &idx, const QVariant &value, int role); void insertDataItem(const WatchData &data); @@ -850,6 +851,19 @@ QVariant WatchItem::data(int column, int role) const return QVariant(); } +QVariant WatchModel::data(const QModelIndex &idx, int role) const +{ + if (role == BaseTreeView::ExtraIndicesForColumnWidth) { + QModelIndexList l; + foreach (TreeItem *item, m_watchRoot->children()) + l.append(indexFromItem(item)); + foreach (TreeItem *item, m_returnRoot->children()) + l.append(indexFromItem(item)); + return QVariant::fromValue(l); + } + return WatchModelBase::data(idx, role); +} + bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role) { if (!idx.isValid()) From 2ae8ae5d875e00eb883e02111996e6024c5ac79c Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 6 Mar 2015 18:21:11 +0100 Subject: [PATCH 60/61] Utils: add additional search paths to FileInProjectFinder This can be used e.g. by profilers that need to match some on-device path to a local path. Change-Id: I38e572bfbd7848cfb2e8ba9e275b99bb09692fea Reviewed-by: Daniel Teske Reviewed-by: Ulf Hermann --- src/libs/utils/fileinprojectfinder.cpp | 53 ++++++++++++++++++++++++++ src/libs/utils/fileinprojectfinder.h | 6 +++ 2 files changed, 59 insertions(+) diff --git a/src/libs/utils/fileinprojectfinder.cpp b/src/libs/utils/fileinprojectfinder.cpp index e40b33136b7..1f31d912673 100644 --- a/src/libs/utils/fileinprojectfinder.cpp +++ b/src/libs/utils/fileinprojectfinder.cpp @@ -229,6 +229,9 @@ QString FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const return matchedFilePath; } + if (findInSearchPaths(&originalPath)) + return originalPath; + if (debug) qDebug() << "FileInProjectFinder: checking absolute path in sysroot ..."; @@ -253,6 +256,45 @@ QString FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const return originalPath; } +bool FileInProjectFinder::findInSearchPaths(QString *filePath) const +{ + foreach (const QString &dirPath, m_searchDirectories) { + if (findInSearchPath(dirPath, filePath)) + return true; + } + return false; +} + +static void chopFirstDir(QString *dirPath) +{ + int i = dirPath->indexOf(QLatin1Char('/')); + if (i == -1) + dirPath->clear(); + else + dirPath->remove(0, i + 1); +} + +bool FileInProjectFinder::findInSearchPath(const QString &searchPath, QString *filePath) +{ + if (debug) + qDebug() << "FileInProjectFinder: checking search path" << searchPath; + + QFileInfo fi; + QString s = *filePath; + while (!s.isEmpty()) { + fi.setFile(searchPath + QLatin1Char('/') + s); + if (debug) + qDebug() << "FileInProjectFinder: trying" << fi.filePath(); + if (fi.exists() && fi.isReadable()) { + *filePath = fi.filePath(); + return true; + } + chopFirstDir(&s); + } + + return false; +} + QStringList FileInProjectFinder::filesWithSameFileName(const QString &fileName) const { QStringList result; @@ -293,4 +335,15 @@ QString FileInProjectFinder::bestMatch(const QStringList &filePaths, const QStri return QString(); } +QStringList FileInProjectFinder::searchDirectories() const +{ + return m_searchDirectories; +} + +void FileInProjectFinder::setAdditionalSearchDirectories(const QStringList &searchDirectories) +{ + m_searchDirectories = searchDirectories; +} + + } // namespace Utils diff --git a/src/libs/utils/fileinprojectfinder.h b/src/libs/utils/fileinprojectfinder.h index c208ba2ecfd..ba632febede 100644 --- a/src/libs/utils/fileinprojectfinder.h +++ b/src/libs/utils/fileinprojectfinder.h @@ -53,7 +53,12 @@ public: QString findFile(const QUrl &fileUrl, bool *success = 0) const; + QStringList searchDirectories() const; + void setAdditionalSearchDirectories(const QStringList &searchDirectories); + private: + bool findInSearchPaths(QString *filePath) const; + static bool findInSearchPath(const QString &searchPath, QString *filePath); QStringList filesWithSameFileName(const QString &fileName) const; static int rankFilePath(const QString &candidatePath, const QString &filePathToFind); static QString bestMatch(const QStringList &filePaths, const QString &filePathToFind); @@ -61,6 +66,7 @@ private: QString m_projectDir; QString m_sysroot; QStringList m_projectFiles; + QStringList m_searchDirectories; mutable QHash m_cache; }; From bc6893773f1aab6c3255cf7bd169f578645d101b Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 6 Mar 2015 11:52:08 +0100 Subject: [PATCH 61/61] Timeline: Use QHash instead of QVector for child render states The offsets can get very large if you have long traces or zoom in very closely. We hardly ever need more than a few on each level, so this is just a waste of memory. Also, use 64bit integers to index them, as we can get very close to the numerical limit with 32bit ones. Change-Id: I20db4ea5dd2ea8922fa6552c106194bb4f19a76b Task-number: QTCREATORBUG-14105 Reviewed-by: Kai Koehne --- src/libs/timeline/timelinerenderer.cpp | 10 ++++------ src/libs/timeline/timelinerenderer_p.h | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/libs/timeline/timelinerenderer.cpp b/src/libs/timeline/timelinerenderer.cpp index 98fc95bc189..b114e99acda 100644 --- a/src/libs/timeline/timelinerenderer.cpp +++ b/src/libs/timeline/timelinerenderer.cpp @@ -73,9 +73,9 @@ void TimelineRenderer::TimelineRendererPrivate::resetCurrentSelection() TimelineRenderState *TimelineRenderer::TimelineRendererPrivate::findRenderState() { int newLevel = 0; - int newOffset = 0; + qint64 newOffset = 0; int level; - int offset; + qint64 offset; qint64 newStart = zoomer->traceStart(); qint64 newEnd = zoomer->traceEnd(); @@ -97,8 +97,6 @@ TimelineRenderState *TimelineRenderer::TimelineRendererPrivate::findRenderState( if (renderStates.length() <= level) renderStates.resize(level + 1); - if (renderStates[level].length() <= offset) - renderStates[level].resize(offset + 1); TimelineRenderState *state = renderStates[level][offset]; if (state == 0) { state = new TimelineRenderState(start, end, 1.0 / static_cast(SafeFloatMax), @@ -124,8 +122,8 @@ QSGNode *TimelineRenderer::updatePaintNode(QSGNode *node, UpdatePaintNodeData *u if (d->modelDirty) { if (node) node->removeAllChildNodes(); - foreach (QVector stateVector, d->renderStates) - qDeleteAll(stateVector); + for (auto i = d->renderStates.begin(); i != d->renderStates.end(); ++i) + qDeleteAll(*i); d->renderStates.clear(); d->lastState = 0; } diff --git a/src/libs/timeline/timelinerenderer_p.h b/src/libs/timeline/timelinerenderer_p.h index 3d4a2678aa0..807e6822a9b 100644 --- a/src/libs/timeline/timelinerenderer_p.h +++ b/src/libs/timeline/timelinerenderer_p.h @@ -59,7 +59,7 @@ public: int eventIndex; } currentSelection; - QVector > renderStates; + QVector > renderStates; TimelineRenderState *lastState; private: