Files
xtree.old.ng/src/application/xqchildmodel.cpp

171 lines
5.3 KiB
C++
Raw Normal View History

2025-08-05 22:39:41 +02:00
/***************************************************************************
source::worx xtree
Copyright © 2024-2025 c.holzheuer
christoph.holzheuer@gmail.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
***************************************************************************/
#include <znode_factory.h>
#include <xqchildmodel.h>
#include <xqselectionmodel.h>
#include <xqitemdelegate.h>
#include <xqappdata.h>
2025-08-07 03:11:56 +02:00
#include <xqtreetable.h>
2025-08-05 22:39:41 +02:00
#include <xqitemfactory.h>
2025-08-07 18:49:18 +02:00
//! default konstruktor.
2025-08-05 22:39:41 +02:00
XQChildModel::XQChildModel( QObject *parent )
2025-08-07 03:11:56 +02:00
: XQViewModel{parent}
2025-08-05 22:39:41 +02:00
{
}
2025-08-07 18:49:18 +02:00
//! erzeugt die basisstruktur des models.
2025-08-13 22:25:01 +02:00
/*
2025-08-05 22:39:41 +02:00
void XQChildModel::initModel(const QString& modelName)
{
2025-08-09 11:56:11 +02:00
2025-08-13 19:25:14 +02:00
auto extendItemType = [=,this](const XQNodePtr& entry)
2025-08-09 11:56:11 +02:00
{
const QString& typeName = entry->attribute("ItemType");
XQItemType* itemType = _itemFactory.findItemTypeTemplate( typeName); // throws
// über alle attribute
for (const auto& attr : entry->attributes())
{
// prüfen, ob der itemType des attribute schon hat
int role = itemType->hasAttribute( attr.first);
// wenn ja, überschreiben
if( role != XQItem::NoRole )
{
QVariant newValue = _itemFactory.makeVariant(role,attr.second);
itemType->replaceAttribute( newValue, role );
}
}
};
2025-08-05 22:39:41 +02:00
// #0: Wir suchen die Model-Beschreibung
XQNodePtr modelSheet = _itemFactory.findModelSheet( modelName ); // throws
2025-08-09 11:56:11 +02:00
// #1: Wir erzeugen die Model-Struktur: Jedes Kind beschreibt einen
2025-08-05 22:39:41 +02:00
// XML-Datentyp, z.B. <Panel atr1="..." />, <Battery .../>
// Jeder XML-Knoten entspricht einer Zeile im späteren Model, jedes
// Attribut wird einem eigenen Feld (XQItem) abgebildet.
2025-08-09 11:56:11 +02:00
for( const auto& sheetNode : modelSheet->children() )
2025-08-05 22:39:41 +02:00
{
2025-08-09 11:56:11 +02:00
2025-08-05 22:39:41 +02:00
XQItemList list = _itemFactory.makeHeaderRow( sheetNode );
// für jeden XML-Knotentyp in der Modelbeschreibung erzeugen wir eine section
addSection(list, sheetNode );
2025-08-09 11:56:11 +02:00
// jedes kind kann enthält einen itemType und einen headerItemType. Für
// diese sind eventuell weitere attribute vorhanden, die die im type
// enthaltenen defualt-werte überschreiben.
for( const auto& sheetChild : sheetNode->children() )
{
//qDebug() << "---- kloppo: " << sheetChild->tag_name() << ": " << sheetChild->to_string();
extendItemType( sheetChild );
}
2025-08-13 22:25:01 +02:00
2025-08-09 11:56:11 +02:00
// empty row:
2025-08-13 22:25:01 +02:00
// XQNodePtr contentNode = XQNode::make_node( sheetNode->tag_name() );
// XQItemList emptyRow = _itemFactory.makeEmptyRow( contentNode, sheetNode );
// appendRow( emptyRow );
2025-08-05 22:39:41 +02:00
} // for
}
2025-08-13 22:25:01 +02:00
*/
2025-08-05 22:39:41 +02:00
2025-08-07 18:49:18 +02:00
//! erzegut den sichtbaren inhalt des models aus einem root-datenknoten.
2025-08-05 22:39:41 +02:00
void XQChildModel::setContent( const XQNodePtr& contentRoot )
{
// __fix: set object name ??
qDebug() << " --- create Model Data: " << contentRoot->to_string();
// Die Datenbasis als shared_ptr sichern
_contentRoot = contentRoot;
// Wir gehen über alle Einträge, die verschiedenen Typen
// haben, hier: <Panel>. <Battery> ...
for (const auto& contentEntry : _contentRoot->children())
{
// Das ist hier der Typ des Eintrags: Panel, Battery ...
QString key = contentEntry->tag_name();
// 'silent failure' hier der Datenbaum kann auch Knoten enthalten
// die nicht für uns gedacht sind.
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
section.contentRootNode = contentEntry->parent();
int newRow = _sections.lastRow(section);
2025-08-06 23:34:43 +02:00
//qDebug() << " --- AHJA: " << key << " -- last Row dazu: " << newRow;
2025-08-05 22:39:41 +02:00
XQItemList list = _itemFactory.makeContentRow( contentEntry, section.sheetRootNode );
// als Baum?
//section.headerItem().appendRow( list );
insertRow( newRow, list);
} // for
}
2025-08-07 18:49:18 +02:00
//! erzeugt ein adhoc-contextmenu, je nachdem welche aktionen gerade möflich sind.
2025-08-05 22:39:41 +02:00
void XQChildModel::initContextMenu()
{
// __fixme! add a menu title
_contextMenu->clear();
2025-08-07 10:39:42 +02:00
const QModelIndex& curIdx = _treeTable->currentIndex();
bool hasSel = curIdx.isValid() && _treeTable->selectionModel()->hasSelection();
2025-08-05 22:39:41 +02:00
bool canPaste = _clipBoard.canPaste( curIdx );
_contextMenu->addAction( "icn11Dummy", "Undo", XQCommand::cmdUndo, _undoStack->canUndo() );
_contextMenu->addAction( "icn17Dummy", "Redo", XQCommand::cmdRedo, _undoStack->canRedo() );
_contextMenu->addAction( "icn58Dummy", "Cut", XQCommand::cmdCut, hasSel );
_contextMenu->addAction( "icn61Dummy", "Paste", XQCommand::cmdPaste, canPaste );
_contextMenu->addAction( "icn55Dummy", "Copy", XQCommand::cmdCopy, hasSel );
//_contextMenu->addAction( "icn35Dummy", "Move", XQCommand::cmdMove, hasSel );
_contextMenu->addAction( "icn70Dummy", "New", XQCommand::cmdNew, hasSel );
_contextMenu->addAction( "icn50Dummy", "Delete", XQCommand::cmdDelete, hasSel );
// __fixme! set 'toggle section <name>' entry
//contextMenu.actions().first()->setText("<name>");
_contextMenu->addAction( "icn29Dummy", "Toggle Section", XQCommand::cmdToggleSection, hasSel);
}