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.
1173 lines
34 KiB
1173 lines
34 KiB
/***************************************************************************
|
|
tagactionset.cpp
|
|
-------------------
|
|
|
|
copyright : (C) 2004 - Paulo Moura Guedes
|
|
email : moura@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 <tdeapplication.h>
|
|
#include <tdeconfig.h>
|
|
#include <tdeactioncollection.h>
|
|
#include <tdeactionclasses.h>
|
|
#include <dom/dom_node.h>
|
|
#include <dom/dom_string.h>
|
|
#include <tdelocale.h>
|
|
|
|
#include <tqwidget.h>
|
|
|
|
#include "tagactionset.h"
|
|
#include "tagactionmanager.h"
|
|
#include "kafkacommon.h"
|
|
#include "cursors.h"
|
|
#include "undoredo.h"
|
|
#include "wkafkapart.h"
|
|
#include "node.h"
|
|
#include "quantaview.h"
|
|
#include "viewmanager.h"
|
|
#include "tag.h"
|
|
#include "quantacommon.h"
|
|
#include "document.h"
|
|
#include "resource.h"
|
|
|
|
|
|
TagActionSetAbstract::TagActionSetAbstract(TQObject *parent, const char *name)
|
|
: TQObject(parent, name), m_currentNode(0)
|
|
{}
|
|
|
|
TagActionSetAbstract::~TagActionSetAbstract()
|
|
{}
|
|
|
|
Node* TagActionSetAbstract::parentTag(Node* node, TQString const& tagName)
|
|
{
|
|
Q_ASSERT(node);
|
|
|
|
Node* aux = node;
|
|
while(aux && aux->nodeName().lower() != tagName)
|
|
aux = aux->parent;
|
|
|
|
return aux;
|
|
}
|
|
|
|
Node* TagActionSetAbstract::firstChildTag(Node* startParentNode, TQString const& tagName)
|
|
{
|
|
Node* aux = startParentNode;
|
|
while(aux && aux->nodeName().lower() != tagName)
|
|
{
|
|
aux = aux->nextSibling();
|
|
if(!startParentNode->hasForChild(aux))
|
|
return 0;
|
|
}
|
|
|
|
return aux;
|
|
}
|
|
|
|
bool TagActionSetAbstract::fillWithTagActions(TQWidget* /*widget*/, DOM::Node const& node)
|
|
{
|
|
m_currentDomNode = node;
|
|
m_currentNode = KafkaDocument::ref()->getNode(m_currentDomNode);
|
|
|
|
return m_currentNode;
|
|
}
|
|
|
|
//_____________________________________________________________________________
|
|
|
|
TagActionSet::TagActionSet(TQObject *parent, const char *name)
|
|
: TagActionSetAbstract(parent, name), m_separator(0)
|
|
{
|
|
m_separator = new TDEActionSeparator();
|
|
}
|
|
|
|
bool TagActionSet::isInTagContext() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void TagActionSet::initActionMenus(TQWidget* /*widget*/)
|
|
{
|
|
}
|
|
|
|
void TagActionSet::initActions(TQWidget* /*parent*/)
|
|
{
|
|
TDEActionCollection* ac(TagActionManager::self()->actionCollection());
|
|
|
|
const char *actionName = "apply_source_indentation";
|
|
new TDEAction(i18n("Apply Source Indentation"), 0, this,
|
|
TQT_SLOT(slotApplySourceIndentation()),
|
|
ac, actionName);
|
|
|
|
actionName = "copy_div_element";
|
|
new TDEAction(i18n("Copy DIV Area"), 0, this,
|
|
TQT_SLOT(slotCopyDivElement()),
|
|
ac, actionName);
|
|
|
|
actionName = "cut_div_element";
|
|
new TDEAction(i18n("Cut DIV Area"), 0, this,
|
|
TQT_SLOT(slotCutDivElement()),
|
|
ac, actionName);
|
|
}
|
|
|
|
bool TagActionSet::fillWithTagActions(TQWidget* widget, DOM::Node const& node)
|
|
{
|
|
bool validNode = TagActionSetAbstract::fillWithTagActions(widget, node);
|
|
|
|
if(!validNode || !isInTagContext())
|
|
{
|
|
unplugAllActions(widget);
|
|
return false;
|
|
}
|
|
|
|
m_separator->unplugAll();
|
|
|
|
TDEActionCollection* ac(TagActionManager::self()->actionCollection());
|
|
|
|
TDEAction* copyDivAction = ac->action("copy_div_element");
|
|
Q_ASSERT(copyDivAction);
|
|
TDEAction* cutDivAction = ac->action("cut_div_element");
|
|
Q_ASSERT(cutDivAction);
|
|
|
|
if(/*!KafkaDocument::ref()->getKafkaWidget()->hasSelection() && */isInDivArea())
|
|
{
|
|
if(!copyDivAction->isPlugged(widget))
|
|
copyDivAction->plug(widget);
|
|
|
|
if(!cutDivAction->isPlugged(widget))
|
|
cutDivAction->plug(widget);
|
|
|
|
m_separator->plug(widget);
|
|
}
|
|
else
|
|
{
|
|
copyDivAction->unplug(widget);
|
|
cutDivAction->unplug(widget);
|
|
}
|
|
|
|
// TDEAction* applySourceIndentationAction = ac->action("apply_source_indentation");
|
|
// Q_ASSERT(applySourceIndentationAction);
|
|
//
|
|
// applySourceIndentationAction->unplug(widget); // to keep things in order
|
|
// applySourceIndentationAction->plug(widget);
|
|
//
|
|
// m_separator->plug(widget);
|
|
|
|
return true;
|
|
}
|
|
|
|
void TagActionSet::unplugAllActions(TQWidget* widget) const
|
|
{
|
|
TDEActionCollection* ac(TagActionManager::self()->actionCollection());
|
|
|
|
m_separator->unplugAll();
|
|
|
|
TDEAction* applySourceIndentationAction = ac->action("apply_source_indentation");
|
|
Q_ASSERT(applySourceIndentationAction);
|
|
applySourceIndentationAction->unplug(widget);
|
|
|
|
TDEAction* copyDivAction = ac->action("copy_div_element");
|
|
Q_ASSERT(copyDivAction);
|
|
copyDivAction->unplug(widget);
|
|
|
|
TDEAction* cutDivAction = ac->action("cut_div_element");
|
|
Q_ASSERT(cutDivAction);
|
|
cutDivAction->unplug(widget);
|
|
}
|
|
|
|
void TagActionSet::slotApplySourceIndentation()
|
|
{
|
|
QuantaView* view = ViewManager::ref()->activeView();
|
|
NodeModifsSet *modifs = new NodeModifsSet();
|
|
|
|
TDEConfig* config = kapp->config();
|
|
config->setGroup("Kate Document Defaults");
|
|
int indentationWidth = config->readNumEntry("Indentation Width", 4);
|
|
|
|
//Once the changes have been made, we will generate the "clean" string for Text Nodes only, and
|
|
//we will add the empty indentation Nodes.
|
|
int eLine, eCol;
|
|
Node* node = baseNode;
|
|
while(node)
|
|
{
|
|
if(/*!node->tag->cleanStrBuilt() && */node->tag->type == Tag::Text)
|
|
{
|
|
if(!node->insideSpecial)
|
|
{
|
|
node->tag->setStr(KafkaDocument::ref()->generateCodeFromNode(node, 0, 0, eLine, eCol, false));
|
|
node->tag->setCleanStrBuilt(true);
|
|
}
|
|
}
|
|
if(/*!node->tag->indentationDone() && */!node->insideSpecial)
|
|
{
|
|
kafkaCommon::fitIndentationNodes(kafkaCommon::getPrevNodeNE(node), node, modifs);
|
|
bool goUp = false;
|
|
kafkaCommon::fitIndentationNodes(node, kafkaCommon::getNextNodeNE(node, goUp), modifs);
|
|
kafkaCommon::applyIndentation(node, indentationWidth, 0, modifs, qConfig.inlineNodeIndentation);
|
|
}
|
|
node = node->nextSibling();
|
|
}
|
|
|
|
view->document()->docUndoRedo->addNewModifsSet(modifs, undoRedo::NodeTreeModif);
|
|
}
|
|
|
|
bool TagActionSet::isInDivArea() const
|
|
{
|
|
Q_ASSERT(m_currentNode);
|
|
|
|
return parentTag(m_currentNode, "div");
|
|
}
|
|
|
|
void TagActionSet::slotCopyDivElement()
|
|
{
|
|
Q_ASSERT(m_currentNode);
|
|
|
|
Node* divNode = parentTag(m_currentNode, "div");
|
|
Q_ASSERT(divNode);
|
|
|
|
Node* divClosingNode = divNode->getClosingNode();
|
|
if(!divClosingNode)
|
|
{
|
|
kdError(25001) << "DIV element without closing node: " << divNode << endl;
|
|
return;
|
|
}
|
|
|
|
KafkaDocument::ref()->slotCopy(divNode, 0, divClosingNode, 0, TQString());
|
|
}
|
|
|
|
void TagActionSet::slotCutDivElement()
|
|
{
|
|
Q_ASSERT(m_currentNode);
|
|
|
|
Node* divNode = parentTag(m_currentNode, "div");
|
|
Q_ASSERT(divNode);
|
|
|
|
Node* divClosingNode = divNode->getClosingNode();
|
|
if(!divClosingNode)
|
|
{
|
|
kdError(25001) << "DIV element without closing node: " << divNode << endl;
|
|
return;
|
|
}
|
|
|
|
NodeSelectionInd selection_ind;
|
|
selection_ind.fillWithVPLCursorSelection();
|
|
|
|
int cursorOffset = selection_ind.cursorOffset();
|
|
|
|
KafkaDocument::ref()->slotCut(divNode, 0, divClosingNode, 0, &m_currentNode, cursorOffset, TQString());
|
|
|
|
}
|
|
|
|
//_____________________________________________________________________________
|
|
|
|
TableTagActionSet::TableTagActionSet(TQObject *parent, const char *name)
|
|
: TagActionSetAbstract(parent, name), m_separator(0), m_tableActionMenu_0(0), m_insertActionMenu_1(0)
|
|
{
|
|
m_separator = new TDEActionSeparator();
|
|
}
|
|
|
|
bool TableTagActionSet::isInTagContext() const
|
|
{
|
|
return parentTag(m_currentNode, "table");
|
|
}
|
|
|
|
void TableTagActionSet::initActionMenus(TQWidget* widget)
|
|
{
|
|
Q_ASSERT(!m_tableActionMenu_0);
|
|
|
|
m_tableActionMenu_0 = new TDEActionMenu(i18n("Table..."), TQT_TQOBJECT(widget));
|
|
m_insertActionMenu_1 = new TDEActionMenu(i18n("Insert..."), m_tableActionMenu_0);
|
|
m_removeActionMenu_1 = new TDEActionMenu(i18n("Remove..."), m_tableActionMenu_0);
|
|
}
|
|
|
|
|
|
void TableTagActionSet::initActions(TQWidget* parent)
|
|
{
|
|
if(!m_tableActionMenu_0)
|
|
initActionMenus(parent);
|
|
|
|
TDEActionCollection* ac(TagActionManager::self()->actionCollection());
|
|
|
|
// Insert___________________________________________________________________________
|
|
|
|
const char *actionName = "insert_table";
|
|
//m_actionNames += actionName;
|
|
new TDEAction(i18n("Table..."), 0, this,
|
|
TQT_SLOT(slotInsertTable()),
|
|
ac, actionName);
|
|
|
|
actionName = "insert_row_above";
|
|
//m_actionNames += actionName;
|
|
new TDEAction(i18n("Row Above"), 0, this,
|
|
TQT_SLOT(slotInsertRowAbove()),
|
|
ac, actionName);
|
|
|
|
actionName = "insert_row_below";
|
|
//m_actionNames += actionName;
|
|
new TDEAction(i18n("Row Below"), 0, this,
|
|
TQT_SLOT(slotInsertRowBelow()),
|
|
ac, actionName);
|
|
|
|
actionName = "insert_column_left";
|
|
//m_actionNames += actionName;
|
|
new TDEAction(i18n("Column Left"), 0, this,
|
|
TQT_SLOT(slotInsertColumnLeft()),
|
|
ac, actionName);
|
|
|
|
actionName = "insert_column_right";
|
|
//m_actionNames += actionName;
|
|
new TDEAction(i18n("Column Right"), 0, this,
|
|
TQT_SLOT(slotInsertColumnRight()),
|
|
ac, actionName);
|
|
|
|
// Remove___________________________________________________________________________
|
|
|
|
actionName = "remove_table";
|
|
//m_actionNames += actionName;
|
|
new TDEAction(i18n("Table"), 0, this,
|
|
TQT_SLOT(slotRemoveTable()),
|
|
ac, actionName);
|
|
|
|
actionName = "remove_rows";
|
|
//m_actionNames += actionName;
|
|
new TDEAction(i18n("Row(s)"), 0, this,
|
|
TQT_SLOT(slotRemoveRows()),
|
|
ac, actionName);
|
|
|
|
actionName = "remove_columns";
|
|
//m_actionNames += actionName;
|
|
new TDEAction(i18n("Column(s)"), 0, this,
|
|
TQT_SLOT(slotRemoveColumns()),
|
|
ac, actionName);
|
|
|
|
actionName = "remove_cells";
|
|
//m_actionNames += actionName;
|
|
new TDEAction(i18n("Cell(s)"), 0, this,
|
|
TQT_SLOT(slotRemoveCells()),
|
|
ac, actionName);
|
|
|
|
actionName = "remove_cells_content";
|
|
//m_actionNames += actionName;
|
|
new TDEAction(i18n("Cell(s) Content"), 0, this,
|
|
TQT_SLOT(slotRemoveCellsContent()),
|
|
ac, actionName);
|
|
|
|
// Merge___________________________________________________________________________
|
|
|
|
actionName = "merge_selected_cells";
|
|
//m_actionNames += actionName;
|
|
new TDEAction(i18n("Merge Selected Cells"), 0, this,
|
|
TQT_SLOT(slotMergeSelectedCells()),
|
|
ac, actionName);
|
|
}
|
|
|
|
bool TableTagActionSet::fillWithTagActions(TQWidget* widget, DOM::Node const& node)
|
|
{
|
|
bool validNode = TagActionSetAbstract::fillWithTagActions(widget, node);
|
|
|
|
if(!validNode || !isInTagContext(/*node*/))
|
|
{
|
|
unplugAllActions(widget);
|
|
return false;
|
|
}
|
|
|
|
m_separator->unplugAll();
|
|
|
|
TDEActionCollection* ac(TagActionManager::self()->actionCollection());
|
|
|
|
// Table
|
|
bool emptyTableActionMenu_0 = true;
|
|
|
|
// Insert _____________________________________________________________________
|
|
|
|
// Insert
|
|
bool emptyInsertActionMenu_1 = true;
|
|
|
|
// Insert Table
|
|
TDEAction* insertTableAction = ac->action("insert_table");
|
|
Q_ASSERT(insertTableAction);
|
|
|
|
m_insertActionMenu_1->remove(insertTableAction);
|
|
if(canInsertTable())
|
|
{
|
|
emptyTableActionMenu_0 = emptyInsertActionMenu_1 = false;
|
|
m_insertActionMenu_1->insert(insertTableAction);
|
|
|
|
m_insertActionMenu_1->insert(m_separator);
|
|
}
|
|
// Insert Row Above
|
|
TDEAction* insertRowAboveAction = ac->action("insert_row_above");
|
|
Q_ASSERT(insertRowAboveAction);
|
|
|
|
m_insertActionMenu_1->remove(insertRowAboveAction);
|
|
if(canInsertRowAbove())
|
|
{
|
|
emptyTableActionMenu_0 = emptyInsertActionMenu_1 = false;
|
|
m_insertActionMenu_1->insert(insertRowAboveAction);
|
|
|
|
//m_insertActionMenu_1->insert(m_separator);
|
|
}
|
|
// Insert Row Below
|
|
TDEAction* insertRowBelowAction = ac->action("insert_row_below");
|
|
Q_ASSERT(insertRowBelowAction);
|
|
|
|
m_insertActionMenu_1->remove(insertRowBelowAction);
|
|
if(canInsertRowBelow())
|
|
{
|
|
emptyTableActionMenu_0 = emptyInsertActionMenu_1 = false;
|
|
m_insertActionMenu_1->insert(insertRowBelowAction);
|
|
|
|
m_insertActionMenu_1->insert(m_separator);
|
|
}
|
|
// Insert Column Left
|
|
TDEAction* insertColumnLeftAction = ac->action("insert_column_left");
|
|
Q_ASSERT(insertColumnLeftAction);
|
|
|
|
m_insertActionMenu_1->remove(insertColumnLeftAction);
|
|
if(canInsertColumnLeft())
|
|
{
|
|
emptyTableActionMenu_0 = emptyInsertActionMenu_1 = false;
|
|
m_insertActionMenu_1->insert(insertColumnLeftAction);
|
|
|
|
//m_insertActionMenu_1->insert(m_separator);
|
|
}
|
|
// Insert Column Right
|
|
TDEAction* insertColumnRightAction = ac->action("insert_column_right");
|
|
Q_ASSERT(insertColumnRightAction);
|
|
|
|
m_insertActionMenu_1->remove(insertColumnRightAction);
|
|
if(canInsertColumnRight())
|
|
{
|
|
emptyTableActionMenu_0 = emptyInsertActionMenu_1 = false;
|
|
m_insertActionMenu_1->insert(insertColumnRightAction);
|
|
|
|
m_insertActionMenu_1->insert(m_separator);
|
|
}
|
|
// Remove _____________________________________________________________________
|
|
|
|
// Remove
|
|
bool emptyRemoveActionMenu_1 = true;
|
|
|
|
// Remove Table
|
|
TDEAction* removeTableAction = ac->action("remove_table");
|
|
Q_ASSERT(removeTableAction);
|
|
|
|
m_removeActionMenu_1->remove(removeTableAction);
|
|
if(canRemoveTable())
|
|
{
|
|
emptyTableActionMenu_0 = emptyRemoveActionMenu_1 = false;
|
|
m_removeActionMenu_1->insert(removeTableAction);
|
|
|
|
m_removeActionMenu_1->insert(m_separator);
|
|
}
|
|
// Remove Row(s)
|
|
TDEAction* removeRowsAction = ac->action("remove_rows");
|
|
Q_ASSERT(removeRowsAction);
|
|
|
|
m_removeActionMenu_1->remove(removeRowsAction);
|
|
if(canRemoveRows())
|
|
{
|
|
emptyTableActionMenu_0 = emptyRemoveActionMenu_1 = false;
|
|
m_removeActionMenu_1->insert(removeRowsAction);
|
|
|
|
//m_removeActionMenu_1->insert(m_separator);
|
|
}
|
|
// Remove Column(s)
|
|
TDEAction* removeColumnsAction = ac->action("remove_columns");
|
|
Q_ASSERT(removeColumnsAction);
|
|
|
|
m_removeActionMenu_1->remove(removeColumnsAction);
|
|
if(canRemoveColumns())
|
|
{
|
|
emptyTableActionMenu_0 = emptyRemoveActionMenu_1 = false;
|
|
m_removeActionMenu_1->insert(removeColumnsAction);
|
|
|
|
//m_removeActionMenu_1->insert(m_separator);
|
|
}
|
|
/* // Remove Cell(s)
|
|
TDEAction* removeCellsAction = ac->action("remove_cells");
|
|
Q_ASSERT(removeCellsAction);
|
|
|
|
m_removeActionMenu_1->remove(removeCellsAction);
|
|
if(canRemoveCells())
|
|
{
|
|
emptyTableActionMenu_0 = emptyRemoveActionMenu_1 = false;
|
|
m_removeActionMenu_1->insert(removeCellsAction);
|
|
|
|
//m_removeActionMenu_1->insert(m_separator);
|
|
}*/
|
|
// Remove Cell(s) Content
|
|
TDEAction* removeCellsContentAction = ac->action("remove_cells_content");
|
|
Q_ASSERT(removeCellsContentAction);
|
|
|
|
m_removeActionMenu_1->remove(removeCellsContentAction);
|
|
if(canRemoveCellsContent())
|
|
{
|
|
emptyTableActionMenu_0 = emptyRemoveActionMenu_1 = false;
|
|
m_removeActionMenu_1->insert(removeCellsContentAction);
|
|
|
|
//m_removeActionMenu_1->insert(m_separator);
|
|
}
|
|
// Remove _____________________________________________________________________
|
|
|
|
// Merge
|
|
// bool emptyRemoveActionMenu_1 = true;
|
|
|
|
// _____________________________________________________________________________
|
|
|
|
// Table
|
|
m_tableActionMenu_0->unplug(widget);
|
|
if(!emptyTableActionMenu_0)
|
|
{
|
|
m_tableActionMenu_0->plug(widget);
|
|
|
|
m_tableActionMenu_0->remove(m_insertActionMenu_1);
|
|
if(!emptyInsertActionMenu_1)
|
|
m_tableActionMenu_0->insert(m_insertActionMenu_1);
|
|
|
|
m_tableActionMenu_0->remove(m_removeActionMenu_1);
|
|
if(!emptyRemoveActionMenu_1)
|
|
m_tableActionMenu_0->insert(m_removeActionMenu_1);
|
|
|
|
m_tableActionMenu_0->insert(m_separator);
|
|
}
|
|
// Merge selected cells
|
|
TDEAction* mergeSelectedCellsAction = ac->action("merge_selected_cells");
|
|
Q_ASSERT(mergeSelectedCellsAction);
|
|
|
|
m_tableActionMenu_0->remove(mergeSelectedCellsAction);
|
|
if(canMergeSelectedCells())
|
|
{
|
|
emptyTableActionMenu_0 = false;
|
|
m_tableActionMenu_0->insert(mergeSelectedCellsAction);
|
|
|
|
// m_removeActionMenu_1->insert(m_separator);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void TableTagActionSet::unplugAllActions(TQWidget* widget) const
|
|
{
|
|
m_separator->unplugAll();
|
|
m_tableActionMenu_0->unplug(widget);
|
|
}
|
|
|
|
// Insert _____________________________________________________________________
|
|
|
|
bool TableTagActionSet::canInsertTable() const
|
|
{
|
|
return false;
|
|
// return isInTagContext(currentDomNode()); // TODO Implement slotInsertTable
|
|
}
|
|
|
|
void TableTagActionSet::slotInsertTable()
|
|
{
|
|
Q_ASSERT(m_currentNode);
|
|
|
|
}
|
|
|
|
bool TableTagActionSet::canInsertRowAbove() const
|
|
{
|
|
return isInTagContext() && parentTag(m_currentNode, "tbody");
|
|
}
|
|
|
|
void TableTagActionSet::slotInsertRowAbove()
|
|
{
|
|
Q_ASSERT(m_currentNode);
|
|
|
|
Node* nearRow = parentTag(m_currentNode, "tr");
|
|
|
|
if(!nearRow)
|
|
return;
|
|
|
|
Node* nodeParent= nearRow->parent;
|
|
|
|
QuantaView* view = ViewManager::ref()->activeView();
|
|
NodeModifsSet *modifs = new NodeModifsSet();
|
|
Node* nodeToInsert = buildEmptyRowSubtree();
|
|
|
|
kafkaCommon::insertNodeSubtree(nodeToInsert, nodeParent, nearRow, modifs);
|
|
|
|
view->document()->docUndoRedo->addNewModifsSet(modifs, undoRedo::NodeTreeModif);
|
|
|
|
// kafkaCommon::coutTree(baseNode, 3);
|
|
}
|
|
|
|
bool TableTagActionSet::canInsertRowBelow() const
|
|
{
|
|
return isInTagContext();
|
|
}
|
|
|
|
void TableTagActionSet::slotInsertRowBelow()
|
|
{
|
|
Q_ASSERT(m_currentNode);
|
|
|
|
Node* nearRow = 0;
|
|
Node* aux = parentTag(m_currentNode, "thead");
|
|
if(aux)
|
|
nearRow= firstChildTag(tableStart(), "tr");
|
|
else
|
|
nearRow = parentTag(m_currentNode, "tr");
|
|
|
|
if(!nearRow)
|
|
return;
|
|
|
|
Node* nodeParent= nearRow->parent;
|
|
Node* nextSibling = nearRow->SNext();
|
|
|
|
QuantaView* view = ViewManager::ref()->activeView();
|
|
NodeModifsSet *modifs = new NodeModifsSet();
|
|
Node* nodeToInsert = buildEmptyRowSubtree();
|
|
|
|
kafkaCommon::insertNodeSubtree(nodeToInsert, nodeParent, nextSibling, modifs);
|
|
|
|
view->document()->docUndoRedo->addNewModifsSet(modifs, undoRedo::NodeTreeModif);
|
|
|
|
// kafkaCommon::coutTree(baseNode, 3);
|
|
}
|
|
|
|
bool TableTagActionSet::canInsertColumnLeft() const
|
|
{
|
|
return isInTagContext();
|
|
}
|
|
|
|
void TableTagActionSet::slotInsertColumnLeft()
|
|
{
|
|
Q_ASSERT(m_currentNode);
|
|
|
|
QuantaView* view = ViewManager::ref()->activeView();
|
|
NodeModifsSet *modifs = new NodeModifsSet();
|
|
|
|
Node* nodeToInsertInBody = buildEmptyTBodyCellSubtree();
|
|
Node* nodeToInsertInHead = buildEmptyTHeadCellSubtree();
|
|
Q_ASSERT(nodeToInsertInBody);
|
|
Q_ASSERT(nodeToInsertInHead);
|
|
|
|
int const _currentColumnIndex = currentColumnIndex();
|
|
|
|
// thead
|
|
Node* trChild = firstChildTag(firstChildTag(tableStart(), "thead"), "tr");
|
|
while(trChild)
|
|
{
|
|
Node* thChild = firstChildTag(trChild, "th");
|
|
for(int i = 0; (i != _currentColumnIndex && thChild); ++i)
|
|
thChild = thChild->SNext();
|
|
|
|
kafkaCommon::insertNodeSubtree(nodeToInsertInHead, trChild, thChild, modifs);
|
|
|
|
nodeToInsertInHead = kafkaCommon::duplicateNodeSubtree(nodeToInsertInHead);
|
|
|
|
trChild = trChild->SNext();
|
|
}
|
|
|
|
// tbody
|
|
trChild = firstChildTag(firstChildTag(tableStart(), "tbody"), "tr");
|
|
while(trChild)
|
|
{
|
|
Node* tdChild = firstChildTag(trChild, "td");
|
|
for(int i = 0; (i != _currentColumnIndex && tdChild); ++i)
|
|
tdChild = tdChild->SNext();
|
|
|
|
kafkaCommon::insertNodeSubtree(nodeToInsertInBody, trChild, tdChild, modifs);
|
|
|
|
nodeToInsertInBody = kafkaCommon::duplicateNodeSubtree(nodeToInsertInBody);
|
|
|
|
trChild = trChild->SNext();
|
|
}
|
|
|
|
view->document()->docUndoRedo->addNewModifsSet(modifs, undoRedo::NodeTreeModif);
|
|
|
|
// kafkaCommon::coutTree(baseNode, 3);
|
|
}
|
|
|
|
bool TableTagActionSet::canInsertColumnRight() const
|
|
{
|
|
return isInTagContext();
|
|
}
|
|
|
|
void TableTagActionSet::slotInsertColumnRight()
|
|
{
|
|
Q_ASSERT(m_currentNode);
|
|
|
|
QuantaView* view = ViewManager::ref()->activeView();
|
|
NodeModifsSet *modifs = new NodeModifsSet();
|
|
|
|
Node* nodeToInsertInBody = buildEmptyTBodyCellSubtree();
|
|
Node* nodeToInsertInHead = buildEmptyTHeadCellSubtree();
|
|
Q_ASSERT(nodeToInsertInBody);
|
|
Q_ASSERT(nodeToInsertInHead);
|
|
|
|
int const _currentColumnIndex = currentColumnIndex();
|
|
|
|
// thead
|
|
Node* trChild = firstChildTag(firstChildTag(tableStart(), "thead"), "tr");
|
|
while(trChild)
|
|
{
|
|
Node* thChild = firstChildTag(trChild, "th");
|
|
for(int i = 0; (i != _currentColumnIndex + 1 && thChild); ++i)
|
|
thChild = thChild->SNext();
|
|
|
|
kafkaCommon::insertNodeSubtree(nodeToInsertInHead, trChild, thChild, modifs);
|
|
|
|
nodeToInsertInHead = kafkaCommon::duplicateNodeSubtree(nodeToInsertInHead);
|
|
|
|
trChild = trChild->SNext();
|
|
}
|
|
|
|
// tbody
|
|
trChild = firstChildTag(firstChildTag(tableStart(), "tbody"), "tr");
|
|
while(trChild)
|
|
{
|
|
Node* tdChild = firstChildTag(trChild, "td");
|
|
for(int i = 0; (i != _currentColumnIndex + 1 && tdChild); ++i)
|
|
tdChild = tdChild->SNext();
|
|
|
|
kafkaCommon::insertNodeSubtree(nodeToInsertInBody, trChild, tdChild, modifs);
|
|
|
|
nodeToInsertInBody = kafkaCommon::duplicateNodeSubtree(nodeToInsertInBody);
|
|
|
|
trChild = trChild->SNext();
|
|
}
|
|
|
|
view->document()->docUndoRedo->addNewModifsSet(modifs, undoRedo::NodeTreeModif);
|
|
|
|
// kafkaCommon::coutTree(baseNode, 3);
|
|
}
|
|
|
|
// Remove ________________________________________________________________
|
|
|
|
bool TableTagActionSet::canRemoveTable() const
|
|
{
|
|
return isInTagContext();
|
|
}
|
|
|
|
void TableTagActionSet::slotRemoveTable()
|
|
{
|
|
Q_ASSERT(m_currentNode);
|
|
|
|
QuantaView* view = ViewManager::ref()->activeView();
|
|
NodeModifsSet *modifs = new NodeModifsSet();
|
|
|
|
Node* _tableStart = tableStart();
|
|
|
|
kafkaCommon::extractAndDeleteNode(_tableStart, modifs, true, true);
|
|
|
|
view->document()->docUndoRedo->addNewModifsSet(modifs, undoRedo::NodeTreeModif);
|
|
|
|
// kafkaCommon::coutTree(baseNode, 3);
|
|
}
|
|
|
|
bool TableTagActionSet::canRemoveRows() const
|
|
{
|
|
return isInTagContext();
|
|
}
|
|
|
|
void TableTagActionSet::slotRemoveRows()
|
|
{
|
|
Q_ASSERT(m_currentNode);
|
|
|
|
QuantaView* view = ViewManager::ref()->activeView();
|
|
NodeModifsSet *modifs = new NodeModifsSet();
|
|
|
|
NodeSelectionInd selection;
|
|
selection.fillWithVPLCursorSelection();
|
|
|
|
if(!selection.hasSelection())
|
|
{
|
|
Node* nearTr = parentTag(m_currentNode, "tr");
|
|
kafkaCommon::extractAndDeleteNode(nearTr, modifs, true, true);
|
|
}
|
|
else
|
|
{
|
|
Node* startSelection = kafkaCommon::getNodeFromLocation(selection.cursorNode());
|
|
Node* endSelection = kafkaCommon::getNodeFromLocation(selection.cursorNodeEndSel());
|
|
|
|
Node* startTr = parentTag(startSelection, "tr");
|
|
Node* endTr = parentTag(endSelection, "tr");
|
|
|
|
Node* iteratorNode = startTr;
|
|
bool loop(true);
|
|
while(iteratorNode && loop)
|
|
{
|
|
// the check has to be done before extract
|
|
if(iteratorNode == endTr)
|
|
loop = false;
|
|
|
|
Node* aux = iteratorNode;
|
|
iteratorNode = iteratorNode->SNext();
|
|
|
|
kafkaCommon::extractAndDeleteNode(aux, modifs, true, true);
|
|
}
|
|
}
|
|
|
|
view->document()->docUndoRedo->addNewModifsSet(modifs, undoRedo::NodeTreeModif);
|
|
|
|
// kafkaCommon::coutTree(baseNode, 3);
|
|
}
|
|
|
|
bool TableTagActionSet::canRemoveColumns() const
|
|
{
|
|
return isInTagContext();
|
|
}
|
|
|
|
void TableTagActionSet::slotRemoveColumns()
|
|
{
|
|
Q_ASSERT(m_currentNode);
|
|
|
|
QuantaView* view = ViewManager::ref()->activeView();
|
|
NodeModifsSet *modifs = new NodeModifsSet();
|
|
|
|
NodeSelectionInd selection;
|
|
selection.fillWithVPLCursorSelection();
|
|
|
|
if(!selection.hasSelection())
|
|
{
|
|
int const _currentColumnIndex = currentColumnIndex();
|
|
removeColumn(_currentColumnIndex, modifs);
|
|
}
|
|
else
|
|
{
|
|
Node* startSelection = kafkaCommon::getNodeFromLocation(selection.cursorNode());
|
|
Node* endSelection = kafkaCommon::getNodeFromLocation(selection.cursorNodeEndSel());
|
|
|
|
int startColumnIndex = columnIndex(startSelection);
|
|
int endColumnIndex = columnIndex(endSelection);
|
|
int numberOfColumnsSelected = endColumnIndex - startColumnIndex + 1;
|
|
|
|
if(startColumnIndex == -1 || endColumnIndex == -1)
|
|
return;
|
|
|
|
m_currentNode = parentTag(m_currentNode, "tbody"); // m_currentNode will become invalid
|
|
for(int i = 0; i != numberOfColumnsSelected; ++i)
|
|
removeColumn(startColumnIndex, modifs);
|
|
}
|
|
|
|
view->document()->docUndoRedo->addNewModifsSet(modifs, undoRedo::NodeTreeModif);
|
|
|
|
// kafkaCommon::coutTree(baseNode, 3);
|
|
}
|
|
|
|
bool TableTagActionSet::canRemoveCells() const
|
|
{
|
|
return isInTagContext();
|
|
}
|
|
|
|
void TableTagActionSet::slotRemoveCells()
|
|
{}
|
|
|
|
bool TableTagActionSet::canRemoveCellsContent() const
|
|
{
|
|
return isInTagContext();
|
|
}
|
|
|
|
void TableTagActionSet::slotRemoveCellsContent()
|
|
{
|
|
Q_ASSERT(m_currentNode);
|
|
|
|
QuantaView* view = ViewManager::ref()->activeView();
|
|
NodeModifsSet *modifs = new NodeModifsSet();
|
|
|
|
NodeSelectionInd selection;
|
|
selection.fillWithVPLCursorSelection();
|
|
|
|
if(!selection.hasSelection())
|
|
{
|
|
Node* aux = m_currentNode;
|
|
m_currentNode = parentTag(m_currentNode, "tbody");
|
|
|
|
Node* nearTd = parentTag(aux, "td");
|
|
clearCellContents(nearTd, modifs);
|
|
}
|
|
else
|
|
{
|
|
Node* startSelection = kafkaCommon::getNodeFromLocation(selection.cursorNode());
|
|
Node* endSelection = kafkaCommon::getNodeFromLocation(selection.cursorNodeEndSel());
|
|
|
|
Node* startTd = parentTag(startSelection, "td");
|
|
Node* endTd = parentTag(endSelection, "td");
|
|
|
|
if(!startTd || !endTd)
|
|
return;
|
|
|
|
}
|
|
|
|
view->document()->docUndoRedo->addNewModifsSet(modifs, undoRedo::NodeTreeModif);
|
|
|
|
// kafkaCommon::coutTree(baseNode, 3);
|
|
}
|
|
|
|
// Merge ________________________________________________________________
|
|
|
|
bool TableTagActionSet::canMergeSelectedCells() const
|
|
{
|
|
if(!KafkaDocument::ref()->getKafkaWidget()->hasSelection())
|
|
return false;
|
|
|
|
NodeSelectionInd selection;
|
|
selection.fillWithVPLCursorSelection();
|
|
TQValueList<int> start = selection.cursorNode();
|
|
TQValueList<int> end = selection.cursorNodeEndSel();
|
|
|
|
return start != end;
|
|
}
|
|
|
|
void TableTagActionSet::slotMergeSelectedCells()
|
|
{
|
|
Q_ASSERT(m_currentNode);
|
|
|
|
QuantaView* view = ViewManager::ref()->activeView();
|
|
NodeModifsSet *modifs = new NodeModifsSet();
|
|
|
|
NodeSelectionInd selection;
|
|
selection.fillWithVPLCursorSelection();
|
|
|
|
Q_ASSERT(selection.hasSelection());
|
|
|
|
Node* startSelection = kafkaCommon::getNodeFromLocation(selection.cursorNode());
|
|
Node* endSelection = kafkaCommon::getNodeFromLocation(selection.cursorNodeEndSel());
|
|
|
|
Node* startTd = parentTag(startSelection, "td");
|
|
Node* endTd = parentTag(endSelection, "td");
|
|
|
|
Node* nodeIterator = startTd->SNext();
|
|
Node* stopNode = endTd->SNext();
|
|
int count = 1;
|
|
while(nodeIterator && nodeIterator != stopNode)
|
|
{
|
|
Node* aux = nodeIterator;
|
|
nodeIterator = nodeIterator->SNext();
|
|
|
|
Node* child = aux->firstChild();
|
|
while(child)
|
|
{
|
|
Node* next = child->next;
|
|
kafkaCommon::moveNode(child, startTd, 0, modifs);
|
|
child = next;
|
|
}
|
|
|
|
kafkaCommon::extractAndDeleteNode(aux, modifs);
|
|
|
|
++count;
|
|
}
|
|
|
|
if(count == 1)
|
|
return;
|
|
|
|
kafkaCommon::editNodeAttribute(startTd, "colspan", TQString::number(count), modifs);
|
|
kafkaCommon::editNodeAttribute(startTd, "rowspan", "1", modifs);
|
|
|
|
view->document()->docUndoRedo->addNewModifsSet(modifs, undoRedo::NodeTreeModif);
|
|
|
|
// kafkaCommon::coutTree(baseNode, 3);
|
|
}
|
|
|
|
//_____________________________________________________________________________
|
|
|
|
Node* TableTagActionSet::tableStart() const
|
|
{
|
|
Q_ASSERT(isInTagContext());
|
|
Q_ASSERT(m_currentNode);
|
|
|
|
return parentTag(m_currentNode, "table");
|
|
}
|
|
|
|
int TableTagActionSet::numberOfColumns() const
|
|
{
|
|
Node* _tableStart = tableStart();
|
|
if(!_tableStart)
|
|
return -1;
|
|
|
|
Node* firstTd = firstChildTag(_tableStart, "td");
|
|
|
|
if(!firstTd)
|
|
return -1;
|
|
|
|
int count(0);
|
|
Node* aux = firstTd;
|
|
while(aux)
|
|
{
|
|
++count;
|
|
aux = aux->SNext();
|
|
}
|
|
|
|
kdDebug(23100) << "Number of columns: " << count << endl;
|
|
return count;
|
|
}
|
|
|
|
int TableTagActionSet::currentColumnIndex() const
|
|
{
|
|
return columnIndex(m_currentNode);
|
|
/* Node* nearTd = parentTag(m_currentNode, "td");
|
|
if(!nearTd)
|
|
return -1;
|
|
|
|
Node* _tableStart = tableStart();
|
|
if(!_tableStart)
|
|
return -1;
|
|
|
|
Node* firstTd = firstChildTag(parentTag(m_currentNode, "tr"), "td");
|
|
//Node* firstTd = firstChildTag(_tableStart, "td");
|
|
if(!firstTd)
|
|
return -1;
|
|
|
|
int count(0);
|
|
Node* aux = firstTd;
|
|
while(aux && aux != nearTd)
|
|
{
|
|
++count;
|
|
aux = aux->SNext();
|
|
}
|
|
|
|
if(!aux)
|
|
count = -1;
|
|
return count;*/
|
|
}
|
|
|
|
int TableTagActionSet::columnIndex(Node* node) const
|
|
{
|
|
Node* nearTd = parentTag(node, "td");
|
|
if(!nearTd)
|
|
return -1;
|
|
|
|
Node* _tableStart = tableStart();
|
|
if(!_tableStart)
|
|
return -1;
|
|
|
|
Node* firstTd = firstChildTag(parentTag(node, "tr"), "td");
|
|
if(!firstTd)
|
|
return -1;
|
|
|
|
int count(0);
|
|
Node* aux = firstTd;
|
|
while(aux && aux != nearTd)
|
|
{
|
|
++count;
|
|
aux = aux->SNext();
|
|
}
|
|
|
|
if(!aux)
|
|
count = -1;
|
|
return count;
|
|
}
|
|
|
|
Node* TableTagActionSet::buildEmptyRowSubtree() const
|
|
{
|
|
QuantaView* view = ViewManager::ref()->activeView();
|
|
|
|
Node* nodeToInsert = kafkaCommon::createNode("", "", Tag::XmlTag, view->document());
|
|
nodeToInsert->tag->parse("<tr>", view->document());
|
|
kafkaCommon::createMandatoryNodeSubtree(nodeToInsert, view->document());
|
|
// now we have: <tr><td></td></tr>
|
|
|
|
//Let's -> <tr><td><br></td></tr>
|
|
Node* brNode = kafkaCommon::createNode("", "", Tag::XmlTag, view->document());
|
|
brNode->tag->parse("<br>", view->document());
|
|
Node* tdNode = nodeToInsert->child;
|
|
kafkaCommon::insertNode(brNode, tdNode, 0, 0);
|
|
|
|
int _numberOfColumns = numberOfColumns();
|
|
|
|
if(_numberOfColumns == -1)
|
|
return 0;
|
|
|
|
for(int i = 1; i != _numberOfColumns; ++i)
|
|
{
|
|
Node* duplicatedTdSubtree = kafkaCommon::duplicateNodeSubtree(tdNode);
|
|
kafkaCommon::insertNodeSubtree(duplicatedTdSubtree, nodeToInsert, 0, 0);
|
|
}
|
|
|
|
kafkaCommon::coutTree(nodeToInsert, 3);
|
|
|
|
return nodeToInsert;
|
|
}
|
|
|
|
Node* TableTagActionSet::buildEmptyTBodyCellSubtree() const
|
|
{
|
|
QuantaView* view = ViewManager::ref()->activeView();
|
|
|
|
// build tree -> <td><br></td>
|
|
Node* nodeToInsert = kafkaCommon::createNode("", "", Tag::XmlTag, view->document());
|
|
nodeToInsert->tag->parse("<td>", view->document());
|
|
Node* brNode = kafkaCommon::createNode("", "", Tag::XmlTag, view->document());
|
|
brNode->tag->parse("<br>", view->document());
|
|
kafkaCommon::insertNode(brNode, nodeToInsert, 0, 0);
|
|
|
|
return nodeToInsert;
|
|
}
|
|
|
|
Node* TableTagActionSet::buildEmptyTHeadCellSubtree() const
|
|
{
|
|
QuantaView* view = ViewManager::ref()->activeView();
|
|
|
|
// build tree -> <td><br></td>
|
|
Node* nodeToInsert = kafkaCommon::createNode("", "", Tag::XmlTag, view->document());
|
|
nodeToInsert->tag->parse("<th>", view->document());
|
|
Node* brNode = kafkaCommon::createNode("", "", Tag::XmlTag, view->document());
|
|
brNode->tag->parse("<br>", view->document());
|
|
kafkaCommon::insertNode(brNode, nodeToInsert, 0, 0);
|
|
|
|
return nodeToInsert;
|
|
}
|
|
|
|
void TableTagActionSet::removeColumn(int _currentColumnIndex, NodeModifsSet* modifs)
|
|
{
|
|
Q_ASSERT(m_currentNode);
|
|
Q_ASSERT(_currentColumnIndex >= 0);
|
|
Q_ASSERT(modifs);
|
|
|
|
// thead
|
|
Node* trChild = firstChildTag(firstChildTag(tableStart(), "thead"), "tr");
|
|
while(trChild)
|
|
{
|
|
Node* thChild = firstChildTag(trChild, "th");
|
|
for(int i = 0; (i != _currentColumnIndex && thChild); ++i)
|
|
thChild = thChild->SNext();
|
|
|
|
kafkaCommon::extractAndDeleteNode(thChild, modifs, true, true);
|
|
|
|
trChild = trChild->SNext();
|
|
}
|
|
|
|
// tbody
|
|
trChild = firstChildTag(firstChildTag(tableStart(), "tbody"), "tr");
|
|
while(trChild)
|
|
{
|
|
Node* tdChild = firstChildTag(trChild, "td");
|
|
for(int i = 0; (i != _currentColumnIndex && tdChild); ++i)
|
|
tdChild = tdChild->SNext();
|
|
|
|
kafkaCommon::extractAndDeleteNode(tdChild, modifs, true, true);
|
|
|
|
trChild = trChild->SNext();
|
|
}
|
|
}
|
|
|
|
void TableTagActionSet::clearCellContents(Node* tdNode, NodeModifsSet* modifs)
|
|
{
|
|
if (!tdNode)
|
|
return;
|
|
Node* tdChild = tdNode->child;
|
|
|
|
if(!tdChild)
|
|
return;
|
|
|
|
while(tdChild)
|
|
{
|
|
Node* aux = tdChild;
|
|
tdChild = tdChild->next;
|
|
|
|
kafkaCommon::extractAndDeleteNode(aux, modifs, true, false);
|
|
}
|
|
}
|
|
|
|
//_____________________________________________________________________________
|
|
|
|
#include "tagactionset.moc"
|