qtmobility/plugins/contacts/qtcontacts-tracker/trackerchangelistener.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 11 06b8e2af4411
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    45 #include "trackerchangelistener.h"
    45 #include "trackerchangelistener.h"
    46 #include "qcontact.h"
    46 #include "qcontact.h"
    47 
    47 
    48 using namespace SopranoLive;
    48 using namespace SopranoLive;
    49 
    49 
    50 TrackerChangeListener::TrackerChangeListener(QObject* parent)
    50 TrackerChangeListener::TrackerChangeListener(QContactManagerEngine *eng, QObject* parent) :
    51 :QObject(parent)
    51     QObject(parent), engine(eng)
    52 {
    52 {
    53     signaler_contact = SopranoLive::BackEnds::Tracker::ClassUpdateSignaler::get(
    53     signaler_contact = SopranoLive::BackEnds::Tracker::ClassUpdateSignaler::get(nco::Contact::iri());
    54                     nco::Contact::iri());
    54     if (signaler_contact)
    55     connectSignals(signaler_contact);
    55     {
       
    56         SopranoLive::BackEnds::Tracker::ClassUpdateSignaler * signaler = signaler_contact;
       
    57         connect(signaler, SIGNAL(subjectsAdded(const QStringList &)), SLOT(contactsAdded(const QStringList &)));
       
    58         connect(signaler,SIGNAL(subjectsRemoved(const QStringList &)),SLOT(contactsRemoved(const QStringList &)));
       
    59         connect(signaler,SIGNAL(subjectsChanged(const QStringList &)),SLOT(contactsChanged(const QStringList &)));
       
    60     }
    56 
    61 
    57     signaler_imaccount = SopranoLive::BackEnds::Tracker::ClassUpdateSignaler::get(
    62     signaler_imaccount = SopranoLive::BackEnds::Tracker::ClassUpdateSignaler::get(nco::IMAccount::iri());
    58                     nco::IMAccount::iri());
    63     if (signaler_imaccount)
    59     connectSignals(signaler_imaccount);
    64     {
       
    65         // same for all signals - emit selfContact changed
       
    66         SopranoLive::BackEnds::Tracker::ClassUpdateSignaler * signaler = signaler_imaccount;
       
    67         connect(signaler, SIGNAL(subjectsAdded(const QStringList &)),SLOT(imAccountsChanged(const QStringList &)));
       
    68         connect(signaler,SIGNAL(subjectsRemoved(const QStringList &)),SLOT(imAccountsChanged(const QStringList &)));
       
    69         connect(signaler,SIGNAL(subjectsChanged(const QStringList &)),SLOT(imAccountsChanged(const QStringList &)));
       
    70     }
       
    71 
       
    72     signaler_imaddress = SopranoLive::BackEnds::Tracker::ClassUpdateSignaler::get(nco::IMAddress::iri());
       
    73     if (signaler_imaddress)
       
    74     {
       
    75         // same for all signals - contact changed to be emitted
       
    76         SopranoLive::BackEnds::Tracker::ClassUpdateSignaler * signaler = signaler_imaddress;
       
    77         connect(signaler, SIGNAL(subjectsAdded(const QStringList &)),SLOT(imAddressesChanged(const QStringList &)));
       
    78         connect(signaler,SIGNAL(subjectsRemoved(const QStringList &)),SLOT(imAddressesChanged(const QStringList &)));
       
    79         connect(signaler,SIGNAL(subjectsChanged(const QStringList &)),SLOT(imAddressesChanged(const QStringList &)));
       
    80     }
       
    81 
    60 }
    82 }
    61 
    83 
    62 TrackerChangeListener::~TrackerChangeListener()
    84 TrackerChangeListener::~TrackerChangeListener()
    63 {
    85 {
       
    86     if (signaler_imaddress)
       
    87         signaler_imaddress->disconnect(this);
       
    88     if (signaler_contact)
       
    89         signaler_contact->disconnect(this);
       
    90     if (signaler_imaccount)
       
    91         signaler_imaccount->disconnect(this);
    64 }
    92 }
    65 // TEMPORARY here we'll for now extract ids from tracker contact URI.
    93 
    66 // In future need nonblocking async way to get contact ids from tracker contact urls
       
    67 // let's see which signals will be used from libqttracker
       
    68 QContactLocalId url2UniqueId(const QString &contactUrl)
    94 QContactLocalId url2UniqueId(const QString &contactUrl)
    69 {
    95 {
    70 
       
    71     /* Telepathy URI would look like telepathy:///org/freedesktop...
       
    72        convert the URI component which contains the 
       
    73        account + contat id to uint32 expected by
       
    74        qcontactlocalid
       
    75     */
       
    76     if (contactUrl.contains("telepathy")) {
       
    77         QContactLocalId id = 0;
       
    78         QStringList decoded = contactUrl.split(":");
       
    79         id = qHash(decoded.value(1).remove(0,1));
       
    80         return id;
       
    81     }
       
    82 
       
    83     /* handle conatact:interger URL types comming from
    96     /* handle conatact:interger URL types comming from
    84        which are non telepathy url's
    97        which are non telepathy url's
    85     */
    98     */
    86     QRegExp rx("(\\d+)");
    99     QRegExp rx("(\\d+)");
    87     bool conversion = false;
   100     bool conversion = false;
    91         id = rx.cap(1).toUInt(&conversion, 10);
   104         id = rx.cap(1).toUInt(&conversion, 10);
    92     }
   105     }
    93     if( !conversion )
   106     if( !conversion )
    94         qWarning() << Q_FUNC_INFO << "unparsed uri to uniqueI:" << contactUrl;
   107         qWarning() << Q_FUNC_INFO << "unparsed uri to uniqueI:" << contactUrl;
    95     return id;
   108     return id;
    96 
       
    97 }
   109 }
    98 
   110 
    99 void TrackerChangeListener::subjectsAdded(const QStringList &subjects)
   111 void TrackerChangeListener::contactsAdded(const QStringList &subjects)
   100 {
   112 {
   101     QList<QContactLocalId> added;
   113     QList<QContactLocalId> added;
   102     foreach(const QString &uri, subjects)
   114     foreach(const QString &uri, subjects)
   103     {
   115     {
   104         added << url2UniqueId(uri);
   116         added << url2UniqueId(uri);
   105     }
   117     }
   106     emit contactsAdded(added);
   118     emit contactsAdded(added);
   107 }
   119 }
   108 
   120 
   109 void TrackerChangeListener::subjectsRemoved(const QStringList &subjects)
   121 void TrackerChangeListener::contactsRemoved(const QStringList &subjects)
   110 {
   122 {
   111     QList<QContactLocalId> added;
   123     QList<QContactLocalId> added;
   112     foreach(const QString &uri, subjects)
   124     foreach(const QString &uri, subjects)
   113     {
   125     {
   114         added << url2UniqueId(uri);
   126         added << url2UniqueId(uri);
   115     }
   127     }
   116     emit contactsRemoved(added);
   128     emit contactsRemoved(added);
   117 }
   129 }
   118 
   130 
   119 // TODO data changed for full query
   131 
   120 void TrackerChangeListener::subjectsChanged(const QStringList &subjects)
   132 void TrackerChangeListener::contactsChanged(const QStringList &subjects)
   121 {
   133 {
   122     QList<QContactLocalId> changed;
   134     QList<QContactLocalId> changed;
   123     foreach(const QString &uri, subjects) {
   135     foreach(const QString &uri, subjects) {
   124         QContactLocalId id = url2UniqueId(uri);
   136         QContactLocalId id = url2UniqueId(uri);
   125         if (changed.contains(id) == false) {
   137         if (changed.contains(id) == false) {
   127         }
   139         }
   128     }
   140     }
   129     emit contactsChanged(changed);
   141     emit contactsChanged(changed);
   130 }
   142 }
   131 
   143 
   132 
   144 void TrackerChangeListener::imAccountsChanged(const QStringList &subjects)
   133 AsyncQuery::AsyncQuery(RDFSelect selectQuery)
       
   134 {
   145 {
   135     nodes = ::tracker()->modelQuery(selectQuery);
   146     Q_UNUSED(subjects)
   136     QObject::connect(nodes.model(), SIGNAL(modelUpdated()), this,
   147     QContactManager::Error error;
   137             SLOT(queryReady()));
   148     QContactLocalId selfId = engine->selfContactId(&error);
       
   149     if (engine && QContactManager::NoError == error) {
       
   150         emit contactsChanged(QList<QContactLocalId>()<<selfId);
       
   151     } else {
       
   152         qWarning() << __PRETTY_FUNCTION__ << "Signal not propagated:" << engine << error;
       
   153     }
   138 }
   154 }
   139 
   155 
   140 void AsyncQuery::queryReady()
   156 void TrackerChangeListener::imAddressesChanged(const QStringList &subjects)
   141 {
   157 {
   142     emit queryReady(this);
   158     Q_UNUSED(subjects)
       
   159     // TODO use QHash in engine - mapping IMAddress URIs to contacts
       
   160     qWarning() << __PRETTY_FUNCTION__ << "Not implemented";
   143 }
   161 }
   144 
       
   145 void TrackerChangeListener::connectSignals(SopranoLive::BackEnds::Tracker::ClassUpdateSignaler *signaler) {
       
   146     // Note here that we are not using
       
   147     // QAbstractItemModel signals from LiveNodes::model() because
       
   148     // node list for which notification comes is fixed. Those are used for
       
   149     // async implementation
       
   150     if (signaler)
       
   151     {
       
   152         connect(signaler, SIGNAL(subjectsAdded(const QStringList &)),
       
   153                 SLOT(subjectsAdded(const QStringList &)));
       
   154         connect(signaler,
       
   155                 SIGNAL(baseRemoveSubjectsd(const QStringList &)),
       
   156                 SLOT(subjectsRemoved(const QStringList &)));
       
   157         connect(signaler,
       
   158                 SIGNAL(subjectsChanged(const QStringList &)),
       
   159                 SLOT(subjectsChanged(const QStringList &)));
       
   160     }
       
   161 }