diff options
Diffstat (limited to 'part/qdom_add.cpp')
-rw-r--r-- | part/qdom_add.cpp | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/part/qdom_add.cpp b/part/qdom_add.cpp new file mode 100644 index 0000000..142b873 --- /dev/null +++ b/part/qdom_add.cpp @@ -0,0 +1,352 @@ +/*************************************************************************** + qdom_add.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. * + * * + ***************************************************************************/ + +/** This file contains useful datatypes and functions in addition to the Qt DOM classes. */ + +#include "qdom_add.h" + +#include <kiconloader.h> +#include <kdebug.h> + +#include <qtextstream.h> + +#include "kxmleditorfactory.h" +#include "kxesearchdialog.h" + +QPixmap g_iconElement( UserIcon("xml_element",KXMLEditorFactory::instance()) ); +QPixmap g_iconText( UserIcon("xml_text",KXMLEditorFactory::instance()) ); +QPixmap g_iconComment( UserIcon("xml_comment",KXMLEditorFactory::instance()) ); +QPixmap g_iconCDATASection( UserIcon("xml_cdata",KXMLEditorFactory::instance()) ); +QPixmap g_iconProcessingInstruction( UserIcon("xml_procinstr",KXMLEditorFactory::instance()) ); +QPixmap g_iconElement_b( UserIcon("xml_element_b",KXMLEditorFactory::instance()) ); +QPixmap g_iconText_b( UserIcon("xml_text_b",KXMLEditorFactory::instance()) ); +QPixmap g_iconComment_b( UserIcon("xml_comment_b",KXMLEditorFactory::instance()) ); +QPixmap g_iconCDATASection_b( UserIcon("xml_cdata_b",KXMLEditorFactory::instance()) ); +QPixmap g_iconProcessingInstruction_b( UserIcon("xml_procinstr_b",KXMLEditorFactory::instance()) ); +QPixmap g_iconUnknown; + +const QPixmap & domTool_getIconForNodeType( QDomNode::NodeType type, bool bBookmarked ) +{ + if(!bBookmarked) + { switch(type) + { case QDomNode::ElementNode: return g_iconElement; break; + case QDomNode::TextNode: return g_iconText; break; + case QDomNode::CDATASectionNode: return g_iconCDATASection; break; + case QDomNode::CommentNode: return g_iconComment; break; + case QDomNode::ProcessingInstructionNode: return g_iconProcessingInstruction; break; + + default: + kdDebug() << "domTool_getIconForNodeType: unknown node type (" << type << ")" << endl; + } + } + else + { switch(type) + { case QDomNode::ElementNode: return g_iconElement_b; break; + case QDomNode::TextNode: return g_iconText_b; break; + case QDomNode::CDATASectionNode: return g_iconCDATASection_b; break; + case QDomNode::CommentNode: return g_iconComment_b; break; + case QDomNode::ProcessingInstructionNode: return g_iconProcessingInstruction_b; break; + + default: + kdDebug() << "domTool_getIconForNodeType: unknown node type (" << type << ")" << endl; + } + } + return g_iconUnknown; +} + +// Obtain XPath for all nodes, instead of elements +QString domTool_getPath( const QDomNode & node ) +{ + if ( node.isNull() ) + { + kdDebug() << "domTool_getPath: elelent given" << endl; + return QString(); + } + + if(node.isElement()) + { + kdDebug() << "use domTool_getPath( const QDomElement & domElement ) for elements" << endl; + } + + QString strReturn; + + QDomNode parentNode = node.parentNode(); + if ( (!parentNode.isNull()) && (!parentNode.isDocument()) ) + { + strReturn = domTool_getPath( parentNode.toElement() ); // get the parent's path + strReturn += "/"; // append slash + strReturn += node.nodeName(); // append the given node's name + } + else + strReturn = node.nodeName(); // set the given node's name (must be root element) + + return strReturn; +} + +// Obtain XPath for elements +QString domTool_getPath( const QDomElement & domElement ) +{ + if ( domElement.isNull() ) + { + kdDebug() << "domTool_getPath: no node given" << endl; + return QString(); + } + + QString strReturn; + QDomNode parentNode = domElement.parentNode(); + if ( (!parentNode.isNull()) && (!parentNode.isDocument()) ) + { + // calculate index - only for elements with the same name + int i = 0; + bool bUseIndex = false; // index is used only when exist sibling(s) with the same name + + // traverse previous sibling elements with same name and calculate index + QDomNode tmpNode = domElement.previousSibling(); + while ( ! tmpNode.isNull() ) + { + if(tmpNode.isElement()) + { + QDomElement domSiblingElement = tmpNode.toElement(); + + if(domElement.tagName() == domSiblingElement.tagName()) + { i++; bUseIndex = true; + } + } + tmpNode = tmpNode.previousSibling(); + } + + if(bUseIndex == false) + { + // traverse next sibling elements with same name + // and decide, if index is necessary + QDomNode tmpNode = domElement.nextSibling(); + while ( ! tmpNode.isNull() ) + { + if(tmpNode.isElement()) + { + QDomElement domSiblingElement = tmpNode.toElement(); + + if(domElement.tagName() == domSiblingElement.tagName()) + bUseIndex = true; + } + + tmpNode = tmpNode.nextSibling(); + + } + } + + strReturn = domTool_getPath( parentNode.toElement() ); // get the parent's path + strReturn += "/"; // append slash + strReturn += domElement.nodeName(); // append the given node's name + + if(bUseIndex) + { + QString strIndex; + strIndex.setNum(i+1); + strReturn += "[" + strIndex + "]"; // append the index + } + } + else + strReturn = domElement.nodeName(); // set the given node's name (must be root element) + + return strReturn; +} + +unsigned int domTool_getLevel( const QDomNode & node ) +{ + if ( node.isNull() ) + { + kdDebug() << "domTool_getLevel: internal implementation error - the given node is an empty one" << endl; + return 0; + } + + unsigned int iLevel = 0; + QDomNode parentNode = node.parentNode(); + while ( ! parentNode.isNull() ) + { + iLevel++; + parentNode = parentNode.parentNode(); + } + + return iLevel - 1; +} + +QString domTool_save( const QDomNode & node, int iIndent ) +{ + QString strXML; + QTextStream ts( & strXML, IO_WriteOnly ); + + node.save(ts, iIndent); + return strXML; +} + +QDomNode domTool_prevNode( const QDomNode & node ) +{ + if ( node.isNull() ) + { + kdDebug() << "domTool_prevNode: internal implementation error - the given node is an empty one" << endl; + return QDomNode(); + } + + if ( ! node.previousSibling().isNull() ) // if there is a prev. sibling + { // return its last grand child (if there is any) + QDomNode prevNode = node.previousSibling(); + while ( ! prevNode.lastChild().isNull() ) + prevNode = prevNode.lastChild(); + return prevNode; + } + else // if there is no prev. sibling, return + return node.parentNode(); // the nodes parent (if there is any) + +} + +QDomNode domTool_nextNode( const QDomNode & node ) +{ + if ( node.isNull() ) + { + kdDebug() << "domTool_nextNode: internal implementation error - the given node is an empty one" << endl; + return QDomNode(); + } + + // checking for a child + if ( ! node.firstChild().isNull() ) + return node.firstChild(); + + // there is no child -> checking for the next sibling + if ( ! node.nextSibling().isNull() ) + return node.nextSibling(); + + // there is no next sibling -> checking for parents' next sibling(s) + QDomNode nodeParent = node.parentNode(); + while ( ! nodeParent.isNull() ) + { + if ( ! nodeParent.nextSibling().isNull() ) + return nodeParent.nextSibling(); + + nodeParent = nodeParent.parentNode(); // parent has no sibling - try its parent + } + + // parent has no parents anymore + return QDomNode(); // return empty node +} + +QDomNode domTool_matchingNode( const QDomNode & node, const QString & szPath ) +{ + if(szPath.length() == 0) + return QDomNode(); // return void node + + QString szNodePath = node.isDocument() ? QString("") : domTool_getPath(node); + if ( szPath == szNodePath ) // test if the strings match + return node; + + /* L.V. those optimalizations disallow find proc. instr. at doc. level + + // we will find any node in root element subtree + if ( szPath.length() <= szNodePath.length() ) // the given string must be longer + return QDomNode(); // otherwise we don't need to check the childs + + if ( szPath.left(szNodePath.length()) != szNodePath ) // the nodes path must be left part of the given path + return QDomNode(); // otherwise we don't need to check the childs + */ + + // recursively check the childs + QDomNode nodeChild = node.firstChild(); + QDomNode nodeTmp; + while ( ! nodeChild.isNull() ) + { + nodeTmp = domTool_matchingNode( nodeChild, szPath ); + if ( ! nodeTmp.isNull() ) + return nodeTmp; + nodeChild = nodeChild.nextSibling(); + } + + return QDomNode(); // nothing found -> return empty node +} + +bool domTool_match( QDomNode node, const KXESearchDialog * const pConditions ) +{ + if ( node.isNull() ) + { + kdDebug() << "domTool_match: internal implementation error - the given node is an empty one" << endl; + return false; + } + + if ( ! pConditions ) + { + kdDebug() << "domTool_match: internal implementation error - the given pointer is a null pointer" << endl; + return false; + } + + switch ( node.nodeType() ) + { + case QDomNode::ElementNode: // ---------------------------------------- + { + if ( pConditions->getInElementNames() ) + { + if ( node.toElement().tagName().find( pConditions->getSearchString(), 0, pConditions->getMatchCase() ) >= 0 ) + return true; + } + + if ( ( pConditions->getInAttributeNames() ) || ( pConditions->getInAttributeValues() ) ) + { + QDomNamedNodeMap list = node.toElement().attributes(); + unsigned int iLength = list.length(); + if ( iLength <= 0 ) + return false; // no attributes + + for ( unsigned int iRow = 0; iRow < iLength; iRow++ ) + { + if ( pConditions->getInAttributeNames() ) + if ( list.item(iRow).toAttr().name().find( pConditions->getSearchString(), 0, pConditions->getMatchCase() ) >= 0 ) + return true; + if ( pConditions->getInAttributeValues() ) + if ( list.item(iRow).toAttr().value().find( pConditions->getSearchString(), 0, pConditions->getMatchCase() ) >= 0 ) + return true; + } + return false; + } + + return false; + break; + } + + case QDomNode::TextNode: // ---------------------------------------- + case QDomNode::CDATASectionNode: + case QDomNode::CommentNode: + { + if ( pConditions->getInContents() ) + { + if ( node.toCharacterData().data().find( pConditions->getSearchString(), 0, pConditions->getMatchCase() ) >= 0 ) + return true; + else + return false; + } + else + return false; + + break; + } + +// TODO implement this for the other node types (eg proc.instr.) + + default: + kdDebug() << "domTool_match: unknown node type (" << node.nodeType() << ")" << endl; + } + + return true; +} + |