mbox format completed
authorHoà Viêt Dinh <dinh.viet.hoa@free.fr>
Sun, 27 May 2001 22:40:29 +0000 (22:40 +0000)
committerHoà Viêt Dinh <dinh.viet.hoa@free.fr>
Sun, 27 May 2001 22:40:29 +0000 (22:40 +0000)
19 files changed:
ChangeLog.claws
src/compose.c
src/filtering.c
src/folder.c
src/folder.h
src/foldersel.c
src/folderview.c
src/folderview.h
src/mainwindow.c
src/mbox.c
src/mbox_folder.c
src/mbox_folder.h
src/mh.c
src/prefs_filtering.c
src/procheader.c
src/procmsg.c
src/procmsg.h
src/summaryview.c
src/textview.c

index 3734ba6..4031d78 100644 (file)
@@ -1,3 +1,56 @@
+2001-05-28 [hoa]
+
+       * src/compose.c
+               handling flags for mbox format
+
+       * src/filtering.c
+               use of mark file only for MH format
+               handling flags for mbox format
+               filtering cannot yet move or copy mails to mbox folders.
+
+       * src/folder.[ch]
+               changed move_msg, copy_msg,
+               move_msgs_with_dest, copy_msgs_with_dest functions
+               uses only folder->copy_msg() function
+               uses folder->finished_copy() to handle the destination
+               folder at the end of the copy or move operation.
+
+       * src/foldersel.c
+               included mbox directories.
+
+       * src/folderview.[ch]
+       * src/mainwindow.c
+               handle folders operation for mbox format
+
+       * src/mbox.c
+               disable conversion of "From " header
+
+       * src/mbox_folder.[ch]
+               completion of mbox format handling
+
+       * src/mh.c
+               changed mh_copy_msg() function and
+               removed mh_move_msg(), mh_move_msgs_with_dest(),
+               mh_copy_msgs_with_dest()
+
+       * src/prefs_filtering.c
+               removed some warnings
+
+       * src/procheader.c
+               handling flags for mbox format
+               handling of "From " header
+
+       * src/procmsg.[ch]
+               removed data field
+               added MSG_REALLY_DELETED flags to handle deletion of
+               messages in mbox format.
+
+       * src/summaryview.c
+               handling flags for mbox format
+
+       * src/textview.c
+               "From " headers display fixed.
+
 2001-05-27 [alfons]
 
        * src/textview.c:
index 0b5d400..6153a55 100644 (file)
@@ -464,6 +464,14 @@ Compose * compose_new_with_recipient(PrefsAccount *account, const gchar *to)
        return compose;
 }
 
+#define CHANGE_FLAGS(msginfo) \
+{ \
+if (msginfo->folder->folder->change_flags != NULL) \
+msginfo->folder->folder->change_flags(msginfo->folder->folder, \
+                                     msginfo->folder, \
+                                     msginfo); \
+}
+
 void compose_reply(MsgInfo *msginfo, gboolean quote, gboolean to_all,
                   gboolean to_author)
 {
@@ -492,6 +500,8 @@ void compose_reply(MsgInfo *msginfo, gboolean quote, gboolean to_all,
        MSG_UNSET_FLAGS(msginfo->flags, MSG_FORWARDED);
        MSG_SET_FLAGS(msginfo->flags, MSG_REPLIED);
 
+       CHANGE_FLAGS(msginfo);
+
        compose = compose_create(reply_account);
        compose->mode = COMPOSE_REPLY;
 
@@ -554,6 +564,8 @@ Compose * compose_forward(PrefsAccount * account, MsgInfo *msginfo,
        MSG_UNSET_FLAGS(msginfo->flags, MSG_REPLIED);
        MSG_SET_FLAGS(msginfo->flags, MSG_FORWARDED);
 
+       CHANGE_FLAGS(msginfo);
+
        compose = compose_create(account);
        compose->mode = COMPOSE_FORWARD;
 
index e5e45a8..48d0188 100644 (file)
@@ -175,24 +175,27 @@ static gboolean filteringaction_update_mark(MsgInfo * info)
        gchar * dest_path;
        FILE * fp;
 
-       dest_path = folder_item_get_path(info->folder);
-       if (!is_dir_exist(dest_path))
-               make_dir_hier(dest_path);
-
-       if (dest_path == NULL) {
-               g_warning(_("Can't open mark file.\n"));
-               return FALSE;
-       }
-
-       if ((fp = procmsg_open_mark_file(dest_path, TRUE))
-                == NULL) {
-               g_warning(_("Can't open mark file.\n"));
-               return FALSE;
+       if (info->folder->folder->type == F_MH) {
+               dest_path = folder_item_get_path(info->folder);
+               if (!is_dir_exist(dest_path))
+                       make_dir_hier(dest_path);
+               
+               if (dest_path == NULL) {
+                       g_warning(_("Can't open mark file.\n"));
+                       return FALSE;
+               }
+               
+               if ((fp = procmsg_open_mark_file(dest_path, TRUE))
+                   == NULL) {
+                       g_warning(_("Can't open mark file.\n"));
+                       return FALSE;
+               }
+               
+               procmsg_write_flags(info, fp);
+               fclose(fp);
+               return TRUE;
        }
-
-       procmsg_write_flags(info, fp);
-       fclose(fp);
-       return TRUE;
+       return FALSE;
 }
 
 /*
@@ -201,6 +204,14 @@ static gboolean filteringaction_update_mark(MsgInfo * info)
   return value : return TRUE if the action could be applied
 */
 
+#define CHANGE_FLAGS(msginfo) \
+{ \
+if (msginfo->folder->folder->change_flags != NULL) \
+msginfo->folder->folder->change_flags(msginfo->folder->folder, \
+                                     msginfo->folder, \
+                                     msginfo); \
+}
+
 static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info,
                                      GHashTable *folder_table)
 {
@@ -269,24 +280,32 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info,
                MSG_SET_FLAGS(info->flags, MSG_MARKED);
                filteringaction_update_mark(info);
 
+               CHANGE_FLAGS(info);
+
                return TRUE;
 
        case MATCHING_ACTION_UNMARK:
                MSG_UNSET_FLAGS(info->flags, MSG_MARKED);
                filteringaction_update_mark(info);
 
+               CHANGE_FLAGS(info);
+
                return TRUE;
                
        case MATCHING_ACTION_MARK_AS_READ:
                MSG_UNSET_FLAGS(info->flags, MSG_UNREAD | MSG_NEW);
                filteringaction_update_mark(info);
 
+               CHANGE_FLAGS(info);
+
                return TRUE;
 
        case MATCHING_ACTION_MARK_AS_UNREAD:
                MSG_SET_FLAGS(info->flags, MSG_UNREAD | MSG_NEW);
                filteringaction_update_mark(info);
 
+               CHANGE_FLAGS(info);
+               
                return TRUE;
 
        case MATCHING_ACTION_FORWARD:
index 3f36384..e1a0400 100644 (file)
@@ -548,6 +548,7 @@ gint folder_item_add_msg(FolderItem *dest, const gchar *file,
        return num;
 }
 
+/*
 gint folder_item_move_msg(FolderItem *dest, MsgInfo *msginfo)
 {
        Folder *folder;
@@ -568,7 +569,47 @@ gint folder_item_move_msg(FolderItem *dest, MsgInfo *msginfo)
 
        return num;
 }
+*/
+
+gint folder_item_move_msg(FolderItem *dest, MsgInfo *msginfo)
+{
+       Folder *folder;
+       gint num;
+       gchar * filename;
+       Folder * src_folder;
+
+       g_return_val_if_fail(dest != NULL, -1);
+       g_return_val_if_fail(msginfo != NULL, -1);
+
+       folder = dest->folder;
+
+       g_return_val_if_fail(folder->scan != NULL, -1);
+       g_return_val_if_fail(folder->remove_msg != NULL, -1);
+       g_return_val_if_fail(folder->copy_msg != NULL, -1);
 
+       if (dest->last_num < 0) folder->scan(folder, dest);
+
+       src_folder = msginfo->folder->folder;
+
+       num = folder->copy_msg(folder, dest, msginfo);
+       if (num != -1)
+               src_folder->remove_msg(src_folder,
+                                      msginfo->folder,
+                                      msginfo->msgnum);
+       
+       if (folder->finished_copy)
+               folder->finished_copy(folder, dest);
+
+       src_folder = msginfo->folder->folder;
+
+       if (msginfo->folder && src_folder->scan)
+               src_folder->scan(src_folder, msginfo->folder);
+       folder->scan(folder, dest);
+
+       return num;
+}
+
+/*
 gint folder_item_move_msgs_with_dest(FolderItem *dest, GSList *msglist)
 {
        Folder *folder;
@@ -589,7 +630,54 @@ gint folder_item_move_msgs_with_dest(FolderItem *dest, GSList *msglist)
 
        return num;
 }
+*/
+
+gint folder_item_move_msgs_with_dest(FolderItem *dest, GSList *msglist)
+{
+       Folder *folder;
+       FolderItem * item;
+       GSList * l;
+       gchar * filename;
+
+       g_return_val_if_fail(dest != NULL, -1);
+       g_return_val_if_fail(msglist != NULL, -1);
+
+       folder = dest->folder;
+
+       g_return_val_if_fail(folder->scan != NULL, -1);
+       g_return_val_if_fail(folder->copy_msg != NULL, -1);
+       g_return_val_if_fail(folder->remove_msg != NULL, -1);
+
+       if (dest->last_num < 0) folder->scan(folder, dest);
+
+       item = NULL;
+       for(l = msglist ; l != NULL ; l = g_slist_next(l)) {
+               MsgInfo * msginfo = (MsgInfo *) l->data;
+
+               if (!item && msginfo->folder != NULL)
+                       item = msginfo->folder;
+
+               if (folder->copy_msg(folder, dest, msginfo) != -1)
+                       item->folder->remove_msg(item->folder,
+                                                msginfo->folder,
+                                                msginfo->msgnum);
+       }
+
+       if (folder->finished_copy)
+               folder->finished_copy(folder, dest);
+
+       printf("là scan\n");
+
+       if (item && item->folder->scan)
+               item->folder->scan(item->folder, item);
+       folder->scan(folder, dest);
+
+       printf("ici scan\n");
+
+       return dest->last_num;
+}
 
+/*
 gint folder_item_copy_msg(FolderItem *dest, MsgInfo *msginfo)
 {
        Folder *folder;
@@ -610,7 +698,36 @@ gint folder_item_copy_msg(FolderItem *dest, MsgInfo *msginfo)
 
        return num;
 }
+*/
 
+gint folder_item_copy_msg(FolderItem *dest, MsgInfo *msginfo)
+{
+       Folder *folder;
+       gint num;
+       gchar * filename;
+       Folder * src_folder;
+
+       g_return_val_if_fail(dest != NULL, -1);
+       g_return_val_if_fail(msginfo != NULL, -1);
+
+       folder = dest->folder;
+
+       g_return_val_if_fail(folder->scan != NULL, -1);
+       g_return_val_if_fail(folder->copy_msg != NULL, -1);
+
+       if (dest->last_num < 0) folder->scan(folder, dest);
+       
+       num = folder->copy_msg(folder, dest, msginfo);
+
+       if (folder->finished_copy)
+               folder->finished_copy(folder, dest);
+
+       folder->scan(folder, dest);
+
+       return num;
+}
+
+/*
 gint folder_item_copy_msgs_with_dest(FolderItem *dest, GSList *msglist)
 {
        Folder *folder;
@@ -631,6 +748,38 @@ gint folder_item_copy_msgs_with_dest(FolderItem *dest, GSList *msglist)
 
        return num;
 }
+*/
+
+gint folder_item_copy_msgs_with_dest(FolderItem *dest, GSList *msglist)
+{
+       Folder *folder;
+       gint num;
+       GSList * l;
+       gchar * filename;
+
+       g_return_val_if_fail(dest != NULL, -1);
+       g_return_val_if_fail(msglist != NULL, -1);
+
+       folder = dest->folder;
+       g_return_val_if_fail(folder->scan != NULL, -1);
+       g_return_val_if_fail(folder->copy_msg != NULL, -1);
+
+       if (dest->last_num < 0) folder->scan(folder, dest);
+
+       for(l = msglist ; l != NULL ; l = g_slist_next(l)) {
+               MsgInfo * msginfo = (MsgInfo *) l->data;
+
+               folder->copy_msg(folder, dest, msginfo);
+       }
+
+       if (folder->finished_copy)
+               folder->finished_copy(folder, dest);
+
+       folder->scan(folder, dest);
+
+       return dest->last_num;
+}
 
 gint folder_item_remove_msg(FolderItem *item, gint num)
 {
@@ -653,10 +802,12 @@ gint folder_item_remove_all_msg(FolderItem *item)
        Folder *folder;
 
        g_return_val_if_fail(item != NULL, -1);
+
+       folder = item->folder;
+
        g_return_val_if_fail(folder->scan != NULL, -1);
        g_return_val_if_fail(folder->remove_all_msg != NULL, -1);
 
-       folder = item->folder;
        if (item->last_num < 0) folder->scan(folder, item);
 
        return folder->remove_all_msg(folder, item);
@@ -738,10 +889,13 @@ static void folder_init(Folder *folder, FolderType type, const gchar *name)
                folder->get_msg_list        = mh_get_msg_list;
                folder->fetch_msg           = mh_fetch_msg;
                folder->add_msg             = mh_add_msg;
+               /*
                folder->move_msg            = mh_move_msg;
                folder->move_msgs_with_dest = mh_move_msgs_with_dest;
                folder->copy_msg            = mh_copy_msg;
                folder->copy_msgs_with_dest = mh_copy_msgs_with_dest;
+               */
+               folder->copy_msg            = mh_copy_msg;
                folder->remove_msg          = mh_remove_msg;
                folder->remove_all_msg      = mh_remove_all_msg;
                folder->is_msg_changed      = mh_is_msg_changed;
@@ -755,8 +909,10 @@ static void folder_init(Folder *folder, FolderType type, const gchar *name)
        case F_IMAP:
                folder->get_msg_list        = imap_get_msg_list;
                folder->fetch_msg           = imap_fetch_msg;
+               /*
                folder->move_msg            = imap_move_msg;
                folder->move_msgs_with_dest = imap_move_msgs_with_dest;
+               */
                folder->remove_msg          = imap_remove_msg;
                folder->remove_all_msg      = imap_remove_all_msg;
                folder->scan                = imap_scan_folder;
@@ -775,18 +931,23 @@ static void folder_init(Folder *folder, FolderType type, const gchar *name)
                folder->add_msg             = mbox_add_msg;
                folder->remove_all_msg      = mbox_remove_all_msg;
                folder->remove_msg          = mbox_remove_msg;
-               folder->update_mark         = mbox_update_mark;
+               /*
                folder->move_msg            = mbox_move_msg;
                folder->move_msgs_with_dest = mbox_move_msgs_with_dest;
+               folder->copy_msg            = mbox_copy_msg;
+               folder->copy_msgs_with_dest = mbox_copy_msgs_with_dest;
+               */
+               folder->copy_msg            = mbox_copy_msg;
+
+               folder->create_tree         = mbox_create_tree;
+               folder->create_folder       = mbox_create_folder;
+               folder->rename_folder       = mbox_rename_folder;
+               folder->remove_folder       = mbox_remove_folder;
+
+               folder->update_mark         = mbox_update_mark;
+               folder->change_flags        = mbox_change_flags;
+               folder->finished_copy       = mbox_finished_copy;
 
-               /*
-               folder->remove_msg          = mh_remove_msg;
-               folder->is_msg_changed      = mh_is_msg_changed;
-               folder->scan_tree           = mh_scan_tree;
-               folder->create_tree         = mh_create_tree;
-               folder->create_folder       = mh_create_folder;
-               folder->rename_folder       = mh_rename_folder;
-               folder->remove_folder       = mh_remove_folder;*/
                break;
        default:
        }
@@ -1021,7 +1182,7 @@ static void folder_write_list_recursive(GNode *node, gpointer data)
                        xml_file_put_escape_str(fp, folder->name);
                        fputs("\"", fp);
                }
-               if (folder->type == F_MH) {
+               if ((folder->type == F_MH) || (folder->type == F_MBOX)) {
                        fputs(" path=\"", fp);
                        xml_file_put_escape_str
                                (fp, LOCAL_FOLDER(folder)->rootpath);
index 9227f7f..64ea96d 100644 (file)
@@ -148,6 +148,7 @@ struct _Folder
        void     (*change_flags)        (Folder         *folder,
                                         FolderItem     *item,
                                         MsgInfo        *info);
+       void     (*finished_copy)       (Folder * folder, FolderItem * item);
 };
 
 struct _LocalFolder
index e3e79d4..6171869 100644 (file)
@@ -232,7 +232,8 @@ static void foldersel_set_tree(void)
                folder = FOLDER(list->data);
                g_return_if_fail(folder != NULL);
 
-               if (folder->type != F_MH) continue;
+               if ((folder->type != F_MH) && (folder->type != F_MBOX))
+                       continue;
 
                node = gtk_ctree_insert_gnode(GTK_CTREE(ctree), NULL, NULL,
                                              folder->node,
index b4ea54f..8ead09c 100644 (file)
@@ -150,6 +150,9 @@ static void folderview_col_resized  (GtkCList       *clist,
 static void folderview_new_folder_cb   (FolderView     *folderview,
                                         guint           action,
                                         GtkWidget      *widget);
+static void folderview_new_mbox_folder_cb(FolderView *folderview,
+                                         guint action,
+                                         GtkWidget *widget);
 static void folderview_rename_folder_cb        (FolderView     *folderview,
                                         guint           action,
                                         GtkWidget      *widget);
@@ -199,6 +202,17 @@ static void folderview_drag_received_cb  (GtkWidget        *widget,
                                          guint             time,
                                          FolderView       *folderview);
 
+static GtkItemFactoryEntry folderview_mbox_popup_entries[] =
+{
+       {N_("/Create _new folder..."),  NULL, folderview_new_mbox_folder_cb,    0, NULL},
+       {N_("/_Rename folder..."),      NULL, folderview_rename_folder_cb, 0, NULL},
+       {N_("/_Delete folder"),         NULL, folderview_delete_folder_cb, 0, NULL},
+       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
+       {N_("/Remove _mailbox"),        NULL, folderview_remove_mailbox_cb, 0, NULL},
+       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
+       {N_("/_Property..."),           NULL, NULL, 0, NULL}
+};
+
 static GtkItemFactoryEntry folderview_mail_popup_entries[] =
 {
        {N_("/Create _new folder..."),  NULL, folderview_new_folder_cb,    0, NULL},
@@ -243,9 +257,11 @@ FolderView *folderview_create(void)
        GtkWidget *mail_popup;
        GtkWidget *news_popup;
        GtkWidget *imap_popup;
+       GtkWidget *mbox_popup;
        GtkItemFactory *mail_factory;
        GtkItemFactory *news_factory;
        GtkItemFactory *imap_factory;
+       GtkItemFactory *mbox_factory;
        gint n_entries;
        gint i;
 
@@ -306,6 +322,12 @@ FolderView *folderview_create(void)
                                       n_entries,
                                       "<NewsFolder>", &news_factory,
                                       folderview);
+       n_entries = sizeof(folderview_mbox_popup_entries) /
+               sizeof(folderview_mbox_popup_entries[0]);
+       mbox_popup = menu_create_items(folderview_mbox_popup_entries,
+                                      n_entries,
+                                      "<MailFolder>", &mbox_factory,
+                                      folderview);
 
        gtk_signal_connect(GTK_OBJECT(ctree), "key_press_event",
                           GTK_SIGNAL_FUNC(folderview_key_pressed),
@@ -340,6 +362,9 @@ FolderView *folderview_create(void)
        gtk_signal_connect(GTK_OBJECT(news_popup), "selection_done",
                           GTK_SIGNAL_FUNC(folderview_popup_close),
                           folderview);
+       gtk_signal_connect(GTK_OBJECT(mbox_popup), "selection_done",
+                          GTK_SIGNAL_FUNC(folderview_popup_close),
+                          folderview);
 
         /* drop callback */
        gtk_drag_dest_set(ctree, GTK_DEST_DEFAULT_ALL &
@@ -364,6 +389,8 @@ FolderView *folderview_create(void)
        folderview->imap_factory = imap_factory;
        folderview->news_popup   = news_popup;
        folderview->news_factory = news_factory;
+       folderview->mbox_popup   = mbox_popup;
+       folderview->mbox_factory = mbox_factory;
 
        gtk_widget_show_all(scrolledwin);
 
@@ -969,8 +996,10 @@ void folderview_new_folder(FolderView *folderview)
        g_return_if_fail(item->folder != NULL);
 
        switch (item->folder->type) {
-       case F_MH:
        case F_MBOX:
+               folderview_new_mbox_folder_cb(folderview, 0, NULL);
+               break;
+       case F_MH:
        case F_MAILDIR:
                folderview_new_folder_cb(folderview, 0, NULL);
                break;
@@ -1090,6 +1119,7 @@ static void folderview_button_pressed(GtkWidget *ctree, GdkEventButton *event,
        menu_set_insensitive_all(GTK_MENU_SHELL(folderview->mail_popup));
        menu_set_insensitive_all(GTK_MENU_SHELL(folderview->imap_popup));
        menu_set_insensitive_all(GTK_MENU_SHELL(folderview->news_popup));
+       menu_set_insensitive_all(GTK_MENU_SHELL(folderview->mbox_popup));
 
        if (folder->type == F_MH && item->parent == NULL) {
                menu_set_sensitive(folderview->mail_factory,
@@ -1127,6 +1157,22 @@ static void folderview_button_pressed(GtkWidget *ctree, GdkEventButton *event,
                menu_set_sensitive(folderview->news_factory,
                                   "/Remove newsgroup", TRUE);
        }
+       if (folder->type == F_MBOX && item->parent == NULL) {
+               menu_set_sensitive(folderview->mbox_factory,
+                                  "/Create new folder...", TRUE);
+               menu_set_sensitive(folderview->mbox_factory,
+                                  "/Remove mailbox", TRUE);
+       } else if (folder->type == F_MBOX && item->stype != F_NORMAL) {
+               menu_set_sensitive(folderview->mbox_factory,
+                                  "/Create new folder...", TRUE);
+       } else if (folder->type == F_MBOX) {
+               menu_set_sensitive(folderview->mbox_factory,
+                                  "/Create new folder...", TRUE);
+               menu_set_sensitive(folderview->mbox_factory,
+                                  "/Rename folder...", TRUE);
+               menu_set_sensitive(folderview->mbox_factory,
+                                  "/Delete folder", TRUE);
+       }
 
        if (folder->type == F_MH)
                gtk_menu_popup(GTK_MENU(folderview->mail_popup), NULL, NULL,
@@ -1137,6 +1183,9 @@ static void folderview_button_pressed(GtkWidget *ctree, GdkEventButton *event,
        else if (folder->type == F_NEWS)
                gtk_menu_popup(GTK_MENU(folderview->news_popup), NULL, NULL,
                               NULL, NULL, event->button, event->time);
+       else if (folder->type == F_MBOX)
+               gtk_menu_popup(GTK_MENU(folderview->mbox_popup), NULL, NULL,
+                              NULL, NULL, event->button, event->time);
 }
 
 static void folderview_button_released(GtkWidget *ctree, GdkEventButton *event,
@@ -1187,6 +1236,7 @@ static void folderview_selected(GtkCTree *ctree, GtkCTreeNode *row,
 {
        static gboolean can_select = TRUE;      /* exclusive lock */
        FolderItem *item;
+       gchar * s = NULL;
 
        folderview->selected = row;
 
@@ -1347,6 +1397,56 @@ static void folderview_new_folder_cb(FolderView *folderview, guint action,
        folder_write_list();
 }
 
+static void folderview_new_mbox_folder_cb(FolderView *folderview, guint action,
+                                         GtkWidget *widget)
+{
+       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
+       gchar *text[N_FOLDER_COLS] = {NULL, "0", "0", "0"};
+       FolderItem *item;
+       FolderItem *new_item;
+       gchar *new_folder;
+       GtkCTreeNode *node;
+
+       if (!folderview->selected) return;
+
+       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
+       g_return_if_fail(item != NULL);
+       g_return_if_fail(item->folder != NULL);
+
+       new_folder = input_dialog(_("New folder"),
+                                 _("Input the name of new folder:"),
+                                 _("NewFolder"));
+       if (!new_folder) return;
+
+       /* find whether the directory already exists */
+       if (folderview_find_by_name(ctree, folderview->selected, new_folder)) {
+               alertpanel_error(_("The folder `%s' already exists."),
+                                new_folder);
+               g_free(new_folder);
+               return;
+       }
+
+       new_item = item->folder->create_folder(item->folder, item, new_folder);
+       g_free(new_folder);
+       if (!new_item) return;
+
+       gtk_clist_freeze(GTK_CLIST(ctree));
+
+       text[COL_FOLDER] = new_item->name;
+       node = gtk_ctree_insert_node(ctree, folderview->selected, NULL, text,
+                                    FOLDER_SPACING,
+                                    folderxpm, folderxpmmask,
+                                    folderopenxpm, folderopenxpmmask,
+                                    FALSE, FALSE);
+       gtk_ctree_expand(ctree, folderview->selected);
+       gtk_ctree_node_set_row_data(ctree, node, new_item);
+       folderview_sort_folders(folderview, folderview->selected, item->folder);
+
+       gtk_clist_thaw(GTK_CLIST(ctree));
+
+       folder_write_list();
+}
+
 static void folderview_rename_folder_cb(FolderView *folderview, guint action,
                                        GtkWidget *widget)
 {
index 1dd02fe..9b8140a 100644 (file)
@@ -38,10 +38,12 @@ struct _FolderView
        GtkWidget *mail_popup;
        GtkWidget *imap_popup;
        GtkWidget *news_popup;
+       GtkWidget *mbox_popup;
 
        GtkItemFactory *mail_factory;
        GtkItemFactory *imap_factory;
        GtkItemFactory *news_factory;
+       GtkItemFactory *mbox_factory;
 
        GtkCTreeNode *selected;
        GtkCTreeNode *opened;
index c727506..b84a5e4 100644 (file)
@@ -147,6 +147,9 @@ static gint main_window_close_cb (GtkWidget *widget,
 static void add_mailbox_cb      (MainWindow    *mainwin,
                                  guint          action,
                                  GtkWidget     *widget);
+static void add_mbox_cb         (MainWindow    *mainwin,
+                                 guint          action,
+                                 GtkWidget     *widget);
 static void update_folderview_cb (MainWindow   *mainwin,
                                  guint          action,
                                  GtkWidget     *widget);
@@ -191,8 +194,7 @@ static void toggle_toolbar_cb        (MainWindow    *mainwin,
 static void toggle_statusbar_cb         (MainWindow    *mainwin,
                                  guint          action,
                                  GtkWidget     *widget);
-                                 
-static void separate_widget_cb(GtkCheckMenuItem *checkitem, guint action);                                
+static void separate_widget_cb(GtkCheckMenuItem *checkitem, guint action);
 
 static void addressbook_open_cb        (MainWindow     *mainwin,
                                 guint           action,
@@ -351,6 +353,7 @@ static GtkItemFactoryEntry mainwin_entries[] =
 {
        {N_("/_File"),                          NULL, NULL, 0, "<Branch>"},
        {N_("/_File/_Add mailbox..."),          NULL, add_mailbox_cb, 0, NULL},
+       {N_("/_File/_Add mbox mailbox..."),     NULL, add_mbox_cb, 0, NULL},
        {N_("/_File/_Update folder tree"),      NULL, update_folderview_cb, 0, NULL},
        {N_("/_File/_Folder"),                  NULL, NULL, 0, "<Branch>"},
        {N_("/_File/_Folder/Create _new folder..."),
@@ -1048,6 +1051,56 @@ void main_window_add_mailbox(MainWindow *mainwin)
        folderview_set(mainwin->folderview);
 }
 
+void main_window_add_mbox(MainWindow *mainwin)
+{
+       gchar *path;
+       Folder *folder;
+       FolderItem * item;
+
+       path = input_dialog(_("Add mbox mailbox"),
+                           _("Input the location of mailbox."),
+                           "mail");
+
+       if (!path) return;
+
+       /*
+       if (folder_find_from_path(path)) {
+               alertpanel_error(_("The mailbox `%s' already exists."), path);
+               g_free(path);
+               return;
+       }
+       */
+
+       /*
+       if (!strcmp(path, "Mail"))
+               folder = folder_new(F_MBOX, _("Mailbox"), path);
+               else
+       */
+
+       folder = folder_new(F_MBOX, g_basename(path), path);
+       g_free(path);
+
+       if (folder->create_tree(folder) < 0) {
+               alertpanel_error(_("Creation of the mailbox failed."));
+               folder_destroy(folder);
+               return;
+       }
+
+       folder_add(folder);
+
+       item = folder_item_new(folder->name, NULL);
+       item->folder = folder;
+       folder->node = g_node_new(item);
+
+       mbox_create_folder(folder, item, "inbox");
+       mbox_create_folder(folder, item, "outbox");
+       mbox_create_folder(folder, item, "queue");
+       mbox_create_folder(folder, item, "draft");
+       mbox_create_folder(folder, item, "trash");
+
+       folderview_set(mainwin->folderview);
+}
+
 void main_window_set_toolbar_sensitive(MainWindow *mainwin, gboolean sensitive)
 {
        gtk_widget_set_sensitive(mainwin->reply_btn,       sensitive);
@@ -1670,6 +1723,12 @@ static void add_mailbox_cb(MainWindow *mainwin, guint action,
        main_window_add_mailbox(mainwin);
 }
 
+static void add_mbox_cb(MainWindow *mainwin, guint action,
+                       GtkWidget *widget)
+{
+       main_window_add_mbox(mainwin);
+}
+
 static void update_folderview_cb(MainWindow *mainwin, guint action,
                                 GtkWidget *widget)
 {
@@ -1820,7 +1879,7 @@ static void toggle_statusbar_cb(MainWindow *mainwin, guint action,
        }
 }
 
-static void separate_widget_cb(GtkCheckMenuItem *checkitem, guint action)                                 
+static void separate_widget_cb(GtkCheckMenuItem *checkitem, guint action)
 {
        MainWindow *mainwin;
        SeparateType type;
index ae55c97..cf60a2c 100644 (file)
@@ -116,6 +116,7 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, GHashTable *folder_table)
                        FILE_OP_ERROR(tmp_file, "chmod");
 
                /* convert unix From into Return-Path */
+               /*
                startp = from_line + 5;
                endp = strchr(startp, ' ');
                if (endp == NULL)
@@ -126,6 +127,7 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, GHashTable *folder_table)
                g_snprintf(from_line, sizeof(from_line),
                           "Return-Path: %s\n", rpath);
                g_free(rpath);
+               */
 
                FPUTS_TO_TMP_ABORT_IF_FAIL(from_line);
                FPUTS_TO_TMP_ABORT_IF_FAIL(buf);
index d3243b9..bce84b9 100644 (file)
 #include "utils.h"
 #include "intl.h"
 
+#define MSGBUFSIZE     8192
+
 static gboolean mbox_write_data(FILE * mbox_fp, FILE * new_fp,
                                gchar * new_filename, gint size);
+static gboolean mbox_rewrite(gchar * mbox);
+static gboolean mbox_purge_deleted(gchar * mbox);
+static gchar * mbox_get_new_path(FolderItem * parent, gchar * name);
+static gchar * mbox_get_folderitem_name(gchar * name);
+
+
+
+static gchar *mbox_folder_get_path(FolderItem *item)
+{
+       gchar *folder_path;
+       gchar *path;
+
+       g_return_val_if_fail(item != NULL, NULL);
+
+       if (item->path && item->path[0] == G_DIR_SEPARATOR) {
+               return g_strdup(item->path);
+       }
+
+       folder_path = g_strdup(LOCAL_FOLDER(item->folder)->rootpath);
+       g_return_val_if_fail(folder_path != NULL, NULL);
+
+       if (folder_path[0] == G_DIR_SEPARATOR) {
+               if (item->path) {
+                       path = g_strconcat(folder_path, G_DIR_SEPARATOR_S,
+                                          item->path, NULL);
+               }
+               else
+                       path = g_strdup(folder_path);
+       } else {
+               if (item->path)
+                       path = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S,
+                                          folder_path, G_DIR_SEPARATOR_S,
+                                          item->path, NULL);
+               else
+                       path = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S,
+                                          folder_path, NULL);
+       }
+
+       g_free(folder_path);
+
+
+       if (!is_file_exist(path) && item->parent != NULL) {
+
+               gchar * parent_path;
+               gchar * new_path;
+
+               parent_path = mbox_folder_get_path(item->parent);
+                       
+               if (item->parent->parent != NULL)
+                       new_path = g_strconcat(parent_path, ".sbd", NULL);
+               else
+                       new_path = g_strdup(parent_path);
+               g_free(parent_path);
+               
+               if (!is_dir_exist(new_path))
+                       make_dir_hier(new_path);
+               g_free(new_path);
+               
+       }
+
+       return path;
+}
 
 
 /**********************************************************/
@@ -113,9 +177,7 @@ static gboolean mbox_fcntl_unlock_file(FILE * fp)
 
 static gboolean mbox_file_unlock_file(gchar * base)
 {
-       gchar *lockfile, *locklink;
-       gint retry = 0;
-       FILE *lockfp;
+       gchar *lockfile;
 
        lockfile = g_strdup_printf("%s.lock", base);
        unlink(lockfile);
@@ -130,7 +192,7 @@ static gboolean mbox_lockread_file(FILE * fp, gchar * base)
 
        result = mbox_fcntl_lockread_file(fp);
        if (!result) {
-               if (result = mbox_file_lock_file(base)) {
+               if ((result = mbox_file_lock_file(base)) == TRUE) {
                        file_lock = g_slist_append(file_lock, g_strdup(base));
                        debug_print("lockfile lock %s.\n", base);
                }
@@ -149,7 +211,7 @@ static gboolean mbox_lockwrite_file(FILE * fp, gchar * base)
 
        result = mbox_fcntl_lockwrite_file(fp);
        if (!result) {
-               if (result = mbox_file_lock_file(base)) {
+               if ((result = mbox_file_lock_file(base)) == TRUE) {
                        file_lock = g_slist_append(file_lock, g_strdup(base));
                        debug_print("lockfile lock %s.\n", base);
                }
@@ -164,7 +226,7 @@ static gboolean mbox_lockwrite_file(FILE * fp, gchar * base)
 
 static gboolean mbox_unlock_file(FILE * fp, gchar * base)
 {
-       gboolean result;
+       gboolean result = FALSE;
        GSList * l;
        gboolean unlocked = FALSE;
 
@@ -176,12 +238,15 @@ static gboolean mbox_unlock_file(FILE * fp, gchar * base)
                        g_free(data);
                        result = mbox_file_unlock_file(base);
                        unlocked = TRUE;
+                       debug_print("lockfile unlock - %s.\n", base);
                        break;
                }
        }
        
-       if (!unlocked)
+       if (!unlocked) {
                result = mbox_fcntl_unlock_file(fp);
+               debug_print("fcntl unlock - %s.\n", base);
+       }
 
        return result;
 }
@@ -208,9 +273,9 @@ static int mailfile_error = MAILFILE_ERROR_NO_ERROR;
 #define STATE_MEM_ERROR   0x006
 #define STATE_TEXT_BEGIN  0x007
 
-#define STATE_MASK        0x0FF // filter state from functions
+#define STATE_MASK        0x0FF /* filter state from functions */
 
-#define STATE_RESTORE_POS       0x100 // go back while reading
+#define STATE_RESTORE_POS       0x100 /* go back while reading */
 
 typedef struct _mailfile mailfile;
 
@@ -224,7 +289,6 @@ struct _mailfile
 struct _message
 {
        int msgnum;
-       int deleted;
        int offset;
        int header;
        int content;
@@ -233,6 +297,7 @@ struct _message
        gchar * messageid;
        gchar * fromspace;
        MsgFlags flags;
+       MsgFlags old_flags;
        gboolean fetched;
 };
 
@@ -270,7 +335,7 @@ static mailfile * mailfile_init_from_file(FILE * f, gchar * filename)
 {
        int state;
        GList * msg_list = NULL;
-       char * r;
+       char * r = NULL;
        char s[256];
        int lastpos = 0;
        int former_pos = 0;
@@ -281,6 +346,7 @@ static mailfile * mailfile_init_from_file(FILE * f, gchar * filename)
 
        state = STATE_BEGIN;
 
+
        while (state != STATE_END_OF_FILE) {
                if ((state & STATE_RESTORE_POS) == 0) {
                        former_pos = lastpos;
@@ -313,12 +379,13 @@ static mailfile * mailfile_init_from_file(FILE * f, gchar * filename)
                                data->header = lastpos;
                                data->end = 0;
                                data->content = 0;
-                               data->deleted = 0;
                                data->messageid = NULL;
                                data->fromspace = NULL;
                                data->flags = -1;
+                               data->old_flags = -1;
                                data->fetched = FALSE;
-                               msg_list = g_list_append(msg_list, (gpointer) data);
+                               msg_list = g_list_append(msg_list,
+                                                        (gpointer) data);
                        }
                        else
                                state = STATE_BEGIN;
@@ -335,15 +402,15 @@ static mailfile * mailfile_init_from_file(FILE * f, gchar * filename)
                        break;
 
                case STATE_TEXT_BEGIN:
+                       data->content = lastpos;
                        if (r == NULL)
                                state = STATE_END;
                        else if (startFrom(s)) {
-                               data->content = lastpos;
-
                                state = STATE_END | STATE_RESTORE_POS;
                        }
-                       else
+                       else {
                                state = STATE_TEXT_READ;
+                       }
                        break;
          
                case STATE_FROM_READ:
@@ -364,8 +431,9 @@ static mailfile * mailfile_init_from_file(FILE * f, gchar * filename)
                                state = STATE_END;
                        else if (startSpace(s))
                                state = STATE_FIELD_READ;
-                       else if (startEmpty(s))
+                       else if (startEmpty(s)) {
                                state = STATE_TEXT_BEGIN;
+                       }
                        else
                                state = STATE_FIELD_READ;
                        break;
@@ -373,10 +441,7 @@ static mailfile * mailfile_init_from_file(FILE * f, gchar * filename)
       
                if ((state & STATE_MASK) == STATE_END) {
                        state = STATE_BEGIN | (state & STATE_RESTORE_POS);
-                       if (state & STATE_RESTORE_POS)
-                               data->end = former_pos;
-                       else
-                               data->end = lastpos;
+                       data->end = lastpos;
                }
 
                if (ignore_next) {
@@ -396,7 +461,7 @@ static mailfile * mailfile_init_from_file(FILE * f, gchar * filename)
                return NULL;
        }
 
-       mf->msg_list = msg_list;
+       mf->msg_list = g_list_first(msg_list);
 
        mf->filename = g_strdup(filename);
        mf->count = msgnum;
@@ -577,13 +642,42 @@ static int mailfile_find_deleted(mailfile f, char * filename)
 struct _mboxcache {
        gchar * filename;
        mailfile * mf;
+       GPtrArray * tab_mf;
        gint mtime;
+       gboolean modification;
 };
 
 typedef struct _mboxcache mboxcache;
 
 static GHashTable * mbox_cache_table = NULL;
-static mboxcache * current_mbox = NULL;
+
+static MsgInfo *mbox_parse_msg(FILE * fp, struct _message * msg,
+                              FolderItem *item)
+{
+       MsgInfo *msginfo;
+       MsgFlags flags = MSG_NEW|MSG_UNREAD;
+
+       g_return_val_if_fail(fp != NULL, NULL);
+
+       if (item != NULL) {
+               if (item->stype == F_QUEUE) {
+                       MSG_SET_FLAGS(flags, MSG_QUEUED);
+               } else if (item->stype == F_DRAFT) {
+                       MSG_SET_FLAGS(flags, MSG_DRAFT);
+               }
+       }
+
+       msginfo = procheader_file_parse(fp, flags, FALSE);
+
+       if (!msginfo) return NULL;
+
+       if (item != NULL) {
+               msginfo->msgnum = msg->msgnum;
+               msginfo->folder = item;
+       }
+
+       return msginfo;
+}
 
 static void mbox_cache_init()
 {
@@ -597,16 +691,62 @@ static void mbox_cache_done()
 
 static void mbox_cache_free_mbox(mboxcache * cache)
 {
+       g_hash_table_remove(mbox_cache_table, cache->filename);
+
+       if (cache->mf)
+               mailfile_done(cache->mf);
+       if (cache->tab_mf)
+               g_ptr_array_free(cache->tab_mf, FALSE);
        if (cache->filename)
                g_free(cache->filename);
        g_free(cache);
 }
 
+static void mbox_cache_get_msginfo_from_file(FILE * fp, GList * msg_list)
+{
+       GList * l;
+       MsgInfo * msginfo;
+
+       for(l = msg_list ; l != NULL ; l = g_list_next(l)) {
+               struct _message * msg;
+
+               msg = (struct _message *) l->data;
+
+               fseek(fp, msg->header, SEEK_SET);
+               msginfo = mbox_parse_msg(fp, msg, NULL);
+               if (msginfo) {
+                       if (msginfo->msgid)
+                               msg->messageid =
+                                       g_strdup(msginfo->msgid);
+                       if (msginfo->fromspace)
+                               msg->fromspace =
+                                       g_strdup(msginfo->fromspace);
+                       msg->flags = msginfo->flags;
+                       msg->old_flags = msginfo->flags;
+
+                       procmsg_msginfo_free(msginfo);
+               }
+       }
+}
+
+static void mbox_cache_get_msginfo(gchar * filename, GList * msg_list)
+{
+       FILE * fp;
+
+       fp = fopen(filename, "r");
+       if (fp == NULL)
+               return;
+
+       mbox_cache_get_msginfo_from_file(fp, msg_list);
+       fclose(fp);
+}
+
 static mboxcache * mbox_cache_read_mbox(gchar * filename)
 {
        mboxcache * cache;
        struct stat s;
        mailfile * mf;
+       GList * l;
 
        if (stat(filename, &s) < 0)
                return NULL;
@@ -620,6 +760,15 @@ static mboxcache * mbox_cache_read_mbox(gchar * filename)
        cache->mtime = s.st_mtime;
        cache->mf = mf;
        cache->filename = g_strdup(filename);
+       cache->modification = FALSE;
+
+       cache->tab_mf = g_ptr_array_new();
+       for(l = mf->msg_list ; l != NULL ; l = g_list_next(l))
+               g_ptr_array_add(cache->tab_mf, l->data);
+
+       mbox_cache_get_msginfo(filename, mf->msg_list);
+
+       debug_print(_("read mbox - %s\n"), filename);
 
        return cache;
 }
@@ -629,6 +778,7 @@ static mboxcache * mbox_cache_read_mbox_from_file(FILE * fp, gchar * filename)
        mboxcache * cache;
        struct stat s;
        mailfile * mf;
+       GList * l;
 
        if (stat(filename, &s) < 0)
                return NULL;
@@ -643,15 +793,23 @@ static mboxcache * mbox_cache_read_mbox_from_file(FILE * fp, gchar * filename)
        cache->mf = mf;
        cache->filename = g_strdup(filename);
 
+       cache->tab_mf = g_ptr_array_new();
+       for(l = mf->msg_list ; l != NULL ; l = g_list_next(l))
+               g_ptr_array_add(cache->tab_mf, l->data);
+
+       mbox_cache_get_msginfo_from_file(fp, mf->msg_list);
+
+       debug_print(_("read mbox from file - %s\n"), filename);
+
        return cache;
 }
 
-static void mbox_cache_insert_mbox(gchar * filename, mboxcache * data)
+static void mbox_cache_insert_mbox(mboxcache * data)
 {
        if (mbox_cache_table == NULL)
                mbox_cache_init();
 
-       g_hash_table_insert(mbox_cache_table, filename, data);
+       g_hash_table_insert(mbox_cache_table, data->filename, data);
 }
 
 static mboxcache * mbox_cache_get_mbox(gchar * filename)
@@ -700,43 +858,44 @@ static GList * mbox_cache_get_msg_list(gchar * filename)
        return cache->mf->msg_list;
 }
 
-static void mbox_cache_synchronize_lists(GList * msg_new_list,
-                                        GList * msg_old_list)
+static void mbox_cache_synchronize_lists(GList * old_msg_list,
+                                        GList * new_msg_list)
 {
-       struct _message * msg_new;
-       struct _message * msg_old;
-       GList * l_new;
-       GList * l_old;
+       GList * l;
+       GList * l2;
 
-       // could be improved with a hash table
-       for(l_old = msg_old_list ; l_old != NULL ;
-           l_old = g_list_next(l_old)) {
-               msg_old = (struct _message *) l_old->data;
-               
-               if ((msg_old->messageid == NULL) ||
-                   (msg_old->fromspace == NULL))
+       for(l2 = old_msg_list ; l2 != NULL ; l2 = g_list_next(l2)) {
+               struct _message * msg2 = l2->data;
+
+               printf("lili %p\n", msg2);
+       
+               printf("lili %p\n", msg2->messageid);
+       
+               if ((msg2->messageid == NULL) ||
+                   (msg2->fromspace == NULL))
                        continue;
-               
-               for(l_new = msg_new_list ; l_new != NULL ;
-                   l_new = g_list_next(l_new)) {
-                       msg_new = (struct _message *) l_new->data;
+
+               for(l = new_msg_list ; l != NULL ; l = g_list_next(l)) {
+                       struct _message * msg = l->data;
                        
-                       if ((msg_new->messageid == NULL) ||
-                           (msg_new->fromspace == NULL))
+                       if ((msg->messageid == NULL) ||
+                           (msg->fromspace == NULL))
                                continue;
-                       
-                       if (!strcmp(msg_new->messageid, msg_old->messageid) &&
-                           !strcmp(msg_new->fromspace, msg_old->fromspace)) {
-                               // copy flags
-                               msg_new->deleted = msg_old->deleted;
-                               msg_new->flags = msg_old->flags;
-                               break;
+
+                       if ((strcmp(msg->messageid, msg2->messageid) == 0) &&
+                           (strcmp(msg->fromspace, msg2->fromspace) == 0)) {
+                               if ((msg2->flags & MSG_PERMANENT_FLAG_MASK) !=
+                                   (msg2->old_flags &
+                                    MSG_PERMANENT_FLAG_MASK)) {
+                                       msg->flags = msg2->flags;
+                                       break;
+                               }
                        }
                }
        }
 }
 
-static void mbox_cache_synchronize(gchar * filename)
+static void mbox_cache_synchronize(gchar * filename, gboolean sync)
 {
        mboxcache * new_cache;
        mboxcache * old_cache;
@@ -755,26 +914,61 @@ static void mbox_cache_synchronize(gchar * filename)
        }
 
        if (scan_new) {
+               GList * l;
+
+               /*              
+               if (strstr(filename, "trash") == 0)
+                       printf("old_cache: %p %s\n", old_cache, filename);
+                       if (old_cache) {
+                               printf("begin old\n");
+                               for(l = old_cache->mf->msg_list ; l != NULL ;
+                                   l = g_list_next(l)) {
+                                       struct _message * msg = l->data;
+                                       printf("%p\n", msg);
+                               }
+                               printf("end old\n");
+                       }
+               */              
+
                new_cache = mbox_cache_read_mbox(filename);
-               
-               if (new_cache == NULL) {
-                       if (old_cache != NULL)
-                               mbox_cache_free_mbox(old_cache);
+
+               /*
+               if (strstr(filename, "trash") == 0) 
+                       printf("new_cache: %p %s\n", new_cache, filename);
+                       if (new_cache) {
+                               printf("begin new\n");
+                               for(l = new_cache->mf->msg_list ; l != NULL ;
+                                   l = g_list_next(l)) {
+                                       struct _message * msg = l->data;
+                                       printf("%p\n", msg);
+                               }
+                               printf("end new\n");
+                       }
+               */
+
+               if (!new_cache)
                        return;
-               }
 
-               if (old_cache != NULL) {
-                       if ((old_cache->mf != NULL) &&
-                           (new_cache->mf != NULL))
-                               mbox_cache_synchronize_lists(new_cache->mf->msg_list, old_cache->mf->msg_list);
+               if (sync && new_cache && old_cache)
+                       mbox_cache_synchronize_lists(old_cache->mf->msg_list,
+                                                    new_cache->mf->msg_list);
+
+               if (old_cache != NULL)
                        mbox_cache_free_mbox(old_cache);
+
+               if (new_cache) {
+                       mbox_cache_insert_mbox(new_cache);
+                       /*
+                       printf("insert %p %s\n", new_cache, new_cache->filename);
+                       printf("inserted %s %p\n", filename,
+                              mbox_cache_get_mbox(filename));
+                       */
                }
-       
-               mbox_cache_insert_mbox(filename, new_cache);
        }
 }
 
-static void mbox_cache_synchronize_from_file(FILE * fp, gchar * filename)
+static void mbox_cache_synchronize_from_file(FILE * fp, gchar * filename,
+                                            gboolean sync)
 {
        mboxcache * new_cache;
        mboxcache * old_cache;
@@ -792,34 +986,76 @@ static void mbox_cache_synchronize_from_file(FILE * fp, gchar * filename)
                }
        }
 
+
        if (scan_new) {
-               new_cache = mbox_cache_read_mbox_from_file(fp, filename);
+
+               /*
+               GList * l;
+
+               if (strstr(filename, "trash") == 0)
+                       printf("old_cache: %p %s\n", old_cache, filename);
+
+                       if (old_cache) {
+                               printf("begin old\n");
+                               for(l = old_cache->mf->msg_list ; l != NULL ;
+                                   l = g_list_next(l)) {
+                                       struct _message * msg = l->data;
+                                       printf("%p\n", msg);
+                               }
+                               printf("end old\n");
+                       }
+               */
                
-               if (new_cache == NULL) {
-                       if (old_cache != NULL)
-                               mbox_cache_free_mbox(old_cache);
+               new_cache = mbox_cache_read_mbox_from_file(fp, filename);
+
+               /*
+               if (strstr(filename, "trash") == 0) 
+                       printf("new_cache: %p %s\n", new_cache, filename);
+
+                       if (new_cache) {
+                               printf("begin new\n");
+                               for(l = new_cache->mf->msg_list ; l != NULL ;
+                                   l = g_list_next(l)) {
+                                       struct _message * msg = l->data;
+                                       printf("%p\n", msg);
+                               }
+                               printf("end new\n");
+                       }
+               */
+
+               if (!new_cache)
                        return;
-               }
 
-               if (old_cache != NULL) {
-                       if ((old_cache->mf != NULL) &&
-                           (new_cache->mf != NULL))
-                               mbox_cache_synchronize_lists(new_cache->mf->msg_list, old_cache->mf->msg_list);
+               if (sync && new_cache && old_cache)
+                       mbox_cache_synchronize_lists(old_cache->mf->msg_list,
+                                                    new_cache->mf->msg_list);
+
+               if (old_cache != NULL)
                        mbox_cache_free_mbox(old_cache);
+
+               if (new_cache) {
+                       mbox_cache_insert_mbox(new_cache);
+                       /*
+                       printf("insert %p %s\n", new_cache, new_cache->filename);
+                       printf("inserted %s %p\n", filename,
+                              mbox_cache_get_mbox(filename));
+                       */
                }
-       
-               mbox_cache_insert_mbox(filename, new_cache);
        }
 }
 
 gboolean mbox_cache_msg_fetched(gchar * filename, gint num)
 {
-       GList * msg_list;
        struct _message * msg;
+       mboxcache * cache;
+
+       cache = mbox_cache_get_mbox(filename);
 
-       msg_list = mbox_cache_get_msg_list(filename);
-       msg = (struct _message *) g_list_nth_data(msg_list, num - 1);
+       if (cache == NULL)
+               return FALSE;
 
+       msg = (struct _message *) g_ptr_array_index(cache->tab_mf,
+                                                   num - 1);
        if (msg == NULL)
                return FALSE;
 
@@ -828,66 +1064,51 @@ gboolean mbox_cache_msg_fetched(gchar * filename, gint num)
 
 void mbox_cache_msg_set_fetched(gchar * filename, gint num)
 {
-       GList * msg_list;
        struct _message * msg;
+       mboxcache * cache;
 
-       msg_list = mbox_cache_get_msg_list(filename);
-       if ((msg = (struct _message *) g_list_nth_data(msg_list, num - 1))
-           == NULL)
-               return;
-       msg->fetched = TRUE;
-}
+       cache = mbox_cache_get_mbox(filename);
 
+       if (cache == NULL)
+               return;
 
-/**********************************************************/
-/*                                                        */
-/*                   mbox operations                      */
-/*                                                        */
-/**********************************************************/
+       msg = (struct _message *) g_ptr_array_index(cache->tab_mf,
+                                                   num - 1);
+       if (msg == NULL)
+               return;
 
+       msg->fetched = TRUE;
+}
 
-static MsgInfo *mbox_parse_msg(FILE * fp, gint msgnum, FolderItem *item)
+struct _message * mbox_cache_get_msg(gchar * filename, gint num)
 {
-       struct stat s;
-       MsgInfo *msginfo;
-       MsgFlags flags = MSG_NEW|MSG_UNREAD;
+       mboxcache * cache;
 
-       g_return_val_if_fail(item != NULL, NULL);
-       g_return_val_if_fail(fp != NULL, NULL);
+       cache = mbox_cache_get_mbox(filename);
 
-       if (item->stype == F_QUEUE) {
-               MSG_SET_FLAGS(flags, MSG_QUEUED);
-       } else if (item->stype == F_DRAFT) {
-               MSG_SET_FLAGS(flags, MSG_DRAFT);
+       if (cache == NULL) {
+               return NULL;
        }
 
-       msginfo = procheader_file_parse(fp, flags, FALSE);
-
-       if (!msginfo) return NULL;
+       return (struct _message *) g_ptr_array_index(cache->tab_mf,
+                                                    num - 1);
+}
 
-       msginfo->msgnum = msgnum;
-       msginfo->folder = item;
 
-       if (stat(item->path, &s) < 0) {
-               FILE_OP_ERROR(item->path, "stat");
-               msginfo->size = 0;
-               msginfo->mtime = 0;
-       } else {
-               msginfo->size = s.st_size;
-               msginfo->mtime = s.st_mtime;
-       }
+/**********************************************************/
+/*                                                        */
+/*                   mbox operations                      */
+/*                                                        */
+/**********************************************************/
 
-       return msginfo;
-}
 
 GSList *mbox_get_msg_list(Folder *folder, FolderItem *item, gboolean use_cache)
 {
        GSList *mlist;
-       GHashTable *msg_table;
-       MsgFlags flags = MSG_NEW|MSG_UNREAD;
        MsgInfo * msginfo;
        GList * l;
        FILE * fp;
+       gchar * mbox_path;
 
 #ifdef MEASURE_TIME
        struct timeval tv_before, tv_after, tv_result;
@@ -897,44 +1118,54 @@ GSList *mbox_get_msg_list(Folder *folder, FolderItem *item, gboolean use_cache)
 
        mlist = NULL;
 
-       fp = fopen(item->path, "r");
+       mbox_path = mbox_folder_get_path(item);
 
-       mbox_lockread_file(fp, item->path);
+       if (mbox_path == NULL)
+               return NULL;
 
-       mbox_cache_synchronize_from_file(fp, item->path);
+       mbox_purge_deleted(mbox_path);
 
-       if (mbox_cache_get_mbox(item->path) == NULL) {
-               g_warning(_("parsing of %s failed.\n"), item->path);
-               mbox_unlock_file(fp, item->path);
-               fclose(fp);
+       fp = fopen(mbox_path, "r");
+       
+       if (fp == NULL) {
+               g_free(mbox_path);
                return NULL;
        }
 
-       for(l = mbox_cache_get_msg_list(item->path) ; l != NULL ;
+       mbox_lockread_file(fp, mbox_path);
+
+       mbox_cache_synchronize_from_file(fp, mbox_path, TRUE);
+
+       item->last_num = mbox_cache_get_count(mbox_path);
+
+       for(l = mbox_cache_get_msg_list(mbox_path) ; l != NULL ;
            l = g_list_next(l)) {
                struct _message * msg;
 
                msg = (struct _message *) l->data;
 
-               if (!msg->deleted) {
+               if (msg->flags == -1 || !MSG_IS_REALLY_DELETED(msg->flags)) {
                        fseek(fp, msg->header, SEEK_SET);
-                       msginfo = mbox_parse_msg(fp, msg->msgnum, item);
-                       if (msginfo) {
-                               if (msginfo->msgid)
-                                       msg->messageid =
-                                               g_strdup(msginfo->msgid);
-                               if (msginfo->fromspace)
-                                       msg->fromspace =
-                                               g_strdup(msginfo->fromspace);
-                               msginfo->data = msg;
-                       }
+
+                       msginfo = mbox_parse_msg(fp, msg, item);
+
                        if (msg->flags != -1)
                                msginfo->flags = msg->flags;
+                       else {
+                               msg->old_flags = msginfo->flags;
+                               msg->flags = msginfo->flags;
+                       }
+
                        mlist = g_slist_append(mlist, msginfo);
                }
+               else {
+                       msg->flags = MSG_REALLY_DELETED;
+               }
        }
 
-       mbox_unlock_file(fp, item->path);
+       mbox_unlock_file(fp, mbox_path);
+
+       g_free(mbox_path);
 
        fclose(fp);
 
@@ -943,13 +1174,13 @@ GSList *mbox_get_msg_list(Folder *folder, FolderItem *item, gboolean use_cache)
 
        timersub(&tv_after, &tv_before, &tv_result);
        g_print("mbox_get_msg_list: %s: elapsed time: %ld.%06ld sec\n",
-               item->path, tv_result.tv_sec, tv_result.tv_usec);
+               mbox_path, tv_result.tv_sec, tv_result.tv_usec);
 #endif
 
        return mlist;
 }
 
-static gboolean mbox_extract_msg(gchar * mbox_filename, gint msgnum,
+static gboolean mbox_extract_msg(FolderItem * item, gint msgnum,
                                 gchar * dest_filename)
 {
        struct _message * msg;
@@ -959,32 +1190,40 @@ static gboolean mbox_extract_msg(gchar * mbox_filename, gint msgnum,
        FILE * src;
        FILE * dest;
        gboolean err;
-       GList * msg_list;
+       /*      GList * msg_list;*/
        gboolean already_fetched;
+       gchar * mbox_path;
+
+       mbox_path = mbox_folder_get_path(item);
+
+       if (mbox_path == NULL)
+               return FALSE;
 
-       src = fopen(mbox_filename, "r");
-       if (src == NULL)
+       src = fopen(mbox_path, "r");
+       if (src == NULL) {
+               g_free(mbox_path);
                return FALSE;
+       }
 
-       mbox_lockread_file(src, mbox_filename);
+       mbox_lockread_file(src, mbox_path);
 
-       mbox_cache_synchronize_from_file(src, mbox_filename);
+       mbox_cache_synchronize_from_file(src, mbox_path, TRUE);
 
-       already_fetched = mbox_cache_msg_fetched(mbox_filename, msgnum);
+       already_fetched = mbox_cache_msg_fetched(mbox_path, msgnum);
 
        if (already_fetched) {
-               mbox_unlock_file(src, mbox_filename);
+               mbox_unlock_file(src, mbox_path);
                fclose(src);
+               g_free(mbox_path);
                return TRUE;
        }
 
-       msg_list = mbox_cache_get_msg_list(mbox_filename);
-
-       msg = (struct _message *) g_list_nth_data(msg_list, msgnum - 1);
+       msg = mbox_cache_get_msg(mbox_path, msgnum);
 
        if (msg == NULL) {
-               mbox_unlock_file(src, mbox_filename);
+               mbox_unlock_file(src, mbox_path);
                fclose(src);
+               g_free(mbox_path);
                return FALSE;
        }
 
@@ -997,8 +1236,9 @@ static gboolean mbox_extract_msg(gchar * mbox_filename, gint msgnum,
 
        dest = fopen(dest_filename, "w");
        if (dest == NULL) {
-               mbox_unlock_file(src, mbox_filename);
+               mbox_unlock_file(src, mbox_path);
                fclose(src);
+               g_free(mbox_path);
                return FALSE;
        }
 
@@ -1008,34 +1248,37 @@ static gboolean mbox_extract_msg(gchar * mbox_filename, gint msgnum,
        }
 
        if (!mbox_write_data(src, dest, dest_filename, size)) {
-               mbox_unlock_file(src, mbox_filename);
+               mbox_unlock_file(src, mbox_path);
                fclose(dest);
                fclose(src);
                unlink(dest_filename);
+               g_free(mbox_path);
                return FALSE;
        }
 
        err = FALSE;
 
        if (ferror(src)) {
-               FILE_OP_ERROR(mbox_filename, "fread");
+               FILE_OP_ERROR(mbox_path, "fread");
                err = TRUE;
        }
 
-       mbox_cache_msg_set_fetched(mbox_filename, msgnum);
+       mbox_cache_msg_set_fetched(mbox_path, msgnum);
 
        if (fclose(dest) == -1) {
                FILE_OP_ERROR(dest_filename, "fclose");
-               return FALSE;
+               err = TRUE;
        }
 
-       mbox_unlock_file(src, mbox_filename);
+       mbox_unlock_file(src, mbox_path);
 
        if (fclose(src) == -1) {
-               FILE_OP_ERROR(mbox_filename, "fclose");
+               FILE_OP_ERROR(mbox_path, "fclose");
                err = TRUE;
        }
 
+       g_free(mbox_path);
+
        if (err) {
                unlink(dest_filename);
                return FALSE;
@@ -1050,9 +1293,7 @@ gchar *mbox_fetch_msg(Folder *folder, FolderItem *item, gint num)
        gchar *filename;
        
        g_return_val_if_fail(item != NULL, NULL);
-       /*
        g_return_val_if_fail(num > 0 && num <= item->last_num, NULL);
-       */
 
        path = folder_item_get_path(item);
        if (!is_dir_exist(path))
@@ -1062,7 +1303,7 @@ gchar *mbox_fetch_msg(Folder *folder, FolderItem *item, gint num)
 
        g_free(path);
 
-       if (!mbox_extract_msg(item->path, num, filename)) {
+       if (!mbox_extract_msg(item, num, filename)) {
                g_free(filename);
                return NULL;
        }
@@ -1079,6 +1320,8 @@ gint mbox_add_msg(Folder *folder, FolderItem *dest, const gchar *file,
        gint old_size;
        gint n_read;
        gboolean err;
+       gchar * mbox_path;
+       gchar from_line[MSGBUFSIZE];
 
        if (dest->last_num < 0) {
                mbox_scan_folder(folder, dest);
@@ -1090,38 +1333,71 @@ gint mbox_add_msg(Folder *folder, FolderItem *dest, const gchar *file,
                return -1;
        }
 
-       dest_fp = fopen(dest->path, "a");
+       mbox_path = mbox_folder_get_path(dest);
+       if (mbox_path == NULL)
+               return -1;
+
+       dest_fp = fopen(mbox_path, "a");
        if (dest_fp == NULL) {
                fclose(src_fp);
+               g_free(mbox_path);
                return -1;
        }
        old_size = ftell(dest_fp);
 
-       mbox_lockwrite_file(dest_fp, dest->path);
+       mbox_lockwrite_file(dest_fp, mbox_path);
+
+       if (fgets(from_line, sizeof(from_line), src_fp) == NULL) {
+               mbox_unlock_file(dest_fp, mbox_path);
+               g_warning(_("unvalid file - %s.\n"), file);
+               fclose(dest_fp);
+               fclose(src_fp);
+               g_free(mbox_path);
+               return -1;
+       }
        
+       if (strncmp(from_line, "From ", 5) != 0) {
+               struct stat s;
+
+               if (stat(file, &s) < 0) {
+                       mbox_unlock_file(dest_fp, mbox_path);
+                       g_warning(_("unvalid file - %s.\n"), file);
+                       fclose(dest_fp);
+                       fclose(src_fp);
+                       g_free(mbox_path);
+                       return -1;
+               }
+
+               fprintf(dest_fp, "From - %s", ctime(&s.st_mtime));
+       }
+
+       fputs(from_line, dest_fp);
+
        while (1) {
                n_read = fread(buf, 1, sizeof(buf), src_fp);
-               if (n_read < sizeof(buf) && ferror(src_fp))
+               if ((n_read < (gint) sizeof(buf)) && ferror(src_fp))
                        break;
                if (fwrite(buf, n_read, 1, dest_fp) < 1) {
-                       g_warning(_("writing to %s failed.\n"), dest->path);
+                       mbox_unlock_file(dest_fp, mbox_path);
+                       g_warning(_("writing to %s failed.\n"), mbox_path);
                        ftruncate(fileno(dest_fp), old_size);
                        fclose(dest_fp);
                        fclose(src_fp);
+                       g_free(mbox_path);
                        return -1;
                }
 
-               if (n_read < sizeof(buf))
+               if (n_read < (gint) sizeof(buf))
                        break;
        }
 
        err = FALSE;
 
        if (ferror(src_fp)) {
-               FILE_OP_ERROR(dest->path, "fread");
+               FILE_OP_ERROR(mbox_path, "fread");
        }
 
-       mbox_unlock_file(src_fp, dest->path);
+       mbox_unlock_file(dest_fp, mbox_path);
 
        if (fclose(src_fp) == -1) {
                FILE_OP_ERROR(file, "fclose");
@@ -1129,12 +1405,14 @@ gint mbox_add_msg(Folder *folder, FolderItem *dest, const gchar *file,
        }
 
        if (fclose(dest_fp) == -1) {
-               FILE_OP_ERROR(dest->path, "fclose");
+               FILE_OP_ERROR(mbox_path, "fclose");
+               g_free(mbox_path);
                return -1;
        }
 
        if (err) {
                ftruncate(fileno(dest_fp), old_size);
+               g_free(mbox_path);
                return -1;
        }
 
@@ -1143,6 +1421,8 @@ gint mbox_add_msg(Folder *folder, FolderItem *dest, const gchar *file,
                        FILE_OP_ERROR(file, "unlink");
        }
 
+       g_free(mbox_path);
+
        dest->last_num++;
        return dest->last_num;
 
@@ -1151,22 +1431,20 @@ gint mbox_add_msg(Folder *folder, FolderItem *dest, const gchar *file,
 gint mbox_remove_msg(Folder *folder, FolderItem *item, gint num)
 {
        struct _message * msg;
-       GList * msg_list;
+       gchar * mbox_path;
 
-       mbox_cache_synchronize(item->path);
+       mbox_path = mbox_folder_get_path(item);
+       if (mbox_path == NULL)
+               return -1;
 
-       msg_list = mbox_cache_get_msg_list(item->path);
+       mbox_cache_synchronize(mbox_path, TRUE);
 
-       msg = (struct _message *) g_list_nth_data(msg_list,
-                                                 num - 1);
-       msg->deleted = 1;
+       msg = mbox_cache_get_msg(mbox_path, num);
 
-       /*
-       if (!mbox_rewrite(item->path)) {
-               printf("rewrite %s\n", item->path);
-               return -1;
-       }
-       */
+       g_free(mbox_path);
+       
+       if (msg != NULL)
+               MSG_SET_FLAGS(msg->flags, MSG_REALLY_DELETED);
 
        return 0;
 }
@@ -1174,128 +1452,257 @@ gint mbox_remove_msg(Folder *folder, FolderItem *item, gint num)
 gint mbox_remove_all_msg(Folder *folder, FolderItem *item)
 {
        FILE * fp;
+       gchar * mbox_path;
+
+       mbox_path = mbox_folder_get_path(item);
+       if (mbox_path == NULL)
+               return -1;
 
-       fp = fopen(item->path, "w");
+       fp = fopen(mbox_path, "w");
        if (fp == NULL) {
+               g_free(mbox_path);
                return -1;
        }
 
        fclose(fp);
 
+       g_free(mbox_path);
+
        return 0;
 }
 
+/*
 gint mbox_move_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
 {
-       /*
+       gchar * filename;
+       gint msgnum;
 
-       mbox_cache_synchronize(item->path);
+       filename = mbox_fetch_msg(folder, msginfo->folder, msginfo->msgnum);
+       if (filename == NULL)
+               return -1;
 
-       size = msg->end - msg->offset;
+       msgnum = mbox_add_msg(folder, dest, filename, TRUE);
 
-       src = fopen(mbox_filename, "r");
-       if (src == NULL)
-               return FALSE;
-       fseek(src, msg->offset, SEEK_SET);
+       if (msgnum != -1) {
+               MSG_SET_FLAGS(msginfo->flags, MSG_REALLY_DELETED);
+               mbox_change_flags(folder, msginfo->folder, msginfo);
+       }
 
-       mbox_lockread_file(src, mbox_filename);
+       return msgnum;
+}
 
-       dest = fopen(dest_filename, "a");
-       if (dest == NULL) {
-               fclose(src);
-               return FALSE;
-       }
+gint mbox_move_msgs_with_dest(Folder *folder, FolderItem *dest, GSList *msglist)
+{
+       GSList * l;
+       gchar * mbox_path = NULL;
 
-       if (change_file_mode_rw(dest, dest_filename) < 0) {
-               FILE_OP_ERROR(dest_filename, "chmod");
-               g_warning(_("can't change file mode\n"));
+       for(l = msglist ; l != NULL ; l = g_slist_next(l)) {
+               MsgInfo * msginfo = (MsgInfo *) l->data;
+
+               if (msginfo->folder && mbox_path == NULL)
+                       mbox_path = mbox_folder_get_path(msginfo->folder);
+
+               mbox_move_msg(folder, dest, msginfo);
        }
 
-       if (!mbox_write_data(src, dest, dest_filename, size)) {
-                       fclose(dest);
-                       fclose(src);
-                       unlink(dest_filename);
-                       return FALSE;
+       if (mbox_path) {
+               mbox_cache_synchronize(mbox_path);
+               g_free(mbox_path);
        }
-       
-       return -1;
-       */
+
+       mbox_path = mbox_folder_get_path(dest);
+       mbox_cache_synchronize(mbox_path);
+       g_free(mbox_path);
+
+       return dest->last_num;
+}
+*/
+
+/*
+gint mbox_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
+{
        gchar * filename;
+       gint msgnum;
 
        filename = mbox_fetch_msg(folder, msginfo->folder, msginfo->msgnum);
        if (filename == NULL)
                return -1;
 
-       ((struct _message *) msginfo->data)->deleted = TRUE;
+       msgnum = mbox_add_msg(folder, dest, filename, FALSE);
 
-       return mbox_add_msg(folder, dest, filename, TRUE);
+       return msgnum;
 }
 
-gint mbox_move_msgs_with_dest(Folder *folder, FolderItem *dest, GSList *msglist)
+gint mbox_copy_msgs_with_dest(Folder *folder, FolderItem *dest, GSList *msglist)
 {
        GSList * l;
-       gchar * path = NULL;
+       gchar * mbox_path = NULL;
 
        for(l = msglist ; l != NULL ; l = g_slist_next(l)) {
                MsgInfo * msginfo = (MsgInfo *) l->data;
 
-               if (msginfo->folder)
-                       path = msginfo->folder->path;
+               if (msginfo->folder && mbox_path == NULL)
+                       mbox_path = mbox_folder_get_path(msginfo->folder);
 
-               mbox_move_msg(folder, dest, msginfo);
+               mbox_copy_msg(folder, dest, msginfo);
        }
 
-       if (path) {
-               mbox_rewrite(path);
-               printf("fini\n");
-               mbox_cache_synchronize(path);
+       if (mbox_path) {
+               mbox_cache_synchronize(mbox_path);
+               g_free(mbox_path);
        }
-       mbox_cache_synchronize(dest->path);
+
+       mbox_path = mbox_folder_get_path(dest);
+       mbox_cache_synchronize(mbox_path);
+       g_free(mbox_path);
 
        return dest->last_num;
 }
+*/
 
-void mbox_scan_folder(Folder *folder, FolderItem *item)
+struct _copy_flags_info
 {
-       gchar *path;
-       struct stat s;
-       gint max = 0;
        gint num;
+       MsgFlags flags;
+};
+
+typedef struct _copy_flags_info CopyFlagsInfo;
+
+GSList * copy_flags_data = NULL;
+
+gint mbox_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
+{
+       Folder * src_folder;
+       gchar * filename;
+       gint num;
+       gchar * destdir;
+       gchar * mbox_path;
+       struct _message * msg;
+       CopyFlagsInfo * flags_info;
+
+       src_folder = msginfo->folder->folder;
+       
+       g_return_val_if_fail(src_folder->fetch_msg != NULL, -1);
+       
+       /*
+       mbox_path = mbox_folder_get_path(msginfo->folder);
+       mbox_rewrite(mbox_path);
+       g_free(mbox_path);
+       */
+
+       filename = src_folder->fetch_msg(src_folder,
+                                        msginfo->folder,
+                                        msginfo->msgnum);
+       if (filename == NULL)
+               return -1;
+
+       num = folder->add_msg(folder, dest, filename, FALSE);
+
+       /*
+       mbox_path = mbox_folder_get_path(dest);
+       msg = mbox_cache_get_msg(mbox_path, num);
+       if (msg != NULL)
+               msg->flags = msginfo->flags;
+       g_free(mbox_path);
+       */
+
+       flags_info = g_new0(CopyFlagsInfo, 1);
+       flags_info->num = num;
+       flags_info->flags = msginfo->flags;
+       copy_flags_data = g_slist_append(copy_flags_data, flags_info);
+
+       return num;
+}
+
+void mbox_finished_copy(Folder *folder, FolderItem *dest)
+{
+       gchar * mbox_path;
+       GSList * l;
+       mboxcache * cache;
+       
+       mbox_path = mbox_folder_get_path(dest);
+       if (mbox_path == NULL)
+               return;
+
+       mbox_cache_synchronize(mbox_path, TRUE);
+
+       for(l = copy_flags_data ; l != NULL ; l = g_slist_next(l)) {
+               CopyFlagsInfo * flags_info = l->data;
+               struct _message * msg;
+
+               msg = mbox_cache_get_msg(mbox_path, flags_info->num);
+               if (msg != NULL)
+                       msg->flags = flags_info->flags;
+               g_free(flags_info);
+       }
+
+       if (copy_flags_data != NULL) {
+               cache = mbox_cache_get_mbox(mbox_path);
+               cache->modification = TRUE;
+       }
+
+       g_slist_free(copy_flags_data);
+       copy_flags_data = NULL;
+
+       mbox_rewrite(mbox_path);
+
+       g_free(mbox_path);
+}
+
+void mbox_scan_folder(Folder *folder, FolderItem *item)
+{
+       gchar *mbox_path;
        gint n_msg;
        mboxcache * cached;
+       GList * l;
+
+       mbox_path = mbox_folder_get_path(item);
+       if (mbox_path == NULL)
+               return;
 
-       mbox_cache_synchronize(item->path);
+       mbox_cache_synchronize(mbox_path, TRUE);
 
-       cached = mbox_cache_get_mbox(item->path);
+       cached = mbox_cache_get_mbox(mbox_path);
 
        if (cached == NULL) {
                item->new = 0;
                item->unread = 0;
                item->total = 0;
                item->last_num = 0;
+               g_free(mbox_path);
                return;
        }
 
-       n_msg = mbox_cache_get_count(item->path);
+       n_msg = mbox_cache_get_count(mbox_path);
 
-       if (n_msg == 0)
+       if (n_msg == 0) {
                item->new = item->unread = item->total = 0;
+       }
        else {
-               gint new, unread, total;
-
-               //              procmsg_get_mark_sum(".", &new, &unread, &total);
-               if (n_msg > total) {
-                       new += n_msg - total;
-                       unread += n_msg - total;
+               gint new = 0;
+               gint unread = 0;
+               gint total = 0;
+
+               for(l = mbox_cache_get_msg_list(mbox_path) ; l != NULL ;
+                   l = g_list_next(l)) {
+                       struct _message * msg = (struct _message *) l->data;
+                       if (!MSG_IS_REALLY_DELETED(msg->flags))
+                               total ++;
+                       if (MSG_IS_NEW(msg->flags))
+                               new ++;
+                       if (MSG_IS_UNREAD(msg->flags))
+                               unread ++;
                }
+               
                item->new = new;
                item->unread = unread;
-               item->total = n_msg;
+               item->total = total;
        }
 
-       debug_print(_("Last number in dir %s = %d\n"), item->path,
+       debug_print(_("Last number in dir %s = %d\n"), mbox_path,
                    item->total);
-       item->last_num = item->total;
+       item->last_num = n_msg;
+       g_free(mbox_path);
 }
 
 gchar * mbox_get_virtual_path(FolderItem * item)
@@ -1333,12 +1740,13 @@ static gboolean mbox_write_data(FILE * mbox_fp, FILE * new_fp,
 
        pos = 0;
        while (pos < size) {
-               if ((size - pos) > sizeof(buf))
+               if ((size - pos) > (gint) sizeof(buf))
                        max = sizeof(buf);
                else
                        max = (size - pos);
                
                n_read = fread(buf, 1, max, mbox_fp);
+
                if (n_read < max && ferror(mbox_fp)) {
                        return FALSE;
                }
@@ -1357,18 +1765,19 @@ static gboolean mbox_write_data(FILE * mbox_fp, FILE * new_fp,
 }
 
 static gboolean mbox_write_message(FILE * mbox_fp, FILE * new_fp,
-                           gchar * new_filename,
-                           struct _message * msg)
+                                  gchar * new_filename,
+                                  struct _message * msg)
 {
-       GSList * headers;
-       GSList * cur;
        gint size;
+       GPtrArray * headers;
+       gint i;
        
        fseek(mbox_fp, msg->header, SEEK_SET);
-       headers = procheader_get_header_list(mbox_fp);
-       for(cur = headers ; cur != NULL ;
-           cur = g_slist_next(cur)) {
-               Header * h = (Header *) cur->data;
+
+       headers = procheader_get_header_array_asis(mbox_fp);
+
+       for (i = 0; i < (gint) headers->len; i++) {
+               Header * h = g_ptr_array_index(headers, i);
                
                if (!procheader_headername_equal(h->name, 
                                                 "Status") &&
@@ -1376,14 +1785,50 @@ static gboolean mbox_write_message(FILE * mbox_fp, FILE * new_fp,
                                                 "X-Status")) {
                        fwrite(h->name, strlen(h->name),
                               1, new_fp);
-                       fwrite(" ", 1, 1, new_fp);
+                       if (h->name[strlen(h->name) - 1] != ' ')
+                               fwrite(" ", 1, 1, new_fp);
                        fwrite(h->body, strlen(h->body),
                               1, new_fp);
-                       fwrite("\r\n", 2, 1, new_fp);
+                       fwrite("\n", 1, 1, new_fp);
                }
+               procheader_header_free(h);
+               g_ptr_array_remove_index(headers, i);
+               i--;
        }
-       fwrite("\r\n", 2, 1, new_fp);
-       
+
+       g_ptr_array_free(headers, FALSE);
+
+       if (msg->flags != -1) {
+               /* Status header */
+               fwrite("Status: ", strlen("Status: "), 1, new_fp);
+               if (!MSG_IS_UNREAD(msg->flags))
+                       fwrite("R", 1, 1, new_fp);
+               fwrite("O", 1, 1, new_fp);
+               fwrite("\n", 1, 1, new_fp);
+               
+               /* X-Status header */
+               if (msg->flags & 
+                   (MSG_REALLY_DELETED | MSG_MARKED | MSG_DELETED
+                    | MSG_REPLIED | MSG_FORWARDED)) {
+                       fwrite("X-Status: ", strlen("X-Status: "), 1, new_fp);
+                       if (MSG_IS_REALLY_DELETED(msg->flags))
+                               fwrite("D", 1, 1, new_fp); /* really deleted */
+                       else {
+                               if (MSG_IS_MARKED(msg->flags))
+                                       fwrite("F", 1, 1, new_fp);
+                               if (MSG_IS_DELETED(msg->flags))
+                                       fwrite("d", 1, 1, new_fp);
+                               if (MSG_IS_REPLIED(msg->flags))
+                                       fwrite("r", 1, 1, new_fp);
+                               if (MSG_IS_FORWARDED(msg->flags))
+                                       fwrite("f", 1, 1, new_fp);
+                       }
+                       fwrite("\n", 1, 1, new_fp);
+               }
+       }
+
+       fwrite("\n", 1, 1, new_fp);
+
        size = msg->end - msg->content;
        fseek(mbox_fp, msg->content, SEEK_SET);
 
@@ -1392,31 +1837,120 @@ static gboolean mbox_write_message(FILE * mbox_fp, FILE * new_fp,
 
 void mbox_update_mark(Folder * folder, FolderItem * item)
 {
-       GList * msg_list;
-       GList * l;
+       gchar * mbox_path;
 
-       /*      
-       msg_list = mbox_cache_get_msg_list(item->path);
-       
-       for(l = msg_list ; l != NULL ; l = g_list_next(l)) {
-               struct _message * msg = (struct _message *) l->data;
+       mbox_path = mbox_folder_get_path(item);
+       if (mbox_path == NULL)
+               return;
 
-               if (msg->msginfo != NULL) {
-                       msg->flags = msg->msginfo->flags &
-                               MSG_PERMANENT_FLAG_MASK;
-               }
-       }
-       */
+       mbox_rewrite(mbox_path);
+       g_free(mbox_path);
 }
 
 void mbox_change_flags(Folder * folder, FolderItem * item, MsgInfo * info)
 {
-       struct _message * msg = (struct _message *) info->data;
+       struct _message * msg;
+       mboxcache * cache;
+       gchar * mbox_path;
+
+       mbox_path = mbox_folder_get_path(item);
+       if (mbox_path == NULL)
+               return;
+
+       msg = mbox_cache_get_msg(mbox_path, info->msgnum);
+
+       cache = mbox_cache_get_mbox(mbox_path);
+
+       g_free(mbox_path);
+
+       if ((msg == NULL) || (cache == NULL))
+               return;
 
        msg->flags = info->flags;
+
+       cache->modification = TRUE;
 }
 
-gboolean mbox_rewrite(gchar * mbox)
+
+static gboolean mbox_rewrite(gchar * mbox)
+{
+       FILE * mbox_fp;
+       FILE * new_fp;
+       gchar * new;
+       GList * l;
+       gboolean result;
+       GList * msg_list;
+       gint count;
+       mboxcache * cache;
+
+       msg_list = mbox_cache_get_msg_list(mbox);
+
+       cache = mbox_cache_get_mbox(mbox);
+       if (cache == NULL)
+               return FALSE;
+
+       if (!cache->modification) {
+               debug_print(_("no modification - %s\n"), mbox);
+               return FALSE;
+       }
+
+       debug_print(_("save modification - %s\n"), mbox);
+
+       mbox_fp = fopen(mbox, "r+");
+       mbox_lockwrite_file(mbox_fp, mbox);
+
+       mbox_cache_synchronize_from_file(mbox_fp, mbox, TRUE);
+
+       new = g_strconcat(mbox, ".new", NULL);
+       new_fp = fopen(new, "w");
+
+       mbox_lockwrite_file(new_fp, new);
+
+       result = TRUE;
+
+       count = 0;
+       msg_list = mbox_cache_get_msg_list(mbox);
+       for(l = msg_list ; l != NULL ; l = g_list_next(l)) {
+               struct _message * msg = (struct _message *) l->data;
+               if (!mbox_write_message(mbox_fp, new_fp, new, msg)) {
+                       result = FALSE;
+                       break;
+               }
+               count ++;
+       }
+
+       unlink(mbox);
+
+       if (rename(new, mbox) == -1) {
+               g_warning(_("can't rename %s to %s\n"), new, mbox);
+               mbox_unlock_file(new_fp, new);
+               fclose(new_fp);
+               mbox_unlock_file(mbox_fp, mbox);
+               fclose(mbox_fp);
+               return -1;
+       }
+
+       mbox_unlock_file(new_fp, new);
+
+       fclose(new_fp);
+
+       mbox_unlock_file(mbox_fp, mbox);
+
+       fclose(mbox_fp);
+
+       debug_print(_("%i messages written - %s\n"), count, mbox);
+
+       cache = mbox_cache_get_mbox(mbox);
+
+       if (cache != NULL)
+               cache->mtime = -1;
+
+       mbox_cache_synchronize(mbox, FALSE);
+
+       return result;
+}
+
+static gboolean mbox_purge_deleted(gchar * mbox)
 {
        FILE * mbox_fp;
        FILE * new_fp;
@@ -1425,25 +1959,31 @@ gboolean mbox_rewrite(gchar * mbox)
        gboolean result;
        gboolean modification = FALSE;
        GList * msg_list;
+       gint count;
+
+       mbox_cache_synchronize(mbox, TRUE);
 
        msg_list = mbox_cache_get_msg_list(mbox);
 
        for(l = msg_list ; l != NULL ; l = g_list_next(l)) {
                struct _message * msg = (struct _message *) l->data;
-               if (msg->deleted) {
-                       printf("modification\n");
+               if (msg->flags != -1 && MSG_IS_REALLY_DELETED(msg->flags)) {
                        modification = TRUE;
                        break;
                }
        }
 
-       if (!modification)
+       if (!modification) {
+               debug_print(_("no deleted messages - %s\n"), mbox);
                return FALSE;
+       }
+
+       debug_print(_("purge deleted messages - %s\n"), mbox);
 
        mbox_fp = fopen(mbox, "r+");
        mbox_lockwrite_file(mbox_fp, mbox);
 
-       mbox_cache_synchronize_from_file(mbox_fp, mbox);
+       mbox_cache_synchronize_from_file(mbox_fp, mbox, TRUE);
 
        new = g_strconcat(mbox, ".new", NULL);
        new_fp = fopen(new, "w");
@@ -1452,20 +1992,22 @@ gboolean mbox_rewrite(gchar * mbox)
 
        result = TRUE;
 
+       count = 0;
        msg_list = mbox_cache_get_msg_list(mbox);
        for(l = msg_list ; l != NULL ; l = g_list_next(l)) {
                struct _message * msg = (struct _message *) l->data;
-               if (!msg->deleted)
+               if (msg->flags == -1 || !MSG_IS_REALLY_DELETED(msg->flags)) {
                        if (!mbox_write_message(mbox_fp, new_fp, new, msg)) {
                                result = FALSE;
                                break;
                        }
+                       count ++;
+               }
        }
 
        unlink(mbox);
 
-       g_warning(_("can't rename %s to %s\n"), new, mbox);
-       if (rename(new_fp, mbox) == -1) {
+       if (rename(new, mbox) == -1) {
                g_warning(_("can't rename %s to %s\n"), new, mbox);
                mbox_unlock_file(new_fp, new);
                fclose(new_fp);
@@ -1481,5 +2023,162 @@ gboolean mbox_rewrite(gchar * mbox)
        mbox_unlock_file(mbox_fp, mbox);
 
        fclose(mbox_fp);
+
+       debug_print(_("%i messages written - %s\n"), count, mbox);
+
+       mbox_cache_synchronize(mbox, FALSE);
+
        return result;
 }
+
+#define MAKE_DIR_IF_NOT_EXIST(dir) \
+{ \
+       if (!is_dir_exist(dir)) { \
+               if (is_file_exist(dir)) { \
+                       g_warning(_("File `%s' already exists.\n" \
+                                   "Can't create folder."), dir); \
+                       return -1; \
+               } \
+               if (mkdir(dir, S_IRWXU) < 0) { \
+                       FILE_OP_ERROR(dir, "mkdir"); \
+                       return -1; \
+               } \
+               if (chmod(dir, S_IRWXU) < 0) \
+                       FILE_OP_ERROR(dir, "chmod"); \
+       } \
+}
+
+gint mbox_create_tree(Folder *folder)
+{
+       gchar *rootpath;
+
+       g_return_val_if_fail(folder != NULL, -1);
+
+       CHDIR_RETURN_VAL_IF_FAIL(get_home_dir(), -1);
+       rootpath = LOCAL_FOLDER(folder)->rootpath;
+       MAKE_DIR_IF_NOT_EXIST(rootpath);
+       CHDIR_RETURN_VAL_IF_FAIL(rootpath, -1);
+
+       return 0;
+}
+
+#undef MAKE_DIR_IF_NOT_EXIST
+
+static gchar * mbox_get_new_path(FolderItem * parent, gchar * name)
+{
+       gchar * path;
+
+       if (strchr(name, '/') == NULL) {
+               if (parent->path != NULL)
+                       path = g_strconcat(parent->path, ".sbd", G_DIR_SEPARATOR_S, name, NULL);
+               else
+                       path = g_strdup(name);
+       }
+       else
+               path = g_strdup(name);
+
+       return path;
+}
+
+static gchar * mbox_get_folderitem_name(gchar * name)
+{
+       gchar * foldername;
+       gchar * p;
+
+       if ((p = strchr(name, '/')) == NULL)
+               foldername = g_strdup(name);
+       else {
+               gchar * newp = p;
+
+               while (newp != NULL) {
+                       newp = strchr(p, '/');
+                       if (newp != NULL)
+                               p = newp + 1;
+               }
+
+               foldername = g_strdup(p);
+       }
+       return foldername;
+}
+
+FolderItem *mbox_create_folder(Folder *folder, FolderItem *parent,
+                              const gchar *name)
+{
+       gchar * path;
+       FolderItem *new_item;
+       gchar * foldername;
+
+       g_return_val_if_fail(folder != NULL, NULL);
+       g_return_val_if_fail(parent != NULL, NULL);
+       g_return_val_if_fail(name != NULL, NULL);
+
+       path = mbox_get_new_path(parent, (gchar *) name);
+
+       foldername = mbox_get_folderitem_name((gchar *) name);
+
+       new_item = folder_item_new(foldername, path);
+       folder_item_append(parent, new_item);
+
+       if (!strcmp(name, "inbox")) {
+               new_item->stype = F_INBOX;
+               new_item->folder->inbox = new_item;
+       } else if (!strcmp(name, "outbox")) {
+               new_item->stype = F_OUTBOX;
+               new_item->folder->outbox = new_item;
+       } else if (!strcmp(name, "draft")) {
+               new_item->stype = F_DRAFT;
+               new_item->folder->draft = new_item;
+       } else if (!strcmp(name, "queue")) {
+               new_item->stype = F_QUEUE;
+               new_item->folder->queue = new_item;
+       } else if (!strcmp(name, "trash")) {
+               new_item->stype = F_TRASH;
+               new_item->folder->trash = new_item;
+       }
+       
+       g_free(foldername);
+       g_free(path);
+       
+       return new_item;
+}
+
+gint mbox_rename_folder(Folder *folder, FolderItem *item, const gchar *name)
+{
+       gchar * path;
+       gchar * foldername;
+
+       g_return_val_if_fail(folder != NULL, -1);
+       g_return_val_if_fail(item != NULL, -1);
+       g_return_val_if_fail(item->path != NULL, -1);
+       g_return_val_if_fail(name != NULL, -1);
+
+       path = mbox_get_new_path(item->parent, (gchar *) name);
+       foldername = mbox_get_folderitem_name((gchar *) name);
+
+       if (rename(item->path, path) == -1) {
+               g_free(foldername);
+               g_free(path);
+               g_warning(_("Cannot rename folder item"));
+
+               return -1;
+       }
+       else {
+               g_free(item->name);
+               g_free(item->path);
+               item->path = path;
+               item->name = foldername;
+               
+               return 0;
+       }
+}
+
+gint mbox_remove_folder(Folder *folder, FolderItem *item)
+{
+       g_return_val_if_fail(folder != NULL, -1);
+       g_return_val_if_fail(item != NULL, -1);
+       g_return_val_if_fail(item->path != NULL, -1);
+
+       folder_item_remove(item);
+       return 0;
+}
+
index 38c5027..bc513bd 100644 (file)
@@ -27,5 +27,15 @@ void mbox_update_mark(Folder * folder, FolderItem * item);
 gint mbox_move_msgs_with_dest(Folder *folder, FolderItem *dest,
                              GSList *msglist);
 gint mbox_move_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo);
+void mbox_change_flags(Folder * folder, FolderItem * item, MsgInfo * info);
+gint mbox_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo);
+gint mbox_copy_msgs_with_dest(Folder *folder, FolderItem *dest, GSList *msglist);
+gint mbox_create_tree(Folder *folder);
+FolderItem *mbox_create_folder(Folder *folder, FolderItem *parent,
+                              const gchar *name);
+gint mbox_rename_folder(Folder *folder, FolderItem *item, const gchar *name);
+gint mbox_remove_folder(Folder *folder, FolderItem *item);
+void mbox_finished_copy(Folder *folder, FolderItem *dest);
+
 
 #endif
index deac165..5cae5f3 100644 (file)
--- a/src/mh.c
+++ b/src/mh.c
@@ -122,6 +122,7 @@ gchar *mh_fetch_msg(Folder *folder, FolderItem *item, gint num)
        path = folder_item_get_path(item);
        file = g_strconcat(path, G_DIR_SEPARATOR_S, itos(num), NULL);
        g_free(path);
+
        if (!is_file_exist(file)) {
                g_free(file);
                return NULL;
@@ -177,6 +178,7 @@ gint mh_add_msg(Folder *folder, FolderItem *dest, const gchar *file,
        return dest->last_num;
 }
 
+/*
 gint mh_move_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
 {
        gchar *destdir;
@@ -260,7 +262,32 @@ gint mh_move_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
 
        return dest->last_num;
 }
+*/
+
+/*
+gint mh_move_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
+{
+       Folder * src_folder;
+       gchar * filename;
+       gint num;
+       gchar * destdir;
+       
+       src_folder = msginfo->folder->folder;
+
+       g_return_val_if_fail(src_folder->remove_msg != NULL, -1);       
+
+       num = folder->copy_msg(folder, item, msginfo);
+               
+       if (num != -1)
+               src_folder->remove_msg(src_folder,
+                                      msginfo->folder,
+                                      msginfo->msgnum);
+
+       return num;
+}
+*/
 
+/*
 gint mh_move_msgs_with_dest(Folder *folder, FolderItem *dest, GSList *msglist)
 {
        gchar *destdir;
@@ -348,7 +375,9 @@ gint mh_move_msgs_with_dest(Folder *folder, FolderItem *dest, GSList *msglist)
 
        return dest->last_num;
 }
+*/
 
+/*
 gint mh_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
 {
        gchar *destdir;
@@ -421,7 +450,52 @@ gint mh_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
 
        return dest->last_num;
 }
+*/
+
+gint mh_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
+{
+       Folder * src_folder;
+       gchar * filename;
+       gint num;
+       gchar * destdir;
+       FILE * fp;
+
+       src_folder = msginfo->folder->folder;
+       
+       g_return_val_if_fail(src_folder->fetch_msg != NULL, -1);
+       
+       filename = src_folder->fetch_msg(src_folder,
+                                        msginfo->folder,
+                                        msginfo->msgnum);
+       if (filename == NULL)
+               return -1;
+
+       num = folder->add_msg(folder, dest, filename, FALSE);
 
+       destdir = folder_item_get_path(dest);
+       if ((fp = procmsg_open_mark_file(destdir, TRUE)) == NULL)
+               g_warning(_("Can't open mark file.\n"));
+
+       if (fp) {
+               MsgInfo newmsginfo;
+
+               newmsginfo.msgnum = dest->last_num;
+               newmsginfo.flags = msginfo->flags;
+               if (dest->stype == F_OUTBOX ||
+                   dest->stype == F_QUEUE  ||
+                   dest->stype == F_DRAFT  ||
+                   dest->stype == F_TRASH)
+                       MSG_UNSET_FLAGS(newmsginfo.flags,
+                                       MSG_NEW|MSG_UNREAD|MSG_DELETED);
+
+               procmsg_write_flags(&newmsginfo, fp);
+               fclose(fp);
+       }
+       
+       return num;
+}
+
+/*
 gint mh_copy_msgs_with_dest(Folder *folder, FolderItem *dest, GSList *msglist)
 {
        gchar *destdir;
@@ -499,6 +573,7 @@ gint mh_copy_msgs_with_dest(Folder *folder, FolderItem *dest, GSList *msglist)
 
        return dest->last_num;
 }
+*/
 
 gint mh_remove_msg(Folder *folder, FolderItem *item, gint num)
 {
index fa2921c..a4f542c 100644 (file)
@@ -370,7 +370,6 @@ static void prefs_filtering_create(void)
        for (accounts = account_get_list() ; accounts != NULL;
             accounts = accounts->next) {
                PrefsAccount *ac = (PrefsAccount *)accounts->data;
-               GtkWidget *menuitem;
                gchar *name;
 
                name = g_strdup_printf("%s <%s> (%s)",
@@ -650,7 +649,7 @@ static FilteringProp * prefs_filtering_dialog_to_filtering(void)
        cond_str = gtk_entry_get_text(GTK_ENTRY(filtering.cond_entry));
        if (*cond_str == '\0') {
                alertpanel_error(_("Score is not set."));
-               return;
+               return NULL;
        }
 
        action_id = get_sel_from_list(GTK_LIST(filtering.action_list));
@@ -666,7 +665,7 @@ static FilteringProp * prefs_filtering_dialog_to_filtering(void)
                destination = gtk_entry_get_text(GTK_ENTRY(filtering.dest_entry));
                if (*destination == '\0') {
                        alertpanel_error(_("Destination is not set."));
-                       return;
+                       return NULL;
                }
                break;
        default:
@@ -682,7 +681,7 @@ static FilteringProp * prefs_filtering_dialog_to_filtering(void)
        if (tmp == NULL) {
                alertpanel_error(_("Match string is not valid."));
                filteringaction_free(action);
-               return;
+               return NULL;
        }
 
        prop = filteringprop_new(cond, action);
index 561adad..b4f26d5 100644 (file)
@@ -56,8 +56,9 @@ gint procheader_get_one_field(gchar *buf, gint len, FILE *fp,
                        for (hp = hentry, hnum = 0; hp->name != NULL;
                             hp++, hnum++) {
                                if (!strncasecmp(hp->name, buf,
-                                                strlen(hp->name)))
+                                                strlen(hp->name))) {
                                        break;
+                               }
                        }
                } while (hp->name == NULL);
        } else {
@@ -430,8 +431,8 @@ enum
        H_SEEN          = 10,
        H_STATUS        = 11,
        H_X_STATUS      = 12,
-       H_X_FACE        = 13,
-       H_FROM_SPACE    = 14,
+       H_FROM_SPACE    = 13,
+       H_X_FACE        = 14,
        H_DISPOSITION_NOTIFICATION_TO = 15,
        H_RETURN_RECEIPT_TO = 16
 };
@@ -469,8 +470,8 @@ MsgInfo *procheader_file_parse(FILE * fp, MsgFlags flags,
                                           {"Seen:",            NULL, FALSE},
                                           {"Status:",          NULL, FALSE},
                                           {"X-Status:",        NULL, FALSE},
-                                          {"X-Face:",          NULL, FALSE},
                                           {"From ",            NULL, FALSE},
+                                          {"X-Face:",          NULL, FALSE},
                                           {"Disposition-Notification-To:", NULL, FALSE},
                                           {"Return-Receipt-To:", NULL, FALSE},
                                           {NULL,               NULL, FALSE}};
@@ -621,8 +622,17 @@ MsgInfo *procheader_file_parse(FILE * fp, MsgFlags flags,
                                MSG_SET_FLAGS(msginfo->flags, MSG_UNREAD);
                        break;
                case H_X_STATUS:
-                       if (strchr(hp, 'X') != NULL)
+                       if (strchr(hp, 'D') != NULL)
+                               MSG_SET_FLAGS(msginfo->flags,
+                                             MSG_REALLY_DELETED);
+                       if (strchr(hp, 'F') != NULL)
                                MSG_SET_FLAGS(msginfo->flags, MSG_MARKED);
+                       if (strchr(hp, 'd') != NULL)
+                               MSG_SET_FLAGS(msginfo->flags, MSG_DELETED);
+                       if (strchr(hp, 'r') != NULL)
+                               MSG_SET_FLAGS(msginfo->flags, MSG_REPLIED);
+                       if (strchr(hp, 'f') != NULL)
+                               MSG_SET_FLAGS(msginfo->flags, MSG_FORWARDED);
                        break;
                case H_FROM_SPACE:
                        if (msginfo->fromspace) break;
index d0d44de..991adc1 100644 (file)
@@ -773,6 +773,7 @@ void procmsg_msginfo_free(MsgInfo *msginfo)
 {
        if (msginfo == NULL) return;
 
+       g_free(msginfo->fromspace);
        g_free(msginfo->references);
        g_free(msginfo->returnreceiptto);
        g_free(msginfo->dispositionnotificationto);
index b7ed120..1430786 100644 (file)
@@ -39,6 +39,7 @@ typedef enum
        MSG_DELETED     = 1 << 3,
        MSG_REPLIED     = 1 << 4,
        MSG_FORWARDED   = 1 << 5,
+       MSG_REALLY_DELETED = 1 << 6,
 
        /* temporary flags (0xffff0000) */
        MSG_MOVE        = 1 << 16,
@@ -58,7 +59,8 @@ typedef enum
                                         MSG_MARKED    | \
                                         MSG_DELETED   | \
                                         MSG_REPLIED   | \
-                                        MSG_FORWARDED)
+                                        MSG_FORWARDED | \
+                                         MSG_REALLY_DELETED)
 #define MSG_CACHED_FLAG_MASK           (MSG_MIME)
 
 #define MSG_SET_FLAGS(msg, flags)      { (msg) |= (flags); }
@@ -72,6 +74,7 @@ typedef enum
 
 #define MSG_IS_MOVE(msg)               ((msg & MSG_MOVE) != 0)
 #define MSG_IS_COPY(msg)               ((msg & MSG_COPY) != 0)
+#define MSG_IS_REALLY_DELETED(msg)     ((msg & MSG_REALLY_DELETED) != 0)
 
 #define MSG_IS_QUEUED(msg)             ((msg & MSG_QUEUED) != 0)
 #define MSG_IS_DRAFT(msg)              ((msg & MSG_DRAFT) != 0)
@@ -134,8 +137,6 @@ struct _MsgInfo
        /* used only for encrypted messages */
        gchar *plaintext_file;
        guint decryption_failed : 1;
-
-       void * data;
 };
 
 GHashTable *procmsg_msg_hash_table_create      (GSList         *mlist);
index 5b520d8..69d2ecd 100644 (file)
@@ -1644,6 +1644,14 @@ static void summary_set_header(gchar *text[], MsgInfo *msginfo)
                _("(No Subject)");
 }
 
+#define CHANGE_FLAGS(msginfo) \
+{ \
+if (msginfo->folder->folder->change_flags != NULL) \
+msginfo->folder->folder->change_flags(msginfo->folder->folder, \
+                                     msginfo->folder, \
+                                     msginfo); \
+}
+
 static void summary_display_msg(SummaryView *summaryview, GtkCTreeNode *row,
                                gboolean new_window)
 {
@@ -1697,6 +1705,9 @@ static void summary_display_msg(SummaryView *summaryview, GtkCTreeNode *row,
                summaryview->unread--;
        if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) {
                MSG_UNSET_FLAGS(msginfo->flags, MSG_NEW | MSG_UNREAD);
+
+               CHANGE_FLAGS(msginfo);
+               
                summary_set_row_marks(summaryview, row);
                gtk_clist_thaw(GTK_CLIST(ctree));
                summary_status_show(summaryview);
@@ -1888,6 +1899,9 @@ static void summary_mark_row(SummaryView *summaryview, GtkCTreeNode *row)
                summaryview->copied--;
        MSG_UNSET_FLAGS(msginfo->flags, MSG_DELETED | MSG_MOVE | MSG_COPY);
        MSG_SET_FLAGS(msginfo->flags, MSG_MARKED);
+
+       CHANGE_FLAGS(msginfo);
+
        summary_set_row_marks(summaryview, row);
        debug_print(_("Message %d is marked\n"), msginfo->msgnum);
 }
@@ -1918,6 +1932,9 @@ static void summary_mark_row_as_read(SummaryView *summaryview,
        if (MSG_IS_NEW(msginfo->flags) ||
            MSG_IS_UNREAD(msginfo->flags)) {
                MSG_UNSET_FLAGS(msginfo->flags, MSG_NEW | MSG_UNREAD);
+
+               CHANGE_FLAGS(msginfo);
+               
                summary_set_row_marks(summaryview, row);
                debug_print(_("Message %d is marked as being read\n"),
                            msginfo->msgnum);
@@ -1951,12 +1968,16 @@ static void summary_mark_row_as_unread(SummaryView *summaryview,
        MSG_UNSET_FLAGS(msginfo->flags, MSG_REPLIED | MSG_FORWARDED);
        if (!MSG_IS_UNREAD(msginfo->flags)) {
                MSG_SET_FLAGS(msginfo->flags, MSG_UNREAD);
+
                gtk_ctree_node_set_pixmap(ctree, row, S_COL_UNREAD,
                                          unreadxpm, unreadxpmmask);
                summaryview->unread++;
                debug_print(_("Message %d is marked as unread\n"),
                            msginfo->msgnum);
        }
+
+       CHANGE_FLAGS(msginfo);
+
        summary_set_row_marks(summaryview, row);
 }
 
@@ -1991,6 +2012,9 @@ static void summary_delete_row(SummaryView *summaryview, GtkCTreeNode *row)
                        MSG_MOVE |
                        MSG_COPY);
        MSG_SET_FLAGS(msginfo->flags, MSG_DELETED);
+
+       CHANGE_FLAGS(msginfo);
+
        summaryview->deleted++;
 
        if (!prefs_common.immediate_exec)
@@ -2082,6 +2106,9 @@ static void summary_unmark_row(SummaryView *summaryview, GtkCTreeNode *row)
                        MSG_DELETED |
                        MSG_MOVE |
                        MSG_COPY);
+
+       CHANGE_FLAGS(msginfo);
+
        summary_set_row_marks(summaryview, row);
 
        debug_print(_("Message %s/%d is unmarked\n"),
@@ -2118,6 +2145,7 @@ static void summary_move_row_to(SummaryView *summaryview, GtkCTreeNode *row,
                MSG_SET_FLAGS(msginfo->flags, MSG_MOVE);
                summaryview->moved++;
        }
+
        if (!prefs_common.immediate_exec)
                summary_set_row_marks(summaryview, row);
 
@@ -2179,6 +2207,7 @@ static void summary_copy_row_to(SummaryView *summaryview, GtkCTreeNode *row,
                MSG_SET_FLAGS(msginfo->flags, MSG_COPY);
                summaryview->copied++;
        }
+
        if (!prefs_common.immediate_exec)
                summary_set_row_marks(summaryview, row);
 
@@ -2314,7 +2343,8 @@ void summary_execute(SummaryView *summaryview)
 
        gtk_clist_freeze(clist);
 
-       if (prefs_common.enable_thread)
+       if (summaryview->folder_item->prefs->enable_thread)
+               /*      if (prefs_common.enable_thread) */
                summary_unthread_for_exec(summaryview);
 
        summary_execute_move(summaryview);
@@ -2337,7 +2367,8 @@ void summary_execute(SummaryView *summaryview)
                node = next;
        }
 
-       if (prefs_common.enable_thread)
+       if (summaryview->folder_item->prefs->enable_thread)
+               /*      if (prefs_common.enable_thread) */
                summary_thread_build(summaryview);
 
        summaryview->selected = clist->selection ?
@@ -2451,6 +2482,7 @@ static void summary_execute_copy_func(GtkCTree *ctree, GtkCTreeNode *node,
                        g_slist_append(summaryview->mlist, msginfo);
 
                MSG_UNSET_FLAGS(msginfo->flags, MSG_COPY);
+               
                summary_set_row_marks(summaryview, node);
        }
 }
@@ -2927,6 +2959,9 @@ static void summary_selected(GtkCTree *ctree, GtkCTreeNode *row,
        case S_COL_MARK:
                if (MSG_IS_MARKED(msginfo->flags)) {
                        MSG_UNSET_FLAGS(msginfo->flags, MSG_MARKED);
+
+                       CHANGE_FLAGS(msginfo);
+                       
                        summary_set_row_marks(summaryview, row);
                } else
                        summary_mark_row(summaryview, row);
index fa44ba9..80b2508 100644 (file)
@@ -974,7 +974,7 @@ static GPtrArray *textview_scan_header(TextView *textview, FILE *fp)
                }
        }
 
-       g_ptr_array_free(headers, TRUE);
+       g_ptr_array_free(headers, FALSE);
 
        return sorted_headers;
 }
@@ -995,7 +995,9 @@ static void textview_show_header(TextView *textview, GPtrArray *headers)
 
                gtk_text_insert(text, textview->boldfont, NULL, NULL,
                                header->name, -1);
-               gtk_text_insert(text, textview->boldfont, NULL, NULL, " ", 1);
+               if (header->name[strlen(header->name) - 1] != ' ')
+                       gtk_text_insert(text, textview->boldfont,
+                                       NULL, NULL, " ", 1);
 
                if (procheader_headername_equal(header->name, "Subject") ||
                    procheader_headername_equal(header->name, "From")    ||