[anjuta] glade, language-support-cpp-java, sourceview: Initial glade dnd support



commit ea3e609a78d874c6aab213343cf17133ca504337
Author: Johannes Schmid <jhs gnome org>
Date:   Sat Jan 15 13:18:04 2011 +0100

    glade, language-support-cpp-java, sourceview: Initial glade dnd support

 libanjuta/interfaces/libanjuta.idl         |   33 +++++
 plugins/glade/plugin.c                     |   34 +++---
 plugins/language-support-cpp-java/plugin.c |  186 ++++++++++++++++++++++++++++
 plugins/language-support-cpp-java/plugin.h |   10 ++
 plugins/sourceview/anjuta-view.c           |   77 +++++++++++-
 plugins/sourceview/sourceview.c            |    8 ++
 6 files changed, 326 insertions(+), 22 deletions(-)
---
diff --git a/libanjuta/interfaces/libanjuta.idl b/libanjuta/interfaces/libanjuta.idl
index 63785b7..07f8a0e 100644
--- a/libanjuta/interfaces/libanjuta.idl
+++ b/libanjuta/interfaces/libanjuta.idl
@@ -2392,6 +2392,39 @@ interface IAnjutaEditor
 		void matching_brace();
 		
 	}
+	
+	/**
+	 * SECTION:ianjuta-editor-glade-signal
+	 * @title: IAnjutaEditorGladeSignal
+	 * @short_description: Interface for dropping signal handlers
+	 * @see_also: 
+	 * @stability: Unstable
+	 * @include: libanjuta/interfaces/ianjuta-editor-goto.h
+	 * 
+	 */
+	interface IAnjutaEditorGladeSignal
+	{
+		/* IAnjutaEditorGladeSignal::drop-possible
+		 * @obj: self
+		 * @iter: a IAnjutaIterator of the position where drop would happen
+		 *
+		 * Emitted when a signal is dragged over the editor
+		 *
+		 * Return value: TRUE if a signal handler can be dropped, FALSE otherwise
+		 */
+		gboolean ::drop_possible (GObject* iterator);
+		
+		/* IAnjutaEditorGladeSignal::drop
+		 * @obj: self
+		 * @iter: a IAnjutaIterator of the position where drop happens
+		 * @signal_data: Signal data in form "widget:signal:handler", e.g.
+		 * "GtkToggleButton:toggled:on_toggle_button_toggled"
+		 *
+		 * Emitted when a signal was received per drag & drop
+		 *
+		 */
+		void ::drop (GObject* iterator, const gchar* signal_data);
+	}	
 }
 
 /**
diff --git a/plugins/glade/plugin.c b/plugins/glade/plugin.c
index e1bc9a5..d5701f1 100644
--- a/plugins/glade/plugin.c
+++ b/plugins/glade/plugin.c
@@ -97,14 +97,20 @@ value_removed_current_editor (AnjutaPlugin *plugin,
 }
 
 static void
+on_signal_editor_created (GladeApp* app,
+                          GladeSignalEditor* seditor,
+                          gpointer data)
+{
+	glade_signal_editor_enable_dnd (seditor, TRUE);
+}
+
+static void
 on_api_help (GladeEditor* editor, 
              const gchar* book,
              const gchar* page,
              const gchar* search,
              GladePlugin* plugin)
 {
-	gchar *book_comm = NULL, *page_comm = NULL;
-	gchar *string;
 
 	AnjutaPlugin* aplugin = ANJUTA_PLUGIN(plugin);
 	AnjutaShell* shell = aplugin->shell;
@@ -116,17 +122,9 @@ on_api_help (GladeEditor* editor,
 	if (help == NULL)
 		return;
 
-	if (book) book_comm = g_strdup_printf ("book:%s ", book);
-	if (page) page_comm = g_strdup_printf ("page:%s ", page);
-
-	string = g_strdup_printf ("%s%s%s",
-	                          book_comm ? book_comm : "",
-	                          page_comm ? page_comm : "",
-	                          search ? search : "");
-
-	ianjuta_help_search(help, string, NULL);
 
-	g_free (string);
+	if (search)
+		ianjuta_help_search(help, search, NULL);
 }
 
 static void
@@ -393,13 +391,12 @@ activate_plugin (AnjutaPlugin *plugin)
 	priv->paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
 
 	priv->editor = GTK_WIDGET(glade_editor_new());
+	
 	priv->palette = glade_palette_new();
 
 	gtk_paned_add1 (GTK_PANED(priv->paned), priv->inspector);
 	gtk_paned_add2 (GTK_PANED(priv->paned), priv->editor);
 
-	gtk_widget_set_size_request (priv->inspector, -1, 300);
-
 	gtk_widget_show_all (priv->paned);
 
 	anjuta_status_busy_pop (status);
@@ -410,6 +407,9 @@ activate_plugin (AnjutaPlugin *plugin)
 	g_signal_connect(priv->app, "doc-search",
 	                 G_CALLBACK(on_api_help), plugin);
 
+	g_signal_connect(priv->app, "signal-editor-created",
+	                 G_CALLBACK(on_signal_editor_created), plugin);
+
 	gtk_widget_show (priv->palette);
 	gtk_widget_show (priv->editor);
 	gtk_widget_show (priv->inspector);
@@ -602,8 +602,10 @@ ifile_open (IAnjutaFile *ifile, GFile* file, GError **err)
 	{
 		GObject *glade_obj = G_OBJECT (glade_obj_node->data);
 		if (GTK_IS_WINDOW (glade_obj))
-			glade_widget_show (glade_widget_get_from_gobject (glade_obj));
-		break;
+		{
+			glade_project_selection_set (project, glade_obj, TRUE);
+			break;
+		}
 	}
 	anjuta_shell_present_widget (ANJUTA_PLUGIN (ifile)->shell, priv->paned, NULL);
 }
diff --git a/plugins/language-support-cpp-java/plugin.c b/plugins/language-support-cpp-java/plugin.c
index c21508c..c0edbca 100644
--- a/plugins/language-support-cpp-java/plugin.c
+++ b/plugins/language-support-cpp-java/plugin.c
@@ -33,6 +33,7 @@
 #include <libanjuta/interfaces/ianjuta-editor-language.h>
 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
 #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-preferences.h>
 #include <libanjuta/interfaces/ianjuta-symbol.h>
@@ -1749,6 +1750,172 @@ on_editor_char_inserted_java (IAnjutaEditor *editor,
 }
 
 static void
+init_file_type (CppJavaPlugin* lang_plugin)
+{
+	GFile* file = ianjuta_file_get_file (IANJUTA_FILE (lang_plugin->current_editor),
+	                                     NULL);
+
+	if (file)
+	{
+		gchar* mime_type = anjuta_util_get_file_mime_type (file);
+		if (mime_type)
+		{
+			if (g_str_equal (mime_type, "text/x-csrc"))
+				lang_plugin->filetype = LS_FILE_C;
+			else if (g_str_equal (mime_type, "text/x-chdr"))
+				lang_plugin->filetype = LS_FILE_CHDR;
+			else if (g_str_equal (mime_type, "text/x-c++src"))
+				lang_plugin->filetype = LS_FILE_CPP;
+			else if (g_str_equal (mime_type, "text/x-c++hdr"))
+				lang_plugin->filetype = LS_FILE_CPPHDR;
+			else
+				lang_plugin->filetype = LS_FILE_OTHER;
+			return;
+		}
+	}
+	lang_plugin->filetype = LS_FILE_OTHER;
+}
+
+static gboolean
+on_glade_drop_possible (IAnjutaEditor* editor,
+                        IAnjutaIterable* iterator,
+                        CppJavaPlugin* lang_plugin)
+{
+	switch (lang_plugin->filetype)
+	{
+		case LS_FILE_C:
+		case LS_FILE_CHDR:
+			return TRUE;
+		default:
+			return FALSE;
+	}
+}
+
+static gchar*
+language_support_check_param_name (const gchar* name,
+                                   GList** names)
+{
+	gint index = 0;
+	GString* real_name = g_string_new (name);
+	while (g_list_find_custom (*names, real_name->str, (GCompareFunc) strcmp))
+	{
+		g_string_free (real_name, TRUE);
+		real_name = g_string_new (name);
+		g_string_append_printf (real_name, "%d", ++index);
+	}
+	*names = g_list_append (*names, real_name->str);
+	return g_string_free (real_name, FALSE);
+}
+
+static const gchar*
+language_support_get_signal_parameter (const gchar* type_name, GList** names)
+{
+	const gchar* c;
+	const gchar* param_name = NULL;
+	GString* param_string;
+	gchar* real_name;
+	/* Search for the second upper character */
+	for (c = type_name + 1; *c != '\0'; c++)
+	{
+		if (g_ascii_isupper (*c))
+		{
+			param_name = c;
+			break;
+		}
+	}
+	if (param_name && strlen (param_name))
+	{
+		param_string = g_string_new (param_name);
+		g_string_down (param_string);
+	}
+	else
+	{
+		param_string = g_string_new ("arg");
+	}
+	real_name = language_support_check_param_name (g_string_free (param_string, FALSE), names);
+
+	return real_name;
+}
+
+static void
+on_glade_drop (IAnjutaEditor* editor,
+               IAnjutaIterable* iterator,
+               const gchar* signal_data,
+               CppJavaPlugin* lang_plugin)
+{
+	GSignalQuery query;
+	GType type;
+	guint id;
+	
+	const gchar* widget;
+	const gchar* signal;
+	const gchar* handler;
+	const gchar* user_data;
+	gboolean swapped;
+
+	GStrv data = g_strsplit(signal_data, ":", 5);
+	
+	widget = data[0];
+	signal = data[1];
+	handler = data[2];
+	user_data = data[3];
+	swapped = g_str_equal (data[4], "1");
+	
+	type = g_type_from_name (widget);
+	id = g_signal_lookup (signal, type);
+
+	g_signal_query (id, &query);
+	
+	switch (lang_plugin->filetype)
+	{
+		case LS_FILE_C:
+		{
+			GList* names = NULL;
+			GString* str = g_string_new ("\nstatic ");
+			const gchar* widget_param = language_support_get_signal_parameter (widget,
+			                                                                   &names);
+			int i;
+			g_string_append (str, g_type_name (query.return_type));
+			if (!swapped)
+				g_string_append_printf (str, "\n%s (%s *%s", handler, widget, widget_param);
+			else
+				g_string_append_printf (str, "\n%s (gpointer user_data, %s *%s", handler, widget, widget_param);				
+			for (i = 0; i < query.n_params; i++)
+			{
+				const gchar* type_name = g_type_name (query.param_types[i]);
+				const gchar* param_name = language_support_get_signal_parameter (type_name,
+				                                                                 &names);
+				
+				if (query.param_types[i] <= G_TYPE_DOUBLE)
+				{	                                                                
+					g_string_append_printf (str, ", %s %s", type_name, param_name);
+				}
+				else
+				{	                                                                
+					g_string_append_printf (str, ", %s *%s", type_name, param_name);
+				}
+			}
+			if (!swapped)
+				g_string_append (str, ", gpointer user_data)");
+			else
+				g_string_append (str, ")");
+
+			g_string_append (str, "\n{\n\n}\n");
+
+			ianjuta_editor_insert (editor, iterator,
+			                       str->str, -1, NULL);
+			g_string_free (str, TRUE);
+			anjuta_util_glist_strings_free (names);
+			break;
+		}
+		case LS_FILE_CHDR:
+		default:
+			break;
+	}
+	g_strfreev (data);
+}
+
+static void
 install_support (CppJavaPlugin *lang_plugin)
 {	
 	IAnjutaLanguage* lang_manager =
@@ -1792,6 +1959,8 @@ install_support (CppJavaPlugin *lang_plugin)
 	}
 	
 	initialize_indentation_params (lang_plugin);
+	init_file_type (lang_plugin);
+
 	
 	if (!g_str_equal (lang_plugin->current_language, "Vala"))
 	{
@@ -1805,6 +1974,17 @@ install_support (CppJavaPlugin *lang_plugin)
 												NULL),
 					lang_plugin->settings);
 		lang_plugin->assist = assist;
+
+
+		if (IANJUTA_IS_EDITOR_GLADE_SIGNAL (lang_plugin->current_editor))
+		{
+			g_signal_connect (lang_plugin->current_editor,
+			                  "drop-possible", G_CALLBACK (on_glade_drop_possible),
+			                  lang_plugin);
+			g_signal_connect (lang_plugin->current_editor,
+			                  "drop", G_CALLBACK (on_glade_drop),
+			                  lang_plugin);
+		}
 	}	
 		
 	lang_plugin->support_installed = TRUE;
@@ -1838,6 +2018,12 @@ uninstall_support (CppJavaPlugin *lang_plugin)
 		g_object_unref (lang_plugin->assist);
 		lang_plugin->assist = NULL;
 	}
+
+	g_signal_handlers_disconnect_by_func (lang_plugin->current_editor,
+	                                      on_glade_drop_possible, lang_plugin);
+	g_signal_handlers_disconnect_by_func (lang_plugin->current_editor,
+	                                      on_glade_drop, lang_plugin);
+	
 	
 	lang_plugin->support_installed = FALSE;
 }
diff --git a/plugins/language-support-cpp-java/plugin.h b/plugins/language-support-cpp-java/plugin.h
index 4474294..7c67b6c 100644
--- a/plugins/language-support-cpp-java/plugin.h
+++ b/plugins/language-support-cpp-java/plugin.h
@@ -34,6 +34,15 @@ extern GType cpp_java_plugin_get_type (GTypeModule *module);
 typedef struct _CppJavaPlugin CppJavaPlugin;
 typedef struct _CppJavaPluginClass CppJavaPluginClass;
 
+typedef enum
+{
+	LS_FILE_C,
+	LS_FILE_CHDR,
+	LS_FILE_CPP,
+	LS_FILE_CPPHDR,
+	LS_FILE_OTHER
+} CppFileType;
+
 struct _CppJavaPlugin {
 	AnjutaPlugin parent;
 	
@@ -57,6 +66,7 @@ struct _CppJavaPlugin {
 	
 	/* Assist */
 	CppJavaAssist *assist;
+	CppFileType filetype;
 
 	/* Preferences */
 	GtkBuilder* bxml;
diff --git a/plugins/sourceview/anjuta-view.c b/plugins/sourceview/anjuta-view.c
index ad11dcf..b0ce854 100644
--- a/plugins/sourceview/anjuta-view.c
+++ b/plugins/sourceview/anjuta-view.c
@@ -55,6 +55,7 @@
 #define ANJUTA_VIEW_SCROLL_MARGIN 0.02
 
 #define TARGET_URI_LIST 100
+#define TARGET_GLADE 101
 
 #define ANJUTA_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), ANJUTA_TYPE_VIEW, AnjutaViewPrivate))
 
@@ -163,17 +164,15 @@ anjuta_view_get_property (GObject * object,
 }
 
 static GdkAtom
-drag_get_uri_target (GtkWidget      *widget,
+drag_get_target (GtkWidget      *widget,
 		     GdkDragContext *context)
 {
 	GdkAtom target;
 	GtkTargetList *tl;
 	
-	tl = gtk_target_list_new (NULL, 0);
-	gtk_target_list_add_uri_targets (tl, 0);
+	tl = gtk_drag_dest_get_target_list (widget);	
 	
 	target = gtk_drag_dest_find_target (widget, context, tl);
-	gtk_target_list_unref (tl);
 	
 	return target;	
 }
@@ -189,7 +188,7 @@ anjuta_view_drag_drop (GtkWidget      *widget,
 	GdkAtom target;
 
 	/* If this is a URL, just get the drag data */
-	target = drag_get_uri_target (widget, context);
+	target = drag_get_target (widget, context);
 
 	if (target != GDK_NONE)
 	{
@@ -205,6 +204,56 @@ anjuta_view_drag_drop (GtkWidget      *widget,
 	return result;
 }
 
+static SourceviewCell*
+get_cell_from_position (GtkTextView* view,
+                        gint x,
+                        gint y)
+{
+	gint buffer_x, buffer_y;
+	GtkTextIter iter;
+	SourceviewCell* cell;
+	
+	gtk_text_view_window_to_buffer_coords (view,
+	                                       GTK_TEXT_WINDOW_WIDGET,
+	                                       x, y, &buffer_x, &buffer_y);
+
+	gtk_text_view_get_iter_at_location (view,
+	                                    &iter, buffer_x, buffer_y);
+
+	cell = sourceview_cell_new (&iter, view);
+
+	return cell;
+}
+
+static gboolean
+anjuta_view_drag_motion (GtkWidget        *widget,
+                         GdkDragContext   *context,
+                         gint              x,
+                         gint              y,
+                         guint  		   timestamp)
+{
+	AnjutaView* view = ANJUTA_VIEW (widget);
+	SourceviewCell* cell;
+	gboolean retval;
+
+	cell = get_cell_from_position (GTK_TEXT_VIEW(view->priv->sv->priv->view), x, y);
+	
+	g_signal_emit_by_name (view->priv->sv,
+	                       "drop-possible",
+	                       cell, &retval);
+
+	g_object_unref (cell);
+	
+	if (retval)
+	{
+		gdk_drag_status (context, GDK_ACTION_COPY, timestamp);
+	}
+
+	GTK_WIDGET_CLASS (anjuta_view_parent_class)->drag_motion (widget, context, x, y, timestamp);
+	
+	return retval;
+}
+                         
 static void
 anjuta_view_drag_data_received (GtkWidget        *widget,
                                 GdkDragContext   *context,
@@ -237,6 +286,18 @@ anjuta_view_drag_data_received (GtkWidget        *widget,
 		}
 		gtk_drag_finish (context, FALSE, FALSE, timestamp);
 	}
+	else if (info == TARGET_GLADE)
+	{
+		const gchar* signal_data = (gchar*) gtk_selection_data_get_data (selection_data);
+		SourceviewCell* cell = get_cell_from_position (GTK_TEXT_VIEW (view->priv->sv->priv->view),
+		                                               x, y);
+		g_signal_emit_by_name (view->priv->sv,
+		                       "drop",
+		                       cell,
+		                       signal_data);
+		g_object_unref (cell);
+		gtk_drag_finish (context, TRUE, FALSE, timestamp);
+	}
 	else
 	{
 		GTK_WIDGET_CLASS (anjuta_view_parent_class)->drag_data_received (widget, context, x, y, selection_data, info, timestamp);
@@ -263,6 +324,7 @@ anjuta_view_class_init (AnjutaViewClass *klass)
 	widget_class->button_press_event = anjuta_view_button_press_event;
 	widget_class->drag_drop = anjuta_view_drag_drop;
 	widget_class->drag_data_received = anjuta_view_drag_data_received;
+	widget_class->drag_motion = anjuta_view_drag_motion;
   
 	textview_class->move_cursor = anjuta_view_move_cursor;
 
@@ -385,8 +447,11 @@ anjuta_view_init (AnjutaView *view)
   tl = gtk_drag_dest_get_target_list (GTK_WIDGET (view));
 
   if (tl != NULL)
+  {
+	GdkAtom target = gdk_atom_intern_static_string ("application/x-glade-signal");
 	gtk_target_list_add_uri_targets (tl, TARGET_URI_LIST);
-  
+	gtk_target_list_add (tl, target, GTK_TARGET_OTHER_WIDGET, TARGET_GLADE);
+  }
 }
 
 static void
diff --git a/plugins/sourceview/sourceview.c b/plugins/sourceview/sourceview.c
index 2c5150a..9622188 100644
--- a/plugins/sourceview/sourceview.c
+++ b/plugins/sourceview/sourceview.c
@@ -42,6 +42,7 @@
 #include <libanjuta/interfaces/ianjuta-editor-language.h>
 #include <libanjuta/interfaces/ianjuta-editor-search.h>
 #include <libanjuta/interfaces/ianjuta-editor-hover.h>
+#include <libanjuta/interfaces/ianjuta-editor-glade-signal.h>
 #include <libanjuta/interfaces/ianjuta-provider.h>
 
 #include <gtksourceview/gtksourceview.h>
@@ -2459,6 +2460,12 @@ ihover_iface_init(IAnjutaEditorHoverIface* iface)
 	iface->display = ihover_display;
 }
 
+static void
+iglade_iface_init(IAnjutaEditorGladeSignalIface* iface)
+{
+	/* only signals */
+}
+
 ANJUTA_TYPE_BEGIN(Sourceview, sourceview, GTK_TYPE_VBOX);
 ANJUTA_TYPE_ADD_INTERFACE(idocument, IANJUTA_TYPE_DOCUMENT);
 ANJUTA_TYPE_ADD_INTERFACE(ifile, IANJUTA_TYPE_FILE);
@@ -2474,4 +2481,5 @@ ANJUTA_TYPE_ADD_INTERFACE(iprint, IANJUTA_TYPE_PRINT);
 ANJUTA_TYPE_ADD_INTERFACE(ilanguage, IANJUTA_TYPE_EDITOR_LANGUAGE);
 ANJUTA_TYPE_ADD_INTERFACE(isearch, IANJUTA_TYPE_EDITOR_SEARCH);
 ANJUTA_TYPE_ADD_INTERFACE(ihover, IANJUTA_TYPE_EDITOR_HOVER);
+ANJUTA_TYPE_ADD_INTERFACE(iglade, IANJUTA_TYPE_EDITOR_GLADE_SIGNAL);
 ANJUTA_TYPE_END;



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