[rkward/work/remove_khtml] /: WIP: Start actually replacing KHTMLPart with QWebView / QWebPage.
Thomas Friedrichsmeier
thomas.friedrichsmeier at ruhr-uni-bochum.de
Mon Feb 23 11:01:26 UTC 2015
Git commit fcc6002a97581d15ee4fbe6842e3a8255e14ae46 by Thomas Friedrichsmeier.
Committed on 21/02/2015 at 19:46.
Pushed by tfry into branch 'work/remove_khtml'.
WIP: Start actually replacing KHTMLPart with QWebView / QWebPage.
This could be considered a first step in porting to KF5.
M +1 -1 debian/control
M +2 -2 rkward/CMakeLists.txt
M +156 -180 rkward/windows/rkhtmlwindow.cpp
M +64 -34 rkward/windows/rkhtmlwindow.h
M +1 -0 rkward/windows/rkworkplace.cpp
http://commits.kde.org/rkward/fcc6002a97581d15ee4fbe6842e3a8255e14ae46
diff --git a/debian/control b/debian/control
index 1012eb4..254fc11 100644
--- a/debian/control
+++ b/debian/control
@@ -2,7 +2,7 @@ Source: rkward
Section: math
Priority: optional
Maintainer: Thomas Friedrichsmeier <tfry at users.sourceforge.net>
-Build-Depends: debhelper (>= 6.0.0), kdelibs5-dev, cmake, r-base-dev (>= 2.8.0), libx11-dev
+Build-Depends: debhelper (>= 6.0.0), kdelibs5-dev, cmake, r-base-dev (>= 2.8.0), libx11-dev, libqtwebkit-dev
Standards-Version: 3.9.6
Homepage: http://rkward.kde.org
Vcs-Browser: http://quickgit.kde.org/?p=rkward.git&a=tree&f=debian
diff --git a/rkward/CMakeLists.txt b/rkward/CMakeLists.txt
index 5f77e4b..11112d4 100644
--- a/rkward/CMakeLists.txt
+++ b/rkward/CMakeLists.txt
@@ -32,7 +32,7 @@ ENDIF(WIN32)
ADD_SUBDIRECTORY( windows )
ADD_SUBDIRECTORY( syntax )
-INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${X11_X11_INCLUDE_PATH} )
+INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${QT_QTWEBKIT_INCLUDE_DIR} ${X11_X11_INCLUDE_PATH} )
SET(RKWard_Sources
rkward.cpp
@@ -63,7 +63,7 @@ IF(Q_WS_MAC)
@ONLY)
ENDIF(Q_WS_MAC)
-TARGET_LINK_LIBRARIES(rkward.frontend ${KDE4_KDECORE_LIBS} windows ${RKWARD_ADDLIBS} agents dialogs plugin settings dataeditor core scriptbackends rbackend misc ${KDE4_KTEXTEDITOR_LIBS} ${KDE4_KHTML_LIBS} ${KDE4_KFILE_LIBS} ${KDE4_KDEUI_LIBS} ${QT_QTDBUS_LIBRARY} ${QT_QTSCRIPT_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${GETTEXT_LIBRARIES})
+TARGET_LINK_LIBRARIES(rkward.frontend ${KDE4_KDECORE_LIBS} windows ${RKWARD_ADDLIBS} agents dialogs plugin settings dataeditor core scriptbackends rbackend misc ${KDE4_KTEXTEDITOR_LIBS} ${KDE4_KFILE_LIBS} ${KDE4_KDEUI_LIBS} ${QT_QTDBUS_LIBRARY} ${QT_QTSCRIPT_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${QT_QTWEBKIT_LIBRARY} ${GETTEXT_LIBRARIES})
# wrapper executable
GET_DIRECTORY_PROPERTY(R_EXECUTABLE DIRECTORY rbackend DEFINITION R_EXECUTABLE)
diff --git a/rkward/windows/rkhtmlwindow.cpp b/rkward/windows/rkhtmlwindow.cpp
index cd67904..1316245 100644
--- a/rkward/windows/rkhtmlwindow.cpp
+++ b/rkward/windows/rkhtmlwindow.cpp
@@ -28,6 +28,7 @@
#include <kmimetype.h>
#include <kio/job.h>
#include <kservice.h>
+#include <ktemporaryfile.h>
#include <qfileinfo.h>
#include <qwidget.h>
@@ -36,6 +37,9 @@
#include <qdir.h>
#include <QHBoxLayout>
#include <QHostInfo>
+#include <QWebView>
+#include <QWebFrame>
+#include <QPrintDialog>
#include "../rkglobals.h"
#include "../rbackend/rinterface.h"
@@ -59,69 +63,42 @@
RKHTMLWindow::RKHTMLWindow (QWidget *parent, WindowMode mode) : RKMDIWindow (parent, RKMDIWindow::HelpWindow) {
RK_TRACE (APP);
- setComponentData (KGlobal::mainComponent ());
- renderingpart = 0;
- khtmlpart = 0;
-/* KService::Ptr service = KService::serviceByDesktopPath ("kwebkitpart.desktop");
- if (service) renderingpart = service->createInstance<KParts::ReadOnlyPart> (this);
- if (!renderingpart) { */
- khtmlpart = new KHTMLPart (this, 0, KHTMLPart::BrowserViewGUI);
- renderingpart = khtmlpart;
-// }
-
- setPart (renderingpart);
- fixupPartGUI ();
-// WORKAROUND for annoying kdelibs bug in KDE 4.6: https://sourceforge.net/tracker/?func=detail&atid=459007&aid=3310106&group_id=50231
-// NOTE: Fixed in KDE 4.7. See http://git.reviewboard.kde.org/r/101491/
- QAction *action = renderingpart->action ("findAheadText");
- if (action) action->setShortcutContext (Qt::WidgetWithChildrenShortcut);
-// WORKAROUND end
+ current_cache_file = 0;
+
+ QVBoxLayout* layout = new QVBoxLayout (this);
+ layout->setContentsMargins (0, 0, 0, 0);
+ view = new QWebView (this);
+ RKWebPage *page = new RKWebPage (this);
+ view->setPage (page);
+ layout->addWidget (view);
+ part = new RKHTMLWindowPart (this);
+ setPart (part);
+ part->initActions ();
+
initializeActivationSignals ();
- RKXMLGUISyncer::self()->registerChangeListener (renderingpart, this, SLOT (fixupPartGUI()));
- renderingpart->setSelectable (true);
- setFocusProxy (renderingpart->widget ());
- renderingpart->widget ()->setFocusPolicy (Qt::StrongFocus);
-
- renderingpart->widget ()->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
- QHBoxLayout *pLayout = new QHBoxLayout (this);
- pLayout->setContentsMargins (0, 0, 0, 0);
- pLayout->addWidget (renderingpart->widget ());
+// TODO renderingpart->setSelectable (true);
+ setFocusProxy (view);
+ view->setFocusPolicy (Qt::StrongFocus);
// We have to connect this in order to allow browsing.
- connect (renderingpart->browserExtension (), SIGNAL (openUrlRequestDelayed(KUrl,KParts::OpenUrlArguments,KParts::BrowserArguments)), this, SLOT (slotOpenUrl(KUrl,KParts::OpenUrlArguments,KParts::BrowserArguments)));
- connect (renderingpart, SIGNAL (completed()), this, SLOT (loadDone()));
- connect (renderingpart->browserExtension (), SIGNAL (openUrlNotify()), this, SLOT (internalNavigation())); // to catch internal navigation on a page
+ connect (page, SIGNAL (linkClicked (QUrl)), this, SLOT (slotOpenUrl(KUrl)));
+ connect (page, SIGNAL (pageInternalNavigation (QUrl)), this, SLOT (internalNavigation()));
current_history_position = -1;
url_change_is_from_history = false;
- initActions ();
- window_mode = Undefined;
useMode (mode);
-}
-RKHTMLWindow::~RKHTMLWindow () {
- RK_TRACE (APP);
-
-// WORKAROUND for annoying kdelibs bug (KDE 4.0 up to at least KDE 4.6): Status bar icons added by plugins typically do not get deleted in case the KParts::StatusBarExtension
-// has already been deleted, first. See http://www.mail-archive.com/rkward-devel@lists.sourceforge.net/msg01345.html . Therefore, delete the plugins, explicitely, while the
-// StatusBarExtension is still alive...
- QList<KParts::Plugin*> plugins = KParts::Plugin::pluginObjects (renderingpart);
- foreach (KParts::Plugin *plugin, plugins) {
- delete plugin;
- }
-// I hope this does not come back to bite us one day... If it does, here's a safer variant, which simply hides the problem (the way it is hidden in konqueror, among others):
-// RKWardMainWindow::getMain ()->partManager ()->setActivePart (0);
-// WORKAROUND end
- delete renderingpart;
+ // needed to enable / disable the run selection action
+ connect (view, SIGNAL (selectionChanged()), this, SLOT (selectionChanged()));
+ selectionChanged ();
}
-void RKHTMLWindow::fixupPartGUI () {
+RKHTMLWindow::~RKHTMLWindow () {
RK_TRACE (APP);
- // strip down the khtmlpart's GUI. remove some stuff we definitely don't need.
- RKCommonFunctions::removeContainers (renderingpart, QString ("tools,security,extraToolBar,saveBackground,saveFrame,printFrame,kget_menu").split (','), true);
+ delete current_cache_file;
}
KUrl RKHTMLWindow::restorableUrl () {
@@ -135,71 +112,37 @@ bool RKHTMLWindow::isModified () {
return false;
}
-void RKHTMLWindow::initActions () {
- RK_TRACE (APP);
-
- // common actions
- actionCollection ()->addAction (KStandardAction::Copy, "copy", renderingpart->browserExtension (), SLOT (copy()));
-
- print = actionCollection ()->addAction (KStandardAction::Print, "print_html", this, SLOT (slotPrint()));
-
- run_selection = RKStandardActions::runCurrent (this, this, SLOT (runSelection()));
-
- // needed to enable / disable the run selection action
- connect (renderingpart, SIGNAL (selectionChanged()), this, SLOT (selectionChanged()));
- selectionChanged ();
-
- // help window actions
- back = actionCollection ()->addAction (KStandardAction::Back, "help_back", this, SLOT (slotBack()));
- back->setEnabled (false);
-
- forward = actionCollection ()->addAction (KStandardAction::Forward, "help_forward", this, SLOT (slotForward()));
- forward->setEnabled (false);
-
- // output window actions
- outputFlush = actionCollection ()->addAction ("output_flush", this, SLOT (flushOutput()));
- outputFlush->setText (i18n ("&Flush Output"));
- outputFlush->setIcon (KIcon ("edit-delete"));
-
- outputRefresh = actionCollection ()->addAction ("output_refresh", this, SLOT (refresh()));
- outputRefresh->setText (i18n ("&Refresh Output"));
- outputRefresh->setIcon (KIcon ("view-refresh"));
-}
-
void RKHTMLWindow::selectionChanged () {
RK_TRACE (APP);
- if (!run_selection) {
+ if (!(part && part->run_selection)) {
RK_ASSERT (false);
return;
}
- run_selection->setEnabled (khtmlpart->hasSelection ());
+#if QT_VERSION >= 0x040800
+ part->run_selection->setEnabled (view->hasSelection ());
+#else
+ part->run_selection->setEnabled (!view->selectedText ().isEmpty ());
+#endif
}
void RKHTMLWindow::runSelection () {
RK_TRACE (APP);
- RKConsole::pipeUserCommand (khtmlpart->selectedText ());
-}
-
-void RKHTMLWindow::doGotoAnchor (const QString &anchor_name) {
- RK_TRACE (APP);
-
- goto_anchor_name = anchor_name;
- QTimer::singleShot (0, this, SLOT (doGotoAnchorNow()));
-}
-
-void RKHTMLWindow::doGotoAnchorNow () {
- RK_TRACE (APP);
-
- if (khtmlpart) khtmlpart->gotoAnchor (goto_anchor_name);
+ RKConsole::pipeUserCommand (view->selectedText ());
}
void RKHTMLWindow::slotPrint () {
RK_TRACE (APP);
- khtmlpart->view ()->print ();
+ // NOTE: taken from kwebkitpart, with small mods
+ // Make it non-modal, in case a redirection deletes the part
+ QPointer<QPrintDialog> dlg (new QPrintDialog (view));
+ if (dlg->exec () == QPrintDialog::Accepted) {
+ view->print (dlg->printer ());
+ }
+ delete dlg;
}
void RKHTMLWindow::openLocationFromHistory (VisitedLocation &loc) {
@@ -209,17 +152,17 @@ void RKHTMLWindow::openLocationFromHistory (VisitedLocation &loc) {
int history_last = url_history.count () - 1;
RK_ASSERT (current_history_position >= 0);
RK_ASSERT (current_history_position <= history_last);
- if (loc.url == renderingpart->url ()) {
- restoreBrowserState (&(loc.state));
+ if (loc.url == current_url) {
+ restoreBrowserState (&loc);
} else {
url_change_is_from_history = true;
- openURL (loc.url);
- restoreBrowserState (&(loc.state));
+ openURL (loc.url); // TODO: merge into restoreBrowserState()?
+ restoreBrowserState (&loc);
url_change_is_from_history = false;
}
- back->setEnabled (current_history_position > 0);
- forward->setEnabled (current_history_position < history_last);
+ part->back->setEnabled (current_history_position > 0);
+ part->forward->setEnabled (current_history_position < history_last);
}
void RKHTMLWindow::slotForward () {
@@ -234,7 +177,7 @@ void RKHTMLWindow::slotBack () {
// if going back from the end of the history, save that position, first.
if (current_history_position >= (url_history.count () - 1)) {
- changeURL (renderingpart->url ());
+ changeURL (current_url);
--current_history_position;
}
--current_history_position;
@@ -249,18 +192,17 @@ void RKHTMLWindow::openRKHPage (const KUrl& url) {
bool ok = false;
if ((url.host () == "component") || (url.host () == "page")) {
useMode (HTMLHelpWindow);
- QString rendered;
- RKHelpRenderer render (&rendered);
+
+ delete current_cache_file;
+ current_cache_file = new KTemporaryFile ();
+ current_cache_file->open ();
+ RKHelpRenderer render (current_cache_file);
ok = render.renderRKHelp (url);
- if (khtmlpart) {
- khtmlpart->begin (url);
- khtmlpart->write (rendered);
- khtmlpart->end ();
- }
- QString ref = url.ref ();
- if (!ref.isEmpty ()) {
- doGotoAnchor (ref);
- }
+ current_cache_file->close ();
+
+ KUrl cache_url = KUrl::fromLocalFile (current_cache_file->fileName ());
+ cache_url.setFragment (url.fragment ());
+ view->load (cache_url);
} else if (url.host ().toUpper () == "RHELPBASE") { // NOTE: QUrl () may lowercase the host part, internally
KUrl fixed_url = KUrl (RKSettingsModuleR::helpBaseUrl ());
fixed_url.setPath (url.path ());
@@ -322,7 +264,7 @@ bool RKHTMLWindow::openURL (const KUrl &url) {
QFileInfo out_file (url.toLocalFile ());
bool ok = out_file.exists();
if (ok) {
- renderingpart->openUrl (url);
+ view->load (url);
} else {
fileDoesNotExistMessage ();
}
@@ -331,7 +273,7 @@ bool RKHTMLWindow::openURL (const KUrl &url) {
if (url_change_is_from_history || url.protocol ().toLower ().startsWith ("help")) { // handle help pages, and any page that we have previously handled (from history)
changeURL (url);
- renderingpart->openUrl (url);
+ view->load (url);
return true;
}
@@ -361,7 +303,7 @@ void RKHTMLWindow::mimeTypeDetermined (KIO::Job* job, const QString& type) {
tj->putOnHold ();
if (type == "text/html") {
changeURL (url);
- renderingpart->openUrl (url);
+ view->load (url);
} else {
RKWorkplace::mainWorkplace ()->openAnyUrl (url, type);
}
@@ -370,10 +312,20 @@ void RKHTMLWindow::mimeTypeDetermined (KIO::Job* job, const QString& type) {
void RKHTMLWindow::internalNavigation () {
RK_TRACE (APP);
- changeURL (renderingpart->url ());
+ // TODO: handle this type of navigation via openRKHPage (), instead?
+ KUrl real_url = view->url ();
+ if (current_cache_file && real_url.isLocalFile ()) {
+ KUrl cache_url = KUrl::fromLocalFile (current_cache_file->fileName ());
+ QString fragment = real_url.fragment ();
+ real_url = current_url;
+ real_url.setFragment (fragment);
+ }
+
+ changeURL (real_url);
}
void RKHTMLWindow::changeURL (const KUrl &url) {
+ KUrl prev_url = current_url;
current_url = url;
updateCaption (url);
@@ -383,14 +335,14 @@ void RKHTMLWindow::changeURL (const KUrl &url) {
url_history = url_history.mid (0, current_history_position);
VisitedLocation loc;
- loc.url = renderingpart->url ();
- saveBrowserState (&loc.state);
+ loc.url = prev_url;
+ saveBrowserState (&loc);
url_history.append (loc);
}
++current_history_position;
- back->setEnabled (current_history_position > 0);
- forward->setEnabled (false);
+ part->back->setEnabled (current_history_position > 0);
+ part->forward->setEnabled (false);
}
}
}
@@ -402,7 +354,8 @@ void RKHTMLWindow::updateCaption (const KUrl &url) {
else setCaption (url.fileName ());
}
-void RKHTMLWindow::slotOpenUrl (const KUrl & url, const KParts::OpenUrlArguments &, const KParts::BrowserArguments &) {
+// TODO: handle request for new window / tab
+void RKHTMLWindow::slotOpenUrl (const KUrl & url) {
RK_TRACE (APP);
openURL (url);
@@ -411,60 +364,37 @@ void RKHTMLWindow::slotOpenUrl (const KUrl & url, const KParts::OpenUrlArguments
void RKHTMLWindow::refresh () {
RK_TRACE (APP);
- KParts::OpenUrlArguments args;
- args.setReload (true); // this forces the next openURL to reload all images
- renderingpart->setArguments (args);
- saveBrowserState (&saved_state);
- openURL (current_url);
+// TODO: does this restore scroll position?
+ view->reload ();
}
void RKHTMLWindow::loadDone () {
RK_TRACE (APP);
+// TODO: does this work?
if (window_mode == HTMLOutputWindow) { // scroll to bottom
- khtmlpart->view ()->setContentsPos (0, khtmlpart->view ()->contentsHeight ());
- } else { // scroll to previous pos
- restoreBrowserState (&saved_state);
- saved_state.clear ();
+ view->page ()->mainFrame ()->setScrollBarValue (Qt::Vertical, view->page ()->mainFrame ()->scrollBarMaximum (Qt::Vertical));
}
}
void RKHTMLWindow::useMode (WindowMode new_mode) {
RK_TRACE (APP);
- RK_ASSERT (new_mode != Undefined);
if (window_mode == new_mode) return;
if (new_mode == HTMLOutputWindow) {
type = RKMDIWindow::OutputWindow | RKMDIWindow::DocumentWindow;
setWindowIcon (RKStandardIcons::getIcon (RKStandardIcons::WindowOutput));
-
- print->setText (i18n ("Print output"));
- QAction *action = renderingpart->action ("saveDocument");
- if (action) action->setText (i18n ("Export page as HTML"));
- else RK_ASSERT (false); // we should know about this
-
- setXMLFile ("rkoutputwindow.rc");
+ part->setOutputWindowSkin ();
setMetaInfo (i18n ("Output Window"), "rkward://page/rkward_output", RKSettings::PageOutput);
- run_selection->setVisible (false);
} else {
RK_ASSERT (new_mode == HTMLHelpWindow);
type = RKMDIWindow::HelpWindow | RKMDIWindow::DocumentWindow;
setWindowIcon (RKStandardIcons::getIcon (RKStandardIcons::WindowHelp));
-
- print->setText (i18n ("Print page"));
- QAction *action = renderingpart->action ("saveDocument");
- if (action) action->setText (i18n ("Save Output as HTML"));
- else RK_ASSERT (false); // we should know about this
-
- setXMLFile ("rkhelpwindow.rc");
- run_selection->setVisible (true);
+ part->setHelpWindowSkin ();
}
- if (parentClient ()) renderingpart->removeChildClient (this);
- renderingpart->insertChildClient (this);
-
updateCaption (current_url);
window_mode = new_mode;
}
@@ -472,14 +402,19 @@ void RKHTMLWindow::useMode (WindowMode new_mode) {
void RKHTMLWindow::fileDoesNotExistMessage () {
RK_TRACE (APP);
- if (!khtmlpart) return;
- khtmlpart->begin (KUrl ());
+ delete current_cache_file;
+ current_cache_file = new KTemporaryFile ();
+ current_cache_file->open ();
if (window_mode == HTMLOutputWindow) {
- khtmlpart->write (i18n ("<HTML><BODY><H1>RKWard output file could not be found</H1>\n</BODY></HTML>"));
+ current_cache_file->write (i18n ("<HTML><BODY><H1>RKWard output file could not be found</H1>\n</BODY></HTML>").toUtf8 ());
} else {
- khtmlpart->write ("<html><body><h1>" + i18n ("Page does not exist or is broken") + "</h1></body></html>");
+ current_cache_file->write (QString ("<html><body><h1>" + i18n ("Page does not exist or is broken") + "</h1></body></html>").toUtf8 ());
}
- khtmlpart->end ();
+
+ current_cache_file->close ();
+
+ KUrl cache_url = KUrl::fromLocalFile (current_cache_file->fileName ());
+ view->load (cache_url);
}
void RKHTMLWindow::flushOutput () {
@@ -497,30 +432,75 @@ void RKHTMLWindow::flushOutput () {
}
}
-void RKHTMLWindow::saveBrowserState (QByteArray* state) {
+void RKHTMLWindow::saveBrowserState (VisitedLocation* state) {
RK_TRACE (APP);
- KParts::BrowserExtension *bext = renderingpart->browserExtension ();
- if (!bext) {
- RK_ASSERT (bext);
- return;
+ if (view && view->page () && view->page ()->mainFrame ()) {
+ state->scroll_position = view->page ()->mainFrame ()->scrollPosition ();
+ } else {
+ state->scroll_position = QPoint ();
}
- state->clear ();
- QDataStream dummy (state, QIODevice::WriteOnly);
- bext->saveState (dummy);
}
-void RKHTMLWindow::restoreBrowserState (QByteArray* state) {
+void RKHTMLWindow::restoreBrowserState (VisitedLocation* state) {
RK_TRACE (APP);
- if (state->isEmpty()) return;
- KParts::BrowserExtension *bext = renderingpart->browserExtension ();
- if (!bext) {
- RK_ASSERT (bext);
- return;
- }
- QDataStream dummy (state, QIODevice::ReadOnly);
- bext->restoreState (dummy);
+ if (state->scroll_position.isNull ()) return;
+ RK_ASSERT (view && view->page () && view->page ()->mainFrame ());
+ view->page ()->mainFrame ()->setScrollPosition (state->scroll_position);
+}
+
+RKHTMLWindowPart::RKHTMLWindowPart (RKHTMLWindow* window) : KParts::Part (window) {
+ RK_TRACE (APP);
+ setComponentData (KGlobal::mainComponent ());
+ RKHTMLWindowPart::window = window;
+}
+
+void RKHTMLWindowPart::initActions () {
+ RK_TRACE (APP);
+
+ // TODO!!!
+ // common actions
+ actionCollection ()->addAction (KStandardAction::Copy, "copy", this, SLOT (copy()));
+
+ print = actionCollection ()->addAction (KStandardAction::Print, "print_html", this, SLOT (slotPrint()));
+ save_page = actionCollection ()->addAction (KStandardAction::Print, "save_page", this, SLOT (slotPrint()));
+
+ run_selection = RKStandardActions::runCurrent (window, this, SLOT (runSelection()));
+
+ // help window actions
+ back = actionCollection ()->addAction (KStandardAction::Back, "help_back", this, SLOT (slotBack()));
+ back->setEnabled (false);
+
+ forward = actionCollection ()->addAction (KStandardAction::Forward, "help_forward", this, SLOT (slotForward()));
+ forward->setEnabled (false);
+
+ // output window actions
+ outputFlush = actionCollection ()->addAction ("output_flush", this, SLOT (flushOutput()));
+ outputFlush->setText (i18n ("&Flush Output"));
+ outputFlush->setIcon (KIcon ("edit-delete"));
+
+ outputRefresh = actionCollection ()->addAction ("output_refresh", this, SLOT (refresh()));
+ outputRefresh->setText (i18n ("&Refresh Output"));
+ outputRefresh->setIcon (KIcon ("view-refresh"));
+}
+
+void RKHTMLWindowPart::setOutputWindowSkin () {
+ RK_TRACE (APP);
+
+ print->setText (i18n ("Print output"));
+ save_page->setText (i18n ("Export page as HTML"));
+ setXMLFile ("rkoutputwindow.rc");
+ run_selection->setVisible (false);
+}
+
+void RKHTMLWindowPart::setHelpWindowSkin () {
+ RK_TRACE (APP);
+
+ print->setText (i18n ("Print page"));
+ save_page->setText (i18n ("Save Output as HTML"));
+ setXMLFile ("rkhelpwindow.rc");
+ run_selection->setVisible (true);
}
//////////////////////////////////////////
@@ -834,11 +814,7 @@ QString RKHelpRenderer::startSection (const QString &name, const QString &title,
void RKHelpRenderer::writeHTML (const QString& string) {
RK_TRACE (APP);
- buffer->append (string);
-/* else {
- RK_ASSERT (html_write_file);
- html_write_file->write (string.toUtf8 ());
- } */
+ device->write (string.toUtf8 ());
}
/////////////////////////////////////
diff --git a/rkward/windows/rkhtmlwindow.h b/rkward/windows/rkhtmlwindow.h
index c74e6e9..938d281 100644
--- a/rkward/windows/rkhtmlwindow.h
+++ b/rkward/windows/rkhtmlwindow.h
@@ -19,34 +19,47 @@
#define RKHTMLWINDOW_H
#include <kurl.h>
-#include <kparts/browserextension.h>
-#include <kxmlguiclient.h>
+#include <kparts/part.h>
#include <kio/jobclasses.h>
+#include <QWebPage>
+
#include "../windows/rkmdiwindow.h"
-class KHTMLPart;
class KActionCollection;
class KRecentFilesAction;
class QAction;
class QDomElement;
class RKComponentHandle;
class XMLHelper;
+class RKHTMLWindowPart;
+class QWebView;
+class KTemporaryFile;
+
+class RKWebPage : public QWebPage {
+ Q_OBJECT
+public:
+ RKWebPage (QObject* parent) : QWebPage (parent) {};
+signals:
+ void pageInternalNavigation (const QUrl& url);
+protected:
+/** reimplemented to always emit linkClicked() for pages that need special handling (importantly, rkward://-urls). */
+ bool acceptNavigationRequest (QWebFrame* frame, const QNetworkRequest& request, NavigationType type) { return true; }; // TODO
+};
/**
\brief Show html files.
-This class wraps a khtml part.
+Provide a window for viewing HTML pages.
-It is used as a base for several purposes: Display R-help (in HTML format), display generic HTML, display RKWard output. Do not use this class directly. Use the derived classes instead.
+It is used as a base for several purposes: Display R-help (in HTML format), display RKWard help pages, display generic HTML, display RKWard output.
@author Pierre Ecochard
*/
-class RKHTMLWindow : public RKMDIWindow, public KXMLGUIClient {
+class RKHTMLWindow : public RKMDIWindow {
Q_OBJECT
public:
enum WindowMode {
- Undefined,
HTMLHelpWindow,
HTMLOutputWindow
};
@@ -64,20 +77,17 @@ public:
*/
static bool handleRKWardURL (const KUrl &url, RKHTMLWindow *window=0);
void openRKHPage (const KUrl &url);
-/** initialize all actions */
- void initActions ();
bool isModified ();
/** Return current url */
KUrl url ();
/** Return current url in a restorable way, i.e. for help pages, abstract the session specific part of the path */
KUrl restorableUrl ();
- void doGotoAnchor (const QString &anchor_name);
WindowMode mode () { return window_mode; };
public slots:
/** this is used for browsing only. Use openURL instead, when calling from outside. */
- void slotOpenUrl (const KUrl & url, const KParts::OpenUrlArguments &, const KParts::BrowserArguments &);
+ void slotOpenUrl (const KUrl & url);
void slotPrint ();
void slotForward ();
void slotBack ();
@@ -87,35 +97,54 @@ public slots:
void flushOutput ();
/** Reload current page.*/
void refresh ();
-/** apply our customizations to the khtmlpart GUI */
- void fixupPartGUI ();
private slots:
/** This slot is called when the new page has finished loading. Sets scroll position to scroll_position */
void loadDone ();
- void doGotoAnchorNow ();
void mimeTypeDetermined (KIO::Job*, const QString& type);
void internalNavigation ();
-protected:
-/** Here we store the state of the part before refresh. Used to scroll to the same position after a reload */
- QByteArray saved_state;
-/** the part doing all the real work */
- KParts::ReadOnlyPart * renderingpart;
+private:
+ QWebView* view;
/** In case the part is a khtmlpart: A ready-cast pointer to that. 0 otherwise (if a webkit part is in use) */
- KHTMLPart *khtmlpart;
+ RKHTMLWindowPart *part;
/** update caption according to given URL */
virtual void updateCaption (const KUrl &url);
/** called from openURL. Takes care of updating caption, and updating back/forward actions, if available */
void changeURL (const KUrl &url);
-private:
+
struct VisitedLocation {
KUrl url;
- QByteArray state;
+ QPoint scroll_position;
};
QList<VisitedLocation> url_history;
void openLocationFromHistory (VisitedLocation &loc);
int current_history_position;
bool url_change_is_from_history; // dirty!!!
+ KUrl current_url;
+ KTemporaryFile *current_cache_file;
+
+ WindowMode window_mode;
+ void useMode (WindowMode);
+
+ void fileDoesNotExistMessage ();
+
+ void saveBrowserState (VisitedLocation *state);
+ void restoreBrowserState (VisitedLocation *state);
+};
+
+class RKHTMLWindowPart : public KParts::Part {
+ Q_OBJECT
+public:
+ RKHTMLWindowPart (RKHTMLWindow *window);
+ ~RKHTMLWindowPart () {};
+
+ void setOutputWindowSkin ();
+ void setHelpWindowSkin ();
+ void initActions ();
+private:
+ friend class RKHTMLWindow;
+ RKHTMLWindow *window;
+
// general actions
QAction *run_selection;
QAction* print;
@@ -126,16 +155,17 @@ private:
QAction *back;
QAction *forward;
- QString goto_anchor_name;
- KUrl current_url;
-
- WindowMode window_mode;
- void useMode (WindowMode);
-
- void fileDoesNotExistMessage ();
-
- void saveBrowserState (QByteArray *state);
- void restoreBrowserState (QByteArray *state);
+// TODO: Most of these won't need a pointer. This is sort of a todo-list of actions to implement
+ QAction* zoom_in;
+ QAction* zoom_out;
+ QAction* save_page;
+ QAction* find;
+ QAction* findAhead; // shortcut '/'
+ QAction* find_next;
+ QAction* find_previous;
+ QAction* copy;
+ QAction* select_all;
+ // needed? QAction* encoding;
};
/**
@@ -146,7 +176,7 @@ private:
class RKHelpRenderer {
public:
/** ctor */
- RKHelpRenderer (QString *_buffer) { buffer = _buffer; help_xml = 0; component_xml = 0; };
+ RKHelpRenderer (QIODevice *_device) { device = _device; help_xml = 0; component_xml = 0; };
/** destructor */
~RKHelpRenderer () {};
@@ -164,7 +194,7 @@ public:
RKComponentHandle *componentPathToHandle (QString path);
QString startSection (const QString &name, const QString &title, const QString &shorttitle, QStringList *anchors, QStringList *anchor_names);
- QString *buffer;
+ QIODevice *device;
void writeHTML (const QString &string);
};
diff --git a/rkward/windows/rkworkplace.cpp b/rkward/windows/rkworkplace.cpp
index 8530ad3..40f7985 100644
--- a/rkward/windows/rkworkplace.cpp
+++ b/rkward/windows/rkworkplace.cpp
@@ -31,6 +31,7 @@
#include <QFileInfo>
#include <QCryptographicHash>
+#include <QKeyEvent>
#include "detachedwindowcontainer.h"
#include "rkcommandeditorwindow.h"
More information about the rkward-tracker
mailing list