Qt creator 2 adaptations
[family-shop-mgr] / code / family-shop-mgr / model / ShoppingTreeModel.cpp
1 /*\r
2  * This file is part of family-shop-mgr.\r
3  *\r
4  * family-shop-mgr is free software: you can redistribute it and/or modify\r
5  * it under the terms of the GNU General Public License as published by\r
6  * the Free Software Foundation, either version 3 of the License, or\r
7  * (at your option) any later version.\r
8  *\r
9  * family-shop-mgr is distributed in the hope that it will be useful,\r
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12  * GNU General Public License for more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License\r
15  * along with family-shop-mgr.  If not, see <http://www.gnu.org/licenses/>.\r
16  *\r
17  * Author: Unai IRIGOYEN\r
18  * Date: 12/07/2009\r
19  *\r
20  */\r
21 \r
22 #include <QtXml>\r
23 \r
24 #include "ShoppingTreeItem.h"\r
25 #include "ShoppingTreeModel.h"\r
26 \r
27 ShoppingTreeModel::ShoppingTreeModel(QString fileName, QObject *parent)\r
28     : QAbstractItemModel(parent),m_fileName(fileName)\r
29 {\r
30     connect(this, SIGNAL(documentChanged()), this, SLOT(save()));\r
31     QFile file(m_fileName);\r
32     if (!file.open(QIODevice::ReadOnly))\r
33         return;\r
34     if (!domDocument.setContent(&file)) {\r
35         file.close();\r
36         return;\r
37     }\r
38     file.close();\r
39 \r
40     rootItemNode = domDocument.firstChildElement("shoppingList");\r
41     rootItem = new ShoppingTreeItem(rootItemNode, 0);\r
42 }\r
43 \r
44 /*******************************************************************/\r
45 ShoppingTreeModel::~ShoppingTreeModel()\r
46 {\r
47     delete rootItem;\r
48 }\r
49 \r
50 /*******************************************************************/\r
51 int ShoppingTreeModel::columnCount(const QModelIndex &/*parent*/) const\r
52 {\r
53     return 4;\r
54 }\r
55 \r
56 /*******************************************************************/\r
57 QVariant ShoppingTreeModel::data(const QModelIndex &index, int role) const\r
58 {\r
59     if (!index.isValid())\r
60         return QVariant();\r
61 \r
62     if (role != Qt::DisplayRole && role != Qt::EditRole)\r
63         return QVariant();\r
64 \r
65     ShoppingTreeItem *item = static_cast<ShoppingTreeItem*>(index.internalPointer());\r
66 \r
67     QDomNode node = item->node();\r
68 \r
69     switch (index.column()) {\r
70         case 0:\r
71             return node.firstChildElement("title").text();\r
72         case 1:\r
73             if(node.toElement().nodeName() == "item")\r
74             {\r
75                 return node.firstChildElement("quantity").text().toInt();\r
76             }\r
77             return QVariant();\r
78         case 2:\r
79             if(node.toElement().nodeName() == "item")\r
80             {\r
81                 return node.firstChildElement("store").text();\r
82             }\r
83             return QVariant();\r
84         case 3:\r
85             if(node.toElement().nodeName() == "item")\r
86             {\r
87                 return (bool) node.firstChildElement("checked").text().toInt();\r
88             }\r
89             return QVariant();\r
90         default:\r
91             return QVariant();\r
92     }\r
93 }\r
94 \r
95 /*******************************************************************/\r
96 Qt::ItemFlags ShoppingTreeModel::flags(const QModelIndex &index) const\r
97 {\r
98     if (!index.isValid())\r
99         return 0;\r
100 \r
101     return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;\r
102 }\r
103 \r
104 /*******************************************************************/\r
105 QVariant ShoppingTreeModel::headerData(int section, Qt::Orientation orientation,\r
106                               int role) const\r
107 {\r
108     if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {\r
109         switch (section) {\r
110             case 0:\r
111                 return tr("Category/Item name");\r
112             case 1:\r
113                 return tr("Quantity");\r
114             case 2:\r
115                 return tr("Store");\r
116             case 3:\r
117                 return tr("Checked");\r
118             default:\r
119                 return QVariant();\r
120         }\r
121     }\r
122 \r
123     return QVariant();\r
124 }\r
125 \r
126 /*******************************************************************/\r
127 QModelIndex ShoppingTreeModel::index(int row, int column, const QModelIndex &parent)\r
128             const\r
129 {\r
130     if (!hasIndex(row, column, parent))\r
131         return QModelIndex();\r
132 \r
133     ShoppingTreeItem *parentItem;\r
134 \r
135     if (!parent.isValid())\r
136         parentItem = rootItem;\r
137     else\r
138         parentItem = static_cast<ShoppingTreeItem*>(parent.internalPointer());\r
139 \r
140     ShoppingTreeItem *childItem = parentItem->child(row);\r
141     if (childItem)\r
142         return createIndex(row, column, childItem);\r
143     else\r
144         return QModelIndex();\r
145 }\r
146 \r
147 /*******************************************************************/\r
148 QModelIndex ShoppingTreeModel::parent(const QModelIndex &child) const\r
149 {\r
150     if (!child.isValid())\r
151         return QModelIndex();\r
152 \r
153     ShoppingTreeItem *childItem = static_cast<ShoppingTreeItem*>(child.internalPointer());\r
154     ShoppingTreeItem *parentItem = childItem->parent();\r
155 \r
156     if (!parentItem || parentItem == rootItem)\r
157         return QModelIndex();\r
158 \r
159     return createIndex(parentItem->row(), 0, parentItem);\r
160 }\r
161 \r
162 /*******************************************************************/\r
163 int ShoppingTreeModel::rowCount(const QModelIndex &parent) const\r
164 {\r
165     if (parent.column() > 0)\r
166         return 0;\r
167 \r
168     ShoppingTreeItem *parentItem;\r
169 \r
170     if (!parent.isValid())\r
171         parentItem = rootItem;\r
172     else\r
173         parentItem = static_cast<ShoppingTreeItem*>(parent.internalPointer());\r
174 \r
175     int childCount = 0;\r
176     for(QDomElement childElement = parentItem->node().firstChildElement();\r
177         !childElement.isNull(); childElement = childElement.nextSiblingElement())\r
178     {\r
179         if(childElement.nodeName() == "category" || childElement.nodeName() == "item")\r
180             childCount++;\r
181     }\r
182     return childCount;\r
183 }\r
184 \r
185 /*******************************************************************/\r
186 bool ShoppingTreeModel::insertRows(int row, int count, const QModelIndex &parent, ItemType type)\r
187 {\r
188     ShoppingTreeItem *parentItem;\r
189 \r
190     if (!parent.isValid())\r
191         parentItem = rootItem;\r
192     else\r
193         parentItem = static_cast<ShoppingTreeItem*>(parent.internalPointer());\r
194 \r
195     for(int i = 0; i < count; i++)\r
196     {\r
197         QDomElement newElement;\r
198         QDomElement titleElement;\r
199         titleElement.setTagName("title");\r
200         if(type == category)\r
201         {\r
202             newElement.setTagName("category");\r
203             titleElement.setNodeValue(tr("new category"));\r
204             newElement.appendChild(titleElement);\r
205         }\r
206         else if(type == item)\r
207         {\r
208             newElement.setTagName("item");\r
209             titleElement.setNodeValue(tr("new item"));\r
210             newElement.appendChild(titleElement);\r
211             QDomElement quantityElement;\r
212             quantityElement.setTagName("quantity");\r
213             newElement.appendChild(quantityElement);\r
214             QDomElement storeElement;\r
215             storeElement.setTagName("store");\r
216             newElement.appendChild(storeElement);\r
217             QDomElement checkedElement;\r
218             checkedElement.setTagName("checked");\r
219             checkedElement.setNodeValue("0");\r
220             newElement.appendChild(checkedElement);\r
221             QDomElement lastModifiedElement;\r
222             lastModifiedElement.setTagName("lastModified");\r
223             lastModifiedElement.setNodeValue(QDateTime::currentDateTime().toString("dd/MM/yyyy-hh:mm:ss"));\r
224             newElement.appendChild(lastModifiedElement);\r
225         }\r
226         else\r
227             return false;\r
228 \r
229         parentItem->node().insertAfter(newElement, parentItem->child(row + i)->node());\r
230         ShoppingTreeItem* newItem = new ShoppingTreeItem(newElement, parentItem);\r
231         parentItem->addChild(newItem, row + i);\r
232     }\r
233     emit documentChanged();\r
234     return true;\r
235 }\r
236 \r
237 /*******************************************************************/\r
238 bool ShoppingTreeModel::removeRows(int row, int count, const QModelIndex &parent)\r
239 {\r
240     ShoppingTreeItem *parentItem;\r
241 \r
242     if (!parent.isValid())\r
243         parentItem = rootItem;\r
244     else\r
245         parentItem = static_cast<ShoppingTreeItem*>(parent.internalPointer());\r
246 \r
247     for(int i = 0; i < count; i++)\r
248     {\r
249         parentItem->node().removeChild(parentItem->child(row)->node());\r
250         parentItem->removeChild(row);\r
251     }\r
252     emit documentChanged();\r
253     return true;\r
254 }\r
255 \r
256 /*******************************************************************/\r
257 bool ShoppingTreeModel::addCategory(const QModelIndex &index, QString name)\r
258 {\r
259     ShoppingTreeItem *selectedItem;\r
260 \r
261     if (!index.isValid())\r
262         selectedItem = rootItem;\r
263     else\r
264         selectedItem = static_cast<ShoppingTreeItem*>(index.internalPointer());\r
265 \r
266     bool success = insertRows(selectedItem->row(), 1, parent(index), category);\r
267     if(!name.isEmpty())\r
268     {\r
269         selectedItem->parent()->child(selectedItem->row() + 1)\r
270             ->node().setNodeValue(name);\r
271         emit documentChanged();\r
272     }\r
273     return success;\r
274 }\r
275 \r
276 /*******************************************************************/\r
277 bool ShoppingTreeModel::addItem(const QModelIndex &index, QString name)\r
278 {\r
279     ShoppingTreeItem *selectedItem;\r
280 \r
281     if (!index.isValid())\r
282         selectedItem = rootItem;\r
283     else\r
284         selectedItem = static_cast<ShoppingTreeItem*>(index.internalPointer());\r
285 \r
286     bool success = insertRows(selectedItem->row(), 1, parent(index), item);\r
287     if(!name.isEmpty())\r
288     {\r
289         selectedItem->parent()->child(selectedItem->row() + 1)\r
290             ->node().setNodeValue(name);\r
291         emit documentChanged();\r
292     }\r
293     return success;\r
294 }\r
295 \r
296 /*******************************************************************/\r
297 bool ShoppingTreeModel::removeElement(QModelIndex &index)\r
298 {\r
299     ShoppingTreeItem *selectedItem;\r
300 \r
301     if (!index.isValid())\r
302         selectedItem = rootItem;\r
303     else\r
304         selectedItem = static_cast<ShoppingTreeItem*>(index.internalPointer());\r
305 \r
306     return removeRows(selectedItem->row(), 1, parent(index));\r
307 }\r
308 \r
309 /*******************************************************************/\r
310 bool ShoppingTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)\r
311 {\r
312     if (!index.isValid())\r
313         return false;\r
314 \r
315     if (role != Qt::EditRole)\r
316         return false;\r
317 \r
318     ShoppingTreeItem *item = static_cast<ShoppingTreeItem*>(index.internalPointer());\r
319 \r
320     QDomNode node = item->node();\r
321 \r
322     switch (index.column()) {\r
323         case 0:\r
324             node.firstChildElement("title").setNodeValue(value.toString());\r
325             return true;\r
326         case 1:\r
327             if(node.toElement().nodeName() == "item")\r
328             {\r
329                 node.firstChildElement("quantity").setNodeValue(value.toString());\r
330                 return true;\r
331             }\r
332             return false;\r
333         case 2:\r
334             if(node.toElement().nodeName() == "item")\r
335             {\r
336                 node.firstChildElement("store").setNodeValue(value.toString());\r
337                 return true;\r
338             }\r
339             return false;\r
340         case 3:\r
341             if(node.toElement().nodeName() == "item")\r
342             {\r
343                 node.firstChildElement("checked").setNodeValue(value.toString());\r
344                 return true;\r
345             }\r
346             return false;\r
347         default:\r
348             return false;\r
349     }\r
350 }\r
351 \r
352 /*******************************************************************/\r
353 void ShoppingTreeModel::save()\r
354 {\r
355     QFile file(m_fileName);\r
356     file.remove();\r
357     if (!file.open(QIODevice::WriteOnly))\r
358         return;\r
359     if (!file.write(domDocument.toString(4).toUtf8())) {\r
360         file.close();\r
361         return;\r
362     }\r
363     file.close();\r
364 }\r