From 81b68b08a9da9c5753a173d6244a8e20a31a6a63 Mon Sep 17 00:00:00 2001 From: Bruno Dilly Date: Thu, 4 Nov 2010 11:56:15 +0000 Subject: [PATCH] Remove elm_notepad Notepad had a big issue: users couldn't access the entry, so notepad was something near to an useless widget. We needed to choose between wrap all entry functions or add these file save / load and autosave features to entries. As discussed on the emails list, we decided to go with the second option, so we won't have an extra widget with lots of wrap functions. Notepad was internally just an elm_entry with a scroll, so using a scrolled entry with a file set will do the job. I've added a test called Entry Notepad that looks like the removed Notepad test. But we will see the improvements - you can clear the entry or whatever you want, because the entry is the object you are creating. If you were using elm_notepad before, just s/notepad/scrolled_entry and almost everything should work fine. Another change was the function file_save(obj, file, format), is now just file_save(obj), and the file and format used are defined by file_set(). At last, some getters were added. SVN revision: 54145 --- legacy/elementary/src/bin/Makefile.am | 1 - legacy/elementary/src/bin/test.c | 4 +- legacy/elementary/src/bin/test_entry.c | 56 +++ legacy/elementary/src/bin/test_notepad.c | 100 ----- .../elementary/src/edje_externals/Makefile.am | 1 - .../src/edje_externals/elm_notepad.c | 58 --- .../elementary/src/edje_externals/modules.inc | 1 - legacy/elementary/src/lib/Elementary.h.in | 29 +- legacy/elementary/src/lib/Makefile.am | 1 - legacy/elementary/src/lib/elc_notepad.c | 399 ------------------ .../elementary/src/lib/elc_scrolled_entry.c | 89 ++++ legacy/elementary/src/lib/elm_entry.c | 295 ++++++++++++- 12 files changed, 451 insertions(+), 583 deletions(-) delete mode 100644 legacy/elementary/src/bin/test_notepad.c delete mode 100644 legacy/elementary/src/edje_externals/elm_notepad.c delete mode 100644 legacy/elementary/src/lib/elc_notepad.c diff --git a/legacy/elementary/src/bin/Makefile.am b/legacy/elementary/src/bin/Makefile.am index 6bd05a11c9..d3b49742aa 100644 --- a/legacy/elementary/src/bin/Makefile.am +++ b/legacy/elementary/src/bin/Makefile.am @@ -45,7 +45,6 @@ test_clock.c \ test_layout.c \ test_hover.c \ test_entry.c \ -test_notepad.c \ test_anchorview.c \ test_anchorblock.c \ test_toolbar.c \ diff --git a/legacy/elementary/src/bin/test.c b/legacy/elementary/src/bin/test.c index cb374a9a4f..4e737f289c 100644 --- a/legacy/elementary/src/bin/test.c +++ b/legacy/elementary/src/bin/test.c @@ -37,7 +37,7 @@ void test_entry_scrolled(void *data, Evas_Object *obj, void *event_info); void test_entry3(void *data, Evas_Object *obj, void *event_info); void test_entry4(void *data, Evas_Object *obj, void *event_info); void test_entry5(void *data, Evas_Object *obj, void *event_info); -void test_notepad(void *data, Evas_Object *obj, void *event_info); +void test_entry_notepad(void *data, Evas_Object *obj, void *event_info); void test_anchorview(void *data, Evas_Object *obj, void *event_info); void test_anchorblock(void *data, Evas_Object *obj, void *event_info); void test_toolbar(void *data, Evas_Object *obj, void *event_info); @@ -270,7 +270,7 @@ my_win_main(char *autorun) ADD_TEST("Entry 3", test_entry3); ADD_TEST("Entry 4", test_entry4); ADD_TEST("Entry 5", test_entry5); - ADD_TEST("Notepad", test_notepad); + ADD_TEST("Entry Notepad", test_entry_notepad); ADD_TEST("Anchorview", test_anchorview); ADD_TEST("Anchorblock", test_anchorblock); ADD_TEST("Toolbar", test_toolbar); diff --git a/legacy/elementary/src/bin/test_entry.c b/legacy/elementary/src/bin/test_entry.c index e41624d72d..4421148cad 100644 --- a/legacy/elementary/src/bin/test_entry.c +++ b/legacy/elementary/src/bin/test_entry.c @@ -1580,4 +1580,60 @@ test_entry5(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info elm_object_focus(win); evas_object_show(win); } + +static void +_scrolled_entry_clear(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Evas_Object *en = data; + elm_scrolled_entry_entry_set(en, ""); +} + +void +test_entry_notepad(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) +{ + Evas_Object *win, *bg, *bx, *bx2, *bt, *np; + + win = elm_win_add(NULL, "entry-notepad", ELM_WIN_BASIC); + elm_win_title_set(win, "Entry Notepad"); + elm_win_autodel_set(win, EINA_TRUE); + + bg = elm_bg_add(win); + elm_win_resize_object_add(win, bg); + evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(bg); + + bx = elm_box_add(win); + evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, bx); + evas_object_show(bx); + + np = elm_scrolled_entry_add(win); + elm_scrolled_entry_file_set(np, "note.txt", ELM_TEXT_FORMAT_PLAIN_UTF8); + evas_object_size_hint_weight_set(np, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(np, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_box_pack_end(bx, np); + evas_object_show(np); + + bx2 = elm_box_add(win); + elm_box_horizontal_set(bx2, EINA_TRUE); + elm_box_homogenous_set(bx2, EINA_TRUE); + evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL); + + bt = elm_button_add(win); + elm_button_label_set(bt, "Clear"); + evas_object_smart_callback_add(bt, "clicked", _scrolled_entry_clear, np); + evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0); + elm_box_pack_end(bx2, bt); + evas_object_show(bt); + + elm_box_pack_end(bx, bx2); + evas_object_show(bx2); + + evas_object_resize(win, 320, 300); + + elm_object_focus(win); + evas_object_show(win); +} #endif diff --git a/legacy/elementary/src/bin/test_notepad.c b/legacy/elementary/src/bin/test_notepad.c deleted file mode 100644 index c687d3cd14..0000000000 --- a/legacy/elementary/src/bin/test_notepad.c +++ /dev/null @@ -1,100 +0,0 @@ -#include -#ifdef HAVE_CONFIG_H -# include "elementary_config.h" -#endif -#ifndef ELM_LIB_QUICKLAUNCH -static void -my_notepad_bt_1(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) -{ -// Evas_Object *np = data; -} - -static void -my_notepad_bt_2(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) -{ -// Evas_Object *np = data; -} - -static void -my_notepad_bt_3(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) -{ -// Evas_Object *np = data; -} - -void -test_notepad(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) -{ - Evas_Object *win, *bg, *bx, *bx2, *bt, *ic, *np; - - win = elm_win_add(NULL, "notepad", ELM_WIN_BASIC); - elm_win_title_set(win, "Notepad"); - elm_win_autodel_set(win, 1); - - bg = elm_bg_add(win); - elm_win_resize_object_add(win, bg); - evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_show(bg); - - bx = elm_box_add(win); - evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - elm_win_resize_object_add(win, bx); - evas_object_show(bx); - - np = elm_notepad_add(win); - elm_notepad_file_set(np, "note.txt", ELM_TEXT_FORMAT_PLAIN_UTF8); - evas_object_size_hint_weight_set(np, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(np, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_box_pack_end(bx, np); - evas_object_show(np); - - bx2 = elm_box_add(win); - elm_box_horizontal_set(bx2, 1); - elm_box_homogenous_set(bx2, 1); - evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0.0); - evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, EVAS_HINT_FILL); - - bt = elm_button_add(win); - ic = elm_icon_add(win); - elm_icon_standard_set(ic, "arrow_left"); - elm_icon_scale_set(ic, 1, 0); - elm_button_icon_set(bt, ic); - evas_object_show(ic); - evas_object_smart_callback_add(bt, "clicked", my_notepad_bt_1, np); - evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0); - elm_box_pack_end(bx2, bt); - evas_object_show(bt); - - bt = elm_button_add(win); - ic = elm_icon_add(win); - elm_icon_standard_set(ic, "close"); - elm_icon_scale_set(ic, 1, 0); - elm_button_icon_set(bt, ic); - evas_object_show(ic); - evas_object_smart_callback_add(bt, "clicked", my_notepad_bt_2, np); - evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0); - elm_box_pack_end(bx2, bt); - evas_object_show(bt); - - bt = elm_button_add(win); - ic = elm_icon_add(win); - elm_icon_standard_set(ic, "arrow_right"); - elm_icon_scale_set(ic, 1, 0); - elm_button_icon_set(bt, ic); - evas_object_show(ic); - evas_object_smart_callback_add(bt, "clicked", my_notepad_bt_3, np); - evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL); - evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0); - elm_box_pack_end(bx2, bt); - evas_object_show(bt); - - elm_box_pack_end(bx, bx2); - evas_object_show(bx2); - - evas_object_resize(win, 320, 300); - - elm_object_focus(win); - evas_object_show(win); -} -#endif diff --git a/legacy/elementary/src/edje_externals/Makefile.am b/legacy/elementary/src/edje_externals/Makefile.am index 048f96c81a..af1998e23c 100644 --- a/legacy/elementary/src/edje_externals/Makefile.am +++ b/legacy/elementary/src/edje_externals/Makefile.am @@ -41,7 +41,6 @@ elm_genlist.c \ elm_hoversel.c \ elm_list.c \ elm_map.c \ -elm_notepad.c \ elm_photocam.c \ elm_progressbar.c \ elm_radio.c \ diff --git a/legacy/elementary/src/edje_externals/elm_notepad.c b/legacy/elementary/src/edje_externals/elm_notepad.c deleted file mode 100644 index 622b0d8a8b..0000000000 --- a/legacy/elementary/src/edje_externals/elm_notepad.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "private.h" - - -static void -external_notepad_state_set(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const void *from_params __UNUSED__, const void *to_params __UNUSED__, float pos __UNUSED__) -{ - /* TODO: to be expanded */ -} - -static Eina_Bool -external_notepad_param_set(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Edje_External_Param *param) -{ - /* TODO: to be expanded */ - - ERR("unknown parameter '%s' of type '%s'", - param->name, edje_external_param_type_str(param->type)); - - return EINA_FALSE; -} - -static Eina_Bool -external_notepad_param_get(void *data __UNUSED__, const Evas_Object *obj __UNUSED__, Edje_External_Param *param) -{ - /* TODO: to be expanded */ - - ERR("unknown parameter '%s' of type '%s'", - param->name, edje_external_param_type_str(param->type)); - - return EINA_FALSE; -} - -static void * -external_notepad_params_parse(void *data __UNUSED__, Evas_Object *obj __UNUSED__, const Eina_List *params __UNUSED__) -{ - /* TODO: to be expanded */ - - return NULL; -} - -static Evas_Object *external_notepad_content_get(void *data __UNUSED__, - const Evas_Object *obj __UNUSED__, const char *content __UNUSED__) -{ - ERR("No content."); - return NULL; -} - -static void -external_notepad_params_free(void *params __UNUSED__) -{ -} - -static Edje_External_Param_Info external_notepad_params[] = { - DEFINE_EXTERNAL_COMMON_PARAMS, - EDJE_EXTERNAL_PARAM_INFO_SENTINEL -}; - -DEFINE_EXTERNAL_ICON_ADD(notepad, "notepad") -DEFINE_EXTERNAL_TYPE_SIMPLE(notepad, "Notepad"); diff --git a/legacy/elementary/src/edje_externals/modules.inc b/legacy/elementary/src/edje_externals/modules.inc index 3311f183ca..8c75bf930d 100644 --- a/legacy/elementary/src/edje_externals/modules.inc +++ b/legacy/elementary/src/edje_externals/modules.inc @@ -11,7 +11,6 @@ DEFINE_TYPE(genlist) DEFINE_TYPE(hoversel) DEFINE_TYPE(list) DEFINE_TYPE(map) -DEFINE_TYPE(notepad) DEFINE_TYPE(photocam) DEFINE_TYPE(progressbar) DEFINE_TYPE(radio) diff --git a/legacy/elementary/src/lib/Elementary.h.in b/legacy/elementary/src/lib/Elementary.h.in index d7c235b092..c366a58b9b 100644 --- a/legacy/elementary/src/lib/Elementary.h.in +++ b/legacy/elementary/src/lib/Elementary.h.in @@ -265,6 +265,12 @@ extern "C" { ELM_FOCUS_NEXT } Elm_Focus_Direction; + typedef enum _Elm_Text_Format + { + ELM_TEXT_FORMAT_PLAIN_UTF8, + ELM_TEXT_FORMAT_MARKUP_UTF8 + } Elm_Text_Format; + /** * Called back when a widget's tooltip is activated and needs content. * @param data user-data given to elm_object_tooltip_content_cb_set() @@ -1099,6 +1105,11 @@ extern "C" { EAPI void elm_entry_text_filter_remove(Evas_Object *obj, void (*func) (void *data, Evas_Object *entry, char **text), void *data); EAPI char *elm_entry_markup_to_utf8(const char *s); EAPI char *elm_entry_utf8_to_markup(const char *s); + EAPI void elm_entry_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format); + EAPI void elm_entry_file_get(const Evas_Object *obj, const char **file, Elm_Text_Format *format); + EAPI void elm_entry_file_save(Evas_Object *obj); + EAPI void elm_entry_autosave_set(Evas_Object *obj, Eina_Bool autosave); + EAPI Eina_Bool elm_entry_autosave_get(Evas_Object *obj); /* pre-made filters for entries */ typedef struct _Elm_Entry_Filter_Limit_Size Elm_Entry_Filter_Limit_Size; struct _Elm_Entry_Filter_Limit_Size @@ -1135,19 +1146,6 @@ extern "C" { /* composite widgets - these basically put together basic widgets above * in convenient packages that do more than basic stuff */ - typedef enum _Elm_Text_Format - { - ELM_TEXT_FORMAT_PLAIN_UTF8, - ELM_TEXT_FORMAT_MARKUP_UTF8 - } Elm_Text_Format; - EAPI Evas_Object *elm_notepad_add(Evas_Object *parent); - EAPI void elm_notepad_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format); - EAPI void elm_notepad_file_save(Evas_Object *obj, const char *file, Elm_Text_Format format); - EAPI void elm_notepad_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce); - EAPI void elm_notepad_autosave_set(Evas_Object *obj, Eina_Bool autosave); - - /* smart callbacks called: - */ typedef struct _Elm_Entry_Anchorview_Info Elm_Entry_Anchorview_Info; struct _Elm_Entry_Anchorview_Info @@ -2073,6 +2071,11 @@ extern "C" { EAPI void elm_scrolled_entry_text_filter_append(Evas_Object *obj, void (*func) (void *data, Evas_Object *entry, char **text), void *data); EAPI void elm_scrolled_entry_text_filter_prepend(Evas_Object *obj, void (*func) (void *data, Evas_Object *entry, char **text), void *data); EAPI void elm_scrolled_entry_text_filter_remove(Evas_Object *obj, void (*func) (void *data, Evas_Object *entry, char **text), void *data); + EAPI void elm_scrolled_entry_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format); + EAPI void elm_scrolled_entry_file_get(const Evas_Object *obj, const char **file, Elm_Text_Format *format); + EAPI void elm_scrolled_entry_file_save(Evas_Object *obj); + EAPI void elm_scrolled_entry_autosave_set(Evas_Object *obj, Eina_Bool autosave); + EAPI Eina_Bool elm_scrolled_entry_autosave_get(Evas_Object *obj); EAPI Evas_Object *elm_conformant_add(Evas_Object *parent); EAPI void elm_conformant_content_set(Evas_Object *obj, Evas_Object *content); diff --git a/legacy/elementary/src/lib/Makefile.am b/legacy/elementary/src/lib/Makefile.am index cefe1da336..3d5bddae9b 100644 --- a/legacy/elementary/src/lib/Makefile.am +++ b/legacy/elementary/src/lib/Makefile.am @@ -95,7 +95,6 @@ elc_fileselector_button.c \ elc_fileselector_entry.c \ elc_hoversel.c \ elc_hoverlist.c \ -elc_notepad.c \ elc_scrolled_entry.c \ \ els_tooltip.c \ diff --git a/legacy/elementary/src/lib/elc_notepad.c b/legacy/elementary/src/lib/elc_notepad.c deleted file mode 100644 index 5ecf6f706f..0000000000 --- a/legacy/elementary/src/lib/elc_notepad.c +++ /dev/null @@ -1,399 +0,0 @@ -#include -#include "elm_priv.h" -/** - * @defgroup Notepad Notepad - * - * The notepad is an object for quickly loading a text file, displaying it, - * allowing editing of it and saving of changes back to the file loaded. - * - * Signals that you can add callbacks for are: - * - * NONE - * - * A notepad object contains a scroller and an entry. It is a convenience - * widget that loads a text file indicated, puts it in the scrollable entry - * and allows the user to edit it. Changes are written back to the original - * file after a short delay. The file to load and save to is specified by - * elm_notepad_file_set(). - */ -typedef struct _Widget_Data Widget_Data; - -struct _Widget_Data -{ - Evas_Object *scr, *entry; - const char *file; - Elm_Text_Format format; - Ecore_Timer *delay_write; - Eina_Bool can_write : 1; - Eina_Bool autosave : 1; -}; - -static const char *widtype = NULL; -static void _del_hook(Evas_Object *obj); -static void _sizing_eval(Evas_Object *obj); -static void _on_focus_hook(void *data, Evas_Object *obj); -static void _load(Evas_Object *obj); -static void _save(Evas_Object *obj); - -static void -_del_hook(Evas_Object *obj) -{ - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - if (wd->file) eina_stringshare_del(wd->file); - if (wd->delay_write) - { - ecore_timer_del(wd->delay_write); - if (wd->autosave) _save(obj); - } - free(wd); -} - -static void -_sizing_eval(Evas_Object *obj) -{ - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - evas_object_size_hint_min_set(obj, -1, -1); - evas_object_size_hint_max_set(obj, -1, -1); -} - -static void -_on_focus_hook(void *data __UNUSED__, Evas_Object *obj) -{ - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - if (elm_widget_focus_get(obj)) - elm_widget_focus_steal(wd->entry); -} - -static char * -_buf_append(char *buf, const char *str, int *len, int *alloc) -{ - int len2 = strlen(str); - if ((*len + len2) >= *alloc) - { - char *buf2 = realloc(buf, *alloc + len2 + 512); - if (!buf2) return NULL; - buf = buf2; - *alloc += (512 + len2); - } - strcpy(buf + *len, str); - *len += len2; - return buf; -} - -static char * -_load_file(const char *file) -{ - FILE *f; - size_t size; - int alloc = 0, len = 0; - char *text = NULL, buf[PATH_MAX]; - - f = fopen(file, "rb"); - if (!f) return NULL; - while ((size = fread(buf, 1, sizeof(buf), f))) - { - buf[size] = 0; - text = _buf_append(text, buf, &len, &alloc); - } - fclose(f); - return text; -} - -static char * -_load_plain(const char *file) -{ - char *text; - - text = _load_file(file); - if (text) - { - char *text2; - - text2 = elm_entry_utf8_to_markup(text); - free(text); - return text2; - } - return NULL; -} - -static void -_load(Evas_Object *obj) -{ - Widget_Data *wd = elm_widget_data_get(obj); - char *text; - if (!wd) return; - if (!wd->file) - { - elm_entry_entry_set(wd->entry, ""); - return; - } - switch (wd->format) - { - case ELM_TEXT_FORMAT_PLAIN_UTF8: - text = _load_plain(wd->file); - break; - case ELM_TEXT_FORMAT_MARKUP_UTF8: - text = _load_file(wd->file); - break; - default: - text = NULL; - break; - } - if (text) - { - elm_entry_entry_set(wd->entry, text); - free(text); - } - else - elm_entry_entry_set(wd->entry, ""); -} - -static void -_save_markup_utf8(const char *file, const char *text) -{ - FILE *f; - - if ((!text) || (!text[0])) - { - ecore_file_unlink(file); - return; - } - f = fopen(file, "wb"); - if (!f) - { - // FIXME: report a write error - return; - } - fputs(text, f); // FIXME: catch error - fclose(f); -} - -static void -_save_plain_utf8(const char *file, const char *text) -{ - char *text2; - - text2 = elm_entry_markup_to_utf8(text); - if (text2) - { - _save_markup_utf8(file, text2); - free(text2); - } -} - -static void -_save(Evas_Object *obj) -{ - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - if (!wd->file) return; - switch (wd->format) - { - case ELM_TEXT_FORMAT_PLAIN_UTF8: - _save_plain_utf8(wd->file, elm_entry_entry_get(wd->entry)); - break; - case ELM_TEXT_FORMAT_MARKUP_UTF8: - _save_markup_utf8(wd->file, elm_entry_entry_get(wd->entry)); - break; - default: - break; - } -} - -static Eina_Bool -_delay_write(void *data) -{ - Widget_Data *wd = elm_widget_data_get(data); - if (!wd) return ECORE_CALLBACK_CANCEL; - _save(data); - wd->delay_write = NULL; - return ECORE_CALLBACK_CANCEL; -} - -static void -_entry_changed(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) -{ - Widget_Data *wd = elm_widget_data_get(data); - if (!wd) return; - if (wd->delay_write) - { - ecore_timer_del(wd->delay_write); - wd->delay_write = NULL; - } - if (!wd->autosave) return; - wd->delay_write = ecore_timer_add(2.0, _delay_write, data); -} - -static void -_hold_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) -{ - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - elm_widget_scroll_hold_push(wd->scr); -} - -static void -_hold_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) -{ - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - elm_widget_scroll_hold_pop(wd->scr); -} - -static void -_freeze_on(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) -{ - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - elm_widget_scroll_hold_push(wd->scr); -} - -static void -_freeze_off(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) -{ - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - elm_widget_scroll_hold_pop(wd->scr); -} - -/** - * Add a new notepad to the parent - * - * @param parent The parent object - * @return The new object or NULL if it cannot be created - * - * @ingroup Notepad - */ -EAPI Evas_Object * -elm_notepad_add(Evas_Object *parent) -{ - Evas_Object *obj; - Evas *e; - Widget_Data *wd; - - wd = ELM_NEW(Widget_Data); - e = evas_object_evas_get(parent); - obj = elm_widget_add(e); - ELM_SET_WIDTYPE(widtype, "notepad"); - elm_widget_type_set(obj, "notepad"); - elm_widget_sub_object_add(parent, obj); - elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); - elm_widget_data_set(obj, wd); - elm_widget_del_hook_set(obj, _del_hook); - elm_widget_can_focus_set(obj, EINA_TRUE); - - wd->scr = elm_scroller_add(parent); - elm_widget_resize_object_set(obj, wd->scr); - - wd->entry = elm_entry_add(parent); - evas_object_size_hint_weight_set(wd->entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(wd->entry, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_scroller_content_set(wd->scr, wd->entry); - evas_object_show(wd->entry); - - elm_entry_entry_set(wd->entry, ""); - evas_object_smart_callback_add(wd->entry, "changed", _entry_changed, obj); - - evas_object_smart_callback_add(obj, "scroll-hold-on", _hold_on, obj); - evas_object_smart_callback_add(obj, "scroll-hold-off", _hold_off, obj); - evas_object_smart_callback_add(obj, "scroll-freeze-on", _freeze_on, obj); - evas_object_smart_callback_add(obj, "scroll-freeze-off", _freeze_off, obj); - - wd->autosave = EINA_TRUE; - - _sizing_eval(obj); - return obj; -} - -/** - * This sets the file (and implicitly loads it) for the text to display and - * then edit. All changes are written back to the file after a short delay if - * the notepad object is set to autosave. - * - * @param obj The notepad object - * @param file The path to the file to load and save - * @param format The file format - * - * @ingroup Notepad - */ -EAPI void -elm_notepad_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format) -{ - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - if (wd->delay_write) - { - ecore_timer_del(wd->delay_write); - wd->delay_write = NULL; - } - if (wd->autosave) _save(obj); - eina_stringshare_replace(&wd->file, file); - wd->format = format; - _load(obj); -} - -/** - * This function writes any changes made to the file. - * All changes are written back to the file after a short delay. - * - * @param obj The notepad object - * @param file The path to the file to save - * @param format The file format - * - * @ingroup Notepad - */ -EAPI void -elm_notepad_file_save(Evas_Object *obj, const char *file, Elm_Text_Format format) -{ - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if ((!wd) || (!file)) return; - if (wd->delay_write) - { - ecore_timer_del(wd->delay_write); - wd->delay_write = NULL; - } - wd->format = format; - eina_stringshare_replace(&wd->file, file); - wd->delay_write = ecore_timer_add(2.0, _delay_write, obj); -} - -/** - * This will enable or disable the scroller bounce mode for the notepad. See - * elm_scroller_bounce_set() for details - * - * @param obj The notepad object - * @param h_bounce Allow bounce horizontally - * @param v_bounce Allow bounce vertically - * - * @ingroup Notepad - */ -EAPI void -elm_notepad_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce) -{ - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - elm_scroller_bounce_set(wd->scr, h_bounce, v_bounce); -} - -/** - * This sets the notepad object to 'autosave' the loaded text file or not. - * - * @param obj The notepad object - * @param autosave Autosave the loaded file or not - * - * @ingroup Notepad - */ -EAPI void -elm_notepad_autosave_set(Evas_Object *obj, Eina_Bool autosave) -{ - ELM_CHECK_WIDTYPE(obj, widtype); - Widget_Data *wd = elm_widget_data_get(obj); - if (!wd) return; - wd->autosave = autosave; -} diff --git a/legacy/elementary/src/lib/elc_scrolled_entry.c b/legacy/elementary/src/lib/elc_scrolled_entry.c index 412ca722d0..40ff051705 100644 --- a/legacy/elementary/src/lib/elc_scrolled_entry.c +++ b/legacy/elementary/src/lib/elc_scrolled_entry.c @@ -1475,3 +1475,92 @@ elm_scrolled_entry_text_filter_remove(Evas_Object *obj, void (*func) (void *data } } } + +/** + * This sets the file (and implicitly loads it) for the text to display and + * then edit. All changes are written back to the file after a short delay if + * the entry object is set to autosave. + * + * @param obj The scrolled entry object + * @param file The path to the file to load and save + * @param format The file format + * + * @ingroup Scrolled_Entry + */ +EAPI void +elm_scrolled_entry_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_entry_file_set(wd->entry, file, format); +} + +/** + * Gets the file to load and save and the file format + * + * @param obj The scrolled entry object + * @param file The path to the file to load and save + * @param format The file format + * + * @ingroup Scrolled_Entry + */ +EAPI void +elm_scrolled_entry_file_get(const Evas_Object *obj, const char **file, Elm_Text_Format *format) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_entry_file_get(wd->entry, file, format); +} + +/** + * This function writes any changes made to the file set with + * elm_scrolled_entry_file_set() + * + * @param obj The scrolled entry object + * + * @ingroup Scrolled_Entry + */ +EAPI void +elm_scrolled_entry_file_save(Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_entry_file_save(wd->entry); +} + +/** + * This sets the entry object to 'autosave' the loaded text file or not. + * + * @param obj The scrolled entry object + * @param autosave Autosave the loaded file or not + * + * @ingroup Scrolled_Entry + */ +EAPI void +elm_scrolled_entry_autosave_set(Evas_Object *obj, Eina_Bool autosave) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + elm_entry_autosave_set(wd->entry, autosave); +} + +/** + * This gets the entry object's 'autosave' status. + * + * @param obj The scrolled entry object + * @return Autosave the loaded file or not + * + * @ingroup Scrolled_Entry + */ +EAPI Eina_Bool +elm_scrolled_entry_autosave_get(Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return elm_entry_autosave_get(wd->entry); +} diff --git a/legacy/elementary/src/lib/elm_entry.c b/legacy/elementary/src/lib/elm_entry.c index 6fbbfca9a8..41040ce25b 100644 --- a/legacy/elementary/src/lib/elm_entry.c +++ b/legacy/elementary/src/lib/elm_entry.c @@ -11,15 +11,15 @@ * input. Entry widgets are capable of expanding past the * boundaries of the window, thus resizing the window to its * own length. - * + * * You can also insert "items" in the entry with: - * + * * \\ - * + * * for example. sizing can be set bu size=WxH, relsize=WxH or absize=WxH with * vsize=ascent or vsize=full. the href=NAME sets the item name. Entry * supports a list of emoticon names by default. These are: - * + * * - emoticon/angry * - emoticon/angry-shout * - emoticon/crazy-laugh @@ -64,9 +64,14 @@ * These are built-in currently, but you can add your own item provieer that * can create inlined objects in the text and fill the space allocated to the * item with a custom object of your own. - * + * * See the entry test for some more examples of use of this. - * + * + * Entries have functions to load a text file, display it, + * allowing editing of it and saving of changes back to the file loaded. + * Changes are written back to the original file after a short delay. + * The file to load and save to is specified by elm_entry_file_set(). + * * Signals that you can add callbacks for are: * - "changed" - The text within the entry was changed * - "activated" - The entry has had editing finished and changes are to be committed (generally when enter key is pressed) @@ -101,9 +106,12 @@ struct _Widget_Data Ecore_Event_Handler *sel_notify_handler; Ecore_Event_Handler *sel_clear_handler; Ecore_Timer *longpress_timer; + Ecore_Timer *delay_write; /* Only for clipboard */ const char *cut_sel; const char *text; + const char *file; + Elm_Text_Format format; Evas_Coord lastw; Evas_Coord downx, downy; Evas_Coord cx, cy, cw, ch; @@ -125,6 +133,8 @@ struct _Widget_Data Eina_Bool disabled : 1; Eina_Bool context_menu : 1; Eina_Bool drag_selection_asked : 1; + Eina_Bool can_write : 1; + Eina_Bool autosave : 1; }; struct _Elm_Entry_Context_Menu_Item @@ -233,6 +243,164 @@ _module(Evas_Object *obj __UNUSED__) return m->api; } +static char * +_buf_append(char *buf, const char *str, int *len, int *alloc) +{ + int len2 = strlen(str); + if ((*len + len2) >= *alloc) + { + char *buf2 = realloc(buf, *alloc + len2 + 512); + if (!buf2) return NULL; + buf = buf2; + *alloc += (512 + len2); + } + strcpy(buf + *len, str); + *len += len2; + return buf; +} + +static char * +_load_file(const char *file) +{ + FILE *f; + size_t size; + int alloc = 0, len = 0; + char *text = NULL, buf[PATH_MAX]; + + f = fopen(file, "rb"); + if (!f) return NULL; + while ((size = fread(buf, 1, sizeof(buf), f))) + { + buf[size] = 0; + text = _buf_append(text, buf, &len, &alloc); + } + fclose(f); + return text; +} + +static char * +_load_plain(const char *file) +{ + char *text; + + text = _load_file(file); + if (text) + { + char *text2; + + text2 = elm_entry_utf8_to_markup(text); + free(text); + return text2; + } + return NULL; +} + +static void +_load(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + char *text; + if (!wd) return; + if (!wd->file) + { + elm_entry_entry_set(obj, ""); + return; + } + switch (wd->format) + { + case ELM_TEXT_FORMAT_PLAIN_UTF8: + text = _load_plain(wd->file); + break; + case ELM_TEXT_FORMAT_MARKUP_UTF8: + text = _load_file(wd->file); + break; + default: + text = NULL; + break; + } + if (text) + { + elm_entry_entry_set(obj, text); + free(text); + } + else + elm_entry_entry_set(obj, ""); +} + +static void +_save_markup_utf8(const char *file, const char *text) +{ + FILE *f; + + if ((!text) || (!text[0])) + { + ecore_file_unlink(file); + return; + } + f = fopen(file, "wb"); + if (!f) + { + // FIXME: report a write error + return; + } + fputs(text, f); // FIXME: catch error + fclose(f); +} + +static void +_save_plain_utf8(const char *file, const char *text) +{ + char *text2; + + text2 = elm_entry_markup_to_utf8(text); + if (!text2) + return; + _save_markup_utf8(file, text2); + free(text2); +} + +static void +_save(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (!wd->file) return; + switch (wd->format) + { + case ELM_TEXT_FORMAT_PLAIN_UTF8: + _save_plain_utf8(wd->file, elm_entry_entry_get(obj)); + break; + case ELM_TEXT_FORMAT_MARKUP_UTF8: + _save_markup_utf8(wd->file, elm_entry_entry_get(obj)); + break; + default: + break; + } +} + +static Eina_Bool +_delay_write(void *data) +{ + Widget_Data *wd = elm_widget_data_get(data); + if (!wd) return ECORE_CALLBACK_CANCEL; + _save(data); + wd->delay_write = NULL; + return ECORE_CALLBACK_CANCEL; +} + +static void +_del_pre_hook(Evas_Object *obj) +{ + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->delay_write) + { + ecore_timer_del(wd->delay_write); + wd->delay_write = NULL; + if (wd->autosave) _save(obj); + } +} + static void _del_hook(Evas_Object *obj) { @@ -241,6 +409,8 @@ _del_hook(Evas_Object *obj) Elm_Entry_Item_Provider *ip; Elm_Entry_Text_Filter *tf; + if (wd->file) eina_stringshare_del(wd->file); + if (wd->hovdeljob) ecore_job_del(wd->hovdeljob); if ((wd->api) && (wd->api->obj_unhook)) wd->api->obj_unhook(obj); // module - unhook @@ -967,6 +1137,13 @@ _signal_entry_changed(void *data, Evas_Object *obj __UNUSED__, const char *emiss if (wd->text) eina_stringshare_del(wd->text); wd->text = NULL; evas_object_smart_callback_call(data, SIG_CHANGED, NULL); + if (wd->delay_write) + { + ecore_timer_del(wd->delay_write); + wd->delay_write = NULL; + } + if ((!wd->autosave) || (!wd->file)) return; + wd->delay_write = ecore_timer_add(2.0, _delay_write, data); } static void @@ -1386,6 +1563,7 @@ elm_entry_add(Evas_Object *parent) elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); elm_widget_data_set(obj, wd); elm_widget_del_hook_set(obj, _del_hook); + elm_widget_del_pre_hook_set(obj, _del_pre_hook); elm_widget_theme_hook_set(obj, _theme_hook); elm_widget_disable_hook_set(obj, _disable_hook); elm_widget_signal_emit_hook_set(obj, _signal_emit_hook); @@ -1401,6 +1579,7 @@ elm_entry_add(Evas_Object *parent) wd->editable = EINA_TRUE; wd->disabled = EINA_FALSE; wd->context_menu = EINA_TRUE; + wd->autosave = EINA_TRUE; wd->ent = edje_object_add(e); edje_object_item_provider_set(wd->ent, _get_item, obj); @@ -2548,4 +2727,106 @@ elm_entry_filter_accept_set(void *data, Evas_Object *entry __UNUSED__, char **te *insert = 0; } -/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/ +/** + * This sets the file (and implicitly loads it) for the text to display and + * then edit. All changes are written back to the file after a short delay if + * the entry object is set to autosave. + * + * @param obj The entry object + * @param file The path to the file to load and save + * @param format The file format + * + * @ingroup Entry + */ +EAPI void +elm_entry_file_set(Evas_Object *obj, const char *file, Elm_Text_Format format) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->delay_write) + { + ecore_timer_del(wd->delay_write); + wd->delay_write = NULL; + } + if (wd->autosave) _save(obj); + eina_stringshare_replace(&wd->file, file); + wd->format = format; + _load(obj); +} + +/** + * Gets the file to load and save and the file format + * + * @param obj The entry object + * @param file The path to the file to load and save + * @param format The file format + * + * @ingroup Entry + */ +EAPI void +elm_entry_file_get(const Evas_Object *obj, const char **file, Elm_Text_Format *format) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (file) *file = wd->file; + if (format) *format = wd->format; +} + +/** + * This function writes any changes made to the file set with + * elm_entry_file_set() + * + * @param obj The entry object + * + * @ingroup Entry + */ +EAPI void +elm_entry_file_save(Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + if (wd->delay_write) + { + ecore_timer_del(wd->delay_write); + wd->delay_write = NULL; + } + _save(obj); + wd->delay_write = ecore_timer_add(2.0, _delay_write, obj); +} + +/** + * This sets the entry object to 'autosave' the loaded text file or not. + * + * @param obj The entry object + * @param autosave Autosave the loaded file or not + * + * @ingroup Entry + */ +EAPI void +elm_entry_autosave_set(Evas_Object *obj, Eina_Bool autosave) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return; + wd->autosave = !!autosave; +} + +/** + * This gets the entry object's 'autosave' status. + * + * @param obj The entry object + * @return Autosave the loaded file or not + * + * @ingroup Entry + */ +EAPI Eina_Bool +elm_entry_autosave_get(Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return EINA_FALSE; + return wd->autosave; +}