From 53ef7bfb80484727b3e67f806a0339c898dbd653 Mon Sep 17 00:00:00 2001
From: Gennady Pospelov <g.pospelov@fz-juelich.de>
Date: Tue, 15 Mar 2016 17:55:23 +0100
Subject: [PATCH] New signal onSiblingsChange is added to mapper

---
 GUI/coregui/Models/ModelMapper.cpp          | 101 +++++++++++++-------
 GUI/coregui/Models/ModelMapper.h            |   5 +
 Tests/UnitTests/TestGUI/TestMapperForItem.h |  47 ++++++++-
 3 files changed, 117 insertions(+), 36 deletions(-)

diff --git a/GUI/coregui/Models/ModelMapper.cpp b/GUI/coregui/Models/ModelMapper.cpp
index 2c01a988448..15f3be5bf1c 100644
--- a/GUI/coregui/Models/ModelMapper.cpp
+++ b/GUI/coregui/Models/ModelMapper.cpp
@@ -55,6 +55,11 @@ void ModelMapper::setOnChildrenChange(std::function<void ()> f)
     m_onChildrenChange.push_back(f);
 }
 
+void ModelMapper::setOnSiblingsChange(std::function<void ()> f)
+{
+    m_onSiblingsChange.push_back(f);
+}
+
 void ModelMapper::setModel(SessionModel *model)
 {
     if (m_model) {
@@ -86,6 +91,15 @@ int ModelMapper::nestlingDepth(SessionItem *item, int level)
 
 }
 
+void ModelMapper::callOnSiblingsChange()
+{
+    if (m_active && m_onSiblingsChange.size() > 0) {
+        for (auto f : m_onSiblingsChange) {
+            f();
+        }
+    }
+}
+
 void ModelMapper::onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
                                 const QVector<int> &roles)
 {
@@ -128,61 +142,78 @@ void ModelMapper::onDataChanged(const QModelIndex &topLeft, const QModelIndex &b
 
 void ModelMapper::onRowsInserted(const QModelIndex &parent, int first, int last)
 {
-    if (parent.isValid()) {
-        if (SessionItem *newChild = m_model->itemForIndex(parent.child(first, 0))) {
-            if (m_item == newChild) {
-                if (m_active && m_onParentChange.size() > 0) {
-                    for (auto f : m_onParentChange) {
-                        f(m_model->itemForIndex(parent));
-                    }
+    if(!parent.isValid()) return;
+
+    if (SessionItem *newChild = m_model->itemForIndex(parent.child(first, 0))) {
+        if (m_item == newChild) {
+            if (m_active && m_onParentChange.size() > 0) {
+                for (auto f : m_onParentChange) {
+                    f(m_model->itemForIndex(parent));
                 }
+            }
 
-//                if (m_active && m_onChildrenChange.size() > 0) {
-//                    for (auto f : m_onChildrenChange) {
-//                        f();
-//                    }
+//            if (m_active && m_onChildrenChange.size() > 0) {
+//                for (auto f : m_onChildrenChange) {
+//                    f();
 //                }
-            }
+//            }
+        }
 
-            else if(m_item == newChild->parent()) {
-                if (m_active && m_onChildrenChange.size() > 0) {
-                    for (auto f : m_onChildrenChange) {
-                        f();
-                    }
+        else if(m_item == newChild->parent()) {
+            if (m_active && m_onChildrenChange.size() > 0) {
+                for (auto f : m_onChildrenChange) {
+                    f();
                 }
             }
+        }
 
+        // inform siblings about the change
+        if(SessionItem *parent = newChild->parent()) {
+            QVector<SessionItem *> items = parent->getItems(parent->tagFromItem(newChild));
+            foreach(SessionItem *sibling, items) {
+                if(m_item == sibling) callOnSiblingsChange();
+            }
         }
 
     }
+
 }
 
 void ModelMapper::onBeginRemoveRows(const QModelIndex &parent, int first, int last)
 {
-    if (parent.isValid()) {
-        if (SessionItem *newChild = m_model->itemForIndex(parent.child(first, 0))) {
-            if (m_item == newChild) {
-                if (m_active && m_onParentChange.size() > 0) {
-                    for (auto f : m_onParentChange) {
-                        f(nullptr);
-                    }
+    if(!parent.isValid()) return;
+
+    if (SessionItem *newChild = m_model->itemForIndex(parent.child(first, 0))) {
+        if (m_item == newChild) {
+            if (m_active && m_onParentChange.size() > 0) {
+                for (auto f : m_onParentChange) {
+                    f(nullptr);
                 }
-//                if (m_active && m_onChildrenChange.size() > 0) {
-//                    for (auto f : m_onChildrenChange) {
-//                        f();
-//                    }
-//                }
             }
+//            if (m_active && m_onChildrenChange.size() > 0) {
+//                for (auto f : m_onChildrenChange) {
+//                    f();
+//                }
+//            }
+        }
 
-            else if(m_item == newChild->parent()) {
-                if (m_active && m_onChildrenChange.size() > 0) {
-                    for (auto f : m_onChildrenChange) {
-                        f();
-                    }
+        else if(m_item == newChild->parent()) {
+            if (m_active && m_onChildrenChange.size() > 0) {
+                for (auto f : m_onChildrenChange) {
+                    f();
                 }
             }
+        }
 
-
+        // inform siblings about the change
+        if(SessionItem *parent = newChild->parent()) {
+            QVector<SessionItem *> items = parent->getItems(parent->tagFromItem(newChild));
+            foreach(SessionItem *sibling, items) {
+                if(m_item == sibling) callOnSiblingsChange();
+            }
         }
+
+
+
     }
 }
diff --git a/GUI/coregui/Models/ModelMapper.h b/GUI/coregui/Models/ModelMapper.h
index 4ba14916312..8961422eb6c 100644
--- a/GUI/coregui/Models/ModelMapper.h
+++ b/GUI/coregui/Models/ModelMapper.h
@@ -43,6 +43,8 @@ public:
 
     void setOnChildrenChange(std::function<void(void)> f);
 
+    void setOnSiblingsChange(std::function<void(void)> f);
+
     void setActive(bool state) {m_active = state;}
 
 public slots:
@@ -57,6 +59,8 @@ private:
     void setModel(SessionModel *model);
     int nestlingDepth(SessionItem* item, int level = 0);
 
+    void callOnSiblingsChange();
+
     bool m_active;
     SessionModel *m_model;
     SessionItem *m_item;
@@ -64,6 +68,7 @@ private:
     std::vector<std::function<void(SessionItem*,QString)>> m_onChildPropertyChange;
     std::vector<std::function<void(SessionItem*)>> m_onParentChange;
     std::vector<std::function<void(void)>> m_onChildrenChange;
+    std::vector<std::function<void(void)>> m_onSiblingsChange;
 };
 
 #endif
diff --git a/Tests/UnitTests/TestGUI/TestMapperForItem.h b/Tests/UnitTests/TestGUI/TestMapperForItem.h
index bb213fa7f4c..5325e3ba8bf 100644
--- a/Tests/UnitTests/TestGUI/TestMapperForItem.h
+++ b/Tests/UnitTests/TestGUI/TestMapperForItem.h
@@ -22,6 +22,7 @@ public:
         , m_onChildPropertyChangeCount(0)
         , m_onParentChangeCount(0)
         , m_onChildrenChangeCount(0)
+        , m_onSiblingsChangeCount(0)
         , m_mapped_item(0)
     { }
 
@@ -31,6 +32,7 @@ public:
         m_onChildPropertyChangeCount = 0;
         m_onParentChangeCount = 0;
         m_onChildrenChangeCount = 0;
+        m_onSiblingsChangeCount = 0;
         m_mapped_item = 0;
         m_reported_items.clear();
         m_reported_names.clear();
@@ -67,7 +69,11 @@ public:
             onChildrenChange();
         });
 
-
+        m_mapper->setOnSiblingsChange(
+                    [this]()
+        {
+            onSiblingsChange();
+        });
 
     }
 
@@ -96,10 +102,16 @@ private:
         m_onChildrenChangeCount++;
     }
 
+    void onSiblingsChange()
+    {
+        m_onSiblingsChangeCount++;
+    }
+
     int m_onPropertyChangeCount;
     int m_onChildPropertyChangeCount;
     int m_onParentChangeCount;
     int m_onChildrenChangeCount;
+    int m_onSiblingsChangeCount;
     SessionItem *m_mapped_item;
     QList<SessionItem *> m_reported_items;
     QStringList m_reported_names;
@@ -110,6 +122,7 @@ private slots:
     void test_onPropertyChange();
     void test_onParentChange();
     void test_onChildrenChange();
+    void test_onSiblingsChange();
 };
 
 inline void TestMapperForItem::test_onPropertyChange()
@@ -123,6 +136,7 @@ inline void TestMapperForItem::test_onPropertyChange()
     QVERIFY(m_onChildPropertyChangeCount == 0);
     QVERIFY(m_onParentChangeCount == 0);
     QVERIFY(m_onChildrenChangeCount == 0);
+    QVERIFY(m_onSiblingsChangeCount == 0);
     QVERIFY(m_mapped_item == nullptr);
     QVERIFY(m_reported_items.isEmpty());
     QVERIFY(m_reported_names.isEmpty());
@@ -134,6 +148,7 @@ inline void TestMapperForItem::test_onPropertyChange()
     QVERIFY(m_onChildPropertyChangeCount == 0);
     QVERIFY(m_onParentChangeCount == 0);
     QVERIFY(m_onChildrenChangeCount == 0);
+    QVERIFY(m_onSiblingsChangeCount == 0);
     QVERIFY(m_mapped_item == layer);
     QVERIFY(m_reported_items.isEmpty());
     QVERIFY((m_reported_names.size() == 1) && (m_reported_names[0] == LayerItem::P_THICKNESS));
@@ -145,6 +160,7 @@ inline void TestMapperForItem::test_onPropertyChange()
     QVERIFY(m_onChildPropertyChangeCount == 0);
     QVERIFY(m_onParentChangeCount == 0);
     QVERIFY(m_onChildrenChangeCount == 0);
+    QVERIFY(m_onSiblingsChangeCount == 0);
     QVERIFY(m_mapped_item == layer);
     QVERIFY(m_reported_items.isEmpty());
     QVERIFY(m_reported_names.isEmpty());
@@ -156,6 +172,7 @@ inline void TestMapperForItem::test_onPropertyChange()
     QVERIFY(m_onChildPropertyChangeCount == 1);
     QVERIFY(m_onParentChangeCount == 0);
     QVERIFY(m_onChildrenChangeCount == 0);
+    QVERIFY(m_onSiblingsChangeCount == 0);
     QVERIFY(m_mapped_item == multilayer);
     QVERIFY( (m_reported_items.size() == 1) && (m_reported_items[0] == layer));
     QVERIFY((m_reported_names.size() == 1) && (m_reported_names[0] == LayerItem::P_THICKNESS));
@@ -167,6 +184,7 @@ inline void TestMapperForItem::test_onPropertyChange()
     QVERIFY(m_onChildPropertyChangeCount == 0);
     QVERIFY(m_onParentChangeCount == 0);
     QVERIFY(m_onChildrenChangeCount == 0);
+    QVERIFY(m_onSiblingsChangeCount == 0);
     QVERIFY(m_mapped_item == multilayer);
     QVERIFY(m_reported_items.isEmpty());
     QVERIFY((m_reported_names.size() == 1) && (m_reported_names[0] == MultiLayerItem::P_CROSS_CORR_LENGTH));
@@ -209,10 +227,37 @@ inline void TestMapperForItem::test_onChildrenChange()
     QVERIFY(m_onChildPropertyChangeCount == 2);
     QVERIFY(m_onParentChangeCount == 0);
     QVERIFY(m_onChildrenChangeCount == 1);
+    QVERIFY(m_onSiblingsChangeCount == 0);
     QVERIFY(m_mapped_item == multilayer);
     QVERIFY(m_reported_items.size() == 2);
     QVERIFY(m_reported_names.size() == 2);
 }
 
+inline void TestMapperForItem::test_onSiblingsChange()
+{
+    clear();
+    SampleModel model;
+    SessionItem *multilayer = model.insertNewItem(Constants::MultiLayerType);
+    SessionItem *layer = model.insertNewItem(Constants::LayerType, model.indexOfItem(multilayer));
+
+    // Mapper is looking on child; adding another child to parent
+    setItem(layer);
+    SessionItem *layer2 = model.insertNewItem(Constants::LayerType, model.indexOfItem(multilayer));
+
+    QVERIFY(m_onPropertyChangeCount == 0);
+    QVERIFY(m_onChildPropertyChangeCount == 0);
+    QVERIFY(m_onParentChangeCount == 0);
+    QVERIFY(m_onChildrenChangeCount == 0);
+    QVERIFY(m_onSiblingsChangeCount == 1);
+    QVERIFY(m_mapped_item == layer);
+    QVERIFY(m_reported_items.isEmpty());
+    QVERIFY(m_reported_names.isEmpty());
+
+    multilayer->takeRow(layer2->parentRow());
+    QVERIFY(m_onSiblingsChangeCount == 2);
+
+}
+
+
 
 #endif
-- 
GitLab