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 + -
显示快捷键?