Warning: That file was not part of the compilation database. It may have many parsing errors.

1// This file is part of Pate, Kate' Python scripting plugin.
2//
3// Copyright (C) 2006 Paul Giannaros <paul@giannaros.org>
4// Copyright (C) 2012, 2013 Shaheed Haque <srhaque@theiet.org>
5// Copyright (C) 2013 Alex Turbov <i.zaufi@gmail.com>
6//
7// This library is free software; you can redistribute it and/or
8// modify it under the terms of the GNU Lesser General Public
9// License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) version 3, or any
11// later version accepted by the membership of KDE e.V. (or its
12// successor approved by the membership of KDE e.V.), which shall
13// act as a proxy defined in Section 6 of version 3 of the license.
14//
15// This library is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18// Lesser General Public License for more details.
19//
20// You should have received a copy of the GNU Lesser General Public
21// License along with this library. If not, see <http://www.gnu.org/licenses/>.
22//
23
24#ifndef __PATE_ENGINE_H__
25# define __PATE_ENGINE_H__
26
27# include "version_checker.h"
28
29# include <KService>
30# include <KUrl>
31# include <Python.h>
32# include <QAbstractItemModel>
33# include <QList>
34# include <QStringList>
35
36namespace Pate {
37class Python; // fwd decl
38
39/**
40 * The Engine class hosts the Python interpreter, loading
41 * it into memory within Kate, and then with finding and
42 * loading all of the Pate plugins.
43 *
44 * \attention Qt/KDE do not use exceptions (unfortunately),
45 * so this class must be initialized in two steps:
46 * - create an instance (via constructor)
47 * - try to initialize the rest (via \c Engine::tryInitializeGetFailureReason())
48 * If latter returns a non empty (failure reason) string, the only member
49 * can be called is conversion to boolean! (which is implemented as safe-bool idiom [1])
50 * Calling others leads to UB!
51 *
52 * \sa [1] http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool
53 */
54class Engine : public QAbstractItemModel
55{
56 Q_OBJECT
57
58 typedef void (Engine::*bool_type)() const;
59 void unspecified_true_bool_type() const {}
60
61public:
62 /// \todo Turn into a class w/ accessors
63 class PluginState
64 {
65 public:
66 /// \name Immutable accessors
67 //@{
68 QString pythonModuleName() const;
69 const QString& errorReason() const;
70 bool isEnabled() const;
71 bool isBroken() const;
72 bool isUnstable() const;
73 //@}
74
75 private:
76 friend class Engine;
77
78 PluginState();
79 /// Transfort Python module name into a file path part
80 QString moduleFilePathPart() const;
81
82 KService::Ptr m_service;
83 QString m_pythonModule;
84 QString m_errorReason;
85 bool m_enabled;
86 bool m_broken;
87 bool m_unstable;
88 bool m_isDir;
89 };
90
91 /// Default constructor: initialize Python interpreter
92 Engine();
93 /// Cleanup everything on unload
94 ~Engine();
95
96 //BEGIN QAbstractItemModel interface
97 virtual int columnCount(const QModelIndex&) const /*override*/;
98 virtual int rowCount(const QModelIndex&) const /*override*/;
99 virtual QModelIndex index(int, int, const QModelIndex&) const /*override*/;
100 virtual QModelIndex parent(const QModelIndex&) const /*override*/;
101 virtual QVariant headerData(int, Qt::Orientation, int) const /*override*/;
102 virtual QVariant data(const QModelIndex&, int) const /*override*/;
103 virtual Qt::ItemFlags flags(const QModelIndex&) const /*override*/;
104 virtual bool setData(const QModelIndex&, const QVariant&, int) /*override*/;
105 //END QAbstractItemModel interface
106
107 void readSessionPluginsConfiguration(KConfigBase*);
108 void writeSessionPluginsConfiguration(KConfigBase*);
109
110 void setEnabledPlugins(const QStringList&); ///< Set enabled plugins to the model
111 void tryLoadEnabledPlugins(); ///< Try to load enabled plugins
112 QStringList enabledPlugins() const; ///< Form a list of enabled plugins
113 const QList<PluginState>& plugins() const; ///< Provide immutable access to found plugins
114 QString tryInitializeGetFailureReason(); ///< Try to initialize Python interpreter
115 operator bool_type() const; ///< Check if instance is usable
116 void setBroken(); ///< Make it broken by some external reason
117
118public Q_SLOTS:
119 void readGlobalPluginsConfiguration(); ///< Load plugins' configuration.
120 void saveGlobalPluginsConfiguration(); ///< Write out plugins' configuration.
121 void unloadAllModules();
122
123protected:
124 void scanPlugins(); ///< Search for available plugins
125 void loadModule(int); ///< Load module by index in \c m_plugins
126 void unloadModule(int); ///< Unload module by index in \c m_plugins
127
128private:
129 // Simulate strong typed enums from C++11
130 struct Column
131 {
132 enum type
133 {
134 NAME
135 , COMMENT
136 , LAST__
137 };
138 };
139
140 static bool isServiceUsable(const KService::Ptr&); ///< Make sure that service is usable
141 static bool setModuleProperties(PluginState&);
142 static void verifyDependenciesSetStatus(PluginState&);
143 static QPair<QString, version_checker> parseDependency(const QString&);
144 static version tryObtainVersionFromTuple(PyObject*);
145 static version tryObtainVersionFromString(PyObject*);
146
147 PyObject* m_configuration; ///< Application-wide configuration data
148 PyObject* m_sessionConfiguration; ///< Session-wide configuration data
149 QList<PluginState> m_plugins; ///< List of available plugins
150 bool m_engineIsUsable; ///< Is engine loaded Ok?
151};
152
153inline QString Engine::PluginState::pythonModuleName() const
154{
155 return m_service->library();
156}
157inline QString Pate::Engine::PluginState::moduleFilePathPart() const
158{
159 /// \todo Use \c QString::split() and \c KUrl to form a valid path
160 return m_service->library().replace(".", "/");
161}
162inline const QString& Engine::PluginState::errorReason() const
163{
164 return m_errorReason;
165}
166inline bool Engine::PluginState::isEnabled() const
167{
168 return m_enabled;
169}
170inline bool Engine::PluginState::isBroken() const
171{
172 return m_broken;
173}
174inline bool Engine::PluginState::isUnstable() const
175{
176 return m_unstable;
177}
178
179inline const QList<Engine::PluginState>& Engine::plugins() const
180{
181 return m_plugins;
182}
183
184inline Engine::operator bool_type() const
185{
186 return m_engineIsUsable ? &Engine::unspecified_true_bool_type : 0;
187}
188
189inline void Engine::setBroken()
190{
191 m_engineIsUsable = false;
192}
193
194} // namespace Pate
195#endif // __PATE_ENGINE_H__
196// kate: indent-width 4;
197

Warning: That file was not part of the compilation database. It may have many parsing errors.