Browse Source

1998-12-02 Federico Mena Quintero <federico@nuclecu.unam.mx>

	* gtkdtree.c (gtk_dtree_do_select_dir): Made static, as it is for
	internal use only.
	Fixed a little bunch of compiler warnings.

	* gscreen.c (x_fill_panel): Use gtk_dtree_select_dir(), not
	gtk_ctree_do_select_dir().

	* gpopup.c (gpopup_do_popup): Fixed incorrect assertion and
	actually create the menu (doh).
	(gpopup_do_popup): Do the same magic as in gnome-popup-menu to
	fetch the item that was activated in the menu.  Keep this code out
	of reach of children.
	(fill_menu): New function to fill the menu using the
	gnome-popup-menu magic for fetching the activated menu item.
	Removed ifdef'ed code.
Miguel de Icaza 26 years ago
parent
commit
befc99bf8d
5 changed files with 132 additions and 235 deletions
  1. 18 0
      gnome/ChangeLog
  2. 106 224
      gnome/gpopup.c
  3. 1 1
      gnome/gscreen.c
  4. 6 10
      gnome/gtkdtree.c
  5. 1 0
      gnome/gtkdtree.h

+ 18 - 0
gnome/ChangeLog

@@ -1,3 +1,21 @@
+1998-12-02  Federico Mena Quintero  <federico@nuclecu.unam.mx>
+
+	* gtkdtree.c (gtk_dtree_do_select_dir): Made static, as it is for
+	internal use only.
+	Fixed a little bunch of compiler warnings.
+
+	* gscreen.c (x_fill_panel): Use gtk_dtree_select_dir(), not
+	gtk_ctree_do_select_dir().
+
+	* gpopup.c (gpopup_do_popup): Fixed incorrect assertion and
+	actually create the menu (doh).
+	(gpopup_do_popup): Do the same magic as in gnome-popup-menu to
+	fetch the item that was activated in the menu.  Keep this code out
+	of reach of children.
+	(fill_menu): New function to fill the menu using the
+	gnome-popup-menu magic for fetching the activated menu item.
+	Removed ifdef'ed code.
+
 1998-12-02  Miguel de Icaza  <miguel@nuclecu.unam.mx>
 
 	* gscreen.c (tree_drag_open_directory, panel_tree_drag_motion,

+ 106 - 224
gnome/gpopup.c

@@ -109,6 +109,68 @@ dicon_delete (GtkWidget *widget, char *filename)
 	g_warning ("Implement this function!");
 }
 
+/* This is our custom signal connection function for popup menu items -- see below for the
+ * marshaller information.  We pass the original callback function as the data pointer for the
+ * marshaller (uiinfo->moreinfo).
+ */
+static void
+popup_connect_func (GnomeUIInfo *uiinfo, gchar *signal_name, GnomeUIBuilderData *uibdata)
+{
+	g_assert (uibdata->is_interp);
+
+	if (uiinfo->moreinfo) {
+		gtk_object_set_data (GTK_OBJECT (uiinfo->widget), "popup_user_data", uiinfo->user_data);
+		gtk_signal_connect_full (GTK_OBJECT (uiinfo->widget), signal_name,
+					 NULL,
+					 uibdata->relay_func,
+					 uiinfo->moreinfo,
+					 uibdata->destroy_func,
+					 FALSE,
+					 FALSE);
+	}
+}
+
+/* Our custom marshaller for menu items.  We need it so that it can extract the per-attachment
+ * user_data pointer from the parent menu shell and pass it to the callback.  This overrides the
+ * user-specified data from the GnomeUIInfo structures.
+ */
+
+typedef void (* ActivateFunc) (GtkObject *object, gpointer data);
+
+static void
+popup_marshal_func (GtkObject *object, gpointer data, guint n_args, GtkArg *args)
+{
+	ActivateFunc func;
+	gpointer user_data;
+
+	func = (ActivateFunc) data;
+	user_data = gtk_object_get_data (object, "popup_user_data");
+
+	gtk_object_set_data (GTK_OBJECT (GTK_WIDGET (object)->parent), "popup_active_item", object);
+	(* func) (object, user_data);
+}
+
+/* Fills the menu with the specified uiinfo at the specified position, using our magic marshallers
+ * to be able to fetch the active item.  The code is shamelessly ripped from gnome-popup-menu.
+ */
+static void
+fill_menu (GtkMenuShell *menu_shell, GnomeUIInfo *uiinfo, int pos)
+{
+	GnomeUIBuilderData uibdata;
+
+	/* We use our own callback marshaller so that it can fetch the popup user data
+	 * from the popup menu and pass it on to the user-defined callbacks.
+	 */
+
+	uibdata.connect_func = popup_connect_func;
+	uibdata.data = NULL;
+	uibdata.is_interp = TRUE;
+	uibdata.relay_func = popup_marshal_func;
+	uibdata.destroy_func = NULL;
+
+	gnome_app_fill_menu_custom (menu_shell, uiinfo, &uibdata, NULL, FALSE, pos);
+}
+
 
 /* The context menu: text displayed, condition that must be met and the routine that gets invoked
  * upon activation.
@@ -243,7 +305,7 @@ create_actions (GtkWidget *menu, WPanel *panel, int panel_row, char *filename)
 		} else
 			uiinfo[0].type = GNOME_APP_UI_SEPARATOR;
 
-		gnome_app_fill_menu (GTK_MENU_SHELL (menu), uiinfo, NULL, FALSE, pos);
+		fill_menu (GTK_MENU_SHELL (menu), uiinfo, pos);
 		pos++;
 	}
 
@@ -327,7 +389,7 @@ create_regexp_actions (GtkWidget *menu, WPanel *panel, int panel_row, char *file
 	for (i = 0; i < 5; i++)
 		a_uiinfo[i].user_data = closure;
 
-	gnome_app_fill_menu (GTK_MENU_SHELL (menu), a_uiinfo, NULL, FALSE, insert_pos);
+	fill_menu (GTK_MENU_SHELL (menu), a_uiinfo, insert_pos);
 	insert_pos += 5; /* the number of items from the common menus */
 
 	/* Fill in the regex command part */
@@ -366,7 +428,7 @@ create_regexp_actions (GtkWidget *menu, WPanel *panel, int panel_row, char *file
 		uiinfo[0].ac_mods = 0;
 		uiinfo[0].widget = NULL;
 
-		gnome_app_fill_menu (GTK_MENU_SHELL (menu), uiinfo, NULL, FALSE, insert_pos++);
+		fill_menu (GTK_MENU_SHELL (menu), uiinfo, insert_pos++);
 
 		/* Next! */
 
@@ -377,6 +439,30 @@ create_regexp_actions (GtkWidget *menu, WPanel *panel, int panel_row, char *file
 	}
 }
 
+/* Convenience callback to exit the main loop of a modal popup menu when it is deactivated*/
+static void
+menu_shell_deactivated (GtkMenuShell *menu_shell, gpointer data)
+{
+	gtk_main_quit ();
+}
+
+/* Returns the index of the active item in the specified menu, or -1 if none is active */
+static int
+get_active_index (GtkMenu *menu)
+{
+	GList *l;
+	GtkWidget *active;
+	int i;
+
+	active = gtk_object_get_data (GTK_OBJECT (menu), "popup_active_item");
+
+	for (i = 0, l = GTK_MENU_SHELL (menu)->children; l; l = l->next, i++)
+		if (active == l->data)
+			return i;
+
+	return -1;
+}
+
 /*
  * Create a context menu
  * It can take either a WPanel or a GnomeDesktopEntry.  One of them should
@@ -387,236 +473,32 @@ gpopup_do_popup (GdkEventButton *event, WPanel *from_panel, int panel_row, char
 {
 	GtkWidget *menu;
 	int pos;
+	guint id;
 
 	g_return_val_if_fail (event != NULL, -1);
-	g_return_val_if_fail ((from_panel != NULL) ^ (filename != NULL), -1);
+	g_return_val_if_fail (from_panel != NULL || filename != NULL, -1);
 
-	pos = create_actions (menu, from_panel, panel_row, filename);
-	create_regexp_actions (menu, from_panel, panel_row, filename, pos);
+	menu = gtk_menu_new ();
 
-	gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 3, event->time);
-	return 0; /* FIXME: return the index of the selected item */
-}
+	/* Connect to the deactivation signal to be able to quit our modal main loop */
 
+	id = gtk_signal_connect (GTK_OBJECT (menu), "deactivate",
+				 (GtkSignalFunc) menu_shell_deactivated,
+				 NULL);
 
+	/* Fill the menu */
 
+	pos = create_actions (menu, from_panel, panel_row, filename);
+	create_regexp_actions (menu, from_panel, panel_row, filename, pos);
 
+	/* Run it */
 
+	gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 3, event->time);
+	gtk_grab_add (menu);
+	gtk_main ();
+	gtk_grab_remove (menu);
 
+	gtk_signal_disconnect (GTK_OBJECT (menu), id);
 
-
-
-#if 0
-
-#include <config.h>
-#include <sys/stat.h>
-#include "util.h"
-#include <gnome.h>
-#include "gpopup.h"
-#define WANT_WIDGETS /* yuck */
-#include "main.h"
-#include "../vfs/vfs.h"
-
-
-static void popup_open (GtkWidget *widget, gpointer data);
-static void popup_open_new_window (GtkWidget *widget, gpointer data);
-static void popup_open_with_program (GtkWidget *widget, gpointer data);
-static void popup_open_with_arguments (GtkWidget *widget, gpointer data);
-static void popup_view (GtkWidget *widget, gpointer data);
-static void popup_edit (GtkWidget *widget, gpointer data);
-static void popup_move (GtkWidget *widget, gpointer data);
-static void popup_copy (GtkWidget *widget, gpointer data);
-static void popup_link (GtkWidget *widget, gpointer data);
-static void popup_delete (GtkWidget *widget, gpointer data);
-static void popup_properties (GtkWidget *widget, gpointer data);
-
-
-/* Keep this in sync with the popup_info array defined below, as these values are used to figure out
- * which items to enable/disable as appropriate.
- */
-enum {
-	POPUP_OPEN			= 0,
-	POPUP_OPEN_IN_NEW_WINDOW	= 1,
-	POPUP_OPEN_WITH_PROGRAM		= 2,
-	POPUP_OPEN_WITH_ARGUMENTS	= 3,
-	POPUP_VIEW			= 5,
-	POPUP_EDIT			= 6,
-	POPUP_VIEW_EDIT_SEPARATOR	= 7
-};
-
-/* The generic popup menu */
-static GnomeUIInfo popup_info[] = {
-	GNOMEUIINFO_ITEM_NONE (N_("_Open"), NULL, popup_open),
-	GNOMEUIINFO_ITEM_NONE (N_("Open in _new window"), NULL, popup_open_new_window),
-	GNOMEUIINFO_ITEM_NONE (N_("Open with pro_gram..."), NULL, popup_open_with_program),
-	GNOMEUIINFO_ITEM_NONE (N_("Open with _arguments..."), NULL, popup_open_with_arguments),
-
-	GNOMEUIINFO_SEPARATOR,
-
-	GNOMEUIINFO_ITEM_NONE (N_("_View"), NULL, popup_view),
-	GNOMEUIINFO_ITEM_NONE (N_("_Edit"), NULL, popup_edit),
-
-	GNOMEUIINFO_SEPARATOR,
-
-	GNOMEUIINFO_ITEM_NONE (N_("_Move/rename..."), NULL, popup_move),
-	GNOMEUIINFO_ITEM_NONE (N_("_Copy..."), NULL, popup_copy),
-	GNOMEUIINFO_ITEM_NONE (N_("_Link..."), NULL, popup_link),
-	GNOMEUIINFO_ITEM_NONE (N_("_Delete"), NULL, popup_delete),
-
-	GNOMEUIINFO_SEPARATOR,
-
-	GNOMEUIINFO_ITEM_NONE (N_("_Properties..."), NULL, popup_properties),
-	GNOMEUIINFO_END
-};
-
-struct popup_file_info {
-	char *filename;
-	WPanel *panel;
-};
-
-int
-gpopup_do_popup (char *filename, WPanel *from_panel, GdkEventButton *event)
-{
-	GtkWidget *popup;
-	struct stat s;
-	int result;
-	struct popup_file_info pfi;
-
-	if (mc_stat (filename, &s) != 0) {
-		g_warning ("Could not stat %s, no popup menu will be run", filename);
-		return -1;
-	}
-
-	popup = gnome_popup_menu_new (popup_info);
-
-	/* Hide the menu items that are not appropriate */
-
-	if (S_ISDIR (s.st_mode)) {
-		if (!from_panel)
-			gtk_widget_hide (popup_info[POPUP_OPEN].widget); /* Only allow "open in new window" */
-
-		gtk_widget_hide (popup_info[POPUP_OPEN_WITH_ARGUMENTS].widget);
-		gtk_widget_hide (popup_info[POPUP_VIEW].widget);
-		gtk_widget_hide (popup_info[POPUP_EDIT].widget);
-		gtk_widget_hide (popup_info[POPUP_VIEW_EDIT_SEPARATOR].widget);
-	} else {
-		gtk_widget_hide (popup_info[POPUP_OPEN_IN_NEW_WINDOW].widget);
-
-		if (is_exe (s.st_mode))
-			gtk_widget_hide (popup_info[POPUP_OPEN_WITH_PROGRAM].widget);
-		else
-			gtk_widget_hide (popup_info[POPUP_OPEN_WITH_ARGUMENTS].widget);
-	}
-
-	/* Go! */
-
-	pfi.filename = filename;
-	pfi.panel = from_panel;
-
-	result = gnome_popup_menu_do_popup_modal (popup, NULL, NULL, event, &pfi);
-
-	gtk_widget_destroy (popup);
-	return result;
-}
-
-static void
-popup_open (GtkWidget *widget, gpointer data)
-{
-	struct popup_file_info *pfi;
-	struct stat s;
-
-	pfi = data;
-
-	if (mc_stat (pfi->filename, &s) != 0) {
-		g_warning ("Could not stat %s", pfi->filename);
-		return;
-	}
-
-	do_enter (pfi->panel);
-
-#if 0
-	if (S_ISDIR (s.st_mode)) {
-		/* Open the directory in the panel the menu was activated from */
-
-		g_assert (pfi->panel != NULL);
-
-		do_panel_cd (pfi->panel, pfi->filename, cd_exact);
-	} else if (is_exe (s.st_mode)) {
-		/* FIXME: execute */
-	} else {
-		/* FIXME: get default program and launch it with this file */
-	}
-#endif
-}
-
-static void
-popup_open_new_window (GtkWidget *widget, gpointer data)
-{
-	/* FIXME */
-	g_warning ("Implement this function!");
-}
-
-static void
-popup_open_with_program (GtkWidget *widget, gpointer data)
-{
-	/* FIXME */
-	g_warning ("Implement this function!");
-}
-
-static void
-popup_open_with_arguments (GtkWidget *widget, gpointer data)
-{
-	/* FIXME */
-	g_warning ("Implement this function!");
-}
-
-static void
-popup_view (GtkWidget *widget, gpointer data)
-{
-	/* FIXME */
-	g_warning ("Implement this function!");
-}
-
-static void
-popup_edit (GtkWidget *widget, gpointer data)
-{
-	/* FIXME */
-	g_warning ("Implement this function!");
-}
-
-static void
-popup_move (GtkWidget *widget, gpointer data)
-{
-	/* FIXME */
-	g_warning ("Implement this function!");
-}
-
-static void
-popup_copy (GtkWidget *widget, gpointer data)
-{
-	/* FIXME */
-	g_warning ("Implement this function!");
-}
-
-static void
-popup_link (GtkWidget *widget, gpointer data)
-{
-	/* FIXME */
-	g_warning ("Implement this function!");
-}
-
-static void
-popup_delete (GtkWidget *widget, gpointer data)
-{
-	/* FIXME */
-	g_warning ("Implement this function!");
-}
-
-static void
-popup_properties (GtkWidget *widget, gpointer data)
-{
-	/* FIXME */
-	g_warning ("Implement this function!");
+	return get_active_index (GTK_MENU (menu));
 }
-
-#endif

+ 1 - 1
gnome/gscreen.c

@@ -276,7 +276,7 @@ x_fill_panel (WPanel *panel)
 
 	gtk_signal_handler_block_by_data (GTK_OBJECT (panel->tree), panel);
 
-	gtk_dtree_do_select_dir (GTK_DTREE (panel->tree), panel->cwd); 
+	gtk_dtree_select_dir (GTK_DTREE (panel->tree), panel->cwd); 
 
 	gtk_signal_handler_unblock_by_data (GTK_OBJECT (panel->tree), panel);
 }

+ 6 - 10
gnome/gtkdtree.c

@@ -73,7 +73,6 @@ static GtkCTreeNode *
 gtk_dtree_contains (GtkDTree *dtree, GtkCTreeNode *parent, char *text)
 {
 	GtkCTreeNode *node;
-	char *s;
 	
 	g_assert (dtree);
 	g_assert (parent);
@@ -100,8 +99,6 @@ gtk_dtree_load_path (GtkDTree *dtree, char *path, GtkCTreeNode *parent, int leve
 {
 	DIR *dir;
 	struct dirent *dirent;
-	char *full_name;
-	int stats = 0;
 	
 	g_assert (path);
 	g_assert (parent);
@@ -174,7 +171,6 @@ static void
 gtk_dtree_select_row (GtkCTree *ctree, GtkCTreeNode *row, gint column)
 {
 	GtkDTree *dtree = GTK_DTREE (ctree);
-	GtkCTreeNode *last_node;
 	char *path;
 
 	parent_class->tree_select_row (ctree, row, column);
@@ -243,7 +239,7 @@ gtk_dtree_lookup_dir (GtkDTree *dtree, GtkCTreeNode *parent, char *dirname)
 	return NULL;
 }
 
-gboolean
+static gboolean
 gtk_dtree_do_select_dir (GtkDTree *dtree, char *path)
 {
 	GtkCTreeNode *current_node;
@@ -264,7 +260,7 @@ gtk_dtree_do_select_dir (GtkDTree *dtree, char *path)
 	npath = g_strdup ("/");
 
 	while ((current = strtok (s, "/")) != NULL){
-		char *comp, *full_path;
+		char *full_path;
 		GtkCTreeNode *node;
 
 		s = NULL;
@@ -320,10 +316,10 @@ gtk_dtree_do_select_dir (GtkDTree *dtree, char *path)
 gboolean
 gtk_dtree_select_dir (GtkDTree *dtree, char *path)
 {
-	g_return_if_fail (dtree != NULL);
-	g_return_if_fail (GTK_IS_DTREE (dtree));
-	g_return_if_fail (path != NULL);
-	g_return_if_fail (*path == '/');
+	g_return_val_if_fail (dtree != NULL, FALSE);
+	g_return_val_if_fail (GTK_IS_DTREE (dtree), FALSE);
+	g_return_val_if_fail (path != NULL, FALSE);
+	g_return_val_if_fail (*path == '/', FALSE);
 
 	if (dtree->visible)
 		gtk_dtree_do_select_dir (dtree, path);

+ 1 - 0
gnome/gtkdtree.h

@@ -48,4 +48,5 @@ void       gtk_dtree_remove_dir_by_name (GtkDTree *dtree,
 					 char *directory);
 gboolean   gtk_dtree_select_dir         (GtkDTree *dtree,
 					 char *directory);
+
 #endif