From 9c6f7688d7c232f97a67b7aee4b6df1c24d78ba4 Mon Sep 17 00:00:00 2001 From: "PANIK\\chris" Date: Fri, 5 Sep 2025 11:49:36 +0200 Subject: [PATCH] Enable section toggle --- src/application/xqchildmodel.cpp | 10 +-- src/application/xqmainmodel.cpp | 20 ++++++ src/application/xqmainwindow.cpp | 7 +- ...elsectionlist.cpp => xqsectionmanager.cpp} | 64 ++++++++++++------- ...qmodelsectionlist.h => xqsectionmanager.h} | 27 +++++--- src/model/xqviewmodel.cpp | 23 +++---- src/model/xqviewmodel.h | 10 +-- src/xtree.pro | 4 +- 8 files changed, 96 insertions(+), 69 deletions(-) rename src/model/{xqmodelsectionlist.cpp => xqsectionmanager.cpp} (65%) rename src/model/{xqmodelsectionlist.h => xqsectionmanager.h} (72%) diff --git a/src/application/xqchildmodel.cpp b/src/application/xqchildmodel.cpp index 769b07d..dbf01fc 100644 --- a/src/application/xqchildmodel.cpp +++ b/src/application/xqchildmodel.cpp @@ -55,13 +55,7 @@ void XQChildModel::addModelData( const XQNodePtr& contentRoot ) if (!_sections.hasValidSection(key)) continue; - XQModelSection& section = _sections.at( key ); - // wir speichern das parent des datenknoten auch in der - // section. - // contentEntry->parent == _contentRoot, aber halt nur weil das model flach ist - - //qDebug() << " --- add section ENTRY: " << key << " TagName: " << contentEntry->attribute("TagName"); - + const XQModelSection& section = _sections.sectionByKey( key ); section.setContentRootNode( contentEntry->parent() ); int newRow = _sections.lastRow(section); @@ -81,7 +75,7 @@ void XQChildModel::addModelData( const XQNodePtr& contentRoot ) void XQChildModel::addSectionEntry( const QString& key, const XQNodePtr& contentEntry ) { - XQModelSection& section = _sections.at( key ); + const XQModelSection& section = _sections.sectionByKey( key ); if(section.isValid() ) { section.setContentRootNode( contentEntry->parent() ); diff --git a/src/application/xqmainmodel.cpp b/src/application/xqmainmodel.cpp index fcebe68..fe922a1 100644 --- a/src/application/xqmainmodel.cpp +++ b/src/application/xqmainmodel.cpp @@ -48,6 +48,25 @@ XQItem* XQMainModel::addProjectItem( XQNodePtr contentNode ) // wir durchsuchen alle unsere sections nach dem passenden content-type, // hier: content-type beschreibt den projekt-status + const QString& sectionKey = contentNode->attribute(c_ContentType); + if( _sections.hasValidSection( sectionKey ) ) + { + const XQModelSection& section = _sections.sectionByKey( sectionKey ); + qDebug() << " --- add PROJECT: contentNode: " << contentNode->to_string(); + + // __fixme! das ist mist! + const XQNodePtr sheetNode = section.sheetRootNode()->first_child(); + XQItem* newItem = _itemFactory.makeSingleItem( sheetNode, contentNode->attribute( "ProjectName") ); + + // den neuen eintrag in die passende section der übersicht eintragen ... + section.headerItem().appendRow( newItem ); + // erzeuger sheet node speichern + newItem->setSheetNode( sheetNode ); + expandNewItem(section.headerItem().index() ); + return newItem; + } + + /* for(const auto& section : _sections ) { if( contentNode->attribute(c_ContentType) == section.contentType() ) @@ -66,6 +85,7 @@ XQItem* XQMainModel::addProjectItem( XQNodePtr contentNode ) return newItem; } } + */ throw XQException( "addProjectItem: main model should not be empty!" ); } diff --git a/src/application/xqmainwindow.cpp b/src/application/xqmainwindow.cpp index e85e928..a6d2748 100644 --- a/src/application/xqmainwindow.cpp +++ b/src/application/xqmainwindow.cpp @@ -140,9 +140,6 @@ void XQMainWindow::initMainWindow() } - - - //! slot für zentrales undo void XQMainWindow::onUndo() @@ -244,7 +241,7 @@ void XQMainWindow::onAbout() QMessageBox msgBox(QMessageBox::NoIcon, "About", "", QMessageBox::Ok); QString text = "xtree concept
"; - text += "2024 c.holzheuer

"; + text += "2024-2025 c.holzheuer

"; text += "sourceworx.org/xtree"; msgBox.setTextFormat(Qt::RichText); // This allows you to click the link @@ -292,7 +289,7 @@ void XQMainWindow::onTreeViewItemChanged(const XQItem& item ) { qDebug() << " --- should toggle: " << item.text(); XQViewModel& childModel = *_documentStore[idx].viewModel; - childModel.toggleSection(item.text()); + childModel.onToggleSection(item.text()); } } } diff --git a/src/model/xqmodelsectionlist.cpp b/src/model/xqsectionmanager.cpp similarity index 65% rename from src/model/xqmodelsectionlist.cpp rename to src/model/xqsectionmanager.cpp index d689d14..565435b 100644 --- a/src/model/xqmodelsectionlist.cpp +++ b/src/model/xqsectionmanager.cpp @@ -12,7 +12,7 @@ ***************************************************************************/ -#include +#include //! kontstruktor. übergibt den start-index und einen model-knoten mit der beschreibung @@ -72,7 +72,7 @@ XQNodePtr XQModelSection::contentRootNode() const return _contentRootNode; } -void XQModelSection::setContentRootNode( const XQNodePtr contentRootNode ) +void XQModelSection::setContentRootNode( const XQNodePtr contentRootNode ) const { _contentRootNode = contentRootNode; } @@ -104,33 +104,42 @@ XQItem& XQModelSection::XQModelSection::headerItem() const //! testet, ob die unter 'sectionKey' eine gültige section vorhanden ist. -bool XQModelSectionList::hasValidSection(const QString& sectionKey) const +bool XQSectionManager::hasValidSection(const QString& sectionKey) const { - if (!contains(sectionKey) ) + if (!_sections.contains(sectionKey) ) return false; - return at(sectionKey).isValid(); + return _sections.at(sectionKey).isValid(); } +const XQModelSection& XQSectionManager::sectionByKey( const QString& sectionKey ) +{ + if( hasValidSection( sectionKey ) ) + return _sections.at(sectionKey); + + static const XQModelSection s_DummySection; + return s_DummySection; + +} //! gibt für einen model index die 'zuständige' section zurück. -const XQModelSection& XQModelSectionList::sectionFromIndex( const QModelIndex& index ) const +const XQModelSection& XQSectionManager::sectionByIndex( const QModelIndex& index ) const { - return sectionFromRow( index.row() ); + return sectionByRow( index.row() ); } //! gibt für eine zeile die 'zuständige' section zurück: der bestand an section wird //! nach der passenden section durchsucht. -const XQModelSection& XQModelSectionList::sectionFromRow(int itemRow ) const +const XQModelSection& XQSectionManager::sectionByRow(int itemRow ) const { - int i = size() - 1; + int i = _sections.size() - 1; for (; i >= 0; --i) { - if ( at(i).persistentModelIndex().row() < itemRow ) - return at(i); + if ( _sections.at(i).persistentModelIndex().row() < itemRow ) + return _sections.at(i); } static XQModelSection s_DummySection; @@ -139,40 +148,47 @@ const XQModelSection& XQModelSectionList::sectionFromRow(int itemRow ) const } +const XQModelSection& XQSectionManager::createSection(const QString& sectionKey, const QModelIndex& modelIndex, XQNodePtr sheetNode) +{ + // 6. jetzt können wir auch die sction erzeugen + XQModelSection section(modelIndex, sheetNode ); + _sections.addAtKey( sectionKey, section); + return sectionByKey(sectionKey); +} //! ermittelt die erste zeile einer section. -int XQModelSectionList::firstRow(const QModelIndex& idx) const +int XQSectionManager::firstRow(const QModelIndex& idx) const { - return sectionFromRow(idx.row() ).row(); + return sectionByRow(idx.row() ).row(); } //! ermittelt die zeile unterhalb des gegebenen modelindex, //! zum einfügen neuer items ebendort. -int XQModelSectionList::lastRow(const QModelIndex& idx) const +int XQSectionManager::lastRow(const QModelIndex& idx) const { - return lastRow(sectionFromRow(idx.row())); + return lastRow(sectionByRow(idx.row())); } //! ermittelt die zeile unterhalb der gegebenen section, //! zum einfügen neuer items ebendort. -int XQModelSectionList::lastRow(const XQModelSection& section ) const +int XQSectionManager::lastRow(const XQModelSection& section ) const { //qDebug() << " -- last row in section: " << section.modelIndex.data().toString() << " --> " << section.modelIndex.row(); // row() der section unterhalb dieser // __fix? index mit speichern? - int index = indexOf(section); + int index = _sections.indexOf(section); if (index > -1) { // last section? return last row of model - if (index == size() - 1) + if (index == _sections.size() - 1) return section.persistentModelIndex().model()->rowCount();// - 1; // return row above the row of the next section -> last row of given section - return at(index+1).row(); + return _sections.at(index+1).row(); } return -1; } @@ -180,13 +196,13 @@ int XQModelSectionList::lastRow(const XQModelSection& section ) const //! gibt alle sections aus, zum ankucken. -void XQModelSectionList::dump() const +void XQSectionManager::dump() const { - qDebug() << " --- sections dump(): " < @@ -41,7 +41,7 @@ public: XQNodePtr sectionRootNode() const; XQNodePtr sheetRootNode() const; XQNodePtr contentRootNode() const; - void setContentRootNode( const XQNodePtr dataRootNode ); + void setContentRootNode( const XQNodePtr dataRootNode ) const; const QString& contentType() const; XQItem& headerItem() const; @@ -50,8 +50,8 @@ protected: QPersistentModelIndex _modelIndex; - XQNodePtr _sectionRootNode{}; - XQNodePtr _contentRootNode{}; + mutable XQNodePtr _sectionRootNode{}; + mutable XQNodePtr _contentRootNode{}; }; @@ -60,21 +60,28 @@ Q_DECLARE_METATYPE(XQModelSection) //! 'maptor' struktur, die alle sections enthält -class XQModelSectionList : public XQMaptor +class XQSectionManager { public: bool hasValidSection(const QString& sectionKey) const; - const XQModelSection& sectionFromRow( int row ) const; - const XQModelSection& sectionFromIndex( const QModelIndex& index ) const; + const XQModelSection& sectionByKey( const QString& sectionKey ); + const XQModelSection& sectionByRow( int row ) const; + const XQModelSection& sectionByIndex( const QModelIndex& index ) const; + + const XQModelSection& createSection(const QString& sectionKey, const QModelIndex& modelIndex, XQNodePtr sheetNode); int firstRow(const QModelIndex& idx) const; int lastRow(const QModelIndex& idx) const; int lastRow(const XQModelSection& section) const; - void dump()const override; + void dump()const; + +protected: + + XQMaptor _sections; }; -#endif // XQMODELSECTIONLIST_H +#endif // XQSECTIONMANAGER_H diff --git a/src/model/xqviewmodel.cpp b/src/model/xqviewmodel.cpp index 38f5d74..550065a 100644 --- a/src/model/xqviewmodel.cpp +++ b/src/model/xqviewmodel.cpp @@ -165,9 +165,9 @@ void XQViewModel::addSection(const XQItemList& list, const XQNodePtr& sectionNod // 5. das erzeugt dann auch valide indices appendRow(list); + const QString §ionKey = sectionNode->attribute(c_ContentType); // 6. jetzt können wir auch die sction erzeugen - XQModelSection section(list[0]->index(), sectionNode ); - _sections.addAtKey(sectionNode->attribute( c_ContentType), section); + const XQModelSection& section = _sections.createSection( sectionKey, list[0]->index(), sectionNode ); // ... und es der welt mitteilen. emit sectionCreated( section ); @@ -178,6 +178,8 @@ void XQViewModel::addSection(const XQItemList& list, const XQNodePtr& sectionNod void XQViewModel::onToggleSection(const QString& sectionKey ) { qDebug() << " --- onToggleSection: " << sectionKey; + if( _sections.hasValidSection( sectionKey ) ) + toggleSection( _sections.sectionByKey(sectionKey)); } @@ -197,15 +199,6 @@ void XQViewModel::toggleSection( const XQModelSection& section ) } -void XQViewModel::toggleSection( const QString& sectionKey ) -{ - if( _sections.hasValidSection( sectionKey ) ) - { - XQModelSection& section = _sections.at( sectionKey); - //section. - } -} - /* //! SLOT als weiterleitung vom SIGNAL itemchanged @@ -353,7 +346,7 @@ void XQViewModel::cmdCutUndo( const XQCommand& command ) // die anfangsposition int itmPos = command.first().itemPos; // die 'zuständige' section rausfinden - const XQModelSection& section = _sections.sectionFromRow( itmPos ); + const XQModelSection& section = _sections.sectionByRow( itmPos ); // über alle einträge ... for (auto& entry : command ) { @@ -387,7 +380,7 @@ void XQViewModel::cmdPaste( const XQCommand& command ) int nodePos = item.contentNode()->own_pos()+1; // die zugehörige section finden - const XQModelSection& section = _sections.sectionFromRow( insRow-1 ); + const XQModelSection& section = _sections.sectionByRow( insRow-1 ); // wir pasten das clipboard for (auto& entry : _clipBoard ) { @@ -476,7 +469,7 @@ void XQViewModel::cmdNew( const XQCommand& command ) //... - const XQModelSection& section = _sections.sectionFromIndex( origin ); + const XQModelSection& section = _sections.sectionByIndex( origin ); // neue, leere zeile erzeugen ... XQItemList list =_itemFactory.makeRow( section.sheetRootNode(), newNode ); @@ -506,7 +499,7 @@ void XQViewModel::cmdToggleSection( const XQCommand& command ) { const QModelIndex& index = command.originIndex(); Q_ASSERT(index.isValid()); - toggleSection( _sections.sectionFromIndex(index) ); + toggleSection( _sections.sectionByIndex(index) ); } diff --git a/src/model/xqviewmodel.h b/src/model/xqviewmodel.h index 858a997..1bc3a37 100644 --- a/src/model/xqviewmodel.h +++ b/src/model/xqviewmodel.h @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include @@ -130,11 +130,11 @@ protected: using MemCallMap = QMap; // das eine reference auf ein globales singleton - XQItemFactory& _itemFactory; - XQSimpleClipBoard _clipBoard; - XQModelSectionList _sections; + XQItemFactory& _itemFactory; + XQSimpleClipBoard _clipBoard; + XQSectionManager _sections; - XQTreeTable* _treeTable{}; + XQTreeTable* _treeTable{}; //QAbstractItemView* _treeTable{}; QUndoStack* _undoStack{}; XQContextMenu* _contextMenu{}; diff --git a/src/xtree.pro b/src/xtree.pro index b1d5b1c..abde6c3 100644 --- a/src/xtree.pro +++ b/src/xtree.pro @@ -23,9 +23,9 @@ HEADERS += \ items/xqitemtype.h \ items/xqitemdelegate.h \ model/xqcommand.h \ - model/xqmodelsectionlist.h \ model/xqnode.h \ model/xqnodewriter.h \ + model/xqsectionmanager.h \ model/xqselectionmodel.h \ model/xqsimpleclipboard.h \ model/xqviewmodel.h \ @@ -61,9 +61,9 @@ SOURCES += \ items/xqitemdelegate.cpp \ main.cpp \ model/xqcommand.cpp \ - model/xqmodelsectionlist.cpp \ model/xqnode.cpp \ model/xqnodewriter.cpp \ + model/xqsectionmanager.cpp \ model/xqselectionmodel.cpp \ model/xqsimpleclipboard.cpp \ model/xqviewmodel.cpp \