summaryrefslogtreecommitdiff
authorzecke <zecke>2004-05-17 21:22:51 (UTC)
committer zecke <zecke>2004-05-17 21:22:51 (UTC)
commitf3d15e6f81369f8495811c7c3624e51d032615ba (patch) (unidiff)
tree8319000a9aa8634a4214306ca19ac49dbcc5bc2b
parente0d8fdf2bcf61f8b6793ee757de35b985aef1b8d (diff)
downloadopie-f3d15e6f81369f8495811c7c3624e51d032615ba.zip
opie-f3d15e6f81369f8495811c7c3624e51d032615ba.tar.gz
opie-f3d15e6f81369f8495811c7c3624e51d032615ba.tar.bz2
OPluginManager first bits of saving, enabling and sorting Plugin Config
At least it compiles, test and GUI will come this week
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiecore/opluginloader.cpp369
-rw-r--r--libopie2/opiecore/opluginloader.h59
2 files changed, 395 insertions, 33 deletions
diff --git a/libopie2/opiecore/opluginloader.cpp b/libopie2/opiecore/opluginloader.cpp
index b473cd7..2aca382 100644
--- a/libopie2/opiecore/opluginloader.cpp
+++ b/libopie2/opiecore/opluginloader.cpp
@@ -1,541 +1,878 @@
1/* 1/*
2 * LGPLv2 or later 2 * LGPLv2 or later
3 * zecke@handhelds.org 3 * zecke@handhelds.org
4 */ 4 */
5 5
6#include "opluginloader.h" 6#include "opluginloader.h"
7#include "oconfig.h" 7#include "oconfig.h"
8 8
9#include <qpe/qpeapplication.h> 9#include <qpe/qpeapplication.h>
10 10
11#include <qdir.h> 11#include <qdir.h>
12#include <qdict.h> 12#include <qdict.h>
13#include <qtl.h> 13#include <qtl.h>
14#include <qfile.h>
14 15
15#include <stdlib.h> 16#include <stdlib.h>
16 17
17 18
18 19
19namespace Opie { 20namespace Opie {
20namespace Core { 21namespace Core {
21namespace Internal { 22namespace Internal {
22struct OPluginLibraryHolder { 23struct OPluginLibraryHolder {
23 static OPluginLibraryHolder *self(); 24 static OPluginLibraryHolder *self();
24 QLibrary *ref( const QString& ); 25 QLibrary *ref( const QString& );
25 void deref( QLibrary* ); 26 void deref( QLibrary* );
26private: 27private:
27 28
28 OPluginLibraryHolder(); 29 OPluginLibraryHolder();
29 ~OPluginLibraryHolder(); 30 ~OPluginLibraryHolder();
30 QDict<QLibrary> m_libs; 31 QDict<QLibrary> m_libs;
31 static OPluginLibraryHolder* m_self; 32 static OPluginLibraryHolder* m_self;
32}; 33};
33 34
34 OPluginLibraryHolder* OPluginLibraryHolder::m_self = 0; 35 OPluginLibraryHolder* OPluginLibraryHolder::m_self = 0;
35 OPluginLibraryHolder* OPluginLibraryHolder::self() { 36 OPluginLibraryHolder* OPluginLibraryHolder::self() {
36 if ( !m_self ) 37 if ( !m_self )
37 m_self = new OPluginLibraryHolder; 38 m_self = new OPluginLibraryHolder;
38 39
39 return m_self; 40 return m_self;
40 } 41 }
41 42
42 OPluginLibraryHolder::OPluginLibraryHolder() {} 43 OPluginLibraryHolder::OPluginLibraryHolder() {}
43 OPluginLibraryHolder::~OPluginLibraryHolder() {} 44 OPluginLibraryHolder::~OPluginLibraryHolder() {}
44 45
45 /* 46 /*
46 * We do simple ref counting... We will add the QLibrary again 47 * 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 * 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 * 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 * luckily dlopen does some ref counting as well so we don't need
50 * to hack QPEApplication 51 * to hack QPEApplication
51 */ 52 */
52 QLibrary* OPluginLibraryHolder::ref(const QString& str) { 53 QLibrary* OPluginLibraryHolder::ref(const QString& str) {
53 QLibrary *lib = m_libs[str]; 54 QLibrary *lib = m_libs[str];
54 55
55 /* if not in the dict try to load it */ 56 /* if not in the dict try to load it */
56 if ( !lib ) { 57 if ( !lib ) {
57 lib = new QLibrary( str, QLibrary::Immediately ); 58 lib = new QLibrary( str, QLibrary::Immediately );
58 if ( !lib->isLoaded() ) { 59 if ( !lib->isLoaded() ) {
59 delete lib; 60 delete lib;
60 return 0l; 61 return 0l;
61 } 62 }
62 } 63 }
63 64
64 /* now refcount one up */ 65 /* now refcount one up */
65 m_libs.insert( str, lib ); 66 m_libs.insert( str, lib );
66 return lib; 67 return lib;
67 } 68 }
68 69
69 /* 70 /*
70 * 'unshadow' the items until we're the last then unload and delete 71 * 'unshadow' the items until we're the last then unload and delete
71 */ 72 */
72 void OPluginLibraryHolder::deref( QLibrary* lib ) { 73 void OPluginLibraryHolder::deref( QLibrary* lib ) {
73 if ( !lib ) 74 if ( !lib )
74 return; 75 return;
75 76
76 QString str = lib->library(); 77 QString str = lib->library();
77 /* no need to check if the lib was inserted or such */ 78 /* no need to check if the lib was inserted or such */
78 (void) m_libs.take( str ); 79 (void) m_libs.take( str );
79 if ( !m_libs[str] ) { 80 if ( !m_libs[str] ) {
80 lib->unload(); 81 lib->unload();
81 delete lib; 82 delete lib;
82 } 83 }
83 } 84 }
84} 85}
85 86
86/** 87/**
87 * We want values with 30,29,28 at the beginning of the list 88 * We want values with 30,29,28 at the beginning of the list
88 */ 89 */
89 90
90bool operator<( const OPluginItem& l, const OPluginItem& r ) { 91bool operator<( const OPluginItem& l, const OPluginItem& r ) {
91 return l.position() > r.position(); 92 return l.position() > r.position();
92} 93}
93 94
94bool operator>( const OPluginItem& l, const OPluginItem& r ) { 95bool operator>( const OPluginItem& l, const OPluginItem& r ) {
95 return l.position() < r.position(); 96 return l.position() < r.position();
96} 97}
97 98
98bool operator<=( const OPluginItem& l, const OPluginItem& r ) { 99bool operator<=( const OPluginItem& l, const OPluginItem& r ) {
99 return l.position() >= r.position(); 100 return l.position() >= r.position();
100} 101}
101 102
102/** 103/**
103 * \brief Creates an Empty OPluginItem 104 * \brief Creates an Empty OPluginItem
104 * 105 *
105 * create an empty pluginitem. Position is set to -1 and the 106 * create an empty pluginitem. Position is set to -1 and the
106 * other things are used with the default ctors 107 * other things are used with the default ctors
107 */ 108 */
108OPluginItem::OPluginItem() 109OPluginItem::OPluginItem()
109 : m_pos( -1 ) { 110 : m_pos( -1 ) {
110} 111}
111 112
112/** 113/**
114 * @todo Create Internal name so we can have the plugin names translated. Or only for the gui? I'm not yet sure
113 * \brief Create an OPluginItem 115 * \brief Create an OPluginItem
114 * 116 *
115 * Create a Plugin Item with all information. 117 * Create a Plugin Item with all information. If you for some reasons
118 * need to create your own OPluginItems make sure that 'name' is always the same
119 * as it if used for positions and exclude list.
116 * 120 *
117 * @param name The if available translated Name 121 * @param name The if available translated Name
118 * @param path The path to the plugin 122 * @param path The path to the plugin must be absolute.
123 * @param b If the OPluginItem is enabled or not
119 * @param pos The position of the plugin if used for sorting 124 * @param pos The position of the plugin if used for sorting
120 * 125 *
121 */ 126 */
122OPluginItem::OPluginItem( const QString& name, const QString& path, int pos ) 127OPluginItem::OPluginItem( const QString& name, const QString& path, bool b, int pos )
123 : m_name( name ), m_path( path ), m_pos( pos ) { 128 : m_name( name ), m_path( path ), m_enabled( b ), m_pos( pos )
124} 129{}
125 130
126/** 131/**
127 * \brief simple d'tor 132 * \brief simple d'tor
128 */ 133 */
129OPluginItem::~OPluginItem() { 134OPluginItem::~OPluginItem() {
130} 135}
131 136
132/** 137/**
138 * \brief Test if this Item is Empty and does not represent a loadable plugin
139 * Test if a OPluginItem is empty. A OPluginItem is empty if name and path are empty
140 * ,pos equals -1 and the item is disabled
141 *
142 * @see QString::isEmpty()
143 *
144 */
145bool OPluginItem::isEmpty()const {
146 if ( m_pos != -1 ) return false;
147 if ( m_enabled ) return false;
148 if ( !m_name.isEmpty() ) return false;
149 if ( !m_path.isEmpty() ) return false;
150
151 return true;
152}
153
154/**
155 * \brief test equality
133 * operator to test equalness of two OPluginItem 156 * operator to test equalness of two OPluginItem
134 */ 157 */
135bool OPluginItem::operator==( const OPluginItem& r )const{ 158bool OPluginItem::operator==( const OPluginItem& r )const{
136 if ( m_pos != r.m_pos ) return false; 159 if ( m_pos != r.m_pos ) return false;
137 if ( m_name != r.m_name ) return false; 160 if ( m_enabled != r.m_enabled) return false;
138 if ( m_path != r.m_path ) return false; 161 if ( m_name != r.m_name ) return false;
162 if ( m_path != r.m_path ) return false;
139 return true; 163 return true;
140} 164}
141 165
166/**
167 * \brief test non equality
168 * operator to test non-equalness of two OPluginItem
169 */
142bool OPluginItem::operator!=( const OPluginItem& r )const{ 170bool OPluginItem::operator!=( const OPluginItem& r )const{
143 return !( *this == r ); 171 return !( *this == r );
144} 172}
145 173
146/** 174/**
175 * \brief returns the name of the plugin
147 * return the name of this Plugin 176 * return the name of this Plugin
148 */ 177 */
149QString OPluginItem::name()const { 178QString OPluginItem::name()const {
150 return m_name; 179 return m_name;
151} 180}
152 181
153/** 182/**
154 * return the path of the plugin 183 * \brief return the path of the plugin
155 */ 184 */
156QString OPluginItem::path()const { 185QString OPluginItem::path()const {
157 return m_path; 186 return m_path;
158} 187}
159 188
189/**
190 * \brief Return if this item is enabled.
191 */
192bool OPluginItem::isEnabled()const {
193 return m_enabled;
194}
195
196/**
197 * \brief return the position of a plugin.
198 * return the position of the item
199 * -1 is the default value and means normally that the whole items are unsorted.
200 * Higher numbers belong to an upper position. With plugins with the postions 20,19,5,3
201 * the item with pos 20 would be the first in the list returned by the OGenericPluginLoader
202 *
203 * @see OGenericPluginLoader::allAvailable
204 * @see OGenericPluginLoader::filtered
205 */
160int OPluginItem::position()const{ 206int OPluginItem::position()const{
161 return m_pos; 207 return m_pos;
162} 208}
163 209
164/** 210/**
211 * \brief set the name of a plugin
165 * Set the name of the Plugin Item 212 * Set the name of the Plugin Item
166 * @param name 213 * @param name
167 */ 214 */
168void OPluginItem::setName( const QString& name ) { 215void OPluginItem::setName( const QString& name ) {
169 m_name = name; 216 m_name = name;
170} 217}
171 218
172/** 219/**
173 * Set the path of Plugin Item 220 * \brief set the path of a plugin
221 * Set the path of Plugin Item. The path must be absolute.
174 * @param name The path of the plugin 222 * @param name The path of the plugin
175 */ 223 */
176void OPluginItem::setPath( const QString& name ) { 224void OPluginItem::setPath( const QString& name ) {
177 m_name = name; 225 m_name = name;
178} 226}
179 227
180/** 228/**
229 * \brief enable or disable the to load attribute
230 * Set the Enabled attribute. Such changes won't be saved. If you want to save it
231 * use a OPluginManager to configure your plugins manually or Opie::Ui::OPluginConfig
232 * for a graphical frontend.
233 *
234 * @param enabled Enable or Disable the Enabled Attribute
235 */
236void OPluginItem::setEnabled( bool enabled ) {
237 m_enabled = enabled;
238}
239
240/**
241 * \brief Set the position.
181 * Set the position 242 * Set the position
182 * @param pos The position 243 * @param pos The position
244 *
245 * @see position()
183 */ 246 */
184void OPluginItem::setPosition( int pos ) { 247void OPluginItem::setPosition( int pos ) {
185 m_pos = pos; 248 m_pos = pos;
186} 249}
187 250
188 251
189 252
190/** 253/**
191 * \brief create a PluginLoader 254 * \brief create a PluginLoader
192 * 255 *
193 * Create a PluginLoader autoDelete is set to false 256 * Create a PluginLoader autoDelete is set to false
194 * 257 *
195 * \code 258 * \code
196 * Opie::Core::OGenericPluginLoader loader("myapp-plugin"); 259 * Opie::Core::OGenericPluginLoader loader("myapp-plugin");
197 * Opie::Core::OPluginItem::List lst = loader.filtered(); 260 * Opie::Core::OPluginItem::List lst = loader.filtered();
198 * for(Opie::Core::OPluginItem::List::Iterator it = lst.begin(); it!=lst.end();++it){ 261 * for(Opie::Core::OPluginItem::List::Iterator it = lst.begin(); it!=lst.end();++it){
199 * MyIface* iface = static_cast<MyIface*>(loader.load(*it,IID_MyIface)); 262 * MyIface* iface = static_cast<MyIface*>(loader.load(*it,IID_MyIface));
200 * } 263 * }
201 * \endcode 264 * \endcode
202 * 265 *
203 * \code 266 * \code
204 * Opie::Core::OGenericPluginLoader loader("myapp-plugin"); 267 * Opie::Core::OGenericPluginLoader loader("myapp-plugin");
205 * Opie::Core::OPluginItem::List lst = loader.filtered(); 268 * Opie::Core::OPluginItem::List lst = loader.filtered();
206 * for(Opie::Core::OPluginItem::List::Iterator it = lst.begin(); it!=lst.end();++it){ 269 * for(Opie::Core::OPluginItem::List::Iterator it = lst.begin(); it!=lst.end();++it){
207 * MyIface* iface = static_cast<MyIface*>(loader.load(*it,IID_MyIface)); 270 * MyIface* iface = static_cast<MyIface*>(loader.load(*it,IID_MyIface));
208 * } 271 * }
209 * ... 272 * ...
210 * loader.clear(); 273 * loader.clear();
211 * 274 *
212 * \endcode 275 * \endcode
213 * 276 *
214 * @param name The name of the plugin directory. 277 * @param name The name of the plugin directory.
215 * @param isSorted Tell the PluginLoader if your Plugins are sorted 278 * @param isSorted Tell the PluginLoader if your Plugins are sorted
216 */ 279 */
217OGenericPluginLoader::OGenericPluginLoader( const QString& name, bool isSorted) 280OGenericPluginLoader::OGenericPluginLoader( const QString& name, bool isSorted)
218 : m_dir( name ), m_autoDelete( false ), m_isSafeMode( false ), 281 : m_dir( name ), m_autoDelete( false ), m_isSafeMode( false ),
219 m_isSorted( isSorted ) 282 m_isSorted( isSorted )
220{ 283{
221 setPluginDir( QPEApplication::qpeDir() + "/plugins/"+name ); 284 setPluginDir( QPEApplication::qpeDir() + "/plugins/"+name );
222 readConfig(); 285 readConfig();
223} 286}
224 287
225 288
226/** 289/**
290 * \brief simple d'tor that cleans up depending on autoDelete
291 *
227 * calls clear if autoDelete is true. This will release all interfaces 292 * calls clear if autoDelete is true. This will release all interfaces
228 * and remove the library from this process if the refcount falls to zero 293 * and remove the library from this process if the refcount falls to zero
229 */ 294 */
230OGenericPluginLoader::~OGenericPluginLoader() { 295OGenericPluginLoader::~OGenericPluginLoader() {
231 if ( m_autoDelete ) 296 if ( m_autoDelete )
232 clear(); 297 clear();
233} 298}
234 299
235/** 300/**
301 * \brief Enable or disable autoDelete on destruction
302 *
236 * enable autoDelete. This will call clear on the d'tor 303 * enable autoDelete. This will call clear on the d'tor
237 * 304 *
238 * @see ~OGenericPluginLoader 305 * @see ~OGenericPluginLoader
239 * @see clear() 306 * @see clear()
240 */ 307 */
241void OGenericPluginLoader::setAutoDelete( bool t ) { 308void OGenericPluginLoader::setAutoDelete( bool t ) {
242 m_autoDelete = t; 309 m_autoDelete = t;
243} 310}
244 311
245/** 312/**
246 * see if autoDelet is enabled 313 * \brief See if autoDelete is enabled.
247 */ 314 */
248bool OGenericPluginLoader::autoDelete()const{ 315bool OGenericPluginLoader::autoDelete()const{
249 return m_autoDelete; 316 return m_autoDelete;
250} 317}
251 318
252/** 319/**
320 * \brief unload all loaded Plugins
321 *
253 * This will unload all returned QUnknownInterfaces by load. Unload 322 * This will unload all returned QUnknownInterfaces by load. Unload
254 * will be called. 323 * will be called.
255 */ 324 */
256void OGenericPluginLoader::clear() { 325void OGenericPluginLoader::clear() {
257 QPtrDictIterator<QLibrary> it( m_library ); 326 QPtrDictIterator<QLibrary> it( m_library );
258 for ( ;it.current(); ) 327 for ( ;it.current(); )
259 unload( static_cast<QUnknownInterface*>( it.currentKey() ) ); 328 unload( static_cast<QUnknownInterface*>( it.currentKey() ) );
260} 329}
261 330
262/** 331/**
332 * \brief unload the Plugin and the accompanied Resources.
333 *
263 * This will take the iface from the internal QPtrDict, Release it, 334 * This will take the iface from the internal QPtrDict, Release it,
264 * and deref the libray used. 335 * and deref the libray used.
265 * The visibility depends on the QPtrDict. 336 * The visibility depends on the QPtrDict.
266 * @see QPtrDict::insert 337 * @see QPtrDict::insert
267 */ 338 */
268void OGenericPluginLoader::unload( QUnknownInterface* iface ) { 339void OGenericPluginLoader::unload( QUnknownInterface* iface ) {
269 if ( !iface ) 340 if ( !iface )
270 return; 341 return;
271 342
272 iface->release(); 343 iface->release();
273 Internal::OPluginLibraryHolder::self()->deref( m_library.take( iface ) ); 344 Internal::OPluginLibraryHolder::self()->deref( m_library.take( iface ) );
274} 345}
275 346
276/** 347/**
348 * \brief The name of the plugins.
349 *
350 * Return the name/type you specified in the constructor.
351 * This is at least used by the OPluginManager to find the right config
352 */
353QString OGenericPluginLoader::name()const {
354 return m_dir;
355}
356
357
358/**
359 * \brief See if loading of a plugin segfaulted
277 * This tells you 360 * This tells you
278 * if by previous tries to load, loading crashed your application. 361 * if by previous tries to load, loading crashed your application.
279 * If isInSafeMode you can use the GUI to configure the plugins prior to loading 362 * If isInSafeMode you can use the GUI to configure the plugins prior to loading
280 * 363 *
281 * @return true if prior loading failed 364 * @return true if prior loading failed
282 */ 365 */
283bool OGenericPluginLoader::isInSafeMode()const { 366bool OGenericPluginLoader::isInSafeMode()const {
284 return m_isSafeMode; 367 return m_isSafeMode;
285} 368}
286 369
287 370
288/** 371/**
372 * \brief Return all Plugins found in the plugins dirs.
289 * Return the list of all available plugins. This will go through all plugin 373 * Return the list of all available plugins. This will go through all plugin
290 * directories and search for your type of plugins ( by subdir ) 374 * directories and search for your type of plugins ( by subdir )
291 * 375 *
292 * @param sorted Tell if you want to have the positions sorted. This only makes sense if you 376 * @param sorted Tell if you want to have the positions sorted. This only makes sense if you
293 */ 377 */
294OPluginItem::List OGenericPluginLoader::allAvailable( bool sorted )const { 378OPluginItem::List OGenericPluginLoader::allAvailable( bool sorted )const {
295 OPluginItem::List lst; 379 OPluginItem::List lst;
296 for ( QStringList::ConstIterator it = m_plugDirs.begin(); it != m_plugDirs.end(); ++it ) 380 for ( QStringList::ConstIterator it = m_plugDirs.begin(); it != m_plugDirs.end(); ++it )
297 lst += plugins( *it, sorted, false ); 381 lst += plugins( *it, sorted, false );
298 382
299 if ( sorted ) 383 if ( sorted )
300 qHeapSort( lst ); 384 qHeapSort( lst );
301 return lst; 385 return lst;
302} 386}
303 387
304/** 388/**
389 * \brief Return only the enabled plugins
305 * Return only activated plugins. 390 * Return only activated plugins.
306 * 391 *
307 * @param sorted If the list should be sorted 392 * @param sorted If the list should be sorted
308 */ 393 */
309OPluginItem::List OGenericPluginLoader::filtered( bool sorted )const { 394OPluginItem::List OGenericPluginLoader::filtered( bool sorted )const {
310 OPluginItem::List lst; 395 OPluginItem::List lst;
311 for ( QStringList::ConstIterator it = m_plugDirs.begin(); it != m_plugDirs.end(); ++it ) 396 for ( QStringList::ConstIterator it = m_plugDirs.begin(); it != m_plugDirs.end(); ++it )
312 lst += plugins( *it, sorted, true ); 397 lst += plugins( *it, sorted, true );
313 398
314 if ( sorted ) 399 if ( sorted )
315 qHeapSort( lst ); 400 qHeapSort( lst );
316 return lst; 401 return lst;
317} 402}
318 403
319 404
320/** 405/**
406 * \brief Load a OPluginItem for the specified interface
407 * This will open the resource of the OPluginItem::path() and then will query
408 * if the Interface specified in the uuid is available and then will manage the
409 * resource and Interface.
410 *
411 * @param item The OPluginItem that should be loaded
412 * @param uuid The Interface to query for
321 * 413 *
414 * @return Either 0 in case of failure or the Plugin as QUnknownInterface*
322 */ 415 */
323QUnknownInterface* OGenericPluginLoader::load( const OPluginItem& item, const QUuid& uuid) { 416QUnknownInterface* OGenericPluginLoader::load( const OPluginItem& item, const QUuid& uuid) {
324 /* 417 /*
325 * Check if there could be a library 418 * Check if there could be a library
326 */ 419 */
327 QString pa = item.path(); 420 QString pa = item.path();
328 if ( pa.isEmpty() ) 421 if ( pa.isEmpty() )
329 return 0l; 422 return 0l;
330 423
331 /* 424 /*
332 * See if we get a library 425 * See if we get a library
333 * return if we've none 426 * return if we've none
334 */ 427 */
335 setSafeMode( pa, true ); 428 setSafeMode( pa, true );
336 QLibrary *lib = Internal::OPluginLibraryHolder::self()->ref( pa ); 429 QLibrary *lib = Internal::OPluginLibraryHolder::self()->ref( pa );
337 if ( !lib ) { 430 if ( !lib ) {
338 setSafeMode(); 431 setSafeMode();
339 return 0l; 432 return 0l;
340 } 433 }
341 434
342 /** 435 /**
343 * try to load the plugin and just in case initialize the pointer to a pointer again 436 * try to load the plugin and just in case initialize the pointer to a pointer again
344 */ 437 */
345 QUnknownInterface* iface=0; 438 QUnknownInterface* iface=0;
346 if ( lib->queryInterface( uuid, &iface ) == QS_OK ) { 439 if ( lib->queryInterface( uuid, &iface ) == QS_OK ) {
347 installTranslators(pa.left( pa.find("."))); 440 installTranslators(pa.left( pa.find(".")));
348 m_library.insert( iface, lib ); 441 m_library.insert( iface, lib );
349 }else 442 }else
350 iface = 0; 443 iface = 0;
351 444
352 setSafeMode(); 445 setSafeMode();
353 446
354 return iface; 447 return iface;
355} 448}
356 449
357/** 450/**
358 * @internal and reads in the safe mode 451 * @internal and reads in the safe mode
359 */ 452 */
360void OGenericPluginLoader::readConfig() { 453void OGenericPluginLoader::readConfig() {
361 /* read the config for SafeMode */ 454
455
456/* read the config for SafeMode */
362 OConfig conf( m_dir + "-odpplugins" ); 457 OConfig conf( m_dir + "-odpplugins" );
363 conf.setGroup( "General" ); 458 conf.setGroup( "General" );
364 m_isSafeMode = conf.readBoolEntry( "SafeMode", false ); 459 m_isSafeMode = conf.readBoolEntry( "SafeMode", false );
365} 460}
366 461
367/** 462/**
368 * Enter or leave SafeMode 463 * @internal Enter or leave SafeMode
369 */ 464 */
370void OGenericPluginLoader::setSafeMode(const QString& str, bool b) { 465void OGenericPluginLoader::setSafeMode(const QString& str, bool b) {
371 OConfig conf( m_dir + "-odpplugins" ); 466 OConfig conf( m_dir + "-odpplugins" );
372 conf.setGroup( "General" ); 467 conf.setGroup( "General" );
373 conf.writeEntry( "SafeMode", b ); 468 conf.writeEntry( "SafeMode", b );
374 conf.writeEntry( "CrashedPlugin", str ); 469 conf.writeEntry( "CrashedPlugin", str );
375} 470}
376 471
377/** 472/**
378 * @internal 473 * @internal
379 * 474 *
380 * Set the List of Plugin Dirs to lst. Currently only QPEApplication::qpeDir()+"/plugins/"+mytype 475 * Set the List of Plugin Dirs to lst. Currently only QPEApplication::qpeDir()+"/plugins/"+mytype
381 * is used as plugin dir 476 * is used as plugin dir
382 */ 477 */
383void OGenericPluginLoader::setPluginDirs( const QStringList& lst ) { 478void OGenericPluginLoader::setPluginDirs( const QStringList& lst ) {
384 m_plugDirs = lst; 479 m_plugDirs = lst;
385} 480}
386 481
387/** 482/**
388 * 483 *
389 * @internal 484 * @internal
390 * Set the Plugin Dir to str. Str will be the only element in the list of plugin dirs 485 * Set the Plugin Dir to str. Str will be the only element in the list of plugin dirs
391 */ 486 */
392void OGenericPluginLoader::setPluginDir( const QString& str) { 487void OGenericPluginLoader::setPluginDir( const QString& str) {
393 m_plugDirs.clear(); 488 m_plugDirs.clear();
394 m_plugDirs.append( str ); 489 m_plugDirs.append( str );
395} 490}
396 491
397 492
398/** 493/**
399 * @internal 494 * @internal
400 */ 495 */
401bool OGenericPluginLoader::isSorted()const{ 496bool OGenericPluginLoader::isSorted()const{
402 return m_isSorted; 497 return m_isSorted;
403} 498}
404 499
405/* 500/*
406 * make libfoo.so.1.0.0 -> foo on UNIX 501 * make libfoo.so.1.0.0 -> foo on UNIX
407 * make libfoo.dylib -> foo on MAC OS X Unix 502 * make libfoo.dylib -> foo on MAC OS X Unix
408 * windows is obviously missing 503 * windows is obviously missing
409 */ 504 */
410/** 505/**
411 * @internal 506 * @internal
412 */ 507 */
413QString OGenericPluginLoader::unlibify( const QString& str ) { 508QString OGenericPluginLoader::unlibify( const QString& str ) {
414 QString st = str.mid( str.find( "lib" )+3 ); 509 QString st = str.mid( str.find( "lib" )+3 );
415#ifdef Q_OS_MACX 510#ifdef Q_OS_MACX
416 return st.left( st.findRev( ".dylib" ) ); 511 return st.left( st.findRev( ".dylib" ) );
417#else 512#else
418 return st.left( st.findRev( ".so" ) ); 513 return st.left( st.findRev( ".so" ) );
419#endif 514#endif
420} 515}
421 516
422/** 517/**
423 * Return a List of Plugins for a dir and add positions and remove disabled. 518 * @internal
519 *
520 * \brief method to return available plugins. Internal and for reeimplementations
521 *
522 *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 523 * If a plugin is on the excluded list assign position -2
425 * 524 *
426 * @param dir The dir to look in 525 * @param dir The dir to look in
427 * @param sorted Should positions be read? 526 * @param sorted Should positions be read?
428 * @param disabled Remove excluded from the list 527 * @param disabled Remove excluded from the list
429 */ 528 */
430OPluginItem::List OGenericPluginLoader::plugins( const QString& _dir, bool sorted, bool disabled )const { 529OPluginItem::List OGenericPluginLoader::plugins( const QString& _dir, bool sorted, bool disabled )const {
431#ifdef Q_OS_MACX 530#ifdef Q_OS_MACX
432 QDir dir( _dir, "lib*.dylib" ); 531 QDir dir( _dir, "lib*.dylib" );
433#else 532#else
434 QDir dir( _dir, "lib*.so" ); 533 QDir dir( _dir, "lib*.so" );
435#endif 534#endif
436 535
437 OPluginItem::List lst; 536 OPluginItem::List lst;
438 537
439 /* 538 /*
440 * get excluded list and then iterate over them 539 * get excluded list and then iterate over them
441 * Excluded list contains the name 540 * Excluded list contains the name
442 * Position is a list with 'name.pos.name.pos.name.pos' 541 * Position is a list with 'name.pos.name.pos.name.pos'
443 * 542 *
444 * For the look up we will create two QMap<QString,pos> 543 * For the look up we will create two QMap<QString,pos>
445 */ 544 */
446 QMap<QString, int> positionMap; 545 QMap<QString, int> positionMap;
447 QMap<QString, int> excludedMap; 546 QMap<QString, int> excludedMap;
448 547
449 548
450 OConfig cfg( m_dir+"odpplugins" ); 549 OConfig cfg( m_dir+"odpplugins" );
451 cfg.setGroup( _dir ); 550 cfg.setGroup( _dir );
452 551
453 552
454 QStringList excludes = cfg.readListEntry( "Excluded", ',' ); 553 QStringList excludes = cfg.readListEntry( "Excluded", ',' );
455 for ( QStringList::Iterator it = excludes.begin(); it != excludes.end(); ++it ) 554 for ( QStringList::Iterator it = excludes.begin(); it != excludes.end(); ++it )
456 excludedMap.insert( *it, -2 ); 555 excludedMap.insert( *it, -2 );
457 556
458 if ( m_isSorted ) { 557 if ( m_isSorted ) {
459 QStringList pos = cfg.readListEntry( "Positions", '.' ); 558 QStringList pos = cfg.readListEntry( "Positions", '.' );
460 QStringList::Iterator it = pos.begin(); 559 QStringList::Iterator it = pos.begin();
461 while ( it != pos.end() ) 560 while ( it != pos.end() )
462 positionMap.insert( *it++, (*it++).toInt() ); 561 positionMap.insert( *it++, (*it++).toInt() );
463 } 562 }
464 563
465 564
466 565
467 566
468 QStringList list = dir.entryList(); 567 QStringList list = dir.entryList();
469 QStringList::Iterator it; 568 QStringList::Iterator it;
470 for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { 569 for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
471 QString str = unlibify( *it ); 570 QString str = unlibify( *it );
472 OPluginItem item( str, _dir + "/" + *it ); 571 OPluginItem item( str, _dir + "/" + *it );
473 572
474 bool ex = excludedMap.contains( str ); 573 bool ex = excludedMap.contains( str );
475 /* 574 /*
476 * if disabled but we should show all assign a -2 575 * if disabled but we should show all mark it as disabled
477 * else continue because we don't want to add the item 576 * else continue because we don't want to add the item
478 * else if sorted we assign the right position 577 * else if sorted we assign the right position
479 */ 578 */
480 if ( ex && !disabled) 579 if ( ex && !disabled)
481 item.setPosition( -2 ); 580 item.setEnabled( false );
482 else if ( ex && disabled ) 581 else if ( ex && disabled )
483 continue; 582 continue;
484 else if ( sorted ) 583 else if ( sorted )
485 item.setPosition( positionMap[str] ); 584 item.setPosition( positionMap[str] );
486 585
487 lst.append( item ); 586 lst.append( item );
488 } 587 }
489 588
490 return lst; 589 return lst;
491} 590}
492 591
493/** 592/**
494 * @internal generate a list of languages from $LANG 593 * @internal generate a list of languages from $LANG
495 */ 594 */
496QStringList OGenericPluginLoader::languageList() { 595QStringList OGenericPluginLoader::languageList() {
497 if ( m_languages.isEmpty() ) { 596 if ( m_languages.isEmpty() ) {
498 /* 597 /*
499 * be_BY.CP1251 We will add, be_BY.CP1251,be_BY,be 598 * be_BY.CP1251 We will add, be_BY.CP1251,be_BY,be
500 * to our list of languages. 599 * to our list of languages.
501 */ 600 */
502 QString str = ::getenv( "LANG" ); 601 QString str = ::getenv( "LANG" );
503 m_languages += str; 602 m_languages += str;
504 int pos = str.find( '.' ); 603 int pos = str.find( '.' );
505 604
506 if ( pos > 0 ) 605 if ( pos > 0 )
507 m_languages += str.left( pos ); 606 m_languages += str.left( pos );
508 607
509 int n_pos = str.find( '_' ); 608 int n_pos = str.find( '_' );
510 if ( pos > 0 && n_pos >= pos ) 609 if ( pos > 0 && n_pos >= pos )
511 m_languages += str.left( n_pos ); 610 m_languages += str.left( n_pos );
512 611
513 } 612 }
514 return m_languages; 613 return m_languages;
515} 614}
516 615
616/**
617 * @internal
618 * Tries to install languages using the languageList for the type
619 */
517void OGenericPluginLoader::installTranslators(const QString& type) { 620void OGenericPluginLoader::installTranslators(const QString& type) {
518 QStringList lst = languageList(); 621 QStringList lst = languageList();
519 622
520 /* 623 /*
521 * for each language and maybe later for each language dir... 624 * for each language and maybe later for each language dir...
522 * try to load a Translator 625 * try to load a Translator
523 */ 626 */
524 for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { 627 for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) {
525 QTranslator* trans = new QTranslator( qApp ); 628 QTranslator* trans = new QTranslator( qApp );
526 QString tfn = QPEApplication::qpeDir()+"/i18n/" + *it + "/" + type + ".qm" ; 629 QString tfn = QPEApplication::qpeDir()+"/i18n/" + *it + "/" + type + ".qm" ;
527 630
528 /* 631 /*
529 * If loaded then install else clean up and don't leak 632 * If loaded then install else clean up and don't leak
530 */ 633 */
531 if ( trans->load( tfn ) ) 634 if ( trans->load( tfn ) )
532 qApp->installTranslator( trans ); 635 qApp->installTranslator( trans );
533 else 636 else
534 delete trans; 637 delete trans;
535 } 638 }
536} 639}
537 640
641/**
642 * \brief Simple c'tor.
643 *
644 * Simple C'tor same as the one of the base class. Additional this
645 * class can cast for you if you nee it.
646 *
647 *
648 * @param name The name of your plugin class
649 * @param sorted If plugins are sorted
650 *
651 * @see OGenericPluginLoader
652 */
653OPluginLoader::OPluginLoader( const QString& name, bool sorted )
654 : OGenericPluginLoader( name, sorted )
655{
656}
657
658/**
659 * d'tor
660 * @see OGenericPluginLoader::~OGenericPluginLoader
661 */
662OPluginLoader::~OPluginLoader() {
663}
664
665/**
666 * \brief C'Tor using a OGenericPluginLoader
667 * The C'tor. Pass your OGenericPluginLoader to manage
668 * OGenericPluginLoader::allAvailable plugins.
669 *
670 *
671 * @param loader A Pointer to your OGenericPluginLoader
672 * @param name The name
673 */
674OPluginManager::OPluginManager( OGenericPluginLoader* loader)
675 : m_loader( loader )
676{
677}
678
679/**
680 * \brief Overloaded c'tor using a List of Plugins and a type name
681 * Overloaded Constructor to work with a 'Type' of plugins
682 * and a correspending list of those. In this case calling load
683 * is a no operation.
684 *
685 * @param name The name of your plugin ('today','inputmethods','applets')
686 * @param lst A List with plugins of your type to manage
687 * @param isSorted If the List should be treated sorted
688 */
689OPluginManager::OPluginManager( const QString& name, const OPluginItem::List& lst, bool isSorted)
690 : m_loader( 0l ), m_cfgName( name ), m_plugins( lst ), m_isSorted( isSorted )
691{
692}
693
694/**
695 * \brief A simple d'tor
696 */
697OPluginManager::~OPluginManager() {
698}
699
700/**
701 * \brief Return the OPluginItem where loading is likely to have crashed on.
538 702
703 * Return the Item that made the OGenericPluginLoader crash
704 * the returned OPluginItem could be empty if no crash occured
705 * which should apply most of the time. It could also be empty if the crashed
706 * plugin is not in the current list of available/managed plugins
707 *
708 * @see OPluginItem::isEmpty
709 * @return OPluginItem that crashed the loader
710 */
711OPluginItem OPluginManager::crashedPlugin()const {
712 return m_crashed;
713}
714
715/**
716 * \brief Return a list of plugins that are managed by this OPluginManager
717 *
718 * Return the list of managed plugins. This could either result
719 * from passing a OGenericPluginLoader and calling load or by
720 * giving name and a list of plugins.
721 */
722OPluginItem::List OPluginManager::managedPlugins()const {
723 return m_plugins;
724}
725
726/**
727 * \brief Set the position of the items
728 *
729 * Replace the OPluginItem with the name and path and this way
730 * apply the new position. The search is linear and this way O(n/2)
731 * You still need to call save() to make your changes effective. After saving
732 * a call to OGenericPluginLoader::filtered() returns the newly configured order and items
733 *
734 * @param item The OPluginItem to be replaced internall
735 *
736 */
737void OPluginManager::setPosition( const OPluginItem& item) {
738 replace( item );
739}
740
741/**
742 * \brief Enable the item specified as argument
743 *
744 * This will make sure that OPluginItem::setEnabled is called and then will replace
745 * the item with one that matches name and path internally.
746 * @see setPosition
747 *
748 * @param the Item to enable
749 */
750void OPluginManager::enable( const OPluginItem& item ) {
751 setEnabled( item, true );
752}
753
754/**
755 * \brief disable the Item.
756 *
757 * Disable the OPluginItem. Same applies as in
758 * @see setPosition and @see enable
759 *
760 * @param item Item to disable
761 */
762void OPluginManager::disable( const OPluginItem& item) {
763 setEnabled( item, false );
764}
765
766/**
767 * \brief Enable or disable the OPluginItem.
768 * Depending on the value of the parameter this will either disable
769 * or enable the pluginitem.
770 * Beside that same as in @see disable, @see enable, @see setPosition
771 * applies.
772 *
773 * @param _item The OPluginItem to enable or to disable.
774 * @param b Enable or disable the plugin.
775 *
776 */
777void OPluginManager::setEnabled( const OPluginItem& _item, bool b ) {
778 OPluginItem item = _item;
779 item.setEnabled( b );
780 replace( item );
781}
782
783/**
784 * \brief Load necessary information after constructing the object
785 * If you speified a OGenericPluginLoader you need to call this method
786 * so that this manager knows what to manage and have a right value for \sa crashedPlugin
787 * For the name and the list of plugins this does only try to find out the crashed plugin
788 */
789void OPluginManager::load() {
790 OConfig cfg( configName() );
791 cfg.setGroup( "General" );
792 QString crashedPath = cfg.readEntry( "CrashedPlugin" );
793
794 /* if we've a loader this applies if we were called from the first part */
795 if ( m_loader )
796 m_plugins = m_loader->allAvailable( m_loader->isSorted() );
797
798 /* fast and normal route if we did not crash... */
799 if ( crashedPath.isEmpty() )
800 return;
801
802 /* lets try to find the plugin path and this way the associated item */
803 for ( OPluginItem::List::Iterator it = m_plugins.begin(); it != m_plugins.end(); ++it )
804 if ( (*it).path() == crashedPath ) {
805 m_crashed = *it;
806 break;
807 }
808}
809
810
811/**
812 * \brief Save the values and this way make it available.
813 *
814 * Save the current set of data. A call to @see OGenericPluginLoader::filtered
815 * now would return your saved changes.
816 */
817void OPluginManager::save() {
818 QMap<QString, QStringList> excluded; // map for path to excluded name
819 QMap<QString, QStringList> positions; // if positions matter contains splitted up by dirs
820 bool sorted = m_loader ? m_loader->isSorted() : m_isSorted;
821
822 /*
823 * We will create some maps for the groups to include positions a
824 */
825 for ( OPluginItem::List::Iterator it = m_plugins.begin(); it != m_plugins.end(); ++it ) {
826 OPluginItem item = *it;
827 QString path = QFileInfo( item.path() ).filePath();
828 if ( sorted ) {
829 positions[path].append( item.name() );
830 positions[path].append( QString::number( item.position() ) );
831 }
832
833 if ( !item.isEnabled() )
834 excluded[path].append( item.name() );
835 }
836
837/*
838 * The code below wouldn't work because we can't delete groups/keys from the config
839 * ### for ODP make Config right!
840 */
841// if ( excluded.isEmpty() && positions.isEmpty() ) return;
842 /*
843 * Now safe for each path
844 */
845 OConfig cfg( configName() );
846
847 /* safe excluded items */
848 for ( QMap<QString, QStringList>::Iterator it = excluded.begin(); it != excluded.end(); ++it ) {
849 OConfigGroupSaver saver( &cfg, it.key() );
850 cfg.writeEntry("Excluded", it.data(), ',' );
851 }
852
853 /* safe positions we could also see if positions.contains(path) and remove/write in the above loop
854 * ### Write a Test Suite that can profile these runs...
855 */
856 for ( QMap<QString, QStringList>::Iterator it = positions.begin(); it != positions.end(); ++it ) {
857 OConfigGroupSaver saver( &cfg, it.key() );
858 cfg.writeEntry("Positions", it.data(), '.' );
859 }
860}
861
862/**
863 * @internal
864 */
865QString OPluginManager::configName()const {
866 QString str = m_loader ? m_loader->name() : m_cfgName;
867 return str + "odpplugins";
868}
869
870/**
871 * @internal.. replace in m_plugins by path... this is linear search O(n/2)
872 */
873void OPluginManager::replace( const OPluginItem& item ) {
874// ### fixme
875}
539 876
540} 877}
541} 878}
diff --git a/libopie2/opiecore/opluginloader.h b/libopie2/opiecore/opluginloader.h
index 6166b75..2f9ec2a 100644
--- a/libopie2/opiecore/opluginloader.h
+++ b/libopie2/opiecore/opluginloader.h
@@ -1,181 +1,206 @@
1/* 1/*
2 * LGPLv2 or later 2 * LGPLv2 or later
3 * zecke@handhelds.org 3 * zecke@handhelds.org
4 */ 4 */
5#ifndef ODP_CORE_OPLUGIN_LOADER_H 5#ifndef ODP_CORE_OPLUGIN_LOADER_H
6#define ODP_CORE_OPLUGIN_LOADER_H 6#define ODP_CORE_OPLUGIN_LOADER_H
7 7
8#include <qpe/qlibrary.h> 8#include <qpe/qlibrary.h>
9 9
10#include <qptrdict.h> 10#include <qptrdict.h>
11#include <qstringlist.h> 11#include <qstringlist.h>
12 12
13namespace Opie { 13namespace Opie {
14namespace Core { 14namespace Core {
15class OConfig; 15class OConfig;
16namespace Internal { 16namespace Internal {
17class OPluginLibraryHolder; 17class OPluginLibraryHolder;
18} 18}
19 19
20template class QPtrDict<QLibrary>; 20template class QPtrDict<QLibrary>;
21 21
22/** 22/**
23 * \brief A small item representing the Plugin Information 23 * \brief A small item representing the Plugin Information
24 * This class contains the information about a Plugin. It contains 24 * This class contains the information about a Plugin. It contains
25 * a translated name if available to the system, a config key, 25 * a translated name if available to the system, a config key,
26 * and the path location. 26 * and the path location.
27 * 27 *
28 * @since 1.2 28 * @since 1.2
29 * 29 *
30 */ 30 */
31class OPluginItem { 31class OPluginItem {
32public: 32public:
33 typedef QValueList<OPluginItem> List; 33 typedef QValueList<OPluginItem> List;
34 OPluginItem(); 34 OPluginItem();
35 OPluginItem( const QString& name, const QString& path, int pos = -1 ); 35 OPluginItem( const QString& name, const QString& path, bool enabled = true, int pos = -1 );
36 ~OPluginItem(); 36 ~OPluginItem();
37 37
38 bool isEmpty()const;
39
38 bool operator==( const OPluginItem& )const; 40 bool operator==( const OPluginItem& )const;
39 bool operator!=( const OPluginItem& )const; 41 bool operator!=( const OPluginItem& )const;
40 42
41 43
42 QString name()const; 44 QString name()const;
43 QString path()const; 45 QString path()const;
46 bool isEnabled()const;
44 int position()const; 47 int position()const;
45 48
46 void setName( const QString& ); 49 void setName( const QString& );
47 void setPath( const QString& ); 50 void setPath( const QString& );
51 void setEnabled( bool );
48 void setPosition( int ); 52 void setPosition( int );
49 53
50private: 54private:
51 QString m_name; 55 QString m_name;
52 QString m_path; 56 QString m_path;
57 bool m_enabled : 1;
53 int m_pos; 58 int m_pos;
54 struct Private; 59 struct Private;
55 Private *d; 60 Private *d;
56}; 61};
57 62
58/** 63/**
59 * \brief A generic class to easily load and manage plugins 64 * \brief A generic class to easily load and manage plugins
60 * 65 *
61 * This is the generic non sepcialised loader for plugins. Normally 66 * This is the generic non sepcialised loader for plugins. Normally
62 * you would prefer using the OPluginLoader directly. This class 67 * you would prefer using the OPluginLoader directly. This class
63 * exists to minimize the application binary size due the usage 68 * exists to minimize the application binary size due the usage
64 * of templates in the specialized API 69 * of templates in the specialized API
65 * 70 *
66 * @since 1.2 71 * @since 1.2
67 * @see OPluginLoader 72 * @see OPluginLoader
68 */ 73 */
69class OGenericPluginLoader { 74class OGenericPluginLoader {
70public: 75public:
71 typedef OPluginItem::List List; 76 typedef OPluginItem::List List;
72 OGenericPluginLoader( const QString &name, bool isSorted = false ); 77 OGenericPluginLoader( const QString &name, bool isSorted = false );
73 virtual ~OGenericPluginLoader(); 78 virtual ~OGenericPluginLoader();
74 79
75 void setAutoDelete( bool ); 80 void setAutoDelete( bool );
76 bool autoDelete()const; 81 bool autoDelete()const;
77 void clear(); 82 void clear();
78 83
79 84 QString name()const;
85 bool isSorted()const;
80 bool isInSafeMode()const; 86 bool isInSafeMode()const;
81 87
82 88
83 List allAvailable(bool sorted = FALSE)const; 89 List allAvailable(bool sorted = false )const;
84 List filtered(bool sorted = FALSE)const; 90 List filtered(bool sorted = false )const;
85 91
86 92
87 virtual QUnknownInterface* load( const OPluginItem& item, const QUuid& ); 93 virtual QUnknownInterface* load( const OPluginItem& item, const QUuid& );
88 virtual void unload( QUnknownInterface* ); 94 virtual void unload( QUnknownInterface* );
89 95
90protected: 96protected:
97 friend class OPluginManager; // we need the static unlibify
91 void readConfig(); 98 void readConfig();
92 virtual List plugins( const QString& dir, bool sorted, bool disabled )const; 99 virtual List plugins( const QString& dir, bool sorted, bool disabled )const;
93 void setPluginDirs( const QStringList& ); 100 void setPluginDirs( const QStringList& );
94 void setPluginDir( const QString& ); 101 void setPluginDir( const QString& );
95 bool isSorted()const;
96 void setSafeMode(const QString& app = QString::null, bool b = false); 102 void setSafeMode(const QString& app = QString::null, bool b = false);
97 static QString unlibify( const QString& str ); 103 static QString unlibify( const QString& str );
98
99private: 104private:
100 QStringList languageList(); 105 QStringList languageList();
101 void installTranslators(const QString& type); 106 void installTranslators(const QString& type);
102 QString m_dir; 107 QString m_dir;
103 QStringList m_plugDirs; 108 QStringList m_plugDirs;
104 QStringList m_languages; 109 QStringList m_languages;
105 bool m_autoDelete : 1; 110 bool m_autoDelete : 1;
106 bool m_isSafeMode : 1; 111 bool m_isSafeMode : 1;
107 bool m_isSorted : 1; 112 bool m_isSorted : 1;
108 QPtrDict<QLibrary> m_library; 113 QPtrDict<QLibrary> m_library;
109 114
110 struct Private; 115 struct Private;
111 Private* d; 116 Private* d;
112}; 117};
113 118
114/** 119/**
115 * \brief The class to load your QCOM+ plugins 120 * \brief The class to load your QCOM+ plugins
116 * 121 *
117 * This class takes care of activation and even the order 122 * This class takes care of activation and even the order
118 * if you need it. It is normally good to place a .directory file 123 * if you need it. It is normally good to place a .directory file
119 * into your plugin directory if you need order of activation. 124 * into your plugin directory if you need order of activation.
120 * 125 *
121 * You'll create the OPluginLoader and then use it to load the filtered 126 * You'll create the OPluginLoader and then use it to load the filtered
122 * plugins. 127 * plugins.
123 * 128 *
124 * There is also a GUI for the configuration and a Manager to write the 129 * There is also a GUI for the configuration and a Manager to write the
125 * mentioned .directory file 130 * mentioned .directory file
126 * 131 *
127 * On crash the safe mode is activated for the next run. You can then decide 132 * On crash the safe mode is activated for the next run. You can then decide
128 * if you want to load plugins or come up with the Configuration on 133 * if you want to load plugins or come up with the Configuration on
129 * next start yourself then. 134 * next start yourself then.
130 * 135 *
131 * @since 1.2 136 * @since 1.2
132 */ 137 */
133class OPluginLoader : public OGenericPluginLoader { 138class OPluginLoader : public OGenericPluginLoader {
134public: 139public:
135 OPluginLoader( const QString& name, bool sorted = false ); 140 OPluginLoader( const QString& name, bool sorted = false );
136 ~OPluginLoader(); 141 virtual ~OPluginLoader();
137 142
138 template<class IFace> 143 template<class IFace>
139 IFace* load( const OPluginItem& item, const QUuid& ); 144 IFace* load( const OPluginItem& item, const QUuid& );
140}; 145};
141 146
142/** 147/**
143 * \brief A class to manager order and activation of plugins 148 * \brief A class to manage order and activation of plugins
144 * 149 *
145 * Manage order and activation. This is used by the Opie::Ui::OPluginConfig 150 * Manage order and activation. This is used by the Opie::Ui::OPluginConfig
146 * This class controls the activation and order of plugins depending 151 * This class controls the activation and order of plugins depending
147 * on the OPluginLoader you supply. 152 * on the OPluginLoader you supply.
153 * You must call load() and save after construnction an instance
148 * 154 *
149 * @see OPluginConfig 155 * @see Opie::Ui::OPluginConfig
150 * 156 *
151 */ 157 */
152class OPluginManager { 158class OPluginManager {
153public: 159public:
154 OPluginManager( OGenericPluginLoader* , const QString& name); 160 OPluginManager( OGenericPluginLoader* );
155 OPluginManager( OConfig* conf, const QString&, 161 OPluginManager( const QString& name, const OPluginItem::List&, bool isSorted = false );
156 const QCString& group, const OPluginItem::List& ); 162 virtual ~OPluginManager();
157 ~OPluginManager();
158 163
159 QString name(); 164 OPluginItem crashedPlugin()const;
160 void setName( const QString& ); 165
166 OPluginItem::List managedPlugins()const;
161 167
162 void setPosition( const OPluginItem& ); 168 void setPosition( const OPluginItem& );
163 void enable( const OPluginItem& ); 169 void enable( const OPluginItem& );
164 void disable( const OPluginItem& ); 170 void disable( const OPluginItem& );
165 void setEnabled( const OPluginItem&, bool = true); 171 void setEnabled( const OPluginItem&, bool = true);
166 172
167 void load(); 173 virtual void load();
168 void save(); 174 virtual void save();
175
176protected:
177 QString configName()const;
178 void replace( const OPluginItem& );
179private:
180 OGenericPluginLoader *m_loader;
181 QString m_cfgName;
182 OPluginItem::List m_plugins;
183 OPluginItem m_crashed;
184 bool m_isSorted : 1;
169}; 185};
170 186
171 187
188/**
189 * This is a template method allowing you to safely cast
190 * your load function
191 *
192 * \code
193 * MyTypePlugin *plug = load->load<MyTypePlugin>( item, IID_MyPlugin );
194 * \endcode
195 *
196 */
172template<class IFace> 197template<class IFace>
173IFace* OPluginLoader::load( const OPluginItem& item, const QUuid& uid ) { 198IFace* OPluginLoader::load( const OPluginItem& item, const QUuid& uid ) {
174 return static_cast<IFace*>( OGenericPluginLoader::load( item, uid ) ); 199 return static_cast<IFace*>( OGenericPluginLoader::load( item, uid ) );
175} 200}
176 201
177} 202}
178} 203}
179 204
180 205
181#endif 206#endif