1 /* vim: set textwidth=80 tabstop=4 */
4 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
5 * Copyright (C) 1999-2022 Michael Rasmussen and the Claws Mail Team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "claws-features.h"
28 #include <glib/gi18n.h>
33 #include <sys/types.h>
38 #include "gtk/gtkutils.h"
39 #include "common/claws.h"
40 #include "common/version.h"
41 #include "common/md5.h"
43 #include "mainwindow.h"
44 #include "file-utils.h"
48 #include "foldersel.h"
50 #include "procheader.h"
51 #include "libarchive_archive.h"
53 #include "archiver_prefs.h"
54 #include "alertpanel.h"
58 typedef struct _progress_widget progress_widget
;
59 struct _progress_widget
{
60 GtkWidget
* progress_dialog
;
65 GtkWidget
* file_label
;
72 A_FILE_EXISTS
= 1 << 1,
73 A_FILE_IS_LINK
= 1 << 2,
74 A_FILE_IS_DIR
= 1 << 3,
75 A_FILE_NO_WRITE
= 1 << 4,
76 A_FILE_UNKNOWN
= 1 << 5
79 static progress_widget
* progress
= NULL
;
81 static progress_widget
* init_progress() {
82 progress_widget
* ptr
= malloc(sizeof(*ptr
));
84 debug_print("creating progress struct\n");
85 ptr
->progress_dialog
= NULL
;
89 ptr
->add_label
= NULL
;
90 ptr
->file_label
= NULL
;
97 static void progress_dialog_cb(GtkWidget
* widget
, gint action
, gpointer data
) {
98 struct ArchivePage
* page
= (struct ArchivePage
*) data
;
100 debug_print("Cancel operation\n");
102 page
->cancelled
= TRUE
;
103 archive_free_file_list(page
->md5
, page
->rename
);
104 gtk_widget_destroy(widget
);
107 static void create_progress_dialog(struct ArchivePage
* page
) {
108 gchar
* title
= g_strdup_printf("%s %s", _("Archiving"), page
->path
);
109 MainWindow
* mainwin
= mainwindow_get_mainwindow();
110 GtkWidget
*content_area
;
112 progress
->position
= 0;
113 progress
->progress_dialog
= gtk_dialog_new_with_buttons (
115 GTK_WINDOW(mainwin
->window
),
116 GTK_DIALOG_DESTROY_WITH_PARENT
,
122 progress
->progress_dialog
,
124 G_CALLBACK(progress_dialog_cb
),
127 progress
->frame
= gtk_frame_new(_("Press Cancel button to stop archiving"));
128 gtk_frame_set_shadow_type(GTK_FRAME(progress
->frame
),
129 GTK_SHADOW_ETCHED_OUT
);
130 gtk_container_set_border_width(GTK_CONTAINER(progress
->frame
), 4);
131 content_area
= gtk_dialog_get_content_area(GTK_DIALOG(progress
->progress_dialog
));
132 gtk_container_add(GTK_CONTAINER(content_area
), progress
->frame
);
134 progress
->vbox1
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 4);
135 gtk_container_set_border_width (GTK_CONTAINER (progress
->vbox1
), 4);
136 gtk_container_add(GTK_CONTAINER(progress
->frame
), progress
->vbox1
);
138 progress
->hbox1
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 8);
139 gtk_container_set_border_width(GTK_CONTAINER(progress
->hbox1
), 8);
140 gtk_box_pack_start(GTK_BOX(progress
->vbox1
),
141 progress
->hbox1
, FALSE
, FALSE
, 0);
143 progress
->add_label
= gtk_label_new(_("Archiving:"));
144 gtk_box_pack_start(GTK_BOX(progress
->hbox1
),
145 progress
->add_label
, FALSE
, FALSE
, 0);
147 progress
->file_label
= gtk_label_new("");
148 gtk_label_set_ellipsize(GTK_LABEL(progress
->file_label
),
149 PANGO_ELLIPSIZE_START
);
150 gtk_box_pack_start(GTK_BOX(progress
->hbox1
),
151 progress
->file_label
, TRUE
, TRUE
, 0);
153 progress
->hbox1
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 8);
154 gtk_container_set_border_width(GTK_CONTAINER(progress
->hbox1
), 8);
155 gtk_box_pack_start(GTK_BOX(progress
->vbox1
),
156 progress
->hbox1
, FALSE
, FALSE
, 0);
158 progress
->progress
= gtk_progress_bar_new();
159 gtk_box_pack_start(GTK_BOX(progress
->hbox1
),
160 progress
->progress
, TRUE
, TRUE
, 0);
161 gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(progress
->progress
), 0.25);
163 gtk_window_set_default_size(GTK_WINDOW(progress
->progress_dialog
), 400, 80);
164 gtk_widget_show_all(progress
->progress_dialog
);
167 static struct ArchivePage
* init_archive_page() {
168 struct ArchivePage
* page
= malloc(sizeof(struct ArchivePage
));
170 debug_print("creating ArchivePage\n");
175 page
->response
= FALSE
;
176 page
->force_overwrite
= FALSE
;
177 page
->compress_methods
= NULL
;
178 page
->archive_formats
= NULL
;
179 page
->recursive
= NULL
;
180 page
->cancelled
= FALSE
;
183 page
->rename
= FALSE
;
184 page
->rename_files
= NULL
;
185 page
->isoDate
= NULL
;
186 page
->unlink_files
= NULL
;
187 page
->unlink
= FALSE
;
192 static void dispose_archive_page(struct ArchivePage
* page
) {
193 debug_print("freeing ArchivePage\n");
203 static gboolean
valid_file_name(gchar
* file
) {
206 for (i
= 0; INVALID_UNIX_CHARS
[i
] != '\0'; i
++) {
207 if (g_utf8_strchr(file
, g_utf8_strlen(file
, -1), INVALID_UNIX_CHARS
[i
]))
213 static COMPRESS_METHOD
get_compress_method(GSList
* btn
) {
217 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(btn
->data
))) {
218 name
= gtk_widget_get_name(GTK_WIDGET(btn
->data
));
219 if (strcmp("GZIP", name
) == 0) {
220 debug_print("GZIP compression enabled\n");
223 else if (strcmp("BZIP", name
) == 0) {
224 debug_print("BZIP2 compression enabled\n");
227 else if (strcmp("COMPRESS", name
) == 0) {
228 debug_print("COMPRESS compression enabled\n");
231 #if ARCHIVE_VERSION_NUMBER >= 2006990
232 else if (strcmp("LZMA", name
) == 0) {
233 debug_print("LZMA compression enabled\n");
236 else if (strcmp("XZ", name
) == 0) {
237 debug_print("XZ compression enabled\n");
241 #if ARCHIVE_VERSION_NUMBER >= 3000000
242 else if (strcmp("LZIP", name
) == 0) {
243 debug_print("LZIP compression enabled\n");
247 #if ARCHIVE_VERSION_NUMBER >= 3001000
248 else if (strcmp("LRZIP", name
) == 0) {
249 debug_print("LRZIP compression enabled\n");
252 else if (strcmp("LZOP", name
) == 0) {
253 debug_print("LZOP compression enabled\n");
256 else if (strcmp("GRZIP", name
) == 0) {
257 debug_print("GRZIP compression enabled\n");
261 #if ARCHIVE_VERSION_NUMBER >= 3001900
262 else if (strcmp("LZ4", name
) == 0) {
263 debug_print("LZ4 compression enabled\n");
267 else if (strcmp("NONE", name
) == 0) {
268 debug_print("Compression disabled\n");
272 btn
= g_slist_next(btn
);
277 static ARCHIVE_FORMAT
get_archive_format(GSList
* btn
) {
281 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(btn
->data
))) {
282 name
= gtk_widget_get_name(GTK_WIDGET(btn
->data
));
283 if (strcmp("TAR", name
) == 0) {
284 debug_print("TAR archive enabled\n");
287 else if (strcmp("SHAR", name
) == 0) {
288 debug_print("SHAR archive enabled\n");
291 else if (strcmp("PAX", name
) == 0) {
292 debug_print("PAX archive enabled\n");
295 else if (strcmp("CPIO", name
) == 0) {
296 debug_print("CPIO archive enabled\n");
300 btn
= g_slist_next(btn
);
305 static void create_md5sum(const gchar
* file
, const gchar
* md5_file
) {
308 gchar
* md5sum
= malloc(33);
310 debug_print("Creating md5sum file: %s\n", md5_file
);
311 if (md5_hex_digest_file(md5sum
, (const unsigned char *) file
) == -1) {
315 debug_print("md5sum: %s\n", md5sum
);
317 open(md5_file
, O_WRONLY
| O_CREAT
| O_TRUNC
, S_IRUSR
| S_IWUSR
)) == -1) {
318 FILE_OP_ERROR(md5_file
, "create");
322 text
= g_strrstr_len(file
, strlen(file
), "/");
325 text
= g_strdup_printf("%s %s\n", md5sum
, text
);
328 text
= g_strdup_printf("%s %s\n", md5sum
, file
);
330 debug_print("md5sum: %s\n", text
);
331 if (write(fd
, text
, strlen(text
)) < 0)
332 FILE_OP_ERROR(md5_file
, "write");
337 static gchar
* descriptive_file_name(
338 struct ArchivePage
* page
, const gchar
* file
, MsgInfo
*msginfo
) {
339 gchar
* new_file
= NULL
;
340 gchar
*name
, *p
, *to
, *from
, *date
, *subject
;
342 debug_print("renaming file\n");
343 p
= g_strrstr_len(file
, strlen(file
), "/");
344 p
= g_strndup(file
, p
- file
);
348 to
= g_strdup(msginfo
->to
);
354 from
= g_strdup(msginfo
->from
);
355 extract_address(from
);
360 date
= g_strdup(msginfo
->date
);
361 subst_for_shellsafe_filename(date
);
362 /* if not on windows we need to subst some more */
363 subst_chars(date
, ":", '_');
367 if (msginfo
->subject
) {
368 subject
= g_strdup(msginfo
->subject
);
369 subst_for_shellsafe_filename(subject
);
370 /* if not on windows we need to subst some more */
371 subst_chars(subject
, ":", '_');
374 subject
= g_strdup("");
375 name
= g_strdup_printf("%s_%s@%s@%s", date
, from
, to
, subject
);
376 /* ensure file name is not larger than 96 chars (max file name size
377 * is 100 chars but reserve for .md5)
379 if (strlen(name
) > 96)
382 new_file
= g_strconcat(p
, "/", name
, NULL
);
391 debug_print("New_file: %s\n", new_file
);
392 if (link(file
, new_file
) != 0) {
393 if (errno
!= EEXIST
) {
394 FILE_OP_ERROR(new_file
, "link");
396 new_file
= g_strdup(file
);
397 page
->rename
= FALSE
;
404 static void walk_folder(struct ArchivePage
* page
, FolderItem
* item
,
405 gboolean recursive
) {
412 gchar
* md5_file
= NULL
;
415 MsgTrash
* msg_trash
= NULL
;
416 const gchar
* date
= NULL
;
418 if (recursive
&& ! page
->cancelled
) {
419 debug_print("Scanning recursive\n");
420 node
= item
->node
->children
;
421 while(node
&& ! page
->cancelled
) {
422 debug_print("Number of nodes: %d\n", g_node_n_children(node
));
424 child
= FOLDER_ITEM(node
->data
);
425 debug_print("new node: %d messages\n", child
->total_msgs
);
426 walk_folder(page
, child
, recursive
);
431 if (! page
->cancelled
) {
432 date
= gtk_entry_get_text(GTK_ENTRY(page
->isoDate
));
433 debug_print("cut-off date: %s\n", date
);
435 page
->files
+= item
->total_msgs
;
436 msglist
= folder_item_get_msg_list(item
);
437 msg_trash
= new_msg_trash(item
);
438 for (cur
= msglist
; cur
&& ! page
->cancelled
; cur
= cur
->next
) {
439 msginfo
= (MsgInfo
*) cur
->data
;
440 debug_print("%s_%s_%s_%s\n",
441 msginfo
->date
, msginfo
->to
, msginfo
->from
, msginfo
->subject
);
442 file
= folder_item_fetch_msg(item
, msginfo
->msgnum
);
443 if (date
&& strlen(date
) > 0 && !before_date(msginfo
->date_t
, date
)) {
447 page
->total_size
+= msginfo
->size
;
448 /*debug_print("Processing: %s\n", file);*/
451 archive_add_msg_mark(msg_trash
, msginfo
);
454 file
= descriptive_file_name(page
, file
, msginfo
);
456 /* Could not create a descriptive name */
457 file
= folder_item_fetch_msg(item
, msginfo
->msgnum
);
461 md5_file
= g_strdup_printf("%s.md5", file
);
462 create_md5sum(file
, md5_file
);
463 archive_add_file(md5_file
);
466 archive_add_file(file
);
470 if (count
% 350 == 0) {
471 debug_print("pulse progressbar\n");
472 text
= g_strdup_printf(
473 "Scanning %s: %d files", item
->name
, count
);
474 gtk_progress_bar_set_text(
475 GTK_PROGRESS_BAR(progress
->progress
), text
);
477 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progress
->progress
));
482 procmsg_msg_list_free(msglist
);
486 static AFileTest
file_is_writeable(struct ArchivePage
* page
) {
489 if (g_file_test(page
->name
, G_FILE_TEST_EXISTS
) &&
490 ! page
->force_overwrite
)
491 return A_FILE_EXISTS
;
492 if (g_file_test(page
->name
, G_FILE_TEST_IS_SYMLINK
))
493 return A_FILE_IS_LINK
;
494 if (g_file_test(page
->name
, G_FILE_TEST_IS_DIR
))
495 return A_FILE_IS_DIR
;
496 if ((fd
= open(page
->name
, O_WRONLY
| O_CREAT
, S_IRUSR
| S_IWUSR
)) == -1) {
498 case EACCES
: return A_FILE_NO_WRITE
;
499 case EEXIST
: return A_FILE_OK
;
500 default: return A_FILE_UNKNOWN
;
505 claws_unlink(page
->name
);
510 static gboolean
archiver_save_files(struct ArchivePage
* page
) {
512 COMPRESS_METHOD method
;
513 ARCHIVE_FORMAT format
;
517 const gchar
* res
= NULL
;
520 gboolean folder_not_set
;
521 gboolean file_not_set
;
523 /* check if folder to archive and target archive filename are set */
524 folder_not_set
= (*gtk_entry_get_text(GTK_ENTRY(page
->folder
)) == '\0');
525 file_not_set
= (*gtk_entry_get_text(GTK_ENTRY(page
->file
)) == '\0');
526 if (folder_not_set
|| file_not_set
) {
527 alertpanel_error(_("Some uninitialized data prevents from starting\n"
528 "the archiving process:\n"
530 folder_not_set
? _("\n- the folder to archive is not set") : "",
531 file_not_set
? _("\n- the name for archive is not set") : "");
534 /* sync page struct info with folder and archive name edit widgets */
539 page
->path
= g_strdup(gtk_entry_get_text(GTK_ENTRY(page
->folder
)));
540 g_strstrip(page
->path
);
541 debug_print("page->path: %s\n", page
->path
);
547 page
->name
= g_strdup(gtk_entry_get_text(GTK_ENTRY(page
->file
)));
548 g_strstrip(page
->name
);
549 debug_print("page->name: %s\n", page
->name
);
551 if ((perm
= file_is_writeable(page
)) != A_FILE_OK
) {
554 msg
= g_strdup_printf(_("%s: Exists. Continue anyway?"), page
->name
);
557 msg
= g_strdup_printf(_("%s: Is a link. Cannot continue"), page
->name
);
560 msg
= g_strdup_printf(_("%s: Is a directory. Cannot continue"), page
->name
);
562 case A_FILE_NO_WRITE
:
563 msg
= g_strdup_printf(_("%s: Missing permissions. Cannot continue"), page
->name
);
566 msg
= g_strdup_printf(_("%s: Unknown error. Cannot continue"), page
->name
);
571 if (perm
== A_FILE_EXISTS
) {
574 aval
= alertpanel_full(_("Creating archive"), msg
,
575 NULL
, _("_Cancel"), NULL
, _("_OK"), NULL
, NULL
,
576 ALERTFOCUS_FIRST
, FALSE
, NULL
, ALERT_WARNING
);
578 if (aval
!= G_ALERTALTERNATE
)
581 alertpanel_error("%s", msg
);
586 if (! valid_file_name(page
->name
)) {
587 alertpanel_error(_("Not a valid file name:\n%s."), page
->name
);
590 item
= folder_find_item_from_identifier(page
->path
);
592 alertpanel_error(_("Not a valid Claws Mail folder:\n%s."), page
->name
);
596 page
->total_size
= 0;
597 page
->rename
= gtk_toggle_button_get_active(
598 GTK_TOGGLE_BUTTON(page
->rename_files
));
599 recursive
= gtk_toggle_button_get_active(
600 GTK_TOGGLE_BUTTON(page
->recursive
));
601 page
->md5
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page
->md5sum
));
602 page
->unlink
= gtk_toggle_button_get_active(
603 GTK_TOGGLE_BUTTON(page
->unlink_files
));
604 create_progress_dialog(page
);
605 walk_folder(page
, item
, recursive
);
608 list
= archive_get_file_list();
609 orig_file
= (page
->md5
) ? page
->files
* 2 : page
->files
;
610 debug_print("md5: %d, orig: %d, md5: %d\n",
611 page
->md5
, page
->files
, orig_file
);
612 if (orig_file
!= g_slist_length(list
)) {
615 msg
= g_strdup_printf(
616 _("Adding files in folder failed\n"
617 "Files in folder: %d\n"
618 "Files in list: %d\n"
619 "\nContinue anyway?"),
620 orig_file
, g_slist_length(list
));
621 aval
= alertpanel_full(_("Creating archive"), msg
,
622 NULL
, _("_Cancel"), NULL
, _("_OK"), NULL
, NULL
,
623 ALERTFOCUS_FIRST
, FALSE
, NULL
, ALERT_WARNING
);
625 if (aval
!= G_ALERTALTERNATE
) {
626 archive_free_file_list(page
->md5
, page
->rename
);
630 method
= get_compress_method(page
->compress_methods
);
631 format
= get_archive_format(page
->archive_formats
);
632 if ((res
= archive_create(page
->name
, list
, method
, format
)) != NULL
) {
633 alertpanel_error(_("Archive creation error:\n%s"), res
);
634 archive_free_file_list(page
->md5
, page
->rename
);
638 archive_free_archived_files();
643 static void entry_change_cb(GtkWidget
* widget
, gpointer data
) {
644 const gchar
* name
= gtk_widget_get_name(widget
);
645 struct ArchivePage
* page
= (struct ArchivePage
*) data
;
647 if (strcmp("folder", name
) == 0) {
648 page
->path
= g_strdup(gtk_entry_get_text(GTK_ENTRY(widget
)));
649 debug_print("page->folder = %s\n", page
->path
);
651 else if (strcmp("file", name
) == 0) {
652 page
->name
= g_strdup(gtk_entry_get_text(GTK_ENTRY(widget
)));
653 page
->force_overwrite
= FALSE
;
654 debug_print("page->name = %s\n", page
->name
);
658 static void show_result(struct ArchivePage
* page
) {
670 GtkTreeViewColumn
* header
;
671 GtkCellRenderer
* renderer
;
673 GtkWidget
* content_area
;
675 gchar
* method
= NULL
;
676 gchar
* format
= NULL
;
678 MainWindow
* mainwin
= mainwindow_get_mainwindow();
680 switch (get_compress_method(page
->compress_methods
)) {
682 method
= g_strdup("GZIP");
685 method
= g_strdup("BZIP2");
688 method
= g_strdup("Compress");
690 #if ARCHIVE_VERSION_NUMBER >= 2006990
692 method
= g_strdup("LZMA");
695 method
= g_strdup("XZ");
698 #if ARCHIVE_VERSION_NUMBER >= 3000000
700 method
= g_strdup("LZIP");
703 #if ARCHIVE_VERSION_NUMBER >= 3001000
705 method
= g_strdup("LRZIP");
708 method
= g_strdup("LZOP");
711 method
= g_strdup("GRZIP");
714 #if ARCHIVE_VERSION_NUMBER >= 3001900
716 method
= g_strdup("LZ4");
720 method
= g_strdup("No Compression");
724 switch (get_archive_format(page
->archive_formats
)) {
726 format
= g_strdup("TAR");
729 format
= g_strdup("SHAR");
732 format
= g_strdup("PAX");
735 format
= g_strdup("CPIO");
738 format
= g_strdup("NO FORMAT");
741 if (g_stat(page
->name
, &st
) == -1) {
742 alertpanel_error("Could not get size of archive file '%s'.", page
->name
);
745 dialog
= gtk_dialog_new_with_buttons(
747 GTK_WINDOW(mainwin
->window
),
748 GTK_DIALOG_DESTROY_WITH_PARENT
,
752 g_signal_connect_swapped(
755 G_CALLBACK(gtk_widget_destroy
),
758 list
= gtk_list_store_new(N_COLUMNS
, G_TYPE_STRING
, G_TYPE_STRING
);
764 "headers-clickable", FALSE
,
765 "reorderable", FALSE
,
766 "enable-search", FALSE
,
769 renderer
= gtk_cell_renderer_text_new();
771 header
= gtk_tree_view_column_new_with_attributes(
772 _("Attributes"), renderer
, "text", STRING1
, NULL
);
773 gtk_tree_view_append_column(view
, header
);
775 header
= gtk_tree_view_column_new_with_attributes(
776 _("Values"), renderer
, "text", STRING2
, NULL
);
777 gtk_tree_view_append_column(view
, header
);
779 content_area
= gtk_dialog_get_content_area(GTK_DIALOG(dialog
));
781 GTK_CONTAINER(content_area
), GTK_WIDGET(view
));
783 gtk_list_store_append(list
, &iter
);
786 STRING1
, _("Archive"),
787 STRING2
, page
->name
, -1);
789 gtk_list_store_append(list
, &iter
);
792 STRING1
, _("Archive format"),
793 STRING2
, format
, -1);
796 gtk_list_store_append(list
, &iter
);
799 STRING1
, _("Compression method"),
800 STRING2
, method
, -1);
803 gtk_list_store_append(list
, &iter
);
804 msg
= g_strdup_printf("%d", (page
->md5
) ? page
->files
* 2 : page
->files
);
807 STRING1
, _("Number of files"),
811 gtk_list_store_append(list
, &iter
);
812 msg
= g_strdup_printf("%d byte(s)", (guint
) st
.st_size
);
815 STRING1
, _("Archive Size"),
819 gtk_list_store_append(list
, &iter
);
820 msg
= g_strdup_printf("%d byte(s)", page
->total_size
);
823 STRING1
, _("Folder Size"),
827 gtk_list_store_append(list
, &iter
);
828 msg
= g_strdup_printf("%d%%",
829 (guint
)((st
.st_size
* 100) / page
->total_size
));
832 STRING1
, _("Compression level"),
836 gtk_list_store_append(list
, &iter
);
837 msg
= g_strdup_printf("%s", (page
->md5
) ? _("Yes") : _("No"));
840 STRING1
, _("MD5 checksum"),
844 gtk_list_store_append(list
, &iter
);
845 msg
= g_strdup_printf("%s", (page
->rename
) ? _("Yes") : _("No"));
848 STRING1
, _("Descriptive names"),
852 gtk_list_store_append(list
, &iter
);
853 msg
= g_strdup_printf("%s", (page
->unlink
) ? _("Yes") : _("No"));
856 STRING1
, _("Delete selected files"),
860 msg
= g_strdup(gtk_entry_get_text(GTK_ENTRY(page
->isoDate
)));
862 gtk_list_store_append(list
, &iter
);
865 STRING1
, _("Select mails before"),
870 gtk_window_set_default_size(GTK_WINDOW(dialog
), 320, 260);
872 gtk_widget_show_all(dialog
);
875 static void archiver_dialog_cb(GtkWidget
* widget
, gint action
, gpointer data
) {
876 struct ArchivePage
* page
= (struct ArchivePage
*) data
;
877 gboolean result
= FALSE
;
880 case GTK_RESPONSE_ACCEPT
:
881 debug_print("User chose OK\n");
882 page
->response
= TRUE
;
885 debug_print("User chose CANCEL\n");
886 page
->response
= FALSE
;
887 archiver_gtk_done(page
, widget
);
890 debug_print("Settings:\naction: %d\n", page
->response
);
891 if (page
->response
) {
892 debug_print("Settings:\nfolder: %s\nname: %s\n",
893 (page
->path
) ? page
->path
: "(null)",
894 (page
->name
) ? page
->name
: "(null)");
895 result
= archiver_save_files(page
);
896 debug_print("Result->archiver_save_files: %d\n", result
);
897 if (progress
->progress_dialog
&&
898 GTK_IS_WIDGET(progress
->progress_dialog
))
899 gtk_widget_destroy(progress
->progress_dialog
);
900 if (result
&& ! page
->cancelled
) {
902 archive_free_file_list(page
->md5
, page
->rename
);
903 archiver_gtk_done(page
, widget
);
906 if (page
->cancelled
) {
907 archiver_gtk_done(page
, widget
);
913 static void foldersel_cb(GtkWidget
*widget
, gpointer data
)
918 struct ArchivePage
* page
= (struct ArchivePage
*) data
;
920 item
= foldersel_folder_sel(NULL
, FOLDER_SEL_MOVE
, NULL
, FALSE
,
921 _("Select folder to archive"));
922 if (item
&& (item_id
= folder_item_get_identifier(item
)) != NULL
) {
923 gtk_editable_delete_text(GTK_EDITABLE(page
->folder
), 0, -1);
924 gtk_editable_insert_text(GTK_EDITABLE(page
->folder
),
925 item_id
, strlen(item_id
), &newpos
);
926 page
->path
= g_strdup(item_id
);
929 debug_print("Folder to archive: %s\n",
930 gtk_entry_get_text(GTK_ENTRY(page
->folder
)));
933 static void filesel_cb(GtkWidget
*widget
, gpointer data
)
938 struct ArchivePage
* page
= (struct ArchivePage
*) data
;
940 dialog
= gtk_file_chooser_dialog_new(
941 _("Select file name for archive [suffix should reflect archive like .tgz]"),
943 GTK_FILE_CHOOSER_ACTION_SAVE
,
944 _("_Cancel"), GTK_RESPONSE_CANCEL
,
945 _("_Apply"), GTK_RESPONSE_APPLY
,
948 if (archiver_prefs
.save_folder
)
949 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog
),
950 archiver_prefs
.save_folder
);
952 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog
),
954 if (gtk_dialog_run (GTK_DIALOG(dialog
)) == GTK_RESPONSE_APPLY
) {
955 file
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog
));
957 gtk_editable_delete_text(GTK_EDITABLE(page
->file
), 0, -1);
958 gtk_editable_insert_text(GTK_EDITABLE(page
->file
),
959 file
, strlen(file
), &newpos
);
960 page
->name
= g_strdup(file
);
962 page
->force_overwrite
= TRUE
;
965 gtk_widget_destroy(dialog
);
966 debug_print("Name for archive: %s\n",
967 gtk_entry_get_text(GTK_ENTRY(page
->file
)));
970 void set_progress_file_label(const gchar
* file
) {
971 debug_print("IsLabel: %s, Update label: %s\n",
972 GTK_IS_WIDGET(progress
->file_label
)? "Yes" : "No", file
);
973 if (GTK_IS_WIDGET(progress
->file_label
))
974 gtk_label_set_text(GTK_LABEL(progress
->file_label
), file
);
977 void set_progress_print_all(guint fraction
, guint total
, guint step
) {
980 if (GTK_IS_WIDGET(progress
->progress
)) {
981 if ((fraction
- progress
->position
) % step
== 0) {
982 debug_print("frac: %d, total: %d, step: %d, prog->pos: %d\n",
983 fraction
, total
, step
, progress
->position
);
984 gtk_progress_bar_set_fraction(
985 GTK_PROGRESS_BAR(progress
->progress
),
986 (total
== 0) ? 0 : (gfloat
)fraction
/ (gfloat
)total
);
987 text_count
= g_strdup_printf(_("%ld of %ld"),
988 (long) fraction
, (long) total
);
989 gtk_progress_bar_set_text(
990 GTK_PROGRESS_BAR(progress
->progress
), text_count
);
992 progress
->position
= fraction
;
998 void archiver_gtk_show() {
1003 GtkWidget
* folder_label
;
1004 GtkWidget
* folder_select
;
1005 GtkWidget
* file_label
;
1006 GtkWidget
* file_select
;
1007 GtkWidget
* gzip_radio_btn
;
1008 GtkWidget
* bzip_radio_btn
;
1009 GtkWidget
* compress_radio_btn
;
1010 #if ARCHIVE_VERSION_NUMBER >= 2006990
1011 GtkWidget
* lzma_radio_btn
;
1012 GtkWidget
* xz_radio_btn
;
1014 #if ARCHIVE_VERSION_NUMBER >= 3000000
1015 GtkWidget
* lzip_radio_btn
;
1017 #if ARCHIVE_VERSION_NUMBER >= 3001000
1018 GtkWidget
* lrzip_radio_btn
;
1019 GtkWidget
* lzop_radio_btn
;
1020 GtkWidget
* grzip_radio_btn
;
1022 #if ARCHIVE_VERSION_NUMBER >= 3001900
1023 GtkWidget
* lz4_radio_btn
;
1025 GtkWidget
* no_radio_btn
;
1026 GtkWidget
* shar_radio_btn
;
1027 GtkWidget
* pax_radio_btn
;
1028 GtkWidget
* cpio_radio_btn
;
1029 GtkWidget
* tar_radio_btn
;
1030 GtkWidget
* content_area
;
1031 struct ArchivePage
* page
;
1032 MainWindow
* mainwin
= mainwindow_get_mainwindow();
1034 /*debug_set_mode(TRUE);*/
1035 progress
= init_progress();
1037 page
= init_archive_page();
1039 dialog
= gtk_dialog_new_with_buttons (
1040 _("Create Archive"),
1041 GTK_WINDOW(mainwin
->window
),
1042 GTK_DIALOG_DESTROY_WITH_PARENT
,
1044 GTK_RESPONSE_CANCEL
,
1046 GTK_RESPONSE_ACCEPT
,
1052 G_CALLBACK(archiver_dialog_cb
),
1055 frame
= gtk_frame_new(_("Enter Archiver arguments"));
1056 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_OUT
);
1057 gtk_container_set_border_width(GTK_CONTAINER(frame
), 4);
1058 content_area
= gtk_dialog_get_content_area(GTK_DIALOG(dialog
));
1059 gtk_container_add(GTK_CONTAINER(content_area
), frame
);
1061 vbox1
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 4);
1062 gtk_container_set_border_width (GTK_CONTAINER (vbox1
), 4);
1063 gtk_container_add(GTK_CONTAINER(frame
), vbox1
);
1065 hbox1
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
1066 gtk_container_set_border_width(GTK_CONTAINER(hbox1
), 4);
1067 gtk_box_pack_start(GTK_BOX(vbox1
), hbox1
, FALSE
, FALSE
, 0);
1069 folder_label
= gtk_label_new(_("Folder to archive"));
1070 gtk_box_pack_start(GTK_BOX(hbox1
), folder_label
, FALSE
, FALSE
, 0);
1072 page
->folder
= gtk_entry_new();
1073 gtk_widget_set_name(page
->folder
, "folder");
1074 gtk_box_pack_start(GTK_BOX(hbox1
), page
->folder
, TRUE
, TRUE
, 0);
1075 CLAWS_SET_TIP(page
->folder
,
1076 _("Folder which is the root of the archive"));
1078 folder_select
= gtkut_get_browse_directory_btn(_("_Browse"));
1079 gtk_box_pack_start(GTK_BOX(hbox1
), folder_select
, FALSE
, FALSE
, 0);
1080 CLAWS_SET_TIP(folder_select
,
1081 _("Click this button to select a folder which is to be root of the archive"));
1083 hbox1
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
1084 gtk_container_set_border_width(GTK_CONTAINER(hbox1
), 4);
1085 gtk_box_pack_start(GTK_BOX(vbox1
), hbox1
, FALSE
, FALSE
, 0);
1087 file_label
= gtk_label_new(_("Name for archive"));
1088 gtk_box_pack_start(GTK_BOX(hbox1
), file_label
, FALSE
, FALSE
, 0);
1090 page
->file
= gtk_entry_new();
1091 gtk_widget_set_name(page
->file
, "file");
1092 gtk_box_pack_start(GTK_BOX(hbox1
), page
->file
, TRUE
, TRUE
, 0);
1093 CLAWS_SET_TIP(page
->file
, _("Archive location and name"));
1095 file_select
= gtkut_get_browse_directory_btn(_("_Select"));
1096 gtk_box_pack_start(GTK_BOX(hbox1
), file_select
, FALSE
, FALSE
, 0);
1097 CLAWS_SET_TIP(file_select
,
1098 _("Click this button to select a name and location for the archive"));
1100 frame
= gtk_frame_new(_("Choose compression"));
1101 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_OUT
);
1102 gtk_container_set_border_width(GTK_CONTAINER(frame
), 4);
1103 gtk_box_pack_start(GTK_BOX(vbox1
), frame
, FALSE
, FALSE
, 0);
1105 hbox1
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
1106 gtk_container_set_border_width(GTK_CONTAINER(hbox1
), 4);
1107 gtk_container_add(GTK_CONTAINER(frame
), hbox1
);
1109 gzip_radio_btn
= gtk_radio_button_new_with_mnemonic(NULL
, "G_ZIP");
1110 gtk_widget_set_name(gzip_radio_btn
, "GZIP");
1111 gtk_box_pack_start(GTK_BOX(hbox1
), gzip_radio_btn
, FALSE
, FALSE
, 0);
1112 archiver_set_tooltip(gzip_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "GZIP"));
1114 bzip_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1115 GTK_RADIO_BUTTON(gzip_radio_btn
), "BZIP_2");
1116 gtk_widget_set_name(bzip_radio_btn
, "BZIP");
1117 gtk_box_pack_start(GTK_BOX(hbox1
), bzip_radio_btn
, FALSE
, FALSE
, 0);
1118 archiver_set_tooltip(bzip_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "BZIP2"));
1120 compress_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1121 GTK_RADIO_BUTTON(gzip_radio_btn
), "Com_press");
1122 gtk_widget_set_name(compress_radio_btn
, "COMPRESS");
1123 gtk_box_pack_start(GTK_BOX(hbox1
), compress_radio_btn
, FALSE
, FALSE
, 0);
1124 archiver_set_tooltip(compress_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "COMPRESS"));
1126 #if ARCHIVE_VERSION_NUMBER >= 2006990
1127 lzma_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1128 GTK_RADIO_BUTTON(gzip_radio_btn
), "_LZMA");
1129 gtk_widget_set_name(lzma_radio_btn
, "LZMA");
1130 gtk_box_pack_start(GTK_BOX(hbox1
), lzma_radio_btn
, FALSE
, FALSE
, 0);
1131 archiver_set_tooltip(lzma_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "LZMA"));
1133 xz_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1134 GTK_RADIO_BUTTON(gzip_radio_btn
), "_XZ");
1135 gtk_widget_set_name(xz_radio_btn
, "XZ");
1136 gtk_box_pack_start(GTK_BOX(hbox1
), xz_radio_btn
, FALSE
, FALSE
, 0);
1137 archiver_set_tooltip(xz_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "XZ"));
1140 #if ARCHIVE_VERSION_NUMBER >= 3000000
1141 lzip_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1142 GTK_RADIO_BUTTON(gzip_radio_btn
), "_LZIP");
1143 gtk_widget_set_name(lzip_radio_btn
, "LZIP");
1144 gtk_box_pack_start(GTK_BOX(hbox1
), lzip_radio_btn
, FALSE
, FALSE
, 0);
1145 archiver_set_tooltip(lzip_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "LZIP"));
1148 #if ARCHIVE_VERSION_NUMBER >= 3001000
1149 lrzip_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1150 GTK_RADIO_BUTTON(gzip_radio_btn
), "L_RZIP");
1151 gtk_widget_set_name(lrzip_radio_btn
, "LRZIP");
1152 gtk_box_pack_start(GTK_BOX(hbox1
), lrzip_radio_btn
, FALSE
, FALSE
, 0);
1153 archiver_set_tooltip(lrzip_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "LRZIP"));
1155 lzop_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1156 GTK_RADIO_BUTTON(gzip_radio_btn
), "LZ_OP");
1157 gtk_widget_set_name(lzop_radio_btn
, "LZOP");
1158 gtk_box_pack_start(GTK_BOX(hbox1
), lzop_radio_btn
, FALSE
, FALSE
, 0);
1159 archiver_set_tooltip(lzop_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "LZOP"));
1161 grzip_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1162 GTK_RADIO_BUTTON(gzip_radio_btn
), "_GRZIP");
1163 gtk_widget_set_name(grzip_radio_btn
, "GRZIP");
1164 gtk_box_pack_start(GTK_BOX(hbox1
), grzip_radio_btn
, FALSE
, FALSE
, 0);
1165 archiver_set_tooltip(grzip_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "GRZIP"));
1168 #if ARCHIVE_VERSION_NUMBER >= 3001900
1169 lz4_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1170 GTK_RADIO_BUTTON(gzip_radio_btn
), "LZ_4");
1171 gtk_widget_set_name(lz4_radio_btn
, "LZ4");
1172 gtk_box_pack_start(GTK_BOX(hbox1
), lz4_radio_btn
, FALSE
, FALSE
, 0);
1173 archiver_set_tooltip(lz4_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "LZ4"));
1176 no_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1177 GTK_RADIO_BUTTON(gzip_radio_btn
), _("_None"));
1178 gtk_widget_set_name(no_radio_btn
, "NONE");
1179 gtk_box_pack_start(GTK_BOX(hbox1
), no_radio_btn
, FALSE
, FALSE
, 0);
1180 archiver_set_tooltip(no_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "NO"));
1182 page
->compress_methods
=
1183 gtk_radio_button_get_group(GTK_RADIO_BUTTON(gzip_radio_btn
));
1185 switch (archiver_prefs
.compression
) {
1186 case COMPRESSION_GZIP
:
1187 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gzip_radio_btn
), TRUE
);
1189 case COMPRESSION_BZIP
:
1190 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bzip_radio_btn
), TRUE
);
1192 case COMPRESSION_COMPRESS
:
1193 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compress_radio_btn
), TRUE
);
1195 #if ARCHIVE_VERSION_NUMBER >= 2006990
1196 case COMPRESSION_LZMA
:
1197 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lzma_radio_btn
), TRUE
);
1199 case COMPRESSION_XZ
:
1200 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(xz_radio_btn
), TRUE
);
1203 #if ARCHIVE_VERSION_NUMBER >= 3000000
1204 case COMPRESSION_LZIP
:
1205 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lzip_radio_btn
), TRUE
);
1208 #if ARCHIVE_VERSION_NUMBER >= 3001000
1209 case COMPRESSION_LRZIP
:
1210 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lrzip_radio_btn
), TRUE
);
1212 case COMPRESSION_LZOP
:
1213 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lzop_radio_btn
), TRUE
);
1215 case COMPRESSION_GRZIP
:
1216 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grzip_radio_btn
), TRUE
);
1219 #if ARCHIVE_VERSION_NUMBER >= 3001900
1220 case COMPRESSION_LZ4
:
1221 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lz4_radio_btn
), TRUE
);
1224 case COMPRESSION_NONE
:
1225 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(no_radio_btn
), TRUE
);
1229 frame
= gtk_frame_new(_("Choose format"));
1230 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_OUT
);
1231 gtk_container_set_border_width(GTK_CONTAINER(frame
), 4);
1232 gtk_box_pack_start(GTK_BOX(vbox1
), frame
, FALSE
, FALSE
, 0);
1234 hbox1
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
1235 gtk_container_set_border_width(GTK_CONTAINER(hbox1
), 4);
1236 gtk_container_add(GTK_CONTAINER(frame
), hbox1
);
1238 tar_radio_btn
= gtk_radio_button_new_with_mnemonic(NULL
, "_TAR");
1239 gtk_widget_set_name(tar_radio_btn
, "TAR");
1240 gtk_box_pack_start(GTK_BOX(hbox1
), tar_radio_btn
, FALSE
, FALSE
, 0);
1241 archiver_set_tooltip(tar_radio_btn
, g_strdup_printf(_("Choose this to use %s as format for the archive"), "TAR"));
1243 shar_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1244 GTK_RADIO_BUTTON(tar_radio_btn
), "S_HAR");
1245 gtk_widget_set_name(shar_radio_btn
, "SHAR");
1246 gtk_box_pack_start(GTK_BOX(hbox1
), shar_radio_btn
, FALSE
, FALSE
, 0);
1247 archiver_set_tooltip(shar_radio_btn
, g_strdup_printf(_("Choose this to use %s as format for the archive"), "SHAR"));
1249 cpio_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1250 GTK_RADIO_BUTTON(tar_radio_btn
), "CP_IO");
1251 gtk_widget_set_name(cpio_radio_btn
, "CPIO");
1252 gtk_box_pack_start(GTK_BOX(hbox1
), cpio_radio_btn
, FALSE
, FALSE
, 0);
1253 archiver_set_tooltip(cpio_radio_btn
, g_strdup_printf(_("Choose this to use %s as format for the archive"), "CPIO"));
1255 pax_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1256 GTK_RADIO_BUTTON(tar_radio_btn
), "PA_X");
1257 gtk_widget_set_name(pax_radio_btn
, "PAX");
1258 gtk_box_pack_start(GTK_BOX(hbox1
), pax_radio_btn
, FALSE
, FALSE
, 0);
1259 archiver_set_tooltip(pax_radio_btn
, g_strdup_printf(_("Choose this to use %s as format for the archive"), "PAX"));
1261 page
->archive_formats
=
1262 gtk_radio_button_get_group(GTK_RADIO_BUTTON(tar_radio_btn
));
1264 switch (archiver_prefs
.format
) {
1266 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tar_radio_btn
), TRUE
);
1269 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shar_radio_btn
), TRUE
);
1272 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cpio_radio_btn
), TRUE
);
1275 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pax_radio_btn
), TRUE
);
1279 frame
= gtk_frame_new(_("Miscellaneous options"));
1280 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_OUT
);
1281 gtk_container_set_border_width(GTK_CONTAINER(frame
), 4);
1282 gtk_box_pack_start(GTK_BOX(vbox1
), frame
, FALSE
, FALSE
, 0);
1284 hbox1
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
1285 gtk_container_set_border_width(GTK_CONTAINER(hbox1
), 4);
1286 gtk_container_add(GTK_CONTAINER(frame
), hbox1
);
1288 page
->recursive
= gtk_check_button_new_with_mnemonic(_("_Recursive"));
1289 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page
->recursive
), archiver_prefs
.recursive
);
1290 gtk_box_pack_start(GTK_BOX(hbox1
), page
->recursive
, FALSE
, FALSE
, 0);
1291 CLAWS_SET_TIP(page
->recursive
,
1292 _("Choose this option to include subfolders in the archive"));
1294 page
->md5sum
= gtk_check_button_new_with_mnemonic(_("_MD5sum"));
1295 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page
->md5sum
), archiver_prefs
.md5sum
);
1296 gtk_box_pack_start(GTK_BOX(hbox1
), page
->md5sum
, FALSE
, FALSE
, 0);
1297 CLAWS_SET_TIP(page
->md5sum
,
1298 _("Choose this option to add MD5 checksums for each file in the archive.\n"
1299 "Be aware though, that this dramatically increases the time it\n"
1300 "will take to create the archive"));
1302 page
->rename_files
= gtk_check_button_new_with_mnemonic(_("R_ename"));
1303 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page
->rename_files
), archiver_prefs
.rename
);
1304 gtk_box_pack_start(GTK_BOX(hbox1
), page
->rename_files
, FALSE
, FALSE
, 0);
1305 CLAWS_SET_TIP(page
->rename_files
,
1306 _("Choose this option to use descriptive names for each file in the archive.\n"
1307 "The naming scheme: date_from@to@subject.\n"
1308 "Names will be truncated to max 96 characters"));
1310 page
->unlink_files
= gtk_check_button_new_with_mnemonic(_("_Delete"));
1311 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page
->unlink_files
), archiver_prefs
.unlink
);
1312 gtk_box_pack_start(GTK_BOX(hbox1
), page
->unlink_files
, FALSE
, FALSE
, 0);
1313 CLAWS_SET_TIP(page
->unlink_files
,
1314 _("Choose this option to delete mails after archiving\n"
1315 "At this point only handles IMAP4, Local mbox and POP3"));
1318 frame
= gtk_frame_new(_("Selection options"));
1319 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_OUT
);
1320 gtk_container_set_border_width(GTK_CONTAINER(frame
), 4);
1321 gtk_box_pack_start(GTK_BOX(vbox1
), frame
, FALSE
, FALSE
, 0);
1323 hbox1
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
1324 gtk_container_set_border_width(GTK_CONTAINER(hbox1
), 4);
1325 gtk_container_add(GTK_CONTAINER(frame
), hbox1
);
1327 file_label
= gtk_label_new(_("Select mails before"));
1328 gtk_box_pack_start(GTK_BOX(hbox1
), file_label
, FALSE
, FALSE
, 0);
1330 page
->isoDate
= gtk_entry_new();
1331 gtk_widget_set_name(page
->isoDate
, "isoDate");
1332 gtk_box_pack_start(GTK_BOX(hbox1
), page
->isoDate
, TRUE
, TRUE
, 0);
1333 CLAWS_SET_TIP(page
->isoDate
,
1334 _("Select emails before a certain date\n"
1335 "Date must comply to ISO-8601 [YYYY-MM-DD]"));
1337 g_signal_connect(G_OBJECT(folder_select
), "clicked",
1338 G_CALLBACK(foldersel_cb
), page
);
1339 g_signal_connect(G_OBJECT(file_select
), "clicked",
1340 G_CALLBACK(filesel_cb
), page
);
1341 g_signal_connect(G_OBJECT(page
->folder
), "activate",
1342 G_CALLBACK(entry_change_cb
), page
);
1343 g_signal_connect(G_OBJECT(page
->file
), "activate",
1344 G_CALLBACK(entry_change_cb
), page
);
1346 gtk_widget_show_all(dialog
);
1349 void archiver_gtk_done(struct ArchivePage
* page
, GtkWidget
* widget
) {
1350 dispose_archive_page(page
);
1352 gtk_widget_destroy(widget
);
1353 /*debug_set_mode(FALSE);*/