phonebookui/cntcommonui/contacteditors/cnteditviewlistmodel.cpp
changeset 72 6abfb1094884
child 81 640d30f4fb64
equal deleted inserted replaced
67:59984e68247d 72:6abfb1094884
       
     1 /*
       
     2 * Copyright (c) 2009 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:  
       
    15 *
       
    16 */
       
    17 
       
    18 #include "cnteditviewlistmodel.h"
       
    19 #include "cntextensionmanager.h"
       
    20 #include "cntuiextensionfactory.h"
       
    21 #include "cnteditviewitemsupplier.h"
       
    22 #include "cnteditviewdetailitem.h"
       
    23 #include "cnteditviewitembuilder.h"
       
    24 #include <cntviewparams.h>
       
    25 #include <QDir>
       
    26 
       
    27 CntEditViewListModel::CntEditViewListModel( QContact& aContact, CntExtensionManager& aMgr ) :
       
    28 mManager( aMgr ),
       
    29 mContact( aContact )
       
    30 
       
    31 {
       
    32     mLookupTable.insert( EPhonenumber,    -1 );
       
    33     mLookupTable.insert( EEmailAddress,   -1 );
       
    34     mLookupTable.insert( EAddressTemplate,-1 );
       
    35     mLookupTable.insert( EPluginItem,     -1 );
       
    36     mLookupTable.insert( EUrl,            -1 );
       
    37     mLookupTable.insert( ESeparator,      -1 );
       
    38     mLookupTable.insert( EAddressDetail,  -1 );
       
    39     mLookupTable.insert( ECompany,        -1 );
       
    40     mLookupTable.insert( EDate,           -1 );
       
    41     mLookupTable.insert( ERingingTone,    -1 );
       
    42     mLookupTable.insert( ENote,           -1 );
       
    43     mLookupTable.insert( EFamily,         -1 );
       
    44     mLookupTable.insert( ESynchronization,-1 );
       
    45     
       
    46     mLookupMap.insert( QContactPhoneNumber::DefinitionName,     EPhonenumber );
       
    47     mLookupMap.insert( QContactOnlineAccount::DefinitionName,   EPhonenumber );
       
    48     mLookupMap.insert( QContactEmailAddress::DefinitionName,    EEmailAddress );
       
    49     mLookupMap.insert( QContactAddress::DefinitionName,         EAddressDetail);
       
    50     mLookupMap.insert( QContactUrl::DefinitionName,             EUrl );
       
    51     mLookupMap.insert( QContactOrganization::DefinitionName,    ECompany);
       
    52     mLookupMap.insert( QContactBirthday::DefinitionName,        EDate );
       
    53     mLookupMap.insert( QContactAnniversary::DefinitionName,     EDate);
       
    54     mLookupMap.insert( QContactRingtone::DefinitionName,        ERingingTone);
       
    55     mLookupMap.insert( QContactNote::DefinitionName,            ENote);
       
    56     mLookupMap.insert( QContactFamily::DefinitionName,          EFamily);
       
    57     
       
    58     mBuilder = new CntEditViewItemBuilder();
       
    59     mSeparator = new CntEditViewSeparator();
       
    60     
       
    61     refresh();
       
    62 }
       
    63 
       
    64 CntEditViewListModel::~CntEditViewListModel()
       
    65 {
       
    66     // Delete the separator item separately if it hasn't been added to the list
       
    67     if (mSeparator && mItemList.indexOf(mSeparator) == -1)
       
    68     {
       
    69         delete mSeparator;
       
    70         mSeparator = NULL;
       
    71     }
       
    72     
       
    73     qDeleteAll( mItemList );
       
    74     mItemList.clear();
       
    75     
       
    76     delete mBuilder;
       
    77     mBuilder = NULL;
       
    78 }
       
    79  
       
    80 void CntEditViewListModel::updateRingtone()
       
    81 {
       
    82     beginResetModel();
       
    83     KLookupKey key = mLookupMap.value( QContactRingtone::DefinitionName );
       
    84     int index = mLookupTable.value( key );
       
    85     if ( index != -1 )
       
    86     {
       
    87          // fetch the detail item
       
    88         QContactRingtone ringtone = mContact.detail<QContactRingtone>();
       
    89         QUrl ringtoneUrl = ringtone.audioRingtoneUrl();
       
    90         if ( !ringtoneUrl.isEmpty() )
       
    91         {
       
    92             CntEditViewDetailItem* detailItem = new CntEditViewDetailItem(
       
    93                     ringtone,
       
    94                     QContactRingtone::FieldAudioRingtoneUrl,
       
    95                     ringToneFetcherView);
       
    96             detailItem->addText( hbTrId("txt_phob_formlabel_ringing_tone") );
       
    97             QFileInfo ringtoneFileInfo(ringtoneUrl.toString());
       
    98             QString ringtoneFileName = ringtoneFileInfo.fileName();
       
    99             detailItem->addText( ringtoneFileName); 
       
   100             mItemList.replace(index, detailItem );
       
   101         }
       
   102     }   
       
   103     else
       
   104     {
       
   105         insertDetailItem( key, mBuilder->ringtoneDetails(mContact) );
       
   106     }
       
   107     endResetModel();
       
   108 }
       
   109 
       
   110 int CntEditViewListModel::rowCount( const QModelIndex& aParent ) const
       
   111 {
       
   112     Q_UNUSED( aParent );
       
   113     return mItemList.size();
       
   114 }
       
   115 
       
   116 QVariant CntEditViewListModel::data( const QModelIndex& aIndex, int aRole ) const
       
   117 {
       
   118    if ( aIndex.row() >= 0 && aIndex.row() < mItemList.size() )
       
   119    {
       
   120        CntEditViewItem* item = mItemList.at( aIndex.row() );
       
   121        return item->data( aRole );
       
   122    }
       
   123     return QVariant();
       
   124 }
       
   125 
       
   126 Qt::ItemFlags CntEditViewListModel::flags(const QModelIndex& aIndex) const
       
   127 {
       
   128     CntEditViewItem* item = mItemList.at( aIndex.row() );
       
   129     QVariant data = item->data( Hb::ItemTypeRole );
       
   130     if ( data.toInt() == Hb::SeparatorItem )
       
   131     {
       
   132         return Qt::NoItemFlags;
       
   133     }
       
   134     
       
   135     return QAbstractListModel::flags( aIndex );
       
   136 }
       
   137 
       
   138 CntEditViewItem* CntEditViewListModel::itemAt( const QModelIndex& aIndex ) const
       
   139 {
       
   140     return mItemList.at( aIndex.row() );
       
   141 }
       
   142 
       
   143 void CntEditViewListModel::removeItem( CntEditViewItem* aItem, const QModelIndex& aIndex )
       
   144 {
       
   145     int index = mItemList.indexOf( aItem );
       
   146     if ( index >= 0 )
       
   147     {
       
   148         beginRemoveRows( aIndex.parent(), index, index );
       
   149         // remove item from item list
       
   150         CntEditViewItem* item = mItemList.takeAt( index );
       
   151         
       
   152         // get detailed information
       
   153         QContactDetail detail = item->data(ERoleContactDetail).value<QContactDetail>();
       
   154         QStringList fields = item->data(ERoleContactDetailFields).toStringList();
       
   155         
       
   156         // remove the detail from QContact
       
   157         mBuilder->removeDetail( mContact, detail, fields );
       
   158         
       
   159         // Update lookup table. Note, in case of QContactAddress,
       
   160         // we can't remove address template, so the mapping for address always points to address detail
       
   161         KLookupKey lookupKey = mLookupMap.value( detail.definitionName() );
       
   162         removeItem( lookupKey );
       
   163         
       
   164         delete item;
       
   165         
       
   166         endRemoveRows();
       
   167         
       
   168         // Remove separator item if needed
       
   169         if (mItemList.last()->data( Hb::ItemTypeRole ) == QVariant(Hb::SeparatorItem))
       
   170         {
       
   171             int separatorIndex = mItemList.indexOf( mSeparator );
       
   172             beginRemoveRows( aIndex.parent(), separatorIndex, separatorIndex );
       
   173             mItemList.removeAt( separatorIndex );
       
   174             removeItem( ESeparator  );
       
   175             
       
   176             delete mSeparator;
       
   177             mSeparator = NULL;
       
   178             
       
   179             endRemoveRows();
       
   180         }
       
   181         
       
   182         // Check if the removed item is -1 in lookuptable and if it needs a template
       
   183         int lookupValue = mLookupTable.value( lookupKey );
       
   184         if ( lookupValue == -1 )
       
   185         {
       
   186             if ( detail.definitionName() == QContactPhoneNumber::DefinitionName )
       
   187             {
       
   188                 beginInsertRows(aIndex.parent(), index, index);
       
   189                 insertItem( EPhonenumber, mBuilder->phoneNumberItems(mContact) );
       
   190                 endInsertRows();
       
   191             }
       
   192             else if ( detail.definitionName() == QContactEmailAddress::DefinitionName )
       
   193             {
       
   194                 beginInsertRows(aIndex.parent(), index, index);
       
   195                 insertItem( EEmailAddress, mBuilder->emailAddressItems(mContact) );
       
   196                 endInsertRows();
       
   197             }
       
   198             else if ( detail.definitionName() == QContactAddress::DefinitionName )
       
   199             {
       
   200                 // special case: unlike the others, address template isn't in the same index as the last deleted detail
       
   201                 int emailIndex = mLookupTable.value( EEmailAddress );
       
   202                 beginInsertRows(aIndex.parent(), emailIndex + 1, emailIndex + 1);
       
   203                 insertItem( EAddressTemplate, mBuilder->addressItems(mContact) );
       
   204                 endInsertRows();
       
   205             }
       
   206             else if ( detail.definitionName() == QContactUrl::DefinitionName )
       
   207             {
       
   208                 beginInsertRows(aIndex.parent(), index, index);
       
   209                 insertItem( EUrl, mBuilder->urlItems(mContact) );
       
   210                 endInsertRows();
       
   211             }
       
   212         }
       
   213     }
       
   214 }
       
   215 
       
   216 void CntEditViewListModel::refreshExtensionItems()
       
   217 {
       
   218     // remove and delete all extension items
       
   219     for( int i(mItemList.count()-1); i >= 0; i-- )
       
   220     {
       
   221         CntEditViewItem* item = mItemList.at( i );
       
   222         if ( item->data(ERoleItemType) == QVariant(ETypeUiExtension) )
       
   223         {
       
   224             QModelIndex modelIndex = createIndex(i, 0);
       
   225             beginRemoveRows( modelIndex.parent(), i, i );
       
   226             mItemList.removeAt(i);
       
   227             removeItem( EPluginItem );
       
   228             
       
   229             delete item;
       
   230             endRemoveRows();
       
   231         }
       
   232     }
       
   233     // query and reload extension items again
       
   234     int count = mManager.pluginCount();
       
   235     for ( int i(0); i < count; i++ )
       
   236     {
       
   237         CntUiExtensionFactory* factory = mManager.pluginAt(i);
       
   238         CntEditViewItemSupplier* supplier = factory->editViewItemSupplier( mContact );
       
   239         if (supplier)
       
   240         {
       
   241             loadPluginItems( supplier );
       
   242         }
       
   243     }
       
   244 }
       
   245 
       
   246 void CntEditViewListModel::allInUseFields( CntViewIdList& aList )
       
   247 {
       
   248     foreach ( KLookupKey key, mLookupTable.keys() )
       
   249     {
       
   250         int index = mLookupTable.value( key );
       
   251         if ( index != -1 )
       
   252         {
       
   253             switch (key)
       
   254             {
       
   255                 case EAddressDetail:
       
   256                 {
       
   257                     // Considered to be in use if all address contexts have been added
       
   258                     QList<QContactAddress> addrList = mContact.details<QContactAddress>();
       
   259                     if ( addrList.count() >= 3 ) // no context, context home, context work
       
   260                         aList.append( addressEditorView );
       
   261                 }
       
   262                 break;
       
   263                 
       
   264                 case ECompany:
       
   265                 {
       
   266                     // Considered in use if some details and assistant exists
       
   267                     QContactOrganization org = mContact.detail( QContactOrganization::DefinitionName );
       
   268                     if ( !org.assistantName().isEmpty() && 
       
   269                         (!org.name().isEmpty() || !org.department().isEmpty() || !org.title().isEmpty()) )
       
   270                         aList.append( companyEditorView );
       
   271                 }
       
   272                 break;
       
   273                 
       
   274                 case EDate:
       
   275                 {
       
   276                     QContactBirthday bd = mContact.detail( QContactBirthday::DefinitionName );
       
   277                     QContactAnniversary anniversary = mContact.detail( QContactAnniversary::DefinitionName );
       
   278                     // considered as in use when both birthday and anniversary has a valid date
       
   279                     if ( bd.date().isValid() && anniversary.originalDate().isValid() )
       
   280                         aList.append( dateEditorView );
       
   281                 }
       
   282                 break;
       
   283                     
       
   284                 case EFamily:
       
   285                 {
       
   286                     QContactFamily family = mContact.detail( QContactFamily::DefinitionName );
       
   287                     if ( !family.children().isEmpty() && !family.spouse().isEmpty() )
       
   288                         aList.append( familyDetailEditorView );
       
   289                 }
       
   290                 break;
       
   291                 
       
   292                 case ERingingTone:
       
   293                 {
       
   294                     
       
   295                     QContactRingtone tone = mContact.detail( QContactRingtone::DefinitionName );
       
   296                     if ( !tone.audioRingtoneUrl().isEmpty() )
       
   297                         aList.append( ringToneFetcherView );
       
   298                     
       
   299                 }
       
   300                 break;
       
   301                 
       
   302                 default:
       
   303                     break;
       
   304             }
       
   305         }
       
   306     }
       
   307 }
       
   308 
       
   309 QModelIndex CntEditViewListModel::itemIndex( QContactDetail aDetail ) const
       
   310 {
       
   311     QModelIndex itemIndex;
       
   312     for ( int i(0); i < mItemList.count(); i++ ) {
       
   313         CntEditViewItem* item = mItemList.at( i );
       
   314         QVariant data = item->data( ERoleContactDetail );
       
   315         if ( data.value<QContactDetail>() == aDetail )
       
   316         {
       
   317             itemIndex = index( i ); 
       
   318             break;
       
   319         }
       
   320     }
       
   321     return itemIndex;
       
   322 }
       
   323 
       
   324 void CntEditViewListModel::refresh()
       
   325 {
       
   326     insertItem( EPhonenumber, mBuilder->phoneNumberItems(mContact) );
       
   327     insertItem( EEmailAddress, mBuilder->emailAddressItems(mContact) );
       
   328     insertItem( EAddressTemplate, mBuilder->addressItems(mContact) );
       
   329     insertItem( EUrl, mBuilder->urlItems(mContact) );
       
   330         
       
   331     int count = mManager.pluginCount();
       
   332     for ( int i(0); i < count; i++ )
       
   333     {
       
   334         CntUiExtensionFactory* factory = mManager.pluginAt(i);
       
   335         CntEditViewItemSupplier* supplier = factory->editViewItemSupplier( mContact );
       
   336         if (supplier)
       
   337         {
       
   338             loadPluginItems( supplier );
       
   339         }
       
   340     }
       
   341         
       
   342     insertDetailItem( EAddressDetail, mBuilder->addressDetails(mContact) );
       
   343     insertDetailItem( ECompany, mBuilder->companyDetails(mContact) );
       
   344     insertDetailItem( EDate, mBuilder->dateDetails(mContact) );
       
   345     insertDetailItem( ENote, mBuilder->noteDetails(mContact) );
       
   346     insertDetailItem( EFamily, mBuilder->familyDetails(mContact) );
       
   347     insertDetailItem( ERingingTone, mBuilder->ringtoneDetails(mContact) );
       
   348 }
       
   349 
       
   350 bool CntEditViewListModel::isEmptyItem( CntEditViewItem* aItem )
       
   351 {
       
   352     if ( aItem )
       
   353     {
       
   354         QContactDetail d = aItem->data( ERoleContactDetail ).value<QContactDetail>();
       
   355         QStringList fields = aItem->data( ERoleContactDetailFields ).toStringList();
       
   356         
       
   357         foreach ( QString field, fields )
       
   358         {
       
   359             if ( !d.value(field).isEmpty() || !d.value<QStringList>(field).isEmpty() )
       
   360             {
       
   361                 return false;
       
   362             }
       
   363         }
       
   364     }
       
   365     return true;
       
   366 }
       
   367 
       
   368 void CntEditViewListModel::loadPluginItems( CntEditViewItemSupplier* aSupplier )
       
   369 {
       
   370     QList<CntEditViewItem*> list;
       
   371     int count = aSupplier->itemCount();
       
   372     for ( int i(0); i < count; i++ )
       
   373     {
       
   374         CntEditViewItem* item = aSupplier->itemAt( i );
       
   375         if ( item )
       
   376         {
       
   377             list << item;
       
   378         }
       
   379     }
       
   380     
       
   381     if ( !list.isEmpty() )
       
   382     {
       
   383         // the new items will be inserted under already existing plugin items...
       
   384         int index = mLookupTable.value( EPluginItem );
       
   385         
       
   386         // ... or under the address template (if no plugins exist)
       
   387         if (index == -1)
       
   388         {
       
   389             index = mLookupTable.value( EAddressTemplate );
       
   390         }
       
   391         
       
   392         // ... or as a final choice, under the email address items (if address template doesn't exist)
       
   393         if (index == -1)
       
   394         {
       
   395             index = mLookupTable.value( EEmailAddress );
       
   396         }
       
   397         QModelIndex modelIndex = createIndex(index, 0);
       
   398         beginInsertRows(modelIndex.parent(), index + 1, index + count);
       
   399         insertItem( EPluginItem, list );
       
   400         endInsertRows();
       
   401     }
       
   402 }
       
   403 
       
   404 void CntEditViewListModel::insertDetailItem( KLookupKey aKey, QList<CntEditViewItem*> aList )
       
   405 {
       
   406     if ( !aList.isEmpty() )
       
   407     {
       
   408         insertSeparator();
       
   409         insertItem( aKey, aList );
       
   410     }
       
   411 }
       
   412 
       
   413 void CntEditViewListModel::insertItem( KLookupKey aLookupKey, QList<CntEditViewItem*> aList )
       
   414 {
       
   415     if ( !aList.isEmpty() )
       
   416     {
       
   417         QList<KLookupKey> keys = mLookupTable.keys();
       
   418         int ind = keys.indexOf( aLookupKey );
       
   419         for ( int i=ind; i >= 0; i-- )
       
   420         {
       
   421             KLookupKey key = keys.at( i );
       
   422             int lastIndexValue = mLookupTable.value( key );
       
   423             // search next suitable "lastindex" where to insert the items
       
   424             if ( i != 0 && lastIndexValue == -1 )
       
   425                 continue;
       
   426                    
       
   427             // insert items to current index
       
   428             for ( int j(0); j < aList.count(); j++ )
       
   429             {
       
   430                 mItemList.insert( lastIndexValue + j + 1, aList[j] );
       
   431             }
       
   432                    
       
   433             // lookup keys value "lastindex"
       
   434             int listCount = aList.count();
       
   435             lastIndexValue = lastIndexValue + listCount;
       
   436             mLookupTable.insert( aLookupKey, lastIndexValue );
       
   437             // update all indexes in lookuptable 
       
   438             for ( int k(ind+1); k < keys.size(); k++ )
       
   439             {
       
   440                 int value = mLookupTable.value(keys[k]);
       
   441                 if ( value != -1 )
       
   442                 {
       
   443                     mLookupTable.insert( keys[k], value + aList.count() );
       
   444                 }
       
   445             }
       
   446             break;
       
   447         }
       
   448     }
       
   449 }
       
   450 
       
   451 void CntEditViewListModel::removeItem( KLookupKey aKey )
       
   452 {
       
   453     QList<KLookupKey> keys = mLookupTable.keys();
       
   454     int ind = keys.indexOf( aKey );
       
   455     for ( int i(ind); i < keys.count(); i++ )
       
   456     {
       
   457         KLookupKey key = keys.at( i );
       
   458         int lastIndexValue = mLookupTable.value( key ) - 1;
       
   459         
       
   460         // climb the keys (bottom to top) and see if somebody has the same value (then set value to -1)
       
   461         for ( int j(ind); j >= 0; j-- )
       
   462         {
       
   463             if ( mLookupTable.value(keys[j]) == lastIndexValue )
       
   464             {
       
   465                 lastIndexValue = -1;
       
   466                 break;
       
   467             }
       
   468         }
       
   469         
       
   470         mLookupTable.insert( key, lastIndexValue );
       
   471         // update rest of the keys by reducing one (top to bottom)
       
   472         for ( int k(ind+1); k < keys.count(); k++ )
       
   473         {
       
   474             KLookupKey tmp = keys.at( k );
       
   475             int value = mLookupTable.value( tmp );
       
   476             if ( value != -1 )
       
   477             {
       
   478                 mLookupTable.insert( tmp, value - 1 );
       
   479             }
       
   480         }
       
   481         
       
   482         break;
       
   483     }
       
   484 }
       
   485 
       
   486 void CntEditViewListModel::insertSeparator()
       
   487 {
       
   488     if ( mItemList.indexOf(mSeparator) == -1 )
       
   489     {
       
   490         QList<CntEditViewItem*> list;
       
   491         if (!mSeparator)
       
   492         {
       
   493             mSeparator = new CntEditViewSeparator();
       
   494         }
       
   495         list << mSeparator;
       
   496         insertItem( ESeparator, list );
       
   497     }
       
   498 }
       
   499 
       
   500 // End of File