[anjuta] Implement automatic member declaration and initialization for widgets in the glade plugin.



commit 5abe8fd3a97d802c50ce7ac036252aba24feba6c
Author: Marco Diego AurÃlio Mesquita <marcodiegomesquita gmail com>
Date:   Thu Jan 12 14:05:01 2012 -0300

    Implement automatic member declaration and initialization for widgets in the glade plugin.

 libanjuta/interfaces/libanjuta.idl                 |    9 +++
 manuals/anjuta-manual/C/anjuta-glade-start.page    |   41 +++++++++++++-
 plugins/glade/plugin.c                             |   28 +++++++++
 plugins/language-support-cpp-java/plugin.c         |   60 +++++++++++++++++++-
 plugins/project-wizard/templates/gtk/src/main.c    |   15 +++++
 .../templates/gtkapplication/src/application.c     |   22 +++++++-
 .../templates/gtkapplication/src/application.h     |    4 +
 7 files changed, 175 insertions(+), 4 deletions(-)
---
diff --git a/libanjuta/interfaces/libanjuta.idl b/libanjuta/interfaces/libanjuta.idl
index 2951b20..b625476 100644
--- a/libanjuta/interfaces/libanjuta.idl
+++ b/libanjuta/interfaces/libanjuta.idl
@@ -1276,6 +1276,15 @@ interface IAnjutaEditor
 	}
 
 	/**
+	 * IAnjutaEditor::glade-member-add:
+	 * @widget_name: Name of the widget that will become a member of the class.
+	 * @obj: Self
+	 *
+	 * This signal is emitted when code for a widget must be generated.
+	 */
+	void   ::glade_member_add (gchar *widget_name);
+
+	/**
 	 * IAnjutaEditor::code-added:
 	 * @position: The iter position where @ch is added.
 	 * @code: The code that has been added.
diff --git a/manuals/anjuta-manual/C/anjuta-glade-start.page b/manuals/anjuta-manual/C/anjuta-glade-start.page
index 45b71ed..a902b15 100644
--- a/manuals/anjuta-manual/C/anjuta-glade-start.page
+++ b/manuals/anjuta-manual/C/anjuta-glade-start.page
@@ -44,4 +44,43 @@
 <title>Add widget properties</title>
 </section>
 
-</page>
\ No newline at end of file
+<section>
+<title>Generating code for widgets</title>
+
+	<section>
+		<title>Introduction</title>
+		<p>In a GUI program, sometimes, some widgets are only important for
+		generating events (eg: static buttons) while other ones are needed to
+		get or show data to the user (eg: a text entry). In this later case,
+		some code has to be generated so that these widgets can be accessed at
+		runtime. With the glade plug-in, <app>Anjuta</app> is able to automatically
+		generate such code.
+		</p>
+	</section>
+
+	<section>
+		<title>Automatic generation</title>
+		<p>To automatically generate code for a widget, some conditions must be
+		met: the glade plug-in must be running and the source file that will
+		hold the code must be opened. To make sure that the glade plug-in is
+		running, it is enough to open the <file>.ui</file> file that holds the UI for the
+		current project. By default, the file that will hold the code for the
+		widgets is the same one where callbacks will be created (eg:
+		<file>application.c</file>). Both files can easily be found in the project file list
+		and are automatically created by the project template.
+		</p>
+
+		<p>Once the glade plug-in is running and the file that will hold the code
+		is being viewed, simply double click a widget in the glade inspector.
+		The file being viewed will then be scanned for some marker comments
+		(/* ANJUTA: Widgets declaration - DO NOT REMOVE */ and
+		/* ANJUTA: Widgets initialization - DO NOT REMOVE */) and, if found, code
+		will be added right after such comments. So, for this feature to work
+		correctly, it is important not to modify such marker comments.
+		</p>
+	</section>
+
+</section>
+
+
+</page>
diff --git a/plugins/glade/plugin.c b/plugins/glade/plugin.c
index d1f9231..5ded804 100644
--- a/plugins/glade/plugin.c
+++ b/plugins/glade/plugin.c
@@ -337,6 +337,31 @@ glade_plugin_add_project (GladePlugin *glade_plugin, GladeProject *project)
 }
 
 static void
+add_glade_member (GladeWidget		 *widget,
+				  AnjutaPlugin       *plugin)
+{
+	IAnjutaEditor* current_editor;
+	IAnjutaDocument *doc;
+	IAnjutaDocumentManager *docman;
+
+	docman = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
+										 IAnjutaDocumentManager, NULL);
+	if(!docman)
+		return;
+
+	doc = ianjuta_document_manager_get_current_document (docman, NULL);
+	if(!doc)
+		return;
+
+	current_editor = IANJUTA_EDITOR (doc);
+	if(!current_editor)
+		return;
+
+	g_signal_emit_by_name (G_OBJECT (current_editor), "glade-member-add",
+						   glade_widget_get_name (widget));
+}
+
+static void
 inspector_item_activated_cb (GladeInspector     *inspector,
                              AnjutaPlugin       *plugin)
 {
@@ -344,11 +369,14 @@ inspector_item_activated_cb (GladeInspector     *inspector,
 	GList *item;
 	g_assert (GLADE_IS_WIDGET (items->data) && (items->next == NULL));
 
+	GladeWidget *widget = GLADE_WIDGET (items->data);
+
 	/* switch to this widget in the workspace */
 	for (item = items; item != NULL; item = g_list_next (item))
 	{
 		glade_widget_hide (GLADE_WIDGET (item->data));
 		glade_widget_show (GLADE_WIDGET (item->data));
+		add_glade_member (item->data, plugin);
 	}
 
 	g_list_free (item);
diff --git a/plugins/language-support-cpp-java/plugin.c b/plugins/language-support-cpp-java/plugin.c
index a14b063..76dac50 100644
--- a/plugins/language-support-cpp-java/plugin.c
+++ b/plugins/language-support-cpp-java/plugin.c
@@ -815,8 +815,58 @@ on_glade_drop (IAnjutaEditor* editor,
 	g_strfreev (split_signal_data);
 }
 
-/* Enable/Disable language-support */
+static gchar* generate_widget_member_decl_str(gchar *widget_name)
+{
+       return g_strdup_printf ("\n\tGtkWidget* %s;", widget_name);
+}
+
+static gchar *generate_widget_member_init_str(gchar *widget_name)
+{
+       return g_strdup_printf ("\n\tpriv->%s = GTK_WIDGET ("
+                               "gtk_builder_get_object(builder, \"%s\"));", widget_name, widget_name);
+}
+
+static gboolean insert_after_mark (IAnjutaEditor* editor, gchar* mark,
+gchar* code_to_add)
+{
+       IAnjutaIterable* mark_position;
+       mark_position = language_support_get_mark_position (editor, mark);
+       if(!mark_position)
+		return FALSE;
+
+       ianjuta_editor_insert (editor, mark_position, code_to_add, -1, NULL);
+
+       /* Emit code-added signal, so symbols will be updated */
+       g_signal_emit_by_name (G_OBJECT (editor), "code-added", mark_position, code_to_add);
+       g_object_unref (mark_position);
+
+       return TRUE;
+}
+
+static void insert_member_decl_and_init (IAnjutaEditor* editor, gchar* widget_name,
+                                         CppJavaPlugin *lang_plugin)
+{
+       AnjutaStatus* status;
+       gchar* member_decl = generate_widget_member_decl_str(widget_name);
+       gchar* member_init = generate_widget_member_init_str(widget_name);
 
+       status = anjuta_shell_get_status (ANJUTA_PLUGIN (lang_plugin)->shell, NULL);
+
+       if(insert_after_mark (editor, "/* ANJUTA: Widgets declaration - DO NOT REMOVE */", member_decl) &&
+          insert_after_mark (editor, "/* ANJUTA: Widgets initialization - DO NOT REMOVE */", member_init))
+              anjuta_status_set (status, _("Code added for widget."));
+
+       g_free (member_decl);
+       g_free (member_init);
+}
+
+static void
+on_glade_member_add (IAnjutaEditor *editor, gchar *widget_name, CppJavaPlugin *lang_plugin)
+{
+	insert_member_decl_and_init (editor, widget_name, lang_plugin);
+}
+
+/* Enable/Disable language-support */
 static void
 install_support (CppJavaPlugin *lang_plugin)
 {	
@@ -846,6 +896,12 @@ install_support (CppJavaPlugin *lang_plugin)
 						  "char-added",
 						  G_CALLBACK (cpp_indentation),
 						  lang_plugin);
+
+		g_signal_connect (lang_plugin->current_editor,
+						  "glade-member-add",
+						  G_CALLBACK (on_glade_member_add),
+						  lang_plugin);
+
 	}
 	else if (lang_plugin->current_language &&
 		(g_str_equal (lang_plugin->current_language, "Java")))
@@ -929,6 +985,8 @@ uninstall_support (CppJavaPlugin *lang_plugin)
 	                                      on_glade_drop_possible, lang_plugin);
 	g_signal_handlers_disconnect_by_func (lang_plugin->current_editor,
 	                                      on_glade_drop, lang_plugin);
+	g_signal_handlers_disconnect_by_func (lang_plugin->current_editor,
+										  on_glade_member_add, lang_plugin);
 	if (lang_plugin->packages)
 	{
 		g_object_unref (lang_plugin->packages);
diff --git a/plugins/project-wizard/templates/gtk/src/main.c b/plugins/project-wizard/templates/gtk/src/main.c
index 43c4002..b87632f 100644
--- a/plugins/project-wizard/templates/gtk/src/main.c
+++ b/plugins/project-wizard/templates/gtk/src/main.c
@@ -18,6 +18,14 @@
 [+ENDIF+]
 
 [+IF (=(get "HaveBuilderUI") "1")+]
+typedef struct _Private Private;
+static struct _Private
+{
+	/* ANJUTA: Widgets declaration - DO NOT REMOVE */
+};
+
+static struct Private* priv = NULL;
+
 /* For testing propose use the local (not installed) ui file */
 /* #define UI_FILE PACKAGE_DATA_DIR"/ui/[+NameHLower+].ui" */
 #define UI_FILE "src/[+NameHLower+].ui"
@@ -61,6 +69,10 @@ create_window (void)
 				TOP_WINDOW,
 				UI_FILE);
         }
+
+	priv = g_malloc (sizeof (struct _Private));
+	/* ANJUTA: Widgets initialization - DO NOT REMOVE */
+
 	g_object_unref (builder);
 	
 	return window;
@@ -100,5 +112,8 @@ main (int argc, char *argv[])
 	gtk_widget_show (window);
 
 	gtk_main ();
+[+IF (=(get "HaveBuilderUI") "1")+]
+	g_free (priv);
+[+ENDIF+]
 	return 0;
 }
diff --git a/plugins/project-wizard/templates/gtkapplication/src/application.c b/plugins/project-wizard/templates/gtkapplication/src/application.c
index 07c24fa..8255ef8 100644
--- a/plugins/project-wizard/templates/gtkapplication/src/application.c
+++ b/plugins/project-wizard/templates/gtkapplication/src/application.c
@@ -23,6 +23,16 @@
 
 G_DEFINE_TYPE ([+NameCClass+], [+NameCLower+], GTK_TYPE_APPLICATION);
 
+[+IF (=(get "HaveBuilderUI") "1")+]
+/* Define the private structure in the .c file */
+#define [+NameCUpper+]_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), [+NameCUpper+]_TYPE_APPLICATION, [+NameCClass+]Private))
+
+struct _[+NameCClass+]Private
+{
+	/* ANJUTA: Widgets declaration - DO NOT REMOVE */
+};
+[+ENDIF+]
+
 /* Create a new window loading a file */
 static void
 [+NameCLower+]_new_window (GApplication *app,
@@ -33,6 +43,8 @@ static void
 	GtkBuilder *builder;
 	GError* error = NULL;
 
+	[+NameCClass+]Private *priv = [+NameCUpper+]_GET_PRIVATE(app);
+
 	/* Load UI from file */
 	builder = gtk_builder_new ();
 	if (!gtk_builder_add_from_file (builder, UI_FILE, &error))
@@ -42,7 +54,7 @@ static void
 	}
 
 	/* Auto-connect signal handlers */
-	gtk_builder_connect_signals (builder, NULL);
+	gtk_builder_connect_signals (builder, app);
 
 	/* Get the window object from the ui file */
 	window = GTK_WIDGET (gtk_builder_get_object (builder, TOP_WINDOW));
@@ -52,6 +64,10 @@ static void
 				TOP_WINDOW,
 				UI_FILE);
         }
+
+	
+	/* ANJUTA: Widgets initialization - DO NOT REMOVE */
+
 	g_object_unref (builder);
 [+ELSE+]
 	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
@@ -104,7 +120,9 @@ static void
 {
 	G_APPLICATION_CLASS (klass)->activate = [+NameCLower+]_activate;
 	G_APPLICATION_CLASS (klass)->open = [+NameCLower+]_open;
-
+[+IF (=(get "HaveBuilderUI") "1")+]
+	g_type_class_add_private (klass, sizeof ([+NameCClass+]Private));
+[+ENDIF+]
 	G_OBJECT_CLASS (klass)->finalize = [+NameCLower+]_finalize;
 }
 
diff --git a/plugins/project-wizard/templates/gtkapplication/src/application.h b/plugins/project-wizard/templates/gtkapplication/src/application.h
index f08a2b8..2758551 100644
--- a/plugins/project-wizard/templates/gtkapplication/src/application.h
+++ b/plugins/project-wizard/templates/gtkapplication/src/application.h
@@ -26,6 +26,7 @@ G_BEGIN_DECLS
 
 typedef struct _[+NameCClass+]Class [+NameCClass+]Class;
 typedef struct _[+NameCClass+] [+NameCClass+];
+[+IF (=(get "HaveBuilderUI") "1")+]typedef struct _[+NameCClass+]Private [+NameCClass+]Private;[+ENDIF+]
 
 struct _[+NameCClass+]Class
 {
@@ -35,6 +36,9 @@ struct _[+NameCClass+]Class
 struct _[+NameCClass+]
 {
 	GtkApplication parent_instance;
+[+IF (=(get "HaveBuilderUI") "1")+]
+	[+NameCClass+]Private *priv;
+[+ENDIF+]
 };
 
 GType [+NameCLower+]_get_type (void) G_GNUC_CONST;



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