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