[rkward/work/remove_khtml] rkward: Implement searchbar for new HTML view
Thomas Friedrichsmeier
thomas.friedrichsmeier at ruhr-uni-bochum.de
Wed Feb 25 15:12:45 UTC 2015
Git commit 8e17bc3b8f47fd9ba1fc0fe619ca230d980c4d83 by Thomas Friedrichsmeier.
Committed on 25/02/2015 at 15:09.
Pushed by tfry into branch 'work/remove_khtml'.
Implement searchbar for new HTML view
M +1 -0 rkward/misc/CMakeLists.txt
A +160 -0 rkward/misc/rkfindbar.cpp [License: GPL (v2+)]
A +67 -0 rkward/misc/rkfindbar.h [License: GPL (v2+)]
M +4 -0 rkward/windows/rkhelpwindow.rc
M +32 -9 rkward/windows/rkhtmlwindow.cpp
M +4 -0 rkward/windows/rkhtmlwindow.h
M +4 -0 rkward/windows/rkoutputwindow.rc
http://commits.kde.org/rkward/8e17bc3b8f47fd9ba1fc0fe619ca230d980c4d83
diff --git a/rkward/misc/CMakeLists.txt b/rkward/misc/CMakeLists.txt
index 1ae4afc..285b90b 100644
--- a/rkward/misc/CMakeLists.txt
+++ b/rkward/misc/CMakeLists.txt
@@ -25,6 +25,7 @@ SET(misc_STAT_SRCS
editformatdialog.cpp
rkmessagecatalog.cpp
rkdbusapi.cpp
+ rkfindbar.cpp
)
QT4_AUTOMOC(${misc_STAT_SRCS})
diff --git a/rkward/misc/rkfindbar.cpp b/rkward/misc/rkfindbar.cpp
new file mode 100644
index 0000000..5b0ab71
--- /dev/null
+++ b/rkward/misc/rkfindbar.cpp
@@ -0,0 +1,160 @@
+/***************************************************************************
+ rkfindbar - description
+ -------------------
+ begin : Tue Feb 24 2015
+ copyright : (C) 2015 by Thomas Friedrichsmeier
+ email : tfry at users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 "rkfindbar.h"
+
+#include <QHBoxLayout>
+#include <QToolButton>
+#include <QCheckBox>
+#include <QLineEdit>
+
+#include <khistorycombobox.h>
+#include <klocale.h>
+#include <kicon.h>
+
+#include "rkcommonfunctions.h"
+
+#include "../debug.h"
+
+RKFindBar::RKFindBar (QWidget* parent, bool custom) : QWidget (parent) {
+ RK_TRACE (APP);
+
+ mlayout = new QHBoxLayout (this);
+ mlayout->setContentsMargins (0, 0, 0, 0);
+ QToolButton* close_button = new QToolButton (this);
+ close_button->setIcon (KIcon ("dialog-close"));
+ close_button->setAutoRaise (true); // makes it flat
+ connect (close_button, SIGNAL (clicked ()), this, SLOT (hide ()));
+ mlayout->addWidget (close_button);
+
+ QHBoxLayout* slayout = new QHBoxLayout ();
+ mlayout->addLayout (slayout, 1);
+ slayout->setContentsMargins (0, 0, 0, 0);
+ slayout->setSpacing (0);
+ term_edit = new KHistoryComboBox (this);
+ term_edit->setMaximumWidth (fontMetrics ().width ("This is quite a long search term by any standard, indeed"));
+ term_edit->setMinimumWidth (fontMetrics ().width ("A short search term"));
+ connect (term_edit, SIGNAL (editTextChanged(QString)), this, SLOT (searchChanged()));
+ connect (term_edit, SIGNAL(returnPressed(QString)), this, SLOT (forward()));
+ regular_palette = term_edit->palette ();
+ nomatch_palette = regular_palette;
+ nomatch_palette.setColor (QPalette::Text, QColor (255, 0, 0));
+ slayout->addWidget (term_edit, 1);
+
+ QToolButton* backward_button = new QToolButton (this);
+ backward_button->setArrowType (Qt::UpArrow);
+ backward_button->setContentsMargins (0, 0, 0, 0);
+ RKCommonFunctions::setTips (i18n ("Search backwards (previous occurence of search term"), backward_button);
+ connect (backward_button, SIGNAL (clicked()), this, SLOT(backward()));
+ slayout->addWidget (backward_button);
+ QToolButton* forward_button = new QToolButton (this);
+ forward_button->setArrowType (Qt::DownArrow);
+ forward_button->setContentsMargins (0, 0, 0, 0);
+ RKCommonFunctions::setTips (i18n ("Search forward (next occurence of search term"), forward_button);
+ connect (forward_button, SIGNAL (clicked()), this, SLOT(forward()));
+ slayout->addWidget (forward_button);
+
+ mlayout->addSpacing (15);
+
+ if (!custom) {
+ setPrimaryOptions (QList<QWidget*> () << getOption (MatchCase) << getOption (FindAsYouType) << getOption (HighlightAll));
+ }
+}
+
+RKFindBar::~RKFindBar () {
+ RK_TRACE (APP);
+}
+
+void RKFindBar::setPrimaryOptions (const QList<QWidget*>& options) {
+ RK_TRACE (APP);
+
+ for (int i = 0; i < options.size (); ++i) {
+ mlayout->addWidget (options[i]);
+ }
+ mlayout->addStretch ();
+}
+
+QCheckBox* RKFindBar::getOption (const RKFindBar::FindOptions option) {
+ RK_TRACE (APP);
+
+ if (!default_actions.contains (option)) {
+ QCheckBox* action;
+ if (option == MatchCase) {
+ action = new QCheckBox (i18n ("Match case"), this);
+ } else if (option == FindAsYouType) {
+ action = new QCheckBox (i18n ("Find as you type"), this);
+ action->setChecked (true);
+ } else if (option == HighlightAll) {
+ action = new QCheckBox (i18n ("Highlight all matches"), this);
+ } else {
+ RK_ASSERT (false);
+ }
+ connect (action, SIGNAL(stateChanged(int)), this, SLOT(searchChanged()));
+ default_actions.insert (option, action);
+ }
+
+ return (default_actions[option]);
+}
+
+bool RKFindBar::isOptionSet (const RKFindBar::FindOptions option) const {
+ if (!default_actions.contains (option)) return false;
+ return default_actions[option]->isChecked ();
+}
+
+void RKFindBar::searchChanged () {
+ RK_TRACE (APP);
+ term_edit->lineEdit ()->setFocus ();
+ if (default_actions.contains (FindAsYouType) && default_actions[FindAsYouType]->isChecked ()) forward ();
+}
+
+void RKFindBar::forward () {
+ RK_TRACE (APP);
+ doSearch (false);
+}
+
+void RKFindBar::backward () {
+ RK_TRACE (APP);
+ doSearch (true);
+}
+
+void RKFindBar::doSearch (bool backward) {
+ RK_TRACE (APP);
+ show ();
+ bool found = false;
+ QString term = term_edit->currentText ();
+ findRequest (term, backward, this, &found);
+ if (found || term.isEmpty ()) term_edit->lineEdit ()->setPalette (regular_palette);
+ else term_edit->lineEdit ()->setPalette (nomatch_palette);
+}
+
+void RKFindBar::activate () {
+ RK_TRACE (APP);
+
+ show ();
+ term_edit->lineEdit ()->selectAll ();
+ term_edit->lineEdit ()->setFocus ();
+}
+
+void RKFindBar::activateWithFindAsYouType () {
+ RK_TRACE (APP);
+
+ getOption (FindAsYouType)->setChecked (true);
+ activate ();
+}
+
+
+#include "rkfindbar.moc"
diff --git a/rkward/misc/rkfindbar.h b/rkward/misc/rkfindbar.h
new file mode 100644
index 0000000..9c9615c
--- /dev/null
+++ b/rkward/misc/rkfindbar.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ rkfindbar - description
+ -------------------
+ begin : Tue Feb 24 2015
+ copyright : (C) 2015 by Thomas Friedrichsmeier
+ email : tfry at users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 RKFINDBAR_H
+#define RKFINDBAR_H
+
+#include <QWidget>
+#include <QMap>
+
+class QCheckBox;
+class KHistoryComboBox;
+class QHBoxLayout;
+
+class RKFindBar : public QWidget {
+ Q_OBJECT
+public:
+ RKFindBar (QWidget *parent, bool custom=false);
+ ~RKFindBar ();
+
+ enum FindOptions {
+ HighlightAll,
+ FindAsYouType,
+ MatchCase
+ };
+
+/** Insert the given option-widgets into the search bar. Widgets must be owned by the find bar.
+
+I'd love to be able to implement options as QWidgetAction, instead of QWidgets.
+However, these can't be inserted into anything other than QToolBar or QMenu... */
+ void setPrimaryOptions (const QList<QWidget*>& options);
+
+ QCheckBox* getOption (const FindOptions option);
+ bool isOptionSet (const FindOptions option) const;
+public slots:
+ void activate ();
+ void activateWithFindAsYouType ();
+ void forward ();
+ void backward ();
+signals:
+ void findRequest (const QString& text, bool backwards, const RKFindBar *findbar, bool *result);
+private slots:
+/** search term _or_ search options changed. Triggers a forward search, if FindAsYouType is active */
+ void searchChanged ();
+private:
+ QMap<FindOptions, QCheckBox*> default_actions;
+ KHistoryComboBox* term_edit;
+ QHBoxLayout *mlayout;
+ void doSearch (bool backward);
+ QPalette regular_palette;
+ QPalette nomatch_palette;
+};
+
+#endif
diff --git a/rkward/windows/rkhelpwindow.rc b/rkward/windows/rkhelpwindow.rc
index 3b3bbde..55cd006 100644
--- a/rkward/windows/rkhelpwindow.rc
+++ b/rkward/windows/rkhelpwindow.rc
@@ -8,6 +8,10 @@
<Menu name="edit"><text>&Edit</text>
<Action name="copy"/>
<Separator/>
+ <Action name="find"/>
+ <Action name="find_next"/>
+ <Action name="find_previous"/>
+ <Separator/>
<Action name="select_all"/>
</Menu>
<Menu name="view"><text>&View</text>
diff --git a/rkward/windows/rkhtmlwindow.cpp b/rkward/windows/rkhtmlwindow.cpp
index 9434f69..5b9d624 100644
--- a/rkward/windows/rkhtmlwindow.cpp
+++ b/rkward/windows/rkhtmlwindow.cpp
@@ -60,6 +60,7 @@
#include "../misc/rkxmlguisyncer.h"
#include "../misc/rkprogresscontrol.h"
#include "../misc/rkmessagecatalog.h"
+#include "../misc/rkfindbar.h"
#include "../plugin/rkcomponentmap.h"
#include "../windows/rkworkplace.h"
#include "../windows/rkworkplaceview.h"
@@ -124,11 +125,16 @@ RKHTMLWindow::RKHTMLWindow (QWidget *parent, WindowMode mode) : RKMDIWindow (par
page = new RKWebPage (this);
view->setPage (page);
view->setContextMenuPolicy (Qt::CustomContextMenu);
- layout->addWidget (view);
+ layout->addWidget (view, 1);
+ findbar = new RKFindBar (this);
+ layout->addWidget (findbar);
+ findbar->hide ();
+ connect (findbar, SIGNAL(findRequest(QString,bool,const RKFindBar*,bool*)), this, SLOT(findRequest(QString,bool,const RKFindBar*,bool*)));
+ bool have_highlight = false;
+
part = new RKHTMLWindowPart (this);
setPart (part);
part->initActions ();
-
initializeActivationSignals ();
part->setSelectable (true);
setFocusPolicy (Qt::StrongFocus);
@@ -198,6 +204,22 @@ void RKHTMLWindow::runSelection () {
RKConsole::pipeUserCommand (view->selectedText ());
}
+void RKHTMLWindow::findRequest (const QString& text, bool backwards, const RKFindBar* findbar, bool* found) {
+ RK_TRACE (APP);
+
+ QWebPage::FindFlags flags = QWebPage::FindWrapsAroundDocument;
+ if (backwards) flags |= QWebPage::FindBackward;
+ bool highlight = findbar->isOptionSet (RKFindBar::HighlightAll);
+ if (highlight) flags |= QWebPage::HighlightAllOccurrences;
+ if (findbar->isOptionSet (RKFindBar::MatchCase)) flags |= QWebPage::FindCaseSensitively;
+
+ // clear previous highlight, if any
+ if (have_highlight) page->findText (QString (), QWebPage::HighlightAllOccurrences);
+
+ *found = page->findText (text, flags);
+ have_highlight = found && highlight;
+}
+
void RKHTMLWindow::slotPrint () {
RK_TRACE (APP);
@@ -561,7 +583,7 @@ void RKHTMLWindowPart::initActions () {
connect (zoom_in, SIGNAL(triggered(bool)), window, SLOT (zoomIn()));
QAction* zoom_out = actionCollection ()->addAction ("zoom_out", new KAction (KIcon ("zoom-out"), i18n ("Zoom Out"), this));
connect (zoom_out, SIGNAL(triggered(bool)), window, SLOT (zoomOut()));
- QAction* select_all = actionCollection ()->addAction (KStandardAction::SelectAll, "select_all", window->view->pageAction (QWebPage::SelectAll), SLOT (trigger()));
+ actionCollection ()->addAction (KStandardAction::SelectAll, "select_all", window->view->pageAction (QWebPage::SelectAll), SLOT (trigger()));
// unfortunately, this will only affect the default encoding, not necessarily the "real" encoding
KCodecAction *encoding = new KCodecAction (KIcon ("character-set"), i18n ("Default &Encoding"), this, true);
encoding->setStatusTip (i18n ("Set the encoding to assume in case no explicit encoding has been set in the page or in the HTTP headers."));
@@ -589,12 +611,13 @@ void RKHTMLWindowPart::initActions () {
outputRefresh->setText (i18n ("&Refresh Output"));
outputRefresh->setIcon (KIcon ("view-refresh"));
- // TODO!!!
- QAction* find;
- QAction* findAhead; // shortcut '/'
- QAction* find_next;
- QAction* find_previous;
-
+ actionCollection ()->addAction (KStandardAction::Find, "find", window->findbar, SLOT (activate()));
+ KAction* findAhead = actionCollection ()->addAction ("find_ahead", new KAction (i18n ("Find as you type"), this));
+ findAhead->setShortcut ('/');
+ connect (findAhead, SIGNAL (triggered(bool)), window->findbar, SLOT (activate()));
+ actionCollection ()->addAction (KStandardAction::FindNext, "find_next", window->findbar, SLOT (forward()));;
+ actionCollection ()->addAction (KStandardAction::FindPrev, "find_previous", window->findbar, SLOT (backward()));;;
+}
void RKHTMLWindowPart::setOutputWindowSkin () {
RK_TRACE (APP);
diff --git a/rkward/windows/rkhtmlwindow.h b/rkward/windows/rkhtmlwindow.h
index c5a87e8..ef1e44e 100644
--- a/rkward/windows/rkhtmlwindow.h
+++ b/rkward/windows/rkhtmlwindow.h
@@ -36,6 +36,7 @@ class RKHTMLWindowPart;
class KWebView;
class KTemporaryFile;
class RKHTMLWindow;
+class RKFindBar;
class RKWebPage : public KWebPage {
Q_OBJECT
@@ -114,10 +115,13 @@ private slots:
void mimeTypeDetermined (KIO::Job*, const QString& type);
void internalNavigation (const QUrl& new_url);
void makeContextMenu (const QPoint& pos);
+ void findRequest (const QString& text, bool backwards, const RKFindBar *findbar, bool* found);
private:
friend class RKHTMLWindowPart;
KWebView* view;
RKWebPage* page;
+ RKFindBar* findbar;
+ bool have_highlight;
/** In case the part is a khtmlpart: A ready-cast pointer to that. 0 otherwise (if a webkit part is in use) */
RKHTMLWindowPart *part;
/** update caption according to given URL */
diff --git a/rkward/windows/rkoutputwindow.rc b/rkward/windows/rkoutputwindow.rc
index 2aa6987..1766340 100644
--- a/rkward/windows/rkoutputwindow.rc
+++ b/rkward/windows/rkoutputwindow.rc
@@ -8,6 +8,10 @@
<Menu name="edit"><text>&Edit</text>
<Action name="copy"/>
<Separator/>
+ <Action name="find"/>
+ <Action name="find_next"/>
+ <Action name="find_previous"/>
+ <Separator/>
<Action name="select_all"/>
<Separator/>
<Action name="output_flush"/>
More information about the rkward-tracker
mailing list