/*************************************************************************** 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 #include #include #include #include #include #include #include XQMainWindow::XQMainWindow( QWidget* parent ) : QMainWindow(parent) { setupUi(this); setWindowTitle( QString("XTree %1").arg(c_Version)); initMainWindow(); } void XQMainWindow::initMainWindow() { qDebug() << " --- initMainWindow(): here we go!"; // als allererstes laden wir die Modelschreibungen XQItemFactory::instance().initItemFactory( c_ModelSheetFileName ); _undoView->setStack( &_undoStack ); _actionUndo->setData( XQCommand::cmdUndo); _actionRedo->setData( XQCommand::cmdRedo); _actionCut->setData( XQCommand::cmdCut); _actionCopy->setData( XQCommand::cmdCopy); _actionPaste->setData( XQCommand::cmdPaste); _actionNew->setData( XQCommand::cmdNew); _actionDelete->setData( XQCommand::cmdDelete); connect( _actionUndo, &QAction::triggered, this, &XQMainWindow::onUndo ); connect( _actionRedo, &QAction::triggered, this, &XQMainWindow::onRedo ); connect( _actionOpen, &QAction::triggered, this, &XQMainWindow::onOpenDocument ); connect( _actionSave, &QAction::triggered, this, &XQMainWindow::onSaveDocument ); connect( _actionSaveAs, &QAction::triggered, this, &XQMainWindow::onSaveDocumentAs ); connect( _actionExit, &QAction::triggered, this, &XQMainWindow::onExit ); connect( _actionAbout, &QAction::triggered, this, &XQMainWindow::onAbout ); //connect( _mainTreeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(onDoubleClicked(QModelIndex)) ); connect( _mainTreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(onTreeItemClicked(QModelIndex)) ); connect( _tabWidget, SIGNAL(tabBarClicked(int)), this, SLOT(onTabClicked(int)) ); connect( &_mainModelView, &XQViewModel::xqItemCreated, this, [=, this](XQItem* item) { // when a new main tree item has been created ... 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 { // hand over undostack _mainModelView.setUndoStack(&_undoStack); // hand over left side navigation tree _mainModelView.setTreeTable(_mainTreeView); // #1. init the left side main tree view _mainModelView.initModel( c_MainModelName ); // #2. load demo data loadDocument( c_DocumentFileName1 ); //loadDocument( c_DocumentFileName2 ); qDebug() << " --- all here: " << XQNode::s_Count; } catch( XQException& exception ) { qDebug() << exception.what(); QMessageBox::critical( this, "Failure", QString("Failure: %1").arg(exception.what()) ); } } void XQMainWindow::onUndo() { qDebug() << " --- undo Pressed"; if(_undoStack.canUndo()) _undoStack.undo(); } void XQMainWindow::onRedo() { qDebug() << " --- redo Pressed"; if(_undoStack.canRedo()) _undoStack.redo(); } void XQMainWindow::onCreateDocument() { qDebug() << " ---- create document Pressed!"; } void XQMainWindow::onOpenDocument() { QString fileName = QFileDialog::getOpenFileName(this, tr("Open Project"), c_DocumentDirectory, tr("project data(*.xtr)") ); QFile file(fileName); if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(this, "Warning", "Cannot load file: " + file.errorString()); return; } // close dummy file ... file.close(); loadDocument( fileName ); } void XQMainWindow::onSaveDocument() { qDebug() << " ---- save Pressed!"; saveDocument( c_ModelDummyFileName ); } void XQMainWindow::onSaveDocumentAs() { QString fileName = QFileDialog::getSaveFileName(this, "Save as", c_DocumentDirectory, tr("project data(*.xtr)") ); QFile file(fileName); // open dummy file if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString()); return; } // close dummy file ... file.close(); // and create a xml stream saveDocument( fileName ); } void XQMainWindow::onCloseDocument() { qDebug() << " ---- close Pressed!"; } void XQMainWindow::onExit() { qApp->exit(); } void XQMainWindow::onAbout() { QMessageBox msgBox(QMessageBox::NoIcon, "About", "", QMessageBox::Ok); QString text = "xtree concept
"; text += "2024 c.holzheuer

"; text += "sourceworx.org/xtree"; msgBox.setTextFormat(Qt::RichText); // This allows you to click the link msgBox.setText( text ); msgBox.exec(); } // when item in the left tree is clicked, switch view on the right side void XQMainWindow::onTreeItemClicked(const QModelIndex& index ) { XQItem& entry = XQItem::xqItemFromIndex(index); qDebug() << " --- mainWindow onTreeItemClicked:" << entry.text(); return; //_mainTreeView->selectionModel()->select(index, QItemSelectionModel::Select); //entry->setBackground( QBrush( Qt::green ) ); QString key = entry.attribute(c_ProjectID); if( _documentStore.contains(key) ) _tabWidget->setCurrentWidget( _documentStore[key].modelView->treeTable() ); } // when item in the left tree is clicked, switch view on the right side void XQMainWindow::onTabClicked( int index ) { const QString& key = _documentStore[index].treeItem->attribute( c_ProjectID ); qDebug() << " ---- tab clicked: " << index << " : " << _documentStore[index].friendlyName << ": " << key; _mainTreeView->setCurrentIndex( _documentStore[index].treeItem->index() ); } void XQMainWindow::loadDocument( const QString& fileName ) { //ntThrowIfNullPtr // gibts die Datei? if( !QFile::exists( fileName) ) throw XQException( "no such file", fileName ); // load data tree from xml file XQNodeFactory treeLoader; XQNodePtr rawTree = treeLoader.load_tree( qPrintable(fileName) ); // versteckten root node ignorieren XQNodePtr contentRoot = rawTree->first_child(); // Project-ID behandeln const QString& pID = contentRoot->attribute(c_ProjectID); int idx = _documentStore.indexOf( pID ); if( idx > -1 ) { const XQDocument& doc = _documentStore.at(idx); QMessageBox::warning( this, "Load Document", QString("File: %1 already loaded.").arg( fileName ) ); _mainTreeView->setCurrentIndex( doc.treeItem->index() ); _tabWidget->setCurrentIndex( idx ); return; } // 'friendly Name' ist ein Link auf ein anderes Attribute // das als Namen verwendet wird. const QString& fName = contentRoot->friendly_name(); QString pTitle = QString("Project %1: %2").arg( pID, fName ); // Eine neue TreeView erzeugn und im TabWidget parken. XQTreeTable* childTreeView = new XQTreeTable(_tabWidget); _tabWidget->addTab( childTreeView, pTitle ); _tabWidget->setCurrentWidget( childTreeView ); setWindowTitle( pTitle ); // Ein neues Child-Model erzeugen XQChildModel* childModel = new XQChildModel(this); // die Modelstruktur anlegen childModel->initModel( c_ChildModelName ); // Den globalen undo-stack ... childModel->setUndoStack(&_undoStack); // und die TreeView übergeben childModel->setTreeTable(childTreeView); // read the model data childModel->setContent( contentRoot->first_child() ); // create new entry in the left side main tree view XQItem* newEntry = _mainModelView.createTreeEntry( contentRoot ); _mainTreeView->setCurrentIndex( newEntry->index() ); _documentStore.addDocument( fileName, pTitle, newEntry, childModel ); } void XQMainWindow::saveDocument( const QString& fileName ) { XQNodeWriter nodeWriter; int curIdx = _tabWidget->currentIndex(); XQNodePtr rootNode = _documentStore[curIdx].treeItem->contentNode(); nodeWriter.dumpTree( rootNode, fileName ); }