[PATCHES] gnome-debug and project-tool



gIDE users may be interested in these patches. Can someone apply these?
I am also writing a debugger based on Dave Camp's gnome-debug libdryad
debugger to use the GDB/MI interface. The code is already much in better
some respects since the MI interface is clean for application use. It is
designed for instance to have built-in support for adding a watches
window for instance and all the data is returned in a clean format when
you request say a stack trace. I already have it handling application
crashes and will be working on finishing it in the next few days before
school.

gIDE
==========
project-tool.c
- add support for a recent files list to gIDE, great for testing just
about anything in gIDE

debugger-tool.c
- add better error messages
- pick src/foo instead of src/.libs/foo if src/.libs/foo cannot be found

- add support to stack-browser so that when the user chooses a different
frame, gIDE displays the right file

gnome-debug
===========
- fix it to use IDL:GNOME/Development/Debugger:1.0 instead of
IDL:GDF/Debugger:1.0
- add support to stack-browser so that when the user chooses a different
frame, gIDE displays the right file

Mark
diff -ur orig/gIDE/plugins/project-manager/project-tool.c gIDE/plugins/project-manager/project-tool.c
--- orig/gIDE/plugins/project-manager/project-tool.c	Wed Aug  8 16:11:01 2001
+++ gIDE/plugins/project-manager/project-tool.c	Thu Aug 16 20:12:26 2001
@@ -10,9 +10,18 @@
 #include <libgide/libgide.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <gconf/gconf-client.h>
 
 #define PROJECT_COMPONENT_IID "OAFIID:GNOME_Development_Plugin:project-manager"
 
+static GSList* get_recent_files (GideTool *tool);
+static void save_recent_files (GideTool *tool, GSList* list );
+static void add_recent_files (GideTool *tool, const gchar* path);
+static void build_recent_files_menu(GideTool *tool, BonoboUIComponent *uic, GSList* recent_files);
+
+#define MAX_RECENT_FILES 5
+
+
 static void
 open_file (GideTool *tool, GBF_Source *source, int line_num, CORBA_Environment *ev)
 {
@@ -134,6 +143,8 @@
 							       "CurrentProject",
 							       &ev);
 		gtk_object_set_data (GTK_OBJECT (tool), "project", proj);
+
+		add_recent_files(tool, path);
 	} else {
 		ior = CORBA_string_dup ("");
 	}
@@ -305,6 +316,27 @@
 	}
 }
 
+static void
+project_open_recent_file(BonoboUIComponent *component, gpointer data, const char *cname)
+{
+    if( data != NULL ) {
+     GideTool *tool = GIDE_TOOL (data);
+     gchar* filename;
+     GSList* recent_files = get_recent_files(tool);
+     int i = 0;
+
+     i = cname[ strlen(cname) - 1] - '0';
+
+     filename = (gchar*)g_slist_nth_data( recent_files, i - 1 );
+     if( filename != NULL ) {
+         set_build( tool, filename );
+     }
+
+     g_slist_free( recent_files );
+    }
+}
+
+
 static BonoboUIVerb verbs [] = {
 	BONOBO_UI_UNSAFE_VERB ("ProjectNew", project_new),
 	BONOBO_UI_UNSAFE_VERB ("ProjectOpen", project_open),
@@ -416,12 +448,168 @@
 	CORBA_exception_free (&ev);
 }
 
+/*
+  Gets the recent file list each time from gconf - this assumes the user
+  will not be constantly opening and close projects which is reasonable.
+ */
+static void
+add_recent_files (GideTool *tool, const gchar* path)
+{
+	GSList *recent_files, *list, *plist;
+	int i = 0;
+
+	/* Get Recent files from GConf */
+	recent_files = get_recent_files(tool);
+
+	recent_files = g_slist_prepend( recent_files, g_strdup(path) );
+	plist = recent_files;
+	list = plist->next;
+
+	/* Clean out duplicates */
+	if( list != NULL ) {
+		for(; list != NULL && list->data != NULL; plist = list, list = list->next) {
+			if( strcmp(list->data, path) == 0 ) {
+				plist->next = list->next;
+				list->next = NULL;
+				g_slist_free( list );
+				break;
+			}
+		}
+	}
+
+	/* Trim list as needed */
+	list = recent_files;
+	for(i = 1; list != NULL && list->data != NULL; list = list->next, i++) {
+		if( i >= MAX_RECENT_FILES ) {
+			g_slist_free( list->next );
+			list->next = NULL;
+			break;
+		}
+	}
+
+	/*
+	  Save list back to gconf 
+	  This should trigger a listener event which will update the menu
+	*/
+	save_recent_files( tool, recent_files );
+
+	/* 
+	   BUGBUG: I do not know why the listener is not being triggered but this works
+	   Rebuild Menu 
+	*/
+	{
+	    BonoboUIComponent *uic = gtk_object_get_data (GTK_OBJECT (tool), "ui_component");
+
+	    build_recent_files_menu(tool, uic, recent_files);
+	}
+
+	g_slist_free( recent_files );
+}
+
+
+static void
+recent_files_changed(GConfClient* client,
+		     guint cnxn_id,
+		     GConfEntry *entry,
+		     gpointer user_data)
+{
+	GideTool *tool = GIDE_TOOL (user_data);
+
+	BonoboUIComponent *uic = gtk_object_get_data (GTK_OBJECT (tool), "ui_component");
+
+	GDL_TRACE();
+
+	build_recent_files_menu(tool, uic, gconf_value_get_list( entry->value));
+}
+
+static void
+init_recent_files(GideTool *tool, BonoboUIComponent *uic)
+{
+	GConfClient *gconf_client = gtk_object_get_data (GTK_OBJECT (tool), "gconf_client");
+
+	/* Build Menu */
+	GSList* recent_files = get_recent_files(tool);
+     
+	build_recent_files_menu(tool, uic, recent_files);
+     
+	g_slist_free( recent_files );
+
+	/* Add Listener */
+	gconf_client_notify_add(gconf_client,
+				"/gIDE/tools/projects/RecentFiles",
+				recent_files_changed,
+				tool,
+				NULL, NULL);
+}
+
+static void
+build_recent_files_menu(GideTool *tool, BonoboUIComponent *uic, GSList* recent_files)
+{
+	int i = 0;
+	CORBA_Environment ev;
+    
+	if( recent_files == NULL )
+	    return;
+
+	CORBA_exception_init (&ev);
+
+	bonobo_ui_component_set_translate( uic, "/menu/Project Manager/Project", "<separator name='s2'/>", &ev);
+
+	/* Recent Files */
+	for( i = 1;  recent_files != NULL && recent_files->data != NULL;
+	     recent_files = recent_files->next, i++) {
+		gchar* basename = g_basename( recent_files->data );
+		gchar* project_str = g_strdup(recent_files->data);
+		gchar* tempstr;
+		
+
+		tempstr = g_strdup_printf("ProjectOpenRecentProject%d",i);
+                 
+		bonobo_ui_component_add_verb( uic, tempstr, project_open_recent_file, tool );
+
+		g_free(tempstr);
+
+
+		tempstr = g_strdup_printf("<menuitem name='ProjectOpenRecentProject%d' _label='%d. %s' verb='ProjectOpenRecentProject%d' _tip='Open %s' />",i,i,basename,i,project_str);
+                 
+		bonobo_ui_component_set_translate( uic, "/menu/Project Manager/Project", tempstr, &ev);
+
+		g_free(tempstr);
+	}
+
+	CORBA_exception_free (&ev);
+}
+
+static GSList*
+get_recent_files(GideTool *tool)
+{
+	GConfClient *gconf_client = gtk_object_get_data (GTK_OBJECT (tool), "gconf_client");
+	GSList *list = NULL;
+
+	list = gconf_client_get_list( gconf_client, "/gIDE/tools/projects/RecentFiles",
+				      GCONF_VALUE_STRING, NULL );
+
+	return list;
+}
+
+static void
+save_recent_files (GideTool *tool, GSList* recent_files )
+{	
+	GConfClient *gconf_client = gtk_object_get_data (GTK_OBJECT (tool), "gconf_client");
+
+	gconf_client_set_list( gconf_client, "/gIDE/tools/projects/RecentFiles",
+			       GCONF_VALUE_STRING, recent_files, NULL );
+}
+
+
+
 static gboolean
 impl_init (GideTool *tool, 
 	   gpointer closure)
 {
 	BonoboUIComponent *uic;
 	CORBA_Environment ev;
+	GConfClient *gconf_client;
 
 	g_return_val_if_fail (tool != NULL, FALSE);
 	g_return_val_if_fail (GIDE_IS_TOOL (tool), FALSE);
@@ -435,9 +623,16 @@
 	bonobo_ui_component_add_verb_list_with_data (uic, verbs, 
 						     tool);
 
+	gconf_client = gconf_client_get_default();
+
+	gtk_object_set_data(GTK_OBJECT(tool), "gconf_client", gconf_client);
+
+
 	init_project_tree (tool, uic);
 	init_target_tree (tool, uic);
 	init_build_info (tool, uic);
+	init_recent_files(tool, uic);
+
 
 	gtk_object_set_data(GTK_OBJECT(tool), "ui_component", uic);
 
@@ -452,19 +647,20 @@
 {
 	CORBA_Environment ev;
 	CORBA_Object obj;
+	GConfClient *gconf_client;
 
 	CORBA_exception_init (&ev);
 	
 	GNOME_Development_Environment_Shell_removeObject (tool->shell,
 							  "GbfFileTree",
 							  &ev);
-	obj = gtk_object_get_data (tool, "tree_view");
+	obj = gtk_object_get_data (GTK_OBJECT (tool), "tree_view");
 	bonobo_object_release_unref (obj, &ev);
 	
 	GNOME_Development_Environment_Shell_removeObject (tool->shell,
 							  "GbfTargetTree",
 							  &ev);
-	obj = gtk_object_get_data (tool, "target_view");
+	obj = gtk_object_get_data (GTK_OBJECT (tool), "target_view");
 	bonobo_object_release_unref (obj, &ev);
 
 	GNOME_Development_Environment_Shell_removeObject (tool->shell,
@@ -473,12 +669,16 @@
 	GNOME_Development_Environment_Shell_removeObject (tool->shell,
 							  "CurrentProject",
 							  &ev);
-	obj = gtk_object_get_data (tool, "build_info_view");
+	obj = gtk_object_get_data (GTK_OBJECT (tool), "build_info_view");
 	bonobo_object_release_unref (obj, &ev);
 
 	bonobo_ui_component_unset_container(gtk_object_get_data(GTK_OBJECT(
 		tool), "ui_component"));
 	gtk_object_remove_data(GTK_OBJECT(tool), "ui_component");
+
+	gconf_client = gtk_object_get_data (GTK_OBJECT (tool), "gconf_client");
+	
+	gtk_object_unref(GTK_OBJECT(gconf_client));
 
 	CORBA_exception_free (&ev);
 }
diff -ur orig/gIDE/plugins/debugger/debugger-tool.c gIDE/plugins/debugger/debugger-tool.c
--- orig/gIDE/plugins/debugger/debugger-tool.c	Wed Aug  8 16:10:59 2001
+++ gIDE/plugins/debugger/debugger-tool.c	Mon Aug 20 03:21:20 2001
@@ -9,6 +9,8 @@
 #include <liboaf/liboaf.h>
 #include <libgide/libgide.h>
 #include <gbf/gbf.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
 typedef struct 
 {
@@ -177,12 +179,27 @@
 		prj = gbf_project_client_new_from_corba (corba_prj);
 		res = gbf_project_client_get_project_root (prj, &root);
 		if (res == GBF_PROJECT_CLIENT_OK) {
+			struct stat stat_buf;
+
 			GDL_TRACE ();
 			
 			ret = g_strdup_printf ("%s/%s/.libs/%s",
 					       root, target->path, 
 					       target->name);
-			
+
+		
+			if (stat (ret, &stat_buf ) != 0 ) {
+				/*
+				  Looks like the file is not in the .libs directory, but in
+				  the normal directory
+				 */
+				g_free(ret);
+				
+				ret = g_strdup_printf ("%s/%s/%s",
+						       root, target->path, 
+						       target->name);
+			}	
+
 			CORBA_free (root);
 		} else {
 			GDL_TRACE ();
@@ -342,6 +359,7 @@
 load_debugger (GideTool *tool)
 {
 	GdfDebuggerClientResult res;
+	struct stat stat_buf;
 	char *filename;
 
 	unload_debugger (tool);
@@ -349,6 +367,22 @@
 	filename = get_target_filename (tool, 
 					PRIV(tool)->current_target);
 	
+	if (stat (filename, &stat_buf ) != 0 ) {
+		/*
+		  Could not find target so let's give the user a decent error message
+		 */
+		char* error_msg;
+		
+		error_msg = g_strdup_printf("Unable to find debugging target file: %s\n"
+					    "You may need to rebuild this target.",
+					    filename);
+
+		gI_error_dialog (error_msg);
+					    
+		g_free(error_msg);
+		return;
+	}	
+
 	PRIV(tool)->dbg = gdf_debugger_client_new_for_file (filename);
 	if (!PRIV(tool)->dbg) {
 		gI_error_dialog (_("Unable to start a debugging server for "
@@ -720,6 +754,22 @@
 	}
 }
 
+static void
+event_cb (BonoboListener *listener, const char *event,
+		CORBA_any *any, CORBA_Environment *ev,
+		gpointer user_data)
+{
+	GDL_TRACE ();
+
+	if (!strcmp (event, "set-source-line")) {
+		GideTool *tool = GIDE_TOOL (user_data);
+		GNOME_Development_SourceLocation *source = any->_value;
+
+		GDL_TRACE_EXTRA("%s:%d",source->file,source->line);
+		execution_source_line_cb(NULL, source->file, source->line, tool);
+	}
+}
+
 /* Listener setup and destruction. */
 
 static gboolean
@@ -768,6 +818,29 @@
 /* Control setup and destruction */
 
 static void
+add_event_listener (GideTool *tool, Bonobo_Control ctrl)
+{
+	BonoboListener *listener;
+	CORBA_Object source;
+	CORBA_Environment ev;
+	
+	CORBA_exception_init (&ev);
+	listener = bonobo_listener_new (NULL, NULL);
+	gtk_signal_connect (GTK_OBJECT (listener), "event_notify",
+			    GTK_SIGNAL_FUNC (event_cb), tool);
+	source = Bonobo_Unknown_queryInterface (ctrl, 
+						"IDL:Bonobo/EventSource:1.0", 
+						&ev);
+	if (!CORBA_Object_is_nil (source, &ev) && ev._major == CORBA_NO_EXCEPTION) {
+		Bonobo_EventSource_addListener (source, bonobo_object_corba_objref (BONOBO_OBJECT (listener)), &ev);
+	} else {
+		g_error ("couldn't get event source for debugger widget");
+	}
+	
+	CORBA_exception_free (&ev);	
+}
+
+static void
 add_debug_control (GideTool *tool, GdfControl *control_desc)
 {
 	CORBA_Environment ev;
@@ -784,6 +857,11 @@
 								&ev);
 		gtk_object_set_data (GTK_OBJECT (tool), 
 				     control_desc->name, ctrl);
+
+		if(strcmp(control_desc->name, "GdfStackBrowser") == 0 ) {
+		    //Add event source
+		    add_event_listener(tool, ctrl);
+		}
 	} else {
 		g_warning ("Could not load %s", control_desc->name);
 	}
@@ -927,6 +1005,7 @@
 
 	set_sensitivities (tool);
 }
+
 
 static gboolean
 impl_init (GideTool *tool, 
diff -ur orig/gnome-debug/src/controls/control-factories.c gnome-debug/src/controls/control-factories.c
--- orig/gnome-debug/src/controls/control-factories.c	Sat Jul  7 23:07:37 2001
+++ gnome-debug/src/controls/control-factories.c	Mon Aug 20 03:15:48 2001
@@ -111,6 +111,7 @@
 {
 	BonoboPropertyBag *pb;
 	BonoboControl *control;
+	BonoboEventSource *event_source;
 	GtkWidget *sb;
 
 	/* Create the control */
@@ -126,6 +127,10 @@
                              BONOBO_ARG_STRING, NULL, 
                              "Object reference of the debugging backend", 0);
 	
+    event_source = gdf_stack_browser_get_event_source (GNOME_Development_STACK_BROWSER(sb));
+    bonobo_object_add_interface (BONOBO_OBJECT (control), 
+                                 BONOBO_OBJECT (event_source));
+
 	return BONOBO_OBJECT (control);
 }
 
diff -ur orig/gnome-debug/src/controls/gdf-stack-browser.c gnome-debug/src/controls/gdf-stack-browser.c
--- orig/gnome-debug/src/controls/gdf-stack-browser.c	Wed Jul  4 16:35:50 2001
+++ gnome-debug/src/controls/gdf-stack-browser.c	Mon Aug 20 21:45:59 2001
@@ -54,6 +54,8 @@
     int execution_exited_sig;
     int execution_killed_sig;
     int program_unloaded_sig;
+
+	BonoboEventSource *event_source;
 };
 
 enum {
@@ -204,6 +206,8 @@
     sb->priv->stack = NULL;
     sb->priv->current_frame = -1;
 
+	sb->priv->event_source = bonobo_event_source_new ();
+
     create_children (sb);
 }
 
@@ -413,7 +417,38 @@
     GdfStackBrowser *sb = data;
   
     if (val) {
         gdf_debugger_client_change_frame (sb->priv->dbg, row);
+
+        /* Change displayed document */
+        {
+		BonoboArg *arg = NULL;
+        GNOME_Development_StackFrame *frame = &sb->priv->stack->_buffer[row];
+
+        if( g_path_is_absolute(frame->location.file) ) {
+           arg = gdf_marshal_event_source_location (frame->location.file,
+                                                    frame->location.line);
+        } else {
+            gchar* absolute_filename;
+
+            gdf_debugger_client_get_absolute_source_path(sb->priv->dbg,
+                                                         frame->location.file,
+                                                         &absolute_filename);
+
+            if( absolute_filename != NULL ) {
+                arg = gdf_marshal_event_source_location (absolute_filename,
+                                                         frame->location.line);
+
+                g_free(absolute_filename);
+            }
+        }
+
+		CORBA_any_set_release (arg, FALSE);
+
+		bonobo_event_source_notify_listeners (sb->priv->event_source,
+						      "set-source-line",
+						      arg, NULL);
+		bonobo_arg_release (arg);
+        }
     }
 }
 
@@ -477,4 +515,10 @@
     } 
     sb->priv->current_frame = -1;
     e_table_model_changed (sb->priv->e_table_model);
+}
+
+BonoboEventSource*
+gdf_stack_browser_get_event_source (GdfStackBrowser *sb)
+{
+	return sb->priv->event_source;
 }
diff -ur orig/gnome-debug/src/controls/gdf-stack-browser.h gnome-debug/src/controls/gdf-stack-browser.h
--- orig/gnome-debug/src/controls/gdf-stack-browser.h	Wed Jul  4 16:35:50 2001
+++ gnome-debug/src/controls/gdf-stack-browser.h	Mon Aug 20 03:15:06 2001
@@ -24,6 +24,7 @@
 #define __GNOME_Development_STACK_BROWSER_H__
 
 #include <gnome.h>
+#include <bonobo/bonobo-event-source.h>
 #include <gdf.h>
 
 BEGIN_GNOME_DECLS
@@ -52,6 +53,8 @@
 GtkWidget *gdf_stack_browser_new (void);
 void gdf_stack_browser_set_debugger (GdfStackBrowser *sb, 
                                      GdfDebuggerClient *dbg);
+
+BonoboEventSource *gdf_stack_browser_get_event_source (GdfStackBrowser *sb);
 
 END_GNOME_DECLS
 #endif
diff -ur orig/gnome-debug/src/lib/gdf-debugger-client.c gnome-debug/src/lib/gdf-debugger-client.c
--- orig/gnome-debug/src/lib/gdf-debugger-client.c	Sun Jul 15 23:38:25 2001
+++ gnome-debug/src/lib/gdf-debugger-client.c	Wed Aug 22 02:49:17 2001
@@ -94,12 +94,12 @@
     
     CORBA_exception_init (&ev);
  
-    dbg->priv->listener = bonobo_listener_new (NULL, NULL);
-    gtk_signal_connect (GTK_OBJECT (dbg->priv->listener),
+    dbg->priv->listener = bonobo_listener_new ((BonoboListenerCallbackFn)event_pushed_cb, dbg);
+    /*    gtk_signal_connect (GTK_OBJECT (dbg->priv->listener),
                         "event_notify", 
                         GTK_SIGNAL_FUNC (event_pushed_cb), 
                         dbg);
-    
+    */
      source = GNOME_Development_Debugger_getEventSource (corba_object,
                                                               &ev);
     
@@ -138,14 +138,14 @@
     OAF_ServerInfoList *oaf_result;
     
     CORBA_exception_init (&ev);
-    
-    query = g_strdup_printf ("repo_ids.has ('IDL:GDF/Debugger:1.0') AND supported_mime_types.has ('%s')", type ? type : "unknown");
+
+    query = g_strdup_printf ("repo_ids.has ('IDL:GNOME/Development/Debugger:1.0') AND bonobo:supported_mime_types.has ('%s')", type ? type : "unknown");
     
     oaf_result = oaf_query (query, NULL, &ev);
 
     /* FIXME: Deal with the case where a mime type is handled by more than
      * one backend */
     if (ev._major == CORBA_NO_EXCEPTION && oaf_result != NULL && oaf_result->_length >= 1) {
         ret = gdf_debugger_client_new (oaf_result->_buffer[0].iid);
     }
 


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