appointmentbuilder.cpp
来自「funambol window mobile客户端源代码」· C++ 代码 · 共 1,079 行 · 第 1/3 页
CPP
1,079 行
/*
* Funambol is a mobile platform developed by Funambol, Inc.
* Copyright (C) 2003 - 2007 Funambol, Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation with the addition of the following permission
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
* WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, see http://www.gnu.org/licenses or write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA.
*
* You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
* 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License
* version 3, these Appropriate Legal Notices must retain the display of the
* "Powered by Funambol" logo. If the display of the logo is not reasonably
* feasible for technical reasons, the Appropriate Legal Notices must display
* the words "Powered by Funambol".
*/
#include "pim/AppointmentBuilder.h"
#include "base/Log.h"
#include "pim/difftime.h"
#include "pim/UtilsRecurrence.h"
#include "pim/MAPIUtils.h"
#include "base/util/utils.h"
#include "syncml/core/PropParam.h"
/**
* Enumeration of appointment fields used by WM plugin.
* @note Don't change the order of these properties!
* This list MUST be synchronized with PIMPR_props_app array of CEPROPID fields.
*/
enum {
ePIMPR_SUBJECT ,
ePIMPR_ALL_DAY_EVENT ,
ePIMPR_SENSITIVITY ,
ePIMPR_IS_RECURRING ,
ePIMPR_REMINDER_SET ,
// ePIMPR_REMINDER_SOUND_FILE ,
ePIMPR_REMINDER_OPTIONS ,
// ePIMPR_DURATION ,
ePIMPR_LOCATION ,
ePIMPR_START ,
ePIMPR_END ,
ePIMPR_BUSY_STATUS ,
ePIMPR_REMINDER_MINUTES_BEFORE_START ,
// ePIMPR_GLOBAL_OBJECT_ID ,
ePIMPR_TIMEZONE ,
ePIMPR_MEETING_STATUS ,
// ePIMPR_MEETING_ORGANIZER_NAME ,
// ePIMPR_MEETING_OWNER_CRITICAL_CHANGE ,
// ePIMPR_ATTENDEES_CRITICAL_CHANGE ,
ePIMPR_CATEGORIES ,
ePIMPR_BODY_TEXT ,
// --- Recurring fields from here ---
ePIMPR_RECURRING_TYPE ,
ePIMPR_RECURRING_PATTERNSTARTDATE ,
ePIMPR_RECURRING_PATTERNENDDATE ,
ePIMPR_RECURRING_STARTTIME ,
ePIMPR_RECURRING_ENDTIME ,
ePIMPR_RECURRING_NOEND ,
ePIMPR_RECURRING_OCCURRENCES ,
ePIMPR_RECURRING_INTERVAL ,
ePIMPR_RECURRING_DAYOFWEEKMASK ,
ePIMPR_RECURRING_DAYOFMONTH ,
ePIMPR_RECURRING_INSTANCE ,
// ePIMPR_RECURRING_DURATION ,
ePIMPR_RECURRING_MONTHOFYEAR ,
// This is the total number of appointment properties supported (including recurring ones)
NUM_COLS_APP
};
/**
* Array of appointment fields used by WM plugin.
* **********************************************
*
* Recurring properties are appended at the end.
* @note Don't change the order of these properties!
*/
static CEPROPID PIMPR_props_app[] = {
PIMPR_SUBJECT ,
PIMPR_ALL_DAY_EVENT ,
PIMPR_SENSITIVITY ,
PIMPR_IS_RECURRING ,
PIMPR_REMINDER_SET ,
// PIMPR_REMINDER_SOUND_FILE ,
PIMPR_REMINDER_OPTIONS ,
// PIMPR_DURATION ,
PIMPR_LOCATION ,
PIMPR_START ,
PIMPR_END ,
PIMPR_BUSY_STATUS ,
PIMPR_REMINDER_MINUTES_BEFORE_START ,
// PIMPR_GLOBAL_OBJECT_ID ,
PIMPR_TIMEZONE ,
PIMPR_MEETING_STATUS ,
// PIMPR_MEETING_ORGANIZER_NAME ,
// PIMPR_MEETING_OWNER_CRITICAL_CHANGE ,
// PIMPR_ATTENDEES_CRITICAL_CHANGE ,
PIMPR_CATEGORIES ,
PIMPR_BODY_TEXT ,
// --- Recurring fields from here ---
PIMPR_RECURRING_TYPE ,
PIMPR_RECURRING_PATTERNSTARTDATE ,
PIMPR_RECURRING_PATTERNENDDATE ,
PIMPR_RECURRING_STARTTIME ,
PIMPR_RECURRING_ENDTIME ,
PIMPR_RECURRING_NOEND ,
PIMPR_RECURRING_OCCURRENCES ,
PIMPR_RECURRING_INTERVAL ,
PIMPR_RECURRING_DAYOFWEEKMASK ,
PIMPR_RECURRING_DAYOFMONTH ,
PIMPR_RECURRING_INSTANCE ,
// PIMPR_RECURRING_DURATION ,
PIMPR_RECURRING_MONTHOFYEAR
};
/**
* Array of appointment fields names for SIF format.
* Recurring fields are listed in recurrenceFields[] array.
* @note Don't change the order of these properties!
* This list MUST be synchronized with PIMPR_props_app array of CEPROPID fields.
*/
const wchar_t* appointmentFields[] = {
{L"Subject" }, // Returns or sets the subject for the Outlook item. This property corresponds to the MAPI property PR_SUBJECT. The Subject property is the default property for Outlook items.
{L"AllDayEvent" }, // True if the appointment is an all-day event (as opposed to a specified time). Corresponds to the All day event check box on the Appointment page of an AppointmentItem - MUST be set AFTER "Start" and "End" fields.
{L"Sensitivity" }, // Returns or sets the sensitivity for the Outlook item. Can be one of the following OlSensitivity constants: olConfidential(3), olNormal(0), olPersonal(1), or olPrivate(2). This property corresponds to the MAPI property PR_SENSITIVITY
{L"IsRecurring" }, // True if the appointment or task is a recurring appointment or task. When the GetRecurrencePattern method is used with an AppointmentItem or TaskItem object, this property is set to True
{L"ReminderSet" }, // True if a reminder has been set for this appointment, mail item or task.
// {L"ReminderSoundFile" }, // Returns or sets the path and filename of the sound file to play when the reminder occurs for the appointment or task. This property is only valid if the ReminderOverrideDefault and ReminderPlaySound properties are set to True
{L"ReminderOptions" }, // What actions to take when the reminder occurs. (LED=1, Vibrate=2, Dialog=4, Sound=8, Repeat=16)
// {L"Duration" }, // The length of an appointment in minutes.
{L"Location" }, // Returns or sets the specific office location (for example, Building 1 Room 1 or Suite 123) for the appointment. This property corresponds to the MAPI property PR_OFFICE_LOCATION
{L"Start" }, // Returns or sets the starting date and time for the appointment or journal entry. Use only in calendar
{L"End" }, // Returns or sets the end date and time of an appointment or journal entry. Use only on calendar
{L"BusyStatus" }, // Returns or sets the busy status of the user for the appointment. Can be one of the following OlBusyStatus constants: olBusy(2), olFree(0), olOutOfOffice(3), or olTentative(1).
{L"ReminderMinutesBeforeStart" }, // Returns or sets the number of minutes the reminder should occur prior to the start of the appointment
{L"Timezone" }, // The timezone of the appointment as a TIME_ZONE_INFORMATION structure
{L"MeetingStatus" }, // OlRemoteStatus can be one of these OlRemoteStatus constants.
// {L"MeetingOrganizerName" }, // The name of the person who organized the meeting.
// {L"MeetingOwnerCriticalChange" }, // A timestamp indicating that the meeting owner wants to update the meeting request. Required when sending an updated meeting request to attendees.
// {L"MeetingAttendeesCriticalChange" }, // A timestamp indicating that a meeting attendee wants to update the meeting request. Required when sending an updated meeting request back to the meeting owner.
{L"Categories" }, // Returns or sets the categories assigned to the Outlook item.
{L"Body" }, // Returns or sets the clear-text body of the Outlook item.
{NULL}
};
/*
* Method to populate the appointment XML structure.
* It get every property name and value and build the XML structure to exchange with server.
*
* @param appointmentStringItem : the string that will contain the xml structure
* @param pAppointment : the appointment object that contain every value
*
*/
void populateAppointmentStringItem(std::wstring &appointmentStringItem, IAppointment *pAppointment, BOOL isCRC) {
BSTR element = NULL ;
long elementLong = 0 ;
DATE startdate = NULL ;
DATE enddate = NULL ;
DATE date = NULL ;
wstring element_s;
//
// FOR RECURRENCE
// to get if a modification in the UTC goes into day before or after
// store the initial value of day and check the last value
//
int x = 0, y = 0, z = 0;
BOOL changeDay = FALSE, isBackward = FALSE;
BOOL changeYearBackward = FALSE, changeYearForward = FALSE;
VARIANT_BOOL variantBool = NULL; // 0==false -1==true
wchar_t tempDate [DIM_LOCAL_TEMP];
wchar_t* charBlob = NULL;
appointmentStringItem = TEXT("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
appointmentStringItem += TEXT("<appointment>");
// BSTR
pAppointment->get_Subject(&element);
element_s = wstring(element);
encodeSpecialChar(element_s);
appointmentStringItem += TEXT("<Subject>") + element_s + TEXT("</Subject>");
SysFreeString(element);
pAppointment->get_Location(&element);
element_s = wstring(element); encodeSpecialChar(element_s);
appointmentStringItem += TEXT("<Location>") + element_s + TEXT("</Location>");
SysFreeString(element);
pAppointment->get_Categories(&element);
element_s = wstring(element); encodeSpecialChar(element_s);
appointmentStringItem += TEXT("<Categories>") + element_s + TEXT("</Categories>");
SysFreeString(element);
pAppointment->get_ReminderSoundFile(&element);
element_s = wstring(element); encodeSpecialChar(element_s);
appointmentStringItem += TEXT("<ReminderSoundFile>") + element_s + TEXT("</ReminderSoundFile>");
SysFreeString(element);
pAppointment->get_Body(&element);
removeEndCarriage(&element);
element_s = wstring(element); encodeSpecialChar(element_s);
appointmentStringItem += TEXT("<Body>") + element_s + TEXT("</Body>");
SysFreeString(element);
// DATE
pAppointment->get_Start(&startdate);
pAppointment->get_End(&enddate);
/*
* see the start and end date. If the start is 00:00 and end is 23:59 the appointment is decided to be
* an all day event. So the AllDayEvent tag is put to 'true' only in the SIF structure. The format of the date
* is like the birthday: yyyy-MM-dd
*
*/
BOOL isAllDay = FALSE;
if (isWindowsMobile5()) {
pAppointment->get_AllDayEvent(&variantBool);
variantBool == -1 ? isAllDay = TRUE : isAllDay = FALSE;
if (isAllDay)
enddate -= 1; // to be decremented of a day if it is all day in windows mobile 5.
// This because the end date is 00:00:00 of the next day. we want the all day
// is represented as <startDate>2007-01-15</StartDate> and and date as the same
} else {
isAllDayEvent(startdate, enddate);
}
wsprintf(tempDate, TEXT(""));
double toCompare = MAX_DATE_DOUBLE;
double toCompare4000 = MAX_DATE_DOUBLE_4000;
SYSTEMTIME st;
if (startdate != toCompare) {
VariantTimeToSystemTime(startdate, &st);
x = st.wHour;
localTimeToUTC2(st);
y = st.wHour;
if (isAllDay) {
doubleToSystemTimeBirthday(tempDate, startdate);
} else {
doubleToSystemTime(tempDate, startdate);
}
}
appointmentStringItem = appointmentStringItem + TEXT("<Start>") + tempDate + TEXT("</Start>");
wsprintf(tempDate, TEXT(""));
if (enddate != toCompare) {
if (isAllDay) {
doubleToSystemTimeBirthday(tempDate, enddate);
} else {
doubleToSystemTime(tempDate, enddate);
}
}
appointmentStringItem = appointmentStringItem + TEXT("<End>") + tempDate + TEXT("</End>");
if (isAllDay) {
wsprintf(tempDate, TEXT("1")); // TRUE
} else {
wsprintf(tempDate, TEXT("0")); // TRUE
}
appointmentStringItem = appointmentStringItem + TEXT("<AllDayEvent>") + tempDate + TEXT("</AllDayEvent>");
pAppointment->get_ReminderSet(&variantBool);
wsprintf(tempDate, TEXT("%i"), variantBool);
normalizeBoolean(tempDate);
appointmentStringItem = appointmentStringItem + TEXT("<ReminderSet>") + tempDate + TEXT("</ReminderSet>");
// long
//pAppointment->get_Duration(&elementLong);
//wsprintf(tempDate, TEXT("%i"), elementLong);
//appointmentStringItem = appointmentStringItem + TEXT("<Duration>") + tempDate + TEXT("</Duration>");
pAppointment->get_BusyStatus(&elementLong);
wsprintf(tempDate, TEXT("%i"), elementLong);
appointmentStringItem = appointmentStringItem + TEXT("<BusyStatus>") + tempDate + TEXT("</BusyStatus>");
pAppointment->get_Sensitivity(&elementLong);
wsprintf(tempDate, TEXT("%i"), elementLong);
appointmentStringItem = appointmentStringItem + TEXT("<Sensitivity>") + tempDate + TEXT("</Sensitivity>");
pAppointment->get_ReminderOptions(&elementLong);
wsprintf(tempDate, TEXT("%i"), elementLong);
appointmentStringItem = appointmentStringItem + TEXT("<ReminderOptions>") + tempDate + TEXT("</ReminderOptions>");
pAppointment->get_ReminderMinutesBeforeStart(&elementLong);
wsprintf(tempDate, TEXT("%i"), elementLong);
appointmentStringItem = appointmentStringItem + TEXT("<ReminderMinutesBeforeStart>") + tempDate + TEXT("</ReminderMinutesBeforeStart>");
/******************************************************/
//Recurrence
VARIANT_BOOL isRecurring;
pAppointment->get_IsRecurring(&isRecurring);
wsprintf(tempDate, TEXT("%i"), isRecurring);
normalizeBoolean(tempDate);
appointmentStringItem = appointmentStringItem + TEXT("<IsRecurring>") + tempDate + TEXT("</IsRecurring>");
IRecurrencePattern *pRecurrence;
pAppointment->GetRecurrencePattern (&pRecurrence);
wstring recurrence = L"";
if (!isCRC || isRecurring == -1) { // variant bool to say TRUE
recurrence = getRecurrenceTags(pRecurrence, isRecurring, x, y, olFolderCalendar, startdate, isAllDay);
}
// handle recurrence and exceptions events
// wstring recurrence = getRecurrenceTags(pRecurrence, isRecurring, x, y, olFolderCalendar, startdate, isAllDay);
pRecurrence->Release();
appointmentStringItem += recurrence;
appointmentStringItem = appointmentStringItem + TEXT("</appointment>");
}
BOOL isAllDayEvent(DATE startdate, DATE enddate) {
SYSTEMTIME ststart, stend;
VariantTimeToSystemTime(startdate, &ststart);
VariantTimeToSystemTime(enddate, &stend);
BOOL ret = FALSE;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?