/*************************************************************************** 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 #include #include #include KXE_TreeViewItem::KXE_TreeViewItem( const TQDomNode & xmlNode, TQListViewItem * pParent ) : TQListViewItem(pParent), m_xmlNode(xmlNode), m_pPrevSibling(0), m_bBookmarked(false), m_bChildsCreated(false), m_bGrandChildsCreated(false) { init(); initChilds(); } KXE_TreeViewItem::KXE_TreeViewItem( const TQDomNode & xmlNode, KListView * pParent, TQListViewItem* pAfter) : TQListViewItem(pParent,pAfter), m_xmlNode(xmlNode), m_pPrevSibling(0), m_bBookmarked(false), m_bChildsCreated(false), m_bGrandChildsCreated(false) { init(); initChilds(); } KXE_TreeViewItem::KXE_TreeViewItem( const TQDomNode & xmlNode, TQListViewItem * pParent, TQListViewItem * pAfter ) : TQListViewItem( 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 (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 (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 TQDomNode::ElementNode: setText( 0, m_xmlNode.toElement().nodeName() ); if ( KXMLEditorFactory::configuration()->treeview()->elemDisplMode() == KXETreeViewSettings::NoAttributes ) setText( 1, TQString() ); else { // parse all attributes to fill the second column TQString 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 TQDomNode::TextNode: case TQDomNode::CDATASectionNode: case TQDomNode::CommentNode: { // set name TQString strText = m_xmlNode.toCharacterData().data(); strText = strText.replace( TQRegExp("\n"), " " ); // replace every newline by a space strText = strText.replace( TQRegExp("\t"), "" ); // removes every tab strText = strText.replace( TQRegExp("\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 TQDomNode::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 TQListViewItem * pTmpItem = firstChild(); // if there are no childs return 0 if ( ! pTmpItem ) return 0; TQListViewItem * pTmpItem2; while ( (pTmpItem2 = pTmpItem->nextSibling()) != 0 ) // traversing all childs { pTmpItem = pTmpItem2; } return static_cast (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 (parent()); // return this' parent (if there is any) } KXE_TreeViewItem * KXE_TreeViewItem::nextItem() { // checking for a child TQListViewItem * pTmp = firstChild(); if (pTmp) return static_cast (pTmp); // there is no child -> checking for the next sibling pTmp = nextSibling(); if (pTmp) return static_cast (pTmp); // there is no next sibling -> checking for parents' next sibling(s) TQListViewItem * pParent = parent(); while (pParent) { pTmp = pParent->nextSibling(); if (pTmp) return static_cast (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 ( firstChild() ); while ( pChild ) { pChild->expandSubTree(iNewLevel); pChild = static_cast ( 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 ( firstChild() ); while ( pChild ) { pChild->collapseSubTree( iNewLevel ); pChild = static_cast ( 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 ) { TQDomNode 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 ( firstChild() ); while ( pChild ) { pChild->ensureChildItemsCreated(); pChild = static_cast ( 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 ( listView() ))->isRenameable( iCol ) ) TQListViewItem::startRename( iCol ); }