Compare commits
13 Commits
experiment
...
main
Author | SHA1 | Date | |
---|---|---|---|
306a68f6c9 | |||
![]() |
0ec1f7a7c0 | ||
6393096072 | |||
123dc695d9 | |||
c870ef8801 | |||
![]() |
429c939cdf | ||
0f7299a74a | |||
1433e393f7 | |||
372873717e | |||
a13a1de8fe | |||
8756793039 | |||
d249c9c631 | |||
062b935a7c |
@@ -77,10 +77,10 @@ namespace XQAppData
|
|||||||
namedInsert( "BrowserStop", QStyle::SP_BrowserStop );
|
namedInsert( "BrowserStop", QStyle::SP_BrowserStop );
|
||||||
namedInsert( "icn33Dummy", QStyle::SP_DriveHDIcon );
|
namedInsert( "icn33Dummy", QStyle::SP_DriveHDIcon );
|
||||||
namedInsert( "icn34Dummy", QStyle::SP_MessageBoxQuestion );
|
namedInsert( "icn34Dummy", QStyle::SP_MessageBoxQuestion );
|
||||||
namedInsert( "icn35Dummy", QStyle::SP_CommandLink );
|
namedInsert( "CommandLink", QStyle::SP_CommandLink );
|
||||||
namedInsert( "icn36Dummy", QStyle::SP_DriveNetIcon );
|
namedInsert( "icn36Dummy", QStyle::SP_DriveNetIcon );
|
||||||
namedInsert( "icn37Dummy", QStyle::SP_MessageBoxWarning );
|
namedInsert( "MessageBoxWarning", QStyle::SP_MessageBoxWarning );
|
||||||
namedInsert( "icn38Dummy", QStyle::SP_ComputerIcon );
|
namedInsert( "ComputerIcon", QStyle::SP_ComputerIcon );
|
||||||
namedInsert( "icn39Dummy", QStyle::SP_FileDialogBack );
|
namedInsert( "icn39Dummy", QStyle::SP_FileDialogBack );
|
||||||
namedInsert( "icn40Dummy", QStyle::SP_TitleBarCloseButton );
|
namedInsert( "icn40Dummy", QStyle::SP_TitleBarCloseButton );
|
||||||
namedInsert( "icn42Dummy", QStyle::SP_FileDialogContentsView );
|
namedInsert( "icn42Dummy", QStyle::SP_FileDialogContentsView );
|
||||||
@@ -114,7 +114,7 @@ namespace XQAppData
|
|||||||
namedInsert( "TrashIcon", QStyle::SP_TrashIcon );
|
namedInsert( "TrashIcon", QStyle::SP_TrashIcon );
|
||||||
namedInsert( "icn72Dummy", QStyle::SP_DialogSaveButton );
|
namedInsert( "icn72Dummy", QStyle::SP_DialogSaveButton );
|
||||||
namedInsert( "icn73Dummy", QStyle::SP_MediaPause );
|
namedInsert( "icn73Dummy", QStyle::SP_MediaPause );
|
||||||
namedInsert( "icn74Dummy", QStyle::SP_VistaShield );
|
namedInsert( "VistaShield", QStyle::SP_VistaShield );
|
||||||
namedInsert( "icn75Dummy", QStyle::SP_DialogYesButton );
|
namedInsert( "icn75Dummy", QStyle::SP_DialogYesButton );
|
||||||
namedInsert( "icn76Dummy", QStyle::SP_MediaPlay );
|
namedInsert( "icn76Dummy", QStyle::SP_MediaPlay );
|
||||||
namedInsert( "icn77Dummy", QStyle::SP_DirClosedIcon );
|
namedInsert( "icn77Dummy", QStyle::SP_DirClosedIcon );
|
||||||
|
@@ -29,7 +29,7 @@ const QString c_ItemType = "ItemType";
|
|||||||
const QString c_Caption = "Caption";
|
const QString c_Caption = "Caption";
|
||||||
const QString c_Header = "Header";
|
const QString c_Header = "Header";
|
||||||
const QString c_ContentType = "ContentType";
|
const QString c_ContentType = "ContentType";
|
||||||
const QString c_Data = "Data";
|
const QString c_ModelSheet = "ModelSheet";
|
||||||
|
|
||||||
const QString c_MainModelName = "DocumentTreeModel";
|
const QString c_MainModelName = "DocumentTreeModel";
|
||||||
const QString c_ChildModelName = "DocumentDetailsModel";
|
const QString c_ChildModelName = "DocumentDetailsModel";
|
||||||
|
@@ -43,8 +43,8 @@ void XQChildModel::setContent( const XQNodePtr& contentRoot )
|
|||||||
// Die Datenbasis als shared_ptr sichern
|
// Die Datenbasis als shared_ptr sichern
|
||||||
_contentRoot = contentRoot;
|
_contentRoot = contentRoot;
|
||||||
|
|
||||||
// Wir gehen über alle Einträge, die verschiedenen Typen
|
// Wir gehen über alle Einträge, die auch unterschiedliche Typen
|
||||||
// haben, hier: <Panel>. <Battery> ...
|
// haben können, hier: <Panel>. <Battery> ...
|
||||||
for (const auto& contentEntry : _contentRoot->children())
|
for (const auto& contentEntry : _contentRoot->children())
|
||||||
{
|
{
|
||||||
// Das ist hier der Typ des Eintrags: Panel, Battery ...
|
// Das ist hier der Typ des Eintrags: Panel, Battery ...
|
||||||
@@ -59,10 +59,12 @@ void XQChildModel::setContent( const XQNodePtr& contentRoot )
|
|||||||
// wir speichern das parent des datenknoten auch in der
|
// wir speichern das parent des datenknoten auch in der
|
||||||
// section.
|
// section.
|
||||||
// contentEntry->parent == _contentRoot, aber halt nur weil das model flach ist
|
// contentEntry->parent == _contentRoot, aber halt nur weil das model flach ist
|
||||||
section.contentRootNode = contentEntry->parent();
|
section.setContentRootNode( contentEntry->parent() );
|
||||||
int newRow = _sections.lastRow(section);
|
int newRow = _sections.lastRow(section);
|
||||||
|
|
||||||
XQItemList list = _itemFactory.makeContentRow( section.sheetRootNode, contentEntry );
|
XQNodePtr node = section.sheetRootNode();
|
||||||
|
XQItemList list = _itemFactory.makeContentRow( node, contentEntry );
|
||||||
|
//XQItemList list = _itemFactory.makeContentRow( section.sheetRootNode, contentEntry );
|
||||||
|
|
||||||
// als Baum?
|
// als Baum?
|
||||||
//section.headerItem().appendRow( list );
|
//section.headerItem().appendRow( list );
|
||||||
|
@@ -41,3 +41,48 @@ void XQMainModel::initContextMenu()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! erzeugt einen eintrag in der baum-übersicht.
|
||||||
|
|
||||||
|
XQItem* XQMainModel::addProjectItem( XQNodePtr contentNode )
|
||||||
|
{
|
||||||
|
// wir durchsuchen alle unsere section nach dem passenden content-type,
|
||||||
|
// hier: content-type beschreibt die
|
||||||
|
for(const auto& section : _sections )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( contentNode->attribute( c_ContentType) == section.contentType() )
|
||||||
|
{
|
||||||
|
const QString& content = contentNode->attribute( "ProjectName" );
|
||||||
|
// __fixme! das ist mist!
|
||||||
|
const XQNodePtr sheetNode = section.sheetRootNode()->first_child();
|
||||||
|
XQItem* newItem = _itemFactory.makeStaticItem(sheetNode, content );
|
||||||
|
// erzeuger sheet node speichern
|
||||||
|
newItem->setSheetNode( sheetNode );
|
||||||
|
|
||||||
|
// den neuen eintrag in die passende section der übersicht eintragen ...
|
||||||
|
section.headerItem().appendRow( newItem );
|
||||||
|
// ... ausklappen...
|
||||||
|
const QModelIndex index = section.headerItem().index();
|
||||||
|
_treeTable->expand( index );
|
||||||
|
// ... und markieren
|
||||||
|
_treeTable->setCurrentIndex( index );
|
||||||
|
// quellknoten auch speichern
|
||||||
|
//newItem->setContentNode( contentNode );
|
||||||
|
//emit itemCreated( newItem );
|
||||||
|
|
||||||
|
return newItem;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
throw XQException( "addProjectItem: main model should not be empty!" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void XQMainModel::addSectionItem( const XQModelSection& section, XQItem* projectItem )
|
||||||
|
{
|
||||||
|
XQNodePtr sheetNode = projectItem->sheetNode()->find_child_by_tag_name("CurrentSection");
|
||||||
|
XQItem* newItem = _itemFactory.makeStaticItem(sheetNode, section.contentType() );
|
||||||
|
projectItem->appendRow( newItem );
|
||||||
|
_treeTable->expand( projectItem->index() );
|
||||||
|
}
|
||||||
|
@@ -32,9 +32,8 @@ public:
|
|||||||
explicit XQMainModel(QObject *parent = nullptr);
|
explicit XQMainModel(QObject *parent = nullptr);
|
||||||
virtual ~XQMainModel() = default;
|
virtual ~XQMainModel() = default;
|
||||||
|
|
||||||
|
XQItem* addProjectItem( XQNodePtr contentNode );
|
||||||
|
void addSectionItem( const XQModelSection& section, XQItem* projectItem );
|
||||||
public slots:
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@@ -15,12 +15,14 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
#include <xqmainwindow.h>
|
#include <xqmainwindow.h>
|
||||||
#include <xqcommand.h>
|
#include <xqcommand.h>
|
||||||
#include <xqexception.h>
|
#include <xqexception.h>
|
||||||
#include <xqitemfactory.h>
|
#include <xqitemfactory.h>
|
||||||
#include <xqnodewriter.h>
|
#include <xqnodewriter.h>
|
||||||
|
#include <xqquickwidget.h>
|
||||||
|
|
||||||
|
|
||||||
//! konstruktor.
|
//! konstruktor.
|
||||||
@@ -87,10 +89,20 @@ void XQMainWindow::initMainWindow()
|
|||||||
|
|
||||||
//connect( _mainTreeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(onDoubleClicked(QModelIndex)) );
|
//connect( _mainTreeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(onDoubleClicked(QModelIndex)) );
|
||||||
connect( _mainTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(onTreeItemClicked(QModelIndex)) );
|
connect( _mainTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(onTreeItemClicked(QModelIndex)) );
|
||||||
connect( _tabWidget, SIGNAL(tabBarClicked(int)), this, SLOT(onTabClicked(int)) );
|
connect( _tabWidget, SIGNAL(tabBarClicked(int)), this, SLOT(onTabClicked(int)) );
|
||||||
|
|
||||||
|
connect( _tabWidget, SIGNAL(tabBarClicked(int)), this, SLOT(onTabClicked(int)) );
|
||||||
|
|
||||||
connect( &_mainModelView, &XQViewModel::xqItemCreated, this, [=, this](XQItem* item)
|
/*
|
||||||
|
XQQuickWidget* butt = new XQQuickWidget;
|
||||||
|
butt->resize(800,600);
|
||||||
|
butt->setWindowFlags(Qt::Dialog | Qt::WindowStaysOnTopHint);
|
||||||
|
butt->move( 1200,300);
|
||||||
|
butt->show();
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
connect( &_mainModelView, &XQViewModel::itemCreated, this, [=, this](XQItem* item)
|
||||||
{
|
{
|
||||||
// when a new main tree item has been created ...
|
// when a new main tree item has been created ...
|
||||||
QString pID = item->contentNode()->attribute(c_ProjectID);
|
QString pID = item->contentNode()->attribute(c_ProjectID);
|
||||||
@@ -99,6 +111,7 @@ void XQMainWindow::initMainWindow()
|
|||||||
if( _documentStore.contains( pID ) )
|
if( _documentStore.contains( pID ) )
|
||||||
_tabWidget->setCurrentWidget( _documentStore[pID].modelView->treeTable() );
|
_tabWidget->setCurrentWidget( _documentStore[pID].modelView->treeTable() );
|
||||||
} );
|
} );
|
||||||
|
*/
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -110,7 +123,7 @@ void XQMainWindow::initMainWindow()
|
|||||||
_mainModelView.initModel( c_MainModelName );
|
_mainModelView.initModel( c_MainModelName );
|
||||||
|
|
||||||
// #2. load demo data
|
// #2. load demo data
|
||||||
loadDocument( c_DocumentFileName1 );
|
//loadDocument( c_DocumentFileName1 );
|
||||||
//loadDocument( c_DocumentFileName2 );
|
//loadDocument( c_DocumentFileName2 );
|
||||||
|
|
||||||
qDebug() << " --- all here: " << XQNode::s_Count;
|
qDebug() << " --- all here: " << XQNode::s_Count;
|
||||||
@@ -244,15 +257,20 @@ void XQMainWindow::onTreeItemClicked(const QModelIndex& index )
|
|||||||
|
|
||||||
XQItem& entry = XQItem::xqItemFromIndex(index);
|
XQItem& entry = XQItem::xqItemFromIndex(index);
|
||||||
|
|
||||||
qDebug() << " --- mainWindow onTreeItemClicked:" << entry.text();
|
qDebug() << " --- XXX mainWindow onTreeItemClicked:" << entry.text();
|
||||||
|
_mainTreeView->selectionModel()->select(index, QItemSelectionModel::Select);
|
||||||
|
//entry.setBackground( QBrush( Qt::green ) );
|
||||||
|
|
||||||
return;
|
QVariant variant = entry.QStandardItem::data( XQItem::ContentNodeRole );
|
||||||
//_mainTreeView->selectionModel()->select(index, QItemSelectionModel::Select);
|
|
||||||
//entry->setBackground( QBrush( Qt::green ) );
|
|
||||||
|
|
||||||
QString key = entry.attribute(c_ProjectID);
|
XQNodePtr ptr = variant.value<XQNodePtr>();
|
||||||
if( _documentStore.contains(key) )
|
|
||||||
_tabWidget->setCurrentWidget( _documentStore[key].modelView->treeTable() );
|
QString key = entry.attribute(c_ProjectID);
|
||||||
|
qDebug() << " --- FIRZ: key: " << key;
|
||||||
|
|
||||||
|
bool isThere = _documentStore.contains(key);
|
||||||
|
if( isThere)
|
||||||
|
_tabWidget->setCurrentWidget( _documentStore[key].modelView->treeTable() );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,30 +284,41 @@ void XQMainWindow::onTabClicked( int index )
|
|||||||
_mainTreeView->setCurrentIndex( _documentStore[index].treeItem->index() );
|
_mainTreeView->setCurrentIndex( _documentStore[index].treeItem->index() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XQMainWindow::onSectionCreated( const XQModelSection& section )
|
||||||
|
{
|
||||||
|
if( _currentProjectItem )
|
||||||
|
{
|
||||||
|
_mainModelView.addSectionItem( section, _currentProjectItem );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void XQMainWindow::onSectionToggled( const XQModelSection& section )
|
||||||
|
{
|
||||||
|
//qDebug() << " --- XXX section toggled: " << section.contentType() << ":" << section.sheetRootNode()->to_string();
|
||||||
|
}
|
||||||
|
|
||||||
//! liest eine XML datei namens 'fileName'
|
//! liest eine XML datei namens 'fileName'
|
||||||
|
|
||||||
void XQMainWindow::loadDocument( const QString& fileName )
|
void XQMainWindow::loadDocument( const QString& fileName )
|
||||||
{
|
{
|
||||||
// gibts die Datei?
|
|
||||||
|
// gibts die Datei?
|
||||||
if( !QFile::exists( fileName) )
|
if( !QFile::exists( fileName) )
|
||||||
throw XQException( "no such file", fileName );
|
throw XQException( "no such file", fileName );
|
||||||
|
|
||||||
// load data tree from xml file
|
|
||||||
XQNodeFactory treeLoader;
|
XQNodeFactory treeLoader;
|
||||||
|
// xml daten laden
|
||||||
XQNodePtr rawTree = treeLoader.load_tree( qPrintable(fileName) );
|
XQNodePtr rawTree = treeLoader.load_tree( qPrintable(fileName) );
|
||||||
|
|
||||||
// versteckten root node ignorieren
|
// versteckten root node ignorieren
|
||||||
XQNodePtr contentRoot = rawTree->first_child();
|
XQNodePtr contentRoot = rawTree->first_child();
|
||||||
|
|
||||||
// Project-ID behandeln
|
// Project-ID behandeln
|
||||||
const QString& pID = contentRoot->attribute(c_ProjectID);
|
const QString& pID = contentRoot->attribute(c_ProjectID);
|
||||||
int idx = _documentStore.indexOf( pID );
|
int idx = _documentStore.indexOf( pID );
|
||||||
if( idx > -1 )
|
if( idx > -1 )
|
||||||
{
|
{
|
||||||
const XQDocument& doc = _documentStore.at(idx);
|
const XQDocument& document = _documentStore.at(idx);
|
||||||
QMessageBox::warning( this, "Load Document", QString("File: %1 already loaded.").arg( fileName ) );
|
QMessageBox::warning( this, "Load Document", QString("File: %1 already loaded.").arg( fileName ) );
|
||||||
_mainTreeView->setCurrentIndex( doc.treeItem->index() );
|
_mainTreeView->setCurrentIndex( document.treeItem->index() );
|
||||||
_tabWidget->setCurrentIndex( idx );
|
_tabWidget->setCurrentIndex( idx );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -307,22 +336,28 @@ void XQMainWindow::loadDocument( const QString& fileName )
|
|||||||
|
|
||||||
// Ein neues Child-Model erzeugen
|
// Ein neues Child-Model erzeugen
|
||||||
XQChildModel* childModel = new XQChildModel(this);
|
XQChildModel* childModel = new XQChildModel(this);
|
||||||
// die Modelstruktur anlegen
|
|
||||||
childModel->initModel( c_ChildModelName );
|
connect( childModel, SIGNAL(sectionCreated(XQModelSection)), this, SLOT(onSectionCreated(XQModelSection)) );
|
||||||
|
connect( childModel, SIGNAL(sectionToggled(XQModelSection)), this, SLOT(onSectionToggled(XQModelSection)) );
|
||||||
|
|
||||||
// Den globalen undo-stack ...
|
// Den globalen undo-stack ...
|
||||||
childModel->setUndoStack(&_undoStack);
|
childModel->setUndoStack(&_undoStack);
|
||||||
|
|
||||||
// und die TreeView übergeben
|
// und die TreeView übergeben
|
||||||
childModel->setTreeTable(childTreeView);
|
childModel->setTreeTable(childTreeView);
|
||||||
|
|
||||||
// read the model data
|
// neuen eintrag im übsichts-baum erzeugen
|
||||||
|
_currentProjectItem = _mainModelView.addProjectItem( contentRoot );
|
||||||
|
_documentStore.addDocument( fileName, pTitle, _currentProjectItem, childModel );
|
||||||
|
|
||||||
|
qDebug() << " --- ZZZ und jetzt:";
|
||||||
|
|
||||||
|
// die Modelstruktur anlegen
|
||||||
|
childModel->initModel( c_ChildModelName );
|
||||||
|
|
||||||
|
// model inhalte laden
|
||||||
childModel->setContent( contentRoot->first_child() );
|
childModel->setContent( contentRoot->first_child() );
|
||||||
|
|
||||||
/*
|
|
||||||
// create new entry in the left side main tree view
|
|
||||||
XQItem* newEntry = _mainModelView.createTreeEntry( contentRoot );
|
|
||||||
_mainTreeView->setCurrentIndex( newEntry->index() );
|
|
||||||
_documentStore.addDocument( fileName, pTitle, newEntry, childModel );
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -48,6 +48,10 @@ public slots:
|
|||||||
|
|
||||||
void onTreeItemClicked(const QModelIndex& index );
|
void onTreeItemClicked(const QModelIndex& index );
|
||||||
void onTabClicked( int index );
|
void onTabClicked( int index );
|
||||||
|
//void onItemCreated( XQItem* item );
|
||||||
|
void onSectionCreated( const XQModelSection& section);
|
||||||
|
void onSectionToggled( const XQModelSection& section );
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@@ -58,10 +62,12 @@ protected:
|
|||||||
void loadDocument( const QString& fileName );
|
void loadDocument( const QString& fileName );
|
||||||
void saveDocument( const QString& fileName );
|
void saveDocument( const QString& fileName );
|
||||||
|
|
||||||
|
|
||||||
QUndoStack _undoStack;
|
QUndoStack _undoStack;
|
||||||
XQDocumentStore _documentStore;
|
XQDocumentStore _documentStore;
|
||||||
|
|
||||||
XQMainModel _mainModelView;
|
XQMainModel _mainModelView;
|
||||||
|
XQItem* _currentProjectItem{};
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -136,14 +136,6 @@ XQItem::XQItem(XQItemType* itemType, const QString *content )
|
|||||||
setContent(content);
|
setContent(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warum beides?
|
|
||||||
XQItem::XQItem(XQItemType* itemType, const QString *content, const XQNodePtr& contentNode )
|
|
||||||
: XQItem{ itemType, content }
|
|
||||||
{
|
|
||||||
setContentNode(contentNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! ruft den copy-konstruktor auf.
|
//! ruft den copy-konstruktor auf.
|
||||||
|
|
||||||
XQItem* XQItem::clone() const
|
XQItem* XQItem::clone() const
|
||||||
@@ -166,7 +158,10 @@ bool XQItem::isValid() const
|
|||||||
|
|
||||||
XQNodePtr XQItem::contentNode() const
|
XQNodePtr XQItem::contentNode() const
|
||||||
{
|
{
|
||||||
return data( ContentNodeRole ).value<XQNodePtr>();
|
XQNodePtr node = data( ContentNodeRole ).value<XQNodePtr>();
|
||||||
|
if( node )
|
||||||
|
return node;
|
||||||
|
throw XQException("XQItem::contentNode() nullptr");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -257,6 +252,14 @@ void XQItem::clearFlag( Qt::ItemFlag newFlag )
|
|||||||
setFlags( flags() & ~newFlag);
|
setFlags( flags() & ~newFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! gibt die itemFlags als string zurück.
|
||||||
|
|
||||||
|
QString XQItem::itemFlagsToString() const
|
||||||
|
{
|
||||||
|
return'(' + data(XQItem::FlagsRole).toString() +')';
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// data() access shortcuts
|
/// data() access shortcuts
|
||||||
///
|
///
|
||||||
@@ -277,6 +280,7 @@ QString XQItem::renderStyleToString() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! setzt den editorType. wird im itemType gespeichert.
|
//! setzt den editorType. wird im itemType gespeichert.
|
||||||
|
|
||||||
void XQItem::setRenderStyle(RenderStyle renderStyle )
|
void XQItem::setRenderStyle(RenderStyle renderStyle )
|
||||||
@@ -332,18 +336,20 @@ void XQItem::setUnitType(UnitType unitType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! gibt den content-string zurück. das ist ein derefenzierter pointer
|
//! Verweist auf data(Qt::EditRole). Das ist der unformatierte text.
|
||||||
//! auf das zu diesem item gehörige daten-attribut 'useres' datenknotens.
|
|
||||||
|
|
||||||
const QString& XQItem::content() const
|
QString XQItem::rawText() const
|
||||||
{
|
{
|
||||||
const QString* contentPtr = QStandardItem::data( XQItem::ContentRole ).value<const QString*>();
|
return data( Qt::EditRole ).toString();
|
||||||
if(contentPtr)
|
}
|
||||||
return *contentPtr;
|
|
||||||
|
|
||||||
static const QString s_dummyContent("-");
|
|
||||||
|
|
||||||
return s_dummyContent;
|
//! Gibt den string-zeiger auf das attribut aus unseren XQNodePtr zurück.
|
||||||
|
|
||||||
|
QString* XQItem::content() const
|
||||||
|
{
|
||||||
|
// macht jetzt das, ws draufsteht: gibt einen string* zurück
|
||||||
|
return data( XQItem::ContentRole ).value<QString*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -357,9 +363,9 @@ void XQItem::setContent( const QString* content )
|
|||||||
|
|
||||||
//! holt den schlüssel bzw. bezeicher des content() string aus 'unserem' content knoten.
|
//! holt den schlüssel bzw. bezeicher des content() string aus 'unserem' content knoten.
|
||||||
|
|
||||||
const QString& XQItem::contentKey() const
|
QString XQItem::contentKey() const
|
||||||
{
|
{
|
||||||
return contentNode()->attributes().key_of( content() );
|
return contentNode()->attributes().key_of( rawText() );
|
||||||
}
|
}
|
||||||
|
|
||||||
//! gibt den content-format string zurück
|
//! gibt den content-format string zurück
|
||||||
@@ -478,12 +484,18 @@ QVariant XQItem::data(int role ) const
|
|||||||
case Qt::EditRole :
|
case Qt::EditRole :
|
||||||
case XQItem::ContentRole:
|
case XQItem::ContentRole:
|
||||||
{
|
{
|
||||||
return content();
|
|
||||||
|
const QString* contentPtr = QStandardItem::data( XQItem::ContentRole ).value<const QString*>();
|
||||||
|
if(contentPtr)
|
||||||
|
return *contentPtr;
|
||||||
|
|
||||||
|
static const QString s_dummyContent("-");
|
||||||
|
return s_dummyContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Qt::ToolTipRole:
|
case Qt::ToolTipRole:
|
||||||
{
|
{
|
||||||
return content() + ":" + itemType().text() + ":" + renderStyleToString() + ":" + unitTypeToString();
|
return rawText() + ":" + unitTypeToString() + ":" + renderStyleToString() + ":" + unitTypeToString() + ":" + itemFlagsToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -571,30 +583,24 @@ void XQItem::setData(const QVariant& value, int role )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DAS PASSIERT NIE, AUSSER
|
|
||||||
// set the raw, unformatted data
|
// set the raw, unformatted data
|
||||||
case ContentRole:
|
case ContentRole:
|
||||||
{
|
{
|
||||||
// what will happen? value is a string ptr ?!
|
// string ptr setzen kann die basis.
|
||||||
//qDebug() << " --- setting content: " << value.toString();
|
|
||||||
// string ptr setzen kann die basis.
|
|
||||||
break;
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Qt::EditRole :
|
case Qt::EditRole :
|
||||||
{
|
{
|
||||||
// what will happen? value is a string ptr ?!
|
qDebug() << " --- setting EDITrole: " << value.toString();
|
||||||
qDebug() << " --- setting editrole: " << value.toString();
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Qt::DisplayRole :
|
case Qt::DisplayRole :
|
||||||
{
|
{
|
||||||
// what will happen? value is a string ptr ?!
|
// what will happen? value is a string ptr ?!
|
||||||
qDebug() << " --- setting DISPLAYrole: " << value.toString();
|
qDebug() << " --- setting DISPLAYrole: " << value.toString();
|
||||||
// ignore this
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// alles andere wie gehabt
|
// alles andere wie gehabt
|
||||||
@@ -721,5 +727,68 @@ QString XQItem::fetchUnitTypeToString( UnitType unitType)
|
|||||||
return s_UnitTypeMap[unitType];
|
return s_UnitTypeMap[unitType];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ---
|
||||||
|
/// ---
|
||||||
|
/// ---
|
||||||
|
|
||||||
|
XQStaticItem::XQStaticItem()
|
||||||
|
: XQItem{XQItemType::staticItemType()}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
XQStaticItem::XQStaticItem( XQItemType* itemType )
|
||||||
|
{
|
||||||
|
setItemType( itemType );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
XQStaticItem::XQStaticItem(XQItemType* itemType, const QString& content )
|
||||||
|
: XQItem{ itemType }
|
||||||
|
{
|
||||||
|
setText(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QVariant XQStaticItem::data(int role ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
switch(role)
|
||||||
|
{
|
||||||
|
// DisplayRole gibt den formatieren inhalt wieder. die formatierung übernimmt
|
||||||
|
// der item type
|
||||||
|
// auf den original inhalt im content node zurückgeben.
|
||||||
|
|
||||||
|
case Qt::DisplayRole :
|
||||||
|
{
|
||||||
|
if( itemType().renderStyle() == XQItem::FormattedStyle)//return "display:"+content();
|
||||||
|
return itemType().formatText( *this );
|
||||||
|
return QStandardItem::data(Qt::DisplayRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
case Qt::EditRole :
|
||||||
|
{
|
||||||
|
return QStandardItem::data(Qt::EditRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
case XQItem::ContentRole:
|
||||||
|
{
|
||||||
|
qDebug() << " --- FIRTZ!";
|
||||||
|
return QStandardItem::data( XQItem::ContentRole );
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return XQItem::data(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XQStaticItem::setData(const QVariant &value, int role )
|
||||||
|
{
|
||||||
|
// hier: behandlung wie gehabt
|
||||||
|
return XQItem::setData( value,role);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -126,10 +126,8 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
XQItem();
|
XQItem();
|
||||||
|
|
||||||
XQItem( XQItemType* itemType );
|
XQItem( XQItemType* itemType );
|
||||||
XQItem( XQItemType* itemType, const QString* content );
|
XQItem( XQItemType* itemType, const QString* content );
|
||||||
XQItem( XQItemType* itemType, const QString* content, const XQNodePtr& contentNode );
|
|
||||||
|
|
||||||
virtual ~XQItem() = default;
|
virtual ~XQItem() = default;
|
||||||
|
|
||||||
@@ -143,8 +141,6 @@ public:
|
|||||||
// shortcuts auf XQNodePtr
|
// shortcuts auf XQNodePtr
|
||||||
//! gibt den zu diesem item gehörigen datenknoten
|
//! gibt den zu diesem item gehörigen datenknoten
|
||||||
virtual XQNodePtr contentNode() const;
|
virtual XQNodePtr contentNode() const;
|
||||||
|
|
||||||
|
|
||||||
virtual void setContentNode(const XQNodePtr& contentNode );
|
virtual void setContentNode(const XQNodePtr& contentNode );
|
||||||
|
|
||||||
virtual XQNodePtr sheetNode() const;
|
virtual XQNodePtr sheetNode() const;
|
||||||
@@ -161,13 +157,14 @@ public:
|
|||||||
// __fix! das können die selber !?
|
// __fix! das können die selber !?
|
||||||
void addFlag( Qt::ItemFlag newFlag );
|
void addFlag( Qt::ItemFlag newFlag );
|
||||||
void clearFlag( Qt::ItemFlag newFlag );
|
void clearFlag( Qt::ItemFlag newFlag );
|
||||||
|
QString itemFlagsToString() const;
|
||||||
|
|
||||||
//das ist ein Sonderfall: Ein ist ein dereferenzierter Zeiger auf 'unser' Atrribut in
|
// das ist die EditRole: unformatierter Text
|
||||||
// XQNodePtr, also unserem contentNode(). Das wird hier direkt aufgelöst und nicht auf
|
QString rawText() const;
|
||||||
// data() umgeleitet.
|
|
||||||
|
|
||||||
const QString& content() const;
|
// changed: gibt jetzt den pointer zurück.
|
||||||
const QString& contentKey() const;
|
QString* content() const;
|
||||||
|
QString contentKey() const;
|
||||||
void setContent( const QString* content );
|
void setContent( const QString* content );
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -264,6 +261,27 @@ protected:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class XQStaticItem : public XQItem
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
XQStaticItem();
|
||||||
|
|
||||||
|
XQStaticItem( XQItemType* itemType );
|
||||||
|
XQStaticItem( XQItemType* itemType, const QString& content );
|
||||||
|
|
||||||
|
virtual ~XQStaticItem() = default;
|
||||||
|
|
||||||
|
QVariant data(int role = Qt::DisplayRole ) const override;
|
||||||
|
void setData(const QVariant &value, int role ) override;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(XQItem::RenderStyle);
|
Q_DECLARE_METATYPE(XQItem::RenderStyle);
|
||||||
Q_DECLARE_METATYPE(XQItem::EditorType);
|
Q_DECLARE_METATYPE(XQItem::EditorType);
|
||||||
Q_DECLARE_METATYPE(XQItem::UnitType);
|
Q_DECLARE_METATYPE(XQItem::UnitType);
|
||||||
|
@@ -81,22 +81,6 @@ XQItem& XQItemDelegate::xqItemFromIndex( const QModelIndex& index ) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QWidget* XQItemDelegate::prepareHeaderOption(const QStyleOptionViewItem& option, const QModelIndex& index, QStyleOptionHeader& headerOption) const
|
|
||||||
{
|
|
||||||
// use the header as "parent" for style init
|
|
||||||
QWidget* srcWidget = treeTable()->header();
|
|
||||||
headerOption.initFrom(srcWidget);
|
|
||||||
headerOption.text = index.data(Qt::DisplayRole).toString();
|
|
||||||
headerOption.rect = option.rect;
|
|
||||||
headerOption.styleObject = option.styleObject;
|
|
||||||
// __ch: reduce inner offset when painting
|
|
||||||
headerOption.textAlignment |= Qt::AlignVCenter;
|
|
||||||
|
|
||||||
return srcWidget;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void XQItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
void XQItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
if( !index.isValid() )
|
if( !index.isValid() )
|
||||||
@@ -131,11 +115,24 @@ void XQItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! einen section header im header-style zeichnen
|
||||||
|
|
||||||
void XQItemDelegate::drawHeaderStyle(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
void XQItemDelegate::drawHeaderStyle(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
QStyleOptionHeader headerOption;
|
QStyleOptionHeader headerOption;
|
||||||
QWidget* srcWidget = prepareHeaderOption(option, index, headerOption);
|
|
||||||
|
XQItem& item = xqItemFromIndex( index );
|
||||||
|
|
||||||
|
// use the header as "parent" for style init
|
||||||
|
QWidget* srcWidget = treeTable();//->header();
|
||||||
|
headerOption.initFrom(srcWidget);
|
||||||
|
headerOption.text = index.data(Qt::DisplayRole).toString();
|
||||||
|
headerOption.rect = option.rect.adjusted(0,0,0,3);
|
||||||
|
headerOption.styleObject = option.styleObject;
|
||||||
|
// __ch: reduce inner offset when painting
|
||||||
|
headerOption.textAlignment |= Qt::AlignVCenter;
|
||||||
|
headerOption.icon = item.icon();
|
||||||
|
|
||||||
if (srcWidget != nullptr)
|
if (srcWidget != nullptr)
|
||||||
{
|
{
|
||||||
// save painter
|
// save painter
|
||||||
|
@@ -46,8 +46,6 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
QWidget* prepareHeaderOption(const QStyleOptionViewItem& option, const QModelIndex& index, QStyleOptionHeader& headerOption) const;
|
|
||||||
|
|
||||||
void drawHeaderStyle(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
void drawHeaderStyle(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
void drawProgressBarStyle(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
void drawProgressBarStyle(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
void drawComboBoxStyle(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
void drawComboBoxStyle(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
|
@@ -77,13 +77,12 @@ bool XQItemFactory::isValid()
|
|||||||
XQItemType* XQItemFactory::makeItemType(const XQNodePtr& sheetEntry )
|
XQItemType* XQItemFactory::makeItemType(const XQNodePtr& sheetEntry )
|
||||||
{
|
{
|
||||||
QString typeKey = sheetEntry->attribute( c_ItemType );
|
QString typeKey = sheetEntry->attribute( c_ItemType );
|
||||||
|
|
||||||
XQItemType* itemType = findItemTypeTemplate(typeKey);
|
XQItemType* itemType = findItemTypeTemplate(typeKey);
|
||||||
|
|
||||||
// wir prüfen, ob im sheetEntry noch zusätzliche attribute vorhanden
|
// wir prüfen, ob im sheetEntry noch zusätzliche attribute vorhanden
|
||||||
// sind, die wir in dem itemType müssen
|
// sind, die wir in dem itemType müssen
|
||||||
|
|
||||||
qDebug() << " --- makeItemType: " << sheetEntry->to_string();
|
//qDebug() << " --- makeItemType: " << sheetEntry->to_string();
|
||||||
|
|
||||||
// über alle attribute
|
// über alle attribute
|
||||||
for (const auto& attrEntry : sheetEntry->attributes())
|
for (const auto& attrEntry : sheetEntry->attributes())
|
||||||
@@ -157,7 +156,7 @@ QVariant XQItemFactory::makeVariant( int dataRole, const QString& source ) const
|
|||||||
case XQItem::ItemTypeRole:
|
case XQItem::ItemTypeRole:
|
||||||
{
|
{
|
||||||
// itemType() -> XQItemType*
|
// itemType() -> XQItemType*
|
||||||
qDebug() << " --- makeVariant: make ItemType: " << source;
|
//qDebug() << " --- makeVariant: make ItemType: " << source;
|
||||||
XQItemType* itemType = findItemTypeTemplate( source );
|
XQItemType* itemType = findItemTypeTemplate( source );
|
||||||
value = QVariant::fromValue(itemType);
|
value = QVariant::fromValue(itemType);
|
||||||
break;
|
break;
|
||||||
@@ -179,7 +178,7 @@ QVariant XQItemFactory::makeVariant( int dataRole, const QString& source ) const
|
|||||||
|
|
||||||
case XQItem::UnitTypeRole:
|
case XQItem::UnitTypeRole:
|
||||||
{
|
{
|
||||||
qDebug() << " --- make unit type: " << source;
|
//qDebug() << " --- make unit type: " << source;
|
||||||
XQItem::UnitType unitType = XQItem::fetchUnitType( source );
|
XQItem::UnitType unitType = XQItem::fetchUnitType( source );
|
||||||
value = QVariant::fromValue(unitType);
|
value = QVariant::fromValue(unitType);
|
||||||
break;
|
break;
|
||||||
@@ -259,61 +258,7 @@ QVariant XQItemFactory::makeVariant( int dataRole, const QString& source ) const
|
|||||||
///
|
///
|
||||||
|
|
||||||
|
|
||||||
//! erzeugt ein XQItem aus einer typ-beschreibung ('sheetNode') und einem daten-knoten ('contentNode').
|
|
||||||
//! wenn der content node nicht gesetzt ist, wird stattdess das attribut 'Caption' aus der typ-beschreibung
|
|
||||||
//! verwendet: es handelt sich dann um ein header item, das erzeugt wurde.
|
|
||||||
|
|
||||||
XQItem* XQItemFactory::makeItem( const XQNodePtr& sheetNode, const XQNodePtr& contentNode )
|
|
||||||
{
|
|
||||||
// den itemtype des neuen items rausfinden
|
|
||||||
QString typeKey = sheetNode->attribute(c_ItemType);
|
|
||||||
|
|
||||||
XQItemType* itemType = makeItemType(sheetNode); // throws
|
|
||||||
// fallunterscheidung beim inhalt:
|
|
||||||
const QString* contentPtr{};
|
|
||||||
// das ist Unterschied zum normalen Item: Der Titel kommt aus der Modelbeschreibung
|
|
||||||
if(!contentNode)
|
|
||||||
contentPtr = sheetNode->attribute_ptr(c_Caption);
|
|
||||||
else
|
|
||||||
// der content wird indirect über den tag-name des sheetnode geholt
|
|
||||||
contentPtr = contentNode->attribute_ptr( sheetNode->tag_name() );
|
|
||||||
|
|
||||||
return new XQItem( itemType, contentPtr );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! erzeugt eine item-row.
|
|
||||||
|
|
||||||
XQItemList XQItemFactory::makeContentRow( const XQNodePtr& sheetNode, const XQNodePtr& contentNode )
|
|
||||||
{
|
|
||||||
|
|
||||||
XQItemList list;
|
|
||||||
|
|
||||||
// - Gehe über alle Einträge der Typbeschreibung:
|
|
||||||
//
|
|
||||||
// <Battery>
|
|
||||||
// <Voltage .../>
|
|
||||||
// -> <Capacity ../>
|
|
||||||
//
|
|
||||||
// - Nimm das dazugehörige Attribut aus dem contentNode
|
|
||||||
// value = contentNode->attributes["Capacity"];
|
|
||||||
//
|
|
||||||
|
|
||||||
for( const auto& sheetEntry : sheetNode->children() )
|
|
||||||
{
|
|
||||||
list.append( makeItem( sheetEntry, contentNode ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !list.empty() )
|
|
||||||
{
|
|
||||||
// wir merken uns den original content node auch, aber
|
|
||||||
// im ersten Item.
|
|
||||||
dynamic_cast<XQItem*>(list[0])->setContentNode(contentNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -337,7 +282,7 @@ XQItemList XQItemFactory::makeEmptyRow( const XQNodePtr& contentNode, const XQNo
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
XQItemList XQItemFactory::createGenericRow( const XQNodePtr& contentNode, const XQNodePtr& sheetNode )
|
XQItemList XQItemFactory::createGenericRow( const XQNodePtr& contentNode, const XQNodePtr& sheetNode )
|
||||||
{
|
{
|
||||||
|
|
||||||
// we have a new empty contentNode, so we add attributes first.
|
// we have a new empty contentNode, so we add attributes first.
|
||||||
for( const auto& sheetEntry : sheetNode->children() )
|
for( const auto& sheetEntry : sheetNode->children() )
|
||||||
@@ -356,3 +301,126 @@ XQItemList XQItemFactory::createGenericRow( const XQNodePtr& contentNode, const
|
|||||||
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//! erzeugt eine header-item row.
|
||||||
|
|
||||||
|
XQItemList XQItemFactory::makeHeaderRow( const XQNodePtr& sheetNode )
|
||||||
|
{
|
||||||
|
|
||||||
|
XQItemList list;
|
||||||
|
|
||||||
|
for( const auto& sheetEntry : sheetNode->children() )
|
||||||
|
{
|
||||||
|
list.append( makeHeaderItem( sheetEntry ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(!list.empty());
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! erzeugt eine item-row.
|
||||||
|
|
||||||
|
XQItemList XQItemFactory::makeContentRow( const XQNodePtr& sheetNode, const XQNodePtr& contentNode )
|
||||||
|
{
|
||||||
|
|
||||||
|
XQItemList list;
|
||||||
|
|
||||||
|
// - Gehe über alle Einträge der Typbeschreibung:
|
||||||
|
//
|
||||||
|
// <Battery>
|
||||||
|
// <Voltage .../>
|
||||||
|
// -> <Capacity ../>
|
||||||
|
//
|
||||||
|
// - Nimm das dazugehörige Attribut aus dem contentNode
|
||||||
|
// value = contentNode->attributes["Capacity"];
|
||||||
|
//
|
||||||
|
|
||||||
|
for( const auto& sheetEntry : sheetNode->children() )
|
||||||
|
{
|
||||||
|
list.append( makeContentItem( sheetEntry, contentNode ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(!list.empty());
|
||||||
|
|
||||||
|
// wir merken uns den original content node auch, aber
|
||||||
|
// im ersten Item.
|
||||||
|
dynamic_cast<XQItem*>(list[0])->setContentNode(contentNode);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
XQItem* XQItemFactory::makeHeaderItem( const XQNodePtr& sheetNode )
|
||||||
|
{
|
||||||
|
// den itemtype des neuen items rausfinden
|
||||||
|
XQItemType* itemType = makeItemType(sheetNode); // throws
|
||||||
|
|
||||||
|
// das ist Unterschied zum normalen Item: Der Titel kommt aus der Modelbeschreibung
|
||||||
|
// der content wird indirect über den tag-name des sheetnode geholt
|
||||||
|
|
||||||
|
XQItem* newItem = new XQItem( itemType, sheetNode->attribute_ptr(c_Caption) );
|
||||||
|
|
||||||
|
// __fixme!
|
||||||
|
if( newItem->isCheckable() )
|
||||||
|
newItem->setCheckState( Qt::Checked );
|
||||||
|
|
||||||
|
return newItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! fixme! unsinn!
|
||||||
|
//! erzeugt ein XQItem aus einer typ-beschreibung ('sheetNode') und einem daten-knoten ('contentNode').
|
||||||
|
//! wenn der content node nicht gesetzt ist, wird stattdess das attribut 'Caption' aus der typ-beschreibung
|
||||||
|
//! verwendet: es handelt sich dann um ein header item, das erzeugt wurde.
|
||||||
|
|
||||||
|
XQItem* XQItemFactory::makeContentItem( const XQNodePtr& sheetNode, const XQNodePtr& contentNode )
|
||||||
|
{
|
||||||
|
// den itemtype des neuen items rausfinden
|
||||||
|
XQItemType* itemType = makeItemType(sheetNode); // throws
|
||||||
|
|
||||||
|
// das ist Unterschied zum normalen Item: Der Titel kommt aus der Modelbeschreibung
|
||||||
|
// der content wird indirect über den tag-name des sheetnode geholt
|
||||||
|
|
||||||
|
// das ist Unterschied vom HeaderItem zum normalen Item: Der Titel kommt aus der Modelbeschreibung
|
||||||
|
if(!contentNode)
|
||||||
|
return makeStaticItem( sheetNode, sheetNode->attribute(c_Caption) );
|
||||||
|
|
||||||
|
// der content wird indirect über den tag-name des sheetnode geholt
|
||||||
|
const QString* contentPtr = contentNode->attribute_ptr( sheetNode->tag_name() );
|
||||||
|
return makeItem( sheetNode, contentPtr );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
XQItem* XQItemFactory::makeItem( const XQNodePtr& sheetNode, const QString* contentPtr )
|
||||||
|
{
|
||||||
|
// den itemtype des neuen items rausfinden
|
||||||
|
XQItemType* itemType = makeItemType(sheetNode); // throws
|
||||||
|
XQItem* newItem = new XQItem( itemType, contentPtr );
|
||||||
|
|
||||||
|
// __fixme!
|
||||||
|
if( newItem->isCheckable() )
|
||||||
|
{
|
||||||
|
newItem->setCheckState( Qt::Checked );
|
||||||
|
}
|
||||||
|
|
||||||
|
return newItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
XQStaticItem* XQItemFactory::makeStaticItem( const XQNodePtr& sheetNode, const QString& content )
|
||||||
|
{
|
||||||
|
XQItemType* itemType = makeItemType(sheetNode); // throws
|
||||||
|
XQStaticItem* newItem = new XQStaticItem( itemType, content );
|
||||||
|
|
||||||
|
// __fixme!
|
||||||
|
if( newItem->isCheckable() )
|
||||||
|
{
|
||||||
|
newItem->setCheckState( Qt::Checked );
|
||||||
|
}
|
||||||
|
|
||||||
|
return newItem;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -30,17 +30,19 @@ public:
|
|||||||
|
|
||||||
void initItemFactory(const QString& modelSheetFileName );
|
void initItemFactory(const QString& modelSheetFileName );
|
||||||
|
|
||||||
XQNodePtr findModelSheet( const QString& modelName ) const;
|
XQNodePtr findModelSheet( const QString& modelName ) const;
|
||||||
|
|
||||||
XQItem* makeItem( const XQNodePtr& sheetNode, const XQNodePtr& contentNode=nullptr);
|
|
||||||
|
|
||||||
|
|
||||||
XQItemList makeContentRow( const XQNodePtr& sheetNode, const XQNodePtr& contentNode );
|
|
||||||
//XQItemList makeEmptyRow( const XQNodePtr& contentNode, const XQNodePtr& sheetNode );
|
//XQItemList makeEmptyRow( const XQNodePtr& contentNode, const XQNodePtr& sheetNode );
|
||||||
|
|
||||||
|
XQItemList makeHeaderRow( const XQNodePtr& sheetNode );
|
||||||
|
XQItemList makeContentRow( const XQNodePtr& sheetNode, const XQNodePtr& contentNode );
|
||||||
|
|
||||||
// wozu ist das gut?
|
// wozu ist das gut?
|
||||||
//XQItemList createGenericRow( const XQNodePtr& contentNode, const XQNodePtr& sheetNode );
|
//XQItemList createGenericRow( const XQNodePtr& contentNode, const XQNodePtr& sheetNode );
|
||||||
|
|
||||||
|
XQStaticItem* makeStaticItem( const XQNodePtr& sheetNode, const QString& contentPtr );
|
||||||
|
|
||||||
|
|
||||||
void setItemDataFromString( XQItem& item, const QString& roleKey, const QString& source ) const;
|
void setItemDataFromString( XQItem& item, const QString& roleKey, const QString& source ) const;
|
||||||
|
|
||||||
XQItemType* makeItemType(const XQNodePtr& sheetEntry );
|
XQItemType* makeItemType(const XQNodePtr& sheetEntry );
|
||||||
@@ -51,6 +53,12 @@ protected:
|
|||||||
|
|
||||||
bool isValid();
|
bool isValid();
|
||||||
|
|
||||||
|
XQItem* makeHeaderItem( const XQNodePtr& sheetNode );
|
||||||
|
XQItem* makeContentItem( const XQNodePtr& sheetNode, const XQNodePtr& contentNode );
|
||||||
|
|
||||||
|
XQItem* makeItem( const XQNodePtr& sheetNode, const XQNodePtr& contentNode );
|
||||||
|
XQItem* makeItem( const XQNodePtr& sheetNode, const QString* contentPtr );
|
||||||
|
|
||||||
// shortcuts
|
// shortcuts
|
||||||
using ItemConfigFunc = std::function<void( XQItem* item, const QString& attrValue, XQNodePtr contentNode, XQNodePtr sheetNode )>;
|
using ItemConfigFunc = std::function<void( XQItem* item, const QString& attrValue, XQNodePtr contentNode, XQNodePtr sheetNode )>;
|
||||||
using ItemConfigMap = QMap<QString,ItemConfigFunc>;
|
using ItemConfigMap = QMap<QString,ItemConfigFunc>;
|
||||||
|
@@ -97,7 +97,7 @@ XQItemType* XQItemType::replaceAttribute( const QVariant& newValue, int role )
|
|||||||
msg = XQAppData::iconName( icn );
|
msg = XQAppData::iconName( icn );
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << " --- Before: " << makeItemTypeKey() << " role:" << XQItem::fetchItemDataRoleName(role) << " value:" << msg;
|
//qDebug() << " --- Before: " << makeItemTypeKey() << " role:" << XQItem::fetchItemDataRoleName(role) << " value:" << msg;
|
||||||
|
|
||||||
// hat sich überhaupt was geändert?
|
// hat sich überhaupt was geändert?
|
||||||
QVariant oldValue = data(role);
|
QVariant oldValue = data(role);
|
||||||
@@ -124,9 +124,7 @@ XQItemType* XQItemType::replaceAttribute( const QVariant& newValue, int role )
|
|||||||
// speichern
|
// speichern
|
||||||
s_ItemTypeMap.insert( newKey, myClone );
|
s_ItemTypeMap.insert( newKey, myClone );
|
||||||
|
|
||||||
|
//qDebug() << " --- After: " << myClone->makeItemTypeKey();
|
||||||
|
|
||||||
qDebug() << " --- After: " << myClone->makeItemTypeKey();
|
|
||||||
|
|
||||||
/// Obacht! Der alte, geänderte itemType bleibt erhalten
|
/// Obacht! Der alte, geänderte itemType bleibt erhalten
|
||||||
/// und verrottet ggf. ohne Daseinszweck
|
/// und verrottet ggf. ohne Daseinszweck
|
||||||
@@ -142,7 +140,7 @@ QVariant XQItemType::formatText( const XQItem& item ) const
|
|||||||
{
|
{
|
||||||
XQItem::UnitType uType = unitType();
|
XQItem::UnitType uType = unitType();
|
||||||
//qDebug() << " --- formatText: " << XQItem::fetchUnitTypeToString( uType);
|
//qDebug() << " --- formatText: " << XQItem::fetchUnitTypeToString( uType);
|
||||||
const QString& cont = item.content();
|
const QString& cont = item.rawText();
|
||||||
if( uType != XQItem::NoUnitType )
|
if( uType != XQItem::NoUnitType )
|
||||||
return formatToSI( cont, uType );
|
return formatToSI( cont, uType );
|
||||||
return cont;
|
return cont;
|
||||||
@@ -255,8 +253,8 @@ QString XQItemType::makeItemTypeKey()
|
|||||||
key = key.arg( renderStyleToString() );
|
key = key.arg( renderStyleToString() );
|
||||||
key = key.arg( editorTypeToString() );
|
key = key.arg( editorTypeToString() );
|
||||||
key = key.arg( unitTypeToString() );
|
key = key.arg( unitTypeToString() );
|
||||||
key = key.arg( contentFormat() );
|
key = key.arg( contentFormat() );
|
||||||
key = key.arg( data(XQItem::FlagsRole).toString() );
|
key = key.arg( itemFlagsToString() );
|
||||||
// icons haben leider keine namen, es sei denn, sie kommen aus einen theme
|
// icons haben leider keine namen, es sei denn, sie kommen aus einen theme
|
||||||
//key = key.arg( icon().name() );
|
//key = key.arg( icon().name() );
|
||||||
//key = key.arg( icon().cacheKey() );
|
//key = key.arg( icon().cacheKey() );
|
||||||
|
10
src/main.cpp
10
src/main.cpp
@@ -54,7 +54,15 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
QIcon icon;
|
/*
|
||||||
|
// Signal für einzelne QStandardItem-Änderungen
|
||||||
|
connect(model, &QStandardItemModel::itemChanged,
|
||||||
|
this, [](QStandardItem *changedItem){
|
||||||
|
QVariant state = changedItem->data(Qt::CheckStateRole);
|
||||||
|
qDebug() << "Neuer Check-State:" << state.toInt();
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
//app.setStyle("fusion");
|
//app.setStyle("fusion");
|
||||||
XQMainWindow window;
|
XQMainWindow window;
|
||||||
|
@@ -15,12 +15,11 @@
|
|||||||
#include <xqmodelsectionlist.h>
|
#include <xqmodelsectionlist.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! kontstruktor. übergibt den start-index und einen model-knoten mit der beschreibung
|
//! kontstruktor. übergibt den start-index und einen model-knoten mit der beschreibung
|
||||||
//! der datenknoten.
|
//! der datenknoten.
|
||||||
|
|
||||||
XQModelSection::XQModelSection(const QModelIndex& aModelIndex, XQNodePtr aSheetNode)
|
XQModelSection::XQModelSection(const QModelIndex& modelIndex, XQNodePtr sheetNode)
|
||||||
: modelIndex{ aModelIndex }, sheetRootNode{ aSheetNode }
|
: _modelIndex{ modelIndex }, _sectionRootNode{ sheetNode }
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -30,7 +29,7 @@ XQModelSection::XQModelSection(const QModelIndex& aModelIndex, XQNodePtr aSheetN
|
|||||||
|
|
||||||
bool XQModelSection::operator==(const XQModelSection& other) const
|
bool XQModelSection::operator==(const XQModelSection& other) const
|
||||||
{
|
{
|
||||||
return modelIndex == other.modelIndex && sheetRootNode == other.sheetRootNode;
|
return _modelIndex == other._modelIndex && _sectionRootNode == other._sectionRootNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -38,7 +37,44 @@ bool XQModelSection::operator==(const XQModelSection& other) const
|
|||||||
|
|
||||||
bool XQModelSection::isValid() const
|
bool XQModelSection::isValid() const
|
||||||
{
|
{
|
||||||
return modelIndex.isValid() && sheetRootNode;
|
return _modelIndex.isValid() && _sectionRootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QModelIndex& XQModelSection::modelIndex() const
|
||||||
|
{
|
||||||
|
return _modelIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
XQNodePtr XQModelSection::sectionRootNode() const
|
||||||
|
{
|
||||||
|
return _sectionRootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Gibt den sheet-node zurück, das ist die model-beschreibung,
|
||||||
|
//! siehe modelsheet.xml:
|
||||||
|
//! <section>
|
||||||
|
//! <header>
|
||||||
|
//! <data> <- dort
|
||||||
|
|
||||||
|
//! __fix! das versteht doch kein mensch!
|
||||||
|
|
||||||
|
XQNodePtr XQModelSection::sheetRootNode() const
|
||||||
|
{
|
||||||
|
return _sectionRootNode->find_child_by_tag_name( c_ModelSheet );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Gibt den content root node zurück, das ist der
|
||||||
|
//! zeiger auf die realen inhalte.
|
||||||
|
|
||||||
|
XQNodePtr XQModelSection::contentRootNode() const
|
||||||
|
{
|
||||||
|
return _contentRootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XQModelSection::setContentRootNode( const XQNodePtr contentRootNode )
|
||||||
|
{
|
||||||
|
_contentRootNode = contentRootNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -46,7 +82,15 @@ bool XQModelSection::isValid() const
|
|||||||
|
|
||||||
int XQModelSection::XQModelSection::row() const
|
int XQModelSection::XQModelSection::row() const
|
||||||
{
|
{
|
||||||
return modelIndex.row();
|
return _modelIndex.row();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! gibt den 'content type' zurück.
|
||||||
|
|
||||||
|
const QString& XQModelSection::contentType() const
|
||||||
|
{
|
||||||
|
return _sectionRootNode->attribute( c_ContentType );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -54,9 +98,10 @@ int XQModelSection::XQModelSection::row() const
|
|||||||
|
|
||||||
XQItem& XQModelSection::XQModelSection::headerItem() const
|
XQItem& XQModelSection::XQModelSection::headerItem() const
|
||||||
{
|
{
|
||||||
return XQItem::xqItemFromIndex( modelIndex );
|
return XQItem::xqItemFromIndex( _modelIndex );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! testet, ob die unter 'sectionKey' eine gültige section vorhanden ist.
|
//! testet, ob die unter 'sectionKey' eine gültige section vorhanden ist.
|
||||||
|
|
||||||
bool XQModelSectionList::hasValidSection(const QString& sectionKey) const
|
bool XQModelSectionList::hasValidSection(const QString& sectionKey) const
|
||||||
@@ -66,6 +111,7 @@ bool XQModelSectionList::hasValidSection(const QString& sectionKey) const
|
|||||||
return at(sectionKey).isValid();
|
return at(sectionKey).isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! gibt für einen model index die 'zuständige' section zurück.
|
//! gibt für einen model index die 'zuständige' section zurück.
|
||||||
|
|
||||||
const XQModelSection& XQModelSectionList::sectionFromIndex( const QModelIndex& index ) const
|
const XQModelSection& XQModelSectionList::sectionFromIndex( const QModelIndex& index ) const
|
||||||
@@ -83,11 +129,12 @@ const XQModelSection& XQModelSectionList::sectionFromRow(int itemRow ) const
|
|||||||
int i = size() - 1;
|
int i = size() - 1;
|
||||||
for (; i >= 0; --i)
|
for (; i >= 0; --i)
|
||||||
{
|
{
|
||||||
if ( at(i).modelIndex.row() < itemRow )
|
if ( at(i).modelIndex().row() < itemRow )
|
||||||
return at(i);
|
return at(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static XQModelSection s_DummySection;
|
static XQModelSection s_DummySection;
|
||||||
|
|
||||||
return s_DummySection;
|
return s_DummySection;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -123,7 +170,7 @@ int XQModelSectionList::lastRow(const XQModelSection& section ) const
|
|||||||
{
|
{
|
||||||
// last section? return last row of model
|
// last section? return last row of model
|
||||||
if (index == size() - 1)
|
if (index == size() - 1)
|
||||||
return section.modelIndex.model()->rowCount();// - 1;
|
return section.modelIndex().model()->rowCount();// - 1;
|
||||||
// return row above the row of the next section -> last row of given section
|
// return row above the row of the next section -> last row of given section
|
||||||
return at(index+1).row();
|
return at(index+1).row();
|
||||||
}
|
}
|
||||||
@@ -138,7 +185,7 @@ void XQModelSectionList::dump() const
|
|||||||
qDebug() << " --- sections dump(): " <<size() << " entries.";
|
qDebug() << " --- sections dump(): " <<size() << " entries.";
|
||||||
for( int i = 0; i<size(); ++i )
|
for( int i = 0; i<size(); ++i )
|
||||||
{
|
{
|
||||||
QModelIndex idx = at(i).modelIndex;
|
QModelIndex idx = at(i).modelIndex();
|
||||||
qDebug() << " --- sections:" << i << "row: " << idx.row() << " keyOf(i): " << keyOf(i) << " indexData: "<< idx.data().toString() << " itemData: " << XQItem::xqItemFromIndex(idx).data(Qt::DisplayRole).toString();
|
qDebug() << " --- sections:" << i << "row: " << idx.row() << " keyOf(i): " << keyOf(i) << " indexData: "<< idx.data().toString() << " itemData: " << XQItem::xqItemFromIndex(idx).data(Qt::DisplayRole).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,23 +24,38 @@
|
|||||||
* @brief Struct containing data for a header section
|
* @brief Struct containing data for a header section
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct XQModelSection
|
class XQModelSection
|
||||||
{
|
{
|
||||||
QPersistentModelIndex modelIndex;
|
|
||||||
|
|
||||||
XQNodePtr sheetRootNode{};
|
public:
|
||||||
XQNodePtr contentRootNode{};
|
|
||||||
|
|
||||||
XQModelSection() = default;
|
XQModelSection() = default;
|
||||||
XQModelSection(const QModelIndex& aModelIndex, XQNodePtr aSheetNode);
|
XQModelSection(const QModelIndex& modelIndex, XQNodePtr sheetNode );
|
||||||
|
|
||||||
bool operator==(const XQModelSection& other) const;
|
bool operator==(const XQModelSection& other) const;
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
int row() const;
|
int row() const;
|
||||||
|
|
||||||
|
const QModelIndex& modelIndex() const;
|
||||||
|
XQNodePtr sectionRootNode() const;
|
||||||
|
XQNodePtr sheetRootNode() const;
|
||||||
|
XQNodePtr contentRootNode() const;
|
||||||
|
void setContentRootNode( const XQNodePtr dataRootNode );
|
||||||
|
|
||||||
|
const QString& contentType() const;
|
||||||
XQItem& headerItem() const;
|
XQItem& headerItem() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
QPersistentModelIndex _modelIndex;
|
||||||
|
|
||||||
|
XQNodePtr _sectionRootNode{};
|
||||||
|
XQNodePtr _contentRootNode{};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(XQModelSection)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Maptor containing all header sections.
|
* @brief Maptor containing all header sections.
|
||||||
|
@@ -102,46 +102,50 @@ void XQViewModel::initModel(const QString& modelName)
|
|||||||
XQNodePtr modelSheet = _itemFactory.findModelSheet( modelName ); // throws
|
XQNodePtr modelSheet = _itemFactory.findModelSheet( modelName ); // throws
|
||||||
|
|
||||||
// #1: über alle sections
|
// #1: über alle sections
|
||||||
for( auto& section : modelSheet->children() )
|
for( auto& sectionNode : modelSheet->children() )
|
||||||
{
|
{
|
||||||
// #2: (optionalen?) header erzeugen
|
// #2: (optionalen?) header erzeugen
|
||||||
const XQNodePtr header = section->find_child_by_tag_name( "Header");
|
const XQNodePtr header = sectionNode->find_child_by_tag_name( c_Header );
|
||||||
if( header )
|
if( header )
|
||||||
{
|
{
|
||||||
XQItemList list = _itemFactory.makeContentRow( header, nullptr );
|
XQItemList list = _itemFactory.makeHeaderRow( header );
|
||||||
addSection(list, section );
|
addSection(list, sectionNode );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! hilfsfunktion: fügt die liste unserem model hinzu und erzeugt eine 'section'.
|
//! Hilfsfunktion: fügt die item-liste unserem model hinzu und erzeugt eine 'section'.
|
||||||
//! die section kann erst gültig sein, wenn die items im model gelandet sind,
|
//! die section kann erst gültig sein, wenn die items im model gelandet sind,
|
||||||
//! deswegen ist das hier zusammengefasst.
|
//! deswegen ist das hier zusammengefasst.
|
||||||
|
|
||||||
//! erzeugt dann eine section aus einer frisch erzeugten itemlist. der erste modelindex
|
//! Wrzeugt dann eine section aus einer frisch erzeugten itemlist. Der erste modelindex
|
||||||
//! der liste und der unterknoten 'Data' werden gespeichert.
|
//! der liste und der root knoten der model-beschreibung werden gespeichert.
|
||||||
|
|
||||||
void XQViewModel::addSection(const XQItemList& list, const XQNodePtr& sheetNode )
|
void XQViewModel::addSection(const XQItemList& list, const XQNodePtr& sectionNode )
|
||||||
{
|
{
|
||||||
// 1. die liste darf nicht leer sein
|
// 1. die liste darf nicht leer sein
|
||||||
Q_ASSERT(!list.isEmpty());
|
Q_ASSERT(!list.isEmpty());
|
||||||
// 2. sheetNode muss da sein
|
// 2. sectionNode muss da sein
|
||||||
Q_ASSERT(sheetNode);
|
Q_ASSERT(sectionNode);
|
||||||
// 3. 'ContenType' muss vorhanden sein
|
// 3. 'ContenType' muss vorhanden sein
|
||||||
if( !sheetNode->has_attribute( c_ContentType) )
|
if( !sectionNode->has_attribute( c_ContentType) )
|
||||||
throw XQException( "section list: Section node needs attribute '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
|
// 5. das erzeugt dann auch valide indices
|
||||||
appendRow(list);
|
appendRow(list);
|
||||||
|
|
||||||
XQModelSection section(list[0]->index(), dataNode );
|
// 6. die beschreibung der daten liegt im unterknoten 'Data'
|
||||||
_sections.addAtKey(sheetNode->attribute( c_ContentType), section);
|
|
||||||
|
|
||||||
|
// 6. jetzt können wir auch die sction erzeugen
|
||||||
|
XQModelSection section(list[0]->index(), sectionNode );
|
||||||
|
_sections.addAtKey(sectionNode->attribute( c_ContentType), section);
|
||||||
|
|
||||||
|
// ... und es der welt mitteilen.
|
||||||
|
emit sectionCreated( section );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -192,16 +196,7 @@ void XQViewModel::onActionTriggered(QAction* action)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
//! führt die 'redo' action des gegebenen commnds aus.
|
|
||||||
|
|
||||||
void XQViewModel::onCommandRedo( XQCommand& command )
|
|
||||||
{
|
|
||||||
QMap<XQCommand::CmdType,std::function<void(XQCommand&)>> s_RedoMap;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
switch (command.commandType())
|
switch (command.commandType())
|
||||||
{
|
{
|
||||||
case XQCommand::cmdToggleSection:
|
case XQCommand::cmdToggleSection:
|
||||||
@@ -225,6 +220,28 @@ void XQViewModel::onCommandRedo( XQCommand& command )
|
|||||||
default:
|
default:
|
||||||
qDebug() << " --- onCommandRedo: default: not handled: " << command.toString();
|
qDebug() << " --- onCommandRedo: default: not handled: " << command.toString();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! führt die 'redo' action des gegebenen commnds aus.
|
||||||
|
|
||||||
|
void XQViewModel::onCommandRedo( XQCommand& command )
|
||||||
|
{
|
||||||
|
static MemCallMap redoCalls
|
||||||
|
{
|
||||||
|
{ XQCommand::cmdToggleSection, &XQViewModel::cmdToggleSection },
|
||||||
|
{ XQCommand::cmdCut, &XQViewModel::cmdCut },
|
||||||
|
{ XQCommand::cmdPaste, &XQViewModel::cmdPaste },
|
||||||
|
{ XQCommand::cmdNew, &XQViewModel::cmdNew },
|
||||||
|
{ XQCommand::cmdDelete, &XQViewModel::cmdDelete }
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MemCall memCall = redoCalls[command.commandType()];
|
||||||
|
if( memCall )
|
||||||
|
(this->*memCall)( command );
|
||||||
|
else
|
||||||
|
qDebug() << " --- onCommandRedo: default: not handled: " << command.toString();
|
||||||
}
|
}
|
||||||
catch( XQException& exception )
|
catch( XQException& exception )
|
||||||
{
|
{
|
||||||
@@ -233,12 +250,7 @@ void XQViewModel::onCommandRedo( XQCommand& command )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
//! führt die 'undo' action des gegebenen commnds aus.
|
|
||||||
|
|
||||||
void XQViewModel::onCommandUndo( XQCommand& command )
|
|
||||||
{
|
|
||||||
qDebug() << " --- onCommandUndo: count: " << XQNode::s_Count;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch (command.commandType())
|
switch (command.commandType())
|
||||||
@@ -273,13 +285,35 @@ void XQViewModel::onCommandUndo( XQCommand& command )
|
|||||||
default:
|
default:
|
||||||
qDebug() << " --- onCommandUndo: default: not handled: " << command.toString();
|
qDebug() << " --- onCommandUndo: default: not handled: " << command.toString();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
//! führt die 'undo' action des gegebenen commnds aus.
|
||||||
|
|
||||||
|
void XQViewModel::onCommandUndo( XQCommand& command )
|
||||||
|
{
|
||||||
|
qDebug() << " --- onCommandUndo: count: " << XQNode::s_Count;
|
||||||
|
|
||||||
|
static MemCallMap undoCalls
|
||||||
|
{
|
||||||
|
{ XQCommand::cmdToggleSection, &XQViewModel::cmdToggleSection },
|
||||||
|
{ XQCommand::cmdCut, &XQViewModel::cmdCutUndo },
|
||||||
|
{ XQCommand::cmdPaste, &XQViewModel::cmdPasteUndo },
|
||||||
|
{ XQCommand::cmdNew, &XQViewModel::cmdNewUndo },
|
||||||
|
{ XQCommand::cmdDelete, &XQViewModel::cmdDeleteUndo },
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MemCall memCall = undoCalls[command.commandType()];
|
||||||
|
if( memCall )
|
||||||
|
(this->*memCall)( command );
|
||||||
|
else
|
||||||
|
qDebug() << " --- onCommandUndo: default: not handled: " << command.toString();
|
||||||
}
|
}
|
||||||
catch( XQException& exception )
|
catch( XQException& exception )
|
||||||
{
|
{
|
||||||
qDebug() << exception.what();
|
qDebug() << exception.what();
|
||||||
QMessageBox::critical( nullptr, "Failure", QString("Failure: %1").arg(exception.what()) );
|
QMessageBox::critical( nullptr, "Failure", QString("Failure: %1").arg(exception.what()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// undo-/redo-able stuff
|
// undo-/redo-able stuff
|
||||||
@@ -319,7 +353,7 @@ void XQViewModel::cmdCutUndo( XQCommand& command )
|
|||||||
const XQNodePtr& savedNode = entry.contentNode;
|
const XQNodePtr& savedNode = entry.contentNode;
|
||||||
// __fix! should not be _contentRoot!
|
// __fix! should not be _contentRoot!
|
||||||
savedNode->add_me_at( entry.nodePos, _contentRoot );
|
savedNode->add_me_at( entry.nodePos, _contentRoot );
|
||||||
XQItemList list = _itemFactory.makeContentRow( section.sheetRootNode, savedNode );
|
XQItemList list = _itemFactory.makeContentRow( section.sheetRootNode(), savedNode );
|
||||||
|
|
||||||
XQItem& firstItem = *((XQItem*)list[0]);
|
XQItem& firstItem = *((XQItem*)list[0]);
|
||||||
qDebug() << " --- Cut Undo: " << firstItem.text() << " " << firstItem.row() << " id#" << entry.contentNode->_id << " count: " << entry.contentNode.use_count();
|
qDebug() << " --- Cut Undo: " << firstItem.text() << " " << firstItem.row() << " id#" << entry.contentNode->_id << " count: " << entry.contentNode.use_count();
|
||||||
@@ -351,10 +385,10 @@ void XQViewModel::cmdPaste( XQCommand& command )
|
|||||||
for (auto& entry : _clipBoard )
|
for (auto& entry : _clipBoard )
|
||||||
{
|
{
|
||||||
// noch ein clone vom clone erzeugen ...
|
// noch ein clone vom clone erzeugen ...
|
||||||
XQNodePtr newNode = entry.contentNode->clone(section.contentRootNode );
|
XQNodePtr newNode = entry.contentNode->clone(section.contentRootNode() );
|
||||||
newNode->clone(section.contentRootNode )->add_me_at( nodePos );
|
newNode->clone(section.contentRootNode() )->add_me_at( nodePos );
|
||||||
// ... und damit eine frische item-row erzeugen
|
// ... und damit eine frische item-row erzeugen
|
||||||
XQItemList list = _itemFactory.makeContentRow( section.sheetRootNode, newNode );
|
XQItemList list = _itemFactory.makeContentRow( section.sheetRootNode(), newNode );
|
||||||
insertRow( insRow, list );
|
insertRow( insRow, list );
|
||||||
// die neue item-row selektieren
|
// die neue item-row selektieren
|
||||||
const QModelIndex& selIdx = list[0]->index();
|
const QModelIndex& selIdx = list[0]->index();
|
||||||
@@ -461,8 +495,9 @@ void XQViewModel::cmdNewUndo( XQCommand& command )
|
|||||||
|
|
||||||
//! schaltet eine section sichtbar oder unsichtbar.
|
//! schaltet eine section sichtbar oder unsichtbar.
|
||||||
|
|
||||||
void XQViewModel::cmdToggleSection( const QModelIndex& index )
|
void XQViewModel::cmdToggleSection( XQCommand& command )
|
||||||
{
|
{
|
||||||
|
const QModelIndex& index = command.originIndex();
|
||||||
Q_ASSERT(index.isValid());
|
Q_ASSERT(index.isValid());
|
||||||
|
|
||||||
int fstRow = _sections.firstRow( index );
|
int fstRow = _sections.firstRow( index );
|
||||||
@@ -472,6 +507,7 @@ void XQViewModel::cmdToggleSection( const QModelIndex& index )
|
|||||||
for (int row = fstRow; row < lstRow; ++row )
|
for (int row = fstRow; row < lstRow; ++row )
|
||||||
_treeTable->setRowHidden( row, _treeTable->rootIndex(), !hidden );
|
_treeTable->setRowHidden( row, _treeTable->rootIndex(), !hidden );
|
||||||
|
|
||||||
|
emit sectionToggled( _sections.sectionFromIndex(index) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
599
src/model/xqviewmodel.cpp~RF540b760.TMP
Normal file
599
src/model/xqviewmodel.cpp~RF540b760.TMP
Normal file
@@ -0,0 +1,599 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
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 <QMessageBox>
|
||||||
|
#include <QUndoStack>
|
||||||
|
|
||||||
|
#include <xqexception.h>
|
||||||
|
#include <xqviewmodel.h>
|
||||||
|
#include <xqselectionmodel.h>
|
||||||
|
#include <xqtreetable.h>
|
||||||
|
#include <xqcommand.h>
|
||||||
|
#include <xqitemdelegate.h>
|
||||||
|
#include <xqitemfactory.h>
|
||||||
|
#include <znode_factory.h>
|
||||||
|
|
||||||
|
|
||||||
|
// create global dummy item as
|
||||||
|
// fallback return value (klappt nicht)
|
||||||
|
//Q_GLOBAL_STATIC(XQItem,s_dummyItem)
|
||||||
|
|
||||||
|
|
||||||
|
//! hilfsfunkion, zeigt den string-content() für alle elemente der liste
|
||||||
|
|
||||||
|
void showItemList( const XQItemList& list)
|
||||||
|
{
|
||||||
|
for(const auto& entry : list )
|
||||||
|
qDebug() << " --- itemList: " << ((XQItem*)entry)->content();
|
||||||
|
qDebug();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Konstruktur mit parent.
|
||||||
|
|
||||||
|
XQViewModel::XQViewModel( QObject* parent )
|
||||||
|
: QStandardItemModel{ parent }, _itemFactory{ XQItemFactory::instance() }
|
||||||
|
{
|
||||||
|
invisibleRootItem()->setData( "[rootItem]", Qt::DisplayRole );
|
||||||
|
setItemPrototype( new XQItem );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! gibt einen static-cast<QXItem*> auf 'invisibleRootItem()' zurück
|
||||||
|
|
||||||
|
const XQItem& XQViewModel::xqRootItem()
|
||||||
|
{
|
||||||
|
// das ist ein hack, denn 'invisibleRootItem()' ist und bleibt ein
|
||||||
|
// QStandardItem. Trick: keine eigenen members in XQItem, alles
|
||||||
|
// dynamisch über den ItemData Mechanismus wie in QStandardItem
|
||||||
|
|
||||||
|
return *static_cast<XQItem*>(invisibleRootItem());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! hifsfunktion, die das item zu einen index zurückgibt
|
||||||
|
|
||||||
|
XQItem& XQViewModel::xqItemFromIndex(const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
if( index.isValid() )
|
||||||
|
{
|
||||||
|
QStandardItem* xqItem = QStandardItemModel::itemFromIndex(index);
|
||||||
|
if( xqItem )
|
||||||
|
return *static_cast<XQItem*>(xqItem);
|
||||||
|
}
|
||||||
|
return XQItem::fallBackDummyItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! hilfsfunktiom, die das erste xqitem einer zeile zurückgibt.
|
||||||
|
|
||||||
|
XQItem& XQViewModel::xqFirstItem(int row) const
|
||||||
|
{
|
||||||
|
return *static_cast<XQItem*>( QStandardItemModel::item(row) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! initialisiert dieses model über den namen. Es wird hier
|
||||||
|
//! nur die strukur erzeugt, keine inhalte.
|
||||||
|
|
||||||
|
void XQViewModel::initModel(const QString& modelName)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
model
|
||||||
|
section
|
||||||
|
header
|
||||||
|
data
|
||||||
|
section
|
||||||
|
...
|
||||||
|
|
||||||
|
*/
|
||||||
|
// model rootnode finden -> <DocumentTreeModel>
|
||||||
|
XQNodePtr modelSheet = _itemFactory.findModelSheet( modelName ); // throws
|
||||||
|
|
||||||
|
// #1: über alle sections
|
||||||
|
for( auto& section : modelSheet->children() )
|
||||||
|
{
|
||||||
|
// #2: (optionalen?) header erzeugen
|
||||||
|
const XQNodePtr header = section->find_child_by_tag_name( "Header");
|
||||||
|
if( header )
|
||||||
|
{
|
||||||
|
XQItemList list = _itemFactory.makeContentRow( header, nullptr );
|
||||||
|
addSection(list, section );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! 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);
|
||||||
|
|
||||||
|
emit sectionCreated( §ion );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! SLOT, der aufgerufen wird, wenn eine edit-action getriggert wurde.
|
||||||
|
|
||||||
|
void XQViewModel::onActionTriggered(QAction* action)
|
||||||
|
{
|
||||||
|
qDebug() << " --- onActionTriggered: count:" << XQNode::s_Count;
|
||||||
|
|
||||||
|
// all selected indices
|
||||||
|
QModelIndexList selectionList = treeTable()->selectionModel()->selectedRows();
|
||||||
|
// extract command type
|
||||||
|
XQCommand::CmdType cmdType = action->data().value<XQCommand::CmdType>();
|
||||||
|
|
||||||
|
switch( cmdType )
|
||||||
|
{
|
||||||
|
// just handle undo ...
|
||||||
|
case XQCommand::cmdUndo :
|
||||||
|
return _undoStack->undo();
|
||||||
|
|
||||||
|
// ... or do/redo
|
||||||
|
case XQCommand::cmdRedo :
|
||||||
|
return _undoStack->redo();
|
||||||
|
|
||||||
|
// for copy & cut, we create a clone of the dataNodes in the clipboard
|
||||||
|
case XQCommand::cmdCopy :
|
||||||
|
case XQCommand::cmdCut :
|
||||||
|
// don't 'copy' empty selections
|
||||||
|
if( !selectionList.isEmpty() )
|
||||||
|
_clipBoard.saveNodes( selectionList );
|
||||||
|
// for copy, we are done, since copy cannot be undone
|
||||||
|
if( cmdType == XQCommand::cmdCopy )
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we create a command
|
||||||
|
XQCommand* command = new XQCommand( cmdType, this );
|
||||||
|
// store the row positions of the selected indices
|
||||||
|
command->saveNodes( selectionList );
|
||||||
|
command->setOriginIndex( treeTable()->currentIndex() );
|
||||||
|
|
||||||
|
// execute command
|
||||||
|
_undoStack->push( command );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
switch (command.commandType())
|
||||||
|
{
|
||||||
|
case XQCommand::cmdToggleSection:
|
||||||
|
return cmdToggleSection( command.originIndex() );
|
||||||
|
|
||||||
|
case XQCommand::cmdCut:
|
||||||
|
return cmdCut( command );
|
||||||
|
|
||||||
|
case XQCommand::cmdPaste:
|
||||||
|
return cmdPaste( command );
|
||||||
|
|
||||||
|
case XQCommand::cmdNew:
|
||||||
|
return cmdNew( command );
|
||||||
|
|
||||||
|
case XQCommand::cmdDelete:
|
||||||
|
return cmdDelete( command );
|
||||||
|
|
||||||
|
case XQCommand::cmdMove:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
qDebug() << " --- onCommandRedo: default: not handled: " << command.toString();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! führt die 'redo' action des gegebenen commnds aus.
|
||||||
|
|
||||||
|
void XQViewModel::onCommandRedo( XQCommand& command )
|
||||||
|
{
|
||||||
|
static MemCallMap redoCalls
|
||||||
|
{
|
||||||
|
{ XQCommand::cmdToggleSection, &XQViewModel::cmdToggleSection },
|
||||||
|
{ XQCommand::cmdCut, &XQViewModel::cmdCut },
|
||||||
|
{ XQCommand::cmdPaste, &XQViewModel::cmdPaste },
|
||||||
|
{ XQCommand::cmdNew, &XQViewModel::cmdNew },
|
||||||
|
{ XQCommand::cmdDelete, &XQViewModel::cmdDelete }
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MemCall memCall = redoCalls[command.commandType()];
|
||||||
|
if( memCall )
|
||||||
|
(this->*memCall)( command );
|
||||||
|
else
|
||||||
|
qDebug() << " --- onCommandRedo: default: not handled: " << command.toString();
|
||||||
|
}
|
||||||
|
catch( XQException& exception )
|
||||||
|
{
|
||||||
|
qDebug() << exception.what();
|
||||||
|
QMessageBox::critical( nullptr, "Failure", QString("Failure: %1").arg(exception.what()) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (command.commandType())
|
||||||
|
{
|
||||||
|
case XQCommand::cmdToggleSection:
|
||||||
|
return cmdToggleSection( command.originIndex() );
|
||||||
|
break;
|
||||||
|
|
||||||
|
// undo Cut -> perform undoCut
|
||||||
|
case XQCommand::cmdCut:
|
||||||
|
return cmdCutUndo( command );
|
||||||
|
|
||||||
|
// undo Paste -> perform Cut
|
||||||
|
case XQCommand::cmdPaste:
|
||||||
|
return cmdPasteUndo( command );
|
||||||
|
|
||||||
|
// undo Move -> perform move back
|
||||||
|
case XQCommand::cmdMove:
|
||||||
|
// not yet implemented
|
||||||
|
break;
|
||||||
|
|
||||||
|
// undo New -> perform Delete
|
||||||
|
case XQCommand::cmdNew:
|
||||||
|
cmdNewUndo( command );
|
||||||
|
break;
|
||||||
|
|
||||||
|
// undo Delete -> perform New
|
||||||
|
case XQCommand::cmdDelete:
|
||||||
|
qDebug() << " --- onCommandUndo: delete: " << command.toString();
|
||||||
|
return cmdDeleteUndo( command );
|
||||||
|
|
||||||
|
default:
|
||||||
|
qDebug() << " --- onCommandUndo: default: not handled: " << command.toString();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//! führt die 'undo' action des gegebenen commnds aus.
|
||||||
|
|
||||||
|
void XQViewModel::onCommandUndo( XQCommand& command )
|
||||||
|
{
|
||||||
|
qDebug() << " --- onCommandUndo: count: " << XQNode::s_Count;
|
||||||
|
|
||||||
|
static MemCallMap undoCalls
|
||||||
|
{
|
||||||
|
{ XQCommand::cmdToggleSection, &XQViewModel::cmdToggleSection },
|
||||||
|
{ XQCommand::cmdCut, &XQViewModel::cmdCutUndo },
|
||||||
|
{ XQCommand::cmdPaste, &XQViewModel::cmdPasteUndo },
|
||||||
|
{ XQCommand::cmdNew, &XQViewModel::cmdNewUndo },
|
||||||
|
{ XQCommand::cmdDelete, &XQViewModel::cmdDeleteUndo },
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MemCall memCall = undoCalls[command.commandType()];
|
||||||
|
if( memCall )
|
||||||
|
(this->*memCall)( command );
|
||||||
|
else
|
||||||
|
qDebug() << " --- onCommandUndo: default: not handled: " << command.toString();
|
||||||
|
}
|
||||||
|
catch( XQException& exception )
|
||||||
|
{
|
||||||
|
qDebug() << exception.what();
|
||||||
|
QMessageBox::critical( nullptr, "Failure", QString("Failure: %1").arg(exception.what()) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// undo-/redo-able stuff
|
||||||
|
|
||||||
|
//! markierte knoten entfernen, 'command' enthält die liste
|
||||||
|
|
||||||
|
void XQViewModel::cmdCut( XQCommand& command )
|
||||||
|
{
|
||||||
|
// wir gehen rückwärts über alle gemerkten knoten ...
|
||||||
|
for (auto it = command.rbegin(); it != command.rend(); ++it)
|
||||||
|
{
|
||||||
|
// ... holen das erste item, das auch den content node enthält
|
||||||
|
//const XQNodeBackup& entry = *it;
|
||||||
|
// 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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! entfernte knoten wieder einfügen , 'command' enthält die liste
|
||||||
|
|
||||||
|
void XQViewModel::cmdCutUndo( XQCommand& command )
|
||||||
|
{
|
||||||
|
// die anfangsposition
|
||||||
|
int itmPos = command.first().itemPos;
|
||||||
|
// die 'zuständige' section rausfinden
|
||||||
|
const XQModelSection& section = _sections.sectionFromRow( itmPos );
|
||||||
|
// über alle einträge ...
|
||||||
|
for (auto& entry : command )
|
||||||
|
{
|
||||||
|
const XQNodePtr& savedNode = entry.contentNode;
|
||||||
|
// __fix! should not be _contentRoot!
|
||||||
|
savedNode->add_me_at( entry.nodePos, _contentRoot );
|
||||||
|
XQItemList list = _itemFactory.makeContentRow( section.sheetRootNode, savedNode );
|
||||||
|
|
||||||
|
XQItem& firstItem = *((XQItem*)list[0]);
|
||||||
|
qDebug() << " --- Cut Undo: " << firstItem.text() << " " << firstItem.row() << " id#" << entry.contentNode->_id << " count: " << entry.contentNode.use_count();
|
||||||
|
|
||||||
|
insertRow( entry.itemPos, list );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! clipboard inhalte einfügen
|
||||||
|
|
||||||
|
void XQViewModel::cmdPaste( XQCommand& command )
|
||||||
|
{
|
||||||
|
// selection holen ...
|
||||||
|
QItemSelectionModel* selectionModel = treeTable()->selectionModel();
|
||||||
|
// ... und löschen
|
||||||
|
selectionModel->clearSelection();
|
||||||
|
|
||||||
|
// aktuelles item finden
|
||||||
|
const XQItem& item = xqItemFromIndex( command.originIndex() );
|
||||||
|
|
||||||
|
// die neue item position ist unter dem akutellen item
|
||||||
|
int insRow = item.row()+1;
|
||||||
|
int nodePos = item.contentNode()->own_pos()+1;
|
||||||
|
|
||||||
|
// die zugehörige section finden
|
||||||
|
const XQModelSection& section = _sections.sectionFromRow( insRow-1 );
|
||||||
|
// wir pasten das clipboard
|
||||||
|
for (auto& entry : _clipBoard )
|
||||||
|
{
|
||||||
|
// noch ein clone vom clone erzeugen ...
|
||||||
|
XQNodePtr newNode = entry.contentNode->clone(section.contentRootNode );
|
||||||
|
newNode->clone(section.contentRootNode )->add_me_at( nodePos );
|
||||||
|
// ... und damit eine frische item-row erzeugen
|
||||||
|
XQItemList list = _itemFactory.makeContentRow( section.sheetRootNode, newNode );
|
||||||
|
insertRow( insRow, list );
|
||||||
|
// die neue item-row selektieren
|
||||||
|
const QModelIndex& selIdx = list[0]->index();
|
||||||
|
_treeTable->selectionModel()->select(selIdx, QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||||
|
// zur nächsten zeile
|
||||||
|
insRow++;
|
||||||
|
nodePos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsere änderungen merken fürs 'undo'
|
||||||
|
command.saveNodes( selectionModel->selectedRows() );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! einfügen aus dem clipboard wieder rückgängig machen
|
||||||
|
|
||||||
|
void XQViewModel::cmdPasteUndo( XQCommand& command )
|
||||||
|
{
|
||||||
|
command.dumpList("Paste UNDO");
|
||||||
|
// wir gehen rückwärts über alle markieren knoten ...
|
||||||
|
for (auto it = command.rbegin(); it != command.rend(); ++it)
|
||||||
|
{
|
||||||
|
// ... 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();
|
||||||
|
// jetzt löschen
|
||||||
|
entry.contentNode->unlink_self();
|
||||||
|
removeRow(entry.itemPos );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// don't clone into clipboard, remove items
|
||||||
|
|
||||||
|
//! entfernen der selection ohne copy in clipboard.
|
||||||
|
|
||||||
|
void XQViewModel::cmdDelete( XQCommand& command )
|
||||||
|
{
|
||||||
|
// wir gehen rückwärts über alle markieren knoten ...
|
||||||
|
for (auto it = command.rbegin(); it != command.rend(); ++it)
|
||||||
|
{
|
||||||
|
// ... 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();
|
||||||
|
// jetzt löschen
|
||||||
|
entry.contentNode->unlink_self();
|
||||||
|
removeRow(entry.itemPos );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! macht 'delete' wirder rückgängig.
|
||||||
|
|
||||||
|
void XQViewModel::cmdDeleteUndo( XQCommand& command )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! legt eine neue, leere zeile an.
|
||||||
|
|
||||||
|
void XQViewModel::cmdNew( XQCommand& command )
|
||||||
|
{
|
||||||
|
|
||||||
|
// __fix
|
||||||
|
/*
|
||||||
|
const QModelIndex& origin = command.originIndex();
|
||||||
|
if( !origin.isValid() )
|
||||||
|
throw XQException("cmdNewRow failed: index not valid ");
|
||||||
|
|
||||||
|
XQItem* target = xqItemFromIndex( origin );
|
||||||
|
// current data node
|
||||||
|
XQNodePtr node = target->contentNode();
|
||||||
|
|
||||||
|
// we create a new data node
|
||||||
|
//XQNodePtr newNode = new XQNodePtr( node->tag_name(), node->parent() );
|
||||||
|
XQNodePtr newNode = XQNode::make_node( node->tag_name(), node->tag_value(), node->parent() );
|
||||||
|
// store node in node->parent()
|
||||||
|
//node->add_before_me( newNode );
|
||||||
|
// store node also in 'command' to enable undo
|
||||||
|
const XQModelSection& section = _sections.sectionFromIndex( origin );
|
||||||
|
|
||||||
|
// create new item row
|
||||||
|
XQItemList list = _itemFactory.createGenericRow( newNode, section.sheetRootNode );
|
||||||
|
|
||||||
|
// add it to the treeview ...
|
||||||
|
insertRow( origin.row(), list );
|
||||||
|
|
||||||
|
// ... and make it ...
|
||||||
|
treeTable()->setCurrentIndex( list[0]->index() );
|
||||||
|
// ... editable
|
||||||
|
treeTable()->edit( list[0]->index() );
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
//! entfernt die neu angelegte zeile.
|
||||||
|
|
||||||
|
void XQViewModel::cmdNewUndo( XQCommand& command )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! schaltet eine section sichtbar oder unsichtbar.
|
||||||
|
|
||||||
|
void XQViewModel::cmdToggleSection( XQCommand& command )
|
||||||
|
{
|
||||||
|
const QModelIndex& index = command.originIndex();
|
||||||
|
Q_ASSERT(index.isValid());
|
||||||
|
|
||||||
|
int fstRow = _sections.firstRow( index );
|
||||||
|
int lstRow = _sections.lastRow( index );
|
||||||
|
|
||||||
|
bool hidden =_treeTable->isRowHidden( fstRow, _treeTable->rootIndex() );
|
||||||
|
for (int row = fstRow; row < lstRow; ++row )
|
||||||
|
_treeTable->setRowHidden( row, _treeTable->rootIndex(), !hidden );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! git die treetable zurück
|
||||||
|
|
||||||
|
XQTreeTable* XQViewModel::treeTable()
|
||||||
|
{
|
||||||
|
return _treeTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! setzt die treetable als member.
|
||||||
|
|
||||||
|
void XQViewModel::setTreeTable(XQTreeTable* mainView )
|
||||||
|
{
|
||||||
|
// store view for direct access: the maintree
|
||||||
|
_treeTable = mainView;
|
||||||
|
// connect myself as model to the mainview
|
||||||
|
_treeTable->setModel(this);
|
||||||
|
XQItemDelegate* delegate = new XQItemDelegate( *this );
|
||||||
|
_treeTable->setItemDelegate( delegate );
|
||||||
|
|
||||||
|
_contextMenu = new XQContextMenu( mainView );
|
||||||
|
|
||||||
|
connect( _treeTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onShowContextMenu(QPoint)));
|
||||||
|
//connect( _treeTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(onDoubleClicked(QModelIndex)) );
|
||||||
|
connect(_contextMenu, SIGNAL(triggered(QAction*)), this, SLOT(onActionTriggered(QAction*)));
|
||||||
|
|
||||||
|
// __fixme, die view soll über das modelsheet konfiguriert werden!
|
||||||
|
setupViewProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! setzt die eigenschaften der TreeTable.
|
||||||
|
|
||||||
|
void XQViewModel::setupViewProperties()
|
||||||
|
{
|
||||||
|
_treeTable->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
_treeTable->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
|
||||||
|
_treeTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
_treeTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
|
//_treeTable->setSelectionMode(QAbstractItemView::ContiguousSelection);
|
||||||
|
_treeTable->setSelectionModel( new XQSelectionModel(this) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! gibt den undo-stack zurück.
|
||||||
|
|
||||||
|
QUndoStack* XQViewModel::undoStack()
|
||||||
|
{
|
||||||
|
return _undoStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! setzt den undo-stack.
|
||||||
|
|
||||||
|
void XQViewModel::setUndoStack( QUndoStack* undoStack )
|
||||||
|
{
|
||||||
|
_undoStack = undoStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! SLOT, der die erstellung & anzeige es context-menues triggert.
|
||||||
|
|
||||||
|
void XQViewModel::onShowContextMenu(const QPoint& point)
|
||||||
|
{
|
||||||
|
initContextMenu();
|
||||||
|
_contextMenu->popup(_treeTable->mapToGlobal(point));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! gibt die namen der neuen data-roles zurück.
|
||||||
|
//! __fix: die alten roles fehlen hier!
|
||||||
|
|
||||||
|
QHash<int, QByteArray> XQViewModel::roleNames() const
|
||||||
|
{
|
||||||
|
|
||||||
|
QHash<int, QByteArray> roles;
|
||||||
|
roles[XQItem::ContentRole] = "content";
|
||||||
|
roles[XQItem::ItemTypeRole] = "itemType";
|
||||||
|
roles[XQItem::RenderStyleRole] = "renderStyle";
|
||||||
|
roles[XQItem::EditorTypeRole] = "editorType";
|
||||||
|
roles[XQItem::UnitTypeRole] = "unitType";
|
||||||
|
roles[XQItem::FixedChoicesRole] = "fixedChoices";
|
||||||
|
roles[XQItem::ContentNodeRole] = "contentNode";
|
||||||
|
roles[XQItem::SheetNodeRole] = "sheetNode";
|
||||||
|
roles[XQItem::TypeKeyRole] = "typeKey";
|
||||||
|
|
||||||
|
return roles;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@@ -58,7 +58,7 @@ public:
|
|||||||
|
|
||||||
// undo-/redo-able stuff
|
// undo-/redo-able stuff
|
||||||
|
|
||||||
virtual void cmdToggleSection( const QModelIndex& index );
|
virtual void cmdToggleSection( XQCommand& command );
|
||||||
virtual void cmdCut( XQCommand& command );
|
virtual void cmdCut( XQCommand& command );
|
||||||
virtual void cmdCutUndo( XQCommand& command );
|
virtual void cmdCutUndo( XQCommand& command );
|
||||||
virtual void cmdPaste( XQCommand& command );
|
virtual void cmdPaste( XQCommand& command );
|
||||||
@@ -99,7 +99,9 @@ public slots:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void xqItemCreated( XQItem* newItem );
|
void itemCreated( XQItem* newItem );
|
||||||
|
void sectionCreated( const XQModelSection& section );
|
||||||
|
void sectionToggled( const XQModelSection& section );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@@ -111,6 +113,9 @@ protected:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
using MemCall = void (XQViewModel::*)(XQCommand&);
|
||||||
|
using MemCallMap = QMap<XQCommand::CmdType,MemCall>;
|
||||||
|
|
||||||
// das eine reference auf ein globales singleton
|
// das eine reference auf ein globales singleton
|
||||||
XQItemFactory& _itemFactory;
|
XQItemFactory& _itemFactory;
|
||||||
XQSimpleClipBoard _clipBoard;
|
XQSimpleClipBoard _clipBoard;
|
||||||
|
@@ -33,7 +33,6 @@ public:
|
|||||||
(*this)[key] = index;
|
(*this)[key] = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int indexOf(const QString& key) const
|
int indexOf(const QString& key) const
|
||||||
{
|
{
|
||||||
if (contains(key))
|
if (contains(key))
|
||||||
|
22
src/widgets/xqquickwidget.cpp
Normal file
22
src/widgets/xqquickwidget.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
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 <xqquickwidget.h>
|
||||||
|
|
||||||
|
XQQuickWidget::XQQuickWidget()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
27
src/widgets/xqquickwidget.h
Normal file
27
src/widgets/xqquickwidget.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef XQQUICKWIDGET_H
|
||||||
|
#define XQQUICKWIDGET_H
|
||||||
|
|
||||||
|
#include <QQuickWidget>
|
||||||
|
|
||||||
|
class XQQuickWidget : public QQuickWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
XQQuickWidget();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // XQQUICKWIDGET_H
|
@@ -1,4 +1,4 @@
|
|||||||
QT += core gui widgets
|
QT += core gui widgets quick quickwidgets
|
||||||
# widgets-private
|
# widgets-private
|
||||||
|
|
||||||
CONFIG += c++20
|
CONFIG += c++20
|
||||||
@@ -43,6 +43,7 @@ HEADERS += \
|
|||||||
util/xsingleton.h \
|
util/xsingleton.h \
|
||||||
util/xtreewalker.h \
|
util/xtreewalker.h \
|
||||||
widgets/xqcontextmenu.h \
|
widgets/xqcontextmenu.h \
|
||||||
|
widgets/xqquickwidget.h \
|
||||||
widgets/xqtreetable.h
|
widgets/xqtreetable.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
@@ -67,6 +68,7 @@ SOURCES += \
|
|||||||
pugixml/pugixml.cpp \
|
pugixml/pugixml.cpp \
|
||||||
util/xqexception.cpp \
|
util/xqexception.cpp \
|
||||||
widgets/xqcontextmenu.cpp \
|
widgets/xqcontextmenu.cpp \
|
||||||
|
widgets/xqquickwidget.cpp \
|
||||||
widgets/xqtreetable.cpp
|
widgets/xqtreetable.cpp
|
||||||
|
|
||||||
|
|
||||||
@@ -82,6 +84,7 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin
|
|||||||
!isEmpty(target.path): INSTALLS += target
|
!isEmpty(target.path): INSTALLS += target
|
||||||
|
|
||||||
DISTFILES += \
|
DISTFILES += \
|
||||||
|
../quick/xqmodelview.qml \
|
||||||
README.md \
|
README.md \
|
||||||
xml/modelsheets.xml \
|
xml/modelsheets.xml \
|
||||||
xml/modeldata1.xtr \
|
xml/modeldata1.xtr \
|
||||||
|
@@ -7,16 +7,18 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<ItemTypes>
|
<ItemTypes>
|
||||||
<TreeParentType RenderStyle="PlainStyle" ItemFlags="IsEnabled|IsDropEnabled" Icon="DirIcon" />
|
<TreeParentType RenderStyle="PlainStyle" ItemFlags="IsEnabled|IsDropEnabled" Icon="DirIcon" />
|
||||||
<TreeChildType RenderStyle="PlainStyle" ItemFlags="IsCheckable|IsEnabled|IsDragEnabled|IsSelectable|IsDropEnabled"/>
|
<TreeChildType RenderStyle="PlainStyle" ItemFlags="IsEnabled" Icon="DesktopIcon"/>
|
||||||
<HeaderType RenderStyle="HeaderStyle" ItemFlags="IsCheckable|IsEnabled" Icon="DirIcon"/>
|
<TreeSectionType RenderStyle="PlainStyle" ItemFlags="IsUserCheckable|IsEnabled" Icon="DirIcon"/>
|
||||||
<HiddenType RenderStyle="HiddenStyle"/>
|
<HeaderType RenderStyle="HeaderStyle" ItemFlags="IsEnabled"/>
|
||||||
<StaticType RenderStyle="PlainStyle"/>
|
<HiddenType RenderStyle="HiddenStyle"/>
|
||||||
<PlainType RenderStyle="PlainStyle" ItemFlags="IsEnabled|IsEditable|IsSelectable"/>
|
<StaticType RenderStyle="PlainStyle"/>
|
||||||
<ValueType RenderStyle="FormattedStyle" ItemFlags="IsEnabled|IsEditable|IsSelectable" Icon="DirIcon" UnitType="Coulomb"/>
|
<PlainType RenderStyle="PlainStyle" ItemFlags="IsEnabled|IsEditable|IsSelectable"/>
|
||||||
<PercentageType RenderStyle="ProgressBarStyle" ItemFlags="IsEnabled|IsSelectable"/>
|
<ValueType RenderStyle="FormattedStyle" ItemFlags="IsEnabled|IsEditable|IsSelectable" UnitType="Coulomb"/>
|
||||||
<ChoiceType RenderStyle="ComboBoxStyle" ItemFlags="IsEnabled|IsSelectable|IsEditable" FixedChoices="la|le|lo|lu"/>
|
<CheckableType RenderStyle="FormattedStyle" ItemFlags="IsEnabled|IsEditable|IsSelectable" UnitType="###"/>
|
||||||
<IntValueType RenderStyle="SpinBoxStyle" ItemFlags="IsEnabled|IsSelectable"/>
|
<PercentageType RenderStyle="ProgressBarStyle" ItemFlags="IsEnabled|IsSelectable"/>
|
||||||
|
<ChoiceType RenderStyle="ComboBoxStyle" ItemFlags="IsEnabled|IsSelectable|IsEditable" FixedChoices="la|le|lo|lu"/>
|
||||||
|
<IntValueType RenderStyle="SpinBoxStyle" ItemFlags="IsEnabled|IsSelectable"/>
|
||||||
</ItemTypes>
|
</ItemTypes>
|
||||||
|
|
||||||
|
|
||||||
@@ -25,34 +27,39 @@
|
|||||||
<Header>
|
<Header>
|
||||||
<Entry Caption="Active Projects" ItemType="TreeParentType"/>
|
<Entry Caption="Active Projects" ItemType="TreeParentType"/>
|
||||||
</Header>
|
</Header>
|
||||||
<Data>
|
<ModelSheet firz="running">
|
||||||
<Project Caption="@ProjectName" ItemType="TreeParentType"/>
|
<Project Caption="@ProjectName" ItemType="TreeChildType">
|
||||||
</Data>
|
<CurrentSection ItemType="TreeSectionType"/>
|
||||||
</Section>
|
</Project>
|
||||||
|
</ModelSheet>
|
||||||
|
</Section>
|
||||||
<Section ContentType="planned">
|
<Section ContentType="planned">
|
||||||
<Header>
|
<Header>
|
||||||
<Entry Caption="Planned Projects" ItemType="TreeParentType"/>
|
<Entry Caption="Planned Projects" ItemType="TreeParentType"/>
|
||||||
</Header>
|
</Header>
|
||||||
<Data>
|
<ModelSheet firz="planned">
|
||||||
<Project Caption="@ProjectName" ItemType="TreeParentType"/>
|
<Project Caption="@ProjectName" ItemType="TreeChildType">
|
||||||
</Data>
|
<CurrentSection ItemType="TreeSectionType"/>
|
||||||
|
</Project>
|
||||||
|
</ModelSheet>
|
||||||
</Section>
|
</Section>
|
||||||
<Section ContentType="finished">
|
<Section ContentType="finished">
|
||||||
<Header>
|
<Header>
|
||||||
<Entry Caption="Finished Projects" ItemType="TreeParentType"/>
|
<Entry Caption="Finished Projects" ItemType="TreeParentType"/>
|
||||||
</Header>
|
</Header>
|
||||||
<Data>
|
<ModelSheet firz="finished">
|
||||||
<Project Caption="@ProjectName" ItemType="TreeParentType"/>
|
<Project Caption="@ProjectName" ItemType="TreeChildType">
|
||||||
</Data>
|
<CurrentSection ItemType="TreeSectionType"/>
|
||||||
|
</Project>
|
||||||
|
</ModelSheet>
|
||||||
</Section>
|
</Section>
|
||||||
</DocumentTreeModel>
|
</DocumentTreeModel>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<DocumentDetailsModel>
|
<DocumentDetailsModel>
|
||||||
|
|
||||||
<Section ContentType="Panel">
|
<Section ContentType="Panel" firz="farz">
|
||||||
<Header Marker="Panel">
|
<Header Marker="Panel">
|
||||||
<PanelID Caption="Panel" ItemType="HeaderType" />
|
<PanelID Caption="Panel" ItemType="HeaderType" />
|
||||||
<PanelName Caption="Name" ItemType="HeaderType" Icon="BrowserStop" />
|
<PanelName Caption="Name" ItemType="HeaderType" Icon="BrowserStop" />
|
||||||
@@ -64,22 +71,65 @@
|
|||||||
<MaxVolt Caption="max. Volt" ItemType="HeaderType" />
|
<MaxVolt Caption="max. Volt" ItemType="HeaderType" />
|
||||||
<MaxAmpere Caption="max. Ampere" ItemType="HeaderType" />
|
<MaxAmpere Caption="max. Ampere" ItemType="HeaderType" />
|
||||||
</Header>
|
</Header>
|
||||||
<Data>
|
<ModelSheet Marker="Panel">
|
||||||
<!-- 'Icon' überschreibt den default wert im ItemType und erzeugt damit einen neuen ItemType-->
|
<!-- 'Icon' überschreibt den default wert im ItemType und erzeugt damit einen neuen ItemType-->
|
||||||
<PanelID ItemType="PlainType" Icon="DesktopIcon"/>
|
<PanelID ItemType="PlainType" Icon="DesktopIcon"/>
|
||||||
<PanelName ItemType="PlainType" Icon="BrowserStop"/>
|
<PanelName ItemType="PlainType" Icon="BrowserStop"/>
|
||||||
<Manufacturer ItemType="ValueType"/>
|
<Manufacturer ItemType="ValueType"/>
|
||||||
<!-- 'UnitType' überschreibt den default wert im ItemType und erzeugt damit einen neuen ItemType-->
|
<!-- 'UnitType' überschreibt den default wert im ItemType und erzeugt damit einen neuen ItemType-->
|
||||||
<WattPeak ItemType="ValueType" UnitType="Wp" Icon="DesktopIcon"/>
|
<WattPeak ItemType="ValueType" UnitType="Wp"/>
|
||||||
<Width ItemType="ValueType" UnitType="m"/>
|
<Width ItemType="CheckableType" Icon="VistaShield" UnitType="m"/>
|
||||||
<Height ItemType="ValueType" UnitType="m"/>
|
<Height ItemType="ValueType" UnitType="m"/>
|
||||||
<Weight ItemType="ValueType" UnitType="kg"/>
|
<Weight ItemType="ValueType" UnitType="kg"/>
|
||||||
<MaxVolt ItemType="ValueType" UnitType="V"/>
|
<MaxVolt ItemType="ValueType" UnitType="V"/>
|
||||||
<MaxAmpere ItemType="ValueType" UnitType="A"/>
|
<MaxAmpere ItemType="ValueType" UnitType="A"/>
|
||||||
</Data>
|
</ModelSheet>
|
||||||
</Section>
|
</Section>
|
||||||
|
|
||||||
|
|
||||||
|
<Section ContentType="Inverter" firz="farz">
|
||||||
|
<Header Marker="Inverter">
|
||||||
|
<InverterID Caption="Inverter" ItemType="HeaderType" />
|
||||||
|
<InverterName Caption="Name" ItemType="HeaderType" />
|
||||||
|
<Manufacturer Caption="Manufacturer" ItemType="HeaderType" />
|
||||||
|
<MaxPowerInput Caption="max. Input" ItemType="HeaderType" />
|
||||||
|
<MaxPowerOutput Caption="max Output" ItemType="HeaderType" />
|
||||||
|
<NumStrings Caption="Strings" ItemType="HeaderType" />
|
||||||
|
<Weight Caption="Weight" ItemType="HeaderType" />
|
||||||
|
</Header>
|
||||||
|
<ModelSheet Marker="Inverter">
|
||||||
|
<InverterID Caption="Inverter" ItemType="ValueType" />
|
||||||
|
<InverterName Caption="Name" ItemType="ValueType" />
|
||||||
|
<Manufacturer Caption="Manufacturer" ItemType="ValueType" />
|
||||||
|
<MaxPowerInput Caption="max. Input" ItemType="ValueType" ItemType="ChoiceType" ChoiceModelSheetSource="MaxPowerInputChoice" UnitType="W"/>
|
||||||
|
<MaxPowerOutput Caption="max Output" ItemType="ValueType" UnitType="W"/>
|
||||||
|
<NumStrings Caption="Strings" ItemType="ValueType" />
|
||||||
|
<Weight Caption="Weight" ItemType="ValueType" UnitType="kg"/>
|
||||||
|
</ModelSheet>
|
||||||
|
</Section>
|
||||||
|
|
||||||
</DocumentDetailsModel>
|
<Section ContentType="Battery" firz="farz">
|
||||||
|
<Header Marker="Battery">
|
||||||
|
<BatteryID Caption="Name" ItemType="HeaderType" />
|
||||||
|
<BatteryName Caption="Battery" ItemType="HeaderType" />
|
||||||
|
<Manufacturer Caption="Manufacturer" ItemType="HeaderType" />
|
||||||
|
<Capacity Caption="Capacity" ItemType="HeaderType"/>
|
||||||
|
<Yield Caption="Yield" ItemType="HeaderType" />
|
||||||
|
<MaxCurrent Caption="max. Current" ItemType="HeaderType" />
|
||||||
|
<MaxVolt Caption="max. Volt" ItemType="HeaderType" />
|
||||||
|
</Header>
|
||||||
|
<ModelSheet Marker="Bettery">
|
||||||
|
<BatteryID Caption="Battery" ItemType="ValueType" />
|
||||||
|
<BatteryName Caption="Name" ItemType="ValueType" />
|
||||||
|
<Manufacturer Caption="Manufacturer" ItemType="ValueType" />
|
||||||
|
<Capacity Caption="Capacity" ItemType="ValueType" UnitType="Wh"/>
|
||||||
|
<Yield Caption="Yield" ItemType="ValueType" ItemType="PercentageType" UnitType="%"/>
|
||||||
|
<MaxCurrent Caption="max. Current" ItemType="ValueType" UnitType="A"/>
|
||||||
|
<MaxVolt Caption="max. Volt" ItemType="ValueType" UnitType="V"/>
|
||||||
|
</ModelSheet>
|
||||||
|
</Section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</DocumentDetailsModel>
|
Reference in New Issue
Block a user