1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
10 #include "fileopctx.h"
13 #include "../vfs/vfs.h"
25 /* This structure describes the UI and internal data required by a file
29 /* The progress window */
32 /* Set to FALSE in file_op_context_create_ui, set on the cancel_cb if
33 * user click on Cancel.
37 /* Source file label */
38 GtkWidget
*op_source_label
;
40 /* Target file label */
41 GtkWidget
*op_target_label
;
43 /* File number label */
44 GtkObject
*count_label
;
46 /* Current file label */
47 GtkWidget
*file_label
;
49 /* Bytes progress bar */
52 /* Copy status in query replace dialog */
54 int minor_copy_status
;
56 /* Overwrite toggle */
60 static char *gdialog_to_string
= N_("To: ");
61 static char *gdialog_from_string
= N_("Copying from: ");
62 static char *gdialog_deleting_string
= N_("Deleting file: ");
64 #define GDIALOG_PROGRESS_WIDTH 350
66 /* Callbacks go here... */
68 fmd_check_box_callback (GtkWidget
*widget
, gpointer data
)
71 *((gint
*)data
) = GTK_TOGGLE_BUTTON (widget
)->active
;
75 trim_file_name (FileOpContextUI
*ui
, gchar
*path
, gint length
, gint cur_length
)
77 static gint dotdotdot
= 0;
78 gchar
*path_copy
= NULL
;
82 dotdotdot
= gdk_string_width (ui
->op_source_label
->style
->font
, "...");
83 /* Cut the font length of path to length. */
86 len
= (gint
) ((1.0 - (gfloat
) length
/ (gfloat
) cur_length
) * strlen (path
));
88 /* we guess a starting point */
89 if (gdk_string_width (ui
->op_source_label
->style
->font
, path
+ len
) < length
) {
90 while (gdk_string_width (ui
->op_source_label
->style
->font
, path
+ len
) < length
)
94 while (gdk_string_width (ui
->op_source_label
->style
->font
, path
+ len
) > length
)
98 path_copy
= g_strdup_printf ("...%s", path
+ len
);
103 file_progress_show_source (FileOpContext
*ctx
, char *path
)
105 static gint from_width
= 0;
108 gchar
*path_copy
= NULL
;
110 g_return_val_if_fail (ctx
!= NULL
, FILE_CONT
);
112 /* ctx->ui might be NULL for background processes */
118 g_return_val_if_fail (ui
->op_source_label
!= NULL
, FILE_CONT
);
124 gtk_label_set_text (GTK_LABEL (ui
->op_source_label
), "");
129 from_width
= gdk_string_width (ui
->op_source_label
->style
->font
,
130 _(gdialog_from_string
));
132 path_width
= gdk_string_width (ui
->op_source_label
->style
->font
, path
);
133 if (from_width
+ path_width
< GDIALOG_PROGRESS_WIDTH
)
134 gtk_label_set_text (GTK_LABEL (ui
->op_source_label
), path
);
136 path_copy
= trim_file_name (ui
, path
, GDIALOG_PROGRESS_WIDTH
- from_width
,
139 gtk_label_set_text (GTK_LABEL (ui
->op_source_label
), path_copy
);
147 file_progress_show_target (FileOpContext
*ctx
, char *path
)
149 static gint to_width
= 0;
152 gchar
*path_copy
= NULL
;
154 g_return_val_if_fail (ctx
!= NULL
, FILE_CONT
);
155 /* ctx->ui might be NULL for background processes */
161 g_return_val_if_fail (ui
->op_target_label
!= NULL
, FILE_CONT
);
167 gtk_label_set_text (GTK_LABEL (ui
->op_target_label
), "");
172 to_width
= gdk_string_width (ui
->op_target_label
->style
->font
,
173 _(gdialog_to_string
));
174 path_width
= gdk_string_width (ui
->op_target_label
->style
->font
, path
);
175 if (to_width
+ path_width
< GDIALOG_PROGRESS_WIDTH
)
176 gtk_label_set_text (GTK_LABEL (ui
->op_target_label
), path
);
178 path_copy
= trim_file_name (ui
, path
, GDIALOG_PROGRESS_WIDTH
- to_width
, path_width
);
179 gtk_label_set_text (GTK_LABEL (ui
->op_target_label
), path_copy
);
187 file_progress_show_deleting (FileOpContext
*ctx
, char *path
)
189 static gint deleting_width
= 0;
192 gchar
*path_copy
= NULL
;
194 g_return_val_if_fail (ctx
!= NULL
, FILE_CONT
);
196 /* ctx->ui might be NULL for background processes */
206 gtk_label_set_text (GTK_LABEL (ui
->op_source_label
), "");
210 if (!deleting_width
){
211 deleting_width
= gdk_string_width (ui
->op_source_label
->style
->font
,
212 _(gdialog_deleting_string
));
214 path_width
= gdk_string_width (ui
->op_source_label
->style
->font
, path
);
215 if (deleting_width
+ path_width
< GDIALOG_PROGRESS_WIDTH
)
216 gtk_label_set_text (GTK_LABEL (ui
->op_source_label
), path
);
218 path_copy
= trim_file_name (ui
, path
, GDIALOG_PROGRESS_WIDTH
- deleting_width
,
221 gtk_label_set_text (GTK_LABEL (ui
->op_source_label
), path_copy
);
228 file_progress_show (FileOpContext
*ctx
, long done
, long total
)
230 static gchar count
[20];
234 g_return_val_if_fail (ctx
!= NULL
, FILE_CONT
);
236 /* ctx->ui might be NULL for background processes */
246 perc
= (double) done
/ (double) total
;
247 g_snprintf (count
, 9, "%3d%% ", (gint
) (100.0 * perc
));
248 gtk_label_set_text (GTK_LABEL (ui
->file_label
), count
);
250 while (gtk_events_pending ())
251 gtk_main_iteration ();
256 file_progress_show_count (FileOpContext
*ctx
, long done
, long total
)
258 static gchar count
[100];
261 g_return_val_if_fail (ctx
!= NULL
, FILE_CONT
);
263 /* ctx->ui might be NULL for background processes */
272 g_snprintf (count
, 100, "%ld/%ld ", done
, total
);
273 gtk_label_set_text (GTK_LABEL (ui
->count_label
), count
);
274 while (gtk_events_pending ())
275 gtk_main_iteration ();
280 file_progress_show_bytes (FileOpContext
*ctx
, double done
, double total
)
285 g_return_val_if_fail (ctx
!= NULL
, FILE_CONT
);
287 /* ctx->ui might be NULL for background processes */
301 gtk_progress_bar_update (GTK_PROGRESS_BAR (ui
->byte_prog
), CLAMP (perc
, 0.0, 1.0));
303 while (gtk_events_pending ())
304 gtk_main_iteration ();
309 option_menu_policy_callback (GtkWidget
*item
, gpointer data
)
315 status
= GPOINTER_TO_INT (gtk_object_get_user_data (GTK_OBJECT (item
)));
317 ui
->minor_copy_status
= status
;
318 ui
->copy_status
= status
;
319 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ui
->op_radio
), TRUE
);
323 policy_callback (GtkWidget
*button
, gpointer data
)
329 status
= GPOINTER_TO_INT (gtk_object_get_user_data (GTK_OBJECT (button
)));
331 if (GTK_TOGGLE_BUTTON (button
)->active
) {
332 if (status
== REPLACE_OPTION_MENU
) {
333 ui
->copy_status
= ui
->minor_copy_status
;
335 ui
->copy_status
= status
;
340 file_progress_query_replace_policy (FileOpContext
*ctx
, gboolean dialog_needed
)
351 GSList
*group
= NULL
;
354 GtkWidget
*menu_item
;
356 g_return_val_if_fail (ctx
!= NULL
, FILE_CONT
);
358 /* ctx->ui might be NULL for background processes */
367 ui
->copy_status
= REPLACE_PROMPT
;
368 if (dialog_needed
== FALSE
)
370 ui
->minor_copy_status
= REPLACE_ALWAYS
;
371 qrp_dlg
= gnome_dialog_new (_("Files Exist"),
372 GNOME_STOCK_BUTTON_OK
,
373 GNOME_STOCK_BUTTON_CANCEL
,
375 gtk_window_set_position (GTK_WINDOW (qrp_dlg
), GTK_WIN_POS_MOUSE
);
377 hbox
= gtk_hbox_new (FALSE
, GNOME_PAD_SMALL
);
378 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (qrp_dlg
)->vbox
), hbox
, FALSE
, FALSE
, 0);
380 icon
= gnome_stock_pixmap_widget (hbox
, GNOME_STOCK_PIXMAP_HELP
);
381 gtk_box_pack_start (GTK_BOX (hbox
), icon
, FALSE
, FALSE
, 0);
383 vbox
= gtk_vbox_new (FALSE
, GNOME_PAD_SMALL
);
384 gtk_box_pack_start (GTK_BOX (hbox
), vbox
, FALSE
, FALSE
, GNOME_PAD_SMALL
);
386 label
= gtk_label_new (_("Some of the files you are trying to copy already "
387 "exist in the destination folder. Please select "
388 "the action to be performed."));
389 gtk_misc_set_alignment (GTK_MISC (label
), 0.0, 0.5);
390 gtk_label_set_justify (GTK_LABEL (label
), GTK_JUSTIFY_LEFT
);
391 gtk_label_set_line_wrap (GTK_LABEL (label
), TRUE
);
393 gtk_box_pack_start (GTK_BOX (vbox
), label
, FALSE
, FALSE
, 0);
394 gtk_box_pack_start (GTK_BOX (vbox
), gtk_hseparator_new (), FALSE
, FALSE
, 0);
396 vbox2
= gtk_vbox_new (TRUE
, 0);
397 gtk_box_pack_start (GTK_BOX (vbox
), vbox2
, FALSE
, FALSE
, 0);
399 radio
= gtk_radio_button_new_with_label (group
, _("Prompt me before overwriting any file."));
400 gtk_object_set_user_data (GTK_OBJECT (radio
), GINT_TO_POINTER (REPLACE_PROMPT
));
401 gtk_signal_connect (GTK_OBJECT (radio
), "toggled",
402 GTK_SIGNAL_FUNC (policy_callback
), ui
);
403 gtk_box_pack_start (GTK_BOX (vbox2
), radio
, FALSE
, FALSE
, 0);
404 group
= gtk_radio_button_group (GTK_RADIO_BUTTON (radio
));
406 radio
= gtk_radio_button_new_with_label (group
, _("Don't overwrite any files."));
407 gtk_object_set_user_data (GTK_OBJECT (radio
), GINT_TO_POINTER (REPLACE_NEVER
));
408 gtk_signal_connect (GTK_OBJECT (radio
), "toggled",
409 GTK_SIGNAL_FUNC (policy_callback
), ui
);
410 gtk_box_pack_start (GTK_BOX (vbox2
), radio
, FALSE
, FALSE
, 0);
411 group
= gtk_radio_button_group (GTK_RADIO_BUTTON (radio
));
413 ui
->op_radio
= gtk_radio_button_new (group
);
414 gtk_object_set_user_data (GTK_OBJECT (ui
->op_radio
), GINT_TO_POINTER (REPLACE_OPTION_MENU
));
415 gtk_signal_connect (GTK_OBJECT (ui
->op_radio
), "toggled",
416 GTK_SIGNAL_FUNC (policy_callback
), ui
);
417 gtk_box_pack_start (GTK_BOX (vbox2
), ui
->op_radio
, FALSE
, FALSE
, 0);
419 hrbox
= gtk_hbox_new (FALSE
, GNOME_PAD_SMALL
);
420 gtk_container_add (GTK_CONTAINER (ui
->op_radio
), hrbox
);
422 gtk_box_pack_start (GTK_BOX (hrbox
), gtk_label_new (_("Overwrite:")), FALSE
, FALSE
, 0);
424 /* we set up the option menu. */
425 omenu
= gtk_option_menu_new ();
426 gtk_box_pack_start (GTK_BOX (hrbox
), omenu
, FALSE
, FALSE
, 0);
427 menu
= gtk_menu_new ();
429 menu_item
= gtk_menu_item_new_with_label ( _("Older files."));
430 gtk_menu_append (GTK_MENU (menu
), menu_item
);
431 gtk_object_set_user_data (GTK_OBJECT (menu_item
), GINT_TO_POINTER (REPLACE_UPDATE
));
432 gtk_signal_connect (GTK_OBJECT (menu_item
), "activate",
433 GTK_SIGNAL_FUNC (option_menu_policy_callback
), ui
);
435 menu_item
= gtk_menu_item_new_with_label ( _("Files only if size differs."));
436 gtk_menu_append (GTK_MENU (menu
), menu_item
);
437 gtk_object_set_user_data (GTK_OBJECT (menu_item
), GINT_TO_POINTER (REPLACE_SIZE
));
438 gtk_signal_connect (GTK_OBJECT (menu_item
), "activate",
439 GTK_SIGNAL_FUNC (option_menu_policy_callback
), ui
);
441 menu_item
= gtk_menu_item_new_with_label ( _("All files."));
442 gtk_menu_append (GTK_MENU (menu
), menu_item
);
443 gtk_object_set_user_data (GTK_OBJECT (menu_item
), GINT_TO_POINTER (REPLACE_ALWAYS
));
444 gtk_signal_connect (GTK_OBJECT (menu_item
), "activate",
445 GTK_SIGNAL_FUNC (option_menu_policy_callback
), ui
);
447 gtk_widget_show_all (menu
);
448 gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu
), menu
);
450 gtk_widget_show_all (GTK_WIDGET (GNOME_DIALOG (qrp_dlg
)->vbox
));
451 switch (gnome_dialog_run_and_close (GNOME_DIALOG (qrp_dlg
))) {
456 ui
->copy_status
= REPLACE_ABORT
;
463 file_progress_real_query_replace (FileOpContext
*ctx
, enum OperationMode mode
, char *destname
,
464 struct stat
*_s_stat
, struct stat
*_d_stat
)
471 g_return_val_if_fail (ctx
!= NULL
, FILE_CONT
);
472 g_return_val_if_fail (ctx
->ui
!= NULL
, FILE_CONT
);
479 /* so what's the situation? Do we prompt or don't we prompt. */
480 if (ui
->copy_status
== REPLACE_PROMPT
){
481 qr_dlg
= gnome_dialog_new (_("File Exists"),
482 GNOME_STOCK_BUTTON_YES
,
483 GNOME_STOCK_BUTTON_NO
,
484 GNOME_STOCK_BUTTON_CANCEL
, NULL
);
486 gtk_window_set_position (GTK_WINDOW (qr_dlg
), GTK_WIN_POS_MOUSE
);
487 g_snprintf (msg
, sizeof (msg
)-1, _("The target file already exists: %s"), destname
);
488 label
= gtk_label_new (msg
);
489 gtk_label_set_justify (GTK_LABEL (label
), GTK_JUSTIFY_LEFT
);
490 gtk_misc_set_alignment (GTK_MISC (label
), 0.0, 0.5);
491 gtk_label_set_line_wrap (GTK_LABEL (label
), TRUE
);
492 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (qr_dlg
)->vbox
),
493 label
, FALSE
, FALSE
, 0);
494 label
= gtk_label_new (_("Replace it?"));
495 gtk_label_set_justify (GTK_LABEL (label
), GTK_JUSTIFY_LEFT
);
496 gtk_misc_set_alignment (GTK_MISC (label
), 0.0, 0.5);
497 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (qr_dlg
)->vbox
),
498 label
, FALSE
, FALSE
, 0);
499 gtk_widget_show_all (GNOME_DIALOG (qr_dlg
)->vbox
);
500 switch (gnome_dialog_run_and_close (GNOME_DIALOG (qr_dlg
))) {
510 switch (ui
->copy_status
){
512 if (_s_stat
->st_mtime
> _d_stat
->st_mtime
)
517 if (_s_stat
->st_size
== _d_stat
->st_size
)
532 file_progress_set_stalled_label (FileOpContext
*ctx
, char *stalled_msg
)
534 g_return_if_fail (ctx
!= NULL
);
539 if (!stalled_msg
|| !*stalled_msg
)
542 g_warning ("FIXME: file_progress_set_stalled_label!\nmsg\t%s\n",stalled_msg
);
546 file_mask_dialog (FileOpContext
*ctx
, FileOperation operation
, char *text
, char *def_text
,
547 int only_one
, int *do_background
)
552 GtkWidget
*vbox
, *label
;
556 int source_easy_patterns
= easy_patterns
;
557 char *source_mask
, *orig_mask
, *dest_dir
;
562 g_return_val_if_fail (ctx
!= NULL
, NULL
);
564 ctx
->stable_symlinks
= 0;
569 fmd_win
= gnome_dialog_new (_("Copy"), GNOME_STOCK_BUTTON_OK
,
570 GNOME_STOCK_BUTTON_CANCEL
, NULL
);
573 fmd_win
= gnome_dialog_new (_("Move"), GNOME_STOCK_BUTTON_OK
,
574 GNOME_STOCK_BUTTON_CANCEL
, NULL
);
577 g_assert_not_reached ();
578 return NULL
; /* keep -Wall happy */
581 gtk_window_set_position (GTK_WINDOW (fmd_win
), GTK_WIN_POS_MOUSE
);
583 notebook
= gtk_notebook_new ();
584 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (fmd_win
)->vbox
),
585 notebook
, FALSE
, FALSE
, 0);
587 hbox
= gtk_hbox_new (FALSE
, GNOME_PAD
);
588 gtk_notebook_append_page (GTK_NOTEBOOK (notebook
),
590 gtk_label_new (_("Destination")));
592 /* FIXME: I want a bigger, badder, better Icon here... */
593 icon
= gnome_stock_pixmap_widget (hbox
, GNOME_STOCK_PIXMAP_HELP
);
594 gtk_box_pack_start (GTK_BOX (hbox
), icon
, FALSE
, FALSE
, 0);
596 vbox
= gtk_vbox_new (FALSE
, GNOME_PAD
);
597 gtk_box_pack_start (GTK_BOX (hbox
), vbox
, TRUE
, TRUE
, 0);
598 gtk_container_set_border_width (GTK_CONTAINER (vbox
), GNOME_PAD
);
600 label
= gtk_label_new (text
);
601 gtk_misc_set_alignment (GTK_MISC (label
), 0.0, 0.5);
602 gtk_box_pack_start (GTK_BOX (vbox
), label
, FALSE
, FALSE
, 0);
604 fentry
= gnome_file_entry_new ("gmc-copy-file", _("Find Destination Folder"));
605 gnome_file_entry_set_directory (GNOME_FILE_ENTRY (fentry
), TRUE
);
606 gtk_entry_set_text (GTK_ENTRY (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (fentry
))),
608 gnome_file_entry_set_default_path (GNOME_FILE_ENTRY (fentry
), def_text
);
609 gnome_file_entry_set_modal (GNOME_FILE_ENTRY (fentry
), TRUE
);
610 gtk_box_pack_start (GTK_BOX (vbox
), fentry
, FALSE
, FALSE
, 0);
612 /* Background operations are completely hosed, so we olympically disable
613 * them. How's that for foolproof bugfixing.
616 *do_background
= FALSE
;
618 cbox
= gtk_check_button_new_with_label (_("Copy as a background process"));
619 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cbox
), *do_background
);
620 gtk_signal_connect (GTK_OBJECT (cbox
), "toggled",
621 (GtkSignalFunc
) fmd_check_box_callback
, do_background
);
623 gnome_widget_add_help (cbox
, "Selecting this will run the copying in the background. "
624 "This is useful for transfers over networks that might take a long "
625 "time to complete.");
627 gtk_box_pack_end (GTK_BOX (vbox
), cbox
, FALSE
, FALSE
, 0);
628 gtk_box_pack_end (GTK_BOX (vbox
), gtk_hseparator_new (), FALSE
, FALSE
, 0);
631 /* Advanced Options */
632 hbox
= gtk_hbox_new (FALSE
, GNOME_PAD_SMALL
);
633 vbox
= gtk_vbox_new (FALSE
, GNOME_PAD_SMALL
);
634 gtk_notebook_append_page (GTK_NOTEBOOK (notebook
),
636 gtk_label_new (_("Advanced Options")));
637 gtk_container_set_border_width (GTK_CONTAINER (hbox
), GNOME_PAD
);
638 gtk_box_pack_start (GTK_BOX (hbox
), vbox
, TRUE
, TRUE
, 0);
640 cbox
= gtk_check_button_new_with_label (_("Preserve symlinks"));
641 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cbox
), ctx
->stable_symlinks
);
642 gtk_signal_connect (GTK_OBJECT (cbox
), "toggled",
643 (GtkSignalFunc
) fmd_check_box_callback
, &ctx
->stable_symlinks
);
645 gnome_widget_add_help (cbox
, "FIXME: Add something here Miguel");
647 gtk_box_pack_start (GTK_BOX (vbox
), cbox
, FALSE
, FALSE
, 0);
649 if (operation
== OP_COPY
) {
650 cbox
= gtk_check_button_new_with_label (_("Follow links."));
651 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cbox
), ctx
->follow_links
);
652 gtk_signal_connect (GTK_OBJECT (cbox
), "toggled",
653 (GtkSignalFunc
) fmd_check_box_callback
, &ctx
->follow_links
);
655 gnome_widget_add_help (cbox
,
656 _("Selecting this will copy the files that symlinks point "
657 "to instead of just copying the link."));
659 gtk_box_pack_start (GTK_BOX (vbox
), cbox
, FALSE
, FALSE
, 0);
661 cbox
= gtk_check_button_new_with_label (_("Preserve file attributes."));
662 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cbox
), ctx
->op_preserve
);
663 gtk_signal_connect (GTK_OBJECT (cbox
), "toggled",
664 (GtkSignalFunc
) fmd_check_box_callback
, &ctx
->op_preserve
);
666 gnome_widget_add_help (cbox
,
667 _("Preserves the permissions and the UID/GID if possible"));
669 gtk_box_pack_start (GTK_BOX (vbox
), cbox
, FALSE
, FALSE
, 0);
671 vbox
= gtk_vbox_new (FALSE
, GNOME_PAD_SMALL
);
672 gtk_box_pack_start (GTK_BOX (hbox
), vbox
, TRUE
, TRUE
, 0);
673 cbox
= gtk_check_button_new_with_label (_("Recursively copy subdirectories."));
674 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cbox
), ctx
->dive_into_subdirs
);
675 gtk_signal_connect (GTK_OBJECT (cbox
), "toggled",
676 (GtkSignalFunc
) fmd_check_box_callback
,
677 &ctx
->dive_into_subdirs
);
679 gnome_widget_add_help (cbox
,
680 _("If set, this will copy the directories recursively"));
682 gtk_box_pack_start (GTK_BOX (vbox
), cbox
, FALSE
, FALSE
, 0);
685 gtk_widget_show_all (GNOME_DIALOG (fmd_win
)->vbox
);
686 gnome_dialog_set_close (GNOME_DIALOG (fmd_win
), TRUE
);
687 gnome_dialog_close_hides (GNOME_DIALOG (fmd_win
), TRUE
);
689 /* Off to the races!!! */
690 run
= gnome_dialog_run (GNOME_DIALOG (fmd_win
));
692 if (run
== 1 || run
== -1) {
693 gtk_widget_destroy (fmd_win
);
697 dest_dir
= gnome_file_entry_get_full_path (GNOME_FILE_ENTRY (fentry
), FALSE
);
698 gtk_widget_destroy (fmd_win
);
701 if (!dest_dir
|| !*dest_dir
)
704 if (ctx
->follow_links
&& operation
!= OP_MOVE
)
705 ctx
->stat_func
= mc_stat
;
707 ctx
->stat_func
= mc_lstat
;
709 if (ctx
->op_preserve
|| operation
== OP_MOVE
){
711 ctx
->umask_kill
= 0777777;
712 ctx
->preserve_uidgid
= (geteuid () == 0) ? 1 : 0;
715 ctx
->preserve
= ctx
->preserve_uidgid
= 0;
718 ctx
->umask_kill
= i
^ 0777777;
720 source_mask
= g_strdup ("*");
721 orig_mask
= source_mask
;
722 if (!dest_dir
|| !*dest_dir
){
724 g_free (source_mask
);
736 if (source_easy_patterns
) {
737 source_easy_patterns
= easy_patterns
;
739 source_mask
= convert_pattern (source_mask
, match_file
, 1);
740 easy_patterns
= source_easy_patterns
;
741 error
= re_compile_pattern (source_mask
, strlen (source_mask
), &ctx
->rx
);
742 g_free (source_mask
);
744 error
= re_compile_pattern (source_mask
, strlen (source_mask
), &ctx
->rx
);
747 g_warning ("%s\n",error
);
751 ctx
->dest_mask
= strrchr (dest_dir
, PATH_SEP
);
752 if (ctx
->dest_mask
== NULL
)
753 ctx
->dest_mask
= dest_dir
;
756 orig_mask
= ctx
->dest_mask
;
758 || (!ctx
->dive_into_subdirs
&& !is_wildcarded (ctx
->dest_mask
)
759 && (!only_one
|| (!mc_stat (dest_dir
, &buf
)
760 && S_ISDIR (buf
.st_mode
))))
761 || (ctx
->dive_into_subdirs
&& ((!only_one
&& !is_wildcarded (ctx
->dest_mask
))
762 || (only_one
&& !mc_stat (dest_dir
, &buf
)
763 && S_ISDIR (buf
.st_mode
)))))
764 ctx
->dest_mask
= g_strdup ("*");
766 ctx
->dest_mask
= g_strdup (ctx
->dest_mask
);
771 dest_dir
= g_strdup ("./");
777 file_delete_query_recursive (FileOpContext
*ctx
, enum OperationMode mode
, gchar
*s
)
780 GtkWidget
*togglebutton
;
786 if (ctx
->recursive_result
< RECURSIVE_ALWAYS
) {
787 msg
= g_strdup_printf (_("%s\n\nDirectory not empty. Delete it recursively?"),
789 dialog
= gnome_message_box_new (msg
,
790 GNOME_MESSAGE_BOX_QUESTION
,
791 GNOME_STOCK_BUTTON_YES
,
792 GNOME_STOCK_BUTTON_NO
,
793 GNOME_STOCK_BUTTON_CANCEL
,
797 title
= g_strconcat (_(" Delete: "), name_trunc (s
, 30), " ", NULL
);
798 gtk_window_set_title (GTK_WINDOW (dialog
), title
);
801 togglebutton
= gtk_check_button_new_with_label (_("Do the same for the rest"));
802 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog
)->vbox
),
803 togglebutton
, FALSE
, FALSE
, 0);
804 gtk_widget_show_all (GNOME_DIALOG (dialog
)->vbox
);
806 gnome_dialog_close_hides (GNOME_DIALOG (dialog
), TRUE
);
808 button
= gnome_dialog_run (GNOME_DIALOG (dialog
));
809 rest_same
= GTK_TOGGLE_BUTTON (togglebutton
)->active
;
811 gtk_widget_destroy (dialog
);
815 ctx
->recursive_result
= rest_same
? RECURSIVE_ALWAYS
: RECURSIVE_YES
;
818 ctx
->recursive_result
= rest_same
? RECURSIVE_NEVER
: RECURSIVE_NO
;
821 ctx
->recursive_result
= RECURSIVE_ABORT
;
827 if (ctx
->recursive_result
!= RECURSIVE_ABORT
)
831 switch (ctx
->recursive_result
){
833 case RECURSIVE_ALWAYS
:
837 case RECURSIVE_NEVER
:
840 case RECURSIVE_ABORT
:
848 cancel_cb (GtkWidget
*widget
, gpointer data
)
856 /* Handler for the close signal from the GnomeDialog in the file operation
857 * context UI. We mark the operation as "aborted" and ask GnomeDialog not to
858 * close the window for us.
861 close_cb (GtkWidget
*widget
, gpointer data
)
871 file_op_context_create_ui (FileOpContext
*ctx
, FileOperation op
, int with_eta
)
874 GtkWidget
*alignment
;
877 g_return_if_fail (ctx
!= NULL
);
878 g_return_if_fail (ctx
->ui
== NULL
);
880 ui
= g_new0 (FileOpContextUI
, 1);
885 ui
->op_win
= gnome_dialog_new (_("Move Progress"), GNOME_STOCK_BUTTON_CANCEL
, NULL
);
888 ui
->op_win
= gnome_dialog_new (_("Copy Progress"), GNOME_STOCK_BUTTON_CANCEL
, NULL
);
891 ui
->op_win
= gnome_dialog_new (_("Delete Progress"), GNOME_STOCK_BUTTON_CANCEL
, NULL
);
894 gtk_window_set_position (GTK_WINDOW (ui
->op_win
), GTK_WIN_POS_MOUSE
);
896 gnome_dialog_button_connect (GNOME_DIALOG (ui
->op_win
), 0,
897 GTK_SIGNAL_FUNC (cancel_cb
),
900 gtk_signal_connect (GTK_OBJECT (ui
->op_win
), "close",
901 GTK_SIGNAL_FUNC (close_cb
),
904 if (op
!= OP_DELETE
) {
905 alignment
= gtk_alignment_new (0.0, 0.5, 0, 0);
906 hbox
= gtk_hbox_new (FALSE
, 0);
907 gtk_container_add (GTK_CONTAINER (alignment
), hbox
);
908 gtk_box_pack_start (GTK_BOX (hbox
), gtk_label_new (_(gdialog_from_string
)),
910 ui
->op_source_label
= gtk_label_new ("");
912 gtk_box_pack_start (GTK_BOX (hbox
), ui
->op_source_label
, FALSE
, FALSE
, 0);
913 gtk_box_set_spacing (GTK_BOX (GNOME_DIALOG (ui
->op_win
)->vbox
), GNOME_PAD_SMALL
);
914 gtk_container_set_border_width (GTK_CONTAINER (GNOME_DIALOG (ui
->op_win
)->vbox
),
916 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (ui
->op_win
)->vbox
),
917 alignment
, FALSE
, FALSE
, 0);
919 alignment
= gtk_alignment_new (0.0, 0.5, 0, 0);
920 hbox
= gtk_hbox_new (FALSE
, 0);
921 gtk_container_add (GTK_CONTAINER (alignment
), hbox
);
922 gtk_box_pack_start (GTK_BOX (hbox
), gtk_label_new (_(gdialog_to_string
)),
924 ui
->op_target_label
= gtk_label_new ("");
925 gtk_box_pack_start (GTK_BOX (hbox
), ui
->op_target_label
, FALSE
, FALSE
, 0);
926 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (ui
->op_win
)->vbox
),
927 alignment
, FALSE
, FALSE
, 0);
930 alignment
= gtk_alignment_new (0.0, 0.5, 0, 0);
931 hbox
= gtk_hbox_new (FALSE
, 0);
932 gtk_container_add (GTK_CONTAINER (alignment
), hbox
);
933 gtk_box_pack_start (GTK_BOX (hbox
), gtk_label_new (_(gdialog_deleting_string
)),
935 ui
->op_source_label
= gtk_label_new ("");
937 gtk_box_pack_start (GTK_BOX (hbox
), ui
->op_source_label
, FALSE
, FALSE
, 0);
938 gtk_box_set_spacing (GTK_BOX (GNOME_DIALOG (ui
->op_win
)->vbox
), GNOME_PAD_SMALL
);
939 gtk_container_set_border_width (GTK_CONTAINER (GNOME_DIALOG (ui
->op_win
)->vbox
),
941 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (ui
->op_win
)->vbox
),
942 alignment
, FALSE
, FALSE
, 0);
945 alignment
= gtk_alignment_new (0.0, 0.5, 0, 0);
946 hbox
= gtk_hbox_new (FALSE
, 0);
947 gtk_box_pack_start (GTK_BOX (hbox
), gtk_label_new (_("File ")), FALSE
, FALSE
, 0);
948 ui
->count_label
= GTK_OBJECT (gtk_label_new (""));
949 gtk_box_pack_start (GTK_BOX (hbox
), GTK_WIDGET (ui
->count_label
), FALSE
, FALSE
, 0);
951 gtk_box_pack_start (GTK_BOX (hbox
), gtk_label_new (_("is ")), FALSE
, FALSE
, 0);
952 ui
->file_label
= gtk_label_new ("");
953 gtk_box_pack_start (GTK_BOX (hbox
), ui
->file_label
, FALSE
, FALSE
, 0);
954 gtk_box_pack_start (GTK_BOX (hbox
), gtk_label_new (_("done.")), FALSE
, FALSE
, 0);
955 gtk_container_add (GTK_CONTAINER (alignment
), hbox
);
957 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (ui
->op_win
)->vbox
),
958 alignment
, FALSE
, FALSE
, 0);
960 ui
->byte_prog
= GTK_OBJECT (gtk_progress_bar_new ());
961 gtk_widget_set_usize (GTK_WIDGET (ui
->byte_prog
), GDIALOG_PROGRESS_WIDTH
, -1);
962 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (ui
->op_win
)->vbox
),
963 GTK_WIDGET (ui
->byte_prog
), FALSE
, FALSE
, 0);
965 /* done with things */
966 gtk_widget_show_all (GNOME_DIALOG (ui
->op_win
)->vbox
);
967 gtk_window_set_modal (GTK_WINDOW (ui
->op_win
), TRUE
);
968 gtk_widget_show_now (ui
->op_win
);
972 file_op_context_destroy_ui (FileOpContext
*ctx
)
976 g_return_if_fail (ctx
!= NULL
);
983 gtk_widget_destroy (ui
->op_win
);
990 fmd_init_i18n (int force
)
992 /* unneccessary func */
995 /* Callback for the gnome_request_dialog() in the input dialog */
997 input_dialog_cb (gchar
*string
, gpointer data
)
1007 /* Our implementation of the general-purpose input dialog */
1009 real_input_dialog_help (char *header
, char *text
, char *help
, char *def_text
)
1015 if (strncmp (text
, _("Password:"), strlen (_("Password"))) == 0)
1018 is_password
= FALSE
;
1020 dialog
= gnome_request_dialog (is_password
, text
, def_text
, 0,
1021 input_dialog_cb
, &string
,
1023 gtk_window_set_title (GTK_WINDOW (dialog
), header
);
1024 gtk_window_set_modal (GTK_WINDOW (dialog
), TRUE
);
1029 /* Our implementation of the symlink-to dialog */
1031 symlink_dialog (char *existing
, char *new, char **ret_existing
, char **ret_new
)
1036 GtkWidget
*entry1
, *entry2
;
1040 g_return_if_fail (existing
!= NULL
);
1041 g_return_if_fail (new != NULL
);
1042 g_return_if_fail (ret_existing
!= NULL
);
1043 g_return_if_fail (ret_new
!= NULL
);
1045 /* Create the dialog */
1047 dialog
= gnome_dialog_new (_("Symbolic Link"),
1048 GNOME_STOCK_BUTTON_OK
,
1049 GNOME_STOCK_BUTTON_CANCEL
,
1051 gnome_dialog_close_hides (GNOME_DIALOG (dialog
), TRUE
);
1052 gnome_dialog_set_default (GNOME_DIALOG (dialog
), 0);
1055 if (!is_a_desktop_panel (panel
))
1056 gnome_dialog_set_parent (GNOME_DIALOG (dialog
), panel
->xwindow
);
1058 /* File symlink will point to */
1060 vbox
= gtk_vbox_new (FALSE
, GNOME_PAD_SMALL
);
1061 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog
)->vbox
), vbox
, FALSE
, FALSE
, 0);
1063 w
= gtk_label_new (_("Existing filename (filename symlink will point to):"));
1064 gtk_misc_set_alignment (GTK_MISC (w
), 0.0, 0.5);
1065 gtk_box_pack_start (GTK_BOX (vbox
), w
, FALSE
, FALSE
, 0);
1067 entry1
= gtk_entry_new ();
1068 gtk_entry_set_text (GTK_ENTRY (entry1
), existing
);
1069 gtk_box_pack_start (GTK_BOX (vbox
), entry1
, FALSE
, FALSE
, 0);
1070 gnome_dialog_editable_enters (GNOME_DIALOG (dialog
), GTK_EDITABLE (entry1
));
1072 /* Name of symlink */
1074 vbox
= gtk_vbox_new (FALSE
, GNOME_PAD_SMALL
);
1075 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog
)->vbox
), vbox
, FALSE
, FALSE
, 0);
1077 w
= gtk_label_new (_("Symbolic link filename:"));
1078 gtk_misc_set_alignment (GTK_MISC (w
), 0.0, 0.5);
1079 gtk_box_pack_start (GTK_BOX (vbox
), w
, FALSE
, FALSE
, 0);
1081 entry2
= gtk_entry_new ();
1082 gtk_entry_set_text (GTK_ENTRY (entry2
), new);
1083 gtk_box_pack_start (GTK_BOX (vbox
), entry2
, FALSE
, FALSE
, 0);
1084 gnome_dialog_editable_enters (GNOME_DIALOG (dialog
), GTK_EDITABLE (entry2
));
1085 gtk_widget_grab_focus (entry2
);
1089 gtk_widget_show_all (GNOME_DIALOG (dialog
)->vbox
);
1090 ret
= gnome_dialog_run (GNOME_DIALOG (dialog
));
1093 *ret_existing
= NULL
;
1096 *ret_existing
= g_strdup (gtk_entry_get_text (GTK_ENTRY (entry1
)));
1097 *ret_new
= g_strdup (gtk_entry_get_text (GTK_ENTRY (entry2
)));
1101 gtk_widget_destroy (dialog
);
1105 struct smb_authinfo
*
1106 vfs_smb_get_authinfo (const char *host
, const char *share
, const char *domain
,
1109 struct smb_authinfo
*return_value
;
1110 GtkWidget
*smbauth_dialog
;
1111 GtkWidget
*domain_entry
, *user_entry
, *passwd_entry
;
1112 GtkWidget
*domain_label
, *user_label
, *passwd_label
;
1115 static char* labs
[] = {N_("Domain:"), N_("Username:"), N_("Password: ")};
1122 title
= g_strdup_printf (_("Password for \\\\%s\\%s"), host
, share
);
1126 gnome_dialog_new(title
, GNOME_STOCK_BUTTON_OK
,
1127 GNOME_STOCK_BUTTON_CANCEL
, NULL
);
1129 gmc_window_setup_from_panel(GNOME_DIALOG(smbauth_dialog
), cpanel
);
1131 domain_label
= gtk_label_new(_(labs
[0]));
1132 gtk_misc_set_alignment(GTK_MISC(domain_label
), 0.0, 0.5);
1133 gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(smbauth_dialog
)->vbox
), domain_label
, FALSE
,
1136 domain_entry
= gnome_entry_new("domain");
1137 gnome_entry_load_history(GNOME_ENTRY(domain_entry
));
1138 gtk_entry_set_text(GTK_ENTRY(gnome_entry_gtk_entry(GNOME_ENTRY(domain_entry
))),
1140 gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(smbauth_dialog
)->vbox
), domain_entry
, FALSE
,
1143 user_label
= gtk_label_new(_(labs
[1]));
1144 gtk_misc_set_alignment(GTK_MISC(user_label
), 0.0, 0.5);
1145 gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(smbauth_dialog
)->vbox
), user_label
, FALSE
,
1148 user_entry
= gnome_entry_new("user");
1149 gnome_entry_load_history(GNOME_ENTRY(user_entry
));
1150 gtk_entry_set_text(GTK_ENTRY(gnome_entry_gtk_entry(GNOME_ENTRY(user_entry
))),
1152 gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(smbauth_dialog
)->vbox
), user_entry
, FALSE
,
1155 passwd_label
= gtk_label_new(_(labs
[2]));
1156 gtk_misc_set_alignment(GTK_MISC(passwd_label
), 0.0, 0.5);
1157 gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(smbauth_dialog
)->vbox
), passwd_label
, FALSE
,
1160 passwd_entry
= gtk_entry_new();
1161 gtk_entry_set_text(GTK_ENTRY(passwd_entry
), "");
1162 gtk_entry_set_visibility(GTK_ENTRY(passwd_entry
), FALSE
);
1163 gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(smbauth_dialog
)->vbox
), passwd_entry
, FALSE
,
1166 gtk_widget_grab_focus(passwd_entry
);
1167 gnome_dialog_set_default(GNOME_DIALOG(smbauth_dialog
), 0);
1169 gtk_widget_show_all(GNOME_DIALOG(smbauth_dialog
)->vbox
);
1171 switch (gnome_dialog_run(GNOME_DIALOG(smbauth_dialog
))) {
1173 return_value
= g_new (struct smb_authinfo
, 1);
1177 return_value
->host
= g_strdup (host
);
1178 return_value
->share
= g_strdup (share
);
1179 return_value
->domain
=
1180 g_strdup(gtk_entry_get_text
1181 (GTK_ENTRY(gnome_entry_gtk_entry(GNOME_ENTRY(domain_entry
)))));
1182 return_value
->user
=
1183 g_strdup(gtk_entry_get_text
1184 (GTK_ENTRY(gnome_entry_gtk_entry(GNOME_ENTRY(user_entry
)))));
1185 return_value
->password
= g_strdup(gtk_entry_get_text(GTK_ENTRY(passwd_entry
)));
1196 gtk_widget_destroy(smbauth_dialog
);
1198 return return_value
;
1200 #endif /* WITH_SMBFS */