43 Commits

Author SHA1 Message Date
0f8addbe7f add ignore 2025-09-13 22:54:25 +02:00
b6890257f1 cosmetics 2025-09-13 22:53:32 +02:00
10752908ca try to fix vcx proj 2025-09-13 22:44:33 +02:00
32c5121fcd Merge branch 'experimental/qml-edit' into experimental/add-tree-children
# Conflicts:
#	src/application/xqchildmodel.cpp
2025-09-12 17:21:35 +02:00
Christoph Holzheuer
d07ef3fbf9 First steps. 2025-09-12 15:38:06 +02:00
fd94b2d354 --- fy 2025-09-12 00:39:51 +02:00
cc441d094c Added write-back for combos 2025-09-11 23:09:14 +02:00
Christoph Holzheuer
d5c1f8925c re-merge. 2025-09-11 17:45:44 +02:00
fd41138175 Fix choice model. 2025-09-10 23:32:00 +02:00
Christoph Holzheuer
03b0dafdcc -- fy 2025-09-10 17:57:10 +02:00
a0064b2566 delegate cleanups 2025-09-10 07:27:09 +02:00
Christoph Holzheuer
cbe8b92582 --- fy 2025-09-09 16:22:59 +02:00
809ef10c0d fixed toggle section 2025-09-08 22:58:52 +02:00
Christoph Holzheuer
95b7b026ff --- mess 2025-09-08 15:42:15 +02:00
05bc5ad5d9 -- fy 2025-09-07 23:34:09 +02:00
93ec52933e -- pre fy 2025-09-07 16:22:42 +02:00
3ac129ef26 fixed delete undo. 2025-09-07 15:46:01 +02:00
50703a4c44 fixed cut undo. 2025-09-07 11:29:51 +02:00
1531ec14f1 -- semi-fy 2025-09-06 22:13:46 +02:00
0fe15d6043 fixed selection crashes. 2025-09-06 16:06:47 +02:00
89c671295f finally, fixed hiding of headers. 2025-09-06 14:07:25 +02:00
a9dacca684 Fixed toggleSection 2025-09-06 11:08:07 +02:00
3887748c1a remorked sections. 2025-09-05 21:42:40 +02:00
b8f0893d59 Backup. 2025-09-05 17:12:38 +02:00
9c6f7688d7 Enable section toggle 2025-09-05 11:49:36 +02:00
8d26c32e51 cleanups, added const iterators to xqmaptor 2025-09-05 09:57:43 +02:00
c9b61c1c2b Fixed ::setData, part II 2025-09-04 20:09:21 +02:00
d6ccac1d85 Fixed ::setData, part I 2025-09-04 18:10:14 +02:00
5d2fb1b378 Added new-undo == delete 2025-09-04 17:01:01 +02:00
89c5fd21f1 Completed cmdNew implementation. 2025-09-04 14:56:18 +02:00
f8bd0886d3 Added cmdNew implementation. 2025-09-04 13:52:23 +02:00
Christoph Holzheuer
831daf898c --fy 2025-09-03 17:23:52 +02:00
Christoph Holzheuer
3e7b65dca5 add signal prototypes 2025-09-02 16:58:56 +02:00
147769bf60 added signal handler 'itemChanged' 2025-09-01 23:28:24 +02:00
Christoph Holzheuer
527de65074 -- fy 2025-09-01 17:40:08 +02:00
4d49a495fd -- fy 2025-08-31 23:18:14 +02:00
952409ab1a repaired it (a bit) 2025-08-31 14:38:11 +02:00
c6454f3106 cracket it. 2025-08-27 15:39:33 +02:00
04b0f650d6 -- pre-holiday 2025-08-27 14:06:31 +02:00
6ee677c595 looking better. 2025-08-26 19:41:28 +02:00
5057edb9ad Merge branch 'experimental/qml-widget' 2025-08-26 17:57:16 +02:00
39909ad543 Added scrollbars. 2025-08-26 17:55:39 +02:00
b217f2f9ad little breakthrought im QML Layouts 2025-08-26 17:45:06 +02:00
49 changed files with 1605 additions and 1348 deletions

1
.gitignore vendored
View File

@@ -13,3 +13,4 @@ UsersC998D~1.HOLAppDataLocalTemptmpj0mbo3rd
xml/fitzefatz.xml xml/fitzefatz.xml
build* build*
doc/ doc/
src/xtree.vcxproj.user

View File

@@ -1,5 +1,14 @@
# XTree # XTree
## keys
- Widgetset für XML Daten
- experimenteller qml support
- docs erzeugen
-
experimenelle
## Also, noch mal von vorn: ## Also, noch mal von vorn:
- Es geht um das Editieren von XML Daten in einer baumartigen Darstellung am Bildschirm. - Es geht um das Editieren von XML Daten in einer baumartigen Darstellung am Bildschirm.

83
qml/xqtreeview.qml Normal file
View File

@@ -0,0 +1,83 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
TreeView
{
anchors.fill: parent
clip: true
columnSpacing: 1
rowSpacing: 1
model: xtrChildModel
columnWidthProvider: function(column)
{
var z= 1.7*(width / columns);
return z;
}
delegate: Rectangle
{
required property int row
required property int column
required property var model
border.width: 0
implicitWidth: 30
implicitHeight: 20
border.color: "#cccccc"
//color: index % 2 === 0 ? "#f9f9f9" : "#e0e0e0"
//color: TreeView.isSelected ? "#d0eaff" : (row % 2 === 0 ? "#f9f9f9" : "#ffffff")
//color: TreeView.isSelected ? "#d0eaff" : (row % 2 === 0 ? "#f9f9f9" : "#ffffff")
TextField
{
id: currentEntry
anchors.centerIn: parent
text: display
font.pixelSize: 12
// Ändere die Border-Farbe je nachdem, ob das Feld den Fokus hat
property color borderColor: currentEntry.activeFocus ? "dodgerblue" : "gray"
property int borderWidth: currentEntry.activeFocus ? 2 : 1
background: Rectangle {
// Die Farbe des Hintergrunds im Normalzustand
color: "#ffffff"
// Hier werden Rahmenfarbe und -breite definiert
border.color: currentEntry.borderColor
border.width: currentEntry.borderWidth
// Abgerundete Ecken für ein modernes Aussehen
radius: 4
// Sanfter Übergang der Rahmenfarbe und -breite
Behavior on border.color {
ColorAnimation { duration: 150 }
}
Behavior on border.width {
NumberAnimation { duration: 150 }
}
}
onEditingFinished:
{
console.log("Editing finished, new text is :"+ text + " at index :" + index)
model.display = text //The roles here are defined in model class
}
}
}
ScrollBar.horizontal: ScrollBar {}
ScrollBar.vertical: ScrollBar {}
}

View File

@@ -1,35 +0,0 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
TableView
{
id: table
anchors.fill: parent
columnSpacing: 2
rowSpacing: 2
model: meinModel // z.B. QStandardItemModel mit 9 Spalten
delegate: Rectangle
{
required property string display
width: 100
height: 20
border.color: "#ccc"
Text
{
anchors.centerIn: parent
text: display
font.pixelSize: 10
}
}
// // Optional: Spaltenbreiten setzen
// onModelChanged: {
// for (let i = 0; i < model.columns; ++i)
// table.setColumnWidth(i, 100)
// }
}

View File

@@ -38,6 +38,7 @@ const QString c_ProjectID = "ProjectID";
const QString c_ModelSheetFileName = "xml/modelsheets.xml"; const QString c_ModelSheetFileName = "xml/modelsheets.xml";
const QString c_ModelDummyFileName = "xml/saved_testfile.xtr"; const QString c_ModelDummyFileName = "xml/saved_testfile.xtr";
const QString c_DocumentDirectory = "xml/"; const QString c_DocumentDirectory = "xml/";
const QString c_DocumentFileName1 = "xml/modeldata1.xtr"; const QString c_DocumentFileName1 = "xml/modeldata1.xtr";
const QString c_DocumentFileName2 = "xml/modeldata2.xtr"; const QString c_DocumentFileName2 = "xml/modeldata2.xtr";
const QString c_DocumentFileName3 = "xml/modeldata3.xtr"; const QString c_DocumentFileName3 = "xml/modeldata3.xtr";

View File

@@ -36,9 +36,8 @@ XQChildModel::XQChildModel( QObject *parent )
void XQChildModel::addModelData( const XQNodePtr& contentRoot ) void XQChildModel::addModelData( const XQNodePtr& contentRoot )
{ {
// __fix: set object name ?? setObjectName( contentRoot->to_string() );
//qDebug() << " --- create Model Data: " << contentRoot->to_string();
qDebug() << " --- create Model Data: " << contentRoot->to_string();
// Die Datenbasis als shared_ptr sichern // Die Datenbasis als shared_ptr sichern
_contentRoot = contentRoot; _contentRoot = contentRoot;
@@ -50,70 +49,81 @@ void XQChildModel::addModelData( const XQNodePtr& contentRoot )
// Das ist hier der Typ des Eintrags: Panel, Battery ... // Das ist hier der Typ des Eintrags: Panel, Battery ...
QString key = contentEntry->tag_name(); QString key = contentEntry->tag_name();
// 'silent failure' hier der Datenbaum kann auch Knoten enthalten // 'silent failure' hier der Datenbaum kann auch Knoten enthalten
// die nicht für uns gedacht sind. // die nicht für uns gedacht sind.
if (!_sections.hasValidSection(key)) if (!_sections.hasValidSection(key))
continue; continue;
XQModelSection& section = _sections.at( key ); const XQModelSection& section = _sections.sectionByKey( key );
// wir speichern das parent des datenknoten auch in der
// section.
// contentEntry->parent == _contentRoot, aber halt nur weil das model flach ist
//qDebug() << " --- add section ENTRY: " << key << " TagName: " << contentEntry->attribute("TagName");
section.setContentRootNode( contentEntry->parent() ); section.setContentRootNode( contentEntry->parent() );
int newRow = _sections.lastRow(section); int newRow = _sections.lastRow(section);
XQNodePtr sheetNode = section.sheetRootNode(); XQNodePtr sheetNode = section.sheetRootNode();
XQItemList list = _itemFactory.makeRow( XQItemFactory::mData, sheetNode, contentEntry ); XQItemList list = _itemFactory.makeRow( sheetNode, contentEntry );
// als Baum? // als Baum?
//section.headerItem().appendRow( list ); //section.headerItem().appendRow( list );
insertRow( newRow, list);
// _hinter_ der letzen zeile einfügen
insertRow( newRow+1, list);
if( contentEntry->has_children())
{
qDebug() << " --- AddModelData: CHILD Found for: :" << contentEntry->tag_name() << " sheet parent: " << sheetNode->tag_name();
if( !sheetNode->has_children() )
qDebug() << " --- AUA";
//else
}
} // for } // for
} }
//! Erzeugt eine model-section und fügt den zugehörigen header ein.
void XQChildModel::addSectionEntry( const QString& key, const XQNodePtr& contentEntry ) void XQChildModel::addSectionEntry( const QString& key, const XQNodePtr& contentEntry )
{ {
XQModelSection& section = _sections.at( key ); const XQModelSection& section = _sections.sectionByKey( key );
if(section.isValid() ) if(section.isValid() )
{ {
section.setContentRootNode( contentEntry->parent() ); section.setContentRootNode( contentEntry->parent() );
int newRow = _sections.lastRow(section); int newRow =_sections.lastRow(section);
XQNodePtr sheetNode = section.sheetRootNode(); XQNodePtr sheetNode = section.sheetRootNode();
XQItemList list = _itemFactory.makeRow( XQItemFactory::mHeader, sheetNode, contentEntry ); XQItemList list = _itemFactory.makeRow( sheetNode, nullptr );
insertRow( newRow, list); insertRow( newRow, list);
} }
} }
//! erzeugt ein adhoc-contextmenu, je nachdem welche aktionen gerade möflich sind.
//! erzeugt ein adhoc-contextmenu, je nachdem welche aktionen gerade möglich sind.
void XQChildModel::initContextMenu() void XQChildModel::initContextMenu()
{ {
// __fixme! add a menu title // __fixme! add a menu title
_contextMenu->clear(); _contextMenu->clear();
const QModelIndex& curIdx = _treeTable->currentIndex(); const QModelIndex& curIdx = _treeTable->currentIndex();
bool hasSel = curIdx.isValid() && _treeTable->selectionModel()->hasSelection();
bool canPaste = _clipBoard.canPaste( curIdx );
_contextMenu->addAction( "icn11Dummy", "Undo", XQCommand::cmdUndo, _undoStack->canUndo() ); _contextMenu->addAction( "icn11Dummy", "Undo", XQCommand::cmdUndo, _undoStack->canUndo() );
_contextMenu->addAction( "icn17Dummy", "Redo", XQCommand::cmdRedo, _undoStack->canRedo() ); _contextMenu->addAction( "icn17Dummy", "Redo", XQCommand::cmdRedo, _undoStack->canRedo() );
_contextMenu->addAction( "icn58Dummy", "Cut", XQCommand::cmdCut, hasSel ); // editieren nur wenns kein header ist.
_contextMenu->addAction( "icn61Dummy", "Paste", XQCommand::cmdPaste, canPaste ); if ( !xqItemFromIndex(curIdx).isHeaderStyle() )
_contextMenu->addAction( "icn55Dummy", "Copy", XQCommand::cmdCopy, hasSel ); {
//_contextMenu->addAction( "icn35Dummy", "Move", XQCommand::cmdMove, hasSel ); bool hasSel = curIdx.isValid() && _treeTable->selectionModel()->hasSelection();
_contextMenu->addAction( "icn70Dummy", "New", XQCommand::cmdNew, hasSel ); bool canPaste = _clipBoard.canPaste( curIdx );
_contextMenu->addAction( "icn50Dummy", "Delete", XQCommand::cmdDelete, hasSel );
_contextMenu->addAction( "icn58Dummy", "Cut", XQCommand::cmdCut, hasSel );
_contextMenu->addAction( "icn61Dummy", "Paste", XQCommand::cmdPaste, canPaste );
_contextMenu->addAction( "icn55Dummy", "Copy", XQCommand::cmdCopy, hasSel );
//_contextMenu->addAction( "icn35Dummy", "Move", XQCommand::cmdMove, hasSel );
_contextMenu->addAction( "icn70Dummy", "New", XQCommand::cmdNew, hasSel );
_contextMenu->addAction( "icn50Dummy", "Delete", XQCommand::cmdDelete, hasSel );
}
// __fixme! set 'toggle section <name>' entry // __fixme! set 'toggle section <name>' entry
//contextMenu.actions().first()->setText("<name>"); //contextMenu.actions().first()->setText("<name>");
_contextMenu->addAction( "icn29Dummy", "Toggle Section", XQCommand::cmdToggleSection, hasSel); _contextMenu->addAction( "icn29Dummy", "Hide Section", XQCommand::cmdToggleSection, true );
} }

View File

@@ -18,8 +18,8 @@
//! erzeugt ein docukument //! erzeugt ein docukument
XQDocument::XQDocument(const QString& aFileName, const QString& aFriendlyName, XQItem* aTreeItem, XQViewModel* aModelView ) XQDocument::XQDocument(const QString& aFileName, const QString& aFriendlyName, XQItem* aTreeItem, XQViewModel* aViewModel )
: fileName{ aFileName }, friendlyName{ aFriendlyName }, treeItem{ aTreeItem }, modelView{ aModelView } : fileName{ aFileName }, friendlyName{ aFriendlyName }, treeItem{ aTreeItem }, viewModel{ aViewModel }
{ {
} }
@@ -44,9 +44,9 @@ XQDocumentStore::~XQDocumentStore()
//! erzeugt ein document eintrag //! erzeugt ein document eintrag
void XQDocumentStore::addDocument( const QString& aFileName, const QString& aFriendlyName, XQItem* aTreeItem, XQViewModel* aModelView ) void XQDocumentStore::addDocument(const QString& aFileName, const QString& aFriendlyName, XQItem* aTreeItem, XQViewModel* aViewModel )
{ {
XQDocument newDocument( aFileName, aFriendlyName, aTreeItem, aModelView ); XQDocument newDocument( aFileName, aFriendlyName, aTreeItem, aViewModel );
addAtKey( aFileName, newDocument ); addAtKey( aFileName, newDocument );
// attention: this assumes the presence of the 'ProjectID' value // attention: this assumes the presence of the 'ProjectID' value
//addAlias( aFileName, aTreeItem->attribute(c_ProjectID) ); //addAlias( aFileName, aTreeItem->attribute(c_ProjectID) );

View File

@@ -28,12 +28,10 @@ struct XQDocument
XQDocument() = default; XQDocument() = default;
XQDocument( const QString& aFileName, const QString& aFriendlyName, XQItem* aTreeItem, XQViewModel* aModelView ); XQDocument( const QString& aFileName, const QString& aFriendlyName, XQItem* aTreeItem, XQViewModel* aModelView );
virtual ~XQDocument() = default;
QString fileName; // also used as key QString fileName; // also used as key
QString friendlyName; QString friendlyName;
XQItem* treeItem{}; XQItem* treeItem{};
XQViewModel* modelView{}; XQViewModel* viewModel{};
}; };
@@ -46,11 +44,7 @@ public:
XQDocumentStore() = default; XQDocumentStore() = default;
virtual ~ XQDocumentStore(); virtual ~ XQDocumentStore();
void addDocument( const QString& aFileName, const QString& aFriendlyName, XQItem* aTreeItem, XQViewModel* aModelView ); void addDocument( const QString& aFileName, const QString& aFriendlyName, XQItem* aTreeItem, XQViewModel* aViewModel );
protected:
XQNode _treeRootNode{ "treeRootNode" };
}; };

View File

@@ -45,57 +45,36 @@ void XQMainModel::initContextMenu()
XQItem* XQMainModel::addProjectItem( XQNodePtr contentNode ) XQItem* XQMainModel::addProjectItem( XQNodePtr contentNode )
{ {
// wir durchsuchen alle unsere section nach dem passenden content-type, // wir durchsuchen alle unsere sections nach dem passenden content-type,
// hier: content-type beschreibt die // hier: content-type beschreibt den projekt-status
const QString& sectionKey = contentNode->attribute(c_ContentType);
for(const auto& section : _sections ) if( _sections.hasValidSection( sectionKey ) )
{ {
const XQModelSection& section = _sections.sectionByKey( sectionKey );
// __fixme! das ist mist!
const XQNodePtr sheetNode = section.sheetRootNode()->first_child();
XQItem* newItem = _itemFactory.makeSingleItem( sheetNode, contentNode->attribute( "ProjectName") );
if( contentNode->attribute( c_ContentType) == section.contentType() ) // den neuen eintrag in die passende section der übersicht eintragen ...
{ section.headerItem().appendRow( newItem );
// erzeuger sheet node speichern
qDebug() << " --- add PROJECT: contentNode: " << contentNode->to_string(); newItem->setSheetNode( sheetNode );
expandNewItem(section.headerItem().index() );
// __fixme! das ist mist! return newItem;
const XQNodePtr sheetNode = section.sheetRootNode()->first_child();
XQItemList list = _itemFactory.makeRow( XQItemFactory::mSingle, sheetNode, contentNode, "ProjectName");
// den neuen eintrag in die passende section der übersicht eintragen ...
section.headerItem().appendRow( list );
// ... ausklappen...
const QModelIndex index = section.headerItem().index();
_treeTable->expand( index );
// ... und markieren
_treeTable->setCurrentIndex( index );
// quellknoten auch speichern
//newItem->setContentNode( contentNode );
//emit itemCreated( newItem );
XQItem* newItem = dynamic_cast<XQItem*>(list[0]);
// erzeuger sheet node speichern
newItem->setSheetNode( sheetNode );
return newItem;
}
} }
throw XQException( "addProjectItem: main model should not be empty!" ); throw XQException( "addProjectItem: main model should not be empty!" );
} }
//! erzeugt einen einzelen baum-eintrag mit hilfe der section und den projekt-daten
void XQMainModel::addSectionItem( const XQModelSection& section, XQItem* projectItem ) void XQMainModel::addSectionItem( const XQModelSection& section, XQItem* projectItem )
{ {
return;
// ich brauche _meine_ section für den sheetNode!
XQNodePtr sheetNode = projectItem->sheetNode()->find_child_by_tag_name("CurrentSection"); XQNodePtr sheetNode = projectItem->sheetNode()->find_child_by_tag_name("CurrentSection");
XQItemList list = _itemFactory.makeRow( XQItemFactory::mSingle, sheetNode, nullptr, c_ContentType ); XQItem* newItem = _itemFactory.makeSingleItem( sheetNode, section.contentType() );
projectItem->appendRow( list ); projectItem->appendRow( newItem );
_treeTable->expand( projectItem->index() ); expandNewItem(projectItem->index() );
} }

View File

@@ -35,6 +35,7 @@ public:
XQItem* addProjectItem( XQNodePtr contentNode ); XQItem* addProjectItem( XQNodePtr contentNode );
void addSectionItem( const XQModelSection& section, XQItem* projectItem ); void addSectionItem( const XQModelSection& section, XQItem* projectItem );
protected: protected:
void initContextMenu() override; void initContextMenu() override;

View File

@@ -88,36 +88,33 @@ void XQMainWindow::initMainWindow()
connect( _actionExit, &QAction::triggered, this, &XQMainWindow::onExit ); connect( _actionExit, &QAction::triggered, this, &XQMainWindow::onExit );
connect( _actionAbout, &QAction::triggered, this, &XQMainWindow::onAbout ); connect( _actionAbout, &QAction::triggered, this, &XQMainWindow::onAbout );
connect( _tabWidget, SIGNAL(tabBarClicked(int)), this, SLOT(onChildViewTabClicked(int)) );
//connect(&_mainModel, &QStandardItemModel::itemChanged, this, &XQMainWindow::onTreeItemChanged );
//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(&_mainModel, &XQViewModel::xqItemChanged, this, &XQMainWindow::onTreeViewItemChanged );
connect( _mainTreeView, &QTreeView::clicked, this, [&,this](const QModelIndex& index)
/*
connect( &_mainModelView, &XQViewModel::itemCreated, this, [=, this](XQItem* item)
{ {
// when a new main tree item has been created ... onTreeViewItemClicked( XQItem::xqItemFromIndex(index) );
QString pID = item->contentNode()->attribute(c_ProjectID); });
_mainTreeView->setCurrentIndex( item->index() );
// ... we set the current view to this node
if( _documentStore.contains( pID ) )
_tabWidget->setCurrentWidget( _documentStore[pID].modelView->treeTable() );
} );
*/
try try
{ {
// hand over undostack // hand over undostack
_mainModelView.setUndoStack(&_undoStack); _mainModel.setUndoStack(&_undoStack);
// hand over left side navigation tree // hand over left side navigation tree
_mainModelView.setTreeTable(_mainTreeView); _mainModel.setTreeTable(_mainTreeView);
// #1. init the left side main tree view // #1. init the left side main tree view
_mainModelView.initModel( c_MainModelName ); _mainModel.initModel( c_MainModelName );
// #2. load demo data // #2. load demo data
loadDocument( c_DocumentFileName1 ); loadDocument( c_DocumentFileName1 );
//loadDocumentQML( c_DocumentFileName2 ); loadDocumentQML( c_DocumentFileName2 );
//loadDocument( c_DocumentFileName2 );
//loadDocument( c_DocumentFileName3 );
qDebug() << " --- all here: " << XQNode::s_Count; qDebug() << " --- all here: " << XQNode::s_Count;
@@ -232,7 +229,7 @@ void XQMainWindow::onAbout()
QMessageBox msgBox(QMessageBox::NoIcon, "About", "", QMessageBox::Ok); QMessageBox msgBox(QMessageBox::NoIcon, "About", "", QMessageBox::Ok);
QString text = "<b>xtree concept</b><br>"; QString text = "<b>xtree concept</b><br>";
text += "2024 c.holzheuer<br><br>"; text += "2024-2025 c.holzheuer<br><br>";
text += "<a href=\"https://sourceworx.org/xtree\">sourceworx.org/xtree</a>"; text += "<a href=\"https://sourceworx.org/xtree\">sourceworx.org/xtree</a>";
msgBox.setTextFormat(Qt::RichText); // This allows you to click the link msgBox.setTextFormat(Qt::RichText); // This allows you to click the link
@@ -242,64 +239,93 @@ void XQMainWindow::onAbout()
} }
//! wenn ein item im navigations-baum geklickt wird, soll die document //! wenn ein item im navigations-baum geklickt wird, soll die document
//! view rechts angepasst werden. //! view rechts angepasst werden.
void XQMainWindow::onTreeItemClicked(const QModelIndex& index ) void XQMainWindow::onTreeViewItemClicked( const XQItem& item )
{ {
//qDebug() << " --- Tree item CLICK:" << item.text() << " : " << item.itemType().text();
XQItem& entry = XQItem::xqItemFromIndex(index); if( item.itemType().text() == "TreeChildType" )
qDebug() << " --- XXX mainWindow onTreeItemClicked:" << entry.text();
_mainTreeView->selectionModel()->select(index, QItemSelectionModel::Select);
if( XQNodePtr contentNode = entry.contentNode() )
{ {
QString key = contentNode->attribute(c_ProjectID); setChildTabByName( item.text() );
qDebug() << " --- FIRZ: key: " << key;
bool isThere = _documentStore.contains(key);
if( isThere)
_tabWidget->setCurrentWidget( _documentStore[key].modelView->treeTable() );
} }
}
void XQMainWindow::onTreeViewItemChanged(const XQItem& item )
{
qDebug() << " --- TREE VIEW itemChanged:" << item.text() << " : " << item.parent()->text() << " : " << (void*)&_mainModel << " : " << (void*) sender();
// hier müssen wir erst das projekt aktivieren
XQItem* xqItem = static_cast<XQItem*>(item.parent());
onTreeViewItemClicked( *xqItem );
//if( item.itemType().text() == "TreeSectionType" )
{
int idx = _tabWidget->currentIndex();
if(_documentStore.contains(idx) )
{
qDebug() << " --- should toggle: " << item.text();
XQViewModel& childModel = *_documentStore[idx].viewModel;
childModel.onToggleSection(item.text());
}
}
} }
//! beim click auf ein tab im linken fenster wird der navigationsbaum angepasst. //! beim click auf ein tab im linken fenster wird der navigationsbaum angepasst.
void XQMainWindow::onTabClicked( int index ) void XQMainWindow::onChildViewTabClicked( int idx )
{ {
//const QString& key = _documentStore[index].treeItem->attribute( c_ProjectID ); if(_documentStore.contains(idx) )
//qDebug() << " ---- tab clicked: " << index << " : " << _documentStore[index].friendlyName;// << ": " << key;
//_mainTreeView->setCurrentIndex( _documentStore[index].treeItem->index() );
}
void XQMainWindow::onSectionCreated( const XQModelSection& section )
{
qDebug() << " --- XXX section created: " << section.contentType() << ":" << section.sheetRootNode()->to_string();
if( _currentProjectItem )
{ {
_mainModelView.addSectionItem( section, _currentProjectItem ); QModelIndex treeIndex =_documentStore[idx].treeItem->index();
_mainModel.expandNewItem( treeIndex );
} }
} }
void XQMainWindow::onSectionToggled( const XQModelSection& section )
//! SLOT, der aufgerufen wird, sobald eine section erzeugt worden ist.
void XQMainWindow::onSectionCreated( const XQModelSection& section )
{ {
//qDebug() << " --- XXX section toggled: " << section.contentType() << ":" << section.sheetRootNode()->to_string(); if( _currentProjectItem )
{
_mainModel.addSectionItem( section, _currentProjectItem );
}
} }
QStandardItemModel* createModel() {
auto* model = new QStandardItemModel;
model->setHorizontalHeaderLabels({ "Name" });
QStandardItem* parent = new QStandardItem("Tiere"); //! SLOT, der aufgerufen wird, wenn eine section getoggelt wurde.
parent->appendRow(new QStandardItem("Hund"));
parent->appendRow(new QStandardItem("Katze"));
model->appendRow(parent);
return model; void XQMainWindow::onSectionToggled( const XQModelSection& section )
{
qDebug() << " --- XXX section toggled: " << section.contentType() << ":" << section.sheetRootNode()->to_string();
{
for (int row = 0; row < _currentProjectItem->rowCount(); ++row)
{
QStandardItem* child = _currentProjectItem->child(row);
if (child->text() == section.contentType() )
{
bool checked = (child->checkState() == Qt::Checked);
child->setCheckState( checked ? Qt::Unchecked :Qt::Checked );
break;
}
}
}
}
//! aktiviert das tab, das zum dokument mit dem schlüssel 'key' gehört.
void XQMainWindow::setChildTabByName( const QString& key )
{
for( int i=0; i<_documentStore.size(); ++i )
{
if( key == _documentStore[i].friendlyName)
{
_tabWidget->setCurrentIndex(i);
return;
}
}
} }
void XQMainWindow::loadDocumentQML( const QString& fileName ) void XQMainWindow::loadDocumentQML( const QString& fileName )
@@ -319,8 +345,6 @@ void XQMainWindow::loadDocumentQML( const QString& fileName )
// das als Namen verwendet wird. // das als Namen verwendet wird.
const QString& fName = contentRoot->friendly_name(); const QString& fName = contentRoot->friendly_name();
QStandardItemModel* model = createModel();
// Ein neues Child-Model erzeugen // Ein neues Child-Model erzeugen
XQChildModel* childModel = new XQChildModel(this); XQChildModel* childModel = new XQChildModel(this);
// die Modelstruktur anlegen // die Modelstruktur anlegen
@@ -331,13 +355,12 @@ void XQMainWindow::loadDocumentQML( const QString& fileName )
XQQuickWidget* quickChild = new XQQuickWidget(_tabWidget); XQQuickWidget* quickChild = new XQQuickWidget(_tabWidget);
//quickChild->setResizeMode(QQuickWidget::SizeViewToRootObject); //quickChild->setResizeMode(QQuickWidget::SizeViewToRootObject);
quickChild->rootContext()->setContextProperty("meinModel", childModel); quickChild->rootContext()->setContextProperty("xtrChildModel", childModel);
quickChild->setSource(QUrl(QStringLiteral("qrc:/quickview.qml"))); quickChild->setSource(QUrl("qrc:/xqtreeview.qml"));
_tabWidget->addTab( quickChild, "Fitze!" ); _tabWidget->addTab( quickChild, "QML:"+fName );
_tabWidget->setCurrentWidget( quickChild ); _tabWidget->setCurrentWidget( quickChild );
quickChild->setResizeMode(QQuickWidget::SizeRootObjectToView); quickChild->setResizeMode(QQuickWidget::SizeRootObjectToView);
} }
//! liest eine XML datei namens 'fileName' //! liest eine XML datei namens 'fileName'
@@ -369,13 +392,13 @@ void XQMainWindow::loadDocument( const QString& fileName )
// 'friendly Name' ist ein Link auf ein anderes Attribute // 'friendly Name' ist ein Link auf ein anderes Attribute
// das als Namen verwendet wird. // das als Namen verwendet wird.
const QString& fName = contentRoot->friendly_name(); const QString& fName = contentRoot->friendly_name();
QString pTitle = QString("Project %1: %2").arg( pID, fName ); QString pTabTitle = QString("Project %1: %2").arg( pID, fName );
// Eine neue TreeView erzeugn und im TabWidget parken. // Eine neue TreeView erzeugn und im TabWidget parken.
XQTreeTable* childTreeView = new XQTreeTable(_tabWidget); XQTreeTable* childTreeView = new XQTreeTable(_tabWidget);
_tabWidget->addTab( childTreeView, pTitle ); _tabWidget->addTab( childTreeView, pTabTitle );
_tabWidget->setCurrentWidget( childTreeView ); _tabWidget->setCurrentWidget( childTreeView );
setWindowTitle( pTitle ); setWindowTitle( pTabTitle );
// Ein neues Child-Model erzeugen // Ein neues Child-Model erzeugen
XQChildModel* childModel = new XQChildModel(this); XQChildModel* childModel = new XQChildModel(this);
@@ -390,8 +413,8 @@ void XQMainWindow::loadDocument( const QString& fileName )
childModel->setTreeTable(childTreeView); childModel->setTreeTable(childTreeView);
// neuen eintrag im übsichts-baum erzeugen // neuen eintrag im übsichts-baum erzeugen
_currentProjectItem = _mainModelView.addProjectItem( contentRoot ); _currentProjectItem = _mainModel.addProjectItem( contentRoot );
_documentStore.addDocument( fileName, pTitle, _currentProjectItem, childModel ); _documentStore.addDocument( fileName, fName, _currentProjectItem, childModel );
// die Modelstruktur anlegen // die Modelstruktur anlegen
childModel->initModel( c_ChildModelName ); childModel->initModel( c_ChildModelName );
@@ -409,7 +432,9 @@ void XQMainWindow::saveDocument( const QString& fileName )
{ {
XQNodeWriter nodeWriter; XQNodeWriter nodeWriter;
int curIdx = _tabWidget->currentIndex(); int curIdx = _tabWidget->currentIndex();
XQNodePtr rootNode = _documentStore[curIdx].treeItem->contentNode(); //XQNodePtr rootNode = _documentStore[curIdx].treeItem->contentNode();
XQNodePtr rootNode = _documentStore[curIdx].viewModel->contentRootNode();
Q_ASSERT(rootNode);
nodeWriter.dumpTree( rootNode, fileName ); nodeWriter.dumpTree( rootNode, fileName );
} }

View File

@@ -35,6 +35,11 @@ public:
public slots: public slots:
virtual void onMyFirz(XQItem& item)
{
qDebug() << " --- myFirz: " << item.text();
}
void onUndo(); void onUndo();
void onRedo(); void onRedo();
@@ -46,30 +51,32 @@ public slots:
void onAbout(); void onAbout();
void onExit(); void onExit();
void onTreeItemClicked(const QModelIndex& index ); void onTreeViewItemClicked( const XQItem& item );
void onTabClicked( int index ); void onTreeViewItemChanged( const XQItem& item );
void onChildViewTabClicked( int index );
//void onItemCreated( XQItem* item ); //void onItemCreated( XQItem* item );
void onSectionCreated( const XQModelSection& section); void onSectionCreated( const XQModelSection& section);
void onSectionToggled( const XQModelSection& section ); void onSectionToggled( const XQModelSection& section );
void setChildTabByName( const QString& key );
static void setupWorkingDir();
protected: protected:
void setupWorkingDir();
// fixme implement // fixme implement
void showDocumnet( const QString& key ){} void showDocument( const QString& key ){}
void loadDocument( const QString& fileName ); void loadDocument( const QString& fileName );
void loadDocumentQML( const QString& fileName ); void loadDocumentQML( const QString& fileName );
void saveDocument( const QString& fileName ); void saveDocument( const QString& fileName );
QUndoStack _undoStack; QUndoStack _undoStack;
XQDocumentStore _documentStore; XQDocumentStore _documentStore;
XQMainModel _mainModelView; XQMainModel _mainModel;
XQItem* _currentProjectItem{}; XQItem* _currentProjectItem{};
//XQChildModel* _currentChildModel{};
}; };

View File

@@ -64,7 +64,7 @@ XQItem::XQRenderStyleMap XQItem::s_RenderStyleMap
{ "CustomRenderStyle", CustomRenderStyle }, { "CustomRenderStyle", CustomRenderStyle },
{ "PickerStyle", PickerStyle }, { "PickerStyle", PickerStyle },
{ "SpinBoxStyle", SpinBoxStyle }, { "SpinBoxStyle", SpinBoxStyle },
{ "ProgressBarStyle", ProgressBarStyle}, { "ColorBarStyle", ColorBarStyle},
{ "FormattedStyle", FormattedStyle}, { "FormattedStyle", FormattedStyle},
}; };
@@ -74,7 +74,7 @@ XQItem::XQEditorTypeMap XQItem::s_EditorTypeMap
{ "LineEditType", LineEditType }, { "LineEditType", LineEditType },
{ "ComboBoxType", ComboBoxType }, { "ComboBoxType", ComboBoxType },
{ "PickerType", PickerType }, { "PickerType", PickerType },
{ "ProgressBarType", ProgressBarType }, { "ColorBarType", ColorBarType },
{ "SpinBoxType", SpinBoxType}, { "SpinBoxType", SpinBoxType},
{ "CustomEditorType", CustomEditorType} { "CustomEditorType", CustomEditorType}
}; };
@@ -116,6 +116,8 @@ XQItem::XQPrefixExponentMap XQItem::s_PrefixExponentMap
}; };
//! Default konstruktor, setzt einen ungültigen (dummy)
//! itemType.
XQItem::XQItem() XQItem::XQItem()
: XQItem{XQItemType::staticItemType()} : XQItem{XQItemType::staticItemType()}
@@ -123,6 +125,9 @@ XQItem::XQItem()
} }
//! Default konstruktor mit einem vorhandenen itemType.
XQItem::XQItem( XQItemType* itemType ) XQItem::XQItem( XQItemType* itemType )
: QStandardItem{} : QStandardItem{}
{ {
@@ -130,12 +135,21 @@ XQItem::XQItem( XQItemType* itemType )
} }
XQItem::XQItem(XQItemType* itemType, const QString *content ) //! konstruiert ein daten-item mit zeiger auf 'unser' attribut
//! im übergeordneten content-node.
XQItem::XQItem(XQItemType* itemType, const QString* content )
: XQItem{ itemType } : XQItem{ itemType }
{ {
setContent(content); // hier setzen wir direkt ohne umwege den string pointer
QStandardItem::setData( QVariant::fromValue<const QString*>(content), XQItem::ContentRole );
} }
XQItem::XQItem( XQItemType* itemType, const QString& content )
: XQItem{ itemType }
{
setText(content);
}
//! ruft den copy-konstruktor auf. //! ruft den copy-konstruktor auf.
XQItem* XQItem::clone() const XQItem* XQItem::clone() const
@@ -147,21 +161,36 @@ XQItem* XQItem::clone() const
//! false für ein ungültiges item. 'ungültig' heisst hier, dass nur ein //! false für ein ungültiges item. 'ungültig' heisst hier, dass nur ein
//! mockup-itemtype gesetzt ist. //! mockup-itemtype gesetzt ist.
bool XQItem::isValid() const bool XQItem::isValidX() const
{ {
XQItemType* dummyType = XQItemType::staticItemType(); XQItemType* dummyType = XQItemType::staticItemType();
return QStandardItem::data( XQItem::ItemTypeRole ).value<XQItemType*>() != dummyType; return QStandardItem::data( XQItem::ItemTypeRole ).value<XQItemType*>() != dummyType;
} }
bool XQItem::hasContentNode() const
{
if( column() == 0)
{
QVariant value = QStandardItem::data( XQItem::ContentNodeRole );
return !value.isNull();
}
// sonst: delegieren an den node-Besitzer
QModelIndex pIndex = model()->index( row(), 0 );
if( pIndex.isValid() )
{
XQItem& firstItem = xqItemFromIndex( pIndex );
return firstItem.hasContentNode();
}
return false;
}
//! gibt den content-node zurück. //! gibt den content-node zurück.
XQNodePtr XQItem::contentNode() const XQNodePtr XQItem::contentNode() const
{ {
XQNodePtr node = data( ContentNodeRole ).value<XQNodePtr>(); return data( ContentNodeRole ).value<XQNodePtr>();
if( node )
return node;
throw XQException("XQItem::contentNode() nullptr");
} }
@@ -319,37 +348,23 @@ QString XQItem::rawText() const
//! Gibt den string-zeiger auf das attribut aus unseren XQNodePtr zurück. //! Gibt den string-zeiger auf das attribut aus unseren XQNodePtr zurück.
/*
QString* XQItem::content() const QString* XQItem::content() const
{ {
// macht jetzt das, ws draufsteht: gibt einen string* zurück // macht jetzt das, was draufsteht: gibt einen string* zurück
return data( XQItem::ContentRole ).value<QString*>(); return data( XQItem::ContentRole ).value<QString*>();
} }
*/
//! set den content()-string pointer. (als leihgabe) //! Gibt den content-format string zurück
void XQItem::setContent( const QString* content )
{
setData( QVariant::fromValue<const QString*>(content), XQItem::ContentRole );
}
//! holt den schlüssel bzw. bezeicher des content() string aus 'unserem' content knoten.
QString XQItem::contentKey() const
{
return contentNode()->attributes().key_of( rawText() );
}
//! gibt den content-format string zurück
QString XQItem::contentFormat() const QString XQItem::contentFormat() const
{ {
return data( XQItem::ContentFormatRole ).toString(); return data( XQItem::ContentFormatRole ).toString();
} }
//! setz den den content format-string. wird im itemType gespeichert. //! Setzt den den content format-string. wird im itemType gespeichert.
void XQItem::setContentFormat(const QString& contentFormat) void XQItem::setContentFormat(const QString& contentFormat)
{ {
@@ -357,7 +372,7 @@ void XQItem::setContentFormat(const QString& contentFormat)
} }
//! gibt das read-only auswahl-model zurück (wenn dieses item als //! Gibt das read-only auswahl-model zurück (wenn dieses item als
//! combobox gerendert wird). wird im itemType gespeichert. //! combobox gerendert wird). wird im itemType gespeichert.
QStandardItemModel* XQItem::fixedChoices() const QStandardItemModel* XQItem::fixedChoices() const
@@ -413,6 +428,30 @@ QString XQItem::dataRoleName(int role) const
return XQItem::fetchItemDataRoleName(role); return XQItem::fetchItemDataRoleName(role);
} }
bool XQItem::hasContentPtr() const
{
return !QStandardItem::data( XQItem::ContentRole ).isNull();
}
//! Gibt den content()-String zurück, sofern vorhanden.
//! sonst: gibt der ihnalt der Qt::DisplayRole als fallback
//! zurück.
QString XQItem::contentFallBackText() const
{
if( hasContentPtr() )
{
const QString* contentPtr = QStandardItem::data( XQItem::ContentRole ).value<const QString*>();
if(contentPtr)
return *contentPtr;
}
// wenn wir keinen contentPtr haben, benutzen wir als fallback
// die basis-text() role
return QStandardItem::data( Qt::DisplayRole ).toString();
}
//! angespasste variante von qstandarditem::setData. geteilte attribute //! angespasste variante von qstandarditem::setData. geteilte attribute
//! werden vom xqitemtype geholt //! werden vom xqitemtype geholt
@@ -438,33 +477,35 @@ QVariant XQItem::data(int role ) const
return itemType().data(role); return itemType().data(role);
} }
// Zugriffe auf den sichtbaren inhalt geben den inhalt des string pointer case XQItem::ContentRole:
// auf ein feld in content node wieder.
// 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(); qDebug() << " --- data(XQItem::ContentRole) should NOT be called!";
return itemType().formatText( *this ); return *QStandardItem::data( XQItem::ContentRole ).value<QString*>();
[[fallthrough]];
} }
// EditRole & ContentRole sollen den 'rohen' inhalt unseres string-pointers // EditRole & ContentRole sollen den 'rohen' inhalt unseres string-pointers
// auf den original inhalt im content node zurückgeben. // auf den original inhalt im content node zurückgeben.
case Qt::EditRole : case Qt::EditRole :
case XQItem::ContentRole:
{ {
// Zugriffe auf den text-inhalt geben den inhalt des string pointer
// auf ein feld in content-node wieder. Wenn kein content-node vorhanden
// ist (single-items), wird Qt::DisplayRole zurückgeliefert.
const QString* contentPtr = QStandardItem::data( XQItem::ContentRole ).value<const QString*>(); return contentFallBackText();
if(contentPtr) //[[fallthrough]];
return *contentPtr; }
static const QString s_dummyContent("-"); // DisplayRole gibt den formatierten inhalt wieder. die formatierung übernimmt
return s_dummyContent; // der item type
case Qt::DisplayRole :
{
QString plainText = contentFallBackText();
//if( renderStyle() == XQItem::FormattedStyle)
if( unitType() != XQItem::NoUnitType)
return XQItemType::formatToSI( plainText, unitType() );
return plainText;
} }
case Qt::ToolTipRole: case Qt::ToolTipRole:
@@ -479,16 +520,30 @@ QVariant XQItem::data(int role ) const
case ContentNodeRole: case ContentNodeRole:
{ {
// Das Node-Besitzer-Item wohnt in der ersten Spalte, // Das Node-Besitzer-Item wohnt in der ersten Spalte,
// wenn wir also der Node-Besitzer item sind ... // wenn wir also der Node-Besitzer item sind ...
if( column() == 0) if( column() == 0)
return QStandardItem::data( XQItem::ContentNodeRole ); {
QVariant value = QStandardItem::data( XQItem::ContentNodeRole );
if( !value.isNull() )
return value;
// sonst: delegieren an den node-Besitzer // das gibt immerhin was zurück, was auf nullptr getestet werden kann,
QModelIndex pIndex = model()->index( row(), 0 ); return QVariant::fromValue<XQNodePtr>(nullptr);
// diese variante erzieht uns zur verwendung von 'hasContentNode()'
// was ist besser ?
throw XQException( "ContentNode is nullptr!");
}
// sonst: delegieren an den node-Besitzer
QModelIndex pIndex = model()->index( row(), 0 );
if( pIndex.isValid())
{
XQItem& firstItem = xqItemFromIndex( pIndex ); XQItem& firstItem = xqItemFromIndex( pIndex );
return firstItem.data( XQItem::ContentNodeRole ); return firstItem.data( XQItem::ContentNodeRole );
}
throw XQException( "Item has no valid index (yet)!");
} }
case Qt::StatusTipRole: case Qt::StatusTipRole:
@@ -537,7 +592,6 @@ void XQItem::setData(const QVariant& value, int role )
{ {
switch(role) switch(role)
{ {
case RenderStyleRole : case RenderStyleRole :
case EditorTypeRole : case EditorTypeRole :
case UnitTypeRole: case UnitTypeRole:
@@ -557,30 +611,33 @@ void XQItem::setData(const QVariant& value, int role )
return; return;
} }
// set the raw, unformatted data case Qt::DisplayRole:
case ContentRole: case Qt::EditRole:
case XQItem::ContentRole:
{ {
// string ptr setzen kann die basis. QVariant newValue;
break;
}
case Qt::EditRole : //if( itemType().renderStyle() == XQItem::FormattedStyle)
{ if( unitType() != XQItem::NoUnitType)
qDebug() << " --- setting EDITrole: " << value.toString(); newValue = XQItemType::unFormatFromSI( value.toString() );
break; else
} newValue = value;
case Qt::DisplayRole : // fallback: wenns keinen content node gibt, dann nehmen wir
{ // das standardverfahren.
// what will happen? value is a string ptr ?! if( !hasContentPtr() )
qDebug() << " --- setting DISPLAYrole: " << value.toString(); return QStandardItem::setData( newValue, Qt::DisplayRole );
break;
// wir nehmen den string pointer
const QString* constContentPtr = QStandardItem::data( XQItem::ContentRole ).value<const QString*>();
// aua, aua, muss aber sein, weil sonst alle anderen consts nicht durchgehalten werden könnten
*const_cast<QString*>(constContentPtr) = newValue.toString();
return;
} }
// alles andere wie gehabt // alles andere wie gehabt
case ContentNodeRole: case ContentNodeRole:
case SheetNodeRole: case SheetNodeRole:
//case TypeKeyRole: not used //case TypeKeyRole: not used
default: default:
break; break;
@@ -591,6 +648,133 @@ void XQItem::setData(const QVariant& value, int role )
} }
//! erzeugt eine QVariant zur gegebenen rolle aus dem gegebenen string.
//! Hack: Das Item wird hier als zusätzliche datenquelle übergeben,
//! um _vorher_ erzeugte eigenschaften des items als parameter für _jetzt_
//! erzeugte eigenschaft verwenden zu können.
//! Beispiel
QVariant XQItem::makeVariant( XQItem* item, int dataRole, const QString& source )
{
QVariant value;
//qDebug() << " ----- makeVariant: " << XQItem::fetchItemDataRoleName( dataRole );
switch(dataRole)
{
// das ist ein pointer auf den original-string aus dem XML
case XQItem::ContentRole:
{
// content() -> QString*
value = QVariant::fromValue(&source);
break;
}
/*
case XQItem::ItemTypeRole:
{
// itemType() -> XQItemType*
XQItemType* itemType = findItemTypeTemplate( source );
value = QVariant::fromValue(itemType);
break;
}
*/
case XQItem::RenderStyleRole:
{
XQItem::RenderStyle renderStyle = XQItem::fetchRenderStyle( source );
value = QVariant::fromValue(renderStyle);
break;
}
case XQItem::EditorTypeRole:
{
XQItem::EditorType editorType = XQItem::fetchEditorType( source );
value = QVariant::fromValue(editorType);
break;
}
case XQItem::UnitTypeRole:
{
//qDebug() << " --- make unit type: " << source;
XQItem::UnitType unitType = XQItem::fetchUnitType( source );
value = QVariant::fromValue(unitType);
break;
}
case XQItem::ContentFormatRole:
{
// contentFormat() -> QString
value = QVariant::fromValue(source);
break;
}
case XQItem::FlagsRole:
{
QFlags itemFlags = Qt::NoItemFlags;
const QStringList flagKeys = source.split( '|' );
for( const QString& flagKey : flagKeys )
{
Qt::ItemFlag flag = XQItem::fetchItemFlag( flagKey );
itemFlags.setFlag( flag );
}
value = QVariant::fromValue(itemFlags);
break;
}
case XQItem::IconRole:
{
QIcon typeIcon = XQAppData::typeIcon(source);
value = QVariant::fromValue(typeIcon);
break;
}
case XQItem::FixedChoicesRole:
{
const QStringList choices = source.split( '|' );
QStandardItemModel* fixedChoices = new QStandardItemModel();
for( const QString& entry : choices )
{
QString result = entry;
if( item->unitType() != XQItem::NoUnitType )
result = XQItemType::formatToSI( entry, item->unitType() );
fixedChoices->appendRow( new QStandardItem( result ) );
}
value = QVariant::fromValue(fixedChoices);
break;
}
/*
case XQItem::ContentNodeRole:
{
value = QVariant::fromValue(&source);
break;
}
case XQItem::XQItem::SheetNodeRole:
{
value = QVariant::fromValue(&source);
break;
}
*/
default:
case XQItem::XQItem::NoRole:
{
break;
}
};
//if( !value.toString().isEmpty())
// setData( value, dataRole);
return value;
}
//! gibt ein statisches invalid-item zurück, anstelle von nullptr //! gibt ein statisches invalid-item zurück, anstelle von nullptr
@@ -694,13 +878,10 @@ XQItem::UnitType XQItem::fetchUnitType(const QString& unitTypeKey)
return s_UnitTypeMap.key(unitTypeKey); return s_UnitTypeMap.key(unitTypeKey);
} }
//! gibt die bezeichung für den gegebenen unitType aus. //! gibt die bezeichung für den gegebenen unitType aus.
QString XQItem::fetchUnitTypeToString( UnitType unitType) QString XQItem::fetchUnitTypeToString( UnitType unitType)
{ {
return s_UnitTypeMap[unitType]; return s_UnitTypeMap[unitType];
} }
/// ---
/// ---
/// ---

View File

@@ -15,6 +15,7 @@
#ifndef XQITEM_H #ifndef XQITEM_H
#define XQITEM_H #define XQITEM_H
#include <QtQmlIntegration>
#include <QVariant> #include <QVariant>
#include <QVector> #include <QVector>
#include <QStandardItem> #include <QStandardItem>
@@ -35,6 +36,8 @@ class XQItemType;
class XQItem : public QStandardItem class XQItem : public QStandardItem
{ {
QML_ELEMENT
friend class XQItemFactory; friend class XQItemFactory;
public: public:
@@ -81,7 +84,7 @@ public:
ComboBoxStyle, ComboBoxStyle,
PickerStyle, PickerStyle,
SpinBoxStyle, SpinBoxStyle,
ProgressBarStyle, ColorBarStyle,
FormattedStyle, FormattedStyle,
TreeHeaderStyle, TreeHeaderStyle,
CustomRenderStyle, CustomRenderStyle,
@@ -96,7 +99,7 @@ public:
LineEditType, LineEditType,
ComboBoxType, ComboBoxType,
PickerType, PickerType,
ProgressBarType, ColorBarType,
SpinBoxType, SpinBoxType,
CustomEditorType, CustomEditorType,
EditorTypeEnd EditorTypeEnd
@@ -130,6 +133,7 @@ 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 );
virtual ~XQItem() = default; virtual ~XQItem() = default;
@@ -137,14 +141,16 @@ public:
//! -- not used at the moment -- //! -- not used at the moment --
XQItem* clone() const override; XQItem* clone() const override;
//! //! __fix Tested, ob ein itemtype vorhanden ist.
bool isValid() const; bool isValidX() const;
//! gibt den zu diesem item gehörigen datenknoten zurück bool hasContentNode() const;
virtual XQNodePtr contentNode() const; //! gibt den zu diesem item gehörigen datenknoten zurück
XQNodePtr contentNode() const;
virtual XQNodePtr sheetNode() const;
virtual void setSheetNode( const XQNodePtr& sheetNode ); XQNodePtr sheetNode() const;
void setSheetNode( const XQNodePtr& sheetNode );
XQItemType& itemType() const; XQItemType& itemType() const;
void setItemType( XQItemType* itemTypePtr ); void setItemType( XQItemType* itemTypePtr );
@@ -159,9 +165,8 @@ public:
QString rawText() const; QString rawText() const;
// changed: gibt jetzt den pointer zurück. // changed: gibt jetzt den pointer zurück.
QString* content() const; //QString* content() const;
QString contentKey() const; //void setContent( const QString* content );
void setContent( const QString* content );
// //
// Convenience-Funktionen zum Memberzugriff, die Implementierung // Convenience-Funktionen zum Memberzugriff, die Implementierung
@@ -219,6 +224,8 @@ public:
/// Static convenience methods /// Static convenience methods
/// ///
static QVariant makeVariant( XQItem* item, int dataRole, const QString& source );
static XQItem& xqItemFromIndex( const QModelIndex& index ); static XQItem& xqItemFromIndex( const QModelIndex& index );
static XQItem& fallBackDummyItem(); static XQItem& fallBackDummyItem();
@@ -238,6 +245,10 @@ protected:
XQItem(const XQItem& other) = default; XQItem(const XQItem& other) = default;
XQItem& operator=(const XQItem& other) = default; XQItem& operator=(const XQItem& other) = default;
bool hasContentPtr() const;
QString contentFallBackText() const;
// das ist protected, weil damit der content()-zugriff demoliert werden kann
void setContentNode(const XQNodePtr& contentNode ); void setContentNode(const XQNodePtr& contentNode );
using XQItemFlagMap = QMap<QString,int>; using XQItemFlagMap = QMap<QString,int>;
@@ -259,9 +270,7 @@ protected:
}; };
Q_DECLARE_METATYPE(XQItem);
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);

View File

@@ -17,6 +17,7 @@
#include <QComboBox> #include <QComboBox>
#include <QDoubleSpinBox> #include <QDoubleSpinBox>
#include <QProgressBar> #include <QProgressBar>
#include <QSlider>
#include <QPainter> #include <QPainter>
#include <QHeaderView> #include <QHeaderView>
@@ -28,153 +29,167 @@
#include <xqviewmodel.h> #include <xqviewmodel.h>
//! erzeugt eine editorfactory mit den hauseigenen editortypen.
class XQItemEditorFactory : public QItemEditorFactory class XQItemEditorFactory : public QItemEditorFactory
{ {
public: public:
XQItemEditorFactory() XQItemEditorFactory()
{ {
registerEditor(XQItem::LineEditType, new QStandardItemEditorCreator<QLineEdit>()); registerEditor(XQItem::LineEditType, new QStandardItemEditorCreator<QLineEdit>());
registerEditor(XQItem::ComboBoxType, new QStandardItemEditorCreator<QLineEdit>()); registerEditor(XQItem::ComboBoxType, new QStandardItemEditorCreator<QComboBox>());
registerEditor(XQItem::PickerType, new QStandardItemEditorCreator<QLineEdit>()); registerEditor(XQItem::PickerType, new QStandardItemEditorCreator<QLineEdit>());
registerEditor(XQItem::ProgressBarType, new QStandardItemEditorCreator<QLineEdit>()); //registerEditor(XQItem::ColorBarType, new QStandardItemEditorCreator<QProgressBar>());
registerEditor(XQItem::SpinBoxType, new QStandardItemEditorCreator<QLineEdit>()); registerEditor(XQItem::ColorBarType, new QStandardItemEditorCreator<QSlider>());
registerEditor(XQItem::SpinBoxType, new QStandardItemEditorCreator<QSpinBox>());
registerEditor(XQItem::CustomEditorType, new QStandardItemEditorCreator<QLineEdit>()); registerEditor(XQItem::CustomEditorType, new QStandardItemEditorCreator<QLineEdit>());
/*
registerEditor(XQItem::LineEditStyle, new QStandardItemEditorCreator<QLineEdit>());
registerEditor(XQItemType::ComboBoxStyle, new QStandardItemEditorCreator<QComboBox>());
//registerEditor(XQItemType::ProgressBarStyle, new QStandardItemEditorCreator<QProgressBar>());
registerEditor(XQItemType::SpinBoxStyle, new QStandardItemEditorCreator<QSpinBox>());
*/
/*
registerEditor(XQItem::etDoubleSpinType, new QStandardItemEditorCreator<QDoubleSpinBox>());
registerEditor(XQItemItemTypes::etDoubleSpinType, new QStandardItemEditorCreator<QDoubleSpinBox>());
registerEditor(XQItemItemTypes::etIPAddressType, new QStandardItemEditorCreator<NTIpAddressEdit>());
registerEditor(XQItemItemTypes::etLineEditBrowser, new QStandardItemEditorCreator<NTFileSelectLine>());
*/
} }
}; };
//! kontruktor mit dem zusändigen viewModel
XQItemDelegate::XQItemDelegate( XQViewModel& modelView) XQItemDelegate::XQItemDelegate( XQViewModel& viewModel)
: _modelView{modelView} : QStyledItemDelegate(), _modelView{viewModel}
{ {
static XQItemEditorFactory s_EditorFactory; static XQItemEditorFactory s_EditorFactory;
setItemEditorFactory(&s_EditorFactory); setItemEditorFactory(&s_EditorFactory);
} }
//! gibt die interne tree table zurück
XQTreeTable* XQItemDelegate::treeTable() const XQTreeTable* XQItemDelegate::treeTable() const
{ {
return _modelView.treeTable(); return _modelView.treeTable();
} }
//! shortcut: gibt das XQItem für den gegebenen index zurück.
XQItem& XQItemDelegate::xqItemFromIndex( const QModelIndex& index ) const XQItem& XQItemDelegate::xqItemFromIndex( const QModelIndex& index ) const
{ {
return _modelView.xqItemFromIndex( index ); return _modelView.xqItemFromIndex( index );
} }
//! überladene paint-methode: zeichnet das item je nach render-style.
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() )
qDebug() << " index DEAD!";
XQItem& item = xqItemFromIndex( index );
if( item.isValid() )
{ {
XQItem& item = xqItemFromIndex( index );
switch( item.renderStyle() ) switch( item.renderStyle() )
{ {
case XQItem::HeaderStyle : case XQItem::HeaderStyle :
return drawHeaderStyle( painter, option, index ); return drawHeaderStyle( painter, option, item );
//return drawHeaderStyleX( painter, option, index );
case XQItem::ComboBoxStyle : case XQItem::ComboBoxStyle :
return drawComboBoxStyle( painter, option, index ); return drawComboBoxStyle( painter, option, item );
case XQItem::ColorBarStyle :
return drawColorBarStyle( painter, option, item );
// das funktioniert nicht unter windows11
//case XQItem::SpinBoxStyle :
// return drawSpinBoxStyle( painter, option, item );
case XQItem::HiddenStyle : case XQItem::HiddenStyle :
return; return;
//case XQItem::ProgressBarStyle :
// return drawProgressBarStyle( painter, option, index );
default: default:
break; break;
} // switch } // switch
} }
else
{
qDebug() << " ---- paint: INDEX DEAD!" ;
}
QStyledItemDelegate::paint(painter, option, index); QStyledItemDelegate::paint(painter, option, index);
} }
//! einen section header im header-style zeichnen //! 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 XQItem& item) const
{ {
QStyleOptionHeader headerOption; QStyleOptionHeader headerOption;
XQItem& item = xqItemFromIndex( index );
// use the header as "parent" for style init // use the header as "parent" for style init
QWidget* srcWidget = treeTable();//->header(); QWidget* srcWidget = treeTable();//->header();
headerOption.initFrom(srcWidget); headerOption.initFrom(srcWidget);
headerOption.text = index.data(Qt::DisplayRole).toString(); headerOption.text = item.text();//index.data(Qt::DisplayRole).toString();
headerOption.rect = option.rect.adjusted(0,0,0,3); headerOption.rect = option.rect;//.adjusted(0,0,0,3);
headerOption.styleObject = option.styleObject; headerOption.styleObject = option.styleObject;
// __ch: reduce inner offset when painting // __ch: reduce inner offset when painting
headerOption.textAlignment |= Qt::AlignVCenter; headerOption.textAlignment |= Qt::AlignVCenter;
headerOption.icon = item.icon(); headerOption.icon = item.icon();
if (srcWidget != nullptr) // save painter
{ painter->save();
// save painter //value = index.data(Qt::ForegroundRole);
painter->save(); //if (value.canConvert<QBrush>())
//value = index.data(Qt::ForegroundRole); //headerOption.palette.setBrush(QPalette::Text, Qt::red );
//if (value.canConvert<QBrush>()) //headerOption.palette.setBrush(QPalette::Window, Qt::red );
//headerOption.palette.setBrush(QPalette::Text, Qt::red ); //QCommonStyle itemStyle;
//headerOption.palette.setBrush(QPalette::Window, Qt::red );
QCommonStyle itemStyle;
//headerOption.backgroundBrush()
//srcWidget->style()->drawControl(QStyle::CE_Header, &headerOption, painter, srcWidget);
itemStyle.drawControl(QStyle::CE_Header, &headerOption, painter, srcWidget);
// restore painter
painter->restore();
}
}
void XQItemDelegate::drawProgressBarStyle(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const //qApp->style()->drawControl(QStyle::CE_Header, &headerOption, painter, srcWidget);
{ //srcWidget->style()->drawControl(QStyle::CE_Header, &headerOption, painter, srcWidget);
// warum das nur mit dem commonstyle, ist mir echt unklar.
_commonStyle.drawControl(QStyle::CE_Header, &headerOption, painter, srcWidget);
// restore painter
painter->restore();
int progress = index.data(XQItem::ContentRole ).toInt();
QStyleOptionProgressBar progressBarOption;
progressBarOption.rect = option.rect;
progressBarOption.minimum = 0;
progressBarOption.maximum = 100;
progressBarOption.progress = progress;
progressBarOption.text = QString::number(progress) + "%";
progressBarOption.textAlignment = Qt::AlignCenter;
progressBarOption.textVisible = true;
QApplication::style()->drawControl(QStyle::CE_ProgressBar,&progressBarOption, painter);
} }
void XQItemDelegate::drawComboBoxStyle(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
//! Zeichnet prozent-werte als balken
void XQItemDelegate::drawColorBarStyle(QPainter* painter, const QStyleOptionViewItem& option, const XQItem& item) const
{ {
//QStyledItemDelegate::paint(painter, option, item);
// Wert aus dem Modell holen
bool ok;
int value = item.data(Qt::EditRole).toInt(&ok);
if (!ok || value < 0 || value > 100)
return;
// Balkenbereich berechnen
QRect rect = option.rect.adjusted(2, 2, -2, -2); // etwas Padding
int barWidth = static_cast<int>(rect.width() * (value / 100.0));
// Balken zeichnen
painter->save();
painter->setRenderHint(QPainter::Antialiasing);
QRect barRect(rect.left(), rect.top(), barWidth, rect.height());
QColor barColor = QColor(100, 180, 255);
painter->setBrush(barColor);
painter->setPen(Qt::NoPen);
painter->drawRect(barRect);
painter->setPen(Qt::black);
painter->drawText(rect, Qt::AlignCenter, item.text() );
painter->restore();
}
//! Zeichnet das Item als combo box.
void XQItemDelegate::drawComboBoxStyle(QPainter* painter, const QStyleOptionViewItem& option, const XQItem& item) const
{
QStyleOptionComboBox comboOption;
QWidget* srcWidget = qobject_cast<QWidget*>(option.styleObject); QWidget* srcWidget = qobject_cast<QWidget*>(option.styleObject);
QStyleOptionComboBox comboOption;
QStyle* comboStyle = srcWidget->style();
comboOption.initFrom(srcWidget); comboOption.initFrom(srcWidget);
// set options // set options
@@ -182,68 +197,102 @@ void XQItemDelegate::drawComboBoxStyle(QPainter *painter, const QStyleOptionView
comboOption.state = option.state | QStyle::State_Selected | QStyle::State_Enabled; comboOption.state = option.state | QStyle::State_Selected | QStyle::State_Enabled;
// not editable => only visual, but painter needs to know it // not editable => only visual, but painter needs to know it
comboOption.editable = false; comboOption.editable = false;
comboOption.currentText = index.data(Qt::DisplayRole).toString(); comboOption.currentText = item.text();
// decoration (if any) // decoration (if any)
comboOption.currentIcon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole)); comboOption.currentIcon = qvariant_cast<QIcon>(item.data(Qt::DecorationRole));
comboOption.iconSize = comboOption.currentIcon.actualSize(QSize(option.rect.height() - 3, option.rect.height() - 3)); comboOption.iconSize = comboOption.currentIcon.actualSize(QSize(option.rect.height() - 3, option.rect.height() - 3));
// save painter // save painter
painter->save(); painter->save();
// hier wiederum funktioniert der '_commonStyle' nicht
QStyle* widgetStyle = srcWidget->style();
// draw combo // draw combo
comboStyle->drawComplexControl(QStyle::CC_ComboBox, &comboOption, painter, srcWidget); widgetStyle->drawComplexControl(QStyle::CC_ComboBox, &comboOption, painter, srcWidget);
// and combobox label // and combobox label
comboStyle->drawControl(QStyle::CE_ComboBoxLabel, &comboOption, painter, srcWidget); widgetStyle->drawControl(QStyle::CE_ComboBoxLabel, &comboOption, painter, srcWidget);
// restore painter // restore painter
painter->restore(); painter->restore();
} }
void XQItemDelegate::drawSpinBoxStyle(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
//! Zeichnet das Item als spin box.
void XQItemDelegate::drawSpinBoxStyle(QPainter* painter, const QStyleOptionViewItem& option, const XQItem& item) const
{ {
// xx_fix! qDebug() << " --- jawas +++? SPINBOX!";
//int value = index.data(XQItem::ContentRole ).toInt();
QStyleOptionSpinBox spinBoxOption; QWidget* srcWidget = qobject_cast<QWidget*>(option.styleObject);
spinBoxOption.rect = option.rect; QStyleOptionViewItem viewOption(option);
/* QStyleOptionSpinBox spinBoxOption;
spinBoxOption.text = QString::number(value); spinBoxOption.initFrom(srcWidget);
spinBoxOption.textAlignment = Qt::AlignCenter;
spinBoxOption.textVisible = true; initStyleOption(&viewOption, item.index());
*/ if (option.state & QStyle::State_HasFocus)
{
viewOption.state = viewOption.state ^ QStyle::State_HasFocus; // Fokus nicht auf dem Hintergrund malen
}
QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &viewOption, painter);
spinBoxOption.rect = option.rect;//.adjusted( 0,0,-40,0);
spinBoxOption.state = option.state | QStyle::State_Sunken; // Sunken-State für den "LineEdit"-Look
spinBoxOption.buttonSymbols = QAbstractSpinBox::UpDownArrows;
spinBoxOption.stepEnabled = QAbstractSpinBox::StepUpEnabled | QAbstractSpinBox::StepDownEnabled;
spinBoxOption.frame = true;
_commonStyle.drawComplexControl(QStyle::CC_SpinBox, &spinBoxOption, painter, nullptr);
QRect editRect =_commonStyle.subControlRect(QStyle::CC_SpinBox, &spinBoxOption, QStyle::SC_SpinBoxEditField, nullptr);
painter->drawText(spinBoxOption.rect, Qt::AlignCenter, item.text());
QApplication::style()->drawComplexControl(QStyle::CC_SpinBox,&spinBoxOption, painter);
} }
QSize XQItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const //! Überschreibt QStyledItemDelegate::sizeHint(option, index);
QSize XQItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{ {
return QStyledItemDelegate::sizeHint(option, index); return QStyledItemDelegate::sizeHint(option, index);
} }
//! Erzeugt ein editor-widget, sofern ein gültiger content-Ptr vorhanden und ein editor-Type gesetzt ist.
QWidget* XQItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const QWidget* XQItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{ {
Q_UNUSED(option);
return QStyledItemDelegate::createEditor( parent, option, index ); XQItem& item = xqItemFromIndex(index);
XQItem::EditorType edType = item.editorType();
int editorType = XQItem::xqItemFromIndex(index).editorType(); if( edType == XQItem::NoEditorType )
QWidget* editor = itemEditorFactory()->createEditor(editorType, parent);
if( editor )
{ {
return editor; qDebug() << "---- NO Content or NO EditorType";
return nullptr;
} }
qDebug() << "---- ed type:" << XQItem::fetchEditorTypeToString( edType ) << ": " << edType;
QWidget* editor = itemEditorFactory()->createEditor(edType, parent);;
//return QStyledItemDelegate::createEditor( parent, option, index );
return editor;
} }
//! Füttert einen editor mit den model-daten
void XQItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const void XQItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{ {
XQItem& item = xqItemFromIndex( index ); XQItem& item = xqItemFromIndex( index );
switch( item.editorType() ) XQItem::EditorType edType = item.editorType();
if( edType == XQItem::NoEditorType )
return;
switch( edType )
{ {
case XQItemType::ComboBoxType : case XQItemType::ComboBoxType :
{ {
QComboBox* comboBox = qobject_cast<QComboBox*>(editor); QComboBox* comboBox = qobject_cast<QComboBox*>(editor);
// wir erwarten hier ein gültiges model?
comboBox->setModel( item.fixedChoices()); comboBox->setModel( item.fixedChoices());
comboBox->setCurrentText( item.data().toString() ); comboBox->setCurrentText( item.data().toString() );
comboBox->showPopup(); comboBox->showPopup();
@@ -251,24 +300,37 @@ void XQItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) co
} }
default: default:
break;
// wir benutzen hier die DisplayRole wenn der Inhalt schon formatiert ist.
int role = item.renderStyle() == XQItem::FormattedStyle ? Qt::DisplayRole : Qt::EditRole;
QVariant value = index.data(role);
QByteArray userProp = editor->metaObject()->userProperty().name();
if (!userProp.isEmpty())
{
if (!value.isValid())
value = QVariant(editor->property(userProp).metaType());
editor->setProperty(userProp, value);
}
} }
QStyledItemDelegate::setEditorData(editor, index);
} }
void XQItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
//! Schreibt die daten aus dem editor ins model zurück
void XQItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{ {
XQItem& item = xqItemFromIndex( index ); XQItem& item = xqItemFromIndex( index );
switch( item.editorType() ) switch( item.editorType() )
{ {
case XQItem::ComboBoxType : case XQItem::ComboBoxType :
{ {
QComboBox* comboBox = qobject_cast<QComboBox*>(editor); QComboBox* comboBox = qobject_cast<QComboBox*>(editor);
item.setData( comboBox->currentText(), Qt::DisplayRole );
return; return;
} }
@@ -280,8 +342,12 @@ void XQItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, co
QStyledItemDelegate::setModelData(editor, model, index); QStyledItemDelegate::setModelData(editor, model, index);
} }
//! Überschreibt QItemDelegate::updateEditorGeometry. Nicht implementiert.
void XQItemDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const void XQItemDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const
{ {
//qDebug() << " --- update Editor Geometry"; //qDebug() << " --- update Editor Geometry";
QStyledItemDelegate::updateEditorGeometry(editor, option, index); QStyledItemDelegate::updateEditorGeometry(editor, option, index);
} }

View File

@@ -16,6 +16,7 @@
#define XQITEMDELEGATE_H #define XQITEMDELEGATE_H
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
#include <QCommonStyle>
#include <xqappdata.h> #include <xqappdata.h>
class XQItem; class XQItem;
@@ -32,26 +33,27 @@ class XQItemDelegate : public QStyledItemDelegate
public: public:
explicit XQItemDelegate(XQViewModel& modelView); explicit XQItemDelegate(XQViewModel& viewModel);
XQTreeTable* treeTable() const; XQTreeTable* treeTable() const;
XQItem& xqItemFromIndex( const QModelIndex& index ) const; XQItem& xqItemFromIndex( const QModelIndex& index ) const;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override;
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override; void setEditorData(QWidget* editor, const QModelIndex& index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; void setModelData(QWidget* editor, QAbstractItemModel *model, const QModelIndex& index) const override;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
protected: protected:
void drawHeaderStyle(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawHeaderStyle(QPainter* painter, const QStyleOptionViewItem& option, const XQItem& item ) const;
void drawProgressBarStyle(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawColorBarStyle(QPainter* painter, const QStyleOptionViewItem& option, const XQItem& item) const;
void drawComboBoxStyle(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawComboBoxStyle(QPainter* painter, const QStyleOptionViewItem& option, const XQItem& item) const;
void drawSpinBoxStyle(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawSpinBoxStyle(QPainter* painter, const QStyleOptionViewItem& option, const XQItem& item) const;
XQViewModel& _modelView; XQViewModel& _modelView;
QCommonStyle _commonStyle;
}; };

View File

@@ -29,7 +29,7 @@ void XQItemFactory::initItemFactory( const QString& modelSheetFileName )
for( const auto& [key,value] : sheetNode->attributes() ) for( const auto& [key,value] : sheetNode->attributes() )
{ {
//qDebug() << " --- conf item Type: " << key << " : " << value; //qDebug() << " --- conf item Type: " << key << " : " << value;
setItemDataFromString( *itemType, key, value ); setItemTypeDataFromString( *itemType, key, value );
} }
}; };
@@ -91,7 +91,7 @@ XQItemType* XQItemFactory::makeItemType(const XQNodePtr& sheetEntry )
// wenn ja, überschreiben // wenn ja, überschreiben
if( role != XQItem::NoRole ) if( role != XQItem::NoRole )
{ {
QVariant newValue = makeVariant(role, attrEntry.second ); QVariant newValue = XQItem::makeVariant( itemType, role, attrEntry.second );
itemType = itemType->replaceAttribute( newValue, role ); itemType = itemType->replaceAttribute( newValue, role );
} }
@@ -99,12 +99,13 @@ XQItemType* XQItemFactory::makeItemType(const XQNodePtr& sheetEntry )
return itemType; return itemType;
} }
//! sucht einen item typ aus der map mit 'vorgefertigen' itemtypen. //! sucht einen item typ aus der map mit 'vorgefertigen' itemtypen.
XQItemType* XQItemFactory::findItemTypeTemplate(const QString& key ) const XQItemType* XQItemFactory::findItemTypeTemplate(const QString& key ) const
{ {
if( !key.isEmpty() && s_ItemTypeTemplates.contains(key)) if( !key.isEmpty() && s_ItemTypeTemplates.contains(key))
return s_ItemTypeTemplates[key]; return s_ItemTypeTemplates[key];
throw XQException( "itemfactory: findItemTypeTemplate: not found:", key ); throw XQException( "itemfactory: findItemTypeTemplate: not found:", key );
} }
@@ -123,188 +124,21 @@ XQNodePtr XQItemFactory::findModelSheet( const QString& modelName ) const
//! erzeugt eine QVariant aus dem gegebenen string und setzt diese dann via role im item. //! erzeugt eine QVariant aus dem gegebenen string und setzt diese dann via role im item.
void XQItemFactory::setItemDataFromString( XQItem& item, const QString& roleKey, const QString& source ) const void XQItemFactory::setItemTypeDataFromString( XQItem& item, const QString& roleKey, const QString& source ) const
{ {
int dataRole = XQItem::fetchItemDataRole( roleKey ); int dataRole = XQItem::fetchItemDataRole( roleKey );
if( dataRole != XQItem::NoRole) if( dataRole != XQItem::NoRole)
{ {
QVariant variant = makeVariant( dataRole, source ); QVariant variant = XQItem::makeVariant( &item, dataRole, source );
if( !variant.isNull() && variant.isValid() ) if( !variant.isNull() && variant.isValid() )
item.setData( variant, dataRole ); item.setData( variant, dataRole );
} }
} }
//! erzeugt eine QVariant aus dem gegebenen string
QVariant XQItemFactory::makeVariant( int dataRole, const QString& source ) const
{
QVariant value;
switch(dataRole)
{
// das ist ein pointer auf den original-string aus dem XML
case XQItem::ContentRole:
{
// content() -> QString*
value = QVariant::fromValue(&source);
break;
}
case XQItem::ItemTypeRole:
{
// itemType() -> XQItemType*
//qDebug() << " --- makeVariant: make ItemType: " << source;
XQItemType* itemType = findItemTypeTemplate( source );
value = QVariant::fromValue(itemType);
break;
}
case XQItem::RenderStyleRole:
{
XQItem::RenderStyle renderStyle = XQItem::fetchRenderStyle( source );
value = QVariant::fromValue(renderStyle);
break;
}
case XQItem::EditorTypeRole:
{
XQItem::EditorType editorType = XQItem::fetchEditorType( source );
value = QVariant::fromValue(editorType);
break;
}
case XQItem::UnitTypeRole:
{
//qDebug() << " --- make unit type: " << source;
XQItem::UnitType unitType = XQItem::fetchUnitType( source );
value = QVariant::fromValue(unitType);
break;
}
case XQItem::ContentFormatRole:
{
// contentFormat() -> QString
value = QVariant::fromValue(source);
break;
}
case XQItem::FlagsRole:
{
QFlags itemFlags = Qt::NoItemFlags;
const QStringList flagKeys = source.split( '|' );
for( const QString& flagKey : flagKeys )
{
Qt::ItemFlag flag = XQItem::fetchItemFlag( flagKey );
itemFlags.setFlag( flag );
}
value = QVariant::fromValue(itemFlags);
break;
}
case XQItem::IconRole:
{
QIcon typeIcon = XQAppData::typeIcon(source);
value = QVariant::fromValue(typeIcon);
break;
}
case XQItem::FixedChoicesRole:
{
const QStringList choices = source.split( '|' );
QStandardItemModel* fixedChoices = new QStandardItemModel();
for( const QString& entry : choices )
fixedChoices->appendRow( new QStandardItem( entry ) );
value = QVariant::fromValue(fixedChoices);
break;
}
/*
case XQItem::ContentNodeRole:
{
value = QVariant::fromValue(&source);
break;
}
case XQItem::XQItem::SheetNodeRole:
{
value = QVariant::fromValue(&source);
break;
}
*/
default:
case XQItem::XQItem::NoRole:
{
break;
}
};
//if( !value.toString().isEmpty())
// setData( value, dataRole);
return value;
}
///
/// ------------------------------------------------
///
/*
XQItemList XQItemFactory::makeEmptyRow( const XQNodePtr& contentNode, const XQNodePtr& sheetNode )
{
Q_UNUSED(contentNode)
XQItemList list;
// create a data node for each sheet entry
size_t max = sheetNode->children().size();
for( size_t i=0; i<max; ++i )
{
// __fix
//list.append( new XQItem( "", XQItemType::EmptyStyle ) );
}
return list;
}
*/
/*
XQItemList XQItemFactory::createGenericRow( const XQNodePtr& contentNode, const XQNodePtr& sheetNode )
{
// we have a new empty contentNode, so we add attributes first.
for( const auto& sheetEntry : sheetNode->children() )
{
QString value = "[" + sheetEntry->tag_name() + "]";
if( sheetEntry->has_attribute("Unit") )
value = "0";
contentNode->set_attribute( sheetEntry->tag_name(), value );
}
if( sheetNode->has_attribute( c_FriendlyName ) )
contentNode->set_attribute( c_FriendlyName, sheetNode->friendly_name() );
// now, we can create a normal entry row
return makeContentRow(contentNode, sheetNode );
}
*/
//! erzeugt eine item-row. //! erzeugt eine item-row.
XQItemList XQItemFactory::makeRow(CreationMode mode, const XQNodePtr& sheetNode, const XQNodePtr& contentNode, const QString& captionKey ) XQItemList XQItemFactory::makeRow(const XQNodePtr& sheetNode, const XQNodePtr& contentNode )
{ {
XQItemList list; XQItemList list;
@@ -320,24 +154,31 @@ XQItemList XQItemFactory::makeRow(CreationMode mode, const XQNodePtr& sheetNode,
// //
for( const auto& sheetEntry : sheetNode->children() ) for( const auto& sheetEntry : sheetNode->children() )
list.append( makeItem( mode, sheetEntry, contentNode, captionKey ) ); list.append( makeItem( sheetEntry, contentNode ) );
Q_ASSERT(!list.empty()); Q_ASSERT(!list.empty());
// wir merken uns den original content node auch, aber // wir merken uns den original content node auch, aber
// im ersten Item. // im ersten Item. Kann null sein, macht aber erstmal nix.
dynamic_cast<XQItem*>(list[0])->setContentNode(contentNode); dynamic_cast<XQItem*>(list[0])->setContentNode(contentNode);
return list; return list;
} }
XQItemList XQItemFactory::makeChildRow( XQItem* parent, const XQNodePtr& sheetNode, const XQNodePtr& contentNode )
{
Q_UNUSED(parent);
Q_UNUSED(sheetNode);
Q_UNUSED(contentNode);
//! fixme! unsinn! return XQItemList();
//! 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(CreationMode mode, const XQNodePtr& sheetNode, const XQNodePtr& contentNode, const QString& captionKey ) //! 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
XQItem* XQItemFactory::makeItem(const XQNodePtr& sheetNode, const XQNodePtr& contentNode )
{ {
// den itemtype des neuen items rausfinden // den itemtype des neuen items rausfinden
XQItemType* itemType = makeItemType(sheetNode); // throws XQItemType* itemType = makeItemType(sheetNode); // throws
@@ -347,19 +188,10 @@ XQItem* XQItemFactory::makeItem(CreationMode mode, const XQNodePtr& sheetNode, c
// das ist Unterschied vom HeaderItem zum normalen Item: Der Titel kommt aus der Modelbeschreibung, // das ist Unterschied vom HeaderItem zum normalen Item: Der Titel kommt aus der Modelbeschreibung,
// sonst wird der content indirekt über den tag-name des sheetnode geholt // sonst wird der content indirekt über den tag-name des sheetnode geholt
switch( mode ) if( !contentNode )
{ contentPtr = sheetNode->attribute_ptr(c_Caption);
case mHeader: else
contentPtr = sheetNode->attribute_ptr(captionKey); contentPtr = contentNode->attribute_ptr( sheetNode->tag_name() );
break;
case mData:
contentPtr = contentNode->attribute_ptr( sheetNode->tag_name() );
break;
case mSingle:
contentPtr = contentNode->attribute_ptr( captionKey );
}
XQItem* newItem = new XQItem( itemType, contentPtr); XQItem* newItem = new XQItem( itemType, contentPtr);
@@ -371,3 +203,18 @@ XQItem* XQItemFactory::makeItem(CreationMode mode, const XQNodePtr& sheetNode, c
return newItem; return newItem;
} }
//! Erzeugt ein Item _ohne_ internen content node, sondern
XQItem* XQItemFactory::makeSingleItem( const XQNodePtr& sheetNode, const QString& caption )
{
// den itemtype des neuen items rausfinden
XQItemType* itemType = makeItemType(sheetNode); // throws
XQItem* newItem = new XQItem( itemType, caption);
// __fixme!
if( newItem->isCheckable() )
{
newItem->setCheckState( Qt::Checked );
}
return newItem;
}

View File

@@ -28,35 +28,25 @@ class XQItemFactory : public xsingleton<XQItemFactory>
public: public:
enum CreationMode
{
mHeader,
mData,
mSingle
};
void initItemFactory(const QString& modelSheetFileName ); void initItemFactory(const QString& modelSheetFileName );
XQNodePtr findModelSheet( const QString& modelName ) const; XQNodePtr findModelSheet( const QString& modelName ) const;
//XQItemList makeEmptyRow( const XQNodePtr& contentNode, const XQNodePtr& sheetNode ); XQItemList makeRow( const XQNodePtr& sheetNode, const XQNodePtr& contentNode );
XQItemList makeChildRow( XQItem* parent, const XQNodePtr& sheetNode, const XQNodePtr& contentNode );
XQItem* makeSingleItem( const XQNodePtr& sheetNode, const QString& caption );
XQItemList makeRow( CreationMode mode, const XQNodePtr& sheetNode, const XQNodePtr& contentNode, const QString& captionKey=c_Caption ); void setItemTypeDataFromString( XQItem& item, const QString& roleKey, const QString& source ) const;
// wozu ist das gut?
//XQItemList createGenericRow( const XQNodePtr& contentNode, const XQNodePtr& sheetNode );
void setItemDataFromString( XQItem& item, const QString& roleKey, const QString& source ) const;
XQItemType* makeItemType(const XQNodePtr& sheetEntry ); XQItemType* makeItemType(const XQNodePtr& sheetEntry );
XQItemType* findItemTypeTemplate(const QString& key ) const; XQItemType* findItemTypeTemplate(const QString& key ) const;
QVariant makeVariant(int dataRole, const QString &value ) const;
protected: protected:
bool isValid(); bool isValid();
XQItem* makeItem( CreationMode mode, const XQNodePtr& sheetNode, const XQNodePtr& contentNode, const QString& captionKey ); XQItem* makeItem(const XQNodePtr& sheetNode, const XQNodePtr& contentNode );
// 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 )>;

View File

@@ -113,6 +113,7 @@ XQItemType* XQItemType::replaceAttribute( const QVariant& newValue, int role )
// Gibt es den geänderten ItemType schon? // Gibt es den geänderten ItemType schon?
QString newKey = myClone->makeItemTypeKey(); QString newKey = myClone->makeItemTypeKey();
// jawoll // jawoll
if( s_ItemTypeMap.contains( newKey ) ) if( s_ItemTypeMap.contains( newKey ) )
{ {
// abräumen ... // abräumen ...
@@ -134,22 +135,9 @@ XQItemType* XQItemType::replaceAttribute( const QVariant& newValue, int role )
} }
//! formatiert den content() string eines items.
QVariant XQItemType::formatText( const XQItem& item ) const
{
XQItem::UnitType uType = unitType();
//qDebug() << " --- formatText: " << XQItem::fetchUnitTypeToString( uType);
const QString& cont = item.rawText();
if( uType != XQItem::NoUnitType )
return formatToSI( cont, uType );
return cont;
}
//! formatiert einen zahlenwert als string mit einheit. //! formatiert einen zahlenwert als string mit einheit.
QString XQItemType::formatToSI( const QString& valueTxt, XQItem::UnitType unitType ) const QString XQItemType::formatToSI( const QString& valueTxt, XQItem::UnitType unitType )
{ {
if( valueTxt.isEmpty() ) if( valueTxt.isEmpty() )
@@ -180,18 +168,18 @@ QString XQItemType::formatToSI( const QString& valueTxt, XQItem::UnitType unitTy
strVal = sysLocale.toString(nVal, 'f', 2); strVal = sysLocale.toString(nVal, 'f', 2);
strPrefix = s_PrefixExponentMap.key(exp); strPrefix = s_PrefixExponentMap.key(exp);
//qDebug() << " convert: " << dVal << " : " << valueTxt << ": " << strVal << ":" << exp << " : " << strPrefix << ": " << nVal; //qDebug() << " convert: " << dVal << " : " << valueTxt << ": " << strVal << ":" << exp << " : " << strPrefix << ": " << nVal;
QString unitStr = XQItem::fetchUnitTypeToString( unitType);
return QString("%1 %2%3").arg( strVal, strPrefix, unitTypeToString() ); return QString("%1 %2%3").arg( strVal, strPrefix, unitStr );
} }
//! entfernt die einheit aus einem formatierten string //! entfernt die einheit aus einem formatierten string
QString XQItemType::unFormatFromSI(const QString& formText ) const QString XQItemType::unFormatFromSI(const QString& formText )
{ {
QString input = formText.simplified(); const QString input = formText.simplified();
// #1: strip numeric part // #1: strip numeric part
if( input.isEmpty() ) if( input.isEmpty() )
return input; return input;

View File

@@ -40,17 +40,14 @@ public:
QVariant data( int role ) const override; QVariant data( int role ) const override;
void setData(const QVariant& value, int role ) override; void setData(const QVariant& value, int role ) override;
QVariant formatText( const XQItem& item ) const;
QString formatToSI(const QString& rawText, XQItem::UnitType unitType ) const;
QString unFormatFromSI(const QString& valueText ) const;
int roleForAttributeKey( const QString& attrKey ); int roleForAttributeKey( const QString& attrKey );
XQItemType* replaceAttribute(const QVariant& newValue, int role ); XQItemType* replaceAttribute(const QVariant& newValue, int role );
QString makeItemTypeKey(); QString makeItemTypeKey();
static XQItemType* staticItemType(); static XQItemType* staticItemType();
static QString formatToSI(const QString& rawText, XQItem::UnitType unitType );
static QString unFormatFromSI(const QString& valueText );
protected: protected:

View File

@@ -15,6 +15,14 @@
#include <QDebug> #include <QDebug>
#include <QApplication> #include <QApplication>
#include <QMetaType> #include <QMetaType>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QUrl>
#include <QQmlContext>
#include <QStyleFactory>
#include <xqchildmodel.h>
#include <xqquickwidget.h>
#include <xqmainwindow.h> #include <xqmainwindow.h>
@@ -49,25 +57,67 @@ who is who:
*/ */
XQChildModel* createChildModel()
{
XQChildModel* myModel = new XQChildModel();
myModel->initModel( c_ChildModelName );
XQNodeFactory treeLoader;
// xml daten laden
XQNodePtr rawTree = treeLoader.load_tree( qPrintable(c_DocumentFileName1) );
// versteckten root node ignorieren
XQNodePtr contentRoot = rawTree->first_child();
myModel->addModelData( contentRoot->first_child() );
return myModel;
}
using namespace Qt::Literals::StringLiterals;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication app(argc, argv); QApplication app(argc, argv);
//qDebug() << QStyleFactory::keys();
//QApplication::setStyle("fusion");
//QApplication::setStyle("windowsvista");
//QApplication::setStyle("windows");
/*
// 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");
XQMainWindow window; XQMainWindow window;
window.show(); window.show();
/*
QApplication app(argc, argv);
XQMainWindow::setupWorkingDir();
XQItemFactory::instance().initItemFactory( c_ModelSheetFileName );
XQChildModel* myModel = createChildModel();
qmlRegisterType< XQChildModel>("MyApp.Models", 1, 0, "MyChildModel");
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("myChildModel", myModel);
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() { QCoreApplication::exit(-1); },
Qt::QueuedConnection);
qDebug() << " fitz!";
engine.load( QUrl(QStringLiteral("qrc:/dummyview.qml")) );
//engine.load( QUrl(QStringLiteral("qrc:/xqtableview.qml")) );
qDebug() << " hhakl!";
*/
return app.exec(); return app.exec();
} }

View File

@@ -28,10 +28,10 @@ void XQNodeStore::dumpList( const QString& title ) const
} }
//! kostruktor. übergibt command-type und die aufrufende modelView. //! kostruktor. übergibt command-type und die aufrufende viewModel.
XQCommand::XQCommand(CmdType cmdType, XQViewModel* modelView ) XQCommand::XQCommand(CmdType cmdType, XQViewModel* viewModel )
: _cmdType{ cmdType }, _model(modelView) : _cmdType{ cmdType }, _viewModel(viewModel)
{ {
} }
@@ -66,7 +66,7 @@ void XQCommand::setCommandType( XQCommand::CmdType cmdType )
void XQCommand::redo() void XQCommand::redo()
{ {
_model->onCommandRedo( *this ); _viewModel->onCommandRedo( *this );
} }
@@ -74,7 +74,7 @@ void XQCommand::redo()
void XQCommand::undo() void XQCommand::undo()
{ {
_model->onCommandUndo( *this ); _viewModel->onCommandUndo( *this );
} }
@@ -108,20 +108,22 @@ void XQCommand::setOriginIndex( const QModelIndex& origin )
void XQCommand::saveNodes( const QModelIndexList& list ) void XQCommand::saveNodes( const QModelIndexList& list )
{ {
clear(); clear();
// über jede zeil // über jede zeile
for( auto entry : list ) for( auto entry : list )
{ {
// knoten holen // knoten holen
const XQNodePtr& contentNode = XQItem::xqItemFromIndex( entry ).contentNode(); const XQNodePtr& contentNode = XQItem::xqItemFromIndex( entry ).contentNode();
// hier speichern wir den original knoten, nicht einen clone, wie im clipboard. // hier speichern wir den original knoten, nicht einen clone, wie im clipboard.
push_back( {entry.row(), contentNode->own_pos(), contentNode } ); // obacht: bei einem Header is der content node null
if(contentNode)
push_back( {entry.row(), contentNode->own_pos(), contentNode } );
} }
} }
//! erzeugt einen string aus dem command-type, fürs debuggen. //! erzeugt einen string aus dem command-type, fürs debuggen.
QString XQCommand::toString() QString XQCommand::toString() const
{ {
static QMap<CmdType,QString> s_CmdTypeMap static QMap<CmdType,QString> s_CmdTypeMap

View File

@@ -66,7 +66,7 @@ public:
cmdExtern //?? cmdExtern //??
}; };
XQCommand(CmdType cmdType, XQViewModel* modelView ); XQCommand(CmdType cmdType, XQViewModel* viewModel );
virtual ~XQCommand(); virtual ~XQCommand();
CmdType commandType() const; CmdType commandType() const;
@@ -80,13 +80,13 @@ public:
void redo() override; void redo() override;
void undo() override; void undo() override;
QString toString(); QString toString() const;
protected: protected:
CmdType _cmdType{cmdInvalid}; CmdType _cmdType{cmdInvalid};
XQViewModel* _model{}; // needed for redo() / undo() XQViewModel* _viewModel{}; // needed for redo() / undo()
QModelIndex _originIndex; QModelIndex _originIndex;
/* /*

View File

@@ -1,206 +0,0 @@
/***************************************************************************
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 <xqmodelsectionlist.h>
//! kontstruktor. übergibt den start-index und einen model-knoten mit der beschreibung
//! der datenknoten.
XQModelSection::XQModelSection(const QModelIndex& modelIndex, XQNodePtr sheetNode)
: _modelIndex{ modelIndex }, _sectionRootNode{ sheetNode }
{
}
//! elementvergleich.
bool XQModelSection::operator==(const XQModelSection& other) const
{
return _modelIndex == other._modelIndex && _sectionRootNode == other._sectionRootNode;
}
//! true wenn der start-index valide und ein model-knoten vorhanden.
bool XQModelSection::isValid() const
{
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;
}
//! gibt die zeile des start-index zurück.
int XQModelSection::XQModelSection::row() const
{
return _modelIndex.row();
}
//! gibt den 'content type' zurück.
const QString& XQModelSection::contentType() const
{
return _sectionRootNode->attribute( c_ContentType );
}
//! gibt das dieser section entsprechende header-item zurück.
XQItem& XQModelSection::XQModelSection::headerItem() const
{
return XQItem::xqItemFromIndex( _modelIndex );
}
//! testet, ob die unter 'sectionKey' eine gültige section vorhanden ist.
bool XQModelSectionList::hasValidSection(const QString& sectionKey) const
{
if (!contains(sectionKey) )
return false;
return at(sectionKey).isValid();
}
//! gibt für einen model index die 'zuständige' section zurück.
const XQModelSection& XQModelSectionList::sectionFromIndex( const QModelIndex& index ) const
{
return sectionFromRow( index.row() );
}
//! gibt für eine zeile die 'zuständige' section zurück: der bestand an section wird
//! nach der passenden section durchsucht.
const XQModelSection& XQModelSectionList::sectionFromRow(int itemRow ) const
{
int i = size() - 1;
for (; i >= 0; --i)
{
if ( at(i).modelIndex().row() < itemRow )
return at(i);
}
static XQModelSection s_DummySection;
return s_DummySection;
}
//! ermittelt die erste zeile einer section.
int XQModelSectionList::firstRow(const QModelIndex& idx) const
{
return sectionFromRow(idx.row() ).row();
}
//! ermittelt die zeile unterhalb des gegebenen modelindex,
//! zum einfügen neuer items ebendort.
int XQModelSectionList::lastRow(const QModelIndex& idx) const
{
return lastRow(sectionFromRow(idx.row()));
}
//! ermittelt die zeile unterhalb der gegebenen section,
//! zum einfügen neuer items ebendort.
int XQModelSectionList::lastRow(const XQModelSection& section ) const
{
//qDebug() << " -- last row in section: " << section.modelIndex.data().toString() << " --> " << section.modelIndex.row();
// row() der section unterhalb dieser
// __fix? index mit speichern?
int index = indexOf(section);
if (index > -1)
{
// last section? return last row of model
if (index == size() - 1)
return section.modelIndex().model()->rowCount();// - 1;
// return row above the row of the next section -> last row of given section
return at(index+1).row();
}
return -1;
}
//! gibt alle sections aus, zum ankucken.
void XQModelSectionList::dump() const
{
qDebug() << " --- sections dump(): " <<size() << " entries.";
for( int i = 0; i<size(); ++i )
{
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();
}
}

View File

@@ -0,0 +1,207 @@
/***************************************************************************
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 <xqsectionmanager.h>
//! kontstruktor. übergibt den start-index und einen model-knoten mit der beschreibung
//! der datenknoten.
XQModelSection::XQModelSection(const QModelIndex& modelIndex, XQNodePtr sheetNode)
: _modelIndex{ modelIndex }, _sectionSheetRootNode{ sheetNode }
{
}
//! elementvergleich.
bool XQModelSection::operator==(const XQModelSection& other) const
{
return _modelIndex == other._modelIndex && _sectionSheetRootNode == other._sectionSheetRootNode;
}
//! true wenn der start-index valide und ein model-knoten vorhanden.
bool XQModelSection::isValid() const
{
return _modelIndex.isValid() && _sectionSheetRootNode;
}
QModelIndex XQModelSection::startIndex() const
{
return _modelIndex.operator QModelIndex();
}
XQNodePtr XQModelSection::sectionRootNode() const
{
return _sectionSheetRootNode;
}
//! 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 _sectionSheetRootNode->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 ) const
{
_contentRootNode = contentRootNode;
}
//! gibt die zeile des start-index zurück.
int XQModelSection::XQModelSection::firstRow() const
{
return _modelIndex.row();
}
//! gibt den 'content type' zurück.
const QString& XQModelSection::contentType() const
{
//qDebug() << " ---AUA & AUS!";
return _sectionSheetRootNode->attribute( c_ContentType );
}
//! gibt das dieser section entsprechende header-item zurück.
XQItem& XQModelSection::XQModelSection::headerItem() const
{
return XQItem::xqItemFromIndex( _modelIndex );
}
//! testet, ob die unter 'sectionKey' eine gültige section vorhanden ist.
bool XQSectionManager::hasValidSection(const QString& sectionKey) const
{
if (!_sections.contains(sectionKey) )
return false;
return _sections.at(sectionKey).isValid();
}
const XQModelSection& XQSectionManager::sectionByKey( const QString& sectionKey ) const
{
if( hasValidSection( sectionKey ) )
return _sections.at(sectionKey);
throw XQException( "No section for key: ", sectionKey);
}
//! gibt für eine zeile die 'zuständige' section zurück: der bestand an section wird
//! nach der passenden section durchsucht.
const XQModelSection& XQSectionManager::sectionByRow(int itemRow ) const
{
for (const auto& section : _sections)
{
qDebug() << " ---- SEC: " << itemRow << " -> " << section.firstRow() << " : " << lastRow( section );
XQSectionRange range = sectionRange(section);
if( itemRow >= range.firstRow && itemRow <= range.lastRow)
return section;
}
throw XQException( "No section for item row: ", QString::number(itemRow));
}
const XQModelSection& XQSectionManager::createSection(const QModelIndex& modelIndex, XQNodePtr sheetNode)
{
const QString& sectionKey = sheetNode->attribute(c_ContentType);
//qDebug() << " --- create Section: " << sectionKey << ": " << modelIndex.data().toString();
XQModelSection section(modelIndex, sheetNode );
_sections.addAtKey( sectionKey, section);
return sectionByKey(sectionKey);
}
//! ermittelt die zeile unterhalb des gegebenen modelindex,
//! zum einfügen neuer items ebendort.
int XQSectionManager::lastRow(const XQModelSection& section ) const
{
//qDebug() << " -- last row in section: " << section.startIndex().data().toString() << " --> " << section.startIndex().row();
// row() der section unterhalb dieser
// __fix? index mit speichern?
int index = _sections.indexOf(section);
if (index > -1)
{
// last section? return last row of model
if (index == _sections.size() - 1)
return section.startIndex().model()->rowCount() - 1;
// return row above the row of the next section -> last row of given section
return _sections.at(index+1).firstRow() - 1;
}
return -1;
}
XQSectionRange XQSectionManager::sectionRange(const XQModelSection& section ) const
{
return XQSectionRange{ section.startIndex().row(), lastRow(section) };
}
//! gibt alle sections aus, zum ankucken.
void XQSectionManager::dump() const
{
qDebug() << " --- sections dump(): " <<_sections.size() << " entries.";
for( int i = 0; i<_sections.size(); ++i )
{
QModelIndex idx = _sections.at(i).startIndex();
qDebug() << " --- sections:" << i << "row: " << idx.row() << " keyOf(i): " << _sections.keyOf(i) << " indexData: "<< idx.data().toString() << " itemData: " << XQItem::xqItemFromIndex(idx).data(Qt::DisplayRole).toString();
}
}

View File

@@ -12,17 +12,18 @@
***************************************************************************/ ***************************************************************************/
#ifndef XQMODELSECTIONLIST_H #ifndef XQSECTIONMANAGER_H
#define XQMODELSECTIONLIST_H #define XQSECTIONMANAGER_H
#include <QPersistentModelIndex> #include <QPersistentModelIndex>
#include <xqmaptor.h> #include <xqmaptor.h>
#include <xqitem.h> #include <xqitem.h>
/**
* @brief Struct containing data for a header section
*/
//! Daten zur beschreibung einer 'sektion' des models.
class XQModelSection class XQModelSection
{ {
@@ -35,13 +36,13 @@ public:
bool operator==(const XQModelSection& other) const; bool operator==(const XQModelSection& other) const;
bool isValid() const; bool isValid() const;
int row() const; int firstRow() const;
const QModelIndex& modelIndex() const; QModelIndex startIndex() const;
XQNodePtr sectionRootNode() const; XQNodePtr sectionRootNode() const;
XQNodePtr sheetRootNode() const; XQNodePtr sheetRootNode() const;
XQNodePtr contentRootNode() const; XQNodePtr contentRootNode() const;
void setContentRootNode( const XQNodePtr dataRootNode ); void setContentRootNode( const XQNodePtr dataRootNode ) const;
const QString& contentType() const; const QString& contentType() const;
XQItem& headerItem() const; XQItem& headerItem() const;
@@ -50,32 +51,42 @@ protected:
QPersistentModelIndex _modelIndex; QPersistentModelIndex _modelIndex;
XQNodePtr _sectionRootNode{}; mutable XQNodePtr _sectionSheetRootNode{};
XQNodePtr _contentRootNode{}; mutable XQNodePtr _contentRootNode{};
}; };
Q_DECLARE_METATYPE(XQModelSection) Q_DECLARE_METATYPE(XQModelSection)
/** //! Erste und letzte ziele einer XQModelSection
* @brief Maptor containing all header sections. struct XQSectionRange
*/ {
int firstRow{-1};
int lastRow{-1};
};
class XQModelSectionList : public XQMaptor<XQModelSection>
//! struktur, die alle sections enthält
class XQSectionManager
{ {
public: public:
bool hasValidSection(const QString& sectionKey) const; bool hasValidSection(const QString& sectionKey) const;
const XQModelSection& sectionFromRow( int row ) const; const XQModelSection& sectionByKey( const QString& sectionKey ) const;
const XQModelSection& sectionFromIndex( const QModelIndex& index ) const; const XQModelSection& sectionByRow( int row ) const;
int firstRow(const QModelIndex& idx) const; const XQModelSection& createSection(const QModelIndex& modelIndex, XQNodePtr sheetNode);
int lastRow(const QModelIndex& idx) const; int lastRow(const XQModelSection& section ) const;
int lastRow(const XQModelSection& section) const; XQSectionRange sectionRange(const XQModelSection &section) const;
void dump()const override; void dump()const;
protected:
XQMaptor<XQModelSection> _sections;
}; };
#endif // XQMODELSECTIONLIST_H #endif // XQSECTIONMANAGER_H

View File

@@ -35,28 +35,34 @@ XQSelectionModel::XQSelectionModel(QAbstractItemModel* model, QObject* parent)
} }
//! firz //! jetzt die selektierten indices, wie die basisklasse, aber nur die innerhalt einer section.
void XQSelectionModel::select(const QItemSelection& selection, QItemSelectionModel::SelectionFlags command) void XQSelectionModel::select(const QItemSelection& selection, QItemSelectionModel::SelectionFlags command)
{ {
// step #0: fetch selected indices. // step #0: die ursprüngliche selection bestimmen
const QModelIndexList list = selection.indexes(); const QModelIndexList list = selection.indexes();
if (list.isEmpty() || selectedRows().isEmpty() ) if (list.isEmpty() || selectedRows().isEmpty() )
return QItemSelectionModel::select(selection, command); return QItemSelectionModel::select(selection, command);
// fetch first index // step 01: den ersten index bestimmen
QModelIndex firstValid = list.first(); QModelIndex firstValid = list.first();
if (hasSelection() ) if (hasSelection() )
firstValid = selectedRows().first(); firstValid = selectedRows().first();
//XQItem& firstItem = XQItem::xqItemFromIndex(firstValid); // step 02: finde das erste item gültigem content node.
//if( firstItem.isValid() ) XQNodePtr firstNode = XQItem::xqItemFromIndex(firstValid).contentNode();
while( !firstNode)
{ {
firstValid = firstValid.siblingAtRow( firstValid.row()+1);
firstNode = XQItem::xqItemFromIndex(firstValid).contentNode();
}
XQNodePtr firstNode = XQItem::xqItemFromIndex(firstValid).contentNode(); // step 03: selektiere nur knoten, die den gleichen tag_name haben, sich also
// in der selben section befinden
if( firstNode )
{
QItemSelection newSelection; QItemSelection newSelection;
// __fixme! das crasht!
for (const QModelIndex& idx : list) for (const QModelIndex& idx : list)
{ {
XQNodePtr nextNode = XQItem::xqItemFromIndex(idx).contentNode(); XQNodePtr nextNode = XQItem::xqItemFromIndex(idx).contentNode();
@@ -66,5 +72,7 @@ void XQSelectionModel::select(const QItemSelection& selection, QItemSelectionMod
} }
return QItemSelectionModel::select(newSelection, command); return QItemSelectionModel::select(newSelection, command);
} }
// fallback
QItemSelectionModel::select(selection, command); QItemSelectionModel::select(selection, command);
} }

View File

@@ -35,18 +35,34 @@
void showItemList( const XQItemList& list) void showItemList( const XQItemList& list)
{ {
for(const auto& entry : list ) for(const auto& entry : list )
qDebug() << " --- itemList: " << ((XQItem*)entry)->content(); qDebug() << " --- itemList: " << entry->text();
qDebug();
}
void showSelectionList( const QModelIndexList& list)
{
for(const auto& entry : list )
qDebug() << " --- SelectionList: " << entry.data().toString();
qDebug(); qDebug();
} }
//! Konstruktur mit parent. //! Konstruktor mit parent.
XQViewModel::XQViewModel( QObject* parent ) XQViewModel::XQViewModel( QObject* parent )
: QStandardItemModel{ parent }, _itemFactory{ XQItemFactory::instance() } : QStandardItemModel{ parent }, _itemFactory{ XQItemFactory::instance() }
{ {
invisibleRootItem()->setData( "[rootItem]", Qt::DisplayRole ); invisibleRootItem()->setData( "[rootItem]", Qt::DisplayRole );
setItemPrototype( new XQItem ); setItemPrototype( new XQItem );
// auf änderungen kann in den unterklassen reagiert werden
connect(this, &QStandardItemModel::itemChanged, this, [this](QStandardItem *item)
{
XQItem* xqItem = static_cast<XQItem*>(item);
emit xqItemChanged( *xqItem );
});
// not needed
//qRegisterMetaType<XQItem>("XQItem");
} }
@@ -59,7 +75,14 @@ const XQItem& XQViewModel::xqRootItem()
// dynamisch über den ItemData Mechanismus wie in QStandardItem // dynamisch über den ItemData Mechanismus wie in QStandardItem
return *static_cast<XQItem*>(invisibleRootItem()); return *static_cast<XQItem*>(invisibleRootItem());
}
//! Gibt den daten root node des models zurück.
XQNodePtr XQViewModel::contentRootNode()
{
return _contentRoot;
} }
@@ -83,6 +106,16 @@ XQItem& XQViewModel::xqFirstItem(int row) const
return *static_cast<XQItem*>( QStandardItemModel::item(row) ); return *static_cast<XQItem*>( QStandardItemModel::item(row) );
} }
void XQViewModel::expandNewItem(const QModelIndex& index)
{
if( _treeTable )
{
// ... ausklappen...
_treeTable->expand( index );
// ... und markieren
_treeTable->setCurrentIndex( index );
}
}
//! initialisiert dieses model über den namen. Es wird hier //! initialisiert dieses model über den namen. Es wird hier
//! nur die strukur erzeugt, keine inhalte. //! nur die strukur erzeugt, keine inhalte.
@@ -99,9 +132,7 @@ void XQViewModel::initModel(const QString& modelName)
*/ */
setObjectName( modelName ); setObjectName( modelName );
qDebug() << " --- initModel: " << objectName(); // model rootnode finden -> <DocumentTreeModel>
// model rootnode finden -> <DocumentTreeModel>
XQNodePtr modelSheet = _itemFactory.findModelSheet( modelName ); // throws XQNodePtr modelSheet = _itemFactory.findModelSheet( modelName ); // throws
// #1: über alle sections // #1: über alle sections
@@ -111,7 +142,7 @@ void XQViewModel::initModel(const QString& modelName)
const XQNodePtr header = sectionNode->find_child_by_tag_name( c_Header ); const XQNodePtr header = sectionNode->find_child_by_tag_name( c_Header );
if( header ) if( header )
{ {
XQItemList list = _itemFactory.makeRow( XQItemFactory::mHeader, header, nullptr ); XQItemList list = _itemFactory.makeRow( header, nullptr );
addSection(list, sectionNode ); addSection(list, sectionNode );
} }
} }
@@ -122,25 +153,24 @@ void XQViewModel::initModel(const QString& modelName)
//! 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.
//! Wrzeugt dann eine section aus einer frisch erzeugten itemlist. Der erste modelindex //! Erzeugt dann eine section aus einer frisch erzeugten itemlist. Der erste modelindex
//! der liste und der root knoten der model-beschreibung werden gespeichert. //! der liste und der root knoten der model-beschreibung werden gespeichert.
void XQViewModel::addSection(const XQItemList& list, const XQNodePtr& sectionNode ) void XQViewModel::addSection(const XQItemList& list, const XQNodePtr& sheetNode )
{ {
// 1. die liste darf nicht leer sein // 1. die liste darf nicht leer sein
Q_ASSERT(!list.isEmpty()); Q_ASSERT(!list.isEmpty());
// 2. sectionNode muss da sein // 2. sheetNode muss da sein
Q_ASSERT(sectionNode); Q_ASSERT(sheetNode);
// 3. 'ContenType' muss vorhanden sein // 3. 'ContenType' muss vorhanden sein
if( !sectionNode->has_attribute( c_ContentType) ) if( !sheetNode->has_attribute( c_ContentType) )
throw XQException( "section list: Section node needs attribute 'ContentType'!"); throw XQException( "section list: Section node needs attribute 'ContentType'!");
// 5. das erzeugt dann auch valide indices // 5. das erzeugt dann auch valide indices
appendRow(list); appendRow(list);
// 6. jetzt können wir auch die sction erzeugen // 6. jetzt können wir auch die section erzeugen
XQModelSection section(list[0]->index(), sectionNode ); const XQModelSection& section = _sections.createSection( list[0]->index(), sheetNode );
_sections.addAtKey(sectionNode->attribute( c_ContentType), section);
// ... und es der welt mitteilen. // ... und es der welt mitteilen.
emit sectionCreated( section ); emit sectionCreated( section );
@@ -148,11 +178,43 @@ void XQViewModel::addSection(const XQItemList& list, const XQNodePtr& sectionNod
} }
//! SLOT, toggled die section mit dem 'sectionKey' (hier: contentType)
void XQViewModel::onToggleSection(const QString& sectionKey )
{
toggleSection( _sections.sectionByKey(sectionKey) );
}
//! toggled die gegebene model section.
void XQViewModel::toggleSection( const XQModelSection& section )
{
if( section.isValid() && _treeTable )
{
XQSectionRange pos = _sections.sectionRange(section);
qDebug() << " --- Section RANGE: " << pos.firstRow << " -> " << pos.lastRow;
_treeTable->toggleRowsHidden(pos.firstRow, pos.lastRow );
}
}
/*
//! SLOT als weiterleitung vom SIGNAL itemchanged
void XQViewModel::onItemChanged(XQItem* item )
{
qDebug() << " --- BASE item changed: " << item->text();
}
*/
//! SLOT, der aufgerufen wird, wenn eine edit-action getriggert wurde. //! SLOT, der aufgerufen wird, wenn eine edit-action getriggert wurde.
void XQViewModel::onActionTriggered(QAction* action) void XQViewModel::onActionTriggered(QAction* action)
{ {
qDebug() << " --- onActionTriggered: count:" << XQNode::s_Count; qDebug() << " --- onActionTriggered: count:" << action->text() <<": " << XQNode::s_Count;
// all selected indices // all selected indices
QModelIndexList selectionList = treeTable()->selectionModel()->selectedRows(); QModelIndexList selectionList = treeTable()->selectionModel()->selectedRows();
@@ -161,6 +223,7 @@ void XQViewModel::onActionTriggered(QAction* action)
switch( cmdType ) switch( cmdType )
{ {
// just handle undo ... // just handle undo ...
case XQCommand::cmdUndo : case XQCommand::cmdUndo :
return _undoStack->undo(); return _undoStack->undo();
@@ -185,45 +248,22 @@ void XQViewModel::onActionTriggered(QAction* action)
// we create a command // we create a command
XQCommand* command = new XQCommand( cmdType, this ); XQCommand* command = new XQCommand( cmdType, this );
QModelIndex currentIndex = treeTable()->currentIndex();
command->setOriginIndex(currentIndex);
// store the row positions of the selected indices // store the row positions of the selected indices
showSelectionList(selectionList);
command->saveNodes( selectionList ); command->saveNodes( selectionList );
command->setOriginIndex( treeTable()->currentIndex() );
// execute command // execute command
_undoStack->push( 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. //! führt die 'redo' action des gegebenen commnds aus.
void XQViewModel::onCommandRedo( XQCommand& command ) void XQViewModel::onCommandRedo( const XQCommand& command )
{ {
static MemCallMap redoCalls static MemCallMap redoCalls
{ {
@@ -249,45 +289,10 @@ void XQViewModel::onCommandRedo( XQCommand& command )
} }
} }
/*
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. //! führt die 'undo' action des gegebenen commnds aus.
void XQViewModel::onCommandUndo( XQCommand& command ) void XQViewModel::onCommandUndo( const XQCommand& command )
{ {
qDebug() << " --- onCommandUndo: count: " << XQNode::s_Count; qDebug() << " --- onCommandUndo: count: " << XQNode::s_Count;
@@ -319,18 +324,26 @@ void XQViewModel::onCommandUndo( XQCommand& command )
//! markierte knoten entfernen, 'command' enthält die liste //! markierte knoten entfernen, 'command' enthält die liste
void XQViewModel::cmdCut( XQCommand& command ) void XQViewModel::cmdCut( const XQCommand& command )
{ {
int itmPos = command.first().itemPos;
const XQModelSection& section = _sections.sectionByRow( itmPos );
qDebug() << " --- HEADSHOT I: " << itmPos << "->" << section.contentType();
// wir gehen rückwärts über alle gemerkten knoten ... // wir gehen rückwärts über alle gemerkten knoten ...
for (auto it = command.rbegin(); it != command.rend(); ++it) for (auto it = command.rbegin(); it != command.rend(); ++it)
{ {
// ... holen das erste item, das auch den content node enthält // ... holen das erste item, das auch den content node enthält
//const XQNodeBackup& entry = *it; //const XQNodeBackup& entry = *it;
// jetzt löschen, dabei wird die parent-verbindung entfernt // jetzt löschen, dabei wird die parent-verbindung entfernt
const XQNodeBackup& entry = *it; const XQNodeBackup& entry = *it;
XQItem& firstItem = xqFirstItem( (*it).itemPos ); XQItem& firstItem = xqFirstItem( (*it).itemPos );
qDebug() << " --- Cut: " << firstItem.text() << " " << firstItem.row() << " id#" << entry.contentNode->_id; //qDebug() << " --- Cut: " << firstItem.text() << " " << firstItem.row() << " id#" << entry.contentNode->_id;
qDebug() << " ---- command CUT: itemPos: " << entry.itemPos << " nodePos: "<< entry.nodePos << " is " << entry.contentNode->friendly_name();
entry.contentNode->unlink_self(); entry.contentNode->unlink_self();
removeRow(entry.itemPos ); removeRow(entry.itemPos );
@@ -340,31 +353,37 @@ void XQViewModel::cmdCut( XQCommand& command )
//! entfernte knoten wieder einfügen , 'command' enthält die liste //! entfernte knoten wieder einfügen , 'command' enthält die liste
void XQViewModel::cmdCutUndo( XQCommand& command ) void XQViewModel::cmdCutUndo( const XQCommand& command )
{ {
// die anfangsposition // die anfangsposition
int itmPos = command.first().itemPos; int itmPos = command.first().itemPos;
// die 'zuständige' section rausfinden // die 'zuständige' section rausfinden
const XQModelSection& section = _sections.sectionFromRow( itmPos ); const XQModelSection& section = _sections.sectionByRow( itmPos );
qDebug() << " --- HEADSHOT II: " << itmPos << "->" << section.contentType();
// über alle einträge ... // über alle einträge ...
for (auto& entry : command ) for (auto& entry : 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.makeRow( XQItemFactory::mData, section.sheetRootNode(), savedNode ); XQItemList list = _itemFactory.makeRow( section.sheetRootNode(), savedNode );
insertRow( entry.itemPos, list );
XQItem& firstItem = *((XQItem*)list[0]); XQItem& firstItem = *((XQItem*)list[0]);
qDebug() << " ---- command cut UNDO2: itemPos: " << entry.itemPos << " nodePos: "<< entry.nodePos << " is " << entry.contentNode->friendly_name();
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();
insertRow( entry.itemPos, list );
} }
} }
//! clipboard inhalte einfügen //! clipboard inhalte einfügen
void XQViewModel::cmdPaste( XQCommand& command ) void XQViewModel::cmdPaste( const XQCommand& command )
{ {
// selection holen ... // selection holen ...
QItemSelectionModel* selectionModel = treeTable()->selectionModel(); QItemSelectionModel* selectionModel = treeTable()->selectionModel();
@@ -379,7 +398,7 @@ void XQViewModel::cmdPaste( XQCommand& command )
int nodePos = item.contentNode()->own_pos()+1; int nodePos = item.contentNode()->own_pos()+1;
// die zugehörige section finden // die zugehörige section finden
const XQModelSection& section = _sections.sectionFromRow( insRow-1 ); const XQModelSection& section = _sections.sectionByRow( insRow-1 );
// wir pasten das clipboard // wir pasten das clipboard
for (auto& entry : _clipBoard ) for (auto& entry : _clipBoard )
{ {
@@ -388,7 +407,7 @@ void XQViewModel::cmdPaste( XQCommand& command )
// ... diesen einfügen ... // ... diesen einfügen ...
newNode->add_me_at( nodePos ); newNode->add_me_at( nodePos );
// ... und damit eine frische item-row erzeugen // ... und damit eine frische item-row erzeugen
XQItemList list = _itemFactory.makeRow( XQItemFactory::mData, section.sheetRootNode(), newNode ); XQItemList list = _itemFactory.makeRow( 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();
@@ -399,14 +418,16 @@ void XQViewModel::cmdPaste( XQCommand& command )
} }
// unsere änderungen merken fürs 'undo' // unsere änderungen merken fürs 'undo'
command.saveNodes( selectionModel->selectedRows() );
/// fix_xx
const_cast<XQCommand&>(command).saveNodes( selectionModel->selectedRows() );
} }
//! einfügen aus dem clipboard wieder rückgängig machen //! einfügen aus dem clipboard wieder rückgängig machen
void XQViewModel::cmdPasteUndo( XQCommand& command ) void XQViewModel::cmdPasteUndo( const XQCommand& command )
{ {
command.dumpList("Paste UNDO"); command.dumpList("Paste UNDO");
// wir gehen rückwärts über alle markieren knoten ... // wir gehen rückwärts über alle markieren knoten ...
@@ -427,7 +448,7 @@ void XQViewModel::cmdPasteUndo( XQCommand& command )
//! entfernen der selection ohne copy in clipboard. //! entfernen der selection ohne copy in clipboard.
void XQViewModel::cmdDelete( XQCommand& command ) void XQViewModel::cmdDelete( const XQCommand& command )
{ {
// wir gehen rückwärts über alle markieren knoten ... // wir gehen rückwärts über alle markieren knoten ...
for (auto it = command.rbegin(); it != command.rend(); ++it) for (auto it = command.rbegin(); it != command.rend(); ++it)
@@ -435,83 +456,85 @@ void XQViewModel::cmdDelete( XQCommand& command )
// ... holen das erste item, das auch den content node enthält // ... holen das erste item, das auch den content node enthält
const XQNodeBackup& entry = *it; const XQNodeBackup& entry = *it;
XQItem& firstItem = xqFirstItem( (*it).itemPos ); XQItem& firstItem = xqFirstItem( (*it).itemPos );
qDebug() << " --- Cut: " << firstItem.text() << " " << firstItem.row(); qDebug() << " --- delete: " << firstItem.text() << " " << firstItem.row();
// jetzt löschen // jetzt löschen
entry.contentNode->unlink_self(); entry.contentNode->unlink_self();
removeRow(entry.itemPos ); removeRow(entry.itemPos );
} }
} }
//! macht 'delete' wirder rückgängig. //! macht 'delete' wieder rückgängig.
void XQViewModel::cmdDeleteUndo( XQCommand& command ) void XQViewModel::cmdDeleteUndo( const XQCommand& command )
{ {
for (const auto& entry : command)
{
qDebug() << " --- delete UNDo: " << entry.contentNode->friendly_name();
}
cmdCutUndo(command);
} }
//! legt eine neue, leere zeile an. //! legt eine neue, leere zeile an.
void XQViewModel::cmdNew( XQCommand& command ) void XQViewModel::cmdNew( const XQCommand& command )
{ {
// __fix
/*
const QModelIndex& origin = command.originIndex(); const QModelIndex& origin = command.originIndex();
if( !origin.isValid() )
throw XQException("cmdNewRow failed: index not valid ");
XQItem* target = xqItemFromIndex( origin ); XQItem& target = xqItemFromIndex( origin );
// current data node // current data node
XQNodePtr node = target->contentNode(); XQNodePtr node = target.contentNode();
// we create a new data node
// we create a new data node XQNodePtr newNode = XQNode::make_node( node->tag_name(), node->tag_value() );
//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() // store node in node->parent()
//node->add_before_me( newNode ); newNode->add_me_at( node->own_pos(), node->parent() );
// 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 ... //...
const XQModelSection& section = _sections.sectionByRow( origin.row() );
// neue, leere zeile erzeugen ...
XQItemList list =_itemFactory.makeRow( section.sheetRootNode(), newNode );
// ... zur treeview hinzufügen ...
insertRow( origin.row(), list ); insertRow( origin.row(), list );
// ... editierbar machen ...
QModelIndex newIndex = list[0]->index();
treeTable()->setCurrentIndex( newIndex );
treeTable()->edit( newIndex );
// ,,, und fürs undo speichern
const_cast<XQCommand&>(command).saveNodes( {newIndex} );
// ... and make it ...
treeTable()->setCurrentIndex( list[0]->index() );
// ... editable
treeTable()->edit( list[0]->index() );
*/
} }
//! entfernt die neu angelegte zeile. //! entfernt die neu angelegte zeile.
void XQViewModel::cmdNewUndo( XQCommand& command ) void XQViewModel::cmdNewUndo( const XQCommand& command )
{ {
cmdDelete( command );
} }
//! schaltet eine section sichtbar oder unsichtbar. //! schaltet eine section sichtbar oder unsichtbar.
void XQViewModel::cmdToggleSection( XQCommand& command ) void XQViewModel::cmdToggleSection( const XQCommand& command )
{ {
const QModelIndex& index = command.originIndex(); const QModelIndex& index = command.originIndex();
Q_ASSERT(index.isValid()); Q_ASSERT(index.isValid());
const XQModelSection& section = _sections.sectionByRow(index.row());
int fstRow = _sections.firstRow( index ); // Obacht! Das ist hier etwas unsauber, 'toogleSection'' ändert den check-State
int lstRow = _sections.lastRow( index ); // im document-tree, was wiederum die 'toggleSection' auslöst, das gibt also
// einen doppelten Aufruf und wir sind dann wieder im Anfangszustand.
bool hidden =_treeTable->isRowHidden( fstRow, _treeTable->rootIndex() ); //toggleSection( section );
for (int row = fstRow; row < lstRow; ++row )
_treeTable->setRowHidden( row, _treeTable->rootIndex(), !hidden ); emit sectionToggled(section);
emit sectionToggled( _sections.sectionFromIndex(index) );
} }
//! git die treetable zurück //! gibt die treetable zurück
XQTreeTable* XQViewModel::treeTable() XQTreeTable* XQViewModel::treeTable()
{ {
@@ -524,7 +547,7 @@ void XQViewModel::setTreeTable(XQTreeTable* mainView )
{ {
// store view for direct access: the maintree // store view for direct access: the maintree
_treeTable = mainView; _treeTable = mainView;
// connect myself as model to the mainview // set myself as model to the mainview
_treeTable->setModel(this); _treeTable->setModel(this);
XQItemDelegate* delegate = new XQItemDelegate( *this ); XQItemDelegate* delegate = new XQItemDelegate( *this );
_treeTable->setItemDelegate( delegate ); _treeTable->setItemDelegate( delegate );

View File

@@ -19,9 +19,10 @@
#include <QMenu> #include <QMenu>
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QAbstractItemView> #include <QAbstractItemView>
#include <QtQmlIntegration>
#include <xqsimpleclipboard.h> #include <xqsimpleclipboard.h>
#include <xqmodelsectionlist.h> #include <xqsectionmanager.h>
#include <xqitemfactory.h> #include <xqitemfactory.h>
#include <xqcontextmenu.h> #include <xqcontextmenu.h>
@@ -36,12 +37,15 @@ class XQCommand;
class XQViewModel : public QStandardItemModel class XQViewModel : public QStandardItemModel
{ {
Q_OBJECT Q_OBJECT
QML_ELEMENT
public: public:
XQViewModel(QObject* parent = nullptr); XQViewModel(QObject* parent = nullptr);
virtual ~XQViewModel() = default; virtual ~XQViewModel() = default;
QHash<int, QByteArray> roleNames() const override;
XQTreeTable* treeTable(); XQTreeTable* treeTable();
virtual void setTreeTable( XQTreeTable* mainView ); virtual void setTreeTable( XQTreeTable* mainView );
@@ -50,78 +54,65 @@ public:
virtual void initModel( const QString& modelName); virtual void initModel( const QString& modelName);
void expandNewItem(const QModelIndex& index);
void toggleSection( const XQModelSection& section );
//little helpers //little helpers
const XQItem& xqRootItem(); const XQItem& xqRootItem();
XQNodePtr contentRootNode();
XQItem& xqItemFromIndex(const QModelIndex& index) const; XQItem& xqItemFromIndex(const QModelIndex& index) const;
XQItem& xqFirstItem(int row) const; XQItem& xqFirstItem(int row) const;
// undo-/redo-able stuff // undo-/redo-able stuff
virtual void cmdToggleSection( XQCommand& command ); virtual void cmdToggleSection( const XQCommand& command );
virtual void cmdCut( XQCommand& command ); virtual void cmdCut( const XQCommand& command );
virtual void cmdCutUndo( XQCommand& command ); virtual void cmdCutUndo( const XQCommand& command );
virtual void cmdPaste( XQCommand& command ); virtual void cmdPaste( const XQCommand& command );
virtual void cmdPasteUndo( XQCommand& command ); virtual void cmdPasteUndo( const XQCommand& command );
virtual void cmdDelete( XQCommand& command ); virtual void cmdDelete( const XQCommand& command );
virtual void cmdDeleteUndo( XQCommand& command ); virtual void cmdDeleteUndo( const XQCommand& command );
virtual void cmdNew( XQCommand& command ); virtual void cmdNew( const XQCommand& command );
virtual void cmdNewUndo( XQCommand& command ); virtual void cmdNewUndo( const XQCommand& command );
QHash<int, QByteArray> roleNames() const override; // Derzeit wird die default-implementierung von data/setData genutzt. hier wäre dann die
// Stelle um setData & data an externe 'handler' umzubiegen, siehe giovannies 'model-injection'
/*! signals:
Derzeit wird die default-implementierung von data/setData genutzt. hier wäre dann die void xqItemChanged( const XQItem& item );
Stelle um setData & data an externe 'handler' umzubiegen, siehe giovannies 'model-injection' void itemCreated( XQItem* newItem );
void sectionCreated( const XQModelSection& section );
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override void sectionToggled( const XQModelSection& section );
{
return QStandardItemModel::data( index, role );
}
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override
{
qDebug() << " --- setData: " << value.toString();
return QStandardItemModel::setData( index, value, role );
}
*/
public slots: public slots:
virtual void onShowContextMenu(const QPoint& point); virtual void onShowContextMenu(const QPoint& point);
virtual void onActionTriggered(QAction* action); virtual void onActionTriggered(QAction* action);
virtual void onToggleSection(const QString& sectionKey );
// handle XQCommands ( == UndoCommand ) // handle XQCommands ( == UndoCommand )
virtual void onCommandRedo( XQCommand& command ); virtual void onCommandRedo( const XQCommand& command );
virtual void onCommandUndo( XQCommand& command ); virtual void onCommandUndo( const XQCommand& command );
signals:
void itemCreated( XQItem* newItem );
void sectionCreated( const XQModelSection& section );
void sectionToggled( const XQModelSection& section );
protected: protected:
void addSection(const XQItemList& list, const XQNodePtr& sheetNode ); void addSection(const XQItemList& list, const XQNodePtr& sheetNode );
virtual void initContextMenu() = 0; virtual void initContextMenu() = 0;
// __fixme: should be created from xml // __fixme: should be created from xml
virtual void setupViewProperties(); virtual void setupViewProperties();
protected: protected:
using MemCall = void (XQViewModel::*)(XQCommand&); using MemCall = void (XQViewModel::*)(const XQCommand&);
using MemCallMap = QMap<XQCommand::CmdType,MemCall>; 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;
XQModelSectionList _sections; XQSectionManager _sections;
XQTreeTable* _treeTable{}; XQTreeTable* _treeTable{};
//QAbstractItemView* _treeTable{}; //QAbstractItemView* _treeTable{};
QUndoStack* _undoStack{}; QUndoStack* _undoStack{};
XQContextMenu* _contextMenu{}; XQContextMenu* _contextMenu{};

View File

@@ -78,6 +78,7 @@ namespace znode
zweak_node _parent; zweak_node _parent;
znode_list _children; znode_list _children;
// functor, der auf pointer gleichheit prüft.
struct match_node struct match_node
{ {
match_node( zbasic_node* match ) match_node( zbasic_node* match )
@@ -95,9 +96,11 @@ namespace znode
public: public:
//! shortcut auf std::make_shared... //! shortcut auf std::make_shared...
static zshared_node make_node( str_cref arg1, str_cref arg2 = "" , zshared_cref parent = nullptr ) //! beachte: der eltern-knoten wird hier nicht gesetzt, der neue knoten
//! wird nirgends eingefügt.
static zshared_node make_node( str_cref arg1, str_cref arg2 = "" )
{ {
return std::make_shared<zbasic_node>( arg1, arg2, parent ); return std::make_shared<zbasic_node>( arg1, arg2 );
} }
//! leerer konstruktor //! leerer konstruktor
@@ -136,7 +139,7 @@ namespace znode
zbasic_node(const zbasic_node&) = delete; zbasic_node(const zbasic_node&) = delete;
zbasic_node& operator=(const zbasic_node&) = delete; zbasic_node& operator=(const zbasic_node&) = delete;
// 'move' geht (shared_from_this bleibt gültig) //! 'move' geht (shared_from_this bleibt gültig)
zbasic_node(zbasic_node&&) noexcept = default; zbasic_node(zbasic_node&&) noexcept = default;
zbasic_node& operator=(zbasic_node&&) noexcept = default; zbasic_node& operator=(zbasic_node&&) noexcept = default;
@@ -178,31 +181,31 @@ namespace znode
return _parent.lock(); return _parent.lock();
} }
//! gibt den nachfolge-knoten oder 'end()' zurück.
zshared_node sibling() zshared_node sibling()
{ {
if( !parent() ) if( parent() )
//return zshared_node( make_node("WTF1") ); {
return zshared_node(); znode_list& childs = _parent->_children;
auto it = std::find( childs.begin(), childs.end(), this->shared_from_this() );
znode_list& childs = _parent->_children;
auto it = std::find( childs.begin(), childs.end(), this->shared_from_this() );
if( ++it != childs.end())
return *(it); return *(it);
}
//return zshared_node( make_node("WTF?") ); throw std::runtime_error("sibling(): no parent node");
return zshared_node();
} }
//! gibt den vector mit kind-knoten zurück
inline const znode_list& children() const inline const znode_list& children() const
{ {
return _children; return _children;
} }
//! testet, ob kinder vorhanden sind.
bool has_children() const bool has_children() const
{ {
return !children().empty(); return !children().empty();
} }
//! gibt das erste kind zurück
zshared_node first_child() zshared_node first_child()
{ {
if(!children().empty()) if(!children().empty())
@@ -210,6 +213,7 @@ namespace znode
return nullptr; return nullptr;
} }
//! gibt das letzte kind oder nullptr zurück
zshared_node last_child() zshared_node last_child()
{ {
if(!children().empty()) if(!children().empty())
@@ -237,7 +241,6 @@ namespace znode
int add_child_at( int idx, const zshared_node& node ) int add_child_at( int idx, const zshared_node& node )
{ {
// _fixme! was ist, wenn da schon ein elternknoten ist? // _fixme! was ist, wenn da schon ein elternknoten ist?
_children.insert(children().begin() + idx, node ); _children.insert(children().begin() + idx, node );
node->_parent = this->shared_from_this(); node->_parent = this->shared_from_this();
return int(children().size() - 1); return int(children().size() - 1);
@@ -250,10 +253,9 @@ namespace znode
parent()->add_child_at( offset, this->shared_from_this() ); parent()->add_child_at( offset, this->shared_from_this() );
else else
throw std::runtime_error("add_me_at(offset): no parent node"); throw std::runtime_error("add_me_at(offset): no parent node");
} }
//! fügt einen shard_ptr von 'mir' in die kinderliste des übergebenen knotens ein //! fügt einen shared_ptr von 'mir' in die kinderliste des übergebenen knotens ein
//! und macht diesen zu meinem elternknoten. //! und macht diesen zu meinem elternknoten.
void add_me_at( int offset, const zshared_node& parent_node ) void add_me_at( int offset, const zshared_node& parent_node )
{ {
@@ -266,18 +268,17 @@ namespace znode
{ {
throw std::runtime_error("add_me_at(offset,parent): no parent node"); throw std::runtime_error("add_me_at(offset,parent): no parent node");
} }
} }
//! findet die eigene position im eltern-knoten
int own_pos() int own_pos()
{ {
if( parent()) if( parent())
return parent()->child_pos( this->shared_from_this() ); return parent()->child_pos( this->shared_from_this() );
return -1; return -1;
} }
//int child_pos(zbasic_node* child) //! findet die postion eines kind-knotens
int child_pos(const zshared_node& child) int child_pos(const zshared_node& child)
{ {
//auto pos = std::find_if(children().begin(), children().end(), match_node(child) ); //auto pos = std::find_if(children().begin(), children().end(), match_node(child) );
@@ -287,7 +288,7 @@ namespace znode
return -1; return -1;
} }
//zshared_node unlink_child( zbasic_node* node ) //! findet die postion eines kind-knotens
zshared_node unlink_child( const zshared_node& node ) zshared_node unlink_child( const zshared_node& node )
{ {
auto it = std::find(_children.begin(), _children.end(), node); auto it = std::find(_children.begin(), _children.end(), node);
@@ -315,11 +316,10 @@ namespace znode
{ {
for( auto child : _children ) for( auto child : _children )
{ {
qDebug() << " --#- " << child->name() << " : " << child->has_attribute( attrkey, attrvalue );
if( child->has_attribute( attrkey, attrvalue )) if( child->has_attribute( attrkey, attrvalue ))
return child; return child;
} }
return zshared_node(); return nullptr;
} }
// //
@@ -330,7 +330,7 @@ namespace znode
if( child->tag_name() == tagname ) if( child->tag_name() == tagname )
return child; return child;
} }
return zshared_node(); return nullptr;
} }
zshared_node find_child_by_id( int id ) zshared_node find_child_by_id( int id )
@@ -340,46 +340,7 @@ namespace znode
if (child->_id == id) if (child->_id == id)
return child; return child;
} }
return zshared_node(); return nullptr;
}
void dump(int indent = 0) const
{
// fix_me!
qDebug() << std::string(indent * 2, ' ').c_str() << this->to_string();
//qDebug() << to_string();
//qDebug() << '\n';// std::endl;
if (!children().empty())
{
for (auto child : _children)
{
//qDebug() << " --- type: " << typeid(child).name();
child.get()->dump( indent + 1 );
}
}
}
template<typename T>
bool for_each_x( T func, int depth = 0 )
//bool for_each( auto func ) const
{
if( !apply( func, depth ) )
return false;
if( !children().empty() )
{
for( auto child : _children )
{
if( !child->for_each( func, depth+1 ) )
return false;
}
}
return true;
} }
// find ... // find ...
@@ -392,22 +353,6 @@ namespace znode
}; };
class zbasic_node_walker
{
public:
virtual void begin()
{}
template<typename str_t>
void for_each_node( zbasic_node<str_t>* node );
virtual void end()
{}
};
} //namespace znode } //namespace znode

View File

@@ -100,7 +100,7 @@ namespace znode
//parent->add_child( new_node ); //parent->add_child( new_node );
//zbasic_node<str_t>* new_node = new zbasic_node<str_t>( node.name(), node.child_value(), parent ); //zbasic_node<str_t>* new_node = new zbasic_node<str_t>( node.name(), node.child_value(), parent );
zshared_node new_node = zbasic_node<str_t>::make_node( xml_node.name(), xml_node.child_value(), parent ); zshared_node new_node = zbasic_node<str_t>::make_node( xml_node.name(), xml_node.child_value() );
parent->add_child( new_node ); parent->add_child( new_node );
if( !xml_node.attributes().empty() ) if( !xml_node.attributes().empty() )

View File

@@ -4,9 +4,6 @@
#include <vector> #include <vector>
#include <map> #include <map>
//#include <znode_stringmap.h>
//#include <znode_attributes.h>
namespace znode namespace znode
{ {
template<typename str_t> template<typename str_t>

View File

@@ -73,12 +73,23 @@ public:
return _data.end(); return _data.end();
} }
auto begin() const
{
return _data.begin();
}
auto end() const
{
return _data.end();
}
inline int size() const inline int size() const
{ {
return (int) _data.size(); return (int) _data.size();
} }
inline bool isEmpty() const inline bool isEmpty() const
{ {
return (_data.size()==0); return (_data.size()==0);
@@ -94,13 +105,11 @@ public:
return mapIndex().contains(key); return mapIndex().contains(key);
} }
inline const XQMapIndex& mapIndex() const inline const XQMapIndex& mapIndex() const
{ {
return _index; return _index;
} }
int indexOf( const QString& key ) const int indexOf( const QString& key ) const
{ {
return mapIndex().indexOf(key); return mapIndex().indexOf(key);
@@ -121,7 +130,6 @@ public:
return mapIndex().key( index ); return mapIndex().key( index );
} }
T& operator[]( int index ) T& operator[]( int index )
{ {
if( contains(index) ) if( contains(index) )
@@ -129,7 +137,6 @@ public:
throw XQException("XQMaptor operator[ int index ]: out of range"); throw XQException("XQMaptor operator[ int index ]: out of range");
} }
const T& operator[]( int index ) const const T& operator[]( int index ) const
{ {
if ( contains(index) ) if ( contains(index) )
@@ -150,19 +157,17 @@ public:
T& operator[]( const QString& key ) T& operator[]( const QString& key )
{ {
if( key.isEmpty() || !contains(key) ) if( key.isEmpty() || !contains(key) )
throw XQException("maprow operator[]: key empty || not found: " + key); throw XQException("XQMaptor operator[]: key empty || not found: " + key);
return _data[ _index[key] ]; return _data[ _index[key] ];
} }
const T& operator[]( const QString& key ) const const T& operator[]( const QString& key ) const
{ {
if (key.isEmpty() || !contains(key)) if (key.isEmpty() || !contains(key))
throw XQException("maprow operator[]: key empty || not found: " + key); throw XQException("XQMaptor operator[]: key empty || not found: " + key);
return _data[_index[key]]; return _data[_index[key]];
} }
T& at( const QString& key ) T& at( const QString& key )
{ {
return (*this)[key]; return (*this)[key];
@@ -173,28 +178,54 @@ public:
return (*this)[key]; return (*this)[key];
} }
const T& last() const
{
if(_data.isEmpty())
throw XQException( "XQMaptor last: is empty!" );
return _data.last();
}
const T& first() const
{
if(_data.isEmpty())
throw XQException( "XQMaptor first: is empty!" );
return _data.first();
}
T& last()
{
if(_data.isEmpty())
throw XQException( "XQMaptor last: is empty!" );
return _data.last();
}
T& first()
{
if(_data.isEmpty())
throw XQException( "XQMaptor first: is empty!" );
return _data.first();
}
virtual int add( const T& item ) virtual int add( const T& item )
{ {
_data.push_back( item ); _data.push_back( item );
return _data.size()-1; return _data.size()-1;
} }
virtual void addAtIndex( int index, const T& item ) virtual void addAtIndex( int index, const T& item )
{ {
if(contains(index)) if(contains(index))
throw XQException( "QStringrow::add: index out of range!" ); throw XQException( "XQMaptor add at index: index out of range!" );
_data[index] = item; _data[index] = item;
} }
// convenience method to mimic QMap<T,QString> // convenience method to mimic QMap<T,QString>
virtual void insert( const T& item, const QString& key ) virtual void insert( const T& item, const QString& key )
{ {
addAtKey(key, item ); addAtKey(key, item );
} }
virtual void addAtKey( const QString& key, const T& item ) virtual void addAtKey( const QString& key, const T& item )
{ {
XQMapIndex::iterator pos = _index.find( key ); XQMapIndex::iterator pos = _index.find( key );
@@ -209,7 +240,6 @@ public:
} }
} }
bool addAlias( const QString& key, const QString& alias ) bool addAlias( const QString& key, const QString& alias )
{ {
// look for 'original' key // look for 'original' key
@@ -227,20 +257,17 @@ public:
return true; return true;
} }
void addKey( const QString& key, int index ) void addKey( const QString& key, int index )
{ {
_index.addKey( key, index ); _index.addKey( key, index );
} }
virtual void clear() virtual void clear()
{ {
_data.clear(); _data.clear();
_index.clear(); _index.clear();
} }
virtual bool killEntry( const QString& key ) virtual bool killEntry( const QString& key )
{ {
int idx = indexOf( key ); int idx = indexOf( key );
@@ -249,7 +276,6 @@ public:
return killEntry( (int) idx ); return killEntry( (int) idx );
} }
virtual bool killEntry( int index ) virtual bool killEntry( int index )
{ {
if( index >= this->_data.size() ) if( index >= this->_data.size() )
@@ -261,19 +287,16 @@ public:
return true; return true;
} }
virtual QString toString() const virtual QString toString() const
{ {
return join( ";" ); return join( ";" );
} }
virtual void dump() const virtual void dump() const
{ {
throw XQException("XQMaptor: dump not implemented!" ); throw XQException("XQMaptor: dump not implemented!" );
} }
virtual QString join( const QString& sep, int from=0, int to=-1) const virtual QString join( const QString& sep, int from=0, int to=-1) const
{ {
Q_UNUSED(sep) Q_UNUSED(sep)
@@ -283,7 +306,6 @@ public:
return "--"; return "--";
} }
int replaceKey( const QString& oldkey, const QString& newkey ) int replaceKey( const QString& oldkey, const QString& newkey )
{ {
int idx = indexOf( oldkey ); int idx = indexOf( oldkey );

View File

@@ -31,7 +31,7 @@ void XQContextMenu::addAction(const QString& text, XQCommand::CmdType commandTyp
QAction* newAction = new QAction(text, this); QAction* newAction = new QAction(text, this);
newAction->setData(commandType); newAction->setData(commandType);
_actionMap[commandType] = newAction; _actionMap[commandType] = newAction;
QWidget::addAction(newAction); QMenu::addAction(newAction);
setActionEnabled( commandType, enabled ); setActionEnabled( commandType, enabled );
} }
@@ -53,7 +53,7 @@ void XQContextMenu::addAction(const QIcon& icon, const QString& text, XQCommand:
QAction* newAction = new QAction(icon, text, this); QAction* newAction = new QAction(icon, text, this);
newAction->setData(commandType); newAction->setData(commandType);
_actionMap[commandType] = newAction; _actionMap[commandType] = newAction;
QWidget::addAction(newAction); QMenu::addAction(newAction);
setActionEnabled( commandType, enabled ); setActionEnabled( commandType, enabled );
} }

View File

@@ -14,7 +14,7 @@
#include <xqquickwidget.h> #include <xqquickwidget.h>
XQQuickWidget::XQQuickWidget(QWidget *parent) XQQuickWidget::XQQuickWidget(QWidget* parent)
: QQuickWidget(parent) : QQuickWidget(parent)
{ {

View File

@@ -23,7 +23,7 @@ class XQQuickWidget : public QQuickWidget
public: public:
XQQuickWidget(QWidget *parent = nullptr); XQQuickWidget(QWidget* parent = nullptr);
}; };
#endif // XQQUICKWIDGET_H #endif // XQQUICKWIDGET_H

View File

@@ -38,7 +38,7 @@ XQTreeTable::XQTreeTable(QWidget* parent)
//! gibt die verbundene modelview zurück, cast auf 'model()' //! gibt die verbundene modelview zurück, cast auf 'model()'
XQViewModel* XQTreeTable::modelView() XQViewModel* XQTreeTable::viewModel()
{ {
return static_cast<XQViewModel*>(model()); return static_cast<XQViewModel*>(model());
} }
@@ -48,7 +48,18 @@ XQViewModel* XQTreeTable::modelView()
XQItem& XQTreeTable::xqItemFromIndex(const QModelIndex& index ) XQItem& XQTreeTable::xqItemFromIndex(const QModelIndex& index )
{ {
return modelView()->xqItemFromIndex( index ); return viewModel()->xqItemFromIndex( index );
}
//! rows sichtbar/unsichtbar schalten, von 'fstRow' bis _einschliesslich_
//! 'lstRow'
void XQTreeTable::toggleRowsHidden( int fstRow, int lstRow )
{
bool hidden = isRowHidden( fstRow, rootIndex() );
for (int row = fstRow; row <= lstRow; ++row )
setRowHidden( row, rootIndex(), !hidden );
} }
@@ -71,7 +82,7 @@ void XQTreeTable::currentChanged(const QModelIndex& current, const QModelIndex&
} }
//! firz //! ändert die breite eines header-feldes anhand der maus-position
void XQTreeTable::mouseResizeHeaderEntry(int xpos) void XQTreeTable::mouseResizeHeaderEntry(int xpos)
{ {
@@ -96,7 +107,7 @@ void XQTreeTable::mouseResizeHeaderEntry(int xpos)
} }
//! firz //! behandelt den mouse-drag zur grössenänderung der header-felder.
void XQTreeTable::mouseMoveEvent(QMouseEvent* event) void XQTreeTable::mouseMoveEvent(QMouseEvent* event)
{ {
@@ -106,10 +117,9 @@ void XQTreeTable::mouseMoveEvent(QMouseEvent* event)
bool leftBtn = (event->buttons() & Qt::LeftButton); bool leftBtn = (event->buttons() & Qt::LeftButton);
QPoint eventPos = event->pos(); QPoint eventPos = event->pos();
// splitcursor ist active // splitcursor ist gesetzt
bool splitCursor = (cursor().shape() == Qt::SplitHCursor); bool splitCursor = (cursor().shape() == Qt::SplitHCursor);
// sind wir schon am 'draggen'? // sind wir schon am 'draggen'?
if (_indexToResize.isValid() && splitCursor && leftBtn) if (_indexToResize.isValid() && splitCursor && leftBtn)
{ {

View File

@@ -38,9 +38,11 @@ public:
XQTreeTable(QWidget* parent = nullptr ); XQTreeTable(QWidget* parent = nullptr );
virtual ~XQTreeTable() = default; virtual ~XQTreeTable() = default;
XQViewModel* modelView(); XQViewModel* viewModel();
XQItem& xqItemFromIndex(const QModelIndex& index ); XQItem& xqItemFromIndex(const QModelIndex& index );
void toggleRowsHidden(int fstRow, int lstRow );
protected: protected:
void currentChanged(const QModelIndex& current, const QModelIndex& previous) override; void currentChanged(const QModelIndex& current, const QModelIndex& previous) override;

View File

@@ -1,7 +1,11 @@
QT += core gui widgets quick quickwidgets QT += core gui widgets quick quickwidgets
# widgets-private # widgets-private
CONFIG += c++20 CONFIG += c++20 qmltypes
CONFIG -= qml_debug
QML_IMPORT_NAME = org.sourceworx.qmlcomponents
QML_IMPORT_MAJOR_VERSION = 1
# You can make your code fail to compile if it uses deprecated APIs. # You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line. # In order to do so, uncomment the following line.
@@ -20,9 +24,9 @@ HEADERS += \
items/xqitemtype.h \ items/xqitemtype.h \
items/xqitemdelegate.h \ items/xqitemdelegate.h \
model/xqcommand.h \ model/xqcommand.h \
model/xqmodelsectionlist.h \
model/xqnode.h \ model/xqnode.h \
model/xqnodewriter.h \ model/xqnodewriter.h \
model/xqsectionmanager.h \
model/xqselectionmodel.h \ model/xqselectionmodel.h \
model/xqsimpleclipboard.h \ model/xqsimpleclipboard.h \
model/xqviewmodel.h \ model/xqviewmodel.h \
@@ -58,9 +62,9 @@ SOURCES += \
items/xqitemdelegate.cpp \ items/xqitemdelegate.cpp \
main.cpp \ main.cpp \
model/xqcommand.cpp \ model/xqcommand.cpp \
model/xqmodelsectionlist.cpp \
model/xqnode.cpp \ model/xqnode.cpp \
model/xqnodewriter.cpp \ model/xqnodewriter.cpp \
model/xqsectionmanager.cpp \
model/xqselectionmodel.cpp \ model/xqselectionmodel.cpp \
model/xqsimpleclipboard.cpp \ model/xqsimpleclipboard.cpp \
model/xqviewmodel.cpp \ model/xqviewmodel.cpp \

View File

@@ -4,7 +4,6 @@
<file alias="modeldata2.xtr">../xml/modeldata2.xtr</file> <file alias="modeldata2.xtr">../xml/modeldata2.xtr</file>
<file alias="modeldata3.xtr">../xml/modeldata3.xtr</file> <file alias="modeldata3.xtr">../xml/modeldata3.xtr</file>
<file alias="modelsheet.xml">../xml/modelsheets.xml</file> <file alias="modelsheet.xml">../xml/modelsheets.xml</file>
<file alias="quickview.qml">../quick/quickview.qml</file> <file alias="xqtreeview.qml">../qml/xqtreeview.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -7,14 +7,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xtree", "xtree.vcxproj", "{
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86 Debug|x64 = Debug|x64
Release|x86 = Release|x86 Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D9E56CB4-F99F-4F88-B721-1443A0AFD5D0}.Debug|x86.ActiveCfg = Debug|Win32 {D9E56CB4-F99F-4F88-B721-1443A0AFD5D0}.Debug|x64.ActiveCfg = Debug|x64
{D9E56CB4-F99F-4F88-B721-1443A0AFD5D0}.Debug|x86.Build.0 = Debug|Win32 {D9E56CB4-F99F-4F88-B721-1443A0AFD5D0}.Debug|x64.Build.0 = Debug|x64
{D9E56CB4-F99F-4F88-B721-1443A0AFD5D0}.Release|x86.ActiveCfg = Release|Win32 {D9E56CB4-F99F-4F88-B721-1443A0AFD5D0}.Release|x64.ActiveCfg = Release|x64
{D9E56CB4-F99F-4F88-B721-1443A0AFD5D0}.Release|x86.Build.0 = Release|Win32 {D9E56CB4-F99F-4F88-B721-1443A0AFD5D0}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -5,16 +5,26 @@
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32"> <ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{D9E56CB4-F99F-4F88-B721-1443A0AFD5D0}</ProjectGuid> <ProjectGuid>{D9E56CB4-F99F-4F88-B721-1443A0AFD5D0}</ProjectGuid>
<Keyword>QtVS_v304</Keyword> <Keyword>QtVS_v304</Keyword>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|Win32'">10.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|Win32'">10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'">10.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'">10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)'=='Release|x64'">10.0</WindowsTargetPlatformVersion>
<QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild> <QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
@@ -24,6 +34,12 @@
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
@@ -31,13 +47,25 @@
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')"> <ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
<Import Project="$(QtMsBuild)\qt_defaults.props" /> <Import Project="$(QtMsBuild)\qt_defaults.props" />
</ImportGroup> </ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|Win32'" Label="QtSettings"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|Win32'" Label="QtSettings">
<QtInstall>qt691</QtInstall> <QtInstall>qt692</QtInstall>
<QtModules>core;gui;widgets</QtModules> <QtModules>core;gui;quick;quickcontrols2;quickdialogs2;quicklayouts;widgets;quickwidgets</QtModules>
<QtBuildConfig>debug</QtBuildConfig>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="QtSettings">
<QtInstall>qt692</QtInstall>
<QtModules>core;gui;quick;widgets;quickwidgets</QtModules>
<QtBuildConfig>debug</QtBuildConfig> <QtBuildConfig>debug</QtBuildConfig>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'" Label="QtSettings"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'" Label="QtSettings">
@@ -45,6 +73,11 @@
<QtModules>core;gui;widgets</QtModules> <QtModules>core;gui;widgets</QtModules>
<QtBuildConfig>release</QtBuildConfig> <QtBuildConfig>release</QtBuildConfig>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="QtSettings">
<QtInstall>VS2017x86Default</QtInstall>
<QtModules>core;gui;widgets</QtModules>
<QtBuildConfig>release</QtBuildConfig>
</PropertyGroup>
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')"> <Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." /> <Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
</Target> </Target>
@@ -54,13 +87,22 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" /> <Import Project="$(QtMsBuild)\Qt.props" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" /> <Import Project="$(QtMsBuild)\Qt.props" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|Win32'">
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'">
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@@ -69,6 +111,12 @@
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<AdditionalIncludeDirectories>items;model;application;widgets;util;nodes;pugixml;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|Win32'" Label="Configuration"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|Win32'" Label="Configuration">
<ClCompile> <ClCompile>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
@@ -81,6 +129,18 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ClCompile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'" Label="Configuration"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|Win32'" Label="Configuration">
<ClCompile> <ClCompile>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
@@ -97,62 +157,70 @@
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ClCompile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<QtRcc Include="xtree.qrc" /> <QtRcc Include="xtree.qrc" />
<QtUic Include="application\xqmainwindow.ui" /> <QtUic Include="application\xqmainwindow.ui" />
<ClCompile Include="application\xqappdata.cpp" /> <ClCompile Include="application\xqappdata.cpp" />
<ClCompile Include="application\xqchildmodelview.cpp" /> <ClCompile Include="application\xqchildmodel.cpp" />
<ClCompile Include="application\xqdocumentstore.cpp" /> <ClCompile Include="application\xqdocumentstore.cpp" />
<ClCompile Include="application\xqmainmodelview.cpp" /> <ClCompile Include="application\xqmainmodel.cpp" />
<ClCompile Include="application\xqmainwindow.cpp" /> <ClCompile Include="application\xqmainwindow.cpp" />
<ClCompile Include="items\xqgenericitem.cpp" />
<ClCompile Include="items\xqitem.cpp" /> <ClCompile Include="items\xqitem.cpp" />
<ClCompile Include="items\xqitemdelegate.cpp" /> <ClCompile Include="items\xqitemdelegate.cpp" />
<ClCompile Include="items\xqitemfactory.cpp" /> <ClCompile Include="items\xqitemfactory.cpp" />
<ClCompile Include="items\xqitemtype.cpp" /> <ClCompile Include="items\xqitemtype.cpp" />
<ClCompile Include="model\xqcommand.cpp" /> <ClCompile Include="model\xqcommand.cpp" />
<ClCompile Include="model\xqitemtype.cpp" />
<ClCompile Include="model\xqitemtypefactory.cpp" />
<ClCompile Include="model\xqnodewriter.cpp" /> <ClCompile Include="model\xqnodewriter.cpp" />
<ClCompile Include="model\xqsectionmanager.cpp" />
<ClCompile Include="model\xqselectionmodel.cpp" /> <ClCompile Include="model\xqselectionmodel.cpp" />
<ClCompile Include="model\xqitem.cpp" />
<ClCompile Include="model\xqmodelview.cpp" />
<ClCompile Include="model\xqmodelsections.cpp" />
<ClCompile Include="model\xqsimpleclipboard.cpp" /> <ClCompile Include="model\xqsimpleclipboard.cpp" />
<ClCompile Include="model\xqitemfactory.cpp" />
<ClCompile Include="model\xqnode.cpp" /> <ClCompile Include="model\xqnode.cpp" />
<ClCompile Include="model\xqviewmodel.cpp" />
<ClCompile Include="nodes\znode.cpp" /> <ClCompile Include="nodes\znode.cpp" />
<ClCompile Include="pugixml\pugixml.cpp" /> <ClCompile Include="pugixml\pugixml.cpp" />
<ClCompile Include="util\xqexception.cpp" /> <ClCompile Include="util\xqexception.cpp" />
<ClCompile Include="widgets\xqitemdelegate.cpp" />
<ClCompile Include="widgets\xqcontextmenu.cpp" /> <ClCompile Include="widgets\xqcontextmenu.cpp" />
<ClCompile Include="widgets\xqtreeview.cpp" /> <ClCompile Include="widgets\xqquickwidget.cpp" />
<ClCompile Include="widgets\xqtreetable.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<QtMoc Include="application\xqchildmodelview.h" />
</ItemGroup>
<ItemGroup>
<QtMoc Include="application\xqmainmodelview.h" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="application\xqmainwindow.h" /> <QtMoc Include="application\xqmainwindow.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="widgets\xqtreetable.h" />
<QtMoc Include="widgets\xqquickwidget.h" />
<QtMoc Include="application\xqdocumentstore.h" /> <QtMoc Include="application\xqdocumentstore.h" />
<ClInclude Include="application\xqappdata.h" /> <ClInclude Include="application\xqappdata.h" />
<ClInclude Include="items\xqgenericitem.h" /> <QtMoc Include="application\xqchildmodel.h" />
<QtMoc Include="application\xqmainmodel.h" />
<ClInclude Include="items\xqitem.h" /> <ClInclude Include="items\xqitem.h" />
<ClInclude Include="items\xqitemdelegate.h" /> <ClInclude Include="items\xqitemdelegate.h" />
<ClInclude Include="items\xqitemfactory.h" /> <ClInclude Include="items\xqitemfactory.h" />
<ClInclude Include="items\xqitemtype.h" /> <ClInclude Include="items\xqitemtype.h" />
<ClInclude Include="model\xqcommand.h" /> <ClInclude Include="model\xqcommand.h" />
<ClInclude Include="model\xqmodelsections.h" />
<ClInclude Include="model\xqnodewriter.h" /> <ClInclude Include="model\xqnodewriter.h" />
<ClInclude Include="model\xqsectionmanager.h" />
<ClInclude Include="model\xqsimpleclipboard.h" /> <ClInclude Include="model\xqsimpleclipboard.h" />
<ClInclude Include="model\xqnode.h" /> <ClInclude Include="model\xqnode.h" />
<QtMoc Include="model\xqviewmodel.h" />
<ClInclude Include="nodes\znode.h" /> <ClInclude Include="nodes\znode.h" />
<ClInclude Include="nodes\znode_attributes.h" />
<ClInclude Include="nodes\znode_factory.h" /> <ClInclude Include="nodes\znode_factory.h" />
<ClInclude Include="nodes\znode_id.h" /> <ClInclude Include="nodes\znode_id.h" />
<ClInclude Include="nodes\znode_iterator.h" /> <ClInclude Include="nodes\znode_iterator.h" />
@@ -166,10 +234,7 @@
<ClInclude Include="util\xqptrmaptor.h" /> <ClInclude Include="util\xqptrmaptor.h" />
<ClInclude Include="util\xsingleton.h" /> <ClInclude Include="util\xsingleton.h" />
<ClInclude Include="util\xtreewalker.h" /> <ClInclude Include="util\xtreewalker.h" />
<QtMoc Include="widgets\xqtreeview.h" />
<QtMoc Include="widgets\xqcontextmenu.h" /> <QtMoc Include="widgets\xqcontextmenu.h" />
<QtMoc Include="widgets\xqitemdelegate.h" />
<QtMoc Include="model\xqmodelview.h" />
<QtMoc Include="model\xqselectionmodel.h" /> <QtMoc Include="model\xqselectionmodel.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@@ -76,42 +76,21 @@
<ClCompile Include="model\xqcommand.cpp"> <ClCompile Include="model\xqcommand.cpp">
<Filter>Source Files\model</Filter> <Filter>Source Files\model</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="model\xqitem.cpp">
<Filter>Source Files\model</Filter>
</ClCompile>
<ClCompile Include="model\xqmodelview.cpp">
<Filter>Source Files\model</Filter>
</ClCompile>
<ClCompile Include="model\xqnode.cpp"> <ClCompile Include="model\xqnode.cpp">
<Filter>Source Files\model</Filter> <Filter>Source Files\model</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="application\xqmainmodelview.cpp">
<Filter>Source Files\application</Filter>
</ClCompile>
<ClCompile Include="application\xqmainwindow.cpp"> <ClCompile Include="application\xqmainwindow.cpp">
<Filter>Source Files\application</Filter> <Filter>Source Files\application</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="nodes\znode.cpp"> <ClCompile Include="nodes\znode.cpp">
<Filter>Source Files\nodes</Filter> <Filter>Source Files\nodes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="widgets\xqitemdelegate.cpp">
<Filter>Source Files\widgets</Filter>
</ClCompile>
<ClCompile Include="widgets\xqtreeview.cpp">
<Filter>Source Files\widgets</Filter>
</ClCompile>
<ClCompile Include="pugixml\pugixml.cpp"> <ClCompile Include="pugixml\pugixml.cpp">
<Filter>Source Files\pugixml</Filter> <Filter>Source Files\pugixml</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="model\xqmodelsections.cpp">
<Filter>Source Files\model</Filter>
</ClCompile>
<ClCompile Include="model\xqselectionmodel.cpp"> <ClCompile Include="model\xqselectionmodel.cpp">
<Filter>Source Files\model</Filter> <Filter>Source Files\model</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="application\xqchildmodelview.cpp">
<Filter>Source Files\application</Filter>
</ClCompile>
<ClCompile Include="model\xqsimpleclipboard.cpp"> <ClCompile Include="model\xqsimpleclipboard.cpp">
<Filter>Source Files\model</Filter> <Filter>Source Files\model</Filter>
</ClCompile> </ClCompile>
@@ -127,21 +106,9 @@
<ClCompile Include="model\xqnodewriter.cpp"> <ClCompile Include="model\xqnodewriter.cpp">
<Filter>Source Files\model</Filter> <Filter>Source Files\model</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="model\xqitemfactory.cpp">
<Filter>Source Files\model</Filter>
</ClCompile>
<ClCompile Include="application\xqappdata.cpp"> <ClCompile Include="application\xqappdata.cpp">
<Filter>Source Files\application</Filter> <Filter>Source Files\application</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="model\xqitemtypefactory.cpp">
<Filter>Source Files\model</Filter>
</ClCompile>
<ClCompile Include="model\xqitemtype.cpp">
<Filter>Source Files\model</Filter>
</ClCompile>
<ClCompile Include="items\xqgenericitem.cpp">
<Filter>Source Files\Items</Filter>
</ClCompile>
<ClCompile Include="items\xqitem.cpp"> <ClCompile Include="items\xqitem.cpp">
<Filter>Source Files\Items</Filter> <Filter>Source Files\Items</Filter>
</ClCompile> </ClCompile>
@@ -154,6 +121,24 @@
<ClCompile Include="items\xqitemtype.cpp"> <ClCompile Include="items\xqitemtype.cpp">
<Filter>Source Files\Items</Filter> <Filter>Source Files\Items</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="model\xqsectionmanager.cpp">
<Filter>Source Files\model</Filter>
</ClCompile>
<ClCompile Include="model\xqviewmodel.cpp">
<Filter>Source Files\model</Filter>
</ClCompile>
<ClCompile Include="widgets\xqquickwidget.cpp">
<Filter>Source Files\widgets</Filter>
</ClCompile>
<ClCompile Include="widgets\xqtreetable.cpp">
<Filter>Source Files\widgets</Filter>
</ClCompile>
<ClCompile Include="application\xqchildmodel.cpp">
<Filter>Source Files\application</Filter>
</ClCompile>
<ClCompile Include="application\xqmainmodel.cpp">
<Filter>Source Files\application</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="model\xqcommand.h"> <ClInclude Include="model\xqcommand.h">
@@ -183,9 +168,6 @@
<ClInclude Include="pugixml\pugixml.hpp"> <ClInclude Include="pugixml\pugixml.hpp">
<Filter>Header Files\pugixml</Filter> <Filter>Header Files\pugixml</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="model\xqmodelsections.h">
<Filter>Header Files\model</Filter>
</ClInclude>
<ClInclude Include="util\xqmapindex.h"> <ClInclude Include="util\xqmapindex.h">
<Filter>Header Files\util</Filter> <Filter>Header Files\util</Filter>
</ClInclude> </ClInclude>
@@ -216,12 +198,6 @@
<ClInclude Include="nodes\znode_payload.h"> <ClInclude Include="nodes\znode_payload.h">
<Filter>Header Files\nodes</Filter> <Filter>Header Files\nodes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="nodes\znode_attributes.h">
<Filter>Header Files\nodes</Filter>
</ClInclude>
<ClInclude Include="items\xqgenericitem.h">
<Filter>Header Files\items</Filter>
</ClInclude>
<ClInclude Include="items\xqitem.h"> <ClInclude Include="items\xqitem.h">
<Filter>Header Files\items</Filter> <Filter>Header Files\items</Filter>
</ClInclude> </ClInclude>
@@ -234,33 +210,36 @@
<ClInclude Include="items\xqitemtype.h"> <ClInclude Include="items\xqitemtype.h">
<Filter>Header Files\items</Filter> <Filter>Header Files\items</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="model\xqsectionmanager.h">
<Filter>Header Files\model</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="model\xqmodelview.h">
<Filter>Header Files\model</Filter>
</QtMoc>
<QtMoc Include="application\xqmainmodelview.h">
<Filter>Header Files\application</Filter>
</QtMoc>
<QtMoc Include="application\xqmainwindow.h"> <QtMoc Include="application\xqmainwindow.h">
<Filter>Header Files\application</Filter> <Filter>Header Files\application</Filter>
</QtMoc> </QtMoc>
<QtMoc Include="widgets\xqitemdelegate.h">
<Filter>Header Files\widgets</Filter>
</QtMoc>
<QtMoc Include="widgets\xqtreeview.h">
<Filter>Header Files\widgets</Filter>
</QtMoc>
<QtMoc Include="widgets\xqcontextmenu.h"> <QtMoc Include="widgets\xqcontextmenu.h">
<Filter>Header Files\widgets</Filter> <Filter>Header Files\widgets</Filter>
</QtMoc> </QtMoc>
<QtMoc Include="model\xqselectionmodel.h"> <QtMoc Include="model\xqselectionmodel.h">
<Filter>Header Files\model</Filter> <Filter>Header Files\model</Filter>
</QtMoc> </QtMoc>
<QtMoc Include="application\xqchildmodelview.h"> <QtMoc Include="application\xqdocumentstore.h">
<Filter>Header Files\application</Filter> <Filter>Header Files\application</Filter>
</QtMoc> </QtMoc>
<QtMoc Include="application\xqdocumentstore.h"> <QtMoc Include="model\xqviewmodel.h">
<Filter>Header Files\model</Filter>
</QtMoc>
<QtMoc Include="widgets\xqquickwidget.h">
<Filter>Header Files\widgets</Filter>
</QtMoc>
<QtMoc Include="widgets\xqtreetable.h">
<Filter>Header Files\widgets</Filter>
</QtMoc>
<QtMoc Include="application\xqchildmodel.h">
<Filter>Header Files\application</Filter>
</QtMoc>
<QtMoc Include="application\xqmainmodel.h">
<Filter>Header Files\application</Filter> <Filter>Header Files\application</Filter>
</QtMoc> </QtMoc>
</ItemGroup> </ItemGroup>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<QtTouchProperty>
</QtTouchProperty>
</PropertyGroup>
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<QtTouchProperty>
</QtTouchProperty>
</PropertyGroup>
</Project>

View File

@@ -10,21 +10,20 @@
<Panel PanelID="#4 JA 04" FriendlyName="@PanelName" PanelName="JA 04 Solar X58C" Manufacturer="JA Solar 4" WattPeak="440" Height="1,70" Width="1,10" Weight="12" MaxVolt="42" MaxAmpere="11"/> <Panel PanelID="#4 JA 04" FriendlyName="@PanelName" PanelName="JA 04 Solar X58C" Manufacturer="JA Solar 4" WattPeak="440" Height="1,70" Width="1,10" Weight="12" MaxVolt="42" MaxAmpere="11"/>
<Panel PanelID="#5 JA 05" FriendlyName="@PanelName" PanelName="JA 05 Solar X58C" Manufacturer="JA Solar 5" WattPeak="440" Height="1,70" Width="1,10" Weight="12" MaxVolt="42" MaxAmpere="11"/> <Panel PanelID="#5 JA 05" FriendlyName="@PanelName" PanelName="JA 05 Solar X58C" Manufacturer="JA Solar 5" WattPeak="440" Height="1,70" Width="1,10" Weight="12" MaxVolt="42" MaxAmpere="11"/>
<Panel PanelID="#6 JA 06" FriendlyName="@PanelName" PanelName="JA 06 Solar X58C" Manufacturer="JA Solar 6" WattPeak="440" Height="1,70" Width="1,10" Weight="12" MaxVolt="42" MaxAmpere="11"/> <Panel PanelID="#6 JA 06" FriendlyName="@PanelName" PanelName="JA 06 Solar X58C" Manufacturer="JA Solar 6" WattPeak="440" Height="1,70" Width="1,10" Weight="12" MaxVolt="42" MaxAmpere="11"/>
<Inverter InverterID="#1 HM600 01" FriendlyName="@InverterName" InverterName="01 HM600 S2 TMax" Manufacturer="HoyMiles" MaxPowerInput="2000" MaxPowerInputChoice="2000;4000;6000" MaxPowerOutput="600" NumStrings="2" Weight="28"/> <Inverter InverterID="#1 HM600 01" FriendlyName="@InverterName" InverterName="01 HM600 S2 TMax" Manufacturer="HoyMiles" MaxPowerInput="3000,00" MaxPowerInputChoice="2000;4000;6000" MaxPowerOutput="600" NumStrings="2" Weight="28"/>
<Inverter InverterID="#2 HM800 02" FriendlyName="@InverterName" InverterName="02 HM800 S2 TMax" Manufacturer="HoyMiles" MaxPowerInput="4000" MaxPowerInputChoice="2000;4000;6000" MaxPowerOutput="800" NumStrings="2" Weight="29"/> <Inverter InverterID="#2 HM800 02" FriendlyName="@InverterName" InverterName="02 HM800 S2 TMax" Manufacturer="HoyMiles" MaxPowerInput="4000" MaxPowerInputChoice="4000;6000;8000" MaxPowerOutput="800" NumStrings="2" Weight="29"/>
<Inverter InverterID="#3 HM1600 03" FriendlyName="@InverterName" InverterName="03 HM1600 S4 TMax" Manufacturer="HoyMiles" MaxPowerInput="6000" MaxPowerInputChoice="2000;4000;6000" MaxPowerOutput="1600" NumStrings="4" Weight="32"/> <Inverter InverterID="#3 HM1600 03" FriendlyName="@InverterName" InverterName="03 HM1600 S4 TMax" Manufacturer="HoyMiles" MaxPowerInput="9000,00" MaxPowerInputChoice="6000;8000;10000" MaxPowerOutput="1600" NumStrings="4" Weight="32"/>
<Inverter InverterID="#4 D12K 04" FriendlyName="@InverterName" InverterName="04 HM600 S2 TMax" Manufacturer="Deye" MaxPowerInput="12000,33" MaxPowerInputChoice="6000;8000;12000" MaxPowerOutput="600" NumStrings="2" Weight="28"/> <Inverter InverterID="#4 D12K 04" FriendlyName="@InverterName" InverterName="04 HM600 S2 TMax" Manufacturer="Deye" MaxPowerInput="8000" MaxPowerInputChoice="6000;8000;12000" MaxPowerOutput="600" NumStrings="2" Weight="28"/>
<Battery BatteryID="#1 BYD 01" FriendlyName="@BatteryName" BatteryName="01 BYD T01 Stackable" Manufacturer="BYD" Capacity="4500" Yield="90" MaxCurrent="120" MaxVolt="48"> <Battery BatteryID="#1 BYD 01" FriendlyName="@BatteryName" BatteryName="01 BYD T01 Stackable" Manufacturer="BYD" Capacity="4500" Yield="90" MaxCurrent="120" MaxVolt="48">
<AdditionalData DataItem="Image" DataValue="image.png"/> <Images FrontView="image.png" PackageView="package.png" InstalledView="installed.png"/>
<AdditionalData DataItem="Manual" DataValue="manual.docx"/> <Documents Manual="manual.docx" Certificate="certificate.pdf"/>
<AdditionalData DataItem="Certificate" DataValue="certificate.pdf"/>
</Battery> </Battery>
<Battery BatteryID="#2 BYD 02" FriendlyName="@BatteryName" BatteryName="02 BYD T02 Stackable" Manufacturer="BYD" Capacity="9000" Yield="94" MaxCurrent="120" MaxVolt="48"/> <Battery BatteryID="#2 BYD 02" FriendlyName="@BatteryName" BatteryName="02 BYD T02 Stackable" Manufacturer="BYD" Capacity="9000" Yield="94" MaxCurrent="120" MaxVolt="48"/>
<Battery BatteryID="#3 BYD 03" FriendlyName="@BatteryName" BatteryName="03 BYD T01 Stackable" Manufacturer="BYD" Capacity="4500" Yield="86" MaxCurrent="120" MaxVolt="48"/> <Battery BatteryID="#3 BYD 03" FriendlyName="@BatteryName" BatteryName="03 BYD T01 Stackable" Manufacturer="BYD" Capacity="4500" Yield="86" MaxCurrent="120" MaxVolt="48"/>
<Battery BatteryID="#4 BYD 04" FriendlyName="@BatteryName" BatteryName="04 BYD T02 Stackable" Manufacturer="BYD" Capacity="9000" Yield="98" MaxCurrent="120" MaxVolt="48"/> <Battery BatteryID="#4 BYD 04" FriendlyName="@BatteryName" BatteryName="04 BYD T02 Stackable" Manufacturer="BYD" Capacity="9000" Yield="91" MaxCurrent="120" MaxVolt="48"/>
<Battery BatteryID="#5 GroWatt 05 G2K" FriendlyName="@BatteryName" BatteryName="05 BYD T01 Stackable" Manufacturer="GroWatt" Capacity="4500" Yield="94" MaxCurrent="120" MaxVolt="48"/> <Battery BatteryID="#5 GroWatt 05 G2K" FriendlyName="@BatteryName" BatteryName="05 BYD T01 Stackable" Manufacturer="GroWatt" Capacity="4500" Yield="94" MaxCurrent="120" MaxVolt="48"/>
<Battery BatteryID="#6 GroWatt 06 G4K" FriendlyName="@BatteryName" BatteryName="06 BYD T02 Stackable" Manufacturer="GroWatt" Capacity="9000" Yield="49" MaxCurrent="120" MaxVolt="48"/> <Battery BatteryID="#6 GroWatt 06 G4K" FriendlyName="@BatteryName" BatteryName="06 BYD T02 Stackable" Manufacturer="GroWatt" Capacity="9000" Yield="49" MaxCurrent="120" MaxVolt="48"/>
<Battery BatteryID="#7 Pyne 07 G4K" FriendlyName="@BatteryName" BatteryName="07 Pyne K7 Stackable" Manufacturer="PyNe" Capacity="9000" Yield="49" MaxCurrent="120" MaxVolt="48"/> <Battery BatteryID="#7 Pyne 07 G4K" FriendlyName="@BatteryName" BatteryName="07 Pyne K7 Stackable" Manufacturer="PyNe" Capacity="9000" Yield="68" MaxCurrent="120" MaxVolt="48"/>
</Components> </Components>
<IrgendWasAnderes> <IrgendWasAnderes>

View File

@@ -4,9 +4,9 @@
<Project ProjectID="HA02" FriendlyName="@ProjectName" ProjectName="Gerbrunn Ost" Established="2006" WattPeak="9840" ContentType="planned"> <Project ProjectID="HA02" FriendlyName="@ProjectName" ProjectName="Gerbrunn Ost" Established="2006" WattPeak="9840" ContentType="planned">
<Components> <Components>
<Panel PanelID="Jingli 01" FriendlyName="@PanelName" PanelName="Jingli 01 Solar T62B" Manufacturer="Jingli Solar" WattPeak="620" Height="2,70" Width="1,10" Weight="12" MaxVolt="67" MaxAmpere="11"> <Panel PanelID="Jingli 01" FriendlyName="@PanelName" PanelName="Jingli 01 Solar T62B" Manufacturer="Jingli Solar" WattPeak="620" Height="2,70" Width="1,10" Weight="12" MaxVolt="67" MaxAmpere="11">
<AdditionalData DataItem="Image" DataValue="image,png"/> <AdditionalData DataItem="Image" DataValue="image.png"/>
<AdditionalData DataItem="Manual" DataValue="manual,docx"/> <AdditionalData DataItem="Manual" DataValue="manual.docx"/>
<AdditionalData DataItem="Certificate" DataValue="certificate,pdf"/> <AdditionalData DataItem="Certificate" DataValue="certificate.pdf"/>
</Panel> </Panel>
<Panel PanelID="Jingli 02" FriendlyName="@PanelName" PanelName="Jingli 02 Solar X58C" Manufacturer="Jingli Solar" WattPeak="440" Height="1,70" Width="1,10" Weight="12" MaxVolt="42" MaxAmpere="11"/> <Panel PanelID="Jingli 02" FriendlyName="@PanelName" PanelName="Jingli 02 Solar X58C" Manufacturer="Jingli Solar" WattPeak="440" Height="1,70" Width="1,10" Weight="12" MaxVolt="42" MaxAmpere="11"/>
<Panel PanelID="Jingli 03" FriendlyName="@PanelName" PanelName="Jingli 03 Solar T62B" Manufacturer="Jingli Solar" WattPeak="620" Height="2,70" Width="1,10" Weight="12" MaxVolt="67" MaxAmpere="11"/> <Panel PanelID="Jingli 03" FriendlyName="@PanelName" PanelName="Jingli 03 Solar T62B" Manufacturer="Jingli Solar" WattPeak="620" Height="2,70" Width="1,10" Weight="12" MaxVolt="67" MaxAmpere="11"/>

View File

@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<Project ProjectID="HA03" FriendlyName="@ProjectName" ProjectName="Neubrunn Süd" Established="2006" WattPeak="9840" ContentType="runnning"> <Project ProjectID="HA03" FriendlyName="@ProjectName" ProjectName="Tauberbischoffsheim SÜD" Established="2006" WattPeak="9840" ContentType="runnning">
<Components> <Components>
<Panel PanelID="AIKO 01" FriendlyName="@PanelName" PanelName="AIKO 01 Solar T62B" Manufacturer="AIKO Solar" WattPeak="620" Height="2,70" Width="1,10" Weight="12" MaxVolt="67" MaxAmpere="11"> <Panel PanelID="AIKO 01" FriendlyName="@PanelName" PanelName="AIKO 01 Solar T62B" Manufacturer="AIKO Solar" WattPeak="620" Height="2,70" Width="1,10" Weight="12" MaxVolt="67" MaxAmpere="11">
<AdditionalData DataItem="Image" DataValue="image.png"/> <AdditionalData DataItem="Image" DataValue="image.png"/>

View File

@@ -6,28 +6,29 @@
--> -->
<ItemTypes> <ItemTypes>
<TreeParentType RenderStyle="PlainStyle" ItemFlags="IsEnabled|IsDropEnabled" Icon="DirIcon" /> <TreeParentType RenderStyle="PlainStyle" EditorType="LineEditType" ItemFlags="IsEnabled|IsDropEnabled" Icon="DirIcon" />
<TreeSectionType RenderStyle="PlainStyle" ItemFlags="IsEnabled" Icon="DesktopIcon"/> <TreeChildType RenderStyle="PlainStyle" EditorType="LineEditType" ItemFlags="IsEnabled" Icon="MediaPlay"/>
<TreeChildType RenderStyle="PlainStyle" ItemFlags="IsUserCheckable|IsEnabled" Icon="MediaPlay"/> <TreeSectionType RenderStyle="PlainStyle" EditorType="LineEditType" ItemFlags="IsUserCheckable|IsEnabled" Icon="DesktopIcon"/>
<HeaderType RenderStyle="HeaderStyle" ItemFlags="IsEnabled"/> <HeaderType RenderStyle="HeaderStyle" EditorType="LineEditType" ItemFlags="IsEnabled"/>
<HiddenType RenderStyle="HiddenStyle"/> <HiddenType RenderStyle="HiddenStyle"/>
<StaticType RenderStyle="PlainStyle"/> <StaticType RenderStyle="PlainStyle"/>
<PlainType RenderStyle="PlainStyle" ItemFlags="IsEnabled|IsEditable|IsSelectable"/> <PlainType RenderStyle="PlainStyle" EditorType="LineEditType" ItemFlags="IsEnabled|IsEditable|IsSelectable"/>
<ValueType RenderStyle="FormattedStyle" ItemFlags="IsEnabled|IsEditable|IsSelectable" UnitType="Coulomb"/> <ValueType RenderStyle="FormattedStyle" EditorType="LineEditType" ItemFlags="IsEnabled|IsEditable|IsSelectable" UnitType="Coulomb"/>
<CheckableType RenderStyle="FormattedStyle" ItemFlags="IsEnabled|IsEditable|IsSelectable" UnitType="###"/> <CheckableType RenderStyle="FormattedStyle" EditorType="LineEditType" ItemFlags="IsEnabled|IsEditable|IsSelectable" />
<PercentageType RenderStyle="ProgressBarStyle" ItemFlags="IsEnabled|IsSelectable"/> <PercentageType RenderStyle="ColorBarStyle" EditorType="ColorBarType" ItemFlags="IsEnabled|IsEditable|IsSelectable" UnitType="%"/>
<ChoiceType RenderStyle="ComboBoxStyle" ItemFlags="IsEnabled|IsSelectable|IsEditable" FixedChoices="la|le|lo|lu"/> <ChoiceType RenderStyle="ComboBoxStyle" EditorType="ComboBoxType" ItemFlags="IsEnabled|IsEditable|IsSelectable" UnitType="W" FixedChoices="2000|4000|6000|8000" />
<IntValueType RenderStyle="SpinBoxStyle" ItemFlags="IsEnabled|IsSelectable"/> <IntValueType RenderStyle="SpinBoxStyle" EditorType="SpinBoxType" ItemFlags="IsEnabled|IsEditable|IsSelectable"/>
</ItemTypes> </ItemTypes>
<DocumentTreeModel> <DocumentTreeModel>
<Section ContentType="runnning"> <Section ContentType="runnning">
<Header> <Header>
<Entry Caption="Active Projects" ItemType="TreeParentType"/> <Entry Caption="Active Projects" ItemType="TreeParentType"/>
</Header> </Header>
<ModelSheet firz="running"> <ModelSheet>
<Project Caption="@ProjectName" ItemType="TreeChildType"> <Project Caption="@ProjectName" ItemType="TreeChildType">
<CurrentSection ItemType="TreeSectionType"/> <CurrentSection ItemType="TreeSectionType"/>
</Project> </Project>
@@ -37,7 +38,7 @@
<Header> <Header>
<Entry Caption="Planned Projects" ItemType="TreeParentType"/> <Entry Caption="Planned Projects" ItemType="TreeParentType"/>
</Header> </Header>
<ModelSheet firz="planned"> <ModelSheet>
<Project Caption="@ProjectName" ItemType="TreeChildType"> <Project Caption="@ProjectName" ItemType="TreeChildType">
<CurrentSection ItemType="TreeSectionType"/> <CurrentSection ItemType="TreeSectionType"/>
</Project> </Project>
@@ -47,7 +48,7 @@
<Header> <Header>
<Entry Caption="Finished Projects" ItemType="TreeParentType"/> <Entry Caption="Finished Projects" ItemType="TreeParentType"/>
</Header> </Header>
<ModelSheet firz="finished"> <ModelSheet>
<Project Caption="@ProjectName" ItemType="TreeChildType"> <Project Caption="@ProjectName" ItemType="TreeChildType">
<CurrentSection ItemType="TreeSectionType"/> <CurrentSection ItemType="TreeSectionType"/>
</Project> </Project>
@@ -75,10 +76,10 @@
<!-- '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="PlainType"/>
<!-- '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"/> <WattPeak ItemType="ValueType" UnitType="Wp"/>
<Width ItemType="CheckableType" Icon="VistaShield" UnitType="m"/> <Width ItemType="ValueType" 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"/>
@@ -86,8 +87,7 @@
</ModelSheet> </ModelSheet>
</Section> </Section>
<Section ContentType="Inverter" >
<Section ContentType="Inverter" >
<Header > <Header >
<InverterID Caption="Inverter" ItemType="HeaderType" /> <InverterID Caption="Inverter" ItemType="HeaderType" />
<InverterName Caption="Name" ItemType="HeaderType" /> <InverterName Caption="Name" ItemType="HeaderType" />
@@ -98,20 +98,20 @@
<Weight Caption="Weight" ItemType="HeaderType" /> <Weight Caption="Weight" ItemType="HeaderType" />
</Header> </Header>
<ModelSheet> <ModelSheet>
<InverterID Caption="Inverter" ItemType="ValueType" /> <InverterID ItemType="PlainType" />
<InverterName Caption="Name" ItemType="ValueType" /> <InverterName ItemType="PlainType" />
<Manufacturer Caption="Manufacturer" ItemType="ValueType" /> <Manufacturer ItemType="PlainType" />
<MaxPowerInput Caption="max. Input" ItemType="ValueType" ItemType="ChoiceType" ChoiceModelSheetSource="MaxPowerInputChoice" UnitType="W"/> <MaxPowerInput ItemType="ChoiceType" FixedChoices="2000|4000|6000|8000" UnitType="W"/>
<MaxPowerOutput Caption="max Output" ItemType="ValueType" UnitType="W"/> <MaxPowerOutput ItemType="ValueType" UnitType="W"/>
<NumStrings Caption="Strings" ItemType="ValueType" /> <NumStrings ItemType="IntValueType" />
<Weight Caption="Weight" ItemType="ValueType" UnitType="kg"/> <Weight ItemType="ValueType" UnitType="kg"/>
</ModelSheet> </ModelSheet>
</Section> </Section>
<Section ContentType="Battery" > <Section ContentType="Battery" >
<Header> <Header>
<BatteryID Caption="Name" ItemType="HeaderType" /> <BatteryID Caption="Battery" ItemType="HeaderType" />
<BatteryName Caption="Battery" ItemType="HeaderType" /> <BatteryName Caption="Name" ItemType="HeaderType" />
<Manufacturer Caption="Manufacturer" ItemType="HeaderType" /> <Manufacturer Caption="Manufacturer" ItemType="HeaderType" />
<Capacity Caption="Capacity" ItemType="HeaderType"/> <Capacity Caption="Capacity" ItemType="HeaderType"/>
<Yield Caption="Yield" ItemType="HeaderType" /> <Yield Caption="Yield" ItemType="HeaderType" />
@@ -119,14 +119,24 @@
<MaxVolt Caption="max. Volt" ItemType="HeaderType" /> <MaxVolt Caption="max. Volt" ItemType="HeaderType" />
</Header> </Header>
<ModelSheet> <ModelSheet>
<BatteryID Caption="Battery" ItemType="ValueType" /> <BatteryID ItemType="PlainType" />
<BatteryName Caption="Name" ItemType="ValueType" /> <BatteryName ItemType="PlainType" />
<Manufacturer Caption="Manufacturer" ItemType="ValueType" /> <Manufacturer ItemType="PlainType" />
<Capacity Caption="Capacity" ItemType="ValueType" UnitType="Wh"/> <Capacity ItemType="ValueType" UnitType="Wh"/>
<Yield Caption="Yield" ItemType="ValueType" ItemType="PercentageType" UnitType="%"/> <Yield ItemType="PercentageType" UnitType="%"/>
<MaxCurrent Caption="max. Current" ItemType="ValueType" UnitType="A"/> <MaxCurrent ItemType="ValueType" UnitType="A">
<MaxVolt Caption="max. Volt" ItemType="ValueType" UnitType="V"/> <SubType ItemType="PlainType"/>
</MaxCurrent>
<MaxVolt ItemType="ValueType" UnitType="V"/>
<firz ItemType="PlainType"/>
<Image DataValue="image.png" ItemType="PlainType"/>
<Manual DataValue="manual.docx" ItemType="PlainType"/>
<Certificate DataValue="certificate.pdf" ItemType="PlainType"/>
</ModelSheet> </ModelSheet>
</Section> </Section>
</DocumentDetailsModel> </DocumentDetailsModel>

View File

@@ -1,27 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Project Established="2006" FriendlyName="@ProjectName" ProjectID="HA01" ProjectName="Wiebelbach West" State="runnning" WattPeak="84000"> <Components>
<Components> <Panel FriendlyName="@PanelName" Height="2,70" Manufacturer="JA Solar 1 XX" MaxAmpere="11" MaxVolt="67" PanelID="#1 JA 01" PanelName="JA 01 Solar T62B" WattPeak="620" Weight="12" Width="1,10"/>
<Panel FriendlyName="@PanelName" Height="2,70" Manufacturer="JA Solar 1 XX" MaxAmpere="11" MaxVolt="67" PanelID="#1 JA 01" PanelName="JA 01 Solar T62B" WattPeak="620" Weight="12" Width="1,10"/> <Panel FriendlyName="@PanelName" Height="1,70" Manufacturer="JA Solar 2" MaxAmpere="11" MaxVolt="42" PanelID="#2 JA 02" PanelName="JA 02 Solar X58C" WattPeak="440" Weight="12" Width="1,10"/>
<Panel FriendlyName="@PanelName" Height="1,70" Manufacturer="JA Solar 2" MaxAmpere="11" MaxVolt="42" PanelID="#2 JA 02" PanelName="JA 02 Solar X58C" WattPeak="440" Weight="12" Width="1,10"/> <Panel FriendlyName="@PanelName" Height="2,70" Manufacturer="JA Solar 3" MaxAmpere="11" MaxVolt="67" PanelID="#3 JA 03" PanelName="JA 03 Solar T62B" WattPeak="620" Weight="12" Width="1,10"/>
<Panel FriendlyName="@PanelName" Height="2,70" Manufacturer="JA Solar 3" MaxAmpere="11" MaxVolt="67" PanelID="#3 JA 03" PanelName="JA 03 Solar T62B" WattPeak="620" Weight="12" Width="1,10"/> <Panel FriendlyName="@PanelName" Height="1,70" Manufacturer="JA Solar 4" MaxAmpere="11" MaxVolt="42" PanelID="#4 JA 04" PanelName="JA 04 Solar X58C" WattPeak="440" Weight="12" Width="1,10"/>
<Panel FriendlyName="@PanelName" Height="1,70" Manufacturer="JA Solar 4" MaxAmpere="11" MaxVolt="42" PanelID="#4 JA 04" PanelName="JA 04 Solar X58C" WattPeak="440" Weight="12" Width="1,10"/> <Panel FriendlyName="@PanelName" Height="1,70" Manufacturer="JA Solar 5" MaxAmpere="11" MaxVolt="42" PanelID="#5 JA 05" PanelName="JA 05 Solar X58C" WattPeak="440" Weight="12" Width="1,10"/>
<Panel FriendlyName="@PanelName" Height="1,70" Manufacturer="JA Solar 5" MaxAmpere="11" MaxVolt="42" PanelID="#5 JA 05" PanelName="JA 05 Solar X58C" WattPeak="440" Weight="12" Width="1,10"/> <Panel FriendlyName="@PanelName" Height="1,70" Manufacturer="JA Solar 6" MaxAmpere="11" MaxVolt="42" PanelID="#6 JA 06" PanelName="JA 06 Solar X58C" WattPeak="440" Weight="12" Width="1,10"/>
<Panel FriendlyName="@PanelName" Height="1,70" Manufacturer="JA Solar 6" MaxAmpere="11" MaxVolt="42" PanelID="#6 JA 06" PanelName="JA 06 Solar X58C" WattPeak="440" Weight="12" Width="1,10"/> <Inverter FriendlyName="@InverterName" InverterID="#1 HM600 01" InverterName="01 HM600 S2 TMax" Manufacturer="HoyMiles" MaxPowerInput="3000,00" MaxPowerInputChoice="2000;4000;6000" MaxPowerOutput="600" NumStrings="2" Weight="28"/>
<Inverter FriendlyName="@InverterName" InverterID="#1 HM600 01" InverterName="01 HM600 S2 TMax" Manufacturer="HoyMiles" MaxPowerInput="2000" MaxPowerInputChoice="2000;4000;6000" MaxPowerOutput="600" NumStrings="2" Weight="28"/> <Inverter FriendlyName="@InverterName" InverterID="#2 HM800 02" InverterName="02 HM800 S2 TMax" Manufacturer="HoyMiles" MaxPowerInput="4000" MaxPowerInputChoice="4000;6000;8000" MaxPowerOutput="800" NumStrings="2" Weight="29"/>
<Inverter FriendlyName="@InverterName" InverterID="#2 HM800 02" InverterName="02 HM800 S2 TMax" Manufacturer="HoyMiles" MaxPowerInput="4000" MaxPowerInputChoice="2000;4000;6000" MaxPowerOutput="800" NumStrings="2" Weight="29"/> <Inverter FriendlyName="@InverterName" InverterID="#3 HM1600 03" InverterName="03 HM1600 S4 TMax" Manufacturer="HoyMiles" MaxPowerInput="9000,00" MaxPowerInputChoice="6000;8000;10000" MaxPowerOutput="1600" NumStrings="4" Weight="32"/>
<Inverter FriendlyName="@InverterName" InverterID="#3 HM1600 03" InverterName="03 HM1600 S4 TMax" Manufacturer="HoyMiles" MaxPowerInput="6000" MaxPowerInputChoice="2000;4000;6000" MaxPowerOutput="1600" NumStrings="4" Weight="32"/> <Inverter FriendlyName="@InverterName" InverterID="#4 D12K 04" InverterName="04 HM600 S2 TMax" Manufacturer="Deye" MaxPowerInput="8000" MaxPowerInputChoice="6000;8000;12000" MaxPowerOutput="600" NumStrings="2" Weight="28"/>
<Inverter FriendlyName="@InverterName" InverterID="#4 D12K 04" InverterName="04 HM600 S2 TMax" Manufacturer="Deye" MaxPowerInput="12000,33" MaxPowerInputChoice="6000;8000;12000" MaxPowerOutput="600" NumStrings="2" Weight="28"/> <Battery BatteryID="#1 BYD 01" BatteryName="01 BYD T01 Stackable" Capacity="4500" FriendlyName="@BatteryName" Manufacturer="BYD" MaxCurrent="120" MaxVolt="48" Yield="90">
<Battery BatteryID="#1 BYD 01" BatteryName="01 BYD T01 Stackable" Capacity="4500" FriendlyName="@BatteryName" Manufacturer="BYD" MaxCurrent="120" MaxVolt="48" Yield="90"> <Images FrontView="image.png" InstalledView="installed.png" PackageView="package.png"/>
<AdditionalData DataItem="Image" DataValue="image.png"/> <Documents Certificate="certificate.pdf" Manual="manual.docx"/>
<AdditionalData DataItem="Manual" DataValue="manual.docx"/> </Battery>
<AdditionalData DataItem="Certificate" DataValue="certificate.pdf"/> <Battery BatteryID="#2 BYD 02" BatteryName="02 BYD T02 Stackable" Capacity="9000" FriendlyName="@BatteryName" Manufacturer="BYD" MaxCurrent="120" MaxVolt="48" Yield="94"/>
</Battery> <Battery BatteryID="#3 BYD 03" BatteryName="03 BYD T01 Stackable" Capacity="4500" FriendlyName="@BatteryName" Manufacturer="BYD" MaxCurrent="120" MaxVolt="48" Yield="86"/>
<Battery BatteryID="#2 BYD 02" BatteryName="02 BYD T02 Stackable" Capacity="9000" FriendlyName="@BatteryName" Manufacturer="BYD" MaxCurrent="120" MaxVolt="48" Yield="94"/> <Battery BatteryID="#4 BYD 04" BatteryName="04 BYD T02 Stackable" Capacity="9000" FriendlyName="@BatteryName" Manufacturer="BYD" MaxCurrent="120" MaxVolt="48" Yield="91"/>
<Battery BatteryID="#3 BYD 03" BatteryName="03 BYD T01 Stackable" Capacity="4500" FriendlyName="@BatteryName" Manufacturer="BYD" MaxCurrent="120" MaxVolt="48" Yield="86"/> <Battery BatteryID="#5 GroWatt 05 G2K" BatteryName="05 BYD T01 Stackable" Capacity="4500" FriendlyName="@BatteryName" Manufacturer="GroWatt" MaxCurrent="120" MaxVolt="48" Yield="94"/>
<Battery BatteryID="#4 BYD 04" BatteryName="04 BYD T02 Stackable" Capacity="9000" FriendlyName="@BatteryName" Manufacturer="BYD" MaxCurrent="120" MaxVolt="48" Yield="98"/> <Battery BatteryID="#6 GroWatt 06 G4K" BatteryName="06 BYD T02 Stackable" Capacity="9000" FriendlyName="@BatteryName" Manufacturer="GroWatt" MaxCurrent="120" MaxVolt="48" Yield="49"/>
<Battery BatteryID="#5 GroWatt 05 G2K" BatteryName="05 BYD T01 Stackable" Capacity="4500" FriendlyName="@BatteryName" Manufacturer="GroWatt" MaxCurrent="120" MaxVolt="48" Yield="94"/> <Battery BatteryID="#7 Pyne 07 G4K" BatteryName="07 Pyne K7 Stackable" Capacity="9000" FriendlyName="@BatteryName" Manufacturer="PyNe" MaxCurrent="120" MaxVolt="48" Yield="68"/>
<Battery BatteryID="#6 GroWatt 06 G4K" BatteryName="06 BYD T02 Stackable" Capacity="9000" FriendlyName="@BatteryName" Manufacturer="GroWatt" MaxCurrent="120" MaxVolt="48" Yield="49"/> </Components>
<Battery BatteryID="#7 Pyne 07 G4K" BatteryName="07 Pyne K7 Stackable" Capacity="9000" FriendlyName="@BatteryName" Manufacturer="PyNe" MaxCurrent="120" MaxVolt="48" Yield="49"/>
</Components>
<IrgendWasAnderes/>
</Project>