OSDN Git Service

Merge remote branch 'origin/2.1'
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qmlprojectmanager / qmlproject.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** Commercial Usage
10 **
11 ** Licensees holding valid Qt Commercial licenses may use this file in
12 ** accordance with the Qt Commercial License Agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and Nokia.
15 **
16 ** GNU Lesser General Public License Usage
17 **
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** If you are unsure which license is appropriate for your use, please
26 ** contact the sales department at http://qt.nokia.com/contact.
27 **
28 **************************************************************************/
29
30 #include "qmlproject.h"
31 #include "qmlprojectfile.h"
32 #include "qmlprojectmanagerconstants.h"
33 #include "fileformat/qmlprojectitem.h"
34 #include "qmlprojectrunconfiguration.h"
35 #include "qmlprojecttarget.h"
36
37 #include <coreplugin/icore.h>
38 #include <coreplugin/messagemanager.h>
39 #include <extensionsystem/pluginmanager.h>
40 #include <projectexplorer/filewatcher.h>
41 #include <qt4projectmanager/qmldumptool.h>
42 #include <qt4projectmanager/qtversionmanager.h>
43 #include <qmljs/qmljsmodelmanagerinterface.h>
44
45 #include <QTextStream>
46 #include <QDeclarativeComponent>
47 #include <QtDebug>
48
49 namespace QmlProjectManager {
50
51 QmlProject::QmlProject(Internal::Manager *manager, const QString &fileName)
52     : m_manager(manager),
53       m_fileName(fileName),
54       m_modelManager(ExtensionSystem::PluginManager::instance()->getObject<QmlJS::ModelManagerInterface>()),
55       m_fileWatcher(new ProjectExplorer::FileWatcher(this))
56 {
57     setSupportedTargetIds(QSet<QString>() << QLatin1String(Constants::QML_VIEWER_TARGET_ID));
58     QFileInfo fileInfo(m_fileName);
59     m_projectName = fileInfo.completeBaseName();
60
61     m_file = new Internal::QmlProjectFile(this, fileName);
62     m_rootNode = new Internal::QmlProjectNode(this, m_file);
63
64     m_fileWatcher->addFile(fileName),
65     connect(m_fileWatcher, SIGNAL(fileChanged(QString)),
66             this, SLOT(refreshProjectFile()));
67
68     m_manager->registerProject(this);
69 }
70
71 QmlProject::~QmlProject()
72 {
73     m_manager->unregisterProject(this);
74
75     delete m_projectItem.data();
76     delete m_rootNode;
77 }
78
79 QDir QmlProject::projectDir() const
80 {
81     return QFileInfo(file()->fileName()).dir();
82 }
83
84 QString QmlProject::filesFileName() const
85 { return m_fileName; }
86
87 void QmlProject::parseProject(RefreshOptions options)
88 {
89     if (options & Files) {
90         if (options & ProjectFile)
91             delete m_projectItem.data();
92         if (!m_projectItem) {
93             QFile file(m_fileName);
94             if (file.open(QFile::ReadOnly)) {
95                 QDeclarativeComponent *component = new QDeclarativeComponent(&m_engine, this);
96                 component->setData(file.readAll(), QUrl::fromLocalFile(m_fileName));
97                 if (component->isReady()
98                     && qobject_cast<QmlProjectItem*>(component->create())) {
99                     m_projectItem = qobject_cast<QmlProjectItem*>(component->create());
100                     connect(m_projectItem.data(), SIGNAL(qmlFilesChanged(QSet<QString>, QSet<QString>)),
101                             this, SLOT(refreshFiles(QSet<QString>, QSet<QString>)));
102                 } else {
103                     Core::MessageManager *messageManager = Core::ICore::instance()->messageManager();
104                     messageManager->printToOutputPane(tr("Error while loading project file!"));
105                     messageManager->printToOutputPane(component->errorString(), true);
106                 }
107             }
108         }
109         if (m_projectItem) {
110             m_projectItem.data()->setSourceDirectory(projectDir().path());
111             m_modelManager->updateSourceFiles(m_projectItem.data()->files(), true);
112         }
113         m_rootNode->refresh();
114     }
115
116     if (options & Configuration) {
117         // update configuration
118     }
119
120     if (options & Files)
121         emit fileListChanged();
122 }
123
124 void QmlProject::refresh(RefreshOptions options)
125 {
126     parseProject(options);
127
128     if (options & Files)
129         m_rootNode->refresh();
130
131     QmlJS::ModelManagerInterface::ProjectInfo pinfo(this);
132     pinfo.sourceFiles = files();
133     pinfo.importPaths = importPaths();
134     Qt4ProjectManager::QmlDumpTool::pathAndEnvironment(this, &pinfo.qmlDumpPath, &pinfo.qmlDumpEnvironment);
135     m_modelManager->updateProjectInfo(pinfo);
136 }
137
138 QStringList QmlProject::convertToAbsoluteFiles(const QStringList &paths) const
139 {
140     const QDir projectDir(QFileInfo(m_fileName).dir());
141     QStringList absolutePaths;
142     foreach (const QString &file, paths) {
143         QFileInfo fileInfo(projectDir, file);
144         absolutePaths.append(fileInfo.absoluteFilePath());
145     }
146     absolutePaths.removeDuplicates();
147     return absolutePaths;
148 }
149
150 QStringList QmlProject::files() const
151 {
152     QStringList files;
153     if (m_projectItem) {
154         files = m_projectItem.data()->files();
155     } else {
156         files = m_files;
157     }
158     return files;
159 }
160
161 QString QmlProject::mainFile() const
162 {
163     if (m_projectItem)
164         return m_projectItem.data()->mainFile();
165     return QString();
166 }
167
168 bool QmlProject::validProjectFile() const
169 {
170     return !m_projectItem.isNull();
171 }
172
173 QStringList QmlProject::importPaths() const
174 {
175     QStringList importPaths;
176     if (m_projectItem)
177         importPaths = m_projectItem.data()->importPaths();
178
179     // add the default import path for the target Qt version
180     if (activeTarget()) {
181         const QmlProjectRunConfiguration *runConfig =
182                 qobject_cast<QmlProjectRunConfiguration*>(activeTarget()->activeRunConfiguration());
183         if (runConfig) {
184             const Qt4ProjectManager::QtVersion *qtVersion = runConfig->qtVersion();
185             if (qtVersion && qtVersion->isValid()) {
186                 const QString qtVersionImportPath = qtVersion->versionInfo().value("QT_INSTALL_IMPORTS");
187                 if (!qtVersionImportPath.isEmpty())
188                     importPaths += qtVersionImportPath;
189             }
190         }
191     }
192
193     return importPaths;
194 }
195
196 bool QmlProject::addFiles(const QStringList &filePaths)
197 {
198     QStringList toAdd;
199     foreach (const QString &filePath, filePaths) {
200         if (!m_projectItem.data()->matchesFile(filePath))
201             toAdd << filePaths;
202     }
203     return toAdd.isEmpty();
204 }
205
206 void QmlProject::refreshProjectFile()
207 {
208     refresh(QmlProject::ProjectFile | Files);
209 }
210
211 void QmlProject::refreshFiles(const QSet<QString> &/*added*/, const QSet<QString> &removed)
212 {
213     refresh(Files);
214     if (!removed.isEmpty())
215         m_modelManager->removeFiles(removed.toList());
216 }
217
218 QString QmlProject::displayName() const
219 {
220     return m_projectName;
221 }
222
223 QString QmlProject::id() const
224 {
225     return QLatin1String("QmlProjectManager.QmlProject");
226 }
227
228 Core::IFile *QmlProject::file() const
229 {
230     return m_file;
231 }
232
233 Internal::Manager *QmlProject::projectManager() const
234 {
235     return m_manager;
236 }
237
238 QList<ProjectExplorer::Project *> QmlProject::dependsOn()
239 {
240     return QList<Project *>();
241 }
242
243 QList<ProjectExplorer::BuildConfigWidget*> QmlProject::subConfigWidgets()
244 {
245     return QList<ProjectExplorer::BuildConfigWidget*>();
246 }
247
248 Internal::QmlProjectTarget *QmlProject::activeTarget() const
249 {
250     return static_cast<Internal::QmlProjectTarget *>(Project::activeTarget());
251 }
252
253 Internal::QmlProjectNode *QmlProject::rootProjectNode() const
254 {
255     return m_rootNode;
256 }
257
258 QStringList QmlProject::files(FilesMode) const
259 {
260     return files();
261 }
262
263 bool QmlProject::fromMap(const QVariantMap &map)
264 {
265     if (!Project::fromMap(map))
266         return false;
267
268     if (targets().isEmpty()) {
269         Internal::QmlProjectTargetFactory *factory
270                 = ExtensionSystem::PluginManager::instance()->getObject<Internal::QmlProjectTargetFactory>();
271         Internal::QmlProjectTarget *target = factory->create(this, QLatin1String(Constants::QML_VIEWER_TARGET_ID));
272         addTarget(target);
273     }
274
275     refresh(Everything);
276     // FIXME workaround to guarantee that run/debug actions are enabled if a valid file exists
277     QmlProjectRunConfiguration *runConfig = qobject_cast<QmlProjectRunConfiguration*>(activeTarget()->activeRunConfiguration());
278     if (runConfig)
279         runConfig->changeCurrentFile(0);
280
281     return true;
282 }
283
284 } // namespace QmlProjectManager
285