mirror of https://github.com/MidnightCommander/mc
1424 lines
45 KiB
C
1424 lines
45 KiB
C
/* gnome-file-property-dialog.c
|
|
* 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"
|
|
#include "gmain.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);
|
|
|
|
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: "), use_magic ?
|
|
gnome_mime_type_or_default_of_file (fp_dlg->file_name, "text/plain") :
|
|
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) {
|
|
g_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) {
|
|
g_snprintf (buf, MC_MAXPATHLEN, "%.1f", (gfloat) fp_dlg->st.st_size / 1024.0);
|
|
g_snprintf (buf2, MC_MAXPATHLEN, "%d", (gint) fp_dlg->st.st_size);
|
|
gen_string = g_strconcat (_("File Size: "), buf, _(" KBytes ("),
|
|
buf2, _(" bytes)"), NULL);
|
|
} else {
|
|
g_snprintf (buf, MC_MAXPATHLEN, "%.1f",
|
|
(gfloat) fp_dlg->st.st_size / (1024.0 * 1024.0));
|
|
g_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;
|
|
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 *
|
|
align_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, align_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), align_label_new (_("Current mode: "), 0.0, 0.5),
|
|
FALSE, FALSE, 0);
|
|
|
|
fp_dlg->mode_label = align_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, align_label_new (_("Read"), 0.0, 0.5), 1, 2, 0, 1);
|
|
ATTACH (table, align_label_new (_("Write"), 0.0, 0.5), 2, 3, 0, 1);
|
|
ATTACH (table, align_label_new (_("Exec"), 0.0, 0.5), 3, 4, 0, 1);
|
|
ATTACH (table, align_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 {
|
|
char buf[100];
|
|
|
|
g_snprintf (buf, sizeof (buf), "%d", (int) fp_dlg->st.st_uid);
|
|
gtk_entry_set_text (GTK_ENTRY (gentry), buf);
|
|
}
|
|
|
|
return gentry;
|
|
}
|
|
|
|
static GtkWidget *
|
|
perm_group_new (GnomeFilePropertyDialog *fp_dlg)
|
|
{
|
|
GtkWidget *gentry;
|
|
struct group *grp;
|
|
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 {
|
|
fp_dlg->group_name = g_strdup_printf ("%d", (int) grp->gr_gid);
|
|
}
|
|
} else {
|
|
fp_dlg->group_name = g_strdup_printf ("%d", (int) fp_dlg->st.st_gid);
|
|
}
|
|
|
|
/* 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 = g_strdup (grp->gr_name);
|
|
else
|
|
grpname = g_strdup_printf ("%d", (int) grp->gr_gid);
|
|
} else
|
|
grpname = g_strdup_printf ("%d", (int) fp_dlg->st.st_gid);
|
|
|
|
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), fp_dlg->group_name);
|
|
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);
|
|
if (grp)
|
|
gtk_entry_set_text (GTK_ENTRY (gentry), grp->gr_name);
|
|
else {
|
|
char buf[100];
|
|
|
|
g_snprintf (buf, sizeof (buf), _("<Unknown> (%d)"), fp_dlg->st.st_gid);
|
|
gtk_entry_set_text (GTK_ENTRY (gentry), buf);
|
|
}
|
|
}
|
|
g_free (grpname);
|
|
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), align_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), align_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.
|
|
*/
|
|
if (use_magic)
|
|
{
|
|
mime_type = (char *) gnome_mime_type_or_default_of_file (file_name, NULL);
|
|
}
|
|
else
|
|
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 (fpd->user_name && 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, MSG_ERROR, _("You entered an invalid username"));
|
|
uid = fpd->st.st_uid;
|
|
}
|
|
} else
|
|
uid = p->pw_uid;
|
|
} else {
|
|
if (new_user_name){
|
|
p = getpwnam (new_user_name);
|
|
if (!p) {
|
|
uid = atoi (new_user_name);
|
|
if (uid == 0) {
|
|
message (1, MSG_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, MSG_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;
|
|
FileOpContext *ctx;
|
|
long count = 0;
|
|
double bytes = 0;
|
|
|
|
new_name = gtk_entry_get_text (GTK_ENTRY (fpd->file_entry));
|
|
if (!*new_name) {
|
|
message (1, MSG_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, MSG_ERROR, _("You cannot rename a file to something containing a '/' character"));
|
|
return 0;
|
|
} else {
|
|
char *p;
|
|
int s;
|
|
char *base_name;
|
|
char *full_target;
|
|
|
|
/* 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);
|
|
g_free (base_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;
|
|
}
|