Sync to laptop - Federico

This commit is contained in:
Miguel de Icaza 1998-12-01 06:23:50 +00:00
parent deec804b4a
commit 4dbadb32ec
6 changed files with 360 additions and 323 deletions

View File

@ -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 <federico@nuclecu.unam.mx>

View File

@ -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;
}

View File

@ -6,6 +6,357 @@
* Miguel de Icaza <miguel@nuclecu.unam.mx>
*/
#include <config.h>
#include "util.h"
#include <gnome.h>
#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 <config.h>
#include <sys/stat.h>
#include "util.h"
@ -216,3 +567,5 @@ popup_properties (GtkWidget *widget, gpointer data)
/* FIXME */
g_warning ("Implement this function!");
}
#endif

View File

@ -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);

View File

@ -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)
{

View File

@ -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;