diff options
author | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2005-07-01 10:42:15 +0000 |
---|---|---|
committer | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2005-07-01 10:42:15 +0000 |
commit | 0ada6c15f7eef4e46d8f1b8964dad1193692a10a (patch) | |
tree | e767d7b49be640a123d3bf49ae751fa2af7ba441 /src | |
parent | 0839e124a6910f5d134ec3b229466cd470b0c7ea (diff) |
implemented folder move.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@389 ee746299-78ed-0310-b773-934348b2243d
Diffstat (limited to 'src')
-rw-r--r-- | src/folder.c | 8 | ||||
-rw-r--r-- | src/folder.h | 3 | ||||
-rw-r--r-- | src/foldersel.c | 32 | ||||
-rw-r--r-- | src/foldersel.h | 5 | ||||
-rw-r--r-- | src/folderview.c | 112 | ||||
-rw-r--r-- | src/folderview.h | 1 | ||||
-rw-r--r-- | src/imap.c | 1 | ||||
-rw-r--r-- | src/mainwindow.c | 25 | ||||
-rw-r--r-- | src/mh.c | 82 | ||||
-rw-r--r-- | src/news.c | 1 |
10 files changed, 238 insertions, 32 deletions
diff --git a/src/folder.c b/src/folder.c index 00c43c6a..c4645fe3 100644 --- a/src/folder.c +++ b/src/folder.c @@ -659,7 +659,13 @@ gchar *folder_item_get_identifier(FolderItem *item) gchar *folder_id; g_return_val_if_fail(item != NULL, NULL); - g_return_val_if_fail(item->path != NULL, NULL); + + if (!item->path) { + if (!item->parent) + return folder_get_identifier(item->folder); + else + return NULL; + } folder_id = folder_get_identifier(item->folder); id = g_strconcat(folder_id, "/", item->path, NULL); diff --git a/src/folder.h b/src/folder.h index 0d241a13..0908e241 100644 --- a/src/folder.h +++ b/src/folder.h @@ -200,6 +200,9 @@ struct _FolderClass gint (*rename_folder) (Folder *folder, FolderItem *item, const gchar *name); + gint (*move_folder) (Folder *folder, + FolderItem *item, + FolderItem *new_parent); gint (*remove_folder) (Folder *folder, FolderItem *item); }; diff --git a/src/foldersel.c b/src/foldersel.c index 89f43cf1..0f93bb58 100644 --- a/src/foldersel.c +++ b/src/foldersel.c @@ -84,10 +84,12 @@ static GtkWidget *ok_button; static GtkWidget *cancel_button; static GtkWidget *new_button; +static GtkTreeStore *tree_store; + static FolderItem *folder_item; static FolderItem *selected_item; -static GtkTreeStore *tree_store; +FolderSelectionType sel_type; static gboolean cancelled; static gboolean finished; @@ -100,8 +102,7 @@ static void foldersel_append_item (GtkTreeStore *store, GtkTreeIter *iter, GtkTreeIter *parent); -static void foldersel_set_tree (Folder *cur_folder, - FolderSelectionType type); +static void foldersel_set_tree (Folder *cur_folder); static gboolean foldersel_selected (GtkTreeSelection *selection, GtkTreeModel *model, @@ -145,13 +146,14 @@ FolderItem *foldersel_folder_sel(Folder *cur_folder, FolderSelectionType type, const gchar *default_folder) { selected_item = NULL; + sel_type = type; if (!window) { foldersel_create(); foldersel_init(); } - foldersel_set_tree(cur_folder, type); + foldersel_set_tree(cur_folder); /* select current */ if (folder_item) { @@ -199,12 +201,16 @@ FolderItem *foldersel_folder_sel(Folder *cur_folder, FolderSelectionType type, gtk_entry_set_text(GTK_ENTRY(entry), ""); gtk_tree_store_clear(tree_store); - if (!cancelled && - selected_item && selected_item->path && !selected_item->no_select) { + if (cancelled || !selected_item) + return NULL; + + if (type == FOLDER_SEL_MOVE_FOLDER || + (selected_item->path && !selected_item->no_select)) { folder_item = selected_item; return folder_item; - } else - return NULL; + } + + return NULL; } static void foldersel_create(void) @@ -410,7 +416,7 @@ static void foldersel_insert_gnode_in_store(GtkTreeStore *store, GNode *node, foldersel_insert_gnode_in_store(store, iter, &child); } -static void foldersel_set_tree(Folder *cur_folder, FolderSelectionType type) +static void foldersel_set_tree(Folder *cur_folder) { Folder *folder; GList *list; @@ -419,10 +425,12 @@ static void foldersel_set_tree(Folder *cur_folder, FolderSelectionType type) folder = FOLDER(list->data); g_return_if_fail(folder != NULL); - if (type != FOLDER_SEL_ALL) { + if (sel_type != FOLDER_SEL_ALL) { if (FOLDER_TYPE(folder) == F_NEWS) continue; } + if (sel_type == FOLDER_SEL_MOVE_FOLDER && folder != cur_folder) + continue; foldersel_insert_gnode_in_store(tree_store, folder->node, NULL); } @@ -451,7 +459,9 @@ static gboolean foldersel_selected(GtkTreeSelection *selection, FOLDERSEL_FOLDERITEM, &item, -1); selected_item = item; - if (selected_item && selected_item->path && !selected_item->no_select) { + if (selected_item && + (sel_type == FOLDER_SEL_MOVE_FOLDER || + (selected_item->path && !selected_item->no_select))) { gchar *id; id = folder_item_get_identifier(selected_item); gtk_entry_set_text(GTK_ENTRY(entry), id); diff --git a/src/foldersel.h b/src/foldersel.h index 802bb50e..e1b065b2 100644 --- a/src/foldersel.h +++ b/src/foldersel.h @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 1999-2002 Hiroyuki Yamamoto + * Copyright (C) 1999-2005 Hiroyuki Yamamoto * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,7 +29,8 @@ typedef enum { FOLDER_SEL_ALL, FOLDER_SEL_MOVE, - FOLDER_SEL_COPY + FOLDER_SEL_COPY, + FOLDER_SEL_MOVE_FOLDER } FolderSelectionType; FolderItem *foldersel_folder_sel(Folder *cur_folder, diff --git a/src/folderview.c b/src/folderview.c index 27020fae..2cbd85e2 100644 --- a/src/folderview.c +++ b/src/folderview.c @@ -48,6 +48,7 @@ #include "summary_search.h" #include "inputdialog.h" #include "grouplistdialog.h" +#include "foldersel.h" #include "manage_window.h" #include "alertpanel.h" #include "menu.h" @@ -165,6 +166,9 @@ static void folderview_new_folder_cb (FolderView *folderview, static void folderview_rename_folder_cb (FolderView *folderview, guint action, GtkWidget *widget); +static void folderview_move_folder_cb (FolderView *folderview, + guint action, + GtkWidget *widget); static void folderview_delete_folder_cb (FolderView *folderview, guint action, GtkWidget *widget); @@ -223,8 +227,9 @@ GtkTargetEntry folderview_drag_types[] = static GtkItemFactoryEntry folderview_mail_popup_entries[] = { - {N_("/Create _new folder..."), NULL, folderview_new_folder_cb, 0, NULL}, + {N_("/Create _new folder..."), NULL, folderview_new_folder_cb, 0, NULL}, {N_("/_Rename folder..."), NULL, folderview_rename_folder_cb, 0, NULL}, + {N_("/_Move folder..."), NULL, folderview_move_folder_cb, 0, NULL}, {N_("/_Delete folder"), NULL, folderview_delete_folder_cb, 0, NULL}, {N_("/---"), NULL, NULL, 0, "<Separator>"}, {N_("/Empty _trash"), NULL, folderview_empty_trash_cb, 0, NULL}, @@ -1252,32 +1257,37 @@ void folderview_update_all_updated(gboolean update_summary) } } -static void folderview_insert_item_recursive(FolderView *folderview, - FolderItem *item) +static gboolean folderview_insert_item_recursive(FolderView *folderview, + FolderItem *item, + GtkTreeIter *iter) { GNode *node; - GtkTreeIter iter; + GtkTreeIter iter_; gboolean valid; - g_return_if_fail(item != NULL); + g_return_val_if_fail(item != NULL, FALSE); - valid = folderview_append_item(folderview, &iter, item, FALSE); - g_return_if_fail(valid == TRUE); + valid = folderview_append_item(folderview, &iter_, item, FALSE); + g_return_val_if_fail(valid == TRUE, FALSE); for (node = item->node->children; node != NULL; node = node->next) { FolderItem *child_item = FOLDER_ITEM(node->data); - folderview_insert_item_recursive(folderview, child_item); + folderview_insert_item_recursive(folderview, child_item, NULL); } if (item->node->children && !item->collapsed) { GtkTreePath *path; path = gtk_tree_model_get_path - (GTK_TREE_MODEL(folderview->store), &iter); + (GTK_TREE_MODEL(folderview->store), &iter_); gtk_tree_view_expand_row(GTK_TREE_VIEW(folderview->treeview), path, FALSE); gtk_tree_path_free(path); } + + if (iter) + *iter = iter_; + return TRUE; } static void folderview_append_folder(FolderView *folderview, Folder *folder) @@ -1285,7 +1295,7 @@ static void folderview_append_folder(FolderView *folderview, Folder *folder) g_return_if_fail(folder != NULL); folderview_insert_item_recursive - (folderview, FOLDER_ITEM(folder->node->data)); + (folderview, FOLDER_ITEM(folder->node->data), NULL); } void folderview_new_folder(FolderView *folderview) @@ -1321,6 +1331,23 @@ void folderview_rename_folder(FolderView *folderview) folderview_rename_folder_cb(folderview, 0, NULL); } +void folderview_move_folder(FolderView *folderview) +{ + FolderItem *item; + + item = folderview_get_selected_item(folderview); + if (!item) + return; + + g_return_if_fail(item->folder != NULL); + + if (!item->path) return; + if (item->stype != F_NORMAL) return; + + if (item->folder->klass->move_folder) + folderview_move_folder_cb(folderview, 0, NULL); +} + void folderview_delete_folder(FolderView *folderview) { FolderItem *item; @@ -1406,6 +1433,7 @@ static gboolean folderview_menu_popup(FolderView *folderview, GtkTreeIter iter; gboolean new_folder = FALSE; gboolean rename_folder = FALSE; + gboolean move_folder = FALSE; gboolean delete_folder = FALSE; gboolean empty_trash = FALSE; gboolean download_msg = FALSE; @@ -1444,9 +1472,11 @@ static gboolean folderview_menu_popup(FolderView *folderview, if (FOLDER_IS_LOCAL(folder) || FOLDER_TYPE(folder) == F_IMAP) { if (item->parent == NULL) update_tree = rescan_tree = TRUE; - else if (item->stype == F_NORMAL) + else if (item->stype == F_NORMAL) { rename_folder = delete_folder = TRUE; - else if (item->stype == F_TRASH) + if (folder->klass->move_folder) + move_folder = TRUE; + } else if (item->stype == F_TRASH) empty_trash = TRUE; } else if (FOLDER_TYPE(folder) == F_NEWS) { if (item->parent != NULL) @@ -1467,6 +1497,7 @@ static gboolean folderview_menu_popup(FolderView *folderview, menu_set_insensitive_all(GTK_MENU_SHELL(popup)); SET_SENS(mail_factory, "/Create new folder...", new_folder); SET_SENS(mail_factory, "/Rename folder...", rename_folder); + SET_SENS(mail_factory, "/Move folder...", move_folder); SET_SENS(mail_factory, "/Delete folder", delete_folder); SET_SENS(mail_factory, "/Empty trash", empty_trash); SET_SENS(mail_factory, "/Check for new messages", update_tree); @@ -1994,6 +2025,63 @@ static void folderview_rename_folder_cb(FolderView *folderview, guint action, folder_write_list(); } +static void folderview_move_folder_cb(FolderView *folderview, guint action, + GtkWidget *widget) +{ + FolderItem *item; + FolderItem *new_parent; + GtkTreePath *sel_path; + GtkTreePath *open_path; + GtkTreeIter iter; + + item = folderview_get_selected_item(folderview); + if (!item) + return; + + g_return_if_fail(item->path != NULL); + g_return_if_fail(item->folder != NULL); + + new_parent = foldersel_folder_sel(item->folder, FOLDER_SEL_MOVE_FOLDER, + NULL); + if (!new_parent) + return; + if (new_parent->folder != item->folder) + return; + if (new_parent == item->parent) + return; + + if (item->folder->klass->move_folder + (item->folder, item, new_parent) < 0) { + alertpanel_error(_("Can't move the folder `%s'."), item->name); + return; + } + + /* rename filter paths */ + + sel_path = gtk_tree_row_reference_get_path(folderview->selected); + open_path = gtk_tree_row_reference_get_path(folderview->opened); + g_return_if_fail(sel_path != NULL); + gtk_tree_model_get_iter(GTK_TREE_MODEL(folderview->store), &iter, + sel_path); + if (sel_path && open_path && + (gtk_tree_path_compare(open_path, sel_path) == 0 || + gtk_tree_path_is_ancestor(sel_path, open_path))) { + summary_clear_all(folderview->summaryview); + gtk_tree_row_reference_free(folderview->opened); + folderview->opened = NULL; + } + gtk_tree_path_free(open_path); + gtk_tree_path_free(sel_path); + + gtk_tree_store_remove(folderview->store, &iter); + if (folderview_insert_item_recursive(folderview, item, &iter)) { + gtkut_tree_view_expand_parent_all + (GTK_TREE_VIEW(folderview->treeview), &iter); + } + + folder_write_list(); +} + static void folderview_delete_folder_cb(FolderView *folderview, guint action, GtkWidget *widget) { diff --git a/src/folderview.h b/src/folderview.h index 352ea6c7..5fb251f2 100644 --- a/src/folderview.h +++ b/src/folderview.h @@ -100,6 +100,7 @@ void folderview_update_all_updated (gboolean update_summary); void folderview_new_folder (FolderView *folderview); void folderview_rename_folder (FolderView *folderview); +void folderview_move_folder (FolderView *folderview); void folderview_delete_folder (FolderView *folderview); void folderview_check_new_selected (FolderView *folderview); @@ -391,6 +391,7 @@ static FolderClass imap_class = imap_create_folder, imap_rename_folder, + NULL, imap_remove_folder }; diff --git a/src/mainwindow.c b/src/mainwindow.c index 3af7d2dc..98180364 100644 --- a/src/mainwindow.c +++ b/src/mainwindow.c @@ -194,6 +194,9 @@ static void new_folder_cb (MainWindow *mainwin, static void rename_folder_cb (MainWindow *mainwin, guint action, GtkWidget *widget); +static void move_folder_cb (MainWindow *mainwin, + guint action, + GtkWidget *widget); static void delete_folder_cb (MainWindow *mainwin, guint action, GtkWidget *widget); @@ -469,6 +472,7 @@ static GtkItemFactoryEntry mainwin_entries[] = {N_("/_File/_Folder/Create _new folder..."), NULL, new_folder_cb, 0, NULL}, {N_("/_File/_Folder/_Rename folder..."),NULL, rename_folder_cb, 0, NULL}, + {N_("/_File/_Folder/_Move folder..."), NULL, move_folder_cb, 0, NULL}, {N_("/_File/_Folder/_Delete folder"), NULL, delete_folder_cb, 0, NULL}, {N_("/_File/_Mailbox"), NULL, NULL, 0, "<Branch>"}, {N_("/_File/_Mailbox/Add _mailbox..."), NULL, add_mailbox_cb, 0, NULL}, @@ -1622,12 +1626,13 @@ typedef enum M_FOLDER_NEWOK = 1 << 17, M_FOLDER_RENOK = 1 << 18, - M_FOLDER_DELOK = 1 << 19, - M_MBOX_ADDOK = 1 << 20, - M_MBOX_RMOK = 1 << 21, - M_MBOX_CHKOK = 1 << 22, - M_MBOX_CHKALLOK = 1 << 23, - M_MBOX_REBUILDOK = 1 << 24 + M_FOLDER_MOVEOK = 1 << 19, + M_FOLDER_DELOK = 1 << 20, + M_MBOX_ADDOK = 1 << 21, + M_MBOX_RMOK = 1 << 22, + M_MBOX_CHKOK = 1 << 23, + M_MBOX_CHKALLOK = 1 << 24, + M_MBOX_REBUILDOK = 1 << 25 } SensitiveCond; static SensitiveCond main_window_get_current_state(MainWindow *mainwin) @@ -1684,6 +1689,8 @@ static SensitiveCond main_window_get_current_state(MainWindow *mainwin) else if (item->stype == F_NORMAL) { state |= M_FOLDER_RENOK; state |= M_FOLDER_DELOK; + if (item->folder->klass->move_folder) + state |= M_FOLDER_MOVEOK; } } else if (FOLDER_TYPE(item->folder) == F_NEWS) { if (item->parent != NULL) @@ -1766,6 +1773,7 @@ void main_window_set_menu_sensitive(MainWindow *mainwin) } entry[] = { {"/File/Folder/Create new folder...", M_UNLOCKED|M_FOLDER_NEWOK}, {"/File/Folder/Rename folder..." , M_UNLOCKED|M_FOLDER_RENOK}, + {"/File/Folder/Move folder..." , M_UNLOCKED|M_FOLDER_MOVEOK}, {"/File/Folder/Delete folder" , M_UNLOCKED|M_FOLDER_DELOK}, {"/File/Mailbox/Add mailbox..." , M_UNLOCKED|M_MBOX_ADDOK}, {"/File/Mailbox/Remove mailbox" , M_UNLOCKED|M_MBOX_RMOK}, @@ -2638,6 +2646,11 @@ static void rename_folder_cb(MainWindow *mainwin, guint action, folderview_rename_folder(mainwin->folderview); } +static void move_folder_cb(MainWindow *mainwin, guint action, GtkWidget *widget) +{ + folderview_move_folder(mainwin->folderview); +} + static void delete_folder_cb(MainWindow *mainwin, guint action, GtkWidget *widget) { @@ -108,6 +108,9 @@ static FolderItem *mh_create_folder (Folder *folder, static gint mh_rename_folder (Folder *folder, FolderItem *item, const gchar *name); +static gint mh_move_folder (Folder *folder, + FolderItem *item, + FolderItem *new_parent); static gint mh_remove_folder (Folder *folder, FolderItem *item); @@ -156,6 +159,7 @@ static FolderClass mh_class = mh_create_folder, mh_rename_folder, + mh_move_folder, mh_remove_folder, }; @@ -931,6 +935,84 @@ static gint mh_rename_folder(Folder *folder, FolderItem *item, g_free(paths[0]); g_free(paths[1]); + + return 0; +} + +static gint mh_move_folder(Folder *folder, FolderItem *item, + FolderItem *new_parent) +{ + gchar *oldpath; + gchar *newpath; + gchar *new_dir; + gchar *name; + gchar *utf8_name; + gchar *paths[2]; + + 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(new_parent != NULL, -1); + g_return_val_if_fail(item != new_parent, -1); + g_return_val_if_fail(item->parent != new_parent, -1); + g_return_val_if_fail(folder == item->folder, -1); + g_return_val_if_fail(item->folder == new_parent->folder, -1); + + if (g_node_is_ancestor(item->node, new_parent->node)) { + g_warning("folder to be moved is ancestor of new parent\n"); + return -1; + } + + oldpath = folder_item_get_path(item); + name = g_path_get_basename(oldpath); + utf8_name = g_filename_to_utf8(name, -1, NULL, NULL, NULL); + if (!utf8_name) + utf8_name = g_strdup(name); + new_dir = folder_item_get_path(new_parent); + newpath = g_strconcat(new_dir, G_DIR_SEPARATOR_S, name, NULL); + g_free(new_dir); + + if (is_file_entry_exist(newpath)) { + g_warning("%s already exists\n", newpath); + g_free(oldpath); + g_free(newpath); + g_free(utf8_name); + return -1; + } + + debug_print("mh_move_folder: rename(%s, %s)\n", oldpath, newpath); + g_free(name); + + if (rename(oldpath, newpath) < 0) { + FILE_OP_ERROR(oldpath, "rename"); + g_free(oldpath); + g_free(newpath); + g_free(utf8_name); + return -1; + } + + g_free(oldpath); + g_free(newpath); + + g_node_unlink(item->node); + g_node_append(new_parent->node, item->node); + item->parent = new_parent; + + if (new_parent->path != NULL) { + newpath = g_strconcat(new_parent->path, G_DIR_SEPARATOR_S, + utf8_name, NULL); + g_free(utf8_name); + } else + newpath = utf8_name; + + paths[0] = g_strdup(item->path); + paths[1] = newpath; + g_node_traverse(item->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, + mh_rename_folder_func, paths); + + g_free(paths[0]); + g_free(paths[1]); + return 0; } @@ -153,6 +153,7 @@ static FolderClass news_class = NULL, NULL, + NULL, NULL }; |