evolution-data-server r9877 - in branches/camel-gobject: . addressbook addressbook/backends/file addressbook/backends/google addressbook/backends/groupwise addressbook/backends/vcf addressbook/libebook addressbook/libedata-book calendar calendar/backends calendar/backends/caldav calendar/backends/http calendar/backends/weather calendar/libecal camel camel/providers/groupwise camel/providers/imap camel/providers/local camel/providers/pop3 docs/reference/addressbook/libebook/tmpl docs/reference/addressbook/libedata-book docs/reference/addressbook/libedata-book/tmpl docs/reference/calendar/libecal docs/reference/calendar/libecal/tmpl docs/reference/calendar/libedata-cal docs/reference/camel docs/reference/libedataserverui docs/reference/libedataserverui/tmpl libedataserver libedataserverui po servers/exchange servers/exchange/lib servers/groupwise
- From: mbarnes svn gnome org
- To: svn-commits-list gnome org
- Subject: evolution-data-server r9877 - in branches/camel-gobject: . addressbook addressbook/backends/file addressbook/backends/google addressbook/backends/groupwise addressbook/backends/vcf addressbook/libebook addressbook/libedata-book calendar calendar/backends calendar/backends/caldav calendar/backends/http calendar/backends/weather calendar/libecal camel camel/providers/groupwise camel/providers/imap camel/providers/local camel/providers/pop3 docs/reference/addressbook/libebook/tmpl docs/reference/addressbook/libedata-book docs/reference/addressbook/libedata-book/tmpl docs/reference/calendar/libecal docs/reference/calendar/libecal/tmpl docs/reference/calendar/libedata-cal docs/reference/camel docs/reference/libedataserverui docs/reference/libedataserverui/tmpl libedataserver libedataserverui po servers/exchange servers/exchange/lib servers/groupwise
- Date: Tue, 6 Jan 2009 01:56:50 +0000 (UTC)
Author: mbarnes
Date: Tue Jan 6 01:56:50 2009
New Revision: 9877
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=9877&view=rev
Log:
Merge revisions 9745:9876 from trunk.
Added:
branches/camel-gobject/libedataserverui/e-category-completion.c
- copied unchanged from r9876, /trunk/libedataserverui/e-category-completion.c
branches/camel-gobject/libedataserverui/e-category-completion.h
- copied unchanged from r9876, /trunk/libedataserverui/e-category-completion.h
branches/camel-gobject/libedataserverui/test-category-completion.c
- copied unchanged from r9876, /trunk/libedataserverui/test-category-completion.c
Modified:
branches/camel-gobject/ (props changed)
branches/camel-gobject/ChangeLog
branches/camel-gobject/NEWS
branches/camel-gobject/addressbook/ChangeLog
branches/camel-gobject/addressbook/backends/file/e-book-backend-file.c
branches/camel-gobject/addressbook/backends/google/e-book-backend-google.c
branches/camel-gobject/addressbook/backends/groupwise/e-book-backend-groupwise.c
branches/camel-gobject/addressbook/backends/vcf/e-book-backend-vcf.c
branches/camel-gobject/addressbook/libebook/e-contact.c
branches/camel-gobject/addressbook/libebook/e-contact.h
branches/camel-gobject/addressbook/libebook/e-vcard.c
branches/camel-gobject/addressbook/libebook/e-vcard.h
branches/camel-gobject/addressbook/libedata-book/e-book-backend-db-cache.c
branches/camel-gobject/addressbook/libedata-book/e-book-backend-db-cache.h
branches/camel-gobject/addressbook/libedata-book/e-book-backend-sexp.c
branches/camel-gobject/addressbook/libedata-book/e-book-backend.c
branches/camel-gobject/addressbook/libedata-book/e-data-book-view.c
branches/camel-gobject/calendar/ChangeLog
branches/camel-gobject/calendar/backends/Makefile.am
branches/camel-gobject/calendar/backends/caldav/e-cal-backend-caldav-factory.c
branches/camel-gobject/calendar/backends/caldav/e-cal-backend-caldav.c
branches/camel-gobject/calendar/backends/http/e-cal-backend-http.c
branches/camel-gobject/calendar/backends/weather/Locations.xml.in
branches/camel-gobject/calendar/backends/weather/Makefile.am
branches/camel-gobject/calendar/backends/weather/e-cal-backend-weather.c
branches/camel-gobject/calendar/backends/weather/e-weather-source-ccf.c
branches/camel-gobject/calendar/backends/weather/e-weather-source-ccf.h
branches/camel-gobject/calendar/backends/weather/e-weather-source.c
branches/camel-gobject/calendar/backends/weather/e-weather-source.h
branches/camel-gobject/calendar/libecal/e-cal-util.h
branches/camel-gobject/calendar/libecal/e-cal.c
branches/camel-gobject/camel/ChangeLog
branches/camel-gobject/camel/camel-db.c
branches/camel-gobject/camel/camel-db.h
branches/camel-gobject/camel/camel-folder-summary.c
branches/camel-gobject/camel/camel-folder-summary.h
branches/camel-gobject/camel/camel-folder.c
branches/camel-gobject/camel/camel-mime-utils.c
branches/camel-gobject/camel/camel-object.h
branches/camel-gobject/camel/camel-private.h
branches/camel-gobject/camel/camel-search-sql-sexp.c
branches/camel-gobject/camel/camel-store-summary.h
branches/camel-gobject/camel/camel-store.c
branches/camel-gobject/camel/camel-store.h
branches/camel-gobject/camel/camel-utf8.c
branches/camel-gobject/camel/camel-utf8.h
branches/camel-gobject/camel/camel-vee-folder.c
branches/camel-gobject/camel/camel-vee-summary.c
branches/camel-gobject/camel/camel-vtrash-folder.c
branches/camel-gobject/camel/providers/groupwise/ChangeLog
branches/camel-gobject/camel/providers/groupwise/camel-groupwise-folder.c
branches/camel-gobject/camel/providers/groupwise/camel-groupwise-provider.c
branches/camel-gobject/camel/providers/groupwise/camel-groupwise-store.c
branches/camel-gobject/camel/providers/imap/ChangeLog
branches/camel-gobject/camel/providers/imap/camel-imap-folder.c
branches/camel-gobject/camel/providers/imap/camel-imap-journal.c
branches/camel-gobject/camel/providers/imap/camel-imap-store.c
branches/camel-gobject/camel/providers/imap/camel-imap-summary.c
branches/camel-gobject/camel/providers/local/camel-local-folder.c
branches/camel-gobject/camel/providers/pop3/ChangeLog
branches/camel-gobject/camel/providers/pop3/camel-pop3-store.c
branches/camel-gobject/configure.in
branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-contact.sgml
branches/camel-gobject/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
branches/camel-gobject/docs/reference/addressbook/libedata-book/tmpl/e-book-backend-db-cache.sgml
branches/camel-gobject/docs/reference/calendar/libecal/libecal-sections.txt
branches/camel-gobject/docs/reference/calendar/libecal/tmpl/e-cal-util.sgml
branches/camel-gobject/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt
branches/camel-gobject/docs/reference/camel/camel-docs.sgml
branches/camel-gobject/docs/reference/camel/camel-sections.txt
branches/camel-gobject/docs/reference/libedataserverui/libedataserverui-sections.txt
branches/camel-gobject/docs/reference/libedataserverui/tmpl/e-data-server-ui-marshal.sgml
branches/camel-gobject/docs/reference/libedataserverui/tmpl/e-source-selector.sgml
branches/camel-gobject/evolution-data-server-zip.in
branches/camel-gobject/libedataserver/e-sexp.c
branches/camel-gobject/libedataserver/e-source.c
branches/camel-gobject/libedataserver/e-url.c
branches/camel-gobject/libedataserverui/ChangeLog
branches/camel-gobject/libedataserverui/Makefile.am
branches/camel-gobject/libedataserverui/e-categories-dialog.c
branches/camel-gobject/libedataserverui/e-contact-store.c
branches/camel-gobject/libedataserverui/e-data-server-ui-marshal.list
branches/camel-gobject/libedataserverui/e-source-selector.c
branches/camel-gobject/libedataserverui/e-source-selector.h
branches/camel-gobject/po/ChangeLog
branches/camel-gobject/po/es.po
branches/camel-gobject/po/hu.po
branches/camel-gobject/po/it.po
branches/camel-gobject/po/nb.po
branches/camel-gobject/po/sl.po
branches/camel-gobject/servers/exchange/ChangeLog
branches/camel-gobject/servers/exchange/lib/e2k-autoconfig.c
branches/camel-gobject/servers/groupwise/ChangeLog
branches/camel-gobject/servers/groupwise/e-gw-connection.c
branches/camel-gobject/servers/groupwise/e-gw-item.c
Modified: branches/camel-gobject/NEWS
==============================================================================
--- branches/camel-gobject/NEWS (original)
+++ branches/camel-gobject/NEWS Tue Jan 6 01:56:50 2009
@@ -1,3 +1,57 @@
+Evolution-Data-Server 2.25.3 2008-12-15
+---------------------------------------
+
+Bug Fixes:
+ #270376: Skype name field added to the list of IM information (Sasa Ostrouska)
+ #348299: New files implement category completion (Matthew Barnes)
+ #352287: Share locations and forecast rertieving with libgweather (Milan Crha)
+ #357948: Show preview of the selected image file when choosing new icon (Milan Crha)
+ #435632: (Novell Bugzilla) Don't unref when things aren't reffed (Srinivasa Ragavan)
+ #440265, #447121: (Novell Bugzilla) Fix some stupidity (Srinivasa Ragavan)
+ #451734: Correctly set Blythe, CA URL (Ian Weisser)
+ #503662: Use last '@' in the address part to be the delimiter between user name and server address, not the first one (Milan Crha)
+ #545834: Update mailing list information after full retrieval if necessary (Milan Crha)
+ #552986: Ensure error description is valid UTF-8 text before using it (Milan Crha)
+ #558883: Don't do DB sort from IMAP (Srinivasa Ragavan)
+ #561081: Delete mails for XGWMOVE when mails are moved (Srinivasa Ragavan)
+ #561561: Use a sufficiently large buffer for strings used as an operand in strftime() (Federic van Starbann)
+ #562228: Always store correct owa_path when validating, without trailing slash and without mailbox name (Milan Crha)
+ #562567: Remember local/remote mode correctly. Also done various cleanups, less debug output and waits for the slave thread only if exists (Milan Crha)
+
+Updated Translations:
+ Kjartan Maraas (nb)
+ Luca Ferretti (it)
+ Gabor Kelemen (hu)
+
+Evolution-Data-Server 2.25.2 2008-12-01
+---------------------------------------
+
+New in 2.25.2
+ Support CalDAV for VTODO and VJOURNAL (Milan Crha)
+
+Bug Fixes:
+ #359745: Support CalDAV for VTODO and VJOURNAL (Milan Crha)
+ #524377: Attachments with localised letters are unrecognised by Outlook (Milan Crha)
+ #527692: CalDAV does not work with Apple CalDAV (Milan Crha)
+ #531090: Deprecate dead API in camel-object.h (Matthew Barnes)
+ #546637: Mail opened from the "Unread mails" displays empty list (Srinivasa Ragavan)
+ #555979: Evolution does not empty trash on exit (Milan Crha)
+ #556119: Evolution takes a very long time to index newsgroup (Srinivasa Ragavan)
+ #557348: Search folders with "Include threads" do not update reliably (Srinivasa Ragavan)
+ #557818: Centralize ESourceSelector drag-n-drop handling (Matthew Barnes)
+ #558322: Pressing "F2" on a highlighted Task List / Memo List / Address Book / Calendar
+ should bring up the properties dialog box (Matthew Barnes)
+ #558737: Evolution freezes on trying to store folder (Milan Crha)
+ #558883: Evolution 2.24 is terribly slow with large IMAP folders (Milan Crha) (Srinivasa Ragavan)
+ #559272: Evolution freeze while using a CalDAV calendar (Milan Crha)
+ #560076: Follow-Ups doesn't work in 2.24 (Srinivasa Ragavan)
+ #560185: Support 'getctag' in CalDAV, if available (Milan Crha)
+ #560681: Parsing QUOTED-PRINTABLE vcards probably ignores CHARSET info (Milan Crha)
+ #560981: Result of xpath query is not freed in CalDAV synch loop (Andrew McMillan)
+ #561069: Evolution crashed expunging 48k deleted junk messages (Srinivasa Ragavan)
+ #561466: Changes needed in E-D-S for evolution-mapi (Suman Manjunath)
+ #435964 (bugzilla.novell.com): Crash after switching from offline to online in GW addressbook (Ashish Shrivastava)
+
Evolution-Data-Server 2.25.1 2008-11-03
---------------------------------------
Modified: branches/camel-gobject/addressbook/backends/file/e-book-backend-file.c
==============================================================================
--- branches/camel-gobject/addressbook/backends/file/e-book-backend-file.c (original)
+++ branches/camel-gobject/addressbook/backends/file/e-book-backend-file.c Tue Jan 6 01:56:50 2009
@@ -172,7 +172,7 @@
static void
set_revision (EContact *contact)
{
- char time_string[25] = {0};
+ char time_string[100] = {0};
const struct tm *tm = NULL;
GTimeVal tv;
Modified: branches/camel-gobject/addressbook/backends/google/e-book-backend-google.c
==============================================================================
--- branches/camel-gobject/addressbook/backends/google/e-book-backend-google.c (original)
+++ branches/camel-gobject/addressbook/backends/google/e-book-backend-google.c Tue Jan 6 01:56:50 2009
@@ -51,11 +51,11 @@
static EBookBackendSyncStatus e_book_backend_status_from_google_book_error (GoogleBookError error_code);
static EBookBackendSyncStatus
-e_book_backend_google_create_contact (EBookBackendSync *backend,
- EDataBook *book,
- guint32 opid,
- const char *vcard_str,
- EContact **out_contact)
+e_book_backend_google_create_contact (EBookBackendSync *backend,
+ EDataBook *book,
+ guint32 opid,
+ const char *vcard_str,
+ EContact **out_contact)
{
EBookBackendGooglePrivate *priv;
EBookBackendSyncStatus status = GNOME_Evolution_Addressbook_OtherError;
@@ -69,18 +69,18 @@
*out_contact = NULL;
if (priv->mode != GNOME_Evolution_Addressbook_MODE_REMOTE) {
- return GNOME_Evolution_Addressbook_OfflineUnavailable;
+ return GNOME_Evolution_Addressbook_OfflineUnavailable;
}
contact = e_contact_new_from_vcard (vcard_str);
google_book_add_contact (priv->book, contact, out_contact, &error);
g_object_unref (contact);
if (error) {
- status = e_book_backend_status_from_google_book_error (error->code);
- __debug__ ("Creating contact failed: %s", error->message);
- g_clear_error (&error);
- *out_contact = NULL;
- return status;
+ status = e_book_backend_status_from_google_book_error (error->code);
+ __debug__ ("Creating contact failed: %s", error->message);
+ g_clear_error (&error);
+ *out_contact = NULL;
+ return status;
}
return GNOME_Evolution_Addressbook_Success;
@@ -88,10 +88,10 @@
static EBookBackendSyncStatus
e_book_backend_google_remove_contacts (EBookBackendSync *backend,
- EDataBook *book,
- guint32 opid,
- GList *id_list,
- GList **ids)
+ EDataBook *book,
+ guint32 opid,
+ GList *id_list,
+ GList **ids)
{
EBookBackendGooglePrivate *priv;
EBookBackendSyncStatus status = GNOME_Evolution_Addressbook_OtherError;
@@ -103,37 +103,37 @@
*ids = NULL;
if (priv->mode != GNOME_Evolution_Addressbook_MODE_REMOTE) {
- return GNOME_Evolution_Addressbook_OfflineUnavailable;
+ return GNOME_Evolution_Addressbook_OfflineUnavailable;
}
for (id_iter = id_list; id_iter; id_iter = id_iter->next) {
- GError *error = NULL;
- const char *uid;
+ GError *error = NULL;
+ const char *uid;
- uid = id_iter->data;
- google_book_remove_contact (priv->book, uid, &error);
- if (error) {
- /* Only last error will be reported */
- status = e_book_backend_status_from_google_book_error (error->code);
- __debug__ ("Deleting contact %s failed: %s", uid, error->message);
- g_clear_error (&error);
- } else {
- *ids = g_list_append (*ids, g_strdup (uid));
- }
+ uid = id_iter->data;
+ google_book_remove_contact (priv->book, uid, &error);
+ if (error) {
+ /* Only last error will be reported */
+ status = e_book_backend_status_from_google_book_error (error->code);
+ __debug__ ("Deleting contact %s failed: %s", uid, error->message);
+ g_clear_error (&error);
+ } else {
+ *ids = g_list_append (*ids, g_strdup (uid));
+ }
}
if (NULL == *ids) {
- return status;
+ return status;
}
return GNOME_Evolution_Addressbook_Success;
}
static EBookBackendSyncStatus
-e_book_backend_google_modify_contact (EBookBackendSync *backend,
- EDataBook *book,
- guint32 opid,
- const char *vcard_str,
- EContact **out_contact)
+e_book_backend_google_modify_contact (EBookBackendSync *backend,
+ EDataBook *book,
+ guint32 opid,
+ const char *vcard_str,
+ EContact **out_contact)
{
EBookBackendGooglePrivate *priv;
EBookBackendSyncStatus status = GNOME_Evolution_Addressbook_OtherError;
@@ -147,29 +147,29 @@
*out_contact = NULL;
if (priv->mode != GNOME_Evolution_Addressbook_MODE_REMOTE) {
- return GNOME_Evolution_Addressbook_OfflineUnavailable;
+ return GNOME_Evolution_Addressbook_OfflineUnavailable;
}
contact = e_contact_new_from_vcard (vcard_str);
google_book_update_contact (priv->book, contact, out_contact, &error);
g_object_unref (contact);
if (error) {
- status = e_book_backend_status_from_google_book_error (error->code);
- __debug__ ("Modifying contact failed: %s", error->message);
- g_clear_error (&error);
- *out_contact = NULL;
- return status;
+ status = e_book_backend_status_from_google_book_error (error->code);
+ __debug__ ("Modifying contact failed: %s", error->message);
+ g_clear_error (&error);
+ *out_contact = NULL;
+ return status;
}
return GNOME_Evolution_Addressbook_Success;
}
static EBookBackendSyncStatus
-e_book_backend_google_get_contact (EBookBackendSync *backend,
- EDataBook *book,
- guint32 opid,
- const char *uid,
- char **vcard_str)
+e_book_backend_google_get_contact (EBookBackendSync *backend,
+ EDataBook *book,
+ guint32 opid,
+ const char *uid,
+ char **vcard_str)
{
EBookBackendGooglePrivate *priv;
EBookBackendSyncStatus status = GNOME_Evolution_Addressbook_OtherError;
@@ -181,10 +181,10 @@
contact = google_book_get_contact (priv->book, uid, &error);
if (error) {
- status = e_book_backend_status_from_google_book_error (error->code);
- __debug__ ("Getting contact with uid %s failed: %s", uid, error->message);
- g_clear_error (&error);
- return status;
+ status = e_book_backend_status_from_google_book_error (error->code);
+ __debug__ ("Getting contact with uid %s failed: %s", uid, error->message);
+ g_clear_error (&error);
+ return status;
}
*vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
g_object_unref (contact);
@@ -194,10 +194,10 @@
static EBookBackendSyncStatus
e_book_backend_google_get_contact_list (EBookBackendSync *backend,
- EDataBook *book,
- guint32 opid,
- const char *query,
- GList **contacts)
+ EDataBook *book,
+ guint32 opid,
+ const char *query,
+ GList **contacts)
{
EBookBackendGooglePrivate *priv;
EBookBackendSyncStatus status = GNOME_Evolution_Addressbook_OtherError;
@@ -212,24 +212,24 @@
all_contacts = google_book_get_all_contacts (priv->book, &error);
if (error) {
- status = e_book_backend_status_from_google_book_error (error->code);
- __debug__ ("Getting all contacts failed: %s", error->message);
- g_clear_error (&error);
- return status;
+ status = e_book_backend_status_from_google_book_error (error->code);
+ __debug__ ("Getting all contacts failed: %s", error->message);
+ g_clear_error (&error);
+ return status;
}
sexp = e_book_backend_sexp_new (query);
while (all_contacts) {
- EContact *contact;
+ EContact *contact;
- contact = all_contacts->data;
- if (e_book_backend_sexp_match_contact (sexp, contact)) {
- char *vcard_str;
- vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
- *contacts = g_list_append (*contacts, vcard_str);
- }
- g_object_unref (contact);
- all_contacts = g_list_delete_link (all_contacts, all_contacts);
+ contact = all_contacts->data;
+ if (e_book_backend_sexp_match_contact (sexp, contact)) {
+ char *vcard_str;
+ vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ *contacts = g_list_append (*contacts, vcard_str);
+ }
+ g_object_unref (contact);
+ all_contacts = g_list_delete_link (all_contacts, all_contacts);
}
g_object_unref (sexp);
@@ -244,8 +244,8 @@
priv = GET_PRIVATE (user_data);
for (iter = priv->bookviews; iter; iter = iter->next) {
- g_object_ref (contact);
- e_data_book_view_notify_update (E_DATA_BOOK_VIEW (iter->data), contact);
+ g_object_ref (contact);
+ e_data_book_view_notify_update (E_DATA_BOOK_VIEW (iter->data), contact);
}
}
@@ -257,7 +257,7 @@
priv = GET_PRIVATE (user_data);
for (iter = priv->bookviews; iter; iter = iter->next) {
- e_data_book_view_notify_remove (E_DATA_BOOK_VIEW (iter->data), g_strdup (uid));
+ e_data_book_view_notify_remove (E_DATA_BOOK_VIEW (iter->data), g_strdup (uid));
}
}
@@ -269,8 +269,8 @@
priv = GET_PRIVATE (user_data);
for (iter = priv->bookviews; iter; iter = iter->next) {
- g_object_ref (contact);
- e_data_book_view_notify_update (E_DATA_BOOK_VIEW (iter->data), contact);
+ g_object_ref (contact);
+ e_data_book_view_notify_update (E_DATA_BOOK_VIEW (iter->data), contact);
}
}
@@ -283,19 +283,19 @@
priv = GET_PRIVATE (user_data);
if (error) {
- status = e_book_backend_status_from_google_book_error (error->code);
- __debug__ ("Book-view query failed: %s", error->message);
- status = e_book_backend_status_from_google_book_error (error->code);
- g_clear_error (&error);
+ status = e_book_backend_status_from_google_book_error (error->code);
+ __debug__ ("Book-view query failed: %s", error->message);
+ status = e_book_backend_status_from_google_book_error (error->code);
+ g_clear_error (&error);
}
for (iter = priv->bookviews; iter; iter = iter->next) {
- e_data_book_view_notify_complete (E_DATA_BOOK_VIEW (iter->data), GNOME_Evolution_Addressbook_Success);
+ e_data_book_view_notify_complete (E_DATA_BOOK_VIEW (iter->data), GNOME_Evolution_Addressbook_Success);
}
}
static void
e_book_backend_google_start_book_view (EBookBackend *backend,
- EDataBookView *bookview)
+ EDataBookView *bookview)
{
EBookBackendGooglePrivate *priv;
GList *cached_contacts;
@@ -314,18 +314,18 @@
google_book_set_live_mode (priv->book, TRUE);
cached_contacts = google_book_get_all_contacts_in_live_mode (priv->book);
while (cached_contacts) {
- EContact *contact = cached_contacts->data;
+ EContact *contact = cached_contacts->data;
- e_data_book_view_notify_update (bookview, contact);
- g_object_unref (contact);
- cached_contacts = g_list_delete_link (cached_contacts, cached_contacts);
+ e_data_book_view_notify_update (bookview, contact);
+ g_object_unref (contact);
+ cached_contacts = g_list_delete_link (cached_contacts, cached_contacts);
}
e_data_book_view_notify_complete (bookview, GNOME_Evolution_Addressbook_Success);
}
static void
e_book_backend_google_stop_book_view (EBookBackend *backend,
- EDataBookView *bookview)
+ EDataBookView *bookview)
{
EBookBackendGooglePrivate *priv;
@@ -336,17 +336,17 @@
e_data_book_view_unref (bookview);
if (NULL == priv->bookviews) {
- google_book_set_live_mode (priv->book, FALSE);
+ google_book_set_live_mode (priv->book, FALSE);
}
}
static EBookBackendSyncStatus
e_book_backend_google_authenticate_user (EBookBackendSync *backend,
- EDataBook *book,
- guint32 opid,
- const char *username,
- const char *password,
- const char *auth_method)
+ EDataBook *book,
+ guint32 opid,
+ const char *username,
+ const char *password,
+ const char *auth_method)
{
EBookBackendGooglePrivate *priv;
EBookBackendSyncStatus status = GNOME_Evolution_Addressbook_Success;
@@ -358,42 +358,42 @@
priv = GET_PRIVATE (backend);
if (priv->mode != GNOME_Evolution_Addressbook_MODE_REMOTE) {
- return GNOME_Evolution_Addressbook_Success;
+ return GNOME_Evolution_Addressbook_Success;
}
if (NULL == username || username[0] == 0) {
- return GNOME_Evolution_Addressbook_AuthenticationFailed;
+ return GNOME_Evolution_Addressbook_AuthenticationFailed;
}
g_object_get (G_OBJECT (priv->book),
- "username", &book_username,
- NULL);
+ "username", &book_username,
+ NULL);
match = (0 == strcmp (username, book_username));
g_free (book_username);
if (FALSE == match) {
- g_warning ("Username given when loading source and on authentication did not match!");
- return GNOME_Evolution_Addressbook_OtherError;
+ g_warning ("Username given when loading source and on authentication did not match!");
+ return GNOME_Evolution_Addressbook_OtherError;
}
google_book_connect_to_google (priv->book, password, &error);
if (error) {
- status = e_book_backend_status_from_google_book_error (error->code);
- __debug__ ("Authentication failed: %s", error->message);
- status = e_book_backend_status_from_google_book_error (error->code);
- g_clear_error (&error);
+ status = e_book_backend_status_from_google_book_error (error->code);
+ __debug__ ("Authentication failed: %s", error->message);
+ status = e_book_backend_status_from_google_book_error (error->code);
+ g_clear_error (&error);
} else {
- e_book_backend_notify_writable (E_BOOK_BACKEND (backend), TRUE);
+ e_book_backend_notify_writable (E_BOOK_BACKEND (backend), TRUE);
}
return status;
}
static EBookBackendSyncStatus
-e_book_backend_google_get_supported_auth_methods (EBookBackendSync *backend,
- EDataBook *book,
- guint32 opid,
- GList **methods)
+e_book_backend_google_get_supported_auth_methods (EBookBackendSync *backend,
+ EDataBook *book,
+ guint32 opid,
+ GList **methods)
{
char *auth_method;
@@ -405,10 +405,10 @@
}
static EBookBackendSyncStatus
-e_book_backend_google_get_required_fields (EBookBackendSync *backend,
- EDataBook *book,
- guint32 opid,
- GList **fields_out)
+e_book_backend_google_get_required_fields (EBookBackendSync *backend,
+ EDataBook *book,
+ guint32 opid,
+ GList **fields_out)
{
__debug__ (G_STRFUNC);
@@ -417,36 +417,39 @@
}
static EBookBackendSyncStatus
-e_book_backend_google_get_supported_fields (EBookBackendSync *backend,
- EDataBook *book,
- guint32 opid,
- GList **fields_out)
+e_book_backend_google_get_supported_fields (EBookBackendSync *backend,
+ EDataBook *book,
+ guint32 opid,
+ GList **fields_out)
{
const int supported_fields[] =
{
- E_CONTACT_FULL_NAME,
- E_CONTACT_EMAIL_1,
- E_CONTACT_EMAIL_2,
- E_CONTACT_EMAIL_3,
- E_CONTACT_EMAIL_4,
- E_CONTACT_ADDRESS_LABEL_HOME,
- E_CONTACT_ADDRESS_LABEL_WORK,
- E_CONTACT_ADDRESS_LABEL_OTHER,
- E_CONTACT_PHONE_HOME,
- E_CONTACT_PHONE_HOME_FAX,
- E_CONTACT_PHONE_BUSINESS,
- E_CONTACT_PHONE_BUSINESS_FAX,
- E_CONTACT_PHONE_MOBILE,
- E_CONTACT_PHONE_PAGER,
- E_CONTACT_IM_AIM,
- E_CONTACT_IM_JABBER,
- E_CONTACT_IM_YAHOO,
- E_CONTACT_IM_MSN,
- E_CONTACT_IM_ICQ,
- E_CONTACT_ADDRESS,
- E_CONTACT_ADDRESS_HOME,
- E_CONTACT_ADDRESS_WORK,
- E_CONTACT_ADDRESS_OTHER
+ E_CONTACT_FULL_NAME,
+ E_CONTACT_EMAIL_1,
+ E_CONTACT_EMAIL_2,
+ E_CONTACT_EMAIL_3,
+ E_CONTACT_EMAIL_4,
+ E_CONTACT_ADDRESS_LABEL_HOME,
+ E_CONTACT_ADDRESS_LABEL_WORK,
+ E_CONTACT_ADDRESS_LABEL_OTHER,
+ E_CONTACT_PHONE_HOME,
+ E_CONTACT_PHONE_HOME_FAX,
+ E_CONTACT_PHONE_BUSINESS,
+ E_CONTACT_PHONE_BUSINESS_FAX,
+ E_CONTACT_PHONE_MOBILE,
+ E_CONTACT_PHONE_PAGER,
+ E_CONTACT_IM_AIM,
+ E_CONTACT_IM_JABBER,
+ E_CONTACT_IM_YAHOO,
+ E_CONTACT_IM_MSN,
+ E_CONTACT_IM_ICQ,
+ E_CONTACT_IM_SKYPE,
+ E_CONTACT_IM_GADUGADU,
+ E_CONTACT_IM_GROUPWISE,
+ E_CONTACT_ADDRESS,
+ E_CONTACT_ADDRESS_HOME,
+ E_CONTACT_ADDRESS_WORK,
+ E_CONTACT_ADDRESS_OTHER
};
GList *fields = NULL;
int i;
@@ -454,10 +457,10 @@
__debug__ (G_STRFUNC);
for (i = 0; i < G_N_ELEMENTS (supported_fields); i++) {
- const char *field_name;
+ const char *field_name;
- field_name = e_contact_field_name (supported_fields[i]);
- fields = g_list_append (fields, g_strdup (field_name));
+ field_name = e_contact_field_name (supported_fields[i]);
+ fields = g_list_append (fields, g_strdup (field_name));
}
*fields_out = fields;
@@ -465,20 +468,20 @@
}
static EBookBackendSyncStatus
-e_book_backend_google_get_changes (EBookBackendSync *backend,
- EDataBook *book,
- guint32 opid,
- const char *change_id,
- GList **changes_out)
+e_book_backend_google_get_changes (EBookBackendSync *backend,
+ EDataBook *book,
+ guint32 opid,
+ const char *change_id,
+ GList **changes_out)
{
__debug__ (G_STRFUNC);
return GNOME_Evolution_Addressbook_OtherError;
}
static EBookBackendSyncStatus
-e_book_backend_google_remove (EBookBackendSync *backend,
- EDataBook *book,
- guint32 opid)
+e_book_backend_google_remove (EBookBackendSync *backend,
+ EDataBook *book,
+ guint32 opid)
{
__debug__ (G_STRFUNC);
return GNOME_Evolution_Addressbook_Success;
@@ -493,8 +496,8 @@
static GNOME_Evolution_Addressbook_CallStatus
e_book_backend_google_load_source (EBookBackend *backend,
- ESource *source,
- gboolean only_if_exists)
+ ESource *source,
+ gboolean only_if_exists)
{
EBookBackendGooglePrivate *priv = GET_PRIVATE (backend);
const char *refresh_interval_str, *use_ssl_str, *use_cache_str;
@@ -503,15 +506,15 @@
const char *username;
if (priv->book) {
- g_warning ("Source already loaded!");
- return GNOME_Evolution_Addressbook_OtherError;
+ g_warning ("Source already loaded!");
+ return GNOME_Evolution_Addressbook_OtherError;
}
username = e_source_get_property (source, "username");
if (NULL == username || username[0] == '\0') {
- g_warning ("No or empty username!");
- return GNOME_Evolution_Addressbook_OtherError;
+ g_warning ("No or empty username!");
+ return GNOME_Evolution_Addressbook_OtherError;
}
refresh_interval_str = e_source_get_property (source, "refresh-interval");
@@ -519,37 +522,37 @@
use_cache_str = e_source_get_property (source, "offline_sync");
if (refresh_interval_str) {
- if (1 != sscanf (refresh_interval_str, "%u", &refresh_interval)) {
- g_warning ("Could not parse refresh-interval!");
- refresh_interval = 3600;
- }
+ if (1 != sscanf (refresh_interval_str, "%u", &refresh_interval)) {
+ g_warning ("Could not parse refresh-interval!");
+ refresh_interval = 3600;
+ }
}
use_ssl = TRUE;
if (use_ssl_str) {
- if (0 == g_ascii_strcasecmp (use_ssl_str, "false") || 0 == strcmp (use_ssl_str, "0"))
- use_ssl = FALSE;
+ if (0 == g_ascii_strcasecmp (use_ssl_str, "false") || 0 == strcmp (use_ssl_str, "0"))
+ use_ssl = FALSE;
}
use_cache = TRUE;
if (use_cache_str) {
- if (0 == g_ascii_strcasecmp (use_cache_str, "false") || 0 == strcmp (use_cache_str, "0"))
- use_cache = FALSE;
+ if (0 == g_ascii_strcasecmp (use_cache_str, "false") || 0 == strcmp (use_cache_str, "0"))
+ use_cache = FALSE;
}
priv->book = google_book_new (username, use_cache);
g_object_set (G_OBJECT (priv->book),
- "refresh-interval", refresh_interval,
- "use-ssl", use_ssl,
- NULL);
+ "refresh-interval", refresh_interval,
+ "use-ssl", use_ssl,
+ NULL);
g_object_connect (G_OBJECT (priv->book),
- "signal::contact-added", G_CALLBACK (on_google_book_contact_added), backend,
- "signal::contact-changed", G_CALLBACK (on_google_book_contact_changed), backend,
- "signal::contact-removed", G_CALLBACK (on_google_book_contact_removed), backend,
- "signal::sequence-complete", G_CALLBACK (on_google_book_sequence_complete), backend,
- "signal::auth-required", G_CALLBACK (on_google_book_auth_required), backend,
- NULL);
+ "signal::contact-added", G_CALLBACK (on_google_book_contact_added), backend,
+ "signal::contact-changed", G_CALLBACK (on_google_book_contact_changed), backend,
+ "signal::contact-removed", G_CALLBACK (on_google_book_contact_removed), backend,
+ "signal::sequence-complete", G_CALLBACK (on_google_book_sequence_complete), backend,
+ "signal::auth-required", G_CALLBACK (on_google_book_auth_required), backend,
+ NULL);
__debug__ (G_STRFUNC);
@@ -583,19 +586,19 @@
__debug__ (G_STRFUNC);
if (mode == priv->mode) {
- return;
+ return;
}
priv->mode = mode;
if (NULL == priv->book) {
- return;
+ return;
}
if (mode == GNOME_Evolution_Addressbook_MODE_REMOTE) {
- google_book_set_offline_mode (priv->book, FALSE);
+ google_book_set_offline_mode (priv->book, FALSE);
} else {
- google_book_set_offline_mode (priv->book, TRUE);
+ google_book_set_offline_mode (priv->book, TRUE);
}
}
@@ -607,13 +610,13 @@
__debug__ (G_STRFUNC);
while (priv->bookviews) {
- e_data_book_view_unref (priv->bookviews->data);
- priv->bookviews = g_list_delete_link (priv->bookviews,
- priv->bookviews);
+ e_data_book_view_unref (priv->bookviews->data);
+ priv->bookviews = g_list_delete_link (priv->bookviews,
+ priv->bookviews);
}
if (priv->book) {
- g_object_unref (priv->book);
- priv->book = NULL;
+ g_object_unref (priv->book);
+ priv->book = NULL;
}
G_OBJECT_CLASS (e_book_backend_google_parent_class)->dispose (object);
@@ -641,23 +644,23 @@
g_type_class_add_private (klass, sizeof (EBookBackendGooglePrivate));
/* Set the virtual methods. */
- backend_class->load_source = e_book_backend_google_load_source;
- backend_class->get_static_capabilities = e_book_backend_google_get_static_capabilities;
- backend_class->start_book_view = e_book_backend_google_start_book_view;
- backend_class->stop_book_view = e_book_backend_google_stop_book_view;
- backend_class->cancel_operation = e_book_backend_google_cancel_operation;
- backend_class->set_mode = e_book_backend_google_set_mode;
- sync_class->remove_sync = e_book_backend_google_remove;
- sync_class->create_contact_sync = e_book_backend_google_create_contact;
- sync_class->remove_contacts_sync = e_book_backend_google_remove_contacts;
- sync_class->modify_contact_sync = e_book_backend_google_modify_contact;
- sync_class->get_contact_sync = e_book_backend_google_get_contact;
- sync_class->get_contact_list_sync = e_book_backend_google_get_contact_list;
- sync_class->get_changes_sync = e_book_backend_google_get_changes;
- sync_class->authenticate_user_sync = e_book_backend_google_authenticate_user;
- sync_class->get_supported_fields_sync = e_book_backend_google_get_supported_fields;
- sync_class->get_required_fields_sync = e_book_backend_google_get_required_fields;
- sync_class->get_supported_auth_methods_sync = e_book_backend_google_get_supported_auth_methods;
+ backend_class->load_source = e_book_backend_google_load_source;
+ backend_class->get_static_capabilities = e_book_backend_google_get_static_capabilities;
+ backend_class->start_book_view = e_book_backend_google_start_book_view;
+ backend_class->stop_book_view = e_book_backend_google_stop_book_view;
+ backend_class->cancel_operation = e_book_backend_google_cancel_operation;
+ backend_class->set_mode = e_book_backend_google_set_mode;
+ sync_class->remove_sync = e_book_backend_google_remove;
+ sync_class->create_contact_sync = e_book_backend_google_create_contact;
+ sync_class->remove_contacts_sync = e_book_backend_google_remove_contacts;
+ sync_class->modify_contact_sync = e_book_backend_google_modify_contact;
+ sync_class->get_contact_sync = e_book_backend_google_get_contact;
+ sync_class->get_contact_list_sync = e_book_backend_google_get_contact_list;
+ sync_class->get_changes_sync = e_book_backend_google_get_changes;
+ sync_class->authenticate_user_sync = e_book_backend_google_authenticate_user;
+ sync_class->get_supported_fields_sync = e_book_backend_google_get_supported_fields;
+ sync_class->get_required_fields_sync = e_book_backend_google_get_required_fields;
+ sync_class->get_supported_auth_methods_sync = e_book_backend_google_get_supported_auth_methods;
object_class->dispose = e_book_backend_google_dispose;
object_class->finalize = e_book_backend_google_finalize;
Modified: branches/camel-gobject/addressbook/backends/groupwise/e-book-backend-groupwise.c
==============================================================================
--- branches/camel-gobject/addressbook/backends/groupwise/e-book-backend-groupwise.c (original)
+++ branches/camel-gobject/addressbook/backends/groupwise/e-book-backend-groupwise.c Tue Jan 6 01:56:50 2009
@@ -44,6 +44,7 @@
#include "libedataserver/e-flag.h"
#include "libedataserver/e-url.h"
#include "libebook/e-contact.h"
+#include "libebook/e-destination.h"
#include "libedata-book/e-book-backend-sexp.h"
#include "libedata-book/e-data-book.h"
#include "libedata-book/e-data-book-view.h"
@@ -178,6 +179,7 @@
GList *yahoo_list = NULL;
GList *gadugadu_list = NULL;
GList *msn_list = NULL;
+ GList *skype_list = NULL;
GList *jabber_list = NULL;
GList *groupwise_list = NULL;
IMAddress *address;
@@ -204,10 +206,14 @@
im_field_id = E_CONTACT_IM_AIM;
im_attr_list = &aim_list;
}
- else if ( g_str_equal (address->service, "msn")) {
+ else if (g_str_equal (address->service, "msn")) {
im_field_id = E_CONTACT_IM_MSN;
im_attr_list = &msn_list;
}
+ else if (g_str_equal (address->service, "skype")) {
+ im_field_id = E_CONTACT_IM_SKYPE;
+ im_attr_list = &skype_list;
+ }
else if (g_str_equal (address->service, "yahoo")) {
im_field_id = E_CONTACT_IM_YAHOO;
im_attr_list = &yahoo_list;
@@ -240,6 +246,7 @@
e_contact_set_attributes (contact, E_CONTACT_IM_YAHOO, yahoo_list);
e_contact_set_attributes (contact, E_CONTACT_IM_GADUGADU, gadugadu_list);
e_contact_set_attributes (contact, E_CONTACT_IM_MSN, msn_list);
+ e_contact_set_attributes (contact, E_CONTACT_IM_SKYPE, skype_list);
e_contact_set_attributes (contact, E_CONTACT_IM_GROUPWISE, groupwise_list);
free_attr_list (aim_list);
@@ -248,6 +255,7 @@
free_attr_list (yahoo_list);
free_attr_list (gadugadu_list);
free_attr_list (msn_list);
+ free_attr_list (skype_list);
free_attr_list (groupwise_list);
}
@@ -280,6 +288,7 @@
append_ims_to_list (&im_list, contact, "gadu-gadu", E_CONTACT_IM_GADUGADU);
append_ims_to_list (&im_list, contact, "icq", E_CONTACT_IM_ICQ);
append_ims_to_list (&im_list, contact, "msn", E_CONTACT_IM_MSN);
+ append_ims_to_list (&im_list, contact, "skype", E_CONTACT_IM_SKYPE);
append_ims_to_list (&im_list, contact, "jabber", E_CONTACT_IM_JABBER);
append_ims_to_list (&im_list, contact, "nov", E_CONTACT_IM_GROUPWISE);
if (im_list)
@@ -798,7 +807,7 @@
static void
set_members_in_gw_item (EGwItem *item, EContact *contact, EBookBackendGroupwise *egwb)
{
- GList *members, *temp, *items, *p, *emails_without_ids;
+ GList *members, *temp, *dtemp, *items, *p, *emails_without_ids, *dest_without_ids;
GList *group_members;
char *email;
EGwFilter *filter;
@@ -816,10 +825,12 @@
filter = e_gw_filter_new ();
group_members = NULL;
emails_without_ids = NULL;
+ dest_without_ids = NULL;
for ( ;temp != NULL; temp = g_list_next (temp)) {
EVCardAttribute *attr = temp->data;
id = email = NULL;
+ EDestination *dest = e_destination_new ();
for (p = e_vcard_attribute_get_params (attr); p; p = p->next) {
EVCardAttributeParam *param = p->data;
@@ -848,13 +859,19 @@
email = v ? v->data : NULL;
}
}
+
+ if (!id && !email)
+ email = e_vcard_attribute_get_value (attr);
if (id) {
member = g_new0 (EGroupMember , 1);
member->id = g_strdup (id);
group_members = g_list_append (group_members, member);
} else if (email) {
+ e_destination_set_raw (dest, email);
e_gw_filter_add_filter_component (filter, E_GW_FILTER_OP_EQUAL, "emailList/@primary", email);
emails_without_ids = g_list_append (emails_without_ids, g_strdup (email));
+ dest_without_ids = g_list_append (dest_without_ids, dest);
+
count++;
}
}
@@ -871,8 +888,15 @@
temp_item = E_GW_ITEM (items->data);
emails = e_gw_item_get_email_list (temp_item);
if (emails_without_ids && (ptr = g_list_find_custom (emails_without_ids, emails->data, (GCompareFunc)strcasecmp ))) {
+ int pos = g_list_position (emails_without_ids, ptr);
emails_without_ids = g_list_remove_link (emails_without_ids, ptr);
g_list_free (ptr);
+
+ ptr = g_list_nth (dest_without_ids, pos);
+ dest_without_ids = g_list_remove_link (dest_without_ids, ptr);
+ g_object_unref (ptr->data);
+ g_list_free (ptr);
+
id = g_strdup (e_gw_item_get_id (temp_item));
member = g_new0 (EGroupMember , 1);
member->id = id;
@@ -890,19 +914,21 @@
*/
temp = emails_without_ids ;
- for (; temp != NULL; temp = g_list_next (temp)) {
+ dtemp = dest_without_ids;
+ for (; temp != NULL && dtemp != NULL ; temp = g_list_next (temp), dtemp = g_list_next(dtemp)) {
EContact *new_contact = e_contact_new ();
EGwItem *new_item = e_gw_item_new_empty ();
FullName *full_name;
+ EDestination *tdest = (EDestination *)dtemp->data;
- e_contact_set (new_contact,E_CONTACT_FULL_NAME, e_contact_name_from_string (strdup (temp->data)));
- e_contact_set (new_contact, E_CONTACT_EMAIL_1, strdup (temp->data));
+ e_contact_set (new_contact,E_CONTACT_FULL_NAME, e_contact_name_from_string (strdup (e_destination_get_email(tdest))));
+ e_contact_set (new_contact, E_CONTACT_EMAIL_1, strdup (e_destination_get_email(tdest)));
e_contact_set (new_contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (FALSE));
e_gw_item_set_item_type (new_item, E_GW_ITEM_TYPE_CONTACT);
e_gw_item_set_container_id (new_item, g_strdup(egwb->priv->container_id));
full_name = g_new0 (FullName, 1);
full_name->name_prefix = NULL;
- full_name->first_name = g_strdup(temp->data);
+ full_name->first_name = g_strdup(e_destination_get_name(tdest));
full_name->middle_name = NULL;
full_name->last_name = NULL;
full_name->name_suffix = NULL;
@@ -956,6 +982,9 @@
g_list_free (members);
g_list_foreach (emails_without_ids, (GFunc) g_free, NULL);
g_list_free (emails_without_ids);
+ g_list_foreach (dest_without_ids, (GFunc) g_object_unref, NULL);
+ g_list_free (dest_without_ids);
+
g_list_free (items);
e_gw_item_set_member_list (item, group_members);
}
@@ -2020,7 +2049,7 @@
g_object_unref (contact);
}
g_ptr_array_free (ids, TRUE);
- ids->len = 0;
+ ids = NULL;
}
}
else {
@@ -2821,7 +2850,7 @@
EContact *contact;
EGwFilter *filter;
time_t mod_time;
- char cache_time_string[25], *status_msg;
+ char cache_time_string[100], *status_msg;
const struct tm *tm;
struct stat buf;
char *cache_file_name;
@@ -3454,6 +3483,7 @@
fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_IM_YAHOO)));
fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_IM_GADUGADU)));
fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_IM_MSN)));
+ fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_IM_SKYPE)));
fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_IM_JABBER)));
fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_IM_GROUPWISE)));
fields = g_list_append (fields, g_strdup (e_contact_field_name (E_CONTACT_ADDRESS_WORK)));
Modified: branches/camel-gobject/addressbook/backends/vcf/e-book-backend-vcf.c
==============================================================================
--- branches/camel-gobject/addressbook/backends/vcf/e-book-backend-vcf.c (original)
+++ branches/camel-gobject/addressbook/backends/vcf/e-book-backend-vcf.c Tue Jan 6 01:56:50 2009
@@ -216,7 +216,7 @@
static void
set_revision (EContact *contact)
{
- char time_string[25] = {0};
+ char time_string[100] = {0};
const struct tm *tm = NULL;
GTimeVal tv;
Modified: branches/camel-gobject/addressbook/libebook/e-contact.c
==============================================================================
--- branches/camel-gobject/addressbook/libebook/e-contact.c (original)
+++ branches/camel-gobject/addressbook/libebook/e-contact.c Tue Jan 6 01:56:50 2009
@@ -273,7 +273,15 @@
/* Geo information */
STRUCT_FIELD (E_CONTACT_GEO, EVC_GEO, "geo", N_("Geographic Information"), FALSE, geo_getter, geo_setter, e_contact_geo_get_type),
- MULTI_LIST_FIELD (E_CONTACT_TEL, EVC_TEL, "phone", N_("Telephone"), FALSE)
+ MULTI_LIST_FIELD (E_CONTACT_TEL, EVC_TEL, "phone", N_("Telephone"), FALSE),
+
+ ATTR_TYPE_STR_FIELD (E_CONTACT_IM_SKYPE_HOME_1, EVC_X_SKYPE, "im_skype_home_1", N_("Skype Home Name 1"), FALSE, "HOME", 0),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_IM_SKYPE_HOME_2, EVC_X_SKYPE, "im_skype_home_2", N_("Skype Home Name 2"), FALSE, "HOME", 1),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_IM_SKYPE_HOME_3, EVC_X_SKYPE, "im_skype_home_3", N_("Skype Home Name 3"), FALSE, "HOME", 2),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_IM_SKYPE_WORK_1, EVC_X_SKYPE, "im_skype_work_1", N_("Skype Work Name 1"), FALSE, "WORK", 0),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_IM_SKYPE_WORK_2, EVC_X_SKYPE, "im_skype_work_2", N_("Skype Work Name 2"), FALSE, "WORK", 1),
+ ATTR_TYPE_STR_FIELD (E_CONTACT_IM_SKYPE_WORK_3, EVC_X_SKYPE, "im_skype_work_3", N_("Skype Work Name 3"), FALSE, "WORK", 2),
+ MULTI_LIST_FIELD (E_CONTACT_IM_SKYPE, EVC_X_SKYPE, "im_skype", N_("Skype Name List"), FALSE)
};
#undef LIST_ELEM_STR_FIELD
Modified: branches/camel-gobject/addressbook/libebook/e-contact.h
==============================================================================
--- branches/camel-gobject/addressbook/libebook/e-contact.h (original)
+++ branches/camel-gobject/addressbook/libebook/e-contact.h Tue Jan 6 01:56:50 2009
@@ -199,6 +199,14 @@
E_CONTACT_TEL, /* list of strings */
+ E_CONTACT_IM_SKYPE_HOME_1, /* Synthetic string field */
+ E_CONTACT_IM_SKYPE_HOME_2, /* Synthetic string field */
+ E_CONTACT_IM_SKYPE_HOME_3, /* Synthetic string field */
+ E_CONTACT_IM_SKYPE_WORK_1, /* Synthetic string field */
+ E_CONTACT_IM_SKYPE_WORK_2, /* Synthetic string field */
+ E_CONTACT_IM_SKYPE_WORK_3, /* Synthetic string field */
+ E_CONTACT_IM_SKYPE, /* Multi-valued */
+
E_CONTACT_FIELD_LAST,
E_CONTACT_FIELD_FIRST = E_CONTACT_UID,
Modified: branches/camel-gobject/addressbook/libebook/e-vcard.c
==============================================================================
--- branches/camel-gobject/addressbook/libebook/e-vcard.c (original)
+++ branches/camel-gobject/addressbook/libebook/e-vcard.c Tue Jan 6 01:56:50 2009
@@ -223,7 +223,7 @@
}
static void
-read_attribute_value (EVCardAttribute *attr, char **p, gboolean quoted_printable)
+read_attribute_value (EVCardAttribute *attr, char **p, gboolean quoted_printable, const char *charset)
{
char *lp = *p;
GString *str;
@@ -289,6 +289,16 @@
}
else if ((*lp == ';') ||
(*lp == ',' && !g_ascii_strcasecmp (attr->name, "CATEGORIES"))) {
+ if (charset) {
+ char *tmp;
+
+ tmp = g_convert (str->str, str->len, "UTF-8", charset, NULL, NULL, NULL);
+ if (tmp) {
+ g_string_assign (str, tmp);
+ g_free (tmp);
+ }
+ }
+
e_vcard_attribute_add_value (attr, str->str);
g_string_assign (str, "");
lp = g_utf8_next_char(lp);
@@ -299,6 +309,16 @@
}
}
if (str) {
+ if (charset) {
+ char *tmp;
+
+ tmp = g_convert (str->str, str->len, "UTF-8", charset, NULL, NULL, NULL);
+ if (tmp) {
+ g_string_assign (str, tmp);
+ g_free (tmp);
+ }
+ }
+
e_vcard_attribute_add_value (attr, str->str);
g_string_free (str, TRUE);
}
@@ -309,7 +329,7 @@
}
static void
-read_attribute_params (EVCardAttribute *attr, char **p, gboolean *quoted_printable)
+read_attribute_params (EVCardAttribute *attr, char **p, gboolean *quoted_printable, char **charset)
{
char *lp;
GString *str;
@@ -389,6 +409,13 @@
*quoted_printable = TRUE;
e_vcard_attribute_param_free (param);
param = NULL;
+ } else if (param
+ && !g_ascii_strcasecmp (param->name, "charset")
+ && g_ascii_strcasecmp (param->values->data, "utf-8") != 0) {
+ g_free (*charset);
+ *charset = g_strdup (param->values->data);
+ e_vcard_attribute_param_free (param);
+ param = NULL;
}
}
else {
@@ -468,6 +495,7 @@
GString *str;
char *lp;
gboolean is_qp = FALSE;
+ char *charset = NULL;
/* first read in the group/name */
str = g_string_new ("");
@@ -533,16 +561,18 @@
if (*lp == ';') {
/* skip past the ';' */
lp = g_utf8_next_char(lp);
- read_attribute_params (attr, &lp, &is_qp);
+ read_attribute_params (attr, &lp, &is_qp, &charset);
if (is_qp)
attr->encoding = EVC_ENCODING_RAW;
}
if (*lp == ':') {
/* skip past the ':' */
lp = g_utf8_next_char(lp);
- read_attribute_value (attr, &lp, is_qp);
+ read_attribute_value (attr, &lp, is_qp, charset);
}
+ g_free (charset);
+
*p = lp;
if (!attr->values)
Modified: branches/camel-gobject/addressbook/libebook/e-vcard.h
==============================================================================
--- branches/camel-gobject/addressbook/libebook/e-vcard.h (original)
+++ branches/camel-gobject/addressbook/libebook/e-vcard.h Tue Jan 6 01:56:50 2009
@@ -81,6 +81,7 @@
#define EVC_X_LIST "X-EVOLUTION-LIST"
#define EVC_X_MANAGER "X-EVOLUTION-MANAGER"
#define EVC_X_MSN "X-MSN"
+#define EVC_X_SKYPE "X-SKYPE"
#define EVC_X_RADIO "X-EVOLUTION-RADIO"
#define EVC_X_SPOUSE "X-EVOLUTION-SPOUSE"
#define EVC_X_TELEX "X-EVOLUTION-TELEX"
@@ -88,7 +89,7 @@
#define EVC_X_VIDEO_URL "X-EVOLUTION-VIDEO-URL"
#define EVC_X_WANTS_HTML "X-MOZILLA-HTML"
#define EVC_X_YAHOO "X-YAHOO"
-#define EVC_X_GADUGADU "X-GADUGADU"
+#define EVC_X_GADUGADU "X-GADUGADU"
#define EVC_X_GROUPWISE "X-GROUPWISE"
#define EVC_X_BOOK_URI "X-EVOLUTION-BOOK-URI"
Modified: branches/camel-gobject/addressbook/libedata-book/e-book-backend-db-cache.c
==============================================================================
--- branches/camel-gobject/addressbook/libedata-book/e-book-backend-db-cache.c (original)
+++ branches/camel-gobject/addressbook/libedata-book/e-book-backend-db-cache.c Tue Jan 6 01:56:50 2009
@@ -131,8 +131,8 @@
EContact *
e_book_backend_db_cache_get_contact (DB *db, const char *uid)
{
- DBT uid_dbt, vcard_dbt;
- int db_error;
+ DBT uid_dbt, vcard_dbt;
+ int db_error;
EContact *contact = NULL;
g_return_val_if_fail (uid != NULL, NULL);
@@ -163,19 +163,19 @@
**/
gboolean
e_book_backend_db_cache_add_contact (DB *db,
- EContact *contact)
+ EContact *contact)
{
- DBT uid_dbt, vcard_dbt;
- int db_error;
- char *vcard_str;
+ DBT uid_dbt, vcard_dbt;
+ int db_error;
+ char *vcard_str;
const char *uid;
uid = e_contact_get_const (contact, E_CONTACT_UID);
if (!uid) {
printf ("no uid\n");
printf("name:%s, email:%s\n",
- (char*)e_contact_get (contact, E_CONTACT_GIVEN_NAME),
- (char*)e_contact_get (contact, E_CONTACT_EMAIL_1));
+ (char*)e_contact_get (contact, E_CONTACT_GIVEN_NAME),
+ (char*)e_contact_get (contact, E_CONTACT_EMAIL_1));
return FALSE;
}
string_to_dbt (uid, &uid_dbt);
@@ -207,11 +207,11 @@
**/
gboolean
e_book_backend_db_cache_remove_contact (DB *db,
- const char *uid)
+ const char *uid)
{
- DBT uid_dbt;
- int db_error;
+ DBT uid_dbt;
+ int db_error;
g_return_val_if_fail (uid != NULL, FALSE);
@@ -239,8 +239,8 @@
gboolean
e_book_backend_db_cache_check_contact (DB *db, const char *uid)
{
- DBT uid_dbt, vcard_dbt;
- int db_error;
+ DBT uid_dbt, vcard_dbt;
+ int db_error;
g_return_val_if_fail (uid != NULL, FALSE);
@@ -271,11 +271,11 @@
GList *
e_book_backend_db_cache_get_contacts (DB *db, const char *query)
{
- DBC *dbc;
- DBT uid_dbt, vcard_dbt;
- int db_error;
+ DBC *dbc;
+ DBT uid_dbt, vcard_dbt;
+ int db_error;
GList *list = NULL;
- EBookBackendSExp *sexp = NULL;
+ EBookBackendSExp *sexp = NULL;
EContact *contact;
if (query) {
@@ -315,7 +315,7 @@
if (sexp)
g_object_unref (sexp);
- return g_list_reverse (list);
+ return g_list_reverse (list);
}
/**
@@ -381,8 +381,8 @@
void
e_book_backend_db_cache_set_populated (DB *db)
{
- DBT uid_dbt, vcard_dbt;
- int db_error;
+ DBT uid_dbt, vcard_dbt;
+ int db_error;
string_to_dbt ("populated", &uid_dbt);
string_to_dbt ("TRUE", &vcard_dbt);
@@ -404,8 +404,8 @@
gboolean
e_book_backend_db_cache_is_populated (DB *db)
{
- DBT uid_dbt, vcard_dbt;
- int db_error;
+ DBT uid_dbt, vcard_dbt;
+ int db_error;
string_to_dbt ("populated", &uid_dbt);
memset(&vcard_dbt, 0, sizeof(vcard_dbt));
@@ -420,3 +420,40 @@
return TRUE;
}
}
+
+void
+e_book_backend_db_cache_set_time(DB *db, const char *t)
+{
+ DBT uid_dbt, vcard_dbt;
+ int db_error;
+
+ string_to_dbt ("last_update_time", &uid_dbt);
+ string_to_dbt (t, &vcard_dbt);
+
+ db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0);
+ if (db_error != 0) {
+ g_warning ("db->put failed with %d", db_error);
+ }
+}
+
+char *
+e_book_backend_db_cache_get_time (DB *db)
+{
+ DBT uid_dbt, vcard_dbt;
+ int db_error;
+ char *t = NULL;
+
+ string_to_dbt ("last_update_time", &uid_dbt);
+ memset (&vcard_dbt, 0, sizeof(vcard_dbt));
+ vcard_dbt.flags = DB_DBT_MALLOC;
+
+ db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt, 0);
+ if (db_error != 0) {
+ g_warning ("db->get failed with %d", db_error);
+ } else {
+ t = g_strdup (vcard_dbt.data);
+ free (vcard_dbt.data);
+ }
+
+ return t;
+}
Modified: branches/camel-gobject/addressbook/libedata-book/e-book-backend-db-cache.h
==============================================================================
--- branches/camel-gobject/addressbook/libedata-book/e-book-backend-db-cache.h (original)
+++ branches/camel-gobject/addressbook/libedata-book/e-book-backend-db-cache.h Tue Jan 6 01:56:50 2009
@@ -25,6 +25,8 @@
#include <libebook/e-contact.h>
#include "db.h"
+G_BEGIN_DECLS
+
EContact* e_book_backend_db_cache_get_contact (DB *db, const char *uid);
void string_to_dbt(const char *str, DBT *dbt);
char *e_book_backend_db_cache_get_filename(DB *db);
@@ -39,9 +41,8 @@
void e_book_backend_db_cache_set_populated (DB *db);
gboolean e_book_backend_db_cache_is_populated (DB *db);
GPtrArray* e_book_backend_db_cache_search (DB *db, const char *query);
-
-
-
+void e_book_backend_db_cache_set_time(DB *db, const char *t);
+char * e_book_backend_db_cache_get_time (DB *db);
G_END_DECLS
Modified: branches/camel-gobject/addressbook/libedata-book/e-book-backend-sexp.c
==============================================================================
--- branches/camel-gobject/addressbook/libedata-book/e-book-backend-sexp.c (original)
+++ branches/camel-gobject/addressbook/libedata-book/e-book-backend-sexp.c Tue Jan 6 01:56:50 2009
@@ -76,6 +76,13 @@
}
static gboolean
+compare_im_skype (EContact *contact, const char *str,
+ char *(*compare)(const char*, const char*))
+{
+ return compare_im (contact, str, compare, E_CONTACT_IM_SKYPE);
+}
+
+static gboolean
compare_im_icq (EContact *contact, const char *str,
char *(*compare)(const char*, const char*))
{
@@ -266,6 +273,7 @@
NORMAL_PROP ( E_CONTACT_NOTE, "note"),
LIST_PROP ( "im_aim", compare_im_aim ),
LIST_PROP ( "im_msn", compare_im_msn ),
+ LIST_PROP ( "im_skype", compare_im_skype ),
LIST_PROP ( "im_icq", compare_im_icq ),
LIST_PROP ( "im_jabber", compare_im_jabber ),
LIST_PROP ( "im_yahoo", compare_im_yahoo ),
Modified: branches/camel-gobject/addressbook/libedata-book/e-book-backend.c
==============================================================================
--- branches/camel-gobject/addressbook/libedata-book/e-book-backend.c (original)
+++ branches/camel-gobject/addressbook/libedata-book/e-book-backend.c Tue Jan 6 01:56:50 2009
@@ -476,12 +476,21 @@
e_book_backend_remove_client (backend, (EDataBook *)where_book_was);
}
-static void
-listener_died_cb (gpointer cnx, gpointer user_data)
+static gboolean
+idle_remove_client (gpointer data)
{
- EDataBook *book = E_DATA_BOOK (user_data);
+ EDataBook *book = (EDataBook *) data;
e_book_backend_remove_client (e_data_book_get_backend (book), book);
+ g_object_unref ((GObject *) book);
+
+ return FALSE;
+}
+static void
+listener_died_cb (gpointer cnx, gpointer user_data)
+{
+ g_object_ref ((GObject *)user_data);
+ g_idle_add (idle_remove_client, user_data);
}
static void
Modified: branches/camel-gobject/addressbook/libedata-book/e-data-book-view.c
==============================================================================
--- branches/camel-gobject/addressbook/libedata-book/e-data-book-view.c (original)
+++ branches/camel-gobject/addressbook/libedata-book/e-data-book-view.c Tue Jan 6 01:56:50 2009
@@ -247,7 +247,6 @@
id = e_contact_get_const (contact, E_CONTACT_UID);
if (!id) {
- g_object_unref (contact);
g_mutex_unlock (book_view->priv->pending_mutex);
return;
}
Modified: branches/camel-gobject/calendar/backends/Makefile.am
==============================================================================
--- branches/camel-gobject/calendar/backends/Makefile.am (original)
+++ branches/camel-gobject/calendar/backends/Makefile.am Tue Jan 6 01:56:50 2009
@@ -1 +1,7 @@
-SUBDIRS = file groupwise http contacts weather caldav google
+if ENABLE_WEATHER
+WEATHER_SUBDIR = weather
+else
+WEATHER_SUBDIR =
+endif
+
+SUBDIRS = file groupwise http contacts $(WEATHER_SUBDIR) caldav google
Modified: branches/camel-gobject/calendar/backends/caldav/e-cal-backend-caldav-factory.c
==============================================================================
--- branches/camel-gobject/calendar/backends/caldav/e-cal-backend-caldav-factory.c (original)
+++ branches/camel-gobject/calendar/backends/caldav/e-cal-backend-caldav-factory.c Tue Jan 6 01:56:50 2009
@@ -32,79 +32,92 @@
#include "e-cal-backend-caldav.h"
typedef struct {
- ECalBackendFactory parent_object;
+ ECalBackendFactory parent_object;
} ECalBackendCalDAVFactory;
typedef struct {
- ECalBackendFactoryClass parent_class;
+ ECalBackendFactoryClass parent_class;
} ECalBackendCalDAVFactoryClass;
static void
-e_cal_backend_caldav_factory_instance_init (ECalBackendCalDAVFactory *factory)
+ecb_caldav_factory_instance_init (ECalBackendCalDAVFactory *factory)
{
}
static const char *
_get_protocol (ECalBackendFactory *factory)
{
- return "caldav";
-}
-
-static ECalBackend*
-_events_new_backend (ECalBackendFactory *factory, ESource *source)
-{
- return g_object_new (E_TYPE_CAL_BACKEND_CALDAV,
- "source", source,
- "kind", ICAL_VEVENT_COMPONENT,
- NULL);
-}
-
-static icalcomponent_kind
-_events_get_kind (ECalBackendFactory *factory)
-{
- return ICAL_VEVENT_COMPONENT;
-}
-
-static void
-events_backend_factory_class_init (ECalBackendCalDAVFactoryClass *klass)
-{
- E_CAL_BACKEND_FACTORY_CLASS (klass)->get_protocol = _get_protocol;
- E_CAL_BACKEND_FACTORY_CLASS (klass)->get_kind = _events_get_kind;
- E_CAL_BACKEND_FACTORY_CLASS (klass)->new_backend = _events_new_backend;
-}
-
-static GType
-events_backend_factory_get_type (GTypeModule *module)
-{
- GType type;
-
- GTypeInfo info = {
- sizeof (ECalBackendCalDAVFactoryClass),
- NULL, /* base_class_init */
- NULL, /* base_class_finalize */
- (GClassInitFunc) events_backend_factory_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (ECalBackend),
- 0, /* n_preallocs */
- (GInstanceInitFunc) e_cal_backend_caldav_factory_instance_init
- };
-
- type = g_type_module_register_type (module,
- E_TYPE_CAL_BACKEND_FACTORY,
- "ECalBackendCalDAVEventsFactory",
- &info, 0);
-
- return type;
+ return "caldav";
}
+#define declare_functions(_type,_name) \
+ \
+static ECalBackend* \
+_new_backend_ ## _type (ECalBackendFactory *factory, ESource *source) \
+{ \
+ return g_object_new (E_TYPE_CAL_BACKEND_CALDAV, \
+ "source", source, \
+ "kind", ICAL_ ## _type ## _COMPONENT, \
+ NULL); \
+} \
+ \
+static icalcomponent_kind \
+_get_kind_ ## _type (ECalBackendFactory *factory) \
+{ \
+ return ICAL_ ## _type ## _COMPONENT; \
+} \
+ \
+static void \
+_backend_factory_class_init_ ## _type (ECalBackendCalDAVFactoryClass *klass) \
+{ \
+ ECalBackendFactoryClass *bc = E_CAL_BACKEND_FACTORY_CLASS (klass); \
+ \
+ g_return_if_fail (bc != NULL); \
+ \
+ bc->get_protocol = _get_protocol; \
+ bc->get_kind = _get_kind_ ## _type; \
+ bc->new_backend = _new_backend_ ## _type; \
+} \
+ \
+static GType \
+backend_factory_get_type_ ## _type (GTypeModule *module) \
+{ \
+ static GType type = 0; \
+ \
+ GTypeInfo info = { \
+ sizeof (ECalBackendCalDAVFactoryClass), \
+ NULL, /* base_class_init */ \
+ NULL, /* base_class_finalize */ \
+ (GClassInitFunc) _backend_factory_class_init_ ## _type, \
+ NULL, /* class_finalize */ \
+ NULL, /* class_data */ \
+ sizeof (ECalBackend), \
+ 0, /* n_preallocs */ \
+ (GInstanceInitFunc) ecb_caldav_factory_instance_init \
+ }; \
+ \
+ if (!type) { \
+ type = g_type_module_register_type (module, \
+ E_TYPE_CAL_BACKEND_FACTORY, \
+ _name, \
+ &info, 0); \
+ } \
+ \
+ return type; \
+} \
+
+declare_functions (VEVENT, "ECalBackendCalDAVEventsFactory");
+declare_functions (VTODO, "ECalBackendCalDAVTodosFactory");
+declare_functions (VJOURNAL, "ECalBackendCalDAVMemosFactory");
-static GType caldav_types[1];
+static GType caldav_types[3];
void
eds_module_initialize (GTypeModule *module)
{
- caldav_types[0] = events_backend_factory_get_type (module);
+ caldav_types[0] = backend_factory_get_type_VEVENT (module);
+ caldav_types[1] = backend_factory_get_type_VTODO (module);
+ caldav_types[2] = backend_factory_get_type_VJOURNAL (module);
}
void
@@ -115,6 +128,6 @@
void
eds_module_list_types (const GType **types, int *num_types)
{
- *types = caldav_types;
- *num_types = 1;
+ *types = caldav_types;
+ *num_types = 3;
}
Modified: branches/camel-gobject/calendar/backends/caldav/e-cal-backend-caldav.c
==============================================================================
--- branches/camel-gobject/calendar/backends/caldav/e-cal-backend-caldav.c (original)
+++ branches/camel-gobject/calendar/backends/caldav/e-cal-backend-caldav.c Tue Jan 6 01:56:50 2009
@@ -74,9 +74,6 @@
/* TRUE after caldav_open */
gboolean loaded;
- /* the open status */
- ECalBackendSyncStatus ostatus;
-
/* lock to protect cache */
GMutex *lock;
@@ -87,7 +84,7 @@
GCond *slave_gone_cond;
/* BG synch thread */
- GThread *synch_slave;
+ const GThread *synch_slave; /* just for a reference, whether thread exists */
SlaveCommand slave_cmd;
GTimeVal refresh_time;
gboolean do_synch;
@@ -115,6 +112,10 @@
gboolean disposed;
icaltimezone *default_zone;
+
+ /* support for 'getctag' extension */
+ gboolean ctag_supported;
+ gchar *ctag;
};
/* ************************************************************************* */
@@ -123,6 +124,7 @@
#define DEBUG_MESSAGE "message"
#define DEBUG_MESSAGE_HEADER "message:header"
#define DEBUG_MESSAGE_BODY "message:body"
+#define DEBUG_SERVER_ITEMS "items"
static gboolean caldav_debug_all = FALSE;
static GHashTable *caldav_debug_table = NULL;
@@ -151,7 +153,7 @@
debug_key,
debug_value);
- g_debug ("Adding %s to enabled debugging keys", debug_key);
+ d(g_debug ("Adding %s to enabled debugging keys", debug_key));
}
static gpointer
@@ -164,7 +166,7 @@
if (dbg) {
const char *ptr;
- g_debug ("Got debug env variable: [%s]", dbg);
+ d(g_debug ("Got debug env variable: [%s]", dbg));
caldav_debug_table = g_hash_table_new (g_str_hash,
g_str_equal);
@@ -466,7 +468,7 @@
*online = FALSE;
- if (priv->loaded != TRUE) {
+ if (!priv->loaded) {
return GNOME_Evolution_Calendar_OtherError;
}
@@ -542,13 +544,14 @@
static char *
xp_object_get_string (xmlXPathObjectPtr result)
{
- char *ret;
+ char *ret = NULL;
- if (result == NULL || result->type != XPATH_STRING) {
- return NULL;
- }
+ if (result == NULL)
+ return ret;
- ret = g_strdup ((char *) result->stringval);
+ if (result->type == XPATH_STRING) {
+ ret = g_strdup ((char *) result->stringval);
+ }
xmlXPathFreeObject (result);
return ret;
@@ -559,23 +562,26 @@
static char *
xp_object_get_href (xmlXPathObjectPtr result)
{
- char *ret;
+ char *ret = NULL;
char *val;
- if (result == NULL || result->type != XPATH_STRING) {
- return NULL;
- }
+ if (result == NULL)
+ return ret;
- val = (char *) result->stringval;
+ if (result->type == XPATH_STRING) {
+ val = (char *) result->stringval;
- if ((ret = g_strrstr (val, "/")) == NULL) {
- ret = val;
- } else {
- ret++; /* skip the unwanted "/" */
- }
+ if ((ret = g_strrstr (val, "/")) == NULL) {
+ ret = val;
+ } else {
+ ret++; /* skip the unwanted "/" */
+ }
+
+ ret = g_strdup (ret);
- ret = g_strdup (ret);
- d(g_debug ("found href: %s", ret));
+ if (caldav_debug_show (DEBUG_SERVER_ITEMS))
+ printf ("CalDAV found href: %s\n", ret);
+ }
xmlXPathFreeObject (result);
return ret;
@@ -585,16 +591,17 @@
static char *
xp_object_get_etag (xmlXPathObjectPtr result)
{
- char *ret;
+ char *ret = NULL;
char *str;
- if (result == NULL || result->type != XPATH_STRING) {
- return NULL;
- }
+ if (result == NULL)
+ return ret;
- str = (char *) result->stringval;
+ if (result->type == XPATH_STRING) {
+ str = (char *) result->stringval;
- ret = quote_etag (str);
+ ret = quote_etag (str);
+ }
xmlXPathFreeObject (result);
return ret;
@@ -604,20 +611,20 @@
xp_object_get_status (xmlXPathObjectPtr result)
{
gboolean res;
- guint ret;
-
+ guint ret = 0;
- if (result == NULL || result->type != XPATH_STRING) {
- return 0;
- }
+ if (result == NULL)
+ return ret;
- res = soup_headers_parse_status_line ((char *) result->stringval,
- NULL,
- &ret,
- NULL);
+ if (result->type == XPATH_STRING) {
+ res = soup_headers_parse_status_line ((char *) result->stringval,
+ NULL,
+ &ret,
+ NULL);
- if (res != TRUE) {
- ret = 0;
+ if (!res) {
+ ret = 0;
+ }
}
xmlXPathFreeObject (result);
@@ -628,13 +635,14 @@
static int
xp_object_get_number (xmlXPathObjectPtr result)
{
- int ret;
+ int ret = -1;
- if (result == NULL || result->type != XPATH_STRING) {
- return -1;
- }
+ if (result == NULL)
+ return ret;
- ret = result->boolval;
+ if (result->type == XPATH_STRING) {
+ ret = result->boolval;
+ }
xmlXPathFreeObject (result);
return ret;
@@ -647,7 +655,8 @@
#define XPATH_GETETAG_STATUS "string(/D:multistatus/D:response[%d]/D:propstat/D:prop/D:getetag/../../D:status)"
#define XPATH_GETETAG "string(/D:multistatus/D:response[%d]/D:propstat/D:prop/D:getetag)"
#define XPATH_CALENDAR_DATA "string(/D:multistatus/D:response[%d]/C:calendar-data)"
-
+#define XPATH_GETCTAG_STATUS "string(/D:multistatus/D:response/D:propstat/D:prop/CS:getctag/../../D:status)"
+#define XPATH_GETCTAG "string(/D:multistatus/D:response/D:propstat/D:prop/CS:getctag)"
typedef struct _CalDAVObject CalDAVObject;
@@ -750,6 +759,8 @@
}
out:
+ if (result != NULL)
+ xmlXPathFreeObject (result);
xmlXPathFreeContext (xpctx);
xmlFreeDoc (doc);
return res;
@@ -771,7 +782,9 @@
cbdav = E_CAL_BACKEND_CALDAV (data);
priv = E_CAL_BACKEND_CALDAV_GET_PRIVATE (cbdav);
- soup_auth_authenticate (auth, priv->username, priv->password);
+ /* do not send same password twice, but keep it for later use */
+ if (!retrying)
+ soup_auth_authenticate (auth, priv->username, priv->password);
}
static gint
@@ -905,8 +918,8 @@
priv = E_CAL_BACKEND_CALDAV_GET_PRIVATE (cbdav);
- /* priv->uri must NOT have trailing slash */
- uri = g_strconcat (priv->uri, "/" , target, NULL);
+ /* priv->uri *have* trailing slash already */
+ uri = g_strconcat (priv->uri, target, NULL);
return uri;
}
@@ -926,6 +939,8 @@
/* FIXME: setup text_uri */
message = soup_message_new (SOUP_METHOD_OPTIONS, priv->uri);
+ if (message == NULL)
+ return GNOME_Evolution_Calendar_NoSuchCal;
soup_message_headers_append (message->request_headers,
"User-Agent", "Evolution/" VERSION);
@@ -967,6 +982,139 @@
return GNOME_Evolution_Calendar_NoSuchCal;
}
+/* returns whether was able to read new ctag from the server's response */
+static gboolean
+parse_getctag_response (SoupMessage *message, gchar **new_ctag)
+{
+ xmlXPathContextPtr xpctx;
+ xmlDocPtr doc;
+ gboolean res = FALSE;
+
+ g_return_val_if_fail (message != NULL, FALSE);
+ g_return_val_if_fail (new_ctag != NULL, FALSE);
+
+ doc = xmlReadMemory (message->response_body->data,
+ message->response_body->length,
+ "response.xml",
+ NULL,
+ 0);
+
+ if (doc == NULL) {
+ return FALSE;
+ }
+
+ xpctx = xmlXPathNewContext (doc);
+ xmlXPathRegisterNs (xpctx, (xmlChar *) "D", (xmlChar *) "DAV:");
+ xmlXPathRegisterNs (xpctx, (xmlChar *) "CS", (xmlChar *) "http://calendarserver.org/ns/");
+
+ if (xp_object_get_status (xpath_eval (xpctx, XPATH_GETCTAG_STATUS)) == 200) {
+ char *txt = xp_object_get_string (xpath_eval (xpctx, XPATH_GETCTAG));
+
+ if (txt && *txt) {
+ int len = strlen (txt);
+
+ if (*txt == '\"' && len > 2 && txt [len - 1] == '\"') {
+ /* dequote */
+ *new_ctag = g_strndup (txt + 1, len - 2);
+ } else {
+ *new_ctag = txt;
+ txt = NULL;
+ }
+
+ res = (*new_ctag) != NULL;
+ }
+
+ g_free (txt);
+ }
+
+ xmlXPathFreeContext (xpctx);
+ xmlFreeDoc (doc);
+
+ return res;
+}
+
+/* Returns whether calendar changed on the server. This works only when server
+ supports 'getctag' extension. */
+static gboolean
+check_calendar_changed_on_server (ECalBackendCalDAV *cbdav)
+{
+ ECalBackendCalDAVPrivate *priv;
+ xmlOutputBufferPtr buf;
+ SoupMessage *message;
+ xmlDocPtr doc;
+ xmlNodePtr root, node;
+ xmlNsPtr ns, nsdav;
+ gboolean result = TRUE;
+
+ g_return_val_if_fail (cbdav != NULL, TRUE);
+
+ priv = E_CAL_BACKEND_CALDAV_GET_PRIVATE (cbdav);
+
+ /* no support for 'getctag', thus update cache */
+ if (!priv->ctag_supported)
+ return TRUE;
+
+ /* Prepare the soup message */
+ message = soup_message_new ("PROPFIND", priv->uri);
+ if (message == NULL)
+ return FALSE;
+
+ doc = xmlNewDoc ((xmlChar *) "1.0");
+ root = xmlNewNode (NULL, (xmlChar *) "propfind");
+ nsdav = xmlNewNs (root, (xmlChar *) "DAV:", NULL);
+ ns = xmlNewNs (root, (xmlChar *) "http://calendarserver.org/ns/", (xmlChar *) "CS");
+
+ node = xmlNewTextChild (root, nsdav, (xmlChar *) "prop", NULL);
+ node = xmlNewTextChild (node, nsdav, (xmlChar *) "getctag", NULL);
+ xmlSetNs (node, ns);
+
+ buf = xmlAllocOutputBuffer (NULL);
+ xmlNodeDumpOutput (buf, doc, root, 0, 1, NULL);
+ xmlOutputBufferFlush (buf);
+
+ soup_message_headers_append (message->request_headers,
+ "User-Agent", "Evolution/" VERSION);
+ soup_message_headers_append (message->request_headers,
+ "Depth", "0");
+
+ soup_message_set_request (message,
+ "application/xml",
+ SOUP_MEMORY_COPY,
+ (char *) buf->buffer->content,
+ buf->buffer->use);
+
+ /* Send the request now */
+ send_and_handle_redirection (priv->session, message, NULL);
+
+ /* Clean up the memory */
+ xmlOutputBufferClose (buf);
+ xmlFreeDoc (doc);
+
+ /* Check the result */
+ if (message->status_code != 207) {
+ /* does not support it, but report calendar changed to update cache */
+ priv->ctag_supported = FALSE;
+ } else {
+ char *ctag = NULL;
+
+ if (parse_getctag_response (message, &ctag)) {
+ if (ctag && priv->ctag && g_str_equal (ctag, priv->ctag)) {
+ /* ctag is same, no change in the calendar */
+ result = FALSE;
+ g_free (ctag);
+ } else {
+ g_free (priv->ctag);
+ priv->ctag = ctag;
+ }
+ } else {
+ priv->ctag_supported = FALSE;
+ }
+ }
+
+ g_object_unref (message);
+
+ return result;
+}
static gboolean
caldav_server_list_objects (ECalBackendCalDAV *cbdav, CalDAVObject **objs, int *len)
@@ -983,6 +1131,10 @@
gboolean result;
priv = E_CAL_BACKEND_CALDAV_GET_PRIVATE (cbdav);
+ /* Allocate the soup message */
+ message = soup_message_new ("REPORT", priv->uri);
+ if (message == NULL)
+ return FALSE;
/* Maybe we should just do a g_strdup_printf here? */
/* Prepare request body */
@@ -1002,7 +1154,18 @@
xmlSetProp (node, (xmlChar *) "name", (xmlChar *) "VCALENDAR");
sn = xmlNewTextChild (node, nscd, (xmlChar *) "comp-filter", NULL);
- xmlSetProp (sn, (xmlChar *) "name", (xmlChar *) "VEVENT");
+ switch (e_cal_backend_get_kind (E_CAL_BACKEND (cbdav))) {
+ default:
+ case ICAL_VEVENT_COMPONENT:
+ xmlSetProp (sn, (xmlChar *) "name", (xmlChar *) "VEVENT");
+ break;
+ case ICAL_VJOURNAL_COMPONENT:
+ xmlSetProp (sn, (xmlChar *) "name", (xmlChar *) "VJOURNAL");
+ break;
+ case ICAL_VTODO_COMPONENT:
+ xmlSetProp (sn, (xmlChar *) "name", (xmlChar *) "VTODO");
+ break;
+ }
/* ^^^ add timerange for performance? */
@@ -1011,7 +1174,6 @@
xmlOutputBufferFlush (buf);
/* Prepare the soup message */
- message = soup_message_new ("REPORT", priv->uri);
soup_message_headers_append (message->request_headers,
"User-Agent", "Evolution/" VERSION);
soup_message_headers_append (message->request_headers,
@@ -1032,7 +1194,9 @@
/* Check the result */
if (message->status_code != 207) {
- g_warning ("Sever did not response with 207, but with code %d\n", message->status_code);
+ g_warning ("Server did not response with 207, but with code %d (%s)", message->status_code, soup_status_get_phrase (message->status_code) ? soup_status_get_phrase (message->status_code) : "Unknown code");
+
+ g_object_unref (message);
return FALSE;
}
@@ -1061,6 +1225,8 @@
uri = caldav_generate_uri (cbdav, object->href);
message = soup_message_new (SOUP_METHOD_GET, uri);
g_free (uri);
+ if (message == NULL)
+ return GNOME_Evolution_Calendar_NoSuchCal;
soup_message_headers_append (message->request_headers,
"User-Agent", "Evolution/" VERSION);
@@ -1117,6 +1283,8 @@
uri = caldav_generate_uri (cbdav, object->href);
message = soup_message_new (SOUP_METHOD_PUT, uri);
g_free (uri);
+ if (message == NULL)
+ return GNOME_Evolution_Calendar_NoSuchCal;
soup_message_headers_append (message->request_headers,
"User-Agent", "Evolution/" VERSION);
@@ -1188,6 +1356,8 @@
uri = caldav_generate_uri (cbdav, object->href);
message = soup_message_new (SOUP_METHOD_DELETE, uri);
g_free (uri);
+ if (message == NULL)
+ return GNOME_Evolution_Calendar_NoSuchCal;
soup_message_headers_append (message->request_headers,
"User-Agent", "Evolution/" VERSION);
@@ -1240,31 +1410,34 @@
bkend = E_CAL_BACKEND (cbdav);
if (kind == ICAL_VCALENDAR_COMPONENT) {
-
kind = e_cal_backend_get_kind (bkend);
subcomp = icalcomponent_get_first_component (icomp, kind);
- comp = e_cal_component_new ();
- res = e_cal_component_set_icalcomponent (comp,
+ if (!subcomp) {
+ res = FALSE;
+ } else {
+ comp = e_cal_component_new ();
+ res = e_cal_component_set_icalcomponent (comp,
icalcomponent_new_clone (subcomp));
- if (res == TRUE) {
- icaltimezone *zone = icaltimezone_new ();
+ if (res) {
+ icaltimezone *zone = icaltimezone_new ();
- e_cal_component_set_href (comp, object->href);
- e_cal_component_set_etag (comp, object->etag);
+ e_cal_component_set_href (comp, object->href);
+ e_cal_component_set_etag (comp, object->etag);
- for (subcomp = icalcomponent_get_first_component (icomp, ICAL_VTIMEZONE_COMPONENT);
- subcomp;
- subcomp = icalcomponent_get_next_component (icomp, ICAL_VTIMEZONE_COMPONENT)) {
- /* copy timezones of the component to our cache to have it available later */
- if (icaltimezone_set_component (zone, subcomp))
- e_cal_backend_cache_put_timezone (priv->cache, zone);
- }
+ for (subcomp = icalcomponent_get_first_component (icomp, ICAL_VTIMEZONE_COMPONENT);
+ subcomp;
+ subcomp = icalcomponent_get_next_component (icomp, ICAL_VTIMEZONE_COMPONENT)) {
+ /* copy timezones of the component to our cache to have it available later */
+ if (icaltimezone_set_component (zone, subcomp))
+ e_cal_backend_cache_put_timezone (priv->cache, zone);
+ }
- icaltimezone_free (zone, TRUE);
- } else {
- g_object_unref (comp);
- comp = NULL;
+ icaltimezone_free (zone, TRUE);
+ } else {
+ g_object_unref (comp);
+ comp = NULL;
+ }
}
} else {
res = FALSE;
@@ -1272,7 +1445,7 @@
icalcomponent_free (icomp);
- if (res == FALSE) {
+ if (!res) {
return res;
}
@@ -1316,13 +1489,15 @@
len = 0;
sobjs = NULL;
+ if (!check_calendar_changed_on_server (cbdav)) {
+ /* no changes on the server, no update required */
+ return;
+ }
+
res = caldav_server_list_objects (cbdav, &sobjs, &len);
- if (res == FALSE) {
- /* FIXME: bloek! */
- g_warning ("Could not synch server BLehh!");
+ if (!res)
return;
- }
hindex = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
cobjs = e_cal_backend_cache_get_components (bcache);
@@ -1365,7 +1540,7 @@
res = synchronize_object (cbdav, object, ccomp, &created, &modified);
}
- if (res == TRUE) {
+ if (res) {
cobjs = g_list_remove (cobjs, ccomp);
}
@@ -1473,6 +1648,8 @@
/* signal we are done */
g_cond_signal (priv->slave_gone_cond);
+ priv->synch_slave = NULL;
+
/* we got killed ... */
g_mutex_unlock (priv->lock);
return NULL;
@@ -1550,7 +1727,6 @@
ECalBackendSyncStatus result;
ECalBackendCalDAVPrivate *priv;
ESource *source;
- GThread *slave;
const char *os_val;
const char *uri;
gsize len;
@@ -1568,14 +1744,13 @@
}
os_val = e_source_get_property (source, "auth");
-
- if (os_val) {
- priv->need_auth = TRUE;
- }
+ priv->need_auth = os_val != NULL;
os_val = e_source_get_property(source, "ssl");
uri = e_cal_backend_get_uri (E_CAL_BACKEND (cbdav));
+ g_free (priv->uri);
+ priv->uri = NULL;
if (g_str_has_prefix (uri, "caldav://")) {
const char *proto;
@@ -1586,13 +1761,11 @@
}
priv->uri = g_strconcat (proto, uri + 9, NULL);
-
} else {
-
priv->uri = g_strdup (uri);
}
- /* remove trailing slashes */
+ /* remove trailing slashes... */
len = strlen (priv->uri);
while (len--) {
if (priv->uri[len] == '/') {
@@ -1602,8 +1775,32 @@
}
}
+ /* ...and append exactly one slash */
+ if (priv->uri && *priv->uri) {
+ char *tmp = priv->uri;
+
+ priv->uri = g_strconcat (priv->uri, "/", NULL);
+
+ g_free (tmp);
+ }
+
if (priv->cache == NULL) {
- priv->cache = e_cal_backend_cache_new (priv->uri, E_CAL_SOURCE_TYPE_EVENT);
+ ECalSourceType source_type;
+
+ switch (e_cal_backend_get_kind (E_CAL_BACKEND (cbdav))) {
+ default:
+ case ICAL_VEVENT_COMPONENT:
+ source_type = E_CAL_SOURCE_TYPE_EVENT;
+ break;
+ case ICAL_VTODO_COMPONENT:
+ source_type = E_CAL_SOURCE_TYPE_TODO;
+ break;
+ case ICAL_VJOURNAL_COMPONENT:
+ source_type = E_CAL_SOURCE_TYPE_JOURNAL;
+ break;
+ }
+
+ priv->cache = e_cal_backend_cache_new (priv->uri, source_type);
if (priv->cache == NULL) {
result = GNOME_Evolution_Calendar_OtherError;
@@ -1615,17 +1812,20 @@
refresh = e_source_get_property (source, "refresh");
priv->refresh_time.tv_sec = (refresh && atoi (refresh) > 0) ? (60 * atoi (refresh)) : (DEFAULT_REFRESH_TIME);
- priv->slave_cmd = SLAVE_SHOULD_SLEEP;
- slave = g_thread_create (synch_slave_loop, cbdav, FALSE, NULL);
+ if (!priv->synch_slave) {
+ GThread *slave;
- if (slave == NULL) {
- g_warning ("Could not create synch slave");
- result = GNOME_Evolution_Calendar_OtherError;
- }
+ priv->slave_cmd = SLAVE_SHOULD_SLEEP;
+ slave = g_thread_create (synch_slave_loop, cbdav, FALSE, NULL);
- priv->report_changes = TRUE;
- priv->synch_slave = slave;
- priv->loaded = TRUE;
+ if (slave == NULL) {
+ g_warning ("Could not create synch slave");
+ result = GNOME_Evolution_Calendar_OtherError;
+ }
+
+ priv->report_changes = TRUE;
+ priv->synch_slave = slave;
+ }
out:
return result;
}
@@ -1648,32 +1848,39 @@
g_mutex_lock (priv->lock);
- if (priv->loaded != TRUE) {
- priv->ostatus = initialize_backend (cbdav);
+ /* let it decide the 'getctag' extension availability again */
+ g_free (priv->ctag);
+ priv->ctag = NULL;
+ priv->ctag_supported = TRUE;
+
+ if (!priv->loaded) {
+ status = initialize_backend (cbdav);
}
- if (priv->ostatus != GNOME_Evolution_Calendar_Success) {
+ if (status != GNOME_Evolution_Calendar_Success) {
g_mutex_unlock (priv->lock);
return status;
}
-
- if (priv->need_auth == TRUE) {
+ if (priv->need_auth) {
if ((username == NULL || password == NULL)) {
g_mutex_unlock (priv->lock);
return GNOME_Evolution_Calendar_AuthenticationRequired;
}
+ g_free (priv->username);
priv->username = g_strdup (username);
+ g_free (priv->password);
priv->password = g_strdup (password);
- priv->need_auth = FALSE;
}
- if (! priv->do_offline && priv->mode == CAL_MODE_LOCAL) {
+ if (!priv->do_offline && priv->mode == CAL_MODE_LOCAL) {
g_mutex_unlock (priv->lock);
return GNOME_Evolution_Calendar_RepositoryOffline;
}
+ priv->loaded = TRUE;
+
if (priv->mode == CAL_MODE_REMOTE) {
/* set forward proxy */
caldav_set_session_proxy (priv);
@@ -1707,7 +1914,7 @@
g_mutex_lock (priv->lock);
- if (priv->loaded != TRUE) {
+ if (!priv->loaded) {
g_mutex_unlock (priv->lock);
return GNOME_Evolution_Calendar_Success;
}
@@ -1722,7 +1929,14 @@
priv->cache = NULL;
priv->loaded = FALSE;
priv->slave_cmd = SLAVE_SHOULD_DIE;
- g_cond_signal (priv->cond);
+
+ if (priv->synch_slave) {
+ g_cond_signal (priv->cond);
+
+ /* wait until the slave died */
+ g_cond_wait (priv->slave_gone_cond, priv->lock);
+ }
+
g_mutex_unlock (priv->lock);
return GNOME_Evolution_Calendar_Success;
@@ -2099,7 +2313,6 @@
ekind);
while (scomp) {
-
/* Remove components from toplevel here */
*objects = g_list_prepend (*objects, scomp);
icalcomponent_remove_component (icomp, scomp);
@@ -2307,8 +2520,7 @@
return GNOME_Evolution_Calendar_InvalidObject;
}
- /* FIXME: use the e_cal_backend_xxx_kind call here */
- kind = ICAL_VEVENT_COMPONENT;
+ kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend));
status = extract_objects (icomp, kind, &objects);
if (status != GNOME_Evolution_Calendar_Success) {
@@ -2393,7 +2605,22 @@
ECalComponent *comp;
comp = e_cal_component_new ();
- e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_EVENT);
+
+ switch (e_cal_backend_get_kind (E_CAL_BACKEND (backend))) {
+ case ICAL_VEVENT_COMPONENT:
+ e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_EVENT);
+ break;
+ case ICAL_VTODO_COMPONENT:
+ e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_TODO);
+ break;
+ case ICAL_VJOURNAL_COMPONENT:
+ e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_JOURNAL);
+ break;
+ default:
+ g_object_unref (comp);
+ return GNOME_Evolution_Calendar_ObjectNotFound;
+ }
+
*object = e_cal_component_get_as_string (comp);
g_object_unref (comp);
@@ -2578,7 +2805,7 @@
for (iter = list; iter; iter = g_list_next (iter)) {
ECalComponent *comp = E_CAL_COMPONENT (iter->data);
- if (do_search == FALSE ||
+ if (!do_search ||
e_cal_backend_sexp_match_comp (sexp, comp, bkend)) {
char *str = e_cal_component_get_as_string (comp);
*objects = g_list_prepend (*objects, str);
@@ -2629,7 +2856,7 @@
for (iter = list; iter; iter = g_list_next (iter)) {
ECalComponent *comp = E_CAL_COMPONENT (iter->data);
- if (do_search == FALSE ||
+ if (!do_search ||
e_cal_backend_sexp_match_comp (sexp, comp, bkend)) {
char *str = e_cal_component_get_as_string (comp);
e_data_cal_view_notify_objects_added_1 (query, str);
@@ -2676,14 +2903,14 @@
static gboolean
caldav_is_loaded (ECalBackend *backend)
+{
+ ECalBackendCalDAV *cbdav;
+ ECalBackendCalDAVPrivate *priv;
-{ ECalBackendCalDAV *cbdav;
-ECalBackendCalDAVPrivate *priv;
-
-cbdav = E_CAL_BACKEND_CALDAV (backend);
-priv = E_CAL_BACKEND_CALDAV_GET_PRIVATE (cbdav);
+ cbdav = E_CAL_BACKEND_CALDAV (backend);
+ priv = E_CAL_BACKEND_CALDAV_GET_PRIVATE (cbdav);
-return priv->loaded;
+ return priv->loaded;
}
static CalMode
@@ -2716,9 +2943,11 @@
e_cal_backend_notify_mode (backend,
GNOME_Evolution_Calendar_CalListener_MODE_NOT_SUPPORTED,
cal_mode_to_corba (mode));
+ g_mutex_unlock (priv->lock);
+ return;
}
- if (priv->mode == mode || priv->loaded == FALSE) {
+ if (priv->mode == mode || !priv->loaded) {
priv->mode = mode;
e_cal_backend_notify_mode (backend,
GNOME_Evolution_Calendar_CalListener_MODE_SET,
@@ -2727,6 +2956,8 @@
return;
}
+ priv->mode = mode;
+
if (mode == CAL_MODE_REMOTE) {
/* Wake up the slave thread */
priv->slave_cmd = SLAVE_SHOULD_WORK;
@@ -2793,17 +3024,19 @@
g_mutex_lock (priv->lock);
- if (priv->disposed == TRUE) {
+ if (priv->disposed) {
g_mutex_unlock (priv->lock);
return;
}
/* stop the slave */
priv->slave_cmd = SLAVE_SHOULD_DIE;
- g_cond_signal (priv->cond);
+ if (priv->synch_slave) {
+ g_cond_signal (priv->cond);
- /* wait until the slave died */
- g_cond_wait (priv->slave_gone_cond, priv->lock);
+ /* wait until the slave died */
+ g_cond_wait (priv->slave_gone_cond, priv->lock);
+ }
g_object_unref (priv->session);
@@ -2831,6 +3064,9 @@
cbdav = E_CAL_BACKEND_CALDAV (object);
priv = E_CAL_BACKEND_CALDAV_GET_PRIVATE (cbdav);
+ g_free (priv->ctag);
+ priv->ctag = NULL;
+
g_mutex_free (priv->lock);
g_cond_free (priv->cond);
g_cond_free (priv->slave_gone_cond);
@@ -2862,6 +3098,10 @@
priv->do_synch = FALSE;
priv->loaded = FALSE;
+ /* Thinks the 'getctag' extension is available the first time, but unset it when realizes it isn't. */
+ priv->ctag_supported = TRUE;
+ priv->ctag = NULL;
+
priv->lock = g_mutex_new ();
priv->cond = g_cond_new ();
priv->slave_gone_cond = g_cond_new ();
Modified: branches/camel-gobject/calendar/backends/http/e-cal-backend-http.c
==============================================================================
--- branches/camel-gobject/calendar/backends/http/e-cal-backend-http.c (original)
+++ branches/camel-gobject/calendar/backends/http/e-cal-backend-http.c Tue Jan 6 01:56:50 2009
@@ -483,6 +483,11 @@
/* create message to be sent to server */
soup_message = soup_message_new (SOUP_METHOD_GET, priv->uri);
+ if (soup_message == NULL) {
+ priv->is_loading = FALSE;
+ return FALSE;
+ }
+
soup_message_headers_append (soup_message->request_headers, "User-Agent",
"Evolution/" VERSION);
soup_message_set_flags (soup_message, SOUP_MESSAGE_NO_REDIRECT);
Modified: branches/camel-gobject/calendar/backends/weather/Locations.xml.in
==============================================================================
--- branches/camel-gobject/calendar/backends/weather/Locations.xml.in (original)
+++ branches/camel-gobject/calendar/backends/weather/Locations.xml.in Tue Jan 6 01:56:50 2009
@@ -53,7 +53,7 @@
<location type="ccf" code="BFL" url="http://www.crh.noaa.gov/data/HNX/CCFHNX">Bakersfield</location>
<location type="ccf" code="CIH" url="http://www.crh.noaa.gov/data/VEF/CCFVEF">Bishop</location>
<location type="ccf" code="BLU" url="http://www.crh.noaa.gov/data/STO/CCFSTO">Blue Canyon</location>
- <location type="ccf" code="SLE" url="http://www.crh.noaa.gov/data/PQR/CCFPQR">Blythe</location>
+ <location type="ccf" code="BLH" url="http://www.crh.noaa.gov/data/PSR/CCFPSR">Blythe</location>
<location type="ccf" code="CEC" url="http://www.crh.noaa.gov/data/EKA/CCFEKA">Crescent City</location>
<location type="ccf" code="DAG" url="http://www.crh.noaa.gov/data/VEF/CCFVEF">Daggett</location>
<location type="ccf" code="FAT" url="http://www.crh.noaa.gov/data/HNX/CCFHNX">Fresno</location>
Modified: branches/camel-gobject/calendar/backends/weather/Makefile.am
==============================================================================
--- branches/camel-gobject/calendar/backends/weather/Makefile.am (original)
+++ branches/camel-gobject/calendar/backends/weather/Makefile.am Tue Jan 6 01:56:50 2009
@@ -13,7 +13,8 @@
-DE_DATA_SERVER_PREFIX=\"$(prefix)\" \
-DWEATHER_DATADIR=\""$(weatherdatadir)"\" \
$(EVOLUTION_CALENDAR_CFLAGS) \
- $(SOUP_CFLAGS)
+ $(SOUP_CFLAGS) \
+ $(LIBGWEATHER_CFLAGS)
extension_LTLIBRARIES = libecalbackendweather.la
@@ -31,12 +32,15 @@
$(top_builddir)/calendar/libecal/libecal-1.2.la \
$(top_builddir)/calendar/libedata-cal/libedata-cal-1.2.la \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
- $(top_builddir)/libebackend/libebackend-1.2.la \
+ $(top_builddir)/libebackend/libebackend-1.2.la \
$(EVOLUTION_CALENDAR_LIBS) \
- $(SOUP_LIBS)
+ $(SOUP_LIBS) \
+ $(LIBGWEATHER_LIBS)
-libecalbackendweather_la_LDFLAGS = \
- -module -avoid-version $(NO_UNDEFINED)
+libecalbackendweather_la_LDFLAGS = \
+ -module -avoid-version $(NO_UNDEFINED) \
+ $(LIBGWEATHER_LIBS)
+
weatherdata_in_files = Locations.xml.in
weatherdata_DATA = $(weatherdata_in_files:.xml.in=.xml)
Modified: branches/camel-gobject/calendar/backends/weather/e-cal-backend-weather.c
==============================================================================
--- branches/camel-gobject/calendar/backends/weather/e-cal-backend-weather.c (original)
+++ branches/camel-gobject/calendar/backends/weather/e-cal-backend-weather.c Tue Jan 6 01:56:50 2009
@@ -27,11 +27,15 @@
#include "e-cal-backend-weather.h"
#include "e-weather-source.h"
+#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include <libgweather/weather.h>
+#undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+
#define WEATHER_UID_EXT "-weather"
static gboolean reload_cb (ECalBackendWeather *cbw);
static gboolean begin_retrieval_cb (ECalBackendWeather *cbw);
-static ECalComponent* create_weather (ECalBackendWeather *cbw, WeatherForecast *report);
+static ECalComponent* create_weather (ECalBackendWeather *cbw, WeatherInfo *report, gboolean is_forecast);
static ECalBackendSyncStatus
e_cal_backend_weather_add_timezone (ECalBackendSync *backend, EDataCal *cal, const char *tzobj);
@@ -131,16 +135,17 @@
}
static void
-finished_retrieval_cb (GList *forecasts, ECalBackendWeather *cbw)
+finished_retrieval_cb (WeatherInfo *info, ECalBackendWeather *cbw)
{
ECalBackendWeatherPrivate *priv;
ECalComponent *comp;
icalcomponent *icomp;
GList *l;
+ char *obj;
priv = cbw->priv;
- if (forecasts == NULL) {
+ if (info == NULL) {
e_cal_backend_notify_error (E_CAL_BACKEND (cbw), _("Could not retrieve weather data"));
return;
}
@@ -167,14 +172,36 @@
g_list_free (l);
e_file_cache_clean (E_FILE_CACHE (priv->cache));
- for (l = forecasts; l != NULL; l = g_list_next (l)) {
- char *obj;
- comp = create_weather (cbw, l->data);
+ comp = create_weather (cbw, info, FALSE);
+ if (comp) {
+ GSList *forecasts;
+
e_cal_backend_cache_put_component (priv->cache, comp);
icomp = e_cal_component_get_icalcomponent (comp);
obj = icalcomponent_as_ical_string (icomp);
e_cal_backend_notify_object_created (E_CAL_BACKEND (cbw), obj);
g_free (obj);
+
+ forecasts = weather_info_get_forecast_list (info);
+ if (forecasts) {
+ GSList *f;
+
+ /* skip the first one, it's for today, which has been added above */
+ for (f = forecasts->next; f; f = f->next) {
+ WeatherInfo *nfo = f->data;
+
+ if (nfo) {
+ comp = create_weather (cbw, nfo, TRUE);
+ if (comp) {
+ e_cal_backend_cache_put_component (priv->cache, comp);
+ icomp = e_cal_component_get_icalcomponent (comp);
+ obj = icalcomponent_as_ical_string (icomp);
+ e_cal_backend_notify_object_created (E_CAL_BACKEND (cbw), obj);
+ g_free (obj);
+ }
+ }
+ }
+ }
}
priv->is_loading = FALSE;
@@ -210,86 +237,40 @@
}
static const char*
-getConditions (WeatherForecast *report)
-{
- switch (report->conditions) {
- case WEATHER_FAIR: return _("Fair");
- case WEATHER_SNOW_SHOWERS: return _("Snow showers");
- case WEATHER_SNOW: return _("Snow");
- case WEATHER_PARTLY_CLOUDY: return _("Partly cloudy");
- case WEATHER_SMOKE: return _("Smoke");
- case WEATHER_THUNDERSTORMS: return _("Thunderstorms");
- case WEATHER_CLOUDY: return _("Cloudy");
- case WEATHER_DRIZZLE: return _("Drizzle");
- case WEATHER_SUNNY: return _("Sunny");
- case WEATHER_DUST: return _("Dust");
- case WEATHER_CLEAR: return _("Clear");
- case WEATHER_MOSTLY_CLOUDY: return _("Mostly cloudy");
- case WEATHER_WINDY: return _("Windy");
- case WEATHER_RAIN_SHOWERS: return _("Rain showers");
- case WEATHER_FOGGY: return _("Foggy");
- case WEATHER_RAIN_OR_SNOW_MIXED: return _("Rain/snow mixed");
- case WEATHER_SLEET: return _("Sleet");
- case WEATHER_VERY_HOT_OR_HOT_HUMID: return _("Very hot/humid");
- case WEATHER_BLIZZARD: return _("Blizzard");
- case WEATHER_FREEZING_RAIN: return _("Freezing rain");
- case WEATHER_HAZE: return _("Haze");
- case WEATHER_BLOWING_SNOW: return _("Blowing snow");
- case WEATHER_FREEZING_DRIZZLE: return _("Freezing drizzle");
- case WEATHER_VERY_COLD_WIND_CHILL: return _("Very cold/wind chill");
- case WEATHER_RAIN: return _("Rain");
- default: return NULL;
- }
-}
-
-static const char*
-getCategory (WeatherForecast *report)
+getCategory (WeatherInfo *report)
{
- /* Right now this is based on which icons we have available */
- switch (report->conditions) {
- case WEATHER_FAIR: return _("Weather: Sunny");
- case WEATHER_SNOW_SHOWERS: return _("Weather: Snow");
- case WEATHER_SNOW: return _("Weather: Snow");
- case WEATHER_PARTLY_CLOUDY: return _("Weather: Partly Cloudy");
- case WEATHER_SMOKE: return _("Weather: Fog");
- case WEATHER_THUNDERSTORMS: return _("Weather: Thunderstorms");
- case WEATHER_CLOUDY: return _("Weather: Cloudy");
- case WEATHER_DRIZZLE: return _("Weather: Rain");
- case WEATHER_SUNNY: return _("Weather: Sunny");
- case WEATHER_DUST: return _("Weather: Fog");
- case WEATHER_CLEAR: return _("Weather: Sunny");
- case WEATHER_MOSTLY_CLOUDY: return _("Weather: Cloudy");
- case WEATHER_WINDY: return "";
- case WEATHER_RAIN_SHOWERS: return _("Weather: Rain");
- case WEATHER_FOGGY: return _("Weather: Fog");
- case WEATHER_RAIN_OR_SNOW_MIXED: return _("Weather: Rain");
- case WEATHER_SLEET: return _("Weather: Rain");
- case WEATHER_VERY_HOT_OR_HOT_HUMID: return _("Weather: Sunny");
- case WEATHER_BLIZZARD: return _("Weather: Snow");
- case WEATHER_FREEZING_RAIN: return _("Weather: Rain");
- case WEATHER_HAZE: return _("Weather: Fog");
- case WEATHER_BLOWING_SNOW: return _("Weather: Snow");
- case WEATHER_FREEZING_DRIZZLE: return _("Weather: Rain");
- case WEATHER_VERY_COLD_WIND_CHILL: return "";
- case WEATHER_RAIN: return _("Weather: Rain");
- default: return NULL;
+ struct {
+ const char *description;
+ const char *icon_name;
+ } categories[] = {
+ { N_("Weather: Fog"), "weather-fog" },
+ { N_("Weather: Cloudy"), "weather-few-clouds" },
+ { N_("Weather: Cloudy Night"), "weather-few-clouds-night" },
+ { N_("Weather: Overcast"), "weather-overcast" },
+ { N_("Weather: Showers"), "weather-showers" },
+ { N_("Weather: Snow"), "weather-snow" },
+ { N_("Weather: Sunny"), "weather-clear" },
+ { N_("Weather: Clear Night"), "weather-clear-night" },
+ { N_("Weather: Thunderstorms"), "weather-storm" },
+ { NULL, NULL }
+ };
+
+ int i;
+ const char *icon_name = weather_info_get_icon_name (report);
+
+ if (!icon_name)
+ return NULL;
+
+ for (i = 0; categories [i].description; i++) {
+ if (g_str_equal (categories [i].icon_name, icon_name))
+ return _(categories [i].description);
}
-}
-static float
-ctof (float c)
-{
- return ((c * 9.0f / 5.0f) + 32.0f);
-}
-
-static float
-cmtoin (float cm)
-{
- return cm / 2.54f;
+ return NULL;
}
static ECalComponent*
-create_weather (ECalBackendWeather *cbw, WeatherForecast *report)
+create_weather (ECalBackendWeather *cbw, WeatherInfo *report, gboolean is_forecast)
{
ECalBackendWeatherPrivate *priv;
ECalComponent *cal_comp;
@@ -297,30 +278,40 @@
icalcomponent *ical_comp;
struct icaltimetype itt;
ECalComponentDateTime dt;
- const char *uid;
+ char *uid;
GSList *text_list = NULL;
ECalComponentText *description;
- char *pop, *snow;
ESource *source;
gboolean metric;
- const char *format;
+ const char *tmp;
+ time_t update_time;
+ icaltimezone *update_zone = NULL;
+ const WeatherLocation *location;
g_return_val_if_fail (E_IS_CAL_BACKEND_WEATHER (cbw), NULL);
+ if (!weather_info_get_value_update (report, &update_time))
+ return NULL;
+
priv = cbw->priv;
source = e_cal_backend_get_source (E_CAL_BACKEND (cbw));
- format = e_source_get_property (source, "units");
- if (format == NULL) {
- format = e_source_get_property (source, "temperature");
- if (format == NULL)
+ tmp = e_source_get_property (source, "units");
+ if (tmp == NULL) {
+ tmp = e_source_get_property (source, "temperature");
+ if (tmp == NULL)
metric = FALSE;
else
- metric = (strcmp (format, "fahrenheit") != 0);
+ metric = (strcmp (tmp, "fahrenheit") != 0);
} else {
- metric = (strcmp (format, "metric") == 0);
+ metric = (strcmp (tmp, "metric") == 0);
}
+ if (metric)
+ weather_info_to_metric (report);
+ else
+ weather_info_to_imperial (report);
+
/* create the component and event object */
ical_comp = icalcomponent_new (ICAL_VEVENT_COMPONENT);
cal_comp = e_cal_component_new ();
@@ -329,57 +320,87 @@
/* set uid */
uid = e_cal_component_gen_uid ();
e_cal_component_set_uid (cal_comp, uid);
+ g_free (uid);
+
+ /* use timezone of the location to determine date for which this is set */
+ location = weather_info_get_location (report);
+ if (location && location->tz_hint && *location->tz_hint)
+ update_zone = icaltimezone_get_builtin_timezone (location->tz_hint);
+
+ if (!update_zone)
+ update_zone = priv->default_zone;
+
+ /* Set all-day event's date from forecast data - cannot set is_date,
+ because in that case no timezone conversion is done */
+ itt = icaltime_from_timet_with_zone (update_time, 0, update_zone);
+ itt.hour = 0;
+ itt.minute = 0;
+ itt.second = 0;
+ itt.is_date = 1;
- /* Set all-day event's date from forecast data */
- itt = icaltime_from_timet (report->date, 1);
dt.value = &itt;
- dt.tzid = NULL;
+ if (update_zone)
+ dt.tzid = icaltimezone_get_tzid (update_zone);
+ else
+ dt.tzid = NULL;
+
e_cal_component_set_dtstart (cal_comp, &dt);
- itt = icaltime_from_timet (report->date, 1);
icaltime_adjust (&itt, 1, 0, 0, 0);
- dt.value = &itt;
- dt.tzid = NULL;
/* We have to add 1 day to DTEND, as it is not inclusive. */
e_cal_component_set_dtend (cal_comp, &dt);
- /* The summary is the high or high/low temperatures */
- if (report->high == report->low) {
- if (metric)
- comp_summary.value = g_strdup_printf (_("%.1fÂC - %s"), report->high, priv->city);
- else
- comp_summary.value = g_strdup_printf (_("%.1fÂF - %s"), ctof (report->high), priv->city);
+ if (is_forecast) {
+ gdouble tmin = 0.0, tmax = 0.0;
+
+ if (weather_info_get_value_temp_min (report, TEMP_UNIT_DEFAULT, &tmin) &&
+ weather_info_get_value_temp_max (report, TEMP_UNIT_DEFAULT, &tmax) &&
+ tmin != tmax) {
+ /* because weather_info_get_temp* uses one internal buffer, thus finally
+ the last value is shown for both, which is obviously wrong */
+ GString *str = g_string_new (priv->city);
+
+ g_string_append (str, " : ");
+ g_string_append (str, weather_info_get_temp_min (report));
+ g_string_append (str, "/");
+ g_string_append (str, weather_info_get_temp_max (report));
+
+ comp_summary.value = g_string_free (str, FALSE);
+ } else {
+ comp_summary.value = g_strdup_printf ("%s : %s", priv->city, weather_info_get_temp (report));
+ }
} else {
- if (metric)
- comp_summary.value = g_strdup_printf (_("%.1f/%.1fÂC - %s"), report->high, report->low, priv->city);
- else
- comp_summary.value = g_strdup_printf (_("%.1f/%.1fÂF - %s"), ctof (report->high), ctof (report->low), priv->city);
+ gdouble tmin = 0.0, tmax = 0.0;
+ /* because weather_info_get_temp* uses one internal buffer, thus finally
+ the last value is shown for both, which is obviously wrong */
+ GString *str = g_string_new (priv->city);
+
+ g_string_append (str, " : ");
+ if (weather_info_get_value_temp_min (report, TEMP_UNIT_DEFAULT, &tmin) &&
+ weather_info_get_value_temp_max (report, TEMP_UNIT_DEFAULT, &tmax) &&
+ tmin != tmax) {
+ g_string_append (str, weather_info_get_temp_min (report));
+ g_string_append (str, "/");
+ g_string_append (str, weather_info_get_temp_max (report));
+ } else {
+ g_string_append (str, weather_info_get_temp (report));
+ }
+
+ comp_summary.value = g_string_free (str, FALSE);
}
comp_summary.altrep = NULL;
e_cal_component_set_summary (cal_comp, &comp_summary);
+ g_free ((char *)comp_summary.value);
+
+ tmp = weather_info_get_forecast (report);
+ comp_summary.value = weather_info_get_weather_summary (report);
- if (report->pop != 0)
- pop = g_strdup_printf (_("%d%% chance of precipitation\n"), report->pop);
- else
- pop = g_strdup ("");
- if (report->snowhigh == 0)
- snow = g_strdup ("");
- else if (report->snowhigh == report->snowlow) {
- if (metric)
- snow = g_strdup_printf (_("%.1fcm snow\n"), report->snowhigh);
- else
- snow = g_strdup_printf (_("%.1fin snow\n"), cmtoin(report->snowhigh));
- } else {
- if (metric)
- snow = g_strdup_printf (_("%.1f-%.1fcm snow\n"), report->snowlow, report->snowhigh);
- else
- snow = g_strdup_printf (_("%.1f-%.1fin snow\n"), cmtoin(report->snowlow), cmtoin(report->snowhigh));
- }
description = g_new0 (ECalComponentText, 1);
- description->value = g_strdup_printf ("%s\n%s%s", getConditions (report), pop, snow);
+ description->value = g_strconcat (is_forecast ? "" : comp_summary.value, is_forecast ? "" : "\n", tmp ? _("Forecast") : "", tmp ? ":" : "", tmp && !is_forecast ? "\n" : "", tmp ? tmp : "", NULL);
description->altrep = "";
text_list = g_slist_append (text_list, description);
e_cal_component_set_description_list (cal_comp, text_list);
+ g_free ((char *)comp_summary.value);
/* Set category and visibility */
e_cal_component_set_categories (cal_comp, getCategory (report));
@@ -390,9 +411,6 @@
e_cal_component_commit_sequence (cal_comp);
- g_free (pop);
- g_free (snow);
-
return cal_comp;
}
Modified: branches/camel-gobject/calendar/backends/weather/e-weather-source-ccf.c
==============================================================================
--- branches/camel-gobject/calendar/backends/weather/e-weather-source-ccf.c (original)
+++ branches/camel-gobject/calendar/backends/weather/e-weather-source-ccf.c Tue Jan 6 01:56:50 2009
@@ -26,18 +26,14 @@
#include <string.h>
#include <stdlib.h>
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-
#include <glib/gi18n-lib.h>
-#include <gconf/gconf-client.h>
-
-#include "libedataserver/e-xml-utils.h"
-
#include "e-weather-source-ccf.h"
-#define DATA_SIZE 5000
+#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include <libgweather/weather.h>
+#include <libgweather/gweather-xml.h>
+#undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
#ifdef G_OS_WIN32
@@ -58,86 +54,98 @@
#define strtok_r(s,sep,lasts) (*(lasts)=strtok((s),(sep)))
#endif
-static gchar *
-parse_for_url (char *code, char *name, xmlNode *parent)
+struct search_struct
{
- xmlNode *child;
- if (parent->type == XML_ELEMENT_NODE) {
- if (strcmp ((char*)parent->name, "location") == 0) {
- child = parent->children;
- g_assert (child->type == XML_TEXT_NODE);
- if (strcmp ((char*)child->content, name) == 0) {
- xmlAttr *attr;
- gchar *url = NULL;
- for (attr = parent->properties; attr; attr = attr->next) {
- if (strcmp ((char*)attr->name, "code") == 0) {
- if (strcmp ((char*)attr->children->content, code) != 0)
- return NULL;
- }
- if (strcmp ((char*)attr->name, "url") == 0)
- url = (char*)attr->children->content;
- }
- return g_strdup (url);
- }
- return NULL;
- } else {
- for (child = parent->children; child; child = child->next) {
- gchar *url = parse_for_url (code, name, child);
- if (url)
- return url;
- }
- }
+ const char *code;
+ const char *name;
+ gboolean is_old;
+ WeatherLocation *location;
+};
+
+static gboolean
+find_location_func (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *node, gpointer data)
+{
+ WeatherLocation *wl = NULL;
+ struct search_struct *search = (struct search_struct *)data;
+
+ gtk_tree_model_get (model, node, GWEATHER_XML_COL_POINTER, &wl, -1);
+ if (!wl || !wl->name || !wl->code || !search || search->location)
+ return FALSE;
+
+ if (((!strcmp (wl->code, search->code)) || (search->is_old && !strcmp (wl->code + 1, search->code))) &&
+ (!strcmp (wl->name, search->name))) {
+ search->location = weather_location_clone (wl);
+ return TRUE;
}
- return NULL;
+
+ return FALSE;
}
-static void
-find_station_url (gchar *station, EWeatherSourceCCF *source)
+static WeatherLocation *
+find_location (const gchar *code_name, gboolean is_old)
{
- xmlDoc *doc;
- xmlNode *root;
- gchar **sstation;
- gchar *url;
- gchar *filename;
-
- sstation = g_strsplit (station, "/", 2);
-
-#ifndef G_OS_WIN32
- filename = g_strdup (WEATHER_DATADIR "/Locations.xml");
-#else
- filename = e_util_replace_prefix (E_DATA_SERVER_PREFIX,
- e_util_get_prefix (),
- WEATHER_DATADIR "/Locations.xml");
-#endif
+ GtkTreeModel *model;
+ gchar **ids;
+ struct search_struct search;
+
+ search.location = NULL;
- doc = e_xml_parse_file (filename);
+ ids = g_strsplit (code_name, "/", 2);
- g_assert (doc != NULL);
+ if (!ids || !ids [0] || !ids [1])
+ goto done;
- root = xmlDocGetRootElement (doc);
+ model = gweather_xml_load_locations ();
+ if (!model)
+ goto done;
- url = parse_for_url (sstation[0], sstation[1], root);
+ search.code = ids [0];
+ search.name = ids [1];
+ search.is_old = is_old;
+ search.location = NULL;
- source->url = g_strdup (url);
- source->substation = g_strdup (sstation[0]);
+ gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc) find_location_func, &search);
- g_strfreev (sstation);
+ gweather_xml_free_locations (model);
+ g_strfreev (ids);
+
+done:
+ return search.location;
}
EWeatherSource*
e_weather_source_ccf_new (const char *uri)
{
- /* Our URI is formatted as weather://ccf/AAA[/BBB] - AAA is the 3-letter station
+ /* Old URI is formatted as weather://ccf/AAA[/BBB] - AAA is the 3-letter station
* code for identifying the providing station (subdirectory within the crh data
* repository). BBB is an optional additional station ID for the station within
* the CCF file. If not present, BBB is assumed to be the same station as AAA.
+ * But the new URI is as weather://code/name, where code is 4-letter code.
+ * So if got the old URI, then migrate to the new one, if possible.
*/
- EWeatherSourceCCF *source = E_WEATHER_SOURCE_CCF (g_object_new (e_weather_source_ccf_get_type (), NULL));
- find_station_url (strchr (uri, '/') + 1, source);
+ WeatherLocation *wl;
+ EWeatherSourceCCF *source;
+
+ if (!uri)
+ return NULL;
+
+ if (strncmp (uri, "ccf/", 4) == 0)
+ wl = find_location (uri + 4, TRUE);
+ else
+ wl = find_location (uri, FALSE);
+
+ if (!wl)
+ return NULL;
+
+ source = E_WEATHER_SOURCE_CCF (g_object_new (e_weather_source_ccf_get_type (), NULL));
+ source->location = wl;
+ source->info = NULL;
+
return E_WEATHER_SOURCE (source);
}
+#if 0
static GSList*
tokenize (char *buffer)
{
@@ -388,74 +396,48 @@
g_free (forecasts);
g_list_free (fc);
}
+#endif
static void
-retrieval_done (SoupSession *session, SoupMessage *message, EWeatherSourceCCF *source)
+parse_done (WeatherInfo *info, gpointer data)
{
- /* check status code */
- if (!SOUP_STATUS_IS_SUCCESSFUL (message->status_code)) {
- source->done (NULL, source->finished_data);
+ EWeatherSourceCCF *ccfsource = (EWeatherSourceCCF *) data;
+
+ if (!ccfsource)
+ return;
+
+ if (!info || !weather_info_is_valid (info)) {
+ ccfsource->done (NULL, ccfsource->finished_data);
return;
}
- e_weather_source_ccf_do_parse (source, (char *)message->response_body->data);
+ ccfsource->done (info, ccfsource->finished_data);
}
static void
e_weather_source_ccf_parse (EWeatherSource *source, EWeatherSourceFinished done, gpointer data)
{
EWeatherSourceCCF *ccfsource = (EWeatherSourceCCF*) source;
- SoupMessage *soup_message;
+ WeatherPrefs prefs;
ccfsource->finished_data = data;
-
ccfsource->done = done;
- if (!ccfsource->soup_session) {
- GConfClient *conf_client;
- ccfsource->soup_session = soup_session_async_new ();
-
- /* set the HTTP proxy, if configuration is set to do so */
- conf_client = gconf_client_get_default ();
- if (gconf_client_get_bool (conf_client, "/system/http_proxy/use_http_proxy", NULL)) {
- char *server, *proxy_uri;
- int port;
-
- server = gconf_client_get_string (conf_client, "/system/http_proxy/host", NULL);
- port = gconf_client_get_int (conf_client, "/system/http_proxy/port", NULL);
-
- if (server && server[0]) {
- SoupURI *suri;
- if (gconf_client_get_bool (conf_client, "/system/http_proxy/use_authentication", NULL)) {
- char *user, *password;
-
- user = gconf_client_get_string (conf_client,
- "/system/http_proxy/authentication_user",
- NULL);
- password = gconf_client_get_string (conf_client,
- "/system/http_proxy/authentication_password",
- NULL);
-
- proxy_uri = g_strdup_printf("http://%s:%s %s:%d", user, password, server, port);
-
- g_free (user);
- g_free (password);
- } else
- proxy_uri = g_strdup_printf ("http://%s:%d", server, port);
-
- suri = soup_uri_new (proxy_uri);
- g_object_set (G_OBJECT (ccfsource->soup_session), SOUP_SESSION_PROXY_URI, suri, NULL);
-
- soup_uri_free (suri);
- g_free (server);
- g_free (proxy_uri);
- }
- }
- g_object_unref (conf_client);
+ prefs.type = FORECAST_LIST;
+ prefs.radar = FALSE;
+ prefs.radar_custom_url = NULL;
+ prefs.temperature_unit = TEMP_UNIT_CENTIGRADE;
+ prefs.speed_unit = SPEED_UNIT_MS;
+ prefs.pressure_unit = PRESSURE_UNIT_HPA;
+ prefs.distance_unit = DISTANCE_UNIT_METERS;
+
+ if (ccfsource->location && !ccfsource->info) {
+ ccfsource->info = weather_info_new (ccfsource->location, &prefs, parse_done, source);
+ weather_location_free (ccfsource->location);
+ ccfsource->location = NULL;
+ } else {
+ ccfsource->info = weather_info_update (ccfsource->info, &prefs, parse_done, source);
}
-
- soup_message = soup_message_new (SOUP_METHOD_GET, ccfsource->url);
- soup_session_queue_message (ccfsource->soup_session, soup_message, (SoupSessionCallback) retrieval_done, source);
}
static void
@@ -471,9 +453,8 @@
static void
e_weather_source_ccf_init (EWeatherSourceCCF *source)
{
- source->url = NULL;
- source->substation = NULL;
- source->soup_session = NULL;
+ source->location = NULL;
+ source->info = NULL;
}
GType
Modified: branches/camel-gobject/calendar/backends/weather/e-weather-source-ccf.h
==============================================================================
--- branches/camel-gobject/calendar/backends/weather/e-weather-source-ccf.h (original)
+++ branches/camel-gobject/calendar/backends/weather/e-weather-source-ccf.h Tue Jan 6 01:56:50 2009
@@ -26,6 +26,10 @@
#include <libsoup/soup-uri.h>
#include "e-weather-source.h"
+#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include <libgweather/weather.h>
+#undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+
G_BEGIN_DECLS
#define E_TYPE_WEATHER_SOURCE_CCF (e_weather_source_ccf_get_type ())
@@ -40,10 +44,10 @@
struct _EWeatherSourceCCF {
EWeatherSource parent;
- char *url;
- char *substation;
+ WeatherLocation *location;
+ WeatherInfo *info;
+
EWeatherSourceFinished done;
- SoupSession *soup_session;
gpointer finished_data;
};
Modified: branches/camel-gobject/calendar/backends/weather/e-weather-source.c
==============================================================================
--- branches/camel-gobject/calendar/backends/weather/e-weather-source.c (original)
+++ branches/camel-gobject/calendar/backends/weather/e-weather-source.c Tue Jan 6 01:56:50 2009
@@ -70,7 +70,5 @@
{
const char *base = uri + 10; /* skip weather:// */
- if (strncmp (base, "ccf/", 4) == 0)
- return e_weather_source_ccf_new (base);
- return NULL;
+ return e_weather_source_ccf_new (base);
}
Modified: branches/camel-gobject/calendar/backends/weather/e-weather-source.h
==============================================================================
--- branches/camel-gobject/calendar/backends/weather/e-weather-source.h (original)
+++ branches/camel-gobject/calendar/backends/weather/e-weather-source.h Tue Jan 6 01:56:50 2009
@@ -24,6 +24,10 @@
#include <glib-object.h>
#include <time.h>
+#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include <libgweather/weather.h>
+#undef GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+
G_BEGIN_DECLS
typedef enum {
@@ -54,21 +58,7 @@
WEATHER_RAIN,
} WeatherConditions;
-typedef struct {
- /* date, in UTC */
- time_t date;
- /* expected conditions */
- WeatherConditions conditions;
- /* internal storage is always in celcius and should be
- * converted based on the user's current locale setting */
- float high, low;
- /* probability of precipitation */
- int pop;
- /* snowfall forecast - internal storage in cm */
- float snowhigh, snowlow;
-} WeatherForecast;
-
-typedef void (*EWeatherSourceFinished)(GList *results, gpointer data);
+typedef void (*EWeatherSourceFinished)(WeatherInfo *result, gpointer data);
#define E_TYPE_WEATHER_SOURCE (e_weather_source_get_type ())
#define E_WEATHER_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_WEATHER_SOURCE, EWeatherSource))
Modified: branches/camel-gobject/calendar/libecal/e-cal-util.h
==============================================================================
--- branches/camel-gobject/calendar/libecal/e-cal-util.h (original)
+++ branches/camel-gobject/calendar/libecal/e-cal-util.h Tue Jan 6 01:56:50 2009
@@ -115,6 +115,7 @@
#define CAL_STATIC_CAPABILITY_ORGANIZER_MUST_ATTEND "organizer-must-attend"
#define CAL_STATIC_CAPABILITY_ORGANIZER_NOT_EMAIL_ADDRESS "organizer-not-email-address"
#define CAL_STATIC_CAPABILITY_REMOVE_ALARMS "remove-alarms"
+#define CAL_STATIC_CAPABILITY_CREATE_MESSAGES "create-messages"
#define CAL_STATIC_CAPABILITY_SAVE_SCHEDULES "save-schedules"
#define CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK "no-conv-to-assign-task"
#define CAL_STATIC_CAPABILITY_NO_CONV_TO_RECUR "no-conv-to-recur"
Modified: branches/camel-gobject/calendar/libecal/e-cal.c
==============================================================================
--- branches/camel-gobject/calendar/libecal/e-cal.c (original)
+++ branches/camel-gobject/calendar/libecal/e-cal.c Tue Jan 6 01:56:50 2009
@@ -1386,7 +1386,16 @@
priv->local_attachment_store =
g_filename_to_uri (filename, NULL, NULL);
g_free (filename);
+ } else if (g_str_has_prefix (priv->uri, "mapi://")) {
+ gchar *filename = g_build_filename (g_get_home_dir (),
+ ".evolution/cache/calendar",
+ mangled_uri,
+ NULL);
+ priv->local_attachment_store =
+ g_filename_to_uri (filename, NULL, NULL);
+ g_free (filename);
}
+
g_free (mangled_uri);
}
Modified: branches/camel-gobject/camel/camel-db.c
==============================================================================
--- branches/camel-gobject/camel/camel-db.c (original)
+++ branches/camel-gobject/camel/camel-db.c Tue Jan 6 01:56:50 2009
@@ -47,6 +47,8 @@
static GStaticRecMutex trans_lock = G_STATIC_REC_MUTEX_INIT;
+static int write_mir (CamelDB *cdb, const char *folder_name, CamelMIRecord *record, CamelException *ex, gboolean delete_old_record);
+
static int
cdb_sql_exec (sqlite3 *db, const char* stmt, CamelException *ex)
{
@@ -124,7 +126,6 @@
cache = g_strdup ("PRAGMA cache_size=100");
camel_db_command (cdb, cache, NULL);
-
g_free (cache);
sqlite3_busy_timeout (cdb->db, CAMEL_DB_SLEEP_INTERVAL);
@@ -190,7 +191,8 @@
{
if (!cdb)
return -1;
- g_static_rec_mutex_lock (&trans_lock);
+ if (g_getenv("SQLITE_TRANSLOCK"))
+ g_static_rec_mutex_lock (&trans_lock);
g_mutex_lock (cdb->lock);
return (cdb_sql_exec (cdb->db, "BEGIN", ex));
@@ -207,7 +209,8 @@
ret = cdb_sql_exec (cdb->db, "COMMIT", ex);
END;
g_mutex_unlock (cdb->lock);
- g_static_rec_mutex_unlock (&trans_lock);
+ if (g_getenv("SQLITE_TRANSLOCK"))
+ g_static_rec_mutex_unlock (&trans_lock);
CAMEL_DB_RELEASE_SQLITE_MEMORY;
@@ -221,7 +224,8 @@
ret = cdb_sql_exec (cdb->db, "ROLLBACK", ex);
g_mutex_unlock (cdb->lock);
- g_static_rec_mutex_unlock (&trans_lock);
+ if (g_getenv("SQLITE_TRANSLOCK"))
+ g_static_rec_mutex_unlock (&trans_lock);
CAMEL_DB_RELEASE_SQLITE_MEMORY;
return ret;
@@ -453,7 +457,7 @@
if (!cdb)
return ret;
- d(g_print ("\n%s:\n%s \n", __FUNCTION__, stmt));
+ d(g_print ("\n%s:\n%s \n", G_STRFUNC, stmt));
g_mutex_lock (cdb->lock);
START(stmt);
@@ -558,6 +562,53 @@
return ret;
}
+struct _db_data_uids_flags {
+ GPtrArray *uids;
+ GPtrArray *flags;
+};
+static int
+read_uids_flags_callback (void *ref, int ncol, char ** cols, char ** name)
+{
+ struct _db_data_uids_flags *data= (struct _db_data_uids_flags *) ref;
+
+ int i;
+ for (i = 0; i < ncol; ++i) {
+ if (!strcmp (name [i], "uid"))
+ g_ptr_array_add (data->uids, (char *) (camel_pstring_strdup(cols [i])));
+ else if (!strcmp (name [i], "flags"))
+ g_ptr_array_add (data->flags, GUINT_TO_POINTER(strtoul (cols [i], NULL, 10)));
+ }
+
+ return 0;
+}
+
+int
+camel_db_get_folder_uids_flags (CamelDB *db, char *folder_name, char *sort_by, char *collate, GPtrArray *summary, GHashTable *table, CamelException *ex)
+{
+ GPtrArray *uids = summary;
+ GPtrArray *flags = g_ptr_array_new ();
+ char *sel_query;
+ int ret;
+ struct _db_data_uids_flags data;
+ int i;
+
+ data.uids = uids;
+ data.flags = flags;
+
+
+ sel_query = sqlite3_mprintf("SELECT uid,flags FROM %Q%s%s%s%s", folder_name, sort_by ? " order by " : "", sort_by ? sort_by: "", (sort_by && collate) ? " collate " : "", (sort_by && collate) ? collate : "");
+
+ ret = camel_db_select (db, sel_query, read_uids_flags_callback, &data, ex);
+ sqlite3_free (sel_query);
+
+ for (i=0; i<uids->len; i++) {
+ g_hash_table_insert (table, uids->pdata[i], flags->pdata[i]);
+ }
+
+ g_ptr_array_free (flags, TRUE);
+ return ret;
+}
+
static int
read_uids_callback (void *ref, int ncol, char ** cols, char ** name)
{
@@ -763,13 +814,29 @@
return ret;
}
+
+int
+camel_db_write_fresh_message_info_record (CamelDB *cdb, const char *folder_name, CamelMIRecord *record, CamelException *ex)
+{
+ return write_mir (cdb, folder_name, record, ex, FALSE);
+}
+
+
int
camel_db_write_message_info_record (CamelDB *cdb, const char *folder_name, CamelMIRecord *record, CamelException *ex)
{
+ return write_mir (cdb, folder_name, record, ex, TRUE);
+}
+
+static int
+write_mir (CamelDB *cdb, const char *folder_name, CamelMIRecord *record, CamelException *ex, gboolean delete_old_record)
+{
int ret;
char *del_query;
char *ins_query;
+ /* FIXME: We should migrate from this DELETE followed by INSERT model to an INSERT OR REPLACE model as pointed out by pvanhoof */
+
/* NB: UGLIEST Hack. We can't modify the schema now. We are using msg_security (an unsed one to notify of FLAGGED/Dirty infos */
ins_query = sqlite3_mprintf ("INSERT INTO %Q VALUES (%Q, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %ld, %ld, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q, %Q )",
@@ -783,7 +850,8 @@
record->part, record->labels, record->usertags,
record->cinfo, record->bdata);
- del_query = sqlite3_mprintf ("DELETE FROM %Q WHERE uid = %Q", folder_name, record->uid);
+ if (delete_old_record)
+ del_query = sqlite3_mprintf ("DELETE FROM %Q WHERE uid = %Q", folder_name, record->uid);
#if 0
char *upd_query;
@@ -793,12 +861,14 @@
g_free (upd_query);
#else
- ret = camel_db_add_to_transaction (cdb, del_query, ex);
+ if (delete_old_record)
+ ret = camel_db_add_to_transaction (cdb, del_query, ex);
ret = camel_db_add_to_transaction (cdb, ins_query, ex);
#endif
- sqlite3_free (del_query);
+ if (delete_old_record)
+ sqlite3_free (del_query);
sqlite3_free (ins_query);
return ret;
@@ -1149,3 +1219,39 @@
CAMEL_DB_RELEASE_SQLITE_MEMORY;
return ret;
}
+
+int camel_db_start_in_memory_transactions (CamelDB *cdb, CamelException *ex)
+{
+ int ret;
+ char *cmd = sqlite3_mprintf ("ATTACH DATABASE ':memory:' AS %s", CAMEL_DB_IN_MEMORY_DB);
+
+ ret = camel_db_command (cdb, cmd, ex);
+ sqlite3_free (cmd);
+
+ cmd = sqlite3_mprintf ("CREATE TEMPORARY TABLE %Q ( uid TEXT PRIMARY KEY , flags INTEGER , msg_type INTEGER , read INTEGER , deleted INTEGER , replied INTEGER , important INTEGER , junk INTEGER , attachment INTEGER , msg_security INTEGER , size INTEGER , dsent NUMERIC , dreceived NUMERIC , subject TEXT , mail_from TEXT , mail_to TEXT , mail_cc TEXT , mlist TEXT , followup_flag TEXT , followup_completed_on TEXT , followup_due_by TEXT , part TEXT , labels TEXT , usertags TEXT , cinfo TEXT , bdata TEXT )", CAMEL_DB_IN_MEMORY_TABLE);
+ ret = camel_db_command (cdb, cmd, ex);
+ if (ret != 0 )
+ abort ();
+ sqlite3_free (cmd);
+
+ return ret;
+}
+
+int camel_db_flush_in_memory_transactions (CamelDB *cdb, const char * folder_name, CamelException *ex)
+{
+ int ret;
+ char *cmd = sqlite3_mprintf ("INSERT INTO %Q SELECT * FROM %Q", folder_name, CAMEL_DB_IN_MEMORY_TABLE);
+
+ ret = camel_db_command (cdb, cmd, ex);
+ sqlite3_free (cmd);
+
+ cmd = sqlite3_mprintf ("DROP TABLE %Q", CAMEL_DB_IN_MEMORY_TABLE);
+ ret = camel_db_command (cdb, cmd, ex);
+ sqlite3_free (cmd);
+
+ cmd = sqlite3_mprintf ("DETACH %Q", CAMEL_DB_IN_MEMORY_DB);
+ ret = camel_db_command (cdb, cmd, ex);
+ sqlite3_free (cmd);
+
+ return ret;
+}
Modified: branches/camel-gobject/camel/camel-db.h
==============================================================================
--- branches/camel-gobject/camel/camel-db.h (original)
+++ branches/camel-gobject/camel/camel-db.h Tue Jan 6 01:56:50 2009
@@ -4,8 +4,14 @@
#define __CAMEL_DB_H
#include <sqlite3.h>
#include <glib.h>
+
#define CAMEL_DB_FILE "folders.db"
+/* Hopefully no one will create a folder named EVO_IN_meM_hAnDlE */
+#define CAMEL_DB_IN_MEMORY_TABLE "EVO_IN_meM_hAnDlE.temp"
+#define CAMEL_DB_IN_MEMORY_DB "EVO_IN_meM_hAnDlE"
+#define CAMEL_DB_IN_MEMORY_TABLE_LIMIT 100000
+
#include "camel-exception.h"
typedef struct _CamelDBPrivate CamelDBPrivate;
@@ -132,6 +138,7 @@
int camel_db_prepare_message_info_table (CamelDB *cdb, const char *folder_name, CamelException *ex);
int camel_db_write_message_info_record (CamelDB *cdb, const char *folder_name, CamelMIRecord *record, CamelException *ex);
+int camel_db_write_fresh_message_info_record (CamelDB *cdb, const char *folder_name, CamelMIRecord *record, CamelException *ex);
int camel_db_read_message_info_records (CamelDB *cdb, const char *folder_name, gpointer p, CamelDBSelectCB read_mir_callback, CamelException *ex);
int camel_db_read_message_info_record_with_uid (CamelDB *cdb, const char *folder_name, const char *uid, gpointer p, CamelDBSelectCB read_mir_callback, CamelException *ex);
@@ -156,6 +163,7 @@
int camel_db_add_to_vfolder_transaction (CamelDB *db, char *folder_name, char *vuid, CamelException *ex);
int camel_db_get_folder_uids (CamelDB *db, char *folder_name, char *sort_by, char *collate, GPtrArray *array, CamelException *ex);
+int camel_db_get_folder_uids_flags (CamelDB *db, char *folder_name, char *sort_by, char *collate, GPtrArray *summary, GHashTable *table, CamelException *ex);
GPtrArray * camel_db_get_folder_junk_uids (CamelDB *db, char *folder_name, CamelException *ex);
GPtrArray * camel_db_get_folder_deleted_uids (CamelDB *db, char *folder_name, CamelException *ex);
@@ -167,5 +175,9 @@
int camel_db_set_collate (CamelDB *cdb, const char *col, const char *collate, CamelDBCollate func);
/* Migration APIS */
int camel_db_migrate_vfolders_to_14(CamelDB *cdb, const char *folder, CamelException *ex);
+
+int camel_db_start_in_memory_transactions (CamelDB *cdb, CamelException *ex);
+int camel_db_flush_in_memory_transactions (CamelDB *cdb, const char * folder_name, CamelException *ex);
+
#endif
Modified: branches/camel-gobject/camel/camel-folder-summary.c
==============================================================================
--- branches/camel-gobject/camel/camel-folder-summary.c (original)
+++ branches/camel-gobject/camel/camel-folder-summary.c Tue Jan 6 01:56:50 2009
@@ -41,6 +41,7 @@
#include <libedataserver/e-memory.h>
#include "camel-db.h"
+#include "camel-debug.h"
#include "camel-file-utils.h"
#include "camel-folder-summary.h"
#include "camel-folder.h"
@@ -67,6 +68,7 @@
/* Make 5 minutes as default cache drop */
#define SUMMARY_CACHE_DROP 300
+#define dd(x) if (camel_debug("sync")) x
static pthread_mutex_t info_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -78,7 +80,6 @@
/* this should probably be conditional on it existing */
#define USE_BSEARCH
-#define dd(x)
#define d(x)
#define io(x) /* io debug */
#define w(x)
@@ -128,7 +129,7 @@
static int content_info_save(CamelFolderSummary *, FILE *, CamelMessageContentInfo *);
static void content_info_free(CamelFolderSummary *, CamelMessageContentInfo *);
-static int save_message_infos_to_db (CamelFolderSummary *s, CamelException *ex);
+static int save_message_infos_to_db (CamelFolderSummary *s, gboolean fresh_mir, CamelException *ex);
static int camel_read_mir_callback (void * ref, int ncol, char ** cols, char ** name);
static char *next_uid_string(CamelFolderSummary *s);
@@ -154,6 +155,7 @@
s->message_info_size = sizeof(CamelMessageInfoBase);
s->content_info_size = sizeof(CamelMessageContentInfo);
+ p->flag_cache = g_hash_table_new (g_str_hash, g_str_equal);
s->message_info_chunks = NULL;
s->content_info_chunks = NULL;
@@ -199,7 +201,7 @@
CamelFolderSummary *s = (CamelFolderSummary *)obj;
p = _PRIVATE(obj);
-
+ g_hash_table_destroy (p->flag_cache);
if (s->timeout_handle)
g_source_remove (s->timeout_handle);
//camel_folder_summary_clear(s);
@@ -825,16 +827,17 @@
CamelFolderSummary *s = m->summary;
CAMEL_DB_RELEASE_SQLITE_MEMORY;
-
+ camel_folder_sync (s->folder, FALSE, NULL);
+
if (time(NULL) - s->cache_load_time < SUMMARY_CACHE_DROP)
return;
- d(printf("removing cache for %s %d %p\n", s->folder ? s->folder->full_name : s->summary_path, g_hash_table_size (s->loaded_infos), s->loaded_infos));
+ dd(printf("removing cache for %s %d %p\n", s->folder ? s->folder->full_name : s->summary_path, g_hash_table_size (s->loaded_infos), s->loaded_infos));
/* FIXME[disk-summary] hack. fix it */
CAMEL_SUMMARY_LOCK (s, summary_lock);
g_hash_table_foreach_remove (s->loaded_infos, (GHRFunc) remove_item, s);
CAMEL_SUMMARY_UNLOCK (s, summary_lock);
- d(printf("done .. now %d\n",g_hash_table_size (s->loaded_infos)));
+ dd(printf("done .. now %d\n",g_hash_table_size (s->loaded_infos)));
s->cache_load_time = time(NULL);
@@ -932,14 +935,23 @@
printf("\n");
}
+GHashTable *
+camel_folder_summary_get_flag_cache (CamelFolderSummary *summary)
+{
+ struct _CamelFolderSummaryPrivate *p = _PRIVATE(summary);
+
+ return p->flag_cache;
+}
+
int
camel_folder_summary_load_from_db (CamelFolderSummary *s, CamelException *ex)
{
CamelDB *cdb;
char *folder_name;
int ret = 0;
+ struct _CamelFolderSummaryPrivate *p = _PRIVATE(s);
+
/* struct _db_pass_data data; */
-
d(printf ("\ncamel_folder_summary_load_from_db called \n"));
s->flags &= ~CAMEL_SUMMARY_DIRTY;
@@ -951,7 +963,7 @@
folder_name = s->folder->full_name;
cdb = s->folder->parent_store->cdb_r;
- ret = camel_db_get_folder_uids (cdb, folder_name, (char *)s->sort_by, (char *)s->collate, s->uids, ex);
+ ret = camel_db_get_folder_uids_flags (cdb, folder_name, (char *)s->sort_by, (char *)s->collate, s->uids, p->flag_cache, ex);
/* camel_folder_summary_dump (s); */
#if 0
@@ -1225,23 +1237,20 @@
if (fclose (in) != 0)
return -1;
-
- camel_db_begin_transaction (cdb, &ex);
-
- ret = save_message_infos_to_db (s, &ex);
-
- if (ret != 0) {
- camel_db_abort_transaction (cdb, &ex);
+ record = (((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_to_db (s, &ex));
+ if (!record) {
return -1;
}
- camel_db_end_transaction (cdb, &ex);
- record = (((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_to_db (s, &ex));
- if (!record) {
+ ret = save_message_infos_to_db (s, TRUE, &ex);
+
+ if (ret != 0) {
return -1;
}
+ camel_db_begin_transaction (cdb, &ex);
ret = camel_db_write_folder_info_record (cdb, record, &ex);
+ camel_db_end_transaction (cdb, &ex);
g_free (record->bdata);
g_free (record);
@@ -1309,17 +1318,24 @@
return 0;
}
+typedef struct {
+ CamelException *ex;
+ gboolean migration;
+ int progress;
+} SaveToDBArgs;
+
static void
save_to_db_cb (gpointer key, gpointer value, gpointer data)
{
- CamelException *ex = (CamelException *)data;
+ SaveToDBArgs *args = (SaveToDBArgs *) data;
+ CamelException *ex = args->ex;
CamelMessageInfoBase *mi = (CamelMessageInfoBase *)value;
CamelFolderSummary *s = (CamelFolderSummary *)mi->summary;
char *folder_name = s->folder->full_name;
CamelDB *cdb = s->folder->parent_store->cdb_w;
CamelMIRecord *mir;
- if (!mi->dirty)
+ if (!args->migration && !mi->dirty)
return;
mir = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_to_db (s, (CamelMessageInfo *)mi);
@@ -1333,22 +1349,44 @@
}
}
- if (camel_db_write_message_info_record (cdb, folder_name, mir, ex) != 0) {
- camel_db_camel_mir_free (mir);
- return;
+ if (!args->migration) {
+ if (camel_db_write_message_info_record (cdb, folder_name, mir, ex) != 0) {
+ camel_db_camel_mir_free (mir);
+ return;
+ }
+ } else {
+ if (camel_db_write_fresh_message_info_record (cdb, CAMEL_DB_IN_MEMORY_TABLE, mir, ex) != 0) {
+ camel_db_camel_mir_free (mir);
+ return;
+ }
+
+ if (args->progress > CAMEL_DB_IN_MEMORY_TABLE_LIMIT) {
+ g_print ("BULK INsert limit reached \n");
+ camel_db_flush_in_memory_transactions (cdb, folder_name, ex);
+ camel_db_start_in_memory_transactions (cdb, ex);
+ args->progress = 0;
+ } else {
+ args->progress ++;
+ }
}
/* Reset the flags */
mi->dirty = FALSE;
+ mi->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
camel_db_camel_mir_free (mir);
}
static int
-save_message_infos_to_db (CamelFolderSummary *s, CamelException *ex)
+save_message_infos_to_db (CamelFolderSummary *s, gboolean fresh_mirs, CamelException *ex)
{
CamelDB *cdb = s->folder->parent_store->cdb_w;
char *folder_name;
+ SaveToDBArgs args;
+
+ args.ex = ex;
+ args.migration = fresh_mirs;
+ args.progress = 0;
folder_name = s->folder->full_name;
if (camel_db_prepare_message_info_table (cdb, folder_name, ex) != 0) {
@@ -1356,7 +1394,7 @@
}
CAMEL_SUMMARY_LOCK(s, summary_lock);
/* Push MessageInfo-es */
- g_hash_table_foreach (s->loaded_infos, save_to_db_cb, ex);
+ g_hash_table_foreach (s->loaded_infos, save_to_db_cb, &args);
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
/* FIXME[disk-summary] make sure we free the message infos that are loaded
* are freed if not used anymore or should we leave that to the timer? */
@@ -1382,11 +1420,11 @@
if (!count)
return camel_folder_summary_header_save_to_db (s, ex);
- d(printf("Saving %d/%d dirty records of %s\n", count, g_hash_table_size (s->loaded_infos), s->folder->full_name));
+ dd(printf("Saving %d/%d dirty records of %s\n", count, g_hash_table_size (s->loaded_infos), s->folder->full_name));
camel_db_begin_transaction (cdb, ex);
- ret = save_message_infos_to_db (s, ex);
+ ret = save_message_infos_to_db (s, FALSE, ex);
if (ret != 0) {
camel_db_abort_transaction (cdb, ex);
/* Failed, so lets reset the flag */
@@ -2078,25 +2116,24 @@
void
camel_folder_summary_clear(CamelFolderSummary *s)
{
-#if 0
- int i;
+ d(printf ("\ncamel_folder_summary_clearcalled \n"));
+ s->flags &= ~CAMEL_SUMMARY_DIRTY;
CAMEL_SUMMARY_LOCK(s, summary_lock);
if (camel_folder_summary_count(s) == 0) {
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
return;
}
+
+ g_ptr_array_foreach (s->uids, (GFunc) camel_pstring_free, NULL);
+ g_ptr_array_free (s->uids, TRUE);
+ s->uids = g_ptr_array_new ();
+ s->visible_count = s->deleted_count = s->unread_count = 0;
- for (i=0;i<s->messages->len;i++)
- camel_message_info_free(s->messages->pdata[i]);
+ g_hash_table_destroy(s->loaded_infos);
+ s->loaded_infos = g_hash_table_new(g_str_hash, g_str_equal);
- g_ptr_array_set_size(s->messages, 0);
- g_hash_table_destroy(s->messages_uid);
- s->messages_uid = g_hash_table_new(g_str_hash, g_str_equal);
- s->flags |= CAMEL_SUMMARY_DIRTY;
- s->meta_summary->msg_expunged = TRUE;
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
-#endif
}
/* FIXME: This is non-sense. Neither an exception is passed,
@@ -3082,7 +3119,7 @@
message_info_load(CamelFolderSummary *s, FILE *in)
{
CamelMessageInfoBase *mi;
- guint count;
+ guint32 count;
int i;
char *subject, *from, *to, *cc, *mlist, *uid;
Modified: branches/camel-gobject/camel/camel-folder-summary.h
==============================================================================
--- branches/camel-gobject/camel/camel-folder-summary.h (original)
+++ branches/camel-gobject/camel/camel-folder-summary.h Tue Jan 6 01:56:50 2009
@@ -407,6 +407,7 @@
GPtrArray *camel_folder_summary_array(CamelFolderSummary *summary);
GHashTable *camel_folder_summary_get_hashtable(CamelFolderSummary *s);
void camel_folder_summary_free_hashtable (GHashTable *ht);
+GHashTable *camel_folder_summary_get_flag_cache (CamelFolderSummary *summary);
/* basically like strings, but certain keywords can be compressed and de-cased */
int camel_folder_summary_encode_token(FILE *out, const char *str);
Modified: branches/camel-gobject/camel/camel-folder.c
==============================================================================
--- branches/camel-gobject/camel/camel-folder.c (original)
+++ branches/camel-gobject/camel/camel-folder.c Tue Jan 6 01:56:50 2009
@@ -1143,24 +1143,9 @@
GPtrArray *array;
int i, j, count;
- array = g_ptr_array_new();
+ g_return_val_if_fail(folder->summary != NULL, g_ptr_array_new ());
- g_return_val_if_fail(folder->summary != NULL, array);
-
- count = camel_folder_summary_count(folder->summary);
- g_ptr_array_set_size(array, count);
- for (i = 0, j = 0; i < count; i++) {
- CamelMessageInfo *info = camel_folder_summary_index(folder->summary, i);
-
- if (info) {
- array->pdata[j++] = (char *)camel_pstring_strdup (camel_message_info_uid (info));
- camel_message_info_free(info);
- }
- }
-
- g_ptr_array_set_size (array, j);
-
- return array;
+ return camel_folder_summary_array (folder->summary);
}
Modified: branches/camel-gobject/camel/camel-mime-utils.c
==============================================================================
--- branches/camel-gobject/camel/camel-mime-utils.c (original)
+++ branches/camel-gobject/camel/camel-mime-utils.c Tue Jan 6 01:56:50 2009
@@ -3281,7 +3281,7 @@
}
static char *
-header_encode_param (const unsigned char *in, gboolean *encoded)
+header_encode_param (const unsigned char *in, gboolean *encoded, gboolean is_filename)
{
const unsigned char *inptr = in;
unsigned char *outbuf = NULL;
@@ -3294,11 +3294,34 @@
g_return_val_if_fail (in != NULL, NULL);
+ if (is_filename) {
+ if (!g_utf8_validate (inptr, -1, NULL)) {
+ GString *buff = g_string_new ("");
+
+ for (; inptr && *inptr; inptr++) {
+ if (*inptr < 32)
+ g_string_append_printf (buff, "%%%02X", (*inptr) & 0xFF);
+ else
+ g_string_append_c (buff, *inptr);
+ }
+
+ outbuf = g_string_free (buff, FALSE);
+ inptr = outbuf;
+ }
+
+ /* do not set encoded flag for file names */
+ str = camel_header_encode_string (inptr);
+ g_free (outbuf);
+
+ return str;
+ }
+
/* if we have really broken utf8 passed in, we just treat it as binary data */
charset = camel_charset_best((char *) in, strlen((char *) in));
- if (charset == NULL)
+ if (charset == NULL) {
return g_strdup((char *) in);
+ }
if (g_ascii_strcasecmp(charset, "UTF-8") != 0) {
if ((outbuf = (unsigned char *) header_convert(charset, "UTF-8", (const char *) in, strlen((char *) in))))
@@ -3322,16 +3345,23 @@
str = out->str;
g_string_free (out, FALSE);
*encoded = TRUE;
-
+
return str;
}
+/* HACK: Set to non-zero when you want the 'filename' and 'name' headers encode in RFC 2047 way,
+ otherwise they will be encoded in the correct RFC 2231 way. It's because Outlook and GMail
+ do not understand the correct standard and refuse attachments with localized name sent
+ from evolution. */
+int camel_header_param_encode_filenames_in_rfc_2047 = 0;
+
void
camel_header_param_list_format_append (GString *out, struct _camel_header_param *p)
{
int used = out->len;
while (p) {
+ gboolean is_filename = camel_header_param_encode_filenames_in_rfc_2047 && (g_ascii_strcasecmp (p->name, "filename") == 0 || g_ascii_strcasecmp (p->name, "name") == 0);
gboolean encoded = FALSE;
gboolean quote = FALSE;
int here = out->len;
@@ -3343,7 +3373,7 @@
continue;
}
- value = header_encode_param ((unsigned char *) p->value, &encoded);
+ value = header_encode_param ((unsigned char *) p->value, &encoded, is_filename);
if (!value) {
w(g_warning ("appending parameter %s=%s violates rfc2184", p->name, p->value));
value = g_strdup (p->value);
@@ -3360,17 +3390,19 @@
quote = ch && *ch;
}
+ quote = quote || is_filename;
nlen = strlen (p->name);
vlen = strlen (value);
- if (used + nlen + vlen > CAMEL_FOLD_SIZE - 8) {
+ /* do not fold file names */
+ if (!is_filename && used + nlen + vlen > CAMEL_FOLD_SIZE - 8) {
out = g_string_append (out, ";\n\t");
here = out->len;
used = 0;
} else
out = g_string_append (out, "; ");
- if (nlen + vlen > CAMEL_FOLD_SIZE - 8) {
+ if (!is_filename && nlen + vlen > CAMEL_FOLD_SIZE - 8) {
/* we need to do special rfc2184 parameter wrapping */
int maxlen = CAMEL_FOLD_SIZE - (nlen + 8);
char *inptr, *inend;
Modified: branches/camel-gobject/camel/camel-object.h
==============================================================================
--- branches/camel-gobject/camel/camel-object.h (original)
+++ branches/camel-gobject/camel/camel-object.h Tue Jan 6 01:56:50 2009
@@ -126,9 +126,8 @@
typedef unsigned int CamelObjectHookID;
#ifndef CAMEL_DISABLE_DEPRECATED
typedef struct _CamelObjectMeta CamelObjectMeta;
-#endif /* CAMEL_DISABLE_DEPRECATED */
-
typedef struct _CamelInterface CamelInterface;
+#endif /* CAMEL_DISABLE_DEPRECATED */
typedef void (*CamelObjectClassInitFunc) (CamelObjectClass *);
typedef void (*CamelObjectClassFinalizeFunc) (CamelObjectClass *);
@@ -241,10 +240,12 @@
int (*state_write)(struct _CamelObject *, FILE *fp);
};
+#ifndef CAMEL_DISABLE_DEPRECATED
/* an interface is just a class with no instance data */
struct _CamelInterface {
struct _CamelObjectClass type;
};
+#endif /* CAMEL_DISABLE_DEPRECATED */
#ifndef CAMEL_DISABLE_DEPRECATED
/* The type system .... it's pretty simple..... */
@@ -319,6 +320,7 @@
}
#endif /* CAMEL_DISABLE_DEPRECATED */
+#ifndef CAMEL_DISABLE_DEPRECATED
/* Utility functions, not object specific, but too small to separate */
typedef struct _CamelIteratorVTable CamelIteratorVTable;
typedef struct _CamelIterator CamelIterator;
@@ -345,6 +347,7 @@
const void *camel_iterator_next(void *it, CamelException *ex);
void camel_iterator_reset(void *it);
int camel_iterator_length(void *it);
+#endif /* CAMEL_DISABLE_DEPRECATED */
G_END_DECLS
Modified: branches/camel-gobject/camel/camel-private.h
==============================================================================
--- branches/camel-gobject/camel/camel-private.h (original)
+++ branches/camel-gobject/camel/camel-private.h Tue Jan 6 01:56:50 2009
@@ -128,6 +128,7 @@
GMutex *filter_lock; /* for accessing any of the filtering/indexing stuff, since we share them */
GMutex *alloc_lock; /* for setting up and using allocators */
GMutex *ref_lock; /* for reffing/unreffing messageinfo's ALWAYS obtain before summary_lock */
+ GHashTable *flag_cache;
};
#define CAMEL_SUMMARY_LOCK(f, l) \
Modified: branches/camel-gobject/camel/camel-search-sql-sexp.c
==============================================================================
--- branches/camel-gobject/camel/camel-search-sql-sexp.c (original)
+++ branches/camel-gobject/camel/camel-search-sql-sexp.c Tue Jan 6 01:56:50 2009
@@ -150,8 +150,12 @@
if (r1->type == ESEXP_RES_STRING) {
r = e_sexp_result_new(f, ESEXP_RES_STRING);
- r->value.string = g_strdup_printf ("(NOT (%s))",
- r1->value.string);
+ /* HACK: Fix and handle completed-on better. */
+ if (strcmp(r1->value.string, "( (usertags LIKE '%completed-on 0%' AND usertags LIKE '%completed-on%') )") == 0)
+ r->value.string = g_strdup ("( (not (usertags LIKE '%completed-on 0%')) AND usertags LIKE '%completed-on%' )");
+ else
+ r->value.string = g_strdup_printf ("(NOT (%s))",
+ r1->value.string);
}
e_sexp_result_free (f, r1);
@@ -439,7 +443,7 @@
r = e_sexp_result_new(f, ESEXP_RES_STRING);
/* Hacks no otherway to fix these really :( */
if (strcmp(argv[0]->value.string, "completed-on") == 0)
- r->value.string = g_strdup_printf("usertags NOT LIKE '%ccompleted-on%c'", '%', '%');
+ r->value.string = g_strdup_printf("(usertags LIKE '%ccompleted-on 0%c' AND usertags LIKE '%ccompleted-on%c')", '%', '%', '%', '%');
else if (strcmp(argv[0]->value.string, "follow-up") == 0)
r->value.string = g_strdup_printf("usertags NOT LIKE '%cfollow-up%c'", '%', '%');
else
Modified: branches/camel-gobject/camel/camel-store-summary.h
==============================================================================
--- branches/camel-gobject/camel/camel-store-summary.h (original)
+++ branches/camel-gobject/camel/camel-store-summary.h Tue Jan 6 01:56:50 2009
@@ -57,6 +57,7 @@
/* not in camle-store.h yet */
CAMEL_STORE_INFO_FOLDER_READONLY = 1<<13,
+ CAMEL_STORE_INFO_FOLDER_CHECK_FOR_NEW = 1<<14,
CAMEL_STORE_INFO_FOLDER_FLAGGED = 1<<31
} CamelStoreInfoFlags;
Modified: branches/camel-gobject/camel/camel-store.c
==============================================================================
--- branches/camel-gobject/camel/camel-store.c (original)
+++ branches/camel-gobject/camel/camel-store.c Tue Jan 6 01:56:50 2009
@@ -322,6 +322,21 @@
}
if (!folder) {
+
+ if (flags & CAMEL_STORE_IS_MIGRATING) {
+ if ((store->flags & CAMEL_STORE_VTRASH) && strcmp(folder_name, CAMEL_VTRASH_NAME) == 0) {
+ if (store->folders)
+ camel_object_bag_abort(store->folders, folder_name);
+ return NULL;
+ }
+
+ if ((store->flags & CAMEL_STORE_VJUNK) && strcmp(folder_name, CAMEL_VJUNK_NAME) == 0) {
+ if (store->folders)
+ camel_object_bag_abort(store->folders, folder_name);
+ return NULL;
+ }
+ }
+
if ((store->flags & CAMEL_STORE_VTRASH) && strcmp(folder_name, CAMEL_VTRASH_NAME) == 0) {
folder = CS_CLASS(store)->get_trash(store, ex);
} else if ((store->flags & CAMEL_STORE_VJUNK) && strcmp(folder_name, CAMEL_VJUNK_NAME) == 0) {
Modified: branches/camel-gobject/camel/camel-store.h
==============================================================================
--- branches/camel-gobject/camel/camel-store.h (original)
+++ branches/camel-gobject/camel/camel-store.h Tue Jan 6 01:56:50 2009
@@ -115,6 +115,7 @@
#define CAMEL_STORE_FILTER_INBOX (1 << 2)
#define CAMEL_STORE_VJUNK (1 << 3)
#define CAMEL_STORE_PROXY (1 << 4)
+#define CAMEL_STORE_IS_MIGRATING (1 << 5)
struct _CamelDB;
@@ -274,6 +275,7 @@
CamelFolderInfo *info,
CamelException *ex);
+#ifndef CAMEL_DISABLE_DEPRECATED
typedef struct _CamelISubscribe CamelISubscribe;
struct _CamelISubscribe {
CamelInterface iface;
@@ -287,6 +289,7 @@
gboolean camel_isubscribe_subscribed(CamelStore *store, const char *name);
void camel_isubscribe_subscribe(CamelStore *store, const char *folder_name, CamelException *ex);
void camel_isubscribe_unsubscribe(CamelStore *store, const char *folder_name, CamelException *ex);
+#endif /* CAMEL_DISABLE_DEPRECATED */
G_END_DECLS
Modified: branches/camel-gobject/camel/camel-utf8.c
==============================================================================
--- branches/camel-gobject/camel/camel-utf8.c (original)
+++ branches/camel-gobject/camel/camel-utf8.c Tue Jan 6 01:56:50 2009
@@ -399,3 +399,27 @@
return out;
}
+
+/**
+ * camel_utf8_make_valid:
+ * @text:
+ *
+ * Ensures the returned text will be valid UTF-8 string, with incorrect letters
+ * changed to question marks. Returned pointer should be freed with g_free.
+ **/
+char *
+camel_utf8_make_valid (const char *text)
+{
+ gchar *res = g_strdup (text), *p;
+
+ if (!res)
+ return res;
+
+ p = res;
+ while (!g_utf8_validate (p, -1, (const gchar **) &p)) {
+ /* make all invalid characters appear as question marks */
+ *p = '?';
+ }
+
+ return res;
+}
Modified: branches/camel-gobject/camel/camel-utf8.h
==============================================================================
--- branches/camel-gobject/camel/camel-utf8.h (original)
+++ branches/camel-gobject/camel/camel-utf8.h Tue Jan 6 01:56:50 2009
@@ -40,6 +40,9 @@
char *camel_utf8_ucs2(const char *ptr);
char *camel_ucs2_utf8(const char *ptr);
+/* make valid utf8 string */
+char *camel_utf8_make_valid (const char *text);
+
G_END_DECLS
#endif /* ! _CAMEL_UTF8_H */
Modified: branches/camel-gobject/camel/camel-vee-folder.c
==============================================================================
--- branches/camel-gobject/camel/camel-vee-folder.c (original)
+++ branches/camel-gobject/camel/camel-vee-folder.c Tue Jan 6 01:56:50 2009
@@ -150,7 +150,7 @@
camel_vee_folder_construct(vf, parent_store, full, name, flags);
}
- d(printf("returning folder %s %p, count = %d\n", name, vf, camel_folder_get_message_count((CamelFolder *)vf)));
+ d(printf("returning folder %s %p, count = %d\n", full, vf, camel_folder_get_message_count((CamelFolder *)vf)));
if (vf) {
tmp = g_strdup_printf("%s/%s.cmeta", ((CamelService *)parent_store)->url->path, full);
@@ -2018,13 +2018,14 @@
camel_object_unhook_event((CamelObject *)o, "summary_reloaded", (CamelObjectEventHookFunc) summary_reloaded, data);
}
+ /*
m = camel_session_thread_msg_new(session, &folder_flags_ops, sizeof(*m));
m->sub = summary->folder;
g_object_ref((CamelObject *)summary->folder);
m->vf = vf;
g_object_ref((CamelObject *)vf);
camel_session_thread_queue(session, &m->msg, 0);
-
+ */
}
/* vfolder base implementaitons */
@@ -2065,8 +2066,16 @@
}
/* Recreate the table when the query changes, only if we are not setting it first */
- if (vf->expression)
+ if (vf->expression) {
+ CamelFolderSummary *s = ((CamelFolder *)vf)->summary;
+ camel_folder_summary_clear (s);
camel_db_recreate_vfolder (((CamelFolder *) vf)->parent_store->cdb_w, ((CamelFolder *) vf)->full_name, NULL);
+ s->junk_count = 0;
+ s->deleted_count = 0;
+ s->unread_count = 0;
+ s->visible_count = 0;
+ s->junk_not_deleted_count = 0;
+ }
g_free(vf->expression);
@@ -2091,6 +2100,94 @@
CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock);
}
+/* This entire code will be useless, since we sync the counts always. */
+static int
+vf_getv(CamelObject *object, CamelException *ex, CamelArgGetV *args)
+{
+ CamelFolder *folder = (CamelFolder *)object;
+ int i;
+ guint32 tag;
+ int unread = -1, deleted = 0, junked = 0, visible = 0, count = -1, junked_not_deleted = -1;
+
+ for (i=0;i<args->argc;i++) {
+ CamelArgGet *arg = &args->argv[i];
+
+ tag = arg->tag;
+
+ /* NB: this is a copy of camel-folder.c with the unread count logic altered.
+ makes sure its still atomically calculated */
+ switch (tag & CAMEL_ARG_TAG) {
+ case CAMEL_FOLDER_ARG_UNREAD:
+ case CAMEL_FOLDER_ARG_DELETED:
+ case CAMEL_FOLDER_ARG_JUNKED:
+ case CAMEL_FOLDER_ARG_JUNKED_NOT_DELETED:
+ case CAMEL_FOLDER_ARG_VISIBLE:
+
+ /* This is so we can get the values atomically, and also so we can calculate them only once */
+ if (unread == -1) {
+ int j;
+ CamelMessageInfoBase *info;
+ CamelVeeMessageInfo *vinfo;
+
+ unread = deleted = visible = junked = junked_not_deleted = 0;
+ count = camel_folder_summary_count(folder->summary);
+ for (j=0; j<count; j++) {
+ if ((info = (CamelMessageInfoBase *) camel_folder_summary_index(folder->summary, j))) {
+ guint32 flags;
+
+ vinfo = (CamelVeeMessageInfo *) info;
+ flags = vinfo->old_flags;// ? vinfo->old_flags : camel_message_info_flags(info);
+
+ if ((flags & (CAMEL_MESSAGE_SEEN)) == 0)
+ unread++;
+ if (flags & CAMEL_MESSAGE_DELETED)
+ deleted++;
+ if (flags & CAMEL_MESSAGE_JUNK) {
+ junked++;
+ if (! (flags & CAMEL_MESSAGE_DELETED))
+ junked_not_deleted++;
+ }
+ if ((flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
+ visible++;
+ camel_message_info_free(info);
+ }
+ }
+ }
+
+ switch (tag & CAMEL_ARG_TAG) {
+ case CAMEL_FOLDER_ARG_UNREAD:
+ count = unread == -1 ? 0 : unread;
+ break;
+ case CAMEL_FOLDER_ARG_DELETED:
+ count = deleted == -1 ? 0 : deleted;
+ break;
+ case CAMEL_FOLDER_ARG_JUNKED:
+ count = junked == -1 ? 0 : junked;
+ break;
+ case CAMEL_FOLDER_ARG_JUNKED_NOT_DELETED:
+ count = junked_not_deleted == -1 ? 0 : junked_not_deleted;
+ break;
+ case CAMEL_FOLDER_ARG_VISIBLE:
+ count = visible == -1 ? 0 : visible;
+ break;
+ }
+ folder->summary->unread_count = unread == -1 ? 0 : unread;
+ folder->summary->deleted_count = deleted == -1 ? 0 : deleted;
+ junked = folder->summary->junk_count = junked == -1 ? 0 : junked;
+ folder->summary->junk_not_deleted_count = junked_not_deleted == -1 ? 0 : junked_not_deleted;
+ folder->summary->visible_count = visible == -1 ? 0 : visible;
+ *arg->ca_int = count;
+ break;
+ default:
+ continue;
+ }
+
+ arg->tag = (tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE;
+ }
+
+ return ((CamelObjectClass *)camel_vee_folder_parent)->getv(object, ex, args);
+}
+
static void
camel_vee_folder_class_init (CamelVeeFolderClass *klass)
{
@@ -2098,6 +2195,8 @@
camel_vee_folder_parent = CAMEL_FOLDER_CLASS(g_type_class_peek (camel_folder_get_type ()));
+ ((CamelObjectClass *)klass)->getv = vf_getv;
+
folder_class->refresh_info = vee_refresh_info;
folder_class->sync = vee_sync;
folder_class->expunge = vee_expunge;
Modified: branches/camel-gobject/camel/camel-vee-summary.c
==============================================================================
--- branches/camel-gobject/camel/camel-vee-summary.c (original)
+++ branches/camel-gobject/camel/camel-vee-summary.c Tue Jan 6 01:56:50 2009
@@ -42,7 +42,7 @@
#define d(x)
static CamelFolderSummaryClass *camel_vee_summary_parent;
-const char *unread_str = " (and\n \n (match-all (not (system-flag \"Seen\")))\n \n )\n; (match-threads \"all\" (and\n \n (match-all (not (system-flag \"Seen\")))\n \n )\n)\n;";
+const char *unread_str = " (and\n \n (match-all (not (system-flag \"Seen\")))\n \n )\n; (or\n \n (match-all (not (system-flag \"Seen\")))\n \n )\n; (match-threads \"all\" (and\n \n (match-all (not (system-flag \"Seen\")))\n \n )\n)\n; (match-threads \"all\" (or\n \n (match-all (not (system-flag \"Seen\")))\n \n )\n)\n;";
static void
vee_message_info_free(CamelFolderSummary *s, CamelMessageInfo *info)
@@ -176,20 +176,33 @@
{
int res = FALSE;
CamelVeeFolder *vf = (CamelVeeFolder *)mi->summary->folder;
- const char *exp = g_getenv("CAMEL_VFOLDER_UNREAD_EXP");
+ static char *exp = NULL;
+ static only_once = FALSE;
gboolean hacked_unread_folder = FALSE;
+ char *meta = NULL;
/* HACK: Ugliest of all hacks. Its virtually not possible now
* to maintain counts and the non matching uids of unread vfolder here.
* So, I hardcode unread vfolder expression and hack it. */
+ if (!only_once) {
+ exp = g_getenv("CAMEL_VFOLDER_UNREAD_EXP") ? g_strcompress(g_getenv("CAMEL_VFOLDER_UNREAD_EXP")) : NULL;
+ only_once = TRUE;
+ }
+
if (!exp || !*exp)
- exp = unread_str;
+ exp = g_strcompress(unread_str);
+
if (camel_debug("vfolderexp"))
printf("Expression for vfolder '%s' is '%s'\n", mi->summary->folder->full_name, g_strescape(vf->expression, ""));
if (strstr(exp, vf->expression) && (vf->flags & CAMEL_STORE_VEE_FOLDER_SPECIAL) == 0)
hacked_unread_folder = TRUE;
+ meta = camel_object_meta_get (mi->summary->folder, "vfolder:unread");
+ if (!hacked_unread_folder && meta && strcmp (meta, "true") == 0)
+ hacked_unread_folder = TRUE;
+ g_free(meta);
+
if (mi->uid) {
guint32 old_visible, old_unread, old_deleted, old_junked, old_junked_not_deleted;
guint32 visible, unread, deleted, junked, junked_not_deleted;
@@ -418,7 +431,7 @@
{
CamelVeeMessageInfo *mi;
char *vuid;
-
+ GHashTable * fcache;
vuid = g_malloc(strlen(uid)+9);
memcpy(vuid, hash, 8);
strcpy(vuid+8, uid);
@@ -441,6 +454,8 @@
mi = (CamelVeeMessageInfo *)camel_message_info_new(&s->summary);
mi->summary = summary;
+ fcache = camel_folder_summary_get_flag_cache(summary);
+ mi->old_flags = GPOINTER_TO_UINT(g_hash_table_lookup (fcache, uid));
/* We would do lazy loading of flags, when the folders are loaded to memory through folder_reloaded signal */
g_object_ref (summary);
mi->info.uid = (char *) camel_pstring_strdup (vuid);
Modified: branches/camel-gobject/camel/camel-vtrash-folder.c
==============================================================================
--- branches/camel-gobject/camel/camel-vtrash-folder.c (original)
+++ branches/camel-gobject/camel/camel-vtrash-folder.c Tue Jan 6 01:56:50 2009
@@ -151,7 +151,7 @@
guint32 flags;
vinfo = (CamelVeeMessageInfo *) info;
- flags = vinfo->old_flags ? vinfo->old_flags : camel_message_info_flags(info);
+ flags = vinfo->old_flags;// ? vinfo->old_flags : camel_message_info_flags(info);
if ((flags & (CAMEL_MESSAGE_SEEN)) == 0)
unread++;
Modified: branches/camel-gobject/camel/providers/groupwise/camel-groupwise-folder.c
==============================================================================
--- branches/camel-gobject/camel/providers/groupwise/camel-groupwise-folder.c (original)
+++ branches/camel-gobject/camel/providers/groupwise/camel-groupwise-folder.c Tue Jan 6 01:56:50 2009
@@ -229,8 +229,11 @@
time_t actual_time;
int offset = 0;
dtstring = e_gw_item_get_creation_date (item);
- time = e_gw_connection_get_date_from_string (dtstring);
- actual_time = camel_header_decode_date (ctime(&time), NULL);
+ if (dtstring) {
+ time = e_gw_connection_get_date_from_string (dtstring);
+ actual_time = camel_header_decode_date (ctime(&time), NULL);
+ } else
+ actual_time = (time_t) 0;
camel_mime_message_set_date (msg, actual_time, offset);
}
}
@@ -922,7 +925,13 @@
done = FALSE;
m->slist = NULL;
- while (!done && !camel_application_is_exiting) {
+ while (!done) {
+
+ if (camel_application_is_exiting) {
+ CAMEL_SERVICE_REC_UNLOCK (gw_store, connect_lock);
+ return ;
+ }
+
item_list = NULL;
status = e_gw_connection_get_all_mail_uids (m->cnc, m->container_id, cursor, FALSE, READ_CURSOR_MAX_IDS, position, &item_list);
if (status != E_GW_CONNECTION_STATUS_OK) {
@@ -1191,10 +1200,6 @@
if (gw_store->current_folder != folder) {
gw_store->current_folder = folder;
}
-
- if (list) {
- gw_update_cache (folder, list, ex, FALSE);
- }
if (check_all && !is_proxy) {
EGwContainer *container;
@@ -1205,8 +1210,15 @@
if (camel_folder_summary_count (folder->summary) == e_gw_container_get_total_count (container))
check_all = FALSE;
+
+ folder->summary->unread_count = e_gw_container_get_unread_count (container);
+ folder->summary->visible_count = e_gw_container_get_total_count (container);
g_object_unref (container);
}
+
+ if (list) {
+ gw_update_cache (folder, list, ex, FALSE);
+ }
}
@@ -1270,7 +1282,7 @@
int folder_needs_caching;
- camel_object_get (folder, NULL, CAMEL_OFFLINE_FOLDER_ARG_SYNC_OFFLINE, &folder_needs_caching, NULL);
+ camel_object_get (folder, NULL, CAMEL_OFFLINE_FOLDER_SYNC_OFFLINE, &folder_needs_caching, NULL);
changes = camel_folder_change_info_new ();
container_id = g_strdup (camel_groupwise_store_container_id_lookup (gw_store, folder->full_name));
@@ -1343,6 +1355,8 @@
mi->info.content->type = camel_content_type_new ("multipart", "mixed");
}
+ mi->info.flags = 0;
+
if (type == E_GW_ITEM_TYPE_APPOINTMENT || type == E_GW_ITEM_TYPE_TASK || type == E_GW_ITEM_TYPE_NOTE)
camel_message_info_set_user_flag ((CamelMessageInfo*)mi, "$has_cal", TRUE);
}
@@ -1359,16 +1373,12 @@
item_status = e_gw_item_get_item_status (item);
if (item_status & E_GW_ITEM_STAT_READ)
- status_flags |= CAMEL_MESSAGE_SEEN;
+ mi->info.flags |= CAMEL_MESSAGE_SEEN;
else
mi->info.flags &= ~CAMEL_MESSAGE_SEEN;
if (item_status & E_GW_ITEM_STAT_REPLIED)
- status_flags |= CAMEL_MESSAGE_ANSWERED;
- if (exists)
- mi->info.flags |= status_flags;
- else
- mi->info.flags = status_flags;
+ mi->info.flags |= CAMEL_MESSAGE_ANSWERED;
priority = e_gw_item_get_priority (item);
if (priority && !(g_ascii_strcasecmp (priority,"High"))) {
@@ -1449,12 +1459,17 @@
time_t time;
time_t actual_time;
temp_date = e_gw_item_get_creation_date (item);
- time = e_gw_connection_get_date_from_string (temp_date);
- actual_time = camel_header_decode_date (ctime(&time), NULL);
+ if (temp_date) {
+ /* Creation date can be returned as null for auto-generated meetings */
+ time = e_gw_connection_get_date_from_string (temp_date);
+ actual_time = camel_header_decode_date (ctime(&time), NULL);
+ } else
+ actual_time = (time_t) 0;
mi->info.date_sent = mi->info.date_received = actual_time;
}
}
+ mi->info.dirty = TRUE;
if (exists) {
camel_folder_change_info_change_uid (changes, mi->info.uid);
camel_message_info_free (pmi);
@@ -1462,12 +1477,7 @@
mi->info.uid = camel_pstring_strdup (e_gw_item_get_id(item));
mi->info.size = e_gw_item_get_mail_size (item);
mi->info.subject = camel_pstring_strdup(e_gw_item_get_subject(item));
- mi->info.dirty = TRUE;
- folder->summary->visible_count ++;
- if (!(mi->info.flags & CAMEL_MESSAGE_SEEN))
- folder->summary->unread_count ++;
-
camel_folder_summary_add (folder->summary,(CamelMessageInfo *)mi);
camel_folder_change_info_add_uid (changes, mi->info.uid);
camel_folder_change_info_recent_uid (changes, mi->info.uid);
@@ -1670,8 +1680,11 @@
time_t time;
time_t actual_time;
temp_date = e_gw_item_get_creation_date (item);
- time = e_gw_connection_get_date_from_string (temp_date);
- actual_time = camel_header_decode_date (ctime(&time), NULL);
+ if (temp_date) {
+ time = e_gw_connection_get_date_from_string (temp_date);
+ actual_time = camel_header_decode_date (ctime(&time), NULL);
+ } else
+ actual_time = (time_t) 0;
mi->info.date_sent = mi->info.date_received = actual_time;
}
}
@@ -1780,7 +1793,7 @@
gsize len_iter = 0;
char *temp = NULL;
- temp = g_base64_decode(t_attach, &len_iter);
+ temp = (char *) g_base64_decode(t_attach, &len_iter);
gstr = g_string_append_len (gstr, temp, len_iter);
g_free (temp);
len += len_iter;
@@ -1924,7 +1937,7 @@
gsize len_iter = 0;
char *temp = NULL;
- temp = g_base64_decode(t_attach, &len_iter);
+ temp = (char *) g_base64_decode(t_attach, &len_iter);
gstr = g_string_append_len (gstr, temp, len_iter);
g_free (temp);
len += len_iter;
@@ -2686,7 +2699,21 @@
g_string_append_printf (gstr, "UID:%s\n",e_gw_item_get_icalid (item));
g_string_append_printf (gstr, "DTSTART:%s\n",e_gw_item_get_start_date (item));
g_string_append_printf (gstr, "SUMMARY:%s\n", e_gw_item_get_subject (item));
- g_string_append_printf (gstr, "DESCRIPTION:%s\n", e_gw_item_get_message (item));
+
+ temp = e_gw_item_get_message (item);
+ if (temp) {
+ g_string_append(gstr, "DESCRIPTION:");
+ while (*temp) {
+ if (*temp == '\n')
+ g_string_append(gstr, "\\n");
+ else
+ g_string_append_c(gstr, *temp);
+ temp++;
+ }
+ g_string_append(gstr, "\n");
+ }
+ temp = NULL;
+
g_string_append_printf (gstr, "DTSTAMP:%s\n", e_gw_item_get_creation_date (item));
g_string_append_printf (gstr, "X-GWMESSAGEID:%s\n", e_gw_item_get_id (item));
g_string_append_printf (gstr, "X-GWSHOW-AS:BUSY\n");
@@ -2741,6 +2768,7 @@
EGwItemOrganizer *org = NULL;
GString *gstr = g_string_new (NULL);
char **tmp = NULL;
+ const char *temp = NULL;
tmp = g_strsplit (e_gw_item_get_id (item), "@", -1);
@@ -2750,7 +2778,21 @@
g_string_append_printf (gstr, "UID:%s\n",e_gw_item_get_icalid (item));
g_string_append_printf (gstr, "DTSTART:%s\n",e_gw_item_get_start_date (item));
g_string_append_printf (gstr, "SUMMARY:%s\n", e_gw_item_get_subject (item));
- g_string_append_printf (gstr, "DESCRIPTION:%s\n", e_gw_item_get_message (item));
+
+ temp = e_gw_item_get_message (item);
+ if (temp) {
+ g_string_append(gstr, "DESCRIPTION:");
+ while (*temp) {
+ if (*temp == '\n')
+ g_string_append(gstr, "\\n");
+ else
+ g_string_append_c(gstr, *temp);
+ temp++;
+ }
+ g_string_append(gstr, "\n");
+ }
+ temp = NULL;
+
g_string_append_printf (gstr, "DTSTAMP:%s\n", e_gw_item_get_creation_date (item));
g_string_append_printf (gstr, "X-GWMESSAGEID:%s\n", e_gw_item_get_id (item));
g_string_append_printf (gstr, "X-GWRECORDID:%s\n", tmp[0]);
Modified: branches/camel-gobject/camel/providers/groupwise/camel-groupwise-provider.c
==============================================================================
--- branches/camel-gobject/camel/providers/groupwise/camel-groupwise-provider.c (original)
+++ branches/camel-gobject/camel/providers/groupwise/camel-groupwise-provider.c Tue Jan 6 01:56:50 2009
@@ -73,7 +73,7 @@
N_("SOAP Settings") },
{ CAMEL_PROVIDER_CONF_ENTRY, "soap_port", NULL,
- N_("Post Office Agent SOAP Port:"), "7191" },
+ N_("Post Office Agent SOAP _Port:"), "7191" },
{ CAMEL_PROVIDER_CONF_HIDDEN, "auth-domain", NULL,
NULL, "Groupwise" },
Modified: branches/camel-gobject/camel/providers/groupwise/camel-groupwise-store.c
==============================================================================
--- branches/camel-gobject/camel/providers/groupwise/camel-groupwise-store.c (original)
+++ branches/camel-gobject/camel/providers/groupwise/camel-groupwise-store.c Tue Jan 6 01:56:50 2009
@@ -1430,6 +1430,17 @@
return NULL;
}
+static gboolean
+groupwise_can_refresh_folder (CamelStore *store, CamelFolderInfo *info, CamelException *ex)
+{
+ gboolean res;
+
+ res = CAMEL_STORE_CLASS(parent_class)->can_refresh_folder (store, info, ex) ||
+ (camel_url_get_param (((CamelService *)store)->url, "check_all") != NULL);
+
+ return res;
+}
+
/*
* Function to check if we are both connected and are _actually_
* online. Based on an equivalient function in IMAP
@@ -1498,6 +1509,7 @@
camel_store_class->get_folder_info = groupwise_get_folder_info;
camel_store_class->free_folder_info = camel_store_free_folder_info_full;
camel_store_class->get_trash = groupwise_get_trash;
+ camel_store_class->can_refresh_folder = groupwise_can_refresh_folder;
}
@@ -1597,3 +1609,4 @@
return camel_groupwise_store_type;
}
+
Modified: branches/camel-gobject/camel/providers/imap/camel-imap-folder.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap/camel-imap-folder.c (original)
+++ branches/camel-gobject/camel/providers/imap/camel-imap-folder.c Tue Jan 6 01:56:50 2009
@@ -473,6 +473,7 @@
break; }
/* imap args */
case CAMEL_IMAP_FOLDER_ARG_CHECK_FOLDER:
+ /* The internal value has precedence before the one stored in the summary. */
*arg->ca_int = ((CamelImapFolder *)object)->check_folder;
break;
/* CamelObject args */
@@ -514,8 +515,27 @@
switch (tag & CAMEL_ARG_TAG) {
case CAMEL_IMAP_FOLDER_ARG_CHECK_FOLDER:
if (((CamelImapFolder *)object)->check_folder != arg->ca_int) {
+ CamelFolder *folder = (CamelFolder *)object;
+
((CamelImapFolder *)object)->check_folder = arg->ca_int;
save = 1;
+
+ /* store both to the summary and to folder cmeta, to have this value restored correctly next time folder is fully loaded */
+ if (folder->parent_store && CAMEL_IS_IMAP_STORE (folder->parent_store)) {
+ CamelStoreInfo *si;
+ CamelStoreSummary *sm = CAMEL_STORE_SUMMARY (((CamelImapStore *)(folder->parent_store))->summary);
+
+ si = camel_store_summary_path (sm, folder->full_name);
+ if (si) {
+ if ((si->flags & CAMEL_STORE_INFO_FOLDER_CHECK_FOR_NEW) != 0 ? 1 : 0 != (arg->ca_int) ? 1 : 0) {
+ si->flags = (si->flags & (~CAMEL_STORE_INFO_FOLDER_CHECK_FOR_NEW)) | ((arg->ca_int) ? CAMEL_STORE_INFO_FOLDER_CHECK_FOR_NEW : 0);
+ camel_store_summary_touch (sm);
+ camel_store_summary_save (sm);
+ }
+
+ camel_store_summary_info_free (sm, si);
+ }
+ }
}
break;
default:
@@ -1587,6 +1607,8 @@
camel_folder_summary_save_to_db (folder->summary, ex);
uids = camel_db_get_folder_deleted_uids (folder->parent_store->cdb_r, folder->full_name, ex);
+ if (!uids)
+ return;
if (CAMEL_OFFLINE_STORE (store)->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL)
imap_expunge_uids_online (folder, uids, ex);
@@ -2254,12 +2276,12 @@
if (response)
handle_copyuid_copy_user_tags (response, source, destination);
camel_imap_response_free (store, response);
+ }
- if (!camel_exception_is_set(ex) && delete_originals) {
- for (i=last;i<uid;i++)
- camel_folder_delete_message(source, uids->pdata[i]);
- last = uid;
- }
+ if (!camel_exception_is_set(ex) && delete_originals) {
+ for (i=last;i<uid;i++)
+ camel_folder_delete_message(source, uids->pdata[i]);
+ last = uid;
}
g_free (uidset);
}
@@ -2899,12 +2921,29 @@
&& retry < 2
&& camel_exception_get_id(ex) == CAMEL_EXCEPTION_SERVICE_UNAVAILABLE);
-done: /* FIXME, this shouldn't be done this way. */
- if (msg)
+done:
+ if (msg) {
+ /* FIXME, this shouldn't be done this way. */
camel_medium_set_header (CAMEL_MEDIUM (msg), "X-Evolution-Source", store->base_url);
+
+ if (!mi->info.mlist || !*mi->info.mlist) {
+ /* update mailing list information, if necessary */
+ char *mlist = camel_header_raw_check_mailing_list (&(CAMEL_MIME_PART (msg)->headers));
+
+ if (mlist) {
+ if (mi->info.mlist)
+ camel_pstring_free (mi->info.mlist);
+ mi->info.mlist = camel_pstring_add (mlist, TRUE);
+ mi->info.dirty = TRUE;
+
+ if (mi->info.summary)
+ camel_folder_summary_touch (mi->info.summary);
+ }
+ }
+ }
fail:
camel_message_info_free(&mi->info);
-
+
return msg;
}
Modified: branches/camel-gobject/camel/providers/imap/camel-imap-journal.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap/camel-imap-journal.c (original)
+++ branches/camel-gobject/camel/providers/imap/camel-imap-journal.c Tue Jan 6 01:56:50 2009
@@ -160,6 +160,25 @@
}
static GPtrArray *
+copy_uids_array (GPtrArray *array)
+{
+ GPtrArray *res;
+ guint i, sz;
+
+ if (!array)
+ return NULL;
+
+ sz = array->len;
+ res = g_ptr_array_sized_new (sz);
+
+ for (i = 0; i < sz; i++) {
+ g_ptr_array_add (res, g_strdup (g_ptr_array_index (array, i)));
+ }
+
+ return res;
+}
+
+static GPtrArray *
decode_uids (FILE *file)
{
GPtrArray *uids;
@@ -413,20 +432,20 @@
{
GPtrArray *uids = va_arg (ap, GPtrArray *);
- entry->uids = uids;
+ entry->uids = copy_uids_array (uids);
break;
}
case CAMEL_IMAP_JOURNAL_ENTRY_APPEND:
{
char *uid = va_arg (ap, char *);
- entry->append_uid = uid;
+ entry->append_uid = g_strdup (uid);
break;
}
case CAMEL_IMAP_JOURNAL_ENTRY_TRANSFER:
{
CamelFolder *dest = va_arg (ap, CamelFolder *);
- entry->uids = va_arg (ap, GPtrArray *);
+ entry->uids = copy_uids_array (va_arg (ap, GPtrArray *));
entry->move = va_arg (ap, gboolean);
entry->dest_folder_name = g_strdup (dest->full_name);
break;
Modified: branches/camel-gobject/camel/providers/imap/camel-imap-store.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap/camel-imap-store.c (original)
+++ branches/camel-gobject/camel/providers/imap/camel-imap-store.c Tue Jan 6 01:56:50 2009
@@ -2385,7 +2385,7 @@
if (si == NULL)
return NULL;
- newflags = (si->info.flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) | (flags & ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED);
+ newflags = (si->info.flags & (CAMEL_STORE_INFO_FOLDER_SUBSCRIBED | CAMEL_STORE_INFO_FOLDER_CHECK_FOR_NEW)) | (flags & ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED);
if (si->info.flags != newflags) {
si->info.flags = newflags;
camel_store_summary_touch((CamelStoreSummary *)imap_store->summary);
@@ -3074,12 +3074,19 @@
(camel_url_get_param (((CamelService *)store)->url, "check_all") != NULL) ||
(camel_url_get_param (((CamelService *)store)->url, "check_lsub") != NULL && (info->flags & CAMEL_FOLDER_SUBSCRIBED) != 0);
- if (!res && !camel_exception_is_set (ex)) {
- CamelFolder *folder;
+ if (!res && !camel_exception_is_set (ex) && CAMEL_IS_IMAP_STORE (store)) {
+ CamelStoreInfo *si;
+ CamelStoreSummary *sm = CAMEL_STORE_SUMMARY (((CamelImapStore *)(store))->summary);
- folder = camel_store_get_folder (store, info->full_name, 0, ex);
- if (folder && CAMEL_IS_IMAP_FOLDER (folder))
- res = CAMEL_IMAP_FOLDER (folder)->check_folder;
+ if (!sm)
+ return FALSE;
+
+ si = camel_store_summary_path (sm, info->full_name);
+ if (si) {
+ res = (si->flags & CAMEL_STORE_INFO_FOLDER_CHECK_FOR_NEW) != 0 ? TRUE : FALSE;
+
+ camel_store_summary_info_free (sm, si);
+ }
}
return res;
Modified: branches/camel-gobject/camel/providers/imap/camel-imap-summary.c
==============================================================================
--- branches/camel-gobject/camel/providers/imap/camel-imap-summary.c (original)
+++ branches/camel-gobject/camel/providers/imap/camel-imap-summary.c Tue Jan 6 01:56:50 2009
@@ -163,6 +163,22 @@
return (a1 < a1) ? -1 : (a1 > a2) ? 1 : 0;
}
+static int
+uid_compare (const void *va, const void *vb)
+{
+ const char **sa = (const char **)va, **sb = (const char **)vb;
+ unsigned long a, b;
+
+ a = strtoul (*sa, NULL, 10);
+ b = strtoul (*sb, NULL, 10);
+ if (a < b)
+ return -1;
+ else if (a == b)
+ return 0;
+ else
+ return 1;
+}
+
/**
* camel_imap_summary_new:
* @folder: Parent folder.
@@ -181,7 +197,8 @@
camel_exception_init (&ex);
summary->folder = folder;
- if (folder) {
+ /* Don't do DB sort. Its pretty slow to load */
+ if (folder && 0) {
camel_db_set_collate (folder->parent_store->cdb_r, "uid", "imap_uid_sort", (CamelDBCollate)sort_uid_cmp);
summary->sort_by = "uid";
summary->collate = "imap_uid_sort";
@@ -199,6 +216,8 @@
camel_exception_clear (&ex);
}
+ g_ptr_array_sort (summary->uids, (GCompareFunc) uid_compare);
+
return summary;
}
Modified: branches/camel-gobject/camel/providers/local/camel-local-folder.c
==============================================================================
--- branches/camel-gobject/camel/providers/local/camel-local-folder.c (original)
+++ branches/camel-gobject/camel/providers/local/camel-local-folder.c Tue Jan 6 01:56:50 2009
@@ -290,7 +290,7 @@
}
folder->summary = (CamelFolderSummary *)CLOCALF_CLASS(lf)->create_summary(lf, lf->summary_path, lf->folder_path, lf->index);
- if (camel_local_summary_load((CamelLocalSummary *)folder->summary, forceindex, NULL) == -1) {
+ if (!(flags & CAMEL_STORE_IS_MIGRATING) && camel_local_summary_load((CamelLocalSummary *)folder->summary, forceindex, NULL) == -1) {
/* ? */
if (camel_local_summary_check((CamelLocalSummary *)folder->summary, lf->changes, ex) == 0) {
/* we sync here so that any hard work setting up the folder isn't lost */
Modified: branches/camel-gobject/camel/providers/pop3/camel-pop3-store.c
==============================================================================
--- branches/camel-gobject/camel/providers/pop3/camel-pop3-store.c (original)
+++ branches/camel-gobject/camel/providers/pop3/camel-pop3-store.c Tue Jan 6 01:56:50 2009
@@ -50,6 +50,7 @@
#include "camel-tcp-stream-raw.h"
#include "camel-tcp-stream.h"
#include "camel-url.h"
+#include "camel-utf8.h"
#ifdef HAVE_SSL
#include "camel-tcp-stream-ssl.h"
@@ -610,7 +611,9 @@
/* we only re-prompt if we failed to authenticate, any other error and we just abort */
if (status == 0 && camel_exception_get_id (ex) == CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE) {
- errbuf = g_markup_printf_escaped ("%s\n\n", camel_exception_get_description (ex));
+ char *tmp = camel_utf8_make_valid (camel_exception_get_description (ex));
+ errbuf = g_markup_printf_escaped ("%s\n\n", tmp);
+ g_free (tmp);
camel_exception_clear (ex);
camel_session_forget_password (session, service, NULL, "password", ex);
Modified: branches/camel-gobject/configure.in
==============================================================================
--- branches/camel-gobject/configure.in (original)
+++ branches/camel-gobject/configure.in Tue Jan 6 01:56:50 2009
@@ -4,7 +4,7 @@
# Evolution-Data-Server version */
m4_define([eds_major_version], [2])
m4_define([eds_minor_version], [25])
-m4_define([eds_micro_version], [2])
+m4_define([eds_micro_version], [4])
m4_define([eds_version],
[eds_major_version.eds_minor_version.eds_micro_version])
@@ -32,6 +32,7 @@
m4_define([libsoup_minimum_version], [2.3.0])
m4_define([gnome_keyring_minimum_version], [2.20.1])
m4_define([sqlite_minimum_version], [3.5])
+m4_define([gweather_minimum_version], [2.25.4])
dnl *************************************************************************************************
dnl Base Version
@@ -1000,6 +1001,28 @@
msg_calendar=$enable_calendar
dnl **************************************************
+dnl Weather calendar backend support
+dnl **************************************************
+AC_MSG_CHECKING(if we should build the weather calendar backend)
+AC_ARG_WITH([weather],
+ [AS_HELP_STRING([--with-weather], [Build the weather calendar backend (default=yes)])],
+ [use_gweather=$withval],
+ [use_gweather=yes])
+if test $enable_calendar = no; then
+ use_gweather="no (calendar support is disabled)"
+fi
+AC_MSG_RESULT($use_gweather)
+
+if test $use_gweather = yes; then
+ PKG_CHECK_MODULES([LIBGWEATHER],
+ [gweather >= gweather_minimum_version],
+ [],
+ [AC_MSG_ERROR([The weather calendar backend requires GWeather >= gweather_minimum_version. Alternatively, you may specify --without-weather as a configure option to avoid building the backend.])])
+fi
+
+AM_CONDITIONAL(ENABLE_WEATHER, test $use_gweather = yes)
+
+dnl **************************************************
dnl NNTP support.
dnl **************************************************
AC_ARG_ENABLE(nntp,
@@ -1624,8 +1647,10 @@
gladedir="$privdatadir/glade"
AC_SUBST(gladedir)
-weatherdatadir="$privdatadir/weather"
-AC_SUBST(weatherdatadir)
+if test $use_gweather = yes; then
+ weatherdatadir="$privdatadir/weather"
+ AC_SUBST(weatherdatadir)
+fi
dnl separate camel from e-d-s? or should it be under the same spot? same for now.
camel_providerdir='${libdir}'/evolution-data-server-$API_VERSION/camel-providers
@@ -1776,6 +1801,7 @@
echo "
evolution-data-server has been configured as follows:
Calendar: $msg_calendar
+ Weather calendar: $use_gweather
Mail Directory: $system_mail_dir, $system_mail_perm
LDAP support: $msg_ldap"
if test "$msg_nntp" = "yes"; then
Modified: branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-contact.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-contact.sgml (original)
+++ branches/camel-gobject/docs/reference/addressbook/libebook/tmpl/e-contact.sgml Tue Jan 6 01:56:50 2009
@@ -433,6 +433,41 @@
</para>
+<!-- ##### ARG EContact:im-skype ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EContact:im-skype-home-1 ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EContact:im-skype-home-2 ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EContact:im-skype-home-3 ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EContact:im-skype-work-1 ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EContact:im-skype-work-2 ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG EContact:im-skype-work-3 ##### -->
+<para>
+
+</para>
+
<!-- ##### ARG EContact:im-yahoo ##### -->
<para>
@@ -736,6 +771,13 @@
@E_CONTACT_IM_GADUGADU:
@E_CONTACT_GEO:
@E_CONTACT_TEL:
+ E_CONTACT_IM_SKYPE_HOME_1:
+ E_CONTACT_IM_SKYPE_HOME_2:
+ E_CONTACT_IM_SKYPE_HOME_3:
+ E_CONTACT_IM_SKYPE_WORK_1:
+ E_CONTACT_IM_SKYPE_WORK_2:
+ E_CONTACT_IM_SKYPE_WORK_3:
+ E_CONTACT_IM_SKYPE:
@E_CONTACT_FIELD_LAST:
@E_CONTACT_FIELD_FIRST:
@E_CONTACT_LAST_SIMPLE_STRING:
Modified: branches/camel-gobject/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
==============================================================================
--- branches/camel-gobject/docs/reference/addressbook/libedata-book/libedata-book-sections.txt (original)
+++ branches/camel-gobject/docs/reference/addressbook/libedata-book/libedata-book-sections.txt Tue Jan 6 01:56:50 2009
@@ -296,4 +296,6 @@
e_book_backend_db_cache_set_populated
e_book_backend_db_cache_is_populated
e_book_backend_db_cache_search
+e_book_backend_db_cache_set_time
+e_book_backend_db_cache_get_time
</SECTION>
Modified: branches/camel-gobject/docs/reference/addressbook/libedata-book/tmpl/e-book-backend-db-cache.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/addressbook/libedata-book/tmpl/e-book-backend-db-cache.sgml (original)
+++ branches/camel-gobject/docs/reference/addressbook/libedata-book/tmpl/e-book-backend-db-cache.sgml Tue Jan 6 01:56:50 2009
@@ -130,3 +130,21 @@
@Returns:
+<!-- ##### FUNCTION e_book_backend_db_cache_set_time ##### -->
+<para>
+
+</para>
+
+ db:
+ t:
+
+
+<!-- ##### FUNCTION e_book_backend_db_cache_get_time ##### -->
+<para>
+
+</para>
+
+ db:
+ Returns:
+
+
Modified: branches/camel-gobject/docs/reference/calendar/libecal/libecal-sections.txt
==============================================================================
--- branches/camel-gobject/docs/reference/calendar/libecal/libecal-sections.txt (original)
+++ branches/camel-gobject/docs/reference/calendar/libecal/libecal-sections.txt Tue Jan 6 01:56:50 2009
@@ -370,6 +370,7 @@
CAL_STATIC_CAPABILITY_ORGANIZER_MUST_ATTEND
CAL_STATIC_CAPABILITY_ORGANIZER_NOT_EMAIL_ADDRESS
CAL_STATIC_CAPABILITY_REMOVE_ALARMS
+CAL_STATIC_CAPABILITY_CREATE_MESSAGES
CAL_STATIC_CAPABILITY_SAVE_SCHEDULES
CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK
CAL_STATIC_CAPABILITY_NO_CONV_TO_RECUR
Modified: branches/camel-gobject/docs/reference/calendar/libecal/tmpl/e-cal-util.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/calendar/libecal/tmpl/e-cal-util.sgml (original)
+++ branches/camel-gobject/docs/reference/calendar/libecal/tmpl/e-cal-util.sgml Tue Jan 6 01:56:50 2009
@@ -327,6 +327,13 @@
+<!-- ##### MACRO CAL_STATIC_CAPABILITY_CREATE_MESSAGES ##### -->
+<para>
+
+</para>
+
+
+
<!-- ##### MACRO CAL_STATIC_CAPABILITY_SAVE_SCHEDULES ##### -->
<para>
Modified: branches/camel-gobject/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt
==============================================================================
--- branches/camel-gobject/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt (original)
+++ branches/camel-gobject/docs/reference/calendar/libedata-cal/libedata-cal-sections.txt Tue Jan 6 01:56:50 2009
@@ -159,7 +159,6 @@
e_cal_backend_get_free_busy
e_cal_backend_internal_get_default_timezone
e_cal_backend_internal_get_timezone
-e_cal_backend_last_client_gone
e_cal_backend_set_notification_proxy
e_cal_backend_notify_object_created
e_cal_backend_notify_object_modified
Modified: branches/camel-gobject/docs/reference/camel/camel-docs.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/camel/camel-docs.sgml (original)
+++ branches/camel-gobject/docs/reference/camel/camel-docs.sgml Tue Jan 6 01:56:50 2009
@@ -87,6 +87,7 @@
<!ENTITY CamelSASLPlain SYSTEM "xml/camel-sasl-plain.xml">
<!ENTITY CamelSASLPOPb4SMTP SYSTEM "xml/camel-sasl-popb4smtp.xml">
<!ENTITY CamelSearchSQL SYSTEM "xml/camel-search-sql.xml">
+<!ENTITY CamelSearchSQLSexp SYSTEM "xml/camel-search-sql-sexp.xml">
<!ENTITY CamelService SYSTEM "xml/camel-service.xml">
<!ENTITY CamelSession SYSTEM "xml/camel-session.xml">
<!ENTITY CamelSMIMEContext SYSTEM "xml/camel-smime-context.xml">
@@ -303,6 +304,7 @@
&CamelMsgPort;
&CamelNetUtils;
&CamelSearchSQL;
+ &CamelSearchSQLSexp;
&CamelStringUtils;
&CamelTrie;
&CamelUIDCache;
Modified: branches/camel-gobject/docs/reference/camel/camel-sections.txt
==============================================================================
--- branches/camel-gobject/docs/reference/camel/camel-sections.txt (original)
+++ branches/camel-gobject/docs/reference/camel/camel-sections.txt Tue Jan 6 01:56:50 2009
@@ -204,6 +204,7 @@
CamelFIRecord
CamelDBSelectCB
camel_db_open
+camel_db_clone
camel_db_close
camel_db_command
camel_db_transaction_command
@@ -216,6 +217,7 @@
camel_db_delete_folder
camel_db_delete_uid
camel_db_delete_uids
+camel_db_delete_vuids
camel_db_create_folders_table
camel_db_select
camel_db_write_folder_info_record
@@ -231,6 +233,7 @@
camel_db_count_visible_message_info
camel_db_count_visible_unread_message_info
camel_db_count_junk_not_deleted_message_info
+camel_db_count_message_info
camel_db_camel_mir_free
camel_db_create_vfolder
camel_db_recreate_vfolder
@@ -247,6 +250,8 @@
camel_db_get_column_name
camel_db_set_collate
camel_db_migrate_vfolders_to_14
+<SUBSECTION Private>
+CamelDBPrivate
</SECTION>
<SECTION>
@@ -405,6 +410,7 @@
camel_folder_search_by_expression
camel_folder_search_by_uids
camel_folder_search_free
+camel_folder_count_by_expression
camel_folder_get_message_info
camel_folder_free_message_info
camel_folder_ref_message_info
@@ -456,6 +462,7 @@
camel_folder_search_set_body_index
camel_folder_search_execute_expression
camel_folder_search_search
+camel_folder_search_count
camel_folder_search_free_result
<SUBSECTION Standard>
CAMEL_FOLDER_SEARCH
@@ -498,6 +505,7 @@
camel_folder_summary_header_save_to_db
camel_folder_summary_touch
camel_folder_summary_add
+camel_folder_summary_peek_info
camel_folder_summary_get_changed
camel_folder_summary_cache_size
camel_folder_summary_reload_from_db
@@ -524,6 +532,8 @@
camel_folder_summary_uid_from_index
camel_folder_summary_check_uid
camel_folder_summary_array
+camel_folder_summary_get_hashtable
+camel_folder_summary_free_hashtable
camel_folder_summary_encode_token
camel_folder_summary_decode_token
camel_flag_get
@@ -1299,7 +1309,6 @@
camel_interface_cast
camel_interface_is
camel_object_new
-camel_object_new_name
camel_object_ref
camel_object_unref
camel_object_hook_event
@@ -1577,6 +1586,11 @@
</SECTION>
<SECTION>
+<FILE>camel-search-sql-sexp</FILE>
+camel_sexp_to_sql_sexp
+</SECTION>
+
+<SECTION>
<FILE>camel-seekable-stream</FILE>
<TITLE>CamelSeekableStream</TITLE>
CamelSeekableStream
@@ -2096,6 +2110,8 @@
camel_vee_folder_set_folders
camel_vee_folder_rebuild_folder
camel_vee_folder_set_expression
+camel_vee_folder_mask_event_folder_changed
+camel_vee_folder_unmask_event_folder_changed
camel_vee_folder_hash_folder
camel_vee_folder_sync_headers
<SUBSECTION Standard>
@@ -3405,6 +3421,12 @@
CamelArgV
CamelArgGet
CamelArgGetV
+ca_object
+ca_int
+ca_double
+ca_str
+ca_ptr
+CAMEL_ARGV_MAX
camel_argv_start
camel_argv_end
camel_argv_build
Modified: branches/camel-gobject/docs/reference/libedataserverui/libedataserverui-sections.txt
==============================================================================
--- branches/camel-gobject/docs/reference/libedataserverui/libedataserverui-sections.txt (original)
+++ branches/camel-gobject/docs/reference/libedataserverui/libedataserverui-sections.txt Tue Jan 6 01:56:50 2009
@@ -257,6 +257,7 @@
e_source_selector_show_selection
e_source_selector_selection_shown
e_source_selector_set_select_new
+e_source_selector_edit_primary_selection
e_source_selector_peek_primary_selection
e_source_selector_set_primary_selection
e_source_selector_get_primary_source_group
@@ -312,6 +313,7 @@
<SECTION>
<FILE>e-data-server-ui-marshal</FILE>
+e_data_server_ui_marshal_BOOLEAN__BOXED_OBJECT_FLAGS_UINT
e_data_server_ui_marshal_BOOLEAN__OBJECT_BOXED
</SECTION>
Modified: branches/camel-gobject/docs/reference/libedataserverui/tmpl/e-data-server-ui-marshal.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/libedataserverui/tmpl/e-data-server-ui-marshal.sgml (original)
+++ branches/camel-gobject/docs/reference/libedataserverui/tmpl/e-data-server-ui-marshal.sgml Tue Jan 6 01:56:50 2009
@@ -17,6 +17,19 @@
<!-- ##### SECTION Stability_Level ##### -->
+<!-- ##### FUNCTION e_data_server_ui_marshal_BOOLEAN__BOXED_OBJECT_FLAGS_UINT ##### -->
+<para>
+
+</para>
+
+ closure:
+ return_value:
+ n_param_values:
+ param_values:
+ invocation_hint:
+ marshal_data:
+
+
<!-- ##### FUNCTION e_data_server_ui_marshal_BOOLEAN__OBJECT_BOXED ##### -->
<para>
Modified: branches/camel-gobject/docs/reference/libedataserverui/tmpl/e-source-selector.sgml
==============================================================================
--- branches/camel-gobject/docs/reference/libedataserverui/tmpl/e-source-selector.sgml (original)
+++ branches/camel-gobject/docs/reference/libedataserverui/tmpl/e-source-selector.sgml Tue Jan 6 01:56:50 2009
@@ -23,6 +23,18 @@
</para>
+<!-- ##### SIGNAL ESourceSelector::data-dropped ##### -->
+<para>
+
+</para>
+
+ esourceselector: the object which received the signal.
+ arg1:
+ arg2:
+ arg3:
+ arg4:
+ Returns:
+
<!-- ##### SIGNAL ESourceSelector::popup-event ##### -->
<para>
@@ -142,6 +154,14 @@
@state:
+<!-- ##### FUNCTION e_source_selector_edit_primary_selection ##### -->
+<para>
+
+</para>
+
+ selector:
+
+
<!-- ##### FUNCTION e_source_selector_peek_primary_selection ##### -->
<para>
Modified: branches/camel-gobject/evolution-data-server-zip.in
==============================================================================
--- branches/camel-gobject/evolution-data-server-zip.in (original)
+++ branches/camel-gobject/evolution-data-server-zip.in Tue Jan 6 01:56:50 2009
@@ -19,12 +19,14 @@
LIBEXCHANGE_STORAGE_CURRENT_MINUS_AGE=`expr @LIBEXCHANGE_STORAGE_CURRENT@ - @LIBEXCHANGE_STORAGE_AGE `
LIBGDATA_CURRENT_MINUS_AGE=`expr @LIBGDATA_CURRENT@ - @LIBGDATA_AGE `
LIBGDATA_GOOGLE_CURRENT_MINUS_AGE=`expr @LIBGDATA_GOOGLE_CURRENT@ - @LIBGDATA_GOOGLE_AGE `
+LIBEBACKEND_CURRENT_MINUS_AGE=`expr @LIBEBACKEND_CURRENT@ - @LIBEBACKEND_AGE `
cd @prefix@
rm $ZIP
zip $ZIP -@ <<EOF
bin/libcamel-1.2-$LIBCAMEL_CURRENT_MINUS_AGE.dll
bin/libcamel-provider-1.2-$LIBCAMEL_CURRENT_MINUS_AGE.dll
+bin/libebackend-1.2-$LIBEBACKEND_CURRENT_MINUS_AGE.dll
bin/libebook-1.2-$LIBEBOOK_CURRENT_MINUS_AGE.dll
bin/libecal-1.2-$LIBECAL_CURRENT_MINUS_AGE.dll
bin/libedata-book-1.2-$LIBEDATABOOK_CURRENT_MINUS_AGE.dll
@@ -90,34 +92,9 @@
lib/libexchange-storage-1.2.dll.a
lib/libgdata-1.2.dll.a
lib/libgdata-google-1.2.dll.a
-lib/pkgconfig/camel-1.2.pc
-lib/pkgconfig/camel-provider-1.2.pc
-lib/pkgconfig/evolution-data-server-1.2.pc
-lib/pkgconfig/libebook-1.2.pc
-lib/pkgconfig/libecal-1.2.pc
-lib/pkgconfig/libedata-book-1.2.pc
-lib/pkgconfig/libedata-cal-1.2.pc
-lib/pkgconfig/libedataserver-1.2.pc
-lib/pkgconfig/libedataserverui-1.2.pc
-lib/pkgconfig/libegroupwise-1.2.pc
-lib/pkgconfig/libexchange-storage-1.2.pc
-lib/pkgconfig/libgdata-1.2.pc
-lib/pkgconfig/libgdata-google-1.2.pc
-include/evolution-data-server- BASE_VERSION@/camel
-include/evolution-data-server- BASE_VERSION@/exchange
-include/evolution-data-server- BASE_VERSION@/google
-include/evolution-data-server- BASE_VERSION@/groupwise
-include/evolution-data-server- BASE_VERSION@/libebook
-include/evolution-data-server- BASE_VERSION@/libecal
-include/evolution-data-server- BASE_VERSION@/libedata-book
-include/evolution-data-server- BASE_VERSION@/libedata-cal
-include/evolution-data-server- BASE_VERSION@/libedataserver
-include/evolution-data-server- BASE_VERSION@/libedataserverui
-include/evolution-data-server- BASE_VERSION@/libical
-share/gtk-doc/html/libebook
-share/gtk-doc/html/libecal
-share/gtk-doc/html/libedata-cal
-share/gtk-doc/html/libedataserver
+lib/pkgconfig
+include/evolution-data-server- BASE_VERSION@
+share/gtk-doc
share/idl/evolution-data-server-1.2/Evolution-DataServer-Addressbook.idl
share/idl/evolution-data-server-1.2/Evolution-DataServer-Calendar.idl
share/idl/evolution-data-server-1.2/Evolution-DataServer.idl
Modified: branches/camel-gobject/libedataserver/e-sexp.c
==============================================================================
--- branches/camel-gobject/libedataserver/e-sexp.c (original)
+++ branches/camel-gobject/libedataserver/e-sexp.c Tue Jan 6 01:56:50 2009
@@ -706,7 +706,7 @@
r->value.time = t->value.time;
break;
case ESEXP_TERM_IFUNC:
- if (t->value.func.sym->f.ifunc)
+ if (t->value.func.sym && t->value.func.sym->f.ifunc)
r = t->value.func.sym->f.ifunc(f, t->value.func.termcount, t->value.func.terms, t->value.func.sym->data);
break;
case ESEXP_TERM_FUNC:
Modified: branches/camel-gobject/libedataserver/e-source.c
==============================================================================
--- branches/camel-gobject/libedataserver/e-source.c (original)
+++ branches/camel-gobject/libedataserver/e-source.c Tue Jan 6 01:56:50 2009
@@ -537,6 +537,7 @@
}
+#ifndef EDS_DISABLE_DEPRECATED
void
e_source_set_color (ESource *source,
guint32 color)
@@ -556,6 +557,7 @@
e_source_set_color_spec (source, NULL);
}
+#endif
/**
* e_source_set_color_spec:
@@ -646,6 +648,7 @@
}
+#ifndef EDS_DISABLE_DEPRECATED
/**
* e_source_get_color:
* @source: An ESource
@@ -679,6 +682,7 @@
return TRUE;
}
+#endif
char *
e_source_get_uri (ESource *source)
@@ -791,7 +795,7 @@
}
/**
- * e_source_compare:
+ * e_source_equal:
* @a: An ESource
* @b: Another ESource
*
Modified: branches/camel-gobject/libedataserver/e-url.c
==============================================================================
--- branches/camel-gobject/libedataserver/e-url.c (original)
+++ branches/camel-gobject/libedataserver/e-url.c Tue Jan 6 01:56:50 2009
@@ -180,6 +180,16 @@
slash = uri_string + strcspn (uri_string, "/#");
at = strchr (uri_string, '@');
if (at && at < slash) {
+ const char *at2;
+ /* this is for cases where username contains '@' at it, like:
+ http://user domain com@server.addr.com/path
+ We skip all at-s before the slash here. */
+
+ while (at2 = strchr (at + 1, '@'), at2 && at2 < slash) {
+ at = at2;
+ }
+ }
+ if (at && at < slash) {
colon = strchr (uri_string, ':');
if (colon && colon < at) {
uri->passwd = g_strndup (colon + 1, at - colon - 1);
Modified: branches/camel-gobject/libedataserverui/Makefile.am
==============================================================================
--- branches/camel-gobject/libedataserverui/Makefile.am (original)
+++ branches/camel-gobject/libedataserverui/Makefile.am Tue Jan 6 01:56:50 2009
@@ -12,6 +12,7 @@
lib_LTLIBRARIES = libedataserverui-1.2.la
noinst_PROGRAMS = \
+ test-category-completion \
test-source-combo-box \
test-source-selector \
test-contact-store \
@@ -20,6 +21,7 @@
libedataserverui_1_2_la_SOURCES = \
$(MARSHAL_GENERATED) \
e-categories-dialog.c \
+ e-category-completion.c \
e-destination-store.c \
e-book-auth-util.c \
e-contact-store.c \
@@ -48,6 +50,7 @@
libedataserveruiinclude_HEADERS = \
e-categories-dialog.h \
+ e-category-completion.h \
e-destination-store.h \
e-book-auth-util.h \
e-contact-store.h \
@@ -65,6 +68,12 @@
e-cell-renderer-color.h
# Test programs
+test_category_completion_SOURCES = test-category-completion.c
+test_category_completion_LDADD = \
+ libedataserverui-1.2.la \
+ $(top_builddir)/libedataserver/libedataserver-1.2.la \
+ $(E_DATA_SERVER_UI_LIBS)
+
test_source_selector_SOURCES = test-source-selector.c
test_source_selector_LDADD = \
libedataserverui-1.2.la \
Modified: branches/camel-gobject/libedataserverui/e-categories-dialog.c
==============================================================================
--- branches/camel-gobject/libedataserverui/e-categories-dialog.c (original)
+++ branches/camel-gobject/libedataserverui/e-categories-dialog.c Tue Jan 6 01:56:50 2009
@@ -28,6 +28,7 @@
#include "libedataserver/e-categories.h"
#include "libedataserver/libedataserver-private.h"
#include "e-categories-dialog.h"
+#include "e-category-completion.h"
enum {
COLUMN_ACTIVE,
@@ -59,6 +60,25 @@
GtkWidget *category_icon;
} CategoryPropertiesDialog;
+static void
+update_preview (GtkFileChooser *chooser, gpointer user_data)
+{
+ GtkImage *image;
+ char *filename;
+
+ g_return_if_fail (chooser != NULL);
+
+ image = GTK_IMAGE (gtk_file_chooser_get_preview_widget (chooser));
+ g_return_if_fail (image != NULL);
+
+ filename = gtk_file_chooser_get_preview_filename (chooser);
+
+ gtk_image_set_from_file (image, filename);
+ gtk_file_chooser_set_preview_widget_active (chooser, filename != NULL);
+
+ g_free (filename);
+}
+
static CategoryPropertiesDialog *
load_properties_dialog (ECategoriesDialog *parent)
{
@@ -86,6 +106,21 @@
prop_dialog->category_name = glade_xml_get_widget (prop_dialog->gui, "category-name");
prop_dialog->category_icon = glade_xml_get_widget (prop_dialog->gui, "category-icon");
+ if (prop_dialog->category_icon) {
+ GtkFileChooser *chooser = GTK_FILE_CHOOSER (prop_dialog->category_icon);
+
+ if (chooser) {
+ GtkWidget *image = gtk_image_new ();
+
+ gtk_widget_show (image);
+
+ gtk_file_chooser_set_preview_widget (chooser, image);
+ gtk_file_chooser_set_preview_widget_active (chooser, TRUE);
+
+ g_signal_connect (G_OBJECT (chooser), "update-preview", (GCallback) update_preview, NULL);
+ }
+ }
+
return prop_dialog;
}
@@ -110,6 +145,70 @@
G_DEFINE_TYPE (ECategoriesDialog, e_categories_dialog, GTK_TYPE_DIALOG)
static void
+categories_dialog_build_model (ECategoriesDialog *dialog)
+{
+ GtkTreeView *tree_view;
+ GtkListStore *store;
+ GList *list, *iter;
+
+ store = gtk_list_store_new (
+ N_COLUMNS, G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, G_TYPE_STRING);
+
+ gtk_tree_sortable_set_sort_column_id (
+ GTK_TREE_SORTABLE (store),
+ COLUMN_CATEGORY, GTK_SORT_ASCENDING);
+
+ list = e_categories_get_list ();
+ for (iter = list; iter != NULL; iter = iter->next) {
+ const gchar *category_name = iter->data;
+ const gchar *filename;
+ GdkPixbuf *pixbuf = NULL;
+ GtkTreeIter iter;
+ gboolean active;
+
+ /* Only add user-visible categories. */
+ if (!e_categories_is_searchable (category_name))
+ continue;
+
+ active = (g_hash_table_lookup (
+ dialog->priv->selected_categories,
+ category_name) != NULL);
+
+ filename = e_categories_get_icon_file_for (category_name);
+ if (filename != NULL)
+ pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
+
+ gtk_list_store_append (store, &iter);
+
+ gtk_list_store_set (
+ store, &iter,
+ COLUMN_ACTIVE, active,
+ COLUMN_ICON, pixbuf,
+ COLUMN_CATEGORY, category_name,
+ -1);
+
+ if (pixbuf != NULL)
+ g_object_unref (pixbuf);
+ }
+
+ tree_view = GTK_TREE_VIEW (dialog->priv->categories_list);
+ gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (store));
+
+ /* This has to be reset everytime we install a new model. */
+ gtk_tree_view_set_search_column (tree_view, COLUMN_CATEGORY);
+
+ g_list_free (list);
+ g_object_unref (store);
+}
+
+static void
+categories_dialog_listener_cb (gpointer useless_pointer,
+ ECategoriesDialog *dialog)
+{
+ categories_dialog_build_model (dialog);
+}
+
+static void
e_categories_dialog_dispose (GObject *object)
{
ECategoriesDialogPrivate *priv = E_CATEGORIES_DIALOG (object)->priv;
@@ -132,6 +231,9 @@
{
ECategoriesDialogPrivate *priv = E_CATEGORIES_DIALOG (object)->priv;
+ e_categories_unregister_change_listener (
+ G_CALLBACK (categories_dialog_listener_cb), object);
+
g_free (priv);
E_CATEGORIES_DIALOG (object)->priv = NULL;
@@ -155,7 +257,7 @@
GString **str = user_data;
if (strlen ((*str)->str) > 0)
- *str = g_string_append (*str, ",");
+ *str = g_string_append (*str, ", ");
*str = g_string_append (*str, (const char *) key);
}
@@ -247,7 +349,6 @@
if (gtk_dialog_run (GTK_DIALOG (prop_dialog->the_dialog)) == GTK_RESPONSE_OK) {
const char *category_name;
char *correct_category_name;
- GtkTreeIter iter;
category_name = gtk_entry_get_text (GTK_ENTRY (prop_dialog->category_name));
correct_category_name = check_category_name (category_name);
@@ -266,27 +367,12 @@
g_free (correct_category_name);
} else {
gchar *category_icon;
- GdkPixbuf *icon = NULL;
- GtkListStore *list_store = GTK_LIST_STORE (
- gtk_tree_view_get_model (GTK_TREE_VIEW (prop_dialog->parent->priv->categories_list)));
category_icon = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (prop_dialog->category_icon));
- if (category_icon)
- icon = gdk_pixbuf_new_from_file (category_icon, NULL);
e_categories_add (correct_category_name, NULL, category_icon, TRUE);
- gtk_list_store_append (list_store, &iter);
- gtk_list_store_set (list_store, &iter,
- COLUMN_ACTIVE, FALSE,
- COLUMN_ICON, icon,
- COLUMN_CATEGORY,correct_category_name,
- -1);
-
- if (icon)
- g_object_unref (icon);
- if (category_icon)
- g_free (category_icon);
+ g_free (category_icon);
g_free (correct_category_name);
break;
@@ -376,17 +462,15 @@
gtk_tree_model_get (model, &iter, COLUMN_CATEGORY, &category_name, -1);
e_categories_remove (category_name);
- gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
}
static void
e_categories_dialog_init (ECategoriesDialog *dialog)
{
ECategoriesDialogPrivate *priv;
- GList *cat_list;
GtkCellRenderer *renderer;
+ GtkEntryCompletion *completion;
GtkTreeViewColumn *column;
- GtkListStore *model;
GtkWidget *main_widget;
char *gladefile;
@@ -412,6 +496,10 @@
priv->categories_entry = glade_xml_get_widget (priv->gui, "entry-categories");
priv->categories_list = glade_xml_get_widget (priv->gui, "categories-list");
+ completion = e_category_completion_new ();
+ gtk_entry_set_completion (GTK_ENTRY (priv->categories_entry), completion);
+ g_object_unref (completion);
+
priv->new_button = glade_xml_get_widget (priv->gui, "button-new");
g_signal_connect (G_OBJECT (priv->new_button), "clicked", G_CALLBACK (new_button_clicked_cb), dialog);
priv->edit_button = glade_xml_get_widget (priv->gui, "button-edit");
@@ -425,37 +513,6 @@
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE);
gtk_window_set_title (GTK_WINDOW (dialog), _("Categories"));
- /* set up the categories list */
- model = gtk_list_store_new (
- N_COLUMNS, G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, G_TYPE_STRING);
- gtk_tree_sortable_set_sort_column_id (
- GTK_TREE_SORTABLE (model),
- COLUMN_CATEGORY, GTK_SORT_ASCENDING);
- cat_list = e_categories_get_list ();
- while (cat_list != NULL) {
- GtkTreeIter iter;
-
- /* only add categories that are user-visible */
- if (e_categories_is_searchable ((const char *) cat_list->data)) {
- const gchar *icon_file;
- GdkPixbuf *icon = NULL;
- icon_file = e_categories_get_icon_file_for ((const char *) cat_list->data);
- if (icon_file)
- icon = gdk_pixbuf_new_from_file (icon_file, NULL);
- gtk_list_store_append (model, &iter);
- gtk_list_store_set (model, &iter,
- COLUMN_ACTIVE, FALSE,
- COLUMN_ICON, icon,
- COLUMN_CATEGORY, cat_list->data,
- -1);
- if (icon)
- g_object_unref (icon);
- }
-
- cat_list = g_list_remove (cat_list, cat_list->data);
- }
- gtk_tree_view_set_model (GTK_TREE_VIEW (priv->categories_list), GTK_TREE_MODEL (model));
-
renderer = gtk_cell_renderer_toggle_new ();
g_signal_connect (G_OBJECT (renderer), "toggled", G_CALLBACK (category_toggled_cb), dialog);
column = gtk_tree_view_column_new_with_attributes ("?", renderer,
@@ -472,8 +529,10 @@
"text", COLUMN_CATEGORY, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (priv->categories_list), column);
- /* free memory */
- g_object_unref (model);
+ categories_dialog_build_model (dialog);
+
+ e_categories_register_change_listener (
+ G_CALLBACK (categories_dialog_listener_cb), dialog);
}
/**
Modified: branches/camel-gobject/libedataserverui/e-contact-store.c
==============================================================================
--- branches/camel-gobject/libedataserverui/e-contact-store.c (original)
+++ branches/camel-gobject/libedataserverui/e-contact-store.c Tue Jan 6 01:56:50 2009
@@ -372,6 +372,8 @@
GPtrArray *contacts;
gint i;
+ g_return_val_if_fail (find_uid != NULL, -1);
+
source_index = find_contact_source_by_view (contact_store, find_view);
if (source_index < 0)
return -1;
@@ -387,7 +389,7 @@
EContact *contact = g_ptr_array_index (contacts, i);
const gchar *uid = e_contact_get_const (contact, E_CONTACT_UID);
- if (!strcmp (find_uid, uid))
+ if (uid && !strcmp (find_uid, uid))
return i;
}
Modified: branches/camel-gobject/libedataserverui/e-data-server-ui-marshal.list
==============================================================================
--- branches/camel-gobject/libedataserverui/e-data-server-ui-marshal.list (original)
+++ branches/camel-gobject/libedataserverui/e-data-server-ui-marshal.list Tue Jan 6 01:56:50 2009
@@ -1 +1,2 @@
BOOLEAN:OBJECT,BOXED
+BOOLEAN:BOXED,OBJECT,FLAGS,UINT
Modified: branches/camel-gobject/libedataserverui/e-source-selector.c
==============================================================================
--- branches/camel-gobject/libedataserverui/e-source-selector.c (original)
+++ branches/camel-gobject/libedataserverui/e-source-selector.c Tue Jan 6 01:56:50 2009
@@ -68,12 +68,11 @@
SELECTION_CHANGED,
PRIMARY_SELECTION_CHANGED,
POPUP_EVENT,
+ DATA_DROPPED,
NUM_SIGNALS
};
static unsigned int signals[NUM_SIGNALS] = { 0 };
-static gboolean selector_popup_menu (GtkWidget *widget);
-
G_DEFINE_TYPE (ESourceSelector, e_source_selector, GTK_TYPE_TREE_VIEW)
/* Selection management. */
@@ -673,18 +672,6 @@
}
static gboolean
-selector_popup_menu (GtkWidget *widget)
-{
- ESourceSelector *selector = E_SOURCE_SELECTOR (widget);
- ESource *source;
- gboolean res = FALSE;
-
- source = e_source_selector_peek_primary_selection (selector);
- g_signal_emit (selector, signals[POPUP_EVENT], 0, source, NULL, &res);
- return res;
-}
-
-static gboolean
selector_button_press_event (GtkWidget *widget, GdkEventButton *event, ESourceSelector *selector)
{
ESourceSelectorPrivate *priv = selector->priv;
@@ -827,6 +814,161 @@
G_OBJECT_CLASS (e_source_selector_parent_class)->finalize (object);
}
+static void
+source_selector_drag_leave (GtkWidget *widget,
+ GdkDragContext *context,
+ guint time_)
+{
+ GtkTreeView *tree_view;
+ GtkTreeViewDropPosition pos;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ pos = GTK_TREE_VIEW_DROP_BEFORE;
+
+ gtk_tree_view_set_drag_dest_row (tree_view, NULL, pos);
+}
+
+static gboolean
+source_selector_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time_)
+{
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkTreePath *path = NULL;
+ GtkTreeIter iter;
+ GtkTreeViewDropPosition pos;
+ GdkDragAction action = 0;
+ gpointer object = NULL;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ model = gtk_tree_view_get_model (tree_view);
+
+ if (!gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &path, NULL))
+ goto exit;
+
+ if (!gtk_tree_model_get_iter (model, &iter, path))
+ goto exit;
+
+ gtk_tree_model_get (model, &iter, 0, &object, -1);
+
+ if (E_IS_SOURCE_GROUP (object) || e_source_get_readonly (object))
+ goto exit;
+
+ pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
+ gtk_tree_view_set_drag_dest_row (tree_view, path, pos);
+
+ if (context->actions & GDK_ACTION_MOVE)
+ action = GDK_ACTION_MOVE;
+ else
+ action = context->suggested_action;
+
+exit:
+ if (path != NULL)
+ gtk_tree_path_free (path);
+
+ if (object != NULL)
+ g_object_unref (object);
+
+ gdk_drag_status (context, action, time_);
+
+ return TRUE;
+}
+
+static gboolean
+source_selector_drag_drop (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time_)
+{
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ gboolean drop_zone;
+ gboolean valid;
+ gpointer object;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ model = gtk_tree_view_get_model (tree_view);
+
+ if (!gtk_tree_view_get_path_at_pos (
+ tree_view, x, y, &path, NULL, NULL, NULL))
+ return FALSE;
+
+ valid = gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_path_free (path);
+ g_return_val_if_fail (valid, FALSE);
+
+ gtk_tree_model_get (model, &iter, 0, &object, -1);
+ drop_zone = E_IS_SOURCE (object);
+ g_object_unref (object);
+
+ return drop_zone;
+}
+
+static void
+source_selector_drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time_)
+{
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkTreePath *path = NULL;
+ GtkTreeIter iter;
+ gpointer object = NULL;
+ gboolean delete;
+ gboolean success = FALSE;
+
+ tree_view = GTK_TREE_VIEW (widget);
+ model = gtk_tree_view_get_model (tree_view);
+ delete = (context->action == GDK_ACTION_MOVE);
+
+ if (!gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &path, NULL))
+ goto exit;
+
+ if (!gtk_tree_model_get_iter (model, &iter, path))
+ goto exit;
+
+ gtk_tree_model_get (model, &iter, 0, &object, -1);
+
+ if (!E_IS_SOURCE (object) || e_source_get_readonly (object))
+ goto exit;
+
+ g_signal_emit (
+ widget, signals[DATA_DROPPED], 0, selection_data,
+ object, context->action, info, &success);
+
+exit:
+ if (path != NULL)
+ gtk_tree_path_free (path);
+
+ if (object != NULL)
+ g_object_unref (object);
+
+ gtk_drag_finish (context, success, delete, time_);
+}
+
+static gboolean
+source_selector_popup_menu (GtkWidget *widget)
+{
+ ESourceSelector *selector;
+ ESource *source;
+ gboolean res = FALSE;
+
+ selector = E_SOURCE_SELECTOR (widget);
+ source = e_source_selector_peek_primary_selection (selector);
+ g_signal_emit (selector, signals[POPUP_EVENT], 0, source, NULL, &res);
+
+ return res;
+}
/* Initialization. */
static gboolean
@@ -854,7 +996,11 @@
object_class->finalize = source_selector_finalize;
widget_class = GTK_WIDGET_CLASS (class);
- widget_class->popup_menu = selector_popup_menu;
+ widget_class->drag_leave = source_selector_drag_leave;
+ widget_class->drag_motion = source_selector_drag_motion;
+ widget_class->drag_drop = source_selector_drag_drop;
+ widget_class->drag_data_received = source_selector_drag_data_received;
+ widget_class->popup_menu = source_selector_popup_menu;
g_object_class_install_property (
object_class,
@@ -893,6 +1039,18 @@
e_data_server_ui_marshal_BOOLEAN__OBJECT_BOXED,
G_TYPE_BOOLEAN, 2, G_TYPE_OBJECT,
GDK_TYPE_EVENT|G_SIGNAL_TYPE_STATIC_SCOPE);
+ signals[DATA_DROPPED] =
+ g_signal_new ("data_dropped",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ESourceSelectorClass, data_dropped),
+ NULL, NULL,
+ e_data_server_ui_marshal_BOOLEAN__BOXED_OBJECT_FLAGS_UINT,
+ G_TYPE_BOOLEAN, 4,
+ GTK_TYPE_SELECTION_DATA | G_SIGNAL_TYPE_STATIC_SCOPE,
+ E_TYPE_SOURCE,
+ GDK_TYPE_DRAG_ACTION,
+ G_TYPE_UINT);
}
static gboolean
Modified: branches/camel-gobject/libedataserverui/e-source-selector.h
==============================================================================
--- branches/camel-gobject/libedataserverui/e-source-selector.h (original)
+++ branches/camel-gobject/libedataserverui/e-source-selector.h Tue Jan 6 01:56:50 2009
@@ -49,9 +49,21 @@
struct _ESourceSelectorClass {
GtkTreeViewClass parent_class;
- void (* selection_changed) (ESourceSelector *selector);
- void (* primary_selection_changed) (ESourceSelector *selector);
- gboolean (*popup_event)(ESourceSelector *selector, ESource *primary, GdkEventButton *event);
+ void (*selection_changed) (ESourceSelector *selector);
+ void (*primary_selection_changed)
+ (ESourceSelector *selector);
+ gboolean (*popup_event) (ESourceSelector *selector,
+ ESource *primary,
+ GdkEventButton *event);
+ gboolean (*data_dropped) (ESourceSelector *selector,
+ GtkSelectionData *data,
+ ESource *destination,
+ GdkDragAction action,
+ guint target_info);
+
+ gpointer padding1;
+ gpointer padding2;
+ gpointer padding3;
};
Modified: branches/camel-gobject/servers/exchange/lib/e2k-autoconfig.c
==============================================================================
--- branches/camel-gobject/servers/exchange/lib/e2k-autoconfig.c (original)
+++ branches/camel-gobject/servers/exchange/lib/e2k-autoconfig.c Tue Jan 6 01:56:50 2009
@@ -1516,6 +1516,8 @@
}
if (*result == E2K_AUTOCONFIG_OK) {
+ int len;
+
*result = e2k_autoconfig_check_global_catalog (ac, &op);
e2k_operation_free (&op);
@@ -1524,6 +1526,13 @@
path = g_strdup (euri->path + 1);
e2k_uri_free (euri);
+ /* no slash at the end of path */
+ len = strlen (path);
+ while (len && path [len - 1] == '/') {
+ path [len - 1] = '\0';
+ len--;
+ }
+
/* change a mailbox only if not set by the caller */
if (!exchange_params->mailbox || !*exchange_params->mailbox) {
mailbox = strrchr (path, '/');
@@ -1536,6 +1545,12 @@
g_free (exchange_params->mailbox);
exchange_params->mailbox = g_strdup (mailbox);
+ } else {
+ /* always strip the mailbox part from the path */
+ char *slash = strrchr (path, '/');
+
+ if (slash)
+ *slash = '\0';
}
exchange_params->owa_path = g_strdup_printf ("%s%s", "/", path);
Modified: branches/camel-gobject/servers/groupwise/e-gw-connection.c
==============================================================================
--- branches/camel-gobject/servers/groupwise/e-gw-connection.c (original)
+++ branches/camel-gobject/servers/groupwise/e-gw-connection.c Tue Jan 6 01:56:50 2009
@@ -840,7 +840,7 @@
}
e_gw_message_write_string_parameter (msg, "uid", NULL, uid);
- e_gw_message_write_string_parameter (msg, "view", NULL, "count");
+ e_gw_message_write_string_parameter (msg, "view", NULL, "count unreadCount");
e_gw_message_write_footer (msg);
/* send message to server */
@@ -1813,39 +1813,41 @@
static time_t
timet_from_string (const char *str)
{
- struct tm date;
- int len, i;
+ struct tm date;
+ int len, i;
- g_return_val_if_fail (str != NULL, -1);
+ g_return_val_if_fail (str != NULL, -1);
- /* yyyymmdd[Thhmmss[Z]] */
- len = strlen (str);
+ /* yyyymmdd[Thhmmss[Z]] */
+ len = strlen (str);
- if (!(len == 8 || len == 15 || len == 16))
- return -1;
-
- for (i = 0; i < len; i++)
- if (!((i != 8 && i != 15 && isdigit (str[i]))
- || (i == 8 && str[i] == 'T')
- || (i == 15 && str[i] == 'Z')))
- return -1;
+ if (!(len == 8 || len == 15 || len == 16))
+ return -1;
+
+ for (i = 0; i < len; i++)
+ if (!((i != 8 && i != 15 && isdigit (str[i]))
+ || (i == 8 && str[i] == 'T')
+ || (i == 15 && str[i] == 'Z')))
+ return -1;
#define digit_at(x,y) (x[y] - '0')
- date.tm_year = digit_at (str, 0) * 1000
- + digit_at (str, 1) * 100
- + digit_at (str, 2) * 10
- + digit_at (str, 3) -1900;
- date.tm_mon = digit_at (str, 4) * 10 + digit_at (str, 5) -1;
- date.tm_mday = digit_at (str, 6) * 10 + digit_at (str, 7);
- if (len > 8) {
- date.tm_hour = digit_at (str, 9) * 10 + digit_at (str, 10);
- date.tm_min = digit_at (str, 11) * 10 + digit_at (str, 12);
- date.tm_sec = digit_at (str, 13) * 10 + digit_at (str, 14);
- } else
- date.tm_hour = date.tm_min = date.tm_sec = 0;
+ date.tm_year = digit_at (str, 0) * 1000
+ + digit_at (str, 1) * 100
+ + digit_at (str, 2) * 10
+ + digit_at (str, 3) -1900;
+ date.tm_mon = digit_at (str, 4) * 10 + digit_at (str, 5) -1;
+ date.tm_mday = digit_at (str, 6) * 10 + digit_at (str, 7);
+ if (len > 8) {
+ date.tm_hour = digit_at (str, 9) * 10 + digit_at (str, 10);
+ date.tm_min = digit_at (str, 11) * 10 + digit_at (str, 12);
+ date.tm_sec = digit_at (str, 13) * 10 + digit_at (str, 14);
+ } else
+ date.tm_hour = date.tm_min = date.tm_sec = 0;
+
+ date.tm_wday = date.tm_yday = date.tm_isdst = 0;
- return mktime (&date);
+ return mktime (&date);
}
char *
@@ -2770,7 +2772,7 @@
if (buffer && buf_length && atoi (buf_length) > 0) {
gsize len = atoi (buf_length) ;
- *attachment = g_base64_decode (buffer,&len) ;
+ *attachment = (char *) g_base64_decode (buffer,&len) ;
*attach_length = len ;
} else {
*attachment = NULL;
Modified: branches/camel-gobject/servers/groupwise/e-gw-item.c
==============================================================================
--- branches/camel-gobject/servers/groupwise/e-gw-item.c (original)
+++ branches/camel-gobject/servers/groupwise/e-gw-item.c Tue Jan 6 01:56:50 2009
@@ -307,6 +307,11 @@
priv->classification = NULL;
}
+ if (priv->security) {
+ g_free (priv->security);
+ priv->security = NULL;
+ }
+
if (priv->accept_level) {
g_free (priv->accept_level);
priv->accept_level = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]