[bijiben] VJOURNAL: initial support
- From: Pierre-Yves Luyten <pyluyten src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [bijiben] VJOURNAL: initial support
- Date: Sun, 27 Apr 2014 09:34:30 +0000 (UTC)
commit 20b0c6dbb85b2b56835c9cb9551a679af7814b21
Author: Pierre-Yves Luyten <py luyten fr>
Date: Tue Apr 22 00:38:15 2014 +0200
VJOURNAL: initial support
See #728581
- VJOURNAL ("memos") notes from evolution accounts are
automatically shown
- They appear on the bottom (date is not handled)
User can amend notes.
- Categories is not supported yet
- A crash occurs if an Ical is set as default storage
and new notes is asked.
Because it is not implemented.
- Saving note does not damage attachments and so on
configure.ac | 6 +-
src/bjb-bijiben.c | 50 +++-
src/libbiji/Makefile.am | 4 +
src/libbiji/biji-manager.c | 16 +-
src/libbiji/biji-manager.h | 13 +-
src/libbiji/biji-note-obj.c | 9 +-
src/libbiji/biji-note-obj.h | 33 ++
src/libbiji/editor/biji-webkit-editor.c | 2 +-
src/libbiji/provider/biji-memo-note.c | 432 ++++++++++++++++++++
src/libbiji/provider/biji-memo-note.h | 71 ++++
src/libbiji/provider/biji-memo-provider.c | 590 ++++++++++++++++++++++++++++
src/libbiji/provider/biji-memo-provider.h | 72 ++++
src/libbiji/provider/biji-own-cloud-note.c | 2 +-
13 files changed, 1293 insertions(+), 7 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 0e15a92..274d64e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -58,15 +58,19 @@ AM_PROG_LIBTOOL
GLIB_REQUIRED_VERSION=2.28
GTK_REQUIRED_VERSION=3.11.4
+
PKG_CHECK_MODULES([TRACKER], [tracker-sparql-1.0], [sparql_version="tracker-sparql-1.0"],
[PKG_CHECK_MODULES([TRACKER], [tracker-sparql-0.18], [sparql_version="tracker-sparql-0.18"])
])
PKG_CHECK_MODULES(BIJIBEN,
- [ gio-unix-2.0
+ [ evolution-calendar-3.0
+ evolution-data-server-1.2
+ gio-unix-2.0
glib-2.0 >= $GLIB_REQUIRED_VERSION
goa-1.0
gtk+-3.0 >= $GTK_REQUIRED_VERSION
+ libecal-1.2
libxml-2.0
$sparql_version
uuid
diff --git a/src/bjb-bijiben.c b/src/bjb-bijiben.c
index 51a924a..8209bc2 100644
--- a/src/bjb-bijiben.c
+++ b/src/bjb-bijiben.c
@@ -20,6 +20,9 @@
#include <glib/gi18n.h>
#include <stdlib.h>
+#include <libedataserver/libedataserver.h> /* ESourceRegistry */
+#include <libecal/libecal.h> /* ECalClient */
+
#include <libbiji/libbiji.h>
@@ -293,6 +296,50 @@ on_client_got (GObject *source_object,
g_list_free (accounts);
}
+
+
+
+
+/*
+ * Currently bjb checks eds accounts
+ * and asks libbiji about them.
+ * This, in case we want a setting
+ * Another way might be to let libbiji live its life
+ */
+void
+on_registry_got (GObject *obj,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error;
+ ESourceRegistry *registry;
+ GList *list, *l;
+ Bijiben *self = BIJIBEN_APPLICATION (user_data);
+
+ error = NULL;
+ registry = e_source_registry_new_finish (res, &error);
+
+ if (error)
+ {
+ g_warning ("no registry :(, %s", error->message);
+ return;
+ }
+
+ list = e_source_registry_list_sources (registry, E_SOURCE_EXTENSION_MEMO_LIST);
+ for (l=list; l!= NULL; l=l->next)
+ {
+ biji_manager_add_e_source_extension_memo (self->priv->manager, l->data);
+ }
+
+ g_list_free_full (list, g_object_unref);
+}
+
+
+
+
+
+
+
static void
bijiben_startup (GApplication *application)
{
@@ -348,8 +395,9 @@ bijiben_startup (GApplication *application)
if (error)
goto out;
- /* Goa */
+ /* Goa, e-d-s */
goa_client_new (NULL, on_client_got, self); // cancellable
+ e_source_registry_new (NULL, on_registry_got, self);
/* Automatic imports on startup */
diff --git a/src/libbiji/Makefile.am b/src/libbiji/Makefile.am
index 80434f6..685bf82 100644
--- a/src/libbiji/Makefile.am
+++ b/src/libbiji/Makefile.am
@@ -72,6 +72,10 @@ libbiji_la_SOURCES = \
provider/biji-local-note.h \
provider/biji-local-provider.c \
provider/biji-local-provider.h \
+ provider/biji-memo-note.c \
+ provider/biji-memo-note.h \
+ provider/biji-memo-provider.c \
+ provider/biji-memo-provider.h \
provider/biji-own-cloud-note.c \
provider/biji-own-cloud-note.h \
provider/biji-own-cloud-provider.c \
diff --git a/src/libbiji/biji-manager.c b/src/libbiji/biji-manager.c
index 76b4b62..e9d76d1 100644
--- a/src/libbiji/biji-manager.c
+++ b/src/libbiji/biji-manager.c
@@ -24,6 +24,7 @@
#include "provider/biji-import-provider.h"
#include "provider/biji-local-provider.h"
+#include "provider/biji-memo-provider.h"
#include "provider/biji-own-cloud-provider.h"
@@ -525,11 +526,24 @@ _add_provider (BijiManager *self,
info = biji_provider_get_info (provider);
g_hash_table_insert (self->priv->providers, (gpointer) info->unique_id, provider);
- g_signal_connect (provider, "loaded",
+ g_signal_connect (provider, "loaded",
G_CALLBACK (on_provider_loaded_cb), self);
}
+
+
+void
+biji_manager_add_e_source_extension_memo (BijiManager *self,
+ ESource *source)
+{
+ BijiProvider *provider = NULL;
+
+ provider = biji_memo_provider_new (self, source);
+ _add_provider (self, provider);
+}
+
+
void
biji_manager_add_goa_object (BijiManager *self,
GoaObject *object)
diff --git a/src/libbiji/biji-manager.h b/src/libbiji/biji-manager.h
index 164671c..ac23b2b 100644
--- a/src/libbiji/biji-manager.h
+++ b/src/libbiji/biji-manager.h
@@ -11,9 +11,14 @@
#include "biji-info-set.h"
#include "biji-note-obj.h"
+
+#include <libedataserver/libedataserver.h> /* ESourceRegistry */
+
#define GOA_API_IS_SUBJECT_TO_CHANGE
#include <goa/goa.h>
+
+
G_BEGIN_DECLS
/* The flag tells if view should reload the whole model or not */
@@ -62,7 +67,7 @@ struct _BijiManager
-GType biji_manager_get_type (void) G_GNUC_CONST;
+GType biji_manager_get_type (void) G_GNUC_CONST;
@@ -76,6 +81,12 @@ void biji_manager_import_uri (BijiManager *manager,
gchar *uri);
+
+void biji_manager_add_e_source_extension_memo
+ (BijiManager *self,
+ ESource *source);
+
+
void biji_manager_add_goa_object (BijiManager *manager,
GoaObject *object);
diff --git a/src/libbiji/biji-note-obj.c b/src/libbiji/biji-note-obj.c
index 5aa6f42..c4c8733 100644
--- a/src/libbiji/biji-note-obj.c
+++ b/src/libbiji/biji-note-obj.c
@@ -825,7 +825,14 @@ html_from_plain_text (gchar *content)
NULL);
retval = g_strconcat ("<html xmlns=\"http://www.w3.org/1999/xhtml\">",
- "<body>", escaped, "</body></html>", NULL);
+ "<body contenteditable='true' id='editable'>",
+ "<script type='text/javascript'>",
+ " window.onload = function () {",
+ " document.getElementById('editable').focus();",
+ " };",
+ "</script>",
+ escaped,
+ "</body></html>", NULL);
g_free (escaped);
return retval;
diff --git a/src/libbiji/biji-note-obj.h b/src/libbiji/biji-note-obj.h
index 6df6059..03010b2 100644
--- a/src/libbiji/biji-note-obj.h
+++ b/src/libbiji/biji-note-obj.h
@@ -57,14 +57,47 @@ struct _BijiNoteObjClass
BijiItemClass parent_class;
gchar* (*get_basename) (BijiNoteObj *note);
+
+ /*
+ * Mandatory. Provide the latest note html.
+ * Use html_from_plain_text if needed. */
gchar* (*get_html) (BijiNoteObj *note);
+
+ /*
+ * Mandatory. When editor amends html, assign it */
void (*set_html) (BijiNoteObj *note, gchar *html);
+
+ /*
+ * Mandatory. Store the note. This might be async. */
void (*save_note) (BijiNoteObj *note);
+
+ /*
+ * Mandatory
+ * Move the note to trash bin. What to do depends on the provider
+ * Return FALSE is this fails.
+ * If the provider does not support trash,
+ * you should delete the note */
gboolean (*archive) (BijiNoteObj *note);
+
+ /*
+ * Mandatory
+ * Return TRUE if the note is marked as trashed in any way
+ * (depending on the provider)
+ *
+ * Return FALSE if the note is note trashed.
+ *
+ * If the provider does not suport this, return FALSE */
gboolean (*is_trashed) (BijiNoteObj *note);
+
+ /*
+ * Mandatory
+ * Return TRUE if the note can store rich text:
+ * - bold, italic, srike
+ */
gboolean (*can_format) (BijiNoteObj *note);
};
+
struct _BijiNoteObj
{
BijiItem parent_instance;
diff --git a/src/libbiji/editor/biji-webkit-editor.c b/src/libbiji/editor/biji-webkit-editor.c
index 50487ed..7718107 100644
--- a/src/libbiji/editor/biji-webkit-editor.c
+++ b/src/libbiji/editor/biji-webkit-editor.c
@@ -274,7 +274,7 @@ on_content_changed (WebKitWebView *view)
{
gchar *title;
gchar *unique_title;
-
+
title = rows[0];
if (g_strcmp0 (title, biji_item_get_title (BIJI_ITEM (note))) != 0)
diff --git a/src/libbiji/provider/biji-memo-note.c b/src/libbiji/provider/biji-memo-note.c
new file mode 100644
index 0000000..dac17b5
--- /dev/null
+++ b/src/libbiji/provider/biji-memo-note.c
@@ -0,0 +1,432 @@
+/* bjb-memo-note.c
+ * Copyright (C) Pierre-Yves LUYTEN 2014 <py luyten fr>
+ *
+ * bijiben is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bijiben is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+
+#include "biji-memo-provider.h"
+#include "biji-memo-note.h"
+
+struct _BijiMemoNotePrivate
+{
+ BijiProvider *provider;
+ ECalComponent *ecal;
+ ECalClient *client;
+ gchar *description;
+ BijiNoteID *id;
+};
+
+
+G_DEFINE_TYPE (BijiMemoNote, biji_memo_note, BIJI_TYPE_NOTE_OBJ);
+
+
+/* Properties */
+enum {
+ PROP_0,
+ PROP_ECAL,
+ MEMO_NOTE_PROP
+};
+
+
+static GParamSpec *properties[MEMO_NOTE_PROP] = { NULL, };
+
+
+
+/* Function from evo calendar gui comp-util.c (LGPL)
+ * to be removed if we depen on evo,
+ * the func is borrowed as is (=3.13.1) */
+gboolean
+cal_comp_is_on_server (ECalComponent *comp,
+ ECalClient *client)
+{
+ const gchar *uid;
+ gchar *rid = NULL;
+ icalcomponent *icalcomp = NULL;
+ GError *error = NULL;
+
+ g_return_val_if_fail (comp != NULL, FALSE);
+ g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
+
+ /* See if the component is on the server. If it is not, then it likely
+ * means that the appointment is new, only in the day view, and we
+ * haven't added it yet to the server. In that case, we don't need to
+ * confirm and we can just delete the event. Otherwise, we ask
+ * the user.
+ */
+ e_cal_component_get_uid (comp, &uid);
+
+ /* TODO We should not be checking for this here. But since
+ * e_cal_util_construct_instance does not create the instances
+ * of all day events, so we default to old behaviour. */
+ if (e_cal_client_check_recurrences_no_master (client))
+ {
+ rid = e_cal_component_get_recurid_as_string (comp);
+ }
+
+ e_cal_client_get_object_sync (
+ client, uid, rid, &icalcomp, NULL, &error);
+
+ if (icalcomp != NULL)
+ {
+ icalcomponent_free (icalcomp);
+ g_free (rid);
+
+ return TRUE;
+ }
+
+ if (!g_error_matches (error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND))
+ g_warning (G_STRLOC ": %s", error->message);
+
+ g_clear_error (&error);
+ g_free (rid);
+
+ return FALSE;
+}
+
+
+
+/*
+ * Parse current note content to update ECalComponent
+ *
+ * "clone" properties we do not change remain as "comp"
+ * This is true for attachments, too.
+ *
+ * Comments refer to where evolution 3.13.1 does the same.
+ */
+static void
+fill_in_components (ECalComponent *comp,
+ ECalComponent *clone,
+ BijiMemoNote *self)
+{
+ ECalComponentText text;
+ GSList l;
+
+
+ /* ----------------- FIELDS FROM "memo_page_fill_components"------------------ */
+
+
+ /* Set : title */
+ text.value = biji_item_get_title (BIJI_ITEM (self));
+ text.altrep = NULL;
+ e_cal_component_set_summary (clone, &text);
+
+ /* Set : content */
+ text.value = biji_note_obj_get_raw_text (BIJI_NOTE_OBJ (self));
+ text.altrep = NULL;
+ l.data = &text;
+ l.next = NULL;
+ e_cal_component_set_description_list (clone, &l);
+
+
+ /* dtstart : we'd rather use "created", "modified" */
+
+ /* Classification :? */
+
+
+ /* Categories : to be implemented */
+
+ /* Recipients : do not touch this */
+ /* Organizer : do not touch this */
+
+
+ /* ------------- FIELDS FROM "save_comp" in comp-editor.c ------- */
+
+ /* Attachment list */
+
+
+ /* rdate, rrule, exdate, exrule */
+
+ /* Sequence */
+
+
+ /* X-EVOLUTION-OPTIONS-DELAY */
+
+
+ /* -------------- OHER FILEDS (from specification) -------
+ * FIXME: some of theme belong somewhere above....
+ *
+ * Unique: created / description / dtstamp / last-mod / recurid / status / url /
+ * Several: attach / attendee / comment / contact / related / rstatus / x-prop
+ */
+}
+
+
+
+/*
+ * https://git.gnome.org/browse/evolution/tree/calendar/gui/dialogs/comp-editor.c#n471
+ */
+static void
+memo_note_save (BijiNoteObj *note)
+{
+ BijiMemoNote *self = BIJI_MEMO_NOTE (note);
+ BijiMemoNotePrivate *priv = self->priv;
+ const gchar *orig_uid;
+ icalcomponent *icalcomp;
+ gboolean result;
+ GError *error;
+ ECalComponent *clone;
+ //gchar *orig_uid_copy;
+
+ clone = e_cal_component_clone (priv->ecal);
+ fill_in_components (priv->ecal, clone, self);
+
+ /* Save */
+ e_cal_component_commit_sequence (clone);
+ g_object_unref (priv->ecal);
+ priv->ecal = clone;
+
+ e_cal_component_get_uid (priv->ecal, &orig_uid);
+
+ /* Make a copy of it, because call of e_cal_create_object()
+ * rewrites the internal uid.
+ orig_uid_copy = g_strdup (orig_uid); */
+ icalcomp = e_cal_component_get_icalcomponent (priv->ecal);
+
+
+ if (!cal_comp_is_on_server (priv->ecal, priv->client))
+ {
+ gchar *uid = NULL;
+ result = e_cal_client_create_object_sync (
+ priv->client, icalcomp, &uid, NULL, &error);
+ if (result)
+ {
+ icalcomponent_set_uid (icalcomp, uid);
+ g_free (uid);
+ //g_signal_emit_by_name (editor, "object_created");
+ }
+ }
+
+ else
+ {
+ result = e_cal_client_modify_object_sync (
+ priv->client, icalcomp, E_CAL_OBJ_MOD_THIS, NULL, &error);
+ e_cal_component_commit_sequence (clone);
+ }
+}
+
+
+/* Save title when saving note.
+ * No need to do anything here */
+static void
+on_title_changed_cb (BijiMemoNote *self)
+{
+}
+
+
+
+static void
+biji_memo_note_constructed (GObject *obj)
+{
+ BijiMemoNote *self = BIJI_MEMO_NOTE (obj);
+
+ G_OBJECT_CLASS (biji_memo_note_parent_class)->constructed (obj);
+
+ g_signal_connect_swapped (self->priv->id, "notify::title",
+ G_CALLBACK (on_title_changed_cb), self);
+}
+
+
+static void
+biji_memo_note_init (BijiMemoNote *biji_memo_note)
+{
+ biji_memo_note->priv = G_TYPE_INSTANCE_GET_PRIVATE (biji_memo_note, BIJI_TYPE_MEMO_NOTE,
BijiMemoNotePrivate);
+
+}
+
+
+
+/* Let the provider finalize the ECalComponent. */
+static void
+biji_memo_note_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (biji_memo_note_parent_class)->finalize (object);
+}
+
+
+
+
+static void
+biji_memo_note_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ BijiMemoNote *self = BIJI_MEMO_NOTE (object);
+
+
+ switch (property_id)
+ {
+ case PROP_ECAL:
+ self->priv->ecal = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+biji_memo_note_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ BijiMemoNote *self = BIJI_MEMO_NOTE (object);
+
+ switch (property_id)
+ {
+ case PROP_ECAL:
+ g_value_set_object (value, self->priv->ecal);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+
+static void
+memo_set_html (BijiNoteObj *note, gchar *html)
+{
+ /* NULL */
+}
+
+
+
+static gboolean
+memo_delete (BijiNoteObj *note)
+{
+ g_warning ("delete is not implemented yet");
+
+ return FALSE;
+}
+
+
+static gchar *
+memo_get_html (BijiNoteObj *note)
+{
+ // we cast but the func should expect a const gchar, really
+ return html_from_plain_text ((gchar*) biji_note_obj_get_raw_text (note));
+}
+
+
+
+static const gchar *
+memo_get_place (BijiItem *item)
+{
+ BijiMemoNote *self;
+ const BijiProviderInfo *info;
+
+ self = BIJI_MEMO_NOTE (item);
+ info = biji_provider_get_info (BIJI_PROVIDER (self->priv->provider));
+
+ return info->name;
+}
+
+
+
+static gboolean
+item_no (BijiItem * item)
+{
+ return FALSE;
+}
+
+
+static gboolean
+note_no (BijiNoteObj *item)
+{
+ return FALSE;
+}
+
+
+static void
+biji_memo_note_class_init (BijiMemoNoteClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ BijiItemClass *item_class;
+ BijiNoteObjClass *note_class;
+
+ item_class = BIJI_ITEM_CLASS (klass);
+ note_class = BIJI_NOTE_OBJ_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (BijiMemoNotePrivate));
+
+ object_class->finalize = biji_memo_note_finalize;
+ object_class->constructed = biji_memo_note_constructed;
+ object_class->get_property = biji_memo_note_get_property;
+ object_class->set_property = biji_memo_note_set_property;
+
+ item_class->is_collectable = item_no;
+ item_class->has_color = item_no;
+ item_class->get_place = memo_get_place;
+
+ note_class->get_basename = NULL;
+ note_class->get_html = memo_get_html;
+ note_class->set_html = memo_set_html;
+ note_class->save_note = memo_note_save;
+ note_class->can_format = note_no;
+ note_class->archive = memo_delete;
+ note_class->is_trashed = note_no;
+
+ properties[PROP_ECAL] =
+ g_param_spec_object("ecal",
+ "ECalComponent",
+ "ECalComponent which this note refers to",
+ E_TYPE_CAL_COMPONENT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+ g_object_class_install_properties (object_class, MEMO_NOTE_PROP, properties);
+}
+
+
+
+
+
+
+/*
+ * The provider looks for a content ("description")
+ * in order to push to tracker.
+ *
+ */
+BijiNoteObj *
+biji_memo_note_new_from_info (BijiMemoProvider *provider,
+ BijiManager *manager,
+ BijiInfoSet *info,
+ ECalComponent *component,
+ gchar *description,
+ ECalClient *client)
+{
+ BijiNoteID *id;
+ BijiMemoNote *ret;
+
+ id = biji_note_id_new_from_info (info);
+
+ ret = g_object_new (BIJI_TYPE_MEMO_NOTE,
+ "manager", manager,
+ "id", id,
+ "ecal", component,
+ NULL);
+
+ ret->priv->id = id;
+ ret->priv->provider = BIJI_PROVIDER (provider);
+ ret->priv->description = description;
+ ret->priv->client = client;
+ return BIJI_NOTE_OBJ (ret);
+}
diff --git a/src/libbiji/provider/biji-memo-note.h b/src/libbiji/provider/biji-memo-note.h
new file mode 100644
index 0000000..3055e2e
--- /dev/null
+++ b/src/libbiji/provider/biji-memo-note.h
@@ -0,0 +1,71 @@
+/* bjb-memo-note.h
+ * Copyright (C) Pierre-Yves LUYTEN 2014 <py luyten fr>
+ *
+ * bijiben is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bijiben is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _BIJI_MEMO_NOTE_H_
+#define _BIJI_MEMO_NOTE_H_ 1
+
+#include <libecal/libecal.h> /* ECalClient */
+
+#include "biji-tracker.h"
+#include "biji-note-id.h"
+#include "biji-note-obj.h"
+
+
+G_BEGIN_DECLS
+
+#define BIJI_TYPE_MEMO_NOTE (biji_memo_note_get_type ())
+#define BIJI_MEMO_NOTE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BIJI_TYPE_MEMO_NOTE,
BijiMemoNote))
+#define BIJI_MEMO_NOTE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BIJI_TYPE_MEMO_NOTE,
BijiMemoNoteClass))
+#define BIJI_IS_MEMO_NOTE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BIJI_TYPE_MEMO_NOTE))
+#define BIJI_IS_MEMO_NOTE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BIJI_TYPE_MEMO_NOTE))
+#define BIJI_MEMO_NOTE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BIJI_TYPE_MEMO_NOTE,
BijiMemoNoteClass))
+
+typedef struct _BijiMemoNoteClass BijiMemoNoteClass;
+typedef struct _BijiMemoNote BijiMemoNote;
+typedef struct _BijiMemoNotePrivate BijiMemoNotePrivate;
+
+
+struct _BijiMemoNote
+{
+ BijiNoteObj parent_instance;
+
+ BijiMemoNotePrivate *priv;
+};
+
+
+struct _BijiMemoNoteClass
+{
+ BijiNoteObjClass parent_class;
+};
+
+
+
+GType biji_memo_note_get_type (void) G_GNUC_CONST;
+
+
+BijiNoteObj *biji_memo_note_new_from_info (BijiMemoProvider *provider,
+ BijiManager *manager,
+ BijiInfoSet *info,
+ ECalComponent *comp,
+ gchar *description,
+ ECalClient *client);
+
+
+G_END_DECLS
+
+#endif /* _BIJI_MEMO_NOTE_H_ */
+
diff --git a/src/libbiji/provider/biji-memo-provider.c b/src/libbiji/provider/biji-memo-provider.c
new file mode 100644
index 0000000..ddc2190
--- /dev/null
+++ b/src/libbiji/provider/biji-memo-provider.c
@@ -0,0 +1,590 @@
+/*
+ * biji-memo-provider.c
+ * Copyright (C) Pierre-Yves LUYTEN 2013 <py luyten fr>
+ *
+ * bijiben is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bijiben is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/*
+ * http://tools.ietf.org/html/rfc2445
+ *
+ * Evolution UI offers to sync Memo to local computer
+ * TODO: check this
+ */
+
+
+#include <libecal/libecal.h> /* ECalClient */
+
+#include "biji-memo-provider.h"
+#include "biji-memo-note.h"
+
+
+#define MINER_ID "gn:memo:miner:fd48e15b-2460-4761-a7be-942616102fa6"
+
+struct _BijiMemoProviderPrivate
+{
+ BijiProviderInfo info;
+ ESource *source;
+ ECalClient *client;
+
+ /* Startup */
+ GSList *memos;
+ GHashTable *tracker;
+ GHashTable *items;
+ GHashTable *archives;
+ GQueue *queue;
+};
+
+
+
+
+G_DEFINE_TYPE (BijiMemoProvider, biji_memo_provider, BIJI_TYPE_PROVIDER);
+
+
+/* Properties */
+enum {
+ PROP_0,
+ PROP_SOURCE,
+ BIJI_MEMO_PROP
+};
+
+
+
+static GParamSpec *properties[BIJI_MEMO_PROP] = { NULL, };
+
+/* Memos */
+
+
+typedef struct
+{
+ ECalComponent *ecal;
+ BijiMemoProvider *self;
+ BijiInfoSet set;
+} BijiMemoItem;
+
+
+
+static BijiMemoItem *
+memo_item_new (BijiMemoProvider *self)
+{
+ BijiMemoItem *item;
+
+ item = g_slice_new (BijiMemoItem);
+ item->ecal = NULL;
+ item->self = self;
+
+ item->set.content = NULL;
+ item->set.mtime = 0;
+ item->set.created = 0;
+ item->set.title = NULL;
+ item->set.url = NULL;
+
+ return item;
+}
+
+
+/* ECalComponent do not transfer much values */
+static void
+memo_item_free (BijiMemoItem *item)
+{
+ g_free (item->set.content);
+ g_slice_free (BijiMemoItem, item);
+}
+
+
+
+/* No color, hence we use default color */
+
+static void
+create_note_from_item (BijiMemoItem *item)
+{
+ BijiNoteObj *note;
+ GdkRGBA color;
+ BijiManager *manager;
+
+ manager = biji_provider_get_manager (BIJI_PROVIDER (item->self));
+ note = biji_memo_note_new_from_info (item->self,
+ manager,
+ &item->set,
+ item->ecal,
+ item->set.content,
+ item->self->priv->client);
+
+ biji_manager_get_default_color (manager, &color);
+ biji_note_obj_set_rgba (note, &color);
+ g_hash_table_replace (item->self->priv->items,
+ item->set.url,
+ note);
+}
+
+
+
+static void
+trash (gpointer urn_uuid, gpointer self)
+{
+ biji_tracker_trash_ressource (
+ biji_provider_get_manager (BIJI_PROVIDER (self)), (gchar*) urn_uuid);
+}
+
+
+static void
+handle_next_item (BijiMemoProvider *self)
+{
+ BijiMemoProviderPrivate *priv = self->priv;
+ BijiMemoItem *item;
+ GList *list;
+
+ item = g_queue_pop_head (self->priv->queue);
+
+ if (item != NULL)
+ {
+ g_hash_table_remove (priv->tracker, item->set.url);
+
+ create_note_from_item (item);
+ /* debug pour tracker. Il faut en plus datasource->urn */
+ g_debug ("created=%li", item->set.created);
+ g_debug ("title=%s", item->set.title);
+ g_debug ("url=%s", item->set.url);
+ g_debug ("content=%s\n================\n\n\n", item->set.content);
+
+ biji_tracker_ensure_ressource_from_info (
+ biji_provider_get_manager (BIJI_PROVIDER (self)), &item->set);
+
+ //memo_item_free (item);
+ handle_next_item (self);
+ }
+
+
+ /* Loading and notes creation over. Provide notes to manager */
+ else
+ {
+ /* Post load tracker db clean-up */
+ list = g_hash_table_get_values (self->priv->tracker);
+ g_list_foreach (list, trash, self);
+ g_list_free (list);
+
+ /* Now simply provide data to controller */
+ list = g_hash_table_get_values (self->priv->items);
+ BIJI_PROVIDER_GET_CLASS (self)->notify_loaded (BIJI_PROVIDER (self), list, BIJI_LIVING_ITEMS);
+ g_list_free (list);
+ }
+}
+
+
+
+static void
+on_object_list_got (GObject *obj,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GSList *l, *desc, *ll;
+ GError *error;
+ BijiMemoProvider *self = BIJI_MEMO_PROVIDER (user_data);
+
+ error = NULL;
+ e_cal_client_get_object_list_finish (self->priv->client,
+ res,
+ &self->priv->memos,
+ &error);
+
+ if (error)
+ {
+ g_warning ("e cal get obj list fin %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+/*
+ * ECALCOMPONENT
+ * uid, categories, created (or dtstart), last modified,
+ * summary,
+ *
+ * but the tricky part is description,
+ * since ical says as-many-descriptions-as-you-want
+ * while we need a single content.
+ * Let's start with something simple: take the last
+ * description we find.
+ *
+ * e_cal_component_free_******
+ *
+ */
+
+
+/*
+
+void e_cal_client_get_timezone (ECalClient *client,
+ const gchar *tzid,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+*/
+
+ for (l=self->priv->memos; l!=NULL; l=l->next)
+ {
+ ECalComponent *co; /* Memo */
+ ECalComponentText text;
+ const gchar *uid;
+ BijiMemoItem *item;
+ icaltimetype *t;
+ gchar *iso;
+ //GTimeVal time = {0;0};
+ //gint64 sec;
+
+ item = memo_item_new (self);
+ item->set.datasource_urn = g_strdup (self->priv->info.datasource);
+ co = item->ecal = e_cal_component_new_from_icalcomponent (l->data);
+
+#ifdef FALSE
+//iso8601 => g_time_val.tv_sec
+struct icaltimetype
+{
+int year; /**< Actual year, e.g. 2001. */
+int month; /**< 1 (Jan) to 12 (Dec). */
+int day;
+int hour;
+int minute;
+int second;
+int is_utc; /**< 1-> time is in UTC timezone */
+int is_date; /**< 1 -> interpret this as date. */
+int is_daylight; /**< 1 -> time is in daylight savings time. */
+const icaltimezone *zone; /**< timezone */
+};
+#endif
+
+ e_cal_component_get_summary (co, &text);
+ item->set.title = g_strdup (text.value);
+ e_cal_component_get_uid (co, &uid);
+ item->set.url = g_strdup (uid);
+
+ /* Set url contains timezone. Not the-right-thing-to-do however */
+
+ // time: we expect something like time.tv_sec (sec since)
+ e_cal_component_get_last_modified (co, &t); // or dtstart
+//gchar * isodate_from_time_t (time_t t);
+
+ iso = g_strdup_printf ("%i-%i-%iT%i:%i:%i",
+ t->year,
+ t->month,
+ t->day,
+ t->hour,
+ t->minute,
+ t->second);
+ g_warning ("iso=%s", iso);
+
+ item->set.mtime = 0;
+ e_cal_component_free_icaltimetype (t);
+ e_cal_component_get_created (co, &t); // or dtstart
+ item->set.created = 0;
+ e_cal_component_free_icaltimetype (t);
+
+ e_cal_component_get_description_list (co, &desc);
+ for (ll=desc; ll!=NULL; ll=ll->next)
+ {
+ ECalComponentText *txt = ll->data;
+
+ if (txt->value != NULL)
+ {
+ //g_warning ("txt value got: memo %s has\n %s\n====", item->set.title, txt->value);
+ item->set.content = g_strdup (txt->value);
+ break;
+ }
+ }
+
+ if (item->set.content == NULL)
+ g_warning ("note %s has no content", item->set.title);
+
+
+ e_cal_component_free_text_list (desc);
+ g_queue_push_head (self->priv->queue, item);
+ }
+
+ handle_next_item (self);
+}
+
+
+
+
+static gchar *
+i_want_all_memos (void)
+{
+ g_warning ("FIXME: memo provider query is wrong");
+/*
+ return "occur-in-time-range? "
+ "(make-time \"19000101T204153Z\") "
+ "(make-time \"22220202T204153Z\")";*/
+ return "occur-in-time-range? (make-time \"20110421T204153Z\") (make-time \"20140423T232416Z\")";
+}
+
+
+
+/* Stock all existing urn-uuid. Then parse files */
+static void
+on_notes_mined (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ BijiMemoProvider *self;
+ TrackerSparqlConnection *connect;
+ TrackerSparqlCursor *cursor;
+ GError *error;
+
+ self = user_data;
+ connect = TRACKER_SPARQL_CONNECTION (source_object);
+ error = NULL;
+ cursor = tracker_sparql_connection_query_finish (connect, res, &error);
+
+ if (error)
+ {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+
+ if (cursor)
+ {
+ while (tracker_sparql_cursor_next (cursor, NULL, NULL))
+ {
+ g_hash_table_insert (self->priv->tracker,
+ g_strdup (tracker_sparql_cursor_get_string (cursor, 0, NULL)),
+ g_strdup (tracker_sparql_cursor_get_string (cursor, 1, NULL)));
+
+ }
+ }
+
+ e_cal_client_get_object_list (self->priv->client,
+ i_want_all_memos(), /* sexp, not null */
+ NULL, /* Cancellable */
+ on_object_list_got,
+ self);
+}
+
+
+/*
+ * Once the client is connected,
+ * mine notes for this.
+ */
+static void
+on_client_connected (GObject *obj,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error;
+ error = NULL;
+ gchar *query;
+ BijiMemoProvider *self = BIJI_MEMO_PROVIDER (user_data);
+
+ e_cal_client_connect_finish (res, &error);
+
+ if (error)
+ {
+ g_warning ("On Client Connected : %s", error->message);
+ return;
+ }
+
+ self->priv->client = E_CAL_CLIENT (obj);
+
+ g_warning ("datasource=%s", self->priv->info.datasource);
+ query = g_strdup_printf ("SELECT ?url ?urn WHERE {?urn a nfo:Note; "
+ " nie:dataSource '%s' ; nie:url ?url}",
+ self->priv->info.datasource);
+
+ tracker_sparql_connection_query_async (
+ biji_manager_get_tracker_connection (
+ biji_provider_get_manager (BIJI_PROVIDER (self))),
+ query,
+ NULL,
+ on_notes_mined,
+ self);
+
+ g_free (query);
+}
+
+
+/* GObject */
+
+
+/*
+ * TODO : implement the icon. At least some color
+
+hint : Default value: "#becedd" > this is hex, AFAIM we want GdkRGBA
+const gchar * e_source_selectable_get_color (ESourceSelectable *extension);
+
+ GObject
+ +----ESourceExtension
+ +----ESourceBackend
+ +----ESourceSelectable
+ +----ESourceCalendar
+ +----ESourceMemoList
+ +----ESourceTaskList
+
+*/
+
+static void
+biji_memo_provider_constructed (GObject *obj)
+{
+ BijiMemoProvider *self;
+ BijiMemoProviderPrivate *priv;
+
+ G_OBJECT_CLASS (biji_memo_provider_parent_class)->constructed (obj);
+
+ self = BIJI_MEMO_PROVIDER (obj);
+ priv = self->priv;
+
+ /* Info */
+ priv->info.unique_id = e_source_get_uid (priv->source);
+ priv->info.datasource = g_strdup_printf ("memo:%s",
+ priv->info.unique_id);
+ priv->info.name = g_strdup (e_source_get_display_name (priv->source));
+ priv->info.icon =
+ gtk_image_new_from_icon_name ("user-home", GTK_ICON_SIZE_INVALID);
+ gtk_image_set_pixel_size (GTK_IMAGE (priv->info.icon), 48);
+ g_object_ref (priv->info.icon);
+
+ e_cal_client_connect (self->priv->source,
+ E_CAL_CLIENT_SOURCE_TYPE_MEMOS,
+ NULL, /* cancel */
+ on_client_connected,
+ self);
+}
+
+
+
+/*
+
+
+void e_cal_client_create_object (ECalClient *client,
+ icalcomponent *icalcomp,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean e_cal_client_create_object_finish (ECalClient *client,
+ GAsyncResult *result,
+ gchar **out_uid,
+ GError **error);
+
+*/
+
+
+
+static void
+biji_memo_provider_init (BijiMemoProvider *self)
+{
+ BijiMemoProviderPrivate *priv;
+
+ priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, BIJI_TYPE_MEMO_PROVIDER, BijiMemoProviderPrivate);
+
+ priv->queue = g_queue_new ();
+ priv->items = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ priv->tracker = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ priv->memos = NULL;
+
+}
+
+static void
+biji_memo_provider_finalize (GObject *object)
+{
+ e_cal_client_free_icalcomp_slist (BIJI_MEMO_PROVIDER (object)->priv->memos);
+
+ G_OBJECT_CLASS (biji_memo_provider_parent_class)->finalize (object);
+}
+
+
+
+static void
+biji_memo_provider_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ BijiMemoProvider *self = BIJI_MEMO_PROVIDER (object);
+
+
+ switch (property_id)
+ {
+ case PROP_SOURCE:
+ self->priv->source = g_value_get_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void
+biji_memo_provider_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ BijiMemoProvider *self = BIJI_MEMO_PROVIDER (object);
+
+ switch (property_id)
+ {
+ case PROP_SOURCE:
+ g_value_set_object (value, self->priv->source);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+
+const BijiProviderInfo *
+memo_provider_get_info (BijiProvider *provider)
+{
+ return &(BIJI_MEMO_PROVIDER (provider)->priv->info);
+}
+
+
+static void
+biji_memo_provider_class_init (BijiMemoProviderClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+ BijiProviderClass *provider_class = BIJI_PROVIDER_CLASS (klass);
+
+ object_class->finalize = biji_memo_provider_finalize;
+ object_class->constructed = biji_memo_provider_constructed;
+ object_class->get_property = biji_memo_provider_get_property;
+ object_class->set_property = biji_memo_provider_set_property;
+
+ provider_class->get_info = memo_provider_get_info;
+ provider_class->create_new_note = NULL;
+ provider_class->create_note_full = NULL;
+
+ properties[PROP_SOURCE] =
+ g_param_spec_object ("source",
+ "Provider ESource",
+ "ESource Memo associated to Provider",
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+ g_object_class_install_properties (object_class, BIJI_MEMO_PROP, properties);
+
+ g_type_class_add_private (klass, sizeof (BijiMemoProviderPrivate));
+}
+
+
+
+BijiProvider *
+biji_memo_provider_new (BijiManager *manager,
+ ESource *source)
+{
+ return g_object_new (BIJI_TYPE_MEMO_PROVIDER,
+ "manager", manager,
+ "source", source,
+ NULL);
+}
diff --git a/src/libbiji/provider/biji-memo-provider.h b/src/libbiji/provider/biji-memo-provider.h
new file mode 100644
index 0000000..e9e9f49
--- /dev/null
+++ b/src/libbiji/provider/biji-memo-provider.h
@@ -0,0 +1,72 @@
+/*
+ * biji-memo-provider.h
+ * Copyright (C) Pierre-Yves LUYTEN 2014 <py luyten fr>
+ *
+ * bijiben is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * bijiben is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _BIJI_MEMO_PROVIDER_H_
+#define _BIJI_MEMO_PROVIDER_H_ 1
+
+
+#include <libedataserver/libedataserver.h> /* ESourceRegistry */
+//#include <libecal/libecal.h> /* ECalClient */
+
+#include "../biji-manager.h"
+#include "biji-provider.h"
+
+
+
+G_BEGIN_DECLS
+
+#define BIJI_TYPE_MEMO_PROVIDER (biji_memo_provider_get_type ())
+#define BIJI_MEMO_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BIJI_TYPE_MEMO_PROVIDER,
BijiMemoProvider))
+#define BIJI_MEMO_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BIJI_TYPE_MEMO_PROVIDER,
BijiMemoProviderClass))
+#define BIJI_IS_MEMO_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BIJI_TYPE_MEMO_PROVIDER))
+#define BIJI_IS_MEMO_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BIJI_TYPE_MEMO_PROVIDER))
+#define BIJI_MEMO_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BIJI_TYPE_MEMO_PROVIDER,
BijiMemoProviderClass))
+
+typedef struct _BijiMemoProviderClass BijiMemoProviderClass;
+typedef struct _BijiMemoProvider BijiMemoProvider;
+typedef struct _BijiMemoProviderPrivate BijiMemoProviderPrivate;
+
+
+
+
+struct _BijiMemoProvider
+{
+ BijiProvider parent_instance;
+ BijiMemoProviderPrivate *priv;
+};
+
+
+
+struct _BijiMemoProviderClass
+{
+ BijiProviderClass parent_class;
+};
+
+
+
+GType biji_memo_provider_get_type (void) G_GNUC_CONST;
+
+
+BijiProvider *biji_memo_provider_new (BijiManager *manager,
+ ESource *source);
+
+
+G_END_DECLS
+
+#endif /* _BIJI_MEMO_PROVIDER_H_ */
+
diff --git a/src/libbiji/provider/biji-own-cloud-note.c b/src/libbiji/provider/biji-own-cloud-note.c
index 0eb5d04..2491961 100644
--- a/src/libbiji/provider/biji-own-cloud-note.c
+++ b/src/libbiji/provider/biji-own-cloud-note.c
@@ -403,7 +403,7 @@ BijiNoteObj *biji_own_cloud_note_new_from_info (BijiOwnCloudPro
uuid_generate (unique);
uuid_unparse_lower (unique, out);
-
+
info->url = g_strdup_printf ("%s/%s.txt",
biji_own_cloud_provider_get_readable_path (prov),
out);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]