qmlprojectruncontrol.cpp 8.27 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) 2010 Nokia Corporation and/or its subsidiary(-ies).
Kai Koehne's avatar
Kai Koehne committed
6 7 8
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
con's avatar
con committed
9
** No Commercial Usage
Kai Koehne's avatar
Kai Koehne committed
10
**
con's avatar
con committed
11 12 13 14
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
Kai Koehne's avatar
Kai Koehne committed
15 16 17 18 19 20 21 22 23 24
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
con's avatar
con committed
25 26 27 28 29 30
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
Kai Koehne's avatar
Kai Koehne committed
31 32 33 34 35
**
**************************************************************************/

#include "qmlprojectruncontrol.h"
#include "qmlprojectrunconfiguration.h"
36
#include "qmlprojectconstants.h"
Kai Koehne's avatar
Kai Koehne committed
37 38 39 40
#include <coreplugin/icore.h>
#include <coreplugin/modemanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/applicationlauncher.h>
41
#include <qt4projectmanager/qtversionmanager.h>
42
#include <utils/environment.h>
Kai Koehne's avatar
Kai Koehne committed
43
#include <utils/qtcassert.h>
44
#include <utils/qtcprocess.h>
Kai Koehne's avatar
Kai Koehne committed
45

Lasse Holmstedt's avatar
Lasse Holmstedt committed
46 47
#include <debugger/debuggerrunner.h>
#include <debugger/debuggerplugin.h>
48
#include <debugger/debuggerconstants.h>
Lasse Holmstedt's avatar
Lasse Holmstedt committed
49
#include <debugger/debuggerengine.h>
Friedemann Kleint's avatar
Friedemann Kleint committed
50
#include <debugger/debuggerstartparameters.h>
51
#include <qmljsinspector/qmljsinspectorconstants.h>
52 53
#include <qt4projectmanager/qtversionmanager.h>
#include <qt4projectmanager/qmlobservertool.h>
54
#include <qt4projectmanager/qt4projectmanagerconstants.h>
55

56
#include <QApplication>
Kai Koehne's avatar
Kai Koehne committed
57 58
#include <QDir>
#include <QLabel>
59
#include <QMessageBox>
60
#include <QPushButton>
Kai Koehne's avatar
Kai Koehne committed
61

62
using namespace ProjectExplorer;
Kai Koehne's avatar
Kai Koehne committed
63 64 65 66

namespace QmlProjectManager {
namespace Internal {

dt's avatar
dt committed
67 68
QmlRunControl::QmlRunControl(QmlProjectRunConfiguration *runConfiguration, QString mode)
    : RunControl(runConfiguration, mode)
Kai Koehne's avatar
Kai Koehne committed
69
{
70
    m_applicationLauncher.setEnvironment(runConfiguration->environment());
Kai Koehne's avatar
Kai Koehne committed
71 72
    m_applicationLauncher.setWorkingDirectory(runConfiguration->workingDirectory());

73 74 75 76 77
    if (mode == ProjectExplorer::Constants::RUNMODE) {
        m_executable = runConfiguration->viewerPath();
    } else {
        m_executable = runConfiguration->observerPath();
    }
Kai Koehne's avatar
Kai Koehne committed
78 79
    m_commandLineArguments = runConfiguration->viewerArguments();

80 81
    connect(&m_applicationLauncher, SIGNAL(appendMessage(QString,ProjectExplorer::OutputFormat)),
            this, SLOT(slotAppendMessage(QString, ProjectExplorer::OutputFormat)));
Kai Koehne's avatar
Kai Koehne committed
82 83 84 85 86 87 88 89
    connect(&m_applicationLauncher, SIGNAL(processExited(int)),
            this, SLOT(processExited(int)));
    connect(&m_applicationLauncher, SIGNAL(bringToForegroundRequested(qint64)),
            this, SLOT(slotBringApplicationToForeground(qint64)));
}

QmlRunControl::~QmlRunControl()
{
90
    stop();
Kai Koehne's avatar
Kai Koehne committed
91 92 93 94
}

void QmlRunControl::start()
{
95
    m_applicationLauncher.start(ApplicationLauncher::Gui, m_executable,
Kai Koehne's avatar
Kai Koehne committed
96
                                m_commandLineArguments);
97

Kai Koehne's avatar
Kai Koehne committed
98
    emit started();
99 100 101
    QString msg = tr("Starting %1 %2")
        .arg(QDir::toNativeSeparators(m_executable), m_commandLineArguments);
    appendMessage(this, msg, NormalMessageFormat);
Kai Koehne's avatar
Kai Koehne committed
102 103
}

104
RunControl::StopResult QmlRunControl::stop()
Kai Koehne's avatar
Kai Koehne committed
105 106
{
    m_applicationLauncher.stop();
107
    return StoppedSynchronously;
Kai Koehne's avatar
Kai Koehne committed
108 109 110 111 112 113 114 115 116 117 118 119
}

bool QmlRunControl::isRunning() const
{
    return m_applicationLauncher.isRunning();
}

void QmlRunControl::slotBringApplicationToForeground(qint64 pid)
{
    bringApplicationToForeground(pid);
}

120
void QmlRunControl::slotAppendMessage(const QString &line, OutputFormat format)
Kai Koehne's avatar
Kai Koehne committed
121
{
122
    emit appendMessage(this, line, format);
Kai Koehne's avatar
Kai Koehne committed
123 124 125 126
}

void QmlRunControl::processExited(int exitCode)
{
127 128 129
    QString msg = tr("%1 exited with code %2")
        .arg(QDir::toNativeSeparators(m_executable)).arg(exitCode);
    emit appendMessage(this, msg, exitCode ? ErrorMessageFormat : NormalMessageFormat);
Kai Koehne's avatar
Kai Koehne committed
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    emit finished();
}

QmlRunControlFactory::QmlRunControlFactory(QObject *parent)
    : IRunControlFactory(parent)
{
}

QmlRunControlFactory::~QmlRunControlFactory()
{
}

bool QmlRunControlFactory::canRun(RunConfiguration *runConfiguration,
                                  const QString &mode) const
{
145 146 147
    QmlProjectRunConfiguration *config =
        qobject_cast<QmlProjectRunConfiguration*>(runConfiguration);
    if (mode == ProjectExplorer::Constants::RUNMODE)
148
        return config != 0 && !config->viewerPath().isEmpty();
149 150 151 152 153 154 155 156 157 158 159 160

    bool qmlDebugSupportInstalled =
            Debugger::DebuggerPlugin::isActiveDebugLanguage(Debugger::QmlLanguage);

    if (config && qmlDebugSupportInstalled) {
        if (!config->observerPath().isEmpty())
            return true;

        if (config->qtVersion() && Qt4ProjectManager::QmlObserverTool::canBuild(config->qtVersion())) {
            return true;
        } else {
            return false;
161
        }
162
    }
Lasse Holmstedt's avatar
Lasse Holmstedt committed
163 164

    return false;
Kai Koehne's avatar
Kai Koehne committed
165 166 167 168 169 170
}

RunControl *QmlRunControlFactory::create(RunConfiguration *runConfiguration,
                                         const QString &mode)
{
    QTC_ASSERT(canRun(runConfiguration, mode), return 0);
Lasse Holmstedt's avatar
Lasse Holmstedt committed
171 172 173 174 175

    QmlProjectRunConfiguration *config = qobject_cast<QmlProjectRunConfiguration *>(runConfiguration);
    RunControl *runControl = 0;
    if (mode == ProjectExplorer::Constants::RUNMODE) {
       runControl = new QmlRunControl(config, mode);
176
    } else if (mode == Debugger::Constants::DEBUGMODE) {
Lasse Holmstedt's avatar
Lasse Holmstedt committed
177 178 179
        runControl = createDebugRunControl(config);
    }
    return runControl;
Kai Koehne's avatar
Kai Koehne committed
180 181 182 183 184 185 186
}

QString QmlRunControlFactory::displayName() const
{
    return tr("Run");
}

187
QWidget *QmlRunControlFactory::createConfigurationWidget(RunConfiguration *runConfiguration)
Kai Koehne's avatar
Kai Koehne committed
188 189 190 191 192
{
    Q_UNUSED(runConfiguration)
    return new QLabel("TODO add Configuration widget");
}

193
RunControl *QmlRunControlFactory::createDebugRunControl(QmlProjectRunConfiguration *runConfig)
Lasse Holmstedt's avatar
Lasse Holmstedt committed
194 195 196
{
    Debugger::DebuggerStartParameters params;
    params.startMode = Debugger::StartInternal;
197
    params.executable = runConfig->observerPath();
198 199
    params.qmlServerAddress = "127.0.0.1";
    params.qmlServerPort = runConfig->qmlDebugServerPort();
Lasse Holmstedt's avatar
Lasse Holmstedt committed
200
    params.processArgs = runConfig->viewerArguments();
201 202
    Utils::QtcProcess::addArg(&params.processArgs,
            QLatin1String("-qmljsdebugger=port:") + QString::number(runConfig->qmlDebugServerPort()));
Lasse Holmstedt's avatar
Lasse Holmstedt committed
203
    params.workingDirectory = runConfig->workingDirectory();
204
    params.environment = runConfig->environment();
Lasse Holmstedt's avatar
Lasse Holmstedt committed
205 206
    params.displayName = runConfig->displayName();

207 208 209 210 211
    if (params.executable.isEmpty()) {
        showQmlObserverToolWarning();
        return 0;
    }

212
    return Debugger::DebuggerPlugin::createDebugger(params, runConfig);
Lasse Holmstedt's avatar
Lasse Holmstedt committed
213 214
}

215 216 217 218 219 220 221 222 223 224
void QmlRunControlFactory::showQmlObserverToolWarning() {
    QMessageBox dialog(QApplication::activeWindow());
    QPushButton *qtPref = dialog.addButton(tr("Open Qt4 Options"),
                                           QMessageBox::ActionRole);
    dialog.addButton(tr("Cancel"), QMessageBox::ActionRole);
    dialog.setDefaultButton(qtPref);
    dialog.setWindowTitle(tr("QML Observer Missing"));
    dialog.setText(tr("QML Observer could not be found."));
    dialog.setInformativeText(tr(
                                  "QML Observer is used to offer debugging features for "
Pawel Polanski's avatar
Pawel Polanski committed
225
                                  "QML applications, such as interactive debugging and inspection tools. "
226 227 228 229 230 231 232 233 234 235 236
                                  "It must be compiled for each used Qt version separately. "
                                  "On the Qt4 options page, select the current Qt installation "
                                  "and click Rebuild."));
    dialog.exec();
    if (dialog.clickedButton() == qtPref) {
        Core::ICore::instance()->showOptionsDialog(
                    Qt4ProjectManager::Constants::QT_SETTINGS_CATEGORY,
                    Qt4ProjectManager::Constants::QTVERSION_SETTINGS_PAGE_ID);
    }
}

Kai Koehne's avatar
Kai Koehne committed
237 238 239
} // namespace Internal
} // namespace QmlProjectManager