utilsrecurrence.cpp
来自「funambol window mobile客户端源代码」· C++ 代码 · 共 1,256 行 · 第 1/3 页
CPP
1,256 行
int instance = -1;
//int duration = -1;
int monthOfYear = -1;
wstring pStart, pEnd, startTime, endTime;
int durationInMinutes = 0; // the duration of the recurrence
//
// Get all props from WinRecurrence.
//
int i=0;
winRec.getIntProperty(recurrenceFields[i++], &recType);
winRec.getProperty (recurrenceFields[i++], pStart);
winRec.getProperty (recurrenceFields[i++], pEnd);
i++; // "startTime" is not used, but keep the sequence
i++; // "endTime" is not used, but keep the sequence
winRec.getIntProperty(recurrenceFields[i++], &noEndDate);
winRec.getIntProperty(recurrenceFields[i++], &occurrences);
winRec.getIntProperty(recurrenceFields[i++], &interval);
winRec.getIntProperty(recurrenceFields[i++], &dayOfWeekMask);
winRec.getIntProperty(recurrenceFields[i++], &dayOfMonth);
winRec.getIntProperty(recurrenceFields[i++], &instance);
//winRec.getIntProperty(recurrenceFields[i++], &duration);
winRec.getIntProperty(recurrenceFields[i++], &monthOfYear);
// The boolean need to take care about the appointment synced from a 7.0.x client
// against a server 6.5.x that doesn't support the timezone.
// the data were store with local time
if (pStart.find(TEXT("Z")) == wstring::npos) {
toLocal = false;
}
//
// Recurrence Conversions.
//
if (recType<0 || recType>6) {
// RecurrenceType is mandatory.
LOG.error("Error setting recurrenceType: %d not supported", recType);
return incNumProp;
}
if (interval < 1) {
interval = 1;
}
// ---- PatternStartDate ----
if (toLocal) {
// OLD STYLE (v6.5): get value from Start if not empty.
// Used by allday, tasks, and also to keep compatibility on incoming items.
pStart = start;
}
else {
// Extract pStart (only date) & startTime (only time)
if (pStart == TEXT("")) {
// pStart can be missing, for example in vCal 1.0
pStart = getPatternStartDateFromStart(start, tzInfo);
}
replaceAll(L"-", L"", pStart); // Safe: to accept SIF format "yyyy-mm-dd" too.
if (pStart.size() >= 15) {
startTime = TEXT("18991230T"); // stands for the date = 0
startTime += pStart.substr(9, 6);
}
if (pStart.size() >= 8) {
pStart = pStart.substr(0, 8);
pStart += TEXT("T000000");
}
}
// ---- PatternEndDate ----
if (!toLocal) {
// Extract pEnd (only date)
if (pEnd.size() >= 8) {
replaceAll(L"-", L"", pEnd); // Safe: to accept SIF format "yyyy-mm-dd" too.
pEnd = pEnd.substr(0, 8);
pEnd += TEXT("T000000");
}
}
// ---- EndTime ----
// It's now mandatory, if we set the startTime. We have to calculate it.
if (startTime.size() > 0) {
// "Duration" is constant, can be retrieved from (Start - End)
DATE startDate, endDate, startTimeDate;
stringTimeToDouble(start, &startDate); // not converting to local time
stringTimeToDouble(end, &endDate);
stringTimeToDouble(startTime, &startTimeDate);
DATE endTimeDate = startTimeDate + (endDate - startDate);
// the end time date must be calculated only for the time. The date must be
// the default one 18991230, so the first part is deleted
endTimeDate = endTimeDate - (int)endTimeDate;
WCHAR tmp[20];
doubleToSystemTimeHourZero(tmp, endTimeDate, FALSE, FALSE); // not converting to UTC
endTime = tmp;
// calculate the duration of the recurrence: this could be 1,0416666667 that is 25 hours
// so get the 1, that means 1 day that are 1440 minutes
DATE val = endDate - startDate;
durationInMinutes = (int)val * 1440;
// then the 0,41666667 * 1440 that means how many minutes used in a day
durationInMinutes += round((val - (int)val) * 1440);
}
// CHANGE-DAY to Local: modify monthOfYear / dayOfMonth / dayOfWeekMask.
// All-day event don't need conversions.
if (toLocal) {
changeDay(TEXT("Local"), start, &monthOfYear, &dayOfMonth, &dayOfWeekMask);
}
//
// Set all props to MAPI.
// If using timezone, values should be in local time - however all formats are accepted.
// NOTE: the order is important!!!
//
setIntPropertyToMapi(&prgPropvalPoom[incNumProp++], PIMPR_RECURRING_TYPE, recType);
FILETIME date = getDatePropertyFromString(pStart, isAllDay);
setDatePropertyToMapi(&prgPropvalPoom[incNumProp++], PIMPR_RECURRING_PATTERNSTARTDATE, date);
if ((noEndDate != 1) && (occurrences <= 0)) {
// Set PatternEndDate only if Occurrences not found or wrong.
if (pEnd.size() > 0) {
date = getDatePropertyFromString(pEnd); // Expected UTC value...
setDatePropertyToMapi(&prgPropvalPoom[incNumProp++], PIMPR_RECURRING_PATTERNENDDATE, date);
}
}
if (startTime.size() > 0) {
date = getDatePropertyFromString(startTime, isAllDay);
setDatePropertyToMapi(&prgPropvalPoom[incNumProp++], PIMPR_RECURRING_STARTTIME, date);
}
/* the end time is not used because the durationInMinutes substitutes this value
if (endTime.size() > 0) {
date = getDatePropertyFromString(endTime, isAllDay);
setDatePropertyToMapi(&prgPropvalPoom[incNumProp++], PIMPR_RECURRING_ENDTIME, date);
}
*/
if (durationInMinutes > 0) {
setIntPropertyToMapi(&prgPropvalPoom[incNumProp++], PIMPR_RECURRING_DURATION, durationInMinutes);
}
if (noEndDate > 0) {
setIntPropertyToMapi(&prgPropvalPoom[incNumProp++], PIMPR_RECURRING_NOEND, noEndDate);
}
if ((noEndDate != 1) && (occurrences > 0)) {
setIntPropertyToMapi(&prgPropvalPoom[incNumProp++], PIMPR_RECURRING_OCCURRENCES, occurrences);
}
if (interval > 0) {
setIntPropertyToMapi(&prgPropvalPoom[incNumProp++], PIMPR_RECURRING_INTERVAL, interval);
}
if (dayOfWeekMask > 0) {
setIntPropertyToMapi(&prgPropvalPoom[incNumProp++], PIMPR_RECURRING_DAYOFWEEKMASK, dayOfWeekMask);
}
if (dayOfMonth > 0) {
setIntPropertyToMapi(&prgPropvalPoom[incNumProp++], PIMPR_RECURRING_DAYOFMONTH, dayOfMonth);
}
if (instance > 0) {
setIntPropertyToMapi(&prgPropvalPoom[incNumProp++], PIMPR_RECURRING_INSTANCE, instance);
}
if (monthOfYear > 0) {
setIntPropertyToMapi(&prgPropvalPoom[incNumProp++], PIMPR_RECURRING_MONTHOFYEAR, monthOfYear);
}
// Return the updated number of properties.
return incNumProp;
}
wstring getPatternStartDateFromStart(const wstring& start, const TIME_ZONE_INFORMATION* tzInfo) {
if (start.find(L"Z", 0) == wstring::npos) {
// "Start" is in local time, so PatternStart is the same.
return start;
}
if (start.find(L"-", 0) != wstring::npos) {
// Start is in old SIF style: "yyyy-mm-dd".
wstring ret = start;
replaceAll(L"-", L"", ret);
ret += L"T000000";
return ret;
}
if (start.size() == 8) {
// Start is in format "yyyymmdd" (allday).
return start;
}
// Backup the current tzInfo of the System
bool tzBackuped = false;
TIME_ZONE_INFORMATION backupTzInfo;
if (tzInfo) {
GetTimeZoneInformation(&backupTzInfo);
// Optimization: do it ONLY if tz is different.
if (!isSameTimezone(tzInfo, &backupTzInfo)) {
SetTimeZoneInformation(tzInfo);
tzBackuped = true;
}
}
SYSTEMTIME t;
DATE startDate = 0;
WCHAR tmp[20];
systemTimeToDouble(start.c_str(), &startDate, NULL); // converts to local time
VariantTimeToSystemTime(startDate, &t);
wsprintf(tmp, TEXT("%d%02d%02dT%02d%02d%02d"), t.wYear, t.wMonth, t.wDay,
t.wHour, t.wMinute, t.wSecond);
// Restore correct tzInfo.
if (tzInfo && tzBackuped) {
SetTimeZoneInformation(&backupTzInfo);
}
wstring patternStart = tmp;
return patternStart;
}
bool changeDay(const wstring& dest, const wstring& start,
int* monthOfYear, int* dayOfMonth, int* dayOfWeekMask)
{
DATE date = 0;
SYSTEMTIME time, localTime, utcTime;
// This call gets 'date' ALWAYS in local time... *** verify if true on WM! **** TODO!
systemTimeToDouble (start.c_str(), &date, NULL);
VariantTimeToSystemTime(date, &time);
localTime = time;
localTimeToUTC2(time);
utcTime = time;
// Day to be changed!
if (localTime.wDay != utcTime.wDay) {
if (dest == L"Local") {
time = localTime;
}
// MonthOfYear: get from Start
if (*monthOfYear != 0 && *monthOfYear != -1) {
*monthOfYear = time.wMonth;
}
// DayOfMonth: get from Start
if (*dayOfMonth != 0 && *dayOfMonth != -1) {
*dayOfMonth = time.wDay;
}
// DayOfWeekMask: shift the mask
if (*dayOfWeekMask != 0 && *dayOfWeekMask != -1) {
// Calculate if forward or backward 1 day.
TIME_ZONE_INFORMATION tmz;
GetTimeZoneInformation(&tmz);
bool forward;
if (dest == L"Local") {
if (tmz.Bias < 0) forward = true;
else forward = false;
}
else {
if (tmz.Bias < 0) forward = false;
else forward = true;
}
// Forward = left shift.
if (forward) {
*dayOfWeekMask = *dayOfWeekMask << 1;
if (*dayOfWeekMask > 127) {
*dayOfWeekMask -= 127;
}
}
// Backward = right shift.
else {
if (*dayOfWeekMask & 1) {
*dayOfWeekMask += 127;
}
*dayOfWeekMask = *dayOfWeekMask >> 1;
}
}
return true;
}
return false;
}
ArrayList* getRecurrenceProperties(){
int i = 0;
ArrayList* props = new ArrayList();
while (recurrenceFields[i]){
if (wcscmp (recurrenceFields[i] , L"StartTime") == 0 ||
wcscmp (recurrenceFields[i] , L"EndTime") == 0 ) {
i++;
}else{
Property prop;
char* field = toMultibyte(recurrenceFields[i]);
prop.setPropName(field);
props->add(prop);
delete [] field;
i++;
}
}
return props;
}
// ************************** TODO: remove? **************************
/*
* delete the occurrences of the recurrence if there are any between them
*/
//void deleteIntraOccurrences(IRecurrencePattern* pRecurrence, DATE originalDate, DATE startDate) {
//
// IAppointment* pExAppointment;
//
// if (originalDate > startDate) {
// for (originalDate-=1; originalDate > startDate; originalDate-=1) {
//
// pRecurrence->GetOccurrence(originalDate, &pExAppointment);
// if (pExAppointment) {
// pExAppointment->Delete();
// pExAppointment->Release();
// }
// }
// } else {
// for (originalDate+=1; originalDate < startDate; originalDate+=1) {
//
// pRecurrence->GetOccurrence(originalDate, &pExAppointment);
// if (pExAppointment) {
// pExAppointment->Delete();
// pExAppointment->Release();
// }
// }
// }
//}
//vector<RecurrenceException> getExceptionList(IRecurrencePattern* pRecurrence,
// const wchar_t* ptrData,
// const wchar_t* action) {
//
// wchar_t* dummy = NULL;
// wchar_t* dummyEvent = NULL;
// wstring dummyEvent_s;
// VARIANT_BOOL isNotAllDayEvent = TRUE;
// unsigned int pos = 0;
//
// vector<RecurrenceException> listExceptions;
//
// unsigned int previous = pos;
// while ((dummyEvent = getElementContent(&ptrData[pos], (wchar_t*)action, &pos)) != NULL) {
//
// if (wcscmp(dummyEvent, TEXT("")) == 0) {
// pos += previous;
// previous = pos;
// continue;
//
// }
//
// BOOL isAllDayFormat = FALSE;
// DATE originalDate;
//
// RecurrenceException rec;
//
// isAllDayFormat = isDateForAllDayEventFormat(dummyEvent);
// if (isAllDayFormat) {
// systemTimeToDoubleBirthFormat(dummyEvent, &originalDate, TEXT("START")); // put 00:00 for the date
// } else {
// systemTimeToDouble(dummyEvent, &originalDate, NULL);
// }
//
// rec.setOriginalDate(originalDate);
//
// if (wcscmp(action, EXCLUDE_DATE) == 0) {
// rec.setIsDeleted(TRUE);
// } else {
// rec.setIsDeleted(FALSE);
// rec.setAllDayEvent(isAllDayFormat);
// }
//
// pos += previous;
// previous = pos;
//
// listExceptions.push_back(rec);
// }
//
// return listExceptions;
//}
/*
* Try to check if exists already an occurrence in that date...
* If exists it delete the existing ont to insert the other appointment exception
*/
//BOOL checkAlreadyAnException(IRecurrencePattern* pRecurrence, DATE originalDate, DATE startDate) {
//
// IAppointment* pApp;
// pRecurrence->GetOccurrence(startDate, &pApp);
//
// if (pApp) {
//
// if ((int)originalDate - (int)startDate) {
// LOG.info("An exception of the calendar already exists. Delete it to insert the new one");
// pApp->Delete();
// pApp->Release();
// return TRUE;
// }
// }
//
// return FALSE;
//
//}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?