From dae1d490ea45d385fc62eac2c6d04894690a84c3 Mon Sep 17 00:00:00 2001 From: Johannes Schmid Date: Sun, 12 Feb 2012 13:26:27 +0100 Subject: [PATCH] search: Implemented file search based on mime-type and some memory fixes. --- .../document-manager/anjuta-document-manager.ui | 47 +--- plugins/document-manager/search-file-command.c | 14 +- plugins/document-manager/search-files.c | 267 ++++++++++++++++----- .../document-manager/search-filter-file-command.c | 68 +++++- .../document-manager/search-filter-file-command.h | 1 + 5 files changed, 268 insertions(+), 129 deletions(-) diff --git a/plugins/document-manager/anjuta-document-manager.ui b/plugins/document-manager/anjuta-document-manager.ui index fed8c722c..cdae3a1ec 100644 --- a/plugins/document-manager/anjuta-document-manager.ui +++ b/plugins/document-manager/anjuta-document-manager.ui @@ -15,48 +15,6 @@ 1 10 - - - - - - - - - - All Files - - - - C/C++ Source files - text/x-c - - - Vala Source files - text/x-vala - - - Python Source files - text/x-python,application/x-extension-wsgi - - - Javascript Source files - application/javascript - - - XML files - application/xml - - - User interface files - application/x-glade,application/x-designer - - - Source files - text/source - - - @@ -491,8 +449,6 @@ True False - True - file_type_model 0 0 @@ -617,6 +573,9 @@ 1 + + + diff --git a/plugins/document-manager/search-file-command.c b/plugins/document-manager/search-file-command.c index 592a74083..8bbc58d53 100644 --- a/plugins/document-manager/search-file-command.c +++ b/plugins/document-manager/search-file-command.c @@ -194,17 +194,17 @@ static void search_file_command_init (SearchFileCommand *cmd) { cmd->priv = G_TYPE_INSTANCE_GET_PRIVATE (cmd, SEARCH_TYPE_FILE_COMMAND, SearchFileCommandPrivate); - - cmd->priv->file = NULL; - cmd->priv->pattern = NULL; - cmd->priv->replace = NULL; - cmd->priv->regex = FALSE; } static void search_file_command_finalize (GObject *object) { - /* TODO: Add deinitalization code here */ + SearchFileCommand* cmd = SEARCH_FILE_COMMAND (object); + + if (cmd->priv->file) + g_object_unref (cmd->priv->file); + g_free (cmd->priv->pattern); + g_free (cmd->priv->replace); G_OBJECT_CLASS (search_file_command_parent_class)->finalize (object); } @@ -222,7 +222,7 @@ search_file_command_set_property (GObject *object, guint prop_id, const GValue * { case PROP_FILE: if (cmd->priv->file) - g_object_unref (cmd->priv->file); + g_object_unref (cmd->priv->file); cmd->priv->file = g_value_dup_object (value); break; case PROP_PATTERN: diff --git a/plugins/document-manager/search-files.c b/plugins/document-manager/search-files.c index 54f5bbfec..15043a942 100644 --- a/plugins/document-manager/search-files.c +++ b/plugins/document-manager/search-files.c @@ -19,12 +19,16 @@ #include "search-files.h" #include "search-file-command.h" +#include "search-filter-file-command.h" #include #include #include +#include #define BUILDER_FILE PACKAGE_DATA_DIR"/glade/anjuta-document-manager.ui" +#define TEXT_MIME_TYPE "text/*" + struct _SearchFilesPrivate { GtkBuilder* builder; @@ -61,12 +65,22 @@ struct _SearchFilesPrivate gboolean regex; gchar* last_search_string; gchar* last_replace_string; + + /* Project uri of last search */ + GFile* project_file; gboolean busy; }; enum { + COMBO_LANG_NAME, + COMBO_LANG_TYPES, + COMBO_N_COLUMNS +}; + +enum +{ COLUMN_SELECTED, COLUMN_FILENAME, COLUMN_COUNT, @@ -85,7 +99,6 @@ 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) { @@ -126,20 +139,6 @@ search_files_update_ui (SearchFiles* sf) } static void -search_files_get_files (GFile* parent, GList** files, IAnjutaProjectManager* pm) -{ - GList* node; - GList* children = ianjuta_project_manager_get_children(pm, parent, NULL); - for (node = children;node != NULL; node = g_list_next(node)) - { - search_files_get_files(G_FILE(node->data), files, pm); - *files = g_list_append (*files, node->data); - } - g_list_foreach (children, (GFunc)g_object_unref, NULL); - g_list_free(children); -} - -static void search_files_check_column_toggled (GtkCellRendererToggle* renderer, gchar* path, SearchFiles* sf) @@ -351,6 +350,71 @@ search_files_replace_clicked (SearchFiles* sf) } } +static void +search_files_get_files (GFile* parent, GList** files, IAnjutaProjectManager* pm) +{ + GList* node; + GList* children = ianjuta_project_manager_get_children(pm, parent, NULL); + for (node = children;node != NULL; node = g_list_next(node)) + { + search_files_get_files(G_FILE(node->data), files, pm); + if (ianjuta_project_manager_get_target_type (pm, + G_FILE (node->data), + NULL) + == ANJUTA_PROJECT_SOURCE) + { + *files = g_list_append (*files, node->data); + } + } + g_list_foreach (children, (GFunc)g_object_unref, NULL); + g_list_free(children); +} + +static void +search_files_filter_command_finished (SearchFilterFileCommand* cmd, + guint return_code, + SearchFiles* sf) +{ + GFile* file; + GtkTreeIter iter; + gchar* display_name = NULL; + + if (return_code) + return; + + g_object_get (cmd, "file", &file, NULL); + + if (sf->priv->project_file) + { + display_name = g_file_get_relative_path (sf->priv->project_file, + G_FILE (file)); + } + if (!display_name) + display_name = g_file_get_path (G_FILE(file)); + + gtk_list_store_append(GTK_LIST_STORE (sf->priv->files_model), + &iter); + gtk_list_store_set (GTK_LIST_STORE (sf->priv->files_model), &iter, + COLUMN_SELECTED, TRUE, + COLUMN_FILENAME, display_name, + COLUMN_FILE, file, + COLUMN_COUNT, 0, + COLUMN_SPINNER, FALSE, + COLUMN_PULSE, FALSE, -1); + + g_object_unref (file); + g_free (display_name); +} + +static void +search_files_filter_finished (AnjutaCommandQueue* queue, + SearchFiles* sf) +{ + g_object_unref (queue); + sf->priv->busy = FALSE; + search_files_update_ui(sf); +} + void search_files_find_files_clicked (SearchFiles* sf) { @@ -358,69 +422,72 @@ search_files_find_files_clicked (SearchFiles* sf) IAnjutaProjectManager* pm; GList* files = NULL; GList* file; - - gchar* project_uri = NULL; - GFile* project_file = NULL; + gchar* project_uri; + AnjutaCommandQueue* queue; + gchar* mime_types; + GtkComboBox* type_combo; + GtkTreeIter iter; g_return_if_fail (sf != NULL && SEARCH_IS_FILES (sf)); - pm = anjuta_shell_get_interface (sf->priv->docman->shell, - IAnjutaProjectManager, - NULL); + /* Clear store */ + gtk_list_store_clear(GTK_LIST_STORE (sf->priv->files_model)); + gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (sf->priv->files_model), + COLUMN_FILENAME, + GTK_SORT_DESCENDING); + /* Get file and type selection */ selected = ianjuta_project_chooser_get_selected(IANJUTA_PROJECT_CHOOSER (sf->priv->project_combo), NULL); - + type_combo = GTK_COMBO_BOX (sf->priv->file_type_combo); + gtk_combo_box_get_active_iter(type_combo, &iter); + gtk_tree_model_get (gtk_combo_box_get_model (type_combo), + &iter, + COMBO_LANG_TYPES, &mime_types, + -1); + + /* Get files from project manager */ + pm = anjuta_shell_get_interface (sf->priv->docman->shell, + IAnjutaProjectManager, + NULL); search_files_get_files (selected, &files, pm); - - gtk_list_store_clear(GTK_LIST_STORE (sf->priv->files_model)); + + /* Query project root uri */ anjuta_shell_get (sf->priv->docman->shell, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI, G_TYPE_STRING, &project_uri, NULL); + if (sf->priv->project_file) + g_object_unref (sf->priv->project_file); if (project_uri) - project_file = g_file_new_for_uri (project_uri); - g_free (project_uri); - - for (file = files; file != NULL; file = g_list_next (file)) { - GtkTreeIter iter; + sf->priv->project_file = g_file_new_for_uri (project_uri); + } + g_free (project_uri); - gchar* display_name = NULL; - if (project_file) - { - display_name = g_file_get_relative_path (project_file, - G_FILE (file->data)); - if (!display_name) - continue; - } -#if 0 - if (!display_name) - display_name = g_file_get_path (G_FILE (file->data)); - if (!display_name) - display_name = g_file_get_uri (G_FILE (file->data)); -#endif - gtk_list_store_append(GTK_LIST_STORE (sf->priv->files_model), - &iter); - gtk_list_store_set (GTK_LIST_STORE (sf->priv->files_model), &iter, - COLUMN_SELECTED, TRUE, - COLUMN_FILENAME, display_name, - COLUMN_FILE, file->data, - COLUMN_COUNT, 0, - COLUMN_SPINNER, FALSE, - COLUMN_PULSE, FALSE, -1); + /* Queue file filtering */ + queue = anjuta_command_queue_new(ANJUTA_COMMAND_QUEUE_EXECUTE_MANUAL); + g_signal_connect (queue, "finished", + G_CALLBACK (search_files_filter_finished), sf); + for (file = files; file != NULL; file = g_list_next (file)) + { + SearchFilterFileCommand* cmd = + search_filter_file_command_new(G_FILE (file->data), + mime_types); + g_signal_connect (cmd, "command-finished", + G_CALLBACK (search_files_filter_command_finished), sf); + anjuta_command_queue_push(queue, ANJUTA_COMMAND(cmd)); } - g_object_unref (project_file); - - gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (sf->priv->files_model), - COLUMN_FILENAME, - GTK_SORT_DESCENDING); + sf->priv->busy = TRUE; + anjuta_command_queue_start (queue); + search_files_update_ui(sf); g_list_foreach (files, (GFunc) g_object_unref, NULL); g_list_free (files); + g_free (mime_types); } static void @@ -622,10 +689,81 @@ search_files_init_tree (SearchFiles* sf) } static void +search_files_type_combo_init (SearchFiles* sf) +{ + GtkCellRenderer* combo_renderer = gtk_cell_renderer_text_new(); + + GtkTreeIter iter; + GtkListStore* store; + + IAnjutaLanguage* lang_manager = + anjuta_shell_get_interface (sf->priv->docman->shell, + IAnjutaLanguage, + NULL); + + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (sf->priv->file_type_combo), + combo_renderer, TRUE); + gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (sf->priv->file_type_combo), + combo_renderer, "text", 0); + + store = gtk_list_store_new (COMBO_N_COLUMNS, + G_TYPE_STRING, + G_TYPE_STRING); + gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (store), + COMBO_LANG_NAME, + GTK_SORT_DESCENDING); + + gtk_combo_box_set_model(GTK_COMBO_BOX(sf->priv->file_type_combo), + GTK_TREE_MODEL (store)); + + gtk_list_store_append(store, &iter); + gtk_list_store_set (store, &iter, + COMBO_LANG_NAME, _("All text files"), + COMBO_LANG_TYPES, TEXT_MIME_TYPE, + -1); + gtk_combo_box_set_active_iter(GTK_COMBO_BOX(sf->priv->file_type_combo), + &iter); + + if (lang_manager) + { + GList* languages = + ianjuta_language_get_languages(lang_manager, NULL); + GList* lang; + for (lang = languages; lang != NULL; lang = g_list_next (lang)) + { + GList* mime_type; + GString* type_string = g_string_new(NULL); + + GList* mime_types = ianjuta_language_get_mime_types (lang_manager, + GPOINTER_TO_INT (lang->data), + NULL); + const gchar* name = ianjuta_language_get_name (lang_manager, + GPOINTER_TO_INT (lang->data), + NULL); + + for (mime_type = mime_types; mime_type != NULL; mime_type = g_list_next (mime_type)) + { + if (type_string->len) + { + g_string_append_c (type_string, ','); + } + g_string_append (type_string, mime_type->data); + } + gtk_list_store_append(store, &iter); + gtk_list_store_set (store, &iter, + COMBO_LANG_NAME, name, + COMBO_LANG_TYPES, type_string->str, + -1); + + g_string_free (type_string, TRUE); + } + } +} + +static void search_files_init (SearchFiles* sf) { GError* error = NULL; - GtkCellRenderer* combo_renderer; sf->priv = G_TYPE_INSTANCE_GET_PRIVATE (sf, SEARCH_TYPE_FILES, SearchFilesPrivate); @@ -640,8 +778,6 @@ search_files_init (SearchFiles* sf) g_error_free(error); return; } - - combo_renderer = gtk_cell_renderer_text_new(); sf->priv->main_box = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder, "main_box")); @@ -659,10 +795,6 @@ search_files_init (SearchFiles* sf) "project_combo")); sf->priv->file_type_combo = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder, "file_type_combo")); - gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (sf->priv->file_type_combo), - 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")); @@ -690,6 +822,10 @@ search_files_finalize (GObject* object) g_object_unref (sf->priv->main_box); g_object_unref (sf->priv->builder); + if (sf->priv->project_file) + g_object_unref (sf->priv->project_file); + g_free (sf->priv->last_search_string); + g_free (sf->priv->last_replace_string); G_OBJECT_CLASS (search_files_parent_class)->finalize (object); } @@ -739,7 +875,8 @@ search_files_new (AnjutaDocman* docman, SearchBox* search_box) sf->priv->search_box = search_box; gtk_widget_show (sf->priv->main_box); - + + search_files_type_combo_init(sf); search_files_update_ui(sf); return sf; diff --git a/plugins/document-manager/search-filter-file-command.c b/plugins/document-manager/search-filter-file-command.c index 44cad5597..09f57f5a9 100644 --- a/plugins/document-manager/search-filter-file-command.c +++ b/plugins/document-manager/search-filter-file-command.c @@ -18,12 +18,13 @@ */ #include "search-filter-file-command.h" +#include -struct _SearchFileFilterCommandPrivate +struct _SearchFilterFileCommandPrivate { - GFile* file, - const gchar* mime_types; -} + GFile* file; + gchar* mime_types; +}; enum { @@ -36,9 +37,47 @@ enum static guint -search_filter_file_command_run (void) +search_filter_file_command_run (AnjutaCommand* anjuta_cmd) { - /* TODO: Add private function implementation here */ + SearchFilterFileCommand* cmd = SEARCH_FILTER_FILE_COMMAND (anjuta_cmd); + + gchar** mime_types = g_strsplit (cmd->priv->mime_types, ",", -1); + gchar** mime_type; + guint retval = 1; + + GFileInfo* file_info; + GError* error = NULL; + + file_info = g_file_query_info (cmd->priv->file, + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, + G_FILE_QUERY_INFO_NONE, + NULL, &error); + + if (file_info) + { + for (mime_type = mime_types; mime_type && *mime_type; mime_type++) + { + gchar* content_type = g_content_type_from_mime_type (*mime_type); + if (g_content_type_is_a (g_file_info_get_content_type (file_info), + content_type)) + { + retval = 0; + g_free (content_type); + break; + } + } + g_object_unref (file_info); + } + else + { + int code = error->code; + DEBUG_PRINT ("Couldn't query mime-type: %s", error->message); + g_error_free (error); + return code; + } + g_strfreev(mime_types); + + return retval; } G_DEFINE_TYPE (SearchFilterFileCommand, search_filter_file_command, ANJUTA_TYPE_ASYNC_COMMAND); @@ -47,8 +86,8 @@ static void search_filter_file_command_init (SearchFilterFileCommand *cmd) { cmd->priv = G_TYPE_INSTANCE_GET_PRIVATE (cmd, - SEARCH_TYPE_FILE_COMMAND, - SearchFileCommandPrivate); + SEARCH_TYPE_FILTER_FILE_COMMAND, + SearchFilterFileCommandPrivate); } static void @@ -77,11 +116,11 @@ search_filter_file_command_set_property (GObject *object, guint prop_id, const G case PROP_FILE: if (cmd->priv->file) g_object_unref (cmd->priv->file); - cmd->priv->file = G_FILE(g_value_get_object (value)); + cmd->priv->file = G_FILE(g_value_dup_object (value)); break; case PROP_MIME_TYPES: g_free (cmd->priv->mime_types); - cmd->priv->mime_types = g_value_get_string (value)); + cmd->priv->mime_types = g_value_dup_string (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -116,7 +155,7 @@ static void search_filter_file_command_class_init (SearchFilterFileCommandClass *klass) { GObjectClass* object_class = G_OBJECT_CLASS (klass); - AnjutaAsyncCommandClass* parent_class = ANJUTA_ASYNC_COMMAND_CLASS (klass); + AnjutaCommandClass* cmd_class = ANJUTA_COMMAND_CLASS (klass); object_class->finalize = search_filter_file_command_finalize; object_class->set_property = search_filter_file_command_set_property; @@ -132,11 +171,14 @@ search_filter_file_command_class_init (SearchFilterFileCommandClass *klass) g_object_class_install_property (object_class, PROP_MIME_TYPES, - g_param_spec_pointer ("mime-types", + g_param_spec_string ("mime-types", "", "", + NULL, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); + cmd_class->run = search_filter_file_command_run; + g_type_class_add_private (klass, sizeof (SearchFilterFileCommandPrivate)); } @@ -146,7 +188,7 @@ search_filter_file_command_new (GFile* file, const gchar* mime_types) { SearchFilterFileCommand* cmd; - cmd = SEARCH_FILTER_FILE_COMMAND (g_object_new (SEARCH_TYPE_FILE_COMMAND, + cmd = SEARCH_FILTER_FILE_COMMAND (g_object_new (SEARCH_TYPE_FILTER_FILE_COMMAND, "file", file, "mime-types", mime_types, NULL)); diff --git a/plugins/document-manager/search-filter-file-command.h b/plugins/document-manager/search-filter-file-command.h index 92bb2dc5d..3d9b40cab 100644 --- a/plugins/document-manager/search-filter-file-command.h +++ b/plugins/document-manager/search-filter-file-command.h @@ -21,6 +21,7 @@ #define _SEARCH_FILTER_FILE_COMMAND_H_ #include +#include G_BEGIN_DECLS -- 2.11.4.GIT