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