summaryrefslogtreecommitdiffstats
path: root/part/qdom_add.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'part/qdom_add.cpp')
-rw-r--r--part/qdom_add.cpp352
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;
+}
+