Changeset 2293

Show
Ignore:
Timestamp:
07/08/07 09:23:53 (1 year ago)
Author:
abaumann
Message:

Further cleanup and updates to the kdepim plugin:

  • Re-add support for event and todo object types
  • Push more functionality into common code to reduce duplication
    between contact and event/todo modules
  • Remove unused wrapper for "read" callback
  • Other cleanup

This is only lightly tested, and still under development. Syncing
events currently results in a failed assertion in the vformat converter
and empty event data in the other sync members.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • plugins/kdepim/Makefile.am

    r2277 r2293  
    5050        src/kdepim_impl.cpp \ 
    5151        src/datasource.cpp \ 
    52         src/kaddrbook.cpp 
    53 #     src/kcal.cpp 
     52        src/kaddrbook.cpp \ 
     53      src/kcal.cpp 
    5454#       src/knotes.cpp 
    5555#nodist_kdepim_lib_la_SOURCES = KNotesIface_stub.cpp 
  • plugins/kdepim/src/datasource.cpp

    r2277 r2293  
     1/** 
     2 * @author Andrew Baumann <andrewb@cse.unsw.edu.au> 
     3 */ 
    14 
    25#include <stdlib.h> 
     
    3639        obj->get_changes(info, ctx); 
    3740        osync_trace(TRACE_EXIT, "%s", __PRETTY_FUNCTION__); 
    38 } 
    39  
    40 static osync_bool read_wrapper(void *userdata, OSyncPluginInfo *info, OSyncContext *ctx, OSyncChange *chg) 
    41 { 
    42         osync_trace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __PRETTY_FUNCTION__, userdata, info, ctx, chg); 
    43         OSyncDataSource *obj = (OSyncDataSource *)osync_objtype_sink_get_userdata(osync_plugin_info_get_sink(info)); 
    44         bool ret = obj->read(info, ctx, chg); 
    45         osync_trace(TRACE_EXIT, "%s: %d", __PRETTY_FUNCTION__, ret); 
    46         return ret; 
    4741} 
    4842 
     
    7569        NULL, // write 
    7670        NULL, // committed_all 
    77         read_wrapper, 
     71        NULL, // read 
    7872        NULL, // batch_commit 
    7973        sync_done_wrapper}; 
     
    8276{ 
    8377        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __PRETTY_FUNCTION__, plugin, info); 
    84          
    85         (void)plugin; // silence "unused argument" warning 
    8678         
    8779        sink = osync_objtype_sink_new(objtype, error); 
     
    133125} 
    134126 
     127bool OSyncDataSource::report_change(OSyncPluginInfo *info, OSyncContext *ctx, QString uid, QString data, QString hash, OSyncObjFormat *objformat) 
     128{ 
     129        OSyncError *error = NULL; 
     130        OSyncChangeType changetype; 
     131        OSyncData *odata; 
     132        OSyncChange *change; 
     133        char *data_str; 
     134 
     135        osync_trace(TRACE_ENTRY, "%s(%p, %p, %s, (data), (hash), %p)", __PRETTY_FUNCTION__, info, ctx, uid.data(), objformat); 
     136 
     137        change = osync_change_new(&error); 
     138        if (!change) 
     139                goto error; 
     140 
     141        osync_change_set_uid(change, uid.local8Bit()); 
     142 
     143        data_str = strdup((const char *)data.utf8()); 
     144 
     145        osync_trace(TRACE_SENSITIVE,"Data:\n%s", data_str); 
     146 
     147        odata = osync_data_new(data_str, strlen(data_str), objformat, &error); 
     148        if (!odata) 
     149                goto error; 
     150 
     151        osync_data_set_objtype(odata, osync_objtype_sink_get_name(sink)); 
     152 
     153        //Now you can set the data for the object 
     154        osync_change_set_data(change, odata); 
     155        osync_data_unref(odata); 
     156 
     157        // Use the hash table to check if the object 
     158        // needs to be reported 
     159        osync_change_set_hash(change, hash.data()); 
     160 
     161        // Report entry ... otherwise it gets deleted! 
     162        osync_hashtable_report(hashtable, uid); 
     163 
     164        changetype = osync_hashtable_get_changetype(hashtable, uid, hash.data()); 
     165        osync_change_set_changetype(change, changetype); 
     166        if (OSYNC_CHANGE_TYPE_UNMODIFIED != changetype) { 
     167                osync_context_report_change(ctx, change); 
     168                osync_hashtable_update_hash(hashtable, changetype, uid, hash.data()); 
     169        } 
     170 
     171        osync_trace(TRACE_EXIT, "%s", __PRETTY_FUNCTION__); 
     172        return true; 
     173 
     174error: 
     175        if (change) 
     176                osync_change_unref(change); 
     177        osync_context_report_osyncerror(ctx, error); 
     178        osync_trace(TRACE_EXIT_ERROR, "%s: %s", __PRETTY_FUNCTION__, osync_error_print(&error)); 
     179        osync_error_unref(&error); 
     180        return false; 
     181} 
     182 
     183bool OSyncDataSource::report_deleted(OSyncPluginInfo *info, OSyncContext *ctx) 
     184{ 
     185        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __PRETTY_FUNCTION__, info, ctx); 
     186         
     187        int i; 
     188        OSyncError *error = NULL; 
     189        char **uids = osync_hashtable_get_deleted(hashtable); 
     190        OSyncChange *change; 
     191         
     192        for (i=0; uids[i]; i++) { 
     193                osync_trace(TRACE_INTERNAL, "going to delete entry with uid: %s", uids[i]); 
     194                 
     195                change = osync_change_new(&error); 
     196                if (!change) { 
     197                        for (; uids[i]; i++) 
     198                                g_free(uids[i]); 
     199                        g_free(uids); 
     200                        osync_context_report_osyncerror(ctx, error); 
     201                        osync_trace(TRACE_EXIT_ERROR, "%s: %s", __PRETTY_FUNCTION__, osync_error_print(&error)); 
     202                        osync_error_unref(&error); 
     203                        return false; 
     204                } 
     205 
     206                osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_DELETED); 
     207                osync_change_set_uid(change, uids[i]); 
     208                osync_context_report_change(ctx, change); 
     209                osync_hashtable_update_hash(hashtable, OSYNC_CHANGE_TYPE_DELETED, uids[i], NULL); 
     210 
     211                g_free(uids[i]); 
     212                osync_change_unref(change); 
     213        } 
     214        g_free(uids); 
     215        osync_trace(TRACE_EXIT, "%s", __PRETTY_FUNCTION__); 
     216        return true; 
     217} 
     218 
    135219OSyncDataSource::~OSyncDataSource() 
    136220{ 
  • plugins/kdepim/src/datasource.h

    r2277 r2293  
    1 #ifndef KDEPIM_OSYNC_DATASOURCE_BASE_
    2 #define KDEPIM_OSYNC_DATASOURCE_BASE_
     1#ifndef KDEPIM_OSYNC_DATASOURCE_
     2#define KDEPIM_OSYNC_DATASOURCE_
    33 
    4 /* abstract parent class for all KDE Data sources/sinks */ 
    5 class OSyncDataSourceBase 
     4/* common parent class and shared code for all KDE Data sources/sinks */ 
     5class OSyncDataSource 
    66{ 
    7         public: 
    8                 virtual ~OSyncDataSourceBase() {}; 
     7        friend class KCalSharedResource; 
    98 
    10                 virtual bool initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) = 0; 
    11  
    12                 virtual void connect(OSyncPluginInfo *info, OSyncContext *ctx) = 0; 
    13                 virtual void disconnect(OSyncPluginInfo *info, OSyncContext *ctx) = 0; 
    14                 virtual void get_changes(OSyncPluginInfo *info, OSyncContext *ctx) = 0; 
    15                 virtual bool read(OSyncPluginInfo *info, OSyncContext *ctx, OSyncChange *chg) = 0; 
    16                 virtual void commit(OSyncPluginInfo *info, OSyncContext *ctx, OSyncChange *chg) = 0; 
    17                 virtual void sync_done(OSyncPluginInfo *info, OSyncContext *ctx) = 0; 
    18 }; 
    19  
    20 /* common implementation of OSyncDataSourceBase */ 
    21 class OSyncDataSource : public OSyncDataSourceBase 
    22 { 
    239        protected: 
    2410                const char *objtype; 
     
    2612                OSyncObjTypeSink *sink; 
    2713 
     14                /* utility functions for subclasses */ 
     15                bool report_change(OSyncPluginInfo *info, OSyncContext *ctx, QString uid, QString data, QString hash, OSyncObjFormat *objformat); 
     16                bool report_deleted(OSyncPluginInfo *info, OSyncContext *ctx); 
     17 
    2818        public: 
    2919                OSyncDataSource(const char *objtype) : objtype(objtype) {} 
    3020                virtual ~OSyncDataSource(); 
    3121                 
    32                 virtual bool initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error); 
     22                /* common code for some of the callbacks, should be used by a subclass */ 
     23                bool initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error); 
     24 
     25                /* these map to opensync's per-sink callbacks */ 
    3326                virtual void connect(OSyncPluginInfo *info, OSyncContext *ctx); 
     27                virtual void disconnect(OSyncPluginInfo *info, OSyncContext *ctx) = 0; 
     28                virtual void get_changes(OSyncPluginInfo *info, OSyncContext *ctx) = 0; 
     29                virtual void commit(OSyncPluginInfo *info, OSyncContext *ctx, OSyncChange *chg) = 0; 
    3430                virtual void sync_done(OSyncPluginInfo *info, OSyncContext *ctx); 
    3531}; 
    3632 
    37 #endif // KDEPIM_OSYNC_DATASOURCE_BASE_
     33#endif // KDEPIM_OSYNC_DATASOURCE_
  • plugins/kdepim/src/kaddrbook.cpp

    r2277 r2293  
    2222*************************************************************************/ 
    2323/** 
    24  * @autor Eduardo Pereira Habkost <ehabkost@conectiva.com.br> 
    25  * @autor Armin Bauer <armin.bauer@opensync.org> 
     24 * @author Eduardo Pereira Habkost <ehabkost@conectiva.com.br> 
     25 * @author Armin Bauer <armin.bauer@opensync.org> 
     26 * @author Andrew Baumann <andrewb@cse.unsw.edu.au> 
    2627 */ 
    2728 
     
    9293         
    9394        osync_trace(TRACE_EXIT, "%s", __PRETTY_FUNCTION__); 
    94         return; 
    9595} 
    9696 
     
    121121        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __PRETTY_FUNCTION__, info, ctx); 
    122122 
    123         OSyncError *error = NULL; 
    124         OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info); 
    125  
    126123        if (osync_objtype_sink_get_slowsync(sink)) { 
    127                 osync_trace(TRACE_INTERNAL, "Got slow-sync"); 
     124                osync_trace(TRACE_INTERNAL, "Got slow-sync, resetting hashtable"); 
    128125                osync_hashtable_reset(hashtable); 
    129126        } 
     
    141138        KABC::VCardConverter converter; 
    142139        for (KABC::AddressBook::Iterator it=addressbookptr->begin(); it!=addressbookptr->end(); it++ ) { 
    143                 QString uid = it->uid(); 
    144  
    145                 OSyncChange *change = osync_change_new(&error); 
    146  
    147                 osync_change_set_uid(change, uid.local8Bit()); 
    148  
    149                 QString hash = calc_hash(*it); 
    150  
    151140                // Convert the VCARD data into a string 
    152141                // only vcard3.0 exports Categories 
    153                 QString tmp = converter.createVCard(*it, KABC::VCardConverter::v3_0); 
    154  
    155                 char *data = strdup((const char *)tmp.utf8()); 
    156  
    157                 osync_trace(TRACE_SENSITIVE,"\n%s", data); 
    158  
    159                 OSyncData *odata = osync_data_new(data, strlen(data), objformat, &error); 
    160                 if (!odata) { 
    161                         osync_change_unref(change); 
    162                         osync_context_report_osyncwarning(ctx, error); 
    163                         osync_error_unref(&error); 
    164                         continue; 
    165                 } 
    166  
    167                 osync_data_set_objtype(odata, osync_objtype_sink_get_name(sink)); 
    168  
    169                 //Now you can set the data for the object 
    170                 osync_change_set_data(change, odata); 
    171                 osync_data_unref(odata); 
    172  
    173                 // Use the hash table to check if the object 
    174                 // needs to be reported 
    175                 osync_change_set_hash(change, hash.data()); 
    176  
    177                 // Report entry ... otherwise it gets deleted! 
    178                 osync_hashtable_report(hashtable, uid); 
    179  
    180                 OSyncChangeType changetype = osync_hashtable_get_changetype(hashtable, uid.local8Bit(), hash.data()); 
    181                 osync_change_set_changetype(change, changetype); 
    182                 if (OSYNC_CHANGE_TYPE_UNMODIFIED != changetype) { 
    183                         osync_context_report_change(ctx, change); 
    184                         osync_hashtable_update_hash(hashtable, changetype, uid, hash.data()); 
    185                 } 
    186         } 
    187  
    188         int i; 
    189         char **uids = osync_hashtable_get_deleted(hashtable); 
    190         for (i=0; uids[i]; i++) { 
    191                 osync_trace(TRACE_INTERNAL, "going to delete entry with uid: %s", uids[i]); 
    192                 OSyncChange *change = osync_change_new(&error); 
    193                 if (!change) { 
    194                         g_free(uids[i]); 
    195                         osync_context_report_osyncwarning(ctx, error); 
    196                         osync_error_unref(&error); 
    197                         continue; 
    198                 } 
    199  
    200                 osync_change_set_uid(change, uids[i]); 
    201                 osync_change_set_changetype(change, OSYNC_CHANGE_TYPE_DELETED); 
    202  
    203                 OSyncData *odata = osync_data_new(NULL, 0, objformat, &error); 
    204                 if (!odata) { 
    205                         g_free(uids[i]); 
    206                         osync_change_unref(change); 
    207                         osync_context_report_osyncwarning(ctx, error); 
    208                         osync_error_unref(&error); 
    209                         continue; 
    210                 } 
    211  
    212                 osync_data_set_objtype(odata, osync_objtype_sink_get_name(sink)); 
    213                 osync_change_set_data(change, odata); 
    214                 osync_data_unref(odata); 
    215  
    216                 osync_context_report_change(ctx, change); 
    217  
    218                 osync_hashtable_update_hash(hashtable, osync_change_get_changetype(change), osync_change_get_uid(change), NULL); 
    219  
    220                 osync_change_unref(change); 
    221                 g_free(uids[i]); 
    222         } 
    223         g_free(uids); 
     142                QString data = converter.createVCard(*it, KABC::VCardConverter::v3_0); 
     143 
     144                if (!report_change(info, ctx, it->uid(), data, calc_hash(*it), objformat)) { 
     145                        osync_trace(TRACE_EXIT_ERROR, "%s", __PRETTY_FUNCTION__); 
     146                        return; 
     147                } 
     148        } 
     149 
     150        if (!report_deleted(info, ctx)) { 
     151                osync_trace(TRACE_EXIT_ERROR, "%s", __PRETTY_FUNCTION__); 
     152                return; 
     153        } 
    224154 
    225155        osync_context_report_success(ctx); 
    226156        osync_trace(TRACE_EXIT, "%s", __PRETTY_FUNCTION__); 
    227         return; 
    228 
    229  
    230 /** vcard access method 
    231  * 
    232  * This method is used by both access() and commit_change() method, 
    233  * so it shouldn't call osync_context_report_success(). On success, 
    234  * it should just return true and let the caller report success() to 
    235  * OpenSync 
    236  */ 
    237 bool KContactDataSource::__vcard_access(OSyncContext *ctx, OSyncChange *chg) 
     157
     158 
     159void KContactDataSource::commit(OSyncPluginInfo *, OSyncContext *ctx, OSyncChange *chg) 
    238160{ 
    239161        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __PRETTY_FUNCTION__, ctx, chg); 
     
    288210                                osync_context_report_error(ctx, OSYNC_ERROR_FILE_NOT_FOUND, "Trying to delete entry with empty UID"); 
    289211                                osync_trace(TRACE_EXIT_ERROR, "%s: Trying to delete but uid is empty", __PRETTY_FUNCTION__); 
    290                                 return FALSE
     212                                return
    291213                        } 
    292214 
     
    303225                        osync_context_report_error(ctx, OSYNC_ERROR_NOT_SUPPORTED, "Operation not supported"); 
    304226                        osync_trace(TRACE_EXIT_ERROR, "%s: Operation not supported", __PRETTY_FUNCTION__); 
    305                         return FALSE; 
    306                 } 
    307         } 
    308  
    309         osync_trace(TRACE_EXIT, "%s", __PRETTY_FUNCTION__); 
    310         return TRUE; 
    311 
    312  
    313 bool KContactDataSource::read(OSyncPluginInfo *info, OSyncContext *ctx, OSyncChange *chg) 
    314 
    315         if (!__vcard_access(ctx, chg)) 
    316                 return false; 
     227                        return; 
     228                } 
     229        } 
     230 
     231        osync_hashtable_update_hash(hashtable, chtype, uid, osync_change_get_hash(chg)); 
    317232 
    318233        osync_context_report_success(ctx); 
    319         return true; 
    320 
    321  
    322 void KContactDataSource::commit(OSyncPluginInfo *info, OSyncContext *ctx, OSyncChange *chg) 
    323 
    324         if (__vcard_access(ctx, chg)) 
    325                 osync_context_report_success(ctx); 
    326         return; 
    327 
     234        osync_trace(TRACE_EXIT, "%s", __PRETTY_FUNCTION__); 
     235
  • plugins/kdepim/src/kaddrbook.h

    r2277 r2293  
    3535        private: 
    3636                KABC::AddressBook* addressbookptr; 
    37  
    38                 bool __vcard_access(OSyncContext *ctx, OSyncChange *chg); 
    3937                QString calc_hash(KABC::Addressee &e); 
    4038 
    4139        public: 
    4240                KContactDataSource() : OSyncDataSource("contact") {}; 
     41                virtual ~KContactDataSource() {}; 
    4342 
    44                 virtual bool initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error); 
     43                bool initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error); 
    4544                virtual void connect(OSyncPluginInfo *info, OSyncContext *ctx); 
    4645                virtual void disconnect(OSyncPluginInfo *info, OSyncContext *ctx); 
    4746                virtual void get_changes(OSyncPluginInfo *info, OSyncContext *ctx); 
    48                 virtual bool read(OSyncPluginInfo *info, OSyncContext *ctx, OSyncChange *chg); 
    4947                virtual void commit(OSyncPluginInfo *info, OSyncContext *ctx, OSyncChange *chg); 
    5048}; 
  • plugins/kdepim/src/kcal.cpp

    r1760 r2293  
    2121*************************************************************************/ 
    2222/** 
    23  * @autor Eduardo Pereira Habkost <ehabkost@conectiva.com.br> 
     23 * @author Eduardo Pereira Habkost <ehabkost@conectiva.com.br> 
     24 * @author Andrew Baumann <andrewb@cse.unsw.edu.au> 
    2425 */ 
    2526 
    2627#include "kcal.h" 
    2728 
     29#include <assert.h> 
    2830#include <kapplication.h> 
    2931#include <dcopclient.h> 
    3032 
    31 KCalDataSource::KCalDataSource(OSyncMember *member, OSyncHashTable *hashtable) 
    32                 : hashtable(hashtable), member(member) 
    33 
    34         connected = false; 
    35 
    36  
    37 bool KCalDataSource::connect(OSyncContext *ctx) 
    38 
     33bool KCalSharedResource::open(OSyncContext *ctx) 
     34
     35        if (refcount++ > 0) { 
     36                assert(calendar); 
     37                return true; 
     38        } 
     39 
    3940        DCOPClient *dcopc = KApplication::kApplication()->dcopClient(); 
    4041        if (!dcopc) { 
     
    6768#endif 
    6869 
    69         //Detection mechanismn if this is the first sync 
    70         if (osync_member_objtype_enabled(member, "event") 
    71             && !osync_anchor_compare(member, "event", "true")) { 
    72                 osync_trace(TRACE_INTERNAL, "Setting slow-sync for event"); 
    73                 osync_member_set_slow_sync(member, "event", TRUE); 
    74         } 
    75  
    76         if (osync_member_objtype_enabled(member, "todo") 
    77             && !osync_anchor_compare(member, "todo", "true")) { 
    78                 osync_trace(TRACE_INTERNAL, "Setting slow-sync for todo"); 
    79                 osync_member_set_slow_sync(member, "todo", TRUE); 
    80         } 
    81  
    8270//      osync_debug("kcal", 3, "Calendar: %d events", calendar->events().size()); 
    8371 
    84         connected = true; 
    85         return true; 
    86 
    87  
    88 bool KCalDataSource::disconnect(OSyncContext *) 
     72        return true; 
     73
     74 
     75bool KCalSharedResource::close(OSyncContext *) 
    8976{ 
    9077        /* Save the changes */ 
    9178        calendar->save(); 
     79         
     80        if (--refcount > 0) 
     81                return true; 
    9282 
    9383        delete calendar; 
    9484        calendar = NULL; 
    95         connected = false; 
    96         return true; 
    97 
    98  
     85        return true; 
     86
     87         
    9988static QString calc_hash(const KCal::Incidence *e) 
    10089{ 
     
    10897} 
    10998 
    110 /** Report a list of calendar incidences (events or to-dos), with the 
    111  * right objtype and objformat. 
    112  * 
    113  * This function exists because the logic for converting the events or to-dos 
    114  * is the same, only the objtype and format is different. 
    115  */ 
    116 bool KCalDataSource::report_incidence(OSyncContext *ctx, KCal::Incidence *e, const char *objtype, const char *objformat) 
    117 { 
    118 //      osync_debug("kcal", 3, "One calendar incidence (%s)", objtype); 
    119         QString hash = calc_hash(e); 
    120  
    121         QString uid = e->uid(); 
    122  
    123         /* Build a local calendar for the incidence data */ 
    124         KCal::CalendarLocal cal(calendar->timeZoneId()); 
    125 //      osync_debug("kcal", 3, "timezoneid: %s\n", (const char*)cal.timeZoneId().local8Bit()); 
    126         cal.addIncidence(e->clone()); 
    127  
    128         /* Convert the data to vcalendar */ 
    129         KCal::ICalFormat format; 
    130         QCString datastr = format.toString(&cal).utf8(); 
    131         const char *data = datastr; 
    132  
    133 //      osync_debug("kcal", 3, "UID: %s\n", (const char*)uid.local8Bit()); 
    134         OSyncChange *chg = osync_change_new(); 
    135         osync_change_set_uid(chg, uid.local8Bit()); 
    136         osync_change_set_member(chg, member); 
    137  
    138         // object type and format 
    139         osync_change_set_objtype_string(chg, objtype); 
    140         osync_change_set_objformat_string(chg, objformat); 
    141         osync_change_set_data(chg, strdup(data), strlen(data) +1, 1); 
    142  
    143         // Use the hash table to check if the object 
    144         // needs to be reported 
    145         osync_change_set_hash(chg, hash.data()); 
    146         if (osync_hashtable_detect_change(hashtable, chg)) { 
    147                 osync_context_report_change(ctx, chg); 
    148                 osync_hashtable_update_hash(hashtable, chg); 
    149         } 
    150  
    151         return true; 
    152 } 
    153  
    154 bool KCalDataSource::get_changeinfo_events(OSyncContext *ctx) 
    155 { 
    156         KCal::Event::List events = calendar->events(); 
    157 //      osync_debug("kcal", 3, "Number of events: %d", events.size()); 
    158  
    159         if (osync_member_get_slow_sync(member, "event")) { 
    160 //              osync_debug("kcal", 3, "Setting slow-sync for events"); 
    161                 osync_hashtable_set_slow_sync(hashtable, "event"); 
    162         } 
    163  
    164         for (KCal::Event::List::ConstIterator i = events.begin(); i != events.end(); i++) { 
    165  
    166                 /* Skip entries from birthday resource. This is just a workaround. 
    167                  * patch by rhuitl 
    168                  * FIXME: todo: add a list of resources to kdepim-sync.conf 
    169                  */ 
    170                 if ( (*i)->uid().contains("KABC_Birthday") || (*i)->uid().contains("KABC_Anniversary") ) 
    171                         continue; 
    172  
    173                 if (!report_incidence(ctx, *i, "event", "vevent20")) 
    174                         return false; 
    175         } 
    176  
    177         osync_hashtable_report_deleted(hashtable, ctx, "event"); 
    178  
    179         return true; 
    180 } 
    181  
    182 bool KCalDataSource::get_changeinfo_todos(OSyncContext *ctx) 
    183 { 
    184         KCal::Todo::List todos = calendar->todos(); 
    185  
    186 //      osync_debug("kcal", 3, "Number of to-dos: %d", todos.size()); 
    187  
    188         if (osync_member_get_slow_sync(member, "todo")) { 
    189 //              osync_debug("kcal", 3, "Setting slow-sync for todos"); 
    190                 osync_hashtable_set_slow_sync(hashtable, "todo"); 
    191         } 
    192  
    193         for (KCal::Todo::List::ConstIterator i = todos.begin(); i != todos.end(); i++) { 
    194 //              osync_debug("kcal", 3, "%p: doesFloat: %d", *i, (*i)->doesFloat()); 
    195                 if (!report_incidence(ctx, *i, "todo", "vtodo20")) 
    196                         return false; 
    197         } 
    198  
    199         osync_hashtable_report_deleted(hashtable, ctx, "todo"); 
    200  
    201         return true; 
    202  
    203 } 
    204  
    205 void KCalDataSource::get_data(OSyncContext *ctx, OSyncChange *) 
    206 { 
    207         osync_context_report_error(ctx, OSYNC_ERROR_NOT_SUPPORTED, "Not implemented yet"); 
    208 } 
    209  
    21099/** Add or change a incidence on the calendar. This function 
    211100 * is used for events and to-dos 
    212101 */ 
    213 bool KCalDataSource::__access(OSyncContext *ctx, OSyncChange *chg) 
     102bool KCalSharedResource::commit(OSyncContext *ctx, OSyncChange *chg) 
    214103{ 
    215104        OSyncChangeType type = osync_change_get_changetype(chg); 
     
    228117                case OSYNC_CHANGE_TYPE_MODIFIED: { 
    229118                        KCal::ICalFormat format; 
     119         
     120                        OSyncData *odata = osync_change_get_data(chg); 
     121 
     122                        char *databuf; 
     123                        size_t databuf_size;  
     124                        osync_data_get_data(odata, &databuf, &databuf_size); 
    230125 
    231126                        /* First, parse to a temporary calendar, because 
     
    234129 
    235130                        KCal::CalendarLocal cal(QString::fromLatin1( "UTC" )); 
    236                         QString data = QString::fromUtf8(osync_change_get_data(chg), osync_change_get_datasize(chg)); 
     131                        QString data = QString::fromUtf8(databuf, databuf_size); 
    237132                        if (!format.fromString(&cal, data)) { 
    238133                                osync_context_report_error(ctx, OSYNC_ERROR_CONVERT, "Couldn't import calendar data"); 
     
    240135                        } 
    241136 
    242                         /*FIXME: The event/to-do will be overwritten. But I can't differentiate 
    243                                 * between a field being removed and a missing field because 
    244                                 * the other device don't support them, because OpenSync currently 
    245                                 * doesn't have support for it. Yes, it is risky, but unfortunately 
    246                                 * CalendarResources don't have support for changing an event 
    247                                 * from vcard data, and not adding it. 
    248                                 */ 
    249137                        KCal::Incidence *oldevt = calendar->incidence(osync_change_get_uid(chg)); 
    250138                        if (oldevt) 
     
    261149                                        e->setUid(osync_change_get_uid(chg)); 
    262150 
    263 //                            osync_debug("kcal", 3, "Writing incidence: uid: %s, summary: %s", 
    264                                                 (const char*)e->uid().local8Bit(), (const char*)e->summary().local8Bit()); 
     151/*                            osync_debug("kcal", 3, "Writing incidence: uid: %s, summary: %s", 
     152                                                (const char*)e->uid().local8Bit(), (const char*)e->summary().local8Bit()); */ 
    265153 
    266154                                QString c_uid = e->uid().utf8(); 
     
    281169} 
    282170 
    283 bool KCalDataSource::event_access(OSyncContext *ctx, OSyncChange *chg) 
     171/** Report a list of calendar incidences (events or to-dos), with the 
     172 * right objtype and objformat. 
     173 * 
     174 * This function exists because the logic for converting the events or to-dos 
     175 * is the same, only the objtype and format is different. 
     176 */ 
     177bool KCalSharedResource::report_incidence(OSyncDataSource *dsobj, OSyncPluginInfo *info, OSyncContext *ctx, KCal::Incidence *e, OSyncObjFormat *objformat) 
     178
     179        /* Build a local calendar for the incidence data */ 
     180        KCal::CalendarLocal cal(calendar->timeZoneId()); 
     181//      osync_debug("kcal", 3, "timezoneid: %s\n", (const char*)cal.timeZoneId().local8Bit()); 
     182        cal.addIncidence(e->clone()); 
     183 
     184        /* Convert the data to vcalendar */ 
     185        KCal::ICalFormat format; 
     186        QString data = format.toString(&cal); 
     187 
     188        return dsobj->report_change(info, ctx, e->uid(), data, calc_hash(e), objformat); 
     189
     190 
     191bool KCalSharedResource::get_event_changes(OSyncDataSource *dsobj, OSyncPluginInfo *info, OSyncContext *ctx) 
     192
     193        OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env(info); 
     194        OSyncObjFormat *objformat = osync_format_env_find_objformat(formatenv, "vevent20"); 
     195         
     196        KCal::Event::List events = calendar->events(); 
     197//      osync_debug("kcal", 3, "Number of events: %d", events.size()); 
     198 
     199        for (KCal::Event::List::ConstIterator i = events.begin(); i != events.end(); i++) { 
     200 
     201                /* Skip entries from birthday resource. This is just a workaround. 
     202                 * patch by rhuitl 
     203                 * FIXME: todo: add a list of resources to kdepim-sync.conf 
     204                 */ 
     205                if ( (*i)->uid().contains("KABC_Birthday") || (*i)->uid().contains("KABC_Anniversary") ) 
     206                        continue; 
     207 
     208                if (!report_incidence(dsobj, info, ctx, *i, objformat)) 
     209                        return false; 
     210        } 
     211 
     212        return true; 
     213
     214 
     215bool KCalSharedResource::get_todo_changes(OSyncDataSource *dsobj, OSyncPluginInfo *info, OSyncContext *ctx) 
     216
     217        OSyncFormatEnv *formatenv = osync_plugin_info_get_format_env(info); 
     218        OSyncObjFormat *objformat = osync_format_env_find_objformat(formatenv, "vtodo20"); 
     219         
     220        KCal::Todo::List todos = calendar->todos(); 
     221 
     222//      osync_debug("kcal", 3, "Number of to-dos: %d", todos.size()); 
     223 
     224        for (KCal::Todo::List::ConstIterator i = todos.begin(); i != todos.end(); i++) { 
     225//              osync_debug("kcal", 3, "%p: doesFloat: %d", *i, (*i)->doesFloat()); 
     226                if (!report_incidence(dsobj, info, ctx, *i, objformat)) 
     227                        return false; 
     228        } 
     229 
     230        return true; 
     231
     232 
     233bool KCalEventDataSource::initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) 
     234
     235        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __PRETTY_FUNCTION__, plugin, info); 
     236 
     237        if (!OSyncDataSource::initialize(plugin, info, error)) { 
     238                osync_trace(TRACE_EXIT_ERROR, "%s", __PRETTY_FUNCTION__); 
     239                return false; 
     240        } 
     241 
     242        osync_objtype_sink_add_objformat(sink, "vevent20"); 
     243 
     244        osync_trace(TRACE_EXIT, "%s", __PRETTY_FUNCTION__); 
     245        return true; 
     246
     247 
     248bool KCalTodoDataSource::initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) 
     249
     250        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __PRETTY_FUNCTION__, plugin, info); 
     251 
     252        if (!OSyncDataSource::initialize(plugin, info, error)) { 
     253                osync_trace(TRACE_EXIT_ERROR, "%s", __PRETTY_FUNCTION__); 
     254                return false; 
     255        } 
     256 
     257        osync_objtype_sink_add_objformat(sink, "vtodo20"); 
     258 
     259        osync_trace(TRACE_EXIT, "%s", __PRETTY_FUNCTION__); 
     260        return true; 
     261
     262 
     263void KCalEventDataSource::connect(OSyncPluginInfo *info, OSyncContext *ctx) 
     264
     265        if (!kcal->open(ctx)) 
     266                return; 
     267        OSyncDataSource::connect(info, ctx); 
     268
     269 
     270void KCalTodoDataSource::connect(OSyncPluginInfo *info, OSyncContext *ctx) 
     271
     272        if (kcal->open(ctx)) 
     273                OSyncDataSource::connect(info, ctx); 
     274
     275 
     276void KCalEventDataSource::disconnect(OSyncPluginInfo *, OSyncContext *ctx) 
     277
     278        if (kcal->close(ctx)) 
     279                osync_context_report_success(ctx); 
     280
     281 
     282void KCalTodoDataSource::disconnect(OSyncPluginInfo *, OSyncContext *ctx) 
     283
     284        if (kcal->close(ctx)) 
     285                osync_context_report_success(ctx); 
     286
     287 
     288void KCalEventDataSource::get_changes(OSyncPluginInfo *info, OSyncContext *ctx) 
     289
     290        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __PRETTY_FUNCTION__, info, ctx); 
     291 
     292        OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info); 
     293 
     294        if (osync_objtype_sink_get_slowsync(sink)) { 
     295                osync_trace(TRACE_INTERNAL, "Got slow-sync"); 
     296                osync_hashtable_reset(hashtable); 
     297        } 
     298 
     299        if (!kcal->get_event_changes(this, info, ctx)) { 
     300                osync_trace(TRACE_EXIT_ERROR, "%s: error in get_todo_changes", __PRETTY_FUNCTION__); 
     301                return; 
     302        } 
     303 
     304        if (!report_deleted(info, ctx)) { 
     305                osync_trace(TRACE_EXIT_ERROR, "%s", __PRETTY_FUNCTION__); 
     306                return; 
     307        } 
     308 
     309        osync_context_report_success(ctx); 
     310        osync_trace(TRACE_EXIT, "%s", __PRETTY_FUNCTION__); 
     311
     312 
     313void KCalTodoDataSource::get_changes(OSyncPluginInfo *info, OSyncContext *ctx) 
     314
     315        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __PRETTY_FUNCTION__, info, ctx); 
     316 
     317        OSyncObjTypeSink *sink = osync_plugin_info_get_sink(info); 
     318 
     319        if (osync_objtype_sink_get_slowsync(sink)) { 
     320                osync_trace(TRACE_INTERNAL, "Got slow-sync"); 
     321                osync_hashtable_reset(hashtable); 
     322        } 
     323 
     324        if (!kcal->get_todo_changes(this, info, ctx)) { 
     325                osync_trace(TRACE_EXIT_ERROR, "%s: error in get_todo_changes", __PRETTY_FUNCTION__); 
     326                return; 
     327        } 
     328 
     329        if (!report_deleted(info, ctx)) { 
     330                osync_trace(TRACE_EXIT_ERROR, "%s", __PRETTY_FUNCTION__); 
     331                return; 
     332        } 
     333 
     334        osync_context_report_success(ctx); 
     335        osync_trace(TRACE_EXIT, "%s", __PRETTY_FUNCTION__); 
     336
     337 
     338void KCalEventDataSource::commit(OSyncPluginInfo *, OSyncContext *ctx, OSyncChange *chg) 
    284339{ 
    285340        // We use the same function for events and to-do 
    286         if (!__access(ctx, chg)) 
    287                 return false; 
    288  
     341        if (!kcal->commit(ctx, chg)) 
     342                return; 
     343         
     344        osync_hashtable_update_hash(hashtable, osync_change_get_changetype(chg), osync_change_get_uid(chg), osync_change_get_hash(chg)); 
    289345        osync_context_report_success(ctx); 
    290         return true; 
    291 
    292  
    293 bool KCalDataSource::event_commit_change(OSyncContext *ctx, OSyncChange *chg) 
    294 
    295         // We use the same function for events and to-do 
    296         if ( !__access(ctx, chg) ) 
    297                return false; 
    298         osync_hashtable_update_hash(hashtable, chg); 
     346
     347 
     348void KCalTodoDataSource::commit(OSyncPluginInfo *, OSyncContext *ctx, OSyncChange *chg) 
     349
     350        // We use the same function for calendar and to-do 
     351        if (!kcal->commit(ctx, chg)) 
     352               return; 
     353         
     354        osync_hashtable_update_hash(hashtable, osync_change_get_changetype(chg), osync_change_get_uid(chg), osync_change_get_hash(chg)); 
    299355        osync_context_report_success(ctx); 
    300         return true; 
    301 
    302  
    303 bool KCalDataSource::todo_access(OSyncContext *ctx, OSyncChange *chg) 
    304 
    305         // We use the same function for calendar and to-do 
    306         if (!__access(ctx, chg)) 
    307                 return false; 
    308  
    309         osync_context_report_success(ctx); 
    310         return true; 
    311 
    312  
    313 bool KCalDataSource::todo_commit_change(OSyncContext *ctx, OSyncChange *chg) 
    314 
    315         // We use the same function for calendar and to-do 
    316         if ( !__access(ctx, chg) ) 
    317                 return false; 
    318         osync_hashtable_update_hash(hashtable, chg); 
    319         osync_context_report_success(ctx); 
    320         return true; 
    321 
     356
  • plugins/kdepim/src/kcal.h

    r1620 r2293  
    2121*************************************************************************/ 
    2222/** 
    23  * @autor Eduardo Pereira Habkost <ehabkost@conectiva.com.br> 
     23 * @author Eduardo Pereira Habkost <ehabkost@conectiva.com.br> 
     24 * @author Andrew Baumann <andrewb@cse.unsw.edu.au> 
    2425 */ 
    2526 
     
    3132 
    3233#include "osyncbase.h" 
     34#include "datasource.h" 
    3335 
    34 /*FIXME: maybe create a parent abstract class for all 
    35  * KDE Data sources/sinks: OSyncDataSourceBase 
    36  */ 
    37 class KCalDataSource 
     36class KCalSharedResource 
    3837{ 
    3938        private: 
    4039                KCal::CalendarResources *calendar; 
     40                int refcount; 
     41         
     42                bool report_incidence(OSyncDataSource *dsobj, OSyncPluginInfo *info, OSyncContext *ctx, KCal::Incidence *e, OSyncObjFormat *objformat); 
     43         
     44        public: 
     45                KCalSharedResource() {calendar = NULL; refcount = 0;}; 
     46                bool open(OSyncContext *ctx); 
     47                bool close(OSyncContext *ctx); 
     48                bool get_event_changes(OSyncDataSource *dsobj, OSyncPluginInfo *info, OSyncContext *ctx); 
     49                bool get_todo_changes(OSyncDataSource *dsobj, OSyncPluginInfo *info, OSyncContext *ctx); 
     50                bool commit(OSyncContext *ctx, OSyncChange *chg); 
     51}; 
    4152 
    42                 OSyncHashTable *hashtable; 
    43                 OSyncMember *member; 
     53class KCalEventDataSource : public OSyncDataSource 
     54
     55        private: 
     56                KCalSharedResource *kcal; 
     57         
     58        public: 
     59                KCalEventDataSource(KCalSharedResource *kcal) : OSyncDataSource("event"), kcal(kcal) {}; 
     60                virtual ~KCalEventDataSource() {}; 
    4461 
    45                 /** access() method, used by commit() and access() 
    46                  * 
    47                  * Returns true on succes, but don't send success reporting 
    48                  * to context, because the caller may need to do more 
    49                  * operations 
    50                  */ 
    51                 bool __access(OSyncContext *ctx, OSyncChange *chg); 
    52                 bool report_incidence(OSyncContext *ctx, KCal::Incidence *e, 
    53                                       const char *objtype, const char *objformat); 
     62                bool initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error); 
     63                virtual void connect(OSyncPluginInfo *info, OSyncContext *ctx); 
     64                virtual void disconnect(OSyncPluginInfo *info, OSyncContext *ctx); 
     65                virtual void get_changes(OSyncPluginInfo *info, OSyncContext *ctx); 
     66                virtual void commit(OSyncPluginInfo *info, OSyncContext *ctx, OSyncChange *chg); 
     67}; 
     68 
     69class KCalTodoDataSource : public OSyncDataSource 
     70
     71        private: 
     72                KCalSharedResource *kcal; 
     73         
    5474        public: 
    55                 KCalDataSource(OSyncMember *member, OSyncHashTable *hashtable); 
     75                KCalTodoDataSource(KCalSharedResource *kcal) : OSyncDataSource("todo"), kcal(kcal) {}; 
     76                virtual ~KCalTodoDataSource() {}; 
    5677 
    57                 /** connect() method 
    58                  * 
    59                  * On success, returns true, but doesn't call osync_context_report_success() 
    60                  * On error, returns false, after calling osync_context_report_error() 
    61                  */ 
    62                 bool connect(OSyncContext *ctx); 
    63  
    64                 /** disconnect() method 
    65               &