Update and integrate apps-common Model. 62/140062/3
authorEugene Kurzberg <i.kurtsberg@samsung.com>
Mon, 24 Jul 2017 06:43:32 +0000 (09:43 +0300)
committerEugene Kurzberg <i.kurtsberg@samsung.com>
Mon, 24 Jul 2017 06:43:32 +0000 (09:43 +0300)
Change-Id: I4f64cff416cad59578ba33f65a6ff43c54fc5d5f
Signed-off-by: Eugene Kurzberg <i.kurtsberg@samsung.com>
alarm-app/inc/List/AlarmsView.h
alarm-app/inc/List/Model/AlarmProvider.h [new file with mode: 0644]
alarm-app/src/List/AlarmsView.cpp
alarm-widget/src/AlarmWidget.cpp
lib-apps-common/inc/Model/DataItem.h
lib-apps-common/inc/Model/DataProvider.h
lib-apps-common/src/Model/DataControlProvider.cpp
lib-apps-common/src/Model/DataItem.cpp
lib-apps-common/src/Model/DataProvider.cpp

index ad3c9b140db71e26bbf3677b1f777e8b8bb22d57..9586d3f7b0aacb871fc8b50e1085e38182f7623d 100644 (file)
@@ -17,7 +17,7 @@
 #ifndef LIST_ALARMS_VIEW_H
 #define LIST_ALARMS_VIEW_H
 
-#include "Model/DataControlProvider.h"
+#include "List/Model/AlarmProvider.h"
 #include "Ux/SelectView.h"
 #include <system_settings.h>
 
@@ -61,7 +61,6 @@ namespace List
                virtual void onSelectCountChanged(size_t selectCount) override;
                virtual Evas_Object *createDoneButton() override;
                virtual Ux::MultiSelector *createMultiSelector() override;
-               void onUpdateFinished();
 
                Evas_Object *createContentLayout(Evas_Object *parent);
                Evas_Object *createNoContents(Evas_Object *parent);
@@ -84,7 +83,7 @@ namespace List
                void onItemLongpressed(Evas_Object *genlist, Elm_Object_Item *item);
                bool onSelectFinished();
 
-               Model::DataControlProvider m_Provider;
+               Model::AlarmProvider m_Provider;
                Evas_Object *m_NoContents;
                Evas_Object *m_ContentLayout;
                Ui::Genlist *m_Genlist;
diff --git a/alarm-app/inc/List/Model/AlarmProvider.h b/alarm-app/inc/List/Model/AlarmProvider.h
new file mode 100644 (file)
index 0000000..82cee58
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIST_MODEL_ALARM_PROVIDER_H
+#define LIST_MODEL_ALARM_PROVIDER_H
+
+#include "Model/DataControlProvider.h"
+#include "Common/Model/Alarm.h"
+
+namespace List
+{
+       namespace Model
+       {
+               class AlarmProvider : public ::Model::DataControlProvider
+               {
+               public:
+                       using DataControlProvider::DataControlProvider;
+
+               private:
+                       virtual bool compareDataItems(const ::Model::DataItem *first, const ::Model::DataItem *second) override
+                       {
+                               return static_cast<const Common::Model::Alarm &>(*first) <
+                                               static_cast<const Common::Model::Alarm &>(*second);
+                       }
+               };
+       }
+}
+
+#endif /* LIST_MODEL_ALARM_PROVIDER_H */
index 33000ae371206f96d224e90705122072ea7ae58a..7656e0b42e6f16523f5f82c7c84421832b3185f6 100644 (file)
@@ -84,15 +84,15 @@ Evas_Object *AlarmsView::onCreate(Evas_Object *parent)
 
 void AlarmsView::onCreated()
 {
-       m_Provider.onUpdateFinished() += { std::bind(&AlarmsView::onUpdateFinished, this), this };
+       m_Provider.onUpdated() += { std::bind(&AlarmsView::updateEmptyState, this), this };
        m_Provider.onInserted() += { std::bind(&AlarmsView::onAlarmInserted, this, _1), this };
-       m_Provider.initialize([this] {
+       m_Provider.initialize([this] {
                for (auto &&dataItem : m_Provider.getDataList()) {
                        insertItem(createItem(*dataItem));
                }
                m_AddAlarmItem->getNextItem()->scrollTo(ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
                updateEmptyState();
-       });
+       }, this });
 }
 
 void AlarmsView::onPageAttached(Ui::NavigatorPage *page)
@@ -176,11 +176,6 @@ Ux::MultiSelector *AlarmsView::createMultiSelector()
        return multiSelector;
 }
 
-void AlarmsView::onUpdateFinished()
-{
-       updateEmptyState();
-}
-
 Evas_Object *AlarmsView::createContentLayout(Evas_Object *parent)
 {
        Evas_Object *layout = elm_layout_add(parent);
index 3bcb691fe827a9813a38f3982cf960ce6de24e3c..c98c0523ec96aed4d606d6bf7ee067d90a6db131 100644 (file)
@@ -194,7 +194,7 @@ void AlarmWidget::setAlarm(Alarm *alarm)
                        widget->saveContent(bundle.getBundle());
                }, this);
        }, this };
-       m_Alarm->onUpdated() += { [this](int changes) {
+       m_Alarm->onUpdated() += { [this](int changes, DataItem *nextDataItem) {
                updateContentLayout(changes);
        }, this };
 
index ff70af60680fd5d09465c5f6ab79c8b36dfdc3af..fb9684d3dbbb7b3546f10bbd172b6ff2174d4161 100644 (file)
@@ -28,8 +28,8 @@ namespace Model
        enum ChangeType
        {
                ChangeNone,
-               ChangeInsert,
                ChangeUpdate,
+               ChangeInsert,
                ChangeDelete
        };
 
@@ -38,9 +38,10 @@ namespace Model
        public:
                /**
                 * @brief Called after item was updated.
-                * @param[in] Which item data was updated (depends on the specific item)
+                * @param[in]   Which item data was updated (depends on the specific item)
+                * @param[in]   Next item according to sort order
                 */
-               typedef Utils::CallbackManager<int> UpdateCallback;
+               typedef Utils::CallbackManager<int, DataItem *> UpdateCallback;
 
                /**
                 * @brief Called before item is deleted.
@@ -48,8 +49,8 @@ namespace Model
                typedef Utils::CallbackManager<> DeleteCallback;
 
                DataItem();
-               DataItem(const DataItem &);
-               DataItem &operator=(const DataItem &);
+               DataItem(const DataItem &that);
+               DataItem &operator=(const DataItem &that);
                virtual ~DataItem() { }
 
                /**
@@ -58,13 +59,23 @@ namespace Model
                int getId() const;
 
                /**
-                * @brief Update item with new data.
-                * @param[in]   data    New item data
+                * @return Custom data associated with the item.
                 */
-               void update(void *data);
+               void *getUserData() const;
 
                /**
-                * @return Whether is standalone (not managed by DataProvider).
+                * @brief Set custom data associated with the item.
+                * @param[in]   data    Data to set
+                */
+               void setUserData(void *data);
+
+               /**
+                * @return Whether the item was changed during update.
+                */
+               bool isChanged() const;
+
+               /**
+                * @return Whether item is standalone (not managed by DataProvider).
                 */
                bool isStandalone() const;
 
@@ -85,6 +96,13 @@ namespace Model
                DeleteCallback &onDeleted();
 
        protected:
+               /**
+                * @brief Update item with new data.
+                * @param[in]   data    New item data
+                * @return Mask describing detected changes or 0 if none.
+                */
+               int update(void *data);
+
                /**
                 * @brief Set ID.
                 * @param[in]   id   Data item id
@@ -113,12 +131,13 @@ namespace Model
 
        private:
                friend class DataProvider;
-               void finishUpdate();
+               void finishUpdate(DataItem *nextItem = nullptr);
 
                int m_Id;
                bool m_IsStandalone;
                int m_Changes;
                ChangeType m_ChangeType;
+               void *m_UserData;
 
                UpdateCallback m_OnUpdated;
                DeleteCallback m_OnDeleted;
index 101023b6d3c7ef283124662c38ff8ae5e48046b1..2e8a891f78050ed335c1214d29b7607890f235c4 100644 (file)
 #define MODEL_DATA_PROVIDER_H
 
 #include "Model/DataItem.h"
-
-#include <list>
+#include <vector>
 
 namespace Model
 {
        class EXPORT_API DataProvider
        {
        public:
-               typedef std::list<DataItem *> DataList;
+               typedef std::vector<DataItem *> DataList;
 
                /**
                 * @brief Called once initialization is finished.
                 */
-               typedef std::function<void()> InitializeCallback;
+               typedef Utils::CallbackManager<> InitializeCallback;
 
                /**
-                * @brief Called when provider has started or finished updating its items.
+                * @brief Called when provider has finished updating its items.
                 */
                typedef Utils::CallbackManager<> UpdateCallback;
 
                /**
                 * @brief Called after item was inserted.
                 * @param[in]   Inserted item
+                * @param[in]   Next item according to sort order
                 */
-               typedef Utils::CallbackManager<DataItem &> InsertCallback;
+               typedef Utils::CallbackManager<DataItem &, DataItem *> InsertCallback;
 
                DataProvider();
                virtual ~DataProvider();
 
                /**
-                * @return Provider data list.
+                * @return List of provided data items.
                 */
-               const DataList &getDataList();
+               const DataList &getDataList() const;
 
                /**
                 * @brief Initialize provider data.
                 * @remark Should be called before retrieving the data.
                 * @param[in]   callback    Initialization finished callback
                 */
-               void initialize(InitializeCallback callback);
+               void initialize(InitializeCallback::Callback callback);
 
                /**
                 * @brief Update provider data.
@@ -80,6 +80,13 @@ namespace Model
                 */
                DataItem *findDataItem(int id);
 
+               /**
+                * @brief Find next item for the specified data item according to sort order.
+                * @param[in]   dataItem    Data item to find next item for
+                * @return Next data item or nullptr if none.
+                */
+               DataItem *findNextDataItem(DataItem &dataItem);
+
                /**
                 * @brief Set whether to start update immediately when update() is called.
                 * @param[in]   isEnabled   Whether data update is enabled
@@ -87,19 +94,19 @@ namespace Model
                void setUpdateEnabled(bool isEnabled);
 
                /**
-                * @brief Add/remove insert callback.
+                * @brief Add/remove initialize callback.
                 */
-               InsertCallback &onInserted();
+               InitializeCallback &onInitialized();
 
                /**
-                * @brief Add/remove update start callback.
+                * @brief Add/remove insert callback.
                 */
-               UpdateCallback &onUpdateStarted();
+               InsertCallback &onInserted();
 
                /**
-                * @brief Add/remove update finish callback.
+                * @brief Add/remove update callback.
                 */
-               UpdateCallback &onUpdateFinished();
+               UpdateCallback &onUpdated();
 
        protected:
                /**
@@ -114,12 +121,32 @@ namespace Model
                 */
                virtual void startUpdate() = 0;
 
+               /**
+                * @brief Called to compare two data items for sorting.
+                * @param[in]   first   First item
+                * @param[in]   second  Second item
+                * @return Whether first item is less than second.
+                */
+               virtual bool compareDataItems(const DataItem *first, const DataItem *second) = 0;
+
+               /**
+                * @brief Called after setUpdateEnabled().
+                */
+               virtual void onUpdateEnabled(bool isEnabled) { }
+
                /**
                 * @brief Insert new DataItem into the list.
                 * @param[in]   dataItem    New data item
                 */
                void insertDataItem(DataItem *dataItem);
 
+               /**
+                * @brief Update DataItem with new data.
+                * @param[in]   dataItem    Data item to update
+                * @param[in]   data        New item data
+                */
+               void updateDataItem(DataItem &dataItem, void *data);
+
                /**
                 * @brief Delete DataItem from the list.
                 * @param[in]   dataItem    Data item to be deleted
@@ -128,9 +155,8 @@ namespace Model
 
                /**
                 * @brief Should be called when initialization is finished.
-                * @param[in]   dataList    Initialized data list
                 */
-               void finishInit(DataList dataList);
+               void finishInit();
 
                /**
                 * @brief Should be called when update is finished.
@@ -139,6 +165,8 @@ namespace Model
                void finishUpdate();
 
        private:
+               void insertSorted(DataItem *dataItem);
+
                bool m_IsBusy;
                bool m_IsInitialized;
                bool m_IsUpdateEnabled;
@@ -147,8 +175,7 @@ namespace Model
 
                InitializeCallback m_OnInitialized;
                InsertCallback m_OnInserted;
-               UpdateCallback m_OnUpdateStarted;
-               UpdateCallback m_OnUpdateFinished;
+               UpdateCallback m_OnUpdated;
 
                DataList m_DataList;
        };
index e7f6313e13450a3e4ed2896f709fa2c6ac501450..be78ce764565b3cd3f8de97a03491e61f7e100b8 100644 (file)
@@ -32,8 +32,13 @@ DataControlProvider::~DataControlProvider()
 
 void DataControlProvider::startInit()
 {
-       m_Consumer.getDataItems(std::bind(&DataControlProvider::finishInit, this, _1));
        m_Consumer.onDataItemChanged() += { std::bind(&DataControlProvider::onDataItemChanged, this, _1, _2), this };
+       m_Consumer.getDataItems([this](DataList dataItems) {
+               for (auto &&dataItem : dataItems) {
+                       insertDataItem(dataItem);
+               }
+               finishInit();
+       });
 }
 
 void DataControlProvider::startUpdate()
@@ -67,7 +72,7 @@ void DataControlProvider::applyChange(ChangeInfo change, ::Model::DataItem *newI
                        break;
                case DATA_CONTROL_DATA_CHANGE_SQL_UPDATE:
                        if (auto item = findDataItem(change.id)) {
-                               item->update(newItem);
+                               updateDataItem(*item, newItem);
                        }
                        delete newItem;
                        break;
index b9622f0e49e1da701cfc9f2915ef04a5408420eb..22900ddbf719bd87214141db86fe60329024220e 100644 (file)
@@ -19,7 +19,8 @@
 using namespace Model;
 
 DataItem::DataItem()
-       : m_Id(0), m_IsStandalone(false), m_Changes(0), m_ChangeType(ChangeNone)
+       : m_Id(0), m_IsStandalone(false), m_Changes(0), m_ChangeType(ChangeNone),
+         m_UserData(nullptr)
 {
 }
 
@@ -46,14 +47,19 @@ int DataItem::getId() const
        return m_Id;
 }
 
-void DataItem::update(void *data)
+void *DataItem::getUserData() const
 {
-       m_Changes |= onUpdate(data);
-       m_ChangeType = ChangeUpdate;
+       return m_UserData;
+}
 
-       if (m_IsStandalone) {
-               finishUpdate();
-       }
+void DataItem::setUserData(void *data)
+{
+       m_UserData = data;
+}
+
+bool DataItem::isChanged() const
+{
+       return m_ChangeType != ChangeNone;
 }
 
 bool DataItem::isStandalone() const
@@ -79,6 +85,13 @@ DataItem::DeleteCallback &DataItem::onDeleted()
        return m_OnDeleted;
 }
 
+int DataItem::update(void *data)
+{
+       int changes = onUpdate(data);
+       setChanged(ChangeUpdate, changes);
+       return changes;
+}
+
 void DataItem::setId(int id)
 {
        m_Id = id;
@@ -86,7 +99,7 @@ void DataItem::setId(int id)
 
 void DataItem::setChanged(ChangeType changeType, int changes)
 {
-       if (m_ChangeType == ChangeNone) {
+       if (m_ChangeType < changeType) {
                m_ChangeType = changeType;
        }
        if (changeType == ChangeUpdate) {
@@ -98,12 +111,12 @@ void DataItem::setChanged(ChangeType changeType, int changes)
        }
 }
 
-void DataItem::finishUpdate()
+void DataItem::finishUpdate(DataItem *nextItem)
 {
        switch (m_ChangeType) {
                case ChangeUpdate:
                        if (m_Changes) {
-                               m_OnUpdated(m_Changes);
+                               m_OnUpdated(m_Changes, nextItem);
                        }
                        break;
                case ChangeDelete:
index b48c17701da84f76b4c906e4a656f58f03af0558..86b6469d49d994b2a102f4752fdbe88cbb18424a 100644 (file)
  */
 
 #include "Model/DataProvider.h"
+#include <algorithm>
 
 using namespace Model;
+using namespace std::placeholders;
 
 DataProvider::DataProvider()
        : m_IsBusy(false), m_IsInitialized(false),
@@ -32,19 +34,19 @@ DataProvider::~DataProvider()
        }
 }
 
-const DataProvider::DataList &DataProvider::getDataList()
+const DataProvider::DataList &DataProvider::getDataList() const
 {
        return m_DataList;
 }
 
-void DataProvider::initialize(InitializeCallback callback)
+void DataProvider::initialize(InitializeCallback::Callback callback)
 {
        if (m_IsInitialized || m_IsBusy) {
                return;
        }
 
        m_IsBusy = true;
-       m_OnInitialized = std::move(callback);
+       m_OnInitialized += std::move(callback);
 
        startInit();
 }
@@ -62,7 +64,6 @@ void DataProvider::update()
 
        m_IsBusy = true;
        m_IsUpdatePending = false;
-       m_OnUpdateStarted();
 
        startUpdate();
 }
@@ -86,12 +87,28 @@ DataItem *DataProvider::findDataItem(int id)
        return nullptr;
 }
 
+DataItem *DataProvider::findNextDataItem(DataItem &dataItem)
+{
+       auto it = std::find(m_DataList.begin(), m_DataList.end(), &dataItem);
+       if (it != m_DataList.end() && ++it != m_DataList.end()) {
+               return *it;
+       }
+
+       return nullptr;
+}
+
 void DataProvider::setUpdateEnabled(bool isEnabled)
 {
        m_IsUpdateEnabled = isEnabled;
        if (m_IsUpdateEnabled && m_IsUpdatePending) {
                update();
        }
+       onUpdateEnabled(m_IsUpdateEnabled);
+}
+
+DataProvider::InitializeCallback &DataProvider::onInitialized()
+{
+       return m_OnInitialized;
 }
 
 DataProvider::InsertCallback &DataProvider::onInserted()
@@ -99,42 +116,45 @@ DataProvider::InsertCallback &DataProvider::onInserted()
        return m_OnInserted;
 }
 
-DataProvider::UpdateCallback &DataProvider::onUpdateStarted()
+DataProvider::UpdateCallback &DataProvider::onUpdated()
 {
-       return m_OnUpdateStarted;
+       return m_OnUpdated;
 }
 
-DataProvider::UpdateCallback &DataProvider::onUpdateFinished()
+void DataProvider::insertDataItem(DataItem *dataItem)
 {
-       return m_OnUpdateFinished;
+       if (m_IsInitialized) {
+               dataItem->setChanged(ChangeInsert);
+       }
+
+       insertSorted(dataItem);
 }
 
-void DataProvider::insertDataItem(DataItem *dataItem)
+void DataProvider::updateDataItem(DataItem &dataItem, void *data)
 {
-       dataItem->m_ChangeType = ChangeInsert;
-       m_DataList.push_back(dataItem);
+       if (dataItem.update(data)) {
+               auto it = std::find(m_DataList.begin(), m_DataList.end(), &dataItem);
+               if (it != m_DataList.end()) {
+                       m_DataList.erase(it);
+               }
+               insertSorted(&dataItem);
+       }
 }
 
 void DataProvider::deleteDataItem(DataItem &dataItem)
 {
-       dataItem.m_ChangeType = ChangeDelete;
+       dataItem.setChanged(ChangeDelete);
 }
 
-void DataProvider::finishInit(DataList dataList)
+void DataProvider::finishInit()
 {
        if (m_IsDestroyPending) {
                delete this;
                return;
        }
 
-       m_DataList = std::move(dataList);
        m_IsInitialized = true;
-
-       if (m_OnInitialized) {
-               m_OnInitialized();
-               m_OnInitialized = nullptr;
-       }
-
+       m_OnInitialized();
        m_IsBusy = false;
 }
 
@@ -145,26 +165,35 @@ void DataProvider::finishUpdate()
                return;
        }
 
-       for (auto it = m_DataList.begin(); it != m_DataList.end(); ) {
+       DataItem *nextItem = nullptr;
+       for (auto it = m_DataList.rbegin(); it != m_DataList.rend(); ) {
                auto changeType = (*it)->m_ChangeType;
-               (*it)->finishUpdate();
+               (*it)->finishUpdate(nextItem);
 
                if (changeType == ChangeInsert) {
                        if (m_OnInserted) {
-                               m_OnInserted(**it);
+                               m_OnInserted(**it, nextItem);
                        }
                } else if (changeType == ChangeDelete) {
                        delete *it;
-                       it = m_DataList.erase(it);
+                       it = DataList::reverse_iterator(m_DataList.erase((++it).base()));
                        continue;
                }
 
+               nextItem = *it;
                ++it;
        }
-       m_OnUpdateFinished();
+       m_OnUpdated();
 
        m_IsBusy = false;
        if (m_IsUpdatePending) {
                update();
        }
 }
+
+void DataProvider::insertSorted(DataItem *dataItem)
+{
+       auto nextItem = std::upper_bound(m_DataList.begin(), m_DataList.end(),
+                       dataItem, std::bind(&DataProvider::compareDataItems, this, _1, _2));
+       m_DataList.insert(nextItem, dataItem);
+}