qmlprojectruncontrol.cpp 8.3 KB
Newer Older
Kai Koehne's avatar
Kai Koehne committed
1 2 3 4
/**************************************************************************
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
Kai Koehne's avatar
Kai Koehne committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
Kai Koehne's avatar
Kai Koehne committed
8 9 10 11
**
**
** GNU Lesser General Public License Usage
**
hjk's avatar
hjk committed
12 13 14 15 16 17
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Kai Koehne's avatar
Kai Koehne committed
18
**
con's avatar
con committed
19
** In addition, as a special exception, Nokia gives you certain additional
hjk's avatar
hjk committed
20
** rights. These rights are described in the Nokia Qt LGPL Exception
con's avatar
con committed
21 22
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
23 24 25 26 27
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
con's avatar
con committed
28
** If you have questions regarding the use of this file, please contact
29
** Nokia at qt-info@nokia.com.
Kai Koehne's avatar
Kai Koehne committed
30 31 32 33 34 35 36
**
**************************************************************************/

#include "qmlprojectruncontrol.h"
#include "qmlprojectrunconfiguration.h"
#include <coreplugin/icore.h>
#include <projectexplorer/projectexplorerconstants.h>
37 38
#include <projectexplorer/target.h>
#include <projectexplorer/project.h>
39
#include <projectexplorer/projectexplorer.h>
Kai Koehne's avatar
Kai Koehne committed
40 41
#include <utils/qtcassert.h>

Lasse Holmstedt's avatar
Lasse Holmstedt committed
42 43
#include <debugger/debuggerrunner.h>
#include <debugger/debuggerplugin.h>
44
#include <debugger/debuggerconstants.h>
Friedemann Kleint's avatar
Friedemann Kleint committed
45
#include <debugger/debuggerstartparameters.h>
Daniel Teske's avatar
Daniel Teske committed
46
#include <qtsupport/baseqtversion.h>
47
#include <qtsupport/qmlobservertool.h>
48

49
#include <qmlprojectmanager/qmlprojectplugin.h>
50

51
using namespace ProjectExplorer;
Kai Koehne's avatar
Kai Koehne committed
52 53

namespace QmlProjectManager {
54

Kai Koehne's avatar
Kai Koehne committed
55 56
namespace Internal {

57
QmlProjectRunControl::QmlProjectRunControl(QmlProjectRunConfiguration *runConfiguration, RunMode mode)
dt's avatar
dt committed
58
    : RunControl(runConfiguration, mode)
Kai Koehne's avatar
Kai Koehne committed
59
{
60
    m_applicationLauncher.setEnvironment(runConfiguration->environment());
Kai Koehne's avatar
Kai Koehne committed
61 62
    m_applicationLauncher.setWorkingDirectory(runConfiguration->workingDirectory());

63
    if (mode == NormalRunMode) {
64 65 66 67
        m_executable = runConfiguration->viewerPath();
    } else {
        m_executable = runConfiguration->observerPath();
    }
Kai Koehne's avatar
Kai Koehne committed
68
    m_commandLineArguments = runConfiguration->viewerArguments();
69
    m_mainQmlFile = runConfiguration->mainScript();
Kai Koehne's avatar
Kai Koehne committed
70

con's avatar
con committed
71 72
    connect(&m_applicationLauncher, SIGNAL(appendMessage(QString,Utils::OutputFormat)),
            this, SLOT(slotAppendMessage(QString, Utils::OutputFormat)));
Kai Koehne's avatar
Kai Koehne committed
73 74 75 76 77 78
    connect(&m_applicationLauncher, SIGNAL(processExited(int)),
            this, SLOT(processExited(int)));
    connect(&m_applicationLauncher, SIGNAL(bringToForegroundRequested(qint64)),
            this, SLOT(slotBringApplicationToForeground(qint64)));
}

79
QmlProjectRunControl::~QmlProjectRunControl()
Kai Koehne's avatar
Kai Koehne committed
80
{
81
    stop();
Kai Koehne's avatar
Kai Koehne committed
82 83
}

84
void QmlProjectRunControl::start()
Kai Koehne's avatar
Kai Koehne committed
85
{
86
    m_applicationLauncher.start(ApplicationLauncher::Gui, m_executable,
Kai Koehne's avatar
Kai Koehne committed
87
                                m_commandLineArguments);
88
    setApplicationProcessHandle(ProcessHandle(m_applicationLauncher.applicationPID()));
Kai Koehne's avatar
Kai Koehne committed
89
    emit started();
dt's avatar
dt committed
90
    QString msg = tr("Starting %1 %2\n")
91
        .arg(QDir::toNativeSeparators(m_executable), m_commandLineArguments);
con's avatar
con committed
92
    appendMessage(msg, Utils::NormalMessageFormat);
Kai Koehne's avatar
Kai Koehne committed
93 94
}

95
RunControl::StopResult QmlProjectRunControl::stop()
Kai Koehne's avatar
Kai Koehne committed
96 97
{
    m_applicationLauncher.stop();
98
    return StoppedSynchronously;
Kai Koehne's avatar
Kai Koehne committed
99 100
}

101
bool QmlProjectRunControl::isRunning() const
Kai Koehne's avatar
Kai Koehne committed
102 103 104 105
{
    return m_applicationLauncher.isRunning();
}

106
QIcon QmlProjectRunControl::icon() const
107 108 109 110
{
    return QIcon(ProjectExplorer::Constants::ICON_RUN_SMALL);
}

111
void QmlProjectRunControl::slotBringApplicationToForeground(qint64 pid)
Kai Koehne's avatar
Kai Koehne committed
112 113 114 115
{
    bringApplicationToForeground(pid);
}

116
void QmlProjectRunControl::slotAppendMessage(const QString &line, Utils::OutputFormat format)
Kai Koehne's avatar
Kai Koehne committed
117
{
118
    appendMessage(line, format);
Kai Koehne's avatar
Kai Koehne committed
119 120
}

121
void QmlProjectRunControl::processExited(int exitCode)
Kai Koehne's avatar
Kai Koehne committed
122
{
dt's avatar
dt committed
123
    QString msg = tr("%1 exited with code %2\n")
124
        .arg(QDir::toNativeSeparators(m_executable)).arg(exitCode);
con's avatar
con committed
125
    appendMessage(msg, exitCode ? Utils::ErrorMessageFormat : Utils::NormalMessageFormat);
Kai Koehne's avatar
Kai Koehne committed
126 127 128
    emit finished();
}

129 130 131 132 133
QString QmlProjectRunControl::mainQmlFile() const
{
    return m_mainQmlFile;
}

134
QmlProjectRunControlFactory::QmlProjectRunControlFactory(QObject *parent)
Kai Koehne's avatar
Kai Koehne committed
135 136 137 138
    : IRunControlFactory(parent)
{
}

139
QmlProjectRunControlFactory::~QmlProjectRunControlFactory()
Kai Koehne's avatar
Kai Koehne committed
140 141 142
{
}

143
bool QmlProjectRunControlFactory::canRun(RunConfiguration *runConfiguration,
144
                                         RunMode mode) const
Kai Koehne's avatar
Kai Koehne committed
145
{
146 147
    QmlProjectRunConfiguration *config =
        qobject_cast<QmlProjectRunConfiguration*>(runConfiguration);
148 149
    if (!config)
        return false;
150
    if (mode == NormalRunMode)
151
        return !config->viewerPath().isEmpty();
152
    if (mode != DebugRunMode)
153
        return false;
154

155 156
    if (!Debugger::DebuggerPlugin::isActiveDebugLanguage(Debugger::QmlLanguage))
        return false;
Lasse Holmstedt's avatar
Lasse Holmstedt committed
157

158 159 160 161 162 163 164 165
    if (!config->observerPath().isEmpty())
        return true;
    if (!config->qtVersion())
        return false;
    if (!config->qtVersion()->needsQmlDebuggingLibrary())
        return true;
    if (QtSupport::QmlObserverTool::canBuild(config->qtVersion()))
        return true;
Lasse Holmstedt's avatar
Lasse Holmstedt committed
166
    return false;
Kai Koehne's avatar
Kai Koehne committed
167 168
}

169
RunControl *QmlProjectRunControlFactory::create(RunConfiguration *runConfiguration,
170
                                                RunMode mode)
Kai Koehne's avatar
Kai Koehne committed
171 172
{
    QTC_ASSERT(canRun(runConfiguration, mode), return 0);
Lasse Holmstedt's avatar
Lasse Holmstedt committed
173
    QmlProjectRunConfiguration *config = qobject_cast<QmlProjectRunConfiguration *>(runConfiguration);
174 175 176 177 178 179 180 181 182 183 184 185

    QList<ProjectExplorer::RunControl *> runcontrols =
            ProjectExplorer::ProjectExplorerPlugin::instance()->runControls();
    foreach (ProjectExplorer::RunControl *rc, runcontrols) {
        if (QmlProjectRunControl *qrc = qobject_cast<QmlProjectRunControl *>(rc)) {
            if (qrc->mainQmlFile() == config->mainScript())
                // Asking the user defeats the purpose
                // Making it configureable might be worth it
                qrc->stop();
        }
    }

Lasse Holmstedt's avatar
Lasse Holmstedt committed
186
    RunControl *runControl = 0;
187
    if (mode == NormalRunMode)
188
        runControl = new QmlProjectRunControl(config, mode);
189
    else if (mode == DebugRunMode)
Lasse Holmstedt's avatar
Lasse Holmstedt committed
190 191
        runControl = createDebugRunControl(config);
    return runControl;
Kai Koehne's avatar
Kai Koehne committed
192 193
}

194
QString QmlProjectRunControlFactory::displayName() const
Kai Koehne's avatar
Kai Koehne committed
195 196 197 198
{
    return tr("Run");
}

199
ProjectExplorer::RunConfigWidget *QmlProjectRunControlFactory::createConfigurationWidget(RunConfiguration *runConfiguration)
Kai Koehne's avatar
Kai Koehne committed
200 201
{
    Q_UNUSED(runConfiguration)
202
    return 0;
Kai Koehne's avatar
Kai Koehne committed
203 204
}

205
RunControl *QmlProjectRunControlFactory::createDebugRunControl(QmlProjectRunConfiguration *runConfig)
Lasse Holmstedt's avatar
Lasse Holmstedt committed
206 207 208
{
    Debugger::DebuggerStartParameters params;
    params.startMode = Debugger::StartInternal;
209
    params.executable = runConfig->observerPath();
210 211
    params.qmlServerAddress = "127.0.0.1";
    params.qmlServerPort = runConfig->qmlDebugServerPort();
212
    params.processArgs = QString("-qmljsdebugger=port:%1,block").arg(runConfig->qmlDebugServerPort());
213
    params.processArgs += QLatin1Char(' ') + runConfig->viewerArguments();
Lasse Holmstedt's avatar
Lasse Holmstedt committed
214
    params.workingDirectory = runConfig->workingDirectory();
215
    params.environment = runConfig->environment();
Lasse Holmstedt's avatar
Lasse Holmstedt committed
216
    params.displayName = runConfig->displayName();
217 218
    params.projectSourceDirectory = runConfig->target()->project()->projectDirectory();
    params.projectSourceFiles = runConfig->target()->project()->files(Project::ExcludeGeneratedFiles);
Kai Koehne's avatar
Kai Koehne committed
219 220 221 222 223
    if (runConfig->useQmlDebugger())
        params.languages |= Debugger::QmlLanguage;
    if (runConfig->useCppDebugger())
        params.languages |= Debugger::CppLanguage;

224 225
    if (!runConfig->qtVersion()->qtAbis().isEmpty())
        params.toolChainAbi = runConfig->qtVersion()->qtAbis().first();
Lasse Holmstedt's avatar
Lasse Holmstedt committed
226

227 228 229 230 231 232 233
    // Makes sure that all bindings go through the JavaScript engine, so that
    // breakpoints are actually hit!
    const QString optimizerKey = QLatin1String("QML_DISABLE_OPTIMIZER");
    if (!params.environment.hasKey(optimizerKey)) {
        params.environment.set(optimizerKey, QLatin1String("1"));
    }

234
    if (params.executable.isEmpty()) {
235
        QmlProjectPlugin::showQmlObserverToolWarning();
236 237 238
        return 0;
    }

239
    return Debugger::DebuggerPlugin::createDebugger(params, runConfig);
Lasse Holmstedt's avatar
Lasse Holmstedt committed
240 241
}

Kai Koehne's avatar
Kai Koehne committed
242 243
} // namespace Internal
} // namespace QmlProjectManager