[anjuta] Automatic callback prototyping when glade signal is dropped in a C source file.



commit c3dd3b1cddee69c0a5f69883942e1ec49a5ca76e
Author: Marco Diego Aurélio Mesquita <marcodiegomesquita gmail com>
Date:   Fri Feb 25 13:02:49 2011 -0300

    Automatic callback prototyping when glade signal is dropped in a C source file.

 plugins/language-support-cpp-java/plugin.c         |  426 +++++++++++++-------
 .../templates/gtkapplication/src/application.h     |    2 +
 plugins/symbol-db/plugin.c                         |   18 +-
 3 files changed, 289 insertions(+), 157 deletions(-)
---
diff --git a/plugins/language-support-cpp-java/plugin.c b/plugins/language-support-cpp-java/plugin.c
index 711676b..d9ecd8f 100644
--- a/plugins/language-support-cpp-java/plugin.c
+++ b/plugins/language-support-cpp-java/plugin.c
@@ -35,6 +35,7 @@
 #include <libanjuta/interfaces/ianjuta-editor-assist.h>
 #include <libanjuta/interfaces/ianjuta-editor-glade-signal.h>
 #include <libanjuta/interfaces/ianjuta-editor-tip.h>
+#include <libanjuta/interfaces/ianjuta-editor-search.h>
 #include <libanjuta/interfaces/ianjuta-preferences.h>
 #include <libanjuta/interfaces/ianjuta-symbol.h>
 #include <libanjuta/interfaces/ianjuta-symbol-manager.h>
@@ -481,48 +482,143 @@ language_support_generate_c_signature (const gchar* separator,
 	return str;
 }
 
-static void
-language_support_add_c_callback (IAnjutaEditor* editor,
-               					 IAnjutaIterable* position,
-				                 GStrv split_signal_data,
-								 const gchar* separator,
-								 const gchar* body,
-								 gint offset)
+const gchar* SOURCE_EXT[] =
 {
-	GSignalQuery query;
-	
-	const gchar* widget = split_signal_data[0];
-	const gchar* signal = split_signal_data[1];
-	const gchar* handler = split_signal_data[2];
-	//const gchar* user_data = split_signal_data[3]; // Currently unused
-	gboolean swapped = g_str_equal (split_signal_data[4], "1");
+	".c",
+	".cc",
+	".C",
+	".cpp",
+	".cxx",
+	".ccg",
+	NULL
+};
 
-	GType type = g_type_from_name (widget);
-	guint id = g_signal_lookup (signal, type);
+const gchar* HEADER_EXT[] =
+{
+	".h",
+	".hh",
+	".H",
+	".hpp",
+	".hxx",
+	".hg",
+	NULL
+};
 
-	g_signal_query (id, &query);
+static GFile*
+language_support_get_header_file (IAnjutaEditor* editor)
+{
+	GFile *file = ianjuta_file_get_file (IANJUTA_FILE (editor), NULL);
+	GFile *parent = g_file_get_parent (file);
+	gchar *parent_uri = g_file_get_uri (parent);
+	gchar *basename = g_file_get_basename (file);
+	g_object_unref (file);
+	g_object_unref (parent);
+	gchar *ext = strstr (basename, ".");
+	GFile *ret = NULL;
+
+	if (ext)
+	{
+		int i;
+		for (i = 0; SOURCE_EXT[i] != NULL; i++)
+		{
+			if (g_str_equal (ext, SOURCE_EXT[i]))
+			{
+				int j;
+				for (j = 0; HEADER_EXT[j] != NULL; j++)
+				{
+					gchar* filename;
+					gchar* uri;
+					GFile* new_file;
+					*ext = '\0';
+					filename = g_strdup_printf ("%s%s", basename, HEADER_EXT[j]);
+					uri = g_build_filename (parent_uri, filename, NULL);
+					new_file = g_file_new_for_uri (uri);
+					g_free (uri);
+					g_free(filename);
+					if (g_file_query_exists (new_file, NULL))
+					{
+            			ret = new_file;
+						goto end;
+					}
+					g_object_unref (new_file);
+				}
+				break;
+			}
+			if (g_str_equal (ext, HEADER_EXT[i]))
+			{
+				int j;
+				for (j = 0; SOURCE_EXT[j] != NULL; j++)
+				{
+					gchar* filename;
+					gchar* uri;
+					GFile* new_file;
+					*ext = '\0';
+					filename = g_strdup_printf ("%s%s", basename, SOURCE_EXT[j]);
+					uri = g_build_filename (parent_uri, filename, NULL);
+					new_file = g_file_new_for_uri (uri);
+					g_free (uri);
+					g_free(filename);
+					if (g_file_query_exists (new_file, NULL))
+					{
+            			ret = new_file;
+						goto end;
+					}
+					g_object_unref (new_file);
+				}
+				break;
+			}
+		}
+	}
 
-	GString* str = language_support_generate_c_signature (separator, widget, query, swapped, handler);
+end:
+	g_free(basename);
+	g_free (parent_uri);
 
-	g_string_append (str, body);
+  return ret;
+}
 
-	ianjuta_editor_insert (editor, position,
-		                   str->str, -1, NULL);
+static IAnjutaEditor*
+language_support_get_editor_from_file (CppJavaPlugin* lang_plugin,
+													  GFile *file)
+{
+	IAnjutaDocumentManager *document_manager = anjuta_shell_get_interface (
+										  ANJUTA_PLUGIN (lang_plugin)->shell,
+										  IAnjutaDocumentManager,
+										  NULL);
 
-	/* Emit code-added signal, so symbols will be updated */
-	g_signal_emit_by_name (G_OBJECT (editor), "code-added", position, str);
+	IAnjutaDocument *document = ianjuta_document_manager_find_document_with_file
+                                                        (document_manager,
+                                                         file,
+                                                         NULL);
 
-	g_string_free (str, TRUE);
+	return IANJUTA_EDITOR (document);
+}
 
-	/* Will now set the caret position offset */
-	ianjuta_editor_goto_line (editor,
-							  ianjuta_editor_get_line_from_position (
-											editor, position, NULL) + offset, NULL);
+static IAnjutaIterable*
+language_support_get_mark_position (IAnjutaEditor* editor, gchar* mark)
+{
+	IAnjutaEditorCell *search_start = IANJUTA_EDITOR_CELL (
+										ianjuta_editor_get_start_position(editor, NULL));
+	IAnjutaEditorCell *search_end = IANJUTA_EDITOR_CELL (
+										ianjuta_editor_get_end_position(editor, NULL));
+	IAnjutaEditorCell *result_start;
+	IAnjutaEditorCell *result_end;
+
+	ianjuta_editor_search_forward (IANJUTA_EDITOR_SEARCH (editor),
+								   mark, FALSE,
+								   search_start, search_end,
+								   &result_start,
+								   &result_end, NULL);
+
+	g_object_unref (result_start);
+
+	return IANJUTA_ITERABLE (result_end);
 }
-               
-static IAnjutaIterable *
+
+static IAnjutaIterable*
 language_support_find_symbol (CppJavaPlugin* lang_plugin,
-							 const gchar* handler)
+							  IAnjutaEditor* editor,
+							  const gchar* handler)
 {
 	IAnjutaSymbolManager *isymbol_manager = anjuta_shell_get_interface (
 										  ANJUTA_PLUGIN (lang_plugin)->shell,
@@ -537,15 +633,150 @@ language_support_find_symbol (CppJavaPlugin* lang_plugin,
 	IAnjutaSymbolField field = IANJUTA_SYMBOL_FIELD_FILE_POS;
 	ianjuta_symbol_query_set_fields (symbol_query, 1, &field, NULL);
 
-	GFile* file = ianjuta_file_get_file (IANJUTA_FILE (lang_plugin->current_editor),
+	GFile* file = ianjuta_file_get_file (IANJUTA_FILE (editor),
                                  		 NULL);
 
 	IAnjutaIterable *iter = ianjuta_symbol_query_search_file (symbol_query,
                          				            		  handler, file, NULL);
 
+	g_object_unref (file);
+	g_object_unref (symbol_query);
+
 	return iter;
 }
 
+static gboolean
+language_support_get_callback_strings (gchar** separator,
+									   gchar** body,
+									   gint* offset,
+									   CppFileType filetype)
+{
+	switch (filetype)
+	{
+		case LS_FILE_C:
+		{
+			*separator = C_SEPARATOR;
+			*body = C_BODY;
+			*offset = C_OFFSET;
+			break;
+		}
+		case LS_FILE_CHDR:
+		{
+			*separator = CHDR_SEPARATOR;
+			*body = CHDR_BODY;
+			*offset = CHDR_OFFSET;
+			break;
+		}
+		default:
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
+static IAnjutaIterable*
+language_support_get_header_editor_and_mark (CppJavaPlugin* lang_plugin,
+											 IAnjutaEditor* editor,
+											 gchar* mark,
+											 IAnjutaEditor** header_editor)
+{
+	IAnjutaIterable* mark_position;
+	GFile *header_file = language_support_get_header_file (editor);
+
+	/* Yes, we have a header */
+	if (header_file)
+	{
+		*header_editor = language_support_get_editor_from_file (lang_plugin,
+																header_file);
+		/* We'll now search for the mark */
+
+		mark_position = language_support_get_mark_position (*header_editor, mark);
+
+		g_object_unref (header_file);
+	}
+
+	return mark_position;
+}
+
+static void
+language_support_add_c_callback (CppJavaPlugin* lang_plugin,
+               					 IAnjutaEditor* editor,
+               					 IAnjutaIterable* position,
+				                 GStrv split_signal_data,
+								 CppFileType filetype)
+{
+	GSignalQuery query;
+
+	gchar* separator;
+	gchar* body;
+	gint offset;
+
+	const gchar* widget = split_signal_data[0];
+	const gchar* signal = split_signal_data[1];
+	const gchar* handler = split_signal_data[2];
+	//const gchar* user_data = split_signal_data[3]; // Currently unused
+	gboolean swapped = g_str_equal (split_signal_data[4], "1");
+
+	GType type = g_type_from_name (widget);
+	guint id = g_signal_lookup (signal, type);
+
+	g_signal_query (id, &query);
+
+
+	if (!language_support_get_callback_strings (&separator, &body, &offset, filetype))
+		return;
+
+
+
+	GString* str = language_support_generate_c_signature (separator, widget,
+														  query, swapped, handler);
+
+	g_string_append (str, body);
+
+	ianjuta_editor_insert (editor, position,
+		                   str->str, -1, NULL);
+
+	/* Code was inserted, we'll now check if we should add a prototype to the header */
+	if (filetype == LS_FILE_C)
+	{
+		IAnjutaEditor* header_editor;
+		IAnjutaIterable* mark_position;
+		mark_position = language_support_get_header_editor_and_mark (lang_plugin,
+																	 editor,
+																	 "/* Callbacks */", 
+																	 &header_editor);
+		if (mark_position)
+		{
+			/* Check if there's a the prototype to the header */
+			IAnjutaIterable* symbol;
+			symbol = language_support_find_symbol (lang_plugin, header_editor, handler);
+
+			if (symbol)
+			{
+				g_object_unref (symbol);
+			} else {
+				/* Add prototype to the header */
+				language_support_add_c_callback (lang_plugin, header_editor, mark_position,
+												 split_signal_data, LS_FILE_CHDR);
+
+			}
+
+			g_object_unref (mark_position);
+		}
+	}
+
+	gchar *string = g_string_free (str, FALSE);
+	/* Emit code-added signal, so symbols will be updated */
+	g_signal_emit_by_name (G_OBJECT (editor), "code-added", position, string);
+
+	if (string) g_free (string);
+
+	/* Will now set the caret position offset */
+	ianjuta_editor_goto_line (editor,
+							  ianjuta_editor_get_line_from_position (
+											editor, position, NULL) + offset, NULL);
+}
+
 static void
 on_glade_drop (IAnjutaEditor* editor,
                IAnjutaIterable* iterator,
@@ -564,29 +795,13 @@ on_glade_drop (IAnjutaEditor* editor,
 	 */
 
 	IAnjutaIterable *iter;
-	if ((iter = language_support_find_symbol (lang_plugin, handler)) == NULL)
+	iter = language_support_find_symbol (lang_plugin,
+										 IANJUTA_EDITOR (lang_plugin->current_editor),
+										 handler);
+	if (iter == NULL)
 	{
-		switch (lang_plugin->filetype)
-		{
-			case LS_FILE_C:
-			{
-				language_support_add_c_callback (editor, iterator, split_signal_data,
-												 C_SEPARATOR,
-												 C_BODY,
-												 C_OFFSET);
-				break;
-			}
-			case LS_FILE_CHDR:
-			{
-				language_support_add_c_callback (editor, iterator, split_signal_data,
-												 CHDR_SEPARATOR,
-												 CHDR_BODY,
-												 CHDR_OFFSET);
-				break;
-			}
-			default:
-				break;
-		}
+		language_support_add_c_callback (lang_plugin, editor, iterator, split_signal_data,
+										 lang_plugin->filetype);
 	} else {
 		/* Symbol found, going there */
 		ianjuta_editor_goto_line (editor, ianjuta_symbol_get_int (
@@ -758,36 +973,10 @@ on_value_removed_current_editor (AnjutaPlugin *plugin, const gchar *name,
 	lang_plugin->current_editor = NULL;
 }
 
-const gchar* SOURCE_EXT[] =
-{
-	".c",
-	".cc",
-	".C",
-	".cpp",
-	".cxx",
-	".ccg",
-	NULL
-};
-
-const gchar* HEADER_EXT[] =
-{
-	".h",
-	".hh",
-	".H",
-	".hpp",
-	".hxx",
-	".hg",
-	NULL
-};
-
 static void
 on_swap_activate (GtkAction* action, gpointer data)
 {
 	GFile* file;
-	GFile* parent;
-	gchar* parent_uri;
-	gchar* basename;
-	gchar* ext;
 	CppJavaPlugin *lang_plugin = ANJUTA_PLUGIN_CPP_JAVA (data);
 	IAnjutaDocumentManager* docman =
 		anjuta_shell_get_interface (ANJUTA_PLUGIN(lang_plugin)->shell,
@@ -798,75 +987,18 @@ on_swap_activate (GtkAction* action, gpointer data)
 	
 	file = ianjuta_file_get_file (IANJUTA_FILE (lang_plugin->current_editor),
 								  NULL);
-	parent = g_file_get_parent (file);
-	parent_uri = g_file_get_uri (parent);
-	basename = g_file_get_basename (file);
-	g_object_unref (file);
-	g_object_unref (parent);
-	ext = strstr (basename, ".");
-	if (ext)
+
+	GFile* new_file = language_support_get_header_file (
+										IANJUTA_EDITOR (lang_plugin->current_editor));
+
+	if (g_file_query_exists (new_file, NULL))
 	{
-		int i;
-		for (i = 0; SOURCE_EXT[i] != NULL; i++)
-		{
-			if (g_str_equal (ext, SOURCE_EXT[i]))
-			{
-				int j;
-				for (j = 0; HEADER_EXT[j] != NULL; j++)
-				{
-					gchar* filename;
-					gchar* uri;
-					GFile* new_file;
-					*ext = '\0';
-					filename = g_strdup_printf ("%s%s", basename, HEADER_EXT[j]);
-					uri = g_build_filename (parent_uri, filename, NULL);
-					new_file = g_file_new_for_uri (uri);
-					g_free (uri);
-					g_free(filename);
-					if (g_file_query_exists (new_file, NULL))
-					{
-						ianjuta_document_manager_goto_file_line (docman,
-																 new_file,
-																 -1,
-																 NULL);
-						g_object_unref (new_file);
-						break;
-					}
-					g_object_unref (new_file);
-				}
-				break;
-			}
-			if (g_str_equal (ext, HEADER_EXT[i]))
-			{
-				int j;
-				for (j = 0; SOURCE_EXT[j] != NULL; j++)
-				{
-					gchar* filename;
-					gchar* uri;
-					GFile* new_file;
-					*ext = '\0';
-					filename = g_strdup_printf ("%s%s", basename, SOURCE_EXT[j]);
-					uri = g_build_filename (parent_uri, filename, NULL);
-					new_file = g_file_new_for_uri (uri);
-					g_free (uri);
-					g_free(filename);
-					if (g_file_query_exists (new_file, NULL))
-					{
-						ianjuta_document_manager_goto_file_line (docman,
-																 new_file,
-																 -1,
-																 NULL);
-						g_object_unref (new_file);
-						break;
-					}
-					g_object_unref (new_file);
-				}
-				break;
-			}
-		}
+		ianjuta_document_manager_goto_file_line (docman,
+												 new_file,
+												 -1,
+												 NULL);
+		g_object_unref (new_file);
 	}
-	g_free(basename);
-	g_free (parent_uri);
 }
 
 static void
diff --git a/plugins/project-wizard/templates/gtkapplication/src/application.h b/plugins/project-wizard/templates/gtkapplication/src/application.h
index ad68aa8..f08a2b8 100644
--- a/plugins/project-wizard/templates/gtkapplication/src/application.h
+++ b/plugins/project-wizard/templates/gtkapplication/src/application.h
@@ -40,6 +40,8 @@ struct _[+NameCClass+]
 GType [+NameCLower+]_get_type (void) G_GNUC_CONST;
 [+NameCClass+] *[+NameCLower+]_new (void);
 
+/* Callbacks */
+
 G_END_DECLS
 
 #endif /* _APPLICATION_H_ */
diff --git a/plugins/symbol-db/plugin.c b/plugins/symbol-db/plugin.c
index 6db0c5b..7e13a05 100644
--- a/plugins/symbol-db/plugin.c
+++ b/plugins/symbol-db/plugin.c
@@ -348,9 +348,8 @@ static GtkActionEntry actions_search[] = {
 };
 
 static gboolean
-editor_buffer_symbols_update (SymbolDBPlugin *sdb_plugin)
+editor_buffer_symbols_update (IAnjutaEditor *editor, SymbolDBPlugin *sdb_plugin)
 {
-	IAnjutaEditor *ed;
 	gchar *current_buffer = NULL;
 	gsize buffer_size = 0;
 	GFile* file;
@@ -366,14 +365,12 @@ editor_buffer_symbols_update (SymbolDBPlugin *sdb_plugin)
 	if (sdb_plugin->need_symbols_update == FALSE)
 		return TRUE;
 
-	if (sdb_plugin->current_editor) 
+	if (editor) 
 	{
-		ed = IANJUTA_EDITOR (sdb_plugin->current_editor);
-		
-		buffer_size = ianjuta_editor_get_length (ed, NULL);
-		current_buffer = ianjuta_editor_get_text_all (ed, NULL);
+		buffer_size = ianjuta_editor_get_length (editor, NULL);
+		current_buffer = ianjuta_editor_get_text_all (editor, NULL);
 				
-		file = ianjuta_file_get_file (IANJUTA_FILE (ed), NULL);
+		file = ianjuta_file_get_file (IANJUTA_FILE (editor), NULL);
 	} 
 	else
 		return FALSE;
@@ -467,7 +464,8 @@ on_editor_buffer_symbols_update_timeout (gpointer user_data)
 	if (seconds_elapsed < TIMEOUT_SECONDS_AFTER_LAST_TIP)
 		return TRUE;
 
-	return editor_buffer_symbols_update (sdb_plugin);
+	return editor_buffer_symbols_update (IANJUTA_EDITOR (sdb_plugin->current_editor),
+										 sdb_plugin);
 }
 
 static void
@@ -567,7 +565,7 @@ on_code_added (IAnjutaEditor *editor, IAnjutaIterable *position, gchar *code,
 			   SymbolDBPlugin *sdb_plugin)
 {
 	sdb_plugin->need_symbols_update = TRUE;
-	editor_buffer_symbols_update (sdb_plugin);
+	editor_buffer_symbols_update (editor, sdb_plugin);
 }
 
 static void



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