a8d771d31e78a146d1e735c39cc9875e1ce56ee5
[profile/ivi/qtdeclarative.git] / src / qml / debugger / qqmlinspectorservice.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
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 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qqmlinspectorservice_p.h"
43 #include "qqmlinspectorinterface_p.h"
44 #include "qqmldebugserver_p.h"
45
46 #include <private/qqmlglobal_p.h>
47
48 #include <QtCore/QCoreApplication>
49 #include <QtCore/QDebug>
50 #include <QtCore/QDir>
51 #include <QtCore/QPluginLoader>
52
53 // print detailed information about loading of plugins
54 DEFINE_BOOL_CONFIG_OPTION(qmlDebugVerbose, QML_DEBUGGER_VERBOSE)
55
56 QT_BEGIN_NAMESPACE
57
58 Q_GLOBAL_STATIC(QQmlInspectorService, serviceInstance)
59
60 QQmlInspectorService::QQmlInspectorService()
61     : QQmlDebugService(QStringLiteral("QmlInspector"), 1)
62     , m_currentInspectorPlugin(0)
63 {
64     registerService();
65 }
66
67 QQmlInspectorService *QQmlInspectorService::instance()
68 {
69     return serviceInstance();
70 }
71
72 void QQmlInspectorService::addView(QObject *view)
73 {
74     m_views.append(view);
75     updateState();
76 }
77
78 void QQmlInspectorService::removeView(QObject *view)
79 {
80     m_views.removeAll(view);
81     updateState();
82 }
83
84 void QQmlInspectorService::sendMessage(const QByteArray &message)
85 {
86     if (state() != Enabled)
87         return;
88
89     QQmlDebugService::sendMessage(message);
90 }
91
92 void QQmlInspectorService::stateChanged(State /*state*/)
93 {
94     QMetaObject::invokeMethod(this, "updateState", Qt::QueuedConnection);
95 }
96
97 void QQmlInspectorService::updateState()
98 {
99     if (m_views.isEmpty()) {
100         if (m_currentInspectorPlugin) {
101             m_currentInspectorPlugin->deactivate();
102             m_currentInspectorPlugin = 0;
103         }
104         return;
105     }
106
107     if (state() == Enabled) {
108         if (m_inspectorPlugins.isEmpty())
109             loadInspectorPlugins();
110
111         if (m_inspectorPlugins.isEmpty()) {
112             qWarning() << "QQmlInspector: No plugins found.";
113             QQmlDebugServer::instance()->removeService(this);
114             return;
115         }
116
117         foreach (QQmlInspectorInterface *inspector, m_inspectorPlugins) {
118             if (inspector->canHandleView(m_views.first())) {
119                 m_currentInspectorPlugin = inspector;
120                 break;
121             }
122         }
123
124         if (!m_currentInspectorPlugin) {
125             qWarning() << "QQmlInspector: No plugin available for view '" << m_views.first()->metaObject()->className() << "'.";
126             return;
127         }
128         m_currentInspectorPlugin->activate(m_views.first());
129     } else {
130         if (m_currentInspectorPlugin) {
131             m_currentInspectorPlugin->deactivate();
132             m_currentInspectorPlugin = 0;
133         }
134     }
135 }
136
137 void QQmlInspectorService::messageReceived(const QByteArray &message)
138 {
139     QMetaObject::invokeMethod(this, "processMessage", Qt::QueuedConnection, Q_ARG(QByteArray, message));
140 }
141
142 void QQmlInspectorService::processMessage(const QByteArray &message)
143 {
144     if (m_currentInspectorPlugin)
145         m_currentInspectorPlugin->clientMessage(message);
146 }
147
148 void QQmlInspectorService::loadInspectorPlugins()
149 {
150     QStringList pluginCandidates;
151     const QStringList paths = QCoreApplication::libraryPaths();
152     foreach (const QString &libPath, paths) {
153         const QDir dir(libPath + QLatin1String("/qmltooling"));
154         if (dir.exists())
155             foreach (const QString &pluginPath, dir.entryList(QDir::Files))
156                 pluginCandidates << dir.absoluteFilePath(pluginPath);
157     }
158
159     foreach (const QString &pluginPath, pluginCandidates) {
160         if (qmlDebugVerbose())
161             qDebug() << "QQmlInspector: Trying to load plugin " << pluginPath << "...";
162
163         QPluginLoader loader(pluginPath);
164         if (!loader.load()) {
165             if (qmlDebugVerbose())
166                 qDebug() << "QQmlInspector: Error while loading: " << loader.errorString();
167
168             continue;
169         }
170
171         QQmlInspectorInterface *inspector =
172                 qobject_cast<QQmlInspectorInterface*>(loader.instance());
173         if (inspector) {
174             if (qmlDebugVerbose())
175                 qDebug() << "QQmlInspector: Plugin successfully loaded.";
176             m_inspectorPlugins << inspector;
177         } else {
178             if (qmlDebugVerbose())
179                 qDebug() << "QQmlInspector: Plugin does not implement interface QQmlInspectorInterface.";
180
181             loader.unload();
182         }
183     }
184 }
185
186 QT_END_NAMESPACE