added section signals
This commit is contained in:
@@ -87,10 +87,14 @@ void XQMainWindow::initMainWindow()
|
||||
|
||||
//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( _tabWidget, SIGNAL(tabBarClicked(int)), this, SLOT(onTabClicked(int)) );
|
||||
|
||||
connect( _tabWidget, SIGNAL(tabBarClicked(int)), this, SLOT(onTabClicked(int)) );
|
||||
|
||||
|
||||
connect( &_mainModelView, &XQViewModel::xqItemCreated, this, [=, this](XQItem* item)
|
||||
|
||||
/*
|
||||
connect( &_mainModelView, &XQViewModel::itemCreated, this, [=, this](XQItem* item)
|
||||
{
|
||||
// when a new main tree item has been created ...
|
||||
QString pID = item->contentNode()->attribute(c_ProjectID);
|
||||
@@ -99,6 +103,7 @@ void XQMainWindow::initMainWindow()
|
||||
if( _documentStore.contains( pID ) )
|
||||
_tabWidget->setCurrentWidget( _documentStore[pID].modelView->treeTable() );
|
||||
} );
|
||||
*/
|
||||
|
||||
try
|
||||
{
|
||||
@@ -266,6 +271,15 @@ void XQMainWindow::onTabClicked( int index )
|
||||
_mainTreeView->setCurrentIndex( _documentStore[index].treeItem->index() );
|
||||
}
|
||||
|
||||
void XQMainWindow::onSectionCreated( const XQModelSection* section )
|
||||
{
|
||||
qDebug() << " --- XXX section created: " << section->row();
|
||||
}
|
||||
|
||||
void XQMainWindow::onSectionToggled( const XQModelSection* section )
|
||||
{
|
||||
qDebug() << " --- XXX section toggled: " << section->row();
|
||||
}
|
||||
|
||||
//! liest eine XML datei namens 'fileName'
|
||||
|
||||
@@ -307,14 +321,22 @@ void XQMainWindow::loadDocument( const QString& fileName )
|
||||
|
||||
// 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
|
||||
bool c1 = connect( childModel, SIGNAL(sectionCreated(const XQModelSection*)), this, SLOT(onSectionCreated(const XQModelSection*)) );
|
||||
bool c2 = connect( childModel, SIGNAL(sectionToggled(const XQModelSection*)), this, SLOT(onSectionToggled(const XQModelSection*)) );
|
||||
|
||||
qDebug() << " --- EWTF: " << c1 << ":" << c2;
|
||||
|
||||
// model inhalte laden
|
||||
childModel->setContent( contentRoot->first_child() );
|
||||
|
||||
/*
|
||||
@@ -324,6 +346,10 @@ void XQMainWindow::loadDocument( const QString& fileName )
|
||||
_documentStore.addDocument( fileName, pTitle, newEntry, childModel );
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@@ -48,6 +48,10 @@ public slots:
|
||||
|
||||
void onTreeItemClicked(const QModelIndex& index );
|
||||
void onTabClicked( int index );
|
||||
//void onItemCreated( XQItem* item );
|
||||
void onSectionCreated( const XQModelSection* section);
|
||||
void onSectionToggled( const XQModelSection* section );
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
@@ -83,7 +83,7 @@ XQItemType* XQItemFactory::makeItemType(const XQNodePtr& sheetEntry )
|
||||
// wir prüfen, ob im sheetEntry noch zusätzliche attribute vorhanden
|
||||
// sind, die wir in dem itemType müssen
|
||||
|
||||
qDebug() << " --- makeItemType: " << sheetEntry->to_string();
|
||||
//qDebug() << " --- makeItemType: " << sheetEntry->to_string();
|
||||
|
||||
// über alle attribute
|
||||
for (const auto& attrEntry : sheetEntry->attributes())
|
||||
@@ -157,7 +157,7 @@ QVariant XQItemFactory::makeVariant( int dataRole, const QString& source ) const
|
||||
case XQItem::ItemTypeRole:
|
||||
{
|
||||
// itemType() -> XQItemType*
|
||||
qDebug() << " --- makeVariant: make ItemType: " << source;
|
||||
//qDebug() << " --- makeVariant: make ItemType: " << source;
|
||||
XQItemType* itemType = findItemTypeTemplate( source );
|
||||
value = QVariant::fromValue(itemType);
|
||||
break;
|
||||
@@ -179,7 +179,7 @@ QVariant XQItemFactory::makeVariant( int dataRole, const QString& source ) const
|
||||
|
||||
case XQItem::UnitTypeRole:
|
||||
{
|
||||
qDebug() << " --- make unit type: " << source;
|
||||
//qDebug() << " --- make unit type: " << source;
|
||||
XQItem::UnitType unitType = XQItem::fetchUnitType( source );
|
||||
value = QVariant::fromValue(unitType);
|
||||
break;
|
||||
@@ -281,7 +281,7 @@ XQItem* XQItemFactory::makeItem( const XQNodePtr& sheetNode, const XQNodePtr& co
|
||||
XQItem* newItem = new XQItem( itemType, contentPtr );
|
||||
if( newItem->isCheckable() )
|
||||
{
|
||||
qDebug() << " --- yooo: " << newItem->toolTip();
|
||||
//qDebug() << " --- yooo: " << newItem->toolTip();
|
||||
newItem->setCheckState( Qt::Checked );
|
||||
}
|
||||
|
||||
|
@@ -97,7 +97,7 @@ XQItemType* XQItemType::replaceAttribute( const QVariant& newValue, int role )
|
||||
msg = XQAppData::iconName( icn );
|
||||
}
|
||||
|
||||
qDebug() << " --- Before: " << makeItemTypeKey() << " role:" << XQItem::fetchItemDataRoleName(role) << " value:" << msg;
|
||||
//qDebug() << " --- Before: " << makeItemTypeKey() << " role:" << XQItem::fetchItemDataRoleName(role) << " value:" << msg;
|
||||
|
||||
// hat sich überhaupt was geändert?
|
||||
QVariant oldValue = data(role);
|
||||
@@ -124,9 +124,7 @@ XQItemType* XQItemType::replaceAttribute( const QVariant& newValue, int role )
|
||||
// speichern
|
||||
s_ItemTypeMap.insert( newKey, myClone );
|
||||
|
||||
|
||||
|
||||
qDebug() << " --- After: " << myClone->makeItemTypeKey();
|
||||
//qDebug() << " --- After: " << myClone->makeItemTypeKey();
|
||||
|
||||
/// Obacht! Der alte, geänderte itemType bleibt erhalten
|
||||
/// und verrottet ggf. ohne Daseinszweck
|
||||
|
@@ -41,6 +41,7 @@ struct XQModelSection
|
||||
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(XQModelSection)
|
||||
|
||||
/**
|
||||
* @brief Maptor containing all header sections.
|
||||
|
@@ -140,8 +140,13 @@ void XQViewModel::addSection(const XQItemList& list, const XQNodePtr& sheetNode
|
||||
// 5. das erzeugt dann auch valide indices
|
||||
appendRow(list);
|
||||
|
||||
// 6. jetzt können wir auch die sction erzeugen
|
||||
XQModelSection section(list[0]->index(), dataNode );
|
||||
_sections.addAtKey(sheetNode->attribute( c_ContentType), section);
|
||||
|
||||
// ... und es der welt mitteilen.
|
||||
emit sectionCreated( §ion );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -503,6 +508,7 @@ void XQViewModel::cmdToggleSection( XQCommand& command )
|
||||
for (int row = fstRow; row < lstRow; ++row )
|
||||
_treeTable->setRowHidden( row, _treeTable->rootIndex(), !hidden );
|
||||
|
||||
emit sectionToggled( &_sections.sectionFromIndex(index) );
|
||||
}
|
||||
|
||||
|
||||
|
599
src/model/xqviewmodel.cpp~RF540b760.TMP
Normal file
599
src/model/xqviewmodel.cpp~RF540b760.TMP
Normal file
@@ -0,0 +1,599 @@
|
||||
/***************************************************************************
|
||||
|
||||
source::worx xtree
|
||||
Copyright © 2024-2025 c.holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QUndoStack>
|
||||
|
||||
#include <xqexception.h>
|
||||
#include <xqviewmodel.h>
|
||||
#include <xqselectionmodel.h>
|
||||
#include <xqtreetable.h>
|
||||
#include <xqcommand.h>
|
||||
#include <xqitemdelegate.h>
|
||||
#include <xqitemfactory.h>
|
||||
#include <znode_factory.h>
|
||||
|
||||
|
||||
// create global dummy item as
|
||||
// fallback return value (klappt nicht)
|
||||
//Q_GLOBAL_STATIC(XQItem,s_dummyItem)
|
||||
|
||||
|
||||
//! hilfsfunkion, zeigt den string-content() für alle elemente der liste
|
||||
|
||||
void showItemList( const XQItemList& list)
|
||||
{
|
||||
for(const auto& entry : list )
|
||||
qDebug() << " --- itemList: " << ((XQItem*)entry)->content();
|
||||
qDebug();
|
||||
}
|
||||
|
||||
|
||||
//! Konstruktur mit parent.
|
||||
|
||||
XQViewModel::XQViewModel( QObject* parent )
|
||||
: QStandardItemModel{ parent }, _itemFactory{ XQItemFactory::instance() }
|
||||
{
|
||||
invisibleRootItem()->setData( "[rootItem]", Qt::DisplayRole );
|
||||
setItemPrototype( new XQItem );
|
||||
}
|
||||
|
||||
|
||||
//! gibt einen static-cast<QXItem*> auf 'invisibleRootItem()' zurück
|
||||
|
||||
const XQItem& XQViewModel::xqRootItem()
|
||||
{
|
||||
// das ist ein hack, denn 'invisibleRootItem()' ist und bleibt ein
|
||||
// QStandardItem. Trick: keine eigenen members in XQItem, alles
|
||||
// dynamisch über den ItemData Mechanismus wie in QStandardItem
|
||||
|
||||
return *static_cast<XQItem*>(invisibleRootItem());
|
||||
|
||||
}
|
||||
|
||||
|
||||
//! hifsfunktion, die das item zu einen index zurückgibt
|
||||
|
||||
XQItem& XQViewModel::xqItemFromIndex(const QModelIndex& index) const
|
||||
{
|
||||
if( index.isValid() )
|
||||
{
|
||||
QStandardItem* xqItem = QStandardItemModel::itemFromIndex(index);
|
||||
if( xqItem )
|
||||
return *static_cast<XQItem*>(xqItem);
|
||||
}
|
||||
return XQItem::fallBackDummyItem();
|
||||
}
|
||||
|
||||
//! hilfsfunktiom, die das erste xqitem einer zeile zurückgibt.
|
||||
|
||||
XQItem& XQViewModel::xqFirstItem(int row) const
|
||||
{
|
||||
return *static_cast<XQItem*>( QStandardItemModel::item(row) );
|
||||
}
|
||||
|
||||
|
||||
//! initialisiert dieses model über den namen. Es wird hier
|
||||
//! nur die strukur erzeugt, keine inhalte.
|
||||
|
||||
void XQViewModel::initModel(const QString& modelName)
|
||||
{
|
||||
/*
|
||||
model
|
||||
section
|
||||
header
|
||||
data
|
||||
section
|
||||
...
|
||||
|
||||
*/
|
||||
// model rootnode finden -> <DocumentTreeModel>
|
||||
XQNodePtr modelSheet = _itemFactory.findModelSheet( modelName ); // throws
|
||||
|
||||
// #1: über alle sections
|
||||
for( auto& section : modelSheet->children() )
|
||||
{
|
||||
// #2: (optionalen?) header erzeugen
|
||||
const XQNodePtr header = section->find_child_by_tag_name( "Header");
|
||||
if( header )
|
||||
{
|
||||
XQItemList list = _itemFactory.makeContentRow( header, nullptr );
|
||||
addSection(list, section );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! hilfsfunktion: fügt die liste unserem model hinzu und erzeugt eine 'section'.
|
||||
//! die section kann erst gültig sein, wenn die items im model gelandet sind,
|
||||
//! deswegen ist das hier zusammengefasst.
|
||||
|
||||
//! erzeugt dann eine section aus einer frisch erzeugten itemlist. der erste modelindex
|
||||
//! der liste und der unterknoten 'Data' werden gespeichert.
|
||||
|
||||
void XQViewModel::addSection(const XQItemList& list, const XQNodePtr& sheetNode )
|
||||
{
|
||||
// 1. die liste darf nicht leer sein
|
||||
Q_ASSERT(!list.isEmpty());
|
||||
// 2. sheetNode muss da sein
|
||||
Q_ASSERT(sheetNode);
|
||||
// 3. 'ContenType' muss vorhanden sein
|
||||
if( !sheetNode->has_attribute( c_ContentType) )
|
||||
throw XQException( "section list: Section node needs attribute 'ContentType'!");
|
||||
// 4. Data child muss auch da sein
|
||||
XQNodePtr dataNode = sheetNode->find_child_by_tag_name( c_Data );
|
||||
if( !dataNode )
|
||||
throw XQException( "section list: 'Data' child is missing!");
|
||||
|
||||
// 5. das erzeugt dann auch valide indices
|
||||
appendRow(list);
|
||||
|
||||
XQModelSection section(list[0]->index(), dataNode );
|
||||
_sections.addAtKey(sheetNode->attribute( c_ContentType), section);
|
||||
|
||||
emit sectionCreated( §ion );
|
||||
|
||||
}
|
||||
|
||||
|
||||
//! SLOT, der aufgerufen wird, wenn eine edit-action getriggert wurde.
|
||||
|
||||
void XQViewModel::onActionTriggered(QAction* action)
|
||||
{
|
||||
qDebug() << " --- onActionTriggered: count:" << XQNode::s_Count;
|
||||
|
||||
// all selected indices
|
||||
QModelIndexList selectionList = treeTable()->selectionModel()->selectedRows();
|
||||
// extract command type
|
||||
XQCommand::CmdType cmdType = action->data().value<XQCommand::CmdType>();
|
||||
|
||||
switch( cmdType )
|
||||
{
|
||||
// just handle undo ...
|
||||
case XQCommand::cmdUndo :
|
||||
return _undoStack->undo();
|
||||
|
||||
// ... or do/redo
|
||||
case XQCommand::cmdRedo :
|
||||
return _undoStack->redo();
|
||||
|
||||
// for copy & cut, we create a clone of the dataNodes in the clipboard
|
||||
case XQCommand::cmdCopy :
|
||||
case XQCommand::cmdCut :
|
||||
// don't 'copy' empty selections
|
||||
if( !selectionList.isEmpty() )
|
||||
_clipBoard.saveNodes( selectionList );
|
||||
// for copy, we are done, since copy cannot be undone
|
||||
if( cmdType == XQCommand::cmdCopy )
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// we create a command
|
||||
XQCommand* command = new XQCommand( cmdType, this );
|
||||
// store the row positions of the selected indices
|
||||
command->saveNodes( selectionList );
|
||||
command->setOriginIndex( treeTable()->currentIndex() );
|
||||
|
||||
// execute command
|
||||
_undoStack->push( command );
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
switch (command.commandType())
|
||||
{
|
||||
case XQCommand::cmdToggleSection:
|
||||
return cmdToggleSection( command.originIndex() );
|
||||
|
||||
case XQCommand::cmdCut:
|
||||
return cmdCut( command );
|
||||
|
||||
case XQCommand::cmdPaste:
|
||||
return cmdPaste( command );
|
||||
|
||||
case XQCommand::cmdNew:
|
||||
return cmdNew( command );
|
||||
|
||||
case XQCommand::cmdDelete:
|
||||
return cmdDelete( command );
|
||||
|
||||
case XQCommand::cmdMove:
|
||||
break;
|
||||
|
||||
default:
|
||||
qDebug() << " --- onCommandRedo: default: not handled: " << command.toString();
|
||||
}
|
||||
*/
|
||||
|
||||
//! führt die 'redo' action des gegebenen commnds aus.
|
||||
|
||||
void XQViewModel::onCommandRedo( XQCommand& command )
|
||||
{
|
||||
static MemCallMap redoCalls
|
||||
{
|
||||
{ XQCommand::cmdToggleSection, &XQViewModel::cmdToggleSection },
|
||||
{ XQCommand::cmdCut, &XQViewModel::cmdCut },
|
||||
{ XQCommand::cmdPaste, &XQViewModel::cmdPaste },
|
||||
{ XQCommand::cmdNew, &XQViewModel::cmdNew },
|
||||
{ XQCommand::cmdDelete, &XQViewModel::cmdDelete }
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
MemCall memCall = redoCalls[command.commandType()];
|
||||
if( memCall )
|
||||
(this->*memCall)( command );
|
||||
else
|
||||
qDebug() << " --- onCommandRedo: default: not handled: " << command.toString();
|
||||
}
|
||||
catch( XQException& exception )
|
||||
{
|
||||
qDebug() << exception.what();
|
||||
QMessageBox::critical( nullptr, "Failure", QString("Failure: %1").arg(exception.what()) );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
try
|
||||
{
|
||||
switch (command.commandType())
|
||||
{
|
||||
case XQCommand::cmdToggleSection:
|
||||
return cmdToggleSection( command.originIndex() );
|
||||
break;
|
||||
|
||||
// undo Cut -> perform undoCut
|
||||
case XQCommand::cmdCut:
|
||||
return cmdCutUndo( command );
|
||||
|
||||
// undo Paste -> perform Cut
|
||||
case XQCommand::cmdPaste:
|
||||
return cmdPasteUndo( command );
|
||||
|
||||
// undo Move -> perform move back
|
||||
case XQCommand::cmdMove:
|
||||
// not yet implemented
|
||||
break;
|
||||
|
||||
// undo New -> perform Delete
|
||||
case XQCommand::cmdNew:
|
||||
cmdNewUndo( command );
|
||||
break;
|
||||
|
||||
// undo Delete -> perform New
|
||||
case XQCommand::cmdDelete:
|
||||
qDebug() << " --- onCommandUndo: delete: " << command.toString();
|
||||
return cmdDeleteUndo( command );
|
||||
|
||||
default:
|
||||
qDebug() << " --- onCommandUndo: default: not handled: " << command.toString();
|
||||
}
|
||||
*/
|
||||
//! führt die 'undo' action des gegebenen commnds aus.
|
||||
|
||||
void XQViewModel::onCommandUndo( XQCommand& command )
|
||||
{
|
||||
qDebug() << " --- onCommandUndo: count: " << XQNode::s_Count;
|
||||
|
||||
static MemCallMap undoCalls
|
||||
{
|
||||
{ XQCommand::cmdToggleSection, &XQViewModel::cmdToggleSection },
|
||||
{ XQCommand::cmdCut, &XQViewModel::cmdCutUndo },
|
||||
{ XQCommand::cmdPaste, &XQViewModel::cmdPasteUndo },
|
||||
{ XQCommand::cmdNew, &XQViewModel::cmdNewUndo },
|
||||
{ XQCommand::cmdDelete, &XQViewModel::cmdDeleteUndo },
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
MemCall memCall = undoCalls[command.commandType()];
|
||||
if( memCall )
|
||||
(this->*memCall)( command );
|
||||
else
|
||||
qDebug() << " --- onCommandUndo: default: not handled: " << command.toString();
|
||||
}
|
||||
catch( XQException& exception )
|
||||
{
|
||||
qDebug() << exception.what();
|
||||
QMessageBox::critical( nullptr, "Failure", QString("Failure: %1").arg(exception.what()) );
|
||||
}
|
||||
}
|
||||
|
||||
// undo-/redo-able stuff
|
||||
|
||||
//! markierte knoten entfernen, 'command' enthält die liste
|
||||
|
||||
void XQViewModel::cmdCut( XQCommand& command )
|
||||
{
|
||||
// wir gehen rückwärts über alle gemerkten knoten ...
|
||||
for (auto it = command.rbegin(); it != command.rend(); ++it)
|
||||
{
|
||||
// ... holen das erste item, das auch den content node enthält
|
||||
//const XQNodeBackup& entry = *it;
|
||||
// jetzt löschen, dabei wird die parent-verbindung entfernt
|
||||
const XQNodeBackup& entry = *it;
|
||||
|
||||
XQItem& firstItem = xqFirstItem( (*it).itemPos );
|
||||
qDebug() << " --- Cut: " << firstItem.text() << " " << firstItem.row() << " id#" << entry.contentNode->_id;
|
||||
|
||||
entry.contentNode->unlink_self();
|
||||
removeRow(entry.itemPos );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! entfernte knoten wieder einfügen , 'command' enthält die liste
|
||||
|
||||
void XQViewModel::cmdCutUndo( XQCommand& command )
|
||||
{
|
||||
// die anfangsposition
|
||||
int itmPos = command.first().itemPos;
|
||||
// die 'zuständige' section rausfinden
|
||||
const XQModelSection& section = _sections.sectionFromRow( itmPos );
|
||||
// über alle einträge ...
|
||||
for (auto& entry : command )
|
||||
{
|
||||
const XQNodePtr& savedNode = entry.contentNode;
|
||||
// __fix! should not be _contentRoot!
|
||||
savedNode->add_me_at( entry.nodePos, _contentRoot );
|
||||
XQItemList list = _itemFactory.makeContentRow( section.sheetRootNode, savedNode );
|
||||
|
||||
XQItem& firstItem = *((XQItem*)list[0]);
|
||||
qDebug() << " --- Cut Undo: " << firstItem.text() << " " << firstItem.row() << " id#" << entry.contentNode->_id << " count: " << entry.contentNode.use_count();
|
||||
|
||||
insertRow( entry.itemPos, list );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! clipboard inhalte einfügen
|
||||
|
||||
void XQViewModel::cmdPaste( XQCommand& command )
|
||||
{
|
||||
// selection holen ...
|
||||
QItemSelectionModel* selectionModel = treeTable()->selectionModel();
|
||||
// ... und löschen
|
||||
selectionModel->clearSelection();
|
||||
|
||||
// aktuelles item finden
|
||||
const XQItem& item = xqItemFromIndex( command.originIndex() );
|
||||
|
||||
// die neue item position ist unter dem akutellen item
|
||||
int insRow = item.row()+1;
|
||||
int nodePos = item.contentNode()->own_pos()+1;
|
||||
|
||||
// die zugehörige section finden
|
||||
const XQModelSection& section = _sections.sectionFromRow( insRow-1 );
|
||||
// wir pasten das clipboard
|
||||
for (auto& entry : _clipBoard )
|
||||
{
|
||||
// noch ein clone vom clone erzeugen ...
|
||||
XQNodePtr newNode = entry.contentNode->clone(section.contentRootNode );
|
||||
newNode->clone(section.contentRootNode )->add_me_at( nodePos );
|
||||
// ... und damit eine frische item-row erzeugen
|
||||
XQItemList list = _itemFactory.makeContentRow( section.sheetRootNode, newNode );
|
||||
insertRow( insRow, list );
|
||||
// die neue item-row selektieren
|
||||
const QModelIndex& selIdx = list[0]->index();
|
||||
_treeTable->selectionModel()->select(selIdx, QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||
// zur nächsten zeile
|
||||
insRow++;
|
||||
nodePos++;
|
||||
}
|
||||
|
||||
// unsere änderungen merken fürs 'undo'
|
||||
command.saveNodes( selectionModel->selectedRows() );
|
||||
|
||||
}
|
||||
|
||||
|
||||
//! einfügen aus dem clipboard wieder rückgängig machen
|
||||
|
||||
void XQViewModel::cmdPasteUndo( XQCommand& command )
|
||||
{
|
||||
command.dumpList("Paste UNDO");
|
||||
// wir gehen rückwärts über alle markieren knoten ...
|
||||
for (auto it = command.rbegin(); it != command.rend(); ++it)
|
||||
{
|
||||
// ... holen das erste item, das auch den content node enthält
|
||||
const XQNodeBackup& entry = *it;
|
||||
XQItem& firstItem = xqFirstItem( (*it).itemPos );
|
||||
qDebug() << " --- Cut: " << firstItem.text() << " " << firstItem.row();
|
||||
// jetzt löschen
|
||||
entry.contentNode->unlink_self();
|
||||
removeRow(entry.itemPos );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// don't clone into clipboard, remove items
|
||||
|
||||
//! entfernen der selection ohne copy in clipboard.
|
||||
|
||||
void XQViewModel::cmdDelete( XQCommand& command )
|
||||
{
|
||||
// wir gehen rückwärts über alle markieren knoten ...
|
||||
for (auto it = command.rbegin(); it != command.rend(); ++it)
|
||||
{
|
||||
// ... holen das erste item, das auch den content node enthält
|
||||
const XQNodeBackup& entry = *it;
|
||||
XQItem& firstItem = xqFirstItem( (*it).itemPos );
|
||||
qDebug() << " --- Cut: " << firstItem.text() << " " << firstItem.row();
|
||||
// jetzt löschen
|
||||
entry.contentNode->unlink_self();
|
||||
removeRow(entry.itemPos );
|
||||
}
|
||||
}
|
||||
|
||||
//! macht 'delete' wirder rückgängig.
|
||||
|
||||
void XQViewModel::cmdDeleteUndo( XQCommand& command )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//! legt eine neue, leere zeile an.
|
||||
|
||||
void XQViewModel::cmdNew( XQCommand& command )
|
||||
{
|
||||
|
||||
// __fix
|
||||
/*
|
||||
const QModelIndex& origin = command.originIndex();
|
||||
if( !origin.isValid() )
|
||||
throw XQException("cmdNewRow failed: index not valid ");
|
||||
|
||||
XQItem* target = xqItemFromIndex( origin );
|
||||
// current data node
|
||||
XQNodePtr node = target->contentNode();
|
||||
|
||||
// we create a new data node
|
||||
//XQNodePtr newNode = new XQNodePtr( node->tag_name(), node->parent() );
|
||||
XQNodePtr newNode = XQNode::make_node( node->tag_name(), node->tag_value(), node->parent() );
|
||||
// store node in node->parent()
|
||||
//node->add_before_me( newNode );
|
||||
// store node also in 'command' to enable undo
|
||||
const XQModelSection& section = _sections.sectionFromIndex( origin );
|
||||
|
||||
// create new item row
|
||||
XQItemList list = _itemFactory.createGenericRow( newNode, section.sheetRootNode );
|
||||
|
||||
// add it to the treeview ...
|
||||
insertRow( origin.row(), list );
|
||||
|
||||
// ... and make it ...
|
||||
treeTable()->setCurrentIndex( list[0]->index() );
|
||||
// ... editable
|
||||
treeTable()->edit( list[0]->index() );
|
||||
*/
|
||||
}
|
||||
|
||||
//! entfernt die neu angelegte zeile.
|
||||
|
||||
void XQViewModel::cmdNewUndo( XQCommand& command )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//! schaltet eine section sichtbar oder unsichtbar.
|
||||
|
||||
void XQViewModel::cmdToggleSection( XQCommand& command )
|
||||
{
|
||||
const QModelIndex& index = command.originIndex();
|
||||
Q_ASSERT(index.isValid());
|
||||
|
||||
int fstRow = _sections.firstRow( index );
|
||||
int lstRow = _sections.lastRow( index );
|
||||
|
||||
bool hidden =_treeTable->isRowHidden( fstRow, _treeTable->rootIndex() );
|
||||
for (int row = fstRow; row < lstRow; ++row )
|
||||
_treeTable->setRowHidden( row, _treeTable->rootIndex(), !hidden );
|
||||
|
||||
}
|
||||
|
||||
|
||||
//! git die treetable zurück
|
||||
|
||||
XQTreeTable* XQViewModel::treeTable()
|
||||
{
|
||||
return _treeTable;
|
||||
}
|
||||
|
||||
//! setzt die treetable als member.
|
||||
|
||||
void XQViewModel::setTreeTable(XQTreeTable* mainView )
|
||||
{
|
||||
// store view for direct access: the maintree
|
||||
_treeTable = mainView;
|
||||
// connect myself as model to the mainview
|
||||
_treeTable->setModel(this);
|
||||
XQItemDelegate* delegate = new XQItemDelegate( *this );
|
||||
_treeTable->setItemDelegate( delegate );
|
||||
|
||||
_contextMenu = new XQContextMenu( mainView );
|
||||
|
||||
connect( _treeTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onShowContextMenu(QPoint)));
|
||||
//connect( _treeTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(onDoubleClicked(QModelIndex)) );
|
||||
connect(_contextMenu, SIGNAL(triggered(QAction*)), this, SLOT(onActionTriggered(QAction*)));
|
||||
|
||||
// __fixme, die view soll über das modelsheet konfiguriert werden!
|
||||
setupViewProperties();
|
||||
}
|
||||
|
||||
|
||||
//! setzt die eigenschaften der TreeTable.
|
||||
|
||||
void XQViewModel::setupViewProperties()
|
||||
{
|
||||
_treeTable->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
_treeTable->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
|
||||
_treeTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
_treeTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
//_treeTable->setSelectionMode(QAbstractItemView::ContiguousSelection);
|
||||
_treeTable->setSelectionModel( new XQSelectionModel(this) );
|
||||
}
|
||||
|
||||
|
||||
//! gibt den undo-stack zurück.
|
||||
|
||||
QUndoStack* XQViewModel::undoStack()
|
||||
{
|
||||
return _undoStack;
|
||||
}
|
||||
|
||||
|
||||
//! setzt den undo-stack.
|
||||
|
||||
void XQViewModel::setUndoStack( QUndoStack* undoStack )
|
||||
{
|
||||
_undoStack = undoStack;
|
||||
}
|
||||
|
||||
|
||||
//! SLOT, der die erstellung & anzeige es context-menues triggert.
|
||||
|
||||
void XQViewModel::onShowContextMenu(const QPoint& point)
|
||||
{
|
||||
initContextMenu();
|
||||
_contextMenu->popup(_treeTable->mapToGlobal(point));
|
||||
}
|
||||
|
||||
|
||||
//! gibt die namen der neuen data-roles zurück.
|
||||
//! __fix: die alten roles fehlen hier!
|
||||
|
||||
QHash<int, QByteArray> XQViewModel::roleNames() const
|
||||
{
|
||||
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[XQItem::ContentRole] = "content";
|
||||
roles[XQItem::ItemTypeRole] = "itemType";
|
||||
roles[XQItem::RenderStyleRole] = "renderStyle";
|
||||
roles[XQItem::EditorTypeRole] = "editorType";
|
||||
roles[XQItem::UnitTypeRole] = "unitType";
|
||||
roles[XQItem::FixedChoicesRole] = "fixedChoices";
|
||||
roles[XQItem::ContentNodeRole] = "contentNode";
|
||||
roles[XQItem::SheetNodeRole] = "sheetNode";
|
||||
roles[XQItem::TypeKeyRole] = "typeKey";
|
||||
|
||||
return roles;
|
||||
|
||||
}
|
||||
|
@@ -99,7 +99,9 @@ public slots:
|
||||
|
||||
signals:
|
||||
|
||||
void xqItemCreated( XQItem* newItem );
|
||||
void itemCreated( XQItem* newItem );
|
||||
void sectionCreated( const XQModelSection* section );
|
||||
void sectionToggled( const XQModelSection* section );
|
||||
|
||||
protected:
|
||||
|
||||
|
@@ -33,7 +33,6 @@ public:
|
||||
(*this)[key] = index;
|
||||
}
|
||||
|
||||
|
||||
int indexOf(const QString& key) const
|
||||
{
|
||||
if (contains(key))
|
||||
|
Reference in New Issue
Block a user