Use Test bugfixes 47/154147/1 accepted/tizen/unified/20171010.063811 submit/tizen/20171010.015810
authorSaulo Moraes <s.moraes@samsung.com>
Fri, 6 Oct 2017 18:57:04 +0000 (15:57 -0300)
committerSaulo Aldighieri Moraes <s.moraes@samsung.com>
Fri, 6 Oct 2017 18:57:43 +0000 (15:57 -0300)
Change-Id: Ib38e4d27b187bf505fe6050dcc6198295844ee49
Signed-off-by: Saulo Aldighieri Moraes <s.moraes@samsung.com>
16 files changed:
common/include/common_ctxpopup.h
common/include/common_popup.h
common/include/common_utils.h
common/src/common_ctxpopup.c
common/src/common_edit_field.c
common/src/common_popup.c
common/src/common_utils.c
ui/src/privacy_dlp_choose_apps_view.c
ui/src/privacy_dlp_menu_view.c
ui/src/privacy_dlp_pattern_create_view.c
ui/src/privacy_dlp_reports_app_rank_view.c
ui/src/privacy_dlp_reports_data_stat_view.c
ui/src/privacy_dlp_reports_del_view.c
ui/src/privacy_dlp_reports_full_view.c
ui/src/privacy_dlp_rule_delete_view.c
ui/src/privacy_dlp_rule_edit_view.c

index eaea655..f2531bd 100644 (file)
@@ -24,7 +24,7 @@
 #define __UI_PRIVACY_SETTING_COMMON_CTXPOPUP_H_
 
 #include "common_utils.h"
-#include <Elementary.h>
+#include <efl_extension.h>
 
 /**
  * @brief create a ctxpopup object
index 430e284..6704c52 100644 (file)
@@ -40,7 +40,7 @@ void destroy_popup(Evas_Object *popup);
  * @param[in] button1_cb       The callback function for when button1 is clicked
  * @param[in] button2_label    The button text for button2
  * @param[in] button2_cb       The callback function for when button2 is clicked
- * @param[in] dismiss_popup_cb The callback function for when the popup is dismissed
+ * @param[in] back_btn_cb      The callback function for when the hardware back button is pressed
  * @param[in] data             User data to be passed to the callback funtions
  *
  * @return the ctxpopup object
@@ -53,7 +53,7 @@ void destroy_popup(Evas_Object *popup);
        Evas_Smart_Cb button1_cb,
        const char *button2_label,
        Evas_Smart_Cb button2_cb,
-       Evas_Smart_Cb dismiss_popup_cb,
+       Evas_Smart_Cb back_btn_cb,
        void* data);
 
 #endif
index 4e05bea..9412eee 100644 (file)
@@ -125,6 +125,34 @@ void free_dlp_pattern(void *pattern);
 */
 bool get_pattern_ids_in_use_list(GList **patterns_not_in_use_list);
 
+/**
+ * @brief check if parameters form a valid rule
+ * @param[in] name the rule name
+ * @param[in] description the rule description
+ * @param[in] pattern the rule pattern
+ *
+ * @return true if the rule is valid, false if otherwise
+*/
+bool is_valid_rule(const char *name, const char *description, const get_pattern_s *pattern);
+
+/**
+ * @brief check if parameters form a valid pattern
+ * @param[in] name the pattern name
+ * @param[in] description the pattern description
+ * @param[in] type the pattern type
+ * @param[in] search_term the pattern search term
+ *
+ * @return true if the pattern is valid, false if otherwise
+*/
+bool is_valid_pattern(const char *name, const char *description, PgDlpPatternType type, const char *search_term);
+
+/**
+ * @brief remove leading spaces from a string. Note: string will be changed in-place
+ * @param[in,out] text the string to be left trimmed
+ * @param[in] len_text the lenght of the string to be left trimmed
+ */
+void left_trim(char *text, const size_t len_text);
+
 #ifdef _cplusplus
 }
 #endif
index a2b6d88..ee7412a 100644 (file)
  */
 
 #include "common_ctxpopup.h"
-#include <efl_extension.h>
 
-static void _dismiss_menu_cb(void *data, Evas_Object *obj, void *event_info)
+static void _back_cb(void *data, Evas_Object *obj, void *event_info)
 {
-       delete_ctxpopup(obj);
+       elm_ctxpopup_dismiss(obj);
 }
 
-void move_menu_popup(Evas_Object *app_win, Evas_Object *ctxpopup)
+static void move_menu_popup(Evas_Object *app_win, Evas_Object *ctxpopup)
 {
        Evas_Coord w, h;
        int pos = -1;
@@ -59,8 +58,7 @@ Evas_Object *create_ctxpop(struct app_data_s *ad)
        Evas_Object *ctxpopup = elm_ctxpopup_add(ad->nf);
        elm_object_style_set(ctxpopup, "more/default");
        elm_ctxpopup_auto_hide_disabled_set(ctxpopup, EINA_TRUE);
-       eext_object_event_callback_add(ctxpopup, EEXT_CALLBACK_BACK, _dismiss_menu_cb, NULL);
-       evas_object_smart_callback_add(ctxpopup, "dismissed", _dismiss_menu_cb, NULL);
+       eext_object_event_callback_add(ctxpopup, EEXT_CALLBACK_BACK, _back_cb, NULL);
        move_menu_popup(ad->win, ctxpopup);
        evas_object_show(ctxpopup);
        return ctxpopup;
index 854dd21..ba202b3 100644 (file)
@@ -146,7 +146,6 @@ dlp_edit_field *create_edit_field(
                evas_object_smart_callback_add(data->entry, "focused", _edit_field_focused_cb, data->edit_field);
                evas_object_smart_callback_add(data->entry, "unfocused", _edit_field_unfocused_cb, data->edit_field);
                evas_object_smart_callback_add(data->entry, "changed", _edit_field_changed_cb, data);
-               evas_object_smart_callback_add(data->entry, "preedit,changed", _edit_field_changed_cb, data->edit_field);
 
                Evas_Object *clear_button = elm_button_add(data->edit_field);
                elm_object_style_set(clear_button, "editfield_clear");
index 47c390c..ace61f9 100644 (file)
@@ -37,9 +37,16 @@ void add_button_to_popup(Evas_Object *popup, void *data, const char* button_text
        evas_object_smart_callback_add(button, "clicked", button_callback, data);
 }
 
-Evas_Object* create_two_buttons_popup(Evas_Object *parent, const char *popup_title, const char *popup_text,
-                                                                                const char *button1_label, Evas_Smart_Cb button1_cb, const char *button2_label,
-                                                                                Evas_Smart_Cb button2_cb, Evas_Smart_Cb dismiss_popup_cb, void* data)
+Evas_Object* create_two_buttons_popup(
+               Evas_Object *parent,
+               const char *popup_title,
+               const char *popup_text,
+               const char *button1_label,
+               Evas_Smart_Cb button1_cb,
+               const char *button2_label,
+               Evas_Smart_Cb button2_cb,
+               Evas_Smart_Cb back_btn_cb,
+               void* data)
 {
        /* Create the popup */
        Evas_Object *popup = elm_popup_add(parent);
@@ -54,8 +61,8 @@ Evas_Object* create_two_buttons_popup(Evas_Object *parent, const char *popup_tit
        add_button_to_popup(popup, data, button1_label, "button1", button1_cb);
        add_button_to_popup(popup, data, button2_label, "button2", button2_cb);
 
-       /* Add callback to popup dismiss popup when user press the hardware back key */
-       eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, dismiss_popup_cb, data);
+       /* Add callback to be called when user press the hardware back key */
+       eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, back_btn_cb, data);
 
        /* Display popup */
        evas_object_show(popup);
index bacb394..ff7ed10 100644 (file)
@@ -171,3 +171,61 @@ bool get_pattern_ids_in_use_list(GList **pattern_ids_in_use_list)
 
        return true;
 }
+
+// Gets position of first non-space character in a string
+static size_t get_first_non_space_pos(const char *text, const size_t len_text)
+{
+       if (NULL == text || 0 == len_text) {
+               LOGE("Invalid parameter");
+               return false;
+       }
+
+       size_t pos = 0;
+       for (; pos < len_text && '\0' != text[pos] && ' ' == text[pos]; ++pos);
+       return pos;
+}
+
+// check if a text field (ususally rule or pattern name and description) is valid.
+// text is considered valid if it is not empty and contains a non-space character.
+static bool is_valid_text_field(const char *text, const size_t len_text)
+{
+       if (NULL == text || 0 == len_text) {
+               LOGE("Invalid parameter");
+               return false;
+       }
+
+       const size_t pos = get_first_non_space_pos(text, len_text);
+       return '\0' != text[pos];
+}
+
+bool is_valid_rule(const char *name, const char *description, const get_pattern_s *pattern)
+{
+       return is_valid_text_field(name, LEN_NAME)
+               && is_valid_text_field(description, LEN_DESCRIPTION)
+               && NULL != pattern;
+}
+
+bool is_valid_pattern(const char *name, const char *description, PgDlpPatternType type, const char *search_term)
+{
+       if (!is_valid_text_field(name, LEN_NAME)
+                       || !is_valid_text_field(description, LEN_DESCRIPTION))
+               return false;
+
+       if (PRIV_GUARD_DLP_PATTERN_STRING == type)
+               return is_valid_text_field(search_term, LEN_PATTERN);
+       else
+               return PRIV_GUARD_ERROR_SUCCESS == privacy_guard_client_validate_pattern(type, search_term);
+}
+
+void left_trim(char *text, const size_t len_text)
+{
+       if (NULL == text || 0 == len_text) {
+               LOGE("Invalid parameter");
+               return;
+       }
+
+       const size_t pos = get_first_non_space_pos(text, len_text);
+       if (pos > 0)
+               for (size_t i = pos; i < len_text; ++i)
+                       text[i - pos] = text[i];
+}
index f3bc0eb..21b880f 100644 (file)
@@ -23,6 +23,9 @@
 #include "privacy_view.h"
 #include <privacy_guard_client.h>
 #include <app_manager.h>
+#include <string.h>
+
+#define DEFAULT_ICON_PATH _TZ_SYS_RO_APP"/org.tizen.privacy-setting/res/icon/default.png"
 
 typedef struct {
        struct app_data_s *ad;
@@ -92,6 +95,18 @@ static gint _compare_selected_app_id_cb(gconstpointer lhs, gconstpointer rhs)
        return strcmp((const char *)lhs, (const char *)rhs);
 }
 
+static char *make_default_app_name(const char *app_id)
+{
+       // uses the last field of the app_id as default app name
+       const char* def_app_name = strrchr(app_id, '.');
+       if (NULL == def_app_name)
+               def_app_name = app_id; // if a dot is not found then use the app_id as default app name
+       else
+               ++def_app_name; // skip the dot
+
+       return strdup(def_app_name); // this must be freed by the caller
+}
+
 /**
  * @brief Internal callback function used to retrieve application information
  * @param[in] app_info appliation handle
@@ -119,8 +134,12 @@ static bool _choose_app_app_info_cb(app_info_h app_info, void *user_data)
                res = app_info_get_label(app_info, &label);
                if (res < 0) {
                        LOGE("%s: app_info_get_label() failed. Error=%d", app->id, res);
-                       app->name = strdup("");
+                       app->name = make_default_app_name(app->id);
                } else {
+                       if ('\0' == label[0]) {
+                               free(label);
+                               label = make_default_app_name(app->id);
+                       }
                        app->name = label;
                }
 
@@ -130,7 +149,7 @@ static bool _choose_app_app_info_cb(app_info_h app_info, void *user_data)
                res = app_info_get_icon(app_info, &(app->icon_path));
                if (res < 0) {
                        LOGE("app_info_get_icon() failed. Error=%d", res);
-                       app->icon_path = strdup("");
+                       app->icon_path = strdup(DEFAULT_ICON_PATH);
                }
 
                choose_app_data_s *choose_app_data = user_data;
@@ -194,7 +213,10 @@ static Evas_Object *_gl_choose_app_content_get_cb(void *data, Evas_Object *obj,
        if (strcmp(part, "elm.swallow.icon") == 0) {
                if (SELECT_ALL_APPS_ITEM_ID != app_item->id) {
                        Evas_Object *icon = elm_icon_add(obj);
-                       elm_image_file_set(icon, app_item->icon_path, NULL);
+                       if (!elm_image_file_set(icon, app_item->icon_path, NULL))
+                               // Sometimes an app has a non-empty icon path, but still fails to set the icon image.
+                               // In these cases, we set the default icon to app
+                               elm_image_file_set(icon, DEFAULT_ICON_PATH, NULL);
                        evas_object_size_hint_min_set(icon, ELM_SCALE_SIZE(50), ELM_SCALE_SIZE(50));
                        return icon;
                }
@@ -485,6 +507,21 @@ void delete_unchecked_apps_rules(const GList *editing_rules_list, GList *selecte
        }
 }
 
+static void add_select_all_item_to_genlist(choose_app_data_s *data)
+{
+       Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
+       itc->item_style = "singleline";
+       itc->func.text_get = _gl_choose_app_text_get_cb;
+       itc->func.content_get = _gl_choose_app_content_get_cb;
+       itc->func.del = NULL;
+
+       Elm_Object_Item *it = elm_genlist_item_append(data->genlist, itc, data->app_list->data, NULL, ELM_GENLIST_ITEM_NONE, _choose_app_menu_item_selected_cb, data);
+       log_if(it == NULL, 1, "Error in elm_genlist_item_append");
+
+       elm_genlist_item_class_free(itc);
+}
+
+
 /**
  * @brief Displays the Choose Applications view
  * @param[in] ad the appliation data
@@ -537,6 +574,7 @@ void create_privacy_dlp_choose_apps_view(struct app_data_s *ad, Elm_Object_Item
        evas_object_size_hint_weight_set(data.genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
        evas_object_size_hint_align_set(data.genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
 
+       add_select_all_item_to_genlist(&data);
        Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
        itc->item_style = "multiline";
        itc->func.text_get = _gl_choose_app_text_get_cb;
@@ -544,7 +582,7 @@ void create_privacy_dlp_choose_apps_view(struct app_data_s *ad, Elm_Object_Item
        itc->func.del = NULL;
        Elm_Object_Item *it = NULL;
        GList* l;
-       for (l = data.app_list; l != NULL; l = l->next) {
+       for (l = g_list_nth(data.app_list, 1); l != NULL; l = l->next) {
                // append item to the genlist
                it = elm_genlist_item_append(data.genlist, itc, l->data, NULL, ELM_GENLIST_ITEM_NONE, _choose_app_menu_item_selected_cb, &data);
                log_if(it == NULL, 1, "Error in elm_genlist_item_append");
index b410893..2efc434 100644 (file)
@@ -373,6 +373,31 @@ static void update_config_value(void *data, Elm_Object_Item* item)
 }
 
 /**
+ * @brief Internal callback function called when DLP on/off item is selected
+ * @param[in] data The user data passed to the elm_genlist_item_append() function
+ * @param[in] obj The object invoking this callback function
+ * @param[in] event_info The structure containing the information on this event
+ */
+static void _gl_enabled_item_select_cb(void *data, Evas_Object *obj, void *event_info)
+{
+       /* Unhighlight selected item */
+       elm_genlist_item_selected_set(event_info, EINA_FALSE);
+
+       /* get check object */
+       Evas_Object *check = elm_object_item_part_content_get(event_info, "elm.swallow.end");
+
+       /* flip dlp enabled state */
+       config.enabled = elm_check_state_get(check) ? 0 : 1;
+
+       const int res = privacy_guard_client_set_dlp_profile(getuid(), &config);
+       if (PRIV_GUARD_ERROR_SUCCESS == res) {
+               elm_check_state_set(check, config.enabled ? EINA_TRUE : EINA_FALSE);
+       } else {
+               LOGE("privacy_guard_client_set_dlp_profile() is failed. [%d]", res);
+       }
+}
+
+/**
  * @brief Internal callback function when default profile is selected.
  * @param[in] data The user data passed to the evas_object_smart_callback_add() function
  * @param[in] obj The object invoking this callback function
@@ -736,7 +761,7 @@ void create_privacy_dlp_menu_view(struct app_data_s *ad)
        itc_enabled->func.content_get = _gl_enabled_content_get_cb;
        itc_enabled->func.del = _gl_del_config_cb;
 
-       elm_genlist_item_append(genlist, itc_enabled, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+       elm_genlist_item_append(genlist, itc_enabled, NULL, NULL, ELM_GENLIST_ITEM_NONE, _gl_enabled_item_select_cb, NULL);
        elm_genlist_item_class_free(itc_enabled);
 
        // Option to Select Protection Mode
index c6d834f..ce1bf4a 100644 (file)
@@ -65,9 +65,11 @@ static void _pattern_create_view_free_category_cb(void *category)
 static void _pattern_create_field_changed_cb(void *data, Evas_Object *obj, void* event_info)
 {
        pattern_create_view_data_s *pcvd = data;
-       if (!is_edit_field_empty(pcvd->name_edit_field)
-                       && !is_edit_field_empty(pcvd->description_edit_field)
-                       && PRIV_GUARD_ERROR_SUCCESS == privacy_guard_client_validate_pattern(pcvd->current_type, get_text_from_edit_field(pcvd->search_string_edit_field)))
+       if (is_valid_pattern(
+                       get_text_from_edit_field(pcvd->name_edit_field),
+                       get_text_from_edit_field(pcvd->description_edit_field),
+                       pcvd->current_type,
+                       get_text_from_edit_field(pcvd->search_string_edit_field)))
                elm_object_disabled_set(pcvd->done_button, EINA_FALSE);
        else
                elm_object_disabled_set(pcvd->done_button, EINA_TRUE);
@@ -83,9 +85,19 @@ static void _pattern_create_done_cb(void *data, Evas_Object *obj, void* event_in
 {
        pattern_create_view_data_s *pcvd = data;
 
+       char name[LEN_NAME];
+       strncpy(name, get_text_from_edit_field(pcvd->name_edit_field), LEN_NAME);
+       left_trim(name, LEN_NAME);
+       name[LEN_NAME - 1] = '\0';
+
+       char description[LEN_DESCRIPTION];
+       strncpy(description, get_text_from_edit_field(pcvd->description_edit_field), LEN_DESCRIPTION);
+       left_trim(description, LEN_DESCRIPTION);
+       description[LEN_DESCRIPTION - 1] = '\0';
+
        const int res = privacy_guard_client_add_dlp_pattern(
-               get_text_from_edit_field(pcvd->name_edit_field),
-               get_text_from_edit_field(pcvd->description_edit_field),
+               name,
+               description,
                elm_object_text_get(pcvd->category_hoversel),
                get_text_from_edit_field(pcvd->search_string_edit_field),
                pcvd->current_type);
index 1a89597..1783114 100644 (file)
@@ -75,11 +75,12 @@ static char* _gl_text_get_cb(void *data, Evas_Object *obj, const char *part)
                int size = snprintf(string_buf, REPORT_TOTAL_LEAKS_LEN, "%s: %d<br>From: ",
                        dgettext("privacy-setting", PRIVACY_MENU_DLP_REPORTS_TOTAL_LEAKS), item->leak_count);
 
-               struct tm *timestamp = gmtime(&item->first_time_stamp);
-               size += strftime(string_buf + size, 100 - size, "%b %d, %Y - To: ", timestamp);
+               struct tm timestamp;
+               gmtime_r(&item->first_time_stamp, &timestamp);
+               size += strftime(string_buf + size, 100 - size, "%b %d, %Y - To: ", &timestamp);
 
-               timestamp = gmtime(&item->last_time_stamp);
-               size += strftime(string_buf + size, 100 - size, "%b %d, %Y", timestamp);
+               gmtime_r(&item->last_time_stamp, &timestamp);
+               size += strftime(string_buf + size, 100 - size, "%b %d, %Y", &timestamp);
 
                char *multiline = strdup(string_buf);
 
index 7ebd202..2e5a456 100644 (file)
@@ -70,11 +70,12 @@ static char* _gl_text_get_cb(void *data, Evas_Object *obj, const char *part)
                int size = snprintf(string_buf, 100, "%s: %d<br>From: ", dgettext("privacy-setting",
                        PRIVACY_MENU_DLP_REPORTS_TOTAL_LEAKS), item->leak_count);
 
-               struct tm *timestamp = gmtime(&item->first_time_stamp);
-               size += strftime(string_buf + size, 100 - size, "%b %d, %Y - To: ", timestamp);
+               struct tm timestamp;
+               gmtime_r(&item->first_time_stamp, &timestamp);
+               size += strftime(string_buf + size, 100 - size, "%b %d, %Y - To: ", &timestamp);
 
-               timestamp = gmtime(&item->last_time_stamp);
-               size += strftime(string_buf + size, 100 - size, "%b %d, %Y", timestamp);
+               gmtime_r(&item->last_time_stamp, &timestamp);
+               size += strftime(string_buf + size, 100 - size, "%b %d, %Y", &timestamp);
 
                char *multiline = strdup(string_buf);
 
index 47564db..2ff1fec 100644 (file)
@@ -212,8 +212,9 @@ static char *_reports_del_gl_text_get_cb(void *data, Evas_Object *obj, const cha
                        return "";
 
                char time_str[64] = {0,};
-               struct tm *timeinfo = localtime(&item->data->time_stamp);
-               strftime(time_str, sizeof(time_str), "%a, %x %X", timeinfo);
+               struct tm timeinfo;
+               localtime_r(&item->data->time_stamp, &timeinfo);
+               strftime(time_str, sizeof(time_str), "%a, %x %X", &timeinfo);
 
                size_t string_mem_needed = snprintf(NULL, 0,
                                                    "%s<br>%s",
index f2ea1ff..a229b82 100644 (file)
@@ -91,8 +91,9 @@ static char* _gl_text_get_cb(void *data, Evas_Object *obj, const char *part)
                        return "";
 
                char time_str[64] = {0,};
-               struct tm *timeinfo = localtime(&item->data->time_stamp);
-               strftime(time_str, sizeof(time_str), "%a, %x %X", timeinfo);
+               struct tm timeinfo;
+               localtime_r(&item->data->time_stamp, &timeinfo);
+               strftime(time_str, sizeof(time_str), "%a, %x %X", &timeinfo);
 
                size_t string_mem_needed = snprintf(NULL, 0,
                                                                                        "%s<br>%s",
index f0926ef..7d250de 100644 (file)
@@ -263,6 +263,20 @@ void create_select_all_rules_item(rule_delete_view_data_s *data)
        }
 }
 
+static void add_select_all_item_to_genlist(rule_delete_view_data_s *data)
+{
+       Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
+       itc->item_style = "singleline";
+       itc->func.text_get = _gl_rule_delete_text_get_cb;
+       itc->func.content_get = _gl_rule_delete_content_get_cb;
+       itc->func.del = NULL;
+
+       Elm_Object_Item *it = elm_genlist_item_append(data->genlist, itc, data->rule_item_list->data, NULL, ELM_GENLIST_ITEM_NONE, _rule_delete_menu_item_selected_cb, data);
+       log_if(it == NULL, 1, "Error in elm_genlist_item_append");
+
+       elm_genlist_item_class_free(itc);
+}
+
 void create_privacy_dlp_rule_delete_view(struct app_data_s *ad, const GList *rule_list, void *rule_list_data)
 {
        if (NULL == ad || NULL == rule_list || NULL == rule_list_data) {
@@ -281,13 +295,14 @@ void create_privacy_dlp_rule_delete_view(struct app_data_s *ad, const GList *rul
        evas_object_size_hint_weight_set(data.genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
        evas_object_size_hint_align_set(data.genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
 
+       add_select_all_item_to_genlist(&data);
        Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
        itc->item_style = "multiline";
        itc->func.text_get = _gl_rule_delete_text_get_cb;
        itc->func.content_get = _gl_rule_delete_content_get_cb;
        itc->func.del = NULL;
        Elm_Object_Item *it = NULL;
-       GList* l = data.rule_item_list;
+       GList* l = g_list_nth(data.rule_item_list, 1);
 
        while (l != NULL) {
                // append item to the genlist
@@ -295,10 +310,6 @@ void create_privacy_dlp_rule_delete_view(struct app_data_s *ad, const GList *rul
                log_if(it == NULL, 1, "Error in elm_genlist_item_append");
 
                const get_custom_rule_s *rule = ((rule_delete_item_s *)(l->data))->rule;
-               if (SELECT_ALL_RULES_ITEM == rule->id) {
-                       l = l->next;
-                       continue;
-               }
 
                // Skip rules that have the same pattern and action as the current rule
                const int pattern_id = rule->pattern_id;
index d93c446..598cf2b 100644 (file)
@@ -122,10 +122,12 @@ static void _rule_edit_done_cb(void *data, Evas_Object *obj, void *event_info)
 
        char name[LEN_NAME];
        strncpy(name, get_text_from_edit_field(red->name_edit_field), LEN_NAME);
+       left_trim(name, LEN_NAME);
        name[LEN_NAME - 1] = '\0';
 
        char description[LEN_DESCRIPTION];
        strncpy(description, get_text_from_edit_field(red->description_edit_field), LEN_DESCRIPTION);
+       left_trim(description, LEN_DESCRIPTION);
        description[LEN_DESCRIPTION - 1] = '\0';
 
        const int pattern_id = current_pattern->id;
@@ -206,9 +208,11 @@ static void _rule_edit_next_cb(void *data, Evas_Object *obj, void *event_info)
        red->edited_rule.pattern[LEN_PATTERN - 1] = '\0';
 
        strncpy(red->edited_rule.name, get_text_from_edit_field(red->name_edit_field), LEN_NAME);
+       left_trim(red->edited_rule.name, LEN_NAME);
        red->edited_rule.name[LEN_NAME - 1] = '\0';
 
        strncpy(red->edited_rule.description, get_text_from_edit_field(red->description_edit_field), LEN_DESCRIPTION);
+       left_trim(red->edited_rule.description, LEN_DESCRIPTION);
        red->edited_rule.description[LEN_DESCRIPTION - 1] = '\0';
 
        strncpy(red->edited_rule.application_id, red->current_rule->application_id, LEN_APPLICATION_ID);
@@ -264,10 +268,10 @@ get_pattern_s *create_pattern(
 
 static void set_state_of_done_button(rule_edit_data_s *red)
 {
-       const Eina_Bool disable = !is_edit_field_empty(red->name_edit_field)
-               && !is_edit_field_empty(red->description_edit_field)
-               && NULL != current_pattern
-               ? EINA_FALSE : EINA_TRUE;
+       const Eina_Bool disable = is_valid_rule(
+               get_text_from_edit_field(red->name_edit_field),
+               get_text_from_edit_field(red->description_edit_field),
+               current_pattern) ? EINA_FALSE : EINA_TRUE;
        Evas_Object *button = (NULL != red->done_button) ? red->done_button : red->next_button;
        elm_object_disabled_set(button, disable);
 }