mirror of
https://invent.kde.org/system/dolphin
synced 2024-09-20 00:41:23 +00:00
443 lines
13 KiB
C++
443 lines
13 KiB
C++
/* 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 "plugin_domtreeviewer.h"
|
|
#include "ui_messagedialog.h"
|
|
|
|
|
|
#include <kundostack.h>
|
|
#include <kconfig.h>
|
|
#include <khtml_part.h>
|
|
#include <klocale.h>
|
|
#include <kmenubar.h>
|
|
#include <kstatusbar.h>
|
|
#include <kstandarddirs.h>
|
|
#include <kstandardguiitem.h>
|
|
#include <ktextedit.h>
|
|
#include <kurl.h>
|
|
#include <kurlrequesterdialog.h>
|
|
#include <kxmlguifactory.h>
|
|
#include <kparts/partmanager.h>
|
|
|
|
#include <kedittoolbar.h>
|
|
#include <kactioncollection.h>
|
|
#include <kaction.h>
|
|
#include <kstandardaction.h>
|
|
|
|
#include <qdatetime.h>
|
|
#include <qtimer.h>
|
|
#include <QDragEnterEvent>
|
|
#include <QMenu>
|
|
#include <QDropEvent>
|
|
|
|
|
|
class MessageDialog : public KDialog, public Ui::MessageDialog
|
|
{
|
|
public:
|
|
MessageDialog(QWidget *parent)
|
|
: KDialog(parent)
|
|
{
|
|
setupUi(mainWidget());
|
|
|
|
setWindowTitle(i18nc("@title:window", "Message Log"));
|
|
setButtons(Close | User1);
|
|
setButtonGuiItem(User1, KStandardGuiItem::clear());
|
|
|
|
QPalette pal = messagePane->palette();
|
|
pal.setColor(messagePane->backgroundRole(), palette().color(QPalette::Active, QPalette::Base));
|
|
messagePane->setPalette(pal);
|
|
|
|
connect(this, SIGNAL(closeClicked()), this, SLOT(close()));
|
|
connect(this, SIGNAL(user1Clicked()), messagePane, SLOT(clear()));
|
|
}
|
|
|
|
void addMessage(const QString &msg)
|
|
{
|
|
messagePane->append(msg);
|
|
}
|
|
};
|
|
|
|
|
|
using domtreeviewer::ManipulationCommand;
|
|
|
|
DOMTreeWindow::DOMTreeWindow(PluginDomtreeviewer *plugin)
|
|
: KXmlGuiWindow( 0 ),
|
|
m_plugin(plugin), m_view(new DOMTreeView(this))
|
|
{
|
|
setObjectName("DOMTreeWindow" );
|
|
part_manager = 0;
|
|
|
|
// set configuration object
|
|
_config = new KConfig("domtreeviewerrc");
|
|
|
|
// accept dnd
|
|
setAcceptDrops(true);
|
|
|
|
// tell the KXmlGuiWindow that this is indeed the main widget
|
|
setCentralWidget(m_view);
|
|
|
|
// message window dialog
|
|
msgdlg = new MessageDialog(0);
|
|
// msgdlg->show();
|
|
|
|
// then, setup our actions
|
|
setupActions();
|
|
|
|
// Add typical actions and save size/toolbars/statusbar
|
|
setupGUI(ToolBar | Keys | StatusBar | Save | Create,
|
|
KStandardDirs::locate( "data", "domtreeviewer/domtreeviewerui.rc", componentData()));
|
|
|
|
// allow the view to change the statusbar and caption
|
|
#if 0
|
|
connect(m_view, SIGNAL(signalChangeStatusbar(QString)),
|
|
this, SLOT(changeStatusbar(QString)));
|
|
connect(m_view, SIGNAL(signalChangeCaption(QString)),
|
|
this, SLOT(changeCaption(QString)));
|
|
#endif
|
|
connect(view(), SIGNAL(htmlPartChanged(KHTMLPart*)),
|
|
SLOT(slotHtmlPartChanged(KHTMLPart*)));
|
|
|
|
ManipulationCommand::connect(SIGNAL(error(int,QString)),
|
|
this, SLOT(addMessage(int,QString)));
|
|
|
|
infopanel_ctx = createInfoPanelAttrContextMenu();
|
|
domtree_ctx = createDOMTreeViewContextMenu();
|
|
|
|
}
|
|
|
|
DOMTreeWindow::~DOMTreeWindow()
|
|
{
|
|
kDebug(90180) << this;
|
|
delete m_commandHistory;
|
|
delete msgdlg;
|
|
delete _config;
|
|
}
|
|
|
|
void DOMTreeWindow::executeAndAddCommand(ManipulationCommand *cmd)
|
|
{
|
|
m_commandHistory->push(cmd); // calls cmd->redo()
|
|
if (!cmd->isValid()) {
|
|
cmd->undo();
|
|
// TODO: ideally, remove the command from m_commandHistory, but I don't see how to do that.
|
|
} else {
|
|
view()->hideMessageLine();
|
|
}
|
|
}
|
|
|
|
void DOMTreeWindow::setupActions()
|
|
{
|
|
KStandardAction::close(this, SLOT(close()), actionCollection());
|
|
|
|
KStandardAction::cut(this, SLOT(slotCut()), actionCollection())->setEnabled(false);
|
|
KStandardAction::copy(this, SLOT(slotCopy()), actionCollection())->setEnabled(false);
|
|
KStandardAction::paste(this, SLOT(slotPaste()), actionCollection())->setEnabled(false);
|
|
|
|
m_commandHistory = new KUndoStack;
|
|
|
|
QAction* undoAction = m_commandHistory->createUndoAction(actionCollection());
|
|
connect(undoAction, SIGNAL(triggered()), m_commandHistory, SLOT(undo()));
|
|
QAction* redoAction = m_commandHistory->createRedoAction(actionCollection());
|
|
connect(redoAction, SIGNAL(triggered()), m_commandHistory, SLOT(redo()));
|
|
|
|
|
|
KStandardAction::find(this, SLOT(slotFind()), actionCollection());
|
|
|
|
KStandardAction::redisplay(m_view, SLOT(refresh()), actionCollection());
|
|
|
|
// Show/hide options
|
|
QAction *pure = actionCollection()->addAction("show_dom_pure");
|
|
pure->setText(i18n("Pure DOM Tree"));
|
|
pure->setCheckable(true);
|
|
pure->setChecked(true);
|
|
connect(pure, SIGNAL(toggled(bool)), m_view, SLOT(slotPureToggled(bool)));
|
|
|
|
QAction *attr = actionCollection()->addAction("show_dom_attributes");
|
|
attr->setText(i18n("Show DOM Attributes"));
|
|
attr->setCheckable(true);
|
|
attr->setChecked(true);
|
|
connect(attr, SIGNAL(toggled(bool)),
|
|
m_view, SLOT(slotShowAttributesToggled(bool)));
|
|
|
|
QAction *highlight = actionCollection()->addAction("show_highlight_html");
|
|
highlight->setText(i18n("Highlight HTML"));
|
|
highlight->setCheckable(true);
|
|
highlight->setChecked(true);
|
|
connect(highlight, SIGNAL(toggled(bool)),
|
|
m_view, SLOT(slotHighlightHTMLToggled(bool)));
|
|
|
|
// toggle manipulation dialog
|
|
QAction *a = actionCollection()->addAction("show_msg_dlg");
|
|
a->setText(i18n("Show Message Log"));
|
|
a->setShortcut(Qt::CTRL+Qt::Key_E);
|
|
connect(a, SIGNAL(triggered()), this, 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
|
|
QAction *tree = KStandardAction::up(view(), SLOT(moveToParent()), actionCollection());
|
|
actionCollection()->addAction("tree_up",tree);
|
|
QAction *tree_inc_level = actionCollection()->addAction("tree_inc_level");
|
|
tree_inc_level->setText(i18n("Expand"));
|
|
tree_inc_level->setIcon(KIcon("arrow-right"));
|
|
tree_inc_level->setShortcut(Qt::CTRL+Qt::Key_Greater);
|
|
tree_inc_level->setToolTip(i18n("Increase expansion level"));
|
|
connect(tree_inc_level, SIGNAL(triggered()), view(), SLOT(increaseExpansionDepth()));
|
|
QAction *tree_dec_level = actionCollection()->addAction( "tree_dec_level");
|
|
tree_dec_level->setText(i18n("Collapse"));
|
|
tree_dec_level->setIcon(KIcon("arrow-left"));
|
|
tree_dec_level->setShortcut(Qt::CTRL+Qt::Key_Less);
|
|
tree_dec_level->setToolTip(i18n("Decrease expansion level"));
|
|
connect(tree_dec_level, SIGNAL(triggered()), view(), SLOT(decreaseExpansionDepth()));
|
|
|
|
// actions for the dom tree list view context menu
|
|
|
|
del_tree = actionCollection()->addAction( "tree_delete");
|
|
del_tree->setText(i18n("&Delete"));
|
|
del_tree->setIcon(KIcon("edit-delete"));
|
|
del_tree->setShortcut(Qt::Key_Delete);
|
|
del_tree->setToolTip(i18n("Delete nodes"));
|
|
del_tree->setShortcutContext(Qt::WidgetShortcut);
|
|
view()->m_listView->addAction(del_tree);
|
|
connect(del_tree, SIGNAL(triggered()), view(), SLOT(deleteNodes()));
|
|
QAction *new_elem = actionCollection()->addAction( "tree_add_element");
|
|
new_elem->setText(i18n("New &Element..."));
|
|
new_elem->setIcon(KIcon("document-new"));
|
|
connect(new_elem, SIGNAL(triggered()), view(), SLOT(slotAddElementDlg()));
|
|
QAction *new_text = actionCollection()->addAction( "tree_add_text");
|
|
new_text->setText(i18n("New &Text Node..."));
|
|
new_text->setIcon(KIcon("draw-text"));
|
|
connect(new_text, SIGNAL(triggered()), view(), SLOT(slotAddTextDlg()));
|
|
|
|
// actions for the info panel attribute list context menu
|
|
del_attr = actionCollection()->addAction( "attr_delete");
|
|
del_attr->setText(i18n("&Delete"));
|
|
del_attr->setIcon(KIcon("edit-delete"));
|
|
del_attr->setShortcut(Qt::Key_Delete);
|
|
del_attr->setToolTip(i18n("Delete attributes"));
|
|
del_attr->setShortcutContext(Qt::WidgetShortcut);
|
|
view()->nodeAttributes->addAction(del_attr);
|
|
connect(del_attr, SIGNAL(triggered()), view(), SLOT(deleteAttributes()));
|
|
|
|
}
|
|
|
|
QMenu *DOMTreeWindow::createInfoPanelAttrContextMenu()
|
|
{
|
|
QWidget *w = factory()->container("infopanelattr_context", this);
|
|
Q_ASSERT(w);
|
|
return static_cast<QMenu *>(w);
|
|
}
|
|
|
|
QMenu *DOMTreeWindow::createDOMTreeViewContextMenu()
|
|
{
|
|
QWidget *w = factory()->container("domtree_context", this);
|
|
Q_ASSERT(w);
|
|
return static_cast<QMenu *>(w);
|
|
}
|
|
|
|
void DOMTreeWindow::saveProperties(KConfigGroup &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()) {
|
|
config.writePathEntry("lastURL", m_view->currentURL());
|
|
#endif
|
|
}
|
|
|
|
void DOMTreeWindow::readProperties(const KConfigGroup &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", QString());
|
|
|
|
if (!url.isEmpty())
|
|
m_view->openUrl(KUrl::fromPathOrUrl(url));
|
|
#endif
|
|
}
|
|
|
|
void DOMTreeWindow::dragEnterEvent(QDragEnterEvent *event)
|
|
{
|
|
// accept uri drops only
|
|
event->setAccepted(KUrl::List::canDecode(event->mimeData()));
|
|
}
|
|
|
|
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
|
|
|
|
// see if we can decode a URI.. if not, just ignore it
|
|
KUrl::List urls = KUrl::List::fromMimeData( event->mimeData() );
|
|
if (!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);
|
|
kWarning() << fullmsg ;
|
|
}
|
|
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->activateWindow();
|
|
}
|
|
|
|
void DOMTreeWindow::optionsConfigureToolbars()
|
|
{
|
|
// use the standard toolbar editor
|
|
saveMainWindowSettings( config()->group( 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(KStandardDirs::locate( "data", "domtreeviewer/domtreeviewerui.rc", componentData()));
|
|
applyMainWindowSettings( config()->group( 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()->showMessage(text);
|
|
}
|
|
|
|
void DOMTreeWindow::changeCaption(const QString& text)
|
|
{
|
|
// display the text on the caption
|
|
setCaption(text);
|
|
}
|
|
|
|
void DOMTreeWindow::slotHtmlPartChanged(KHTMLPart *p)
|
|
{
|
|
kDebug(90180) << p;
|
|
|
|
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)
|
|
{
|
|
kDebug(90180) << p;
|
|
if (p == view()->htmlPart())
|
|
return;
|
|
|
|
m_commandHistory->clear();
|
|
view()->disconnectFromTornDownPart();
|
|
view()->setHtmlPart(qobject_cast<KHTMLPart *>(p));
|
|
}
|
|
|
|
void DOMTreeWindow::slotPartRemoved(KParts::Part *p)
|
|
{
|
|
kDebug(90180) << p;
|
|
if (p != view()->htmlPart()) return;
|
|
|
|
m_commandHistory->clear();
|
|
view()->disconnectFromTornDownPart();
|
|
view()->setHtmlPart(0);
|
|
}
|
|
|
|
void DOMTreeWindow::slotClosePart()
|
|
{
|
|
kDebug(90180) ;
|
|
view()->disconnectFromTornDownPart();
|
|
view()->connectToPart();
|
|
}
|
|
|
|
#include "domtreewindow.moc"
|