2014-04-30 15:06:16 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Search for text within an entry based on what is entered into a search dialog
|
|
|
|
*
|
|
|
|
* Based largely on code in Ecrire by Tom Hacohen <tom@stosb.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <Elementary.h>
|
|
|
|
#include <Evas.h>
|
|
|
|
|
|
|
|
#include "edi_editor.h"
|
|
|
|
#include "edi_private.h"
|
|
|
|
|
2030-07-12 13:12:05 -07:00
|
|
|
/**
|
|
|
|
* @struct _Edi_Editor_Search
|
|
|
|
* An instance of an editor view search session.
|
|
|
|
*/
|
|
|
|
struct _Edi_Editor_Search
|
|
|
|
{
|
|
|
|
Evas_Object *entry; /**< The search text widget */
|
|
|
|
Evas_Object *widget; /**< The search UI panel we wish to show and hide */
|
2014-07-19 20:28:14 -07:00
|
|
|
Evas_Object *parent; /**< The parent panel we will insert into */
|
2030-07-12 13:12:05 -07:00
|
|
|
Evas_Textblock_Cursor *current_search; /**< The current search cursor for this session */
|
|
|
|
|
|
|
|
/* Add new members here. */
|
|
|
|
};
|
2014-04-30 15:06:16 -07:00
|
|
|
|
|
|
|
static Eina_Bool
|
2030-07-12 13:12:05 -07:00
|
|
|
_search_in_entry(Evas_Object *entry, Edi_Editor_Search *search)
|
2014-04-30 15:06:16 -07:00
|
|
|
{
|
|
|
|
Eina_Bool try_next = EINA_FALSE;
|
2030-07-12 13:12:05 -07:00
|
|
|
const char *found, *text;
|
2014-04-30 15:06:16 -07:00
|
|
|
char *utf8;
|
|
|
|
const Evas_Object *tb = elm_entry_textblock_get(entry);
|
|
|
|
Evas_Textblock_Cursor *end, *start, *mcur;
|
|
|
|
size_t initial_pos;
|
2014-03-15 06:17:24 -07:00
|
|
|
Evas_Coord x, y, w, h;
|
2014-04-30 15:06:16 -07:00
|
|
|
|
2030-07-12 13:12:05 -07:00
|
|
|
text = elm_object_text_get(search->entry);
|
2014-04-30 15:06:16 -07:00
|
|
|
if (!text || !*text)
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
mcur = (Evas_Textblock_Cursor *) evas_object_textblock_cursor_get(tb);
|
2030-07-12 13:12:05 -07:00
|
|
|
if (!search->current_search)
|
2014-04-30 15:06:16 -07:00
|
|
|
{
|
2030-07-12 13:12:05 -07:00
|
|
|
search->current_search = evas_object_textblock_cursor_new(tb);
|
2014-04-30 15:06:16 -07:00
|
|
|
}
|
2030-07-12 13:12:05 -07:00
|
|
|
else if (!evas_textblock_cursor_compare(search->current_search, mcur))
|
2014-04-30 15:06:16 -07:00
|
|
|
{
|
|
|
|
try_next = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2030-07-12 13:12:05 -07:00
|
|
|
evas_textblock_cursor_paragraph_last(search->current_search);
|
2014-04-30 15:06:16 -07:00
|
|
|
start = mcur;
|
2030-07-12 13:12:05 -07:00
|
|
|
end = search->current_search;
|
2014-04-30 15:06:16 -07:00
|
|
|
|
|
|
|
initial_pos = evas_textblock_cursor_pos_get(start);
|
|
|
|
|
|
|
|
utf8 = evas_textblock_cursor_range_text_get(start, end,
|
|
|
|
EVAS_TEXTBLOCK_TEXT_PLAIN);
|
|
|
|
|
|
|
|
if (!utf8)
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
if (try_next)
|
|
|
|
{
|
|
|
|
found = strstr(utf8 + 1, text);
|
|
|
|
if (!found)
|
|
|
|
{
|
|
|
|
found = utf8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
found = strstr(utf8, text);
|
|
|
|
}
|
|
|
|
|
2014-03-15 06:17:24 -07:00
|
|
|
elm_entry_select_none(entry);
|
2014-04-30 15:06:16 -07:00
|
|
|
if (found)
|
|
|
|
{
|
|
|
|
size_t pos = 0;
|
|
|
|
int idx = 0;
|
|
|
|
while ((utf8 + idx) < found)
|
|
|
|
{
|
|
|
|
pos++;
|
|
|
|
eina_unicode_utf8_next_get(utf8, &idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
evas_textblock_cursor_pos_set(mcur, pos + initial_pos + strlen(text));
|
2014-03-15 06:17:24 -07:00
|
|
|
elm_entry_cursor_geometry_get(entry, &w, &h, NULL, NULL);
|
2014-04-30 15:06:16 -07:00
|
|
|
elm_entry_cursor_selection_begin(entry);
|
|
|
|
elm_entry_cursor_pos_set(entry, pos + initial_pos);
|
|
|
|
elm_entry_cursor_selection_end(entry);
|
2014-03-15 06:17:24 -07:00
|
|
|
|
|
|
|
elm_entry_cursor_geometry_get(entry, &x, &y, NULL, NULL);
|
|
|
|
w -= x;
|
|
|
|
h -= y;
|
|
|
|
elm_scroller_region_show(entry, x, y, w, h);
|
2030-07-12 13:12:05 -07:00
|
|
|
evas_textblock_cursor_copy(mcur, search->current_search);
|
2014-04-30 15:06:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
free(utf8);
|
|
|
|
|
|
|
|
return !!found;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2030-07-12 13:12:05 -07:00
|
|
|
_edi_editor_search_hide(Edi_Editor *editor)
|
2014-04-30 15:06:16 -07:00
|
|
|
{
|
2030-07-12 13:12:05 -07:00
|
|
|
Edi_Editor_Search *search;
|
|
|
|
|
|
|
|
search = editor->search;
|
2014-07-19 20:28:14 -07:00
|
|
|
if (search && eina_list_data_find(elm_box_children_get(search->parent), search->widget))
|
|
|
|
{
|
|
|
|
evas_object_hide(search->widget);
|
|
|
|
elm_box_unpack(search->parent, search->widget);
|
|
|
|
}
|
2030-07-12 13:12:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
edi_editor_search(Edi_Editor *editor)
|
|
|
|
{
|
|
|
|
Edi_Editor_Search *search;
|
|
|
|
|
|
|
|
search = editor->search;
|
2014-07-19 20:28:14 -07:00
|
|
|
if (search && !eina_list_data_find(elm_box_children_get(search->parent), search->widget))
|
|
|
|
{
|
|
|
|
evas_object_show(search->widget);
|
|
|
|
elm_box_pack_end(search->parent, search->widget);
|
|
|
|
}
|
2014-04-30 15:06:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2030-07-12 13:12:05 -07:00
|
|
|
_search_clicked(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
2014-04-30 15:06:16 -07:00
|
|
|
{
|
2030-07-12 13:12:05 -07:00
|
|
|
Edi_Editor *editor;
|
|
|
|
Edi_Editor_Search *search;
|
2014-04-30 15:06:16 -07:00
|
|
|
|
2030-07-12 13:12:05 -07:00
|
|
|
editor = (Edi_Editor *)data;
|
|
|
|
search = editor->search;
|
|
|
|
|
|
|
|
if (search)
|
|
|
|
_search_in_entry(editor->entry, search);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cancel_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
|
|
|
{
|
|
|
|
_edi_editor_search_hide((Edi_Editor *)data);
|
2014-04-30 15:06:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2030-07-12 13:12:05 -07:00
|
|
|
edi_editor_search_add(Evas_Object *parent, Edi_Editor *editor)
|
2014-04-30 15:06:16 -07:00
|
|
|
{
|
2014-07-19 20:28:14 -07:00
|
|
|
Evas_Object *entry, *lbl, *btn, *box;
|
2030-07-12 13:12:05 -07:00
|
|
|
Edi_Editor_Search *search;
|
2014-04-30 15:06:16 -07:00
|
|
|
|
2014-07-19 20:28:14 -07:00
|
|
|
box = elm_box_add(parent);
|
|
|
|
elm_box_horizontal_set(box, EINA_TRUE);
|
|
|
|
evas_object_size_hint_align_set(box, EVAS_HINT_FILL, 0.5);
|
|
|
|
evas_object_size_hint_weight_set(box, 0.0, 0.0);
|
|
|
|
elm_box_padding_set(box, 15, 0);
|
2014-04-30 15:06:16 -07:00
|
|
|
|
2014-07-19 20:28:14 -07:00
|
|
|
lbl = elm_label_add(box);
|
2014-04-30 15:06:16 -07:00
|
|
|
elm_object_text_set(lbl, "Search term:");
|
|
|
|
evas_object_size_hint_align_set(lbl, EVAS_HINT_FILL, 0.5);
|
|
|
|
evas_object_size_hint_weight_set(lbl, 0.0, 0.0);
|
2014-07-19 20:28:14 -07:00
|
|
|
elm_box_pack_end(box, lbl);
|
2014-04-30 15:06:16 -07:00
|
|
|
evas_object_show(lbl);
|
|
|
|
|
2014-07-19 20:28:14 -07:00
|
|
|
entry = elm_entry_add(box);
|
2030-07-12 13:12:05 -07:00
|
|
|
elm_entry_scrollable_set(entry, EINA_TRUE);
|
|
|
|
elm_entry_single_line_set(entry, EINA_TRUE);
|
|
|
|
evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, 0.0);
|
|
|
|
evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, 0.0);
|
2014-07-19 20:28:14 -07:00
|
|
|
elm_box_pack_end(box, entry);
|
2030-07-12 13:12:05 -07:00
|
|
|
evas_object_show(entry);
|
|
|
|
|
2014-07-19 20:28:14 -07:00
|
|
|
btn = elm_button_add(box);
|
2014-04-30 15:06:16 -07:00
|
|
|
elm_object_text_set(btn, "Search");
|
|
|
|
evas_object_size_hint_align_set(btn, 1.0, 0.0);
|
|
|
|
evas_object_size_hint_weight_set(btn, 0.0, 0.0);
|
|
|
|
evas_object_show(btn);
|
2014-07-19 20:28:14 -07:00
|
|
|
elm_box_pack_end(box, btn);
|
2030-07-12 13:12:05 -07:00
|
|
|
evas_object_smart_callback_add(btn, "clicked", _search_clicked, editor);
|
2014-04-30 15:06:16 -07:00
|
|
|
|
2014-07-19 20:28:14 -07:00
|
|
|
btn = elm_button_add(box);
|
2030-07-12 13:12:05 -07:00
|
|
|
elm_object_text_set(btn, "Cancel");
|
|
|
|
evas_object_size_hint_align_set(btn, 1.0, 0.0);
|
|
|
|
evas_object_size_hint_weight_set(btn, 0.0, 0.0);
|
|
|
|
evas_object_show(btn);
|
2014-07-19 20:28:14 -07:00
|
|
|
elm_box_pack_end(box, btn);
|
2030-07-12 13:12:05 -07:00
|
|
|
evas_object_smart_callback_add(btn, "clicked", _cancel_clicked, editor);
|
2014-04-30 15:06:16 -07:00
|
|
|
|
2030-07-12 13:12:05 -07:00
|
|
|
search = calloc(1, sizeof(*search));
|
|
|
|
search->entry = entry;
|
2014-07-19 20:28:14 -07:00
|
|
|
search->parent = parent;
|
|
|
|
search->widget = box;
|
2030-07-12 13:12:05 -07:00
|
|
|
editor->search = search;
|
2014-07-19 20:28:14 -07:00
|
|
|
evas_object_show(parent);
|
2014-04-30 15:06:16 -07:00
|
|
|
}
|