/***************************************************************************
wkafkapart . cpp
- - - - - - - - - - - - - - - - - - -
copyright : ( C ) 2003 , 2004 - Nicolas Deschildre
email : ndeschildre @ kdewebdev . org
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/***************************************************************************
* *
* 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 . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define HEAVY_DEBUG 1
# include <dom/dom_node.h>
# include <dom/dom_exception.h>
# include <dom/dom_string.h>
# include <dom/css_stylesheet.h>
# include <kdebug.h>
# include <tdehtmlview.h>
# include <kstandarddirs.h>
# include <tdetexteditor/editinterface.h>
# include <tdetexteditor/selectioninterface.h>
# include <kstandarddirs.h>
# include <tdelocale.h>
# include <tdemultipledrag.h>
# include <tdeglobal.h>
# include <kcharsets.h>
# include <tqregexp.h>
# include <tqfile.h>
# include <tqtextstream.h>
# include <tqdatetime.h>
# include <tqclipboard.h>
# include <tqptrvector.h>
# include "document.h"
# include "viewmanager.h"
# include "quantacommon.h"
# include "resource.h"
# include "undoredo.h"
# include "node.h"
# include "parser.h"
# include "project.h"
# include "tag.h"
# include "nodeproperties.h"
# include "htmlenhancer.h"
# include "kafkacommon.h"
# include "kafkaresource.h"
# include "cursors.h"
# include "kafkadragobject.h"
# include "cursors.h"
# include "wkafkapart.moc"
KafkaWidget * kafkaWidget ;
KafkaDocument * kafkaDoc ;
KafkaDocument : : KafkaDocument ( TQWidget * parent , TQWidget * widgetParent , const char * name )
: domNodeProps ( 1021 ) , _docLoaded ( false )
{
// i18n reserve
TQString a = i18n ( " Selector " ) ; TQString b = i18n ( " Attribute " ) ; TQString c = i18n ( " Class " ) ;
TQString d = i18n ( " Pseudo-class " ) ; TQString e = i18n ( " CSS rules " ) ; TQString f = i18n ( " Universal selector " ) ;
TQString g = i18n ( " Linked stylesheets " ) ; TQString h = i18n ( " Embedded stylesheets " ) ; TQString i = i18n ( " Inline style attribute " ) ;
TQString j = i18n ( " Link " ) ; TQString k = i18n ( " Priority " ) ; TQString l = i18n ( " ID " ) ;
TQString m = i18n ( " Browser support " ) ; TQString n = i18n ( " Pseudo-element " ) ; TQString o = i18n ( " Imported " ) ;
TQString p = i18n ( " Inheritance " ) ; TQString q = i18n ( " Inherited " ) ; TQString r = " " ;
TQString s = i18n ( " Name " ) ; TQString tt = i18n ( " Undo " ) ; TQString u = i18n ( " Redo " ) ;
TQString v = i18n ( " Undo/Redo history " ) ; TQString w = i18n ( " CSS styles " ) ;
TQString x = i18n ( " Sorry, VPL does not support this functionality yet. " ) ;
TQString y = i18n ( " Merge cells " ) ;
TQString z = i18n ( " Split cells " ) ;
TQString aa = i18n ( " Edit CSS style of this Tag " ) ;
TQString ab = i18n ( " Ident all " ) ;
//end
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::KafkaDocument() " < < endl ;
# endif
kafkaDoc = this ;
m_kafkaPart = new KafkaWidget ( parent , widgetParent , this , name ) ;
kafkaWidget = m_kafkaPart ;
//m_kafkaPart->showDomTree();
m_currentDoc = 0L ;
mainEnhancer = new HTMLEnhancer ( this ) ;
domNodeProps . setAutoDelete ( false ) ;
TDEStandardDirs * m_stddirs = new TDEStandardDirs ( ) ;
TQFile file ( m_stddirs - > findResource ( " data " , " kafkapart/entities " ) /**locate("appdata","chars") */ ) ;
delete m_stddirs ;
TQString tmp ;
if ( file . open ( IO_ReadOnly ) )
{
TQTextStream t ( & file ) ; // use a text stream
t . setEncoding ( TQTextStream : : UnicodeUTF8 ) ;
while ( ! t . eof ( ) )
{
tmp = t . readLine ( ) ;
if ( tmp . left ( 2 ) = = " // " ) continue ; //comments
int begin = tmp . find ( " ( " ) + 1 ;
if ( begin = = ( - 1 + 1 ) ) continue ; //"(" not found : invalid line
int length = tmp . find ( " ) " ) - begin ;
decodedChars . insert ( tmp . left ( 1 ) , tmp . mid ( begin , length ) ) ;
encodedChars . insert ( tmp . mid ( begin , length ) , tmp . left ( 1 ) ) ;
}
file . close ( ) ;
}
connect ( m_kafkaPart , TQT_SIGNAL ( domNodeInserted ( DOM : : Node , bool , NodeModifsSet * ) ) ,
this , TQT_SLOT ( slotDomNodeInserted ( DOM : : Node , bool , NodeModifsSet * ) ) ) ;
connect ( m_kafkaPart , TQT_SIGNAL ( domNodeModified ( DOM : : Node , NodeModifsSet * ) ) ,
this , TQT_SLOT ( slotDomNodeModified ( DOM : : Node , NodeModifsSet * ) ) ) ;
connect ( m_kafkaPart , TQT_SIGNAL ( domNodeIsAboutToBeRemoved ( DOM : : Node , bool , NodeModifsSet * ) ) ,
this , TQT_SLOT ( slotDomNodeAboutToBeRemoved ( DOM : : Node , bool , NodeModifsSet * ) ) ) ;
connect ( m_kafkaPart , TQT_SIGNAL ( domNodeIsAboutToBeMoved ( DOM : : Node , DOM : : Node , DOM : : Node , NodeModifsSet * ) ) ,
this , TQT_SLOT ( slotDomNodeIsAboutToBeMoved ( DOM : : Node , DOM : : Node , DOM : : Node , NodeModifsSet * ) ) ) ;
connect ( m_kafkaPart , TQT_SIGNAL ( domNodeNewCursorPos ( DOM : : Node , int ) ) ,
this , TQT_SLOT ( slotdomNodeNewCursorPos ( DOM : : Node , int ) ) ) ;
}
KafkaDocument : : ~ KafkaDocument ( )
{
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::~KafkaDocument() " < < endl ;
# endif
//delete the empty node linked to the DOM::Node #document
disconnectAllDomNodes ( ) ;
}
void KafkaDocument : : loadDocument ( Document * doc )
{
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::loadDocument() " < < endl ;
# endif
Node * node ;
Tag * tag ;
DOM : : Node domNode ;
bool goUp ;
if ( ! m_kafkaPart ) return ;
if ( ! doc ) return ;
# ifdef LIGHT_DEBUG
TQTime t ;
t . start ( ) ;
# endif
m_currentDoc = doc ;
( static_cast < HTMLEnhancer * > ( mainEnhancer ) ) - > setBaseURL ( Project : : ref ( ) - > projectBaseURL ( ) ) ;
//create a empty document with a basic tree : HTML, HEAD, BODY
m_kafkaPart - > newDocument ( ) ;
// When loading a weird html file in tdehtml (e.g. without BODY or HTML), tdehtml takes care
// to create the necessary tags. But as we are handling directly the Nodes, we have to handle this!!
// creating and linking an empty node to the root DOM::Node (#document) and
// to HEAD, HTML, BODY
node = new Node ( 0L ) ;
tag = new Tag ( ) ;
tag - > name = " #document " ;
tag - > setNotInTree ( true ) ;
node - > tag = tag ;
connectDomNodeToQuantaNode ( m_kafkaPart - > document ( ) , node ) ;
node = new Node ( 0L ) ;
tag = new Tag ( ) ;
tag - > name = " HTML " ;
tag - > setNotInTree ( true ) ;
node - > tag = tag ;
connectDomNodeToQuantaNode ( m_kafkaPart - > document ( ) . firstChild ( ) , node ) ;
html = m_kafkaPart - > document ( ) . firstChild ( ) ;
node = new Node ( 0L ) ;
tag = new Tag ( ) ;
tag - > name = " HEAD " ;
tag - > setNotInTree ( true ) ;
node - > tag = tag ;
connectDomNodeToQuantaNode ( m_kafkaPart - > document ( ) . firstChild ( ) . firstChild ( ) , node ) ;
head = m_kafkaPart - > document ( ) . firstChild ( ) . firstChild ( ) ;
node = new Node ( 0L ) ;
tag = new Tag ( ) ;
tag - > name = " BODY " ;
tag - > setNotInTree ( true ) ;
node - > tag = tag ;
connectDomNodeToQuantaNode ( m_kafkaPart - > document ( ) . firstChild ( ) . lastChild ( ) , node ) ;
body = m_kafkaPart - > document ( ) . firstChild ( ) . lastChild ( ) ;
//load the DOM::Nodes from the node tree.
node = baseNode ;
while ( node )
{
# ifdef HEAVY_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::loadDocument - Node name : " < <
node - > tag - > name . upper ( ) < < " ; type : " < <
node - > tag - > type < < " ; tagstr : " < < node - > tag - > tagStr ( ) < <
" is opened : " < < node - > opened < < endl ;
# endif
if ( ! buildKafkaNodeFromNode ( node ) )
emit loadingError ( node ) ;
node = node - > nextSibling ( ) ;
}
//post process the DOM::Node Tree by adding Empty TEXT so that the cursor can go
//everywhere the user wants.
domNode = m_kafkaPart - > document ( ) ;
goUp = false ;
while ( ! domNode . isNull ( ) )
{
mainEnhancer - > postEnhanceNode ( domNode ) ;
domNode = kafkaCommon : : getNextDomNode ( domNode , goUp ) ;
}
m_kafkaPart - > putCursorAtFirstAvailableLocation ( ) ;
_docLoaded = true ;
//Avoid moving objects...
m_kafkaPart - > stopAnimations ( ) ;
m_currentDoc - > docUndoRedo - > kafkaLoaded ( ) ;
emit loaded ( ) ;
m_currentDoc - > docUndoRedo - > syncKafkaCursorAndSelection ( 0 ) ;
//m_kafkaPart->document().updateRendering();
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::loadDocument() in " < < t . elapsed ( ) < < " ms only! " < < endl ;
# endif
# ifdef HEAVY_DEBUG
kafkaCommon : : coutDomTree ( m_kafkaPart - > document ( ) , 2 ) ;
coutLinkTree ( baseNode , 2 ) ;
# endif
}
void KafkaDocument : : unloadDocument ( )
{
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::unloadDocument() " < < endl ;
# endif
Node * node ;
domNodeProps . clear ( ) ;
//clean the kafkapart
while ( m_kafkaPart - > document ( ) . hasChildNodes ( ) )
m_kafkaPart - > document ( ) . removeChild ( m_kafkaPart - > document ( ) . firstChild ( ) ) ;
m_currentDoc = 0L ;
html = body = head = DOM : : Node ( ) ;
_docLoaded = false ;
node = baseNode ;
while ( node )
{
if ( node - > rootNode ( ) )
delete node - > rootNode ( ) ;
node - > setRootNode ( 0L ) ;
if ( node - > leafNode ( ) )
delete node - > leafNode ( ) ;
node - > setLeafNode ( 0L ) ;
node = node - > nextSibling ( ) ;
}
emit unloaded ( ) ;
}
void KafkaDocument : : reloadDocument ( )
{
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::reloadDocument() " < < endl ;
# endif
Node * node ;
int offsetX , offsetY ;
offsetX = m_kafkaPart - > view ( ) - > contentsX ( ) ;
offsetY = m_kafkaPart - > view ( ) - > contentsY ( ) ;
m_kafkaPart - > closeURL ( ) ;
if ( ! _docLoaded )
return ;
domNodeProps . clear ( ) ;
while ( m_kafkaPart - > document ( ) . hasChildNodes ( ) )
m_kafkaPart - > document ( ) . removeChild ( m_kafkaPart - > document ( ) . firstChild ( ) ) ;
node = baseNode ;
while ( node )
{
if ( node - > rootNode ( ) )
delete node - > rootNode ( ) ;
node - > setRootNode ( 0L ) ;
if ( node - > leafNode ( ) )
delete node - > leafNode ( ) ;
node - > setLeafNode ( 0L ) ;
node = node - > nextSibling ( ) ;
}
/**KParts::URLArgs args(false, offsetX, offsetY);
( static_cast < KParts : : BrowserExtension * > ( ( ( KParts : : ReadOnlyPart * ) m_kafkaPart ) - > child ( 0L ,
" KParts::BrowserExtension " ) ) ) - > setURLArgs ( args ) ; */
loadDocument ( m_currentDoc ) ;
//m_kafkaPart->view()->setContentsPos(offsetX, offsetY);
}
kNodeAttrs * KafkaDocument : : getAttrs ( DOM : : Node _domNode )
{
return domNodeProps [ _domNode . handle ( ) ] ;
}
Node * KafkaDocument : : getNode ( DOM : : Node _domNode )
{
if ( _domNode . isNull ( ) | | _domNode . nodeName ( ) . string ( ) = = " #document " )
{
kdDebug ( 25001 ) < < " KafkaDocument::getNode() - Bad Node given " < <
endl ;
return 0L ;
}
kNodeAttrs * props = domNodeProps [ _domNode . handle ( ) ] ;
if ( ! props )
{
kdDebug ( 25001 ) < < " KafkaDocument::getNode() - " < <
" Corresponding Node not Found!!! " < < endl ;
return 0L ;
}
return props - > getNode ( ) ;
}
kNodeAttrs * KafkaDocument : : connectDomNodeToQuantaNode ( DOM : : Node domNode , Node * node )
{
TQString name ;
kNodeAttrs * props ;
if ( domNode . isNull ( ) )
{
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::connectDomNodeToQuantaNode() " < <
" - WARNING empty DOM::Node " < < endl ;
# endif
}
/**qtag = QuantaCommon::tagFromDTD(m_currentDoc->defaultDTD(),
_domNode . nodeName ( ) . string ( ) ) ; */
else
name = domNode . nodeName ( ) . string ( ) . lower ( ) ;
// kdDebug(25001) << "KafkaDocument::connectDomNodeToQuantaNode() - domNode name: |" << name << "|" << endl;
props = new kNodeAttrs ( ) ;
//We can split Nodes into several groups essentially for the deletion behavior:
//1- Text
//2- Block in which the cursor can't enter in when deleting e.g. TABLE, IMG
//3- Block in which the cursor can't escape from e.g. TD, BODY
//4- Block in which the cursor can enter in/escape from when deleting e.g. H1, DIV
//5- Inline
//6- "Invisible" Nodes e.g. HTML, HEAD
//Hmmm... I guess we can do better here...
if ( domNode . nodeType ( ) = = DOM : : Node : : TEXT_NODE )
{
props - > setCHCursorFocus ( kNodeAttrs : : textNode ) ;
props - > setCCEnter ( true ) ;
props - > setCBModified ( true ) ;
props - > setCBDeleted ( true ) ;
}
else if ( name = = " abbr " | | name = = " acronym " | | name = = " address " | | name = = " b " | | name = = " bdo " | |
name = = " big " | | name = = " cite " | | name = = " code " | |
name = = " del " | | name = = " dfn " | | name = = " dir " | |
name = = " em " | | name = = " fieldset " | | name = = " font " | | name = = " i " | | name = = " iframe " | |
name = = " ins " | | name = = " kbd " | | name = = " label " | | name = = " legend " | | name = = " menu " | |
name = = " noframes " | | name = = " pre " | | name = = " s " | | name = = " samp " | |
name = = " small " | | name = = " span " | | name = = " strike " | | name = = " strong " | | name = = " sub " | |
name = = " sup " | | name = = " tt " | | name = = " u " | | name = = " var " | | name = = " a " | |
name = = " blockquote " | |
name = = " em " | | name = = " form " | | name = = " ins " | |
name = = " q " | | name = = " tt " )
{
props - > setCHCursorFocus ( kNodeAttrs : : inlineNode ) ;
props - > setCCEnter ( true ) ;
props - > setCBModified ( true ) ;
props - > setCBDeleted ( true ) ;
}
else if ( name = = " center " | | name = = " li " | | name = = " h1 " | | name = = " h2 " | | name = = " h3 " | |
name = = " h4 " | | name = = " h5 " | | name = = " h6 " | | name = = " div " | | name = = " dd " | |
name = = " dt " | | name = = " p " )
{
props - > setCHCursorFocus ( kNodeAttrs : : blockNode ) ;
props - > setCCEnter ( true ) ;
props - > setCBModified ( true ) ;
props - > setCBDeleted ( true ) ;
}
else if ( name = = " applet " | | name = = " button " | | name = = " img " | | name = = " map " | | name = = " object " | |
name = = " hr " | | name = = " input " | | name = = " select " | | name = = " table " | | name = = " textarea " | |
name = = " br " | | name = = " dl " | | name = = " ul " | | name = = " ol " )
{
props - > setCHCursorFocus ( kNodeAttrs : : singleNodeAndItself ) ;
props - > setCCEnter ( false ) ;
props - > setCBModified ( true ) ;
props - > setCBDeleted ( true ) ;
}
else if ( name = = " basefont " | | name = = " location " | | name = = " fieldset " | | name = = " noscript " | |
name = = " script " )
{
props - > setCHCursorFocus ( kNodeAttrs : : no ) ;
props - > setCCEnter ( false ) ;
props - > setCBModified ( true ) ;
props - > setCBDeleted ( true ) ;
}
else if ( name = = " caption " | | name = = " frame " | | name = = " frameset " | | name = = " isindex " | |
name = = " optgroup " | | name = = " param " | | name = = " title " | | name = = " area " | | name = = " base " | |
name = = " body " | | name = = " col " | | name = = " colgroup " | | name = = " head " | | name = = " html " | |
name = = " link " | | name = = " meta " | | name = = " option " | | name = = " style " | | name = = " tbody " | |
name = = " td " | | name = = " tfoot " | | name = = " th " | | name = = " thead " | | name = = " tr " )
{
props - > setCHCursorFocus ( kNodeAttrs : : no ) ;
props - > setCCEnter ( false ) ;
props - > setCBModified ( false ) ;
props - > setCBDeleted ( false ) ;
}
else
{
kdDebug ( 25001 ) < < " KafkaDocument::connectDomNodeToQuantaNode () - " < <
" No TQTag found! Setting default parameters... " < < endl ;
props - > setCHCursorFocus ( kNodeAttrs : : no ) ;
props - > setCCEnter ( false ) ;
props - > setCBModified ( false ) ;
props - > setCBDeleted ( false ) ;
}
# ifdef HEAVY_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::connectDomNodeToQuantaNode() - tag name : " < <
name < < " canBeDeleted: " < < props - > cbDel ( ) < < " canBeModified: " < <
props - > cbMod ( ) < < " canHaveCursorFocus: " < < props - > chCurFoc ( ) < <
" cursorCanEnter: " < < props - > ccanEnter ( ) < < endl ;
# endif
props - > setNode ( node ) ;
props - > setDomNode ( domNode ) ;
domNodeProps . insert ( domNode . handle ( ) , props ) ;
return props ;
}
void KafkaDocument : : disconnectDomNodeFromQuantaNode ( DOM : : Node _domNode )
{
if ( _domNode . isNull ( ) )
return ;
domNodeProps . remove ( _domNode . handle ( ) ) ;
}
void KafkaDocument : : disconnectAllDomNodes ( )
{
domNodeProps . clear ( ) ;
}
void KafkaDocument : : setCursorAndSelection ( NodeSelectionInd * nodeSelection )
{
bool cursorAtSelectionStart ;
DOM : : Node startDomNode , endDomNode , foo ;
Node * startNode , * endNode ;
long startOffset , endOffset ;
cursorAtSelectionStart = nodeSelection - > cursorAtSelectionStart ( ) ;
startNode = kafkaCommon : : getNodeFromLocation ( nodeSelection - > cursorNode ( ) ) ;
endNode = kafkaCommon : : getNodeFromLocation ( nodeSelection - > cursorNodeEndSel ( ) ) ;
if ( startNode & & startNode - > rootNode ( ) )
startDomNode = * ( startNode - > rootNode ( ) ) ;
if ( endNode & & endNode - > rootNode ( ) )
endDomNode = * ( endNode - > rootNode ( ) ) ;
translateNodeIntoKafkaCursorPosition ( startNode , nodeSelection - > cursorOffset ( ) , foo , startOffset ) ;
translateNodeIntoKafkaCursorPosition ( endNode , nodeSelection - > cursorOffsetEndSel ( ) , foo , endOffset ) ;
if ( cursorAtSelectionStart & & ! startDomNode . isNull ( ) )
{
m_kafkaPart - > setCurrentNode ( startDomNode , startOffset ) ;
}
else if ( ! cursorAtSelectionStart & & ! endDomNode . isNull ( ) )
{
m_kafkaPart - > setCurrentNode ( endDomNode , endOffset ) ;
}
if ( ! startDomNode . isNull ( ) & & ! endDomNode . isNull ( ) )
m_kafkaPart - > setSelection ( DOM : : Range ( startDomNode , ( long ) startOffset , endDomNode , ( long ) endOffset ) ) ;
}
void KafkaDocument : : setCursor ( Node * cursorNode , int cursorOffset )
{
DOM : : Node domNode ;
long longDomNodeOffset ;
translateNodeIntoKafkaCursorPosition ( cursorNode , cursorOffset , domNode , longDomNodeOffset ) ;
if ( ! domNode . isNull ( ) & & domNode . nodeType ( ) ! = DOM : : Node : : TEXT_NODE & &
! domNode . firstChild ( ) . isNull ( ) & & domNode . firstChild ( ) . nodeType ( ) = = DOM : : Node : : TEXT_NODE )
domNode = domNode . firstChild ( ) ;
if ( ! domNode . isNull ( ) )
m_kafkaPart - > setCurrentNode ( domNode , ( int ) longDomNodeOffset ) ;
}
bool KafkaDocument : : buildKafkaNodeFromNode ( Node * node , bool insertNode )
{
# ifdef LIGHT_DEBUG
if ( node )
kdDebug ( 25001 ) < < " KafkaDocument::buildKafkaNodeFromNode() " < < endl ;
# endif
DOM : : Node newNode , newNode2 , attr , nextNode , parentNode , * ptDomNode ;
bool removeLeftWhitespaces , removeRightWhitespaces ;
TQString str , nodeValue ;
Node * n , * parent ;
int i ;
// Don't create DOM::Nodes from Quanta empty nodes outside the body or inside other not allowed element, or TDEHTML
// will give us problems.
bool canInsertEmptyNode = false ;
if ( node - > tag - > type = = Tag : : Empty )
{
if ( ! m_currentDoc - > defaultDTD ( ) - > name . contains ( " HTML " , false ) )
canInsertEmptyNode = true ;
else
canInsertEmptyNode = kafkaCommon : : hasParent ( node , " body " ) ;
Node * parent_node = node - > parent ;
TQTag * parent_node_description_tag = QuantaCommon : : tagFromDTD ( parent_node ) ;
if ( parent_node_description_tag & & ! parent_node_description_tag - > isChild ( node , false , true ) )
canInsertEmptyNode = false ;
}
if ( node - > tag - > type = = Tag : : XmlTag | |
( ( node - > tag - > type = = Tag : : Text | | ( node - > tag - > type = = Tag : : Empty & & canInsertEmptyNode ) ) & & ! node - > insideSpecial ) )
{
str = node - > tag - > name . lower ( ) ;
//The basics DOM::Nodes HTML, HEAD and BODY are loaded anyway, but we must now
// link the real HTML,... to their Nodes.
//A basic Common tree is !doctype<-html<-(head, body)
if ( ! node - > parent )
{ //FIXME:html, head and body are HTML-specific tag, for others DTDs it might result to some pbs.
if ( str = = " html " )
{
if ( ! html . isNull ( ) ) //delete the empty Node
disconnectDomNodeFromQuantaNode ( html ) ;
newNode = html ;
insertNode = false ;
}
else if ( str = = " body " )
{
if ( ! body . isNull ( ) )
disconnectDomNodeFromQuantaNode ( body ) ;
newNode = body ;
insertNode = false ;
}
else if ( str = = " head " )
{
if ( ! head . isNull ( ) )
disconnectDomNodeFromQuantaNode ( head ) ;
newNode = head ;
insertNode = false ;
}
else
{
if ( node - > tag - > type = = Tag : : Text | | node - > tag - > type = = Tag : : Empty )
{
newNode = kafkaCommon : : createTextDomNode ( " " , m_kafkaPart - > document ( ) ) ;
}
else
{
newNode = kafkaCommon : : createDomNode ( node , m_kafkaPart - > document ( ) ) ;
}
}
}
else if ( str = = " html " & & ( ! node - > parent | | ( node - > parent & & ! node - > parent - > parent ) ) )
{
if ( ! html . isNull ( ) ) //delete the empty Node
disconnectDomNodeFromQuantaNode ( html ) ;
newNode = html ;
insertNode = false ;
}
else if ( str = = " body " & & ( ( node - > parent & & ! node - > parent - > parent ) | | ( node - > parent & &
node - > parent - > parent & & ! node - > parent - > parent - > parent ) ) )
{
if ( ! body . isNull ( ) )
disconnectDomNodeFromQuantaNode ( body ) ;
newNode = body ;
insertNode = false ;
}
else if ( str = = " head " & & ( ( node - > parent & & ! node - > parent - > parent ) | | ( node - > parent & &
node - > parent - > parent & & ! node - > parent - > parent - > parent ) ) )
{
if ( ! head . isNull ( ) )
disconnectDomNodeFromQuantaNode ( head ) ;
newNode = head ;
insertNode = false ;
}
/** else if(node->parent->tag->str == "html")*/
else
{
if ( node - > tag - > type = = Tag : : Text | | node - > tag - > type = = Tag : : Empty )
{
newNode = kafkaCommon : : createTextDomNode ( " " , m_kafkaPart - > document ( ) ) ;
}
else
{
newNode = kafkaCommon : : createDomNode ( node - > tag - > name , m_currentDoc - > defaultDTD ( ) ,
m_kafkaPart - > document ( ) ) ;
}
}
if ( newNode . isNull ( ) )
{
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::buildKafkaNodeFromNode() - ERROR null newNode " < < endl ;
# endif
return false ;
}
connectDomNodeToQuantaNode ( newNode , node ) ;
if ( node - > tag - > type = = Tag : : Text | | node - > tag - > type = = Tag : : Empty )
{
//Now we get if the whitespaces at the left and right are kept or not.
//Left whitespaces are removed if:
//- It is the first child of a BLOCK
//- Previous Node(skipping inlines) is a text with spaces at the end
//Right whitespaces are removed if:
//- It is the last child of a BLOCK
removeLeftWhitespaces = false ;
n = node ;
parent = node - > parent ;
while ( parent & & parent - > SFirstChild ( ) = = n )
{
if ( ! kafkaCommon : : isInline ( parent - > tag - > name ) )
{
removeLeftWhitespaces = true ;
break ;
}
n = parent ;
parent = parent - > parent ;
}
if ( ! removeLeftWhitespaces )
{
n = node ;
n = kafkaCommon : : getPrevNodeNE ( n ) ;
while ( n & & ( n - > tag - > type = = Tag : : XmlTagEnd | |
( n - > tag - > type = = Tag : : XmlTag & & kafkaCommon : : isInline ( n - > tag - > name ) & &
! n - > tag - > single ) ) )
n = kafkaCommon : : getPrevNodeNE ( n ) ;
if ( n & & n - > tag - > type = = Tag : : Text )
{
nodeValue = n - > tag - > tagStr ( ) ;
if ( nodeValue . length ( ) > 0 & & nodeValue [ nodeValue . length ( ) - 1 ] . isSpace ( ) )
removeLeftWhitespaces = true ;
}
}
removeRightWhitespaces = false ;
n = node ;
parent = node - > parent ;
while ( parent & & parent - > SLastChild ( ) = = n )
{
if ( ! kafkaCommon : : isInline ( parent - > tag - > name ) )
{
removeRightWhitespaces = true ;
break ;
}
n = parent ;
parent = parent - > parent ;
}
nodeValue = node - > tag - > tagStr ( ) ;
nodeValue = getDecodedText ( nodeValue , ! kafkaCommon : : hasParent ( node , " pre " ) ,
removeLeftWhitespaces , removeRightWhitespaces ) ;
newNode . setNodeValue ( nodeValue ) ;
}
for ( i = 0 ; i < node - > tag - > attrCount ( ) ; i + + )
{
attr = kafkaCommon : : createDomNodeAttribute ( node , node - > tag - > attribute ( i ) ,
m_kafkaPart - > document ( ) ) ;
if ( ! attr . isNull ( ) )
{
//TODO: create a createAttr function and add this (setNodeValue sometimes
//don't like null TQString)
if ( ! node - > tag - > attributeValue ( i ) . isNull ( ) )
attr . setNodeValue ( node - > tag - > attributeValue ( i ) ) ;
kafkaCommon : : insertDomNodeAttribute ( newNode , attr ) ;
}
}
if ( node - > next & & node - > next - > tag & & node - > next - > tag - > name = =
( " / " + node - > tag - > name ) )
{
//DEPRECATED, NO USE TO CHANGE THE above check
node - > _closingNode = node - > next ;
}
if ( insertNode )
{
ptDomNode = new DOM : : Node ( newNode ) ;
node - > setRootNode ( ptDomNode ) ;
n = node ;
while ( n - > next )
{
n = n - > next ;
if ( n - > rootNode ( ) )
{
nextNode = * n - > rootNode ( ) ;
break ;
}
}
if ( node - > parent & & node - > parent - > leafNode ( ) )
parentNode = * node - > parent - > leafNode ( ) ;
else if ( node - > parent & & ! node - > parent - > leafNode ( ) )
{
//the parent tag was invalid and tdehtml refuse to insert it
//so impossible to inser the current node
disconnectDomNodeFromQuantaNode ( newNode ) ;
if ( node - > rootNode ( ) )
delete node - > rootNode ( ) ;
node - > setRootNode ( 0L ) ;
return false ;
}
else
parentNode = body ;
//Set the visual enhancements.
ptDomNode = new DOM : : Node ( newNode ) ;
node - > setLeafNode ( ptDomNode ) ;
mainEnhancer - > enhanceNode ( node , parentNode , nextNode ) ;
TQTag * qTag = QuantaCommon : : tagFromDTD ( getCurrentDoc ( ) - > defaultDTD ( ) ,
parentNode . nodeName ( ) . string ( ) ) ;
if ( qTag & & qTag - > isChild ( node , false ) )
{
if ( nextNode . isNull ( ) )
{
if ( ! kafkaCommon : : insertDomNode ( newNode , parentNode ) )
{
disconnectDomNodeFromQuantaNode ( newNode ) ;
if ( node - > rootNode ( ) )
delete node - > rootNode ( ) ;
node - > setRootNode ( 0L ) ;
return false ;
}
}
else
{
if ( ! kafkaCommon : : insertDomNode ( newNode , parentNode , nextNode ) )
{
disconnectDomNodeFromQuantaNode ( newNode ) ;
if ( node - > rootNode ( ) )
delete node - > rootNode ( ) ;
node - > setRootNode ( 0L ) ;
return false ;
}
}
}
}
else
{
ptDomNode = new DOM : : Node ( newNode ) ;
node - > setRootNode ( ptDomNode ) ;
ptDomNode = new DOM : : Node ( newNode ) ;
node - > setLeafNode ( ptDomNode ) ;
}
}
else
{
if ( node - > parent & & node - > parent - > leafNode ( ) )
parentNode = * node - > parent - > leafNode ( ) ;
else
parentNode = body ;
n = node ;
while ( n - > next )
{
n = n - > next ;
if ( n - > rootNode ( ) )
{
nextNode = * n - > rootNode ( ) ;
break ;
}
}
mainEnhancer - > enhanceNode ( node , parentNode , nextNode ) ;
}
return true ;
}
void KafkaDocument : : buildNodeFromKafkaNode ( Node * node , DOM : : Node domNode )
{
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " void KafkaDocument::buildNodeFromKafkaNode() - Node* DOM::Node " < < endl ;
# endif
long i ;
if ( ! node ) return ;
node - > tag - > setCleanStrBuilt ( false ) ;
node - > tag - > setIndentationDone ( false ) ;
if ( domNode . nodeType ( ) = = DOM : : Node : : TEXT_NODE )
{
TQString text = domNode . nodeValue ( ) . string ( ) ;
text . replace ( " < " , " < " ) ;
text . replace ( " > " , " > " ) ;
node - > tag - > setStr ( text ) ;
}
else
{
while ( node - > tag - > attrCount ( ) )
node - > tag - > deleteAttribute ( 0 ) ;
for ( i = 0 ; ( unsigned ) i < domNode . attributes ( ) . length ( ) ; i + + )
{
TagAttr attr ;
attr . name = domNode . attributes ( ) . item ( i ) . nodeName ( ) . string ( ) ;
attr . value = domNode . attributes ( ) . item ( i ) . nodeValue ( ) . string ( ) ;
attr . quoted = true ;
node - > tag - > addAttribute ( attr ) ;
}
}
}
Node * KafkaDocument : : buildNodeFromKafkaNode ( DOM : : Node domNode , Node * nodeParent ,
Node * beginNode , int beginOffset , Node */ * endNode */ , int endOffset , NodeModifsSet * modifs )
{
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " Node* KafkaDocument::buildNodeFromKafkaNode() - DOM::Node 2xNode* int: " < <
beginOffset < < " Node* int: " < < endOffset < < " NodeModifsSet " < < endl ;
# else
Q_UNUSED ( beginOffset ) ;
Q_UNUSED ( endOffset ) ;
# endif
DOM : : Node * ptDomNode ;
Node * node ;
if ( domNode . isNull ( ) )
{
kdDebug ( 25001 ) < < " Node* KafkaDocument::buildNodeFromKafkaNode(DOM::Node, 2xNode*) " < <
" *ERROR* - empty _domNode " < < endl ;
}
//nodeParent can be the false body node which is not in the tree.
if ( nodeParent - > tag - > notInTree ( ) )
nodeParent = 0L ;
/**_node = new Node(_nodeParent);*/
if ( domNode . nodeType ( ) = = DOM : : Node : : TEXT_NODE )
{
node = kafkaCommon : : createNode ( " #text " , " " , Tag : : Text , m_currentDoc ) ;
}
else
{
node = kafkaCommon : : createNode ( domNode . nodeName ( ) . string ( ) , " " ,
Tag : : XmlTag , m_currentDoc ) ;
}
buildNodeFromKafkaNode ( node , domNode ) ;
connectDomNodeToQuantaNode ( domNode , node ) ;
ptDomNode = new DOM : : Node ( domNode ) ;
node - > setRootNode ( ptDomNode ) ;
ptDomNode = new DOM : : Node ( domNode ) ;
node - > setLeafNode ( ptDomNode ) ;
kafkaCommon : : insertNode ( node , nodeParent , beginNode , beginNode , modifs , false ) ;
return node ;
}
TQString KafkaDocument : : getDecodedChar ( const TQString & encodedChar )
{
TQMap < TQString , TQString > : : Iterator it = encodedChars . find ( encodedChar ) ;
if ( it = = encodedChars . end ( ) )
{
//try this
return TDEGlobal : : charsets ( ) - > resolveEntities ( encodedChar ) ; ;
}
return it . data ( ) ;
}
TQString KafkaDocument : : getDecodedText ( const TQString & a_encodedText , bool translateWhiteSpacesAndLineBreaks ,
bool removeLeftWhitespaces , bool removeRightWhitespaces )
{
TQString encodedText = a_encodedText ;
if ( encodedText . isEmpty ( ) )
encodedText = " " ;
TQString decodedChar ;
int i , j ;
# ifdef LIGHT_DEBUG
TQString oldEncodedText = encodedText ;
# endif
i = - 1 ;
while ( ( unsigned ) + + i < encodedText . length ( ) & & translateWhiteSpacesAndLineBreaks )
{
if ( encodedText [ i ] . isSpace ( ) )
{
encodedText . remove ( i , 1 ) ;
encodedText . insert ( i , " " ) ;
while ( ( unsigned ) + + i < encodedText . length ( ) & & encodedText [ i ] . isSpace ( ) )
{
encodedText . remove ( i , 1 ) ;
i - - ;
}
}
}
i = - 1 ;
while ( ( unsigned ) + + i < encodedText . length ( ) )
{
if ( TQString ( encodedText [ i ] ) = = " & " )
{
j = i ;
while ( ( unsigned ) + + i < encodedText . length ( ) & &
TQString ( encodedText [ i ] ) ! = " ; " )
{ }
decodedChar = getDecodedChar ( encodedText . mid ( j , i - j + 1 ) ) ;
encodedText . remove ( j , i - j + 1 ) ;
//TODO:set a special behavior if the encoded symbol doesn't exist
encodedText . insert ( j , decodedChar ) ;
i = j + decodedChar . length ( ) - 1 ;
}
}
if ( translateWhiteSpacesAndLineBreaks & & removeLeftWhitespaces & & encodedText . length ( ) > 0 & &
encodedText [ 0 ] . isSpace ( ) )
encodedText . remove ( 0 , 1 ) ;
if ( translateWhiteSpacesAndLineBreaks & & removeRightWhitespaces & & encodedText . length ( ) > 0 & &
encodedText [ encodedText . length ( ) - 1 ] . isSpace ( ) )
encodedText . remove ( encodedText . length ( ) - 1 , 1 ) ;
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::getDecodedText() - \" " < < oldEncodedText < < " \" -> \" " < <
encodedText < < " \" " < < endl ;
# endif
return encodedText ;
//return TDEGlobal::charsets()->resolveEntities(encodedText); =>nice but not sufficient
}
TQString KafkaDocument : : getEncodedChar ( const TQString & decodedChar , const TQString & previousDecodedChar )
{
if ( decodedChar [ 0 ] . isSpace ( ) & & ! previousDecodedChar [ 0 ] . isSpace ( ) )
return " " ;
else if ( decodedChar [ 0 ] . isSpace ( ) )
//FIXME:for an unknown reason, by default it return ¿ instead of
return " " ;
TQMap < TQString , TQString > : : Iterator it = decodedChars . find ( decodedChar ) ;
if ( it = = decodedChars . end ( ) )
return decodedChar ;
return it . data ( ) ;
}
TQString KafkaDocument : : getEncodedText ( const TQString & a_decodedText , int bLine , int bCol , int & eLine , int & eCol ,
bool translateWhiteSpaces )
{
TQString decodedText = a_decodedText ;
TQString Encodedchar ;
TQString decodedChar , previousDecodedChar ;
# ifdef LIGHT_DEBUG
TQString oldDecodedText = decodedText ;
# endif
int i ;
# ifdef LIGHT_DEBUG
int _bLine = bLine , _bCol = bCol ;
# endif
i = - 1 ;
while ( ( unsigned ) + + i < decodedText . length ( ) )
{
previousDecodedChar = decodedChar ;
decodedChar = TQString ( decodedText [ i ] ) ;
if ( translateWhiteSpaces | | ! decodedText [ i ] . isSpace ( ) )
Encodedchar = getEncodedChar ( TQString ( decodedText [ i ] ) ,
( i > = 1 ) ? previousDecodedChar : TQString ( " " ) ) ;
else
Encodedchar = decodedChar ;
bCol + = Encodedchar . length ( ) ;
decodedText . remove ( i , 1 ) ;
decodedText . insert ( i , Encodedchar ) ;
i + = Encodedchar . length ( ) - 1 ;
}
eLine = bLine ;
eCol = bCol - 1 ;
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::getEncodedText() - " < < oldDecodedText < < " -> " < < decodedText < <
" - " < < _bLine < < " : " < < _bCol < < " - " < < eLine < < " : " < < eCol < < endl ;
# endif
return decodedText ;
}
TQString KafkaDocument : : getEncodedText ( const TQString & decodedText )
{
int a = 0 , b = 0 , c , d ;
return getEncodedText ( decodedText , a , b , c , d ) ;
}
TQString KafkaDocument : : generateCodeFromNode ( Node * node , int bLine , int bCol , int & eLine , int & eCol , bool encodeText )
{
TQString text , _char ;
Node * openingNode ;
int bLineAttr , bColAttr ;
int j = 0 ;
bool hasPreParent ;
if ( ! node ) return " " ;
if ( node - > tag - > type = = Tag : : XmlTag )
{
text = " < " + QuantaCommon : : tagCase ( node - > tag - > name ) ;
bCol + = node - > tag - > name . length ( ) + 1 ;
for ( j = 0 ; j < node - > tag - > attrCount ( ) ; j + + )
{
text + = " " ;
bCol + + ;
bLineAttr = bLine ;
bColAttr = bCol ;
text + = node - > tag - > attribute ( j ) ;
bCol + = node - > tag - > attribute ( j ) . length ( ) ;
//doctype have only attrNames.
if ( node - > tag - > name . lower ( ) ! = " !doctype " & & ! node - > tag - > getAttribute ( j ) . special )
{
text + = " = " ;
bCol + + ;
if ( node - > tag - > isQuotedAttribute ( j ) )
{
text + = qConfig . attrValueQuotation ;
bCol + + ;
}
node - > tag - > setAttributePosition ( j , bLineAttr , bColAttr , bLine , bCol ) ;
text + = node - > tag - > attributeValue ( j ) ;
bCol + = node - > tag - > attributeValue ( j ) . length ( ) ;
if ( node - > tag - > isQuotedAttribute ( j ) )
{
text + = qConfig . attrValueQuotation ;
bCol + + ;
}
}
else
node - > tag - > setAttributePosition ( j , bLineAttr , bColAttr , - 2 , - 2 ) ;
}
//only single Nodes except !doctype and ?xml nodes in XML tag style get the "/"
if ( node - > tag - > dtd ( ) - > singleTagStyle = = " xml " & &
( node - > tag - > single | | ( ! qConfig . closeOptionalTags & &
QuantaCommon : : isOptionalTag ( node - > tag - > dtd ( ) - > name , node - > tag - > name ) ) )
& & node - > tag - > name . lower ( ) ! = " ?xml " & & node - > tag - > name . lower ( ) ! = " !doctype " )
{
text + = " / " ;
bCol + = 2 ;
}
//?xml nodes get a "?"
if ( node - > tag - > name . lower ( ) = = " ?xml " )
{
text + = " ? " ;
bCol + + ;
}
text + = " > " ;
eCol = bCol ;
eLine = bLine ;
}
else if ( node - > tag - > type = = Tag : : XmlTagEnd )
{
openingNode = node - > getOpeningNode ( ) ;
if ( openingNode & & openingNode - > tag - > type = = Tag : : ScriptTag )
{
if ( openingNode - > tag - > name . contains ( " XML PI " , false ) | |
openingNode - > tag - > name . contains ( " PHP " , false ) )
text = " ?> " ;
else if ( openingNode - > tag - > name . contains ( " DTD " , false ) )
text = " > " ;
else
text = " > " ;
}
else
{
if ( node - > tag - > tagStr ( ) = = " --> " )
text = " --> " ;
else
text = " < " + QuantaCommon : : tagCase ( node - > tag - > name ) + " > " ;
}
bCol + = text . length ( ) ;
eCol = bCol - 1 ;
eLine = bLine ;
}
else if ( node - > tag - > type = = Tag : : Text )
{
hasPreParent = kafkaCommon : : hasParent ( node , " pre " ) ;
if ( encodeText )
text = getEncodedText ( node - > tag - > tagStr ( ) , bLine , bCol , eLine , eCol ,
! hasPreParent ) ;
/** Can't use TDEGlobal::charsets()->toEntity() :
* It translate all chars into entities ! */
else if ( ! hasPreParent )
text = node - > tag - > tagStr ( ) . replace ( TQRegExp ( " \\ s+ " ) , " " ) ;
else
text = node - > tag - > tagStr ( ) ;
}
else if ( node - > tag - > type = = Tag : : ScriptTag )
{
//WARNING : HTML SPECIFIC
if ( node - > tag - > name . contains ( " style " , false ) )
{
text = " < " + QuantaCommon : : tagCase ( " style " ) + " > " ;
}
else if ( node - > tag - > name . contains ( " DTD " , false ) )
{
text = " <! " ;
}
else if ( node - > tag - > name . contains ( " XML PI " , false ) )
{
text = " <?xml " ;
}
else if ( node - > tag - > name . contains ( " PHP " , false ) )
{
text = " <?php " ;
}
bCol + = text . length ( ) ;
eCol = bCol - 1 ;
eLine = bLine ;
}
else
{
//default behavior : return node->tag->tagStr()
text = node - > tag - > tagStr ( ) ;
kafkaCommon : : getEndPosition ( text , bLine , bCol , eLine , eCol ) ;
}
return text ;
}
void KafkaDocument : : translateQuantaIntoKafkaCursorPosition ( uint curLine , uint curCol , DOM : : Node & domNode , long & offset )
{
Node * node ;
int bCol , bLine , eCol , eLine , col , line ;
TQString curChar , decodedChar , currentLine ;
bool lookForEntity , lookForSpaces , found ;
node = baseNode ;
while ( node )
{
node - > tag - > beginPos ( bLine , bCol ) ;
node - > tag - > endPos ( eLine , eCol ) ;
if ( ( bLine < ( signed ) curLine | | ( bLine = = ( signed ) curLine & & bCol < = ( signed ) curCol ) ) & &
( eLine > ( signed ) curLine | | ( eLine = = ( signed ) curLine & & eCol > = ( signed ) curCol ) ) )
{
if ( bLine = = ( signed ) curLine & & bCol = = ( signed ) curCol & & node - > tag - > type ! = Tag : : Text & &
node - > previousSibling ( ) & & node - > previousSibling ( ) - > tag - > type = = Tag : : Text )
{
//if we are at the end of a text which is recognized as the beginning of the next tag
node = node - > previousSibling ( ) ;
//we can go directly to the last offset
if ( ! node - > rootNode ( ) )
{
offset = 0 ;
kdDebug ( 25001 ) < < " KafkaDocument::getKafkaCursorPosition() - ERROR DOM::Node not found "
< < endl ;
return ;
}
domNode = * node - > rootNode ( ) ;
offset = domNode . nodeValue ( ) . string ( ) . length ( ) ;
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::getKafkaCursorPosition() - " < <
domNode . nodeName ( ) . string ( ) < < " : " < < offset < < endl ;
# endif
return ;
}
col = bCol ;
line = bLine ;
break ;
}
node = node - > nextSibling ( ) ;
}
if ( ! node )
{
kdDebug ( 25001 ) < < " KafkaDocument::getKafkaCursorPosition() - ERROR node not found " < < endl ;
return ;
}
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::getKafkaCursorPosition() - node : " < < node - > tag - > name < < " : type: " < <
node - > tag - > type < < " : pos " < < bLine < < " : " < < bCol < < " - " < < eLine < < " : " < < eCol < < endl ;
# endif
offset = 0 ;
if ( node - > rootNode ( ) & & node - > rootNode ( ) - > nodeType ( ) = = DOM : : Node : : TEXT_NODE )
{
domNode = * node - > rootNode ( ) ;
currentLine = m_currentDoc - > editIf - > textLine ( line ) ;
if ( line < eLine )
currentLine + = " " ; //remplace the \n
while ( line < ( signed ) curLine | | ( col < ( signed ) curCol & & line = = ( signed ) curLine ) )
{
lookForEntity = false ;
lookForSpaces = false ;
curChar = currentLine . mid ( col , 1 ) ;
if ( curChar = = " & " )
lookForEntity = true ;
else if ( curChar [ 0 ] . isSpace ( ) )
lookForSpaces = true ;
found = false ;
while ( ! found )
{
if ( ( lookForEntity & & curChar = = " ; " ) | |
! ( lookForSpaces | | lookForEntity ) )
found = true ;
else if ( lookForSpaces & & ! curChar [ 0 ] . isSpace ( ) ) //curChar != " ")
break ;
if ( ( col + 1 ) > = ( signed ) currentLine . length ( ) )
{
line + + ;
col = 0 ;
currentLine = m_currentDoc - > editIf - > textLine ( line ) ;
if ( line < eLine )
currentLine + = " " ; //remplace the \n
}
else col + + ;
curChar = currentLine . mid ( col , 1 ) ;
}
# ifdef HEAVY_DEBUG
kdDebug ( 25001 ) < < " endpos at " < < line < < " : " < < col < < endl ;
# endif
offset + + ;
}
}
else if ( node - > rootNode ( ) )
offset = 0 ; //shoud we select?
else
m_kafkaPart - > putCursorAtFirstAvailableLocation ( ) ; //set the cursor in the first text
# ifdef LIGHT_DEBUG
if ( ! domNode . isNull ( ) )
kdDebug ( 25001 ) < < " KafkaDocument::getKafkaCursorPosition() - " < < domNode . nodeName ( ) . string ( ) < <
" : " < < offset < < endl ;
else
kdDebug ( 25001 ) < < " KafkaDocument::getKafkaCursorPosition() - NULL domNode " < < endl ;
# endif
}
void KafkaDocument : : translateQuantaIntoNodeCursorPosition ( uint line , uint col , Node * * node , long & offset )
{
int curCol , curLine , beginCol , beginLine ;
TQString currentLine ;
* node = parser - > nodeAt ( line , col , false ) ;
offset = 0 ;
if ( ! * node )
return ;
if ( ( * node ) - > tag - > cleanStrBuilt ( ) & & ( * node ) - > tag - > indentationDone ( ) )
{
( * node ) - > tag - > beginPos ( beginLine , beginCol ) ;
curLine = beginLine ;
curCol = beginCol ;
while ( curLine < ( signed ) line )
{
currentLine = ViewManager : : ref ( ) - > activeDocument ( ) - > editIf - > textLine ( curLine ) ;
if ( curLine = = beginLine )
offset + = ( signed ) currentLine . length ( ) - beginCol ;
else
offset + = ( signed ) currentLine . length ( ) ;
offset + + ;
curLine + + ;
}
if ( beginLine ! = ( signed ) line )
offset + = col ;
else
offset + = col - beginCol ;
}
else
{
//TODO
}
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::translateQuantaIntoNodeCursorPosition() - " < < * node < <
" : " < < offset < < endl ;
# endif
}
void KafkaDocument : : translateKafkaIntoNodeCursorPosition ( DOM : : Node domNode , long domNodeOffset , Node * * node , long & offset )
{
TQString decodedText , encodedChar , encodedText , currentChar ;
TQChar curChar , oldChar ;
long currentOffset ;
bool waitForSpace = false , found = false ;
int curNodeOffset , bLine = 0 , bCol = 0 , eLine , eCol ;
offset = 0 ;
( * node ) = 0L ;
if ( domNode . isNull ( ) )
{
# ifdef HEAVY_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::translateKafkaIntoNodeCursorPosition() " < <
" - DOM::Node not found! " < < endl ;
# endif
return ;
}
//get the corresponding Node*
( * node ) = getNode ( domNode ) ;
if ( ! ( * node ) )
{
# ifdef HEAVY_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::translateKafkaIntoNodeCursorPosition() " < <
" - Node not found! " < < endl ;
# endif
return ;
}
if ( ! ( * node ) - > tag )
{
# ifdef HEAVY_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::translateKafkaIntoNodeCursorPosition() " < <
" - Node tag not found! " < < endl ;
# endif
( * node ) = 0L ;
return ;
}
//If this node is selected (-1 means selected) then return "node selected" ;-)
if ( domNodeOffset = = - 1 )
{
return ;
}
if ( ! ( * node ) - > tag - > cleanStrBuilt ( ) )
{
//We NEED to have the up-to-date string in node.
( * node ) - > tag - > setStr ( generateCodeFromNode ( ( * node ) , bLine , bCol , eLine , eCol ) ) ;
//FIXME we shouldn't set it but if we don't the text will be re-encoded!
( * node ) - > tag - > setCleanStrBuilt ( true ) ;
}
decodedText = domNode . nodeValue ( ) . string ( ) ;
encodedText = ( * node ) - > tag - > tagStr ( ) ;
currentOffset = domNodeOffset ;
curNodeOffset = 0 ;
# ifdef HEAVY_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::translateKafkaIntoNodeCursorPosition() - decodedText: " < <
decodedText < < " : encoded text: " < < encodedText < < " : " < < endl ;
# endif
if ( ( * node ) - > tag - > type = = Tag : : Text )
{
while ( currentOffset > 0 )
{
curChar = decodedText . at ( domNodeOffset - currentOffset ) ;
# ifdef HEAVY_DEBUG
//kdDebug(24000)<< "CurChar:" << TQString(curChar) << ": oldChar:" <<
// TQString(oldChar) << endl;
# endif
encodedChar = getEncodedChar ( TQString ( curChar ) , TQString ( oldChar ) ) ;
if ( encodedChar = = " " )
encodedChar = " " ;
found = false ;
waitForSpace = false ;
while ( ! found )
{
# ifdef HEAVY_DEBUG
//kdDebug(25001)<< "look 4 :" << encodedChar << ": found :" <<
// encodedText.mid(curNodeOffset, encodedChar.length()) << endl;
# endif
if ( encodedChar ! = " " & & encodedChar = = encodedText . mid ( curNodeOffset ,
encodedChar . length ( ) ) )
found = true ;
else if ( encodedChar = = " " & & encodedText . mid ( curNodeOffset , 1 ) . at ( 0 ) . isSpace ( ) )
waitForSpace = true ;
else if ( waitForSpace )
break ; //no more spaces
else if ( encodedChar = = " " & & encodedText . mid ( curNodeOffset , 6 ) = = "   ; " )
{
encodedChar = " " ;
found = true ;
}
if ( curNodeOffset > ( signed ) encodedText . length ( ) | | encodedChar . isEmpty ( ) )
{
//The good nodeOffset was not found. Returns a default value.
//encodedChar.isEmpty() -->prevent an infinite loop
curNodeOffset = 0 ;
break ;
}
else
curNodeOffset + = encodedChar . length ( ) ;
}
oldChar = curChar ;
currentOffset - - ;
}
}
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::translateKafkaIntoNodeCursorPosition() - " < <
curNodeOffset < < endl ;
# endif
offset = curNodeOffset ;
}
void KafkaDocument : : translateKafkaIntoQuantaCursorPosition ( DOM : : Node _currentDomNode , int offset , int & line , int & col )
{
Node * _currentNode , * closingNode , * node ;
kNodeAttrs * attrs ;
TQString decodedText , encodedChar , currentLine , currentChar ;
TQChar curChar , oldChar ;
int currentOffset ;
int curLine , curCol , endLine , endCol ;
int i ;
bool waitForSpace = false , found = false ;
bool tagLeft = false , tagRight = false , tagMiddle = false ;
bool specialBehavior = false ;
//m_kafkaPart->getCurrentNode(_currentDomNode, offset);
currentOffset = offset ;
if ( _currentDomNode . isNull ( ) )
{
kdDebug ( 25001 ) < < " KafkaDocument::getQuantaCursorPosition() - DOM::Node not found! " < < endl ;
line = 0 ;
col = 0 ;
return ;
}
attrs = getAttrs ( _currentDomNode ) ;
if ( ! attrs )
{
kdDebug ( 25001 ) < < " KafkaDocument::getQuantaCursorPosition() - Attrs not found! " < < endl ;
line = 0 ;
col = 0 ;
return ;
}
//If the current DOM::Node has a special behavior (cf nodeproperties.h), get the nearest
//node which can get the focus!
if ( attrs - > specialBehavior ( ) ! = kNodeAttrs : : none )
{
specialBehavior = true ;
if ( attrs - > specialBehavior ( ) = = kNodeAttrs : : emptyTextSurroundingBlockElementAtTheLeft )
{
_currentDomNode = _currentDomNode . nextSibling ( ) ;
//tagRight means to put the cursor at the left of the tag so that the cursor
//looks at its right place (otherwise as there is no Node for this DOM::Node,
//the cursor won't go anywhere!)
tagLeft = true ;
}
else if ( attrs - > specialBehavior ( ) = = kNodeAttrs : : emptyTextSurroundingBlockElementAtTheRight )
{
_currentDomNode = _currentDomNode . previousSibling ( ) ;
tagRight = true ;
}
else if ( attrs - > specialBehavior ( ) = = kNodeAttrs : : emptyTextAsChildOfAChildlessElement )
{
_currentDomNode = _currentDomNode . parentNode ( ) ;
tagMiddle = true ;
}
attrs = getAttrs ( _currentDomNode ) ;
if ( ! attrs )
{
kdDebug ( 25001 ) < < " KafkaDocument::getQuantaCursorPosition() - Attrs not found! " < < endl ;
line = 0 ;
col = 0 ;
return ;
}
}
_currentNode = attrs - > getNode ( ) ;
if ( ! _currentNode /* && attrs->specialBehavior() == kNodeAttrs::none -- Andras: what happens if _currentNode is null, but this part of the if is not true?*/ )
{
kdDebug ( 25001 ) < < " KafkaDocument::getQuantaCursorPosition() - Node not found! " < < endl ;
line = 0 ;
col = 0 ;
return ;
}
decodedText = _currentDomNode . nodeValue ( ) . string ( ) ;
_currentNode - > tag - > beginPos ( curLine , curCol ) ;
_currentNode - > tag - > endPos ( endLine , endCol ) ;
currentLine = m_currentDoc - > editIf - > textLine ( curLine ) ;
if ( curLine < endLine )
currentLine + = " " ; //remplace the \n
if ( offset = = - 1 )
{
if ( m_currentDoc - > selectionIf )
m_currentDoc - > selectionIf - > setSelection ( curLine , curCol , endLine , endCol + 1 ) ;
line = endLine ;
col = endCol + 1 ;
return ;
}
# ifdef HEAVY_DEBUG
// kdDebug(25001)<< "KafkaDocument::getQuantaCursorPosition() - decodedText:"<< decodedText << ":" << endl;
# endif
if ( _currentNode - > tag - > type = = Tag : : Text )
{
while ( currentOffset > 0 )
{
curChar = decodedText [ offset - currentOffset ] ;
# ifdef HEAVY_DEBUG
// kdDebug(24000)<< "CurChar:" << TQString(curChar) << ": oldChar:" << TQString(oldChar) << endl;
# endif
encodedChar = getEncodedChar ( TQString ( curChar ) , TQString ( oldChar ) ) ;
if ( encodedChar = = " " )
encodedChar = " " ;
found = false ;
waitForSpace = false ;
while ( ! found )
{
# ifdef HEAVY_DEBUG
// kdDebug(25001)<< "look 4 :" << encodedChar << ": found :" <<
// currentLine.mid(curCol, encodedChar.length()) << endl;
// kdDebug(25001)<< "pos " << curLine << ":" << curCol << endl;
// kdDebug(25001)<< "endPos " << endLine << ":" << endCol << endl;
# endif
if ( encodedChar ! = " " & & encodedChar = = currentLine . mid ( curCol , encodedChar . length ( ) ) )
found = true ;
else if ( encodedChar = = " " & & currentLine . mid ( curCol , 1 ) . at ( 0 ) . isSpace ( ) )
waitForSpace = true ;
else if ( waitForSpace )
break ; //no more spaces
else if ( encodedChar = = " " & & currentLine . mid ( curCol , 6 ) = = "   ; " )
{
encodedChar = " " ;
found = true ;
}
if ( ( curCol > endCol & & curLine = = endLine ) | | curLine > endLine | |
encodedChar . length ( ) = = 0 )
{
//encodedChar.length() == 0 =>prevent infinite loop
curLine = endLine ;
curCol = endCol + 1 ;
currentOffset = 0 ;
break ;
}
else if ( ( curCol + encodedChar . length ( ) ) > = currentLine . length ( ) )
{
+ + curLine ;
curCol = 0 ;
currentLine = m_currentDoc - > editIf - > textLine ( curLine ) ;
if ( curLine < endLine )
currentLine + = " " ; //remplace the \n
}
else
{
curCol + = encodedChar . length ( ) ;
}
}
oldChar = curChar ;
- - currentOffset ;
}
}
else if ( _currentNode - > tag - > type = = Tag : : XmlTag )
{
//If we are in the special case
if ( specialBehavior )
{
if ( tagLeft )
_currentNode - > tag - > beginPos ( curLine , curCol ) ;
else if ( tagRight )
{
closingNode = _currentNode - > getClosingNode ( ) ;
if ( closingNode )
closingNode - > tag - > endPos ( curLine , curCol ) ;
else
_currentNode - > tag - > endPos ( curLine , curCol ) ;
+ + curCol ;
}
else
{
_currentNode - > tag - > endPos ( curLine , curCol ) ;
+ + curCol ;
}
}
else
{
if ( _currentNode - > tag - > single )
{
//The tag is single, there shouldn't be any (tag, x) location, but the old way
//was (tag,0) for left of the tag and (tag,1) for the right of the tag)
if ( offset = = 1 )
{
_currentNode - > tag - > endPos ( curLine , curCol ) ;
curCol + + ;
}
else
_currentNode - > tag - > beginPos ( curLine , curCol ) ;
}
else
{
//The new way to define cursor position.
node = _currentNode - > SFirstChild ( ) ;
i = 1 ;
while ( i < offset & & node & & node - > SNext ( ) )
{
node = node - > SNext ( ) ;
+ + i ;
}
if ( ! node )
node = _currentNode ;
if ( offset = = 0 )
node - > tag - > beginPos ( curLine , curCol ) ;
else
{
closingNode = node - > getClosingNode ( ) ;
if ( closingNode )
closingNode - > tag - > endPos ( curLine , curCol ) ;
else
node - > tag - > endPos ( curLine , curCol ) ;
+ + curCol ;
}
}
}
}
line = curLine ;
col = curCol ;
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::getQuantaCursorPosition() - " < < line < < " : " < < col < < endl ;
# endif
return ;
}
void KafkaDocument : : translateNodeIntoKafkaCursorPosition ( Node * node , int offset , DOM : : Node & domNode ,
long & domNodeOffset )
{
TQString textNode , curChar ;
int col ;
bool lookForEntity , lookForSpaces , found ;
if ( node & & node - > rootNode ( ) & & node - > rootNode ( ) - > nodeType ( ) = = DOM : : Node : : TEXT_NODE )
{
domNodeOffset = 0 ;
domNode = * node - > rootNode ( ) ;
textNode = node - > tag - > tagStr ( ) ;
col = 0 ;
while ( col < offset )
{
lookForEntity = false ;
lookForSpaces = false ;
curChar = textNode . mid ( col , 1 ) ;
if ( curChar = = " & " )
lookForEntity = true ;
else if ( curChar [ 0 ] . isSpace ( ) )
lookForSpaces = true ;
found = false ;
while ( ! found & & col < offset )
{
if ( ( lookForEntity & & curChar = = " ; " ) | |
! ( lookForSpaces | | lookForEntity ) )
found = true ;
else if ( lookForSpaces & & ! curChar [ 0 ] . isSpace ( ) ) //curChar != " ")
break ;
col + + ;
curChar = textNode . mid ( col , 1 ) ;
}
# ifdef HEAVY_DEBUG
//kdDebug(25001)<< "endpos at " << line << ":" << col << endl;
# endif
domNodeOffset + + ;
}
}
else if ( node & & node - > rootNode ( ) )
{
domNode = * node - > rootNode ( ) ;
domNodeOffset = 0 ; //shoud we select?
}
else
{
domNode = DOM : : Node ( ) ;
domNodeOffset = 0 ;
}
}
void KafkaDocument : : translateNodeIntoQuantaCursorPosition ( Node * node , int offset , uint & line , uint & col )
{
int curCol , curLine , curOffset ;
node - > tag - > beginPos ( curLine , curCol ) ;
line = curLine ;
col = curCol ;
curOffset = offset ;
while ( curOffset > 0 )
{
if ( node - > tag - > tagStr ( ) [ offset - curOffset ] = = ' \n ' )
line + + ;
else
col + + ;
curOffset - - ;
}
}
bool KafkaDocument : : insertDomNode ( DOM : : Node node , DOM : : Node parent ,
DOM : : Node nextSibling , DOM : : Node rootNode )
{
DOM : : Node siblingNSpecial ;
//First insert the node
if ( ! kafkaCommon : : insertDomNode ( node , parent , nextSibling , rootNode ) )
return false ;
//Then unEnhance and reEnhance the nearest non special nodes so that everything's fine.
siblingNSpecial = getPrevSiblingNSpecial ( node ) ;
if ( ! siblingNSpecial . isNull ( ) )
{
mainEnhancer - > postUnenhanceNode ( siblingNSpecial ) ;
mainEnhancer - > postEnhanceNode ( siblingNSpecial ) ;
}
siblingNSpecial = getNextSiblingNSpecial ( node ) ;
if ( ! siblingNSpecial . isNull ( ) )
{
mainEnhancer - > postUnenhanceNode ( siblingNSpecial ) ;
mainEnhancer - > postEnhanceNode ( siblingNSpecial ) ;
}
mainEnhancer - > postUnenhanceNode ( node . parentNode ( ) ) ;
mainEnhancer - > postEnhanceNode ( node . parentNode ( ) ) ;
mainEnhancer - > postEnhanceNode ( node ) ;
return true ;
}
bool KafkaDocument : : removeDomNode ( DOM : : Node node )
{
DOM : : Node nextSiblingNSpecial , prevSiblingNSpecial , parent ;
//First remove the node
prevSiblingNSpecial = getPrevSiblingNSpecial ( node ) ;
nextSiblingNSpecial = getNextSiblingNSpecial ( node ) ;
parent = node . parentNode ( ) ;
if ( ! kafkaCommon : : removeDomNode ( node ) )
return false ;
//Then unEnhance and reEnhance the nearest non special nodes so that everything's fine.
if ( ! prevSiblingNSpecial . isNull ( ) )
{
mainEnhancer - > postUnenhanceNode ( prevSiblingNSpecial ) ;
mainEnhancer - > postEnhanceNode ( prevSiblingNSpecial ) ;
}
if ( ! nextSiblingNSpecial . isNull ( ) )
{
mainEnhancer - > postUnenhanceNode ( nextSiblingNSpecial ) ;
mainEnhancer - > postEnhanceNode ( nextSiblingNSpecial ) ;
}
mainEnhancer - > postUnenhanceNode ( parent ) ;
mainEnhancer - > postEnhanceNode ( parent ) ;
return true ;
}
DOM : : Node KafkaDocument : : getPrevSiblingNSpecial ( DOM : : Node domNode )
{
kNodeAttrs * attrs ;
if ( domNode . isNull ( ) )
return DOM : : Node ( ) ;
domNode = domNode . previousSibling ( ) ;
while ( ! domNode . isNull ( ) )
{
attrs = getAttrs ( domNode ) ;
if ( ! attrs )
return DOM : : Node ( ) ;
if ( attrs - > specialBehavior ( ) = = kNodeAttrs : : none )
return domNode ;
domNode = domNode . previousSibling ( ) ;
}
return DOM : : Node ( ) ;
}
DOM : : Node KafkaDocument : : getNextSiblingNSpecial ( DOM : : Node domNode )
{
kNodeAttrs * attrs ;
if ( domNode . isNull ( ) )
return DOM : : Node ( ) ;
domNode = domNode . nextSibling ( ) ;
while ( ! domNode . isNull ( ) )
{
attrs = getAttrs ( domNode ) ;
if ( ! attrs )
return DOM : : Node ( ) ;
if ( attrs - > specialBehavior ( ) = = kNodeAttrs : : none )
return domNode ;
domNode = domNode . nextSibling ( ) ;
}
return DOM : : Node ( ) ;
}
void KafkaDocument : : readConfig ( TDEConfig * m_config )
{
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::readConfig() " < < endl ;
# endif
//for each nodeEnhancer
if ( mainEnhancer )
mainEnhancer - > readConfig ( m_config ) ;
//reload the document
reloadDocument ( ) ;
}
const DTDStruct * KafkaDocument : : defaultDTD ( )
{
return m_currentDoc - > defaultDTD ( ) ;
}
# ifdef HEAVY_DEBUG
void KafkaDocument : : coutLinkTree ( Node * node , int indent )
# else
void KafkaDocument : : coutLinkTree ( Node * , int )
# endif
{
# ifdef HEAVY_DEBUG
TQString output , dots ;
DOM : : Node domNode ;
Node * n = 0L ;
if ( ! node )
kdDebug ( 25001 ) < < " kafkaDocument::coutTree() - bad node! " < < endl ;
while ( node )
{
dots = " " ;
dots . fill ( ' * ' , indent ) ;
output = dots ;
if ( node - > tag - > type ! = Tag : : Text )
output + = node - > tag - > name . replace ( ' \n ' , " " ) ;
else
output + = node - > tag - > tagStr ( ) . replace ( ' \n ' , " " ) ;
output + = " ( " ;
output + = node - > tag - > type ;
output + = " ) " ;
n = 0L ;
if ( node - > rootNode ( ) )
{
domNode = * node - > rootNode ( ) ;
n = getNode ( domNode ) ;
}
kdDebug ( 25001 ) < < output < < " ( " < < node < < " ) " < < domNode . handle ( ) < < " - " < < n < < endl ;
if ( node - > child )
coutLinkTree ( node - > child , indent + 4 ) ;
node = node - > next ;
}
# endif
}
void KafkaDocument : : slotDomNodeInserted ( DOM : : Node domNode , bool insertChilds , NodeModifsSet * modifs )
{
# ifdef LIGHT_DEBUG
if ( ! domNode . isNull ( ) )
kdDebug ( 25001 ) < < " KafkaDocument::slotDomNodeInserted() - DOM::Node: " < <
domNode . nodeName ( ) . string ( ) < < endl ;
else
kdDebug ( 25001 ) < < " KafkaDocument::slotDomNodeInserted() - DOM::Node: NULL " < < endl ;
# endif
Node * _nodeParent = 0L , * nodeNext = 0L , * _node = 0L ;
DOM : : Node tmpDomNode , nextDomNode ;
bool b = false ;
# ifdef LIGHT_DEBUG
TQTime t ;
t . start ( ) ;
# endif
_nodeParent = getNode ( domNode . parentNode ( ) ) ;
if ( ! _nodeParent )
{ //DOM::Node not found, strange...
kdDebug ( 25001 ) < < " KafkaDocument::slotDomNodeInserted() - *ERROR* the " < <
" corresponding DOM::Node is not found! " < < endl ;
return ;
}
nextDomNode = getNextSiblingNSpecial ( domNode ) ;
if ( ! nextDomNode . isNull ( ) )
{
nodeNext = getNode ( nextDomNode ) ;
if ( ! nodeNext )
{
kdDebug ( 25001 ) < < " KafkaDocument::slotDomNodeInserted() - *ERROR2* " < <
" the corresponding DOM::Node is not found! " < < endl ;
return ;
}
}
_node = buildNodeFromKafkaNode ( domNode , _nodeParent , nodeNext , 0 , 0L , 0 , modifs ) ;
if ( insertChilds & & domNode . hasChildNodes ( ) )
{
//TODO: check if it is working
tmpDomNode = domNode . firstChild ( ) ;
while ( ! tmpDomNode . isNull ( ) )
{
buildNodeFromKafkaNode ( tmpDomNode ,
getNode ( tmpDomNode . parentNode ( ) ) , 0L , 0 , 0L , 0 , modifs ) ;
tmpDomNode = kafkaCommon : : getNextDomNode ( tmpDomNode , b , false , domNode ) ;
}
}
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::slotDomNodeInserted() in " < < t . elapsed ( ) < <
" ms only! " < < endl ;
# endif
# ifdef HEAVY_DEBUG
kafkaCommon : : coutTree ( baseNode , 2 ) ;
# endif
}
void KafkaDocument : : slotDomNodeModified ( DOM : : Node domNode , NodeModifsSet * modifs )
{
# ifdef LIGHT_DEBUG
if ( ! domNode . isNull ( ) )
kdDebug ( 25001 ) < < " KafkaDocument::slotDomNodeModified() - DOM::Node: " < <
domNode . nodeName ( ) . string ( ) < < endl ;
else
kdDebug ( 25001 ) < < " KafkaDocument::slotDomNodeModfied() - DOM::Node: NULL " < < endl ;
# endif
Node * node = 0L ;
NodeModif * modif ;
kNodeAttrs * props , * newProps ;
DOM : : Node newDomNode , parentDomNode , nextSiblingDomNode ;
DOM : : Node * ptDomNode ;
TQTag * qTag ;
# ifdef LIGHT_DEBUG
TQTime t ;
t . start ( ) ;
# endif
//gets the DOM::Node's kNodeAttrs
props = domNodeProps [ domNode . handle ( ) ] ;
if ( ! props )
{
kdDebug ( 25001 ) < < " KafkaDocument::slotDomNodeModified - *ERROR " < <
" missing kNodeAttrs for a DOM::Node!!! " < < endl ;
return ;
}
//First look if domNode has a corresponding Node.
if ( props - > isLinkedToNode ( ) )
{
//Look which Node correspond to this DOM::Node
node = props - > getNode ( ) ;
if ( ! node )
{ //DOM::Node not found, weird...
kdDebug ( 25001 ) < < " KafkaDocument::slotDomNodeModified() - *ERROR* the " < <
" corresponding DOM::Node is not found! " < < endl ;
return ;
}
modif = new NodeModif ( ) ;
modif - > setType ( NodeModif : : NodeModified ) ;
modif - > setTag ( new Tag ( * ( node - > tag ) ) ) ;
modif - > setLocation ( kafkaCommon : : getLocation ( node ) ) ;
buildNodeFromKafkaNode ( node , domNode ) ;
if ( ! modifs )
modifs = new NodeModifsSet ( ) ;
modifs - > addNodeModif ( modif ) ;
}
else
{
//no corresponding Node, we are in a special case with a special behavior.
qTag = QuantaCommon : : tagFromDTD ( getNode ( domNode . parentNode ( ) ) ) ;
if ( ( ( ! domNode . parentNode ( ) . isNull ( ) & & domNode . parentNode ( ) . nodeName ( ) = = " #document " ) | |
qTag ) & & (
props - > specialBehavior ( ) = = kNodeAttrs : : emptyTextSurroundingBlockElementAtTheLeft | |
props - > specialBehavior ( ) = = kNodeAttrs : : emptyTextSurroundingBlockElementAtTheRight | |
props - > specialBehavior ( ) = = kNodeAttrs : : emptyTextAsChildOfAChildlessElement ) )
{
//let's create the corresponding Text Node and the P tag only if necessary
modifs = new NodeModifsSet ( ) ;
modif = new NodeModif ( ) ;
parentDomNode = domNode . parentNode ( ) ;
nextSiblingDomNode = domNode . nextSibling ( ) ;
if ( ! qTag - > isChild ( " #text " , false ) )
{
newDomNode = kafkaCommon : : createDomNode ( " p " ,
getNode ( domNode . parentNode ( ) ) - > tag - > dtd ( ) , m_kafkaPart - > document ( ) ) ;
kafkaCommon : : removeDomNode ( domNode ) ;
kafkaCommon : : insertDomNode ( newDomNode , parentDomNode , nextSiblingDomNode ) ;
kafkaCommon : : insertDomNode ( domNode , newDomNode ) ;
node = kafkaCommon : : createNode ( " p " , " " , Tag : : XmlTag , m_currentDoc ) ;
newProps = connectDomNodeToQuantaNode ( newDomNode , node ) ;
ptDomNode = new DOM : : Node ( newDomNode ) ;
node - > setRootNode ( ptDomNode ) ;
ptDomNode = new DOM : : Node ( newDomNode ) ;
node - > setLeafNode ( ptDomNode ) ;
node = kafkaCommon : : insertNode ( node , getNode ( parentDomNode ) ,
getNode ( nextSiblingDomNode ) , getNode ( nextSiblingDomNode ) , modifs ) ;
newProps - > setNode ( node ) ;
modifs - > addNodeModif ( modif ) ;
parentDomNode = newDomNode ;
nextSiblingDomNode = DOM : : Node ( ) ;
modif = new NodeModif ( ) ;
}
node = kafkaCommon : : createNode ( " " , domNode . nodeValue ( ) . string ( ) , Tag : : Text ,
m_currentDoc ) ;
ptDomNode = new DOM : : Node ( domNode ) ;
node - > setRootNode ( ptDomNode ) ;
ptDomNode = new DOM : : Node ( domNode ) ;
node - > setLeafNode ( ptDomNode ) ;
//avoid the merging of Text Nodes
node = kafkaCommon : : insertNode ( node , getNode ( parentDomNode ) ,
getNode ( nextSiblingDomNode ) , modifs , false ) ;
props - > setNode ( node ) ;
modifs - > addNodeModif ( modif ) ;
//If there is a empty Node after of before the text, remove them
if ( node - > prev & & node - > prev - > tag - > type = = Tag : : Empty )
kafkaCommon : : extractNode ( node - > prev , modifs ) ;
if ( node - > next & & node - > next - > tag - > type = = Tag : : Empty )
kafkaCommon : : extractNode ( node - > next , modifs ) ;
//Log the changes
m_currentDoc - > docUndoRedo - > addNewModifsSet ( modifs , undoRedo : : KafkaModif ) ;
}
props - > setIsLinkedToNode ( true ) ;
props - > setSpecialBehavior ( kNodeAttrs : : none ) ;
}
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::slotDomNodeModified() in " < < t . elapsed ( ) < <
" ms only! " < < endl ;
# endif
# ifdef HEAVY_DEBUG
kafkaCommon : : coutTree ( baseNode , 2 ) ;
# endif
}
void KafkaDocument : : slotDomNodeAboutToBeRemoved ( DOM : : Node _domNode , bool deleteChilds , NodeModifsSet * modifs )
{
# ifdef LIGHT_DEBUG
if ( ! _domNode . isNull ( ) )
kdDebug ( 25001 ) < < " KafkaDocument::slotDomNodeAboutToBeRemoved() - DOM::Node: " < <
_domNode . nodeName ( ) . string ( ) < < " ( " < < _domNode . handle ( ) < < " ) " < < " bool : " < <
deleteChilds < < endl ;
else
kdDebug ( 25001 ) < < " KafkaDocument::slotDomNodeAboutToBeRemoved() - DOM::Node: NULL bool : " < <
deleteChilds < < endl ;
# endif
Node * _node = 0L , * _nodeNext = 0L , * _tmpNode = 0L , * n = 0L ;
int i , bLine , bCol , eLine , eCol , bLine2 , bCol2 ;
bool hasClosingNode = false , b ;
NodeModif * modif ;
# ifdef LIGHT_DEBUG
TQTime t ;
t . start ( ) ;
# endif
_node = getNode ( _domNode ) ;
if ( ! _node )
{
kdDebug ( 25001 ) < < " KafkaDocument::slotDomNodeAboutToBeRemoved() - *ERROR* the " < <
" corresponding DOM::Node is not found! " < < endl ;
return ;
}
//If we are deleting a PHP Node which is embedded into a tag e.g. <a <? echo boo; ?> >
//We must regenerate the <a> tag string.
if ( _node - > tag - > type = = Tag : : ScriptTag & & _node - > parent )
{
_node - > parent - > tag - > beginPos ( bLine , bCol ) ;
_node - > parent - > tag - > endPos ( eLine , eCol ) ;
_node - > tag - > beginPos ( bLine2 , bCol2 ) ;
if ( QuantaCommon : : isBetween ( bLine2 , bCol2 , bLine , bCol , eLine , eCol ) = = 0 )
_node - > parent - > tag - > setCleanStrBuilt ( false ) ;
}
if ( _node - > prev )
{
//delete the previous empty tag if present
_nodeNext = _node ;
_node = _node - > prev ;
if ( _node & & _node - > tag - > type = = Tag : : Empty )
{
modif = new NodeModif ( ) ;
modif - > setType ( NodeModif : : NodeRemoved ) ;
modif - > setLocation ( kafkaCommon : : getLocation ( _node ) ) ;
if ( _node - > parent & & _node - > parent - > child = = _node )
_node - > parent - > child = _node - > next ;
if ( _node - > prev )
_node - > prev - > next = _node - > next ;
if ( _node - > next )
_node - > next - > prev = _node - > prev ;
if ( _node = = baseNode )
baseNode = _node - > next ;
_node - > parent = 0L ;
_node - > prev = 0L ;
_node - > next = 0L ;
_node - > child = 0L ;
modif - > setNode ( _node ) ;
modifs - > addNodeModif ( modif ) ;
}
_node = _nodeNext ;
}
//delete the Node
modif = new NodeModif ( ) ;
if ( deleteChilds )
modif - > setType ( NodeModif : : NodeAndChildsRemoved ) ;
else
modif - > setType ( NodeModif : : NodeRemoved ) ;
modif - > setLocation ( kafkaCommon : : getLocation ( _node ) ) ;
if ( _node - > getClosingNode ( ) )
hasClosingNode = true ;
else
hasClosingNode = false ;
//_node->removeAll = false;
if ( _node - > parent & & _node - > parent - > child = = _node )
_node - > parent - > child = _node - > next ;
if ( _node - > next )
_node - > next - > prev = _node - > prev ;
if ( _node - > prev )
_node - > prev - > next = _node - > next ;
i = 0 ;
if ( _node - > child & & deleteChilds )
{
_tmpNode = _node - > child ;
b = false ;
while ( _tmpNode )
{
if ( _tmpNode - > rootNode ( ) )
disconnectDomNodeFromQuantaNode ( * _tmpNode - > rootNode ( ) ) ;
if ( _tmpNode - > leafNode ( ) )
disconnectDomNodeFromQuantaNode ( * _tmpNode - > leafNode ( ) ) ;
_tmpNode = kafkaCommon : : getNextNode ( _tmpNode , b , _node ) ;
}
//delete _node->child;
}
else if ( _node - > child ) // && !deleteChilds
{
if ( _node - > parent & & ! _node - > parent - > child )
_node - > parent - > child = _node - > child ;
if ( _node - > prev )
_node - > prev - > next = _node - > child ;
_tmpNode = _node - > child ;
while ( _tmpNode )
{
i + + ;
_tmpNode - > parent = _node - > parent ;
n = _tmpNode ;
_tmpNode = _tmpNode - > next ;
if ( ! _tmpNode )
{
n - > next = _node - > next ;
if ( _node - > next )
_node - > next - > prev = n ;
}
}
}
if ( _node = = baseNode )
baseNode = _node - > next ;
if ( _node - > rootNode ( ) )
disconnectDomNodeFromQuantaNode ( * _node - > rootNode ( ) ) ;
if ( _node - > leafNode ( ) )
disconnectDomNodeFromQuantaNode ( * _node - > leafNode ( ) ) ;
_node - > parent = 0L ;
_nodeNext = _node - > next ;
_node - > next = 0L ;
_node - > prev = 0L ;
_node - > child = 0L ;
modif - > setNode ( _node ) ;
//delete _node;
modif - > setChildrenMovedUp ( i ) ;
modifs - > addNodeModif ( modif ) ;
_node = _nodeNext ;
if ( hasClosingNode )
{
//delete the closing Node if present
if ( _node - > parent & & _node - > parent - > child = = _node )
_node - > parent - > child = _node - > next ;
if ( _node - > prev )
_node - > prev - > next = _node - > next ;
if ( _node - > next )
_node - > next - > prev = _node - > prev ;
_node - > parent = 0L ;
_nodeNext = _node - > next ;
_node - > next = 0L ;
_node - > prev = 0L ;
_node - > child = 0L ;
modif = new NodeModif ( ) ;
modif - > setType ( NodeModif : : NodeRemoved ) ;
modif - > setLocation ( kafkaCommon : : getLocation ( _node ) ) ;
modif - > setNode ( _node ) ;
modifs - > addNodeModif ( modif ) ;
//delete _node;
_node = _nodeNext ;
}
if ( _node & & _node - > tag - > type = = Tag : : Empty )
{
//delete the next empty tag if present
modif = new NodeModif ( ) ;
modif - > setType ( NodeModif : : NodeRemoved ) ;
modif - > setLocation ( kafkaCommon : : getLocation ( _node ) ) ;
if ( _node - > parent & & _node - > parent - > child = = _node )
_node - > parent - > child = _node - > next ;
if ( _node - > prev )
_node - > prev - > next = _node - > next ;
if ( _node - > next )
_node - > next - > prev = _node - > prev ;
_node - > parent = 0L ;
_nodeNext = _node - > next ;
_node - > prev = 0L ;
_node - > next = 0L ;
_node - > child = 0L ;
modif - > setNode ( _node ) ;
modifs - > addNodeModif ( modif ) ;
_node = _nodeNext ;
}
//NO NORMALIZATION!! It is KafkaWidget::normalize()'s job!
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::slotDomNodeDeleted() in " < < t . elapsed ( ) < <
" ms only! " < < endl ;
# endif
# ifdef HEAVY_DEBUG
kafkaCommon : : coutTree ( baseNode , 2 ) ;
# endif
}
void KafkaDocument : : slotDomNodeIsAboutToBeMoved ( DOM : : Node domNode , DOM : : Node newParent , DOM : : Node before , NodeModifsSet * modifs )
{
Node * node , * parent , * nextSibling , * closingNode ;
if ( domNode . isNull ( ) )
return ;
node = getNode ( domNode ) ;
parent = getNode ( newParent ) ;
nextSibling = getNode ( before ) ;
if ( ! node )
return ;
closingNode = node - > getClosingNode ( ) ;
kafkaCommon : : moveNode ( node , parent , nextSibling , modifs , false ) ;
if ( closingNode )
kafkaCommon : : moveNode ( closingNode , parent , nextSibling , modifs , false ) ;
}
void KafkaDocument : : slotdomNodeNewCursorPos ( DOM : : Node , int )
{
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " KafkaDocument::slotdomNodeNewCursorPos() " < < endl ;
# endif
//int line, col;
//dont calculate cursor pos until the next view update
//getQuantaCursorPosition(line, col);
//emit newCursorPosition(line, col);
}
void KafkaDocument : : slotCut ( )
{
TQString text = m_kafkaPart - > selectedText ( ) ;
NodeSelectionInd selection_ind ;
selection_ind . fillWithVPLCursorSelection ( ) ;
int startOffset = selection_ind . cursorOffset ( ) ;
int endOffset = selection_ind . cursorOffsetEndSel ( ) ;
Node * startNode = kafkaCommon : : getNodeFromLocation ( selection_ind . cursorNode ( ) ) ;
Node * endNode = kafkaCommon : : getNodeFromLocation ( selection_ind . cursorNodeEndSel ( ) ) ;
DOM : : Node cursorDomNode ;
long cursorOffset ;
m_kafkaPart - > getCurrentNode ( cursorDomNode , cursorOffset ) ;
Node * cursorNode = getNode ( cursorDomNode ) ;
slotCut ( startNode , startOffset , endNode , endOffset , & cursorNode , cursorOffset , text ) ;
}
void KafkaDocument : : slotCut ( Node * startNode , int startOffset , Node * endNode , int endOffset ,
Node * * cursorNode , long cursorOffset , TQString const & text )
{
if ( ! startNode | | ! endNode )
return ;
NodeModifsSet * modifs = new NodeModifsSet ( ) ;
Node * subtree_root = kafkaCommon : : DTDExtractNodeSubtree ( startNode , startOffset , endNode , endOffset ,
cursorNode , cursorOffset , modifs ) ;
m_currentDoc - > docUndoRedo - > addNewModifsSet ( modifs , undoRedo : : NodeTreeModif ) ;
//Now update the VPL cursor position
kafkaWidget - > setCurrentNode ( startNode , startOffset ) ;
if ( subtree_root )
{
KafkaDragObject * node_drag = new KafkaDragObject ( subtree_root ) ;
TQTextDrag * text_drag = new TQTextDrag ( text ) ;
KMultipleDrag * drag_object = new KMultipleDrag ( ) ;
drag_object - > addDragObject ( node_drag ) ;
drag_object - > addDragObject ( text_drag ) ;
TQApplication : : clipboard ( ) - > setData ( drag_object ) ;
# ifdef LIGHT_DEBUG
kafkaCommon : : coutTree ( subtree_root , 3 ) ;
# endif
}
}
void KafkaDocument : : slotCopy ( )
{
TQString text = m_kafkaPart - > selectedText ( ) ;
NodeSelectionInd selection_ind ;
selection_ind . fillWithVPLCursorSelection ( ) ;
int startOffset = selection_ind . cursorOffset ( ) ;
int endOffset = selection_ind . cursorOffsetEndSel ( ) ;
Node * startNode = kafkaCommon : : getNodeFromLocation ( selection_ind . cursorNode ( ) ) ;
Node * endNode = kafkaCommon : : getNodeFromLocation ( selection_ind . cursorNodeEndSel ( ) ) ;
slotCopy ( startNode , startOffset , endNode , endOffset , text ) ;
}
void KafkaDocument : : slotCopy ( Node * startNode , int startOffset , Node * endNode , int endOffset , TQString const & text )
{
if ( ! startNode | | ! endNode )
return ;
Node * subtree_root = kafkaCommon : : getNodeSubtree ( startNode , startOffset , endNode , endOffset ) ;
if ( subtree_root )
{
KafkaDragObject * node_drag = new KafkaDragObject ( subtree_root ) ;
TQTextDrag * text_drag = new TQTextDrag ( text ) ;
KMultipleDrag * drag_object = new KMultipleDrag ( ) ;
drag_object - > addDragObject ( node_drag ) ;
drag_object - > addDragObject ( text_drag ) ;
TQApplication : : clipboard ( ) - > setData ( drag_object ) ;
// FIXME delete the subtree
# ifdef LIGHT_DEBUG
kafkaCommon : : coutTree ( subtree_root , 3 ) ;
# endif
}
}
void KafkaDocument : : slotPaste ( )
{
TQClipboard * cb = TQApplication : : clipboard ( ) ;
TQMimeSource * e = cb - > data ( ) ;
Node * node = new Node ( 0 ) ;
if ( KafkaDragObject : : decode ( e , node ) )
{
bool go_up = false ;
for ( Node * aux = node ; aux ; aux = kafkaCommon : : getNextNode ( aux , go_up ) )
kafkaCommon : : restorePastedNode ( aux , getCurrentDoc ( ) ) ;
NodeSelectionInd selection_ind ;
selection_ind . fillWithVPLCursorSelection ( ) ;
Node * cursorNode = kafkaCommon : : getNodeFromLocation ( selection_ind . cursorNode ( ) ) ;
long cursorOffset = selection_ind . cursorOffset ( ) ;
NodeModifsSet * modifs = new NodeModifsSet ( ) ;
if ( selection_ind . hasSelection ( ) )
kafkaCommon : : DTDRemoveSelection ( selection_ind , & cursorNode , cursorOffset , modifs ) ;
else
cursorNode = 0 ; // use selection_ind
kafkaCommon : : DTDInsertNodeSubtree ( node , selection_ind , & cursorNode , cursorOffset , modifs ) ;
m_currentDoc - > docUndoRedo - > addNewModifsSet ( modifs , undoRedo : : NodeTreeModif , 0 , false ) ;
//Now update the VPL cursor position
kafkaWidget - > setCurrentNode ( cursorNode , cursorOffset ) ;
}
}