summaryrefslogtreecommitdiffstats
path: root/part/kxmleditorpart.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'part/kxmleditorpart.cpp')
-rw-r--r--part/kxmleditorpart.cpp1923
1 files changed, 1923 insertions, 0 deletions
diff --git a/part/kxmleditorpart.cpp b/part/kxmleditorpart.cpp
new file mode 100644
index 0000000..6abe508
--- /dev/null
+++ b/part/kxmleditorpart.cpp
@@ -0,0 +1,1923 @@
+/***************************************************************************
+ kxmleditorpart.cpp - description
+ -------------------
+ begin : Wed Sep 19 2001
+ copyright : (C) 2001, 2002, 2003 by The KXMLEditor Team
+ email : OleBowle@gmx.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 "kxmleditorpart.h"
+#include "kxmleditorfactory.h"
+
+#include "kxedocument.h"
+
+#include "kxeconfiguration.h"
+#include "kxenewfilesettings.h"
+#include "kxearchiveextssettings.h"
+#include "kxeprintsettings.h"
+#include "kxetextviewsettings.h"
+
+#include "commands_edit.h"
+#include "commands_insert.h"
+
+#include "kxe_viewelement.h"
+#include "kxe_treeviewitem.h"
+
+#include "kxesearchdialog.h"
+#include "kxechoosestringdialog.h"
+#include "kxeelementdialog.h"
+#include "kxeattributedialog.h"
+#include "kxeprocinstrdialog.h"
+#include "kxespecprocinstrdialog.h"
+#include "kxefilenewdialog.h"
+#include "kxechardatadialog.h"
+#include "kxeattachdialogbase.h"
+#include "kxetexteditordialog.h"
+
+#include "actions.h"
+#include "qdom_add.h"
+
+#include <kinstance.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kaction.h>
+#include <kstdaction.h>
+#include <kpopupmenu.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kprinter.h>
+#include <ktar.h>
+#include <kzip.h>
+#include <ktempfile.h>
+#include <kconfig.h>
+#include <kurlrequester.h>
+#include <kcommand.h>
+#include <ktoolbar.h>
+#include <kfiledialog.h>
+
+#include <qregexp.h>
+#include <qtextcodec.h>
+#include <qstringlist.h>
+#include <qsplitter.h>
+#include <qtabwidget.h>
+#include <qtextedit.h>
+#include <qcombobox.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qclipboard.h>
+#include <qdragobject.h>
+#include <qapplication.h>
+#include <qbuffer.h>
+#include <qlabel.h>
+#include <qpainter.h>
+#include <qpaintdevicemetrics.h>
+#include <qevent.h>
+
+#include "dcopiface_part_ro.h" // DCOP Iface
+
+#define CONFIG_MAIN_SPLITTER_SIZES "Main splitter sizes"
+
+
+KXMLEditorPart::KXMLEditorPart( bool fReadWrite, KXEDocument* pDocument, QWidget * pParent, const char * pszName )
+ : KParts::ReadWritePart(pParent,pszName),
+ m_pDlgSearch(0),
+ m_pDocument(0)
+{
+ //////////////////////////////
+ // INIT PART
+ //////////////////////////////
+
+ setInstance(KXMLEditorFactory::instance());
+
+ if(fReadWrite)
+ m_pBrowserExt = 0L; // Create Browser extension only for read-only part
+ else
+ m_pBrowserExt = new KXMLEditorBrowserExtension( this, "KXMLEditorPart browser extension" );
+
+ m_pPrinter = 0L;
+
+ m_bAlreadyModified = false;
+
+ //////////////////////////////
+ // CREATE ACTIONS
+ //////////////////////////////
+
+ // file actions
+ if(fReadWrite)
+ {
+ KStdAction::save(this, SLOT(save()), actionCollection());
+ KStdAction::saveAs(this, SLOT(slotFileSaveAs()), actionCollection());
+ }
+
+ // edit actions
+ m_pActEditFind = KStdAction::find( this, SLOT(slotEditFind()), actionCollection());
+ m_pActEditFindNext = KStdAction::findNext( this, SLOT(slotEditFindNext()), actionCollection());
+ m_pActEditDeselect = new KAction( i18n("D&eselect Node"), CTRL+Key_E, this,
+ SLOT(slotEditDeselect()), actionCollection(), "deselect" );
+
+ // view actions
+ m_pActViewNodeUp = new KAction( i18n("To &Parent Node"), "up", 0, this,
+ SLOT(slotViewNodeUp()), actionCollection(), "treeitem_up" );
+
+ m_pActViewExpNode = new KToolBarPopupAction( i18n("&Expand Node"), "expand_node", CTRL+Key_Plus, this,
+ SLOT(slotViewExpNode()), actionCollection(), "treeitem_expand" );
+ KPopupMenu * pMenuExpNode = m_pActViewExpNode->popupMenu();
+ connect( pMenuExpNode, SIGNAL(activated(int)), this, SLOT(slotViewExpNode(int)) );
+ for ( uint i = 1; i <= 8; i++ )
+ pMenuExpNode->insertItem( i18n("Expand To Level %1").arg(i), i-1 );
+
+ m_pActViewColNode = new KToolBarPopupAction( i18n("&Collapse Node"), "collapse_node", CTRL+Key_Minus, this,
+ SLOT(slotViewColNode()), actionCollection(), "treeitem_collapse" );
+ KPopupMenu * pMenuColNode = m_pActViewColNode->popupMenu();
+ connect( pMenuColNode, SIGNAL(activated(int)), this, SLOT(slotViewColNode(int)) );
+ for ( uint i = 0; i <= 7; i++ )
+ pMenuColNode->insertItem( i18n("Collapse To Level %1").arg(i), i );
+
+ // bookmark actions
+ m_pActBookmarksToggle = new KAction( i18n("&Toggle Bookmark"), "bookmark_add", CTRL+Key_B, this,
+ SLOT(slotBookmarksToggle()), actionCollection(), "bookmark_toggle" );
+ m_pActBookmarksPrev = new KAction( i18n("&Previous Bookmark"), "bookmark_prev", SHIFT+Key_F5, this,
+ SLOT(slotBookmarksPrev()), actionCollection(), "bookmark_prev" );
+ m_pActBookmarksNext = new KAction( i18n("&Next Bookmark"), "bookmark_next", Key_F5, this,
+ SLOT(slotBookmarksNext()), actionCollection(), "bookmark_next" );
+
+ // settings actions
+ new KAction( i18n("&Configure KXMLEditor..."), "configure", 0, this,
+ SLOT (slotConfigure()), actionCollection(), "configure" );
+
+ // path toolbar
+ m_pActPathCombo = new KXmlEditorComboAction( i18n("Path Bar"), 0, this,
+ SLOT(slotPathSelected(const QString &)), actionCollection(), "path_combo" );
+ new KAction( i18n("Clear Path Bar"), BarIcon("locationbar_erase", 16), 0, this,
+ SLOT(slotPathClear()), actionCollection(), "path_clear" );
+ QLabel *m_locationLabel = new ToolbarLabel( i18n("Path: ") );
+ new KWidgetAction( m_locationLabel, i18n("Path: "), 0, this, 0, actionCollection(), "path_label" );
+ m_locationLabel->setBuddy( m_pActPathCombo->comboBox());
+
+ if ( ! fReadWrite )
+ {
+ setXMLFile( "kxmleditorpartBrowseUI.rc", true );
+
+ KStdAction::cut( m_pBrowserExt, SLOT(slotEditCut()), actionCollection(), "cut" );
+ KStdAction::copy( m_pBrowserExt, SLOT(slotEditCopy()), actionCollection(), "copy" );
+ KStdAction::paste( m_pBrowserExt, SLOT(slotEditPaste()), actionCollection(), "paste");
+
+ m_pCmdHistory = 0L;
+
+ m_pActVersionEncoding = 0L;
+ m_pActAttachSchema = 0L;
+ m_pActDetachSchema = 0L;
+ m_pActAttachStylesheet = 0L;
+ m_pActDetachStylesheet = 0L;
+ }
+ else
+ {
+ // document specific actions here
+ m_pActVersionEncoding = new KAction( i18n("&Version && Encoding..."), 0, 0, this, SLOT(slotActVersionEncoding()), actionCollection(), "xml_ins_spec_procins" );
+ m_pActAttachSchema = new KAction(i18n("Attach Schema..."),0,0,this,SLOT(slotActAttachSchema()), actionCollection(), "xml_attach_schema");
+ m_pActDetachSchema = new KAction(i18n("Detach Schema"),0,0,this,SLOT(slotActDetachSchema()), actionCollection(), "xml_detach_schema");
+ m_pActAttachStylesheet = new KAction(i18n("Attach Stylesheet..."),0,0,this,SLOT(slotActAttachStylesheet()), actionCollection(), "xml_attach_stylesheet");
+ m_pActDetachStylesheet = new KAction(i18n("Detach Stylesheet"),0,0,this,SLOT(slotActDetachStylesheet()), actionCollection(), "xml_detach_stylesheet");
+
+ KStdAction::print( this, SLOT(slotActPrint()), actionCollection(), "print" );
+
+ m_pActAttachSchema->setEnabled(false);
+ m_pActDetachSchema->setEnabled(false);
+ m_pActDetachStylesheet->setEnabled(false);
+
+
+ // undo & redo
+ KStdAction::undo(this, SLOT(slotActUndo()), actionCollection());
+ KStdAction::redo(this, SLOT(slotActRedo()), actionCollection());
+
+ m_pCmdHistory = new KCommandHistory(actionCollection());
+
+ m_pActEditCut = KStdAction::cut( this, SLOT(slotEditCut()), actionCollection());
+ m_pActEditCopy = KStdAction::copy( this, SLOT(slotEditCopy()), actionCollection());
+ m_pActEditPaste = KStdAction::paste( this, SLOT(slotEditPaste()), actionCollection());
+
+ // Move node Up & Down
+ m_pActXmlMoveNodeUp = new KAction( i18n("&Move Up"), "xml_move_item_up", CTRL+Key_U, this, SLOT(slotXmlMoveNodeUp()), actionCollection(), "xml_move_item_up" );
+ m_pActXmlMoveNodeDown = new KAction( i18n("Move &Down"), "xml_move_item_down", CTRL+Key_D, this, SLOT(slotXmlMoveNodeDown()), actionCollection(), "xml_move_item_down" );
+
+ // Insert actions
+ m_pActXmlElementInsert = new KAction( i18n("&Element..."), "xml_insert_element", CTRL+SHIFT+Key_E, this, SLOT(slotXmlElementInsert()), actionCollection(), "xml_ins_element" );
+ m_pActXmlAttributesAdd = new KAction( i18n("&Attribute..."), "xml_insert_attribute", CTRL+SHIFT+Key_A, this, SLOT(slotXmlAttributesAdd()), actionCollection(), "xml_add_attribute" );
+ m_pActInsertText = new KAction( i18n("&Text..."), "xml_text", CTRL+SHIFT+Key_T, this, SLOT(slotActInsertText()), actionCollection(), "insert_text" );
+ m_pActInsertCDATA = new KAction( i18n("C&DATA..."), "xml_cdata", CTRL+SHIFT+Key_D, this, SLOT(slotActInsertCDATA()), actionCollection(), "insert_cdata" );
+ m_pActInsertComment = new KAction( i18n("&Comment..."), "xml_comment", CTRL+SHIFT+Key_C, this, SLOT(slotActInsertComment()), actionCollection(), "insert_comment" );
+ m_pActXmlProcInstrInsert = new KAction( i18n("&Processing Instruction..."), "xml_insert_procins", CTRL+SHIFT+Key_P, this, SLOT(slotXmlProcInstrInsert()), actionCollection(), "xml_ins_procins" );
+
+ // Edit node properties
+ m_pActProperties = new KAction(i18n("&Properties..."),"edit",0,this,SLOT(slotActProperties()),actionCollection(),"edit_properties");
+ m_pActEditRawXml = new KAction(i18n("Edit &raw XML..."), 0, 0, this, SLOT(slotActEditRawXml()),actionCollection(),"edit_as_raw_xml");
+
+ // delete actions
+ m_pActXmlAttributeDel = new KAction( i18n("&Delete"), "editdelete", 0, this, SLOT(slotXmlAttributeDel()), actionCollection(), "xml_del_attribute" );
+ m_pActXmlAttributesDel = new KAction( i18n("Delete all Attributes..."), 0, 0, this, SLOT(slotXmlAttributesDel()), actionCollection(), "xml_del_attributes" );
+ m_pActDelete = new KAction(i18n("&Delete"),"editdelete",0,this,SLOT(slotActDelete()),actionCollection(),"edit_delete");
+
+ setXMLFile( "kxmleditorpartEditUI.rc", true );
+
+ // we are not modified since we haven't done anything yet
+ setModified(false);
+ }
+
+ //////////////////////////////
+ // CREATE WIDGETS
+ //////////////////////////////
+
+ pSplitter = new QSplitter( pParent, "KXMLEditorPart main widget (Splitter)" );
+ pSplitter->setFocusPolicy( QWidget::NoFocus );
+ pSplitter->setOpaqueResize(true);
+ setWidget( pSplitter );
+
+ // create the tree view -------------------
+ m_pViewTree = new KXE_TreeView( this, pSplitter, "KXMLEditorPart treeview" );
+
+ connect( m_pViewTree, SIGNAL(sigSelectionCleared(bool)), this, SLOT(slotSelectionCleared(bool)) );
+ connect( m_pViewTree, SIGNAL(sigSelectionChanged(const QDomElement &)), this, SLOT(slotSelectionChanged(const QDomElement &)) );
+ connect( m_pViewTree, SIGNAL(sigSelectionChanged(const QDomCharacterData &)), this, SLOT(slotSelectionChanged(const QDomCharacterData &)) );
+ connect( m_pViewTree, SIGNAL(sigSelectionChanged(const QDomProcessingInstruction &)), this, SLOT(slotSelectionChanged(const QDomProcessingInstruction &)) );
+ connect( m_pViewTree, SIGNAL(sigContextMenuRequested(const QString&,const QPoint&)), this, SLOT(slotContextMenuRequested(const QString&,const QPoint&)) );
+ connect( m_pViewTree, SIGNAL(itemRenamed(QListViewItem *)), this, SLOT(slotItemRenamedInplace(QListViewItem *)) );
+ connect( m_pViewTree, SIGNAL(sigKeyPressed(QKeyEvent* )),this,SLOT(slotTreeViewKeyPressed(QKeyEvent*)));
+
+ // create tab widget ----------------------
+ m_pTabWidget = new QTabWidget( pSplitter, "KXMLEditorPart tabwidget");
+ m_pTabWidget->setFocusPolicy( QWidget::NoFocus );
+
+ // create element view
+ m_pViewElement = new KXE_ViewElement( m_pTabWidget, instance()->config(), "KXMLEditorPart element view" );
+ m_pTabWidget->addTab( m_pViewElement, g_iconElement, i18n("Element") );
+ connect( m_pViewElement, SIGNAL(sigContextMenuRequested(const QString&,const QPoint&)), this, SLOT(slotContextMenuRequested(const QString&,const QPoint&)) );
+ connect( m_pViewElement, SIGNAL(sigAttributeNameChangedInplace(const QDomAttr&, const QString)), this, SLOT(slotAttributeNameChangedInplace(const QDomAttr&, const QString)) );
+ connect( m_pViewElement, SIGNAL(sigAttributeValueChangedInplace(const QDomAttr&, const QString)), this, SLOT(slotAttributeValueChangedInplace(const QDomAttr&, const QString)) );
+
+ // create edit widget, that display XML character data contents
+ m_pViewContents = new QTextEdit( m_pTabWidget, "KXMLEditorPart contents view" );
+ m_pTabWidget->addTab( m_pViewContents, g_iconText, i18n("Contents") );
+ m_pViewContents->setReadOnly( true );
+ m_pViewContents->setWordWrap( QTextEdit::NoWrap );
+ m_pViewContents->setTextFormat(QTextEdit::PlainText);
+
+ // create proc.instr. view
+ m_pViewProcInstr = new QTextEdit( m_pTabWidget, "KXMLEditorPart proc.instr. view" );
+ m_pTabWidget->addTab( m_pViewProcInstr, g_iconProcessingInstruction, i18n("Proc.Instruction") );
+ m_pViewProcInstr->setReadOnly( true );
+ m_pViewProcInstr->setWordWrap( QTextEdit::NoWrap );
+
+ connect( this, SIGNAL(started(KIO::Job*)), this, SLOT(started()) );
+ connect( this, SIGNAL(completed()), this, SLOT(completed()) );
+ connect( this, SIGNAL(canceled(const QString &)), this, SLOT(canceled()) );
+
+ //////////////////////////////
+ // INIT BEGIN STATE
+ //////////////////////////////
+
+ // Disable actions
+ if(m_pBrowserExt)
+ m_pBrowserExt->emit enableAction("copy", false);
+ else
+ m_pActEditCopy->setEnabled(false);
+
+ m_pActEditFindNext->setEnabled(false);
+ m_pActEditDeselect->setEnabled(false);
+ m_pActViewNodeUp->setEnabled(false);
+ m_pActViewExpNode->setEnabled(false);
+ m_pActViewColNode->setEnabled(false);
+ m_pActBookmarksToggle->setEnabled(false);
+ m_pActBookmarksPrev->setEnabled(false);
+ m_pActBookmarksNext->setEnabled(false);
+
+ if ( fReadWrite )
+ {
+ m_pActEditCut->setEnabled(false);
+ m_pActEditPaste->setEnabled(true);
+
+ m_pActXmlElementInsert->setEnabled(true);
+ m_pActXmlAttributesAdd->setEnabled(false);
+ m_pActXmlAttributesDel->setEnabled(false);
+ m_pActXmlProcInstrInsert->setEnabled(true);
+ m_pActInsertText->setEnabled(false);
+ m_pActInsertCDATA->setEnabled(false);
+ m_pActInsertComment->setEnabled(false);
+ m_pActXmlMoveNodeUp->setEnabled(false);
+ m_pActXmlMoveNodeDown->setEnabled(false);
+ m_pActDelete->setEnabled(false);
+ m_pActProperties->setEnabled(false);
+ m_pActEditRawXml->setEnabled(false);
+ }
+
+ m_pTabWidget->setTabEnabled( m_pViewElement, false );
+ m_pTabWidget->setTabEnabled( m_pViewContents, false );
+ m_pTabWidget->setTabEnabled( m_pViewProcInstr, false );
+
+ setReadWrite(fReadWrite);
+
+ // configuring splitter sizes
+ QValueList<int> list = instance()->config()->readIntListEntry(CONFIG_MAIN_SPLITTER_SIZES);
+ if (!list.isEmpty())
+ pSplitter->setSizes(list);
+
+ //////////////////////////////
+ // INIT DCOP object (if any)
+ //////////////////////////////
+ //m_pDCOPIface = NULL;
+ //m_pDCOPIface = new KXMLEditorPartIfaceReadOnly(this);
+ m_pDCOPIface = new KXMLEditorPartIfaceReadWrite(this); // temporarly to test openUrl
+
+ setDocument(pDocument);
+
+}
+
+KXMLEditorPart::~KXMLEditorPart()
+{
+ // saving splitter configuration
+ KConfig *pConfig = instance()->config();
+ pConfig->writeEntry( CONFIG_MAIN_SPLITTER_SIZES, pSplitter->sizes() );
+
+ if (m_pDCOPIface)
+ delete m_pDCOPIface;
+
+ if (m_pDlgSearch)
+ delete m_pDlgSearch;
+
+ if (m_pPrinter)
+ delete m_pPrinter;
+
+ if (document())
+ delete document();
+
+ delete m_pCmdHistory;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// KPART FUNCTIONALITY
+/////////////////////////////////////////////////////////////////////
+
+bool KXMLEditorPart::openFile()
+{
+ if( isModified() )
+ kdError() << "KXMLEditorPart::openFile the current document is modified." << endl;
+
+ document()->setURL(m_url);
+ bool bResult = document()->open(m_file);
+ updateActions();
+ return bResult;
+}
+
+bool KXMLEditorPart::saveFile()
+{
+ emit setStatusBarText( i18n("Saving file...") );
+
+ if( url().isEmpty() )
+ {
+ return slotFileSaveAs();
+ }
+
+ // delegate this operation to underlying document object
+ document()->setURL(m_url);
+ bool bRetVal = document()->save(m_file);
+
+ emit setStatusBarText( i18n("Ready.") );
+ return bRetVal;
+}
+
+void KXMLEditorPart::setModified( bool bModified )
+{
+ KParts::ReadWritePart::setModified( bModified ); // base functionality
+
+ if ( m_bAlreadyModified != bModified )
+ {
+ m_bAlreadyModified = bModified;
+
+ QString szNewCaption = m_url.prettyURL();
+ emit setWindowCaption( szNewCaption );
+ }
+
+ // get a handle on our Save action and make sure it is valid
+ KAction *pActFileSave = actionCollection()->action(KStdAction::stdName(KStdAction::Save));
+ if(!pActFileSave)
+ return;
+
+ // if so, we either enable or disable it based on the current state
+ pActFileSave->setEnabled(bModified);
+
+ // Update others actions
+ updateActions();
+}
+
+void KXMLEditorPart::setReadWrite( bool fReadWrite )
+{
+ m_pViewTree->setReadWrite(fReadWrite);
+ m_pViewElement->setReadWrite(fReadWrite);
+
+ KParts::ReadWritePart::setReadWrite( fReadWrite ); // base functionality
+}
+
+void KXMLEditorPart::started()
+{
+ kdDebug() << "KXMLEditorPart::started" << endl;
+}
+void KXMLEditorPart::completed()
+{
+ kdDebug() << "KXMLEditorPart::completed" << endl;
+}
+void KXMLEditorPart::canceled()
+{
+ kdDebug() << "KXMLEditorPart::canceled" << endl;
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// ACTION SLOTS
+/////////////////////////////////////////////////////////////////////
+
+void KXMLEditorPart::slotActPrint()
+{
+ // this slot is called whenever the File->Print menu is selected,
+ // the Print shortcut is pressed (usually CTRL+P) or the Print toolbar
+ // button is clicked
+ if (!m_pPrinter)
+ m_pPrinter = new KPrinter;
+
+ if (m_pPrinter->setup(widget()))
+ print(m_pPrinter);
+}
+
+void KXMLEditorPart::slotActProperties()
+{
+ QDomNode* pNode = m_pViewTree->getSelectedNode();
+ if (pNode)
+ {
+ if (pNode->isElement())
+ slotXmlElementEdit();
+ else if (pNode->isCharacterData())
+ slotXmlCharDataEdit();
+ else if (pNode->isProcessingInstruction())
+ slotXmlProcInstrEdit();
+ else
+ kdError() << "Unknown node selected.";
+ }
+}
+
+void KXMLEditorPart::slotActDelete()
+{
+ QDomNode* pNode = m_pViewTree->getSelectedNode();
+
+ if (!m_pViewElement->hasFocus())
+ {
+ // delete nodes selected there
+ if (pNode)
+ {
+ KCommand *pCmd = new KXEDeleteNodeCommand(document(), *pNode);
+ m_pCmdHistory->addCommand(pCmd);
+ }
+ }
+ else
+ {
+ // we can have also delete attribute selected on a element view
+ QDomAttr domAttr = m_pViewElement->getSelectedAttribute();
+ if (!domAttr.isNull())
+ {
+ QDomElement domElement = pNode->toElement();
+ QDomAttr domAttr = m_pViewElement->getSelectedAttribute();
+
+ KCommand *pCmd = new KXEDeleteAttrCommand(document(), domElement, domAttr);
+ m_pCmdHistory->addCommand(pCmd);
+ }
+ }
+}
+
+void KXMLEditorPart::slotEditCut()
+{
+ kdDebug() << "KXMLEditor " << k_funcinfo << endl;
+
+ if(! isReadWrite())
+ {
+ kdError() << "KXMLEditorPart::slotEditCut called in readonly mode." << endl;
+ return;
+ }
+
+ QDomNode * pNode = m_pViewTree->getSelectedNode();
+
+ if(pNode)
+ { // copy to clipboard
+ slotEditCopy();
+
+ // and cut it
+ KCommand *pCmd = new KXECutCommand(document(), *pNode);
+ m_pCmdHistory->addCommand(pCmd);
+ }
+}
+
+void KXMLEditorPart::slotEditCopy()
+{
+ kdDebug() << "KXMLEditor " << k_funcinfo << endl;
+
+ QDomNode * pNode = m_pViewTree->getSelectedNode();
+
+ if(pNode)
+ {
+ QTextDrag *pDrag = copyNode(m_pViewTree->getSelectedNode());
+ if(pDrag)
+ QApplication::clipboard()->setData(pDrag);
+ }
+ else
+ kdError() << "KXMLEditorPart::slotEditCopy no element selected." << endl;
+}
+
+void KXMLEditorPart::slotEditPaste()
+{
+ kdDebug() << "KXMLEditor " << k_funcinfo << endl;
+
+ if(!isReadWrite())
+ {
+ kdError() << "KXMLEditorPart::slotEditPaste called in readonly mode." << endl;
+ return;
+ }
+
+ if (document()->documentElement().isNull())
+ {
+ pasteNode(0, QApplication::clipboard()->data());
+ }
+ else
+ {
+ pasteNode(m_pViewTree->getSelectedNode(), QApplication::clipboard()->data());
+ }
+}
+
+void KXMLEditorPart::slotEditFind()
+{
+ emit setStatusBarText( i18n("Search in XML tree ...") );
+
+ if ( ! m_pDlgSearch )
+ {
+ m_pDlgSearch = new KXESearchDialog( widget(), "search dialog", true );
+ }
+
+ if ( m_pDlgSearch->exec() == KXESearchDialog::Accepted )
+ slotEditFindNext();
+
+ m_pActEditFindNext->setEnabled(true);
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotEditFindNext()
+{
+ emit setStatusBarText( i18n("Search in XML tree ...") );
+
+ if ( ! m_pDlgSearch )
+ {
+ kdDebug() << "KXMLEditorPart::slotEditFindNext implementation error - no search dialog" << endl;
+ emit setStatusBarText( i18n("Ready.") );
+ return;
+ }
+
+ // get node to start with (either the next node of the item selected at the tree view or documents root node)
+ QDomNode node = ( (m_pViewTree->getSelectedNode()) && (! m_pViewTree->getSelectedNode()->isNull()) ) ? domTool_nextNode(* m_pViewTree->getSelectedNode()) : document()->documentElement();
+
+ // start testing til the last node
+ while( ! node.isNull() )
+ {
+ if ( domTool_match( node, m_pDlgSearch ) )
+ {
+ m_pViewTree->selectNode(node);
+ emit setStatusBarText( i18n("Ready.") );
+ return;
+ }
+
+ node = domTool_nextNode(node);
+ }
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotXmlElementInsert()
+{
+ if ( ! isReadWrite() )
+ {
+ kdError() << "KXMLEditorPart::slotXmlElementInsert called in readonly mode." << endl;
+ return;
+ }
+
+ emit setStatusBarText( i18n("Inserting XML element into document...") );
+
+ KXEElementDialog dlg( widget(), "XML element dialog" );
+
+ if ( document()->documentElement().isNull() ) // the document doesn't
+ { // have a root element yet
+ if ( dlg.exec( false, true, false ) == QDialog::Accepted )
+ {
+ KCommand *pCmd = new KXEElementCommand(document(), document(), dlg.nsURI(), dlg.prefix(), dlg.name());
+ m_pCmdHistory->addCommand(pCmd);
+ }
+ }
+ else // the document seems to
+ { // have a root element
+ QDomNode * pParentNode = m_pViewTree->getSelectedNode();
+
+ if ( (pParentNode) && (pParentNode->isElement()) )
+ {
+ QDomElement domParentElement = pParentNode->toElement();
+
+ if ( dlg.exec( false, false, false ) == QDialog::Accepted )
+ {
+ KCommand *pCmd = new KXEElementCommand(document(), domParentElement, dlg.nsURI(), dlg.prefix(), dlg.name(), dlg.atTop());
+ m_pCmdHistory->addCommand(pCmd);
+ }
+ }
+ else
+ kdError() << "KXMLEditorPart::slotXmlElementInsert no element selected." << endl;
+ }
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotXmlElementEdit()
+{
+ if ( ! isReadWrite() )
+ {
+ kdError() << "KXMLEditorPart::slotXmlElementEdit called in readonly mode." << endl;
+ return;
+ }
+
+ QDomNode * pNode = m_pViewTree->getSelectedNode();
+ if ( (!pNode) || (!pNode->isElement()) )
+ {
+ kdError() << "KXMLEditorPart::slotXmlElementEdit no node selected or selected node is no XML element." << endl;
+ return;
+ }
+
+ emit setStatusBarText( i18n("Editing XML element...") );
+
+ QDomElement domElement = pNode->toElement();
+
+ KXEElementDialog dlg( widget(), "XML element dialog" );
+
+ dlg.setPrefix(domElement.prefix());
+ dlg.setName(domElement.tagName());
+ if(!domElement.namespaceURI().isNull())
+ dlg.setNsURI(domElement.namespaceURI() );
+
+ if ( dlg.exec( true, false, domElement.namespaceURI().isNull() ) == QDialog::Accepted )
+ {
+ KCommand *pCmd = new KXEEditElementCommand(document(), domElement, dlg.prefix(), dlg.name());
+ m_pCmdHistory->addCommand(pCmd);
+ }
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotActEditRawXml()
+{
+ if ( ! isReadWrite() )
+ {
+ kdError() << "KXMLEditorPart::slotActEditRawXml called in readonly mode." << endl;
+ return;
+ }
+
+ QDomNode * pNode = m_pViewTree->getSelectedNode();
+ if ( (!pNode) || (!pNode->isElement()) )
+ {
+ kdError() << "KXMLEditorPart::slotActEditRawXml no node selected or selected node is no XML element." << endl;
+ return;
+ }
+
+ emit setStatusBarText( i18n("Editing raw XML...") );
+
+ QDomElement domElement = pNode->toElement();
+
+ QString strXML;
+
+ QTextStream streamXML(&strXML, IO_WriteOnly);
+ int iIndent = KXMLEditorFactory::configuration()->textview()->indentSteps();
+ pNode->save(streamXML, iIndent);
+
+ KXETextEditorDialog dlg(0, "Text dialog");
+ dlg.setEditorText(strXML);
+ if((dlg.exec() == QDialog::Accepted) && (strXML != dlg.editorText()))
+ {
+ QString strXML = "<root>" + dlg.editorText() + "</root>";
+
+ // create XML documemt from text
+ QString strErrorMsg;
+ int iErrorLine, iErrorColumn;
+ QDomDocument doc;
+
+ if(!doc.setContent(strXML, true, &strErrorMsg, &iErrorLine, &iErrorColumn) )
+ {
+ kdDebug() << "KXMLEditorPart::slotActEditRawXml: Failed parsing the file." << endl;
+
+ KMessageBox::error(m_pViewTree,
+ i18n("%1 in line %2, column %3").arg(strErrorMsg).arg(iErrorLine).arg(iErrorColumn),
+ i18n("Parsing error !"));
+
+ return;
+ }
+
+ // check if root item already exists
+ if(!doc.firstChild().firstChild().isElement())
+ {
+ KMessageBox::sorry(m_pViewTree, i18n("You are changed root element to another node type, while editing !"));
+ return;
+ }
+
+ QDomElement domNewElement = doc.firstChild().firstChild().toElement();
+ KCommand *pCmd = new KXEEditRawXmlCommand(document(), domElement, domNewElement);
+ m_pCmdHistory->addCommand(pCmd);
+ }
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotXmlAttributesAdd()
+{
+ if ( ! isReadWrite() )
+ {
+ kdError() << "KXMLEditorPart::slotXmlAttributesAdd called in readonly mode." << endl;
+ return;
+ }
+
+ QDomNode * pNode = m_pViewTree->getSelectedNode();
+ if ( (!pNode) || (!pNode->isElement()) )
+ {
+ kdError() << "KXMLEditorPart::slotXmlAttributesAdd no node selected or selected node is no XML element." << endl;
+ return;
+ }
+
+ emit setStatusBarText( i18n("Add attribute...") );
+
+ KXEAttributeDialog dlg( widget(), "attribute dialog" );
+
+ QDomElement domOwnerElement = pNode->toElement();
+ if ( dlg.exec( ) == QDialog::Accepted )
+ {
+ KCommand *pCmd = new KXEAttributeCommand(document(), domOwnerElement, dlg.attributeNamespace(), dlg.QName(), dlg.Value());
+ m_pCmdHistory->addCommand(pCmd);
+ }
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotXmlAttributesDel()
+{
+ if ( ! isReadWrite() )
+ {
+ kdError() << "KXMLEditorPart::slotXmlAttributesDel called in readonly mode." << endl;
+ return;
+ }
+
+ QDomNode * pNode = m_pViewTree->getSelectedNode();
+ if ( (!pNode) || (!pNode->isElement()) )
+ {
+ kdError() << "KXMLEditorPart::slotXmlAttributesDel no node selected or selected node is no XML element." << endl;
+ return;
+ }
+
+ if(KMessageBox::questionYesNo(0, i18n("Remove all attributes from selected node ?")) != KMessageBox::Yes)
+ return;
+
+ emit setStatusBarText( i18n("Delete all attributes...") );
+
+ QDomElement domOwnerElement = pNode->toElement();
+
+ KCommand *pCmd = new KXEDeleteAllAttribCommand(document(), domOwnerElement);
+ m_pCmdHistory->addCommand(pCmd);
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+
+void KXMLEditorPart::slotXmlAttributeDel()
+{
+ if ( ! isReadWrite() )
+ {
+ kdError() << "KXMLEditorPart::slotXmlAttributeDel called in readonly mode." << endl;
+
+ return;
+ }
+
+ QDomNode * pNode = m_pViewTree->getSelectedNode();
+ if ( (!pNode) || (!pNode->isElement()) )
+ {
+ kdError() << "KXMLEditorPart::slotXmlAttributeDel no node selected or selected node is no XML element." << endl;
+ return;
+ }
+
+ emit setStatusBarText( i18n("Delete attribute...") );
+
+ QDomElement domElement = pNode->toElement();
+ QDomAttr domAttr = m_pViewElement->getSelectedAttribute();
+
+ KCommand *pCmd = new KXEDeleteAttrCommand(document(), domElement, domAttr);
+ m_pCmdHistory->addCommand(pCmd);
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotXmlProcInstrInsert()
+{
+ if ( ! isReadWrite() )
+ {
+ kdError() << "KXMLEditorPart::slotXmlProcInstrInsert called in readonly mode." << endl;
+ return;
+ }
+
+ KXEProcInstrDialog dlg( widget(), "proc. instr. dialog" );
+
+ QDomNode * pParentNode = m_pViewTree->getSelectedNode();
+ if ( (pParentNode) && (!pParentNode->isElement()) )
+ {
+ kdError() << k_funcinfo << " The selected node is no XML element." << endl;
+ return;
+ }
+ else
+ {
+ if ( ! pParentNode ) // no node selected -> the new node should be a direct child of the document
+ {
+ if ( dlg.exec( false, true ) == QDialog::Accepted )
+ {
+ KCommand *pCmd = new KXEProcInstrCommand(document(), document(), dlg.atTop(), dlg.target(), dlg.data());
+ m_pCmdHistory->addCommand(pCmd);
+ }
+ }
+ else
+ {
+ if ( dlg.exec( false, false ) == QDialog::Accepted )
+ {
+ QDomElement domParentElement = pParentNode->toElement();
+
+ KCommand *pCmd = new KXEProcInstrCommand(document(), domParentElement, dlg.atTop(), dlg.target(), dlg.data());
+ m_pCmdHistory->addCommand(pCmd);
+ }
+ }
+ }
+
+ emit setStatusBarText( i18n("Inserting processing instruction into document...") );
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotXmlProcInstrEdit()
+{
+ if ( ! isReadWrite() )
+ {
+ kdError() << "KXMLEditorPart::slotXmlProcInstrEdit called in readonly mode." << endl;
+ return;
+ }
+
+ QDomNode * pNode = m_pViewTree->getSelectedNode();
+ if ( (!pNode) || (!pNode->isProcessingInstruction()) )
+ {
+ kdError() << "KXMLEditorPart::slotXmlProcInstrEdit no node selected or selected node is no processing instruction." << endl;
+ return;
+ }
+
+ emit setStatusBarText( i18n("Editing processing instruction...") );
+
+ QDomProcessingInstruction domProcInstr = pNode->toProcessingInstruction();
+
+ // We have two different kinds of processing instructions:
+ // - a special one - defining the documents XML version and encoding
+ // - others
+ // and both cases require different dialogs.
+ if( domProcInstr.target() == "xml" ) // 1st case (special proc.instr.)
+ document()->actVersionEncoding();
+ else // 2nd case (others)
+ {
+ KXEProcInstrDialog dlg( widget(), "proc. instr. dialog" );
+
+ dlg.setTarget(domProcInstr.target());
+ dlg.setData(domProcInstr.data());
+
+ if ( dlg.exec( true, false ) == QDialog::Accepted )
+ {
+ KCommand *pCmd = new KXEEditProcInstrCommand(document(), domProcInstr, dlg.data());
+ m_pCmdHistory->addCommand(pCmd);
+ }
+ }
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotActInsertText()
+{
+ if ( ! isReadWrite() )
+ {
+ kdError() << "KXMLEditorPart::slotActInsertText called in readonly mode." << endl;
+ return;
+ }
+
+ QDomNode * pNode = m_pViewTree->getSelectedNode();
+ if ( (!pNode) || (!pNode->isElement()) )
+ {
+ kdError() << "KXMLEditorPart::slotActInsertText no element selected." << endl;
+ return;
+ }
+
+ emit setStatusBarText( i18n("Inserting text into document...") );
+
+ KXECharDataDialog dlg( widget());
+ dlg.setCaption(i18n("Insert text"));
+
+ QDomElement domParentElement = pNode->toElement();
+
+ if ( dlg.exec( false ) == QDialog::Accepted )
+ {
+ KCommand *pCmd = new KXECharDataCommand(document(), domParentElement, dlg.atTop(), CharDataTextNode, dlg.contents());
+ m_pCmdHistory->addCommand(pCmd);
+ }
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotActInsertCDATA()
+{
+ if ( ! isReadWrite() )
+ {
+ kdError() << "KXMLEditorPart::slotActInsertCDATA called in readonly mode." << endl;
+ return;
+ }
+
+ QDomNode * pNode = m_pViewTree->getSelectedNode();
+ if ( (!pNode) || (!pNode->isElement()) )
+ {
+ kdError() << "KXMLEditorPart::slotActInsertCDATA no element selected." << endl;
+ return;
+ }
+
+ emit setStatusBarText( i18n("Inserting CDATA into document...") );
+
+ KXECharDataDialog dlg( widget());
+ dlg.setCaption(i18n("Insert CDATA"));
+
+ QDomElement domParentElement = pNode->toElement();
+
+ if ( dlg.exec( false ) == QDialog::Accepted )
+ {
+ KCommand *pCmd = new KXECharDataCommand(document(), domParentElement, dlg.atTop(), CharDataCDATASection, dlg.contents());
+ m_pCmdHistory->addCommand(pCmd);
+ }
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotActInsertComment()
+{
+ if ( ! isReadWrite() )
+ {
+ kdError() << "KXMLEditorPart::slotActInsertComment called in readonly mode." << endl;
+ return;
+ }
+
+ QDomNode * pNode = m_pViewTree->getSelectedNode();
+ if ( (!pNode) || (!pNode->isElement()) )
+ {
+ kdError() << "KXMLEditorPart::slotActInsertComment no element selected." << endl;
+ return;
+ }
+
+ emit setStatusBarText( i18n("Inserting comment into document...") );
+
+ KXECharDataDialog dlg( widget());
+ dlg.setCaption(i18n("Insert comment"));
+
+ QDomElement domParentElement = pNode->toElement();
+
+ if ( dlg.exec( false ) == QDialog::Accepted )
+ {
+ KCommand *pCmd = new KXECharDataCommand(document(), domParentElement, dlg.atTop(), CharDataComment, dlg.contents());
+ m_pCmdHistory->addCommand(pCmd);
+ }
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+
+
+void KXMLEditorPart::slotXmlCharDataEdit()
+{
+ if ( ! isReadWrite() )
+ {
+ kdError() << "KXMLEditorPart::slotXmlCharDataEdit called in readonly mode." << endl;
+ return;
+ }
+
+ QDomNode * pNode = m_pViewTree->getSelectedNode();
+ if ( (!pNode) || (!pNode->isCharacterData()) )
+ {
+ kdError() << "KXMLEditorPart::slotXmlCharDataEdit no node selected or selected node is no character data." << endl;
+ return;
+ }
+
+ emit setStatusBarText( i18n("Editing character data...") );
+
+ QDomCharacterData domCharData = pNode->toCharacterData();
+
+ KXECharDataDialog dlg( widget() );
+
+ CharDataKind eCharDataKind;
+ if(domCharData.isText())
+ eCharDataKind = CharDataTextNode;
+ else
+ {
+ if(domCharData.isCDATASection())
+ eCharDataKind = CharDataCDATASection;
+ else
+ eCharDataKind = CharDataComment;
+ }
+
+ // dlg.setCharDataKind(eCharDataKind);
+ dlg.setContents(domCharData.data());
+
+ if ( dlg.exec( true ) == QDialog::Accepted )
+ {
+ KCommand *pCmd = new KXEEditCharDataCommand(document(), domCharData, dlg.contents());
+ m_pCmdHistory->addCommand(pCmd);
+ }
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotXmlMoveNodeUp()
+{
+ if ( ! isReadWrite() )
+ {
+ kdError() << "KXMLEditorPart::slotXmlMoveNodeUp called in readonly mode." << endl;
+ return;
+ }
+
+ QDomNode * pNode = m_pViewTree->getSelectedNode();
+ if ( ! pNode )
+ {
+ kdError() << "KXMLEditorPart::slotXmlMoveNodeUp no node selected." << endl;
+ return;
+ }
+
+ emit setStatusBarText( i18n("Moving node up...") );
+
+ KCommand *pCmd = new KXEUpCommand(document(), * pNode);
+ m_pCmdHistory->addCommand(pCmd);
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotXmlMoveNodeDown()
+{
+ if ( ! isReadWrite() )
+ {
+ kdError() << "KXMLEditorPart::slotXmlMoveNodeDown called in readonly mode." << endl;
+ return;
+ }
+
+ QDomNode * pNode = m_pViewTree->getSelectedNode();
+ if ( ! pNode )
+ {
+ kdError() << "KXMLEditorPart::slotXmlMoveNodeDown no node selected." << endl;
+ return;
+ }
+
+ emit setStatusBarText( i18n("Moving node down...") );
+
+ KCommand *pCmd = new KXEDownCommand(document(), * pNode);
+ m_pCmdHistory->addCommand(pCmd);
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotBookmarksToggle()
+{
+ m_pViewTree->bookmarksToggle();
+ m_pActBookmarksPrev->setEnabled(m_pViewTree->containsBookmarkedItems());
+ m_pActBookmarksNext->setEnabled(m_pViewTree->containsBookmarkedItems());
+}
+
+void KXMLEditorPart::slotConfigure()
+{
+ emit setStatusBarText( i18n("Configure KXML Editor ...") );
+
+ KXMLEditorFactory::configuration()->showDialog();
+
+ emit setStatusBarText( i18n("Ready.") );
+}
+
+void KXMLEditorPart::slotPathSelected( )
+{
+
+}
+
+void KXMLEditorPart::slotPathSelected( const QString & strPath )
+{
+ QDomNode node = domTool_matchingNode( document()->toDocument(), strPath );
+ if(node.isNull())
+ { // node don't exists, remove item from combo
+ m_pActPathCombo->removeItem(strPath);
+ m_pActPathCombo->slotClearEdit();
+ return;
+ }
+
+ if(!m_pViewTree->selectNode(node))
+ { // node not found, remove item from combo
+ m_pActPathCombo->removeItem(strPath);
+ m_pActPathCombo->slotClearEdit();
+ }
+}
+
+void KXMLEditorPart::slotPathClear()
+{
+ slotEditDeselect();
+ m_pActPathCombo->slotFocusEdit();
+}
+
+void KXMLEditorPart::slotItemRenamedInplace( QListViewItem * pItem )
+{
+ KXE_TreeViewItem * pXMLItem = static_cast <KXE_TreeViewItem*> (pItem);
+
+ if ( ! pXMLItem->xmlNode()->isElement() ) // check, if it really represents an XML element
+ {
+ kdFatal() << "KXMLEditorPart " << k_funcinfo << " the given item doesn't represent an XML element." << endl;
+ return;
+ }
+
+ QDomElement domElement = pXMLItem->xmlNode()->toElement();
+
+ if ( domElement.nodeName() != pItem->text(0) ) // if really something was changed
+ {
+ // else the element is "namespaced"
+ int nPosColon = pItem->text(0).find(':');
+
+ if ( nPosColon == -1 ) // if no namespace prefix was entered,
+ {
+ // check name
+ QString strMessage = KXEElementDialog::checkName(pItem->text(0));
+ if(strMessage.length() > 0)
+ {
+ // restore old name
+ m_pViewTree->updateNodeChanged(domElement);
+ KMessageBox::sorry(m_pViewTree, strMessage);
+ return;
+ }
+
+ // clear the elements namespace prefix
+ // and set the entered text as its tag name
+ KCommand *pCmd = new KXEEditElementCommand(document(), domElement, QString::null, pItem->text(0));
+ m_pCmdHistory->addCommand(pCmd);
+ }
+ else
+ {
+ // otherwise split up the entered text by the first colon and
+ QString strPrefix(pItem->text(0).left(nPosColon));
+ QString strName(pItem->text(0).right( pItem->text(0).length() - nPosColon - 1 ));
+
+ // check name
+ QString strMessage = KXEElementDialog::checkName(strName);
+ if(strMessage.length() > 0)
+ {
+ // restore old name
+ m_pViewTree->updateNodeChanged(domElement);
+ KMessageBox::sorry(m_pViewTree, strMessage);
+ return;
+ }
+
+ KCommand *pCmd = new KXEEditElementCommand(
+ document(),
+ domElement,
+ strPrefix,
+ strName
+ );
+
+ m_pCmdHistory->addCommand(pCmd);
+ }
+
+
+ if ( m_pViewTree->selectedItem() == pItem ) // and if the item is still selected
+ {
+ m_pActPathCombo->insertItem( domTool_getIconForNodeType(pXMLItem->xmlNode()->nodeType(), false),
+ domTool_getPath(*pXMLItem->xmlNode()) ); // the path combo
+ }
+ }
+}
+
+void KXMLEditorPart::slotAttributeNameChangedInplace( const QDomAttr & domAttr, const QString strNewName )
+{
+ if ( *m_pViewTree->getSelectedNode() == domAttr.ownerElement() ) // if the corresponding element
+ { // is still selected
+ KCommand *pCmd = new KXEEditAttrNameCommand(document(), domAttr, strNewName);
+ m_pCmdHistory->addCommand(pCmd);
+ }
+}
+
+void KXMLEditorPart::slotAttributeValueChangedInplace( const QDomAttr & domAttr, const QString strNewValue )
+{
+ if ( *m_pViewTree->getSelectedNode() == domAttr.ownerElement() ) // if the corresponding element
+ { // is still selected
+ KCommand *pCmd = new KXEEditAttrValueCommand(document(), domAttr, strNewValue);
+ m_pCmdHistory->addCommand(pCmd);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////
+// MISC FUNCTIONS
+/////////////////////////////////////////////////////////////////////
+
+/** Copy XML node into clipboard */
+QTextDrag * KXMLEditorPart::copyNode(QDomNode * pNode)
+{
+ QTextDrag *pDrag = 0;
+ QString strXML;
+
+ QTextStream streamXML(&strXML, IO_WriteOnly);
+ int iIndent = KXMLEditorFactory::configuration()->textview()->indentSteps();
+ pNode->save(streamXML, iIndent);
+ pDrag = new QTextDrag(strXML, m_pViewTree);
+
+ /*if(pNode->isElement())
+ pDrag->setSubtype(KXE_TreeViewItem::m_strSubtypeXML);
+
+ if(pNode->isProcessingInstruction())
+ pDrag->setSubtype(KXE_TreeViewItem::m_strSubtypeXML_procins);
+
+ if(pNode->isText())
+ pDrag->setSubtype(KXE_TreeViewItem::m_strSubtypeXML_text);
+
+ if(pNode->isCDATASection())
+ pDrag->setSubtype(KXE_TreeViewItem::m_strSubtypeXML_cdata);
+
+ if(pNode->isComment())
+ pDrag->setSubtype(KXE_TreeViewItem::m_strSubtypeXML_comment); */
+
+ return pDrag;
+}
+
+//-----------------------------------------------------------------------------
+//
+// Paste XML node from clipboard into document
+//
+// pTargetNode - target node
+// data - data to pasted
+//
+//-----------------------------------------------------------------------------
+bool KXMLEditorPart::pasteNode(QDomNode * pTargetNode, QMimeSource *data)
+{
+ QString strText;
+
+ // Drop XML Processing Instruction
+ if(QTextDrag::decode(data, strText))
+ { if(strText.find("<?xml ") == 0)
+ {
+ KMessageBox::sorry(0, i18n("This processing instruction cannot be pasted here !"));
+ return false;
+ }
+
+ //---
+
+ QString strXML = "<root>" + strText + "</root>";
+
+ // Paste clipboard contents as XML element
+ QString strErrorMsg;
+ int iErrorLine, iErrorColumn;
+ QDomDocument doc;
+
+ if(!doc.setContent(strXML, true, &strErrorMsg, &iErrorLine, &iErrorColumn) )
+ { kdDebug() << "KXMLEditorPart::pasteNode: Failed parsing the file." << endl;
+
+ KMessageBox::error(m_pViewTree,
+ i18n("%1 in line %2, column %3").arg(strErrorMsg).arg(iErrorLine).arg(iErrorColumn),
+ i18n("Parsing error !"));
+
+ return false;
+ }
+
+ // Import parsed document to main document
+ if(doc.hasChildNodes())
+ { if(pTargetNode == 0)
+ { // check if root item already exists
+ if(!document()->documentElement().isNull() /*(this->documentElement().isElement())*/ && (doc.firstChild().firstChild().isElement()) )
+ { KMessageBox::sorry(m_pViewTree, i18n("Root element already exists !"));
+ return false;
+ }
+
+ if(doc.documentElement().firstChild().isElement() == false)
+ {
+ KMessageBox::sorry(m_pViewTree, i18n("Node pasted to document must be element !"));
+ return false;
+ }
+
+ // Append it as root node
+ QDomElement newNode = doc.documentElement().firstChild().cloneNode(true).toElement();
+
+ KCommand *pCmd = new KXEPasteToDocumentCommand(document(), document(), newNode);
+ m_pCmdHistory->addCommand(pCmd);
+ }
+ else
+ { QDomNode sourceNode = doc.firstChild().firstChild().cloneNode(true);
+
+ /*
+ L.V.
+
+ TESTING CODE FOR [ 925668 ] Attribute values in a copied element can't be changed.
+
+ if(sourceNode.isElement())
+ {
+ QDomElement domSourceElement = sourceNode.toElement();
+
+ QDomNamedNodeMap list = domSourceElement.attributes();
+ unsigned int iLength = list.length();
+
+
+ for ( unsigned int iRow = 0; iRow < iLength; iRow++ )
+ {
+ QDomAttr a = list.item(iRow).toAttr();
+
+ QDomElement domOwnerElement = a.ownerElement();
+ if(domOwnerElement.isNull())
+ KMessageBox::sorry(m_pViewTree, i18n("Cloned owner is null !"));
+ }*/
+ //---
+
+ if(pTargetNode->isElement())
+ {
+ QDomElement domTargetElement = pTargetNode->toElement();
+ KCommand *pCmd = new KXEPasteToElementCommand(document(), domTargetElement, sourceNode);
+ m_pCmdHistory->addCommand(pCmd);
+ return true;
+ }
+
+ if(pTargetNode->isProcessingInstruction() && sourceNode.isProcessingInstruction())
+ { // Replace contents of selected node
+ QDomProcessingInstruction domTargetProcInstr = pTargetNode->toProcessingInstruction();
+ QDomProcessingInstruction domSourceProcInstr = sourceNode.toProcessingInstruction();
+
+ KCommand *pCmd = new KXEPasteToProcInstrCommand(document(), domTargetProcInstr, domSourceProcInstr);
+ m_pCmdHistory->addCommand(pCmd);
+ return true;
+ }
+
+ if(pTargetNode->isCharacterData() && sourceNode.isCharacterData())
+ { // Replace contents of selected node
+ QDomCharacterData domTargetCharData = pTargetNode->toCharacterData();
+ QDomCharacterData domSourceCharData = sourceNode.toCharacterData();
+
+ KCommand *pCmd = new KXEPasteToCharDataCommand(document(), domTargetCharData, domSourceCharData);
+ m_pCmdHistory->addCommand(pCmd);
+ return true;
+ }
+
+ KMessageBox::sorry(m_pViewTree, i18n("Incompactible node types for drag&drop !"));
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+//
+// Drag & Drop MOVE operation
+//
+// domTrgetElement - target element
+// domSourceNode - source node
+//
+//-----------------------------------------------------------------------------
+bool KXMLEditorPart::dropMoveNode(QDomElement & domTargetElement, QDomNode & domSourceNode)
+{
+ KCommand *pCmd = new KXEDragDropMoveCommand(document(), domTargetElement, domSourceNode);
+ m_pCmdHistory->addCommand(pCmd);
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////
+// PRINTING
+/////////////////////////////////////////////////////////////////////
+
+// these defines should rather stay fixed and not configurable by the user.
+#define headerMargin 30;
+#define footerMargin 50;
+#define m_printLinespace 0.4 // percent of font size used to make line indent
+
+int headerHeight, footerHeight; // used in few functions, nevertheless temporary...
+
+void KXMLEditorPart::print(KPrinter* pPrinter)
+{
+ // setup the printer. with Qt, you always "print" to a
+ // QPainter.. whether the output medium is a pixmap, a screen, or paper
+ QPainter p;
+ QPainter *painter = &p;
+ QFont font( KXMLEditorFactory::configuration()->print()->fontFamily(),
+ KXMLEditorFactory::configuration()->print()->fontSize() );
+
+ QPaintDeviceMetrics metrics((QPrinter*)pPrinter); // determining
+ int width = metrics.width(); // width and
+ int height = metrics.height(); // height of the page
+
+ footerHeight = font.pointSize()+footerMargin;
+ headerHeight = font.pointSize()+headerMargin;
+
+ int pageNumber = 0;
+
+ painter->begin(pPrinter); // start print job
+ painter->setFont(font); // set up fonts for printout
+ printHeader(painter,pageNumber,0,width); // draw header on a first page
+ while (printPage (painter,pageNumber,
+ headerHeight,width,
+ height-headerHeight-footerHeight)) // and start printing loop
+ {
+ printFooter(painter, pageNumber, height-footerHeight,width); // draw footer at the end of that page
+ pageNumber++;
+ pPrinter->newPage();
+ printHeader(painter,pageNumber,0,width); // draw header on new page
+ }
+ printFooter(painter,pageNumber,height-footerHeight,width); // draw footer on last page
+ painter->end(); // finish print job
+}
+
+void KXMLEditorPart::printHeader(QPainter* painter,int pageNumber, int ypos, int width)
+{
+ pageNumber = pageNumber;
+ if ( KXMLEditorFactory::configuration()->print()->hasHeader() )
+ {
+ painter->drawText(0,ypos,m_url.prettyURL());
+ painter->drawLine(0,ypos,width,ypos);
+ }
+}
+
+bool KXMLEditorPart::printPage(QPainter* painter,int pageNumber, int top, int width, int height)
+{
+ width = width;
+ if (pageNumber==0)
+ {
+ // initialization of working variables is done when
+ // first page is about to be printed
+ m_printLineNumber = 0;
+ m_printLines = QStringList::split( "\n", document()->toString(KXMLEditorFactory::configuration()->print()->indentSteps()) );
+ }
+ int lineHeight = (int)(painter->font().pointSize()*(1+m_printLinespace));
+ int y = top;
+ while ( y <= height )
+ {
+ painter->drawText(0,y,m_printLines[m_printLineNumber]);
+ if (m_printLineNumber++==m_printLines.size())
+ return false; // no more pages to print
+ y += lineHeight;
+ }
+ return true; // there are still some pages to print
+}
+
+void KXMLEditorPart::printFooter(QPainter* painter,int pageNumber, int ypos, int width)
+{
+ if ( KXMLEditorFactory::configuration()->print()->hasFooter() )
+ {
+ int fh = painter->font().pointSize();
+ painter->drawText(0,ypos,i18n("Page %1").arg(pageNumber+1));
+ painter->drawLine(0,ypos-fh,width,ypos-fh);
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// OTHER SLOTS
+/////////////////////////////////////////////////////////////////////
+
+void KXMLEditorPart::slotTreeViewKeyPressed(QKeyEvent *e)
+{
+ // few keypresses are recognized and proper actions
+ // are executed.
+ switch (e->key())
+ {
+ case Qt::Key_Delete : slotActDelete(); break;
+ case Qt::Key_Return :
+ case Qt::Key_Enter : slotActProperties(); break;
+ }
+}
+
+void KXMLEditorPart::slotSelectionCleared(bool bRootElementExists)
+{
+ // Enable/Disable actions
+ if(m_pBrowserExt)
+ m_pBrowserExt->emit enableAction( "copy", false );
+ else
+ m_pActEditCopy->setEnabled(false);
+
+ m_pActEditDeselect->setEnabled(false);
+ m_pActViewNodeUp->setEnabled(false);
+ m_pActViewExpNode->setEnabled(false);
+ m_pActViewColNode->setEnabled(false);
+ m_pActBookmarksToggle->setEnabled(false);
+
+ if ( isReadWrite() )
+ {
+ m_pActEditCut->setEnabled(false );
+ m_pActEditPaste->setEnabled(true );
+
+ m_pActXmlElementInsert->setEnabled(!bRootElementExists);
+ m_pActXmlAttributesAdd->setEnabled(false);
+ m_pActXmlAttributesDel->setEnabled(false);
+ m_pActXmlProcInstrInsert->setEnabled(true);
+ m_pActInsertText->setEnabled(false);
+ m_pActInsertCDATA->setEnabled(false);
+ m_pActInsertComment->setEnabled(false);
+ m_pActXmlMoveNodeUp->setEnabled(false);
+ m_pActXmlMoveNodeDown->setEnabled(false);
+ m_pActDelete->setEnabled(false);
+ m_pActProperties->setEnabled(false);
+ m_pActEditRawXml->setEnabled(false);
+ }
+
+ m_pActPathCombo->slotClearEdit();
+
+ // change views
+ m_pViewContents->clear();
+
+ m_pTabWidget->setTabEnabled( m_pViewElement, false );
+ m_pTabWidget->setTabEnabled( m_pViewContents, false );
+ m_pTabWidget->setTabEnabled( m_pViewProcInstr, false );
+
+ m_pTabWidget->showPage( m_pViewContents );
+
+ // change path combo
+ m_pActPathCombo->slotClearEdit();
+}
+
+void KXMLEditorPart::slotSelectionChanged( const QDomElement & selectedNode)
+{
+ // Enable/Disable actions
+ if(m_pBrowserExt)
+ m_pBrowserExt->emit enableAction( "copy", true );
+ else
+ m_pActEditCopy->setEnabled(true);
+
+ m_pActEditDeselect->setEnabled(true);
+ m_pActViewNodeUp->setEnabled( ! selectedNode.parentNode().isNull() ); // disable if it's a root item
+ m_pActViewExpNode->setEnabled( ! selectedNode.firstChild().isNull() ); // no childs -> disable
+ m_pActViewColNode->setEnabled( ! selectedNode.firstChild().isNull() ); // no childs -> disable
+ m_pActBookmarksToggle->setEnabled(true);
+
+ if ( isReadWrite() )
+ {
+ m_pActEditCut->setEnabled(true);
+ m_pActEditPaste->setEnabled(true);
+
+ m_pActXmlElementInsert->setEnabled(true);
+ m_pActXmlAttributesAdd->setEnabled(true);
+ m_pActXmlAttributesDel->setEnabled( (selectedNode.attributes().count() != 0) );
+ m_pActXmlProcInstrInsert->setEnabled(true);
+// m_pActXmlCharDataInsert->setEnabled(true);
+ m_pActInsertText->setEnabled(true);
+ m_pActInsertCDATA->setEnabled(true);
+ m_pActInsertComment->setEnabled(true);
+ m_pActDelete->setEnabled(true);
+ m_pActProperties->setEnabled(true);
+ m_pActEditRawXml->setEnabled(true);
+
+ if ( selectedNode.parentNode().isDocument() )
+ {
+ m_pActXmlMoveNodeUp->setEnabled(false);
+ m_pActXmlMoveNodeDown->setEnabled(false);
+ }
+ else
+ {
+ m_pActXmlMoveNodeUp->setEnabled( ! selectedNode.previousSibling().isNull() );
+ m_pActXmlMoveNodeDown->setEnabled( ! selectedNode.nextSibling().isNull() );
+ }
+ }
+
+ // change views
+ m_pViewElement->slotChange(selectedNode);
+
+ m_pTabWidget->setTabEnabled( m_pViewElement, true );
+ m_pTabWidget->setTabEnabled( m_pViewContents, false );
+ m_pTabWidget->setTabEnabled( m_pViewProcInstr, false );
+
+ m_pTabWidget->showPage(m_pViewElement);
+
+ // change path combo
+ m_pActPathCombo->insertItem( domTool_getIconForNodeType(selectedNode.nodeType(), false), domTool_getPath(selectedNode) );
+}
+
+void KXMLEditorPart::slotSelectionChanged( const QDomCharacterData & selectedNode )
+{
+ // Enable/Disable actions
+ if(m_pBrowserExt)
+ m_pBrowserExt->emit enableAction( "copy", true );
+ else
+ m_pActEditCopy->setEnabled(true);
+
+ m_pActEditDeselect->setEnabled(true);
+ m_pActViewNodeUp->setEnabled( ! selectedNode.parentNode().isNull() ); // disable if it's a root item
+ m_pActViewExpNode->setEnabled(false);
+ m_pActViewColNode->setEnabled(false);
+ m_pActBookmarksToggle->setEnabled(true);
+
+ if ( isReadWrite() )
+ {
+ m_pActEditCut->setEnabled(true);
+ m_pActEditPaste->setEnabled(true);
+
+ m_pActXmlElementInsert->setEnabled(false);
+ m_pActXmlAttributesAdd->setEnabled(false);
+ m_pActXmlAttributesDel->setEnabled(false);
+ m_pActXmlProcInstrInsert->setEnabled(false);
+ m_pActInsertText->setEnabled(false);
+ m_pActInsertCDATA->setEnabled(false);
+ m_pActInsertComment->setEnabled(false);
+ m_pActXmlMoveNodeUp->setEnabled( ! selectedNode.previousSibling().isNull() );
+ m_pActXmlMoveNodeDown->setEnabled( ! selectedNode.nextSibling().isNull() );
+ m_pActDelete->setEnabled(true);
+ m_pActProperties->setEnabled(true);
+ m_pActEditRawXml->setEnabled(false);
+ }
+
+ // change views
+ m_pViewContents->setText( selectedNode.data() );
+
+ m_pTabWidget->setTabEnabled( m_pViewElement, false );
+ m_pTabWidget->setTabEnabled( m_pViewContents, true );
+ m_pTabWidget->setTabEnabled( m_pViewProcInstr, false );
+
+ m_pTabWidget->showPage( m_pViewContents );
+
+ // change path combo
+ m_pActPathCombo->insertItem( domTool_getIconForNodeType(selectedNode.nodeType(), false), domTool_getPath(selectedNode) );
+}
+
+void KXMLEditorPart::slotSelectionChanged( const QDomProcessingInstruction & selectedNode )
+{
+ // Enable/Disable actions
+ if(m_pBrowserExt)
+ m_pBrowserExt->emit enableAction( "copy", true );
+ else
+ m_pActEditCopy->setEnabled(true);
+
+ m_pActEditDeselect->setEnabled(true);
+ m_pActViewNodeUp->setEnabled( ! selectedNode.parentNode().isNull() ); // disable if it's a root item
+ m_pActViewExpNode->setEnabled(false);
+ m_pActViewColNode->setEnabled(false);
+ m_pActBookmarksToggle->setEnabled(true);
+
+ if ( isReadWrite() )
+ {
+ m_pActEditCut->setEnabled(true);
+ m_pActEditPaste->setEnabled(true);
+
+ m_pActXmlAttributesAdd->setEnabled(false);
+ m_pActXmlAttributesDel->setEnabled(false);
+ m_pActXmlProcInstrInsert->setEnabled(false);
+ m_pActInsertText->setEnabled(false);
+ m_pActInsertCDATA->setEnabled(false);
+ m_pActInsertComment->setEnabled(false);
+ m_pActDelete->setEnabled(true);
+ m_pActProperties->setEnabled(true);
+ m_pActEditRawXml->setEnabled(false);
+ m_pActXmlElementInsert->setEnabled(selectedNode.parentNode().isDocument() &&
+ document()->documentElement().isNull());
+
+ if ( selectedNode.parentNode().isDocument() )
+ {
+ m_pActXmlMoveNodeUp->setEnabled(false);
+ m_pActXmlMoveNodeDown->setEnabled(false);
+ }
+ else
+ {
+ m_pActXmlMoveNodeUp->setEnabled( ! selectedNode.previousSibling().isNull() );
+ m_pActXmlMoveNodeDown->setEnabled( ! selectedNode.nextSibling().isNull() );
+ }
+ }
+
+ // change views
+ m_pViewProcInstr->setText( selectedNode.data() );
+
+ m_pTabWidget->setTabEnabled( m_pViewElement, false );
+ m_pTabWidget->setTabEnabled( m_pViewContents, false );
+ m_pTabWidget->setTabEnabled( m_pViewProcInstr, true );
+
+ m_pTabWidget->showPage( m_pViewProcInstr );
+
+ // change path combo
+ m_pActPathCombo->insertItem( domTool_getIconForNodeType(selectedNode.nodeType(), false), domTool_getPath(selectedNode) );
+}
+
+void KXMLEditorPart::slotContextMenuRequested( const QString & szMenuName, const QPoint & pos )
+{
+ QWidget * pContainer = hostContainer(szMenuName);
+
+ if ( ! pContainer )
+ {
+ kdError() << "KXMLEditor " << k_funcinfo << " Couldn't get a container widget for the given menu name (" << szMenuName << ")" << endl;
+ return;
+ }
+
+ if ( ! pContainer->inherits("KPopupMenu") )
+ {
+ kdError() << "KXMLEditor " << k_funcinfo << " Wrong container widget" << endl;
+ return;
+ }
+
+ KPopupMenu * pMenu = static_cast <KPopupMenu*> (pContainer);
+ pMenu->popup( pos );
+}
+
+
+/////////////////////////////////////////////////////////////////////
+// FUNCTIONS CALLED FROM KXECommand CHILD CLASSES
+/////////////////////////////////////////////////////////////////////
+
+void KXMLEditorPart::updateNodeCreated(const QDomNode & node)
+{
+ m_pViewTree->updateNodeCreated(node);
+}
+
+void KXMLEditorPart::updateNodeDeleted( const QDomNode & node )
+{
+ m_pViewTree->updateNodeDeleted(node);
+
+ // if root element deleted, enable Insert Element
+ if(node.isElement() && (m_pViewTree->firstChild() == 0) && (isReadWrite()))
+ m_pActXmlElementInsert->setEnabled(true);
+}
+
+void KXMLEditorPart::updateNodeChanged( const QDomElement & domElement )
+{
+ m_pViewTree->updateNodeChanged(domElement);
+ m_pViewElement->slotChange(domElement);
+}
+
+void KXMLEditorPart::updateNodeChanged( const QDomCharacterData & domCharData )
+{
+ m_pViewTree->updateNodeChanged(domCharData);
+ m_pViewContents->setText( domCharData.data() );
+}
+
+void KXMLEditorPart::updateNodeChanged( const QDomProcessingInstruction &domProcInstr )
+{
+ m_pViewTree->updateNodeChanged(domProcInstr);
+ m_pViewProcInstr->setText( domProcInstr.data() );
+}
+
+void KXMLEditorPart::updateNodeMoved( const QDomNode & domNode )
+{
+ m_pViewTree->updateNodeMoved(domNode);
+}
+
+
+bool KXMLEditorPart::slotFileSaveAs()
+{
+ emit setStatusBarText( i18n("Saving file with a new filename...") );
+
+ KFileDialog dlg( QDir::currentDirPath(), // start dir.
+ i18n(FILE_DIALOG_FILTER), // filter
+ widget(), // parent
+ "file dialog for saving", // name
+ true ); // modal
+ dlg.setCaption( i18n("Save as...") );
+ dlg.setOperationMode( KFileDialog::Saving );
+ dlg.exec();
+
+ KURL url = dlg.selectedURL();
+ bool bRetVal = false;
+
+ if(!url.isEmpty())
+ {
+ // append filetype if necessary
+ if(dlg.currentFilter() != "*.*")
+ { QString strExtension = dlg.currentFilter();
+ strExtension.remove('*');
+
+ if(strExtension != url.fileName().right(strExtension.length()))
+ url.setFileName(url.fileName() + strExtension );
+ }
+
+ if((bRetVal = saveAs(url))) // something may go wrong
+ {
+ emit sigAddRecentURL(url);
+ setModified(false);
+ }
+ }
+
+ emit setStatusBarText( i18n("Ready.") );
+ return bRetVal;
+}
+
+void KXMLEditorPart::slotDocOpened()
+{
+// I temporary introduced code to measure the loading time using
+// the different tree view item initialization modes.
+// Simply open a document, remember the measured time difference,
+// change the mode (in the configuration dialog), load the
+// same document again and compare the measurements.
+// Olaf
+//
+// TODO: the three lines operating with the QTime objects
+// can be removed later
+
+ // update the view
+ m_pViewTree->updateClear();
+ int i = document()->childNodes().length();
+ //QTime t1 = QTime::currentTime(); //TODO: remove this line later (Olaf)
+ while ( i > 0 )
+ {
+ i--;
+ m_pViewTree->updateNodeCreated( document()->childNodes().item(i) );
+ }
+
+ //QTime t2 = QTime::currentTime(); //TODO: remove this and the next line later (Olaf)
+ //kdDebug() << "KXMLEditorPart::slotDocOpened() time difference: " << t1.msecsTo(t2) << " msecs" << endl;
+
+ m_pActPathCombo->slotClear();
+}
+
+void KXMLEditorPart::setDocument(KXEDocument *pDocument)
+{
+ // detach previously used document
+ if (m_pDocument)
+ {
+ disconnect (m_pDocument,0,this,0);
+ }
+ m_pDocument = pDocument;
+ if (pDocument)
+ {
+ // open document notification
+ connect(pDocument,SIGNAL(sigOpened()),this,SLOT(slotDocOpened()));
+ // document modification is also dispatched
+ connect(pDocument,SIGNAL(sigModified(bool)),this,SLOT(setModified(bool)));
+ // update notifications
+ connect(pDocument,SIGNAL(sigNodeChanged(const QDomElement&)),this,SLOT(updateNodeChanged(const QDomElement&)));
+ connect(pDocument,SIGNAL(sigNodeChanged(const QDomProcessingInstruction&)),this,SLOT(updateNodeChanged(const QDomProcessingInstruction&)));
+ connect(pDocument,SIGNAL(sigNodeChanged(const QDomCharacterData&)),this,SLOT(updateNodeChanged(const QDomCharacterData&)));
+ connect(pDocument,SIGNAL(sigNodeCreated(const QDomNode&)),this,SLOT(updateNodeCreated(const QDomNode&)));
+ connect(pDocument,SIGNAL(sigNodeDeleted(const QDomNode&)),this,SLOT(updateNodeDeleted(const QDomNode&)));
+ connect(pDocument,SIGNAL(sigNodeMoved(const QDomNode&)),this,SLOT(updateNodeMoved(const QDomNode&)));
+ // merging document action collection
+ insertChildClient(pDocument);
+ }
+}
+
+void KXMLEditorPart::slotActRedo()
+{
+ m_pCmdHistory->redo();
+}
+
+void KXMLEditorPart::slotActUndo()
+{
+ m_pCmdHistory->undo();
+}
+
+void KXMLEditorPart::slotActDetachStylesheet()
+{
+ KCommand *pCmd = m_pDocument->actDetachStylesheet();
+ if(pCmd) m_pCmdHistory->addCommand(pCmd);
+}
+
+void KXMLEditorPart::slotActAttachStylesheet()
+{
+ KCommand *pCmd = m_pDocument->actAttachStylesheet();
+ if(pCmd) m_pCmdHistory->addCommand(pCmd);
+}
+
+void KXMLEditorPart::slotActDetachSchema()
+{
+ KCommand *pCmd = m_pDocument->actDetachSchema();
+ if(pCmd) m_pCmdHistory->addCommand(pCmd);
+}
+
+void KXMLEditorPart::slotActAttachSchema()
+{
+ KCommand *pCmd = m_pDocument->actAttachSchema();
+ if(pCmd) m_pCmdHistory->addCommand(pCmd);
+}
+
+// Instert or edit special processing instruction <?xml ... ?>
+void KXMLEditorPart::slotActVersionEncoding()
+{
+ KCommand *pCmd = m_pDocument->actVersionEncoding();
+ if(pCmd) m_pCmdHistory->addCommand(pCmd);
+}
+
+void KXMLEditorPart::updateActions()
+{
+ if(!m_pDocument) return;
+ if(!m_pActAttachSchema) return; // not in read-write mode
+
+ // Schema
+ bool bSchemaExists = !m_pDocument->documentElement().isNull() &&
+ // that's a question why it works with negated condition ??????
+ !m_pDocument->documentElement().hasAttributeNS(SCHEMA_NAMESPACE,SCHEMA_ATTRIBUTE);
+
+ m_pActAttachSchema->setEnabled(!m_pDocument->documentElement().isNull() && !bSchemaExists);
+ m_pActDetachSchema->setEnabled(bSchemaExists);
+
+ // Stylesheet
+ m_pActDetachStylesheet->setEnabled(!m_pDocument->getSpecProcInstr("xml-stylesheet").isNull());
+}