00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00029 #define _GNU_SOURCE
00030 #include "config.h"
00031 #include <glib.h>
00032 #include <glib/gprintf.h>
00033 #include <qof.h>
00034 #include <stdlib.h>
00035 #include "pi-datebook.h"
00036 #include "qof-main.h"
00037 #include "pilot-qof.h"
00038 #include "qof-datebook.h"
00039
00040 static QofLogModule log_module = PQ_MOD_PILOT;
00041
00043 typedef struct
00044 {
00045 QofInstance inst;
00046 Appointment_t wrap;
00047 gchar *category;
00048 gboolean repeater;
00059 } QofDateBook;
00060
00075 #define ENUM_REPEAT_LIST(_) \
00076 _(repeatNone,) \
00077 _(repeatDaily,) \
00078 _(repeatWeekly,) \
00079 _(repeatMonthlyByDay,) \
00080 _(repeatMonthlyByDate,) \
00081 _(repeatYearly,)
00082
00083 AS_STRING_DEC_NON_TYPEDEF (repeatTypes, ENUM_REPEAT_LIST)
00084 FROM_STRING_DEC_NON_TYPEDEF (repeatTypes, ENUM_REPEAT_LIST)
00086 #define ENUM_ALARM_UNIT(_) \
00087 _(advMinutes,) _(advHours,) _(advDays,)
00088 AS_STRING_DEC_NON_TYPEDEF (alarmTypes, ENUM_ALARM_UNIT)
00089 FROM_STRING_DEC_NON_TYPEDEF (alarmTypes, ENUM_ALARM_UNIT)
00090
00093 #define ENUM_MONTH_DAYQ(_) \
00094 _(dom1stSun,) _(dom1stMon,) _(dom1stTue,) _(dom1stWen,) _(dom1stThu,) \
00095 _(dom1stFri,) _(dom1stSat,) _(dom2ndSun,) _(dom2ndMon,) _(dom2ndTue,) \
00096 _(dom2ndWen,) _(dom2ndThu,) _(dom2ndFri,) _(dom2ndSat,) _(dom3rdSun,) \
00097 _(dom3rdMon,) _(dom3rdTue,) _(dom3rdWen,) _(dom3rdThu,) _(dom3rdFri,) \
00098 _(dom3rdSat,) _(dom4thSun,) _(dom4thMon,) _(dom4thTue,) _(dom4thWen,) \
00099 _(dom4thThu,) _(dom4thFri,) _(dom4thSat,) \
00100 _(domLastSun,) _(domLastMon,) _(domLastTue,) _(domLastWen,) \
00101 _(domLastThu,) _(domLastFri,) _(domLastSat,)
00102 AS_STRING_DEC_NON_TYPEDEF (DayOfMonthType, ENUM_MONTH_DAYQ)
00103 FROM_STRING_DEC_NON_TYPEDEF (DayOfMonthType, ENUM_MONTH_DAYQ)
00104 AS_STRING_FUNC_NON_TYPEDEF (repeatTypes, ENUM_REPEAT_LIST)
00105 FROM_STRING_FUNC_NON_TYPEDEF (repeatTypes, ENUM_REPEAT_LIST)
00106 AS_STRING_FUNC_NON_TYPEDEF (DayOfMonthType, ENUM_MONTH_DAYQ)
00107 FROM_STRING_FUNC_NON_TYPEDEF (DayOfMonthType, ENUM_MONTH_DAYQ)
00108 AS_STRING_FUNC_NON_TYPEDEF (alarmTypes, ENUM_ALARM_UNIT)
00109 FROM_STRING_FUNC_NON_TYPEDEF (alarmTypes, ENUM_ALARM_UNIT)
00116 static QofDateBook *
00117 datebook_create (QofBook * book)
00118 {
00119 Appointment_t *qd;
00120 QofDateBook *obj;
00121 QofCollection *coll;
00122 GList *all;
00123
00124 obj = g_new0 (QofDateBook, 1);
00125 qof_instance_init (&obj->inst, PILOT_LINK_QOF_DATEBOOK, book);
00126 coll = qof_book_get_collection (book, PILOT_LINK_QOF_DATEBOOK);
00127 all = qof_collection_get_data (coll);
00128 all = g_list_prepend (all, obj);
00129 qof_collection_set_data (coll, all);
00130 qd = &obj->wrap;
00131 obj->repeater = FALSE;
00133 qd->exception = NULL;
00134 return obj;
00135 }
00136
00137 Appointment_t * datebook_get_pilot (QofInstance * inst)
00138 {
00139 QofDateBook * d;
00140
00141 d = (QofDateBook *)inst;
00142 return &d->wrap;
00143 }
00144
00145 static gboolean
00146 datebook_getEvent (QofDateBook * d)
00147 {
00148 Appointment_t *qd;
00149
00150 g_return_val_if_fail (d != NULL, -1);
00151 qd = &d->wrap;
00152 return (qd->event) ? TRUE : FALSE;
00153 }
00154
00155 static QofTime *
00156 datebook_getBegin (QofDateBook * d)
00157 {
00158 Appointment_t *qd;
00159 QofTime *qt;
00160
00161 g_return_val_if_fail (d != NULL, NULL);
00162 qd = &d->wrap;
00163 qt = qof_time_from_tm (&qd->begin, 0);
00164 return qt;
00165 }
00166
00167 static QofTime *
00168 datebook_getEnd (QofDateBook * d)
00169 {
00170 Appointment_t *qd;
00171 QofTime *qt;
00172
00173 g_return_val_if_fail (d != NULL, NULL);
00174 qd = &d->wrap;
00175 qt = qof_time_from_tm (&qd->end, 0);
00176 return qt;
00177 }
00178
00179 static gboolean
00180 datebook_getAlarm (QofDateBook * d)
00181 {
00182 Appointment_t *qd;
00183
00184 g_return_val_if_fail (d != NULL, FALSE);
00185 qd = &d->wrap;
00186 return (qd->alarm == 1) ? TRUE : FALSE;
00187 }
00188
00189 static gint
00190 datebook_getAdvance (QofDateBook * d)
00191 {
00192 Appointment_t *qd;
00193
00194 g_return_val_if_fail (d != NULL, -1);
00195 qd = &d->wrap;
00196 return (datebook_getAlarm (d)) ? qd->advance : 0;
00197 }
00198
00203 static const gchar *
00204 datebook_getAdvanceUnit (QofDateBook * d)
00205 {
00206 Appointment_t *qd;
00207 gchar *unit;
00208
00209 g_return_val_if_fail (d != NULL, NULL);
00210 qd = &d->wrap;
00211 if (datebook_getAlarm (d) == FALSE)
00212 return NULL;
00213 unit = g_strdup (alarmTypesasString (qd->advanceUnits));
00214 return unit;
00215 }
00216
00217 static const gchar *
00218 datebook_getRepeatType (QofDateBook * d)
00219 {
00220 Appointment_t *qd;
00221 gchar *type_label;
00222
00223 g_return_val_if_fail (d != NULL, NULL);
00224 qd = &d->wrap;
00225 type_label = g_strdup (repeatTypesasString (qd->repeatType));
00226 return type_label;
00227 }
00228
00229 static gboolean
00230 datebook_getRepeatForever (QofDateBook * d)
00231 {
00232 Appointment_t *qd;
00233
00234 g_return_val_if_fail (d != NULL, -1);
00235 qd = &d->wrap;
00236 return (qd->repeatForever == 1) ? TRUE : FALSE;
00237 }
00238
00239 static QofTime *
00240 datebook_getRepeatEnd (QofDateBook * d)
00241 {
00242 Appointment_t *qd;
00243
00244 g_return_val_if_fail (d != NULL, NULL);
00245 qd = &d->wrap;
00246 if (qd->repeatType == repeatNone)
00247 qd->repeatEnd = qd->end;
00248 return qof_time_from_tm (&qd->repeatEnd, 0);
00249 }
00250
00257 static gint
00258 datebook_getRepeatFrequency (QofDateBook * d)
00259 {
00260 Appointment_t *qd;
00261
00262 g_return_val_if_fail (d != NULL, -1);
00263 qd = &d->wrap;
00264 return qd->repeatFrequency;
00265 }
00266
00267 static const gchar *
00268 datebook_getRepeatDay (QofDateBook * d)
00269 {
00270 Appointment_t *qd;
00271 enum DayOfMonthType type;
00272 gchar *g;
00273
00274 g_return_val_if_fail (d != NULL, NULL);
00275 qd = &d->wrap;
00276 if (qd->repeatType == repeatNone)
00277 return NULL;
00278 type = qd->repeatDay;
00279 g = g_strdup (DayOfMonthTypeasString (type));
00280 return g;
00281 }
00282
00317 static QofDateFormat df = 0;
00318
00319 static gchar *
00320 datebook_getRepeatWeekStart (QofDateBook * d)
00321 {
00322 Appointment_t *qd;
00323 QofTime *qt;
00324 QofDate *qdate;
00325 gboolean result;
00326 gchar *retval;
00327
00328 g_return_val_if_fail (d != NULL, NULL);
00329 qd = &d->wrap;
00330 if (qd->repeatType == repeatNone)
00331 return NULL;
00332 qt = qof_time_get_current ();
00333 if (df == 0)
00334 {
00335 result = qof_date_format_add ("%A", &df);
00336 if (!result)
00337 {
00338 PERR (" failed to fetch the locale format");
00339 return NULL;
00340 }
00341 }
00342 qdate = qof_date_from_qtime (qt);
00343 if (qdate->qd_mday < qdate->qd_wday)
00344 qdate->qd_mday += 7;
00345 qdate->qd_mday -= (qdate->qd_wday + qd->repeatWeekstart);
00346 qof_date_valid (qdate);
00347 qof_time_free (qt);
00348 retval = qof_date_print (qdate, df);
00349 qof_date_free (qdate);
00350 return retval;
00351 }
00352
00353 static gint
00354 datebook_getExceptions (QofDateBook * d)
00355 {
00356 Appointment_t *qd;
00357
00358 g_return_val_if_fail (d != NULL, -1);
00359 qd = &d->wrap;
00360 return qd->exceptions;
00361 }
00362
00363 static gchar *
00364 datebook_getDescription (QofDateBook * d)
00365 {
00366 Appointment_t *qd;
00367
00368 g_return_val_if_fail (d != NULL, NULL);
00369 qd = &d->wrap;
00370 return qd->description;
00371 }
00372
00373 static gchar *
00374 datebook_getNote (QofDateBook * d)
00375 {
00376 Appointment_t *qd;
00377
00378 g_return_val_if_fail (d != NULL, NULL);
00379 qd = &d->wrap;
00380 return qd->note;
00381 }
00382
00383 static gchar *
00384 datebook_getCategory (QofDateBook * d)
00385 {
00386 g_return_val_if_fail (d != NULL, NULL);
00387 return d->category;
00388 }
00389
00390 static double
00391 datebook_getDuration (QofDateBook * d)
00392 {
00393 QofTime *qt_diff, *qt_start, *qt_end;
00394 gdouble retval;
00395
00396 g_return_val_if_fail (d, 0);
00397 qt_start = datebook_getBegin (d);
00398 qt_end = datebook_getEnd (d);
00399 qt_diff = qof_time_diff (qt_end, qt_start);
00400 retval = qof_time_get_secs (qt_diff) / 3600;
00401 qof_time_free (qt_diff);
00402 qof_time_free (qt_start);
00403 qof_time_free (qt_end);
00404 return retval;
00405 }
00406
00407 static gboolean
00408 datebook_check_repeater (QofDateBook * d)
00409 {
00410 g_return_val_if_fail (d, FALSE);
00411 return d->repeater;
00412 }
00413
00414 static void
00415 datebook_set_repeater (QofDateBook * d, gboolean e)
00416 {
00417 g_return_if_fail (d != NULL);
00418 d->repeater = e;
00419 }
00420
00421 static void
00422 datebook_setEvent (QofDateBook * d, gboolean e)
00423 {
00424 Appointment_t *qd;
00425
00426 g_return_if_fail (d != NULL);
00427 qd = &d->wrap;
00428 qd->event = 0;
00429 if (e == TRUE)
00430 qd->event = 1;
00431 }
00432
00433 static void
00434 datebook_setBegin (QofDateBook * d, QofTime *qt)
00435 {
00436 Appointment_t *qd;
00437 gboolean result;
00438 QofDate *qdate;
00439
00440 g_return_if_fail (d != NULL);
00441 qd = &d->wrap;
00442 qdate = qof_date_from_qtime (qt);
00443 result = qof_date_to_struct_tm (qdate, &qd->begin, 0);
00444 if(!result)
00445 PERR (" Date too large for begin.");
00446 qof_date_free (qdate);
00447 }
00448
00449 static void
00450 datebook_setEnd (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->end, 0);
00460 if(!result)
00461 PERR (" Date too large for end.");
00462 qof_date_free (qdate);
00463 }
00464
00465 static void
00466 datebook_setAlarm (QofDateBook * d, gboolean e)
00467 {
00468 Appointment_t *qd;
00469
00470 g_return_if_fail (d != NULL);
00471 qd = &d->wrap;
00472 if (e)
00473 qd->alarm = 1;
00474 }
00475
00476 static void
00477 datebook_setAdvance (QofDateBook * d, gint e)
00478 {
00479 Appointment_t *qd;
00480
00481 g_return_if_fail (d != NULL);
00482 qd = &d->wrap;
00483 qd->advance = e;
00484 }
00485
00486 static void
00487 datebook_setAdvanceUnit (QofDateBook * d, const gchar * e)
00488 {
00489 Appointment_t *qd;
00490 enum alarmTypes type;
00491
00492 g_return_if_fail (d != NULL);
00493 if (e == NULL)
00494 return;
00495 qd = &d->wrap;
00496 alarmTypesfromString (e, &type);
00497 qd->advanceUnits = type;
00498 }
00499
00504 static void
00505 datebook_setRepeatType (QofDateBook * d, const gchar * type_label)
00506 {
00507 Appointment_t *qd;
00508 enum repeatTypes type;
00509
00510 g_return_if_fail (d != NULL);
00511 qd = &d->wrap;
00512 repeatTypesfromString (type_label, &type);
00513 qd->repeatType = type;
00514 }
00515
00516 static void
00517 datebook_setRepeatForever (QofDateBook * d, gboolean e)
00518 {
00519 Appointment_t *qd;
00520
00521 g_return_if_fail (d != NULL);
00522 qd = &d->wrap;
00523 if (e)
00524 qd->repeatForever = 1;
00525 }
00526
00527 static void
00528 datebook_setRepeatEnd (QofDateBook * d, QofTime *qt)
00529 {
00530 Appointment_t *qd;
00531 gboolean result;
00532 QofDate *qdate;
00533
00534 g_return_if_fail (d != NULL);
00535 qd = &d->wrap;
00536 qdate = qof_date_from_qtime (qt);
00537 result = qof_date_to_struct_tm (qdate, &qd->repeatEnd, 0);
00538 if(!result)
00539 PERR (" Date too large for repeatEnd.");
00540 qof_date_free (qdate);
00541 }
00542
00543 static void
00544 datebook_setRepeatFrequency (QofDateBook * d, gint e)
00545 {
00546 Appointment_t *qd;
00547
00548 g_return_if_fail (d != NULL);
00549 qd = &d->wrap;
00550 qd->repeatFrequency = e;
00551 }
00552
00553 static void
00554 datebook_setRepeatDay (QofDateBook * d, const gchar * e)
00555 {
00556 Appointment_t *qd;
00557 enum DayOfMonthType type;
00558
00559 g_return_if_fail (d != NULL);
00560 if (e == NULL)
00561 return;
00562 qd = &d->wrap;
00563 DayOfMonthTypefromString (e, &type);
00564 qd->repeatDay = type;
00565 }
00566
00574 static void
00575 datebook_setRepeatWeekStart (QofDateBook * d, gchar * e)
00576 {
00577 gchar day[MAX_DATE_LENGTH];
00578 Appointment_t *qd;
00579 time_t local;
00580 struct tm *local_tm;
00581 gint i, diff;
00582 gboolean found;
00583
00584 g_return_if_fail (d != NULL);
00585 qd = &d->wrap;
00586 diff = 0;
00587 found = FALSE;
00588 local = time (NULL);
00589 local_tm = localtime (&local);
00590 if (local_tm->tm_wday <= 7)
00591 diff = 1;
00592 else
00593 diff = -1;
00594 for (i = 0; i < 7; i++)
00595 {
00596 strftime (day, MAX_DATE_LENGTH, "%A", local_tm);
00597 if (0 == safe_strcmp (e, day))
00598 {
00599 found = TRUE;
00600 break;
00601 }
00602 local_tm->tm_mday += diff;
00603 }
00604 if (!found)
00605 i = 0;
00606 qd->repeatWeekstart = i;
00607 }
00608
00609 static void
00610 datebook_setExceptions (QofDateBook * d, gint e)
00611 {
00612 Appointment_t *qd;
00613
00614 g_return_if_fail (d != NULL);
00615 qd = &d->wrap;
00616 qd->exceptions = e;
00617 }
00618
00619 static void
00620 datebook_setDescription (QofDateBook * d, gchar * h)
00621 {
00622 Appointment_t *qd;
00623
00624 g_return_if_fail (d);
00625 qd = &d->wrap;
00626 qd->description = g_strdup (qof_util_make_utf8 (h));
00627 }
00628
00629 static void
00630 datebook_setNote (QofDateBook * d, gchar * h)
00631 {
00632 Appointment_t *qd;
00633
00634 g_return_if_fail (d);
00635 qd = &d->wrap;
00636 if (!h)
00637 return;
00638 qd->note = g_strdup (qof_util_make_utf8 (h));
00639 }
00640
00641 static void
00642 datebook_setCategory (QofDateBook * d, gchar * n)
00643 {
00644 g_return_if_fail (d != NULL);
00645 d->category = g_strdup (qof_util_make_utf8 (n));
00646 }
00647
00648 void
00649 datebook_repeater_clone (QofEntity * ent, QofTime * qt_end, QofTime * qt_increment)
00650 {
00651 QofDateBook * clone;
00652 QofInstance * inst;
00653 QofBook * book;
00654 QofDateBook * obj;
00655
00656 obj = (QofDateBook*)ent;
00657 inst = (QofInstance*)obj;
00658 book = inst->book;
00659 clone = datebook_create (book);
00660 clone->repeater = TRUE;
00661
00662 datebook_setEvent (clone, datebook_getEvent (obj));
00663 datebook_setAlarm (clone, datebook_getAlarm (obj));
00664 datebook_setAdvance (clone, datebook_getAdvance (obj));
00665 datebook_setAdvanceUnit (clone, datebook_getAdvanceUnit (obj));
00666 datebook_setDescription (clone, datebook_getDescription (obj));
00667 datebook_setNote (clone, datebook_getNote (obj));
00668 datebook_setCategory (clone, datebook_getCategory (obj));
00669
00670 datebook_setExceptions (clone, 0);
00671 datebook_setRepeatEnd (clone, qt_end);
00672 datebook_setRepeatForever (clone, FALSE);
00673 datebook_setRepeatType (clone,
00674 repeatTypesasString (repeatNone));
00675 datebook_setBegin (clone, qt_increment);
00676 datebook_setEnd (clone, qt_end);
00677 }
00678
00679 static const gchar *
00680 datebookPrintable (gpointer instance)
00681 {
00682 return datebook_getDescription ((QofDateBook *) instance);
00683 }
00684
00685 static QofObject datebook_object_def = {
00686 interface_version:QOF_OBJECT_VERSION,
00687 e_type:PILOT_LINK_QOF_DATEBOOK,
00688 type_label:QOF_DATEBOOK_DESC,
00689 create:(gpointer) datebook_create,
00690 book_begin:NULL,
00691 book_end:NULL,
00692 is_dirty:qof_collection_is_dirty,
00693 mark_clean:qof_collection_mark_clean,
00694 foreach:qof_collection_foreach,
00695 printable:datebookPrintable,
00696 version_cmp:(gint (*)(gpointer, gpointer)) qof_instance_version_cmp,
00697 };
00698
00699 gboolean
00700 DateBookRegister (void)
00701 {
00702 static QofParam params[] = {
00703 {DATEBOOK_EVENT, QOF_TYPE_BOOLEAN,
00704 (QofAccessFunc) datebook_getEvent,
00705 (QofSetterFunc) datebook_setEvent},
00706 {DATEBOOK_BEGIN, QOF_TYPE_TIME, (QofAccessFunc) datebook_getBegin,
00707 (QofSetterFunc) datebook_setBegin},
00708 {DATEBOOK_END, QOF_TYPE_TIME, (QofAccessFunc) datebook_getEnd,
00709 (QofSetterFunc) datebook_setEnd},
00710 {DATEBOOK_ALARM, QOF_TYPE_BOOLEAN,
00711 (QofAccessFunc) datebook_getAlarm,
00712 (QofSetterFunc) datebook_setAlarm},
00713 {DATEBOOK_ADVANCE, QOF_TYPE_INT32,
00714 (QofAccessFunc) datebook_getAdvance,
00715 (QofSetterFunc) datebook_setAdvance},
00716 {DATEBOOK_ADV_UNIT, QOF_TYPE_STRING,
00717 (QofAccessFunc) datebook_getAdvanceUnit,
00718 (QofSetterFunc) datebook_setAdvanceUnit},
00719 {DATEBOOK_REPEAT_TYPE, QOF_TYPE_STRING,
00720 (QofAccessFunc) datebook_getRepeatType,
00721 (QofSetterFunc) datebook_setRepeatType},
00722 {DATEBOOK_REPEAT_FOREVER, QOF_TYPE_BOOLEAN,
00723 (QofAccessFunc) datebook_getRepeatForever,
00724 (QofSetterFunc) datebook_setRepeatForever},
00725 {DATEBOOK_REPEAT_END, QOF_TYPE_TIME,
00726 (QofAccessFunc) datebook_getRepeatEnd,
00727 (QofSetterFunc) datebook_setRepeatEnd},
00728 {DATEBOOK_REPEAT_FREQUENCY, QOF_TYPE_INT32,
00729 (QofAccessFunc) datebook_getRepeatFrequency,
00730 (QofSetterFunc) datebook_setRepeatFrequency},
00731 {DATEBOOK_REPEAT_DAY, QOF_TYPE_STRING,
00732 (QofAccessFunc) datebook_getRepeatDay,
00733 (QofSetterFunc) datebook_setRepeatDay},
00734 {DATEBOOK_REPEAT_WEEK_START, QOF_TYPE_STRING,
00735 (QofAccessFunc) datebook_getRepeatWeekStart,
00736 (QofSetterFunc) datebook_setRepeatWeekStart},
00737 {DATEBOOK_EXCEPTIONS, QOF_TYPE_INT32,
00738 (QofAccessFunc) datebook_getExceptions,
00739 (QofSetterFunc) datebook_setExceptions},
00740 {DATEBOOK_DESCRIPTION, QOF_TYPE_STRING,
00741 (QofAccessFunc) datebook_getDescription,
00742 (QofSetterFunc) datebook_setDescription},
00743 {DATEBOOK_CATEGORY, QOF_TYPE_STRING,
00744 (QofAccessFunc) datebook_getCategory,
00745 (QofSetterFunc) datebook_setCategory},
00746 {DATEBOOK_REPEATER, QOF_TYPE_BOOLEAN,
00747 (QofAccessFunc) datebook_check_repeater,
00748 (QofSetterFunc) datebook_set_repeater},
00749 {DATEBOOK_NOTE, QOF_TYPE_STRING, (QofAccessFunc) datebook_getNote,
00750 (QofSetterFunc) datebook_setNote},
00751 {DATEBOOK_DURATION, QOF_TYPE_DOUBLE,
00752 (QofAccessFunc) datebook_getDuration, NULL},
00753 {DATEBOOK_EXCEPTION, QOF_TYPE_KVP,
00754 (QofAccessFunc) qof_instance_get_slots, NULL},
00755 {QOF_PARAM_BOOK, QOF_ID_BOOK,
00756 (QofAccessFunc) qof_instance_get_book, NULL},
00757 {QOF_PARAM_GUID, QOF_TYPE_GUID,
00758 (QofAccessFunc) qof_instance_get_guid, NULL},
00759 {NULL},
00760 };
00761
00762 qof_class_register (PILOT_LINK_QOF_DATEBOOK, NULL, params);
00763
00764 return qof_object_register (&datebook_object_def);
00765 }
00766