valarm.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright 2005 - 2016 Zarafa and its licensors
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. */
  17. #include <kopano/platform.h>
  18. #include <mapi.h>
  19. #include <mapidefs.h>
  20. #include <mapix.h>
  21. #include <mapiutil.h>
  22. #include <kopano/mapiext.h>
  23. #include <kopano/mapiguidext.h>
  24. #include "valarm.h"
  25. #include "recurrence.h"
  26. #include <kopano/namedprops.h>
  27. #include <kopano/CommonUtil.h>
  28. #include <kopano/Util.h>
  29. #include <kopano/stringutil.h>
  30. namespace KC {
  31. /**
  32. * Generates ical VALARM component from reminderbefore minutes.
  33. * Mapi -> Ical conversion
  34. *
  35. * @param[in] lRemindBefore reminder before minutes.
  36. * @param[in] ttReminderTime Reminder time in UTC format.
  37. * @param[in] bTask If true, the output value is for a task item
  38. * @param[out] lppAlarm ical VALARM component.
  39. * @return MAPI error code
  40. * @retval MAPI_E_INVALID_PARAMETER invalid parameters
  41. */
  42. HRESULT HrParseReminder(LONG lRemindBefore, time_t ttReminderTime, bool bTask, icalcomponent **lppAlarm)
  43. {
  44. icalcomponent *lpVAlarm = NULL;
  45. icaltriggertype sittTrigger;
  46. if (lppAlarm == NULL)
  47. return MAPI_E_INVALID_PARAMETER;
  48. if (lRemindBefore == 1525252321) // OL sets this value for default 15 mins time.
  49. lRemindBefore = 15;
  50. memset(&sittTrigger, 0, sizeof(icaltriggertype));
  51. if (ttReminderTime && bTask) {
  52. sittTrigger.time = icaltime_from_timet_with_zone(ttReminderTime, false, nullptr); // given in UTC
  53. sittTrigger.time.is_utc = 1;
  54. } else
  55. sittTrigger.duration = icaldurationtype_from_int(-1 * lRemindBefore * 60); // set seconds
  56. lpVAlarm = icalcomponent_new_valarm();
  57. icalcomponent_add_property(lpVAlarm, icalproperty_new_trigger(sittTrigger));
  58. icalcomponent_add_property(lpVAlarm, icalproperty_new_action(ICAL_ACTION_DISPLAY));
  59. icalcomponent_add_property(lpVAlarm, icalproperty_new_description("Reminder"));
  60. *lppAlarm = lpVAlarm;
  61. return hrSuccess;
  62. }
  63. /**
  64. * Gets reminder info from the ical VTIMEZONE component.
  65. * ICAL -> MAPI conversion
  66. *
  67. * @param[in] lpicAlarm ical VTIMEZONE component
  68. * @param[out] lplRemindBefore reminder before minutes
  69. * @param[out] lpttReminderTime timestamp reminder trigger time in UTC
  70. * @param[out] lpbReminderSet boolean to specify if reminder is set
  71. * @return MAPI error code
  72. */
  73. HRESULT HrParseVAlarm(icalcomponent *lpicAlarm, LONG *lplRemindBefore, time_t *lpttReminderTime, bool *lpbReminderSet) {
  74. HRESULT hr = hrSuccess;
  75. icalproperty *lpTrigger = NULL;
  76. icalproperty *lpAction = NULL;
  77. icaltriggertype sittTrigger;
  78. icalproperty_action eipaAction;
  79. std::string strValue;
  80. LONG lRemindBefore = 0;
  81. time_t ttReminderTime = 0;
  82. bool bReminderSet = false;
  83. lpTrigger = icalcomponent_get_first_property(lpicAlarm, ICAL_TRIGGER_PROPERTY);
  84. lpAction = icalcomponent_get_first_property(lpicAlarm, ICAL_ACTION_PROPERTY);
  85. if (lpTrigger != NULL) {
  86. sittTrigger = icalproperty_get_trigger(lpTrigger);
  87. ttReminderTime = icaltime_as_timet(sittTrigger.time); // is in utc
  88. lRemindBefore = -1 * (icaldurationtype_as_int(sittTrigger.duration) / 60);
  89. // In iCal, a reminder before can be both negative (meaning alarm BEFORE startdate) or positive (meaning
  90. // alarm AFTER startdate). In MAPI, a remind before can only be positive (meaning alarm BEFORE startdate).
  91. // If (after inverting iCal remind before so it's compatible with MAPI) remind before is negative, we need
  92. // to set it to 0.
  93. if (lRemindBefore < 0)
  94. lRemindBefore = 0;
  95. }
  96. if (lpAction != NULL) {
  97. eipaAction = icalproperty_get_action(lpAction);
  98. // iMac Calendar 6.0 sends ACTION:NONE, which libical doesn't parse correcty to the ICAL_ACTION_NONE enum value
  99. if (eipaAction > ICAL_ACTION_X && eipaAction < ICAL_ACTION_NONE)
  100. bReminderSet = true;
  101. }
  102. if (lplRemindBefore)
  103. *lplRemindBefore = lRemindBefore;
  104. if (lpttReminderTime)
  105. *lpttReminderTime = ttReminderTime;
  106. if (lpbReminderSet)
  107. *lpbReminderSet = bReminderSet;
  108. return hr;
  109. }
  110. } /* namespace */