aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitor Sousa <vitorsousasilva@gmail.com>2016-08-22 21:59:10 -0300
committerVitor Sousa <vitorsousasilva@gmail.com>2016-08-26 19:53:15 -0300
commitc63ebcb560b72349941afbd2fdd1312775642ded (patch)
tree3613abaca8dcaa21e1206525833fcce6a6982334
parentelm fileselector: fix possible premature deletion of Listing_Request struct (diff)
downloadefl-devs/vitorsousa/fix_fileselector.tar.gz
elm fileselector: fix events that must be using Efl.Model objectsdevs/vitorsousa/fix_fileselector
Use the new behavior of Efl.Object.event_callback_call to correctly update events to pass Efl.Model objects while still suppling path strings for legacy smart callbacks. Override Elm.Fileselector.event_callback_legacy_call in order to separate the types of any incoming event call that uses Efl.Model. Fix https://phab.enlightenment.org/T4337
-rw-r--r--src/lib/elementary/elc_fileselector.c198
-rw-r--r--src/lib/elementary/elc_fileselector_button.c37
-rw-r--r--src/lib/elementary/elc_fileselector_entry.c49
-rw-r--r--src/lib/elementary/elm_fileselector.eo1
-rw-r--r--src/lib/elementary/elm_interface_fileselector.h6
5 files changed, 195 insertions, 96 deletions
diff --git a/src/lib/elementary/elc_fileselector.c b/src/lib/elementary/elc_fileselector.c
index 21bf9c4f65..99ec2654c4 100644
--- a/src/lib/elementary/elc_fileselector.c
+++ b/src/lib/elementary/elc_fileselector.c
@@ -25,6 +25,12 @@
/* FIXME: need a way to find a gap between the size of item and thumbnail */
#define GENGRID_PADDING 16
+typedef struct _Legacy_Event_Path_Then_Data
+{
+ Eo *eo_obj;
+ const Efl_Event_Description *evt_desc;
+} Legacy_Event_Path_Then_Data;
+
static Elm_Genlist_Item_Class *list_itc[ELM_FILE_LAST];
static Elm_Gengrid_Item_Class *grid_itc[ELM_FILE_LAST];
@@ -39,11 +45,22 @@ EAPI Eina_Error ELM_FILESELECTOR_ERROR_INVALID_MODEL = 0;
static const char ELM_FILESELECTOR_ERROR_UNKNOWN_STR[] = "Unknown Error";
static const char ELM_FILESELECTOR_ERROR_INVALID_MODEL_STR[] = "Model not set";
+#define ELM_PRIV_FILESELECTOR_SIGNALS(cmd) \
+ cmd(SIG_ACTIVATED, "activated", "s") \
+ cmd(SIG_DIRECTORY_OPEN, "directory,open", "s") \
+ cmd(SIG_DONE, "done", "s") \
+ cmd(SIG_SELECTED, "selected", "s") \
+ cmd(SIG_SELECTED_INVALID, "selected,invalid", "s")
+
+ELM_PRIV_FILESELECTOR_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
+
static const Evas_Smart_Cb_Description _smart_callbacks[] = {
+ ELM_PRIV_FILESELECTOR_SIGNALS(ELM_PRIV_SMART_CALLBACKS_DESC)
{SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
{SIG_LAYOUT_UNFOCUSED, ""}, /**< handled by elm_layout */
{NULL, NULL}
};
+#undef ELM_PRIV_FILESELECTOR_SIGNALS
static Eina_Bool _key_action_select(Evas_Object *obj, const char *params);
static Eina_Bool _key_action_escape(Evas_Object *obj, const char *params);
@@ -77,6 +94,21 @@ _model_free_eo_cb(void *data)
efl_unref(eo);
}
+
+void
+_event_to_legacy_call(Eo *obj, const Efl_Event_Description *evt_desc, void *event_info)
+{
+ const Efl_Event_Description *legacy_desc = efl_object_legacy_only_event_description_get(evt_desc->name);
+ efl_event_callback_call(obj, legacy_desc, event_info);
+}
+
+void
+_model_event_call(Eo *obj, const Efl_Event_Description *evt_desc, Efl_Model *model, const char *path)
+{
+ _event_to_legacy_call(obj, evt_desc, (void *)path);
+ efl_event_callback_call(obj, evt_desc, model);
+}
+
static void
_monitoring_start(Elm_Fileselector *fs, Elm_Fileselector_Data *sd, Efl_Model *model)
{
@@ -623,11 +655,8 @@ _signal_first(Listing_Request *lreq)
sd->multi_selection = eina_list_free(sd->multi_selection);
}
- // EVENTS: should not call legacy
- //efl_event_callback_legacy_call
- // (lreq->obj, ELM_FILESELECTOR_EVENT_DIRECTORY_OPEN, (void *)lreq->model);
-
- evas_object_smart_callback_call(lreq->obj, "directory,open", (void *)lreq->path);
+ _model_event_call
+ (lreq->obj, ELM_FILESELECTOR_EVENT_DIRECTORY_OPEN, lreq->model, lreq->path);
if (!lreq->parent_it)
{
@@ -1072,10 +1101,8 @@ _on_item_activated(void *data, const Eo_Event *event)
if (!it_data->is_dir)
{
- // EVENTS: should not call legacy
- //efl_event_callback_legacy_call
- // (data, ELM_FILESELECTOR_EVENT_ACTIVATED, (void *)it_data->model);
- evas_object_smart_callback_call(data, "activated", (void *)it_data->path);
+ _model_event_call
+ (data, ELM_FILESELECTOR_EVENT_ACTIVATED, it_data->model, it_data->path);
return;
}
@@ -1158,10 +1185,8 @@ _on_item_selected(void *data, const Eo_Event *event)
else
elm_object_text_set(sd->name_entry, it_data->filename);
- // EVENTS: should not call legacy
- //efl_event_callback_legacy_call
- // (data, EFL_UI_EVENT_SELECTED, (void *)it_data->model);
- evas_object_smart_callback_call(data, "selected", (void *)it_data->path);
+ _model_event_call
+ (data, EFL_UI_EVENT_SELECTED, it_data->model, it_data->path);
}
else if (sd->multi && it_data->is_dir && sd->double_tap_navigation)
{
@@ -1302,9 +1327,7 @@ _ok(void *data, const Eo_Event *event EINA_UNUSED)
if (!sd->model || !sd->path)
{
- // EVENTS: should not call legacy
- //efl_event_callback_legacy_call(fs, ELM_FILESELECTOR_EVENT_DONE, NULL);
- evas_object_smart_callback_call(fs, "done", NULL);
+ _model_event_call(fs, ELM_FILESELECTOR_EVENT_DONE, NULL, NULL);
return;
}
@@ -1321,10 +1344,8 @@ _ok(void *data, const Eo_Event *event EINA_UNUSED)
selected_model = efl_add(efl_class_get(sd->model), NULL);
_model_str_property_set(selected_model, "path", selection, NULL);
- // EVENTS: should not call legacy
- //efl_event_callback_legacy_call
- // (fs, ELM_FILESELECTOR_EVENT_DONE, selected_model);
- evas_object_smart_callback_call(fs, "done", (void *) selection);
+ _model_event_call
+ (fs, ELM_FILESELECTOR_EVENT_DONE, selected_model, selection);
efl_unref(selected_model);
eina_stringshare_del(selection);
@@ -1334,15 +1355,14 @@ _ok(void *data, const Eo_Event *event EINA_UNUSED)
Elm_Fileselector_Item_Data *it_data = _selected_item_data_get(sd);
if (it_data)
{
- // EVENTS: should not call legacy
- //efl_event_callback_legacy_call
- // (fs, ELM_FILESELECTOR_EVENT_DONE, it_data->model);
- evas_object_smart_callback_call(fs, "done", (void *) it_data->path);
+ _model_event_call
+ (fs, ELM_FILESELECTOR_EVENT_DONE, it_data->model, it_data->path);
+ }
+ else
+ {
+ _model_event_call
+ (fs, ELM_FILESELECTOR_EVENT_DONE, sd->model, sd->path);
}
- // EVENTS: should not call legacy
- //efl_event_callback_legacy_call
- // (fs, ELM_FILESELECTOR_EVENT_DONE, sd->model);
- evas_object_smart_callback_call(fs, "done", (void *) sd->path);
}
}
@@ -1351,9 +1371,7 @@ _canc(void *data, const Eo_Event *event EINA_UNUSED)
{
Evas_Object *fs = data;
- // EVENTS: should not call legacy
- //efl_event_callback_legacy_call(fs, ELM_FILESELECTOR_EVENT_DONE, NULL);
- evas_object_smart_callback_call(fs, "done", NULL);
+ _model_event_call(fs, ELM_FILESELECTOR_EVENT_DONE, NULL, NULL);
}
static void
@@ -1388,10 +1406,8 @@ _text_activated_is_dir_then(void *data, void *value)
if (sd->only_folder)
{
- // EVENTS: should not call legacy
- //efl_event_callback_legacy_call
- // (fs, EFL_UI_EVENT_SELECTED, (void *)model);
- evas_object_smart_callback_call(fs, "selected", (void *) str);
+ _model_event_call
+ (fs, EFL_UI_EVENT_SELECTED, model, str);
}
}
else
@@ -1407,10 +1423,8 @@ _text_activated_is_dir_then(void *data, void *value)
if (sd->only_folder)
{
- // EVENTS: should not call legacy
- //efl_event_callback_legacy_call
- // (fs, EFL_UI_EVENT_SELECTED, (void *)model);
- evas_object_smart_callback_call(fs, "selected", (void *) str);
+ _model_event_call
+ (fs, EFL_UI_EVENT_SELECTED, model, str);
}
}
}
@@ -1443,18 +1457,14 @@ static void
_on_text_activated_set_path_then_error(void *data, Eina_Error err EINA_UNUSED)
{
Evas_Object *fs = data;
- /* Efl_Model *model = efl_key_data_get(fs, _text_activated_model_key); */
+ Efl_Model *model = efl_key_data_get(fs, _text_activated_model_key);
Eina_Stringshare *str = efl_key_data_get(fs, _text_activated_path_key);
- // EVENTS: should not call legacy
- //efl_event_callback_legacy_call
- // (fs, EFL_UI_EVENT_SELECTED, (void *)model);
- evas_object_smart_callback_call(fs, "selected", (void *)str);
+ _model_event_call
+ (fs, EFL_UI_EVENT_SELECTED, model, str);
- // EVENTS: should not call legacy
- //efl_event_callback_legacy_call
- // (fs, ELM_FILESELECTOR_EVENT_SELECTED_INVALID, (void *)model);
- evas_object_smart_callback_call(fs, "selected,invalid", (void *)str);
+ _model_event_call
+ (fs, ELM_FILESELECTOR_EVENT_SELECTED_INVALID, model, str);
_text_activated_free_fs_data(fs);
}
@@ -2048,6 +2058,98 @@ _elm_fileselector_efl_object_constructor(Eo *obj, Elm_Fileselector_Data *sd)
return obj;
}
+static void
+_legacy_smart_callback_caller_path_then(void *data, void *value)
+{
+ Legacy_Event_Path_Then_Data *evt_data = data;
+ _event_to_legacy_call(evt_data->eo_obj, evt_data->evt_desc, value);
+ free(data);
+}
+
+static void
+_legacy_smart_callback_caller_path_then_error(void *data, Eina_Error err)
+{
+ ERR("Efl.Model property \"path\" error: %s", eina_error_msg_get(err));
+ free(data);
+}
+
+static Eina_Bool
+_from_efl_event_call(Elm_Fileselector *fs, const Efl_Event_Description *evt_desc, Efl_Model *model)
+{
+ Eina_Promise *promise;
+ Legacy_Event_Path_Then_Data *evt_data;
+
+ evt_data = calloc(1, sizeof(Legacy_Event_Path_Then_Data));
+ evt_data->eo_obj = fs;
+ evt_data->evt_desc = evt_desc;
+
+ // Call legacy smart callback with path
+ promise = efl_model_property_get(model, "path");
+ eina_promise_then(promise,
+ _legacy_smart_callback_caller_path_then,
+ _legacy_smart_callback_caller_path_then_error,
+ evt_data);
+
+ // Call Eo event with model
+ return efl_event_callback_call(fs, evt_desc, model);
+}
+
+static Eina_Bool
+_from_legacy_event_call(Elm_Fileselector *fs, Elm_Fileselector_Data *sd, const Efl_Event_Description *legacy_desc, const Efl_Event_Description *evt_desc, const char *path)
+{
+ const Efl_Class *model_cls = NULL;
+ if (!sd->model)
+ model_cls = EIO_MODEL_CLASS;
+ else
+ model_cls = efl_class_get(sd->model);
+
+ Efl_Model *model = efl_add(model_cls, NULL);
+ _model_str_property_set(model, "path", path, NULL);
+
+ // Call Eo event with model
+ efl_event_callback_call(fs, evt_desc, model);
+
+ efl_unref(model);
+
+ // Call legacy smart callback with path
+ return efl_event_callback_call(fs, legacy_desc, (void *)path);
+}
+
+EOLIAN static Eina_Bool
+_elm_fileselector_efl_object_event_callback_legacy_call(Eo *obj, Elm_Fileselector_Data *sd,
+ const Efl_Event_Description *desc, void *event_info)
+{
+ if (desc->legacy_is)
+ {
+ const Efl_Event_Description *evt_desc = NULL;
+ if (strcmp(desc->name, "selected") == 0)
+ evt_desc = EFL_UI_EVENT_SELECTED;
+ else if (strcmp(desc->name, "activated") == 0)
+ evt_desc = ELM_FILESELECTOR_EVENT_ACTIVATED;
+ else if (strcmp(desc->name, "directory,open") == 0)
+ evt_desc = ELM_FILESELECTOR_EVENT_DIRECTORY_OPEN;
+ else if (strcmp(desc->name, "done") == 0)
+ evt_desc = ELM_FILESELECTOR_EVENT_DONE;
+ else if (strcmp(desc->name, "selected,invalid") == 0)
+ evt_desc = ELM_FILESELECTOR_EVENT_SELECTED_INVALID;
+ else
+ return efl_event_callback_legacy_call(efl_super(obj, MY_CLASS), desc, event_info);
+
+ return _from_legacy_event_call(obj, sd, desc, evt_desc, event_info);
+ }
+
+ if (desc == EFL_UI_EVENT_SELECTED ||
+ desc == ELM_FILESELECTOR_EVENT_ACTIVATED ||
+ desc == ELM_FILESELECTOR_EVENT_DIRECTORY_OPEN ||
+ desc == ELM_FILESELECTOR_EVENT_DONE ||
+ desc == ELM_FILESELECTOR_EVENT_SELECTED_INVALID)
+ {
+ return _from_efl_event_call(obj, desc, event_info);
+ }
+
+ return efl_event_callback_legacy_call(efl_super(obj, MY_CLASS), desc, event_info);
+}
+
EAPI void
elm_fileselector_is_save_set(Evas_Object *obj,
Eina_Bool is_save)
diff --git a/src/lib/elementary/elc_fileselector_button.c b/src/lib/elementary/elc_fileselector_button.c
index f7a173bf53..1a4a69d6ac 100644
--- a/src/lib/elementary/elc_fileselector_button.c
+++ b/src/lib/elementary/elc_fileselector_button.c
@@ -74,6 +74,8 @@ _replace_path_then(void *data, void *value)
const char *path = NULL;
eina_value_get(value, &path);
eina_stringshare_replace(&sd->fsd.path, path);
+ _event_to_legacy_call
+ (sd->obj, ELM_FILESELECTOR_BUTTON_EVENT_FILE_CHOSEN, (void *)path);
}
static void
@@ -82,6 +84,8 @@ _replace_path_then_error(void *data, Eina_Error err EINA_UNUSED)
Elm_Fileselector_Button_Data *sd = data;
ERR("could not get information from Efl.Model");
eina_stringshare_replace(&sd->fsd.path, NULL);
+ _event_to_legacy_call
+ (sd->obj, ELM_FILESELECTOR_BUTTON_EVENT_FILE_CHOSEN, NULL);
}
static void
@@ -99,32 +103,19 @@ _selection_done(void *data, const Eo_Event *event)
sd->fsd.model = efl_ref(model);
promise = efl_model_property_get(model, "path");
eina_promise_then(promise, _replace_path_then, _replace_path_then_error, sd);
+ efl_event_callback_call
+ (sd->obj, ELM_FILESELECTOR_BUTTON_EVENT_FILE_CHOSEN, model);
+ }
+ else
+ {
+ _model_event_call
+ (sd->obj, ELM_FILESELECTOR_BUTTON_EVENT_FILE_CHOSEN, NULL, NULL);
}
del = sd->fsw;
sd->fs = NULL;
sd->fsw = NULL;
evas_object_del(del);
-
- // EVENTS: should not call legacy
- //efl_event_callback_legacy_call
- // (sd->obj, ELM_FILESELECTOR_BUTTON_EVENT_FILE_CHOSEN, (void *)model);
-}
-
-
-static void
-_selection_done_path(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
-{
- Elm_Fileselector_Button_Data *sd = data;
- const char *path = event_info;
-
- evas_object_smart_callback_call(sd->obj, "file,chosen", (void *) path);
-
- // EVENTS: code above should not be needed
- Eo_Event e = { NULL, NULL, NULL };
- if (path)
- e.info = efl_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(efl_self, path));
- _selection_done(data, &e);
}
static Evas_Object *
@@ -189,10 +180,8 @@ _activate(Elm_Fileselector_Button_Data *sd)
evas_object_size_hint_weight_set
(sd->fs, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(sd->fs, EVAS_HINT_FILL, EVAS_HINT_FILL);
- // EVENTS: should not call legacy
- //efl_event_callback_add
- // (sd->fs, ELM_FILESELECTOR_EVENT_DONE, _selection_done, sd);
- evas_object_smart_callback_add(sd->fs, "done", _selection_done_path, sd);
+ efl_event_callback_add
+ (sd->fs, ELM_FILESELECTOR_EVENT_DONE, _selection_done, sd);
evas_object_show(sd->fs);
if (is_inwin)
diff --git a/src/lib/elementary/elc_fileselector_entry.c b/src/lib/elementary/elc_fileselector_entry.c
index bb189792ba..5ffcab5067 100644
--- a/src/lib/elementary/elc_fileselector_entry.c
+++ b/src/lib/elementary/elc_fileselector_entry.c
@@ -33,6 +33,7 @@ EAPI const char ELM_FILESELECTOR_ENTRY_SMART_NAME[] = "elm_fileselector_entry";
cmd(SIG_SELECTION_COPY, "selection,copy", "") \
cmd(SIG_SELECTION_CUT, "selection,cut", "") \
cmd(SIG_UNPRESSED, "unpressed", "") \
+ cmd(SIG_FILE_CHOSEN, "file,chosen", "s") \
ELM_PRIV_FILESELECTOR_ENTRY_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
@@ -67,19 +68,32 @@ SIG_FWD(UNPRESSED, EFL_UI_EVENT_UNPRESSED)
static void
_file_chosen_path_then(void *data, void *v)
{
+ Eina_Array *args = data;
const char *file = NULL;
char *s;
+ Eo *fs = eina_array_data_get(args, 0);
+ Efl_Model *model = eina_array_data_get(args, 1);
+
+ eina_array_free(args);
eina_value_get(v, &file);
if (!file) return;
- ELM_FILESELECTOR_ENTRY_DATA_GET(data, sd);
-
- evas_object_smart_callback_call(data, "file,chosen", (void *) file);
+ ELM_FILESELECTOR_ENTRY_DATA_GET(fs, sd);
s = elm_entry_utf8_to_markup(file);
elm_object_text_set(sd->entry, s);
free(s);
+
+ _model_event_call
+ (fs, ELM_FILESELECTOR_ENTRY_EVENT_FILE_CHOSEN, model, file);
+}
+
+static void
+_file_chosen_path_then_error(void *data, Eina_Error err)
+{
+ ERR("Efl.Model property \"path\" error: %s", eina_error_msg_get(err));
+ eina_array_free(data);
}
static void
@@ -87,27 +101,17 @@ _FILE_CHOSEN_fwd(void *data, const Eo_Event *event)
{
Efl_Model *model = event->info;
Eina_Promise *promise = NULL;
+ Eina_Array *args = NULL;
if (!model) return;
- promise = efl_model_property_get(model, "path");
- eina_promise_then(promise, _file_chosen_path_then, NULL, data);
-
- // EVENTS: should not call legacy
- //efl_event_callback_legacy_call
- // (data, ELM_FILESELECTOR_ENTRY_EVENT_FILE_CHOSEN, event->info);
-}
+ args = eina_array_new(2);
+ eina_array_push(args, data);
+ eina_array_push(args, model);
-// EVENTS: should not need this function
-static void
-_FILE_CHOSEN_fwd_path(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
-{
- const char *path = event_info;
-
- Eo_Event e = { NULL, NULL, NULL };
- if (path)
- e.info = efl_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(efl_self, path));
- _FILE_CHOSEN_fwd(data, &e);
+ promise = efl_model_property_get(model, "path");
+ eina_promise_then
+ (promise, _file_chosen_path_then, _file_chosen_path_then_error, args);
}
static void
@@ -328,11 +332,8 @@ _elm_fileselector_entry_efl_canvas_group_group_add(Eo *obj, Elm_Fileselector_Ent
efl_event_callback_add(priv->button, event, _##name##_fwd, obj)
SIG_FWD(CLICKED, EFL_UI_EVENT_CLICKED);
SIG_FWD(UNPRESSED, EFL_UI_EVENT_UNPRESSED);
- // EVENTS: should not call legacy
- //SIG_FWD(FILE_CHOSEN, ELM_FILESELECTOR_BUTTON_EVENT_FILE_CHOSEN);
+ SIG_FWD(FILE_CHOSEN, ELM_FILESELECTOR_BUTTON_EVENT_FILE_CHOSEN);
#undef SIG_FWD
- // EVENTS: should not need this "callback_add"
- evas_object_smart_callback_add(priv->button, "file,chosen", _FILE_CHOSEN_fwd_path, obj);
priv->entry = elm_entry_add(obj);
elm_entry_scrollable_set(priv->entry, EINA_TRUE);
diff --git a/src/lib/elementary/elm_fileselector.eo b/src/lib/elementary/elm_fileselector.eo
index bad9635f7f..f6f0bb5ef4 100644
--- a/src/lib/elementary/elm_fileselector.eo
+++ b/src/lib/elementary/elm_fileselector.eo
@@ -34,6 +34,7 @@ class Elm.Fileselector (Elm.Layout, Elm.Interface.Fileselector,
class.constructor;
class.destructor;
Efl.Object.constructor;
+ Efl.Object.event_callback_legacy_call;
Efl.Canvas.Group.group_add;
Efl.Canvas.Group.group_del;
Elm.Widget.focus_next;
diff --git a/src/lib/elementary/elm_interface_fileselector.h b/src/lib/elementary/elm_interface_fileselector.h
index 1c9b05c57d..1ce059552c 100644
--- a/src/lib/elementary/elm_interface_fileselector.h
+++ b/src/lib/elementary/elm_interface_fileselector.h
@@ -35,4 +35,10 @@ _elm_fileselector_button_path_set_internal(Evas_Object *obj, const char *path);
const char *
_elm_fileselector_button_path_get_internal(const Evas_Object *obj);
+void
+_event_to_legacy_call(Eo *obj, const Efl_Event_Description *evt_desc, void *event_info);
+
+void
+_model_event_call(Eo *obj, const Efl_Event_Description *evt_desc, Efl_Model *model, const char *path);
+
#endif