OSDN Git Service

QmlJS: Fix qmldump not working for qmlproject projects.
[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
36 #include <coreplugin/icore.h>
37 #include <coreplugin/messagemanager.h>
38 #include <extensionsystem/pluginmanager.h>
39 #include <projectexplorer/filewatcher.h>
40 #include <qt4projectmanager/qmldumptool.h>
41 #include <qmljs/qmljsmodelmanagerinterface.h>
42
43 #include <QTextStream>
44 #include <QDeclarativeComponent>
45 #include <QtDebug>
46
47 namespace QmlProjectManager {
48
49 QmlProject::QmlProject(Internal::Manager *manager, const QString &fileName)
50     : m_manager(manager),
51       m_fileName(fileName),
52       m_modelManager(ExtensionSystem::PluginManager::instance()->getObject<QmlJS::ModelManagerInterface>()),
53       m_fileWatcher(new ProjectExplorer::FileWatcher(this)),
54       m_targetFactory(new Internal::QmlProjectTargetFactory(this))
55 {
56     setSupportedTargetIds(QSet<QString>() << QLatin1String(Constants::QML_VIEWER_TARGET_ID));
57     QFileInfo fileInfo(m_fileName);
58     m_projectName = fileInfo.completeBaseName();
59
60     m_file = new Internal::QmlProjectFile(this, fileName);
61     m_rootNode = new Internal::QmlProjectNode(this, m_file);
62
63     m_fileWatcher->addFile(fileName),
64     connect(m_fileWatcher, SIGNAL(fileChanged(QString)),
65             this, SLOT(refreshProjectFile()));
66
67     m_manager->registerProject(this);
68 }
69
70 QmlProject::~QmlProject()
71 {
72     m_manager->unregisterProject(this);
73
74     delete m_projectItem.data();
75     delete m_rootNode;
76 }
77
78 QDir QmlProject::projectDir() const
79 {
80     return QFileInfo(file()->fileName()).dir();
81 }
82
83 QString QmlProject::filesFileName() const
84 { return m_fileName; }
85
86 void QmlProject::parseProject(RefreshOptions options)
87 {
88     if (options & Files) {
89         if (options & ProjectFile)
90             delete m_projectItem.data();
91         if (!m_projectItem) {
92             QFile file(m_fileName);
93             if (file.open(QFile::ReadOnly)) {
94                 QDeclarativeComponent *component = new QDeclarativeComponent(&m_engine, this);
95                 component->setData(file.readAll(), QUrl::fromLocalFile(m_fileName));
96                 if (component->isReady()
97                     && qobject_cast<QmlProjectItem*>(component->create())) {
98                     m_projectItem = qobject_cast<QmlProjectItem*>(component->create());
99                     connect(m_projectItem.data(), SIGNAL(qmlFilesChanged(QSet<QString>, QSet<QString>)),
100                             this, SLOT(refreshFiles(QSet<QString>, QSet<QString>)));
101                 } else {
102                     Core::MessageManager *messageManager = Core::ICore::instance()->messageManager();
103                     messageManager->printToOutputPane(tr("Error while loading project file!"));
104                     messageManager->printToOutputPane(component->errorString(), true);
105                 }
106             }
107         }
108         if (m_projectItem) {
109             m_projectItem.data()->setSourceDirectory(projectDir().path());
110             m_modelManager->updateSourceFiles(m_projectItem.data()->files(), true);
111         }
112         m_rootNode->refresh();
113     }
114
115     if (options & Configuration) {
116         // update configuration
117     }
118
119     if (options & Files)
120         emit fileListChanged();
121 }
122
123 void QmlProject::refresh(RefreshOptions options)
124 {
125     parseProject(options);
126
127     if (options & Files)
128         m_rootNode->refresh();
129
130     QmlJS::ModelManagerInterface::ProjectInfo pinfo(this);
131     pinfo.sourceFiles = files();
132     pinfo.importPaths = importPaths();
133
134     if (pinfo.qmlDumpPath.isNull()) {
135         pinfo.qmlDumpPath = Qt4ProjectManager::QmlDumpTool::qmlDumpPath();
136     }
137
138     m_modelManager->updateProjectInfo(pinfo);
139 }
140
141 QStringList QmlProject::convertToAbsoluteFiles(const QStringList &paths) const
142 {
143     const QDir projectDir(QFileInfo(m_fileName).dir());
144     QStringList absolutePaths;
145     foreach (const QString &file, paths) {
146         QFileInfo fileInfo(projectDir, file);
147         absolutePaths.append(fileInfo.absoluteFilePath());
148     }
149     absolutePaths.removeDuplicates();
150     return absolutePaths;
151 }
152
153 QStringList QmlProject::files() const
154 {
155     QStringList files;
156     if (m_projectItem) {
157         files = m_projectItem.data()->files();
158     } else {
159         files = m_files;
160     }
161     return files;
162 }
163
164 bool QmlProject::validProjectFile() const
165 {
166     return !m_projectItem.isNull();
167 }
168
169 QStringList QmlProject::importPaths() const
170 {
171     QStringList importPaths;
172     if (m_projectItem)
173         importPaths = m_projectItem.data()->importPaths();
174     return importPaths;
175 }
176
177 bool QmlProject::addFiles(const QStringList &filePaths)
178 {
179     QStringList toAdd;
180     foreach (const QString &filePath, filePaths) {
181         if (!m_projectItem.data()->matchesFile(filePath))
182             toAdd << filePaths;
183     }
184     return toAdd.isEmpty();
185 }
186
187 void QmlProject::refreshProjectFile()
188 {
189     refresh(QmlProject::ProjectFile | Files);
190 }
191
192 void QmlProject::refreshFiles(const QSet<QString> &/*added*/, const QSet<QString> &removed)
193 {
194     refresh(Files);
195     if (!removed.isEmpty())
196         m_modelManager->removeFiles(removed.toList());
197 }
198
199 QString QmlProject::displayName() const
200 {
201     return m_projectName;
202 }
203
204 QString QmlProject::id() const
205 {
206     return QLatin1String("QmlProjectManager.QmlProject");
207 }
208
209 Core::IFile *QmlProject::file() const
210 {
211     return m_file;
212 }
213
214 Internal::Manager *QmlProject::projectManager() const
215 {
216     return m_manager;
217 }
218
219 QList<ProjectExplorer::Project *> QmlProject::dependsOn()
220 {
221     return QList<Project *>();
222 }
223
224 ProjectExplorer::BuildConfigWidget *QmlProject::createConfigWidget()
225 {
226     return 0;
227 }
228
229 QList<ProjectExplorer::BuildConfigWidget*> QmlProject::subConfigWidgets()
230 {
231     return QList<ProjectExplorer::BuildConfigWidget*>();
232 }
233
234 Internal::QmlProjectTargetFactory *QmlProject::targetFactory() const
235 {
236     return m_targetFactory;
237 }
238
239 Internal::QmlProjectTarget *QmlProject::activeTarget() const
240 {
241     return static_cast<Internal::QmlProjectTarget *>(Project::activeTarget());
242 }
243
244 Internal::QmlProjectNode *QmlProject::rootProjectNode() const
245 {
246     return m_rootNode;
247 }
248
249 QStringList QmlProject::files(FilesMode) const
250 {
251     return files();
252 }
253
254 bool QmlProject::fromMap(const QVariantMap &map)
255 {
256     if (!Project::fromMap(map))
257         return false;
258
259     if (targets().isEmpty()) {
260         Internal::QmlProjectTarget *target(targetFactory()->create(this, QLatin1String(Constants::QML_VIEWER_TARGET_ID)));
261         addTarget(target);
262     }
263
264     refresh(Everything);
265     // FIXME workaround to guarantee that run/debug actions are enabled if a valid file exists
266     QmlProjectRunConfiguration *runConfig = qobject_cast<QmlProjectRunConfiguration*>(activeTarget()->activeRunConfiguration());
267     if (runConfig)
268         runConfig->changeCurrentFile(0);
269
270     return true;
271 }
272
273 } // namespace QmlProjectManager
274