From: mpv Date: Mon, 31 Mar 2014 13:21:32 +0000 (+0400) Subject: Features and plugins loading mechanisms X-Git-Tag: V_0.1~43^2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=6f64126a35fdc516fd74651dc55c7b5dfba96f8f;p=modules%2Fshaper.git Features and plugins loading mechanisms --- diff --git a/env.bat b/env.bat index b0d1e3dec..2ac0c4d6a 100644 --- a/env.bat +++ b/env.bat @@ -128,6 +128,9 @@ if "%QTDIR%" == "" ( @SET PATH=D:\NewGEOM\build-eclipse\bin;%PATH% +@SET NEW_GEOM_CONFIG_FILE=%ROOT_DIR%\install\plugins +@SET PATH=%ROOT_DIR%\install\plugins;%PATH% + rem -------- Visual Studio -------------------- rem Detect Visual Studio (either commercial or Express edition) if "%VS100COMNTOOLS%" == "" ( diff --git a/src/Config/Config_FeatureReader.cpp b/src/Config/Config_FeatureReader.cpp index d95ee7dcc..73a5c07fb 100644 --- a/src/Config/Config_FeatureReader.cpp +++ b/src/Config/Config_FeatureReader.cpp @@ -39,7 +39,7 @@ Config_FeatureReader::Config_FeatureReader(const std::string& theXmlFile) myLibraryName = ""; #ifdef _DEBUG - if (!Event_Loop::Loop()) { + if (!Event_Loop::loop()) { std::cout << "Config_FeatureReader::importWorkbench: " << "No event loop registered" << std::endl; } @@ -53,7 +53,7 @@ Config_FeatureReader::Config_FeatureReader(const std::string& theXmlFile, myFetchWidgetCfg(false) { #ifdef _DEBUG - if (!Event_Loop::Loop()) { + if (!Event_Loop::loop()) { std::cout << "Config_FeatureReader::importWorkbench: " << "No event loop registered" << std::endl; } @@ -74,16 +74,17 @@ std::string Config_FeatureReader::featureWidgetCfg(std::string theFeatureName) void Config_FeatureReader::processNode(xmlNodePtr theNode) { + static Event_ID aMenuItemEvent = Event_Loop::eventByName("RegisterFeature"); if (isNode(theNode, NODE_FEATURE, NULL)) { if (myFetchWidgetCfg) { xmlBufferPtr buffer = xmlBufferCreate(); int size = xmlNodeDump(buffer, theNode->doc, theNode, 0, 1); myWidgetCfg = std::string((char*) buffer->content); } else { - Event_Loop* aEvLoop = Event_Loop::Loop(); - Config_FeatureMessage aMessage(aEvLoop->EventByName("menu_item"), this); + Event_Loop* aEvLoop = Event_Loop::loop(); + Config_FeatureMessage aMessage(aMenuItemEvent, this); fillFeature(theNode, aMessage); - aEvLoop->Send(aMessage); + aEvLoop->send(aMessage); } } //The m_last* variables always defined before fillFeature() call. XML is a tree. diff --git a/src/Config/Config_XMLReader.cpp b/src/Config/Config_XMLReader.cpp index 89f0d46fc..1b206af82 100644 --- a/src/Config/Config_XMLReader.cpp +++ b/src/Config/Config_XMLReader.cpp @@ -11,10 +11,12 @@ #include #include +/* #ifdef WIN32 //For GetModuleFileNameW #include #endif +*/ #ifdef _DEBUG #include @@ -23,6 +25,8 @@ Config_XMLReader::Config_XMLReader(const std::string& theXmlFileName) { std::string prefix; + /* the problem: application may be launched using python execuable, to use environment variable + (at least for the current moment) //Get path to *.xml files (typically ./bin/../plugins/) #ifdef WIN32 HMODULE hModule = GetModuleHandleW(NULL); @@ -40,6 +44,11 @@ Config_XMLReader::Config_XMLReader(const std::string& theXmlFileName) //TODO(sbh): Find full path to binary on linux prefix = "../plugins/"; #endif + */ + char* anEnv = getenv("NEW_GEOM_CONFIG_FILE"); + if (anEnv) { + prefix = std::string(anEnv) + "/"; + } myDocumentPath = prefix + theXmlFileName; } @@ -109,8 +118,6 @@ xmlNodePtr Config_XMLReader::findRoot() */ void Config_XMLReader::readRecursively(xmlNodePtr theParent) { - static Event_ID aFeatureEvent = Event_Loop::EventByName("Feature"); - if (!theParent) return; xmlNodePtr aNode = theParent->xmlChildrenNode; @@ -118,7 +125,6 @@ void Config_XMLReader::readRecursively(xmlNodePtr theParent) processNode(aNode); if (processChildren(aNode)) { readRecursively(aNode); - Config_FeatureMessage aMessage(aFeatureEvent, this); } } } diff --git a/src/Event/Event_Listener.h b/src/Event/Event_Listener.h index 80719d42d..c47d28dbf 100644 --- a/src/Event/Event_Listener.h +++ b/src/Event/Event_Listener.h @@ -19,7 +19,7 @@ class EVENT_EXPORT Event_Listener { public: //! This method is called by loop when the event is started to process. - virtual void ProcessEvent(const Event_Message* theMessage) = 0; + virtual void processEvent(const Event_Message* theMessage) = 0; }; #endif diff --git a/src/Event/Event_Loop.cxx b/src/Event/Event_Loop.cxx index ffcd6c6e5..c5cadce44 100644 --- a/src/Event/Event_Loop.cxx +++ b/src/Event/Event_Loop.cxx @@ -7,14 +7,14 @@ using namespace std; -Event_Loop* Event_Loop::Loop() +Event_Loop* Event_Loop::loop() { // initialized on initialization of the application static Event_Loop MAIN_LOOP; return &MAIN_LOOP; } -Event_ID Event_Loop::EventByName(const char* theName) +Event_ID Event_Loop::eventByName(const char* theName) { ///! All events created in this session, uniquely identified by the text and char pointer static map CREATED_EVENTS; @@ -30,39 +30,39 @@ Event_ID Event_Loop::EventByName(const char* theName) return Event_ID(aResult); } -void Event_Loop::Send(Event_Message& theMessage) +void Event_Loop::send(Event_Message& theMessage) { // TO DO: make it in thread and wit husage of semaphores map > >::iterator aFindID = myListeners.find( - theMessage.EventID().EventText()); + theMessage.eventID().eventText()); if (aFindID != myListeners.end()) { map >::iterator aFindSender = aFindID->second.find( - theMessage.Sender()); + theMessage.sender()); if (aFindSender != aFindID->second.end()) { list& aListeners = aFindSender->second; for(list::iterator aL = aListeners.begin(); aL != aListeners.end(); aL++) - (*aL)->ProcessEvent(&theMessage); + (*aL)->processEvent(&theMessage); } - if (theMessage.Sender()) { // also call for NULL senders registered + if (theMessage.sender()) { // also call for NULL senders registered aFindSender = aFindID->second.find(NULL); if (aFindSender != aFindID->second.end()) { list& aListeners = aFindSender->second; for(list::iterator aL = aListeners.begin(); aL != aListeners.end(); aL++) - (*aL)->ProcessEvent(&theMessage); + (*aL)->processEvent(&theMessage); } } } } -void Event_Loop::RegisterListener(Event_Listener* theListener, const Event_ID theID, +void Event_Loop::registerListener(Event_Listener* theListener, const Event_ID theID, void* theSender) { map > >::iterator aFindID = myListeners.find( - theID.EventText()); + theID.eventText()); if (aFindID == myListeners.end()) { // create container associated with ID - myListeners[theID.EventText()] = map >(); - aFindID = myListeners.find(theID.EventText()); + myListeners[theID.eventText()] = map >(); + aFindID = myListeners.find(theID.eventText()); } map >::iterator aFindSender = aFindID->second.find(theSender); diff --git a/src/Event/Event_Loop.h b/src/Event/Event_Loop.h index d93b942eb..60ddacd73 100644 --- a/src/Event/Event_Loop.h +++ b/src/Event/Event_Loop.h @@ -29,17 +29,17 @@ class Event_Loop { Event_Loop() {}; public: ///! Returns the main object of the loop, one per application. - EVENT_EXPORT static Event_Loop* Loop(); + EVENT_EXPORT static Event_Loop* loop(); //! Returns the unique event by the given name. Call this method only on initialization of object //! to speedup the events processing without parsing of the string. - EVENT_EXPORT static Event_ID EventByName(const char* theName); + EVENT_EXPORT static Event_ID eventByName(const char* theName); //! Allows to send an event - EVENT_EXPORT void Send(Event_Message& theMessage); + EVENT_EXPORT void send(Event_Message& theMessage); //! Registers (or adds if such listener is already registered) a listener //! that will be called on the event and from the defined sender - EVENT_EXPORT void RegisterListener(Event_Listener* theListener, const Event_ID theID, + EVENT_EXPORT void registerListener(Event_Listener* theListener, const Event_ID theID, void* theSender = 0); }; diff --git a/src/Event/Event_Message.h b/src/Event/Event_Message.h index 27608b7bf..6c851815c 100644 --- a/src/Event/Event_Message.h +++ b/src/Event/Event_Message.h @@ -25,7 +25,7 @@ class EVENT_EXPORT Event_ID { friend class Event_Loop; public: /// Returns the text-identifier of the event (for debugging reasons) - char* EventText() const {return myID;} + char* eventText() const {return myID;} /// Allows to compare identifiers bool operator==(const Event_ID& theID) const {return myID == theID.myID;} }; @@ -46,10 +46,10 @@ public: virtual ~Event_Message() {} //! Returns identifier of the message - const Event_ID& EventID() const {return myEventId;} + const Event_ID& eventID() const {return myEventId;} //! Returns sender of the message or NULL if it is anonymous message - void* Sender() {return mySender;} + void* sender() {return mySender;} }; #endif diff --git a/src/Model/Model_PluginManager.cxx b/src/Model/Model_PluginManager.cxx index e06c66518..c4e28665d 100644 --- a/src/Model/Model_PluginManager.cxx +++ b/src/Model/Model_PluginManager.cxx @@ -4,33 +4,29 @@ #include #include +#include #include #include #include #include -#include - using namespace std; static Model_PluginManager* myImpl = new Model_PluginManager(); -boost::shared_ptr Model_PluginManager::CreateFeature(string theFeatureID) +boost::shared_ptr Model_PluginManager::createFeature(string theFeatureID) { - if (this != myImpl) return myImpl->CreateFeature(theFeatureID); + if (this != myImpl) return myImpl->createFeature(theFeatureID); LoadPluginsInfo(); if (myPlugins.find(theFeatureID) != myPlugins.end()) { - string aLibName = myPlugins[theFeatureID]; -#ifdef WIN32 - aLibName += ".dll"; -#else - aLibName += ".so"; -#endif - Standard_CString aLibNameCStr = aLibName.c_str(); - OSD_SharedLibrary aLib(aLibNameCStr); - if (aLib.DlOpen(OSD_RTLD_NOW)) { - OSD_Function aFunc = aLib.DlSymb("CreateFeature"); + if (myPluginObjs.find(myPlugins[theFeatureID]) == myPluginObjs.end()) { + // load plugin library if not yet done + myCurrentPluginName = myPlugins[theFeatureID]; + loadLibrary(myCurrentPluginName); + } + if (myPluginObjs.find(myCurrentPluginName) != myPluginObjs.end()) { + return myPluginObjs[myCurrentPluginName]->createFeature(theFeatureID); } } @@ -40,22 +36,22 @@ boost::shared_ptr Model_PluginManager::CreateFeature(string th Model_PluginManager::Model_PluginManager() { myPluginsInfoLoaded = false; - static Event_ID aFeatureEvent = Event_Loop::EventByName("Feature"); + static Event_ID aFeatureEvent = Event_Loop::eventByName("RegisterFeature"); ModelAPI_PluginManager::SetPluginManager(boost::shared_ptr(this)); // register the configuration reading listener - Event_Loop* aLoop = Event_Loop::Loop(); - aLoop->RegisterListener(myImpl, aFeatureEvent); + Event_Loop* aLoop = Event_Loop::loop(); + aLoop->registerListener(this, aFeatureEvent); } -void Model_PluginManager::ProcessEvent(const Event_Message* theMessage) +void Model_PluginManager::processEvent(const Event_Message* theMessage) { const Config_FeatureMessage* aMsg = - dynamic_cast( theMessage ); + dynamic_cast(theMessage); if (aMsg) { // proccess the plugin info, load plugin if (myPlugins.find(aMsg->id()) == myPlugins.end()) { - myPlugins[aMsg->id()] = "PartSetPlugin"; // TO DO: plugin name must be also imported from XMLs + myPlugins[aMsg->id()] = aMsg->pluginLibrary(); // TO DO: plugin name must be also imported from XMLs } } // plugins information was started to load, so, it will be loaded @@ -72,3 +68,8 @@ void Model_PluginManager::LoadPluginsInfo() aXMLReader.setAutoImport(true); aXMLReader.readAll(); } + +void Model_PluginManager::registerPlugin(ModelAPI_Plugin* thePlugin) +{ + myPluginObjs[myCurrentPluginName] = thePlugin; +} diff --git a/src/Model/Model_PluginManager.h b/src/Model/Model_PluginManager.h index 44dbef3b5..5a847abce 100644 --- a/src/Model/Model_PluginManager.h +++ b/src/Model/Model_PluginManager.h @@ -20,13 +20,21 @@ class Model_PluginManager : public ModelAPI_PluginManager, public Event_Listener { bool myPluginsInfoLoaded; ///< it true if plugins information is loaded - std::map myPlugins; ///< map of feature IDs to plugin name + /// map of feature IDs to plugin name and object + std::map myPlugins; + std::map myPluginObjs; ///< instances of the already plugins + std::string myCurrentPluginName; ///< name of the plugin that must be loaded currently public: /// Creates the feature object using plugins functionality - MODEL_EXPORT virtual boost::shared_ptr CreateFeature(std::string theFeatureID); + MODEL_EXPORT virtual boost::shared_ptr createFeature(std::string theFeatureID); + + /// Registers the plugin that creates features. + /// It is obligatory for each plugin to call this function on loading to be found by + /// the plugin manager on call of the feature) + virtual void registerPlugin(ModelAPI_Plugin* thePlugin); /// Processes the configuration file reading - MODEL_EXPORT virtual void ProcessEvent(const Event_Message* theMessage); + MODEL_EXPORT virtual void processEvent(const Event_Message* theMessage); /// Is called only once, on startup of the application Model_PluginManager(); diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index 399d32f8b..33fe1bcf8 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -11,6 +11,7 @@ SET(PROJECT_HEADERS ModelAPI.h ModelAPI_Interface.h ModelAPI_PluginManager.h + ModelAPI_Plugin.h ModelAPI_Feature.h ModelAPI_Document.h ) diff --git a/src/ModelAPI/ModelAPI_Document.h b/src/ModelAPI/ModelAPI_Document.h index e2941745d..911aca068 100644 --- a/src/ModelAPI/ModelAPI_Document.h +++ b/src/ModelAPI/ModelAPI_Document.h @@ -55,6 +55,7 @@ public: //! Redoes last operation MODELAPI_EXPORT virtual void Redo() = 0; +protected: /// Only for SWIG wrapping it is here MODELAPI_EXPORT ModelAPI_Document() { diff --git a/src/ModelAPI/ModelAPI_Feature.h b/src/ModelAPI/ModelAPI_Feature.h index ffa5448c4..2c9339c74 100644 --- a/src/ModelAPI/ModelAPI_Feature.h +++ b/src/ModelAPI/ModelAPI_Feature.h @@ -22,6 +22,7 @@ public: /// Returns the kind of a feature (like "Point") virtual std::string GetKind() = 0; +protected: /// Use plugin manager for features creation: this method is /// defined here only for SWIG-wrapping ModelAPI_Feature() diff --git a/src/ModelAPI/ModelAPI_Plugin.h b/src/ModelAPI/ModelAPI_Plugin.h new file mode 100644 index 000000000..5d2d0430c --- /dev/null +++ b/src/ModelAPI/ModelAPI_Plugin.h @@ -0,0 +1,30 @@ +// File: ModelAPI_Plugin.hxx +// Created: 31 Mar 2014 +// Author: Mikhail PONIKAROV + +#ifndef ModelAPI_Plugin_HeaderFile +#define ModelAPI_Plugin_HeaderFile + +#include "ModelAPI.h" +#include +#include + +class ModelAPI_Feature; + +/**\class ModelAPI_Plugin + * \ingroup DataModel + * \brief Interface common for any plugin: allows to use plugin by the plugins manager. + */ + +class MODELAPI_EXPORT ModelAPI_Plugin +{ +public: + /// Creates the feature object of this plugin by the feature string ID + virtual boost::shared_ptr createFeature(std::string theFeatureID) = 0; + +protected: + /// Is needed for python wrapping by swig + ModelAPI_Plugin() {}; +}; + +#endif diff --git a/src/ModelAPI/ModelAPI_PluginManager.cxx b/src/ModelAPI/ModelAPI_PluginManager.cxx index cde7f69bf..d4a20feae 100644 --- a/src/ModelAPI/ModelAPI_PluginManager.cxx +++ b/src/ModelAPI/ModelAPI_PluginManager.cxx @@ -7,6 +7,8 @@ #include // to avoid unresolved ModelAPI_Feature() #include +// to avoid unresolved ModelAPI_Plugin() +#include #ifdef WIN32 #include @@ -16,8 +18,6 @@ using namespace std; -/// loads the library with specific name, appends "lib*.dll" or "*.so" depending on the platform -void loadLibrary(const string theLibName); /// Converts library name to the operation system file name string library(const string& theLibName); @@ -34,7 +34,7 @@ void ModelAPI_PluginManager::SetPluginManager( MY_MANAGER = theManager; } -boost::shared_ptr ModelAPI_PluginManager::Get() +boost::shared_ptr ModelAPI_PluginManager::get() { if (!MY_MANAGER) { // import Model library that implements this interface of ModelAPI loadLibrary("Model"); @@ -62,7 +62,7 @@ string library(const string& theLibName) return aLibName; } -void loadLibrary(const string theLibName) +void ModelAPI_PluginManager::loadLibrary(const string theLibName) { string aFileName = library(theLibName); if ( aFileName.empty() ) diff --git a/src/ModelAPI/ModelAPI_PluginManager.h b/src/ModelAPI/ModelAPI_PluginManager.h index c4033c3b1..620501bfd 100644 --- a/src/ModelAPI/ModelAPI_PluginManager.h +++ b/src/ModelAPI/ModelAPI_PluginManager.h @@ -10,6 +10,7 @@ #include class ModelAPI_Feature; +class ModelAPI_Plugin; /**\class ModelAPI_PluginManager * \ingroup DataModel @@ -22,10 +23,18 @@ class MODELAPI_EXPORT ModelAPI_PluginManager { public: /// Creates the feature object using plugins functionality - virtual boost::shared_ptr CreateFeature(std::string theFeatureID) = 0; + virtual boost::shared_ptr createFeature(std::string theFeatureID) = 0; /// Returns the real implementation (the alone instance per application) of the plugin manager - static boost::shared_ptr Get(); + static boost::shared_ptr get(); + + /// Registers the plugin that creates features. + /// It is obligatory for each plugin to call this function on loading to be found by + /// the plugin manager on call of the feature) + virtual void registerPlugin(ModelAPI_Plugin* thePlugin) = 0; + + /// loads the library with specific name, appends "lib*.dll" or "*.so" depending on the platform + static void ModelAPI_PluginManager::loadLibrary(const std::string theLibName); /// Is needed for python wrapping by swig, call Get to get an instance ModelAPI_PluginManager(); diff --git a/src/PartSetPlugin/CMakeLists.txt b/src/PartSetPlugin/CMakeLists.txt index d6d5787f7..ab07cdc88 100644 --- a/src/PartSetPlugin/CMakeLists.txt +++ b/src/PartSetPlugin/CMakeLists.txt @@ -5,11 +5,12 @@ INCLUDE(FindBoost) SET(PROJECT_HEADERS PartSetPlugin.h + PartSetPlugin_Plugin.h PartSetPlugin_NewPart.h ) SET(PROJECT_SOURCES - PartSetPlugin.cxx + PartSetPlugin_Plugin.cxx PartSetPlugin_NewPart.cxx ) diff --git a/src/PartSetPlugin/PartSetPlugin.cxx b/src/PartSetPlugin/PartSetPlugin.cxx deleted file mode 100644 index 1b641c3a1..000000000 --- a/src/PartSetPlugin/PartSetPlugin.cxx +++ /dev/null @@ -1,16 +0,0 @@ -#include "PartSetPlugin.h" - -#include -#include - -using namespace std; - -/// Standard method of the plugin that creates a specific feature instance by the feature kind -PARTSETPLUGIN_EXPORT boost::shared_ptr CreateFeature(const string& theFeatureKind) -{ - if (theFeatureKind == "new_part") { - return boost::shared_ptr(new PartSetPlugin_NewPart()); - } - // feature of such kind is not found - return boost::shared_ptr(); -} diff --git a/src/PartSetPlugin/PartSetPlugin_Plugin.cxx b/src/PartSetPlugin/PartSetPlugin_Plugin.cxx new file mode 100644 index 000000000..d3d295dc7 --- /dev/null +++ b/src/PartSetPlugin/PartSetPlugin_Plugin.cxx @@ -0,0 +1,23 @@ +#include "PartSetPlugin_Plugin.h" +#include "PartSetPlugin_NewPart.h" +#include + +using namespace std; + +// the only created instance of this plugin +static PartSetPlugin_Plugin* MY_INSTANCE = new PartSetPlugin_Plugin(); + +PartSetPlugin_Plugin::PartSetPlugin_Plugin() +{ + // register this plugin + ModelAPI_PluginManager::get()->registerPlugin(this); +} + +boost::shared_ptr PartSetPlugin_Plugin::createFeature(string theFeatureID) +{ + if (theFeatureID == "new_part") { + return boost::shared_ptr(new PartSetPlugin_NewPart()); + } + // feature of such kind is not found + return boost::shared_ptr(); +} diff --git a/src/PartSetPlugin/PartSetPlugin_Plugin.h b/src/PartSetPlugin/PartSetPlugin_Plugin.h new file mode 100644 index 000000000..ff577f79a --- /dev/null +++ b/src/PartSetPlugin/PartSetPlugin_Plugin.h @@ -0,0 +1,23 @@ +// File: PartSetPlugin_Plugin.hxx +// Created: 31 Mar 2014 +// Author: Mikhail PONIKAROV + +#ifndef PartSetPlugin_Plugin_HeaderFile +#define PartSetPlugin_Plugin_HeaderFile + + +#include "PartSetPlugin.h" +#include "ModelAPI_Plugin.h" + +class PARTSETPLUGIN_EXPORT PartSetPlugin_Plugin: public ModelAPI_Plugin +{ +public: + /// Creates the feature object of this plugin by the feature string ID + virtual boost::shared_ptr createFeature(std::string theFeatureID); + +public: + /// Is needed for python wrapping by swig + PartSetPlugin_Plugin(); +}; + +#endif diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 50208485c..16d693278 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -43,11 +43,11 @@ void XGUI_Workshop::startApplication() { initMenu(); //Initialize event listening - Event_Loop* aLoop = Event_Loop::Loop(); - Event_ID aFeatureId = aLoop->EventByName("menu_item"); - aLoop->RegisterListener(this, aFeatureId); - Event_ID aPartSetId = aLoop->EventByName("partset_module"); - aLoop->RegisterListener(this, aPartSetId); + Event_Loop* aLoop = Event_Loop::loop(); + Event_ID aFeatureId = aLoop->eventByName("RegisterFeature"); + aLoop->registerListener(this, aFeatureId); + Event_ID aPartSetId = aLoop->eventByName("partset_module"); + aLoop->registerListener(this, aPartSetId); activateModule(); myMainWindow->show(); QMdiSubWindow* aWnd = myMainWindow->viewer()->createView(); @@ -105,7 +105,7 @@ XGUI_Workbench* XGUI_Workshop::addWorkbench(const QString& theName) } //****************************************************** -void XGUI_Workshop::ProcessEvent(const Event_Message* theMessage) +void XGUI_Workshop::processEvent(const Event_Message* theMessage) { const Config_FeatureMessage* aFeatureMsg = dynamic_cast(theMessage); if (aFeatureMsg) { diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index aa115e9bd..3e021badd 100644 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -33,7 +33,7 @@ public: XGUI_Workbench* addWorkbench(const QString& theName); - virtual void ProcessEvent(const Event_Message* theMessage); + virtual void processEvent(const Event_Message* theMessage); public slots: void onNew();