604ac25a4655c53ecc76838e05ba293ab7b747be
[claws.git] / src / plugins / archive / archiver_gtk.c
1 /* vim: set textwidth=80 tabstop=4 */
2
3 /*
4  * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
5  * Copyright (C) 1999-2008 Michael Rasmussen and the Claws Mail Team
6  *
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.
11  ii*
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.
16  *
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/>.
19  * 
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include "config.h"
24 #include "claws-features.h"
25 #endif
26
27 #include <glib.h>
28 #include <glib/gi18n.h>
29
30 #include "defs.h"
31
32 #include <gtk/gtk.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <errno.h>
37
38 #include "gtk/gtkutils.h"
39 #include "common/claws.h"
40 #include "common/version.h"
41 #include "common/md5.h"
42 #include "plugin.h"
43 #include "mainwindow.h"
44 #include "utils.h"
45 #include "prefs.h"
46 #include "folder.h"
47 #include "foldersel.h"
48 #include "procmsg.h"
49 #include "procheader.h"
50 #include "libarchive_archive.h"
51 #include "archiver.h"
52 #include "archiver_prefs.h"
53 #include "alertpanel.h"
54
55 #include <archive.h>
56
57 typedef struct _progress_widget progress_widget;
58 struct _progress_widget {
59         GtkWidget*      progress_dialog;
60         GtkWidget*      frame;
61         GtkWidget*      vbox1;
62         GtkWidget*      hbox1;
63         GtkWidget*      add_label;
64         GtkWidget*      file_label;
65         GtkWidget*      progress;
66         guint           position;
67 };
68
69 typedef enum {
70     A_FILE_OK           = 1 << 0,
71     A_FILE_EXISTS       = 1 << 1,
72     A_FILE_IS_LINK      = 1 << 2,
73     A_FILE_IS_DIR       = 1 << 3,
74     A_FILE_NO_WRITE     = 1 << 4,
75     A_FILE_UNKNOWN      = 1 << 5
76 } AFileTest;
77
78 static progress_widget* progress = NULL;
79
80 static progress_widget* init_progress() {
81         progress_widget* ptr = malloc(sizeof(*ptr));
82
83         debug_print("creating progress struct\n");
84         ptr->progress_dialog = NULL;
85         ptr->frame = NULL;
86         ptr->vbox1 = NULL;
87         ptr->hbox1 = NULL;
88         ptr->add_label = NULL;
89         ptr->file_label = NULL;
90         ptr->progress = NULL;
91         ptr->position = 0;
92
93         return ptr;
94 }
95
96 static void progress_dialog_cb(GtkWidget* widget, gint action, gpointer data) {
97         struct ArchivePage* page = (struct ArchivePage *) data;
98
99         debug_print("Cancel operation\n");
100         stop_archiving();
101         page->cancelled = TRUE;
102         archive_free_file_list(page->md5, page->rename);
103         gtk_widget_destroy(widget);
104 }
105
106 static void create_progress_dialog(struct ArchivePage* page) {
107         gchar* title = g_strdup_printf("%s %s", _("Archiving"), page->path);
108         MainWindow* mainwin = mainwindow_get_mainwindow();
109
110         progress->position = 0;
111         progress->progress_dialog = gtk_dialog_new_with_buttons (
112                                 title,
113                                 GTK_WINDOW(mainwin->window),
114                                 GTK_DIALOG_DESTROY_WITH_PARENT,
115                                 GTK_STOCK_CANCEL,
116                                 GTK_RESPONSE_CANCEL,
117                                 NULL);
118
119         g_signal_connect (
120                                 progress->progress_dialog,
121                                 "response",
122                                 G_CALLBACK(progress_dialog_cb),
123                                 page);
124
125         progress->frame = gtk_frame_new(_("Press Cancel button to stop archiving"));
126         gtk_frame_set_shadow_type(GTK_FRAME(progress->frame),
127                                         GTK_SHADOW_ETCHED_OUT);
128         gtk_container_set_border_width(GTK_CONTAINER(progress->frame), 4);
129         gtk_container_add(GTK_CONTAINER(
130                                 GTK_DIALOG(progress->progress_dialog)->vbox), progress->frame);
131
132         progress->vbox1 = gtk_vbox_new (FALSE, 4);
133         gtk_container_set_border_width (GTK_CONTAINER (progress->vbox1), 4);
134         gtk_container_add(GTK_CONTAINER(progress->frame), progress->vbox1);
135         
136         progress->hbox1 = gtk_hbox_new(FALSE, 8);
137         gtk_container_set_border_width(GTK_CONTAINER(progress->hbox1), 8);
138         gtk_box_pack_start(GTK_BOX(progress->vbox1),
139                                         progress->hbox1, FALSE, FALSE, 0);
140
141         progress->add_label = gtk_label_new(_("Archiving:"));
142         gtk_box_pack_start(GTK_BOX(progress->hbox1),
143                                         progress->add_label, FALSE, FALSE, 0);
144
145         progress->file_label = gtk_label_new("");
146         gtk_label_set_ellipsize(GTK_LABEL(progress->file_label),
147                                         PANGO_ELLIPSIZE_START);
148         gtk_box_pack_start(GTK_BOX(progress->hbox1),
149                                         progress->file_label, TRUE, TRUE, 0);
150
151         progress->hbox1 = gtk_hbox_new(FALSE, 8);
152         gtk_container_set_border_width(GTK_CONTAINER(progress->hbox1), 8);
153         gtk_box_pack_start(GTK_BOX(progress->vbox1),
154                                         progress->hbox1, FALSE, FALSE, 0);
155
156         progress->progress = gtk_progress_bar_new();
157         gtk_box_pack_start(GTK_BOX(progress->hbox1), 
158                                         progress->progress, TRUE, TRUE, 0);
159         gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(progress->progress), 0.25);
160
161         gtk_window_set_default_size(GTK_WINDOW(progress->progress_dialog), 400, 80);
162         gtk_widget_show_all(progress->progress_dialog);
163 }
164
165 static struct ArchivePage* init_archive_page() {
166         struct ArchivePage* page = malloc(sizeof(struct ArchivePage));
167
168         debug_print("creating ArchivePage\n");
169         page->path = NULL;
170         page->name = NULL;
171         page->file = NULL;
172         page->folder = NULL;
173         page->response = FALSE;
174         page->force_overwrite = FALSE;
175         page->compress_methods = NULL;
176         page->archive_formats = NULL;
177         page->recursive = NULL;
178         page->cancelled = FALSE;
179         page->md5 = FALSE;
180         page->md5sum = NULL;
181         page->rename = FALSE;
182         page->rename_files = NULL;
183         page->isoDate = NULL;
184         page->unlink_files = NULL;
185         page->unlink = FALSE;
186
187         return page;
188 }
189
190 static void dispose_archive_page(struct ArchivePage* page) {
191         debug_print("freeing ArchivePage\n");
192         if (page->path)
193                 g_free(page->path);
194         page->path = NULL;
195         if (page->name)
196                 g_free(page->name);
197         page->name = NULL;
198         g_free(page);
199 }
200
201 static gboolean valid_file_name(gchar* file) {
202         int i;
203
204         for (i = 0; INVALID_UNIX_CHARS[i] != '\0'; i++) {
205                 if (g_utf8_strchr(file, g_utf8_strlen(file, -1), INVALID_UNIX_CHARS[i]))
206                         return FALSE;
207         }
208         return TRUE;
209 }
210
211 static COMPRESS_METHOD get_compress_method(GSList* btn) {
212         const gchar* name;
213
214         while (btn) {
215                 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(btn->data))) {
216                         name = gtk_widget_get_name(GTK_WIDGET(btn->data));
217                         if (strcmp("GZIP", name) == 0) {
218                                 debug_print("GZIP compression enabled\n");
219                                 return GZIP;
220                         }
221                         else if (strcmp("BZIP", name) == 0) {
222                                 debug_print("BZIP2 compression enabled\n");
223                                 return BZIP2;
224                         }
225             else if (strcmp("COMPRESS", name) == 0) {
226                                 debug_print("COMPRESS compression enabled\n");
227                                 return COMPRESS;
228                         }
229 #if ARCHIVE_VERSION_NUMBER >= 2006990
230                         else if (strcmp("LZMA", name) == 0) {
231                                 debug_print("LZMA compression enabled\n");
232                                 return LZMA;
233                         }
234                         else if (strcmp("XZ", name) == 0) {
235                                 debug_print("XZ compression enabled\n");
236                                 return XZ;
237                         }
238 #endif
239 #if ARCHIVE_VERSION_NUMBER >= 3000000
240                         else if (strcmp("LZIP", name) == 0) {
241                                 debug_print("LZIP compression enabled\n");
242                                 return LZIP;
243                         }
244 #endif
245 #if ARCHIVE_VERSION_NUMBER >= 3001000
246                         else if (strcmp("LRZIP", name) == 0) {
247                                 debug_print("LRZIP compression enabled\n");
248                                 return LRZIP;
249                         }
250                         else if (strcmp("LZOP", name) == 0) {
251                                 debug_print("LZOP compression enabled\n");
252                                 return LZOP;
253                         }
254                         else if (strcmp("GRZIP", name) == 0) {
255                                 debug_print("GRZIP compression enabled\n");
256                                 return GRZIP;
257                         }
258 #endif
259 #if ARCHIVE_VERSION_NUMBER >= 3001900
260                         else if (strcmp("LZ4", name) == 0) {
261                                 debug_print("LZ4 compression enabled\n");
262                                 return LZ4;
263                         }
264 #endif
265                         else if (strcmp("NONE", name) == 0) {
266                                 debug_print("Compression disabled\n");
267                                 return NO_COMPRESS;
268                         }
269                 }
270                 btn = g_slist_next(btn);
271         }
272         return NO_COMPRESS;
273 }
274
275 static ARCHIVE_FORMAT get_archive_format(GSList* btn) {
276         const gchar* name;
277
278         while (btn) {
279                 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(btn->data))) {
280                         name = gtk_widget_get_name(GTK_WIDGET(btn->data));
281                         if (strcmp("TAR", name) == 0) {
282                                 debug_print("TAR archive enabled\n");
283                                 return TAR;
284                         }
285                         else if (strcmp("SHAR", name) == 0) {
286                                 debug_print("SHAR archive enabled\n");
287                                 return SHAR;
288                         }
289                         else if (strcmp("PAX", name) == 0) {
290                                 debug_print("PAX archive enabled\n");
291                                 return PAX;
292                         }
293                         else if (strcmp("CPIO", name) == 0) {
294                                 debug_print("CPIO archive enabled\n");
295                                 return CPIO;
296                         }
297                 }
298                 btn = g_slist_next(btn);
299         }
300         return NO_FORMAT;
301 }
302
303 static void create_md5sum(const gchar* file, const gchar* md5_file) {
304         int fd;
305         gchar* text = NULL;
306         gchar* md5sum = malloc(33);
307
308         debug_print("Creating md5sum file: %s\n", md5_file);
309         if (md5_hex_digest_file(md5sum, (const unsigned char *) file) == -1) {
310                 free(md5sum);
311                 return;
312         }
313         debug_print("md5sum: %s\n", md5sum);
314         if ((fd = 
315                 open(md5_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) == -1) {
316                 free(md5sum);
317                 return;
318         }
319         text = g_strrstr_len(file, strlen(file), "/");
320         if (text) {
321                 text++;
322                 text = g_strdup_printf("%s  %s\n", md5sum, text);
323         }
324         else
325                 text = g_strdup_printf("%s  %s\n", md5sum, file);
326         g_free(md5sum);
327         debug_print("md5sum: %s\n", text);
328         if (write(fd, text, strlen(text)) < 0)
329                 perror("write");
330         close(fd);
331         g_free(text);
332 }
333
334 static gchar* descriptive_file_name(
335                 struct ArchivePage* page, const gchar* file, MsgInfo *msginfo) {
336         gchar* new_file = NULL;
337         gchar *name, *p, *to, *from, *date, *subject;
338
339         debug_print("renaming file\n");
340         p = g_strrstr_len(file, strlen(file), "/");
341         p = g_strndup(file, p - file);
342         if (!p)
343                 return NULL;
344         if (msginfo->to) {
345                 to = g_strdup(msginfo->to);
346                 extract_address(to);
347         }
348         else
349                 to = g_strdup("");
350         if (msginfo->from) {
351                 from = g_strdup(msginfo->from);
352                 extract_address(from);
353         }
354         else
355                 from = g_strdup("");
356         if (msginfo->date) {
357                 date = g_strdup(msginfo->date);
358                 subst_for_shellsafe_filename(date);
359                 /* if not on windows we need to subst some more */
360                 subst_chars(date, ":", '_');
361         }
362         else
363                 date = g_strdup("");
364         if (msginfo->subject) {
365                 subject = g_strdup(msginfo->subject);
366                 subst_for_shellsafe_filename(subject);
367                 /* if not on windows we need to subst some more */
368                 subst_chars(subject, ":", '_');
369         }
370         else
371                 subject = g_strdup("");
372         name = g_strdup_printf("%s_%s@%s@%s", date, from, to, subject);
373         /* ensure file name is not larger than 96 chars (max file name size
374          * is 100 chars but reserve for .md5)
375          */
376         if (strlen(name) > 96)
377                 name[96] = 0;
378         
379         new_file = g_strconcat(p, "/", name, NULL);
380
381         g_free(name);
382         g_free(p);
383         g_free(to);
384         g_free(from);
385         g_free(date);
386         g_free(subject);
387
388         debug_print("New_file: %s\n", new_file);
389         if (link(file, new_file) != 0) {
390                 if (errno != EEXIST) {
391                         perror("link");
392                         g_free(new_file);
393                         new_file = g_strdup(file);
394                         page->rename = FALSE;
395                 }
396         }
397
398         return new_file;
399 }
400
401 static void walk_folder(struct ArchivePage* page, FolderItem* item,
402                                 gboolean recursive) {
403         FolderItem* child;
404         GSList *msglist;
405         GSList *cur;
406         MsgInfo *msginfo;
407         GNode* node;
408         int count;
409         gchar* md5_file = NULL;
410         gchar* text = NULL;
411         gchar* file = NULL;
412         MsgTrash* msg_trash = NULL;
413         const gchar* date = NULL;
414
415         if (recursive && ! page->cancelled) {
416                 debug_print("Scanning recursive\n");
417                 node = item->node->children;
418                 while(node && ! page->cancelled) {
419                         debug_print("Number of nodes: %d\n", g_node_n_children(node));
420                         if (node->data) {
421                                 child = FOLDER_ITEM(node->data);
422                                 debug_print("new node: %d messages\n", child->total_msgs);
423                                 walk_folder(page, child, recursive);
424                         }
425                         node = node->next;
426                 }
427         }
428         if (! page->cancelled) {
429                 date = gtk_entry_get_text(GTK_ENTRY(page->isoDate));
430                 debug_print("cut-off date: %s\n", date);
431                 count = 0;
432                 page->files += item->total_msgs;
433                 msglist = folder_item_get_msg_list(item);
434                 msg_trash = new_msg_trash(item);
435                 for (cur = msglist; cur && ! page->cancelled; cur = cur->next) {
436                         msginfo = (MsgInfo *) cur->data;
437                         debug_print("%s_%s_%s_%s\n",
438                                 msginfo->date, msginfo->to, msginfo->from, msginfo->subject);
439                         file = folder_item_fetch_msg(item, msginfo->msgnum);
440                         if (date && strlen(date) > 0 && !before_date(msginfo->date_t, date)) {
441                             page->files--;
442                             continue;
443                         }
444                         page->total_size += msginfo->size;
445                         /*debug_print("Processing: %s\n", file);*/
446                         if (file) {
447                                 if (page->unlink) {
448                                     archive_add_msg_mark(msg_trash, msginfo);
449                                 }
450                                 if (page->rename) {
451                                         file = descriptive_file_name(page, file, msginfo);
452                                         if (!file) {
453                                                 /* Could not create a descriptive name */
454                                             file = folder_item_fetch_msg(item, msginfo->msgnum);
455                                         }
456                                 }
457                                 if (page->md5) {
458                                         md5_file = g_strdup_printf("%s.md5", file);
459                                         create_md5sum(file, md5_file);
460                                         archive_add_file(md5_file);
461                                         g_free(md5_file);
462                                 }
463                                 archive_add_file(file);
464                                 if (page->rename)
465                                         g_free(file);
466                         }
467                         if (count % 350 == 0) {
468                                 debug_print("pulse progressbar\n");
469                                 text = g_strdup_printf(
470                                                         "Scanning %s: %d files", item->name, count);
471                                 gtk_progress_bar_set_text(
472                                                 GTK_PROGRESS_BAR(progress->progress), text);
473                                 g_free(text);
474                                 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progress->progress));
475                                 GTK_EVENTS_FLUSH();
476                         }
477                         count++;
478                 }
479                 procmsg_msg_list_free(msglist);
480         }
481 }
482
483 static AFileTest file_is_writeable(struct ArchivePage* page) {
484     int fd;
485
486     if (g_file_test(page->name, G_FILE_TEST_EXISTS) &&
487                                 ! page->force_overwrite)
488         return A_FILE_EXISTS;
489     if (g_file_test(page->name, G_FILE_TEST_IS_SYMLINK))
490         return A_FILE_IS_LINK;
491     if (g_file_test(page->name, G_FILE_TEST_IS_DIR))
492         return A_FILE_IS_DIR;
493     if ((fd = open(page->name, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) == -1) {
494         switch (errno) {
495             case EACCES: return A_FILE_NO_WRITE;
496             case EEXIST: return A_FILE_OK;
497             default:     return A_FILE_UNKNOWN;
498         }
499     }
500     else {
501         close(fd);
502         claws_unlink(page->name);
503     }
504     return A_FILE_OK;
505 }
506
507 static gboolean archiver_save_files(struct ArchivePage* page) {
508         FolderItem* item;
509         COMPRESS_METHOD method;
510         ARCHIVE_FORMAT format;
511         gboolean recursive;
512         guint orig_file;
513         GSList* list = NULL;
514         const gchar* res = NULL;
515         AFileTest perm;
516         gchar* msg = NULL;
517         gboolean folder_not_set;
518         gboolean file_not_set;
519
520         /* check if folder to archive and target archive filename are set */
521         folder_not_set = (*gtk_entry_get_text(GTK_ENTRY(page->folder)) == '\0');
522         file_not_set = (*gtk_entry_get_text(GTK_ENTRY(page->file)) == '\0');
523         if (folder_not_set || file_not_set) {
524                 alertpanel_error(_("Some uninitialized data prevents from starting\n"
525                                         "the archiving process:\n"
526                                         "%s%s"),
527                         folder_not_set ? _("\n- the folder to archive is not set") : "",
528                         file_not_set ? _("\n- the name for archive is not set") : "");
529                 return FALSE;
530         }
531         /* sync page struct info with folder and archive name edit widgets */
532         if (page->path) {
533                 g_free(page->path);
534                 page->path = NULL;
535         }
536         page->path = g_strdup(gtk_entry_get_text(GTK_ENTRY(page->folder)));
537         g_strstrip(page->path);
538         debug_print("page->path: %s\n", page->path);
539
540         if (page->name) {
541                 g_free(page->name);
542                 page->name = NULL;
543         }
544         page->name = g_strdup(gtk_entry_get_text(GTK_ENTRY(page->file)));
545         g_strstrip(page->name);
546         debug_print("page->name: %s\n", page->name);
547
548         if ((perm = file_is_writeable(page)) != A_FILE_OK) {
549                 switch (perm) {
550                         case A_FILE_EXISTS:
551                                 msg = g_strdup_printf(_("%s: Exists. Continue anyway?"), page->name);
552                                 break;
553                         case A_FILE_IS_LINK:
554                                 msg = g_strdup_printf(_("%s: Is a link. Cannot continue"), page->name);
555                                 break;
556                          case A_FILE_IS_DIR:
557                                  msg = g_strdup_printf(_("%s: Is a directory. Cannot continue"), page->name);
558                                 break;
559                         case A_FILE_NO_WRITE:
560                                  msg = g_strdup_printf(_("%s: Missing permissions. Cannot continue"), page->name);
561                                 break;
562                         case A_FILE_UNKNOWN:
563                                 msg = g_strdup_printf(_("%s: Unknown error. Cannot continue"), page->name);
564                                 break;
565                         default:
566                                 break;
567                 }
568                 if (perm == A_FILE_EXISTS) {
569                         AlertValue aval;
570
571                         aval = alertpanel_full(_("Creating archive"), msg,
572                                 GTK_STOCK_CANCEL, GTK_STOCK_OK, NULL, FALSE,
573                                 NULL, ALERT_WARNING, G_ALERTDEFAULT);
574                         g_free(msg);
575                         if (aval != G_ALERTALTERNATE)
576                                 return FALSE;
577                 } else {
578                         alertpanel_error(msg);
579                         g_free(msg);
580                         return FALSE;
581                 }
582         }
583         if (! valid_file_name(page->name)) {
584                 alertpanel_error(_("Not a valid file name:\n%s."), page->name);
585                 return FALSE;
586         }
587         item = folder_find_item_from_identifier(page->path);
588         if (! item) {
589                 alertpanel_error(_("Not a valid Claws Mail folder:\n%s."), page->name);
590                 return FALSE;
591         }
592         page->files = 0;
593         page->total_size = 0;
594         page->rename = gtk_toggle_button_get_active(
595                         GTK_TOGGLE_BUTTON(page->rename_files));
596         recursive = gtk_toggle_button_get_active(
597                                         GTK_TOGGLE_BUTTON(page->recursive));
598         page->md5 = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->md5sum));
599         page->unlink = gtk_toggle_button_get_active(
600                         GTK_TOGGLE_BUTTON(page->unlink_files));
601         create_progress_dialog(page);
602         walk_folder(page, item, recursive);
603         if (page->cancelled)
604                 return FALSE;
605         list = archive_get_file_list();
606         orig_file = (page->md5) ? page->files * 2 : page->files;
607         debug_print("md5: %d, orig: %d, md5: %d\n", 
608                                         page->md5, page->files, orig_file);
609         if (orig_file != g_slist_length(list)) {
610                 AlertValue aval;
611
612                 msg = g_strdup_printf(
613                                 _("Adding files in folder failed\n"
614                                   "Files in folder: %d\n"
615                                   "Files in list:   %d\n"
616                                   "\nContinue anyway?"),
617                                 orig_file, g_slist_length(list));
618                 aval = alertpanel_full(_("Creating archive"), msg,
619                         GTK_STOCK_CANCEL, GTK_STOCK_OK, NULL, FALSE,
620                         NULL, ALERT_WARNING, G_ALERTDEFAULT);
621                 g_free(msg);
622                 if (aval != G_ALERTALTERNATE) {
623                         archive_free_file_list(page->md5, page->rename);
624                         return FALSE;
625                 }
626         }
627         method = get_compress_method(page->compress_methods);
628         format = get_archive_format(page->archive_formats);
629         if ((res = archive_create(page->name, list, method, format)) != NULL) {
630                 alertpanel_error(_("Archive creation error:\n%s"), res);
631                 archive_free_file_list(page->md5, page->rename);
632                 return FALSE;
633         }
634         if (page->unlink) {
635                 archive_free_archived_files();
636         }
637         return TRUE;
638 }
639
640 static void entry_change_cb(GtkWidget* widget, gpointer data) {
641         const gchar* name = gtk_widget_get_name(widget);
642         struct ArchivePage* page = (struct ArchivePage *) data;
643
644         if (strcmp("folder", name) == 0) {
645                 page->path = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
646                 debug_print("page->folder = %s\n", page->path);
647         }
648         else if (strcmp("file", name) == 0) {
649                 page->name = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
650                 page->force_overwrite = FALSE;
651                 debug_print("page->name = %s\n", page->name);
652         }
653 }
654
655 static void show_result(struct ArchivePage* page) {
656         
657         enum {
658                 STRING1,
659                 STRING2,
660                 N_COLUMNS
661         };
662
663         GStatBuf st;
664         GtkListStore* list;
665         GtkTreeIter iter;
666         GtkTreeView* view;
667         GtkTreeViewColumn* header;
668         GtkCellRenderer* renderer;
669         GtkWidget* dialog;
670         gchar* msg = NULL;
671         gchar* method = NULL;
672         gchar* format = NULL;
673
674         MainWindow* mainwin = mainwindow_get_mainwindow();
675
676         switch (get_compress_method(page->compress_methods)) {
677                 case GZIP:
678                         method = g_strdup("GZIP");
679                         break;
680                 case BZIP2:
681                         method = g_strdup("BZIP2");
682                         break;
683         case COMPRESS:
684                         method = g_strdup("Compress");
685                         break;
686 #if ARCHIVE_VERSION_NUMBER >= 2006990
687                 case LZMA:
688                         method = g_strdup("LZMA");
689                         break;
690                 case XZ:
691                         method = g_strdup("XZ");
692                         break;
693 #endif
694 #if ARCHIVE_VERSION_NUMBER >= 3000000
695                 case LZIP:
696                         method = g_strdup("LZIP");
697                         break;
698 #endif
699 #if ARCHIVE_VERSION_NUMBER >= 3001000
700                 case LRZIP:
701                         method = g_strdup("LRZIP");
702                         break;
703                 case LZOP:
704                         method = g_strdup("LZOP");
705                         break;
706                 case GRZIP:
707                         method = g_strdup("GRZIP");
708                         break;
709 #endif
710 #if ARCHIVE_VERSION_NUMBER >= 3001900
711                 case LZ4:
712                         method = g_strdup("LZ4");
713                         break;
714 #endif
715                 case NO_COMPRESS:
716                         method = g_strdup("No Compression");
717                         break;
718         }
719         
720         switch (get_archive_format(page->archive_formats)) {
721                 case TAR:
722                         format = g_strdup("TAR");
723                         break;
724                 case SHAR:
725                         format = g_strdup("SHAR");
726                         break;
727                 case PAX:
728                         format = g_strdup("PAX");
729                         break;
730                 case CPIO:
731                         format = g_strdup("CPIO");
732                         break;
733                 case NO_FORMAT:
734                         format = g_strdup("NO FORMAT");
735         }
736
737         g_stat(page->name, &st);
738         dialog = gtk_dialog_new_with_buttons(
739                         _("Archive result"),
740                         GTK_WINDOW(mainwin->window),
741                         GTK_DIALOG_DESTROY_WITH_PARENT,
742                         GTK_STOCK_OK,
743                         GTK_RESPONSE_NONE,
744                         NULL);
745         g_signal_connect_swapped(
746                                 dialog,
747                                 "response",
748                                 G_CALLBACK(gtk_widget_destroy),
749                                 dialog);
750
751         list = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
752         
753         view = g_object_new(
754                                 GTK_TYPE_TREE_VIEW,
755                                 "model", list,
756                                 "rules-hint", FALSE,
757                                 "headers-clickable", FALSE,
758                                 "reorderable", FALSE,
759                                 "enable-search", FALSE,
760                                 NULL);
761
762         renderer = gtk_cell_renderer_text_new();
763
764         header = gtk_tree_view_column_new_with_attributes(
765                                 _("Attributes"), renderer, "text", STRING1, NULL);
766         gtk_tree_view_append_column(view, header);
767
768         header = gtk_tree_view_column_new_with_attributes(
769                                 _("Values"), renderer, "text", STRING2, NULL);
770         gtk_tree_view_append_column(view, header);
771
772         gtk_container_add(
773                                 GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), GTK_WIDGET(view));
774
775         gtk_list_store_append(list, &iter);
776         gtk_list_store_set(
777                                 list, &iter,
778                                 STRING1, _("Archive"),
779                                 STRING2, page->name, -1);
780
781         gtk_list_store_append(list, &iter);
782         gtk_list_store_set(
783                                 list, &iter,
784                                 STRING1, _("Archive format"),
785                                 STRING2, format, -1);
786         g_free(format);
787
788         gtk_list_store_append(list, &iter);
789         gtk_list_store_set(
790                                 list, &iter,
791                                 STRING1, _("Compression method"),
792                                 STRING2, method, -1);
793         g_free(method);
794
795         gtk_list_store_append(list, &iter);
796         msg = g_strdup_printf("%d", (page->md5) ? page->files * 2 : page->files);
797         gtk_list_store_set(
798                                 list, &iter,
799                                 STRING1, _("Number of files"),
800                                 STRING2, msg, -1);
801         g_free(msg);
802
803         gtk_list_store_append(list, &iter);
804         msg = g_strdup_printf("%d byte(s)", (guint) st.st_size);
805         gtk_list_store_set(
806                                 list, &iter,
807                                 STRING1, _("Archive Size"),
808                                 STRING2, msg, -1);
809         g_free(msg);
810
811         gtk_list_store_append(list, &iter);
812         msg = g_strdup_printf("%d byte(s)", page->total_size);
813         gtk_list_store_set(
814                                 list, &iter,
815                                 STRING1, _("Folder Size"),
816                                 STRING2, msg, -1);
817         g_free(msg);
818
819         gtk_list_store_append(list, &iter);
820         msg = g_strdup_printf("%d%%", 
821                                         (guint)((st.st_size * 100) / page->total_size));
822         gtk_list_store_set(
823                                 list, &iter,
824                                 STRING1, _("Compression level"),
825                                 STRING2, msg, -1);
826         g_free(msg);
827
828         gtk_list_store_append(list, &iter);
829         msg = g_strdup_printf("%s", (page->md5) ? _("Yes") : _("No"));
830         gtk_list_store_set(
831                                 list, &iter,
832                                 STRING1, _("MD5 checksum"),
833                                 STRING2, msg, -1);
834         g_free(msg);
835
836         gtk_list_store_append(list, &iter);
837         msg = g_strdup_printf("%s", (page->rename) ? _("Yes") : _("No"));
838         gtk_list_store_set(
839                                 list, &iter,
840                                 STRING1, _("Descriptive names"),
841                                 STRING2, msg, -1);
842         g_free(msg);
843
844         gtk_list_store_append(list, &iter);
845         msg = g_strdup_printf("%s", (page->unlink) ? _("Yes") : _("No"));
846         gtk_list_store_set(
847                                 list, &iter,
848                                 STRING1, _("Delete selected files"),
849                                 STRING2, msg, -1);
850         g_free(msg);
851         
852         msg = g_strdup(gtk_entry_get_text(GTK_ENTRY(page->isoDate)));
853         if (msg) {
854             gtk_list_store_append(list, &iter);
855             gtk_list_store_set(
856                                 list, &iter,
857                                 STRING1, _("Select mails before"),
858                                 STRING2, msg, -1);
859         }
860         g_free(msg);
861
862         gtk_window_set_default_size(GTK_WINDOW(dialog), 320, 260);
863
864         gtk_widget_show_all(dialog);
865 }
866
867 static void archiver_dialog_cb(GtkWidget* widget, gint action, gpointer data) {
868         struct ArchivePage* page = (struct ArchivePage *) data;
869         gboolean result = FALSE;
870
871         switch (action) {
872                 case GTK_RESPONSE_ACCEPT:
873                         debug_print("User chose OK\n");
874                         page->response = TRUE;
875                         break;
876                 default:
877                         debug_print("User chose CANCEL\n");
878                         page->response = FALSE;
879                         archiver_gtk_done(page, widget);
880                         return;
881         }
882         debug_print("Settings:\naction: %d\n", page->response);
883         if (page->response) {
884                 debug_print("Settings:\nfolder: %s\nname: %s\n",
885                                 (page->path) ? page->path : "(null)",
886                                 (page->name) ? page->name : "(null)");
887                 result = archiver_save_files(page);
888                 debug_print("Result->archiver_save_files: %d\n", result);
889                 if (progress->progress_dialog && 
890                                                 GTK_IS_WIDGET(progress->progress_dialog))
891                         gtk_widget_destroy(progress->progress_dialog);          
892                 if (result && ! page->cancelled) {
893                         show_result(page);
894                         archive_free_file_list(page->md5, page->rename);
895                         archiver_gtk_done(page, widget);
896                         return;
897                 }
898                 if (page->cancelled) {
899                         archiver_gtk_done(page, widget);
900                         archiver_gtk_show();
901                 }
902         }
903 }
904
905 static void foldersel_cb(GtkWidget *widget, gpointer data)
906 {
907         FolderItem *item;
908         gchar *item_id;
909         gint newpos = 0;
910         struct ArchivePage* page = (struct ArchivePage *) data;
911
912         item = foldersel_folder_sel(NULL, FOLDER_SEL_MOVE, NULL, FALSE);
913         if (item && (item_id = folder_item_get_identifier(item)) != NULL) {
914                 gtk_editable_delete_text(GTK_EDITABLE(page->folder), 0, -1);
915                 gtk_editable_insert_text(GTK_EDITABLE(page->folder),
916                                         item_id, strlen(item_id), &newpos);
917                 page->path = g_strdup(item_id);
918                 g_free(item_id);
919         }
920         debug_print("Folder to archive: %s\n", 
921                                 gtk_entry_get_text(GTK_ENTRY(page->folder)));
922 }
923
924 static void filesel_cb(GtkWidget *widget, gpointer data)
925 {
926         GtkWidget *dialog;
927         gchar* file;
928         gint newpos = 0;
929         const gchar* homedir;
930         struct ArchivePage* page = (struct ArchivePage *) data;
931
932         dialog = gtk_file_chooser_dialog_new(
933                 _("Select file name for archive [suffix should reflect archive like .tgz]"),
934                         NULL,
935                         GTK_FILE_CHOOSER_ACTION_SAVE,
936                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
937                         GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
938                         NULL);
939         homedir = g_getenv("HOME");
940         if (!homedir)
941                 homedir = g_get_home_dir();
942
943         if (archiver_prefs.save_folder)
944                 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), 
945                                                     archiver_prefs.save_folder);
946         else
947                 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), homedir);
948         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_APPLY) {
949                 file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
950                 if (file) {
951                         gtk_editable_delete_text(GTK_EDITABLE(page->file), 0, -1);
952                         gtk_editable_insert_text(GTK_EDITABLE(page->file),
953                                                 file, strlen(file), &newpos);
954                         page->name = g_strdup(file);
955                         g_free(file);
956                         page->force_overwrite = TRUE;
957                 }
958         }
959         gtk_widget_destroy(dialog);
960         debug_print("Name for archive: %s\n",
961                                 gtk_entry_get_text(GTK_ENTRY(page->file)));
962 }
963
964 void set_progress_file_label(const gchar* file) {
965         debug_print("IsLabel: %s, Update label: %s\n", 
966                                 GTK_IS_WIDGET(progress->file_label)? "Yes" : "No", file);
967         if (GTK_IS_WIDGET(progress->file_label))
968                 gtk_label_set_text(GTK_LABEL(progress->file_label), file);
969 }
970
971 void set_progress_print_all(guint fraction, guint total, guint step) {
972         gchar* text_count;
973
974         if (GTK_IS_WIDGET(progress->progress)) {
975                 if ((fraction - progress->position) % step == 0) {
976                         debug_print("frac: %d, total: %d, step: %d, prog->pos: %d\n",
977                                         fraction, total, step, progress->position);
978                         gtk_progress_bar_set_fraction(
979                                         GTK_PROGRESS_BAR(progress->progress), 
980                                         (total == 0) ? 0 : (gfloat)fraction / (gfloat)total);
981                         text_count = g_strdup_printf(_("%ld of %ld"), 
982                                         (long) fraction, (long) total);
983                         gtk_progress_bar_set_text(
984                                         GTK_PROGRESS_BAR(progress->progress), text_count);
985                         g_free(text_count);
986                         progress->position = fraction;
987                         GTK_EVENTS_FLUSH();
988                 }
989         }
990 }
991
992 void archiver_gtk_show() {
993         GtkWidget* dialog;
994         GtkWidget* frame;
995         GtkWidget* vbox1;
996         GtkWidget* hbox1;
997         GtkWidget* folder_label;
998         GtkWidget* folder_select;
999         GtkWidget* file_label;
1000         GtkWidget* file_select;
1001         GtkWidget* gzip_radio_btn;
1002         GtkWidget* bzip_radio_btn;
1003     GtkWidget* compress_radio_btn;
1004 #if ARCHIVE_VERSION_NUMBER >= 2006990
1005         GtkWidget* lzma_radio_btn;
1006         GtkWidget* xz_radio_btn;
1007 #endif
1008 #if ARCHIVE_VERSION_NUMBER >= 3000000
1009         GtkWidget* lzip_radio_btn;
1010 #endif
1011 #if ARCHIVE_VERSION_NUMBER >= 3001000
1012         GtkWidget* lrzip_radio_btn;
1013         GtkWidget* lzop_radio_btn;
1014         GtkWidget* grzip_radio_btn;
1015 #endif
1016 #if ARCHIVE_VERSION_NUMBER >= 3001900
1017         GtkWidget* lz4_radio_btn;
1018 #endif
1019         GtkWidget* no_radio_btn;
1020         GtkWidget* shar_radio_btn;
1021         GtkWidget* pax_radio_btn;
1022         GtkWidget* cpio_radio_btn;
1023         GtkWidget* tar_radio_btn;
1024         struct ArchivePage* page;
1025         MainWindow* mainwin = mainwindow_get_mainwindow();
1026
1027         /*debug_set_mode(TRUE);*/
1028         progress = init_progress();
1029
1030         page = init_archive_page();
1031
1032         dialog = gtk_dialog_new_with_buttons (
1033                                 _("Create Archive"),
1034                                 GTK_WINDOW(mainwin->window),
1035                                 GTK_DIALOG_DESTROY_WITH_PARENT,
1036                                 GTK_STOCK_CANCEL,
1037                                 GTK_RESPONSE_CANCEL,
1038                                 GTK_STOCK_OK,
1039                                 GTK_RESPONSE_ACCEPT,
1040                                 NULL);
1041
1042         g_signal_connect (
1043                                 dialog,
1044                                 "response",
1045                                 G_CALLBACK(archiver_dialog_cb),
1046                                 page);
1047
1048         frame = gtk_frame_new(_("Enter Archiver arguments"));
1049         gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_OUT);
1050         gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
1051         gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), frame);
1052
1053         vbox1 = gtk_vbox_new (FALSE, 4);
1054         gtk_container_set_border_width (GTK_CONTAINER (vbox1), 4);
1055         gtk_container_add(GTK_CONTAINER(frame), vbox1);
1056         
1057         hbox1 = gtk_hbox_new(FALSE, 4);
1058         gtk_container_set_border_width(GTK_CONTAINER(hbox1), 4);
1059         gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 0);
1060
1061         folder_label = gtk_label_new(_("Folder to archive"));
1062         gtk_box_pack_start(GTK_BOX(hbox1), folder_label, FALSE, FALSE, 0);
1063         
1064         page->folder = gtk_entry_new();
1065         gtk_widget_set_name(page->folder, "folder");
1066         gtk_box_pack_start(GTK_BOX(hbox1), page->folder, TRUE, TRUE, 0);
1067         CLAWS_SET_TIP(page->folder,
1068                         _("Folder which is the root of the archive"));
1069
1070         folder_select = gtkut_get_browse_directory_btn(_("_Browse"));
1071         gtk_box_pack_start(GTK_BOX(hbox1), folder_select, FALSE, FALSE, 0);
1072         CLAWS_SET_TIP(folder_select,
1073                         _("Click this button to select a folder which is to be root of the archive"));
1074
1075         hbox1 = gtk_hbox_new(FALSE, 4);
1076         gtk_container_set_border_width(GTK_CONTAINER(hbox1), 4);
1077         gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 0);
1078
1079         file_label = gtk_label_new(_("Name for archive"));
1080         gtk_box_pack_start(GTK_BOX(hbox1), file_label, FALSE, FALSE, 0);
1081         
1082         page->file = gtk_entry_new();
1083         gtk_widget_set_name(page->file, "file");
1084         gtk_box_pack_start(GTK_BOX(hbox1), page->file, TRUE, TRUE, 0);
1085         CLAWS_SET_TIP(page->file, _("Archive location and name"));
1086
1087         file_select = gtkut_get_browse_directory_btn(_("_Select"));
1088         gtk_box_pack_start(GTK_BOX(hbox1), file_select, FALSE, FALSE, 0);
1089         CLAWS_SET_TIP(file_select,
1090                         _("Click this button to select a name and location for the archive"));
1091
1092         frame = gtk_frame_new(_("Choose compression"));
1093         gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_OUT);
1094         gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
1095         gtk_box_pack_start(GTK_BOX(vbox1), frame, FALSE, FALSE, 0);
1096
1097         hbox1 = gtk_hbox_new(FALSE, 4);
1098         gtk_container_set_border_width(GTK_CONTAINER(hbox1), 4);
1099         gtk_container_add(GTK_CONTAINER(frame), hbox1);
1100
1101         gzip_radio_btn = gtk_radio_button_new_with_mnemonic(NULL, "G_ZIP");
1102         gtk_widget_set_name(gzip_radio_btn, "GZIP");
1103         gtk_box_pack_start(GTK_BOX(hbox1), gzip_radio_btn, FALSE, FALSE, 0);
1104         CLAWS_SET_TIP(gzip_radio_btn,
1105                         _("Choose this option to use GZIP compression for the archive"));
1106
1107         bzip_radio_btn = gtk_radio_button_new_with_mnemonic_from_widget(
1108                                         GTK_RADIO_BUTTON(gzip_radio_btn), "BZIP_2");
1109         gtk_widget_set_name(bzip_radio_btn, "BZIP");
1110         gtk_box_pack_start(GTK_BOX(hbox1), bzip_radio_btn, FALSE, FALSE, 0);
1111         CLAWS_SET_TIP(bzip_radio_btn,
1112                         _("Choose this option to use BZIP2 compression for the archive"));
1113
1114         compress_radio_btn = gtk_radio_button_new_with_mnemonic_from_widget(
1115                                         GTK_RADIO_BUTTON(gzip_radio_btn), "Com_press");
1116         gtk_widget_set_name(compress_radio_btn, "COMPRESS");
1117         gtk_box_pack_start(GTK_BOX(hbox1), compress_radio_btn, FALSE, FALSE, 0);
1118         CLAWS_SET_TIP(compress_radio_btn,
1119                 _("Choose this to use Compress compression for your archive"));
1120
1121 #if ARCHIVE_VERSION_NUMBER >= 2006990
1122         lzma_radio_btn = gtk_radio_button_new_with_mnemonic_from_widget(
1123                                         GTK_RADIO_BUTTON(gzip_radio_btn), "_LZMA");
1124         gtk_widget_set_name(lzma_radio_btn, "LZMA");
1125         gtk_box_pack_start(GTK_BOX(hbox1), lzma_radio_btn, FALSE, FALSE, 0);
1126         CLAWS_SET_TIP(lzma_radio_btn,
1127                         _("Choose this option to use LZMA compression for the archive"));
1128
1129         xz_radio_btn = gtk_radio_button_new_with_mnemonic_from_widget(
1130                                         GTK_RADIO_BUTTON(gzip_radio_btn), "_XZ");
1131         gtk_widget_set_name(xz_radio_btn, "XZ");
1132         gtk_box_pack_start(GTK_BOX(hbox1), xz_radio_btn, FALSE, FALSE, 0);
1133         CLAWS_SET_TIP(xz_radio_btn,
1134                         _("Choose this option to use XZ compression for the archive"));
1135 #endif
1136
1137 #if ARCHIVE_VERSION_NUMBER >= 3000000
1138         lzip_radio_btn = gtk_radio_button_new_with_mnemonic_from_widget(
1139                                         GTK_RADIO_BUTTON(gzip_radio_btn), "_LZIP");
1140         gtk_widget_set_name(lzip_radio_btn, "LZIP");
1141         gtk_box_pack_start(GTK_BOX(hbox1), lzip_radio_btn, FALSE, FALSE, 0);
1142         CLAWS_SET_TIP(lzip_radio_btn,
1143                         _("Choose this option to use LZIP compression for the archive"));
1144 #endif
1145
1146 #if ARCHIVE_VERSION_NUMBER >= 3001000
1147         lrzip_radio_btn = gtk_radio_button_new_with_mnemonic_from_widget(
1148                                         GTK_RADIO_BUTTON(gzip_radio_btn), "L_RZIP");
1149         gtk_widget_set_name(lrzip_radio_btn, "LRZIP");
1150         gtk_box_pack_start(GTK_BOX(hbox1), lrzip_radio_btn, FALSE, FALSE, 0);
1151         CLAWS_SET_TIP(lrzip_radio_btn,
1152                         _("Choose this option to use LRZIP compression for the archive"));
1153
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         CLAWS_SET_TIP(lzop_radio_btn,
1159                         _("Choose this option to use LZOP compression for the archive"));
1160
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         CLAWS_SET_TIP(grzip_radio_btn,
1166                         _("Choose this option to use GRZIP compression for the archive"));
1167 #endif
1168
1169 #if ARCHIVE_VERSION_NUMBER >= 3001900
1170         lz4_radio_btn = gtk_radio_button_new_with_mnemonic_from_widget(
1171                                         GTK_RADIO_BUTTON(gzip_radio_btn), "LZ_4");
1172         gtk_widget_set_name(lz4_radio_btn, "LZ4");
1173         gtk_box_pack_start(GTK_BOX(hbox1), lz4_radio_btn, FALSE, FALSE, 0);
1174         CLAWS_SET_TIP(lz4_radio_btn,
1175                         _("Choose this option to use LZ4 compression for the archive"));
1176 #endif
1177
1178         no_radio_btn = gtk_radio_button_new_with_mnemonic_from_widget(
1179                                         GTK_RADIO_BUTTON(gzip_radio_btn), _("_None"));
1180         gtk_widget_set_name(no_radio_btn, "NONE");
1181         gtk_box_pack_start(GTK_BOX(hbox1), no_radio_btn, FALSE, FALSE, 0);
1182         CLAWS_SET_TIP(no_radio_btn,
1183                 _("Choose this option to disable compression for the archive"));
1184
1185         page->compress_methods = 
1186                         gtk_radio_button_get_group(GTK_RADIO_BUTTON(gzip_radio_btn));
1187
1188         switch (archiver_prefs.compression) {
1189         case COMPRESSION_GZIP:
1190                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gzip_radio_btn), TRUE);
1191                 break;
1192         case COMPRESSION_BZIP:
1193                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bzip_radio_btn), TRUE);
1194                 break;
1195         case COMPRESSION_COMPRESS:
1196                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compress_radio_btn), TRUE);
1197                 break;
1198 #if ARCHIVE_VERSION_NUMBER >= 2006990
1199         case COMPRESSION_LZMA:
1200                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lzma_radio_btn), TRUE);
1201                 break;
1202         case COMPRESSION_XZ:
1203                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(xz_radio_btn), TRUE);
1204                 break;
1205 #endif
1206 #if ARCHIVE_VERSION_NUMBER >= 3000000
1207         case COMPRESSION_LZIP:
1208                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lzip_radio_btn), TRUE);
1209                 break;
1210 #endif
1211 #if ARCHIVE_VERSION_NUMBER >= 3001000
1212         case COMPRESSION_LRZIP:
1213                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lrzip_radio_btn), TRUE);
1214                 break;
1215         case COMPRESSION_LZOP:
1216                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lzop_radio_btn), TRUE);
1217                 break;
1218         case COMPRESSION_GRZIP:
1219                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grzip_radio_btn), TRUE);
1220                 break;
1221 #endif
1222 #if ARCHIVE_VERSION_NUMBER >= 3001900
1223         case COMPRESSION_LZ4:
1224                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lz4_radio_btn), TRUE);
1225                 break;
1226 #endif
1227         case COMPRESSION_NONE:
1228                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(no_radio_btn), TRUE);
1229                 break;
1230         }
1231
1232         frame = gtk_frame_new(_("Choose format"));
1233         gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_OUT);
1234         gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
1235         gtk_box_pack_start(GTK_BOX(vbox1), frame, FALSE, FALSE, 0);
1236
1237         hbox1 = gtk_hbox_new(FALSE, 4);
1238         gtk_container_set_border_width(GTK_CONTAINER(hbox1), 4);
1239         gtk_container_add(GTK_CONTAINER(frame), hbox1);
1240
1241         tar_radio_btn = gtk_radio_button_new_with_mnemonic(NULL, "_TAR");
1242         gtk_widget_set_name(tar_radio_btn, "TAR");
1243         gtk_box_pack_start(GTK_BOX(hbox1), tar_radio_btn, FALSE, FALSE, 0);
1244         CLAWS_SET_TIP(tar_radio_btn,
1245                         _("Choose this option to use TAR as format for the archive"));
1246
1247         shar_radio_btn = gtk_radio_button_new_with_mnemonic_from_widget(
1248                                         GTK_RADIO_BUTTON(tar_radio_btn), "S_HAR");
1249         gtk_widget_set_name(shar_radio_btn, "SHAR");
1250         gtk_box_pack_start(GTK_BOX(hbox1), shar_radio_btn, FALSE, FALSE, 0);
1251         CLAWS_SET_TIP(shar_radio_btn,
1252                         _("Choose this to use SHAR as format for the archive"));
1253
1254         cpio_radio_btn = gtk_radio_button_new_with_mnemonic_from_widget(
1255                                         GTK_RADIO_BUTTON(tar_radio_btn), "CP_IO");
1256         gtk_widget_set_name(cpio_radio_btn, "CPIO");
1257         gtk_box_pack_start(GTK_BOX(hbox1), cpio_radio_btn, FALSE, FALSE, 0);
1258         CLAWS_SET_TIP(cpio_radio_btn,
1259                 _("Choose this option to use CPIO as format for the archive"));
1260
1261         pax_radio_btn = gtk_radio_button_new_with_mnemonic_from_widget(
1262                                         GTK_RADIO_BUTTON(tar_radio_btn), "PA_X");
1263         gtk_widget_set_name(pax_radio_btn, "PAX");
1264         gtk_box_pack_start(GTK_BOX(hbox1), pax_radio_btn, FALSE, FALSE, 0);
1265         CLAWS_SET_TIP(pax_radio_btn,
1266                 _("Choose this option to use PAX as format for the archive"));
1267
1268         page->archive_formats = 
1269                         gtk_radio_button_get_group(GTK_RADIO_BUTTON(tar_radio_btn));
1270
1271         switch (archiver_prefs.format) {
1272         case FORMAT_TAR:
1273                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tar_radio_btn), TRUE);
1274                 break;
1275         case FORMAT_SHAR:
1276                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(shar_radio_btn), TRUE);
1277                 break;
1278         case FORMAT_CPIO:
1279                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cpio_radio_btn), TRUE);
1280                 break;
1281         case FORMAT_PAX:
1282                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pax_radio_btn), TRUE);
1283                 break;
1284         }
1285
1286         frame = gtk_frame_new(_("Miscellaneous options"));
1287         gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_OUT);
1288         gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
1289         gtk_box_pack_start(GTK_BOX(vbox1), frame, FALSE, FALSE, 0);
1290
1291         hbox1 = gtk_hbox_new(FALSE, 4);
1292         gtk_container_set_border_width(GTK_CONTAINER(hbox1), 4);
1293         gtk_container_add(GTK_CONTAINER(frame), hbox1);
1294
1295         page->recursive = gtk_check_button_new_with_mnemonic(_("_Recursive"));
1296         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page->recursive), archiver_prefs.recursive);
1297         gtk_box_pack_start(GTK_BOX(hbox1), page->recursive, FALSE, FALSE, 0);
1298         CLAWS_SET_TIP(page->recursive,
1299                 _("Choose this option to include subfolders in the archive"));
1300         
1301         page->md5sum = gtk_check_button_new_with_mnemonic(_("_MD5sum"));
1302         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page->md5sum), archiver_prefs.md5sum);
1303         gtk_box_pack_start(GTK_BOX(hbox1), page->md5sum, FALSE, FALSE, 0);
1304         CLAWS_SET_TIP(page->md5sum,
1305                 _("Choose this option to add MD5 checksums for each file in the archive.\n"
1306                   "Be aware though, that this dramatically increases the time it\n"
1307                   "will take to create the archive"));
1308
1309         page->rename_files = gtk_check_button_new_with_mnemonic(_("R_ename"));
1310         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page->rename_files), archiver_prefs.rename);
1311         gtk_box_pack_start(GTK_BOX(hbox1), page->rename_files, FALSE, FALSE, 0);
1312         CLAWS_SET_TIP(page->rename_files,
1313                 _("Choose this option to use descriptive names for each file in the archive.\n"
1314                   "The naming scheme: date_from@to@subject.\n"
1315                   "Names will be truncated to max 96 characters"));
1316
1317         page->unlink_files = gtk_check_button_new_with_mnemonic(_("_Delete"));
1318         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page->unlink_files), archiver_prefs.unlink);
1319         gtk_box_pack_start(GTK_BOX(hbox1), page->unlink_files, FALSE, FALSE, 0);
1320         CLAWS_SET_TIP(page->unlink_files,
1321                 _("Choose this option to delete mails after archiving\n"
1322                   "At this point only handles IMAP4, Local mbox and POP3"));
1323
1324
1325         frame = gtk_frame_new(_("Selection options"));
1326         gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_OUT);
1327         gtk_container_set_border_width(GTK_CONTAINER(frame), 4);
1328         gtk_box_pack_start(GTK_BOX(vbox1), frame, FALSE, FALSE, 0);
1329
1330         hbox1 = gtk_hbox_new(FALSE, 4);
1331         gtk_container_set_border_width(GTK_CONTAINER(hbox1), 4);
1332         gtk_container_add(GTK_CONTAINER(frame), hbox1);
1333
1334         file_label = gtk_label_new(_("Select mails before"));
1335         gtk_box_pack_start(GTK_BOX(hbox1), file_label, FALSE, FALSE, 0);
1336         
1337         page->isoDate = gtk_entry_new();
1338         gtk_widget_set_name(page->isoDate, "isoDate");
1339         gtk_box_pack_start(GTK_BOX(hbox1), page->isoDate, TRUE, TRUE, 0);
1340         CLAWS_SET_TIP(page->isoDate, 
1341                 _("Select emails before a certain date\n"
1342                   "Date must comply to ISO-8601 [YYYY-MM-DD]"));
1343
1344         g_signal_connect(G_OBJECT(folder_select), "clicked", 
1345                          G_CALLBACK(foldersel_cb), page);
1346         g_signal_connect(G_OBJECT(file_select), "clicked",
1347                          G_CALLBACK(filesel_cb), page);
1348         g_signal_connect(G_OBJECT(page->folder), "activate",
1349                          G_CALLBACK(entry_change_cb), page);
1350         g_signal_connect(G_OBJECT(page->file), "activate",
1351                          G_CALLBACK(entry_change_cb), page);
1352
1353         gtk_widget_show_all(dialog);
1354 }
1355
1356 void archiver_gtk_done(struct ArchivePage* page, GtkWidget* widget) {
1357         dispose_archive_page(page);
1358         free(progress);
1359         gtk_widget_destroy(widget);
1360         /*debug_set_mode(FALSE);*/
1361 }
1362