diff options
author | Orgad Shaneh <orgad.shaneh@audiocodes.com> | 2017-10-17 20:00:44 +0300 |
---|---|---|
committer | Orgad Shaneh <orgad.shaneh@audiocodes.com> | 2017-10-17 20:00:44 +0300 |
commit | 371b2bbbab6b4bdc300ef7c3d4ce9c504ac25472 (patch) | |
tree | 0987f23b83e9031e35fa84d9495ee4b538f87e81 /src/plugins | |
parent | 5c554c0de9fd9115dbcfa010353640b11e349c6c (diff) | |
parent | aa4e05f07b22b062316bf8a35517956c3770e0f6 (diff) | |
download | qt-creator-371b2bbbab6b4bdc300ef7c3d4ce9c504ac25472.tar.gz |
Merge remote-tracking branch 'origin/4.5' into master
Change-Id: Ibcdd1230b40d1ca7a414843ee0f9ae4cddb29f6f
Diffstat (limited to 'src/plugins')
49 files changed, 274 insertions, 166 deletions
diff --git a/src/plugins/autotest/gtest/gtesttreeitem.cpp b/src/plugins/autotest/gtest/gtesttreeitem.cpp index 3b2c680fe9..b0f1183038 100644 --- a/src/plugins/autotest/gtest/gtesttreeitem.cpp +++ b/src/plugins/autotest/gtest/gtesttreeitem.cpp @@ -295,7 +295,10 @@ QSet<QString> GTestTreeItem::internalTargets() const const auto cppMM = CppTools::CppModelManager::instance(); const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject()); const QString file = filePath(); - for (const CppTools::ProjectPart::Ptr projectPart : projectInfo.projectParts()) { + const QVector<CppTools::ProjectPart::Ptr> projectParts = projectInfo.projectParts(); + if (projectParts.isEmpty()) + return TestTreeItem::dependingInternalTargets(cppMM, file); + for (const CppTools::ProjectPart::Ptr projectPart : projectParts) { if (projectPart->projectFile == proFile() && Utils::anyOf(projectPart->files, [&file] (const CppTools::ProjectFile &pf) { return pf.path == file; diff --git a/src/plugins/autotest/testframeworkmanager.cpp b/src/plugins/autotest/testframeworkmanager.cpp index 0ce72fe282..4726d2e02e 100644 --- a/src/plugins/autotest/testframeworkmanager.cpp +++ b/src/plugins/autotest/testframeworkmanager.cpp @@ -46,7 +46,7 @@ static Q_LOGGING_CATEGORY(LOG, "qtc.autotest.frameworkmanager") namespace Autotest { namespace Internal { -TestFrameworkManager *s_instance = nullptr; +static TestFrameworkManager *s_instance = nullptr; TestFrameworkManager::TestFrameworkManager() { diff --git a/src/plugins/autotest/testtreeitem.cpp b/src/plugins/autotest/testtreeitem.cpp index d27c689e5b..05eab8439f 100644 --- a/src/plugins/autotest/testtreeitem.cpp +++ b/src/plugins/autotest/testtreeitem.cpp @@ -288,6 +288,9 @@ QSet<QString> TestTreeItem::internalTargets() const { auto cppMM = CppTools::CppModelManager::instance(); const QList<CppTools::ProjectPart::Ptr> projectParts = cppMM->projectPart(m_filePath); + // if we have no project parts it's most likely a header with declarations only and CMake based + if (projectParts.isEmpty()) + return TestTreeItem::dependingInternalTargets(cppMM, m_filePath); QSet<QString> targets; for (const CppTools::ProjectPart::Ptr part : projectParts) { targets.insert(part->buildSystemTarget + '|' + part->projectFile); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index f707e2ef2b..fb7f0d658f 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -207,6 +207,7 @@ void CMakeBuildConfiguration::setConfigurationForCMake(const QList<ConfigModel:: ni.value = i.value.toUtf8(); ni.documentation = i.description.toUtf8(); ni.isAdvanced = i.isAdvanced; + ni.isUnset = i.isUnset; ni.inCMakeCache = i.inCMakeCache; ni.values = i.values; switch (i.type) { @@ -274,7 +275,7 @@ void CMakeBuildConfiguration::setConfigurationForCMake(const CMakeConfig &config bool hasKitOverride = false; foreach (const CMakeConfigItem &i, m_configurationForCMake) { const QString b = CMakeConfigItem::expandedValueOf(k, i.key, kitConfig); - if (!b.isNull() && i.expandedValue(k) != b) { + if (!b.isNull() && (i.expandedValue(k) != b || i.isUnset)) { hasKitOverride = true; break; } diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp index 3dd52c0bed..0abe72fd7d 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp @@ -39,11 +39,13 @@ #include <projectexplorer/target.h> #include <utils/asconst.h> +#include <utils/categorysortfiltermodel.h> #include <utils/detailswidget.h> #include <utils/fancylineedit.h> #include <utils/headerviewstretcher.h> -#include <utils/pathchooser.h> #include <utils/itemviews.h> +#include <utils/pathchooser.h> +#include <utils/progressindicator.h> #include <utils/utilsicons.h> #include <QBoxLayout> @@ -61,6 +63,20 @@ namespace CMakeProjectManager { namespace Internal { +static QModelIndex mapToSource(const QAbstractItemView *view, const QModelIndex &idx) +{ + if (!idx.isValid()) + return idx; + + QAbstractItemModel *model = view->model(); + QModelIndex result = idx; + while (QSortFilterProxyModel *proxy = qobject_cast<QSortFilterProxyModel *>(model)) { + result = proxy->mapToSource(result); + model = proxy->sourceModel(); + } + return result; +} + // -------------------------------------------------------------------- // CMakeBuildSettingsWidget: // -------------------------------------------------------------------- @@ -68,8 +84,8 @@ namespace Internal { CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) : m_buildConfiguration(bc), m_configModel(new ConfigModel(this)), - m_configFilterModel(new QSortFilterProxyModel), - m_configTextFilterModel(new QSortFilterProxyModel) + m_configFilterModel(new Utils::CategorySortFilterModel), + m_configTextFilterModel(new Utils::CategorySortFilterModel) { QTC_CHECK(bc); @@ -88,7 +104,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) mainLayout->setMargin(0); mainLayout->setColumnStretch(1, 10); - auto project = static_cast<CMakeProject *>(bc->target()->project()); + auto project = static_cast<CMakeProject *>(bc->project()); auto buildDirChooser = new Utils::PathChooser; buildDirChooser->setBaseFileName(project->projectDirectory()); @@ -182,6 +198,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) auto buttonLayout = new QVBoxLayout; m_addButton = new QPushButton(tr("&Add")); + m_addButton->setToolTip(tr("Add a new configuration value.")); buttonLayout->addWidget(m_addButton); { m_addButtonMenu = new QMenu; @@ -196,8 +213,13 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) m_addButton->setMenu(m_addButtonMenu); } m_editButton = new QPushButton(tr("&Edit")); + m_editButton->setToolTip(tr("Edit the current CMake configuration value.")); buttonLayout->addWidget(m_editButton); + m_unsetButton = new QPushButton(tr("&Unset")); + m_unsetButton->setToolTip(tr("Unset a value in the CMake configuration.")); + buttonLayout->addWidget(m_unsetButton); m_resetButton = new QPushButton(tr("&Reset")); + m_resetButton->setToolTip(tr("Reset all unapplied changes.")); m_resetButton->setEnabled(false); buttonLayout->addWidget(m_resetButton); buttonLayout->addItem(new QSpacerItem(10, 10, QSizePolicy::Fixed, QSizePolicy::Fixed)); @@ -266,6 +288,9 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) connect(m_reconfigureButton, &QPushButton::clicked, this, [this]() { m_buildConfiguration->setConfigurationForCMake(m_configModel->configurationChanges()); }); + connect(m_unsetButton, &QPushButton::clicked, this, [this]() { + m_configModel->toggleUnsetFlag(mapToSource(m_configView, m_configView->currentIndex())); + }); connect(m_editButton, &QPushButton::clicked, this, [this]() { QModelIndex idx = m_configView->currentIndex(); if (idx.column() != 1) @@ -296,6 +321,8 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) this, &CMakeBuildSettingsWidget::updateFromKit); connect(m_buildConfiguration, &CMakeBuildConfiguration::enabledChanged, this, [this]() { setError(m_buildConfiguration->disabledReason()); }); + + updateSelection(QModelIndex(), QModelIndex()); } void CMakeBuildSettingsWidget::setError(const QString &message) @@ -308,6 +335,7 @@ void CMakeBuildSettingsWidget::setError(const QString &message) m_errorMessageLabel->setToolTip(message); m_editButton->setEnabled(!showError); + m_unsetButton->setEnabled(!showError); m_resetButton->setEnabled(!showError); m_showAdvancedCheckBox->setEnabled(!showError); m_filterEdit->setEnabled(!showError); @@ -356,26 +384,12 @@ void CMakeBuildSettingsWidget::updateFromKit() m_configModel->setKitConfiguration(configHash); } -static QModelIndex mapToSource(const QAbstractItemView *view, const QModelIndex &idx) -{ - if (!idx.isValid()) - return idx; - - QAbstractItemModel *model = view->model(); - QModelIndex result = idx; - while (QSortFilterProxyModel *proxy = qobject_cast<QSortFilterProxyModel *>(model)) { - result = proxy->mapToSource(result); - model = proxy->sourceModel(); - } - return result; -} - void CMakeBuildSettingsWidget::updateSelection(const QModelIndex ¤t, const QModelIndex &previous) { Q_UNUSED(previous); - const QModelIndex currentModelIndex = mapToSource(m_configView, current); - if (currentModelIndex.isValid()) - m_editButton->setEnabled(currentModelIndex.flags().testFlag(Qt::ItemIsEditable)); + + m_editButton->setEnabled(current.isValid() && current.flags().testFlag(Qt::ItemIsEditable)); + m_unsetButton->setEnabled(current.isValid() && current.flags().testFlag(Qt::ItemIsSelectable)); } QAction *CMakeBuildSettingsWidget::createForceAction(int type, const QModelIndex &idx) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h index e6e4b1e21c..6d422dfe1e 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h @@ -26,9 +26,6 @@ #pragma once #include <projectexplorer/namedwidget.h> - -#include <utils/progressindicator.h> - #include <QTimer> QT_BEGIN_NAMESPACE @@ -40,7 +37,11 @@ class QSortFilterProxyModel; class QMenu; QT_END_NAMESPACE -namespace Utils { class FancyLineEdit; } +namespace Utils { +class CategorySortFilterModel; +class FancyLineEdit; +class ProgressIndicator; +} // namespace Utils namespace CMakeProjectManager { @@ -72,12 +73,13 @@ private: CMakeBuildConfiguration *m_buildConfiguration; QTreeView *m_configView; ConfigModel *m_configModel; - QSortFilterProxyModel *m_configFilterModel; - QSortFilterProxyModel *m_configTextFilterModel; + Utils::CategorySortFilterModel *m_configFilterModel; + Utils::CategorySortFilterModel *m_configTextFilterModel; Utils::ProgressIndicator *m_progressIndicator; QPushButton *m_addButton; QMenu *m_addButtonMenu; QPushButton *m_editButton; + QPushButton *m_unsetButton; QPushButton *m_resetButton; QCheckBox *m_showAdvancedCheckBox; QPushButton *m_reconfigureButton; diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp index 258803d45e..c4531fed20 100644 --- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp @@ -44,7 +44,8 @@ CMakeConfigItem::CMakeConfigItem() = default; CMakeConfigItem::CMakeConfigItem(const CMakeConfigItem &other) : key(other.key), type(other.type), isAdvanced(other.isAdvanced), - value(other.value), documentation(other.documentation), values(other.values) + inCMakeCache(false), isUnset(other.isUnset), value(other.value), + documentation(other.documentation), values(other.values) {} CMakeConfigItem::CMakeConfigItem(const QByteArray &k, Type t, @@ -316,6 +317,9 @@ QString CMakeConfigItem::toString(const Utils::MacroExpander *expander) const if (key.isEmpty() || type == CMakeProjectManager::CMakeConfigItem::STATIC) return QString(); + if (isUnset) + return "unset " + QString::fromUtf8(key); + QString typeStr; switch (type) { @@ -344,13 +348,15 @@ QString CMakeConfigItem::toString(const Utils::MacroExpander *expander) const QString CMakeConfigItem::toArgument(const Utils::MacroExpander *expander) const { + if (isUnset) + return "-U" + QString::fromUtf8(key); return "-D" + toString(expander); } bool CMakeConfigItem::operator==(const CMakeConfigItem &o) const { // type, isAdvanced and documentation do not matter for a match! - return o.key == key && o.value == value; + return o.key == key && o.value == value && o.isUnset == isUnset; } #if WITH_TESTS diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h index ebac479195..07409d9a36 100644 --- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h +++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h @@ -68,6 +68,7 @@ public: Type type = STRING; bool isAdvanced = false; bool inCMakeCache = false; + bool isUnset = false; QByteArray value; // converted to string as needed QByteArray documentation; QStringList values; diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 5aac57556e..24f1ad9428 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -140,6 +140,9 @@ CMakeProject::CMakeProject(const FileName &fileName) : Project(Constants::CMAKEM connect(this, &Project::activeTargetChanged, this, [this]() { CMakeBuildConfiguration *bc = activeBc(this); + if (!bc) + return; + // Target has switched, so the kit has changed, too. // * run cmake with configuration arguments if the reader needs to be switched // * run cmake without configuration arguments if the reader stays @@ -153,6 +156,9 @@ CMakeProject::CMakeProject(const FileName &fileName) : Project(Constants::CMAKEM subscribeSignal(&Target::activeBuildConfigurationChanged, this, [this]() { CMakeBuildConfiguration *bc = activeBc(this); + if (!bc) + return; + // Build configuration has switched: // * Error out if the reader updates, can not happen since all BCs share a target/kit. // * run cmake without configuration arguments if the reader stays diff --git a/src/plugins/cmakeprojectmanager/configmodel.cpp b/src/plugins/cmakeprojectmanager/configmodel.cpp index b90f35cff3..c31e1edb11 100644 --- a/src/plugins/cmakeprojectmanager/configmodel.cpp +++ b/src/plugins/cmakeprojectmanager/configmodel.cpp @@ -121,13 +121,16 @@ void ConfigModel::resetAllChanges() InternalDataItem ni(i); ni.newValue.clear(); ni.isUserChanged = false; + ni.isUnset = false; return ni; })); } bool ConfigModel::hasChanges() const { - return Utils::contains(m_configuration, [](const InternalDataItem &i) { return i.isUserChanged || i.isUserNew; }); + return Utils::contains(m_configuration, [](const InternalDataItem &i) { + return i.isUserChanged || i.isUserNew || i.isUnset; + }); } bool ConfigModel::hasCMakeChanges() const @@ -155,6 +158,19 @@ void ConfigModel::forceTo(const QModelIndex &idx, const ConfigModel::DataItem::T emit dataChanged(valueIdx, valueIdx); } +void ConfigModel::toggleUnsetFlag(const QModelIndex &idx) +{ + Utils::TreeItem *item = itemForIndex(idx); + auto cmti = dynamic_cast<Internal::ConfigModelTreeItem *>(item); + + QTC_ASSERT(cmti, return); + + cmti->dataItem->isUnset = !cmti->dataItem->isUnset; + const QModelIndex valueIdx = idx.sibling(idx.row(), 1); + const QModelIndex keyIdx = idx.sibling(idx.row(), 0); + emit dataChanged(keyIdx, valueIdx); +} + ConfigModel::DataItem ConfigModel::dataItemFromIndex(const QModelIndex &idx) { const QAbstractItemModel *m = idx.model(); @@ -190,7 +206,7 @@ QList<ConfigModel::DataItem> ConfigModel::configurationChanges() const { const QList<InternalDataItem> tmp = Utils::filtered(m_configuration, [](const InternalDataItem &i) { - return i.isUserChanged || i.isUserNew || !i.inCMakeCache; + return i.isUserChanged || i.isUserNew || !i.inCMakeCache || i.isUnset; }); return Utils::transform(tmp, [](const InternalDataItem &item) { DataItem newItem(item); @@ -246,7 +262,9 @@ void ConfigModel::setConfiguration(const QList<ConfigModel::InternalDataItem> &c QList<InternalDataItem> result; while (newIt != newEndIt && oldIt != oldEndIt) { - if (newIt->isHidden) { + if (oldIt->isUnset) { + ++oldIt; + } else if (newIt->isHidden || newIt->isUnset) { ++newIt; } else if (newIt->key < oldIt->key) { // Add new entry: @@ -350,6 +368,8 @@ QString ConfigModel::InternalDataItem::toolTip() const QString ConfigModel::InternalDataItem::currentValue() const { + if (isUnset) + return value; return isUserChanged ? newValue : value; } @@ -387,7 +407,7 @@ QVariant ConfigModelTreeItem::data(int column, int role) const QFont font; font.setItalic(dataItem->isCMakeChanged); font.setBold(dataItem->isUserNew); - font.setStrikeOut(!dataItem->inCMakeCache && !dataItem->isUserNew); + font.setStrikeOut((!dataItem->inCMakeCache && !dataItem->isUserNew) || dataItem->isUnset); return font; } default: @@ -406,8 +426,9 @@ QVariant ConfigModelTreeItem::data(int column, int role) const return (dataItem->type == ConfigModel::DataItem::BOOLEAN) ? QVariant(isTrue(value)) : QVariant(value); case Qt::FontRole: { QFont font; - font.setBold(dataItem->isUserChanged || dataItem->isUserNew); + font.setBold((dataItem->isUserChanged || dataItem->isUserNew) && !dataItem->isUnset); font.setItalic(dataItem->isCMakeChanged); + font.setStrikeOut((!dataItem->inCMakeCache && !dataItem->isUserNew) || dataItem->isUnset); return font; } case Qt::ForegroundRole: @@ -429,6 +450,8 @@ bool ConfigModelTreeItem::setData(int column, const QVariant &value, int role) { QTC_ASSERT(column >= 0 && column < 2, return false); QTC_ASSERT(dataItem, return false); + if (dataItem->isUnset) + return false; QString newValue = value.toString(); if (role == Qt::CheckStateRole) { @@ -467,6 +490,9 @@ Qt::ItemFlags ConfigModelTreeItem::flags(int column) const QTC_ASSERT(dataItem, return Qt::NoItemFlags); + if (dataItem->isUnset) + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + if (column == 1) { if (dataItem->type == ConfigModel::DataItem::BOOLEAN) return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable; diff --git a/src/plugins/cmakeprojectmanager/configmodel.h b/src/plugins/cmakeprojectmanager/configmodel.h index 6fb96e2990..fbe9b1b090 100644 --- a/src/plugins/cmakeprojectmanager/configmodel.h +++ b/src/plugins/cmakeprojectmanager/configmodel.h @@ -52,6 +52,7 @@ public: bool isHidden = false; bool isAdvanced = false; bool inCMakeCache = false; + bool isUnset = false; QString value; QString description; QStringList values; @@ -79,6 +80,8 @@ public: bool canForceTo(const QModelIndex &idx, const DataItem::Type type) const; void forceTo(const QModelIndex &idx, const DataItem::Type type); + void toggleUnsetFlag(const QModelIndex &idx); + static DataItem dataItemFromIndex(const QModelIndex &idx); QList<DataItem> configurationChanges() const; diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 344b4629e6..dd64cab848 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -476,6 +476,11 @@ void CdbEngine::setupEngine() nativeArguments.push_back(blank); QtcProcess::addArgs(&nativeArguments, QStringList(QDir::toNativeSeparators(sp.inferior.executable))); + if (!sp.inferior.commandLineArguments.isEmpty()) { // Complete native argument string. + if (!nativeArguments.isEmpty()) + nativeArguments.push_back(blank); + nativeArguments += sp.inferior.commandLineArguments; + } break; case AttachToRemoteServer: break; @@ -496,11 +501,6 @@ void CdbEngine::setupEngine() handleSetupFailure(QString("Internal error: Unsupported start mode %1.").arg(sp.startMode)); return; } - if (!sp.inferior.commandLineArguments.isEmpty()) { // Complete native argument string. - if (!nativeArguments.isEmpty()) - nativeArguments.push_back(blank); - nativeArguments += sp.inferior.commandLineArguments; - } const QString msg = QString("Launching %1 %2\nusing %3 of %4."). arg(QDir::toNativeSeparators(executable), diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 559382ce73..fc19bdd51b 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -230,11 +230,9 @@ public: } void doSetupEngine(); - void doSetupInferior(); void doRunEngine(); void doShutdownEngine(); void doShutdownInferior(); - void doInterruptInferior(); void reloadDisassembly() { @@ -691,24 +689,13 @@ void DebuggerEngine::notifyEngineSetupOk() showMessage("NOTE: ENGINE SETUP OK"); QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state()); setState(EngineSetupOk); - if (isMasterEngine() && runTool()) { + if (isMasterEngine() && runTool()) runTool()->reportStarted(); - d->doSetupInferior(); - } -} - -void DebuggerEngine::setupSlaveInferior() -{ - QTC_CHECK(state() == EngineSetupOk); - d->doSetupInferior(); -} -void DebuggerEnginePrivate::doSetupInferior() -{ - m_engine->setState(InferiorSetupRequested); - m_engine->showMessage("CALL: SETUP INFERIOR"); - m_progress.setProgressValue(250); - m_engine->setupInferior(); + setState(InferiorSetupRequested); + showMessage("CALL: SETUP INFERIOR"); + d->m_progress.setProgressValue(250); + setupInferior(); } void DebuggerEngine::notifyInferiorSetupFailed() @@ -868,16 +855,6 @@ void DebuggerEngine::notifyInferiorStopFailed() d->doShutdownEngine(); } -void DebuggerEnginePrivate::doInterruptInferior() -{ - //QTC_ASSERT(isMasterEngine(), return); - QTC_ASSERT(state() == InferiorRunOk, qDebug() << m_engine << state()); - m_engine->setState(InferiorStopRequested); - m_engine->showMessage("CALL: INTERRUPT INFERIOR"); - m_engine->showStatusMessage(tr("Attempting to interrupt.")); - m_engine->interruptInferior(); -} - void DebuggerEnginePrivate::doShutdownInferior() { m_engine->setState(InferiorShutdownRequested); @@ -1249,7 +1226,9 @@ void DebuggerEngine::quitDebugger() d->doShutdownInferior(); break; case InferiorRunOk: - d->doInterruptInferior(); + setState(InferiorStopRequested); + showStatusMessage(tr("Attempting to interrupt.")); + interruptInferior(); break; case EngineSetupRequested: notifyEngineSetupFailed(); @@ -1295,7 +1274,12 @@ void DebuggerEngine::abortDebugger() void DebuggerEngine::requestInterruptInferior() { - d->doInterruptInferior(); + QTC_CHECK(isMasterEngine()); + QTC_ASSERT(state() == InferiorRunOk, qDebug() << this << state()); + setState(InferiorStopRequested); + showMessage("CALL: INTERRUPT INFERIOR"); + showStatusMessage(tr("Attempting to interrupt.")); + interruptInferior(); } void DebuggerEngine::progressPing() diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index a4ff6f47d0..41bcd8a2fa 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -85,7 +85,6 @@ public: ProjectExplorer::StandardRunnable inferior; QString displayName; // Used in the Snapshots view. - Utils::Environment stubEnvironment; Utils::ProcessHandle attachPID; QStringList solibSearchPath; @@ -443,7 +442,7 @@ protected: virtual void continueInferior(); virtual void interruptInferior(); - virtual void requestInterruptInferior(); + void requestInterruptInferior(); virtual void executeRunToLine(const Internal::ContextData &data); virtual void executeRunToFunction(const QString &functionName); @@ -471,7 +470,6 @@ protected: bool isStateDebugging() const; void setStateDebugging(bool on); - virtual void setupSlaveInferior(); virtual void setupSlaveEngine(); virtual void runSlaveEngine(); virtual void shutdownSlaveEngine(); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 23ef2ba06c..d8ee01a58f 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -3035,7 +3035,7 @@ DebuggerEngine *currentEngine() { DebuggerEngine *engine = nullptr; if (dd->m_currentRunTool) - engine = dd->m_currentRunTool->activeEngine(); + engine = dd->m_currentRunTool->engine(); return engine ? engine : dd->dummyEngine(); } diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index e96f0b70a6..b16a94b4f1 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -428,6 +428,11 @@ void DebuggerRunTool::setInferiorExecutable(const QString &executable) m_runParameters.inferior.executable = executable; } +void DebuggerRunTool::setInferiorEnvironment(const Utils::Environment &env) +{ + m_runParameters.inferior.environment = env; +} + void DebuggerRunTool::setRunControlName(const QString &name) { m_runParameters.displayName = name; @@ -671,8 +676,6 @@ bool DebuggerRunTool::fixupParameters() if (rp.symbolFile.isEmpty()) rp.symbolFile = rp.inferior.executable; - rp.stubEnvironment = rp.inferior.environment; // FIXME: Wrong, but contains DYLD_IMAGE_SUFFIX - // Copy over DYLD_IMAGE_SUFFIX etc for (auto var : QStringList({"DYLD_IMAGE_SUFFIX", "DYLD_LIBRARY_PATH", "DYLD_FRAMEWORK_PATH"})) if (rp.inferior.environment.hasKey(var)) diff --git a/src/plugins/debugger/debuggerruncontrol.h b/src/plugins/debugger/debuggerruncontrol.h index f35ba53138..4f17a23ada 100644 --- a/src/plugins/debugger/debuggerruncontrol.h +++ b/src/plugins/debugger/debuggerruncontrol.h @@ -81,6 +81,7 @@ public: void setInferior(const ProjectExplorer::Runnable &runnable); void setInferiorExecutable(const QString &executable); + void setInferiorEnvironment(const Utils::Environment &env); // Used by GammaRay plugin void setRunControlName(const QString &name); void setStartMessage(const QString &msg); void appendInferiorCommandLineArgument(const QString &arg); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 926a730cd4..f4526977e3 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1782,7 +1782,7 @@ void GdbEngine::setLinuxOsAbi() void GdbEngine::detachDebugger() { CHECK_STATE(InferiorStopOk); - QTC_ASSERT(m_startMode != AttachCore, qDebug() << m_startMode); + QTC_CHECK(runParameters().startMode != AttachCore); DebuggerCommand cmd("detach", ExitRequest); cmd.callback = [this](const DebuggerResponse &) { CHECK_STATE(InferiorStopOk); @@ -4242,17 +4242,18 @@ bool GdbEngine::isPlainEngine() const bool GdbEngine::isCoreEngine() const { - return m_startMode == AttachCore; + return runParameters().startMode == AttachCore; } bool GdbEngine::isRemoteEngine() const { - return m_startMode == StartRemoteProcess || m_startMode == AttachToRemoteServer; + DebuggerStartMode startMode = runParameters().startMode; + return startMode == StartRemoteProcess || startMode == AttachToRemoteServer; } bool GdbEngine::isAttachEngine() const { - return m_startMode == AttachExternal; + return runParameters().startMode == AttachExternal; } bool GdbEngine::isTermEngine() const diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 5d481f590f..97278c4d7a 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -38,7 +38,6 @@ #include <coreplugin/id.h> #include <utils/qtcprocess.h> -#include <utils/consoleprocess.h> #include <QProcess> #include <QTextCodec> @@ -55,7 +54,6 @@ class DebuggerResponse; class DisassemblerAgentCookie; class GdbMi; class MemoryAgentCookie; -class TerminalRunner; struct CoreInfo { @@ -444,7 +442,6 @@ private: ////////// General Interface ////////// Utils::QtcProcess m_gdbProc; OutputCollector m_outputCollector; QString m_errorString; - DebuggerStartMode m_startMode = NoStartMode; }; } // namespace Internal diff --git a/src/plugins/debugger/qml/qmlcppengine.cpp b/src/plugins/debugger/qml/qmlcppengine.cpp index 77e5204dc9..7554a68d8b 100644 --- a/src/plugins/debugger/qml/qmlcppengine.cpp +++ b/src/plugins/debugger/qml/qmlcppengine.cpp @@ -337,13 +337,7 @@ void QmlCppEngine::continueInferior() void QmlCppEngine::interruptInferior() { EDEBUG("\nMASTER INTERRUPT INFERIOR"); - m_cppEngine->requestInterruptInferior(); -} - -void QmlCppEngine::requestInterruptInferior() -{ - EDEBUG("\nMASTER REQUEST INTERRUPT INFERIOR"); - DebuggerEngine::requestInterruptInferior(); + m_activeEngine->interruptInferior(); } void QmlCppEngine::executeRunToLine(const ContextData &data) @@ -380,8 +374,8 @@ void QmlCppEngine::setupEngine() void QmlCppEngine::setupInferior() { EDEBUG("\nMASTER SETUP INFERIOR"); - m_qmlEngine->setupSlaveInferior(); - m_cppEngine->setupSlaveInferior(); + m_qmlEngine->setupInferior(); + m_cppEngine->setupInferior(); } void QmlCppEngine::runEngine() diff --git a/src/plugins/debugger/qml/qmlcppengine.h b/src/plugins/debugger/qml/qmlcppengine.h index 1a6bffb7c5..751fa3c410 100644 --- a/src/plugins/debugger/qml/qmlcppengine.h +++ b/src/plugins/debugger/qml/qmlcppengine.h @@ -98,7 +98,6 @@ protected: void executeReturn() override; void continueInferior() override; void interruptInferior() override; - void requestInterruptInferior() override; void executeRunToLine(const ContextData &data) override; void executeRunToFunction(const QString &functionName) override; diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index a9574117d8..af7f5f06b1 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -871,9 +871,13 @@ bool QmlEngine::canHandleToolTip(const DebuggerToolTipContext &) const } void QmlEngine::assignValueInDebugger(WatchItem *item, - const QString &expression, const QVariant &value) + const QString &expression, const QVariant &editValue) { if (!expression.isEmpty()) { + QVariant value = (editValue.type() == QVariant::String) + ? QVariant('"' + editValue.toString().replace('"', "\\\"") + '"') + : editValue; + if (item->isInspect()) { d->inspectorAgent.assignValue(item, expression, value); } else { @@ -882,7 +886,7 @@ void QmlEngine::assignValueInDebugger(WatchItem *item, if (handler->isContentsValid() && handler->currentFrame().isUsable()) { d->evaluate(exp, -1, [this](const QVariantMap &) { d->updateLocals(); }); } else { - showMessage(QString("Cannot evaluate %1 in current stack frame") + showMessage(tr("Cannot evaluate %1 in current stack frame.") .arg(expression), ConsoleOutput); } } diff --git a/src/plugins/debugger/qml/qmlinspectoragent.cpp b/src/plugins/debugger/qml/qmlinspectoragent.cpp index a765746c82..f273529f69 100644 --- a/src/plugins/debugger/qml/qmlinspectoragent.cpp +++ b/src/plugins/debugger/qml/qmlinspectoragent.cpp @@ -176,10 +176,6 @@ void QmlInspectorAgent::assignValue(const WatchItem *data, if (data->id != WatchItem::InvalidId) { QString val(valueV.toString()); - if (valueV.type() == QVariant::String) { - val = val.replace(QLatin1Char('\"'), QLatin1String("\\\"")); - val = QLatin1Char('\"') + val + QLatin1Char('\"'); - } QString expression = QString("%1 = %2;").arg(expr).arg(val); queryExpressionResult(data->id, expression); } diff --git a/src/plugins/debugger/terminal.cpp b/src/plugins/debugger/terminal.cpp index 09dcdb156c..78d60e695b 100644 --- a/src/plugins/debugger/terminal.cpp +++ b/src/plugins/debugger/terminal.cpp @@ -175,15 +175,13 @@ TerminalRunner::TerminalRunner(DebuggerRunTool *debugger) const DebuggerRunParameters &rp = debugger->runParameters(); m_stubRunnable = rp.inferior; - m_stubRunnable.environment = rp.stubEnvironment; - m_stubRunnable.workingDirectory = rp.inferior.workingDirectory; connect(&m_stubProc, &ConsoleProcess::processError, this, &TerminalRunner::stubError); connect(&m_stubProc, &ConsoleProcess::processStarted, this, &TerminalRunner::stubStarted); - connect(&m_stubProc, &ConsoleProcess::stubStopped, - this, &TerminalRunner::stubExited); + connect(&m_stubProc, &ConsoleProcess::processStopped, + this, [this] { reportDone(); }); } void TerminalRunner::start() @@ -224,11 +222,6 @@ void TerminalRunner::stubError(const QString &msg) reportFailure(msg); } -void TerminalRunner::stubExited() -{ - reportStopped(); -} - } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/terminal.h b/src/plugins/debugger/terminal.h index 0745373e0e..cd39daa5fc 100644 --- a/src/plugins/debugger/terminal.h +++ b/src/plugins/debugger/terminal.h @@ -82,7 +82,6 @@ private: void stop() final; void stubStarted(); - void stubExited(); void stubError(const QString &msg); Utils::ConsoleProcess m_stubProc; diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp index 453d6562d6..7c1e727d05 100644 --- a/src/plugins/debugger/watchdata.cpp +++ b/src/plugins/debugger/watchdata.cpp @@ -94,7 +94,7 @@ bool isIntType(const QString &type) bool isFloatType(const QString &type) { - return type == "float" || type == "double" || type == "qreal"; + return type == "float" || type == "double" || type == "qreal" || type == "number"; } bool isIntOrFloatType(const QString &type) diff --git a/src/plugins/git/gerrit/gerritremotechooser.cpp b/src/plugins/git/gerrit/gerritremotechooser.cpp index b5cf6e9f02..c242b1c6ad 100644 --- a/src/plugins/git/gerrit/gerritremotechooser.cpp +++ b/src/plugins/git/gerrit/gerritremotechooser.cpp @@ -99,9 +99,9 @@ bool GerritRemoteChooser::setCurrentRemote(const QString &remoteName) bool GerritRemoteChooser::updateRemotes(bool forceReload) { QTC_ASSERT(!m_repository.isEmpty() || !m_parameters, return false); + m_updatingRemotes = true; m_remoteComboBox->clear(); m_remotes.clear(); - m_updatingRemotes = true; QString errorMessage; // Mute errors. We'll just fallback to the defaults QMap<QString, QString> remotesList = Git::Internal::GitPlugin::client()->synchronousRemotesList(m_repository, &errorMessage); diff --git a/src/plugins/projectexplorer/appoutputpane.cpp b/src/plugins/projectexplorer/appoutputpane.cpp index 676b1de19b..fa4d4f1c19 100644 --- a/src/plugins/projectexplorer/appoutputpane.cpp +++ b/src/plugins/projectexplorer/appoutputpane.cpp @@ -568,7 +568,7 @@ void AppOutputPane::closeTab(int tabIndex, CloseTabMode closeTabMode) // Prompt user to stop if (closeTabMode == CloseTabWithPrompt) { QWidget *tabWidget = m_tabWidget->widget(tabIndex); - if (!runControl->promptToStop()) + if (runControl->isRunning() && !runControl->promptToStop()) return; // The event loop has run, thus the ordering might have changed, a tab might // have been closed, so do some strange things... diff --git a/src/plugins/projectexplorer/miniprojecttargetselector.cpp b/src/plugins/projectexplorer/miniprojecttargetselector.cpp index f41b9f73a4..293791011c 100644 --- a/src/plugins/projectexplorer/miniprojecttargetselector.cpp +++ b/src/plugins/projectexplorer/miniprojecttargetselector.cpp @@ -1111,7 +1111,7 @@ bool MiniProjectTargetSelector::removedBuildConfiguration(BuildConfiguration *bc bool MiniProjectTargetSelector::addedDeployConfiguration(DeployConfiguration *dc) { - if (dc->target() != m_project->activeTarget()) + if (!m_project || dc->target() != m_project->activeTarget()) return false; m_listWidgets[DEPLOY]->addProjectConfiguration(dc); diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 1c38f85638..9e3d3339c7 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -570,8 +570,10 @@ public: QVariantMap data; int startWatchdogInterval = 0; int startWatchdogTimerId = -1; + std::function<void()> startWatchdogCallback; int stopWatchdogInterval = 0; // 5000; int stopWatchdogTimerId = -1; + std::function<void()> stopWatchdogCallback; bool supportsReRunning = true; bool essential = false; }; @@ -1407,10 +1409,15 @@ void SimpleTargetRunner::start() m_stopReported = false; m_launcher.disconnect(this); - QString msg = RunControl::tr("Starting %1...").arg(m_runnable.displayName()); + const bool isDesktop = isSynchronousLauncher(runControl()); + const QString rawDisplayName = m_runnable.displayName(); + const QString displayName = isDesktop + ? QDir::toNativeSeparators(rawDisplayName) + : rawDisplayName; + const QString msg = RunControl::tr("Starting %1...").arg(displayName); appendMessage(msg, Utils::NormalMessageFormat); - if (isSynchronousLauncher(runControl())) { + if (isDesktop) { connect(&m_launcher, &ApplicationLauncher::appendMessage, this, &SimpleTargetRunner::appendMessage); @@ -1562,11 +1569,17 @@ bool RunWorkerPrivate::canStop() const void RunWorkerPrivate::timerEvent(QTimerEvent *ev) { if (ev->timerId() == startWatchdogTimerId) { - q->reportFailure(tr("Worker start timed out.")); + if (startWatchdogCallback) + startWatchdogCallback(); + else + q->reportFailure(tr("Worker start timed out.")); return; } if (ev->timerId() == stopWatchdogTimerId) { - q->reportFailure(tr("Worker stop timed out.")); + if (stopWatchdogCallback) + stopWatchdogCallback(); + else + q->reportFailure(tr("Worker stop timed out.")); return; } } @@ -1760,14 +1773,16 @@ void RunWorker::setId(const QString &id) d->id = id; } -void RunWorker::setStartTimeout(int ms) +void RunWorker::setStartTimeout(int ms, const std::function<void()> &callback) { d->startWatchdogInterval = ms; + d->startWatchdogCallback = callback; } -void RunWorker::setStopTimeout(int ms) +void RunWorker::setStopTimeout(int ms, const std::function<void()> &callback) { d->stopWatchdogInterval = ms; + d->stopWatchdogCallback = callback; } void RunWorker::recordData(const QString &channel, const QVariant &data) diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index 51f5c7b2e2..f938f3a93d 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -347,8 +347,8 @@ public: void setDisplayName(const QString &id) { setId(id); } // FIXME: Obsoleted by setId. void setId(const QString &id); - void setStartTimeout(int ms); - void setStopTimeout(int ms); + void setStartTimeout(int ms, const std::function<void()> &callback = {}); + void setStopTimeout(int ms, const std::function<void()> &callback = {}); void recordData(const QString &channel, const QVariant &data); QVariant recordedData(const QString &channel) const; diff --git a/src/plugins/projectexplorer/runnables.h b/src/plugins/projectexplorer/runnables.h index 9a9568c686..91ac6c220c 100644 --- a/src/plugins/projectexplorer/runnables.h +++ b/src/plugins/projectexplorer/runnables.h @@ -32,7 +32,6 @@ #include <utils/environment.h> -#include <QDir> namespace ProjectExplorer { @@ -46,7 +45,9 @@ public: ApplicationLauncher::Mode runMode = ApplicationLauncher::Gui; IDevice::ConstPtr device; // Override the kit's device. Keep unset by default. - QString displayName() const { return QDir::toNativeSeparators(executable); } + // FIXME: Not necessarily a display name + QString displayName() const { return executable; } + static void *staticTypeId; }; diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp index 30fb0dcbb2..29f55ad94d 100644 --- a/src/plugins/pythoneditor/pythoneditorplugin.cpp +++ b/src/plugins/pythoneditor/pythoneditorplugin.cpp @@ -191,6 +191,7 @@ void PythonRunConfiguration::initialize(Core::Id id) RunConfiguration::initialize(id); m_mainScript = scriptFromId(id); + setDisplayName(defaultDisplayName()); Environment sysEnv = Environment::systemEnvironment(); const QString exec = sysEnv.searchInPath("python").toString(); diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp index 2a54a8e28a..7f551609cb 100644 --- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp +++ b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp @@ -142,6 +142,7 @@ QbsRunConfiguration::QbsRunConfiguration(Target *target) void QbsRunConfiguration::initialize(Core::Id id) { + RunConfiguration::initialize(id); m_uniqueProductName = uniqueProductNameFromId(id); ctor(); } @@ -337,6 +338,7 @@ QbsRunConfigurationWidget::QbsRunConfigurationWidget(QbsRunConfiguration *rc) connect(m_rc, &RunConfiguration::enabledChanged, this, &QbsRunConfigurationWidget::targetInformationHasChanged); + targetInformationHasChanged(); Core::VariableChooser::addSupportForChildWidgets(this, rc->macroExpander()); } diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp index ee18fd8e9f..17a1684fad 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp @@ -335,15 +335,17 @@ void QmakeProjectManagerPlugin::updateContextActions() m_addLibraryActionContextMenu->setEnabled(proFileNode); QmakeProject *qmakeProject = qobject_cast<QmakeProject *>(QmakeManager::contextProject()); QmakeProFileNode *subProjectNode = nullptr; + disableBuildFileMenus(); if (node) { auto subPriFileNode = dynamic_cast<const QmakePriFileNode *>(node); if (!subPriFileNode) subPriFileNode = dynamic_cast<QmakePriFileNode *>(node->parentProjectNode()); subProjectNode = subPriFileNode ? subPriFileNode->proFileNode() : nullptr; + + if (const FileNode *fileNode = node->asFileNode()) + enableBuildFileMenus(fileNode->filePath()); } - const FileNode *fileNode = node ? node->asFileNode() : nullptr; - bool buildFilePossible = subProjectNode && fileNode && (fileNode->fileType() == FileType::Source); bool subProjectActionsVisible = false; if (qmakeProject && subProjectNode) { if (QmakeProFileNode *rootNode = qmakeProject->rootProjectNode()) @@ -358,7 +360,6 @@ void QmakeProjectManagerPlugin::updateContextActions() m_rebuildSubProjectAction->setParameter(subProjectName); m_cleanSubProjectAction->setParameter(subProjectName); m_buildSubProjectContextMenu->setParameter(proFileNode ? proFileNode->displayName() : QString()); - m_buildFileAction->setParameter(buildFilePossible ? fileNode->filePath().fileName() : QString()); auto buildConfiguration = (qmakeProject && qmakeProject->activeTarget()) ? static_cast<QmakeBuildConfiguration *>(qmakeProject->activeTarget()->activeBuildConfiguration()) : nullptr; @@ -373,7 +374,6 @@ void QmakeProjectManagerPlugin::updateContextActions() m_subProjectRebuildSeparator->setVisible(subProjectActionsVisible && isProjectNode); m_rebuildSubProjectContextMenu->setVisible(subProjectActionsVisible && isProjectNode); m_cleanSubProjectContextMenu->setVisible(subProjectActionsVisible && isProjectNode); - m_buildFileAction->setVisible(buildFilePossible); m_buildSubProjectAction->setEnabled(enabled); m_rebuildSubProjectAction->setEnabled(enabled); @@ -383,8 +383,6 @@ void QmakeProjectManagerPlugin::updateContextActions() m_cleanSubProjectContextMenu->setEnabled(enabled && isProjectNode); m_runQMakeActionContextMenu->setEnabled(isProjectNode && !isBuilding && buildConfiguration->qmakeStep()); - m_buildFileAction->setEnabled(buildFilePossible && !isBuilding); - m_buildFileContextMenu->setEnabled(buildFilePossible && !isBuilding); } void QmakeProjectManagerPlugin::buildStateChanged(ProjectExplorer::Project *pro) @@ -398,20 +396,38 @@ void QmakeProjectManagerPlugin::buildStateChanged(ProjectExplorer::Project *pro) void QmakeProjectManagerPlugin::updateBuildFileAction() { + disableBuildFileMenus(); + if (IDocument *currentDocument = EditorManager::currentDocument()) + enableBuildFileMenus(currentDocument->filePath()); +} + +void QmakeProjectManagerPlugin::disableBuildFileMenus() +{ + m_buildFileAction->setVisible(false); + m_buildFileAction->setEnabled(false); + m_buildFileAction->setParameter(QString()); + m_buildFileContextMenu->setEnabled(false); +} + +void QmakeProjectManagerPlugin::enableBuildFileMenus(const Utils::FileName &file) +{ bool visible = false; bool enabled = false; - if (IDocument *currentDocument= EditorManager::currentDocument()) { - Utils::FileName file = currentDocument->filePath(); - Node *node = SessionManager::nodeForFile(file); - Project *project = SessionManager::projectForFile(file); - m_buildFileAction->setParameter(file.fileName()); - visible = qobject_cast<QmakeProject *>(project) - && node - && dynamic_cast<QmakePriFileNode *>(node->parentProjectNode()); - - enabled = !BuildManager::isBuilding(project); + if (Node *node = SessionManager::nodeForFile(file)) { + if (Project *project = SessionManager::projectForFile(file)) { + if (const FileNode *fileNode = node->asFileNode()) { + const FileType type = fileNode->fileType(); + visible = qobject_cast<QmakeProject *>(project) + && dynamic_cast<QmakePriFileNode *>(node->parentProjectNode()) + && (type == FileType::Source || type == FileType::Header); + + enabled = !BuildManager::isBuilding(project); + m_buildFileAction->setParameter(file.fileName()); + } + } } m_buildFileAction->setVisible(visible); m_buildFileAction->setEnabled(enabled); + m_buildFileContextMenu->setEnabled(visible && enabled); } diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.h b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.h index b6d94a9aea..4cc5255f86 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.h +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.h @@ -36,7 +36,10 @@ namespace ProjectExplorer { class Project; class Target; } -namespace Utils { class ParameterAction; } +namespace Utils { +class FileName; +class ParameterAction; +} namespace QmakeProjectManager { @@ -70,6 +73,8 @@ private: void updateContextActions(); void buildStateChanged(ProjectExplorer::Project *pro); void updateBuildFileAction(); + void disableBuildFileMenus(); + void enableBuildFileMenus(const Utils::FileName &file); QmakeManager *m_qmakeProjectManager = nullptr; QmakeProject *m_previousStartupProject = nullptr; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.cpp index be747266f1..827c07e8f4 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.cpp @@ -42,6 +42,11 @@ QString ItemLibraryItem::itemName() const return m_itemLibraryEntry.name(); } +QString ItemLibraryItem::typeName() const +{ + return QString::fromUtf8(m_itemLibraryEntry.typeName()); +} + QString ItemLibraryItem::itemLibraryIconPath() const { //Prepend image provider prefix diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.h index c5ac7d8d87..745418dfea 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryitem.h @@ -48,6 +48,7 @@ public: ~ItemLibraryItem(); QString itemName() const; + QString typeName() const; QString itemLibraryIconPath() const; bool setVisible(bool isVisible); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.cpp index 792d8539bd..73d89b7b57 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarysection.cpp @@ -75,7 +75,8 @@ bool ItemLibrarySection::updateSectionVisibility(const QString &searchText, bool *changed = false; foreach(ItemLibraryItem *itemLibraryItem, m_sectionEntries.items()) { - bool itemVisible = itemLibraryItem->itemName().toLower().contains(searchText); + bool itemVisible = itemLibraryItem->itemName().toLower().contains(searchText) + || itemLibraryItem->typeName().toLower().contains(searchText); bool itemChanged = itemLibraryItem->setVisible(itemVisible); diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 3b78b09de1..d9f3fa1736 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -511,6 +511,9 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in moveNodesInteractive(targetProperty, newModelNodeList, targetRowNumber); } + + if (newQmlItemNode.isValid()) + m_view->selectModelNode(newQmlItemNode.modelNode()); } } @@ -533,6 +536,9 @@ void NavigatorTreeModel::handleItemLibraryImageDrop(const QMimeData *mimeData, i moveNodesInteractive(targetProperty, newModelNodeList, targetRowNumber); } + + if (newQmlItemNode.isValid()) + m_view->selectModelNode(newQmlItemNode.modelNode()); } } diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp b/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp index 698ce6afc0..e3e16e95d4 100644 --- a/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp +++ b/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp @@ -93,6 +93,7 @@ TextEditorView::~TextEditorView() void TextEditorView::modelAttached(Model *model) { Q_ASSERT(model); + m_widget->clearStatusBar(); AbstractView::modelAttached(model); diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index 1f972b68a7..197c7d5064 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -205,6 +205,7 @@ void NodeInstanceView::restartProcess() if (rootNodeInstance().isValid()) rootNodeInstance().setError({}); emitInstanceErrorChange({}); + emitDocumentMessage({}, {}); if (m_restartProcessTimerId) killTimer(m_restartProcessTimerId); diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index 57ce5f8ddc..36875422e0 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -598,7 +598,8 @@ void AbstractView::emitDocumentMessage(const QString &error) void AbstractView::emitDocumentMessage(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings) { - model()->d->setDocumentMessages(errors, warnings); + if (model()) + model()->d->setDocumentMessages(errors, warnings); } void AbstractView::emitCustomNotification(const QString &identifier) diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp index d73f96df94..6f7ed9bbe7 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp @@ -1107,6 +1107,9 @@ bool ModelNode::isComponent() const if (!isValid()) throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); + if (!metaInfo().isValid()) + return false; + if (metaInfo().isFileComponent()) return true; @@ -1114,10 +1117,14 @@ bool ModelNode::isComponent() const return true; if (metaInfo().isView() && hasNodeProperty("delegate")) { - if (nodeProperty("delegate").modelNode().metaInfo().isFileComponent()) - return true; + const ModelNode delegateNode = nodeProperty("delegate").modelNode(); + if (delegateNode.hasMetaInfo()) { + const NodeMetaInfo delegateMetaInfo = delegateNode.metaInfo(); + if (delegateMetaInfo.isValid() && delegateMetaInfo.isFileComponent()) + return true; + } - if (nodeProperty("delegate").modelNode().nodeSourceType() == ModelNode::NodeWithComponentSource) + if (delegateNode.nodeSourceType() == ModelNode::NodeWithComponentSource) return true; } diff --git a/src/plugins/qmljseditor/qmljseditorplugin.cpp b/src/plugins/qmljseditor/qmljseditorplugin.cpp index 34f2fa818a..068fbb4340 100644 --- a/src/plugins/qmljseditor/qmljseditorplugin.cpp +++ b/src/plugins/qmljseditor/qmljseditorplugin.cpp @@ -259,19 +259,28 @@ void QmlJSEditorPlugin::reformatFile() if (!document->isParsedCorrectly()) return; + TextEditor::TabSettings tabSettings = m_currentDocument->tabSettings(); const QString &newText = QmlJS::reformat(document, tabSettings.m_indentSize, tabSettings.m_tabSize); - QmlJSEditorWidget *widget = EditorManager::currentEditor() - ? qobject_cast<QmlJSEditorWidget*>(EditorManager::currentEditor()->widget()) - : nullptr; - if (widget) { - const int position = widget->position(); - m_currentDocument->document()->setPlainText(newText); - widget->setCursorPosition(position); + + // QTextDocument::setPlainText cannot be used, as it would reset undo/redo history + const auto setNewText = [this, &newText]() { + QTextCursor tc(m_currentDocument->document()); + tc.movePosition(QTextCursor::Start); + tc.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); + tc.insertText(newText); + }; + + IEditor *ed = EditorManager::currentEditor(); + if (ed) { + int line = ed->currentLine(); + int column = ed->currentColumn(); + setNewText(); + ed->gotoLine(line, column); } else { - m_currentDocument->document()->setPlainText(newText); + setNewText(); } } } diff --git a/src/plugins/qnx/qnxdebugsupport.cpp b/src/plugins/qnx/qnxdebugsupport.cpp index cee4501c45..d4a55c2419 100644 --- a/src/plugins/qnx/qnxdebugsupport.cpp +++ b/src/plugins/qnx/qnxdebugsupport.cpp @@ -58,6 +58,7 @@ #include <utils/qtcassert.h> #include <utils/qtcprocess.h> +#include <QDir> #include <QFormLayout> #include <QLabel> #include <QVBoxLayout> diff --git a/src/plugins/qnx/qnxtoolchain.cpp b/src/plugins/qnx/qnxtoolchain.cpp index 895346febe..219c089e67 100644 --- a/src/plugins/qnx/qnxtoolchain.cpp +++ b/src/plugins/qnx/qnxtoolchain.cpp @@ -125,8 +125,7 @@ ToolChainConfigWidget *QnxToolChain::configurationWidget() void QnxToolChain::addToEnvironment(Environment &env) const { - if (env.value(QLatin1String("QNX_HOST")).isEmpty() - || env.value(QLatin1String("QNX_TARGET")).isEmpty()) + if (env.value("QNX_HOST").isEmpty() || env.value("QNX_TARGET").isEmpty()) setQnxEnvironment(env, QnxUtils::qnxEnvironment(m_sdpPath)); GccToolChain::addToEnvironment(env); diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 5da5372bd1..1b0128350d 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -397,7 +397,7 @@ public: bool expanded, bool active, bool hovered) const; - void drawLineAnnotation(QPainter &painter, const QTextBlock &block, qreal start, const QRect &eventRect); + void updateLineAnnotation(QPainter &painter, const QTextBlock &block, qreal start, const QRect &eventRect); void toggleBlockVisible(const QTextBlock &block); QRect foldBox(); @@ -3866,9 +3866,11 @@ QRectF TextEditorWidgetPrivate::getLastLineLineRect(const QTextBlock &block) return line.naturalTextRect().translated(contentOffset.x(), top).adjusted(0, 0, -1, -1); } -void TextEditorWidgetPrivate::drawLineAnnotation( +void TextEditorWidgetPrivate::updateLineAnnotation( QPainter &painter, const QTextBlock &block, qreal rightMargin, const QRect &eventRect) { + m_annotationRects.remove(block.blockNumber()); + if (!m_displaySettings.m_displayAnnotations) return; @@ -3912,16 +3914,17 @@ void TextEditorWidgetPrivate::drawLineAnnotation( boundingRect = QRectF(x, lineRect.top(), q->viewport()->width() - x, lineRect.height()); if (boundingRect.isEmpty()) break; + if (eventRect.intersects(boundingRect.toRect())) + mark->paintAnnotation(painter, &boundingRect, offset, itemOffset / 2, q->contentOffset()); - // paint annotation - mark->paintAnnotation(painter, &boundingRect, offset, itemOffset / 2, q->contentOffset()); x = boundingRect.right(); offset = itemOffset / 2; m_annotationRects[block.blockNumber()].append({boundingRect, mark}); } QRect updateRect(lineRect.toRect().topRight(), boundingRect.toRect().bottomRight()); - updateRect.setLeft(qMax(0, updateRect.left())); + updateRect.setLeft(qBound(0, updateRect.left(), q->viewport()->width() - 1)); + updateRect.setRight(qBound(0, updateRect.right(), q->viewport()->width() - 1)); if (!updateRect.isEmpty() && !eventRect.contains(updateRect)) q->viewport()->update(updateRect); } @@ -4425,10 +4428,8 @@ void TextEditorWidget::paintEvent(QPaintEvent *e) || d->m_blockSelection.positionColumn == d->m_blockSelection.anchorColumn) && blockSelectionCursorRect.isValid()) painter.fillRect(blockSelectionCursorRect, palette().text()); - - d->m_annotationRects.remove(block.blockNumber()); - d->drawLineAnnotation(painter, block, lineX < viewportRect.width() ? lineX : 0, er); } + d->updateLineAnnotation(painter, block, lineX < viewportRect.width() ? lineX : 0, er); offset.ry() += r.height(); diff --git a/src/plugins/welcome/welcomeplugin.cpp b/src/plugins/welcome/welcomeplugin.cpp index 848e0e6449..7cb62e6fc0 100644 --- a/src/plugins/welcome/welcomeplugin.cpp +++ b/src/plugins/welcome/welcomeplugin.cpp @@ -147,6 +147,7 @@ public: { setAutoFillBackground(true); setMinimumHeight(30); + setToolTip(m_openUrl); const QString fileName = QString(":/welcome/images/%1.png").arg(iconSource); const Icon icon({{fileName, Theme::Welcome_ForegroundPrimaryColor}}, Icon::Tint); @@ -191,7 +192,7 @@ public: QString m_iconSource; QString m_title; - QString m_openUrl; + const QString m_openUrl; QLabel *m_icon; QLabel *m_label; |