Re: Patch: add header flag "calendar"



El mar, 22-12-2009 a las 19:14 +0100, Philip Van Hoof escribió:
> On Tue, 2009-12-22 at 17:20 +0100, José Dapena Paz wrote:

	So, retaking this.

> 
> > > Not sure how you'll expose it in TnyCamelHeader, shouldn't be too hard.
> > 
> > 	Exactly same api. No change in camel level. Only change would be in
> > camel folder summary default implementation, that would tell it does not
> > support any flag. And specific impleemntations of info_set_user_flag and
> > info_user_flags could override it providing any level of storage.
> > 
> > 	This way we provide the API, we  just implement a stub (no support for
> > flags) in our default backends so no storage increase.
> > 
> 
> Sounds good to me

	I'm attaching the patch with support for user flags, but with stub
implementation in tinymail camel default backends. This way, some
protocol can implement the flag, but default protocols won't.

> 
> >  
> > > 
> > > > > On Tue, 2009-12-22 at 11:52 +0100, José Dapena Paz wrote:
> > > > > > El vie, 18-12-2009 a las 13:04 +0100, Philip Van Hoof escribió:
> > > > > > > On Fri, 2009-12-18 at 12:36 +0100, José Dapena Paz wrote:
> > > > > > > 
> > > > > > > > 	Then we need to find a different way. The approach taken in camel is
> > > > > > > > storing this kind of information in the user flags, which is not
> > > > > > > > supported in camel lite (and also, not exposed in any way to tinymail).
> > > > > > > > As far as I remember, this is one of the things removed to keep small
> > > > > > > > tinymail/camel-lite folder summary storage.
> > > > > > > > 
> > > > > > > > 	Or we can just add the user flags in this way:
> > > > > > > > 	* CamelMessageInfo: same API
> > > > > > > > 	* Add API to TnyHeader to get/set these flags
> > > > > > > > 	* Add a way to know the degree of support for these flags in the header
> > > > > > > > (no support, only memory storage, both memory and persistent storage).
> > > > > > > > 
> > > > > > > > 	void tny_header_set_user_flag (TnyHeader *header, const gchar *name, gboolean flag)
> > > > > > > > 	void tny_header_get_user_flags (TnyHeader *header, TnyList *flags);
> > > > > > > > 
> > > > > > > > 	TnyHeaderSupportFlagsType tny_header_support_user_flags (TnyHeader *header);
> > > > > > > > 	^----- How could this be better implemented? :m
> > > > > > > > 
> > > > > > > > 	Same for camel. We recover the userflags field. By default we would
> > > > > > > > only support storage in memory, and we could allow to set in some way if
> > > > > > > > support is also available to storage in disk. This info would be stored
> > > > > > > > in the CamelFolderSummary. This way, if we have (as we have now) some
> > > > > > > > provider that don't use the camel-lite summary, and provides special
> > > > > > > > flags, we could add access to it.
> > > > > > > 
> > > > > > > 
> > > > > > > This sounds good to me
> > > > > > 
> > > > > > 	This patch implements the proposal for user flags. Finally it's a bit
> > > > > > different: we have a method tny_header_get_user_flag, and no way to
> > > > > > retrieve all the available headers. This is just to mimic the behavior
> > > > > > of the camel backend.
> > > > > > 
> > > > > > 	Also, default implementation in camel is not persistent (and then, no
> > > > > > changes in summary format). But other backends may implement persistent
> > > > > > storage or some or all user flags.
> > > > > > 
> > > > > > 	Attached is the patch implementation.
> > > > > > 
> > > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > 
> > > > > > 
> > > > > 
> > > > 
> > > > 
> > > 
> > 
> > 
> 


-- 
José Dapena Paz <jdapena igalia com>
Igalia
diff --git a/libtinymail-camel/camel-lite/camel/camel-folder-summary.h b/libtinymail-camel/camel-lite/camel/camel-folder-summary.h
index 1ae0211..6142b0d 100644
--- a/libtinymail-camel/camel-lite/camel/camel-folder-summary.h
+++ b/libtinymail-camel/camel-lite/camel/camel-folder-summary.h
@@ -33,6 +33,11 @@
 #define CAMEL_FOLDER_SUMMARY_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_folder_summary_get_type (), CamelFolderSummaryClass)
 #define CAMEL_IS_FOLDER_SUMMARY(obj)      CAMEL_CHECK_TYPE (obj, camel_folder_summary_get_type ())
 
+#define CAMEL_MESSAGE_INFO_SUPPORT_FLAGS_ANY_USER_FLAG "__message_info_support_flags_any"
+#define CAMEL_MESSAGE_INFO_SUPPORT_FLAGS_SOME_USER_FLAG "__message_info_support_flags_some"
+#define CAMEL_MESSAGE_INFO_SUPPORT_PERMANENT_FLAGS_ANY_USER_FLAG "__message_info_support_permanent_flags_any"
+#define CAMEL_MESSAGE_INFO_SUPPORT_PERMANENT_FLAGS_SOME_USER_FLAG "__message_info_support_permanent_flags_some"
+
 G_BEGIN_DECLS
 
 struct _CamelFolder;
@@ -99,6 +104,7 @@ typedef enum _CamelMessageFlags {
 /* Changes to system flags will NOT trigger a folder changed event */
 #define CAMEL_MESSAGE_SYSTEM_MASK (0x1fff << 12)
 
+
 typedef struct _CamelFlag {
 	struct _CamelFlag *next;
 	char name[1];		/* name allocated as part of the structure */
diff --git a/libtinymail-camel/tny-camel-bs-msg-header.c b/libtinymail-camel/tny-camel-bs-msg-header.c
index 3cdf0b5..1aae700 100644
--- a/libtinymail-camel/tny-camel-bs-msg-header.c
+++ b/libtinymail-camel/tny-camel-bs-msg-header.c
@@ -146,6 +146,30 @@ tny_camel_bs_msg_header_unset_flag (TnyHeader *self, TnyHeaderFlags mask)
 	return;
 }
 
+static gboolean
+tny_camel_bs_msg_header_get_user_flag (TnyHeader *self, const gchar *id)
+{
+	return FALSE;
+}
+
+static void
+tny_camel_bs_msg_header_set_user_flag (TnyHeader *self, const gchar *id)
+{
+	return;
+}
+
+static void
+tny_camel_bs_msg_header_unset_user_flag (TnyHeader *self, const gchar *id)
+{
+	return;
+}
+
+static gboolean
+tny_camel_bs_msg_header_support_user_flags (TnyHeader *self)
+{
+	return TNY_HEADER_SUPPORT_FLAGS_NONE;
+}
+
 static time_t
 tny_camel_bs_msg_header_get_date_received (TnyHeader *self)
 {
@@ -265,6 +289,10 @@ tny_header_init (gpointer g, gpointer iface_data)
 	klass->set_flag= tny_camel_bs_msg_header_set_flag;
 	klass->unset_flag= tny_camel_bs_msg_header_unset_flag;
 	klass->get_flags= tny_camel_bs_msg_header_get_flags;
+	klass->set_user_flag= tny_camel_bs_msg_header_set_user_flag;
+	klass->unset_user_flag= tny_camel_bs_msg_header_unset_user_flag;
+	klass->get_user_flag= tny_camel_bs_msg_header_get_user_flag;
+	klass->support_user_flags = tny_camel_bs_msg_header_support_user_flags;
 
 	return;
 }
diff --git a/libtinymail-camel/tny-camel-header.c b/libtinymail-camel/tny-camel-header.c
index 8c33257..d62ea17 100644
--- a/libtinymail-camel/tny-camel-header.c
+++ b/libtinymail-camel/tny-camel-header.c
@@ -202,6 +202,51 @@ tny_camel_header_unset_flag (TnyHeader *self, TnyHeaderFlags mask)
 	return;
 }
 
+static gboolean
+tny_camel_header_get_user_flag (TnyHeader *self, const gchar *id)
+{
+	TnyCamelHeader *me = TNY_CAMEL_HEADER (self);
+	gboolean retval;
+
+	retval = camel_message_info_user_flag (me->info, id);
+
+	return retval;
+}
+
+static void
+tny_camel_header_set_user_flag (TnyHeader *self, const gchar *id)
+{
+	TnyCamelHeader *me = TNY_CAMEL_HEADER (self);
+
+	camel_message_info_set_user_flag (me->info, id, TRUE);
+}
+
+static void
+tny_camel_header_unset_user_flag (TnyHeader *self, const gchar *id)
+{
+	TnyCamelHeader *me = TNY_CAMEL_HEADER (self);
+
+	camel_message_info_set_user_flag (me->info, id, FALSE);
+}
+
+static TnyHeaderSupportFlags
+tny_camel_header_support_user_flags (TnyHeader *self)
+{
+	TnyCamelHeader *me = TNY_CAMEL_HEADER (self);
+	TnyHeaderSupportFlags flags = TNY_HEADER_SUPPORT_FLAGS_NONE;
+
+	if (camel_message_info_user_flag (me->info, CAMEL_MESSAGE_INFO_SUPPORT_FLAGS_ANY_USER_FLAG))
+		flags |= TNY_HEADER_SUPPORT_FLAGS_ANY;
+	if (camel_message_info_user_flag (me->info, CAMEL_MESSAGE_INFO_SUPPORT_FLAGS_SOME_USER_FLAG))
+		flags |= TNY_HEADER_SUPPORT_FLAGS_SOME;
+	if (camel_message_info_user_flag (me->info, CAMEL_MESSAGE_INFO_SUPPORT_PERMANENT_FLAGS_ANY_USER_FLAG))
+		flags |= TNY_HEADER_SUPPORT_PERSISTENT_FLAGS_ANY;
+	if (camel_message_info_user_flag (me->info, CAMEL_MESSAGE_INFO_SUPPORT_PERMANENT_FLAGS_SOME_USER_FLAG))
+		flags |= TNY_HEADER_SUPPORT_PERSISTENT_FLAGS_SOME;
+
+	return flags;
+}
+
 static time_t
 tny_camel_header_get_date_received (TnyHeader *self)
 {
@@ -383,6 +428,10 @@ tny_header_init (gpointer g, gpointer iface_data)
 	klass->set_flag= tny_camel_header_set_flag;
 	klass->unset_flag= tny_camel_header_unset_flag;
 	klass->get_flags= tny_camel_header_get_flags;
+	klass->set_user_flag = tny_camel_header_set_user_flag;
+	klass->get_user_flag = tny_camel_header_get_user_flag;
+	klass->unset_user_flag = tny_camel_header_unset_user_flag;
+	klass->support_user_flags = tny_camel_header_support_user_flags;
 
 	return;
 }
diff --git a/libtinymail-camel/tny-camel-msg-header.c b/libtinymail-camel/tny-camel-msg-header.c
index e5067e5..608d250 100644
--- a/libtinymail-camel/tny-camel-msg-header.c
+++ b/libtinymail-camel/tny-camel-msg-header.c
@@ -298,6 +298,54 @@ tny_camel_msg_header_unset_flag (TnyHeader *self, TnyHeaderFlags mask)
 	return;
 }
 
+static void
+tny_camel_msg_header_set_user_flag (TnyHeader *self, const gchar *id)
+{
+	TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
+
+	if (me->decorated) {
+		tny_header_set_user_flag (me->decorated, id);
+	}
+
+	return;
+}
+
+static void
+tny_camel_msg_header_unset_user_flag (TnyHeader *self, const gchar *id)
+{
+	TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
+
+	if (me->decorated) {
+		tny_header_unset_user_flag (me->decorated, id);
+	}
+
+	return;
+}
+
+static gboolean
+tny_camel_msg_header_get_user_flag (TnyHeader *self, const gchar *id)
+{
+	TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
+
+	if (me->decorated) {
+		return tny_header_get_user_flag (me->decorated, id);
+	} else {
+		return FALSE;
+	}
+}
+
+static TnyHeaderSupportFlags
+tny_camel_msg_header_support_user_flags (TnyHeader *self)
+{
+	TnyCamelMsgHeader *me = TNY_CAMEL_MSG_HEADER (self);
+
+	if (me->decorated) {
+		return tny_header_support_user_flags (me->decorated);
+	} else {
+		return TNY_HEADER_SUPPORT_FLAGS_NONE;
+	}
+}
+
 static time_t
 tny_camel_msg_header_get_date_received (TnyHeader *self)
 {
@@ -564,6 +612,10 @@ tny_header_init (gpointer g, gpointer iface_data)
 	klass->set_flag= tny_camel_msg_header_set_flag;
 	klass->unset_flag= tny_camel_msg_header_unset_flag;
 	klass->get_flags= tny_camel_msg_header_get_flags;
+	klass->set_user_flag= tny_camel_msg_header_set_user_flag;
+	klass->unset_user_flag= tny_camel_msg_header_unset_user_flag;
+	klass->get_user_flag= tny_camel_msg_header_get_user_flag;
+	klass->support_user_flags= tny_camel_msg_header_support_user_flags;
 
 	return;
 }
diff --git a/libtinymail/tny-expunged-header.c b/libtinymail/tny-expunged-header.c
index b84f75d..16d4e99 100644
--- a/libtinymail/tny-expunged-header.c
+++ b/libtinymail/tny-expunged-header.c
@@ -145,6 +145,28 @@ tny_expunged_header_unset_flag (TnyHeader *self, TnyHeaderFlags mask)
 {
 }
 
+static gboolean
+tny_expunged_header_get_user_flag (TnyHeader *self, const gchar *id)
+{
+	return FALSE;
+}
+
+static void
+tny_expunged_header_set_user_flag (TnyHeader *self, const gchar *id)
+{
+}
+
+static void
+tny_expunged_header_unset_user_flag (TnyHeader *self, const gchar *id)
+{
+}
+
+static TnyHeaderSupportFlags
+tny_expunged_header_support_user_flags (TnyHeader *self)
+{
+	return TNY_HEADER_SUPPORT_FLAGS_NONE;
+}
+
 static void
 tny_expunged_header_finalize (GObject *object)
 {
@@ -180,6 +202,10 @@ tny_header_init (TnyHeaderIface *klass)
 	klass->get_flags= tny_expunged_header_get_flags;
 	klass->set_flag= tny_expunged_header_set_flag;
 	klass->unset_flag= tny_expunged_header_unset_flag;
+	klass->get_user_flag= tny_expunged_header_get_user_flag;
+	klass->set_user_flag= tny_expunged_header_set_user_flag;
+	klass->unset_user_flag= tny_expunged_header_unset_user_flag;
+	klass->support_user_flags= tny_expunged_header_support_user_flags;
 }
 
 static void
diff --git a/libtinymail/tny-header.c b/libtinymail/tny-header.c
index af43582..6dfda97 100644
--- a/libtinymail/tny-header.c
+++ b/libtinymail/tny-header.c
@@ -532,6 +532,76 @@ tny_header_set_flag (TnyHeader *self, TnyHeaderFlags mask)
 }
 
 /**
+ * tny_header_set_user_flag:
+ * @self: a #TnyHeader
+ * @name: name of the flag to set
+ * 
+ * Set as %TRUE the user flag with name @name.
+ *
+ * since: 1.0
+ * audience: application-developer
+ **/
+void 
+tny_header_set_user_flag (TnyHeader *self, const gchar *name)
+{
+#ifdef DBC /* require */
+	g_assert (TNY_IS_HEADER (self));
+	g_assert (TNY_HEADER_GET_IFACE (self)->set_user_flag!= NULL);
+#endif
+
+	TNY_HEADER_GET_IFACE (self)->set_user_flag(self, name);
+
+	return;
+}
+
+/**
+ * tny_header_unset_user_flag:
+ * @self: a #TnyHeader
+ * @name: name of the flag to unset
+ * 
+ * Set as %FALSE (not set) the user flag with name @name. This is
+ * the same as removing the flag.
+ *
+ * since: 1.0
+ * audience: application-developer
+ **/
+void 
+tny_header_unset_user_flag (TnyHeader *self, const gchar *name)
+{
+#ifdef DBC /* require */
+	g_assert (TNY_IS_HEADER (self));
+	g_assert (TNY_HEADER_GET_IFACE (self)->unset_user_flag!= NULL);
+#endif
+
+	TNY_HEADER_GET_IFACE (self)->unset_user_flag(self, name);
+
+	return;
+}
+
+/**
+ * tny_header_get_user_flag:
+ * @self: a #TnyHeader
+ * @name: name of the flag
+ * 
+ * Get if a user flag with name @name is set.
+ *
+ * Returns: %TRUE if flag is set, %FALSE otherwise
+ *
+ * since: 1.0
+ * audience: application-developer
+ **/
+gboolean 
+tny_header_get_user_flag (TnyHeader *self, const gchar *name)
+{
+#ifdef DBC /* require */
+	g_assert (TNY_IS_HEADER (self));
+	g_assert (TNY_HEADER_GET_IFACE (self)->get_user_flag!= NULL);
+#endif
+
+	return TNY_HEADER_GET_IFACE (self)->get_user_flag(self, name);
+}
+
+/**
  * tny_header_get_priority:
  * @self: a #TnyHeader
  * 
@@ -610,6 +680,26 @@ tny_header_unset_flag (TnyHeader *self, TnyHeaderFlags mask)
 	return;
 }
 
+/**
+ * tny_header_support_user_flags:
+ * @self: a #TnyHeader
+ *
+ * Tells if user flags are supported in this header. It depends mostly on the
+ * provider implementation.
+ *
+ * since: 1.0
+ * audience: application-developer
+ **/
+TnyHeaderSupportFlags
+tny_header_support_user_flags (TnyHeader *self)
+{
+#ifdef DBC /* require */
+	g_assert (TNY_IS_HEADER (self));
+	g_assert (TNY_HEADER_GET_IFACE (self)->support_user_flags!= NULL);
+#endif
+
+	return TNY_HEADER_GET_IFACE (self)->support_user_flags (self);
+}
 
 static void
 tny_header_base_init (gpointer g_class)
@@ -694,3 +784,34 @@ tny_header_flags_get_type (void)
 	g_once (&once, tny_header_flags_register_type, NULL);
 	return GPOINTER_TO_UINT (once.retval);
 }
+
+static gpointer
+tny_header_support_flags_register_type (gpointer notused)
+{
+	GType etype = 0;
+	static const GFlagsValue values[] = {
+		{ TNY_HEADER_SUPPORT_FLAGS_NONE, "TNY_HEADER_SUPPORT_FLAGS_NONE", "none" },
+		{ TNY_HEADER_SUPPORT_FLAGS_ANY, "TNY_HEADER_SUPPORT_FLAGS_ANY", "any" },
+		{ TNY_HEADER_SUPPORT_FLAGS_SOME, "TNY_HEADER_SUPPORT_FLAGS_SOME", "some" },
+		{ TNY_HEADER_SUPPORT_PERSISTENT_FLAGS_ANY, "TNY_HEADER_SUPPORT_PERSISTENT_FLAGS_ANY", "persistent_any" },
+		{ TNY_HEADER_SUPPORT_PERSISTENT_FLAGS_SOME, "TNY_HEADER_SUPPORT_PERSISTENT_FLAGS_SOME", "persistent_some" },
+		{ 0, NULL, NULL }
+	};
+	etype = g_flags_register_static ("TnyHeaderSupportFlags", values);
+	return GUINT_TO_POINTER (etype);
+}
+
+/**
+ * tny_header_support_flags_get_type:
+ *
+ * GType system helper function
+ *
+ * returns: a #GType
+ **/
+GType
+tny_header_support_flags_get_type (void)
+{
+	static GOnce once = G_ONCE_INIT;
+	g_once (&once, tny_header_support_flags_register_type, NULL);
+	return GPOINTER_TO_UINT (once.retval);
+}
diff --git a/libtinymail/tny-header.h b/libtinymail/tny-header.h
index ddd73a3..ea078fd 100644
--- a/libtinymail/tny-header.h
+++ b/libtinymail/tny-header.h
@@ -44,6 +44,7 @@ G_BEGIN_DECLS
 #define TNY_HEADER_GET_IFACE(inst)  (G_TYPE_INSTANCE_GET_INTERFACE ((inst), TNY_TYPE_HEADER, TnyHeaderIface))
 
 #define TNY_TYPE_HEADER_FLAGS (tny_header_flags_get_type())
+#define TNY_TYPE_HEADER_SUPPORT_FLAGS (tny_header_support_flags_get_type ())
 
 #ifndef TNY_SHARED_H
 typedef struct _TnyHeader TnyHeader;
@@ -70,6 +71,14 @@ typedef enum
 
 #define TNY_HEADER_FLAG_PRIORITY_MASK (1<<9|1<<10)
 
+typedef enum
+{
+	TNY_HEADER_SUPPORT_FLAGS_NONE = 0,
+	TNY_HEADER_SUPPORT_FLAGS_ANY = 1<<0,
+	TNY_HEADER_SUPPORT_FLAGS_SOME = 1<<1,
+	TNY_HEADER_SUPPORT_PERSISTENT_FLAGS_ANY = 1<<2,
+	TNY_HEADER_SUPPORT_PERSISTENT_FLAGS_SOME = 1<<3,
+} TnyHeaderSupportFlags;
 
 struct _TnyHeaderIface
 {
@@ -96,10 +105,15 @@ struct _TnyHeaderIface
 	TnyHeaderFlags (*get_flags) (TnyHeader *self);
 	void (*set_flag) (TnyHeader *self, TnyHeaderFlags mask);
 	void (*unset_flag) (TnyHeader *self, TnyHeaderFlags mask);
+	gboolean (*get_user_flag) (TnyHeader *self, const gchar *id);
+	void (*set_user_flag) (TnyHeader *self, const gchar *id);
+	void (*unset_user_flag) (TnyHeader *self, const gchar *id);
+	TnyHeaderSupportFlags (*support_user_flags) (TnyHeader *self);
 };
 
 GType tny_header_get_type (void);
 GType tny_header_flags_get_type (void);
+GType tny_header_support_flags_get_type (void);
 
 gchar* tny_header_dup_uid (TnyHeader *self);
 gchar* tny_header_dup_bcc (TnyHeader *self);
@@ -122,6 +136,10 @@ TnyFolder* tny_header_get_folder (TnyHeader *self);
 TnyHeaderFlags tny_header_get_flags (TnyHeader *self);
 void tny_header_set_flag (TnyHeader *self, TnyHeaderFlags mask);
 void tny_header_unset_flag (TnyHeader *self, TnyHeaderFlags mask);
+void tny_header_set_user_flag (TnyHeader *self, const gchar *name);
+void tny_header_unset_user_flag (TnyHeader *self, const gchar *name);
+gboolean tny_header_get_user_flag (TnyHeader *self, const gchar *name);
+TnyHeaderSupportFlags tny_header_support_user_flags (TnyHeader *self);
 
 TnyHeaderFlags tny_header_get_priority (TnyHeader *self);
 void tny_header_set_priority (TnyHeader *self, TnyHeaderFlags priority);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]