aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Williams <peterw@ximian.com>2001-07-20 05:35:43 +0800
committerPeter Williams <peterw@src.gnome.org>2001-07-20 05:35:43 +0800
commit85a02926e6c5b8c73dbb44fe343da80247babaf8 (patch)
tree71e8bdcc136081da9ec4f11eacef0027dddff07e
parent3f9e744cab8fc9a34590974da264018ec091bbb1 (diff)
downloadgsoc2013-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/ChangeLog24
-rw-r--r--camel/camel-store.c14
-rw-r--r--camel/providers/imap/camel-imap-store.c169
-rw-r--r--mail/ChangeLog18
-rw-r--r--mail/component-factory.c41
-rw-r--r--mail/mail-callbacks.c10
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);