This commit is contained in:
botanic 2014-09-04 17:27:29 -07:00
commit 49370fb5a4
33 changed files with 2867 additions and 236 deletions

View file

@ -87,6 +87,8 @@ public:
// Set as a type
void setType (CFormLoader &loader, const char *filename);
void setType (TEntryType type);
// Set as a dfn
void setDfn (CFormLoader &loader, const char *filename);
@ -160,6 +162,10 @@ public:
NLMISC::CSmartPtr<CFormDfn> Parent;
};
void addEntry( const std::string &name );
void removeEntry( uint idx );
// ** IO functions
void write (xmlDocPtr root, const char *filename);

View file

@ -41,6 +41,21 @@ void warning (bool exception, const char *format, ... );
// ***************************************************************************
void CFormDfn::addEntry( const std::string &name )
{
CEntry entry;
entry.setName( name.c_str() );
Entries.push_back( entry );
}
void CFormDfn::removeEntry( uint idx )
{
std::vector< CEntry >::iterator itr = Entries.begin() + idx;
Entries.erase( itr );
}
// ***************************************************************************
void CFormDfn::write (xmlDocPtr doc, const char *filename)
{
// Save filename
@ -463,6 +478,11 @@ void CFormDfn::CEntry::setType (CFormLoader &loader, const char *filename)
Type = loader.loadType (filename);
}
void CFormDfn::CEntry::setType( TEntryType type )
{
TypeElement = type;
}
// ***************************************************************************
void CFormDfn::CEntry::setDfn (CFormLoader &loader, const char *filename)

View file

@ -18,11 +18,19 @@ SET(OVQT_PLUG_GEORGES_EDITOR_HDR georges_editor_plugin.h
expandable_headerview.h
browser_ctrl.h
browser_ctrl_pvt.h
dfn_browser_ctrl.h
georges_dfn_dialog.h
filepath_property_manager.h
typ_browser_ctrl.h
georges_typ_dialog.h
)
SET(OVQT_PLUG_GEORGES_EDITOR_UIS georges_editor_form.ui
georges_dirtree_form.ui
georges_treeview_form.ui)
georges_treeview_form.ui
georges_dfn_dialog.ui
georges_typ_dialog.ui
)
SET(OVQT_PLUGIN_GEORGES_EDITOR_RCS georges_editor.qrc)

View file

@ -1,3 +1,22 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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/>.
#include "browser_ctrl.h"
#include "3rdparty/qtpropertybrowser/qttreepropertybrowser.h"
#include "3rdparty/qtpropertybrowser/qtvariantproperty.h"
@ -17,6 +36,7 @@ QObject( browser )
connect( m_pvt, SIGNAL( arrayResized( const QString&, int ) ), this, SLOT( onArrayResized( const QString&, int ) ) );
connect( m_pvt, SIGNAL( modified() ), this, SLOT( onModified() ) );
connect( m_pvt, SIGNAL( valueChanged( const QString&, const QString& ) ), this, SLOT( onValueChanged( const QString&, const QString& ) ) );
}
BrowserCtrl::~BrowserCtrl()
@ -31,18 +51,8 @@ void BrowserCtrl::clicked( const QModelIndex &idx )
m_pvt->clear();
GeorgesQt::CFormItem *item = static_cast< GeorgesQt::CFormItem* >( idx.internalPointer() );
NLGEORGES::UFormElm &root = m_form->getRootNode();
NLGEORGES::CFormElm *rootNode = dynamic_cast< NLGEORGES::CFormElm* >( &root );
m_pvt->setRootNode( rootNode );
NLGEORGES::UFormElm *node = NULL;
bool b = false;
b = m_form->getRootNode().getNodeByName( &node, item->formName().c_str() );
if( !b || ( node == NULL ) )
return;
m_pvt->setupNode( node );
m_pvt->setupNode( item );
enableMgrConnections();
@ -53,6 +63,11 @@ void BrowserCtrl::onValueChanged( QtProperty *p, const QVariant &value )
m_pvt->onValueChanged( p, value );
}
void BrowserCtrl::onValueChanged( const QString &key, const QString &value )
{
Q_EMIT valueChanged( key, value );
}
void BrowserCtrl::onArrayResized( const QString &name, int size )
{
Q_EMIT arrayResized( name, size );

View file

@ -1,3 +1,21 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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 BROWSER_CTRL_H
#define BROWSER_CTRL_H
@ -29,9 +47,11 @@ public Q_SLOTS:
Q_SIGNALS:
void arrayResized( const QString &name, int size );
void modified();
void valueChanged( const QString &key, const QString &value );
private Q_SLOTS:
void onValueChanged( QtProperty *p, const QVariant &value );
void onValueChanged( const QString &key, const QString &value );
void onArrayResized( const QString &name, int size );
void onModified();

View file

@ -1,7 +1,28 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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/>.
#include "browser_ctrl_pvt.h"
#include "3rdparty/qtpropertybrowser/qttreepropertybrowser.h"
#include "3rdparty/qtpropertybrowser/qtvariantproperty.h"
#include <QVariant>
#include "formitem.h"
#include "nel/georges/form.h"
namespace
{
@ -26,6 +47,12 @@ namespace
return t;
}
NLGEORGES::UFormElm* getGeorgesNode( GeorgesQt::CFormItem *item )
{
NLGEORGES::UFormElm *n = NULL;
item->form()->getRootNode().getNodeByName( &n, item->formName().c_str() );
return n;
}
}
@ -34,7 +61,6 @@ QObject( parent )
{
mgr = new QtVariantPropertyManager();
factory = new QtVariantEditorFactory();
m_currentNode = NULL;
m_rootNode = NULL;
}
@ -70,19 +96,6 @@ void BrowserCtrlPvt::setupAtom( NLGEORGES::CFormElmStruct::CFormElmStructElm &el
m_browser->addProperty( p );
}
void BrowserCtrlPvt::setupArray( NLGEORGES::UFormElm *node )
{
NLGEORGES::CFormElmArray *arr = static_cast< NLGEORGES::CFormElmArray* >( node );
uint size = 0;
arr->getArraySize( size );
QString key = QObject::tr( "Array size" );
QtVariantProperty *p = mgr->addProperty( QVariant::Int, key );
p->setValue( size );
m_browser->addProperty( p );
}
void BrowserCtrlPvt::setupStruct( NLGEORGES::UFormElm *node )
{
NLGEORGES::CFormElmStruct *st = static_cast< NLGEORGES::CFormElmStruct* >( node );
@ -104,24 +117,54 @@ void BrowserCtrlPvt::setupStruct( NLGEORGES::UFormElm *node )
}
}
void BrowserCtrlPvt::setupNode( NLGEORGES::UFormElm *node )
void BrowserCtrlPvt::setupStruct( GeorgesQt::CFormItem *node )
{
if( node->isStruct() )
setupStruct( node );
else
NLGEORGES::UFormElm *n = getGeorgesNode( node );
if( n == NULL )
return;
m_currentNode.p = n;
setupStruct( n );
}
void BrowserCtrlPvt::setupArray( GeorgesQt::CFormItem *node )
{
NLGEORGES::UFormElm *n = getGeorgesNode( node );
uint size = 0;
if( n != NULL )
{
NLGEORGES::CFormElmArray *arr = static_cast< NLGEORGES::CFormElmArray* >( n );
arr->getArraySize( size );
m_currentNode.p = n;
}
QString key = QObject::tr( "Array size" );
QtVariantProperty *p = mgr->addProperty( QVariant::Int, key );
p->setValue( size );
m_browser->addProperty( p );
}
void BrowserCtrlPvt::setupNode( GeorgesQt::CFormItem *node )
{
m_currentNode.clear();
m_currentNode.name = node->formName().c_str();
m_rootNode = dynamic_cast< NLGEORGES::CFormElm* >( &(node->form()->getRootNode()) );
if( node->isArray() )
setupArray( node );
else
return;
setupStruct( node );
m_currentNode = node;
m_browser->setFactoryForManager( mgr, factory );
}
void BrowserCtrlPvt::clear()
{
m_browser->clear();
m_currentNode = NULL;
m_currentNode.clear();
}
@ -131,18 +174,63 @@ void BrowserCtrlPvt::onStructValueChanged( QtProperty *p, const QVariant &value
std::string v = value.toString().toUtf8().constData();
bool created = false;
m_currentNode->setValueByName( v.c_str(), k.c_str(), &created );
m_currentNode.p->setValueByName( v.c_str(), k.c_str(), &created );
QString key = m_currentNode.name + "." + p->propertyName();
Q_EMIT modified();
Q_EMIT valueChanged( key, value.toString() );
}
void BrowserCtrlPvt::createArray()
{
const NLGEORGES::CFormDfn *parentDfn;
const NLGEORGES::CFormDfn *nodeDfn;
uint indexDfn;
const NLGEORGES::CType *type;
NLGEORGES::UFormDfn::TEntryType entryType;
NLGEORGES::CFormElm *node;
bool created;
bool isArray;
m_rootNode->createNodeByName( m_currentNode.name.toUtf8().constData(), &parentDfn, indexDfn, &nodeDfn, &type, &node, entryType, isArray, created );
if( !created )
return;
m_currentNode.p = node;
NLGEORGES::CFormElmArray *arr = dynamic_cast< NLGEORGES::CFormElmArray* >( node );
QString idx = "[0]";
arr->createNodeByName( idx.toUtf8().constData(), &parentDfn, indexDfn, &nodeDfn, &type, &node, entryType, isArray, created );
std::string formName;
arr->getFormName( formName, NULL );
Q_EMIT arrayResized( formName.c_str(), 1 );
Q_EMIT modified();
}
void BrowserCtrlPvt::onArrayValueChanged( QtProperty *p, const QVariant &value )
{
NLGEORGES::CFormElmArray *arr = static_cast< NLGEORGES::CFormElmArray* >( m_currentNode );
// Newsize checks hacked in, because setting unsigned value type in QVariant crashes the property browser!
int newSize = value.toInt();
if( newSize < 0 )
return;
if( m_currentNode.p == NULL )
{
if( newSize != 1 )
return;
createArray();
return;
}
NLGEORGES::CFormElmArray *arr = static_cast< NLGEORGES::CFormElmArray* >( m_currentNode.p );
std::string formName;
arr->getFormName( formName, NULL );
int newSize = value.toInt();
int oldSize = arr->Elements.size();
if( newSize == oldSize )
@ -188,17 +276,26 @@ void BrowserCtrlPvt::onArrayValueChanged( QtProperty *p, const QVariant &value )
QString name = formName.c_str();
Q_EMIT arrayResized( name, newSize );
Q_EMIT modified();
if( newSize == 0 )
m_currentNode.p = NULL;
}
void BrowserCtrlPvt::onValueChanged( QtProperty *p, const QVariant &value )
{
if( m_currentNode == NULL )
if( m_currentNode.p == NULL )
{
if( m_currentNode.name.isEmpty() )
return;
if( m_currentNode->isStruct() )
onArrayValueChanged( p, value );
return;
}
if( m_currentNode.p->isStruct() )
onStructValueChanged( p, value );
else
if( m_currentNode->isArray() )
if( m_currentNode.p->isArray() )
onArrayValueChanged( p, value );
}

View file

@ -1,3 +1,21 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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 BROWSER_CTRL_PVT_H
#define BROWSER_CTRL_PVT_H
@ -10,6 +28,11 @@ namespace NLGEORGES
class CFormElmStruct;
}
namespace GeorgesQt
{
class CFormItem;
}
class QtVariantPropertyManager;
class QtVariantEditorFactory;
class QtTreePropertyBrowser;
@ -24,7 +47,7 @@ public:
~BrowserCtrlPvt();
void clear();
void setupNode( NLGEORGES::UFormElm *node );
void setupNode( GeorgesQt::CFormItem *node );
void onValueChanged( QtProperty *p, const QVariant &value );
QtVariantPropertyManager* manager() const{ return mgr; }
@ -34,21 +57,44 @@ public:
Q_SIGNALS:
void arrayResized( const QString &name, int size );
void modified();
void valueChanged( const QString &key, const QString &value );
private:
void setupStruct( NLGEORGES::UFormElm *node );
void setupArray( NLGEORGES::UFormElm *node );
void setupAtom( NLGEORGES::CFormElmStruct::CFormElmStructElm &elm );
void setupStruct( GeorgesQt::CFormItem *node );
void setupArray( GeorgesQt::CFormItem *node );
void onStructValueChanged( QtProperty *p, const QVariant &value );
void onArrayValueChanged( QtProperty *p, const QVariant &value );
void createArray();
QtVariantPropertyManager *mgr;
QtVariantEditorFactory *factory;
QtTreePropertyBrowser *m_browser;
NLGEORGES::UFormElm *m_currentNode;
QString m_currentNodeName;
NLGEORGES::CFormElm *m_rootNode;
struct CurrentNode
{
CurrentNode()
{
clear();
}
void clear()
{
p = NULL;
name = "";
}
QString name;
NLGEORGES::UFormElm *p;
};
CurrentNode m_currentNode;
};
#endif

View file

@ -0,0 +1,271 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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/>.
#include "dfn_browser_ctrl.h"
#include "3rdparty/qtpropertybrowser/qttreepropertybrowser.h"
#include "3rdparty/qtpropertybrowser/qtvariantproperty.h"
#include "3rdparty/qtpropertybrowser/qteditorfactory.h"
#include "3rdparty/qtpropertybrowser/qtpropertymanager.h"
#include "filepath_property_manager.h"
#include "nel/georges/form_dfn.h"
namespace
{
enum EntryEnum
{
ENTRY_TYPE,
ENTRY_DFN,
ENTRY_VIRTUAL_DFN,
ENTRY_TYPE_ARRAY,
ENTRY_DFN_ARRAY
};
QString enumToString( int value )
{
QString s;
switch( value )
{
case ENTRY_TYPE: s = "type"; break;
case ENTRY_DFN: s = "dfn"; break;
case ENTRY_VIRTUAL_DFN: s = "virtual dfn"; break;
case ENTRY_TYPE_ARRAY: s = "type array"; break;
case ENTRY_DFN_ARRAY: s = "dfn array"; break;
}
return s;
}
NLGEORGES::UFormDfn::TEntryType enumToEntry( int value )
{
NLGEORGES::UFormDfn::TEntryType entry = NLGEORGES::UFormDfn::EntryType;
switch( value )
{
case ENTRY_TYPE: entry = NLGEORGES::UFormDfn::EntryType; break;
case ENTRY_DFN: entry = NLGEORGES::UFormDfn::EntryDfn; break;
case ENTRY_VIRTUAL_DFN: entry = NLGEORGES::UFormDfn::EntryVirtualDfn; break;
case ENTRY_TYPE_ARRAY: entry = NLGEORGES::UFormDfn::EntryType; break;
case ENTRY_DFN_ARRAY: entry = NLGEORGES::UFormDfn::EntryDfn; break;
}
return entry;
}
bool enumToArray( int value )
{
bool isArray = false;
switch( value )
{
case ENTRY_TYPE_ARRAY:
case ENTRY_DFN_ARRAY:
isArray = true;
break;
}
return isArray;
}
int entryToEnum( const NLGEORGES::UFormDfn::TEntryType &type, bool isArray )
{
int id = 0;
switch( type )
{
case NLGEORGES::UFormDfn::EntryType:
if( isArray )
id = ENTRY_TYPE_ARRAY;
else
id = ENTRY_TYPE;
break;
case NLGEORGES::UFormDfn::EntryDfn:
if( isArray )
id = ENTRY_DFN_ARRAY;
else
id = ENTRY_DFN;
break;
case NLGEORGES::UFormDfn::EntryVirtualDfn:
id = ENTRY_VIRTUAL_DFN;
break;
}
return id;
}
}
DFNBrowserCtrl::DFNBrowserCtrl( QObject *parent ) :
QObject( parent )
{
m_browser = NULL;
m_dfn = NULL;
m_manager = new QtVariantPropertyManager();
m_factory = new QtVariantEditorFactory();
m_enumMgr = new QtEnumPropertyManager();
m_enumFactory = new QtEnumEditorFactory();
m_fileMgr = new FileManager();
m_fileFactory = new FileEditFactory();
m_idx = -1;
}
DFNBrowserCtrl::~DFNBrowserCtrl()
{
m_browser = NULL;
m_dfn = NULL;
delete m_manager;
m_manager = NULL;
delete m_factory;
m_factory = NULL;
delete m_enumMgr;
m_enumMgr = NULL;
delete m_enumFactory;
m_enumFactory = NULL;
delete m_fileMgr;
m_fileMgr = NULL;
delete m_fileFactory;
m_fileFactory = NULL;
}
void DFNBrowserCtrl::onElementSelected( int idx )
{
NLGEORGES::CFormDfn::CEntry &entry = m_dfn->getEntry( idx );
m_idx = idx;
disconnectManagers();
m_browser->clear();
m_browser->setFactoryForManager( m_manager, m_factory );
m_browser->setFactoryForManager( m_enumMgr, m_enumFactory );
m_browser->setFactoryForManager( m_fileMgr, m_fileFactory );
QtVariantProperty *p = NULL;
QtProperty *prop = NULL;
p = m_manager->addProperty( QVariant::String, "name" );
p->setValue( entry.getName().c_str() );
m_browser->addProperty( p );
NLGEORGES::UFormDfn::TEntryType et = entry.getType();
bool isArray = entry.getArrayFlag();
QStringList options;
options.push_back( "Type" );
options.push_back( "DFN" );
options.push_back( "Virtual DFN" );
options.push_back( "Type Array" );
options.push_back( "DFN Array" );
int enumId = entryToEnum( et, isArray );
prop = m_enumMgr->addProperty( "type" );
m_enumMgr->setEnumNames( prop, options );
m_enumMgr->setValue( prop, enumId );
m_browser->addProperty( prop );
prop = m_fileMgr->addProperty( "value" );
m_fileMgr->setValue( prop, entry.getFilename().c_str() );
m_browser->addProperty( prop );
p = m_manager->addProperty( QVariant::String, "default" );
p->setValue( entry.getDefault().c_str() );
m_browser->addProperty( p );
p = m_manager->addProperty( QVariant::String, "extension" );
p->setValue( entry.getFilenameExt().c_str() );
m_browser->addProperty( p );
connectManagers();
}
void DFNBrowserCtrl::onVariantValueChanged( QtProperty *p, const QVariant &v )
{
NLGEORGES::CFormDfn::CEntry &entry = m_dfn->getEntry( m_idx );
QString key = p->propertyName();
std::string value = v.toString().toUtf8().constData();
if( key == "name" )
{
entry.setName( value.c_str() );
}
else
if( key == "default" )
{
entry.setDefault( value.c_str() );
}
else
if( key == "extension" )
{
entry.setFilenameExt( value.c_str() );
}
else
return;
Q_EMIT valueChanged( key, v.toString() );
}
void DFNBrowserCtrl::onEnumValueChanged( QtProperty *p, int v )
{
NLGEORGES::UFormDfn::TEntryType tentry = enumToEntry( v );
bool isArray = enumToArray( v );
NLGEORGES::CFormDfn::CEntry &entry = m_dfn->getEntry( m_idx );
entry.setArrayFlag( isArray );
entry.setType( tentry );
QString value = enumToString( v );
Q_EMIT valueChanged( p->propertyName(), value );
}
void DFNBrowserCtrl::onFileValueChanged( QtProperty *p, const QString &v )
{
NLGEORGES::CFormDfn::CEntry &entry = m_dfn->getEntry( m_idx );
entry.setFilename( v.toUtf8().constData() );
Q_EMIT valueChanged( p->propertyName(), v );
}
void DFNBrowserCtrl::connectManagers()
{
connect( m_manager, SIGNAL( valueChanged( QtProperty*, const QVariant& ) ), this, SLOT( onVariantValueChanged( QtProperty*, const QVariant& ) ) );
connect( m_enumMgr, SIGNAL( valueChanged( QtProperty*, int ) ), this, SLOT( onEnumValueChanged( QtProperty*, int ) ) );
connect( m_fileMgr, SIGNAL( valueChanged( QtProperty*, const QString& ) ), this, SLOT( onFileValueChanged( QtProperty*, const QString& ) ) );
}
void DFNBrowserCtrl::disconnectManagers()
{
disconnect( m_manager, SIGNAL( valueChanged( QtProperty*, const QVariant& ) ), this, SLOT( onVariantValueChanged( QtProperty*, const QVariant& ) ) );
disconnect( m_enumMgr, SIGNAL( valueChanged( QtProperty*, int ) ), this, SLOT( onEnumValueChanged( QtProperty*, int ) ) );
disconnect( m_fileMgr, SIGNAL( valueChanged( QtProperty*, const QString& ) ), this, SLOT( onFileValueChanged( QtProperty*, const QString& ) ) );
}

View file

@ -0,0 +1,80 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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 DFN_BROWSER_CTRL
#define DFN_BROWSER_CTRL
#include <QObject>
namespace NLGEORGES
{
class CFormDfn;
}
class QtVariantPropertyManager;
class QtVariantEditorFactory;
class QtTreePropertyBrowser;
class QVariant;
class QtProperty;
class QtEnumPropertyManager;
class QtEnumEditorFactory;
class FileManager;
class FileEditFactory;
class DFNBrowserCtrl : public QObject
{
Q_OBJECT
public:
DFNBrowserCtrl( QObject *parent = NULL );
~DFNBrowserCtrl();
void setBrowser( QtTreePropertyBrowser *browser ){ m_browser = browser; }
void setDFN( NLGEORGES::CFormDfn *dfn ){ m_dfn = dfn; }
void onElementSelected( int idx );
Q_SIGNALS:
void valueChanged( const QString &key, const QString &value );
private Q_SLOTS:
void onFileValueChanged( QtProperty *p, const QString &v );
void onVariantValueChanged( QtProperty *p, const QVariant &v );
void onEnumValueChanged( QtProperty *p, int v );
private:
void connectManagers();
void disconnectManagers();
QtTreePropertyBrowser *m_browser;
NLGEORGES::CFormDfn *m_dfn;
QtVariantPropertyManager *m_manager;
QtVariantEditorFactory *m_factory;
QtEnumPropertyManager *m_enumMgr;
QtEnumEditorFactory *m_enumFactory;
FileManager *m_fileMgr;
FileEditFactory *m_fileFactory;
int m_idx;
};
#endif

View file

@ -0,0 +1,320 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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/>.
#include "filepath_property_manager.h"
#include <QLineEdit>
#include <QToolButton>
#include <QHBoxLayout>
#include <QFileDialog>
#include <QMap>
///////////////////////////////////////////////////////////////////// Manager ////////////////////////////////////////////////////////////////////
class FileManagerPvt
{
public:
QMap< const QtProperty*, QString > values;
};
FileManager::FileManager( QObject *parent ) :
QtAbstractPropertyManager( parent )
{
m_pvt = new FileManagerPvt();
}
FileManager::~FileManager()
{
delete m_pvt;
m_pvt = NULL;
}
QString FileManager::value( const QtProperty *p ) const
{
QMap< const QtProperty*, QString >::const_iterator itr = m_pvt->values.find( p );
if( itr == m_pvt->values.end() )
return "";
else
return itr.value();
}
void FileManager::setValue( QtProperty *p, const QString &v )
{
if( !m_pvt->values.contains( p ) )
return;
if( m_pvt->values[ p ] == v )
return;
m_pvt->values[ p ] = v;
Q_EMIT propertyChanged( p );
Q_EMIT valueChanged( p, v );
}
bool FileManager::hasValue( const QtProperty *p ) const
{
if( m_pvt->values.contains( p ) )
return true;
else
return false;
}
QString FileManager::valueText( const QtProperty *p ) const
{
return value( p );
}
void FileManager::initializeProperty( QtProperty *p )
{
if( m_pvt->values.contains( p ) )
return;
m_pvt->values[ p ] = "";
}
void FileManager::uninitializeProperty( QtProperty *p )
{
m_pvt->values.remove( p );
}
///////////////////////////////////////////////////////////////// Factory ///////////////////////////////////////////////////////////////////////////////
class FileEditFactoryPvt
{
public:
QMap< QtProperty*, QList< FileEdit* > > createdEditors;
QMap< FileEdit*, QtProperty* > editorToProperty;
void addEditor( QtProperty *p, FileEdit *editor )
{
editorToProperty[ editor ] = p;
QMap< QtProperty*, QList< FileEdit* > >::iterator itr = createdEditors.find( p );
if( itr == createdEditors.end() )
{
QList< FileEdit* > l;
l.push_back( editor );
createdEditors[ p ] = l;
}
else
{
QList< FileEdit* > &l = itr.value();
l.push_back( editor );
}
}
void removeEditor( QObject *o )
{
// Find in editorToProperty
QMap< FileEdit*, QtProperty* >::iterator itr = editorToProperty.begin();
while( itr != editorToProperty.end() )
{
if( itr.key() == o )
break;
++itr;
}
// Store the property, and remove the editor from editorToProperty
QtProperty *p = NULL;
if( itr != editorToProperty.end() )
{
p = itr.value();
editorToProperty.erase( itr );
}
// Find the property in createdEditors
QMap< QtProperty*, QList< FileEdit* > >::iterator mitr = createdEditors.find( p );
QList< FileEdit* > &l = mitr.value();
// Find the editor in the list
QList< FileEdit* >::iterator litr = l.begin();
while( litr != l.end() )
{
if( o == *litr )
break;
litr++;
}
// Remove the editor and remove the list too if it's empty
if( litr != l.end() )
l.erase( litr );
if( l.isEmpty() )
createdEditors.erase( mitr );
}
};
FileEditFactory::FileEditFactory( QObject *parent ) :
QtAbstractEditorFactory( parent )
{
m_pvt = new FileEditFactoryPvt();
}
FileEditFactory::~FileEditFactory()
{
delete m_pvt;
m_pvt = NULL;
}
void FileEditFactory::connectPropertyManager( FileManager *manager )
{
connect( manager, SIGNAL( valueChanged( QtProperty*, const QString& ) ),
this, SLOT( onPropertyChanged( QtProperty*, const QString& ) ) );
}
void FileEditFactory::disconnectPropertyManager( FileManager *manager )
{
disconnect( manager, SIGNAL( valueChanged( QtProperty*, const QString& ) ),
this, SLOT( onPropertyChanged( QtProperty*, const QString& ) ) );
}
QWidget* FileEditFactory::createEditor( FileManager *manager, QtProperty *p, QWidget *parent )
{
FileEdit *editor = new FileEdit( parent );
editor->setValue( p->valueText() );
connect( editor, SIGNAL( valueChanged( const QString& ) ), this, SLOT( onSetValue( const QString& ) ) );
connect( editor, SIGNAL( destroyed( QObject* ) ), this, SLOT( onEditorDestroyed( QObject* ) ) );
m_pvt->addEditor( p, editor );
return editor;
}
void FileEditFactory::onPropertyChanged( QtProperty *p, const QString &v )
{
QMap< QtProperty*, QList< FileEdit* > >::iterator itr = m_pvt->createdEditors.find( p );
if( itr == m_pvt->createdEditors.end() )
return;
QList< FileEdit* > &l = itr.value();
QList< FileEdit* >::iterator litr = l.begin();
while( litr != l.end() )
{
FileEdit *editor = *litr;
editor->blockSignals( true );
editor->setValue( v );
editor->blockSignals( false );
++litr;
}
}
void FileEditFactory::onSetValue( const QString& v )
{
QObject *s = sender();
FileEdit *editor = qobject_cast< FileEdit* >( s );
if( editor == NULL )
return;
QMap< FileEdit*, QtProperty* >::iterator itr = m_pvt->editorToProperty.find( editor );
if( itr == m_pvt->editorToProperty.end() )
return;
QtProperty *p = *itr;
FileManager *manager = qobject_cast< FileManager* >( p->propertyManager() );
if( manager == NULL )
return;
blockSignals( true );
manager->setValue( p, v );
blockSignals( false );
}
void FileEditFactory::onEditorDestroyed( QObject *editor )
{
m_pvt->removeEditor( editor );
}
//////////////////////////////////////////////////////////////// Editor /////////////////////////////////////////////////////////////////////////////////
class FileEditPvt
{
public:
QLineEdit *lineEdit;
QToolButton *toolButton;
};
FileEdit::FileEdit( QWidget *parent ) :
QWidget( parent )
{
m_pvt = new FileEditPvt();
setupUI();
setupConnections();
}
FileEdit::~FileEdit()
{
delete m_pvt;
m_pvt = NULL;
Q_EMIT destroyed( this );
}
void FileEdit::setValue( const QString &value )
{
m_pvt->lineEdit->setText( value );
}
void FileEdit::onButtonClicked()
{
QString file = QFileDialog::getOpenFileName( this,
tr( "" ),
tr( "" ) );
if( file.isEmpty() )
return;
if( m_pvt->lineEdit->text() == file )
return;
m_pvt->lineEdit->setText( file );
Q_EMIT valueChanged( file );
}
void FileEdit::setupUI()
{
m_pvt->lineEdit = new QLineEdit( this );
m_pvt->toolButton = new QToolButton( this );
m_pvt->toolButton->setText( "..." );
QHBoxLayout *layout = new QHBoxLayout( this );
layout->setContentsMargins( 0, 0, 0, 0 );
layout->setSpacing( 0 );
layout->addWidget( m_pvt->lineEdit );
layout->addWidget( m_pvt->toolButton );
setLayout( layout );
setFocusProxy( m_pvt->lineEdit );
setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Fixed );
}
void FileEdit::setupConnections()
{
connect( m_pvt->toolButton, SIGNAL( clicked( bool ) ), this, SLOT( onButtonClicked() ) );
}

View file

@ -0,0 +1,116 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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 FILEPATH_PROPERTY_MANAGER
#define FILEPATH_PROPERTY_MANAGER
#define QT_QTPROPERTYBROWSER_IMPORT
#include <QWidget>
#include <3rdparty/qtpropertybrowser/qtpropertymanager.h>
/////////////////////////////////////////////////////////////////////// Manager /////////////////////////////////////////////////////////////////
class FileManagerPvt;
class FileManager : public QtAbstractPropertyManager
{
Q_OBJECT
public:
FileManager( QObject *parent = NULL );
~FileManager();
QString value( const QtProperty *p ) const;
public Q_SLOTS:
void setValue( QtProperty *p, const QString &v );
Q_SIGNALS:
void valueChanged( QtProperty *p, const QString &v );
protected:
bool hasValue( const QtProperty *p ) const;
QString valueText( const QtProperty *p ) const;
void initializeProperty( QtProperty *p );
void uninitializeProperty( QtProperty *p );
private:
FileManagerPvt *m_pvt;
Q_DISABLE_COPY( FileManager );
};
//////////////////////////////////////////////////////// Factory ///////////////////////////////////////////////////////////////////
class FileEditFactoryPvt;
class FileEditFactory : public QtAbstractEditorFactory< FileManager >
{
Q_OBJECT
public:
FileEditFactory( QObject *parent = NULL );
~FileEditFactory();
protected:
void connectPropertyManager( FileManager *manager );
void disconnectPropertyManager( FileManager *manager );
QWidget* createEditor( FileManager *manager, QtProperty *p, QWidget *parent );
private Q_SLOTS:
void onPropertyChanged( QtProperty *p, const QString &value );
void onSetValue( const QString &value );
void onEditorDestroyed( QObject *editor );
private:
FileEditFactoryPvt *m_pvt;
Q_DISABLE_COPY( FileEditFactory );
};
//////////////////////////////////////////////////////// Editor ////////////////////////////////////////////////////////////////////
class FileEditPvt;
class FileEdit : public QWidget
{
Q_OBJECT
public:
FileEdit( QWidget *parent = NULL );
~FileEdit();
void setValue( const QString &value );
Q_SIGNALS:
void valueChanged( const QString &value );
void destroyed( QObject *editor );
private Q_SLOTS:
void onButtonClicked();
private:
void setupUI();
void setupConnections();
FileEditPvt *m_pvt;
Q_DISABLE_COPY( FileEdit );
};
#endif

View file

@ -34,6 +34,13 @@ namespace GeorgesQt
{
CFormItem::CFormItem()
{
parentItem = NULL;
formElm = NULL;
m_form = NULL;
_StructId = 0;
_Slot = 0;
_Type = Null;
_Array = false;
}
CFormItem::~CFormItem()
@ -106,48 +113,15 @@ namespace GeorgesQt
bool CFormItem::isArray()
{
// If it wasn't a root node then lets check the node type.
const NLGEORGES::CFormDfn *parentDfn;
uint indexDfn;
const NLGEORGES::CFormDfn *nodeDfn;
const NLGEORGES::CType *nodeType;
NLGEORGES::CFormElm *node;
NLGEORGES::UFormDfn::TEntryType type;
bool array;
bool parentVDfnArray;
NLGEORGES::CForm *form = static_cast<CForm*>(m_form);
NLGEORGES::CFormElm *elm = static_cast<CFormElm*>(&form->getRootNode());
nlverify ( elm->getNodeByName (_FormName.c_str(), &parentDfn, indexDfn,
&nodeDfn, &nodeType, &node, type, array, parentVDfnArray, true, NLGEORGES_FIRST_ROUND) );
if(array && node)
return true;
return false;
return _Array;
}
bool CFormItem::isArrayMember()
{
CFormItem *parent = this->parent();
// If it wasn't a root node then lets check the node type.
const NLGEORGES::CFormDfn *parentDfn;
uint indexDfn;
const NLGEORGES::CFormDfn *nodeDfn;
const NLGEORGES::CType *nodeType;
NLGEORGES::CFormElm *parentNode;
NLGEORGES::UFormDfn::TEntryType type;
bool array;
bool parentVDfnArray;
NLGEORGES::CForm *form = static_cast<CForm*>(m_form);
NLGEORGES::CFormElm *elm = static_cast<CFormElm*>(&form->getRootNode());
nlverify ( elm->getNodeByName (parent->formName ().c_str (), &parentDfn, indexDfn,
&nodeDfn, &nodeType, &parentNode, type, array, parentVDfnArray, true, NLGEORGES_FIRST_ROUND) );
if(array && parentNode)
return true;
if( parentItem == NULL )
return false;
return parentItem->isArray();
}
QIcon CFormItem::getItemImage(CFormItem *rootItem)
@ -237,7 +211,7 @@ namespace GeorgesQt
childItems.clear();
}
CFormItem *CFormItem::add (TSub type, const char *name, uint structId, const char *formName, uint slot, NLGEORGES::UForm *formPtr)
CFormItem *CFormItem::add (TSub type, const char *name, uint structId, const char *formName, uint slot, NLGEORGES::UForm *formPtr, bool isArray)
{
CFormItem *newNode = new CFormItem();
newNode->_Type = type;
@ -247,6 +221,7 @@ namespace GeorgesQt
newNode->_FormName = formName;
newNode->_Slot = slot;
newNode->m_form = formPtr;
newNode->_Array = isArray;
appendChild(newNode);
return newNode;

View file

@ -46,7 +46,7 @@ namespace GeorgesQt
void appendChild(CFormItem *child);
CFormItem *add (TSub type, const char *name, uint structId, const char *formName, uint slot, NLGEORGES::UForm *formPtr);
CFormItem *add (TSub type, const char *name, uint structId, const char *formName, uint slot, NLGEORGES::UForm *formPtr, bool isArray );
CFormItem *child(int row);
int childCount() const;
@ -76,6 +76,13 @@ namespace GeorgesQt
void clearChildren();
bool rootItem() const{
if( parentItem == NULL )
return true;
else
return false;
}
private:
QList<CFormItem*> childItems;
QList<QVariant> itemData;
@ -88,6 +95,7 @@ namespace GeorgesQt
std::string _FormName;
TSub _Type;
uint _Slot;
bool _Array;
}; // CFormItem

View file

@ -0,0 +1,223 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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/>.
#include "georges_dfn_dialog.h"
#include <QInputDialog>
#include <QMessageBox>
#include "georges.h"
#include "dfn_browser_ctrl.h"
#include "nel/misc/file.h"
#include "nel/misc/o_xml.h"
#include "nel/misc/path.h"
class GeorgesDFNDialogPvt
{
public:
GeorgesDFNDialogPvt()
{
dfn = NULL;
ctrl = new DFNBrowserCtrl();
}
~GeorgesDFNDialogPvt()
{
delete ctrl;
ctrl = NULL;
delete dfn;
dfn = NULL;
}
NLGEORGES::CFormDfn *dfn;
DFNBrowserCtrl *ctrl;
};
GeorgesDFNDialog::GeorgesDFNDialog( QWidget *parent ) :
GeorgesDockWidget( parent )
{
m_ui.setupUi( this );
m_pvt = new GeorgesDFNDialogPvt();
m_pvt->ctrl->setBrowser( m_ui.browser );
setupConnections();
}
GeorgesDFNDialog::~GeorgesDFNDialog()
{
delete m_pvt;
m_pvt = NULL;
}
bool GeorgesDFNDialog::load( const QString &fileName )
{
GeorgesQt::CGeorges georges;
NLGEORGES::UFormDfn *udfn = georges.loadFormDfn( fileName.toUtf8().constData() );
if( udfn == NULL )
return false;
QFileInfo info( fileName );
setWindowTitle( info.fileName() );
NLGEORGES::CFormDfn *cdfn = static_cast< NLGEORGES::CFormDfn* >( udfn );
m_pvt->dfn = cdfn;
loadDfn();
m_fileName = fileName;
return true;
}
void GeorgesDFNDialog::write()
{
setModified( false );
setWindowTitle( windowTitle().remove( "*" ) );
m_pvt->dfn->Header.Log = m_ui.logEdit->toPlainText().toUtf8().constData();
NLMISC::COFile file;
if( !file.open( m_fileName.toUtf8().constData(), false, true, false ) )
return;
NLMISC::COXml xml;
xml.init( &file );
m_pvt->dfn->write( xml.getDocument(), m_fileName.toUtf8().constData() );
xml.flush();
file.close();
}
void GeorgesDFNDialog::newDocument( const QString &fileName )
{
m_fileName = fileName;
QFileInfo info( fileName );
setWindowTitle( info.fileName() + "*" );
setModified( true );
m_pvt->dfn = new NLGEORGES::CFormDfn();
loadDfn();
}
void GeorgesDFNDialog::onAddClicked()
{
QString name = QInputDialog::getText( this,
tr( "New element" ),
tr( "Enter name of the new element" ) );
QList< QListWidgetItem* > list = m_ui.list->findItems( name, Qt::MatchFixedString );
if( !list.isEmpty() )
{
QMessageBox::information( this,
tr( "Item already exists" ),
tr( "That item already exists!" ) );
return;
}
m_ui.list->addItem( name );
m_pvt->dfn->addEntry( name.toUtf8().constData() );
log( "Added " + name );
onModified();
}
void GeorgesDFNDialog::onRemoveClicked()
{
int row = m_ui.list->currentRow();
if( row < 0 )
return;
log( "Removed " + m_ui.list->currentItem()->text() );
QListWidgetItem *item = m_ui.list->takeItem( row );
delete item;
m_pvt->dfn->removeEntry( row );
onModified();
}
void GeorgesDFNDialog::onCurrentRowChanged( int row )
{
if( row < 0 )
return;
m_pvt->ctrl->onElementSelected( row );
}
void GeorgesDFNDialog::onValueChanged( const QString &key, const QString &value )
{
onModified();
log( m_ui.list->currentItem()->text() + "." + key + " = " + value );
if( key == "name" )
{
m_ui.list->currentItem()->setText( value );
}
}
void GeorgesDFNDialog::loadDfn()
{
m_pvt->ctrl->setDFN( m_pvt->dfn );
uint c = m_pvt->dfn->getNumEntry();
for( uint i = 0; i < c; i++ )
{
NLGEORGES::CFormDfn::CEntry &entry = m_pvt->dfn->getEntry( i );
m_ui.list->addItem( entry.getName().c_str() );
}
if( c > 0 )
{
m_ui.list->setCurrentRow( 0 );
}
m_ui.commentsEdit->setPlainText( m_pvt->dfn->getComment().c_str() );
m_ui.logEdit->setPlainText( m_pvt->dfn->Header.Log.c_str() );
}
void GeorgesDFNDialog::onModified()
{
if( !isModified() )
{
setModified( true );
setWindowTitle( windowTitle() + "*" );
Q_EMIT modified();
}
}
void GeorgesDFNDialog::log( const QString &msg )
{
QString logMsg = buildLogMsg( msg );
m_ui.logEdit->appendPlainText( logMsg );
}
void GeorgesDFNDialog::setupConnections()
{
connect( m_ui.addButton, SIGNAL( clicked( bool ) ), this, SLOT( onAddClicked() ) );
connect( m_ui.removeButton, SIGNAL( clicked( bool ) ), this, SLOT( onRemoveClicked() ) );
connect( m_ui.list, SIGNAL( currentRowChanged( int ) ), this, SLOT( onCurrentRowChanged( int ) ) );
connect( m_pvt->ctrl, SIGNAL( valueChanged( const QString&, const QString& ) ), this, SLOT( onValueChanged( const QString&, const QString& ) ) );
}

View file

@ -0,0 +1,60 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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 GEORGES_DFN_DIALOG
#define GEORGES_DFN_DIALOG
#include "georges_dock_widget.h"
#include "ui_georges_dfn_dialog.h"
class GeorgesDFNDialogPvt;
class GeorgesDFNDialog : public GeorgesDockWidget
{
Q_OBJECT
public:
GeorgesDFNDialog( QWidget *parent = NULL );
~GeorgesDFNDialog();
bool load( const QString &fileName );
void write();
void newDocument( const QString &fileName );
Q_SIGNALS:
void modified();
private Q_SLOTS:
void onAddClicked();
void onRemoveClicked();
void onCurrentRowChanged( int row );
void onValueChanged( const QString& key, const QString &value );
private:
void loadDfn();
void onModified();
void log( const QString &msg );
void setupConnections();
Ui::GeorgesDFNDialog m_ui;
GeorgesDFNDialogPvt *m_pvt;
QString m_fileName;
};
#endif

View file

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GeorgesDFNDialog</class>
<widget class="QDockWidget" name="GeorgesDFNDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>693</width>
<height>559</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="tabPosition">
<enum>QTabWidget::West</enum>
</property>
<property name="tabShape">
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<property name="documentMode">
<bool>false</bool>
</property>
<property name="movable">
<bool>false</bool>
</property>
<widget class="QWidget" name="dfnTab">
<property name="accessibleName">
<string/>
</property>
<attribute name="title">
<string>Dfn</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="3">
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QListWidget" name="list"/>
<widget class="QtTreePropertyBrowser" name="browser" native="true"/>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="addButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="removeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item row="1" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>466</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="commentTab">
<attribute name="title">
<string>Comments</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QPlainTextEdit" name="commentsEdit">
<property name="textInteractionFlags">
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="logTab">
<attribute name="title">
<string>Log</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QPlainTextEdit" name="logEdit">
<property name="textInteractionFlags">
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>QtTreePropertyBrowser</class>
<extends>QWidget</extends>
<header>qttreepropertybrowser.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View file

@ -74,7 +74,7 @@ void CGeorgesDirTreeDialog::fileSelected(QModelIndex index)
{
if (index.isValid() && !m_dirModel->isDir(index))
{
Q_EMIT selectedForm(m_dirModel->fileName(index));
Q_EMIT fileSelected(m_dirModel->fileName(index));
}
}

View file

@ -49,7 +49,7 @@ private:
QString m_ldPath;
Q_SIGNALS:
void selectedForm(const QString);
void fileSelected(const QString&);
private Q_SLOTS:
void fileSelected(QModelIndex index);

View file

@ -0,0 +1,60 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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/>.
#include "georges_dock_widget.h"
GeorgesDockWidget::GeorgesDockWidget( QWidget *parent ) :
QDockWidget( parent )
{
m_modified = false;
m_undoStack = NULL;
}
GeorgesDockWidget::~GeorgesDockWidget()
{
}
QString GeorgesDockWidget::buildLogMsg( const QString &msg )
{
QString user = getenv( "USER" );
if( user.isEmpty() )
user = getenv( "USERNAME" );
if( user.isEmpty() )
user = "anonymous";
QTime time = QTime::currentTime();
QDate date = QDate::currentDate();
QString dateString = date.toString( "ddd MMM dd" );
QString timeString = time.toString( "HH:mm:ss" );
QString logMsg;
logMsg += dateString;
logMsg += ' ';
logMsg += timeString;
logMsg += ' ';
logMsg += QString::number( date.year() );
logMsg += ' ';
logMsg += "(";
logMsg += user;
logMsg += ")";
logMsg += ' ';
logMsg += msg;
return logMsg;
}

View file

@ -0,0 +1,51 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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 GEORGES_DOCK_WIDGET
#define GEORGES_DOCK_WIDGET
#include <QDockWidget>
class QUndoStack;
class GeorgesDockWidget : public QDockWidget
{
public:
GeorgesDockWidget( QWidget *parent = NULL );
~GeorgesDockWidget();
void setUndoStack( QUndoStack *stack ){ m_undoStack = stack; }
bool isModified() const{ return m_modified; }
void setModified( bool b ){ m_modified = b; }
QString fileName() const{ return m_fileName; }
virtual bool load( const QString &fileName ) = 0;
virtual void write() = 0;
protected:
QString buildLogMsg( const QString &msg );
virtual void log( const QString &msg ) = 0;
QString m_fileName;
bool m_modified;
QUndoStack *m_undoStack;
};
#endif

View file

@ -20,6 +20,8 @@
#include "georges_editor_constants.h"
#include "georges_dirtree_dialog.h"
#include "georges_treeview_dialog.h"
#include "georges_dfn_dialog.h"
#include "georges_typ_dialog.h"
#include "../core/icore.h"
#include "../core/menu_manager.h"
@ -27,6 +29,7 @@
// NeL includes
#include <nel/misc/debug.h>
#include <nel/misc/path.h>
// Qt includes
#include <QSettings>
@ -68,11 +71,20 @@ namespace GeorgesQt
Core::MenuManager *menuManager = Core::ICore::instance()->menuManager();
m_openAction = menuManager->action(Core::Constants::OPEN);
m_newAction = new QAction(tr("&New..."), this);
m_newAction->setIcon(QIcon(Core::Constants::ICON_NEW));
m_newAction->setShortcut(QKeySequence::New);
m_newAction->setStatusTip(tr("Create a new file"));
connect(m_newAction, SIGNAL(triggered()), this, SLOT(newFile()));
m_newTypAction = new QAction(tr("New Type"), this );
m_newTypAction->setIcon(QIcon(Core::Constants::ICON_NEW));
m_newTypAction->setStatusTip(tr("Create a new type file"));
connect( m_newTypAction, SIGNAL(triggered()), this, SLOT(newTyp()));
m_newDfnAction = new QAction(tr("New DFN"), this );
m_newDfnAction->setIcon(QIcon(Core::Constants::ICON_NEW));
m_newDfnAction->setStatusTip(tr("Create a new definition file"));
connect( m_newDfnAction, SIGNAL(triggered()), this, SLOT(newDfn()));
m_newFormAction = new QAction(tr("New Form"), this );
m_newFormAction->setIcon(QIcon(Core::Constants::ICON_NEW));
m_newFormAction->setStatusTip(tr("Create a new form file"));
connect( m_newFormAction, SIGNAL(triggered()), this, SLOT(newForm()));
m_saveAction = new QAction(tr("&Save..."), this);
m_saveAction->setIcon(QIcon(Core::Constants::ICON_SAVE));
@ -81,8 +93,10 @@ namespace GeorgesQt
connect(m_saveAction, SIGNAL(triggered()), this, SLOT(save()));
m_fileToolBar = addToolBar(tr("&File"));
m_fileToolBar->addAction(m_newTypAction);
m_fileToolBar->addAction(m_newDfnAction);
m_fileToolBar->addAction(m_newFormAction);
m_fileToolBar->addAction(m_openAction);
m_fileToolBar->addAction(m_newAction);
m_fileToolBar->addAction(m_saveAction);
m_saveAction->setEnabled(false);
@ -103,8 +117,8 @@ namespace GeorgesQt
connect(Core::ICore::instance(), SIGNAL(changeSettings()),
this, SLOT(settingsChanged()));
connect(m_georgesDirTreeDialog, SIGNAL(selectedForm(const QString)),
this, SLOT(loadFile(const QString)));
connect(m_georgesDirTreeDialog, SIGNAL(fileSelected(const QString&)),
this, SLOT(loadFile(const QString&)));
connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)),
this, SLOT(focusChanged(QWidget*, QWidget*)));
}
@ -126,26 +140,83 @@ namespace GeorgesQt
loadFile(fileName);
}
void GeorgesEditorForm::newFile()
void GeorgesEditorForm::newTyp()
{
// Assume it is a form, for now. We'll have to retrieve the DFN we'll be using as a base.
QString fileName = QFileDialog::getOpenFileName(this, tr("Select Base Form Definition"), m_lastSheetDir, "Form Definition (*.dfn)");
if(!fileName.isNull())
{
// Use the file loader to create the new form.
loadFile(fileName, true);
QString fileName = QFileDialog::getSaveFileName( this,
tr( "New Type" ),
"",
"Type files (*.typ)" );
if( fileName.isEmpty() )
return;
// Save the folder we just opened for future dialogs.
QFileInfo pathInfo( fileName );
m_lastSheetDir = pathInfo.absolutePath();
GeorgesTypDialog *d = new GeorgesTypDialog();
d->newDocument( fileName );
addGeorgesWidget( d );
setModified();
}
void GeorgesEditorForm::newDfn()
{
QString fileName = QFileDialog::getSaveFileName( this,
tr( "New Definition" ),
"",
"Definition files (*.dfn)" );
if( fileName.isEmpty() )
return;
GeorgesDFNDialog *d = new GeorgesDFNDialog();
d->newDocument( fileName );
addGeorgesWidget( d );
setModified();
}
void GeorgesEditorForm::newForm()
{
QString dfnFileName = QFileDialog::getOpenFileName( this,
tr( "New Form" ),
"",
"Definition files (*.dfn)" );
if( dfnFileName.isEmpty() )
return;
QFileInfo dfnInfo( dfnFileName );
QString baseName = dfnInfo.baseName();
QString filter;
filter += baseName;
filter += " files (*.";
filter += baseName;
filter += ")";
QString fileName = QFileDialog::getSaveFileName( this,
tr( "New Form" ),
"",
filter );
if( fileName.isEmpty() )
return;
CGeorgesTreeViewDialog *d = new CGeorgesTreeViewDialog();
if( !d->newDocument( fileName, dfnFileName ) )
{
QMessageBox::information( this,
tr( "Failed to create new form" ),
tr( "Failed to create new form!" ) );
return;
}
addGeorgesWidget( d );
setModified();
}
void GeorgesEditorForm::save()
{
m_lastActiveDock->write();
m_saveAction->setEnabled(false);
m_saveAction->setEnabled(false);
QAction *saveAction = Core::ICore::instance()->menuManager()->action( Core::Constants::SAVE );
if( saveAction != NULL )
saveAction->setEnabled(false);
}
void GeorgesEditorForm::readSettings()
@ -175,6 +246,28 @@ namespace GeorgesQt
settings->sync();
}
void GeorgesEditorForm::addGeorgesWidget( GeorgesDockWidget *w )
{
w->setUndoStack(UndoStack);
m_lastActiveDock = w;
m_dockedWidgets.append(w);
connect(m_dockedWidgets.last(), SIGNAL(closing()), this, SLOT(closingTreeView()));
connect(m_dockedWidgets.last(), SIGNAL(visibilityChanged(bool)), m_dockedWidgets.last(), SLOT(checkVisibility(bool)));
// If there is more than one form open - tabify the new form. If this is the first form open add it to the dock.
if(m_dockedWidgets.size() > 1)
{
m_mainDock->tabifyDockWidget(m_dockedWidgets.at(m_dockedWidgets.size() - 2), m_dockedWidgets.last());
}
else
{
m_mainDock->addDockWidget(Qt::RightDockWidgetArea, m_dockedWidgets.last());
}
w->raise();
}
void GeorgesEditorForm::settingsChanged()
{
QSettings *settings = Core::ICore::instance()->settings();
@ -190,21 +283,25 @@ namespace GeorgesQt
}
}
void GeorgesEditorForm::loadFile(const QString fileName)
void GeorgesEditorForm::loadFile(const QString &fileName)
{
loadFile(fileName, false);
std::string path = NLMISC::CPath::lookup( fileName.toUtf8().constData(), false );
if( path.empty() )
{
QMessageBox::information( this,
tr( "Failed to load file..." ),
tr( "Failed to load file '%1': File doesn't exist!" ).arg( fileName ) );
return;
}
void GeorgesEditorForm::loadFile(const QString fileName, bool loadFromDfn)
{
QFileInfo info(fileName);
QFileInfo info( path.c_str() );
// Check to see if the form is already loaded, if it is just raise it.
if (m_dockedWidgets.size())
{
Q_FOREACH(CGeorgesTreeViewDialog *wgt, m_dockedWidgets)
Q_FOREACH(GeorgesDockWidget *wgt, m_dockedWidgets)
{
if (info.fileName() == wgt->loadedForm)
if ( QString( path.c_str() ) == wgt->fileName())
{
wgt->raise();
return;
@ -212,52 +309,31 @@ namespace GeorgesQt
}
}
CGeorgesTreeViewDialog *dock = new CGeorgesTreeViewDialog(m_mainDock);
dock->setUndoStack(UndoStack);
m_lastActiveDock = dock;
m_dockedWidgets.append(dock);
GeorgesDockWidget *w = NULL;
connect(m_dockedWidgets.last(), SIGNAL(closing()), this, SLOT(closingTreeView()));
connect(m_dockedWidgets.last(), SIGNAL(visibilityChanged(bool)), m_dockedWidgets.last(), SLOT(checkVisibility(bool)));
// If there is more than one form open - tabify the new form. If this is the first form open add it to the dock.
if(m_dockedWidgets.size() > 1)
if( info.suffix() == "dfn" )
{
m_mainDock->tabifyDockWidget(m_dockedWidgets.at(m_dockedWidgets.size() - 2), m_dockedWidgets.last());
w = loadDfnDialog( path.c_str() );
}
else
if( info.suffix() == "typ" )
{
w = loadTypDialog( path.c_str() );
}
else
{
m_mainDock->addDockWidget(Qt::RightDockWidgetArea, m_dockedWidgets.last());
w = loadFormDialog( path.c_str() );
}
// Retrieve the form and load the form.
NLGEORGES::CForm *form;
if(loadFromDfn)
if( w == NULL )
{
// Get the form by DFN name.
form = m_dockedWidgets.last()->getFormByDfnName(info.fileName());
}
else
{
form = m_dockedWidgets.last()->getFormByName(info.fileName());
QMessageBox::information( this,
tr( "Failed to load file..." ),
tr( "Failed to load file '%1': Not a typ, dfn, or form file!" ).arg( info.fileName() ) );
return;
}
if (form)
{
m_dockedWidgets.last()->setForm(form);
m_dockedWidgets.last()->loadFormIntoDialog(form);
QApplication::processEvents();
connect(m_dockedWidgets.last(), SIGNAL(modified()),
this, SLOT(setModified()));
m_dockedWidgets.last()->raise();
connect(m_dockedWidgets.last(), SIGNAL(changeFile(QString)),
m_georgesDirTreeDialog, SLOT(changeFile(QString)));
}
else
{
nlwarning("Failed to load form: %s", info.fileName().toUtf8().constData());
m_dockedWidgets.last()->close();
}
addGeorgesWidget( w );
}
void GeorgesEditorForm::closingTreeView()
@ -311,4 +387,49 @@ namespace GeorgesQt
}
}
}
GeorgesDockWidget* GeorgesEditorForm::loadTypDialog( const QString &fileName )
{
GeorgesTypDialog *d = new GeorgesTypDialog();
if( !d->load( fileName ) )
{
delete d;
return NULL;
}
connect( d, SIGNAL( modified() ), this, SLOT( setModified() ) );
return d;
}
GeorgesDockWidget* GeorgesEditorForm::loadDfnDialog( const QString &fileName )
{
GeorgesDFNDialog *d = new GeorgesDFNDialog();
bool b = d->load( fileName );
if( !b )
{
delete d;
return NULL;
}
connect( d, SIGNAL( modified() ), this, SLOT( setModified() ) );
return d;
}
GeorgesDockWidget* GeorgesEditorForm::loadFormDialog( const QString &fileName )
{
CGeorgesTreeViewDialog *d = new CGeorgesTreeViewDialog();
if( !d->load( fileName ) )
{
delete d;
return NULL;
}
connect(d, SIGNAL(modified()), this, SLOT(setModified()));
connect(d, SIGNAL(changeFile(QString)), m_georgesDirTreeDialog, SLOT(changeFile(QString)));
return d;
}
} /* namespace GeorgesQt */

View file

@ -23,6 +23,8 @@
// Qt includes
#include <QtGui/QUndoStack>
class GeorgesDockWidget;
namespace GeorgesQt
{
@ -42,9 +44,12 @@ public:
public Q_SLOTS:
void open();
void loadFile(const QString fileName);
void loadFile(const QString fileName, bool loadFromDfn);
void newFile();
void loadFile(const QString &fileName);
void newTyp();
void newDfn();
void newForm();
void save();
void settingsChanged();
void closingTreeView();
@ -56,12 +61,20 @@ private:
void readSettings();
void writeSettings();
void addGeorgesWidget( GeorgesDockWidget *w );
GeorgesDockWidget* loadTypDialog(const QString &fileName);
GeorgesDockWidget* loadDfnDialog(const QString &fileName);
GeorgesDockWidget* loadFormDialog(const QString &fileName);
Ui::GeorgesEditorForm m_ui;
CGeorgesDirTreeDialog *m_georgesDirTreeDialog;
QToolBar *m_fileToolBar;
QAction *m_openAction;
QAction *m_newAction;
QAction *m_newTypAction;
QAction *m_newDfnAction;
QAction *m_newFormAction;
QAction *m_saveAction;
QString m_leveldesignPath;
@ -69,10 +82,10 @@ private:
QMainWindow *m_mainDock;
/// Contains a list of all of the open forms.
QList<CGeorgesTreeViewDialog*> m_dockedWidgets;
QList<GeorgesDockWidget*> m_dockedWidgets;
/// Contains a pointer to the last known focal change for active documents.
CGeorgesTreeViewDialog *m_lastActiveDock;
GeorgesDockWidget *m_lastActiveDock;
/// Contains a record of the last directory a sheet file dialog was opened for.
QString m_lastSheetDir;

View file

@ -94,6 +94,11 @@ void GeorgesEditorContext::open()
m_georgesEditorForm->open();
}
void GeorgesEditorContext::save()
{
m_georgesEditorForm->save();
}
QWidget *GeorgesEditorContext::widget()
{
return m_georgesEditorForm;

View file

@ -86,6 +86,8 @@ public:
virtual void open();
void save();
virtual QUndoStack *undoStack();
virtual QWidget *widget();

View file

@ -52,9 +52,8 @@ namespace GeorgesQt
{
CGeorgesTreeViewDialog::CGeorgesTreeViewDialog(QWidget *parent /*= 0*/)
: QDockWidget(parent),
m_header(0),
m_modified(false)
: GeorgesDockWidget(parent),
m_header(0)
{
m_georges = new CGeorges;
@ -71,7 +70,6 @@ namespace GeorgesQt
m_ui.treeView->setHeader(m_header);
m_ui.treeView->header()->setResizeMode(QHeaderView::ResizeToContents);
m_ui.treeView->header()->setStretchLastSection(true);
m_ui.treeViewTabWidget->setTabEnabled (2,false);
m_form = 0;
m_model = NULL;
@ -91,6 +89,7 @@ namespace GeorgesQt
connect(m_browserCtrl, SIGNAL(arrayResized(const QString&,int)), this, SLOT(onArrayResized(const QString&,int)));
connect(m_browserCtrl, SIGNAL(modified()), this, SLOT(modifiedFile()));
connect(m_browserCtrl, SIGNAL(valueChanged(const QString&,const QString&)), this, SLOT(onValueChanged(const QString&,const QString&)));
}
CGeorgesTreeViewDialog::~CGeorgesTreeViewDialog()
@ -121,11 +120,7 @@ namespace GeorgesQt
NLGEORGES::CForm* CGeorgesTreeViewDialog::getFormByName(const QString formName)
{
if(NLMISC::CPath::exists(formName.toAscii().data()))
{
//NLGEORGES::CForm *form = dynamic_cast<NLGEORGES::CForm*>(m_georges->loadForm(formName.toAscii().data()));
return (NLGEORGES::CForm *)m_georges->loadForm(formName.toAscii().data());
}
//else
//{
// CForm *form = 0;
@ -160,13 +155,10 @@ namespace GeorgesQt
// }
// return form;
//}
nlinfo("File '%s' does not exist!", formName.toAscii().data());
return 0;
}
NLGEORGES::CForm* CGeorgesTreeViewDialog::getFormByDfnName(const QString dfnName)
{
if(NLMISC::CPath::exists(dfnName.toAscii().data()))
{
// Create a new form object.
NLGEORGES::CForm *form = new NLGEORGES::CForm();
@ -188,9 +180,6 @@ namespace GeorgesQt
return form;
}
nlinfo("File '%s' does not exist!", dfnName.toAscii().data());
return NULL;
}
NLGEORGES::CFormElm *CGeorgesTreeViewDialog::getRootNode(uint slot)
{
@ -220,6 +209,9 @@ namespace GeorgesQt
else
return;
m_ui.logEdit->setPlainText( form->Header.Log.c_str() );
m_ui.logEdit->setReadOnly( true );
UFormElm *root = 0;
root = &m_form->getRootNode();
@ -260,6 +252,7 @@ namespace GeorgesQt
if (root)
{
loadedForm = m_form->getFilename().c_str();
m_fileName = m_form->getFilename().c_str();
CGeorgesFormModel *model = new CGeorgesFormModel(m_form,deps,comments,parents,m_header->expanded());
m_ui.treeView->setModel(model);
@ -268,9 +261,6 @@ namespace GeorgesQt
connect(model, SIGNAL(dataChanged(const QModelIndex, const QModelIndex)),
this, SLOT(modifiedFile()));
setWindowTitle(loadedForm);
// //Modules::mainWin().getTabBar();
m_model = model;
}
}
@ -306,19 +296,42 @@ namespace GeorgesQt
void CGeorgesTreeViewDialog::modifiedFile( )
{
if (!m_modified)
if (!isModified())
{
m_modified = true;
setModified( true );
setWindowTitle(windowTitle() + "*");
}
Q_EMIT modified();
}
void CGeorgesTreeViewDialog::write( )
bool CGeorgesTreeViewDialog::load( const QString &fileName )
{
// Retrieve the form and load the form.
NLGEORGES::CForm *form = getFormByName(fileName);
if( form == NULL )
return false;
setForm(form);
loadFormIntoDialog(form);
QApplication::processEvents();
m_fileName = fileName;
QFileInfo info( fileName );
setWindowTitle( info.fileName() );
return true;
}
void CGeorgesTreeViewDialog::write( )
{
NLGEORGES::CForm *form = static_cast< NLGEORGES::CForm* >( m_form );
form->Header.Log = m_ui.logEdit->toPlainText().toUtf8().constData();
NLMISC::COFile file;
std::string s = NLMISC::CPath::lookup(loadedForm.toAscii().data(), false);
std::string s = m_fileName.toUtf8().constData();
if(file.open (s))
{
try
@ -367,7 +380,7 @@ namespace GeorgesQt
// //((CForm*)(UForm*)Form)->write (xmlStream.getDocument (), lpszPathName, theApp.Georges4CVS);
m_form->write(file);
setWindowTitle(windowTitle().remove("*"));
m_modified = false;
setModified( false );
// //if (strcmp (xmlStream.getErrorString (), "") != 0)
// //{
// // char message[512];
@ -393,6 +406,26 @@ namespace GeorgesQt
}
}
bool CGeorgesTreeViewDialog::newDocument( const QString &fileName, const QString &dfn )
{
NLGEORGES::CForm *form = getFormByDfnName(dfn);
if( form == NULL )
return false;
setForm(form);
loadFormIntoDialog(form);
QApplication::processEvents();
m_fileName = fileName;
QFileInfo info( fileName );
setWindowTitle( info.fileName() + "*" );
setModified( true );
return true;
}
void CGeorgesTreeViewDialog::doubleClicked ( const QModelIndex & index )
{
//CGeorgesFormModel *model =
@ -468,6 +501,76 @@ namespace GeorgesQt
if( !idx.isValid() )
return;
m_ui.treeView->setCurrentIndex( idx );
log( name + " resized = " + QString::number( size ) );
modifiedFile();
}
void CGeorgesTreeViewDialog::onAppendArray()
{
QModelIndex idx = m_ui.treeView->currentIndex();
CFormItem *item = reinterpret_cast< CFormItem* >( idx.internalPointer() );
QString formName = item->formName().c_str();
int size = item->childCount();
m_model->appendArray( idx );
m_ui.treeView->reset();
m_ui.treeView->expandAll();
m_ui.treeView->setCurrentIndex( idx );
m_browserCtrl->clicked( idx );
log( formName + " resized = " + QString::number( size + 1 ) );
modifiedFile();
}
void CGeorgesTreeViewDialog::onDeleteArrayEntry()
{
QModelIndex current = m_ui.treeView->currentIndex();
QModelIndex parent = current.parent();
CFormItem *item = reinterpret_cast< CFormItem* >( current.internalPointer() );
QString formName = item->formName().c_str();
m_model->deleteArrayEntry( current );
m_ui.treeView->expandAll();
m_ui.treeView->setCurrentIndex( parent );
m_browserCtrl->clicked( parent );
log( "deleted " + formName );
modifiedFile();
}
void CGeorgesTreeViewDialog::onValueChanged( const QString &key, const QString &value )
{
log( key + " = " + value );
}
void CGeorgesTreeViewDialog::onRenameArrayEntry()
{
QModelIndex idx = m_ui.treeView->currentIndex();
CFormItem *item = static_cast< CFormItem* >( idx.internalPointer() );
QString newName = QInputDialog::getText( this,
tr( "Rename" ),
tr( "Enter new name" ),
QLineEdit::Normal,
item->name().c_str() );
m_model->renameArrayEntry( idx, newName );
QString formName = item->formName().c_str();
log( formName + " renamed = " + newName );
modifiedFile();
}
void CGeorgesTreeViewDialog::closeEvent(QCloseEvent *event)
@ -523,12 +626,17 @@ namespace GeorgesQt
// }
if(item->isArray())
{
contextMenu.addAction("Append array entry...");
QAction *appendAction = contextMenu.addAction("Append array entry...");
connect( appendAction, SIGNAL( triggered( bool ) ), this, SLOT( onAppendArray() ) );
}
else if(item->isArrayMember())
{
contextMenu.addAction("Delete array entry...");
contextMenu.addAction("Insert after array entry...");
QAction *deleteAction = contextMenu.addAction("Delete array entry...");
connect( deleteAction, SIGNAL( triggered( bool ) ), this, SLOT( onDeleteArrayEntry() ) );
QAction *renameAction = contextMenu.addAction("Rename");
connect( renameAction, SIGNAL( triggered( bool ) ), this, SLOT( onRenameArrayEntry() ) );
//contextMenu.addAction("Insert after array entry...");
}
// else if(item->getFormElm()->isStruct())
// {
@ -558,24 +666,10 @@ namespace GeorgesQt
// else if(item->getFormElm()->isAtom() && item->valueFrom() == NLGEORGES::UFormElm::ValueForm)
// contextMenu.addAction("Revert to parent/default...");
QAction *selectedItem = contextMenu.exec(QCursor::pos());
contextMenu.exec(QCursor::pos());
/*
if(selectedItem)
{
if(selectedItem->text() == "Append array entry...")
{
} // Append an array entry...
else if(selectedItem->text() == "Delete array entry...")
{
}
else if(selectedItem->text() == "Insert after array entry...")
{
}
// if(selectedItem->text() == "Add parent...")
// {
// // Get the file extension of the form so we can build a dialog pattern.
@ -624,10 +718,18 @@ namespace GeorgesQt
// }
} // if selected context menu item is valid.
*/
} // if 'm' model valid.
//if(structContext)
// delete structContext;
}
void CGeorgesTreeViewDialog::log( const QString &msg )
{
QString logMsg = buildLogMsg( msg );
m_ui.logEdit->appendPlainText( logMsg );
}
} /* namespace GeorgesQt */

View file

@ -18,6 +18,7 @@
#define GEORGES_TREEVIEWER_DIALOG_H
#include "ui_georges_treeview_form.h"
#include "georges_dock_widget.h"
#include "expandable_headerview.h"
// Qt includes
@ -49,7 +50,7 @@ namespace GeorgesQt
class CGeorges;
class CGeorgesFormModel;
class CGeorgesTreeViewDialog: public QDockWidget
class CGeorgesTreeViewDialog: public GeorgesDockWidget
{
Q_OBJECT
@ -57,9 +58,6 @@ namespace GeorgesQt
CGeorgesTreeViewDialog(QWidget *parent = 0);
~CGeorgesTreeViewDialog();
bool isModified() {return m_modified;}
void setModified(bool m) {m_modified = m;}
NLGEORGES::CForm* getFormByName(const QString formName);
NLGEORGES::CForm* getFormByDfnName(const QString dfnName);
@ -71,16 +69,12 @@ namespace GeorgesQt
void addParentForm(QString parentFormNm);
bool load( const QString &fileName );
void write ( );
bool newDocument( const QString &fileName, const QString &dfn );
QTabWidget* tabWidget() { return m_ui.treeViewTabWidget; }
void setUndoStack(QUndoStack *stack) {
m_undoStack = stack;
}
QString loadedForm;
protected:
@ -104,20 +98,22 @@ namespace GeorgesQt
void headerClicked(int);
void onArrayResized( const QString &name, int size );
void onAppendArray();
void onDeleteArrayEntry();
void onValueChanged( const QString &key, const QString &value );
void onRenameArrayEntry();
private:
void log( const QString &msg );
Ui::CGeorgesTreeViewDialog m_ui;
ExpandableHeaderView *m_header;
UForm *m_form;
CGeorges *m_georges;
QUndoStack *m_undoStack;
/// Contains a record of the last directory a sheet file dialog was opened for.
QString m_lastSheetDir;
bool m_modified;
BrowserCtrl *m_browserCtrl;
CGeorgesFormModel *m_model;

View file

@ -0,0 +1,265 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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/>.
#include "georges_typ_dialog.h"
#include "georges.h"
#include "typ_browser_ctrl.h"
#include <QInputDialog>
#include <QMessageBox>
#include "nel/misc/file.h"
#include "nel/misc/o_xml.h"
#include "nel/misc/path.h"
class GeorgesTypDialogPvt
{
public:
GeorgesTypDialogPvt()
{
typ = NULL;
ctrl = new TypBrowserCtrl();
}
~GeorgesTypDialogPvt()
{
delete typ;
typ = NULL;
delete ctrl;
ctrl = NULL;
}
NLGEORGES::CType *typ;
TypBrowserCtrl *ctrl;
};
GeorgesTypDialog::GeorgesTypDialog( QWidget *parent ) :
GeorgesDockWidget( parent )
{
m_ui.setupUi( this );
m_pvt = new GeorgesTypDialogPvt();
m_pvt->ctrl->setBrowser( m_ui.browser );
setupConnections();
}
GeorgesTypDialog::~GeorgesTypDialog()
{
delete m_pvt;
m_pvt = NULL;
}
bool GeorgesTypDialog::load( const QString &fileName )
{
GeorgesQt::CGeorges georges;
NLGEORGES::UType *utyp = georges.loadFormType( fileName.toUtf8().constData() );
if( utyp == NULL )
return false;
m_pvt->typ = dynamic_cast< NLGEORGES::CType* >( utyp );
loadTyp();
m_fileName = fileName;
QFileInfo info( fileName );
setWindowTitle( info.fileName() );
return true;
}
void GeorgesTypDialog::write()
{
NLMISC::COFile file;
if( !file.open( m_fileName.toUtf8().constData(), false, true, false ) )
return;
NLMISC::COXml xml;
xml.init( &file );
m_pvt->typ->Header.Log = m_ui.logEdit->toPlainText().toUtf8().constData();
m_pvt->typ->write( xml.getDocument() );
xml.flush();
file.close();
setModified( false );
setWindowTitle( windowTitle().remove( "*" ) );
}
void GeorgesTypDialog::newDocument( const QString &fileName )
{
m_pvt->typ = new NLGEORGES::CType();
m_fileName = fileName;
QFileInfo info( fileName );
setWindowTitle( info.fileName() + "*" );
setModified( true );
loadTyp();
}
void GeorgesTypDialog::onAddClicked()
{
QString label = QInputDialog::getText( this,
tr( "Adding new definition" ),
tr( "Please specify the label" ) );
if( label.isEmpty() )
return;
QList< QTreeWidgetItem* > l = m_ui.tree->findItems( label, Qt::MatchExactly, 0 );
if( !l.isEmpty() )
{
QMessageBox::information( this,
tr( "Failed to add item" ),
tr( "You can't add an item with the same label more than once!" ) );
return;
}
QTreeWidgetItem *item = new QTreeWidgetItem();
item->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled );
item->setText( 0, label );
item->setText( 1, "" );
m_ui.tree->addTopLevelItem( item );
NLGEORGES::CType::CDefinition def;
def.Label = label.toUtf8().constData();
def.Value = "";
m_pvt->typ->Definitions.push_back( def );
log( "Added definition " + label );
onModified();
}
void GeorgesTypDialog::onRemoveClicked()
{
QTreeWidgetItem *item = m_ui.tree->currentItem();
if( item == NULL )
return;
int i = 0;
for( i = 0; i < m_ui.tree->topLevelItemCount(); i++ )
{
if( item == m_ui.tree->topLevelItem( i ) )
break;
}
QString definition = item->text( 0 );
m_ui.tree->takeTopLevelItem( i );
delete item;
std::vector< NLGEORGES::CType::CDefinition >::iterator itr = m_pvt->typ->Definitions.begin() + i;
m_pvt->typ->Definitions.erase( itr );
log( "Removed definition" + definition );
onModified();
}
void GeorgesTypDialog::onItemChanged( QTreeWidgetItem *item, int column )
{
int i = 0;
for( i = 0; i < m_ui.tree->topLevelItemCount(); i++ )
{
if( item == m_ui.tree->topLevelItem( i ) )
break;
}
NLGEORGES::CType::CDefinition &def = m_pvt->typ->Definitions[ i ];
QString logMsg;
logMsg = "Changed definition" + QString( def.Label.c_str() );
if( i == 0 )
{
logMsg += ".label = ";
logMsg += item->text( 0 );
def.Label = item->text( 0 ).toUtf8().constData();
}
else
{
logMsg += ".value = ";
logMsg += item->text( 1 );
def.Value = item->text( 1 ).toUtf8().constData();
}
log( logMsg );
onModified();
}
void GeorgesTypDialog::onModified()
{
if( isModified() )
return;
setModified( true );
setWindowTitle( windowTitle() + "*" );
Q_EMIT modified();
}
void GeorgesTypDialog::onModified( const QString &k, const QString &v )
{
log( "Changed " + k + " = " + v );
onModified();
}
void GeorgesTypDialog::setupConnections()
{
connect( m_ui.addButton, SIGNAL( clicked( bool ) ), this, SLOT( onAddClicked() ) );
connect( m_ui.removeButton, SIGNAL( clicked( bool ) ), this, SLOT( onRemoveClicked() ) );
connect( m_ui.tree, SIGNAL( itemChanged( QTreeWidgetItem*, int ) ), this, SLOT( onItemChanged( QTreeWidgetItem*, int ) ) );
connect( m_pvt->ctrl, SIGNAL( modified( const QString&, const QString& ) ), this, SLOT( onModified( const QString&, const QString& ) ) );
}
void GeorgesTypDialog::log( const QString &msg )
{
QString logMsg = buildLogMsg( msg );
m_ui.logEdit->appendPlainText( logMsg );
}
void GeorgesTypDialog::loadTyp()
{
m_ui.logEdit->setPlainText( m_pvt->typ->Header.Log.c_str() );
m_ui.commentEdit->setPlainText( m_pvt->typ->Header.Comments.c_str() );
std::vector< NLGEORGES::CType::CDefinition >::iterator itr = m_pvt->typ->Definitions.begin();
while( itr != m_pvt->typ->Definitions.end() )
{
NLGEORGES::CType::CDefinition &def = *itr;
QTreeWidgetItem *item = new QTreeWidgetItem();
item->setFlags( Qt::ItemIsEditable | Qt::ItemIsEnabled );
item->setText( 0, def.Label.c_str() );
item->setText( 1, def.Value.c_str() );
m_ui.tree->addTopLevelItem( item );
++itr;
}
m_pvt->ctrl->setTyp( m_pvt->typ );
m_pvt->ctrl->load();
}

View file

@ -0,0 +1,62 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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 GEORGES_TYP_DIALOG
#define GEORGES_TYP_DIALOG
#include "georges_dock_widget.h"
#include "ui_georges_typ_dialog.h"
class GeorgesTypDialogPvt;
class GeorgesTypDialog : public GeorgesDockWidget
{
Q_OBJECT
public:
GeorgesTypDialog( QWidget *parent = NULL );
~GeorgesTypDialog();
bool load( const QString &fileName );
void write();
void newDocument( const QString &fileName );
Q_SIGNALS:
void modified();
private Q_SLOTS:
void onAddClicked();
void onRemoveClicked();
void onItemChanged( QTreeWidgetItem *item, int column );
void onModified();
void onModified( const QString &k, const QString &v );
private:
void setupConnections();
void log( const QString &msg );
void loadTyp();
Ui::GeorgesTypDialog m_ui;
GeorgesTypDialogPvt *m_pvt;
QString m_fileName;
};
#endif

View file

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GeorgesTypDialog</class>
<widget class="QDockWidget" name="GeorgesTypDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>682</width>
<height>425</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTabWidget" name="logTab">
<property name="tabPosition">
<enum>QTabWidget::West</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Type</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QtTreePropertyBrowser" name="browser" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="3">
<widget class="QTreeWidget" name="tree">
<column>
<property name="text">
<string>Label</string>
</property>
</column>
<column>
<property name="text">
<string>Value</string>
</property>
</column>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="addButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="removeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item row="1" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>15</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Comment</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QPlainTextEdit" name="commentEdit"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Log</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QPlainTextEdit" name="logEdit"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>QtTreePropertyBrowser</class>
<extends>QWidget</extends>
<header>qttreepropertybrowser.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View file

@ -283,7 +283,7 @@ namespace GeorgesQt
NLGEORGES::CForm *formPtr = static_cast<NLGEORGES::CForm*>(m_form);
// Add the new node
CFormItem *newNode = parent->add(CFormItem::Form, name, structId, formName, slot, m_form);
CFormItem *newNode = parent->add(CFormItem::Form, name, structId, formName, slot, m_form, false);
// Can be NULL in virtual DFN
if (parentDfn)
@ -418,7 +418,7 @@ CFormItem *CGeorgesFormModel::addArray(CFormItem *parent,
uint slot)
{
// Add the new node
CFormItem *newNode = parent->add (CFormItem::Form, name, structId, formName, slot, m_form);
CFormItem *newNode = parent->add (CFormItem::Form, name, structId, formName, slot, m_form, true);
// The array exist
if (array)
@ -451,7 +451,7 @@ CFormItem *CGeorgesFormModel::addArray(CFormItem *parent,
else
{
NLGEORGES::CFormElmArray *elmPtr = array->Elements[elm].Element ? static_cast<NLGEORGES::CFormElmArray*>(array->Elements[elm].Element) : NULL;
newNode->add (CFormItem::Form, formArrayName, elm, formArrayElmName, slot, m_form);
newNode->add (CFormItem::Form, formArrayName, elm, formArrayElmName, slot, m_form, false);
}
}
}
@ -494,12 +494,153 @@ void CGeorgesFormModel::arrayResized( const QString &name, int size )
else
n = e.Name.c_str();
item->add( CFormItem::Form, n.toUtf8().constData(), i, formName.toUtf8().constData(), 0, item->form() );
item->add( CFormItem::Form, n.toUtf8().constData(), i, formName.toUtf8().constData(), 0, item->form(), false );
}
if( celm->Elements.size() == 0 )
{
NLGEORGES::CFormElmStruct *ps = dynamic_cast< NLGEORGES::CFormElmStruct* >( celm->getParent() );
if( ps != NULL )
{
const NLGEORGES::CFormDfn *parentDfn;
const NLGEORGES::CFormDfn *nodeDfn;
uint indexDfn;
const NLGEORGES::CType *nodeType;
NLGEORGES::CFormElm *node;
NLGEORGES::CFormDfn::TEntryType type;
bool isArray;
ps->deleteNodeByName( item->name().c_str(), &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, isArray );
}
}
}
void CGeorgesFormModel::appendArray( QModelIndex idx )
{
if( !idx.isValid() )
return;
CFormItem *item = reinterpret_cast< CFormItem* >( idx.internalPointer() );
NLGEORGES::UFormElm *elm = NULL;
item->form()->getRootNode().getNodeByName( &elm, item->formName().c_str() );
const NLGEORGES::CFormDfn *parentDfn;
const NLGEORGES::CFormDfn *nodeDfn;
uint indexDfn;
const NLGEORGES::CType *type;
NLGEORGES::UFormDfn::TEntryType entryType;
NLGEORGES::CFormElm *node;
bool created;
bool isArray;
if( elm == NULL )
{
NLGEORGES::UFormElm *uroot = &item->form()->getRootNode();
NLGEORGES::CFormElm *croot = static_cast< NLGEORGES::CFormElm* >( uroot );
croot->createNodeByName( item->formName().c_str(), &parentDfn, indexDfn, &nodeDfn, &type, &node, entryType, isArray, created );
if( !created )
return;
elm = node;
}
NLGEORGES::CFormElmArray *celm = dynamic_cast< NLGEORGES::CFormElmArray* >( elm );
if( celm == NULL )
return;
unsigned long s = celm->Elements.size();
std::string nodeIdx = "[";
nodeIdx += QString::number( s ).toUtf8().constData();
nodeIdx += "]";
celm->createNodeByName( nodeIdx.c_str(), &parentDfn, indexDfn, &nodeDfn, &type, &node, entryType, isArray, created );
if( !created )
return;
std::string name = "#";
name += QString::number( s ).toUtf8().constData();
std::string formName;
node->getFormName( formName );
item->add( CFormItem::Form, name.c_str(), s, formName.c_str(), 0, item->form(), false );
}
void CGeorgesFormModel::deleteArrayEntry( QModelIndex idx )
{
CFormItem *item = reinterpret_cast< CFormItem* >( idx.internalPointer() );
NLGEORGES::UFormElm &uroot = item->form()->getRootNode();
NLGEORGES::CFormElm *root = static_cast< NLGEORGES::CFormElm* >( &item->form()->getRootNode() );
NLGEORGES::UFormElm *unode;
uroot.getNodeByName( &unode, item->formName().c_str() );
NLGEORGES::CFormElm *cnode = static_cast< NLGEORGES::CFormElm* >( unode );
NLGEORGES::CFormElmArray *arr = static_cast< NLGEORGES::CFormElmArray* >( cnode->getParent() );
NLGEORGES::CFormElm *elm = arr->Elements[ idx.row() ].Element;
Q_EMIT beginResetModel();
std::vector< NLGEORGES::CFormElmArray::CElement >::iterator itr = arr->Elements.begin() + idx.row();
arr->Elements.erase( itr );
delete elm;
item = item->parent();
item->clearChildren();
NLGEORGES::CFormElmArray *celm = arr;
for( int i = 0; i < celm->Elements.size(); i++ )
{
NLGEORGES::CFormElmArray::CElement &e = celm->Elements[ i ];
QString formName = item->formName().c_str();
formName += '[';
formName += QString::number( i );
formName += ']';
QString n;
if( e.Name.empty() )
n = "#" + QString::number( i );
else
n = e.Name.c_str();
item->add( CFormItem::Form, n.toUtf8().constData(), i, formName.toUtf8().constData(), 0, item->form(), false );
}
Q_EMIT endResetModel();
}
void CGeorgesFormModel::renameArrayEntry( QModelIndex idx, const QString &name )
{
CFormItem *item = static_cast< CFormItem* >( idx.internalPointer() );
NLGEORGES::UFormElm *elm;
item->form()->getRootNode().getNodeByName( &elm, item->formName().c_str() );
NLGEORGES::CFormElm *celm = dynamic_cast< NLGEORGES::CFormElm* >( elm );
if( celm == NULL )
return;
NLGEORGES::UFormElm *uparent = celm->getParent();
NLGEORGES::CFormElmArray *cparent = dynamic_cast< NLGEORGES::CFormElmArray* >( uparent );
if( cparent == NULL )
return;
int i = 0;
for( i = 0; i < cparent->Elements.size(); i++ )
{
if( cparent->Elements[ i ].Element == celm )
break;
}
cparent->Elements[ i ].Name = name.toUtf8().constData();
item->setName( name.toUtf8().constData() );
}
/******************************************************************************/

View file

@ -76,6 +76,9 @@ namespace GeorgesQt
}
void arrayResized( const QString &name, int size );
void appendArray( QModelIndex idx );
void deleteArrayEntry( QModelIndex idx );
void renameArrayEntry( QModelIndex idx, const QString &name );
private:
void setupModelData();
@ -100,3 +103,5 @@ namespace GeorgesQt
} /* namespace GeorgesQt */
#endif // GEORGESFORM_MODEL_H

View file

@ -0,0 +1,198 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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/>.
#include "typ_browser_ctrl.h"
#include "3rdparty/qtpropertybrowser/qttreepropertybrowser.h"
#include "3rdparty/qtpropertybrowser/qtvariantproperty.h"
#include "3rdparty/qtpropertybrowser/qtpropertymanager.h"
#include "3rdparty/qtpropertybrowser/qteditorfactory.h"
#include "nel/georges/type.h"
namespace
{
QString typeToString( int v )
{
QString s;
switch( v )
{
case NLGEORGES::UType::UnsignedInt: s = "UnsignedInt"; break;
case NLGEORGES::UType::SignedInt: s = "SignedInt"; break;
case NLGEORGES::UType::Double: s = "Double"; break;
case NLGEORGES::UType::String: s = "String"; break;
case NLGEORGES::UType::Color: s = "Color"; break;
}
return s;
}
QString uitypeToString( int v )
{
QString s;
switch( v )
{
case NLGEORGES::CType::Edit: s = "Edit"; break;
case NLGEORGES::CType::EditSpin: s = "EditSpin"; break;
case NLGEORGES::CType::NonEditableCombo: s = "NonEditableCombo"; break;
case NLGEORGES::CType::FileBrowser: s = "FileBrowser"; break;
case NLGEORGES::CType::BigEdit: s = "BigEdit"; break;
case NLGEORGES::CType::ColorEdit: s = "ColorEdit"; break;
case NLGEORGES::CType::IconWidget: s = "IconWidget"; break;
}
return s;
}
}
TypBrowserCtrl::TypBrowserCtrl( QObject *parent ) :
QObject( parent )
{
m_typ = NULL;
m_variantMgr = new QtVariantPropertyManager( this );
m_variantFactory = new QtVariantEditorFactory( this );
m_enumMgr = new QtEnumPropertyManager( this );
m_enumFactory = new QtEnumEditorFactory( this );
}
TypBrowserCtrl::~TypBrowserCtrl()
{
m_typ = NULL;
m_variantMgr = NULL;
m_variantFactory = NULL;
m_enumMgr = NULL;
m_enumFactory = NULL;
}
void TypBrowserCtrl::load()
{
m_browser->clear();
m_browser->setFactoryForManager( m_variantMgr, m_variantFactory );
m_browser->setFactoryForManager( m_enumMgr, m_enumFactory );
m_typ->Type;
m_typ->UIType;
QtProperty *p = NULL;
p = m_enumMgr->addProperty( "type" );
QStringList l;
l.push_back( "UnsignedInt" );
l.push_back( "SignedInt" );
l.push_back( "Double" );
l.push_back( "String" );
l.push_back( "Color" );
m_enumMgr->setEnumNames( p, l );
m_enumMgr->setValue( p, m_typ->Type );
m_browser->addProperty( p );
p = m_enumMgr->addProperty( "uitype" );
l.clear();
l.push_back( "Edit" );
l.push_back( "EditSpin" );
l.push_back( "NonEditableCombo" );
l.push_back( "FileBrowser" );
l.push_back( "BigEdit" );
l.push_back( "ColorEdit" );
l.push_back( "IconWidget" );
m_enumMgr->setEnumNames( p, l );
m_enumMgr->setValue( p, m_typ->UIType );
m_browser->addProperty( p );
QtVariantProperty *vp = NULL;
vp = m_variantMgr->addProperty( QVariant::String, "default" );
vp->setValue( m_typ->Default.c_str() );
m_browser->addProperty( vp );
vp = m_variantMgr->addProperty( QVariant::String, "min" );
vp->setValue( m_typ->Min.c_str() );
m_browser->addProperty( vp );
vp = m_variantMgr->addProperty( QVariant::String, "max" );
vp->setValue( m_typ->Max.c_str() );
m_browser->addProperty( vp );
vp = m_variantMgr->addProperty( QVariant::String, "increment" );
vp->setValue( m_typ->Increment.c_str() );
m_browser->addProperty( vp );
enableMgrConnections();
}
void TypBrowserCtrl::onVariantValueChanged( QtProperty *p, const QVariant &v )
{
QString n = p->propertyName();
if( n == "default" )
{
m_typ->Default = v.toString().toUtf8().constData();
}
else
if( n == "min" )
{
m_typ->Min = v.toString().toUtf8().constData();
}
else
if( n == "max" )
{
m_typ->Max = v.toString().toUtf8().constData();
}
else
if( n == "increment" )
{
m_typ->Increment = v.toString().toUtf8().constData();
}
else
return;
Q_EMIT modified( n, v.toString().toUtf8().constData() );
}
void TypBrowserCtrl::onEnumValueChanged( QtProperty *p, int v )
{
QString n = p->propertyName();
QString value;
if( n == "type" )
{
m_typ->Type = NLGEORGES::UType::TType( v );
value = typeToString( v );
}
else
if( n == "uitype" )
{
m_typ->UIType = NLGEORGES::CType::TUI( v );
value = uitypeToString( v );
}
else
return;
Q_EMIT modified( n, value );
}
void TypBrowserCtrl::enableMgrConnections()
{
connect( m_variantMgr, SIGNAL( valueChanged( QtProperty*, const QVariant& ) ), this, SLOT( onVariantValueChanged( QtProperty*, const QVariant& ) ) );
connect( m_enumMgr, SIGNAL( valueChanged( QtProperty*, int ) ), this, SLOT( onEnumValueChanged( QtProperty*, int ) ) );
}

View file

@ -0,0 +1,69 @@
// Ryzom Core Studio - Georges Editor Plugin
//
// Copyright (C) 2014 Laszlo Kis-Adam
// Copyright (C) 2010 Ryzom Core <http://ryzomcore.org/>
//
// 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 TYP_BROWSER_CTRL
#define TYP_BROWSER_CTRL
#include <QObject>
class QtVariantPropertyManager;
class QtVariantEditorFactory;
class QtTreePropertyBrowser;
class QtEnumPropertyManager;
class QtEnumEditorFactory;
class QVariant;
class QtProperty;
namespace NLGEORGES
{
class CType;
}
class TypBrowserCtrl : public QObject
{
Q_OBJECT
public:
TypBrowserCtrl( QObject *parent = NULL );
~TypBrowserCtrl();
void load();
void setTyp( NLGEORGES::CType *typ ){ m_typ = typ; }
void setBrowser( QtTreePropertyBrowser *browser ){ m_browser = browser; }
Q_SIGNALS:
void modified( const QString &k, const QString &v );
private Q_SLOTS:
void onVariantValueChanged( QtProperty *p, const QVariant &v );
void onEnumValueChanged( QtProperty *p, int v );
private:
void enableMgrConnections();
NLGEORGES::CType *m_typ;
QtTreePropertyBrowser *m_browser;
QtVariantPropertyManager *m_variantMgr;
QtVariantEditorFactory *m_variantFactory;
QtEnumPropertyManager *m_enumMgr;
QtEnumEditorFactory *m_enumFactory;
};
#endif