phonebookui/cntlistmodel/cntinfofetcher.cpp
changeset 81 640d30f4fb64
equal deleted inserted replaced
77:c18f9fa7f42e 81:640d30f4fb64
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Fetches visual info about contacts.
       
    15 *
       
    16 */
       
    17 
       
    18 #include <QPluginLoader>
       
    19 #include <QDir>
       
    20 #include <qtcontacts.h>
       
    21 #include <cntinfofetcher.h>
       
    22 #include <cntinfoproviderfactory.h>
       
    23 #include <cntinfoprovider.h>
       
    24 #include <cntdefaultinfoprovider.h>
       
    25 #include <cntpresenceinfoprovider.h>
       
    26 #include <cntdebug.h>
       
    27 
       
    28 /*!
       
    29     \class CntInfoCacheItem
       
    30     \brief Cache item that holds some visual info about a contact.
       
    31  */
       
    32 
       
    33 /*!
       
    34     \class CntInfoFetcher
       
    35     \brief CntInfoFetcher asynchronously fetches visual info about contacts.
       
    36 
       
    37     CntInfoFetcher queues requests for contact info that is to be cached.
       
    38     It fetches the info later, when asked by the client to do so.
       
    39 
       
    40     There are three pieces of info that is fetched:
       
    41       - secondary text, e.g. phone number
       
    42       - primary icon, e.g. avatar for contact
       
    43       - secondary icon, e.g. presence status
       
    44 
       
    45     Internally CntInfoFetcher uses plugins (info providers) to fetch the data.
       
    46  */
       
    47 
       
    48 // maximum amount of scheduled jobs; if there are more jobs, the least
       
    49 // important job is cancelled
       
    50 const int MaxInfoJobs = 20;
       
    51 
       
    52 // directory of info providers
       
    53 const char *CNT_INFO_PROVIDER_EXTENSION_PLUGIN_DIRECTORY = "/resource/qt/plugins/contacts/infoproviders/";
       
    54 
       
    55 /*!
       
    56     Creates a CntIconFetcher object.
       
    57  */
       
    58 CntInfoFetcher::CntInfoFetcher(QContactManager *contactManager)
       
    59     : CntAbstractFetcher(MaxInfoJobs),
       
    60       mContactManager(contactManager)
       
    61 {
       
    62     CNT_ENTRY
       
    63 
       
    64     // create static info provider plugins
       
    65     mInfoProviders.insert(new CntDefaultInfoProvider(), ContactInfoAllFields);
       
    66     mInfoProviders.insert(new CntPresenceInfoProvider(), ContactInfoIcon2Field);
       
    67 
       
    68     // load dynamic info provider plugins
       
    69     QDir pluginsDir(CNT_INFO_PROVIDER_EXTENSION_PLUGIN_DIRECTORY);
       
    70     foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
       
    71         // create plugin loader
       
    72         QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
       
    73         if (pluginLoader.load()) {
       
    74             CntInfoProviderFactory *factory = qobject_cast<CntInfoProviderFactory*>(pluginLoader.instance());
       
    75             if (factory) {
       
    76                 CntInfoProvider *provider = factory->infoProvider();
       
    77                 mInfoProviders.insert(provider, provider->supportedFields());
       
    78             }
       
    79         }
       
    80     }
       
    81 
       
    82     // connect the providers
       
    83     QMapIterator<CntInfoProvider*, ContactInfoFields> i(mInfoProviders);
       
    84     while (i.hasNext()) {
       
    85         i.next();
       
    86         connect(static_cast<CntInfoProvider*>(i.key()),
       
    87                 SIGNAL(infoFieldReady(CntInfoProvider*, int, ContactInfoField, const QString&)),
       
    88                 this,
       
    89                 SLOT(forwardInfoToClient(CntInfoProvider*, int, ContactInfoField, const QString&)));
       
    90     }
       
    91 
       
    92     CNT_EXIT
       
    93 }
       
    94 
       
    95 /*!
       
    96     Cleans up and destructs the CntIconFetcher object.
       
    97  */
       
    98 CntInfoFetcher::~CntInfoFetcher()
       
    99 {
       
   100     CNT_ENTRY
       
   101 
       
   102     qDeleteAll(mInfoProviders.keys());
       
   103     mInfoProviders.clear();
       
   104 
       
   105     CNT_EXIT
       
   106 }
       
   107 
       
   108 /*!
       
   109     Processes the next scheduled job. This function must not be
       
   110     called until the previous job has completed.
       
   111  */
       
   112 void CntInfoFetcher::processNextJob()
       
   113 {
       
   114     CNT_ENTRY
       
   115 
       
   116     if (hasScheduledJobs()) {
       
   117         // get the next job
       
   118         CntInfoJob *job = static_cast<CntInfoJob *>(takeNextJob());
       
   119 
       
   120         // fetch a QContact object
       
   121         QContactFetchHint restrictions;
       
   122         restrictions.setOptimizationHints(QContactFetchHint::NoRelationships);
       
   123         QContact contact = mContactManager->contact(job->contactId, restrictions);
       
   124         
       
   125         // request contact info from providers
       
   126         QMapIterator<CntInfoProvider*, ContactInfoFields> i(mInfoProviders);
       
   127         while (i.hasNext()) {
       
   128             i.next();
       
   129             if (i.value() != 0) {
       
   130                 i.key()->requestInfo(contact, i.value());
       
   131             }
       
   132         }
       
   133         
       
   134         delete job;
       
   135     } else if (hasCancelledJobs()) {
       
   136         CntInfoJob *cancelledJob = static_cast<CntInfoJob *>(takeNextCancelledJob());
       
   137         emit infoCancelled(cancelledJob->contactId);
       
   138         delete cancelledJob;
       
   139     }
       
   140 
       
   141     CNT_EXIT
       
   142 }
       
   143 
       
   144 /*!
       
   145     \return true if a job is currently being processed; otherwise returns false.
       
   146  */
       
   147 bool CntInfoFetcher::isProcessingJob()
       
   148 {
       
   149     return false;
       
   150 }
       
   151 
       
   152 /*!
       
   153     Forward info from a provider to the client.
       
   154  */
       
   155 void CntInfoFetcher::forwardInfoToClient(CntInfoProvider *sender,
       
   156                                          int contactId,
       
   157                                          ContactInfoField field,
       
   158                                          const QString &text)
       
   159 {
       
   160     CNT_ENTRY
       
   161 
       
   162     // there can be 3rd party info providers, so we cannot blindly trust them;
       
   163     // info is emitted iff:
       
   164     if (mInfoProviders.contains(sender)
       
   165         && ((field & (field - 1)) == 0)                         // 1) exactly one field bit is set in parameter 'field'
       
   166         && ((field & mInfoProviders.value(sender)) != 0)) {     // 2) the field bit has been assigned to this provider
       
   167         emit infoUpdated(contactId, field, text);
       
   168     }
       
   169 
       
   170     CNT_EXIT
       
   171 }