00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #define _GNU_SOURCE
00025 #include "config.h"
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <regex.h>
00029 #include <ctype.h>
00030 #include <glib.h>
00031 #include <glib/gi18n.h>
00032 #include <glib/gprintf.h>
00033 #include <qof.h>
00034 #include <popt.h>
00035 #include "pi-source.h"
00036 #include "pi-debug.h"
00037 #include "pi-socket.h"
00038 #include "pi-file.h"
00039 #include "pi-header.h"
00040 #include "pi-util.h"
00041 #include "pi-todo.h"
00042 #include "pi-expense.h"
00043 #include "qof-main.h"
00044 #include "pilot-qof.h"
00045 #include "pilot-todo.h"
00046 #include "qof-address.h"
00047 #include "qof-datebook.h"
00048 #ifdef HAVE_QOFEXPENSES
00049 #include <qof-expenses.h>
00050 #endif
00051 #include "pilot-expenses.h"
00052 #include "pilot-expenses-p.h"
00053 #include "palm.h"
00054
00056 static QofLogModule log_module = PQ_MOD_CLI;
00057
00058 #ifdef HAVE_QOFEXPENSES
00059 static Expense_t *
00060 expense_get_pilot (QofEntity * ent)
00061 {
00062 glong nanosecs;
00063 QofDate *qd;
00064 QofTime * qt;
00065 Expense_t *qe;
00066 gchar * string;
00067 const QofParam * param;
00068 gint32 (*int32_getter) (QofEntity*, const QofParam*);
00069
00070 g_return_val_if_fail (ent != NULL, NULL);
00071 if (g_strcmp0(ent->e_type, PILOT_LINK_QOF_EXPENSES) == 0)
00072 return pq_expense_get_pilot(ent);
00073 qe = g_new0 (Expense_t, 1);
00074 param = qof_class_get_parameter (GPE_QOF_EXPENSES, EXP_DATE);
00075 qt = param->param_getfcn (ent, param);
00076 if (!qt)
00077 return NULL;
00078 nanosecs = qof_time_get_nanosecs (qt);
00079 qd = qof_date_from_qtime (qt);
00080 qof_date_to_struct_tm (qd, &qe->date, &nanosecs);
00081 qof_date_free (qd);
00082 param = qof_class_get_parameter (GPE_QOF_EXPENSES, EXP_TYPE);
00083 string = param->param_getfcn (ent, param);
00084 qe->type = ExpenseTypefromString (string);
00085 param = qof_class_get_parameter (GPE_QOF_EXPENSES, EXP_PAYMENT);
00086 string = param->param_getfcn (ent, param);
00087 qe->payment = ExpensePaymentfromString (string);
00088 param = qof_class_get_parameter (GPE_QOF_EXPENSES, EXP_CURRENCY);
00089 int32_getter = (gint32 (*)(QofEntity*, const QofParam*)) param->param_getfcn;
00090 qe->currency = int32_getter(ent, param);
00091 param = qof_class_get_parameter (GPE_QOF_EXPENSES, EXP_AMOUNT);
00092 qe->amount = param->param_getfcn (ent, param);
00093 param = qof_class_get_parameter (GPE_QOF_EXPENSES, EXP_VENDOR);
00094 qe->vendor = param->param_getfcn (ent, param);
00095 param = qof_class_get_parameter (GPE_QOF_EXPENSES, EXP_CITY);
00096 qe->city = param->param_getfcn (ent, param);
00097 param = qof_class_get_parameter (GPE_QOF_EXPENSES, EXP_ATTENDEES);
00098 qe->attendees = param->param_getfcn (ent, param);
00099 param = qof_class_get_parameter (GPE_QOF_EXPENSES, EXP_NOTE);
00100 qe->note = param->param_getfcn (ent, param);
00101 return qe;
00102 }
00103 #else
00104 #define expense_get_pilot pq_expense_get_pilot
00105 #endif
00106
00107 static gint
00108 exp_unpack (QofEntity * ent, gpointer user_data)
00109 {
00110 Expense_t *qe;
00111 pi_buffer_t *pi_buf;
00112 PQContext *context;
00113 const QofParam * param;
00114 size_t len;
00115 gint size;
00116 gchar * string;
00117
00118 context = (PQContext *) user_data;
00119 g_return_val_if_fail (context != NULL, -1);
00120 g_return_val_if_fail (ent != NULL, -1);
00121 qe = expense_get_pilot (ent);
00122 g_return_val_if_fail (qe != NULL, -1);
00123 pi_buf = (pi_buffer_t *) context->pi_buf;
00124 len = sizeof (pi_buf->data);
00125 size = unpack_Expense (qe, pi_buf->data, pi_buf->allocated);
00126 param = qof_class_get_parameter (PILOT_LINK_QOF_EXPENSES, EXP_CATEGORY);
00127 qof_util_param_edit ((QofInstance*)ent, param);
00128 qof_util_param_set_string (ent, param, context->names[context->ent_category]);
00129 qof_util_param_commit ((QofInstance*)ent, param);
00130
00131 param = qof_class_get_parameter (PILOT_LINK_QOF_EXPENSES, EXP_CURRENCY);
00132 string = g_strdup_printf ("%d", qe->currency);
00133 qof_util_param_edit ((QofInstance*)ent, param);
00134 qof_util_param_set_string (ent, param, string);
00135 qof_util_param_commit ((QofInstance*)ent, param);
00136 g_free (string);
00137 return size;
00138 }
00139
00140 static gint
00141 exp_pack (QofEntity * ent, gpointer user_data)
00142 {
00143 PQContext *context;
00144 Expense_t *qe;
00145 gint size, len;
00146
00147 size = 0;
00148 len = PQ_DEF_BUFSZ;
00149 context = (PQContext *) user_data;
00150 g_return_val_if_fail ((context), -1);
00151 qe = expense_get_pilot (ent);
00152
00153
00154 size = pack_Expense (qe, context->pi_buf->data, len);
00155
00156 if (size > 0)
00157 context->pi_buf->used = size;
00158 return size;
00159 }
00160
00161 static gint
00162 exp_pref_unpack (QofEntity * ent, gpointer user_data)
00163 {
00164 struct ExpensePref pref_e;
00165 PQContext *context;
00166
00167
00168 context = (PQContext *) user_data;
00169 g_return_val_if_fail (context != NULL, -1);
00170 ENTER (" ");
00171 unpack_ExpensePref (&pref_e, context->pref_buf, PQ_DEF_BUFSZ);
00172 context->pi_exp_pref.default_currency = pref_e.defaultCurrency;
00173 context->pi_exp_pref.unit_of_distance = pref_e.unitOfDistance;
00174
00175 LEAVE (" ");
00176 return 0;
00177 }
00178
00179 static gint
00180 exp_appinfo_unpack (QofEntity * ent, gpointer user_data)
00181 {
00182 ExpenseAppInfo_t app_e;
00183 PQContext *context;
00184 gint name_count;
00185
00186
00187 context = (PQContext *) user_data;
00188 g_return_val_if_fail (context != NULL, -1);
00189 ENTER (" ");
00190 unpack_ExpenseAppInfo (&app_e, context->app_buf->data, PQ_DEF_BUFSZ);
00191 for (name_count = 0; name_count < 16; name_count++)
00192 {
00193 g_sprintf (context->names[name_count], "%s",
00194 app_e.category.name[name_count]);
00195 }
00196 context->pi_cat = &app_e.category;
00197 LEAVE (" ");
00198 return 0;
00199 }
00200
00201 static gint
00202 qof_exp_free (QofEntity * ent, gpointer user_data)
00203 {
00204 Expense_t *qe;
00205
00206 g_return_val_if_fail (ent != NULL, -1);
00207 ENTER (" ");
00208 qe = expense_get_pilot (ent);
00209 free_Expense (qe);
00210 LEAVE (" ");
00211 return 0;
00212 }
00213
00214 static PQPack expenses_pack_def = {
00215 e_type : PILOT_LINK_QOF_EXPENSES,
00216 pack_func : exp_pack,
00217 unpack_func : exp_unpack,
00218 free_pack_func : qof_exp_free,
00219 palm_db_name : Expense_DB,
00220 app_info_unpack : exp_appinfo_unpack,
00221 db_pref_unpack : exp_pref_unpack,
00222 pref_creator : EXPENSE_CREATOR,
00223 pref_flag : Expense_Pref,
00224 };
00225
00226 static gint
00227 qof_todo_free (QofEntity * ent, gpointer user_data)
00228 {
00229 ToDo_t *qt;
00230
00231 g_return_val_if_fail (ent != NULL, -1);
00232 ENTER (" ");
00233 qt = todo_get_pilot((QofInstance *)ent);
00234 free_ToDo (qt);
00235 LEAVE (" ");
00236 return 0;
00237 }
00238
00239 static gint
00240 todo_unpack (QofEntity * ent, gpointer user_data)
00241 {
00242 pi_buffer_t *pi_buf;
00243 ToDo_t *qt;
00244 PQContext *context;
00245 const QofParam * param;
00246 gint size;
00247
00248 context = (PQContext *) user_data;
00249 g_return_val_if_fail (context != NULL, -1);
00250 g_return_val_if_fail (ent != NULL, -1);
00251 ENTER (" ent_type=%s", ent->e_type);
00252 qt = todo_get_pilot((QofInstance *)ent);
00253 g_return_val_if_fail (qt != NULL, -1);
00254 pi_buf = (pi_buffer_t *) context->pi_buf;
00255 size = 0;
00256 size = unpack_ToDo (qt, pi_buf, TODO_VERSION);
00257 param = qof_class_get_parameter (PILOT_LINK_QOF_TODO, TODO_CATEGORY);
00258 qof_util_param_edit ((QofInstance*)ent, param);
00259 qof_util_param_set_string (ent, param, context->names[context->ent_category]);
00260 PINFO (" category=%s", context->names[context->ent_category]);
00261 qof_util_param_commit ((QofInstance*)ent, param);
00262 LEAVE (" ");
00263 return size;
00264 }
00265
00266 static gint
00267 todo_pack (QofEntity * ent, gpointer user_data)
00268 {
00269 ToDo_t *qt;
00270 PQContext *context;
00271 gint size;
00272
00273 size = 0;
00274 context = (PQContext *) user_data;
00275 g_return_val_if_fail ((context || ent), -1);
00276 ENTER (" ");
00277 qt = todo_get_pilot((QofInstance *)ent);
00278 size = pack_ToDo (qt, context->pi_buf, TODO_VERSION);
00279 LEAVE (" ");
00280 return size;
00281 }
00282
00283 static gint
00284 todo_appinfo_unpack (QofEntity * ent, gpointer user_data)
00285 {
00286 ToDoAppInfo_t app_t;
00287 PQContext *context;
00288 gint name_count;
00289
00290 context = (PQContext *) user_data;
00291 g_return_val_if_fail (context != NULL, -1);
00292 ENTER (" ");
00293 unpack_ToDoAppInfo (&app_t, context->app_buf->data, PQ_DEF_BUFSZ);
00294 for (name_count = 0; name_count < 16; name_count++)
00295 g_sprintf (context->names[name_count], "%s",
00296 app_t.category.name[name_count]);
00297 context->pi_cat = &app_t.category;
00298 LEAVE (" ");
00299 return 0;
00300 }
00301
00302 static PQPack todo_pack_def = {
00303 e_type : PILOT_LINK_QOF_TODO,
00304 pack_func : todo_pack,
00305 unpack_func : todo_unpack,
00306 free_pack_func : qof_todo_free,
00307 palm_db_name : "ToDoDB",
00308 app_info_unpack : todo_appinfo_unpack,
00309 };
00310
00332 static gint
00333 address_pack (QofEntity * ent, gpointer user_data)
00334 {
00335 PQContext *context;
00336 Address_t *qa;
00337 gint size;
00338
00339 size = 0;
00340 context = (PQContext *) user_data;
00341 g_return_val_if_fail ((context || ent), -1);
00342 qa = address_get_pilot((QofInstance *)ent);
00343 size = pack_Address (qa, context->pi_buf, ADDRESS_VERSION);
00344 PINFO (" result=%d", size);
00345 return size;
00346 }
00347
00354 static gint
00355 address_unpack (QofEntity * ent, gpointer user_data)
00356 {
00357 pi_buffer_t *pi_buf;
00358 Address_t *qa;
00359 PQContext *context;
00360 const QofParam * param;
00361 gint size;
00362
00363 context = (PQContext *) user_data;
00364 g_return_val_if_fail (context != NULL, -1);
00365 g_return_val_if_fail (ent != NULL, -1);
00366 qa = address_get_pilot((QofInstance *)ent);
00367 g_return_val_if_fail (qa != NULL, -1);
00368 pi_buf = (pi_buffer_t *) context->pi_buf;
00369 size = 0;
00370 size = unpack_Address (qa, pi_buf, ADDRESS_VERSION);
00371 param = qof_class_get_parameter (PILOT_LINK_QOF_ADDRESS, ADDR_CATEGORY);
00372 qof_util_param_edit ((QofInstance*)ent, param);
00373 PINFO (" category=%s", context->names[context->ent_category]);
00374 qof_util_param_set_string (ent, param, context->names[context->ent_category]);
00375 qof_util_param_commit ((QofInstance*)ent, param);
00376
00377 return size;
00378 }
00379
00386 static gint
00387 addr_appinfo_unpack (QofEntity * ent, gpointer user_data)
00388 {
00389 AddressAppInfo_t app_a;
00390 PQContext *context;
00391 gint name_count;
00392
00393
00394 context = (PQContext *) user_data;
00395 g_return_val_if_fail (context != NULL, -1);
00396 ENTER (" ");
00397 unpack_AddressAppInfo (&app_a, context->app_buf->data, PQ_DEF_BUFSZ);
00398 for (name_count = 0; name_count < 16; name_count++)
00399 {
00400 g_sprintf (context->names[name_count], "%s",
00401 app_a.category.name[name_count]);
00402 }
00403 context->pi_cat = &app_a.category;
00404 LEAVE (" ");
00405 return 0;
00406 }
00407
00413 static gint
00414 qof_address_free (QofEntity * ent, gpointer user_data)
00415 {
00416 Address_t *qa;
00417
00418 g_return_val_if_fail (ent != NULL, -1);
00419 ENTER (" ");
00420 qa = address_get_pilot((QofInstance *)ent);
00421 free_Address (qa);
00422 LEAVE (" ");
00423 return 0;
00424 }
00429 static PQPack address_pack_def = {
00430 e_type : PILOT_LINK_QOF_ADDRESS,
00431 pack_func : address_pack,
00432 unpack_func : address_unpack,
00433 free_pack_func : qof_address_free,
00434 palm_db_name : "AddressDB",
00435 app_info_unpack : addr_appinfo_unpack,
00436 };
00437
00443 static gint
00444 datebook_unpack (QofEntity * ent, gpointer user_data)
00445 {
00446 pi_buffer_t *pi_buf;
00447 Appointment_t *qa;
00448
00449 QofInstance *inst;
00450
00451 KvpFrame *inst_frame;
00452 QofTime *qt, *qt_increment, *qt_end, *qt_repeat;
00453 PQContext *context;
00454 const QofParam * param;
00455 gint size, i, day_interval, month_interval;
00456
00457 context = (PQContext *) user_data;
00458 day_interval = 0;
00459 month_interval = 0;
00460 g_return_val_if_fail (context != NULL, -1);
00461 g_return_val_if_fail (ent != NULL, -1);
00462 inst = (QofInstance *) ent;
00463 inst_frame = qof_instance_get_slots (inst);
00464 qa = datebook_get_pilot ((QofInstance *) ent);
00465 g_return_val_if_fail (qa != NULL, -1);
00466 pi_buf = (pi_buffer_t *) context->pi_buf;
00467 size = 0;
00468 size = unpack_Appointment (qa, pi_buf, DATEBOOK_VERSION);
00469 param = qof_class_get_parameter (PILOT_LINK_QOF_DATEBOOK, DATEBOOK_CATEGORY);
00470 qof_util_param_edit ((QofInstance*)ent, param);
00471 qof_util_param_set_string (ent, param, context->names[context->ent_category]);
00472 qof_util_param_commit ((QofInstance*)ent, param);
00473
00474
00475 for (i = 0; i < qa->exceptions; i++)
00476 {
00477 gchar *extend;
00478
00479 extend = NULL;
00480 DEBUG (" Number of datebook repeat exceptions=%d", qa->exceptions);
00481 qt = qof_time_from_tm (&qa->exception[i], 0);
00482 extend = g_strdup_printf ("%s/%d", DATEBOOK_KVP_PATH, i + 1);
00483 kvp_frame_set_time (inst_frame, extend, qt);
00484 inst->kvp_data = inst_frame;
00485 g_free (extend);
00486 }
00487 if (qa->repeatType == repeatNone)
00488 qa->repeatEnd = qa->end;
00489
00490 switch (qa->repeatType)
00491 {
00492 case repeatNone:
00493 {
00494 day_interval = 0;
00495 month_interval = 0;
00496 break;
00497 }
00498 case repeatDaily:
00499 {
00500 day_interval = 1;
00501 month_interval = 0;
00502 break;
00503 }
00504 case repeatWeekly:
00505 {
00506 day_interval = 7;
00507 month_interval = 0;
00508 break;
00509 }
00510 case repeatMonthlyByDay:
00511 case repeatMonthlyByDate:
00512 {
00513 day_interval = 0;
00514 month_interval = 1;
00515 break;
00516 }
00517 case repeatYearly:
00518 {
00519 day_interval = 0;
00520 month_interval = 12;
00521 break;
00522 }
00523 default:
00524 {
00525 PERR (" unsupported repeatType=%d", qa->repeatType);
00526 }
00527 }
00528 if (day_interval == 0 && month_interval == 0)
00529 return size;
00530
00531 param = qof_class_get_parameter (PILOT_LINK_QOF_DATEBOOK, DATEBOOK_BEGIN);
00532 qt = param->param_getfcn (ent, param);
00533 param = qof_class_get_parameter (PILOT_LINK_QOF_DATEBOOK, DATEBOOK_END);
00534 qt_end = param->param_getfcn (ent, param);
00535 if (qa->repeatForever == 0)
00536 {
00537 param = qof_class_get_parameter (PILOT_LINK_QOF_DATEBOOK, DATEBOOK_REPEAT_END);
00538 qt_repeat = param->param_getfcn (ent, param);
00539
00540 }
00541 else
00542 {
00543 QofDate *qd;
00544
00545
00546
00547
00548 DEBUG (" qa->repeatForever == 1");
00549 qt_repeat = qt;
00550 qd = qof_date_from_qtime (qt_repeat);
00551 qof_date_addmonths (qd, 12, FALSE);
00552 qof_date_adddays (qd, 1);
00553 qof_date_free (qd);
00554 }
00555 qt_increment = qt;
00556
00557
00558 while (qof_time_cmp (qt_increment, qt_repeat) < 0)
00559 {
00560 gboolean skip;
00561
00562 skip = FALSE;
00563 if (day_interval)
00564 {
00565 QofDate *qd;
00566 qd = qof_date_from_qtime (qt_increment);
00567 qof_date_adddays (qd, day_interval);
00568 qt_increment = qof_date_to_qtime (qd);
00569 qof_date_free (qd);
00570 qd = qof_date_from_qtime (qt_end);
00571 qof_date_adddays (qd, day_interval);
00572 qt_end = qof_date_to_qtime (qd);
00573 qof_date_free (qd);
00574 }
00575 if (month_interval)
00576 {
00577 QofDate *qd;
00578 qd = qof_date_from_qtime (qt_increment);
00579 qof_date_addmonths (qd, month_interval, FALSE);
00580 qt_increment = qof_date_to_qtime (qd);
00581 qof_date_free (qd);
00582 qd = qof_date_from_qtime (qt_end);
00583 qof_date_addmonths (qd, month_interval, FALSE);
00584 qt_end = qof_date_to_qtime (qd);
00585 qof_date_free (qd);
00586 }
00587 for (i = 0; i < qa->exceptions; i++)
00588 {
00589 QofDate *qd;
00590
00591 qd = qof_date_from_qtime(qt_increment);
00592 if ((qd->qd_year == qa->exception[i].tm_year) &&
00593 (qd->qd_mday == qa->exception[i].tm_mday) &&
00594 (qd->qd_mon == qa->exception[i].tm_mon))
00595 {
00596
00597 skip = TRUE;
00598 }
00599 }
00600
00601 if (!skip)
00602 datebook_repeater_clone (ent, qt_end, qt_increment);
00603 }
00604 return size;
00605 }
00606
00608 static gint
00609 datebook_pack (QofEntity * ent, gpointer user_data)
00610 {
00611 PQContext *context;
00612 Appointment_t *qa;
00613
00614 QofTime *qt;
00615 KvpFrame *frame;
00616 gint size, i;
00617 gchar *path;
00618
00619 size = 0;
00620 i = 1;
00621 context = (PQContext *) user_data;
00622 g_return_val_if_fail ((context || ent), -1);
00623 ENTER (" ");
00624 qa = datebook_get_pilot ((QofInstance *) ent);
00625
00626
00627
00628
00629 size = pack_Appointment (qa, context->pi_buf, DATEBOOK_VERSION);
00630
00631 frame = qof_instance_get_slots ((QofInstance *) ent);
00632 if (frame)
00633 {
00634 path = g_strdup_printf ("%s/%d", DATEBOOK_KVP_PATH, i);
00635 while (kvp_frame_get_value (frame, path))
00636 {
00637 qt = kvp_frame_get_time (frame, path);
00638 if (qt)
00639 {
00640 QofDate *qd;
00641 gboolean result;
00642 qd = qof_date_from_qtime (qt);
00643 result = qof_date_to_struct_tm (qd,
00644 &qa->exception[i], 0);
00645 if(!result)
00646 PERR (" failed to set exception time: "
00647 "out of range");
00648 }
00649 g_free (path);
00650 i++;
00651 path = g_strdup_printf ("%s/%d", DATEBOOK_KVP_PATH, i);
00652 }
00653 g_free (path);
00654 }
00655 LEAVE (" ");
00656 return size;
00657 }
00658
00665 static gint
00666 datebook_appinfo_unpack (QofEntity * ent, gpointer user_data)
00667 {
00668 AppointmentAppInfo_t app_db;
00669 PQContext *context;
00670 gint name_count;
00671
00672 context = (PQContext *) user_data;
00673 g_return_val_if_fail (context != NULL, -1);
00674 ENTER (" ");
00675 unpack_AppointmentAppInfo (&app_db, context->app_buf->data,
00676 PQ_DEF_BUFSZ);
00677 for (name_count = 0; name_count < 16; name_count++)
00678 {
00679 g_sprintf (context->names[name_count], "%s",
00680 app_db.category.name[name_count]);
00681 }
00682 context->pi_cat = &app_db.category;
00683 LEAVE (" ");
00684 return 0;
00685 }
00686
00688 static gint
00689 qof_datebook_free (QofEntity * ent, gpointer user_data)
00690 {
00691 Appointment_t *qd;
00692
00693
00694 g_return_val_if_fail (ent != NULL, -1);
00695 ENTER (" ");
00696 qd = datebook_get_pilot ((QofInstance *)ent);
00697
00698
00699 free_Appointment (qd);
00700 LEAVE (" ");
00701 return 0;
00702 }
00703
00704 static PQPack datebook_pack_def = {
00705 e_type : PILOT_LINK_QOF_DATEBOOK,
00706 pack_func : datebook_pack,
00707 unpack_func : datebook_unpack,
00708 free_pack_func : qof_datebook_free,
00709 palm_db_name : "DatebookDB",
00710 app_info_unpack : datebook_appinfo_unpack,
00711 };
00712
00713 gboolean packing_registration (void)
00714 {
00715 pilot_qof_pack_register (&expenses_pack_def);
00716 pilot_qof_pack_register (&todo_pack_def);
00717 pilot_qof_pack_register (&address_pack_def);
00718 pilot_qof_pack_register (&datebook_pack_def);
00719 return TRUE;
00720 }