qmlprojectrunconfiguration.cpp 12.4 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 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

dt's avatar
dt committed
30
#include "qmlprojectrunconfiguration.h"
Kai Koehne's avatar
Kai Koehne committed
31 32
#include "qmlproject.h"
#include "qmlprojectmanagerconstants.h"
33
#include "qmlprojectrunconfigurationwidget.h"
34
#include <coreplugin/mimedatabase.h>
Kai Koehne's avatar
Kai Koehne committed
35 36 37
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/icore.h>
38
#include <utils/qtcassert.h>
39
#include <utils/qtcprocess.h>
40
#include <qt4projectmanager/qtversionmanager.h>
41
#include <qt4projectmanager/qtoutputformatter.h>
42
#include <qt4projectmanager/qt4projectmanagerconstants.h>
Kai Koehne's avatar
Kai Koehne committed
43 44 45 46 47 48 49

using Core::EditorManager;
using Core::ICore;
using Core::IEditor;
using Qt4ProjectManager::QtVersionManager;

using namespace QmlProjectManager::Internal;
Kai Koehne's avatar
Kai Koehne committed
50 51 52

namespace QmlProjectManager {

Kai Koehne's avatar
Kai Koehne committed
53 54 55
const char * const M_CURRENT_FILE  = "CurrentFile";

QmlProjectRunConfiguration::QmlProjectRunConfiguration(QmlProjectTarget *parent) :
Kai Koehne's avatar
Kai Koehne committed
56
    ProjectExplorer::RunConfiguration(parent, QLatin1String(Constants::QML_RC_ID)),
57
    m_qtVersionId(-1),
58
    m_projectTarget(parent),
59
    m_usingCurrentFile(true),
60 61
    m_isEnabled(false),
    m_baseEnvironmentBase(BuildEnvironmentBase)
Kai Koehne's avatar
Kai Koehne committed
62 63
{
    ctor();
64
    updateQtVersions();
Kai Koehne's avatar
Kai Koehne committed
65 66
}

Kai Koehne's avatar
Kai Koehne committed
67 68
QmlProjectRunConfiguration::QmlProjectRunConfiguration(QmlProjectTarget *parent,
                                                       QmlProjectRunConfiguration *source) :
Kai Koehne's avatar
Kai Koehne committed
69
    ProjectExplorer::RunConfiguration(parent, source),
70
    m_qtVersionId(source->m_qtVersionId),
71
    m_qmlViewerArgs(source->m_qmlViewerArgs),
72 73 74
    m_projectTarget(parent),
    m_userEnvironmentChanges(source->m_userEnvironmentChanges),
    m_baseEnvironmentBase(source->m_baseEnvironmentBase)
Kai Koehne's avatar
Kai Koehne committed
75
{
76 77
    ctor();
    setMainScript(source->m_scriptFile);
78
    updateQtVersions();
Kai Koehne's avatar
Kai Koehne committed
79 80
}

81 82 83 84
bool QmlProjectRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *bc) const
{
    Q_UNUSED(bc);

85
    return m_isEnabled;
86 87
}

Kai Koehne's avatar
Kai Koehne committed
88 89
void QmlProjectRunConfiguration::ctor()
{
90 91 92 93
    // reset default settings in constructor
    setUseCppDebugger(false);
    setUseQmlDebugger(true);

Kai Koehne's avatar
Kai Koehne committed
94
    EditorManager *em = Core::EditorManager::instance();
95 96 97
    connect(em, SIGNAL(currentEditorChanged(Core::IEditor*)),
            this, SLOT(changeCurrentFile(Core::IEditor*)));

Kai Koehne's avatar
Kai Koehne committed
98
    QtVersionManager *qtVersions = QtVersionManager::instance();
99
    connect(qtVersions, SIGNAL(qtVersionsChanged(QList<int>)), this, SLOT(updateQtVersions()));
100

101
    setDisplayName(tr("QML Viewer", "QMLRunConfiguration display name."));
Kai Koehne's avatar
Kai Koehne committed
102 103 104 105 106 107
}

QmlProjectRunConfiguration::~QmlProjectRunConfiguration()
{
}

Kai Koehne's avatar
Kai Koehne committed
108
QmlProjectTarget *QmlProjectRunConfiguration::qmlTarget() const
Kai Koehne's avatar
Kai Koehne committed
109
{
Kai Koehne's avatar
Kai Koehne committed
110
    return static_cast<QmlProjectTarget *>(target());
Kai Koehne's avatar
Kai Koehne committed
111 112
}

113
QString QmlProjectRunConfiguration::viewerPath() const
114
{
115 116
    Qt4ProjectManager::QtVersion *version = qtVersion();
    if (!version) {
117
        return QString();
118 119 120
    } else {
        return version->qmlviewerCommand();
    }
121 122
}

123
QString QmlProjectRunConfiguration::observerPath() const
Kai Koehne's avatar
Kai Koehne committed
124
{
125 126
    Qt4ProjectManager::QtVersion *version = qtVersion();
    if (!version) {
127
        return QString();
128 129 130
    } else {
        return version->qmlObserverTool();
    }
Kai Koehne's avatar
Kai Koehne committed
131 132
}

133
QString QmlProjectRunConfiguration::viewerArguments() const
Kai Koehne's avatar
Kai Koehne committed
134 135
{
    // arguments in .user file
136
    QString args = m_qmlViewerArgs;
Kai Koehne's avatar
Kai Koehne committed
137 138

    // arguments from .qmlproject file
139
    foreach (const QString &importPath, qmlTarget()->qmlProject()->importPaths()) {
140 141
        Utils::QtcProcess::addArg(&args, "-I");
        Utils::QtcProcess::addArg(&args, importPath);
Kai Koehne's avatar
Kai Koehne committed
142 143
    }

144 145 146
    const QString &s = mainScript();
    if (!s.isEmpty())
        Utils::QtcProcess::addArg(&args, s);
Kai Koehne's avatar
Kai Koehne committed
147 148 149 150 151 152 153 154 155
    return args;
}

QString QmlProjectRunConfiguration::workingDirectory() const
{
    QFileInfo projectFile(qmlTarget()->qmlProject()->file()->fileName());
    return projectFile.absolutePath();
}

156 157 158 159 160
int QmlProjectRunConfiguration::qtVersionId() const
{
    return m_qtVersionId;
}

161 162 163 164 165 166 167
void QmlProjectRunConfiguration::setQtVersionId(int id)
{
    if (m_qtVersionId == id)
        return;

    m_qtVersionId = id;
    qmlTarget()->qmlProject()->refresh(QmlProject::Configuration);
168 169
    if (m_configurationWidget)
        m_configurationWidget.data()->updateQtVersionComboBox();
170 171
}

172 173 174 175 176
Qt4ProjectManager::QtVersion *QmlProjectRunConfiguration::qtVersion() const
{
    if (m_qtVersionId == -1)
        return 0;

Kai Koehne's avatar
Kai Koehne committed
177
    QtVersionManager *versionManager = QtVersionManager::instance();
178 179 180 181 182 183
    Qt4ProjectManager::QtVersion *version = versionManager->version(m_qtVersionId);
    QTC_ASSERT(version, return 0);

    return version;
}

184
QWidget *QmlProjectRunConfiguration::createConfigurationWidget()
Kai Koehne's avatar
Kai Koehne committed
185
{
186 187 188
    QTC_ASSERT(m_configurationWidget.isNull(), return m_configurationWidget.data());
    m_configurationWidget = new QmlProjectRunConfigurationWidget(this);
    return m_configurationWidget.data();
Kai Koehne's avatar
Kai Koehne committed
189 190
}

191 192 193 194
ProjectExplorer::OutputFormatter *QmlProjectRunConfiguration::createOutputFormatter() const
{
    return new Qt4ProjectManager::QtOutputFormatter(qmlTarget()->qmlProject());
}
195

Kai Koehne's avatar
Kai Koehne committed
196 197
QString QmlProjectRunConfiguration::mainScript() const
{
198 199
    if (m_usingCurrentFile)
        return m_currentFileFilename;
Kai Koehne's avatar
Kai Koehne committed
200

201
    return m_mainScriptFilename;
Kai Koehne's avatar
Kai Koehne committed
202 203 204 205 206
}

void QmlProjectRunConfiguration::setMainScript(const QString &scriptFile)
{
    m_scriptFile = scriptFile;
207 208 209
    // replace with locale-agnostic string
    if (m_scriptFile == CURRENT_FILE)
        m_scriptFile = M_CURRENT_FILE;
210

211
    if (m_scriptFile.isEmpty() || m_scriptFile == M_CURRENT_FILE) {
212 213 214 215 216
        m_usingCurrentFile = true;
        changeCurrentFile(Core::EditorManager::instance()->currentEditor());
    } else {
        m_usingCurrentFile = false;
        m_mainScriptFilename = qmlTarget()->qmlProject()->projectDir().absoluteFilePath(scriptFile);
217
        updateEnabled();
218
    }
Kai Koehne's avatar
Kai Koehne committed
219 220
}

221 222 223 224 225 226 227
Utils::Environment QmlProjectRunConfiguration::environment() const
{
    Utils::Environment env = baseEnvironment();
    env.modify(userEnvironmentChanges());
    return env;
}

Kai Koehne's avatar
Kai Koehne committed
228 229 230 231
QVariantMap QmlProjectRunConfiguration::toMap() const
{
    QVariantMap map(ProjectExplorer::RunConfiguration::toMap());

232
    map.insert(QLatin1String(Constants::QML_VIEWER_QT_KEY), m_qtVersionId);
Kai Koehne's avatar
Kai Koehne committed
233 234
    map.insert(QLatin1String(Constants::QML_VIEWER_ARGUMENTS_KEY), m_qmlViewerArgs);
    map.insert(QLatin1String(Constants::QML_MAINSCRIPT_KEY),  m_scriptFile);
235 236 237 238
    map.insert(QLatin1String(Constants::USER_ENVIRONMENT_CHANGES_KEY),
               Utils::EnvironmentItem::toStringList(m_userEnvironmentChanges));
    map.insert(QLatin1String(Constants::BASE_ENVIRONMENT_BASE_KEY),
               static_cast<int>(m_baseEnvironmentBase));
Kai Koehne's avatar
Kai Koehne committed
239 240 241 242 243
    return map;
}

bool QmlProjectRunConfiguration::fromMap(const QVariantMap &map)
{
244
    setQtVersionId(map.value(QLatin1String(Constants::QML_VIEWER_QT_KEY), -1).toInt());
Kai Koehne's avatar
Kai Koehne committed
245
    m_qmlViewerArgs = map.value(QLatin1String(Constants::QML_VIEWER_ARGUMENTS_KEY)).toString();
246
    m_scriptFile = map.value(QLatin1String(Constants::QML_MAINSCRIPT_KEY), M_CURRENT_FILE).toString();
247 248 249 250 251 252 253 254
    m_userEnvironmentChanges = Utils::EnvironmentItem::fromStringList(
                map.value(QLatin1String(Constants::USER_ENVIRONMENT_CHANGES_KEY)).toStringList());
    m_baseEnvironmentBase
            = static_cast<BaseEnvironmentBase>(
                map.value(QLatin1String(Constants::BASE_ENVIRONMENT_BASE_KEY),
                          static_cast<int>(BuildEnvironmentBase)).toInt());


255 256

    updateQtVersions();
257
    setMainScript(m_scriptFile);
Kai Koehne's avatar
Kai Koehne committed
258 259 260 261

    return RunConfiguration::fromMap(map);
}

262 263 264 265 266 267
void QmlProjectRunConfiguration::changeCurrentFile(Core::IEditor * /*editor*/)
{
    updateEnabled();
}

void QmlProjectRunConfiguration::updateEnabled()
268
{
269
    bool qmlFileFound = false;
270
    if (m_usingCurrentFile) {
271
        Core::IEditor *editor = Core::EditorManager::instance()->currentEditor();
Kai Koehne's avatar
Kai Koehne committed
272
        Core::MimeDatabase *db = ICore::instance()->mimeDatabase();
273 274
        if (editor) {
            m_currentFileFilename = editor->file()->fileName();
Kai Koehne's avatar
Kai Koehne committed
275
            if (db->findByFile(mainScript()).type() == QLatin1String("application/x-qml"))
276
                qmlFileFound = true;
277 278
        }
        if (!editor
Kai Koehne's avatar
Kai Koehne committed
279 280 281
            || db->findByFile(mainScript()).type() == QLatin1String("application/x-qmlproject")) {
            // find a qml file with lowercase filename. This is slow, but only done
            // in initialization/other border cases.
282
            foreach(const QString &filename, m_projectTarget->qmlProject()->files()) {
283 284 285
                const QFileInfo fi(filename);

                if (!filename.isEmpty() && fi.baseName()[0].isLower()
Kai Koehne's avatar
Kai Koehne committed
286
                    && db->findByFile(fi).type() == QLatin1String("application/x-qml"))
287 288
                {
                    m_currentFileFilename = filename;
289
                    qmlFileFound = true;
290 291 292 293
                    break;
                }

            }
294
        }
295 296 297 298
    } else { // use default one
        qmlFileFound = !m_mainScriptFilename.isEmpty();
    }

299 300
    bool newValue = (QFileInfo(viewerPath()).exists()
                    || QFileInfo(observerPath()).exists()) && qmlFileFound;
301

302 303 304 305

    // Always emit change signal to force reevaluation of run/debug buttons
    m_isEnabled = newValue;
    emit isEnabledChanged(m_isEnabled);
306 307
}

308
void QmlProjectRunConfiguration::updateQtVersions()
309
{
Kai Koehne's avatar
Kai Koehne committed
310
    QtVersionManager *qtVersions = QtVersionManager::instance();
311 312 313 314 315 316

    //
    // update m_qtVersionId
    //
    if (!qtVersions->isValidId(m_qtVersionId)
            || !isValidVersion(qtVersions->version(m_qtVersionId))) {
317
        int newVersionId = -1;
318 319 320
        // take first one you find
        foreach (Qt4ProjectManager::QtVersion *version, qtVersions->validVersions()) {
            if (isValidVersion(version)) {
321
                newVersionId = version->uniqueId();
322 323
                break;
            }
324
        }
325
        setQtVersionId(newVersionId);
326 327
    }

328 329 330 331 332 333
    updateEnabled();
}

bool QmlProjectRunConfiguration::isValidVersion(Qt4ProjectManager::QtVersion *version)
{
    if (version
334 335
            && (version->supportsTargetId(Qt4ProjectManager::Constants::DESKTOP_TARGET_ID)
                || version->supportsTargetId(Qt4ProjectManager::Constants::QT_SIMULATOR_TARGET_ID))
336 337 338 339
            && !version->qmlviewerCommand().isEmpty()) {
        return true;
    }
    return false;
340 341
}

342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
Utils::Environment QmlProjectRunConfiguration::baseEnvironment() const
{
    Utils::Environment env;

    if (m_baseEnvironmentBase == QmlProjectRunConfiguration::CleanEnvironmentBase) {
        // Nothing
    } else  if (m_baseEnvironmentBase == QmlProjectRunConfiguration::SystemEnvironmentBase) {
        env = Utils::Environment::systemEnvironment();
    } else if (m_baseEnvironmentBase == QmlProjectRunConfiguration::BuildEnvironmentBase) {
        env = qtVersion()->qmlToolsEnvironment();
    }
    return env;
}

void QmlProjectRunConfiguration::setBaseEnvironmentBase(BaseEnvironmentBase env)
{
    if (m_baseEnvironmentBase == env)
        return;
    m_baseEnvironmentBase = env;
    if (m_configurationWidget)
        m_configurationWidget.data()->baseEnvironmentChanged();
}

QmlProjectRunConfiguration::BaseEnvironmentBase
QmlProjectRunConfiguration::baseEnvironmentBase() const
{
    return m_baseEnvironmentBase;
}

void QmlProjectRunConfiguration::setUserEnvironmentChanges(const QList<Utils::EnvironmentItem> &diff)
{
    if (m_userEnvironmentChanges != diff) {
        m_userEnvironmentChanges = diff;
        if (m_configurationWidget)
            m_configurationWidget.data()->userEnvironmentChangesChanged();
    }
}

QList<Utils::EnvironmentItem> QmlProjectRunConfiguration::userEnvironmentChanges() const
{
    return m_userEnvironmentChanges;
}


Kai Koehne's avatar
Kai Koehne committed
386
} // namespace QmlProjectManager