From a9cdd2b98abcbe7cd3f42d6b8aea5250c8c55a8e Mon Sep 17 00:00:00 2001 From: hyunho Date: Tue, 3 Sep 2019 15:20:24 +0900 Subject: [PATCH] Add multi-language feature Change-Id: Ie0bc02ea2c352469348d077f6143f25cb03687ad Signed-off-by: hyunho --- notification-ex/CMakeLists.txt | 2 + notification-ex/abstract_item.cc | 45 ++++ notification-ex/abstract_item.h | 6 + notification-ex/abstract_item_implementation.h | 2 + notification-ex/api/notification_ex.h | 1 + notification-ex/api/notification_ex_button.h | 39 +++ notification-ex/api/notification_ex_checkbox.h | 40 +++ notification-ex/api/notification_ex_entry.h | 38 +++ .../api/notification_ex_input_selector.h | 37 +++ .../api/notification_ex_multi_language.h | 107 ++++++++ notification-ex/api/notification_ex_text.h | 42 +++ notification-ex/ex_util.cc | 74 ++++++ notification-ex/ex_util.h | 3 + notification-ex/multi_language.cc | 121 +++++++++ notification-ex/multi_language.h | 58 ++++ notification-ex/multi_language_implementation.h | 53 ++++ notification-ex/stub.cc | 296 +++++++++++++++++---- 17 files changed, 911 insertions(+), 53 deletions(-) create mode 100644 notification-ex/api/notification_ex_multi_language.h create mode 100644 notification-ex/multi_language.cc create mode 100644 notification-ex/multi_language.h create mode 100644 notification-ex/multi_language_implementation.h diff --git a/notification-ex/CMakeLists.txt b/notification-ex/CMakeLists.txt index 7e53f43..0d8cc10 100644 --- a/notification-ex/CMakeLists.txt +++ b/notification-ex/CMakeLists.txt @@ -16,6 +16,8 @@ pkg_check_modules(notification-ex REQUIRED dlog capi-appfw-app-control capi-appfw-app-common + capi-appfw-package-manager + pkgmgr-info aul uuid ) diff --git a/notification-ex/abstract_item.cc b/notification-ex/abstract_item.cc index ff25fd5..375fe0e 100644 --- a/notification-ex/abstract_item.cc +++ b/notification-ex/abstract_item.cc @@ -26,6 +26,7 @@ #include "notification-ex/abstract_item.h" #include "notification-ex/abstract_item_implementation.h" #include "notification-ex/item_info_internal.h" +#include "notification-ex/multi_language.h" #include "notification-ex/ex_util.h" #include "notification-ex/action_inflator.h" #include "notification-ex/factory_manager.h" @@ -82,6 +83,8 @@ #define ABSTRACT_ITEM_TRUE "TRUE" #define ABSTRACT_ITEM_ONGOING_KEY "__ABSTRACT_ITEM_ONGOING_KEY__" #define ABSTRACT_ITEM_MAIN_TYPE_KEY "__ABSTRACT_ITEM_MAIN_TYPE_KEY__" +#define ABSTRACT_ITEM_MULTI_LANG_ARR_KEY "__ABSTRACT_ITEM_MULTI_LANG_ARR_KEY__" +#define ABSTRACT_ITEM_MULTI_LANG_KEY "__ABSTRACT_ITEM_MULTI_LANG_KEY__" using namespace std; using namespace tizen_base; @@ -254,6 +257,19 @@ Bundle AbstractItem::Serialize() const { reinterpret_cast(impl_->action_->Serialize().ToRaw().first.get())); } + if (impl_->multi_lang_ != nullptr) { + b.Add(ABSTRACT_ITEM_MULTI_LANG_KEY, + reinterpret_cast(impl_->multi_lang_->Serialize().ToRaw().first.get())); + } + + if (impl_->multi_lang_arr_.size() > 0) { + vector arr; + for (auto& i : impl_->multi_lang_arr_) { + arr.push_back(reinterpret_cast(i->Serialize().ToRaw().first.get())); + } + b.Add(ABSTRACT_ITEM_MULTI_LANG_ARR_KEY, arr); + } + if (impl_->hide_viewer_list_.size() != 0) { vector arr; @@ -376,6 +392,18 @@ void AbstractItem::Deserialize(Bundle b) { if (!action_str.empty()) impl_->action_ = ActionInflator::Create(Bundle(action_str)); + string multi_str = b.GetString(ABSTRACT_ITEM_MULTI_LANG_KEY); + if (!multi_str.empty()) + impl_->multi_lang_ = shared_ptr(new MultiLanguage(multi_str)); + + vector multi_arr_str = b.GetStringArray(ABSTRACT_ITEM_MULTI_LANG_ARR_KEY); + if (!multi_arr_str.empty()) { + for (string str : multi_arr_str) { + impl_->multi_lang_arr_.push_back( + shared_ptr(new MultiLanguage(str))); + } + } + vector hide_viewer = b.GetStringArray(ABSTRACT_ITEM_HIDE_VIEWER_KEY); if (hide_viewer.size() != 0) { for (string str : hide_viewer) { @@ -575,5 +603,22 @@ AbstractItem& AbstractItem::FindByMainType(AbstractItem::MainType type) { return FactoryManager::GetInst().GetNullItem(); } +std::shared_ptr AbstractItem::GetMultiLanguage() const { + return impl_->multi_lang_; +} + +vector> AbstractItem::GetMultiLanguageArr() const { + return impl_->multi_lang_arr_; +} + +void AbstractItem::SetMultiLanguage(std::shared_ptr multi) { + impl_->multi_lang_ = multi; +} + +void AbstractItem::SetMultiLanguage( + vector> multi_arr) { + impl_->multi_lang_arr_ = multi_arr; +} + } // namespace item } // namespace notification diff --git a/notification-ex/abstract_item.h b/notification-ex/abstract_item.h index 872cabc..223ba2a 100644 --- a/notification-ex/abstract_item.h +++ b/notification-ex/abstract_item.h @@ -25,6 +25,7 @@ #include #include "notification-ex/abstract_action.h" +#include "notification-ex/multi_language.h" #include "notification-ex/iitem_info.h" #ifndef EXPORT_API @@ -834,6 +835,11 @@ class EXPORT_API AbstractItem { */ void SetId(std::string id); + std::vector> GetMultiLanguageArr() const; + std::shared_ptr GetMultiLanguage() const; + void SetMultiLanguage(std::shared_ptr multi); + void SetMultiLanguage(std::vector> multi_arr); + /** * @brief Gets AbstractAction for notification item. * @since_tizen 5.5 diff --git a/notification-ex/abstract_item_implementation.h b/notification-ex/abstract_item_implementation.h index e6a4a64..29dc0bd 100644 --- a/notification-ex/abstract_item_implementation.h +++ b/notification-ex/abstract_item_implementation.h @@ -55,6 +55,8 @@ class AbstractItem::Impl { std::list receiver_group_list_; std::string can_receive_; std::shared_ptr action_; + std::shared_ptr multi_lang_; + std::vector> multi_lang_arr_; AbstractItem* parent_; std::string sound_path_; std::string vibration_path_; diff --git a/notification-ex/api/notification_ex.h b/notification-ex/api/notification_ex.h index b793f35..97278a6 100644 --- a/notification-ex/api/notification_ex.h +++ b/notification-ex/api/notification_ex.h @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/notification-ex/api/notification_ex_button.h b/notification-ex/api/notification_ex_button.h index 490a69c..0d8d8de 100644 --- a/notification-ex/api/notification_ex_button.h +++ b/notification-ex/api/notification_ex_button.h @@ -18,6 +18,7 @@ #define __TIZEN_APPFW_NOTIFICATION_EX_BUTTON_H__ #include +#include #ifdef __cplusplus extern "C" { @@ -63,6 +64,8 @@ int noti_ex_item_button_create(noti_ex_item_h *handle, const char *id, const cha * @brief Gets the title of a button item. * @since_tizen 5.5 * @remarks @a title must be released using free(). + * @remarks If the multi-language handle is set by noti_ex_item_button_set_multi_language_title(), \n + * it will return a multi-language title. * @param[in] handle The notification_ex item handle * @param[out] title The title of notification_ex item * @return #NOTI_EX_ERROR_NONE On success, other value on failure @@ -70,6 +73,7 @@ int noti_ex_item_button_create(noti_ex_item_h *handle, const char *id, const cha * @retval #NOTI_EX_ERROR_INVALID_PARAMETER Invalid parameter, if the item type is not correct, this error is returned * @see #noti_ex_item_h * @see noti_ex_item_button_create() + * @see noti_ex_item_button_set_multi_language_title() * @par Sample code: * @code #include @@ -85,6 +89,41 @@ int noti_ex_item_button_create(noti_ex_item_h *handle, const char *id, const cha int noti_ex_item_button_get_title(noti_ex_item_h handle, char **title); /** + * @brief Sets the multi-language handle. + * @since_tizen 5.5 + * @remarks After the multi-language handle setted successfully, noti_ex_item_button_get_title() \n + * will return the multi-language text. + * @remarks The #noti_ex_item_h handle keeps its own copy of #noti_ex_multi_lang_h. \n + * Therefore, you can destroy @ multi after it was set for @ handle. + * @remarks You can pass NULL to @a multi, if you want to remove multi-language text. + * @param[in] handle The notification_ex button item handle + * @param[in] multi The multi-language handle + * @return #NOTI_EX_ERROR_NONE On success, other value on failure + * @retval #NOTI_EX_ERROR_NONE Success + * @retval #NOTI_EX_ERROR_INVALID_PARAMETER Invalid parameter, if the item type is not correct, this error is returned + * @see #noti_ex_item_h + * @see noti_ex_item_button_create() + * @see noti_ex_multi_lang_create() + * @par Sample code: + * @code +#include + +{ + int ret; + noti_ex_item_h button_item = NULL; + noti_ex_multi_lang_h multi; + + ret = noti_ex_item_button_create(&button_item, "button_id", "button_title"); + ret = noti_ex_multi_lang_create(&multi, "_IDS_NOTI_TEST_", "Hi %d I'm %s", 33, "test"); + ret = noti_ex_item_button_set_multi_language_title(button_item, multi); + noti_ex_multi_lang_destroy(multi); +} + * @endcode + */ +int noti_ex_item_button_set_multi_language_title(noti_ex_item_h handle, + noti_ex_multi_lang_h multi); + +/** * @} */ diff --git a/notification-ex/api/notification_ex_checkbox.h b/notification-ex/api/notification_ex_checkbox.h index 9943f25..d5e4ea6 100644 --- a/notification-ex/api/notification_ex_checkbox.h +++ b/notification-ex/api/notification_ex_checkbox.h @@ -18,6 +18,7 @@ #define __TIZEN_APPFW_NOTIFICATION_EX_CHECKBOX_H__ #include +#include #ifdef __cplusplus extern "C" { @@ -64,6 +65,8 @@ int noti_ex_item_checkbox_create(noti_ex_item_h *handle, const char *id, const c * @brief Gets the title of a checkbox. * @since_tizen 5.5 * @remarks @a title must be released using free(). + * @remarks If the multi-language handle is set by noti_ex_item_checkbox_set_multi_language_title(), \n + * it will return a multi-language title. * @param[in] handle The notification_ex item handle * @param[out] title The title of notification_ex item * @return #NOTI_EX_ERROR_NONE On success, other value on failure @@ -71,6 +74,7 @@ int noti_ex_item_checkbox_create(noti_ex_item_h *handle, const char *id, const c * @retval #NOTI_EX_ERROR_INVALID_PARAMETER Invalid parameter, if the item type is not correct, this error is returned * @see #noti_ex_item_h * @see noti_ex_item_checkbox_create() + * @see noti_ex_item_checkbox_set_multi_language_title() * @par Sample code: * @code #include @@ -86,6 +90,42 @@ int noti_ex_item_checkbox_create(noti_ex_item_h *handle, const char *id, const c int noti_ex_item_checkbox_get_title(noti_ex_item_h handle, char **title); /** + * @brief Sets the multi-language handle. + * @since_tizen 5.5 + * @remarks After the multi-language handle setted successfully, \n + * noti_ex_item_checkbox_get_title() will return the multi-language text. + * @remarks The #noti_ex_item_h handle keeps its own copy of #noti_ex_multi_lang_h. \n + * Therefore, you can destroy @ multi after it was set for @ handle. + * @remarks You can pass NULL to @a multi, if you want to remove the multi-language text. + * @param[in] handle The notification_ex item handle + * @param[in] multi The multi-language handle + * @return #NOTI_EX_ERROR_NONE On success, other value on failure + * @retval #NOTI_EX_ERROR_NONE Success + * @retval #NOTI_EX_ERROR_INVALID_PARAMETER Invalid parameter, if the item type is not correct, this error is returned + * @see #noti_ex_item_h + * @see noti_ex_item_checkbox_create() + * @see noti_ex_item_checkbox_get_title() + * @see noti_ex_multi_lang_create() + * @par Sample code: + * @code +#include + +{ + int ret; + noti_ex_item_h checkbox_item = NULL; + noti_ex_multi_lang_h multi; + + ret = noti_ex_item_checkbox_create(&checkbox_item, "checkbox_id", "checkbox_title", false); + ret = noti_ex_multi_lang_create(&multi, "_IDS_NOTI_TEST_", "Hi %d I'm %s", 33, "test"); + ret = noti_ex_item_checkbox_set_multi_language_title(checkbox_item, multi); + noti_ex_multi_lang_destroy(multi); +} + * @endcode + */ +int noti_ex_item_checkbox_set_multi_language_title(noti_ex_item_h handle, + noti_ex_multi_lang_h multi); + +/** * @brief Gets the check state of a checkbox. * @since_tizen 5.5 * @param[in] handle The notification_ex item handle diff --git a/notification-ex/api/notification_ex_entry.h b/notification-ex/api/notification_ex_entry.h index a02b364..821e420 100644 --- a/notification-ex/api/notification_ex_entry.h +++ b/notification-ex/api/notification_ex_entry.h @@ -62,6 +62,8 @@ int noti_ex_item_entry_create(noti_ex_item_h *handle, const char *id); * @brief Gets the text of an entry item. * @since_tizen 5.5 * @remarks @a text must be released using free(). + * @remarks If the multi-language handle is set by \n + * noti_ex_item_entry_set_multi_language(), it will return a multi-language text. * @param[in] handle The notification_ex item handle * @param[out] text The text of entry item * @return #NOTI_EX_ERROR_NONE On success, other value on failure @@ -69,6 +71,7 @@ int noti_ex_item_entry_create(noti_ex_item_h *handle, const char *id); * @retval #NOTI_EX_ERROR_INVALID_PARAMETER Invalid parameter, if the item type is not correct, this error is returned * @see #noti_ex_item_h * @see noti_ex_item_entry_create() + * @see noti_ex_item_entry_set_multi_language() * @par Sample code: * @code #include @@ -107,6 +110,41 @@ int noti_ex_item_entry_get_text(noti_ex_item_h handle, char **text); int noti_ex_item_entry_set_text(noti_ex_item_h handle, const char *text); /** + * @brief Sets the multi-language handle. + * @since_tizen 5.5 + * @remarks After the multi-language handle setted successfully, \n + * noti_ex_item_entry_get_text() will return the multi-language text. \n + * @remarks The #noti_ex_item_h handle keeps its own copy of #noti_ex_multi_lang_h. \n + * Therefore, you can destroy @ multi after it was set for @ handle. + * @remarks You can pass NULL to @a multi, if you want to remove the multi-language text. + * @param[in] handle The notification_ex item handle + * @param[in] multi The multi-language handle + * @return #NOTI_EX_ERROR_NONE On success, other value on failure + * @retval #NOTI_EX_ERROR_NONE Success + * @retval #NOTI_EX_ERROR_INVALID_PARAMETER Invalid parameter, if the item type is not correct, this error is returned + * @see #noti_ex_item_h + * @see noti_ex_item_text_create() + * @see noti_ex_item_text_set_multi_language() + * @see noti_ex_item_text_get_contents() + * @par Sample code: + * @code +#include + +{ + int ret; + noti_ex_item_h entry_item = NULL; + noti_ex_multi_lang_h multi; + + ret = noti_ex_item_entry_create(&entry_item, "entry_id"); + ret = noti_ex_item_entry_set_multi_language(entry_item, multi); + noti_ex_multi_lang_destroy(multi); +} + * @endcode + */ +int noti_ex_item_entry_set_multi_language(noti_ex_item_h handle, + noti_ex_multi_lang_h multi); + +/** * @} */ diff --git a/notification-ex/api/notification_ex_input_selector.h b/notification-ex/api/notification_ex_input_selector.h index bfe525b..a536c44 100644 --- a/notification-ex/api/notification_ex_input_selector.h +++ b/notification-ex/api/notification_ex_input_selector.h @@ -18,6 +18,7 @@ #define __TIZEN_APPFW_NOTIFICATION_EX_INPUT_SELECTOR_H__ #include +#include #ifdef __cplusplus extern "C" { @@ -62,6 +63,8 @@ int noti_ex_item_input_selector_create(noti_ex_item_h *handle, const char *id); * @brief Gets the contents that can be selected by input selector. * @since_tizen 5.5 * @remarks Each item in the @a list must be released using free(), then the @a list must be released using free(). + * @remarks If the multi-language handle is set by noti_ex_item_input_selector_set_multi_language_contents(), \n + * it will return a multi-language contents. * @param[in] handle The notification_ex item handle * @param[out] list The list of contents * @param[out] count The count of contents @@ -71,6 +74,7 @@ int noti_ex_item_input_selector_create(noti_ex_item_h *handle, const char *id); * @see #noti_ex_item_h * @see noti_ex_item_input_selector_create() * @see noti_ex_item_input_selector_set_contents() + * @see noti_ex_item_input_selector_set_multi_language_contents() * @par Sample code: * @code #include @@ -113,6 +117,39 @@ int noti_ex_item_input_selector_get_contents(noti_ex_item_h handle, char ***list int noti_ex_item_input_selector_set_contents(noti_ex_item_h handle, const char **contents, int count); /** + * @brief Sets the multi-language contents for input selector item. + * @since_tizen 5.5 + * @remarks After the multi-language handle setted successfully, \n + * noti_ex_item_input_selector_get_contents() will return the multi-language text. \n + * @remarks The #noti_ex_item_h handle keeps its own copy of #noti_ex_multi_lang_h list. \n + * Therefore, you can destroy @ multi_language_list after it was set for @ handle. + * @remarks You can pass NULL to @a multi_language_list, if you want to remove the multi-language text. + * @param[in] handle The notification_ex item handle + * @param[in] multi_language_list The list of noti_ex_multi_lang_h + * @param[in] count The count of contents + * @return #NOTI_EX_ERROR_NONE On success, other value on failure + * @retval #NOTI_EX_ERROR_NONE Success + * @retval #NOTI_EX_ERROR_INVALID_PARAMETER Invalid parameter + * @see #noti_ex_item_h + * @see noti_ex_item_input_selector_create() + * @see noti_ex_item_input_selector_get_contents() + * @par Sample code: + * @code +#include + +{ + int ret; + noti_ex_multi_lang_h *contents[] = {multi1, multi2, multi3}; + int count = 3; + + ret = noti_ex_item_input_selector_set_multi_language_contents(selector_item, contents, count); +} + * @endcode + */ +int noti_ex_item_input_selector_set_multi_language_contents( + noti_ex_item_h handle, noti_ex_multi_lang_h *multi_language_list, int count); + +/** * @} */ diff --git a/notification-ex/api/notification_ex_multi_language.h b/notification-ex/api/notification_ex_multi_language.h new file mode 100644 index 0000000..dad8240 --- /dev/null +++ b/notification-ex/api/notification_ex_multi_language.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * 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 __TIZEN_APPFW_NOTIFICATION_EX_MULTI_LANGUAGE_H__ +#define __TIZEN_APPFW_NOTIFICATION_EX_MULTI_LANGUAGE_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup NOTIFICATION_EX_ITEM + * @{ + */ + +/** + * @brief The notification_ex multi-language item handle. + * @since_tizen 5.5 + */ +typedef void *noti_ex_multi_lang_h; + +/** + * @brief Creates the multi-language item handle. + * @since_tizen 5.5 + * @remarks @a handle must be released using noti_ex_multi_lang_destroy(). + * @param[out] handle The multi-language item handle + * @param[in] msgid The identifier of the message to be translated. One of the identifers declared in PO files. \n + * The message of @a msgid and @a format must contain the same specifiers and in the same order. + * @param[in] format The string that contains the text to be written. \n + * It can optionally contain embedded format specifiers \n + * that are replaced by the values specified in subsequent additional arguments and formatted as requested. \n + * Valid specifiers are as follows. \n + * %d : Signed decimal integer \n + * %f : Decimal floating point \n + * %s : String of characters + * @param[in] ... The additional arguments. The values to be used to replace format specifiers in the format string. + * @return #NOTI_EX_ERROR_NONE On success, other value on failure + * @retval #NOTI_EX_ERROR_NONE Success + * @retval #NOTI_EX_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #NOTI_EX_ERROR_OUT_OF_MEMORY out of memory + * @see #noti_ex_multi_lang_h + * @see noti_ex_multi_lang_destroy() + * @par Sample code: + * @code +#include + +{ + int ret; + noti_ex_multi_lang_h handle = NULL; + + // _IDS_TEST_ : "Hi %s version %f" + ret = noti_ex_multi_lang_create(&handle, "_IDS_TEST_", "Hi %s version %f", "Tizen", 5.5); + noti_ex_multi_lang_destroy(handle); +} + * @endcode + */ +int noti_ex_multi_lang_create(noti_ex_multi_lang_h *handle, + const char *msgid, const char *format, ...); + +/** + * @brief Destroys the multi-language item handle. + * @since_tizen 5.5 + * @param[in] handle The multi-language item handle + * @return #NOTI_EX_ERROR_NONE On success, other value on failure + * @retval #NOTI_EX_ERROR_NONE Success + * @retval #NOTI_EX_ERROR_INVALID_PARAMETER Invalid parameter + * @see #noti_ex_multi_lang_h + * @see noti_ex_multi_lang_create() + * @par Sample code: + * @code +#include + +{ + int ret; + noti_ex_multi_lang_h handle = NULL; + + // _IDS_TEST_ : "Hi %s version %f" + ret = noti_ex_multi_lang_create(&handle, "_IDS_TEST_", "Hi %s version %f", "Tizen", 5.5); + noti_ex_multi_lang_destroy(handle); +} + * @endcode + */ +int noti_ex_multi_lang_destroy(noti_ex_multi_lang_h handle); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif +#endif /* __TIZEN_APPFW_NOTIFICATION_EX_MULTI_LANGUAGE_H__ */ diff --git a/notification-ex/api/notification_ex_text.h b/notification-ex/api/notification_ex_text.h index 0faef9d..a2307d6 100644 --- a/notification-ex/api/notification_ex_text.h +++ b/notification-ex/api/notification_ex_text.h @@ -18,6 +18,7 @@ #define __TIZEN_APPFW_NOTIFICATION_EX_TEXT_H__ #include +#include #ifdef __cplusplus extern "C" { @@ -63,6 +64,8 @@ int noti_ex_item_text_create(noti_ex_item_h *handle, const char *id, const char /** * @brief Sets the text contents of the text item. * @since_tizen 5.5 + * @remarks If the multi-language handle is set by noti_ex_item_text_set_multi_language(), \n + * it will return a multi-language content. * @param[in] handle The notification_ex item handle * @param[in] contents The text contents * @return #NOTI_EX_ERROR_NONE On success, other value on failure @@ -87,6 +90,8 @@ int noti_ex_item_text_set_contents(noti_ex_item_h handle, const char *contents); * @brief Gets the text contents of the text item. * @since_tizen 5.5 * @remarks @a contents must be released using free(). + * @remarks If the multi-language handle is set by noti_ex_item_text_set_multi_language(), \n + * it will return a multi-language content. * @param[in] handle The notification_ex item handle * @param[out] contents The text contents * @return #NOTI_EX_ERROR_NONE On success, other value on failure @@ -94,6 +99,7 @@ int noti_ex_item_text_set_contents(noti_ex_item_h handle, const char *contents); * @retval #NOTI_EX_ERROR_INVALID_PARAMETER Invalid parameter, if the item type is not correct, this error is returned * @see #noti_ex_item_h * @see noti_ex_item_text_create() + * @see noti_ex_item_text_set_multi_language() * @par Sample code: * @code #include @@ -134,6 +140,42 @@ int noti_ex_item_text_get_contents(noti_ex_item_h handle, char **contents); int noti_ex_item_text_get_hyperlink(noti_ex_item_h handle, char **hyperlink); /** + * @brief Sets the multi-language handle. + * @since_tizen 5.5 + * @remarks After the multi-language handle setted successfully, \n + * noti_ex_item_text_get_contents() will return the multi-language text. \n + * @remarks The #noti_ex_item_h handle keeps its own copy of #noti_ex_multi_lang_h. \n + * Therefore, you can destroy @ multi after it was set for @ handle. + * @remarks You can pass NULL to @a multi, if you want to remove the multi-language text. + * @param[in] handle The notification_ex item handle + * @param[in] multi The multi-language handle + * @return #NOTI_EX_ERROR_NONE On success, other value on failure + * @retval #NOTI_EX_ERROR_NONE Success + * @retval #NOTI_EX_ERROR_INVALID_PARAMETER Invalid parameter, if the item type is not correct, this error is returned + * @see #noti_ex_item_h + * @see noti_ex_item_text_create() + * @see noti_ex_multi_lang_create() + * @see noti_ex_item_text_get_contents() + * @par Sample code: + * @code +#include + +{ + int ret; + noti_ex_item_h text_item = NULL; + noti_ex_multi_lang_h multi; + + ret = noti_ex_item_text_create(&text_item, "text_id", "text", "hyperlink"); + ret = noti_ex_multi_lang_create(&multi, "_IDS_NOTI_TEST_", "Hi %d I'm %s", 33, "test"); + ret = noti_ex_item_text_set_multi_language(text_item, multi); + noti_ex_multi_lang_destroy(multi); +} + * @endcode + */ +int noti_ex_item_text_set_multi_language(noti_ex_item_h handle, + noti_ex_multi_lang_h multi); + +/** * @} */ diff --git a/notification-ex/ex_util.cc b/notification-ex/ex_util.cc index 975a6ee..d1bcda8 100644 --- a/notification-ex/ex_util.cc +++ b/notification-ex/ex_util.cc @@ -18,8 +18,11 @@ #include #include #include +#include +#include #include +#include #include "notification-ex/ex_util.h" @@ -101,5 +104,76 @@ string GetAppId() { return appid; } +string GetPkgId() { + static string pkgid = ""; + if (!pkgid.empty()) { + LOGI("pkgid(%s)", pkgid.c_str()); + return pkgid; + } + + char pkgid_buf[MAX_PACKAGE_STR_SIZE] = {0, }; + int ret = aul_app_get_pkgid_bypid(getpid(), pkgid_buf, sizeof(pkgid_buf)); + if (ret == AUL_R_OK) + pkgid = string(pkgid_buf); + + return pkgid; +} + +string GetDomainName() { + static string domain_str = ""; + if (!domain_str.empty()) { + LOGI("domain(%s)", domain_str.c_str()); + return domain_str; + } + + string pkgid = GetPkgId(); + if (pkgid.empty()) + return ""; + + string::size_type pos = pkgid.rfind('.'); + if (pos != string::npos) + ++pos; + else + return ""; + + domain_str = pkgid.substr(pos); + return domain_str; +} + +string GetLocaleDirectory() { + string pkgid = GetPkgId(); + if (pkgid.empty()) + return ""; + + static string locale_directory = ""; + if (!locale_directory.empty()) { + LOGI("locale_directory(%s)", locale_directory.c_str()); + return locale_directory; + } + + package_info_h package_info; + int err = package_info_create(pkgid.c_str(), &package_info); + if (err != PACKAGE_MANAGER_ERROR_NONE) { + LOGE("fail to get package info"); + return ""; + } + unique_ptr pkg_ptr( + package_info, package_info_destroy); + + char* app_root_path; + err = package_info_get_root_path(pkg_ptr.get(), &app_root_path); + if (err != PACKAGE_MANAGER_ERROR_NONE) { + LOGE("Failed to get root path err[%d] path[%p]", + err, app_root_path); + return ""; + } + + string app_root_str(app_root_path); + free(app_root_path); + + locale_directory = app_root_str + string("/res/locale"); + return locale_directory; +} + } // namespace util } // namespace notification diff --git a/notification-ex/ex_util.h b/notification-ex/ex_util.h index 958a348..4920be2 100644 --- a/notification-ex/ex_util.h +++ b/notification-ex/ex_util.h @@ -27,6 +27,9 @@ namespace util { GQuark GetQuarkFromString(std::string str); std::string GetQuarkToString(GQuark quark); int GetRequestId(); + std::string GetPkgId(); + std::string GetDomainName(); + std::string GetLocaleDirectory(); } // namespace util } // namespace notification diff --git a/notification-ex/multi_language.cc b/notification-ex/multi_language.cc new file mode 100644 index 0000000..0d08c2b --- /dev/null +++ b/notification-ex/multi_language.cc @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * 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 +#include +#include + +#include + +#include "notification-ex/ex_util.h" +#include "notification-ex/multi_language.h" +#include "notification-ex/multi_language_implementation.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "NOTIFICATION_EX" +#define MULTI_LANGUAGE_MSG_ID_KEY "__MULTI_LANGUAGE_MSG_ID_KEY__" +#define MULTI_LANGUAGE_FORMAT_KEY "__MULTI_LANGUAGE_FORMAT_KEY__" +#define MULTI_LANGUAGE_ARGS_KEY "__MULTI_LANGUAGE_ARGS_KEY__" +#define MULTI_LANGUAGE_TRANSLATED_KEY "__MULTI_LANGUAGE_TRANSLATED_KEY__" + +using namespace std; +using namespace tizen_base; + +namespace notification { +namespace item { + +MultiLanguage::MultiLanguage(string msgid, string format, + vector args) + : impl_(new Impl(msgid, format, args, this)) { +} + +MultiLanguage::MultiLanguage(string serialized) + : impl_(new Impl("", "", this)) { + Bundle b(serialized); + Deserialize(b); +} + +MultiLanguage::~MultiLanguage() = default; +MultiLanguage::Impl::~Impl() = default; + +MultiLanguage::Impl::Impl(string msgid, string format, vector args, + MultiLanguage* parent) + : msgid_(msgid), format_(format), args_(args), parent_(parent) { + LOGI("MultiLanguage impl created"); +} + +MultiLanguage::Impl::Impl(string msgid, string format, + MultiLanguage* parent) + : msgid_(msgid), format_(format), parent_(parent) { + LOGI("MultiLanguage impl created"); +} + +Bundle MultiLanguage::Serialize() const { + Bundle b; + b.Add(MULTI_LANGUAGE_MSG_ID_KEY, impl_->msgid_); + b.Add(MULTI_LANGUAGE_FORMAT_KEY, impl_->format_); + b.Add(MULTI_LANGUAGE_ARGS_KEY, impl_->args_); + b.Add(MULTI_LANGUAGE_TRANSLATED_KEY, impl_->translated_); + return b; +} + +void MultiLanguage::Deserialize(Bundle b) { + impl_->msgid_ = b.GetString(MULTI_LANGUAGE_MSG_ID_KEY); + impl_->format_ = b.GetString(MULTI_LANGUAGE_FORMAT_KEY); + impl_->args_ = b.GetStringArray(MULTI_LANGUAGE_ARGS_KEY); + impl_->translated_ = b.GetString(MULTI_LANGUAGE_TRANSLATED_KEY); +} + +void MultiLanguage::UpdateString() { + UpdateString(util::GetDomainName(), util::GetLocaleDirectory()); +} + +void MultiLanguage::UpdateString(string domain, string locale_directory) { + bindtextdomain(domain.c_str(), locale_directory.c_str()); + char* ret_str = dgettext(domain.c_str(), impl_->msgid_.c_str()); + string base_str = impl_->format_; + + LOGI("ret str(%s)", ret_str); + if (ret_str != nullptr && (strcmp(ret_str, impl_->msgid_.c_str()) != 0)) { + base_str = string(ret_str); + } + + LOGI("base str(%s)", base_str.c_str()); + int arg_pos = 0; + for (string::iterator it = base_str.begin(); *it; ++it) { + if (*it != '%') + continue; + char next_ch = *(it + 1); + if (next_ch != 'd' && next_ch != 'f' && next_ch != 's') + continue; + + size_t pos = base_str.find("%" + string(1, next_ch)); + base_str = base_str.replace(pos, 2, impl_->args_[arg_pos]); + arg_pos++; + } + impl_->translated_ = base_str; + LOGI("translated(%s)", impl_->translated_.c_str()); +} + +string MultiLanguage::GetTranslatedString() { + return impl_->translated_; +} + +} // namespace item +} // namespace notification \ No newline at end of file diff --git a/notification-ex/multi_language.h b/notification-ex/multi_language.h new file mode 100644 index 0000000..0916a1f --- /dev/null +++ b/notification-ex/multi_language.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * 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 NOTIFICATION_EX_MULTI_LANGUAGE_H_ +#define NOTIFICATION_EX_MULTI_LANGUAGE_H_ + +#include +#include +#include + +#include + +#ifndef EXPORT_API +#define EXPORT_API __attribute__((visibility("default"))) +#endif + +namespace notification { +namespace item { + +/** + * @brief The class for MultiLanguage type notification. + * @details The class to make the notification with multi language. + * @since_tizen 5.5 + */ +class EXPORT_API MultiLanguage { + public: + MultiLanguage(std::string msgid, std::string format, + std::vector args); + MultiLanguage(std::string serialized); + virtual ~MultiLanguage(); + tizen_base::Bundle Serialize() const; + void Deserialize(tizen_base::Bundle b); + void UpdateString(std::string domain, std::string locale_directory); + void UpdateString(); + std::string GetTranslatedString(); + + private: + class Impl; + std::unique_ptr impl_; +}; // class MultiLanguage + +} // namespace item +} // namespace notification + +#endif // NOTIFICATION_EX_MULTI_LANGUAGE_H_ diff --git a/notification-ex/multi_language_implementation.h b/notification-ex/multi_language_implementation.h new file mode 100644 index 0000000..70be1b2 --- /dev/null +++ b/notification-ex/multi_language_implementation.h @@ -0,0 +1,53 @@ + + +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * + * 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 NOTIFICATION_EX_MULTI_LANGUAGE_IMPLEMENTATION_H_ +#define NOTIFICATION_EX_MULTI_LANGUAGE_IMPLEMENTATION_H_ + +#include +#include +#include + +#include "notification-ex/multi_language.h" + +namespace notification { +namespace item { + +class MultiLanguage::Impl { + public: + virtual ~Impl(); + + private: + Impl(std::string msgid, std::string format, std::vector args, + MultiLanguage* parent); + Impl(std::string msgid, std::string format, MultiLanguage* parent); + + private: + friend class MultiLanguage; + + std::string msgid_; + std::string format_; + std::vector args_; + std::string translated_; + MultiLanguage* parent_; +}; + +} // namespace item +} // namespace notification + +#endif // NOTIFICATION_EX_MULTI_LANGUAGE_IMPLEMENTATION_H_ diff --git a/notification-ex/stub.cc b/notification-ex/stub.cc index 34007ef..74627cc 100644 --- a/notification-ex/stub.cc +++ b/notification-ex/stub.cc @@ -19,6 +19,8 @@ #include #include +#include +#include #include "api/notification_ex_app_control_action.h" #include "api/notification_ex_button.h" @@ -389,18 +391,52 @@ extern "C" EXPORT_API int noti_ex_item_button_get_title(noti_ex_item_h handle, LOGE("Invalid handle type"); return NOTI_EX_ERROR_INVALID_PARAMETER; } + ButtonItem* p = static_cast(sp->Get()); - if (!p->GetTitle().empty()) { - *title = strdup(p->GetTitle().c_str()); - if (*title == nullptr) { - LOGE("Out-of-memory"); - return NOTI_EX_ERROR_OUT_OF_MEMORY; - } + string str; + if (p->GetMultiLanguage() != nullptr && + !p->GetMultiLanguage()->GetTranslatedString().empty()) + str = p->GetMultiLanguage()->GetTranslatedString(); + else if (!p->GetTitle().empty()) + str = p->GetTitle(); + + *title = strdup(str.c_str()); + if (*title == nullptr) { + LOGE("Out-of-memory"); + return NOTI_EX_ERROR_OUT_OF_MEMORY; } return NOTI_EX_ERROR_NONE; } +extern "C" EXPORT_API int noti_ex_item_button_set_multi_language_title( + noti_ex_item_h handle, noti_ex_multi_lang_h multi) { + if (handle == nullptr) { + LOGE("Invalid parameter"); + return NOTI_EX_ERROR_INVALID_PARAMETER; + } + + Handle* p = static_cast(handle); + if (!p->IsValidType(AbstractItem::Button)) { + LOGE("Invalid handle type"); + return NOTI_EX_ERROR_INVALID_PARAMETER; + } + + ButtonItem* bi = static_cast(p->Get()); + if (multi == nullptr) { + bi->SetMultiLanguage(nullptr); + return NOTI_EX_ERROR_NONE; + } + + shared_ptr mul_ptr = + *reinterpret_cast*>(multi); + + mul_ptr->UpdateString(); + bi->SetMultiLanguage(mul_ptr); + + return NOTI_EX_ERROR_NONE; +} + extern "C" EXPORT_API int noti_ex_item_chat_message_create( noti_ex_item_h *handle, const char *id, noti_ex_item_h name, noti_ex_item_h text, noti_ex_item_h image, noti_ex_item_h time, @@ -546,67 +582,64 @@ extern "C" EXPORT_API int noti_ex_item_checkbox_get_title(noti_ex_item_h handle, LOGE("Invalid handle type"); return NOTI_EX_ERROR_INVALID_PARAMETER; } + CheckBoxItem* p = static_cast(h->Get()); - if (!p->GetTitle().empty()) { - *title = strdup(p->GetTitle().c_str()); - if (*title == nullptr) { - LOGE("Out-of-memory"); - return NOTI_EX_ERROR_OUT_OF_MEMORY; - } + string str; + if (p->GetMultiLanguage() != nullptr && + !p->GetMultiLanguage()->GetTranslatedString().empty()) + str = p->GetMultiLanguage()->GetTranslatedString(); + else if (!p->GetTitle().empty()) + str = p->GetTitle(); + + *title = strdup(str.c_str()); + if (*title == nullptr) { + LOGE("Out-of-memory"); + return NOTI_EX_ERROR_OUT_OF_MEMORY; } return NOTI_EX_ERROR_NONE; } -extern "C" EXPORT_API int noti_ex_item_checkbox_is_checked( - noti_ex_item_h handle, bool *checked) { - if (handle == nullptr || checked == nullptr) { +extern "C" EXPORT_API int noti_ex_item_checkbox_set_multi_language_title( + noti_ex_item_h handle, noti_ex_multi_lang_h multi) { + if (handle == nullptr || multi == nullptr) { LOGE("Invalid parameter"); return NOTI_EX_ERROR_INVALID_PARAMETER; } - Handle* h = static_cast(handle); - if (!h->IsValidType(AbstractItem::CheckBox)) { + + Handle* p = static_cast(handle); + if (!p->IsValidType(AbstractItem::CheckBox)) { LOGE("Invalid handle type"); return NOTI_EX_ERROR_INVALID_PARAMETER; } - CheckBoxItem* p = static_cast(h->Get()); - *checked = p->IsChecked(); - return NOTI_EX_ERROR_NONE; -} - -extern "C" EXPORT_API int noti_ex_item_checkbox_get_check_state( - noti_ex_item_h handle, bool *checked) { - if (handle == nullptr || checked == nullptr) { - LOGE("Invalid parameter"); - return NOTI_EX_ERROR_INVALID_PARAMETER; - } - Handle* h = static_cast(handle); - if (!h->IsValidType(AbstractItem::CheckBox)) { - LOGE("Invalid handle type"); - return NOTI_EX_ERROR_INVALID_PARAMETER; + CheckBoxItem* ci = static_cast(p->Get()); + if (multi == nullptr) { + ci->SetMultiLanguage(nullptr); + return NOTI_EX_ERROR_NONE; } - CheckBoxItem* p = static_cast(h->Get()); - *checked = p->IsChecked(); + + shared_ptr mul_ptr = + *reinterpret_cast*>(multi); + mul_ptr->UpdateString(); + ci->SetMultiLanguage(mul_ptr); return NOTI_EX_ERROR_NONE; } -extern "C" EXPORT_API int noti_ex_item_checkbox_set_check_state( - noti_ex_item_h handle, bool checked) { - if (handle == nullptr) { +extern "C" EXPORT_API int noti_ex_item_checkbox_is_checked(noti_ex_item_h handle, + bool *checked) { + if (handle == nullptr || checked == nullptr) { LOGE("Invalid parameter"); return NOTI_EX_ERROR_INVALID_PARAMETER; } - Handle* h = static_cast(handle); if (!h->IsValidType(AbstractItem::CheckBox)) { LOGE("Invalid handle type"); return NOTI_EX_ERROR_INVALID_PARAMETER; } - CheckBoxItem* p = static_cast(h->Get()); - p->SetChecked(checked); + *checked = p->IsChecked(); return NOTI_EX_ERROR_NONE; } @@ -643,13 +676,19 @@ extern "C" EXPORT_API int noti_ex_item_entry_get_text(noti_ex_item_h handle, LOGE("Invalid handle type"); return NOTI_EX_ERROR_INVALID_PARAMETER; } + EntryItem* p = static_cast(h->Get()); - if (!p->GetText().empty()) { - *text = strdup(p->GetText().c_str()); - if (*text == nullptr) { - LOGE("Out-of-memory"); - return NOTI_EX_ERROR_OUT_OF_MEMORY; - } + string str; + if (p->GetMultiLanguage() != nullptr && + !p->GetMultiLanguage()->GetTranslatedString().empty()) + str = p->GetMultiLanguage()->GetTranslatedString(); + else if (!p->GetText().empty()) + str = p->GetText(); + + *text = strdup(str.c_str()); + if (*text == nullptr) { + LOGE("Out-of-memory"); + return NOTI_EX_ERROR_OUT_OF_MEMORY; } return NOTI_EX_ERROR_NONE; @@ -672,6 +711,28 @@ extern "C" EXPORT_API int noti_ex_item_entry_set_text(noti_ex_item_h handle, return NOTI_EX_ERROR_NONE; } +extern "C" EXPORT_API int noti_ex_item_entry_set_multi_language( + noti_ex_item_h handle, noti_ex_multi_lang_h multi) { + if (handle == nullptr || multi == nullptr) { + LOGE("Invalid parameter"); + return NOTI_EX_ERROR_INVALID_PARAMETER; + } + + Handle* p = static_cast(handle); + if (!p->IsValidType(AbstractItem::Entry)) { + LOGE("Invalid handle type"); + return NOTI_EX_ERROR_INVALID_PARAMETER; + } + + shared_ptr mul_ptr = + *reinterpret_cast*>(multi); + EntryItem* ei = static_cast(p->Get()); + ei->SetMultiLanguage(mul_ptr); + ei->GetMultiLanguage()->UpdateString(); + + return NOTI_EX_ERROR_NONE; +} + extern "C" EXPORT_API int noti_ex_event_info_clone(noti_ex_event_info_h handle, noti_ex_event_info_h* cloned_handle) { if (handle == nullptr || cloned_handle == nullptr) { @@ -977,8 +1038,18 @@ extern "C" EXPORT_API int noti_ex_item_input_selector_get_contents( LOGE("Invalid handle type"); return NOTI_EX_ERROR_INVALID_PARAMETER; } + InputSelectorItem* p = static_cast(h->Get()); - list contents = p->GetContents(); + vector> arr = p->GetMultiLanguageArr(); + list contents; + if (arr.size() == 0) { + contents = p->GetContents(); + } else { + for (auto& i : arr) { + contents.push_back(i->GetTranslatedString()); + } + } + char **list = (char**)calloc(contents.size(), sizeof(char*)); if (list == nullptr) { LOGE("Out of memory"); @@ -1024,6 +1095,33 @@ extern "C" EXPORT_API int noti_ex_item_input_selector_set_contents( return NOTI_EX_ERROR_NONE; } +extern "C" EXPORT_API int noti_ex_item_input_selector_set_multi_language_contents( + noti_ex_item_h handle, noti_ex_multi_lang_h* multi_language_list, int count) { + if (handle == nullptr) { + LOGE("Invalid parameter"); + return NOTI_EX_ERROR_INVALID_PARAMETER; + } + + Handle* p = static_cast(handle); + if (!p->IsValidType(AbstractItem::InputSelector)) { + LOGE("Invalid handle type"); + return NOTI_EX_ERROR_INVALID_PARAMETER; + } + + vector> m_list; + for (int i = 0; i < count; i++) { + shared_ptr mul_ptr = + *reinterpret_cast*>(multi_language_list[i]); + mul_ptr->UpdateString(); + m_list.push_back(mul_ptr); + } + + InputSelectorItem* input = static_cast(p->Get()); + input->SetMultiLanguage(m_list); + + return NOTI_EX_ERROR_NONE; +} + extern "C" EXPORT_API int noti_ex_color_create(noti_ex_color_h *handle, unsigned char a, unsigned char r, unsigned char g, unsigned char b) { if (handle == nullptr) { @@ -2847,13 +2945,19 @@ extern "C" EXPORT_API int noti_ex_item_text_get_contents(noti_ex_item_h handle, LOGE("Invalid handle type"); return NOTI_EX_ERROR_INVALID_PARAMETER; } + TextItem* ti = static_cast(p->Get()); - if (!ti->GetContents().empty()) { - *contents = strdup(ti->GetContents().c_str()); - if (*contents == nullptr) { - LOGE("Out-of-memory"); - return NOTI_EX_ERROR_OUT_OF_MEMORY; - } + string str; + if (ti->GetMultiLanguage() != nullptr && + !ti->GetMultiLanguage()->GetTranslatedString().empty()) + str = ti->GetMultiLanguage()->GetTranslatedString(); + else if (!ti->GetContents().empty()) + str = ti->GetContents(); + + *contents = strdup(str.c_str()); + if (*contents == nullptr) { + LOGE("Out-of-memory"); + return NOTI_EX_ERROR_OUT_OF_MEMORY; } return NOTI_EX_ERROR_NONE; @@ -2883,6 +2987,33 @@ extern "C" EXPORT_API int noti_ex_item_text_get_hyperlink( return NOTI_EX_ERROR_NONE; } +extern "C" EXPORT_API int noti_ex_item_text_set_multi_language( + noti_ex_item_h handle, noti_ex_multi_lang_h multi) { + if (handle == nullptr) { + LOGE("Invalid parameter"); + return NOTI_EX_ERROR_INVALID_PARAMETER; + } + + Handle* p = static_cast(handle); + if (!p->IsValidType(AbstractItem::Text)) { + LOGE("Invalid handle type"); + return NOTI_EX_ERROR_INVALID_PARAMETER; + } + + TextItem* ti = static_cast(p->Get()); + if (multi == nullptr) { + ti->SetMultiLanguage(nullptr); + return NOTI_EX_ERROR_NONE; + } + + shared_ptr mul_ptr = + *reinterpret_cast*>(multi); + ti->SetMultiLanguage(mul_ptr); + ti->GetMultiLanguage()->UpdateString(); + + return NOTI_EX_ERROR_NONE; +} + extern "C" EXPORT_API int noti_ex_item_time_create(noti_ex_item_h *handle, const char *id, time_t time) { TimeItem* p; @@ -2965,3 +3096,62 @@ extern "C" EXPORT_API int noti_ex_action_visibility_set(noti_ex_action_h handle, return NOTI_EX_ERROR_NONE; } + +extern "C" EXPORT_API int noti_ex_multi_lang_create(noti_ex_multi_lang_h* handle, + const char* msgid, const char* format, ...) { + if (handle == nullptr || msgid == nullptr || format == nullptr) { + LOGE("Invalid parameter"); + return NOTI_EX_ERROR_INVALID_PARAMETER; + } + + const char* format_idx = format; + vector arr; + va_list args; + va_start(args, format); + while (*format_idx != '\0') { + char* arg = nullptr; + int arg_i; + double arg_f; + stringstream stream; + if (*format_idx == '%') { + switch (*(format_idx + 1)) { + case 's': + arg = va_arg(args, char *); + arr.push_back(string(arg)); + break; + case 'd': + arg_i = va_arg(args, int); + arr.push_back(to_string(arg_i)); + break; + case 'f': + arg_f = va_arg(args, double); + stream << std::fixed << std::setprecision(2) << arg_f; + arr.push_back(stream.str()); + break; + } + } + format_idx++; + } + va_end(args); + + MultiLanguage* p = new MultiLanguage(string(msgid), format, arr); + if (p == nullptr) { + LOGE("Out-of-memory"); + return NOTI_EX_ERROR_OUT_OF_MEMORY; + } + *handle = new shared_ptr(p); + + return NOTI_EX_ERROR_NONE; +} + +extern "C" EXPORT_API int noti_ex_multi_lang_destroy(noti_ex_multi_lang_h handle) { + if (handle == nullptr) { + LOGE("Invalid parameter"); + return NOTI_EX_ERROR_INVALID_PARAMETER; + } + + shared_ptr* mul_ptr = + reinterpret_cast*>(handle); + delete mul_ptr; + return NOTI_EX_ERROR_NONE; +} -- 2.7.4