aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--dw/findtext.cc124
-rw-r--r--dw/findtext.hh10
-rw-r--r--dw/layout.hh4
-rw-r--r--src/findbar.cc31
-rw-r--r--src/findbar.hh3
-rw-r--r--src/uicmd.cc6
-rw-r--r--src/uicmd.hh3
-rw-r--r--test/dw_find_test.cc2
9 files changed, 150 insertions, 37 deletions
diff --git a/ChangeLog b/ChangeLog
index a4e7e3c1..919c388b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,8 @@ dillo-2.1
+- Added support for numeric IPv6 addresses entered into the url bar.
- Used the URL authority part instead of stripped default port in HTTP query.
Patches: Justus Winter
++- Implemented "search previous" in string searches.
+ Patch: João Ricardo Lourenço
+- Fix for file inputs without values (forms).
- Tuned input width a bit.
- Cleaned up resource embedding (forms)
@@ -50,7 +52,7 @@ dillo-2.1
+- Added the "middle_click_drags_page" dillorc option.
Patch: Jorge Arellano Cid, Thomas Orgis
+- Set the File menu label to hide when the File menu-button is shown.
- - Trying a new iconv() test in configure.in.
+ - Set a new iconv() test in configure.in.
- Allowed the rc parser to skip whitespace around the equal sign.
- Fixed the parser not to call Html_tag_close_* functions twice.
- Implemented loading of remote CSS Stylesheet.
diff --git a/dw/findtext.cc b/dw/findtext.cc
index 15de9f16..93564692 100644
--- a/dw/findtext.cc
+++ b/dw/findtext.cc
@@ -21,6 +21,7 @@
#include "core.hh"
+#include "../lout/msg.h"
namespace dw {
namespace core {
@@ -66,7 +67,8 @@ void FindtextState::setWidget (Widget *widget)
hlIterator = NULL;
}
-FindtextState::Result FindtextState::search (const char *key, bool caseSens)
+FindtextState::Result FindtextState::search (const char *key, bool caseSens,
+ bool backwards)
{
if (!widget || *key == 0) // empty keys are not found
return NOT_FOUND;
@@ -86,18 +88,25 @@ FindtextState::Result FindtextState::search (const char *key, bool caseSens)
if (nexttab)
delete[] nexttab;
- nexttab = createNexttab (key, caseSens);
+ nexttab = createNexttab (key, caseSens, backwards);
if (iterator)
delete iterator;
iterator = new CharIterator (widget);
- iterator->next ();
+
+ if (backwards) {
+ /* Go to end */
+ while(iterator->next () ) ;
+ iterator->prev (); //We don't want to be at CharIterator::END.
+ } else {
+ iterator->next ();
+ }
} else
newKey = false;
bool firstTrial = !wasHighlighted || newKey;
- if (search0 ()) {
+ if (search0 (backwards, firstTrial)) {
// Highlighlighting is done with a clone.
hlIterator = iterator->cloneCharIterator ();
for (int i = 0; key[i]; i++)
@@ -110,16 +119,21 @@ FindtextState::Result FindtextState::search (const char *key, bool caseSens)
iterator->next ();
return SUCCESS;
} else {
- if (firstTrial)
+ if (firstTrial) {
return NOT_FOUND;
- else {
+ } else {
// Nothing found anymore, reset the state for the next trial.
delete iterator;
iterator = new CharIterator (widget);
- iterator->next ();
-
+ if (backwards) {
+ /* Go to end */
+ while(iterator->next ()) ;
+ iterator->prev (); //We don't want to be at CharIterator::END.
+ } else {
+ iterator->next ();
+ }
// We expect a success.
- Result result2 = search (key, caseSens);
+ Result result2 = search (key, caseSens, backwards);
assert (result2 == SUCCESS);
return RESTART;
}
@@ -138,8 +152,29 @@ void FindtextState::resetSearch ()
key = NULL;
}
-int *FindtextState::createNexttab (const char *key, bool caseSens)
+/*
+ * Return a new string: with the reverse of the original.
+ */
+const char* FindtextState::rev(const char *str)
{
+ if (!str)
+ return NULL;
+
+ int len = strlen(str);
+ char *nstr = new char[len+1];
+ for (int i = 0; i < len; ++i)
+ nstr[i] = str[len-1 -i];
+ nstr[len] = 0;
+
+ return nstr;
+}
+
+int *FindtextState::createNexttab (const char *needle, bool caseSens,
+ bool backwards)
+{
+ const char* key;
+
+ key = (backwards) ? rev(needle) : needle;
int i = 0;
int j = -1;
int l = strlen (key);
@@ -156,6 +191,9 @@ int *FindtextState::createNexttab (const char *key, bool caseSens)
j = nexttab[j];
} while (i < l - 1);
+ if (backwards)
+ delete [] key;
+
return nexttab;
}
@@ -179,30 +217,76 @@ bool FindtextState::unhighlight ()
return false;
}
-bool FindtextState::search0 ()
+bool FindtextState::search0 (bool backwards, bool firstTrial)
{
if (iterator->getChar () == CharIterator::END)
return false;
-
+
+ bool ret = false;
+ const char* searchKey = (backwards) ? rev(key) : key;
int j = 0;
bool nextit = true;
int l = strlen (key);
+ if (backwards && !firstTrial) {
+ _MSG("Having to do.");
+ /* Position correctly */
+ /* In order to achieve good results (i.e: find a word that ends within
+ * the previously searched word's limit) we have to position the
+ * iterator in the semilast character of the previously searched word.
+ *
+ * Since we know that if a word was found before it was exactly the
+ * same word as the one we are searching for now, we can apply the
+ * following expression:
+ *
+ * Where l=length of the key and n=num of positions to move:
+ *
+ * n = l - 3
+ *
+ * If n is negative, we have to move backwards, but if it is
+ * positive, we have to move forward. So, when l>=4, we start moving
+ * the iterator forward. */
+
+ if (l==1) {
+ iterator->prev();
+ iterator->prev();
+ } else if (l==2) {
+ iterator->prev();
+ } else if (l>=4) {
+ for (int i=0; i<l-3; i++) {
+ iterator->next();
+ }
+ }
+
+ } else if (backwards && l==1) {
+ /* Particular case where we can't find the last character */
+ iterator->next();
+ }
+
do {
- if (j == -1 || charsEqual (iterator->getChar (), key[j], caseSens)) {
+ if (j == -1 || charsEqual (iterator->getChar(),searchKey[j],caseSens)) {
j++;
- nextit = iterator->next ();
+ nextit = backwards ? iterator->prev () : iterator->next ();
} else
j = nexttab[j];
} while (nextit && j < l);
if (j >= l) {
- // Go back to where the word was found.
- for (int i = 0; i < l; i++)
- iterator->prev ();
- return true;
- } else
- return false;
+ if (backwards) {
+ //This is the location of the key
+ iterator->next();
+ } else {
+ // Go back to where the key was found.
+ for (int i = 0; i < l; i++)
+ iterator->prev ();
+ }
+ ret = true;
+ }
+
+ if (backwards)
+ delete [] searchKey;
+
+ return ret;
}
} // namespace dw
diff --git a/dw/findtext.hh b/dw/findtext.hh
index e9fb57c2..83d22bd3 100644
--- a/dw/findtext.hh
+++ b/dw/findtext.hh
@@ -58,10 +58,12 @@ private:
* NULL, when no text is highlighted.
*/
CharIterator *hlIterator;
-
- static int *createNexttab (const char *key, bool caseSens);
+
+ static const char* rev(const char* _str); /* Function to reverse a C-string */
+
+ static int *createNexttab (const char *needle, bool caseSens, bool backwards);
bool unhighlight ();
- bool search0 ();
+ bool search0 (bool backwards, bool firstTrial);
inline static bool charsEqual (char c1, char c2, bool caseSens)
{ return caseSens ? c1 == c2 : tolower (c1) == tolower (c2) ||
@@ -72,7 +74,7 @@ public:
~FindtextState ();
void setWidget (Widget *widget);
- Result search (const char *key, bool caseSens);
+ Result search (const char *key, bool caseSens, bool backwards);
void resetSearch ();
};
diff --git a/dw/layout.hh b/dw/layout.hh
index ce9786f1..b66d653f 100644
--- a/dw/layout.hh
+++ b/dw/layout.hh
@@ -255,8 +255,8 @@ public:
emitter.connectLayout (receiver); }
/** \brief See dw::core::FindtextState::search. */
- inline FindtextState::Result search (const char *str, bool caseSens)
- { return findtextState.search (str, caseSens); }
+ inline FindtextState::Result search (const char *str, bool caseSens, int backwards)
+ { return findtextState.search (str, caseSens, backwards); }
/** \brief See dw::core::FindtextState::resetSearch. */
inline void resetSearch () { findtextState.resetSearch (); }
diff --git a/src/findbar.cc b/src/findbar.cc
index 5d1c6245..ea1c80f1 100644
--- a/src/findbar.cc
+++ b/src/findbar.cc
@@ -63,7 +63,22 @@ void Findbar::search_cb(Widget *, void *vfb)
if (key[0] != '\0')
a_UIcmd_findtext_search(a_UIcmd_get_bw_by_widget(fb),
- key, case_sens);
+ key, case_sens, false);
+}
+
+/*
+ * Find previous occurrence of input key
+ */
+void Findbar::searchBackwards_cb(Widget *, void *vfb)
+{
+ Findbar *fb = (Findbar *)vfb;
+ const char *key = fb->i->text();
+ bool case_sens = fb->check_btn->value();
+
+ if (key[0] != '\0') {
+ a_UIcmd_findtext_search(a_UIcmd_get_bw_by_widget(fb),
+ key, case_sens, true);
+ }
}
/*
@@ -96,7 +111,7 @@ Findbar::Findbar(int width, int height) :
int button_width = 70;
int gap = 2;
int border = 2;
- int input_width = width - (2 * border + 3 * (button_width + gap));
+ int input_width = width - (2 * border + 4 * (button_width + gap));
int x = border;
height -= 2 * border;
@@ -121,15 +136,23 @@ Findbar::Findbar(int width, int height) :
i->clear_tab_to_focus();
i->set_click_to_focus();
- // TODO: search previous would be nice
next_btn = new HighlightButton(x, border, button_width, height, "Next");
x += button_width + gap;
- next_btn->tooltip("Find next occurrence of the search phrase");
+ next_btn->tooltip("Find next occurrence of the search phrase\n"
+ "shortcut: Enter");
next_btn->add_shortcut(ReturnKey);
next_btn->add_shortcut(KeypadEnter);
next_btn->callback(search_cb, this);
next_btn->clear_tab_to_focus();
+ prev_btn= new HighlightButton(x, border, button_width, height, "Previous");
+ prev_btn->tooltip("Find previous occurrence of the search phrase\n"
+ "shortcut: Shift+Enter");
+ prev_btn->add_shortcut(SHIFT+ReturnKey);
+ prev_btn->callback(searchBackwards_cb, this);
+ prev_btn->clear_tab_to_focus();
+ x += button_width + gap;
+
check_btn = new CheckButton(x, border, 2*button_width, height,
"Case-sensitive");
check_btn->clear_tab_to_focus();
diff --git a/src/findbar.hh b/src/findbar.hh
index 1e8c8d66..90982ffd 100644
--- a/src/findbar.hh
+++ b/src/findbar.hh
@@ -16,12 +16,13 @@ using namespace fltk;
*/
class Findbar : public Group {
Button *clrb;
- HighlightButton *hide_btn, *next_btn;
+ HighlightButton *hide_btn, *next_btn, *prev_btn;
CheckButton *check_btn;
xpmImage *hideImg;
Input *i;
static void search_cb (Widget *, void *);
+ static void searchBackwards_cb (Widget *, void *);
static void search_cb2 (Widget *, void *);
static void hide_cb (Widget *, void *);
diff --git a/src/uicmd.cc b/src/uicmd.cc
index 75d6336e..620669af 100644
--- a/src/uicmd.cc
+++ b/src/uicmd.cc
@@ -948,13 +948,13 @@ void a_UIcmd_fullscreen_toggle(BrowserWindow *bw)
}
/*
- * Search for next occurrence of key.
+ * Search for next/previous occurrence of key.
*/
-void a_UIcmd_findtext_search(BrowserWindow *bw, const char *key, int case_sens)
+void a_UIcmd_findtext_search(BrowserWindow *bw, const char *key, int case_sens, int backwards)
{
Layout *l = (Layout *)bw->render_layout;
- switch (l->search(key, case_sens)) {
+ switch (l->search(key, case_sens, backwards)) {
case FindtextState::RESTART:
a_UIcmd_set_msg(bw, "No further occurrences of \"%s\". "
"Restarting from the top.", key);
diff --git a/src/uicmd.hh b/src/uicmd.hh
index ca5b7cc5..b08b4f8d 100644
--- a/src/uicmd.hh
+++ b/src/uicmd.hh
@@ -34,7 +34,8 @@ void a_UIcmd_book(void *vbw);
void a_UIcmd_add_bookmark(BrowserWindow *bw, const DilloUrl *url);
void a_UIcmd_fullscreen_toggle(BrowserWindow *bw);
void a_UIcmd_findtext_dialog(BrowserWindow *bw);
-void a_UIcmd_findtext_search(BrowserWindow *bw,const char *key,int case_sens);
+void a_UIcmd_findtext_search(BrowserWindow *bw,const char *key,int case_sens,
+ int backwards);
void a_UIcmd_findtext_reset(BrowserWindow *bw);
void a_UIcmd_focus_main_area(BrowserWindow *bw);
void a_UIcmd_focus_location(void *vbw);
diff --git a/test/dw_find_test.cc b/test/dw_find_test.cc
index 651ca653..50f2d1aa 100644
--- a/test/dw_find_test.cc
+++ b/test/dw_find_test.cc
@@ -44,7 +44,7 @@ static ::fltk::Widget *resultLabel;
static void findCallback (::fltk::Widget *widget, void *data)
{
//switch(layout->search ("worm", true)) {
- switch(layout->search ("WORM", false)) {
+ switch(layout->search ("WORM", false, false)) {
case FindtextState::SUCCESS:
resultLabel->label("SUCCESS");
break;