<property name="windowTitle">\r
<string>Form</string>\r
</property>\r
- <widget class="QTreeView" name="treeView">\r
- <property name="geometry">\r
- <rect>\r
- <x>10</x>\r
- <y>40</y>\r
- <width>221</width>\r
- <height>251</height>\r
- </rect>\r
- </property>\r
- </widget>\r
- <widget class="QPushButton" name="pushButton">\r
- <property name="geometry">\r
- <rect>\r
- <x>60</x>\r
- <y>10</y>\r
- <width>121</width>\r
- <height>21</height>\r
- </rect>\r
- </property>\r
- <property name="text">\r
- <string>PushButton</string>\r
- </property>\r
- <property name="checkable">\r
- <bool>true</bool>\r
- </property>\r
- </widget>\r
+ <property name="locale">\r
+ <locale language="English" country="UnitedStates"/>\r
+ </property>\r
+ <layout class="QVBoxLayout" name="verticalLayout">\r
+ <item>\r
+ <layout class="QHBoxLayout" name="horizontalLayout">\r
+ <item>\r
+ <widget class="QPushButton" name="pushButton">\r
+ <property name="locale">\r
+ <locale language="English" country="UnitedStates"/>\r
+ </property>\r
+ <property name="text">\r
+ <string>Show checked</string>\r
+ </property>\r
+ <property name="checkable">\r
+ <bool>true</bool>\r
+ </property>\r
+ </widget>\r
+ </item>\r
+ </layout>\r
+ </item>\r
+ <item>\r
+ <widget class="QTreeView" name="treeView"/>\r
+ </item>\r
+ </layout>\r
</widget>\r
<resources/>\r
<connections/>\r
-<ui version="4.0" >\r
- <author></author>\r
- <comment></comment>\r
- <exportmacro></exportmacro>\r
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ui version="4.0">\r
<class>Form</class>\r
- <widget class="QWidget" name="Form" >\r
- <property name="geometry" >\r
+ <widget class="QWidget" name="Form">\r
+ <property name="geometry">\r
<rect>\r
<x>0</x>\r
<y>0</y>\r
- <width>400</width>\r
+ <width>233</width>\r
<height>300</height>\r
</rect>\r
</property>\r
- <property name="windowTitle" >\r
+ <property name="windowTitle">\r
<string>Form</string>\r
</property>\r
+ <property name="locale">\r
+ <locale language="English" country="UnitedStates"/>\r
+ </property>\r
+ <layout class="QVBoxLayout" name="verticalLayout">\r
+ <item>\r
+ <layout class="QHBoxLayout" name="horizontalLayout">\r
+ <item>\r
+ <widget class="QPushButton" name="pushButton">\r
+ <property name="text">\r
+ <string>Edit structure</string>\r
+ </property>\r
+ <property name="checkable">\r
+ <bool>true</bool>\r
+ </property>\r
+ </widget>\r
+ </item>\r
+ <item>\r
+ <widget class="QPushButton" name="pushButton_3">\r
+ <property name="text">\r
+ <string>Add</string>\r
+ </property>\r
+ </widget>\r
+ </item>\r
+ <item>\r
+ <widget class="QPushButton" name="pushButton_2">\r
+ <property name="text">\r
+ <string>Remove</string>\r
+ </property>\r
+ </widget>\r
+ </item>\r
+ </layout>\r
+ </item>\r
+ <item>\r
+ <widget class="QTreeView" name="treeView"/>\r
+ </item>\r
+ </layout>\r
</widget>\r
- <pixmapfunction></pixmapfunction>\r
+ <resources/>\r
<connections/>\r
</ui>\r
\r
#include "ShoppingTreeItem.h"\r
\r
-ShoppingTreeItem::ShoppingTreeItem(const QVector<QVariant> &data, ShoppingTreeItem *parent)\r
+ShoppingTreeItem::ShoppingTreeItem(const QVector<QVariant> &data,\r
+ ShoppingTreeItem *parent) : m_itemType(NotDefined)\r
{\r
parentItem = parent;\r
itemData = data;\r
QVector<QVariant> data(columns);\r
ShoppingTreeItem *item = new ShoppingTreeItem(data, this);\r
childItems.insert(position, item);\r
+ emit childInserted(item);\r
}\r
\r
return true;\r
}\r
\r
+bool ShoppingTreeItem::insertColumns(int position, int columns)\r
+{\r
+ if (position < 0 || position > itemData.size())\r
+ return false;\r
+\r
+ for (int column = 0; column < columns; ++column)\r
+ itemData.insert(position, QVariant());\r
+\r
+ foreach (ShoppingTreeItem *child, childItems)\r
+ child->insertColumns(position, columns);\r
+\r
+ return true;\r
+}\r
+\r
ShoppingTreeItem *ShoppingTreeItem::parent()\r
{\r
return parentItem;\r
return false;\r
\r
for (int row = 0; row < count; ++row)\r
- delete childItems.takeAt(position);\r
+ {\r
+ ShoppingTreeItem *item = childItems.takeAt(position);\r
+ emit childRemoved(item);\r
+ delete item;\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+bool ShoppingTreeItem::removeColumns(int position, int columns)\r
+{\r
+ if (position < 0 || position + columns > itemData.size())\r
+ return false;\r
+\r
+ for (int column = 0; column < columns; ++column)\r
+ itemData.remove(position);\r
+\r
+ foreach (ShoppingTreeItem *child, childItems)\r
+ child->removeColumns(position, columns);\r
\r
return true;\r
}\r
if (column < 0 || column >= itemData.size())\r
return false;\r
\r
+ if(m_itemType == Category && column != 0)\r
+ return false;\r
+\r
itemData[column] = value;\r
+ emit dataChanged(column);\r
return true;\r
}\r
+\r
+bool ShoppingTreeItem::setItemType(ItemType type)\r
+{\r
+ if(type == NotDefined)\r
+ return false;\r
+\r
+ m_itemType = type;\r
+\r
+ // release enough resources in case we call wait more than once\r
+ m_typeSemaphore.release(1000);\r
+\r
+ return (m_itemType == type) ? true : false;\r
+}\r
+\r
+ShoppingTreeItem::ItemType ShoppingTreeItem::getItemType() const\r
+{\r
+ return m_itemType;\r
+}\r
+\r
+void ShoppingTreeItem::waitItemTypeDefinition()\r
+{\r
+ m_typeSemaphore.acquire();\r
+}\r
#include <QList>\r
#include <QVariant>\r
#include <QVector>\r
+#include <QSemaphore>\r
\r
-class ShoppingTreeItem\r
+class ShoppingTreeItem : public QObject\r
{\r
+Q_OBJECT\r
+\r
public:\r
+\r
+ enum ItemType\r
+ {\r
+ Category = 0,\r
+ Item = 1,\r
+\r
+ NotDefined = -1\r
+ };\r
+\r
ShoppingTreeItem(const QVector<QVariant> &data, ShoppingTreeItem *parent = 0);\r
~ShoppingTreeItem();\r
\r
int columnCount() const;\r
QVariant data(int column) const;\r
bool insertChildren(int position, int count, int columns);\r
+ bool insertColumns(int position, int columns);\r
ShoppingTreeItem *parent();\r
bool removeChildren(int position, int count);\r
+ bool removeColumns(int position, int columns);\r
int childNumber() const;\r
bool setData(int column, const QVariant &value);\r
+ bool setItemType(const ItemType type);\r
+ ItemType getItemType() const;\r
+ void waitItemTypeDefinition();\r
+\r
+signals:\r
+ void childInserted(ShoppingTreeItem *item);\r
+ void dataChanged(int column);\r
+ void childRemoved(ShoppingTreeItem *item);\r
\r
private:\r
QList<ShoppingTreeItem*> childItems;\r
QVector<QVariant> itemData;\r
ShoppingTreeItem *parentItem;\r
+\r
+ ItemType m_itemType;\r
+ QSemaphore m_typeSemaphore;\r
};\r
\r
#endif // SHOPPINGTREEITEM_H\r
rootItem->columnCount());\r
QVector<QVariant> columnData =\r
getColumnsFromItemElement(child);\r
+ rootItem->child(rootItem->childCount() - 1)->\r
+ setItemType(ShoppingTreeItem::Item);\r
for(int column = 0; column < columnData.size(); column++)\r
{\r
rootItem->child(rootItem->childCount() - 1)->setData(column, columnData[column]);\r
m_domElementForItem.insert(rootItem->child(rootItem->childCount() - 1),\r
child);\r
}\r
+\r
+ QHashIterator<ShoppingTreeItem*,QDomElement> i(m_domElementForItem);\r
+ while(i.hasNext())\r
+ {\r
+ i.next();\r
+ connect(i.key(), SIGNAL(childInserted(ShoppingTreeItem*)), this,\r
+ SLOT(registerInsertedChild(ShoppingTreeItem*)));\r
+ connect(i.key(), SIGNAL(childRemoved(ShoppingTreeItem*)), this,\r
+ SLOT(deleteRemovedChild(ShoppingTreeItem*)));\r
+ }\r
}\r
\r
ShoppingTreeModel::~ShoppingTreeModel()\r
return QModelIndex();\r
}\r
\r
+bool ShoppingTreeModel::insertColumns(int position, int columns, const QModelIndex &parent)\r
+{\r
+ bool success;\r
+\r
+ beginInsertColumns(parent, position, position + columns - 1);\r
+ success = rootItem->insertColumns(position, columns);\r
+ endInsertColumns();\r
+\r
+ return success;\r
+}\r
+\r
bool ShoppingTreeModel::insertRows(int position, int rows, const QModelIndex &parent)\r
{\r
ShoppingTreeItem *parentItem = getItem(parent);\r
return createIndex(parentItem->childNumber(), 0, parentItem);\r
}\r
\r
+bool ShoppingTreeModel::removeColumns(int position, int columns, const QModelIndex &parent)\r
+{\r
+ bool success;\r
+\r
+ beginRemoveColumns(parent, position, position + columns - 1);\r
+ success = rootItem->removeColumns(position, columns);\r
+ endRemoveColumns();\r
+\r
+ if (rootItem->columnCount() == 0)\r
+ removeRows(0, rowCount());\r
+\r
+ return success;\r
+}\r
+\r
bool ShoppingTreeModel::removeRows(int position, int rows, const QModelIndex &parent)\r
{\r
ShoppingTreeItem *parentItem = getItem(parent);\r
return result;\r
}\r
\r
+void ShoppingTreeModel::registerInsertedChild(ShoppingTreeItem *item)\r
+{\r
+ // wait until item type is defined\r
+ item->waitItemTypeDefinition();\r
+\r
+ QDomElement parentElement = m_domElementForItem.value(item->parent());\r
+ QDomElement element;\r
+ if(item->getItemType() == ShoppingTreeItem::Category)\r
+ element = m_document.createElement("category");\r
+ else if(item->getItemType() == ShoppingTreeItem::Item)\r
+ element = m_document.createElement("item");\r
+ else\r
+ return;\r
+\r
+ parentElement.appendChild(element);\r
+ updateXmlFile();\r
+ m_domElementForItem.insert(item, element);\r
+ connect(item, SIGNAL(childInserted(ShoppingTreeItem*)), this,\r
+ SLOT(registerInsertedChild(ShoppingTreeItem*)));\r
+ connect(item, SIGNAL(childRemoved(ShoppingTreeItem*)), this,\r
+ SLOT(deleteRemovedChild(ShoppingTreeItem*)));\r
+}\r
+\r
+void ShoppingTreeModel::deleteRemovedChild(ShoppingTreeItem *item)\r
+{\r
+ QDomElement element = m_domElementForItem.value(item);\r
+ QDomNode parentNode = element.parentNode();\r
+ parentNode.removeChild(element);\r
+ updateXmlFile();\r
+ m_domElementForItem.remove(item);\r
+}\r
+\r
void ShoppingTreeModel::parseCategoryElement(const QDomElement &element,\r
ShoppingTreeItem *parentItem)\r
{\r
parentItem->insertChildren(parentItem->childCount(), 1,\r
rootItem->columnCount());\r
\r
+ parentItem->child(parentItem->childCount() - 1)->\r
+ setItemType(ShoppingTreeItem::Category);\r
parentItem->child(parentItem->childCount() - 1)->setData(0, title);\r
m_domElementForItem.insert(parentItem->child(parentItem->childCount() - 1),\r
element);\r
rootItem->columnCount());\r
QVector<QVariant> columnData =\r
getColumnsFromItemElement(child);\r
+ item->child(item->childCount() - 1)->setItemType(ShoppingTreeItem::Item);\r
for(int column = 0; column < columnData.size(); column++)\r
{\r
item->child(item->childCount() - 1)->setData(column, columnData[column]);\r
#include <QModelIndex>\r
#include <QVector>\r
#include <QVariant>\r
+#include <QHash>\r
\r
class ShoppingTreeItem;\r
\r
bool setHeaderData(int section, Qt::Orientation orientation,\r
const QVariant &value, int role = Qt::EditRole);\r
\r
+ bool insertColumns(int position, int columns,\r
+ const QModelIndex &parent = QModelIndex());\r
+ bool removeColumns(int position, int columns,\r
+ const QModelIndex &parent = QModelIndex());\r
bool insertRows(int position, int rows,\r
const QModelIndex &parent = QModelIndex());\r
bool removeRows(int position, int rows,\r
void xmlParseError(QString error, int line, int column);\r
void invalidDocument();\r
\r
+public slots:\r
+ void registerInsertedChild(ShoppingTreeItem *item);\r
+ void deleteRemovedChild(ShoppingTreeItem *item);\r
+\r
protected:\r
void parseCategoryElement(const QDomElement &element,\r
ShoppingTreeItem *parentItem = 0);\r