mailclient2server.cpp

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

CPP
1,974
字号
/*
 * 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/mail/MailClient2Server.h"
#include "pim/mail/MailInfo.h"
#include "pim/mail/MailItem.h"
#include "pim/mail/MailClientData.h"
#include "pim/mail/MailSyncSource.h"

#include "pim/account.h"

#include "pim/utils.h"
#include "base/util/utils.h"
#include "base/util/ArrayList.h"
#include <mapidefs.h>
#include <mapicode.h>
#include <mapitags.h>
#include <mapix.h>
#include <mapiutil.h>
#include <cemapi.h>
#include "wtypes.h"

#include "HwndFunctions.h"

//------------------------------------------------------------- Typedef
enum {
    eeePR_ENTRYID,
    eeePR_MESSAGE_FLAGS,
    eeePR_LAST_MODIFICATION_TIME,
    eeeNUM_COLS};

// These tags represent the message information we would like to pick up
static SizedSPropTagArray(eeeNUM_COLS, endSync) =
{
    eeeNUM_COLS,
    PR_ENTRYID,                       // entry id
    PR_MESSAGE_FLAGS,
    PR_LAST_MODIFICATION_TIME        //

};

enum {
    ePR_ENTRYID,
    ePR_MESSAGE_FLAGS,
    //MM
    ePR_LAST_MODIFICATION_TIME,
    ePR_SUBJECT,
    ePR_SUBJECT_PREFIX,
    ePR_MESSAGE_SIZE,
    ePR_SENDER_NAME,
    ePR_SENDER_EMAIL_ADDRESS,
    ePR_HASATTACH,
    ePR_MESSAGE_DELIVERY_TIME,
    ePR_CUSTOM_MESSAGE_ID,
    ePR_CUSTOM_MESSAGE_HEADER,
    ePR_REPLY_RECIPIENT_NAMES,
    ePR_REPLY_RECIPIENT_ENTRIES,
    ePR_CLIENT_SUBMIT_TIME,
    ePR_IMPORTANCE,
    //MM
    NUM_COLS};

// These tags represent the message information we would like to pick up
static SizedSPropTagArray(NUM_COLS, properties) =
{
    NUM_COLS,
    PR_ENTRYID,                         // entry id
    PR_MESSAGE_FLAGS,
    //MM
    PR_LAST_MODIFICATION_TIME,          //
    PR_SUBJECT,                         // mail Subject
    PR_SUBJECT_PREFIX,
    PR_MESSAGE_SIZE,                    // sum of the size of every property of the object
    PR_SENDER_NAME,                     // "Marco "
    PR_SENDER_EMAIL_ADDRESS,            // From  "Marco <magi@libero.it>
    PR_HASATTACH,
    PR_MESSAGE_DELIVERY_TIME,
    PR_CUSTOM_MESSAGE_ID,
    PR_CUSTOM_MESSAGE_HEADER,
    PR_REPLY_RECIPIENT_NAMES,
    PR_REPLY_RECIPIENT_ENTRIES,
    PR_CLIENT_SUBMIT_TIME,
    PR_IMPORTANCE  

};

enum {
    eePR_ENTRYID,
    eePR_LAST_MODIFICATION_TIME,
    eePR_DISPLAY_NAME,
    eePR_MESSAGE_FLAGS,
    eeNUM_COLS};

// These tags represent the message information we would like to pick up
static SizedSPropTagArray(eeNUM_COLS, Columns) =
{
    eeNUM_COLS,
    PR_ENTRYID,
    PR_LAST_MODIFICATION_TIME,
    PR_DISPLAY_NAME,
    PR_MESSAGE_FLAGS
};

//--------------------------------------------------------- Local variables

static long mailAll;
static long mailNew;
static long mailUpdated;
static long mailDeleted;
static wchar_t accName[256];
//--------------------------------------------------------- Constructors

MailClient2Server::MailClient2Server() {
    mailAll = -2;
    arrayIndex = 0;
    allTot = 0;
    elementIndex = -2;

    mailNew = -2;
    mailUpdated = -2;
    mailDeleted = -2;
    folderNumber = 0;
    // deletedMessages = new ArrayList();

    entryListArray = NULL;
    folderToSync = NULL;
    newMessagesArray = NULL;
    updatedMessagesArray = NULL;
    deletedMessagesArray = NULL;
    accName[0] = 0;
    
    allTotalUpdatedAndDeleted = 0;
    allTotalNew = 0;
}

MailClient2Server::~MailClient2Server() {
    //if (mailMessage) {
    //    delete mailMessage; mailMessage = NULL;
    //}
    LOG.debug("Deleting objects...");
    if (folderToSync) {
        delete [] folderToSync; folderToSync = NULL;
    }
    if (newMessagesArray) {
        LOG.debug("Deleting object newMessagesArray");
        for (int i = 0; i < folderNumber; i++) {
            if (newMessagesArray[i].cValues > 0) {
                MAPIFreeBuffer(newMessagesArray[i].lpbin);
            }
        }
        delete [] newMessagesArray; newMessagesArray = NULL;
        LOG.debug("Deleting object newMessagesArray end");
    }
    if (updatedMessagesArray) {
        LOG.debug("Deleting object updatedMessagesArray");
        for (int i = 0; i < folderNumber; i++) {
            if (updatedMessagesArray[i].cValues > 0) {
                MAPIFreeBuffer(updatedMessagesArray[i].lpbin);
            }
        }
        delete [] updatedMessagesArray; updatedMessagesArray = NULL;
        LOG.debug("Deleting object updatedMessagesArray end");
    }
    if (deletedMessagesArray) {
        delete [] deletedMessagesArray; 
        deletedMessagesArray = NULL;
    }
    if (entryListArray) {
        LOG.debug("Deleting object entryListArray");
        for (int i = 0; i < folderNumber; i++) {
            if (entryListArray[i].cValues > 0) {
                MAPIFreeBuffer(entryListArray[i].lpbin);
            }
        }
        delete [] entryListArray; entryListArray = NULL;
        LOG.debug("Deleting object entryListArray end");
    }
    accName[0] = 0;
}


/*
* The name of the object has to follow the rule in which the name is
* <FolderName>/<id>
* i.e. I/AAAAABBBCCC   Inbox/AAAAABBBCCC
*
* isUpdate: For update only, the completeObject send all the complete message for Draft folder.
* The others sends only the information extra files
*
* keyOnly: used to get only the key of the item and not the complete. It is used to delete all the items
* before a refresh-from-server
*
*/

MailClientData* MailClient2Server::completeObject(IMessage* pmsg, wchar_t folder, BOOL isUpdate, BOOL keyOnly) {

    SPropValue rgprops[2] = {0};
    ULONG    cProps   = 0;
    ULONG    cmsgValue =  0;
    SPropValue* msgprops = NULL;
    bool read = false;
    char * hdrs = NULL;
    wchar_t *id = NULL;
    MailClientData* mcd = NULL;
    HRESULT hr;

    hr = pmsg->GetProps ((LPSPropTagArray)&properties, MAPI_UNICODE, &cmsgValue,
       &msgprops);
    EXIT_ON_FAILED (hr);

    if ( !msgprops ) {
        LOG.error("completeObject: can't get message props.");
        return NULL;
    }

    if (msgprops[ePR_ENTRYID].ulPropTag != PR_ENTRYID) {
        LOG.error("entry id not found.");
        return NULL;
    }

    id = convertBinaryToWChar(msgprops[ePR_ENTRYID].Value.bin, folder);

    mcd = new MailClientData(id);
    delete [] id;
    id = NULL;

    mcd->setParent(folder);

    if (keyOnly) {
        return mcd;
    }

    //********************* Set EmailData properties ***************************

    // Reset flags (is it still needed?)
    mcd->getEmailData()->setRead(false);
    mcd->getEmailData()->setForwarded(false);
    mcd->getEmailData()->setReplied(false);
    mcd->getEmailData()->setReceived(false);
    mcd->getEmailData()->setCreated(false);
    mcd->getEmailData()->setDeleted(false);
    mcd->getEmailData()->setFlagged(false);

    if (msgprops[ePR_MESSAGE_FLAGS].ulPropTag == PR_MESSAGE_FLAGS) {
        if (msgprops[ePR_MESSAGE_FLAGS].Value.ul & MSGFLAG_READ) {
            read = true;
        }
        else {
            read = false;
        }
    }

    mcd->getEmailData()->setRead(read);

    // If it's an update, and the folder is not draft, do not set the message body
    if (isUpdate && folder != 'D' && folder != 'O'){
        LOG.debug("Update only");
    }
    else {
        /*************************************************************************
         * Past this point, the whole message is sent to the server, and
         * must be complete.
         *************************************************************************/
        FILETIME ft;

        wchar_t time[20];

        if (folder == 'T' && msgprops[ePR_MESSAGE_DELIVERY_TIME].ulPropTag == PR_MESSAGE_DELIVERY_TIME){
            ft = msgprops[ePR_MESSAGE_DELIVERY_TIME].Value.ft;  //OK
        }
        else if (msgprops[ePR_LAST_MODIFICATION_TIME].ulPropTag == PR_LAST_MODIFICATION_TIME){
            ft = msgprops[ePR_LAST_MODIFICATION_TIME].Value.ft;  //OK
        }
        else {
            // Should never happen
            LOG.error("Error retrieving last modification time");
            LOG.error("Using current time");
            SYSTEMTIME st;
            GetLocalTime(&st);
            SystemTimeToFileTime(&st, &ft);
        }
        // Set date in the Email header.
        FileTime2UTCTimeFormatter(ft, time);
        char *t = toMultibyte(time);
        mcd->getEmailData()->setModified(t);
        delete [] t;

        //*************** Set emailItem props *******************************/
        MailMessage& msg = mcd->getEmailData()->getEmailItem();
        ULONG attachCount = 0;

        // Set date ------------------------------------------------------------
        BasicTime bDate;
        
        // In case of Outbox we use always the current time
        if (folder == 'O') {
            SYSTEMTIME systemTime;

            GetSystemTime(&systemTime);
            SystemTimeToFileTime(&systemTime, &ft);
        }
       
        FileTimeToBasicDate(ft, &bDate);
        msg.setDate(bDate);

        // Set subject ------------------------------------------------------------
        if (msgprops[ePR_SUBJECT].ulPropTag == PR_SUBJECT) {
            msg.setSubject(_wcc(msgprops[ePR_SUBJECT].Value.lpszW));
        }

        // priority -> PR_IMPORTANCE. PR_PRIORITY is not a field valid
        long importance = 0;
        msg.setImportance("3"); // IMPORTANCE_NORMAL is default

        if (msgprops[ePR_IMPORTANCE].ulPropTag == PR_IMPORTANCE) {            
            importance = msgprops[ePR_IMPORTANCE].Value.l;
            if (importance == IMPORTANCE_HIGH) {
                msg.setImportance("1"); // high
            } else if (importance == IMPORTANCE_LOW) {
                msg.setImportance("5"); // low
            } 
        }
       
        wchar_t* emailSender = NULL;
        wchar_t* sender      = NULL;
        wchar_t* accountName = NULL;
        wchar_t*  fr         = NULL;
        // Set sender address -----------------------------------------------------
        if (msgprops[ePR_SENDER_EMAIL_ADDRESS].ulPropTag == PR_SENDER_EMAIL_ADDRESS) {

            LOG.debug("MailClientToServer: PR_SENDER_EMAIL_ADDRESS: %ls", msgprops[ePR_SENDER_EMAIL_ADDRESS].Value.lpszW);

            emailSender = msgprops[ePR_SENDER_EMAIL_ADDRESS].Value.lpszW;

            if (msgprops[ePR_SENDER_NAME].ulPropTag == PR_SENDER_NAME) {
                sender = msgprops[ePR_SENDER_NAME].Value.lpszW;
            }

            if (sender != NULL && wcscmp(sender, emailSender) == 0 && folder == 'O') {

                    //wchar_t accountMail[256];
                    //accountName = new wchar_t[256];
                    //getAccountInfo(accountName, accountMail);
                    if (wcscmp(emailSender, DEFAULT_USER_W) == 0) {
                        msg.setFrom("");
                    } else {
                        fr = new wchar_t[wcslen(accName) + wcslen(emailSender) + 10];
                        wsprintf(fr, TEXT("\"%s\" <%s>"), accName, emailSender );
                        msg.setFrom(_wcc(fr));
                        delete [] fr; fr = NULL;
                    }

            } else {
                // if the email is default user it means the sender is empty and the user
                // want to use the default mail added by the server.
                // The check wcsstr of the email sender is on the acute only to avoid
                // something like default@email.com that can be valid
                if (wcscmp(emailSender, DEFAULT_USER_W) == 0 ||
                    wcsstr(emailSender, DEFAULT_USER_W_ACUTE) != 0) {
                    msg.setFrom("");
                } else {
                    msg.setFrom(_wcc(emailSender));
                }

⌨️ 快捷键说明

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