plugins/contacts/symbian/plugin/src/cntrelationship.cpp
changeset 0 876b1a06bc25
child 5 603d3f8b6302
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtCore module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <cntitem.h>
       
    43 
       
    44 #include "cntrelationship.h"
       
    45 #include "cntsymbiantransformerror.h"
       
    46 
       
    47 /* ... The macros changed names */
       
    48 #if QT_VERSION < QT_VERSION_CHECK(4, 6, 0)
       
    49 #define QT_TRAP_THROWING QT_TRANSLATE_SYMBIAN_LEAVE_TO_EXCEPTION
       
    50 #define QT_TRYCATCH_LEAVING QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE
       
    51 #endif
       
    52 
       
    53 /*!
       
    54  * Constructor
       
    55  *
       
    56  * \a contactDatabase CContactDatabase with established connection to the database
       
    57  * \a managerUri current manager uri
       
    58  */
       
    59 CntRelationship::CntRelationship(CContactDatabase* contactDatabase, const QString &managerUri)
       
    60     :m_contactDatabase(contactDatabase),
       
    61     m_managerUri(managerUri)
       
    62 {
       
    63     CntAbstractRelationship *relationshipGroup = new CntRelationshipGroup(contactDatabase, managerUri);
       
    64     m_relationshipMap.insert(relationshipGroup->relationshipType(), relationshipGroup);
       
    65 }
       
    66 
       
    67 /*!
       
    68  * Destructor
       
    69  */
       
    70 CntRelationship::~CntRelationship()
       
    71 {
       
    72     QMap<QString, CntAbstractRelationship *>::iterator itr;
       
    73 
       
    74     /* XXX maybe use qDeleteAll? */
       
    75     for (itr = m_relationshipMap.begin(); itr != m_relationshipMap.end(); ++itr)
       
    76     {
       
    77         CntAbstractRelationship* value = itr.value();
       
    78         delete value;
       
    79         value = 0;
       
    80     }
       
    81 }
       
    82 
       
    83 /*!
       
    84  * \return whether relationships of type \a relationshipType is supported by contacts of \a contactType
       
    85  */
       
    86 bool CntRelationship::isRelationshipTypeSupported(const QString &relationshipType, const QString &contactType) const
       
    87 {
       
    88     Q_UNUSED(contactType);
       
    89     return m_relationshipMap.contains(relationshipType);
       
    90 
       
    91     /* XXX Old code:
       
    92     QStringList supportedTypes;
       
    93 
       
    94     foreach(const QString& type, m_relationshipMap.keys()) {
       
    95         supportedTypes.append(type);
       
    96     }
       
    97     return supportedTypes;
       
    98     */
       
    99 }
       
   100 
       
   101 /* !
       
   102  * Retrive the contacts relationships
       
   103  *
       
   104  * \a relationshipType The type of the relationship
       
   105  * \a participantId The contact id
       
   106  * \a role The contact role
       
   107  * \a error Error returned
       
   108  */
       
   109 QList<QContactRelationship> CntRelationship::relationships(const QString& relationshipType, const QContactId& participantId, QContactRelationship::Role role, QContactManager::Error* error) const
       
   110 {
       
   111     QList<QContactRelationship> returnValue;
       
   112     *error = QContactManager::NoError;
       
   113 
       
   114     // if relationshipType is empty, relationships of any type are returned.
       
   115     if (relationshipType.isEmpty())
       
   116     {
       
   117         foreach (const QString& type, m_relationshipMap.keys())
       
   118         {
       
   119             // get the relationship
       
   120             CntAbstractRelationship *abstractRelationship = m_relationshipMap.value(type);
       
   121 
       
   122             // retrieve the relationships
       
   123             TRAPD(symbianError, returnValue.append(abstractRelationship->relationshipsL(participantId, role, error)));
       
   124 
       
   125             // if error translate it into a qt error
       
   126             if (symbianError != KErrNone){
       
   127                 CntSymbianTransformError::transformError(symbianError, error);
       
   128             }
       
   129             
       
   130             // return empty list if there was an error
       
   131             if (*error != QContactManager::NoError && *error != QContactManager::DoesNotExistError) {
       
   132                 return QList<QContactRelationship>();
       
   133             }
       
   134         }
       
   135         // if relationships found, update error
       
   136         if (!returnValue.isEmpty() && *error == QContactManager::DoesNotExistError) {
       
   137             // this can be the case if nothing is found for last relationship type
       
   138             *error = QContactManager::NoError;
       
   139         }
       
   140     }
       
   141     //check if we support the relationship
       
   142     else if (m_relationshipMap.contains(relationshipType))
       
   143     {
       
   144         //get the relationship
       
   145         CntAbstractRelationship *abstractRelationship = m_relationshipMap.value(relationshipType);
       
   146 
       
   147         //retrieve the relationships
       
   148         TRAPD(symbianError, returnValue = abstractRelationship->relationshipsL(participantId, role, error));
       
   149 
       
   150         //if error translate it into a qt error
       
   151         if (symbianError != KErrNone){
       
   152             CntSymbianTransformError::transformError(symbianError, error);
       
   153         }
       
   154     }
       
   155     else{
       
   156         *error = QContactManager::NotSupportedError;
       
   157     }
       
   158     
       
   159     // No relationships found?
       
   160     if (*error == QContactManager::NoError && returnValue.count() == 0 ) {
       
   161         *error = QContactManager::DoesNotExistError;
       
   162     }
       
   163 
       
   164     return returnValue;
       
   165 }
       
   166 
       
   167 /* !
       
   168  * Save the relationship
       
   169  *
       
   170  * \a affectedContactIds will include the affected contact ids
       
   171  * \a relationship to be saved
       
   172  * \a error Error returned
       
   173  */
       
   174 bool CntRelationship::saveRelationship(QSet<QContactLocalId> *affectedContactIds, QContactRelationship* relationship, QContactManager::Error* error)
       
   175 {
       
   176     bool returnValue(false);
       
   177     *error = QContactManager::NoError;
       
   178     if (validateRelationship(*relationship, error))
       
   179     {
       
   180         // Update manager uri to this manager if it is empty
       
   181         if (relationship->second().managerUri().isEmpty()) {
       
   182             QContactId second = relationship->second();
       
   183             second.setManagerUri(m_managerUri);
       
   184             relationship->setSecond(second);
       
   185         }
       
   186         
       
   187         //get the relationship
       
   188         CntAbstractRelationship *abstractRelationship = m_relationshipMap.value(relationship->relationshipType());
       
   189     
       
   190         //save the relationship
       
   191         TRAPD(symbianError, returnValue = abstractRelationship->saveRelationshipL(affectedContactIds, relationship, error));
       
   192     
       
   193         //if symbian error translate it into a qt error
       
   194         if (symbianError != KErrNone){
       
   195             returnValue = false;
       
   196             CntSymbianTransformError::transformError(symbianError, error);
       
   197         }
       
   198     }
       
   199     return returnValue;
       
   200 }
       
   201 
       
   202 /* !
       
   203  * Save many relationships
       
   204  *
       
   205  * \a affectedContactIds will include the affected contact ids
       
   206  * \a relationships to be saved
       
   207  * \a errorMap storage place for errors
       
   208  * \return true if there were no errors saving
       
   209  */
       
   210 bool CntRelationship::saveRelationships(QSet<QContactLocalId> *affectedContactIds, QList<QContactRelationship>* relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
       
   211 {
       
   212     QContactManager::Error singleError;    
       
   213     bool returnValue(true);
       
   214 
       
   215     *error = QContactManager::NoError;
       
   216 
       
   217     // loop through the relationships
       
   218     for (int i = 0; i < relationships->count(); i++)
       
   219     {
       
   220         // save the relationship
       
   221         saveRelationship(affectedContactIds, &(relationships->operator[](i)), &singleError);
       
   222         if (errorMap && singleError != QContactManager::NoError) {
       
   223             errorMap->insert(i, singleError);
       
   224         }
       
   225         
       
   226         // update the total error
       
   227         if (singleError != QContactManager::NoError) {
       
   228             *error = singleError;
       
   229             returnValue = false;
       
   230         }
       
   231 
       
   232     }
       
   233 
       
   234     return returnValue;
       
   235 }
       
   236 
       
   237 /* !
       
   238  * Remove the relationship
       
   239  *
       
   240  * \a affectedContactIds will include the affected contact ids
       
   241  * \a relationship to be removed
       
   242  * \a error Error returned
       
   243  * \return true if no error otherwise false
       
   244  */
       
   245 bool CntRelationship::removeRelationship(QSet<QContactLocalId> *affectedContactIds, const QContactRelationship &relationship, QContactManager::Error* error)
       
   246 {
       
   247     bool returnValue(false);
       
   248     *error = QContactManager::NoError;
       
   249     if (validateRelationship(relationship, error))
       
   250     {
       
   251         //get the relationship
       
   252         CntAbstractRelationship *abstractRelationship = m_relationshipMap.value(relationship.relationshipType());
       
   253 
       
   254         TRAPD(symbianError, returnValue = abstractRelationship->removeRelationshipL(affectedContactIds, relationship, error));
       
   255 
       
   256         //if symbian error translate it into a qt error
       
   257         if (symbianError != KErrNone){
       
   258             returnValue = false;
       
   259             CntSymbianTransformError::transformError(symbianError, error);
       
   260         }
       
   261     }
       
   262     return returnValue;
       
   263 }
       
   264 
       
   265 /* !
       
   266  * Remove many relationships
       
   267  *
       
   268  * \a affectedContactIds will include the affected contact ids
       
   269  * \a relationships to be removed
       
   270  * \a errorMap storage place for errors
       
   271  * \return true if there were no errors removing, false otherwise
       
   272  */
       
   273 bool CntRelationship::removeRelationships(QSet<QContactLocalId> *affectedContactIds, const QList<QContactRelationship>& relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error)
       
   274 {
       
   275     bool returnValue(true);
       
   276     *error = QContactManager::NoError;
       
   277     QContactManager::Error qtError(QContactManager::NoError);
       
   278 
       
   279     //loop through the relationships
       
   280     for(int i = 0; i < relationships.count(); i++)
       
   281     {
       
   282         //remove the relationships
       
   283         removeRelationship(affectedContactIds, relationships.at(i), &qtError);
       
   284         if (errorMap && qtError != QContactManager::NoError)
       
   285             errorMap->insert(i, qtError);
       
   286         
       
   287         // update the total error
       
   288         if (qtError != QContactManager::NoError) {
       
   289             returnValue = false;
       
   290             *error = qtError;
       
   291         }
       
   292     }
       
   293     return returnValue;
       
   294 }
       
   295 
       
   296 bool CntRelationship::validateRelationship(const QContactRelationship &relationship, QContactManager::Error* error)
       
   297 {
       
   298     *error = QContactManager::NoError;
       
   299     
       
   300     // check if supported in this manager
       
   301     if (!m_relationshipMap.contains(relationship.relationshipType())) {
       
   302         *error = QContactManager::NotSupportedError;
       
   303         return false;
       
   304     }
       
   305     
       
   306     QContactId first = relationship.first();
       
   307     QContactId second = relationship.second();    
       
   308     
       
   309     // zero id contacts not accepted
       
   310     if (!(first.localId() && second.localId())) {
       
   311         *error = QContactManager::InvalidRelationshipError;
       
   312         return false;
       
   313     }
       
   314     
       
   315     // "first" must be a contact in this manager
       
   316     if (!first.managerUri().isEmpty() && first.managerUri() != m_managerUri) {
       
   317         *error = QContactManager::InvalidRelationshipError;
       
   318         return false;
       
   319     }
       
   320 
       
   321     // "first" must be found in the database
       
   322     CContactItem* contact = 0;
       
   323     TRAP_IGNORE(contact = m_contactDatabase->ReadContactL(first.localId()));
       
   324     if (!contact) {
       
   325         *error = QContactManager::InvalidRelationshipError;
       
   326         return false;
       
   327     }
       
   328     delete contact;
       
   329     
       
   330     // check if "second" is in this manager 
       
   331     if (second.managerUri().isEmpty() || second.managerUri() == m_managerUri)
       
   332     {
       
   333         // circular relationships not allowed
       
   334         if (first.localId() == second.localId()) {
       
   335             *error = QContactManager::InvalidRelationshipError;
       
   336             return false;
       
   337         }
       
   338     
       
   339         // "second" must be found in the database
       
   340         contact = 0;
       
   341         TRAP_IGNORE(contact = m_contactDatabase->ReadContactL(second.localId()));
       
   342         if (!contact) {
       
   343             *error = QContactManager::InvalidRelationshipError;
       
   344             return false;
       
   345         }
       
   346         delete contact;        
       
   347     }
       
   348     
       
   349     // do additional checks in the actual implementation
       
   350     CntAbstractRelationship *abstractRelationship = m_relationshipMap.value(relationship.relationshipType());
       
   351     return abstractRelationship->validateRelationship(relationship, error);
       
   352 }