aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
diff options
context:
space:
mode:
authorhjk <hjk@qt.io>2018-04-24 16:00:53 +0200
committerhjk <hjk@qt.io>2018-04-26 13:58:00 +0000
commit98b026f9a97d3a2311eb6ec5e88b20dbd76f3e26 (patch)
treec0e48c11322a5028d5a8035ceba16d0c3f0eaaf8 /src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
parent219e23332e5e21d3e4e1a9334bf3f5ef1d485b59 (diff)
ProjectExplorer: Rework CustomExecutableRunConfiguration
Split the run config widget according to the two use cases (direct apply, delayed apply). As basically most data members and important logic was not shared, the double-use made the CustomExecutableRunConfiguration implementation needlessly complicated. Change-Id: If92ba22bae31378bae29049e0d27095b2bbd6090 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Diffstat (limited to 'src/plugins/projectexplorer/customexecutablerunconfiguration.cpp')
-rw-r--r--src/plugins/projectexplorer/customexecutablerunconfiguration.cpp271
1 files changed, 139 insertions, 132 deletions
diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
index 655aa7ee30..da6e50df4b 100644
--- a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
+++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp
@@ -27,110 +27,125 @@
#include "abi.h"
#include "buildconfiguration.h"
-#include "customexecutableconfigurationwidget.h"
#include "devicesupport/devicemanager.h"
+#include "environmentaspect.h"
#include "localenvironmentaspect.h"
#include "project.h"
#include "runconfigurationaspects.h"
#include "target.h"
#include <coreplugin/icore.h>
+#include <coreplugin/variablechooser.h>
-#include <utils/qtcprocess.h>
+#include <utils/detailswidget.h>
+#include <utils/pathchooser.h>
#include <utils/stringutils.h>
#include <QDialog>
#include <QDialogButtonBox>
#include <QDir>
+#include <QFormLayout>
#include <QKeyEvent>
#include <QLabel>
+#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
-using namespace ProjectExplorer::Internal;
+using namespace Utils;
namespace ProjectExplorer {
const char CUSTOM_EXECUTABLE_ID[] = "ProjectExplorer.CustomExecutableRunConfiguration";
-const char EXECUTABLE_KEY[] = "ProjectExplorer.CustomExecutableRunConfiguration.Executable";
-// Dialog embedding the CustomExecutableConfigurationWidget
-// prompting the user to complete the configuration.
+// Dialog prompting the user to complete the configuration.
+
class CustomExecutableDialog : public QDialog
{
- Q_OBJECT
public:
- explicit CustomExecutableDialog(CustomExecutableRunConfiguration *rc, QWidget *parent = 0);
-
- void accept();
+ explicit CustomExecutableDialog(RunConfiguration *rc);
- bool event(QEvent *event);
+ void accept() override;
+ bool event(QEvent *event) override;
private:
- void changed()
- {
- setOkButtonEnabled(m_widget->isValid());
- }
-
- inline void setOkButtonEnabled(bool e)
- {
- m_dialogButtonBox->button(QDialogButtonBox::Ok)->setEnabled(e);
+ void changed() {
+ bool isValid = !m_executableChooser->rawPath().isEmpty();
+ m_dialogButtonBox->button(QDialogButtonBox::Ok)->setEnabled(isValid);
}
- QDialogButtonBox *m_dialogButtonBox;
- CustomExecutableConfigurationWidget *m_widget;
+private:
+ void environmentWasChanged();
+
+ QDialogButtonBox *m_dialogButtonBox = nullptr;
+ RunConfiguration *m_rc = nullptr;
+ ArgumentsAspect m_arguments;
+ WorkingDirectoryAspect m_workingDirectory;
+ TerminalAspect m_terminal;
+ PathChooser *m_executableChooser = nullptr;
};
-CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(Target *target, Core::Id id)
- : RunConfiguration(target, id)
+CustomExecutableDialog::CustomExecutableDialog(RunConfiguration *rc)
+ : QDialog(Core::ICore::dialogParent()),
+ m_rc(rc),
+ m_arguments(rc, rc->extraAspect<ArgumentsAspect>()->settingsKey()),
+ m_workingDirectory(rc, rc->extraAspect<WorkingDirectoryAspect>()->settingsKey()),
+ m_terminal(rc, rc->extraAspect<TerminalAspect>()->settingsKey())
{
- addExtraAspect(new LocalEnvironmentAspect(this, LocalEnvironmentAspect::BaseEnvironmentModifier()));
- addExtraAspect(new ArgumentsAspect(this, "ProjectExplorer.CustomExecutableRunConfiguration.Arguments"));
- addExtraAspect(new TerminalAspect(this, "ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal"));
- addExtraAspect(new WorkingDirectoryAspect(this, "ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory"));
- setDefaultDisplayName(defaultDisplayName());
-}
+ auto vbox = new QVBoxLayout(this);
+ vbox->addWidget(new QLabel(tr("Could not find the executable, please specify one.")));
-CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(Target *target)
- : CustomExecutableRunConfiguration(target, CUSTOM_EXECUTABLE_ID)
-{
-}
+ auto layout = new QFormLayout;
+ layout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
+ layout->setMargin(0);
-// Note: Qt4Project deletes all empty customexecrunconfigs for which isConfigured() == false.
-CustomExecutableRunConfiguration::~CustomExecutableRunConfiguration()
-{
- if (m_dialog) {
- emit configurationFinished();
- disconnect(m_dialog, &QDialog::finished,
- this, &CustomExecutableRunConfiguration::configurationDialogFinished);
- }
- delete m_dialog;
-}
+ auto detailsContainer = new DetailsWidget(this);
+ detailsContainer->setState(DetailsWidget::NoSummary);
+ vbox->addWidget(detailsContainer);
-CustomExecutableDialog::CustomExecutableDialog(CustomExecutableRunConfiguration *rc, QWidget *parent)
- : QDialog(parent)
- , m_dialogButtonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel))
-{
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
- QVBoxLayout *layout = new QVBoxLayout(this);
- QLabel *label = new QLabel(tr("Could not find the executable, please specify one."));
- label->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
- layout->addWidget(label);
- m_widget = new CustomExecutableConfigurationWidget(rc, CustomExecutableConfigurationWidget::DelayedApply);
- m_widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
- connect(m_widget, &CustomExecutableConfigurationWidget::validChanged,
- this, &CustomExecutableDialog::changed);
- layout->addWidget(m_widget);
- setOkButtonEnabled(false);
+ m_dialogButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ m_dialogButtonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
connect(m_dialogButtonBox, &QDialogButtonBox::accepted, this, &CustomExecutableDialog::accept);
connect(m_dialogButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
- layout->addWidget(m_dialogButtonBox);
- layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
+ vbox->addWidget(m_dialogButtonBox);
+ vbox->setSizeConstraint(QLayout::SetMinAndMaxSize);
+
+ auto detailsWidget = new QWidget(detailsContainer);
+ detailsContainer->setWidget(detailsWidget);
+ detailsWidget->setLayout(layout);
+
+ m_executableChooser = new PathChooser(this);
+ m_executableChooser->setHistoryCompleter("Qt.CustomExecutable.History");
+ m_executableChooser->setExpectedKind(PathChooser::ExistingCommand);
+ m_executableChooser->setPath(rc->extraAspect<ExecutableAspect>()->executable().toString());
+ layout->addRow(tr("Executable:"), m_executableChooser);
+ connect(m_executableChooser, &PathChooser::rawPathChanged,
+ this, &CustomExecutableDialog::changed);
+
+ m_arguments.copyFrom(rc->extraAspect<ArgumentsAspect>());
+ m_arguments.addToConfigurationLayout(layout);
+
+ m_workingDirectory.copyFrom(rc->extraAspect<WorkingDirectoryAspect>());
+ m_workingDirectory.addToConfigurationLayout(layout);
+
+ m_terminal.copyFrom(rc->extraAspect<TerminalAspect>());
+ m_terminal.addToConfigurationLayout(layout);
+
+ auto enviromentAspect = rc->extraAspect<EnvironmentAspect>();
+ connect(enviromentAspect, &EnvironmentAspect::environmentChanged,
+ this, &CustomExecutableDialog::environmentWasChanged);
+ environmentWasChanged();
+
+ Core::VariableChooser::addSupportForChildWidgets(this, m_rc->macroExpander());
}
void CustomExecutableDialog::accept()
{
- m_widget->apply();
+ auto executable = FileName::fromString(m_executableChooser->path());
+ m_rc->extraAspect<ExecutableAspect>()->setExecutable(executable);
+ m_rc->extraAspect<WorkingDirectoryAspect>()->copyFrom(&m_workingDirectory);
+ m_rc->extraAspect<ArgumentsAspect>()->copyFrom(&m_arguments);
+ m_rc->extraAspect<TerminalAspect>()->copyFrom(&m_terminal);
+
QDialog::accept();
}
@@ -146,8 +161,55 @@ bool CustomExecutableDialog::event(QEvent *event)
return QDialog::event(event);
}
+void CustomExecutableDialog::environmentWasChanged()
+{
+ auto aspect = m_rc->extraAspect<EnvironmentAspect>();
+ QTC_ASSERT(aspect, return);
+ m_executableChooser->setEnvironment(aspect->environment());
+}
+
+
// CustomExecutableRunConfiguration
+CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(Target *target)
+ : CustomExecutableRunConfiguration(target, CUSTOM_EXECUTABLE_ID)
+{}
+
+CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(Target *target, Core::Id id)
+ : RunConfiguration(target, id)
+{
+ auto envAspect = new LocalEnvironmentAspect(this, LocalEnvironmentAspect::BaseEnvironmentModifier());
+ addExtraAspect(envAspect);
+
+ auto exeAspect = new ExecutableAspect(this);
+ exeAspect->setSettingsKey("ProjectExplorer.CustomExecutableRunConfiguration.Executable");
+ exeAspect->setDisplayStyle(BaseStringAspect::PathChooserDisplay);
+ exeAspect->setHistoryCompleter("Qt.CustomExecutable.History");
+ exeAspect->setExpectedKind(PathChooser::ExistingCommand);
+ exeAspect->setEnvironment(envAspect->environment());
+ addExtraAspect(exeAspect);
+
+ addExtraAspect(new ArgumentsAspect(this, "ProjectExplorer.CustomExecutableRunConfiguration.Arguments"));
+ addExtraAspect(new TerminalAspect(this, "ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal"));
+ addExtraAspect(new WorkingDirectoryAspect(this, "ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory"));
+
+ connect(envAspect, &EnvironmentAspect::environmentChanged,
+ this, [exeAspect, envAspect] { exeAspect->setEnvironment(envAspect->environment()); });
+
+ setDefaultDisplayName(defaultDisplayName());
+}
+
+// Note: Qt4Project deletes all empty customexecrunconfigs for which isConfigured() == false.
+CustomExecutableRunConfiguration::~CustomExecutableRunConfiguration()
+{
+ if (m_dialog) {
+ emit configurationFinished();
+ disconnect(m_dialog, &QDialog::finished,
+ this, &CustomExecutableRunConfiguration::configurationDialogFinished);
+ }
+ delete m_dialog;
+}
+
RunConfiguration::ConfigurationState CustomExecutableRunConfiguration::ensureConfigured(QString *errorMessage)
{
if (m_dialog) {// uhm already shown
@@ -157,7 +219,7 @@ RunConfiguration::ConfigurationState CustomExecutableRunConfiguration::ensureCon
return UnConfigured;
}
- m_dialog = new CustomExecutableDialog(this, Core::ICore::mainWindow());
+ m_dialog = new CustomExecutableDialog(this);
connect(m_dialog, &QDialog::finished,
this, &CustomExecutableRunConfiguration::configurationDialogFinished);
m_dialog->setWindowTitle(displayName()); // pretty pointless
@@ -174,95 +236,42 @@ void CustomExecutableRunConfiguration::configurationDialogFinished()
emit configurationFinished();
}
-// Search the executable in the path.
-bool CustomExecutableRunConfiguration::validateExecutable(QString *executable, QString *errorMessage) const
-{
- if (executable)
- executable->clear();
- if (m_executable.isEmpty()) {
- if (errorMessage)
- *errorMessage = tr("No executable.");
- return false;
- }
- Utils::Environment env;
- EnvironmentAspect *aspect = extraAspect<EnvironmentAspect>();
- if (aspect)
- env = aspect->environment();
- const Utils::FileName exec = env.searchInPath(macroExpander()->expand(m_executable),
- {extraAspect<WorkingDirectoryAspect>()->workingDirectory()});
- if (exec.isEmpty()) {
- if (errorMessage)
- *errorMessage = tr("The executable\n%1\ncannot be found in the path.").
- arg(QDir::toNativeSeparators(m_executable));
- return false;
- }
- if (executable)
- *executable = exec.toString();
- return true;
-}
-
-QString CustomExecutableRunConfiguration::executable() const
-{
- QString result;
- validateExecutable(&result);
- return result;
-}
-
QString CustomExecutableRunConfiguration::rawExecutable() const
{
- return m_executable;
+ return extraAspect<ExecutableAspect>()->executable().toString();
}
bool CustomExecutableRunConfiguration::isConfigured() const
{
- return !m_executable.isEmpty();
+ return !rawExecutable().isEmpty();
}
Runnable CustomExecutableRunConfiguration::runnable() const
{
+ FileName workingDirectory = extraAspect<WorkingDirectoryAspect>()->workingDirectory();
+
StandardRunnable r;
- r.executable = executable();
+ r.executable = extraAspect<ExecutableAspect>()->executable().toString();
r.commandLineArguments = extraAspect<ArgumentsAspect>()->arguments();
- r.environment = extraAspect<LocalEnvironmentAspect>()->environment();
+ r.environment = extraAspect<EnvironmentAspect>()->environment();
r.runMode = extraAspect<TerminalAspect>()->runMode();
+ r.workingDirectory = workingDirectory.toString();
r.device = DeviceManager::instance()->defaultDevice(Constants::DESKTOP_DEVICE_TYPE);
+
+ if (!r.executable.isEmpty()) {
+ QString expanded = macroExpander()->expand(r.executable);
+ r.executable = r.environment.searchInPath(expanded, {workingDirectory}).toString();
+ }
+
return r;
}
QString CustomExecutableRunConfiguration::defaultDisplayName() const
{
- if (m_executable.isEmpty())
+ if (rawExecutable().isEmpty())
return tr("Custom Executable");
else
- return tr("Run %1").arg(QDir::toNativeSeparators(m_executable));
-}
-
-QVariantMap CustomExecutableRunConfiguration::toMap() const
-{
- QVariantMap map(RunConfiguration::toMap());
- map.insert(QLatin1String(EXECUTABLE_KEY), m_executable);
- return map;
-}
-
-bool CustomExecutableRunConfiguration::fromMap(const QVariantMap &map)
-{
- m_executable = map.value(QLatin1String(EXECUTABLE_KEY)).toString();
- setDefaultDisplayName(defaultDisplayName());
- return RunConfiguration::fromMap(map);
-}
-
-void CustomExecutableRunConfiguration::setExecutable(const QString &executable)
-{
- if (executable == m_executable)
- return;
- m_executable = executable;
- setDefaultDisplayName(defaultDisplayName());
- emit changed();
-}
-
-QWidget *CustomExecutableRunConfiguration::createConfigurationWidget()
-{
- return new CustomExecutableConfigurationWidget(this, CustomExecutableConfigurationWidget::InstantApply);
+ return tr("Run %1").arg(QDir::toNativeSeparators(rawExecutable()));
}
Abi CustomExecutableRunConfiguration::abi() const
@@ -279,5 +288,3 @@ CustomExecutableRunConfigurationFactory::CustomExecutableRunConfigurationFactory
}
} // namespace ProjectExplorer
-
-#include "customexecutablerunconfiguration.moc"