1 /* vim: set textwidth=80 tabstop=4 */
4 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
5 * Copyright (C) 1999-2023 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
)
935 GtkFileChooserNative
*dialog
;
938 struct ArchivePage
* page
= (struct ArchivePage
*) data
;
940 dialog
= gtk_file_chooser_native_new(
941 _("Select file name for archive [suffix should reflect archive like .tgz]"),
943 GTK_FILE_CHOOSER_ACTION_SAVE
,
947 if (archiver_prefs
.save_folder
)
948 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog
),
949 archiver_prefs
.save_folder
);
951 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog
),
953 if (gtk_native_dialog_run (GTK_NATIVE_DIALOG(dialog
)) == GTK_RESPONSE_ACCEPT
) {
954 file
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog
));
956 gtk_editable_delete_text(GTK_EDITABLE(page
->file
), 0, -1);
957 gtk_editable_insert_text(GTK_EDITABLE(page
->file
),
958 file
, strlen(file
), &newpos
);
959 page
->name
= g_strdup(file
);
961 page
->force_overwrite
= TRUE
;
964 g_object_unref(dialog
);
965 debug_print("Name for archive: %s\n",
966 gtk_entry_get_text(GTK_ENTRY(page
->file
)));
969 void set_progress_file_label(const gchar
* file
) {
970 debug_print("IsLabel: %s, Update label: %s\n",
971 GTK_IS_WIDGET(progress
->file_label
)? "Yes" : "No", file
);
972 if (GTK_IS_WIDGET(progress
->file_label
))
973 gtk_label_set_text(GTK_LABEL(progress
->file_label
), file
);
976 void set_progress_print_all(guint fraction
, guint total
, guint step
) {
979 if (GTK_IS_WIDGET(progress
->progress
)) {
980 if ((fraction
- progress
->position
) % step
== 0) {
981 debug_print("frac: %d, total: %d, step: %d, prog->pos: %d\n",
982 fraction
, total
, step
, progress
->position
);
983 gtk_progress_bar_set_fraction(
984 GTK_PROGRESS_BAR(progress
->progress
),
985 (total
== 0) ? 0 : (gfloat
)fraction
/ (gfloat
)total
);
986 text_count
= g_strdup_printf(_("%ld of %ld"),
987 (long) fraction
, (long) total
);
988 gtk_progress_bar_set_text(
989 GTK_PROGRESS_BAR(progress
->progress
), text_count
);
991 progress
->position
= fraction
;
997 void archiver_gtk_show(void) {
1002 GtkWidget
* folder_label
;
1003 GtkWidget
* folder_select
;
1004 GtkWidget
* file_label
;
1005 GtkWidget
* file_select
;
1006 GtkWidget
* gzip_radio_btn
;
1007 GtkWidget
* bzip_radio_btn
;
1008 GtkWidget
* compress_radio_btn
;
1009 #if ARCHIVE_VERSION_NUMBER >= 2006990
1010 GtkWidget
* lzma_radio_btn
;
1011 GtkWidget
* xz_radio_btn
;
1013 #if ARCHIVE_VERSION_NUMBER >= 3000000
1014 GtkWidget
* lzip_radio_btn
;
1016 #if ARCHIVE_VERSION_NUMBER >= 3001000
1017 GtkWidget
* lrzip_radio_btn
;
1018 GtkWidget
* lzop_radio_btn
;
1019 GtkWidget
* grzip_radio_btn
;
1021 #if ARCHIVE_VERSION_NUMBER >= 3001900
1022 GtkWidget
* lz4_radio_btn
;
1024 GtkWidget
* no_radio_btn
;
1025 GtkWidget
* shar_radio_btn
;
1026 GtkWidget
* pax_radio_btn
;
1027 GtkWidget
* cpio_radio_btn
;
1028 GtkWidget
* tar_radio_btn
;
1029 GtkWidget
* content_area
;
1030 struct ArchivePage
* page
;
1031 MainWindow
* mainwin
= mainwindow_get_mainwindow();
1033 /*debug_set_mode(TRUE);*/
1034 progress
= init_progress();
1036 page
= init_archive_page();
1038 dialog
= gtk_dialog_new_with_buttons (
1039 _("Create Archive"),
1040 GTK_WINDOW(mainwin
->window
),
1041 GTK_DIALOG_DESTROY_WITH_PARENT
,
1043 GTK_RESPONSE_CANCEL
,
1045 GTK_RESPONSE_ACCEPT
,
1051 G_CALLBACK(archiver_dialog_cb
),
1054 frame
= gtk_frame_new(_("Enter Archiver arguments"));
1055 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_OUT
);
1056 gtk_container_set_border_width(GTK_CONTAINER(frame
), 4);
1057 content_area
= gtk_dialog_get_content_area(GTK_DIALOG(dialog
));
1058 gtk_container_add(GTK_CONTAINER(content_area
), frame
);
1060 vbox1
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 4);
1061 gtk_container_set_border_width (GTK_CONTAINER (vbox1
), 4);
1062 gtk_container_add(GTK_CONTAINER(frame
), vbox1
);
1064 hbox1
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
1065 gtk_container_set_border_width(GTK_CONTAINER(hbox1
), 4);
1066 gtk_box_pack_start(GTK_BOX(vbox1
), hbox1
, FALSE
, FALSE
, 0);
1068 folder_label
= gtk_label_new(_("Folder to archive"));
1069 gtk_box_pack_start(GTK_BOX(hbox1
), folder_label
, FALSE
, FALSE
, 0);
1071 page
->folder
= gtk_entry_new();
1072 gtk_widget_set_name(page
->folder
, "folder");
1073 gtk_box_pack_start(GTK_BOX(hbox1
), page
->folder
, TRUE
, TRUE
, 0);
1074 CLAWS_SET_TIP(page
->folder
,
1075 _("Folder which is the root of the archive"));
1077 folder_select
= gtkut_get_browse_directory_btn(_("_Browse"));
1078 gtk_box_pack_start(GTK_BOX(hbox1
), folder_select
, FALSE
, FALSE
, 0);
1079 CLAWS_SET_TIP(folder_select
,
1080 _("Click this button to select a folder which is to be root of the archive"));
1082 hbox1
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
1083 gtk_container_set_border_width(GTK_CONTAINER(hbox1
), 4);
1084 gtk_box_pack_start(GTK_BOX(vbox1
), hbox1
, FALSE
, FALSE
, 0);
1086 file_label
= gtk_label_new(_("Name for archive"));
1087 gtk_box_pack_start(GTK_BOX(hbox1
), file_label
, FALSE
, FALSE
, 0);
1089 page
->file
= gtk_entry_new();
1090 gtk_widget_set_name(page
->file
, "file");
1091 gtk_box_pack_start(GTK_BOX(hbox1
), page
->file
, TRUE
, TRUE
, 0);
1092 CLAWS_SET_TIP(page
->file
, _("Archive location and name"));
1094 file_select
= gtkut_get_browse_directory_btn(_("_Select"));
1095 gtk_box_pack_start(GTK_BOX(hbox1
), file_select
, FALSE
, FALSE
, 0);
1096 CLAWS_SET_TIP(file_select
,
1097 _("Click this button to select a name and location for the archive"));
1099 frame
= gtk_frame_new(_("Choose compression"));
1100 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_OUT
);
1101 gtk_container_set_border_width(GTK_CONTAINER(frame
), 4);
1102 gtk_box_pack_start(GTK_BOX(vbox1
), frame
, FALSE
, FALSE
, 0);
1104 hbox1
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
1105 gtk_container_set_border_width(GTK_CONTAINER(hbox1
), 4);
1106 gtk_container_add(GTK_CONTAINER(frame
), hbox1
);
1108 gzip_radio_btn
= gtk_radio_button_new_with_mnemonic(NULL
, "G_ZIP");
1109 gtk_widget_set_name(gzip_radio_btn
, "GZIP");
1110 gtk_box_pack_start(GTK_BOX(hbox1
), gzip_radio_btn
, FALSE
, FALSE
, 0);
1111 archiver_set_tooltip(gzip_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "GZIP"));
1113 bzip_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1114 GTK_RADIO_BUTTON(gzip_radio_btn
), "BZIP_2");
1115 gtk_widget_set_name(bzip_radio_btn
, "BZIP");
1116 gtk_box_pack_start(GTK_BOX(hbox1
), bzip_radio_btn
, FALSE
, FALSE
, 0);
1117 archiver_set_tooltip(bzip_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "BZIP2"));
1119 compress_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1120 GTK_RADIO_BUTTON(gzip_radio_btn
), "Com_press");
1121 gtk_widget_set_name(compress_radio_btn
, "COMPRESS");
1122 gtk_box_pack_start(GTK_BOX(hbox1
), compress_radio_btn
, FALSE
, FALSE
, 0);
1123 archiver_set_tooltip(compress_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "COMPRESS"));
1125 #if ARCHIVE_VERSION_NUMBER >= 2006990
1126 lzma_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1127 GTK_RADIO_BUTTON(gzip_radio_btn
), "_LZMA");
1128 gtk_widget_set_name(lzma_radio_btn
, "LZMA");
1129 gtk_box_pack_start(GTK_BOX(hbox1
), lzma_radio_btn
, FALSE
, FALSE
, 0);
1130 archiver_set_tooltip(lzma_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "LZMA"));
1132 xz_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1133 GTK_RADIO_BUTTON(gzip_radio_btn
), "_XZ");
1134 gtk_widget_set_name(xz_radio_btn
, "XZ");
1135 gtk_box_pack_start(GTK_BOX(hbox1
), xz_radio_btn
, FALSE
, FALSE
, 0);
1136 archiver_set_tooltip(xz_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "XZ"));
1139 #if ARCHIVE_VERSION_NUMBER >= 3000000
1140 lzip_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1141 GTK_RADIO_BUTTON(gzip_radio_btn
), "_LZIP");
1142 gtk_widget_set_name(lzip_radio_btn
, "LZIP");
1143 gtk_box_pack_start(GTK_BOX(hbox1
), lzip_radio_btn
, FALSE
, FALSE
, 0);
1144 archiver_set_tooltip(lzip_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "LZIP"));
1147 #if ARCHIVE_VERSION_NUMBER >= 3001000
1148 lrzip_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1149 GTK_RADIO_BUTTON(gzip_radio_btn
), "L_RZIP");
1150 gtk_widget_set_name(lrzip_radio_btn
, "LRZIP");
1151 gtk_box_pack_start(GTK_BOX(hbox1
), lrzip_radio_btn
, FALSE
, FALSE
, 0);
1152 archiver_set_tooltip(lrzip_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "LRZIP"));
1154 lzop_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1155 GTK_RADIO_BUTTON(gzip_radio_btn
), "LZ_OP");
1156 gtk_widget_set_name(lzop_radio_btn
, "LZOP");
1157 gtk_box_pack_start(GTK_BOX(hbox1
), lzop_radio_btn
, FALSE
, FALSE
, 0);
1158 archiver_set_tooltip(lzop_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "LZOP"));
1160 grzip_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1161 GTK_RADIO_BUTTON(gzip_radio_btn
), "_GRZIP");
1162 gtk_widget_set_name(grzip_radio_btn
, "GRZIP");
1163 gtk_box_pack_start(GTK_BOX(hbox1
), grzip_radio_btn
, FALSE
, FALSE
, 0);
1164 archiver_set_tooltip(grzip_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "GRZIP"));
1167 #if ARCHIVE_VERSION_NUMBER >= 3001900
1168 lz4_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1169 GTK_RADIO_BUTTON(gzip_radio_btn
), "LZ_4");
1170 gtk_widget_set_name(lz4_radio_btn
, "LZ4");
1171 gtk_box_pack_start(GTK_BOX(hbox1
), lz4_radio_btn
, FALSE
, FALSE
, 0);
1172 archiver_set_tooltip(lz4_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "LZ4"));
1175 no_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1176 GTK_RADIO_BUTTON(gzip_radio_btn
), _("_None"));
1177 gtk_widget_set_name(no_radio_btn
, "NONE");
1178 gtk_box_pack_start(GTK_BOX(hbox1
), no_radio_btn
, FALSE
, FALSE
, 0);
1179 archiver_set_tooltip(no_radio_btn
, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "NO"));
1181 page
->compress_methods
=
1182 gtk_radio_button_get_group(GTK_RADIO_BUTTON(gzip_radio_btn
));
1184 switch (archiver_prefs
.compression
) {
1185 case COMPRESSION_GZIP
:
1186 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gzip_radio_btn
), TRUE
);
1188 case COMPRESSION_BZIP
:
1189 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bzip_radio_btn
), TRUE
);
1191 case COMPRESSION_COMPRESS
:
1192 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compress_radio_btn
), TRUE
);
1194 #if ARCHIVE_VERSION_NUMBER >= 2006990
1195 case COMPRESSION_LZMA
:
1196 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lzma_radio_btn
), TRUE
);
1198 case COMPRESSION_XZ
:
1199 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(xz_radio_btn
), TRUE
);
1202 #if ARCHIVE_VERSION_NUMBER >= 3000000
1203 case COMPRESSION_LZIP
:
1204 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lzip_radio_btn
), TRUE
);
1207 #if ARCHIVE_VERSION_NUMBER >= 3001000
1208 case COMPRESSION_LRZIP
:
1209 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lrzip_radio_btn
), TRUE
);
1211 case COMPRESSION_LZOP
:
1212 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lzop_radio_btn
), TRUE
);
1214 case COMPRESSION_GRZIP
:
1215 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grzip_radio_btn
), TRUE
);
1218 #if ARCHIVE_VERSION_NUMBER >= 3001900
1219 case COMPRESSION_LZ4
:
1220 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lz4_radio_btn
), TRUE
);
1223 case COMPRESSION_NONE
:
1224 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(no_radio_btn
), TRUE
);
1228 frame
= gtk_frame_new(_("Choose format"));
1229 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_OUT
);
1230 gtk_container_set_border_width(GTK_CONTAINER(frame
), 4);
1231 gtk_box_pack_start(GTK_BOX(vbox1
), frame
, FALSE
, FALSE
, 0);
1233 hbox1
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
1234 gtk_container_set_border_width(GTK_CONTAINER(hbox1
), 4);
1235 gtk_container_add(GTK_CONTAINER(frame
), hbox1
);
1237 tar_radio_btn
= gtk_radio_button_new_with_mnemonic(NULL
, "_TAR");
1238 gtk_widget_set_name(tar_radio_btn
, "TAR");
1239 gtk_box_pack_start(GTK_BOX(hbox1
), tar_radio_btn
, FALSE
, FALSE
, 0);
1240 archiver_set_tooltip(tar_radio_btn
, g_strdup_printf(_("Choose this to use %s as format for the archive"), "TAR"));
1242 shar_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1243 GTK_RADIO_BUTTON(tar_radio_btn
), "S_HAR");
1244 gtk_widget_set_name(shar_radio_btn
, "SHAR");
1245 gtk_box_pack_start(GTK_BOX(hbox1
), shar_radio_btn
, FALSE
, FALSE
, 0);
1246 archiver_set_tooltip(shar_radio_btn
, g_strdup_printf(_("Choose this to use %s as format for the archive"), "SHAR"));
1248 cpio_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1249 GTK_RADIO_BUTTON(tar_radio_btn
), "CP_IO");
1250 gtk_widget_set_name(cpio_radio_btn
, "CPIO");
1251 gtk_box_pack_start(GTK_BOX(hbox1
), cpio_radio_btn
, FALSE
, FALSE
, 0);
1252 archiver_set_tooltip(cpio_radio_btn
, g_strdup_printf(_("Choose this to use %s as format for the archive"), "CPIO"));
1254 pax_radio_btn
= gtk_radio_button_new_with_mnemonic_from_widget(
1255 GTK_RADIO_BUTTON(tar_radio_btn
), "PA_X");
1256 gtk_widget_set_name(pax_radio_btn
, "PAX");
1257 gtk_box_pack_start(GTK_BOX(hbox1
), pax_radio_btn
, FALSE
, FALSE
, 0);
1258 archiver_set_tooltip(pax_radio_btn
, g_strdup_printf(_("Choose this to use %s as format for the archive"), "PAX"));
1260 page
->archive_formats
=
1261 gtk_radio_button_get_group(GTK_RADIO_BUTTON(tar_radio_btn
));
1263 switch (archiver_prefs
.format
) {
1265 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tar_radio_btn
), TRUE
);
1268 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shar_radio_btn
), TRUE
);
1271 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cpio_radio_btn
), TRUE
);
1274 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pax_radio_btn
), TRUE
);
1278 frame
= gtk_frame_new(_("Miscellaneous options"));
1279 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_OUT
);
1280 gtk_container_set_border_width(GTK_CONTAINER(frame
), 4);
1281 gtk_box_pack_start(GTK_BOX(vbox1
), frame
, FALSE
, FALSE
, 0);
1283 hbox1
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
1284 gtk_container_set_border_width(GTK_CONTAINER(hbox1
), 4);
1285 gtk_container_add(GTK_CONTAINER(frame
), hbox1
);
1287 page
->recursive
= gtk_check_button_new_with_mnemonic(_("_Recursive"));
1288 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page
->recursive
), archiver_prefs
.recursive
);
1289 gtk_box_pack_start(GTK_BOX(hbox1
), page
->recursive
, FALSE
, FALSE
, 0);
1290 CLAWS_SET_TIP(page
->recursive
,
1291 _("Choose this option to include subfolders in the archive"));
1293 page
->md5sum
= gtk_check_button_new_with_mnemonic(_("_MD5sum"));
1294 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page
->md5sum
), archiver_prefs
.md5sum
);
1295 gtk_box_pack_start(GTK_BOX(hbox1
), page
->md5sum
, FALSE
, FALSE
, 0);
1296 CLAWS_SET_TIP(page
->md5sum
,
1297 _("Choose this option to add MD5 checksums for each file in the archive.\n"
1298 "Be aware though, that this dramatically increases the time it\n"
1299 "will take to create the archive"));
1301 page
->rename_files
= gtk_check_button_new_with_mnemonic(_("R_ename"));
1302 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page
->rename_files
), archiver_prefs
.rename
);
1303 gtk_box_pack_start(GTK_BOX(hbox1
), page
->rename_files
, FALSE
, FALSE
, 0);
1304 CLAWS_SET_TIP(page
->rename_files
,
1305 _("Choose this option to use descriptive names for each file in the archive.\n"
1306 "The naming scheme: date_from@to@subject.\n"
1307 "Names will be truncated to max 96 characters"));
1309 page
->unlink_files
= gtk_check_button_new_with_mnemonic(_("_Delete"));
1310 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page
->unlink_files
), archiver_prefs
.unlink
);
1311 gtk_box_pack_start(GTK_BOX(hbox1
), page
->unlink_files
, FALSE
, FALSE
, 0);
1312 CLAWS_SET_TIP(page
->unlink_files
,
1313 _("Choose this option to delete mails after archiving\n"
1314 "At this point only handles IMAP4, Local mbox and POP3"));
1317 frame
= gtk_frame_new(_("Selection options"));
1318 gtk_frame_set_shadow_type(GTK_FRAME(frame
), GTK_SHADOW_ETCHED_OUT
);
1319 gtk_container_set_border_width(GTK_CONTAINER(frame
), 4);
1320 gtk_box_pack_start(GTK_BOX(vbox1
), frame
, FALSE
, FALSE
, 0);
1322 hbox1
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 4);
1323 gtk_container_set_border_width(GTK_CONTAINER(hbox1
), 4);
1324 gtk_container_add(GTK_CONTAINER(frame
), hbox1
);
1326 file_label
= gtk_label_new(_("Select mails before"));
1327 gtk_box_pack_start(GTK_BOX(hbox1
), file_label
, FALSE
, FALSE
, 0);
1329 page
->isoDate
= gtk_entry_new();
1330 gtk_widget_set_name(page
->isoDate
, "isoDate");
1331 gtk_box_pack_start(GTK_BOX(hbox1
), page
->isoDate
, TRUE
, TRUE
, 0);
1332 CLAWS_SET_TIP(page
->isoDate
,
1333 _("Select emails before a certain date\n"
1334 "Date must comply to ISO-8601 [YYYY-MM-DD]"));
1336 g_signal_connect(G_OBJECT(folder_select
), "clicked",
1337 G_CALLBACK(foldersel_cb
), page
);
1338 g_signal_connect(G_OBJECT(file_select
), "clicked",
1339 G_CALLBACK(filesel_cb
), page
);
1340 g_signal_connect(G_OBJECT(page
->folder
), "activate",
1341 G_CALLBACK(entry_change_cb
), page
);
1342 g_signal_connect(G_OBJECT(page
->file
), "activate",
1343 G_CALLBACK(entry_change_cb
), page
);
1345 gtk_widget_show_all(dialog
);
1348 void archiver_gtk_done(struct ArchivePage
* page
, GtkWidget
* widget
) {
1349 dispose_archive_page(page
);
1351 gtk_widget_destroy(widget
);
1352 /*debug_set_mode(FALSE);*/