doc/src/examples/editabletreemodel.qdoc
branchRCL_3
changeset 7 3f74d0d4af4c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/src/examples/editabletreemodel.qdoc	Thu Apr 08 14:19:33 2010 +0300
@@ -0,0 +1,459 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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 qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+    \example itemviews/editabletreemodel
+    \title Editable Tree Model Example
+
+    This example shows how to implement a simple item-based tree model that can
+    be used with other classes the model/view framework.
+
+    \image itemviews-editabletreemodel.png
+
+    The model supports editable items, custom headers, and the ability to
+    insert and remove rows and columns. With these features, it is also
+    possible to insert new child items, and this is shown in the supporting
+    example code.
+
+    \note The model only shows the basic principles used when creating an
+    editable, hierarchical model. You may wish to use the \l{ModelTest}
+    project to test production models.
+
+    \section1 Overview
+
+    As described in the \l{Model Subclassing Reference}, models must
+    provide implementations for the standard set of model functions:
+    \l{QAbstractItemModel::}{flags()}, \l{QAbstractItemModel::}{data()},
+    \l{QAbstractItemModel::}{headerData()}, and
+    \l{QAbstractItemModel::}{rowCount()}. In addition, hierarchical models,
+    such as this one, need to provide implementations of
+    \l{QAbstractItemModel::}{index()} and \l{QAbstractItemModel::}{parent()}.
+
+    An editable model needs to provide implementations of
+    \l{QAbstractItemModel::}{setData()} and
+    \l{QAbstractItemModel::}{headerData()}, and must return a suitable
+    combination of flags from its \l{QAbstractItemModel::}{flags()} function.
+
+    Since this example allows the dimensions of the model to be changed,
+    we must also implement \l{QAbstractItemModel::}{insertRows()},
+    \l{QAbstractItemModel::}{insertColumns()},
+    \l{QAbstractItemModel::}{removeRows()}, and
+    \l{QAbstractItemModel::}{removeColumns()}.
+
+    \section1 Design
+
+    As with the \l{itemviews/simpletreemodel}{Simple Tree Model} example,
+    the model simply acts as a wrapper around a collection
+    of instances of a \c TreeItem class. Each \c TreeItem is designed to
+    hold data for a row of items in a tree view, so it contains a list of
+    values corresponding to the data shown in each column.
+
+    Since QTreeView provides a row-oriented view onto a model, it is
+    natural to choose a row-oriented design for data structures that
+    will supply data via a model to this kind of view. Although this makes
+    the tree model less flexible, and possibly less useful for use with
+    more sophisticated views, it makes it less complex to design and easier
+    to implement.
+
+    \target Relations-between-internal-items
+    \table
+    \row \o \inlineimage itemviews-editabletreemodel-items.png
+    \o \bold{Relations between internal items}
+
+    When designing a data structure for use with a custom model, it is useful
+    to expose each item's parent via a function like
+    \l{TreeItem::parent}{TreeItem::parent()} because it will make
+    writing the model's own \l{QAbstractItemModel::}{parent()} function easier.
+    Similarly, a function like \l{TreeItem::child}{TreeItem::child()} is
+    helpful when implementing the model's \l{QAbstractItemModel::}{index()}
+    function. As a result, each \c TreeItem maintains information about
+    its parent and children, making it possible for us to traverse the tree
+    structure.
+
+    The diagram shows how \c TreeItem instances are connected via their
+    \l{TreeItem::parent}{parent()} and \l{TreeItem::child}{child()}
+    functions.
+
+    In the example shown, two top-level items, \bold{A} and
+    \bold{B}, can be obtained from the root item by calling its child()
+    function, and each of these items return the root node from their
+    parent() functions, though this is only shown for item \bold{A}.
+    \endtable
+
+    Each \c TreeItem stores data for each column in the row it represents
+    in its \c itemData private member (a list of QVariant objects).
+    Since there is a one-to-one mapping between each column in the view
+    and each entry in the list, we provide a simple
+    \l{TreeItem::data}{data()} function to read entries in the \c itemData
+    list and a \l{TreeItem::setData}{setData()} function to allow them to
+    be modified.
+    As with other functions in the item, this simplifies the implemention
+    of the model's \l{QAbstractItemModel::}{data()} and
+    \l{QAbstractItemModel::}{setData()} functions.
+
+    We place an item at the root of the tree of items. This root item
+    corresponds to the null model index, \l{QModelIndex::}{QModelIndex()},
+    that is used to represent the parent of a top-level item when handling
+    model indexes.
+    Although the root item does not have a visible representation in any of
+    the standard views, we use its internal list of QVariant objects to
+    store a list of strings that will be passed to views for use as
+    horizontal header titles.
+
+    \table
+    \row \o \inlineimage itemviews-editabletreemodel-model.png
+    \o \bold{Accessing data via the model}
+
+    In the case shown in the diagram, the piece of information represented
+    by \bold{a} can be obtained using the standard model/view API:
+
+    \snippet doc/src/snippets/code/doc_src_examples_editabletreemodel.qdoc 0
+
+    Since each items holds pieces of data for each column in a given row,
+    there can be many model indexes that map to the same \c TreeItem object.
+    For example, the information represented by \bold{b} can be obtained
+    using the following code:
+
+    \snippet doc/src/snippets/code/doc_src_examples_editabletreemodel.qdoc 1
+
+    The same underlying \c TreeItem would be accessed to obtain information
+    for the other model indexes in the same row as \bold{b}.
+    \endtable
+
+    In the model class, \c TreeModel, we relate \c TreeItem objects to
+    model indexes by passing a pointer for each item when we create its
+    corresponding model index with QAbstractItemModel::createIndex() in
+    our \l{TreeModel::index}{index()} and \l{TreeModel::parent}{parent()}
+    implementations.
+    We can retrieve pointers stored in this way by calling the
+    \l{QModelIndex::}{internalPointer()} function on the relevant model
+    index - we create our own \l{TreeModel::getItem}{getItem()} function to
+    do this work for us, and call it from our \l{TreeModel::data}{data()}
+    and \l{TreeModel::parent}{parent()} implementations.
+
+    Storing pointers to items is convenient when we control how they are
+    created and destroyed since we can assume that an address obtained from
+    \l{QModelIndex::}{internalPointer()} is a valid pointer.
+    However, some models need to handle items that are obtained from other
+    components in a system, and in many cases it is not possible to fully
+    control how items are created or destroyed. In such situations, a pure
+    pointer-based approach needs to be supplemented by safeguards to ensure
+    that the model does not attempt to access items that have been deleted.
+
+    \table
+    \row \o \bold{Storing information in the underlying data structure}
+
+    Several pieces of data are stored as QVariant objects in the \c itemData
+    member of each \c TreeItem instance
+
+    The diagram shows how pieces of information,
+    represented by the labels \bold{a}, \bold{b} and \bold{c} in the
+    previous two diagrams, are stored in items \bold{A}, \bold{B} and
+    \bold{C} in the underlying data structure. Note that pieces of
+    information from the same row in the model are all obtained from the
+    same item. Each element in a list corresponds to a piece of information
+    exposed by each column in a given row in the model.
+
+    \o \inlineimage itemviews-editabletreemodel-values.png
+    \endtable
+
+    Since the \c TreeModel implementation has been designed for use with
+    QTreeView, we have added a restriction on the way it uses \c TreeItem
+    instances: each item must expose the same number of columns of data.
+    This makes viewing the model consistent, allowing us to use the root
+    item to determine the number of columns for any given row, and only
+    adds the requirement that we create items containing enough data for
+    the total number of columns. As a result, inserting and removing
+    columns are time-consuming operations because we need to traverse the
+    entire tree to modify every item.
+
+    An alternative approach would be to design the \c TreeModel class so
+    that it truncates or expands the list of data in individual \c TreeItem
+    instances as items of data are modified. However, this "lazy" resizing
+    approach would only allow us to insert and remove columns at the end of
+    each row and would not allow columns to be inserted or removed at
+    arbitrary positions in each row.
+
+    \target Relating-items-using-model-indexes
+    \table
+    \row
+    \o \inlineimage itemviews-editabletreemodel-indexes.png
+    \o \bold{Relating items using model indexes}
+
+    As with the \l{itemviews/simpletreemodel}{Simple Tree Model} example,
+    the \c TreeModel needs to be able to take a model index, find the
+    corresponding \c TreeItem, and return model indexes that correspond to
+    its parents and children. 
+
+    In the diagram, we show how the model's \l{TreeModel::parent()}{parent()}
+    implementation obtains the model index corresponding to the parent of
+    an item supplied by the caller, using the items shown in a
+    \l{Relations-between-internal-items}{previous diagram}.
+
+    A pointer to item \bold{C} is obtained from the corresponding model index
+    using the \l{QModelIndex::internalPointer()} function. The pointer was
+    stored internally in the index when it was created. Since the child
+    contains a pointer to its parent, we use its \l{TreeItem::parent}{parent()}
+    function to obtain a pointer to item \bold{B}. The parent model index is
+    created using the QAbstractItemModel::createIndex() function, passing
+    the pointer to item \bold{B} as the internal pointer.
+    \endtable
+
+    \section1 TreeItem Class Definition
+
+    The \c TreeItem class provides simple items that contain several
+    pieces of data, and which can provide information about their parent
+    and child items:
+
+    \snippet examples/itemviews/editabletreemodel/treeitem.h 0
+
+    We have designed the API to be similar to that provided by
+    QAbstractItemModel by giving each item functions to return the number
+    of columns of information, read and write data, and insert and remove
+    columns. However, we make the relationship between items explicit by
+    providing functions to deal with "children" rather than "rows".
+
+    Each item contains a list of pointers to child items, a pointer to its
+    parent item, and a list of QVariant objects that correspond to
+    information held in columns in a given row in the model.
+
+    \section1 TreeItem Class Implementation
+
+    Each \c TreeItem is constructed with a list of data and an optional
+    parent item:
+
+    \snippet examples/itemviews/editabletreemodel/treeitem.cpp 0
+
+    Initially, each item has no children. These are added to the item's
+    internal \c childItems member using the \c insertChildren() function
+    described later.
+
+    The destructor ensures that each child added to the item is deleted
+    when the item itself is deleted:
+
+    \snippet examples/itemviews/editabletreemodel/treeitem.cpp 1
+
+    \target TreeItem::parent
+    Since each item stores a pointer to its parent, the \c parent() function
+    is trivial:
+
+    \snippet examples/itemviews/editabletreemodel/treeitem.cpp 9
+
+    \target TreeItem::child
+    Three functions provide information about the children of an item.
+    \c child() returns a specific child from the internal list of children:
+
+    \snippet examples/itemviews/editabletreemodel/treeitem.cpp 2
+
+    The \c childCount() function returns the total number of children:
+
+    \snippet examples/itemviews/editabletreemodel/treeitem.cpp 3
+
+    The \c childNumber() function is used to determine the index of the child
+    in its parent's list of children. It accesses the parent's \c childItems
+    member directly to obtain this information:
+
+    \snippet examples/itemviews/editabletreemodel/treeitem.cpp 4
+
+    The root item has no parent item; for this item, we return zero to be
+    consistent with the other items.
+
+    The \c columnCount() function simply returns the number of elements in
+    the internal \c itemData list of QVariant objects:
+
+    \snippet examples/itemviews/editabletreemodel/treeitem.cpp 5
+
+    \target TreeItem::data
+    Data is retrieved using the \c data() function, which accesses the
+    appropriate element in the \c itemData list:
+
+    \snippet examples/itemviews/editabletreemodel/treeitem.cpp 6
+
+    \target TreeItem::setData
+    Data is set using the \c setData() function, which only stores values
+    in the \c itemData list for valid list indexes, corresponding to column
+    values in the model:
+
+    \snippet examples/itemviews/editabletreemodel/treeitem.cpp 11
+
+    To make implementation of the model easier, we return true to indicate
+    whether the data was set successfully, or false if an invalid column
+
+    Editable models often need to be resizable, enabling rows and columns to
+    be inserted and removed. The insertion of rows beneath a given model index
+    in the model leads to the insertion of new child items in the corresponding
+    item, handled by the \c insertChildren() function:
+
+    \snippet examples/itemviews/editabletreemodel/treeitem.cpp 7
+
+    This ensures that new items are created with the required number of columns
+    and inserted at a valid position in the internal \c childItems list.
+    Items are removed with the \c removeChildren() function:
+
+    \snippet examples/itemviews/editabletreemodel/treeitem.cpp 10
+
+    As discussed above, the functions for inserting and removing columns are
+    used differently to those for inserting and removing child items because
+    they are expected to be called on every item in the tree. We do this by
+    recursively calling this function on each child of the item:
+
+    \snippet examples/itemviews/editabletreemodel/treeitem.cpp 8
+
+    \section1 TreeModel Class Definition
+
+    The \c TreeModel class provides an implementation of the QAbstractItemModel
+    class, exposing the necessary interface for a model that can be edited and
+    resized.
+
+    \snippet examples/itemviews/editabletreemodel/treemodel.h 0
+
+    The constructor and destructor are specific to this model.
+
+    \snippet examples/itemviews/editabletreemodel/treemodel.h 1
+
+    Read-only tree models only need to provide the above functions. The
+    following public functions provide support for editing and resizing:
+
+    \snippet examples/itemviews/editabletreemodel/treemodel.h 2
+
+    To simplify this example, the data exposed by the model is organized into
+    a data structure by the model's \l{TreeModel::setupModelData}{setupModelData()}
+    function. Many real world models will not process the raw data at all, but
+    simply work with an existing data structure or library API.
+
+    \section1 TreeModel Class Implementation
+
+    The constructor creates a root item and initializes it with the header
+    data supplied:
+
+    \snippet examples/itemviews/editabletreemodel/treemodel.cpp 0
+
+    We call the internal \l{TreeModel::setupModelData}{setupModelData()}
+    function to convert the textual data supplied to a data structure we can
+    use with the model. Other models may be initialized with a ready-made
+    data structure, or use an API to a library that maintains its own data.
+
+    The destructor only has to delete the root item; all child items will
+    be recursively deleted by the \c TreeItem destructor.
+
+    \snippet examples/itemviews/editabletreemodel/treemodel.cpp 1
+
+    \target TreeModel::getItem
+    Since the model's interface to the other model/view components is based
+    on model indexes, and the internal data structure is item-based, many of
+    the functions implemented by the model need to be able to convert any
+    given model index to its corresponding item. For convenience and
+    consistency, we have defined a \c getItem() function to perform this
+    repetitive task:
+
+    \snippet examples/itemviews/editabletreemodel/treemodel.cpp 4
+
+    This function assumes that each model index it is passed corresponds to
+    a valid item in memory. If the index is invalid, or its internal pointer
+    does not refer to a valid item, the root item is returned instead.
+
+    The model's \c rowCount() implementation is simple: it first uses the
+    \c getItem() function to obtain the relevant item, then returns the
+    number of children it contains:
+
+    \snippet examples/itemviews/editabletreemodel/treemodel.cpp 8
+
+    By contrast, the \c columnCount() implementation does not need to look
+    for a particular item because all items are defined to have the same
+    number of columns associated with them.
+
+    \snippet examples/itemviews/editabletreemodel/treemodel.cpp 2
+
+    As a result, the number of columns can be obtained directly from the root
+    item.
+
+    To enable items to be edited and selected, the \c flags() function needs
+    to be implemented so that it returns a combination of flags that includes
+    the Qt::ItemIsEditable and Qt::ItemIsSelectable flags as well as
+    Qt::ItemIsEnabled:
+
+    \snippet examples/itemviews/editabletreemodel/treemodel.cpp 3
+
+    \target TreeModel::index
+    The model needs to be able to generate model indexes to allow other
+    components to request data and information about its structure. This task
+    is performed by the \c index() function, which is used to obtain model
+    indexes corresponding to children of a given parent item:
+
+    \snippet examples/itemviews/editabletreemodel/treemodel.cpp 5
+
+    In this model, we only return model indexes for child items if the parent
+    index is invalid (corresponding to the root item) or if it has a zero
+    column number.
+
+    We use the custom \l{TreeModel::getItem}{getItem()} function to obtain
+    a \c TreeItem instance that corresponds to the model index supplied, and
+    request its child item that corresponds to the specified row.
+
+    \snippet examples/itemviews/editabletreemodel/treemodel.cpp 6
+
+    Since each item contains information for an entire row of data, we create
+    a model index to uniquely identify it by calling
+    \l{QAbstractItemModel::}{createIndex()} it with the row and column numbers
+    and a pointer to the item. In the \l{TreeModel::data}{data()} function,
+    we will use the item pointer and column number to access the data
+    associated with the model index; in this model, the row number is not
+    needed to identify data.
+
+    \target TreeModel::parent
+    The \c parent() function supplies model indexes for parents of items
+    by finding the corresponding item for a given model index, using its
+    \l{TreeItem::parent}{parent()} function to obtain its parent item,
+    then creating a model index to represent the parent. (See
+    \l{Relating-items-using-model-indexes}{the above diagram}).
+
+    \snippet examples/itemviews/editabletreemodel/treemodel.cpp 7
+
+    Items without parents, including the root item, are handled by returning
+    a null model index. Otherwise, a model index is created and returned as
+    in the \l{TreeModel::index}{index()} function, with a suitable row number,
+    but with a zero column number to be consistent with the scheme used in
+    the \l{TreeModel::index}{index()} implementation.
+
+    \target TreeModel::data
+    \target TreeModel::setupModelData
+
+*/