Qt 4.8
qdeclarativelistmodel.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "private/qdeclarativelistmodel_p_p.h"
43 #include "private/qdeclarativelistmodelworkeragent_p.h"
44 #include "private/qdeclarativeopenmetaobject_p.h"
45 
47 #include <qdeclarativeparser_p.h>
48 #include <qdeclarativeengine_p.h>
49 #include <qdeclarativecontext.h>
50 #include <qdeclarativeinfo.h>
51 
52 #include <QtCore/qdebug.h>
53 #include <QtCore/qstack.h>
54 #include <QXmlStreamReader>
55 #include <QtScript/qscriptvalueiterator.h>
56 
58 
60 
61 template<typename T>
62 void qdeclarativelistmodel_move(int from, int to, int n, T *items)
63 {
64  if (n == 1) {
65  items->move(from, to);
66  } else {
67  T replaced;
68  int i=0;
69  typename T::ConstIterator it=items->begin(); it += from+n;
70  for (; i<to-from; ++i,++it)
71  replaced.append(*it);
72  i=0;
73  it=items->begin(); it += from;
74  for (; i<n; ++i,++it)
75  replaced.append(*it);
76  typename T::ConstIterator f=replaced.begin();
77  typename T::Iterator t=items->begin(); t += from;
78  for (; f != replaced.end(); ++f, ++t)
79  *t = *f;
80  }
81 }
82 
84 {
85  return (QDeclarativeListModelParser::ListInstruction *)((char *)this + sizeof(ListModelData));
86 }
87 
208 /*
209  A ListModel internally uses either a NestedListModel or FlatListModel.
210 
211  A NestedListModel can contain lists of ListElements (which
212  when retrieved from get() is accessible as a list model within the list
213  model) whereas a FlatListModel cannot.
214 
215  ListModel uses a NestedListModel to begin with, and if the model is later
216  used from a WorkerScript, it changes to use a FlatListModel instead. This
217  is because ModelNode (which abstracts the nested list model data) needs
218  access to the declarative engine and script engine, which cannot be
219  safely used from outside of the main thread.
220 */
221 
223 : QListModelInterface(parent), m_agent(0), m_nested(new NestedListModel(this)), m_flat(0)
224 {
225 }
226 
228 : QListModelInterface(parent), m_agent(0), m_nested(0), m_flat(0)
229 {
230  m_flat = new FlatListModel(this);
232 
233  if (orig->m_flat) {
234  m_flat->m_roles = orig->m_flat->m_roles;
235  m_flat->m_strings = orig->m_flat->m_strings;
236  m_flat->m_values = orig->m_flat->m_values;
237 
239  for (int i=0; i<m_flat->m_values.count(); i++)
240  m_flat->m_nodeData << 0;
241  }
242 }
243 
245 {
246  if (m_agent)
247  m_agent->release();
248 
249  delete m_nested;
250  delete m_flat;
251 }
252 
254 {
255  if (m_flat)
256  return true;
257 
259 
261  bool hasNested = false;
262  for (int i=0; i<m_nested->count(); i++) {
263  values.append(m_nested->data(i, roles, &hasNested));
264  if (hasNested)
265  return false;
266  }
267 
268  FlatListModel *flat = new FlatListModel(this);
269  flat->m_values = values;
270 
271  for (int i=0; i<roles.count(); i++) {
272  QString s = m_nested->toString(roles[i]);
273  flat->m_roles.insert(roles[i], s);
274  flat->m_strings.insert(s, roles[i]);
275  }
276 
277  flat->m_nodeData.reserve(flat->m_values.count());
278  for (int i=0; i<flat->m_values.count(); i++)
279  flat->m_nodeData << 0;
280 
281  m_flat = flat;
282  delete m_nested;
283  m_nested = 0;
284  return true;
285 }
286 
288 {
289  return m_flat && m_flat->m_parentAgent;
290 }
291 
293 {
294  if (m_agent)
295  return m_agent;
296 
297  if (!flatten()) {
298  qmlInfo(this) << "List contains list-type data and cannot be used from a worker script";
299  return 0;
300  }
301 
303  return m_agent;
304 }
305 
307 {
308  return m_flat ? m_flat->roles() : m_nested->roles();
309 }
310 
312 {
313  return m_flat ? m_flat->toString(role) : m_nested->toString(role);
314 }
315 
317 {
318  if (index >= count() || index < 0)
319  return QVariant();
320 
321  return m_flat ? m_flat->data(index, role) : m_nested->data(index, role);
322 }
323 
332 {
333  return m_flat ? m_flat->count() : m_nested->count();
334 }
335 
347 {
348  int cleared = count();
349  if (m_flat)
350  m_flat->clear();
351  else
352  m_nested->clear();
353 
354  if (!inWorkerThread()) {
355  emit itemsRemoved(0, cleared);
356  emit countChanged();
357  }
358 }
359 
361 {
362  if (!modelCache) {
363  modelCache = new QDeclarativeListModel;
365  modelCache->m_nested->_root = this; // ListModel defaults to nestable model
366 
367  for (int i=0; i<values.count(); ++i) {
368  ModelNode *subNode = qvariant_cast<ModelNode *>(values.at(i));
369  if (subNode)
370  subNode->m_model = modelCache->m_nested;
371  }
372  }
373  return modelCache;
374 }
375 
377 {
378  if (!objectCache) {
379  objectCache = new ModelObject(this,
380  const_cast<NestedListModel*>(model),
383  for (it = properties.begin(); it != properties.end(); ++it) {
384  objectCache->setValue(it.key().toUtf8(), model->valueForNode(*it));
385  }
386  objectCache->setNodeUpdatesEnabled(true);
387  }
388  return objectCache;
389 }
390 
402 {
403  if (index < 0 || index >= count()) {
404  qmlInfo(this) << tr("remove: index %1 out of range").arg(index);
405  return;
406  }
407 
408  if (m_flat)
409  m_flat->remove(index);
410  else
411  m_nested->remove(index);
412 
413  if (!inWorkerThread()) {
414  emit itemsRemoved(index, 1);
415  emit countChanged();
416  }
417 }
418 
438 {
439  if (!valuemap.isObject() || valuemap.isArray()) {
440  qmlInfo(this) << tr("insert: value is not an object");
441  return;
442  }
443 
444  if (index < 0 || index > count()) {
445  qmlInfo(this) << tr("insert: index %1 out of range").arg(index);
446  return;
447  }
448 
449  bool ok = m_flat ? m_flat->insert(index, valuemap) : m_nested->insert(index, valuemap);
450  if (ok && !inWorkerThread()) {
451  emit itemsInserted(index, 1);
452  emit countChanged();
453  }
454 }
455 
473 void QDeclarativeListModel::move(int from, int to, int n)
474 {
475  if (n==0 || from==to)
476  return;
477  if (!canMove(from, to, n)) {
478  qmlInfo(this) << tr("move: out of range");
479  return;
480  }
481 
482  int origfrom = from;
483  int origto = to;
484  int orign = n;
485  if (from > to) {
486  // Only move forwards - flip if backwards moving
487  int tfrom = from;
488  int tto = to;
489  from = tto;
490  to = tto+n;
491  n = tfrom-tto;
492  }
493 
494  if (m_flat)
495  m_flat->move(from, to, n);
496  else
497  m_nested->move(from, to, n);
498 
499  if (!inWorkerThread())
500  emit itemsMoved(origfrom, origto, orign);
501 }
502 
519 {
520  if (!valuemap.isObject() || valuemap.isArray()) {
521  qmlInfo(this) << tr("append: value is not an object");
522  return;
523  }
524 
525  insert(count(), valuemap);
526 }
527 
563 {
564  // the internal flat/nested class checks for bad index
565  return m_flat ? m_flat->get(index) : m_nested->get(index);
566 }
567 
588 {
590  set(index, valuemap, &roles);
591  if (!roles.isEmpty() && !inWorkerThread())
592  emit itemsChanged(index, 1, roles);
593 }
594 
596 {
597  if (!valuemap.isObject() || valuemap.isArray()) {
598  qmlInfo(this) << tr("set: value is not an object");
599  return;
600  }
601  if (index > count() || index < 0) {
602  qmlInfo(this) << tr("set: index %1 out of range").arg(index);
603  return;
604  }
605 
606  if (index == count()) {
607  append(valuemap);
608  } else {
609  if (m_flat)
610  m_flat->set(index, valuemap, roles);
611  else
612  m_nested->set(index, valuemap, roles);
613  }
614 }
615 
633 {
635  setProperty(index, property, value, &roles);
636  if (!roles.isEmpty() && !inWorkerThread())
637  emit itemsChanged(index, 1, roles);
638 }
639 
641 {
642  if (count() == 0 || index >= count() || index < 0) {
643  qmlInfo(this) << tr("set: index %1 out of range").arg(index);
644  return;
645  }
646 
647  if (m_flat)
648  m_flat->setProperty(index, property, value, roles);
649  else
650  m_nested->setProperty(index, property, value, roles);
651 }
652 
663 {
664  // This is just a dummy method to make it look like sync() exists in
665  // ListModel (and not just QDeclarativeListModelWorkerAgent) and to let
666  // us document sync().
667  qmlInfo(this) << "List sync() can only be called from a WorkerScript";
668 }
669 
671 {
673  for(int ii = 0; ii < values.count(); ++ii) {
674  const QVariant &value = values.at(ii);
675 
676  if(value.userType() == qMetaTypeId<QDeclarativeCustomParserNode>()) {
679 
680  if (node.name() != listElementTypeName) {
681  const QMetaObject *mo = resolveType(node.name());
683  error(node, QDeclarativeListModel::tr("ListElement: cannot contain nested elements"));
684  return false;
685  }
686  listElementTypeName = node.name(); // cache right name for next time
687  }
688 
689  {
690  ListInstruction li;
691  li.type = ListInstruction::Push;
692  li.dataIdx = -1;
693  instr << li;
694  }
695 
697  for(int jj = 0; jj < props.count(); ++jj) {
698  const QDeclarativeCustomParserProperty &nodeProp = props.at(jj);
699  if (nodeProp.name().isEmpty()) {
700  error(nodeProp, QDeclarativeListModel::tr("ListElement: cannot contain nested elements"));
701  return false;
702  }
703  if (nodeProp.name() == "id") {
704  error(nodeProp, QDeclarativeListModel::tr("ListElement: cannot use reserved \"id\" property"));
705  return false;
706  }
707 
708  ListInstruction li;
709  int ref = data.count();
710  data.append(nodeProp.name());
711  data.append('\0');
712  li.type = ListInstruction::Set;
713  li.dataIdx = ref;
714  instr << li;
715 
716  if(!compileProperty(nodeProp, instr, data))
717  return false;
718 
719  li.type = ListInstruction::Pop;
720  li.dataIdx = -1;
721  instr << li;
722  }
723 
724  {
725  ListInstruction li;
726  li.type = ListInstruction::Pop;
727  li.dataIdx = -1;
728  instr << li;
729  }
730 
731  } else {
732 
735 
736  int ref = data.count();
737 
738  QByteArray d;
739  d += char(variant.type()); // type tag
740  if (variant.isString()) {
741  d += variant.asString().toUtf8();
742  } else if (variant.isNumber()) {
743  double temp = variant.asNumber();
744  d += QByteArray( reinterpret_cast<const char*>(&temp), sizeof(double));
745  } else if (variant.isBoolean()) {
746  d += char(variant.asBoolean());
747  } else if (variant.isScript()) {
748  if (definesEmptyList(variant.asScript())) {
749  d[0] = char(QDeclarativeParser::Variant::Invalid); // marks empty list
750  } else {
751  QByteArray script = variant.asScript().toUtf8();
752  int v = evaluateEnum(script);
753  if (v<0) {
754  if (script.startsWith("QT_TR_NOOP(\"") && script.endsWith("\")")) {
756  d += script.mid(12,script.length()-14);
757  } else {
758  error(prop, QDeclarativeListModel::tr("ListElement: cannot use script for property value"));
759  return false;
760  }
761  } else {
763  double temp = v;
764  d += QByteArray( reinterpret_cast<const char*>(&temp), sizeof(double));
765  }
766  }
767  }
768  d.append('\0');
769  data.append(d);
770 
771  ListInstruction li;
772  li.type = ListInstruction::Value;
773  li.dataIdx = ref;
774  instr << li;
775  }
776  }
777 
778  return true;
779 }
780 
782 {
785  listElementTypeName = QByteArray(); // unknown
786 
787  for(int ii = 0; ii < customProps.count(); ++ii) {
788  const QDeclarativeCustomParserProperty &prop = customProps.at(ii);
789  if(!prop.name().isEmpty()) { // isn't default property
790  error(prop, QDeclarativeListModel::tr("ListModel: undefined property '%1'").arg(QString::fromUtf8(prop.name())));
791  return QByteArray();
792  }
793 
794  if(!compileProperty(prop, instr, data)) {
795  return QByteArray();
796  }
797  }
798 
799  int size = sizeof(ListModelData) +
800  instr.count() * sizeof(ListInstruction) +
801  data.count();
802 
803  QByteArray rv;
804  rv.resize(size);
805 
806  ListModelData *lmd = (ListModelData *)rv.data();
807  lmd->dataOffset = sizeof(ListModelData) +
808  instr.count() * sizeof(ListInstruction);
809  lmd->instrCount = instr.count();
810  for (int ii = 0; ii < instr.count(); ++ii)
811  lmd->instructions()[ii] = instr.at(ii);
812  ::memcpy(rv.data() + lmd->dataOffset, data.constData(), data.count());
813 
814  return rv;
815 }
816 
818 {
819  QDeclarativeListModel *rv = static_cast<QDeclarativeListModel *>(obj);
820  ModelNode *root = new ModelNode(rv->m_nested);
821  rv->m_nested->m_ownsRoot = true;
822  rv->m_nested->_root = root;
823  QStack<ModelNode *> nodes;
824  nodes << root;
825 
826  bool processingSet = false;
827 
828  const ListModelData *lmd = (const ListModelData *)d.constData();
829  const char *data = ((const char *)lmd) + lmd->dataOffset;
830 
831  for (int ii = 0; ii < lmd->instrCount; ++ii) {
832  const ListInstruction &instr = lmd->instructions()[ii];
833 
834  switch(instr.type) {
835  case ListInstruction::Push:
836  {
837  ModelNode *n = nodes.top();
838  ModelNode *n2 = new ModelNode(rv->m_nested);
839  n->values << QVariant::fromValue(n2);
840  nodes.push(n2);
841  if (processingSet)
842  n->isArray = true;
843  }
844  break;
845 
846  case ListInstruction::Pop:
847  nodes.pop();
848  break;
849 
850  case ListInstruction::Value:
851  {
852  ModelNode *n = nodes.top();
853  switch (QDeclarativeParser::Variant::Type(data[instr.dataIdx])) {
855  n->isArray = true;
856  break;
858  n->values.append(bool(data[1 + instr.dataIdx]));
859  break;
861  double temp;
862  ::memcpy(&temp, data + 1 + instr.dataIdx, sizeof(double));
863  n->values.append(temp);
864  break;
866  n->values.append(QString::fromUtf8(data + 1 + instr.dataIdx));
867  break;
868  default:
869  Q_ASSERT("Format error in ListInstruction");
870  }
871 
872  processingSet = false;
873  }
874  break;
875 
876  case ListInstruction::Set:
877  {
878  ModelNode *n = nodes.top();
879  ModelNode *n2 = new ModelNode(rv->m_nested);
880  n->properties.insert(QString::fromUtf8(data + instr.dataIdx), n2);
881  nodes.push(n2);
882  processingSet = true;
883  }
884  break;
885  }
886  }
887 
888  ModelNode *rootNode = rv->m_nested->_root;
889  for (int i=0; i<rootNode->values.count(); ++i) {
890  ModelNode *node = qvariant_cast<ModelNode *>(rootNode->values[i]);
891  node->listIndex = i;
892  node->updateListIndexes();
893  }
894 }
895 
897 {
898  if (s.startsWith(QLatin1Char('[')) && s.endsWith(QLatin1Char(']'))) {
899  for (int i=1; i<s.length()-1; i++) {
900  if (!s[i].isSpace())
901  return false;
902  }
903  return true;
904  }
905  return false;
906 }
907 
908 
955  : m_scriptEngine(0), m_listModel(base), m_scriptClass(0), m_parentAgent(0)
956 {
957 }
958 
960 {
962 }
963 
964 QVariant FlatListModel::data(int index, int role) const
965 {
966  Q_ASSERT(index >= 0 && index < m_values.count());
967  if (m_values[index].contains(role))
968  return m_values[index][role];
969  return QVariant();
970 }
971 
973 {
974  return m_roles.keys();
975 }
976 
978 {
979  if (m_roles.contains(role))
980  return m_roles[role];
981  return QString();
982 }
983 
985 {
986  return m_values.count();
987 }
988 
990 {
991  m_values.clear();
992 
994  m_nodeData.clear();
995 }
996 
998 {
999  m_values.removeAt(index);
1000  removedNode(index);
1001 }
1002 
1004 {
1005  Q_ASSERT(index >= 0 && index <= m_values.count());
1006 
1008  if (!addValue(value, &row, 0))
1009  return false;
1010 
1011  m_values.insert(index, row);
1012  insertedNode(index);
1013 
1014  return true;
1015 }
1016 
1018 {
1020 
1021  if (!scriptEngine)
1022  return 0;
1023 
1024  if (index < 0 || index >= m_values.count())
1025  return scriptEngine->undefinedValue();
1026 
1027  FlatListModel *that = const_cast<FlatListModel*>(this);
1028  if (!m_scriptClass)
1029  that->m_scriptClass = new FlatListScriptClass(that, scriptEngine);
1030 
1031  FlatNodeData *data = m_nodeData.value(index);
1032  if (!data) {
1033  data = new FlatNodeData(index);
1034  that->m_nodeData.replace(index, data);
1035  }
1036 
1037  return QScriptDeclarativeClass::newObject(scriptEngine, m_scriptClass, new FlatNodeObjectData(data));
1038 }
1039 
1041 {
1042  Q_ASSERT(index >= 0 && index < m_values.count());
1043 
1045  if (addValue(value, &row, roles))
1046  m_values[index] = row;
1047 }
1048 
1050 {
1051  Q_ASSERT(index >= 0 && index < m_values.count());
1052 
1053  QHash<QString, int>::Iterator iter = m_strings.find(property);
1054  int role;
1055  if (iter == m_strings.end()) {
1056  role = m_roles.count();
1057  m_roles.insert(role, property);
1058  m_strings.insert(property, role);
1059  } else {
1060  role = iter.value();
1061  }
1062 
1063  if (m_values[index][role] != value) {
1064  roles->append(role);
1065  m_values[index][role] = value;
1066  }
1067 }
1068 
1069 void FlatListModel::move(int from, int to, int n)
1070 {
1071  qdeclarativelistmodel_move<QList<QHash<int, QVariant> > >(from, to, n, &m_values);
1072  moveNodes(from, to, n);
1073 }
1074 
1076 {
1077  QScriptValueIterator it(value);
1078  while (it.hasNext()) {
1079  it.next();
1080  QScriptValue value = it.value();
1081  if (!value.isVariant() && !value.isRegExp() && !value.isDate() && value.isObject()) {
1082  qmlInfo(m_listModel) << "Cannot add list-type data when modifying or after modification from a worker script";
1083  return false;
1084  }
1085 
1086  QString name = it.name();
1087  QVariant v = it.value().toVariant();
1088 
1090  if (iter == m_strings.end()) {
1091  int role = m_roles.count();
1092  m_roles.insert(role, name);
1093  iter = m_strings.insert(name, role);
1094  if (roles)
1095  roles->append(role);
1096  } else {
1097  int role = iter.value();
1098  if (roles && row->contains(role) && row->value(role) != v)
1099  roles->append(role);
1100  }
1101  row->insert(*iter, v);
1102  }
1103  return true;
1104 }
1105 
1107 {
1108  if (index >= 0 && index <= m_values.count()) {
1109  m_nodeData.insert(index, 0);
1110 
1111  for (int i=index + 1; i<m_nodeData.count(); i++) {
1112  if (m_nodeData[i])
1113  m_nodeData[i]->index = i;
1114  }
1115  }
1116 }
1117 
1119 {
1120  if (index >= 0 && index < m_nodeData.count()) {
1121  delete m_nodeData.takeAt(index);
1122 
1123  for (int i=index; i<m_nodeData.count(); i++) {
1124  if (m_nodeData[i])
1125  m_nodeData[i]->index = i;
1126  }
1127  }
1128 }
1129 
1130 void FlatListModel::moveNodes(int from, int to, int n)
1131 {
1132  if (!m_listModel->canMove(from, to, n))
1133  return;
1134 
1135  qdeclarativelistmodel_move<QList<FlatNodeData *> >(from, to, n, &m_nodeData);
1136 
1137  for (int i=from; i<from + (to-from); i++) {
1138  if (m_nodeData[i])
1139  m_nodeData[i]->index = i;
1140  }
1141 }
1142 
1143 
1144 
1146 {
1147  for (QSet<FlatNodeObjectData *>::Iterator iter = objects.begin(); iter != objects.end(); ++iter) {
1148  FlatNodeObjectData *data = *iter;
1149  data->nodeData = 0;
1150  }
1151 }
1152 
1154 {
1155  objects.insert(data);
1156 }
1157 
1159 {
1160  objects.remove(data);
1161 }
1162 
1163 
1165  : QScriptDeclarativeClass(seng),
1166  m_model(model)
1167 {
1168 }
1169 
1171 {
1172  FlatNodeObjectData *objData = static_cast<FlatNodeObjectData*>(obj);
1173  if (!objData->nodeData) // item at this index has been deleted
1174  return QScriptDeclarativeClass::Value(engine(), engine()->undefinedValue());
1175 
1176  int index = objData->nodeData->index;
1177  QString propName = toString(name);
1178  int role = m_model->m_strings.value(propName, -1);
1179 
1180  if (role >= 0 && index >=0 ) {
1181  const QHash<int, QVariant> &row = m_model->m_values[index];
1182  QScriptValue sv = engine()->toScriptValue<QVariant>(row[role]);
1183  return QScriptDeclarativeClass::Value(engine(), sv);
1184  }
1185 
1186  return QScriptDeclarativeClass::Value(engine(), engine()->undefinedValue());
1187 }
1188 
1190 {
1191  if (!value.isVariant() && !value.isRegExp() && !value.isDate() && value.isObject()) {
1192  qmlInfo(m_model->m_listModel) << "Cannot add list-type data when modifying or after modification from a worker script";
1193  return;
1194  }
1195 
1196  FlatNodeObjectData *objData = static_cast<FlatNodeObjectData*>(obj);
1197  if (!objData->nodeData) // item at this index has been deleted
1198  return;
1199 
1200  int index = objData->nodeData->index;
1201  QString propName = toString(name);
1202 
1203  int role = m_model->m_strings.value(propName, -1);
1204  if (role >= 0 && index >= 0) {
1206  row[role] = value.toVariant();
1207 
1208  QList<int> roles;
1209  roles << role;
1210  if (m_model->m_parentAgent) {
1211  // This is the list in the worker thread, so tell the agent to
1212  // emit itemsChanged() later
1213  m_model->m_parentAgent->changedData(index, 1, roles);
1214  } else {
1215  // This is the list in the main thread, so emit itemsChanged()
1216  emit m_model->m_listModel->itemsChanged(index, 1, roles);
1217  }
1218  }
1219 }
1220 
1221 QScriptClass::QueryFlags FlatListScriptClass::queryProperty(Object *, const Identifier &, QScriptClass::QueryFlags)
1222 {
1224 }
1225 
1227 {
1228  FlatNodeObjectData *data1 = static_cast<FlatNodeObjectData*>(obj1);
1229  FlatNodeObjectData *data2 = static_cast<FlatNodeObjectData*>(obj2);
1230 
1231  if (!data1->nodeData || !data2->nodeData)
1232  return false;
1233 
1234  return data1->nodeData->index == data2->nodeData->index;
1235 }
1236 
1237 
1238 
1240  : _root(0), m_ownsRoot(false), m_listModel(base), _rolesOk(false)
1241 {
1242 }
1243 
1245 {
1246  if (m_ownsRoot)
1247  delete _root;
1248 }
1249 
1250 QVariant NestedListModel::valueForNode(ModelNode *node, bool *hasNested) const
1251 {
1252  QObject *rv = 0;
1253  if (hasNested)
1254  *hasNested = false;
1255 
1256  if (node->isArray) {
1257  // List
1258  rv = node->model(this);
1259  if (hasNested)
1260  *hasNested = true;
1261  } else {
1262  if (!node->properties.isEmpty()) {
1263  // Object
1264  rv = node->object(this);
1265  } else if (node->values.count() == 0) {
1266  // Invalid
1267  return QVariant();
1268  } else if (node->values.count() == 1) {
1269  // Value
1270  QVariant &var = node->values[0];
1271  ModelNode *valueNode = qvariant_cast<ModelNode *>(var);
1272  if (valueNode) {
1273  if (!valueNode->properties.isEmpty())
1274  rv = valueNode->object(this);
1275  else
1276  rv = valueNode->model(this);
1277  } else {
1278  return var;
1279  }
1280  }
1281  }
1282 
1283  if (rv) {
1284  return QVariant::fromValue(rv);
1285  } else {
1286  return QVariant();
1287  }
1288 }
1289 
1291 {
1292  Q_ASSERT(_root && index >= 0 && index < _root->values.count());
1293  checkRoles();
1295 
1296  ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
1297  if (!node)
1298  return rv;
1299 
1300  for (int ii = 0; ii < roles.count(); ++ii) {
1301  const QString &roleString = roleStrings.at(roles.at(ii));
1302 
1304  if (iter != node->properties.end()) {
1305  ModelNode *row = *iter;
1306  rv.insert(roles.at(ii), valueForNode(row, hasNested));
1307  }
1308  }
1309 
1310  return rv;
1311 }
1312 
1314 {
1315  Q_ASSERT(_root && index >= 0 && index < _root->values.count());
1316  checkRoles();
1317  QVariant rv;
1318  if (roleStrings.count() < role)
1319  return rv;
1320 
1321  ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
1322  if (!node)
1323  return rv;
1324 
1325  const QString &roleString = roleStrings.at(role);
1326 
1328  if (iter != node->properties.end()) {
1329  ModelNode *row = *iter;
1330  rv = valueForNode(row);
1331  }
1332 
1333  return rv;
1334 }
1335 
1337 {
1338  if (!_root) return 0;
1339  return _root->values.count();
1340 }
1341 
1343 {
1344  if (_root)
1345  _root->clear();
1346 }
1347 
1349 {
1350  if (!_root)
1351  return;
1352  ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
1353  _root->values.removeAt(index);
1354  if (node)
1355  delete node;
1356 }
1357 
1358 bool NestedListModel::insert(int index, const QScriptValue& valuemap)
1359 {
1360  if (!_root) {
1361  _root = new ModelNode(this);
1362  m_ownsRoot = true;
1363  }
1364 
1365  ModelNode *mn = new ModelNode(this);
1366  mn->listIndex = index;
1367  mn->setObjectValue(valuemap);
1368  _root->values.insert(index,QVariant::fromValue(mn));
1369  return true;
1370 }
1371 
1372 void NestedListModel::move(int from, int to, int n)
1373 {
1374  if (!_root)
1375  return;
1376  qdeclarativelistmodel_move<QVariantList>(from, to, n, &_root->values);
1377 }
1378 
1380 {
1382  if (!eng)
1383  return 0;
1384 
1385  if (index < 0 || index >= count()) {
1387  if (seng)
1388  return seng->undefinedValue();
1389  return 0;
1390  }
1391 
1392  ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
1393  if (!node)
1394  return 0;
1395 
1396  return QDeclarativeEnginePrivate::qmlScriptObject(node->object(this), eng);
1397 }
1398 
1400 {
1401  Q_ASSERT(index >=0 && index < count());
1402 
1403  ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
1404  bool emitItemsChanged = node->setObjectValue(valuemap);
1405  if (!emitItemsChanged)
1406  return;
1407 
1408  QScriptValueIterator it(valuemap);
1409  while (it.hasNext()) {
1410  it.next();
1411  int r = roleStrings.indexOf(it.name());
1412  if (r < 0) {
1413  r = roleStrings.count();
1414  roleStrings << it.name();
1415  }
1416  roles->append(r);
1417  }
1418 }
1419 
1421 {
1422  Q_ASSERT(index >=0 && index < count());
1423 
1424  ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
1425  bool emitItemsChanged = node->setProperty(property, value);
1426  if (!emitItemsChanged)
1427  return;
1428 
1429  int r = roleStrings.indexOf(property);
1430  if (r < 0) {
1431  r = roleStrings.count();
1432  roleStrings << property;
1433  }
1434  roles->append(r);
1435 }
1436 
1438 {
1439  if (_rolesOk || !_root)
1440  return;
1441 
1442  for (int i = 0; i<_root->values.count(); ++i) {
1443  ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(i));
1444  if (node) {
1445  foreach (const QString &role, node->properties.keys()) {
1446  if (!roleStrings.contains(role))
1447  roleStrings.append(role);
1448  }
1449  }
1450  }
1451 
1452  _rolesOk = true;
1453 }
1454 
1456 {
1457  checkRoles();
1458  QList<int> rv;
1459  for (int ii = 0; ii < roleStrings.count(); ++ii)
1460  rv << ii;
1461  return rv;
1462 }
1463 
1465 {
1466  checkRoles();
1467  if (role < roleStrings.count())
1468  return roleStrings.at(role);
1469  else
1470  return QString();
1471 }
1472 
1473 
1475 : modelCache(0), objectCache(0), isArray(false), m_model(model), listIndex(-1)
1476 {
1477 }
1478 
1480 {
1481  clear();
1482  if (modelCache) { modelCache->m_nested->_root = 0/* ==this */; delete modelCache; modelCache = 0; }
1483  if (objectCache) { delete objectCache; objectCache = 0; }
1484 }
1485 
1487 {
1488  ModelNode *node;
1489  for (int ii = 0; ii < values.count(); ++ii) {
1490  node = qvariant_cast<ModelNode *>(values.at(ii));
1491  if (node) { delete node; node = 0; }
1492  }
1493  values.clear();
1494 
1496  properties.clear();
1497 }
1498 
1499 bool ModelNode::setObjectValue(const QScriptValue& valuemap, bool writeToCache)
1500 {
1501  bool emitItemsChanged = false;
1502 
1503  QScriptValueIterator it(valuemap);
1504  while (it.hasNext()) {
1505  it.next();
1506  ModelNode *prev = properties.value(it.name());
1507  ModelNode *value = new ModelNode(m_model);
1508  QScriptValue v = it.value();
1509 
1510  if (v.isArray()) {
1511  value->isArray = true;
1512  value->setListValue(v);
1513  if (writeToCache && objectCache)
1515  emitItemsChanged = true; // for now, too inefficient to check whether list and sublists have changed
1516  } else {
1517  value->values << v.toVariant();
1518  if (writeToCache && objectCache)
1519  objectCache->setValue(it.name().toUtf8(), value->values.last());
1520  if (!emitItemsChanged && prev && prev->values.count() == 1
1521  && prev->values[0] != value->values.last()) {
1522  emitItemsChanged = true;
1523  }
1524  }
1525  if (properties.contains(it.name()))
1526  delete properties[it.name()];
1527  properties.insert(it.name(), value);
1528  }
1529  return emitItemsChanged;
1530 }
1531 
1532 void ModelNode::setListValue(const QScriptValue& valuelist) {
1533  values.clear();
1534  int size = valuelist.property(QLatin1String("length")).toInt32();
1535  for (int i=0; i<size; i++) {
1536  ModelNode *value = new ModelNode(m_model);
1537  QScriptValue v = valuelist.property(i);
1538  if (v.isArray()) {
1539  value->isArray = true;
1540  value->setListValue(v);
1541  } else if (v.isObject()) {
1542  value->listIndex = i;
1543  value->setObjectValue(v);
1544  } else {
1545  value->listIndex = i;
1546  value->values << v.toVariant();
1547  }
1549  }
1550 }
1551 
1552 bool ModelNode::setProperty(const QString& prop, const QVariant& val) {
1554  bool emitItemsChanged = false;
1555  if (it != properties.end()) {
1556  if (val != (*it)->values[0])
1557  emitItemsChanged = true;
1558  (*it)->values[0] = val;
1559  } else {
1560  ModelNode *n = new ModelNode(m_model);
1561  n->values << val;
1562  properties.insert(prop,n);
1563  }
1564  if (objectCache)
1565  objectCache->setValue(prop.toUtf8(), val);
1566  return emitItemsChanged;
1567 }
1568 
1570 {
1571  for (QHash<QString, ModelNode *>::ConstIterator iter = properties.begin(); iter != properties.end(); ++iter) {
1572  ModelNode *node = iter.value();
1573  if (node->isArray) {
1574  for (int i=0; i<node->values.count(); ++i) {
1575  ModelNode *subNode = qvariant_cast<ModelNode *>(node->values.at(i));
1576  if (subNode)
1577  subNode->listIndex = i;
1578  }
1579  }
1580  node->updateListIndexes();
1581  }
1582 }
1583 
1584 /*
1585  Need to call this to emit itemsChanged() for modifications outside of set()
1586  and setProperty(), i.e. if an item returned from get() is modified
1587 */
1589 {
1590  if (listIndex < 0)
1591  return;
1592 
1593  m_model->checkRoles();
1594  QList<int> roles;
1595  int role = m_model->roleStrings.indexOf(name);
1596  if (role < 0)
1597  roles = m_model->roles();
1598  else
1599  roles << role;
1601 }
1602 
1603 void ModelNode::dump(ModelNode *node, int ind)
1604 {
1605  QByteArray indentBa(ind * 4, ' ');
1606  const char *indent = indentBa.constData();
1607 
1608  for (int ii = 0; ii < node->values.count(); ++ii) {
1609  ModelNode *subNode = qvariant_cast<ModelNode *>(node->values.at(ii));
1610  if (subNode) {
1611  qWarning().nospace() << indent << "Sub-node " << ii;
1612  dump(subNode, ind + 1);
1613  } else {
1614  qWarning().nospace() << indent << "Sub-node " << ii << ": " << node->values.at(ii).toString();
1615  }
1616  }
1617 
1618  for (QHash<QString, ModelNode *>::ConstIterator iter = node->properties.begin(); iter != node->properties.end(); ++iter) {
1619  qWarning().nospace() << indent << "Property " << iter.key() << ':';
1620  dump(iter.value(), ind + 1);
1621  }
1622 }
1623 
1625  : m_model(model),
1626  m_node(node),
1627  m_meta(new ModelNodeMetaObject(seng, this))
1628 {
1629 }
1630 
1632 {
1633  m_meta->setValue(name, val);
1634  //setProperty(name.constData(), val);
1635 }
1636 
1638 {
1639  m_meta->m_enabled = enable;
1640 }
1641 
1642 
1644  : QDeclarativeOpenMetaObject(object),
1645  m_enabled(false),
1646  m_seng(seng),
1647  m_obj(object)
1648 {
1649 }
1650 
1652 {
1653  if (!m_enabled)
1654  return;
1655 
1656  QString propName = QString::fromUtf8(name(index));
1657  QVariant value = operator[](index);
1658 
1659  QScriptValue sv = m_seng->newObject();
1660  sv.setProperty(propName, m_seng->newVariant(value));
1661  bool changed = m_obj->m_node->setObjectValue(sv, false);
1662  if (changed)
1663  m_obj->m_node->changedProperty(propName);
1664 }
1665 
1666 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
static QScriptEngine * getScriptEngine(QDeclarativeEngine *e)
double d
Definition: qnumeric_p.h:62
void setProperty(int index, const QString &property, const QVariant &value, QList< int > *roles)
The QMetaObject class contains meta-information about Qt objects.
Definition: qobjectdefs.h:304
QHash< int, QVariant > data(int index, const QList< int > &roles, bool *hasNested=0) const
QScriptClass::QueryFlags queryProperty(Object *, const Identifier &, QScriptClass::QueryFlags flags)
QList< QDeclarativeCustomParserProperty > properties() const
void move(int from, int to, int count)
The QHash::const_iterator class provides an STL-style const iterator for QHash and QMultiHash...
Definition: qhash.h:395
bool insert(int index, const QScriptValue &)
QScriptValue property(const QString &name, const ResolveFlags &mode=ResolvePrototype) const
Returns the value of this QScriptValue&#39;s property with the given name, using the given mode to resolv...
void setCustomData(QObject *, const QByteArray &)
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void moveNodes(int from, int to, int n)
void setValue(const QByteArray &, const QVariant &)
ModelObject(ModelNode *node, NestedListModel *model, QScriptEngine *seng)
void clear()
Removes all items from the hash.
Definition: qhash.h:574
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
static void setContextForObject(QObject *, QDeclarativeContext *)
Sets the QDeclarativeContext for the object to context.
QHash< QString, ModelNode * > properties
#define it(className, varName)
ModelNodeMetaObject * m_meta
QByteArray & append(char c)
Appends the character ch to this byte array.
virtual QVariant data(int index, int role) const
Returns the data at the given index for the specified roles.
static QScriptValue newObject(QScriptEngine *, QScriptDeclarativeClass *, Object *)
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
Definition: qstring.cpp:4074
QByteArray compile(const QList< QDeclarativeCustomParserProperty > &)
#define error(msg)
qint32 toInt32() const
Returns the signed 32-bit integer value of this QScriptValue, using the conversion rules described in...
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QScriptValue toScriptValue(const T &value)
Creates a QScriptValue with the given value.
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
Value property(Object *, const Identifier &)
QList< int > roles() const
void changedData(int index, int count, const QList< int > &roles)
QDeclarativeListModel(QObject *parent=0)
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
Definition: qvariant.cpp:2270
QString name() const
Returns the name of the last property that was jumped over using next() or previous().
QVariant data(int index, int role) const
static const QMetaObject staticMetaObject
This variable stores the meta-object for the class.
Definition: qobject.h:128
void set(int index, const QScriptValue &, QList< int > *roles)
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
void insert(int i, const T &t)
Inserts value at index position i in the list.
Definition: qlist.h:575
friend class FlatListScriptClass
bool insert(int index, const QScriptValue &)
static QString tr(const char *sourceText, const char *comment=0, int n=-1)
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
The QStack class is a template class that provides a stack.
Definition: qcontainerfwd.h:63
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
Q_INVOKABLE void move(int from, int to, int count)
bool setObjectValue(const QScriptValue &valuemap, bool writeToCache=true)
The QString class provides a Unicode character string.
Definition: qstring.h:83
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
void setProperty(int index, const QString &property, const QVariant &value, QList< int > *roles)
void changedProperty(const QString &name) const
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QString toString(int role) const
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
bool startsWith(const QByteArray &a) const
Returns true if this byte array starts with byte array ba; otherwise returns false.
void itemsRemoved(int index, int count)
Emit this signal when count items are removed at index.
virtual QString toString(int role) const
Returns a string description of the specified role.
static const uint base
Definition: qurl.cpp:268
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
ModelNodeMetaObject(QScriptEngine *seng, ModelObject *object)
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
The QScriptDeclarativeClass::Value class acts as a container for JavaScript data types.
void insertedNode(int index)
QDeclarativeListModel * m_listModel
Q_INVOKABLE void setProperty(int index, const QString &property, const QVariant &value)
Q_INVOKABLE void set(int index, const QScriptValue &)
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
T pop()
Removes the top item from the stack and returns it.
Definition: qstack.h:67
QVariant value(const QByteArray &) const
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
FlatListScriptClass * m_scriptClass
The QScriptEngine class provides an environment for evaluating Qt Script code.
QList< FlatNodeData * > m_nodeData
int indexOf(const QRegExp &rx, int from=0) const
Returns the index position of the first exact match of rx in the list, searching forward from index p...
Definition: qstringlist.h:195
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
void addData(FlatNodeObjectData *data)
bool definesEmptyList(const QString &)
Q_INVOKABLE void append(const QScriptValue &)
QDeclarativeListModel * m_listModel
QList< QVariant > values
const char * name
QScriptEngine * engine() const
Q_INVOKABLE QScriptValue get(int index) const
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
#define emit
Definition: qobjectdefs.h:76
QVariant toVariant() const
Returns the QVariant value of this QScriptValue, if it can be converted to a QVariant; otherwise retu...
static QString fromUtf8(const char *, int size=-1)
Returns a QString initialized with the first size bytes of the UTF-8 string str.
Definition: qstring.cpp:4302
bool isEmpty() const
Returns true if the hash contains no items; otherwise returns false.
Definition: qhash.h:297
static QScriptValue qmlScriptObject(QObject *, QDeclarativeEngine *)
Creates a QScriptValue allowing you to use object in QML script.
Q_CORE_EXPORT void qWarning(const char *,...)
QList< QHash< int, QVariant > > m_values
QDeclarativeListModelWorkerAgent * agent()
QScriptValue newObject()
Creates a QtScript object of class Object.
QBool contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the list contains the string str; otherwise returns false.
Definition: qstringlist.h:172
QVariant valueForNode(ModelNode *, bool *hasNested=0) const
The QListModelInterface class can be subclassed to provide C++ models to QDeclarativeGraphics Views...
void removedNode(int index)
T value(int i) const
Returns the value at index position i in the list.
Definition: qlist.h:661
QHash< int, QString > m_roles
FlatListScriptClass(FlatListModel *model, QScriptEngine *seng)
void clear()
Removes all items from the list.
Definition: qlist.h:764
const Key & key() const
Returns the current item&#39;s key as a const reference.
Definition: qhash.h:347
bool isVariant() const
Returns true if this QScriptValue is a variant value; otherwise returns false.
quint16 values[128]
static QVariant fromValue(const T &value)
Returns a QVariant containing a copy of value.
Definition: qvariant.h:336
void replace(int i, const T &t)
Replaces the item at index position i with value.
Definition: qlist.h:609
QByteArray mid(int index, int len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos...
QDeclarativeListModel * model(const NestedListModel *model)
void push(const T &t)
Adds element t to the top of the stack.
Definition: qstack.h:60
Q_CORE_EXPORT int QT_FASTCALL script(uint ucs4)
#define Q_DECLARE_METATYPE(TYPE)
This macro makes the type Type known to QMetaType as long as it provides a public default constructor...
Definition: qmetatype.h:265
ModelObject * object(const NestedListModel *model)
void itemsChanged(int index, int count, const QList< int > &roles)
Emit this signal when count items at index have had their roles changed.
int length() const
Same as size().
Definition: qbytearray.h:356
NestedListModel(QDeclarativeListModel *base)
QHash< QString, int > m_strings
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
virtual QList< int > roles() const
Returns the list of roles for which the list model interface provides data.
void setProperty(const QString &name, const QScriptValue &value, const PropertyFlags &flags=KeepExistingFlags)
Sets the value of this QScriptValue&#39;s property with the given name to the given value.
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
int userType() const
Returns the storage type of the value stored in the variant.
Definition: qvariant.cpp:1913
FlatListModel(QDeclarativeListModel *base)
The QScriptValueIterator class provides a Java-style iterator for QScriptValue.
bool compileProperty(const QDeclarativeCustomParserProperty &prop, QList< ListInstruction > &instr, QByteArray &data)
Q_DECLARATIVE_EXPORT QDeclarativeEngine * qmlEngine(const QObject *)
int count(char c) const
Returns the number of occurrences of character ch in the byte array.
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:467
QDeclarativeListModel * modelCache
virtual int count() const
Returns the number of data entries in the model.
The QDeclarativeEngine class provides an environment for instantiating QML components.
QDeclarativeListModelWorkerAgent * m_parentAgent
static void dump(ModelNode *node, int ind)
bool isRegExp() const
Returns true if this QScriptValue is an object of the RegExp class; otherwise returns false...
bool compare(Object *, Object *)
enum QDeclarativeListModelParser::ListInstruction::@152 type
Q_INVOKABLE void insert(int index, const QScriptValue &)
QList< T > values() const
Returns a list containing all the values in the hash, in an arbitrary order.
Definition: qhash.h:693
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
QScriptValue value() const
Returns the value of the last property that was jumped over using next() or previous().
void itemsInserted(int index, int count)
Emit this signal when count items are inserted at index.
T & last()
Returns a reference to the last item in the list.
Definition: qlist.h:284
QDeclarativeListModelWorkerAgent * m_agent
void resize(int size)
Sets the size of the byte array to size bytes.
The QHash::iterator class provides an STL-style non-const iterator for QHash and QMultiHash.
Definition: qhash.h:330
const char * property
Definition: qwizard.cpp:138
iterator begin()
Returns an STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:464
QScriptValue get(int index) const
void remove(int index)
T qvariant_cast(const QVariant &)
Definition: qvariant.h:571
QList< int > roles() const
T takeAt(int i)
Removes the item at index position i and returns it.
Definition: qlist.h:484
static const QCssKnownValue properties[NumProperties - 1]
Definition: qcssparser.cpp:67
void qdeclarativelistmodel_move(int from, int to, int n, T *items)
quint16 index
QVariant property(const char *name) const
Returns the value of the object&#39;s name property.
Definition: qobject.cpp:3807
bool isDate() const
Returns true if this QScriptValue is an object of the Date class; otherwise returns false...
void itemsMoved(int from, int to, int count)
Emit this signal when count items are moved from index from to index to.
void setListValue(const QScriptValue &valuelist)
int count(const Key &key) const
Returns the number of items associated with the key.
Definition: qhash.h:719
void setValue(const QByteArray &name, const QVariant &val)
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
QScriptEngine * m_scriptEngine
QString toString(int role) const
QScriptValue undefinedValue()
Returns a QScriptValue of the primitive type Undefined.
static QDeclarativeContext * contextForObject(const QObject *)
Returns the QDeclarativeContext for the object, or 0 if no context has been set.
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
Definition: qhash.h:865
ModelObject * objectCache
const char * variant
NestedListModel * m_model
bool canMove(int from, int to, int n) const
bool isArray() const
Returns true if this QScriptValue is an object of the Array class; otherwise returns false...
QDeclarativeInfo qmlInfo(const QObject *me)
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition: qstring.cpp:3796
void set(int index, const QScriptValue &, QList< int > *roles)
void setProperty(Object *, const Identifier &name, const QScriptValue &)
QVariant & operator[](const QByteArray &)
void removeData(FlatNodeObjectData *data)
ModelNode(NestedListModel *model)
bool addValue(const QScriptValue &value, QHash< int, QVariant > *row, QList< int > *roles)
The QScriptValue class acts as a container for the Qt Script data types.
Definition: qscriptvalue.h:57
friend class QDeclarativeListModelWorkerAgent
Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
Definition: qalgorithms.h:319
QString toString(const Identifier &)
QList< Key > keys() const
Returns a list containing all the keys in the hash, in an arbitrary order.
Definition: qhash.h:648
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
bool setProperty(const QString &prop, const QVariant &val)
void next()
Advances the iterator by one position.
void move(int from, int to, int count)
QScriptValue newVariant(const QVariant &value)
Creates a QtScript object holding the given variant value.
bool isObject() const
Returns true if this QScriptValue is of the Object type; otherwise returns false. ...
void setNodeUpdatesEnabled(bool enable)
QScriptValue get(int index) const
void reserve(int size)
Reserve space for alloc elements.
Definition: qlist.h:496
bool hasNext() const
Returns true if there is at least one item ahead of the iterator (i.e.
bool endsWith(const QByteArray &a) const
Returns true if this byte array ends with byte array ba; otherwise returns false. ...
Q_INVOKABLE void remove(int index)
T & top()
Returns a reference to the stack&#39;s top item.
Definition: qstack.h:72
void removeAt(int i)
Removes the item at index position i.
Definition: qlist.h:480