From 24a99a1363325ac341314c3f2e18326841940fb7 Mon Sep 17 00:00:00 2001 From: Sergey Belash Date: Thu, 20 Mar 2014 12:44:02 +0400 Subject: [PATCH] Implimentation of the Config XML Reader --- CMakeCommon/Common.cmake | 4 + CMakeCommon/XMLProcessing.cmake | 32 ++++-- CMakeLists.txt | 5 +- env.bat | 11 ++- src/Config/CMakeLists.txt | 34 +++++++ src/Config/Config.h | 18 ++++ src/Config/Config_Message.cpp | 17 ++++ src/Config/Config_Message.h | 27 ++++++ src/Config/Config_XMLReader.cpp | 167 ++++++++++++++++++++++++++++++++ src/Config/Config_XMLReader.h | 41 ++++++++ src/Config/plugin-PartSet.xml | 4 +- src/Event/CMakeLists.txt | 4 +- src/Event/Event_Listener.hxx | 2 +- src/Event/Event_Loop.cxx | 2 +- src/Event/Event_Loop.hxx | 2 +- src/Event/Event_Message.cxx | 5 + src/Event/Event_Message.hxx | 5 +- src/GeomModule/CMakeLists.txt | 13 ++- src/GeomModule/GeomModule.cpp | 33 ++----- src/GeomModule/GeomModule.h | 4 +- src/XGUI/CMakeLists.txt | 13 ++- src/XGUI/XGUI_Interfaces.h | 5 +- src/XGUI/XGUI_MainMenu.cpp | 17 +++- src/XGUI/XGUI_MainMenu.h | 3 +- src/XGUI/XGUI_Workbench.cpp | 31 +++++- src/XGUI/XGUI_Workbench.h | 5 +- src/XGUI/XGUI_Workshop.cpp | 55 +++++++++++ src/XGUI/XGUI_Workshop.h | 15 ++- 28 files changed, 506 insertions(+), 68 deletions(-) create mode 100644 src/Config/CMakeLists.txt create mode 100644 src/Config/Config.h create mode 100644 src/Config/Config_Message.cpp create mode 100644 src/Config/Config_Message.h create mode 100644 src/Config/Config_XMLReader.cpp create mode 100644 src/Config/Config_XMLReader.h diff --git a/CMakeCommon/Common.cmake b/CMakeCommon/Common.cmake index 29f6e2241..b1e5384de 100644 --- a/CMakeCommon/Common.cmake +++ b/CMakeCommon/Common.cmake @@ -6,3 +6,7 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) set(CMAKE_INCLUDE_CURRENT_DIR ON) + +IF(WIN32) + ADD_DEFINITIONS(-DWIN32 -D_WINDOWS) +ENDIF(WIN32) diff --git a/CMakeCommon/XMLProcessing.cmake b/CMakeCommon/XMLProcessing.cmake index 114371138..da2bbf47c 100644 --- a/CMakeCommon/XMLProcessing.cmake +++ b/CMakeCommon/XMLProcessing.cmake @@ -1,13 +1,25 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11) -FILE(TO_CMAKE_PATH $ENV{LIBXML2_INCLUDE_DIR} LIBXML2_INCLUDE_DIR) +SET(LIBXMLDIR $ENV{LIBXML2_DIR}) +INCLUDE_DIRECTORIES(${LIBXMLDIR}/include/libxml2) +LINK_DIRECTORIES (${LIBXMLDIR}/lib) + +SET(LIBXML2_LIBRARIES ${LIBXMLDIR}/lib/libxml2.lib) +#set(PROJECT_LIBRARIES ${PROJECT_LIBRARIES} ${LIBXMLDIR}/lib/libxml2.lib) + +#FILE(TO_CMAKE_PATH $ENV{PC_LIBXML_INCLUDEDIR} PC_LIBXML_INCLUDEDIR) +#FILE(TO_CMAKE_PATH $ENV{PC_LIBXML_INCLUDEDIR} PC_LIBXML_INCLUDEDIR) +#FILE(TO_CMAKE_PATH $ENV{PC_LIBXML_LIBDIR} PC_LIBXML_LIBDIR) +#message(STATUS "PC_LIBXML_INCLUDEDIR " ${PC_LIBXML_INCLUDEDIR}) +#message(STATUS "PC_LIBXML_LIBDIR " ${PC_LIBXML_LIBDIR}) + -FIND_PACKAGE(LibXml2 REQUIRED) -if(LIBXML2_FOUND) - message(STATUS "Found libxml2 ver. " ${LIBXML2_VERSION_STRING}) - message(STATUS "LIBXML2_LIBRARIES " ${LIBXML2_LIBRARIES}) - message(STATUS "LIBXML2_INCLUDE_DIR " ${LIBXML2_INCLUDE_DIR}) -endif(LIBXML2_FOUND) - -INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR}) -ADD_DEFINITIONS(${LIBXML2_DEFINITIONS}) +#FIND_PACKAGE(LibXml2 REQUIRED) +#if(LIBXML2_FOUND) +# message(STATUS "Found libxml2 ver. " ${LIBXML2_VERSION_STRING}) +# message(STATUS "LIBXML2_LIBRARIES " ${LIBXML2_LIBRARIES}) +# message(STATUS "LIBXML2_INCLUDE_DIR " ${LIBXML2_INCLUDE_DIR}) +#endif(LIBXML2_FOUND) + +#INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR}) +#ADD_DEFINITIONS(${LIBXML2_DEFINITIONS}) diff --git a/CMakeLists.txt b/CMakeLists.txt index d67d35f11..248e6f91a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,8 @@ INCLUDE(Common) INCLUDE(FindQt5) ADD_SUBDIRECTORY (src/Event) +ADD_SUBDIRECTORY (src/Config) #ADD_SUBDIRECTORY (src/ModelAPI) -ADD_SUBDIRECTORY (src/Model) -ADD_SUBDIRECTORY (src/XGUI) +#ADD_SUBDIRECTORY (src/Model) ADD_SUBDIRECTORY (src/GeomModule) +ADD_SUBDIRECTORY (src/XGUI) diff --git a/env.bat b/env.bat index 55814d96e..ac6d75d7c 100644 --- a/env.bat +++ b/env.bat @@ -99,13 +99,20 @@ if "%QTDIR%" == "" ( @SET PYTHON_VERSION=2.7 @REM ------------------------- +@REM ------------------------- +@REM ZLIB (for LIBXML2) +@SET PATH=%PDIR%\zlib-1.2.5\dll;%PATH% +@REM ------------------------- + @REM ------------------------- @REM LIBXML2 @SET LIBXML2_DIR=%PDIR%\libxml2-2.9.0 +@REM DO NOT rename following 3 variables, +@REM they are required by CMake "find(Libxml2)" procedure @SET LIBXML2_INCLUDE_DIR=%LIBXML2_DIR%\include\libxml2 @SET LIBXML2_LIB_DIR=%LIBXML2_DIR%\lib @SET LIBXML2_BIN_DIR=%LIBXML2_DIR%\bin -@SET PATH=LIBXML2_BIN_DIR;LIBXML2_LIB_DIR;%PATH% +@SET PATH=%LIBXML2_BIN_DIR%;%LIBXML2_LIB_DIR%;%PATH% @REM ------------------------- @REM ------------------------- @@ -113,6 +120,8 @@ if "%QTDIR%" == "" ( @SET PATH=%PDIR%\swig-2.0.9\bin;%PATH% @REM ------------------------- +@SET PATH=D:\NewGEOM\build-eclipse\bin;%PATH% + rem -------- Visual Studio -------------------- rem Detect Visual Studio (either commercial or Express edition) if "%VS100COMNTOOLS%" == "" ( diff --git a/src/Config/CMakeLists.txt b/src/Config/CMakeLists.txt new file mode 100644 index 000000000..95bcd8f53 --- /dev/null +++ b/src/Config/CMakeLists.txt @@ -0,0 +1,34 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11) + +INCLUDE(Common) +INCLUDE(XMLProcessing) + +INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/src/Event) + +SET(PROJECT_HEADERS + Config.h + Config_XMLReader.h + Config_Message.h + ) + +SET(PROJECT_SOURCES + Config_XMLReader.cpp + Config_Message.cpp +) + +SET(XML_RESOURCES + plugin-PartSet.xml + plugins.xml +) + +SET(PROJECT_LIBRARIES + Event + ${LIBXML2_LIBRARIES} +) + +ADD_DEFINITIONS(-DCONFIG_EXPORTS) +ADD_LIBRARY(Config SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS}) + +TARGET_LINK_LIBRARIES(Config ${PROJECT_LIBRARIES}) + +INSTALL(FILES ${XML_RESOURCES} DESTINATION plugins) diff --git a/src/Config/Config.h b/src/Config/Config.h new file mode 100644 index 000000000..587ac534d --- /dev/null +++ b/src/Config/Config.h @@ -0,0 +1,18 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#if defined CONFIG_EXPORTS +#if defined WIN32 +#define CONFIG_EXPORT __declspec( dllexport ) +#else +#define CONFIG_EXPORT +#endif +#else +#if defined WIN32 +#define CONFIG_EXPORT __declspec( dllimport ) +#else +#define CONFIG_EXPORT +#endif +#endif + +#endif //CONFIG_H diff --git a/src/Config/Config_Message.cpp b/src/Config/Config_Message.cpp new file mode 100644 index 000000000..ea701ffd5 --- /dev/null +++ b/src/Config/Config_Message.cpp @@ -0,0 +1,17 @@ +/* + * + */ + +#include "Config_Message.h" + +Config_FeatureMessage::Config_FeatureMessage(const Event_ID theId, const void* theParent) : + Event_Message(theId, theParent) +{ + m_group = ""; + m_id = ""; + m_text = ""; + m_tooltip = ""; + m_icon = ""; + m_keysequence = ""; +} + diff --git a/src/Config/Config_Message.h b/src/Config/Config_Message.h new file mode 100644 index 000000000..2e3d567a8 --- /dev/null +++ b/src/Config/Config_Message.h @@ -0,0 +1,27 @@ +#ifndef CONFIG_MESSAGE_H +#define CONFIG_MESSAGE_H + +#include "Config.h" + +#include +#include + +class CONFIG_EXPORT Config_FeatureMessage : public Event_Message +{ +public: + std::string m_id; + std::string m_text; + std::string m_tooltip; + std::string m_icon; + std::string m_keysequence; + + std::string m_group; + +public: + //const Event_ID theID, const void* theSender = 0 + Config_FeatureMessage(const Event_ID theId, const void* theParent = 0); + +}; + + +#endif // CONFIG_MESSAGE_H diff --git a/src/Config/Config_XMLReader.cpp b/src/Config/Config_XMLReader.cpp new file mode 100644 index 000000000..658d62478 --- /dev/null +++ b/src/Config/Config_XMLReader.cpp @@ -0,0 +1,167 @@ +/* + * Config_XMLReader.cpp + * + * Created on: Mar 14, 2014 + * Author: sbh + */ + +#include + +#include + +#include +#include +#ifdef WIN32 +//For GetModuleFileNameW +#include +#endif + +#ifdef _DEBUG +#include +#endif + +static bool IsNode(xmlNodePtr theNode, const char* theNodeName) +{ + return theNode->type == XML_ELEMENT_NODE + && !xmlStrcmp(theNode->name, (const xmlChar *) theNodeName); +} + +const static char* FEATURE_ID = "id"; +const static char* FEATURE_TEXT = "text"; +const static char* FEATURE_TOOLTIP = "tooltip"; +const static char* FEATURE_ICON = "icon"; +const static char* FEATURE_KEYSEQUENCE = "keysequence"; +const static char* FEATURE_GROUP_NAME = "name"; + +Config_XMLReader::Config_XMLReader(const std::string& theXmlFile) +{ + setDocumentPath(theXmlFile); +} + +Config_XMLReader::~Config_XMLReader() +{ +} + +std::string Config_XMLReader::documentPath() const +{ + return m_DocumentPath; +} + +void Config_XMLReader::setDocumentPath(std::string documentPath) +{ + std::string prefix; +#ifdef WIN32 + HMODULE hModule = GetModuleHandleW(NULL); + WCHAR wchar_path[MAX_PATH]; + GetModuleFileNameW(hModule, wchar_path, MAX_PATH); + char char_path[MAX_PATH]; + char DefChar = ' '; + WideCharToMultiByte(CP_ACP, 0, wchar_path, -1, char_path, MAX_PATH, &DefChar, NULL); + prefix = std::string(char_path); + //chop "bin\XGUI.exe" + unsigned found = prefix.rfind("bin"); + if(found != std::string::npos) + prefix.replace(found, prefix.length(), "plugins\\"); +#else + //TODO(sbh): Find full path to binary on linux + prefix = "../plugins/"; +#endif + m_DocumentPath = prefix + documentPath; +} + +void Config_XMLReader::readAll() +{ + import(); +} + +/* + * TODO: make virtual as beforeImport + */ +bool Config_XMLReader::import() +{ + bool result = false; + xmlDocPtr aDoc; + aDoc = xmlParseFile(m_DocumentPath.c_str()); + if(aDoc == NULL) { + #ifdef _DEBUG + std::cout << "Config_XMLReader::import: " << "Document " << m_DocumentPath + << " is not parsed successfully." << std::endl; + #endif + return result; + } + xmlNodePtr aRoot = xmlDocGetRootElement(aDoc); + if(aRoot == NULL) { + #ifdef _DEBUG + std::cout << "Config_XMLReader::import: " << "Error: empty document"; + #endif + return result; + } + xmlNodePtr aWbSec; + for(aWbSec = aRoot->xmlChildrenNode; aWbSec; aWbSec = aWbSec->next) { // searching for higher level element "workbench" + if(IsNode(aWbSec, "workbench")) { + result = importWorkbench(aWbSec); + } else { + #ifdef _DEBUG + std::cout << "Config_XMLReader::import: " + << "Found strange section, should be workbench" << std::endl; + #endif + continue; + } + } + return result; +} + +/* + * TODO(sbh): make virtual as doImport + */ +bool Config_XMLReader::importWorkbench(void* theRoot) +{ + xmlNodePtr aGroupNode = (static_cast(theRoot))->xmlChildrenNode; + Event_Loop* aEvLoop = Event_Loop::Loop(); + if(!aEvLoop) { + #ifdef _DEBUG + std::cout << "Config_XMLReader::importWorkbench: " + << "No event loop registered" << std::endl; + #endif + return false; + } + for(; aGroupNode; aGroupNode = aGroupNode->next) { // searching for record + if(!IsNode(aGroupNode, "group")) + continue; + std::string aGroupName = getProperty(aGroupNode, FEATURE_GROUP_NAME); + if(aGroupName.empty()) + continue; + xmlNodePtr aFtNode = aGroupNode->xmlChildrenNode; + for(; aFtNode; aFtNode = aFtNode->next) { + if(!IsNode(aFtNode, "feature")) + continue; + //Create feature... + Config_FeatureMessage aMessage(aEvLoop->EventByName("Feature"), this); + fillFeature(aFtNode, aMessage); + aMessage.m_group = aGroupName; + aEvLoop->Send(aMessage); + } + } + return true; +} + +void Config_XMLReader::fillFeature(void *theRoot, + Config_FeatureMessage& outFeatureMessage) +{ + outFeatureMessage.m_id = getProperty(theRoot, FEATURE_ID); + outFeatureMessage.m_text = getProperty(theRoot, FEATURE_TEXT); + outFeatureMessage.m_tooltip = getProperty(theRoot, FEATURE_TOOLTIP); + outFeatureMessage.m_icon = getProperty(theRoot, FEATURE_ICON); + outFeatureMessage.m_keysequence = getProperty(theRoot, FEATURE_KEYSEQUENCE); +} + +std::string Config_XMLReader::getProperty(void *theRoot, const char* name) +{ + std::string result = ""; + xmlNodePtr aNode = (static_cast(theRoot)); + char* aPropChars = (char*) xmlGetProp(aNode, BAD_CAST name); + if(!aPropChars || aPropChars[0] == 0) + return result; + result = std::string(aPropChars); + return result; +} diff --git a/src/Config/Config_XMLReader.h b/src/Config/Config_XMLReader.h new file mode 100644 index 000000000..25637fd49 --- /dev/null +++ b/src/Config/Config_XMLReader.h @@ -0,0 +1,41 @@ +/* + * Config_XMLReader.h + * + * Created on: Mar 14, 2014 + * Author: sbh + */ + +#ifndef CONFIG_XMLREADER_H_ +#define CONFIG_XMLREADER_H_ + +#include "Config.h" +#include "Config_Message.h" + +#include +#include + +class CONFIG_EXPORT Config_XMLReader { +public: + Config_XMLReader(const std::string& theXmlFile); + virtual ~Config_XMLReader(); + + std::string documentPath() const; + void setDocumentPath(std::string documentName); + + void readAll(); + +protected: + //! Performs the real import of the given xml file, return false if file is not found + //! or generates an algo error if file content is bad + //! \param theFile name of the imported XML file + //! \returns true if file exists and not corrupted + bool import(); + bool importWorkbench(void*); + void fillFeature(void *theRoot, Config_FeatureMessage& outFeatureMessage); + std::string getProperty(void *theRoot, const char* name); + +private: + std::string m_DocumentPath; +}; + +#endif /* CONFIG_XMLREADER_H_ */ diff --git a/src/Config/plugin-PartSet.xml b/src/Config/plugin-PartSet.xml index feca64bfc..d3d7d4cb2 100644 --- a/src/Config/plugin-PartSet.xml +++ b/src/Config/plugin-PartSet.xml @@ -1,9 +1,7 @@ - - + diff --git a/src/Event/CMakeLists.txt b/src/Event/CMakeLists.txt index 7a8af5bc4..70b6b3a6d 100644 --- a/src/Event/CMakeLists.txt +++ b/src/Event/CMakeLists.txt @@ -17,7 +17,7 @@ SET(PROJECT_SOURCES ADD_DEFINITIONS(-DEVENT_EXPORTS) ADD_LIBRARY(Event SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS}) + TARGET_LINK_LIBRARIES(Event ${PROJECT_LIBRARIES}) -INCLUDE_DIRECTORIES( -) +INSTALL(TARGETS Event DESTINATION bin) diff --git a/src/Event/Event_Listener.hxx b/src/Event/Event_Listener.hxx index f5d70ba65..8a17122d9 100644 --- a/src/Event/Event_Listener.hxx +++ b/src/Event/Event_Listener.hxx @@ -15,7 +15,7 @@ class Event_Message; * If some object wants to listen some events it must inherit * this class and register in the Loop. */ -EVENT_EXPORT class Event_Listener { +class EVENT_EXPORT Event_Listener { public: //! This method is called by loop when the event is started to process. diff --git a/src/Event/Event_Loop.cxx b/src/Event/Event_Loop.cxx index b1f22b50f..e997c8b8f 100644 --- a/src/Event/Event_Loop.cxx +++ b/src/Event/Event_Loop.cxx @@ -30,7 +30,7 @@ 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 diff --git a/src/Event/Event_Loop.hxx b/src/Event/Event_Loop.hxx index 7b6da9549..3d57ec45c 100644 --- a/src/Event/Event_Loop.hxx +++ b/src/Event/Event_Loop.hxx @@ -35,7 +35,7 @@ public: 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 diff --git a/src/Event/Event_Message.cxx b/src/Event/Event_Message.cxx index 02a018ef3..e9dc311b3 100644 --- a/src/Event/Event_Message.cxx +++ b/src/Event/Event_Message.cxx @@ -3,3 +3,8 @@ // Author: Mikhail PONIKAROV #include + +Event_Message::Event_Message(const Event_ID theID, const void* theSender) : +myID(theID), mySender((void*)theSender) +{ +} diff --git a/src/Event/Event_Message.hxx b/src/Event/Event_Message.hxx index b9abe11ce..4e5337c83 100644 --- a/src/Event/Event_Message.hxx +++ b/src/Event/Event_Message.hxx @@ -17,7 +17,7 @@ * used as an identifier (this is usefull for debugging of the events * with log files and in debugger). */ -EVENT_EXPORT class Event_ID { +class EVENT_EXPORT Event_ID { char* myID; ///< pointer to the text-identifier of the event, unique pointer for all events of such type Event_ID(char* theID) {myID = theID;} @@ -35,7 +35,7 @@ public: * \brief Message for communication between sender and listener of event. * Normally it is inherited by the higher-level */ -EVENT_EXPORT class Event_Message { +class EVENT_EXPORT Event_Message { Event_ID myID; ///< identifier of the event void* mySender; ///< the sender object @@ -43,6 +43,7 @@ public: //! Creates the message Event_Message(const Event_ID theID, const void* theSender = 0); + virtual ~Event_Message() {} //! Returns identifier of the message const Event_ID& ID() const {return myID;} diff --git a/src/GeomModule/CMakeLists.txt b/src/GeomModule/CMakeLists.txt index a27056b6f..540798c8d 100644 --- a/src/GeomModule/CMakeLists.txt +++ b/src/GeomModule/CMakeLists.txt @@ -1,5 +1,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11) +INCLUDE(Common) SET(PROJECT_HEADERS GeomModule_Defs.h @@ -18,14 +19,17 @@ SET(TEXT_RESOURCES GeomModule_msg_en.ts ) +SET(PROJECT_LIBRARIES + Config + ${Qt5Widgets_LIBRARIES} +) + QT5_ADD_RESOURCES(PROJECT_COMPILED_RESOURCES ${PROJECT_RESOURCES}) QT5_ADD_TRANSLATION(QM_RESOURCES ${TEXT_RESOURCES}) SOURCE_GROUP ("Generated Files" FILES ${PROJECT_COMPILED_RESOURCES} ${QM_RESOURCES}) SOURCE_GROUP ("Resource Files" FILES ${TEXT_RESOURCES} ${PROJECT_RESOURCES}) -ADD_DEFINITIONS(-DWIN32 -D_WINDOWS) - ADD_LIBRARY(GeomModule SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS} @@ -37,9 +41,10 @@ ADD_LIBRARY(GeomModule SHARED ADD_DEPENDENCIES(GeomModule XGUI) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/XGUI) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/Config) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/Event) # The Qt5Widgets_LIBRARIES variable also includes QtGui and QtCore -TARGET_LINK_LIBRARIES(GeomModule ${Qt5Widgets_LIBRARIES}) +TARGET_LINK_LIBRARIES(GeomModule ${PROJECT_LIBRARIES}) INSTALL(TARGETS GeomModule DESTINATION bin) -#INSTALL(FILES ${XML_RESOURCES} DESTINATION bin) diff --git a/src/GeomModule/GeomModule.cpp b/src/GeomModule/GeomModule.cpp index 6bddce9b1..f3bc0fd16 100644 --- a/src/GeomModule/GeomModule.cpp +++ b/src/GeomModule/GeomModule.cpp @@ -1,5 +1,7 @@ #include "GeomModule.h" +#include + #include #include #include @@ -25,30 +27,7 @@ GeomModule::~GeomModule() void GeomModule::createFeatures() { - IWorkbench* aPage = myWorkshop->addWorkbench("Home"); - IMenuGroup* aGroup = aPage->addGroup(); - - IFeatureMenu* aCommand = aGroup->addFeature("new_part", "Part", "Creates a new part", QIcon(":pictures/part_ico.png")); - aCommand = aGroup->addFeature("new_point", "Point", "Create a new point", QIcon(":icons/point.png")); - aCommand = aGroup->addFeature("new_axis", "Axis", "Create a new axis", QIcon(":icons/axis.png"), QKeySequence()); - aCommand = aGroup->addFeature("new_plane", "Plane", "Create a new plane", QIcon(":icons/plane.png"), QKeySequence()); - - //aGroup = aPage->addGroup(); - aCommand = aGroup->addFeature("duplicate", "Duplicate", "Duplicate selected object", QIcon(":icons/duplicate.png")); - aCommand = aGroup->addFeature("remove", "Remove", "Remove selected object", QIcon(":icons/remove.png")); - - aPage = myWorkshop->addWorkbench("Features"); - aGroup = aPage->addGroup(); - - aCommand = aGroup->addFeature("extrusion", "Extrusion", "Make extrusion", QIcon(":icons/extrusion.png")); - aCommand = aGroup->addFeature("revolution", "Revolution", "Make revolution", QIcon(":icons/revol.png")); - aCommand = aGroup->addFeature("cut", "Cut", "Make cut", QIcon(":icons/cut.png")); - aCommand = aGroup->addFeature("fusion", "Fusion", "Make fusion", QIcon(":icons/fusion.png")); - aCommand = aGroup->addFeature("common", "Common", "Make common", QIcon(":icons/common.png")); - - //aGroup = aPage->addGroup(); - aCommand = aGroup->addFeature("import", "Import", "Make import", QIcon(":icons/import.png")); - - aPage = myWorkshop->addWorkbench("Sketch"); - aPage = myWorkshop->addWorkbench("Properties"); -} \ No newline at end of file + Config_XMLReader* aReader = + new Config_XMLReader("plugin-PartSet.xml"); + aReader->readAll(); +} diff --git a/src/GeomModule/GeomModule.h b/src/GeomModule/GeomModule.h index 80c8ae501..e190a2305 100644 --- a/src/GeomModule/GeomModule.h +++ b/src/GeomModule/GeomModule.h @@ -6,6 +6,8 @@ #include +class Config_XMLReader; + class GM_EXPORT GeomModule : public IModule { public: @@ -20,4 +22,4 @@ private: IWorkshop* myWorkshop; }; -#endif \ No newline at end of file +#endif diff --git a/src/XGUI/CMakeLists.txt b/src/XGUI/CMakeLists.txt index e4521a148..56aadf140 100644 --- a/src/XGUI/CMakeLists.txt +++ b/src/XGUI/CMakeLists.txt @@ -1,10 +1,10 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11) +INCLUDE(Common) SET(CMAKE_AUTOMOC ON) SET(PROJECT_HEADERS XGUI_Command.h - XGUI_Interfaces.h XGUI_MainMenu.h XGUI_MainWindow.h XGUI_MenuGroupPanel.h @@ -38,13 +38,20 @@ SET(TEXT_RESOURCES XGUI_msg_en.ts ) +SET(PROJECT_LIBRARIES + Event + Config + ${Qt5Widgets_LIBRARIES} +) + QT5_ADD_RESOURCES(PROJECT_COMPILED_RESOURCES ${PROJECT_RESOURCES}) QT5_ADD_TRANSLATION(QM_RESOURCES ${TEXT_RESOURCES}) SOURCE_GROUP ("Generated Files" FILES ${PROJECT_AUTOMOC} ${PROJECT_COMPILED_RESOURCES} ${QM_RESOURCES}) SOURCE_GROUP ("Resource Files" FILES ${TEXT_RESOURCES} ${PROJECT_RESOURCES}) -ADD_DEFINITIONS(-DWIN32 -D_WINDOWS) +INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/src/Event) +INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/src/Config) ADD_EXECUTABLE(XGUI WIN32 ${PROJECT_SOURCES} @@ -55,7 +62,7 @@ ADD_EXECUTABLE(XGUI WIN32 ) # The Qt5Widgets_LIBRARIES variable also includes QtGui and QtCore -TARGET_LINK_LIBRARIES(XGUI ${Qt5Widgets_LIBRARIES}) +TARGET_LINK_LIBRARIES(XGUI ${PROJECT_LIBRARIES}) INSTALL(TARGETS XGUI DESTINATION bin) INSTALL(FILES ${QM_RESOURCES} DESTINATION bin) diff --git a/src/XGUI/XGUI_Interfaces.h b/src/XGUI/XGUI_Interfaces.h index d54bba43b..24b53dcd5 100644 --- a/src/XGUI/XGUI_Interfaces.h +++ b/src/XGUI/XGUI_Interfaces.h @@ -32,7 +32,8 @@ public: class IWorkbench { public: - virtual IMenuGroup* addGroup() = 0; + virtual IMenuGroup* addGroup(const QString& theName = "") = 0; + virtual IMenuGroup* findGroup(const QString& theName) = 0; }; @@ -59,4 +60,4 @@ extern "C" #define CREATE_MODULE "createModule" -#endif \ No newline at end of file +#endif diff --git a/src/XGUI/XGUI_MainMenu.cpp b/src/XGUI/XGUI_MainMenu.cpp index 0a4903bce..a19731dea 100644 --- a/src/XGUI/XGUI_MainMenu.cpp +++ b/src/XGUI/XGUI_MainMenu.cpp @@ -18,9 +18,11 @@ XGUI_MainMenu::~XGUI_MainMenu(void) { } -IWorkbench* XGUI_MainMenu::addWorkbench(QString theTitle) +IWorkbench* XGUI_MainMenu::addWorkbench(const QString& theTitle) { QDockWidget* aDoc = new QDockWidget(myDesktop); + QString workbenchObjName = theTitle + "_Workbench"; + aDoc->setObjectName(workbenchObjName); aDoc->setFeatures(QDockWidget::DockWidgetVerticalTitleBar); aDoc->setAllowedAreas(Qt::TopDockWidgetArea); aDoc->setWindowTitle(theTitle); @@ -35,11 +37,22 @@ IWorkbench* XGUI_MainMenu::addWorkbench(QString theTitle) myDesktop->tabifyDockWidget(myMenuTabs.last(), aDoc); } - myMenuTabs.append(aDoc); return aPage; } +/* + * Searches for already created workbench with given name. + */ +IWorkbench* XGUI_MainMenu::findWorkbench(const QString& theObjName) +{ + QDockWidget* aDoc = myDesktop->findChild(theObjName); + if(aDoc) { + return dynamic_cast(aDoc->widget()); + } + return NULL; +} + IMenuGroup* XGUI_MainMenu::addGroup(int thePageId) { diff --git a/src/XGUI/XGUI_MainMenu.h b/src/XGUI/XGUI_MainMenu.h index ef4dc0511..3addcdb6f 100644 --- a/src/XGUI/XGUI_MainMenu.h +++ b/src/XGUI/XGUI_MainMenu.h @@ -21,7 +21,8 @@ public: XGUI_MainMenu(XGUI_MainWindow *parent); virtual ~XGUI_MainMenu(); - IWorkbench* addWorkbench(QString theTitle); + IWorkbench* addWorkbench(const QString& theTitle); + IWorkbench* findWorkbench(const QString& theObjName); IMenuGroup* addGroup(int thePageId); diff --git a/src/XGUI/XGUI_Workbench.cpp b/src/XGUI/XGUI_Workbench.cpp index f73c693fc..ac930f076 100644 --- a/src/XGUI/XGUI_Workbench.cpp +++ b/src/XGUI/XGUI_Workbench.cpp @@ -69,14 +69,26 @@ XGUI_Workbench::XGUI_Workbench(QWidget *theParent) : } -IMenuGroup* XGUI_Workbench::addGroup() +/* + * Creates a new group in the workbench with given name. + * If no name provided it would be defined as {workbench_name}_Group_N. + */ +IMenuGroup* XGUI_Workbench::addGroup(const QString& theName) { + QString aGroupName = theName; + //Generate a group name. + if(theName.isEmpty()){ + QString aGroupName = objectName(); + aGroupName = aGroupName.replace("_Workbench", "_Group_%1"); + aGroupName = aGroupName.arg(myGroups.count()); + } if (!myLayout->isEmpty()) { int aNb = myLayout->count(); QLayoutItem* aItem = myLayout->itemAt(aNb - 1); myLayout->removeItem(aItem); } XGUI_MenuGroupPanel* aGroup = new XGUI_MenuGroupPanel(myChildWidget); + aGroup->setObjectName(aGroupName); myLayout->addWidget(aGroup); addSeparator(); myLayout->addStretch(); @@ -84,6 +96,22 @@ IMenuGroup* XGUI_Workbench::addGroup() return aGroup; } +/* + * Searches for already created group with given name. + */ +IMenuGroup* XGUI_Workbench::findGroup(const QString& theName) +{ + QString aGroupName = theName; + XGUI_MenuGroupPanel* aPanel; + foreach(aPanel, myGroups) { + if(aPanel->objectName() == theName) { + return aPanel; + } + } + return NULL; +} + + void XGUI_Workbench::addSeparator() { QFrame* aLine = new QFrame(myChildWidget); @@ -92,6 +120,7 @@ void XGUI_Workbench::addSeparator() myLayout->addWidget(aLine); } + void XGUI_Workbench::resizeEvent(QResizeEvent* theEvent) { QWidget::resizeEvent(theEvent); diff --git a/src/XGUI/XGUI_Workbench.h b/src/XGUI/XGUI_Workbench.h index 506845adb..e44b60b87 100644 --- a/src/XGUI/XGUI_Workbench.h +++ b/src/XGUI/XGUI_Workbench.h @@ -21,7 +21,8 @@ class XGUI_Workbench : public QWidget, public IWorkbench public: XGUI_Workbench(QWidget* theParent); - virtual IMenuGroup* addGroup(); + virtual IMenuGroup* addGroup(const QString& theName = ""); + virtual IMenuGroup* findGroup(const QString& theName); private slots: void onLeftScroll(); @@ -45,4 +46,4 @@ private: QPushButton* myLeftButton; }; -#endif; \ No newline at end of file +#endif; diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index b7db81cb1..b7cd63a16 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -4,9 +4,18 @@ #include "XGUI_Command.h" #include "XGUI_Tools.h" +#include +#include + #include #include #include +#ifdef _DEBUG +#include +#endif + + +#include #ifdef WIN32 #include @@ -30,6 +39,10 @@ XGUI_Workshop::~XGUI_Workshop(void) void XGUI_Workshop::startApplication() { initMenu(); + //Initialize event listening + Event_Loop* aLoop = Event_Loop::Loop(); + Event_ID aFeatureId = aLoop->EventByName("Feature"); + aLoop->RegisterListener(this, aFeatureId); activateModule(); myMainWindow->show(); } @@ -85,6 +98,48 @@ IWorkbench* XGUI_Workshop::addWorkbench(const QString& theName) return aMenuBar->addWorkbench(theName); } +//****************************************************** +void XGUI_Workshop::ProcessEvent(const Event_Message* theMessage) +{ + const Config_FeatureMessage* aMsg = + dynamic_cast( theMessage ); + if(aMsg) { + addFeature(aMsg); + return; + } + #ifdef _DEBUG + qDebug() << "XGUI_Workshop::ProcessEvent: " + << "Got message, but it's not a Config_FeatureMessage"; + #endif + +} + +void XGUI_Workshop::addFeature(const Config_FeatureMessage* theMessage) +{ + XGUI_MainMenu* aMenuBar = myMainWindow->menuObject(); + IWorkbench* aPage = aMenuBar->findWorkbench(tr( "GEN_MENU_TITLE" ) + "_Workbench"); + if(!aPage) { + #ifdef _DEBUG + qDebug() << "XGUI_Workshop::ProcessEvent: " + << "Creating a workbench " << tr( "GEN_MENU_TITLE" ); + #endif + aPage = addWorkbench(tr( "GEN_MENU_TITLE" )); + } + QString aGroupName = QString::fromStdString(theMessage->m_group); + IMenuGroup* aGroup = aPage->findGroup(aGroupName); + if(!aGroup) { + aGroup = aPage->addGroup(aGroupName); + } + IFeatureMenu* aCommand; + aCommand = aGroup->addFeature( + QString::fromStdString(theMessage->m_id), + QString::fromStdString(theMessage->m_text), + QString::fromStdString(theMessage->m_tooltip), + QIcon(theMessage->m_icon.c_str()) + //TODO(sbh): QKeySequence + ); +} + //****************************************************** void XGUI_Workshop::onExit() { diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index c941f42d0..b0471732f 100644 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -4,6 +4,9 @@ #include "XGUI_Interfaces.h" +#include +#include + #include #include #include @@ -13,7 +16,9 @@ class XGUI_MainWindow; class XGUI_Command; class XGUI_Module; -class XGUI_Workshop: public QObject, public IWorkshop +class Config_FeatureMessage; + +class XGUI_Workshop: public QObject, public Event_Listener, public IWorkshop { Q_OBJECT public: @@ -27,6 +32,8 @@ public: virtual IWorkbench* addWorkbench(const QString& theName); + virtual void ProcessEvent(const Event_Message* theMessage); + public slots: void onNew(); void onOpen(); @@ -34,6 +41,10 @@ public slots: void onSaveAs(); void onExit(); +protected: + //Event-loop processing methods: + void addFeature(const Config_FeatureMessage*); + private: void initMenu(); @@ -43,4 +54,4 @@ private: XGUI_MainWindow* myMainWindow; }; -#endif \ No newline at end of file +#endif -- 2.39.2