diff options
author | Peter Williams <peterw@ximian.com> | 2001-07-20 05:35:43 +0800 |
---|---|---|
committer | Peter Williams <peterw@src.gnome.org> | 2001-07-20 05:35:43 +0800 |
commit | 85a02926e6c5b8c73dbb44fe343da80247babaf8 (patch) | |
tree | 71e8bdcc136081da9ec4f11eacef0027dddff07e | |
parent | 3f9e744cab8fc9a34590974da264018ec091bbb1 (diff) | |
download | gsoc2013-evolution-85a02926e6c5b8c73dbb44fe343da80247babaf8.tar.gz gsoc2013-evolution-85a02926e6c5b8c73dbb44fe343da80247babaf8.tar.zst gsoc2013-evolution-85a02926e6c5b8c73dbb44fe343da80247babaf8.zip |
In camel:
2001-07-19 Peter Williams <peterw@ximian.com>
Policy change: NULL url's are no longer allowed in CamelFolderInfos. They used
to signify that the folder was, in IMAP jargon, NoSelect; now the same effect
is achieved by adding a "noselect=yes" parameter to the end of the URL. As far
as I know, IMAP is the only affected provider.
* providers/imap/camel-imap-store.c (delete_folder): New function. Implement
folder deletion.
(camel_imap_store_class_init): Set the delete_folder class function here.
(get_folder_status): New function. Utility wrapper around the STATUS command.
(create_folder): If the parent folder is NoSelect but is empty, delete it
and recreate it as a a subfolder-containing folder. If it is NoSelect but
contains messages, set an exception.
(parse_list_response_as_folder_info): Always set the FolderInfo's URL, but
add a NoSelect parameter if it isn't selectable.
(get_folder_info_online): Change logic of removing the namespace to reflect
URL change. Same for logic of checking unread counts.
(get_folder_info_online): Use get_folder_status to simplify this.
* camel-store.c (camel_folder_info_build): When creating
dummy parents, copy the child's URL and set the NoSelect
parameter.
In mail:
2001-07-19 Peter Williams <peterw@ximian.com>
Track the NoSelect changes in Camel.
* mail-callbacks.c (create_folders): We don't need to check if
the URL is NULL or not anymore.
* component-factory.c (create_noselect_control): New
function. Create a dummy control for folders that can't contain
messages (ie \NoSelect)
(create_view): If the URI says the folder is noselect, make a
dummy control. FIXME: still should merge in the global UI
elements.
(xfer_folder): Don't allow the operation if the destination is
NoSelect.
(destination_folder_handle_motion): Ditto.
(destination_folder_handle_drop): Ditto.
svn path=/trunk/; revision=11237
-rw-r--r-- | camel/ChangeLog | 24 | ||||
-rw-r--r-- | camel/camel-store.c | 14 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-store.c | 169 | ||||
-rw-r--r-- | mail/ChangeLog | 18 | ||||
-rw-r--r-- | mail/component-factory.c | 41 | ||||
-rw-r--r-- | mail/mail-callbacks.c | 10 |
6 files changed, 234 insertions, 42 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 2db4d31537..3e767da515 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,27 @@ +2001-07-19 Peter Williams <peterw@ximian.com> + + Policy change: NULL url's are no longer allowed in CamelFolderInfos. They used + to signify that the folder was, in IMAP jargon, NoSelect; now the same effect + is achieved by adding a "noselect=yes" parameter to the end of the URL. As far + as I know, IMAP is the only affected provider. + + * providers/imap/camel-imap-store.c (delete_folder): New function. Implement + folder deletion. + (camel_imap_store_class_init): Set the delete_folder class function here. + (get_folder_status): New function. Utility wrapper around the STATUS command. + (create_folder): If the parent folder is NoSelect but is empty, delete it + and recreate it as a a subfolder-containing folder. If it is NoSelect but + contains messages, set an exception. + (parse_list_response_as_folder_info): Always set the FolderInfo's URL, but + add a NoSelect parameter if it isn't selectable. + (get_folder_info_online): Change logic of removing the namespace to reflect + URL change. Same for logic of checking unread counts. + (get_folder_info_online): Use get_folder_status to simplify this. + + * camel-store.c (camel_folder_info_build): When creating + dummy parents, copy the child's URL and set the NoSelect + parameter. + 2001-07-19 Jeffrey Stedfast <fejj@ximian.com> * camel-mime-part-utils.c diff --git a/camel/camel-store.c b/camel/camel-store.c index 23c4b82e9d..dbf0fce2e7 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -651,6 +651,9 @@ camel_folder_info_build (GPtrArray *folders, const char *namespace, if (pfi) { g_free (pname); } else { + CamelURL *url; + char *sep; + pfi = g_new0 (CamelFolderInfo, 1); pfi->full_name = pname; if (short_names) { @@ -661,6 +664,17 @@ camel_folder_info_build (GPtrArray *folders, const char *namespace, pfi->name = g_strdup (pname); } else pfi->name = g_strdup (pname); + + url = camel_url_new (fi->url, NULL); + sep = strrchr (url->path, separator); + if (sep) + *sep = '\0'; + else + g_warning ("huh, no \"%c\" in \"%s\"?", separator, fi->url); + camel_url_set_param (url, "noselect", "yes"); + pfi->url = camel_url_to_string (url, 0); + camel_url_free (url); + g_hash_table_insert (hash, pname, pfi); g_ptr_array_add (folders, pfi); } diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index a86a3b51e7..f6c24d09cd 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -76,6 +76,7 @@ static gint compare_folder_name (gconstpointer a, gconstpointer b); static CamelFolder *get_folder_online (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); static CamelFolder *get_folder_offline (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); static CamelFolderInfo *create_folder (CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex); +static void delete_folder (CamelStore *store, const char *folder_name, CamelException *ex); static CamelFolderInfo *get_folder_info_online (CamelStore *store, const char *top, guint32 flags, @@ -114,6 +115,7 @@ camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class) camel_store_class->hash_folder_name = hash_folder_name; camel_store_class->compare_folder_name = compare_folder_name; camel_store_class->create_folder = create_folder; + camel_store_class->delete_folder = delete_folder; camel_store_class->free_folder_info = camel_store_free_folder_info_full; camel_store_class->folder_subscribed = folder_subscribed; camel_store_class->subscribe_folder = subscribe_folder; @@ -826,6 +828,38 @@ no_such_folder (const char *name, CamelException *ex) return NULL; } +static int +get_folder_status (CamelImapStore *imap_store, const char *folder_name, const char *type) +{ + CamelImapResponse *response; + char *status, *p; + int out; + + /* FIXME: we assume the server is STATUS-capable */ + + response = camel_imap_command (imap_store, NULL, NULL, + "STATUS %S (%s)", + folder_name, + type); + + if (!response) + return -1; + + status = camel_imap_response_extract (imap_store, response, + "STATUS", NULL); + if (!status) + return -1; + + p = strstrcase (status, type); + if (p) + out = strtoul (p + strlen (type), NULL, 10); + else + out = -1; + + g_free (status); + return out; +} + static CamelFolder * get_folder_online (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) @@ -925,6 +959,32 @@ imap_concat (CamelImapStore *imap_store, const char *prefix, const char *suffix) return g_strdup_printf ("%s%c%s", prefix, imap_store->dir_sep, suffix); } +static void +delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) +{ + CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); + CamelImapResponse *response; + + if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex)) + return; + + /* make sure this folder isn't currently SELECTed */ + + response = camel_imap_command (imap_store, NULL, ex, "SELECT INBOX"); + if (response) { + camel_imap_response_free (imap_store, response); + imap_store->current_folder = NULL; + } else + return; + + /* delete the old parent and recreate it */ + + response = camel_imap_command (imap_store, NULL, ex, "DELETE %S", + folder_name); + if (response) + camel_imap_response_free (imap_store, response); +} + static CamelFolderInfo * create_folder (CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex) @@ -932,14 +992,74 @@ create_folder (CamelStore *store, const char *parent_name, CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); CamelImapResponse *response; CamelFolderInfo *fi; - char *full_name; + char *full_name, *resp, *thisone; + gboolean need_convert; + int i, flags; if (!camel_disco_store_check_online (CAMEL_DISCO_STORE (store), ex)) return NULL; if (!parent_name) parent_name = imap_store->namespace; - full_name = imap_concat (imap_store, parent_name, folder_name); + /* check if the parent allows inferiors */ + + need_convert = FALSE; + response = camel_imap_command (imap_store, NULL, ex, "LIST \"\" %S", + parent_name); + if (!response) /* whoa, this is bad */ + return NULL; + + /* FIXME: does not handle unexpected circumstances very well */ + for (i = 0; i < response->untagged->len; i++) { + resp = response->untagged->pdata[i]; + + if (!imap_parse_list_response (resp, &flags, NULL, &thisone)) + continue; + + if (strcmp (thisone, parent_name) == 0) { + if (flags & IMAP_LIST_FLAG_NOINFERIORS) + need_convert = TRUE; + break; + } + } + + camel_imap_response_free (imap_store, response); + + /* if not, check if we can delete it and recreate it */ + if (need_convert) { + gchar *name; + CamelException internal_ex; + + if (get_folder_status (imap_store, parent_name, "MESSAGES")) { + camel_exception_set (ex, CAMEL_EXCEPTION_FOLDER_INVALID_STATE, + _("The parent folder is not allowed to contain subfolders")); + return NULL; + } + + /* delete the old parent and recreate it */ + camel_exception_init (&internal_ex); + delete_folder (store, parent_name, &internal_ex); + if (camel_exception_is_set (&internal_ex)) { + camel_exception_xfer (ex, &internal_ex); + return; + } + + /* add the dirsep to the end of parent_name */ + name = g_strdup_printf ("%s%c", parent_name, imap_store->dir_sep); + response = camel_imap_command (imap_store, NULL, ex, "CREATE %S", + name); + g_free (name); + + if (!response) + return NULL; + else + camel_imap_response_free (imap_store, response); + } + + + /* ok now we can create the folder */ + + full_name = imap_concat (imap_store, parent_name, folder_name); response = camel_imap_command (imap_store, NULL, ex, "CREATE %S", full_name); if (response) { @@ -959,6 +1079,7 @@ parse_list_response_as_folder_info (CamelImapStore *imap_store, CamelFolderInfo *fi; int flags; char sep, *dir, *name = NULL; + CamelURL *url; if (!imap_parse_list_response (response, &flags, &sep, &dir)) return NULL; @@ -977,15 +1098,16 @@ parse_list_response_as_folder_info (CamelImapStore *imap_store, fi->name = g_strdup (name); else fi->name = g_strdup (dir); - if (!(flags & IMAP_LIST_FLAG_NOSELECT)) { - CamelURL *url; - - url = camel_url_new (imap_store->base_url, NULL); - g_free (url->path); - url->path = g_strdup_printf ("/%s", dir); - fi->url = camel_url_to_string (url, 0); - camel_url_free (url); - } + + url = camel_url_new (imap_store->base_url, NULL); + g_free (url->path); + url->path = g_strdup_printf ("/%s", dir); + if (flags & IMAP_LIST_FLAG_NOSELECT) + camel_url_set_param (url, "noselect", "yes"); + fi->url = camel_url_to_string (url, 0); + camel_url_free (url); + + if (!(flags & IMAP_LIST_FLAG_UNMARKED)) fi->unread_message_count = -1; @@ -1072,11 +1194,10 @@ get_folder_info_online (CamelStore *store, const char *top, guint32 flags, CamelException *ex) { CamelImapStore *imap_store = CAMEL_IMAP_STORE (store); - CamelImapResponse *response; gboolean need_inbox = FALSE; GPtrArray *folders; const char *name; - char *pattern, *status, *p; + char *pattern; CamelFolderInfo *fi, *tree; int i; @@ -1097,7 +1218,9 @@ get_folder_info_online (CamelStore *store, const char *top, goto lose; if (folders->len) { fi = folders->pdata[0]; - if (!fi->url) { + /* note that == is okay; see above */ + if (strstr (fi->url, "noselect=yes") && + name == imap_store->namespace) { camel_folder_info_free (fi); g_ptr_array_remove_index (folders, 0); } @@ -1173,8 +1296,9 @@ get_folder_info_online (CamelStore *store, const char *top, /* Don't check if it doesn't contain messages or if it * was \UnMarked. */ - if (!fi->url || fi->unread_message_count != -1) + if (fi->unread_message_count != -1 || strstr (fi->url, "noselect=yes")) continue; + /* Don't check if it's not INBOX and we're only * checking INBOX. */ @@ -1192,20 +1316,7 @@ get_folder_info_online (CamelStore *store, const char *top, continue; } - response = camel_imap_command (imap_store, NULL, NULL, - "STATUS %S (UNSEEN)", - fi->full_name); - if (!response) - continue; - status = camel_imap_response_extract (imap_store, response, - "STATUS", NULL); - if (!status) - continue; - - p = strstrcase (status, "UNSEEN"); - if (p) - fi->unread_message_count = strtoul (p + 6, NULL, 10); - g_free (status); + fi->unread_message_count = get_folder_status (imap_store, fi->full_name, "UNSEEN"); } g_ptr_array_free (folders, TRUE); diff --git a/mail/ChangeLog b/mail/ChangeLog index d295e66bf0..f97bc2df27 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,21 @@ +2001-07-19 Peter Williams <peterw@ximian.com> + + Track the NoSelect changes in Camel. + + * mail-callbacks.c (create_folders): We don't need to check if + the URL is NULL or not anymore. + + * component-factory.c (create_noselect_control): New + function. Create a dummy control for folders that can't contain + messages (ie \NoSelect) + (create_view): If the URI says the folder is noselect, make a + dummy control. FIXME: still should merge in the global UI + elements. + (xfer_folder): Don't allow the operation if the destination is + NoSelect. + (destination_folder_handle_motion): Ditto. + (destination_folder_handle_drop): Ditto. + 2001-07-19 Not Zed <NotZed@Ximian.com> * mail-local.c (reconfigure_folder_reconfigure): remvoed diff --git a/mail/component-factory.c b/mail/component-factory.c index 5502fa7683..5074cbfabf 100644 --- a/mail/component-factory.c +++ b/mail/component-factory.c @@ -103,6 +103,16 @@ static const char *schema_types[] = { /* EvolutionShellComponent methods and signals. */ +static BonoboControl * +create_noselect_control (void) +{ + GtkWidget *label; + + label = gtk_label_new (_("This folder cannot contain messages.")); + gtk_widget_show (label); + return bonobo_control_new (label); +} + static EvolutionShellComponentResult create_view (EvolutionShellComponent *shell_component, const char *physical_uri, @@ -118,8 +128,12 @@ create_view (EvolutionShellComponent *shell_component, corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); if (g_strcasecmp (folder_type, "mail") == 0) { - control = folder_browser_factory_new_control (physical_uri, - corba_shell); + /* hack-tastic! */ + if (strstr (physical_uri, "noselect=yes")) + control = create_noselect_control (); + else + control = folder_browser_factory_new_control (physical_uri, + corba_shell); } else if (g_strcasecmp (folder_type, "mailstorage") == 0) { CamelService *store; EvolutionStorage *storage; @@ -262,6 +276,12 @@ xfer_folder (EvolutionShellComponent *shell_component, CamelException ex; GPtrArray *uids; + if (strstr (destination_physical_uri, "noselect=yes")) { + GNOME_Evolution_ShellComponentListener_notifyResult (listener, + GNOME_Evolution_ShellComponentListener_UNSUPPORTED_OPERATION, &ev); + return; + } + camel_exception_init (&ex); source = mail_tool_uri_to_folder (source_physical_uri, &ex); camel_exception_clear (&ex); @@ -321,8 +341,12 @@ destination_folder_handle_motion (EvolutionShellComponentDndDestinationFolder *f gpointer user_data) { g_print ("in destination_folder_handle_motion (%s)\n", physical_uri); - - *suggested_action_return = GNOME_Evolution_ShellComponentDnd_ACTION_MOVE; + + if (strstr (physical_uri, "noselect=yes")) + /* uh, no way to say "illegal" */ + *suggested_action_return = GNOME_Evolution_ShellComponentDnd_ACTION_DEFAULT; + else + *suggested_action_return = GNOME_Evolution_ShellComponentDnd_ACTION_MOVE; return TRUE; } @@ -381,6 +405,9 @@ destination_folder_handle_drop (EvolutionShellComponentDndDestinationFolder *des if (action == GNOME_Evolution_ShellComponentDnd_ACTION_LINK) return FALSE; /* we can't create links */ + if (strstr (physical_uri, "noselect=yes")) + return FALSE; + g_print ("in destination_folder_handle_drop (%s)\n", physical_uri); for (type = 0; accepted_dnd_types[type]; type++) @@ -546,7 +573,7 @@ owner_set_cb (EvolutionShellComponent *shell_component, mail_config_init (); storages_hash = g_hash_table_new (NULL, NULL); - + vfolder_create_storage (shell_component); corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); @@ -732,7 +759,7 @@ storage_create_folder (EvolutionStorage *storage, prefix = g_strndup (path, name - path - 1); folder_created (store, prefix, fi); g_free (prefix); - + camel_store_free_folder_info (store, fi); return EVOLUTION_STORAGE_OK; @@ -775,7 +802,7 @@ storage_remove_folder (EvolutionStorage *storage, if (camel_store_supports_subscriptions (store)) camel_store_unsubscribe_folder (store, fi->full_name, NULL); - folder_deleted (store, fi); + evolution_storage_removed_folder (storage, path); camel_store_free_folder_info (store, fi); diff --git a/mail/mail-callbacks.c b/mail/mail-callbacks.c index b20ee1baf0..067866fed5 100644 --- a/mail/mail-callbacks.c +++ b/mail/mail-callbacks.c @@ -2016,15 +2016,13 @@ static void create_folders (EvolutionStorage *storage, const char *prefix, CamelFolderInfo *fi) { char *path; - - if (fi->url) { - mail_folder_cache_set_update_estorage (fi->url, storage); - mail_folder_cache_note_folderinfo (fi->url, fi); - } + + mail_folder_cache_set_update_estorage (fi->url, storage); + mail_folder_cache_note_folderinfo (fi->url, fi); path = g_strdup_printf ("%s/%s", prefix, fi->name); evolution_storage_new_folder (storage, path, fi->name, - "mail", fi->url ? fi->url : "", + "mail", fi->url, fi->name, /* description */ fi->unread_message_count > 0); |