gnome-commander r1662 - in trunk: . doc/C src
- From: epiotr svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-commander r1662 - in trunk: . doc/C src
- Date: Wed, 26 Mar 2008 16:42:23 +0000 (GMT)
Author: epiotr
Date: Wed Mar 26 16:42:23 2008
New Revision: 1662
URL: http://svn.gnome.org/viewvc/gnome-commander?rev=1662&view=rev
Log:
Bugfixes + added accelerators to the search dlg
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/doc/C/gnome-commander.xml
trunk/src/gnome-cmd-search-dialog.cc
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Wed Mar 26 16:42:23 2008
@@ -10,6 +10,7 @@
* Root Mode for starting GNOME Commander with administrator privileges
* GUI for keyboard shortcuts management
* Multi-Rename-Tool - new $x and $X placeholders for random hexadecimal numbers
+ * Revamped search dialog
* Updated help docs
* New or updated translations: en_GB, es, eu, fi, oc, pl
* New key bindings:
Modified: trunk/doc/C/gnome-commander.xml
==============================================================================
--- trunk/doc/C/gnome-commander.xml (original)
+++ trunk/doc/C/gnome-commander.xml Wed Mar 26 16:42:23 2008
@@ -5838,6 +5838,9 @@
<para>Multi-Rename-Tool - new $x and $X placeholders for random hexadecimal numbers</para>
</listitem>
<listitem>
+ <para>Revamped search dialog</para>
+ </listitem>
+ <listitem>
<para>Updated help docs</para>
</listitem>
<listitem>
Modified: trunk/src/gnome-cmd-search-dialog.cc
==============================================================================
--- trunk/src/gnome-cmd-search-dialog.cc (original)
+++ trunk/src/gnome-cmd-search-dialog.cc Wed Mar 26 16:42:23 2008
@@ -36,7 +36,10 @@
static GnomeCmdDialogClass *parent_class = NULL;
-#define PBAR_MAX 50
+#define PBAR_MAX 50
+
+#define SEARCH_JUMP_SIZE 4096U
+#define SEARCH_BUFFER_SIZE (SEARCH_JUMP_SIZE * 10U)
struct ProtectedData
{
@@ -67,9 +70,18 @@
gboolean search_done;
gboolean stopped; // stops the search routine if set to TRUE. This is done by the stop_button
- gboolean dialog_destroyed; // set when the search dialog is destroyed, also stopps the search of course
+ gboolean dialog_destroyed; // set when the search dialog is destroyed, also stops the search of course
+
+ gchar *search_mem; // memory to search in the content of a file
};
+struct SearchFileData
+{
+ gchar *uri_str;
+ GnomeVFSHandle *handle;
+ gint offset;
+ guint len;
+};
struct _GnomeCmdSearchDialogPrivate
{
@@ -78,11 +90,9 @@
GnomeCmdCon *con;
GtkWidget *pattern_combo;
- GtkWidget *pattern_entry;
GtkWidget *dir_browser;
GtkWidget *dir_entry;
GtkWidget *find_text_combo;
- GtkWidget *find_text_entry;
GtkWidget *find_text_check;
GtkWidget *result_list;
GtkWidget *statusbar;
@@ -99,22 +109,6 @@
};
-static void on_search (GtkButton *button, GnomeCmdSearchDialog *dialog);
-
-
-static gboolean on_pattern_entry_keypressed (GtkWidget *entry, GdkEventKey *event, GnomeCmdSearchDialog *dialog)
-{
- if (state_is_blank (event->state) && event->keyval == GDK_Return)
- {
- on_search (NULL, dialog);
- event->keyval = GDK_Escape;
- return TRUE;
- }
-
- return FALSE;
-}
-
-
static void on_list_file_clicked (GnomeCmdFileList *fl, GnomeCmdFile *finfo, GdkEventButton *button, GnomeCmdSearchDialog *dialog)
{
if (dialog->priv->data->search_done)
@@ -134,76 +128,123 @@
data->context_id, msg);
}
+/**
+ *
+ */
+inline void search_file_data_free (SearchFileData *searchfile_data)
+{
+ if (searchfile_data->handle != NULL)
+ gnome_vfs_close (searchfile_data->handle);
+
+ g_free (searchfile_data->uri_str);
+ g_free (searchfile_data);
+}
/**
- * Loads a file and returns the content.
- * FIXME: Recode this so not the whole file has
- * to be loaded in memory.
+ * Loads a file in chunks and returns the content.
*/
-static gchar *load_file (GnomeCmdFile *finfo)
+static SearchFileData *read_search_file (SearchData *data,
+ SearchFileData *searchfile_data,
+ GnomeCmdFile *finfo)
{
g_return_val_if_fail (finfo != NULL, NULL);
g_return_val_if_fail (finfo->info != NULL, NULL);
- gchar *buf = (gchar *) g_malloc (finfo->info->size+1);
- gchar *uri_str = gnome_cmd_file_get_uri_str (finfo);
- GnomeVFSHandle *handle;
- GnomeVFSResult result = gnome_vfs_open (&handle, uri_str, GNOME_VFS_OPEN_READ);
+ GnomeVFSResult result;
- if (result != GNOME_VFS_OK)
+ if (searchfile_data == NULL)
+ {
+ searchfile_data = g_new0 (SearchFileData, 1);
+ searchfile_data->uri_str = gnome_cmd_file_get_uri_str (finfo);
+ result = gnome_vfs_open (&searchfile_data->handle, searchfile_data->uri_str, GNOME_VFS_OPEN_READ);
+
+ if (result != GNOME_VFS_OK)
+ {
+ warn_print (_("Failed to open file %s: %s\n"), searchfile_data->uri_str, gnome_vfs_result_to_string (result));
+ search_file_data_free (searchfile_data);
+ return NULL;
+ }
+ }
+
+ // If the stop button was pressed let's abort here
+ if (data->stopped)
{
- warn_print (_("Failed to open file %s: %s\n"), uri_str, gnome_vfs_result_to_string (result));
- g_free (uri_str);
- g_free (buf);
+ search_file_data_free (searchfile_data);
return NULL;
}
+ if (searchfile_data->len != NULL)
+ {
+ if ((searchfile_data->offset + searchfile_data->len) >= finfo->info->size)
+ { // end, all has been read
+ search_file_data_free (searchfile_data);
+ return NULL;
+ }
+ else
+ { // jump a big step backward to give the regex a chance
+ searchfile_data->offset += searchfile_data->len - SEARCH_JUMP_SIZE;
+ if (finfo->info->size < (searchfile_data->offset + (SEARCH_BUFFER_SIZE - 1)))
+ searchfile_data->len = finfo->info->size - searchfile_data->offset;
+ else
+ searchfile_data->len = SEARCH_BUFFER_SIZE - 1;
+ }
+ }
+ else
+ { // first time call of this function
+ if (finfo->info->size < (SEARCH_BUFFER_SIZE - 1))
+ searchfile_data->len = finfo->info->size;
+ else
+ searchfile_data->len = SEARCH_BUFFER_SIZE - 1;
+ }
+
GnomeVFSFileSize ret;
- result = gnome_vfs_read (handle, buf, finfo->info->size, &ret);
+ result = gnome_vfs_seek (searchfile_data->handle, GNOME_VFS_SEEK_START, searchfile_data->offset);
if (result != GNOME_VFS_OK)
{
- warn_print (_("Failed to read from file %s: %s\n"),
- uri_str, gnome_vfs_result_to_string (result));
- g_free (uri_str);
- g_free (buf);
- gnome_vfs_close (handle);
+ warn_print (_("Failed to seek in file %s: %s\n"), searchfile_data->uri_str, gnome_vfs_result_to_string (result));
+ search_file_data_free (searchfile_data);
return NULL;
}
+ result = gnome_vfs_read (searchfile_data->handle, data->search_mem, searchfile_data->len, &ret);
+ if (result != GNOME_VFS_OK)
+ {
+ warn_print (_("Failed to read from file %s: %s\n"), searchfile_data->uri_str, gnome_vfs_result_to_string (result));
+ search_file_data_free (searchfile_data);
+ return NULL;
+ }
+ data->search_mem[searchfile_data->len] = '\0';
- buf[ret] = '\0';
-
- g_free (uri_str);
- gnome_vfs_close (handle);
-
- return buf;
+ return searchfile_data;
}
/**
- * Determinates if the name of a file matches an regexp
+ * Determines if the content of a file matches an regexp
*
*/
-inline gboolean name_matches (gchar *name, SearchData *data)
+inline gboolean content_matches (GnomeCmdFile *finfo, SearchData *data)
{
- return filter_match (data->name_filter, name);
-}
+ gint ret = REG_NOMATCH;
+ if (finfo->info->size > 0)
+ {
+ regmatch_t match;
+ SearchFileData *search_file = NULL;
+
+ while ((search_file = read_search_file (data, search_file, finfo)) != NULL)
+ ret = regexec (data->content_regex, data->search_mem, 1, &match, 0);
+ }
+
+ return ret != REG_NOMATCH;
+}
/**
- * Determinates if the content of a file matches an regexp
+ * Determines if the name of a file matches an regexp
*
*/
-inline gboolean content_matches (GnomeCmdFile *finfo, SearchData *data)
+inline gboolean name_matches (gchar *name, SearchData *data)
{
- static regmatch_t match;
- gint ret = REG_NOMATCH;
- gchar *buf = load_file (finfo);
- if (buf)
- {
- ret = regexec (data->content_regex, buf, 1, &match, 0);
- g_free (buf);
- }
- return ret == 0;
+ return filter_match (data->name_filter, name);
}
@@ -389,6 +430,9 @@
gtk_widget_set_sensitive (data->dialog->priv->search_button, TRUE);
gtk_widget_set_sensitive (data->dialog->priv->stop_button, FALSE);
+ // set focus to result list
+ gtk_widget_grab_focus (data->dialog->priv->result_list);
+
gtk_widget_hide (data->dialog->priv->pbar);
}
@@ -411,6 +455,11 @@
if (data->thread)
g_thread_join (data->thread);
+ if (data->pdata.mutex != NULL)
+ g_mutex_free (data->pdata.mutex);
+
+ g_free (data->search_mem);
+
g_free (data);
return FALSE;
@@ -468,8 +517,8 @@
}
data->dialog = dialog;
- data->name_pattern = gtk_entry_get_text (GTK_ENTRY (dialog->priv->pattern_entry));
- data->content_pattern = gtk_entry_get_text (GTK_ENTRY (dialog->priv->find_text_entry));
+ data->name_pattern = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dialog->priv->pattern_combo));
+ data->content_pattern = gtk_combo_box_get_active_text (GTK_COMBO_BOX (dialog->priv->find_text_combo));
data->dir = gtk_entry_get_text (GTK_ENTRY (dialog->priv->dir_entry));
data->context_id = gtk_statusbar_get_context_id (GTK_STATUSBAR (data->dialog->priv->statusbar), "info");
data->content_search = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->find_text_check));
@@ -497,14 +546,15 @@
// create an re for filename matching
data->name_filter = filter_new (data->name_pattern, data->case_sens, gnome_cmd_data_get_filter_type ());
-
// if we're going to search through file content create an re for that too
if (data->content_search)
{
data->content_regex = g_new0 (regex_t, 1);
- regcomp (data->content_regex, data->content_pattern, 0);
+ regcomp (data->content_regex, data->content_pattern, data->case_sens ? 0 : REG_ICASE);
}
+ if (dialog->priv->data->search_mem == NULL)
+ dialog->priv->data->search_mem = (gchar *) g_malloc(SEARCH_BUFFER_SIZE);
// start the search
path = gnome_cmd_con_create_path (dialog->priv->con, data->dir);
@@ -512,7 +562,10 @@
gnome_cmd_dir_ref (data->start_dir);
data->search_done = FALSE;
- data->pdata.mutex = g_mutex_new ();
+
+ if (data->pdata.mutex == NULL)
+ data->pdata.mutex = g_mutex_new ();
+
data->thread = g_thread_create ((GThreadFunc)perform_search_operation, data, TRUE, NULL);
gtk_widget_show (data->dialog->priv->pbar);
@@ -613,13 +666,19 @@
return FALSE;
}
-
-static gboolean on_list_keypressed (GnomeCmdFileList *fl, GdkEventKey *event, GnomeCmdSearchDialog *dialog)
+/*
+ *
+ */
+static gboolean on_list_keypressed (GtkWidget *result_list, GdkEventKey *event, gpointer dialog)
{
- if (gnome_cmd_file_list_keypressed (fl, event) || handle_list_keypress (fl, event, dialog))
- stop_kp (GTK_OBJECT (fl));
+ if (gnome_cmd_file_list_keypressed (GNOME_CMD_FILE_LIST (result_list), event) ||
+ handle_list_keypress (GNOME_CMD_FILE_LIST (result_list), event, GNOME_CMD_SEARCH_DIALOG (dialog)))
+ {
+ stop_kp (GTK_OBJECT (result_list));
+ return TRUE;
+ }
- return TRUE;
+ return FALSE;
}
@@ -632,7 +691,7 @@
if (gtk_toggle_button_get_active (togglebutton))
{
gtk_widget_set_sensitive (dialog->priv->find_text_combo, TRUE);
- gtk_widget_grab_focus (dialog->priv->find_text_entry);
+ gtk_widget_grab_focus (dialog->priv->find_text_combo);
}
else
gtk_widget_set_sensitive (dialog->priv->find_text_combo, FALSE);
@@ -646,8 +705,12 @@
static void destroy (GtkObject *object)
{
GnomeCmdSearchDialog *dialog = GNOME_CMD_SEARCH_DIALOG (object);
- if (dialog->priv)
+
+ if (dialog->priv != NULL)
+ {
g_free (dialog->priv);
+ dialog->priv = NULL;
+ }
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
@@ -673,6 +736,64 @@
widget_class->map = ::map;
}
+/*
+ * create a label with keyboard shortcut and a widget to activate
+ * if shortcut is pressed.
+ */
+inline GtkWidget *create_label_with_mnemonic (GtkWidget *parent, const gchar *text, GtkWidget *for_widget)
+{
+ GtkWidget *label;
+
+ label = gtk_label_new_with_mnemonic (text);
+ if (for_widget != NULL)
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), for_widget);
+
+ gtk_widget_ref (label);
+ gtk_object_set_data_full (GTK_OBJECT (parent), "label", label,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_widget_show (label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ return label;
+}
+
+/*
+ * create a check_box_button with keyboard shortcut
+ */
+inline GtkWidget *create_check_with_mnemonic (GtkWidget *parent, gchar *text, gchar *name)
+{
+ GtkWidget *btn = gtk_check_button_new_with_mnemonic (text);
+
+ gtk_widget_ref (btn);
+ gtk_object_set_data_full (GTK_OBJECT (parent), name, btn, (GtkDestroyNotify) gtk_widget_unref);
+ gtk_widget_show (btn);
+
+ return btn;
+}
+
+/*
+ * create a gtk_combo_box_entry_new_text.
+ * gtk_combo is deprecated.
+ */
+inline GtkWidget *create_combo_box_entry (GtkWidget *parent)
+{
+ GtkWidget *combo = gtk_combo_box_entry_new_text ();
+ gtk_widget_ref (combo);
+ gtk_object_set_data_full (GTK_OBJECT (parent), "combo", combo,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_widget_show (combo);
+ return combo;
+}
+
+/*
+ * callback function for 'g_list_foreach' to add default value
+ * to dropdownbox
+ */
+static void combo_box_insert_text (gpointer data, gpointer user_data)
+{
+ gtk_combo_box_append_text (GTK_COMBO_BOX (user_data), (gchar *) data);
+}
+
static void init (GnomeCmdSearchDialog *dialog)
{
@@ -687,13 +808,6 @@
dialog->priv = g_new0 (GnomeCmdSearchDialogPrivate, 1);
dialog->priv->data = g_new0 (SearchData, 1);
- dialog->priv->data->match_dirs = NULL;
- dialog->priv->data->thread = NULL;
- dialog->priv->data->search_done = TRUE;
-
- dialog->priv->data->pdata.files = NULL;
- dialog->priv->data->pdata.msg = NULL;
- dialog->priv->data->pdata.mutex = NULL;
window = GTK_WIDGET (dialog);
gtk_object_set_data (GTK_OBJECT (window), "window", window);
@@ -710,22 +824,22 @@
gtk_box_pack_start (GTK_BOX (vbox1), table, FALSE, TRUE, 0);
// Search for
- label = create_label (window, _("Search for: "));
+ dialog->priv->pattern_combo = create_combo_box_entry (window);
+ label = create_label_with_mnemonic (window, _("Search _for: "), dialog->priv->pattern_combo);
table_add (table, label, 0, 0, GTK_FILL);
- dialog->priv->pattern_combo = create_combo (window);
table_add (table, dialog->priv->pattern_combo, 1, 0, (GtkAttachOptions) (GTK_EXPAND|GTK_FILL));
if (defaults->name_patterns)
- gtk_combo_set_popdown_strings (GTK_COMBO (dialog->priv->pattern_combo), defaults->name_patterns);
+ g_list_foreach (defaults->name_patterns, combo_box_insert_text, dialog->priv->pattern_combo);
- dialog->priv->pattern_entry = GTK_COMBO (dialog->priv->pattern_combo)->entry;
- gnome_cmd_dialog_editable_enters (GNOME_CMD_DIALOG (dialog), GTK_EDITABLE (dialog->priv->pattern_entry));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->priv->pattern_combo), 0);
+ gnome_cmd_dialog_editable_enters (GNOME_CMD_DIALOG (dialog), GTK_EDITABLE (gtk_bin_get_child (GTK_BIN (dialog->priv->pattern_combo))));
// Search in
- label = create_label (window, _("Search in: "));
+ dialog->priv->dir_browser = create_file_entry (window, "dir_browser", "");
+ label = create_label_with_mnemonic (window, _("Search _in: "), dialog->priv->dir_browser);
table_add (table, label, 0, 1, GTK_FILL);
- dialog->priv->dir_browser = create_file_entry (window, "dir_browser", "");
table_add (table, dialog->priv->dir_browser, 1, 1, (GtkAttachOptions) (GTK_EXPAND|GTK_FILL));
if (defaults->directories)
gtk_combo_set_popdown_strings (
@@ -736,28 +850,28 @@
gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (dialog->priv->dir_browser));
// Find text
- dialog->priv->find_text_check = create_check (window, _("Find text: "), "find_text");
+ dialog->priv->find_text_check = create_check_with_mnemonic (window, _("Find _text: "), "find_text");
table_add (table, dialog->priv->find_text_check, 0, 2, GTK_FILL);
- dialog->priv->find_text_combo = create_combo (window);
+ dialog->priv->find_text_combo = create_combo_box_entry (window);
table_add (table, dialog->priv->find_text_combo, 1, 2, (GtkAttachOptions) (GTK_EXPAND|GTK_FILL));
gtk_widget_set_sensitive (dialog->priv->find_text_combo, FALSE);
if (defaults->content_patterns)
- gtk_combo_set_popdown_strings (GTK_COMBO (dialog->priv->find_text_combo), defaults->content_patterns);
+ g_list_foreach (defaults->content_patterns, combo_box_insert_text, dialog->priv->find_text_combo);
- dialog->priv->find_text_entry = GTK_COMBO (dialog->priv->find_text_combo)->entry;
- gnome_cmd_dialog_editable_enters (GNOME_CMD_DIALOG (dialog), GTK_EDITABLE (dialog->priv->find_text_entry));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->priv->find_text_combo), 0);
+ gnome_cmd_dialog_editable_enters (GNOME_CMD_DIALOG (dialog), GTK_EDITABLE (gtk_bin_get_child (GTK_BIN (dialog->priv->find_text_combo))));
// Recurse check
- dialog->priv->recurse_check = create_check (window, _("Search Recursively"), "recurse_check");
+ dialog->priv->recurse_check = create_check_with_mnemonic (window, _("Search _recursively"), "recurse_check");
gtk_table_attach (GTK_TABLE (table), dialog->priv->recurse_check, 0, 2, 3, 4,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->recurse_check), defaults->recursive);
// Case check
- dialog->priv->case_check = create_check (window, _("Case Sensitive"), "case_check");
+ dialog->priv->case_check = create_check_with_mnemonic (window, _("_Case sensitive"), "case_check");
gtk_table_attach (GTK_TABLE (table), dialog->priv->case_check, 0, 2, 4, 5,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
@@ -808,17 +922,16 @@
dialog->priv->pbar = pbar;
- gtk_signal_connect (GTK_OBJECT (dialog), "destroy", GTK_SIGNAL_FUNC (on_dialog_destroy), NULL);
- gtk_signal_connect (GTK_OBJECT (dialog), "size-allocate", GTK_SIGNAL_FUNC (on_dialog_size_allocate), NULL);
- gtk_signal_connect (GTK_OBJECT (dialog->priv->result_list), "key-press-event", GTK_SIGNAL_FUNC (on_list_keypressed), dialog);
- gtk_signal_connect (GTK_OBJECT (dialog->priv->result_list), "file-clicked", GTK_SIGNAL_FUNC (on_list_file_clicked), dialog);
-
- gtk_signal_connect (GTK_OBJECT (dialog->priv->pattern_entry),
- "key-press-event",
- GTK_SIGNAL_FUNC (on_pattern_entry_keypressed), dialog);
+ g_signal_connect (G_OBJECT (dialog), "destroy", G_CALLBACK (on_dialog_destroy), NULL);
+ g_signal_connect (G_OBJECT (dialog), "size-allocate", G_CALLBACK (on_dialog_size_allocate), NULL);
+ g_signal_connect (G_OBJECT (dialog->priv->result_list), "key-press-event", G_CALLBACK (on_list_keypressed), dialog);
+ g_signal_connect (G_OBJECT (dialog->priv->result_list), "file-clicked", G_CALLBACK (on_list_file_clicked), dialog);
+
gtk_signal_connect (GTK_OBJECT (dialog->priv->find_text_check), "toggled", GTK_SIGNAL_FUNC (find_text_toggled), dialog);
- gtk_widget_grab_focus (dialog->priv->pattern_entry);
+ gtk_window_set_keep_above (GTK_WINDOW (dialog), FALSE);
+
+ gtk_widget_grab_focus (dialog->priv->pattern_combo);
gnome_cmd_file_list_update_style (GNOME_CMD_FILE_LIST (dialog->priv->result_list));
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]