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
This commit is contained in:
Bruno Dilly 2010-11-04 11:56:15 +00:00
parent eff9c70829
commit 81b68b08a9
12 changed files with 451 additions and 583 deletions

View File

@ -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 \

View File

@ -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);

View File

@ -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

View File

@ -1,100 +0,0 @@
#include <Elementary.h>
#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

View File

@ -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 \

View File

@ -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");

View File

@ -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)

View File

@ -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);

View File

@ -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 \

View File

@ -1,399 +0,0 @@
#include <Elementary.h>
#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;
}

View File

@ -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);
}

View File

@ -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:
*
*
* \<item size=16x16 vsize=full href=emoticon/haha\>\</item\>
*
*
* 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;
}