author | zecke <zecke> | 2004-05-10 21:11:25 (UTC) |
---|---|---|
committer | zecke <zecke> | 2004-05-10 21:11:25 (UTC) |
commit | 23a70b8db47ea571bf9a35f4ff8f5696a6c9c1d3 (patch) (side-by-side diff) | |
tree | b084195bd871b12c3ea1b01e52a4916d17c8a2c6 /libopie2/opiecore/opluginloader.cpp | |
parent | 613e0a6b246d8dcfd808089b2b6a1dc0501732da (diff) | |
download | opie-23a70b8db47ea571bf9a35f4ff8f5696a6c9c1d3.zip opie-23a70b8db47ea571bf9a35f4ff8f5696a6c9c1d3.tar.gz opie-23a70b8db47ea571bf9a35f4ff8f5696a6c9c1d3.tar.bz2 |
First draft of PluginLoader
-actual loading of plugins is 80% done
-Manager no code is there yet. I hope to have some time in uni tomorrow
Diffstat (limited to 'libopie2/opiecore/opluginloader.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libopie2/opiecore/opluginloader.cpp | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/libopie2/opiecore/opluginloader.cpp b/libopie2/opiecore/opluginloader.cpp new file mode 100644 index 0000000..e5a0903 --- a/dev/null +++ b/libopie2/opiecore/opluginloader.cpp @@ -0,0 +1,397 @@ +/* + * LGPLv2 or later + * zecke@handhelds.org + */ + +#include "opluginloader.h" + +#include <stdlib.h> + + + +namespace Opie { +namespace Core { +namespace Internal { +struct OPluginLibraryHolder { + static OPluginLibraryHolder *self(); + QLibrary *getLibrary( const QString& ); + void putLibrary( QLibrary* ); +private: + OPluginLibraryHolder(); + ~OPluginLibraryHolder(); + OPluginLibraryHolder* m_self; + +}; +} + +}} +/** + * \brief Creates an Empty OPluginItem + * + * create an empty pluginitem. Position is set to -1 and the + * other things are used with the default ctors + */ +OPluginItem::OPluginItem() + : m_pos( -1 ) { +} + +/** + * \brief Create an OPluginItem + * + * Create a Plugin Item with all information. + * + * @param name The if available translated Name + * @param conf The name of the config group + * @param path The path to the plugin + * @param pos The position of the plugin if used for sorting + * + */ +OPluginItem::OPluginItem( const QString& name, const QCString& conf, + const QString& path, int pos = -1 ) + : m_name( name ), m_conf( conf ), m_path( path ), m_pos( pos ) { +} + +/** + * \brief simple d'tor + */ +OPluginItem::~OPluginItem() { +} + +/** + * operator to test equalness of two OPluginItem + */ +bool OPluginItem::operator==( const OPluginItem& r )const{ + if ( m_pos != r.m_pos ) return false; + if ( m_name != r.m_name ) return false; + if ( m_conf != r.m_conf ) return false; + if ( m_path != r.m_path ) return false; + return true; +} + +bool OPluginItem::operator!=( const OPluginItem& r ) { + return !( *this == r ); +} + +/** + * return the name of this Plugin + */ +QString OPluginItem::name()const { + return m_name; +} + +/** + * return the config key + */ +QCString OPluginItem::configKey()const{ + return m_conf; +} + +/** + * return the path of the plugin + */ +QString OPluginItem::path()const { + return m_path; +} + +int OPluginItem::position()const{ + return m_pos; +} + +/** + * Set the name of the Plugin Item + * @param name + */ +void OPluginItem::setName( const QString& name ) { + m_name = name; +} + +/** + * Set the config key + * @param key The config key/group of this plugin + */ +void OPluginItem::setConfigKey( const QCString& conf ) { + m_conf = conf; +} + +/** + * Set the path of Plugin Item + * @param name The path of the plugin + */ +void OPluginItem::setPath( const QString& name ) { + m_name = name; +} + +/** + * Set the position + * @param pos The position + */ +void OPluginItem::setPosition( int pos ) { + m_pos = pos; +} + + + +/** + * \brief create a PluginLoader + * + * Create a PluginLoader autoDelete is set to false + * + * \code + * Opie::Core::OGenericPluginLoader loader("myapp-plugin"); + * Opie::Core::OPluginItem::List lst = loader.filtered(); + * for(Opie::Core::OPluginItem::List::Iterator it = lst.begin(); it!=lst.end();++it){ + * MyIface* iface = static_cast<MyIface*>(loader.load(*it,IID_MyIface)); + * } + * \endcode + * + * \code + * Opie::Core::OGenericPluginLoader loader("myapp-plugin"); + * Opie::Core::OPluginItem::List lst = loader.filtered(); + * for(Opie::Core::OPluginItem::List::Iterator it = lst.begin(); it!=lst.end();++it){ + * MyIface* iface = static_cast<MyIface*>(loader.load(*it,IID_MyIface)); + * } + * ... + * loader.clear(); + * + * \endcode + * + * @param name The name of the plugin directory. + * @param isSorted Tell the PluginLoader if your Plugins are sorted + */ +OGenericPluginLoader::OGenericPluginLoader( const QString& name, bool isSorted) + : m_dir( name ), m_autoDelete( false ), m_isSafeMode( false ), + m_isSorted( isSorted ), m_readConfig( false ) +{ + setPluginDir( QPEApplication::qpeDir() + "/plugins/"+name ); +} + + +/** + * calls clear if autoDelete is true. This will release all interfaces + * and remove the library from this process if the refcount falls to zero + */ +OGenericPluginLoader::~OGenericPluginLoader() { + if ( m_autoDelete ) + clear(); +} + +/** + * enable autoDelete. This will call clear on the d'tor + * + * @see ~OGenericPluginLoader + * @see clear() + */ +void OGenericPluginLoader::setAutoDelete( bool t ) { + m_autoDelete = t; +} + +/** + * see if autoDelet is enabled + */ +bool OGenericPluginLoader::autoDelete()const{ + return m_autoDelete; +} + +/** + * This will unload all returned QUnknownInterfaces by load. Unload + * will be called. + */ +void OGenericPluginLoader::clear() { + QPtrDictIterator<QLibrary> it( m_library ); + for ( ;it.current(); ) + unload( static_cast<QUnknownInterface*>( it.currentKey() ) ); +} + +/** + * This will take the iface from the internal QPtrDict, Release it, + * and deref the libray used. + * The visibility depends on the QPtrDict. + * @see QPtrDict::insert + */ +void OGenericPluginLoader::unload( QUnknownInterface* iface ) { + if ( !iface ) + return; + + iface->release(); + OPluginLibraryHolder::self()->deref( m_library.take( iface ) ); +} + +/** + * This tells you + * if by previous tries to load, loading crashed your application. + * If isInSafeMode you can use the GUI to configure the plugins prior to loading + * + * @return true if prior loading failed + */ +bool OGenericPluginLoader::isInSafeMode()const { + if ( !m_readConfig ) + readConfig(); + return m_isSafeMode; +} + +/** + * return if the plugin list is sorted. + */ +bool OGenericPluginLoader::isSorted()const { + if ( !m_readConfig ) + readConfig(); + return m_isSorted; +} + +/** + * Return the list of all available plugins. This will go through all plugin + * directories and search for your type of plugins ( by subdir ) + * + * @param sorted Tell if you want to have the positions sorted. This only makes sense if you + */ +OPluginItem::List OGenericPluginLoader::allAvailable( bool sorted )const { + OPluginItem::List lst; + for ( QStringList::ConstIterator it = m_plugDirs.begin(); it != m_plugDirs.end(); ++it ) + lst += plugins( *it, sorted, false ); + + if ( sorted ) + qHeapSort( lst ); + return lst; +} + +/** + * Return only activated plugins. + * + * @param sorted If the list should be sorted + */ +OPluginItem::List OGenericPluginLoader::filtered( bool sorted )const { + OPluginItem::List lst; + for ( QStringList::ConstIterator it = m_plugDirs.begin(); it != m_plugDirs.end(); ++it ) + lst += plugins( *it, sorted, true ); + + if ( sorted ) + qHeapSort( lst ); + return lst; +} + + +/** + * + */ +QUnknownInterface* OGenericPluginLoader::load( const OPluginItem& item, const QUuid& uuid) { + /* + * Check if there could be a library + */ + QString pa = item.path(); + if ( pa.isEmpty() ) + return 0l; + + /* + * See if we get a library + * return if we've none + */ + setSafeMode( true ); + QLibrary *lib = OPluginLibraryHolder::self()->getLibrary( pa ); + if ( !lib ) { + setSafeMode(); + return 0l; + } + + /** + * try to load the plugin and just in case initialize the pointer to a pointer again + */ + QUnknownInterface** iface = 0; + if ( lib->queryInterface( uuid, iface ) == QS_OK ) { + installTranslators(pa.left( pa.find("."))); + m_library.insert( *iface, lib ); + }else + *iface = 0; + + setSafeMode(); + + return *iface; +} + +void OGenericPluginLoader::readConfig() { + m_readConfig = true; + + /* read the config for SafeMode */ + OConfig conf( m_name + "-odpplugins" ); + conf.setGroup( "General" ); + m_isSafeMode = conf.readBoolEntry( "SafeMode", false ); +} + +void OGenericPluginLoader::setSafeMode(bool b) { + OConfig conf( m_name + "-odpplugins" ); + conf.setGroup( "General" ); + conf.writeEntry( "SafeMode", b ); +} + +void OGenericPluginLoader::setPluginDirs( const QStringList& lst ) { + m_plugDirs = lst; +} + +void OGenericPluginLoader::setPluginDir( const QString& str) { + m_plugDirs.clear(); + m_plugDirs.append( str ); +} + +bool &OGenericPluginLoader::isSafeMode()const { + return m_isSafeMode; +} + +bool &OGenericPluginLoader::isSorted()const { + return m_isSorted; +} + +OPluginItem::List OGenericPluginLoader::plugins( const QString& dir, bool sorted, bool disabled ) { +#ifdef Q_OS_MACX + QDir dir( dir, "lib*.dylib" ); +#else + QDir dir( dir, "lib*.so" ); +#endif + /* + * get excluded list and then iterate over them + */ + OConfig cfg( m_name+"odpplugins" ); + cfg.setGroup( dir ); + QStringList excludes = cfg.readListEntry( "Excluded" ); + + QStringList list = dir.entryList(); +// for ( + +} + + +QStringList OGenericPluginLoader::languageList() { + if ( languageList.isEmpty() ) { + /* + * be_BY.CP1251 We will add, be_BY.CP1251,be_BY,be + * to our list of languages. + */ + QString str = ::getenv( "LANG" ); + m_languages += str; + int pos = str.find( '.' ); + + if ( pos > 0 ) + m_languages += str.left( pos ); + + int n_pos = str.find( '_' ); + if ( pos > 0 && n_pos >= pos ) + m_languages += str.left( n_pos ); + + } + return m_languages; +} + +void OGenericPluginLoader::installTranslators(const QString& type) { + QStringList lst = languageList(); + for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { + QTranslator* trans = new QTranslator( qApp ); + QString tfn = QPEApplication::qpeDir()+"/i18n/" + lang + "/" + type + ".qm" ; + if ( trans->load( tfn ) ) + qApp->installTranslator( trans ); + else + delete trans; + } +} + + + +} +} |