diff options
author | Don Sanders <don.sanders@nokia.com> | 2010-09-22 14:19:32 +1000 |
---|---|---|
committer | Don Sanders <don.sanders@nokia.com> | 2010-09-22 14:19:32 +1000 |
commit | 4f478d6ef2d97fc8207da14cd461270e10cd4b97 (patch) | |
tree | ca7b61c666a8138461e270960efb93ddb9576495 | |
parent | cbc4056c214143fbf3f1ad14f334a5c6c16db67f (diff) | |
parent | 0a566b28bafb714c8802bf557a35f6525ba93fd6 (diff) |
Merge branch '1.0'
Conflicts:
examples/lightmaps/lightmaps.cpp
examples/player/player.cpp
examples/sensors/panoramaWithSense/inputcontroller.cpp
examples/sensors/panoramaWithSense/keycontroller.cpp
examples/sensors/panoramaWithSense/main.cpp
examples/sensors/panoramaWithSense/view.cpp
plugins/declarative/sensors/sensors.pro
plugins/multimedia/symbian/openmaxal/mediarecorder/mediarecorder.pro
plugins/multimedia/symbian/openmaxal/mediarecorder/qxarecordmediaserviceproviderplugin.cpp
src/messaging/modestengine_maemo.cpp
src/messaging/qmessage_p.h
src/s60installs/s60installs.pro
src/versit/qversitcontactimporter_p.cpp
63 files changed, 2634 insertions, 546 deletions
diff --git a/.gitignore b/.gitignore index e5fa7f230e..d791d802e9 100644 --- a/.gitignore +++ b/.gitignore @@ -99,6 +99,7 @@ config.tests/qmf/qmf config.tests/maemo5-contacts/maemo5-contacts config.tests/bluez/bluez .qmake.cache +translations/qtmobility_untranslated.ts translations/qtmobility_*.qm #Symbian specific diff --git a/demos/player/player.h b/demos/player/player.h index aa83a9ebb0..8a717c9542 100644 --- a/demos/player/player.h +++ b/demos/player/player.h @@ -53,6 +53,7 @@ class QAbstractItemView; class QLabel; class QModelIndex; class QSlider; +class QPushButton; class QMediaPlayer; class QVideoWidget; @@ -86,6 +87,7 @@ private slots: void statusChanged(QMediaPlayer::MediaStatus status); void bufferingProgress(int progress); + void videoAvailableChanged(bool available); void displayErrorMessage(); @@ -104,6 +106,8 @@ private: QVideoWidget *videoWidget; QLabel *coverLabel; QSlider *slider; + QPushButton *fullScreenButton; + QPushButton *colorButton; PlaylistModel *playlistModel; QAbstractItemView *playlistView; QString trackInfo; diff --git a/examples/radio/radio.cpp b/examples/radio/radio.cpp index 7aab46f64b..f1311d75c2 100644 --- a/examples/radio/radio.cpp +++ b/examples/radio/radio.cpp @@ -47,6 +47,7 @@ Radio::Radio() radio = new QRadioTuner; connect(radio,SIGNAL(frequencyChanged(int)),this,SLOT(freqChanged(int))); connect(radio,SIGNAL(signalStrengthChanged(int)),this,SLOT(signalChanged(int))); + connect(radio, SIGNAL(error(QRadioTuner::Error)), this, SLOT(error(QRadioTuner::Error))); if(radio->isBandSupported(QRadioTuner::FM)) radio->setBand(QRadioTuner::FM); @@ -169,3 +170,10 @@ void Radio::updateVolume(int v) radio->setVolume(v); } +void Radio::error(QRadioTuner::Error error) +{ + const QMetaObject* metaObj = radio->metaObject(); + QMetaEnum errorEnum = metaObj->enumerator(metaObj->indexOfEnumerator("Error")); + qWarning().nospace() << "Warning: Example application received error QRadioTuner::" << errorEnum.valueToKey(error); +} + diff --git a/examples/radio/radio.h b/examples/radio/radio.h index 4f22b93b85..5f9573a15e 100644 --- a/examples/radio/radio.h +++ b/examples/radio/radio.h @@ -68,6 +68,7 @@ public slots: void freqChanged(int f); void signalChanged(int s); void updateVolume(int v); + void error(QRadioTuner::Error error); private: QLabel* freq; diff --git a/examples/sensors/panoramaWithSense/keycontroller.cpp b/examples/sensors/panoramaWithSense/keycontroller.cpp index bec0a3fda7..e27904fd2b 100644 --- a/examples/sensors/panoramaWithSense/keycontroller.cpp +++ b/examples/sensors/panoramaWithSense/keycontroller.cpp @@ -37,6 +37,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ + #include "keycontroller.h" KeyController::KeyController(): TimedController(), m_step(5){} diff --git a/plugins/multimedia/audiocapture/audiocapturesession.cpp b/plugins/multimedia/audiocapture/audiocapturesession.cpp index 938fe1f174..d264a43169 100644 --- a/plugins/multimedia/audiocapture/audiocapturesession.cpp +++ b/plugins/multimedia/audiocapture/audiocapturesession.cpp @@ -139,9 +139,9 @@ QString AudioCaptureSession::containerDescription(const QString &formatMimeType) { if(m_deviceInfo) { if (formatMimeType.contains(QLatin1String("audio/pcm"))) - return QString(tr("RAW file format")); + return tr("RAW file format"); if (formatMimeType.contains(QLatin1String("audio/x-wav"))) - return QString(tr("WAV file format")); + return tr("WAV file format"); } return QString(); } diff --git a/plugins/multimedia/audiocapture/audioencodercontrol.cpp b/plugins/multimedia/audiocapture/audioencodercontrol.cpp index a63884f9f4..888deac459 100644 --- a/plugins/multimedia/audiocapture/audioencodercontrol.cpp +++ b/plugins/multimedia/audiocapture/audioencodercontrol.cpp @@ -84,7 +84,7 @@ QStringList AudioEncoderControl::supportedAudioCodecs() const QString AudioEncoderControl::codecDescription(const QString &codecName) const { if (codecName.contains(QLatin1String("audio/pcm"))) - return QString(tr("PCM audio data")); + return tr("PCM audio data"); return QString(); } diff --git a/plugins/multimedia/m3u/qm3uhandler.cpp b/plugins/multimedia/m3u/qm3uhandler.cpp index ac03b8d4c9..c2719305e9 100644 --- a/plugins/multimedia/m3u/qm3uhandler.cpp +++ b/plugins/multimedia/m3u/qm3uhandler.cpp @@ -100,7 +100,10 @@ public: if (line.isEmpty() || line[0] == '#') continue; - nextResource = QMediaContent(QUrl(line)); + if (QFile::exists(line)) + nextResource = QMediaContent(QUrl::fromLocalFile(line)); + else + nextResource = QMediaContent(QUrl(line)); break; } diff --git a/plugins/multimedia/qt7/mediaplayer/qt7playersession.mm b/plugins/multimedia/qt7/mediaplayer/qt7playersession.mm index 7f1e6f1dab..c7a544cc17 100644 --- a/plugins/multimedia/qt7/mediaplayer/qt7playersession.mm +++ b/plugins/multimedia/qt7/mediaplayer/qt7playersession.mm @@ -185,6 +185,9 @@ QT7PlayerSession::QT7PlayerSession(QObject *parent) QT7PlayerSession::~QT7PlayerSession() { + if (m_videoOutput) + m_videoOutput->setMovie(0); + [(QTMovieObserver*)m_movieObserver setMovie:nil]; [(QTMovieObserver*)m_movieObserver release]; [(QTMovie*)m_QTMovie release]; diff --git a/src/bearer/qnetworkconfigmanager.cpp b/src/bearer/qnetworkconfigmanager.cpp index 3e7be7a88d..f5db643152 100644 --- a/src/bearer/qnetworkconfigmanager.cpp +++ b/src/bearer/qnetworkconfigmanager.cpp @@ -49,9 +49,31 @@ #include "qnetworkconfigmanager_p.h" #endif +#include <QtCore/QCoreApplication> + QTM_BEGIN_NAMESPACE -Q_GLOBAL_STATIC(QNetworkConfigurationManagerPrivate, connManager); +#define Q_GLOBAL_STATIC_QAPP_DESTRUCTION(TYPE, NAME) \ + Q_GLOBAL_STATIC_INIT(TYPE, NAME); \ + static void NAME##_cleanup() \ + { \ + delete this_##NAME.pointer; \ + this_##NAME.pointer = 0; \ + this_##NAME.destroyed = true; \ + } \ + static TYPE *NAME() \ + { \ + if (!this_##NAME.pointer && !this_##NAME.destroyed) { \ + TYPE *x = new TYPE; \ + if (!this_##NAME.pointer.testAndSetOrdered(0, x)) \ + delete x; \ + else \ + qAddPostRoutine(NAME##_cleanup); \ + } \ + return this_##NAME.pointer; \ + } + +Q_GLOBAL_STATIC_QAPP_DESTRUCTION(QNetworkConfigurationManagerPrivate, connManager); /*! \class QNetworkConfigurationManager diff --git a/src/messaging/eventloggerengine_maemo.cpp b/src/messaging/eventloggerengine_maemo.cpp index f695635fae..abb8b9aeb5 100644 --- a/src/messaging/eventloggerengine_maemo.cpp +++ b/src/messaging/eventloggerengine_maemo.cpp @@ -41,6 +41,8 @@ #include "eventloggerengine_maemo_p.h" #include "telepathyengine_maemo_p.h" +#include "maemohelpers_p.h" +#include "qmessageservice_maemo_p.h" #include <QDebug> QTM_BEGIN_NAMESPACE @@ -72,8 +74,13 @@ EventLoggerEngine::EventLoggerEngine(QObject *parent):QObject(parent), _filterId g_signal_connect(G_OBJECT(el), "new-event", G_CALLBACK(new_event_cb),(void*)this); + g_signal_connect(G_OBJECT(el), "event-deleted", G_CALLBACK(event_deleted_cb),(void*)this); + g_signal_connect(G_OBJECT(el), "event-updated", G_CALLBACK(event_updated_cb),(void*)this); + + qRegisterMetaType<QMessageIdList>("QMessageIdList"); } + void EventLoggerEngine::new_event_cb(RTComEl *el,int event_id, const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, const char *group_uid,const char *service,EventLoggerEngine *p) @@ -82,6 +89,23 @@ void EventLoggerEngine::new_event_cb(RTComEl *el,int event_id, p->newEvent(event_id, local_uid,remote_uid ,remote_ebook_uid,group_uid,service); }; +void EventLoggerEngine::event_deleted_cb(RTComEl *el,int event_id, + const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, + const char *group_uid,const char *service,EventLoggerEngine *p) +{ + Q_UNUSED(el); + p->deletedEvent(event_id, local_uid,remote_uid ,remote_ebook_uid,group_uid,service); +}; + +void EventLoggerEngine::event_updated_cb(RTComEl *el,int event_id, + const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, + const char *group_uid,const char *service,EventLoggerEngine *p) +{ + Q_UNUSED(el); + p->updatedEvent(event_id, local_uid,remote_uid ,remote_ebook_uid,group_uid,service); +}; + + void EventLoggerEngine::newEvent(int event_id, const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, const char *group_uid,const char *service) @@ -91,10 +115,36 @@ void EventLoggerEngine::newEvent(int event_id, QString eventIds=QString("el")+QString::number(event_id); QMessageId id(eventIds); - + qDebug() << "newEvent id=" << eventIds; notification(event_id,service,QMessageStorePrivate::Added); } +void EventLoggerEngine::updatedEvent(int event_id, + const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, + const char *group_uid,const char *service) +{ + Q_UNUSED(local_uid); Q_UNUSED(remote_uid);Q_UNUSED(remote_ebook_uid); + Q_UNUSED(group_uid);Q_UNUSED(service); + QString eventIds=QString("el")+QString::number(event_id); + QMessageId id(eventIds); + + qDebug() << "updatedEvent id=" << eventIds; + notification(event_id,service,QMessageStorePrivate::Updated); +} + +void EventLoggerEngine::deletedEvent(int event_id, + const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, + const char *group_uid,const char *service) +{ + Q_UNUSED(local_uid); Q_UNUSED(remote_uid);Q_UNUSED(remote_ebook_uid); + Q_UNUSED(group_uid);Q_UNUSED(service); + QString eventIds=QString("el")+QString::number(event_id); + QMessageId id(eventIds); + + qDebug() << "deletedEvent id=" << eventIds; + notification(event_id,service,QMessageStorePrivate::Removed); +} + QMessageManager::NotificationFilterId EventLoggerEngine::registerNotificationFilter(QMessageStorePrivate& aPrivateStore, const QMessageFilter &filter) { @@ -143,7 +193,7 @@ QMessage EventLoggerEngine::eventToMessage(RTComElEvent & ev) QMessageAddressList messageAddresslist; messageAddresslist.append(QMessageAddress(QMessageAddress::Phone, QString(ev.fld_local_uid))); message.setTo(messageAddresslist); - message.setBody(QString(ev.fld_free_text)); + message.setBody(QString::fromUtf8(ev.fld_free_text)); QMessagePrivate* privateMessage = QMessagePrivate::implementation(message); privateMessage->_id = QMessageId(QString("el")+QString::number(ev.fld_id)); privateMessage->_modified = false; @@ -239,7 +289,7 @@ additional_text=%s icon_name=%s pango_markup=%s\n", QMessageAddressList messageAddresslist; messageAddresslist.append(QMessageAddress(QMessageAddress::Phone, QString(ev.fld_local_uid))); message.setTo(messageAddresslist); - message.setBody(QString(ev.fld_free_text)); + message.setBody(QString::fromUtf8(ev.fld_free_text)); QMessagePrivate* privateMessage = QMessagePrivate::implementation(message); privateMessage->_id = id; privateMessage->_modified = false; @@ -249,6 +299,8 @@ additional_text=%s icon_name=%s pango_markup=%s\n", if(iter) g_object_unref(iter); // debugMessage(message); + MessageCache::instance()->insert(message); + return message; } @@ -308,6 +360,15 @@ void EventLoggerEngine::notification(int eventId, QString service,QMessageStoreP } } + if (notificationType == QMessageStorePrivate::Updated) { + // Remove updated message from cache to make sure that message + // will be retrieved again from backend + MessageCache::instance()->remove(QMessageId(QString("el")+QString::number(eventId))); + } else if (notificationType == QMessageStorePrivate::Removed) { + // Remove removed message from cache + MessageCache::instance()->remove(QMessageId(QString("el")+QString::number(eventId))); + } + if (matchingFilters.count() > 0) { ipMessageStorePrivate->messageNotification(notificationType, QMessageId(QString("el")+QString::number(eventId)), @@ -324,10 +385,11 @@ QMessageIdList EventLoggerEngine::filterAndOrderMessages(const QMessageFilter &f } #endif -bool EventLoggerEngine::filterMessages(const QMessageFilter &filter, - const QMessageSortOrder& sortOrder, - QString body, - QMessageDataComparator::MatchFlags matchFlags) +bool EventLoggerEngine::filterMessages(QMessageServicePrivate* privateService, + const QMessageFilter &filter, + const QMessageSortOrder& sortOrder, + QString body, + QMessageDataComparator::MatchFlags matchFlags) { // qDebug() << "EventLoggerEngine::filterMessages"; @@ -345,7 +407,7 @@ bool EventLoggerEngine::filterMessages(const QMessageFilter &filter, queryThread=new QueryThread(); connect(queryThread, SIGNAL(completed()), this, SLOT(reportMatchingIds()), Qt::QueuedConnection); }; - queryThread->setArgs(this, filter, body, matchFlags, sortOrder, 0,0); + queryThread->setArgs(privateService, this, filter, body, matchFlags, sortOrder, 0,0); queryThread->start(); // return queryThread.queryMessages(filter,sortOrder,body,matchFlags); @@ -361,9 +423,14 @@ void EventLoggerEngine::messagesFound_(const QMessageIdList &ids) void EventLoggerEngine::reportMatchingIds() { - // qDebug() << "EventLoggerEngine::messagesFound" << m_ids.count(); - emit messagesFound(m_ids,true,false); - completed(); + // qDebug() << "EventLoggerEngine::messagesFound" << m_ids.count(); + QMetaObject::invokeMethod(queryThread->_privateService, + "messagesFound", + Qt::QueuedConnection, + Q_ARG(const QMessageIdList, m_ids), + Q_ARG(bool, true), + Q_ARG(bool, false)); + completed(); } void EventLoggerEngine::completed() @@ -434,6 +501,7 @@ QMessageIdList EventLoggerEngine::filterAndOrderMessages(const QMessageFilter &f if (pf->filter(message)) { // qDebug() <<"Filter :filtering match" << message.id().toString(); //matchingFilters.insert(it.key()); + MessageCache::instance()->insert(message); idList.append(message.id()); }; }; @@ -452,8 +520,9 @@ QueryThread::QueryThread(): QThread() { } -void QueryThread::setArgs(EventLoggerEngine *parent, const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset) +void QueryThread::setArgs(QMessageServicePrivate* privateService, EventLoggerEngine *parent, const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset) { + _privateService = privateService; _parent=parent; _filter=filter; _body=body; diff --git a/src/messaging/eventloggerengine_maemo_p.h b/src/messaging/eventloggerengine_maemo_p.h index 3d1c693a02..e45bd20229 100644 --- a/src/messaging/eventloggerengine_maemo_p.h +++ b/src/messaging/eventloggerengine_maemo_p.h @@ -80,12 +80,14 @@ class QueryThread : public QThread public: QueryThread(); - void setArgs(EventLoggerEngine *parent, const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset); + void setArgs(QMessageServicePrivate* privateService, EventLoggerEngine *parent, const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset); void run(); signals: void completed(); + public: + QMessageServicePrivate* _privateService; EventLoggerEngine *_parent; QMessageFilter _filter; QString _body; @@ -114,14 +116,27 @@ public: static void new_event_cb(RTComEl *el,int event_id, const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, const char *group_uid,const char *service,EventLoggerEngine *p); + static void event_updated_cb(RTComEl *el,int event_id, + const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, + const char *group_uid,const char *service,EventLoggerEngine *p); + static void event_deleted_cb(RTComEl *el,int event_id, + const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, + const char *group_uid,const char *service,EventLoggerEngine *p); void newEvent(int event_id, const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, const char *group_uid,const char *service); + void deletedEvent(int event_id, + const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, + const char *group_uid,const char *service); + void updatedEvent(int event_id, + const char *local_uid,const char *remote_uid,const char *remote_ebook_uid, + const char *group_uid,const char *service); + QMessageIdList filterAndOrderMessages(const QMessageFilter &filter, const QMessageSortOrder& sortOrder, QString body, QMessageDataComparator::MatchFlags matchFlags); - bool filterMessages(const QMessageFilter &filter, const QMessageSortOrder& sortOrder, - QString body, QMessageDataComparator::MatchFlags matchFlags); + bool filterMessages(QMessageServicePrivate* privateService, const QMessageFilter &filter, + const QMessageSortOrder& sortOrder, QString body, QMessageDataComparator::MatchFlags matchFlags); void addEvent(QMessage &message); QMessageIdList m_ids; diff --git a/src/messaging/maemohelpers.cpp b/src/messaging/maemohelpers.cpp index 3e3c798ee0..2a7afc75d9 100644 --- a/src/messaging/maemohelpers.cpp +++ b/src/messaging/maemohelpers.cpp @@ -49,6 +49,7 @@ QTM_BEGIN_NAMESPACE +Q_GLOBAL_STATIC(MessageCache, messageCache); Q_GLOBAL_STATIC(MessagingHelper, messagingHelper); MessagingHelper* MessagingHelper::instance() @@ -209,22 +210,33 @@ void MessagingHelper::filterMessages(QMessageIdList& messageIds, const QMessageF (pf->_filterList.count() == 0)) { if (pf->_notFilter) { // There is only one filter: empty ~QMessageFilter() - // => accountIds must be cleared + // => messageIds must be cleared messageIds.clear(); return; } else { // There is only one filter: empty QMessageFilter() - // => accountIds list can remain intact + // => messageIds list can remain intact return; } } if (pf->_valid) { + MessageCache* cache = MessageCache::instance(); QMessageStore* store = QMessageStore::instance(); + QMessage* msg; for (int i=messageIds.count()-1; i >= 0; i--) { - QMessage message = store->message(messageIds[i]); - if (!pf->filter(message)) { - messageIds.removeAt(i); + cache->lock(); + msg = cache->messageObject(messageIds[i]); + if (msg) { + if (!pf->filter(*msg)) { + messageIds.removeAt(i); + } + cache->unlock(); + } else { + cache->unlock(); + if (!pf->filter(store->message(messageIds[i]))) { + messageIds.removeAt(i); + } } } } @@ -233,10 +245,34 @@ void MessagingHelper::filterMessages(QMessageIdList& messageIds, const QMessageF bool MessagingHelper::messageLessThan(const QMessageId messageId1, const QMessageId messageId2) { - QMessageStore* store = QMessageStore::instance(); - return QMessageSortOrderPrivate::lessThan(*messagingHelper()->m_MessageSortOrder, - store->message(messageId1), - store->message(messageId2)); + bool retVal = false; + + MessageCache* cache = MessageCache::instance(); + cache->lock(); + QMessage *msg1 = cache->messageObject(messageId1); + QMessage *msg2 = cache->messageObject(messageId2); + + if (msg1 == 0 || msg2 == 0) { + QMessageStore* store = QMessageStore::instance(); + if (msg1 != 0) { + retVal = QMessageSortOrderPrivate::lessThan(*messagingHelper()->m_MessageSortOrder, + *msg1, + store->message(messageId2)); + } else if (msg2 != 0) { + retVal = QMessageSortOrderPrivate::lessThan(*messagingHelper()->m_MessageSortOrder, + store->message(messageId1), + *msg2); + } else { + retVal = QMessageSortOrderPrivate::lessThan(*messagingHelper()->m_MessageSortOrder, + store->message(messageId1), + store->message(messageId2)); + } + } else { + retVal = QMessageSortOrderPrivate::lessThan(*messagingHelper()->m_MessageSortOrder, *msg1, *msg2); + } + cache->unlock(); + + return retVal; } void MessagingHelper::orderMessages(QMessageIdList& messageIds, const QMessageSortOrder &sortOrder) @@ -504,4 +540,140 @@ void MessagingHelper::handleNestedFiltersFromMessageFilter(QMessageFilter &filte } } +bool MessagingHelper::preFilter(QMessageFilter &filter, QMessage::Type type) +{ + QMessageFilterPrivate* pMFFilter = QMessageFilterPrivate::implementation(filter); + + QString prefix; + if (type == QMessage::Email) { + prefix = "MO_"; + } else if (type == QMessage::Sms) { + prefix = "el"; + } + + return pMFFilter->preFilter(type, prefix); +} + +MessageCache* MessageCache::instance() +{ + return messageCache(); +} + +MessageCache::MessageCache() +{ + m_messageCache.setMaxCost(maxMessageCacheSize); +} + +MessageCache::~MessageCache() +{ +} + +bool MessageCache::insert(const QMessage &message) +{ + bool retVal; + + m_mutex.lock(); + QMessage *msg = new QMessage(message); + retVal = m_messageCache.insert(message.id().toString(), msg); + if (retVal == false) { + delete msg; + } + m_mutex.unlock(); + + return retVal; +} + +bool MessageCache::update(const QMessage &message) +{ + bool retVal; + + m_mutex.lock(); + retVal = m_messageCache.remove(message.id().toString()); + if (retVal) { + QMessage *msg = new QMessage(message); + m_messageCache.insert(message.id().toString(), msg); + } + m_mutex.unlock(); + + return retVal; +} + +bool MessageCache::remove(const QMessageId &id) +{ + bool retVal; + + m_mutex.lock(); + retVal = m_messageCache.remove(id.toString()); + m_mutex.unlock(); + + return retVal; +} + +QMessage MessageCache::message(const QMessageId &id) +{ + QMessage message; + + m_mutex.lock(); + QMessage *msg = m_messageCache.object(id.toString()); + if (msg) { + message = *msg; + } + m_mutex.unlock(); + + return message; +} + +bool MessageCache::isFull() const +{ + if (m_messageCache.size() >= maxMessageCacheSize) { + return true; + } + + return false; +} + +bool MessageCache::insertObject(QMessage *message) +{ + bool retVal; + + m_mutex.lock(); + retVal = m_messageCache.insert(message->id().toString(), message); + m_mutex.unlock(); + + return retVal; +} + +QMessage* MessageCache::messageObject(const QMessageId &id) +{ + return m_messageCache.object(id.toString()); +} + +QMessageIdList MessageCache::messageIds() +{ + QMessageIdList ids; + + QStringList keys = m_messageCache.keys(); + for (int i=0; i < keys.count(); i++) { + ids.append(QMessageId(keys[i])); + } + + return ids; +} + +int MessageCache::count() const +{ + return m_messageCache.count(); +} + +void MessageCache::lock() +{ + m_mutex.lock(); +} + +void MessageCache::unlock() +{ + m_mutex.unlock(); +} + + QTM_END_NAMESPACE diff --git a/src/messaging/maemohelpers_p.h b/src/messaging/maemohelpers_p.h index 57aa57afc7..315fb4acb3 100644 --- a/src/messaging/maemohelpers_p.h +++ b/src/messaging/maemohelpers_p.h @@ -42,7 +42,12 @@ #ifndef QMESSAGINGMAEMOHELPERPRIVATE_H #define QMESSAGINGMAEMOHELPERPRIVATE_H +#include <QString> +#include <QMutex> +#include <QCache> + #include <qmessageglobal.h> +#include <qmessage.h> #include <qmessageid.h> #include <qmessagesortorder.h> #include <qmessageaccountid.h> @@ -52,6 +57,8 @@ QTM_BEGIN_NAMESPACE +static const int maxMessageCacheSize = 100000; + class QMessageAccountFilter; class QMessageAccountSortOrder; class QMessageFolderFilter; @@ -82,6 +89,8 @@ public: static void handleNestedFiltersFromFolderFilter(QMessageFolderFilter &filter); static void handleNestedFiltersFromMessageFilter(QMessageFilter &filter); + static bool preFilter(QMessageFilter &filter, QMessage::Type type); + private: static bool accountLessThan(const QMessageAccountId accountId1, const QMessageAccountId accountId2); static bool folderLessThan(const QMessageFolderId folderId1, const QMessageFolderId folderId2); @@ -93,6 +102,35 @@ private: QMessageSortOrder* m_MessageSortOrder; }; +class MessageCache +{ +public: + static MessageCache* instance(); + + MessageCache(); + ~MessageCache(); + + bool insert(const QMessage &message); + bool update(const QMessage &message); + bool remove(const QMessageId &id); + QMessage message(const QMessageId &id); + + QMessageIdList messageIds(); + + bool isFull() const; + int count() const; + + bool insertObject(QMessage *message); + QMessage* messageObject(const QMessageId &id); + void lock(); + void unlock(); + +private: + QCache<QString, QMessage> m_messageCache; + QMutex m_mutex; +}; + + QTM_END_NAMESPACE #endif // QMESSAGINGMAEMOHELPERPRIVATE_H diff --git a/src/messaging/modestengine_maemo.cpp b/src/messaging/modestengine_maemo.cpp index 1636cd646a..007caf8ef7 100644 --- a/src/messaging/modestengine_maemo.cpp +++ b/src/messaging/modestengine_maemo.cpp @@ -267,7 +267,7 @@ typedef enum { Q_GLOBAL_STATIC(ModestEngine,modestEngine); ModestEngine::ModestEngine() - : m_queryIds(0), m_filterId(0) + : m_queryIds(0), m_filterId(0), m_allEmailMessagesInCache(false) { qWarning() << "ModestEngine::ModestEngine Starting to initialize"; g_type_init(); @@ -332,6 +332,7 @@ ModestEngine::ModestEngine() qRegisterMetaType<MessagingModestFolder>(); + qRegisterMetaType<QList<QtMobility::QMessageId> >("QList<QtMobility::QMessageId>"); connect(&m_MailFoldersWatcher, SIGNAL(fileChanged(int, QString, uint)), this, SLOT(fileChangedSlot(int, QString, uint))); @@ -1145,6 +1146,7 @@ void ModestEngine::fileChangedSlot(int watchDescriptor, QString filePath, uint e // => Start watching new folder QString newDirPath = QString(filePath.toUtf8()); m_MailFoldersWatcher.addDirectory(newDirPath + "/cur"); + return; } } @@ -1294,32 +1296,65 @@ bool ModestEngine::exportUpdates(const QMessageAccountId &id) return true; } -QMessage ModestEngine::message(const QMessageId &id, bool useCache) const +bool ModestEngine::retrieveMessageMimeInformation(QMessage& message) { - if (useCache) { - QMessage message = m_messageCache.value(id.toString()); - if (message.type() != QMessage::NoType) { - return message; + QMessagePrivate* privateMessage = QMessagePrivate::implementation(message); + if (!privateMessage->_mimeInformationRetrieved) { + QString modestAccountId = modestAccountIdFromMessageId(message.id()); + QString modestFolderId = modestFolderIdFromMessageId(message.id()); + QString modestMessageId = modestMessageIdFromMessageId(message.id()); + + MessagingModestMessage modestMessage = messageFromModest(modestAccountId, + modestFolderId, + modestMessageId); + + if (modestMessage.flags & MessagingModestMessageDeleted) { + return false; + } + + if (modestMessage.accountId.isEmpty()) { + return false; } + + privateMessage->_mimeInformationRetrieved = true; + + mimeInformationFromModestMessageToMessage(modestMessage, message); + MessageCache::instance()->insert(message); } - QString modestAccountId = modestAccountIdFromMessageId(id); - QString modestFolderId = modestFolderIdFromMessageId(id); - QString modestMessageId = modestMessageIdFromMessageId(id); + return true; +} - MessagingModestMessage modestMessage = messageFromModest(modestAccountId, - modestFolderId, - modestMessageId); +QMessage ModestEngine::message(const QMessageId &id, bool useCache) const +{ + QMessage message; - if (modestMessage.flags & MessagingModestMessageDeleted) { - return QMessage(); + if (useCache) { + message = MessageCache::instance()->message(id.toString()); } - if (modestMessage.accountId.isEmpty()) { - return QMessage(); + if (message.type() == QMessage::NoType) { + QString modestAccountId = modestAccountIdFromMessageId(id); + QString modestFolderId = modestFolderIdFromMessageId(id); + QString modestMessageId = modestMessageIdFromMessageId(id); + + MessagingModestMessage modestMessage = messageFromModest(modestAccountId, + modestFolderId, + modestMessageId); + + if (modestMessage.flags & MessagingModestMessageDeleted) { + return QMessage(); + } + + if (modestMessage.accountId.isEmpty()) { + return QMessage(); + } + + message = messageFromModestMessage(modestMessage, accountIdFromMessageId(id)); + MessageCache::instance()->insert(message); } - return messageFromModestMessage(modestMessage, accountIdFromMessageId(id)); + return message; } QMessage::StandardFolder ModestEngine::standardFolderFromModestFolderId(const QString& modestFolderId) const @@ -1352,7 +1387,6 @@ QMessage ModestEngine::messageFromModestMessage(const MessagingModestMessage& mo { QMessage message; QMessagePrivate* privateMessage = QMessagePrivate::implementation(message); - QMessageContentContainerPrivate* container = QMessagePrivate::containerImplementation(message); // Type message.setType(QMessage::Email); @@ -1398,6 +1432,88 @@ QMessage ModestEngine::messageFromModestMessage(const MessagingModestMessage& mo break; } + // Standard Folder + QMessagePrivate::setStandardFolder(message, + standardFolderFromModestFolderId(modestMessage.folderId)); + + // MIME information (for actual message & attachments) + mimeInformationFromModestMessageToMessage(modestMessage, message); + + // From + if (modestMessage.from.size() > 0) { + message.setFrom(QMessageAddress(QMessageAddress::Email, modestMessage.from)); + QMessagePrivate::setSenderName(message, modestMessage.from); + } + + // To + if (modestMessage.to.size() > 0) { + QMessageAddressList toAddresses; + foreach (const QString &element, modestMessage.to.split(",", QString::SkipEmptyParts)) { + QMessageAddress addr; + addr.setType(QMessageAddress::Email); + addr.setAddressee(element.trimmed()); + toAddresses.append(addr); + } + message.setTo(toAddresses); + } + + // Cc + if (modestMessage.cc.size() > 0) { + QMessageAddressList ccAddresses; + foreach (const QString &element, modestMessage.cc.split(",", QString::SkipEmptyParts)) { + QMessageAddress addr; + addr.setType(QMessageAddress::Email); + addr.setAddressee(element.trimmed()); + ccAddresses.append(addr); + } + message.setCc(ccAddresses); + } + + // Bcc + if (modestMessage.bcc.size() > 0) { + QMessageAddressList bccAddresses; + foreach (const QString &element, modestMessage.bcc.split(",", QString::SkipEmptyParts)) { + QMessageAddress addr; + addr.setType(QMessageAddress::Email); + addr.setAddressee(element.trimmed()); + bccAddresses.append(addr); + } + message.setBcc(bccAddresses); + } + + // Subject + message.setSubject(modestMessage.subject); + + // Size + privateMessage->_size = modestMessage.size; + + // Read Status + if (modestMessage.flags & MessagingModestMessageSeen) { + privateMessage->_status = privateMessage->_status | QMessage::Read; + } + + // Attachments Status + if (modestMessage.flags & MessagingModestMessageAttachments) { + privateMessage->_status = privateMessage->_status | QMessage::HasAttachments; + } + + // Modest specific url + privateMessage->_url = modestMessage.url; + + // Modified flag + privateMessage->_modified = false; + + return message; +} + +void ModestEngine::mimeInformationFromModestMessageToMessage(const MessagingModestMessage& modestMessage, + QMessage& message) const +{ + QMessagePrivate* privateMessage = QMessagePrivate::implementation(message); + QMessageContentContainerPrivate* container = QMessagePrivate::containerImplementation(message); + + QMessageId messageId = message.id(); + // Message MIME type QString fullMimeType = modestMessage.mimeType; int slashIndex = fullMimeType.indexOf('/'); @@ -1406,10 +1522,6 @@ QMessage ModestEngine::messageFromModestMessage(const MessagingModestMessage& mo container->_type = mimeType.data(); container->_subType = mimeSubType.data(); - // Standard Folder - QMessagePrivate::setStandardFolder(message, - standardFolderFromModestFolderId(modestMessage.folderId)); - // Body & Attachments handling for (int i=0; i < modestMessage.mimeParts.count(); i++) { if (!modestMessage.mimeParts[i].isAttachment) { @@ -1519,72 +1631,6 @@ QMessage ModestEngine::messageFromModestMessage(const MessagingModestMessage& mo appendAttachmentToMessage(message, attachment); } } - - // From - if (modestMessage.from.size() > 0) { - message.setFrom(QMessageAddress(QMessageAddress::Email, modestMessage.from)); - QMessagePrivate::setSenderName(message, modestMessage.from); - } - - // To - if (modestMessage.to.size() > 0) { - QMessageAddressList toAddresses; - foreach (const QString &element, modestMessage.to.split(",", QString::SkipEmptyParts)) { - QMessageAddress addr; - addr.setType(QMessageAddress::Email); - addr.setAddressee(element.trimmed()); - toAddresses.append(addr); - } - message.setTo(toAddresses); - } - - // Cc - if (modestMessage.cc.size() > 0) { - QMessageAddressList ccAddresses; - foreach (const QString &element, modestMessage.cc.split(",", QString::SkipEmptyParts)) { - QMessageAddress addr; - addr.setType(QMessageAddress::Email); - addr.setAddressee(element.trimmed()); - ccAddresses.append(addr); - } - message.setCc(ccAddresses); - } - - // Bcc - if (modestMessage.bcc.size() > 0) { - QMessageAddressList bccAddresses; - foreach (const QString &element, modestMessage.bcc.split(",", QString::SkipEmptyParts)) { - QMessageAddress addr; - addr.setType(QMessageAddress::Email); - addr.setAddressee(element.trimmed()); - bccAddresses.append(addr); - } - message.setBcc(bccAddresses); - } - - // Subject - message.setSubject(modestMessage.subject); - - // Size - privateMessage->_size = modestMessage.size; - - // Read Status - if (modestMessage.flags & MessagingModestMessageSeen) { - privateMessage->_status = privateMessage->_status | QMessage::Read; - } - - // Attachments Status - if (modestMessage.flags & MessagingModestMessageAttachments) { - privateMessage->_status = privateMessage->_status | QMessage::HasAttachments; - } - - // Modest specific url - privateMessage->_url = modestMessage.url; - - // Modified flag - privateMessage->_modified = false; - - return message; } void ModestEngine::appendAttachmentToMessage(QMessage& message, QMessageContentContainer& attachment) const @@ -1701,6 +1747,9 @@ bool ModestEngine::addMessage(QMessage &message) // immediately after message creation in add call updateMessage(message); + // Make sure that there will be instant notification about added message + notification(message.id(), ModestEngine::Added); + return true; } @@ -1777,7 +1826,7 @@ bool ModestEngine::removeMessage(const QMessageId &id, QMessageManager::RemovalO } else { m_ModestDBusInterface->call(MODEST_DBUS_METHOD_DELETE_MESSAGE, privateMessage->_url); - // Make sure that there will instant notification about removed message + // Make sure that there will be instant notification about removed message notification(id, ModestEngine::Removed); } return true; @@ -1901,6 +1950,7 @@ bool ModestEngine::countMessages(QMessageService& messageService, const QMessage MessageQueryInfo &queryInfo = m_pendingMessageQueries[m_pendingMessageQueries.count()-1]; + queryInfo.queryId = -1; queryInfo.filter = filter; queryInfo.limit = 0; queryInfo.offset = 0; @@ -1909,11 +1959,41 @@ bool ModestEngine::countMessages(QMessageService& messageService, const QMessage queryInfo.handledFiltersCount = 0; queryInfo.isQuery = false; queryInfo.returnWithSingleShot = false; + queryInfo.allMessagesQuery = false; + queryInfo.queryThread = 0; - if (!startQueryingAndFilteringMessages(m_pendingMessageQueries[m_pendingMessageQueries.count()-1])) { - QMessageServicePrivate::implementation(messageService)->setFinished(false); - m_pendingMessageQueries.removeAt(m_pendingMessageQueries.count()-1); - return false; + if (m_allEmailMessagesInCache) { + queryInfo.queryThread = new MessageQueryThread(filter, QMessageSortOrder()); + connect(queryInfo.queryThread, SIGNAL(queryFinished(void*, QList<QtMobility::QMessageId>)), + this, SLOT(messageQueryFinishedSlot(void*, QList<QtMobility::QMessageId>))); + + queryInfo.queryThread->start(); + } else { + if (!startQueryingAndFilteringMessages(m_pendingMessageQueries[m_pendingMessageQueries.count()-1])) { + m_pendingMessageQueries.removeAt(m_pendingMessageQueries.count()-1); + if (m_pendingMessageQueries.count() == 0) { + // This was last query in pending queries queue + // => Disconnect from "GetHeaders" request related DBus signals + // Note: Disconnecting signals is done to optimize signal handling + // <=> Disconnecting prevents unnecessary handling of signals + // which have been sent from other applications using + // Qt Mobility Messaging API + m_QtmPluginDBusInterface->connection().disconnect(MODESTENGINE_QTM_PLUGIN_NAME, + MODESTENGINE_QTM_PLUGIN_PATH, + MODESTENGINE_QTM_PLUGIN_NAME, + "HeadersReceived", + (ModestEngine*)this, + SLOT(searchMessagesHeadersReceivedSlot(QDBusMessage))); + + m_QtmPluginDBusInterface->connection().disconnect(MODESTENGINE_QTM_PLUGIN_NAME, + MODESTENGINE_QTM_PLUGIN_PATH, + MODESTENGINE_QTM_PLUGIN_NAME, + "HeadersFetched", + (ModestEngine*)this, + SLOT(searchMessagesHeadersFetchedSlot(QDBusMessage))); + } + return false; + } } return true; @@ -1931,6 +2011,7 @@ bool ModestEngine::queryMessages(QMessageService& messageService, const QMessage MessageQueryInfo &queryInfo = m_pendingMessageQueries[m_pendingMessageQueries.count()-1]; + queryInfo.queryId = -1; queryInfo.body = body; queryInfo.matchFlags = matchFlags; queryInfo.filter = filter; @@ -1942,31 +2023,40 @@ bool ModestEngine::queryMessages(QMessageService& messageService, const QMessage queryInfo.handledFiltersCount = 0; queryInfo.isQuery = true; queryInfo.returnWithSingleShot = false; + queryInfo.allMessagesQuery = false; + queryInfo.queryThread = 0; + + if (m_allEmailMessagesInCache) { + queryInfo.queryThread = new MessageQueryThread(filter, sortOrder); + connect(queryInfo.queryThread, SIGNAL(queryFinished(void*, QList<QtMobility::QMessageId>)), + this, SLOT(messageQueryFinishedSlot(void*, QList<QtMobility::QMessageId>))); + queryInfo.queryThread->start(); + } else { + if (!startQueryingAndFilteringMessages(m_pendingMessageQueries[m_pendingMessageQueries.count()-1])) { + m_pendingMessageQueries.removeAt(m_pendingMessageQueries.count()-1); + if (m_pendingMessageQueries.count() == 0) { + // This was last query in pending queries queue + // => Disconnect from "GetHeaders" request related DBus signals + // Note: Disconnecting signals is done to optimize signal handling + // <=> Disconnecting prevents unnecessary handling of signals + // which have been sent from other applications using + // Qt Mobility Messaging API + m_QtmPluginDBusInterface->connection().disconnect(MODESTENGINE_QTM_PLUGIN_NAME, + MODESTENGINE_QTM_PLUGIN_PATH, + MODESTENGINE_QTM_PLUGIN_NAME, + "HeadersReceived", + (ModestEngine*)this, + SLOT(searchMessagesHeadersReceivedSlot(QDBusMessage))); - if (!startQueryingAndFilteringMessages(m_pendingMessageQueries[m_pendingMessageQueries.count()-1])) { - m_pendingMessageQueries.removeAt(m_pendingMessageQueries.count()-1); - if (m_pendingMessageQueries.count() == 0) { - // This was last query in pending queries queue - // => Disconnect from "GetHeaders" request related DBus signals - // Note: Disconnecting signals is done to optimize signal handling - // <=> Disconnecting prevents unnecessary handling of signals - // which have been sent from other applications using - // Qt Mobility Messaging API - m_QtmPluginDBusInterface->connection().disconnect(MODESTENGINE_QTM_PLUGIN_NAME, - MODESTENGINE_QTM_PLUGIN_PATH, - MODESTENGINE_QTM_PLUGIN_NAME, - "HeadersReceived", - (ModestEngine*)this, - SLOT(searchMessagesHeadersReceivedSlot(QDBusMessage))); - - m_QtmPluginDBusInterface->connection().disconnect(MODESTENGINE_QTM_PLUGIN_NAME, - MODESTENGINE_QTM_PLUGIN_PATH, - MODESTENGINE_QTM_PLUGIN_NAME, - "HeadersFetched", - (ModestEngine*)this, - SLOT(searchMessagesHeadersFetchedSlot(QDBusMessage))); + m_QtmPluginDBusInterface->connection().disconnect(MODESTENGINE_QTM_PLUGIN_NAME, + MODESTENGINE_QTM_PLUGIN_PATH, + MODESTENGINE_QTM_PLUGIN_NAME, + "HeadersFetched", + (ModestEngine*)this, + SLOT(searchMessagesHeadersFetchedSlot(QDBusMessage))); + } + return false; } - return false; } return true; @@ -2272,6 +2362,12 @@ bool ModestEngine::searchMessages(MessageQueryInfo &msgQueryInfo, const QStringL } } + if (sDate == 0 && eDate == 0 && accountIds.isEmpty() && folderUris.isEmpty()) { + msgQueryInfo.allMessagesQuery = true; + } else { + msgQueryInfo.allMessagesQuery = false; + } + if (m_pendingMessageQueries.count() == 1) { // This is the first query in pending queries queue // => connect to signals @@ -2297,7 +2393,6 @@ bool ModestEngine::searchMessages(MessageQueryInfo &msgQueryInfo, const QStringL eDate, false); if (reply.type() != QDBusMessage::ErrorMessage) { - m_messageCache.clear(); msgQueryInfo.queryId = reply.arguments().takeFirst().toInt(); } else { return false; @@ -2403,9 +2498,11 @@ void ModestEngine::searchMessagesHeadersReceivedSlot(QDBusMessage msg) } } - QMessage message = messageFromModestMessage(modestMessage); + QMessage *message = new QMessage(messageFromModestMessage(modestMessage)); + QMessagePrivate* privateMessage = QMessagePrivate::implementation(*message); + privateMessage->_mimeInformationRetrieved = false; + if (reportedAccountId == "local_folders") { - QMessagePrivate* privateMessage = QMessagePrivate::implementation(message); QString id = privateMessage->_id.toString(); QString newProtocol = "maildir"; replaceProtocol(id, newProtocol); @@ -2414,14 +2511,13 @@ void ModestEngine::searchMessagesHeadersReceivedSlot(QDBusMessage msg) replaceProtocol(id, newProtocol); privateMessage->_parentFolderId = QMessageFolderId(id); } - if (filterMessage(message, filters, 0)) { - if (!queryInfo.ids.contains(message.id())) { - if (m_messageCache.size() < maxCacheSize) { - m_messageCache.insert(message.id().toString(), message); - } - queryInfo.ids.append(message.id()); + + if (filterMessage(*message, filters, 0)) { + if (!queryInfo.ids.contains(message->id())) { + queryInfo.ids.append(message->id()); } } + MessageCache::instance()->insertObject(message); } } @@ -2469,6 +2565,11 @@ void ModestEngine::handleQueryFinished(int index) const } else { queryInfo.privateService->messagesCounted(queryInfo.ids.count()); } + + if (queryInfo.allMessagesQuery && !MessageCache::instance()->isFull()) { + m_allEmailMessagesInCache = true; + } + m_pendingMessageQueries.removeAt(index); if (m_pendingMessageQueries.count() == 0) { @@ -2494,6 +2595,29 @@ void ModestEngine::handleQueryFinished(int index) const } } +void ModestEngine::messageQueryFinishedSlot(void* queryThread, QList<QtMobility::QMessageId> ids) +{ + int index = -1; + for (int i=0; i < m_pendingMessageQueries.count(); i++) { + if (m_pendingMessageQueries[i].queryThread == queryThread) { + index = i; + break; + } + } + + if (index >= 0) { + MessageQueryInfo &queryInfo = m_pendingMessageQueries[index]; + + if (queryInfo.isQuery) { + queryInfo.privateService->messagesFound(ids, true, true); + } else { + queryInfo.privateService->messagesCounted(ids.count()); + } + + m_pendingMessageQueries.removeAt(index); + } +} + void ModestEngine::sendEmailCallEnded(QDBusPendingCallWatcher *watcher) { @@ -2869,35 +2993,42 @@ void ModestEngine::notification(const QMessageId& messageId, NotificationType no } QMessageManager::NotificationFilterIdSet matchingFilters; + QMessage message; + + MessagingModestMessage modestMessage = messageFromModest(modestAccountId, + modestFolderId, + modestMessageId); + + if (modestMessage.accountId.isEmpty()) { + return; + } + + if (modestMessage.flags & MessagingModestMessageDeleted) { + notificationType = ModestEngine::Removed; + } + if (modestMessage.size == 0) { + notificationType = ModestEngine::Removed; + } + + message = messageFromModestMessage(modestMessage); + + realMessageId = message.id(); + + if (notificationType == ModestEngine::Added) { + MessageCache::instance()->insert(message); + } else if (notificationType == ModestEngine::Updated) { + MessageCache::instance()->update(message); + } else if (notificationType == ModestEngine::Removed) { + MessageCache::instance()->remove(message.id()); + } // Copy the filter map to protect against modification during traversal QMap<int, QMessageFilter> filters(m_filters); QMap<int, QMessageFilter>::const_iterator it = filters.begin(), end = filters.end(); - QMessage message; - bool messageRetrieved = false; + int counter = 1; for ( ; it != end; ++it) { const QMessageFilter &filter(it.value()); - - if (!messageRetrieved) { - MessagingModestMessage modestMessage = messageFromModest(modestAccountId, - modestFolderId, - modestMessageId); - - if (modestMessage.accountId.isEmpty()) { - return; - } - - if (modestMessage.flags & MessagingModestMessageDeleted) { - notificationType = ModestEngine::Removed; - } - if (modestMessage.size == 0) { - notificationType = ModestEngine::Removed; - } - - message = messageFromModestMessage(modestMessage); - realMessageId =message.id(); - messageRetrieved = true; - } + counter++; if (filter.isEmpty()) { // Empty filter matches to all messages @@ -3670,9 +3801,36 @@ ModestStringMap ModestEngine::getModestHeaders(QMessage &message) return ModestStringMap(); // stub } -void ModestEngine::clearHeaderCache() +MessageQueryThread::MessageQueryThread(const QMessageFilter &filter, + const QMessageSortOrder &sortOrder) + : m_filter(filter), m_sortOrder(sortOrder) { - m_messageCache.clear(); +} + +MessageQueryThread::~MessageQueryThread() +{ + // Tell the thread's event loop to exit + // => thread returns from the call to exec() + exit(); + + // Wait until this thread has finished execution + // <=> waits until thread returns from run() + wait(); +} + +void MessageQueryThread::run() +{ + QMessageIdList ids = MessageCache::instance()->messageIds(); + + MessagingHelper::filterMessages(ids, m_filter & QMessageFilter::byType(QMessage::Email)); + MessagingHelper::orderMessages(ids, m_sortOrder); + + emit queryFinished(this, ids); + + QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection); + + // Enter the thread event loop + (void) exec(); } #include "moc_modestengine_maemo_p.cpp" diff --git a/src/messaging/modestengine_maemo_p.h b/src/messaging/modestengine_maemo_p.h index ecc96c2149..2265216e28 100644 --- a/src/messaging/modestengine_maemo_p.h +++ b/src/messaging/modestengine_maemo_p.h @@ -72,6 +72,7 @@ static const int maxCacheSize = 100000; class QMessageService; class QMessageServicePrivate; class QMessageStorePrivate; +class MessageQueryThread; struct MessageQueryInfo { @@ -90,6 +91,8 @@ struct MessageQueryInfo QString realAccountId; bool isQuery; bool returnWithSingleShot; + bool allMessagesQuery; + MessageQueryThread *queryThread; }; struct ModestUnreadMessageDBusStruct @@ -311,7 +314,7 @@ public: bool retrieveBody(QMessageService& messageService, const QMessageId &id); bool retrieve(QMessageService& messageService, const QMessageId &messageId, const QMessageContentContainerId &id, QMessage *msg = 0); - void clearHeaderCache(); + bool retrieveMessageMimeInformation(QMessage& message); private: QFileInfoList localFolders() const; @@ -391,6 +394,10 @@ private: bool accountExists(const QMessageAccountId& accountId) const; + void mimeInformationFromModestMessageToMessage(const MessagingModestMessage& modestMessage, + QMessage& message) const; + + private slots: void searchMessagesHeadersReceivedSlot(QDBusMessage msg); void searchMessagesHeadersFetchedSlot(QDBusMessage msg); @@ -405,6 +412,7 @@ private slots: void stateChanged(QMessageService::State newState); void returnQueryResultsSlot(); void modestFolderContentsChangedSlot(QDBusMessage msg); + void messageQueryFinishedSlot(void* queryThread, QList<QtMobility::QMessageId> ids); private: //Data GConfClient *m_gconfclient; @@ -417,7 +425,6 @@ private: //Data mutable QHash<QString, QMessageAccount> iAccounts; mutable QMessageAccountId iDefaultEmailAccountId; - mutable int m_queryIds; mutable QList<MessageQueryInfo> m_pendingMessageQueries; QMap<QMessageManager::NotificationFilterId, QMessageFilter> m_filters; @@ -429,12 +436,13 @@ private: //Data mutable QStringList m_latestAddOrRemoveNotifications; mutable QMap<QString, MessagingModestFolder> m_folderCache; - mutable QMap<QString, QMessage> m_messageCache; mutable QMap<int, QMessageServicePrivate*> m_pending_downloads; mutable QMessageFolderIdList m_observed_folders; + mutable bool m_allEmailMessagesInCache; + // Following variables are used for sync queries mutable QMessageService m_service; mutable QEventLoop m_eventLoop; @@ -444,6 +452,24 @@ private: //Data mutable bool m_isFiltered; }; +class MessageQueryThread : public QThread +{ + Q_OBJECT + +public: + MessageQueryThread(const QMessageFilter &filter, const QMessageSortOrder &sortOrder); + ~MessageQueryThread(); + + void run(); + +signals: + void queryFinished(void* queryThread, QList<QtMobility::QMessageId> ids); + +private: + QMessageFilter m_filter; + QMessageSortOrder m_sortOrder; +}; + QTM_END_NAMESPACE // Marshall the MyStructure data into a D-Bus argument @@ -460,6 +486,7 @@ Q_DECLARE_METATYPE(QtMobility::ModestAccountsUnreadMessagesDBusStruct); Q_DECLARE_METATYPE(QtMobility::ModestMessage); Q_DECLARE_METATYPE(QtMobility::MessagingModestMimePart); Q_DECLARE_METATYPE(QtMobility::MessagingModestFolder); +Q_DECLARE_METATYPE(QList<QtMobility::QMessageId>); #endif // MODESTENGINE_MAEMO_H diff --git a/src/messaging/qfsengine_symbian.cpp b/src/messaging/qfsengine_symbian.cpp index 0ce94b0b8c..835bcadd2b 100644 --- a/src/messaging/qfsengine_symbian.cpp +++ b/src/messaging/qfsengine_symbian.cpp @@ -68,13 +68,17 @@ #include <memailcontent.h> #include <mmessageiterator.h> +#include <QThreadStorage> +#include <QCoreApplication> + using namespace EmailInterface; QTM_BEGIN_NAMESPACE using namespace SymbianHelpers; -Q_GLOBAL_STATIC(CFSEngine,fsEngine); +Q_GLOBAL_STATIC(CFSEngine, applicationThreadFsEngine); +Q_GLOBAL_STATIC(QThreadStorage<CFSEngine *>, fsEngineThreadStorage) CFSEngine::CFSEngine() { @@ -95,32 +99,70 @@ CFSEngine::CFSEngine() CFSEngine::~CFSEngine() { + m_mtmAccountList.clear(); + for (TInt i = 0; i < m_attachments.Count(); i++){ + m_attachments[i]->Release(); + } + m_attachments.Reset(); + + for (TInt i = 0; i < m_mailboxes.Count(); i++){ + m_mailboxes[i]->Release(); + } + m_mailboxes.Reset(); + + if (m_clientApi) { + m_clientApi->Release(); + m_clientApi = NULL; + } + + if (m_factory) { + delete m_factory; + m_factory = NULL; + } } void CFSEngine::cleanupFSBackend() { m_mtmAccountList.clear(); + for (TInt i = 0; i < m_attachments.Count(); i++){ m_attachments[i]->Release(); } m_attachments.Reset(); + for (TInt i = 0; i < m_mailboxes.Count(); i++){ m_mailboxes[i]->Release(); } m_mailboxes.Reset(); - m_clientApi->Release(); - delete m_factory; + + if (m_clientApi) { + m_clientApi->Release(); + m_clientApi = NULL; + } + + if (m_factory) { + delete m_factory; + m_factory = NULL; + } } CFSEngine* CFSEngine::instance() { - return fsEngine(); + if (QCoreApplication::instance() && QCoreApplication::instance()->thread() == QThread::currentThread()) { + return applicationThreadFsEngine(); + } + + if (!fsEngineThreadStorage()->hasLocalData()) { + fsEngineThreadStorage()->setLocalData(new CFSEngine); + } + + return fsEngineThreadStorage()->localData(); } bool CFSEngine::accountLessThan(const QMessageAccountId accountId1, const QMessageAccountId accountId2) { - CFSEngine* freestyleEngine = fsEngine(); + CFSEngine* freestyleEngine = instance(); return QMessageAccountSortOrderPrivate::lessThan(freestyleEngine->m_currentAccountOrdering, freestyleEngine->account(accountId1), freestyleEngine->account(accountId2)); @@ -135,7 +177,7 @@ void CFSEngine::orderAccounts(QMessageAccountIdList& accountIds, const QMessageA bool CFSEngine::folderLessThan(const QMessageFolderId folderId1, const QMessageFolderId folderId2) { - CFSEngine* freestyleEngine = fsEngine(); + CFSEngine* freestyleEngine = instance(); return QMessageFolderSortOrderPrivate::lessThan(freestyleEngine->m_currentFolderOrdering, freestyleEngine->folder(folderId1), freestyleEngine->folder(folderId2)); @@ -149,7 +191,7 @@ void CFSEngine::orderFolders(QMessageFolderIdList& folderIds, const QMessageFol bool CFSEngine::messageLessThan(const QMessage& message1, const QMessage& message2) { - CFSEngine* freestyleEngine = fsEngine(); + CFSEngine* freestyleEngine = instance(); return QMessageSortOrderPrivate::lessThan(freestyleEngine->m_currentMessageOrdering, message1, message2); } @@ -1369,6 +1411,12 @@ void CFSEngine::applyOffsetAndLimitToMsgIds(QMessageIdList& idList, int offset, QMessageManager::NotificationFilterId CFSEngine::registerNotificationFilter(QMessageStorePrivate& aPrivateStore, const QMessageFilter &filter, QMessageManager::NotificationFilterId aId) { + if (QCoreApplication::instance() && QCoreApplication::instance()->thread() != QThread::currentThread()) { + if (this != applicationThreadFsEngine()) { + return applicationThreadFsEngine()->registerNotificationFilter(aPrivateStore, filter, aId); + } + } + ipMessageStorePrivate = &aPrivateStore; iListenForNotifications = true; @@ -1381,6 +1429,12 @@ QMessageManager::NotificationFilterId CFSEngine::registerNotificationFilter(QMes void CFSEngine::unregisterNotificationFilter(QMessageManager::NotificationFilterId notificationFilterId) { + if (QCoreApplication::instance() && QCoreApplication::instance()->thread() != QThread::currentThread()) { + if (this != applicationThreadFsEngine()) { + return applicationThreadFsEngine()->unregisterNotificationFilter(notificationFilterId); + } + } + m_filters.remove(notificationFilterId); if (m_filters.count() == 0) { iListenForNotifications = false; diff --git a/src/messaging/qmessage_maemo.cpp b/src/messaging/qmessage_maemo.cpp index b7c882e472..d05824a0dd 100644 --- a/src/messaging/qmessage_maemo.cpp +++ b/src/messaging/qmessage_maemo.cpp @@ -43,6 +43,7 @@ #include "qmessagecontentcontainer_maemo_p.h" #include "qmessagemanager.h" #include "qmessageid_p.h" +#include "modestengine_maemo_p.h" QTM_BEGIN_NAMESPACE @@ -96,6 +97,7 @@ QMessage::QMessage() setDerivedMessage(this); d_ptr->_size = 0; d_ptr->_modified = false; + d_ptr->_mimeInformationRetrieved = true; } QMessage::QMessage(const QMessageId& id) @@ -285,6 +287,10 @@ void QMessage::setPriority(Priority newPriority) int QMessage::size() const { + if (d_ptr->_type == QMessage::Email) { + ModestEngine::instance()->retrieveMessageMimeInformation(*(QMessage*)this); + } + int size = 0; if (d_ptr->_size != 0) { size = d_ptr->_size; @@ -305,6 +311,9 @@ QMessageContentContainerId QMessage::bodyId() const // TODO: Example body finding algorithm. // If the content type of the message is text, then that is the body // otherwise if the first part of the body is text then that is the body. + if (d_ptr->_type == QMessage::Email) { + ModestEngine::instance()->retrieveMessageMimeInformation(*(QMessage*)this); + } return d_ptr->_bodyId; } @@ -380,6 +389,10 @@ QMessageContentContainerIdList QMessage::attachmentIds() const { QMessageContentContainerIdList ids; + if (d_ptr->_type == QMessage::Email) { + ModestEngine::instance()->retrieveMessageMimeInformation(*(QMessage*)this); + } + QMessageContentContainerId msgBodyId(bodyId()); foreach (const QMessageContentContainerId &contentId, contentIds()) { if (contentId != msgBodyId) { @@ -392,6 +405,10 @@ QMessageContentContainerIdList QMessage::attachmentIds() const void QMessage::appendAttachments(const QStringList &fileNames) { + if (d_ptr->_type == QMessage::Email) { + ModestEngine::instance()->retrieveMessageMimeInformation(*(QMessage*)this); + } + if (!fileNames.isEmpty()) { d_ptr->_modified = true; @@ -441,6 +458,10 @@ bool QMessage::isModified() const QMessage QMessage::createResponseMessage(ResponseType type) const { + if (d_ptr->_type == QMessage::Email) { + ModestEngine::instance()->retrieveMessageMimeInformation(*(QMessage*)this); + } + QMessage message; message.setType(d_ptr->_type); message.setParentAccountId(d_ptr->_parentAccountId); diff --git a/src/messaging/qmessage_p.h b/src/messaging/qmessage_p.h index b875ca603b..540540ef48 100644 --- a/src/messaging/qmessage_p.h +++ b/src/messaging/qmessage_p.h @@ -137,6 +137,8 @@ public: #if defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6) QString _url; + bool _mimeInformationRetrieved; + static QMessagePrivate* implementation(const QMessage &message); static QMessageContentContainerPrivate* containerImplementation(const QMessage &message); #endif diff --git a/src/messaging/qmessageaccountfilter.cpp b/src/messaging/qmessageaccountfilter.cpp index 57f03a34a4..94f61b6bc0 100644 --- a/src/messaging/qmessageaccountfilter.cpp +++ b/src/messaging/qmessageaccountfilter.cpp @@ -116,8 +116,11 @@ QTM_BEGIN_NAMESPACE An empty filter matches all accounts. - The result of combining an empty filter with a non-empty filter is the original non-empty filter. - This is true regardless of whether the combination is formed by an AND or an OR operation. + The result of combining an empty filter with a non-empty filter using an AND operation is the + original non-empty filter. + + The result of combining an empty filter with a non-empty filter using an OR operation is the + empty filter. The result of combining two empty filters is an empty filter. */ diff --git a/src/messaging/qmessagefilter.cpp b/src/messaging/qmessagefilter.cpp index 152d0406ae..f6603e8d79 100644 --- a/src/messaging/qmessagefilter.cpp +++ b/src/messaging/qmessagefilter.cpp @@ -126,8 +126,11 @@ QTM_BEGIN_NAMESPACE An empty filter matches all messages. - The result of combining an empty filter with a non-empty filter is the original non-empty filter. - This is true regardless of whether the combination is formed by an AND or an OR operation. + The result of combining an empty filter with a non-empty filter using an AND operation is the + original non-empty filter. + + The result of combining an empty filter with a non-empty filter using an OR operation is the + empty filter. The result of combining two empty filters is an empty filter. */ diff --git a/src/messaging/qmessagefilter_maemo.cpp b/src/messaging/qmessagefilter_maemo.cpp index 25d5b6b0e7..b5dbf6f02d 100644 --- a/src/messaging/qmessagefilter_maemo.cpp +++ b/src/messaging/qmessagefilter_maemo.cpp @@ -638,6 +638,199 @@ bool QMessageFilterPrivate::filter(const QMessage &message) const return result; } +bool QMessageFilterPrivate::preFilter(QMessage::Type type, const QString &idPrefix, const QMessageFilterPrivate &privateFilter) +{ + bool result = true; + + switch (privateFilter._field) { + case QMessageFilterPrivate::Id: + { + if (privateFilter._comparatorType == QMessageFilterPrivate::Equality) { + QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(privateFilter._comparatorValue)); + if (cmp == QMessageDataComparator::Equal) { + if (!privateFilter._value.toString().isEmpty()) { + if (!privateFilter._value.toString().startsWith(idPrefix)) { + result = false; + } + } + } else { // NotEqual + // => Filter must be handled + } + } else if (privateFilter._comparatorType == QMessageFilterPrivate::Inclusion) { + QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(privateFilter._comparatorValue)); + if (privateFilter._ids.count() > 0) { // QMessageIdList + if (cmp == QMessageDataComparator::Includes) { + result = false; + for (int i = 0; i < privateFilter._ids.count(); i++) { + if (privateFilter._ids[i].toString().startsWith(idPrefix)) { + result = true; + break; + } + } + } else { // Excludes + // => Filter must be handled + } + } else { // QMessageFilter + if (cmp == QMessageDataComparator::Includes) { + // TODO: + } else { // Excludes + // TODO: + } + } + } + break; + } + case QMessageFilterPrivate::Type: + { + QMessage::Type typeFromFilter = static_cast<QMessage::Type>(privateFilter._value.toInt()); + if (privateFilter._comparatorType == QMessageFilterPrivate::Equality) { + QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(privateFilter._comparatorValue)); + if (cmp == QMessageDataComparator::Equal) { + if (typeFromFilter != QMessage::NoType && type != typeFromFilter) { + result = false; + } + } else { // NotEqual + if (typeFromFilter != QMessage::NoType && type == typeFromFilter) { + result = false; + } + } + } else if (privateFilter._comparatorType == QMessageFilterPrivate::Inclusion) { + QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(privateFilter._comparatorValue)); + if (cmp == QMessageDataComparator::Includes) { + if ((type & typeFromFilter) == 0) { + result = false; + } + } else { // Excludes + if ((type & typeFromFilter) == type) { + result = false; + } + } + } + break; + } + case QMessageFilterPrivate::ParentAccountId: + { + if (privateFilter._comparatorType == QMessageFilterPrivate::Equality) { + QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(privateFilter._comparatorValue)); + if (cmp == QMessageDataComparator::Equal) { + if (!privateFilter._value.toString().isEmpty()) { + if (!privateFilter._value.toString().startsWith(idPrefix)) { + result = false; + } + } + } else { // NotEqual + // => Filter must be handled + } + } + break; + } + case QMessageFilterPrivate::ParentFolderId: + { + if (privateFilter._comparatorType == QMessageFilterPrivate::Equality) { + QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(privateFilter._comparatorValue)); + if (cmp == QMessageDataComparator::Equal) { + if (!privateFilter._value.toString().isEmpty()) { + if (!privateFilter._value.toString().startsWith(idPrefix)) { + result = false; + } + } + } else { // NotEqual + // => Filter must be handled + } + } else if (privateFilter._comparatorType == QMessageFilterPrivate::Inclusion) { + QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(privateFilter._comparatorValue)); + if (cmp == QMessageDataComparator::Includes) { + result = false; + for (int i = 0; i < privateFilter._ids.count(); i++) { + if (privateFilter._ids[i].toString().startsWith(idPrefix)) { + result = true; + break; + } + } + } else { // Excludes + // => Filter must be handled + } + } + break; + } + case QMessageFilterPrivate::AncestorFolderIds: + { + if (privateFilter._comparatorType == QMessageFilterPrivate::Inclusion) { + QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(privateFilter._comparatorValue)); + if (!privateFilter._value.isNull()) { // QMessageFolderId + if (cmp == QMessageDataComparator::Includes) { + result = false; + for (int i = 0; i < privateFilter._ids.count(); i++) { + if (privateFilter._ids[i].toString().startsWith(idPrefix)) { + result = true; + break; + } + } + } else { // Excludes + // => Filter must be handled + } + } else { // QMessageFolderFilter + if (cmp == QMessageDataComparator::Includes) { + // TODO: + } else { // Excludes + // TODO: + } + } + } + break; + } + case QMessageFilterPrivate::ParentAccountIdFilter: + case QMessageFilterPrivate::ParentFolderIdFilter: + case QMessageFilterPrivate::StandardFolder: + case QMessageFilterPrivate::TimeStamp: + case QMessageFilterPrivate::ReceptionTimeStamp: + case QMessageFilterPrivate::Sender: + case QMessageFilterPrivate::Recipients: + case QMessageFilterPrivate::Subject: + case QMessageFilterPrivate::Status: + case QMessageFilterPrivate::Priority: + case QMessageFilterPrivate::Size: + case QMessageFilterPrivate::None: + break; + } + + return result; +} + +bool QMessageFilterPrivate::preFilterRow(QMessage::Type type, const QString &idPrefix, const SortedMessageFilterList &filterRow) +{ + bool result = true; + + for (int i=0; i < filterRow.count(); i++) { + result = preFilter(type, idPrefix, *filterRow[i].d_ptr); + if (result == false) { + break; + } + } + + return result; +} + +bool QMessageFilterPrivate::preFilter(QMessage::Type type, const QString idPrefix) const +{ + bool result = false; + + SortedMessageFilterList filterRow; + + if (_filterList.count() == 0) { + result = preFilter(type, idPrefix, *this); + } else { + for (int i=0; i < _filterList.count(); i++) { + result = preFilterRow(type, idPrefix, _filterList[i]); + if (result == true) { + break; + } + } + } + + return result; +} + QMessageFilterPrivate* QMessageFilterPrivate::implementation(const QMessageFilter &filter) { diff --git a/src/messaging/qmessagefilter_p.h b/src/messaging/qmessagefilter_p.h index 2dde27dd80..a4a3fb6a4a 100644 --- a/src/messaging/qmessagefilter_p.h +++ b/src/messaging/qmessagefilter_p.h @@ -114,6 +114,16 @@ public: bool filter(const QMessage &message) const; static bool filter(const QMessage &message, const QMessageFilterPrivate &filter); + +#if defined(Q_WS_MAEMO_5) + static bool preFilter(QMessage::Type type, const QString &idPrefix, const QMessageFilterPrivate &privateFilter); + static bool preFilterRow(QMessage::Type type, const QString &idPrefix, const SortedMessageFilterList &filterRow); + bool preFilter(QMessage::Type type, const QString idPrefix = QString()) const; +#else + static bool preFilter(QMessage::Type type, const QString &idPrefix, const QMessageFilterPrivate &privateFilter) { return true; } + static bool preFilterRow(QMessage::Type type, const QString &idPrefix, const SortedMessageFilterList &filterRow) { return true; } + bool preFilter(QMessage::Type type, const QString idPrefix = QString()) const { return true; } +#endif static void changeComparatorValuesToOpposite(QMessageFilter& filter); static void changeANDsAndORsToOpposite(QMessageFilter& filter); diff --git a/src/messaging/qmessagefolderfilter.cpp b/src/messaging/qmessagefolderfilter.cpp index 95aa94db44..36577e36ad 100644 --- a/src/messaging/qmessagefolderfilter.cpp +++ b/src/messaging/qmessagefolderfilter.cpp @@ -116,8 +116,11 @@ QTM_BEGIN_NAMESPACE An empty filter matches all folders. - The result of combining an empty filter with a non-empty filter is the original non-empty filter. - This is true regardless of whether the combination is formed by an AND or an OR operation. + The result of combining an empty filter with a non-empty filter using an AND operation is the + original non-empty filter. + + The result of combining an empty filter with a non-empty filter using an OR operation is the + empty filter. The result of combining two empty filters is an empty filter. */ diff --git a/src/messaging/qmessageid_symbian.cpp b/src/messaging/qmessageid_symbian.cpp index a67497c1cc..97ba2fc7dd 100644 --- a/src/messaging/qmessageid_symbian.cpp +++ b/src/messaging/qmessageid_symbian.cpp @@ -76,6 +76,7 @@ QMessageId& QMessageId::operator=(const QMessageId& other) { if (!other.d_ptr) { delete d_ptr; + d_ptr = 0; return *this; } diff --git a/src/messaging/qmessageservice_maemo.cpp b/src/messaging/qmessageservice_maemo.cpp index 6eaebe5460..4519492c4f 100644 --- a/src/messaging/qmessageservice_maemo.cpp +++ b/src/messaging/qmessageservice_maemo.cpp @@ -59,10 +59,6 @@ QMessageServicePrivate::QMessageServicePrivate(QMessageService* parent) _active(false), _actionId(-1), _pendingRequestCount(0) { -#ifdef EVENTLOGGER_THREAD - connect(EventLoggerEngine::instance(),SIGNAL(messagesFound(const QMessageIdList &,bool,bool)),this,SLOT(messagesFound(const QMessageIdList &,bool,bool))); - -#endif } QMessageServicePrivate::~QMessageServicePrivate() @@ -96,19 +92,29 @@ bool QMessageServicePrivate::queryMessages(QMessageService &messageService, _pendingRequestCount = 0; + bool preFiltered = false; + if (enginesToCall & EnginesToCallTelepathy) { + if (MessagingHelper::preFilter(_filter, QMessage::Sms)) { #ifndef EVENTLOGGER_THREAD - _ids = EventLoggerEngine::instance()->filterAndOrderMessages(filter,sortOrder,QString(),QMessageDataComparator::MatchFlags()); - QMetaObject::invokeMethod(this, "messagesFoundSlot", Qt::QueuedConnection); + _ids = EventLoggerEngine::instance()->filterAndOrderMessages(filter,sortOrder,QString(),QMessageDataComparator::MatchFlags()); + QMetaObject::invokeMethod(this, "messagesFoundSlot", Qt::QueuedConnection); #else - EventLoggerEngine::instance()->filterMessages(_filter,sortOrder,QString(),QMessageDataComparator::MatchFlags()); + EventLoggerEngine::instance()->filterMessages(this, _filter,sortOrder,QString(),QMessageDataComparator::MatchFlags()); #endif - _pendingRequestCount++; + _pendingRequestCount++; + } else { + preFiltered = true; + } } if (enginesToCall & EnginesToCallModest) { - if (ModestEngine::instance()->queryMessages(messageService, _filter, sortOrder, limit, offset)) { - _pendingRequestCount++; + if (MessagingHelper::preFilter(_filter, QMessage::Email)) { + if (ModestEngine::instance()->queryMessages(messageService, _filter, sortOrder, limit, offset)) { + _pendingRequestCount++; + } + } else { + preFiltered = true; } } @@ -120,7 +126,15 @@ bool QMessageServicePrivate::queryMessages(QMessageService &messageService, stateChanged(QMessageService::ActiveState); } else { _filter = QMessageFilter(); - setFinished(false); + if (preFiltered) { + stateChanged(QMessageService::ActiveState); + _pendingRequestCount = 1; + QMetaObject::invokeMethod(this, "messagesFoundSlot", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, "finishedSlot", Qt::QueuedConnection); + return true; + } else { + setFinished(false); + } } return _active; @@ -150,20 +164,30 @@ bool QMessageServicePrivate::queryMessages(QMessageService &messageService, _pendingRequestCount = 0; + bool preFiltered = false; + if (enginesToCall & EnginesToCallTelepathy) { + if (MessagingHelper::preFilter(_filter, QMessage::Sms)) { #ifndef EVENTLOGGER_THREAD - _ids= EventLoggerEngine::instance()->filterAndOrderMessages(filter,sortOrder,body,matchFlags); - QMetaObject::invokeMethod(this, "messagesFoundSlot", Qt::QueuedConnection); + _ids= EventLoggerEngine::instance()->filterAndOrderMessages(filter,sortOrder,body,matchFlags); + QMetaObject::invokeMethod(this, "messagesFoundSlot", Qt::QueuedConnection); #else - EventLoggerEngine::instance()->filterMessages(_filter,sortOrder,body,matchFlags); + EventLoggerEngine::instance()->filterMessages(this, _filter,sortOrder,body,matchFlags); #endif - _pendingRequestCount++; + _pendingRequestCount++; + } else { + preFiltered = true; + } } if (enginesToCall & EnginesToCallModest) { - if (ModestEngine::instance()->queryMessages(messageService, _filter, body, matchFlags, - sortOrder, limit, offset)) { - _pendingRequestCount++; + if (MessagingHelper::preFilter(_filter, QMessage::Email)) { + if (ModestEngine::instance()->queryMessages(messageService, _filter, body, matchFlags, + sortOrder, limit, offset)) { + _pendingRequestCount++; + } + } else { + preFiltered = true; } } @@ -175,7 +199,15 @@ bool QMessageServicePrivate::queryMessages(QMessageService &messageService, stateChanged(QMessageService::ActiveState); } else { _filter = QMessageFilter(); - setFinished(false); + if (preFiltered) { + stateChanged(QMessageService::ActiveState); + _pendingRequestCount = 1; + QMetaObject::invokeMethod(this, "messagesFoundSlot", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, "finishedSlot", Qt::QueuedConnection); + return true; + } else { + setFinished(false); + } } return _active; @@ -199,20 +231,35 @@ bool QMessageServicePrivate::countMessages(QMessageService &messageService, _pendingRequestCount = 0; + bool preFiltered = false; + //TODO: SMS count support //if (enginesToCall & EnginesToCallTelepathy) { //} if (enginesToCall & EnginesToCallModest) { - if (ModestEngine::instance()->countMessages(messageService, handledFilter)) { - _pendingRequestCount++; + if (MessagingHelper::preFilter(handledFilter, QMessage::Email)) { + if (ModestEngine::instance()->countMessages(messageService, handledFilter)) { + _pendingRequestCount++; + } + } else { + preFiltered = true; } } if (_pendingRequestCount > 0) { stateChanged(QMessageService::ActiveState); } else { - setFinished(false); + _filter = QMessageFilter(); + if (preFiltered) { + stateChanged(QMessageService::ActiveState); + _pendingRequestCount = 1; + QMetaObject::invokeMethod(this, "messagesCountedSlot", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, "finishedSlot", Qt::QueuedConnection); + return true; + } else { + setFinished(false); + } } return _active; @@ -231,13 +278,16 @@ void QMessageServicePrivate::setFinished(bool successful) _error = QMessageManager::RequestIncomplete; } - _active = false; stateChanged(QMessageService::FinishedState); } } void QMessageServicePrivate::stateChanged(QMessageService::State state) { + if (state == QMessageService::FinishedState) { + _active = false; + } + _state = state; emit q_ptr->stateChanged(_state); } @@ -269,8 +319,6 @@ void QMessageServicePrivate::messagesFound(const QMessageIdList &ids, bool isFil } MessagingHelper::applyOffsetAndLimitToMessageIdList(_ids, _limit, _offset); - ModestEngine::instance()->clearHeaderCache(); - emit q_ptr->messagesFound(_ids); setFinished(true); @@ -288,12 +336,11 @@ void QMessageServicePrivate::messagesCounted(int count) _count += count; if (_pendingRequestCount == 0) { - ModestEngine::instance()->clearHeaderCache(); - emit q_ptr->messagesCounted(_count); setFinished(true); + _filter = QMessageFilter(); _count = 0; } } @@ -313,6 +360,10 @@ void QMessageServicePrivate::messagesCountedSlot() messagesCounted(0); } +void QMessageServicePrivate::finishedSlot(bool successful) +{ + setFinished(successful); +} QMessageService::QMessageService(QObject *parent) : QObject(parent), @@ -343,7 +394,6 @@ bool QMessageService::countMessages(const QMessageFilter &filter) bool QMessageService::send(QMessage &message) { - qDebug() << "QMessageService::send"; if (d_ptr->_active) { return false; } @@ -434,13 +484,11 @@ bool QMessageService::send(QMessage &message) } d_ptr->setFinished(retVal); - qDebug() << "send returns=" << retVal; return retVal; } bool QMessageService::compose(const QMessage &message) { - // qDebug() << "qMessageService::compose"; if (d_ptr->_active) { return false; } @@ -451,12 +499,10 @@ bool QMessageService::compose(const QMessage &message) bool retVal=false; d_ptr->_state = QMessageService::ActiveState; emit stateChanged(d_ptr->_state); - qDebug() << "qMessageService::compose stateChanged"; if (message.type() == QMessage::Sms && !message.to().isEmpty() && !message.to().first().addressee().isEmpty()) { QUrl smsUrl((QString("sms:%1").arg(message.to().first().addressee()))); smsUrl.addQueryItem("body",message.textContent()); - // qDebug() << "compose SMS url=" << smsUrl.toString(); hildon_uri_open(smsUrl.toString().toStdString().c_str(),NULL,NULL); retVal = true; @@ -470,7 +516,6 @@ bool QMessageService::compose(const QMessage &message) } d_ptr->setFinished(retVal); - // qDebug() << "compose returns=" << retVal; return retVal; } diff --git a/src/messaging/qmessageservice_maemo_p.h b/src/messaging/qmessageservice_maemo_p.h index 931ba104b0..28db39c3d6 100644 --- a/src/messaging/qmessageservice_maemo_p.h +++ b/src/messaging/qmessageservice_maemo_p.h @@ -78,6 +78,7 @@ public: void progressChanged(uint value, uint total); public slots: + void finishedSlot(bool successful = true); void messagesFoundSlot(); void messagesCountedSlot(); void messagesFound(const QMessageIdList &ids, bool isFiltered, bool isSorted); diff --git a/src/messaging/qmessageservice_symbian.cpp b/src/messaging/qmessageservice_symbian.cpp index ab70ba6c5b..6d0b992fd9 100644 --- a/src/messaging/qmessageservice_symbian.cpp +++ b/src/messaging/qmessageservice_symbian.cpp @@ -74,12 +74,12 @@ QMessageServicePrivate::~QMessageServicePrivate() bool QMessageServicePrivate::sendSMS(QMessage &message) { - return CMTMEngine::instance()->sendSMS(message); + return CMTMEngine::instance()->sendSMS((QMessageServicePrivate&)*this, message); } bool QMessageServicePrivate::sendMMS(QMessage &message) { - return CMTMEngine::instance()->sendMMS(message); + return CMTMEngine::instance()->sendMMS((QMessageServicePrivate&)*this, message); } bool QMessageServicePrivate::sendEmail(QMessage &message) @@ -87,14 +87,18 @@ bool QMessageServicePrivate::sendEmail(QMessage &message) switch (idType(message.parentAccountId())) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED - return CFSEngine::instance()->sendEmail(message); + bool retVal = CFSEngine::instance()->sendEmail(message); + if (retVal == true) { + setFinished(retVal); + } + return retVal; #else return false; #endif break; case EngineTypeMTM: default: - return CMTMEngine::instance()->sendEmail(message); + return CMTMEngine::instance()->sendEmail((QMessageServicePrivate&)*this, message); break; } } @@ -328,9 +332,9 @@ void QMessageServicePrivate::setFinished(bool successful) _error = QMessageManager::RequestIncomplete; } + _active = false; _state = QMessageService::FinishedState; emit q_ptr->stateChanged(_state); - _active = false; } QMessageService::QMessageService(QObject *parent) @@ -491,7 +495,9 @@ bool QMessageService::send(QMessage &message) } } - d_ptr->setFinished(retVal); + if (retVal == false) { + d_ptr->setFinished(retVal); + } return retVal; } diff --git a/src/messaging/qmessagestore_maemo.cpp b/src/messaging/qmessagestore_maemo.cpp index 24084777a0..f6e1c0e122 100644 --- a/src/messaging/qmessagestore_maemo.cpp +++ b/src/messaging/qmessagestore_maemo.cpp @@ -136,10 +136,14 @@ QMessageIdList QMessageStore::queryMessages(const QMessageFilter &filter, const bool isFiltered = false; bool isSorted = false; - messageIds = ModestEngine::instance()->queryMessagesSync(handledFilter, sortOrder, limit, offset, - isFiltered, isSorted); + if (MessagingHelper::preFilter(handledFilter, QMessage::Email)) { + messageIds = ModestEngine::instance()->queryMessagesSync(handledFilter, sortOrder, limit, offset, + isFiltered, isSorted); + } - messageIds += EventLoggerEngine::instance()->filterAndOrderMessages(handledFilter,sortOrder,QString(),QMessageDataComparator::MatchFlags()); + if (MessagingHelper::preFilter(handledFilter, QMessage::Sms)) { + messageIds += EventLoggerEngine::instance()->filterAndOrderMessages(handledFilter,sortOrder,QString(),QMessageDataComparator::MatchFlags()); + } if (!isFiltered) { MessagingHelper::filterMessages(messageIds, handledFilter); @@ -149,8 +153,6 @@ QMessageIdList QMessageStore::queryMessages(const QMessageFilter &filter, const } MessagingHelper::applyOffsetAndLimitToMessageIdList(messageIds, limit, offset); - ModestEngine::instance()->clearHeaderCache(); - return messageIds; } @@ -163,10 +165,15 @@ QMessageIdList QMessageStore::queryMessages(const QMessageFilter &filter, const bool isFiltered = false; bool isSorted = false; - messageIds = ModestEngine::instance()->queryMessagesSync(handledFilter, body, matchFlags, sortOrder, - limit, offset, isFiltered, isSorted); - messageIds +=EventLoggerEngine::instance()->filterAndOrderMessages(handledFilter,sortOrder,body,matchFlags); + if (MessagingHelper::preFilter(handledFilter, QMessage::Email)) { + messageIds = ModestEngine::instance()->queryMessagesSync(handledFilter, body, matchFlags, sortOrder, + limit, offset, isFiltered, isSorted); + } + + if (MessagingHelper::preFilter(handledFilter, QMessage::Sms)) { + messageIds +=EventLoggerEngine::instance()->filterAndOrderMessages(handledFilter,sortOrder,body,matchFlags); + } if (!isFiltered) { MessagingHelper::filterMessages(messageIds, handledFilter); @@ -176,8 +183,6 @@ QMessageIdList QMessageStore::queryMessages(const QMessageFilter &filter, const } MessagingHelper::applyOffsetAndLimitToMessageIdList(messageIds, limit, offset); - ModestEngine::instance()->clearHeaderCache(); - return messageIds; } @@ -231,9 +236,14 @@ int QMessageStore::countMessages(const QMessageFilter& filter) const QMessageFilter handledFilter = filter; MessagingHelper::handleNestedFiltersFromMessageFilter(handledFilter); - count += ModestEngine::instance()->countMessagesSync(handledFilter); + if (MessagingHelper::preFilter(handledFilter, QMessage::Email)) { + count += ModestEngine::instance()->countMessagesSync(handledFilter); + } - ModestEngine::instance()->clearHeaderCache(); + if (MessagingHelper::preFilter(handledFilter, QMessage::Sms)) { + QMessageIdList messageIds = EventLoggerEngine::instance()->filterAndOrderMessages(handledFilter,QMessageSortOrder(),QString(),QMessageDataComparator::MatchFlags()); + count += messageIds.count(); + } return count; } @@ -372,6 +382,11 @@ bool QMessageStore::updateMessage(QMessage *m) QMessage QMessageStore::message(const QMessageId& id) const { + QMessage message = MessageCache::instance()->message(id); + if (message.type() != QMessage::NoType) { + return message; + } + if (id.toString().startsWith("MO_")) { return ModestEngine::instance()->message(id); } else { diff --git a/src/messaging/qmessagestore_symbian.cpp b/src/messaging/qmessagestore_symbian.cpp index 868a59eb8c..35a0592477 100644 --- a/src/messaging/qmessagestore_symbian.cpp +++ b/src/messaging/qmessagestore_symbian.cpp @@ -70,9 +70,6 @@ void QMessageStorePrivate::initialize(QMessageStore *store) { q_ptr = store; _mtmEngine = CMTMEngine::instance(); -#ifdef FREESTYLEMAILUSED - _fsEngine = CFSEngine::instance(); -#endif } QMessageIdList QMessageStorePrivate::queryMessages(const QMessageFilter &filter, const QMessageSortOrder &sortOrder, uint limit, uint offset) const @@ -146,8 +143,8 @@ QMessageAccountIdList QMessageStorePrivate::queryAccounts(const QMessageAccountF idList << _mtmEngine->queryAccounts(filter, sortOrder, 0, 0); #ifdef FREESTYLEMAILUSED - _fsEngine->setMtmAccountIdList(idList); - idList << _fsEngine->queryAccounts(filter, sortOrder, 0, 0); + CFSEngine::instance()->setMtmAccountIdList(idList); + idList << CFSEngine::instance()->queryAccounts(filter, sortOrder, 0, 0); #endif MessagingHelper::orderAccounts(idList, sortOrder); @@ -161,7 +158,7 @@ int QMessageStorePrivate::countAccounts(const QMessageAccountFilter &filter) con { int count = 0; #ifdef FREESTYLEMAILUSED - count += _fsEngine->countAccounts(filter); + count += CFSEngine::instance()->countAccounts(filter); #endif count += _mtmEngine->countAccounts(filter); return count; @@ -171,7 +168,7 @@ QMessageFolderIdList QMessageStorePrivate::queryFolders(const QMessageFolderFilt { QMessageFolderIdList idList; #ifdef FREESTYLEMAILUSED - idList << _fsEngine->queryFolders(filter, sortOrder, 0, 0); + idList << CFSEngine::instance()->queryFolders(filter, sortOrder, 0, 0); #endif idList << _mtmEngine->queryFolders(filter, sortOrder, 0, 0); @@ -186,7 +183,7 @@ int QMessageStorePrivate::countFolders(const QMessageFolderFilter& filter) const { int count = 0; #ifdef FREESTYLEMAILUSED - count += _fsEngine->countFolders(filter); + count += CFSEngine::instance()->countFolders(filter); #endif count += _mtmEngine->countFolders(filter); return count; @@ -197,7 +194,7 @@ QMessageFolder QMessageStorePrivate::folder(const QMessageFolderId& id) const switch (idType(id)) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED - return _fsEngine->folder(id); + return CFSEngine::instance()->folder(id); #else return QMessageFolder(); #endif @@ -215,7 +212,7 @@ bool QMessageStorePrivate::addMessage(QMessage *m) switch (idType(m->parentAccountId())) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED - return _fsEngine->addMessage(m); + return CFSEngine::instance()->addMessage(m); #else return false; #endif @@ -232,7 +229,7 @@ bool QMessageStorePrivate::updateMessage(QMessage *m) switch (idType(m->id())) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED - return _fsEngine->updateMessage(m); + return CFSEngine::instance()->updateMessage(m); #else return false; #endif @@ -249,7 +246,7 @@ bool QMessageStorePrivate::removeMessage(const QMessageId &id, QMessageManager:: switch (idType(id)) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED - return _fsEngine->removeMessage(id, option); + return CFSEngine::instance()->removeMessage(id, option); #else return false; #endif @@ -279,7 +276,7 @@ bool QMessageStorePrivate::removeMessages(const QMessageFilter &filter, QMessage switch (idType(ids[i])) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED - if (!_fsEngine->removeMessage(ids[i], option)) { + if (!CFSEngine::instance()->removeMessage(ids[i], option)) { retVal = false; } #else @@ -307,7 +304,7 @@ QMessage QMessageStorePrivate::message(const QMessageId& id) const switch (idType(id)) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED - return _fsEngine->message(id); + return CFSEngine::instance()->message(id); #else return QMessage(); #endif @@ -324,7 +321,7 @@ QMessageAccount QMessageStorePrivate::account(const QMessageAccountId &id) const switch (idType(id)) { case EngineTypeFreestyle: #ifdef FREESTYLEMAILUSED - return _fsEngine->account(id); + return CFSEngine::instance()->account(id); #else return QMessageAccount(); #endif @@ -340,7 +337,7 @@ QMessageManager::NotificationFilterId QMessageStorePrivate::registerNotification { QMessageManager::NotificationFilterId id = _mtmEngine->registerNotificationFilter(*this, filter); #ifdef FREESTYLEMAILUSED - return _fsEngine->registerNotificationFilter(*this, filter, id); + return CFSEngine::instance()->registerNotificationFilter(*this, filter, id); #else return id; #endif @@ -349,7 +346,7 @@ QMessageManager::NotificationFilterId QMessageStorePrivate::registerNotification void QMessageStorePrivate::unregisterNotificationFilter(QMessageManager::NotificationFilterId notificationFilterId) { #ifdef FREESTYLEMAILUSED - _fsEngine->unregisterNotificationFilter(notificationFilterId); + CFSEngine::instance()->unregisterNotificationFilter(notificationFilterId); #endif _mtmEngine->unregisterNotificationFilter(notificationFilterId); diff --git a/src/messaging/qmessagestore_symbian_p.h b/src/messaging/qmessagestore_symbian_p.h index fd9f8a6e42..a226ad9259 100644 --- a/src/messaging/qmessagestore_symbian_p.h +++ b/src/messaging/qmessagestore_symbian_p.h @@ -103,9 +103,6 @@ private: QMessageStore* q_ptr; CMTMEngine* _mtmEngine; -#ifdef FREESTYLEMAILUSED - CFSEngine* _fsEngine; -#endif QMessageManager::Error _error; diff --git a/src/messaging/qmtmengine_symbian.cpp b/src/messaging/qmtmengine_symbian.cpp index 5b0bcdf931..0e1f7d9f59 100644 --- a/src/messaging/qmtmengine_symbian.cpp +++ b/src/messaging/qmtmengine_symbian.cpp @@ -2244,14 +2244,25 @@ bool CMTMEngine::storeMMS(QMessage &message) return true; } -bool CMTMEngine::sendMMS(QMessage &message) +bool CMTMEngine::sendMMS(QMessageServicePrivate& privateService, QMessage &message) { if (!iSessionReady) { return false; } - TRAPD(err, sendMMSL(message)); + TRAPD(err, sendMMSL(privateService, message)); if (err != KErrNone) { + // sendMMSL() function adds messageId to iPendingSends array + // just before message is tried to send. + // => Make sure that messageId will be removed if sending fails + TMsvId messageId = SymbianHelpers::stripIdPrefix(message.id().toString()).toLong(); + for (int index=0; index < iPendingSends.count(); index++) { + if (iPendingSends[index].messageId == messageId) { + iPendingSends.removeAt(index); + break; + } + } + return false; } @@ -2272,14 +2283,25 @@ bool CMTMEngine::storeEmail(QMessage &message) return true; } -bool CMTMEngine::sendEmail(QMessage &message) +bool CMTMEngine::sendEmail(QMessageServicePrivate& privateService, QMessage &message) { if (!iSessionReady) { return false; } - TRAPD(err, sendEmailL(message)); + TRAPD(err, sendEmailL(privateService, message)); if (err != KErrNone) { + // sendEmailL() function adds messageId to iPendingSends array + // just before message is tried to send. + // => Make sure that messageId will be removed if sending fails + TMsvId messageId = SymbianHelpers::stripIdPrefix(message.id().toString()).toLong(); + for (int index=0; index < iPendingSends.count(); index++) { + if (iPendingSends[index].messageId == messageId) { + iPendingSends.removeAt(index); + break; + } + } + return false; } @@ -2420,14 +2442,25 @@ void CMTMEngine::storeSMSL(QMessage &message) privateMessage->_id = QMessageId(SymbianHelpers::addIdPrefix(QString::number(entry.Id()), SymbianHelpers::EngineTypeMTM)); } -bool CMTMEngine::sendSMS(QMessage &message) +bool CMTMEngine::sendSMS(QMessageServicePrivate& privateService, QMessage &message) { if (!iSessionReady) { return false; } - TRAPD(err, sendSMSL(message)); + TRAPD(err, sendSMSL(privateService, message)); if (err != KErrNone) { + // sendSMSL() function adds messageId to iPendingSends array + // just before message is tried to send. + // => Make sure that messageId will be removed if sending fails + TMsvId messageId = SymbianHelpers::stripIdPrefix(message.id().toString()).toLong(); + for (int index=0; index < iPendingSends.count(); index++) { + if (iPendingSends[index].messageId == messageId) { + iPendingSends.removeAt(index); + break; + } + } + return false; } @@ -2453,7 +2486,70 @@ bool CMTMEngine::validateSMS() return true; } -void CMTMEngine::sendSMSL(QMessage &message) +// Following array contains all unicode characters which can +// be found from (unescaped) GSM 03.38 (7 bit) character set: +const unsigned short int KSMS0338UnicodeChars[128] = + { 0x0040, 0x00A3, 0x0024, 0x00A5, 0x00E8, 0x00E9, 0x00F9, 0x00EC, + 0x00F2, 0x00E7, 0x000A, 0x00D8, 0x00F8, 0x000D, 0x00C5, 0x00E5, + 0x0394, 0x005F, 0x03A6, 0x0393, 0x039B, 0x03A9, 0x03A0, 0x03A8, + 0x03A3, 0x0398, 0x039E, 0x00A0, 0x00C6, 0x00E6, 0x00DF, 0x00C9, + 0x0020, 0x0021, 0x0022, 0x0023, 0x00A4, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x00A1, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x00C4, 0x00D6, 0x00D1, 0x00DC, 0x00A7, + 0x00BF, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x00E4, 0x00F6, 0x00F1, 0x00FC, 0x00E0 }; + +// Following array contains all unicode characters which can +// be found from escaped GSM 03.38 (7 bit) character set. +// <Unicode> = <GSM 03.38> = <character> +// 0x000C = 0x1B0A = Form Feed +// 0x005E = 0x1B14 = ^ +// 0x007B = 0x1B28 = { +// 0x007D = 0x1B29 = } +// 0x005C = 0x1B2F = \ +// 0x005B = 0x1B3C = [ +// 0x007E = 0x1B3D = ~ +// 0x005D = 0x1B3E = ] +// 0x007C = 0x1B40 = | +// 0x20AC = 0x1B65 = +const unsigned short int KEscapedSMS0338UnicodeChars[10] = + { 0x000C, 0x005E, 0x007B, 0x007D, 0x005C, 0x005B, 0x007E, 0x005D, + 0x007C, 0x20AC }; + +bool CMTMEngine::isGsm0338CompatibleUnicodeCharacter(TUint16 aValue) +{ + for (int i=0; i < 128; i++) { + if (KSMS0338UnicodeChars[i] == aValue) { + if (aValue == 0x00A0) { + // Escape chatacter <=> character 0x1B in GSM 03.38 + // character set + // => Can't be mapped to GSM 03.38 character set + // <=> KEscapedSMS0338UnicodeChars array contains + // all Unicode characters which can be mapped + // to GSM 03.38 character set using escaping + return false; + } + return true; + } + } + + for (int i=0; i < 10; i++) { + if (KEscapedSMS0338UnicodeChars[i] == aValue) { + return true; + } + } + + return false; +} + +void CMTMEngine::sendSMSL(QMessageServicePrivate& privateService, QMessage &message) { if (!iSessionReady) { User::Leave(KErrNotReady); @@ -2489,8 +2585,27 @@ void CMTMEngine::sendSMSL(QMessage &message) CSmsHeader& smsHeader = ipSmsMtm->SmsHeader(); CSmsSettings* pSmsSettings = CSmsSettings::NewL(); CleanupStack::PushL(pSmsSettings); - + + TSmsDataCodingScheme::TSmsAlphabet dataCodingScheme = TSmsDataCodingScheme::ESmsAlphabet7Bit; + CRichText& body = ipSmsMtm->Body(); + HBufC* bodyBuf = HBufC::NewLC(body.DocumentLength()); + TPtr16 ptrBody = bodyBuf->Des(); + body.Extract(ptrBody, 0, body.DocumentLength()); + + // Check if message body contains other than GSM 03.38 (7 bit) + // compatible Unicode characters. + // => If incompatible characters are found, UCS2 encoding will be used + for (TInt i = 0; i < ptrBody.Length(); i++) { + if (!isGsm0338CompatibleUnicodeCharacter(ptrBody[i])) { + dataCodingScheme = TSmsDataCodingScheme::ESmsAlphabetUCS2; + break; + } + } + + CleanupStack::PopAndDestroy(bodyBuf); + pSmsSettings->CopyL(ipSmsMtm->ServiceSettings()); + pSmsSettings->SetCharacterSet(dataCodingScheme); pSmsSettings->SetDelivery(ESmsDeliveryImmediately); pSmsSettings->SetDeliveryReport(EFalse); smsHeader.SetSmsSettingsL(*pSmsSettings); @@ -2520,6 +2635,11 @@ void CMTMEngine::sendSMSL(QMessage &message) ipSmsMtm->SaveMessageL(); if (validateSMS()) { + PendingSend pendingSend; + pendingSend.privateService = &privateService; + pendingSend.messageId = messageId; + iPendingSends.append(pendingSend); + // Switch current SMS MTM context to SMS message parent folder entry ipSmsMtm->SwitchCurrentEntryL(ipSmsMtm->Entry().Entry().Parent()); @@ -3299,7 +3419,7 @@ void CMTMEngine::updateEmailL(QMessage &message) } } -void CMTMEngine::sendMMSL(QMessage &message) +void CMTMEngine::sendMMSL(QMessageServicePrivate& privateService, QMessage &message) { if (!iSessionReady) { User::Leave(KErrNotReady); @@ -3317,6 +3437,11 @@ void CMTMEngine::sendMMSL(QMessage &message) User::Leave(KErrNotReady); } + PendingSend pendingSend; + pendingSend.privateService = &privateService; + pendingSend.messageId = messageId; + iPendingSends.append(pendingSend); + CMsvEntry* pMsvEntry = retrieveCMsvEntryAndPushToCleanupStack(messageId); QMTMWait mtmWait; @@ -3650,7 +3775,7 @@ void CMTMEngine::storeEmailL(QMessage &message) privateMessage->_id = QMessageId(SymbianHelpers::addIdPrefix(QString::number(newMessageId),SymbianHelpers::EngineTypeMTM)); } -void CMTMEngine::sendEmailL(QMessage &message) +void CMTMEngine::sendEmailL(QMessageServicePrivate& privateService, QMessage &message) { if (!iSessionReady) { User::Leave(KErrNotReady); @@ -3681,6 +3806,11 @@ void CMTMEngine::sendEmailL(QMessage &message) User::Leave(KErrNotReady); } + PendingSend pendingSend; + pendingSend.privateService = &privateService; + pendingSend.messageId = messageId; + iPendingSends.append(pendingSend); + CMsvEntry* pMsvEntry = retrieveCMsvEntryAndPushToCleanupStack(messageId); QMTMWait mtmWait; @@ -4333,6 +4463,8 @@ CMsvEntry* CMTMEngine::retrieveCMsvEntryAndPushToCleanupStack(TMsvId id) const if (retVal != KErrNone) { delete pEntry; pEntry = NULL; + } else { + iCmsvEntryPoolFree.Remove(iCmsvEntryPoolFree.Count()-1); } } else { if (id == 0) { @@ -4693,7 +4825,7 @@ void CMTMEngine::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, case EMsvEntriesChanged: case EMsvEntriesDeleted: case EMsvEntriesMoved: - if (aArg2 && iListenForNotifications) { + if (aArg2) { CMsvEntrySelection* entries = static_cast<CMsvEntrySelection*>(aArg1); if (entries != NULL) { @@ -4701,14 +4833,59 @@ void CMTMEngine::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, while (count--) { const TMsvId id = (*entries)[count]; if (aEvent == EMsvEntriesDeleted) { - notification(aEvent, TUid(), *(static_cast<TMsvId*>(aArg2)), id); + // Handle message status change + QMessageServicePrivate* pPrivateService = NULL; + for (int index=0; index < iPendingSends.count(); index++) { + if (iPendingSends[index].messageId == id) { + pPrivateService = iPendingSends[index].privateService; + iPendingSends.removeAt(index); + break; + } + } + if (pPrivateService) { + pPrivateService->setFinished(false); + } + + // Handle message event + if (iListenForNotifications) { + notification(aEvent, TUid(), *(static_cast<TMsvId*>(aArg2)), id); + } } else { CMsvEntry* pReceivedEntry = NULL; TRAPD(err, pReceivedEntry = ipMsvSession->GetEntryL(id)); if (err == KErrNone) { const TMsvEntry& entry = pReceivedEntry->Entry(); if (entry.iType == KUidMsvMessageEntry) { - notification(aEvent, entry.iMtm, *(static_cast<TMsvId*>(aArg2)), id); + // Handle message status change + if (entry.SendingState() == KMsvSendStateFailed) { + QMessageServicePrivate* pPrivateService = NULL; + for (int index=0; index < iPendingSends.count(); index++) { + if (iPendingSends[index].messageId == id) { + pPrivateService = iPendingSends[index].privateService; + iPendingSends.removeAt(index); + break; + } + } + if (pPrivateService) { + pPrivateService->setFinished(false); + } + } else if (entry.SendingState() == KMsvSendStateSent) { + QMessageServicePrivate* pPrivateService = NULL; + for (int index=0; index < iPendingSends.count(); index++) { + if (iPendingSends[index].messageId == id) { + pPrivateService = iPendingSends[index].privateService; + iPendingSends.removeAt(index); + break; + } + } + if (pPrivateService) { + pPrivateService->setFinished(true); + } + } + // Handle message event + if (iListenForNotifications) { + notification(aEvent, entry.iMtm, *(static_cast<TMsvId*>(aArg2)), id); + } } delete pReceivedEntry; } diff --git a/src/messaging/qmtmengine_symbian_p.h b/src/messaging/qmtmengine_symbian_p.h index 2a0a0ce374..0ec35c6fb1 100644 --- a/src/messaging/qmtmengine_symbian_p.h +++ b/src/messaging/qmtmengine_symbian_p.h @@ -87,6 +87,12 @@ struct MessageEvent bool unfiltered; }; +struct PendingSend +{ + TMsvId messageId; + QMessageServicePrivate* privateService; +}; + struct MessageQueryInfo { int operationId; @@ -145,11 +151,11 @@ public: QMessage message(const QMessageId& id) const; bool storeMMS(QMessage &message); - bool sendMMS(QMessage &message); + bool sendMMS(QMessageServicePrivate& privateService, QMessage &message); bool storeEmail(QMessage &message); - bool sendEmail(QMessage &message); + bool sendEmail(QMessageServicePrivate& privateService, QMessage &message); bool storeSMS(QMessage &message); - bool sendSMS(QMessage &message); + bool sendSMS(QMessageServicePrivate& privateService, QMessage &message); bool retrieve(QMessageServicePrivate& privateService, const QMessageId &messageId, const QMessageContentContainerId& id); bool retrieveBody(QMessageServicePrivate& privateService, const QMessageId& id); bool retrieveHeader(QMessageServicePrivate& privateService, const QMessageId& id); @@ -230,12 +236,12 @@ private: void showMessageL(const QMessageId &id); void storeMMSL(QMessage &message); - void sendMMSL(QMessage &message); + void sendMMSL(QMessageServicePrivate& privateService, QMessage &message); void storeEmailL(QMessage &message); - void sendEmailL(QMessage &message); + void sendEmailL(QMessageServicePrivate& privateService, QMessage &message); void storeSMSL(QMessage &message); bool validateSMS(); - void sendSMSL(QMessage &message); + void sendSMSL(QMessageServicePrivate& privateService, QMessage &message); void retrieveL(QMessageServicePrivate& privateService, const QMessageId &messageId, const QMessageContentContainerId& id); void retrieveBodyL(QMessageServicePrivate& privateService, const QMessageId& id); void retrieveHeaderL(QMessageServicePrivate& privateService, const QMessageId& id); @@ -257,6 +263,8 @@ private: TMsvId serviceId); void deleteAsynchronousMTMOperation(CAsynchronousMTMOperation *apOperation); bool checkIfWaitingDiscardClearMessage(TMsvId aMessageId); + + bool isGsm0338CompatibleUnicodeCharacter(TUint16 aValue); private: // from CActive void RunL(); @@ -311,6 +319,7 @@ private: mutable int iOperationIds; mutable QList<MessageQueryInfo> iMessageQueries; + mutable QList<PendingSend> iPendingSends; mutable QMessageAccountSortOrder iCurrentAccountOrdering; mutable QMessageFolderSortOrder iCurrentFolderOrdering; diff --git a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp index 0db451778e..14420f2bec 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_alsa_p.cpp @@ -252,37 +252,40 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const // set the values! snd_pcm_hw_params_set_channels(handle,params,format.channels()); snd_pcm_hw_params_set_rate(handle,params,format.frequency(),dir); + + err = -1; + switch(format.sampleSize()) { case 8: if(format.sampleType() == QAudioFormat::SignedInt) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S8); else if(format.sampleType() == QAudioFormat::UnSignedInt) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U8); break; case 16: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S16_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U16_BE); } break; case 32: if(format.sampleType() == QAudioFormat::SignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_S32_BE); } else if(format.sampleType() == QAudioFormat::UnSignedInt) { if(format.byteOrder() == QAudioFormat::LittleEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_LE); else if(format.byteOrder() == QAudioFormat::BigEndian) - snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE); + err = snd_pcm_hw_params_set_format(handle,params,SND_PCM_FORMAT_U32_BE); } } diff --git a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp index 8fe4f49061..a0cc933100 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_mac_p.cpp @@ -89,7 +89,13 @@ QAudioDeviceInfoInternal::QAudioDeviceInfoInternal(QByteArray const& handle, QAu bool QAudioDeviceInfoInternal::isFormatSupported(const QAudioFormat& format) const { - return format.codec() == QString::fromLatin1("audio/pcm"); + QAudioDeviceInfoInternal *self = const_cast<QAudioDeviceInfoInternal*>(this); + + return format.isValid() + && format.codec() == QString::fromLatin1("audio/pcm") + && self->supportedSampleRates().contains(format.sampleRate()) + && self->supportedChannelCounts().contains(format.channelCount()) + && self->supportedSampleSizes().contains(format.sampleSize()); } QAudioFormat QAudioDeviceInfoInternal::preferredFormat() const diff --git a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp index 19f0aa4147..f355aef591 100644 --- a/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo_win32_p.cpp @@ -188,8 +188,9 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } - if (!match) failed = true; // check frequency match = false; @@ -200,6 +201,8 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } // check sample size @@ -211,6 +214,8 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } // check byte order @@ -222,6 +227,8 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } // check sample type @@ -233,6 +240,8 @@ bool QAudioDeviceInfoInternal::testSettings(const QAudioFormat& format) const break; } } + if (!match) + failed = true; } if(!failed) { diff --git a/src/multimedia/audio/qaudioinput_alsa_p.cpp b/src/multimedia/audio/qaudioinput_alsa_p.cpp index 1033a21b9d..3159854b1b 100644 --- a/src/multimedia/audio/qaudioinput_alsa_p.cpp +++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp @@ -156,7 +156,7 @@ int QAudioInputPrivate::xrun_recovery(int err) int QAudioInputPrivate::setFormat() { - snd_pcm_format_t format = SND_PCM_FORMAT_S16; + snd_pcm_format_t format = SND_PCM_FORMAT_UNKNOWN; if(settings.sampleSize() == 8) { format = SND_PCM_FORMAT_U8; @@ -208,7 +208,9 @@ int QAudioInputPrivate::setFormat() format = SND_PCM_FORMAT_FLOAT64_BE; } - return snd_pcm_hw_params_set_format( handle, hwparams, format); + return format != SND_PCM_FORMAT_UNKNOWN + ? snd_pcm_hw_params_set_format( handle, hwparams, format) + : -1; } void QAudioInputPrivate::start(QIODevice* device) @@ -274,10 +276,27 @@ bool QAudioInputPrivate::open() elapsedTimeOffset = 0; int dir; - int err=-1; + int err = 0; int count=0; unsigned int freakuency=settings.frequency(); + if (!settings.isValid()) { + qWarning("QAudioOutput: open error, invalid format."); + } else if (settings.sampleRate() <= 0) { + qWarning("QAudioOutput: open error, invalid sample rate (%d).", + settings.sampleRate()); + } else { + err = -1; + } + + if (err == 0) { + errorState = QAudio::OpenError; + deviceState = QAudio::StoppedState; + emit errorChanged(errorState); + return false; + } + + QString dev = QString(QLatin1String(m_device.constData())); QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioInput); if(dev.compare(QLatin1String("default")) == 0) { diff --git a/src/multimedia/audio/qaudioinput_mac_p.cpp b/src/multimedia/audio/qaudioinput_mac_p.cpp index 9aea50a616..fc75ecf44e 100644 --- a/src/multimedia/audio/qaudioinput_mac_p.cpp +++ b/src/multimedia/audio/qaudioinput_mac_p.cpp @@ -722,7 +722,7 @@ void QAudioInputPrivate::start(QIODevice* device) { QIODevice* op = device; - if (!audioFormat.isValid() || !open()) { + if (!audioDeviceInfo->isFormatSupported(audioFormat) || !open()) { stateCode = QAudio::StoppedState; errorCode = QAudio::OpenError; return; @@ -750,7 +750,7 @@ QIODevice* QAudioInputPrivate::start() { QIODevice* op = 0; - if (!audioFormat.isValid() || !open()) { + if (!audioDeviceInfo->isFormatSupported(audioFormat) || !open()) { stateCode = QAudio::StoppedState; errorCode = QAudio::OpenError; return audioIO; diff --git a/src/multimedia/audio/qaudioinput_win32_p.cpp b/src/multimedia/audio/qaudioinput_win32_p.cpp index 1f8ed6f860..1f5a138167 100644 --- a/src/multimedia/audio/qaudioinput_win32_p.cpp +++ b/src/multimedia/audio/qaudioinput_win32_p.cpp @@ -230,18 +230,45 @@ bool QAudioInputPrivate::open() qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()"; #endif header = 0; - if(buffer_size == 0) { - // Default buffer size, 200ms, default period size is 40ms - buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.2; - period_size = buffer_size/5; + + period_size = 0; + + if (!settings.isValid()) { + qWarning("QAudioInput: open error, invalid format."); + } else if (settings.channelCount() <= 0) { + qWarning("QAudioInput: open error, invalid number of channels (%d).", + settings.channelCount()); + } else if (settings.sampleSize() <= 0) { + qWarning("QAudioInput: open error, invalid sample size (%d).", + settings.sampleSize()); + } else if (settings.frequency() < 8000 || settings.frequency() > 48000) { + qWarning("QAudioInput: open error, frequency out of range (%d).", settings.frequency()); + } else if (buffer_size == 0) { + + buffer_size + = (settings.frequency() + * settings.channelCount() + * settings.sampleSize() +#ifndef Q_OS_WINCE // Default buffer size, 200ms, default period size is 40ms + + 39) / 40; + period_size = buffer_size / 5; } else { - period_size = buffer_size/5; - } -#ifdef Q_OS_WINCE - // For wince reduce size to 40ms for buffer size and 20ms period - buffer_size = settings.sampleRate()*settings.channelCount()*(settings.sampleSize()/8)*0.04; - period_size = buffer_size/2; + period_size = buffer_size / 5; +#else // For wince reduce size to 40ms for buffer size and 20ms period + + 199) / 200; + period_size = buffer_size / 2; + } else { + period_size = buffer_size / 2; #endif + } + + if (period_size == 0) { + errorState = QAudio::OpenError; + deviceState = QAudio::StoppedState; + emit stateChanged(deviceState); + return false; + } + timeStamp.restart(); elapsedTimeOffset = 0; wfx.nSamplesPerSec = settings.frequency(); diff --git a/src/multimedia/audio/qaudiooutput_alsa_p.cpp b/src/multimedia/audio/qaudiooutput_alsa_p.cpp index 9729e5dd38..c2b714fdc9 100644 --- a/src/multimedia/audio/qaudiooutput_alsa_p.cpp +++ b/src/multimedia/audio/qaudiooutput_alsa_p.cpp @@ -156,7 +156,7 @@ int QAudioOutputPrivate::xrun_recovery(int err) int QAudioOutputPrivate::setFormat() { - snd_pcm_format_t pcmformat = SND_PCM_FORMAT_S16; + snd_pcm_format_t pcmformat = SND_PCM_FORMAT_UNKNOWN; if(settings.sampleSize() == 8) { pcmformat = SND_PCM_FORMAT_U8; @@ -209,7 +209,9 @@ int QAudioOutputPrivate::setFormat() pcmformat = SND_PCM_FORMAT_FLOAT64_BE; } - return snd_pcm_hw_params_set_format( handle, hwparams, pcmformat); + return pcmformat != SND_PCM_FORMAT_UNKNOWN + ? snd_pcm_hw_params_set_format( handle, hwparams, pcmformat) + : -1; } void QAudioOutputPrivate::start(QIODevice* device) @@ -288,10 +290,26 @@ bool QAudioOutputPrivate::open() elapsedTimeOffset = 0; int dir; - int err=-1; + int err = 0; int count=0; unsigned int freakuency=settings.frequency(); + if (!settings.isValid()) { + qWarning("QAudioOutput: open error, invalid format."); + } else if (settings.sampleRate() <= 0) { + qWarning("QAudioOutput: open error, invalid sample rate (%d).", + settings.sampleRate()); + } else { + err = -1; + } + + if (err == 0) { + errorState = QAudio::OpenError; + deviceState = QAudio::StoppedState; + emit errorChanged(errorState); + return false; + } + QString dev = QString(QLatin1String(m_device.constData())); QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioOutput); if(dev.compare(QLatin1String("default")) == 0) { diff --git a/src/multimedia/audio/qaudiooutput_mac_p.cpp b/src/multimedia/audio/qaudiooutput_mac_p.cpp index 29e73d1ac6..bd08a7d352 100644 --- a/src/multimedia/audio/qaudiooutput_mac_p.cpp +++ b/src/multimedia/audio/qaudiooutput_mac_p.cpp @@ -60,11 +60,11 @@ #include <QtCore/qtimer.h> #include <QtCore/qdebug.h> -#include <qaudiodeviceinfo.h> #include <qaudiooutput.h> #include "qaudio_mac_p.h" #include "qaudiooutput_mac_p.h" +#include "qaudiodeviceinfo_mac_p.h" QT_BEGIN_NAMESPACE @@ -277,6 +277,7 @@ QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray& device) if (QAudio::Mode(mode) == QAudio::AudioInput) errorCode = QAudio::OpenError; else { + audioDeviceInfo = new QAudioDeviceInfoInternal(device, QAudio::AudioOutput); isOpen = false; audioDeviceId = AudioDeviceID(did); audioUnit = 0; @@ -298,6 +299,7 @@ QAudioOutputPrivate::QAudioOutputPrivate(const QByteArray& device) QAudioOutputPrivate::~QAudioOutputPrivate() { + delete audioDeviceInfo; close(); } @@ -429,7 +431,7 @@ void QAudioOutputPrivate::start(QIODevice* device) { QIODevice* op = device; - if (!audioFormat.isValid() || !open()) { + if (!audioDeviceInfo->isFormatSupported(audioFormat) || !open()) { stateCode = QAudio::StoppedState; errorCode = QAudio::OpenError; } @@ -460,7 +462,7 @@ QIODevice* QAudioOutputPrivate::start() { QIODevice* op = 0; - if (!audioFormat.isValid() || !open()) { + if (!audioDeviceInfo->isFormatSupported(audioFormat) || !open()) { stateCode = QAudio::StoppedState; errorCode = QAudio::OpenError; return audioIO; diff --git a/src/multimedia/audio/qaudiooutput_mac_p.h b/src/multimedia/audio/qaudiooutput_mac_p.h index 08cc61bb47..4c2243633c 100644 --- a/src/multimedia/audio/qaudiooutput_mac_p.h +++ b/src/multimedia/audio/qaudiooutput_mac_p.h @@ -73,6 +73,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE class QIODevice; +class QAbstractAudioDeviceInfo; namespace QtMultimediaKitInternal { @@ -101,6 +102,7 @@ public: QWaitCondition threadFinished; QMutex mutex; QTimer* intervalTimer; + QAbstractAudioDeviceInfo *audioDeviceInfo; QAudio::Error errorCode; QAudio::State stateCode; diff --git a/src/multimedia/audio/qaudiooutput_win32_p.cpp b/src/multimedia/audio/qaudiooutput_win32_p.cpp index 025f601b77..82ce2d713f 100644 --- a/src/multimedia/audio/qaudiooutput_win32_p.cpp +++ b/src/multimedia/audio/qaudiooutput_win32_p.cpp @@ -267,20 +267,38 @@ bool QAudioOutputPrivate::open() QTime now(QTime::currentTime()); qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()"; #endif - if (!(settings.frequency() >= 8000 && settings.frequency() <= 48000)) { + + period_size = 0; + + if (!settings.isValid()) { + qWarning("QAudioOutput: open error, invalid format."); + } else if (settings.channelCount() <= 0) { + qWarning("QAudioOutput: open error, invalid number of channels (%d).", + settings.channelCount()); + } else if (settings.sampleSize() <= 0) { + qWarning("QAudioOutput: open error, invalid sample size (%d).", + settings.sampleSize()); + } else if (settings.frequency() < 8000 || settings.frequency() > 48000) { + qWarning("QAudioOutput: open error, frequency out of range (%d).", settings.frequency()); + } else if (buffer_size == 0) { + // Default buffer size, 200ms, default period size is 40ms + buffer_size + = (settings.frequency() + * settings.channelCount() + * settings.sampleSize() + + 39) / 40; + period_size = buffer_size / 5; + } else { + period_size = buffer_size / 5; + } + + if (period_size == 0) { errorState = QAudio::OpenError; deviceState = QAudio::StoppedState; emit stateChanged(deviceState); - qWarning("QAudioOutput: open error, frequency out of range."); return false; } - if(buffer_size == 0) { - // Default buffer size, 200ms, default period size is 40ms - buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.2; - period_size = buffer_size/5; - } else { - period_size = buffer_size/5; - } + waveBlocks = allocateBlocks(period_size, buffer_size/period_size); mutex.lock(); diff --git a/src/multimedia/audio/qaudiopluginloader.cpp b/src/multimedia/audio/qaudiopluginloader.cpp index a445055b9b..7ff8b24bcd 100644 --- a/src/multimedia/audio/qaudiopluginloader.cpp +++ b/src/multimedia/audio/qaudiopluginloader.cpp @@ -101,7 +101,11 @@ QStringList QAudioPluginLoader::pluginList() const qDebug()<<"Looking for plugins in "<<pluginsDir.path()<<files; #endif for (int j=0; j < files.count(); j++) { - plugins << pluginsDir.absoluteFilePath(files.at(j)); + const QString &file = files.at(j); +#if defined(Q_WS_MAEMO_5) + if (!file.contains(QLatin1String("n900audio"))) +#endif + plugins << pluginsDir.absoluteFilePath(file); } } return plugins; @@ -109,7 +113,7 @@ QStringList QAudioPluginLoader::pluginList() const QStringList QAudioPluginLoader::keys() const { - QMutexLocker(m_mutex()); + QMutexLocker locker(const_cast<QMutex *>(&m_mutex)); QStringList list; for (int i = 0; i < m_plugins.count(); i++) { @@ -122,7 +126,7 @@ QStringList QAudioPluginLoader::keys() const QObject* QAudioPluginLoader::instance(QString const &key) { - QMutexLocker(mutex()); + QMutexLocker locker(&m_mutex); for (int i = 0; i < m_plugins.count(); i++) { QAudioSystemPlugin* p = qobject_cast<QAudioSystemPlugin*>(m_plugins.at(i)->instance()); @@ -134,7 +138,7 @@ QObject* QAudioPluginLoader::instance(QString const &key) QList<QObject*> QAudioPluginLoader::instances(QString const &key) { - QMutexLocker(mutex()); + QMutexLocker locker(&m_mutex); QList<QObject*> list; for (int i = 0; i < m_plugins.count(); i++) { diff --git a/src/multimedia/qradiotuner.cpp b/src/multimedia/qradiotuner.cpp index b34a63e758..b068c8d147 100644 --- a/src/multimedia/qradiotuner.cpp +++ b/src/multimedia/qradiotuner.cpp @@ -113,6 +113,7 @@ QRadioTuner::QRadioTuner(QObject *parent, QMediaServiceProvider* provider): connect(d->control, SIGNAL(signalStrengthChanged(int)), SIGNAL(signalStrengthChanged(int))); connect(d->control, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged(int))); connect(d->control, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool))); + connect(d->control, SIGNAL(error(QRadioTuner::Error)), SIGNAL(error(QRadioTuner::Error))); } } } diff --git a/src/multimedia/qradiotuner.h b/src/multimedia/qradiotuner.h index 331b8435e6..a63c13bed7 100644 --- a/src/multimedia/qradiotuner.h +++ b/src/multimedia/qradiotuner.h @@ -128,7 +128,7 @@ Q_SIGNALS: void signalStrengthChanged(int signalStrength); void volumeChanged(int volume); void mutedChanged(bool muted); - void error(Error err); + void error(QRadioTuner::Error error); private: Q_DISABLE_COPY(QRadioTuner) diff --git a/src/publishsubscribe/gconfitem.cpp b/src/publishsubscribe/gconfitem.cpp index 98e9165e3f..7caba9a14c 100644 --- a/src/publishsubscribe/gconfitem.cpp +++ b/src/publishsubscribe/gconfitem.cpp @@ -317,6 +317,23 @@ void GConfItem::unset() { set(QVariant()); } +void GConfItem::recursiveUnset() { + withClient(client) { + QByteArray k = convertKey(priv->key); + GError *error = NULL; + + GConfUnsetFlags flags; + gconf_client_recursive_unset(client, k.data(), flags, &error); + + if (error) { + qWarning() << error->message; + g_error_free(error); + } else { + priv->value = QVariant(); + emit valueChanged(); + } + } +} QList<QString> GConfItem::listDirs() const { QList<QString> children; diff --git a/src/publishsubscribe/gconfitem_p.h b/src/publishsubscribe/gconfitem_p.h index 9afe824574..f27c804223 100644 --- a/src/publishsubscribe/gconfitem_p.h +++ b/src/publishsubscribe/gconfitem_p.h @@ -135,6 +135,10 @@ class GConfItem : public QObject */ void unset(); + /*! Unset this item's all sub items recursively. + */ + void recursiveUnset(); + /*! Return a list of the directories below this item. The returned strings are absolute key names like "/myapp/settings". diff --git a/src/publishsubscribe/gconflayer_linux.cpp b/src/publishsubscribe/gconflayer_linux.cpp index 5a0709c1f8..e34ca8ee38 100644 --- a/src/publishsubscribe/gconflayer_linux.cpp +++ b/src/publishsubscribe/gconflayer_linux.cpp @@ -133,6 +133,9 @@ bool GConfLayer::getValue(Handle handle, const QString &subPath, QVariant *data) value = path.mid(index + 1); path.truncate(index); + if (path.isEmpty()) + path.append(QLatin1Char('/')); + handle = getItem(handle, path); createdHandle = true; } @@ -318,7 +321,7 @@ bool GConfLayer::setValue(QValueSpacePublisher */*creator*/, } QString fullPath(sh->path); - if (fullPath != QLatin1String("/")) + if (fullPath != QLatin1String("/") && !value.isEmpty()) fullPath.append(QLatin1Char('/')); fullPath.append(value); @@ -385,7 +388,7 @@ bool GConfLayer::removeValue(QValueSpacePublisher */*creator*/, } GConfItem gconfItem(fullPath); - gconfItem.unset(); + gconfItem.recursiveUnset(); return true; } diff --git a/tests/auto/qaudioinput/tst_qaudioinput.cpp b/tests/auto/qaudioinput/tst_qaudioinput.cpp index cdae48d6c0..fc3fdd7b58 100755 --- a/tests/auto/qaudioinput/tst_qaudioinput.cpp +++ b/tests/auto/qaudioinput/tst_qaudioinput.cpp @@ -57,6 +57,8 @@ #define SRCDIR "" #endif +Q_DECLARE_METATYPE(QAudioFormat) + class tst_QAudioInput : public QObject { Q_OBJECT @@ -67,6 +69,7 @@ private slots: void initTestCase(); void format(); + void invalidFormat_data(); void invalidFormat(); void bufferSize(); @@ -127,6 +130,8 @@ QString tst_QAudioInput::workingDir() void tst_QAudioInput::initTestCase() { + qRegisterMetaType<QAudioFormat>(); + // Only perform tests if audio output device exists const QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); @@ -206,10 +211,34 @@ void tst_QAudioInput::format() QString("sampleType: requested=%1, actual=%2").arg(requested.sampleType()).arg(actual.sampleType()).toLocal8Bit().constData()); } +void tst_QAudioInput::invalidFormat_data() +{ + QTest::addColumn<QAudioFormat>("invalidFormat"); + + QAudioFormat format; + + QTest::newRow("Null Format") + << format; + + format = audioDevice.preferredFormat(); + format.setChannelCount(0); + QTest::newRow("Channel count 0") + << format; + + format = audioDevice.preferredFormat(); + format.setSampleRate(0); + QTest::newRow("Sample rate 0") + << format; + + format = audioDevice.preferredFormat(); + format.setSampleSize(0); + QTest::newRow("Sample size 0") + << format; +} + void tst_QAudioInput::invalidFormat() { - QAudioFormat invalidFormat; - invalidFormat.setFrequency(0); + QFETCH(QAudioFormat, invalidFormat); QVERIFY2(!audioDevice.isFormatSupported(invalidFormat), "isFormatSupported() is returning true on an invalid format"); diff --git a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp index aec2279ba9..ae0a4d0ea7 100755 --- a/tests/auto/qaudiooutput/tst_qaudiooutput.cpp +++ b/tests/auto/qaudiooutput/tst_qaudiooutput.cpp @@ -57,6 +57,8 @@ #define SRCDIR "" #endif +Q_DECLARE_METATYPE(QAudioFormat) + class tst_QAudioOutput : public QObject { Q_OBJECT @@ -67,6 +69,7 @@ private slots: void initTestCase(); void format(); + void invalidFormat_data(); void invalidFormat(); void bufferSize(); @@ -174,6 +177,8 @@ void tst_QAudioOutput::createSineWaveData(const QAudioFormat &format, qint64 len void tst_QAudioOutput::initTestCase() { + qRegisterMetaType<QAudioFormat>(); + // Only perform tests if audio output device exists const QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); @@ -262,10 +267,34 @@ void tst_QAudioOutput::format() QString("sampleType: requested=%1, actual=%2").arg(requested.sampleType()).arg(actual.sampleType()).toLocal8Bit().constData()); } +void tst_QAudioOutput::invalidFormat_data() +{ + QTest::addColumn<QAudioFormat>("invalidFormat"); + + QAudioFormat format; + + QTest::newRow("Null Format") + << format; + + format = audioDevice.preferredFormat(); + format.setChannelCount(0); + QTest::newRow("Channel count 0") + << format; + + format = audioDevice.preferredFormat(); + format.setSampleRate(0); + QTest::newRow("Sample rate 0") + << format; + + format = audioDevice.preferredFormat(); + format.setSampleSize(0); + QTest::newRow("Sample size 0") + << format; +} + void tst_QAudioOutput::invalidFormat() { - QAudioFormat invalidFormat; - invalidFormat.setFrequency(0); + QFETCH(QAudioFormat, invalidFormat); QVERIFY2(!audioDevice.isFormatSupported(invalidFormat), "isFormatSupported() is returning true on an invalid format"); diff --git a/tests/auto/qmessageservice/tst_qmessageservice.cpp b/tests/auto/qmessageservice/tst_qmessageservice.cpp index 115a34e062..960ae9ba2a 100644 --- a/tests/auto/qmessageservice/tst_qmessageservice.cpp +++ b/tests/auto/qmessageservice/tst_qmessageservice.cpp @@ -43,7 +43,6 @@ #include <QObject> #include <QTest> -#include <QDebug> #include "qmessageservice.h" #include "../support/support.h" @@ -515,13 +514,11 @@ void tst_QMessageService::testQueryCountData() QTest::addColumn<QMessageIdList>("negatedIds"); QTest::addColumn<QString>("body"); -#if !defined(Q_WS_MAEMO_5) && !defined(Q_WS_MAEMO_6) QTest::newRow("empty filter") << QMessageFilter() << messageIds << QMessageIdList() << ""; -#endif QTest::newRow("id equality 1") << QMessageFilter::byId(messageIds[0], QMessageDataComparator::Equal) @@ -1946,7 +1943,7 @@ void tst_QMessageService::testCountMessages() SignalCatcher sc(this); connect(testService,SIGNAL(messagesCounted(int)),&sc,SLOT(messagesCounted(int))); -#ifdef Q_OS_SYMBIAN +#if (defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)) connect(testService,SIGNAL(stateChanged(QMessageService::State)),&sc,SLOT(stateChanged(QMessageService::State))); #endif @@ -1954,7 +1951,7 @@ void tst_QMessageService::testCountMessages() if(body.isEmpty()) { QCOMPARE(testService->countMessages(filter&~existingAccountsFilter),true); -#ifdef Q_OS_SYMBIAN +#if (defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)) QTRY_VERIFY(sc.state == QMessageService::FinishedState); #else while(testService->state() == QMessageService::ActiveState) @@ -1963,7 +1960,7 @@ void tst_QMessageService::testCountMessages() QCOMPARE(sc.count-existingMessageIds.count(), ids.count()); QCOMPARE(testService->countMessages(~filter&~existingAccountsFilter),true); -#ifdef Q_OS_SYMBIAN +#if (defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)) QTRY_VERIFY(sc.state == QMessageService::FinishedState); #else while(testService->state() == QMessageService::ActiveState) diff --git a/tests/auto/qmessagestore/tst_qmessagestore.cpp b/tests/auto/qmessagestore/tst_qmessagestore.cpp index 2db6d1ee71..6a98070185 100644 --- a/tests/auto/qmessagestore/tst_qmessagestore.cpp +++ b/tests/auto/qmessagestore/tst_qmessagestore.cpp @@ -649,7 +649,7 @@ void tst_QMessageStore::testMessage() QCOMPARE(message.parentAccountId(), testAccountId); QCOMPARE(message.parentFolderId(), testFolderId); -#ifndef Q_OS_SYMBIAN // Created Messages are not stored in Standard Folders in Symbian & Maemo +#if !defined(Q_OS_SYMBIAN) && !defined(Q_WS_MAEMO_5) && !defined(Q_WS_MAEMO_6) // Created Messages are not stored in Standard Folders in Symbian & Maemo QCOMPARE(message.standardFolder(), QMessage::InboxFolder); #endif diff --git a/tests/auto/qmessagestorefiltercache/qmessagestorefiltercache.pro b/tests/auto/qmessagestorefiltercache/qmessagestorefiltercache.pro new file mode 100644 index 0000000000..58e31bf402 --- /dev/null +++ b/tests/auto/qmessagestorefiltercache/qmessagestorefiltercache.pro @@ -0,0 +1,309 @@ +TEMPLATE = app +TARGET = tst_qmessagestorefiltercache + +CONFIG += testcase +QT += testlib + +INCLUDEPATH += ../../../src/messaging +VPATH += ../../../src/messaging + +include(../../../common.pri) + +# Input +PUBLIC_HEADERS += qmessageid.h \ + qmessagecontentcontainerid.h \ + qmessagefolderid.h \ + qmessageaccountid.h \ + qmessagecontentcontainer.h \ + qmessageaddress.h \ + qmessage.h \ + qmessagefolder.h \ + qmessageaccount.h \ + qmessageaccountfilter.h \ + qmessageaccountsortorder.h \ + qmessagefolderfilter.h \ + qmessagefoldersortorder.h \ + qmessagefilter.h \ + qmessagemanager.h \ + qmessagesortorder.h \ + qmessageservice.h \ + qmessagedatacomparator.h \ + qmessageglobal.h +PRIVATE_HEADERS += addresshelper_p.h \ + qmessageid_p.h \ + qmessagecontentcontainerid_p.h \ + qmessagefolderid_p.h \ + qmessageaccountid_p.h \ + qmessagecontentcontainer_p.h \ + qmessageaddress_p.h \ + qmessage_p.h \ + qmessagefolder_p.h \ + qmessageaccount_p.h \ + qmessageaccountfilter_p.h \ + qmessageaccountsortorder_p.h \ + qmessagefolderfilter_p.h \ + qmessagefoldersortorder_p.h \ + qmessagefilter_p.h \ + qmessagesortorder_p.h \ + qmessagestore.h \ + qmessagestore_p.h \ + messagingutil_p.h +SOURCES += qmessageid.cpp \ + qmessagecontentcontainerid.cpp \ + qmessagefolderid.cpp \ + qmessageaccountid.cpp \ + qmessagecontentcontainer.cpp \ + addresshelper.cpp \ + qmessageaddress.cpp \ + qmessage.cpp \ + qmessagefolder.cpp \ + qmessageaccount.cpp \ + qmessageaccountfilter.cpp \ + qmessageaccountsortorder.cpp \ + qmessagefolderfilter.cpp \ + qmessagefoldersortorder.cpp \ + qmessagefilter.cpp \ + qmessagemanager.cpp \ + qmessagesortorder.cpp \ + qmessagestore.cpp \ + qmessageservice.cpp \ + messagingutil.cpp +symbian|win32|maemo6|maemo5|mac { + mac|maemo6: SOURCES += qmessageid_stub.cpp \ + qmessagecontentcontainerid_stub.cpp \ + qmessagefolderid_stub.cpp \ + qmessageaccountid_stub.cpp \ + qmessagecontentcontainer_stub.cpp \ + qmessage_stub.cpp \ + qmessagefolder_stub.cpp \ + qmessageaccount_stub.cpp \ + qmessageaccountfilter_stub.cpp \ + qmessageaccountsortorder_stub.cpp \ + qmessagefolderfilter_stub.cpp \ + qmessagefoldersortorder_stub.cpp \ + qmessagefilter_stub.cpp \ + qmessagesortorder_stub.cpp \ + qmessagestore_stub.cpp \ + qmessageservice_stub.cpp + maemo5 { + QT += dbus + CONFIG += link_pkgconfig + PUBLIC_HEADERS -= qmessagecontentcontainer_p.h + PRIVATE_HEADERS -= qmessagecontentcontainer_p.h + HEADERS += qmessagecontentcontainer_maemo_p.h \ + qmessageservice_maemo_p.h \ + modestengine_maemo_p.h \ + telepathyengine_maemo_p.h \ + maemohelpers_p.h\ + eventloggerengine_maemo_p.h + SOURCES += qmessageid_maemo.cpp \ + qmessagecontentcontainerid_maemo.cpp \ + qmessagefolderid_maemo.cpp \ + qmessageaccountid_maemo.cpp \ + qmessagecontentcontainer_maemo.cpp \ + qmessage_maemo.cpp \ + qmessagefolder_maemo.cpp \ + qmessageaccount_maemo.cpp \ + qmessageaccountfilter_maemo.cpp \ + qmessageaccountsortorder_maemo.cpp \ + qmessagefolderfilter_maemo.cpp \ + qmessagefoldersortorder_maemo.cpp \ + qmessagefilter_maemo.cpp \ + qmessagesortorder_maemo.cpp \ + qmessagestore_maemo.cpp \ + qmessageservice_maemo.cpp \ + modestengine_maemo.cpp \ + telepathyengine_maemo.cpp \ + maemohelpers.cpp\ + eventloggerengine_maemo.cpp + documentation.path = $$QT_MOBILITY_PREFIX/doc + documentation.files = doc/html + PKGCONFIG += glib-2.0 \ + dbus-glib-1 \ + gconf-2.0 \ + libosso \ + libmodest-dbus-client-1.0 \ + TpSession \ + TelepathyQt4 + CONFIG += create_pc \ + create_prl + QMAKE_PKGCONFIG_REQUIRES = glib-2.0 \ + dbus-glib-1 \ + gconf-2.0 \ + osso \ + modest-dbus-client-1.0 \ + TpSession \ + TelepathyQt4 + pkgconfig.path = $$QT_MOBILITY_LIB/pkgconfig + pkgconfig.files = QtMessaging.pc + INSTALLS += pkgconfig \ + documentation + LIBS += -lgconf-2 -lrtcom-eventlogger -lmodest-dbus-client-1.0 -losso -ldbus-glib-1 -ldbus-1 -lgobject-2.0 -lglib-2.0 -ltpsession -ltelepathy-qt4 -lhildonmime + } + symbian { + INCLUDEPATH += $$APP_LAYER_SYSTEMINCLUDE + contains(messaging_freestyle_enabled, yes) { + CONFIG += FREESTYLEMAIL + DEFINES += FREESTYLEMAILUSED + DEFINES += FREESTYLEMAILBOXOBSERVERUSED + } + contains(messaging_ncnlist_enabled, no) { + DEFINES += NCNLISTREMOVED + } + HEADERS -= qmessagestore_p.h \ + qmessagecontentcontainer_p.h \ + qmessage_p.h + HEADERS += qmtmengine_symbian_p.h \ + qmessagestore_symbian_p.h \ + qmessageservice_symbian_p.h \ + qmessagecontentcontainer_symbian_p.h \ + qmessage_symbian_p.h \ + maemohelpers_p.h + + contains(CONFIG, FREESTYLEMAIL) { + HEADERS += qfsengine_symbian_p.h + } + + SOURCES += qmtmengine_symbian.cpp \ + qmessageid_symbian.cpp \ + qmessagecontentcontainerid_symbian.cpp \ + qmessagefolderid_symbian.cpp \ + qmessageaccountid_symbian.cpp \ + qmessagecontentcontainer_symbian.cpp \ + qmessage_symbian.cpp \ + qmessagefolder_symbian.cpp \ + qmessageaccount_symbian.cpp \ + qmessageaccountfilter_symbian.cpp \ + qmessageaccountsortorder_symbian.cpp \ + qmessagefolderfilter_symbian.cpp \ + qmessagefoldersortorder_symbian.cpp \ + qmessagefilter_symbian.cpp \ + qmessagesortorder_symbian.cpp \ + qmessagestore_symbian.cpp \ + qmessageservice_symbian.cpp \ + maemohelpers.cpp + + contains(CONFIG, FREESTYLEMAIL) { + SOURCES += qfsengine_symbian.cpp + } + LIBS += -lsendas2 \ + -lmsgs \ + -letext \ + -lefsrv \ + -lcharconv \ + -lgsmu \ + -limcm \ + -lbafl \ + -lmtur \ + -lsendui \ + -lsmcm \ + -limcm \ + -leikcore \ + -lcone \ + -lapgrfx \ + -lapmime \ + -lecom + TARGET.CAPABILITY = ALL \ + -TCB + TARGET.UID3 = 0x2002AC82 + QtMessaging.sources = QtMessaging.dll + QtMessaging.path = /sys/bin + DEPLOYMENT += QtMessaging + } + win32 { + PRIVATE_HEADERS += winhelpers_p.h + SOURCES += winhelpers.cpp \ + qmessageid_win.cpp \ + qmessagecontentcontainerid_win.cpp \ + qmessagefolderid_win.cpp \ + qmessageaccountid_win.cpp \ + qmessagecontentcontainer_win.cpp \ + qmessage_win.cpp \ + qmessagefolder_win.cpp \ + qmessageaccount_win.cpp \ + qmessageaccountfilter_win.cpp \ + qmessageaccountsortorder_win.cpp \ + qmessagefolderfilter_win.cpp \ + qmessagefoldersortorder_win.cpp \ + qmessagefilter_win.cpp \ + qmessagesortorder_win.cpp \ + qmessagestore_win.cpp \ + qmessageservice_win.cpp + wince* { + # Include the source files from QMF needed for MIME parsing + # These files are copied directly from the QMF repo with no changes: + PRIVATE_HEADERS += win32wce/qmailaddress.h \ + win32wce/qmailcodec.h \ + win32wce/qmailfolderfwd.h \ + win32wce/qmailglobal.h \ + win32wce/qmailid.h \ + win32wce/qmailipc.h \ + win32wce/qmaillog.h \ + win32wce/qmailmessage.h \ + win32wce/qmailmessagefwd.h \ + win32wce/qmailmessage_p.h \ + win32wce/qmailnamespace.h \ + win32wce/qmailtimestamp.h \ + win32wce/longstring_p.h \ + win32wce/qprivateimplementation.h \ + win32wce/qprivateimplementationdef.h + SOURCES += win32wce/qmailaddress.cpp \ + win32wce/qmailcodec.cpp \ + win32wce/qmailid.cpp \ + win32wce/qmailinstantiations.cpp \ + win32wce/qmaillog.cpp \ + win32wce/qmailmessage.cpp \ + win32wce/qmailmessagefwd.cpp \ + win32wce/qmailnamespace.cpp \ + win32wce/qmailtimestamp.cpp \ + win32wce/longstring.cpp \ + win32wce/qprivateimplementation.cpp + DEFINES += QTOPIAMAIL_PARSING_ONLY \ + QTOPIAMAIL_OMIT_QCOP \ + SINGLE_MODULE_QTOPIAMAIL + LIBS += cemapi.lib \ + strmiids.lib \ + uuid.lib + } + else:LIBS += mapi32.lib \ + shlwapi.lib \ + user32.lib + } +} +else:contains(qmf_enabled, yes) { + DEFINES += USE_QMF_IMPLEMENTATION + + # QMF headers must be located at $QMF_INCLUDEDIR + INCLUDEPATH += $$(QMF_INCLUDEDIR) \ + $$(QMF_INCLUDEDIR)/support + + # QMF libraries must be located at $QMF_LIBDIR + LIBS += -L \ + $$(QMF_LIBDIR) \ + -lqtopiamail + PRIVATE_HEADERS += qmfhelpers_p.h \ + qmessagestore_qmf_p.h + SOURCES += qmessageid_qmf.cpp \ + qmessagecontentcontainerid_qmf.cpp \ + qmessagefolderid_qmf.cpp \ + qmessageaccountid_qmf.cpp \ + qmessagecontentcontainer_qmf.cpp \ + qmessage_qmf.cpp \ + qmessagefolder_qmf.cpp \ + qmessageaccount_qmf.cpp \ + qmessageaccountfilter_qmf.cpp \ + qmessageaccountsortorder_qmf.cpp \ + qmessagefolderfilter_qmf.cpp \ + qmessagefoldersortorder_qmf.cpp \ + qmessagefilter_qmf.cpp \ + qmessagesortorder_qmf.cpp \ + qmessagestore_qmf.cpp \ + qmessageservice_qmf.cpp \ + qmfhelpers.cpp +} +HEADERS += $$PUBLIC_HEADERS \ + $$PRIVATE_HEADERS + +SOURCES += \ + tst_qmessagestorefiltercache.cpp + diff --git a/tests/auto/qmessagestorefiltercache/tst_qmessagestorefiltercache.cpp b/tests/auto/qmessagestorefiltercache/tst_qmessagestorefiltercache.cpp new file mode 100644 index 0000000000..885bfa4aff --- /dev/null +++ b/tests/auto/qmessagestorefiltercache/tst_qmessagestorefiltercache.cpp @@ -0,0 +1,421 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QObject> +#include <QTest> +#include <QDebug> + +#include "qmessage.h" +#include "qmessage_p.h" +#include "qmessagefilter.h" +#include "qmessagefilter_p.h" +#include "maemohelpers_p.h" +#include "../support/support.h" + +//TESTED_CLASS= +//TESTED_FILES= + +QTM_USE_NAMESPACE +#ifdef Q_OS_WIN +const QByteArray defaultCharset("UTF-16"); +#else +const QByteArray defaultCharset("UTF-8"); +#endif + +static const QString email_prefix = "MO_"; +static const QString sms_prefix = "el"; + +/* + Unit test for QMessageFilter class. +*/ +class tst_QMessageFilter : public QObject +{ + Q_OBJECT + +public: + tst_QMessageFilter(); + virtual ~tst_QMessageFilter(); + +private slots: + void initTestCase(); + void cleanup(); + void cleanupTestCase(); + + void testIdFilter(); + void testTypeFilter(); + void testSenderFilter(); + void testRecipientsFilter(); + void testSubjectFilter(); + void testTimeStampFilter(); + void testStatusFilter(); + void testPriorityFilter(); + void testSizeFilter(); + void testParentAccountIdFilter(); + void testStandardFolderFilter(); + void testParentFolderIdFilter(); + +#if defined(Q_WS_MAEMO_5) + void testIdPreFilter(); + void testTypePreFilter(); + void testParentAccountIdPreFilter(); + void testParentFolderIdPreFilter(); + void testComplexFiltersPreFilter(); +#endif +}; + +QTEST_MAIN(tst_QMessageFilter) + +#include "tst_qmessagestorefiltercache.moc" + +tst_QMessageFilter::tst_QMessageFilter() +{ +} + +tst_QMessageFilter::~tst_QMessageFilter() +{ +} + +void tst_QMessageFilter::initTestCase() +{ +} + +void tst_QMessageFilter::cleanup() +{ +} + +void tst_QMessageFilter::cleanupTestCase() +{ +} + +void tst_QMessageFilter::testIdFilter() +{ +#if defined(Q_WS_MAEMO_5) + QMessage message; + QMessagePrivate* privateMessage = QMessagePrivate::implementation(message); + privateMessage->_id = QMessageId("123"); + + QMessageFilter filter = QMessageFilter::byId(QMessageId("123"), QMessageDataComparator::Equal); + QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(filter); + QCOMPARE(pf->filter(message), true); + + filter = QMessageFilter::byId(QMessageId("124"), QMessageDataComparator::Equal); + pf = QMessageFilterPrivate::implementation(filter); + QCOMPARE(pf->filter(message), false); + + filter = QMessageFilter::byId(QMessageId("123"), QMessageDataComparator::NotEqual); + pf = QMessageFilterPrivate::implementation(filter); + QCOMPARE(pf->filter(message), false); + + filter = QMessageFilter::byId(QMessageId("124"), QMessageDataComparator::NotEqual); + pf = QMessageFilterPrivate::implementation(filter); + QCOMPARE(pf->filter(message), true); + + QMessageIdList idList; + idList.append(QMessageId("123")); + idList.append(QMessageId("124")); + idList.append(QMessageId("125")); + filter = QMessageFilter::byId(idList, QMessageDataComparator::Includes); + pf = QMessageFilterPrivate::implementation(filter); + QCOMPARE(pf->filter(message), true); + + filter = QMessageFilter::byId(idList, QMessageDataComparator::Excludes); + pf = QMessageFilterPrivate::implementation(filter); + QCOMPARE(pf->filter(message), false); + + idList.clear(); + idList.append(QMessageId("124")); + idList.append(QMessageId("125")); + idList.append(QMessageId("126")); + filter = QMessageFilter::byId(idList, QMessageDataComparator::Includes); + pf = QMessageFilterPrivate::implementation(filter); + QCOMPARE(pf->filter(message), false); + + filter = QMessageFilter::byId(idList, QMessageDataComparator::Excludes); + pf = QMessageFilterPrivate::implementation(filter); + QCOMPARE(pf->filter(message), true); +#endif +} + +void tst_QMessageFilter::testTypeFilter() +{ +#if defined(Q_WS_MAEMO_5) +#endif +} + +void tst_QMessageFilter::testSenderFilter() +{ +#if defined(Q_WS_MAEMO_5) +#endif +} + +void tst_QMessageFilter::testRecipientsFilter() +{ +#if defined(Q_WS_MAEMO_5) +#endif +} + +void tst_QMessageFilter::testSubjectFilter() +{ +#if defined(Q_WS_MAEMO_5) +#endif +} + +void tst_QMessageFilter::testTimeStampFilter() +{ +#if defined(Q_WS_MAEMO_5) +#endif +} + +void tst_QMessageFilter::testStatusFilter() +{ +#if defined(Q_WS_MAEMO_5) +#endif +} + +void tst_QMessageFilter::testPriorityFilter() +{ +#if defined(Q_WS_MAEMO_5) +#endif +} + +void tst_QMessageFilter::testSizeFilter() +{ +#if defined(Q_WS_MAEMO_5) +#endif +} + +void tst_QMessageFilter::testParentAccountIdFilter() +{ +#if defined(Q_WS_MAEMO_5) +#endif +} + +void tst_QMessageFilter::testStandardFolderFilter() +{ +#if defined(Q_WS_MAEMO_5) +#endif +} + +void tst_QMessageFilter::testParentFolderIdFilter() +{ +#if defined(Q_WS_MAEMO_5) +#endif +} + +#if defined(Q_WS_MAEMO_5) +void tst_QMessageFilter::testIdPreFilter() +{ + QMessageFilter filter = QMessageFilter::byId(QMessageId(email_prefix+"123"), QMessageDataComparator::Equal); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), false); + + filter = QMessageFilter::byId(QMessageId(sms_prefix+"123"), QMessageDataComparator::Equal); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), false); + + filter = QMessageFilter::byId(QMessageId(email_prefix+"123"), QMessageDataComparator::NotEqual); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + filter = QMessageFilter::byId(QMessageId(), QMessageDataComparator::Equal); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + filter = QMessageFilter::byId(QMessageId(), QMessageDataComparator::NotEqual); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + QMessageIdList idList; + idList.append(QMessageId(email_prefix+"123")); + idList.append(QMessageId(email_prefix+"124")); + filter = QMessageFilter::byId(idList, QMessageDataComparator::Includes); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), false); + + filter = QMessageFilter::byId(idList, QMessageDataComparator::Excludes); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + idList.clear(); + idList.append(QMessageId(sms_prefix+"123")); + idList.append(QMessageId(sms_prefix+"124")); + filter = QMessageFilter::byId(idList, QMessageDataComparator::Includes); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), false); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + filter = QMessageFilter::byId(idList, QMessageDataComparator::Excludes); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + idList.clear(); + idList.append(QMessageId(email_prefix+"123")); + idList.append(QMessageId(sms_prefix+"124")); + filter = QMessageFilter::byId(idList, QMessageDataComparator::Includes); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + filter = QMessageFilter::byId(idList, QMessageDataComparator::Excludes); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); +} + +void tst_QMessageFilter::testTypePreFilter() +{ + QMessageFilter filter = QMessageFilter::byType(QMessage::Email, QMessageDataComparator::Equal); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), false); + + filter = QMessageFilter::byType(QMessage::Sms, QMessageDataComparator::Equal); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), false); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + filter = QMessageFilter::byType(QMessage::Email, QMessageDataComparator::NotEqual); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), false); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + filter = QMessageFilter::byType(QMessage::Sms, QMessageDataComparator::NotEqual); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), false); + + filter = QMessageFilter::byType(QMessage::NoType, QMessageDataComparator::Equal); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + filter = QMessageFilter::byType(QMessage::NoType, QMessageDataComparator::NotEqual); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + filter = QMessageFilter::byType(QMessage::Email | QMessage::Mms, QMessageDataComparator::Includes); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), false); + + filter = QMessageFilter::byType(QMessage::Sms | QMessage::Mms, QMessageDataComparator::Includes); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), false); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + filter = QMessageFilter::byType(QMessage::Email | QMessage::Sms, QMessageDataComparator::Includes); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + filter = QMessageFilter::byType(QMessage::Email | QMessage::Mms, QMessageDataComparator::Excludes); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), false); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + filter = QMessageFilter::byType(QMessage::Sms | QMessage::Mms, QMessageDataComparator::Excludes); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), false); + + filter = QMessageFilter::byType(QMessage::Email | QMessage::Sms, QMessageDataComparator::Excludes); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), false); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), false); +} + +void tst_QMessageFilter::testParentAccountIdPreFilter() +{ + QMessageFilter filter = QMessageFilter::byParentAccountId(QMessageAccountId(email_prefix+"123"), QMessageDataComparator::Equal); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), false); + + filter = QMessageFilter::byParentAccountId(QMessageAccountId(sms_prefix+"123"), QMessageDataComparator::Equal); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), false); + + filter = QMessageFilter::byParentAccountId(QMessageAccountId(email_prefix+"123"), QMessageDataComparator::NotEqual); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + filter = QMessageFilter::byParentAccountId(QMessageAccountId(sms_prefix+"123"), QMessageDataComparator::NotEqual); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); +} + +void tst_QMessageFilter::testParentFolderIdPreFilter() +{ + QMessageFilter filter = QMessageFilter::byParentFolderId(QMessageFolderId(email_prefix+"123"), QMessageDataComparator::Equal); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), false); + + filter = QMessageFilter::byParentFolderId(QMessageFolderId(sms_prefix+"123"), QMessageDataComparator::Equal); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), false); + + filter = QMessageFilter::byParentFolderId(QMessageFolderId(email_prefix+"123"), QMessageDataComparator::NotEqual); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); + + filter = QMessageFilter::byParentFolderId(QMessageFolderId(sms_prefix+"123"), QMessageDataComparator::NotEqual); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(filter, QMessage::Sms), true); +} + +void tst_QMessageFilter::testComplexFiltersPreFilter() +{ + QMessageFilter filter1 = QMessageFilter::byId(QMessageId(email_prefix+"123"), QMessageDataComparator::Equal); + QMessageFilter filter2 = QMessageFilter::byId(QMessageId(sms_prefix+"123"), QMessageDataComparator::Equal); + QMessageFilter filter3 = QMessageFilter::byType(QMessage::Email, QMessageDataComparator::Equal); + QMessageFilter filter4 = QMessageFilter::byType(QMessage::Sms, QMessageDataComparator::Equal); + QMessageFilter filter5 = QMessageFilter::byType(QMessage::Mms, QMessageDataComparator::Equal); + QMessageFilter filter6 = QMessageFilter::byReceptionTimeStamp(QDateTime::fromString("1999-04-01T10:31:00Z", Qt::ISODate), QMessageDataComparator::Equal); + QMessageFilter filter7 = QMessageFilter::byStatus(QMessage::HasAttachments, QMessageDataComparator::NotEqual); + + QMessageFilter complexFilter = (filter1 & filter6) | filter3; + QCOMPARE(MessagingHelper::preFilter(complexFilter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(complexFilter, QMessage::Sms), false); + + complexFilter = (filter4 & filter6) | (filter2 & filter7); + QCOMPARE(MessagingHelper::preFilter(complexFilter, QMessage::Email), false); + QCOMPARE(MessagingHelper::preFilter(complexFilter, QMessage::Sms), true); + + complexFilter = filter3 | (filter2 & filter7); + QCOMPARE(MessagingHelper::preFilter(complexFilter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(complexFilter, QMessage::Sms), true); + + complexFilter = (filter1 & filter6) | (filter4 & filter6); + QCOMPARE(MessagingHelper::preFilter(complexFilter, QMessage::Email), true); + QCOMPARE(MessagingHelper::preFilter(complexFilter, QMessage::Sms), true); + + complexFilter = (filter5 & filter6) | (filter5 & filter7); + QCOMPARE(MessagingHelper::preFilter(complexFilter, QMessage::Email), false); + QCOMPARE(MessagingHelper::preFilter(complexFilter, QMessage::Sms), false); + + +} +#endif + diff --git a/tests/auto/qmessagestorekeys/tst_qmessagestorekeys.cpp b/tests/auto/qmessagestorekeys/tst_qmessagestorekeys.cpp index 3092285d74..630094a7d2 100644 --- a/tests/auto/qmessagestorekeys/tst_qmessagestorekeys.cpp +++ b/tests/auto/qmessagestorekeys/tst_qmessagestorekeys.cpp @@ -82,6 +82,8 @@ private slots: void cleanup(); void cleanupTestCase(); + void testFilterOperations(); + void testAccountFilter_data(); void testAccountFilter(); @@ -403,6 +405,36 @@ void tst_QMessageStoreKeys::cleanupTestCase() { } +void tst_QMessageStoreKeys::testFilterOperations() +{ + QMessageFilter filter1; + QMessageFilter filter2 = QMessageFilter::byId(QMessageId("123"), QMessageDataComparator::Equal); + + // AND + QMessageFilter combinedFilter = filter1 & filter2; + QCOMPARE(combinedFilter == filter1, false); + QCOMPARE(combinedFilter == filter2, true); + QCOMPARE(combinedFilter == QMessageFilter(), false); + + combinedFilter = filter1; + combinedFilter &= filter2; + QCOMPARE(combinedFilter == filter1, false); + QCOMPARE(combinedFilter == filter2, true); + QCOMPARE(combinedFilter == QMessageFilter(), false); + + // OR + combinedFilter = filter1 | filter2; + QCOMPARE(combinedFilter == filter1, true); + QCOMPARE(combinedFilter == filter2, false); + QCOMPARE(combinedFilter == QMessageFilter(), true); + + combinedFilter = filter1; + combinedFilter |= filter2; + QCOMPARE(combinedFilter == filter1, true); + QCOMPARE(combinedFilter == filter2, false); + QCOMPARE(combinedFilter == QMessageFilter(), true); +} + void tst_QMessageStoreKeys::testAccountFilter_data() { QTest::addColumn<QMessageAccountFilter>("filter"); diff --git a/tests/auto/qvaluespacepublisher/tst_qvaluespacepublisher.cpp b/tests/auto/qvaluespacepublisher/tst_qvaluespacepublisher.cpp index 03acc740b6..2b8c970887 100644 --- a/tests/auto/qvaluespacepublisher/tst_qvaluespacepublisher.cpp +++ b/tests/auto/qvaluespacepublisher/tst_qvaluespacepublisher.cpp @@ -108,6 +108,9 @@ private slots: void threads_data(); void threads(); + void testQtMobility400_data(); + void testQtMobility400(); + private: int variantMetaTypeId; }; @@ -721,5 +724,46 @@ void tst_QValueSpacePublisher::threads() delete writeThreads[i]; } +void tst_QValueSpacePublisher::testQtMobility400_data() +{ + QTest::addColumn<QUuid>("uuid"); + + QList<QAbstractValueSpaceLayer *> layers = QValueSpaceManager::instance()->getLayers(); + + bool foundSupported = false; + + for (int i = 0; i < layers.count(); ++i) { + QAbstractValueSpaceLayer *layer = layers.at(i); + if (layer->layerOptions() & QValueSpace::PermanentLayer) { + foundSupported = true; + + QTest::newRow(layer->name().toAscii().constData()) << layer->id(); + } + } + + if (!foundSupported) + QSKIP("No layer with Permanent flag set.", SkipAll); +} + +void tst_QValueSpacePublisher::testQtMobility400() +{ + QFETCH(QUuid, uuid); + + QValueSpacePublisher publisher(uuid, QLatin1String("/Device")); + publisher.setValue(QLatin1String("State"), QLatin1String("Starting")); + publisher.setValue(QLatin1String("State/Memory"), 1000); + publisher.sync(); + + QCOMPARE(QValueSpaceSubscriber(QLatin1String("/Device/State")).value().toString(), + QLatin1String("Starting")); + QCOMPARE(QValueSpaceSubscriber(QLatin1String("/Device/State/Memory")).value().toInt(), 1000); + + publisher.resetValue("State"); + publisher.sync(); + + QVERIFY(!QValueSpaceSubscriber(QLatin1String("/Device/State")).value().isValid()); + QVERIFY(!QValueSpaceSubscriber(QLatin1String("/Device/State/Memory")).value().isValid()); +} + QTEST_MAIN(tst_QValueSpacePublisher) #include "tst_qvaluespacepublisher.moc" diff --git a/translations/check-ts.pl b/translations/check-ts.pl new file mode 100755 index 0000000000..7b3dad7f58 --- /dev/null +++ b/translations/check-ts.pl @@ -0,0 +1,87 @@ +#! /usr/bin/perl -w +############################################################################# +## +## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +## All rights reserved. +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is part of the Qt Mobility Components. +## +## $QT_BEGIN_LICENSE:LGPL$ +## No Commercial Usage +## This file contains pre-release code and may not be distributed. +## You may use this file in accordance with the terms and conditions +## contained in the Technology Preview License Agreement accompanying +## this package. +## +## 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, Nokia gives you certain additional +## rights. These rights are described in the Nokia Qt LGPL Exception +## version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# + + +use strict; + +my %scores = (); + +my $files = join("\n", <*_??.ts>); +my $res = `xmlpatterns -param files=\"$files\" check-ts.xq`; +for my $i (split(/ /, $res)) { + $i =~ /^(?:[^\/]+\/)*qtmobility_(..)\.ts:(.*)$/; + my ($lang, $pc) = ($1, $2); + $scores{$lang} = $pc; +} + +my $code = ""; + +for my $lang (sort(keys(%scores))) { + my $pc = $scores{$lang}; + my $fail = ""; + if (int($pc) < 98) { + $fail = " (excluded)"; + } else { + $code .= " ".$lang; + } + printf "%-5s %3d%s\n", $lang, $pc, $fail; +} + +my $fn = "translations.pro"; +my $nfn = $fn."new"; +open IN, $fn or die; +open OUT, ">".$nfn or die; +while (1) { + $_ = <IN>; + last if (/^LANGUAGES /); + print OUT $_; +} +while ($_ =~ /\\\n$/) { + $_ = <IN>; +} +print OUT "LANGUAGES =".$code."\n"; +while (<IN>) { + print OUT $_; +} +close OUT; +close IN; +rename $nfn, $fn; diff --git a/translations/check-ts.xq b/translations/check-ts.xq new file mode 100644 index 0000000000..2d6404cefc --- /dev/null +++ b/translations/check-ts.xq @@ -0,0 +1,3 @@ +for $file in tokenize($files, codepoints-to-string(10)) + let $fresh := doc($file)/TS/context/message[not (translation/@type = 'obsolete')] + return concat($file, ":", count($fresh/translation[not (@type = 'unfinished')]) * 100 idiv count($fresh)) diff --git a/translations/qtmobility_ja_JP.ts b/translations/qtmobility_ja.ts index 1fcdd5d890..1fcdd5d890 100644 --- a/translations/qtmobility_ja_JP.ts +++ b/translations/qtmobility_ja.ts diff --git a/translations/qtmobility_uk.ts b/translations/qtmobility_uk.ts index cb2a459627..0d0c3cce41 100644 --- a/translations/qtmobility_uk.ts +++ b/translations/qtmobility_uk.ts @@ -4,404 +4,328 @@ <context> <name>AudioCaptureSession</name> <message> - <location filename="../plugins/multimedia/audiocapture/audiocapturesession.cpp" line="+141"/> <source>RAW file format</source> - <translation type="unfinished"></translation> + <translation>Файл формату RAW</translation> </message> <message> - <location line="+2"/> <source>WAV file format</source> - <translation type="unfinished"></translation> + <translation>Файл формату WAV</translation> </message> </context> <context> <name>AudioEncoderControl</name> <message> - <location filename="../plugins/multimedia/audiocapture/audioencodercontrol.cpp" line="+87"/> <source>PCM audio data</source> - <translation type="unfinished"></translation> + <translation>Аудіо дані PCM</translation> </message> </context> <context> <name>QGstreamerAudioEncode</name> <message> - <location filename="../plugins/multimedia/gstreamer/mediacapture/maemo/qgstreameraudioencode_maemo.cpp" line="+68"/> - <location filename="../plugins/multimedia/gstreamer/mediacapture/qgstreameraudioencode.cpp" line="+83"/> <source>Raw PCM audio</source> - <translation type="unfinished"></translation> + <translation>Сире аудіо PCM</translation> </message> </context> <context> <name>QGstreamerCaptureSession</name> <message> - <location filename="../plugins/multimedia/gstreamer/mediacapture/qgstreamercapturesession.cpp" line="+200"/> <source>Could not create an audio source element</source> - <translation type="unfinished"></translation> + <translation>Не вдалось створити елемент аудіо-джерела</translation> </message> <message> - <location line="+244"/> <source>Failed to build media capture pipeline.</source> - <translation type="unfinished"></translation> + <translation>Збій побудови конвеєру захоплення медіа.</translation> </message> </context> <context> <name>QGstreamerPlayerSession</name> <message> - <location filename="../plugins/multimedia/gstreamer/mediaplayer/qgstreamerplayersession.cpp" line="+271"/> - <location line="+16"/> <source>Unable to play %1</source> - <translation type="unfinished"></translation> + <translation>Неможливо відтворити %1</translation> </message> </context> <context> <name>QGstreamerRecorderControl</name> <message> - <location filename="../plugins/multimedia/gstreamer/mediacapture/maemo/qgstreamerrecordercontrol_maemo.cpp" line="+108"/> - <location line="+8"/> - <location filename="../plugins/multimedia/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp" line="+109"/> - <location line="+11"/> <source>Service has not been started</source> - <translation type="unfinished"></translation> + <translation>Сервіс має бути запущеним</translation> </message> <message> - <location line="+92"/> - <location filename="../plugins/multimedia/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp" line="+92"/> <source>Not compatible codecs and container format.</source> - <translation type="unfinished"></translation> + <translation>Несумісні кодеки та формат контейнера.</translation> + </message> +</context> +<context> + <name>QMLContactModel</name> + <message> + <source>Phone</source> + <translation>Телефон</translation> + </message> + <message> + <source>Email</source> + <translation>Ел. пошта</translation> </message> </context> <context> <name>QMediaPlayer</name> <message> - <location filename="../src/multimedia/qmediaplayer.cpp" line="+475"/> <source>The QMediaPlayer object does not have a valid service</source> - <translation type="unfinished"></translation> + <translation>Об'єкт QMediaPlayer не має дійсного сервісу</translation> </message> </context> <context> <name>QMediaPlaylist</name> <message> - <location filename="../src/multimedia/qmediaplaylist.cpp" line="+449"/> - <location line="+46"/> <source>Could not add items to read only playlist.</source> - <translation type="unfinished"></translation> + <translation>Не вдалось додати елементи в список програвання лише для читання.</translation> </message> <message> - <location line="-27"/> - <location line="+46"/> <source>Playlist format is not supported</source> - <translation type="unfinished"></translation> + <translation>Формат списку програвання не підтримується</translation> </message> <message> - <location line="+26"/> <source>The file could not be accessed.</source> - <translation type="unfinished"></translation> + <translation>Не вдалось отримати доступ до файлу.</translation> </message> <message> - <location line="+35"/> <source>Playlist format is not supported.</source> - <translation type="unfinished"></translation> + <translation>Формат списку програвання не підтримується.</translation> </message> </context> <context> <name>QMessage</name> <message> - <location filename="../src/messaging/qmessage_qmf.cpp" line="+597"/> - <location filename="../src/messaging/qmessage_win.cpp" line="+534"/> <source>Subject</source> - <translation type="unfinished"></translation> + <translation>Тема</translation> </message> <message> - <location line="+1"/> - <location filename="../src/messaging/qmessage_win.cpp" line="+1"/> <source>Date</source> - <translation type="unfinished"></translation> + <translation>Дата</translation> </message> <message> - <location line="+1"/> - <location filename="../src/messaging/qmessage_win.cpp" line="+1"/> <source>From</source> - <translation type="unfinished"></translation> + <translation>Від</translation> </message> <message> - <location line="+7"/> - <location filename="../src/messaging/qmessage_win.cpp" line="+1"/> <source>To</source> - <translation type="unfinished"></translation> + <translation>Кому</translation> </message> <message> - <location line="+82"/> - <location filename="../src/messaging/qmessage_win.cpp" line="+66"/> <source>On %1 you wrote: > </source> - <translation type="unfinished"></translation> + <translation>%1 ви писали: +> </translation> </message> <message> - <location filename="../src/messaging/qmessage_win.cpp" line="-70"/> <source>Forwarded Message</source> - <translation type="unfinished"></translation> + <translation>Переслане повідомлення</translation> </message> </context> <context> <name>QNetworkConfigurationManagerPrivate</name> <message> - <location filename="../src/bearer/qnetworkconfigmanager_p.cpp" line="+178"/> <source>Internet</source> - <translation type="unfinished"></translation> + <translation>Інтернет</translation> </message> </context> <context> <name>QNetworkSessionPrivate</name> <message> - <location filename="../src/bearer/qnetworksession_p.cpp" line="+301"/> - <location filename="../src/bearer/qnetworksession_s60_p.cpp" line="+265"/> <source>Unknown session error.</source> - <translation type="unfinished"></translation> + <translation>Невідома помилка сесії.</translation> </message> <message> - <location line="+2"/> - <location filename="../src/bearer/qnetworksession_s60_p.cpp" line="+2"/> <source>The session was aborted by the user or system.</source> - <translation type="unfinished"></translation> + <translation>Сесія була перервана користувачем або системою.</translation> </message> <message> - <location line="+2"/> - <location filename="../src/bearer/qnetworksession_s60_p.cpp" line="+2"/> <source>The requested operation is not supported by the system.</source> - <translation type="unfinished"></translation> + <translation>Операція, що запитується, не підтримується системою.</translation> </message> <message> - <location line="+2"/> - <location filename="../src/bearer/qnetworksession_s60_p.cpp" line="+2"/> <source>The specified configuration cannot be used.</source> - <translation type="unfinished"></translation> + <translation>Вказана конфігурація не може бути використана.</translation> </message> <message> - <location line="+2"/> - <location filename="../src/bearer/qnetworksession_s60_p.cpp" line="+2"/> <source>Roaming was aborted or is not possible.</source> - <translation type="unfinished"></translation> + <translation>Переміщення було перерване або неможливе.</translation> </message> </context> <context> <name>QObject</name> <message> - <location filename="../src/bearer/qnetworksession_maemo.cpp" line="+993"/> <source>Roaming error</source> - <translation type="unfinished"></translation> + <translation>Помилка переміщення</translation> </message> <message> - <location line="+3"/> <source>Session aborted by user or system</source> - <translation type="unfinished"></translation> + <translation>Сесія була перервана користувачем або системою</translation> </message> <message> - <location line="+4"/> <source>Unidentified Error</source> - <translation type="unfinished"></translation> + <translation>Неідентифікована помилка</translation> </message> <message> - <location filename="../src/publishsubscribe/qsystemreadwritelock_unix.cpp" line="+237"/> <source>QSystemReadWriteLock::QSystemReadWriteLock: unable to make key file for key: %1(%2)</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::QSystemReadWriteLock: неможливо створити ключовий файл для ключа: %1(%2)</translation> </message> <message> - <location line="+9"/> <source>QSystemReadWriteLock::QSystemReadWriteLock: ftok failed for key %1(%2)</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::QSystemReadWriteLock: збій ftok для ключа %1(%2)</translation> </message> <message> - <location line="+13"/> <source>QSystemReadWriteLock::QSystemReadWriteLock: Unable to access semaphore set for key %1(%2)</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::QSystemReadWriteLock: Неможливо отримати доступ до семафору, встановленого для ключа %1(%2)</translation> </message> <message> - <location line="+6"/> <source>QSystemReadWriteLock:QSystemReadWriteLock: Unable to access semaphore set for key %1(%2)</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::QSystemReadWriteLock: Неможливо отримати доступ до семафору, встановленого для ключа %1(%2)</translation> </message> <message> - <location line="+32"/> <source>QSystemReadWriteLock::QSystemReadWriteLock: Unable to reset semaphore set for key %1(%2)</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::QSystemReadWriteLock: Неможливо скинути семафор, встановлений для ключа %1(%2)</translation> </message> <message> - <location line="+16"/> <source>QSystemReadWriteLock::QSystemReadWriteLock: Unable to increment NumInstances semaphore for key%1(%2)</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::QSystemReadWriteLock: Неможливо інкрементувати семафор NumInstances для ключа %1(%2)</translation> </message> <message> - <location line="+73"/> <source>QSystemReadWriteLock::lockForRead: Unable to lock for read for key %1(Lock had not been correctly initialized)</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::lockForRead: Неможливо замкнути для читання ключ %1 (Блокування не було коректно ініціалізоване)</translation> </message> <message> - <location line="+18"/> <source>QSystemReadWriteLock::lockForRead: Unable to lock for read for key %1(%2)</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::lockForRead: Неможливо замкнути для читання ключ %1(%2)</translation> </message> <message> - <location line="+18"/> <source>QSystemReadWriteLock::lockForWrite: Unable to lock for write for key %1(Lock had not been correctly initialized)</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::lockForWrite: Неможливо замкнути для запису ключ %1 (Блокування не було коректно ініціалізоване)</translation> </message> <message> - <location line="+14"/> <source>QSystemReadWriteLock::lockForWrite: Could not increment TotalWriters semaphore for key %1(%2)</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock:::lockForWrite: Не вдалось інкрементувати семафор TotalWriters для ключа %1(%2)</translation> </message> <message> - <location line="+11"/> <source>QSystemReadWriteLock::lockForWrite: Could not detect if all readers were finished for key %1(%2)</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::lockForWrite: Не вдалось визначити чи усі читачі були завершені для ключа %1(%2)</translation> </message> <message> - <location line="+17"/> <source>QSystemReadWriteLock::lockForWrite: Could not decrement ActiveWriterSem semaphore for key %1(%2)</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock:::lockForWrite: Не вдалось декрементувати семафор ActiveWriterSem для ключа %1(%2)</translation> </message> <message> - <location line="+22"/> <source>QSystemReadWriteLock::unlock: Unable to unlock for key %1(Lock had not been correctly initialized)</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::unlock: Неможливо розблокувати ключ %1 (Блокування не було коректно ініціалізоване)</translation> </message> <message> - <location line="+29"/> <source>QSystemSemaphoreWriteLock::unlock: Unable to check and update writer semaphores for key %1(%2)</source> - <translation type="unfinished"></translation> + <translation>QSystemSemaphoreWriteLock::unlock: Неможливо перевірити та оновити семафори записувача для ключа %1(%2)</translation> </message> <message> - <location line="+9"/> <source>QSystemReadWriteLock::unlock: Unable to decrement ActiveReaders semaphore for key %1(%2)</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::unlock: Неможливо декрементувати семафор ActiveReaders для ключа %1(%2)</translation> </message> <message> - <location filename="../src/publishsubscribe/qsystemreadwritelock_win.cpp" line="+105"/> <source>QSystemReadWriteLockPrivate::QSystemReadWriteLockPrivate: Unable to create/attach to shared memory</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLockPrivate::QSystemReadWriteLockPrivate: Неможливо створити/приєднатись до спільної пам'яті</translation> </message> <message> - <location line="+7"/> <source>QSystemReadWriteLockPrivate::QSystemReadWriteLockPrivate: Unable to initialize shared memory</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLockPrivate::QSystemReadWriteLockPrivate: Неможливо ініціалізувати спільну пам'ять</translation> </message> <message> - <location line="+75"/> <source>QSystemReadWriteLock::lockForRead(): cannot peform operation, lock initialization had not been successful</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::lockForRead(): неможливо виконати операцію, невдала ініціалізація блокування</translation> </message> <message> - <location line="+6"/> <source>QSystemReadWriteLock::lockForRead(): cannot perform operation, locking of shared memory was unsuccessful</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::lockForRead(): неможливо виконати операцію, невдале блокування спільної пам'яті</translation> </message> <message> - <location line="+32"/> <source>QSystemReadWriteLock::lockForWrite(): cannot peform operation, lock initialization had not been successful</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::lockForWrite(): неможливо виконати операцію, невдала ініціалізація блокування</translation> </message> <message> - <location line="+6"/> - <location line="+39"/> <source>QSystemReadWriteLock::lockForwrite(): cannot perform operation, locking of shared memory was unsuccessful</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::lockForWrite(): неможливо виконати операцію, невдале блокування спільної пам'яті</translation> </message> <message> - <location line="-6"/> <source>QSystemReadWriteLock::unlock(): cannot peform operation, lock initialization had not been successful</source> - <translation type="unfinished"></translation> + <translation>QSystemReadWriteLock::unlock(): неможливо виконати операцію, невдала ініціалізація блокування</translation> </message> </context> <context> <name>QXARecordSession</name> <message> - <location filename="../plugins/multimedia/symbian/openmaxal/mediarecorder/qxarecordsession.cpp" line="+60"/> - <location line="+11"/> <source>Service has not been started</source> - <translation type="unfinished"></translation> + <translation>Сервіс не було запущено</translation> </message> <message> - <location line="+31"/> <source>Unable to start Service</source> - <translation type="unfinished"></translation> + <translation>Неможливо запустити сервіс</translation> </message> <message> - <location line="+44"/> - <location line="+48"/> <source>Generic error</source> - <translation type="unfinished"></translation> + <translation>Загальна помилка</translation> + </message> + <message> + <source>Settings cannot be changed once recording started</source> + <translation>Налаштування не можуть бути змінені після початку запису</translation> </message> <message> - <location line="+17"/> <source>Unable to pause</source> - <translation type="unfinished"></translation> + <translation>Неможливо призупинити</translation> </message> <message> - <location line="+17"/> <source>Unable to stop</source> - <translation type="unfinished"></translation> + <translation>Неможливо зупинити</translation> </message> <message> - <location line="+26"/> <source>Resources Unavailable</source> - <translation type="unfinished"></translation> + <translation>Ресурси недоступні</translation> </message> <message> - <location line="+76"/> <source>Invalid endpoint</source> - <translation type="unfinished"></translation> + <translation>Неправильна кінцева точка</translation> </message> <message> - <location line="+126"/> - <location line="+12"/> <source>Invalid container</source> - <translation type="unfinished"></translation> + <translation>Неправильний контейнер</translation> </message> <message> - <location line="+70"/> <source>Invalid bitrate</source> - <translation type="unfinished"></translation> + <translation>Неправильна бітова швидкість</translation> </message> <message> - <location line="+13"/> <source>Invalid channel count</source> - <translation type="unfinished"></translation> + <translation>Неправильна кількість каналів</translation> </message> <message> - <location line="+15"/> <source>Invalid codec</source> - <translation type="unfinished"></translation> + <translation>Неправильний кодек</translation> </message> <message> - <location line="+24"/> <source>Invalid encoding quality setting</source> - <translation type="unfinished"></translation> + <translation>Неправильні налаштування якості кодування</translation> </message> <message> - <location line="+9"/> - <location line="+14"/> - <location line="+14"/> <source>Invalid encoding mode setting</source> - <translation type="unfinished"></translation> + <translation>Неправильні налаштування режиму кодування</translation> </message> <message> - <location line="-23"/> - <location line="+14"/> <source>Internal error</source> - <translation type="unfinished"></translation> + <translation>Внутрішня помилка</translation> </message> <message> - <location line="+19"/> <source>Invalid sample rate</source> - <translation type="unfinished"></translation> + <translation>Неправильний розмір семплу</translation> </message> </context> <context> <name>S60MediaPlayerControl</name> <message> - <location filename="../plugins/multimedia/symbian/mmf/mediaplayer/s60mediaplayercontrol.cpp" line="+229"/> <source>Media couldn't be resolved</source> - <translation type="unfinished"></translation> + <translation>Не вдалось розв'язати медіа</translation> </message> </context> </TS> diff --git a/translations/translations.pri b/translations/translations.pri deleted file mode 100644 index aae1062120..0000000000 --- a/translations/translations.pri +++ /dev/null @@ -1,31 +0,0 @@ -defineReplace(prependAll) { - prepend = $$1 - arglist = $$2 - append = $$3 - for(a,arglist) { - result += $${prepend}$${a}$${append} - } - return ($$result) -} - -qtPrepareTool(LUPDATE, lupdate) -LUPDATE += -locations relative -no-ui-lines - -QTMOBILITY_TS = ar cs da de es fr he hu ja_JP pl pt ru sk sl sv uk zh_CN zh_TW - -lupdate.commands = (cd $$QT_MOBILITY_SOURCE_TREE && $$LUPDATE \ - -I../include \ - src/bearer \ - src/contacts \ - src/location \ - src/messaging \ - src/multimedia \ - src/publishsubscribe \ - src/sensors \ - src/serviceframework \ - src/systeminfo \ - src/versit \ - plugins \ - -ts $$prependAll($$QT_MOBILITY_SOURCE_TREE/translations/qtmobility_,$$QTMOBILITY_TS,.ts)) - -QMAKE_EXTRA_TARGETS += lupdate diff --git a/translations/translations.pro b/translations/translations.pro index 0daa888a59..1701b9fc88 100644 --- a/translations/translations.pro +++ b/translations/translations.pro @@ -1,22 +1,76 @@ include(../staticconfig.pri) -#most of this is shamelessly copied from Qt +# most of this is shamelessly copied from Qt Creator -include(translations.pri) # for "make lupdate" rule +LANGUAGES = -TRANSLATIONS = $$files(*.ts) +LUPDATE_ARGS = \ + -I../include \ + src/bearer \ + src/contacts \ + src/location \ + src/messaging \ + src/multimedia \ + src/publishsubscribe \ + src/sensors \ + src/serviceframework \ + src/systeminfo \ + src/versit \ + plugins +# var, prepend, append +defineReplace(prependAll) { + for(a,$$1):result += $$2$${a}$$3 + return($$result) +} + +qtPrepareTool(LUPDATE, lupdate) qtPrepareTool(LRELEASE, lrelease) +qtPrepareTool(LCONVERT, lconvert) +LUPDATE += -locations relative -no-ui-lines -no-sort -contains(TEMPLATE_PREFIX, vc):vcproj = 1 +TRANSLATIONS = $$prependAll(LANGUAGES, $$PWD/qtmobility_,.ts) + +files = $$files($$PWD/*_??.ts) $$PWD/qtmobility_untranslated.ts +for(file, files) { + lang = $$replace(file, .*_([^/]*)\\.ts, \\1) + v = ts-$${lang}.commands + $$v = cd $$QT_MOBILITY_SOURCE_TREE && $$LUPDATE $$LUPDATE_ARGS -ts $$file + QMAKE_EXTRA_TARGETS += ts-$$lang +} +ts-all.commands = cd $$QT_MOBILITY_SOURCE_TREE && $$LUPDATE $$LUPDATE_ARGS -ts $$files +QMAKE_EXTRA_TARGETS += ts-all + +check-ts.commands = (cd $$PWD && perl check-ts.pl) +check-ts.depends = ts-all +QMAKE_EXTRA_TARGETS += check-ts + +isEqual(QMAKE_DIR_SEP, /) { + commit-ts.commands = \ + cd $$IDE_SOURCE_TREE; \ + for f in `git diff-files --name-only translations/*_??.ts`; do \ + $$LCONVERT -locations none -i \$\$f -o \$\$f; \ + done; \ + git add translations/*_??.ts && git commit +} else { + wd = $$replace(IDE_SOURCE_TREE, /, \\) + commit-ts.commands = \ + cd $$wd && \ + for /f usebackq %%f in (`git diff-files --name-only translations/*_??.ts`) do \ + $$LCONVERT -locations none -i %%f -o %%f $$escape_expand(\\n\\t) \ + cd $$wd && git add translations/*_??.ts && git commit +} +QMAKE_EXTRA_TARGETS += commit-ts TEMPLATE = app TARGET = qm_phony_target -CONFIG -= qt separate_debug_info sis_targets +CONFIG -= qt separate_debug_info gdb_dwarf_index sis_targets CONFIG += no_icon QT = LIBS = +contains(TEMPLATE_PREFIX, vc):vcproj = 1 + updateqm.input = TRANSLATIONS updateqm.output = ${QMAKE_FILE_BASE}.qm isEmpty(vcproj):updateqm.variable_out = PRE_TARGETDEPS @@ -42,9 +96,7 @@ isEmpty(vcproj) { QMAKE_EXTRA_COMPILERS += phony_src } -translations.path = $${QT_MOBILITY_PREFIX}/translations -translations.files = $$TRANSLATIONS -translations.files ~= s,\\.ts$,.qm,g -translations.files ~= s,^,$$OUT_PWD/,g -translations.CONFIG += no_check_exist -INSTALLS += translations +qmfiles.files = $$prependAll(LANGUAGES, $$OUT_PWD/qtmobility_,.qm) +qmfiles.path = $${QT_MOBILITY_PREFIX}/translations +qmfiles.CONFIG += no_check_exist +INSTALLS += qmfiles |