src/messaging/eventloggerengine_maemo.cpp
changeset 0 876b1a06bc25
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/messaging/eventloggerengine_maemo.cpp	Wed Aug 25 15:49:42 2010 +0300
@@ -0,0 +1,478 @@
+/****************************************************************************
+**
+** 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 "eventloggerengine_maemo_p.h"
+#include "telepathyengine_maemo_p.h"
+#include <QDebug>
+
+QTM_BEGIN_NAMESPACE
+
+
+Q_GLOBAL_STATIC(EventLoggerEngine,eventLoggerEngine);
+
+
+EventLoggerEngine* EventLoggerEngine::instance()
+{
+    return eventLoggerEngine();
+}
+
+
+EventLoggerEngine::EventLoggerEngine(QObject *parent):QObject(parent)
+{
+  //    qDebug() << "EventLoggerEngine::EventLoggerEngine";
+    DBusError err=DBUS_ERROR_INIT;
+    active = false;
+    g_type_init();
+    dbus = dbus_bus_get(DBUS_BUS_SESSION, &err); // Create dummy Dbus object and
+    dbus_connection_setup_with_g_main (dbus, NULL); //add it to g_mainloop because eventlogger library expects that someone alse has added session bus to g_mainloop
+    el=rtcom_el_new ();
+    if(!RTCOM_IS_EL(el)) qDebug() << "EventLoggerEngine::EventLoggerEngine():Could't create RTComEl\n";
+
+    queryThread=0;
+    //    queryThread.run();
+    //    connect(queryThread, SIGNAL(messagesFound(const QMessageIdList &)),this, SLOT(messagesFound_(const QMessageIdList &)));
+
+
+    g_signal_connect(G_OBJECT(el), "new-event", G_CALLBACK(new_event_cb),(void*)this);
+}
+
+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)
+{
+  Q_UNUSED(el);
+  p->newEvent(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)
+{
+  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);
+
+
+    notification(event_id,service,QMessageStorePrivate::Added);
+}
+
+QMessageManager::NotificationFilterId EventLoggerEngine::registerNotificationFilter(QMessageStorePrivate& aPrivateStore,
+                                                                           const QMessageFilter &filter)
+{
+    iListenForNotifications = true;
+    ipMessageStorePrivate = &aPrivateStore;
+
+    int filterId = ++_filterId;
+    _filters.insert(filterId, filter);
+    return filterId;
+}
+
+void EventLoggerEngine::unregisterNotificationFilter(QMessageManager::NotificationFilterId notificationFilterId)
+{
+    _filters.remove(notificationFilterId);
+    if (_filters.count() == 0) {
+        iListenForNotifications = false;
+    }
+}
+QMessage EventLoggerEngine::eventToMessage(RTComElEvent & ev)
+{
+
+    QMessage message;
+
+    if (!strcmp(ev.fld_service, "RTCOM_EL_SERVICE_SMS")) {
+        message.setType(QMessage::Sms);
+    } else if (!strcmp(ev.fld_service,"RTCOM_EL_SERVICE_CHAT")) {
+        message.setType(QMessage::InstantMessage);
+    } else {
+        message.setType(QMessage::NoType);  // Other type, as exampele voice Call
+    };
+
+    message.setParentAccountId(QMessageAccountId(QString("y/Account/%1").arg(ev.fld_local_uid)));
+
+    if (!ev.fld_is_read) {
+        message.setStatus(QMessage::Read);
+    };
+    message.setPriority(QMessage::NormalPriority);
+    message.setDate(QDateTime::fromTime_t(ev.fld_start_time));
+    message.setReceivedDate(QDateTime::fromTime_t(ev.fld_start_time));
+    if (ev.fld_outgoing) QMessagePrivate::setStandardFolder(message,QMessage::SentFolder);
+    else
+      QMessagePrivate::setStandardFolder(message,QMessage::InboxFolder);
+    //    qDebug() << "event_type:"  << ev.fld_event_type << ev.fld_event_type_id << "Outgoing:" << ev.fld_outgoing << " Folder:" << message.standardFolder();
+    message.setFrom(QMessageAddress(QMessageAddress::Phone, QString(ev.fld_remote_uid)));
+    QMessagePrivate::setSenderName(message, QString(ev.fld_remote_uid));
+    QMessageAddressList messageAddresslist;
+    messageAddresslist.append(QMessageAddress(QMessageAddress::Phone, QString(ev.fld_local_uid)));
+    message.setTo(messageAddresslist);
+    message.setBody(QString(ev.fld_free_text));
+    QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
+    privateMessage->_id = QMessageId(QString("el")+QString::number(ev.fld_id));
+    privateMessage->_modified = false;
+    // qDebug() << "id:" << message.id().toString() << "From:" << message.from().addressee() << "Text:" << message.textContent();
+    return message;
+
+}
+void EventLoggerEngine::addEvent(QMessage &message)
+{
+    qDebug() << "EventLoggerEngine::addEvent()\n";
+    RTComElEvent *ev = rtcom_el_event_new();
+
+    if (message.type()==QMessage::Sms) {
+        RTCOM_EL_EVENT_SET_FIELD(ev,service,(gchar *)"RTCOM_EL_SERVICE_SMS");
+    }
+    else if (message.type()==QMessage::InstantMessage) {
+        RTCOM_EL_EVENT_SET_FIELD(ev,service,(gchar *)"RTCOM_EL_SERVICE_CHAT");
+        RTCOM_EL_EVENT_SET_FIELD(ev,remote_uid,(gchar *)message.from().addressee().toStdString().c_str());
+        RTCOM_EL_EVENT_SET_FIELD(ev,group_uid,(gchar *)message.from().addressee().toStdString().c_str());
+    }
+    else return; // Invalid messge type
+
+    RTCOM_EL_EVENT_SET_FIELD(ev,event_type,(gchar *)"RTCOM_EL_EVENTTYPE_SMS_INBOUND");
+    RTCOM_EL_EVENT_SET_FIELD(ev,local_uid,(gchar *)"ring/tel/ring");
+    RTCOM_EL_EVENT_SET_FIELD(ev,local_name,(gchar *)"<SelfHandle>");
+    RTCOM_EL_EVENT_SET_FIELD(ev,remote_uid,(gchar *)message.from().addressee().toStdString().c_str());
+    RTCOM_EL_EVENT_SET_FIELD(ev,group_uid,(gchar *)message.from().addressee().toStdString().c_str());
+    RTCOM_EL_EVENT_SET_FIELD(ev,start_time,time(NULL));
+    RTCOM_EL_EVENT_SET_FIELD(ev,remote_ebook_uid,(gchar *)"1");
+    RTCOM_EL_EVENT_SET_FIELD(ev,free_text,(gchar *)message.textContent().toStdString().c_str());
+    rtcom_el_add_event(el,ev,NULL);
+    rtcom_el_event_free(ev);
+}
+
+bool EventLoggerEngine::deleteMessage(const QMessageId& id)
+{
+  int status=rtcom_el_delete_event(el,id.toString().remove("el").toInt(),NULL);
+  return status==0;
+}
+
+QMessage EventLoggerEngine::message(const QMessageId& id)
+{
+
+    QMessage message;
+
+    // qDebug() << "EventLoggerEngine::getMessage id=" << id.toString();
+
+    RTComElEvent ev;
+    bzero(&ev,sizeof(ev));
+    RTComElQuery *q=rtcom_el_query_new(el);
+    rtcom_el_query_prepare(q,"id",id.toString().remove("el").toInt(),RTCOM_EL_OP_EQUAL,NULL);
+    RTComElIter *iter=rtcom_el_get_events(el,q);
+    g_object_unref(q);
+    if(iter && rtcom_el_iter_first(iter))
+    {
+     gboolean res=rtcom_el_iter_get_full(iter,&ev);
+     if(res) {
+#if 0
+         printf("got event id=%d service_id=%d event_typ_id=%d\n\
+local_uid=%s local_name=%s\n\
+remote_uid=%s remote_name=%s remote_ebook_uid=%s\n\
+channel=%s free_text=%s group_uid=%s\n\
+service=%s event_type=%s\n\
+additional_text=%s icon_name=%s pango_markup=%s\n",
+                    ev.fld_id,ev.fld_service_id,ev.fld_event_type_id,
+                    ev.fld_local_uid,ev.fld_local_name,
+                    ev.fld_remote_uid,ev.fld_remote_name,ev.fld_remote_ebook_uid,
+                    ev.fld_channel,ev.fld_free_text,ev.fld_group_uid,
+                    ev.fld_service,ev.fld_event_type,
+                    ev.fld_additional_text,ev.fld_icon_name,ev.fld_pango_markup);
+#endif
+         if (!strcmp(ev.fld_service, "RTCOM_EL_SERVICE_SMS")) {
+             message.setType(QMessage::Sms);
+         } else if (!strcmp(ev.fld_service,"RTCOM_EL_SERVICE_CHAT")) {
+             message.setType(QMessage::InstantMessage);
+         } else {
+             message.setType(QMessage::NoType);  // Other type, as exampele voice Call
+         };
+         //QMessageAccount account =  TelepathyEngine::instance()->account(QMessageAccountId(QString("/y/Account%1").arg(ev.fld_local_uid)));
+
+         message.setParentAccountId(QMessageAccountId(QString("/y/Account/%1").arg(ev.fld_local_uid)));
+         if (!ev.fld_is_read) {
+             message.setStatus(QMessage::Read);
+         };
+         message.setPriority(QMessage::NormalPriority);
+         message.setDate(QDateTime::fromTime_t(ev.fld_start_time));
+         message.setReceivedDate(QDateTime::fromTime_t(ev.fld_start_time));
+	 if (ev.fld_outgoing) QMessagePrivate::setStandardFolder(message,QMessage::SentFolder);
+	 else
+	   QMessagePrivate::setStandardFolder(message,QMessage::InboxFolder);
+         message.setFrom(QMessageAddress(QMessageAddress::Phone, QString(ev.fld_remote_uid)));
+         QMessagePrivate::setSenderName(message, QString(ev.fld_remote_uid));
+         QMessageAddressList messageAddresslist;
+         messageAddresslist.append(QMessageAddress(QMessageAddress::Phone, QString(ev.fld_local_uid)));
+         message.setTo(messageAddresslist);
+         message.setBody(QString(ev.fld_free_text));
+         QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
+         privateMessage->_id = id;
+         privateMessage->_modified = false;
+	 //  qDebug() << "id:" << message.id().toString() << "From:" << message.from().addressee() << "Text:" << message.textContent();
+     };
+    };
+    if(iter) g_object_unref(iter);
+    //    debugMessage(message);
+
+    return message;
+
+}
+
+void EventLoggerEngine::debugMessage(QMessage &message)
+{
+    qDebug() << "id:" << message.id().toString() << "type:" << message.type() << "size:" << message.size() << "status:" << message.status() << "priority:" << message.priority();
+    qDebug() << "AccountId:" << message.parentAccountId().toString() << "StantardFolder" << message.standardFolder() << "parenFolderId:" << message.parentFolderId().toString();
+    qDebug() << "Date:" << message.date() << "receivedDate:" << message.receivedDate() << "Subject:" << message.subject();
+    qDebug() << "From:" << message.from().addressee();
+    qDebug() << "To:" << (message.to().isEmpty() ? "**none**" : message.to().first().addressee());
+    qDebug() << "Body:" <<message.textContent();
+}
+
+
+void EventLoggerEngine::notification(int eventId, QString service,QMessageStorePrivate::NotificationType notificationType)
+{
+
+
+    QMessageManager::NotificationFilterIdSet matchingFilters;
+    // qDebug() << "EventLoggerEngine::notification id=" << eventId;
+
+    // Copy the filter map to protect against modification during traversal
+    QMap<int, QMessageFilter> filters(_filters);
+    QMap<int, QMessageFilter>::const_iterator it = filters.begin(), end = filters.end();
+    QMessage msg;
+    bool messageRetrieved = false;
+
+    for ( ; it != end; ++it) {
+        const QMessageFilter &filter(it.value());
+        if (filter.isEmpty()) {
+            // Empty filter matches to all messages
+            matchingFilters.insert(it.key());
+        } else {
+            QMessageFilterPrivate* privateMessageFilter = QMessageFilterPrivate::implementation(filter);
+            if (!messageRetrieved && (privateMessageFilter->_field == QMessageFilterPrivate::Type)) {
+                if (service == "RTCOM_EL_SERVICE_SMS") {
+                    msg.setType(QMessage::Sms);
+                } else if (service== "RTCOM_EL_SERVICE_CHAT") {
+                    msg.setType(QMessage::InstantMessage);
+                } else {
+                    msg.setType(QMessage::NoType);  // Other type, as eample voice calll
+                }
+            }
+            else if (!messageRetrieved) {
+                msg = this->message(QMessageId(QString("el")+QString::number(eventId)));
+                if (msg.type() == QMessage::NoType) {
+                    matchingFilters.clear();
+                    break;
+                } else {
+                    messageRetrieved = true;
+                }
+            }
+            if (privateMessageFilter->filter(msg)) {
+                matchingFilters.insert(it.key());
+            }
+        }
+    }
+
+    if (matchingFilters.count() > 0) {
+            ipMessageStorePrivate->messageNotification(notificationType,
+                                                       QMessageId(QString("el")+QString::number(eventId)),
+                                                       matchingFilters);
+        }
+
+}
+
+#if 0
+QMessageIdList EventLoggerEngine::filterAndOrderMessages(const QMessageFilter &filter, const QMessageSortOrder& sortOrder,
+                                                    QString body, QMessageDataComparator::MatchFlags matchFlags)
+{
+    filterAndOrderMessages(filte, sortOrder, body, matchFlags);
+}
+#endif
+
+bool EventLoggerEngine::filterMessages(const QMessageFilter &filter,
+                                                    const QMessageSortOrder& sortOrder,
+                                                    QString body,
+                                                    QMessageDataComparator::MatchFlags matchFlags)
+{
+
+  //  qDebug() << "EventLoggerEngine::filterMessages";
+  if (active) {
+    qWarning() << "EventLoggerEngine::filterMessages::Service is currently busy";
+    return false;
+  }
+
+
+  active = true;
+  state = QMessageService::ActiveState;
+  emit stateChanged(state);
+
+  if(!queryThread) {
+    queryThread=new QueryThread();
+    connect(queryThread, SIGNAL(completed()), this, SLOT(reportMatchingIds()), Qt::QueuedConnection);
+  };
+  queryThread->setArgs(this, filter, body, matchFlags, sortOrder, 0,0);
+  queryThread->start();
+
+    //  return queryThread.queryMessages(filter,sortOrder,body,matchFlags);
+    return true;
+}
+
+void EventLoggerEngine::messagesFound_(const QMessageIdList &ids)
+{
+  //  qDebug() << "EventLoggerEngine::messagesFound";
+  emit messagesFound(ids,true,false); // filtered but not sorted
+}
+
+
+void EventLoggerEngine::reportMatchingIds()
+{
+  //  qDebug() << "EventLoggerEngine::messagesFound" << m_ids.count();
+  emit messagesFound(m_ids,true,false);
+  completed();
+}
+
+void EventLoggerEngine::completed()
+{
+    active = false;
+    state = QMessageService::FinishedState;
+    emit stateChanged(state);
+}
+
+
+QMessageIdList EventLoggerEngine::filterAndOrderMessages(const QMessageFilter &filter,
+                                                    const QMessageSortOrder& sortOrder,
+                                                    QString body,
+                                                    QMessageDataComparator::MatchFlags matchFlags)
+{
+  Q_UNUSED(body);
+  Q_UNUSED(matchFlags);
+  Q_UNUSED(sortOrder);
+    QMessageId fId;  // Filtering id
+    //    QMessageType fType;
+    QDate fDate;
+    RTComElEvent ev;
+    QMessage message;
+    
+    const char *services[]={"RTCOM_EL_SERVICE_CHAT","RTCOM_EL_SERVICE_SMS", NULL };
+
+    QMessageIdList idList;
+
+    QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(filter);
+#if 0
+    if ((filters.count() == 1) && (pf->_field == QMessageFilterPrivate::None) && (pf->_filterList.count() == 0)) {
+        if (pf->_notFilter) {
+            // There is only one filter: empty ~QMessageFilter()
+            // => return empty QMessageIdList
+            return idList;
+        } else {
+            // There is only one filter: empty QMessageFilter()
+            // => return all messages
+
+            }
+        }
+    // Pre-filtering setup
+    switch (pf->_field) {
+    case QMessageFilterPrivate::Id:
+    case QMessageFilterPrivate::ParentAccountId:
+        {
+        if (pf->_comparatorType == QMessageFilterPrivate::Equality) { // QMessageAccountId
+            iNumberOfHandledFilters++;
+            QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
+            if (cmp == QMessageDataComparator::Equal) {
+                QMessageAccount messageAccount = TelepathyEngine::instance()->account(QMessageAccountId(QString("/y/Account%1").arg(pf->_value.toString())));
+            }
+        }
+       }
+    }
+#endif
+    RTComElQuery *q=rtcom_el_query_new(el);
+    rtcom_el_query_prepare(q,"service", services, RTCOM_EL_OP_IN_STRV, NULL);
+    RTComElIter *iter=rtcom_el_get_events(el,q);
+    g_object_unref(q);
+    if(iter && rtcom_el_iter_first(iter))
+       do {
+         bzero(&ev,sizeof(ev));
+         if(rtcom_el_iter_get_full(iter,&ev))
+	   {
+	     message=eventToMessage(ev);
+	     // debugMessage(message);
+	     if (pf->filter(message)) {
+	       //   qDebug() <<"Filter :filtering match" << message.id().toString();
+	       //matchingFilters.insert(it.key());
+	       idList.append(message.id());
+	     };
+	   };
+       }
+       while( rtcom_el_iter_next(iter));
+#if 0
+    foreach(const QMessageId& id, idList) {
+         	  qDebug() << "id=" << id.toString();
+        }
+#endif
+    return idList;
+}
+
+
+QueryThread::QueryThread(): QThread()
+{
+}
+
+void QueryThread::setArgs(EventLoggerEngine *parent, const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset)
+{
+  _parent=parent;
+  _filter=filter;
+  _body=body;
+  _matchFlags=matchFlags;
+  _sortOrder=sortOrder;
+  _limit=limit;
+  _offset=offset;
+}
+
+void QueryThread::run()
+{
+  //  qDebug() << "QueryThread::run()";
+  _parent->m_ids=EventLoggerEngine::instance()->filterAndOrderMessages(_filter,_sortOrder,_body,_matchFlags);
+  //  qDebug() << "QueryThread::run() done" << _parent->m_ids.count();
+  emit completed();
+}
+
+
+
+#include "moc_eventloggerengine_maemo_p.cpp"
+
+QTM_END_NAMESPACE