[anjuta] search: Implemented file search based on mime-type and some memory fixes.



commit dae1d490ea45d385fc62eac2c6d04894690a84c3
Author: Johannes Schmid <jhs gnome org>
Date:   Sun Feb 12 13:26:27 2012 +0100

    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 fed8c72..cdae3a1 100644
--- a/plugins/document-manager/anjuta-document-manager.ui
+++ b/plugins/document-manager/anjuta-document-manager.ui
@@ -15,48 +15,6 @@
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
-  <object class="GtkListStore" id="file_type_model">
-    <columns>
-      <!-- column-name Name -->
-      <column type="gchararray"/>
-      <!-- column-name mime-types -->
-      <column type="gchararray"/>
-    </columns>
-    <data>
-      <row>
-        <col id="0" translatable="yes">All Files</col>
-        <col id="1" translatable="yes"></col>
-      </row>
-      <row>
-        <col id="0" translatable="yes">C/C++ Source files</col>
-        <col id="1" translatable="yes">text/x-c</col>
-      </row>
-      <row>
-        <col id="0" translatable="yes">Vala Source files</col>
-        <col id="1" translatable="yes">text/x-vala</col>
-      </row>
-      <row>
-        <col id="0" translatable="yes">Python Source files</col>
-        <col id="1" translatable="yes">text/x-python,application/x-extension-wsgi</col>
-      </row>
-      <row>
-        <col id="0" translatable="yes">Javascript Source files</col>
-        <col id="1" translatable="yes">application/javascript</col>
-      </row>
-      <row>
-        <col id="0" translatable="yes">XML files</col>
-        <col id="1" translatable="yes">application/xml</col>
-      </row>
-      <row>
-        <col id="0" translatable="yes">User interface files</col>
-        <col id="1" translatable="yes">application/x-glade,application/x-designer</col>
-      </row>
-      <row>
-        <col id="0" translatable="yes">Source files</col>
-        <col id="1" translatable="yes">text/source</col>
-      </row>
-    </data>
-  </object>
   <object class="GtkListStore" id="model1">
     <columns>
       <!-- column-name gchararray -->
@@ -491,8 +449,6 @@
               <object class="GtkComboBox" id="file_type_combo">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="hexpand">True</property>
-                <property name="model">file_type_model</property>
                 <property name="active">0</property>
                 <property name="entry_text_column">0</property>
               </object>
@@ -617,6 +573,9 @@
             <property name="height">1</property>
           </packing>
         </child>
+        <child>
+          <placeholder/>
+        </child>
       </object>
     </child>
   </object>
diff --git a/plugins/document-manager/search-file-command.c b/plugins/document-manager/search-file-command.c
index 592a740..8bbc58d 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 54f5bbf..15043a9 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 <libanjuta/anjuta-command-queue.h>
 #include <libanjuta/interfaces/ianjuta-project-manager.h>
 #include <libanjuta/interfaces/ianjuta-project-chooser.h>
+#include <libanjuta/interfaces/ianjuta-language.h>
 
 #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 44cad55..09f57f5 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 <libanjuta/anjuta-debug.h>
 
-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 92bb2dc..3d9b40c 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 <libanjuta/anjuta-async-command.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]