contentstorage/caclient/src/caitemmodel.cpp
changeset 60 f62f87b200ec
child 61 8e5041d13c84
equal deleted inserted replaced
4:1a2a00e78665 60:f62f87b200ec
       
     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: caitemmodel.cpp
       
    15  *
       
    16  */
       
    17 
       
    18 #include <HbIcon>
       
    19 
       
    20 #include "caitemmodel.h"
       
    21 #include "caitemmodel_p.h"
       
    22 #include "canotifier.h"
       
    23 #include "canotifierfilter.h"
       
    24 #include "caclienttest_global.h"
       
    25 
       
    26 // Constants
       
    27 const QSize defaultIconSize(30, 30);
       
    28 
       
    29 // ======== MEMBER FUNCTIONS ========
       
    30 
       
    31 /*!
       
    32  *   \class CaItemModel
       
    33  *
       
    34  *   \brief This class provides model containing CaEntry class objects.
       
    35  *
       
    36  *   To create instance of CaItemModel object, you need to pass CaQuery
       
    37  *   object in constructor. CaQuery should describe items that you want
       
    38  *   to have in a model.
       
    39  *
       
    40  *   \example
       
    41  *   \code
       
    42  *
       
    43  *   CaQuery query;
       
    44  *   query.setFlagsOn(VisibleEntryFlag);
       
    45  *   query.setParentId(collectionId);
       
    46  *   CaItemModel* model = new CaItemModel(query, this);
       
    47  *
       
    48  *   \endcode
       
    49  */
       
    50 
       
    51 /*!
       
    52  Constructor.
       
    53  \param query query describing entries that should be present in a model.
       
    54  \param parent parent of a model
       
    55  */
       
    56 CaItemModel::CaItemModel(const CaQuery &query, QObject *parent) :
       
    57     QAbstractItemModel(parent), m_d(new CaItemModelPrivate(query, this))
       
    58 {
       
    59 
       
    60 }
       
    61 
       
    62 /*!
       
    63  Destructor
       
    64  */
       
    65 CaItemModel::~CaItemModel()
       
    66 {
       
    67     delete m_d;
       
    68 }
       
    69 
       
    70 /*!
       
    71  Returns number of columns
       
    72  \param parent not used
       
    73  \retval 1
       
    74 
       
    75  \code
       
    76  ...
       
    77  // to get number of columns in a model
       
    78  int columns = model->columnCount();
       
    79  ...
       
    80  \endcode
       
    81 
       
    82  */
       
    83 int CaItemModel::columnCount(const QModelIndex &parent) const
       
    84 {
       
    85     Q_UNUSED(parent);
       
    86     //model keeps entries in a column 0 and a parent entry in a column 1
       
    87     //parent entry is treated as an invisible root item,
       
    88     //so column count is always 1
       
    89     return 1;
       
    90 }
       
    91 
       
    92 /*!
       
    93  Returns number of rows
       
    94  \param parent not used
       
    95  \retval number of rows
       
    96 
       
    97  \code
       
    98  ...
       
    99  // to get number of rows in a model
       
   100  int rows = model->rowCount();
       
   101  ...
       
   102  \endcode
       
   103  */
       
   104 int CaItemModel::rowCount(const QModelIndex &parent) const
       
   105 {
       
   106     Q_UNUSED(parent);
       
   107     return m_d->rowCount();
       
   108 }
       
   109 
       
   110 /*!
       
   111  Returns QModelIndex of an item
       
   112  \param row row in which an item is placed
       
   113  \param column not used
       
   114  \param parent not used
       
   115  \retval index of item in model
       
   116 
       
   117  \code
       
   118  ...
       
   119  // to get model index of an item
       
   120  QModelIndex modelIndex = model->index(5);
       
   121  ...
       
   122  \endcode
       
   123 
       
   124  */
       
   125 QModelIndex CaItemModel::index(int row, int column,
       
   126                                const QModelIndex &parent) const
       
   127 {
       
   128     Q_UNUSED(column);
       
   129     Q_UNUSED(parent);
       
   130     return m_d->index(row);
       
   131 }
       
   132 
       
   133 /*!
       
   134  Returns parent item
       
   135  \param child index (ignored)
       
   136  \retval parent index. in case of CaItemModel it is always QModelIndex()
       
   137 
       
   138  \code
       
   139  ...
       
   140  // to get model index of a parent of an item
       
   141  QModelIndex parentModelIndex = model->parent(childModelIndex);
       
   142  ...
       
   143  \endcode
       
   144  */
       
   145 QModelIndex CaItemModel::parent(const QModelIndex &index) const
       
   146 {
       
   147     Q_UNUSED(index);
       
   148     return QModelIndex();
       
   149 }
       
   150 
       
   151 /*!
       
   152  Returns root item model index
       
   153  \retval root item model index
       
   154 
       
   155  \code
       
   156  ...
       
   157  // to get model index of a root item
       
   158  QModelIndex rootIndex = model->root();
       
   159  ...
       
   160  \endcode
       
   161  */
       
   162 QModelIndex CaItemModel::root() const
       
   163 {
       
   164     return m_d->root();
       
   165 }
       
   166 
       
   167 /*!
       
   168  Returns appropiate model's data
       
   169  \param index model index
       
   170  \param role which data role to return
       
   171  \retval models data
       
   172 
       
   173  \code
       
   174  ...
       
   175  // to get data for model item
       
   176  QVariant = model->data(itemModelIndex, Qt::DisplayRole);
       
   177  ...
       
   178  \endcode
       
   179 
       
   180  */
       
   181 QVariant CaItemModel::data(const QModelIndex &index, int role) const
       
   182 {
       
   183     return m_d->data(index, role);
       
   184 }
       
   185 
       
   186 /*!
       
   187  Disables or enables auto-update feature of the model
       
   188  \param autoUpdate true to enable autoupdate, false to disable
       
   189 
       
   190  \code
       
   191  ...
       
   192  // to enable model auto update
       
   193  model->setAutoUpdate(true);
       
   194  ...
       
   195  \endcode
       
   196 
       
   197  */
       
   198 void CaItemModel::setAutoUpdate(bool autoUpdate)
       
   199 {
       
   200     m_d->setAutoUpdate(autoUpdate);
       
   201 }
       
   202 
       
   203 /*!
       
   204  Disables or enables secondline feature of the model
       
   205  \param secondLine enable or disable second line
       
   206 
       
   207  \code
       
   208  ...
       
   209  // to enable model second line visibility
       
   210  model->setSecondLineVisibility(true);
       
   211  ...
       
   212  \endcode
       
   213 
       
   214  */
       
   215 void CaItemModel::setSecondLineVisibility(bool secondLineVisible)
       
   216 {
       
   217     m_d->setSecondLineVisibility(secondLineVisible);
       
   218 }
       
   219 
       
   220 /*!
       
   221  Gets second line visibility attribute
       
   222  \retrun second line visibility attribute
       
   223 
       
   224  \code
       
   225  ...
       
   226  // to check second line visibility attribute
       
   227  bool visibility = model->secondLineVisibility();
       
   228  ...
       
   229  \endcode
       
   230 
       
   231  */
       
   232 bool CaItemModel::secondLineVisibility() const
       
   233 {
       
   234     return m_d->secondLineVisibility();
       
   235 }
       
   236 /*!
       
   237  Returns auto update status
       
   238  \retval true if autoupdate is on, false if not
       
   239 
       
   240  \code
       
   241  ...
       
   242  // to check auto update attribute
       
   243  bool autoUpdate = model->isAutoUpdate();
       
   244  ...
       
   245  \endcode
       
   246 
       
   247  */
       
   248 bool CaItemModel::isAutoUpdate() const
       
   249 {
       
   250     return m_d->notifierExists();
       
   251 }
       
   252 
       
   253 /*!
       
   254  Method for setting sorting order on model
       
   255  \param sortAttribute sort attribute (by name, timestamp, ect...)
       
   256  \param sortOrder sort order (ascending, descending)
       
   257 
       
   258  \code
       
   259  ...
       
   260  // to set sort order in a model
       
   261  model->setSort(NameSortAttribute, Qt::Ascending);
       
   262  ...
       
   263  \endcode
       
   264 
       
   265  */
       
   266 void CaItemModel::setSort(SortAttribute sortAttribute,
       
   267                           Qt::SortOrder sortOrder)
       
   268 {
       
   269     m_d->setSort(sortAttribute, sortOrder);
       
   270 }
       
   271 
       
   272 /*!
       
   273  Method for setting icon size
       
   274  \param  size icon size to display
       
   275 
       
   276  \code
       
   277  ...
       
   278  // to set an icon size in a model
       
   279  QSize iconSize(50,50);
       
   280  model->setIconSize(iconSize);
       
   281  ...
       
   282  \endcode
       
   283 
       
   284  */
       
   285 void CaItemModel::setIconSize(const QSize &size)
       
   286 {
       
   287     m_d->setIconSize(size);
       
   288 }
       
   289 
       
   290 /*!
       
   291  Method for getting icon size
       
   292  \param  size icon size to display
       
   293  */
       
   294 QSize CaItemModel::getIconSize() const
       
   295 {
       
   296     return m_d->getIconSize();
       
   297 }
       
   298 
       
   299 /*!
       
   300  Updates model with fresh entries
       
   301 
       
   302  \code
       
   303  ...
       
   304  // to refresh a model
       
   305  model->updateModel();
       
   306  ...
       
   307  \endcode
       
   308 
       
   309  */
       
   310 void CaItemModel::updateModel()
       
   311 {
       
   312     m_d->updateModel();
       
   313 }
       
   314 
       
   315 /*!
       
   316  Sets parent and fetch children items from a storage
       
   317  \param parentId id of a collection
       
   318 
       
   319  \code
       
   320  ...
       
   321  // to set a new parent id
       
   322  int newParentId = 10;
       
   323  model->setParentId(newParentId);
       
   324  ...
       
   325  \endcode
       
   326 
       
   327  */
       
   328 void CaItemModel::setParentId(int parentId)
       
   329 {
       
   330     m_d->setParentId(parentId);
       
   331 }
       
   332 
       
   333 /*!
       
   334  Sets flags to mQuery which should be enabled.
       
   335  This method does not update current model - only mQuery member.
       
   336  Now to do this setParentId have to be invoke.
       
   337  \param onFlags flags.
       
   338 
       
   339  \code
       
   340  ...
       
   341  // to set a flags enabled
       
   342  model->setFlagsOn(RemovableEntryFlag);
       
   343  ...
       
   344  \endcode
       
   345 
       
   346  */
       
   347 void CaItemModel::setFlagsOn(const EntryFlags &onFlags)
       
   348 {
       
   349     m_d->setFlagsOn(onFlags);
       
   350 }
       
   351 
       
   352 /*!
       
   353  Sets flags to mQuery which should be disabled.
       
   354  This method does not update current model - only mQuery member.
       
   355  Now to do this setParentId have to be invoke.
       
   356  \param offFlags flags.
       
   357 
       
   358  \code
       
   359  ...
       
   360  // to set a flags disabled
       
   361  model->setFlagsOff(RemovableEntryFlag);
       
   362  ...
       
   363  \endcode
       
   364 
       
   365  */
       
   366 void CaItemModel::setFlagsOff(const EntryFlags &offFlags)
       
   367 {
       
   368     m_d->setFlagsOff(offFlags);
       
   369 }
       
   370 
       
   371 /*!
       
   372  Returns an entry from model
       
   373  \param index of entry in model
       
   374  \retval pointer to an entry
       
   375 
       
   376  \code
       
   377  ...
       
   378  // to get an entry from a model
       
   379  CaEntry* entry = model->entry(entryModelIndex);
       
   380  ...
       
   381  delete entry;
       
   382  \endcode
       
   383 
       
   384  */
       
   385 CaEntry *CaItemModel::entry(const QModelIndex &index) const
       
   386 {
       
   387     return m_d->entry(index);
       
   388 }
       
   389 
       
   390 /*!
       
   391  Constructor
       
   392  \param query needed to create model
       
   393  \param pointer to public implementation object connected
       
   394  */
       
   395 CaItemModelPrivate::CaItemModelPrivate(const CaQuery &query,
       
   396                                        CaItemModel *itemModelPublic) :
       
   397     QObject(), m_q(itemModelPublic), mParentEntry(0), mQuery(query),
       
   398     mService(CaService::instance()), mEntries(mService), mNotifier(NULL),
       
   399     mSize(defaultIconSize), mSecondLineVisibility(true)
       
   400 {
       
   401     updateModel();
       
   402     setAutoUpdate(true);
       
   403 }
       
   404 
       
   405 /*!
       
   406  Destructor
       
   407  */
       
   408 CaItemModelPrivate::~CaItemModelPrivate()
       
   409 {
       
   410     mEntries.clear();
       
   411     delete mParentEntry;
       
   412     delete mNotifier;
       
   413 }
       
   414 
       
   415 /*!
       
   416  Returns count of rows in model
       
   417  \retval number of rows
       
   418  */
       
   419 int CaItemModelPrivate::rowCount() const
       
   420 {
       
   421     return mEntries.count();
       
   422 }
       
   423 
       
   424 /*!
       
   425  Returns QModelIndex of an item
       
   426  \param row row
       
   427  \retval QModelIndex of item in model
       
   428  */
       
   429 QModelIndex CaItemModelPrivate::index(int row)
       
   430 {
       
   431     if ((row >= 0) && (row < mEntries.count())) {
       
   432         return m_q->createIndex(row, 0);
       
   433     } else {
       
   434         return QModelIndex();
       
   435     }
       
   436 }
       
   437 
       
   438 /*!
       
   439  Returns appropiate model's data
       
   440  \param modelIndex model index
       
   441  \param role which data role to return
       
   442  \retval models data as QVariant
       
   443  */
       
   444 QVariant CaItemModelPrivate::data(const QModelIndex &modelIndex,
       
   445                                   int role) const
       
   446 {
       
   447     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::data");
       
   448     QVariant variant;
       
   449     if (modelIndex.isValid()) {
       
   450         switch (role) {
       
   451         case Qt::DisplayRole:
       
   452             variant = displayRole(modelIndex);
       
   453             break;
       
   454         case Qt::DecorationRole:
       
   455             variant = QVariant(HbIcon(entry(modelIndex)->makeIcon(mSize)));
       
   456             break;
       
   457         case CaItemModel::IdRole:
       
   458             variant = QVariant(entry(modelIndex)->id());
       
   459             break;
       
   460         case CaItemModel::TypeRole:
       
   461             variant = QVariant(entry(modelIndex)->entryTypeName());
       
   462             break;
       
   463         case CaItemModel::FlagsRole:
       
   464             variant = qVariantFromValue(entry(modelIndex)->flags());
       
   465             break;
       
   466         case CaItemModel::TextRole:
       
   467             variant = QVariant(entry(modelIndex)->text());
       
   468             break;
       
   469         default:
       
   470             variant = QVariant(QVariant::Invalid);
       
   471         }
       
   472     }
       
   473     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::data");
       
   474     return variant;
       
   475 }
       
   476 
       
   477 /*!
       
   478  Disables or enables auto-update feature of the model
       
   479  \param autoUpdate (HsMenuAutoUpdate)
       
   480  */
       
   481 void CaItemModelPrivate::setAutoUpdate(bool autoUpdate)
       
   482 {
       
   483     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::setAutoUpdate");
       
   484     if (autoUpdate) {
       
   485         if (!mNotifier) {
       
   486             CaNotifierFilter filter(mQuery);
       
   487             mNotifier = mService->createNotifier(filter);
       
   488             connectSlots();
       
   489         }
       
   490     } else {
       
   491         disconnectSlots();
       
   492         delete mNotifier;
       
   493         mNotifier = NULL;
       
   494     }
       
   495     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::setAutoUpdate");
       
   496 }
       
   497 
       
   498 /*!
       
   499  Method for setting sorting order on model
       
   500  (probably will be moved to MenuService)
       
   501  \param  sortOrder sorting order (SortAttribute)
       
   502  */
       
   503 void CaItemModelPrivate::setSort(SortAttribute sortAttribute,
       
   504                                  Qt::SortOrder sortOrder)
       
   505 {
       
   506     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::setSort");
       
   507     mQuery.setSort(sortAttribute, sortOrder);
       
   508     updateLayout();
       
   509     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::setSort");
       
   510 }
       
   511 
       
   512 /*!
       
   513  Method for setting icon size
       
   514  \param size icon size to display
       
   515  */
       
   516 void CaItemModelPrivate::setIconSize(const QSize &size)
       
   517 {
       
   518     if (mSize == size)
       
   519         return;
       
   520     m_q->layoutAboutToBeChanged();
       
   521     mSize = size;
       
   522     m_q->layoutChanged();
       
   523 }
       
   524 
       
   525 /*!
       
   526  Method for getting icon size
       
   527  \retval icon size to display
       
   528  */
       
   529 QSize CaItemModelPrivate::getIconSize() const
       
   530 {
       
   531     return mSize;
       
   532 }
       
   533 
       
   534 
       
   535 /*!
       
   536  Gets index of the parent item
       
   537  \retval QModelIndex representing root item
       
   538  */
       
   539 QModelIndex CaItemModelPrivate::root()
       
   540 {
       
   541     if (mQuery.parentId()) {
       
   542         return m_q->createIndex(0, 1);
       
   543     } else {
       
   544         return QModelIndex();
       
   545     }
       
   546 }
       
   547 
       
   548 /*!
       
   549  Returns an entry from model
       
   550  \param modelIndex index of entry in model
       
   551  \retval pointer to an entry
       
   552  */
       
   553 CaEntry *CaItemModelPrivate::entry(const QModelIndex &modelIndex) const
       
   554 {
       
   555     if (modelIndex.column() == 1) {
       
   556         return mParentEntry;
       
   557     } else {
       
   558         return mEntries.at(modelIndex.row());
       
   559     }
       
   560 }
       
   561 
       
   562 /*!
       
   563  Disables or enables secondline feature of the model
       
   564  \param secondLine disables or enables second line
       
   565  */
       
   566 void CaItemModelPrivate::setSecondLineVisibility(bool secondLineVisibility)
       
   567 {
       
   568     if (mSecondLineVisibility == secondLineVisibility)
       
   569         return;
       
   570     m_q->layoutAboutToBeChanged();
       
   571     mSecondLineVisibility = secondLineVisibility;
       
   572     m_q->layoutChanged();
       
   573 }
       
   574 
       
   575 /*!
       
   576  Gets second line visibility attribute
       
   577  \retrun second line visibility attribute
       
   578  */
       
   579 bool CaItemModelPrivate::secondLineVisibility() const
       
   580 {
       
   581     return mSecondLineVisibility;
       
   582 }
       
   583 
       
   584 /*!
       
   585  Returns proper display role for item
       
   586  \param modelIndex item index
       
   587  \retval QVariant containing display role
       
   588  */
       
   589 QVariant CaItemModelPrivate::displayRole(const QModelIndex &modelIndex) const
       
   590 {
       
   591     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::displayRole")
       
   592 
       
   593     QVariant result;
       
   594     if (mSecondLineVisibility) {
       
   595         if (entry(modelIndex)->description().isEmpty()) {
       
   596             result = entry(modelIndex)->text();
       
   597         } else {
       
   598             QList<QVariant> text;
       
   599             text << entry(modelIndex)->text();
       
   600             text << entry(modelIndex)->description();
       
   601             result = QVariant(text);
       
   602         }
       
   603     } else {
       
   604         result = entry(modelIndex)->text();
       
   605     }
       
   606     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::displayRole")
       
   607     return result;
       
   608 }
       
   609 
       
   610 /*!
       
   611  Sets parent
       
   612  \param parentId
       
   613  */
       
   614 void CaItemModelPrivate::setParentId(int parentId)
       
   615 {
       
   616     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::setParentId");
       
   617     mQuery.setParentId(parentId);
       
   618     if (mNotifier) {
       
   619         delete mNotifier;
       
   620         mNotifier = mService->createNotifier(CaNotifierFilter(mQuery));
       
   621         reconnectSlots();
       
   622     }
       
   623     updateModel();
       
   624     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::setParentId");
       
   625 
       
   626 }
       
   627 
       
   628 /*!
       
   629  Sets flags to mQuery which should be enabled.
       
   630  \param onFlags flags.
       
   631 
       
   632   */
       
   633 void CaItemModelPrivate::setFlagsOn(const EntryFlags &onFlags)
       
   634 {
       
   635     mQuery.setFlagsOn(onFlags);
       
   636 }
       
   637 
       
   638 /*!
       
   639  Sets flags to mQuery which should be disabled.
       
   640  \param offFlags flags.
       
   641 
       
   642  \code
       
   643  ...
       
   644  // to set a new parent id
       
   645  model->setFlagsOff(RemovableEntryFlag);
       
   646  ...
       
   647  \endcode
       
   648 
       
   649  */
       
   650 void CaItemModelPrivate::setFlagsOff(const EntryFlags &offFlags)
       
   651 {
       
   652     mQuery.setFlagsOff(offFlags);
       
   653 }
       
   654 
       
   655 /*!
       
   656  Checks if notifier exists
       
   657   \retval true if notifier exists otherwise false
       
   658  */
       
   659 bool CaItemModelPrivate::notifierExists() const
       
   660 {
       
   661     if (mNotifier) {
       
   662         return true;
       
   663     }
       
   664     return false;
       
   665 }
       
   666 
       
   667 
       
   668 /*!
       
   669  Updates model with fresh entries and resets model
       
   670  */
       
   671 void CaItemModelPrivate::updateModel()
       
   672 {
       
   673     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::updateModel");
       
   674 
       
   675     mEntries.reloadEntries(mQuery);
       
   676     updateParentEntry();
       
   677     m_q->reset();
       
   678 
       
   679     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::updateModel");
       
   680 }
       
   681 
       
   682 /*!
       
   683  Updates parent entry
       
   684  */
       
   685 void CaItemModelPrivate::updateParentEntry()
       
   686 {
       
   687     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::updateParentEntry");
       
   688 
       
   689     if (mQuery.parentId()) {
       
   690         delete mParentEntry;
       
   691         mParentEntry = mService->getEntry(mQuery.parentId());
       
   692     }
       
   693 
       
   694     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::updateParentEntry");
       
   695 
       
   696 }
       
   697 
       
   698 /*!
       
   699  Updates model item with fresh data
       
   700  \param id id of item to update
       
   701  */
       
   702 void CaItemModelPrivate::updateItemData(int id)
       
   703 {
       
   704     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::updateItemData");
       
   705 
       
   706     mEntries.updateEntry(id);
       
   707 
       
   708     QList<int> ids = mService->getEntryIds(mQuery);
       
   709     if (mEntries.indexOf(id) >= 0 && ids.indexOf(id)
       
   710             == mEntries.indexOf(id)) {
       
   711         emit m_q->dataChanged(index(mEntries.indexOf(id)), index(
       
   712                                   mEntries.indexOf(id)));
       
   713     } else {
       
   714         if (mParentEntry && id == mParentEntry->id()) {
       
   715             updateParentEntry();
       
   716             m_q->reset();
       
   717         } else {
       
   718             updateLayout();
       
   719         }
       
   720     }
       
   721     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::updateItemData");
       
   722 }
       
   723 
       
   724 /*!
       
   725  Adds new item to model
       
   726  \param id id of item to add
       
   727  */
       
   728 void CaItemModelPrivate::addItem(int id)
       
   729 {
       
   730     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::addItem");
       
   731 
       
   732     int row = itemRow(id);
       
   733     //we use beginInsertRows and endInsertRows to emit proper signal
       
   734     //(see Qt documentation of QAbstractItemModel)
       
   735     if (mEntries.indexOf(id) < 0 && row >= 0) {
       
   736         m_q->beginInsertRows(QModelIndex(), row, row);
       
   737         mEntries.insert(row, id);
       
   738         m_q->endInsertRows();
       
   739     }
       
   740     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::addItem");
       
   741 }
       
   742 
       
   743 /*!
       
   744  Adds new items to model
       
   745  \param itemsList current items list
       
   746  */
       
   747 void CaItemModelPrivate::handleAddItems(QList<int> &itemsList)
       
   748 {
       
   749     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::handleAddItems");
       
   750 
       
   751     int entriesCount = mEntries.count();
       
   752     if (entriesCount) {
       
   753         int lastRow = itemsList.indexOf(mEntries[entriesCount - 1]);
       
   754         if (itemsList.count() == entriesCount && lastRow == (entriesCount
       
   755                 - 1)) {
       
   756             //count is same and last item is in same position
       
   757             //so we update whole model
       
   758             updateModel();
       
   759         } else if ((itemsList.count() - entriesCount) == 1 && lastRow
       
   760                    == entriesCount) {
       
   761             //just one item added - collection
       
   762             int i = 0;
       
   763             for (i = 0; i < entriesCount; i++) {
       
   764                 if (itemsList[i] != mEntries[i]) {
       
   765                     addItem(itemsList[i]);
       
   766                     updateLayout();
       
   767                     emit m_q->scrollTo(i,
       
   768                                        QAbstractItemView::PositionAtTop);
       
   769                 }
       
   770             }
       
   771             while (i < itemsList.count()) {
       
   772                 addItem(itemsList[i]);
       
   773                 i++;
       
   774             }
       
   775         } else {
       
   776             //some items were inserted or reordered,
       
   777             //so we update layout and emit signal with row number
       
   778             //of first moved/added item
       
   779             //signal is needed to scroll a view to proper position after
       
   780             //some items were added
       
   781             updateLayout();
       
   782             emit m_q->scrollTo(lastRow + 1,
       
   783                                QAbstractItemView::PositionAtTop);
       
   784         }
       
   785     } else {
       
   786         updateModel();
       
   787     }
       
   788     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::handleAddItems");
       
   789 }
       
   790 
       
   791 /*!
       
   792  Gets index/row for new item
       
   793  \param id of item to add
       
   794  \retval row in model list for new item to insert
       
   795  */
       
   796 int CaItemModelPrivate::itemRow(int id)
       
   797 {
       
   798     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::itemRow");
       
   799     QList<int> ids = mService->getEntryIds(mQuery);
       
   800     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::itemRow");
       
   801     return ids.indexOf(id);
       
   802 }
       
   803 
       
   804 /*!
       
   805  Removes item from model
       
   806  \param id of item to remove
       
   807  */
       
   808 void CaItemModelPrivate::removeItem(int id)
       
   809 {
       
   810     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::removeItem");
       
   811     int row = mEntries.indexOf(id);
       
   812     if (row >= 0) {
       
   813         m_q->beginRemoveRows(QModelIndex(), mEntries.indexOf(id),
       
   814                              mEntries.indexOf(id));
       
   815         mEntries.remove(id);
       
   816         m_q->endRemoveRows();
       
   817     } else {
       
   818         updateLayout();
       
   819     }
       
   820     
       
   821     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::removeItem");
       
   822 }
       
   823 
       
   824 /*!
       
   825  Removes missing items from model
       
   826  \param itemsList current items list
       
   827  */
       
   828 void CaItemModelPrivate::removeItems(const QList<int> &itemsList)
       
   829 {
       
   830     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::removeItems");
       
   831     int i = 0;
       
   832     for (i = 0; i < itemsList.count(); i++) {
       
   833         if (itemsList[i] != mEntries[i]) {
       
   834             removeItem(mEntries[i]);
       
   835         }
       
   836     }
       
   837     while (i < mEntries.count()) {
       
   838         removeItem(mEntries[i]);
       
   839         i++;
       
   840     }
       
   841     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::removeItems");
       
   842 }
       
   843 
       
   844 /*!
       
   845  Layout update
       
   846  */
       
   847 void CaItemModelPrivate::updateLayout()
       
   848 {
       
   849     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::updateLayout");
       
   850     m_q->layoutAboutToBeChanged();
       
   851     mEntries.updateEntries(mQuery);
       
   852     updateParentEntry();
       
   853     m_q->layoutChanged();
       
   854     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::updateLayout");
       
   855 }
       
   856 
       
   857 /*!
       
   858  Connects slots
       
   859  */
       
   860 void CaItemModelPrivate::connectSlots()
       
   861 {
       
   862     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::connectSlots");
       
   863     connect(mNotifier, SIGNAL(entryChanged(int,ChangeType)),
       
   864             this, SLOT(updateModelItem(int,ChangeType)));
       
   865 
       
   866     if (mQuery.parentId() > 0) {
       
   867         connect(mNotifier, SIGNAL(groupContentChanged(int)),
       
   868                 this, SLOT(updateModelContent(int)));
       
   869     }
       
   870     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::connectSlots");
       
   871 }
       
   872 
       
   873 /*!
       
   874  Disconnects slots
       
   875  */
       
   876 void CaItemModelPrivate::disconnectSlots()
       
   877 {
       
   878     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::disconnectSlots");
       
   879     disconnect(mNotifier, SIGNAL(entryChanged(int,ChangeType)),
       
   880                this, SLOT(updateModelItem(int,ChangeType)));
       
   881     if (mQuery.parentId() > 0) {
       
   882         disconnect(mNotifier, SIGNAL(groupContentChanged(int)),
       
   883                    this, SLOT(updateModelContent(int)));
       
   884     }
       
   885     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::disconnectSlots");
       
   886 }
       
   887 
       
   888 /*!
       
   889  Reconnects slots
       
   890  */
       
   891 void CaItemModelPrivate::reconnectSlots()
       
   892 {
       
   893     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::reconnectSlots");
       
   894     disconnectSlots();
       
   895     connectSlots();
       
   896     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::reconnectSlots");
       
   897 }
       
   898 
       
   899 /*!
       
   900  Updates model with fresh entries
       
   901  \param id of item to handle
       
   902  \param changeType change type
       
   903  */
       
   904 void CaItemModelPrivate::updateModelItem(int id, ChangeType changeType)
       
   905 {
       
   906     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::updateModelItem");
       
   907     switch (changeType) {
       
   908     case AddChangeType:
       
   909         addItem(id);
       
   910         break;
       
   911     case RemoveChangeType:
       
   912         removeItem(id);
       
   913         break;
       
   914     default:
       
   915         updateItemData(id);
       
   916         break;
       
   917     }
       
   918     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::updateModelItem");
       
   919 }
       
   920 
       
   921 /*!
       
   922  Updates model with fresh entries
       
   923  \param id of parent
       
   924  */
       
   925 void CaItemModelPrivate::updateModelContent(int id)
       
   926 {
       
   927     Q_UNUSED(id);
       
   928     CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::updateModelContent");
       
   929     QList<int> ids = mService->getEntryIds(mQuery);
       
   930 
       
   931     if (ids.count() >= mEntries.count()) {
       
   932         handleAddItems(ids);
       
   933     } else {
       
   934         removeItems(ids);
       
   935     }
       
   936     CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::updateModelContent");
       
   937 }