From 4dbadb32ec1d37ffb8ef3eb1d836d8802e77f923 Mon Sep 17 00:00:00 2001 From: Miguel de Icaza Date: Tue, 1 Dec 1998 06:23:50 +0000 Subject: [PATCH] Sync to laptop - Federico --- gnome/ChangeLog | 1 + gnome/gdesktop.c | 3 + gnome/gpopup.c | 353 +++++++++++++++++++++++++++++++++++++++++++++++ gnome/gpopup.h | 2 + gnome/gscreen.c | 323 ------------------------------------------- src/filegui.c | 1 + 6 files changed, 360 insertions(+), 323 deletions(-) diff --git a/gnome/ChangeLog b/gnome/ChangeLog index 47cc7de26..a8a0c3165 100644 --- a/gnome/ChangeLog +++ b/gnome/ChangeLog @@ -2,6 +2,7 @@ * gscreen.c (panel_icon_list_select_icon): Use gpopup_do_popup(). (panel_file_list_select_row): Use gpopup_do_popup(). + Moved the popup menu code to gpopup.c. 1998-11-29 Federico Mena Quintero diff --git a/gnome/gdesktop.c b/gnome/gdesktop.c index 49915c5e3..a1873a5bb 100644 --- a/gnome/gdesktop.c +++ b/gnome/gdesktop.c @@ -347,7 +347,10 @@ desktop_icon_info_event (struct desktop_icon_info *dii, GdkEvent *event, int on_ retval = TRUE; } else if (event->button.button == 3) { filename = g_concat_dir_and_file (desktop_directory, dii->filename); +#if 0 gpopup_do_popup (filename, FALSE, (GdkEventButton *) event); +#endif + g_free (filename); retval = TRUE; } diff --git a/gnome/gpopup.c b/gnome/gpopup.c index 0c21e91cd..47aae0728 100644 --- a/gnome/gpopup.c +++ b/gnome/gpopup.c @@ -6,6 +6,357 @@ * Miguel de Icaza */ + +#include +#include "util.h" +#include +#include "panel.h" +#include "cmd.h" +#include "dialog.h" +#include "ext.h" +#include "gpageprop.h" +#include "gpopup.h" +#include "main.h" + + +#define CLIST_FROM_SW(panel_list) GTK_CLIST (GTK_BIN (panel_list)->child) + + +/* + * Flags for the context-sensitive popup menus + */ +#define F_ALL 1 +#define F_REGULAR 2 +#define F_SYMLINK 4 +#define F_SINGLE 8 +#define F_NOTDIR 16 +#define F_DICON 32 /* Only applies to desktop_icon_t */ +#define F_PANEL 64 /* Only applies to WPanel */ + + +static void +panel_action_open_with (GtkWidget *widget, WPanel *panel) +{ + char *command; + + command = input_expand_dialog (_(" Open with..."), + _("Enter extra arguments:"), panel->dir.list [panel->selected].fname); + if (!command) + return; + execute (command); + free (command); +} + +static void +panel_action_open (GtkWidget *widget, WPanel *panel) +{ + if (do_enter (panel)) + return; + panel_action_open_with (widget, panel); +} + +void +panel_action_view (GtkWidget *widget, WPanel *panel) +{ + view_cmd (panel); +} + +void +panel_action_view_unfiltered (GtkWidget *widget, WPanel *panel) +{ + view_simple_cmd (panel); +} + +void +panel_action_edit (GtkWidget *widget, WPanel *panel) +{ + edit_cmd (panel); +} + +void +panel_action_properties (GtkWidget *widget, WPanel *panel) +{ + file_entry *fe = &panel->dir.list [panel->selected]; + char *full_name = concat_dir_and_file (panel->cwd, fe->fname); + + if (item_properties (GTK_WIDGET (CLIST_FROM_SW (panel->list)), full_name, NULL) != 0) + reread_cmd (); + + free (full_name); +} + +typedef void (*context_menu_callback)(GtkWidget *, void *); + +/* + * The context menu: text displayed, condition that must be met and + * the routine that gets invoked upon activation. + */ +static struct { + char *text; + int flags; + context_menu_callback callback; +} file_actions [] = { + { N_("Properties"), F_SINGLE | F_PANEL, (context_menu_callback) panel_action_properties }, +#if 0 + { N_("Properties"), F_SINGLE | F_DICON, (context_menu_callback) desktop_icon_properties }, +#endif + { "", F_SINGLE, NULL }, + { N_("Open"), F_PANEL | F_ALL, (context_menu_callback) panel_action_open }, +#if 0 + { N_("Open"), F_DICON | F_ALL, (context_menu_callback) desktop_icon_execute }, +#endif + { N_("Open with"), F_PANEL | F_ALL, (context_menu_callback) panel_action_open_with }, + { N_("View"), F_PANEL | F_NOTDIR, (context_menu_callback) panel_action_view }, + { N_("View unfiltered"), F_PANEL | F_NOTDIR, (context_menu_callback) panel_action_view_unfiltered }, + { N_("Edit"), F_PANEL | F_NOTDIR, (context_menu_callback) panel_action_edit }, + { "", 0, NULL }, + { N_("Link..."), F_PANEL | F_REGULAR | F_SINGLE, (context_menu_callback) link_cmd }, + { N_("Symlink..."), F_PANEL | F_SINGLE, (context_menu_callback) symlink_cmd }, + { N_("Edit symlink..."), F_PANEL | F_SYMLINK, (context_menu_callback) edit_symlink_cmd }, + { NULL, 0, NULL }, +}; + +typedef struct { + char *text; + context_menu_callback callback; +} common_menu_t; + +/* + * context menu, constant entries + */ +common_menu_t common_panel_actions [] = { + { N_("Copy..."), (context_menu_callback) copy_cmd }, + { N_("Rename/move..."), (context_menu_callback) ren_cmd }, + { N_("Delete..."), (context_menu_callback) delete_cmd }, + { NULL, NULL } +}; + +common_menu_t common_dicon_actions [] = { +#if 0 + { N_("Delete"), (context_menu_callback) desktop_icon_delete }, +#endif + { NULL, NULL } +}; + +static GtkWidget * +create_popup_submenu (WPanel *panel, desktop_icon_t *di, int row, char *filename) +{ + static int submenu_translated; + GtkWidget *menu; + int i; + void *closure; + + closure = (panel != 0 ? (void *) panel : (void *)di); + + if (!submenu_translated){ + /* FIXME translate it */ + submenu_translated = 1; + } + + menu = gtk_menu_new (); + for (i = 0; file_actions [i].text; i++){ + GtkWidget *item; + + /* First, try F_PANEL and F_DICON flags */ + if (di && (file_actions [i].flags & F_PANEL)) + continue; + + if (panel && (file_actions [i].flags & F_DICON)) + continue; + + /* Items with F_ALL bypass any other condition */ + if (!(file_actions [i].flags & F_ALL)){ + + /* Items with F_SINGLE require that ONLY ONE marked files exist */ + if (panel && file_actions [i].flags & F_SINGLE){ + if (panel->marked > 1) + continue; + } + + /* Items with F_NOTDIR requiere that the selection is not a directory */ + if (panel && file_actions [i].flags & F_NOTDIR){ + struct stat *s = &panel->dir.list [row].buf; + + if (panel->dir.list [row].f.link_to_dir) + continue; + + if (S_ISDIR (s->st_mode)) + continue; + } + + /* Items with F_REGULAR do not accept any strange file types */ + if (panel && file_actions [i].flags & F_REGULAR){ + struct stat *s = &panel->dir.list [row].buf; + + if (S_ISLNK (panel->dir.list [row].f.link_to_dir)) + continue; + if (S_ISSOCK (s->st_mode) || S_ISCHR (s->st_mode) || + S_ISFIFO (s->st_mode) || S_ISBLK (s->st_mode)) + continue; + } + + /* Items with F_SYMLINK only operate on symbolic links */ + if (panel && file_actions [i].flags & F_SYMLINK){ + if (!S_ISLNK (panel->dir.list [row].buf.st_mode)) + continue; + } + } + if (*file_actions [i].text) + item = gtk_menu_item_new_with_label (_(file_actions [i].text)); + else + item = gtk_menu_item_new (); + + gtk_widget_show (item); + if (file_actions [i].callback){ + gtk_signal_connect (GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC(file_actions [i].callback), closure); + } + + gtk_menu_append (GTK_MENU (menu), item); + } + return menu; +} + +/* + * Ok, this activates a menu popup action for a filename + * it is kind of hackish, it gets the desired action from the + * item, so it has to peek inside the item to retrieve the label + */ +static void +popup_activate_by_string (GtkMenuItem *item, WPanel *panel) +{ + char *filename = panel->dir.list [panel->selected].fname; + char *action; + int movedir; + + g_return_if_fail (GTK_IS_MENU_ITEM (item)); + g_return_if_fail (GTK_IS_LABEL (GTK_BIN (item)->child)); + + action = GTK_LABEL (GTK_BIN (item)->child)->label; + + regex_command (filename, action, NULL, &movedir); +} + +static void +popup_activate_desktop_icon (GtkMenuItem *item, char *filename) +{ + char *action; + int movedir; + + action = GTK_LABEL (GTK_BIN (item)->child)->label; + + regex_command (filename, action, NULL, &movedir); +} + +static void +file_popup_add_context (GtkMenu *menu, WPanel *panel, desktop_icon_t *di, char *filename) +{ + GtkWidget *item; + char *p, *q; + int c, i; + void *closure, *regex_closure; + common_menu_t *menu_p; + GtkSignalFunc regex_func; + + if (panel){ + menu_p = common_panel_actions; + closure = panel; + regex_func = GTK_SIGNAL_FUNC (popup_activate_by_string); + regex_closure = panel; + } else { + menu_p = common_dicon_actions; + closure = di; + regex_func = GTK_SIGNAL_FUNC (popup_activate_desktop_icon); + regex_closure = di->dentry->exec [0]; + } + + for (i = 0; menu_p [i].text; i++){ + GtkWidget *item; + + item = gtk_menu_item_new_with_label (_(menu_p [i].text)); + gtk_widget_show (item); + gtk_signal_connect (GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (menu_p [i].callback), closure); + gtk_menu_append (GTK_MENU (menu), item); + } + + p = regex_command (filename, NULL, NULL, NULL); + if (!p) + return; + + item = gtk_menu_item_new (); + gtk_widget_show (item); + gtk_menu_append (menu, item); + + for (;;){ + while (*p == ' ' || *p == '\t') + p++; + if (!*p) + break; + q = p; + while (*q && *q != '=' && *q != '\t') + q++; + c = *q; + *q = 0; + + item = gtk_menu_item_new_with_label (p); + gtk_widget_show (item); + + gtk_signal_connect (GTK_OBJECT(item), "activate", regex_func, regex_closure); + gtk_menu_append (menu, item); + if (!c) + break; + p = q + 1; + } +} + +/* + * Create a context menu + * It can take either a WPanel or a GnomeDesktopEntry. One of them should + * be set to NULL. + */ +void +file_popup (GdkEventButton *event, void *WPanel_pointer, void *desktop_icon_t_pointer, int row, char *filename) +{ + GtkWidget *menu = gtk_menu_new (); + GtkWidget *submenu; + GtkWidget *item; + WPanel *panel = WPanel_pointer; + desktop_icon_t *di = desktop_icon_t_pointer; + char *str; + + g_return_if_fail (((panel != NULL) ^ (di != NULL))); + + if (panel) + str = (panel->marked > 1) ? "..." : filename; + else + str = filename; + + if (panel){ + item = gtk_menu_item_new_with_label (str); + gtk_widget_show (item); + gtk_menu_append (GTK_MENU (menu), item); + + submenu = create_popup_submenu (panel, di, row, filename); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); + } else + menu = create_popup_submenu (panel, di, row, filename); + + file_popup_add_context (GTK_MENU (menu), panel, di, filename); + + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 3, event->time); +} + + + + + + + + + +#if 0 + #include #include #include "util.h" @@ -216,3 +567,5 @@ popup_properties (GtkWidget *widget, gpointer data) /* FIXME */ g_warning ("Implement this function!"); } + +#endif diff --git a/gnome/gpopup.h b/gnome/gpopup.h index 3c9d86715..21e13bc2e 100644 --- a/gnome/gpopup.h +++ b/gnome/gpopup.h @@ -14,6 +14,8 @@ #include "panel.h" +void file_popup (GdkEventButton *event, void *WPanel_pointer, void *desktop_icon_t_pointer, int row, char *filename); + int gpopup_do_popup (char *filename, WPanel *from_panel, GdkEventButton *event); diff --git a/gnome/gscreen.c b/gnome/gscreen.c index 528286ed5..063769785 100644 --- a/gnome/gscreen.c +++ b/gnome/gscreen.c @@ -84,18 +84,6 @@ GtkWidget *drag_directory_ok = NULL; GtkWidget *drag_multiple = NULL; GtkWidget *drag_multiple_ok = NULL; -typedef void (*context_menu_callback)(GtkWidget *, void *); - -/* - * Flags for the context-sensitive popup menus - */ -#define F_ALL 1 -#define F_REGULAR 2 -#define F_SYMLINK 4 -#define F_SINGLE 8 -#define F_NOTDIR 16 -#define F_DICON 32 /* Only applies to desktop_icon_t */ -#define F_PANEL 64 /* Only applies to WPanel */ static void panel_file_list_configure_contents (GtkWidget *sw, WPanel *panel, int main_width, int height); @@ -490,317 +478,6 @@ panel_file_list_configure_contents (GtkWidget *sw, WPanel *panel, int main_width gtk_clist_thaw (clist); } -static void -panel_action_open_with (GtkWidget *widget, WPanel *panel) -{ - char *command; - - command = input_expand_dialog (_(" Open with..."), - _("Enter extra arguments:"), panel->dir.list [panel->selected].fname); - if (!command) - return; - execute (command); - free (command); -} - -static void -panel_action_open (GtkWidget *widget, WPanel *panel) -{ - if (do_enter (panel)) - return; - panel_action_open_with (widget, panel); -} - -void -panel_action_view (GtkWidget *widget, WPanel *panel) -{ - view_cmd (panel); -} - -void -panel_action_view_unfiltered (GtkWidget *widget, WPanel *panel) -{ - view_simple_cmd (panel); -} - -void -panel_action_edit (GtkWidget *widget, WPanel *panel) -{ - edit_cmd (panel); -} - -void -panel_action_properties (GtkWidget *widget, WPanel *panel) -{ - file_entry *fe = &panel->dir.list [panel->selected]; - char *full_name = concat_dir_and_file (panel->cwd, fe->fname); - - if (item_properties (GTK_WIDGET (CLIST_FROM_SW (panel->list)), full_name, NULL) != 0) - reread_cmd (); - - free (full_name); -} - -/* - * The context menu: text displayed, condition that must be met and - * the routine that gets invoked upon activation. - */ -static struct { - char *text; - int flags; - context_menu_callback callback; -} file_actions [] = { - { N_("Properties"), F_SINGLE | F_PANEL, (context_menu_callback) panel_action_properties }, -#if 0 - { N_("Properties"), F_SINGLE | F_DICON, (context_menu_callback) desktop_icon_properties }, -#endif - { "", F_SINGLE, NULL }, - { N_("Open"), F_PANEL | F_ALL, (context_menu_callback) panel_action_open }, -#if 0 - { N_("Open"), F_DICON | F_ALL, (context_menu_callback) desktop_icon_execute }, -#endif - { N_("Open with"), F_PANEL | F_ALL, (context_menu_callback) panel_action_open_with }, - { N_("View"), F_PANEL | F_NOTDIR, (context_menu_callback) panel_action_view }, - { N_("View unfiltered"), F_PANEL | F_NOTDIR, (context_menu_callback) panel_action_view_unfiltered }, - { N_("Edit"), F_PANEL | F_NOTDIR, (context_menu_callback) panel_action_edit }, - { "", 0, NULL }, - { N_("Link..."), F_PANEL | F_REGULAR | F_SINGLE, (context_menu_callback) link_cmd }, - { N_("Symlink..."), F_PANEL | F_SINGLE, (context_menu_callback) symlink_cmd }, - { N_("Edit symlink..."), F_PANEL | F_SYMLINK, (context_menu_callback) edit_symlink_cmd }, - { NULL, 0, NULL }, -}; - -typedef struct { - char *text; - context_menu_callback callback; -} common_menu_t; - -/* - * context menu, constant entries - */ -common_menu_t common_panel_actions [] = { - { N_("Copy..."), (context_menu_callback) copy_cmd }, - { N_("Rename/move..."), (context_menu_callback) ren_cmd }, - { N_("Delete..."), (context_menu_callback) delete_cmd }, - { NULL, NULL } -}; - -common_menu_t common_dicon_actions [] = { -#if 0 - { N_("Delete"), (context_menu_callback) desktop_icon_delete }, -#endif - { NULL, NULL } -}; - -static GtkWidget * -create_popup_submenu (WPanel *panel, desktop_icon_t *di, int row, char *filename) -{ - static int submenu_translated; - GtkWidget *menu; - int i; - void *closure; - - closure = (panel != 0 ? (void *) panel : (void *)di); - - if (!submenu_translated){ - /* FIXME translate it */ - submenu_translated = 1; - } - -/* menu = gtk_menu_new (); */ - for (i = 0; file_actions [i].text; i++){ - GtkWidget *item; - - /* First, try F_PANEL and F_DICON flags */ - if (di && (file_actions [i].flags & F_PANEL)) - continue; - - if (panel && (file_actions [i].flags & F_DICON)) - continue; - - /* Items with F_ALL bypass any other condition */ - if (!(file_actions [i].flags & F_ALL)){ - - /* Items with F_SINGLE require that ONLY ONE marked files exist */ - if (panel && file_actions [i].flags & F_SINGLE){ - if (panel->marked > 1) - continue; - } - - /* Items with F_NOTDIR requiere that the selection is not a directory */ - if (panel && file_actions [i].flags & F_NOTDIR){ - struct stat *s = &panel->dir.list [row].buf; - - if (panel->dir.list [row].f.link_to_dir) - continue; - - if (S_ISDIR (s->st_mode)) - continue; - } - - /* Items with F_REGULAR do not accept any strange file types */ - if (panel && file_actions [i].flags & F_REGULAR){ - struct stat *s = &panel->dir.list [row].buf; - - if (S_ISLNK (panel->dir.list [row].f.link_to_dir)) - continue; - if (S_ISSOCK (s->st_mode) || S_ISCHR (s->st_mode) || - S_ISFIFO (s->st_mode) || S_ISBLK (s->st_mode)) - continue; - } - - /* Items with F_SYMLINK only operate on symbolic links */ - if (panel && file_actions [i].flags & F_SYMLINK){ - if (!S_ISLNK (panel->dir.list [row].buf.st_mode)) - continue; - } - } - if (*file_actions [i].text) - item = gtk_menu_item_new_with_label (_(file_actions [i].text)); - else - item = gtk_menu_item_new (); - - gtk_widget_show (item); - if (file_actions [i].callback){ - gtk_signal_connect (GTK_OBJECT (item), "activate", - GTK_SIGNAL_FUNC(file_actions [i].callback), closure); - } - - gtk_menu_append (GTK_MENU (menu), item); - } - return menu; -} - -/* - * Ok, this activates a menu popup action for a filename - * it is kind of hackish, it gets the desired action from the - * item, so it has to peek inside the item to retrieve the label - */ -static void -popup_activate_by_string (GtkMenuItem *item, WPanel *panel) -{ - char *filename = panel->dir.list [panel->selected].fname; - char *action; - int movedir; - - g_return_if_fail (GTK_IS_MENU_ITEM (item)); - g_return_if_fail (GTK_IS_LABEL (GTK_BIN (item)->child)); - - action = GTK_LABEL (GTK_BIN (item)->child)->label; - - regex_command (filename, action, NULL, &movedir); -} - -static void -popup_activate_desktop_icon (GtkMenuItem *item, char *filename) -{ - char *action; - int movedir; - - action = GTK_LABEL (GTK_BIN (item)->child)->label; - - regex_command (filename, action, NULL, &movedir); -} - -static void -file_popup_add_context (GtkMenu *menu, WPanel *panel, desktop_icon_t *di, char *filename) -{ - GtkWidget *item; - char *p, *q; - int c, i; - void *closure, *regex_closure; - common_menu_t *menu_p; - GtkSignalFunc regex_func; - - if (panel){ - menu_p = common_panel_actions; - closure = panel; - regex_func = GTK_SIGNAL_FUNC (popup_activate_by_string); - regex_closure = panel; - } else { - menu_p = common_dicon_actions; - closure = di; - regex_func = GTK_SIGNAL_FUNC (popup_activate_desktop_icon); - regex_closure = di->dentry->exec [0]; - } - - for (i = 0; menu_p [i].text; i++){ - GtkWidget *item; - - item = gtk_menu_item_new_with_label (_(menu_p [i].text)); - gtk_widget_show (item); - gtk_signal_connect (GTK_OBJECT (item), "activate", - GTK_SIGNAL_FUNC (menu_p [i].callback), closure); - gtk_menu_append (GTK_MENU (menu), item); - } - - p = regex_command (filename, NULL, NULL, NULL); - if (!p) - return; - - item = gtk_menu_item_new (); - gtk_widget_show (item); - gtk_menu_append (menu, item); - - for (;;){ - while (*p == ' ' || *p == '\t') - p++; - if (!*p) - break; - q = p; - while (*q && *q != '=' && *q != '\t') - q++; - c = *q; - *q = 0; - - item = gtk_menu_item_new_with_label (p); - gtk_widget_show (item); - - gtk_signal_connect (GTK_OBJECT(item), "activate", regex_func, regex_closure); - gtk_menu_append (menu, item); - if (!c) - break; - p = q + 1; - } -} - -/* - * Create a context menu - * It can take either a WPanel or a GnomeDesktopEntry. One of them should - * be set to NULL. - */ -void -file_popup (GdkEventButton *event, void *WPanel_pointer, void *desktop_icon_t_pointer, int row, char *filename) -{ - GtkWidget *menu = gtk_menu_new (); - GtkWidget *submenu; - GtkWidget *item; - WPanel *panel = WPanel_pointer; - desktop_icon_t *di = desktop_icon_t_pointer; - char *str; - - g_return_if_fail (((panel != NULL) ^ (di != NULL))); - - if (panel) - str = (panel->marked > 1) ? "..." : filename; - else - str = filename; - - if (panel){ - item = gtk_menu_item_new_with_label (str); - gtk_widget_show (item); - gtk_menu_append (GTK_MENU (menu), item); - - submenu = create_popup_submenu (panel, di, row, filename); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); - } else - menu = create_popup_submenu (panel, di, row, filename); - - file_popup_add_context (GTK_MENU (menu), panel, di, filename); - - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 3, event->time); -} - static void internal_select_item (GtkWidget *file_list, WPanel *panel, int row) { diff --git a/src/filegui.c b/src/filegui.c index 2d60522b1..4553e97d6 100644 --- a/src/filegui.c +++ b/src/filegui.c @@ -178,6 +178,7 @@ file_progress_check_buttons (void) int c; Gpm_Event event; + x_flush_events (); c = get_event (&event, 0, 0); if (c == EV_NONE) return FILE_CONT;