1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25
26 #include "customexecutablerunconfiguration.h"
27
28 #include "abi.h"
29 #include "buildconfiguration.h"
30 #include "devicesupport/devicemanager.h"
31 #include "environmentaspect.h"
32 #include "localenvironmentaspect.h"
33 #include "project.h"
34 #include "runcontrol.h"
35 #include "target.h"
36
37 #include <coreplugin/icore.h>
38
39 #include <utils/detailswidget.h>
40 #include <utils/pathchooser.h>
41 #include <utils/stringutils.h>
42 #include <utils/variablechooser.h>
43
44 #include <QDialog>
45 #include <QDialogButtonBox>
46 #include <QDir>
47 #include <QFormLayout>
48 #include <QKeyEvent>
49 #include <QLabel>
50 #include <QLineEdit>
51 #include <QPushButton>
52 #include <QVBoxLayout>
53
54 using namespace Utils;
55
56 namespace ProjectExplorer {
57
58 const char CUSTOM_EXECUTABLE_RUNCONFIG_ID[] = "ProjectExplorer.CustomExecutableRunConfiguration";
59
60 // CustomExecutableRunConfiguration
61
CustomExecutableRunConfiguration(Target * target)62 CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(Target *target)
63 : CustomExecutableRunConfiguration(target, CUSTOM_EXECUTABLE_RUNCONFIG_ID)
64 {}
65
CustomExecutableRunConfiguration(Target * target,Utils::Id id)66 CustomExecutableRunConfiguration::CustomExecutableRunConfiguration(Target *target, Utils::Id id)
67 : RunConfiguration(target, id)
68 {
69 auto envAspect = addAspect<LocalEnvironmentAspect>(target);
70
71 auto exeAspect = addAspect<ExecutableAspect>();
72 exeAspect->setSettingsKey("ProjectExplorer.CustomExecutableRunConfiguration.Executable");
73 exeAspect->setDisplayStyle(StringAspect::PathChooserDisplay);
74 exeAspect->setHistoryCompleter("Qt.CustomExecutable.History");
75 exeAspect->setExpectedKind(PathChooser::ExistingCommand);
76 exeAspect->setEnvironment(envAspect->environment());
77
78 addAspect<ArgumentsAspect>();
79 addAspect<WorkingDirectoryAspect>();
80 addAspect<TerminalAspect>();
81
82 connect(envAspect, &EnvironmentAspect::environmentChanged,
83 this, [exeAspect, envAspect] { exeAspect->setEnvironment(envAspect->environment()); });
84
85 setDefaultDisplayName(defaultDisplayName());
86 }
87
rawExecutable() const88 QString CustomExecutableRunConfiguration::rawExecutable() const
89 {
90 return aspect<ExecutableAspect>()->executable().toString();
91 }
92
isEnabled() const93 bool CustomExecutableRunConfiguration::isEnabled() const
94 {
95 return true;
96 }
97
runnable() const98 Runnable CustomExecutableRunConfiguration::runnable() const
99 {
100 FilePath workingDirectory =
101 aspect<WorkingDirectoryAspect>()->workingDirectory(macroExpander());
102
103 Runnable r;
104 r.setCommandLine(commandLine());
105 r.environment = aspect<EnvironmentAspect>()->environment();
106 r.workingDirectory = workingDirectory.toString();
107 r.device = DeviceManager::defaultDesktopDevice();
108
109 if (!r.executable.isEmpty()) {
110 const QString expanded = macroExpander()->expand(r.executable.toString());
111 r.executable = r.environment.searchInPath(expanded, {workingDirectory});
112 }
113
114 return r;
115 }
116
defaultDisplayName() const117 QString CustomExecutableRunConfiguration::defaultDisplayName() const
118 {
119 if (rawExecutable().isEmpty())
120 return tr("Custom Executable");
121 else
122 return tr("Run %1").arg(QDir::toNativeSeparators(rawExecutable()));
123 }
124
checkForIssues() const125 Tasks CustomExecutableRunConfiguration::checkForIssues() const
126 {
127 Tasks tasks;
128 if (rawExecutable().isEmpty()) {
129 tasks << createConfigurationIssue(tr("You need to set an executable in the custom run "
130 "configuration."));
131 }
132 return tasks;
133 }
134
135 // Factories
136
CustomExecutableRunConfigurationFactory()137 CustomExecutableRunConfigurationFactory::CustomExecutableRunConfigurationFactory() :
138 FixedRunConfigurationFactory(CustomExecutableRunConfiguration::tr("Custom Executable"))
139 {
140 registerRunConfiguration<CustomExecutableRunConfiguration>(CUSTOM_EXECUTABLE_RUNCONFIG_ID);
141 }
142
CustomExecutableRunWorkerFactory()143 CustomExecutableRunWorkerFactory::CustomExecutableRunWorkerFactory()
144 {
145 setProduct<SimpleTargetRunner>();
146 addSupportedRunMode(Constants::NORMAL_RUN_MODE);
147 addSupportedRunConfig(CUSTOM_EXECUTABLE_RUNCONFIG_ID);
148 }
149
150 } // namespace ProjectExplorer
151