From 0d7ab33c742bb3dd6cbe3d0348c5191e989ba113 Mon Sep 17 00:00:00 2001 From: "DIASPORA\\chris" Date: Thu, 14 Aug 2025 21:36:39 +0200 Subject: [PATCH] reworked model sections. --- {src/items => deprecated}/xqgenericitem.cpp | 0 {src/items => deprecated}/xqgenericitem.h | 0 src/application/xqappdata.h | 1 + src/application/xqchildmodel.cpp | 8 ---- src/application/xqmainmodel.cpp | 17 ++++++- src/items/xqitemfactory.cpp | 21 +-------- src/items/xqitemfactory.h | 3 -- src/model/xqmodelsectionlist.cpp | 32 +++++++------ src/model/xqmodelsectionlist.h | 9 ++-- src/model/xqviewmodel.cpp | 51 +++++++++++++++------ src/model/xqviewmodel.h | 3 -- src/xtree.pro | 2 - xml/modelsheets.xml | 2 +- 13 files changed, 79 insertions(+), 70 deletions(-) rename {src/items => deprecated}/xqgenericitem.cpp (100%) rename {src/items => deprecated}/xqgenericitem.h (100%) diff --git a/src/items/xqgenericitem.cpp b/deprecated/xqgenericitem.cpp similarity index 100% rename from src/items/xqgenericitem.cpp rename to deprecated/xqgenericitem.cpp diff --git a/src/items/xqgenericitem.h b/deprecated/xqgenericitem.h similarity index 100% rename from src/items/xqgenericitem.h rename to deprecated/xqgenericitem.h diff --git a/src/application/xqappdata.h b/src/application/xqappdata.h index e4b288a..73cd6f6 100644 --- a/src/application/xqappdata.h +++ b/src/application/xqappdata.h @@ -28,6 +28,7 @@ const QString c_ItemType = "ItemType"; const QString c_Caption = "Caption"; const QString c_Header = "Header"; const QString c_ContentType = "ContentType"; +const QString c_Data = "Data"; const QString c_MainModelName = "DocumentTreeModel"; const QString c_ChildModelName = "DocumentDetailsModel"; diff --git a/src/application/xqchildmodel.cpp b/src/application/xqchildmodel.cpp index d509d8c..9e16dfc 100644 --- a/src/application/xqchildmodel.cpp +++ b/src/application/xqchildmodel.cpp @@ -47,20 +47,14 @@ void XQChildModel::setContent( const XQNodePtr& contentRoot ) // haben, hier: . ... for (const auto& contentEntry : _contentRoot->children()) { - - qDebug() << " --- GOGOGO: 00: " << contentEntry->to_string(); - // Das ist hier der Typ des Eintrags: Panel, Battery ... QString key = contentEntry->tag_name(); - qDebug() << " --- GOGOGO: " << key; // 'silent failure' hier der Datenbaum kann auch Knoten enthalten // die nicht für uns gedacht sind. if (!_sections.hasValidSection(key)) continue; - qDebug() << " --- GOGOGO: FOUND!" << key; - XQModelSection& section = _sections.at( key ); // wir speichern das parent des datenknoten auch in der // section. @@ -70,8 +64,6 @@ void XQChildModel::setContent( const XQNodePtr& contentRoot ) XQItemList list = _itemFactory.makeContentRow( section.sheetRootNode, contentEntry ); - qDebug() << " --- AHJA: " << key << " -- last Row dazu: " << newRow; - // als Baum? //section.headerItem().appendRow( list ); insertRow( newRow, list); diff --git a/src/application/xqmainmodel.cpp b/src/application/xqmainmodel.cpp index ad087cd..047919c 100644 --- a/src/application/xqmainmodel.cpp +++ b/src/application/xqmainmodel.cpp @@ -40,6 +40,7 @@ XQMainModel::XQMainModel(QObject *parent ) XQItem* XQMainModel::createTreeEntry( XQNodePtr contentNode ) { + /* for(const auto& section : _sections ) { qDebug() << " --- wtf1: " << contentNode->to_string(); @@ -47,7 +48,20 @@ XQItem* XQMainModel::createTreeEntry( XQNodePtr contentNode ) if( contentNode->attribute("State") == section.sheetRootNode->attribute("State") ) { - XQItem* newTreeentry = _itemFactory.makeTreeChildItem( contentNode, section.sheetRootNode ); + //XQItem* newTreeentry = _itemFactory.makeTreeChildItem( contentNode, section.sheetRootNode ); + + makeTreeChildItem: + // den itemtype des neuen items rausfinden + QString typeKey = sheetEntry->attribute("ItemType"); + XQItemType* itemType = findItemTypeTemplate(typeKey); // throws + //XQItemType* itemType = makeItemType(sheetEntry); // throws + + const QString* contentPtr = contentNode->attribute_ptr( "ProjectName" ); + + XQItem* newItem = new XQItem( itemType, contentPtr ); + + return newItem; + section.headerItem().appendRow( newTreeentry ); _treeTable->expand( section.modelIndex ); // ?? @@ -57,6 +71,7 @@ XQItem* XQMainModel::createTreeEntry( XQNodePtr contentNode ) return newTreeentry; } } + */ throw XQException( "createTreeEntry: main model should not be empty!" ); } diff --git a/src/items/xqitemfactory.cpp b/src/items/xqitemfactory.cpp index 8644a65..dd135fb 100644 --- a/src/items/xqitemfactory.cpp +++ b/src/items/xqitemfactory.cpp @@ -119,24 +119,7 @@ XQNodePtr XQItemFactory::findModelSheet( const QString& modelName ) const } -//! firz! - -XQItem* XQItemFactory::makeTreeChildItem( const XQNodePtr& contentNode, const XQNodePtr& sheetEntry ) -{ - // den itemtype des neuen items rausfinden - QString typeKey = sheetEntry->attribute("ItemType"); - XQItemType* itemType = findItemTypeTemplate(typeKey); // throws - //XQItemType* itemType = makeItemType(sheetEntry); // throws - - const QString* contentPtr = contentNode->attribute_ptr( "ProjectName" ); - - XQItem* newItem = new XQItem( itemType, contentPtr ); - - return newItem; -} - - -//! firz! +//! erzeugt eine QVariant aus dem gegebenen string und setzt diese dann via role im item. void XQItemFactory::setItemDataFromString( XQItem& item, const QString& roleKey, const QString& source ) const { @@ -150,7 +133,7 @@ void XQItemFactory::setItemDataFromString( XQItem& item, const QString& roleKey, } -//! firz! +//! erzeugt eine QVariant aus dem gegebenen string QVariant XQItemFactory::makeVariant( int dataRole, const QString& source ) const { diff --git a/src/items/xqitemfactory.h b/src/items/xqitemfactory.h index 535d7bf..b5f4872 100644 --- a/src/items/xqitemfactory.h +++ b/src/items/xqitemfactory.h @@ -32,9 +32,6 @@ public: XQNodePtr findModelSheet( const QString& modelName ) const; - - XQItem* makeTreeChildItem( const XQNodePtr& contentNode, const XQNodePtr& sheetEntry ); - XQItem* makeItem( const XQNodePtr& sheetNode, const XQNodePtr& contentNode=nullptr); XQItemList makeHeaderRow( const XQNodePtr& sheetNode ); diff --git a/src/model/xqmodelsectionlist.cpp b/src/model/xqmodelsectionlist.cpp index ce3a9d8..b2c20cd 100644 --- a/src/model/xqmodelsectionlist.cpp +++ b/src/model/xqmodelsectionlist.cpp @@ -13,7 +13,7 @@ #include -#include + //! kontstruktor. übergibt den start-index und einen model-knoten mit der beschreibung @@ -38,6 +38,7 @@ bool XQModelSection::operator==(const XQModelSection& other) const bool XQModelSection::isValid() const { + qDebug() << " mi: " << modelIndex.isValid() << " sheetNode: " << (bool)(sheetRootNode); return modelIndex.isValid() && sheetRootNode; } @@ -57,32 +58,27 @@ XQItem& XQModelSection::XQModelSection::headerItem() const return XQItem::xqItemFromIndex( modelIndex ); } - - -void XQModelSectionList::addSectionEntry(const QModelIndex& idx, XQNodePtr sheetNode) -{ - if( !sheetNode->has_attribute( c_ContentType) ) - throw XQException( "section list: Section node needs attribute 'ContentType'!"); - - XQModelSection section(idx, sheetNode->find_child_by_tag_name("Data")); - qDebug() << " ---- ADD section: " << sheetNode->attribute( c_ContentType); - addAtKey(sheetNode->attribute( c_ContentType), section); -} +//! testet, ob die unter 'sectionKey' eine gültige section vorhanden ist. bool XQModelSectionList::hasValidSection(const QString& sectionKey) const { + qDebug() << " ---- FIND section: " << sectionKey << ":" << contains(sectionKey) << ":" << at(sectionKey).isValid(); if (!contains(sectionKey) ) return false; return at(sectionKey).isValid(); } +//! gibt für einen model index die 'zuständige' section zurück. -const XQModelSection& XQModelSectionList::sectionxqItemFromIndex( const QModelIndex& index ) const +const XQModelSection& XQModelSectionList::sectionFromIndex( const QModelIndex& index ) const { return sectionFromRow( 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 { @@ -99,18 +95,26 @@ const XQModelSection& XQModelSectionList::sectionFromRow(int itemRow ) const } +//! ermittelt die erste zeile einer section. + int XQModelSectionList::firstRow(const QModelIndex& idx) const { return sectionFromRow(idx.row() ).row(); } +//! ermittelt die zeile unterhalb des gegebenen modelindex, +//! zum einfügen neuer items ebendort. + int XQModelSectionList::lastRow(const QModelIndex& idx) const { return lastRow(sectionFromRow(idx.row())); } +//! ermittelt die zeile unterhalb der gegebenen section, +//! zum einfügen neuer items ebendort. + int XQModelSectionList::lastRow(const XQModelSection& section ) const { //qDebug() << " -- last row in section: " << section.modelIndex.data().toString() << " --> " << section.modelIndex.row(); @@ -129,6 +133,8 @@ int XQModelSectionList::lastRow(const XQModelSection& section ) const } +//! gibt alle sections aus, zum ankucken. + void XQModelSectionList::dump() const { qDebug() << " --- sections dump(): " < -#include -#include -class XQItem; +#include +#include /** * @brief Struct containing data for a header section @@ -54,11 +53,11 @@ public: XQModelSectionList() = default; virtual ~XQModelSectionList() = default; - void addSectionEntry(const QModelIndex& idx, XQNodePtr sheetNode ); + void createSectionEntry(const XQItemList& list, const XQNodePtr& sheetNode ); bool hasValidSection(const QString& sectionKey) const; const XQModelSection& sectionFromRow( int row ) const; - const XQModelSection& sectionxqItemFromIndex( const QModelIndex& index ) const; + const XQModelSection& sectionFromIndex( const QModelIndex& index ) const; int firstRow(const QModelIndex& idx) const; int lastRow(const QModelIndex& idx) const; diff --git a/src/model/xqviewmodel.cpp b/src/model/xqviewmodel.cpp index 258348e..52bebae 100644 --- a/src/model/xqviewmodel.cpp +++ b/src/model/xqviewmodel.cpp @@ -104,12 +104,12 @@ void XQViewModel::initModel(const QString& modelName) // #1: über alle sections for( auto& section : modelSheet->children() ) { - // #2: (optionalen) header erzeugen + // #2: (optionalen?) header erzeugen const XQNodePtr header = section->find_child_by_tag_name( "Header"); if( header ) { - XQItemList list = _itemFactory.makeHeaderRow( header ); - Q_ASSERT(!list.isEmpty()); + //XQItemList list = _itemFactory.makeHeaderRow( header ); + XQItemList list = _itemFactory.makeContentRow( header, nullptr ); addSection(list, section ); } @@ -117,6 +117,33 @@ void XQViewModel::initModel(const QString& modelName) } +//! hilfsfunktion: fügt die liste unserem model hinzu und erzeugt eine 'section'. +//! die section kann erst gültig sein, wenn die items im model gelandet sind, +//! deswegen ist das hier zusammengefasst. + +//! erzeugt dann eine section aus einer frisch erzeugten itemlist. der erste modelindex +//! der liste und der unterknoten 'Data' werden gespeichert. + +void XQViewModel::addSection(const XQItemList& list, const XQNodePtr& sheetNode ) +{ + // 1. die liste darf nicht leer sein + Q_ASSERT(!list.isEmpty()); + // 2. sheetNode muss da sein + Q_ASSERT(sheetNode); + // 3. 'ContenType' muss vorhanden sein + if( !sheetNode->has_attribute( c_ContentType) ) + throw XQException( "section list: Section node needs attribute 'ContentType'!"); + // 4. Data child muss auch da sein + XQNodePtr dataNode = sheetNode->find_child_by_tag_name( c_Data ); + if( !dataNode ) + throw XQException( "section list: 'Data' child is missing!"); + + // 5. das erzeugt dann auch valide indices + appendRow(list); + + XQModelSection section(list[0]->index(), dataNode ); + _sections.addAtKey(sheetNode->attribute( c_ContentType), section); +} //! SLOT, der aufgerufen wird, wenn eine edit-action getriggert wurde. void XQViewModel::onActionTriggered(QAction* action) @@ -263,10 +290,13 @@ void XQViewModel::cmdCut( XQCommand& command ) { // ... holen das erste item, das auch den content node enthält //const XQNodeBackup& entry = *it; - //XQItem& firstItem = xqFirstItem( (*it).itemPos ); - //qDebug() << " --- Cut: " << firstItem.text() << " " << firstItem.row() << " id#" << entry.contentNode->_id; // jetzt löschen, dabei wird die parent-verbindung entfernt const XQNodeBackup& entry = *it; + + XQItem& firstItem = xqFirstItem( (*it).itemPos ); + qDebug() << " --- Cut: " << firstItem.text() << " " << firstItem.row() << " id#" << entry.contentNode->_id; + + entry.contentNode->unlink_self(); removeRow(entry.itemPos ); } @@ -404,7 +434,7 @@ void XQViewModel::cmdNew( XQCommand& command ) // store node in node->parent() //node->add_before_me( newNode ); // store node also in 'command' to enable undo - const XQModelSection& section = _sections.sectionxqItemFromIndex( origin ); + const XQModelSection& section = _sections.sectionFromIndex( origin ); // create new item row XQItemList list = _itemFactory.createGenericRow( newNode, section.sheetRootNode ); @@ -484,15 +514,6 @@ void XQViewModel::setupViewProperties() } -//! füg eine section mit header hinzu. - -void XQViewModel::addSection( const XQItemList& list, const XQNodePtr& sheetNode ) -{ - appendRow(list); - _sections.addSectionEntry( list[0]->index(), sheetNode ); -} - - //! gibt den undo-stack zurück. QUndoStack* XQViewModel::undoStack() diff --git a/src/model/xqviewmodel.h b/src/model/xqviewmodel.h index 6085a88..8b84534 100644 --- a/src/model/xqviewmodel.h +++ b/src/model/xqviewmodel.h @@ -104,9 +104,6 @@ signals: protected: void addSection(const XQItemList& list, const XQNodePtr& sheetNode ); - -protected: - virtual void initContextMenu() = 0; // __fixme: should be created from xml diff --git a/src/xtree.pro b/src/xtree.pro index 1415e11..00a8b87 100644 --- a/src/xtree.pro +++ b/src/xtree.pro @@ -15,7 +15,6 @@ HEADERS += \ application/xqmainmodel.h \ application/xqmainwindow.h \ application/xqappdata.h \ - items/xqgenericitem.h \ items/xqitem.h \ items/xqitemfactory.h \ items/xqitemtype.h \ @@ -52,7 +51,6 @@ SOURCES += \ application/xqmainmodel.cpp \ application/xqmainwindow.cpp \ application/xqappdata.cpp \ - items/xqgenericitem.cpp \ items/xqitem.cpp \ items/xqitemfactory.cpp \ items/xqitemtype.cpp \ diff --git a/xml/modelsheets.xml b/xml/modelsheets.xml index 83267c2..ad50027 100644 --- a/xml/modelsheets.xml +++ b/xml/modelsheets.xml @@ -8,7 +8,7 @@ - +