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.
331 lines
9.4 KiB
331 lines
9.4 KiB
9 years ago
|
/***************************************************************************
|
||
|
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 );
|
||
|
}
|