diff --git a/code/nel/include/nel/georges/form_elm.h b/code/nel/include/nel/georges/form_elm.h index 5453717a2..48118b7d8 100644 --- a/code/nel/include/nel/georges/form_elm.h +++ b/code/nel/include/nel/georges/form_elm.h @@ -454,6 +454,7 @@ public: // Set the value, the elt been used void setValue (const char *value); + std::string getValue() const; private: // The value diff --git a/code/nel/src/georges/form_elm.cpp b/code/nel/src/georges/form_elm.cpp index 518782342..03d39967a 100644 --- a/code/nel/src/georges/form_elm.cpp +++ b/code/nel/src/georges/form_elm.cpp @@ -3056,6 +3056,13 @@ void CFormElmAtom::setValue (const char *value) // *************************************************************************** +std::string CFormElmAtom::getValue() const +{ + return Value; +} + +// *************************************************************************** + void CFormElmAtom::getFormName (std::string &result, const CFormElm *child) const { // Must be NULL diff --git a/code/studio/src/plugins/georges_editor/CMakeLists.txt b/code/studio/src/plugins/georges_editor/CMakeLists.txt index 0f0cbc1e0..bf7e6e0c9 100644 --- a/code/studio/src/plugins/georges_editor/CMakeLists.txt +++ b/code/studio/src/plugins/georges_editor/CMakeLists.txt @@ -23,6 +23,7 @@ SET(OVQT_PLUG_GEORGES_EDITOR_HDR georges_editor_plugin.h filepath_property_manager.h typ_browser_ctrl.h georges_typ_dialog.h + georges_dock_widget.h ) SET(OVQT_PLUG_GEORGES_EDITOR_UIS georges_editor_form.ui diff --git a/code/studio/src/plugins/georges_editor/browser_ctrl.cpp b/code/studio/src/plugins/georges_editor/browser_ctrl.cpp index 2788bd00a..ad947edcf 100644 --- a/code/studio/src/plugins/georges_editor/browser_ctrl.cpp +++ b/code/studio/src/plugins/georges_editor/browser_ctrl.cpp @@ -20,6 +20,7 @@ #include "browser_ctrl.h" #include "3rdparty/qtpropertybrowser/qttreepropertybrowser.h" #include "3rdparty/qtpropertybrowser/qtvariantproperty.h" +#include "filepath_property_manager.h" #include #include "nel/georges/form.h" @@ -37,6 +38,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& ) ) ); + connect( m_pvt, SIGNAL( vstructChanged( const QString& ) ), this, SLOT( onVStructChanged( const QString& ) ) ); } BrowserCtrl::~BrowserCtrl() @@ -68,6 +70,11 @@ void BrowserCtrl::onValueChanged( const QString &key, const QString &value ) Q_EMIT valueChanged( key, value ); } +void BrowserCtrl::onFileValueChanged( QtProperty *p, const QString &value ) +{ + m_pvt->onFileValueChanged( p, value ); +} + void BrowserCtrl::onArrayResized( const QString &name, int size ) { Q_EMIT arrayResized( name, size ); @@ -78,19 +85,30 @@ void BrowserCtrl::onModified() Q_EMIT modified(); } +void BrowserCtrl::onVStructChanged( const QString &name ) +{ + Q_EMIT vstructChanged( name ); +} + void BrowserCtrl::enableMgrConnections() { QtVariantPropertyManager *mgr = m_pvt->manager(); + FileManager *fileMgr = m_pvt->fileManager(); connect( mgr, SIGNAL( valueChanged( QtProperty*, const QVariant & ) ), this, SLOT( onValueChanged( QtProperty*, const QVariant & ) ) ); + connect( fileMgr, SIGNAL( valueChanged( QtProperty*, const QString & ) ), + this, SLOT( onFileValueChanged( QtProperty*, const QString & ) ) ); } void BrowserCtrl::disableMgrConnections() { QtVariantPropertyManager *mgr = m_pvt->manager(); + FileManager *fileMgr = m_pvt->fileManager(); disconnect( mgr, SIGNAL( valueChanged( QtProperty*, const QVariant & ) ), this, SLOT( onValueChanged( QtProperty*, const QVariant & ) ) ); + disconnect( fileMgr, SIGNAL( valueChanged( QtProperty*, const QString & ) ), + this, SLOT( onFileValueChanged( QtProperty*, const QString & ) ) ); } diff --git a/code/studio/src/plugins/georges_editor/browser_ctrl.h b/code/studio/src/plugins/georges_editor/browser_ctrl.h index 25aeaf49f..a70b57356 100644 --- a/code/studio/src/plugins/georges_editor/browser_ctrl.h +++ b/code/studio/src/plugins/georges_editor/browser_ctrl.h @@ -48,12 +48,15 @@ Q_SIGNALS: void arrayResized( const QString &name, int size ); void modified(); void valueChanged( const QString &key, const QString &value ); + void vstructChanged( const QString &name ); private Q_SLOTS: void onValueChanged( QtProperty *p, const QVariant &value ); void onValueChanged( const QString &key, const QString &value ); + void onFileValueChanged( QtProperty *p, const QString &value ); void onArrayResized( const QString &name, int size ); void onModified(); + void onVStructChanged( const QString &name ); private: void enableMgrConnections(); diff --git a/code/studio/src/plugins/georges_editor/browser_ctrl_pvt.cpp b/code/studio/src/plugins/georges_editor/browser_ctrl_pvt.cpp index 492258c71..484649e52 100644 --- a/code/studio/src/plugins/georges_editor/browser_ctrl_pvt.cpp +++ b/code/studio/src/plugins/georges_editor/browser_ctrl_pvt.cpp @@ -24,16 +24,31 @@ #include "nel/georges/form.h" +#include "filepath_property_manager.h" namespace { + const unsigned int FILEBROWSER = 9000000; QVariant::Type getValueType( const NLGEORGES::UType *typ ) { QVariant::Type t = QVariant::String; + bool file = false; + NLGEORGES::UType::TType ttyp = NLGEORGES::UType::String; if( typ != NULL ) + { ttyp = typ->getType(); + + const NLGEORGES::CType *ctyp = static_cast< const NLGEORGES::CType* >( typ ); + if(ctyp->UIType == NLGEORGES::CType::FileBrowser ) + { + file = true; + } + } + + if( file ) + return QVariant::Type( FILEBROWSER ); switch( ttyp ) { @@ -47,12 +62,111 @@ namespace return t; } + QVariant::Type getValueTypeFromDfn( NLGEORGES::CFormElmStruct *st, int idx ) + { + NLGEORGES::CFormDfn *cdfn = st->FormDfn; + NLGEORGES::CFormDfn::CEntry entry = cdfn->getEntry( idx ); + return getValueType( entry.getTypePtr() ); + } + + + QVariant::Type getValueTypeFromDfn( NLGEORGES::CFormElmAtom *atom ) + { + QVariant::Type t = QVariant::String; + + NLGEORGES::CFormElm *cparent = static_cast< NLGEORGES::CFormElm* >( atom->getParent() ); + + if( cparent->isArray() ) + { + NLGEORGES::CFormElmStruct *aparent = static_cast< NLGEORGES::CFormElmStruct* >( cparent->getParent() ); + NLGEORGES::CFormDfn *cdfn = static_cast< NLGEORGES::CFormDfn* >( aparent->getStructDfn() ); + + int idx = -1; + for( idx = 0; idx < aparent->Elements.size(); idx++ ) + { + if( aparent->Elements[ idx ].Element == cparent ) + break; + } + + NLGEORGES::CFormDfn::CEntry entry = cdfn->getEntry( idx ); + return getValueType( entry.getTypePtr() ); + } + else + if( cparent->isStruct() ) + { + NLGEORGES::CFormElmStruct *sparent = static_cast< NLGEORGES::CFormElmStruct* >( cparent ); + NLGEORGES::CFormDfn *cdfn = static_cast< NLGEORGES::CFormDfn* >( cparent->getStructDfn() ); + + int idx = -1; + for( idx = 0; idx < sparent->Elements.size(); idx++ ) + { + if( sparent->Elements[ idx ].Element == atom ) + break; + } + + NLGEORGES::CFormDfn::CEntry entry = cdfn->getEntry( idx ); + return getValueType( entry.getTypePtr() ); + } + + return t; + } + NLGEORGES::UFormElm* getGeorgesNode( GeorgesQt::CFormItem *item ) { NLGEORGES::UFormElm *n = NULL; item->form()->getRootNode().getNodeByName( &n, item->formName().c_str() ); return n; } + + // Get the data from a string, and pack it into a QVariant properly + // Needed for some special values, like color + // which are represented differently in Nel and Qt + QVariant stringToVariant( const QString &value, QVariant::Type type ) + { + QVariant v; + + if( type == QVariant::Color ) + { + QStringList l = value.split( ',' ); + if( l.size() != 3 ) + v = ""; + else + { + QColor c; + c.setRed( l[ 0 ].toInt() ); + c.setGreen( l[ 1 ].toInt() ); + c.setBlue( l[ 2 ].toInt() ); + v = c; + } + + } + else + v = value; + + return v; + } + + // The inverse function of stringToVariant + // Unpacks the data from a QVariant properly + QString variantToString( const QVariant &value ) + { + QString v; + + if( value.type() == QVariant::Color ) + { + QColor c = value.value< QColor >(); + v += QString::number( c.red() ); + v += ','; + v += QString::number( c.green() ); + v += ','; + v += QString::number( c.blue() ); + } + else + v = value.toString(); + + return v; + } + } @@ -61,6 +175,8 @@ QObject( parent ) { mgr = new QtVariantPropertyManager(); factory = new QtVariantEditorFactory(); + m_fileMgr = new FileManager( this ); + m_fileFactory = new FileEditFactory( this ); m_rootNode = NULL; } @@ -70,30 +186,71 @@ BrowserCtrlPvt::~BrowserCtrlPvt() mgr = NULL; delete factory; factory = NULL; + m_fileMgr = NULL; + m_fileFactory = NULL; m_browser = NULL; } -void BrowserCtrlPvt::setupAtom( NLGEORGES::CFormElmStruct::CFormElmStructElm &elm ) +NLGEORGES::UFormElm* BrowserCtrlPvt::getNode( const QString &name ) { + NLGEORGES::UFormElm *node = NULL; + m_rootNode->getNodeByName( &node, name.toUtf8().constData(), NULL, true ); + + return node; +} + +NLGEORGES::UFormElm* BrowserCtrlPvt::getCurrentNode() +{ + return getNode( m_currentNode.name ); +} + +void BrowserCtrlPvt::setupAtom( NLGEORGES::CFormElmStruct *st, int idx ) +{ + NLGEORGES::CFormElmStruct::CFormElmStructElm &elm = st->Elements[ idx ]; + if( ( elm.Element != NULL ) && !elm.Element->isAtom() ) + return; + + if( elm.Element == NULL ) + { + NLGEORGES::CFormDfn::CEntry &entry = st->FormDfn->getEntry( idx ); + if( entry.getArrayFlag() ) + return; + + if( entry.getType() == NLGEORGES::UFormDfn::EntryVirtualDfn ) + return; + } + QString key = elm.Name.c_str(); QString value = ""; QVariant::Type t = QVariant::String; + // If the atom exists, get the value from it + // Otherwise just get the type so we can set up the proper editor if( elm.Element != NULL ) { - t = getValueType( elm.Element->getType() ); + // Check if there's a type, if not get it from the Dfn + const NLGEORGES::CType *type = elm.Element->getType(); + if( type != NULL ) + t = getValueType( elm.Element->getType() ); + else + t = getValueTypeFromDfn( st, idx ); std::string formName; elm.Element->getFormName( formName, NULL ); std::string v; m_rootNode->getValueByName( v, formName.c_str(), NLGEORGES::UFormElm::NoEval, NULL, 0 ); - value = v.c_str(); + value = stringToVariant( v.c_str(), t ).toString(); + } + else + { + t = getValueTypeFromDfn( st, idx ); } - QtVariantProperty *p = mgr->addProperty( t, key ); - p->setValue( value ); - m_browser->addProperty( p ); + if( t == QVariant::Type( FILEBROWSER ) ) + addFileProperty( key, value ); + else + addVariantProperty( t, key, value ); } void BrowserCtrlPvt::setupStruct( NLGEORGES::UFormElm *node ) @@ -102,18 +259,7 @@ void BrowserCtrlPvt::setupStruct( NLGEORGES::UFormElm *node ) for( int i = 0; i < st->Elements.size(); i++ ) { - NLGEORGES::CFormElmStruct::CFormElmStructElm &elm = st->Elements[ i ]; - if( ( elm.Element != NULL ) && !elm.Element->isAtom() ) - continue; - - if( elm.Element == NULL ) - { - NLGEORGES::CFormDfn::CEntry &entry = st->FormDfn->getEntry( i ); - if( entry.getArrayFlag() ) - continue; - } - - setupAtom( elm ); + setupAtom( st, i ); } } @@ -123,11 +269,24 @@ void BrowserCtrlPvt::setupStruct( GeorgesQt::CFormItem *node ) if( n == NULL ) return; - m_currentNode.p = n; - setupStruct( n ); } +void BrowserCtrlPvt::setupVStruct( GeorgesQt::CFormItem *node ) +{ + NLGEORGES::UFormElm *n = getGeorgesNode( node ); + + QtProperty *p = NULL; + p = addFileProperty( "Dfn filename", "" ); + + if( n != NULL ) + { + NLGEORGES::CFormElmVirtualStruct *vs = static_cast< NLGEORGES::CFormElmVirtualStruct* >( n ); + m_fileMgr->setValue( p, vs->DfnFilename.c_str() ); + setupStruct( n ); + } +} + void BrowserCtrlPvt::setupArray( GeorgesQt::CFormItem *node ) { NLGEORGES::UFormElm *n = getGeorgesNode( node ); @@ -137,28 +296,61 @@ void BrowserCtrlPvt::setupArray( GeorgesQt::CFormItem *node ) { 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 ); + QtVariantProperty *p = addVariantProperty( QVariant::Int, key, size ); +} + +void BrowserCtrlPvt::setupAtom( GeorgesQt::CFormItem *node ) +{ + NLGEORGES::UFormElm *n = getGeorgesNode( node ); + + if( n == NULL ) + return; + + NLGEORGES::CFormElmAtom *atom = static_cast< NLGEORGES::CFormElmAtom* >( n ); + std::string v = atom->getValue(); + + const NLGEORGES::CType *t = atom->getType(); + QVariant::Type tt = QVariant::String; + if( t != NULL ) + { + tt = getValueType( t ); + } + else + { + tt = getValueTypeFromDfn( atom ); + } + + if( tt == QVariant::Type( FILEBROWSER ) ) + addFileProperty( "value", v.c_str() ); + else + addVariantProperty( tt, "value", v.c_str() ); } void BrowserCtrlPvt::setupNode( GeorgesQt::CFormItem *node ) { m_currentNode.clear(); m_currentNode.name = node->formName().c_str(); - + m_currentNode.type = node->type(); + m_rootNode = dynamic_cast< NLGEORGES::CFormElm* >( &(node->form()->getRootNode()) ); if( node->isArray() ) setupArray( node ); else + if( node->isStruct() ) setupStruct( node ); + else + if( node->isVStruct() ) + setupVStruct( node ); + else + if( node->isAtom() ) + setupAtom( node ); m_browser->setFactoryForManager( mgr, factory ); + m_browser->setFactoryForManager( m_fileMgr, m_fileFactory ); } void BrowserCtrlPvt::clear() @@ -171,10 +363,13 @@ void BrowserCtrlPvt::clear() void BrowserCtrlPvt::onStructValueChanged( QtProperty *p, const QVariant &value ) { std::string k = p->propertyName().toUtf8().constData(); - std::string v = value.toString().toUtf8().constData(); + std::string v; + v = variantToString( value ).toUtf8().constData(); + + NLGEORGES::UFormElm *node = getCurrentNode(); bool created = false; - m_currentNode.p->setValueByName( v.c_str(), k.c_str(), &created ); + node->setValueByName( v.c_str(), k.c_str(), &created ); QString key = m_currentNode.name + "." + p->propertyName(); @@ -182,6 +377,43 @@ void BrowserCtrlPvt::onStructValueChanged( QtProperty *p, const QVariant &value Q_EMIT valueChanged( key, value.toString() ); } +void BrowserCtrlPvt::onVStructValueChanged( QtProperty *p, const QVariant &value ) +{ + if( p->propertyName() != "Dfn filename" ) + { + onStructValueChanged( p, value ); + return; + } + + NLGEORGES::CFormElmVirtualStruct *vs = static_cast< NLGEORGES::CFormElmVirtualStruct* >( getCurrentNode() ); + if( vs == NULL ) + { + 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; + + vs = static_cast< NLGEORGES::CFormElmVirtualStruct* >( node ); + } + + vs->DfnFilename = value.toString().toUtf8().constData(); + + QString key = m_currentNode.name + "." + p->propertyName(); + + Q_EMIT modified(); + Q_EMIT valueChanged( key, value.toString() ); + Q_EMIT vstructChanged( m_currentNode.name ); +} + void BrowserCtrlPvt::createArray() { const NLGEORGES::CFormDfn *parentDfn; @@ -198,8 +430,6 @@ void BrowserCtrlPvt::createArray() 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 ); @@ -219,7 +449,10 @@ void BrowserCtrlPvt::onArrayValueChanged( QtProperty *p, const QVariant &value ) if( newSize < 0 ) return; - if( m_currentNode.p == NULL ) + + NLGEORGES::UFormElm *node = getCurrentNode(); + + if( node == NULL ) { if( newSize != 1 ) return; @@ -227,7 +460,7 @@ void BrowserCtrlPvt::onArrayValueChanged( QtProperty *p, const QVariant &value ) return; } - NLGEORGES::CFormElmArray *arr = static_cast< NLGEORGES::CFormElmArray* >( m_currentNode.p ); + NLGEORGES::CFormElmArray *arr = static_cast< NLGEORGES::CFormElmArray* >( node ); std::string formName; arr->getFormName( formName, NULL ); @@ -276,27 +509,87 @@ 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::onAtomValueChanged( QtProperty *p, const QVariant &value ) +{ + NLGEORGES::CFormElmAtom *atom = static_cast< NLGEORGES::CFormElmAtom* >( getCurrentNode() ); + atom->setValue( value.toString().toUtf8() ); + + Q_EMIT modified(); + Q_EMIT valueChanged( m_currentNode.name, value.toString() ); } void BrowserCtrlPvt::onValueChanged( QtProperty *p, const QVariant &value ) { - if( m_currentNode.p == NULL ) - { - if( m_currentNode.name.isEmpty() ) - return; - - onArrayValueChanged( p, value ); - return; - } - - if( m_currentNode.p->isStruct() ) + if( m_currentNode.type == GeorgesQt::CFormItem::TYPE_VSTRUCT ) + onVStructValueChanged( p, value ); + else + if( m_currentNode.type == GeorgesQt::CFormItem::TYPE_STRUCT ) onStructValueChanged( p, value ); else - if( m_currentNode.p->isArray() ) + if( m_currentNode.type == GeorgesQt::CFormItem::TYPE_ARRAY ) onArrayValueChanged( p, value ); + else + if( m_currentNode.type == GeorgesQt::CFormItem::TYPE_ATOM ) + onAtomValueChanged( p, value ); +} + +void BrowserCtrlPvt::onFileValueChanged( QtProperty *p, const QString &value ) +{ + QString v = value; + QFileInfo info( value ); + if( !info.exists() ) + return; + + v = info.fileName(); + blockSignals( true ); + m_fileMgr->setValue( p, v ); + blockSignals( false ); + + if( m_currentNode.type == GeorgesQt::CFormItem::TYPE_VSTRUCT ) + onVStructValueChanged( p, v ); + else + if( m_currentNode.type == GeorgesQt::CFormItem::TYPE_STRUCT ) + onStructValueChanged( p, v ); + else + if( m_currentNode.type == GeorgesQt::CFormItem::TYPE_ATOM ) + onAtomValueChanged( p, v ); +} + +QtVariantProperty* BrowserCtrlPvt::addVariantProperty( QVariant::Type type, const QString &key, const QVariant &value ) +{ + QtVariantProperty *p = mgr->addProperty( type, key ); + + // Remove the color sub-properties, so they don't get triggered on value change + if( type == QVariant::Color ) + { + QList< QtProperty* > sp = p->subProperties(); + QListIterator< QtProperty* > itr( sp ); + while( itr.hasNext() ) + { + QtProperty *prop = itr.next(); + p->removeSubProperty( prop ); + delete prop; + } + sp.clear(); + } + + p->setValue( value ); + m_browser->addProperty( p ); + + return p; +} + +QtProperty* BrowserCtrlPvt::addFileProperty( const QString &key, const QString &value ) +{ + QtProperty *p = m_fileMgr->addProperty( key ); + + m_fileMgr->setValue( p, value ); + m_browser->addProperty( p ); + + return p; } + diff --git a/code/studio/src/plugins/georges_editor/browser_ctrl_pvt.h b/code/studio/src/plugins/georges_editor/browser_ctrl_pvt.h index bebb65c3e..2f9785411 100644 --- a/code/studio/src/plugins/georges_editor/browser_ctrl_pvt.h +++ b/code/studio/src/plugins/georges_editor/browser_ctrl_pvt.h @@ -38,6 +38,10 @@ class QtVariantEditorFactory; class QtTreePropertyBrowser; class QVariant; class QtProperty; +class QtVariantProperty; + +class FileManager; +class FileEditFactory; class BrowserCtrlPvt : public QObject { @@ -49,8 +53,10 @@ public: void clear(); void setupNode( GeorgesQt::CFormItem *node ); void onValueChanged( QtProperty *p, const QVariant &value ); + void onFileValueChanged( QtProperty *p, const QString &value ); QtVariantPropertyManager* manager() const{ return mgr; } + FileManager* fileManager() const{ return m_fileMgr; } void setRootNode( NLGEORGES::CFormElm *root ){ m_rootNode = root; } void setBrowser( QtTreePropertyBrowser *browser ){ m_browser = browser; } @@ -58,22 +64,36 @@ Q_SIGNALS: void arrayResized( const QString &name, int size ); void modified(); void valueChanged( const QString &key, const QString &value ); + void vstructChanged( const QString &name ); private: + NLGEORGES::UFormElm* getNode( const QString &name ); + NLGEORGES::UFormElm* getCurrentNode(); + void setupStruct( NLGEORGES::UFormElm *node ); - void setupAtom( NLGEORGES::CFormElmStruct::CFormElmStructElm &elm ); + void setupAtom( NLGEORGES::CFormElmStruct *st, int idx ); void setupStruct( GeorgesQt::CFormItem *node ); + void setupVStruct( GeorgesQt::CFormItem *node ); void setupArray( GeorgesQt::CFormItem *node ); + void setupAtom( GeorgesQt::CFormItem *node ); void onStructValueChanged( QtProperty *p, const QVariant &value ); + void onVStructValueChanged( QtProperty *p, const QVariant &value ); void onArrayValueChanged( QtProperty *p, const QVariant &value ); + void onAtomValueChanged( QtProperty *p, const QVariant &value ); void createArray(); + + QtVariantProperty* addVariantProperty( QVariant::Type type, const QString &key, const QVariant &value ); + QtProperty *addFileProperty( const QString &key, const QString &value ); QtVariantPropertyManager *mgr; QtVariantEditorFactory *factory; QtTreePropertyBrowser *m_browser; + FileManager *m_fileMgr; + FileEditFactory *m_fileFactory; + QString m_currentNodeName; NLGEORGES::CFormElm *m_rootNode; @@ -86,12 +106,12 @@ private: void clear() { - p = NULL; + type = -1; name = ""; } QString name; - NLGEORGES::UFormElm *p; + int type; }; CurrentNode m_currentNode; diff --git a/code/studio/src/plugins/georges_editor/dfn_browser_ctrl.cpp b/code/studio/src/plugins/georges_editor/dfn_browser_ctrl.cpp index 9e2c86a56..c406b549a 100644 --- a/code/studio/src/plugins/georges_editor/dfn_browser_ctrl.cpp +++ b/code/studio/src/plugins/georges_editor/dfn_browser_ctrl.cpp @@ -26,6 +26,8 @@ #include "nel/georges/form_dfn.h" +#include + namespace { enum EntryEnum @@ -248,7 +250,15 @@ void DFNBrowserCtrl::onEnumValueChanged( QtProperty *p, int v ) void DFNBrowserCtrl::onFileValueChanged( QtProperty *p, const QString &v ) { NLGEORGES::CFormDfn::CEntry &entry = m_dfn->getEntry( m_idx ); - entry.setFilename( v.toUtf8().constData() ); + QFileInfo info( v ); + if( !info.exists() ) + return; + + entry.setFilename( info.fileName().toUtf8().constData() ); + + blockSignals( true ); + m_fileMgr->setValue( p, info.fileName() ); + blockSignals( false ); Q_EMIT valueChanged( p->propertyName(), v ); } diff --git a/code/studio/src/plugins/georges_editor/formitem.cpp b/code/studio/src/plugins/georges_editor/formitem.cpp index 8cd479961..939ec4cf4 100644 --- a/code/studio/src/plugins/georges_editor/formitem.cpp +++ b/code/studio/src/plugins/georges_editor/formitem.cpp @@ -40,7 +40,7 @@ namespace GeorgesQt _StructId = 0; _Slot = 0; _Type = Null; - _Array = false; + _TType = TYPE_ATOM; } CFormItem::~CFormItem() @@ -113,7 +113,10 @@ namespace GeorgesQt bool CFormItem::isArray() { - return _Array; + if( _TType == TYPE_ARRAY ) + return true; + else + return false; } bool CFormItem::isArrayMember() @@ -124,6 +127,30 @@ namespace GeorgesQt return parentItem->isArray(); } + bool CFormItem::isStruct() + { + if( _TType == TYPE_STRUCT ) + return true; + else + return false; + } + + bool CFormItem::isVStruct() + { + if( _TType == TYPE_VSTRUCT ) + return true; + else + return false; + } + + bool CFormItem::isAtom() + { + if( _TType == TYPE_ATOM ) + return true; + else + return false; + } + QIcon CFormItem::getItemImage(CFormItem *rootItem) { if(_Type == CFormItem::Null) @@ -211,7 +238,14 @@ namespace GeorgesQt childItems.clear(); } - CFormItem *CFormItem::add (TSub type, const char *name, uint structId, const char *formName, uint slot, NLGEORGES::UForm *formPtr, bool isArray) + void CFormItem::removeChild( int idx ) + { + CFormItem *item = childItems[ idx ]; + childItems.removeAt( idx ); + delete item; + } + + CFormItem *CFormItem::add (TSub type, const char *name, uint structId, const char *formName, uint slot, NLGEORGES::UForm *formPtr, TType itemType ) { CFormItem *newNode = new CFormItem(); newNode->_Type = type; @@ -221,7 +255,7 @@ namespace GeorgesQt newNode->_FormName = formName; newNode->_Slot = slot; newNode->m_form = formPtr; - newNode->_Array = isArray; + newNode->_TType = itemType; appendChild(newNode); return newNode; diff --git a/code/studio/src/plugins/georges_editor/formitem.h b/code/studio/src/plugins/georges_editor/formitem.h index cd67d1b21..a0aabfc10 100644 --- a/code/studio/src/plugins/georges_editor/formitem.h +++ b/code/studio/src/plugins/georges_editor/formitem.h @@ -41,12 +41,20 @@ namespace GeorgesQt Form, // This node is a form }; + enum TType + { + TYPE_ARRAY, + TYPE_STRUCT, + TYPE_VSTRUCT, + TYPE_ATOM + }; + CFormItem(); ~CFormItem(); void appendChild(CFormItem *child); - CFormItem *add (TSub type, const char *name, uint structId, const char *formName, uint slot, NLGEORGES::UForm *formPtr, bool isArray ); + CFormItem *add (TSub type, const char *name, uint structId, const char *formName, uint slot, NLGEORGES::UForm *formPtr, TType itemType ); CFormItem *child(int row); int childCount() const; @@ -69,6 +77,11 @@ namespace GeorgesQt bool isEditable(int column); bool isArray(); bool isArrayMember(); + bool isStruct(); + bool isVStruct(); + bool isAtom(); + + TType type() const{ return _TType; } QIcon getItemImage(CFormItem *rootItem); @@ -76,6 +89,8 @@ namespace GeorgesQt void clearChildren(); + void removeChild( int idx ); + bool rootItem() const{ if( parentItem == NULL ) return true; @@ -95,7 +110,7 @@ namespace GeorgesQt std::string _FormName; TSub _Type; uint _Slot; - bool _Array; + TType _TType; }; // CFormItem diff --git a/code/studio/src/plugins/georges_editor/georges_dfn_dialog.cpp b/code/studio/src/plugins/georges_editor/georges_dfn_dialog.cpp index d7d329dac..c7244273e 100644 --- a/code/studio/src/plugins/georges_editor/georges_dfn_dialog.cpp +++ b/code/studio/src/plugins/georges_editor/georges_dfn_dialog.cpp @@ -82,6 +82,8 @@ bool GeorgesDFNDialog::load( const QString &fileName ) m_fileName = fileName; + connect(m_ui.commentsEdit, SIGNAL(textChanged()), this, SLOT(onCommentsEdited())); + return true; } @@ -91,6 +93,7 @@ void GeorgesDFNDialog::write() setWindowTitle( windowTitle().remove( "*" ) ); m_pvt->dfn->Header.Log = m_ui.logEdit->toPlainText().toUtf8().constData(); + m_pvt->dfn->Header.Comments = m_ui.commentsEdit->toPlainText().toUtf8().constData(); NLMISC::COFile file; if( !file.open( m_fileName.toUtf8().constData(), false, true, false ) ) @@ -115,6 +118,8 @@ void GeorgesDFNDialog::newDocument( const QString &fileName ) m_pvt->dfn = new NLGEORGES::CFormDfn(); loadDfn(); + + log( "Created" ); } void GeorgesDFNDialog::onAddClicked() @@ -176,6 +181,11 @@ void GeorgesDFNDialog::onValueChanged( const QString &key, const QString &value } } +void GeorgesDFNDialog::onCommentsEdited() +{ + onModified(); +} + void GeorgesDFNDialog::loadDfn() { m_pvt->ctrl->setDFN( m_pvt->dfn ); diff --git a/code/studio/src/plugins/georges_editor/georges_dfn_dialog.h b/code/studio/src/plugins/georges_editor/georges_dfn_dialog.h index 2d6dc4113..edb67144c 100644 --- a/code/studio/src/plugins/georges_editor/georges_dfn_dialog.h +++ b/code/studio/src/plugins/georges_editor/georges_dfn_dialog.h @@ -44,6 +44,7 @@ private Q_SLOTS: void onCurrentRowChanged( int row ); void onValueChanged( const QString& key, const QString &value ); + void onCommentsEdited(); private: void loadDfn(); @@ -53,7 +54,6 @@ private: Ui::GeorgesDFNDialog m_ui; GeorgesDFNDialogPvt *m_pvt; - QString m_fileName; }; #endif diff --git a/code/studio/src/plugins/georges_editor/georges_dfn_dialog.ui b/code/studio/src/plugins/georges_editor/georges_dfn_dialog.ui index 3cbdb7419..70b5bd265 100644 --- a/code/studio/src/plugins/georges_editor/georges_dfn_dialog.ui +++ b/code/studio/src/plugins/georges_editor/georges_dfn_dialog.ui @@ -98,7 +98,7 @@ - Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + Qt::TextEditorInteraction diff --git a/code/studio/src/plugins/georges_editor/georges_dock_widget.cpp b/code/studio/src/plugins/georges_editor/georges_dock_widget.cpp index 921f59e0b..e031fbc8f 100644 --- a/code/studio/src/plugins/georges_editor/georges_dock_widget.cpp +++ b/code/studio/src/plugins/georges_editor/georges_dock_widget.cpp @@ -17,6 +17,7 @@ // along with this program. If not, see . #include "georges_dock_widget.h" +#include GeorgesDockWidget::GeorgesDockWidget( QWidget *parent ) : QDockWidget( parent ) @@ -29,6 +30,31 @@ GeorgesDockWidget::~GeorgesDockWidget() { } +void GeorgesDockWidget::closeEvent( QCloseEvent *e ) +{ + if( isModified() ) + { + QString title = windowTitle(); + title.remove( '*' ); + + int reply = QMessageBox::question( this, + tr( "Closing dialog" ), + title + tr( " has been modified.\nWould you like to save the changes?" ), + QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel ); + + if( reply == QMessageBox::Cancel ) + { + e->ignore(); + return; + } + + if( reply == QMessageBox::Yes ) + write(); + } + + Q_EMIT closing( this ); +} + QString GeorgesDockWidget::buildLogMsg( const QString &msg ) { QString user = getenv( "USER" ); diff --git a/code/studio/src/plugins/georges_editor/georges_dock_widget.h b/code/studio/src/plugins/georges_editor/georges_dock_widget.h index 53e4f6841..d7f80dff1 100644 --- a/code/studio/src/plugins/georges_editor/georges_dock_widget.h +++ b/code/studio/src/plugins/georges_editor/georges_dock_widget.h @@ -25,6 +25,7 @@ class QUndoStack; class GeorgesDockWidget : public QDockWidget { + Q_OBJECT public: GeorgesDockWidget( QWidget *parent = NULL ); ~GeorgesDockWidget(); @@ -39,6 +40,12 @@ public: virtual bool load( const QString &fileName ) = 0; virtual void write() = 0; +protected: + void closeEvent( QCloseEvent *e ); + +Q_SIGNALS: + void closing( GeorgesDockWidget *d ); + protected: QString buildLogMsg( const QString &msg ); virtual void log( const QString &msg ) = 0; diff --git a/code/studio/src/plugins/georges_editor/georges_editor_form.cpp b/code/studio/src/plugins/georges_editor/georges_editor_form.cpp index 54028b5a4..4f4b814ec 100644 --- a/code/studio/src/plugins/georges_editor/georges_editor_form.cpp +++ b/code/studio/src/plugins/georges_editor/georges_editor_form.cpp @@ -252,7 +252,7 @@ namespace GeorgesQt m_lastActiveDock = w; m_dockedWidgets.append(w); - connect(m_dockedWidgets.last(), SIGNAL(closing()), this, SLOT(closingTreeView())); + connect( w, SIGNAL( closing( GeorgesDockWidget* ) ), this, SLOT( dialogClosing( GeorgesDockWidget* ) ) ); 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. @@ -265,6 +265,7 @@ namespace GeorgesQt m_mainDock->addDockWidget(Qt::RightDockWidgetArea, m_dockedWidgets.last()); } + QCoreApplication::processEvents(); w->raise(); } @@ -336,12 +337,16 @@ namespace GeorgesQt addGeorgesWidget( w ); } - void GeorgesEditorForm::closingTreeView() + void GeorgesEditorForm::dialogClosing( GeorgesDockWidget *d ) { - //qDebug() << "closingTreeView"; - m_dockedWidgets.removeAll(qobject_cast(sender())); - if (qobject_cast(sender()) == m_lastActiveDock) - m_lastActiveDock = 0; + m_dockedWidgets.removeAll( d ); + + if( m_dockedWidgets.size() == 0 ) + m_lastActiveDock = NULL; + else + m_lastActiveDock = m_dockedWidgets.last(); + + delete d; } void GeorgesEditorForm::setModified () diff --git a/code/studio/src/plugins/georges_editor/georges_editor_form.h b/code/studio/src/plugins/georges_editor/georges_editor_form.h index adfaf2e59..031d6e0fc 100644 --- a/code/studio/src/plugins/georges_editor/georges_editor_form.h +++ b/code/studio/src/plugins/georges_editor/georges_editor_form.h @@ -52,7 +52,7 @@ public Q_SLOTS: void save(); void settingsChanged(); - void closingTreeView(); + void dialogClosing( GeorgesDockWidget *d ); void setModified(); void focusChanged(QWidget *old, QWidget *now); diff --git a/code/studio/src/plugins/georges_editor/georges_treeview_dialog.cpp b/code/studio/src/plugins/georges_editor/georges_treeview_dialog.cpp index c2aa78005..ab5f03924 100644 --- a/code/studio/src/plugins/georges_editor/georges_treeview_dialog.cpp +++ b/code/studio/src/plugins/georges_editor/georges_treeview_dialog.cpp @@ -90,6 +90,7 @@ namespace GeorgesQt connect(m_browserCtrl, SIGNAL(modified()), this, SLOT(modifiedFile())); connect(m_browserCtrl, SIGNAL(valueChanged(const QString&,const QString&)), this, SLOT(onValueChanged(const QString&,const QString&))); + connect(m_browserCtrl, SIGNAL(vstructChanged(const QString&)), this, SLOT( onVStructChanged(const QString&))); } CGeorgesTreeViewDialog::~CGeorgesTreeViewDialog() @@ -322,6 +323,8 @@ namespace GeorgesQt QFileInfo info( fileName ); setWindowTitle( info.fileName() ); + connect(m_ui.commentEdit, SIGNAL(textChanged()), this, SLOT(onCommentsEdited())); + return true; } @@ -329,6 +332,7 @@ namespace GeorgesQt { NLGEORGES::CForm *form = static_cast< NLGEORGES::CForm* >( m_form ); form->Header.Log = m_ui.logEdit->toPlainText().toUtf8().constData(); + form->Header.Comments = m_ui.commentEdit->toPlainText().toUtf8().constData(); NLMISC::COFile file; std::string s = m_fileName.toUtf8().constData(); @@ -423,6 +427,8 @@ namespace GeorgesQt setWindowTitle( info.fileName() + "*" ); setModified( true ); + log( "Created" ); + return true; } @@ -573,10 +579,24 @@ namespace GeorgesQt modifiedFile(); } - void CGeorgesTreeViewDialog::closeEvent(QCloseEvent *event) + void CGeorgesTreeViewDialog::onVStructChanged( const QString &name ) { - Q_EMIT closing(); - deleteLater(); + QModelIndex idx = m_ui.treeView->currentIndex(); + QModelIndex parent = idx.parent(); + int row = idx.row(); + + m_model->changeVStructDfn( idx ); + + idx = m_model->index( row, 0, parent ); + + m_ui.treeView->expandAll(); + m_ui.treeView->setCurrentIndex( idx ); + m_browserCtrl->clicked( idx ); + } + + void CGeorgesTreeViewDialog::onCommentsEdited() + { + modifiedFile(); } void CGeorgesTreeViewDialog::checkVisibility(bool visible) { diff --git a/code/studio/src/plugins/georges_editor/georges_treeview_dialog.h b/code/studio/src/plugins/georges_editor/georges_treeview_dialog.h index 459258c3f..37ae55c20 100644 --- a/code/studio/src/plugins/georges_editor/georges_treeview_dialog.h +++ b/code/studio/src/plugins/georges_editor/georges_treeview_dialog.h @@ -77,13 +77,9 @@ namespace GeorgesQt QString loadedForm; - protected: - void closeEvent(QCloseEvent *event); - Q_SIGNALS: void changeFile(QString); void modified(); - void closing(); public Q_SLOTS: void setForm(const CForm*); @@ -101,7 +97,9 @@ namespace GeorgesQt void onAppendArray(); void onDeleteArrayEntry(); void onValueChanged( const QString &key, const QString &value ); + void onVStructChanged( const QString &name ); void onRenameArrayEntry(); + void onCommentsEdited(); private: void log( const QString &msg ); diff --git a/code/studio/src/plugins/georges_editor/georges_treeview_form.ui b/code/studio/src/plugins/georges_editor/georges_treeview_form.ui index 42d9afcf9..43d50e103 100644 --- a/code/studio/src/plugins/georges_editor/georges_treeview_form.ui +++ b/code/studio/src/plugins/georges_editor/georges_treeview_form.ui @@ -112,7 +112,11 @@ - + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + diff --git a/code/studio/src/plugins/georges_editor/georges_typ_dialog.cpp b/code/studio/src/plugins/georges_editor/georges_typ_dialog.cpp index 7e832ba26..ab4cc0472 100644 --- a/code/studio/src/plugins/georges_editor/georges_typ_dialog.cpp +++ b/code/studio/src/plugins/georges_editor/georges_typ_dialog.cpp @@ -82,6 +82,8 @@ bool GeorgesTypDialog::load( const QString &fileName ) QFileInfo info( fileName ); setWindowTitle( info.fileName() ); + connect( m_ui.commentEdit, SIGNAL( textChanged() ), this, SLOT( onCommentsEdited() ) ); + return true; } @@ -96,6 +98,7 @@ void GeorgesTypDialog::write() xml.init( &file ); m_pvt->typ->Header.Log = m_ui.logEdit->toPlainText().toUtf8().constData(); + m_pvt->typ->Header.Comments = m_ui.commentEdit->toPlainText().toUtf8().constData(); m_pvt->typ->write( xml.getDocument() ); xml.flush(); @@ -115,6 +118,8 @@ void GeorgesTypDialog::newDocument( const QString &fileName ) setModified( true ); loadTyp(); + + log( "Created" ); } void GeorgesTypDialog::onAddClicked() @@ -225,6 +230,11 @@ void GeorgesTypDialog::onModified( const QString &k, const QString &v ) onModified(); } +void GeorgesTypDialog::onCommentsEdited() +{ + onModified(); +} + void GeorgesTypDialog::setupConnections() { connect( m_ui.addButton, SIGNAL( clicked( bool ) ), this, SLOT( onAddClicked() ) ); diff --git a/code/studio/src/plugins/georges_editor/georges_typ_dialog.h b/code/studio/src/plugins/georges_editor/georges_typ_dialog.h index b241c4c8d..5a6c09e61 100644 --- a/code/studio/src/plugins/georges_editor/georges_typ_dialog.h +++ b/code/studio/src/plugins/georges_editor/georges_typ_dialog.h @@ -45,6 +45,7 @@ private Q_SLOTS: void onItemChanged( QTreeWidgetItem *item, int column ); void onModified(); void onModified( const QString &k, const QString &v ); + void onCommentsEdited(); private: void setupConnections(); @@ -53,8 +54,6 @@ private: Ui::GeorgesTypDialog m_ui; GeorgesTypDialogPvt *m_pvt; - - QString m_fileName; }; diff --git a/code/studio/src/plugins/georges_editor/georges_typ_dialog.ui b/code/studio/src/plugins/georges_editor/georges_typ_dialog.ui index 6cd080579..8978fa13b 100644 --- a/code/studio/src/plugins/georges_editor/georges_typ_dialog.ui +++ b/code/studio/src/plugins/georges_editor/georges_typ_dialog.ui @@ -118,7 +118,11 @@ - + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + diff --git a/code/studio/src/plugins/georges_editor/georgesform_model.cpp b/code/studio/src/plugins/georges_editor/georgesform_model.cpp index 6fc3c7b9c..2579a09f5 100644 --- a/code/studio/src/plugins/georges_editor/georgesform_model.cpp +++ b/code/studio/src/plugins/georges_editor/georgesform_model.cpp @@ -45,6 +45,8 @@ #include "georges_editor_form.h" #include "actions.h" +#include "georges.h" + using namespace NLGEORGES; namespace GeorgesQt @@ -277,13 +279,20 @@ namespace GeorgesQt const char *name, uint structId, const char *formName, - uint slot) + uint slot, + bool isVirtual) { // The form pointer NLGEORGES::CForm *formPtr = static_cast(m_form); // Add the new node - CFormItem *newNode = parent->add(CFormItem::Form, name, structId, formName, slot, m_form, false); + CFormItem::TType ttype; + if( isVirtual ) + ttype = CFormItem::TYPE_VSTRUCT; + else + ttype = CFormItem::TYPE_STRUCT; + + CFormItem *newNode = parent->add(CFormItem::Form, name, structId, formName, slot, m_form, ttype ); // Can be NULL in virtual DFN if (parentDfn) @@ -367,7 +376,10 @@ namespace GeorgesQt NLGEORGES::CFormDfn *tmpDfn = vStruct ? ((NLGEORGES::CFormDfn*)vStruct->FormDfn) : entry.getDfnPtr(); // Add the new struct - addStruct (newNode, nextForm, tmpDfn, entry.getName().c_str(), elm, entryName.c_str(), slot); + if( entry.getType() == NLGEORGES::UFormDfn::EntryVirtualDfn ) + addStruct (newNode, nextForm, tmpDfn, entry.getName().c_str(), elm, entryName.c_str(), slot, true); + else + addStruct (newNode, nextForm, tmpDfn, entry.getName().c_str(), elm, entryName.c_str(), slot); } } // Array of type ? @@ -418,7 +430,7 @@ CFormItem *CGeorgesFormModel::addArray(CFormItem *parent, uint slot) { // Add the new node - CFormItem *newNode = parent->add (CFormItem::Form, name, structId, formName, slot, m_form, true); + CFormItem *newNode = parent->add (CFormItem::Form, name, structId, formName, slot, m_form, CFormItem::TYPE_ARRAY ); // The array exist if (array) @@ -451,7 +463,7 @@ CFormItem *CGeorgesFormModel::addArray(CFormItem *parent, else { NLGEORGES::CFormElmArray *elmPtr = array->Elements[elm].Element ? static_cast(array->Elements[elm].Element) : NULL; - newNode->add (CFormItem::Form, formArrayName, elm, formArrayElmName, slot, m_form, false); + addAtom( newNode, elmPtr, rootDfn, formArrayName, elm, formArrayElmName ); } } } @@ -460,6 +472,39 @@ CFormItem *CGeorgesFormModel::addArray(CFormItem *parent, } +CFormItem *CGeorgesFormModel::addAtom(CFormItem *parent, NLGEORGES::CFormElm *elm, NLGEORGES::CFormDfn *dfn, const char *name, uint id, const char *formName) +{ + CFormItem *item = parent->add( CFormItem::Form, name, id, formName, 0, m_form, CFormItem::TYPE_ATOM ); + + return item; +} + + +CFormItem *CGeorgesFormModel::addItem(CFormItem *parent, NLGEORGES::CFormElm *elm, NLGEORGES::CFormDfn *dfn, const char *name, uint id, const char *formName) +{ + CFormItem *item = NULL; + + if( elm->isAtom() ) + item = addAtom(parent, elm, dfn, name, id, formName ); + else + if( elm->isStruct() || elm->isVirtualStruct() ) + { + NLGEORGES::CFormElmStruct *st = static_cast< NLGEORGES::CFormElmStruct* >( elm ); + if( st->isVirtualStruct() ) + item = addStruct(parent, st, st->FormDfn, name, id, formName, 0, true); + else + item = addStruct(parent, st, st->FormDfn, name, id, formName, 0, false); + } + else + if( elm->isArray() ) + { + NLGEORGES::CFormElmArray *arr = static_cast< NLGEORGES::CFormElmArray* >( elm ); + item = addArray(parent, arr, arr->FormDfn, name, id, formName, 0 ); + } + + return item; +} + void CGeorgesFormModel::arrayResized( const QString &name, int size ) { CFormItem *item = m_rootItem->findItem( name ); @@ -494,7 +539,9 @@ 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(), false ); + NLGEORGES::UFormDfn *udfn = e.Element->getStructDfn(); + NLGEORGES::CFormDfn *cdfn = static_cast< NLGEORGES::CFormDfn* >( udfn ); + addItem( item, e.Element, cdfn, n.toUtf8().constData(), i, formName.toUtf8().constData() ); } if( celm->Elements.size() == 0 ) @@ -566,7 +613,9 @@ void CGeorgesFormModel::appendArray( QModelIndex idx ) std::string formName; node->getFormName( formName ); - item->add( CFormItem::Form, name.c_str(), s, formName.c_str(), 0, item->form(), false ); + NLGEORGES::CFormDfn *cdfn = const_cast< NLGEORGES::CFormDfn* >( nodeDfn ); + addItem( item, node, cdfn, name.c_str(), s, formName.c_str() ); + } void CGeorgesFormModel::deleteArrayEntry( QModelIndex idx ) @@ -608,7 +657,9 @@ void CGeorgesFormModel::deleteArrayEntry( QModelIndex idx ) else n = e.Name.c_str(); - item->add( CFormItem::Form, n.toUtf8().constData(), i, formName.toUtf8().constData(), 0, item->form(), false ); + NLGEORGES::UFormDfn *udfn = e.Element->getStructDfn(); + NLGEORGES::CFormDfn *cdfn = static_cast< NLGEORGES::CFormDfn* >( udfn ); + addItem( item, e.Element, cdfn, n.toUtf8().constData(), i, formName.toUtf8().constData() ); } Q_EMIT endResetModel(); @@ -642,6 +693,42 @@ void CGeorgesFormModel::renameArrayEntry( QModelIndex idx, const QString &name ) item->setName( name.toUtf8().constData() ); } +void CGeorgesFormModel::changeVStructDfn( QModelIndex idx ) +{ + CFormItem *item = static_cast< CFormItem* >( idx.internalPointer() ); + + QString vstruct = item->formName().c_str(); + + NLGEORGES::UFormElm *uelm = NULL; + m_form->getRootNode().getNodeByName( &uelm, vstruct.toUtf8().constData() ); + + if( uelm == NULL ) + return; + + NLGEORGES::CFormElmVirtualStruct *vs = static_cast< NLGEORGES::CFormElmVirtualStruct* >( uelm ); + + CGeorges g; + NLGEORGES::UFormDfn *udfn = g.loadFormDfn( vs->DfnFilename ); + if( udfn == NULL ) + return; + + NLGEORGES::CFormDfn *cdfn = static_cast< NLGEORGES::CFormDfn* >( udfn ); + vs->build( cdfn ); + + + beginResetModel(); + + CFormItem *parent = item->parent(); + int row = idx.row(); + QString name = item->name().c_str(); + QString formName = item->formName().c_str(); + parent->removeChild( row ); + + addItem( parent, vs, cdfn, name.toUtf8().constData(), row, formName.toUtf8().constData() ); + + endResetModel(); +} + /******************************************************************************/ void CGeorgesFormModel::loadFormHeader() diff --git a/code/studio/src/plugins/georges_editor/georgesform_model.h b/code/studio/src/plugins/georges_editor/georgesform_model.h index 70d602232..7d6bac3f3 100644 --- a/code/studio/src/plugins/georges_editor/georgesform_model.h +++ b/code/studio/src/plugins/georges_editor/georgesform_model.h @@ -65,11 +65,15 @@ namespace GeorgesQt NLGEORGES::UFormElm *getRootForm() { return m_rootElm; } CFormItem *addStruct (CFormItem *parent, NLGEORGES::CFormElmStruct *_struct, NLGEORGES::CFormDfn *parentDfn, - const char *name, uint structId, const char *formName, uint slot); + const char *name, uint structId, const char *formName, uint slot, bool isVirtual = false ); CFormItem *addArray(CFormItem *parent, NLGEORGES::CFormElmArray *array, NLGEORGES::CFormDfn *rootDfn, const char *name, uint structId, const char *formName, uint slot); + CFormItem *addAtom(CFormItem *parent, NLGEORGES::CFormElm *elm, NLGEORGES::CFormDfn *dfn, const char *name, uint id, const char *formName); + + CFormItem *addItem(CFormItem *parent, NLGEORGES::CFormElm *elm, NLGEORGES::CFormDfn *dfn, const char *name, uint id, const char *formName); + void emitDataChanged(const QModelIndex &index) { Q_EMIT dataChanged(index, index); @@ -79,6 +83,7 @@ namespace GeorgesQt void appendArray( QModelIndex idx ); void deleteArrayEntry( QModelIndex idx ); void renameArrayEntry( QModelIndex idx, const QString &name ); + void changeVStructDfn( QModelIndex idx ); private: void setupModelData();