Added cs to the list of languages
[midnight-commander.git] / gnome / gnome-file-property-dialog.c
blobe7e5674cd077d7020c06d778c90864ad8d77b288
1 /* gnome-file-property-dialog.c
2 * Copyright (C) 1999 J. Arthur Random
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include <gnome.h>
21 #include <time.h>
22 #include <string.h>
23 #include "gnome-file-property-dialog.h"
24 #include "dir.h"
25 #include "gdesktop.h"
26 #include <pwd.h>
27 #include <grp.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include "fileopctx.h"
31 #include "file.h"
32 #include "../vfs/vfs.h"
33 #include "gicon.h"
34 #include "dialog.h"
35 #include "util.h"
37 static void gnome_file_property_dialog_init (GnomeFilePropertyDialog *file_property_dialog);
38 static void gnome_file_property_dialog_class_init (GnomeFilePropertyDialogClass *klass);
39 static void gnome_file_property_dialog_finalize (GtkObject *object);
41 static GnomeDialogClass *parent_class = NULL;
44 GtkType
45 gnome_file_property_dialog_get_type (void)
47 static GtkType file_property_dialog_type = 0;
49 if (!file_property_dialog_type)
51 static const GtkTypeInfo file_property_dialog_info =
53 "GnomeFilePropertyDialog",
54 sizeof (GnomeFilePropertyDialog),
55 sizeof (GnomeFilePropertyDialogClass),
56 (GtkClassInitFunc) gnome_file_property_dialog_class_init,
57 (GtkObjectInitFunc) gnome_file_property_dialog_init,
58 /* reserved_1 */ NULL,
59 /* reserved_2 */ NULL,
62 file_property_dialog_type = gtk_type_unique (gnome_dialog_get_type (), &file_property_dialog_info);
65 return file_property_dialog_type;
68 static void
69 gnome_file_property_dialog_class_init (GnomeFilePropertyDialogClass *klass)
71 GtkObjectClass *object_class;
73 object_class = (GtkObjectClass*) klass;
75 parent_class = gtk_type_class (gnome_dialog_get_type ());
76 object_class->finalize = gnome_file_property_dialog_finalize;
81 static void
82 gnome_file_property_dialog_init (GnomeFilePropertyDialog *file_property_dialog)
84 file_property_dialog->file_name = NULL;
85 file_property_dialog->file_entry = NULL;
86 file_property_dialog->group_name = NULL;
87 file_property_dialog->modifyable = TRUE;
88 file_property_dialog->user_name = NULL;
89 file_property_dialog->prop1_label = NULL;
90 file_property_dialog->prop2_label = NULL;
91 file_property_dialog->prop1_entry = NULL;
92 file_property_dialog->prop2_entry = NULL;
93 file_property_dialog->prop1_cbox = NULL;
94 file_property_dialog->prop2_cbox = NULL;
95 file_property_dialog->fm_open = NULL;
96 file_property_dialog->fm_view = NULL;
97 file_property_dialog->edit = NULL;
98 file_property_dialog->drop_target = NULL;
99 file_property_dialog->im = NULL;
101 static void
102 gnome_file_property_dialog_finalize (GtkObject *object)
104 GnomeFilePropertyDialog *gfpd;
106 g_return_if_fail (object != NULL);
107 g_return_if_fail (GNOME_IS_FILE_PROPERTY_DIALOG (object));
109 gfpd = GNOME_FILE_PROPERTY_DIALOG (object);
111 if (gfpd->file_name)
112 g_free (gfpd->file_name);
113 if (gfpd->im)
114 gdk_imlib_destroy_image (gfpd->im);
115 if (gfpd->fm_open)
116 g_free (gfpd->fm_open);
117 if (gfpd->fm_view)
118 g_free (gfpd->fm_view);
119 if (gfpd->edit)
120 g_free (gfpd->edit);
121 if (gfpd->drop_target)
122 g_free (gfpd->drop_target);
123 if (gfpd->icon_filename)
124 g_free (gfpd->icon_filename);
125 if (gfpd->desktop_url)
126 g_free (gfpd->desktop_url);
127 if (gfpd->caption)
128 g_free (gfpd->caption);
130 (* GTK_OBJECT_CLASS (parent_class)->finalize) (object);
133 /* Create the pane */
135 static GtkWidget *
136 create_general_properties (GnomeFilePropertyDialog *fp_dlg)
138 GtkWidget *vbox;
139 GtkWidget *hbox;
140 GtkWidget *label;
141 GtkWidget *align;
142 gchar *direc;
143 gchar *gen_string;
144 gchar size[50]; /* this is a HUGE file. (: */
145 gchar size2[20]; /* this is a HUGE file. (: */
146 file_entry *fe;
147 GtkWidget *icon;
148 struct tm *time;
149 GtkWidget *table;
150 int n;
152 vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
153 gtk_container_set_border_width (GTK_CONTAINER (vbox), GNOME_PAD);
155 /* first, we set the icon */
156 direc = g_strdup (fp_dlg->file_name);
157 strrchr (direc, '/')[0] = '\0';
158 fe = file_entry_from_file (fp_dlg->file_name);
159 fp_dlg->im = gicon_get_icon_for_file_speed (direc, fe, FALSE);
160 file_entry_free (fe);
161 g_free (direc);
162 icon = gnome_pixmap_new_from_imlib (fp_dlg->im);
163 gtk_box_pack_start (GTK_BOX (vbox), icon, FALSE, FALSE, 0);
165 /* we set the file part */
166 gen_string = g_strconcat (_("Full Name: "), fp_dlg->file_name, NULL);
167 label = gtk_label_new (gen_string);
168 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
169 g_free (gen_string);
170 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
171 /* if it's a symlink */
172 align = gtk_alignment_new (0.0, 0.5, 1.0, 1.0);
173 hbox = gtk_hbox_new (FALSE, 2);
174 label = gtk_label_new (_("File Name"));
175 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
176 fp_dlg->file_entry = gtk_entry_new ();
177 gen_string = strrchr (fp_dlg->file_name, '/');
178 if (gen_string)
179 gtk_entry_set_text (GTK_ENTRY (fp_dlg->file_entry), gen_string + 1);
180 else
181 /* I don't think this should happen anymore, but it can't hurt in
182 * case this ever gets used outside gmc */
183 gtk_entry_set_text (GTK_ENTRY (fp_dlg->file_entry), fp_dlg->file_name);
184 /* We want to prevent editing of the file if
185 * the thing is a BLK, CHAR, or we don't own it */
186 /* FIXME: We can actually edit it if we're in the same grp of the file. */
187 if (fp_dlg->modifyable == FALSE)
188 gtk_widget_set_sensitive (fp_dlg->file_entry, FALSE);
189 gtk_box_pack_start (GTK_BOX (hbox), fp_dlg->file_entry, FALSE, FALSE, 0);
190 gtk_container_add (GTK_CONTAINER (align), hbox);
191 gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
192 gtk_box_pack_start (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, FALSE, 8);
194 /* File statistics */
195 /* File type first */
196 if (S_ISREG (fp_dlg->st.st_mode)) {
197 gen_string = g_strconcat (_("File Type: "),
198 gnome_mime_type (fp_dlg->file_name),
199 NULL);
200 label = gtk_label_new (gen_string);
201 g_free (gen_string);
202 } else if (S_ISLNK (fp_dlg->st.st_mode)) {
203 label = gtk_label_new (_("File Type: Symbolic Link"));
204 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
205 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
206 n = mc_readlink (fp_dlg->file_name, size, 49);
207 if (n < 0)
208 label = gtk_label_new (_("Target Name: INVALID LINK"));
209 else {
210 size[n] = '\0';
211 gen_string = g_strconcat (_("Target Name: "), size, NULL);
212 label = gtk_label_new (gen_string);
213 g_free (gen_string);
215 }else if (S_ISDIR (fp_dlg->st.st_mode))
216 label = gtk_label_new (_("File Type: Directory"));
217 else if (S_ISCHR (fp_dlg->st.st_mode))
218 label = gtk_label_new (_("File Type: Character Device"));
219 else if (S_ISBLK (fp_dlg->st.st_mode))
220 label = gtk_label_new (_("File Type: Block Device"));
221 else if (S_ISSOCK (fp_dlg->st.st_mode))
222 label = gtk_label_new (_("File Type: Socket"));
223 else if (S_ISFIFO (fp_dlg->st.st_mode))
224 label = gtk_label_new (_("File Type: FIFO"));
225 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
226 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
228 /* Now file size */
229 if (S_ISDIR (fp_dlg->st.st_mode)
230 || S_ISREG (fp_dlg->st.st_mode)
231 || S_ISLNK (fp_dlg->st.st_mode)) {
232 if ((gint)fp_dlg->st.st_size < 1024) {
233 snprintf (size, 19, "%d", (gint) fp_dlg->st.st_size);
234 gen_string = g_strconcat (_("File Size: "), size, _(" bytes"), NULL);
235 } else if ((gint)fp_dlg->st.st_size < 1024 * 1024) {
236 snprintf (size, 19, "%.1f", (gfloat) fp_dlg->st.st_size / 1024.0);
237 snprintf (size2, 19, "%d", (gint) fp_dlg->st.st_size);
238 gen_string = g_strconcat (_("File Size: "), size, _(" KBytes ("),
239 size2, _(" bytes)"), NULL);
240 } else {
241 snprintf (size, 19, "%.1f", (gfloat) fp_dlg->st.st_size / (1024.0 * 1024.0));
242 snprintf (size2, 19, "%d", (gint) fp_dlg->st.st_size);
243 gen_string = g_strconcat (_("File Size: "), size, _(" MBytes ("),
244 size2, _(" bytes)"), NULL);
246 label = gtk_label_new (gen_string);
247 g_free (gen_string);
248 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
249 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
250 } else {
251 label = gtk_label_new (_("File Size: N/A"));
252 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
253 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
256 gtk_box_pack_start (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, FALSE, 8);
258 /* Time Fields */
259 table = gtk_table_new (3, 2, FALSE);
260 gtk_table_set_row_spacings (GTK_TABLE (table), 2);
261 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
262 label = gtk_label_new (_("File Created on: "));
263 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
264 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
265 time = gmtime (&(fp_dlg->st.st_ctime));
266 strftime (size, 49, "%a, %b %d %Y, %I:%M:%S %p", time);
267 label = gtk_label_new (size);
268 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
269 gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 0, 1);
271 label = gtk_label_new (_("Last Modified on: "));
272 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
273 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
274 time = gmtime (&(fp_dlg->st.st_mtime));
275 strftime (size, 49, "%a, %b %d %Y, %I:%M:%S %p", time);
276 label = gtk_label_new (size);
277 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
278 gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 1, 2);
280 label = gtk_label_new (_("Last Accessed on: "));
281 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
282 gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
283 time = gmtime (&(fp_dlg->st.st_atime));
284 strftime (size, 49, "%a, %b %d %Y, %I:%M:%S %p", time);
285 label = gtk_label_new (size);
286 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
287 gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 2, 3);
288 return vbox;
291 static GtkWidget *
292 create_url_properties (GnomeFilePropertyDialog *fp_dlg)
294 GtkWidget *table, *label;
296 table = gtk_table_new (0, 0, 0);
298 label = gtk_label_new (_("URL:"));
299 gtk_table_attach (GTK_TABLE (table), label,
300 1, 2, 1, 2, 0, 0, GNOME_PAD, GNOME_PAD);
301 fp_dlg->desktop_entry = gtk_entry_new ();
302 gtk_table_attach (GTK_TABLE (table), fp_dlg->desktop_entry,
303 2, 3, 1, 2, GTK_FILL | GTK_EXPAND, 0, GNOME_PAD, GNOME_PAD);
305 label = gtk_label_new (_("Caption:"));
306 gtk_table_attach (GTK_TABLE (table), label,
307 1, 2, 2, 3, 0, 0, GNOME_PAD, GNOME_PAD);
308 fp_dlg->caption_entry = gtk_entry_new ();
309 gtk_table_attach (GTK_TABLE (table), fp_dlg->caption_entry,
310 2, 3, 2, 3, GTK_FILL | GTK_EXPAND, 0, GNOME_PAD, GNOME_PAD);
312 gtk_widget_show_all (table);
313 return table;
316 /* Settings Pane */
317 static void
318 metadata_toggled (GtkWidget *cbox, GnomeFilePropertyDialog *fp_dlg)
320 if (fp_dlg->changing)
321 return;
322 if (cbox == fp_dlg->open_cbox) {
323 if (GTK_TOGGLE_BUTTON (cbox)->active) {
324 gtk_widget_set_sensitive (fp_dlg->open_entry, FALSE);
325 if (fp_dlg->mime_fm_open)
326 gtk_entry_set_text (GTK_ENTRY (fp_dlg->open_entry), fp_dlg->mime_fm_open);
327 } else {
328 gtk_widget_set_sensitive (fp_dlg->open_entry, TRUE);
329 if (fp_dlg->fm_open) {
330 gtk_entry_set_text (GTK_ENTRY (fp_dlg->open_entry), fp_dlg->fm_open);
333 } else if (cbox == fp_dlg->prop1_cbox) {
334 if (GTK_TOGGLE_BUTTON (cbox)->active) {
335 gtk_widget_set_sensitive (fp_dlg->prop1_entry, FALSE);
336 if (fp_dlg->executable && fp_dlg->mime_drop_target) {
337 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->mime_drop_target);
338 } else if (!fp_dlg->executable && fp_dlg->mime_fm_view) {
339 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->mime_fm_view);
340 } else {
341 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), "");
343 } else {
344 gtk_widget_set_sensitive (fp_dlg->prop1_entry, TRUE);
345 if (fp_dlg->executable && fp_dlg->drop_target) {
346 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->drop_target);
347 } else if (!fp_dlg->executable && fp_dlg->fm_view) {
348 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->fm_view);
351 } else {
352 if (GTK_TOGGLE_BUTTON (cbox)->active) {
353 gtk_widget_set_sensitive (fp_dlg->prop2_entry, FALSE);
354 if (fp_dlg->mime_edit) {
355 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop2_entry), fp_dlg->mime_edit);
356 } else {
357 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop2_entry), "");
359 } else {
360 gtk_widget_set_sensitive (fp_dlg->prop2_entry, TRUE);
361 if (fp_dlg->edit) {
362 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop2_entry), fp_dlg->edit);
367 static void
368 switch_metadata_box (GnomeFilePropertyDialog *fp_dlg)
370 if (NULL == fp_dlg->prop1_label)
371 return;
372 fp_dlg->changing = TRUE;
374 if (fp_dlg->desktop_url){
375 gtk_entry_set_text (GTK_ENTRY (fp_dlg->desktop_entry), fp_dlg->desktop_url);
377 gtk_entry_set_text (GTK_ENTRY (fp_dlg->caption_entry), fp_dlg->caption);
380 if (fp_dlg->executable) {
381 gtk_label_set_text (GTK_LABEL (fp_dlg->prop1_label), "Drop Action");
382 gtk_label_set_text (GTK_LABEL (GTK_BIN (fp_dlg->prop1_cbox)->child), "Use default Drop Action options");
383 if (fp_dlg->drop_target) {
384 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop1_cbox), FALSE);
385 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->drop_target);
386 gtk_widget_set_sensitive (fp_dlg->prop1_entry, TRUE);
387 } else if (fp_dlg->mime_drop_target) {
388 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->mime_drop_target);
389 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop1_cbox), TRUE);
390 gtk_widget_set_sensitive (fp_dlg->prop1_entry, FALSE);
391 } else {
392 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), "");
393 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop1_cbox), TRUE);
394 gtk_widget_set_sensitive (fp_dlg->prop1_entry, FALSE);
396 } else {
397 gtk_label_set_text (GTK_LABEL (fp_dlg->prop1_label), "View");
398 gtk_label_set_text (GTK_LABEL (GTK_BIN (fp_dlg->prop1_cbox)->child), "Use default View options");
399 if (fp_dlg->fm_view) {
400 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->fm_view);
401 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop1_cbox), FALSE);
402 gtk_widget_set_sensitive (fp_dlg->prop1_entry, TRUE);
403 } else if (fp_dlg->mime_fm_view) {
404 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), fp_dlg->mime_fm_view);
405 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop1_cbox), TRUE);
406 gtk_widget_set_sensitive (fp_dlg->prop1_entry, FALSE);
407 } else {
408 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop1_entry), "");
409 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop1_cbox), TRUE);
410 gtk_widget_set_sensitive (fp_dlg->prop1_entry, FALSE);
413 if (fp_dlg->executable) {
414 gtk_widget_hide (fp_dlg->prop2_label);
415 gtk_widget_hide (fp_dlg->prop2_entry);
416 gtk_widget_hide (fp_dlg->prop2_cbox);
417 gtk_widget_hide (fp_dlg->prop2_hline);
418 } else {
419 gtk_widget_show (fp_dlg->prop2_label);
420 gtk_widget_show (fp_dlg->prop2_entry);
421 gtk_widget_show (fp_dlg->prop2_cbox);
422 gtk_widget_show (fp_dlg->prop2_hline);
424 fp_dlg->changing = FALSE;
426 static GtkWidget *
427 generate_icon_sel (GnomeFilePropertyDialog *fp_dlg)
429 GtkWidget *retval;
430 gchar *icon;
432 retval = gnome_icon_entry_new ("gmc_file_icon", "Select an Icon");
433 icon = gicon_image_to_name (fp_dlg->im);
434 if (!icon)
435 return retval;
437 if (!icon[0]){
438 g_free (icon);
439 return retval;
441 gnome_icon_entry_set_icon (GNOME_ICON_ENTRY (retval), icon);
442 g_free (icon);
443 return retval;
445 static GtkWidget *
446 generate_actions_box (GnomeFilePropertyDialog *fp_dlg)
448 GtkWidget *vbox;
449 GtkWidget *table;
451 /* Here's the Logic: */
452 /* All tops of files (other then folders) should let us edit "open" */
453 /* If we are a file, and an executable, we want to edit our "drop-target" */
454 /* Metadata, as it is meaningful to us. */
455 /* If we are non-executable, we want to edit our "edit" and "view" fields. */
456 /* Sym links want to have the same options as above, but use their Target's */
457 /* Executable/set bit in order to determine which one. */
458 /* Note, symlinks can set their own metadata, independent from their */
459 /* targets. */
461 table = gtk_table_new (8, 2, FALSE);
462 gtk_container_set_border_width (GTK_CONTAINER (table), GNOME_PAD_SMALL);
464 /* we do open first */
465 fp_dlg->open_label = gtk_label_new (_("Open"));
466 gtk_misc_set_alignment (GTK_MISC (fp_dlg->open_label), 0.0, 0.5);
467 gtk_misc_set_padding (GTK_MISC (fp_dlg->open_label), 2, 0);
468 gtk_table_attach_defaults (GTK_TABLE (table),
469 fp_dlg->open_label,
470 0, 1, 0, 1);
471 fp_dlg->open_entry = gtk_entry_new ();
472 gtk_table_attach_defaults (GTK_TABLE (table),
473 fp_dlg->open_entry,
474 1, 2, 0, 1);
475 fp_dlg->open_cbox = gtk_check_button_new_with_label (_("Use default Open options"));
476 gtk_signal_connect (GTK_OBJECT (fp_dlg->open_cbox), "toggled", metadata_toggled, fp_dlg);
477 gtk_table_attach_defaults (GTK_TABLE (table), fp_dlg->open_cbox, 0, 2, 1, 2);
480 vbox = gtk_vbox_new (FALSE, 0);
481 gtk_box_pack_start (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, FALSE, GNOME_PAD_SMALL);
482 gtk_table_attach_defaults (GTK_TABLE (table), vbox, 0, 2, 2, 3);
484 if (fp_dlg->executable)
485 fp_dlg->prop1_label = gtk_label_new (_("Drop Action"));
486 else
487 fp_dlg->prop1_label = gtk_label_new (_("View"));
488 gtk_misc_set_alignment (GTK_MISC (fp_dlg->prop1_label), 0.0, 0.5);
489 gtk_misc_set_padding (GTK_MISC (fp_dlg->prop1_label), 2, 0);
490 gtk_table_attach_defaults (GTK_TABLE (table),
491 fp_dlg->prop1_label,
492 0, 1, 3, 4);
493 fp_dlg->prop1_entry = gtk_entry_new ();
494 gtk_table_attach_defaults (GTK_TABLE (table),
495 fp_dlg->prop1_entry,
496 1, 2, 3, 4);
497 if (fp_dlg->executable)
498 fp_dlg->prop1_cbox = gtk_check_button_new_with_label (_("Use default Drop action options"));
499 else
500 fp_dlg->prop1_cbox = gtk_check_button_new_with_label (_("Use default View options"));
501 gtk_signal_connect (GTK_OBJECT (fp_dlg->prop1_cbox), "toggled", metadata_toggled, fp_dlg);
502 gtk_table_attach_defaults (GTK_TABLE (table), fp_dlg->prop1_cbox, 0, 2, 4, 5);
504 vbox = gtk_vbox_new (FALSE, 0);
505 fp_dlg->prop2_hline = gtk_hseparator_new ();
506 gtk_box_pack_start (GTK_BOX (vbox), fp_dlg->prop2_hline, FALSE, FALSE, GNOME_PAD_SMALL);
507 gtk_table_attach_defaults (GTK_TABLE (table), vbox, 0, 2, 5, 6);
509 fp_dlg->prop2_label = gtk_label_new (_("Edit"));
510 gtk_misc_set_alignment (GTK_MISC (fp_dlg->prop2_label), 0.0, 0.5);
511 gtk_misc_set_padding (GTK_MISC (fp_dlg->prop2_label), 2, 0);
512 gtk_table_attach_defaults (GTK_TABLE (table),
513 fp_dlg->prop2_label,
514 0, 1, 6, 7);
515 fp_dlg->prop2_entry = gtk_entry_new ();
516 gtk_table_attach_defaults (GTK_TABLE (table),
517 fp_dlg->prop2_entry,
518 1, 2, 6, 7);
519 fp_dlg->prop2_cbox = gtk_check_button_new_with_label (_("Use default Edit options"));
520 gtk_signal_connect (GTK_OBJECT (fp_dlg->prop2_cbox), "toggled", metadata_toggled, fp_dlg);
521 gtk_table_attach_defaults (GTK_TABLE (table), fp_dlg->prop2_cbox, 0, 2, 7, 8);
523 /* we set the open field */
524 fp_dlg->changing = TRUE;
525 if (fp_dlg->fm_open) {
526 gtk_entry_set_text (GTK_ENTRY (fp_dlg->open_entry), fp_dlg->fm_open);
527 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->open_cbox), FALSE);
528 gtk_widget_set_sensitive (fp_dlg->open_entry, TRUE);
529 } else if (fp_dlg->mime_fm_open) {
530 gtk_entry_set_text (GTK_ENTRY (fp_dlg->open_entry), fp_dlg->mime_fm_open);
531 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->open_cbox), TRUE);
532 gtk_widget_set_sensitive (fp_dlg->open_entry, FALSE);
533 } else {
534 gtk_entry_set_text (GTK_ENTRY (fp_dlg->open_entry), "");
535 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->open_cbox), TRUE);
536 gtk_widget_set_sensitive (fp_dlg->open_entry, FALSE);
538 if (fp_dlg->edit) {
539 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop2_cbox), FALSE);
540 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop2_entry), fp_dlg->edit);
541 gtk_widget_set_sensitive (fp_dlg->prop2_entry, TRUE);
542 } else if (fp_dlg->mime_edit) {
543 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop2_entry), fp_dlg->mime_edit);
544 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop2_cbox), TRUE);
545 gtk_widget_set_sensitive (fp_dlg->prop2_entry, FALSE);
546 } else {
547 gtk_entry_set_text (GTK_ENTRY (fp_dlg->prop2_entry), "");
548 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (fp_dlg->prop2_cbox), TRUE);
549 gtk_widget_set_sensitive (fp_dlg->prop2_entry, FALSE);
551 fp_dlg->changing = FALSE;
553 return table;
555 static GtkWidget *
556 create_settings_pane (GnomeFilePropertyDialog *fp_dlg)
558 GtkWidget *vbox = NULL;
559 GtkWidget *hbox;
560 GtkWidget *vbox2;
561 GtkWidget *frame;
562 GtkWidget *align;
563 GtkWidget *table;
564 struct stat linkstat;
566 vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
567 gtk_container_set_border_width (GTK_CONTAINER (vbox), GNOME_PAD);
569 if (fp_dlg->can_set_icon) {
571 frame = gtk_frame_new (_("Icon"));
572 vbox2 = gtk_vbox_new (FALSE, 0);
573 hbox = gtk_hbox_new (FALSE, 0);
574 align = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
575 gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
576 fp_dlg->button = generate_icon_sel (fp_dlg);
577 gtk_container_add (GTK_CONTAINER (frame), vbox2);
578 gtk_container_set_border_width (GTK_CONTAINER (vbox2), GNOME_PAD_SMALL);
579 gtk_box_pack_start (GTK_BOX (vbox2), hbox, TRUE, FALSE, 0);
580 gtk_box_pack_start (GTK_BOX (hbox), align, TRUE, FALSE, 0);
581 gtk_container_add (GTK_CONTAINER (align), fp_dlg->button);
583 /* Are we a directory or device? If so, we do nothing else. */
584 if (S_ISLNK (fp_dlg->st.st_mode))
585 mc_stat (fp_dlg->file_name, &linkstat);
587 if (!(S_ISREG (fp_dlg->st.st_mode) || (S_ISLNK (fp_dlg->st.st_mode) && !S_ISREG (linkstat.st_mode)))) {
588 if (!fp_dlg->can_set_icon) {
589 gtk_widget_unref (vbox);
590 vbox = NULL;
592 return vbox;
595 /* We must be a file or a link to a file. */
596 frame = gtk_frame_new (_("Actions"));
597 gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
598 table = generate_actions_box (fp_dlg);
599 gtk_container_add (GTK_CONTAINER (frame), table);
600 return vbox;
603 /* Permissions Pane */
604 static GtkWidget *
605 label_new (char *text, double xalign, double yalign)
607 GtkWidget *label;
609 label = gtk_label_new (text);
610 gtk_misc_set_alignment (GTK_MISC (label), xalign, yalign);
611 gtk_widget_show (label);
613 return label;
616 static mode_t
617 perm_get_umode (GnomeFilePropertyDialog *fp_dlg)
619 mode_t umode;
621 #define SETBIT(widget, flag) umode |= GTK_TOGGLE_BUTTON (widget)->active ? flag : 0
623 umode = 0;
625 SETBIT (fp_dlg->suid, S_ISUID);
626 SETBIT (fp_dlg->sgid, S_ISGID);
627 SETBIT (fp_dlg->svtx, S_ISVTX);
629 SETBIT (fp_dlg->rusr, S_IRUSR);
630 SETBIT (fp_dlg->wusr, S_IWUSR);
631 SETBIT (fp_dlg->xusr, S_IXUSR);
633 SETBIT (fp_dlg->rgrp, S_IRGRP);
634 SETBIT (fp_dlg->wgrp, S_IWGRP);
635 SETBIT (fp_dlg->xgrp, S_IXGRP);
637 SETBIT (fp_dlg->roth, S_IROTH);
638 SETBIT (fp_dlg->woth, S_IWOTH);
639 SETBIT (fp_dlg->xoth, S_IXOTH);
641 return umode;
643 #undef SETBIT
647 static void
648 perm_set_mode_label (GtkWidget *widget, gpointer data)
650 GnomeFilePropertyDialog *fp_dlg;
651 mode_t umode;
652 char s_mode[5];
654 fp_dlg = GNOME_FILE_PROPERTY_DIALOG (data);
655 umode = perm_get_umode (fp_dlg);
656 if (!fp_dlg->executable && (umode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
657 fp_dlg->executable = TRUE;
658 switch_metadata_box (fp_dlg);
659 } else if (fp_dlg->executable && !(umode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
660 fp_dlg->executable = FALSE;
661 switch_metadata_box (fp_dlg);
664 s_mode[0] = '0' + ((umode & (S_ISUID | S_ISGID | S_ISVTX)) >> 9);
665 s_mode[1] = '0' + ((umode & (S_IRUSR | S_IWUSR | S_IXUSR)) >> 6);
666 s_mode[2] = '0' + ((umode & (S_IRGRP | S_IWGRP | S_IXGRP)) >> 3);
667 s_mode[3] = '0' + ((umode & (S_IROTH | S_IWOTH | S_IXOTH)) >> 0);
668 s_mode[4] = 0;
669 gtk_label_set_text (GTK_LABEL (fp_dlg->mode_label), s_mode);
672 static GtkWidget *
673 perm_check_new (char *text, int state, GnomeFilePropertyDialog *fp_dlg)
675 GtkWidget *check;
677 if (text)
678 check = gtk_check_button_new_with_label (text);
679 else
680 check = gtk_check_button_new ();
682 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (check), FALSE);
683 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), state ? TRUE : FALSE);
685 gtk_signal_connect (GTK_OBJECT (check), "toggled",
686 (GtkSignalFunc) perm_set_mode_label,
687 fp_dlg);
689 gtk_widget_show (check);
690 return check;
693 #define ATTACH(table, widget, left, right, top, bottom) \
694 gtk_table_attach (GTK_TABLE (table), widget, \
695 left, right, top, bottom, \
696 GTK_FILL | GTK_SHRINK, \
697 GTK_FILL | GTK_SHRINK, \
698 0, 0);
700 #define PERMSET(name, r, w, x, rmask, wmask, xmask, y) do { \
701 r = perm_check_new (NULL, fp_dlg->st.st_mode & rmask, fp_dlg); \
702 w = perm_check_new (NULL, fp_dlg->st.st_mode & wmask, fp_dlg); \
703 x = perm_check_new (NULL, fp_dlg->st.st_mode & xmask, fp_dlg); \
705 ATTACH (table, label_new (name, 0.0, 0.5), 0, 1, y, y + 1); \
706 ATTACH (table, r, 1, 2, y, y + 1); \
707 ATTACH (table, w, 2, 3, y, y + 1); \
708 ATTACH (table, x, 3, 4, y, y + 1); \
709 } while (0);
711 static GtkWidget *
712 perm_mode_new (GnomeFilePropertyDialog *fp_dlg)
714 GtkWidget *frame;
715 GtkWidget *vbox;
716 GtkWidget *hbox;
717 GtkWidget *table;
718 gchar *mode;
720 frame = gtk_frame_new (_("File Permissions"));
722 vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
723 gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
724 gtk_container_add (GTK_CONTAINER (frame), vbox);
725 gtk_widget_show (vbox);
727 hbox = gtk_hbox_new (FALSE, 0);
728 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
729 gtk_widget_show (hbox);
731 gtk_box_pack_start (GTK_BOX (hbox), label_new (_("Current mode: "), 0.0, 0.5), FALSE, FALSE, 0);
733 fp_dlg->mode_label = label_new ("0000", 0.0, 0.5);
734 gtk_box_pack_start (GTK_BOX (hbox), fp_dlg->mode_label, FALSE, FALSE, 0);
736 table = gtk_table_new (4, 5, FALSE);
737 if (!fp_dlg->modifyable || S_ISLNK (fp_dlg->st.st_mode))
738 gtk_widget_set_sensitive (table, FALSE);
739 gtk_table_set_col_spacings (GTK_TABLE (table), 4);
740 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
741 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
742 gtk_widget_show (table);
744 /* Headings */
746 ATTACH (table, label_new (_("Read"), 0.0, 0.5), 1, 2, 0, 1);
747 ATTACH (table, label_new (_("Write"), 0.0, 0.5), 2, 3, 0, 1);
748 ATTACH (table, label_new (_("Exec"), 0.0, 0.5), 3, 4, 0, 1);
749 ATTACH (table, label_new (_("Special"), 0.0, 0.5), 4, 5, 0, 1);
751 /* Permissions */
753 PERMSET (_("User"), fp_dlg->rusr, fp_dlg->wusr, fp_dlg->xusr, S_IRUSR, S_IWUSR, S_IXUSR, 1);
754 PERMSET (_("Group"), fp_dlg->rgrp, fp_dlg->wgrp, fp_dlg->xgrp, S_IRGRP, S_IWGRP, S_IXGRP, 2);
755 PERMSET (_("Other"), fp_dlg->roth, fp_dlg->woth, fp_dlg->xoth, S_IROTH, S_IWOTH, S_IXOTH, 3);
757 /* Special */
759 fp_dlg->suid = perm_check_new (_("Set UID"), fp_dlg->st.st_mode & S_ISUID, fp_dlg);
760 fp_dlg->sgid = perm_check_new (_("Set GID"), fp_dlg->st.st_mode & S_ISGID, fp_dlg);
761 fp_dlg->svtx = perm_check_new (_("Sticky"), fp_dlg->st.st_mode & S_ISVTX, fp_dlg);
763 ATTACH (table, fp_dlg->suid, 4, 5, 1, 2);
764 ATTACH (table, fp_dlg->sgid, 4, 5, 2, 3);
765 ATTACH (table, fp_dlg->svtx, 4, 5, 3, 4);
767 perm_set_mode_label (NULL, fp_dlg);
768 gtk_label_get (GTK_LABEL (fp_dlg->mode_label), &mode);
769 fp_dlg->mode_name = g_strdup (mode);
770 return frame;
773 #undef ATTACH
774 #undef PERMSET
776 static GtkWidget *
777 perm_owner_new (GnomeFilePropertyDialog *fp_dlg)
779 GtkWidget *gentry;
780 struct passwd *passwd;
782 gentry = gtk_entry_new ();
784 if (fp_dlg->euid != 0)
785 gtk_widget_set_sensitive (gentry, FALSE);
786 passwd = getpwuid (fp_dlg->st.st_uid);
787 if (passwd) {
788 fp_dlg->user_name = passwd->pw_name;
789 gtk_entry_set_text (GTK_ENTRY (gentry), passwd->pw_name);
790 } else
791 gtk_entry_set_text (GTK_ENTRY (gentry), "<Unknown>");
793 return gentry;
795 static GtkWidget *
796 perm_group_new (GnomeFilePropertyDialog *fp_dlg)
798 GtkWidget *gentry;
799 struct group *grp;
800 gchar grpnum [10];
801 gboolean grp_flag = FALSE;
802 gchar *grpname = NULL;
803 GList *templist;
804 GList *list = NULL;
807 /* Are we root? Do we own the file? */
808 /* In this case we can change it. */
809 /* A little bit of this was swiped from kfm. */
811 if ((fp_dlg->euid == 0) || (fp_dlg->st.st_uid == fp_dlg->euid)) {
812 gentry = gtk_combo_new ();
813 grp = getgrgid (fp_dlg->st.st_gid);
814 if (grp->gr_name)
815 fp_dlg->group_name = g_strdup (grp->gr_name);
816 else {
817 g_snprintf (grpnum, 9, "%d", (int) grp->gr_gid);
818 fp_dlg->group_name = g_strdup (grpnum);
821 /* we change this, b/c we are able to set the egid, if we aren't in the group already */
822 grp = getgrgid (getegid());
823 if (grp) {
824 if (grp->gr_name)
825 grpname = grp->gr_name;
826 else {
827 g_snprintf (grpnum, 9, "%d", (int) grp->gr_gid);
828 grpname = grpnum;
831 if (fp_dlg->euid != 0)
832 gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (gentry)->entry), FALSE);
833 for (setgrent (); (grp = getgrent ()) != NULL;) {
834 if (!grp_flag && grpname && !strcmp (grp->gr_name, grpname)) {
835 list = g_list_insert_sorted (list, g_strdup (grp->gr_name), (GCompareFunc)strcmp);
836 grp_flag = TRUE;
837 continue;
839 if (fp_dlg->euid == 0) {
840 list = g_list_insert_sorted (list, g_strdup (grp->gr_name), (GCompareFunc)strcmp);
841 } else {
842 gchar **members = grp->gr_mem;
843 gchar *member;
844 while ((member = *members) != 0L) {
845 if (!strcmp (member, fp_dlg->user_name)) {
846 list = g_list_insert_sorted (list, g_strdup (grp->gr_name), (GCompareFunc)strcmp);
847 break;
849 ++members;
853 endgrent ();
855 /* we also might want to add the egid to the list. */
856 if (!grp_flag)
857 list = g_list_insert_sorted (list, g_strdup (grpname), (GCompareFunc)strcmp);
859 /* Now we have a list. We should make our option menu. */
860 gtk_combo_set_popdown_strings (GTK_COMBO (gentry), list);
861 for (templist = list; templist; templist = templist->next) {
862 g_free (templist->data);
864 grp = getgrgid (fp_dlg->st.st_gid);
865 gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (gentry)->entry), grp->gr_name);
866 g_list_free (list);
867 } else {
868 /* we're neither so we just put an entry down */
869 gentry = gtk_entry_new ();
870 gtk_widget_set_sensitive (gentry, FALSE);
871 grp = getgrgid (fp_dlg->st.st_gid);
872 gtk_entry_set_text (GTK_ENTRY (gentry), grp->gr_name);
874 return gentry;
877 static GtkWidget *
878 perm_ownership_new (GnomeFilePropertyDialog *fp_dlg)
880 GtkWidget *frame;
881 GtkWidget *table;
883 frame = gtk_frame_new ("File ownership");
885 table = gtk_table_new (2, 2, FALSE);
886 gtk_container_set_border_width (GTK_CONTAINER (table), 6);
887 gtk_table_set_col_spacings (GTK_TABLE (table), 6);
888 gtk_table_set_row_spacings (GTK_TABLE (table), 4);
889 gtk_container_add (GTK_CONTAINER (frame), table);
890 gtk_widget_show (table);
892 /* Owner */
894 gtk_table_attach (GTK_TABLE (table), label_new (_("Owner"), 0.0, 0.5),
895 0, 1, 0, 1,
896 GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK,
897 0, 0);
899 fp_dlg->owner_entry = perm_owner_new (fp_dlg);
900 gtk_table_attach (GTK_TABLE (table), fp_dlg->owner_entry,
901 1, 2, 0, 1,
902 GTK_EXPAND | GTK_FILL | GTK_SHRINK,
903 GTK_FILL | GTK_SHRINK,
904 0, 0);
905 gtk_widget_show (fp_dlg->owner_entry);
907 /* Group */
909 gtk_table_attach (GTK_TABLE (table), label_new (_("Group"), 0.0, 0.5),
910 0, 1, 1, 2,
911 GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK,
912 0, 0);
914 fp_dlg->group_entry = perm_group_new (fp_dlg);
915 gtk_table_attach (GTK_TABLE (table), fp_dlg->group_entry,
916 1, 2, 1, 2,
917 GTK_EXPAND | GTK_FILL | GTK_SHRINK,
918 GTK_FILL | GTK_SHRINK,
919 0, 0);
920 gtk_widget_show (fp_dlg->group_entry);
921 return frame;
924 static GtkWidget *
925 create_perm_properties (GnomeFilePropertyDialog *fp_dlg)
927 GtkWidget *vbox;
929 vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
930 gtk_container_set_border_width (GTK_CONTAINER (vbox), GNOME_PAD);
931 gtk_box_pack_start (GTK_BOX (vbox), perm_mode_new (fp_dlg), FALSE, FALSE, 0);
932 gtk_box_pack_start (GTK_BOX (vbox), perm_ownership_new (fp_dlg), TRUE, TRUE, 0);
933 return vbox;
935 /* finally the new dialog */
936 static void
937 init_metadata (GnomeFilePropertyDialog *fp_dlg)
939 gint size;
940 char *mime_type;
941 gchar link_name[60];
942 gint n;
943 gchar *file_name, *desktop_url;
945 if (gnome_metadata_get (fp_dlg->file_name, "fm-open", &size, &fp_dlg->fm_open) != 0)
946 gnome_metadata_get (fp_dlg->file_name, "open", &size, &fp_dlg->fm_open);
947 if (gnome_metadata_get (fp_dlg->file_name, "fm-view", &size, &fp_dlg->fm_view) != 0)
948 gnome_metadata_get (fp_dlg->file_name, "view", &size, &fp_dlg->fm_view);
949 gnome_metadata_get (fp_dlg->file_name, "edit", &size, &fp_dlg->edit);
950 gnome_metadata_get (fp_dlg->file_name, "drop-target", &size, &fp_dlg->drop_target);
952 /* Mime stuff */
953 file_name = fp_dlg->file_name;
954 if (S_ISLNK (fp_dlg->st.st_mode)) {
955 n = mc_readlink (fp_dlg->file_name, link_name, 59);
956 if (n > 0) {
957 link_name[n] = '\0';
958 file_name = link_name;
962 if (gnome_metadata_get (fp_dlg->file_name, "desktop-url", &size, &desktop_url) == 0)
963 fp_dlg->desktop_url = desktop_url;
964 else
965 fp_dlg->desktop_url = NULL;
967 if (gnome_metadata_get (fp_dlg->file_name, "icon-caption", &size, &fp_dlg->caption))
968 fp_dlg->caption = g_strdup (desktop_url);
971 * Mime type.
973 mime_type = (char *) gnome_mime_type_or_default (file_name, NULL);
974 if (!mime_type)
975 return;
976 fp_dlg->mime_fm_open = gnome_mime_get_value (mime_type, "fm-open");
977 if (!fp_dlg->mime_fm_open)
978 fp_dlg->mime_fm_open = gnome_mime_get_value (mime_type, "open");
979 fp_dlg->mime_fm_view = gnome_mime_get_value (mime_type, "fm-view");
980 if (!fp_dlg->mime_fm_view)
981 fp_dlg->mime_fm_view = gnome_mime_get_value (mime_type, "view");
982 fp_dlg->mime_edit = gnome_mime_get_value (mime_type, "edit");
983 fp_dlg->mime_edit = gnome_mime_get_value (mime_type, "drop-target");
985 gnome_metadata_get (fp_dlg->file_name, "icon-filename", &size, &fp_dlg->icon_filename);
986 if (fp_dlg->icon_filename)
987 g_print ("we have an icon-filename:%s:\n", fp_dlg->icon_filename);
990 GtkWidget *
991 gnome_file_property_dialog_new (gchar *file_name, gboolean can_set_icon)
993 GnomeFilePropertyDialog *fp_dlg;
994 GtkWidget *notebook;
995 GtkWidget *new_page;
996 gchar *title_string;
998 g_return_val_if_fail (file_name != NULL, NULL);
999 fp_dlg = gtk_type_new (gnome_file_property_dialog_get_type ());
1001 /* We set non-gui specific things first */
1002 if (mc_lstat (file_name, &fp_dlg->st) == -1) {
1003 /* Bad things man, bad things */
1004 gtk_object_unref (GTK_OBJECT (fp_dlg));
1005 return NULL;
1009 if (fp_dlg->st.st_mode & (S_IXUSR | S_IXGRP |S_IXOTH)) {
1010 fp_dlg->executable = TRUE;
1011 } else {
1012 fp_dlg->executable = FALSE;
1015 fp_dlg->file_name = g_strdup (file_name);
1016 fp_dlg->euid = geteuid ();
1017 fp_dlg->can_set_icon = can_set_icon;
1018 if (S_ISCHR (fp_dlg->st.st_mode) || S_ISBLK (fp_dlg->st.st_mode)
1019 || ((fp_dlg->euid != fp_dlg->st.st_uid) && (fp_dlg->euid != 0)))
1020 fp_dlg->modifyable = FALSE;
1021 init_metadata (fp_dlg);
1023 /* and now, we set up the gui. */
1024 notebook = gtk_notebook_new ();
1026 if (fp_dlg->desktop_url)
1027 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1028 create_url_properties (fp_dlg),
1029 gtk_label_new (_("URL")));
1030 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1031 create_general_properties (fp_dlg),
1032 gtk_label_new (_("Statistics")));
1034 new_page = create_settings_pane (fp_dlg);
1035 if (new_page)
1036 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1037 new_page,
1038 gtk_label_new (_("Options")));
1039 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1040 create_perm_properties (fp_dlg),
1041 gtk_label_new (_("Permissions")));
1042 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (fp_dlg)->vbox),
1043 notebook, TRUE, TRUE, 0);
1044 title_string = g_strconcat (strrchr (file_name, '/') + 1, _(" Properties"), NULL);
1045 gtk_window_set_title (GTK_WINDOW (fp_dlg), title_string);
1046 g_free (title_string);
1048 gnome_dialog_append_button ( GNOME_DIALOG(fp_dlg),
1049 GNOME_STOCK_BUTTON_OK);
1050 gnome_dialog_append_button ( GNOME_DIALOG(fp_dlg),
1051 GNOME_STOCK_BUTTON_CANCEL);
1052 gtk_widget_show_all (GNOME_DIALOG (fp_dlg)->vbox);
1054 /* It's okay to do this now... */
1055 /* and set the rest of the fields */
1056 switch_metadata_box (fp_dlg);
1058 return GTK_WIDGET (fp_dlg);
1060 static gint
1061 apply_mode_change (GnomeFilePropertyDialog *fpd)
1063 gchar *new_mode;
1064 gtk_label_get (GTK_LABEL (fpd->mode_label), &new_mode);
1065 if (strcmp (new_mode, fpd->mode_name)) {
1066 mc_chmod (fpd->file_name, (mode_t) strtol(new_mode, (char **)NULL, 8));
1067 return 1;
1069 return 0;
1071 static gint
1072 apply_uid_group_change (GnomeFilePropertyDialog *fpd)
1074 uid_t uid;
1075 gid_t gid;
1076 struct passwd *p;
1077 struct group *g;
1078 gchar *new_user_name = NULL;
1079 gchar *new_group_name = NULL;
1081 uid = fpd->st.st_uid;
1082 gid = fpd->st.st_gid;
1084 /* we only check if our euid == 0 */
1085 if (fpd->euid == 0) {
1086 new_user_name = gtk_entry_get_text (GTK_ENTRY (fpd->owner_entry));
1087 if (new_user_name && strcmp (fpd->user_name, new_user_name)) {
1088 /* now we need to get the new uid */
1089 p = getpwnam (new_user_name);
1090 if (!p) {
1091 uid = atoi (new_user_name);
1092 if (uid == 0) {
1093 message (1, "Error", _("You entered an invalid username"));
1094 uid = fpd->st.st_uid;
1096 } else
1097 uid = p->pw_uid;
1102 /* now we check the group */
1103 /* We are only a combo if we are sensitive, and we only want to check if we are
1104 * sensitive. */
1105 if (GTK_WIDGET_IS_SENSITIVE (fpd->group_entry))
1106 new_group_name = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (fpd->group_entry)->entry));
1108 if (fpd->group_name && new_group_name && strcmp (fpd->group_name, new_group_name)) {
1109 g = getgrnam (new_group_name);
1110 if (!g) {
1111 gid = atoi (new_group_name);
1112 if (gid == 0) {
1113 message (1, "Error", "You entered an invalid group name");
1114 gid = fpd->st.st_gid;
1116 } else
1117 gid = g->gr_gid;
1119 if ((uid != fpd->st.st_uid) || (gid != fpd->st.st_gid)) {
1120 mc_chown (fpd->file_name, uid, gid);
1121 return 1;
1123 return 0;
1125 static gint
1126 apply_name_change (GnomeFilePropertyDialog *fpd)
1128 char *new_name;
1129 char *base_name;
1130 char *full_target;
1131 FileOpContext *ctx;
1132 long count = 0;
1133 double bytes = 0;
1135 new_name = gtk_entry_get_text (GTK_ENTRY (fpd->file_entry));
1136 if (!*new_name) {
1137 message (1, "Error", _("You must rename your file to something"));
1138 return 0;
1140 /* has it changed? */
1141 if (strcmp (strrchr(fpd->file_name, '/') + 1, new_name)) {
1142 if (strchr (new_name, '/')) {
1143 message (1, "Error", _("You cannot rename a file to something containing a '/' character"));
1144 return 0;
1145 } else {
1146 char *p;
1148 /* create the files. */
1149 base_name = g_strdup (fpd->file_name);
1151 p = strrchr (base_name, '/');
1153 if (p)
1154 *p = '\0';
1156 full_target = concat_dir_and_file (base_name, new_name);
1158 ctx = file_op_context_new ();
1159 file_op_context_create_ui (ctx, OP_MOVE, FALSE);
1160 move_file_file (ctx, fpd->file_name, full_target, &count, &bytes);
1161 file_op_context_destroy (ctx);
1162 g_free (full_target);
1165 return 1;
1167 static gint
1168 apply_metadata_change (GnomeFilePropertyDialog *fpd)
1170 gchar *text;
1171 gchar *icon_name;
1173 /* If we don't have an open_cbox, that means we have no metadata
1174 * to set.
1176 if (fpd->open_cbox != NULL) {
1177 if (!GTK_TOGGLE_BUTTON (fpd->open_cbox)->active) {
1178 text = gtk_entry_get_text (GTK_ENTRY (fpd->open_entry));
1179 if (text && text[0])
1180 gnome_metadata_set (fpd->file_name,
1181 "fm-open",
1182 strlen (text) + 1,
1183 text);
1184 else
1185 gnome_metadata_remove (fpd->file_name,
1186 "fm-open");
1187 } else {
1188 if (fpd->fm_open)
1189 gnome_metadata_remove (fpd->file_name,
1190 "fm-open");
1192 if (fpd->executable) {
1193 if (!GTK_TOGGLE_BUTTON (fpd->prop1_cbox)->active) {
1194 text = gtk_entry_get_text (GTK_ENTRY (fpd->prop1_entry));
1195 if (text && text[0])
1196 gnome_metadata_set (fpd->file_name,
1197 "drop-target",
1198 strlen (text) + 1,
1199 text);
1200 else
1201 gnome_metadata_remove (fpd->file_name,
1202 "drop-target");
1203 } else {
1204 if (fpd->drop_target)
1205 gnome_metadata_remove (fpd->file_name,
1206 "drop-target");
1208 } else {
1209 if (!GTK_TOGGLE_BUTTON (fpd->prop1_cbox)->active) {
1210 text = gtk_entry_get_text (GTK_ENTRY (fpd->prop1_entry));
1211 if (text && text[0])
1212 gnome_metadata_set (fpd->file_name,
1213 "fm-view",
1214 strlen (text) + 1,
1215 text);
1216 else
1217 gnome_metadata_remove (fpd->file_name,
1218 "fm-view");
1219 } else {
1220 if (fpd->fm_view)
1221 gnome_metadata_remove (fpd->file_name,
1222 "fm-view");
1224 if (!GTK_TOGGLE_BUTTON (fpd->prop2_cbox)->active) {
1225 text = gtk_entry_get_text (GTK_ENTRY (fpd->prop2_entry));
1226 if (text && text[0])
1227 gnome_metadata_set (fpd->file_name,
1228 "edit",
1229 strlen (text) + 1,
1230 text);
1231 else
1232 gnome_metadata_remove (fpd->file_name,
1233 "edit");
1234 } else {
1235 if (fpd->edit)
1236 gnome_metadata_remove (fpd->file_name,
1237 "edit");
1242 if (fpd->desktop_url){
1243 char *new_desktop_url = gtk_entry_get_text (GTK_ENTRY (fpd->desktop_entry));
1244 char *new_caption = gtk_entry_get_text (GTK_ENTRY (fpd->caption_entry));
1246 gnome_metadata_set (fpd->file_name, "desktop-url",
1247 strlen (new_desktop_url)+1, new_desktop_url);
1248 gnome_metadata_set (fpd->file_name, "icon-caption",
1249 strlen (new_caption)+1, new_caption);
1252 if (!fpd->can_set_icon)
1253 return 1;
1254 /* And finally, we set the metadata on the icon filename */
1255 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))));*/
1256 icon_name = gicon_image_to_name (fpd->im);
1257 if (text) {
1258 if (strcmp (text, icon_name))
1259 /* FIXME: We make a big assumption here. If the file doesn't exist, it will
1260 * default to the basic icon. We prolly should check that this is a valid
1261 * file here, but I'm too tired to do it now -- jrb */
1262 gnome_metadata_set (fpd->file_name, "icon-filename", strlen (text) + 1, text);
1263 else {
1264 /* If text is equal to icon_name it means the user did not
1265 * touch it, not that he did remove it
1268 gnome_metadata_remove (fpd->file_name, "icon-filename");
1272 /* I suppose we should only do this if we know there's been a change -- I'll try to figure it
1273 * out later if it turns out to be important. */
1274 return 1;
1277 /* This function will apply what changes it can do. It is meant to be used in conjunction
1278 * with a gnome_dialog_run_and_hide. Please note that doing a gnome_dialog_run
1279 * will (obviously) cause greivious bogoness. */
1281 gint
1282 gnome_file_property_dialog_make_changes (GnomeFilePropertyDialog *file_property_dialog)
1284 gint retval = 0;
1285 g_return_val_if_fail (file_property_dialog != NULL, 1);
1286 g_return_val_if_fail (GNOME_IS_FILE_PROPERTY_DIALOG (file_property_dialog), 1);
1288 retval += apply_mode_change (file_property_dialog);
1289 retval += apply_uid_group_change (file_property_dialog);
1290 retval += apply_name_change (file_property_dialog);
1291 retval += apply_metadata_change (file_property_dialog);
1293 return retval;