diff options
Diffstat (limited to 'part/kxe_treeviewitem.cpp')
-rw-r--r-- | part/kxe_treeviewitem.cpp | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/part/kxe_treeviewitem.cpp b/part/kxe_treeviewitem.cpp new file mode 100644 index 0000000..0107bee --- /dev/null +++ b/part/kxe_treeviewitem.cpp @@ -0,0 +1,330 @@ +/*************************************************************************** + kxe_treeviewitem.cpp - description + ------------------- + begin : Wed Nov 21 2001 + copyright : (C) 2001, 2002, 2003 by The KXMLEditor Team + email : lvanek@users.sourceforge.net + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 "kxe_treeviewitem.h" + +#include "kxmleditorfactory.h" +#include "kxeconfiguration.h" +#include "kxetreeviewsettings.h" + +#include "qdom_add.h" + +#include <qregexp.h> + +#include <klistview.h> +#include <kdebug.h> +#include <kiconloader.h> + +KXE_TreeViewItem::KXE_TreeViewItem( const QDomNode & xmlNode, QListViewItem * pParent ) + : QListViewItem(pParent), + m_xmlNode(xmlNode), + m_pPrevSibling(0), + m_bBookmarked(false), + m_bChildsCreated(false), + m_bGrandChildsCreated(false) +{ + init(); + initChilds(); +} + +KXE_TreeViewItem::KXE_TreeViewItem( const QDomNode & xmlNode, KListView * pParent, QListViewItem* pAfter) + : QListViewItem(pParent,pAfter), + m_xmlNode(xmlNode), + m_pPrevSibling(0), + m_bBookmarked(false), + m_bChildsCreated(false), + m_bGrandChildsCreated(false) +{ + init(); + initChilds(); +} + +KXE_TreeViewItem::KXE_TreeViewItem( const QDomNode & xmlNode, QListViewItem * pParent, QListViewItem * pAfter ) + : QListViewItem( pParent, pAfter ), + m_xmlNode(xmlNode), + m_pPrevSibling(0), + m_bBookmarked(false), + m_bChildsCreated(false), + m_bGrandChildsCreated(false) +{ + init(); + initChilds(); +} + +KXE_TreeViewItem::~KXE_TreeViewItem() +{ + // inform the next sibling (if there's any) about destroying this item (as its previous sibling) + KXE_TreeViewItem * pNextItem = static_cast <KXE_TreeViewItem*> (nextSibling()); + if ( pNextItem ) + { pNextItem->setPrevSibling(m_pPrevSibling); + } +} + +void KXE_TreeViewItem::init() +{ + // A tree view item can only be in-place renameable, if it represents an XML element + // (the final check occurs in KXE_TreeViewItem::startRename). + if ( m_xmlNode.isElement() ) + setRenameEnabled( 0, true ); + + // inform the next sibling (if there's any) about this item (as its previous sibling) + KXE_TreeViewItem * pNextItem = static_cast <KXE_TreeViewItem*> (nextSibling()); + if ( pNextItem ) + pNextItem->setPrevSibling(this); + + setPixmap(0, domTool_getIconForNodeType(m_xmlNode.nodeType(), false)); + + if ( domTool_getLevel(m_xmlNode) < (unsigned int)KXMLEditorFactory::configuration()->treeview()->dfltExpLevel() ) + setOpen(true); + + setTexts(); +} + +void KXE_TreeViewItem::setTexts() +{ + switch ( m_xmlNode.nodeType() ) + { + case QDomNode::ElementNode: + + setText( 0, m_xmlNode.toElement().nodeName() ); + + if ( KXMLEditorFactory::configuration()->treeview()->elemDisplMode() == KXETreeViewSettings::NoAttributes ) + setText( 1, QString() ); + else + { + // parse all attributes to fill the second column + QString str2ndCol; + for ( uint i=0; i < m_xmlNode.toElement().attributes().length(); i++ ) + { + if ( i > 0 ) + str2ndCol += ", "; + str2ndCol += m_xmlNode.toElement().attributes().item(i).toAttr().name(); + if ( KXMLEditorFactory::configuration()->treeview()->elemDisplMode() == KXETreeViewSettings::NamesAndValues ) + str2ndCol += '=' + m_xmlNode.toElement().attributes().item(i).toAttr().value(); + } + setText( 1, str2ndCol ); + } + break; + + case QDomNode::TextNode: + case QDomNode::CDATASectionNode: + case QDomNode::CommentNode: + { + // set name + QString strText = m_xmlNode.toCharacterData().data(); + strText = strText.replace( QRegExp("\n"), " " ); // replace every newline by a space + strText = strText.replace( QRegExp("\t"), "" ); // removes every tab + strText = strText.replace( QRegExp("\r"), "" ); // removes every return + strText = strText.simplifyWhiteSpace(); + if( strText.length() > 30 ) // reduce name length, if necessary + strText = strText.left(30) + "..."; + setText( 0, strText ); + + break; + } + + case QDomNode::ProcessingInstructionNode: + + setText( 0, m_xmlNode.toProcessingInstruction().target() ); + break; + + default: + kdDebug() << "KXE_TreeViewItem::init: unknown node type (" << m_xmlNode.nodeType() << ")" << endl; + } +} + +void KXE_TreeViewItem::initChilds() +{ + if ( ! KXMLEditorFactory::configuration()->treeview()->createItemsOnDemand() || + ( ! m_bChildsCreated && + ( ! parent() || ( parent() && parent()->isOpen() ) ) + ) + ) + ensureChildItemsCreated(); +} + +bool KXE_TreeViewItem::toggleBookmark() +{ + m_bBookmarked = ! m_bBookmarked; + + setPixmap(0, domTool_getIconForNodeType(m_xmlNode.nodeType(), m_bBookmarked)); + + return m_bBookmarked; +} + +KXE_TreeViewItem * KXE_TreeViewItem::lastChild() const +{ + // take the first child + QListViewItem * pTmpItem = firstChild(); + // if there are no childs return 0 + if ( ! pTmpItem ) + return 0; + + QListViewItem * pTmpItem2; + while ( (pTmpItem2 = pTmpItem->nextSibling()) != 0 ) // traversing all childs + { + pTmpItem = pTmpItem2; + } + + return static_cast <KXE_TreeViewItem*> (pTmpItem); +} + +KXE_TreeViewItem * KXE_TreeViewItem::prevItem() +{ + if ( m_pPrevSibling ) // if there is a prev. sibling + { // return its last grand child (if there is any) + KXE_TreeViewItem * pPrevItem = m_pPrevSibling; + KXE_TreeViewItem * pTmpItem; + while ( (pTmpItem=pPrevItem->lastChild()) ) + pPrevItem = pTmpItem; + return pPrevItem; + } + else // if there is no prev. sibling, + return static_cast <KXE_TreeViewItem*> (parent()); // return this' parent (if there is any) +} + +KXE_TreeViewItem * KXE_TreeViewItem::nextItem() +{ + // checking for a child + QListViewItem * pTmp = firstChild(); + if (pTmp) + return static_cast <KXE_TreeViewItem*> (pTmp); + + // there is no child -> checking for the next sibling + pTmp = nextSibling(); + if (pTmp) + return static_cast <KXE_TreeViewItem*> (pTmp); + + // there is no next sibling -> checking for parents' next sibling(s) + QListViewItem * pParent = parent(); + while (pParent) + { + pTmp = pParent->nextSibling(); + if (pTmp) + return static_cast <KXE_TreeViewItem*> (pTmp); + pParent = pParent->parent(); + } + return 0; +} + +void KXE_TreeViewItem::expandSubTree( int iLevel ) +{ + setOpen(true); // expand this item + + if ( iLevel == 0 ) // return, if we are deep enough + return; + + // expand childs (recursive) + int iNewLevel = ( iLevel == -1 ) ? -1 : iLevel-1; + KXE_TreeViewItem * pChild = static_cast <KXE_TreeViewItem*> ( firstChild() ); + while ( pChild ) + { + pChild->expandSubTree(iNewLevel); + pChild = static_cast <KXE_TreeViewItem*> ( pChild->nextSibling() ); + } +} + +void KXE_TreeViewItem::collapseSubTree( int iLevel ) +{ + if ( iLevel < 0 ) + { + kdDebug() << "KXE_TreeViewItem::collapseSubTree: wrong level given (iLevel=" << iLevel << ")" << endl; + return; + } + + int iNewLevel; + if (iLevel==0) // collapse this item, + { // because we are deep enough + setOpen(false); + iNewLevel = 0; + } + else + iNewLevel = iLevel - 1; + + // collapsing in childs (recursive) + KXE_TreeViewItem * pChild = static_cast <KXE_TreeViewItem*> ( firstChild() ); + while ( pChild ) + { + pChild->collapseSubTree( iNewLevel ); + pChild = static_cast <KXE_TreeViewItem*> ( pChild->nextSibling() ); + } +} + +/** Test, if item in parameter is my direct or indirect child item */ +bool KXE_TreeViewItem::isMyChildren(const KXE_TreeViewItem *pTestItem) +{ + KXE_TreeViewItem* pChildXmlTreeItem = (KXE_TreeViewItem*) firstChild(); + while(pChildXmlTreeItem) + { if(pChildXmlTreeItem == pTestItem) + return true; + + // test child item childrens + if(pChildXmlTreeItem->isMyChildren(pTestItem)) + return true; + + pChildXmlTreeItem = (KXE_TreeViewItem*) pChildXmlTreeItem->nextSibling(); + } + return false; +} + + +void KXE_TreeViewItem::ensureChildItemsCreated() +{ + if ( ! m_bChildsCreated ) + { + QDomNode tmpNode = m_xmlNode.lastChild(); + + while ( ! tmpNode.isNull() ) + { + new KXE_TreeViewItem( tmpNode, this ); + tmpNode = tmpNode.previousSibling(); + } + + m_bChildsCreated = true; + } +} + + +void KXE_TreeViewItem::ensureGrandChildItemsCreated() +{ + if ( ! m_bGrandChildsCreated ) + { + // ensure, that all child items of this item are created + if ( ! m_bChildsCreated ) + ensureChildItemsCreated(); + + // Iterate over all children now and ensure their child items + // (this' grandchildrens) are created. + KXE_TreeViewItem * pChild = static_cast <KXE_TreeViewItem*> ( firstChild() ); + while ( pChild ) + { + pChild->ensureChildItemsCreated(); + pChild = static_cast <KXE_TreeViewItem*> ( pChild->nextSibling() ); + } + + m_bGrandChildsCreated = true; + } +} + +void KXE_TreeViewItem::startRename( int iCol ) +{ + // If the given column is set to be in-place renameable in this item's view, + // we can start renaming in-place. + // Remember: This function is only reached for items representing XML elements. + if ( (reinterpret_cast<KListView*> ( listView() ))->isRenameable( iCol ) ) + QListViewItem::startRename( iCol ); +} |