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

2275 lines
80 KiB

/***************************************************************************
kafkahtmlpart.cpp
-------------------
copyright : (C) 2001 - The Kafka Team
(C) 2003, 2004 - Nicolas Deschildre
email : kde-kafka@master.kde.org && 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. *
* *
***************************************************************************/
#include <tqfile.h>
#include <tqpainter.h>
#include <tqtextstream.h>
#include <tqstringlist.h>
#include <tqlayout.h>
#include <tqmainwindow.h>
#include <tqtimer.h>
#include <tqtooltip.h>
#include <tqpopupmenu.h>
#include <kdebug.h>
#include <tdelocale.h>
#include <tdehtmlview.h>
#include <tdemessagebox.h>
#include <ktrader.h>
#include <klibloader.h>
#include <tdeparts/factory.h>
#include <dom/dom_node.h>
#include <dom/dom_text.h>
#include <dom/dom_exception.h>
#include <dom/dom_string.h>
#include <dom/dom2_range.h>
#include <tdehtml_events.h>
//#include <tdehtml_part.h>
#include "kafkacommon.h"
#ifdef HEAVY_DEBUG
#include "domtreeview.h"
#include <tqdialog.h>
#endif
#include "wkafkapart.h"
#include "undoredo.h"
#include "nodeproperties.h"
#include "tagaction.h"
#include "tagactionset.h"
#include "document.h"
#include "resource.h"
#include "quantacommon.h"
#include "quanta.h"
#include "quantaview.h"
#include "tagattributetree.h"
#include "tagactionmanager.h"
#include "tagactionset.h"
#include "cursors.h"
#include "viewmanager.h"
class KafkaWidgetPrivate
{
public:
KafkaWidgetPrivate()
{}
~KafkaWidgetPrivate()
{}
int m_cursorOffset;
int m_pressOffset;
int m_releaseOffset;
/** when going up and down, trying to be as close as possible from the
original node X pos like a good text editor :=) */
bool stuckCursorHorizontalPos;
int stuckedCursorPosX;
#ifdef HEAVY_DEBUG
KafkaDOMTreeDialog *domdialog;
#endif
};
KafkaWidget::KafkaWidget(TQWidget *parent, TQWidget *widgetParent, KafkaDocument *part,
const char *name)
: TDEHTMLPart(widgetParent, name, parent, name),
w(part)
{
m_contextPopupMenu = new TQPopupMenu();
d = new KafkaWidgetPrivate();
d->m_cursorOffset = 0;
d->m_pressOffset = 0;
d->m_releaseOffset = 0;
d->stuckCursorHorizontalPos = false;
m_modifs = 0L;
view()->setInputMethodEnabled(true);
// With the mix of Leo Savernik's caret Mode and the current editing
// functions, it will be kind of VERY messy
setCaretMode(true);
connect(this, TQT_SIGNAL(caretPositionChanged(const DOM::Node &, long)),
this, TQT_SLOT(slotNewCursorPos(const DOM::Node &, long)));
setCaretDisplayPolicyNonFocused(TDEHTMLPart::CaretVisible);
connect(this, TQT_SIGNAL(popupMenu(const TQString&, const TQPoint&)),
this, TQT_SLOT(slotContextMenuRequested(const TQString&, const TQPoint&)));
view()->setMouseTracking(true);
view()->installEventFilter(this);
//for debug purposes, we add a DOM tree view
#ifdef HEAVY_DEBUG
//d->domdialog = new KafkaDOMTreeDialog(view(), this);
//d->domdialog->show();
#endif
//IMPORTANT:without him, no document() is created in tdehtmlPart
begin();
write("<html></html>");
end();
}
KafkaWidget::~KafkaWidget()
{}
void KafkaWidget::newDocument()
{
//FIXME: Somehow we should get it from Quanta settings: qConfig.attrValueQuotation
//-->No need for that: Quotations aren't stored in the DOM::Nodes
TQString newPageHTMLCode = "<html>\n"
"<head>\n"
"</head>\n"
"<body>\n"
"</body>\n"
"</html>\n";
begin();
write(newPageHTMLCode);
end();
}
void KafkaWidget::insertText(DOM::Node node, const TQString &text, int position)
{
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::insertText text " << text << " pos " << position << endl;
#endif
int focus;
kNodeAttrs *attrs = w->getAttrs(node);
if(!attrs)
return;
focus = attrs->chCurFoc();
if(position < 0)
return;//nothing to do if something is selected
//if(focus == kNodeAttrs::no || !cbModified) return;//can't add text in this Node.
if(position == 0 && node.nodeName().string().lower() == "body")
{
//SPECIFIC HTML code!!!
//doesn't work!
//putCursorAtFirstAvailableLocation();
if(!node.firstChild().isNull() && node.firstChild().nodeType() == DOM::Node::TEXT_NODE)
{
node = m_currentNode = node.firstChild();
position = 0;
}
if(position == 0 && node.nodeName().string().lower() == "body")
{
//We shouldn't go here...
DOM::Text textNode = document().createTextNode(text);
node.appendChild(textNode);
m_currentNode = textNode;
d->m_cursorOffset = text.length();
emit domNodeInserted(textNode, false, m_modifs);
#ifdef LIGHT_DEBUG
kdDebug(25001) << "KafkaWidget::insertText() - added text - 1" << endl;
#endif
TQTimer::singleShot(0, this, TQT_SLOT(slotDelayedSetCaretPosition()));
return;
}
}
if(focus == kNodeAttrs::textNode && node.nodeType() == DOM::Node::TEXT_NODE)
{
DOM::DOMString textNode = node.nodeValue();
DOM::DOMString textSplitted = textNode.split(position);
node.setNodeValue(textNode + text + textSplitted);
d->m_cursorOffset += text.length();
emit domNodeModified(node, m_modifs);
#ifdef LIGHT_DEBUG
kdDebug(25001) << "KafkaWidget::insertText() - added text" << endl;
#endif
}
else if(position == 0)
{
DOM::Text textNode = document().createTextNode(text);
DOM::Node parent = node.parentNode();
//FIXME: Andras: safety checks, as parent can be null. Maybe it just hides the error...
if (!parent.isNull())
parent.insertBefore(textNode, node);
else
node.appendChild(textNode);
m_currentNode = textNode;
d->m_cursorOffset = text.length();
emit domNodeInserted(textNode, false, m_modifs);
#ifdef LIGHT_DEBUG
kdDebug(25001) << "KafkaWidget::insertText() - added text - 2" << endl;
#endif
}
else if(position == 3 || (position == 1 && (focus == kNodeAttrs::singleNodeAndItself)))
{
DOM::Text textNode = document().createTextNode(text);
DOM::Node parent = node.parentNode();
//FIXME: Andras: safety checks, as parent and node.nextSibling can be null. Maybe it just hides the error...
//Also it seems that position can be 3 and node is "body". See bug 112733.
if (node.nodeName().string().lower() != "body" && !parent.isNull())
{
if (!node.nextSibling().isNull())
parent.insertBefore(textNode, node.nextSibling());
else
parent.insertBefore(textNode, node);
}
else
node.appendChild(textNode);
m_currentNode = textNode;
d->m_cursorOffset = text.length();
emit domNodeInserted(textNode, false, m_modifs);
#ifdef LIGHT_DEBUG
kdDebug(25001) << "KafkaWidget::insertText() - added text - 3" << endl;
#endif
}
else if(position == 1)
{
DOM::Text textNode = document().createTextNode(text);
if(!node.firstChild().isNull())
node.insertBefore(textNode, node.firstChild());
else
node.appendChild(textNode);
m_currentNode = textNode;
d->m_cursorOffset = text.length();
emit domNodeInserted(textNode, false, m_modifs);
#ifdef LIGHT_DEBUG
kdDebug(25001) << "KafkaWidget::insertText() - added text - 4" << endl;
#endif
}
//document().updateRendering();
TQTimer::singleShot(0, this, TQT_SLOT(slotDelayedSetCaretPosition()));
}
void KafkaWidget::slotDelayedSetCaretPosition()
{
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
}
void KafkaWidget::insertText(const TQString &text, int position)
{
insertText(m_currentNode, text, (position == -1 ? d->m_cursorOffset : position));
}
void KafkaWidget::normalize(DOM::Node _node)
{
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::normalize()" << endl;
#endif
//FIXME: Andras: getAttrs() can sometimes return NULL and causes a crash. No idea why and what it means though.
DOM::Node childNode = _node.firstChild();
while(!childNode.isNull())
{
if(w->getAttrs(childNode) && w->getAttrs(childNode)->chCurFoc() == kNodeAttrs::textNode)
{
while(!childNode.nextSibling().isNull() &&
w->getAttrs(childNode.nextSibling()) && w->getAttrs(childNode.nextSibling())->chCurFoc() ==
kNodeAttrs::textNode )
{
childNode.setNodeValue(childNode.nodeValue() +
childNode.nextSibling().nodeValue());
emit domNodeModified(childNode, m_modifs);
emit domNodeIsAboutToBeRemoved(childNode.nextSibling(), true, m_modifs);
_node.removeChild(childNode.nextSibling());
}
}
childNode = childNode.nextSibling();
}
}
void KafkaWidget::keyReturn(bool specialPressed)
{
//WARNING : HTML-specific function
DOM::Node text, text2, pDomNode, pDomNode2, brDomNode, brDomNode2, tmp, PNode, emptyText;
int focus;
// TQTag *qTag;
bool childOfP;
//kNodeAttrs *props;
if(m_currentNode.isNull())
return;
if(!w->getAttrs(m_currentNode))
return;
focus = w->getAttrs(m_currentNode)->chCurFoc();
if (focus == kNodeAttrs::textNode)
{
//First determine if the current Node is a child of a P
childOfP = false;
tmp = m_currentNode;
while(!tmp.isNull())
{
if(tmp.nodeName().string().lower() == "p")
{
PNode = tmp;
childOfP = true;
break;
}
tmp = tmp.parentNode();
}
//Then split if necessary the text
if((static_cast<DOM::CharacterData>(m_currentNode)).length() == 0)
text = m_currentNode;
else if(d->m_cursorOffset <= 0)
text2 = m_currentNode;
else if((unsigned)d->m_cursorOffset >=
(static_cast<DOM::CharacterData>(m_currentNode)).length())
text = m_currentNode;
else
{
text = m_currentNode;
text2 = (static_cast<DOM::Text>(m_currentNode)).splitText(d->m_cursorOffset);
emit domNodeModified(m_currentNode, m_modifs);
emit domNodeInserted(text2, false, m_modifs);
}
if(!specialPressed)
{
if(childOfP)
{}
else
{}
}
else
{
if(childOfP)
{}
else
{}
}
//Then look if we are in a area which can handle a P
//and if it is ok and necessary, insert the current text in a P
//TODO: Change a bit for the p so that it handle every case
/**qTag = QuantaCommon::tagFromDTD(w->getCurrentDoc()->defaultDTD(),
m_currentNode.parentNode().nodeName().string());
pDomNode = kafkaCommon::hasParent(m_currentNode, "p");
if(pDomNode.isNull() && qTag && qTag->isChild("p"))
{
if(!text.isNull())
{
emit domNodeIsAboutToBeRemoved(text, false);
w->removeDomNode(text);
}
pDomNode = kafkaCommon::createDomNode("p", w->getCurrentDoc()->defaultDTD(),
document());
w->insertDomNode(pDomNode, m_currentNode.parentNode(),
m_currentNode.nextSibling());
emit domNodeInserted(pDomNode, false);
if(!text.isNull())
{
w->::insertDomNode(text, pDomNode);
emit domNodeInserted(text, false);
}
}
//Then we insert either a P or a BR tag.
if(qTag && qTag->isChild("p") && !pDomNode.isNull())
{
if(!text2.isNull())
{
emit domNodeIsAboutToBeRemoved(text2, false);
w->::removeDomNode(text2);
}
pDomNode2 = kafkaCommon::createDomNode("p", w->getCurrentDoc()->defaultDTD(),
document());
w->insertDomNode(pDomNode2, pDomNode.parentNode(),
pDomNode.nextSibling());
emit domNodeInserted(pDomNode2, false);
if(!text2.isNull())
{
w->insertDomNode(text2, pDomNode2);
emit domNodeInserted(text2, false);
}
m_currentNode = pDomNode2.firstChild();
d->m_cursorOffset = 0;
}
else
{*/
brDomNode = kafkaCommon::createDomNode("br", w->getCurrentDoc()->defaultDTD(),
document());
if(!text.isNull())
w->insertDomNode(brDomNode, m_currentNode.parentNode(),
text.nextSibling());
else
w->insertDomNode(brDomNode, m_currentNode.parentNode(),
text2);
emit domNodeInserted(brDomNode, false, m_modifs);
if(!text2.isNull())
m_currentNode = text2;
else
{
if(!brDomNode.nextSibling().isNull())
m_currentNode = brDomNode.nextSibling();
if(!brDomNode.nextSibling().isNull() && brDomNode.nextSibling().nextSibling().isNull())
{
//TEMP before the webcore caret.
brDomNode2 = kafkaCommon::createDomNode("br", w->getCurrentDoc()->defaultDTD(),
document());
if(!brDomNode.nextSibling().isNull())
w->insertDomNode(brDomNode2, m_currentNode.parentNode(),
DOM::Node());
emit domNodeInserted(brDomNode2, false, m_modifs);
m_currentNode = brDomNode;
}
}
d->m_cursorOffset = 0;
}
else if( m_currentNode.nodeName().string().lower() == "br")
{
brDomNode = kafkaCommon::createDomNode("br", w->getCurrentDoc()->defaultDTD(),
document());
w->insertDomNode(brDomNode, m_currentNode.parentNode(),
brDomNode.nextSibling());
emit domNodeInserted(brDomNode, false, m_modifs);
m_currentNode = brDomNode;
d->m_cursorOffset = 0;
}
#ifdef HEAVY_DEBUG
kdDebug(25001)<< "CURNODE : " << m_currentNode.nodeName().string() << ":"
<< m_currentNode.nodeValue().string() << " : " << d->m_cursorOffset << endl;
TQTimer::singleShot(0, this, TQT_SLOT(slotDelayedSetCaretPosition()));
kdDebug(25001)<< "CURNODE : " << m_currentNode.nodeName().string() << ":"
<< m_currentNode.nodeValue().string() << " : " << d->m_cursorOffset << endl;
//emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
// kdDebug(25001)<< "CURNODE : " << m_currentNode.nodeName().string() << ":"
// << m_currentNode.nodeValue().string() << " : " << d->m_cursorOffset << endl;
//postprocessCursorPosition();
kdDebug(25001)<< "CURNODE : " << m_currentNode.nodeName().string() << ":"
<< m_currentNode.nodeValue().string() << " : " << d->m_cursorOffset << endl;
#endif
TQTimer::singleShot(0, this, TQT_SLOT(slotDelayedSetCaretPosition()));
}
bool KafkaWidget::eventFilter(TQObject *, TQEvent *event)
{
bool forgetEvent = false;
//tmp
//DOM::Node attr, tmpNode;
//end tmp
if(event->type() == TQEvent::FocusIn)
{
#ifdef LIGHT_DEBUG
kdDebug(25001) << "KafkaWidget::eventFilter() FocusIn" << endl;
#endif
emit hasFocus(true);
}
if(event->type() == TQEvent::FocusOut)
{
#ifdef LIGHT_DEBUG
kdDebug(25001) << "KafkaWidget::eventFilter() FocusOut" << endl;
#endif
emit hasFocus(false);
}
if(event->type() == TQEvent::KeyPress || event->type() == TQEvent::IMEnd)
{
TQKeyEvent *keyevent = static_cast<TQKeyEvent*>(event);
//Create a new NodeModifsSet where the changes will be logged.
m_modifs = new NodeModifsSet();
switch(keyevent->key())
{
case Key_Left:
#ifdef LIGHT_DEBUG
kdDebug(25001) << "KafkaWidget::eventFilter() Left" << endl;
#endif
//previousOffset(1);
d->stuckCursorHorizontalPos = false;
//forgetEvent = true;//to avoid the scrolling of the page
break;
case Key_Right:
#ifdef LIGHT_DEBUG
kdDebug(25001) << "KafkaWidget::eventFilter() Right" << endl;
#endif
//nextOffset(1);
d->stuckCursorHorizontalPos = false;
//forgetEvent = true;
break;
case Key_Backspace:
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::eventFilter() Backspace" << endl;
#endif
keyBackspace();
d->stuckCursorHorizontalPos = false;
break;
case Key_Delete:
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::eventFilter() Delete" << endl;
#endif
keyDelete();
d->stuckCursorHorizontalPos = false;
break;
case Key_Up:
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::eventFilter() Up" << endl;
#endif
//keyUp();
//forgetEvent = true;
break;
case Key_Down:
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::eventFilter() Down" << endl;
#endif
//keyDown();
//forgetEvent = true;
break;
case Key_Escape:
break;
case Key_Tab:
if(!m_currentNode.isNull() && w->getAttrs(m_currentNode) &&
w->getAttrs(m_currentNode)->chCurFoc() != kNodeAttrs::no)
{
// @todo check tab settings in Quanta
if(hasSelection())
removeSelection();
insertText(" ", -1);
makeCursorVisible();
}
forgetEvent = true;
d->stuckCursorHorizontalPos = false;
break;
case Key_BackTab:
break;
case Key_Return:
case Key_Enter:
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::eventFilter() Return" << endl;
#endif
if(hasSelection())
removeSelection();
applyQueuedToggableTagActions();
keyReturn(keyevent->state() & ControlButton);
d->stuckCursorHorizontalPos = false;
break;
case Key_Insert:
break;
case Key_Pause:
#ifdef HEAVY_DEBUG
kafkaCommon::coutTree(baseNode, 2);
kafkaCommon::coutDomTree(document(), 2);
w->coutLinkTree(baseNode, 2);
#endif
break;
case Key_Print:
break;
case Key_SysReq:
break;
case Key_Home:
d->stuckCursorHorizontalPos = false;
break;
case Key_End:
d->stuckCursorHorizontalPos = false;
break;
case Key_Next:
break;
case Key_Shift:
break;
case Key_Control:
break;
case Key_Meta:
break;
case Key_Alt:
break;
case Key_CapsLock:
break;
case Key_NumLock:
break;
case Key_ScrollLock:
break;
default:
if(m_currentNode.isNull())
{
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::eventFilter() - DOM::Node NULL" << endl;
#endif
break;
}
else if(w->getAttrs(m_currentNode) &&
w->getAttrs(m_currentNode)->chCurFoc() != kNodeAttrs::no ||
m_currentNode.nodeName().string().lower() == "body")
{
#ifdef LIGHT_DEBUG
kdDebug(25001) << "KafkaWidget::eventFilter() Text - " <<
keyevent->text() << endl;
#endif
//if(( keyevent->state() & TQt::ShiftButton) || ( keyevent->state() == TQt::NoButton))
if( keyevent->text().length() &&
( !( keyevent->state() & ControlButton ) &&
!( keyevent->state() & AltButton ) &&
!( keyevent->state() & MetaButton ) ||
( ( (keyevent->state()&ControlButton) | AltButton ) == (ControlButton|AltButton) ) ) &&
( !keyevent->ascii() || keyevent->ascii() >= 32 || keyevent->text() == "\t" ) || event->type() == TQEvent::IMEnd )
{
if(hasSelection())
removeSelection();
applyQueuedToggableTagActions();
insertText(keyevent->text(), -1);
}
makeCursorVisible();
#ifdef HEAVY_DEBUG
//w->coutLinkTree(baseNode, 2);
#endif
}
forgetEvent = true;
d->stuckCursorHorizontalPos = false;
break;
}
//Submit the modifs to the undoRedo system.
ViewManager::ref()->activeDocument()->docUndoRedo->addNewModifsSet(m_modifs, undoRedo::KafkaModif, 0, qConfig.replaceAccented);
m_modifs = 0L;
}
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "Current Offset : " << m_currentNode.nodeName().string() << ":" <<
d->m_cursorOffset << " (" << event->type() << ")" << endl;
#endif
return forgetEvent;
}
void KafkaWidget::slotContextMenuRequested(const TQString& /*url*/, const TQPoint& point)
{
TagActionManager::self()->fillWithTagActions(m_contextPopupMenu, nodeUnderMouse());
if(m_contextPopupMenu->count() != 0)
m_contextPopupMenu->popup(point);
}
#if 0
void KafkaWidget::keyDeleteNodes(DOM::Node &startNode, long &offset, bool backspace)
{
DOM::Node domNode = startNode, nextNode;
kNodeAttrs *attrs;
long nextOffset;
DOM::DOMString nodeText, textSplitted;
while(!domNode.isNull())
{
//Start by getting the attributes of the Node
attrs = w->getAttrs(domNode);
if(!attrs)
{
#ifdef LIGHT_DEBUG
kdDebug(25001)<<"KafkaWidget::keyDeleteNodes() - ERROR KNodeAttrs not found!"
<< endl;
#endif
break;
}
//Get the next Location
nextNode = domNode;
nextOffset = offset;
if(backspace)
getPrevNodeRangeSpecs(nextNode, offset, blok! );
else
getNextNodeRangeSpecs(nextNode, offset);
//Nodes that can't be deleted stop the cursor (e.g. TBODY)
if(!attrs->cbDel())
break;
//If we are in some text, and a letter can be deleted, delete it.
if(domNode.nodeType() == DOM::Node::TEXT_NODE && ((backspace && offset != 0)) ||
(!backspace && offset != (static_cast<DOM::CharacterData>(domNode)).length()))
)
{
nodeText = domNode.nodeValue();
textSplitted = nodeText.split(backspace?offset:offset + 1);
nodeText.split(backspace?offset - 1:offset);
domNode.setNodeValue(nodeText + textSplitted);
//m_currentNode.parentNode().applyChanges();
emit domNodeModified(domNode);
//postprocessCursorPosition();
break;
}
//If we are in an empty text (shoudn't occur), delete it
if(domNode.nodeType()
== DOM::Node::TEXT_NODE &&
(static_cast<DOM::CharacterData>(domNode)).length() == 0)
{
emit domNodeIsAboutToBeRemoved(domNode, true);
domNode.parentNode().removeChild(domNode);
domNode = nextNode;
continue;
}
//If we are in an empty Node (Inline), delete it
if(domNode.nodeType()
== DOM::Node::ELEMENT_NODE && offset == 0 && !domNode.hasChildNodes())
{
continue;
}
//If the current Node is an empty Text, delete it
if()
{
continue;
}
//If the current Node is an empty Node (kNodeAttrs::singleNodeAndItself)), delete it
if()
{
return;
}
//If the current Node is an empty Node (Inline) delete it
if()
{
continue;
}
}
}
#endif
void KafkaWidget::keyDelete()
{
kNodeAttrs *attrs, *attrsTmp;
int focus, childPosition;
DOM::Node _nodeParent, _node, _nodeNext, temp, tempParent, nextSibling, nodeNextNext;
DOM::Node toplevelBlock, toplevelBlock2, startNode, endNode, startNode2, endNode2;
DOM::Node childOfCommonParent, childOfCommonParent2, commonParent;
bool _goingTowardsRootNode, isParent, singleNodeDeleted, nextIsBlock, startNode2IsNotInline;
if(hasSelection())
{
removeSelection();
return;
}
if(m_currentNode.isNull())
return;
attrs = w->getAttrs(m_currentNode);
if(!attrs)
return;
//OLD PART, TO BE REMOVED or #ifdef'ed
if(attrs->chCurFoc() == kNodeAttrs::textNode && (unsigned)d->m_cursorOffset !=
(static_cast<DOM::CharacterData>(m_currentNode)).length())
{//if we are in the middle of some text, we remove one letter
if(!attrs->cbMod())
return;
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::keyDelete() - one letter removed - 1" << endl;
#endif
DOM::DOMString nodeText = m_currentNode.nodeValue();
DOM::DOMString textSplitted = nodeText.split(d->m_cursorOffset + 1);
nodeText.split(d->m_cursorOffset);
m_currentNode.setNodeValue(nodeText + textSplitted);
m_currentNode.parentNode().applyChanges();
emit domNodeModified(m_currentNode, m_modifs);
postprocessCursorPosition();
return;
}
if(attrs->chCurFoc() != kNodeAttrs::no && attrs->chCurFoc() != kNodeAttrs::textNode &&
d->m_cursorOffset < 0)
{//if we delete ourselves, which node will be m_currentNode??
if(!attrs->cbDel())
return;
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::keyDelete() - deleting a Node - 2" << endl;
#endif
DOM::Node _node = m_currentNode;
bool b = false;
while(1)
{//try to find a prev node from which we can delete the node
_node = getPrevNode(_node, b);
if(_node == 0)
break;
attrs = w->getAttrs(_node);
if(attrs && attrs->chCurFoc() == kNodeAttrs::textNode)
{
m_currentNode = _node;
d->m_cursorOffset =
(static_cast<DOM::CharacterData>(_node)).length();
keyDelete();
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
return;
}
if(attrs && attrs->chCurFoc() != kNodeAttrs::no &&
attrs->chCurFoc() != kNodeAttrs::textNode)
{
m_currentNode = _node;
d->m_cursorOffset = 1;
keyDelete();
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
return;
}
}
b = false;
while(1)
{//try to find a next node from which we can delete the node
_node = getNextNode(_node, b);
if(_node == 0)
break;
attrs = w->getAttrs(_node);
if(attrs && attrs->chCurFoc() != kNodeAttrs::no)
{
m_currentNode = _node;
d->m_cursorOffset = 0;
keyBackspace();
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
return;
}
}
//here, there is no node right and left that can have the cursor focus
_node = m_currentNode.parentNode();
emit domNodeIsAboutToBeRemoved(m_currentNode, true, m_modifs);
_node.removeChild(m_currentNode);
m_currentNode = document().createTextNode("");
_node.appendChild(m_currentNode);
emit domNodeInserted(m_currentNode, false, m_modifs);
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
}
//Beginning of the actual keyDelete
_node = m_currentNode;
_goingTowardsRootNode = false;
singleNodeDeleted = false;
_nodeNext = getNextNode(_node, _goingTowardsRootNode);
while(!_nodeNext.isNull())
{
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::keyDelete() - currentNode: " <<
_nodeNext.nodeName().string() << endl;
#endif
attrs = w->getAttrs(_nodeNext);
//If this Node can't be deleted, we stop here.
if(!attrs || !attrs->cbDel())
return;
//If we are in a TEXT node, we remove a letter
if(attrs->chCurFoc() == kNodeAttrs::textNode)
{
if((static_cast<DOM::CharacterData>(_nodeNext)).length() != 0)
{
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::keyDelete() - one letter" <<
" removed - 2" << endl;
#endif
DOM::DOMString nodeText = _nodeNext.nodeValue();
DOM::DOMString textSplitted = nodeText.split(1);
_nodeNext.setNodeValue(textSplitted);
emit domNodeModified(_nodeNext, m_modifs);
postprocessCursorPosition();
normalize(_nodeNext.parentNode());
break;
}
else
{//if we are in an empty text, delete it
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::keyDelete() - deleting" <<
"empty #text" << endl;
#endif
_nodeParent = _nodeNext.parentNode();
//If this empty text contains the cursor, change node to its parent.
if(_nodeNext == _node && _nodeParent.firstChild() == _nodeNext &&
_nodeNext.nextSibling().isNull())
{
_node = _nodeParent;
//d->m_cursorOffset = -2;
}
emit domNodeIsAboutToBeRemoved(_nodeNext, true, m_modifs);
_nodeParent.removeChild(_nodeNext);
singleNodeDeleted = true;
_nodeParent.applyChanges();
_nodeNext = _node;
}
}
//Else if the current Node is a BLOCK which can be entered/leaved e.g. H1
else if(attrs->chCurFoc() == kNodeAttrs::blockNode)
{
//First look if it is one of _node's parent
isParent = false;
temp = _node;
while(!temp.isNull())
{
if(_nodeNext == temp)
isParent = true;
temp = temp.parentNode();
}
//1 - Locate the toplevel blocks
temp = _nodeNext;
if(isParent)
{
toplevelBlock = temp;
while(temp.parentNode().lastChild() == temp && w->getAttrs(temp.parentNode()) &&
w->getAttrs(temp.parentNode())->chCurFoc() == kNodeAttrs::blockNode)
temp = temp.parentNode();
childOfCommonParent = temp;
temp = temp.nextSibling();
}
if(temp.isNull())
break;
childOfCommonParent2 = temp;
commonParent = temp.parentNode();
attrsTmp = w->getAttrs(temp);
nextIsBlock = (attrsTmp && attrsTmp->chCurFoc() == kNodeAttrs::blockNode);
while(!temp.isNull() && temp.hasChildNodes() && w->getAttrs(temp.firstChild()) &&
w->getAttrs(temp.firstChild())->chCurFoc() == kNodeAttrs::blockNode)
temp = temp.firstChild();
toplevelBlock2 = temp;
//2 - Determine the Nodes which could be moved
if(!toplevelBlock.isNull() && toplevelBlock.hasChildNodes())
endNode = toplevelBlock.lastChild();
else if(!childOfCommonParent2.isNull() && !childOfCommonParent2.previousSibling().isNull())
endNode = childOfCommonParent2.previousSibling();
temp = endNode;
while(!temp.isNull() && !temp.previousSibling().isNull() &&
((kafkaCommon::isInline(temp) && (temp.previousSibling().isNull() ||
kafkaCommon::isInline(temp.previousSibling()))) /**||
(!isInline(temp) && temp.previousSibling().isNull())*/))
temp = temp.previousSibling();
startNode = temp;
if(!toplevelBlock2.isNull() && toplevelBlock2.hasChildNodes())
startNode2 = toplevelBlock2.firstChild();
else if(!childOfCommonParent.isNull() && !childOfCommonParent.nextSibling().isNull())
startNode2 = childOfCommonParent.nextSibling();
startNode2IsNotInline = false;
temp = startNode2;
attrsTmp = w->getAttrs(temp);
if(attrsTmp && (attrsTmp->chCurFoc() == kNodeAttrs::singleNodeAndItself ||
attrsTmp->chCurFoc() == kNodeAttrs::no))
startNode2IsNotInline = true;
while(!temp.isNull() && !temp.nextSibling().isNull() &&
((kafkaCommon::isInline(temp) && (temp.nextSibling().isNull() ||
kafkaCommon::isInline(temp.nextSibling())))/** ||
(!isInline(temp) && temp.nextSibling().isNull())*/))
temp = temp.nextSibling();
endNode2 = temp;
//3 - Move Nodes.
if(!startNode2.isNull() && startNode2IsNotInline)
{
emit domNodeIsAboutToBeRemoved(startNode2, true, m_modifs);
startNode2.parentNode().removeChild(startNode2);
}
else if(isParent && !nextIsBlock)
{
if(kafkaCommon::parentSupports(toplevelBlock, startNode2, endNode2,
w->getCurrentDoc()->defaultDTD()))
moveDomNodes(toplevelBlock, startNode2, endNode2, DOM::Node(), false);
else
{
if(kafkaCommon::parentSupports(commonParent, startNode, endNode,
w->getCurrentDoc()->defaultDTD()))
moveDomNodes(commonParent, startNode, endNode, childOfCommonParent2,
true);
else
{
//Damn it! What to do??
}
}
}
else if(isParent && nextIsBlock)
{
if(kafkaCommon::parentSupports(toplevelBlock, startNode2, endNode2,
w->getCurrentDoc()->defaultDTD()))
moveDomNodes(toplevelBlock, startNode2, endNode2, DOM::Node(), false);
else
{
if(kafkaCommon::parentSupports(commonParent, startNode, endNode,
w->getCurrentDoc()->defaultDTD()) && kafkaCommon::parentSupports(
commonParent, startNode2, endNode2, w->getCurrentDoc()->defaultDTD()))
{
moveDomNodes(commonParent, startNode, endNode, childOfCommonParent,
false);
moveDomNodes(commonParent, startNode2, endNode2, childOfCommonParent2,
true);
}
else
{
//Damn it! What to do??
}
}
}
else if(!isParent && nextIsBlock)
{
if(kafkaCommon::parentSupports(commonParent, startNode2, endNode2,
w->getCurrentDoc()->defaultDTD()))
moveDomNodes(commonParent, startNode2, endNode2, childOfCommonParent2, true);
else
{
//Damn it! What to do??
}
}
if(!endNode.isNull())
normalize(endNode.parentNode());
//4 - Delete empty Block Nodes.
if(!toplevelBlock.isNull())
{
temp = toplevelBlock;
attrsTmp = w->getAttrs(temp);
while(attrsTmp && attrsTmp->chCurFoc() == kNodeAttrs::blockNode &&
!temp.hasChildNodes())
{
tempParent = temp.parentNode();
emit domNodeIsAboutToBeRemoved(temp, true, m_modifs);
tempParent.removeChild(temp);
temp = tempParent;
attrsTmp = w->getAttrs(temp);
}
}
if(!toplevelBlock2.isNull())
{
temp = toplevelBlock2;
attrsTmp = w->getAttrs(temp);
while(attrsTmp && attrsTmp->chCurFoc() == kNodeAttrs::blockNode &&
!temp.hasChildNodes())
{
tempParent = temp.parentNode();
emit domNodeIsAboutToBeRemoved(temp, true, m_modifs);
tempParent.removeChild(temp);
temp = tempParent;
attrsTmp = w->getAttrs(temp);
}
}
break;
}
//Else if the nextNode is a BLOCK, or an invisible Node, Inline Node
//which can be deleted, delete it!
else if(attrs->chCurFoc() == kNodeAttrs::singleNodeAndItself || ((attrs->chCurFoc() ==
kNodeAttrs::no || attrs->chCurFoc() == kNodeAttrs::inlineNode) &&
!_nodeNext.hasChildNodes()))
{
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::keyDelete() - deleting" <<
" a Node" << endl;
#endif
_nodeParent = _nodeNext.parentNode();
//If this block is used to define the cursor pos, change node to its parent.
if(_nodeNext == _node && _nodeParent.firstChild() == _nodeNext &&
_nodeNext.nextSibling().isNull())
{
_node = _nodeParent;
//d->m_cursorOffset = -2;
}
focus = w->getAttrs(_nodeNext)->chCurFoc();
emit domNodeIsAboutToBeRemoved(_nodeNext, true, m_modifs);
_nodeParent.removeChild(_nodeNext);
singleNodeDeleted = true;
_nodeNext = _node;
if(focus == kNodeAttrs::singleNodeAndItself)
{
normalize(_nodeParent);
break;
}
}
_nodeNext = getNextNode(_nodeNext, _goingTowardsRootNode);
}
//If the node which is defining the cursor position has been deleted (thus changed)
if(false && singleNodeDeleted)
{
//Now that we have deleted something, the cursor may end up in something weird, e.g.
//in an empty text or empty Inline. So delete them.
_nodeNext = _nodeParent;//<== !!!!
_nodeParent = _node.parentNode();
childPosition = -1;
while(!_nodeNext.isNull())
{
attrs = w->getAttrs(_nodeNext);
//If this Node can't be deleted, we stop here.
if(!attrs || !attrs->cbDel())
break;
//Let's delete useless Nodes
if((_nodeNext.nodeType() == DOM::Node::TEXT_NODE &&
(static_cast<DOM::CharacterData>(_nodeNext)).length() == 0) ||
(attrs->chCurFoc() == kNodeAttrs::inlineNode && _nodeNext.hasChildNodes())
)
{
childPosition = kafkaCommon::childPosition(_node);
_node = _nodeParent;
emit domNodeIsAboutToBeRemoved(_nodeNext, true, m_modifs);
_nodeParent.removeChild(_nodeNext);
normalize(_nodeParent);
}
else
break;
_nodeNext = _nodeParent;
}
//And finally, if the cursor is at a bad place (e.g. inside a Inline with childs), move it
attrs = w->getAttrs(_node);
while(attrs && attrs->chCurFoc() == kNodeAttrs::inlineNode && _node.hasChildNodes())
{
_node = kafkaCommon::getChildNode(_node, childPosition, true);
childPosition = 1;
}
}
/**m_currentNode = _node;
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset, m_modifs);*/
}
void KafkaWidget::keyBackspace()
{
kNodeAttrs *attrs, *attrsTmp;
int focus, m_currentNodeType;
DOM::Node _nodeParent, _node, _nodePrev, oldCurrentNode, temp, tempParent, prevSibling, nodePrevPrev;
DOM::Node toplevelBlock, toplevelBlock2, startNode, endNode, startNode2, endNode2;
DOM::Node childOfCommonParent, childOfCommonParent2, commonParent;
bool _goingTowardsRootNode, singleNodeDeleted, isParent, prevIsBlock, endNodeIsNotInline, boolTmp;
TQString text;
if(hasSelection())
{
removeSelection();
return;
}
if(m_currentNode.isNull())
return;
attrs = w->getAttrs(m_currentNode);
if(!attrs)
return;
m_currentNodeType = m_currentNode.nodeType();
#ifdef HEAVY_DEBUG
kdDebug(25001)<< "m_currentNode(" << m_currentNode.handle() << ") : " << m_currentNode.nodeName() <<
endl;
#endif
//OLD PART, to be removed or #ifdef'ed
if(attrs->chCurFoc() == kNodeAttrs::textNode && d->m_cursorOffset != 0)
{//if we are in the middle of some text, we remove one letter
if(!attrs->cbMod())
return;
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::keyBackspace() - one letter removed - 1" << endl;
#endif
DOM::DOMString nodeText = m_currentNode.nodeValue();
DOM::DOMString textSplitted = nodeText.split(d->m_cursorOffset);
nodeText.split(d->m_cursorOffset - 1);
#ifdef LIGHT_DEBUG
kdDebug(25001) << nodeText.string() << textSplitted.string() << endl;
#endif
m_currentNode.setNodeValue(nodeText + textSplitted);
m_currentNode.parentNode().applyChanges();
--(d->m_cursorOffset);
emit domNodeModified(m_currentNode, m_modifs);
postprocessCursorPosition();
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
return;
}
if(attrs->chCurFoc() == kNodeAttrs::singleNodeAndItself &&
d->m_cursorOffset != 0)
{//if we delete ourselves, which node will be m_currentNode??
if(!attrs->cbDel())
return;
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::keyBackspace() - deleting a TagDeletable - 2" << endl;
#endif
DOM::Node _node = m_currentNode;
bool b = false;
while(1)
{//try to find a previous node from which we can delete the node
_node = getPrevNode(_node, b);
if(_node == 0)
break;
attrs = w->getAttrs(_node);
if(attrs && attrs->chCurFoc() == kNodeAttrs::textNode)
{
m_currentNode = _node;
d->m_cursorOffset = (static_cast<DOM::CharacterData>(_node)).length();
keyDelete();
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
return;
}
if(attrs && attrs->chCurFoc() != kNodeAttrs::no && attrs->chCurFoc() !=
kNodeAttrs::textNode)
{
m_currentNode = _node;
d->m_cursorOffset = 1;
keyDelete();
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
return;
}
}
_node = m_currentNode;
b = false;
while(1)
{//try to find a next node from which we can delete the node
_node = getNextNode(_node, b);
if(_node == 0)
break;
attrs = w->getAttrs(_node);
if(attrs && attrs->chCurFoc() != kNodeAttrs::no)
{
m_currentNode = _node;
d->m_cursorOffset = 0;
keyBackspace();
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
return;
}
}
//here, there is no node right and left that can have the cursor focus
_node = m_currentNode.parentNode();
emit domNodeIsAboutToBeRemoved(m_currentNode, true, m_modifs);
_node.removeChild(m_currentNode);
m_currentNode = document().createTextNode("");
_node.appendChild(m_currentNode);
emit domNodeInserted(m_currentNode, false, m_modifs);
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
}
//Beginning of the actual keyBackspace
_node = m_currentNode;
_goingTowardsRootNode = false;
singleNodeDeleted = false;
_nodePrev = getPrevNode(_node, _goingTowardsRootNode);
oldCurrentNode = m_currentNode;
while(!_nodePrev.isNull())
{
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::keyBackspace() - currentNode: " <<
_nodePrev.nodeName().string() << endl;
#endif
attrs = w->getAttrs(_nodePrev);
if(!attrs)
{
kdError(25001) << "NULL kNodeAttrs instance: attrs = w->getAttrs(_nodePrev);" << endl;
kafkaCommon::coutDomTree(_nodePrev, 3);
return;
// FIXME Understand why this happen.
// Test case:
// 1. Write two words in a new VPL document and make the first one a link;
// 2. Put the cursor at most right and then press backspace until it crashes
// When you get to the link the cursor stays in the same plave and you have press it several times until it crashes.
}
//If this Node can't be deleted, we stop here.
if(!attrs->cbDel())
return;
//If we are in a TEXT node, we remove a letter
if(attrs->chCurFoc() == kNodeAttrs::textNode)
{
if((static_cast<DOM::CharacterData>(_nodePrev)).length() != 0)
{//if we are in text, remove a letter
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::keyBackspace() - one" <<
" letter removed - 2" << endl;
#endif
DOM::DOMString nodeText = _nodePrev.nodeValue();
nodeText.split((static_cast<DOM::CharacterData>(_nodePrev)).length() - 1);
_nodePrev.setNodeValue(nodeText);
_nodePrev.parentNode().applyChanges();
m_currentNode = _nodePrev;
d->m_cursorOffset = (static_cast<DOM::CharacterData>(_nodePrev)).length();
postprocessCursorPosition();
emit domNodeModified(_nodePrev, m_modifs);
return;
}
else
{//if we are in an empty text
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::keyBackspace() - deleting" <<
" empty #text" << endl;
#endif
_nodeParent = _nodePrev.parentNode();
emit domNodeIsAboutToBeRemoved(_nodePrev, true, m_modifs);
_nodeParent.removeChild(_nodePrev);
_nodeParent.applyChanges();
_nodePrev = _node;
continue;
}
}
//Else if the current Node if a BLOCK which can be entered/leaved e.g. H1, P
else if(attrs->chCurFoc() == kNodeAttrs::blockNode)
{
//First look if it is one of _node's parent
isParent = false;
temp = _node;
while(!temp.isNull())
{
if(_nodePrev == temp)
isParent = true;
temp = temp.parentNode();
}
//1 - Locate the toplevel blocks
temp = _nodePrev;
if(isParent)
{
toplevelBlock2 = temp;
while(temp.parentNode().firstChild() == temp && w->getAttrs(temp.parentNode()) &&
w->getAttrs(temp.parentNode())->chCurFoc() == kNodeAttrs::blockNode)
temp = temp.parentNode();
childOfCommonParent2 = temp;
temp = temp.previousSibling();
}
if(temp.isNull())
break;
childOfCommonParent = temp;
commonParent = temp.parentNode();
attrsTmp = w->getAttrs(temp);
prevIsBlock = (attrsTmp && attrsTmp->chCurFoc() == kNodeAttrs::blockNode);
while(!temp.isNull() && temp.hasChildNodes() && w->getAttrs(temp.lastChild()) &&
w->getAttrs(temp.lastChild())->chCurFoc() == kNodeAttrs::blockNode)
temp = temp.lastChild();
toplevelBlock = temp;
//2 - Determine the Nodes which could be moved
if(!toplevelBlock.isNull() && toplevelBlock.hasChildNodes())
endNode = toplevelBlock.lastChild();
else if(!childOfCommonParent2.isNull() && !childOfCommonParent2.previousSibling().isNull())
endNode = childOfCommonParent2.previousSibling();
endNodeIsNotInline = false;
temp = endNode;
attrsTmp = w->getAttrs(temp);
if(attrsTmp && (attrsTmp->chCurFoc() == kNodeAttrs::singleNodeAndItself ||
attrs->chCurFoc() == kNodeAttrs::no))
endNodeIsNotInline = true;
while(!temp.isNull() && !temp.previousSibling().isNull() &&
((kafkaCommon::isInline(temp) && (temp.previousSibling().isNull() ||
kafkaCommon::isInline(temp.previousSibling())))))
temp = temp.previousSibling();
startNode = temp;
if(!toplevelBlock2.isNull() && toplevelBlock2.hasChildNodes())
startNode2 = toplevelBlock2.firstChild();
else if(!childOfCommonParent.isNull() && !childOfCommonParent.nextSibling().isNull())
startNode2 = childOfCommonParent.nextSibling();
temp = startNode2;
while(!temp.isNull() && !temp.nextSibling().isNull() &&
((kafkaCommon::isInline(temp) && (temp.nextSibling().isNull() ||
kafkaCommon::isInline(temp.nextSibling())))))
temp = temp.nextSibling();
endNode2 = temp;
//3 - Move Nodes.
if(!endNode.isNull() && endNodeIsNotInline)
{
emit domNodeIsAboutToBeRemoved(endNode, true, m_modifs);
endNode.parentNode().removeChild(endNode);
}
else if(isParent && !prevIsBlock)
{
if(kafkaCommon::parentSupports(toplevelBlock2, startNode, endNode,
w->getCurrentDoc()->defaultDTD()))
moveDomNodes(toplevelBlock2, startNode, endNode, toplevelBlock2.firstChild(),
true);
else
{
if(kafkaCommon::parentSupports(commonParent, startNode2, endNode2,
w->getCurrentDoc()->defaultDTD()))
moveDomNodes(commonParent, startNode2, endNode2,
childOfCommonParent2, true);
else
{
//Damn it! What to do??
}
}
}
else if(isParent && prevIsBlock)
{
if(kafkaCommon::parentSupports(toplevelBlock2, startNode, endNode,
w->getCurrentDoc()->defaultDTD()))
moveDomNodes(toplevelBlock2, startNode, endNode, toplevelBlock2.firstChild(),
true);
else
{
if(kafkaCommon::parentSupports(commonParent, startNode, endNode,
w->getCurrentDoc()->defaultDTD()) && kafkaCommon::parentSupports(
commonParent, startNode2, endNode2, w->getCurrentDoc()->defaultDTD()))
{
moveDomNodes(commonParent, startNode, endNode, childOfCommonParent,
false);
moveDomNodes(commonParent, startNode2, endNode2, childOfCommonParent2,
true);
}
else
{
//Damn it! What to do??
}
}
}
else if(!isParent && prevIsBlock)
{
if(kafkaCommon::parentSupports(commonParent, startNode, endNode,
w->getCurrentDoc()->defaultDTD()))
moveDomNodes(commonParent, startNode, endNode, childOfCommonParent, false);
else
{
//Damn it! What to do??
}
}
if(!startNode2.isNull() && startNode2.nodeType() == DOM::Node::TEXT_NODE)
{
//normalize(startNode2.parentNode());
temp = startNode2.previousSibling();
if(!temp.isNull() && temp.nodeType() == DOM::Node::TEXT_NODE)
{
boolTmp = false;
if(m_currentNode == startNode2)
{
m_currentNode = temp;
d->m_cursorOffset += temp.nodeValue().length();
boolTmp = true;
}
text = temp.nodeValue().string() + startNode2.nodeValue().string();
tempParent = temp.parentNode();
emit domNodeIsAboutToBeRemoved(startNode2, true, m_modifs);
tempParent.removeChild(startNode2);
temp.setNodeValue(text);
emit domNodeModified(temp, m_modifs);
if(boolTmp)
TQTimer::singleShot(0, this, TQT_SLOT(slotDelayedSetCaretPosition()));
}
}
//4 - Delete empty Block Nodes.
if(!toplevelBlock.isNull())
{
temp = toplevelBlock;
attrsTmp = w->getAttrs(temp);
while(attrsTmp && attrsTmp->chCurFoc() == kNodeAttrs::blockNode &&
!temp.hasChildNodes())
{
tempParent = temp.parentNode();
emit domNodeIsAboutToBeRemoved(temp, true, m_modifs);
tempParent.removeChild(temp);
temp = tempParent;
attrsTmp = w->getAttrs(temp);
}
}
if(!toplevelBlock2.isNull())
{
temp = toplevelBlock2;
attrsTmp = w->getAttrs(temp);
while(attrsTmp && attrsTmp->chCurFoc() == kNodeAttrs::blockNode &&
!temp.hasChildNodes())
{
tempParent = temp.parentNode();
emit domNodeIsAboutToBeRemoved(temp, true, m_modifs);
tempParent.removeChild(temp);
temp = tempParent;
attrsTmp = w->getAttrs(temp);
}
}
break;
}
//Else if the prevNode is a BLOCK or an invisible Node, Inline Node
//which can be deleted, delete it!
else if(attrs->chCurFoc() == kNodeAttrs::singleNodeAndItself || ((attrs->chCurFoc() ==
kNodeAttrs::no || attrs->chCurFoc() == kNodeAttrs::inlineNode) &&
!_nodePrev.hasChildNodes()))
{
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::keyBackspace() - deleting" <<
" a Node" << endl;
#endif
_nodeParent = _nodePrev.parentNode();
focus = w->getAttrs(_nodePrev)->chCurFoc();
emit domNodeIsAboutToBeRemoved(_nodePrev, true, m_modifs);
_nodeParent.removeChild(_nodePrev);
//normalize(_nodeParent);
if(focus == kNodeAttrs::singleNodeAndItself)
{
postprocessCursorPosition();
//merge the previous DOM::Node if it is a text.
//domNodeIsAboutToBeRemoved() already do it in the Node tree.
//=> It seems it was removed from it.
_nodePrev = _node.previousSibling();
if(!_nodePrev.isNull() && _nodePrev.nodeType() == DOM::Node::TEXT_NODE &&
m_currentNodeType == DOM::Node::TEXT_NODE)
{
if(_node == m_currentNode)
{
m_currentNode = _nodePrev;
d->m_cursorOffset += (static_cast<DOM::CharacterData>(_nodePrev)).length();
TQTimer::singleShot(0, this, TQT_SLOT(slotDelayedSetCaretPosition()));
}
_nodePrev.setNodeValue(_nodePrev.nodeValue() + _node.nodeValue());
emit domNodeModified(_nodePrev, m_modifs);
//_nodeParent = _nodePrev.parentNode();
emit domNodeIsAboutToBeRemoved(_node, true, m_modifs);
_nodeParent.removeChild(_node);
}
//dirty workaround when after having deleted a br, there is only one br left
//Anyway webcore will override this
if(m_currentNode.nodeName().string().lower() == "br" &&
(m_currentNode.previousSibling().isNull() || (m_currentNode.previousSibling().nodeType() ==
DOM::Node::TEXT_NODE && m_currentNode.previousSibling().previousSibling().isNull())) &&
(m_currentNode.nextSibling().isNull() || (m_currentNode.nextSibling().nodeType() ==
DOM::Node::TEXT_NODE && m_currentNode.nextSibling().nextSibling().isNull())))
{
if(!m_currentNode.previousSibling().isNull())
{
m_currentNode = m_currentNode.previousSibling();
d->m_cursorOffset = 0;
TQTimer::singleShot(0, this, TQT_SLOT(slotDelayedSetCaretPosition()));
}
else if(!m_currentNode.nextSibling().isNull())
{
m_currentNode = m_currentNode.nextSibling();
d->m_cursorOffset = 0;
}
}
break;
}
_nodePrev = _node;
}
_nodePrev = getPrevNode(_nodePrev, _goingTowardsRootNode);
}
}
DOM::Node KafkaWidget::getNextNode(DOM::Node _node, bool &goingTowardsRootNode, bool skipParentNodes, bool dontBlock, DOM::Node _endNode)
{
kNodeAttrs *attrs = 0L;
if(_node == 0)
return 0;
attrs = w->getAttrs(_node);
if(!attrs)
{
kdDebug(25001)<< "KafkaWidget::getNextNode() Attrs not found!"<< endl;
return 0;
}
if(_node.hasChildNodes() && goingTowardsRootNode == false &&
(attrs->ccanEnter() || dontBlock))
{//if we can descend to a child node, we do it
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::getNextNode() - descending from node : " <<
_node.nodeName().string() << " to " <<
_node.firstChild().nodeName().string() << endl;
#endif
if(_endNode == _node.firstChild())
return 0;
return _node.firstChild();
}
if(_node.nextSibling() != 0)
{//else if there is a sibling, we move to it
goingTowardsRootNode = false;
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::getNextNode() - going from node : " <<
_node.nodeName().string() <<
" to " << _node.nextSibling().nodeName().string() << endl;
#endif
if(_endNode == _node.nextSibling())
return 0;
return _node.nextSibling();
}
if(_node.nextSibling() == 0)
{//else if there is no sibling, we go up if we can
goingTowardsRootNode = true;
if(_node.parentNode().isNull())
return 0;
if(w->getAttrs(_node.parentNode()) &&
w->getAttrs(_node.parentNode())->ccanEnter() || dontBlock)
{
if(!_node.parentNode().isNull())
{
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::getNextNode() - going" <<
" up from node : " << _node.nodeName().string() <<
" to " << _node.parentNode().nodeName().string() << endl;
#endif
}
else
{
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::getNextNode() - going" <<
" up from node : " << _node.nodeName().string() <<
" to an empty Node" << endl;
#endif
}
if(skipParentNodes)
{
if(_endNode == _node.parentNode())
return 0;
return getNextNode(_node.parentNode(), goingTowardsRootNode,
skipParentNodes, dontBlock);
}
else
{
if(_endNode == _node.parentNode())
return 0;
return _node.parentNode();
}
}
else
return 0;
}
kdError()<< "KafkaWidget::getNextNode() ERROR" << endl;
return 0;
}
DOM::Node KafkaWidget::getPrevNode(DOM::Node _node, bool &goingTowardsRootNode, bool skipParentNodes, bool dontBlock, DOM::Node _endNode)
{
kNodeAttrs *attrs = 0L;
if(_node == 0)
return 0;
attrs = w->getAttrs(_node);
if(!attrs)
{
kdDebug(25001)<< "KafkaWidget::getPrevNode() Attrs not found!"<< endl;
return 0;
}
if(_node.hasChildNodes() && goingTowardsRootNode == false &&
(attrs->ccanEnter() || dontBlock))
{//if we can descend to a child node, we do it
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::getPrevNode() - descending from node : " <<
_node.nodeName().string() << " to " <<
_node.lastChild().nodeName().string() << endl;
#endif
if(_endNode == _node.lastChild())
return DOM::Node();
return _node.lastChild();
}
if(_node.previousSibling() != 0)
{//else if there is a sibling, we move to it
goingTowardsRootNode = false;
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::getPrevNode() - going from node : " <<
_node.nodeName().string() <<
" to " << _node.previousSibling().nodeName().string() << endl;
#endif
if(_endNode == _node.previousSibling())
return DOM::Node();
return _node.previousSibling();
}
if(_node.previousSibling() == 0)
{//else if there is no sibling, we go up if we can
goingTowardsRootNode = true;
if(_node.parentNode().isNull())
return DOM::Node();
if(w->getAttrs(_node.parentNode()) &&
w->getAttrs(_node.parentNode())->ccanEnter() || dontBlock)
{
if(!_node.parentNode().isNull())
{
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::getPrevNode() - going up from" <<
" node : " << _node.nodeName().string() << " to " <<
_node.parentNode().nodeName().string() << endl;
#endif
}
else
{
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::getPrevNode() - going up from" <<
" node : " << _node.nodeName().string() << " to an " <<
"empty Node" << endl;
#endif
}
if (skipParentNodes)
{
if(_endNode == _node.parentNode())
return DOM::Node();
return getPrevNode(_node.parentNode(), goingTowardsRootNode,
skipParentNodes, dontBlock);
}
else
{
if(_endNode == _node.parentNode())
return DOM::Node();
return _node.parentNode();
}
}
else
return 0;
}
kdError()<< "KafkaWidget::getPrevNode() ERROR" << endl;
return 0;
}
void KafkaWidget::updateToggableTagActions(/*const DOM::Node &domNode, long offset*/) const
{
//Andras: Disable toggle behavior. It is just too broken.
return;
quantaApp->removeAllTagActionPoolItems();
NodeSelectionInd selection;
selection.fillWithVPLCursorSelection();
Node* start_node = 0, *end_node = 0;
// int start_offset = 0, end_offset = 0;
start_node = kafkaCommon::getNodeFromLocation(selection.cursorNode());
// start_offset = selection.cursorOffset();
if(!start_node)
return;
if(selection.hasSelection())
{
end_node = kafkaCommon::getNodeFromLocation(selection.cursorNodeEndSel());
// end_offset = selection.cursorOffsetEndSel();
}
else
{
end_node = start_node;
// end_offset = start_offset;
}
// Iterate all toggable toolbar actions and toggle them on or off
// Look if there is a selection
TagAction* tag_action = 0;
TQPtrList<TagAction> tag_actions = quantaApp->tagActions();
for (tag_action = tag_actions.first(); tag_action; tag_action = tag_actions.next())
{
if(tag_action->toggable())
{
TQString tag_name = tag_action->XMLTagName();
if(tag_name.isEmpty())
break;
TQDomElement data(tag_action->data());
TQString attribute_name(data.attribute("attribute_name", TQString()));
TQString attribute_value(data.attribute("attribute_value", TQString()));
int inside_tag;
if(!attribute_name.isEmpty() && !attribute_value.isEmpty())
inside_tag = kafkaCommon::isInsideTag(start_node, end_node, tag_name, attribute_name, attribute_value);
else
inside_tag = kafkaCommon::isInsideTag(start_node, end_node, tag_name);
tag_action->setChecked(inside_tag == 1);
}
}
}
void KafkaWidget::makeCursorVisible(int , int )
{
/**DOM::Range range;
if(m_currentNode == 0)
return;
kdDebug(25001)<< "KafkaWidget::makeCursorVisible()" << endl;
int X, Y, dummy;
getCursor(m_currentNode, d->m_cursorOffset, X, Y, dummy);
view()->ensureVisible (X, Y, xMargin, yMargin);*/
//does not work... ???
/**range = selection();
//try{
range.setStart(m_currentNode, d->m_cursorOffset);
}
catch(DOM::RangeException e)
{
//ignore
kdDebug(25001)<< "KafkaWidget::makeCursorVisible() - ERROR " << e.code << endl;
return;
}
catch(DOM::DOMException e)
{
kdDebug(25001)<< "KafkaWidget::makeCursorVisible() - ERROR " << e.code << endl;
}*/
//range.setEnd(m_currentNode, d->m_cursorOffset);
}
void KafkaWidget::postprocessCursorPosition()
{
kNodeAttrs *attrs, *attrs2;
if(m_currentNode == 0)
return;
attrs = w->getAttrs(m_currentNode);
DOM::Node _prevNextNode;
DOM::Node _nextNode = m_currentNode;
bool b = false;
if(!attrs)
{
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::postprocessCursorPosition() - WARNING no Attrs!! " << endl;
#endif
return;
}
if(attrs->chCurFoc() == kNodeAttrs::textNode &&
d->m_cursorOffset == 0)
{
/** while(1)
{
_prevNextNode = _nextNode;
_nextNode = kafkaCommon::getPrevDomNode(_nextNode);
if(_nextNode.isNull())
break;
attrs2 = w->getAttrs(_nextNode);
if(attrs2 && attrs2->chCurFoc() == kNodeAttrs::textNode &&
(static_cast<DOM::CharacterData>(_nextNode)).length() != 0)
{
m_currentNode = _nextNode;
d->m_cursorOffset = (static_cast<DOM::CharacterData>(_nextNode)).length();
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::postprocessCursorPosition()" <<
" - new currentNode :" <<
m_currentNode.nodeName().string() << endl;
#endif
break;
}
else if(attrs2->chCurFoc() == kNodeAttrs::singleNodeAndItself ||
attrs2->chCurFoc() == kNodeAttrs::inlineNode ||
attrs2->chCurFoc() == kNodeAttrs::blockNode)
break;
else
continue;
}*/
}
else if(attrs->chCurFoc() == kNodeAttrs::singleNodeAndItself)
{
if(d->m_cursorOffset == 0 && !m_currentNode.isNull() &&
(m_currentNode.nodeName().string().lower() != "br" ||
(m_currentNode.nodeName().string().lower() == "br" && /**!m_currentNode.nextSibling().isNull() &&
m_currentNode.nextSibling().nodeType() == DOM::Node::TEXT_NODE &&
m_currentNode.nextSibling().nodeValue().string().isEmpty() &&
m_currentNode.nextSibling().nextSibling().isNull() &&*/
!m_currentNode.previousSibling().isNull() &&
m_currentNode.previousSibling().nodeType() == DOM::Node::TEXT_NODE &&
!m_currentNode.previousSibling().nodeValue().string().isEmpty())))
{
while(1)
{
_prevNextNode = _nextNode;
_nextNode = getPrevNode(_nextNode, b);
if(_nextNode == 0)
break;
attrs2 = w->getAttrs(_nextNode);
if(attrs2 && attrs2->chCurFoc() == kNodeAttrs::textNode &&
(static_cast<DOM::CharacterData>(_nextNode)).length()
!= 0)
{
m_currentNode = _nextNode;
d->m_cursorOffset = (static_cast<DOM::CharacterData>(_nextNode)).length();
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::postprocessCursorPosition()" <<
" - new currentNode :" << m_currentNode.nodeName().string() << endl;
#endif
break;
}
else if(attrs2 && attrs2->chCurFoc() == kNodeAttrs::singleNodeAndItself)
{
m_currentNode = _nextNode;
d->m_cursorOffset = 1;
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::postprocessCursorPosition()" <<
" - new currentNode :" << m_currentNode.nodeName().string() << endl;
#endif
break;
}
else
continue;
}
}
else if(d->m_cursorOffset == 1)
{
while(1)
{
_prevNextNode = _nextNode;
_nextNode = getNextNode(_nextNode, b);
if(_nextNode == 0)
break;
attrs2 = w->getAttrs(_nextNode);
if(attrs2 && attrs2->chCurFoc() == kNodeAttrs::singleNodeAndItself)
break;
else if(attrs2 && attrs2->chCurFoc() == kNodeAttrs::textNode &&
(static_cast<DOM::CharacterData>(_nextNode)).length() != 0)
{
m_currentNode = _nextNode;
d->m_cursorOffset = 0;
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
emit domNodeNewCursorPos(m_currentNode, d->m_cursorOffset);
#ifdef LIGHT_DEBUG
kdDebug(25001)<< "KafkaWidget::postprocessCursorPosition() " <<
"- new currentNode :" << m_currentNode.nodeName().string() << endl;
#endif
break;
}
else
continue;
}
}
}
makeCursorVisible();
}
void KafkaWidget::tdehtmlMouseMoveEvent(tdehtml::MouseMoveEvent *event)
{
DOM::Node mouseNode = event->innerNode();
if(mouseNode == 0)
{
return;
}
if(mouseNode.nodeType() == DOM::Node::TEXT_NODE)
view()->setCursor(TQt::ibeamCursor);
else
view()->setCursor(TQt::arrowCursor);
TDEHTMLPart::tdehtmlMouseMoveEvent(event);
}
void KafkaWidget::tdehtmlMouseReleaseEvent(tdehtml::MouseReleaseEvent *event)
{
TDEHTMLPart::tdehtmlMouseReleaseEvent(event);
if(m_currentNode.isNull() || m_currentNode.nodeName().string().lower() == "#document")
{
m_currentNode = w->body;
d->m_cursorOffset = 0;
setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
}
if(quantaApp->aTab)
quantaApp->aTab->setCurrentNode(w->getNode(event->innerNode()));
}
void KafkaWidget::tdehtmlMousePressEvent(tdehtml::MousePressEvent *event)
{
TDEHTMLPart::tdehtmlMousePressEvent(event);
if(d->m_cursorOffset == 0 && !m_currentNode.isNull() &&
m_currentNode.nodeName().string().lower() == "body")
putCursorAtFirstAvailableLocation();
#ifdef HEAVY_DEBUG
//d->domdialog->domview->showTree(document());
#endif
}
void KafkaWidget::tdehtmlDrawContentsEvent(tdehtml::DrawContentsEvent *event)
{
TDEHTMLPart::tdehtmlDrawContentsEvent(event);
}
void KafkaWidget::getCurrentNode(DOM::Node &_currentNode, long &offset)
{
_currentNode = m_currentNode;
offset = d->m_cursorOffset;
}
void KafkaWidget::setCurrentNode(DOM::Node node, int offset)
{
m_currentNode = node;
d->m_cursorOffset = offset;
makeCursorVisible();
if(!m_currentNode.isNull() && m_currentNode.nodeName().string() != "#document")
TQTimer::singleShot(0, this, TQT_SLOT(slotDelayedSetCaretPosition()));
//setCaretPosition(m_currentNode, (long)d->m_cursorOffset);
}
void KafkaWidget::setCurrentNode(Node* cursorNode, int cursorOffset)
{
DOM::Node domNode;
long longDomNodeOffset;
KafkaDocument::ref()->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())
setCurrentNode(domNode, (int)longDomNodeOffset);
}
void KafkaWidget::putCursorAtFirstAvailableLocation()
{
kNodeAttrs *attrs = 0L;
DOM::Node node = w->body;
bool b = false;
#ifdef HEAVY_DEBUG
w->coutLinkTree(baseNode, 2);
kafkaCommon::coutTree(baseNode, 2);
kafkaCommon::coutDomTree(document(), 2);
#endif
while(!node.isNull())
{
node = kafkaCommon::getNextDomNode(node, b);
if(node.isNull())
{
if(!w->body.isNull())
node = w->body;
else
node = DOM::Node();
break;
}
attrs = w->getAttrs(node);
if(!attrs)
{
node = w->body;
break;
}
if(node.nodeType() == DOM::Node::TEXT_NODE)
break;
}
m_currentNode = node;
d->m_cursorOffset = 0;
TQTimer::singleShot(0, this, TQT_SLOT(slotDelayedSetCaretPosition()));
#ifdef LIGHT_DEBUG
if(!m_currentNode.isNull())
kdDebug(25001)<< "KafkaWidget::putCursorAtFirstAvailableLocation() - " <<
m_currentNode.nodeName().string() << endl;
#endif
}
void KafkaWidget::slotNewCursorPos(const DOM::Node &domNode, long offset)
{
if(!w->isLoaded())
return;
m_currentNode = domNode;
d->m_cursorOffset = (int)offset;
#ifdef LIGHT_DEBUG
kdDebug(25001)<<"KafkaWidget::slotNewCursorPos() offset : " << d->m_cursorOffset << endl;
#endif
if(quantaApp->aTab && ViewManager::ref()->activeView()->hadLastFocus() == QuantaView::VPLFocus)
quantaApp->aTab->setCurrentNode(w->getNode(domNode));
updateToggableTagActions(/*domNode, offset*/);
}
void KafkaWidget::moveDomNodes(DOM::Node newParent, DOM::Node startNode, DOM::Node endNode,
DOM::Node refNode, bool before)
{
DOM::Node domNode, domNodeNext;
if(newParent.isNull())
return;
if(before)
{
domNode = endNode;
while(!domNode.isNull())
{
domNodeNext = domNode.previousSibling();
emit domNodeIsAboutToBeMoved(domNode, newParent, refNode, m_modifs);
//emit domNodeIsAboutToBeRemoved(domNode, true);
domNode = domNode.parentNode().removeChild(domNode);
if(!refNode.isNull())
newParent.insertBefore(domNode, refNode);
else
newParent.insertBefore(domNode, DOM::Node());
//emit domNodeInserted(domNode, true);
if(domNode == startNode)
break;
domNode = domNodeNext;
}
}
else
{
domNode = startNode;
while(!domNode.isNull())
{
domNodeNext = domNode.nextSibling();
//emit domNodeIsAboutToBeRemoved(domNode, true);
if(!refNode.isNull())
emit domNodeIsAboutToBeMoved(domNode, newParent, refNode.nextSibling(), m_modifs);
else
emit domNodeIsAboutToBeMoved(domNode, newParent, DOM::Node(), m_modifs);
domNode = domNode.parentNode().removeChild(domNode);
if(!refNode.isNull())
newParent.insertBefore(domNode, refNode.nextSibling());
else
newParent.insertBefore(domNode, DOM::Node());
//emit domNodeInserted(domNode, true);
if(domNode == endNode)
break;
domNode = domNodeNext;
}
}
}
void KafkaWidget::removeSelection()
{
Q_ASSERT(hasSelection());
NodeSelectionInd selection;
selection.fillWithVPLCursorSelection();
Node* cursorNode = kafkaCommon::getNodeFromLocation(selection.cursorNode());
long cursorOffset = 0;
long domNodeCursorOffset = 0;
kafkaCommon::DTDRemoveSelection(selection, &cursorNode, cursorOffset, m_modifs);
KafkaDocument::ref()->translateNodeIntoKafkaCursorPosition(cursorNode, cursorOffset, m_currentNode, domNodeCursorOffset);
d->m_cursorOffset = domNodeCursorOffset;
setCurrentNode(m_currentNode, domNodeCursorOffset);
TQTimer::singleShot(0, this, TQT_SLOT(slotDelayedSetCaretPosition()));
NodeSelection* cursorPos = new NodeSelection();
cursorPos->setCursorNode(cursorNode);
cursorPos->setCursorOffset(cursorOffset);
ViewManager::ref()->activeDocument()->docUndoRedo->addNewModifsSet(m_modifs, undoRedo::NodeTreeModif, cursorPos);
m_modifs = 0;
delete cursorPos;
makeCursorVisible();
}
void KafkaWidget::applyQueuedToggableTagActions()
{
TQStringList queued_actions = quantaApp->tagActionPool();
TQPtrList<TagAction> action_list = quantaApp->tagActions();
for(TQStringList::Iterator it = queued_actions.begin(); it != queued_actions.end(); ++it)
{
TagAction* tag_action = 0;
for (tag_action = action_list.first(); tag_action; tag_action = action_list.next())
{
if(tag_action->name() == *it)
{
tag_action->slotActionActivated(TDEAction::EmulatedActivation, TQt::NoButton);
break;
}
}
}
quantaApp->removeAllTagActionPoolItems();
}
#include "kafkahtmlpart.moc"