[evolution-kolab/ek-wip-porting] EBookBackendKolab: ported old 2.30 code over to 3.3.x
- From: Christian Hilberg <chilberg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-kolab/ek-wip-porting] EBookBackendKolab: ported old 2.30 code over to 3.3.x
- Date: Sun, 18 Mar 2012 17:08:02 +0000 (UTC)
commit b9e1bea116dc1ddc5c65db42dd28f149475f8e93
Author: Christian Hilberg <hilberg kernelconcepts de>
Date: Sun Mar 18 18:06:52 2012 +0100
EBookBackendKolab: ported old 2.30 code over to 3.3.x
* fixed the old contacts API code for building
with 3.3.x
* display of contacts objects works again
* more fixups needed
src/addressbook/e-book-backend-kolab.c | 405 +++++++++++++++++++-------------
1 files changed, 241 insertions(+), 164 deletions(-)
---
diff --git a/src/addressbook/e-book-backend-kolab.c b/src/addressbook/e-book-backend-kolab.c
index e3942f6..42a6bb8 100644
--- a/src/addressbook/e-book-backend-kolab.c
+++ b/src/addressbook/e-book-backend-kolab.c
@@ -144,7 +144,7 @@ book_backend_kolab_signal_online_cb (GObject *object)
}
static gboolean
-book_backend_kolab_notify_open (EBookBackendKolab *self,
+book_backend_kolab_notify_opened (EBookBackendKolab *self,
GError **err)
{
EBookBackend *bbackend = NULL;
@@ -165,11 +165,25 @@ book_backend_kolab_notify_open (EBookBackendKolab *self,
}
e_book_backend_notify_online (bbackend,
tmp_mode = KOLAB_MAIL_ACCESS_OPMODE_ONLINE ? TRUE : FALSE);
+ e_book_backend_notify_readonly (bbackend, FALSE);
e_book_backend_notify_opened (bbackend, NULL);
return TRUE;
}
+static void
+book_backend_kolab_notify_removed (EBookBackendKolab *self)
+{
+ EBookBackend *bbackend = NULL;
+
+ g_assert (E_IS_BOOK_BACKEND_KOLAB (self));
+
+ bbackend = E_BOOK_BACKEND (self);
+
+ e_book_backend_notify_readonly (bbackend, TRUE);
+ e_book_backend_notify_online (bbackend, FALSE);
+}
+
/*----------------------------------------------------------------------------*/
/* class functions */
@@ -304,7 +318,7 @@ e_book_backend_kolab_open (EBookBackendSync *backend,
g_error_free (tmp_err);
return;
}
- ok = book_backend_kolab_notify_open (self, &tmp_err);
+ ok = book_backend_kolab_notify_opened (self, &tmp_err);
if (! ok) {
kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
g_error_free (tmp_err);
@@ -443,10 +457,9 @@ e_book_backend_kolab_remove (EBookBackendSync *backend,
e_book_backend_notify_writable (E_BOOK_BACKEND (backend), FALSE);
e_book_backend_notify_connection_status (E_BOOK_BACKEND (backend), FALSE);
e_book_backend_set_is_loaded (E_BOOK_BACKEND (backend), FALSE);
-
- return GNOME_Evolution_Addressbook_Success;
#endif /* FIXME*/
+ book_backend_kolab_notify_removed (self);
}
static void
@@ -466,7 +479,7 @@ e_book_backend_kolab_refresh (EBookBackendSync *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- g_error ("%s: FIXME implement me", __func__);
+ g_warning ("%s: FIXME implement me", __func__);
}
#if 0 /* probably not needed */
@@ -533,6 +546,11 @@ e_book_backend_kolab_create_contacts (EBookBackendSync *backend,
{
EBookBackendKolab *self = NULL;
EBookBackendKolabPrivate *priv = NULL;
+ EContact *econtact = NULL;
+ const GSList *it = NULL;
+ const gchar *vcard = NULL;
+ gboolean ok = FALSE;
+ GError *tmp_err = NULL;
g_return_if_fail (error == NULL || *error == NULL);
e_return_data_book_error_if_fail (E_IS_BOOK_BACKEND_KOLAB (backend), E_DATA_BOOK_STATUS_INVALID_ARG);
@@ -544,50 +562,45 @@ e_book_backend_kolab_create_contacts (EBookBackendSync *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- g_error ("%s: FIXME implement me", __func__);
-
-#if 0 /* FIXME old */
- g_debug ("%s()[%u] called.", __func__, __LINE__);
+ for (it = vcards; it != NULL; it = g_slist_next (it)) {
+ vcard = (const gchar *) it->data;
+ econtact = e_contact_new_from_vcard (vcard);
+ if (econtact == NULL) {
+ g_warning ("%s()[%u] error creating contact from vcard:\n%s",
+ __func__, __LINE__, vcard);
+ tmp_err = e_data_book_create_error (E_DATA_BOOK_STATUS_OTHER_ERROR, NULL);
+ goto exit;
+ }
- *contact = e_contact_new_from_vcard (vcard);
- if (*contact == NULL) {
- g_warning ("%s()[%u] error creating contact from vcard:\n%s",
- __func__, __LINE__, vcard);
- return GNOME_Evolution_Addressbook_OtherError;
+ ok = kolab_util_contact_cache_assure_uid_on_econtact (priv->book_cache,
+ priv->book_koma,
+ econtact,
+ priv->book_uri,
+ FALSE,
+ cancellable,
+ &tmp_err);
+ if (! ok)
+ goto exit;
+
+ ok = kolab_util_contact_store (econtact,
+ priv->book_koma,
+ priv->book_uri,
+ cancellable,
+ &tmp_err);
+ if (! ok)
+ goto exit;
+
+ *added_contacts = g_slist_append (*added_contacts, econtact);
}
- kolab_util_contact_cache_assure_uid_on_econtact (priv->book_cache,
- priv->book_koma,
- priv->book_uri,
- *contact,
- FALSE,
- &error);
- if (error != NULL) {
- status = kolab_util_contact_map_error (error);
- g_warning ("%s()[%u]: %s.",
- __func__, __LINE__, error->message);
- g_error_free (error);
- g_object_unref (*contact);
- *contact = NULL;
- return status;
- }
+ exit:
- kolab_util_contact_store (*contact,
- priv->book_koma,
- priv->book_uri,
- &error);
- if (error != NULL) {
- status = kolab_util_contact_map_error (error);
- g_warning ("%s()[%u]: %s",
- __func__, __LINE__, error->message);
- g_error_free (error);
- g_object_unref (*contact);
- *contact = NULL;
- return status;
+ if (tmp_err != NULL) {
+ if (econtact != NULL)
+ g_object_unref (econtact);
+ kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
}
-
- return GNOME_Evolution_Addressbook_Success;
-#endif /* FIXME */
}
static void
@@ -600,6 +613,10 @@ e_book_backend_kolab_remove_contacts (EBookBackendSync *backend,
{
EBookBackendKolab *self = NULL;
EBookBackendKolabPrivate *priv = NULL;
+ const GSList *it = NULL;
+ gchar *sourcename = NULL;
+ gboolean ok = FALSE;
+ GError *tmp_err = NULL;
g_return_if_fail (error == NULL || *error == NULL);
e_return_data_book_error_if_fail (E_IS_BOOK_BACKEND_KOLAB (backend), E_DATA_BOOK_STATUS_INVALID_ARG);
@@ -611,26 +628,34 @@ e_book_backend_kolab_remove_contacts (EBookBackendSync *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- g_error ("%s: FIXME implement me", __func__);
-
-#if 0 /* FIXME old */
- g_debug ("%s()[%u] called.", __func__, __LINE__);
sourcename = kolab_util_backend_get_relative_path_from_uri (priv->book_uri);
- for (it = g_list_first (id_list); it != NULL; it = g_list_next (it)) {
- gchar *uid = it->data;
- ok = kolab_mail_access_delete_by_uid (priv->book_koma, uid, sourcename, &error);
- if (error != NULL) {
- g_warning ("%s()[%u]: %s", __func__, __LINE__, error->message);
- g_error_free (error);
- error = NULL;
- } else {
- *removed_ids = g_list_append (*removed_ids, g_strdup(uid));
+
+ for (it = id_list; it != NULL; it = g_slist_next (it)) {
+ const gchar *uid = it->data;
+ ok = kolab_mail_access_delete_by_uid (priv->book_koma,
+ uid,
+ sourcename,
+ cancellable,
+ &tmp_err);
+ if (! ok) {
+ if (tmp_err->code != KOLAB_BACKEND_ERROR_NOTFOUND)
+ goto exit;
+
+ g_warning ("%s()[%u]: %s", __func__, __LINE__, tmp_err->message);
+ g_error_free (tmp_err);
+ tmp_err = NULL;
}
+
+ *removed_ids = g_slist_append (*removed_ids, g_strdup(uid));
}
+
+ exit:
g_free (sourcename);
- return GNOME_Evolution_Addressbook_Success;
-#endif /* FIXME */
+ if (tmp_err != NULL) {
+ kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ }
}
static void
@@ -643,6 +668,11 @@ e_book_backend_kolab_modify_contacts (EBookBackendSync *backend,
{
EBookBackendKolab *self = NULL;
EBookBackendKolabPrivate *priv = NULL;
+ EContact *econtact = NULL;
+ const GSList *it = NULL;
+ const gchar *vcard = NULL;
+ gboolean ok = FALSE;
+ GError *tmp_err = NULL;
g_return_if_fail (error == NULL || *error == NULL);
e_return_data_book_error_if_fail (E_IS_BOOK_BACKEND_KOLAB (backend), E_DATA_BOOK_STATUS_INVALID_ARG);
@@ -654,29 +684,35 @@ e_book_backend_kolab_modify_contacts (EBookBackendSync *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- g_error ("%s: FIXME implement me", __func__);
+ for (it = vcards; it != NULL; it = g_slist_next (vcards)) {
+ vcard = (const gchar *) it->data;
+ econtact = e_contact_new_from_vcard (vcard);
+ if (econtact == NULL) {
+ g_warning ("%s()[%u] error creating contact from vcard:\n%s",
+ __func__, __LINE__, vcard);
+ tmp_err = e_data_book_create_error (E_DATA_BOOK_STATUS_OTHER_ERROR, NULL);
+ goto exit;
+ }
-#if 0 /* FIXME old */
- g_debug ("%s()[%u] called.", __func__, __LINE__);
+ ok = kolab_util_contact_store (econtact,
+ priv->book_koma,
+ priv->book_uri,
+ cancellable,
+ &tmp_err);
+ if (! ok)
+ goto exit;
- *contact = e_contact_new_from_vcard (vcard);
- if (*contact == NULL) {
- g_warning ("%s()[%u] error creating contact from vcard:\n%s", __func__, __LINE__, vcard);
- return GNOME_Evolution_Addressbook_OtherError;
+ *modified_contacts = g_slist_append (*modified_contacts,
+ econtact);
}
- kolab_util_contact_store (*contact, priv->book_koma, priv->book_uri, &error);
- if (error != NULL) {
- status = kolab_util_contact_map_error (error);
- g_warning ("%s()[%u]: %s", __func__, __LINE__, error->message);
- g_error_free (error);
- g_object_unref (*contact);
- *contact = NULL;
- return status;
+ exit:
+ if (tmp_err != NULL) {
+ if (econtact != NULL)
+ g_object_unref (econtact);
+ kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
}
-
- return GNOME_Evolution_Addressbook_Success;
-#endif /* FIXME */
}
static void
@@ -689,6 +725,8 @@ e_book_backend_kolab_get_contact (EBookBackendSync *backend,
{
EBookBackendKolab *self = NULL;
EBookBackendKolabPrivate *priv = NULL;
+ EContact *econtact = NULL;
+ GError *tmp_err = NULL;
g_return_if_fail (error == NULL || *error == NULL);
e_return_data_book_error_if_fail (E_IS_BOOK_BACKEND_KOLAB (backend), E_DATA_BOOK_STATUS_INVALID_ARG);
@@ -700,31 +738,24 @@ e_book_backend_kolab_get_contact (EBookBackendSync *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- g_error ("%s: FIXME implement me", __func__);
-
-#if 0 /* FIXME old */
g_debug ("%s()[%u] called.", __func__, __LINE__);
econtact = kolab_util_contact_cache_get_object (priv->book_cache,
priv->book_koma,
priv->book_uri,
- id, FALSE,
- &error);
- if (error != NULL) {
- status = kolab_util_contact_map_error (error);
- g_warning ("%s()[%u]: %s",
- __func__, __LINE__, error->message);
- g_error_free (error);
- *vcard = NULL;
- return status;
+ id,
+ FALSE,
+ cancellable,
+ &tmp_err);
+ if (tmp_err != NULL) {
+ kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ return;
}
+
*vcard = e_vcard_to_string (E_VCARD (econtact),
EVC_FORMAT_VCARD_30);
-
g_object_unref (econtact);
-
- return GNOME_Evolution_Addressbook_Success;
-#endif /* FIXME */
}
static void
@@ -737,6 +768,10 @@ e_book_backend_kolab_get_contact_list (EBookBackendSync *backend,
{
EBookBackendKolab *self = NULL;
EBookBackendKolabPrivate *priv = NULL;
+ GList *econtact_list = NULL;
+ GList *it = NULL;
+ gboolean ok = FALSE;
+ GError *tmp_err = NULL;
g_return_if_fail (error == NULL || *error == NULL);
e_return_data_book_error_if_fail (E_IS_BOOK_BACKEND_KOLAB (backend), E_DATA_BOOK_STATUS_INVALID_ARG);
@@ -748,43 +783,44 @@ e_book_backend_kolab_get_contact_list (EBookBackendSync *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- g_error ("%s: FIXME implement me", __func__);
-
-#if 0 /* FIXME old */
g_debug ("%s()[%u] called.", __func__, __LINE__);
g_debug (" + query: %s", query);
/* Update the cache to contain all data requested. */
- kolab_util_contact_cache_update_on_query (priv->book_cache,
- priv->book_koma,
- query,
- priv->book_uri);
+ ok = kolab_util_contact_cache_update_on_query (priv->book_cache,
+ priv->book_koma,
+ query,
+ priv->book_uri,
+ cancellable,
+ &tmp_err);
+ if (! ok) {
+ kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ return;
+ }
+
/* Fetch information from BackendCache */;
econtact_list = kolab_util_contact_cache_get_contacts (priv->book_cache,
priv->book_koma,
query,
priv->book_uri,
- &error);
- if (error != NULL) {
- status = kolab_util_contact_map_error (error);
- g_warning ("%s()[%u]: %s",
- __func__, __LINE__, error->message);
- g_error_free (error);
- *contacts = NULL;
- return status;
+ cancellable,
+ &tmp_err);
+ if (tmp_err != NULL) {
+ kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ return;
}
- for (it = g_list_first (econtact_list); it != NULL; it = g_list_next (it)) {
+
+ for (it = econtact_list; it != NULL; it = g_list_next (it)) {
EContact *econtact = it->data;
gchar *vcard = e_vcard_to_string (E_VCARD (econtact),
EVC_FORMAT_VCARD_30);
- *contacts = g_list_append (*contacts, vcard);
+ *contacts = g_slist_append (*contacts, vcard);
g_object_unref (econtact);
}
g_list_free (econtact_list);
-
- return GNOME_Evolution_Addressbook_Success;
-#endif /* FIXME */
}
static void
@@ -797,6 +833,10 @@ e_book_backend_kolab_get_contact_list_uids (EBookBackendSync *backend,
{
EBookBackendKolab *self = NULL;
EBookBackendKolabPrivate *priv = NULL;
+ GList *econtact_list = NULL;
+ GList *it = NULL;
+ gboolean ok = FALSE;
+ GError *tmp_err = NULL;
g_return_if_fail (error == NULL || *error == NULL);
e_return_data_book_error_if_fail (E_IS_BOOK_BACKEND_KOLAB (backend), E_DATA_BOOK_STATUS_INVALID_ARG);
@@ -808,7 +848,54 @@ e_book_backend_kolab_get_contact_list_uids (EBookBackendSync *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- g_error ("%s: FIXME implement me", __func__);
+ /* TODO This function currently works the same way as
+ * e_book_backend_kolab_get_contact_list, since
+ * we need to update the local cache information
+ * when querying UIDs from KolabMailAccess.
+ *
+ * Once this is issue is resolved, we can simply
+ * query the KolabMailAccess instance for UIDs,
+ * which is a far less i/o intensive operation
+ * than actually querying the EContact objects
+ * (the latter involves reading Kolab mail data
+ * from the disk cache and conversion to EContact)
+ */
+
+ /* Update the cache to contain all data requested. */
+ ok = kolab_util_contact_cache_update_on_query (priv->book_cache,
+ priv->book_koma,
+ query,
+ priv->book_uri,
+ cancellable,
+ &tmp_err);
+ if (! ok) {
+ kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ return;
+ }
+
+ /* Fetch information from BackendCache */;
+ econtact_list = kolab_util_contact_cache_get_contacts (priv->book_cache,
+ priv->book_koma,
+ query,
+ priv->book_uri,
+ cancellable,
+ &tmp_err);
+ if (tmp_err != NULL) {
+ kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ return;
+ }
+
+ for (it = econtact_list; it != NULL; it = g_list_next (it)) {
+ EContact *econtact = it->data;
+ gchar *uid = e_contact_get (econtact,
+ E_CONTACT_UID);
+ *contacts_uids = g_slist_append (*contacts_uids, uid);
+ g_object_unref (econtact);
+ }
+
+ g_list_free (econtact_list);
}
static void
@@ -882,7 +969,7 @@ e_book_backend_kolab_authenticate_user (EBookBackendSync *backend,
return;
}
- ok = book_backend_kolab_notify_open (self, &tmp_err);
+ ok = book_backend_kolab_notify_opened (self, &tmp_err);
if (! ok) {
kolab_util_contact_err_to_edb_err (error, tmp_err, __func__, __LINE__);
g_error_free (tmp_err);
@@ -939,6 +1026,12 @@ e_book_backend_kolab_start_book_view (EBookBackend *backend,
{
EBookBackendKolab *self = NULL;
EBookBackendKolabPrivate *priv = NULL;
+ GList *econtact_list = NULL;
+ GList *it = NULL;
+ gchar *query = NULL;
+ gboolean ok = NULL;
+ GError *tmp_err = NULL;
+ GError *notify_err = NULL;
g_return_if_fail (E_IS_BOOK_BACKEND_KOLAB (backend));
g_return_if_fail (E_IS_DATA_BOOK_VIEW (book_view));
@@ -946,65 +1039,48 @@ e_book_backend_kolab_start_book_view (EBookBackend *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- g_error ("%s: FIXME implement me", __func__);
-
-#if 0 /* FIXME old */
- g_debug ("%s()[%u] called.", __func__, __LINE__);
- /* This should not be necessary, if everything works as expected,
- * ..._start_book_view () will not be issued, if the KoMA was not
- * configured correctly.
- */
- koma_mode = kolab_mail_access_get_opmode (priv->book_koma, &error);
- if (error != NULL) {
- g_warning ("%s()[%u]: %s", __func__, __LINE__, error->message);
- g_error_free (error);
- error = NULL;
- }
- if (koma_mode < KOLAB_MAIL_ACCESS_OPMODE_OFFLINE) {
- g_error ("%s()[%u]: %s called while the KolabMailAccess was "
- "not ready! Should not happen, forcing exit.",
- __func__, __LINE__, __func__);
- }
- if ((koma_mode < KOLAB_MAIL_ACCESS_OPMODE_ONLINE) &&
- (priv->book_mode == GNOME_Evolution_Addressbook_MODE_REMOTE)) {
- g_warning ("%s()[%u]: %s called before authentication took place. "
- "Requesting auth now.",
- __func__, __LINE__, __func__);
- e_book_backend_notify_auth_required (backend);
- return;
- }
-
query = e_data_book_view_get_card_query (book_view);
+
/* First update the BackendCache to the current situation. */
- kolab_util_contact_cache_update_on_query (priv->book_cache,
- priv->book_koma,
- query,
- priv->book_uri);
- /* econtact_list = e_book_backend_cache_get_contacts (priv->book_cache, query); */
+ ok = kolab_util_contact_cache_update_on_query (priv->book_cache,
+ priv->book_koma,
+ query,
+ priv->book_uri,
+ NULL, /* FIXME GCancellable */
+ &tmp_err);
+ if (! ok)
+ goto exit;
+
econtact_list = kolab_util_contact_cache_get_contacts (priv->book_cache,
priv->book_koma,
query,
priv->book_uri,
- &error);
- if (error != NULL) {
- g_warning ("%s()[%u]: %s",
- __func__, __LINE__, error->message);
- g_error_free (error);
- error = NULL;
- }
+ NULL, /* FIXME GCancellable */
+ &tmp_err);
+ if (tmp_err != NULL)
+ goto exit;
+
/* Then deliver requests from there. */
- for (it = g_list_first (econtact_list); it != NULL; it = g_list_next (it)) {
+ for (it = econtact_list; it != NULL; it = g_list_next (it)) {
EContact *econtact = it->data;
e_data_book_view_notify_update (book_view, econtact);
- g_object_unref (econtact);
}
- g_list_free (econtact_list);
- g_free (sourcename);
+ exit:
+ if (query != NULL)
+ g_free (query);
- e_data_book_view_notify_complete (book_view,
- GNOME_Evolution_Addressbook_Success);
-#endif /* FIXME */
+ if (econtact_list != NULL)
+ g_list_free_full (econtact_list, g_object_unref);
+
+ if (tmp_err != NULL) {
+ kolab_util_contact_err_to_edb_err (¬ify_err, tmp_err, __func__, __LINE__);
+ g_error_free (tmp_err);
+ }
+
+ e_data_book_view_notify_complete (book_view, notify_err);
+ if (notify_err != NULL)
+ g_error_free (notify_err);
}
static void
@@ -1020,7 +1096,8 @@ e_book_backend_kolab_stop_book_view (EBookBackend *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- g_error ("%s: FIXME implement me", __func__);
+ g_warning ("%s: FIXME implement me", __func__);
+ e_data_book_view_notify_complete (book_view, NULL);
}
static void
@@ -1036,7 +1113,7 @@ e_book_backend_kolab_notify_update (EBookBackend *backend,
self = E_BOOK_BACKEND_KOLAB (backend);
priv = E_BOOK_BACKEND_KOLAB_PRIVATE (self);
- g_error ("%s: FIXME implement me", __func__);
+ g_warning ("%s: FIXME implement me", __func__);
}
/*----------------------------------------------------------------------------*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]