[anjuta] search: Improve find in files dialog
- From: Johannes Schmid <jhs src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta] search: Improve find in files dialog
- Date: Sun, 12 Feb 2012 12:27:25 +0000 (UTC)
commit 8aee876aeb591ba68177c83413dd5ffbe8d3a279
Author: Johannes Schmid <jhs gnome org>
Date: Sat Feb 11 17:43:02 2012 +0100
search: Improve find in files dialog
* Double click on result opens in editor
* SearchBox in editor will highlight all matches with the same settings as "Find in files"
* Basic replace implementation
plugins/document-manager/action-callbacks.c | 5 +-
plugins/document-manager/anjuta-docman.c | 55 ++--
.../document-manager/anjuta-document-manager.ui | 55 +++-
plugins/document-manager/search-box.c | 28 ++-
plugins/document-manager/search-file-command.c | 86 +++--
plugins/document-manager/search-file-command.h | 6 +-
plugins/document-manager/search-files.c | 407 ++++++++++++++++++--
plugins/document-manager/search-files.h | 5 +-
8 files changed, 541 insertions(+), 106 deletions(-)
---
diff --git a/plugins/document-manager/action-callbacks.c b/plugins/document-manager/action-callbacks.c
index 3096783..19d4035 100644
--- a/plugins/document-manager/action-callbacks.c
+++ b/plugins/document-manager/action-callbacks.c
@@ -920,7 +920,8 @@ on_search_find_in_files (GtkAction *action, gpointer user_data)
if (!plugin->search_files)
{
- plugin->search_files = G_OBJECT (search_files_new (ANJUTA_DOCMAN (plugin->docman)));
+ plugin->search_files = G_OBJECT (search_files_new (ANJUTA_DOCMAN (plugin->docman),
+ SEARCH_BOX(plugin->search_box)));
}
search_files_present (SEARCH_FILES(plugin->search_files));
}
@@ -1037,9 +1038,7 @@ void
on_autocomplete_activate (GtkAction *action, gpointer user_data)
{
IAnjutaDocument *doc;
- DocmanPlugin *plugin;
doc = get_current_document (user_data);
- plugin = ANJUTA_PLUGIN_DOCMAN (user_data);
if (doc && IANJUTA_IS_EDITOR_ASSIST(doc))
{
IAnjutaEditorAssist* assist = IANJUTA_EDITOR_ASSIST (doc);
diff --git a/plugins/document-manager/anjuta-docman.c b/plugins/document-manager/anjuta-docman.c
index 0f3bbba..e7c1c3c 100644
--- a/plugins/document-manager/anjuta-docman.c
+++ b/plugins/document-manager/anjuta-docman.c
@@ -1633,30 +1633,9 @@ anjuta_docman_get_document_for_file (AnjutaDocman *docman, GFile* file)
{
IAnjutaDocument *file_doc = NULL;
GList *node;
- gchar *path;
- gchar *local_real_path = NULL;
g_return_val_if_fail (file != NULL, NULL);
-
- path = g_file_get_path (file);
- if (path)
- {
- local_real_path = anjuta_util_get_real_path (path);
- if (local_real_path)
- {
- g_free (path);
- }
- else
- {
- local_real_path = path;
- }
- }
- else
- {
- return NULL;
- }
-
for (node = docman->priv->pages; node != NULL; node = g_list_next (node))
{
AnjutaDocmanPage *page;
@@ -1672,7 +1651,9 @@ anjuta_docman_get_document_for_file (AnjutaDocman *docman, GFile* file)
doc_file = ianjuta_file_get_file (IANJUTA_FILE (doc), NULL);
if (doc_file)
{
-
+ gchar *path;
+ gchar *local_real_path = NULL;
+
/* Try exact match first */
if (g_file_equal (file, doc_file))
{
@@ -1682,19 +1663,37 @@ anjuta_docman_get_document_for_file (AnjutaDocman *docman, GFile* file)
}
/* Try a local file alias */
+ path = g_file_get_path (file);
+ if (path)
+ {
+ local_real_path = anjuta_util_get_real_path (path);
+ if (local_real_path)
+ {
+ g_free (path);
+ }
+ else
+ {
+ local_real_path = path;
+ }
+ }
+ else
+ {
+ continue;
+ }
+
if ((file_doc == NULL) && (local_real_path))
{
- gchar *path = g_file_get_path (doc_file);
- if (path)
+ gchar *doc_path = g_file_get_path (doc_file);
+ if (doc_path)
{
- gchar *doc_real_path = anjuta_util_get_real_path (path);
+ gchar *doc_real_path = anjuta_util_get_real_path (doc_path);
if (doc_real_path)
{
- g_free (path);
+ g_free (doc_path);
}
else
{
- doc_real_path = path;
+ doc_real_path = doc_path;
}
if ((strcmp (doc_real_path, local_real_path) == 0))
{
@@ -1703,11 +1702,11 @@ anjuta_docman_get_document_for_file (AnjutaDocman *docman, GFile* file)
g_free (doc_real_path);
}
}
+ g_free (local_real_path);
g_object_unref (doc_file);
}
}
}
- g_free (local_real_path);
return file_doc;
}
diff --git a/plugins/document-manager/anjuta-document-manager.ui b/plugins/document-manager/anjuta-document-manager.ui
index a3a522c..fed8c72 100644
--- a/plugins/document-manager/anjuta-document-manager.ui
+++ b/plugins/document-manager/anjuta-document-manager.ui
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="2.16"/>
+ <!-- interface-requires gtk+ 3.0 -->
<!-- interface-requires anjuta 0.0 -->
<object class="GtkAdjustment" id="adjustment1">
<property name="lower">1</property>
@@ -414,6 +414,7 @@
<property name="invisible_char">â</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_stock">gtk-find</property>
+ <signal name="changed" handler="search_files_update_ui" swapped="yes"/>
</object>
<packing>
<property name="left_attach">0</property>
@@ -485,7 +486,7 @@
<property name="row_spacing">5</property>
<property name="column_spacing">5</property>
<property name="n_rows">1</property>
- <property name="n_columns">2</property>
+ <property name="n_columns">5</property>
<child>
<object class="GtkComboBox" id="file_type_combo">
<property name="visible">True</property>
@@ -517,6 +518,53 @@
<property name="height">1</property>
</packing>
</child>
+ <child>
+ <object class="GtkCheckButton" id="case_check">
+ <property name="label" translatable="yes">Case sensitive</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="regex_check">
+ <property name="label" translatable="yes">Regular expression</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinner" id="spinner_busy">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">4</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="left_attach">0</property>
@@ -569,9 +617,6 @@
<property name="height">1</property>
</packing>
</child>
- <child>
- <placeholder/>
- </child>
</object>
</child>
</object>
diff --git a/plugins/document-manager/search-box.c b/plugins/document-manager/search-box.c
index 5cc18c9..9359b77 100644
--- a/plugins/document-manager/search-box.c
+++ b/plugins/document-manager/search-box.c
@@ -62,12 +62,18 @@ struct _SearchBoxPrivate
IAnjutaEditor* current_editor;
AnjutaStatus* status;
+ AnjutaShell* shell;
/* Search options popup menu */
GtkWidget* popup_menu;
+ GtkAction* case_action;
+ GtkAction* highlight_action;
+ GtkAction* regex_action;
+
gboolean case_sensitive;
gboolean highlight_all;
gboolean regex_mode;
+
gboolean highlight_complete;
};
@@ -611,6 +617,8 @@ search_box_toggle_highlight (SearchBox * search_box, gboolean status)
return;
search_box->priv->highlight_all = status;
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(search_box->priv->highlight_action),
+ status);
if (!status)
{
@@ -621,10 +629,12 @@ search_box_toggle_highlight (SearchBox * search_box, gboolean status)
void
search_box_toggle_case_sensitive (SearchBox * search_box, gboolean status)
-{
+{
if (!search_box->priv->current_editor)
return;
-
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(search_box->priv->case_action),
+ status);
+
search_box->priv->case_sensitive = status;
search_box_clear_highlight(search_box);
}
@@ -635,6 +645,9 @@ search_box_toggle_regex (SearchBox * search_box, gboolean status)
if (!search_box->priv->current_editor)
return;
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(search_box->priv->regex_action),
+ status);
+
search_box->priv->regex_mode = status;
search_box_clear_highlight(search_box);
@@ -1083,6 +1096,17 @@ search_box_new (AnjutaDocman *docman)
"/SearchboxPopup");
g_assert (search_box->priv->popup_menu != NULL && GTK_IS_MENU (search_box->priv->popup_menu));
+ search_box->priv->case_action =
+ gtk_ui_manager_get_action (GTK_UI_MANAGER (ui),
+ "/SearchboxPopup/CaseCheck");
+
+ search_box->priv->highlight_action =
+ gtk_ui_manager_get_action (GTK_UI_MANAGER (ui),
+ "/SearchboxPopup/HighlightAll");
+ search_box->priv->regex_action =
+ gtk_ui_manager_get_action (GTK_UI_MANAGER (ui),
+ "/SearchboxPopup/RegexSearch");
+
g_signal_connect (search_box->priv->popup_menu, "deactivate",
G_CALLBACK (gtk_widget_hide), NULL);
diff --git a/plugins/document-manager/search-file-command.c b/plugins/document-manager/search-file-command.c
index b106ebb..592a740 100644
--- a/plugins/document-manager/search-file-command.c
+++ b/plugins/document-manager/search-file-command.c
@@ -26,6 +26,7 @@ struct _SearchFileCommandPrivate
gchar* pattern;
gchar* replace;
gboolean regex;
+ gboolean case_sensitive;
gint n_matches;
};
@@ -36,11 +37,14 @@ enum
PROP_FILE,
PROP_PATTERN,
PROP_REPLACE,
+ PROP_CASE_SENSITIVE,
PROP_REGEX
};
#define BUFFER_SIZE 1024
+G_DEFINE_TYPE (SearchFileCommand, search_file_command, ANJUTA_TYPE_ASYNC_COMMAND);
+
static void
search_file_command_save (SearchFileCommand* cmd, const gchar* new_content, GError **error)
{
@@ -84,7 +88,7 @@ search_file_command_load (SearchFileCommand* cmd, GError **error)
content = g_string_new (NULL);
while ((bytes_read = g_input_stream_read (G_INPUT_STREAM (istream),
buffer,
- BUFFER_SIZE,
+ BUFFER_SIZE - 1,
NULL,
error)))
{
@@ -110,9 +114,12 @@ search_file_command_run (AnjutaCommand* anjuta_cmd)
gchar* pattern;
gchar* replace;
gchar* content;
+ GRegexCompileFlags flags = 0;
+ GRegex *regex;
+ GMatchInfo *match_info;
g_return_val_if_fail (cmd->priv->file != NULL && G_IS_FILE (cmd->priv->file), 1);
-
+ g_return_val_if_fail (cmd->priv->pattern != NULL, 1);
cmd->priv->n_matches = 0;
content = search_file_command_load (cmd, &error);
@@ -140,29 +147,30 @@ search_file_command_run (AnjutaCommand* anjuta_cmd)
replace = NULL;
}
- if (!replace)
- {
- GRegex *regex;
- GMatchInfo *match_info;
+ if (!cmd->priv->case_sensitive)
+ flags |= G_REGEX_CASELESS;
- regex = g_regex_new (pattern, 0, 0, NULL);
- g_regex_match (regex, content, 0, &match_info);
- while (g_match_info_matches (match_info))
- {
- cmd->priv->n_matches++;
- g_match_info_next (match_info, NULL);
- }
- g_match_info_free (match_info);
- g_regex_unref (regex);
+ regex = g_regex_new (pattern, flags, 0, &error);
+ if (error)
+ {
+ anjuta_command_set_error_message(anjuta_cmd, error->message);
+ g_error_free (error);
+ g_free (content);
+ return 1;
}
- else
+ g_regex_match (regex, content, 0, &match_info);
+ while (g_match_info_matches (match_info))
+ {
+ cmd->priv->n_matches++;
+ g_match_info_next (match_info, NULL);
+ }
+ g_match_info_free (match_info);
+
+ if (replace && cmd->priv->n_matches)
{
gchar* new_content;
- GRegex *regex;
- regex = g_regex_new (pattern, 0, 0, NULL);
new_content = g_regex_replace (regex, content, -1, 0, replace, 0, NULL);
- g_regex_unref (regex);
search_file_command_save (cmd, new_content, &error);
g_free (new_content);
@@ -173,13 +181,15 @@ search_file_command_run (AnjutaCommand* anjuta_cmd)
return 1;
}
}
+
+ g_regex_unref (regex);
g_free (content);
+ g_free (pattern);
+ g_free (replace);
return 0;
}
-G_DEFINE_TYPE (SearchFileCommand, search_file_command, ANJUTA_TYPE_ASYNC_COMMAND);
-
static void
search_file_command_init (SearchFileCommand *cmd)
{
@@ -223,6 +233,9 @@ search_file_command_set_property (GObject *object, guint prop_id, const GValue *
g_free (cmd->priv->replace);
cmd->priv->replace = g_value_dup_string (value);
break;
+ case PROP_CASE_SENSITIVE:
+ cmd->priv->case_sensitive = g_value_get_boolean (value);
+ break;
case PROP_REGEX:
cmd->priv->regex = g_value_get_boolean (value);
break;
@@ -252,6 +265,9 @@ search_file_command_get_property (GObject *object, guint prop_id, GValue *value,
case PROP_REPLACE:
g_value_set_string (value, cmd->priv->replace);
break;
+ case PROP_CASE_SENSITIVE:
+ g_value_set_boolean (value, cmd->priv->case_sensitive);
+ break;
case PROP_REGEX:
g_value_set_boolean (value, cmd->priv->regex);
break;
@@ -277,24 +293,30 @@ search_file_command_class_init (SearchFileCommandClass *klass)
"filename",
"Filename to search in",
G_TYPE_FILE,
- G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY));
+ G_PARAM_WRITABLE | G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
PROP_PATTERN,
g_param_spec_string ("pattern", "", "",
- "",
- G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY));
+ NULL,
+ G_PARAM_WRITABLE | G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
- PROP_PATTERN,
+ PROP_REPLACE,
g_param_spec_string ("replace", "", "",
- "",
- G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY));
+ NULL,
+ G_PARAM_WRITABLE | G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
+ PROP_CASE_SENSITIVE,
+ g_param_spec_boolean ("case-sensitive", "", "",
+ TRUE,
+ G_PARAM_WRITABLE | G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class,
PROP_REGEX,
g_param_spec_boolean ("regex", "", "",
FALSE,
- G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY));
+ G_PARAM_WRITABLE | G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY));
command_class->run = search_file_command_run;
@@ -303,7 +325,8 @@ search_file_command_class_init (SearchFileCommandClass *klass)
SearchFileCommand*
-search_file_command_new (GFile* file, const gchar* pattern, const gchar* replace, gboolean regex)
+search_file_command_new (GFile* file, const gchar* pattern,
+ const gchar* replace, gboolean case_sensitive, gboolean regex)
{
SearchFileCommand* command;
@@ -311,14 +334,15 @@ search_file_command_new (GFile* file, const gchar* pattern, const gchar* replace
"file", file,
"pattern", pattern,
"replace", replace,
+ "case-sensitive", case_sensitive,
"regex", regex, NULL));
return command;
}
gint
-search_command_get_n_matches (SearchFileCommand* cmd)
+search_file_command_get_n_matches (SearchFileCommand* cmd)
{
- g_return_val_if_fail (cmd != NULL && !SEARCH_IS_FILE_COMMAND (cmd), 0);
+ g_return_val_if_fail (cmd != NULL && SEARCH_IS_FILE_COMMAND (cmd), 0);
return cmd->priv->n_matches;
}
\ No newline at end of file
diff --git a/plugins/document-manager/search-file-command.h b/plugins/document-manager/search-file-command.h
index ef606af..20c5f9b 100644
--- a/plugins/document-manager/search-file-command.h
+++ b/plugins/document-manager/search-file-command.h
@@ -51,8 +51,10 @@ struct _SearchFileCommand
GType search_file_command_get_type (void) G_GNUC_CONST;
SearchFileCommand* search_file_command_new (GFile* file,
const gchar* pattern,
- const gchar* replace, gboolean regex);
-gint search_command_get_n_matches (SearchFileCommand* cmd);
+ const gchar* replace,
+ gboolean case_sensitive,
+ gboolean regex);
+gint search_file_command_get_n_matches (SearchFileCommand* cmd);
G_END_DECLS
diff --git a/plugins/document-manager/search-files.c b/plugins/document-manager/search-files.c
index 0162400..e381eea 100644
--- a/plugins/document-manager/search-files.c
+++ b/plugins/document-manager/search-files.c
@@ -18,6 +18,8 @@
*/
#include "search-files.h"
+#include "search-file-command.h"
+#include <libanjuta/anjuta-command-queue.h>
#include <libanjuta/interfaces/ianjuta-project-manager.h>
#include <libanjuta/interfaces/ianjuta-project-chooser.h>
@@ -40,13 +42,27 @@ struct _SearchFilesPrivate
GtkWidget* project_combo;
GtkWidget* file_type_combo;
+ GtkWidget* case_check;
+ GtkWidget* regex_check;
+
+ GtkWidget* spinner_busy;
+
GtkWidget* files_tree;
GtkTreeModel* files_model;
GtkWidget* files_tree_check;
AnjutaDocman* docman;
+ SearchBox* search_box;
GtkWidget* dialog;
+
+ /* Saved from last search */
+ gboolean case_sensitive;
+ gboolean regex;
+ gchar* last_search_string;
+ gchar* last_replace_string;
+
+ gboolean busy;
};
enum
@@ -56,7 +72,10 @@ enum
COLUMN_COUNT,
COLUMN_PULSE,
COLUMN_SPINNER,
- COLUMN_FILE
+ COLUMN_FILE,
+ COLUMN_ERROR_TOOLTIP,
+ COLUMN_ERROR_CODE,
+ N_COLUMNS
};
G_DEFINE_TYPE (SearchFiles, search_files, G_TYPE_OBJECT);
@@ -64,6 +83,47 @@ G_DEFINE_TYPE (SearchFiles, search_files, G_TYPE_OBJECT);
void search_files_search_clicked (SearchFiles* sf);
void search_files_replace_clicked (SearchFiles* sf);
void search_files_find_files_clicked (SearchFiles* sf);
+void search_files_update_ui (SearchFiles* sf);
+
+
+void
+search_files_update_ui (SearchFiles* sf)
+{
+ GtkTreeIter iter;
+ gboolean can_search = FALSE;
+
+ if (!sf->priv->busy)
+ {
+ gtk_spinner_stop(GTK_SPINNER (sf->priv->spinner_busy));
+ gtk_widget_hide (sf->priv->spinner_busy);
+
+ if (strlen(gtk_entry_get_text (GTK_ENTRY (sf->priv->search_entry))) > 0
+ && gtk_tree_model_get_iter_first(sf->priv->files_model, &iter))
+ {
+ do
+ {
+ gboolean selected;
+ gtk_tree_model_get (sf->priv->files_model, &iter,
+ COLUMN_SELECTED, &selected, -1);
+ if (selected)
+ {
+ can_search = TRUE;
+ break;
+ }
+ }
+ while (gtk_tree_model_iter_next(sf->priv->files_model, &iter));
+ }
+ }
+ else
+ {
+ gtk_spinner_start(GTK_SPINNER (sf->priv->spinner_busy));
+ gtk_widget_show (sf->priv->spinner_busy);
+ }
+
+ gtk_widget_set_sensitive (sf->priv->search_button, can_search);
+ gtk_widget_set_sensitive (sf->priv->replace_button, can_search);
+ gtk_widget_set_sensitive (sf->priv->find_files_button, !sf->priv->busy);
+}
static void
search_files_get_files (GFile* parent, GList** files, IAnjutaProjectManager* pm)
@@ -87,22 +147,215 @@ search_files_check_column_clicked (SearchFiles* sf,
}
static void
-search_files_check_column_toggled (SearchFiles* sf,
- GtkCellRenderer* renderer)
+search_files_check_column_toggled (GtkCellRendererToggle* renderer,
+ gchar* path,
+ SearchFiles* sf)
+{
+ GtkTreePath* tree_path;
+ GtkTreeIter iter;
+ gboolean state;
+
+ if (sf->priv->busy)
+ return;
+
+ tree_path = gtk_tree_path_new_from_string(path);
+ gtk_tree_model_get_iter (sf->priv->files_model, &iter, tree_path);
+
+ gtk_tree_path_free(tree_path);
+
+ gtk_tree_model_get (sf->priv->files_model, &iter,
+ COLUMN_SELECTED, &state, -1);
+
+ gtk_list_store_set (GTK_LIST_STORE (sf->priv->files_model), &iter,
+ COLUMN_SELECTED, !state,
+ -1);
+}
+
+static void
+search_files_finished (SearchFiles* sf, AnjutaCommandQueue* queue)
{
+ sf->priv->busy = FALSE;
+ g_object_unref (queue);
+
+ search_files_update_ui(sf);
+}
+
+static void
+search_files_command_finished (SearchFileCommand* cmd,
+ guint return_code,
+ SearchFiles* sf)
+{
+ GtkTreeIter iter;
+ GtkTreeRowReference* tree_ref;
+ GtkTreePath* path;
+
+ tree_ref = g_object_get_data (G_OBJECT (cmd),
+ "__tree_ref");
+ path = gtk_tree_row_reference_get_path(tree_ref);
+
+ gtk_tree_model_get_iter(sf->priv->files_model, &iter, path);
+ gtk_list_store_set (GTK_LIST_STORE (sf->priv->files_model),
+ &iter,
+ COLUMN_COUNT, search_file_command_get_n_matches(cmd),
+ COLUMN_ERROR_CODE, return_code,
+ COLUMN_ERROR_TOOLTIP, NULL,
+ -1);
+ gtk_tree_row_reference_free(tree_ref);
+ gtk_tree_path_free(path);
+ if (return_code)
+ {
+ gtk_list_store_set (GTK_LIST_STORE (sf->priv->files_model),
+ &iter,
+ COLUMN_ERROR_CODE, return_code,
+ COLUMN_ERROR_TOOLTIP,
+ anjuta_command_get_error_message(cmd),
+ -1);
+ }
+
+ g_object_unref (cmd);
}
void
search_files_search_clicked (SearchFiles* sf)
{
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_get_iter_first(sf->priv->files_model, &iter))
+ {
+ AnjutaCommandQueue* queue = anjuta_command_queue_new(ANJUTA_COMMAND_QUEUE_EXECUTE_MANUAL);
+ const gchar* pattern =
+ gtk_entry_get_text (GTK_ENTRY (sf->priv->search_entry));
+ do
+ {
+ GFile* file;
+ gboolean selected;
+
+ /* Save the current values */
+ sf->priv->regex =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (sf->priv->regex_check));
+ sf->priv->case_sensitive =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (sf->priv->case_check));
+
+ g_free (sf->priv->last_search_string);
+ sf->priv->last_search_string = g_strdup(pattern);
+ g_free (sf->priv->last_replace_string);
+ sf->priv->last_replace_string = NULL;
+
+ gtk_tree_model_get (sf->priv->files_model, &iter,
+ COLUMN_FILE, &file,
+ COLUMN_SELECTED, &selected, -1);
+ if (selected)
+ {
+ GtkTreePath* path;
+ GtkTreeRowReference* ref;
+
+ path = gtk_tree_model_get_path(sf->priv->files_model, &iter);
+ ref = gtk_tree_row_reference_new(sf->priv->files_model,
+ path);
+ gtk_tree_path_free(path);
+
+
+ SearchFileCommand* cmd = search_file_command_new(file,
+ pattern,
+ NULL,
+ sf->priv->case_sensitive,
+ sf->priv->regex);
+ g_object_set_data (G_OBJECT (cmd), "__tree_ref",
+ ref);
+
+ g_signal_connect (cmd, "command-finished",
+ G_CALLBACK(search_files_command_finished), sf);
+
+ anjuta_command_queue_push(queue,
+ ANJUTA_COMMAND(cmd));
+ }
+ g_object_unref (file);
+ }
+ while (gtk_tree_model_iter_next(sf->priv->files_model, &iter));
+ g_signal_connect_swapped (queue, "finished", G_CALLBACK (search_files_finished), sf);
+
+ anjuta_command_queue_start (queue);
+ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (sf->priv->files_model),
+ COLUMN_COUNT,
+ GTK_SORT_DESCENDING);
+
+ sf->priv->busy = TRUE;
+ search_files_update_ui(sf);
+ }
}
void
search_files_replace_clicked (SearchFiles* sf)
{
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_get_iter_first(sf->priv->files_model, &iter))
+ {
+ AnjutaCommandQueue* queue = anjuta_command_queue_new(ANJUTA_COMMAND_QUEUE_EXECUTE_MANUAL);
+ const gchar* pattern =
+ gtk_entry_get_text (GTK_ENTRY (sf->priv->search_entry));
+ const gchar* replace =
+ gtk_entry_get_text (GTK_ENTRY (sf->priv->replace_entry));
+ do
+ {
+ GFile* file;
+ gboolean selected;
+ /* Save the current values */
+ sf->priv->regex =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (sf->priv->regex_check));
+ sf->priv->case_sensitive =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (sf->priv->case_check));
+
+ g_free (sf->priv->last_search_string);
+ sf->priv->last_search_string = g_strdup(pattern);
+ g_free (sf->priv->last_replace_string);
+ sf->priv->last_replace_string = g_strdup(replace);
+
+ gtk_tree_model_get (sf->priv->files_model, &iter,
+ COLUMN_FILE, &file,
+ COLUMN_SELECTED, &selected, -1);
+ if (selected)
+ {
+ GtkTreePath* path;
+ GtkTreeRowReference* ref;
+
+ path = gtk_tree_model_get_path(sf->priv->files_model, &iter);
+ ref = gtk_tree_row_reference_new(sf->priv->files_model,
+ path);
+ gtk_tree_path_free(path);
+
+
+ SearchFileCommand* cmd = search_file_command_new(file,
+ pattern,
+ replace,
+ sf->priv->case_sensitive,
+ sf->priv->regex);
+ g_object_set_data (G_OBJECT (cmd), "__tree_ref",
+ ref);
+
+ g_signal_connect (cmd, "command-finished",
+ G_CALLBACK(search_files_command_finished), sf);
+
+ anjuta_command_queue_push(queue,
+ ANJUTA_COMMAND(cmd));
+ }
+ g_object_unref (file);
+ }
+ while (gtk_tree_model_iter_next(sf->priv->files_model, &iter));
+
+ g_signal_connect_swapped (queue, "finished", G_CALLBACK (search_files_finished), sf);
+
+ anjuta_command_queue_start (queue);
+ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (sf->priv->files_model),
+ COLUMN_COUNT,
+ GTK_SORT_DESCENDING);
+
+ sf->priv->busy = TRUE;
+ search_files_update_ui(sf);
+ }
}
void
@@ -165,6 +418,10 @@ search_files_find_files_clicked (SearchFiles* sf)
COLUMN_PULSE, FALSE, -1);
}
g_object_unref (project_file);
+
+ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (sf->priv->files_model),
+ COLUMN_FILENAME,
+ GTK_SORT_DESCENDING);
g_list_foreach (files, (GFunc) g_object_unref, NULL);
g_list_free (files);
@@ -189,29 +446,66 @@ search_files_render_count (GtkTreeViewColumn *tree_column,
}
static void
-search_files_update_ui (SearchFiles* sf)
+search_files_editor_loaded (SearchFiles* sf, IAnjutaEditor* editor)
+{
+ search_box_set_search_string(sf->priv->search_box,
+ sf->priv->last_search_string);
+ if (sf->priv->last_replace_string)
+ {
+ search_box_set_replace_string(sf->priv->search_box,
+ sf->priv->last_replace_string);
+ search_box_set_replace(sf->priv->search_box,
+ TRUE);
+ }
+ else
+ {
+ search_box_set_replace(sf->priv->search_box,
+ FALSE);
+ }
+ search_box_toggle_case_sensitive(sf->priv->search_box,
+ sf->priv->case_sensitive);
+ search_box_toggle_highlight(sf->priv->search_box,
+ TRUE);
+ search_box_toggle_regex(sf->priv->search_box,
+ sf->priv->regex);
+ search_box_search_highlight_all(sf->priv->search_box, TRUE);
+ search_box_incremental_search(sf->priv->search_box, TRUE, FALSE);
+
+ gtk_widget_show (GTK_WIDGET(sf->priv->search_box));
+}
+
+
+static void
+search_files_result_activated (GtkTreeView* files_tree,
+ GtkTreePath* path,
+ GtkTreeViewColumn* column,
+ SearchFiles* sf)
{
+ IAnjutaDocument* editor;
+ GFile* file;
GtkTreeIter iter;
- gboolean file_available = FALSE;
+
+ gtk_tree_model_get_iter (sf->priv->files_model, &iter, path);
+ gtk_tree_model_get (sf->priv->files_model, &iter,
+ COLUMN_FILE, &file, -1);
- if (gtk_tree_model_get_iter_first(sf->priv->files_model, &iter))
+ /* Check if document is open */
+ editor = anjuta_docman_get_document_for_file(sf->priv->docman, file);
+
+ if (editor && IANJUTA_IS_EDITOR(editor))
{
- do
- {
- gboolean selected;
- gtk_tree_model_get (sf->priv->files_model, &iter,
- COLUMN_SELECTED, &selected, -1);
- if (selected)
- {
- file_available = TRUE;
- break;
- }
- }
- while (gtk_tree_model_iter_next(sf->priv->files_model, &iter));
+ search_files_editor_loaded (sf, IANJUTA_EDITOR(editor));
+ }
+ else
+ {
+ IAnjutaEditor* real_editor =
+ anjuta_docman_goto_file_line(sf->priv->docman, file, 0);
+ if (real_editor)
+ g_signal_connect_swapped (real_editor, "opened",
+ G_CALLBACK (search_files_editor_loaded), sf);
}
- gtk_widget_set_sensitive (sf->priv->search_button, file_available);
- gtk_widget_set_sensitive (sf->priv->replace_button, file_available);
+ g_object_unref (file);
}
static void
@@ -224,6 +518,7 @@ search_files_init_tree (SearchFiles* sf)
GtkCellRenderer* selection_renderer;
GtkCellRenderer* filename_renderer;
GtkCellRenderer* count_renderer;
+ GtkCellRenderer* error_renderer;
column_select = gtk_tree_view_column_new();
sf->priv->files_tree_check = gtk_check_button_new();
@@ -240,8 +535,8 @@ search_files_init_tree (SearchFiles* sf)
selection_renderer,
"active",
COLUMN_SELECTED);
- g_signal_connect_swapped (selection_renderer, "toggled",
- G_CALLBACK(search_files_check_column_toggled), sf);
+ g_signal_connect (selection_renderer, "toggled",
+ G_CALLBACK(search_files_check_column_toggled), sf);
column_filename = gtk_tree_view_column_new();
gtk_tree_view_column_set_expand(column_filename,
@@ -251,31 +546,57 @@ search_files_init_tree (SearchFiles* sf)
gtk_tree_view_column_pack_start(column_filename,
filename_renderer,
TRUE);
- gtk_tree_view_column_add_attribute(column_filename,
- filename_renderer,
- "text",
- COLUMN_FILENAME);
-
+ gtk_tree_view_column_add_attribute (column_filename,
+ filename_renderer,
+ "text",
+ COLUMN_FILENAME);
+ gtk_tree_view_column_add_attribute (column_filename,
+ filename_renderer,
+ "sensitive",
+ COLUMN_COUNT);
+ gtk_tree_view_column_set_sort_column_id(column_filename,
+ COLUMN_FILENAME);
+ error_renderer = gtk_cell_renderer_pixbuf_new();
+ g_object_set (error_renderer, "stock-id", GTK_STOCK_DIALOG_ERROR, NULL);
+ gtk_tree_view_column_pack_start(column_filename,
+ error_renderer,
+ FALSE);
+ gtk_tree_view_column_add_attribute (column_filename,
+ error_renderer,
+ "visible",
+ COLUMN_ERROR_CODE);
+
column_count = gtk_tree_view_column_new();
gtk_tree_view_column_set_title (column_count, "#");
count_renderer = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(column_count,
count_renderer,
TRUE);
+ gtk_tree_view_column_add_attribute (column_count,
+ count_renderer,
+ "sensitive",
+ COLUMN_COUNT);
gtk_tree_view_column_set_cell_data_func(column_count,
count_renderer,
search_files_render_count,
NULL,
NULL);
-
- sf->priv->files_model = GTK_TREE_MODEL (gtk_list_store_new (6,
+ gtk_tree_view_column_set_sort_column_id(column_count,
+ COLUMN_COUNT);
+
+ sf->priv->files_model = GTK_TREE_MODEL (gtk_list_store_new (N_COLUMNS,
G_TYPE_BOOLEAN,
G_TYPE_STRING,
G_TYPE_INT,
G_TYPE_BOOLEAN,
G_TYPE_BOOLEAN,
- G_TYPE_FILE));
-
+ G_TYPE_FILE,
+ G_TYPE_STRING,
+ G_TYPE_INT));
+ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (sf->priv->files_model),
+ COLUMN_FILENAME,
+ GTK_SORT_DESCENDING);
+
g_signal_connect_swapped (sf->priv->files_model,
"row-inserted",
G_CALLBACK (search_files_update_ui),
@@ -288,7 +609,7 @@ search_files_init_tree (SearchFiles* sf)
"row-changed",
G_CALLBACK (search_files_update_ui),
sf);
-
+
gtk_tree_view_set_model (GTK_TREE_VIEW (sf->priv->files_tree), sf->priv->files_model);
gtk_tree_view_append_column(GTK_TREE_VIEW (sf->priv->files_tree),
column_select);
@@ -296,6 +617,10 @@ search_files_init_tree (SearchFiles* sf)
column_filename);
gtk_tree_view_append_column(GTK_TREE_VIEW (sf->priv->files_tree),
column_count);
+ gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW (sf->priv->files_tree),
+ COLUMN_ERROR_TOOLTIP);
+ g_signal_connect (sf->priv->files_tree, "row-activated",
+ G_CALLBACK (search_files_result_activated), sf);
}
static void
@@ -340,6 +665,14 @@ search_files_init (SearchFiles* sf)
combo_renderer, TRUE);
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (sf->priv->file_type_combo),
combo_renderer, "text", 0);
+
+ sf->priv->case_check = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
+ "case_check"));
+ sf->priv->regex_check = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
+ "regex_check"));
+ sf->priv->spinner_busy = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
+ "spinner_busy"));
+
sf->priv->files_tree = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
"files_tree"));
@@ -389,7 +722,7 @@ search_files_project_loaded (SearchFiles* sf, IAnjutaProjectManager *pm, GError*
}
SearchFiles*
-search_files_new (AnjutaDocman* docman)
+search_files_new (AnjutaDocman* docman, SearchBox* search_box)
{
AnjutaShell* shell = docman->shell;
GObject* obj = g_object_new (SEARCH_TYPE_FILES, NULL);
@@ -408,6 +741,7 @@ search_files_new (AnjutaDocman* docman)
ANJUTA_SHELL_PLACEMENT_BOTTOM, NULL);
sf->priv->docman = docman;
+ sf->priv->search_box = search_box;
gtk_widget_show_all (sf->priv->main_box);
@@ -416,6 +750,13 @@ search_files_new (AnjutaDocman* docman)
void search_files_present (SearchFiles* sf)
{
+ g_return_if_fail (sf != NULL && SEARCH_IS_FILES(sf));
+
+ gtk_entry_set_text (GTK_ENTRY (sf->priv->search_entry),
+ search_box_get_search_string(sf->priv->search_box));
+ gtk_entry_set_text (GTK_ENTRY (sf->priv->replace_entry),
+ search_box_get_replace_string(sf->priv->search_box));
+
anjuta_shell_present_widget(sf->priv->docman->shell,
sf->priv->main_box,
NULL);
diff --git a/plugins/document-manager/search-files.h b/plugins/document-manager/search-files.h
index cecc569..fd7c58f 100644
--- a/plugins/document-manager/search-files.h
+++ b/plugins/document-manager/search-files.h
@@ -20,7 +20,8 @@
#ifndef _SEARCH_FILES_H_
#define _SEARCH_FILES_H_
-#include <anjuta-docman.h>
+#include "anjuta-docman.h"
+#include "search-box.h"
G_BEGIN_DECLS
@@ -48,7 +49,7 @@ struct _SearchFiles
};
GType search_files_get_type (void) G_GNUC_CONST;
-SearchFiles* search_files_new (AnjutaDocman* docman);
+SearchFiles* search_files_new (AnjutaDocman* docman, SearchBox* search_box);
void search_files_present (SearchFiles* files);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]