git-svn-id: file:///svnroot/family-shop-mgr@11 26eb2498-383b-47a6-be48-5d6f36779e85
authoronil <u.irigoyen@gmail.com>
Fri, 11 Dec 2009 14:39:55 +0000 (14:39 +0000)
committeronil <u.irigoyen@gmail.com>
Fri, 11 Dec 2009 14:39:55 +0000 (14:39 +0000)
code/family-shop-mgr/GoShopping.ui
code/family-shop-mgr/ListManager.ui
code/family-shop-mgr/ShoppingTreeItem.cpp
code/family-shop-mgr/ShoppingTreeItem.h
code/family-shop-mgr/ShoppingTreeModel.cpp
code/family-shop-mgr/ShoppingTreeModel.h

index 1bfdd43..92e0978 100644 (file)
   <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
index c7bf143..205ddf7 100644 (file)
@@ -1,21 +1,55 @@
-<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
index 69daf33..5f8faa1 100644 (file)
@@ -21,7 +21,8 @@
 \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
@@ -69,11 +70,26 @@ bool ShoppingTreeItem::insertChildren(int position, int count, int columns)
         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
@@ -85,7 +101,25 @@ bool ShoppingTreeItem::removeChildren(int position, int count)
         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
@@ -95,6 +129,33 @@ bool ShoppingTreeItem::setData(int column, const QVariant &value)
     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
index 71b71fe..2ff73b0 100644 (file)
 #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
@@ -37,15 +49,28 @@ public:
     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
index 4690694..1d0120d 100644 (file)
@@ -84,6 +84,8 @@ QAbstractItemModel(parent), m_document("ShoppingList")
                 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
@@ -91,6 +93,16 @@ QAbstractItemModel(parent), m_document("ShoppingList")
         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
@@ -151,6 +163,17 @@ QModelIndex ShoppingTreeModel::index(int row, int column, const QModelIndex &par
         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
@@ -177,6 +200,20 @@ QModelIndex ShoppingTreeModel::parent(const QModelIndex &index) const
     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
@@ -235,6 +272,38 @@ bool ShoppingTreeModel::setHeaderData(int section, Qt::Orientation orientation,
     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
@@ -249,6 +318,8 @@ void ShoppingTreeModel::parseCategoryElement(const QDomElement &element,
         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
@@ -275,6 +346,7 @@ void ShoppingTreeModel::parseCategoryElement(const QDomElement &element,
                     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
index 5270732..31301d6 100644 (file)
@@ -27,6 +27,7 @@
 #include <QModelIndex>\r
 #include <QVector>\r
 #include <QVariant>\r
+#include <QHash>\r
 \r
 class ShoppingTreeItem;\r
 \r
@@ -54,6 +55,10 @@ public:
     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
@@ -63,6 +68,10 @@ signals:
     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