src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
    75     Q_DECLARE_PUBLIC(QDeclarativeVisualItemModel)
    75     Q_DECLARE_PUBLIC(QDeclarativeVisualItemModel)
    76 public:
    76 public:
    77     QDeclarativeVisualItemModelPrivate() : QObjectPrivate() {}
    77     QDeclarativeVisualItemModelPrivate() : QObjectPrivate() {}
    78 
    78 
    79     static void children_append(QDeclarativeListProperty<QDeclarativeItem> *prop, QDeclarativeItem *item) {
    79     static void children_append(QDeclarativeListProperty<QDeclarativeItem> *prop, QDeclarativeItem *item) {
    80         item->QObject::setParent(prop->object);
    80         QDeclarative_setParent_noEvent(item, prop->object);
    81         static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->children.append(item);
    81         static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->children.append(item);
    82         static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->itemAppended();
    82         static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->itemAppended();
    83         static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->emitChildrenChanged();
    83         static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->emitChildrenChanged();
    84     }
    84     }
    85 
    85 
   111 /*!
   111 /*!
   112     \qmlclass VisualItemModel QDeclarativeVisualItemModel
   112     \qmlclass VisualItemModel QDeclarativeVisualItemModel
   113   \since 4.7
   113   \since 4.7
   114     \brief The VisualItemModel allows items to be provided to a view.
   114     \brief The VisualItemModel allows items to be provided to a view.
   115 
   115 
   116     The children of the VisualItemModel are provided in a model which
   116     A VisualItemModel contains the visual items to be used in a view.
   117     can be used in a view.  Note that no delegate should be
   117     When a VisualItemModel is used in a view, the view does not require
   118     provided to a view since the VisualItemModel contains the
   118     a delegate since the VisualItemModel already contains the visual
   119     visual delegate (items).
   119     delegate (items).
   120 
   120 
   121     An item can determine its index within the
   121     An item can determine its index within the
   122     model via the VisualItemModel.index attached property.
   122     model via the \l{VisualItemModel::index}{index} attached property.
   123 
   123 
   124     The example below places three colored rectangles in a ListView.
   124     The example below places three colored rectangles in a ListView.
   125     \code
   125     \code
   126     Item {
   126     import Qt 4.7
       
   127 
       
   128     Rectangle {
   127         VisualItemModel {
   129         VisualItemModel {
   128             id: itemModel
   130             id: itemModel
   129             Rectangle { height: 30; width: 80; color: "red" }
   131             Rectangle { height: 30; width: 80; color: "red" }
   130             Rectangle { height: 30; width: 80; color: "green" }
   132             Rectangle { height: 30; width: 80; color: "green" }
   131             Rectangle { height: 30; width: 80; color: "blue" }
   133             Rectangle { height: 30; width: 80; color: "blue" }
   135             anchors.fill: parent
   137             anchors.fill: parent
   136             model: itemModel
   138             model: itemModel
   137         }
   139         }
   138     }
   140     }
   139     \endcode
   141     \endcode
       
   142 
       
   143     \image visualitemmodel.png
       
   144 
       
   145     \sa {declarative/modelviews/visualitemmodel}{VisualItemModel example}
   140 */
   146 */
   141 QDeclarativeVisualItemModel::QDeclarativeVisualItemModel(QObject *parent)
   147 QDeclarativeVisualItemModel::QDeclarativeVisualItemModel(QObject *parent)
   142     : QDeclarativeVisualModel(*(new QDeclarativeVisualItemModelPrivate), parent)
   148     : QDeclarativeVisualModel(*(new QDeclarativeVisualItemModelPrivate), parent)
   143 {
   149 {
   144 }
   150 }
   145 
   151 
       
   152 /*!
       
   153     \qmlattachedproperty int VisualItemModel::index
       
   154     This attached property holds the index of this delegate's item within the model.
       
   155 
       
   156     It is attached to each instance of the delegate.
       
   157 */
       
   158 
   146 QDeclarativeListProperty<QDeclarativeItem> QDeclarativeVisualItemModel::children()
   159 QDeclarativeListProperty<QDeclarativeItem> QDeclarativeVisualItemModel::children()
   147 {
   160 {
   148     Q_D(QDeclarativeVisualItemModel);
   161     Q_D(QDeclarativeVisualItemModel);
   149     return QDeclarativeListProperty<QDeclarativeItem>(this, d, d->children_append,
   162     return QDeclarativeListProperty<QDeclarativeItem>(this, d, d->children_append,
   150                                                       d->children_count, d->children_at);
   163                                                       d->children_count, d->children_at);
   170 {
   183 {
   171     Q_D(QDeclarativeVisualItemModel);
   184     Q_D(QDeclarativeVisualItemModel);
   172     return d->children.at(index);
   185     return d->children.at(index);
   173 }
   186 }
   174 
   187 
   175 QDeclarativeVisualModel::ReleaseFlags QDeclarativeVisualItemModel::release(QDeclarativeItem *)
   188 QDeclarativeVisualModel::ReleaseFlags QDeclarativeVisualItemModel::release(QDeclarativeItem *item)
   176 {
   189 {
   177     // Nothing to do
   190     if (item->scene())
       
   191         item->scene()->removeItem(item);
       
   192     QDeclarative_setParent_noEvent(item, this);
   178     return 0;
   193     return 0;
   179 }
   194 }
   180 
   195 
   181 bool QDeclarativeVisualItemModel::completePending() const
   196 bool QDeclarativeVisualItemModel::completePending() const
   182 {
   197 {
   268                     m_roleNames.insert(*it, it.key());
   283                     m_roleNames.insert(*it, it.key());
   269                 }
   284                 }
   270                 if (m_roles.count() == 1)
   285                 if (m_roles.count() == 1)
   271                     m_roleNames.insert("modelData", m_roles.at(0));
   286                     m_roleNames.insert("modelData", m_roles.at(0));
   272                 if (m_roles.count())
   287                 if (m_roles.count())
   273                     m_roleNames.insert("hasModelChildren", 0);
   288                     m_roleNames.insert("hasModelChildren", -1);
   274             } else if (m_listAccessor) {
   289             } else if (m_listAccessor) {
   275                 m_roleNames.insert("modelData", 0);
   290                 m_roleNames.insert("modelData", 0);
   276                 if (m_listAccessor->type() == QDeclarativeListAccessor::Instance) {
   291                 if (m_listAccessor->type() == QDeclarativeListAccessor::Instance) {
   277                     if (QObject *object = m_listAccessor->at(0).value<QObject*>()) {
   292                     if (QObject *object = m_listAccessor->at(0).value<QObject*>()) {
   278                         int count = object->metaObject()->propertyCount();
   293                         int count = object->metaObject()->propertyCount();
   603     \brief The VisualDataModel encapsulates a model and delegate
   618     \brief The VisualDataModel encapsulates a model and delegate
   604 
   619 
   605     A VisualDataModel encapsulates a model and the delegate that will
   620     A VisualDataModel encapsulates a model and the delegate that will
   606     be instantiated for items in the model.
   621     be instantiated for items in the model.
   607 
   622 
   608     It is usually not necessary to create a VisualDataModel directly,
   623     It is usually not necessary to create VisualDataModel elements.
   609     since the QML views will create one internally.
   624     However, it can be useful for manipulating and accessing the \l modelIndex 
       
   625     when a QAbstractItemModel subclass is used as the 
       
   626     model. Also, VisualDataModel is used together with \l Package to 
       
   627     provide delegates to multiple views.
   610 
   628 
   611     The example below illustrates using a VisualDataModel with a ListView.
   629     The example below illustrates using a VisualDataModel with a ListView.
   612 
   630 
   613     \code
   631     \snippet doc/src/snippets/declarative/visualdatamodel.qml 0
   614     VisualDataModel {
       
   615         id: visualModel
       
   616         model: myModel
       
   617         delegate: Component {
       
   618             Rectangle {
       
   619                 height: 25
       
   620                 width: 100
       
   621                 Text { text: "Name:" + name}
       
   622             }
       
   623         }
       
   624     }
       
   625     ListView {
       
   626         width: 100
       
   627         height: 100
       
   628         anchors.fill: parent
       
   629         model: visualModel
       
   630     }
       
   631     \endcode
       
   632 */
   632 */
   633 
   633 
   634 QDeclarativeVisualDataModel::QDeclarativeVisualDataModel()
   634 QDeclarativeVisualDataModel::QDeclarativeVisualDataModel()
   635 : QDeclarativeVisualModel(*(new QDeclarativeVisualDataModelPrivate(0)))
   635 : QDeclarativeVisualModel(*(new QDeclarativeVisualDataModelPrivate(0)))
   636 {
   636 {
   801 }
   801 }
   802 
   802 
   803 /*!
   803 /*!
   804     \qmlproperty QModelIndex VisualDataModel::rootIndex
   804     \qmlproperty QModelIndex VisualDataModel::rootIndex
   805 
   805 
   806     QAbstractItemModel provides a heirachical tree of data, whereas
   806     QAbstractItemModel provides a hierarchical tree of data, whereas
   807     QML only operates on list data.  \c rootIndex allows the children of
   807     QML only operates on list data.  \c rootIndex allows the children of
   808     any node in a QAbstractItemModel to be provided by this model.
   808     any node in a QAbstractItemModel to be provided by this model.
   809 
   809 
   810     This property only affects models of type QAbstractItemModel.
   810     This property only affects models of type QAbstractItemModel.
   811 
   811 
   812     \code
   812     For example, here is a simple interactive file system browser.
   813     // main.cpp
   813     When a directory name is clicked, the view's \c rootIndex is set to the
   814 
   814     QModelIndex node of the clicked directory, thus updating the view to show
   815     int main(int argc, char ** argv)
   815     the new directory's contents.
   816     {
   816 
   817         QApplication app(argc, argv);
   817     \c main.cpp:
   818 
   818     \snippet doc/src/snippets/declarative/visualdatamodel_rootindex/main.cpp 0
   819         QDeclarativeView view;
   819    
   820 
   820     \c view.qml:
   821         QDirModel model;
   821     \snippet doc/src/snippets/declarative/visualdatamodel_rootindex/view.qml 0
   822         view.rootContext()->setContextProperty("myModel", &model);
   822 
   823 
   823     If the \l model is a QAbstractItemModel subclass, the delegate can also
   824         view.setSource(QUrl("qrc:view.qml"));
   824     reference a \c hasModelChildren property (optionally qualified by a
   825         view.show();
   825     \e model. prefix) that indicates whether the delegate's model item has 
   826 
   826     any child nodes.
   827         return app.exec();
   827 
   828     }
       
   829 
       
   830     #include "main.moc"
       
   831     \endcode
       
   832 
       
   833     \code
       
   834     // view.qml
       
   835     import Qt 4.7
       
   836 
       
   837     ListView {
       
   838         id: view
       
   839         width: 200
       
   840         height: 200
       
   841         model: VisualDataModel {
       
   842             model: myModel
       
   843             delegate: Component {
       
   844                 Rectangle {
       
   845                     height: 25; width: 200
       
   846                     Text { text: filePath }
       
   847                     MouseArea {
       
   848                         anchors.fill: parent;
       
   849                         onClicked: if (hasModelChildren) view.model.rootIndex = view.model.modelIndex(index)
       
   850                     }
       
   851                 }
       
   852             }
       
   853         }
       
   854     }
       
   855     \endcode
       
   856 
   828 
   857     \sa modelIndex(), parentModelIndex()
   829     \sa modelIndex(), parentModelIndex()
   858 */
   830 */
   859 QVariant QDeclarativeVisualDataModel::rootIndex() const
   831 QVariant QDeclarativeVisualDataModel::rootIndex() const
   860 {
   832 {
   882 
   854 
   883 
   855 
   884 /*!
   856 /*!
   885     \qmlmethod QModelIndex VisualDataModel::modelIndex(int index)
   857     \qmlmethod QModelIndex VisualDataModel::modelIndex(int index)
   886 
   858 
   887     QAbstractItemModel provides a heirachical tree of data, whereas
   859     QAbstractItemModel provides a hierarchical tree of data, whereas
   888     QML only operates on list data.  This function assists in using
   860     QML only operates on list data.  This function assists in using
   889     tree models in QML.
   861     tree models in QML.
   890 
   862 
   891     Returns a QModelIndex for the specified index.
   863     Returns a QModelIndex for the specified index.
   892     This value can be assigned to rootIndex.
   864     This value can be assigned to rootIndex.
   902 }
   874 }
   903 
   875 
   904 /*!
   876 /*!
   905     \qmlmethod QModelIndex VisualDataModel::parentModelIndex()
   877     \qmlmethod QModelIndex VisualDataModel::parentModelIndex()
   906 
   878 
   907     QAbstractItemModel provides a heirachical tree of data, whereas
   879     QAbstractItemModel provides a hierarchical tree of data, whereas
   908     QML only operates on list data.  This function assists in using
   880     QML only operates on list data.  This function assists in using
   909     tree models in QML.
   881     tree models in QML.
   910 
   882 
   911     Returns a QModelIndex for the parent of the current rootIndex.
   883     Returns a QModelIndex for the parent of the current rootIndex.
   912     This value can be assigned to rootIndex.
   884     This value can be assigned to rootIndex.
   996 /*!
   968 /*!
   997     \qmlproperty object VisualDataModel::parts
   969     \qmlproperty object VisualDataModel::parts
   998 
   970 
   999     The \a parts property selects a VisualDataModel which creates
   971     The \a parts property selects a VisualDataModel which creates
  1000     delegates from the part named.  This is used in conjunction with
   972     delegates from the part named.  This is used in conjunction with
  1001     the Package element.
   973     the \l Package element.
  1002 
   974 
  1003     For example, the code below selects a model which creates
   975     For example, the code below selects a model which creates
  1004     delegates named \e list from a Package:
   976     delegates named \e list from a \l Package:
  1005 
   977 
  1006     \code
   978     \code
  1007     VisualDataModel {
   979     VisualDataModel {
  1008         id: visualModel
   980         id: visualModel
  1009         delegate: Package {
   981         delegate: Package {
  1116 QString QDeclarativeVisualDataModel::stringValue(int index, const QString &name)
  1088 QString QDeclarativeVisualDataModel::stringValue(int index, const QString &name)
  1117 {
  1089 {
  1118     Q_D(QDeclarativeVisualDataModel);
  1090     Q_D(QDeclarativeVisualDataModel);
  1119     if (d->m_visualItemModel)
  1091     if (d->m_visualItemModel)
  1120         return d->m_visualItemModel->stringValue(index, name);
  1092         return d->m_visualItemModel->stringValue(index, name);
       
  1093 
       
  1094     if ((!d->m_listModelInterface || !d->m_abstractItemModel) && d->m_listAccessor) {
       
  1095         if (QObject *object = d->m_listAccessor->at(index).value<QObject*>())
       
  1096             return object->property(name.toUtf8()).toString();
       
  1097     }
  1121 
  1098 
  1122     if ((!d->m_listModelInterface && !d->m_abstractItemModel) || !d->m_delegate)
  1099     if ((!d->m_listModelInterface && !d->m_abstractItemModel) || !d->m_delegate)
  1123         return QString();
  1100         return QString();
  1124 
  1101 
  1125     QString val;
  1102     QString val;