diff options
-rw-r--r-- | shell/ChangeLog | 23 | ||||
-rw-r--r-- | shell/e-shell-folder-commands.c | 16 | ||||
-rw-r--r-- | shell/e-shell-view.c | 135 |
3 files changed, 170 insertions, 4 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog index b8374179f6..4a7312c7a4 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,26 @@ +2002-03-04 Ettore Perazzoli <ettore@ximian.com> + + [Fix #20234, Deleting Folder gratuitiously causes /local to open.] + + * e-shell-view.c (find_inbox_in_storage): New helper function to + heuristically find an Inbox folder. + (handle_current_folder_removed): New function to handle the + removal of the currently displayed folder in a slightly smarter + way than before. It tries to display the parent folder of the + folder that got deleted and, if not possible, the Inbox in the + same storage. If neither of this is possible, it displays the + default local Inbox. [It still doesn't handle the case where you + have no Inbox gracefully, but that can come later.] + (storage_set_removed_folder_callback): Call + `handle_current_folder_removed'. + +2002-03-04 Ettore Perazzoli <ettore@ximian.com> + + [Fix #20237, Shell silently drops xfer_folder errors.] + + * e-shell-folder-commands.c (xfer_result_callback): Display an + error message if the operation failed. + 2002-02-26 Ettore Perazzoli <ettore@ximian.com> [This gets rid of some spurious "could not find handler" messages diff --git a/shell/e-shell-folder-commands.c b/shell/e-shell-folder-commands.c index 73ca33829f..4a2bbe7e4f 100644 --- a/shell/e-shell-folder-commands.c +++ b/shell/e-shell-folder-commands.c @@ -133,7 +133,21 @@ xfer_result_callback (EStorageSet *storage_set, folder_command_data = (FolderCommandData *) data; - /* FIXME: do something. */ + if (result != E_STORAGE_OK) { + char *msg; + + if (folder_command_data->command == FOLDER_COMMAND_COPY) + msg = g_strdup_printf (_("Cannot copy folder: %s"), + e_storage_result_to_string (result)); + else + msg = g_strdup_printf (_("Cannot move folder: %s"), + e_storage_result_to_string (result)); + + e_notice (GTK_WINDOW (folder_command_data->shell_view), + GNOME_MESSAGE_BOX_ERROR, msg); + + g_free (msg); + } folder_command_data_free (folder_command_data); } diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c index 78059f5e17..29d815db97 100644 --- a/shell/e-shell-view.c +++ b/shell/e-shell-view.c @@ -33,8 +33,7 @@ #include <ctype.h> #include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> +#include <libgnome/libgnome.h> #include <libgnomeui/gnome-window.h> #include <libgnomeui/gnome-window-icon.h> #include <libgnomeui/gnome-app.h> @@ -44,6 +43,7 @@ #include <gal/e-paned/e-hpaned.h> #include <gal/util/e-util.h> +#include <gal/util/e-unicode-i18n.h> #include <gal/widgets/e-gui-utils.h> #include <gal/widgets/e-unicode.h> #include <gal/widgets/e-scroll-frame.h> @@ -167,6 +167,10 @@ static guint signals[LAST_SIGNAL] = { 0 }; #define SET_FOLDER_DELAY 250 +/* URI to display when the currently displayed folder is removed from the + storage. */ +#define FALLBACK_URI "evolution:/local/Inbox" + /* The icons for the offline/online status. */ @@ -353,6 +357,126 @@ remove_uri_from_history (EShellView *shell_view, } +/* This implements the behavior for when the folder which is currently displayed + gets deleted. */ + +/* Find the path for an Inbox in the specified storage. This is not really + 100% correct, but should work for most cases. */ +static char * +find_inbox_in_storage (EShellView *shell_view, + const char *storage_name) +{ + EShellViewPrivate *priv; + EStorageSet *storage_set; + EStorage *storage; + GList *subfolder_paths; + GList *p; + + priv = shell_view->priv; + storage_set = e_shell_get_storage_set (priv->shell); + storage = e_storage_set_get_storage (storage_set, storage_name); + + subfolder_paths = e_storage_get_subfolder_paths (storage, "/"); + for (p = subfolder_paths; p != NULL; p = p->next) { + const char *path; + + path = (const char *) p->data; + if (g_utf8_strcasecmp (path, "/inbox") == 0 + || g_utf8_strcasecmp (path + 1, U_("Inbox")) == 0) { + char *return_path; + + return_path = g_strconcat ("/", storage_name, "/", path, + NULL); + e_free_string_list (subfolder_paths); + return return_path; + } + } + + e_free_string_list (subfolder_paths); + + return NULL; +} + +static void +handle_current_folder_removed (EShellView *shell_view) +{ + EShellViewPrivate *priv; + const char *current_path; + const char *p; + char *new_path; + + /* Note: we assume that priv->uri is an evolution: URI. */ + + priv = shell_view->priv; + + current_path = priv->uri + E_SHELL_URI_PREFIX_LEN; + + g_assert (*current_path == G_DIR_SEPARATOR); + + new_path = NULL; + + /* If we have a parent folder (not a parent storage), try to display + that one. */ + + p = strrchr (current_path + 1, G_DIR_SEPARATOR); + if (p != NULL && p[1] != '\0' && strchr (current_path + 1, G_DIR_SEPARATOR) != p) { + new_path = g_strndup (current_path, p - current_path); + } else { + /* We don't have a parent folder, so try to see if there is an + Inbox folder in the same storage. */ + + /* Extract the storage name. */ + p = strchr (current_path + 1, G_DIR_SEPARATOR); + if (p == NULL) { + /* The URL points itself to a storage, so just redirect + to the default case. */ + new_path = NULL; + } else { + char *storage_name; + + storage_name = g_strndup (current_path + 1, p - current_path - 1); + + new_path = find_inbox_in_storage (shell_view, storage_name); + if (new_path == NULL) { + char *storage_uri; + + /* No Inbox in this storage -- fallback to the storage. */ + storage_uri = g_strconcat (E_SHELL_URI_PREFIX, storage_name, NULL); + e_shell_view_display_uri (shell_view, storage_uri); + + g_free (storage_uri); + g_free (storage_name); + return; + } + + g_free (storage_name); + } + } + + if (new_path == NULL) { + e_shell_view_display_uri (shell_view, FALLBACK_URI); + } else { + EFolder *folder; + + /* Check that the folder we have chosen exists; if it doesn't, + we just use the fallback URI. */ + + folder = e_storage_set_get_folder (e_shell_get_storage_set (priv->shell), new_path); + if (folder == NULL) { + e_shell_view_display_uri (shell_view, FALLBACK_URI); + } else { + char *new_uri; + + new_uri = g_strconcat (E_SHELL_URI_PREFIX, new_path, NULL); + e_shell_view_display_uri (shell_view, new_uri); + g_free (new_uri); + } + + g_free (new_path); + } +} + + /* Callbacks for the EStorageSet. */ static void @@ -396,9 +520,10 @@ storage_set_removed_folder_callback (EStorageSet *storage_set, page_num = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), view->control); + /* Check if it's the URI that we are currently displaying. */ if (strncmp (priv->uri, E_SHELL_URI_PREFIX, E_SHELL_URI_PREFIX_LEN) == 0 && strcmp (priv->uri + E_SHELL_URI_PREFIX_LEN, path) == 0) { - e_shell_view_display_uri (shell_view, "evolution:/local/Inbox"); + handle_current_folder_removed (shell_view); } bonobo_control_frame_control_deactivate (BONOBO_CONTROL_FRAME (bonobo_widget_get_control_frame (BONOBO_WIDGET (view->control)))); @@ -1197,6 +1322,10 @@ destroy (GtkObject *object) storage set used for the delayed selection mechanism. */ cleanup_delayed_selection (shell_view); + /* This is necessary to remove the signal handler for folder_new on the + storage set used for the delayed selection mechanism. */ + cleanup_delayed_selection (shell_view); + gtk_object_unref (GTK_OBJECT (priv->tooltips)); if (priv->history != NULL) |