diff --git a/code/studio/src/plugins/georges_editor/browser_ctrl.cpp b/code/studio/src/plugins/georges_editor/browser_ctrl.cpp index 5c4d2a499..dadbeacde 100644 --- a/code/studio/src/plugins/georges_editor/browser_ctrl.cpp +++ b/code/studio/src/plugins/georges_editor/browser_ctrl.cpp @@ -17,6 +17,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 +32,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 +44,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 ); diff --git a/code/studio/src/plugins/georges_editor/browser_ctrl.h b/code/studio/src/plugins/georges_editor/browser_ctrl.h index d61d3b9e9..7c56deceb 100644 --- a/code/studio/src/plugins/georges_editor/browser_ctrl.h +++ b/code/studio/src/plugins/georges_editor/browser_ctrl.h @@ -29,9 +29,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(); 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 d5026ef71..765493f0a 100644 --- a/code/studio/src/plugins/georges_editor/browser_ctrl_pvt.cpp +++ b/code/studio/src/plugins/georges_editor/browser_ctrl_pvt.cpp @@ -2,6 +2,9 @@ #include "3rdparty/qtpropertybrowser/qttreepropertybrowser.h" #include "3rdparty/qtpropertybrowser/qtvariantproperty.h" #include +#include "formitem.h" + +#include "nel/georges/form.h" namespace { @@ -26,6 +29,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 +43,6 @@ QObject( parent ) { mgr = new QtVariantPropertyManager(); factory = new QtVariantEditorFactory(); - m_currentNode = NULL; m_rootNode = NULL; } @@ -70,19 +78,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 +99,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 +156,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 +258,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 ) - return; + 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 ); } 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 c34d5ce0c..c3d1cf50e 100644 --- a/code/studio/src/plugins/georges_editor/browser_ctrl_pvt.h +++ b/code/studio/src/plugins/georges_editor/browser_ctrl_pvt.h @@ -10,6 +10,11 @@ namespace NLGEORGES class CFormElmStruct; } +namespace GeorgesQt +{ + class CFormItem; +} + class QtVariantPropertyManager; class QtVariantEditorFactory; class QtTreePropertyBrowser; @@ -24,7 +29,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 +39,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 diff --git a/code/studio/src/plugins/georges_editor/formitem.cpp b/code/studio/src/plugins/georges_editor/formitem.cpp index 1ca2ecbe1..8cd479961 100644 --- a/code/studio/src/plugins/georges_editor/formitem.cpp +++ b/code/studio/src/plugins/georges_editor/formitem.cpp @@ -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(m_form); - NLGEORGES::CFormElm *elm = static_cast(&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( parentItem == NULL ) + return false; - // 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(m_form); - NLGEORGES::CFormElm *elm = static_cast(&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; - - 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; diff --git a/code/studio/src/plugins/georges_editor/formitem.h b/code/studio/src/plugins/georges_editor/formitem.h index d29dfce0c..cd67d1b21 100644 --- a/code/studio/src/plugins/georges_editor/formitem.h +++ b/code/studio/src/plugins/georges_editor/formitem.h @@ -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 childItems; QList itemData; @@ -88,6 +95,7 @@ namespace GeorgesQt std::string _FormName; TSub _Type; uint _Slot; + bool _Array; }; // CFormItem diff --git a/code/studio/src/plugins/georges_editor/georges_dirtree_dialog.cpp b/code/studio/src/plugins/georges_editor/georges_dirtree_dialog.cpp index 0a467aac5..c1853233c 100644 --- a/code/studio/src/plugins/georges_editor/georges_dirtree_dialog.cpp +++ b/code/studio/src/plugins/georges_editor/georges_dirtree_dialog.cpp @@ -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)); } } diff --git a/code/studio/src/plugins/georges_editor/georges_dirtree_dialog.h b/code/studio/src/plugins/georges_editor/georges_dirtree_dialog.h index 3654783f3..0a8fc682b 100644 --- a/code/studio/src/plugins/georges_editor/georges_dirtree_dialog.h +++ b/code/studio/src/plugins/georges_editor/georges_dirtree_dialog.h @@ -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); 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 dc0ca409d..166243adf 100644 --- a/code/studio/src/plugins/georges_editor/georges_editor_form.cpp +++ b/code/studio/src/plugins/georges_editor/georges_editor_form.cpp @@ -103,8 +103,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*))); } @@ -144,8 +144,12 @@ namespace GeorgesQt 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() @@ -190,12 +194,12 @@ namespace GeorgesQt } } - void GeorgesEditorForm::loadFile(const QString fileName) + void GeorgesEditorForm::loadFile(const QString &fileName) { loadFile(fileName, false); } - void GeorgesEditorForm::loadFile(const QString fileName, bool loadFromDfn) + void GeorgesEditorForm::loadFile(const QString &fileName, bool loadFromDfn) { QFileInfo info(fileName); @@ -257,6 +261,10 @@ namespace GeorgesQt { nlwarning("Failed to load form: %s", info.fileName().toUtf8().constData()); m_dockedWidgets.last()->close(); + + QMessageBox::information( this, + tr( "Failed to load form..." ), + tr( "Failed to load form '%1'" ).arg( info.fileName() ) ); } } 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 c9cef964c..6b4e33fcd 100644 --- a/code/studio/src/plugins/georges_editor/georges_editor_form.h +++ b/code/studio/src/plugins/georges_editor/georges_editor_form.h @@ -42,8 +42,8 @@ public: public Q_SLOTS: void open(); - void loadFile(const QString fileName); - void loadFile(const QString fileName, bool loadFromDfn); + void loadFile(const QString &fileName); + void loadFile(const QString &fileName, bool loadFromDfn); void newFile(); void save(); void settingsChanged(); diff --git a/code/studio/src/plugins/georges_editor/georges_editor_plugin.cpp b/code/studio/src/plugins/georges_editor/georges_editor_plugin.cpp index f1b419e4e..e0b29af2f 100644 --- a/code/studio/src/plugins/georges_editor/georges_editor_plugin.cpp +++ b/code/studio/src/plugins/georges_editor/georges_editor_plugin.cpp @@ -94,6 +94,11 @@ void GeorgesEditorContext::open() m_georgesEditorForm->open(); } +void GeorgesEditorContext::save() +{ + m_georgesEditorForm->save(); +} + QWidget *GeorgesEditorContext::widget() { return m_georgesEditorForm; diff --git a/code/studio/src/plugins/georges_editor/georges_editor_plugin.h b/code/studio/src/plugins/georges_editor/georges_editor_plugin.h index e21d8c57a..931e83ddf 100644 --- a/code/studio/src/plugins/georges_editor/georges_editor_plugin.h +++ b/code/studio/src/plugins/georges_editor/georges_editor_plugin.h @@ -86,6 +86,8 @@ public: virtual void open(); + void save(); + virtual QUndoStack *undoStack(); virtual QWidget *widget(); 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 3ecc73045..9def10065 100644 --- a/code/studio/src/plugins/georges_editor/georges_treeview_dialog.cpp +++ b/code/studio/src/plugins/georges_editor/georges_treeview_dialog.cpp @@ -71,7 +71,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 +90,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() @@ -220,6 +220,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(); @@ -316,6 +319,8 @@ namespace GeorgesQt 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); @@ -468,6 +473,74 @@ namespace GeorgesQt if( !idx.isValid() ) return; m_ui.treeView->setCurrentIndex( idx ); + + log( name + " resized = " + QString::number( size ) ); + } + + 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 +596,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 +636,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 +688,41 @@ namespace GeorgesQt // } } // if selected context menu item is valid. + */ } // if 'm' model valid. //if(structContext) // delete structContext; } + void CGeorgesTreeViewDialog::log( 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; + + m_ui.logEdit->appendPlainText( logMsg ); + } + } /* namespace GeorgesQt */ 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 7b40fc3ef..c3e9937ef 100644 --- a/code/studio/src/plugins/georges_editor/georges_treeview_dialog.h +++ b/code/studio/src/plugins/georges_editor/georges_treeview_dialog.h @@ -104,8 +104,14 @@ 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; diff --git a/code/studio/src/plugins/georges_editor/georgesform_model.cpp b/code/studio/src/plugins/georges_editor/georgesform_model.cpp index 90eaaaacd..f00e090f2 100644 --- a/code/studio/src/plugins/georges_editor/georgesform_model.cpp +++ b/code/studio/src/plugins/georges_editor/georgesform_model.cpp @@ -283,7 +283,7 @@ namespace GeorgesQt NLGEORGES::CForm *formPtr = static_cast(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(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() ); +} /******************************************************************************/ diff --git a/code/studio/src/plugins/georges_editor/georgesform_model.h b/code/studio/src/plugins/georges_editor/georgesform_model.h index d133b5ec6..70d602232 100644 --- a/code/studio/src/plugins/georges_editor/georgesform_model.h +++ b/code/studio/src/plugins/georges_editor/georgesform_model.h @@ -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 + +