cbebd9cd27
* gdesktop.c (do_mount_umount): Use g_readlink here. * gpopup2.c (handle_eject): Small tuning. And use g_readlink :-). * gmount.c (mount_point_to_device): New function. Mapes a mount point to its device. Required since we are now using the mount point (as this is not ambiguous) as the key for the devices and the eject command needs the device name, not the mount point. * gdesktop.c (desktop_icon_info_open): First try to see if filename is mountable. Then do the directory tests and the file launching tests. Fixes mount-by-double click. * gmount.c (setup_devices): Use new tigert icon.
736 строки
18 KiB
C
736 строки
18 KiB
C
/* Popup menus for the Midnight Commander
|
|
*
|
|
* Copyright (C) 1998 The Free Software Foundation
|
|
*
|
|
* Authors: Federico Mena <federico@nuclecu.unam.mx>
|
|
* Miguel de Icaza <miguel@nuclecu.unam.mx>
|
|
* Jonathan Blandford <jrb@redhat.com>
|
|
*/
|
|
|
|
/* These rules really need to be duplicated elsewhere.
|
|
* They should exist for the menu bar too...
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include "global.h"
|
|
#include <gnome.h>
|
|
#include "panel.h"
|
|
#include "cmd.h"
|
|
#include "dialog.h"
|
|
#include "ext.h"
|
|
#include "main.h"
|
|
#include "../vfs/vfs.h"
|
|
#include "gpageprop.h"
|
|
#include "gpopup.h"
|
|
#include "gnome-file-property-dialog.h"
|
|
#include "gnome-open-dialog.h"
|
|
#include "gmain.h"
|
|
#define CLIST_FROM_SW(panel_list) GTK_CLIST (GTK_BIN (panel_list)->child)
|
|
|
|
|
|
/* Flags for the popup menu entries. They specify to which kinds of files an
|
|
* entry is valid for.
|
|
*/
|
|
enum {
|
|
F_ALL = 1 << 0, /* Applies to all files */
|
|
F_REGULAR = 1 << 1, /* Applies only to regular files */
|
|
F_SYMLINK = 1 << 2, /* Applies only to symlinks */
|
|
F_SINGLE = 1 << 3, /* Applies only to a single file, not to multiple files */
|
|
F_NOTDIR = 1 << 4, /* Applies to non-directories */
|
|
F_NOTDEV = 1 << 5, /* Applies to non-devices only (ie. reg, lnk, dir) */
|
|
F_ADVANCED = 1 << 6, /* Only appears in advanced mode */
|
|
F_MIME_ACTIONS = 1 << 7 /* Special marker for the position of MIME actions */
|
|
};
|
|
|
|
/* An entry in the actions menu */
|
|
|
|
typedef gboolean (*menu_func) (WPanel *panel, DesktopIconInfo *dii);
|
|
|
|
struct action {
|
|
char *text; /* Menu item text */
|
|
int flags; /* Flags from the above enum */
|
|
gpointer callback; /* Callback for menu item */
|
|
menu_func func; /* NULL if item is always present; a predicate otherwise */
|
|
};
|
|
|
|
|
|
/* Multiple File commands */
|
|
static void handle_open (GtkWidget *widget, WPanel *panel);
|
|
static void handle_mount (GtkWidget *widget, WPanel *panel);
|
|
static void handle_unmount (GtkWidget *widget, WPanel *panel);
|
|
static void handle_eject (GtkWidget *widget, WPanel *panel);
|
|
static void handle_view (GtkWidget *widget, WPanel *panel);
|
|
static void handle_view_unfiltered (GtkWidget *widget, WPanel *panel);
|
|
static void handle_edit (GtkWidget *widget, WPanel *panel);
|
|
static void handle_copy (GtkWidget *widget, WPanel *panel);
|
|
static void handle_delete (GtkWidget *widget, WPanel *panel);
|
|
static void handle_move (GtkWidget *widget, WPanel *panel);
|
|
|
|
/* F_SINGLE file commands */
|
|
static void handle_properties (GtkWidget *widget, WPanel *panel);
|
|
static void handle_open_with (GtkWidget *widget, WPanel *panel);
|
|
static void handle_symlink (GtkWidget *widget, WPanel *panel);
|
|
static void handle_hard_link (GtkWidget *widget, WPanel *panel);
|
|
static void handle_edit_symlink (GtkWidget *widget, WPanel *panel);
|
|
|
|
/* Helper funcs and testing funcs. */
|
|
static gboolean check_mount_func (WPanel *panel, DesktopIconInfo *dii);
|
|
static gboolean check_unmount_func (WPanel *panel, DesktopIconInfo *dii);
|
|
static gboolean check_eject_func (WPanel *panel, DesktopIconInfo *dii);
|
|
static gboolean check_edit_func (WPanel *panel, DesktopIconInfo *dii);
|
|
static gboolean check_view_func (WPanel *panel, DesktopIconInfo *dii);
|
|
|
|
static gchar * get_full_filename (WPanel *panel);
|
|
|
|
/* Now, the actual code */
|
|
static gchar *
|
|
get_full_filename (WPanel *panel)
|
|
{
|
|
if (is_a_desktop_panel (panel)) {
|
|
gint i;
|
|
for (i = 0; i < panel->count; i++)
|
|
if (panel->dir.list [i].f.marked) {
|
|
return concat_dir_and_file (panel->cwd,
|
|
panel->dir.list [i].fname);
|
|
}
|
|
g_return_val_if_fail (FALSE, NULL);
|
|
} else
|
|
return concat_dir_and_file (panel->cwd, selection (panel)->fname);
|
|
|
|
}
|
|
|
|
static gboolean
|
|
check_mount_umount (DesktopIconInfo *dii, int mount)
|
|
{
|
|
char *full_name;
|
|
file_entry *fe;
|
|
int v;
|
|
int is_mounted;
|
|
|
|
full_name = g_concat_dir_and_file (desktop_directory, dii->filename);
|
|
fe = file_entry_from_file (full_name);
|
|
if (!fe) {
|
|
g_free (full_name);
|
|
return FALSE;
|
|
}
|
|
|
|
v = is_mountable (full_name, fe, &is_mounted, NULL);
|
|
file_entry_free (fe);
|
|
g_free (full_name);
|
|
|
|
if (!v)
|
|
return FALSE;
|
|
|
|
if (is_mounted && mount)
|
|
return FALSE;
|
|
|
|
if (!is_mounted && !mount)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
check_mount_func (WPanel *panel, DesktopIconInfo *dii)
|
|
{
|
|
if (!dii)
|
|
return FALSE;
|
|
|
|
return check_mount_umount (dii, TRUE);
|
|
}
|
|
|
|
static gboolean
|
|
check_unmount_func (WPanel *panel, DesktopIconInfo *dii)
|
|
{
|
|
if (!dii)
|
|
return FALSE;
|
|
|
|
return check_mount_umount (dii, FALSE);
|
|
}
|
|
|
|
static gboolean
|
|
check_eject_func (WPanel *panel, DesktopIconInfo *dii)
|
|
{
|
|
char *full_name;
|
|
file_entry *fe;
|
|
int v;
|
|
int is_mounted;
|
|
int retval;
|
|
|
|
if (!dii)
|
|
return FALSE;
|
|
|
|
full_name = g_concat_dir_and_file (desktop_directory, dii->filename);
|
|
fe = file_entry_from_file (full_name);
|
|
if (!fe) {
|
|
g_free (full_name);
|
|
return FALSE;
|
|
}
|
|
|
|
v = is_mountable (full_name, fe, &is_mounted, NULL);
|
|
file_entry_free (fe);
|
|
|
|
if (!v)
|
|
retval = FALSE;
|
|
else if (!is_ejectable (full_name))
|
|
retval = FALSE;
|
|
else
|
|
retval = TRUE;
|
|
|
|
g_free (full_name);
|
|
return retval;
|
|
}
|
|
|
|
static gboolean
|
|
check_edit_func (WPanel *panel, DesktopIconInfo *dii)
|
|
{
|
|
/* As far as I can tell, by looking at gactions.c, edit will _ALWAYS work */
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
check_view_func (WPanel *panel, DesktopIconInfo *dii)
|
|
{
|
|
gchar *full_name;
|
|
if (is_a_desktop_panel (panel)) {
|
|
g_assert (dii != NULL);
|
|
full_name = g_concat_dir_and_file (panel->cwd, dii->filename);
|
|
} else
|
|
full_name = g_concat_dir_and_file (panel->cwd, panel->dir.list[panel->selected].fname);
|
|
|
|
return gmc_can_view_file (full_name);
|
|
}
|
|
|
|
/* global vars */
|
|
extern int we_can_afford_the_speed;
|
|
|
|
static struct action file_actions[] = {
|
|
{ N_("Open"), F_NOTDEV | F_SINGLE, handle_open, NULL },
|
|
{ N_("Mount device"), F_ALL | F_SINGLE, handle_mount, check_mount_func },
|
|
{ N_("Unmount device"), F_ALL | F_SINGLE, handle_unmount, check_unmount_func },
|
|
{ N_("Eject device"), F_ALL | F_SINGLE, handle_eject, check_eject_func },
|
|
{ "", F_NOTDEV | F_SINGLE, NULL, NULL },
|
|
{ "", F_MIME_ACTIONS | F_SINGLE, NULL, NULL },
|
|
{ N_("Open with..."), F_REGULAR | F_SINGLE, handle_open_with, NULL },
|
|
{ N_("View"), F_REGULAR | F_SINGLE, handle_view, check_view_func },
|
|
{ N_("View Unfiltered"), F_REGULAR | F_ADVANCED | F_SINGLE, handle_view_unfiltered, NULL },
|
|
{ N_("Edit"), F_REGULAR | F_SINGLE, handle_edit, check_edit_func },
|
|
{ "", F_REGULAR | F_SINGLE, NULL, NULL },
|
|
{ N_("Copy..."), F_ALL, handle_copy, NULL },
|
|
{ N_("Delete"), F_ALL, handle_delete, NULL },
|
|
{ N_("Move..."), F_ALL, handle_move, NULL },
|
|
{ N_("Hard Link..."), F_ADVANCED | F_SINGLE, handle_hard_link, NULL },
|
|
{ N_("Symlink..."), F_SINGLE, handle_symlink, NULL },
|
|
{ N_("Edit Symlink..."), F_SYMLINK | F_SINGLE, handle_edit_symlink, NULL },
|
|
{ "", F_SINGLE | F_ALL, NULL, NULL },
|
|
{ N_("Properties..."), F_SINGLE | F_ALL, handle_properties, NULL },
|
|
{ NULL, 0, NULL, NULL }
|
|
};
|
|
|
|
/* 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, WPanel *panel);
|
|
|
|
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);
|
|
}
|
|
|
|
/* Convenience function to free something when an object is destroyed */
|
|
static void
|
|
free_on_destroy (GtkObject *object, gpointer data)
|
|
{
|
|
g_free (data);
|
|
}
|
|
|
|
/* Callback for MIME-based actions */
|
|
static void
|
|
mime_action_callback (GtkWidget *widget, gpointer data)
|
|
{
|
|
char *filename;
|
|
char *key, *buf;
|
|
const char *mime_type;
|
|
const char *value;
|
|
int needs_terminal = 0;
|
|
int size;
|
|
|
|
filename = data;
|
|
key = gtk_object_get_user_data (GTK_OBJECT (widget));
|
|
|
|
g_assert (filename != NULL);
|
|
g_assert (key != NULL);
|
|
|
|
mime_type = gnome_mime_type_or_default (filename, NULL);
|
|
g_assert (mime_type != NULL);
|
|
|
|
/*
|
|
* Find out if we need to run this in a terminal
|
|
*/
|
|
if (gnome_metadata_get (filename, "flags", &size, &buf) == 0){
|
|
needs_terminal = strstr (buf, "needsterminal") != 0;
|
|
g_free (buf);
|
|
} else {
|
|
char *flag_key;
|
|
const char *flags;
|
|
|
|
flag_key = g_strconcat ("flags.", key, "flags", NULL);
|
|
flags = gnome_mime_get_value (filename, flag_key);
|
|
g_free (flag_key);
|
|
if (flags)
|
|
needs_terminal = strstr (flags, "needsterminal") != 0;
|
|
}
|
|
|
|
value = gnome_mime_get_value (mime_type, key);
|
|
exec_extension (filename, value, NULL, NULL, 0, needs_terminal);
|
|
}
|
|
|
|
/* Creates the menu items for actions based on the MIME type of the selected
|
|
* file in the panel.
|
|
*/
|
|
static int
|
|
create_mime_actions (GtkWidget *menu, WPanel *panel, int pos, DesktopIconInfo *dii)
|
|
{
|
|
char *full_name;
|
|
const char *mime_type;
|
|
GList *keys, *l;
|
|
gint pos_init = pos;
|
|
GnomeUIInfo uiinfo[] = {
|
|
{ 0 },
|
|
GNOMEUIINFO_END
|
|
};
|
|
|
|
if (is_a_desktop_panel (panel)) {
|
|
g_assert (dii != NULL);
|
|
full_name = g_concat_dir_and_file (panel->cwd, dii->filename);
|
|
} else
|
|
full_name = g_concat_dir_and_file (panel->cwd,
|
|
panel->dir.list[panel->selected].fname);
|
|
mime_type = gnome_mime_type_or_default (full_name, NULL);
|
|
g_free (full_name);
|
|
|
|
if (!mime_type)
|
|
return pos;
|
|
|
|
keys = gnome_mime_get_keys (mime_type);
|
|
for (l = keys; l; l = l->next) {
|
|
char *key;
|
|
char *str;
|
|
|
|
str = key = l->data;
|
|
|
|
if (strncmp (key, "open.", 5) != 0)
|
|
continue;
|
|
|
|
str += 5;
|
|
while (*str && *str != '.')
|
|
str++;
|
|
|
|
if (*str)
|
|
str++;
|
|
|
|
if (!*str)
|
|
continue;
|
|
|
|
/* Create the item for that entry */
|
|
|
|
uiinfo[0].type = GNOME_APP_UI_ITEM;
|
|
uiinfo[0].label = str;
|
|
uiinfo[0].hint = NULL;
|
|
uiinfo[0].moreinfo = mime_action_callback;
|
|
uiinfo[0].user_data = full_name;
|
|
uiinfo[0].unused_data = NULL;
|
|
uiinfo[0].pixmap_type = GNOME_APP_PIXMAP_NONE;
|
|
uiinfo[0].pixmap_info = NULL;
|
|
uiinfo[0].accelerator_key = 0;
|
|
uiinfo[0].ac_mods = 0;
|
|
uiinfo[0].widget = NULL;
|
|
|
|
fill_menu (GTK_MENU_SHELL (menu), uiinfo, pos++);
|
|
gtk_object_set_user_data (GTK_OBJECT (uiinfo[0].widget), key);
|
|
|
|
/* Remember to free this memory */
|
|
|
|
gtk_signal_connect (GTK_OBJECT (uiinfo[0].widget), "destroy",
|
|
(GtkSignalFunc) free_on_destroy,
|
|
full_name);
|
|
}
|
|
if (pos_init != pos) {
|
|
uiinfo[0].type = GNOME_APP_UI_SEPARATOR;
|
|
fill_menu (GTK_MENU_SHELL (menu), uiinfo, pos++);
|
|
g_list_free (keys);
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
/* Creates the menu items for the standard actions. Returns the position at
|
|
* which additional menu items should be inserted.
|
|
*/
|
|
static void
|
|
create_actions (GtkWidget *menu, gint flags, WPanel *panel, DesktopIconInfo *dii)
|
|
{
|
|
struct action *action;
|
|
int pos;
|
|
GnomeUIInfo uiinfo[] = {
|
|
{ 0 },
|
|
GNOMEUIINFO_END
|
|
};
|
|
|
|
pos = 0;
|
|
|
|
for (action = file_actions; action->text; action++) {
|
|
/* Insert the MIME actions if appropriate */
|
|
if ((action->flags & F_MIME_ACTIONS) && (flags & F_SINGLE)) {
|
|
pos = create_mime_actions (menu, panel, pos, dii);
|
|
continue;
|
|
}
|
|
|
|
/* Filter the actions that are not appropriate */
|
|
if ((action->flags & flags) != action->flags)
|
|
continue;
|
|
|
|
if (action->func && !((action->func)(panel, dii)))
|
|
continue;
|
|
|
|
/* Create the menu item for this action */
|
|
if (action->text[0]) {
|
|
uiinfo[0].type = GNOME_APP_UI_ITEM;
|
|
uiinfo[0].label = _(action->text);
|
|
uiinfo[0].hint = NULL;
|
|
uiinfo[0].moreinfo = action->callback;
|
|
uiinfo[0].user_data = (gpointer) panel;
|
|
uiinfo[0].unused_data = NULL;
|
|
uiinfo[0].pixmap_type = GNOME_APP_PIXMAP_NONE;
|
|
uiinfo[0].pixmap_info = NULL;
|
|
uiinfo[0].accelerator_key = 0;
|
|
uiinfo[0].ac_mods = 0;
|
|
uiinfo[0].widget = NULL;
|
|
} else
|
|
uiinfo[0].type = GNOME_APP_UI_SEPARATOR;
|
|
|
|
fill_menu (GTK_MENU_SHELL (menu), uiinfo, pos++);
|
|
}
|
|
}
|
|
|
|
/* Convenience callback to exit the main loop of a modal popup menu when it is deactivated*/
|
|
static void
|
|
menu_shell_deactivated (GtkMenuShell *menu_shell, WPanel *panel)
|
|
{
|
|
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;
|
|
}
|
|
|
|
#define REMOVE(x,f) x &= ~f
|
|
|
|
int
|
|
gpopup_do_popup2 (GdkEventButton *event, WPanel *panel, DesktopIconInfo *dii)
|
|
{
|
|
GtkWidget *menu;
|
|
gint flags = F_ALL | F_REGULAR | F_SYMLINK | F_SINGLE | F_NOTDEV | F_NOTDIR;
|
|
struct stat s;
|
|
guint id;
|
|
int i;
|
|
int marked;
|
|
|
|
g_return_val_if_fail (event != NULL, -1);
|
|
g_return_val_if_fail (panel != NULL, -1);
|
|
|
|
menu = gtk_menu_new ();
|
|
|
|
/* 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);
|
|
|
|
marked = 0;
|
|
|
|
for (i = 0; i < panel->count; i++) {
|
|
if (!strcmp (panel->dir.list [i].fname, "..") || !panel->dir.list[i].f.marked)
|
|
continue;
|
|
|
|
marked++;
|
|
|
|
s = panel->dir.list[i].buf;
|
|
|
|
if (S_ISLNK (s.st_mode))
|
|
mc_stat (panel->dir.list [i].fname, &s);
|
|
else
|
|
REMOVE (flags, F_SYMLINK);
|
|
|
|
if (S_ISDIR (s.st_mode))
|
|
REMOVE (flags, F_NOTDIR);
|
|
|
|
if (!S_ISREG (s.st_mode))
|
|
REMOVE (flags, F_REGULAR);
|
|
|
|
if (S_ISCHR (s.st_mode) || S_ISBLK (s.st_mode))
|
|
REMOVE (flags, F_NOTDEV);
|
|
}
|
|
|
|
g_assert (marked > 0);
|
|
|
|
if (marked > 1)
|
|
REMOVE (flags, F_SINGLE);
|
|
|
|
/* Fill the menu */
|
|
create_actions (menu, flags, panel, dii);
|
|
|
|
/* Run it */
|
|
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button, event->time);
|
|
gtk_grab_add (menu);
|
|
gtk_main ();
|
|
gtk_grab_remove (menu);
|
|
|
|
gtk_signal_disconnect (GTK_OBJECT (menu), id);
|
|
|
|
i = get_active_index (GTK_MENU (menu));
|
|
gtk_widget_unref (menu);
|
|
return i;
|
|
}
|
|
|
|
static void
|
|
handle_open (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
gchar *full_name;
|
|
DesktopIconInfo *dii;
|
|
|
|
full_name = get_full_filename (panel);
|
|
|
|
if (is_a_desktop_panel (panel)) {
|
|
dii = desktop_icon_info_get_by_filename (x_basename (full_name));
|
|
g_assert (dii != NULL);
|
|
g_free (full_name);
|
|
desktop_icon_info_open (dii);
|
|
return;
|
|
}
|
|
|
|
if (gmc_open_filename (full_name, 0))
|
|
return;
|
|
gmc_open_with (full_name);
|
|
g_free (full_name);
|
|
}
|
|
|
|
static void
|
|
handle_mount (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
char *full_name;
|
|
|
|
g_assert (is_a_desktop_panel (panel));
|
|
|
|
full_name = get_full_filename (panel);
|
|
do_mount_umount (full_name, TRUE);
|
|
g_free (full_name);
|
|
}
|
|
|
|
static void
|
|
handle_unmount (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
char *full_name;
|
|
|
|
g_assert (is_a_desktop_panel (panel));
|
|
|
|
full_name = get_full_filename (panel);
|
|
do_mount_umount (full_name, FALSE);
|
|
g_free (full_name);
|
|
}
|
|
|
|
static void
|
|
handle_eject (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
char *full_name;
|
|
char *lname;
|
|
|
|
g_assert (is_a_desktop_panel (panel));
|
|
|
|
full_name = get_full_filename (panel);
|
|
lname = g_readlink (full_name);
|
|
if (!lname){
|
|
g_free (full_name);
|
|
return;
|
|
}
|
|
|
|
if (is_block_device_mounted (lname))
|
|
do_mount_umount (full_name, FALSE);
|
|
|
|
do_eject (lname);
|
|
|
|
g_free (lname);
|
|
g_free (full_name);
|
|
}
|
|
|
|
static void
|
|
handle_view (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
gchar *full_name;
|
|
|
|
full_name = get_full_filename (panel);
|
|
gmc_view (full_name, 0);
|
|
g_free (full_name);
|
|
}
|
|
|
|
static void
|
|
handle_view_unfiltered (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
/* We need it to do the right thing later. */
|
|
/*view_simple_cmd (panel);*/
|
|
return;
|
|
}
|
|
|
|
static void
|
|
handle_edit (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
gchar *full_name;
|
|
|
|
full_name = get_full_filename (panel);
|
|
gmc_edit (full_name);
|
|
g_free (full_name);
|
|
}
|
|
|
|
static void
|
|
handle_copy (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
copy_cmd ();
|
|
}
|
|
|
|
static void
|
|
handle_delete (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
delete_cmd ();
|
|
}
|
|
|
|
static void
|
|
handle_move (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
ren_cmd ();
|
|
}
|
|
|
|
/* F_SINGLE file commands */
|
|
static void
|
|
handle_properties (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
gint retval = 0;
|
|
GtkWidget *dialog;
|
|
gchar *full_name = NULL;
|
|
|
|
full_name = get_full_filename (panel);
|
|
dialog = gnome_file_property_dialog_new (full_name,
|
|
(is_a_desktop_panel (panel)
|
|
? TRUE
|
|
: we_can_afford_the_speed));
|
|
|
|
if (!is_a_desktop_panel (panel))
|
|
gnome_dialog_set_parent (GNOME_DIALOG (dialog), GTK_WINDOW (panel->xwindow));
|
|
|
|
if (gnome_dialog_run (GNOME_DIALOG (dialog)) == 0)
|
|
retval = gnome_file_property_dialog_make_changes (
|
|
GNOME_FILE_PROPERTY_DIALOG (dialog));
|
|
|
|
gtk_widget_destroy (dialog);
|
|
g_free (full_name);
|
|
if (retval && !is_a_desktop_panel (panel))
|
|
reread_cmd ();
|
|
}
|
|
|
|
static void
|
|
handle_open_with (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
gchar *full_name;
|
|
full_name = get_full_filename (panel);
|
|
gmc_open_with (full_name);
|
|
g_free (full_name);
|
|
}
|
|
|
|
static void
|
|
handle_hard_link (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
/* yeah right d: -jrb */
|
|
link_cmd ();
|
|
}
|
|
|
|
static void
|
|
handle_symlink (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
symlink_cmd ();
|
|
}
|
|
|
|
static void
|
|
handle_edit_symlink (GtkWidget *widget, WPanel *panel)
|
|
{
|
|
edit_symlink_cmd ();
|
|
}
|
|
|