summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/examples/opiecore/oplugins/oplugins.cpp37
-rw-r--r--libopie2/examples/opiecore/oplugins/oplugins.pro11
-rw-r--r--libopie2/opiecore/opiecore.pro4
-rw-r--r--libopie2/opiecore/opluginloader.cpp272
-rw-r--r--libopie2/opiecore/opluginloader.h22
5 files changed, 268 insertions, 78 deletions
diff --git a/libopie2/examples/opiecore/oplugins/oplugins.cpp b/libopie2/examples/opiecore/oplugins/oplugins.cpp
new file mode 100644
index 0000000..4aa2da5
--- a/dev/null
+++ b/libopie2/examples/opiecore/oplugins/oplugins.cpp
@@ -0,0 +1,37 @@
1/*
2 * You may copy, modify and or distribute without any limitation
3 */
4#include <opie2/odebug.h>
5#include <opie2/opluginloader.h>
6
7#include <opie2/todayplugininterface.h>
8
9using Opie::Core::OPluginItem;
10using Opie::Core::OGenericPluginLoader;
11
12void debugLst( const OPluginItem::List& lst ) {
13 for ( OPluginItem::List::ConstIterator it = lst.begin(); it != lst.end(); ++it )
14 odebug << "Name " << (*it).name() << " " << (*it).path() << " " << (*it).position() << oendl;
15}
16
17
18int main( void ) {
19 OGenericPluginLoader loader( "today", true );
20 loader.setAutoDelete( true );
21
22 odebug << "IS in Safe Mode" << loader.isInSafeMode() << oendl;
23
24 OPluginItem::List lst = loader.allAvailable( true );
25 debugLst( lst );
26
27 lst = loader.filtered( true );
28 debugLst( lst );
29
30 for ( OPluginItem::List::Iterator it = lst.begin(); it != lst.end(); ++it ) {
31 QUnknownInterface* iface = loader.load( *it, IID_TodayPluginInterface );
32 }
33
34 /*
35 * now it's autodelete so cleaned up for us
36 */
37}
diff --git a/libopie2/examples/opiecore/oplugins/oplugins.pro b/libopie2/examples/opiecore/oplugins/oplugins.pro
new file mode 100644
index 0000000..7286de9
--- a/dev/null
+++ b/libopie2/examples/opiecore/oplugins/oplugins.pro
@@ -0,0 +1,11 @@
1TEMPLATE = app
2CONFIG += qt warn_on
3
4SOURCES = oplugins.cpp
5
6INCLUDEPATH += $(OPIEDIR)/include
7DEPENDSPATH += $(OPIEDIR)/include
8
9LIBS += -lopiecore2
10
11include ( $(OPIEDIR)/include.pro )
diff --git a/libopie2/opiecore/opiecore.pro b/libopie2/opiecore/opiecore.pro
index a9562b5..5056d48 100644
--- a/libopie2/opiecore/opiecore.pro
+++ b/libopie2/opiecore/opiecore.pro
@@ -9,2 +9,3 @@ HEADERS = oapplication.h \
9 okeyconfigmanager.h \ 9 okeyconfigmanager.h \
10 opluginloader.h \
10 oprocess.h \ 11 oprocess.h \
@@ -21,4 +22,5 @@ SOURCES = oapplication.cpp \
21 okeyconfigmanager.cpp \ 22 okeyconfigmanager.cpp \
23 opluginloader.cpp \
22 oprocess.cpp \ 24 oprocess.cpp \
23 oprocctrl.cpp \ 25 oprocctrl.cpp \
24 ostorageinfo.cpp \ 26 ostorageinfo.cpp \
diff --git a/libopie2/opiecore/opluginloader.cpp b/libopie2/opiecore/opluginloader.cpp
index e5a0903..b473cd7 100644
--- a/libopie2/opiecore/opluginloader.cpp
+++ b/libopie2/opiecore/opluginloader.cpp
@@ -6,2 +6,9 @@
6#include "opluginloader.h" 6#include "opluginloader.h"
7#include "oconfig.h"
8
9#include <qpe/qpeapplication.h>
10
11#include <qdir.h>
12#include <qdict.h>
13#include <qtl.h>
7 14
@@ -16,13 +23,80 @@ struct OPluginLibraryHolder {
16 static OPluginLibraryHolder *self(); 23 static OPluginLibraryHolder *self();
17 QLibrary *getLibrary( const QString& ); 24 QLibrary *ref( const QString& );
18 void putLibrary( QLibrary* ); 25 void deref( QLibrary* );
19private: 26private:
27
20 OPluginLibraryHolder(); 28 OPluginLibraryHolder();
21 ~OPluginLibraryHolder(); 29 ~OPluginLibraryHolder();
22 OPluginLibraryHolder* m_self; 30 QDict<QLibrary> m_libs;
23 31 static OPluginLibraryHolder* m_self;
24}; 32};
33
34 OPluginLibraryHolder* OPluginLibraryHolder::m_self = 0;
35 OPluginLibraryHolder* OPluginLibraryHolder::self() {
36 if ( !m_self )
37 m_self = new OPluginLibraryHolder;
38
39 return m_self;
40 }
41
42 OPluginLibraryHolder::OPluginLibraryHolder() {}
43 OPluginLibraryHolder::~OPluginLibraryHolder() {}
44
45 /*
46 * We do simple ref counting... We will add the QLibrary again
47 * and again to the dictionary and on deref we will pop and pop it
48 * until there are no more library and we will unload and delete the library
49 * luckily dlopen does some ref counting as well so we don't need
50 * to hack QPEApplication
51 */
52 QLibrary* OPluginLibraryHolder::ref(const QString& str) {
53 QLibrary *lib = m_libs[str];
54
55 /* if not in the dict try to load it */
56 if ( !lib ) {
57 lib = new QLibrary( str, QLibrary::Immediately );
58 if ( !lib->isLoaded() ) {
59 delete lib;
60 return 0l;
61 }
62 }
63
64 /* now refcount one up */
65 m_libs.insert( str, lib );
66 return lib;
67 }
68
69 /*
70 * 'unshadow' the items until we're the last then unload and delete
71 */
72 void OPluginLibraryHolder::deref( QLibrary* lib ) {
73 if ( !lib )
74 return;
75
76 QString str = lib->library();
77 /* no need to check if the lib was inserted or such */
78 (void) m_libs.take( str );
79 if ( !m_libs[str] ) {
80 lib->unload();
81 delete lib;
82 }
83 }
84}
85
86/**
87 * We want values with 30,29,28 at the beginning of the list
88 */
89
90bool operator<( const OPluginItem& l, const OPluginItem& r ) {
91 return l.position() > r.position();
92}
93
94bool operator>( const OPluginItem& l, const OPluginItem& r ) {
95 return l.position() < r.position();
96}
97
98bool operator<=( const OPluginItem& l, const OPluginItem& r ) {
99 return l.position() >= r.position();
25} 100}
26 101
27}}
28/** 102/**
@@ -43,3 +117,2 @@ OPluginItem::OPluginItem()
43 * @param name The if available translated Name 117 * @param name The if available translated Name
44 * @param conf The name of the config group
45 * @param path The path to the plugin 118 * @param path The path to the plugin
@@ -48,5 +121,4 @@ OPluginItem::OPluginItem()
48 */ 121 */
49OPluginItem::OPluginItem( const QString& name, const QCString& conf, 122OPluginItem::OPluginItem( const QString& name, const QString& path, int pos )
50 const QString& path, int pos = -1 ) 123 : m_name( name ), m_path( path ), m_pos( pos ) {
51 : m_name( name ), m_conf( conf ), m_path( path ), m_pos( pos ) {
52} 124}
@@ -65,3 +137,2 @@ bool OPluginItem::operator==( const OPluginItem& r )const{
65 if ( m_name != r.m_name ) return false; 137 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; 138 if ( m_path != r.m_path ) return false;
@@ -70,3 +141,3 @@ bool OPluginItem::operator==( const OPluginItem& r )const{
70 141
71bool OPluginItem::operator!=( const OPluginItem& r ) { 142bool OPluginItem::operator!=( const OPluginItem& r )const{
72 return !( *this == r ); 143 return !( *this == r );
@@ -82,9 +153,2 @@ QString OPluginItem::name()const {
82/** 153/**
83 * return the config key
84 */
85QCString OPluginItem::configKey()const{
86 return m_conf;
87}
88
89/**
90 * return the path of the plugin 154 * return the path of the plugin
@@ -108,10 +172,2 @@ void OPluginItem::setName( const QString& name ) {
108/** 172/**
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 173 * Set the path of Plugin Item
@@ -162,5 +218,6 @@ OGenericPluginLoader::OGenericPluginLoader( const QString& name, bool isSorted)
162 : m_dir( name ), m_autoDelete( false ), m_isSafeMode( false ), 218 : m_dir( name ), m_autoDelete( false ), m_isSafeMode( false ),
163 m_isSorted( isSorted ), m_readConfig( false ) 219 m_isSorted( isSorted )
164{ 220{
165 setPluginDir( QPEApplication::qpeDir() + "/plugins/"+name ); 221 setPluginDir( QPEApplication::qpeDir() + "/plugins/"+name );
222 readConfig();
166} 223}
@@ -215,3 +272,3 @@ void OGenericPluginLoader::unload( QUnknownInterface* iface ) {
215 iface->release(); 272 iface->release();
216 OPluginLibraryHolder::self()->deref( m_library.take( iface ) ); 273 Internal::OPluginLibraryHolder::self()->deref( m_library.take( iface ) );
217} 274}
@@ -226,4 +283,2 @@ void OGenericPluginLoader::unload( QUnknownInterface* iface ) {
226bool OGenericPluginLoader::isInSafeMode()const { 283bool OGenericPluginLoader::isInSafeMode()const {
227 if ( !m_readConfig )
228 readConfig();
229 return m_isSafeMode; 284 return m_isSafeMode;
@@ -231,10 +286,2 @@ bool OGenericPluginLoader::isInSafeMode()const {
231 286
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 287
@@ -287,4 +334,4 @@ QUnknownInterface* OGenericPluginLoader::load( const OPluginItem& item, const QU
287 */ 334 */
288 setSafeMode( true ); 335 setSafeMode( pa, true );
289 QLibrary *lib = OPluginLibraryHolder::self()->getLibrary( pa ); 336 QLibrary *lib = Internal::OPluginLibraryHolder::self()->ref( pa );
290 if ( !lib ) { 337 if ( !lib ) {
@@ -297,8 +344,8 @@ QUnknownInterface* OGenericPluginLoader::load( const OPluginItem& item, const QU
297 */ 344 */
298 QUnknownInterface** iface = 0; 345 QUnknownInterface* iface=0;
299 if ( lib->queryInterface( uuid, iface ) == QS_OK ) { 346 if ( lib->queryInterface( uuid, &iface ) == QS_OK ) {
300 installTranslators(pa.left( pa.find("."))); 347 installTranslators(pa.left( pa.find(".")));
301 m_library.insert( *iface, lib ); 348 m_library.insert( iface, lib );
302 }else 349 }else
303 *iface = 0; 350 iface = 0;
304 351
@@ -306,10 +353,11 @@ QUnknownInterface* OGenericPluginLoader::load( const OPluginItem& item, const QU
306 353
307 return *iface; 354 return iface;
308} 355}
309 356
357/**
358 * @internal and reads in the safe mode
359 */
310void OGenericPluginLoader::readConfig() { 360void OGenericPluginLoader::readConfig() {
311 m_readConfig = true;
312
313 /* read the config for SafeMode */ 361 /* read the config for SafeMode */
314 OConfig conf( m_name + "-odpplugins" ); 362 OConfig conf( m_dir + "-odpplugins" );
315 conf.setGroup( "General" ); 363 conf.setGroup( "General" );
@@ -318,8 +366,18 @@ void OGenericPluginLoader::readConfig() {
318 366
319void OGenericPluginLoader::setSafeMode(bool b) { 367/**
320 OConfig conf( m_name + "-odpplugins" ); 368 * Enter or leave SafeMode
369 */
370void OGenericPluginLoader::setSafeMode(const QString& str, bool b) {
371 OConfig conf( m_dir + "-odpplugins" );
321 conf.setGroup( "General" ); 372 conf.setGroup( "General" );
322 conf.writeEntry( "SafeMode", b ); 373 conf.writeEntry( "SafeMode", b );
374 conf.writeEntry( "CrashedPlugin", str );
323} 375}
324 376
377/**
378 * @internal
379 *
380 * Set the List of Plugin Dirs to lst. Currently only QPEApplication::qpeDir()+"/plugins/"+mytype
381 * is used as plugin dir
382 */
325void OGenericPluginLoader::setPluginDirs( const QStringList& lst ) { 383void OGenericPluginLoader::setPluginDirs( const QStringList& lst ) {
@@ -328,2 +386,7 @@ void OGenericPluginLoader::setPluginDirs( const QStringList& lst ) {
328 386
387/**
388 *
389 * @internal
390 * Set the Plugin Dir to str. Str will be the only element in the list of plugin dirs
391 */
329void OGenericPluginLoader::setPluginDir( const QString& str) { 392void OGenericPluginLoader::setPluginDir( const QString& str) {
@@ -333,7 +396,7 @@ void OGenericPluginLoader::setPluginDir( const QString& str) {
333 396
334bool &OGenericPluginLoader::isSafeMode()const {
335 return m_isSafeMode;
336}
337 397
338bool &OGenericPluginLoader::isSorted()const { 398/**
399 * @internal
400 */
401bool OGenericPluginLoader::isSorted()const{
339 return m_isSorted; 402 return m_isSorted;
@@ -341,23 +404,95 @@ bool &OGenericPluginLoader::isSorted()const {
341 404
342OPluginItem::List OGenericPluginLoader::plugins( const QString& dir, bool sorted, bool disabled ) { 405/*
406 * make libfoo.so.1.0.0 -> foo on UNIX
407 * make libfoo.dylib -> foo on MAC OS X Unix
408 * windows is obviously missing
409 */
410/**
411 * @internal
412 */
413QString OGenericPluginLoader::unlibify( const QString& str ) {
414 QString st = str.mid( str.find( "lib" )+3 );
343#ifdef Q_OS_MACX 415#ifdef Q_OS_MACX
344 QDir dir( dir, "lib*.dylib" ); 416 return st.left( st.findRev( ".dylib" ) );
345#else 417#else
346 QDir dir( dir, "lib*.so" ); 418 return st.left( st.findRev( ".so" ) );
347#endif 419#endif
420}
421
422/**
423 * Return a List of Plugins for a dir and add positions and remove disabled.
424 * If a plugin is on the excluded list assign position -2
425 *
426 * @param dir The dir to look in
427 * @param sorted Should positions be read?
428 * @param disabled Remove excluded from the list
429 */
430OPluginItem::List OGenericPluginLoader::plugins( const QString& _dir, bool sorted, bool disabled )const {
431#ifdef Q_OS_MACX
432 QDir dir( _dir, "lib*.dylib" );
433#else
434 QDir dir( _dir, "lib*.so" );
435#endif
436
437 OPluginItem::List lst;
438
348 /* 439 /*
349 * get excluded list and then iterate over them 440 * get excluded list and then iterate over them
441 * Excluded list contains the name
442 * Position is a list with 'name.pos.name.pos.name.pos'
443 *
444 * For the look up we will create two QMap<QString,pos>
350 */ 445 */
351 OConfig cfg( m_name+"odpplugins" ); 446 QMap<QString, int> positionMap;
352 cfg.setGroup( dir ); 447 QMap<QString, int> excludedMap;
353 QStringList excludes = cfg.readListEntry( "Excluded" ); 448
449
450 OConfig cfg( m_dir+"odpplugins" );
451 cfg.setGroup( _dir );
452
453
454 QStringList excludes = cfg.readListEntry( "Excluded", ',' );
455 for ( QStringList::Iterator it = excludes.begin(); it != excludes.end(); ++it )
456 excludedMap.insert( *it, -2 );
457
458 if ( m_isSorted ) {
459 QStringList pos = cfg.readListEntry( "Positions", '.' );
460 QStringList::Iterator it = pos.begin();
461 while ( it != pos.end() )
462 positionMap.insert( *it++, (*it++).toInt() );
463 }
464
465
466
354 467
355 QStringList list = dir.entryList(); 468 QStringList list = dir.entryList();
356// for ( 469 QStringList::Iterator it;
470 for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
471 QString str = unlibify( *it );
472 OPluginItem item( str, _dir + "/" + *it );
357 473
358} 474 bool ex = excludedMap.contains( str );
475 /*
476 * if disabled but we should show all assign a -2
477 * else continue because we don't want to add the item
478 * else if sorted we assign the right position
479 */
480 if ( ex && !disabled)
481 item.setPosition( -2 );
482 else if ( ex && disabled )
483 continue;
484 else if ( sorted )
485 item.setPosition( positionMap[str] );
486
487 lst.append( item );
488 }
359 489
490 return lst;
491}
360 492
493/**
494 * @internal generate a list of languages from $LANG
495 */
361QStringList OGenericPluginLoader::languageList() { 496QStringList OGenericPluginLoader::languageList() {
362 if ( languageList.isEmpty() ) { 497 if ( m_languages.isEmpty() ) {
363 /* 498 /*
@@ -383,5 +518,14 @@ void OGenericPluginLoader::installTranslators(const QString& type) {
383 QStringList lst = languageList(); 518 QStringList lst = languageList();
519
520 /*
521 * for each language and maybe later for each language dir...
522 * try to load a Translator
523 */
384 for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { 524 for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) {
385 QTranslator* trans = new QTranslator( qApp ); 525 QTranslator* trans = new QTranslator( qApp );
386 QString tfn = QPEApplication::qpeDir()+"/i18n/" + lang + "/" + type + ".qm" ; 526 QString tfn = QPEApplication::qpeDir()+"/i18n/" + *it + "/" + type + ".qm" ;
527
528 /*
529 * If loaded then install else clean up and don't leak
530 */
387 if ( trans->load( tfn ) ) 531 if ( trans->load( tfn ) )
diff --git a/libopie2/opiecore/opluginloader.h b/libopie2/opiecore/opluginloader.h
index a7df4a8..421d1f6 100644
--- a/libopie2/opiecore/opluginloader.h
+++ b/libopie2/opiecore/opluginloader.h
@@ -9,2 +9,3 @@
9 9
10#include <qptrdict.h>
10#include <qstringlist.h> 11#include <qstringlist.h>
@@ -33,3 +34,3 @@ public:
33 OPluginItem(); 34 OPluginItem();
34 OPluginItem( const QString& name, const QCString& confopt, const QString& path, int pos = -1 ); 35 OPluginItem( const QString& name, const QString& path, int pos = -1 );
35 ~OPluginItem(); 36 ~OPluginItem();
@@ -41,3 +42,2 @@ public:
41 QString name()const; 42 QString name()const;
42 QCString configKey()const;
43 QString path()const; 43 QString path()const;
@@ -46,3 +46,2 @@ public:
46 void setName( const QString& ); 46 void setName( const QString& );
47 void setConfigKey( const QCString& );
48 void setPath( const QString& ); 47 void setPath( const QString& );
@@ -52,3 +51,2 @@ private:
52 QString m_name; 51 QString m_name;
53 QCString m_conf;
54 QString m_path; 52 QString m_path;
@@ -92,3 +90,3 @@ public:
92protected: 90protected:
93 virtual void readConfig(); 91 void readConfig();
94 virtual List plugins( const QString& dir, bool sorted, bool disabled )const; 92 virtual List plugins( const QString& dir, bool sorted, bool disabled )const;
@@ -96,9 +94,8 @@ protected:
96 void setPluginDir( const QString& ); 94 void setPluginDir( const QString& );
97 bool &isSafeMode()const; 95 bool isSorted()const;
98 bool &isSorted()const; 96 void setSafeMode(const QString& app = QString::null, bool b = false);
99 void readConfig()const; 97 static QString unlibify( const QString& str );
100 void setSafeMode(bool b = false);
101 98
102private: 99private:
103 QString languageList(); 100 QStringList languageList();
104 void installTranslators(const QString& type); 101 void installTranslators(const QString& type);
@@ -109,3 +106,2 @@ private:
109 bool m_isSafeMode : 1; 106 bool m_isSafeMode : 1;
110 bool m_readConfig : 1;
111 bool m_isSorted : 1; 107 bool m_isSorted : 1;
@@ -141,5 +137,5 @@ public:
141 137
142 temlate<class IFace> 138 template<class IFace>
143 IFace* load( const QString& name, const QUuid& ); 139 IFace* load( const QString& name, const QUuid& );
144 temlate<class IFace> 140 template<class IFace>
145 IFace* load( const OPluginItem& item, const QUuid& ); 141 IFace* load( const OPluginItem& item, const QUuid& );