TizenRefApp-5006 Migrate Phone Dialer 04/51704/2
authorEugene Kurzberg <i.kurtsberg@samsung.com>
Thu, 12 Nov 2015 09:54:10 +0000 (11:54 +0200)
committerEugene Kurzberg <i.kurtsberg@samsung.com>
Thu, 12 Nov 2015 15:57:39 +0000 (17:57 +0200)
Change-Id: I15dcaf84a0903831c0c593d7672845b77e6e5871
Signed-off-by: Eugene Kurzberg <i.kurtsberg@samsung.com>
71 files changed:
CMakeLists.txt
lib-common/inc/App/AppControlRequest.h
lib-common/inc/Contacts/Utils.h [new file with mode: 0644]
lib-common/inc/Ui/Button.h [new file with mode: 0644]
lib-common/src/App/AppControlRequest.cpp
lib-common/src/Ui/Button.cpp [new file with mode: 0644]
lib-common/src/Ui/Menu.cpp
lib-common/src/Ui/Popup.cpp
lib-phone/CMakeLists.txt [new file with mode: 0644]
lib-phone/inc/Phone/Dialer/AddNumberPopup.h [new file with mode: 0644]
lib-phone/inc/Phone/Dialer/KeypadButton.h [new file with mode: 0644]
lib-phone/inc/Phone/Dialer/KeypadEntry.h [new file with mode: 0644]
lib-phone/inc/Phone/Dialer/MainView.h [new file with mode: 0644]
lib-phone/inc/Phone/Dialer/SearchEngine.h [new file with mode: 0644]
lib-phone/inc/Phone/Dialer/SearchResult.h [new file with mode: 0644]
lib-phone/inc/Phone/Dialer/SearchResultsPopup.h [new file with mode: 0644]
lib-phone/inc/Phone/Dialer/SearchResultsWidget.h [new file with mode: 0644]
lib-phone/inc/Phone/Dialer/SearchTypes.h [new file with mode: 0644]
lib-phone/inc/Phone/Dialer/SearchUtils.h [new file with mode: 0644]
lib-phone/inc/Phone/Dialer/SpeeddialPopup.h [new file with mode: 0644]
lib-phone/inc/Phone/Utils.h [new file with mode: 0644]
lib-phone/res/dialer/CMakeLists.txt [new file with mode: 0644]
lib-phone/res/dialer/edje/DialerLayout.h [new file with mode: 0644]
lib-phone/res/dialer/edje/DialerLayoutColors.h [new file with mode: 0644]
lib-phone/res/dialer/edje/DialerLayoutMetrics.h [new file with mode: 0644]
lib-phone/res/dialer/edje/DialerPath.h [new file with mode: 0644]
lib-phone/res/dialer/edje/dialer-keypad.edc [new file with mode: 0644]
lib-phone/res/dialer/edje/dialer-layout.edc [new file with mode: 0644]
lib-phone/res/dialer/edje/dialer-predictive.edc [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_english_01.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_english_02.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_english_03.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_english_04.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_english_05.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_english_06.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_english_07.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_english_08.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_english_10.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_ic_back.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_ic_call.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_number_00.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_number_01.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_number_02.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_number_03.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_number_04.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_number_05.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_number_06.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_number_07.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_number_08.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_number_09.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_number_asterisk.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_number_sharp.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_predictive_arrow.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_speed_dial_add.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_speed_dial_ic.png [new file with mode: 0644]
lib-phone/res/dialer/images/keypad_speed_dial_ic_bg.#.png [new file with mode: 0644]
lib-phone/src/Phone/Dialer/AddNumberPopup.cpp [new file with mode: 0644]
lib-phone/src/Phone/Dialer/KeypadButton.cpp [new file with mode: 0644]
lib-phone/src/Phone/Dialer/KeypadEntry.cpp [new file with mode: 0644]
lib-phone/src/Phone/Dialer/MainView.cpp [new file with mode: 0644]
lib-phone/src/Phone/Dialer/SearchEngine.cpp [new file with mode: 0644]
lib-phone/src/Phone/Dialer/SearchResult.cpp [new file with mode: 0644]
lib-phone/src/Phone/Dialer/SearchResultsPopup.cpp [new file with mode: 0644]
lib-phone/src/Phone/Dialer/SearchResultsWidget.cpp [new file with mode: 0644]
lib-phone/src/Phone/Dialer/SearchUtils.cpp [new file with mode: 0644]
lib-phone/src/Phone/Dialer/SpeeddialPopup.cpp [new file with mode: 0644]
lib-phone/src/Phone/Utils.cpp [new file with mode: 0644]
main-app/CMakeLists.txt
main-app/src/OperationDefaultController.cpp
main-app/tizen-manifest.xml.in
packaging/org.tizen.contacts.spec

index 257d14a..886ffec 100644 (file)
@@ -1,5 +1,5 @@
 cmake_minimum_required(VERSION 2.6)
-project(${PACKAGE} C CXX)
+project(${PACKAGE} CXX)
 
 include(FindPkgConfig)
 pkg_check_modules(TIZEN_PACKAGES REQUIRED
@@ -10,6 +10,8 @@ pkg_check_modules(TIZEN_PACKAGES REQUIRED
        dlog
        efl-extension
        elementary
+       feedback
+       notification
 )
 
 set(INCLUDES      "${TIZEN_PACKAGES_INCLUDE_DIRS};inc")
@@ -23,13 +25,13 @@ set(CMAKE_INSTALL_RPATH ${LIBDIR})
 set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
 
 set(COMPILER_FLAGS "-fpie -fPIC -Wall")
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILER_FLAGS} -std=gnu99")
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILER_FLAGS} -std=c++11")
 
 add_definitions("-DPACKAGE=\"${PACKAGE}\"")
 add_definitions("-DTEXT_DOMAIN=\"${PACKAGE}\"")
-add_definitions("-DRESDIR=\"${RESDIR}\"")
+add_definitions("-DRESDIR=\"${RESDIR}/\"")
 add_definitions("-DLOCALEDIR=\"${LOCALEDIR}\"")
 
 add_subdirectory(lib-common)
+add_subdirectory(lib-phone)
 add_subdirectory(main-app)
index 9a495c6..b8b8b7a 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "App/AppControl.h"
 
+#define APP_CONTROL_OPERATION_SETTING_CALL "http://tizen.org/appcontrol/operation/setting/call"
+
 #define APP_CONTROL_MIME_CONTACT "application/vnd.tizen.contact"
 
 #define APP_CONTROL_SELECT_SINGLE "single"
@@ -70,6 +72,12 @@ namespace App
        AppControl EXPORT_API requestTelephonyCall(const char *number);
 
        /**
+        * @brief Request launch call settings
+        * @return AppControl wrapper
+        */
+       AppControl EXPORT_API requestCallSettings();
+
+       /**
         * @brief Request message composer
         * @param[in]   scheme      URI scheme (e.g. sms:, mmsto: or mailto:)
         * @param[in]   to          Message recipient
diff --git a/lib-common/inc/Contacts/Utils.h b/lib-common/inc/Contacts/Utils.h
new file mode 100644 (file)
index 0000000..ac4b63d
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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 CONTACTS_UTILS_H
+#define CONTACTS_UTILS_H
+
+#define CONTACTS_LIST_FOREACH(list, record) \
+       bool success = (contacts_list_get_current_record_p(list, &record) == CONTACTS_ERROR_NONE); \
+       for ( ; success; \
+                       success = ((contacts_list_next(list) == CONTACTS_ERROR_NONE) \
+                       && (contacts_list_get_current_record_p(list, &record) == CONTACTS_ERROR_NONE)) \
+               )
+
+#endif /* CONTACTS_UTILS_H */
diff --git a/lib-common/inc/Ui/Button.h b/lib-common/inc/Ui/Button.h
new file mode 100644 (file)
index 0000000..3fd5787
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * 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 UI_BUTTON_H
+#define UI_BUTTON_H
+
+#include "Ui/Control.h"
+#include <functional>
+
+namespace Ui
+{
+       /**
+        * @brief Provides convenient press and longpress events handling.
+        */
+       class EXPORT_API Button : public Control
+       {
+       public:
+               Button();
+               virtual ~Button() override;
+
+               /**
+                * @brief Set press-event callback.
+                */
+               void setPressedCallback(std::function<void(Button &)> callback);
+
+               /**
+                * @brief Set longpress-event callback.
+                * @details Callback should return true if the event was handled.
+                *          If callback returns false onPressed event will be delivered
+                *          as well when the button is released.
+                */
+               void setLongpressedCallback(std::function<bool(Button &)> callback);
+
+       private:
+               virtual Evas_Object *onCreate(Evas_Object *parent) override;
+               virtual void onCreated() override;
+
+               void onMouseDown(Evas *evas, Evas_Object *obj, void *eventInfo);
+               void onMouseUp(Evas *evas, Evas_Object *obj, void *eventInfo);
+               void onMouseOut(Evas *evas, Evas_Object *obj, void *eventInfo);
+
+               void resetTimer();
+               Eina_Bool onTimeout();
+
+               Ecore_Timer *m_Timer;
+               bool m_IsLongpressed;
+
+               std::function<void(Button &)> m_OnPressed;
+               std::function<bool(Button &)> m_OnLongpressed;
+       };
+}
+
+#endif /* UI_BUTTON_H */
index 07420e9..3a6ded3 100644 (file)
@@ -59,6 +59,11 @@ AppControl App::requestTelephonyCall(const char *number)
                        std::string("tel:").append(number).c_str());
 }
 
+AppControl App::requestCallSettings()
+{
+       return AppControl(APP_CONTROL_OPERATION_SETTING_CALL);
+}
+
 AppControl App::requestMessageComposer(const char *scheme, const char *to,
                const char *subject, const char *text)
 {
diff --git a/lib-common/src/Ui/Button.cpp b/lib-common/src/Ui/Button.cpp
new file mode 100644 (file)
index 0000000..96b4667
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 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 "Ui/Button.h"
+#include "Utils/Callback.h"
+
+#include <Ecore.h>
+
+using namespace Ui;
+
+Button::Button()
+       : m_Timer(nullptr), m_IsLongpressed(false)
+{
+}
+
+Button::~Button()
+{
+       resetTimer();
+}
+
+void Button::setPressedCallback(std::function<void(Button&)> callback)
+{
+       m_OnPressed = std::move(callback);
+}
+
+void Button::setLongpressedCallback(std::function<bool(Button&)> callback)
+{
+       m_OnLongpressed = std::move(callback);
+}
+
+Evas_Object *Button::onCreate(Evas_Object *parent)
+{
+       Evas_Object *button = elm_button_add(parent);
+       return button;
+}
+
+void Button::onCreated()
+{
+       evas_object_event_callback_add(getEvasObject(), EVAS_CALLBACK_MOUSE_DOWN,
+                       makeCallback(&Button::onMouseDown), this);
+       evas_object_event_callback_add(getEvasObject(), EVAS_CALLBACK_MOUSE_UP,
+                       makeCallback(&Button::onMouseUp), this);
+       evas_object_event_callback_add(getEvasObject(), EVAS_CALLBACK_MOUSE_OUT,
+                       makeCallback(&Button::onMouseOut), this);
+}
+
+void Button::onMouseDown(Evas *evas, Evas_Object *obj, void *eventInfo)
+{
+       m_IsLongpressed = false;
+       m_Timer = ecore_timer_add(elm_config_longpress_timeout_get(),
+               makeCallback(&Button::onTimeout), this);
+}
+
+void Button::onMouseUp(Evas *evas, Evas_Object *obj, void *eventInfo)
+{
+       Evas_Event_Mouse_Up *e = (Evas_Event_Mouse_Up *) eventInfo;
+
+       if (!m_IsLongpressed) {
+               int x = 0, y = 0, w = 0, h = 0;
+               evas_object_geometry_get(obj, &x, &y, &w, &h);
+
+               if (m_OnPressed) {
+                       if (e->output.x >= x && e->output.x <= x + w
+                        && e->output.y >= y && e->output.x <= y + h) {
+                               m_OnPressed(*this);
+                       }
+               }
+
+               resetTimer();
+       }
+}
+
+void Button::onMouseOut(Evas *evas, Evas_Object *obj, void *eventInfo)
+{
+       resetTimer();
+}
+
+void Button::resetTimer()
+{
+       ecore_timer_del(m_Timer);
+       m_Timer = nullptr;
+}
+
+Eina_Bool Button::onTimeout()
+{
+       if (m_OnLongpressed) {
+               m_IsLongpressed = m_OnLongpressed(*this);
+       }
+
+       resetTimer();
+       return ECORE_CALLBACK_CANCEL;
+}
index 1e6c6da..458fd65 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "Ui/Menu.h"
+#include "Ui/Window.h"
 #include "Utils/Callback.h"
 
 #include <efl_extension.h>
@@ -33,6 +34,11 @@ Elm_Object_Item *Menu::addItem(const char *text, ItemCallback callback)
 
 Evas_Object *Menu::onCreate(Evas_Object *parent)
 {
+       Window *window = static_cast<Window *>(getControl(elm_object_top_widget_get(parent)));
+       if (window) {
+               parent = window->getBaseLayout();
+       }
+
        Evas_Object *menu = elm_ctxpopup_add(parent);
        elm_object_style_set(menu, "more/default");
 
index 675d8b0..305be8c 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "Ui/Popup.h"
+#include "Ui/Window.h"
 #include "Utils/Callback.h"
 
 #include <efl_extension.h>
@@ -82,6 +83,11 @@ Evas_Object *Popup::addButton(const char *text, ButtonCallback callback)
 
 Evas_Object *Popup::onCreate(Evas_Object *parent)
 {
+       Window *window = static_cast<Window *>(getControl(elm_object_top_widget_get(parent)));
+       if (window) {
+               parent = window->getBaseLayout();
+       }
+
        Evas_Object *popup = elm_popup_add(parent);
        elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
        eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, nullptr);
diff --git a/lib-phone/CMakeLists.txt b/lib-phone/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0fb93d5
--- /dev/null
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 2.6)
+project(phone CXX)
+
+file(GLOB_RECURSE SOURCES src/*.cpp)
+include_directories(
+       ${CMAKE_SOURCE_DIR}/lib-common/inc
+       ${CMAKE_SOURCE_DIR}/lib-common/res/common/edje
+       ${CMAKE_CURRENT_SOURCE_DIR}/res/dialer/edje
+       ${CMAKE_CURRENT_SOURCE_DIR}/inc
+)
+
+add_library(${PROJECT_NAME} SHARED ${SOURCES})
+target_link_libraries(${PROJECT_NAME} ${LIBRARIES} common)
+
+install(TARGETS ${PROJECT_NAME} DESTINATION ${LIBDIR})
+
+add_subdirectory(res/dialer)
diff --git a/lib-phone/inc/Phone/Dialer/AddNumberPopup.h b/lib-phone/inc/Phone/Dialer/AddNumberPopup.h
new file mode 100644 (file)
index 0000000..daf256d
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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 PHONE_DIALER_ADD_NUMBER_POPUP_H
+#define PHONE_DIALER_ADD_NUMBER_POPUP_H
+
+#include "Ui/Popup.h"
+
+namespace Phone
+{
+       namespace Dialer
+       {
+               /**
+                * @brief Add number to contacts popup.
+                */
+               class AddNumberPopup : public Ui::Popup
+               {
+               public:
+                       /**
+                        * @brief Create "Add to contacts" popup.
+                        * @param[in]   number  Number to add
+                        */
+                       AddNumberPopup(std::string number);
+
+               private:
+                       virtual void onCreated() override;
+
+                       Evas_Object *createGenlist(Evas_Object *parent);
+                       Elm_Genlist_Item_Class *createItemClass();
+                       static char *getItemText(void *data, Evas_Object *obj, const char *part);
+
+                       static void launchContactCreate(void *data, Evas_Object *obj, void *event_info);
+                       static void launchContactUpdate(void *data, Evas_Object *obj, void *event_info);
+
+                       std::string m_Number;
+               };
+       }
+}
+
+#endif /* PHONE_DIALER_ADD_NUMBER_POPUP_H */
diff --git a/lib-phone/inc/Phone/Dialer/KeypadButton.h b/lib-phone/inc/Phone/Dialer/KeypadButton.h
new file mode 100644 (file)
index 0000000..9b015f6
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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 PHONE_DIALER_KEYPAD_BUTTON_H
+#define PHONE_DIALER_KEYPAD_BUTTON_H
+
+#include "Ui/Button.h"
+
+namespace Phone
+{
+       namespace Dialer
+       {
+               /**
+                * @brief Dialer keypad button
+                */
+               class KeypadButton : public Ui::Button
+               {
+               public:
+                       /**
+                        * @brief Phone dialer key ID.
+                        */
+                       enum Id
+                       {
+                               ID_1,       /**< Dialer key 1 */
+                               ID_2,       /**< Dialer key 2 */
+                               ID_3,       /**< Dialer key 3 */
+                               ID_4,       /**< Dialer key 4 */
+                               ID_5,       /**< Dialer key 5 */
+                               ID_6,       /**< Dialer key 6 */
+                               ID_7,       /**< Dialer key 7 */
+                               ID_8,       /**< Dialer key 8 */
+                               ID_9,       /**< Dialer key 9 */
+                               ID_STAR,    /**< Dialer key * */
+                               ID_0,       /**< Dialer key 0 */
+                               ID_SHARP,   /**< Dialer key # */
+                       };
+
+                       /**
+                        * @brief Create keypad button.
+                        * @param   id  Key ID
+                        */
+                       KeypadButton(Id id);
+
+                       /**
+                        * @return Button character value.
+                        */
+                       char getValue() const;
+
+                       /**
+                        * @return Button ID.
+                        */
+                       Id   getId() const;
+
+               private:
+                       virtual Evas_Object *onCreate(Evas_Object *parent) override;
+
+                       Id m_Id;
+                       const struct KeypadButtonData *m_Data;
+               };
+       }
+}
+
+#endif /* PHONE_DIALER_KEYPAD_BUTTON_H */
diff --git a/lib-phone/inc/Phone/Dialer/KeypadEntry.h b/lib-phone/inc/Phone/Dialer/KeypadEntry.h
new file mode 100644 (file)
index 0000000..2658eec
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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 PHONE_DIALER_KEYPAD_ENTRY_H
+#define PHONE_DIALER_KEYPAD_ENTRY_H
+
+#include "Ui/Control.h"
+#include <string>
+#include <functional>
+
+namespace Phone
+{
+       namespace Dialer
+       {
+               /**
+                * @brief Dialer keypad entry.
+                */
+               class KeypadEntry : public Ui::Control
+               {
+               public:
+                       /**
+                        * @brief Entry text changed callback
+                        */
+                       typedef std::function<void()> ChangedCallback;
+
+                       /**
+                        * @return Entered number
+                        */
+                       std::string getNumber() const;
+
+                       /**
+                        * @brief Set number
+                        */
+                       void setNumber(const std::string &number);
+
+                       /**
+                        * @brief Insert character at the cursor position.
+                        * @param   c   Character to insert
+                        */
+                       void insert(char c);
+
+                       /**
+                        * @brief Remove last character from the current entry.
+                        */
+                       void popBack();
+
+                       /**
+                        * @brief Erase current entry.
+                        */
+                       void clear();
+
+                       /**
+                        * @brief Set changed event callback.
+                        */
+                       void setChangedCallback(ChangedCallback callback);
+
+               private:
+                       virtual Evas_Object *onCreate(Evas_Object *parent) override;
+                       void onChanged(Evas_Object *obj, void *event_info);
+
+                       ChangedCallback m_OnChanged;
+               };
+       }
+}
+
+#endif /* PHONE_DIALER_KEYPAD_ENTRY_H */
diff --git a/lib-phone/inc/Phone/Dialer/MainView.h b/lib-phone/inc/Phone/Dialer/MainView.h
new file mode 100644 (file)
index 0000000..035feb2
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * 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 PHONE_DIALER_MAIN_VIEW_H
+#define PHONE_DIALER_MAIN_VIEW_H
+
+#include "App/AppControl.h"
+#include "Phone/Dialer/SearchEngine.h"
+#include "Ui/View.h"
+#include <string>
+
+namespace Ui
+{
+       class Button;
+}
+
+namespace Phone
+{
+       namespace Dialer
+       {
+               class KeypadEntry;
+               class SearchResultsWidget;
+
+               /**
+                * @brief Dialer main view.
+                */
+               class EXPORT_API MainView : public Ui::View
+               {
+               public:
+                       MainView();
+                       virtual ~MainView() override;
+
+                       /**
+                        * @brief Set number to be displayed
+                        * @param[in]   number  Number
+                        */
+                       void setNumber(const std::string &number);
+
+               private:
+                       virtual Evas_Object *onCreate(Evas_Object *parent) override;
+                       virtual void onCreated() override;
+                       virtual void onPageAttached() override;
+                       virtual void onNavigation(bool isCurrentView) override;
+                       virtual Evas_Object *onMenuPressed() override;
+
+                       Evas_Object *createEntry(Evas_Object *parent);
+                       Evas_Object *createSearchWidget(Evas_Object *parent);
+                       Evas_Object *createKeypad(Evas_Object *parent);
+                       Evas_Object *createCallButton(Evas_Object *parent);
+                       Evas_Object *createBackspaceButton(Evas_Object *parent);
+
+                       void onEntryChanged();
+                       void onResultSelected(SearchResultPtr result);
+
+                       void onKeyPressed(Ui::Button &button);
+                       bool onKeyLongpressed(Ui::Button &button);
+
+                       void onBackspacePressed(Ui::Button &button);
+                       bool onBackspaceLongpressed(Ui::Button &button);
+                       void onCallPressed(Evas_Object *obj, void *event_info);
+
+                       void onDbChanged(const char *uri);
+
+                       static void launchCall(const std::string &number);
+                       void launchSpeeddial(int digit);
+                       static std::string getSpeeddialNumber(int digit);
+                       static std::string getLastNumber();
+
+                       App::AppControl m_AppControl;
+                       SearchEngine m_SearchEngine;
+
+                       KeypadEntry *m_Entry;
+                       SearchResultsWidget *m_SearchWidget;
+               };
+       }
+}
+
+#endif /* PHONE_DIALER_MAIN_VIEW_H */
diff --git a/lib-phone/inc/Phone/Dialer/SearchEngine.h b/lib-phone/inc/Phone/Dialer/SearchEngine.h
new file mode 100644 (file)
index 0000000..59be81a
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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 PHONE_DIALER_SEARCH_ENGINE_H
+#define PHONE_DIALER_SEARCH_ENGINE_H
+
+#include <string>
+
+#include "Phone/Dialer/SearchTypes.h"
+
+namespace Phone
+{
+       namespace Dialer
+       {
+               /**
+                * @brief This class provides incremental search logic for predictive number functionality
+                */
+               class SearchEngine
+               {
+               public:
+                       SearchEngine();
+
+                       /**
+                        * @brief Perform incremental search
+                        * @param[in]   number          Value to find
+                        */
+                       void search(const std::string &number);
+
+                       /**
+                        * @brief Retrieves result list
+                        * @return Result list or nullptr on empty list
+                        */
+                       const SearchResults *getSearchResult() const;
+
+                       /**
+                        * @return true if there is no results, otherwise false
+                        */
+                       bool empty() const;
+
+                       /**
+                        * @brief make search like a first time
+                        * @param[in] number value to find
+                        */
+                       void searchFromScratch(const std::string &number);
+
+               private:
+                       void distinctLogs(SearchResults &searchList);
+                       void firstSearch(const std::string &number);
+                       SearchResults searchInDB(const std::string &number);
+                       void chooseSearch(const std::string &number);
+
+                       bool searchInCache(SearchHistory::iterator from, const std::string &number);
+                       SearchHistory::reverse_iterator firstMismatch(const std::string &number);
+                       SearchHistory::reverse_iterator skipEmptyResults(size_t offset);
+
+                       void clear();
+
+                       bool needSearch(const std::string &number);
+
+                       std::string m_Number;
+                       SearchHistory m_Cache;
+                       int m_LastFoundIndex;
+               };
+       }
+}
+
+#endif /* PHONE_DIALER_SEARCH_ENGINE_H */
diff --git a/lib-phone/inc/Phone/Dialer/SearchResult.h b/lib-phone/inc/Phone/Dialer/SearchResult.h
new file mode 100644 (file)
index 0000000..e5051d3
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * 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 PHONE_DIALER_SEARCH_RESULT_H
+#define PHONE_DIALER_SEARCH_RESULT_H
+
+#include <string>
+#include <contacts.h>
+
+/**
+ * @brief This class provides contact info for predictive number functionality
+ */
+namespace Phone
+{
+       namespace Dialer
+       {
+               /**
+                * @brief Specifies the source of predictive search result item.
+                */
+               enum ResultType {
+                       ResultNone = -1,    /**< Invalid result */
+                       ResultSpeeddial,    /**< From speed dial */
+                       ResultLog,          /**< From call logs */
+                       ResultName,         /**< From contacts matched by name */
+                       ResultNumber,       /**< From contacts matched by number */
+                       ResultMax           /**< Sentinel value */
+               };
+
+               /**
+                * @brief Predictive search result item.
+                */
+               class SearchResult
+               {
+               public:
+                       SearchResult(ResultType type, const contacts_record_h record = NULL);
+
+                       /**
+                        * @brief Gets searchable string, according to info type
+                        * @return Returns searchable string
+                        */
+                       std::string getSearchString() const;
+
+                       /**
+                        * @return info type value on successfully constructed object, otherwise IT_NONE value
+                        */
+                       ResultType getType() const;
+
+                       /**
+                        * @return contact ID on success or 0 if object constructed with errors
+                        */
+                       int getId() const;
+
+                       /**
+                        * @return speeddial ID on success or 0 if object constructed with errors
+                        */
+                       int getSpeedDialId() const;
+
+                       /**
+                        * @brief Gets normal or highlighted name
+                        * @param[in]   isHighlighted           Should highlighted name be returned
+                        * @return name of contact
+                        *
+                        * @remark This function returns reference to string,
+                        *                      it should be used before object destruction
+                        */
+                       const std::string &getName(bool isHighlighted) const;
+
+                       /**
+                        * @brief Gets normal or highlighted number
+                        * @param[in]   isHighlighted           Should highlighted number be returned
+                        * @return number of contact
+                        *
+                        * @remark This function returns reference to string,
+                        *                      it should be used before object destruction
+                        */
+                       const std::string &getNumber(bool isHighlighted) const;
+
+                       /**
+                        * @return highlighted text
+                        *
+                        * @remark This function returns reference to string,
+                        *                      it should be used before object destruction
+                        */
+                       const std::string &getHighlightedText() const;
+
+                       /**
+                        * @brief Highlights match text
+                        * @param[in]   searchStr               Search string
+                        * @return true if text was highlighted
+                        */
+                       bool updateHighlightText(const std::string searchStr, size_t position);
+
+               private:
+                       bool fillWithRecord(ResultType type, const contacts_record_h record);
+                       void fillSpeedDial(const contacts_record_h record);
+                       void fillLog(const contacts_record_h record);
+                       void fillContact(ResultType type, const contacts_record_h record);
+
+                       ResultType m_Type;
+                       int m_Id;
+                       int m_SpeedDialId;
+                       std::string m_MaskedName;
+                       std::string m_Name;
+                       std::string m_Number;
+                       std::string m_HighlightedText;
+               };
+       }
+}
+
+#endif /* PHONE_DIALER_SEARCH_RESULT_H */
diff --git a/lib-phone/inc/Phone/Dialer/SearchResultsPopup.h b/lib-phone/inc/Phone/Dialer/SearchResultsPopup.h
new file mode 100644 (file)
index 0000000..490e7ad
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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 PHONE_DIALER_SEARCH_RESULTS_POPUP_H
+#define PHONE_DIALER_SEARCH_RESULTS_POPUP_H
+
+#include "Phone/Dialer/SearchTypes.h"
+#include "Ui/Popup.h"
+
+namespace Phone
+{
+       namespace Dialer
+       {
+               class KeypadEntry;
+
+               /**
+                * @brief Predictive search result list popup.
+                */
+               class SearchResultsPopup : public Ui::Popup
+               {
+               public:
+                       /**
+                        * @brief Result selection callback
+                        * @param[in]   Selected result
+                        */
+                       typedef std::function<void(SearchResultPtr)> SelectedCallback;
+
+                       /**
+                        * @brief Constructor
+                        * @param[in]   result  Search results
+                        */
+                       SearchResultsPopup(const SearchResults *results);
+
+                       /**
+                        * @brief Set result selected callback
+                        */
+                       void setSelectedCallback(SelectedCallback callback);
+
+               private:
+                       virtual void onCreated() override;
+                       Evas_Object *createContactList(Evas_Object *parent);
+                       Elm_Genlist_Item_Class *createItemClass();
+
+                       static char *getItemText(void *data, Evas_Object *obj, const char *part);
+                       static Evas_Object *getItemContent(void *data, Evas_Object *obj, const char *part);
+                       void onItemSelected(Evas_Object *obj, void *event_info);
+
+                       const SearchResults *m_Results;
+                       SelectedCallback m_OnSelected;
+               };
+       }
+}
+
+#endif /* PHONE_DIALER_SEARCH_RESULTS_POPUP_H */
diff --git a/lib-phone/inc/Phone/Dialer/SearchResultsWidget.h b/lib-phone/inc/Phone/Dialer/SearchResultsWidget.h
new file mode 100644 (file)
index 0000000..3bc1090
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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 PHONE_DIALER_SEARCH_RESULTS_WIDGET_H
+#define PHONE_DIALER_SEARCH_RESULTS_WIDGET_H
+
+#include "Ui/Control.h"
+#include "Phone/Dialer/SearchTypes.h"
+
+namespace Phone
+{
+       namespace Dialer
+       {
+               /**
+                * @brief Predictive search result widget.
+                */
+               class SearchResultsWidget : public Ui::Control
+               {
+               public:
+                       /**
+                        * @brief Result selection callback
+                        * @param[in]   Selected result
+                        */
+                       typedef std::function<void(SearchResultPtr)> SelectedCallback;
+
+                       SearchResultsWidget();
+
+                       /**
+                        * @brief Set search results to be displayed
+                        * @param[in]   results     Search results
+                        */
+                       void setResults(const SearchResults *results);
+
+                       /**
+                        * @brief Clear search results and display nothing
+                        */
+                       void clearResults();
+
+                       /**
+                        * @brief Set result selected callback
+                        */
+                       void setSelectedCallback(SelectedCallback callback);
+
+               private:
+                       enum ResultsState
+                       {
+                               ResultsNone,
+                               ResultsEmpty,
+                               ResultsPresent,
+                               ResultsMany
+                       };
+
+               private:
+                       virtual Evas_Object *onCreate(Evas_Object *parent) override;
+
+                       void setLayout(const char *groupName);
+                       void clearLayout();
+
+                       void setResultsEmpty();
+                       void setResultsPresent();
+                       void setResultsCount(size_t count);
+
+                       void setResultInfo(SearchResultPtr result);
+                       void setResultSpeeddial(SearchResultPtr result);
+
+                       void onResultPressed();
+                       void onShowResultsPressed();
+
+                       const SearchResults *m_Results;
+                       ResultsState m_State;
+                       SelectedCallback m_OnSelected;
+                       Evas_Object *m_ResultsCount;
+               };
+       }
+}
+
+#endif /* PHONE_DIALER_SEARCH_RESULTS_WIDGET_H */
diff --git a/lib-phone/inc/Phone/Dialer/SearchTypes.h b/lib-phone/inc/Phone/Dialer/SearchTypes.h
new file mode 100644 (file)
index 0000000..f3e57aa
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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 PHONE_DIALER_SEARCH_TYPES_H
+#define PHONE_DIALER_SEARCH_TYPES_H
+
+#include "Phone/Dialer/SearchResult.h"
+#include <memory>
+#include <vector>
+
+namespace Phone
+{
+       namespace Dialer
+       {
+               /**
+                * @brief Smart pointer to SearchResult.
+                */
+               typedef std::shared_ptr<SearchResult> SearchResultPtr;
+
+               /**
+                * @brief List of searchable results.
+                */
+               typedef std::vector<SearchResultPtr> SearchResults;
+
+               /**
+                * @brief History of results.
+                */
+               typedef std::vector<SearchResults> SearchHistory;
+       }
+}
+
+#endif /* PHONE_DIALER_SEARCH_TYPES_H */
diff --git a/lib-phone/inc/Phone/Dialer/SearchUtils.h b/lib-phone/inc/Phone/Dialer/SearchUtils.h
new file mode 100644 (file)
index 0000000..9f3345d
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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 PHONE_DIALER_SEARCH_UTILS_H
+#define PHONE_DIALER_SEARCH_UTILS_H
+
+#include <string>
+#include <contacts.h>
+#include <Evas.h>
+
+namespace Phone
+{
+       namespace Dialer
+       {
+               namespace Utils
+               {
+                       /**
+                        * @param[in]   number  Speed dial number
+                        * @return contact with speed dial matched @a number
+                        */
+                       contacts_list_h getSpeedDial(char number);
+
+                       /**
+                        * @param[in]   digit   Digit in log number
+                        * @return log list with numbers contains @a digit
+                        */
+                       contacts_list_h getLogList(char digit);
+
+                       /**
+                        * @param[in]   digit   Digit on keypad
+                        * @return contacts list with names contains @a digit on phone keypad
+                        */
+                       contacts_list_h getContactListByName(char digit);
+
+                       /**
+                        * @param[in]   digit   Digit in contact's number
+                        * @return contacts list with numbers contains @a digit
+                        */
+                       contacts_list_h getContactListByNumber(char digit);
+
+                       /**
+                        * @param[in]   name    Contact name
+                        * @return converted contact name to letter mask
+                        */
+                       std::string contactNameToMask(const std::string &name);
+
+                       /**
+                        * @brief Highlight text from position
+                        * @param[in]   text       Text to highlight
+                        * @param[in]   position   Position from which the text should be highlighted
+                        * @param[in]   length     Length of highlighted part of text
+                        * @return highlighted string.
+                        */
+                       std::string highlightTextByPos(std::string &text, size_t position, size_t length);
+
+                       /**
+                        * param[in]    parent                          Parent layout
+                        * param[in]    contactId                       Contact ID
+                        */
+                       Evas_Object *createThumbnail(Evas_Object *parent, int contactId);
+               }
+       }
+}
+
+#endif /* PHONE_DIALER_SEARCH_UTILS_H */
diff --git a/lib-phone/inc/Phone/Dialer/SpeeddialPopup.h b/lib-phone/inc/Phone/Dialer/SpeeddialPopup.h
new file mode 100644 (file)
index 0000000..aa79553
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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 PHONE_DIALER_SPEEDDIAL_POPUP_H
+#define PHONE_DIALER_SPEEDDIAL_POPUP_H
+
+#include "Ui/Popup.h"
+#include <app_control.h>
+
+namespace Phone
+{
+       namespace Dialer
+       {
+               /**
+                * @brief "Add to speed dial" prompt popup.
+                */
+               class SpeeddialPopup : public Ui::Popup
+               {
+               public:
+                       /**
+                        * @brief Create speed dial popup.
+                        * @param[in]   speedNumber Dialer key value
+                        */
+                       SpeeddialPopup(int speedNumber);
+
+               private:
+                       virtual void onCreated() override;
+                       bool onOkPressed();
+
+                       static void onPickResult(app_control_h request, app_control_h reply,
+                                       app_control_result_e result, void *data);
+
+                       int m_SpeedNumber;
+               };
+       }
+}
+
+#endif /* PHONE_DIALER_SPEEDDIAL_POPUP_H */
diff --git a/lib-phone/inc/Phone/Utils.h b/lib-phone/inc/Phone/Utils.h
new file mode 100644 (file)
index 0000000..5b86e79
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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 PHONE_UTILS_H
+#define PHONE_UTILS_H
+
+namespace Phone
+{
+       /**
+        * @brief Add speed dial number.
+        * @param[in]   speedNumber Number on the dialer
+        * @param[in]   numberId    ID of number to assign to @a speedNumber
+        * @return true on success, false if number with this @a numberId already exists.
+        */
+       bool addSpeedDialNumber(int speedNumber, int numberId);
+}
+
+#endif /* PHONE_UTILS_H */
diff --git a/lib-phone/res/dialer/CMakeLists.txt b/lib-phone/res/dialer/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1ef6f6a
--- /dev/null
@@ -0,0 +1,15 @@
+set(EDCFILES dialer-keypad.edc dialer-layout.edc dialer-predictive.edc)
+set(EDJDIR "${RESDIR}/dialer/edje")
+
+foreach(EDCFILE ${EDCFILES})
+       get_filename_component(EDJFILE ${EDCFILE} NAME_WE)
+       set(EDJFILE ${EDJFILE}.edj)
+
+       add_custom_target(${EDJFILE}
+               COMMAND edje_cc -id .. edje/${EDCFILE} ${EDJFILE}
+               DEPENDS edje/${EDCFILE}
+       )
+
+       add_dependencies(${PROJECT_NAME} ${EDJFILE})
+       install(FILES ${EDJFILE} DESTINATION ${EDJDIR})
+endforeach(${EDCFILE})
diff --git a/lib-phone/res/dialer/edje/DialerLayout.h b/lib-phone/res/dialer/edje/DialerLayout.h
new file mode 100644 (file)
index 0000000..7ccf332
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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 DIALER_LAYOUT_H
+#define DIALER_LAYOUT_H
+
+#include "DialerPath.h"
+
+#define GROUP_DIALER                    "dialer"
+#define PART_SWALLOW_ENTRY              "swallow.entry"
+#define PART_SWALLOW_PREDICTIVE         "swallow.predictive"
+#define PART_SWALLOW_KEYPAD             "swallow.keypad"
+#define PART_SWALLOW_CALL               "swallow.call"
+#define PART_SWALLOW_BACKSPACE          "swallow.backspace"
+
+#define GROUP_PREDICTIVE_NO_RESULTS     "predictive_noresults"
+#define PART_TEXT_ADD                   "text.add"
+
+#define GROUP_PREDICTIVE                "predictive"
+#define PART_SWALLOW_THUMBNAIL          "swallow.thumbnail"
+#define PART_SWALLOW_SPEEDDIAL          "swallow.speeddial"
+#define PART_TEXT_NAME                  "text.name"
+#define PART_TEXT_NUMBER                "text.number"
+#define PART_TEXT_1_LINE                "text.1line"
+#define PART_SWALLOW_RESULTS            "swallow.results"
+
+#define GROUP_SPEEDDIAL_NUMBER          "speeddial_number"
+
+#define GROUP_PREDICTIVE_RES_COUNT      "predictive_res_count"
+#define PART_TEXT_COUNT                 "text.count"
+#define PART_SWALLOW_ARROW              "swallow.arrow"
+
+#define GROUP_BUTTON_CALL               "button_call"
+#define GROUP_BUTTON_BACKSPACE          "button_backspace"
+
+#define GROUP_BUTTON_1                  "keypad_button_1"
+#define GROUP_BUTTON_2                  "keypad_button_2"
+#define GROUP_BUTTON_3                  "keypad_button_3"
+#define GROUP_BUTTON_4                  "keypad_button_4"
+#define GROUP_BUTTON_5                  "keypad_button_5"
+#define GROUP_BUTTON_6                  "keypad_button_6"
+#define GROUP_BUTTON_7                  "keypad_button_7"
+#define GROUP_BUTTON_8                  "keypad_button_8"
+#define GROUP_BUTTON_9                  "keypad_button_9"
+#define GROUP_BUTTON_ASTERISK           "keypad_button_asterisk"
+#define GROUP_BUTTON_0                  "keypad_button_0"
+#define GROUP_BUTTON_SHARP              "keypad_button_sharp"
+
+#define BUTTON_CALL_NORMAL              89, 176, 58, 255
+#define BUTTON_CALL_PRESSED             127, 184, 106, 255
+
+#endif /* DIALER_LAYOUT_H */
diff --git a/lib-phone/res/dialer/edje/DialerLayoutColors.h b/lib-phone/res/dialer/edje/DialerLayoutColors.h
new file mode 100644 (file)
index 0000000..1050986
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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 DIALER_LAYOUT_COLORS_H
+#define DIALER_LAYOUT_COLORS_H
+
+color_classes {
+       color_class {//AO005
+               name: "keypad_bg_normal";
+               color: 255 255 255 255;
+       }
+       color_class {//AO005P
+               name: "keypad_bg_pressed";
+               color: 61 185 204 77;
+       }
+       color_class {//AO003
+               name: "button_number";
+               color: 0 0 0 217;
+       }
+       color_class {//AO003D
+               name: "button_number_pressed";
+               color: 0 0 0 77;
+       }
+       color_class {//AO004
+               name: "button_letter";
+               color: 51 51 51 205;
+       }
+       color_class {//AO004D
+               name: "button_letter_pressed";
+               color: 51 51 51 64;
+       }
+       color_class {//AO002
+               name: "action_button_normal";
+               color: 90 176 58 255;
+       }
+       color_class {//AO002D
+               name: "action_button_pressed";
+               color: 120 84 97 255;
+       }
+       color_class {//AO008
+               name: "divider_bg";
+               color: 217 217 217 255;
+       }
+       color_class {//AO006
+               name: "predictive_bg";
+               color: 255 255 255 26;
+       }
+       color_class {
+               name: "predictive_bg_pressed";
+               color: 0 0 0 26;
+       }
+       color_class {//A03O003L1
+               name: "predictive_icon";
+               color:  61 185 204 128;
+       }
+       color_class {//A03O003
+               name: "predictive_icon_bg";
+               color:  255 255 255 255;
+       }
+       color_class {//AO001
+               name: "action_panel_bg";
+               color: 255 255 255 255;
+       }
+       color_class {//AO014
+               name: "action_button_icon_normal";
+               color: 255 255 255 255;
+       }
+       color_class {
+               name: "back_button_icon_normal";
+               color: 180 180 180 255;
+       }
+       color_class {//AO014D
+               name: "action_button_icon_pressed";
+               color: 255 255 255 128;
+       }
+       color_class {
+               name: "transparent_bg";
+               color: 0 0 0 0;
+       }
+       color_class {//AO027
+               name: "speeddial_ic_bg";
+               color: 250 250 250 102;
+       }
+}
+
+#endif /* DIALER_LAYOUT_COLORS_H */
diff --git a/lib-phone/res/dialer/edje/DialerLayoutMetrics.h b/lib-phone/res/dialer/edje/DialerLayoutMetrics.h
new file mode 100644 (file)
index 0000000..a11a5b1
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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 DIALER_LAYOUT_METRICS_H
+#define DIALER_LAYOUT_METRICS_H
+
+#define TOTAL_W                             720
+#define TOTAL_H                             1120
+
+#define ENTRY_H                             296
+#define PREDICTIVE_H                        144
+#define KEYPAD_H                            528
+#define ACTION_PANEL_H                      152
+
+#define BUTTON_NUMBER_W                     238
+#define BUTTON_NUMBER_H                     130
+#define DIVIDER_SIZE                        2
+
+#define BUTTON_PART_W                       108
+#define BUTTON_PART_NUMBER_H                71
+#define BUTTON_PART_LETTERS_H               36
+
+#define OFFSET_BUTTON_PART_X                65
+#define OFFSET_BUTTON_PART_Y                12
+
+#define ACTION_BUTTONS_H                    152
+
+#define BUTTON_CALL_SIZE                    104
+#define BUTTON_CALL_X                       ((TOTAL_W-BUTTON_CALL_SIZE)/2)
+#define BUTTON_CALL_Y                       ((ACTION_BUTTONS_H-BUTTON_CALL_SIZE)/2)
+
+#define BUTTON_BACKSPACE_SIZE               90
+#define BUTTON_BACKSPACE_X                  82
+#define BUTTON_BACKSPACE_Y                  ((ACTION_BUTTONS_H-BUTTON_BACKSPACE_SIZE)/2)
+
+#define PREDICTIVE_PICTURE_BG_W             162
+#define PREDICTIVE_PICTURE_SIZE             98
+#define PREDICTIVE_MAIN_TEXT_H              57
+#define PREDICTIVE_SUB_TEXT_H               45
+#define PREDICTIVE_TEXT_W                   446
+#define PREDICTIVE_PARTS_H                  48
+#define PREDICTIVE_PARTS_W                  48
+#define PREDICTIVE_RESULTS_BG_W             112
+#define PREDICTIVE_ADD_SIZE                 80
+
+#define OFFSET_PREDICTIVE_Y                 24
+#define OFFSET_PREDICTIVE_TEXT_Y            ((PREDICTIVE_H-PREDICTIVE_MAIN_TEXT_H-PREDICTIVE_SUB_TEXT_H)/2)
+#define OFFSET_PREDICTIVE_1_LINE_TEXT_Y     ((PREDICTIVE_H-PREDICTIVE_MAIN_TEXT_H)/2)
+#define SPACER_PREDICTIVE_Y                 1
+#define SPACER_PREDICTIVE_X                 32
+#define OFFSET_PREDICTIVE_ADD               32
+
+#define SPEEDDIAL_AREA_W                    76
+#define SPEEDDIAL_AREA_H                    45
+#define SPEEDDIAL_IC_SIZE                   28
+#define SPEEDIAL_TEXT_W                     18
+
+#define SPEEDDIAL_SPACER                    12
+#define OFFSET_INNER_SPEEDDIAL_AREA_H       ((SPEEDDIAL_AREA_W-SPEEDDIAL_IC_SIZE-SPEEDIAL_TEXT_W)/2)
+#define OFFSET_T_SPEEDDIAL_IC               9
+#define OFFSET_B_SPEEDDIAL_IC               8
+
+#endif /* DIALER_LAYOUT_METRICS_H */
diff --git a/lib-phone/res/dialer/edje/DialerPath.h b/lib-phone/res/dialer/edje/DialerPath.h
new file mode 100644 (file)
index 0000000..8ad9a4f
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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 DIALER_PATH_H
+#define DIALER_PATH_H
+
+#define DIALER_IMG_DIR "dialer/images/"
+#define DIALER_EDJ_DIR "dialer/edje/"
+
+#define DIALER_LAYOUT_EDJ       DIALER_EDJ_DIR"dialer-layout.edj"
+#define DIALER_KEYPAD_EDJ       DIALER_EDJ_DIR"dialer-keypad.edj"
+#define DIALER_PREDICTIVE_EDJ   DIALER_EDJ_DIR"dialer-predictive.edj"
+
+#define KEYPAD_NUMBER_1         DIALER_IMG_DIR"keypad_number_01.png"
+#define KEYPAD_NUMBER_2         DIALER_IMG_DIR"keypad_number_02.png"
+#define KEYPAD_NUMBER_3         DIALER_IMG_DIR"keypad_number_03.png"
+#define KEYPAD_NUMBER_4         DIALER_IMG_DIR"keypad_number_04.png"
+#define KEYPAD_NUMBER_5         DIALER_IMG_DIR"keypad_number_05.png"
+#define KEYPAD_NUMBER_6         DIALER_IMG_DIR"keypad_number_06.png"
+#define KEYPAD_NUMBER_7         DIALER_IMG_DIR"keypad_number_07.png"
+#define KEYPAD_NUMBER_8         DIALER_IMG_DIR"keypad_number_08.png"
+#define KEYPAD_NUMBER_9         DIALER_IMG_DIR"keypad_number_09.png"
+#define KEYPAD_NUMBER_ASTERISK  DIALER_IMG_DIR"keypad_number_asterisk.png"
+#define KEYPAD_NUMBER_0         DIALER_IMG_DIR"keypad_number_00.png"
+#define KEYPAD_NUMBER_SHARP     DIALER_IMG_DIR"keypad_number_sharp.png"
+
+#define KEYPAD_LETTERS_2        DIALER_IMG_DIR"keypad_english_01.png"
+#define KEYPAD_LETTERS_3        DIALER_IMG_DIR"keypad_english_02.png"
+#define KEYPAD_LETTERS_4        DIALER_IMG_DIR"keypad_english_03.png"
+#define KEYPAD_LETTERS_5        DIALER_IMG_DIR"keypad_english_04.png"
+#define KEYPAD_LETTERS_6        DIALER_IMG_DIR"keypad_english_05.png"
+#define KEYPAD_LETTERS_7        DIALER_IMG_DIR"keypad_english_06.png"
+#define KEYPAD_LETTERS_8        DIALER_IMG_DIR"keypad_english_07.png"
+#define KEYPAD_LETTERS_9        DIALER_IMG_DIR"keypad_english_08.png"
+#define KEYPAD_LETTERS_0        DIALER_IMG_DIR"keypad_english_10.png"
+
+#define BUTTON_CALL             DIALER_IMG_DIR"keypad_ic_call.png"
+#define BUTTON_BACKSPACE        DIALER_IMG_DIR"keypad_ic_back.png"
+
+#define PREDICTIVE_ADD          DIALER_IMG_DIR"keypad_speed_dial_add.png"
+#define PREDICTIVE_ARROW        DIALER_IMG_DIR"keypad_predictive_arrow.png"
+
+#define SPEEDDIAL_IC_BG         DIALER_IMG_DIR"keypad_speed_dial_ic_bg.#.png"
+#define SPEEDDIAL_IC            DIALER_IMG_DIR"keypad_speed_dial_ic.png"
+
+#endif /* DIALER_PATH_H */
diff --git a/lib-phone/res/dialer/edje/dialer-keypad.edc b/lib-phone/res/dialer/edje/dialer-keypad.edc
new file mode 100644 (file)
index 0000000..9ee970a
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * 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 "DialerLayout.h"
+#include "DialerLayoutMetrics.h"
+#include "DialerLayoutColors.h"
+
+#define PART_BG \
+       part { \
+               name: "bg"; \
+               type: RECT; \
+               description { \
+                       state: "default" 0.0; \
+                       color_class: "keypad_bg_normal"; \
+               } \
+               description { \
+                       state: "pressed" 0.0; \
+                       color_class: "keypad_bg_pressed"; \
+               } \
+       }
+
+#define PART_NUMBER(IMAGE_PATH) \
+       part { \
+               name: "image.number"; \
+               type: IMAGE; \
+               images.image: IMAGE_PATH COMP; \
+               description { \
+                       state: "default" 0.0; \
+                       aspect: 0.0 1.0; \
+                       aspect_preference: SOURCE; \
+                       color_class: "button_number"; \
+                       rel1 { relative: (OFFSET_BUTTON_PART_X/BUTTON_NUMBER_W) (OFFSET_BUTTON_PART_Y/BUTTON_NUMBER_H); } \
+                       rel2 { relative: ((OFFSET_BUTTON_PART_X+BUTTON_PART_W)/BUTTON_NUMBER_W) ((OFFSET_BUTTON_PART_Y+BUTTON_PART_NUMBER_H)/BUTTON_NUMBER_H); } \
+                       image.normal: IMAGE_PATH; \
+               } \
+               description { \
+                       inherit: "default" 0.0; \
+                       state: "pressed" 0.0; \
+                       color_class: "button_number_pressed"; \
+               } \
+       }
+
+#define PART_LETTERS(IMAGE_PATH) \
+       part { \
+               name: "image.letters"; \
+               type: IMAGE; \
+               images.image: IMAGE_PATH COMP; \
+               description { \
+                       state: "default" 0.0; \
+                       aspect: 1.0 1.0; \
+                       aspect_preference: SOURCE; \
+                       color_class: "button_letter"; \
+                       rel1 { relative: (OFFSET_BUTTON_PART_X/BUTTON_NUMBER_W) ((OFFSET_BUTTON_PART_Y+BUTTON_PART_NUMBER_H)/BUTTON_NUMBER_H); } \
+                       rel2 { relative: ((OFFSET_BUTTON_PART_X+BUTTON_PART_W)/BUTTON_NUMBER_W) ((OFFSET_BUTTON_PART_Y+BUTTON_PART_NUMBER_H+BUTTON_PART_LETTERS_H)/BUTTON_NUMBER_H); } \
+                       image.normal: IMAGE_PATH; \
+               } \
+               description { \
+                       inherit: "default" 0.0; \
+                       state: "pressed" 0.0; \
+                       color_class: "button_letter_pressed"; \
+               } \
+       }
+
+#define PROGRAMS \
+       programs { \
+               program { \
+                       name: "pressed"; \
+                       signal: "mouse,down,*"; \
+                       source: "*"; \
+                       action: STATE_SET "pressed" 0.0; \
+                       target: "bg"; \
+               } \
+               program { \
+                       name: "unpressed"; \
+                       signal: "mouse,up,*"; \
+                       source: "*"; \
+                       action: STATE_SET "default" 0.0; \
+                       target: "bg"; \
+               } \
+       }
+
+#define KEYPAD_BUTTON_WITH_LETTERS( GROUP_NAME, NUMBER_PATH, LETTERS_PATH ) \
+       group { \
+               name: GROUP_NAME; \
+               parts { \
+                       PART_BG \
+                       PART_NUMBER(NUMBER_PATH) \
+                       PART_LETTERS(LETTERS_PATH) \
+               } \
+               PROGRAMS \
+       }
+
+#define KEYPAD_BUTTON_WITHOUT_LETTERS( GROUP_NAME, NUMBER_PATH ) \
+       group { \
+               name: GROUP_NAME; \
+               parts { \
+                       PART_BG \
+                       PART_NUMBER(NUMBER_PATH) \
+               } \
+               PROGRAMS \
+       }
+
+collections {
+       KEYPAD_BUTTON_WITHOUT_LETTERS(GROUP_BUTTON_1, KEYPAD_NUMBER_1);
+       KEYPAD_BUTTON_WITH_LETTERS(GROUP_BUTTON_2, KEYPAD_NUMBER_2, KEYPAD_LETTERS_2);
+       KEYPAD_BUTTON_WITH_LETTERS(GROUP_BUTTON_3, KEYPAD_NUMBER_3, KEYPAD_LETTERS_3);
+       KEYPAD_BUTTON_WITH_LETTERS(GROUP_BUTTON_4, KEYPAD_NUMBER_4, KEYPAD_LETTERS_4);
+       KEYPAD_BUTTON_WITH_LETTERS(GROUP_BUTTON_5, KEYPAD_NUMBER_5, KEYPAD_LETTERS_5);
+       KEYPAD_BUTTON_WITH_LETTERS(GROUP_BUTTON_6, KEYPAD_NUMBER_6, KEYPAD_LETTERS_6);
+       KEYPAD_BUTTON_WITH_LETTERS(GROUP_BUTTON_7, KEYPAD_NUMBER_7, KEYPAD_LETTERS_7);
+       KEYPAD_BUTTON_WITH_LETTERS(GROUP_BUTTON_8, KEYPAD_NUMBER_8, KEYPAD_LETTERS_8);
+       KEYPAD_BUTTON_WITH_LETTERS(GROUP_BUTTON_9, KEYPAD_NUMBER_9, KEYPAD_LETTERS_9);
+       KEYPAD_BUTTON_WITHOUT_LETTERS(GROUP_BUTTON_ASTERISK, KEYPAD_NUMBER_ASTERISK);
+       KEYPAD_BUTTON_WITH_LETTERS(GROUP_BUTTON_0, KEYPAD_NUMBER_0, KEYPAD_LETTERS_0);
+       KEYPAD_BUTTON_WITHOUT_LETTERS(GROUP_BUTTON_SHARP, KEYPAD_NUMBER_SHARP);
+}
\ No newline at end of file
diff --git a/lib-phone/res/dialer/edje/dialer-layout.edc b/lib-phone/res/dialer/edje/dialer-layout.edc
new file mode 100644 (file)
index 0000000..1b1a589
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * 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 "DialerLayout.h"
+#include "DialerLayoutMetrics.h"
+#include "DialerLayoutColors.h"
+#include "../../../../lib-common/res/common/edje/common-utils.edc"
+
+
+collections {
+       base_scale: 2.6;
+
+       group {
+               name: GROUP_DIALER;
+
+               parts {
+                       part {
+                               name: PART_SWALLOW_ENTRY;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.0 0.0; }
+                                       rel2 { relative: 1.0 (ENTRY_H/TOTAL_H); }
+                               }
+                       }
+                       part {
+                               name: PART_SWALLOW_PREDICTIVE;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       fixed: 1 1;
+                                       rel1 { relative: 0.0 ((ENTRY_H+1)/TOTAL_H); }
+                                       rel2 { relative: 1.0 ((ENTRY_H+PREDICTIVE_H)/TOTAL_H); }
+                               }
+                       }
+                       part {
+                               name: "keypad_bg";
+                               type: RECT;
+                               description {
+                                       state: "default" 0.0;
+                                       color_class: "divider_bg";
+                                       rel1 { relative: 0.0 ((ENTRY_H+PREDICTIVE_H+1)/TOTAL_H); }
+                                       rel2 { relative: 1.0 ((ENTRY_H+PREDICTIVE_H+KEYPAD_H-DIVIDER_SIZE)/TOTAL_H); }
+                               }
+                       }
+                       part {
+                               name: PART_SWALLOW_KEYPAD;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 { relative: 0.0 0.0; to: "keypad_bg"; }
+                                       rel2 { relative: 1.0 1.0; to: "keypad_bg"; }
+                               }
+                       }
+                       part {
+                               name: "divider";
+                               type: RECT;
+                               description {
+                                       state: "default" 0.0;
+                                       color_class: "divider_bg";
+                                       rel1 { relative: 0.0 1.0; to: "keypad_bg"; }
+                                       rel2 { relative: 1.0 ((ENTRY_H+PREDICTIVE_H+KEYPAD_H)/TOTAL_H); }
+                               }
+                       }
+                       part {
+                               name: "action_panel_bg";
+                               type: RECT;
+                               description {
+                                       state: "default" 0.0;
+                                       color_class: "action_panel_bg";
+                                       rel1 { relative: 0.0 1.0; to: "divider"; }
+                                       rel2 { relative: 1.0 1.0; }
+                               }
+                       }
+                       part {
+                               name: PART_SWALLOW_CALL;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       aspect: 1.0 1.0;
+                                       aspect_preference: SOURCE;
+                                       fixed: 1 1;
+                                       rel1 { relative: (BUTTON_CALL_X/TOTAL_W) (BUTTON_CALL_Y/ACTION_PANEL_H); to: "action_panel_bg"; }
+                                       rel2 { relative: (1.0-(BUTTON_CALL_X/TOTAL_W)) (1.0-(BUTTON_CALL_Y/ACTION_PANEL_H)); to: "action_panel_bg"; }
+                               }
+                       }
+                       part {
+                               name: PART_SWALLOW_BACKSPACE;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       aspect: 1.0 1.0;
+                                       aspect_preference: SOURCE;
+                                       fixed: 1 1;
+                                       rel1 { relative: (1.0-((BUTTON_BACKSPACE_X+BUTTON_BACKSPACE_SIZE)/TOTAL_W)) (BUTTON_BACKSPACE_Y/ACTION_PANEL_H); to: "action_panel_bg"; }
+                                       rel2 { relative: (1.0-(BUTTON_BACKSPACE_X/TOTAL_W)) (1.0-(BUTTON_BACKSPACE_Y/ACTION_PANEL_H)); to: "action_panel_bg"; }
+                               }
+                       }
+               }
+       }
+
+       IMAGE_WITH_COLOR(GROUP_BUTTON_CALL, BUTTON_CALL, "action_button_icon_normal");
+       IMAGE_WITH_COLOR(GROUP_BUTTON_BACKSPACE, BUTTON_BACKSPACE, "back_button_icon_normal");
+}
diff --git a/lib-phone/res/dialer/edje/dialer-predictive.edc b/lib-phone/res/dialer/edje/dialer-predictive.edc
new file mode 100644 (file)
index 0000000..7627703
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * 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 "DialerLayout.h"
+#include "DialerLayoutMetrics.h"
+#include "DialerLayoutColors.h"
+
+images {
+       image: PREDICTIVE_ADD COMP;
+       image: PREDICTIVE_ARROW COMP;
+       image: SPEEDDIAL_IC_BG COMP;
+       image: SPEEDDIAL_IC COMP;
+}
+
+styles {
+       style {
+               name: "add_to_contacts_style";
+               base: "font=Tizen:style=Light font_size=46 color=#FAFAFA ellipsis=1.0";
+       }
+       style {
+               name: "highlight_style";
+               base: "font=Tizen:style=Light font_size=40 color=#FAFAFA ellipsis=1.0";
+               tag: "match" "+color=#86EDFC";
+       }
+       style {
+               name: "small_highlight_style";
+               base: "font=Tizen:style=Light font_size=32 color=#FAFAFA ellipsis=1.0";
+               tag: "match" "+color=#86EDFC";
+       }
+       style {
+               name: "count_style";
+               base: "font=Tizen:style=Regular font_size=36 align=center color=#FAFAFA ellipsis=1.0";
+       }
+       style {
+               name: "predictive_speeddial_style";
+               base: "font=Tizen:style=Regular font_size=32 color=#FFFAFA";
+       }
+
+}
+
+collections {
+       base_scale: 2.6;
+       group {
+               name: GROUP_PREDICTIVE_NO_RESULTS;
+               parts {
+                       part {
+                               name: "bg";
+                               type: RECT;
+                               description {
+                                       state: "default" 0.0;
+                                       color_class: "predictive_bg";
+                               }
+                               description {
+                                       state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "predictive_bg_pressed";
+                               }
+                       }
+                       part {
+                               name: PART_TEXT_ADD;
+                               type: TEXTBLOCK;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       text {
+                                               align: 0.1 0.5;
+                                               style: "add_to_contacts_style";
+                                       }
+                                       rel1 { relative: ((OFFSET_PREDICTIVE_ADD+1)/TOTAL_W) ((OFFSET_PREDICTIVE_ADD+1)/PREDICTIVE_H); }
+                                       rel2 { relative: ((TOTAL_W-PREDICTIVE_H)/TOTAL_W) ((OFFSET_PREDICTIVE_ADD+PREDICTIVE_ADD_SIZE)/PREDICTIVE_H); to_x: "add_bg"; }
+                               }
+                       }
+                       part {
+                               name: "add_bg";
+                               type: RECT;
+                               description {
+                                       state: "default" 0.0;
+                                       color_class: "transparent_bg";
+                                       rel1 { relative: ((TOTAL_W-PREDICTIVE_H+1)/TOTAL_W) 0.0; }
+                                       rel2 { relative: 1.0 1.0; }
+                               }
+                       }
+                       part {
+                               name: "image.add";
+                               type: IMAGE;
+                               description {
+                                       state: "default" 0.0;
+                                       aspect: 1.0 1.0;
+                                       aspect_preference: SOURCE;
+                                       image.normal: PREDICTIVE_ADD;
+                                       rel1 { relative: ((OFFSET_PREDICTIVE_ADD+1)/PREDICTIVE_H) ((OFFSET_PREDICTIVE_ADD+1)/PREDICTIVE_H); to:"add_bg"; }
+                                       rel2 { relative: ((OFFSET_PREDICTIVE_ADD+PREDICTIVE_ADD_SIZE)/PREDICTIVE_H) ((OFFSET_PREDICTIVE_ADD+PREDICTIVE_ADD_SIZE)/PREDICTIVE_H); to:"add_bg"; }
+                               }
+                       }
+               }
+
+               programs {
+                       program {
+                               name: "pressed";
+                               signal: "mouse,down,*";
+                               source: "*";
+                               action: STATE_SET "pressed" 0.0;
+                               target: "bg";
+                       }
+                       program {
+                               name: "unpressed";
+                               signal: "mouse,up,*";
+                               source: "*";
+                               action: STATE_SET "default" 0.0;
+                               target: "bg";
+                       }
+               }
+       }
+
+       group {
+               name: GROUP_PREDICTIVE;
+               parts {
+                       part {
+                               name: "bg";
+                               type: RECT;
+                               description {
+                                       state: "default" 0.0;
+                                       color_class: "predictive_bg";
+                               }
+                               description {
+                                       state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "predictive_bg_pressed";
+                               }
+                       }
+                       part {
+                               name: "thumbnail_bg";
+                               type: RECT;
+                               description {
+                                       state: "default" 0.0;
+                                       color_class: "transparent_bg";
+                                       rel2 { relative: (PREDICTIVE_PICTURE_BG_W/TOTAL_W) 1.0; }
+                               }
+                       }
+                       part {
+                               name: PART_SWALLOW_THUMBNAIL;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 { relative: ((SPACER_PREDICTIVE_X+1)/PREDICTIVE_PICTURE_BG_W) ((OFFSET_PREDICTIVE_Y+1)/PREDICTIVE_H); to: "thumbnail_bg"; }
+                                       rel2 { relative: ((SPACER_PREDICTIVE_X+PREDICTIVE_PICTURE_SIZE)/PREDICTIVE_PICTURE_BG_W) ((OFFSET_PREDICTIVE_Y+PREDICTIVE_PICTURE_SIZE)/PREDICTIVE_H); to: "thumbnail_bg"; }
+                               }
+                       }
+                       part {
+                               name: PART_SWALLOW_SPEEDDIAL;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       visible: 0;
+                                       rel1 { relative: 1.0 ((OFFSET_PREDICTIVE_TEXT_Y+1)/PREDICTIVE_H); to_x: "thumbnail_bg"; }
+                                       rel2 { relative: ((PREDICTIVE_PICTURE_BG_W+SPEEDDIAL_AREA_W)/TOTAL_W) ((OFFSET_PREDICTIVE_TEXT_Y+PREDICTIVE_MAIN_TEXT_H)/PREDICTIVE_H); }
+                               }
+                               description {
+                                       state: "speeddial" 0.0;
+                                       inherit: "default" 0.0;
+                                       visible: 1;
+                               }
+                       }
+                       part {
+                               name: PART_TEXT_NAME;
+                               type: TEXTBLOCK;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       text {
+                                               align: 0.0 0.5;
+                                               style: "highlight_style";
+                                       }
+                                       rel1 { relative: 1.0 ((OFFSET_PREDICTIVE_TEXT_Y+1)/PREDICTIVE_H); to_x: "thumbnail_bg"; }
+                                       rel2 { relative: 0.0 ((OFFSET_PREDICTIVE_TEXT_Y+PREDICTIVE_MAIN_TEXT_H)/PREDICTIVE_H); to_x: "result_bg"; }
+                               }
+                               description {
+                                       state: "speeddial" 0.0;
+                                       inherit: "default" 0.0;
+                                       rel1 {
+                                               relative: ((PREDICTIVE_PICTURE_BG_W+SPEEDDIAL_AREA_W + SPEEDDIAL_SPACER)/TOTAL_W) ((OFFSET_PREDICTIVE_TEXT_Y+1)/PREDICTIVE_H);
+                                               to_x: "";
+                                       }
+                                       rel2 {
+                                               relative: 0.0 ((OFFSET_PREDICTIVE_TEXT_Y+PREDICTIVE_MAIN_TEXT_H)/PREDICTIVE_H);
+                                               to_x: "result_bg";
+                                       }
+                               }
+                       }
+                       part {
+                               name: PART_TEXT_NUMBER;
+                               type: TEXTBLOCK;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       text {
+                                               align: 0.0 0.5;
+                                               style: "small_highlight_style";
+                                       }
+                                       rel1 { relative: 1.0 ((OFFSET_PREDICTIVE_TEXT_Y+PREDICTIVE_MAIN_TEXT_H+1)/PREDICTIVE_H); to_x: "thumbnail_bg"; }
+                                       rel2 { relative: 0.0 ((OFFSET_PREDICTIVE_TEXT_Y+PREDICTIVE_MAIN_TEXT_H+PREDICTIVE_SUB_TEXT_H)/PREDICTIVE_H); to_x: "result_bg"; }
+                               }
+                       }
+                       part {
+                               name: PART_TEXT_1_LINE;
+                               type: TEXTBLOCK;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       text {
+                                               align: 0.0 0.5;
+                                               style: "highlight_style";
+                                       }
+                                       rel1 { relative: 1.0 ((OFFSET_PREDICTIVE_1_LINE_TEXT_Y+1)/PREDICTIVE_H); to_x: "thumbnail_bg"; }
+                                       rel2 { relative: 0.0 ((OFFSET_PREDICTIVE_1_LINE_TEXT_Y+PREDICTIVE_MAIN_TEXT_H)/PREDICTIVE_H); to_x: "result_bg"; }
+                               }
+                       }
+                       part {
+                               name: "result_bg";
+                               type: RECT;
+                               description {
+                                       state: "default" 0.0;
+                                       color_class: "transparent_bg";
+                                       rel1 { relative: ((PREDICTIVE_PICTURE_BG_W+PREDICTIVE_TEXT_W+1)/TOTAL_W) 0.0; }
+                                       rel2 { relative: 1.0 1.0; }
+                               }
+                       }
+                       part {
+                               name: PART_SWALLOW_RESULTS;
+                               type: SWALLOW;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1.to: "result_bg";
+                                       rel2.to: "result_bg";
+                               }
+                       }
+               }
+               programs {
+                       program {
+                               name: "pressed";
+                               signal: "mouse,down,*";
+                               source: "*";
+                               action: STATE_SET "pressed" 0.0;
+                               target: "bg";
+                       }
+                       program {
+                               name: "unpressed";
+                               signal: "mouse,up,*";
+                               source: "*";
+                               action: STATE_SET "default" 0.0;
+                               target: "bg";
+                       }
+                       program {
+                               name: "show_speeddial_icon";
+                               signal: "show,speeddial,icon";
+                               action: STATE_SET "speeddial" 0.0;
+                               target: PART_SWALLOW_SPEEDDIAL;
+                               target: PART_TEXT_NAME;
+                       }
+                       program {
+                               name: "hide_speeddial_icon";
+                               signal: "hide,speeddial,icon";
+                               action: STATE_SET "default" 0.0;
+                               target: PART_SWALLOW_SPEEDDIAL;
+                               target: PART_TEXT_NAME;
+                       }
+               }
+       }
+
+       group {
+               name: GROUP_SPEEDDIAL_NUMBER;
+               parts {
+                       part {
+                               name: "bg";
+                               type: IMAGE;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       image.normal: SPEEDDIAL_IC_BG;
+                                       color_class: "speeddial_ic_bg";
+                               }
+                       }
+                       part {
+                               name: "swallow.icon";
+                               type: IMAGE;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1.relative: (OFFSET_INNER_SPEEDDIAL_AREA_H/SPEEDDIAL_AREA_W) (OFFSET_T_SPEEDDIAL_IC/SPEEDDIAL_AREA_H);
+                                       rel2.relative: ((OFFSET_INNER_SPEEDDIAL_AREA_H+SPEEDDIAL_IC_SIZE)/SPEEDDIAL_AREA_W) ((OFFSET_T_SPEEDDIAL_IC+SPEEDDIAL_IC_SIZE)/SPEEDDIAL_AREA_H);
+                                       image.normal: SPEEDDIAL_IC;
+                               }
+                       }
+                       part {
+                               name: PART_TEXT_NUMBER;
+                               type: TEXTBLOCK;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       rel1 {
+                                               relative: 1.0 0.0;
+                                               to_x: "swallow.icon";
+                                       }
+                                       rel2.relative: 1.0 1.0;
+                                       text {
+                                               align: 0.0 0.5;
+                                               style: "predictive_speeddial_style";
+                                       }
+                               }
+                       }
+               }
+       }
+
+       group {
+               name: GROUP_PREDICTIVE_RES_COUNT;
+               parts {
+                       part {
+                               name: "bg";
+                               type: "RECT";
+                               description {
+                                       state: "default" 0.0;
+                                       color_class: "transparent_bg";
+                               }
+                       }
+                       part {
+                               name: PART_TEXT_COUNT;
+                               type: TEXTBLOCK;
+                               scale: 1;
+                               description {
+                                       state: "default" 0.0;
+                                       text {
+                                               align: 0.5 0.0;
+                                               style: "count_style";
+                                       }
+                                       rel1 { relative: 0.0 ((OFFSET_PREDICTIVE_Y+1)/PREDICTIVE_H); }
+                                       rel2 { relative: 1.0 ((OFFSET_PREDICTIVE_Y+PREDICTIVE_PARTS_H)/PREDICTIVE_H); }
+                               }
+                       }
+                       part {
+                               name: PART_SWALLOW_ARROW;
+                               type: IMAGE;
+                               description {
+                                       state: "default" 0.0;
+                                       aspect: 1.0 1.0;
+                                       aspect_preference: SOURCE;
+                                       rel1 { relative: ((SPACER_PREDICTIVE_X+1)/PREDICTIVE_RESULTS_BG_W) ((OFFSET_PREDICTIVE_Y+PREDICTIVE_PARTS_H+SPACER_PREDICTIVE_Y+1)/PREDICTIVE_H); }
+                                       rel2 { relative: ((SPACER_PREDICTIVE_X+PREDICTIVE_PARTS_W)/PREDICTIVE_RESULTS_BG_W) ((OFFSET_PREDICTIVE_Y+2*PREDICTIVE_PARTS_H+SPACER_PREDICTIVE_Y)/PREDICTIVE_H); }
+                                       image.normal: PREDICTIVE_ARROW;
+                               }
+                               description {
+                                       state: "pressed" 0.0;
+                                       inherit: "default" 0.0;
+                                       color_class: "predictive_icon";
+                               }
+                       }
+               }
+               programs {
+                       program {
+                               name: "pressed";
+                               signal: "mouse,down,*";
+                               source: "*";
+                               action: STATE_SET "pressed" 0.0;
+                               target: PART_SWALLOW_ARROW;
+                       }
+                       program {
+                               name: "unpressed";
+                               signal: "mouse,up,*";
+                               source: "*";
+                               action: STATE_SET "default" 0.0;
+                               target: PART_SWALLOW_ARROW;
+                       }
+               }
+       }
+}
diff --git a/lib-phone/res/dialer/images/keypad_english_01.png b/lib-phone/res/dialer/images/keypad_english_01.png
new file mode 100644 (file)
index 0000000..309dd86
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_english_01.png differ
diff --git a/lib-phone/res/dialer/images/keypad_english_02.png b/lib-phone/res/dialer/images/keypad_english_02.png
new file mode 100644 (file)
index 0000000..2fa7a0b
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_english_02.png differ
diff --git a/lib-phone/res/dialer/images/keypad_english_03.png b/lib-phone/res/dialer/images/keypad_english_03.png
new file mode 100644 (file)
index 0000000..98f7ad1
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_english_03.png differ
diff --git a/lib-phone/res/dialer/images/keypad_english_04.png b/lib-phone/res/dialer/images/keypad_english_04.png
new file mode 100644 (file)
index 0000000..6b6a172
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_english_04.png differ
diff --git a/lib-phone/res/dialer/images/keypad_english_05.png b/lib-phone/res/dialer/images/keypad_english_05.png
new file mode 100644 (file)
index 0000000..288854f
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_english_05.png differ
diff --git a/lib-phone/res/dialer/images/keypad_english_06.png b/lib-phone/res/dialer/images/keypad_english_06.png
new file mode 100644 (file)
index 0000000..f346c46
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_english_06.png differ
diff --git a/lib-phone/res/dialer/images/keypad_english_07.png b/lib-phone/res/dialer/images/keypad_english_07.png
new file mode 100644 (file)
index 0000000..e70e9a8
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_english_07.png differ
diff --git a/lib-phone/res/dialer/images/keypad_english_08.png b/lib-phone/res/dialer/images/keypad_english_08.png
new file mode 100644 (file)
index 0000000..f4de8af
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_english_08.png differ
diff --git a/lib-phone/res/dialer/images/keypad_english_10.png b/lib-phone/res/dialer/images/keypad_english_10.png
new file mode 100644 (file)
index 0000000..2072f56
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_english_10.png differ
diff --git a/lib-phone/res/dialer/images/keypad_ic_back.png b/lib-phone/res/dialer/images/keypad_ic_back.png
new file mode 100644 (file)
index 0000000..2f08d97
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_ic_back.png differ
diff --git a/lib-phone/res/dialer/images/keypad_ic_call.png b/lib-phone/res/dialer/images/keypad_ic_call.png
new file mode 100644 (file)
index 0000000..526483c
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_ic_call.png differ
diff --git a/lib-phone/res/dialer/images/keypad_number_00.png b/lib-phone/res/dialer/images/keypad_number_00.png
new file mode 100644 (file)
index 0000000..255c897
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_number_00.png differ
diff --git a/lib-phone/res/dialer/images/keypad_number_01.png b/lib-phone/res/dialer/images/keypad_number_01.png
new file mode 100644 (file)
index 0000000..409bfb8
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_number_01.png differ
diff --git a/lib-phone/res/dialer/images/keypad_number_02.png b/lib-phone/res/dialer/images/keypad_number_02.png
new file mode 100644 (file)
index 0000000..b12b92f
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_number_02.png differ
diff --git a/lib-phone/res/dialer/images/keypad_number_03.png b/lib-phone/res/dialer/images/keypad_number_03.png
new file mode 100644 (file)
index 0000000..058876c
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_number_03.png differ
diff --git a/lib-phone/res/dialer/images/keypad_number_04.png b/lib-phone/res/dialer/images/keypad_number_04.png
new file mode 100644 (file)
index 0000000..3906f18
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_number_04.png differ
diff --git a/lib-phone/res/dialer/images/keypad_number_05.png b/lib-phone/res/dialer/images/keypad_number_05.png
new file mode 100644 (file)
index 0000000..a104591
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_number_05.png differ
diff --git a/lib-phone/res/dialer/images/keypad_number_06.png b/lib-phone/res/dialer/images/keypad_number_06.png
new file mode 100644 (file)
index 0000000..4c0893b
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_number_06.png differ
diff --git a/lib-phone/res/dialer/images/keypad_number_07.png b/lib-phone/res/dialer/images/keypad_number_07.png
new file mode 100644 (file)
index 0000000..e9eb6a0
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_number_07.png differ
diff --git a/lib-phone/res/dialer/images/keypad_number_08.png b/lib-phone/res/dialer/images/keypad_number_08.png
new file mode 100644 (file)
index 0000000..f6bd01b
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_number_08.png differ
diff --git a/lib-phone/res/dialer/images/keypad_number_09.png b/lib-phone/res/dialer/images/keypad_number_09.png
new file mode 100644 (file)
index 0000000..ede6db2
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_number_09.png differ
diff --git a/lib-phone/res/dialer/images/keypad_number_asterisk.png b/lib-phone/res/dialer/images/keypad_number_asterisk.png
new file mode 100644 (file)
index 0000000..923ea88
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_number_asterisk.png differ
diff --git a/lib-phone/res/dialer/images/keypad_number_sharp.png b/lib-phone/res/dialer/images/keypad_number_sharp.png
new file mode 100644 (file)
index 0000000..e0118d4
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_number_sharp.png differ
diff --git a/lib-phone/res/dialer/images/keypad_predictive_arrow.png b/lib-phone/res/dialer/images/keypad_predictive_arrow.png
new file mode 100644 (file)
index 0000000..7617f4e
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_predictive_arrow.png differ
diff --git a/lib-phone/res/dialer/images/keypad_speed_dial_add.png b/lib-phone/res/dialer/images/keypad_speed_dial_add.png
new file mode 100644 (file)
index 0000000..39c6a86
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_speed_dial_add.png differ
diff --git a/lib-phone/res/dialer/images/keypad_speed_dial_ic.png b/lib-phone/res/dialer/images/keypad_speed_dial_ic.png
new file mode 100644 (file)
index 0000000..7297b95
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_speed_dial_ic.png differ
diff --git a/lib-phone/res/dialer/images/keypad_speed_dial_ic_bg.#.png b/lib-phone/res/dialer/images/keypad_speed_dial_ic_bg.#.png
new file mode 100644 (file)
index 0000000..584f366
Binary files /dev/null and b/lib-phone/res/dialer/images/keypad_speed_dial_ic_bg.#.png differ
diff --git a/lib-phone/src/Phone/Dialer/AddNumberPopup.cpp b/lib-phone/src/Phone/Dialer/AddNumberPopup.cpp
new file mode 100644 (file)
index 0000000..4ff5968
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * 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 "Phone/Dialer/AddNumberPopup.h"
+#include "App/AppControlRequest.h"
+#include "Ui/Editfield.h"
+#include "Utils/Logger.h"
+
+#include <app_i18n.h>
+
+using namespace App;
+using namespace Phone::Dialer;
+
+AddNumberPopup::AddNumberPopup(std::string number)
+       : m_Number(std::move(number))
+{
+}
+
+void AddNumberPopup::onCreated()
+{
+       elm_popup_orient_set(getEvasObject(), ELM_POPUP_ORIENT_CENTER);
+       setTitle("IDS_KPD_BUTTON_ADD_TO_CONTACTS_ABB2");
+       setContent(createGenlist(getEvasObject()));
+}
+
+Evas_Object *AddNumberPopup::createGenlist(Evas_Object *parent)
+{
+       Evas_Object *genlist = elm_genlist_add(parent);
+       elm_genlist_homogeneous_set(genlist, EINA_TRUE);
+       elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
+       elm_scroller_content_min_limit(genlist, EINA_FALSE, EINA_TRUE);
+
+       Elm_Genlist_Item_Class *itc = createItemClass();
+
+       elm_genlist_item_append(genlist, itc, "IDS_LOGS_BUTTON_CREATE_CONTACT_ABB",
+                       NULL, ELM_GENLIST_ITEM_NONE, launchContactCreate, this);
+       elm_genlist_item_append(genlist, itc, "IDS_LOGS_BUTTON_UPDATE_CONTACT_ABB2",
+                       NULL, ELM_GENLIST_ITEM_NONE, launchContactUpdate, this);
+
+       elm_genlist_item_class_free(itc);
+       return genlist;
+}
+
+Elm_Genlist_Item_Class *AddNumberPopup::createItemClass()
+{
+       Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
+       RETVM_IF(!itc, NULL, "elm_genlist_item_class_new() failed");
+       itc->item_style = "type1";
+       itc->func.text_get = getItemText;
+       return itc;
+}
+
+char *AddNumberPopup::getItemText(void *data, Evas_Object *obj, const char *part)
+{
+       RETVM_IF(!data, NULL, "data = NULL");
+       const char *text = (const char *)data;
+
+       if (!strcmp(part, "elm.text")) {
+               return strdup(_(text));
+       }
+
+       return NULL;
+}
+
+void AddNumberPopup::launchContactCreate(void *data,
+               Evas_Object *obj, void *event_info)
+{
+       RETM_IF(!data, "data = NULL");
+       AddNumberPopup *popup = (AddNumberPopup*)data;
+
+       AppControl request = requestContactCreate(popup->m_Number.c_str());
+       request.launch();
+       request.detach();
+
+       delete popup;
+}
+
+void AddNumberPopup::launchContactUpdate(void *data,
+               Evas_Object *obj, void *event_info)
+{
+       RETM_IF(!data, "data = NULL");
+       AddNumberPopup *popup = (AddNumberPopup*)data;
+
+       AppControl request = requestContactEdit(0, popup->m_Number.c_str());
+       request.launch();
+       request.detach();
+
+       delete popup;
+}
diff --git a/lib-phone/src/Phone/Dialer/KeypadButton.cpp b/lib-phone/src/Phone/Dialer/KeypadButton.cpp
new file mode 100644 (file)
index 0000000..bcffce2
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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 "Phone/Dialer/KeypadButton.h"
+#include "App/Path.h"
+#include "Utils/Logger.h"
+
+#include "DialerLayout.h"
+
+#include <feedback.h>
+
+using namespace Phone::Dialer;
+
+struct Phone::Dialer::KeypadButtonData
+{
+       char value;
+       const char *group;
+       feedback_pattern_e pattern;
+};
+
+namespace
+{
+       const KeypadButtonData keyData[] = {
+               { '1', GROUP_BUTTON_1, FEEDBACK_PATTERN_KEY1 },
+               { '2', GROUP_BUTTON_2, FEEDBACK_PATTERN_KEY2 },
+               { '3', GROUP_BUTTON_3, FEEDBACK_PATTERN_KEY3 },
+               { '4', GROUP_BUTTON_4, FEEDBACK_PATTERN_KEY4 },
+               { '5', GROUP_BUTTON_5, FEEDBACK_PATTERN_KEY5 },
+               { '6', GROUP_BUTTON_6, FEEDBACK_PATTERN_KEY6 },
+               { '7', GROUP_BUTTON_7, FEEDBACK_PATTERN_KEY7 },
+               { '8', GROUP_BUTTON_8, FEEDBACK_PATTERN_KEY8 },
+               { '9', GROUP_BUTTON_9, FEEDBACK_PATTERN_KEY9 },
+               { '*', GROUP_BUTTON_ASTERISK, FEEDBACK_PATTERN_KEY_STAR },
+               { '0', GROUP_BUTTON_0, FEEDBACK_PATTERN_KEY0 },
+               { '#', GROUP_BUTTON_SHARP, FEEDBACK_PATTERN_KEY_SHARP },
+       };
+}
+
+KeypadButton::KeypadButton(Id id)
+       : m_Id(id), m_Data(&keyData[id])
+{
+}
+
+Evas_Object *KeypadButton::onCreate(Evas_Object *parent)
+{
+       static const std::string path = App::getResourcePath(DIALER_KEYPAD_EDJ);
+       Evas_Object *layout = elm_layout_add(parent);
+       Eina_Bool res = elm_layout_file_set(layout, path.c_str(), m_Data->group);
+       WARN_IF(res != EINA_TRUE, "elm_layout_file_set() failed");
+       evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_DOWN,
+                       (Evas_Object_Event_Cb) feedback_play, (void *) m_Data->pattern);
+
+       return layout;
+}
+
+char KeypadButton::getValue() const
+{
+       return m_Data->value;
+}
+
+KeypadButton::Id KeypadButton::getId() const
+{
+       return m_Id;
+}
diff --git a/lib-phone/src/Phone/Dialer/KeypadEntry.cpp b/lib-phone/src/Phone/Dialer/KeypadEntry.cpp
new file mode 100644 (file)
index 0000000..2bd7445
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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 "Phone/Dialer/KeypadEntry.h"
+#include "Utils/Callback.h"
+
+#include <efl_extension.h>
+
+using namespace Phone::Dialer;
+
+std::string KeypadEntry::getNumber() const
+{
+       std::string number;
+       char *str = elm_entry_markup_to_utf8(elm_entry_entry_get(getEvasObject()));
+       if (str) {
+               number = str;
+               free(str);
+       }
+
+       return number;
+}
+
+void KeypadEntry::setNumber(const std::string &number)
+{
+       elm_entry_entry_set(getEvasObject(), number.c_str());
+       elm_entry_cursor_line_end_set(getEvasObject());
+}
+
+void KeypadEntry::insert(char c)
+{
+       char str[] = { c, '\0' };
+       elm_entry_entry_insert(getEvasObject(), str);
+}
+
+void KeypadEntry::popBack()
+{
+       int pos = elm_entry_cursor_pos_get(getEvasObject());
+       if (pos > 0) {
+               elm_entry_select_region_set(getEvasObject(), pos - 1, pos);
+               elm_entry_entry_insert(getEvasObject(), "");
+       }
+}
+
+void KeypadEntry::clear()
+{
+       elm_entry_entry_set(getEvasObject(), "");
+}
+
+void KeypadEntry::setChangedCallback(ChangedCallback callback)
+{
+       m_OnChanged = std::move(callback);
+}
+
+Evas_Object *KeypadEntry::onCreate(Evas_Object *parent)
+{
+       Evas_Object *entry = elm_entry_add(parent);
+       elm_entry_single_line_set(entry, EINA_TRUE);
+       elm_entry_scrollable_set(entry, EINA_TRUE);
+       elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
+
+       static Elm_Entry_Filter_Accept_Set filter = { "+*#;,1234567890", NULL };
+       elm_entry_markup_filter_append(entry, elm_entry_filter_accept_set, &filter);
+       elm_entry_text_style_user_push(entry, "DEFAULT='font=Tizen:style=Light font_size=60 color=#fff align=center'");
+
+       eext_entry_selection_back_event_allow_set(entry, EINA_TRUE);
+       evas_object_smart_callback_add(entry, "changed",
+                       makeCallback(&KeypadEntry::onChanged), this);
+       return entry;
+}
+
+void KeypadEntry::onChanged(Evas_Object *obj, void *event_info)
+{
+       if (m_OnChanged) {
+               m_OnChanged();
+       }
+}
diff --git a/lib-phone/src/Phone/Dialer/MainView.cpp b/lib-phone/src/Phone/Dialer/MainView.cpp
new file mode 100644 (file)
index 0000000..31e32b5
--- /dev/null
@@ -0,0 +1,382 @@
+/*
+ * 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 "Phone/Dialer/MainView.h"
+#include "Phone/Dialer/AddNumberPopup.h"
+#include "Phone/Dialer/KeypadButton.h"
+#include "Phone/Dialer/KeypadEntry.h"
+#include "Phone/Dialer/SearchResultsWidget.h"
+#include "Phone/Dialer/SpeeddialPopup.h"
+
+#include "App/AppControlRequest.h"
+#include "App/Path.h"
+#include "Ui/Menu.h"
+#include "Ui/Window.h"
+#include "Utils/Callback.h"
+#include "Utils/Logger.h"
+
+#include "CommonButtons.h"
+#include "DialerLayout.h"
+
+#include <app_control.h>
+#include <contacts.h>
+#include <feedback.h>
+
+#define KEYPAD_ROWS 4
+#define KEYPAD_COLS 3
+
+namespace
+{
+       const std::string layoutFilePath = App::getResourcePath(DIALER_LAYOUT_EDJ);
+}
+
+using namespace Phone::Dialer;
+using namespace std::placeholders;
+
+MainView::MainView()
+       : m_Entry(nullptr), m_SearchWidget(nullptr)
+{
+}
+
+MainView::~MainView()
+{
+       feedback_deinitialize();
+       contacts_db_remove_changed_cb(_contacts_contact._uri,
+                       makeCallbackWithLastParam(&MainView::onDbChanged), this);
+}
+
+void MainView::onCreated()
+{
+       feedback_initialize();
+       contacts_db_add_changed_cb(_contacts_contact._uri,
+                       makeCallbackWithLastParam(&MainView::onDbChanged), this);
+}
+
+Evas_Object *MainView::onCreate(Evas_Object *parent)
+{
+       elm_theme_extension_add(nullptr, App::getResourcePath(COMMON_BUTTONS_EDJ).c_str());
+
+       Evas_Object *layout = elm_layout_add(parent);
+       Eina_Bool res = elm_layout_file_set(layout, layoutFilePath.c_str(), GROUP_DIALER);
+       WARN_IF(res != EINA_TRUE, "elm_layout_file_set() failed");
+
+       elm_object_part_content_set(layout, PART_SWALLOW_ENTRY, createEntry(layout));
+       elm_object_part_content_set(layout, PART_SWALLOW_PREDICTIVE, createSearchWidget(layout));
+       elm_object_part_content_set(layout, PART_SWALLOW_KEYPAD, createKeypad(layout));
+       elm_object_part_content_set(layout, PART_SWALLOW_CALL, createCallButton(layout));
+       elm_object_part_content_set(layout, PART_SWALLOW_BACKSPACE, createBackspaceButton(layout));
+
+       return layout;
+}
+
+void MainView::setNumber(const std::string &number)
+{
+       if (m_Entry) {
+               m_Entry->setNumber(number);
+       }
+}
+
+void MainView::onPageAttached()
+{
+       getPage()->setTitle("IDS_KPD_ITAB3_KEYPAD");
+}
+
+void MainView::onNavigation(bool isCurrentView)
+{
+       Evas_Object *conf = getWindow()->getConformant();
+       if (isCurrentView) {
+               elm_object_signal_emit(conf, "elm,state,virtualkeypad,disable", "");
+               elm_object_signal_emit(conf, "elm,state,clipboard,disable", "");
+       } else {
+               elm_object_signal_emit(conf, "elm,state,virtualkeypad,enable", "");
+               elm_object_signal_emit(conf, "elm,state,clipboard,enable", "");
+       }
+}
+
+Evas_Object *MainView::onMenuPressed()
+{
+       Ui::Menu *menu = new Ui::Menu();
+       menu->create(getEvasObject());
+
+       if (!m_Entry->getNumber().empty()) {
+               menu->addItem("IDS_KPD_BUTTON_SEND_MESSAGE", [this] {
+                       m_AppControl = App::requestMessageComposer("sms:", m_Entry->getNumber().c_str());
+                       m_AppControl.launch();
+               });
+               menu->addItem("IDS_KPD_OPT_ADD_2_SECOND_PAUSE_ABB", [this] {
+                       m_Entry->insert(',');
+               });
+               menu->addItem("IDS_KPD_OPT_ADD_WAIT_ABB", [this] {
+                       m_Entry->insert(';');
+               });
+       }
+
+       menu->addItem("IDS_KPD_OPT_SPEED_DIAL_SETTINGS_ABB2", [this] {
+               //TODO: getNavigator()->navigateTo(new SpeeddialView());
+       });
+       menu->addItem("IDS_KPD_OPT_CALL_SETTINGS_ABB", [this] {
+               m_AppControl = App::requestCallSettings();
+               m_AppControl.launch();
+       });
+
+       return menu->getEvasObject();
+}
+
+Evas_Object *MainView::createEntry(Evas_Object *parent)
+{
+       m_Entry = new KeypadEntry();
+       m_Entry->setChangedCallback(std::bind(&MainView::onEntryChanged, this));
+       return m_Entry->create(parent);
+}
+
+Evas_Object *MainView::createSearchWidget(Evas_Object *parent)
+{
+       m_SearchWidget = new SearchResultsWidget();
+       m_SearchWidget->setSelectedCallback(std::bind(&MainView::onResultSelected, this, _1));
+       return m_SearchWidget->create(parent);
+}
+
+Evas_Object *MainView::createKeypad(Evas_Object *parent)
+{
+       Evas_Object *table = elm_table_add(parent);
+       elm_table_padding_set(table, 2, 2);
+
+       int id = 0;
+       for(int i = 0; i < KEYPAD_ROWS; ++i) {
+               for(int j = 0; j < KEYPAD_COLS; ++j, ++id) {
+                       KeypadButton *key = new KeypadButton((KeypadButton::Id) id);
+                       key->setPressedCallback(std::bind(&MainView::onKeyPressed, this, _1));
+                       key->setLongpressedCallback(std::bind(&MainView::onKeyLongpressed, this, _1));
+
+                       Evas_Object *button = key->create(table);
+                       evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+                       evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL);
+                       elm_table_pack(table, button, j, i, 1, 1);
+                       evas_object_show(button);
+               }
+       }
+
+       return table;
+}
+
+Evas_Object *MainView::createCallButton(Evas_Object *parent)
+{
+       Evas_Object *button = elm_button_add(parent);
+       elm_object_style_set(button, BUTTON_STYLE_CUSTOM_CIRCLE);
+       evas_object_smart_callback_add(button, "clicked",
+                       makeCallback(&MainView::onCallPressed), this);
+
+       Evas_Object *edje = elm_layout_edje_get(button);
+       edje_object_color_class_set(edje, BUTTON_COLOR_CLASS_NORMAL, BUTTON_CALL_NORMAL,
+                       0, 0, 0, 0, 0, 0, 0, 0);
+       edje_object_color_class_set(edje, BUTTON_COLOR_CLASS_PRESSED, BUTTON_CALL_PRESSED,
+                       0, 0, 0, 0, 0, 0, 0, 0);
+
+       Evas_Object *image = elm_image_add(button);
+       Eina_Bool res = elm_image_file_set(image, layoutFilePath.c_str(), GROUP_BUTTON_CALL);
+       WARN_IF(res != EINA_TRUE, "elm_layout_file_set() failed");
+       elm_object_part_content_set(button, "elm.swallow.content", image);
+
+       return button;
+}
+
+Evas_Object *MainView::createBackspaceButton(Evas_Object *parent)
+{
+       Ui::Button *key = new Ui::Button();
+       key->setPressedCallback(std::bind(&MainView::onBackspacePressed, this, _1));
+       key->setLongpressedCallback(std::bind(&MainView::onBackspaceLongpressed, this, _1));
+
+       Evas_Object *button = key->create(parent);
+       elm_object_style_set(button, "transparent");
+
+       Evas_Object *image = elm_image_add(button);
+       Eina_Bool res = elm_image_file_set(image, layoutFilePath.c_str(), GROUP_BUTTON_BACKSPACE);
+       WARN_IF(res != EINA_TRUE, "elm_layout_file_set() failed");
+       elm_object_part_content_set(button, "elm.swallow.content", image);
+
+       return button;
+}
+
+void MainView::onEntryChanged()
+{
+       std::string number = m_Entry->getNumber();
+       if (!number.empty()) {
+               m_SearchEngine.search(number);
+               m_SearchWidget->setResults(m_SearchEngine.getSearchResult());
+       } else {
+               m_SearchWidget->clearResults();
+       }
+}
+
+void MainView::onResultSelected(SearchResultPtr result)
+{
+       if (result) {
+               m_Entry->setNumber(result->getNumber(false));
+       } else {
+               Ui::Popup *popup = new AddNumberPopup(m_Entry->getNumber());
+               popup->create(getEvasObject());
+       }
+}
+
+void MainView::onKeyPressed(Ui::Button &button)
+{
+       KeypadButton &key = static_cast<KeypadButton &>(button);
+       m_Entry->insert(key.getValue());
+}
+
+bool MainView::onKeyLongpressed(Ui::Button &button)
+{
+       KeypadButton &key = static_cast<KeypadButton &>(button);
+       int id = key.getId();
+
+       if (m_Entry->getNumber().empty()) {
+               if (id >= KeypadButton::ID_1 && id <= KeypadButton::ID_9) {
+                       launchSpeeddial(key.getValue() - '0');
+                       return true;
+               }
+       }
+
+       if (id == KeypadButton::ID_0) {
+               m_Entry->insert('+');
+               return true;
+       }
+
+       return false;
+}
+
+void MainView::onBackspacePressed(Ui::Button &button)
+{
+       feedback_play(FEEDBACK_PATTERN_KEY_BACK);
+       m_Entry->popBack();
+}
+
+bool MainView::onBackspaceLongpressed(Ui::Button &button)
+{
+       m_Entry->clear();
+       return true;
+}
+
+void MainView::onCallPressed(Evas_Object *obj, void *event_info)
+{
+       std::string number = m_Entry->getNumber();
+       if (!number.empty()) {
+               launchCall(number);
+               m_Entry->clear();
+       } else {
+               m_Entry->setNumber(getLastNumber());
+       }
+}
+
+void MainView::onDbChanged(const char *uri)
+{
+       std::string number = m_Entry->getNumber();
+       m_SearchEngine.searchFromScratch(number);
+       m_SearchWidget->setResults(m_SearchEngine.getSearchResult());
+}
+
+void MainView::launchCall(const std::string &number)
+{
+       App::AppControl request = App::requestTelephonyCall(number.c_str());
+       request.launch(nullptr, nullptr, false);
+       request.detach();
+}
+
+void MainView::launchSpeeddial(int digit)
+{
+       std::string number = getSpeeddialNumber(digit);
+       if (!number.empty()) {
+               launchCall(number);
+       } else {
+               Ui::Popup *popup = new SpeeddialPopup(digit);
+               popup->create(getEvasObject());
+       }
+}
+
+std::string MainView::getSpeeddialNumber(int digit)
+{
+       std::string number;
+       contacts_filter_h filter = NULL;
+       contacts_query_h query = NULL;
+       contacts_list_h list = NULL;
+
+       contacts_filter_create(_contacts_speeddial._uri, &filter);
+       contacts_filter_add_int(filter, _contacts_speeddial.speeddial_number, CONTACTS_MATCH_EQUAL, digit);
+
+       contacts_query_create(_contacts_speeddial._uri, &query);
+       contacts_query_set_filter(query, filter);
+
+       int err = contacts_db_get_records_with_query(query, 0, 1, &list);
+       WARN_IF(err != CONTACTS_ERROR_NONE, "contacts_db_get_records_with_query() failed(0x%x)", err);
+       if (list) {
+               contacts_record_h record = NULL;
+               contacts_list_get_current_record_p(list, &record);
+               if (record) {
+                       char *str = NULL;
+                       contacts_record_get_str_p(record, _contacts_speeddial.number, &str);
+                       if (str) {
+                               number = str;
+                       }
+               }
+
+               contacts_list_destroy(list, true);
+       }
+
+       contacts_query_destroy(query);
+       contacts_filter_destroy(filter);
+
+       return number;
+}
+
+std::string MainView::getLastNumber()
+{
+       std::string number;
+       contacts_list_h list = NULL;
+       contacts_query_h query = NULL;
+       contacts_filter_h filter = NULL;
+
+       contacts_filter_create(_contacts_person_phone_log._uri, &filter);
+       contacts_filter_add_int(filter, _contacts_person_phone_log.log_type,
+                       CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VOICE_INCOMMING);
+       contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
+       contacts_filter_add_int(filter, _contacts_person_phone_log.log_type,
+                       CONTACTS_MATCH_LESS_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_BLOCKED);
+
+       contacts_query_create(_contacts_person_phone_log._uri, &query);
+       contacts_query_set_filter(query, filter);
+       contacts_query_set_sort(query, _contacts_person_phone_log.log_time, false);
+
+       int err = contacts_db_get_records_with_query(query, 0, 1, &list);
+       WARN_IF(err != CONTACTS_ERROR_NONE, "contacts_db_get_records_with_query() failed(0x%x)", err);
+       if (list) {
+               contacts_record_h record = NULL;
+               contacts_list_get_current_record_p(list, &record);
+               if (record) {
+                       char *str = NULL;
+                       contacts_record_get_str_p(record, _contacts_person_phone_log.address, &str);
+                       if (str) {
+                               number = str;
+                       }
+               }
+
+               contacts_list_destroy(list, true);
+       }
+
+       contacts_query_destroy(query);
+       contacts_filter_destroy(filter);
+
+       return number;
+}
diff --git a/lib-phone/src/Phone/Dialer/SearchEngine.cpp b/lib-phone/src/Phone/Dialer/SearchEngine.cpp
new file mode 100644 (file)
index 0000000..642c1fb
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * 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 "Phone/Dialer/SearchEngine.h"
+#include "Phone/Dialer/SearchUtils.h"
+#include "Contacts/Utils.h"
+#include <utility>
+#include <algorithm>
+
+using namespace Phone::Dialer;
+
+namespace
+{
+       typedef contacts_list_h (*ContactListGetter)(char digit);
+
+       ContactListGetter contactListGetters[] = {
+               Utils::getSpeedDial,
+               Utils::getLogList,
+               Utils::getContactListByName,
+               Utils::getContactListByNumber
+       };
+}
+
+SearchEngine::SearchEngine()
+       : m_LastFoundIndex(-1)
+{}
+
+void SearchEngine::search(const std::string &number)
+{
+       if (number.empty()) {
+               clear();
+       } else {
+               chooseSearch(number);
+       }
+
+       m_Number = number;
+}
+
+const SearchResults *SearchEngine::getSearchResult() const
+{
+       if (!m_Cache.empty()) {
+               return &m_Cache.back();
+       }
+
+       return nullptr;
+}
+
+bool SearchEngine::empty() const
+{
+       return m_Cache.empty() || m_Cache.back().empty();
+}
+
+void SearchEngine::distinctLogs(SearchResults &searchList)
+{
+       auto logPred = [](SearchResultPtr pSearchInfo) {
+               return pSearchInfo->getType() == ResultLog;
+       };
+
+       auto logComp = [](SearchResultPtr lhs, SearchResultPtr rhs) {
+               return lhs->getSearchString() < rhs->getSearchString();
+       };
+
+       auto eqPred = [](SearchResultPtr lhs, SearchResultPtr rhs) {
+               return lhs->getSearchString() == rhs->getSearchString();
+       };
+
+       SearchResults::iterator beg = std::find_if(searchList.begin(), searchList.end(), logPred);
+       SearchResults::iterator end = std::find_if_not(beg, searchList.end(), logPred);
+
+       if (beg != end) {
+               std::sort(beg, end, logComp);
+               SearchResults::iterator itForErase = std::unique(beg, end, eqPred);
+
+               searchList.erase(itForErase, end);
+       }
+}
+
+void SearchEngine::firstSearch(const std::string &number)
+{
+       clear();
+
+       SearchResults searchList = searchInDB(number);
+
+       if (!searchList.empty()) {
+               distinctLogs(searchList);
+
+               m_Cache.resize(number.size());
+               m_Cache.front() = std::move(searchList);
+               m_LastFoundIndex = 0;
+
+               if (number.size() > 1) {
+                       if (!searchInCache(m_Cache.begin(), number)) {
+                               clear();
+                       }
+               }
+       }
+}
+
+SearchResults SearchEngine::searchInDB(const std::string &number)
+{
+       SearchResults searchList;
+       contacts_record_h record = NULL;
+
+       for (int i = ResultSpeeddial; i < ResultMax; ++i) {
+               contacts_list_h list = contactListGetters[i](number.front());
+               CONTACTS_LIST_FOREACH(list, record) {
+                       SearchResult searchInfo((ResultType)i, record);
+                       if (searchInfo.getType() != ResultNone) {
+                               size_t position = searchInfo.getSearchString().find(number);
+                               if (position != std::string::npos) {
+                                       searchInfo.updateHighlightText(number, position);
+                               }
+                               searchList.push_back(std::make_shared<SearchResult>(std::move(searchInfo)));
+                       }
+               }
+               contacts_list_destroy(list, true);
+       }
+
+       return searchList;
+}
+
+void SearchEngine::chooseSearch(const std::string &number)
+{
+       if (m_Number.empty()) {
+               firstSearch(number);
+       }
+
+       if (!needSearch(number)) {
+               return;
+       }
+
+       m_Cache.resize(number.size());
+       auto rIt = firstMismatch(number);
+       if (rIt == m_Cache.rend()) {//Perform initial search
+               firstSearch(number);
+       } else {
+               searchInCache(rIt.base() - 1, number);
+       }
+}
+
+bool SearchEngine::searchInCache(SearchHistory::iterator from, const std::string &number)
+{
+       SearchResults searchRes;
+       for (SearchResultPtr &sInfo : *from) {
+               if (sInfo) {
+                       size_t position = sInfo->getSearchString().find(number);
+                       if (position != std::string::npos) {
+                               sInfo->updateHighlightText(number, position);
+                               searchRes.push_back(sInfo);
+                       }
+               }
+       }
+
+       if (!searchRes.empty()) {
+               m_LastFoundIndex = m_Cache.size() - 1;
+               m_Cache.back() = std::move(searchRes);
+               return true;
+       } else {
+               return false;
+       }
+}
+
+SearchHistory::reverse_iterator SearchEngine::firstMismatch(const std::string &number)
+{
+       size_t minSize = std::min(m_Number.size(), number.size());
+       auto itPair = std::mismatch(m_Number.begin(), m_Number.begin() + minSize, number.begin());
+
+       auto rIt = skipEmptyResults(itPair.first - m_Number.begin());
+       return rIt;
+}
+
+SearchHistory::reverse_iterator SearchEngine::skipEmptyResults(size_t offset)
+{
+       auto rIt = std::reverse_iterator<SearchHistory::iterator>(m_Cache.begin() + offset);
+
+       while (rIt != m_Cache.rend() && rIt->empty()) {
+               ++rIt;
+       }
+
+       return rIt;
+}
+
+void SearchEngine::clear()
+{
+       m_Cache.clear();
+       m_LastFoundIndex = -1;
+}
+
+bool SearchEngine::needSearch(const std::string &number)
+{
+       if (number.size() >= m_Number.size()
+               &&(int)(m_Cache.size() - 1) > m_LastFoundIndex) {
+               return false;
+       }
+       return true;
+}
+
+void SearchEngine::searchFromScratch(const std::string &number)
+{
+       if (number.empty()) {
+               clear();
+       } else {
+               firstSearch(number);
+       }
+
+       m_Number = number;
+}
diff --git a/lib-phone/src/Phone/Dialer/SearchResult.cpp b/lib-phone/src/Phone/Dialer/SearchResult.cpp
new file mode 100644 (file)
index 0000000..4a284ad
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * 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 "Phone/Dialer/SearchResult.h"
+#include "Phone/Dialer/SearchUtils.h"
+
+using namespace Phone::Dialer;
+using namespace Phone::Dialer::Utils;
+
+SearchResult::SearchResult(ResultType type, const contacts_record_h record)
+       : m_Type(type), m_Id(0), m_SpeedDialId(0)
+{
+       if (record) {
+               if (!fillWithRecord(type, record)) {
+                       m_Type = ResultNone;
+               }
+       }
+}
+
+std::string SearchResult::getSearchString() const
+{
+       switch (m_Type) {
+               case ResultSpeeddial:
+                       return std::string(1, (m_SpeedDialId + '0'));
+               case ResultLog:
+               case ResultNumber:
+                       return m_Number;
+               case ResultName:
+                       return m_MaskedName;
+               case ResultNone:
+               case ResultMax:
+               default:
+                       return "";
+       }
+}
+
+ResultType SearchResult::getType() const
+{
+       return m_Type;
+}
+
+int SearchResult::getId() const
+{
+       return m_Id;
+}
+
+int SearchResult::getSpeedDialId() const
+{
+       return m_SpeedDialId;
+}
+
+const std::string &SearchResult::getName(bool isHighlighted) const
+{
+       bool returnHighlight = isHighlighted && (m_Type == ResultName) && !m_HighlightedText.empty();
+       return returnHighlight ? m_HighlightedText : m_Name;
+}
+
+const std::string &SearchResult::getNumber(bool isHighlighted) const
+{
+       bool returnHighlight = isHighlighted && ((m_Type == ResultLog) || (m_Type == ResultNumber)) && !m_HighlightedText.empty();
+       return returnHighlight ? m_HighlightedText : m_Number;
+}
+
+const std::string &SearchResult::getHighlightedText() const
+{
+       return m_HighlightedText;
+}
+
+bool SearchResult::updateHighlightText(const std::string searchStr, size_t position)
+{
+       switch(m_Type)
+       {
+               case ResultLog:
+               case ResultNumber:
+                       m_HighlightedText = Utils::highlightTextByPos(m_Number, position, searchStr.size());
+                       return true;
+               case ResultName:
+                       m_HighlightedText = Utils::highlightTextByPos(m_Name, position, searchStr.size());
+                       return true;
+               case ResultNone:
+               case ResultSpeeddial:
+               case ResultMax:
+               default:
+                       return false;
+       }
+}
+
+bool SearchResult::fillWithRecord(ResultType type, const contacts_record_h record)
+{
+       switch(type)
+       {
+               case ResultSpeeddial:
+                       fillSpeedDial(record);
+                       return true;
+               case ResultLog:
+                       fillLog(record);
+                       return true;
+               case ResultName:
+               case ResultNumber:
+                       fillContact(type, record);
+                       return true;
+               case ResultNone:
+               case ResultMax:
+               default:
+                       return false;
+       }
+}
+
+void SearchResult::fillSpeedDial(const contacts_record_h record)
+{
+       char *tempStr = NULL;
+
+       contacts_record_get_int(record, _contacts_speeddial.person_id, &m_Id);
+       contacts_record_get_int(record, _contacts_speeddial.speeddial_number, &m_SpeedDialId);
+       contacts_record_get_str_p(record, _contacts_speeddial.number, &tempStr);
+       m_Number = tempStr;
+       contacts_record_get_str_p(record, _contacts_speeddial.display_name, &tempStr);
+       m_Name = tempStr;
+}
+
+void SearchResult::fillLog(const contacts_record_h record)
+{
+       char *tempStr = NULL;
+
+       contacts_record_get_int(record, _contacts_phone_log.person_id, &m_Id);
+       contacts_record_get_str_p(record, _contacts_phone_log.address, &tempStr);
+       m_Number = tempStr;
+}
+
+void SearchResult::fillContact(ResultType type, const contacts_record_h record)
+{
+       char *tempStr = NULL;
+
+       contacts_record_get_int(record, _contacts_contact_number.contact_id, &m_Id);
+       contacts_record_get_str_p(record, _contacts_contact_number.display_name, &tempStr);
+       m_Name = tempStr;
+       contacts_record_get_str_p(record, _contacts_contact_number.number, &tempStr);
+       m_Number = tempStr;
+       if(type == ResultName) {
+               m_MaskedName = Utils::contactNameToMask(m_Name);
+       }
+}
diff --git a/lib-phone/src/Phone/Dialer/SearchResultsPopup.cpp b/lib-phone/src/Phone/Dialer/SearchResultsPopup.cpp
new file mode 100644 (file)
index 0000000..44ef4e9
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * 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 "Phone/Dialer/SearchResultsPopup.h"
+#include "Phone/Dialer/SearchUtils.h"
+#include "Phone/Dialer/KeypadEntry.h"
+#include "Utils/Callback.h"
+#include "Utils/Logger.h"
+
+#include "DialerLayout.h"
+
+#include <app_i18n.h>
+
+using namespace Phone::Dialer;
+
+SearchResultsPopup::SearchResultsPopup(const SearchResults *results)
+       : m_Results(results)
+{
+}
+
+void SearchResultsPopup::setSelectedCallback(SelectedCallback callback)
+{
+       m_OnSelected = std::move(callback);
+}
+
+void SearchResultsPopup::onCreated()
+{
+       Evas_Object *popup = getEvasObject();
+       elm_object_style_set(popup, "theme_bg");
+       elm_popup_orient_set(popup, ELM_POPUP_ORIENT_CENTER);
+
+       const size_t bufferSize = 32;
+       char buffer[bufferSize];
+       snprintf(buffer, bufferSize, _("IDS_KPD_HEADER_SEARCH_RESULTS_HPD_ABB"), m_Results->size());
+
+       setTitle(buffer);
+       setContent(createContactList(popup));
+}
+
+Evas_Object *SearchResultsPopup::createContactList(Evas_Object *parent)
+{
+       Evas_Object *genlist = elm_genlist_add(parent);
+       elm_genlist_homogeneous_set(genlist, EINA_TRUE);
+       elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
+       elm_scroller_content_min_limit(genlist, EINA_FALSE, EINA_TRUE);
+       evas_object_smart_callback_add(genlist, "selected",
+                       makeCallback(&SearchResultsPopup::onItemSelected), this);
+
+       Elm_Genlist_Item_Class *itc = createItemClass();
+
+       for (auto &&info : *m_Results) {
+               elm_genlist_item_append(genlist, itc, &info, nullptr,
+                               ELM_GENLIST_ITEM_NONE, nullptr, nullptr);
+       }
+
+       elm_genlist_item_class_free(itc);
+       return genlist;
+}
+
+Elm_Genlist_Item_Class *SearchResultsPopup::createItemClass()
+{
+       Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
+       RETVM_IF(!itc, NULL, "elm_genlist_item_class_new() failed");
+       itc->item_style = "type1";
+       itc->func.text_get = getItemText;
+       itc->func.content_get = getItemContent;
+       return itc;
+}
+
+char *SearchResultsPopup::getItemText(void *data, Evas_Object *obj, const char *part)
+{
+       SearchResultPtr info = *(SearchResultPtr *)data;
+       const std::string &name = info->getName(true);
+       const std::string &number = info->getNumber(true);
+
+       if (!strcmp(part, "elm.text")) {
+               return strdup(name.empty() ? number.c_str() : name.c_str());
+       } else if (!strcmp(part, "elm.text.sub")) {
+               if (!name.empty()) {
+                       return strdup(number.c_str());
+               }
+       }
+
+       return nullptr;
+}
+
+Evas_Object *SearchResultsPopup::getItemContent(void *data, Evas_Object *obj, const char *part)
+{
+       SearchResultPtr info = *(SearchResultPtr *)data;
+       if (!strcmp(part, "elm.swallow.icon")) {
+               return Utils::createThumbnail(obj, info->getId());
+       }
+
+       return nullptr;
+}
+
+void SearchResultsPopup::onItemSelected(Evas_Object *obj, void *event_info)
+{
+       elm_genlist_item_selected_set((Elm_Object_Item *)event_info, EINA_FALSE);
+
+       SearchResultPtr info = *(SearchResultPtr *)elm_object_item_data_get((Elm_Object_Item *)event_info);
+       if (m_OnSelected) {
+               m_OnSelected(info);
+       }
+
+       delete this;
+}
diff --git a/lib-phone/src/Phone/Dialer/SearchResultsWidget.cpp b/lib-phone/src/Phone/Dialer/SearchResultsWidget.cpp
new file mode 100644 (file)
index 0000000..e693e26
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * 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 "Phone/Dialer/SearchResultsWidget.h"
+#include "Phone/Dialer/SearchResultsPopup.h"
+#include "Phone/Dialer/SearchUtils.h"
+
+#include "App/Path.h"
+#include "Utils/Callback.h"
+#include "Utils/Logger.h"
+
+#include "DialerLayout.h"
+
+using namespace Phone::Dialer;
+
+namespace
+{
+       const std::string layoutFilePath = App::getResourcePath(DIALER_PREDICTIVE_EDJ);
+}
+
+SearchResultsWidget::SearchResultsWidget()
+       : m_Results(nullptr), m_State(ResultsNone),
+         m_ResultsCount(nullptr)
+{
+}
+
+void SearchResultsWidget::setResults(const SearchResults *results)
+{
+       m_Results = results;
+       if (!m_Results || m_Results->empty()) {
+               setResultsEmpty();
+       } else {
+               setResultsPresent();
+               setResultsCount(m_Results->size());
+       }
+}
+
+void SearchResultsWidget::clearResults()
+{
+       setLayout(nullptr);
+       m_State = ResultsNone;
+       m_Results = nullptr;
+}
+
+void SearchResultsWidget::setSelectedCallback(SelectedCallback callback)
+{
+       m_OnSelected = std::move(callback);
+}
+
+Evas_Object *SearchResultsWidget::onCreate(Evas_Object *parent)
+{
+       Evas_Object *layout = elm_layout_add(parent);
+       evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_DOWN,
+                       (Evas_Object_Event_Cb) makeCallback(&SearchResultsWidget::onResultPressed), this);
+       return layout;
+}
+
+void SearchResultsWidget::setLayout(const char *groupName)
+{
+       clearLayout();
+       elm_layout_file_set(getEvasObject(), layoutFilePath.c_str(), groupName);
+}
+
+void SearchResultsWidget::clearLayout()
+{
+       Eina_List *list = elm_layout_content_swallow_list_get(getEvasObject());
+       Eina_List *node = nullptr;
+       void *obj = nullptr;
+       EINA_LIST_FOREACH(list, node, obj) {
+               evas_object_del((Evas_Object *) obj);
+       }
+
+       eina_list_free(list);
+}
+
+void SearchResultsWidget::setResultsEmpty()
+{
+       if (m_State != ResultsEmpty) {
+               m_State = ResultsEmpty;
+               setLayout(GROUP_PREDICTIVE_NO_RESULTS);
+               elm_object_translatable_part_text_set(getEvasObject(), PART_TEXT_ADD, "IDS_KPD_BUTTON_ADD_TO_CONTACTS_ABB2");
+       }
+}
+
+void SearchResultsWidget::setResultsPresent()
+{
+       if (m_State != ResultsPresent && m_State != ResultsMany) {
+               m_State = ResultsPresent;
+               setLayout(GROUP_PREDICTIVE);
+       }
+
+       setResultInfo(m_Results->front());
+}
+
+void SearchResultsWidget::setResultsCount(size_t count)
+{
+       if (count > 1) {
+               if (m_State != ResultsMany) {
+                       m_State = ResultsMany;
+
+                       m_ResultsCount = elm_layout_add(getEvasObject());
+                       elm_layout_file_set(m_ResultsCount, layoutFilePath.c_str(), GROUP_PREDICTIVE_RES_COUNT);
+                       evas_object_propagate_events_set(m_ResultsCount, EINA_FALSE);
+                       evas_object_event_callback_add(m_ResultsCount, EVAS_CALLBACK_MOUSE_DOWN,
+                                       (Evas_Object_Event_Cb) makeCallback(&SearchResultsWidget::onShowResultsPressed), this);
+               }
+
+               elm_object_part_text_set(m_ResultsCount, PART_TEXT_COUNT,
+                               std::to_string(count).c_str());
+       } else {
+               m_ResultsCount = nullptr;
+               m_State = ResultsPresent;
+       }
+
+       elm_object_part_content_set(getEvasObject(), PART_SWALLOW_RESULTS, m_ResultsCount);
+}
+
+void SearchResultsWidget::setResultInfo(SearchResultPtr result)
+{
+       Evas_Object *layout = getEvasObject();
+       elm_object_part_content_set(layout, PART_SWALLOW_THUMBNAIL,
+                       Utils::createThumbnail(layout, result->getId()));
+
+       if (result->getName(false).empty()) {
+               elm_object_part_text_set(layout, PART_TEXT_1_LINE, result->getNumber(true).c_str());
+               elm_object_part_text_set(layout, PART_TEXT_NAME, "");
+               elm_object_part_text_set(layout, PART_TEXT_NUMBER, "");
+       } else {
+               elm_object_part_text_set(layout, PART_TEXT_1_LINE, "");
+               elm_object_part_text_set(layout, PART_TEXT_NAME, result->getName(true).c_str());
+               elm_object_part_text_set(layout, PART_TEXT_NUMBER, result->getNumber(true).c_str());
+       }
+
+       if (result->getType() == ResultSpeeddial) {
+               setResultSpeeddial(result);
+               elm_object_signal_emit(getEvasObject(), "show,speeddial,icon", "");
+       } else {
+               elm_object_signal_emit(getEvasObject(), "hide,speeddial,icon", "");
+       }
+}
+
+void SearchResultsWidget::setResultSpeeddial(SearchResultPtr result)
+{
+       Evas_Object *speeddialLayout = elm_layout_add(getEvasObject());
+       elm_layout_file_set(speeddialLayout, layoutFilePath.c_str(), GROUP_SPEEDDIAL_NUMBER);
+       elm_object_part_text_set(speeddialLayout, PART_TEXT_NUMBER, result->getSearchString().c_str());
+       elm_object_part_content_set(getEvasObject(), PART_SWALLOW_SPEEDDIAL, speeddialLayout);
+}
+
+void SearchResultsWidget::onResultPressed()
+{
+       TRACE;
+       if (m_OnSelected) {
+               if (m_Results && !m_Results->empty()) {
+                       m_OnSelected(m_Results->front());
+               } else {
+                       m_OnSelected(nullptr);
+               }
+       }
+}
+
+void SearchResultsWidget::onShowResultsPressed()
+{
+       TRACE;
+       SearchResultsPopup *popup = new SearchResultsPopup(m_Results);
+       popup->setSelectedCallback(m_OnSelected);
+       popup->create(getEvasObject());
+}
diff --git a/lib-phone/src/Phone/Dialer/SearchUtils.cpp b/lib-phone/src/Phone/Dialer/SearchUtils.cpp
new file mode 100644 (file)
index 0000000..325315f
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * 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 "Phone/Dialer/SearchUtils.h"
+#include "Contacts/Utils.h"
+#include "Ui/Thumbnail.h"
+#include "Utils/Logger.h"
+
+using namespace Phone::Dialer;
+using namespace Phone::Dialer::Utils;
+
+#define TAG_MATCH_PREFIX "<match>"
+#define TAG_MATCH_SUFFIX "</match>"
+
+namespace
+{
+       const char *mask[] = {
+               "+", "", "abc", "def",
+               "ghi", "jkl", "mno",
+               "pqrs", "tuv", "wxyz"
+       };
+
+       char getDigit(char c)
+       {
+               static const char hash[] = "22233344455566677778889999";
+
+               if (c == '+') {
+                       return '0';
+               }
+
+               size_t index = tolower(c) - 'a';
+               if (index >= sizeof(hash) - 1) {
+                       return '\0';
+               }
+
+               return hash[index];
+       }
+
+       std::string getDigitMask(char digit)
+       {
+               if (digit > '9' || digit < '0') {
+                       ERR("getDigitMask expected digit(0-9) argument, but %c is provided", digit);
+                       return "";
+               }
+
+               int index = digit - '0';
+               return mask[index];
+       }
+
+       contacts_filter_h createContactNameFilters(char digit)
+       {
+               std::string mask = getDigitMask(digit);
+               if (mask.empty()) {
+                       return NULL;
+               }
+
+               contacts_filter_h filter = NULL;
+               contacts_filter_create(_contacts_contact_number._uri, &filter);
+               bool isFirst = true;
+               for (auto &x : mask) {
+                       if (!isFirst) {
+                               contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_OR);
+                       }
+
+                       char str[] = { x, '\0' };
+                       contacts_filter_add_str(filter, _contacts_contact_number.display_name, CONTACTS_MATCH_CONTAINS, str);
+                       isFirst = false;
+               }
+               return filter;
+       }
+
+       contacts_list_h runQuery(const char *tableUri, contacts_filter_h filter)
+       {
+               contacts_list_h list = NULL;
+               contacts_query_h query = NULL;
+
+               contacts_query_create(tableUri, &query);
+               contacts_query_set_filter(query, filter);
+
+               contacts_db_get_records_with_query(query, 0, 0, &list);
+
+               contacts_query_destroy(query);
+               contacts_filter_destroy(filter);
+
+               return list;
+       }
+
+       std::string getThumbnail(int id)
+       {
+               std::string path;
+               contacts_record_h record = NULL;
+               if (contacts_db_get_record(_contacts_contact._uri, id, &record) == CONTACTS_ERROR_NONE) {
+                       char *imgPath = NULL;
+                       contacts_record_get_str_p(record, _contacts_contact.image_thumbnail_path, &imgPath);
+                       if (imgPath) {
+                               path = imgPath;
+                       }
+                       contacts_record_destroy(record, true);
+               }
+               return path;
+       }
+}
+
+contacts_list_h Phone::Dialer::Utils::getSpeedDial(char number)
+{
+       contacts_filter_h filter = NULL;
+       contacts_filter_create(_contacts_speeddial._uri, &filter);
+       contacts_filter_add_int(filter, _contacts_speeddial.speeddial_number, CONTACTS_MATCH_EQUAL, number - '0');
+
+       contacts_list_h list = runQuery(_contacts_speeddial._uri, filter);
+
+       return list;
+}
+
+contacts_list_h Phone::Dialer::Utils::getLogList(char digit)
+{
+       char number[] = { digit, '\0' };
+       contacts_filter_h filter = NULL;
+       contacts_filter_create(_contacts_phone_log._uri, &filter);
+
+       contacts_filter_add_str(filter, _contacts_phone_log.address, CONTACTS_MATCH_CONTAINS, number);
+       contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
+       contacts_filter_add_int(filter, _contacts_phone_log.log_type,
+                       CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VOICE_INCOMMING);
+       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);
+
+       contacts_list_h list = runQuery(_contacts_phone_log._uri, filter);
+
+       contacts_list_h retList = NULL;
+       contacts_list_create(&retList);
+       contacts_record_h record = NULL;
+       CONTACTS_LIST_FOREACH(list, record) {
+               int personId = 0;
+               contacts_record_get_int(record, _contacts_phone_log.person_id, &personId);
+               if (personId == 0) {
+                       contacts_list_add(retList, record);
+               } else {
+                       contacts_record_destroy(record, true);
+               }
+       }
+       contacts_list_destroy(list, false);
+
+       return retList;
+}
+
+contacts_list_h Phone::Dialer::Utils::getContactListByName(char digit)
+{
+       contacts_query_h query = NULL;
+       contacts_list_h list = NULL;
+       contacts_query_create(_contacts_contact_number._uri, &query);
+       contacts_filter_h filter = createContactNameFilters(digit);
+       if (filter) {
+               contacts_query_set_filter(query, filter);
+               contacts_db_get_records_with_query(query, 0, 0, &list);
+       }
+
+       contacts_filter_destroy(filter);
+       contacts_query_destroy(query);
+       return list;
+}
+
+contacts_list_h Phone::Dialer::Utils::getContactListByNumber(char digit)
+{
+       char number[] = { digit, '\0' };
+       contacts_filter_h filter = NULL;
+       contacts_filter_create(_contacts_contact_number._uri, &filter);
+       contacts_filter_add_str(filter, _contacts_contact_number.number, CONTACTS_MATCH_CONTAINS, number);
+
+       contacts_list_h list = runQuery(_contacts_contact_number._uri, filter);
+
+       return list;
+}
+
+std::string Phone::Dialer::Utils::contactNameToMask(const std::string &name)
+{
+       std::string number;
+       number.reserve(name.size());
+
+       for (auto &x : name) {
+               char digit = getDigit(x);
+               if (digit == '\0') {
+                       break;
+               }
+               number.push_back(digit);
+       }
+       return number;
+}
+
+std::string Phone::Dialer::Utils::highlightTextByPos(std::string &text, size_t position, size_t length)
+{
+       std::string highlightText = text;
+       size_t endPos = position + length + sizeof(TAG_MATCH_PREFIX) - 1;
+
+       highlightText.insert(position, TAG_MATCH_PREFIX);
+       highlightText.insert(endPos, TAG_MATCH_SUFFIX);
+
+       return highlightText;
+}
+
+Evas_Object *Phone::Dialer::Utils::createThumbnail(Evas_Object *parent, int contactId)
+{
+       Ui::Thumbnail *thumbnail = Ui::Thumbnail::create(parent,
+                       Ui::Thumbnail::SizeSmall, getThumbnail(contactId).c_str());
+
+       return thumbnail->getEvasObject();
+}
diff --git a/lib-phone/src/Phone/Dialer/SpeeddialPopup.cpp b/lib-phone/src/Phone/Dialer/SpeeddialPopup.cpp
new file mode 100644 (file)
index 0000000..6716dcd
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * 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 "Phone/Dialer/SpeeddialPopup.h"
+#include "App/AppControlRequest.h"
+#include "Phone/Utils.h"
+#include "Utils/Logger.h"
+
+#include <contacts.h>
+#include <notification.h>
+
+using namespace Phone::Dialer;
+
+SpeeddialPopup::SpeeddialPopup(int speedNumber)
+       : m_SpeedNumber(speedNumber)
+{
+}
+
+void SpeeddialPopup::onCreated()
+{
+       setTitle("IDS_KPD_HEADER_ASSIGN_AS_SPEED_DIAL_NUMBER_ABB");
+       setText("IDS_KPD_POP_THERE_IS_NO_CONTACT_ASSIGNED_TO_THIS_SPEED_DIAL_NUMBER_TAP_OK_TO_ASSIGN_ONE_NOW");
+
+       using namespace std::placeholders;
+       addButton("IDS_LOGS_BUTTON_CANCEL_ABB3");
+       addButton("IDS_PB_BUTTON_OK_ABB2", std::bind(&SpeeddialPopup::onOkPressed, this));
+}
+
+bool SpeeddialPopup::onOkPressed()
+{
+       App::AppControl request = App::requestContactPick(APP_CONTROL_SELECT_SINGLE,
+                       APP_CONTROL_RESULT_PHONE);
+
+       int err = request.launch(&SpeeddialPopup::onPickResult, this);
+       RETVM_IF(err != APP_CONTROL_ERROR_NONE, true, "launchContactPick() failed(0x%x)", err);
+
+       request.detach();
+       return false;
+}
+
+void SpeeddialPopup::onPickResult(app_control_h request, app_control_h reply,
+               app_control_result_e result, void *data)
+{
+       SpeeddialPopup *popup = (SpeeddialPopup*) data;
+
+       char **numberIds = 0;
+       int count = 0;
+
+       int err = app_control_get_extra_data_array(reply, APP_CONTROL_DATA_SELECTED, &numberIds, &count);
+       RETM_IF(err != APP_CONTROL_ERROR_NONE, "app_control_get_extra_data() failed(0x%x)", err);
+
+       if (numberIds && numberIds[0]) {
+               int numberId = atoi(numberIds[0]);
+               if (numberId > 0) {
+                       if (Phone::addSpeedDialNumber(popup->m_SpeedNumber, numberId)) {
+                               notification_status_message_post(_("IDS_KPD_TPOP_SPEED_DIAL_NUMBER_ASSIGNED"));
+                       } else {
+                               notification_status_message_post(_("IDS_PB_POP_ALREADY_EXISTS_LC"));
+                       }
+               }
+       }
+
+       for (int i = 0; i < count; ++i) {
+               free(numberIds[i]);
+       }
+       free(numberIds);
+
+       delete popup;
+}
diff --git a/lib-phone/src/Phone/Utils.cpp b/lib-phone/src/Phone/Utils.cpp
new file mode 100644 (file)
index 0000000..6c9329f
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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 "Phone/Utils.h"
+#include "Utils/Logger.h"
+
+#include <contacts.h>
+
+bool Phone::addSpeedDialNumber(int speedNumber, int numberId)
+{
+       contacts_filter_h filter = nullptr;
+       contacts_filter_create(_contacts_speeddial._uri, &filter);
+       contacts_filter_add_int(filter, _contacts_speeddial.number_id, CONTACTS_MATCH_EQUAL, numberId);
+
+       contacts_query_h query = nullptr;
+       contacts_query_create(_contacts_speeddial._uri, &query);
+       contacts_query_set_filter(query, filter);
+
+       contacts_list_h list = nullptr;
+       int err = contacts_db_get_records_with_query(query, 0, 1, &list);
+       contacts_query_destroy(query);
+       contacts_filter_destroy(filter);
+       RETVM_IF(err != CONTACTS_ERROR_NONE, false, "contacts_db_get_records_with_query() failed(%d)", err);
+
+       int count = 0;
+       contacts_list_get_count(list, &count);
+       contacts_list_destroy(list, true);
+       if (count > 0) {
+               return false;
+       }
+
+       contacts_record_h record = nullptr;
+       contacts_record_create(_contacts_speeddial._uri, &record);
+       contacts_record_set_int(record, _contacts_speeddial.speeddial_number, speedNumber);
+       contacts_record_set_int(record, _contacts_speeddial.number_id, numberId);
+       err = contacts_db_insert_record(record, nullptr);
+       contacts_record_destroy(record, true);
+       RETVM_IF(err != CONTACTS_ERROR_NONE, false, "contacts_db_insert_record() failed(%d)", err);
+
+       return true;
+}
index 3ecd919..2d107fb 100644 (file)
@@ -1,14 +1,18 @@
 cmake_minimum_required(VERSION 2.6)
-project(contacts C CXX)
+project(contacts CXX)
 
-file(GLOB_RECURSE SOURCES src/*.c src/*.cpp)
+file(GLOB_RECURSE SOURCES src/*.cpp)
 include_directories(
        ${CMAKE_SOURCE_DIR}/lib-common/inc
+       ${CMAKE_SOURCE_DIR}/lib-phone/inc
        ${CMAKE_CURRENT_SOURCE_DIR}/inc
 )
 
 add_executable(${PROJECT_NAME} ${SOURCES})
-target_link_libraries(${PROJECT_NAME} ${LIBRARIES} common -pie)
+target_link_libraries(${PROJECT_NAME} ${LIBRARIES} -pie
+       common
+       phone
+)
 
 install(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR})
 
index c9f63b2..7ee91d3 100644 (file)
@@ -18,6 +18,7 @@
 #include "OperationDefaultController.h"
 
 #include "MainApp.h"
+#include "Phone/Dialer/MainView.h"
 #include "Ui/TabView.h"
 
 #include <app_preference.h>
@@ -45,8 +46,8 @@ void OperationDefaultController::onCreate()
        m_Navigator = new Ui::TabView();
        mainNavigator->navigateTo(m_Navigator);
 
+       m_Tabs[TabDialer] = new Phone::Dialer::MainView();
        /* TODO:
-       m_Tabs[TabDialer] = new Phone::DialerView();
        m_Tabs[TabLogs] = new Phone::Logs::ListView();
        m_Tabs[TabContacts] = new Contacts::ListView();
         */
@@ -63,11 +64,8 @@ void OperationDefaultController::onRequest(Operation operation, app_control_h re
 
        TabId selectedTab = TabContacts;
        if (operation == OPERATION_DIAL) {
-               /* TODO:
-               Phone::DialerView *dialer = static_cast<Phone::DialerView *>(m_Tabs[TabDialer]);
+               auto dialer = static_cast<Phone::Dialer::MainView *>(m_Tabs[TabDialer]);
                dialer->setNumber(getPhoneNumber(request));
-                */
-
                selectedTab = TabDialer;
        } else if (appId && strcmp(appId, APP_CONTROL_PHONE_APPID) == 0) {
                if (getBadgeCount(APP_CONTROL_PHONE_APPID) > 0) {
index 0c4ddb0..56c8e5f 100644 (file)
        </ui-application>
        <privileges>
                <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+               <privilege>http://tizen.org/privilege/call</privilege>
+               <privilege>http://tizen.org/privilege/callhistory.read</privilege>
                <privilege>http://tizen.org/privilege/contact.read</privilege>
                <privilege>http://tizen.org/privilege/contact.write</privilege>
+               <privilege>http://tizen.org/privilege/notification</privilege>
        </privileges>
 </manifest>
index 11b5358..bc65c0f 100644 (file)
@@ -17,6 +17,8 @@ BuildRequires: pkgconfig(contacts-service2)
 BuildRequires: pkgconfig(dlog)
 BuildRequires: pkgconfig(efl-extension)
 BuildRequires: pkgconfig(elementary)
+BuildRequires: pkgconfig(feedback)
+BuildRequires: pkgconfig(notification)
 
 %description
 Contacts and Phone Reference Applications.