summaryrefslogtreecommitdiff
path: root/libopie2/opiecore/opluginloader.cpp
Unidiff
Diffstat (limited to 'libopie2/opiecore/opluginloader.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiecore/opluginloader.cpp397
1 files changed, 397 insertions, 0 deletions
diff --git a/libopie2/opiecore/opluginloader.cpp b/libopie2/opiecore/opluginloader.cpp
new file mode 100644
index 0000000..e5a0903
--- a/dev/null
+++ b/libopie2/opiecore/opluginloader.cpp
@@ -0,0 +1,397 @@
1/*
2 * LGPLv2 or later
3 * zecke@handhelds.org
4 */
5
6#include "opluginloader.h"
7
8#include <stdlib.h>
9
10
11
12namespace Opie {
13namespace Core {
14namespace Internal {
15struct OPluginLibraryHolder {
16 static OPluginLibraryHolder *self();
17 QLibrary *getLibrary( const QString& );
18 void putLibrary( QLibrary* );
19private:
20 OPluginLibraryHolder();
21 ~OPluginLibraryHolder();
22 OPluginLibraryHolder* m_self;
23
24};
25}
26
27}}
28/**
29 * \brief Creates an Empty OPluginItem
30 *
31 * create an empty pluginitem. Position is set to -1 and the
32 * other things are used with the default ctors
33 */
34OPluginItem::OPluginItem()
35 : m_pos( -1 ) {
36}
37
38/**
39 * \brief Create an OPluginItem
40 *
41 * Create a Plugin Item with all information.
42 *
43 * @param name The if available translated Name
44 * @param conf The name of the config group
45 * @param path The path to the plugin
46 * @param pos The position of the plugin if used for sorting
47 *
48 */
49OPluginItem::OPluginItem( const QString& name, const QCString& conf,
50 const QString& path, int pos = -1 )
51 : m_name( name ), m_conf( conf ), m_path( path ), m_pos( pos ) {
52}
53
54/**
55 * \brief simple d'tor
56 */
57OPluginItem::~OPluginItem() {
58}
59
60/**
61 * operator to test equalness of two OPluginItem
62 */
63bool OPluginItem::operator==( const OPluginItem& r )const{
64 if ( m_pos != r.m_pos ) return false;
65 if ( m_name != r.m_name ) return false;
66 if ( m_conf != r.m_conf ) return false;
67 if ( m_path != r.m_path ) return false;
68 return true;
69}
70
71bool OPluginItem::operator!=( const OPluginItem& r ) {
72 return !( *this == r );
73}
74
75/**
76 * return the name of this Plugin
77 */
78QString OPluginItem::name()const {
79 return m_name;
80}
81
82/**
83 * return the config key
84 */
85QCString OPluginItem::configKey()const{
86 return m_conf;
87}
88
89/**
90 * return the path of the plugin
91 */
92QString OPluginItem::path()const {
93 return m_path;
94}
95
96int OPluginItem::position()const{
97 return m_pos;
98}
99
100/**
101 * Set the name of the Plugin Item
102 * @param name
103 */
104void OPluginItem::setName( const QString& name ) {
105 m_name = name;
106}
107
108/**
109 * Set the config key
110 * @param key The config key/group of this plugin
111 */
112void OPluginItem::setConfigKey( const QCString& conf ) {
113 m_conf = conf;
114}
115
116/**
117 * Set the path of Plugin Item
118 * @param name The path of the plugin
119 */
120void OPluginItem::setPath( const QString& name ) {
121 m_name = name;
122}
123
124/**
125 * Set the position
126 * @param pos The position
127 */
128void OPluginItem::setPosition( int pos ) {
129 m_pos = pos;
130}
131
132
133
134/**
135 * \brief create a PluginLoader
136 *
137 * Create a PluginLoader autoDelete is set to false
138 *
139 * \code
140 * Opie::Core::OGenericPluginLoader loader("myapp-plugin");
141 * Opie::Core::OPluginItem::List lst = loader.filtered();
142 * for(Opie::Core::OPluginItem::List::Iterator it = lst.begin(); it!=lst.end();++it){
143 * MyIface* iface = static_cast<MyIface*>(loader.load(*it,IID_MyIface));
144 * }
145 * \endcode
146 *
147 * \code
148 * Opie::Core::OGenericPluginLoader loader("myapp-plugin");
149 * Opie::Core::OPluginItem::List lst = loader.filtered();
150 * for(Opie::Core::OPluginItem::List::Iterator it = lst.begin(); it!=lst.end();++it){
151 * MyIface* iface = static_cast<MyIface*>(loader.load(*it,IID_MyIface));
152 * }
153 * ...
154 * loader.clear();
155 *
156 * \endcode
157 *
158 * @param name The name of the plugin directory.
159 * @param isSorted Tell the PluginLoader if your Plugins are sorted
160 */
161OGenericPluginLoader::OGenericPluginLoader( const QString& name, bool isSorted)
162 : m_dir( name ), m_autoDelete( false ), m_isSafeMode( false ),
163 m_isSorted( isSorted ), m_readConfig( false )
164{
165 setPluginDir( QPEApplication::qpeDir() + "/plugins/"+name );
166}
167
168
169/**
170 * calls clear if autoDelete is true. This will release all interfaces
171 * and remove the library from this process if the refcount falls to zero
172 */
173OGenericPluginLoader::~OGenericPluginLoader() {
174 if ( m_autoDelete )
175 clear();
176}
177
178/**
179 * enable autoDelete. This will call clear on the d'tor
180 *
181 * @see ~OGenericPluginLoader
182 * @see clear()
183 */
184void OGenericPluginLoader::setAutoDelete( bool t ) {
185 m_autoDelete = t;
186}
187
188/**
189 * see if autoDelet is enabled
190 */
191bool OGenericPluginLoader::autoDelete()const{
192 return m_autoDelete;
193}
194
195/**
196 * This will unload all returned QUnknownInterfaces by load. Unload
197 * will be called.
198 */
199void OGenericPluginLoader::clear() {
200 QPtrDictIterator<QLibrary> it( m_library );
201 for ( ;it.current(); )
202 unload( static_cast<QUnknownInterface*>( it.currentKey() ) );
203}
204
205/**
206 * This will take the iface from the internal QPtrDict, Release it,
207 * and deref the libray used.
208 * The visibility depends on the QPtrDict.
209 * @see QPtrDict::insert
210 */
211void OGenericPluginLoader::unload( QUnknownInterface* iface ) {
212 if ( !iface )
213 return;
214
215 iface->release();
216 OPluginLibraryHolder::self()->deref( m_library.take( iface ) );
217}
218
219/**
220 * This tells you
221 * if by previous tries to load, loading crashed your application.
222 * If isInSafeMode you can use the GUI to configure the plugins prior to loading
223 *
224 * @return true if prior loading failed
225 */
226bool OGenericPluginLoader::isInSafeMode()const {
227 if ( !m_readConfig )
228 readConfig();
229 return m_isSafeMode;
230}
231
232/**
233 * return if the plugin list is sorted.
234 */
235bool OGenericPluginLoader::isSorted()const {
236 if ( !m_readConfig )
237 readConfig();
238 return m_isSorted;
239}
240
241/**
242 * Return the list of all available plugins. This will go through all plugin
243 * directories and search for your type of plugins ( by subdir )
244 *
245 * @param sorted Tell if you want to have the positions sorted. This only makes sense if you
246 */
247OPluginItem::List OGenericPluginLoader::allAvailable( bool sorted )const {
248 OPluginItem::List lst;
249 for ( QStringList::ConstIterator it = m_plugDirs.begin(); it != m_plugDirs.end(); ++it )
250 lst += plugins( *it, sorted, false );
251
252 if ( sorted )
253 qHeapSort( lst );
254 return lst;
255}
256
257/**
258 * Return only activated plugins.
259 *
260 * @param sorted If the list should be sorted
261 */
262OPluginItem::List OGenericPluginLoader::filtered( bool sorted )const {
263 OPluginItem::List lst;
264 for ( QStringList::ConstIterator it = m_plugDirs.begin(); it != m_plugDirs.end(); ++it )
265 lst += plugins( *it, sorted, true );
266
267 if ( sorted )
268 qHeapSort( lst );
269 return lst;
270}
271
272
273/**
274 *
275 */
276QUnknownInterface* OGenericPluginLoader::load( const OPluginItem& item, const QUuid& uuid) {
277 /*
278 * Check if there could be a library
279 */
280 QString pa = item.path();
281 if ( pa.isEmpty() )
282 return 0l;
283
284 /*
285 * See if we get a library
286 * return if we've none
287 */
288 setSafeMode( true );
289 QLibrary *lib = OPluginLibraryHolder::self()->getLibrary( pa );
290 if ( !lib ) {
291 setSafeMode();
292 return 0l;
293 }
294
295 /**
296 * try to load the plugin and just in case initialize the pointer to a pointer again
297 */
298 QUnknownInterface** iface = 0;
299 if ( lib->queryInterface( uuid, iface ) == QS_OK ) {
300 installTranslators(pa.left( pa.find(".")));
301 m_library.insert( *iface, lib );
302 }else
303 *iface = 0;
304
305 setSafeMode();
306
307 return *iface;
308}
309
310void OGenericPluginLoader::readConfig() {
311 m_readConfig = true;
312
313 /* read the config for SafeMode */
314 OConfig conf( m_name + "-odpplugins" );
315 conf.setGroup( "General" );
316 m_isSafeMode = conf.readBoolEntry( "SafeMode", false );
317}
318
319void OGenericPluginLoader::setSafeMode(bool b) {
320 OConfig conf( m_name + "-odpplugins" );
321 conf.setGroup( "General" );
322 conf.writeEntry( "SafeMode", b );
323}
324
325void OGenericPluginLoader::setPluginDirs( const QStringList& lst ) {
326 m_plugDirs = lst;
327}
328
329void OGenericPluginLoader::setPluginDir( const QString& str) {
330 m_plugDirs.clear();
331 m_plugDirs.append( str );
332}
333
334bool &OGenericPluginLoader::isSafeMode()const {
335 return m_isSafeMode;
336}
337
338bool &OGenericPluginLoader::isSorted()const {
339 return m_isSorted;
340}
341
342OPluginItem::List OGenericPluginLoader::plugins( const QString& dir, bool sorted, bool disabled ) {
343#ifdef Q_OS_MACX
344 QDir dir( dir, "lib*.dylib" );
345#else
346 QDir dir( dir, "lib*.so" );
347#endif
348 /*
349 * get excluded list and then iterate over them
350 */
351 OConfig cfg( m_name+"odpplugins" );
352 cfg.setGroup( dir );
353 QStringList excludes = cfg.readListEntry( "Excluded" );
354
355 QStringList list = dir.entryList();
356// for (
357
358}
359
360
361QStringList OGenericPluginLoader::languageList() {
362 if ( languageList.isEmpty() ) {
363 /*
364 * be_BY.CP1251 We will add, be_BY.CP1251,be_BY,be
365 * to our list of languages.
366 */
367 QString str = ::getenv( "LANG" );
368 m_languages += str;
369 int pos = str.find( '.' );
370
371 if ( pos > 0 )
372 m_languages += str.left( pos );
373
374 int n_pos = str.find( '_' );
375 if ( pos > 0 && n_pos >= pos )
376 m_languages += str.left( n_pos );
377
378 }
379 return m_languages;
380}
381
382void OGenericPluginLoader::installTranslators(const QString& type) {
383 QStringList lst = languageList();
384 for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) {
385 QTranslator* trans = new QTranslator( qApp );
386 QString tfn = QPEApplication::qpeDir()+"/i18n/" + lang + "/" + type + ".qm" ;
387 if ( trans->load( tfn ) )
388 qApp->installTranslator( trans );
389 else
390 delete trans;
391 }
392}
393
394
395
396}
397}