TizenRefApp-5303 Implement onLog Changed callback 20/55420/14
authorIryna Ferenchak <i.ferenchak@samsung.com>
Wed, 3 Feb 2016 15:30:56 +0000 (17:30 +0200)
committerIryna Ferenchak <i.ferenchak@samsung.com>
Wed, 3 Feb 2016 15:30:56 +0000 (17:30 +0200)
Change-Id: I139ecd15688931c4e550be6128045b187fecf373
Signed-off-by: Iryna Ferenchak <i.ferenchak@samsung.com>
lib-logs/inc/Logs/Model/Log.h
lib-logs/inc/Logs/Model/LogGroup.h
lib-logs/inc/Logs/Model/LogProvider.h
lib-logs/inc/Logs/Model/LogRecord.h [deleted file]
lib-logs/inc/Logs/Model/LogType.h [deleted file]
lib-logs/src/Logs/Model/Log.cpp [new file with mode: 0644]
lib-logs/src/Logs/Model/LogGroup.cpp
lib-logs/src/Logs/Model/LogProvider.cpp
lib-logs/src/Logs/Model/LogRecord.cpp [deleted file]

index 52fb12977d75e06954a4fdfddebbfa7fe183dc61..a53644aea73b5e5bfda67ab0f2c0c726f97a914b 100644 (file)
@@ -25,59 +25,81 @@ namespace Logs
 {
        namespace Model
        {
+               class LogGroup;
                /**
-                * @brief Log information
+                * @brief Log record information
                 */
                class Log
                {
                public:
-                       virtual ~Log() { }
                        /**
-                        * @return is log group
+                        * @brief Create log record
+                        * @param[in]   record  Log record (_contact_person_phone_log)
                         */
-                       virtual bool isGroup() const = 0;
-
-                       /**
-                        * @return log record
-                        */
-                       virtual const contacts_record_h getLogRecord() const = 0;
+                       Log(contacts_record_h record);
+                       ~Log();
+                       Log(const Log &log) = delete;
+                       Log &operator=(const Log &log) = delete;
 
                        /**
                         * @return log name
                         */
-                       virtual const char *getName() const = 0;
+                       const char *getName() const;
 
                        /**
                         * @return log number
                         */
-                       virtual const char *getNumber() const = 0;
+                       const char *getNumber() const;
 
                        /**
                         * @return log name image path
                         */
-                       virtual const char *getImagePath() const = 0 ;
+                       const char *getImagePath() const;
 
                        /**
                         * @return log type
                         */
-                       virtual int getType() const = 0;
+                       int getType() const;
 
                        /**
                         * @return log time
                         */
-                       virtual struct tm getTime() const = 0;
+                       tm getTime() const;
 
                        /**
                         * @return log id
                         */
-                       virtual int getId() const = 0;
+                       int getId() const;
 
                        /**
                         * @return log person id
                         */
-                       virtual int getPersonId() const = 0;
+                       int getPersonId() const;
+
+                       /**
+                        * @brief  Set log group
+                        * @param[in]   logGroup  Parent log group
+                        */
+                       void setLogGroup(LogGroup *group);
+
+                       /**
+                        * @return Parent log group
+                        */
+                       LogGroup *getLogGroup() const;
+
+                       /**
+                        * @return Remove log from database
+                        */
+                       void remove();
+
+               private:
+                       contacts_record_h getContactRecord();
+
+                       contacts_record_h m_LogRecord;
+                       contacts_record_h m_ContactRecord;
+
+                       LogGroup *m_Group;
                };
        }
 }
-
 #endif /* LOGS_MODEL_LOG_H */
index aef4643bedaaeb2e1c9cc203925e1a30517da4e3..f6c86fce9d42509495fc73665d849900e1d91106 100644 (file)
 #ifndef LOGS_MODEL_LOG_GROUP_H
 #define LOGS_MODEL_LOG_GROUP_H
 
-#include "Logs/Model/Log.h"
-#include "Logs/Model/LogType.h"
+#include <list>
+#include <functional>
 
 namespace Logs
 {
        namespace Model
        {
+               class Log;
+
                /**
                 * @brief Group of logs
                 */
-               class LogGroup : public Log
+               class LogGroup
                {
                public:
 
+                       enum ChangedType {
+                               Remove,
+                               Update
+                       };
                        /**
-                        * @see Log::isGroup()
+                        * @brief Changed group callback
                         */
-                       virtual bool isGroup() const override;
+                       typedef std::function<void(ChangedType)> ChangeCallback;
 
                        /**
-                        * @see Log::getLogRecord()
+                        * @brief List of logs.
                         */
-                       virtual const contacts_record_h getLogRecord() const override;
+                       typedef std::list<Log *> LogList;
 
                        /**
-                        * @see Log::getName()
-                        */
-                       virtual const char *getName() const override;
-
-                       /**
-                        * @see Log::getNumber()
-                        */
-                       virtual const char *getNumber() const override;
-
-                       /**
-                        * @see Log::getImagePath()
+                        * @brief Constructor
+                        * @param[in]   log  Log to add
                         */
-                       virtual const char *getImagePath() const override;
+                       LogGroup(Log *log);
 
                        /**
-                        * @see Log::getType()
+                        * @brief Get log group list
+                        * @return list of log. The reference will be valid till this LogGroup object exist.
                         */
-                       virtual int getType() const override;
+                       const LogList &getLogList() const;
 
                        /**
-                        * @see Log::getTime()
+                        * @brief Set log changed callback
+                        * @remark Callback called when log is changed.
+                        * @param[in]    callback    Changed log callback
                         */
-                       virtual struct tm getTime() const override;
+                       void setChangeCallback(ChangeCallback callback);
 
                        /**
-                        * @see Log::getId()
+                        * @brief Unset log change callback
                         */
-                       virtual int getId() const override;
+                       void unsetChangeCallback();
 
                        /**
-                        * @see Log::getPersonId()
+                        * @brief Call log change callback
+                        * @param[in]   type  Changed type
                         */
-                       virtual int getPersonId() const override;
+                       void onChange(ChangedType type);
 
                        /**
-                        * @brief Remove log from LogGroup by id
-                        * @param[in]   id  Log id
+                        * @brief Add log to LogGroup
+                        * @param[in]   log  Log to add
                         */
-                       void removeLog(int id);
+                       void addLog(Log *log);
 
                        /**
-                        * @brief Add log to LogGroup
-                        * @param[in]   log  Log to add
+                        * @brief Remove log from log group
+                        * @param[in]   log  Log to remove
                         */
-                       void addLog(LogPtr log);
+                       void removeLog(Log *log);
 
                        /**
-                        * @brief Get log group list
-                        * @return list of log group. The reference will be valid till this LogGroup object exist.
+                        * @brief Remove all logs from database
                         */
-                       const LogList &getLogList() const;
+                       void remove();
 
                private:
                        LogList m_LogList;
+
+                       ChangeCallback m_ChangeCallback;
                };
        }
 }
index 3c8cf701da20fe9382fb06f3aed699fb8c4ad4ba..842d250d74be97bafd7ddea7a315d742ac1a88ed 100644 (file)
 #ifndef LOGS_MODEL_LOG_PROVIDER_H
 #define LOGS_MODEL_LOG_PROVIDER_H
 
-#include <map>
 #include <contacts.h>
-#include "Logs/Model/LogType.h"
+#include <memory>
+#include <set>
+
+#include "Logs/Model/Log.h"
+#include "Logs/Model/LogGroup.h"
 
 namespace Logs
 {
@@ -33,67 +36,96 @@ namespace Logs
                {
                public:
                        /**
-                        * @brief Constructor
+                        * @brief Unique logs.
                         */
-                       LogProvider();
+                       typedef std::unique_ptr<Log> LogPtr;
 
                        /**
-                        * @brief Destructor
+                        * @brief Unique logs.
                         */
-                       ~LogProvider();
+                       typedef std::unique_ptr<LogGroup> LogGroupPtr;
 
                        /**
-                        * @brief Get log list
-                        * @return list of logs.
+                        * @brief Log list.
                         */
-                       const LogList &getLogList() const;
+                       typedef std::list<LogPtr> LogList;
 
                        /**
-                        * @brief Add contact change callback
-                        * @remark Callback called when contact update or delete or insert
-                        * @param[in]    id          Contact ID or null to insert contact
-                        * @param[in]    callback    Change contact callback
+                        * @brief Log group list.
                         */
-                       void addContactChangeCallback(int id, ContactChangeCallback callback);
+                       typedef std::list<LogGroupPtr> LogGroupList;
 
                        /**
-                        * @brief Remove contact change callback
-                        * @param[in]    id    Contact ID
+                        * @brief Log iterator.
                         */
-                       void removeContactChangeCallback(int id);
+                       typedef LogList::iterator LogIterator;
 
                        /**
-                        * @brief Set log change callback
-                        * @remark It can be update or delete or insert of contact
-                        * @param[in]    callback    Change Log callback
+                        * @brief New log group callback
+                        * @param[in]    logGroup    Log group
                         */
-                       void setLogChangeCallback(LogChangeCallback callback);
+                       typedef std::function<void(LogGroup *group)> InsertCallback;
 
                        /**
-                        * @brief Unset log change callback
+                        * @brief Determines how to filter log list
                         */
-                       void unsetLogChangeCallback();
+                       enum FilterType
+                       {
+                               FilterAll,
+                               FilterMissed
+                       };
+
+                       /**
+                        * @brief Constructor
+                        */
+                       LogProvider(FilterType filterType);
+
+                       /**
+                        * @brief Destructor
+                        */
+                       ~LogProvider();
+
+                       /**
+                        * @brief Get log group list
+                        * @return list of logs groups.
+                        */
+                       const LogGroupList &getLogGroupList();
+
+                       /**
+                        * @brief Set new log callback
+                        * @param[in]    callback    New Log callback
+                        */
+                       void setInsertCallback(InsertCallback callback);
+
+                       /**
+                        * @brief Unset new log callback
+                        */
+                       void unsetInsertCallback();
 
                private:
-                       void fillList();
-                       bool shouldGroupLogs(LogPtr log, LogPtr prevLog);
-                       bool isTimeEqual(struct tm logTime, struct tm prevLogTime);
-                       LogGroupPtr groupLogs(LogPtr log, LogPtr prevLog);
-                       void addLog(contacts_record_h record);
-                       void addFirstLog(contacts_record_h record);
+                       void fillList(LogList &logList);
+                       void fillGroupList(LogList &logList, LogGroupList &logGroupList);
+                       bool shouldGroupLogs(Log *log, LogGroup *prevLogGroup);
+                       LogGroup *addLog(LogGroupList &logList, Log *log);
+
+                       contacts_filter_h getFilter(FilterType filterType);
                        contacts_list_h fetchLogList();
 
                        void onLogChanged(const char *viewUri);
-                       void onContactChanged(const char *viewUri);
+                       void onGroupChanged(LogGroup *group);
+                       void onGroupInsert(LogGroup *group);
 
-                       void notifyLogWithChange(int contactId, contacts_changed_e changeType);
+                       void deleteRemovedLogs(LogIterator &newIt, LogList &newLogList);
+                       void addNewLogs(LogIterator &newIt, LogList &newLogList);
+                       void onContactChanged(const char *viewUri);
 
-                       LogList m_AllLogs;
+                       FilterType m_FilterType;
                        int m_DbVersion;
 
-                       std::multimap<int, ContactChangeCallback> m_ChangeContactCallbacks;
+                       LogGroupList m_Groups;
+                       LogList m_Logs;
 
-                       LogChangeCallback m_LogCallback;
+                       InsertCallback m_InsertCallback;
                };
        }
 }
diff --git a/lib-logs/inc/Logs/Model/LogRecord.h b/lib-logs/inc/Logs/Model/LogRecord.h
deleted file mode 100644 (file)
index 9e10d1f..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 LOGS_MODEL_LOG_RECORD_H
-#define LOGS_MODEL_LOG_RECORD_H
-
-#include "Logs/Model/Log.h"
-
-namespace Logs
-{
-       namespace Model
-       {
-               /**
-                * @brief Log record information
-                */
-               class LogRecord : public Log
-               {
-               public:
-                       /**
-                        * @brief Create log record
-                        * @param[in]   record  Contact record (_contact_person_phone_log)
-                        */
-                       LogRecord(contacts_record_h record);
-
-                       virtual ~LogRecord();
-
-                       LogRecord(const LogRecord &log) = delete;
-
-                       LogRecord &operator=(const LogRecord &log) = delete;
-
-                       /**
-                        * @see Log::isGroup()
-                        */
-                       virtual bool isGroup() const override;
-
-                       /**
-                        * @see Log::getLogRecord()
-                        */
-                       virtual const contacts_record_h getLogRecord() const override;
-
-                       /**
-                        * @see Log::getName()
-                        */
-                       virtual const char *getName() const override;
-
-                       /**
-                        * @see Log::getNumber()
-                        */
-                       virtual const char *getNumber() const override;
-
-                       /**
-                        * @see Log::getImagePath()
-                        */
-                       virtual const char *getImagePath() const override;
-
-                       /**
-                        * @see Log::getType()
-                        */
-                       virtual int getType() const override;
-
-                       /**
-                        * @see Log::getTime()
-                        */
-                       virtual struct tm getTime() const override;
-
-                       /**
-                        * @see Log::getId()
-                        */
-                       virtual int getId() const override;
-
-                       /**
-                        * @see Log::getPersonId()
-                        */
-                       virtual int getPersonId() const override;
-
-               private:
-                       contacts_record_h getContactRecord();
-                       contacts_record_h m_LogRecord;
-                       contacts_record_h m_ContactRecord;
-               };
-       }
-}
-#endif /* LOGS_MODEL_LOG_RECORD_H */
diff --git a/lib-logs/inc/Logs/Model/LogType.h b/lib-logs/inc/Logs/Model/LogType.h
deleted file mode 100644 (file)
index 995190b..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 LOGS_MODEL_LOG_TYPE_H
-#define LOGS_MODEL_LOG_TYPE_H
-
-#include <list>
-#include <memory>
-#include <functional>
-
-namespace Logs
-{
-       namespace Model
-       {
-               class Log;
-               class LogGroup;
-
-               /**
-                * @brief Smart pointer to Log.
-                */
-               typedef std::shared_ptr<Log> LogPtr;
-
-               /**
-                * @brief List of logs.
-                */
-               typedef std::list<LogPtr> LogList;
-
-               /**
-                * @brief Smart pointer of LogGroup.
-                */
-               typedef std::shared_ptr<LogGroup> LogGroupPtr;
-
-               /**
-                * @brief Changed contact callback
-                */
-               typedef std::function<void()> ContactChangeCallback;
-
-               /**
-                * @brief Changed log callback
-                */
-               typedef std::function<void()> LogChangeCallback;
-       }
-}
-
-#endif /* LOGS_MODEL_LOG_TYPE_H */
diff --git a/lib-logs/src/Logs/Model/Log.cpp b/lib-logs/src/Logs/Model/Log.cpp
new file mode 100644 (file)
index 0000000..a211ee6
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ *
+ */
+
+#include "Logs/Model/Log.h"
+#include "Logs/Model/LogGroup.h"
+#include "Utils/Logger.h"
+
+using namespace Logs::Model;
+
+Log::Log(contacts_record_h record)
+       : m_LogRecord(record), m_ContactRecord(getContactRecord()), m_Group(nullptr)
+{
+}
+
+Log::~Log()
+{
+       if (m_Group) {
+               m_Group->removeLog(this);
+       }
+       contacts_record_destroy(m_LogRecord, true);
+       contacts_record_destroy(m_ContactRecord, true);
+}
+
+const char *Log::getName() const
+{
+       char *name = nullptr;
+       contacts_record_get_str_p(m_ContactRecord, _contacts_person.display_name, &name);
+       return name;
+}
+
+const char *Log::getNumber() const
+{
+       char *number = nullptr;
+       contacts_record_get_str_p(m_LogRecord, _contacts_phone_log.address, &number);
+       return number;
+}
+
+const char *Log::getImagePath() const
+{
+       char *path = nullptr;
+       contacts_record_get_str_p(m_ContactRecord, _contacts_person.image_thumbnail_path, &path);
+       return path;
+}
+
+int Log::getType() const
+{
+       int type = CONTACTS_PLOG_TYPE_NONE;
+       contacts_record_get_int(m_LogRecord, _contacts_phone_log.log_type, &type);
+
+       return type;
+}
+
+tm Log::getTime() const
+{
+       int time = 0;
+       contacts_record_get_int(m_LogRecord, _contacts_phone_log.log_time, &time);
+
+       time_t logTime = time;
+       struct tm logDate;
+
+       localtime_r(&logTime, &logDate);
+       return logDate;
+}
+
+int Log::getId() const
+{
+       int id = 0;
+       contacts_record_get_int(m_LogRecord, _contacts_phone_log.id, &id);
+       return id;
+}
+
+int Log::getPersonId() const
+{
+       int id = 0;
+       contacts_record_get_int(m_LogRecord, _contacts_phone_log.person_id, &id);
+       return id;
+}
+
+contacts_record_h Log::getContactRecord()
+{
+       contacts_record_h record = nullptr;
+       contacts_db_get_record(_contacts_person._uri, getPersonId(), &record);
+       return record;
+}
+
+void Log::setLogGroup(LogGroup *group)
+{
+       m_Group = group;
+}
+
+LogGroup *Log::getLogGroup() const
+{
+       return m_Group;
+}
+
+void Log::remove()
+{
+       contacts_db_delete_record(_contacts_phone_log._uri, getId());
+}
index c64a0767ffb0b84510680722f1cabf612bb07c16..439754a7295a318d1a11aea854f50ee897696156 100644 (file)
  */
 
 #include "Logs/Model/LogGroup.h"
-#include <algorithm>
+#include "Logs/Model/Log.h"
 
 using namespace Logs::Model;
 
-bool LogGroup::isGroup() const
+LogGroup::LogGroup(Log *log)
 {
-       return true;
+       addLog(log);
 }
 
-const contacts_record_h LogGroup::getLogRecord() const
+const LogGroup::LogList &LogGroup::getLogList() const
 {
-       return m_LogList.back()->getLogRecord();
-}
-
-const char *LogGroup::getName() const
-{
-       return m_LogList.back()->getName();
-}
-
-const char *LogGroup::getNumber() const
-{
-       return m_LogList.back()->getNumber();
-}
-
-const char *LogGroup::getImagePath() const
-{
-       return m_LogList.back()->getImagePath();
-}
-
-int LogGroup::getType() const
-{
-       return m_LogList.back()->getType();
+       return m_LogList;
 }
 
-struct tm LogGroup::getTime() const
+void LogGroup::setChangeCallback(ChangeCallback callback)
 {
-       return m_LogList.back()->getTime();
+       m_ChangeCallback = std::move(callback);
 }
 
-int LogGroup::getId() const
+void LogGroup::unsetChangeCallback()
 {
-       return m_LogList.back()->getId();
+       m_ChangeCallback = nullptr;
 }
 
-int LogGroup::getPersonId() const
+void LogGroup::onChange(ChangedType type)
 {
-       return m_LogList.back()->getPersonId();
+       if (m_ChangeCallback) {
+               m_ChangeCallback(type);
+       }
 }
 
-void LogGroup::removeLog(int id)
+void LogGroup::addLog(Log *log)
 {
-       auto position = std::find_if(m_LogList.begin(), m_LogList.end(), [id](LogPtr log) {
-               return (log->getId() == id);
-       });
-       m_LogList.erase(position);
+       m_LogList.push_back(log);
+       log->setLogGroup(this);
 }
 
-void LogGroup::addLog(LogPtr log)
+void LogGroup::removeLog(Log *log)
 {
-       m_LogList.push_back(log);
+       m_LogList.remove(log);
+       log->setLogGroup(nullptr);
 }
 
-const LogList &LogGroup::getLogList() const
+void LogGroup::remove()
 {
-       return m_LogList;
+       for (auto &&log : m_LogList) {
+               log->remove();
+       }
 }
index 4e5fa46cd28bbf863aa824e6b9863a261d0bcb2b..3d049f157ab5c43364d9052fff1f802e2b0aad47 100644 (file)
@@ -16,8 +16,6 @@
  */
 
 #include "Logs/Model/LogProvider.h"
-#include "Logs/Model/LogRecord.h"
-#include "Logs/Model/LogGroup.h"
 #include "Contacts/Utils.h"
 #include "Utils/Logger.h"
 #include "Utils/Callback.h"
 
 using namespace Logs::Model;
 
-LogProvider::LogProvider()
+LogProvider::LogProvider(FilterType filterType):
+               m_FilterType(filterType), m_InsertCallback(nullptr)
 {
        contacts_db_get_current_version(&m_DbVersion);
        contacts_db_add_changed_cb(_contacts_phone_log._uri, makeCallbackWithLastParam(&LogProvider::onLogChanged), this);
        contacts_db_add_changed_cb(_contacts_person._uri, makeCallbackWithLastParam(&LogProvider::onContactChanged), this);
-       fillList();
 }
 
 LogProvider::~LogProvider()
@@ -40,117 +38,98 @@ LogProvider::~LogProvider()
        contacts_db_remove_changed_cb(_contacts_person._uri, makeCallbackWithLastParam(&LogProvider::onContactChanged), this);
 }
 
-const LogList &LogProvider::getLogList() const
+const LogProvider::LogGroupList &LogProvider::getLogGroupList()
 {
-       return m_AllLogs;
-}
-
-void LogProvider::addContactChangeCallback(int id, ContactChangeCallback callback)
-{
-       if (callback) {
-               m_ChangeContactCallbacks.insert({id, std::move(callback)});
+       if (m_Groups.empty()) {
+               if (m_Logs.empty()) {
+                       fillList(m_Logs);
+               }
+               fillGroupList(m_Logs, m_Groups);
        }
+       return m_Groups;
 }
 
-void LogProvider::removeContactChangeCallback(int id)
-{
-       m_ChangeContactCallbacks.erase(id);
-}
-
-void LogProvider::setLogChangeCallback(LogChangeCallback callback)
+void LogProvider::setInsertCallback(InsertCallback callback)
 {
-       m_LogCallback = callback;
+       m_InsertCallback = std::move(callback);
 }
 
-void LogProvider::unsetLogChangeCallback()
+void LogProvider::unsetInsertCallback()
 {
-       m_LogCallback = nullptr;
+       m_InsertCallback = nullptr;
 }
 
-void LogProvider::fillList()
+void LogProvider::fillList(LogList &logList)
 {
        contacts_list_h list = fetchLogList();
-
+       contacts_db_get_all_records(_contacts_phone_log._uri, 0, 0, &list);
        contacts_record_h record = nullptr;
-       if (contacts_list_get_current_record_p(list, &record) != CONTACTS_ERROR_NONE) {
-               return;
-       }
-
-       addFirstLog(record);
-
-       contacts_list_next(list);
 
        CONTACTS_LIST_FOREACH(list, record) {
-               addLog(record);
+               logList.push_back(LogPtr(new Log(record)));
        }
 
        contacts_list_destroy(list, false);
 }
 
-bool LogProvider::shouldGroupLogs(LogPtr log, LogPtr prevLog)
-{
-       return (log->getType() == prevLog->getType()
-                       && strcmp(log->getNumber(), prevLog->getNumber()) == 0
-                       && isTimeEqual(log->getTime(), prevLog->getTime()));
-}
-
-bool LogProvider::isTimeEqual(struct tm logTime, struct tm prevLogTime)
+void LogProvider::fillGroupList(LogList &logList, LogGroupList &logGroupList)
 {
-       return (logTime.tm_year == prevLogTime.tm_year &&
-                               logTime.tm_mon == prevLogTime.tm_mon &&
-                               logTime.tm_mday == prevLogTime.tm_mday);
-}
+       if (logList.empty()) {
+               return;
+       }
+       LogList::iterator log = logList.begin();
+       logGroupList.push_back(LogGroupPtr(new LogGroup(log->get())));
 
-LogGroupPtr LogProvider::groupLogs(LogPtr log, LogPtr prevLog)
-{
-       LogGroupPtr logGroup = nullptr;
-       if (prevLog->isGroup()) {
-               logGroup = std::static_pointer_cast<LogGroup>(prevLog);
-               logGroup->addLog(std::move(log));
-       } else {
-               logGroup = LogGroupPtr(new LogGroup());
-               logGroup->addLog(std::move(prevLog));
-               logGroup->addLog(std::move(log));
+       for (++log; log != logList.end(); ++log) {
+               addLog(logGroupList, log->get());
        }
-       return logGroup;
 }
 
-void LogProvider::onLogChanged(const char *viewUri)
+bool LogProvider::shouldGroupLogs(Log *log, LogGroup *prevLogGroup)
 {
-       /*
-        TODO
-        */
+       Log *prevLog = prevLogGroup->getLogList().back();
+       return (log->getType() == prevLog->getType()
+                       && strcmp(log->getNumber(), prevLog->getNumber()) == 0);
 }
 
-void LogProvider::addLog(contacts_record_h record)
+LogGroup *LogProvider::addLog(LogGroupList &logGroupList, Log *log)
 {
-       LogPtr log = LogPtr(new LogRecord(record));
-       LogPtr lastLog = m_AllLogs.back();
+       LogGroup *lastLogGroup = logGroupList.back().get();
 
-       if (shouldGroupLogs(log, lastLog)) {
-               m_AllLogs.pop_back();
-               log = groupLogs(std::move(log), std::move(lastLog));
+       if (shouldGroupLogs(log, lastLogGroup)) {
+               lastLogGroup->addLog(log);
+       } else {
+               LogGroup *logGroup = new LogGroup(log);
+               logGroupList.push_back(LogGroupPtr(logGroup));
+               return logGroup;
        }
-       m_AllLogs.push_back(log);
+       return nullptr;
 }
 
-void LogProvider::addFirstLog(contacts_record_h record)
+contacts_filter_h LogProvider::getFilter(LogProvider::FilterType filterType)
 {
-       if (m_AllLogs.empty()) {
-               LogPtr log = LogPtr(new LogRecord(record));
-               m_AllLogs.push_back(log);
+       contacts_filter_h filter = nullptr;
+       contacts_filter_create(_contacts_phone_log._uri, &filter);
+
+       if (filterType != LogProvider::FilterMissed) {
+               contacts_filter_add_int(filter, _contacts_phone_log.log_type, CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VOICE_INCOMING_UNSEEN);
+               contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
+               contacts_filter_add_int(filter, _contacts_phone_log.log_type, CONTACTS_MATCH_LESS_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VOICE_INCOMING_SEEN);
        } else {
-               addLog(record);
+               contacts_filter_add_int(filter, _contacts_phone_log.log_type, CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VOICE_INCOMING);
+               contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
+               contacts_filter_add_int(filter, _contacts_phone_log.log_type, CONTACTS_MATCH_LESS_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_BLOCKED);
        }
+
+       return filter;
 }
 
 contacts_list_h LogProvider::fetchLogList()
 {
        contacts_list_h list = nullptr;
        contacts_query_h query = nullptr;
-       contacts_filter_h filter = nullptr;
+       contacts_filter_h filter = getFilter(m_FilterType);
 
-       contacts_filter_create(_contacts_phone_log._uri, &filter);
        contacts_query_create(_contacts_phone_log._uri, &query);
        contacts_query_set_filter(query, filter);
        contacts_query_set_sort(query, _contacts_phone_log.log_time, true);
@@ -158,31 +137,137 @@ contacts_list_h LogProvider::fetchLogList()
 
        contacts_filter_destroy(filter);
        contacts_query_destroy(query);
+
        return list;
 }
 
-void LogProvider::onContactChanged(const char *viewUri)
+void LogProvider::onLogChanged(const char *viewUri)
 {
-       contacts_list_h changes = nullptr;
-       contacts_db_get_changes_by_version(_contacts_contact_updated_info._uri, 0, m_DbVersion, &changes, &m_DbVersion);
+       LogList newLogList;
 
-       contacts_record_h record = nullptr;
-       CONTACTS_LIST_FOREACH(changes, record) {
-               int contactId = 0;
-               int changeType = -1;
+       fillList(newLogList);
 
-               contacts_record_get_int(record, _contacts_contact_updated_info.contact_id, &contactId);
-               contacts_record_get_int(record, _contacts_contact_updated_info.type, &changeType);
+       LogIterator newIt = newLogList.begin();
+
+       deleteRemovedLogs(newIt, newLogList);
+       addNewLogs(newIt, newLogList);
+}
 
-               notifyLogWithChange(contactId, static_cast<contacts_changed_e>(changeType));
+void LogProvider::onGroupChanged(LogGroup *group)
+{
+       if (group->getLogList().empty()) {
+               group->onChange(LogGroup::Remove);
+               m_Groups.remove_if([group](const LogGroupPtr &groupPtr) {
+                       return groupPtr.get() == group;
+               });
+       } else {
+               group->onChange(LogGroup::Update);
+       }
+}
+
+void LogProvider::onGroupInsert(LogGroup *group)
+{
+       if (m_InsertCallback) {
+               m_InsertCallback(group);
        }
-       contacts_list_destroy(changes, true);
 }
 
-void LogProvider::notifyLogWithChange(int contactId, contacts_changed_e changeType)
+void LogProvider::deleteRemovedLogs(LogIterator &newIt, LogList &newLogList)
 {
-       auto range = m_ChangeContactCallbacks.equal_range(contactId);
-       for (auto i = range.first; i != range.second; ++i) {
-               i->second();
+       LogIterator oldIt = m_Logs.begin();
+       LogGroup *prevGroup = nullptr;
+
+       bool isChanged = false;
+       while (newIt != newLogList.end() && oldIt != m_Logs.end()) {
+               if (prevGroup != (*oldIt)->getLogGroup()) {
+                       if (isChanged == true) {
+                               onGroupChanged(prevGroup);
+                               isChanged = false;
+                       }
+                       prevGroup = (*oldIt)->getLogGroup();
+               }
+
+               if ((*newIt)->getId() != (*oldIt)->getId()) {
+                       isChanged = true;
+                       oldIt = m_Logs.erase(oldIt);
+               } else {
+                       ++newIt;
+                       ++oldIt;
+               }
        }
+
+       while (oldIt != m_Logs.end()) {
+               if (prevGroup != (*oldIt)->getLogGroup()) {
+                       if (isChanged) {
+                               onGroupChanged(prevGroup);
+                               isChanged = false;
+                       }
+                       prevGroup = (*oldIt)->getLogGroup();
+               }
+
+               isChanged = true;
+               oldIt = m_Logs.erase(oldIt);
+       }
+
+       if (isChanged) {
+               onGroupChanged(prevGroup);
+       }
+}
+
+void LogProvider::addNewLogs(LogIterator &newIt, LogList &newLogList)
+{
+       LogGroup *group = nullptr;
+
+       if (newIt != newLogList.end() && m_Groups.empty()) {
+               group = new LogGroup(newIt->get());
+               m_Logs.push_back(std::move(*newIt));
+               m_Groups.push_back(LogGroupPtr(group));
+               ++newIt;
+       } else {
+               group = m_Groups.back().get();
+               bool isChanged = false;
+
+               LogGroup *newGroup = nullptr;
+               for (; newIt != newLogList.end(); ++newIt) {
+                       newGroup = addLog(m_Groups, newIt->get());
+                       if (newGroup) {
+                               break;
+                       }
+                       isChanged = true;
+               }
+               if (isChanged) {
+                       group->onChange(LogGroup::Update);
+               }
+
+               group = newGroup;
+       }
+
+       for (; newIt != newLogList.end(); ++newIt) {
+               LogGroup *newGroup = addLog(m_Groups, newIt->get());
+               if (newGroup) {
+                       if (group) {
+                               onGroupInsert(group);
+                       }
+                       group = newGroup;
+               }
+               m_Logs.push_back(std::move(*newIt));
+       }
+
+       if (group) {
+               onGroupInsert(group);
+       }
+}
+
+void LogProvider::onContactChanged(const char *viewUri)
+{
+       contacts_list_h changes = nullptr;
+       contacts_db_get_changes_by_version(_contacts_contact_updated_info._uri, 0, m_DbVersion, &changes, &m_DbVersion);
+
+       contacts_record_h record = nullptr;
+       CONTACTS_LIST_FOREACH(changes, record) {
+               /*
+                * TODO
+                */
+       }
+       contacts_list_destroy(changes, true);
 }
diff --git a/lib-logs/src/Logs/Model/LogRecord.cpp b/lib-logs/src/Logs/Model/LogRecord.cpp
deleted file mode 100644 (file)
index 296f1af..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.
- *
- */
-
-#include "Logs/Model/LogRecord.h"
-#include "Utils/Logger.h"
-
-using namespace Logs::Model;
-
-LogRecord::LogRecord(contacts_record_h record)
-       : m_LogRecord(record), m_ContactRecord(getContactRecord())
-{
-}
-
-LogRecord::~LogRecord()
-{
-       contacts_record_destroy(m_LogRecord, true);
-       contacts_record_destroy(m_ContactRecord, true);
-}
-
-bool LogRecord::isGroup() const
-{
-       return false;
-}
-
-const contacts_record_h LogRecord::getLogRecord() const
-{
-       return m_LogRecord;
-}
-
-const char *LogRecord::getName() const
-{
-       char *name = nullptr;
-       contacts_record_get_str_p(m_ContactRecord, _contacts_person.display_name, &name);
-       return name;
-}
-
-const char *LogRecord::getNumber() const
-{
-       char *number = nullptr;
-       contacts_record_get_str_p(m_LogRecord, _contacts_phone_log.address, &number);
-       return number;
-}
-
-const char *LogRecord::getImagePath() const
-{
-       char *path = nullptr;
-       contacts_record_get_str_p(m_ContactRecord, _contacts_person.image_thumbnail_path, &path);
-       return path;
-}
-
-struct tm LogRecord::getTime() const
-{
-       int time = 0;
-       contacts_record_get_int(m_LogRecord, _contacts_phone_log.log_time, &time);
-
-       time_t logTime = time;
-       struct tm logDate;
-
-       localtime_r(&logTime, &logDate);
-       return logDate;
-}
-
-int LogRecord::getType() const
-{
-       int type = CONTACTS_PLOG_TYPE_NONE;
-       contacts_record_get_int(m_LogRecord, _contacts_phone_log.log_type, &type);
-
-       return type;
-}
-
-int LogRecord::getId() const
-{
-       int id = 0;
-       contacts_record_get_int(m_LogRecord, _contacts_phone_log.id, &id);
-       return id;
-}
-
-int LogRecord::getPersonId() const
-{
-       int id = 0;
-       contacts_record_get_int(m_LogRecord, _contacts_phone_log.person_id, &id);
-       return id;
-}
-
-contacts_record_h LogRecord::getContactRecord()
-{
-       contacts_record_h record = nullptr;
-       contacts_db_get_record(_contacts_person._uri, getPersonId(), &record);
-       return record;
-}