Config_WidgetAPI.h
Config_WidgetReader.h
Config_PointerMessage.h
+ Config_Common.h
)
SET(PROJECT_SOURCES
--- /dev/null
+/*
+ * Config_Common.h
+ *
+ * Created on: Apr 17, 2014
+ * Author: sbh
+ */
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+//>> Forward declaration of xmlNodePtr.
+typedef struct _xmlNode xmlNode;
+typedef xmlNode *xmlNodePtr;
+struct _xmlNode;
+//<<
+
+//>> Forward declaration of xmlDocPtr.
+typedef struct _xmlDoc xmlDoc;
+typedef xmlDoc *xmlDocPtr;
+struct _xmlDoc;
+//<<
+
+/*
+ * Returns true if theNode is XML ELEMENT node (not a "text" node ie).
+ */
+static bool isElementNode(xmlNodePtr theNode)
+{
+ return theNode->type == XML_ELEMENT_NODE;
+}
+
+/*
+ * Returns true if theNode is XML node with a given name.
+
+ * Please note that this function should be called with NULL last argument.
+ * In example: isNode(aNode, "type1", ["type2", ...], NULL);
+ * ", NULL" is required to use unlimited number of arguments.
+ * TODO(sbh): find a way to simplify calling this method.
+ */
+static bool isNode(xmlNodePtr theNode, const char* theNodeName, ...)
+{
+ bool result = false;
+ const xmlChar* aName = theNode->name;
+ if (!aName || !isElementNode(theNode)) {
+ return false;
+ }
+ if (!xmlStrcmp(aName, (const xmlChar *) theNodeName)) {
+ return true;
+ }
+ va_list args; // define argument list variable
+ va_start(args, theNodeName); // init list; point to last defined argument
+ while(true) {
+ char *anArg = va_arg (args, char*); // get next argument
+ if (anArg == NULL)
+ break;
+ if (!xmlStrcmp(aName, (const xmlChar *) anArg)) {
+ va_end(args); // cleanup the system stack
+ return true;
+ }
+ }
+ va_end(args); // cleanup the system stack
+ return false;
+}
+
+
+/*
+ * Every xml node has child. Even if there is no explicit
+ * child nodes libxml gives the "Text node" as child.
+ *
+ * This method checks if real child nodes exist in the
+ * given node.
+ */
+static bool hasChild(xmlNodePtr theNode)
+{
+ xmlNodePtr aNode = theNode->children;
+ for(; aNode; aNode = aNode->next) {
+ if (isElementNode(theNode)) {
+ return true;
+ }
+ }
+ return false;
+}
*/
#include <Config_Keywords.h>
+#include <Config_Common.h>
#include <Config_FeatureMessage.h>
#include <Config_FeatureReader.h>
#include <Event_Message.h>
const static char* NODE_WORKBENCH = "workbench";
const static char* NODE_GROUP = "group";
const static char* NODE_FEATURE = "feature";
-const static char* NODE_DOUBLE_WDG = "doublevalue";
+//Widgets
+const static char* WDG_DOUBLEVALUE = "doublevalue";
+//Widget containers
+const static char* WDG_GROUP = "groupbox";
+const static char* WDG_CHECK_GROUP = "check_groupbox";
+const static char* WDG_TOOLBOX = "toolbox";
+const static char* WDG_TOOLBOX_BOX = "box";
+const static char* WDG_SWITCH = "switch";
+const static char* WDG_SWITCH_CASE = "case";
+
const static char* _ID = "id";
//const static char* WORKBENCH_ID = "id";
const static char* DOUBLE_WDG_STEP = "step";
const static char* DOUBLE_WDG_DFLT = "default";
+//toolbox/switch properties
+const static char* CONTAINER_PAGE_NAME = "title";
+
+
/*
* Hardcoded xml entities of plugins.xml
*/
*/
#include <Config_Keywords.h>
+#include <Config_Common.h>
#include <Config_ModuleReader.h>
#include <Config_FeatureReader.h>
*/
#include <Config_WidgetAPI.h>
+#include <Config_Keywords.h>
+#include <Config_Common.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
Config_WidgetAPI::Config_WidgetAPI(std::string theRawXml)
{
myDoc = xmlParseDoc(BAD_CAST theRawXml.c_str());
- myCurrentNode = NULL;
+ myCurrentNode = xmlDocGetRootElement(myDoc);
}
xmlFreeDoc(myDoc);
}
-void Config_WidgetAPI::reset()
+bool Config_WidgetAPI::toNextWidget()
{
- xmlNodePtr aRoot = xmlDocGetRootElement(myDoc);
- if(aRoot) {
- myCurrentNode = aRoot->children;
+ //Skip all non-element node, stop if next node is null
+ xmlNodePtr aNextNode = myCurrentNode;
+ do {
+ aNextNode = aNextNode->next;
+ } while(aNextNode && !isElementNode(aNextNode));
+
+ if(!aNextNode) {
+ toParentWidget();
+ return false;
}
+ myCurrentNode = aNextNode;
+ return true;
}
-bool Config_WidgetAPI::nextWidget()
+bool Config_WidgetAPI::toChildWidget()
+{
+ if(myCurrentNode && hasChild(myCurrentNode)) {
+ myCurrentNode = myCurrentNode->children;
+ while(!isElementNode(myCurrentNode)) {
+ myCurrentNode = myCurrentNode->next;
+ }
+ return true;
+ }
+ return false;
+}
+
+bool Config_WidgetAPI::toParentWidget()
{
if(myCurrentNode) {
- myCurrentNode = myCurrentNode->next;
+ myCurrentNode = myCurrentNode->parent;
}
return myCurrentNode != NULL;
}
return result;
}
+bool Config_WidgetAPI::isContainerWidget()
+{
+ return isNode(myCurrentNode, WDG_GROUP, WDG_CHECK_GROUP,
+ NULL);
+}
+
+bool Config_WidgetAPI::isPagedWidget()
+{
+ return isNode(myCurrentNode, WDG_TOOLBOX, WDG_SWITCH,
+ NULL);
+}
+
std::string Config_WidgetAPI::getProperty(const char* thePropName)
{
std::string result = "";
{
return getProperty("label");
}
-
-bool Config_WidgetAPI::isNode(xmlNodePtr theNode, const char* theNodeName, ...)
-{
- bool result = false;
- const xmlChar* aName = theNode->name;
- if (!aName || theNode->type != XML_ELEMENT_NODE)
- return false;
-
- if (!xmlStrcmp(aName, (const xmlChar *) theNodeName))
- return true;
-
- va_list args; // define argument list variable
- va_start(args, theNodeName); // init list; point to last defined argument
- while(true) {
- char *anArg = va_arg (args, char*); // get next argument
- if (anArg == NULL)
- break;
- if (!xmlStrcmp(aName, (const xmlChar *) anArg)) {
- va_end(args); // cleanup the system stack
- return true;
- }
- }
- va_end(args); // cleanup the system stack
- return false;
-}
Config_WidgetAPI(std::string theRawXml);
virtual ~Config_WidgetAPI();
- void reset();
- bool nextWidget();
+ bool toNextWidget();
+ bool toChildWidget();
+ bool toParentWidget();
std::string widgetType();
+ bool isContainerWidget();
+ bool isPagedWidget();
std::string widgetId();
std::string widgetIcon();
std::string getProperty(const char* thePropName);
-protected:
- bool isNode(xmlNodePtr theNode, const char* name, ...);
-
private:
xmlDocPtr myDoc;
xmlNodePtr myCurrentNode;
#include <Config_WidgetReader.h>
#include <Config_Keywords.h>
+#include <Config_Common.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
return result;
}
-/*
- * Returns true if theNode is XML node with a given name.
- */
-bool Config_XMLReader::isNode(xmlNodePtr theNode, const char* theNodeName, ...)
-{
- bool result = false;
- const xmlChar* aName = theNode->name;
- if (!aName || theNode->type != XML_ELEMENT_NODE) {
- return false;
- }
- if (!xmlStrcmp(aName, (const xmlChar *) theNodeName)) {
- return true;
- }
- va_list args; // define argument list variable
- va_start(args, theNodeName); // init list; point to last defined argument
- while(true) {
- char *anArg = va_arg (args, char*); // get next argument
- if (anArg == NULL)
- break;
- if (!xmlStrcmp(aName, (const xmlChar *) anArg)) {
- va_end(args); // cleanup the system stack
- return true;
- }
- }
- va_end(args); // cleanup the system stack
- return false;
-}
-
-/*
- * Every xml node has child. Even if there is no explicit
- * child nodes libxml gives the "Text node" as child.
- *
- * This method checks if real child nodes exist in the
- * given node.
- */
-bool Config_XMLReader::hasChild(xmlNodePtr theNode)
-{
- xmlNodePtr aNode = theNode->children;
- for(; aNode; aNode = aNode->next) {
- if (aNode->type != XML_ELEMENT_NODE) {
- return true;
- }
- }
- return false;
-}
xmlNodePtr node(void* theNode);
std::string getProperty(xmlNodePtr theNode, const char* property);
- /*
- * Please note that this function should be called with NULL last argument.
- * In example: isNode(aNode, "type1", ["type2", ...], NULL);
- * ", NULL" is required to use unlimited number of arguments.
- * TODO(sbh): find a way to simplify calling this method.
- */
- bool isNode(xmlNodePtr theNode, const char* name, ...);
- bool hasChild(xmlNodePtr theNode);
protected:
std::string myDocumentPath;
XGUI_ObjectsBrowser.h
XGUI_DataTreeModel.h
XGUI_SelectionMgr.h
+ XGUI_SwitchWidget.h
)
SET(PROJECT_AUTOMOC
XGUI_PartDataModel.cpp
XGUI_ObjectsBrowser.cpp
XGUI_SelectionMgr.cpp
+ XGUI_SwitchWidget.cpp
)
SET(PROJECT_RESOURCES
--- /dev/null
+/*
+ * XGUI_SwitchWidget.cpp
+ *
+ * Created on: Apr 16, 2014
+ * Author: sbh
+ */
+
+#include <XGUI_SwitchWidget.h>
+
+#include <QComboBox>
+#include <QVBoxLayout>
+#include <QSpacerItem>
+
+XGUI_SwitchWidget::XGUI_SwitchWidget(QWidget* parent)
+: QFrame(parent)
+{
+ myMainLay = new QVBoxLayout(this);
+ myMainLay->setContentsMargins(2, 4, 2, 2);
+ myCombo = new QComboBox(this);
+ myCombo->hide();
+ myMainLay->addWidget(myCombo);
+ this->setFrameShape(QFrame::StyledPanel);
+ connect(myCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(setCurrentIndex(int)));
+ connect(myCombo, SIGNAL(currentIndexChanged(int)),
+ this, SIGNAL(currentPageChanged(int)));
+
+}
+
+XGUI_SwitchWidget::~XGUI_SwitchWidget()
+{
+}
+
+int XGUI_SwitchWidget::addPage(QWidget* theWidget, const QString& theName)
+{
+ return insertPage(count(), theWidget, theName);
+}
+
+int XGUI_SwitchWidget::count() const
+{
+ return myCombo->count();
+}
+
+int XGUI_SwitchWidget::currentIndex() const
+{
+ return myCombo->currentIndex();
+}
+
+QWidget* XGUI_SwitchWidget::currentWidget() const
+{
+ int idx = currentIndex();
+ return myCases[idx];
+}
+
+int XGUI_SwitchWidget::indexOf(QWidget* theWidget) const
+{
+ return myCases.indexOf(theWidget);
+}
+
+int XGUI_SwitchWidget::insertPage(int theIndex, QWidget* theWidget, const QString& theName)
+{
+ int index = theIndex < count() ? theIndex : count();
+ if(count() == 0)
+ myCombo->show();
+ myCombo->insertItem(index, theName);
+ myCases.insert(index, theWidget);
+ myMainLay->addWidget(theWidget);
+ setCurrentIndex(theIndex);
+ return index;
+}
+
+bool XGUI_SwitchWidget::isPageEnabled(int index) const
+{
+ return myCases[index]->isEnabled();
+}
+
+QString XGUI_SwitchWidget::pageText(int index) const
+{
+ return myCombo->itemText(index);
+}
+
+QString XGUI_SwitchWidget::pageToolTip(int index) const
+{
+ return myCases[index]->toolTip();
+}
+
+void XGUI_SwitchWidget::removePage(int index)
+{
+ myCombo->removeItem(index);
+ myCases.removeAt(index);
+ if (count() == 0) {
+ myCombo->hide();
+ }
+}
+
+void XGUI_SwitchWidget::setPageEnabled(int index, bool enabled)
+{
+ myCases[index]->setEnabled(enabled);
+}
+
+void XGUI_SwitchWidget::setPageName(int index, const QString& theName)
+{
+ myCombo->setItemText(index, theName);
+}
+
+void XGUI_SwitchWidget::setPageToolTip(int index, const QString& toolTip)
+{
+ myCases[index]->setToolTip(toolTip);
+}
+
+void XGUI_SwitchWidget::setCurrentIndex(int index)
+{
+ myCombo->setCurrentIndex(index);
+ refresh();
+}
+
+void XGUI_SwitchWidget::refresh()
+{
+ foreach(QWidget* eachWidget, myCases) {
+ eachWidget->setVisible(false);
+ }
+ if(currentIndex() >= myCases.count())
+ return;
+ myCases[currentIndex()]->setVisible(true);
+}
--- /dev/null
+/*
+ * XGUI_SwitchWidget.h
+ *
+ * Created on: Apr 16, 2014
+ * Author: sbh
+ */
+
+#ifndef XGUI_SWITCHWIDGET_H_
+#define XGUI_SWITCHWIDGET_H_
+
+#include <XGUI.h>
+#include <QFrame>
+
+class QComboBox;
+class QVBoxLayout;
+
+class XGUI_EXPORT XGUI_SwitchWidget: public QFrame
+{
+ Q_OBJECT
+public:
+ XGUI_SwitchWidget(QWidget* parent = NULL);
+ virtual ~XGUI_SwitchWidget();
+
+ int addPage(QWidget * theWidget, const QString & theName);
+ int count() const;
+ int currentIndex() const;
+ QWidget * currentWidget() const;
+ int indexOf(QWidget * theWidget) const;
+ int insertPage(int index, QWidget * theWidget, const QString & theName);
+ bool isPageEnabled(int index) const;
+ QString pageText(int index) const;
+ QString pageToolTip(int index) const;
+ void removePage(int index);
+ void setPageEnabled(int index, bool enabled);
+ void setPageName(int index, const QString & text);
+ void setPageToolTip(int index, const QString & toolTip);
+
+public slots:
+ void setCurrentIndex(int index);
+
+signals:
+ void currentPageChanged(int);
+
+protected:
+ void refresh();
+
+private:
+ QVBoxLayout* myMainLay;
+ QComboBox* myCombo;
+ QWidgetList myCases;
+};
+
+#endif /* XGUI_SWITCHWIDGET_H_ */
*/
#include <XGUI_WidgetFactory.h>
-#include <ModuleBase_Operation.h>
+#include <XGUI_SwitchWidget.h>
+
+#include <ModuleBase_Operation.h>
#include <Config_Keywords.h>
#include <Config_WidgetAPI.h>
#include <QMetaProperty>
#include <QLabel>
#include <QPixmap>
+#include <QGroupBox>
+#include <QToolBox>
#ifdef _DEBUG
#include <QDebug>
{
}
-void XGUI_WidgetFactory::fillWidget(QWidget* theParent)
+void XGUI_WidgetFactory::createWidget(QWidget* theParent)
{
- myWidgetApi->reset();
- if (theParent->layout()) {
- theParent->layout()->deleteLater();
- }
+ if (!myWidgetApi->toChildWidget())
+ return;
QVBoxLayout* aWidgetLay = new QVBoxLayout(theParent);
- aWidgetLay->setContentsMargins(0, 0, 0, 0);
- do {
+ aWidgetLay->setContentsMargins(2, 2, 2, 2);
+ do { //Iterate over each node
std::string aWdgType = myWidgetApi->widgetType();
- QWidget* aWidget = NULL;
- if (aWdgType == NODE_DOUBLE_WDG) {
- aWidget = doubleSpinBoxWidget();
- } else {
- #ifdef _DEBUG
- qDebug() << "XGUI_WidgetFactory::fillWidget: find bad widget type";
- #endif
- }
+ //Create a widget (doublevalue, groupbox, toolbox, etc.
+ QWidget* aWidget = createWidgetByType(aWdgType, theParent);
if (aWidget) {
aWidgetLay->addWidget(aWidget);
}
- } while(myWidgetApi->nextWidget());
+ if (myWidgetApi->isContainerWidget()) {
+ //if current widget is groupbox (container) process it's children recursively
+ QString aGroupName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
+ createWidget(aWidget);
+ QGroupBox* aGrBox = qobject_cast<QGroupBox*>(aWidget);
+ aGrBox->setTitle(aGroupName);
+ }
+ if (myWidgetApi->isPagedWidget()) {
+ //If current widget is toolbox or switch-casebox then fetch all
+ //it's pages recursively and setup into the widget.
+ myWidgetApi->toChildWidget();
+ do {
+ QString aPageName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
+ QWidget* aPage = new QWidget(aWidget);
+ createWidget(aPage);
+ if (aWdgType == WDG_SWITCH) {
+ XGUI_SwitchWidget* aSwitch = qobject_cast<XGUI_SwitchWidget*>(aWidget);
+ aSwitch->addPage(aPage, aPageName);
+ } else if (aWdgType == WDG_TOOLBOX){
+ QToolBox* aToolbox = qobject_cast<QToolBox*>(aWidget);
+ aToolbox->addItem(aPage, aPageName);
+ }
+ } while(myWidgetApi->toNextWidget());
+ }
+ } while(myWidgetApi->toNextWidget());
theParent->setLayout(aWidgetLay);
}
-QWidget* XGUI_WidgetFactory::doubleSpinBoxWidget()
+QWidget* XGUI_WidgetFactory::createWidgetByType(const std::string& theType, QWidget* theParent)
+{
+ QWidget* result = NULL;
+ if (theType == WDG_DOUBLEVALUE) {
+ result = doubleSpinBoxControl();
+ } else if (myWidgetApi->isContainerWidget() || myWidgetApi->isPagedWidget()) {
+ result = createContainer(theType, theParent);
+ }
+#ifdef _DEBUG
+ else { qDebug() << "XGUI_WidgetFactory::fillWidget: find bad widget type"; }
+#endif
+ return result;
+}
+
+QWidget* XGUI_WidgetFactory::createContainer(const std::string& theType, QWidget* theParent)
+{
+ QWidget* result = NULL;
+ if (theType == WDG_GROUP || theType == WDG_CHECK_GROUP) {
+ QGroupBox* aGroupBox = new QGroupBox(theParent);
+ aGroupBox->setCheckable(theType == WDG_CHECK_GROUP);
+ result = aGroupBox;
+ } else if (theType == WDG_TOOLBOX) {
+ result = new QToolBox(theParent);
+ } else if (theType == WDG_SWITCH) {
+ result = new XGUI_SwitchWidget(theParent);
+ } else if (theType == WDG_TOOLBOX_BOX || theType == WDG_SWITCH_CASE) {
+ result = NULL;
+ }
+#ifdef _DEBUG
+ else { qDebug() << "XGUI_WidgetFactory::fillWidget: find bad container type"; }
+#endif
+ return result;
+}
+
+QWidget* XGUI_WidgetFactory::doubleSpinBoxControl()
{
QWidget* result = new QWidget();
QHBoxLayout* aControlLay = new QHBoxLayout(result);
aControlLay->addWidget(aBox);
aControlLay->setStretch(1, 1);
result->setLayout(aControlLay);
- connectWidget(aBox, NODE_DOUBLE_WDG);
+ connectWidget(aBox, WDG_DOUBLEVALUE);
return result;
}
-bool XGUI_WidgetFactory::connectWidget(QWidget* theWidget, const QString& theType)
+bool XGUI_WidgetFactory::connectWidget(QWidget* theWidget, const QString& theType)
{
bool result = false;
- if (theType == NODE_DOUBLE_WDG) {
+ if (theType == WDG_DOUBLEVALUE) {
result = QObject::connect(theWidget, SIGNAL(valueChanged(double)),
myOperation, SLOT(storeReal(double)));
}
XGUI_WidgetFactory(ModuleBase_Operation*);
virtual ~XGUI_WidgetFactory();
- void fillWidget(QWidget* theParent);
+ void createWidget(QWidget* theParent);
protected:
- QWidget* doubleSpinBoxWidget();
-
+ //Widgets
+ QWidget* doubleSpinBoxControl();
+ QWidget* createWidgetByType(const std::string& theType, QWidget* theParent = NULL);
+ QWidget* createContainer(const std::string& theType, QWidget* theParent = NULL);
bool connectWidget(QWidget*, const QString&);
-private:
QString qs(const std::string& theStdString) const;
+private:
Config_WidgetAPI* myWidgetApi;
ModuleBase_Operation* myOperation;
+
+
};
#endif /* XGUI_WIDGETFACTORY_H_ */
qDeleteAll(aPropWidget->children());
theOperation->start();
XGUI_WidgetFactory aFactory = XGUI_WidgetFactory(theOperation);
- aFactory.fillWidget(aPropWidget);
+ aFactory.createWidget(aPropWidget);
}
void XGUI_Workshop::setCurrentOperation(ModuleBase_Operation* theOperation)