Text searching problems

Updates the behaviour of the search function. Thanks to qnikst.
This commit is contained in:
Moritz Lipp 2010-12-21 11:53:40 +01:00
parent 9f8441461d
commit 10659ac545

171
zathura.c
View file

@ -35,7 +35,7 @@ enum { NEXT, PREVIOUS, LEFT, RIGHT, UP, DOWN, BOTTOM, TOP, HIDE, HIGHLIGHT,
BACKWARD, ADJUST_BESTFIT, ADJUST_WIDTH, ADJUST_NONE, CONTINUOUS, DELETE_LAST, BACKWARD, ADJUST_BESTFIT, ADJUST_WIDTH, ADJUST_NONE, CONTINUOUS, DELETE_LAST,
ADD_MARKER, EVAL_MARKER, EXPAND, COLLAPSE, SELECT, GOTO_DEFAULT, GOTO_LABELS, ADD_MARKER, EVAL_MARKER, EXPAND, COLLAPSE, SELECT, GOTO_DEFAULT, GOTO_LABELS,
GOTO_OFFSET, HALF_UP, HALF_DOWN, FULL_UP, FULL_DOWN, NEXT_CHAR, PREVIOUS_CHAR, GOTO_OFFSET, HALF_UP, HALF_DOWN, FULL_UP, FULL_DOWN, NEXT_CHAR, PREVIOUS_CHAR,
DELETE_TO_LINE_START, APPEND_FILEPATH }; DELETE_TO_LINE_START, APPEND_FILEPATH, NO_SEARCH };
/* define modes */ /* define modes */
#define ALL (1 << 0) #define ALL (1 << 0)
@ -321,6 +321,7 @@ struct
GList* results; GList* results;
int page; int page;
gboolean draw; gboolean draw;
gchar* query;
} Search; } Search;
struct struct
@ -451,7 +452,7 @@ void bcmd_setmarker(char*, Argument*);
void bcmd_zoom(char*, Argument*); void bcmd_zoom(char*, Argument*);
/* special command delcarations */ /* special command delcarations */
gboolean scmd_search(char*, Argument*); gboolean scmd_search(gchar*, Argument*);
/* callback declarations */ /* callback declarations */
gboolean cb_destroy(GtkWidget*, gpointer); gboolean cb_destroy(GtkWidget*, gpointer);
@ -680,6 +681,7 @@ init_zathura(void)
Zathura.Search.results = NULL; Zathura.Search.results = NULL;
Zathura.Search.page = 0; Zathura.Search.page = 0;
Zathura.Search.draw = FALSE; Zathura.Search.draw = FALSE;
Zathura.Search.query = NULL;
Zathura.FileMonitor.monitor = NULL; Zathura.FileMonitor.monitor = NULL;
Zathura.FileMonitor.file = NULL; Zathura.FileMonitor.file = NULL;
@ -1852,71 +1854,83 @@ search(void* parameter)
static char* search_item; static char* search_item;
static int direction; static int direction;
static int next_page = 0; static int next_page = 0;
gchar* old_query;
int page_counter; int page_counter;
GList* results = NULL; GList* results = NULL;
if(argument->data) if(argument->n != NO_SEARCH)
{ {
if(search_item) if(argument->data)
g_free(search_item);
search_item = g_strdup((char*) argument->data);
}
g_static_mutex_lock(&(Zathura.Lock.pdf_obj_lock));
if(!Zathura.PDF.document || !search_item || !strlen(search_item))
{
g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
g_static_mutex_lock(&(Zathura.Lock.search_lock));
Zathura.Thread.search_thread_running = FALSE;
g_static_mutex_unlock(&(Zathura.Lock.search_lock));
g_thread_exit(NULL);
}
/* delete old results */
if(Zathura.Search.results)
{
g_list_free(Zathura.Search.results);
Zathura.Search.results = NULL;
}
/* search document */
if(argument->n)
direction = (argument->n == BACKWARD) ? -1 : 1;
int number_of_pages = Zathura.PDF.number_of_pages;
int page_number = Zathura.PDF.page_number;
g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
for(page_counter = 1; page_counter <= number_of_pages; page_counter++)
{
g_static_mutex_lock(&(Zathura.Lock.search_lock));
if(Zathura.Thread.search_thread_running == FALSE)
{ {
if(search_item)
g_free(search_item);
search_item = g_strdup((char*) argument->data);
}
g_static_mutex_lock(&(Zathura.Lock.pdf_obj_lock));
if(!Zathura.PDF.document || !search_item || !strlen(search_item))
{
g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
g_static_mutex_lock(&(Zathura.Lock.search_lock));
Zathura.Thread.search_thread_running = FALSE;
g_static_mutex_unlock(&(Zathura.Lock.search_lock)); g_static_mutex_unlock(&(Zathura.Lock.search_lock));
g_thread_exit(NULL); g_thread_exit(NULL);
} }
g_static_mutex_unlock(&(Zathura.Lock.search_lock));
next_page = (number_of_pages + page_number + old_query = Zathura.Search.query;
page_counter * direction) % number_of_pages;
g_static_mutex_lock(&(Zathura.Lock.pdflib_lock)); /* delete old results */
PopplerPage* page = poppler_document_get_page(Zathura.PDF.document, next_page); if(Zathura.Search.results)
g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock)); {
g_list_free(Zathura.Search.results);
Zathura.Search.results = NULL;
}
if(!page) /* search document */
g_thread_exit(NULL); if(argument->n)
direction = (argument->n == BACKWARD) ? -1 : 1;
g_static_mutex_lock(&(Zathura.Lock.pdflib_lock)); Zathura.Search.query = g_strdup(search_item);
results = poppler_page_find_text(page, search_item);
g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
g_object_unref(page); int number_of_pages = Zathura.PDF.number_of_pages;
int page_number = Zathura.PDF.page_number;
if(results) g_static_mutex_unlock(&(Zathura.Lock.pdf_obj_lock));
break;
page_counter = (g_strcmp0(old_query,search_item) == 0) ? 1 : 0;
for( ; page_counter <= number_of_pages; page_counter++)
{
g_static_mutex_lock(&(Zathura.Lock.search_lock));
if(Zathura.Thread.search_thread_running == FALSE)
{
g_static_mutex_unlock(&(Zathura.Lock.search_lock));
g_thread_exit(NULL);
}
g_static_mutex_unlock(&(Zathura.Lock.search_lock));
next_page = (number_of_pages + page_number +
page_counter * direction) % number_of_pages;
g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
PopplerPage* page = poppler_document_get_page(Zathura.PDF.document, next_page);
g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
if(!page)
{
g_free(old_query);
g_thread_exit(NULL);
}
g_static_mutex_lock(&(Zathura.Lock.pdflib_lock));
results = poppler_page_find_text(page, search_item);
g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock));
g_object_unref(page);
if(results)
break;
}
} }
/* draw results */ /* draw results */
@ -1932,6 +1946,7 @@ search(void* parameter)
Zathura.Search.results = results; Zathura.Search.results = results;
Zathura.Search.page = next_page; Zathura.Search.page = next_page;
Zathura.Search.draw = TRUE; Zathura.Search.draw = TRUE;
Zathura.Search.query = g_strdup(search_item);
gdk_threads_leave(); gdk_threads_leave();
} }
@ -1940,6 +1955,7 @@ search(void* parameter)
Zathura.Thread.search_thread_running = FALSE; Zathura.Thread.search_thread_running = FALSE;
g_static_mutex_unlock(&(Zathura.Lock.search_lock)); g_static_mutex_unlock(&(Zathura.Lock.search_lock));
g_free(old_query);
g_thread_exit(NULL); g_thread_exit(NULL);
return NULL; return NULL;
} }
@ -3988,12 +4004,12 @@ bcmd_zoom(char* buffer, Argument* argument)
/* special command implementation */ /* special command implementation */
gboolean gboolean
scmd_search(char* input, Argument* argument) scmd_search(gchar* input, Argument* argument)
{ {
if(!strlen(input)) if(!input || !strlen(input))
return TRUE; return TRUE;
argument->data = input; argument->data = g_strdup(input);
sc_search(argument); sc_search(argument);
return TRUE; return TRUE;
@ -4129,18 +4145,55 @@ cb_inputbar_kb_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
} }
/* special commands */ /* special commands */
char identifier = gtk_editable_get_chars(GTK_EDITABLE(Zathura.UI.inputbar), 0, 1)[0]; char* identifier_string = gtk_editable_get_chars(GTK_EDITABLE(Zathura.UI.inputbar), 0, 1);
char identifier = identifier_string[0];
for(i = 0; i < LENGTH(special_commands); i++) for(i = 0; i < LENGTH(special_commands); i++)
{ {
if((identifier == special_commands[i].identifier) && if((identifier == special_commands[i].identifier) &&
(special_commands[i].always == 1)) (special_commands[i].always == 1))
{ {
gchar *input = gtk_editable_get_chars(GTK_EDITABLE(Zathura.UI.inputbar), 1, -1); gchar *input = gtk_editable_get_chars(GTK_EDITABLE(Zathura.UI.inputbar), 1, -1);
special_commands[i].function(input, &(special_commands[i].argument)); guint new_utf_char = gdk_keyval_to_unicode(event->keyval);
if(new_utf_char != 0)
{
gchar* newchar = malloc(6 * sizeof(gchar));
if(newchar == NULL)
{
g_free(input);
continue;
}
gint len = g_unichar_to_utf8(new_utf_char, newchar);
newchar[len] = 0;
gchar* tmp = g_strconcat(input, newchar, NULL);
g_free(input);
g_free(newchar);
input = tmp;
}
// FIXME
if((special_commands[i].function == scmd_search) && (event->keyval == GDK_Return))
{
Argument argument = { NO_SEARCH, NULL };
scmd_search(input, &argument);
}
else
{
special_commands[i].function(input, &(special_commands[i].argument));
}
g_free(identifier_string);
g_free(input);
return FALSE; return FALSE;
} }
} }
g_free(identifier_string);
return FALSE; return FALSE;
} }