diff -r 000000000000 -r 16d8024aca5e src/hbwidgets/dataform/hbdataformmodel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hbwidgets/dataform/hbdataformmodel.cpp Mon Apr 19 14:02:13 2010 +0300 @@ -0,0 +1,706 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (developer.feedback@nokia.com) +** +** This file is part of the HbWidgets module of the UI Extensions for Mobile. +** +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at developer.feedback@nokia.com. +** +****************************************************************************/ + +#include +#include + +#include "hbdataformmodel_p.h" + +/* + \internal + + adds the dataformviewitem or page or group depending upon /a itemType + and return pointer to newly created form item. + \a label : Label for the dataformItem. In case of GroupPage and FormPage, + label is added to parents combobox as one of the selectors. + \a parent : is parent of item + +*/ +HbDataFormModelItem* HbDataFormModelPrivate::addItem( + HbDataFormModelItem::DataItemType itemType , const QString& label, HbDataFormModelItem *parent) +{ + if(!parent) { + parent = mRoot; + } + return insertItem( parent->childCount(), itemType , label , parent); +} + +/* + \internal + + insert data form item or page or group depending upon /a itemType + and return pointer to newly created form item. + \a label : Heading for data group , group tital in case of group page and page tital in case + item us data page item. + \a parent : is parent of item + +*/ +HbDataFormModelItem* HbDataFormModelPrivate::insertItem( + int index,HbDataFormModelItem::DataItemType itemType ,const QString& label, HbDataFormModelItem *parent) +{ + if(!parent) { + parent = mRoot; + } + if(itemType == HbDataFormModelItem::GroupPageItem && (parent->type() != HbDataFormModelItem::GroupItem)) { + return 0; + } + HbDataFormModelItem *item = new HbDataFormModelItem(itemType, label); + parent->insertChild(index , item); + return item; +} + +/* + \internal +*/ +void HbDataFormModelPrivate::rowsAboutToBeInserted(HbDataFormModelItem *parent, + int start, int end) +{ + Q_Q(HbDataFormModel); + QModelIndex index = q->indexFromItem(parent); + q->beginInsertRows(index, start, end); +} + +/* + \internal +*/ +void HbDataFormModelPrivate::rowsAboutToBeRemoved(HbDataFormModelItem *parent, + int start, int end) +{ + Q_Q(HbDataFormModel); + QModelIndex index = q->indexFromItem(parent); + q->beginRemoveRows(index, start, end); +} + +/* + \internal +*/ +void HbDataFormModelPrivate::rowsInserted() +{ + Q_Q(HbDataFormModel); + q->endInsertRows(); +} + +/* + \internal +*/ +void HbDataFormModelPrivate::rowsRemoved() +{ + Q_Q(HbDataFormModel); + q->endRemoveRows(); +} + + +/*! + @beta + @hbwidgets + \class HbDataFormModel hbdataformmodel.h + \brief The HbDataFormModel class provides data model for HbDataForm. + \ingroup model-view + + HbDataFormModel is derived from QAbstractItemModel. So applications can use, + QAbstractItemModel API's to create their datamodel. HbDataFormModel also provides + convenience API's specific to HbDataForm. These convinience API's are useful in creating + form page, group, group page and data item. + + A HbDataForm can be used to display the contents of the model. + HbDataFormModel also has Apis to return modelindex of the items and vice-versa. + So applications can individually modify the items data and set it to the HbDataForm. + */ + +/*! + Constructs a new data form model with the given \a parent. + +*/ +HbDataFormModel::HbDataFormModel(QObject *parent) + :QAbstractItemModel(parent),d_ptr(new HbDataFormModelPrivate ) +{ + Q_D(HbDataFormModel); + d->q_ptr = this; + d->mRoot->setModel(this); +} + +HbDataFormModel::~HbDataFormModel() +{ + Q_D(HbDataFormModel); + removeItem(d->mRoot); + delete d_ptr; +} + +/*! + @beta + + Appends FormPageItem and return pointer to newly created HbDataFormModelItem. + The parent of FormPageItem is always model's root item. The DataItemType is set + as FormPageItem. + + \a label Label for data page. This label will be added in the top level combo box. + + \sa insertDataFormPage + +*/ +HbDataFormModelItem* HbDataFormModel::appendDataFormPage(const QString &label) +{ + Q_D(HbDataFormModel); + return d->addItem(HbDataFormModelItem::FormPageItem,label,0); +} + +/*! + @beta + + Appends GroupItem and returns pointer to newly created HbDataFormModelItem. + The DataItemType is set as GroupItem. + + \a label Label for data group. This label will be set as a group heading. + \a parent Parent of item. The parent of GroupItem can be either model's root + index or FormPageItem. + + \sa insertDataFormGroup + +*/ +HbDataFormModelItem* HbDataFormModel::appendDataFormGroup(const QString &label, + HbDataFormModelItem *parent) +{ + Q_D(HbDataFormModel); + return d->addItem(HbDataFormModelItem::GroupItem,label,parent); +} + +/*! + @beta + + Appends GroupPageItem and returns pointer to newly created HbDataFormModelItem. + The parent of GroupPageItem can only be GroupItem. If parent passed is other than + GroupItem then this item is not appended to model and returns 0. The DataItemType + is set as GroupPageItem. + + \a label Label for data group page. This label will be added in group combo box. + + \a parent Parent of item which can be only GroupItem. + + \sa insertDataFormGroupPage + +*/ +HbDataFormModelItem* HbDataFormModel::appendDataFormGroupPage(const QString &label, + HbDataFormModelItem *parent) +{ + Q_D(HbDataFormModel); + return d->addItem(HbDataFormModelItem::GroupPageItem,label,parent); + +} + +/*! + @beta + + Appends data item and returns pointer to newly created HbDataFormModelItem. + + \a itemType Type of data item. It can be anything in + HbDataFormModelItem::DataItemType other than FormPageItem, GroupItem and + GroupPageItem. + \a label Label for data item. + \a parent Parent of data item. Parent can be model's root index, FormPageItem, + GroupPageItem or GroupItem. + + \sa insertDataFormItem + +*/ +HbDataFormModelItem* HbDataFormModel::appendDataFormItem( + HbDataFormModelItem::DataItemType itemType ,const QString &label, + HbDataFormModelItem *parent) +{ + Q_D(HbDataFormModel); + return d->addItem(itemType,label,parent); +} + +/*! + @beta + + This is a convenience API. If user wants then he can create HbDataFormModelItem + individually and then add that item in model using this API. + If the \a data is of FormpageItemtype then parent is not considered. FormPage Items are always added + to rootItem. Also GroupPage Item has to be inserted in GroupItem. + + \a data Child item to be inserted. + \a parent Parent of DataFormViewItem + + \sa insertDataFormItem + +*/ +void HbDataFormModel::appendDataFormItem(HbDataFormModelItem *data, HbDataFormModelItem *parent) +{ + if(!data) + return; + + HbDataFormModelItem::DataItemType itemType = data->type(); + + if(!parent || itemType == HbDataFormModelItem::FormPageItem) { + parent = invisibleRootItem(); + } + + + HbDataFormModelItem::DataItemType parentType = parent->type(); + + if(itemType == HbDataFormModelItem::GroupPageItem && parentType != HbDataFormModelItem::GroupItem) + return; + + + parent->appendChild(data); +} + +/*! + @beta + + Inserts FormPageItem at the specified index and returns pointer to newly created + HbDataFormModelItem. The parent can be only model's root index. + + \a index Index where FormPageItem has to be inserted. + \a label Label of FormPageItem. This will be added in top level combo + + \sa appendDataFormPage + +*/ +HbDataFormModelItem* HbDataFormModel::insertDataFormPage(int index,const QString &label) +{ + Q_D(HbDataFormModel); + return d->insertItem(index , HbDataFormModelItem::FormPageItem , label); +} + +/*! + @beta + + Inserts GroupItem at the specified index and returns pointer to newly created + HbDataFormModelItem. + + \a index Index where GroupItem has to be inserted. + \a label Label for GroupItem. This will be group heading. + \a parent Parent of item + + \sa appendDataFormGroup + +*/ +HbDataFormModelItem* HbDataFormModel::insertDataFormGroup(int index, const QString &label, + HbDataFormModelItem *parent) +{ + Q_D(HbDataFormModel); + return d->insertItem(index , HbDataFormModelItem::GroupItem ,label ,parent); +} + +/*! + @beta + + Inserts GroupPageItem at the specified index and returns pointer to newly created + HbDataFormModelItem. Return 0 if parent passed is other than GroupItem. + + \a index Index where GroupPageItem has to be inserted. + \a label Label for GroupPageItem. This will be added in group combo box. + \a parent Parent of item + + \sa appendDataFormGroupPage + +*/ +HbDataFormModelItem* HbDataFormModel::insertDataFormGroupPage( + int index, const QString &label, HbDataFormModelItem *parent) +{ + Q_D(HbDataFormModel); + return d->insertItem(index , HbDataFormModelItem::GroupPageItem, label ,parent); +} + +/*! + @beta + + Inserts data item at the specified index and returns pointer to newly created + HbDataFormModelItem. + + \a index Index where data item has to be inserted. + \a label Label for data page. + \a parent Parent of item + + \sa appendDataFormItem + +*/ +HbDataFormModelItem* HbDataFormModel::insertDataFormItem(int index, + HbDataFormModelItem::DataItemType itemType ,const QString &label, + HbDataFormModelItem *parent) +{ + Q_D(HbDataFormModel); + return d->insertItem(index ,itemType , label ,parent); +} + +/*! + @beta + + Inserts given HbDataFormModelItem \a data in the \a parent at the specified \a index. + + \a index Index where data has to be inserted in parent + \a data HbDataFormModelItem which has to be inserted + \a parent Parent of item + + \sa appendDataFormItem + +*/ +void HbDataFormModel::insertDataFormItem(int index, HbDataFormModelItem *data, + HbDataFormModelItem *parent) +{ + if(!parent || (data->data(HbDataFormModelItem::ItemTypeRole) == HbDataFormModelItem::FormPageItem )) { + parent = invisibleRootItem(); + } + parent->insertChild(index,data); +} + + +/*! + \deprecated HbDataFormModel::insertRows(int row, int count, const QModelIndex &index) + is deprecated. Please use other insert and additem API's in HbDataFormModel instead. +*/ +bool HbDataFormModel::insertRows(int row, int count, const QModelIndex &index) +{ + Q_D(HbDataFormModel); + HbDataFormModelItem *item = index.isValid() ? itemFromIndex(index) : d->mRoot; + if (item == 0) { + return false; + } + + QList items; + for(int i =0 ; i < count ; i ++) { + items.append(new HbDataFormModelItem()); + } + item->insertChildren(row,count,items); + return true; +} + + +/*! + @beta + + Removes and deletes the model item from the model at the given \a index. The visualization + corresponding to this \a index is also deleted. Returns true if \a index is removed otherwise + returns false. + + \sa removeItem +*/ +bool HbDataFormModel::removeItem(const QModelIndex &index ) +{ + return removeItem(itemFromIndex(index)); +} + +/*! + @beta + + Removes and deletes given \a item. The visualization corresponding to this \a item + is also deleted. If the \a item has childrens, all the children items are removed and deleted. + \a item is deleted only if \a item belongs to current model. Returns true if \a item is removed + otherwise returns false. + + \sa removeItem +*/ +bool HbDataFormModel::removeItem(HbDataFormModelItem *item) +{ + if( !item ) { + return false; + } + HbDataFormModelItem* parent = const_cast(item->parent()); + if ( item->model() != this ) { + return false; + } + + if( parent ) { + int index = parent->indexOf(item); + parent->removeChild(index); + return true; + } else if ( item == invisibleRootItem() ) { + delete item; + item = 0; + return true; + } + + return false; + +} + +/*! + \reimp +*/ +bool HbDataFormModel::removeRows(int row, int count, const QModelIndex &index) +{ + HbDataFormModelItem *item = itemFromIndex(index); + if ((item == 0) || (count < 1) || (row < 0) || ((row + count) > item->childCount())) { + return false; + } + + item->removeChildren(row, count); + return true; +} + +/*! + \reimp + Column value should be 0 as DataForm has only one column.If the value is not 0 + function returns invalid index. + If index is not valid then rootItem's index is considered. +*/ +QModelIndex HbDataFormModel::index(int row, int column, + const QModelIndex &index) const +{ + + if (!hasIndex(row, column, index) && column > 0) { + return QModelIndex(); + } + HbDataFormModelItem *parentItem = 0; + + if (!index.isValid()) { + parentItem = invisibleRootItem(); + } else { + parentItem = itemFromIndex(index); + } + + HbDataFormModelItem *childItem = parentItem->childAt(row); + if (childItem) { + return createIndex(row, column, childItem); + } else { + return QModelIndex(); + } +} + +/*! + \reimp +*/ +QModelIndex HbDataFormModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) { + return QModelIndex(); + } + + HbDataFormModelItem *childItem =itemFromIndex(index); + HbDataFormModelItem *parentItem = childItem->parent(); + + if (parentItem == invisibleRootItem()) { + return QModelIndex(); + } + + return indexFromItem(parentItem); +} + +/*! + \reimp +*/ +int HbDataFormModel::rowCount(const QModelIndex &item ) const +{ + HbDataFormModelItem *parentItem; + if (item.column() > 0) { + return 0; + } + + if (!item.isValid()) { + parentItem = invisibleRootItem(); + } else { + parentItem = static_cast(item.internalPointer()); + } + return parentItem->childCount(); +} + +/*! + \reimp +*/ +int HbDataFormModel::columnCount(const QModelIndex & /*parent*/) const +{ + return 1; +} + +/*! + \reimp + + Returns true if given /a index has children, other wise false +*/ +bool HbDataFormModel::hasChildren(const QModelIndex &index) const +{ + HbDataFormModelItem* item = 0; + if(index.isValid()) { + item = static_cast(index.internalPointer()); + if(item && item->childCount()) { + return true; + } + } + return false; +} + +/*! + @beta + + Returns child count for given parent index /a parent +*/ +int HbDataFormModel::childCount(const QModelIndex &index) const +{ + return rowCount(index); +} + +/*! + \reimp +*/ +QVariant HbDataFormModel::data(const QModelIndex &index, int role) const +{ + HbDataFormModelItem *item = static_cast(index.internalPointer()); + return item ? item->data(role) : QVariant(); +} + +/*! + \reimp +*/ +bool HbDataFormModel::setData(const QModelIndex &index, const QVariant &value, + int role) +{ + if (!index.isValid()) { + return false; + } + HbDataFormModelItem *item = itemFromIndex(index); + if (item == 0) { + return false; + } + item->setData(role , value); + return true; +} + +/*! + @beta + + Removes all items from the model and sets the + number of rows and columns to zero. + + \sa removeColumns(), removeRows() +*/ +void HbDataFormModel::clear() +{ + Q_D(HbDataFormModel); + removeItem(invisibleRootItem()); + d->mRoot = new HbDataFormModelItem(); + d->mRoot->setModel(this); + reset(); +} + +/*! + \reimp + + Returns a pointer to the HbDataFormModelItem associated with the given \a index. + + Calling this function is typically the initial step when processing + QModelIndex-based signals from a view, such as + HbAbstractItemView::activated(). In your slot, you call itemFromIndex(), + with the QModelIndex carried by the signal as argument, to obtain a + pointer to the corresponding HbDataFormModelItem. + + NOTE: index passed should be the one returned from HbDataFromModel Only. + + If \a index is an invalid index, this function returns 0. + + \sa indexFromItem() +*/ +HbDataFormModelItem* HbDataFormModel::itemFromIndex(const QModelIndex &index) const +{ + if ((index.row() < 0) || (index.column() < 0) || (index.model() != this)) { + return 0; + } + + HbDataFormModelItem *item = static_cast(index.internalPointer()); + if (item) { + return item; + } + return 0; +} + +/*! + \reimp + + Returns the QModelIndex associated with the given \a item. + Use this function when you want to perform an operation that requires the + QModelIndex of the item, such as HbAbstractItemView::scrollTo(). + + \sa itemFromIndex() +*/ +QModelIndex HbDataFormModel::indexFromItem(const HbDataFormModelItem* item) const +{ + if(item) { + HbDataFormModelItem* parentItem = item->parent(); + if (parentItem) { + return createIndex(parentItem->indexOf(item), 0, (void*)item); + } + } + return QModelIndex(); +} + +/*! @beta + + Returns the HbDataFormModelItem at given \a row and with given parent /a index. +*/ +HbDataFormModelItem* HbDataFormModel::item(int row, const QModelIndex &index) const +{ + if(index.isValid()) { + return itemFromIndex(index)->childAt(row); + } else { + return invisibleRootItem()->childAt(row); + } +} + +/*! + \reimp + + Returns the model's invisible root item. + + The invisible root item provides access to the model's top-level items + through the HbDataFormModelItem API, making it possible to write functions that + can treat top-level items and their children in a uniform way. + for example,recursive functions involving a tree model. + +*/ +HbDataFormModelItem* HbDataFormModel::invisibleRootItem() const +{ + Q_D(const HbDataFormModel); + return d->mRoot; +} + +/* + \reimp +*/ +bool HbDataFormModel::canFetchMore ( const QModelIndex & parent ) const +{ + if(parent.isValid()) { + if((hasChildren(parent)) || (sibling(parent.row() + 1,0,parent)).isValid()) { + return true; + } + } + + return false; +} + +/* + \reimp +*/ +Qt::ItemFlags HbDataFormModel::flags(const QModelIndex &index) const +{ + if (index.isValid()) { + const HbDataFormModelItem *item = itemFromIndex(index); + if (item) { + return item->flags(); + } + } + return 0; +} + +