utilsrecurrence.cpp

来自「funambol window mobile客户端源代码」· C++ 代码 · 共 1,256 行 · 第 1/3 页

CPP
1,256
字号
 * @param x                 used to check the day shift
 * @param y                 used to check the day shift
 */
void parseRecurrenceTags(IRecurrencePattern *pRecurrence,
                         const wchar_t* ptrData,
                         DATE recurrenceStart,
                         int x, int y) {

    wchar_t* dummy                 = NULL;
    wchar_t* dummyEvent            = NULL;
    wstring  dummyEvent_s;
    VARIANT_BOOL isNotAllDayEvent  = TRUE;
    long            recurrenceType = 0,
                    interval       = 0,
                    monthOfYear    = 0,
                    dayOfMonth     = 0,
                    dayOfWeekMask  = 0,
                    instance       = 0;

    //
    // 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 z = 0;
    BOOL changeDay = FALSE, isBackward = FALSE;
    BOOL changeYearBackward = FALSE, changeYearForward = FALSE;
    //
    // Modification to get right information about changing day, month...
    //
    TIME_ZONE_INFORMATION tmz;
    GetTimeZoneInformation(&tmz);

    //----- server -> client  => do not change date
    z = (x-y) < 0 ? (x-y)*(-1) : (x-y) ;

    //
    // Change day? Backward and Forward are inverted because it is from utc to localtime
    //
    changeDay = z > 12 ? TRUE : FALSE;
    if (changeDay) {
        if (tmz.Bias < 0)
            isBackward = FALSE;
        else
            isBackward = TRUE;
    }

    dummyEvent = getElementContent(ptrData, TEXT("RecurrenceType"), NULL);
    if (dummyEvent != NULL && wcstol(dummyEvent, &dummy, 0) >= 0) {
        pRecurrence->put_RecurrenceType(wcstol(dummyEvent, &dummy, 0));
        delete [] dummyEvent;dummyEvent=NULL;
    }

    dummyEvent = getElementContent(ptrData, TEXT ("Interval"), NULL);
    if (dummyEvent != NULL && wcstol(dummyEvent, &dummy, 0) > 0) {
        pRecurrence->put_Interval(wcstol(dummyEvent, &dummy, 0));
        delete [] dummyEvent;dummyEvent=NULL;
    }

    //
    // Day of Month
    //
    dummyEvent = getElementContent(ptrData, TEXT ("DayOfMonth"), NULL);
    if (dummyEvent != NULL && wcstol(dummyEvent, &dummy, 0) > 0) {
        dayOfMonth = wcstol(dummyEvent, &dummy, 0);
        if (changeDay) {
            if (isBackward) {
                dayOfMonth = dayOfMonth - 1;
                if (dayOfMonth == 0) {
                    if (monthOfYear == 5 || monthOfYear == 7 || monthOfYear == 10) {
                        // if May, July, October the month before has 30 days
                        dayOfMonth = 30;
                    } else {
                        dayOfMonth = 31;
                    }
                    changeYearBackward = TRUE;
                }
            } else { // is
                dayOfMonth = dayOfMonth + 1;
                if (dayOfMonth >  31  ||
                      (dayOfMonth == 31 &&
                        (monthOfYear == 4 || monthOfYear == 6 || monthOfYear == 9)
                       )
                    ) {
                    dayOfMonth = 1;
                    changeYearForward = TRUE;
                }
            }
        }; //end if(changeDay)

        pRecurrence->put_DayOfMonth(dayOfMonth);
        delete [] dummyEvent;dummyEvent=NULL;
    }

    //
    // Month of Year
    //
    dummyEvent = getElementContent(ptrData, TEXT ("MonthOfYear"), NULL);
    if (dummyEvent != NULL && wcstol(dummyEvent, &dummy , 0) > 0) {
        monthOfYear = wcstol(dummyEvent, &dummy , 0);
        if (changeYearBackward) {
            monthOfYear = monthOfYear - 1;
            if (monthOfYear == 0) {
                monthOfYear = 12;
            }
        } else if (changeYearForward) {
            monthOfYear = monthOfYear + 1;
            if (monthOfYear > 12) {
                monthOfYear = 1;
            }
        }
        pRecurrence->put_MonthOfYear(monthOfYear);
        delete [] dummyEvent;dummyEvent=NULL;
    }

    //
    // DayOfWeekMask
    //
    dummyEvent = getElementContent(ptrData, TEXT ("DayOfWeekMask"), NULL);
    if (dummyEvent != NULL && wcstol(dummyEvent, &dummy, 0) > 0) {
        dayOfWeekMask = wcstol(dummyEvent, &dummy, 0);
        if (changeDay) {
            if (isBackward) {
                dayOfWeekMask = convertDayOfWeekMaskBackward(dayOfWeekMask);
            } else {
                dayOfWeekMask = convertDayOfWeekMaskForward(dayOfWeekMask);
            }
        }

        pRecurrence->put_DayOfWeekMask(dayOfWeekMask);
        delete [] dummyEvent;dummyEvent=NULL;
    }

    dummyEvent = getElementContent(ptrData, TEXT ("Instance"), NULL);
    if (dummyEvent) {
        if (wcstol(dummyEvent, &dummy, 0) > 0) {
            pRecurrence->put_Instance(wcstol(dummyEvent, &dummy, 0));
        }
        delete [] dummyEvent; dummyEvent=NULL;
    }

    // Pattern Start Date
    // -------------------
    // We use recurrenceStart instead of PatternStartDate
    // to handle timezone changes.
    // PatternStartDate is used only as a backup if the others are not available
    if (!recurrenceStart) {
        dummyEvent = getElementContent(ptrData, TEXT("PatternStartDate"), NULL);
        if (dummyEvent) {
            // If is not empty, get it
            if (*dummyEvent) {
                recurrenceStart = getDATEFromString(dummyEvent);
            }
            delete [] dummyEvent; dummyEvent=NULL;
        }
    }
    // Make sure the date is without the time part
    recurrenceStart = (int)recurrenceStart;

    pRecurrence->put_PatternStartDate(recurrenceStart);

    if (dummyEvent) { delete [] dummyEvent; dummyEvent = NULL; }

    //VARIANT_BOOL -- NoEndDate
    dummyEvent = getElementContent(ptrData, TEXT ("NoEndDate"), NULL);

    if (dummyEvent != NULL &&
        (wcscmp(dummyEvent, TEXT("1")) == 0 ||
         wcscmp(dummyEvent, TEXT("-1")) == 0 ||
         wcscmp(dummyEvent, TEXT("True")) == 0)) {
        pRecurrence->put_NoEndDate(VARIANT_TRUE);

    } else {
        pRecurrence->put_NoEndDate(VARIANT_FALSE);

        //Pattern End Date
        dummyEvent = getElementContent(ptrData, TEXT ("PatternEndDate"), NULL);
        // If not null and not empty, parse it
        if (dummyEvent && *dummyEvent) {
            DATE en = getDATEFromString(dummyEvent);
            pRecurrence->put_PatternEndDate(en);
            delete [] dummyEvent; dummyEvent = NULL;
        }

    }
    // Occurrences
    //
    dummyEvent = getElementContent(ptrData, TEXT ("Occurrences"), NULL);
    if (dummyEvent != NULL && wcstol(dummyEvent, &dummy, 0) > 0) {
        pRecurrence->put_Occurrences(wcstol(dummyEvent, &dummy , 0));
        delete [] dummyEvent; dummyEvent = NULL;
    }

}


/*
* Return the oid of the new appointment just inserted
*/
long createAppointmentFromException(IAppointment* pAppointment, RecurrenceException rec, IP_OUTLOOK_APP* polApp) {

    IAppointment* pAppointmentCopy, *pAppointmentNew;
    pAppointment->Copy(&pAppointmentCopy);
    pAppointmentCopy->Save();
    long oid = 0;
    pAppointmentCopy->get_Oid(&oid);
    pAppointmentCopy->Release();

    polApp->GetItemFromOid (oid, (IDispatch**)&pAppointmentNew);

    if (pAppointmentNew) {
        DATE originaldate = rec.getOriginalDate();

        DATE start = 0, end = 0;
        pAppointment->get_Start(&start);
        pAppointment->get_End(&end);

        DATE offset = end - start;
        end = (originaldate + offset);

        pAppointmentNew->ClearRecurrencePattern();
        pAppointmentNew->put_Start(originaldate);
        pAppointmentNew->put_End(end);
        pAppointmentNew->Save();
        pAppointmentNew->Release();
    }

    return oid;

}

/*
* The file contains the oid of the appointment whose crc must be set to 0 during the
* creation of the cache file. It means to send to the server the right apppointmnet
* at the next sync
*/
void writeOidToReset(vector<long> oids, const wchar_t* wpath) {

    wstring filename(L"appOidToReset.dat");
    wstring path(wpath);
    path += L"\\";
    path += filename;

    FILE* f;
    f = _wfopen(path.c_str(), L"w+");

    if (!f)
        return;

    int oidLength = oids.size();

    for (int i = 0; i < oidLength; i++) {
        long currentLongOid = oids[i];
        fwprintf(f, TEXT("<oid>%i</oid>\n"), currentLongOid);
    }
    fflush(f);
    fclose(f);
}



void setWinRecurrenceProps(WinRecurrence& winRec, const CEPROPVAL* prgPropvalPoom, int firstProperty,
                           const wstring& start, const bool isAllDay, bool isAppointment) {

    wstring pStart, pEnd, startTime, endTime;
    
    // If using timezone
    bool toUTC = true;
    if (isAllDay || winRec.hasTimezone()) {
        toUTC = false;
    }

    //
    // Get all properties from MAPI.
    //
    int i = firstProperty;
    int recType       = getIntPropertyFromMapi(&prgPropvalPoom[i++]);
    pStart            = getDatePropertyFromMapi(&prgPropvalPoom[i++], toUTC, isAllDay);
    if (isAppointment) { // startTime and endTime are not valid in recurrent tasks
        pEnd              = getDatePropertyFromMapi(&prgPropvalPoom[i++], toUTC, false);
        startTime         = getDatePropertyFromMapi(&prgPropvalPoom[i++], toUTC, false);
        endTime           = getDatePropertyFromMapi(&prgPropvalPoom[i++], toUTC, false);
    } else {
        pEnd              = getDatePropertyFromMapi(&prgPropvalPoom[i++], toUTC, true);   
    }
    int noEndDate     = getIntPropertyFromMapi(&prgPropvalPoom[i++]);
    int occurrences   = getIntPropertyFromMapi(&prgPropvalPoom[i++]);
    int interval      = getIntPropertyFromMapi(&prgPropvalPoom[i++]);
    int dayOfWeekMask = getIntPropertyFromMapi(&prgPropvalPoom[i++]);
    int dayOfMonth    = getIntPropertyFromMapi(&prgPropvalPoom[i++]);
    int instance      = getIntPropertyFromMapi(&prgPropvalPoom[i++]);
    //int duration    = getIntPropertyFromMapi(&prgPropvalPoom[i++]);
    int monthOfYear   = getIntPropertyFromMapi(&prgPropvalPoom[i++]);


    //
    // Recurrence Conversions.
    //
    // Yearly interval = 1 (for compatibility)
    if (recType > 4) {
        interval = 1;
    }
    // For compatibility: weekly with interval = 0 is not correct...
    if ((recType == 1) && (interval == 0)) {
        interval = 1;
    }
    
    // PatternStartDate
    if (!isAllDay) {
        if (toUTC) {
            // OLD STYLE: get patternStart from start (use exactly the same).           **** TODO: remove? ****
            if (start != TEXT("")) { 
                pStart = start; 
            }
        } else {
            // "PatternStartDate" is composed by PatternStartDate + StartTime
            if (pStart.size() >= 8 && startTime.size() >= 15) {
                pStart  = pStart.substr(0, 8);      // the start date
                pStart += TEXT("T");
                pStart += startTime.substr(9, 6);   // the start time
            }
        }
    }


    // For compatibility
    if (noEndDate) {
        occurrences = 0;
        pEnd = TEXT("");
    }
    else {
        DATE pEndDate = 0;
        systemTimeToDouble(pEnd.c_str(), &pEndDate, NULL);
        if (pEndDate && pEndDate < LIMIT_MAX_DATE) {
            if (toUTC) {
                // OLD STYLE: Correct with the exact hours from "Start" (bug #3688)      **** TODO: remove? ****
                DATE startDate = NULL;
                systemTimeToDouble(start.c_str(), &startDate, NULL);
                if (startDate) {
                    double hours = startDate - (int)startDate;
                    pEndDate = (int)pEndDate + hours;
                    wchar_t tmp[30];
                    doubleToSystemTime(tmp, pEndDate);
                    pEnd = tmp;
                }
            }
            else {
                // "PatternEndDate" is composed by PatternEndDate + StartTime 
                // (note: StartTime, not EndTime!)
                if (pEnd.size() >= 8 && startTime.size() >= 15) {
                    pEnd = pEnd.substr(0, 8);        // the end date
                    pEnd += TEXT("T");
                    pEnd += startTime.substr(9, 6);  // the start time
                }
            }
        }
        else {
            // To avoid PatternEndDate = 4501-01-01
            pEnd = TEXT("");
        }
    }

    // CHANGE-DAY to UTC: modify monthOfYear / dayOfMonth / dayOfWeekMask.
    // All-day events don't need conversions.
    if (toUTC) {
        changeDay(L"UTC", start, &monthOfYear, &dayOfMonth, &dayOfWeekMask);
    }


    //
    // Fill WinRec with all properties.
    //
    int j=0;
    winRec.setIntProperty(recurrenceFields[j++], recType      );
    winRec.setProperty(recurrenceFields[j++],    pStart       );
    winRec.setProperty(recurrenceFields[j++],    pEnd         );
    j++;       // "startTime" is not used, but keep the sequence
    j++;       // "endTime"   is not used, but keep the sequence    
    winRec.setIntProperty(recurrenceFields[j++], noEndDate    );
    winRec.setIntProperty(recurrenceFields[j++], occurrences  );
    winRec.setIntProperty(recurrenceFields[j++], interval     );
    winRec.setIntProperty(recurrenceFields[j++], dayOfWeekMask);
    winRec.setIntProperty(recurrenceFields[j++], dayOfMonth   );
    winRec.setIntProperty(recurrenceFields[j++], instance     );
    // winRec.setIntProperty(recurrenceFields[j++],   duration   );
    winRec.setIntProperty(recurrenceFields[j++], monthOfYear  );
}






int setMAPIRecurrenceProps(CEPROPVAL* prgPropvalPoom, const int propsNumber,
                           WinRecurrence& winRec, const wstring& start, const wstring& end,
                           const bool isAllDay, const TIME_ZONE_INFORMATION* tzInfo,
                           bool isAppointment) {

    // The index of properties, is updated for every prop inserted and thus returned.
    int incNumProp = propsNumber;

    // "Start" is mandatory
    if (start == TEXT("")) {
        LOG.error("Cannot save recurrence, \"Start\" property is missing.");
        return incNumProp;
    }

    // If using timezone, data is already in local time.
    bool toLocal = true;
    if (isAllDay || winRec.hasTimezone()) {
        toLocal = false;
    }

    int recType       = -1;
    int noEndDate     = -1;
    int occurrences   = -1;
    int interval      = -1;
    int dayOfWeekMask = -1;
    int dayOfMonth    = -1;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?