qof-datebook.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *            qof-datebook.c
00003  *
00004  *  Thu Oct 21 15:38:39 2004
00005  *  Copyright  2004-2005  Neil Williams
00006  *  linux@codehelp.co.uk
00007  ****************************************************************************/
00008 /*
00009  *  This program is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  This program is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with this program; if not, write to the Free Software
00021  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00022  */
00030 #define _GNU_SOURCE
00031 #include "config.h"
00032 #include <glib.h>
00033 #include <glib/gprintf.h>
00034 #include <qof.h>
00035 #include <stdlib.h>
00036 #include "pi-datebook.h"
00037 #include "qof-main.h"
00038 #include "pilot-qof.h"
00039 #include "qof-datebook.h"
00040 
00041 static QofLogModule log_module = PQ_MOD_PILOT;
00042 
00043 #define DATEBOOK_VERSION datebook_v1
00044 #define DATEBOOK_EVENT        "untimed_event"
00045 #define DATEBOOK_BEGIN        "start_time"
00046 #define DATEBOOK_END          "end_time"
00047 #define DATEBOOK_ALARM        "use_alarm"
00048 #define DATEBOOK_ADVANCE      "alarm_advance"
00049 #define DATEBOOK_ADV_UNIT     "advance_unit"
00050 #define DATEBOOK_REPEAT_TYPE  "repeat_type"
00051 
00055 #define DATEBOOK_REPEAT_FOREVER    "repeat_forever"
00056 #define DATEBOOK_REPEAT_END        "repeat_end"
00057 #define DATEBOOK_REPEAT_FREQUENCY  "repeat_frequency"
00058 #define DATEBOOK_REPEAT_DAY        "repeat_day"
00059 #define DATEBOOK_REPEAT_WEEK_START "repeat_week_start"
00060 #define DATEBOOK_EXCEPTIONS        "exception_count"
00061 #define DATEBOOK_EXCEPTION         "exception_list"
00062 #define DATEBOOK_NOTE              "note"
00063 #define DATEBOOK_CATEGORY          "category"
00064 #define DATEBOOK_KVP_PATH          "datebook/exceptions"
00065 
00067 typedef struct
00068 {
00069     QofInstance inst;
00070     Appointment_t wrap;         //0.12
00071     gchar *category;
00072     gboolean repeater;   
00083 } QofDateBook;
00084 
00099 #define ENUM_REPEAT_LIST(_) \
00100     _(repeatNone,) \
00101     _(repeatDaily,) \
00102     _(repeatWeekly,) \
00103     _(repeatMonthlyByDay,) \
00104     _(repeatMonthlyByDate,) \
00105     _(repeatYearly,)
00106 
00107 AS_STRING_DEC_NON_TYPEDEF (repeatTypes, ENUM_REPEAT_LIST)
00108 FROM_STRING_DEC_NON_TYPEDEF (repeatTypes, ENUM_REPEAT_LIST)
00110 #define ENUM_ALARM_UNIT(_) \
00111     _(advMinutes,) _(advHours,) _(advDays,)
00112     AS_STRING_DEC_NON_TYPEDEF (alarmTypes, ENUM_ALARM_UNIT)
00113 FROM_STRING_DEC_NON_TYPEDEF (alarmTypes, ENUM_ALARM_UNIT)
00114 
00117 #define ENUM_MONTH_DAYQ(_) \
00118     _(dom1stSun,) _(dom1stMon,) _(dom1stTue,) _(dom1stWen,) _(dom1stThu,) \
00119     _(dom1stFri,) _(dom1stSat,) _(dom2ndSun,) _(dom2ndMon,) _(dom2ndTue,) \
00120     _(dom2ndWen,) _(dom2ndThu,) _(dom2ndFri,) _(dom2ndSat,) _(dom3rdSun,) \
00121     _(dom3rdMon,) _(dom3rdTue,) _(dom3rdWen,) _(dom3rdThu,) _(dom3rdFri,) \
00122     _(dom3rdSat,) _(dom4thSun,) _(dom4thMon,) _(dom4thTue,) _(dom4thWen,) \
00123     _(dom4thThu,) _(dom4thFri,) _(dom4thSat,) \
00124     _(domLastSun,) _(domLastMon,) _(domLastTue,) _(domLastWen,) \
00125     _(domLastThu,) _(domLastFri,) _(domLastSat,)
00126 AS_STRING_DEC_NON_TYPEDEF (DayOfMonthType, ENUM_MONTH_DAYQ)
00127 FROM_STRING_DEC_NON_TYPEDEF (DayOfMonthType, ENUM_MONTH_DAYQ)
00128 AS_STRING_FUNC_NON_TYPEDEF (repeatTypes, ENUM_REPEAT_LIST)
00129 FROM_STRING_FUNC_NON_TYPEDEF (repeatTypes, ENUM_REPEAT_LIST)
00130 AS_STRING_FUNC_NON_TYPEDEF (DayOfMonthType, ENUM_MONTH_DAYQ)
00131 FROM_STRING_FUNC_NON_TYPEDEF (DayOfMonthType, ENUM_MONTH_DAYQ)
00132 AS_STRING_FUNC_NON_TYPEDEF (alarmTypes, ENUM_ALARM_UNIT)
00133 FROM_STRING_FUNC_NON_TYPEDEF (alarmTypes, ENUM_ALARM_UNIT)
00140 static QofDateBook *
00141 datebook_create (QofBook * book)
00142 {
00143     Appointment_t *qd;
00144     QofDateBook *obj;
00145     QofCollection *coll;
00146     GList *all;
00147 
00148     obj = g_new0 (QofDateBook, 1);
00149     qof_instance_init (&obj->inst, PILOT_LINK_QOF_DATEBOOK, book);
00150     coll = qof_book_get_collection (book, PILOT_LINK_QOF_DATEBOOK);
00151     all = qof_collection_get_data (coll);
00152     all = g_list_prepend (all, obj);
00153     qof_collection_set_data (coll, all);
00154     qd = &obj->wrap;
00155     obj->repeater = FALSE;
00157     qd->exception = NULL;
00158     return obj;
00159 }
00160 
00161 static gboolean
00162 datebook_getEvent (QofDateBook * d)
00163 {
00164     Appointment_t *qd;
00165 
00166     g_return_val_if_fail (d != NULL, -1);
00167     qd = &d->wrap;
00168     return (qd->event) ? TRUE : FALSE;
00169 }
00170 
00171 static QofTime *
00172 datebook_getBegin (QofDateBook * d)
00173 {
00174     Appointment_t *qd;
00175     QofTime *qt;
00176 
00177     g_return_val_if_fail (d != NULL, NULL);
00178     qd = &d->wrap;
00179     qt = qof_time_from_tm (&qd->begin, 0);
00180     return qt;
00181 }
00182 
00183 static QofTime *
00184 datebook_getEnd (QofDateBook * d)
00185 {
00186     Appointment_t *qd;
00187     QofTime *qt;
00188 
00189     g_return_val_if_fail (d != NULL, NULL);
00190     qd = &d->wrap;
00191     qt = qof_time_from_tm (&qd->end, 0);
00192     return qt;
00193 }
00194 
00195 static gboolean
00196 datebook_getAlarm (QofDateBook * d)
00197 {
00198     Appointment_t *qd;
00199 
00200     g_return_val_if_fail (d != NULL, FALSE);
00201     qd = &d->wrap;
00202     return (qd->alarm == 1) ? TRUE : FALSE;
00203 }
00204 
00205 static gint
00206 datebook_getAdvance (QofDateBook * d)
00207 {
00208     Appointment_t *qd;
00209 
00210     g_return_val_if_fail (d != NULL, -1);
00211     qd = &d->wrap;
00212     return (datebook_getAlarm (d)) ? qd->advance : 0;
00213 }
00214 
00219 static const gchar *
00220 datebook_getAdvanceUnit (QofDateBook * d)
00221 {
00222     Appointment_t *qd;
00223     gchar *unit;
00224 
00225     g_return_val_if_fail (d != NULL, NULL);
00226     qd = &d->wrap;
00227     if (datebook_getAlarm (d) == FALSE)
00228         return NULL;
00229     unit = g_strdup (alarmTypesasString (qd->advanceUnits));
00230     return unit;
00231 }
00232 
00233 static const gchar *
00234 datebook_getRepeatType (QofDateBook * d)
00235 {
00236     Appointment_t *qd;
00237     gchar *type_label;
00238 
00239     g_return_val_if_fail (d != NULL, NULL);
00240     qd = &d->wrap;
00241     type_label = g_strdup (repeatTypesasString (qd->repeatType));
00242     return type_label;
00243 }
00244 
00245 static gboolean
00246 datebook_getRepeatForever (QofDateBook * d)
00247 {
00248     Appointment_t *qd;
00249 
00250     g_return_val_if_fail (d != NULL, -1);
00251     qd = &d->wrap;
00252     return (qd->repeatForever == 1) ? TRUE : FALSE;
00253 }
00254 
00255 static QofTime *
00256 datebook_getRepeatEnd (QofDateBook * d)
00257 {
00258     Appointment_t *qd;
00259 
00260     g_return_val_if_fail (d != NULL, NULL);
00261     qd = &d->wrap;
00262     if (qd->repeatType == repeatNone)
00263         qd->repeatEnd = qd->end;
00264     return qof_time_from_tm (&qd->repeatEnd, 0);
00265 }
00266 
00273 static gint
00274 datebook_getRepeatFrequency (QofDateBook * d)
00275 {
00276     Appointment_t *qd;
00277 
00278     g_return_val_if_fail (d != NULL, -1);
00279     qd = &d->wrap;
00280     return qd->repeatFrequency;
00281 }
00282 
00283 static const gchar *
00284 datebook_getRepeatDay (QofDateBook * d)
00285 {
00286     Appointment_t *qd;
00287     enum DayOfMonthType type;
00288     gchar *g;
00289 
00290     g_return_val_if_fail (d != NULL, NULL);
00291     qd = &d->wrap;
00292     if (qd->repeatType == repeatNone)
00293         return NULL;
00294     type = qd->repeatDay;
00295     g = g_strdup (DayOfMonthTypeasString (type));
00296     return g;
00297 }
00298 
00333 static QofDateFormat df = 0;
00334 
00335 static gchar *
00336 datebook_getRepeatWeekStart (QofDateBook * d)
00337 {
00338     Appointment_t *qd;
00339     QofTime *qt;
00340     QofDate *qdate;
00341     gboolean result;
00342     gchar *retval;
00343 
00344     g_return_val_if_fail (d != NULL, NULL);
00345     qd = &d->wrap;
00346     if (qd->repeatType == repeatNone)
00347         return NULL;
00348     qt = qof_time_get_current ();
00349     if (df == 0)
00350     {
00351         result = qof_date_format_add ("%A", &df);
00352         if (!result)
00353         {
00354             PERR (" failed to fetch the locale format");
00355             return NULL;
00356         }
00357     }
00358     qdate = qof_date_from_qtime (qt);
00359     if (qdate->qd_mday < qdate->qd_wday)
00360         qdate->qd_mday += 7;
00361     qdate->qd_mday -= (qdate->qd_wday + qd->repeatWeekstart);
00362     qof_date_valid (qdate);
00363     qof_time_free (qt);
00364     retval = qof_date_print (qdate, df);
00365     qof_date_free (qdate);
00366     return retval;
00367 }
00368 
00369 static gint
00370 datebook_getExceptions (QofDateBook * d)
00371 {
00372     Appointment_t *qd;
00373 
00374     g_return_val_if_fail (d != NULL, -1);
00375     qd = &d->wrap;
00376     return qd->exceptions;
00377 }
00378 
00379 static gchar *
00380 datebook_getDescription (QofDateBook * d)
00381 {
00382     Appointment_t *qd;
00383 
00384     g_return_val_if_fail (d != NULL, NULL);
00385     qd = &d->wrap;
00386     return qd->description;
00387 }
00388 
00389 static gchar *
00390 datebook_getNote (QofDateBook * d)
00391 {
00392     Appointment_t *qd;
00393 
00394     g_return_val_if_fail (d != NULL, NULL);
00395     qd = &d->wrap;
00396     return qd->note;
00397 }
00398 
00399 static gchar *
00400 datebook_getCategory (QofDateBook * d)
00401 {
00402     g_return_val_if_fail (d != NULL, NULL);
00403     return d->category;
00404 }
00405 
00406 static double
00407 datebook_getDuration (QofDateBook * d)
00408 {
00409     QofTime *qt_diff, *qt_start, *qt_end;
00410     gdouble retval;
00411 
00412     g_return_val_if_fail (d, 0);
00413     qt_start = datebook_getBegin (d);
00414     qt_end = datebook_getEnd (d);
00415     qt_diff = qof_time_diff (qt_end, qt_start);
00416     retval = qof_time_get_secs (qt_diff) / 3600;
00417     qof_time_free (qt_diff);
00418     qof_time_free (qt_start);
00419     qof_time_free (qt_end);
00420     return retval;
00421 }
00422 
00423 static gboolean
00424 datebook_check_repeater (QofDateBook * d)
00425 {
00426     g_return_val_if_fail (d, FALSE);
00427     return d->repeater;
00428 }
00429 
00430 static void
00431 datebook_set_repeater (QofDateBook * d, gboolean e)
00432 {
00433     g_return_if_fail (d != NULL);
00434     d->repeater = e;
00435 }
00436 
00437 static void
00438 datebook_setEvent (QofDateBook * d, gboolean e)
00439 {
00440     Appointment_t *qd;
00441 
00442     g_return_if_fail (d != NULL);
00443     qd = &d->wrap;
00444     qd->event = 0;
00445     if (e == TRUE)
00446         qd->event = 1;
00447 }
00448 
00449 static void
00450 datebook_setBegin (QofDateBook * d, QofTime *qt)
00451 {
00452     Appointment_t *qd;
00453     gboolean result;
00454     QofDate *qdate;
00455 
00456     g_return_if_fail (d != NULL);
00457     qd = &d->wrap;
00458     qdate = qof_date_from_qtime (qt);
00459     result = qof_date_to_struct_tm (qdate, &qd->begin, 0);
00460     if(!result)
00461         PERR (" Date too large for begin.");
00462     qof_date_free (qdate);
00463 }
00464 
00465 static void
00466 datebook_setEnd (QofDateBook * d, QofTime *qt)
00467 {
00468     Appointment_t *qd;
00469     gboolean result;
00470     QofDate *qdate;
00471 
00472     g_return_if_fail (d != NULL);
00473     qd = &d->wrap;
00474     qdate = qof_date_from_qtime (qt);
00475     result = qof_date_to_struct_tm (qdate, &qd->end, 0);
00476     if(!result)
00477         PERR (" Date too large for end.");
00478     qof_date_free (qdate);
00479 }
00480 
00481 static void
00482 datebook_setAlarm (QofDateBook * d, gboolean e)
00483 {
00484     Appointment_t *qd;
00485 
00486     g_return_if_fail (d != NULL);
00487     qd = &d->wrap;
00488     if (e)
00489         qd->alarm = 1;
00490 }
00491 
00492 static void
00493 datebook_setAdvance (QofDateBook * d, gint e)
00494 {
00495     Appointment_t *qd;
00496 
00497     g_return_if_fail (d != NULL);
00498     qd = &d->wrap;
00499     qd->advance = e;
00500 }
00501 
00502 static void
00503 datebook_setAdvanceUnit (QofDateBook * d, const gchar * e)
00504 {
00505     Appointment_t *qd;
00506     enum alarmTypes type;
00507 
00508     g_return_if_fail (d != NULL);
00509     if (e == NULL)
00510         return;
00511     qd = &d->wrap;
00512     alarmTypesfromString (e, &type);
00513     qd->advanceUnits = type;
00514 }
00515 
00520 static void
00521 datebook_setRepeatType (QofDateBook * d, const gchar * type_label)
00522 {
00523     Appointment_t *qd;
00524     enum repeatTypes type;
00525 
00526     g_return_if_fail (d != NULL);
00527     qd = &d->wrap;
00528     repeatTypesfromString (type_label, &type);
00529     qd->repeatType = type;
00530 }
00531 
00532 static void
00533 datebook_setRepeatForever (QofDateBook * d, gboolean e)
00534 {
00535     Appointment_t *qd;
00536 
00537     g_return_if_fail (d != NULL);
00538     qd = &d->wrap;
00539     if (e)
00540         qd->repeatForever = 1;
00541 }
00542 
00543 static void
00544 datebook_setRepeatEnd (QofDateBook * d, QofTime *qt)
00545 {
00546     Appointment_t *qd;
00547     gboolean result;
00548     QofDate *qdate;
00549 
00550     g_return_if_fail (d != NULL);
00551     qd = &d->wrap;
00552     qdate = qof_date_from_qtime (qt);
00553     result = qof_date_to_struct_tm (qdate, &qd->repeatEnd, 0);
00554     if(!result)
00555         PERR (" Date too large for repeatEnd.");
00556     qof_date_free (qdate);
00557 }
00558 
00559 static void
00560 datebook_setRepeatFrequency (QofDateBook * d, gint e)
00561 {
00562     Appointment_t *qd;
00563 
00564     g_return_if_fail (d != NULL);
00565     qd = &d->wrap;
00566     qd->repeatFrequency = e;
00567 }
00568 
00569 static void
00570 datebook_setRepeatDay (QofDateBook * d, const gchar * e)
00571 {
00572     Appointment_t *qd;
00573     enum DayOfMonthType type;
00574 
00575     g_return_if_fail (d != NULL);
00576     if (e == NULL)
00577         return;
00578     qd = &d->wrap;
00579     DayOfMonthTypefromString (e, &type);
00580     qd->repeatDay = type;
00581 }
00582 
00590 static void
00591 datebook_setRepeatWeekStart (QofDateBook * d, gchar * e)
00592 {
00593     gchar day[MAX_DATE_LENGTH];
00594     Appointment_t *qd;
00595     time_t local;
00596     struct tm *local_tm;
00597     gint i, diff;
00598     gboolean found;
00599 
00600     g_return_if_fail (d != NULL);
00601     qd = &d->wrap;
00602     diff = 0;
00603     found = FALSE;
00604     local = time (NULL);
00605     local_tm = localtime (&local);
00606     if (local_tm->tm_wday <= 7)
00607         diff = 1;
00608     else
00609         diff = -1;
00610     for (i = 0; i < 7; i++)
00611     {
00612         strftime (day, MAX_DATE_LENGTH, "%A", local_tm);
00613         if (0 == safe_strcmp (e, day))
00614         {
00615             found = TRUE;
00616             break;
00617         }
00618         local_tm->tm_mday += diff;
00619     }
00620     if (!found)
00621         i = 0;
00622     qd->repeatWeekstart = i;
00623 }
00624 
00625 static void
00626 datebook_setExceptions (QofDateBook * d, gint e)
00627 {
00628     Appointment_t *qd;
00629 
00630     g_return_if_fail (d != NULL);
00631     qd = &d->wrap;
00632     qd->exceptions = e;
00633 }
00634 
00635 static void
00636 datebook_setDescription (QofDateBook * d, gchar * h)
00637 {
00638     Appointment_t *qd;
00639 
00640     g_return_if_fail (d);
00641     qd = &d->wrap;
00642     qd->description = g_strdup (qof_main_make_utf8 (h));
00643 }
00644 
00645 static void
00646 datebook_setNote (QofDateBook * d, gchar * h)
00647 {
00648     Appointment_t *qd;
00649 
00650     g_return_if_fail (d);
00651     qd = &d->wrap;
00652     if (!h)
00653         return;
00654     qd->note = g_strdup (qof_main_make_utf8 (h));
00655 }
00656 
00657 static void
00658 datebook_setCategory (QofDateBook * d, gchar * n)
00659 {
00660     g_return_if_fail (d != NULL);
00661     d->category = g_strdup (qof_main_make_utf8 (n));
00662 }
00663 
00669 static gint
00670 datebook_unpack (QofEntity * ent, gpointer user_data)
00671 {
00672     pi_buffer_t *pi_buf;
00673     Appointment_t *qa;
00674     QofDateBook *obj, *clone;
00675     QofInstance *inst;
00676     QofBook *book;
00677     KvpFrame *inst_frame;
00678     QofTime *qt, *qt_increment, *qt_end, *qt_repeat;
00679     PQContext *context;
00680     gint size, i, day_interval, month_interval;
00681 
00682     context = (PQContext *) user_data;
00683     day_interval = 0;
00684     month_interval = 0;
00685     g_return_val_if_fail (context != NULL, -1);
00686     g_return_val_if_fail (ent != NULL, -1);
00687     obj = (QofDateBook *) ent;
00688     inst = (QofInstance *) ent;
00689     inst_frame = qof_instance_get_slots (inst);
00690     qa = &obj->wrap;
00691     pi_buf = (pi_buffer_t *) context->pi_buf;
00692     size = 0;
00693     size = unpack_Appointment (qa, pi_buf, DATEBOOK_VERSION);   // 0.12
00694     datebook_setCategory (obj, context->names[context->ent_category]);
00695     /* Use <= and handle zero if < omits last entry (&623) */
00696     for (i = 0; i < qa->exceptions; i++)
00697     {
00698         gchar *extend;
00699 
00700         extend = NULL;
00701         DEBUG (" exceptions=%d", qa->exceptions);
00702         qt = qof_time_from_tm (&qa->exception[i], 0);
00703         extend = g_strdup_printf ("%s/%d", DATEBOOK_KVP_PATH, i + 1);
00704         kvp_frame_set_time (inst_frame, extend, qt);
00705         inst->kvp_data = inst_frame;
00706         g_free (extend);
00707     }
00708     if (qa->repeatType == repeatNone)
00709         qa->repeatEnd = qa->end;
00710     /* set a marker for the interval. Do the iteration once, outside the switch. */
00711     switch (qa->repeatType)
00712     {
00713     case repeatNone:
00714         {
00715             day_interval = 0;
00716             month_interval = 0;
00717             break;
00718         }
00719     case repeatDaily:
00720         {
00721             day_interval = 1;
00722             month_interval = 0;
00723             break;
00724         }
00725     case repeatWeekly:
00726         {
00727             day_interval = 7;
00728             month_interval = 0;
00729             break;
00730         }
00731     case repeatMonthlyByDay:
00732     case repeatMonthlyByDate:
00733         {
00734             day_interval = 0;
00735             month_interval = 1;
00736             break;
00737         }
00738     case repeatYearly:
00739         {
00740             day_interval = 0;
00741             month_interval = 12;
00742             break;
00743         }
00744     default:
00745         {
00746             PERR (" unsupported repeatType=%d", qa->repeatType);
00747         }
00748     }
00749     if (day_interval == 0 && month_interval == 0)
00750         return size;
00751     /* Now create a repeater in the SAME book. */
00752     qt = datebook_getBegin (obj);
00753     qt_end = datebook_getEnd (obj);
00754     if (qa->repeatForever == 0)
00755     {
00756         qt_repeat = datebook_getRepeatEnd (obj);
00757     }
00758     else
00759     {
00760         QofDate *qd;
00761         /*  if qa->repeatForever == 1 (true), calculate year and a day from
00762            start_time. qof_date_add_months(12)
00763            qof_date_add_days(1). Store for use as repeatEnd
00764          */
00765         DEBUG (" qa->repeatForever == 1");
00766         qt_repeat = qt;
00767         qd = qof_date_from_qtime (qt_repeat);
00768         qof_date_addmonths (qd, 12, FALSE);
00769         qof_date_adddays (qd, 1);
00770         qof_date_free (qd);
00771     }
00772     qt_increment = qt;
00773     /*  qa->exception is an array of struct tm* qa->exceptions long. */
00774     /* while datebook_getBegin is less (earlier) than repeat_end */
00775     while (qof_time_cmp (qt_increment, qt_repeat) < 0)
00776     {
00777         gboolean skip;
00778 
00779         skip = FALSE;
00780         if (day_interval)
00781         {
00782             QofDate *qd;
00783             qd = qof_date_from_qtime (qt_increment);
00784             qof_date_adddays (qd, day_interval);
00785             qt_increment = qof_date_to_qtime (qd);
00786             qof_date_free (qd);
00787             qd = qof_date_from_qtime (qt_end);
00788             qof_date_adddays (qd, day_interval);
00789             qt_end = qof_date_to_qtime (qd);
00790             qof_date_free (qd);
00791         }
00792         if (month_interval)
00793         {
00794             QofDate *qd;
00795             qd = qof_date_from_qtime (qt_increment);
00796             qof_date_addmonths (qd, month_interval, FALSE);
00797             qt_increment = qof_date_to_qtime (qd);
00798             qof_date_free (qd);
00799             qd = qof_date_from_qtime (qt_end);
00800             qof_date_addmonths (qd, month_interval, FALSE);
00801             qt_end = qof_date_to_qtime (qd);
00802             qof_date_free (qd);
00803         }
00804         for (i = 0; i < qa->exceptions; i++)
00805         {
00806             QofDate *qd;
00807 
00808             qd = qof_date_from_qtime(qt_increment);
00809             if ((qd->qd_year == qa->exception[i].tm_year) &&
00810                 (qd->qd_mday == qa->exception[i].tm_mday) &&
00811                 (qd->qd_mon == qa->exception[i].tm_mon))
00812             {
00813                 /* exclude */
00814                 skip = TRUE;
00815             }
00816         }
00817         /* create the repeater */
00818         if (!skip)
00819         {
00820             book = inst->book;
00821             clone = datebook_create (book);
00822             clone->repeater = TRUE;
00823             /* clone the main parts of the event */
00824             datebook_setEvent (clone, datebook_getEvent (obj));
00825             datebook_setAlarm (clone, datebook_getAlarm (obj));
00826             datebook_setAdvance (clone, datebook_getAdvance (obj));
00827             datebook_setAdvanceUnit (clone, datebook_getAdvanceUnit (obj));
00828             datebook_setDescription (clone, datebook_getDescription (obj));
00829             datebook_setNote (clone, datebook_getNote (obj));
00830             datebook_setCategory (clone, datebook_getCategory (obj));
00831             /* the clone does not repeat */
00832             datebook_setExceptions (clone, 0);
00833             datebook_setRepeatEnd (clone, qt_end);
00834             datebook_setRepeatForever (clone, FALSE);
00835             datebook_setRepeatType (clone,
00836                 repeatTypesasString (repeatNone));
00837             datebook_setBegin (clone, qt_increment);
00838             datebook_setEnd (clone, qt_end);
00839         }
00840     }
00841     return size;
00842 }
00843 
00845 static gint
00846 datebook_pack (QofEntity * ent, gpointer user_data)
00847 {
00848     PQContext *context;
00849     Appointment_t *qa;
00850     QofDateBook *obj;
00851     QofTime *qt;
00852     KvpFrame *frame;
00853     gint size, i;
00854     gchar *path;
00855 
00856     size = 0;
00857     i = 1;
00858     context = (PQContext *) user_data;
00859     g_return_val_if_fail ((context || ent), -1);
00860     ENTER (" ");
00861     obj = (QofDateBook *) ent;
00862     if (obj->repeater == TRUE)
00863         return 0;
00864     qa = &obj->wrap;
00865     size = pack_Appointment (qa, context->pi_buf, DATEBOOK_VERSION);    // 0.12
00866     /* pack slots into exceptions */
00867     frame = qof_instance_get_slots ((QofInstance *) ent);
00868     if (frame)
00869     {
00870         path = g_strdup_printf ("%s/%d", DATEBOOK_KVP_PATH, i);
00871         while (kvp_frame_get_value (frame, path))
00872         {
00873             qt = kvp_frame_get_time (frame, path);
00874             if (qt)
00875             {
00876                 QofDate *qd;
00877                 gboolean result;
00878                 qd = qof_date_from_qtime (qt);
00879                 result = qof_date_to_struct_tm (qd,
00880                     &qa->exception[i], 0);
00881                 if(!result)
00882                     PERR (" failed to set exception time: "
00883                     "out of range");
00884             }
00885             g_free (path);
00886             i++;
00887             path = g_strdup_printf ("%s/%d", DATEBOOK_KVP_PATH, i);
00888         }
00889         g_free (path);
00890     }
00891     LEAVE (" ");
00892     return size;
00893 }
00894 
00901 static gint
00902 datebook_appinfo_unpack (QofEntity * ent, gpointer user_data)
00903 {
00904     AppointmentAppInfo_t app_db;
00905     PQContext *context;
00906     gint name_count;
00907 
00908     context = (PQContext *) user_data;
00909     g_return_val_if_fail (context != NULL, -1);
00910     ENTER (" ");
00911     unpack_AppointmentAppInfo (&app_db, context->app_buf->data,
00912         PQ_DEF_BUFSZ);
00913     for (name_count = 0; name_count < 16; name_count++)
00914     {
00915         g_sprintf (context->names[name_count], "%s",
00916             app_db.category.name[name_count]);
00917     }
00918     context->pi_cat = &app_db.category;
00919     LEAVE (" ");
00920     return 0;
00921 }
00922 
00924 static gint
00925 qof_datebook_free (QofEntity * ent, gpointer user_data)
00926 {
00927     Appointment_t *qd;
00928     QofDateBook *obj;
00929 
00930     g_return_val_if_fail (ent != NULL, -1);
00931     ENTER (" ");
00932     obj = (QofDateBook *) ent;
00933     qd = &obj->wrap;
00934     free_Appointment (qd);
00935     LEAVE (" ");
00936     return 0;
00937 }
00938 
00939 static const gchar *
00940 datebookPrintable (gpointer instance)
00941 {
00942     return datebook_getDescription ((QofDateBook *) instance);
00943 }
00944 
00945 static QofObject datebook_object_def = {
00946   interface_version:QOF_OBJECT_VERSION,
00947   e_type:PILOT_LINK_QOF_DATEBOOK,
00948   type_label:QOF_DATEBOOK_DESC,
00949   create:(gpointer) datebook_create,
00950   book_begin:NULL,
00951   book_end:NULL,
00952   is_dirty:qof_collection_is_dirty,
00953   mark_clean:qof_collection_mark_clean,
00954   foreach:qof_collection_foreach,
00955   printable:datebookPrintable,
00956   version_cmp:(gint (*)(gpointer, gpointer)) qof_instance_version_cmp,
00957 };
00958 
00959 static PQPack datebook_pack_def = {
00960   e_type:PILOT_LINK_QOF_DATEBOOK,
00961   pack_func:datebook_pack,
00962   unpack_func:datebook_unpack,
00963   free_pack_func:qof_datebook_free,
00964   palm_db_name:"DatebookDB",
00965   app_info_unpack:datebook_appinfo_unpack,
00966 };
00967 
00968 gboolean
00969 DateBookRegister (void)
00970 {
00971     static QofParam params[] = {
00972         {DATEBOOK_EVENT, QOF_TYPE_BOOLEAN,
00973                 (QofAccessFunc) datebook_getEvent,
00974             (QofSetterFunc) datebook_setEvent},
00975         {DATEBOOK_BEGIN, QOF_TYPE_TIME, (QofAccessFunc) datebook_getBegin,
00976             (QofSetterFunc) datebook_setBegin},
00977         {DATEBOOK_END, QOF_TYPE_TIME, (QofAccessFunc) datebook_getEnd,
00978             (QofSetterFunc) datebook_setEnd},
00979         {DATEBOOK_ALARM, QOF_TYPE_BOOLEAN,
00980                 (QofAccessFunc) datebook_getAlarm,
00981             (QofSetterFunc) datebook_setAlarm},
00982         {DATEBOOK_ADVANCE, QOF_TYPE_INT32,
00983                 (QofAccessFunc) datebook_getAdvance,
00984             (QofSetterFunc) datebook_setAdvance},
00985         {DATEBOOK_ADV_UNIT, QOF_TYPE_STRING,
00986                 (QofAccessFunc) datebook_getAdvanceUnit,
00987             (QofSetterFunc) datebook_setAdvanceUnit},
00988         {DATEBOOK_REPEAT_TYPE, QOF_TYPE_STRING,
00989                 (QofAccessFunc) datebook_getRepeatType,
00990             (QofSetterFunc) datebook_setRepeatType},
00991         {DATEBOOK_REPEAT_FOREVER, QOF_TYPE_BOOLEAN,
00992                 (QofAccessFunc) datebook_getRepeatForever,
00993             (QofSetterFunc) datebook_setRepeatForever},
00994         {DATEBOOK_REPEAT_END, QOF_TYPE_TIME,
00995                 (QofAccessFunc) datebook_getRepeatEnd,
00996             (QofSetterFunc) datebook_setRepeatEnd},
00997         {DATEBOOK_REPEAT_FREQUENCY, QOF_TYPE_INT32,
00998                 (QofAccessFunc) datebook_getRepeatFrequency,
00999             (QofSetterFunc) datebook_setRepeatFrequency},
01000         {DATEBOOK_REPEAT_DAY, QOF_TYPE_STRING,
01001                 (QofAccessFunc) datebook_getRepeatDay,
01002             (QofSetterFunc) datebook_setRepeatDay},
01003         {DATEBOOK_REPEAT_WEEK_START, QOF_TYPE_STRING,
01004                 (QofAccessFunc) datebook_getRepeatWeekStart,
01005             (QofSetterFunc) datebook_setRepeatWeekStart},
01006         {DATEBOOK_EXCEPTIONS, QOF_TYPE_INT32,
01007                 (QofAccessFunc) datebook_getExceptions,
01008             (QofSetterFunc) datebook_setExceptions},
01009         {DATEBOOK_DESCRIPTION, QOF_TYPE_STRING,
01010                 (QofAccessFunc) datebook_getDescription,
01011             (QofSetterFunc) datebook_setDescription},
01012         {DATEBOOK_CATEGORY, QOF_TYPE_STRING,
01013                 (QofAccessFunc) datebook_getCategory,
01014             (QofSetterFunc) datebook_setCategory},
01015         {DATEBOOK_REPEATER, QOF_TYPE_BOOLEAN,
01016                 (QofAccessFunc) datebook_check_repeater,
01017             (QofSetterFunc) datebook_set_repeater},
01018         {DATEBOOK_NOTE, QOF_TYPE_STRING, (QofAccessFunc) datebook_getNote,
01019             (QofSetterFunc) datebook_setNote},
01020         {DATEBOOK_DURATION, QOF_TYPE_DOUBLE,
01021                 (QofAccessFunc) datebook_getDuration, NULL},
01022         {DATEBOOK_EXCEPTION, QOF_TYPE_KVP,
01023                 (QofAccessFunc) qof_instance_get_slots, NULL},
01024         {QOF_PARAM_BOOK, QOF_ID_BOOK,
01025                 (QofAccessFunc) qof_instance_get_book, NULL},
01026         {QOF_PARAM_GUID, QOF_TYPE_GUID,
01027                 (QofAccessFunc) qof_instance_get_guid, NULL},
01028         {NULL},
01029     };
01030 
01031     qof_class_register (PILOT_LINK_QOF_DATEBOOK, NULL, params);
01032 
01033     pilot_qof_pack_register (&datebook_pack_def);
01034 
01035     return qof_object_register (&datebook_object_def);
01036 }
01037 

Generated on Tue Mar 6 00:08:09 2007 for pilot-qof by  doxygen 1.5.1