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