Logo Search packages:      
Sourcecode: packagesearch version File versions

pluginmanager.h

//
// C++ Interface: pluginmanager
//
// Description: 
//
//
// Author: Benjamin Mesing <bensmail@gmx.net>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//
#ifndef __PLUGINMANAGER_H_2004_08_11
#define __PLUGINMANAGER_H_2004_08_11

#include <string>
#include <map>
#include <vector>

#include <qdom.h>
#include <qobject.h>

#include "xmldata.h"

#include "plugininformer.h"
#include "plugincontainer.h"  // also for PluginInformation

using namespace std;

class QWidget;
class QListView;
class PluginProgressDlg;
class PluginControl;


namespace NXml
{
      class XmlData;
}

namespace NUtil
{
      class IProgressObserver;
      class ProgressDisplayDlg;
}

namespace NPlugin 
{

class IPluginUser;
class IProvider;
class PluginListItem;

/** @brief The PluginManager can be used to load and manage plugins.
  * 
  * It informs the IPluginUser instances which have registered via the 
  * addPluginUser function about loading and unloading of plugins.
  *
  * The settings for all plugins will be loaded on loadSettings and stored
  * in the PluginManager. If a plugin is loaded, the plugin manager will 
  * search for the settings of this plugin and call its loadSettings function.\n
  * The settings of the manager and the plugins can be stored via the saveSettings 
  * function, where the settings for all active plugins and the plugins 
  * which are disabled will be stored. If a plugin is no longer available 
  * (i.e. neither disabled nor active) its settings will not be saved even
  * if they were loaded before.
  *
  * @author Benjamin Mesing
  */
00069 class PluginManager : public QObject, public PluginInformer
{
      Q_OBJECT
      friend class PluginListItem;
      /** @brief The directories the plugin manager searches for plugins. */
00074       vector<string> _directories;
      /** @brief The provider which provides informations for the plugins. */
00076       IProvider* _pProvider;
      IPluginUser* _pPluginUser;    
      /** @brief This holds the settings for all available plugins. 
        *
        * This is done to hold the settings for plugins which are not
        * loaded so they can also be saved.
        *
        * Implementation note: The QDomElements here come from the QDomTree
        * loaded on loadSettings(). Because of the QDom semantics (including 
        * garbage collection) they won't be deleted. So it is save to access
        * them.
        */
00088       map<string, const QDomElement> _pluginSettings;
      /** @brief The version of the settings tree used by this class. */
00090       const QString _settingsVersion;
      /** @brief This holds a pointer to the dialog displaying the status of the plugin 
        * loading process 
        *
        * This is only set if the dialog is currently active, else it holds 0.
        */
00096       NUtil::ProgressDisplayDlg* _pProgressDlg;
      /** @brief This holds a pointer to the control dialog.
        *
        * This is only set if the dialog is currently active, else it holds 0.
        */
00101       PluginControl* _pControlDialog;
public:
      /**
        * 
        * @param directories the directories the the manager searches for plugins 
        * @param pProvider the provider which provides informations for the plugins
        * @param pUser the user that cares for the plugin changes
        */
      PluginManager(vector<string> directories, IProvider* pProvider, IPluginUser* pUser);
      ~PluginManager();

      /** @brief Save the settings from this plugin container into the given XML tree
        * 
        * Currently the only information is the plugins which are disabled.
        * @param outData XML Document which owns parent
        * @param parent the parent where under to add the settings
        */
      void saveSettings(NXml::XmlData& outData, QDomElement parent);
      /** @brief Loads the settings for the plugins from inData.
        * 
        * Currently the only information is the plugins which are disabled.
        * @param inData XML Document which owns source
        * @param source the element where the information is stored
        */
      void loadSettings(const NXml::XmlData& inData, const QDomElement source);
      /** @brief This shows a dialog which can be used to control the plugins.
        *
        * It allows to enable and disable the different plugins.
        * 
        * @param pParent the widget this dialog should be have as parent,
        * hand 0 if it should be a top level dialog
        */
      void showControlDialog(QWidget* pParent);
      /** @todo remove this function and move the code to the control dialog. */
      void showSettingsDialog(QWidget* pParent);
      /** @brief This loads all available plugins excluding the disabled ones.
        *
        * This loads all plugins found in the plugin directories. It does not load plugins
        * which are disabled.\n
        * Use loadSettings() to read the disabled plugins. */
      void loadPlugins();

      /** This returns the plugins currently loaded
        * 
        */
      vector<PluginContainer*> getLoadedPlugins() const;
      /** @brief Returns the observer where to report progress to.
        *
        * @returns 0 if no observer is available
        */
      NUtil::IProgressObserver* progressObserver();
      
private slots:
      void onPluginToggled(PluginListItem* pSrc, bool state);
/**
 * Protected stuff
 */
protected:
      /** @brief This holds information about the plugin. */
00160       struct PluginData
      {
            PluginData() :
                  information()
            {
                  libraryHandle = 0;
                  pPlugin = 0;
            }
            PluginInformation information;
            string directory;
            bool informationEquals(const PluginData& pd) const
            {
                  return information == pd.information;
            }
            /** Accessors for convenience */
00175             const string& name() const { return information.name; }
            /** Accessors for convenience */
00177             const string& version() const { return information.version; }
            /** Accessors for convenience */
00179             const string& author() const { return information.author; }
            
            /** @brief A pointer to the instance of the plugin, 0 if the plugin is not loaded. */
00182             PluginContainer* pPlugin;
            /** @brief A handle of the loaded library for this plugin, 0 if the plugin is not loaded. */
00184             void* libraryHandle;
      };
      /** @brief Function object to find plugins with equal information. */
00187       struct PluginInformationEquals
      {
            PluginInformationEquals(const PluginData& pd) : _pd(pd)
            {}
            bool operator()(const PluginData& pd) const 
            { return pd.information == _pd.information; }
            bool operator()(const pair<PluginContainer*, PluginData>& p) const
            { return p.second.information == _pd.information; }
      private:
            const PluginData& _pd;
      };
      /** @brief Function object to find plugins which are equal. */
00199       struct PluginEquals
      {
            PluginEquals(const PluginData& pd) : _pd(pd)
            {}
            bool operator()(const PluginData& pd) const 
            { return pd.information == _pd.information && pd.directory == _pd.directory; }
      private:
            const PluginData& _pd;
      };
      /** This returns all plugins currently available.
        *
        * These are plugins that are in the plugin directories and plugins 
        * which are loaded but not longer in any directory.
        */
      vector<PluginData> getAvailablePlugins();
      /** @brief This loads the plugin and informs the plugin users about the loading. 
        *
        * The plugin will be added to the list of loaded plugins.
        * @param directory the directory where the plugin is located
        * @param libraryName the name of the library (without lib and .so)
        * @returns a pointer to the plugin loaded, 0 if loading failed
        * @note You should have called loadSettings before because else
        * this function will be unloaded. 
        */
      PluginContainer* loadPlugin( const string& directory, const string& libraryName);
      /** @brief This unloads the plugin and informs the plugin users about the unloading. 
        * 
        * It will delete the plugin and close the library, so make sure that every reference
        * is removed in the plugin users.
        * @param pPlugin the plugin to be unloaded 
        * @pre pPlugin is_in keys(_loadedPlugins)
        */
      void unloadPlugin(PluginContainer* pPlugin);

private:
      /** @brief This check if an error occured in a dl* function and if so prints
        * the error message to stderr.
        * @returns true if an error occured, else false
        */
      bool checkDlError();
      typedef map<PluginContainer*, PluginData> PluginToDataMap;
      /** @brief This holds the plugins currently loaded.
        *
        * It maps them to the handle of the library used for them. */
00243       PluginToDataMap _loadedPlugins;
      list<PluginData> _disabledPlugins;
      /** @brief This removes the given plugin with the given from the disabled plugin list.
        *
        * @param pd the data of the plugin to be removed, the first disabled plugins which 
        * equals this data will be removed.
        * @returns if data was removed or not
        */
      bool removeFromDisabled(const PluginData& pd);
      /** Holds the listview where the plugins are shown to the user, only active
        * while the plugin dialog is shown.  */
00254       QListView* _pPluginListView;
};

};

#endif      //  __PLUGINMANAGER_H_2004_08_11

Generated by  Doxygen 1.6.0   Back to index