--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contentstorage/caclient/src/caitemmodel.cpp Tue Aug 31 15:30:51 2010 +0300
@@ -0,0 +1,1081 @@
+/*
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description: caitemmodel.cpp
+ *
+ */
+
+#include <HbIcon>
+
+#include "caclient_defines.h"
+#include "caitemmodel.h"
+#include "caitemmodel_p.h"
+#include "canotifier.h"
+#include "canotifierfilter.h"
+#include "caclienttest_global.h"
+
+// Constants
+const QSizeF defaultIconSize(30, 30);
+
+// ======== MEMBER FUNCTIONS ========
+
+/*!
+ * \class CaItemModel
+ *
+ * \brief This class provides model containing CaEntry class objects.
+ *
+ * To create instance of CaItemModel object, you need to pass CaQuery
+ * object in constructor. CaQuery should describe items that you want
+ * to have in a model.
+ *
+ * \example
+ * \code
+ *
+ * CaQuery query;
+ * query.setFlagsOn(VisibleEntryFlag);
+ * query.setParentId(collectionId);
+ * CaItemModel* model = new CaItemModel(query, this);
+ *
+ * \endcode
+ */
+
+/*!
+ Constructor.
+ \param query query describing entries that should be present in a model.
+ \param parent parent of a model
+ */
+CaItemModel::CaItemModel(const CaQuery &query, QObject *parent) :
+ QAbstractItemModel(parent), m_d(new CaItemModelPrivate(query, this))
+{
+
+}
+
+/*!
+ Destructor
+ */
+CaItemModel::~CaItemModel()
+{
+ delete m_d;
+}
+
+/*!
+ Returns number of columns
+ \param parent not used
+ \retval 1
+
+ \code
+ ...
+ // to get number of columns in a model
+ int columns = model->columnCount();
+ ...
+ \endcode
+
+ */
+int CaItemModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ //model keeps entries in a column 0 and a parent entry in a column 1
+ //parent entry is treated as an invisible root item,
+ //so column count is always 1
+ return 1;
+}
+
+/*!
+ Returns number of rows
+ \param parent not used
+ \retval number of rows
+
+ \code
+ ...
+ // to get number of rows in a model
+ int rows = model->rowCount();
+ ...
+ \endcode
+ */
+int CaItemModel::rowCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return m_d->rowCount();
+}
+
+/*!
+ Returns QModelIndex of an item
+ \param row row in which an item is placed
+ \param column not used
+ \param parent not used
+ \retval index of item in model
+
+ \code
+ ...
+ // to get model index of an item
+ QModelIndex modelIndex = model->index(5);
+ ...
+ \endcode
+
+ */
+QModelIndex CaItemModel::index(int row, int column,
+ const QModelIndex &parent) const
+{
+ Q_UNUSED(column);
+ Q_UNUSED(parent);
+ return m_d->index(row);
+}
+
+/*!
+ Returns parent item
+ \param child index (ignored)
+ \retval parent index. in case of CaItemModel it is always QModelIndex()
+
+ \code
+ ...
+ // to get model index of a parent of an item
+ QModelIndex parentModelIndex = model->parent(childModelIndex);
+ ...
+ \endcode
+ */
+QModelIndex CaItemModel::parent(const QModelIndex &index) const
+{
+ Q_UNUSED(index);
+ return QModelIndex();
+}
+
+/*!
+ Returns root item model index
+ \retval root item model index
+
+ \code
+ ...
+ // to get model index of a root item
+ QModelIndex rootIndex = model->root();
+ ...
+ \endcode
+ */
+QModelIndex CaItemModel::root() const
+{
+ return m_d->root();
+}
+
+/*!
+ Returns appropiate model's data
+ \param index model index
+ \param role which data role to return
+ \retval models data
+
+ \code
+ ...
+ // to get data for model item
+ QVariant = model->data(itemModelIndex, Qt::DisplayRole);
+ ...
+ \endcode
+
+ */
+QVariant CaItemModel::data(const QModelIndex &index, int role) const
+{
+ return m_d->data(index, role);
+}
+
+/*!
+ Disables or enables auto-update feature of the model
+ \param autoUpdate true to enable autoupdate, false to disable
+
+ \code
+ ...
+ // to enable model auto update
+ model->setAutoUpdate(true);
+ ...
+ \endcode
+
+ */
+void CaItemModel::setAutoUpdate(bool autoUpdate)
+{
+ m_d->setAutoUpdate(autoUpdate);
+}
+
+/*!
+ Disables or enables secondline feature of the model
+ \param secondLine enable or disable second line
+
+ \code
+ ...
+ // to enable model second line visibility
+ model->setSecondLineVisibility(true);
+ ...
+ \endcode
+
+ */
+void CaItemModel::setSecondLineVisibility(bool secondLineVisible)
+{
+ m_d->setSecondLineVisibility(secondLineVisible);
+}
+
+/*!
+ Gets second line visibility attribute
+ \retrun second line visibility attribute
+
+ \code
+ ...
+ // to check second line visibility attribute
+ bool visibility = model->secondLineVisibility();
+ ...
+ \endcode
+
+ */
+bool CaItemModel::secondLineVisibility() const
+{
+ return m_d->secondLineVisibility();
+}
+/*!
+ Returns auto update status
+ \retval true if autoupdate is on, false if not
+
+ \code
+ ...
+ // to check auto update attribute
+ bool autoUpdate = model->isAutoUpdate();
+ ...
+ \endcode
+
+ */
+bool CaItemModel::isAutoUpdate() const
+{
+ return m_d->notifierExists();
+}
+
+/*!
+ Method for setting sorting order on model
+ \param sortAttribute sort attribute (by name, timestamp, ect...)
+ \param sortOrder sort order (ascending, descending)
+
+ \code
+ ...
+ // to set sort order in a model
+ model->setSort(NameSortAttribute, Qt::Ascending);
+ ...
+ \endcode
+
+ */
+void CaItemModel::setSort(SortAttribute sortAttribute,
+ Qt::SortOrder sortOrder)
+{
+ m_d->setSort(sortAttribute, sortOrder);
+}
+
+/*!
+ Method for setting icon size
+ \param size icon size to display
+
+ \code
+ ...
+ // to set an icon size in a model
+ QSize iconSize(50,50);
+ model->setIconSize(iconSize);
+ ...
+ \endcode
+
+ */
+void CaItemModel::setIconSize(const QSizeF &size)
+{
+ m_d->setIconSize(size);
+}
+
+/*!
+ Method for getting icon size
+ \param size icon size to display
+ */
+QSizeF CaItemModel::getIconSize() const
+{
+ return m_d->getIconSize();
+}
+
+/*!
+ Updates model with fresh entries
+
+ \code
+ ...
+ // to refresh a model
+ model->updateModel();
+ ...
+ \endcode
+
+ */
+void CaItemModel::updateModel()
+{
+ m_d->updateModel();
+}
+
+/*!
+ Sets parent and fetch children items from a storage
+ \param parentId id of a collection
+
+ \code
+ ...
+ // to set a new parent id
+ int newParentId = 10;
+ model->setParentId(newParentId);
+ ...
+ \endcode
+
+ */
+void CaItemModel::setParentId(int parentId)
+{
+ m_d->setParentId(parentId);
+}
+
+/*!
+ Sets flags to mQuery which should be enabled.
+ This method does not update current model - only mQuery member.
+ Now to do this setParentId have to be invoke.
+ \param onFlags flags.
+
+ \code
+ ...
+ // to set a flags enabled
+ model->setFlagsOn(RemovableEntryFlag);
+ ...
+ \endcode
+
+ */
+void CaItemModel::setFlagsOn(const EntryFlags &onFlags)
+{
+ m_d->setFlagsOn(onFlags);
+}
+
+/*!
+ Sets flags to mQuery which should be disabled.
+ This method does not update current model - only mQuery member.
+ Now to do this setParentId have to be invoke.
+ \param offFlags flags.
+
+ \code
+ ...
+ // to set a flags disabled
+ model->setFlagsOff(RemovableEntryFlag);
+ ...
+ \endcode
+
+ */
+void CaItemModel::setFlagsOff(const EntryFlags &offFlags)
+{
+ m_d->setFlagsOff(offFlags);
+}
+
+/*!
+ Returns an entry from model
+ \param index of entry in model
+ \retval pointer to an entry
+
+ \code
+ ...
+ // to get an entry from a model
+ CaEntry* entry = model->entry(entryModelIndex);
+ ...
+ delete entry;
+ \endcode
+
+ */
+QSharedPointer<CaEntry> CaItemModel::entry(const QModelIndex &index) const
+{
+ return m_d->entry(index);
+}
+
+QList<int> CaItemModel::getUninstallingEntriesIds(int componentId)
+{
+ return m_d->getUninstallingEntriesIds(componentId);
+}
+
+void CaItemModel::updateProgress(int id, int valueOfProgress)
+{
+ m_d->updateProgress(id, valueOfProgress);
+}
+
+/*!
+ Constructor
+ \param query needed to create model
+ \param pointer to public implementation object connected
+ */
+CaItemModelPrivate::CaItemModelPrivate(const CaQuery &query,
+ CaItemModel *itemModelPublic) :
+ QObject(), m_q(itemModelPublic), mParentEntry(), mQuery(query),
+ mService(CaService::instance()), mEntries(mService), mNotifier(NULL),
+ mSize(defaultIconSize), mSecondLineVisibility(true)
+{
+ updateModel();
+ setAutoUpdate(true);
+}
+
+/*!
+ Destructor
+ */
+CaItemModelPrivate::~CaItemModelPrivate()
+{
+ mEntries.clear();
+ delete mNotifier;
+}
+
+/*!
+ Returns count of rows in model
+ \retval number of rows
+ */
+int CaItemModelPrivate::rowCount() const
+{
+ return mEntries.count();
+}
+
+/*!
+ Returns QModelIndex of an item
+ \param row row
+ \retval QModelIndex of item in model
+ */
+QModelIndex CaItemModelPrivate::index(int row)
+{
+ if ((row >= 0) && (row < mEntries.count())) {
+ return m_q->createIndex(row, 0);
+ } else {
+ return QModelIndex();
+ }
+}
+
+/*!
+ Returns appropiate model's data
+ \param modelIndex model index
+ \param role which data role to return
+ \retval models data as QVariant
+ */
+QVariant CaItemModelPrivate::data(const QModelIndex &modelIndex,
+ int role) const
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::data");
+ QVariant variant;
+ QSharedPointer<CaEntry> pEntry = entry(modelIndex);
+ if (!pEntry.isNull()) {
+ switch (role) {
+ case Qt::DisplayRole:
+ variant = displayRole(pEntry.data());
+ break;
+ case Qt::DecorationRole:
+ variant = QVariant(HbIcon(pEntry->makeIcon(mSize)));
+ break;
+ case CaItemModel::IdRole:
+ variant = QVariant(pEntry->id());
+ break;
+ case CaItemModel::TypeRole:
+ variant = QVariant(pEntry->entryTypeName());
+ break;
+ case CaItemModel::FlagsRole:
+ variant = qVariantFromValue(pEntry->flags());
+ break;
+ case CaItemModel::TextRole:
+ variant = QVariant(pEntry->text());
+ break;
+ case CaItemModel::FullTextRole:
+ variant = QVariant(pEntry->text() + QString(" ") + pEntry->description());
+ break;
+ case CaItemModel::UninstalRole:
+ variant = QVariant(
+ pEntry->attribute(UNINSTALL_PROGRESS_APPLICATION_ATTRIBUTE_NAME).toInt());
+ break;
+ case CaItemModel::CollectionTitleRole:
+ if (!pEntry->attribute(COLLECTION_TITLE_NAME).isNull()) {
+ variant = QVariant(pEntry->
+ attribute(COLLECTION_TITLE_NAME).toUtf8());
+ }
+ else {
+ variant = QVariant(pEntry->text());
+ }
+ break;
+
+ default:
+ variant = QVariant(QVariant::Invalid);
+ }
+ }
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::data");
+ return variant;
+}
+
+/*!
+ Disables or enables auto-update feature of the model
+ \param autoUpdate (HsMenuAutoUpdate)
+ */
+void CaItemModelPrivate::setAutoUpdate(bool autoUpdate)
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::setAutoUpdate");
+ if (autoUpdate) {
+ if (!mNotifier) {
+ CaNotifierFilter filter(mQuery);
+ mNotifier = mService->createNotifier(filter);
+ connectSlots();
+ }
+ } else {
+ disconnectSlots();
+ delete mNotifier;
+ mNotifier = NULL;
+ }
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::setAutoUpdate");
+}
+
+/*!
+ Method for setting sorting order on model
+ (probably will be moved to MenuService)
+ \param sortOrder sorting order (SortAttribute)
+ */
+void CaItemModelPrivate::setSort(SortAttribute sortAttribute,
+ Qt::SortOrder sortOrder)
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::setSort");
+ mQuery.setSort(sortAttribute, sortOrder);
+ updateLayout();
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::setSort");
+}
+
+/*!
+ Method for setting icon size
+ \param size icon size to display
+ */
+void CaItemModelPrivate::setIconSize(const QSizeF &size)
+{
+ if (mSize == size)
+ return;
+ m_q->layoutAboutToBeChanged();
+ mSize = size;
+ m_q->layoutChanged();
+}
+
+/*!
+ Method for getting icon size
+ \retval icon size to display
+ */
+QSizeF CaItemModelPrivate::getIconSize() const
+{
+ return mSize;
+}
+
+
+/*!
+ Gets index of the parent item
+ \retval QModelIndex representing root item
+ */
+QModelIndex CaItemModelPrivate::root()
+{
+ if (mQuery.parentId()) {
+ return m_q->createIndex(0, 1);
+ } else {
+ return QModelIndex();
+ }
+}
+
+/*!
+ Returns an entry from model
+ \param modelIndex index of entry in model
+ \retval pointer to an entry
+ */
+QSharedPointer<CaEntry> CaItemModelPrivate::entry(const QModelIndex &modelIndex) const
+{
+ if (modelIndex.isValid()) {
+ if (modelIndex.column() == 1) {
+ return mParentEntry;
+ }
+ else {
+ int row = modelIndex.row();
+ if (row >= mEntries.count()) {
+ return QSharedPointer<CaEntry> ();
+ }
+ else {
+ return mEntries.at(row);
+ }
+ }
+ }
+ return QSharedPointer<CaEntry> ();
+}
+
+/*!
+ Disables or enables secondline feature of the model
+ \param secondLine disables or enables second line
+ */
+void CaItemModelPrivate::setSecondLineVisibility(bool secondLineVisibility)
+{
+ if (mSecondLineVisibility == secondLineVisibility)
+ return;
+ m_q->layoutAboutToBeChanged();
+ mSecondLineVisibility = secondLineVisibility;
+ m_q->layoutChanged();
+}
+
+/*!
+ Gets second line visibility attribute
+ \retrun second line visibility attribute
+ */
+bool CaItemModelPrivate::secondLineVisibility() const
+{
+ return mSecondLineVisibility;
+}
+
+/*!
+ Returns proper display role for item
+ \param modelIndex item index
+ \retval QVariant containing display role
+ */
+QVariant CaItemModelPrivate::displayRole(const CaEntry* entry) const
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::displayRole")
+
+ QVariant result;
+ if (mSecondLineVisibility) {
+ if (entry->description().isEmpty()) {
+ result = entry->text();
+ } else {
+ QList<QVariant> text;
+ text << entry->text();
+ text << entry->description();
+ result = QVariant(text);
+ }
+ } else {
+ result = entry->text();
+ }
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::displayRole")
+ return result;
+}
+
+/*!
+ Sets parent
+ \param parentId
+ */
+void CaItemModelPrivate::setParentId(int parentId)
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::setParentId");
+ mQuery.setParentId(parentId);
+ if (mNotifier) {
+ delete mNotifier;
+ mNotifier = mService->createNotifier(CaNotifierFilter(mQuery));
+ reconnectSlots();
+ }
+ updateModel();
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::setParentId");
+
+}
+
+/*!
+ Sets flags to mQuery which should be enabled.
+ \param onFlags flags.
+
+ */
+void CaItemModelPrivate::setFlagsOn(const EntryFlags &onFlags)
+{
+ mQuery.setFlagsOn(onFlags);
+}
+
+/*!
+ Sets flags to mQuery which should be disabled.
+ \param offFlags flags.
+
+ \code
+ ...
+ // to set a new parent id
+ model->setFlagsOff(RemovableEntryFlag);
+ ...
+ \endcode
+
+ */
+void CaItemModelPrivate::setFlagsOff(const EntryFlags &offFlags)
+{
+ mQuery.setFlagsOff(offFlags);
+}
+
+/*!
+ Checks if notifier exists
+ \retval true if notifier exists otherwise false
+ */
+bool CaItemModelPrivate::notifierExists() const
+{
+ if (mNotifier) {
+ return true;
+ }
+ return false;
+}
+
+
+QList<int> CaItemModelPrivate::getUninstallingEntriesIds(int componentId)
+{
+ CaQuery* query = new CaQuery(mQuery);
+ QString compId(QString().setNum(componentId));
+ query->setAttribute(QString("component_id"), compId);
+ query->setFlagsOn(RemovableEntryFlag | VisibleEntryFlag);
+ QList<int> ids = mService->getEntryIds(*query);
+ delete query;
+ return ids;
+}
+
+void CaItemModelPrivate::updateProgress(int id, int valueOfProgress)
+{
+ int updateIndex = mEntries.updateProgress(id, valueOfProgress);
+ if (updateIndex >= 0) {
+ emit m_q->dataChanged(
+ index(updateIndex), index(updateIndex));
+ }
+}
+/*!
+ Updates model with fresh entries and resets model
+ */
+void CaItemModelPrivate::updateModel()
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::updateModel");
+
+ mEntries.reloadEntries(mQuery);
+ updateParentEntry();
+ m_q->reset();
+
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::updateModel");
+}
+
+/*!
+ Updates parent entry
+ */
+void CaItemModelPrivate::updateParentEntry()
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::updateParentEntry");
+
+ if (mQuery.parentId()) {
+ mParentEntry = mService->getEntry(mQuery.parentId());
+ }
+
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::updateParentEntry");
+
+}
+
+/*!
+ Updates model item with fresh data
+ \param entry item to update
+ */
+void CaItemModelPrivate::updateItemData(const QSharedPointer<CaEntry> &entry)
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::updateItemData");
+
+
+ int id = entry->id();
+ QList<int> ids = mService->getEntryIds(mQuery);
+ if (mEntries.indexOf(id) >= 0
+ && ids.indexOf(id) == mEntries.indexOf(id)) {
+ mEntries.updateEntry(entry);
+ emit m_q->dataChanged(
+ index(mEntries.indexOf(id)), index(mEntries.indexOf(id)));
+ } else if (mParentEntry && id == mParentEntry->id()) {
+ updateParentEntry();
+ m_q->reset();
+ } else if (ids.indexOf(id) < 0) {
+ removeItem(id);
+ } else if (mEntries.indexOf(id) < 0) {
+ addItem(id);
+ } else {
+ updateModel();
+ }
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::updateItemData");
+}
+
+/*!
+ Adds new item to model
+ \param id id of item to add
+ */
+void CaItemModelPrivate::addItem(int id)
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::addItem");
+
+ int row = itemRow(id);
+ //we use beginInsertRows and endInsertRows to emit proper signal
+ //(see Qt documentation of QAbstractItemModel)
+ if (mEntries.indexOf(id) < 0 && row >= 0) {
+ if (row > mEntries.count()) {
+ m_q->beginInsertRows(QModelIndex(), mEntries.count(), mEntries.count());
+ mEntries.insert(mEntries.count(), id);
+ } else {
+ m_q->beginInsertRows(QModelIndex(), row , row);
+ mEntries.insert(row, id);
+ }
+ m_q->endInsertRows();
+ } else if (row == -1) {
+ //we udpade whole model because we do not know parent collecion for given item
+ updateModel();
+ }
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::addItem");
+}
+
+/*!
+ Adds new item block to model
+ Use in cases when inserting / appending an adjacent block of items
+ \param itemsList list of adjacent items
+ */
+void CaItemModelPrivate::addItemBlock(const QList<int> &itemsList)
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::addItemBlock");
+ if (!itemsList.isEmpty()) {
+ int firstRow = itemRow(itemsList.first());
+ int lastRow = itemRow(itemsList.last());
+ m_q->beginInsertRows(QModelIndex(), firstRow, lastRow);
+ for (int i = 0; i < itemsList.count(); ++i) {
+ mEntries.insert(firstRow + i, itemsList.at(i));
+ }
+ m_q->endInsertRows();
+ emit m_q->scrollTo(firstRow, QAbstractItemView::PositionAtTop);
+ }
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::addItemBlock");
+}
+
+/*!
+ Adds new items to model
+ \param itemsList current items list
+ */
+void CaItemModelPrivate::handleAddItems(const QList<int> &itemsList)
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::handleAddItems");
+ const int oldItemCount(mEntries.count());
+ if (oldItemCount) {
+ const int newItemCount(itemsList.count());
+ int i = 0;
+ QList<int> oldList = mEntries.orderedIdList();
+ //we loop through items to find first added
+ while (i < oldList.count()) {
+ if (oldList[i] != itemsList[i]) {
+ oldList.takeAt(i);
+ } else {
+ ++i;
+ }
+ }
+ if (newItemCount == oldItemCount) {
+ // count is the same - check if item order changed
+ if (itemsList == oldList) {
+ // assume that if the order has not changed
+ // it had to be the secondary lines
+ emit m_q->dataChanged(index(0), index(m_q->rowCount()-1));
+ } else {
+ updateLayout();
+ }
+ } else {
+ updateModel();
+ //i is the index of first added item
+ }
+ emit m_q->scrollTo(i, QAbstractItemView::PositionAtTop);
+ } else {
+ // items added to an empty list - add all as a single block
+ addItemBlock(itemsList);
+ }
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::handleAddItems");
+}
+
+/*!
+ Gets index/row for new item
+ \param id of item to add
+ \retval row in model list for new item to insert
+ */
+int CaItemModelPrivate::itemRow(int id)
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::itemRow");
+ QList<int> ids = mService->getEntryIds(mQuery);
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::itemRow");
+ return ids.indexOf(id);
+}
+
+/*!
+ Removes item from model
+ \param id of item to remove
+ */
+void CaItemModelPrivate::removeItem(int id)
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::removeItem");
+ int row = mEntries.indexOf(id);
+ if (row >= 0) {
+ m_q->beginRemoveRows(QModelIndex(), mEntries.indexOf(id),
+ mEntries.indexOf(id));
+ mEntries.remove(id);
+ m_q->endRemoveRows();
+ } else {
+ updateModel();
+ }
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::removeItem");
+}
+
+/*!
+ Removes missing items from model
+ \param itemsList current items list
+ */
+void CaItemModelPrivate::removeItems(const QList<int> &itemsList)
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::removeItems");
+ int i = 0;
+ for (i = 0; i < itemsList.count(); i++) {
+ if (itemsList[i] != mEntries[i]) {
+ removeItem(mEntries[i]);
+ }
+ }
+ while (i < mEntries.count()) {
+ removeItem(mEntries[i]);
+ i++;
+ }
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::removeItems");
+}
+
+/*!
+ Layout update
+ NOTE: this method should be called only if the entries get rearranged
+ and do not change their contents!
+ */
+void CaItemModelPrivate::updateLayout()
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::updateLayout");
+ m_q->layoutAboutToBeChanged();
+
+ // get the ID list from before the update
+ QList<int> oldOrderedIdList = mEntries.orderedIdList();
+
+ // do the update, the entries should only get rearranged
+ mEntries.updateEntries(mQuery);
+
+ // get the new ID list after the entries got rearranged
+ QList<int> newOrderedIdList = mEntries.orderedIdList();
+ // this list will contain the new position indices
+ QList<int> newPositionsList;
+ int entry;
+ foreach (entry, oldOrderedIdList) {
+ newPositionsList << newOrderedIdList.indexOf(entry);
+ }
+
+ // now check which items in the previous persistent index list changed
+ // their positions, make new indices for them and store in the new
+ // persistent index list
+ QModelIndexList oldPersistentIndexList = m_q->persistentIndexList();
+ QModelIndexList newPersistentIndexList;
+ QModelIndex index;
+ foreach (index, oldPersistentIndexList) {
+ newPersistentIndexList <<
+ m_q->createIndex(
+ newPositionsList.at(index.row()), 0, index.internalPointer());
+ }
+ m_q->changePersistentIndexList(
+ oldPersistentIndexList, newPersistentIndexList);
+
+ m_q->layoutChanged();
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::updateLayout");
+}
+
+/*!
+ Connects slots
+ */
+void CaItemModelPrivate::connectSlots()
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::connectSlots");
+ connect(mNotifier, SIGNAL(entryChanged(CaEntry ,ChangeType)),
+ this, SLOT(updateModelItem(CaEntry, ChangeType)));
+
+ if (mQuery.parentId() > 0) {
+ connect(mNotifier, SIGNAL(groupContentChanged(int)),
+ this, SLOT(updateModelContent(int)));
+ }
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::connectSlots");
+}
+
+/*!
+ Disconnects slots
+ */
+void CaItemModelPrivate::disconnectSlots()
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::disconnectSlots");
+ disconnect(mNotifier, SIGNAL(entryChanged(CaEntry ,ChangeType)),
+ this, SLOT(updateModelItem(CaEntry, ChangeType)));
+ if (mQuery.parentId() > 0) {
+ disconnect(mNotifier, SIGNAL(groupContentChanged(int)),
+ this, SLOT(updateModelContent(int)));
+ }
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::disconnectSlots");
+}
+
+/*!
+ Reconnects slots
+ */
+void CaItemModelPrivate::reconnectSlots()
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::reconnectSlots");
+ disconnectSlots();
+ connectSlots();
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::reconnectSlots");
+}
+
+/*!
+ Updates model with fresh entries
+ \param id of item to handle
+ \param changeType change type
+ */
+void CaItemModelPrivate::updateModelItem(
+ const CaEntry &entry, ChangeType changeType)
+{
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::updateModelItem");
+ QSharedPointer<CaEntry> sharedEntry(new CaEntry(entry));
+ int previousCount = rowCount();
+ switch (changeType) {
+ case AddChangeType:
+ addItem(sharedEntry->id());
+ break;
+ case RemoveChangeType:
+ removeItem(sharedEntry->id());
+ break;
+ default:
+ updateItemData(sharedEntry);
+ break;
+ }
+ emitEmpty(previousCount);
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::updateModelItem");
+}
+
+/*!
+ Updates model with fresh entries
+ \param id of parent
+ */
+void CaItemModelPrivate::updateModelContent(int id)
+{
+ Q_UNUSED(id);
+ int previousCount = rowCount();
+
+ CACLIENTTEST_FUNC_ENTRY("CaItemModelPrivate::updateModelContent");
+ QList<int> ids = mService->getEntryIds(mQuery);
+
+ if (ids.count() >= mEntries.count()) {
+ handleAddItems(ids);
+ } else {
+ removeItems(ids);
+ }
+ emitEmpty(previousCount);
+ emitCountChange(previousCount);
+ CACLIENTTEST_FUNC_EXIT("CaItemModelPrivate::updateModelContent");
+}
+
+/*!
+ Emits empty signal if model state was changed
+ \param id of parent
+ */
+void CaItemModelPrivate::emitEmpty(int previousCount)
+{
+ if ( previousCount && !rowCount()) {
+ emit m_q->empty(true);
+ }
+ if ( !previousCount && rowCount()) {
+ emit m_q->empty(false);
+ }
+}
+
+/*!
+ Emits empty signal if count of item in model was change
+ \param previousCount
+ */
+void CaItemModelPrivate::emitCountChange(int previousCount)
+{
+ if (previousCount != rowCount()) {
+ emit m_q->countChange();
+ }
+}
+