plugins/contacts/maemo5/qcontactabook.cpp
changeset 5 603d3f8b6302
parent 0 876b1a06bc25
equal deleted inserted replaced
3:e4ebb16b39ea 5:603d3f8b6302
   325   }
   325   }
   326   *error = QContactManager::NoError;
   326   *error = QContactManager::NoError;
   327   return rtn;
   327   return rtn;
   328   */
   328   */
   329 }
   329 }
       
   330 #include "qcontactdetail_p.h"
   330 
   331 
   331 QContact* QContactABook::getQContact(const QContactLocalId& contactId, QContactManager::Error* error) const
   332 QContact* QContactABook::getQContact(const QContactLocalId& contactId, QContactManager::Error* error) const
   332 {
   333 {
   333   QContact *rtn;
   334   QContact *rtn;
   334   OssoABookContact* aContact = getAContact(contactId, error);
   335   OssoABookContact* aContact = getAContact(contactId, error);
   822   detailList << getNicknameDetail(eContact);
   823   detailList << getNicknameDetail(eContact);
   823 
   824 
   824   /* Note */
   825   /* Note */
   825   detailList << getNoteDetail(eContact);
   826   detailList << getNoteDetail(eContact);
   826 
   827 
   827   /* Online Account & presences*/
   828   /* Online Account */
   828   QList<QContactOnlineAccount*> onlineAccounts;
   829   QList<QContactOnlineAccount*> onlineAccountList = getOnlineAccountDetail(eContact);
   829   QList<QContactPresence*> presences;
       
   830   getOnlineAccountAndPresenceDetails(eContact, onlineAccounts, presences);
       
   831   
       
   832   QContactOnlineAccount* onlineAccount;
   830   QContactOnlineAccount* onlineAccount;
   833   foreach(onlineAccount, onlineAccounts)
   831   foreach(onlineAccount, onlineAccountList)
   834     detailList << onlineAccount;
   832     detailList << onlineAccount;
   835   
       
   836   QContactPresence* presence;
       
   837   foreach(presence, presences)
       
   838     detailList << presence;
       
   839 
   833 
   840   /* Organization */
   834   /* Organization */
   841   detailList << getOrganizationDetail(eContact);
   835   detailList << getOrganizationDetail(eContact);
   842 
   836 
   843   /* Phone*/
   837   /* Phone*/
   900 {
   894 {
   901   OssoABookContact* rtn = NULL;
   895   OssoABookContact* rtn = NULL;
   902 
   896 
   903   QCM5_DEBUG << "Getting aContact with id " << m_localIds[contactId] << "local contactId is" << contactId;
   897   QCM5_DEBUG << "Getting aContact with id " << m_localIds[contactId] << "local contactId is" << contactId;
   904 
   898 
   905   if(QString::fromAscii(m_localIds[contactId]).compare("osso-abook-self") == 0) {
   899   if(QString(m_localIds[contactId]).compare("osso-abook-self") == 0) {
   906     *error = QContactManager::NoError;
   900     *error = QContactManager::NoError;
   907     rtn = A_CONTACT(osso_abook_self_contact_get_default());
   901     rtn = A_CONTACT(osso_abook_self_contact_get_default());
   908   } else {
   902   } else {
   909     GList* c = osso_abook_aggregator_lookup(m_abookAgregator, m_localIds[contactId]);
   903     EBookQuery* query;
   910     if (c)
   904     GList* contacts;
   911       rtn = A_CONTACT(c->data);
   905 
   912     *error = rtn ? QContactManager::NoError : QContactManager::DoesNotExistError;
   906     query = e_book_query_field_test(E_CONTACT_UID, E_BOOK_QUERY_IS, m_localIds[contactId]);
   913     return rtn;
   907     contacts = osso_abook_aggregator_find_contacts(m_abookAgregator, query);
       
   908     if (query)
       
   909         e_book_query_unref(query);
       
   910 
       
   911     if (g_list_length(contacts) == 1) {
       
   912       *error = QContactManager::NoError;
       
   913       rtn = A_CONTACT(contacts->data);
       
   914     } else if (g_list_length(contacts) == 0) {
       
   915       *error = QContactManager::DoesNotExistError;
       
   916     } else {
       
   917       // Several contacts have the same UID or the contactId belongs to a roster contact.
       
   918       *error = QContactManager::UnspecifiedError;
       
   919     }
       
   920     if (contacts)
       
   921       g_list_free(contacts);
   914   }
   922   }
   915 
   923 
   916   return rtn;
   924   return rtn;
   917 }
   925 }
   918 
   926 
   970     }
   978     }
   971     
   979     
   972     // Set Address Values
   980     // Set Address Values
   973     GList *v = NULL;
   981     GList *v = NULL;
   974     v =e_vcard_attribute_get_values(attr);
   982     v =e_vcard_attribute_get_values(attr);
   975     if (!v) {
   983     if (!v)
   976       // ADR attribute data is corrupted.  Skipping.
   984       qFatal("ADR attribute data is corrupted"); 
   977       g_list_free(attrList);
   985     if (g_list_length(v) != 7){
   978       return rtnList;
   986       g_list_free(v);
   979     }
   987       qCritical() << "ADR attribute data is corrupted"; 
   980 
   988     }
   981     int i = 0;
   989     int i = 0;
   982     while (v && i < 7) {
   990     while (v){
   983       // we only deal with the first 7 fields: pobox, extension, street, locality, region, postcode, country.
       
   984       map[addressFields[i]] = QString::fromUtf8(CONST_CHAR(v->data));
   991       map[addressFields[i]] = QString::fromUtf8(CONST_CHAR(v->data));
   985       i++;
   992       i++;
   986       v = v->next;
   993       v = v->next;
   987     }
   994     }
   988     g_list_free(v);
   995     g_list_free(v);
   991     
   998     
   992     rtnList << address;
   999     rtnList << address;
   993   }
  1000   }
   994   
  1001   
   995   g_list_free(attrList);
  1002   g_list_free(attrList);
       
  1003   
   996   return rtnList;
  1004   return rtnList;
   997 }
  1005 }
   998 
  1006 
   999 QContactName* QContactABook::getNameDetail(EContact *eContact) const
  1007 QContactName* QContactABook::getNameDetail(EContact *eContact) const
  1000 {
  1008 {
  1224     return rtn;
  1232     return rtn;
  1225   else
  1233   else
  1226     return QStringList();
  1234     return QStringList();
  1227 }
  1235 }
  1228 
  1236 
  1229 #if 0
  1237 QList<QContactOnlineAccount*> QContactABook::getOnlineAccountDetail(EContact *eContact) const
  1230 // BUG? This code has been commented out because osso_abook_presence_get_presence_status returns empty strings
  1238 {
  1231 static QContactPresence::PresenceState telepathyStatusToPresenceState(const QString& status){
  1239   QList<QContactOnlineAccount*> rtnList;
  1232   if (status == "offline")
  1240   
  1233     return QContactPresence::PresenceOffline;
  1241   // Get VCards that store Online Account Details.
  1234   else if (status == "unknown" || status == "error")
       
  1235     return QContactPresence::PresenceUnknown;
       
  1236   else if (status == "available")
       
  1237     return QContactPresence::PresenceAvailable;
       
  1238   else if (status == "away" || status == "brb" ) //Be Right Back (a more specific form of Away)
       
  1239     return QContactPresence::PresenceAway;
       
  1240   else if (status == "busy" || status == "dnd") //Do Not Disturb (a more specific form of Busy)
       
  1241     return QContactPresence::PresenceBusy;
       
  1242   else if (status == "xa") //Extended Away
       
  1243     return QContactPresence::PresenceExtendedAway;
       
  1244   else if (status == "hidden") // "Invisible" or "Appear Offline"
       
  1245     return QContactPresence::PresenceHidden;
       
  1246 }
       
  1247 #endif
       
  1248 
       
  1249 void QContactABook::getOnlineAccountAndPresenceDetails(EContact *eContact, 
       
  1250                                                       QList<QContactOnlineAccount*>& onlineAccounts,
       
  1251                                                       QList<QContactPresence*>& presences) const
       
  1252 {
       
  1253   const QStringList telepathyVCards = vcardsManagedByTelepathy();
  1242   const QStringList telepathyVCards = vcardsManagedByTelepathy();
  1254   
  1243   
  1255   // Parsing Attributes associated to the Telepathy VCards
  1244   // Parsing Attributes associated to the previous VCards
  1256   GList *attributeList = e_vcard_get_attributes((EVCard*)eContact);
  1245   GList *attributeList = e_vcard_get_attributes((EVCard*)eContact);
  1257   GList *node;
  1246   GList *node;
  1258 
  1247 
  1259   if (!attributeList)
  1248   if (!attributeList)
  1260     return;
  1249     return rtnList;
  1261   
  1250   
  1262   for (node = attributeList; node != NULL; node = g_list_next (node)) {
  1251   for (node = attributeList; node != NULL; node = g_list_next (node)) {
  1263     QContactOnlineAccount* onlineAccount = new QContactOnlineAccount;
  1252     QContactOnlineAccount* rtn = new QContactOnlineAccount;
  1264     QContactPresence* contactPresence = new QContactPresence;
       
  1265     
       
  1266     const char* accountUri = NULL;
  1253     const char* accountUri = NULL;
  1267     const char* serviceProvider = NULL;
  1254     const char* serviceProvider = NULL;
  1268     const char* accountPath = NULL; // Outgoing account path eg: SERVICE_NAME/PROTOCOL_NAME/USER_NAME
  1255     const char* accountPath = NULL; // Outgoing account path eg: SERVICE_NAME/PROTOCOL_NAME/USER_NAME
  1269     EVCardAttribute* attr = NULL;
  1256     
  1270     QVariantMap map;
       
  1271     QString presenceMsg, presenceIcon, presenceDisplayState, presenceNickname;
       
  1272     QStringList caps;
  1257     QStringList caps;
  1273     
  1258     EVCardAttribute* attr = (EVCardAttribute*)node->data;
  1274     attr = (EVCardAttribute*)node->data;
       
  1275     if (!attr)
  1259     if (!attr)
  1276       continue;
  1260       continue;
  1277     
  1261     
  1278     // Continue if the attribute doesn't contain Online Account info
  1262     // Continue if the attribute doesn't contain Online Account info
  1279     QString attributeName = e_vcard_attribute_get_name(attr);
  1263     QString attributeName = e_vcard_attribute_get_name(attr);
  1282     
  1266     
  1283     // Get the account URI
  1267     // Get the account URI
  1284     accountUri = e_vcard_attribute_get_value(attr);
  1268     accountUri = e_vcard_attribute_get_value(attr);
  1285 
  1269 
  1286     // Get AccountPath and service provider for the roster contact associated to the attribute
  1270     // Get AccountPath and service provider for the roster contact associated to the attribute
  1287     // Note: there should be just one roster contact associated to the attribute
       
  1288     GList* rContacts = osso_abook_contact_find_roster_contacts_for_attribute(A_CONTACT(eContact), attr);
  1271     GList* rContacts = osso_abook_contact_find_roster_contacts_for_attribute(A_CONTACT(eContact), attr);
  1289     for (GList * node = rContacts; node != NULL; node = g_list_next(node)){
  1272     for (GList * node = rContacts; node != NULL; node = g_list_next(node)){
  1290       OssoABookContact* c = NULL;
  1273       OssoABookContact* c = NULL;
       
  1274       McAccount* a = NULL;
  1291       c = A_CONTACT(node->data);
  1275       c = A_CONTACT(node->data);
  1292       if (c) {
  1276       if (c) {
  1293        McAccount* a = NULL;
       
  1294        OssoABookPresence *p = NULL;
       
  1295        
       
  1296        a = osso_abook_contact_get_account(c);
  1277        a = osso_abook_contact_get_account(c);
  1297        if (a){
  1278        if (a){
  1298          accountPath = a->name;
  1279          accountPath = a->name;
  1299          serviceProvider = mc_account_compat_get_profile(a);
  1280          serviceProvider = mc_account_compat_get_profile(a);
  1300        }
  1281        }
  1301        
       
  1302        p = OSSO_ABOOK_PRESENCE(c);
       
  1303        presenceMsg = QString::fromUtf8(osso_abook_presence_get_presence_status_message(p));
       
  1304        presenceIcon = QString::fromUtf8(osso_abook_presence_get_icon_name(p));
       
  1305        // presenceState = QString::fromUtf8(osso_abook_presence_get_presence_status(p)); //BUG in osso_abook_presence_get_presence_status??
       
  1306        presenceDisplayState = QString::fromUtf8(osso_abook_presence_get_display_status(p));
       
  1307        presenceNickname = QString::fromUtf8(osso_abook_contact_get_display_name(c));
       
  1308        // Set OnlineAccount details
       
  1309        map.clear();
       
  1310        map[QContactOnlineAccount::FieldAccountUri] = accountUri;
       
  1311        map[QContactOnlineAccount::FieldCapabilities] = serviceProviderCapabilities(serviceProvider);
       
  1312        map[QContactOnlineAccount::FieldServiceProvider] = serviceProvider; // eg: facebook-chat,
       
  1313        map["AccountPath"] = accountPath;
       
  1314        setDetailValues(map, onlineAccount);
       
  1315        onlineAccounts << onlineAccount;
       
  1316     
       
  1317        // Set OnlinePresence details
       
  1318        map.clear();
       
  1319        map[QContactDetail::FieldLinkedDetailUris] = accountUri;
       
  1320        map[QContactPresence::FieldCustomMessage] = presenceMsg;
       
  1321        map[QContactPresence::FieldPresenceStateImageUrl] = presenceIcon;
       
  1322        map[QContactPresence::FieldPresenceStateText] = presenceDisplayState;
       
  1323        map[QContactPresence::FieldNickname] = presenceNickname;
       
  1324        //map[QContactPresence::FieldPresenceState] = telepathyStatusToPresenceState(presenceState);
       
  1325        //map[QContactPresence::FieldTimestamp] = ;
       
  1326        setDetailValues(map, contactPresence);
       
  1327        presences << contactPresence;
       
  1328       }
  1282       }
  1329     }
  1283     }
  1330   }
  1284     
       
  1285     // Set details
       
  1286     QVariantMap map;
       
  1287     map[QContactOnlineAccount::FieldAccountUri] = accountUri;
       
  1288     map[QContactOnlineAccount::FieldCapabilities] = serviceProviderCapabilities(serviceProvider);
       
  1289     map[QContactOnlineAccount::FieldServiceProvider] = serviceProvider; // eg: facebook-chat,
       
  1290     map["AccountPath"] = accountPath;
       
  1291     setDetailValues(map, rtn);
       
  1292     
       
  1293     rtnList << rtn;
       
  1294   }
       
  1295   
       
  1296   return rtnList;
  1331 }
  1297 }
  1332 
  1298 
  1333 QContactOrganization* QContactABook::getOrganizationDetail(EContact *eContact) const
  1299 QContactOrganization* QContactABook::getOrganizationDetail(EContact *eContact) const
  1334 {
  1300 {
  1335   QContactOrganization* rtn = new QContactOrganization;
  1301   QContactOrganization* rtn = new QContactOrganization;
  1383     
  1349     
  1384     rtnList << phoneNumber;
  1350     rtnList << phoneNumber;
  1385   }
  1351   }
  1386   g_list_free(l);
  1352   g_list_free(l);
  1387   
  1353   
       
  1354   return rtnList;
       
  1355 }
       
  1356 
       
  1357 
       
  1358 QList<QContactPresence*> QContactABook::getPresenceDetail(EContact *eContact) const
       
  1359 {
       
  1360   QList<QContactPresence*> rtnList;
       
  1361 
       
  1362   QStringList evcardToSkip = vcardsManagedByTelepathy();
       
  1363 
       
  1364   // Gets info of online accounts from roster contacts associated to the master one
       
  1365   if (!osso_abook_contact_is_roster_contact (A_CONTACT(eContact))) {
       
  1366     QContactPresence* rtn = new QContactPresence;
       
  1367 
       
  1368     GList *contacts = osso_abook_contact_get_roster_contacts(A_CONTACT(eContact));
       
  1369     GList *node;
       
  1370     for (node = contacts; node != NULL; node = g_list_next(node)){
       
  1371       OssoABookContact *rosterContact = A_CONTACT(node->data);
       
  1372 
       
  1373       McProfile* id = osso_abook_contact_get_profile(rosterContact);
       
  1374       McAccount* account = osso_abook_contact_get_account(rosterContact);
       
  1375 
       
  1376       // Avoid to look for Roster contacts into the VCard
       
  1377       QString accountVCard = mc_profile_get_vcard_field(id);
       
  1378       evcardToSkip.removeOne(accountVCard);
       
  1379 
       
  1380       // Presence
       
  1381       OssoABookPresence *presence = OSSO_ABOOK_PRESENCE (rosterContact);
       
  1382       TpConnectionPresenceType presenceType = osso_abook_presence_get_presence_type (presence);
       
  1383       QString presenceTypeString;
       
  1384       QContactPresence::PresenceState presenceTypeEnum;
       
  1385       switch (presenceType) {
       
  1386         case TP_CONNECTION_PRESENCE_TYPE_UNSET: presenceTypeString = "Unset"; presenceTypeEnum = QContactPresence::PresenceUnknown; break;
       
  1387         case TP_CONNECTION_PRESENCE_TYPE_OFFLINE: presenceTypeString = "Offline"; presenceTypeEnum = QContactPresence::PresenceOffline; break;
       
  1388         case TP_CONNECTION_PRESENCE_TYPE_AVAILABLE: presenceTypeString = "Available"; presenceTypeEnum = QContactPresence::PresenceAvailable; break;
       
  1389         case TP_CONNECTION_PRESENCE_TYPE_AWAY: presenceTypeString = "Away"; presenceTypeEnum = QContactPresence::PresenceAway; break;
       
  1390         case TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY: presenceTypeString = "Extended Away"; presenceTypeEnum = QContactPresence::PresenceExtendedAway; break;
       
  1391         case TP_CONNECTION_PRESENCE_TYPE_HIDDEN: presenceTypeString = "Hidden"; presenceTypeEnum = QContactPresence::PresenceHidden; break;
       
  1392         case TP_CONNECTION_PRESENCE_TYPE_BUSY: presenceTypeString = "Busy"; presenceTypeEnum = QContactPresence::PresenceBusy; break;
       
  1393         case TP_CONNECTION_PRESENCE_TYPE_UNKNOWN: presenceTypeString = "Unknown"; presenceTypeEnum = QContactPresence::PresenceUnknown; break;
       
  1394         case TP_CONNECTION_PRESENCE_TYPE_ERROR: presenceTypeString = "Error"; presenceTypeEnum = QContactPresence::PresenceUnknown; break;
       
  1395         default:
       
  1396           qCritical() << "Presence type is not valid" << presenceType;
       
  1397       }
       
  1398 
       
  1399       QVariantMap map; // XXX FIXME
       
  1400       map[QContactPresence::FieldNickname] = osso_abook_contact_get_display_name(rosterContact);
       
  1401       map[QContactPresence::FieldPresenceState] = presenceTypeEnum;
       
  1402       map[QContactPresence::FieldPresenceStateText] = QString::fromUtf8(osso_abook_presence_get_presence_status_message(presence));
       
  1403       map[QContactPresence::FieldLinkedDetailUris] = mc_profile_get_unique_name(id); //use the unique name as a detail uri of the online account.
       
  1404       map["AccountPath"] = account->name; //MCAccount name: variable part of the D-Bus object path.
       
  1405 
       
  1406       setDetailValues(map, rtn);
       
  1407     }
       
  1408     rtnList << rtn;
       
  1409     g_list_free (contacts);
       
  1410   }
       
  1411 
       
  1412   /* Users can add Online account details manually. Eg: IRC username.
       
  1413    * evcardToSkip stringlist contains evCard attributes that have been already processed.
       
  1414    */
       
  1415   GList *attributeList = e_vcard_get_attributes((EVCard*)eContact);
       
  1416   GList *node;
       
  1417 
       
  1418   if (attributeList) {
       
  1419     for (node = attributeList; node != NULL; node = g_list_next (node)) {
       
  1420       EVCardAttribute* attr = (EVCardAttribute*)node->data;
       
  1421       if (!attr)
       
  1422         continue;
       
  1423       QString attributeName = e_vcard_attribute_get_name(attr);
       
  1424 
       
  1425       // Skip attributes processed scanning roster contacts.
       
  1426       if (!evcardToSkip.contains(attributeName))
       
  1427         continue;
       
  1428 
       
  1429       GList *params = e_vcard_attribute_get_params(attr);
       
  1430       GList *nodeP;
       
  1431       QString type;
       
  1432       // If the parameter list lenght is 1, X-OSSO-VALID is not specified
       
  1433       bool ossoValidIsOk = (g_list_length(params) == 1) ? true : false;
       
  1434 
       
  1435       for (nodeP = params; nodeP != NULL; nodeP = g_list_next (nodeP)) {
       
  1436         EVCardAttributeParam* p = (EVCardAttributeParam*) nodeP->data;
       
  1437         QString paramName = e_vcard_attribute_param_get_name(p);
       
  1438         bool attrIsType = false;
       
  1439         bool attrIsOssoValid = false;
       
  1440 
       
  1441         //If type is empty check if the attribute is "TYPE"
       
  1442         if (type.isEmpty())
       
  1443           attrIsType = paramName.contains(EVC_TYPE);
       
  1444 
       
  1445         if(!ossoValidIsOk)
       
  1446           attrIsOssoValid = paramName.contains("X-OSSO-VALID");
       
  1447 
       
  1448         if (!attrIsType && !attrIsOssoValid) {
       
  1449           //qWarning () << "Skipping attribute parameter checking for" << paramName;
       
  1450           continue;
       
  1451         }
       
  1452 
       
  1453         GList *values = e_vcard_attribute_param_get_values(p);
       
  1454         GList *node;
       
  1455         for (node = values; node != NULL; node = g_list_next (node)) {
       
  1456           QString attributeParameterValue = CONST_CHAR(node->data);
       
  1457           if (attrIsOssoValid) {
       
  1458             ossoValidIsOk = (attributeParameterValue == "yes")? true : false;
       
  1459             if (!ossoValidIsOk) {
       
  1460               //qWarning() << "X-OSSO-VALID is false.";
       
  1461               break;
       
  1462             }
       
  1463           } else if (type.isEmpty()) {
       
  1464             type = attributeParameterValue;
       
  1465             if (type.isEmpty())
       
  1466               qCritical() << "TYPE is empty";
       
  1467           }
       
  1468         }
       
  1469 
       
  1470         if (ossoValidIsOk && !type.isEmpty()) {
       
  1471           QContactPresence* rtn = new QContactPresence;
       
  1472           QVariantMap map;
       
  1473           map[QContactPresence::FieldNickname] = QString::fromUtf8(e_vcard_attribute_get_value(attr));
       
  1474           map[QContactPresence::FieldLinkedDetailUris] = type; // XXX FIXME
       
  1475           setDetailValues(map, rtn);
       
  1476           rtnList << rtn;
       
  1477         }
       
  1478       }
       
  1479     }
       
  1480   }
       
  1481 
  1388   return rtnList;
  1482   return rtnList;
  1389 }
  1483 }
  1390 
  1484 
  1391 QContactTimestamp* QContactABook::getTimestampDetail(EContact *eContact) const
  1485 QContactTimestamp* QContactABook::getTimestampDetail(EContact *eContact) const
  1392 {
  1486 {