Added cs to the list of languages
[midnight-commander.git] / gnome / gdialogs.c
blob6282078b77888efd7666bda3e00d0b0ee66a2aa6
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2 /* New dialogs... */
3 #include <config.h>
4 #include "panel.h"
5 #include <gnome.h>
6 #include "global.h"
7 #include "file.h"
8 #include "filegui.h"
9 #include "fileopctx.h"
10 #include "eregex.h"
11 #include "../vfs/vfs.h"
13 enum {
14 REPLACE_PROMPT,
15 REPLACE_ALWAYS,
16 REPLACE_UPDATE,
17 REPLACE_NEVER,
18 REPLACE_ABORT,
19 REPLACE_SIZE,
20 REPLACE_OPTION_MENU
21 } FileReplaceCode;
23 /* This structure describes the UI and internal data required by a file
24 * operation context.
26 typedef struct {
27 /* The progress window */
28 GtkWidget *op_win;
30 /* Set to FALSE in file_op_context_create_ui, set on the cancel_cb if
31 * user click on Cancel.
33 gboolean aborting;
35 /* Source file label */
36 GtkWidget *op_source_label;
38 /* Target file label */
39 GtkWidget *op_target_label;
41 /* File number label */
42 GtkObject *count_label;
44 /* Current file label */
45 GtkWidget *file_label;
47 /* Bytes progress bar */
48 GtkObject *byte_prog;
50 /* Copy status in query replace dialog */
51 int copy_status;
52 int minor_copy_status;
54 /* Overwrite toggle */
55 GtkWidget *op_radio;
56 } FileOpContextUI;
58 static char *gdialog_to_string = N_("To: ");
59 static char *gdialog_from_string = N_("Copying from: ");
60 static char *gdialog_deleting_string = N_("Deleting file: ");
62 #define GDIALOG_PROGRESS_WIDTH 350
64 /* Callbacks go here... */
65 static void
66 fmd_check_box_callback (GtkWidget *widget, gpointer data)
68 if (data)
69 *((gint*)data) = GTK_TOGGLE_BUTTON (widget)->active;
72 static gchar *
73 trim_file_name (FileOpContextUI *ui, gchar *path, gint length, gint cur_length)
75 static gint dotdotdot = 0;
76 gchar *path_copy = NULL;
77 gint len;
79 if (!dotdotdot)
80 dotdotdot = gdk_string_width (ui->op_source_label->style->font, "...");
81 /* Cut the font length of path to length. */
83 length -= dotdotdot;
84 len = (gint) ((1.0 - (gfloat) length / (gfloat) cur_length) * strlen (path));
86 /* we guess a starting point */
87 if (gdk_string_width (ui->op_source_label->style->font, path + len) < length) {
88 while (gdk_string_width (ui->op_source_label->style->font, path + len) < length)
89 len --;
90 len++;
91 } else {
92 while (gdk_string_width (ui->op_source_label->style->font, path + len) > length)
93 len ++;
95 path_copy = g_strdup_printf ("...%s", path + len);
96 return path_copy;
99 FileProgressStatus
100 file_progress_show_source (FileOpContext *ctx, char *path)
102 static gint from_width = 0;
103 FileOpContextUI *ui;
104 gint path_width;
105 gchar *path_copy = NULL;
107 g_return_val_if_fail (ctx != NULL, FILE_CONT);
108 g_return_val_if_fail (ctx->ui != NULL, FILE_CONT);
110 ui = ctx->ui;
112 g_return_val_if_fail (ui->op_source_label != NULL, FILE_CONT);
114 if (ui->aborting)
115 return FILE_ABORT;
117 if (path == NULL){
118 gtk_label_set_text (GTK_LABEL (ui->op_source_label), "");
119 return FILE_CONT;
122 if (!from_width){
123 from_width = gdk_string_width (ui->op_source_label->style->font,
124 _(gdialog_from_string));
126 path_width = gdk_string_width (ui->op_source_label->style->font, path);
127 if (from_width + path_width < GDIALOG_PROGRESS_WIDTH)
128 gtk_label_set_text (GTK_LABEL (ui->op_source_label), path);
129 else {
130 path_copy = trim_file_name (ui, path, GDIALOG_PROGRESS_WIDTH - from_width,
131 path_width);
133 gtk_label_set_text (GTK_LABEL (ui->op_source_label), path_copy);
134 g_free (path_copy);
137 return FILE_CONT;
140 FileProgressStatus
141 file_progress_show_target (FileOpContext *ctx, char *path)
143 static gint to_width = 0;
144 FileOpContextUI *ui;
145 gint path_width;
146 gchar *path_copy = NULL;
148 g_return_val_if_fail (ctx != NULL, FILE_CONT);
149 g_return_val_if_fail (ctx->ui != NULL, FILE_CONT);
151 ui = ctx->ui;
153 g_return_val_if_fail (ui->op_target_label != NULL, FILE_CONT);
155 if (ui->aborting)
156 return FILE_ABORT;
158 if (path == NULL){
159 gtk_label_set_text (GTK_LABEL (ui->op_target_label), "");
160 return FILE_CONT;
163 if (!to_width)
164 to_width = gdk_string_width (ui->op_target_label->style->font,
165 _(gdialog_to_string));
166 path_width = gdk_string_width (ui->op_target_label->style->font, path);
167 if (to_width + path_width < GDIALOG_PROGRESS_WIDTH)
168 gtk_label_set_text (GTK_LABEL (ui->op_target_label), path);
169 else {
170 path_copy = trim_file_name (ui, path, GDIALOG_PROGRESS_WIDTH - to_width, path_width);
171 gtk_label_set_text (GTK_LABEL (ui->op_target_label), path_copy);
172 g_free (path_copy);
175 return FILE_CONT;
178 FileProgressStatus
179 file_progress_show_deleting (FileOpContext *ctx, char *path)
181 static gint deleting_width = 0;
182 FileOpContextUI *ui;
183 gint path_width;
184 gchar *path_copy = NULL;
186 g_return_val_if_fail (ctx != NULL, FILE_CONT);
187 g_return_val_if_fail (ctx->ui != NULL, FILE_CONT);
189 ui = ctx->ui;
191 if (ui->aborting)
192 return FILE_ABORT;
194 if (path == NULL){
195 gtk_label_set_text (GTK_LABEL (ui->op_source_label), "");
196 return FILE_CONT;
199 if (!deleting_width){
200 deleting_width = gdk_string_width (ui->op_source_label->style->font,
201 _(gdialog_deleting_string));
203 path_width = gdk_string_width (ui->op_source_label->style->font, path);
204 if (deleting_width + path_width < GDIALOG_PROGRESS_WIDTH)
205 gtk_label_set_text (GTK_LABEL (ui->op_source_label), path);
206 else {
207 path_copy = trim_file_name (ui, path, GDIALOG_PROGRESS_WIDTH - deleting_width,
208 path_width);
210 gtk_label_set_text (GTK_LABEL (ui->op_source_label), path_copy);
211 g_free (path_copy);
213 return FILE_CONT;
216 FileProgressStatus
217 file_progress_show (FileOpContext *ctx, long done, long total)
219 static gchar count[10];
220 FileOpContextUI *ui;
222 g_return_val_if_fail (ctx != NULL, FILE_CONT);
223 g_return_val_if_fail (ctx->ui != NULL, FILE_CONT);
225 ui = ctx->ui;
227 if (ui->aborting)
228 return FILE_ABORT;
230 snprintf (count, 9, "%d%%", (gint)(100.0 *(gfloat)done/(gfloat)total));
231 gtk_label_set_text (GTK_LABEL (ui->file_label), count);
232 while (gtk_events_pending ())
233 gtk_main_iteration ();
234 return FILE_CONT;
237 FileProgressStatus
238 file_progress_show_count (FileOpContext *ctx, long done, long total)
240 static gchar count[14]; /* that's a lot of files... */
241 FileOpContextUI *ui;
243 g_return_val_if_fail (ctx != NULL, FILE_CONT);
244 g_return_val_if_fail (ctx->ui != NULL, FILE_CONT);
246 ui = ctx->ui;
248 if (ui->aborting)
249 return FILE_ABORT;
251 snprintf (count, 13, "%d/%d", done, total);
252 gtk_label_set_text (GTK_LABEL (ui->count_label), count);
253 while (gtk_events_pending ())
254 gtk_main_iteration ();
255 return FILE_CONT;
258 FileProgressStatus
259 file_progress_show_bytes (FileOpContext *ctx, double done, double total)
261 FileOpContextUI *ui;
263 g_return_val_if_fail (ctx != NULL, FILE_CONT);
264 g_return_val_if_fail (ctx->ui != NULL, FILE_CONT);
266 ui = ctx->ui;
268 if (ui->aborting)
269 return FILE_ABORT;
271 if (total == 0.0)
272 gtk_progress_bar_update (GTK_PROGRESS_BAR (ui->byte_prog), 0.0);
273 else
274 gtk_progress_bar_update (GTK_PROGRESS_BAR (ui->byte_prog),
275 (gfloat) done/(gfloat) total);
276 while (gtk_events_pending ())
277 gtk_main_iteration ();
278 return FILE_CONT;
281 static void
282 option_menu_policy_callback (GtkWidget *item, gpointer data)
284 FileOpContextUI *ui;
285 int status;
287 ui = data;
288 status = GPOINTER_TO_INT (gtk_object_get_user_data (GTK_OBJECT (item)));
290 ui->minor_copy_status = status;
291 ui->copy_status = status;
292 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ui->op_radio), TRUE);
295 static void
296 policy_callback (GtkWidget *button, gpointer data)
298 FileOpContextUI *ui;
299 int status;
301 ui = data;
302 status = GPOINTER_TO_INT (gtk_object_get_user_data (GTK_OBJECT (button)));
304 if (GTK_TOGGLE_BUTTON (button)->active) {
305 if (status == REPLACE_OPTION_MENU) {
306 ui->copy_status = ui->minor_copy_status;
307 } else
308 ui->copy_status = status;
312 FileProgressStatus
313 file_progress_query_replace_policy (FileOpContext *ctx, gboolean dialog_needed)
315 FileOpContextUI *ui;
316 GtkWidget *qrp_dlg;
317 GtkWidget *radio;
318 GtkWidget *vbox;
319 GtkWidget *hbox;
320 GtkWidget *icon;
321 GtkWidget *label;
322 GtkWidget *hrbox;
323 GSList *group = NULL;
324 GtkWidget *omenu;
325 GtkWidget *menu;
326 GtkWidget *menu_item;
328 g_return_val_if_fail (ctx != NULL, FILE_CONT);
329 g_return_val_if_fail (ctx->ui != NULL, FILE_CONT);
331 ui = ctx->ui;
333 if (ui->aborting)
334 return FILE_ABORT;
336 ui->copy_status = REPLACE_PROMPT;
337 if (dialog_needed == FALSE)
338 return FILE_CONT;
339 ui->minor_copy_status = REPLACE_ALWAYS;
340 qrp_dlg = gnome_dialog_new (_("Files Exist"),
341 GNOME_STOCK_BUTTON_OK,
342 GNOME_STOCK_BUTTON_CANCEL,
343 NULL);
344 gtk_window_set_position (GTK_WINDOW (qrp_dlg), GTK_WIN_POS_MOUSE);
345 vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
346 hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
347 icon = gnome_stock_pixmap_widget (hbox, GNOME_STOCK_PIXMAP_HELP);
349 gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
350 gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, GNOME_PAD_SMALL);
352 label = gtk_label_new (_("Some of the files you are trying to copy already "
353 "exist in the destination folder."));
354 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
355 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
356 gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
358 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
359 gtk_box_pack_start (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, FALSE, 0);
361 radio = gtk_radio_button_new_with_label (group, _("Prompt me before overwriting any file."));
362 gtk_object_set_user_data (GTK_OBJECT (radio), GINT_TO_POINTER (REPLACE_PROMPT));
363 gtk_signal_connect (GTK_OBJECT (radio), "toggled",
364 GTK_SIGNAL_FUNC (policy_callback), ui);
365 gtk_box_pack_start (GTK_BOX (vbox), radio, FALSE, FALSE, 0);
366 group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio));
368 radio = gtk_radio_button_new_with_label (group, _("Don't overwrite any files."));
369 gtk_object_set_user_data (GTK_OBJECT (radio), GINT_TO_POINTER (REPLACE_NEVER));
370 gtk_signal_connect (GTK_OBJECT (radio), "toggled",
371 GTK_SIGNAL_FUNC (policy_callback), ui);
372 gtk_box_pack_start (GTK_BOX (vbox), radio, FALSE, FALSE, 0);
373 group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio));
375 ui->op_radio = gtk_radio_button_new (group);
376 gtk_object_set_user_data (GTK_OBJECT (ui->op_radio), GINT_TO_POINTER (REPLACE_OPTION_MENU));
377 gtk_signal_connect (GTK_OBJECT (ui->op_radio), "toggled",
378 GTK_SIGNAL_FUNC (policy_callback), ui);
379 hrbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
380 gtk_box_pack_start (GTK_BOX (hrbox), gtk_label_new (_("Overwrite:")), FALSE, FALSE, 0);
382 /* we set up the option menu. */
383 omenu = gtk_option_menu_new ();
384 gtk_box_pack_start (GTK_BOX (hrbox), omenu, FALSE, FALSE, 0);
385 menu = gtk_menu_new ();
387 menu_item = gtk_menu_item_new_with_label ( _("Older files."));
388 gtk_menu_append (GTK_MENU (menu), menu_item);
389 gtk_object_set_user_data (GTK_OBJECT (menu_item), GINT_TO_POINTER (REPLACE_UPDATE));
390 gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
391 GTK_SIGNAL_FUNC (option_menu_policy_callback), ui);
393 menu_item = gtk_menu_item_new_with_label ( _("Files only if size differs."));
394 gtk_menu_append (GTK_MENU (menu), menu_item);
395 gtk_object_set_user_data (GTK_OBJECT (menu_item), GINT_TO_POINTER (REPLACE_SIZE));
396 gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
397 GTK_SIGNAL_FUNC (option_menu_policy_callback), ui);
399 menu_item = gtk_menu_item_new_with_label ( _("All files."));
400 gtk_menu_append (GTK_MENU (menu), menu_item);
401 gtk_object_set_user_data (GTK_OBJECT (menu_item), GINT_TO_POINTER (REPLACE_ALWAYS));
402 gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
403 GTK_SIGNAL_FUNC (option_menu_policy_callback), ui);
405 gtk_widget_show_all (menu);
406 gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
408 gtk_signal_connect (GTK_OBJECT (ui->op_radio), "toggled",
409 GTK_SIGNAL_FUNC (policy_callback), (gpointer) REPLACE_ALWAYS);
410 gtk_box_pack_start (GTK_BOX (vbox), ui->op_radio, FALSE, FALSE, 0);
411 group = gtk_radio_button_group (GTK_RADIO_BUTTON (ui->op_radio));
412 gtk_container_add (GTK_CONTAINER (ui->op_radio), hrbox);
414 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (qrp_dlg)->vbox),
415 hbox, FALSE, FALSE, 0);
417 gtk_widget_show_all (GTK_WIDGET (GNOME_DIALOG (qrp_dlg)->vbox));
418 switch (gnome_dialog_run_and_close (GNOME_DIALOG (qrp_dlg))) {
419 case 0:
420 break;
421 case -1:
422 default:
423 ui->copy_status = REPLACE_ABORT;
424 return FILE_ABORT;
426 return FILE_CONT;
429 FileProgressStatus
430 file_progress_real_query_replace (FileOpContext *ctx, enum OperationMode mode, char *destname,
431 struct stat *_s_stat, struct stat *_d_stat)
433 FileOpContextUI *ui;
434 GtkWidget *qr_dlg;
435 gchar msg[128];
436 GtkWidget *label;
438 g_return_val_if_fail (ctx != NULL, FILE_CONT);
439 g_return_val_if_fail (ctx->ui != NULL, FILE_CONT);
441 ui = ctx->ui;
443 if (ui->aborting)
444 return FILE_ABORT;
446 /* so what's the situation? Do we prompt or don't we prompt. */
447 if (ui->copy_status == REPLACE_PROMPT){
448 qr_dlg = gnome_dialog_new (_("File Exists"),
449 GNOME_STOCK_BUTTON_YES,
450 GNOME_STOCK_BUTTON_NO,
451 GNOME_STOCK_BUTTON_CANCEL, NULL);
453 gtk_window_set_position (GTK_WINDOW (qr_dlg), GTK_WIN_POS_MOUSE);
454 snprintf (msg, sizeof (msg)-1, _("The target file already exists: %s"), destname);
455 label = gtk_label_new (msg);
456 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
457 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
458 gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
459 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (qr_dlg)->vbox),
460 label, FALSE, FALSE, 0);
461 label = gtk_label_new (_("Replace it?"));
462 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
463 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
464 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (qr_dlg)->vbox),
465 label, FALSE, FALSE, 0);
466 gtk_widget_show_all (GNOME_DIALOG (qr_dlg)->vbox);
467 switch (gnome_dialog_run_and_close (GNOME_DIALOG (qr_dlg))) {
468 case 0:
469 return FILE_CONT;
470 case 1:
471 return FILE_SKIP;
472 default:
473 return FILE_ABORT;
477 switch (ui->copy_status){
478 case REPLACE_UPDATE:
479 if (_s_stat->st_mtime > _d_stat->st_mtime)
480 return FILE_CONT;
481 else
482 return FILE_SKIP;
483 case REPLACE_SIZE:
484 if (_s_stat->st_size == _d_stat->st_size)
485 return FILE_SKIP;
486 else
487 return FILE_CONT;
488 case REPLACE_ALWAYS:
489 return FILE_CONT;
490 case REPLACE_NEVER:
491 return FILE_SKIP;
492 case REPLACE_ABORT:
493 default:
494 return FILE_ABORT;
498 void
499 file_progress_set_stalled_label (FileOpContext *ctx, char *stalled_msg)
501 g_return_if_fail (ctx != NULL);
502 g_return_if_fail (ctx->ui != NULL);
504 if (!stalled_msg || !*stalled_msg)
505 return;
506 /* FIXME */
507 g_warning ("FIXME: file_progress_set_stalled_label!\nmsg\t%s\n",stalled_msg);
509 char *
510 file_mask_dialog (FileOpContext *ctx, FileOperation operation, char *text, char *def_text,
511 int only_one, int *do_background)
513 GtkWidget *fmd_win;
514 GtkWidget *notebook;
515 GtkWidget *hbox;
516 GtkWidget *vbox, *label;
517 GtkWidget *alignment;
518 GtkWidget *fentry;
519 GtkWidget *cbox;
520 GtkWidget *icon;
521 int source_easy_patterns = easy_patterns;
522 char *source_mask, *orig_mask, *dest_dir;
523 const char *error;
524 struct stat buf;
526 g_return_val_if_fail (ctx != NULL, NULL);
528 ctx->stable_symlinks = 0;
530 /* Basic window */
531 if (operation == OP_COPY)
532 fmd_win = gnome_dialog_new (_("Copy"), GNOME_STOCK_BUTTON_OK,
533 GNOME_STOCK_BUTTON_CANCEL, NULL);
534 else if (operation == OP_MOVE)
535 fmd_win = gnome_dialog_new (_("Move"), GNOME_STOCK_BUTTON_OK,
536 GNOME_STOCK_BUTTON_CANCEL, NULL);
538 gtk_window_set_position (GTK_WINDOW (fmd_win), GTK_WIN_POS_MOUSE);
540 hbox = gtk_hbox_new (FALSE, GNOME_PAD);
541 notebook = gtk_notebook_new ();
542 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (fmd_win)->vbox),
543 notebook, FALSE, FALSE, 0);
544 /*FIXME: I wan't a bigger, badder, better Icon here... */
545 icon = gnome_stock_pixmap_widget (hbox, GNOME_STOCK_PIXMAP_HELP);
546 gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
547 vbox = gtk_vbox_new (FALSE, GNOME_PAD);
548 gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
549 gtk_container_set_border_width (GTK_CONTAINER (vbox), GNOME_PAD);
550 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
551 hbox,
552 gtk_label_new (_("Destination")));
553 alignment = gtk_alignment_new (0.0, 0.5, 0, 0);
554 label = gtk_label_new (text);
555 gtk_container_add (GTK_CONTAINER (alignment), label);
556 fentry = gnome_file_entry_new ("gmc-copy-file", _("Find Destination Folder"));
557 gnome_file_entry_set_directory (GNOME_FILE_ENTRY (fentry), TRUE);
558 gtk_entry_set_text (GTK_ENTRY (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (fentry))),
559 def_text);
560 gnome_file_entry_set_default_path (GNOME_FILE_ENTRY (fentry), def_text);
561 cbox = gtk_check_button_new_with_label (_("Copy as a background process"));
562 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cbox), *do_background);
563 gtk_signal_connect (GTK_OBJECT (cbox), "toggled", (GtkSignalFunc) fmd_check_box_callback, do_background);
564 #if 0
565 gnome_widget_add_help (cbox, "Selecting this will run the copying in the background. "
566 "This is useful for transfers over networks that might take a long "
567 "time to complete.");
568 #endif
569 gtk_box_pack_end (GTK_BOX (vbox), cbox, FALSE, FALSE, 0);
570 gtk_box_pack_end (GTK_BOX (vbox), gtk_hseparator_new (), FALSE, FALSE, 0);
571 gtk_box_pack_end (GTK_BOX (vbox), fentry, FALSE, FALSE, 0);
572 gnome_file_entry_set_modal(GNOME_FILE_ENTRY (fentry),TRUE);
574 gtk_box_pack_end (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
576 /* Advanced Options */
577 hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
578 vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
579 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
580 hbox,
581 gtk_label_new (_("Advanced Options")));
582 gtk_container_set_border_width (GTK_CONTAINER (hbox), GNOME_PAD);
583 gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
585 cbox = gtk_check_button_new_with_label (_("Preserve symlinks"));
586 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cbox), ctx->stable_symlinks);
587 gtk_signal_connect (GTK_OBJECT (cbox), "toggled",
588 (GtkSignalFunc) fmd_check_box_callback, &ctx->stable_symlinks);
589 #if 0
590 gnome_widget_add_help (cbox, "FIXME: Add something here Miguel");
591 #endif
592 gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, FALSE, 0);
594 if (operation == OP_COPY) {
595 cbox = gtk_check_button_new_with_label (_("Follow links."));
596 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cbox), ctx->follow_links);
597 gtk_signal_connect (GTK_OBJECT (cbox), "toggled",
598 (GtkSignalFunc) fmd_check_box_callback, &ctx->follow_links);
599 gnome_widget_add_help (cbox,
600 _("Selecting this will copy the files that symlinks point "
601 "to instead of just copying the link."));
602 gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, FALSE, 0);
604 cbox = gtk_check_button_new_with_label (_("Preserve file attributes."));
605 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cbox), ctx->op_preserve);
606 gtk_signal_connect (GTK_OBJECT (cbox), "toggled",
607 (GtkSignalFunc) fmd_check_box_callback, &ctx->op_preserve);
608 gnome_widget_add_help (cbox, _("Preserves the permissions and the UID/GID if possible"));
609 gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, FALSE, 0);
611 vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
612 gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
613 cbox = gtk_check_button_new_with_label (_("Recursively copy subdirectories."));
614 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cbox), ctx->dive_into_subdirs);
615 gtk_signal_connect (GTK_OBJECT (cbox), "toggled",
616 (GtkSignalFunc) fmd_check_box_callback, &ctx->dive_into_subdirs);
617 gnome_widget_add_help (cbox, _("If set, this will copy the directories recursively"));
618 gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, FALSE, 0);
621 gtk_widget_show_all (GNOME_DIALOG (fmd_win)->vbox);
622 gtk_window_set_modal (GTK_WINDOW (fmd_win), FALSE);
623 gnome_dialog_set_close (GNOME_DIALOG (fmd_win), TRUE);
624 gnome_dialog_close_hides (GNOME_DIALOG (fmd_win), TRUE);
626 /* Off to the races!!! */
627 if (gnome_dialog_run (GNOME_DIALOG (fmd_win)) == 1) {
628 gtk_widget_destroy (fmd_win);
629 return NULL;
632 dest_dir = gnome_file_entry_get_full_path(GNOME_FILE_ENTRY (fentry), TRUE);
633 gtk_widget_destroy (fmd_win);
634 easy_patterns = 1;
635 if (!dest_dir || !*dest_dir)
636 return NULL;
638 if (ctx->follow_links && operation != OP_MOVE)
639 ctx->stat_func = mc_stat;
640 else
641 ctx->stat_func = mc_lstat;
643 if (ctx->op_preserve || operation == OP_MOVE){
644 ctx->preserve = 1;
645 ctx->umask_kill = 0777777;
646 ctx->preserve_uidgid = (geteuid () == 0) ? 1 : 0;
647 } else {
648 int i;
649 ctx->preserve = ctx->preserve_uidgid = 0;
650 i = umask (0);
651 umask (i);
652 ctx->umask_kill = i ^ 0777777;
654 source_mask = g_strdup ("*");
655 orig_mask = source_mask;
656 if (!dest_dir || !*dest_dir){
657 if (source_mask)
658 g_free (source_mask);
659 return dest_dir;
662 if (!dest_dir)
663 return NULL;
665 if (!*dest_dir) {
666 g_free (dest_dir);
667 return NULL;
670 if (source_easy_patterns) {
671 source_easy_patterns = easy_patterns;
672 easy_patterns = 1;
673 source_mask = convert_pattern (source_mask, match_file, 1);
674 easy_patterns = source_easy_patterns;
675 error = re_compile_pattern (source_mask, strlen (source_mask), &ctx->rx);
676 g_free (source_mask);
677 } else
678 error = re_compile_pattern (source_mask, strlen (source_mask), &ctx->rx);
680 if (error)
681 g_warning ("%s\n",error);
683 if (orig_mask)
684 g_free (orig_mask);
685 ctx->dest_mask = strrchr (dest_dir, PATH_SEP);
686 if (ctx->dest_mask == NULL)
687 ctx->dest_mask = dest_dir;
688 else
689 ctx->dest_mask++;
690 orig_mask = ctx->dest_mask;
691 if (!*ctx->dest_mask || (!ctx->dive_into_subdirs && !is_wildcarded (ctx->dest_mask) &&
692 (!only_one || (!mc_stat (dest_dir, &buf)
693 && S_ISDIR (buf.st_mode)))) ||
694 (ctx->dive_into_subdirs && ((!only_one && !is_wildcarded (ctx->dest_mask)) ||
695 (only_one && !mc_stat (dest_dir, &buf)
696 && S_ISDIR (buf.st_mode)))))
697 ctx->dest_mask = g_strdup ("*");
698 else {
699 ctx->dest_mask = g_strdup (ctx->dest_mask);
700 *orig_mask = 0;
702 if (!*dest_dir){
703 g_free (dest_dir);
704 dest_dir = g_strdup ("./");
706 return dest_dir;
709 static void
710 cancel_cb (GtkWidget *widget, gpointer data)
712 FileOpContextUI *ui;
714 ui = data;
715 ui->aborting = TRUE;
718 void
719 file_op_context_create_ui (FileOpContext *ctx, FileOperation op, int with_eta)
721 FileOpContextUI *ui;
722 GtkWidget *alignment;
723 GtkWidget *hbox;
725 g_return_if_fail (ctx != NULL);
726 g_return_if_fail (ctx->ui == NULL);
728 ui = g_new0 (FileOpContextUI, 1);
729 ctx->ui = ui;
731 switch (op) {
732 case OP_MOVE:
733 ui->op_win = gnome_dialog_new (_("Move Progress"), GNOME_STOCK_BUTTON_CANCEL, NULL);
734 break;
735 case OP_COPY:
736 ui->op_win = gnome_dialog_new (_("Copy Progress"), GNOME_STOCK_BUTTON_CANCEL, NULL);
737 break;
738 case OP_DELETE:
739 ui->op_win = gnome_dialog_new (_("Delete Progress"), GNOME_STOCK_BUTTON_CANCEL, NULL);
740 break;
742 gtk_window_set_position (GTK_WINDOW (ui->op_win), GTK_WIN_POS_MOUSE);
744 gnome_dialog_button_connect (GNOME_DIALOG (ui->op_win), 0,
745 GTK_SIGNAL_FUNC (cancel_cb), ui);
747 if (op != OP_DELETE) {
748 alignment = gtk_alignment_new (0.0, 0.5, 0, 0);
749 hbox = gtk_hbox_new (FALSE, 0);
750 gtk_container_add (GTK_CONTAINER (alignment), hbox);
751 gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_(gdialog_from_string)), FALSE, FALSE, 0);
752 ui->op_source_label = gtk_label_new ("");
754 gtk_box_pack_start (GTK_BOX (hbox), ui->op_source_label, FALSE, FALSE, 0);
755 gtk_box_set_spacing (GTK_BOX (GNOME_DIALOG (ui->op_win)->vbox), GNOME_PAD_SMALL);
756 gtk_container_set_border_width (GTK_CONTAINER (GNOME_DIALOG (ui->op_win)->vbox), GNOME_PAD);
757 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (ui->op_win)->vbox),
758 alignment, FALSE, FALSE, 0);
760 alignment = gtk_alignment_new (0.0, 0.5, 0, 0);
761 hbox = gtk_hbox_new (FALSE, 0);
762 gtk_container_add (GTK_CONTAINER (alignment), hbox);
763 gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_(gdialog_to_string)), FALSE, FALSE, 0);
764 ui->op_target_label = gtk_label_new ("");
765 gtk_box_pack_start (GTK_BOX (hbox), ui->op_target_label, FALSE, FALSE, 0);
766 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (ui->op_win)->vbox),
767 alignment, FALSE, FALSE, 0);
769 } else {
770 alignment = gtk_alignment_new (0.0, 0.5, 0, 0);
771 hbox = gtk_hbox_new (FALSE, 0);
772 gtk_container_add (GTK_CONTAINER (alignment), hbox);
773 gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_(gdialog_deleting_string)), FALSE, FALSE, 0);
774 ui->op_source_label = gtk_label_new ("");
776 gtk_box_pack_start (GTK_BOX (hbox), ui->op_source_label, FALSE, FALSE, 0);
777 gtk_box_set_spacing (GTK_BOX (GNOME_DIALOG (ui->op_win)->vbox), GNOME_PAD_SMALL);
778 gtk_container_set_border_width (GTK_CONTAINER (GNOME_DIALOG (ui->op_win)->vbox), GNOME_PAD);
779 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (ui->op_win)->vbox),
780 alignment, FALSE, FALSE, 0);
782 alignment = gtk_alignment_new (0.0, 0.5, 0, 0);
783 hbox = gtk_hbox_new (FALSE, 0);
784 gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("File ")), FALSE, FALSE, 0);
785 ui->count_label = GTK_OBJECT (gtk_label_new (""));
786 gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (ui->count_label), FALSE, FALSE, 0);
788 gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_(" is ")), FALSE, FALSE, 0);
789 ui->file_label = gtk_label_new ("");
790 gtk_box_pack_start (GTK_BOX (hbox), ui->file_label, FALSE, FALSE, 0);
791 gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_(" Done.")), FALSE, FALSE, 0);
792 gtk_container_add (GTK_CONTAINER (alignment), hbox);
794 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (ui->op_win)->vbox),
795 alignment, FALSE, FALSE, 0);
797 ui->byte_prog = GTK_OBJECT (gtk_progress_bar_new ());
798 gtk_widget_set_usize (GTK_WIDGET (ui->byte_prog), GDIALOG_PROGRESS_WIDTH, -1);
799 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (ui->op_win)->vbox),
800 GTK_WIDGET (ui->byte_prog), FALSE, FALSE, 0);
802 /*done with things */
803 gtk_widget_show_all (GNOME_DIALOG (ui->op_win)->vbox);
804 gtk_widget_show_now (ui->op_win);
807 void
808 file_op_context_destroy_ui (FileOpContext *ctx)
810 FileOpContextUI *ui;
812 g_return_if_fail (ctx != NULL);
813 g_return_if_fail (ctx->ui != NULL);
815 ui = ctx->ui;
817 gtk_widget_destroy (ui->op_win);
819 g_free (ui);
820 ctx->ui = NULL;
823 void
824 fmd_init_i18n (int force)
826 /* unneccessary func */