/* * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3 * http://www.gnu.org/licenses/lgpl-3.0.html */ #ifndef PLUGINMANAGER_H #define PLUGINMANAGER_H #include <vector> #include <map> #include <wx/dynarray.h> #include "globals.h" // PluginType #include "settings.h" #include "manager.h" //forward decls struct PluginInfo; class cbPlugin; class cbMimePlugin; class cbConfigurationPanel; class cbProject; class wxDynamicLibrary; class wxMenuBar; class wxMenu; class CodeBlocksEvent; class TiXmlDocument; class FileTreeData; // typedefs for plugins' function pointers typedef void(*PluginSDKVersionProc)(int*,int*,int*); typedef cbPlugin*(*CreatePluginProc)(); typedef void(*FreePluginProc)(cbPlugin*); /** Information about the plugin */ struct PluginInfo { wxString name; wxString title; wxString version; wxString description; wxString author; wxString authorEmail; wxString authorWebsite; wxString thanksTo; wxString license; }; // struct with info about each pluing struct PluginElement { PluginInfo info; // plugin's info struct wxString fileName; // plugin's filename wxDynamicLibrary* library; // plugin's library FreePluginProc freeProc; // plugin's release function pointer cbPlugin* plugin; // the plugin itself }; WX_DEFINE_ARRAY(PluginElement*, PluginElementsArray); WX_DEFINE_ARRAY(cbPlugin*, PluginsArray); WX_DEFINE_ARRAY(cbConfigurationPanel*, ConfigurationPanelsArray); /** * PluginManager manages plugins. * * There are two plugin types: binary and scripted. * * Binary plugins are dynamically loaded shared libraries (dll/so) which * can do pretty much anything with the SDK. * * Script plugins are more lightweight and are very convenient for * smaller scale/functionality plugins. */ class DLLIMPORT PluginManager : public Mgr<PluginManager>, public wxEvtHandler { public: friend class Mgr<PluginManager>; friend class Manager; // give Manager access to our private members void CreateMenu(wxMenuBar* menuBar); void ReleaseMenu(wxMenuBar* menuBar); void RegisterPlugin(const wxString& name, CreatePluginProc createProc, FreePluginProc freeProc, PluginSDKVersionProc versionProc); int ScanForPlugins(const wxString& path); bool LoadPlugin(const wxString& pluginName); void LoadAllPlugins(); void UnloadAllPlugins(); void UnloadPlugin(cbPlugin* plugin); int ExecutePlugin(const wxString& pluginName); int ConfigurePlugin(const wxString& pluginName); bool AttachPlugin(cbPlugin* plugin, bool ignoreSafeMode = false); bool DetachPlugin(cbPlugin* plugin); bool InstallPlugin(const wxString& pluginName, bool forAllUsers = true, bool askForConfirmation = true); bool UninstallPlugin(cbPlugin* plugin, bool removeFiles = true); bool ExportPlugin(cbPlugin* plugin, const wxString& filename); const PluginInfo* GetPluginInfo(const wxString& pluginName); const PluginInfo* GetPluginInfo(cbPlugin* plugin); PluginElementsArray& GetPlugins(){ return m_Plugins; } PluginElement* FindElementByName(const wxString& pluginName); cbPlugin* FindPluginByName(const wxString& pluginName); cbPlugin* FindPluginByFileName(const wxString& pluginFileName); PluginsArray GetToolOffers(); PluginsArray GetMimeOffers(); PluginsArray GetCompilerOffers(); PluginsArray GetDebuggerOffers(); PluginsArray GetCodeCompletionOffers(); PluginsArray GetOffersFor(PluginType type); void AskPluginsForModuleMenu(const ModuleType type, wxMenu* menu, const FileTreeData* data = 0); cbMimePlugin* GetMIMEHandlerForFile(const wxString& filename); void GetConfigurationPanels(int group, wxWindow* parent, ConfigurationPanelsArray& arrayToFill); void GetProjectConfigurationPanels(wxWindow* parent, cbProject* project, ConfigurationPanelsArray& arrayToFill); int Configure(); void SetupLocaleDomain(const wxString& DomainName); void NotifyPlugins(CodeBlocksEvent& event); void NotifyPlugins(CodeBlocksDockEvent& event); void NotifyPlugins(CodeBlocksLayoutEvent& event); static void SetSafeMode(bool on){ s_SafeMode = on; } static bool GetSafeMode(){ return s_SafeMode; } private: PluginManager(); ~PluginManager(); void OnScriptMenu(wxCommandEvent& event); void OnScriptModuleMenu(wxCommandEvent& event); /// @return True if the plugin should be loaded, false if not. bool ReadManifestFile(const wxString& pluginFilename, const wxString& pluginName = wxEmptyString, PluginInfo* infoOut = 0); void ReadExtraFilesFromManifestFile(const wxString& pluginFilename, wxArrayString& extraFiles); bool ExtractFile(const wxString& bundlename, const wxString& src_filename, const wxString& dst_filename, bool isMandatory = true); PluginElementsArray m_Plugins; wxString m_CurrentlyLoadingFilename; wxDynamicLibrary* m_pCurrentlyLoadingLib; TiXmlDocument* m_pCurrentlyLoadingManifestDoc; // this struct fills the following vector each time // RegisterPlugin() is called. // this vector is then used in LoadPlugin() (which triggered // the call to RegisterPlugin()) to actually // load the plugins and then it is cleared. // // This is done to avoid global variables initialization order issues // inside the plugins (yes, it happened to me ;)). struct PluginRegistration { PluginRegistration() : createProc(0), freeProc(0), versionProc(0) {} PluginRegistration(const PluginRegistration& rhs) : name(rhs.name), createProc(rhs.createProc), freeProc(rhs.freeProc), versionProc(rhs.versionProc), info(rhs.info) {} wxString name; CreatePluginProc createProc; FreePluginProc freeProc; PluginSDKVersionProc versionProc; PluginInfo info; }; std::vector<PluginRegistration> m_RegisteredPlugins; static bool s_SafeMode; DECLARE_EVENT_TABLE() }; #endif // PLUGINMANAGER_H