ProjectExplorer: Let user provide default for "run in terminal"

We enable the "Run in terminal" checkbox for all applications that
declare themselves console apps, but that's not necessarily what the
user wants. So let them opt out of this mechanism via a global setting.

[ChangeLog] There now is a global setting for "Run in terminal".

Change-Id: Ieeed72fdd01144d9aec0a7c7d4a12b9e5a94cd1d
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2019-03-12 15:19:56 +01:00
parent a6f0e564d4
commit 8c0037af52
9 changed files with 199 additions and 123 deletions

View File

@@ -84,8 +84,7 @@ void CMakeRunConfiguration::updateTargetInformation()
aspect<LocalEnvironmentAspect>()->buildEnvironmentHasChanged(); aspect<LocalEnvironmentAspect>()->buildEnvironmentHasChanged();
auto terminalAspect = aspect<TerminalAspect>(); auto terminalAspect = aspect<TerminalAspect>();
if (!terminalAspect->isUserSet()) terminalAspect->setUseTerminalHint(bti.usesTerminal);
terminalAspect->setUseTerminal(bti.usesTerminal);
} }
// Factory // Factory

View File

@@ -246,6 +246,8 @@ const char PROJECT_OPEN_LOCATIONS_CONTEXT_MENU[] = "Project.P.OpenLocation.CtxM
const char DEFAULT_BUILD_DIRECTORY_TEMPLATE[] = "../%{JS: Util.asciify(\"build-%{CurrentProject:Name}-%{CurrentKit:FileSystemName}-%{CurrentBuild:Name}\")}"; const char DEFAULT_BUILD_DIRECTORY_TEMPLATE[] = "../%{JS: Util.asciify(\"build-%{CurrentProject:Name}-%{CurrentKit:FileSystemName}-%{CurrentBuild:Name}\")}";
const char DEFAULT_BUILD_DIRECTORY_TEMPLATE_KEY[] = "Directories/BuildDirectory.Template"; const char DEFAULT_BUILD_DIRECTORY_TEMPLATE_KEY[] = "Directories/BuildDirectory.Template";
const char TERMINAL_MODE_SETTINGS_KEY[] = "ProjectExplorer/Settings/TerminalMode";
} // namespace Constants } // namespace Constants
@@ -1325,6 +1327,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
if (tmp < 0 || tmp > ProjectExplorerSettings::StopSameBuildDir) if (tmp < 0 || tmp > ProjectExplorerSettings::StopSameBuildDir)
tmp = Utils::HostOsInfo::isWindowsHost() ? 1 : 0; tmp = Utils::HostOsInfo::isWindowsHost() ? 1 : 0;
dd->m_projectExplorerSettings.stopBeforeBuild = ProjectExplorerSettings::StopBeforeBuild(tmp); dd->m_projectExplorerSettings.stopBeforeBuild = ProjectExplorerSettings::StopBeforeBuild(tmp);
dd->m_projectExplorerSettings.terminalMode = static_cast<TerminalMode>(s->value(
Constants::TERMINAL_MODE_SETTINGS_KEY, int(TerminalMode::Smart)).toInt());
dd->m_projectExplorerSettings.buildDirectoryTemplate dd->m_projectExplorerSettings.buildDirectoryTemplate
= s->value(Constants::DEFAULT_BUILD_DIRECTORY_TEMPLATE_KEY).toString(); = s->value(Constants::DEFAULT_BUILD_DIRECTORY_TEMPLATE_KEY).toString();
if (dd->m_projectExplorerSettings.buildDirectoryTemplate.isEmpty()) if (dd->m_projectExplorerSettings.buildDirectoryTemplate.isEmpty())
@@ -1908,6 +1912,8 @@ void ProjectExplorerPluginPrivate::savePersistentSettings()
s->setValue(QLatin1String("ProjectExplorer/Settings/AutoRestoreLastSession"), dd->m_projectExplorerSettings.autorestoreLastSession); s->setValue(QLatin1String("ProjectExplorer/Settings/AutoRestoreLastSession"), dd->m_projectExplorerSettings.autorestoreLastSession);
s->setValue(QLatin1String("ProjectExplorer/Settings/AddLibraryPathsToRunEnv"), dd->m_projectExplorerSettings.addLibraryPathsToRunEnv); s->setValue(QLatin1String("ProjectExplorer/Settings/AddLibraryPathsToRunEnv"), dd->m_projectExplorerSettings.addLibraryPathsToRunEnv);
s->setValue(QLatin1String("ProjectExplorer/Settings/PromptToStopRunControl"), dd->m_projectExplorerSettings.prompToStopRunControl); s->setValue(QLatin1String("ProjectExplorer/Settings/PromptToStopRunControl"), dd->m_projectExplorerSettings.prompToStopRunControl);
s->setValue(Constants::TERMINAL_MODE_SETTINGS_KEY,
int(dd->m_projectExplorerSettings.terminalMode));
s->setValue(QLatin1String("ProjectExplorer/Settings/AutomaticallyCreateRunConfigurations"), s->setValue(QLatin1String("ProjectExplorer/Settings/AutomaticallyCreateRunConfigurations"),
dd->m_projectExplorerSettings.automaticallyCreateRunConfigurations); dd->m_projectExplorerSettings.automaticallyCreateRunConfigurations);
s->setValue(QLatin1String("ProjectExplorer/Settings/EnvironmentId"), dd->m_projectExplorerSettings.environmentId.toByteArray()); s->setValue(QLatin1String("ProjectExplorer/Settings/EnvironmentId"), dd->m_projectExplorerSettings.environmentId.toByteArray());

View File

@@ -33,6 +33,8 @@
namespace ProjectExplorer { namespace ProjectExplorer {
namespace Internal { namespace Internal {
enum class TerminalMode { On, Off, Smart };
class ProjectExplorerSettings class ProjectExplorerSettings
{ {
public: public:
@@ -47,6 +49,7 @@ public:
bool automaticallyCreateRunConfigurations = true; bool automaticallyCreateRunConfigurations = true;
bool addLibraryPathsToRunEnv = true; bool addLibraryPathsToRunEnv = true;
StopBeforeBuild stopBeforeBuild = StopBeforeBuild::StopNone; StopBeforeBuild stopBeforeBuild = StopBeforeBuild::StopNone;
TerminalMode terminalMode = TerminalMode::Smart;
QString buildDirectoryTemplate; QString buildDirectoryTemplate;
// Add a UUid which is used to identify the development environment. // Add a UUid which is used to identify the development environment.
@@ -67,6 +70,7 @@ inline bool operator==(const ProjectExplorerSettings &p1, const ProjectExplorerS
&& p1.addLibraryPathsToRunEnv == p2.addLibraryPathsToRunEnv && p1.addLibraryPathsToRunEnv == p2.addLibraryPathsToRunEnv
&& p1.environmentId == p2.environmentId && p1.environmentId == p2.environmentId
&& p1.stopBeforeBuild == p2.stopBeforeBuild && p1.stopBeforeBuild == p2.stopBeforeBuild
&& p1.terminalMode == p2.terminalMode
&& p1.buildDirectoryTemplate == p2.buildDirectoryTemplate; && p1.buildDirectoryTemplate == p2.buildDirectoryTemplate;
} }

View File

@@ -105,6 +105,7 @@ ProjectExplorerSettings ProjectExplorerSettingsWidget::settings() const
m_settings.prompToStopRunControl = m_ui.promptToStopRunControlCheckBox->isChecked(); m_settings.prompToStopRunControl = m_ui.promptToStopRunControlCheckBox->isChecked();
m_settings.automaticallyCreateRunConfigurations = m_ui.automaticallyCreateRunConfiguration->isChecked(); m_settings.automaticallyCreateRunConfigurations = m_ui.automaticallyCreateRunConfiguration->isChecked();
m_settings.stopBeforeBuild = static_cast<ProjectExplorerSettings::StopBeforeBuild>(m_ui.stopBeforeBuildComboBox->currentIndex()); m_settings.stopBeforeBuild = static_cast<ProjectExplorerSettings::StopBeforeBuild>(m_ui.stopBeforeBuildComboBox->currentIndex());
m_settings.terminalMode = static_cast<TerminalMode>(m_ui.terminalModeComboBox->currentIndex());
m_settings.buildDirectoryTemplate = buildDirectoryTemplate(); m_settings.buildDirectoryTemplate = buildDirectoryTemplate();
return m_settings; return m_settings;
} }
@@ -120,6 +121,7 @@ void ProjectExplorerSettingsWidget::setSettings(const ProjectExplorerSettings &
m_ui.promptToStopRunControlCheckBox->setChecked(m_settings.prompToStopRunControl); m_ui.promptToStopRunControlCheckBox->setChecked(m_settings.prompToStopRunControl);
m_ui.automaticallyCreateRunConfiguration->setChecked(m_settings.automaticallyCreateRunConfigurations); m_ui.automaticallyCreateRunConfiguration->setChecked(m_settings.automaticallyCreateRunConfigurations);
m_ui.stopBeforeBuildComboBox->setCurrentIndex(static_cast<int>(m_settings.stopBeforeBuild)); m_ui.stopBeforeBuildComboBox->setCurrentIndex(static_cast<int>(m_settings.stopBeforeBuild));
m_ui.terminalModeComboBox->setCurrentIndex(static_cast<int>(m_settings.terminalMode));
setBuildDirectoryTemplate(pes.buildDirectoryTemplate); setBuildDirectoryTemplate(pes.buildDirectoryTemplate);
} }

View File

@@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>963</width> <width>987</width>
<height>564</height> <height>684</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
@@ -51,8 +51,54 @@
<property name="title"> <property name="title">
<string>Build and Run</string> <string>Build and Run</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QVBoxLayout" name="verticalLayout_3">
<item row="5" column="0"> <item>
<widget class="QCheckBox" name="saveAllFilesCheckBox">
<property name="text">
<string>Save all files before build</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="buildProjectBeforeDeployCheckBox">
<property name="text">
<string>Always build project before deploying it</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="deployProjectBeforeRunCheckBox">
<property name="text">
<string>Always deploy project before running it</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="addLibraryPathsToRunEnvCheckBox">
<property name="text">
<string>Add linker library search paths to run environment</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_1" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="promptToStopRunControlCheckBox"> <widget class="QCheckBox" name="promptToStopRunControlCheckBox">
<property name="toolTip"> <property name="toolTip">
<string>Asks before terminating the running application in response to clicking the stop button in Application Output.</string> <string>Asks before terminating the running application in response to clicking the stop button in Application Output.</string>
@@ -62,48 +108,27 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="0" colspan="2">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<item> <item>
<widget class="QCheckBox" name="jomCheckbox"> <widget class="QCheckBox" name="automaticallyCreateRunConfiguration">
<property name="whatsThis"> <property name="toolTip">
<string/> <string>Creates suitable run configurations automatically when setting up a new kit.</string>
</property> </property>
<property name="text"> <property name="text">
<string>Use jom instead of nmake</string> <string>Create suitable run configurations automatically</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="jomLabel"> <layout class="QFormLayout" name="formLayout">
<property name="text"> <item row="0" column="0">
<string>&lt;i&gt;jom&lt;/i&gt; is a drop-in replacement for &lt;i&gt;nmake&lt;/i&gt; which distributes the compilation process to multiple CPU cores. The latest binary is available at &lt;a href=&quot;http://download.qt.io/official_releases/jom/&quot;&gt;http://download.qt.io/official_releases/jom/&lt;/a&gt;. Disable it if you experience problems with your builds.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="indent">
<number>20</number>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="labelStopBeforeBuild"> <widget class="QLabel" name="labelStopBeforeBuild">
<property name="text"> <property name="text">
<string>Stop applications before building:</string> <string>Stop applications before building:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QComboBox" name="stopBeforeBuildComboBox"> <widget class="QComboBox" name="stopBeforeBuildComboBox">
<item> <item>
@@ -143,24 +168,85 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="3" column="0"> <item row="1" column="0">
<widget class="QCheckBox" name="addLibraryPathsToRunEnvCheckBox"> <widget class="QLabel" name="terminalModeLabel">
<property name="text"> <property name="text">
<string>Add linker library search paths to run environment</string> <string>Default for &quot;Run in terminal&quot;:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0"> <item row="1" column="1">
<widget class="QCheckBox" name="automaticallyCreateRunConfiguration"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="toolTip"> <item>
<string>Creates suitable run configurations automatically when setting up a new kit.</string> <widget class="QComboBox" name="terminalModeComboBox">
<item>
<property name="text">
<string>Enabled</string>
</property>
</item>
<item>
<property name="text">
<string>Disabled</string>
</property>
</item>
<item>
<property name="text">
<string>Deduced From Project</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="jomCheckbox">
<property name="whatsThis">
<string/>
</property> </property>
<property name="text"> <property name="text">
<string>Create suitable run configurations automatically</string> <string>Use jom instead of nmake</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="0" colspan="2"> <item>
<widget class="QLabel" name="jomLabel">
<property name="text">
<string>&lt;i&gt;jom&lt;/i&gt; is a drop-in replacement for &lt;i&gt;nmake&lt;/i&gt; which distributes the compilation process to multiple CPU cores. The latest binary is available at &lt;a href=&quot;http://download.qt.io/official_releases/jom/&quot;&gt;http://download.qt.io/official_releases/jom/&lt;/a&gt;. Disable it if you experience problems with your builds.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="indent">
<number>20</number>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="topMargin"> <property name="topMargin">
<number>12</number> <number>12</number>
@@ -184,45 +270,6 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="1" column="0">
<widget class="QCheckBox" name="buildProjectBeforeDeployCheckBox">
<property name="text">
<string>Always build project before deploying it</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="saveAllFilesCheckBox">
<property name="text">
<string>Save all files before build</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QWidget" name="widget_1" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="deployProjectBeforeRunCheckBox">
<property name="text">
<string>Always deploy project before running it</string>
</property>
</widget>
</item>
</layout> </layout>
<zorder>widget_1</zorder> <zorder>widget_1</zorder>
<zorder>automaticallyCreateRunConfiguration</zorder> <zorder>automaticallyCreateRunConfiguration</zorder>

View File

@@ -56,6 +56,9 @@ TerminalAspect::TerminalAspect()
setDisplayName(tr("Terminal")); setDisplayName(tr("Terminal"));
setId("TerminalAspect"); setId("TerminalAspect");
setSettingsKey("RunConfiguration.UseTerminal"); setSettingsKey("RunConfiguration.UseTerminal");
calculateUseTerminal();
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
this, &TerminalAspect::calculateUseTerminal);
} }
void TerminalAspect::addToConfigurationLayout(QFormLayout *layout) void TerminalAspect::addToConfigurationLayout(QFormLayout *layout)
@@ -90,13 +93,16 @@ void TerminalAspect::toMap(QVariantMap &data) const
data.insert(settingsKey(), m_useTerminal); data.insert(settingsKey(), m_useTerminal);
} }
bool TerminalAspect::useTerminal() const void TerminalAspect::calculateUseTerminal()
{ {
return m_useTerminal; if (m_userSet)
return;
bool useTerminal;
switch (ProjectExplorerPlugin::projectExplorerSettings().terminalMode) {
case Internal::TerminalMode::On: useTerminal = true; break;
case Internal::TerminalMode::Off: useTerminal = false; break;
case Internal::TerminalMode::Smart: useTerminal = m_useTerminalHint;
} }
void TerminalAspect::setUseTerminal(bool useTerminal)
{
if (m_useTerminal != useTerminal) { if (m_useTerminal != useTerminal) {
m_useTerminal = useTerminal; m_useTerminal = useTerminal;
emit changed(); emit changed();
@@ -105,6 +111,17 @@ void TerminalAspect::setUseTerminal(bool useTerminal)
m_checkBox->setChecked(m_useTerminal); m_checkBox->setChecked(m_useTerminal);
} }
bool TerminalAspect::useTerminal() const
{
return m_useTerminal;
}
void TerminalAspect::setUseTerminalHint(bool hint)
{
m_useTerminalHint = hint;
calculateUseTerminal();
}
bool TerminalAspect::isUserSet() const bool TerminalAspect::isUserSet() const
{ {
return m_userSet; return m_userSet;

View File

@@ -46,7 +46,7 @@ public:
void addToConfigurationLayout(QFormLayout *layout) override; void addToConfigurationLayout(QFormLayout *layout) override;
bool useTerminal() const; bool useTerminal() const;
void setUseTerminal(bool useTerminal); void setUseTerminalHint(bool useTerminal);
bool isUserSet() const; bool isUserSet() const;
@@ -54,6 +54,9 @@ private:
void fromMap(const QVariantMap &map) override; void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override; void toMap(QVariantMap &map) const override;
void calculateUseTerminal();
bool m_useTerminalHint = false;
bool m_useTerminal = false; bool m_useTerminal = false;
bool m_userSet = false; bool m_userSet = false;
QPointer<QCheckBox> m_checkBox; // Owned by RunConfigWidget QPointer<QCheckBox> m_checkBox; // Owned by RunConfigWidget

View File

@@ -145,8 +145,7 @@ void QbsRunConfiguration::updateTargetInformation()
BuildTargetInfo bti = buildTargetInfo(); BuildTargetInfo bti = buildTargetInfo();
const FileName executable = executableToRun(bti); const FileName executable = executableToRun(bti);
auto terminalAspect = aspect<TerminalAspect>(); auto terminalAspect = aspect<TerminalAspect>();
if (!terminalAspect->isUserSet()) terminalAspect->setUseTerminalHint(bti.usesTerminal);
terminalAspect->setUseTerminal(bti.usesTerminal);
aspect<ExecutableAspect>()->setExecutable(executable); aspect<ExecutableAspect>()->setExecutable(executable);

View File

@@ -107,8 +107,7 @@ void DesktopQmakeRunConfiguration::updateTargetInformation()
wda->pathChooser()->setBaseFileName(target()->project()->projectDirectory()); wda->pathChooser()->setBaseFileName(target()->project()->projectDirectory());
auto terminalAspect = aspect<TerminalAspect>(); auto terminalAspect = aspect<TerminalAspect>();
if (!terminalAspect->isUserSet()) terminalAspect->setUseTerminalHint(bti.usesTerminal);
terminalAspect->setUseTerminal(bti.usesTerminal);
aspect<ExecutableAspect>()->setExecutable(bti.targetFilePath); aspect<ExecutableAspect>()->setExecutable(bti.targetFilePath);
} }