/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Mobility Components. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include // CSmsHeader #include #include #include #include #include // CnvUtfConverter #include "qmessageservice.h" #include "qmessageservice_symbian_p.h" #include "qmtmengine_symbian_p.h" #include "qmessage_symbian_p.h" #include "messagingutil_p.h" #include "maemohelpers_p.h" // contains non-meamo specific helpers for messaging #ifdef FREESTYLEMAILUSED #include "qfsengine_symbian_p.h" #endif QTM_BEGIN_NAMESPACE using namespace SymbianHelpers; QMessageServicePrivate::QMessageServicePrivate(QMessageService* parent) : q_ptr(parent), _state(QMessageService::InactiveState), _active(false), _pendingRequestCount(0) { } QMessageServicePrivate::~QMessageServicePrivate() { } bool QMessageServicePrivate::sendSMS(QMessage &message) { return CMTMEngine::instance()->sendSMS((QMessageServicePrivate&)*this, message); } bool QMessageServicePrivate::sendMMS(QMessage &message) { return CMTMEngine::instance()->sendMMS((QMessageServicePrivate&)*this, message); } bool QMessageServicePrivate::sendEmail(QMessage &message) { switch (idType(message.parentAccountId())) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED { bool retVal = CFSEngine::instance()->sendEmail(message); if (retVal == true) { setFinished(retVal); } return retVal; } #else return false; #endif case EngineTypeMTM: default: return CMTMEngine::instance()->sendEmail((QMessageServicePrivate&)*this, message); } } bool QMessageServicePrivate::show(const QMessageId& id) { switch (idType(id)) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED return CFSEngine::instance()->showMessage(id); #else return false; #endif case EngineTypeMTM: default: return CMTMEngine::instance()->showMessage(id); } } bool QMessageServicePrivate::compose(const QMessage &message) { switch (idType(message.parentAccountId())) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED return CFSEngine::instance()->composeMessage(message); #else return false; #endif case EngineTypeMTM: default: return CMTMEngine::instance()->composeMessage(message); } } bool QMessageServicePrivate::queryMessages(const QMessageFilter &filter, const QMessageSortOrder &sortOrder, uint limit, uint offset) const { if (_pendingRequestCount > 0) { return false; } _pendingRequestCount = 0; _active = true; _filter = filter; _sortOrder = sortOrder; _limit = limit; _offset = offset; _filtered = true; _sorted = true; _pendingRequestCount++; CMTMEngine::instance()->queryMessages((QMessageServicePrivate&)*this, filter, sortOrder, 0, 0); #ifdef FREESTYLEMAILUSED _pendingRequestCount++; CFSEngine::instance()->queryMessages((QMessageServicePrivate&)*this, filter, sortOrder, 0, 0); #endif return _active; } bool QMessageServicePrivate::queryMessages(const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset) const { if (_pendingRequestCount > 0) { return false; } _pendingRequestCount = 0; _active = true; _filter = filter; _sortOrder = sortOrder; _limit = limit; _offset = offset; _filtered = true; _sorted = true; _pendingRequestCount++; CMTMEngine::instance()->queryMessages((QMessageServicePrivate&)*this, filter, body, matchFlags, sortOrder, 0, 0); #ifdef FREESTYLEMAILUSED _pendingRequestCount++; CFSEngine::instance()->queryMessages((QMessageServicePrivate&)*this, filter, body, matchFlags, sortOrder, 0, 0); #endif return _active; } bool QMessageServicePrivate::countMessages(const QMessageFilter &filter) { if (_pendingRequestCount > 0) { return false; } _pendingRequestCount = 0; _active = true; _count = 0; _pendingRequestCount++; CMTMEngine::instance()->countMessages((QMessageServicePrivate&)*this, filter); #ifdef FREESTYLEMAILUSED _pendingRequestCount++; CFSEngine::instance()->countMessages((QMessageServicePrivate&)*this, filter); #endif return _active; } bool QMessageServicePrivate::moveMessages(const QMessageIdList &messageIds, const QMessageFolderId &toFolderId) { bool ret = false; // it'a already verified that messageIds has elements and they are of same type switch (idType(messageIds.at(0))) { case EngineTypeFreestyle: { #ifdef FREESTYLEMAILMAPI12USED ret = CFSEngine::instance()->moveMessages( *this, messageIds, toFolderId ); #else // not supported ret = false; #endif break; } case EngineTypeMTM: // flow through default: { // not supported ret = false; break; } } return ret; } bool QMessageServicePrivate::retrieve(const QMessageId &messageId, const QMessageContentContainerId &id) { switch (idType(messageId)) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED return CFSEngine::instance()->retrieve(*this, messageId, id); #else return false; #endif case EngineTypeMTM: default: return CMTMEngine::instance()->retrieve(*this, messageId, id); } } bool QMessageServicePrivate::retrieveBody(const QMessageId& id) { switch (idType(id)) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED return CFSEngine::instance()->retrieveBody(*this, id); #else return false; #endif case EngineTypeMTM: default: return CMTMEngine::instance()->retrieveBody(*this, id); } } bool QMessageServicePrivate::retrieveHeader(const QMessageId& id) { switch (idType(id)) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED return CFSEngine::instance()->retrieveHeader(*this, id); #else return false; #endif case EngineTypeMTM: default: return CMTMEngine::instance()->retrieveHeader(*this, id); } } void QMessageServicePrivate::messagesFound(const QMessageIdList &ids, bool isFiltered, bool isSorted) { _pendingRequestCount--; if (!isFiltered) { _filtered = false; } if (!isSorted) { _sorted = false; } else { if ((ids.count() > 0) && (_ids.count() > 0)) { _sorted = false; } } _ids.append(ids); if (_pendingRequestCount == 0) { if (!_filtered) { MessagingHelper::filterMessages(_ids, _filter); } if (!_sorted) { MessagingHelper::orderMessages(_ids, _sortOrder); } MessagingHelper::applyOffsetAndLimitToMessageIdList(_ids, _limit, _offset); emit q_ptr->messagesFound(_ids); setFinished(true); _ids.clear(); _filter = QMessageFilter(); _sortOrder = QMessageSortOrder(); } } void QMessageServicePrivate::messagesCounted(int count) { _pendingRequestCount--; _count += count; if (_pendingRequestCount == 0) { emit q_ptr->messagesCounted(_count); setFinished(true); _count = 0; } } bool QMessageServicePrivate::synchronize(const QMessageAccountId &id) { switch (idType(id)) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED return CFSEngine::instance()->synchronize(*this, id); #else return false; #endif case EngineTypeMTM: default: return CMTMEngine::instance()->exportUpdates(*this, id); } } void QMessageServicePrivate::setFinished(bool successful) { if (!successful && (_error == QMessageManager::NoError)) { // We must report an error of some sort _error = QMessageManager::RequestIncomplete; } _active = false; _state = QMessageService::FinishedState; emit q_ptr->stateChanged(_state); } void QMessageServicePrivate::cancel() { if (_active) { #ifdef FREESTYLEMAILUSED CFSEngine::instance()->cancel((QMessageServicePrivate&)*this); #endif CMTMEngine::instance()->cancel((QMessageServicePrivate&)*this); } } QMessageService::QMessageService(QObject *parent) : QObject(parent), d_ptr(new QMessageServicePrivate(this)) { connect(d_ptr, SIGNAL(stateChanged(QMessageService::State)), this, SIGNAL(stateChanged(QMessageService::State))); connect(d_ptr, SIGNAL(messagesFound(const QMessageIdList&)), this, SIGNAL(messagesFound(const QMessageIdList&))); //connect(d_ptr, SIGNAL(messagesCounted(int)), this, SIGNAL(messagesCounted(int))); connect(d_ptr, SIGNAL(progressChanged(uint, uint)), this, SIGNAL(progressChanged(uint, uint))); } QMessageService::~QMessageService() { d_ptr->cancel(); } bool QMessageService::queryMessages(const QMessageFilter &filter, const QMessageSortOrder &sortOrder, uint limit, uint offset) { if (d_ptr->_active) { return false; } d_ptr->_active = true; d_ptr->_error = QMessageManager::NoError; if (d_ptr->queryMessages(filter, sortOrder, limit, offset)) { d_ptr->_state = QMessageService::ActiveState; emit stateChanged(d_ptr->_state); } else { d_ptr->setFinished(false); } return d_ptr->_active; } bool QMessageService::queryMessages(const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset) { if (d_ptr->_active) { return false; } d_ptr->_active = true; d_ptr->_error = QMessageManager::NoError; if (d_ptr->queryMessages(filter, body, matchFlags, sortOrder, limit, offset)) { d_ptr->_state = QMessageService::ActiveState; emit stateChanged(d_ptr->_state); } else { d_ptr->setFinished(false); } return d_ptr->_active; } bool QMessageService::countMessages(const QMessageFilter &filter) { if (d_ptr->_active) { return false; } d_ptr->_active = true; d_ptr->_error = QMessageManager::NoError; if (d_ptr->countMessages(filter)) { d_ptr->_state = QMessageService::ActiveState; emit stateChanged(d_ptr->_state); } else { d_ptr->setFinished(false); } return d_ptr->_active; } bool QMessageService::send(QMessage &message) { if (d_ptr->_active) { return false; } d_ptr->_active = true; d_ptr->_error = QMessageManager::NoError; bool retVal = true; d_ptr->_state = QMessageService::ActiveState; emit stateChanged(d_ptr->_state); QMessageAccountId accountId = message.parentAccountId(); QMessage::Type msgType = QMessage::NoType; // Check message type if (message.type() == QMessage::AnyType || message.type() == QMessage::NoType) { QMessage::TypeFlags types = QMessage::NoType; if (accountId.isValid()) { // ParentAccountId was defined => Message type can be read // from parent account QMessageAccount account = QMessageAccount(accountId); QMessage::TypeFlags types = account.messageTypes(); if (types & QMessage::Sms) { msgType = QMessage::Sms; } else if (types & QMessage::Mms) { msgType = QMessage::Mms; } else if (types & QMessage::Email) { msgType = QMessage::Email; } } if (msgType == QMessage::NoType) { d_ptr->_error = QMessageManager::ConstraintFailure; retVal = false; } } if (retVal) { // Check account if (!accountId.isValid()) { accountId = QMessageAccount::defaultAccount(message.type()); if (!accountId.isValid()) { d_ptr->_error = QMessageManager::InvalidId; retVal = false; } } } QMessageAccount account(accountId); if (retVal) { // Check account/message type compatibility if (!(account.messageTypes() & message.type()) && (msgType == QMessage::NoType)) { d_ptr->_error = QMessageManager::ConstraintFailure; retVal = false; } } if (retVal) { // Check recipients QMessageAddressList recipients = message.to() + message.bcc() + message.cc(); if (recipients.isEmpty()) { d_ptr->_error = QMessageManager::ConstraintFailure; return false; } } if (retVal) { QMessage outgoing(message); // Set default account if unset if (!outgoing.parentAccountId().isValid()) { outgoing.setParentAccountId(accountId); } if (outgoing.type() == QMessage::AnyType || outgoing.type() == QMessage::NoType) { outgoing.setType(msgType); } if (account.messageTypes() & QMessage::Sms) { retVal = d_ptr->sendSMS(outgoing); } else if (account.messageTypes() & QMessage::Mms) { retVal = d_ptr->sendMMS(outgoing); } else if (account.messageTypes() & QMessage::Email) { retVal = d_ptr->sendEmail(outgoing); } QMessagePrivate* privateMessage = QMessagePrivate::implementation(message); privateMessage->_id = outgoing.id(); } if (retVal == false) { d_ptr->setFinished(retVal); } return retVal; } bool QMessageService::compose(const QMessage &message) { if (d_ptr->_active) { return false; } d_ptr->_active = true; d_ptr->_error = QMessageManager::NoError; bool retVal = true; d_ptr->_state = QMessageService::ActiveState; emit stateChanged(d_ptr->_state); retVal = d_ptr->compose(message); d_ptr->setFinished(retVal); return retVal; } bool QMessageService::retrieveHeader(const QMessageId& id) { if (d_ptr->_active) { return false; } if (!id.isValid()) { d_ptr->_error = QMessageManager::InvalidId; return false; } d_ptr->_active = true; d_ptr->_error = QMessageManager::NoError; bool retVal = true; d_ptr->_state = QMessageService::ActiveState; emit stateChanged(d_ptr->_state); retVal = d_ptr->retrieveHeader(id); if (retVal == false) { d_ptr->setFinished(retVal); } return retVal; } bool QMessageService::retrieveBody(const QMessageId& id) { if (d_ptr->_active) { return false; } if (!id.isValid()) { d_ptr->_error = QMessageManager::InvalidId; return false; } d_ptr->_active = true; d_ptr->_error = QMessageManager::NoError; bool retVal = true; d_ptr->_state = QMessageService::ActiveState; emit stateChanged(d_ptr->_state); retVal = d_ptr->retrieveBody(id); if (retVal == false) { d_ptr->setFinished(retVal); } return retVal; } bool QMessageService::retrieve(const QMessageId &messageId, const QMessageContentContainerId& id) { if (d_ptr->_active) { return false; } if (!messageId.isValid() || !id.isValid()) { d_ptr->_error = QMessageManager::InvalidId; return false; } d_ptr->_active = true; d_ptr->_error = QMessageManager::NoError; bool retVal = true; d_ptr->_state = QMessageService::ActiveState; emit stateChanged(d_ptr->_state); retVal = d_ptr->retrieve(messageId, id); if (retVal == false) { d_ptr->setFinished(retVal); } return retVal; } bool QMessageService::show(const QMessageId& id) { if (d_ptr->_active) { return false; } if (!id.isValid()) { d_ptr->_error = QMessageManager::InvalidId; return false; } d_ptr->_active = true; d_ptr->_error = QMessageManager::NoError; bool retVal = true; d_ptr->_state = QMessageService::ActiveState; emit stateChanged(d_ptr->_state); retVal = d_ptr->show(id); d_ptr->setFinished(retVal); return retVal; } bool QMessageService::exportUpdates(const QMessageAccountId &id) { return synchronize(id); } bool QMessageService::moveMessages(const QMessageIdList &messageIds, const QMessageFolderId &toFolderId) { if (d_ptr->_active) { return false; } if (!toFolderId.isValid()) { d_ptr->_error = QMessageManager::InvalidId; return false; } const int count = messageIds.count(); if ( count == 0) { return false; } // verify that messages are of same type and valid EngineType expectedType = idType(messageIds[0]); for( int i = 1; i < count; ++i ) { if( idType( messageIds[i] ) != expectedType || !messageIds[i].isValid() ) { // invalid message id or inconsistent type found d_ptr->_error = QMessageManager::InvalidId; return false; } } d_ptr->_active = true; d_ptr->_error = QMessageManager::NoError; d_ptr->_state = QMessageService::ActiveState; emit stateChanged(d_ptr->_state); bool retVal = d_ptr->moveMessages( messageIds, toFolderId ); if (!retVal) { d_ptr->setFinished(retVal); } return retVal; } bool QMessageService::synchronize(const QMessageAccountId &id) { if (d_ptr->_active) { return false; } if (!id.isValid()) { d_ptr->_error = QMessageManager::InvalidId; return false; } d_ptr->_active = true; d_ptr->_error = QMessageManager::NoError; bool retVal = true; d_ptr->_state = QMessageService::ActiveState; emit stateChanged(d_ptr->_state); retVal = d_ptr->synchronize(id); if (retVal == false) { d_ptr->setFinished(retVal); } return retVal; } QMessageService::State QMessageService::state() const { return d_ptr->_state; } void QMessageService::cancel() { if (d_ptr->_active) { d_ptr->cancel(); d_ptr->_active = false; d_ptr->_state = QMessageService::CanceledState; emit stateChanged(d_ptr->_state); } } QMessageManager::Error QMessageService::error() const { return d_ptr->_error; } #include "moc_qmessageservice_symbian_p.cpp" QTM_END_NAMESPACE