You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kxmleditor/part/kxe_treeviewitem.cpp

331 lines
9.4 KiB

/***************************************************************************
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 );
}