diff options
Diffstat (limited to 'konq-plugins/domtreeviewer')
24 files changed, 4670 insertions, 0 deletions
diff --git a/konq-plugins/domtreeviewer/Makefile.am b/konq-plugins/domtreeviewer/Makefile.am new file mode 100644 index 0000000..3dcfcc9 --- /dev/null +++ b/konq-plugins/domtreeviewer/Makefile.am @@ -0,0 +1,44 @@ +INCLUDES = $(all_includes) + +# Needed to catch DOM exceptions +KDE_CXXFLAGS = $(USE_EXCEPTIONS) +# -DKListView=DOMListView + +# Install this plugin in the KDE modules directory +kde_module_LTLIBRARIES = libdomtreeviewerplugin.la + +libdomtreeviewerplugin_la_SOURCES = plugin_domtreeviewer.cpp \ + domtreeview.cpp \ + domlistviewitem.cpp \ + domtreewindow.cpp \ + domtreecommands.cpp \ + signalreceiver.cpp \ + domtreeviewbase.ui \ + attributeeditdialog.ui \ + elementeditdialog.ui \ + texteditdialog.ui \ + messagedialog.ui +# klistview.cpp \ +# +libdomtreeviewerplugin_la_LIBADD = $(LIB_KPARTS) $(LIB_KHTML) +libdomtreeviewerplugin_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) + +pluginsdir = $(kde_datadir)/khtml/kpartplugins +plugins_DATA = plugin_domtreeviewer.rc plugin_domtreeviewer.desktop + +appsdir = $(kde_appsdir)/.hidden +apps_DATA = plugin_domtreeviewer.desktop + +install-data-local: $(srcdir)/../uninstall.desktop + $(mkinstalldirs) $(DESTDIR)$(pluginsdir) + $(INSTALL_DATA) $(srcdir)/../uninstall.desktop $(DESTDIR)$(pluginsdir)/domtreeviewerplugin.desktop + +METASOURCES = AUTO +KDE_ICON = domtreeviewer + +pluginsdatadir = $(kde_datadir)/domtreeviewer +pluginsdata_DATA = domtreeviewerui.rc + +messages: rc.cpp + $(XGETTEXT) *.cpp *.h -o $(podir)/domtreeviewer.pot + diff --git a/konq-plugins/domtreeviewer/attributeeditdialog.ui b/konq-plugins/domtreeviewer/attributeeditdialog.ui new file mode 100644 index 0000000..c77f92d --- /dev/null +++ b/konq-plugins/domtreeviewer/attributeeditdialog.ui @@ -0,0 +1,174 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>AttributeEditDialog</class> +<widget class="QDialog"> + <property name="name"> + <cstring>AttributeEditDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>412</width> + <height>254</height> + </rect> + </property> + <property name="caption"> + <string>Edit Attribute</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout7</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Attribute &name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>attrName</cstring> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>attrName</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Attribute &value:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>attrValue</cstring> + </property> + </widget> + <widget class="KTextEdit"> + <property name="name"> + <cstring>attrValue</cstring> + </property> + <property name="acceptDrops"> + <bool>true</bool> + </property> + <property name="textFormat"> + <enum>PlainText</enum> + </property> + <property name="tabChangesFocus"> + <bool>true</bool> + </property> + <property name="autoFormatting"> + <set>AutoNone</set> + </property> + </widget> + <widget class="Line"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout8</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>okBtn</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="flat"> + <bool>false</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>121</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelBtn</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>okBtn</sender> + <signal>clicked()</signal> + <receiver>AttributeEditDialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>cancelBtn</sender> + <signal>clicked()</signal> + <receiver>AttributeEditDialog</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>attrValue</sender> + <signal>returnPressed()</signal> + <receiver>AttributeEditDialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>attrName</sender> + <signal>returnPressed()</signal> + <receiver>AttributeEditDialog</receiver> + <slot>accept()</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klineedit.h</includehint> + <includehint>ktextedit.h</includehint> +</includehints> +</UI> diff --git a/konq-plugins/domtreeviewer/cr16-action-domtreeviewer.png b/konq-plugins/domtreeviewer/cr16-action-domtreeviewer.png Binary files differnew file mode 100644 index 0000000..d9c99cb --- /dev/null +++ b/konq-plugins/domtreeviewer/cr16-action-domtreeviewer.png diff --git a/konq-plugins/domtreeviewer/cr22-action-domtreeviewer.png b/konq-plugins/domtreeviewer/cr22-action-domtreeviewer.png Binary files differnew file mode 100644 index 0000000..0690b3d --- /dev/null +++ b/konq-plugins/domtreeviewer/cr22-action-domtreeviewer.png diff --git a/konq-plugins/domtreeviewer/domlistviewitem.cpp b/konq-plugins/domtreeviewer/domlistviewitem.cpp new file mode 100644 index 0000000..c24df96 --- /dev/null +++ b/konq-plugins/domtreeviewer/domlistviewitem.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** + domlistviewitem.cpp + ------------------- + + author : Andreas Schlapbach + email : schlpbch@iam.unibe.ch + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 "domlistviewitem.h" + +#include <qpainter.h> +#include <qlistview.h> +#include <qapplication.h> + +#include <kglobalsettings.h> + +DOMListViewItem::DOMListViewItem( const DOM::Node &node, QListView *parent ) + : QListViewItem( parent ), m_node(node) +{ + init(); +} + +DOMListViewItem::DOMListViewItem( const DOM::Node &node, QListView *parent, QListViewItem *after) + : QListViewItem( parent, after ), m_node(node) +{ + init(); +} + +DOMListViewItem::DOMListViewItem( const DOM::Node &node, QListViewItem *parent ) + : QListViewItem( parent ), m_node(node) +{ + init(); +} + +DOMListViewItem::DOMListViewItem( const DOM::Node &node, QListViewItem *parent, QListViewItem *after) + : QListViewItem( parent, after ), m_node(node) +{ + init(); +} + +DOMListViewItem::~DOMListViewItem() +{ + //NOP +} + +void DOMListViewItem::init() +{ + m_color = QApplication::palette().color( QPalette::Active, QColorGroup::Text ); + m_font = KGlobalSettings::generalFont(); + clos = false; +} + +void DOMListViewItem::paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int alignment ) +{ + QColorGroup _cg( cg ); + QColor c = _cg.text(); + + p->setFont(m_font); + _cg.setColor( QColorGroup::Text, m_color ); + QListViewItem::paintCell( p, _cg, column, width, alignment ); + _cg.setColor( QColorGroup::Text, c ); +} + + diff --git a/konq-plugins/domtreeviewer/domlistviewitem.h b/konq-plugins/domtreeviewer/domlistviewitem.h new file mode 100644 index 0000000..22f34b2 --- /dev/null +++ b/konq-plugins/domtreeviewer/domlistviewitem.h @@ -0,0 +1,57 @@ +/*************************************************************************** + domlistviewitem.h + ------------------- + + author : Andreas Schlapbach + email : schlpbch@iam.unibe.ch + *************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef DOMLISTVIEWITEMS_H +#define DOMLISTVIEWITEMS_H + +#include <dom/dom_node.h> + +#include <qlistview.h> +#include <qcolor.h> +#include <qfont.h> + +class DOMListViewItem : public QListViewItem +{ + + public: + DOMListViewItem( const DOM::Node &, QListView *parent ); + DOMListViewItem( const DOM::Node &, QListView *parent, QListViewItem *after ); + DOMListViewItem( const DOM::Node &, QListViewItem *parent ); + DOMListViewItem( const DOM::Node &, QListViewItem *parent, QListViewItem *after ); + virtual ~DOMListViewItem(); + + virtual void paintCell( QPainter *p, const QColorGroup &cg, + int column, int width, int alignment ); + + void setColor( const QColor &color) { m_color = color; } + + void setFont( const QFont &font) { m_font = font;} + void setItalic( bool b) {m_font.setItalic(b);} + void setBold( bool b) {m_font.setBold(b);} + void setUnderline(bool b) {m_font.setUnderline(b);} + + bool isClosing() const { return clos; } + void setClosing(bool s) { clos = s; } + + DOM::Node node() const { return m_node; } + + private: + void init(); + QColor m_color; + QFont m_font; + DOM::Node m_node; + bool clos; +}; +#endif diff --git a/konq-plugins/domtreeviewer/domtreecommands.cpp b/konq-plugins/domtreeviewer/domtreecommands.cpp new file mode 100644 index 0000000..1f91cf1 --- /dev/null +++ b/konq-plugins/domtreeviewer/domtreecommands.cpp @@ -0,0 +1,562 @@ +/* This file is part of the KDE project + * + * Copyright (C) 2005 Leo Savernik <l.savernik@aon.at> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "domtreecommands.h" + +#include <dom/dom_doc.h> +#include <dom/dom_exception.h> + +#include <klocale.h> + +#include <qmap.h> + +using namespace domtreeviewer; + +static const char * const dom_error_msgs[] = { + I18N_NOOP("No error"), + I18N_NOOP("Index size exceeded"), + I18N_NOOP("DOMString size exceeded"), + I18N_NOOP("Hierarchy request error"), + I18N_NOOP("Wrong document"), + I18N_NOOP("Invalid character"), + I18N_NOOP("No data allowed"), + I18N_NOOP("No modification allowed"), + I18N_NOOP("Not found"), + I18N_NOOP("Not supported"), + I18N_NOOP("Attribute in use"), + I18N_NOOP("Invalid state"), + I18N_NOOP("Syntax error"), + I18N_NOOP("Invalid modification"), + I18N_NOOP("Namespace error"), + I18N_NOOP("Invalid access") +}; + +// == global functions ============================================== + +QString domtreeviewer::domErrorMessage(int dom_err) +{ + if ((unsigned)dom_err > sizeof dom_error_msgs/sizeof dom_error_msgs[0]) + return i18n("Unknown Exception %1").arg(dom_err); + else + return i18n(dom_error_msgs[dom_err]); +} + +// == ManipulationCommandSignalEmitter ============================== + +static ManipulationCommandSignalEmitter *_mcse; + +ManipulationCommandSignalEmitter::ManipulationCommandSignalEmitter() +{} +ManipulationCommandSignalEmitter::~ManipulationCommandSignalEmitter() +{} + +namespace domtreeviewer { + +ManipulationCommandSignalEmitter* ManipulationCommand::mcse() +{ + if (!_mcse) _mcse = new ManipulationCommandSignalEmitter; + return _mcse; +} + +} + +// == ChangedNodeSet ================================================ + +namespace domtreeviewer { + +// collection of nodes for which to emit the nodeChanged signal +inline static bool operator <(const DOM::Node &n1, const DOM::Node &n2) +{ + return (long)n1.handle() - (long)n2.handle() < 0; +} + +class ChangedNodeSet : public QMap<DOM::Node, bool> +{ +}; + +} + +// == ManipulationCommand =========================================== + +ManipulationCommand::ManipulationCommand() : _exception(0), changedNodes(0) + , _reapplied(false) , allow_signals(true) +{ +} + +ManipulationCommand::~ManipulationCommand() +{ +} + +void ManipulationCommand::connect(const char *signal, QObject *recv, const char *slot) +{ + QObject::connect(mcse(), signal, recv, slot); +} + +void ManipulationCommand::handleException(DOM::DOMException &ex) +{ + _exception = ex; + QString msg = name() + ": " + domErrorMessage(ex.code); + emit mcse()->error(ex.code, msg); +} + +void ManipulationCommand::checkAndEmitSignals() +{ + if (allow_signals) { + if (changedNodes) { + ChangedNodeSet::Iterator end = changedNodes->end(); + for (ChangedNodeSet::Iterator it = changedNodes->begin(); it != end; ++it) { + emit mcse()->nodeChanged(it.key()); + } + } + + if (struc_changed) emit mcse()->structureChanged(); + } + if (changedNodes) changedNodes->clear(); +} + +void ManipulationCommand::addChangedNode(const DOM::Node &node) +{ + if (!changedNodes) changedNodes = new ChangedNodeSet; + changedNodes->insert(node, true); +} + +void ManipulationCommand::execute() +{ + if (!isValid()) return; + + struc_changed = false; + + try { + if (shouldReapply()) + reapply(); + else + apply(); + + checkAndEmitSignals(); + + } catch(DOM::DOMException &ex) { + handleException(ex); + } + _reapplied = true; +} + +void ManipulationCommand::unexecute() +{ + if (!isValid()) return; + + struc_changed = false; + + try { + unapply(); + checkAndEmitSignals(); + } catch(DOM::DOMException &ex) { + handleException(ex); + } +} + +void ManipulationCommand::reapply() +{ + apply(); +} + +// == MultiCommand =========================================== + +MultiCommand::MultiCommand(const QString &desc) +: _name(desc) +{ + cmds.setAutoDelete(true); +} + +MultiCommand::~MultiCommand() +{ +} + +void MultiCommand::addCommand(ManipulationCommand *cmd) +{ + cmd->allow_signals = false; + cmds.append(cmd); +} + +void MultiCommand::apply() +{ + // apply in forward order + for (QPtrListIterator<ManipulationCommand> it = cmds; *it; ++it) { + try { + if (shouldReapply()) (*it)->reapply(); + else (*it)->apply(); + + struc_changed |= (*it)->struc_changed; + mergeChangedNodesFrom(*it); + + } catch (DOM::DOMException &) { + // rollback + for (--it; *it; --it) { + try { + (*it)->unapply(); + } catch(DOM::DOMException &) { + // ignore + } + } + throw; + } + + } +} + +void MultiCommand::unapply() +{ + // unapply in reverse order + QPtrListIterator<ManipulationCommand> it = cmds; + for (it.toLast(); *it; --it) { + try { + (*it)->unapply(); + + struc_changed |= (*it)->struc_changed; + mergeChangedNodesFrom(*it); + + } catch (DOM::DOMException &) { + // rollback + for (++it; *it; ++it) { + try { + (*it)->reapply(); + } catch(DOM::DOMException &) { + // ignore + } + } + throw; + } + + } +} + +void MultiCommand::mergeChangedNodesFrom(ManipulationCommand *cmd) +{ + if (!cmd->changedNodes) return; + + ChangedNodeSet::ConstIterator end = cmd->changedNodes->end(); + for (ChangedNodeSet::ConstIterator it = cmd->changedNodes->begin(); it != end; ++it) { + addChangedNode(it.key()); + } + + cmd->changedNodes->clear(); +} + +QString MultiCommand::name() const +{ + return _name; +} + +// == AddAttributeCommand =========================================== + +AddAttributeCommand::AddAttributeCommand(const DOM::Element &element, const QString &attrName, const QString &attrValue) +: _element(element), attrName(attrName), attrValue(attrValue) +{ + if (attrValue.isEmpty()) this->attrValue = "<dummy>"; +} + +AddAttributeCommand::~AddAttributeCommand() +{ +} + +void AddAttributeCommand::apply() +{ + _element.setAttribute(attrName, attrValue); + addChangedNode(_element); +} + +void AddAttributeCommand::unapply() +{ + _element.removeAttribute(attrName); + addChangedNode(_element); +} + +QString AddAttributeCommand::name() const +{ + return i18n("Add attribute"); +} + +// == ChangeAttributeValueCommand ==================================== + +ChangeAttributeValueCommand::ChangeAttributeValueCommand( +const DOM::Element &element, const QString &attr, const QString &value) +: _element(element), _attr(attr), new_value(value) +{ +} + +ChangeAttributeValueCommand::~ChangeAttributeValueCommand() +{ +} + +void ChangeAttributeValueCommand::apply() +{ + if (!shouldReapply()) old_value = _element.getAttribute(_attr); + _element.setAttribute(_attr, new_value); + addChangedNode(_element); +} + +void ChangeAttributeValueCommand::unapply() +{ + _element.setAttribute(_attr, old_value); + addChangedNode(_element); +} + +QString ChangeAttributeValueCommand::name() const +{ + return i18n("Change attribute value"); +} + +// == RemoveAttributeCommand ======================================== + +RemoveAttributeCommand::RemoveAttributeCommand(const DOM::Element &element, const QString &attrName) +: _element(element), attrName(attrName) +{ +} + +RemoveAttributeCommand::~RemoveAttributeCommand() +{ +} + +void RemoveAttributeCommand::apply() +{ +// kdDebug(90180) << k_funcinfo << _element.nodeName().string() << ": " << attrName.string() << endl; + if (!shouldReapply()) + oldAttrValue = _element.getAttribute(attrName); + _element.removeAttribute(attrName); + addChangedNode(_element); +} + +void RemoveAttributeCommand::unapply() +{ + _element.setAttribute(attrName, oldAttrValue); + addChangedNode(_element); +} + +QString RemoveAttributeCommand::name() const +{ + return i18n("Remove attribute"); +} + +// == RenameAttributeCommand ======================================== + +RenameAttributeCommand::RenameAttributeCommand(const DOM::Element &element, const QString &attrOldName, const QString &attrNewName) +: _element(element), attrOldName(attrOldName), attrNewName(attrNewName) +{ +} + +RenameAttributeCommand::~RenameAttributeCommand() +{ +} + +void RenameAttributeCommand::apply() +{ + if (!shouldReapply()) + attrValue = _element.getAttribute(attrOldName); + _element.removeAttribute(attrOldName); + _element.setAttribute(attrNewName, attrValue); + addChangedNode(_element); +} + +void RenameAttributeCommand::unapply() +{ + _element.removeAttribute(attrNewName); + _element.setAttribute(attrOldName, attrValue); + addChangedNode(_element); +} + +QString RenameAttributeCommand::name() const +{ + return i18n("Rename attribute"); +} + +// == ChangeCDataCommand ======================================== + +ChangeCDataCommand::ChangeCDataCommand(const DOM::CharacterData &cdata, const QString &value) +: cdata(cdata), value(value), has_newlines(false) +{ +} + +ChangeCDataCommand::~ChangeCDataCommand() +{ +} + +void ChangeCDataCommand::apply() +{ + if (!shouldReapply()) { + oldValue = cdata.data(); + has_newlines = + QConstString(value.unicode(), value.length()).string().contains('\n') + || QConstString(oldValue.unicode(), oldValue.length()).string().contains('\n'); + } + cdata.setData(value); + addChangedNode(cdata); + struc_changed = has_newlines; +} + +void ChangeCDataCommand::unapply() +{ + cdata.setData(oldValue); + addChangedNode(cdata); + struc_changed = has_newlines; +} + +QString ChangeCDataCommand::name() const +{ + return i18n("Change textual content"); +} + +// == ManipulateNodeCommand =========================================== + +ManipulateNodeCommand::ManipulateNodeCommand(const DOM::Node &node, const DOM::Node &parent, const DOM::Node &after) +: _node(node), _parent(parent), _after(after) +{ +} + +ManipulateNodeCommand::~ManipulateNodeCommand() +{ +} + +void ManipulateNodeCommand::insert() +{ + _parent.insertBefore(_node, _after); +} + +void ManipulateNodeCommand::remove() +{ + DOM::DocumentFragment frag = _node; + + if (frag.isNull()) { // do a normal remove + _node = _parent.removeChild(_node); + + } else { // remove fragment nodes and recreate fragment + DOM::DocumentFragment newfrag = _parent.ownerDocument().createDocumentFragment(); + + for (DOM::Node i = frag.firstChild(); !i.isNull(); i = i.nextSibling()) { + newfrag.appendChild(_parent.removeChild(i)); + } + + _node = newfrag; + } +} + +// == InsertNodeCommand =========================================== + +InsertNodeCommand::InsertNodeCommand(const DOM::Node &node, const DOM::Node &parent, const DOM::Node &after) +: ManipulateNodeCommand(node, parent, after) +{ +} + +InsertNodeCommand::~InsertNodeCommand() +{ +} + +void InsertNodeCommand::apply() +{ + insert(); + struc_changed = true; +} + +void InsertNodeCommand::unapply() +{ + remove(); + struc_changed = true; +} + +QString InsertNodeCommand::name() const +{ + return i18n("Insert node"); +} + +// == RemoveNodeCommand =========================================== + +RemoveNodeCommand::RemoveNodeCommand(const DOM::Node &node, const DOM::Node &parent, const DOM::Node &after) +: ManipulateNodeCommand(node, parent, after) +{ +} + +RemoveNodeCommand::~RemoveNodeCommand() +{ +} + +void RemoveNodeCommand::apply() +{ + remove(); + struc_changed = true; +} + +void RemoveNodeCommand::unapply() +{ + insert(); + struc_changed = true; +} + +QString RemoveNodeCommand::name() const +{ + return i18n("Remove node"); +} + +// == MoveNodeCommand =========================================== + +MoveNodeCommand::MoveNodeCommand(const DOM::Node &node, const DOM::Node &parent, const DOM::Node &after) +: _node(node), new_parent(parent), new_after(after) +{ + old_parent = node.parentNode(); + old_after = node.nextSibling(); +} + +MoveNodeCommand::~MoveNodeCommand() +{ +} + +void MoveNodeCommand::apply() +{ + old_parent.removeChild(_node); + try { + new_parent.insertBefore(_node, new_after); + } catch (DOM::DOMException &) { + try { // rollback + old_parent.insertBefore(_node, old_after); + } catch (DOM::DOMException &) {} + throw; + } + struc_changed = true; +} + +void MoveNodeCommand::unapply() +{ + new_parent.removeChild(_node); + try { + old_parent.insertBefore(_node, old_after); + } catch (DOM::DOMException &) { + try { // rollback + new_parent.insertBefore(_node, new_after); + } catch (DOM::DOMException &) {} + throw; + } + struc_changed = true; +} + +QString MoveNodeCommand::name() const +{ + return i18n("Move node"); +} + +#include "domtreecommands.moc" + +#undef MCSE diff --git a/konq-plugins/domtreeviewer/domtreecommands.h b/konq-plugins/domtreeviewer/domtreecommands.h new file mode 100644 index 0000000..bf893dc --- /dev/null +++ b/konq-plugins/domtreeviewer/domtreecommands.h @@ -0,0 +1,375 @@ +/* This file is part of the KDE project + * + * Copyright (C) 2005 Leo Savernik <l.savernik@aon.at> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef domtreecommands_H +#define domtreecommands_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <dom/dom_element.h> +#include <dom/dom_exception.h> +#include <dom/dom_string.h> +#include <dom/dom_text.h> + +#include <kcommand.h> + +#include <qobject.h> +#include <qptrlist.h> + +class DOMTreeView; +class KPrinter; +class KURL; + +namespace domtreeviewer { + +class ManipulationCommandSignalEmitter; +class ChangedNodeSet; + +/** returns a localized string for the given dom exception code */ +QString domErrorMessage(int exception_code); + +/** + * Internal class for emitting signals. + * @internal + */ +class ManipulationCommandSignalEmitter : public QObject +{ + Q_OBJECT + + ManipulationCommandSignalEmitter(); + virtual ~ManipulationCommandSignalEmitter(); + +#undef signals +#define signals public +signals: +#undef signals +#define signals protected + /** emitted if the DOM structure has been changed */ + void structureChanged(); + /** emitted if a DOM node has been changed */ + void nodeChanged(const DOM::Node &changedNode); + /** emitted if an error occurred + * @param err_id DOM error id + * @param msg error message + */ + void error(int err_id, const QString &msg); + +private: // make moc not complain + friend class ManipulationCommand; +}; + +/** + * Base class of all dom tree manipulation commands. + * @author Leo Savernik + */ +class ManipulationCommand : public KCommand +{ +public: + ManipulationCommand(); + virtual ~ManipulationCommand(); + + /** returns whether this command is still valid and can be executed */ + bool isValid() const { return !_exception.code; } + /** returns the last occurred DOM exception */ + DOM::DOMException exception() const { return _exception; } + /** returns true when the next issue of execute will reapply the command */ + bool shouldReapply() const { return _reapplied; } + /** returns true if the command may emit signals */ + bool allowSignals() const { return allow_signals; } + + /** connects the given signal to a slot */ + static void connect(const char *signal, QObject *recv, const char *slot); + + /** does grunt work and calls apply()/reapply() */ + virtual void execute(); + /** does grunt work and calls unapply() */ + virtual void unexecute(); + +protected: + virtual void apply() = 0; + virtual void reapply(); + virtual void unapply() = 0; + + void handleException(DOM::DOMException &); + void checkAndEmitSignals(); + void addChangedNode(const DOM::Node &); + + static ManipulationCommandSignalEmitter *mcse(); + +protected: + DOM::DOMException _exception; + ChangedNodeSet *changedNodes; + bool _reapplied:1; + bool struc_changed:1; + +private: + bool allow_signals:1; + + friend class MultiCommand; +}; + +/** + * Combines multiple commands into a single command. + * + * Does basically the same as KMacroCommand, but inherits from + * ManipulationCommand, and supports rollback. + */ +class MultiCommand : public ManipulationCommand +{ +public: + MultiCommand(const QString &name); + virtual ~MultiCommand(); + + /** Adds a new command. Will take ownership of \c cmd */ + void addCommand(ManipulationCommand *cmd); + + virtual QString name() const; + +protected: + virtual void apply(); + virtual void unapply(); + + void mergeChangedNodesFrom(ManipulationCommand *cmd); + +protected: + QPtrList<ManipulationCommand> cmds; + QString _name; +}; + +/** + * Adds an attribute to a node. + * @author Leo Savernik + */ +class AddAttributeCommand : public ManipulationCommand +{ +public: + AddAttributeCommand(const DOM::Element &element, const QString &attrName, const QString &attrValue); + virtual ~AddAttributeCommand(); + + virtual QString name() const; + +protected: + virtual void apply(); + virtual void unapply(); + +protected: + DOM::Element _element; + DOM::DOMString attrName; + DOM::DOMString attrValue; +}; + +/** + * Manipulates an attribute's value. + * @author Leo Savernik + */ +class ChangeAttributeValueCommand : public ManipulationCommand +{ +public: + ChangeAttributeValueCommand(const DOM::Element &element, const QString &attr, const QString &value); + virtual ~ChangeAttributeValueCommand(); + + virtual QString name() const; + +protected: + virtual void apply(); + virtual void unapply(); + +protected: + DOM::Element _element; + DOM::DOMString _attr; + DOM::DOMString old_value; + DOM::DOMString new_value; +}; + +/** + * Removes an attribute from a node. + * @author Leo Savernik + */ +class RemoveAttributeCommand : public ManipulationCommand +{ +public: + RemoveAttributeCommand(const DOM::Element &element, const QString &attrName); + virtual ~RemoveAttributeCommand(); + + virtual QString name() const; + +protected: + virtual void apply(); + virtual void unapply(); + +protected: + DOM::Element _element; + DOM::DOMString attrName; + DOM::DOMString oldAttrValue; +}; + +/** + * Renames an attribute. + * @author Leo Savernik + */ +class RenameAttributeCommand : public ManipulationCommand +{ +public: + RenameAttributeCommand(const DOM::Element &element, const QString &attrOldName, const QString &attrNewName); + virtual ~RenameAttributeCommand(); + + virtual QString name() const; + +protected: + virtual void apply(); + virtual void unapply(); + +protected: + DOM::Element _element; + DOM::DOMString attrOldName; + DOM::DOMString attrNewName; + DOM::DOMString attrValue; +}; + +/** + * Changes the value of a CData-node. + * @author Leo Savernik + */ +class ChangeCDataCommand : public ManipulationCommand +{ +public: + ChangeCDataCommand(const DOM::CharacterData &, const QString &value); + virtual ~ChangeCDataCommand(); + + virtual QString name() const; + +protected: + virtual void apply(); + virtual void unapply(); + +protected: + DOM::CharacterData cdata; + DOM::DOMString value; + DOM::DOMString oldValue; + bool has_newlines; +}; + +/** + * Handles insertion and deletion primitives of nodes. + * @author Leo Savernik + */ +class ManipulateNodeCommand : public ManipulationCommand +{ +public: + /** + * Prepare command, where \c node is to be contained in \c parent, just + * before \c after. If \c after is 0, it is appended at the end. + */ + ManipulateNodeCommand(const DOM::Node &node, const DOM::Node &parent, const DOM::Node &after); + virtual ~ManipulateNodeCommand(); + +protected: + void insert(); + void remove(); + +protected: + DOM::Node _node; + DOM::Node _parent; + DOM::Node _after; +}; + +/** + * Inserts a node into the tree. + * + * The handed in node may be a full tree, even a document fragment. + * + * @author Leo Savernik + */ +class InsertNodeCommand : public ManipulateNodeCommand +{ +public: + /** + * Prepare insertion command, inserting \c node into \c parent, just + * before \c after. If \c after is 0, append it to the list of children. + */ + InsertNodeCommand(const DOM::Node &node, const DOM::Node &parent, const DOM::Node &after); + virtual ~InsertNodeCommand(); + + virtual QString name() const; + +protected: + virtual void apply(); + virtual void unapply(); + +protected: +}; + +/** + * Removes a node from the tree. + * + * The handed in node may be a full tree, even a document fragment. + * + * @author Leo Savernik + */ +class RemoveNodeCommand : public ManipulateNodeCommand +{ +public: + /** + * Prepare insertion command, inserting \c node into \c parent, just + * before \c after. If \c after is 0, append it to the list of children. + */ + RemoveNodeCommand(const DOM::Node &node, const DOM::Node &parent, const DOM::Node &after); + virtual ~RemoveNodeCommand(); + + virtual QString name() const; + +protected: + virtual void apply(); + virtual void unapply(); + +protected: +}; + +/** + * Moves a node. + * @author Leo Savernik + */ +class MoveNodeCommand : public ManipulationCommand +{ +public: + /** + * Move \c node from current position into \c parent, just before \c after. + * Appends if \c after is 0. + */ + MoveNodeCommand(const DOM::Node &node, const DOM::Node &parent, const DOM::Node &after); + virtual ~MoveNodeCommand(); + + virtual QString name() const; + +protected: + virtual void apply(); + virtual void unapply(); + +protected: + DOM::Node _node; + DOM::Node old_parent, old_after; + DOM::Node new_parent, new_after; +}; + +} // namespace domtreeviewer + +#endif // domtreewindow_H diff --git a/konq-plugins/domtreeviewer/domtreeview.cpp b/konq-plugins/domtreeviewer/domtreeview.cpp new file mode 100644 index 0000000..167d85a --- /dev/null +++ b/konq-plugins/domtreeviewer/domtreeview.cpp @@ -0,0 +1,1226 @@ +/*************************************************************************** + domtreeview.cpp + ------------------- + + copyright : (C) 2001 - The Kafka Team/Andreas Schlapbach + (C) 2005 - Leo Savernik + email : kde-kafka@master.kde.org + schlpbch@iam.unibe.ch + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 "domtreeview.h" +#include "domlistviewitem.h" +#include "domtreewindow.h" +#include "domtreecommands.h" + +#include "attributeeditdialog.h" +#include "elementeditdialog.h" +#include "texteditdialog.h" + +#include "signalreceiver.h" + +#include <assert.h> + +#include <qapplication.h> +#include <qcheckbox.h> +#include <qevent.h> +#include <qfont.h> +#include <qfile.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qpopupmenu.h> +#include <qtextstream.h> +#include <qtimer.h> +#include <qwidgetstack.h> + +#include <dom/dom_core.h> +#include <dom/html_base.h> + +#include <kaction.h> +#include <kdebug.h> +#include <kcombobox.h> +#include <kdialog.h> +#include <keditcl.h> +#include <kfiledialog.h> +#include <kglobalsettings.h> +#include <khtml_part.h> +#include <klineedit.h> +#include <klistview.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kpushbutton.h> +#include <kshortcut.h> +#include <kstdguiitem.h> +#include <ktextedit.h> + +using namespace domtreeviewer; + +DOMTreeView::DOMTreeView(QWidget *parent, const char* name, bool /*allowSaving*/) + : DOMTreeViewBase(parent, name), m_expansionDepth(5), m_maxDepth(0), + m_bPure(true), m_bShowAttributes(true), m_bHighlightHTML(true), + m_findDialog(0), focused_child(0) +{ + part = 0; + + const QFont font(KGlobalSettings::generalFont()); + m_listView->setFont( font ); + m_listView->setSorting(-1); + m_rootListView = m_listView; + + m_pureCheckBox->setChecked(m_bPure); + connect(m_pureCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotPureToggled(bool))); + + m_showAttributesCheckBox->setChecked(m_bShowAttributes); + connect(m_showAttributesCheckBox, SIGNAL(toggled(bool)), this, + SLOT(slotShowAttributesToggled(bool))); + + m_highlightHTMLCheckBox->setChecked(m_bHighlightHTML); + connect(m_highlightHTMLCheckBox, SIGNAL(toggled(bool)), this, + SLOT(slotHighlightHTMLToggled(bool))); + + connect(m_listView, SIGNAL(clicked(QListViewItem *)), this, + SLOT(slotItemClicked(QListViewItem *))); + connect(m_listView, SIGNAL(contextMenuRequested(QListViewItem *, const QPoint &, int)), + SLOT(showDOMTreeContextMenu(QListViewItem *, const QPoint &, int))); + connect(m_listView, SIGNAL(moved(QPtrList<QListViewItem> &, QPtrList<QListViewItem> &, QPtrList<QListViewItem> &)), + SLOT(slotMovedItems(QPtrList<QListViewItem> &, QPtrList<QListViewItem> &, QPtrList<QListViewItem> &))); + + // set up message line + messageLinePane->hide(); + connect(messageHideBtn, SIGNAL(clicked()), SLOT(hideMessageLine())); + connect(messageListBtn, SIGNAL(clicked()), mainWindow(), SLOT(showMessageLog())); + + installEventFilter(m_listView); + + ManipulationCommand::connect(SIGNAL(nodeChanged(const DOM::Node &)), this, SLOT(slotRefreshNode(const DOM::Node &))); + ManipulationCommand::connect(SIGNAL(structureChanged()), this, SLOT(refresh())); + + initDOMNodeInfo(); + + installEventFilter(this); +} + +DOMTreeView::~DOMTreeView() +{ + delete m_findDialog; + disconnectFromActivePart(); +} + +void DOMTreeView::setHtmlPart(KHTMLPart *_part) +{ + KHTMLPart *oldPart = part; + part = _part; + + if (oldPart) { + // nothing here yet + } + + parentWidget()->setCaption( part ? i18n( "DOM Tree for %1" ).arg(part->url().prettyURL()) : i18n("DOM Tree") ); + + QTimer::singleShot(0, this, SLOT(slotSetHtmlPartDelayed())); +} + +DOMTreeWindow *DOMTreeView::mainWindow() const +{ + return static_cast<DOMTreeWindow *>(parentWidget()); +} + +bool DOMTreeView::eventFilter(QObject *o, QEvent *e) +{ + if (e->type() == QEvent::AccelOverride) { + QKeyEvent *ke = static_cast<QKeyEvent *>(e); + kdDebug(90180) << " acceloverride " << ke->key() << " o " << o->name() << endl; + + if (o == m_listView) { // DOM tree + KKey ks = mainWindow()->deleteNodeAction()->shortcut().seq(0).key(0); + if (ke->key() == ks.keyCodeQt()) + return true; + + } else if (o == nodeAttributes) { + KKey ks = mainWindow()->deleteAttributeAction()->shortcut().seq(0).key(0); + if (ke->key() == ks.keyCodeQt()) + return true; + + } + + } else if (e->type() == QEvent::FocusIn) { + + kdDebug(90180) << " focusin o " << o->name() << endl; + if (o != this) { + focused_child = o; + } + + } else if (e->type() == QEvent::FocusOut) { + + kdDebug(90180) << " focusout o " << o->name() << endl; + if (o != this) { + focused_child = 0; + } + + } + + return false; +} + +void DOMTreeView::activateNode(const DOM::Node &node) +{ + slotShowNode(node); + initializeOptionsFromNode(node); +} + +void DOMTreeView::slotShowNode(const DOM::Node &pNode) +{ + + if (QListViewItem *item = m_itemdict[pNode.handle()]) { + m_listView->setCurrentItem(item); + m_listView->ensureItemVisible(item); + } +} + +void DOMTreeView::slotShowTree(const DOM::Node &pNode) +{ + DOM::Node child; + + m_listView->clear(); + m_itemdict.clear(); + + try + { + child = pNode.firstChild(); + } + catch (DOM::DOMException &) + { + return; + } + + while(!child.isNull()) { + showRecursive(0, child, 0); + child = child.nextSibling(); + } + + m_maxDepth--; + //kdDebug(90180) << " Max Depth: " << m_maxDepth << endl; +} + +void DOMTreeView::showRecursive(const DOM::Node &pNode, const DOM::Node &node, uint depth) +{ + DOMListViewItem *cur_item; + DOMListViewItem *parent_item = m_itemdict[pNode.handle()]; + + if (depth > m_maxDepth) { + m_maxDepth = depth; + } + + if (depth == 0) { + cur_item = new DOMListViewItem(node, m_listView); + m_document = pNode.ownerDocument(); + } else { + cur_item = new DOMListViewItem(node, parent_item); + } + + //kdDebug(90180) << node.nodeName().string() << " [" << depth << "]" << endl; + addElement (node, cur_item, false); + cur_item->setOpen(depth < m_expansionDepth); + + if(node.handle()) { + m_itemdict.insert(node.handle(), cur_item); + } + + DOM::Node child = node.lastChild(); + if (child.isNull()) { + DOM::HTMLFrameElement frame = node; + if (!frame.isNull()) child = frame.contentDocument().documentElement(); + } + while(!child.isNull()) { + showRecursive(node, child, depth + 1); + child = child.previousSibling(); + } + + const DOM::Element element = node; + if (!m_bPure) { + if (!element.isNull() && !element.firstChild().isNull()) { + if(depth == 0) { + cur_item = new DOMListViewItem(node, m_listView, cur_item); + m_document = pNode.ownerDocument(); + } else { + cur_item = new DOMListViewItem(node, parent_item, cur_item); + } + //kdDebug(90180) << "</" << node.nodeName().string() << ">" << endl; + addElement(element, cur_item, true); +// cur_item->setOpen(depth < m_expansionDepth); + } + } +} + +void DOMTreeView::addElement ( const DOM::Node &node, DOMListViewItem *cur_item, bool isLast) +{ + cur_item->setClosing(isLast); + + const QString nodeName(node.nodeName().string()); + QString text; + const DOM::Element element = node; + if (!element.isNull()) { + if (!m_bPure) { + if (isLast) { + text ="</"; + } else { + text = "<"; + } + text += nodeName; + } else { + text = nodeName; + } + + if (m_bShowAttributes && !isLast) { + QString attributes; + DOM::Attr attr; + DOM::NamedNodeMap attrs = element.attributes(); + unsigned long lmap = attrs.length(); + for( unsigned int j=0; j<lmap; j++ ) { + attr = static_cast<DOM::Attr>(attrs.item(j)); + attributes += " " + attr.name().string() + "=\"" + attr.value().string() + "\""; + } + if (!(attributes.isEmpty())) { + text += " "; + } + text += attributes.simplifyWhiteSpace(); + } + + if (!m_bPure) { + if(element.firstChild().isNull()) { + text += "/>"; + } else { + text += ">"; + } + } + cur_item->setText(0, text); + } else { + text = "`" + node.nodeValue().string() + "'"; + + // Hacks to deal with PRE + QTextStream ts( text, IO_ReadOnly ); + while (!ts.eof()) { + const QString txt(ts.readLine()); + const QFont font(KGlobalSettings::fixedFont()); + cur_item->setFont( font ); + cur_item->setText(0, txt); + + if(node.handle()) { + m_itemdict.insert(node.handle(), cur_item); + } + + DOMListViewItem *parent; + if (cur_item->parent()) { + parent = static_cast<DOMListViewItem *>(cur_item->parent()); + } else { + parent = cur_item; + } + cur_item = new DOMListViewItem(node, parent, cur_item); + } + // This is one is too much + DOMListViewItem *notLastItem = static_cast<DOMListViewItem *>(cur_item->itemAbove()); + delete cur_item; + cur_item = notLastItem; + } + + if (m_bHighlightHTML && node.ownerDocument().isHTMLDocument()) { + highlightHTML(cur_item, nodeName); + } +} + +void DOMTreeView::highlightHTML(DOMListViewItem *cur_item, const QString &nodeName) +{ + /* This is slow. I could make it O(1) be using the tokenizer of khtml but I don't + * think it's worth it. + */ + + QColor namedColor(palette().active().text()); + QString tagName = nodeName.upper(); + if ( tagName == "HTML" ) { + namedColor = "#0000ff"; + cur_item->setBold(true); + } else if ( tagName == "HEAD" ) { + namedColor = "#0022ff"; + cur_item->setBold(true); + + } else if ( tagName == "TITLE" ) { + namedColor = "#2200ff"; + } else if ( tagName == "SCRIPT" ) { + namedColor = "#4400ff"; + } else if ( tagName == "NOSCRIPT" ) { + namedColor = "#0044ff"; + } else if ( tagName == "STYLE" ) { + namedColor = "#0066ff"; + } else if ( tagName == "LINK" ) { + namedColor = "#6600ff"; + } else if ( tagName == "META" ) { + namedColor = "#0088ff"; + + } else if ( tagName == "BODY" ) { + namedColor = "#ff0000"; + cur_item->setBold(true); + } else if ( tagName == "A") { + namedColor = "blue"; + cur_item->setUnderline(true); + } else if ( tagName == "IMG") { + namedColor = "magenta"; + cur_item->setUnderline(true); + + } else if ( tagName == "DIV" ) { + namedColor = "#ff0044"; + } else if ( tagName == "SPAN" ) { + namedColor = "#ff4400"; + } else if ( tagName == "P" ) { + namedColor = "#ff0066"; + + } else if ( tagName == "DL" || tagName == "OL"|| tagName == "UL" || tagName == "TABLE" ) { + namedColor = "#880088"; + } else if ( tagName == "LI" ) { + namedColor = "#884488"; + } else if ( tagName == "TBODY" ){ + namedColor = "#888888"; + } else if ( tagName == "TR" ) { + namedColor = "#882288"; + } else if ( tagName == "TD" ) { + namedColor = "#886688"; + + } else if ((tagName == "H1")||(tagName == "H2")||(tagName == "H3") || + (tagName == "H4")||(tagName == "H5")||(tagName == "H6")) { + namedColor = "#008800"; + } else if (tagName == "HR" ) { + namedColor = "#228822"; + + } else if ( tagName == "FRAME" || tagName == "IFRAME" ) { + namedColor = "#ff22ff"; + } else if ( tagName == "FRAMESET" ) { + namedColor = "#dd22dd"; + + } else if ( tagName == "APPLET" || tagName == "OBJECT" ) { + namedColor = "#bb22bb"; + + } else if ( tagName == "BASEFONT" || tagName == "FONT" ) { + namedColor = "#097200"; + + } else if ( tagName == "B" || tagName == "STRONG" ) { + cur_item->setBold(true); + } else if ( tagName == "I" || tagName == "EM" ) { + cur_item->setItalic(true); + } else if ( tagName == "U") { + cur_item->setUnderline(true); + } + + cur_item->setColor(namedColor); +} + +void DOMTreeView::slotItemClicked(QListViewItem *cur_item) +{ + DOMListViewItem *cur = static_cast<DOMListViewItem *>(cur_item); + if (!cur) return; + + DOM::Node handle = cur->node(); + if (!handle.isNull()) { + part->setActiveNode(handle); + } +} + +void DOMTreeView::slotFindClicked() +{ + if (m_findDialog == 0) { + m_findDialog = new KEdFind(this); + connect(m_findDialog, SIGNAL(search()), this, SLOT(slotSearch())); + } + m_findDialog->show(); +} + +void DOMTreeView::slotRefreshNode(const DOM::Node &pNode) +{ + DOMListViewItem *cur = static_cast<DOMListViewItem *>(m_itemdict[pNode.handle()]); + if (!cur) return; + + addElement(pNode, cur, false); +} + +void DOMTreeView::slotPrepareMove() +{ + DOMListViewItem *item = static_cast<DOMListViewItem *>(m_listView->currentItem()); + + if (!item) + current_node = DOM::Node(); + else + current_node = item->node(); +} + +void DOMTreeView::slotMovedItems(QPtrList<QListViewItem> &items, QPtrList<QListViewItem> &/*afterFirst*/, QPtrList<QListViewItem> &afterNow) +{ + MultiCommand *cmd = new MultiCommand(i18n("Move Nodes")); + _refreshed = false; + + QPtrList<QListViewItem>::Iterator it = items.begin(); + QPtrList<QListViewItem>::Iterator anit = afterNow.begin(); + for (; it != items.end(); ++it, ++anit) { + DOMListViewItem *item = static_cast<DOMListViewItem *>(*it); + DOMListViewItem *anitem = static_cast<DOMListViewItem *>(*anit); + DOM::Node parent = static_cast<DOMListViewItem *>(item->parent())->node(); + Q_ASSERT(!parent.isNull()); + +// kdDebug(90180) << " afternow " << anitem << " node " << (anitem ? anitem->node().nodeName().string() : QString()) << "=" << (anitem ? anitem->node().nodeValue().string() : QString()) << endl; + + cmd->addCommand(new MoveNodeCommand(item->node(), parent, + anitem ? anitem->node().nextSibling() : parent.firstChild()) + ); + } + + mainWindow()->executeAndAddCommand(cmd); + + // refresh *anyways*, otherwise consistency is disturbed + if (!_refreshed) refresh(); + + slotShowNode(current_node); +} + +void DOMTreeView::slotSearch() +{ + assert(m_findDialog); + const QString& searchText = m_findDialog->getText(); + bool caseSensitive = m_findDialog->case_sensitive(); + + searchRecursive(static_cast<DOMListViewItem*>(m_rootListView->firstChild()), + searchText, caseSensitive); + + m_findDialog->hide(); +} + +void DOMTreeView::searchRecursive(DOMListViewItem* cur_item, const QString& searchText, + bool caseSensitive) +{ + const QString text(cur_item->text(0)); + if (text.contains(searchText, caseSensitive) > 0) { + cur_item->setUnderline(true); + cur_item->setItalic(true); + m_listView->setCurrentItem(cur_item); + m_listView->ensureItemVisible(cur_item); + } else { + cur_item->setOpen(false); + } + + DOMListViewItem* child = static_cast<DOMListViewItem *>(cur_item->firstChild()); + while( child ) { + searchRecursive(child, searchText, caseSensitive); + child = static_cast<DOMListViewItem *>(child->nextSibling()); + } +} + +#if 0 +void DOMTreeView::slotSaveClicked() +{ + //kdDebug(90180) << "void KfingerCSSWidget::slotSaveAs()" << endl; + KURL url = KFileDialog::getSaveFileName( part->url().url(), "*.html", + this, i18n("Save DOM Tree as HTML") ); + if (!(url.isEmpty()) && url.isValid()) { + QFile file(url.path()); + + if (file.exists()) { + const QString title = i18n( "File Exists" ); + const QString text = i18n( "Do you really want to overwrite: \n%1?" ).arg(url.url()); + if (KMessageBox::Continue != KMessageBox::warningContinueCancel(this, text, title, i18n("Overwrite") ) ) { + return; + } + } + + if (file.open(IO_WriteOnly) ) { + kdDebug(90180) << "Opened File: " << url.url() << endl; + m_textStream = new QTextStream(&file); //(stdOut) + saveTreeAsHTML(part->document()); + file.close(); + kdDebug(90180) << "File closed " << endl; + delete m_textStream; + } else { + const QString title = i18n( "Unable to Open File" ); + const QString text = i18n( "Unable to open \n %1 \n for writing" ).arg(url.path()); + KMessageBox::sorry( this, text, title ); + } + } else { + const QString title = i18n( "Invalid URL" ); + const QString text = i18n( "This URL \n %1 \n is not valid." ).arg(url.url()); + KMessageBox::sorry( this, text, title ); + } +} + +void DOMTreeView::saveTreeAsHTML(const DOM::Node &pNode) +{ + assert(m_textStream); + + // Add a doctype + + (*m_textStream) <<"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">" << endl; + if(pNode.ownerDocument().isNull()) { + saveRecursive(pNode, 0); + } else { + saveRecursive(pNode.ownerDocument(), 0); + } +} + +void DOMTreeView::saveRecursive(const DOM::Node &pNode, int indent) +{ + const QString nodeName(pNode.nodeName().string()); + QString text; + QString strIndent; + strIndent.fill(' ', indent); + const DOM::Element element = static_cast<const DOM::Element>(pNode); + + text = strIndent; + + if ( !element.isNull() ) { + if (nodeName.at(0)=='-') { + /* Don't save khtml internal tags '-konq..' + * Approximating it with <DIV> + */ + text += "<DIV> <!-- -KONG_BLOCK -->"; + } else { + text += "<" + nodeName; + + QString attributes; + DOM::Attr attr; + const DOM::NamedNodeMap attrs = element.attributes(); + unsigned long lmap = attrs.length(); + for( uint j=0; j<lmap; j++ ) { + attr = static_cast<DOM::Attr>(attrs.item(j)); + attributes += " " + attr.name().string() + "=\"" + attr.value().string() + "\""; + } + if (!(attributes.isEmpty())){ + text += " "; + } + + text += attributes.simplifyWhiteSpace(); + + if(element.firstChild().isNull()) { + text += "/>"; + } else { + text += ">"; + } + } + } else { + text = strIndent + pNode.nodeValue().string(); + } + + kdDebug(90180) << text << endl; + if (!(text.isEmpty())) { + (*m_textStream) << text << endl; + } + + DOM::Node child = pNode.firstChild(); + while(!child.isNull()) { + saveRecursive(child, indent+2); + child = child.nextSibling(); + } + + if (!(element.isNull()) && (!(element.firstChild().isNull()))) { + if (nodeName.at(0)=='-') { + text = strIndent + "</DIV> <!-- -KONG_BLOCK -->"; + } else { + text = strIndent + "</" + pNode.nodeName().string() + ">"; + } + kdDebug(90180) << text << endl; + (*m_textStream) << text << endl; + } +} +#endif + +void DOMTreeView::updateIncrDecreaseButton() +{ +#if 0 + m_decreaseButton->setEnabled((m_expansionDepth > 0)); + m_increaseButton->setEnabled((m_expansionDepth < m_maxDepth)); +#endif +} + +void DOMTreeView::refresh() +{ + if (!part) return; + scroll_ofs_x = m_listView->contentsX(); + scroll_ofs_y = m_listView->contentsY(); + + m_listView->setUpdatesEnabled(false); + slotShowTree(part->document()); + + QTimer::singleShot(0, this, SLOT(slotRestoreScrollOffset())); + _refreshed = true; +} + +void DOMTreeView::increaseExpansionDepth() +{ + if (!part) return; + if (m_expansionDepth < m_maxDepth) { + ++m_expansionDepth; + adjustDepth(); + updateIncrDecreaseButton(); + } else { + QApplication::beep(); + } +} + +void DOMTreeView::decreaseExpansionDepth() +{ + if (!part) return; + if (m_expansionDepth > 0) { + --m_expansionDepth; + adjustDepth(); + updateIncrDecreaseButton(); + } else { + QApplication::beep(); + } +} + +void DOMTreeView::adjustDepth() +{ + // get current item in a hypersmart way + DOMListViewItem *cur_node_item = m_itemdict[infoNode.handle()]; + if (!cur_node_item) + cur_node_item = static_cast<DOMListViewItem *>(m_listView->currentItem()); + + adjustDepthRecursively(m_rootListView->firstChild(), 0); + + // make current item visible again if possible + if (cur_node_item) + m_listView->ensureVisible(0, cur_node_item->itemPos()); + +} + +void DOMTreeView::adjustDepthRecursively(QListViewItem *cur_item, uint currDepth) +{ + if (!(cur_item == 0)) { + while( cur_item ) { + cur_item->setOpen( (m_expansionDepth > currDepth) ); + adjustDepthRecursively(cur_item->firstChild(), currDepth+1); + cur_item = cur_item->nextSibling(); + } + } +} + +void DOMTreeView::setMessage(const QString &msg) +{ + messageLine->setText(msg); + messageLinePane->show(); +} + +void DOMTreeView::hideMessageLine() +{ + messageLinePane->hide(); +} + +void DOMTreeView::moveToParent() +{ + // This is a hypersmart algorithm. + // If infoNode is defined, go to the parent of infoNode, otherwise, go + // to the parent of the tree view's current item. + // Hope this isn't too smart. + + DOM::Node cur = infoNode; + if (cur.isNull()) cur = static_cast<DOMListViewItem *>(m_listView->currentItem())->node(); + + if (cur.isNull()) return; + + cur = cur.parentNode(); + activateNode(cur); +} + +void DOMTreeView::showDOMTreeContextMenu(QListViewItem */*lvi*/, const QPoint &pos, int /*col*/) +{ + QPopupMenu *ctx = mainWindow()->domTreeViewContextMenu(); + Q_ASSERT(ctx); + ctx->popup(pos); +} + +void DOMTreeView::slotPureToggled(bool b) +{ + m_bPure = b; + refresh(); +} + +void DOMTreeView::slotShowAttributesToggled(bool b) +{ + m_bShowAttributes = b; + refresh(); +} + +void DOMTreeView::slotHighlightHTMLToggled(bool b) +{ + m_bHighlightHTML = b; + refresh(); +} + +void DOMTreeView::deleteNodes() +{ +// kdDebug(90180) << k_funcinfo << endl; + + DOM::Node last; + MultiCommand *cmd = new MultiCommand(i18n("Delete Nodes")); + QListViewItemIterator it(m_listView, QListViewItemIterator::Selected); + for (; *it; ++it) { + DOMListViewItem *item = static_cast<DOMListViewItem *>(*it); +// kdDebug(90180) << " item->node " << item->node().nodeName().string() << " clos " << item->isClosing() << endl; + if (item->isClosing()) continue; + + // don't regard node more than once + if (item->node() == last) continue; + + // check for selected parent + bool has_selected_parent = false; + for (QListViewItem *p = item->parent(); p; p = p->parent()) { + if (p->isSelected()) { has_selected_parent = true; break; } + } + if (has_selected_parent) continue; + +// kdDebug(90180) << " item->node " << item->node().nodeName().string() << ": schedule for removal" << endl; + // remove this node if it isn't already recursively removed by its parent + cmd->addCommand(new RemoveNodeCommand(item->node(), item->node().parentNode(), item->node().nextSibling())); + last = item->node(); + } + mainWindow()->executeAndAddCommand(cmd); +} + +void DOMTreeView::disconnectFromTornDownPart() +{ + if (!part) return; + + m_listView->clear(); + initializeOptionsFromNode(DOM::Node()); + + // remove all references to nodes + infoNode = DOM::Node(); // ### have this handled by dedicated info node panel method + current_node = DOM::Node(); + active_node_rule = DOM::CSSRule(); + stylesheet = DOM::CSSStyleSheet(); +} + +void DOMTreeView::connectToPart() +{ + if (part) { + connect(part, SIGNAL(nodeActivated(const DOM::Node &)), this, + SLOT(activateNode(const DOM::Node &))); + connect(part, SIGNAL(completed()), this, SLOT(refresh())); + + // insert a style rule to indicate activated nodes + try { +kdDebug(90180) << "(1) part.document: " << part->document().handle() << endl; + stylesheet = part->document().implementation().createCSSStyleSheet("-domtreeviewer-style", "screen"); +kdDebug(90180) << "(2)" << endl; + stylesheet.insertRule(":focus { outline: medium #f00 solid }", 0); + // ### for testing only +// stylesheet.insertRule("body { background: #f0f !important }", 1); +kdDebug(90180) << "(3)" << endl; + active_node_rule = stylesheet.cssRules().item(0); +kdDebug(90180) << "(4)" << endl; + part->document().addStyleSheet(stylesheet); +kdDebug(90180) << "(5)" << endl; + } catch (DOM::CSSException &ex) { + kdDebug(90180) << "CSS Exception " << ex.code << endl; + } catch (DOM::DOMException &ex) { + kdDebug(90180) << "DOM Exception " << ex.code << endl; + } + } + + slotShowTree(part ? (DOM::Node)part->document() : DOM::Node()); + updateIncrDecreaseButton(); +} + +void DOMTreeView::disconnectFromActivePart() +{ + if (!part) return; + + // remove style sheet + try { + part->document().removeStyleSheet(stylesheet); + } catch (DOM::CSSException &ex) { + kdDebug(90180) << "CSS Exception " << ex.code << endl; + } catch (DOM::DOMException &ex) { + kdDebug(90180) << "DOM Exception " << ex.code << endl; + } + +} + +void DOMTreeView::slotSetHtmlPartDelayed() +{ + connectToPart(); + emit htmlPartChanged(part); +} + +void DOMTreeView::slotRestoreScrollOffset() +{ + m_listView->setUpdatesEnabled(true); + m_listView->setContentsPos(scroll_ofs_x, scroll_ofs_y); +} + +void DOMTreeView::slotAddElementDlg() +{ + DOMListViewItem *item = static_cast<DOMListViewItem *>(m_listView->currentItem()); + if (!item) return; + + QString qname; + QString namespc; + SignalReceiver addBefore; + + { + ElementEditDialog dlg(this, "ElementEditDialog", true); + connect(dlg.insBeforeBtn, SIGNAL(clicked()), &addBefore, SLOT(slot())); + + // ### activate when namespaces are supported + dlg.elemNamespace->setEnabled(false); + + if (dlg.exec() != QDialog::Accepted) return; + + qname = dlg.elemName->text(); + namespc = dlg.elemNamespace->currentText(); + } + + DOM::Node curNode = item->node(); + + try { + DOM::Node parent = addBefore() ? curNode.parentNode() : curNode; + DOM::Node after = addBefore() ? curNode : 0; + + // ### take namespace into account + DOM::Node newNode = curNode.ownerDocument().createElement(qname); + + ManipulationCommand *cmd = new InsertNodeCommand(newNode, parent, after); + mainWindow()->executeAndAddCommand(cmd); + + if (cmd->isValid()) activateNode(newNode); + + } catch (DOM::DOMException &ex) { + mainWindow()->addMessage(ex.code, domErrorMessage(ex.code)); + } +} + +void DOMTreeView::slotAddTextDlg() +{ + DOMListViewItem *item = static_cast<DOMListViewItem *>(m_listView->currentItem()); + if (!item) return; + + QString text; + SignalReceiver addBefore; + + { + TextEditDialog dlg(this, "TextEditDialog", true); + connect(dlg.insBeforeBtn, SIGNAL(clicked()), &addBefore, SLOT(slot())); + + if (dlg.exec() != QDialog::Accepted) return; + + text = dlg.textPane->text(); + } + + DOM::Node curNode = item->node(); + + try { + DOM::Node parent = addBefore() ? curNode.parentNode() : curNode; + DOM::Node after = addBefore() ? curNode : 0; + + DOM::Node newNode = curNode.ownerDocument().createTextNode(text); + + ManipulationCommand *cmd = new InsertNodeCommand(newNode, parent, after); + mainWindow()->executeAndAddCommand(cmd); + + if (cmd->isValid()) activateNode(newNode); + + } catch (DOM::DOMException &ex) { + mainWindow()->addMessage(ex.code, domErrorMessage(ex.code)); + } +} + +// == DOM Node info panel ============================================= + +static QString *clickToAdd; + +/** + * List view item for attribute list. + */ +class AttributeListItem : public QListViewItem +{ + typedef QListViewItem super; + + bool _new; + +public: + AttributeListItem(QListView *parent, QListViewItem *prev) + : super(parent, prev), _new(true) + { + } + + AttributeListItem(const QString &attrName, const QString &attrValue, + QListView *parent, QListViewItem *prev) + : super(parent, prev), _new(false) + { + setText(0, attrName); + setText(1, attrValue); + } + + bool isNew() const { return _new; } + void setNew(bool s) { _new = s; } + + virtual int compare(QListViewItem *item, int column, bool ascend) const + { + return _new ? 1 : super::compare(item, column, ascend); + } + +protected: + virtual void paintCell( QPainter *p, const QColorGroup &cg, + int column, int width, int alignment ) + { + bool updates_enabled = listView()->isUpdatesEnabled(); + listView()->setUpdatesEnabled(false); + + QColor c = cg.text(); + bool text_changed = false; + QString oldText; + + if (_new) { + c = QApplication::palette().color( QPalette::Disabled, QColorGroup::Text ); + + if (!clickToAdd) clickToAdd = new QString(i18n("<Click to add>")); + oldText = text(column); + text_changed = true; + if (column == 0) setText(0, *clickToAdd); else setText(1, QString()); + } + + QColorGroup _cg( cg ); + _cg.setColor( QColorGroup::Text, c ); + super::paintCell( p, _cg, column, width, alignment ); + + if (text_changed) setText(column, oldText); + listView()->setUpdatesEnabled(updates_enabled); + } + +}; + +void DOMTreeView::initDOMNodeInfo() +{ + connect(m_listView, SIGNAL(clicked(QListViewItem *)), + SLOT(initializeOptionsFromListItem(QListViewItem *))); + + connect(nodeAttributes, SIGNAL(itemRenamed(QListViewItem *, const QString &, int)), + SLOT(slotItemRenamed(QListViewItem *, const QString &, int))); + connect(nodeAttributes, SIGNAL(executed(QListViewItem *, const QPoint &, int)), + SLOT(slotEditAttribute(QListViewItem *, const QPoint &, int))); + connect(nodeAttributes, SIGNAL(contextMenuRequested(QListViewItem *, const QPoint &, int)), + SLOT(showInfoPanelContextMenu(QListViewItem *, const QPoint &, int))); + + connect(applyContent, SIGNAL(clicked()), SLOT(slotApplyContent())); + + ManipulationCommand::connect(SIGNAL(nodeChanged(const DOM::Node &)), this, SLOT(initializeOptionsFromNode(const DOM::Node &))); + + nodeAttributes->setRenameable(0, true); + nodeAttributes->setRenameable(1, true); + + nodeInfoStack->raiseWidget(EmptyPanel); + + installEventFilter(nodeAttributes); +} + +void DOMTreeView::initializeOptionsFromNode(const DOM::Node &node) +{ + infoNode = node; + + nodeName->clear(); + nodeType->clear(); + nodeNamespace->clear(); + nodeValue->clear(); + + if (node.isNull()) { + nodeInfoStack->raiseWidget(EmptyPanel); + return; + } + + nodeName->setText(node.nodeName().string()); + nodeType->setText(QString::number(node.nodeType())); + nodeNamespace->setText(node.namespaceURI().string()); +// nodeValue->setText(node.value().string()); + + DOM::Element element = node; + if (!element.isNull()) { + initializeOptionsFromElement(element); + return; + } + + DOM::CharacterData cdata = node; + if (!cdata.isNull()) { + initializeOptionsFromCData(cdata); + return; + } + + // Fallback + nodeInfoStack->raiseWidget(EmptyPanel); +} + +void DOMTreeView::initializeOptionsFromListItem(QListViewItem *item) +{ + const DOMListViewItem *cur_item = static_cast<const DOMListViewItem *>(item); + +// kdDebug(90180) << "cur_item: " << cur_item << endl; + initializeOptionsFromNode(cur_item ? cur_item->node() : DOM::Node()); +} + +void DOMTreeView::initializeOptionsFromElement(const DOM::Element &element) +{ + QListViewItem *last = 0; + nodeAttributes->clear(); + + DOM::NamedNodeMap attrs = element.attributes(); + unsigned long lmap = attrs.length(); + for (unsigned int j = 0; j < lmap; j++) { + DOM::Attr attr = attrs.item(j); +// kdDebug(90180) << attr.name().string() << "=" << attr.value().string() << endl; + QListViewItem *item = new AttributeListItem(attr.name().string(), + attr.value().string(), nodeAttributes, last); + last = item; + } + + // append new item + last = new AttributeListItem(nodeAttributes, last); + + nodeInfoStack->raiseWidget(ElementPanel); +} + +void DOMTreeView::initializeOptionsFromCData(const DOM::CharacterData &cdata) +{ + contentEditor->setText(cdata.data().string()); + + DOM::Text text = cdata; + contentEditor->setEnabled(!text.isNull()); + + nodeInfoStack->raiseWidget(CDataPanel); +} + +void DOMTreeView::slotItemRenamed(QListViewItem *lvi, const QString &str, int col) +{ + AttributeListItem *item = static_cast<AttributeListItem *>(lvi); + + DOM::Element element = infoNode; + if (element.isNull()) return; // Should never happen + + switch (col) { + case 0: { + ManipulationCommand *cmd; +// kdDebug(90180) << k_funcinfo << "col 0: " << element.nodeName() << " isNew: " << item->isNew() << endl; + if (item->isNew()) { + cmd = new AddAttributeCommand(element, str, item->text(1)); + item->setNew(false); + } else + cmd = new RenameAttributeCommand(element, item->text(0), str); + + mainWindow()->executeAndAddCommand(cmd); + break; + } + case 1: { + if (item->isNew()) { lvi->setText(1, QString()); break; } + + ChangeAttributeValueCommand *cmd = new ChangeAttributeValueCommand( + element, item->text(0), str); + mainWindow()->executeAndAddCommand(cmd); + break; + } + } +} + +void DOMTreeView::slotEditAttribute(QListViewItem *lvi, const QPoint &, int col) +{ + if (!lvi) return; + + QString attrName = lvi->text(0); + QString attrValue = lvi->text(1); + int res = 0; + + { + AttributeEditDialog dlg(this, "AttributeEditDialog", true); + dlg.attrName->setText(attrName); + dlg.attrValue->setText(attrValue); + + if (col == 0) { + dlg.attrName->setFocus(); + dlg.attrName->selectAll(); + } else { + dlg.attrValue->setFocus(); + dlg.attrValue->selectAll(); + } + + res = dlg.exec(); + + attrName = dlg.attrName->text(); + attrValue = dlg.attrValue->text(); + } + +// kdDebug(90180) << "name=" << attrName << " value=" << attrValue << endl; + + if (res == QDialog::Accepted) do { + if (attrName.isEmpty()) break; + + if (lvi->text(0) != attrName) { + // hack: set value to assign attribute/value pair in one go + lvi->setText(1, attrValue); + + slotItemRenamed(lvi, attrName, 0); + // Reget, item may have been changed + lvi = nodeAttributes->findItem(attrName, 0); + } + + if (lvi && lvi->text(1) != attrValue) + slotItemRenamed(lvi, attrValue, 1); + + } while(false) /*end if*/; +} + + +void DOMTreeView::slotApplyContent() +{ + DOM::CharacterData cdata = infoNode; + + if (cdata.isNull()) return; + + ManipulationCommand *cmd = new ChangeCDataCommand(cdata, contentEditor->text()); + mainWindow()->executeAndAddCommand(cmd); +} + +void DOMTreeView::showInfoPanelContextMenu(QListViewItem */*lvi*/, const QPoint &pos, int /*col*/) +{ + QPopupMenu *ctx = mainWindow()->infoPanelAttrContextMenu(); + Q_ASSERT(ctx); + ctx->popup(pos); +} + +void DOMTreeView::copyAttributes() +{ + // TODO implement me +} + +void DOMTreeView::cutAttributes() +{ + // TODO implement me +} + +void DOMTreeView::pasteAttributes() +{ + // TODO implement me +} + +void DOMTreeView::deleteAttributes() +{ + MultiCommand *cmd = new MultiCommand(i18n("Delete Attributes")); + QListViewItemIterator it(nodeAttributes, QListViewItemIterator::Selected); + for (; *it; ++it) { + AttributeListItem *item = static_cast<AttributeListItem *>(*it); + if (item->isNew()) continue; + + cmd->addCommand(new RemoveAttributeCommand(infoNode, item->text(0))); + } + mainWindow()->executeAndAddCommand(cmd); +} + +#include "domtreeview.moc" diff --git a/konq-plugins/domtreeviewer/domtreeview.h b/konq-plugins/domtreeviewer/domtreeview.h new file mode 100644 index 0000000..0e9977d --- /dev/null +++ b/konq-plugins/domtreeviewer/domtreeview.h @@ -0,0 +1,203 @@ +/*************************************************************************** + domtreeview.h + ------------------- + + copyright : (C) 2001 - The Kafka Team/Andreas Schlapbach + (C) 2005 - Leo Savernik + email : kde-kafka@master.kde.org + schlpbch@iam.unibe.ch + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +/* $Id$ */ + +#ifndef DOMTREEVIEW_H +#define DOMTREEVIEW_H + +#include <qptrdict.h> +#include <qptrlist.h> +#include <dom/css_stylesheet.h> +#include <dom/css_rule.h> +#include <dom/dom_node.h> + +#include "domtreeviewbase.h" + +namespace DOM { + class Element; + class CharacterData; +} + +class DOMListViewItem; +class DOMTreeWindow; + +class QListViewItem; + +class KPushButton; +class KEdFind; +class KHTMLPart; + +class DOMTreeView : public DOMTreeViewBase +{ + Q_OBJECT + + public: + DOMTreeView(QWidget *parent, const char* name, bool allowSaving = true); + ~DOMTreeView(); + + KHTMLPart *htmlPart() const { return part; } + void setHtmlPart(KHTMLPart *); + + /** returns the main window */ + DOMTreeWindow *mainWindow() const; + + protected: + /* + void saveTreeAsHTML(const DOM::Node &pNode); + */ + virtual bool eventFilter(QObject *o, QEvent *e); + + signals: + /** emitted when the part has been changed. */ + void htmlPartChanged(KHTMLPart *part); + + public slots: + void refresh(); + void increaseExpansionDepth(); + void decreaseExpansionDepth(); + void setMessage(const QString &msg); + void hideMessageLine(); + + void moveToParent(); + + void activateNode(const DOM::Node &node); + void deleteNodes(); + + /** + * Takes measures to disconnect this instance from the current html + * part as long as it is active. + */ + void disconnectFromActivePart(); + + /** + * Takes measures to disconnect this instance from the current html + * part when it is being torn down. + */ + void disconnectFromTornDownPart(); + + /** + * Connects to the current html part. + */ + void connectToPart(); + + void slotFindClicked(); + void slotAddElementDlg(); + void slotAddTextDlg(); + + protected slots: + void slotShowNode(const DOM::Node &pNode); + void slotShowTree(const DOM::Node &pNode); + void slotItemClicked(QListViewItem *); + void slotRefreshNode(const DOM::Node &pNode); + void slotMovedItems(QPtrList<QListViewItem> &items, QPtrList<QListViewItem> &afterFirst, QPtrList<QListViewItem> &afterNow); + void slotPrepareMove(); + void slotSearch(); + + // void slotSaveClicked(); + + void slotPureToggled(bool); + void slotShowAttributesToggled(bool); + void slotHighlightHTMLToggled(bool); + + void showDOMTreeContextMenu(QListViewItem *, const QPoint &, int); + + void slotSetHtmlPartDelayed(); + void slotRestoreScrollOffset(); + + private: + QPtrDict<DOMListViewItem> m_itemdict; + DOM::Node m_document; + + uint m_expansionDepth, m_maxDepth; + bool m_bPure, m_bShowAttributes, m_bHighlightHTML; + + private: + void showRecursive(const DOM::Node &pNode, const DOM::Node &node, + uint depth); + + // void saveRecursive(const DOM::Node &node, int ident); + + void searchRecursive(DOMListViewItem *cur_item, + const QString &searchText, + bool caseSensitive); + + void adjustDepth(); + void adjustDepthRecursively(QListViewItem *cur_item, uint currDepth); + void highlightHTML(DOMListViewItem *cur_item, + const QString &nodeName); + + void addElement(const DOM::Node &node, DOMListViewItem *cur_item, + bool isLast); + void updateIncrDecreaseButton(); + + private: + KEdFind* m_findDialog; + + KHTMLPart *part; + QTextStream* m_textStream; + + const KListView* m_rootListView; + + KPushButton* m_saveButton; + QObject *focused_child; + DOM::Node current_node; + DOM::CSSStyleSheet stylesheet; + DOM::CSSRule active_node_rule; + + bool _refreshed; + int scroll_ofs_x, scroll_ofs_y; + + + // == DOM Node Info panel ====================================== + + public: + // Keep in sync with the widget stack children + enum InfoPanel { ElementPanel, CDataPanel, EmptyPanel }; + + public slots: + void initializeOptionsFromNode(const DOM::Node &); + void initializeOptionsFromListItem(QListViewItem *); + + void copyAttributes(); + void cutAttributes(); + void pasteAttributes(); + void deleteAttributes(); + + private: + void initDOMNodeInfo(); + + void initializeOptionsFromElement(const DOM::Element &); + void initializeOptionsFromCData(const DOM::CharacterData &); + + private slots: + void slotItemRenamed(QListViewItem *, const QString &str, int col); + void slotEditAttribute(QListViewItem *, const QPoint &, int col); + void slotApplyContent(); + + void showInfoPanelContextMenu(QListViewItem *, const QPoint &, int); + + private: + DOM::Node infoNode; // node these infos apply to + + // == End DOM Node Info panel ================================== + +}; + +#endif diff --git a/konq-plugins/domtreeviewer/domtreeviewbase.ui b/konq-plugins/domtreeviewer/domtreeviewbase.ui new file mode 100644 index 0000000..984e435 --- /dev/null +++ b/konq-plugins/domtreeviewer/domtreeviewbase.ui @@ -0,0 +1,525 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>DOMTreeViewBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>DOMTreeViewBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>508</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>600</width> + <height>380</height> + </size> + </property> + <property name="caption"> + <string>DOM Tree Viewer</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QFrame"> + <property name="name"> + <cstring>messageLinePane</cstring> + </property> + <property name="paletteBackgroundColor"> + <color> + <red>170</red> + <green>0</green> + <blue>127</blue> + </color> + </property> + <property name="frameShape"> + <enum>Panel</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>1</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="KLineEdit"> + <property name="name"> + <cstring>messageLine</cstring> + </property> + <property name="paletteForegroundColor"> + <color> + <red>255</red> + <green>255</green> + <blue>127</blue> + </color> + </property> + <property name="paletteBackgroundColor"> + <color> + <red>170</red> + <green>0</green> + <blue>127</blue> + </color> + </property> + <property name="font"> + <font> + <bold>1</bold> + </font> + </property> + <property name="frame"> + <bool>false</bool> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>messageListBtn</cstring> + </property> + <property name="font"> + <font> + <pointsize>10</pointsize> + </font> + </property> + <property name="text"> + <string>&List</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KPushButton"> + <property name="name"> + <cstring>messageHideBtn</cstring> + </property> + <property name="font"> + <font> + <pointsize>10</pointsize> + </font> + </property> + <property name="text"> + <string>H&ide</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout7</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KListView"> + <column> + <property name="text"> + <string>DOM Tree</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>m_listView</cstring> + </property> + <property name="acceptDrops"> + <bool>true</bool> + </property> + <property name="selectionMode" stdset="0"> + <enum>Extended</enum> + </property> + <property name="rootIsDecorated"> + <bool>true</bool> + </property> + <property name="dragEnabled"> + <bool>true</bool> + </property> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="minimumSize"> + <size> + <width>300</width> + <height>400</height> + </size> + </property> + <property name="title"> + <string>DOM Node Info</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel1_2_3</cstring> + </property> + <property name="text"> + <string>Node &value:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>nodeValue</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel1_2_2</cstring> + </property> + <property name="text"> + <string>Node &type:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>nodeType</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>Namespace &URI:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>nodeNamespace</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Node &name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>nodeName</cstring> + </property> + </widget> + <widget class="KLineEdit" row="1" column="1"> + <property name="name"> + <cstring>nodeNamespace</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="lineWidth"> + <number>0</number> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="KLineEdit" row="3" column="1"> + <property name="name"> + <cstring>nodeValue</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="lineWidth"> + <number>0</number> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>nodeType</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="lineWidth"> + <number>0</number> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>nodeName</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="lineWidth"> + <number>0</number> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <widget class="QWidgetStack"> + <property name="name"> + <cstring>nodeInfoStack</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>ElementInfo</cstring> + </property> + <attribute name="id"> + <number>0</number> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="KListView"> + <column> + <property name="text"> + <string>Name</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>nodeAttributes</cstring> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + <property name="selectionMode" stdset="0"> + <enum>Extended</enum> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="showSortIndicator"> + <bool>true</bool> + </property> + <property name="itemsMovable"> + <bool>false</bool> + </property> + </widget> + </vbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>CharacterData</cstring> + </property> + <attribute name="id"> + <number>1</number> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="KTextEdit"> + <property name="name"> + <cstring>contentEditor</cstring> + </property> + <property name="textFormat"> + <enum>PlainText</enum> + </property> + <property name="tabChangesFocus"> + <bool>false</bool> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>applyContent</cstring> + </property> + <property name="text"> + <string>Appl&y</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>81</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>Empty</cstring> + </property> + <attribute name="id"> + <number>2</number> + </attribute> + </widget> + </widget> + </vbox> + </widget> + </hbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox2</cstring> + </property> + <property name="title"> + <string>DOM Tree Options</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>m_pureCheckBox</cstring> + </property> + <property name="text"> + <string>&Pure</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>m_showAttributesCheckBox</cstring> + </property> + <property name="text"> + <string>Show &attributes</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>m_highlightHTMLCheckBox</cstring> + </property> + <property name="text"> + <string>Highlight &HTML</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<tabstops> + <tabstop>m_listView</tabstop> + <tabstop>nodeName</tabstop> + <tabstop>nodeNamespace</tabstop> + <tabstop>nodeType</tabstop> + <tabstop>nodeValue</tabstop> + <tabstop>contentEditor</tabstop> + <tabstop>applyContent</tabstop> + <tabstop>m_pureCheckBox</tabstop> + <tabstop>m_showAttributesCheckBox</tabstop> + <tabstop>m_highlightHTMLCheckBox</tabstop> + <tabstop>nodeAttributes</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>klistview.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klistview.h</includehint> + <includehint>ktextedit.h</includehint> +</includehints> +</UI> diff --git a/konq-plugins/domtreeviewer/domtreeviewerui.rc b/konq-plugins/domtreeviewer/domtreeviewerui.rc new file mode 100644 index 0000000..7249b63 --- /dev/null +++ b/konq-plugins/domtreeviewer/domtreeviewerui.rc @@ -0,0 +1,45 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="domtreeviewer" version="1"> +<MenuBar> + <Menu name="file"><text>&File</text> + </Menu> + <Menu name="edit"><text>&Edit</text> + </Menu> + <Menu name="view"><text>&View</text> + <WeakSeparator /> + <Action name="tree_inc_level" /> + <Action name="tree_dec_level" /> + <Separator /> + <Action name="show_msg_dlg" /> + </Menu> + <Menu name="go"><text>&Go</text> + <Action name="tree_up" /> + </Menu> +</MenuBar> +<ToolBar name="mainToolBar"><text>Main Toolbar</text> +</ToolBar> +<ToolBar name="treeToolBar"><text>Tree Toolbar</text> + <Action name="tree_up" /> + <Action name="view_redisplay" /> + <Separator /> + <Action name="tree_dec_level" /> + <Action name="tree_inc_level" /> +</ToolBar> +<Menu name="infopanelattr_context"> + <Action name="edit_cut" /> + <Action name="edit_copy" /> + <Action name="edit_paste" /> + <Separator /> + <Action name="attr_delete" /> +</Menu> +<Menu name="domtree_context"> + <Action name="tree_add_element" /> + <Action name="tree_add_text" /> + <Separator /> + <Action name="edit_cut" /> + <Action name="edit_copy" /> + <Action name="edit_paste" /> + <Separator /> + <Action name="tree_delete" /> +</Menu> +</kpartgui> diff --git a/konq-plugins/domtreeviewer/domtreewindow.cpp b/konq-plugins/domtreeviewer/domtreewindow.cpp new file mode 100644 index 0000000..f8b9ed5 --- /dev/null +++ b/konq-plugins/domtreeviewer/domtreewindow.cpp @@ -0,0 +1,379 @@ +/* This file is part of the KDE project + * + * Copyright (C) 2005 Leo Savernik <l.savernik@aon.at> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "domtreewindow.h" +#include "domtreeview.h" +#include "domtreecommands.h" +#include "messagedialog.h" +#include "plugin_domtreeviewer.h" + +#include <kaccel.h> +#include <kapplication.h> +#include <kcommand.h> +#include <kconfig.h> +#include <kdeversion.h> +#include <kglobal.h> +#include <khtml_part.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kmenubar.h> +#include <kstatusbar.h> +#include <kstandarddirs.h> +#include <ktextedit.h> +#include <kurl.h> +#include <kurldrag.h> +#include <kurlrequesterdlg.h> + +#include <kparts/partmanager.h> +#include <kparts/browserextension.h> + +#include <kedittoolbar.h> + +#include <kstdaccel.h> +#include <kaction.h> +#include <kstdaction.h> + +#include <qdatetime.h> +#include <qtimer.h> + +using domtreeviewer::ManipulationCommand; + +DOMTreeWindow::DOMTreeWindow(PluginDomtreeviewer *plugin) + : KMainWindow( 0, "DOMTreeWindow" ), + m_plugin(plugin), m_view(new DOMTreeView(this, "DOMTreeView", false)) +{ + part_manager = 0; + + // set configuration object + _config = new KConfig("domtreeviewerrc"); + + // accept dnd + setAcceptDrops(true); + + // tell the KMainWindow that this is indeed the main widget + setCentralWidget(m_view); + + // message window dialog + msgdlg = new MessageDialog(0, "MessageDialog"); + msgdlg->messagePane->setPaletteBackgroundColor(palette().active().base()); +// msgdlg->show(); + + // then, setup our actions + setupActions(); + + // Add typical actions and save size/toolbars/statusbar + setupGUI(ToolBar | Keys | StatusBar | Save | Create, + locate( "data", "domtreeviewer/domtreeviewerui.rc", instance())); + + // allow the view to change the statusbar and caption +#if 0 + connect(m_view, SIGNAL(signalChangeStatusbar(const QString&)), + this, SLOT(changeStatusbar(const QString&))); + connect(m_view, SIGNAL(signalChangeCaption(const QString&)), + this, SLOT(changeCaption(const QString&))); +#endif + connect(view(), SIGNAL(htmlPartChanged(KHTMLPart *)), + SLOT(slotHtmlPartChanged(KHTMLPart *))); + + ManipulationCommand::connect(SIGNAL(error(int, const QString &)), + this, SLOT(addMessage(int, const QString &))); + + infopanel_ctx = createInfoPanelAttrContextMenu(); + domtree_ctx = createDOMTreeViewContextMenu(); + +} + +DOMTreeWindow::~DOMTreeWindow() +{ + kdDebug(90180) << k_funcinfo << this << endl; + delete m_commandHistory; + delete msgdlg; + delete _config; +} + +void DOMTreeWindow::executeAndAddCommand(ManipulationCommand *cmd) +{ + cmd->execute(); + if (cmd->isValid()) { + m_commandHistory->addCommand(cmd, false); + view()->hideMessageLine(); + } +} + +void DOMTreeWindow::setupActions() +{ + KStdAction::close(this, SLOT(close()), actionCollection()); + + KStdAction::cut(this, SLOT(slotCut()), actionCollection())->setEnabled(false); + KStdAction::copy(this, SLOT(slotCopy()), actionCollection())->setEnabled(false); + KStdAction::paste(this, SLOT(slotPaste()), actionCollection())->setEnabled(false); + + m_commandHistory = new KCommandHistory(actionCollection()); + + KStdAction::find(this, SLOT(slotFind()), actionCollection()); + + KStdAction::redisplay(m_view, SLOT(refresh()), actionCollection()); + + // toggle manipulation dialog + KAction *showMsgDlg = new KAction(i18n("Show Message Log"), + CTRL+Key_E, actionCollection(), "show_msg_dlg"); + connect(showMsgDlg, SIGNAL(activated()), SLOT(showMessageLog())); + +// KAction *custom = new KAction(i18n("Cus&tom Menuitem"), 0, +// this, SLOT(optionsPreferences()), +// actionCollection(), "custom_action"); + + // actions for the dom tree list view toolbar + KStdAction::up(view(), SLOT(moveToParent()), actionCollection(), "tree_up"); + KAction *tree_inc_level = new KAction(i18n("Expand"), + "1rightarrow", CTRL+Key_Greater, view(), + SLOT(increaseExpansionDepth()), actionCollection(), + "tree_inc_level"); + tree_inc_level->setToolTip(i18n("Increase expansion level")); + KAction *tree_dec_level = new KAction(i18n("Collapse"), + "1leftarrow", CTRL+Key_Less, view(), + SLOT(decreaseExpansionDepth()), actionCollection(), + "tree_dec_level"); + tree_dec_level->setToolTip(i18n("Decrease expansion level")); + + // actions for the dom tree list view context menu + + del_tree = new KAction(i18n("&Delete"), "editdelete", + Key_Delete, view(), SLOT(deleteNodes()), + actionCollection(), "tree_delete"); + del_tree->setToolTip(i18n("Delete nodes")); + /*KAction *new_elem = */new KAction(i18n("New &Element ..."), + "bookmark", KShortcut(), view(), + SLOT(slotAddElementDlg()), actionCollection(), + "tree_add_element"); + /*KAction *new_text = */new KAction(i18n("New &Text Node ..."), + "text", KShortcut(), view(), SLOT(slotAddTextDlg()), + actionCollection(), "tree_add_text"); + + // actions for the info panel attribute list context menu + del_attr = new KAction(i18n("&Delete"), "editdelete", + Key_Delete, view(), SLOT(deleteAttributes()), + actionCollection(), "attr_delete"); + del_attr->setToolTip(i18n("Delete attributes")); + +} + +QPopupMenu *DOMTreeWindow::createInfoPanelAttrContextMenu() +{ + QWidget *w = factory()->container("infopanelattr_context", this); + Q_ASSERT(w); + return static_cast<QPopupMenu *>(w); +} + +QPopupMenu *DOMTreeWindow::createDOMTreeViewContextMenu() +{ + QWidget *w = factory()->container("domtree_context", this); + Q_ASSERT(w); + return static_cast<QPopupMenu *>(w); +} + +void DOMTreeWindow::saveProperties(KConfig *config) +{ + // the 'config' object points to the session managed + // config file. anything you write here will be available + // later when this app is restored + +#if 0 + if (!m_view->currentURL().isNull()) { +#if KDE_IS_VERSION(3,1,3) + config->writePathEntry("lastURL", m_view->currentURL()); +#else + config->writeEntry("lastURL", m_view->currentURL()); +#endif + } +#endif +} + +void DOMTreeWindow::readProperties(KConfig *config) +{ + // the 'config' object points to the session managed + // config file. this function is automatically called whenever + // the app is being restored. read in here whatever you wrote + // in 'saveProperties' + +#if 0 + QString url = config->readPathEntry("lastURL"); + + if (!url.isEmpty()) + m_view->openURL(KURL::fromPathOrURL(url)); +#endif +} + +void DOMTreeWindow::dragEnterEvent(QDragEnterEvent *event) +{ + // accept uri drops only + event->accept(KURLDrag::canDecode(event)); +} + +void DOMTreeWindow::dropEvent(QDropEvent *event) +{ + // this is a very simplistic implementation of a drop event. we + // will only accept a dropped URL. the Qt dnd code can do *much* + // much more, so please read the docs there + KURL::List urls; + + // see if we can decode a URI.. if not, just ignore it + if (KURLDrag::decode(event, urls) && !urls.isEmpty()) + { + // okay, we have a URI.. process it + const KURL &url = urls.first(); +#if 0 + // load in the file + load(url); +#endif + } +} + +void DOMTreeWindow::addMessage(int msg_id, const QString &msg) +{ + QDateTime t(QDateTime::currentDateTime()); + QString fullmsg = t.toString(); + fullmsg += ":"; + + if (msg_id != 0) + fullmsg += " (" + QString::number(msg_id) + ") "; + fullmsg += msg; + + if (msgdlg) msgdlg->addMessage(fullmsg); + view()->setMessage(msg); + kdWarning() << fullmsg << endl; +} +void DOMTreeWindow::slotCut() +{ + // TODO implement +} + +void DOMTreeWindow::slotCopy() +{ + // TODO implement +} + +void DOMTreeWindow::slotPaste() +{ + // TODO implement +} + +void DOMTreeWindow::slotFind() +{ + view()->slotFindClicked(); +} + +void DOMTreeWindow::showMessageLog() +{ + msgdlg->show(); + msgdlg->raise(); + msgdlg->setActiveWindow(); +} + +void DOMTreeWindow::optionsConfigureToolbars() +{ + // use the standard toolbar editor + saveMainWindowSettings( config(), autoSaveGroup() ); + KEditToolbar dlg(actionCollection()); + connect(&dlg, SIGNAL(newToolbarConfig()), this, SLOT(newToolbarConfig())); + dlg.exec(); +} + +void DOMTreeWindow::newToolbarConfig() +{ + // this slot is called when user clicks "Ok" or "Apply" in the toolbar editor. + // recreate our GUI, and re-apply the settings (e.g. "text under icons", etc.) + createGUI(locate( "data", "domtreeviewer/domtreeviewerui.rc", instance())); + applyMainWindowSettings( config(), autoSaveGroup() ); +} + +void DOMTreeWindow::optionsPreferences() +{ +#if 0 + // popup some sort of preference dialog, here + DOMTreeWindowPreferences dlg; + if (dlg.exec()) + { + // redo your settings + } +#endif +} + +void DOMTreeWindow::changeStatusbar(const QString& text) +{ + // display the text on the statusbar + statusBar()->message(text); +} + +void DOMTreeWindow::changeCaption(const QString& text) +{ + // display the text on the caption + setCaption(text); +} + +void DOMTreeWindow::slotHtmlPartChanged(KHTMLPart *p) +{ + kdDebug(90180) << k_funcinfo << p << endl; + + if (p) { + // set up manager connections + if ( part_manager ) + disconnect(part_manager); + + part_manager = p->manager(); + + connect(part_manager, SIGNAL(activePartChanged(KParts::Part *)), + SLOT(slotActivePartChanged(KParts::Part *))); + connect(part_manager, SIGNAL(partRemoved(KParts::Part *)), + SLOT(slotPartRemoved(KParts::Part *))); + + // set up browser extension connections + connect(p, SIGNAL(docCreated()), SLOT(slotClosePart())); + } +} + +void DOMTreeWindow::slotActivePartChanged(KParts::Part *p) +{ + kdDebug(90180) << k_funcinfo << p << endl; + Q_ASSERT(p != view()->htmlPart()); + + m_commandHistory->clear(); + view()->disconnectFromTornDownPart(); + view()->setHtmlPart(::qt_cast<KHTMLPart *>(p)); +} + +void DOMTreeWindow::slotPartRemoved(KParts::Part *p) +{ + kdDebug(90180) << k_funcinfo << p << endl; + if (p != view()->htmlPart()) return; + + m_commandHistory->clear(); + view()->disconnectFromTornDownPart(); + view()->setHtmlPart(0); +} + +void DOMTreeWindow::slotClosePart() +{ + kdDebug(90180) << k_funcinfo << endl; + view()->disconnectFromTornDownPart(); + view()->connectToPart(); +} + +#include "domtreewindow.moc" diff --git a/konq-plugins/domtreeviewer/domtreewindow.h b/konq-plugins/domtreeviewer/domtreewindow.h new file mode 100644 index 0000000..f942798 --- /dev/null +++ b/konq-plugins/domtreeviewer/domtreewindow.h @@ -0,0 +1,194 @@ +/* This file is part of the KDE project + * + * Copyright (C) 2005 Leo Savernik <l.savernik@aon.at> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef domtreewindow_H +#define domtreewindow_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <kmainwindow.h> + +#include <qguardedptr.h> + +namespace domtreeviewer { + class ManipulationCommand; +} + +namespace KParts { + class Part; + class PartManager; +} + +class DOMTreeView; +class PluginDomtreeviewer; + +class KAction; +class KConfig; +class KPrinter; +class KURL; +class KCommandHistory; +class KHTMLPart; +class MessageDialog; + +class QPopupMenu; + +/** + * This class serves as the main window for DOM Tree Viewer. It handles the + * menus, toolbars, and status bars. + * + * @short Main window class + * @author Leo Savernik + */ +class DOMTreeWindow : public KMainWindow +{ + Q_OBJECT +public: + /** + * Default Constructor + */ + DOMTreeWindow(PluginDomtreeviewer *plugin); + + /** + * Default Destructor + */ + virtual ~DOMTreeWindow(); + + /** + * returns the dom tree view + */ + DOMTreeView *view() const { return m_view; } + + /** + * returns the command history + */ + KCommandHistory *commandHistory() const { return m_commandHistory; } + + /** + * creates and returns the context menu for the list info panel + */ + QPopupMenu *createInfoPanelAttrContextMenu(); + + /** + * returns the context menu for the list info panel + */ + QPopupMenu *infoPanelAttrContextMenu() { return infopanel_ctx; } + + /** + * creates and returns the context menu for the DOM tree view + */ + QPopupMenu *createDOMTreeViewContextMenu(); + + /** + * returns the context menu for the DOM tree view + */ + QPopupMenu *domTreeViewContextMenu() { return domtree_ctx; } + + /** + * Executes the given command and adds it to the history. + * + * If the command could not be executed, it will not be added. + */ + void executeAndAddCommand(domtreeviewer::ManipulationCommand *); + + /** + * Returns the config object for this plugin. + */ + KConfig *config() const { return _config; } + + /** returns the attribute delete action */ + KAction *deleteAttributeAction() const { return del_attr; } + /** returns the node delete action */ + KAction *deleteNodeAction() const { return del_tree; } + +public slots: + /** + * Adds a log message + * @param id message id + * @param msg message text + */ + void addMessage(int id, const QString &msg); + + /** + * Displays the message log window. + */ + void showMessageLog(); + +protected: + /** + * Overridden virtuals for Qt drag 'n drop (XDND) + */ + virtual void dragEnterEvent(QDragEnterEvent *event); + virtual void dropEvent(QDropEvent *event); +protected: + /** + * This function is called when it is time for the app to save its + * properties for session management purposes. + */ + void saveProperties(KConfig *); + + /** + * This function is called when this app is restored. The KConfig + * object points to the session management config file that was saved + * with @ref saveProperties + */ + void readProperties(KConfig *); + + +private slots: + void slotCut(); + void slotCopy(); + void slotPaste(); + //void slotUndo(); + //void slotRedo(); + void slotFind(); + void optionsConfigureToolbars(); + void optionsPreferences(); + void newToolbarConfig(); + + void changeStatusbar(const QString& text); + void changeCaption(const QString& text); + + void slotHtmlPartChanged(KHTMLPart *); + void slotActivePartChanged(KParts::Part *); + void slotPartRemoved(KParts::Part *); + void slotClosePart(); + +private: + void setupAccel(); + void setupActions(); + +private: + PluginDomtreeviewer *m_plugin; + DOMTreeView *m_view; + MessageDialog *msgdlg; + + KCommandHistory *m_commandHistory; + QPopupMenu *infopanel_ctx; + QPopupMenu *domtree_ctx; + KConfig *_config; + + KAction *del_tree, *del_attr; + + QGuardedPtr<KParts::PartManager> part_manager; +}; + +#endif // domtreewindow_H diff --git a/konq-plugins/domtreeviewer/elementeditdialog.ui b/konq-plugins/domtreeviewer/elementeditdialog.ui new file mode 100644 index 0000000..8705250 --- /dev/null +++ b/konq-plugins/domtreeviewer/elementeditdialog.ui @@ -0,0 +1,201 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ElementEditDialog</class> +<widget class="QDialog"> + <property name="name"> + <cstring>ElementEditDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>469</width> + <height>113</height> + </rect> + </property> + <property name="caption"> + <string>Edit Element</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout7</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Element &name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>elemName</cstring> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>elemName</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Element &namespace:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>elemNamespace</cstring> + </property> + </widget> + <widget class="KComboBox"> + <property name="name"> + <cstring>elemNamespace</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable"> + <bool>true</bool> + </property> + <property name="autoCompletion"> + <bool>true</bool> + </property> + <property name="duplicatesEnabled"> + <bool>false</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="Line"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>insChildBtn</cstring> + </property> + <property name="text"> + <string>&Append as Child</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="flat"> + <bool>false</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>insBeforeBtn</cstring> + </property> + <property name="text"> + <string>Insert &Before Current</string> + </property> + <property name="flat"> + <bool>false</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>60</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelBtn</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>insChildBtn</sender> + <signal>clicked()</signal> + <receiver>ElementEditDialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>cancelBtn</sender> + <signal>clicked()</signal> + <receiver>ElementEditDialog</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>elemName</sender> + <signal>returnPressed()</signal> + <receiver>ElementEditDialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>insBeforeBtn</sender> + <signal>clicked()</signal> + <receiver>ElementEditDialog</receiver> + <slot>accept()</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klineedit.h</includehint> + <includehint>kcombobox.h</includehint> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/konq-plugins/domtreeviewer/messagedialog.ui b/konq-plugins/domtreeviewer/messagedialog.ui new file mode 100644 index 0000000..3ef4a75 --- /dev/null +++ b/konq-plugins/domtreeviewer/messagedialog.ui @@ -0,0 +1,117 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>MessageDialog</class> +<widget class="QDialog"> + <property name="name"> + <cstring>MessageDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>511</width> + <height>282</height> + </rect> + </property> + <property name="caption"> + <string>Message Log</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KTextEdit"> + <property name="name"> + <cstring>messagePane</cstring> + </property> + <property name="textFormat"> + <enum>LogText</enum> + </property> + <property name="wordWrap"> + <enum>FixedColumnWidth</enum> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="undoRedoEnabled"> + <bool>false</bool> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>btnClear</cstring> + </property> + <property name="text"> + <string>C&lear</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>300</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>btnClose</cstring> + </property> + <property name="text"> + <string>&Close</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>btnClose</sender> + <signal>clicked()</signal> + <receiver>MessageDialog</receiver> + <slot>close()</slot> + </connection> + <connection> + <sender>btnClear</sender> + <signal>clicked()</signal> + <receiver>messagePane</receiver> + <slot>clear()</slot> + </connection> +</connections> +<includes> + <include location="local" impldecl="in implementation">messagedialog.ui.h</include> +</includes> +<slots> + <slot specifier="non virtual">addMessage( const QString & msg )</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>ktextedit.h</includehint> +</includehints> +</UI> diff --git a/konq-plugins/domtreeviewer/messagedialog.ui.h b/konq-plugins/domtreeviewer/messagedialog.ui.h new file mode 100644 index 0000000..dcb6609 --- /dev/null +++ b/konq-plugins/domtreeviewer/messagedialog.ui.h @@ -0,0 +1,20 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you want to add, delete, or rename functions or slots, use +** Qt Designer to update this file, preserving your code. +** +** You should not define a constructor or destructor in this file. +** Instead, write your code in functions called init() and destroy(). +** These will automatically be called by the form's constructor and +** destructor. +*****************************************************************************/ + +#include <kdebug.h> + +#include <qdatetime.h> + +void MessageDialog::addMessage( const QString &msg ) +{ + messagePane->append(msg); +} diff --git a/konq-plugins/domtreeviewer/plugin_domtreeviewer.cpp b/konq-plugins/domtreeviewer/plugin_domtreeviewer.cpp new file mode 100644 index 0000000..3555a84 --- /dev/null +++ b/konq-plugins/domtreeviewer/plugin_domtreeviewer.cpp @@ -0,0 +1,56 @@ +#include "plugin_domtreeviewer.h" +#include "domtreewindow.h" +#include "domtreeview.h" + +#include <kaction.h> +#include <kinstance.h> +#include <klibloader.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kgenericfactory.h> + +#include <khtml_part.h> + +typedef KGenericFactory<PluginDomtreeviewer> DomtreeviewerFactory; +K_EXPORT_COMPONENT_FACTORY( libdomtreeviewerplugin, DomtreeviewerFactory( "domtreeviewer" ) ) + +PluginDomtreeviewer::PluginDomtreeviewer( QObject* parent, const char* name, + const QStringList & ) + : Plugin( parent, name ), m_dialog( 0 ) +{ + (void) new KAction( i18n("Show &DOM Tree"), + "domtreeviewer", 0, + this, SLOT(slotShowDOMTree()), + actionCollection(), "viewdomtree" ); +} + +PluginDomtreeviewer::~PluginDomtreeviewer() +{ + kdDebug(90180) << k_funcinfo << endl; + delete m_dialog; +} + +void PluginDomtreeviewer::slotShowDOMTree() +{ + if ( m_dialog ) + { + delete m_dialog; + Q_ASSERT((DOMTreeWindow *)m_dialog == (DOMTreeWindow *)0); + } + if (KHTMLPart *part = ::qt_cast<KHTMLPart *>(parent())) + { + m_dialog = new DOMTreeWindow(this); + connect( m_dialog, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) ); + m_dialog->view()->setHtmlPart(part); + m_dialog->show(); + } +} + +void PluginDomtreeviewer::slotDestroyed() +{ + kdDebug(90180) << k_funcinfo << endl; + m_dialog = 0; +} + +#include <plugin_domtreeviewer.moc> diff --git a/konq-plugins/domtreeviewer/plugin_domtreeviewer.desktop b/konq-plugins/domtreeviewer/plugin_domtreeviewer.desktop new file mode 100644 index 0000000..780947a --- /dev/null +++ b/konq-plugins/domtreeviewer/plugin_domtreeviewer.desktop @@ -0,0 +1,128 @@ +[Desktop Entry] +X-KDE-Library=domtreeviewer +X-KDE-PluginInfo-Author=The Kafka Team, Andreas Schlapbach +X-KDE-PluginInfo-Email=kde-kafka@master.kde.org, schlpbch@iam.unibe.ch +X-KDE-PluginInfo-Name=domtreeviewer +X-KDE-PluginInfo-Version=3.3 +X-KDE-PluginInfo-Website= +X-KDE-PluginInfo-Category=Tools +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +X-KDE-PluginInfo-EnabledByDefault=false +Name=DOM Tree Viewer +Name[bg]=Преглед на DOM +Name[br]=Gweler ar wwezenn DOM +Name[bs]=Preglednik DOM stabla +Name[ca]=Visor de l'arbre DOM +Name[cs]=Prohlížeč DOM stromu +Name[da]=DOM-trævisning +Name[de]=DOM-Baumansicht +Name[el]=Προβολέας δέντρου DOM +Name[eo]=DOM-a arba rigardilo +Name[es]=Visor del árbol DOM +Name[et]=DOM puu vaataja +Name[eu]=DOM arbolaren ikustailea +Name[fa]=مشاهدهگر درخت DOM +Name[fi]=DOM-puun näyttäjä +Name[fr]=Visualiseur d'arborescence DOM +Name[fy]=DOM tree-werjefteprogramma +Name[ga]=Amharcán Crainn DOM +Name[gl]=Visor da Árbore DOM +Name[he]=מציג עץ DOM +Name[hi]=डॉम ट्री प्रदर्शक +Name[hr]=DOM preglednik stabla +Name[hu]=A DOM-fastruktúra megjelenítése +Name[is]=DOM Trjáasýn +Name[it]=Visualizzatore DOM tree +Name[ja]=DOM ツリービューア +Name[ka]=DOM ხის მხილველი +Name[kk]=DOM бұтақтары +Name[km]=កម្មវិធីមើលមែកធាង DOM +Name[lt]=DOM medžio žiūryklė +Name[mk]=Прегледувач на DOM-стебло +Name[ms]=Pelihat Pepohon DOM +Name[nb]=DOM-trevisning +Name[nds]=DOM-Boom-Kieker +Name[ne]=डीओएम ट्री दर्शक +Name[nl]=DOM tree-weergaveprogramma +Name[nn]=DOM-trevising +Name[pa]=DOM ਟਰੀ ਦਰਸ਼ਕ +Name[pl]=Przeglądarka drzewa DOM +Name[pt]=Visualizador da Árvore DOM +Name[pt_BR]=Visão em Árvore DOM +Name[ru]=Дерево DOM +Name[sk]=Prehliadač pre strom DOM +Name[sl]=Drevesni pogled DOM +Name[sr]=Приказивач DOM стабла +Name[sr@Latn]=Prikazivač DOM stabla +Name[sv]=DOM-trädvisaren +Name[ta]=DOM மரக் காட்சியமைப்பு +Name[tg]=Дарахти DOM +Name[tr]=DOM Ağaç Görünümü +Name[uk]=Переглядач дерева DOM +Name[vi]=Bộ xem cây DOM +Name[zh_CN]=DOM 树形视图查看器 +Name[zh_TW]=DOM 樹檢視器 +Comment=DOM tree viewer +Comment[af]=Dom boom aansig +Comment[ar]=مستعرض شجرة DOM +Comment[az]=DOM ağac nümayişçisi +Comment[bg]=Преглед структурата на DOM +Comment[br]=Gweler gwezenn DOM +Comment[bs]=Preglednik DOM stabla +Comment[ca]=Visor de l'arbre DOM +Comment[cs]=Prohlížeč DOM stromu +Comment[cy]=Gwelydd coeden DOM +Comment[da]=DOM-trævisning +Comment[de]=DOM-Baumansicht +Comment[el]=Προβολέας δέντρου DOM +Comment[eo]=DOM-a arba rigardilo +Comment[es]=Visor del árbol DOM +Comment[et]=DOM puu vaataja +Comment[eu]=DOM arbolaren ikustailea +Comment[fa]=مشاهدهگر درخت DOM +Comment[fi]=DOM-puun näyttäjä +Comment[fr]=Afficheur d'arborescence de modèle orienté document +Comment[fy]=DOM tree-werjefteprogramma +Comment[ga]=Amharcán crainn DOM +Comment[gl]=Visor da árbore DOM +Comment[he]=מציג עץ DOM +Comment[hi]=डॉम ट्री प्रदर्शक +Comment[hr]=DOM preglednik stabla +Comment[hu]=DOM-nézegető +Comment[is]=DOM Trjáasýn +Comment[it]=Visualizzatore DOM tree +Comment[ja]=DOM ツリービューア +Comment[ka]=DOM ხის მხილველი +Comment[kk]=DOM бұтақтарын қарау құралы +Comment[km]=កម្មវិធីមើលមែកធាង DOM +Comment[lt]=DOM medžio žiūriklis +Comment[mk]=Прегледувач на DOM-стебло +Comment[ms]=Pelihat pepohon DOM +Comment[nb]=DOM tre-fremviser +Comment[nds]=DOM-Boom-Kieker +Comment[ne]=डीओएम ट्री हेराई +Comment[nl]=DOM tree-weergaveprogramma +Comment[nn]=Framvising av DOM-tre +Comment[pa]=DOM ਲੜੀ ਦਰਸ਼ਕ +Comment[pl]=Widok drzewa DOM +Comment[pt]=Visualizador da árvore DOM +Comment[pt_BR]=Visão em Árvore DOM +Comment[ro]=Afişează o structură arborescentă DOM a documentelor XML/HTML +Comment[ru]=Модуль для просмотра дерева DOM +Comment[sk]=DOM prehliadač +Comment[sl]=Pregledovalnik dreves DOM +Comment[sr]=Приказивач DOM стабла +Comment[sr@Latn]=Prikazivač DOM stabla +Comment[sv]=DOM-trädvisare +Comment[ta]=DOM மரக்காட்சியாளர் +Comment[tg]=Модул барои аз назар гузаронидани дарахти DOM +Comment[tr]=DOM ağaç görünümü +Comment[uk]=Переглядач дерева DOM +Comment[vi]=Bộ xem cây DOM +Comment[xh]=Umbukeli womthi weDOM +Comment[zh_CN]=DOM 树形视图查看器 +Comment[zh_TW]=DOM 樹檢視器 +Icon=domtreeviewer +X-KDE-ParentApp=konqueror +DocPath=konq-plugins/domtreeviewer/index.html diff --git a/konq-plugins/domtreeviewer/plugin_domtreeviewer.h b/konq-plugins/domtreeviewer/plugin_domtreeviewer.h new file mode 100644 index 0000000..ba380a9 --- /dev/null +++ b/konq-plugins/domtreeviewer/plugin_domtreeviewer.h @@ -0,0 +1,27 @@ +/* $Id$ */ + +#ifndef __plugin_domtreeviewer_h +#define __plugin_domtreeviewer_h + +#include <kparts/plugin.h> +// #include <klibloader.h> + +class DOMTreeWindow; +class KURL; + +class PluginDomtreeviewer : public KParts::Plugin +{ + Q_OBJECT +public: + PluginDomtreeviewer( QObject* parent, const char* name, + const QStringList & ); + virtual ~PluginDomtreeviewer(); + +public slots: + void slotShowDOMTree(); + void slotDestroyed(); +private: + DOMTreeWindow* m_dialog; +}; + +#endif diff --git a/konq-plugins/domtreeviewer/plugin_domtreeviewer.rc b/konq-plugins/domtreeviewer/plugin_domtreeviewer.rc new file mode 100644 index 0000000..2216b99 --- /dev/null +++ b/konq-plugins/domtreeviewer/plugin_domtreeviewer.rc @@ -0,0 +1,11 @@ +<!DOCTYPE kpartgui> +<kpartplugin name="domtreeviewer" library="libdomtreeviewerplugin"> +<MenuBar> + <Menu name="tools"><Text>&Tools</Text> + <Action name="viewdomtree"/> + </Menu> +</MenuBar> +<ToolBar name="extraToolBar"><text>Extra Toolbar</text> + <Action name="viewdomtree"/> +</ToolBar> +</kpartplugin> diff --git a/konq-plugins/domtreeviewer/signalreceiver.cpp b/konq-plugins/domtreeviewer/signalreceiver.cpp new file mode 100644 index 0000000..f928036 --- /dev/null +++ b/konq-plugins/domtreeviewer/signalreceiver.cpp @@ -0,0 +1,37 @@ +/* This file is part of the KDE project + * + * Copyright (C) 2005 Leo Savernik <l.savernik@aon.at> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "signalreceiver.h" + +SignalReceiver::SignalReceiver(QObject *parent, const char *name) +: QObject(parent, name), rcvd(false) +{ +} + +SignalReceiver::~SignalReceiver() +{ +} + +void SignalReceiver::slot() +{ + rcvd = true; +} + +#include "signalreceiver.moc" diff --git a/konq-plugins/domtreeviewer/signalreceiver.h b/konq-plugins/domtreeviewer/signalreceiver.h new file mode 100644 index 0000000..8c0f5d9 --- /dev/null +++ b/konq-plugins/domtreeviewer/signalreceiver.h @@ -0,0 +1,67 @@ +/* This file is part of the KDE project + * + * Copyright (C) 2005 Leo Savernik <l.savernik@aon.at> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef SIGNALCATCHER_H +#define SIGNALCATCHER_H + +#include <qobject.h> + +/** + * \brief Class for receiving signals. + * + * This is a convenience class for receiving signals when it is not worth + * the effort, or overly complicated to introduce a dedicated slot. + * + * Use as follows: + * \code + * SignalReceiver sr; + * sr.connect(some_obj, SIGNAL(someSignal()), SLOT(slot())); + * <do something with some_obj> ... + * if (sr.receivedSignal()) { // yes, signal was received + * } + * \endcode + * + * It is not possible to discriminate between different signals. Hence, + * use different signal receiver instances for different signals. + * @autor Leo Savernik + */ +class SignalReceiver : public QObject +{ + Q_OBJECT + +public: + SignalReceiver(QObject *parent = 0, const char *name = 0); + virtual ~SignalReceiver(); + + /** returns true if any signal has been received */ + bool signalReceived() const { return rcvd; } + + /** returns true if any signal has been received */ + bool operator ()() const { return rcvd; } + +public slots: + /** connect a signal to this slot to receive it */ + void slot(); + +private: + bool rcvd; +}; + +#endif // SIGNALCATCHER_H diff --git a/konq-plugins/domtreeviewer/texteditdialog.ui b/konq-plugins/domtreeviewer/texteditdialog.ui new file mode 100644 index 0000000..96980e2 --- /dev/null +++ b/konq-plugins/domtreeviewer/texteditdialog.ui @@ -0,0 +1,149 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>TextEditDialog</class> +<widget class="QDialog"> + <property name="name"> + <cstring>TextEditDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>469</width> + <height>211</height> + </rect> + </property> + <property name="caption"> + <string>Edit Text</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Edit &text for text node:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>textPane</cstring> + </property> + </widget> + <widget class="KTextEdit"> + <property name="name"> + <cstring>textPane</cstring> + </property> + <property name="acceptDrops"> + <bool>true</bool> + </property> + <property name="textFormat"> + <enum>PlainText</enum> + </property> + <property name="tabChangesFocus"> + <bool>true</bool> + </property> + </widget> + <widget class="Line"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>insChildBtn</cstring> + </property> + <property name="text"> + <string>&Append as Child</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="flat"> + <bool>false</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>insBeforeBtn</cstring> + </property> + <property name="text"> + <string>Insert &Before Current</string> + </property> + <property name="flat"> + <bool>false</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>60</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelBtn</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>insChildBtn</sender> + <signal>clicked()</signal> + <receiver>TextEditDialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>cancelBtn</sender> + <signal>clicked()</signal> + <receiver>TextEditDialog</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>insBeforeBtn</sender> + <signal>clicked()</signal> + <receiver>TextEditDialog</receiver> + <slot>accept()</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>ktextedit.h</includehint> +</includehints> +</UI> |