CHANGED: #1471 Widget property templates are now stored in a tree. Also added some new controls to the widget property dialog.

This commit is contained in:
dfighter1985 2012-11-17 04:55:12 +01:00
parent 0d27998506
commit d47c317728
12 changed files with 496 additions and 106 deletions

View file

@ -31,6 +31,7 @@
#include "../../3rdparty/qtpropertybrowser/QtTreePropertyBrowser" #include "../../3rdparty/qtpropertybrowser/QtTreePropertyBrowser"
#include "widget_properties.h" #include "widget_properties.h"
#include "widget_info_tree.h"
#include "widget_properties_parser.h" #include "widget_properties_parser.h"
#include "widget_hierarchy.h" #include "widget_hierarchy.h"
#include "widget_serializer.h" #include "widget_serializer.h"
@ -61,14 +62,17 @@ namespace GUIEditor
viewPort = new NelGUIWidget; viewPort = new NelGUIWidget;
setCentralWidget( viewPort ); setCentralWidget( viewPort );
widgetInfoTree = new CWidgetInfoTree;
createMenus(); createMenus();
readSettings(); readSettings();
CWidgetPropParser parser; CWidgetPropParser parser;
parser.setWidgetPropMap( &widgetInfo ); parser.setWidgetPropMap( &widgetInfo );
parser.setWidgetInfoTree( widgetInfoTree );
parser.parseGUIWidgets(); parser.parseGUIWidgets();
widgetProps->setupWidgetInfo( &widgetInfo ); widgetProps->setupWidgetInfo( widgetInfoTree );
QDockWidget *dock = new QDockWidget( "Widget Hierarchy", this ); QDockWidget *dock = new QDockWidget( "Widget Hierarchy", this );
dock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea ); dock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
@ -80,7 +84,7 @@ namespace GUIEditor
dock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea ); dock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
QtTreePropertyBrowser *propBrowser = new QtTreePropertyBrowser; QtTreePropertyBrowser *propBrowser = new QtTreePropertyBrowser;
browserCtrl.setupWidgetInfo( widgetInfo ); browserCtrl.setupWidgetInfo( widgetInfoTree );
browserCtrl.setBrowser( propBrowser ); browserCtrl.setBrowser( propBrowser );
dock->setWidget( propBrowser ); dock->setWidget( propBrowser );
addDockWidget( Qt::RightDockWidgetArea, dock ); addDockWidget( Qt::RightDockWidgetArea, dock );
@ -116,6 +120,9 @@ namespace GUIEditor
// no deletion needed for these, since dockwidget owns them // no deletion needed for these, since dockwidget owns them
hierarchyView = NULL; hierarchyView = NULL;
propBrowser = NULL; propBrowser = NULL;
delete widgetInfoTree;
widgetInfoTree = NULL;
} }
QUndoStack *GUIEditorWindow::undoStack() const QUndoStack *GUIEditorWindow::undoStack() const

View file

@ -35,6 +35,7 @@ namespace GUIEditor
class ProcList; class ProcList;
class ProjectWindow; class ProjectWindow;
class NelGUIWidget; class NelGUIWidget;
class CWidgetInfoTree;
class GUIEditorWindow: public QMainWindow class GUIEditorWindow: public QMainWindow
{ {
@ -76,6 +77,8 @@ private:
ProjectWindow *projectWindow; ProjectWindow *projectWindow;
NelGUIWidget *viewPort; NelGUIWidget *viewPort;
CWidgetInfoTree *widgetInfoTree;
CPropBrowserCtrl browserCtrl; CPropBrowserCtrl browserCtrl;
QString currentProject; QString currentProject;
QString currentProjectFile; QString currentProjectFile;

View file

@ -21,6 +21,7 @@
#include "nel/gui/interface_group.h" #include "nel/gui/interface_group.h"
#include "nel/gui/widget_manager.h" #include "nel/gui/widget_manager.h"
#include <typeinfo> #include <typeinfo>
#include "widget_info_tree.h"
namespace GUIEditor namespace GUIEditor
{ {
@ -42,14 +43,18 @@ namespace GUIEditor
browser = b; browser = b;
} }
void CPropBrowserCtrl::setupWidgetInfo( const std::map< std::string, SWidgetInfo > &info ) void CPropBrowserCtrl::setupWidgetInfo( CWidgetInfoTree *tree )
{ {
widgetInfo.clear(); widgetInfo.clear();
std::map< std::string, SWidgetInfo >::const_iterator itr; std::vector< std::string > names;
for( itr = info.begin(); itr != info.end(); ++itr ) tree->getNames( names );
std::vector< std::string >::const_iterator itr;
for( itr = names.begin(); itr != names.end(); ++itr )
{ {
const SWidgetInfo &w = itr->second; CWidgetInfoTreeNode *node = tree->findNodeByName( *itr );
const SWidgetInfo &w = node->getInfo();
widgetInfo[ w.GUIName ] = w; widgetInfo[ w.GUIName ] = w;
} }
} }

View file

@ -34,6 +34,7 @@ namespace NLGUI
namespace GUIEditor namespace GUIEditor
{ {
class CWidgetInfoTree;
/// This class controls the Widget property browser widget. /// This class controls the Widget property browser widget.
/// It receives signals from the widget that draws/manages the Nel GUI widgets, and handles them. /// It receives signals from the widget that draws/manages the Nel GUI widgets, and handles them.
@ -45,7 +46,7 @@ namespace GUIEditor
CPropBrowserCtrl(); CPropBrowserCtrl();
~CPropBrowserCtrl(); ~CPropBrowserCtrl();
void setBrowser( QtTreePropertyBrowser *b ); void setBrowser( QtTreePropertyBrowser *b );
void setupWidgetInfo( const std::map< std::string, SWidgetInfo > &info ); void setupWidgetInfo( CWidgetInfoTree *tree );
void clear(); void clear();
public Q_SLOTS: public Q_SLOTS:
@ -60,9 +61,8 @@ namespace GUIEditor
QtTreePropertyBrowser *browser; QtTreePropertyBrowser *browser;
QtVariantPropertyManager *propertyMgr; QtVariantPropertyManager *propertyMgr;
std::map< std::string, SWidgetInfo > widgetInfo;
std::string currentElement; std::string currentElement;
std::map< std::string, SWidgetInfo > widgetInfo;
}; };
} }

View file

@ -56,6 +56,25 @@ namespace GUIEditor
resolved = false; resolved = false;
isAbstract = true; isAbstract = true;
} }
~SWidgetInfo()
{
resolved = false;
isAbstract = false;
}
/// Find a property by it's name
std::vector< SPropEntry >::iterator findProp( const std::string &name )
{
std::vector< SPropEntry >::iterator itr = props.begin();
while( itr != props.end() )
{
if( itr->propName == name )
break;
++itr;
}
return itr;
}
}; };
} }

View file

@ -0,0 +1,94 @@
// Object Viewer Qt GUI Editor plugin <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef WIDGET_INFO_TREE_H
#define WIDGET_INFO_TREE_H
#include "widget_info_tree_node.h"
#include "nel/misc/debug.h"
namespace GUIEditor
{
class CWidgetInfoTree
{
public:
CWidgetInfoTree()
{
root = NULL;
}
~CWidgetInfoTree()
{
delete root;
root = NULL;
}
/// Find a node by it's name
CWidgetInfoTreeNode* findNodeByName( const std::string &name )
{
if( root == NULL )
return NULL;
return root->findNodeByName( name );
}
void addRootNode( SWidgetInfo &info )
{
nlassert( root == NULL );
root = CWidgetInfoTreeNode::create( info );
}
/// Add a new node as a child to it's ancestor
bool addNode( SWidgetInfo &info )
{
CWidgetInfoTreeNode *node = findNodeByName( info.ancestor );
if( node == NULL )
return false;
else
node->addChild( info );
return true;
}
/// Finds a node and removes it
bool removeNode( SWidgetInfo *info )
{
CWidgetInfoTreeNode *node = findNodeByName( info->name );
if( node == NULL )
return false;
if( node == root )
root = NULL;
if( node->getParent() != NULL )
node->getParent()->removeChildByNameND( node->getInfo().name );
delete node;
return true;
}
/// Get the node names and put them into the vector
void getNames( std::vector< std::string > &v ) const
{
if( root == NULL )
return;
root->getNames( v );
}
private:
CWidgetInfoTreeNode *root;
};
}
#endif

View file

@ -0,0 +1,182 @@
// Object Viewer Qt GUI Editor plugin <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef WIDGET_INFO_TREE_NODE
#define WIDGET_INFO_TREE_NODE
#include "widget_info.h"
namespace GUIEditor
{
/// Widget Tree Info Node
class CWidgetInfoTreeNode
{
public:
CWidgetInfoTreeNode( SWidgetInfo &info )
{
this->info = info;
parent = NULL;
children.clear();
}
~CWidgetInfoTreeNode()
{
removeChildren();
parent = NULL;
}
/// Set the parent of this node
void setParent( CWidgetInfoTreeNode *newParent )
{
parent = newParent;
}
/// Returns the parent of this node
CWidgetInfoTreeNode* getParent() const
{
return parent;
}
/// Create a new node
static CWidgetInfoTreeNode* create( SWidgetInfo &info )
{
return new CWidgetInfoTreeNode( info );
}
/// Get the WidgetInfo of this node
SWidgetInfo& getInfo()
{
return info;
}
/// Add a new child node
void addChild( SWidgetInfo &info )
{
CWidgetInfoTreeNode *node = CWidgetInfoTreeNode::create( info );
node->setParent( this );
children.push_back( node );
// copy the properties to the child, since they inherit them
for( std::vector< SPropEntry >::const_iterator itr = this->info.props.begin(); itr != this->info.props.end(); ++itr )
{
node->addProperty( *itr );
}
}
/// Remove child by name
bool removeChildByName( const std::string &name )
{
for( std::vector< CWidgetInfoTreeNode* >::const_iterator itr = children.begin(); itr != children.end(); ++itr )
{
if( ( *itr )->getInfo().name == name )
{
children.erase( itr );
delete ( *itr );
return true;
}
}
return false;
}
/// Remove child by name, but don't delete the child
bool removeChildByNameND( const std::string &name )
{
for( std::vector< CWidgetInfoTreeNode* >::const_iterator itr = children.begin(); itr != children.end(); ++itr )
{
if( ( *itr )->getInfo().name == name )
{
children.erase( itr );
return true;
}
}
return false;
}
/// Remove child by ancestor's name
bool removeChildByAncestor( const std::string &ancestor )
{
for( std::vector< CWidgetInfoTreeNode* >::const_iterator itr = children.begin(); itr != children.end(); ++itr )
{
if( ( *itr )->getInfo().ancestor == ancestor )
{
children.erase( itr );
delete ( *itr );
return true;
}
}
return false;
}
/// Remove all children
void removeChildren()
{
std::vector< CWidgetInfoTreeNode* >::iterator itr = children.begin();
while( itr != children.end() )
{
CWidgetInfoTreeNode *node = *itr;
++itr;
delete node;
}
children.clear();
}
/// Add new property to the node
void addProperty( const SPropEntry &prop )
{
info.props.push_back( prop );
}
/// Find the node by it's name and then return a pointer to it
CWidgetInfoTreeNode* findNodeByName( const std::string &name )
{
if( info.name == name )
return this;
CWidgetInfoTreeNode *node = NULL;
for( std::vector< CWidgetInfoTreeNode* >::iterator itr = children.begin(); itr != children.end(); ++itr )
{
node = ( *itr )->findNodeByName( name );
if( node != NULL )
return node;
}
return NULL;
}
/// Get the node names and put them into the vector
void getNames( std::vector< std::string > &v ) const
{
v.push_back( info.name );
for( std::vector< CWidgetInfoTreeNode* >::const_iterator itr = children.begin(); itr != children.end(); ++itr )
( *itr )->getNames( v );
}
private:
SWidgetInfo info;
CWidgetInfoTreeNode *parent;
std::vector< CWidgetInfoTreeNode* > children;
};
}
#endif

View file

@ -15,32 +15,34 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "widget_properties.h" #include "widget_properties.h"
#include "widget_info_tree.h"
#include <qmessagebox.h>
namespace GUIEditor{ namespace GUIEditor{
CWidgetProperties::CWidgetProperties( QWidget *parent ) : CWidgetProperties::CWidgetProperties( QWidget *parent ) :
QWidget( parent ) QWidget( parent )
{ {
setupUi( this ); setupUi( this );
connect( closeButton, SIGNAL( clicked(bool) ), this, SLOT( hide() ) ); connect( rmWButton, SIGNAL( clicked( bool ) ), this, SLOT( onRemoveWButtonClicked() ) );
connect( rmPButton, SIGNAL( clicked( bool ) ), this, SLOT( onRemovePButtonClicked() ) );
} }
CWidgetProperties::~CWidgetProperties() CWidgetProperties::~CWidgetProperties()
{ {
} }
void CWidgetProperties::setupWidgetInfo( std::map< std::string, SWidgetInfo > *info ) void CWidgetProperties::setupWidgetInfo( CWidgetInfoTree *tree )
{ {
widgetInfo = info; this->tree = tree;
for( std::map< std::string, SWidgetInfo >::iterator itr = info->begin(); itr != info->end(); ++itr ){ buildWidgetList();
widgetList->addItem( itr->first.c_str() );
}
onListSelectionChanged( 0 ); onListSelectionChanged( 0 );
connect( widgetList, SIGNAL( currentRowChanged( int ) ), this, SLOT( onListSelectionChanged( int ) ) ); connect( widgetList, SIGNAL( currentRowChanged( int ) ), this, SLOT( onListSelectionChanged( int ) ) );
} }
void CWidgetProperties::onListSelectionChanged( int i ) void CWidgetProperties::onListSelectionChanged( int i )
{ {
if( i < 0 )
return;
if( i >= widgetList->count() ) if( i >= widgetList->count() )
return; return;
@ -48,18 +50,82 @@ namespace GUIEditor{
setPropsOf( item->text().toStdString().c_str() ); setPropsOf( item->text().toStdString().c_str() );
} }
void CWidgetProperties::onRemoveWButtonClicked()
{
if( widgetList->count() == 0 )
return;
QString widgetName = widgetList->currentItem()->text();
int reply = QMessageBox::question( this,
tr( "Removing a widget" ),
tr( "Are you sure you want to remove %1?" ).arg( widgetName ),
QMessageBox::Yes | QMessageBox::Cancel
);
if( reply != QMessageBox::Yes )
return;
/*
Remove the damned thing here
*/
buildWidgetList();
}
void CWidgetProperties::onRemovePButtonClicked()
{
QTreeWidgetItem *item = widgetPropTree->currentItem();
CWidgetInfoTreeNode *node = tree->findNodeByName( widgetList->currentItem()->text().toStdString() );
if( ( item == NULL ) || ( node == NULL ) )
return;
std::string name = item->text( 0 ).toStdString();
std::vector< SPropEntry >::const_iterator itr = node->getInfo().findProp( name );
if( itr == node->getInfo().props.end() )
return;
int reply = QMessageBox::question( this,
tr( "Removing a property" ),
tr( "Are you sure you want to remove" ).arg( QString( name.c_str() ) ),
QMessageBox::Yes | QMessageBox::Cancel
);
if( reply != QMessageBox::Yes )
return;
/*
Remove the damned thing here
*/
onListSelectionChanged( widgetList->currentRow() );
}
void CWidgetProperties::buildWidgetList()
{
widgetList->clear();
std::vector< std::string > widgetNames;
tree->getNames( widgetNames );
std::sort( widgetNames.begin(), widgetNames.end() );
for( std::vector< std::string >::const_iterator itr = widgetNames.begin(); itr != widgetNames.end(); ++itr )
widgetList->addItem( itr->c_str() );
widgetList->setCurrentRow( 0 );
}
void CWidgetProperties::setPropsOf( const char *name ) void CWidgetProperties::setPropsOf( const char *name )
{ {
std::map< std::string, SWidgetInfo >::iterator itr = CWidgetInfoTreeNode *node = tree->findNodeByName( name );
widgetInfo->find( name ); if( node == NULL )
if( itr == widgetInfo->end() )
return; return;
widgetPropTree->clear(); widgetPropTree->clear();
std::vector< SPropEntry > &v = itr->second.props; const std::vector< SPropEntry > &v = node->getInfo().props;
for( std::vector< SPropEntry >::iterator itr2 = v.begin(); itr2 != v.end(); ++itr2 ) for( std::vector< SPropEntry >::const_iterator itr2 = v.begin(); itr2 != v.end(); ++itr2 )
{ {
SPropEntry e = *itr2; SPropEntry e = *itr2;
QTreeWidgetItem *item = new QTreeWidgetItem; QTreeWidgetItem *item = new QTreeWidgetItem;
@ -69,6 +135,5 @@ namespace GUIEditor{
widgetPropTree->addTopLevelItem( item ); widgetPropTree->addTopLevelItem( item );
} }
} }
} }

View file

@ -26,6 +26,8 @@
namespace GUIEditor namespace GUIEditor
{ {
class CWidgetInfoTree;
class CWidgetProperties : public QWidget, public Ui::WidgetProperties class CWidgetProperties : public QWidget, public Ui::WidgetProperties
{ {
Q_OBJECT Q_OBJECT
@ -33,14 +35,25 @@ namespace GUIEditor
public: public:
CWidgetProperties( QWidget *parent = NULL ); CWidgetProperties( QWidget *parent = NULL );
~CWidgetProperties(); ~CWidgetProperties();
void setupWidgetInfo( std::map< std::string, SWidgetInfo > *info ); void setupWidgetInfo( CWidgetInfoTree *tree );
private Q_SLOTS: private Q_SLOTS:
void onListSelectionChanged( int i ); void onListSelectionChanged( int i );
/// Removes widget from the list
void onRemoveWButtonClicked();
/// Removes widget property from the list
void onRemovePButtonClicked();
private: private:
/// Builds the widget list
void buildWidgetList();
/// Builds the property list for the currently selected widget
void setPropsOf( const char *name ); void setPropsOf( const char *name );
std::map< std::string, SWidgetInfo > *widgetInfo;
CWidgetInfoTree *tree;
}; };
} }

View file

@ -6,15 +6,15 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>618</width> <width>703</width>
<height>308</height> <height>302</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Widget Properties</string> <string>Widget Properties</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QGridLayout" name="gridLayout">
<item> <item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QListWidget" name="widgetList"/> <widget class="QListWidget" name="widgetList"/>
@ -40,38 +40,37 @@
</item> </item>
</layout> </layout>
</item> </item>
<item> <item row="1" column="0">
<spacer name="verticalSpacer"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>56</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
<spacer name="horizontalSpacer"> <widget class="QPushButton" name="addWButton">
<property name="orientation"> <property name="text">
<enum>Qt::Horizontal</enum> <string>Add</string>
</property> </property>
<property name="sizeHint" stdset="0"> </widget>
<size>
<width>428</width>
<height>20</height>
</size>
</property>
</spacer>
</item> </item>
<item> <item>
<widget class="QPushButton" name="closeButton"> <widget class="QPushButton" name="rmWButton">
<property name="text"> <property name="text">
<string>Close</string> <string>Remove</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QPushButton" name="addPButton">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="rmPButton">
<property name="text">
<string>Remove</string>
</property> </property>
</widget> </widget>
</item> </item>

View file

@ -19,11 +19,21 @@
#include <QDir> #include <QDir>
#include <QStringList> #include <QStringList>
#include "nel/misc/debug.h" #include "nel/misc/debug.h"
#include "widget_info_tree.h"
using namespace NLMISC; using namespace NLMISC;
namespace GUIEditor namespace GUIEditor
{ {
CWidgetPropParser::CWidgetPropParser()
{
}
CWidgetPropParser::~CWidgetPropParser()
{
widgetInfoTree = NULL;
}
void CWidgetPropParser::parseGUIWidgets() void CWidgetPropParser::parseGUIWidgets()
{ {
QDir d( "widgets" ); QDir d( "widgets" );
@ -47,7 +57,7 @@ namespace GUIEditor
while( itr.hasNext() ) while( itr.hasNext() )
parseGUIWidget( "widgets/" + itr.next() ); parseGUIWidget( "widgets/" + itr.next() );
resolveInheritance(); buildWidgetInfoTree();
widgetInfo = NULL; widgetInfo = NULL;
} }
@ -209,61 +219,48 @@ namespace GUIEditor
} }
} }
bool propCompare( const SPropEntry &left, const SPropEntry &right ) void CWidgetPropParser::buildWidgetInfoTree()
{
return left.propName < right.propName;
}
void CWidgetPropParser::resolveInheritance()
{ {
// First find the root node
// It is the one which has no ancestor
SWidgetInfo *info = NULL;
for( std::map< std::string, SWidgetInfo >::iterator itr = widgetInfo->begin(); itr != widgetInfo->end(); ++itr ) for( std::map< std::string, SWidgetInfo >::iterator itr = widgetInfo->begin(); itr != widgetInfo->end(); ++itr )
{ {
resolveInheritanceFor( itr->first ); if( itr->second.ancestor.empty() )
std::sort( itr->second.props.begin(), itr->second.props.end(), propCompare ); {
info = &( itr->second );
break;
}
} }
}
void CWidgetPropParser::resolveInheritanceFor( const std::string name ) // No root node, cannot continue!
{ if( info == NULL )
if( name.empty() )
return; return;
std::map< std::string, SWidgetInfo >::iterator itr = widgetInfoTree->addRootNode( *info );
widgetInfo->find( name ); info->resolved = true;
if( itr == widgetInfo->end() )
return;
SWidgetInfo *info = &(itr->second);
if( info->resolved )
return;
if( info->ancestor.empty() )
return;
std::vector< SPropEntry > &props = info->props;
SWidgetInfo *info2 = info;
// Now add the rest of the widgets
bool added = false;
do do
{ {
if( info2->ancestor.empty() ) added = false;
break;
std::map< std::string, SWidgetInfo >::iterator itr2 =
widgetInfo->find( info2->ancestor );
if( itr2 == widgetInfo->end() )
break;
info2 = &( itr2->second ); for( std::map< std::string, SWidgetInfo >::iterator itr = widgetInfo->begin(); itr != widgetInfo->end(); ++itr )
{
for( std::vector< SPropEntry >::iterator propItr = info2->props.begin(); propItr != info2->props.end(); ++propItr ) // Skip if already added
props.push_back( *propItr ); if( itr->second.resolved )
continue;
// Try to add it, if successful, mark it
if( widgetInfoTree->addNode( itr->second ) )
{
itr->second.resolved = true;
added = true;
}
}
} }
while( !info2->resolved ); while( added );
info->resolved = true;
} }
} }

View file

@ -26,14 +26,18 @@
namespace GUIEditor namespace GUIEditor
{ {
class CWidgetInfoTree;
/// Parser for the widget properties XML files /// Parser for the widget properties XML files
class CWidgetPropParser class CWidgetPropParser
{ {
public: public:
CWidgetPropParser(){} CWidgetPropParser();
~CWidgetPropParser(){} ~CWidgetPropParser();
void setWidgetPropMap( std::map< std::string, SWidgetInfo > *info ){ widgetInfo = info; } void setWidgetPropMap( std::map< std::string, SWidgetInfo > *info ){ widgetInfo = info; }
void setWidgetInfoTree( CWidgetInfoTree *tree ){ widgetInfoTree = tree; }
/// Parse the GUI widget template definitions
void parseGUIWidgets(); void parseGUIWidgets();
private: private:
@ -41,10 +45,12 @@ namespace GUIEditor
void parseGUIWidgetXML( QFile &file ); void parseGUIWidgetXML( QFile &file );
QString parseGUIWidgetHeader( QXmlStreamReader &reader ); QString parseGUIWidgetHeader( QXmlStreamReader &reader );
void parseGUIWidgetProperties( QXmlStreamReader &reader, const QString &widgetName ); void parseGUIWidgetProperties( QXmlStreamReader &reader, const QString &widgetName );
void resolveInheritance();
void resolveInheritanceFor( const std::string name ); /// Build the widget info tree from the parsed data
void buildWidgetInfoTree();
std::map< std::string, SWidgetInfo > *widgetInfo; std::map< std::string, SWidgetInfo > *widgetInfo;
CWidgetInfoTree *widgetInfoTree;
}; };
} }