mc/gnome/gnome-file-property-dialog.c

1396 lines
44 KiB
C
Raw Normal View History

/* gnome-file-property-dialog.c
1999-03-10 Federico Mena Quintero <federico@nuclecu.unam.mx> This is a semi-big slew of changes to integrate the DESKTOP_BRANCH into the main trunk. Now the gdesktop code creates a temprary WPanel structure and passes it on to the core file management functions. Also, the menu code is improved (we now use gpopup2; gpopup should go away shortly and gpopup2 should replace it). This makes the desktop act consistently with the file panels. Thanks to Jonathan for his help with this branch. * gdnd.c (perform_action): Use mc_lstat(), not mc_stat(). * glayout.c (update_panels): Do not update the panels that are desktop panels. * gdesktop.c (icon_is_in_area): An icon is not considered to be in a 0x0 area. * gpopup2.c (handle_open): Fetch the desktop icon from the filename and call desktop_icon_info_open(). * gdesktop.c (desktop_icon_info_get_by_filename): New function to look up a desktop icon by its filename. * glayout.c (create_new_menu_from): Test for the ".desktop" suffix correctly. * gpopup2.c (handle_properties): If the file comes from a desktop panel, always allow edition of the icon image. 1999-03-10 Federico Mena Quintero <federico@nuclecu.unam.mx> * file.c (erase_dir): Erase metadata for directories as well. (erase_dir_iff_empty): Likewise. (copy_file_file): Delete/copy the metadata even for char/block/sock/fifo files. Same thing for when copying symlinks. (copy_dir_dir): Delete/copy the metadata. (move_dir_dir): Delete/move the metadata. (recursive_erase): Delete the metadata.
1999-03-11 05:40:53 +03:00
* Copyright (C) 1999 Free Software Foundation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include "dir.h"
#include "util.h"
#include <gnome.h>
#include <time.h>
#include <string.h>
#include "gnome-file-property-dialog.h"
#include "gdesktop.h"
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "fileopctx.h"
#include "file.h"
#include "../vfs/vfs.h"
#include "gicon.h"
#include "dialog.h"
static void gnome_file_property_dialog_init (GnomeFilePropertyDialog *file_property_dialog);
static void gnome_file_property_dialog_class_init (GnomeFilePropertyDialogClass *klass);
static void gnome_file_property_dialog_finalize (GtkObject *object);
static GnomeDialogClass *parent_class = NULL;
GtkType
gnome_file_property_dialog_get_type (void)
{
static GtkType file_property_dialog_type = 0;
if (!file_property_dialog_type)
{
static const GtkTypeInfo file_property_dialog_info =
{
"GnomeFilePropertyDialog",
sizeof (GnomeFilePropertyDialog),
sizeof (GnomeFilePropertyDialogClass),
(GtkClassInitFunc) gnome_file_property_dialog_class_init,
(GtkObjectInitFunc) gnome_file_property_dialog_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
};
file_property_dialog_type = gtk_type_unique (gnome_dialog_get_type (), &file_property_dialog_info);
}
return file_property_dialog_type;
}
static void
gnome_file_property_dialog_class_init (GnomeFilePropertyDialogClass *klass)
{
GtkObjectClass *object_class;
object_class = (GtkObjectClass*) klass;
parent_class = gtk_type_class (gnome_dialog_get_type ());
object_class->finalize = gnome_file_property_dialog_finalize;
}
static void
gnome_file_property_dialog_init (GnomeFilePropertyDialog *file_property_dialog)
{
gnome_dialog_close_hides (GNOME_DIALOG (file_property_dialog), TRUE);
file_property_dialog->file_name = NULL;
file_property_dialog->file_entry = NULL;
file_property_dialog->group_name = NULL;
file_property_dialog->modifyable = TRUE;
file_property_dialog->user_name = NULL;
file_property_dialog->prop1_label = NULL;
file_property_dialog->prop2_label = NULL;
file_property_dialog->prop1_entry = NULL;
file_property_dialog->prop2_entry = NULL;
file_property_dialog->prop1_cbox = NULL;
file_property_dialog->prop2_cbox = NULL;
file_property_dialog->fm_open = NULL;
file_property_dialog->fm_view = NULL;
file_property_dialog->edit = NULL;
file_property_dialog->drop_target = NULL;
file_property_dialog->im = NULL;
}
static void
gnome_file_property_dialog_finalize (GtkObject *object)
{
GnomeFilePropertyDialog *gfpd;
g_return_if_fail (object != NULL);
g_return_if_fail (GNOME_IS_FILE_PROPERTY_DIALOG (object));
gfpd = GNOME_FILE_PROPERTY_DIALOG (object);
if (gfpd->file_name)
g_free (gfpd->file_name);
if (gfpd->fm_open)
g_free (gfpd->fm_open);
if (gfpd->fm_view)
g_free (gfpd->fm_view);
if (gfpd->edit)
g_free (gfpd->edit);
if (gfpd->drop_target)
g_free (gfpd->drop_target);
if (gfpd->icon_filename)
g_free (gfpd->icon_filename);
if (gfpd->desktop_url)
g_free (gfpd->desktop_url);
if (gfpd->caption)
g_free (gfpd->caption);
1999-02-23 19:39:00 +03:00
if (gfpd->mode_name)
g_free (gfpd->mode_name);
(* GTK_OBJECT_CLASS (parent_class)->finalize) (object);
}
/* Create the pane */
static GtkWidget *
create_general_properties (GnomeFilePropertyDialog *fp_dlg)
{
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *align;
gchar *direc;
gchar *gen_string;
gchar buf[MC_MAXPATHLEN];
gchar buf2[MC_MAXPATHLEN];
file_entry *fe;
GtkWidget *icon;
struct tm *time;
GtkWidget *table;
int n;
vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
gtk_container_set_border_width (GTK_CONTAINER (vbox), GNOME_PAD);
/* first, we set the icon */
direc = g_strdup (fp_dlg->file_name);
strrchr (direc, '/')[0] = '\0';
fe = file_entry_from_file (fp_dlg->file_name);
fp_dlg->im = gicon_get_icon_for_file (direc, fe, FALSE);
file_entry_free (fe);
g_free (direc);
icon = gnome_pixmap_new_from_imlib (fp_dlg->im);
gtk_box_pack_start (GTK_BOX (vbox), icon, FALSE, FALSE, 0);
/* we set the file part */
gen_string = g_strconcat (_("Full Name: "), fp_dlg->file_name, NULL);
label = gtk_label_new (gen_string);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
g_free (gen_string);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
/* if it's a symlink */
align = gtk_alignment_new (0.0, 0.5, 1.0, 1.0);
hbox = gtk_hbox_new (FALSE, 2);
label = gtk_label_new (_("File Name"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
fp_dlg->file_entry = gtk_entry_new ();
gen_string = strrchr (fp_dlg->file_name, '/');
if (gen_string)
gtk_entry_set_text (GTK_ENTRY (fp_dlg->file_entry), gen_string + 1);
else
/* I don't think this should happen anymore, but it can't hurt in
* case this ever gets used outside gmc */
gtk_entry_set_text (GTK_ENTRY (fp_dlg->file_entry), fp_dlg->file_name);
/* We want to prevent editing of the file if
* the thing is a BLK, CHAR, or we don't own it */
/* FIXME: We can actually edit it if we're in the same grp of the file. */
if (fp_dlg->modifyable == FALSE)
gtk_widget_set_sensitive (fp_dlg->file_entry, FALSE);
gtk_box_pack_start (GTK_BOX (hbox), fp_dlg->file_entry, FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (align), hbox);
gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, FALSE, 8);
/* File statistics */
/* File type first */
if (S_ISREG (fp_dlg->st.st_mode)) {
gen_string = g_strconcat (_("File Type: "),
gnome_mime_type (fp_dlg->file_name),
NULL);
label = gtk_label_new (gen_string);
g_free (gen_string);
} else if (S_ISLNK (fp_dlg->st.st_mode)) {
label = gtk_label_new (_("File Type: Symbolic Link"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
n = mc_readlink (fp_dlg->file_name, buf, MC_MAXPATHLEN);
if (n < 0)
label = gtk_label_new (_("Target Name: INVALID LINK"));
else {
buf [n] = 0;
gen_string = g_strconcat (_("Target Name: "), buf, NULL);
label = gtk_label_new (gen_string);
g_free (gen_string);
}
}else if (S_ISDIR (fp_dlg->st.st_mode))
label = gtk_label_new (_("File Type: Directory"));
else if (S_ISCHR (fp_dlg->st.st_mode))
label = gtk_label_new (_("File Type: Character Device"));
else if (S_ISBLK (fp_dlg->st.st_mode))
label = gtk_label_new (_("File Type: Block Device"));
else if (S_ISSOCK (fp_dlg->st.st_mode))
label = gtk_label_new (_("File Type: Socket"));
else if (S_ISFIFO (fp_dlg->st.st_mode))
label = gtk_label_new (_("File Type: FIFO"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
/* Now file size */
if (S_ISDIR (fp_dlg->st.st_mode)
|| S_ISREG (fp_dlg->st.st_mode)
|| S_ISLNK (fp_dlg->st.st_mode)) {
if ((gint)fp_dlg->st.st_size < 1024) {
snprintf (buf, MC_MAXPATHLEN, "%d", (gint) fp_dlg->st.st_size);
gen_string = g_strconcat (_("File Size: "), buf, _(" bytes"), NULL);
} else if ((gint)fp_dlg->st.st_size < 1024 * 1024) {
snprintf (buf, MC_MAXPATHLEN, "%.1f", (gfloat) fp_dlg->st.st_size / 1024.0);
snprintf (buf2, MC_MAXPATHLEN, "%d", (gint) fp_dlg->st.st_size);
gen_string = g_strconcat (_("File Size: "), buf, _(" KBytes ("),
buf2, _(" bytes)"), NULL);
} else {
snprintf (buf, MC_MAXPATHLEN, "%.1f",
(gfloat) fp_dlg->st.st_size / (1024.0 * 1024.0));
snprintf (buf2, MC_MAXPATHLEN, "%d", (gint) fp_dlg->st.st_size);
gen_string = g_strconcat (_("File Size: "), buf, _(" MBytes ("),
buf2, _(" bytes)"), NULL);
}
label = gtk_label_new (gen_string);
g_free (gen_string);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
} else {
label = gtk_label_new (_("File Size: N/A"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
}
gtk_box_pack_start (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, FALSE, 8);
/* Time Fields */
table = gtk_table_new (3, 2, FALSE);
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
label = gtk_label_new (_("File Created on: "));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
time = localtime (&(fp_dlg->st.st_ctime));
strftime (buf, MC_MAXPATHLEN, "%a, %b %d %Y, %I:%M:%S %p", time);
label = gtk_label_new (buf);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 0, 1);
label = gtk_label_new (_("Last Modified on: "));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
time = localtime (&(fp_dlg->st.st_mtime));
strftime (buf, MC_MAXPATHLEN, "%a, %b %d %Y, %I:%M:%S %p", time);
label = gtk_label_new (buf);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 1, 2);
label = gtk_label_new (_("Last Accessed on: "));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
time = localtime (&(fp_dlg->st.st_atime));
strftime (buf, MC_MAXPATHLEN, "%a, %b %d %Y, %I:%M:%S %p", time);
label = gtk_label_new (buf);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 2, 3);
return vbox;
}
static GtkWidget *
create_url_properties (GnomeFilePropertyDialog *fp_dlg)
{
GtkWidget *table, *label;
table = gtk_table_new (0, 0, 0);
label = gtk_label_new (_("URL:"));
gtk_table_attach (GTK_TABLE (table), label,
1, 2, 1, 2, 0, 0, GNOME_PAD, GNOME_PAD);
fp_dlg->desktop_entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), fp_dlg->desktop_entry,
2, 3, 1, 2, GTK_FILL | GTK_EXPAND, 0, GNOME_PAD, GNOME_PAD);
label = gtk_label_new (_("Caption:"));
gtk_table_attach (GTK_TABLE (table), label,
1, 2, 2, 3, 0, 0, GNOME_PAD, GNOME_PAD);
fp_dlg->caption_entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), fp_dlg->caption_entry,
2, 3, 2, 3, GTK_FILL | GTK_EXPAND, 0, GNOME_PAD, GNOME_PAD);
gtk_widget_show_all (table);
return table;
}
/* Settings Pane */
static void
metadata_toggled (GtkWidget *cbox, GnomeFilePropertyDialog *fp_dlg)
{
if (fp_dlg->changing)
return;
if (cbox == fp_dlg->open_cbox) {
if (GTK_TOGGLE_BUTTON (cbox)->active) {
gtk_widget_set_sensitive (fp_dlg->open_entry, FALSE);
if (fp_dlg->mime_fm_open)
gtk_entry_set_text (GTK_ENTRY (fp_dlg->open_entry), fp_dlg->mime_fm_open);
} else {
gtk_widget_set_sensitive (fp_dlg->open_entry, TRUE);
if (fp_dlg->fm_open) {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->open_entry), fp_dlg->fm_open);
}
}
} else if (cbox == fp_dlg->prop1_cbox) {
if (GTK_TOGGLE_BUTTON (cbox)->active) {
gtk_widget_set_sensitive (fp_dlg->prop1_entry, FALSE);
if (fp_dlg->executable && fp_dlg->mime_drop_target) {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->mime_drop_target);
} else if (!fp_dlg->executable && fp_dlg->mime_fm_view) {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->mime_fm_view);
} else {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), "");
}
} else {
gtk_widget_set_sensitive (fp_dlg->prop1_entry, TRUE);
if (fp_dlg->executable && fp_dlg->drop_target) {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->drop_target);
} else if (!fp_dlg->executable && fp_dlg->fm_view) {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->fm_view);
}
}
} else {
if (GTK_TOGGLE_BUTTON (cbox)->active) {
gtk_widget_set_sensitive (fp_dlg->prop2_entry, FALSE);
if (fp_dlg->mime_edit) {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop2_entry), fp_dlg->mime_edit);
} else {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop2_entry), "");
}
} else {
gtk_widget_set_sensitive (fp_dlg->prop2_entry, TRUE);
if (fp_dlg->edit) {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop2_entry), fp_dlg->edit);
}
}
}
}
static void
switch_metadata_box (GnomeFilePropertyDialog *fp_dlg)
{
if (NULL == fp_dlg->prop1_label)
return;
fp_dlg->changing = TRUE;
if (fp_dlg->desktop_url){
gtk_entry_set_text (GTK_ENTRY (fp_dlg->desktop_entry), fp_dlg->desktop_url);
gtk_entry_set_text (GTK_ENTRY (fp_dlg->caption_entry), fp_dlg->caption);
}
if (fp_dlg->executable) {
gtk_label_set_text (GTK_LABEL (fp_dlg->prop1_label), _("Drop Action"));
gtk_label_set_text (GTK_LABEL (GTK_BIN (fp_dlg->prop1_cbox)->child), _("Use default Drop Action options"));
if (fp_dlg->drop_target) {
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop1_cbox), FALSE);
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->drop_target);
gtk_widget_set_sensitive (fp_dlg->prop1_entry, TRUE);
} else if (fp_dlg->mime_drop_target) {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->mime_drop_target);
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop1_cbox), TRUE);
gtk_widget_set_sensitive (fp_dlg->prop1_entry, FALSE);
} else {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), "");
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop1_cbox), TRUE);
gtk_widget_set_sensitive (fp_dlg->prop1_entry, FALSE);
}
} else {
gtk_label_set_text (GTK_LABEL (fp_dlg->prop1_label), _("View"));
gtk_label_set_text (GTK_LABEL (GTK_BIN (fp_dlg->prop1_cbox)->child), _("Use default View options"));
if (fp_dlg->fm_view) {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->fm_view);
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop1_cbox), FALSE);
gtk_widget_set_sensitive (fp_dlg->prop1_entry, TRUE);
} else if (fp_dlg->mime_fm_view) {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->mime_fm_view);
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop1_cbox), TRUE);
gtk_widget_set_sensitive (fp_dlg->prop1_entry, FALSE);
} else {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), "");
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop1_cbox), TRUE);
gtk_widget_set_sensitive (fp_dlg->prop1_entry, FALSE);
}
}
if (fp_dlg->executable) {
gtk_widget_hide (fp_dlg->prop2_label);
gtk_widget_hide (fp_dlg->prop2_entry);
gtk_widget_hide (fp_dlg->prop2_cbox);
gtk_widget_hide (fp_dlg->prop2_hline);
} else {
gtk_widget_show (fp_dlg->prop2_label);
gtk_widget_show (fp_dlg->prop2_entry);
gtk_widget_show (fp_dlg->prop2_cbox);
gtk_widget_show (fp_dlg->prop2_hline);
}
fp_dlg->changing = FALSE;
}
static GtkWidget *
generate_icon_sel (GnomeFilePropertyDialog *fp_dlg)
{
GtkWidget *retval;
These are a bunch of changes to fix CORBA and session management. They are almost complete (i.e. to handle all nitty gritty cases), but they seem to be working OK right now. SM should be much more stable now. Please tell me if you find any weird behavior - Federico 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * gdesktop-icon.c (desktop_icon_realize): Remove the WM_CLIENT_LEADER property from icon windows so that window managers will not store SM information for them. * gnome-open-dialog.c: Added missing #includes. * gdesktop-init.c (desktop_init_at): Removed an unused variable. * gdesktop.h: Added some missing prototypes. * gmain.h: Added some missing prototypes. * Makefile.in: Added gsession.[ch] to the list of sources. * gmain.c (create_panels): Consider whether we have a CORBA server and session management. * gdesktop.c: #include "gdesktop-init.h" * gdesktop.c: Added a missing cast to GNOME_DIALOG. * gmain.c (create_panels): Removed the run_desktop global variable. * glayout.c (create_container): Set the wmclass of the panel to include its unique ID. * gsession.[ch]: New file with the functions that deal with session management. * glayout.c (gnome_exit): Use session_set_restart(). * gcorba.c (corba_init): Now returns an int with an error value. (corba_init_server): Initialize the server properly. Fixed all the object implementation code. (corba_create_window): New function used to create a window with the CORBA server. * gmain.c (gnome_check_super_user): Now the check for running as root is done here. There should be no GUI code in src/. 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * dlg.c (dlg_run_done): Do not call the callback of a NULL current widget. * setup.h: Added missing prototype for setup_init(). * filegui.c (check_progress_buttons): Added a missing return value. * dlg.c (remove_widget): Added a missing return value. * main.c: Removed the global directory_list variable. Removed the main_corba_register_server() function. * main.h: Removed the global run_desktop variable. * panel.h: Now the panel structure has a unique numerical ID used for session management. * screen.c (panel_new): Maintain a unique ID for each panel. * main.c (maybe_display_linksdir): Handle display of the desktop init dir here. (main): Call gnome_check_super_user(). (init_corba_with_args): Call corba_init_server(). * main.c (init_corba_with_args): Do CORBA initialization here. Also removed the global force_activation option. 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * vfs.c (vfs_add_current_stamps): Only do stamping of the panels if they exist. * mcserv.c: #include <sys/wait.h> (get_client): Put `#ifdef __EMX__' around an otherwise-unused variable. * utilvfs.c (vfs_split_url): Fix NULL <-> 0 confusion when comparing characters. * ftpfs.c (retrieve_dir): Removed unused variable dot_dot_found. * extfs.c (extfs_init): Assign `key' to c, not `&key'.
1999-03-30 10:09:56 +04:00
gchar *icon;
retval = gnome_icon_entry_new ("gmc_file_icon", _("Select an Icon"));
icon = g_strdup (gicon_get_filename_for_icon (fp_dlg->im));
if (icon == NULL)
return retval;
gnome_icon_entry_set_icon (GNOME_ICON_ENTRY (retval), icon);
fp_dlg->icon_filename = icon;
return retval;
}
static GtkWidget *
generate_actions_box (GnomeFilePropertyDialog *fp_dlg)
{
GtkWidget *vbox;
GtkWidget *table;
/* Here's the Logic: */
/* All tops of files (other then folders) should let us edit "open" */
/* If we are a file, and an executable, we want to edit our "drop-action" */
/* Metadata, as it is meaningful to us. */
/* If we are non-executable, we want to edit our "edit" and "view" fields. */
/* Sym links want to have the same options as above, but use their Target's */
/* Executable/set bit in order to determine which one. */
/* Note, symlinks can set their own metadata, independent from their */
/* targets. */
table = gtk_table_new (8, 2, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (table), GNOME_PAD_SMALL);
/* we do open first */
fp_dlg->open_label = gtk_label_new (_("Open"));
gtk_misc_set_alignment (GTK_MISC (fp_dlg->open_label), 0.0, 0.5);
gtk_misc_set_padding (GTK_MISC (fp_dlg->open_label), 2, 0);
gtk_table_attach_defaults (GTK_TABLE (table),
fp_dlg->open_label,
0, 1, 0, 1);
fp_dlg->open_entry = gtk_entry_new ();
gtk_table_attach_defaults (GTK_TABLE (table),
fp_dlg->open_entry,
1, 2, 0, 1);
fp_dlg->open_cbox = gtk_check_button_new_with_label (_("Use default Open action"));
gtk_signal_connect (GTK_OBJECT (fp_dlg->open_cbox), "toggled", metadata_toggled, fp_dlg);
gtk_table_attach_defaults (GTK_TABLE (table), fp_dlg->open_cbox, 0, 2, 1, 2);
vbox = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, FALSE, GNOME_PAD_SMALL);
gtk_table_attach_defaults (GTK_TABLE (table), vbox, 0, 2, 2, 3);
if (fp_dlg->executable)
fp_dlg->prop1_label = gtk_label_new (_("Drop Action"));
else
fp_dlg->prop1_label = gtk_label_new (_("View"));
gtk_misc_set_alignment (GTK_MISC (fp_dlg->prop1_label), 0.0, 0.5);
gtk_misc_set_padding (GTK_MISC (fp_dlg->prop1_label), 2, 0);
gtk_table_attach_defaults (GTK_TABLE (table),
fp_dlg->prop1_label,
0, 1, 3, 4);
fp_dlg->prop1_entry = gtk_entry_new ();
gtk_table_attach_defaults (GTK_TABLE (table),
fp_dlg->prop1_entry,
1, 2, 3, 4);
if (fp_dlg->executable)
fp_dlg->prop1_cbox = gtk_check_button_new_with_label (_("Use default Drop action"));
else
fp_dlg->prop1_cbox = gtk_check_button_new_with_label (_("Use default View action"));
gtk_signal_connect (GTK_OBJECT (fp_dlg->prop1_cbox), "toggled", metadata_toggled, fp_dlg);
gtk_table_attach_defaults (GTK_TABLE (table), fp_dlg->prop1_cbox, 0, 2, 4, 5);
vbox = gtk_vbox_new (FALSE, 0);
fp_dlg->prop2_hline = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (vbox), fp_dlg->prop2_hline, FALSE, FALSE, GNOME_PAD_SMALL);
gtk_table_attach_defaults (GTK_TABLE (table), vbox, 0, 2, 5, 6);
fp_dlg->prop2_label = gtk_label_new (_("Edit"));
gtk_misc_set_alignment (GTK_MISC (fp_dlg->prop2_label), 0.0, 0.5);
gtk_misc_set_padding (GTK_MISC (fp_dlg->prop2_label), 2, 0);
gtk_table_attach_defaults (GTK_TABLE (table),
fp_dlg->prop2_label,
0, 1, 6, 7);
fp_dlg->prop2_entry = gtk_entry_new ();
gtk_table_attach_defaults (GTK_TABLE (table),
fp_dlg->prop2_entry,
1, 2, 6, 7);
fp_dlg->prop2_cbox = gtk_check_button_new_with_label (_("Use default Edit action"));
gtk_signal_connect (GTK_OBJECT (fp_dlg->prop2_cbox), "toggled", metadata_toggled, fp_dlg);
gtk_table_attach_defaults (GTK_TABLE (table), fp_dlg->prop2_cbox, 0, 2, 7, 8);
/* we set the open field */
fp_dlg->changing = TRUE;
if (fp_dlg->fm_open) {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->open_entry), fp_dlg->fm_open);
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->open_cbox), FALSE);
gtk_widget_set_sensitive (fp_dlg->open_entry, TRUE);
} else if (fp_dlg->mime_fm_open) {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->open_entry), fp_dlg->mime_fm_open);
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->open_cbox), TRUE);
gtk_widget_set_sensitive (fp_dlg->open_entry, FALSE);
} else {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->open_entry), "");
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->open_cbox), TRUE);
gtk_widget_set_sensitive (fp_dlg->open_entry, FALSE);
}
if (fp_dlg->edit) {
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop2_cbox), FALSE);
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop2_entry), fp_dlg->edit);
gtk_widget_set_sensitive (fp_dlg->prop2_entry, TRUE);
} else if (fp_dlg->mime_edit) {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop2_entry), fp_dlg->mime_edit);
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop2_cbox), TRUE);
gtk_widget_set_sensitive (fp_dlg->prop2_entry, FALSE);
} else {
gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop2_entry), "");
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop2_cbox), TRUE);
gtk_widget_set_sensitive (fp_dlg->prop2_entry, FALSE);
}
fp_dlg->changing = FALSE;
return table;
}
static GtkWidget *
create_settings_pane (GnomeFilePropertyDialog *fp_dlg)
{
GtkWidget *vbox = NULL;
GtkWidget *hbox;
GtkWidget *vbox2;
GtkWidget *frame;
GtkWidget *align;
GtkWidget *table;
struct stat linkstat;
int finish;
vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
gtk_container_set_border_width (GTK_CONTAINER (vbox), GNOME_PAD);
if (fp_dlg->can_set_icon) {
frame = gtk_frame_new (_("Icon"));
vbox2 = gtk_vbox_new (FALSE, 0);
hbox = gtk_hbox_new (FALSE, 0);
align = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
fp_dlg->button = generate_icon_sel (fp_dlg);
gtk_container_add (GTK_CONTAINER (frame), vbox2);
gtk_container_set_border_width (GTK_CONTAINER (vbox2), GNOME_PAD_SMALL);
gtk_box_pack_start (GTK_BOX (vbox2), hbox, TRUE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), align, TRUE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (align), fp_dlg->button);
}
/* Are we a directory or device? If so, we do nothing else. */
if (S_ISLNK (fp_dlg->st.st_mode))
mc_stat (fp_dlg->file_name, &linkstat);
finish = 0;
if (!S_ISREG (fp_dlg->st.st_mode)){
if (S_ISLNK (fp_dlg->st.st_mode)){
if (!S_ISREG (linkstat.st_mode))
finish = 1;
} else
finish = 1;
}
if (finish){
if (!fp_dlg->can_set_icon) {
gtk_widget_unref (vbox);
vbox = NULL;
}
return vbox;
}
/* We must be a file or a link to a file. */
frame = gtk_frame_new (_("File Actions"));
gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
table = generate_actions_box (fp_dlg);
gtk_container_add (GTK_CONTAINER (frame), table);
frame = gtk_frame_new (_("Open action"));
fp_dlg->needs_terminal_check = gtk_check_button_new_with_label (_("Needs terminal to run"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fp_dlg->needs_terminal_check),
fp_dlg->needs_terminal);
gtk_container_add (GTK_CONTAINER (frame), fp_dlg->needs_terminal_check);
gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
return vbox;
}
/* Permissions Pane */
static GtkWidget *
label_new (char *text, double xalign, double yalign)
{
GtkWidget *label;
label = gtk_label_new (text);
gtk_misc_set_alignment (GTK_MISC (label), xalign, yalign);
gtk_widget_show (label);
return label;
}
static mode_t
perm_get_umode (GnomeFilePropertyDialog *fp_dlg)
{
mode_t umode;
#define SETBIT(widget, flag) umode |= GTK_TOGGLE_BUTTON (widget)->active ? flag : 0
umode = 0;
SETBIT (fp_dlg->suid, S_ISUID);
SETBIT (fp_dlg->sgid, S_ISGID);
SETBIT (fp_dlg->svtx, S_ISVTX);
SETBIT (fp_dlg->rusr, S_IRUSR);
SETBIT (fp_dlg->wusr, S_IWUSR);
SETBIT (fp_dlg->xusr, S_IXUSR);
SETBIT (fp_dlg->rgrp, S_IRGRP);
SETBIT (fp_dlg->wgrp, S_IWGRP);
SETBIT (fp_dlg->xgrp, S_IXGRP);
SETBIT (fp_dlg->roth, S_IROTH);
SETBIT (fp_dlg->woth, S_IWOTH);
SETBIT (fp_dlg->xoth, S_IXOTH);
return umode;
#undef SETBIT
}
static void
perm_set_mode_label (GtkWidget *widget, gpointer data)
{
GnomeFilePropertyDialog *fp_dlg;
mode_t umode;
char s_mode[5];
fp_dlg = GNOME_FILE_PROPERTY_DIALOG (data);
umode = perm_get_umode (fp_dlg);
if (!fp_dlg->executable && (umode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
fp_dlg->executable = TRUE;
switch_metadata_box (fp_dlg);
} else if (fp_dlg->executable && !(umode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
fp_dlg->executable = FALSE;
switch_metadata_box (fp_dlg);
}
s_mode[0] = '0' + ((umode & (S_ISUID | S_ISGID | S_ISVTX)) >> 9);
s_mode[1] = '0' + ((umode & (S_IRUSR | S_IWUSR | S_IXUSR)) >> 6);
s_mode[2] = '0' + ((umode & (S_IRGRP | S_IWGRP | S_IXGRP)) >> 3);
s_mode[3] = '0' + ((umode & (S_IROTH | S_IWOTH | S_IXOTH)) >> 0);
s_mode[4] = 0;
gtk_label_set_text (GTK_LABEL (fp_dlg->mode_label), s_mode);
}
static GtkWidget *
perm_check_new (char *text, int state, GnomeFilePropertyDialog *fp_dlg)
{
GtkWidget *check;
if (text)
check = gtk_check_button_new_with_label (text);
else
check = gtk_check_button_new ();
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (check), FALSE);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), state ? TRUE : FALSE);
gtk_signal_connect (GTK_OBJECT (check), "toggled",
(GtkSignalFunc) perm_set_mode_label,
fp_dlg);
gtk_widget_show (check);
return check;
}
#define ATTACH(table, widget, left, right, top, bottom) \
gtk_table_attach (GTK_TABLE (table), widget, \
left, right, top, bottom, \
GTK_FILL | GTK_SHRINK, \
GTK_FILL | GTK_SHRINK, \
0, 0);
#define PERMSET(name, r, w, x, rmask, wmask, xmask, y) do { \
r = perm_check_new (NULL, fp_dlg->st.st_mode & rmask, fp_dlg); \
w = perm_check_new (NULL, fp_dlg->st.st_mode & wmask, fp_dlg); \
x = perm_check_new (NULL, fp_dlg->st.st_mode & xmask, fp_dlg); \
\
ATTACH (table, label_new (name, 0.0, 0.5), 0, 1, y, y + 1); \
ATTACH (table, r, 1, 2, y, y + 1); \
ATTACH (table, w, 2, 3, y, y + 1); \
ATTACH (table, x, 3, 4, y, y + 1); \
} while (0);
static GtkWidget *
perm_mode_new (GnomeFilePropertyDialog *fp_dlg)
{
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *table;
gchar *mode;
frame = gtk_frame_new (_("File Permissions"));
vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
gtk_box_pack_start (GTK_BOX (hbox), label_new (_("Current mode: "), 0.0, 0.5), FALSE, FALSE, 0);
fp_dlg->mode_label = label_new ("0000", 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (hbox), fp_dlg->mode_label, FALSE, FALSE, 0);
table = gtk_table_new (4, 5, FALSE);
if (!fp_dlg->modifyable || S_ISLNK (fp_dlg->st.st_mode))
gtk_widget_set_sensitive (table, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
gtk_table_set_row_spacings (GTK_TABLE (table), 6);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
gtk_widget_show (table);
/* Headings */
ATTACH (table, label_new (_("Read"), 0.0, 0.5), 1, 2, 0, 1);
ATTACH (table, label_new (_("Write"), 0.0, 0.5), 2, 3, 0, 1);
ATTACH (table, label_new (_("Exec"), 0.0, 0.5), 3, 4, 0, 1);
ATTACH (table, label_new (_("Special"), 0.0, 0.5), 4, 5, 0, 1);
/* Permissions */
PERMSET (_("User"), fp_dlg->rusr, fp_dlg->wusr, fp_dlg->xusr, S_IRUSR, S_IWUSR, S_IXUSR, 1);
PERMSET (_("Group"), fp_dlg->rgrp, fp_dlg->wgrp, fp_dlg->xgrp, S_IRGRP, S_IWGRP, S_IXGRP, 2);
PERMSET (_("Other"), fp_dlg->roth, fp_dlg->woth, fp_dlg->xoth, S_IROTH, S_IWOTH, S_IXOTH, 3);
/* Special */
fp_dlg->suid = perm_check_new (_("Set UID"), fp_dlg->st.st_mode & S_ISUID, fp_dlg);
fp_dlg->sgid = perm_check_new (_("Set GID"), fp_dlg->st.st_mode & S_ISGID, fp_dlg);
fp_dlg->svtx = perm_check_new (_("Sticky"), fp_dlg->st.st_mode & S_ISVTX, fp_dlg);
ATTACH (table, fp_dlg->suid, 4, 5, 1, 2);
ATTACH (table, fp_dlg->sgid, 4, 5, 2, 3);
ATTACH (table, fp_dlg->svtx, 4, 5, 3, 4);
perm_set_mode_label (NULL, fp_dlg);
gtk_label_get (GTK_LABEL (fp_dlg->mode_label), &mode);
fp_dlg->mode_name = g_strdup (mode);
return frame;
}
#undef ATTACH
#undef PERMSET
static GtkWidget *
perm_owner_new (GnomeFilePropertyDialog *fp_dlg)
{
GtkWidget *gentry;
struct passwd *passwd;
gentry = gtk_entry_new ();
if (fp_dlg->euid != 0)
gtk_widget_set_sensitive (gentry, FALSE);
passwd = getpwuid (fp_dlg->st.st_uid);
if (passwd) {
fp_dlg->user_name = passwd->pw_name;
gtk_entry_set_text (GTK_ENTRY (gentry), passwd->pw_name);
} else
gtk_entry_set_text (GTK_ENTRY (gentry), "<Unknown>");
return gentry;
}
static GtkWidget *
perm_group_new (GnomeFilePropertyDialog *fp_dlg)
{
GtkWidget *gentry;
struct group *grp;
gchar grpnum [50];
gboolean grp_flag = FALSE;
gchar *grpname = NULL;
GList *templist;
GList *list = NULL;
/* Are we root? Do we own the file? */
/* In this case we can change it. */
/* A little bit of this was swiped from kfm. */
if ((fp_dlg->euid == 0) || (fp_dlg->st.st_uid == fp_dlg->euid)) {
gentry = gtk_combo_new ();
grp = getgrgid (fp_dlg->st.st_gid);
if (grp){
if (grp->gr_name)
fp_dlg->group_name = g_strdup (grp->gr_name);
else {
sprintf (grpnum, "%d", (int) grp->gr_gid);
fp_dlg->group_name = g_strdup (grpnum);
}
} else {
sprintf (grpnum, "%d", (int) fp_dlg->st.st_gid);
fp_dlg->group_name = g_strdup (grpnum);
}
/* we change this, b/c we are able to set the egid, if we aren't in the group already */
grp = getgrgid (getegid());
if (grp) {
if (grp->gr_name)
grpname = grp->gr_name;
else {
sprintf (grpnum, "%d", (int) grp->gr_gid);
grpname = grpnum;
}
} else {
sprintf (grpnum, "%d", (int) fp_dlg->st.st_gid);
grpname = grpnum;
}
if (fp_dlg->euid != 0)
gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (gentry)->entry), FALSE);
for (setgrent (); (grp = getgrent ()) != NULL;) {
if (!grp_flag && grpname && !strcmp (grp->gr_name, grpname)) {
list = g_list_insert_sorted (list, g_strdup (grp->gr_name), (GCompareFunc)strcmp);
grp_flag = TRUE;
continue;
}
if (fp_dlg->euid == 0) {
list = g_list_insert_sorted (list, g_strdup (grp->gr_name), (GCompareFunc)strcmp);
} else {
gchar **members = grp->gr_mem;
gchar *member;
while ((member = *members) != 0L) {
if (!strcmp (member, fp_dlg->user_name)) {
list = g_list_insert_sorted (list, g_strdup (grp->gr_name), (GCompareFunc)strcmp);
break;
}
++members;
}
}
}
endgrent ();
/* we also might want to add the egid to the list. */
if (!grp_flag)
list = g_list_insert_sorted (list, g_strdup (grpname), (GCompareFunc)strcmp);
/* Now we have a list. We should make our option menu. */
gtk_combo_set_popdown_strings (GTK_COMBO (gentry), list);
for (templist = list; templist; templist = templist->next) {
g_free (templist->data);
}
gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (gentry)->entry), grpname);
g_list_free (list);
} else {
/* we're neither so we just put an entry down */
gentry = gtk_entry_new ();
gtk_widget_set_sensitive (gentry, FALSE);
grp = getgrgid (fp_dlg->st.st_gid);
gtk_entry_set_text (GTK_ENTRY (gentry), grp->gr_name);
}
return gentry;
}
static GtkWidget *
perm_ownership_new (GnomeFilePropertyDialog *fp_dlg)
{
GtkWidget *frame;
GtkWidget *table;
frame = gtk_frame_new (_("File ownership"));
table = gtk_table_new (2, 2, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (table), 6);
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
gtk_table_set_row_spacings (GTK_TABLE (table), 4);
gtk_container_add (GTK_CONTAINER (frame), table);
gtk_widget_show (table);
/* Owner */
gtk_table_attach (GTK_TABLE (table), label_new (_("Owner"), 0.0, 0.5),
0, 1, 0, 1,
GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK,
0, 0);
fp_dlg->owner_entry = perm_owner_new (fp_dlg);
gtk_table_attach (GTK_TABLE (table), fp_dlg->owner_entry,
1, 2, 0, 1,
GTK_EXPAND | GTK_FILL | GTK_SHRINK,
GTK_FILL | GTK_SHRINK,
0, 0);
gtk_widget_show (fp_dlg->owner_entry);
/* Group */
gtk_table_attach (GTK_TABLE (table), label_new (_("Group"), 0.0, 0.5),
0, 1, 1, 2,
GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK,
0, 0);
fp_dlg->group_entry = perm_group_new (fp_dlg);
gtk_table_attach (GTK_TABLE (table), fp_dlg->group_entry,
1, 2, 1, 2,
GTK_EXPAND | GTK_FILL | GTK_SHRINK,
GTK_FILL | GTK_SHRINK,
0, 0);
gtk_widget_show (fp_dlg->group_entry);
return frame;
}
static GtkWidget *
create_perm_properties (GnomeFilePropertyDialog *fp_dlg)
{
GtkWidget *vbox;
vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
gtk_container_set_border_width (GTK_CONTAINER (vbox), GNOME_PAD);
gtk_box_pack_start (GTK_BOX (vbox), perm_mode_new (fp_dlg), FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), perm_ownership_new (fp_dlg), TRUE, TRUE, 0);
return vbox;
}
/* finally the new dialog */
static void
init_metadata (GnomeFilePropertyDialog *fp_dlg)
{
gint size;
char *mime_type, *str;
gchar link_name[MC_MAXPATHLEN];
gint n;
gchar *file_name, *desktop_url;
if (gnome_metadata_get (fp_dlg->file_name, "fm-open", &size, &fp_dlg->fm_open) != 0)
gnome_metadata_get (fp_dlg->file_name, "open", &size, &fp_dlg->fm_open);
if (gnome_metadata_get (fp_dlg->file_name, "fm-view", &size, &fp_dlg->fm_view) != 0)
gnome_metadata_get (fp_dlg->file_name, "view", &size, &fp_dlg->fm_view);
gnome_metadata_get (fp_dlg->file_name, "edit", &size, &fp_dlg->edit);
gnome_metadata_get (fp_dlg->file_name, "drop-action", &size, &fp_dlg->drop_target);
/*
* Fetch the needs-terminal setting
*/
if (gnome_metadata_get (fp_dlg->file_name, "flags", &size, &str) == 0){
fp_dlg->needs_terminal = strstr (str, "needsterminal") != 0;
g_free (str);
} else
fp_dlg->needs_terminal = 0;
/* Mime stuff */
file_name = fp_dlg->file_name;
if (S_ISLNK (fp_dlg->st.st_mode)) {
n = mc_readlink (fp_dlg->file_name, link_name, MC_MAXPATHLEN);
if (n > 0){
link_name [n] = 0;
file_name = link_name;
}
}
if (gnome_metadata_get (fp_dlg->file_name, "desktop-url", &size, &desktop_url) == 0)
fp_dlg->desktop_url = desktop_url;
else
fp_dlg->desktop_url = NULL;
if (gnome_metadata_get (fp_dlg->file_name, "icon-caption", &size, &fp_dlg->caption))
fp_dlg->caption = g_strdup (desktop_url);
/*
* Mime type.
*/
mime_type = (char *) gnome_mime_type_or_default (file_name, NULL);
if (!mime_type)
return;
fp_dlg->mime_fm_open = gnome_mime_get_value (mime_type, "fm-open");
if (!fp_dlg->mime_fm_open)
fp_dlg->mime_fm_open = gnome_mime_get_value (mime_type, "open");
fp_dlg->mime_fm_view = gnome_mime_get_value (mime_type, "fm-view");
if (!fp_dlg->mime_fm_view)
fp_dlg->mime_fm_view = gnome_mime_get_value (mime_type, "view");
fp_dlg->mime_edit = gnome_mime_get_value (mime_type, "edit");
fp_dlg->mime_drop_target = gnome_mime_get_value (mime_type, "drop-action");
}
GtkWidget *
gnome_file_property_dialog_new (gchar *file_name, gboolean can_set_icon)
{
GnomeFilePropertyDialog *fp_dlg;
GtkWidget *notebook;
GtkWidget *new_page;
gchar *title_string;
mode_t mode;
g_return_val_if_fail (file_name != NULL, NULL);
fp_dlg = gtk_type_new (gnome_file_property_dialog_get_type ());
/* We set non-gui specific things first */
if (mc_lstat (file_name, &fp_dlg->st) == -1) {
/* Bad things man, bad things */
gtk_object_unref (GTK_OBJECT (fp_dlg));
return NULL;
}
mode = fp_dlg->st.st_mode;
if (S_ISLNK (mode)){
struct stat s;
if (mc_stat (file_name, &s) != -1)
mode = s.st_mode;
}
if (fp_dlg->st.st_mode & (S_IXUSR | S_IXGRP |S_IXOTH)) {
fp_dlg->executable = TRUE;
} else {
fp_dlg->executable = FALSE;
}
fp_dlg->file_name = g_strdup (file_name);
fp_dlg->euid = geteuid ();
fp_dlg->can_set_icon = can_set_icon;
if (S_ISCHR (fp_dlg->st.st_mode) || S_ISBLK (fp_dlg->st.st_mode)
|| ((fp_dlg->euid != fp_dlg->st.st_uid) && (fp_dlg->euid != 0)))
fp_dlg->modifyable = FALSE;
init_metadata (fp_dlg);
/* and now, we set up the gui. */
notebook = gtk_notebook_new ();
if (fp_dlg->desktop_url)
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
create_url_properties (fp_dlg),
gtk_label_new (_("URL")));
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
create_general_properties (fp_dlg),
gtk_label_new (_("Statistics")));
new_page = create_settings_pane (fp_dlg);
if (new_page)
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
new_page,
gtk_label_new (_("Options")));
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
create_perm_properties (fp_dlg),
gtk_label_new (_("Permissions")));
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (fp_dlg)->vbox),
notebook, TRUE, TRUE, 0);
title_string = g_strconcat (strrchr (file_name, '/') + 1, _(" Properties"), NULL);
gtk_window_set_title (GTK_WINDOW (fp_dlg), title_string);
g_free (title_string);
gnome_dialog_append_button ( GNOME_DIALOG(fp_dlg),
GNOME_STOCK_BUTTON_OK);
gnome_dialog_append_button ( GNOME_DIALOG(fp_dlg),
GNOME_STOCK_BUTTON_CANCEL);
gtk_widget_show_all (GNOME_DIALOG (fp_dlg)->vbox);
/* It's okay to do this now... */
/* and set the rest of the fields */
switch_metadata_box (fp_dlg);
return GTK_WIDGET (fp_dlg);
}
static gint
apply_mode_change (GnomeFilePropertyDialog *fpd)
{
gchar *new_mode;
gtk_label_get (GTK_LABEL (fpd->mode_label), &new_mode);
if (strcmp (new_mode, fpd->mode_name)) {
mc_chmod (fpd->file_name, (mode_t) strtol(new_mode, (char **)NULL, 8));
return 1;
}
return 0;
}
static gint
apply_uid_group_change (GnomeFilePropertyDialog *fpd)
{
uid_t uid;
gid_t gid;
struct passwd *p;
struct group *g;
gchar *new_user_name = NULL;
gchar *new_group_name = NULL;
uid = fpd->st.st_uid;
gid = fpd->st.st_gid;
/* we only check if our euid == 0 */
if (fpd->euid == 0) {
new_user_name = gtk_entry_get_text (GTK_ENTRY (fpd->owner_entry));
if (new_user_name && strcmp (fpd->user_name, new_user_name)) {
/* now we need to get the new uid */
p = getpwnam (new_user_name);
if (!p) {
uid = atoi (new_user_name);
if (uid == 0) {
message (1, "Error", _("You entered an invalid username"));
uid = fpd->st.st_uid;
}
} else
uid = p->pw_uid;
}
}
/* now we check the group */
/* We are only a combo if we are sensitive, and we only want to check if we are
* sensitive. */
if (GTK_WIDGET_IS_SENSITIVE (fpd->group_entry))
new_group_name = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (fpd->group_entry)->entry));
if (fpd->group_name && new_group_name && strcmp (fpd->group_name, new_group_name)) {
g = getgrnam (new_group_name);
if (!g) {
gid = atoi (new_group_name);
if (gid == 0) {
message (1, "Error", "You entered an invalid group name");
gid = fpd->st.st_gid;
}
} else
gid = g->gr_gid;
}
if ((uid != fpd->st.st_uid) || (gid != fpd->st.st_gid)) {
mc_chown (fpd->file_name, uid, gid);
return 1;
}
return 0;
}
static gint
apply_name_change (GnomeFilePropertyDialog *fpd)
{
char *new_name;
char *base_name;
char *full_target;
FileOpContext *ctx;
long count = 0;
double bytes = 0;
new_name = gtk_entry_get_text (GTK_ENTRY (fpd->file_entry));
if (!*new_name) {
message (1, "Error", _("You must rename your file to something"));
return 0;
}
/* has it changed? */
if (strcmp (strrchr(fpd->file_name, '/') + 1, new_name)) {
if (strchr (new_name, '/')) {
message (1, "Error", _("You cannot rename a file to something containing a '/' character"));
return 0;
} else {
char *p;
int s;
/* create the files. */
base_name = g_strdup (fpd->file_name);
p = strrchr (base_name, '/');
if (p)
*p = '\0';
full_target = concat_dir_and_file (base_name, new_name);
ctx = file_op_context_new ();
file_op_context_create_ui (ctx, OP_MOVE, FALSE);
s = move_file_file (ctx, fpd->file_name, full_target, &count, &bytes);
file_op_context_destroy (ctx);
if (s == FILE_CONT){
g_free (fpd->file_name);
fpd->file_name = full_target;
} else
g_free (full_target);
}
}
return 1;
}
static gint
apply_metadata_change (GnomeFilePropertyDialog *fpd)
{
gchar *text;
/* If we don't have an open_cbox, that means we have no metadata
* to set.
*/
if (fpd->open_cbox != NULL) {
if (!GTK_TOGGLE_BUTTON (fpd->open_cbox)->active) {
text = gtk_entry_get_text (GTK_ENTRY (fpd->open_entry));
if (text && text[0])
gnome_metadata_set (fpd->file_name,
"fm-open",
strlen (text) + 1,
text);
else
gnome_metadata_remove (fpd->file_name,
"fm-open");
} else {
if (fpd->fm_open)
gnome_metadata_remove (fpd->file_name,
"fm-open");
}
if (fpd->executable) {
if (!GTK_TOGGLE_BUTTON (fpd->prop1_cbox)->active) {
text = gtk_entry_get_text (GTK_ENTRY (fpd->prop1_entry));
if (text && text[0])
gnome_metadata_set (fpd->file_name,
"drop-action",
strlen (text) + 1,
text);
else
gnome_metadata_remove (fpd->file_name,
"drop-action");
} else {
if (fpd->drop_target)
gnome_metadata_remove (fpd->file_name,
"drop-action");
}
} else {
if (!GTK_TOGGLE_BUTTON (fpd->prop1_cbox)->active) {
text = gtk_entry_get_text (GTK_ENTRY (fpd->prop1_entry));
if (text && text[0])
gnome_metadata_set (fpd->file_name,
"fm-view",
strlen (text) + 1,
text);
else
gnome_metadata_remove (fpd->file_name,
"fm-view");
} else {
if (fpd->fm_view)
gnome_metadata_remove (fpd->file_name,
"fm-view");
}
if (!GTK_TOGGLE_BUTTON (fpd->prop2_cbox)->active) {
text = gtk_entry_get_text (GTK_ENTRY (fpd->prop2_entry));
if (text && text[0])
gnome_metadata_set (fpd->file_name,
"edit",
strlen (text) + 1,
text);
else
gnome_metadata_remove (fpd->file_name,
"edit");
} else {
if (fpd->edit)
gnome_metadata_remove (fpd->file_name,
"edit");
}
}
}
if (fpd->desktop_url){
char *new_desktop_url = gtk_entry_get_text (GTK_ENTRY (fpd->desktop_entry));
char *new_caption = gtk_entry_get_text (GTK_ENTRY (fpd->caption_entry));
gnome_metadata_set (fpd->file_name, "desktop-url",
strlen (new_desktop_url)+1, new_desktop_url);
gnome_metadata_set (fpd->file_name, "icon-caption",
strlen (new_caption)+1, new_caption);
}
/*
* "Needs terminal" check button
*
* This piece of code is more complex than it should, as the "flags"
* metadata value is actually a list of comma separated flags. So
* we need to edit this list when removing the "needsterminal" flag.
*/
if (fpd->needs_terminal_check)
{
int toggled = 0 != GTK_TOGGLE_BUTTON (fpd->needs_terminal_check)->active;
int size;
char *buf;
if (gnome_metadata_get (fpd->file_name, "flags", &size, &buf) == 0){
char *p;
p = strstr (buf, "needsterminal");
if (toggled){
if (!p){
p = g_strconcat (buf, ",needsterminal", NULL);
gnome_metadata_set (fpd->file_name, "flags", strlen (p)+1, p);
g_free (p);
}
} else {
if (p){
char *p1, *p2;
if (p != buf){
p1 = g_malloc (p - buf + 1);
strncpy (p1, buf, p - buf);
p1 [p - buf ] = 0;
} else
p1 = g_strdup ("");
p += strlen ("needsterminal");
p2 = g_strconcat (p1, p, NULL);
if (strcmp (p2, ",") == 0)
gnome_metadata_remove (fpd->file_name, "flags");
else
gnome_metadata_set (fpd->file_name, "flags",
strlen (p2)+1, p2);
g_free (p2);
g_free (p1);
}
}
} else {
if (toggled){
gnome_metadata_set (fpd->file_name, "flags",
sizeof ("needsterminal"), "needsterminal");
}
}
}
if (!fpd->can_set_icon)
return 1;
/* And finally, we set the metadata on the icon filename */
text = gnome_icon_entry_get_filename (GNOME_ICON_ENTRY (fpd->button));
/*gtk_entry_get_text (GTK_ENTRY (gnome_icon_entry_gtk_entry (GNOME_ICON_ENTRY (fpd->button))));*/
if (text) {
if (fpd->icon_filename == NULL || strcmp (fpd->icon_filename, text) != 0)
gnome_metadata_set (fpd->file_name, "icon-filename", strlen (text) + 1, text);
g_free (text);
}
/* I suppose we should only do this if we know there's been a change -- I'll try to figure it
* out later if it turns out to be important. */
return 1;
}
/* This function will apply what changes it can do. It is meant to be used in conjunction
* with a gnome_dialog_run_and_hide. Please note that doing a gnome_dialog_run
* will (obviously) cause greivious bogoness. */
gint
gnome_file_property_dialog_make_changes (GnomeFilePropertyDialog *file_property_dialog)
{
gint retval = 0;
g_return_val_if_fail (file_property_dialog != NULL, 1);
g_return_val_if_fail (GNOME_IS_FILE_PROPERTY_DIALOG (file_property_dialog), 1);
retval += apply_mode_change (file_property_dialog);
retval += apply_uid_group_change (file_property_dialog);
retval += apply_name_change (file_property_dialog);
retval += apply_metadata_change (file_property_dialog);
return retval;
}