qtquickapp.cpp 10.8 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
2
**
3
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
hjk's avatar
hjk committed
4
** Contact: http://www.qt-project.org/legal
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
7
**
hjk's avatar
hjk committed
8
9
10
11
12
13
14
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
15
16
**
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17
18
19
20
21
22
23
24
25
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
con's avatar
con committed
26
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
28
****************************************************************************/
29

30
#include "qtquickapp.h"
31

32
33
34
35
36
#include <QDir>
#include <QFile>
#include <QRegExp>
#include <QTextStream>
#include <QCoreApplication>
37

38
39
40
41
#ifndef CREATORLESSTEST
#include <coreplugin/icore.h>
#endif // CREATORLESSTEST

42
namespace Qt4ProjectManager {
43
44
namespace Internal {

45
46
47
QtQuickApp::QtQuickApp()
    : AbstractMobileApp()
    , m_mainQmlMode(ModeGenerate)
Feetu Nyrhinen's avatar
Feetu Nyrhinen committed
48
    , m_componentSet(QtQuick10Components)
49
{
50
    m_canSupportMeegoBooster = true;
51
52
}

Feetu Nyrhinen's avatar
Feetu Nyrhinen committed
53
54
55
56
57
58
59
60
61
62
void QtQuickApp::setComponentSet(ComponentSet componentSet)
{
    m_componentSet = componentSet;
}

QtQuickApp::ComponentSet QtQuickApp::componentSet() const
{
    return m_componentSet;
}

63
void QtQuickApp::setMainQml(Mode mode, const QString &file)
64
{
65
66
67
    Q_ASSERT(mode != ModeGenerate || file.isEmpty());
    m_mainQmlMode = mode;
    m_mainQmlFile.setFile(file);
68
69
}

70
QtQuickApp::Mode QtQuickApp::mainQmlMode() const
71
{
72
    return m_mainQmlMode;
73
74
}

75
QString QtQuickApp::pathExtended(int fileType) const
76
{
77
    const bool importQmlFile = m_mainQmlMode == ModeImport;
78
    const QString qmlSubDir = QLatin1String("qml/")
79
                              + (importQmlFile ? m_mainQmlFile.dir().dirName() : projectName())
80
                              + QLatin1Char('/');
81
    const QString appViewerTargetSubDir = appViewerOriginSubDir();
Feetu Nyrhinen's avatar
Feetu Nyrhinen committed
82
83
84
85
86
87
88

    const QString mainQmlFile = QLatin1String("main.qml");
    const QString mainPageQmlFile = QLatin1String("MainPage.qml");

    const QString qmlOriginDir = originsRoot() + QLatin1String("qml/app/")
                        + componentSetDir(componentSet()) + QLatin1Char('/');

89
    const QString pathBase = outputPathBase();
90
91
    const QDir appProFilePath(pathBase);

92
    switch (fileType) {
Feetu Nyrhinen's avatar
Feetu Nyrhinen committed
93
94
        case MainQml:
            return importQmlFile ? m_mainQmlFile.canonicalFilePath() : pathBase + qmlSubDir + mainQmlFile;
95
        case MainQmlDeployed:               return importQmlFile ? qmlSubDir + m_mainQmlFile.fileName()
Feetu Nyrhinen's avatar
Feetu Nyrhinen committed
96
97
98
99
                                                                 : QString(qmlSubDir + mainQmlFile);
        case MainQmlOrigin:                 return qmlOriginDir + mainQmlFile;
        case MainPageQml:                   return pathBase + qmlSubDir + mainPageQmlFile;
        case MainPageQmlOrigin:             return qmlOriginDir + mainPageQmlFile;
100
101
102
103
104
105
        case AppViewerPri:                  return pathBase + appViewerTargetSubDir + fileName(AppViewerPri);
        case AppViewerPriOrigin:            return originsRoot() + appViewerOriginSubDir() + fileName(AppViewerPri);
        case AppViewerCpp:                  return pathBase + appViewerTargetSubDir + fileName(AppViewerCpp);
        case AppViewerCppOrigin:            return originsRoot() + appViewerOriginSubDir() + fileName(AppViewerCpp);
        case AppViewerH:                    return pathBase + appViewerTargetSubDir + fileName(AppViewerH);
        case AppViewerHOrigin:              return originsRoot() + appViewerOriginSubDir() + fileName(AppViewerH);
106
        case QmlDir:                        return pathBase + qmlSubDir;
107
108
        case QmlDirProFileRelative:         return importQmlFile ? appProFilePath.relativeFilePath(m_mainQmlFile.canonicalPath())
                                                                 : QString(qmlSubDir).remove(qmlSubDir.length() - 1, 1);
109
        default:                            qFatal("QtQuickApp::pathExtended() needs more work");
110
111
112
113
    }
    return QString();
}

114
QString QtQuickApp::originsRoot() const
115
{
116
117
    const bool isQtQuick2 = m_componentSet == QtQuick20Components;
    return templatesRoot() + QLatin1String(isQtQuick2 ? "qtquick2app/" : "qtquickapp/");
118
119
}

120
QString QtQuickApp::mainWindowClassName() const
121
{
122
    return QLatin1String("QmlApplicationViewer");
123
124
}

125
bool QtQuickApp::adaptCurrentMainCppTemplateLine(QString &line) const
126
{
127
    const QLatin1Char quote('"');
128

129
    if (line.contains(QLatin1String("// MAINQML")))
130
        insertParameter(line, quote + path(MainQmlDeployed) + quote);
131

132
    return true;
133
134
}

135
void QtQuickApp::handleCurrentProFileTemplateLine(const QString &line,
136
    QTextStream &proFileTemplate, QTextStream &proFile,
137
    bool &commentOutNextLine) const
138
{
Alessandro Portale's avatar
Alessandro Portale committed
139
140
    Q_UNUSED(commentOutNextLine)
    if (line.contains(QLatin1String("# QML_IMPORT_PATH"))) {
141
142
143
        QString nextLine = proFileTemplate.readLine(); // eats 'QML_IMPORT_PATH ='
        if (!nextLine.startsWith(QLatin1String("QML_IMPORT_PATH =")))
            return;
144
        proFile << nextLine << endl;
145
146
147
148
149
    } else if (line.contains(QLatin1String("# HARMATTAN_BOOSTABLE"))) {
        QString nextLine = proFileTemplate.readLine(); // eats '# CONFIG += qdeclarative-boostable'
        if (supportsMeegoBooster())
            nextLine.remove(0, 2); // remove comment
        proFile << nextLine << endl;
150
    }
151
152
}

153
#ifndef CREATORLESSTEST
154
Core::GeneratedFiles QtQuickApp::generateFiles(QString *errorMessage) const
155
{
156
    Core::GeneratedFiles files = AbstractMobileApp::generateFiles(errorMessage);
157
    if (!useExistingMainQml()) {
158
        files.append(file(generateFile(QtQuickAppGeneratedFileInfo::MainQmlFile, errorMessage), path(MainQml)));
159
        if ((componentSet() == QtQuickApp::Meego10Components))
Feetu Nyrhinen's avatar
Feetu Nyrhinen committed
160
            files.append(file(generateFile(QtQuickAppGeneratedFileInfo::MainPageQmlFile, errorMessage), path(MainPageQml)));
161
162
        files.last().setAttributes(Core::GeneratedFile::OpenEditorAttribute);
    }
163

164
165
166
    files.append(file(generateFile(QtQuickAppGeneratedFileInfo::AppViewerPriFile, errorMessage), path(AppViewerPri)));
    files.append(file(generateFile(QtQuickAppGeneratedFileInfo::AppViewerCppFile, errorMessage), path(AppViewerCpp)));
    files.append(file(generateFile(QtQuickAppGeneratedFileInfo::AppViewerHFile, errorMessage), path(AppViewerH)));
167
168
169
170
171

    return files;
}
#endif // CREATORLESSTEST

172
bool QtQuickApp::useExistingMainQml() const
173
174
175
176
{
    return !m_mainQmlFile.filePath().isEmpty();
}

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
QString QtQuickApp::appViewerBaseName() const
{
    return QLatin1String(m_componentSet == QtQuick20Components ?
                             "qtquick2applicationviewer" : "qmlapplicationviewer");
}

QString QtQuickApp::fileName(QtQuickApp::ExtendedFileType type) const
{
    switch (type) {
        case AppViewerPri:      return appViewerBaseName() + QLatin1String(".pri");
        case AppViewerH:        return appViewerBaseName() + QLatin1String(".h");
        case AppViewerCpp:      return appViewerBaseName() + QLatin1String(".cpp");
        default:                return QString();
    }
}

QString QtQuickApp::appViewerOriginSubDir() const
{
    return appViewerBaseName() + QLatin1Char('/');
}

198
QByteArray QtQuickApp::generateFileExtended(int fileType,
199
    bool *versionAndCheckSum, QString *comment, QString *errorMessage) const
200
201
{
    QByteArray data;
202
    switch (fileType) {
203
        case QtQuickAppGeneratedFileInfo::MainQmlFile:
204
            data = readBlob(path(MainQmlOrigin), errorMessage);
205
            break;
Feetu Nyrhinen's avatar
Feetu Nyrhinen committed
206
207
208
        case QtQuickAppGeneratedFileInfo::MainPageQmlFile:
            data = readBlob(path(MainPageQmlOrigin), errorMessage);
            break;
209
        case QtQuickAppGeneratedFileInfo::AppViewerPriFile:
210
            data = readBlob(path(AppViewerPriOrigin), errorMessage);
211
            data.append(readBlob(path(DeploymentPriOrigin), errorMessage));
212
213
            *comment = ProFileComment;
            *versionAndCheckSum = true;
214
            break;
215
        case QtQuickAppGeneratedFileInfo::AppViewerCppFile:
216
217
            data = readBlob(path(AppViewerCppOrigin), errorMessage);
            *versionAndCheckSum = true;
218
            break;
219
        case QtQuickAppGeneratedFileInfo::AppViewerHFile:
220
        default:
221
222
            data = readBlob(path(AppViewerHOrigin), errorMessage);
            *versionAndCheckSum = true;
223
224
            break;
    }
225
    return data;
226
227
}

228
int QtQuickApp::stubVersionMinor() const
229
{
230
    return m_componentSet == QtQuick20Components ? 4 : 23;
231
232
}

233
QList<AbstractGeneratedFileInfo> QtQuickApp::updateableFiles(const QString &mainProFile) const
234
{
235
    QList<AbstractGeneratedFileInfo> result;
236
    static const struct {
237
        int fileType;
238
239
        QString fileName;
    } files[] = {
240
241
242
        {QtQuickAppGeneratedFileInfo::AppViewerPriFile, fileName(AppViewerPri)},
        {QtQuickAppGeneratedFileInfo::AppViewerHFile, fileName(AppViewerH)},
        {QtQuickAppGeneratedFileInfo::AppViewerCppFile, fileName(AppViewerCpp)}
243
244
    };
    const QFileInfo mainProFileInfo(mainProFile);
245
246
    const int size = sizeof(files) / sizeof(files[0]);
    for (int i = 0; i < size; ++i) {
247
        const QString fileName = mainProFileInfo.dir().absolutePath()
248
                + QLatin1Char('/') + appViewerOriginSubDir() + files[i].fileName;
249
250
        if (!QFile::exists(fileName))
            continue;
251
        QtQuickAppGeneratedFileInfo file;
252
        file.fileType = files[i].fileType;
253
        file.fileInfo = QFileInfo(fileName);
254
        file.currentVersion = AbstractMobileApp::makeStubVersion(stubVersionMinor());
255
256
        result.append(file);
    }
257
258
    if (result.count() != size)
        result.clear(); // All files must be found. No wrong/partial updates, please.
259
260
261
    return result;
}

262
263
264
265
266
267
268
QList<DeploymentFolder> QtQuickApp::deploymentFolders() const
{
    QList<DeploymentFolder> result;
    result.append(DeploymentFolder(path(QmlDirProFileRelative), QLatin1String("qml")));
    return result;
}

Feetu Nyrhinen's avatar
Feetu Nyrhinen committed
269
270
271
QString QtQuickApp::componentSetDir(ComponentSet componentSet) const
{
    switch (componentSet) {
272
273
    case Meego10Components:
        return QLatin1String("meego10");
274
275
    case QtQuick20Components:
        return QLatin1String("qtquick20");
Feetu Nyrhinen's avatar
Feetu Nyrhinen committed
276
277
278
279
280
281
    case QtQuick10Components:
    default:
        return QLatin1String("qtquick10");
    }
}

282
} // namespace Internal
283
} // namespace Qt4ProjectManager