multi-file: support quick jump (F5)

if you press F5 on "#include xxxx" line,
Enventor will open that include file.

Conflicts:
	src/lib/edc_parser.c
This commit is contained in:
Hermet Park 2016-07-22 16:13:50 +09:00
parent 8b8aa1fdfe
commit 0462d04c0d
10 changed files with 173 additions and 75 deletions

View File

@ -78,54 +78,7 @@ gl_clicked_double_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
/* Open a double clicked edc file. */
//skip non edc file.
if (!eina_str_has_extension(file->path, "edc")) return;
unsigned int selected_file_len = strlen(file->path);
Enventor_Item *eit;
const char *it_file_path;
//Case 1. main file.
eit = file_mgr_main_item_get();
if (eit)
{
it_file_path = enventor_item_file_get(eit);
if (!it_file_path)
{
EINA_LOG_ERR("No main item file path??");
return;
}
//Ok, This selected file is already openend, let's activate the item.
if (!strcmp(file->name, ecore_file_file_get(it_file_path)))
{
file_mgr_file_focus(eit);
return;
}
}
//Case 2. sub files.
Eina_List *sub_items =
(Eina_List *)enventor_object_sub_items_get(base_enventor_get());
Eina_List *l;
EINA_LIST_FOREACH(sub_items, l, eit)
{
it_file_path = enventor_item_file_get(eit);
if (!it_file_path) continue;
//Let's check if the file is already opened.
if (selected_file_len != strlen(it_file_path)) continue;
//Ok, This selected file is already openend, let's activate the item.
if (!strcmp(file->path, it_file_path))
{
file_mgr_file_focus(eit);
return;
}
}
//This selected file hasn't been opened yet, so let's open this file newly.
file_mgr_sub_file_add(file->path);
file_mgr_file_open(file->path);
}
//Set file->it as NULL when genlist item is deleted.

View File

@ -340,3 +340,59 @@ file_mgr_modified_get(void)
return EINA_FALSE;
}
Eina_Bool
file_mgr_file_open(const char *file_path)
{
if (!file_path) return EINA_FALSE;
//skip non edc nor header files.
if (!(eina_str_has_extension(file_path, "edc") ||
eina_str_has_extension(file_path, "h"))) return EINA_FALSE;
unsigned int selected_file_len = strlen(file_path);
Enventor_Item *eit;
const char *it_file_path;
//Case 1. main file.
eit = file_mgr_main_item_get();
if (eit)
{
it_file_path = enventor_item_file_get(eit);
if (!it_file_path)
{
EINA_LOG_ERR("No main item file path??");
return EINA_FALSE;
}
//Ok, This selected file is already openend, let's activate the item.
if (!strcmp(file_path, ecore_file_file_get(it_file_path)))
{
file_mgr_file_focus(eit);
return EINA_TRUE;
}
}
//Case 2. sub files.
Eina_List *sub_items =
(Eina_List *)enventor_object_sub_items_get(base_enventor_get());
Eina_List *l;
EINA_LIST_FOREACH(sub_items, l, eit)
{
it_file_path = enventor_item_file_get(eit);
if (!it_file_path) continue;
//Let's check if the file is already opened.
if (selected_file_len != strlen(it_file_path)) continue;
//Ok, This selected file is already openend, let's activate the item.
if (!strcmp(file_path, it_file_path))
{
file_mgr_file_focus(eit);
return EINA_TRUE;
}
}
//This selected file hasn't been opened yet, so let's open this file newly.
file_mgr_sub_file_add(file_path);
}

View File

@ -536,6 +536,14 @@ enventor_ctxpopup_dismissed_cb(void *data EINA_UNUSED, Enventor_Object *obj,
enventor_object_focus_set(obj, EINA_FALSE);
}
static void
enventor_file_open_requested_cb(void *data EINA_UNUSED, Enventor_Object *obj,
void *event_info EINA_UNUSED)
{
const char *file_name = event_info;
file_mgr_file_open(file_name);
}
static void
enventor_focused_cb(void *data EINA_UNUSED, Enventor_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
@ -580,6 +588,8 @@ enventor_setup(app_data *ad)
enventor_ctxpopup_dismissed_cb, ad);
evas_object_smart_callback_add(enventor, "focused",
enventor_focused_cb, ad);
evas_object_smart_callback_add(enventor, "file,open,requested",
enventor_file_open_requested_cb, ad);
evas_object_event_callback_add(enventor, EVAS_CALLBACK_MOUSE_DOWN,
enventor_mouse_down_cb, ad);

View File

@ -13,3 +13,5 @@ void file_mgr_file_focus(Enventor_Item *it);
Eina_Bool file_mgr_save_all(void);
Enventor_Item *file_mgr_main_item_get(void);
Eina_Bool file_mgr_modified_get(void);
Eina_Bool file_mgr_file_open(const char *file_path);

View File

@ -323,7 +323,7 @@ syntax_color_thread_cancel_cb(void *data, Ecore_Thread *thread EINA_UNUSED)
free(td);
}
void
static void
bracket_changed_cb(void *data, int left, int right)
{
edit_data *ed = data;
@ -936,6 +936,83 @@ scroller_vbar_unpress_cb(void *data, Evas_Object *obj EINA_UNUSED,
syntax_color_partial_update(ed, SYNTAX_COLOR_SHORT_TIME);
}
static void
edit_link_activate(edit_data *ed)
{
Evas_Object *textblock = elm_entry_textblock_get(ed->en_edit);
int line1 = ed->cur_line - 1;
int line2 = ed->cur_line;
//min position case
if (line1 < 0)
{
line1 = 0;
line2 = 1;
}
//Max position case
Eina_Bool max = EINA_FALSE;
if (line2 >= ed->line_max)
{
line1 = (ed->line_max - 2);
line2 = (ed->line_max - 1);
max = EINA_TRUE;
}
Evas_Textblock_Cursor *cur1 = evas_object_textblock_cursor_new(textblock);
evas_textblock_cursor_line_set(cur1, line1);
if (max) evas_textblock_cursor_line_char_last(cur1);
Evas_Textblock_Cursor *cur2 = evas_object_textblock_cursor_new(textblock);
evas_textblock_cursor_line_set(cur2, line2);
if (max) evas_textblock_cursor_line_char_last(cur2);
int cur1_pos, cur2_pos;
cur1_pos = evas_textblock_cursor_pos_get(cur1);
cur2_pos = evas_textblock_cursor_pos_get(cur2);
char *content = evas_textblock_cursor_range_text_get(cur1, cur2,
EVAS_TEXTBLOCK_TEXT_MARKUP);
char *utf8 = elm_entry_markup_to_utf8(content);
free(content);
//Case 1. File Link?
char *file_link = utf8;
if (file_link = strstr(utf8, "#include "))
{
file_link += 9; //strlen("#include "))
char *name_begin = strstr(utf8, "\"");
if (!name_begin) goto end;
name_begin++;
char *name_end = strstr(name_begin, "\"");
if (!name_end) goto end;
file_link = strndup(name_begin, name_end - name_begin);
if (file_link)
{
//Compose the absolute file path.
const char *file_name = ecore_file_file_get(ed->filepath);
if (!file_name) goto end;
char *file_path =
strndup(ed->filepath, (file_name - ed->filepath));
if (!file_path) goto end;
char buf[PATH_MAX];
snprintf(buf, sizeof(buf), "%s%s", file_path, file_link);
evas_object_smart_callback_call(ed->enventor,
SIG_FILE_OPEN_REQUESTED,
(void*)buf);
free(file_path);
free(file_link);
}
}
//TODO: Case 2. Part Link?
end:
free(utf8);
}
static Eina_Bool
edit_edc_load(edit_data *ed, const char *file_path)
{
@ -1328,7 +1405,7 @@ edit_line_delete(edit_data *ed)
redoundo_text_push(ed->rd, content, cur1_pos, abs(cur2_pos - cur1_pos),
EINA_FALSE);
elm_entry_calc_force(ed->en_edit);
if (content) free(content);
free(content);
edit_line_decrease(ed, 1);
@ -1769,6 +1846,10 @@ edit_key_up_event_dispatch(edit_data *ed, const char *key)
if (!strcmp("Control_L", key))
ed->ctrl_pressed = EINA_FALSE;
//Link
if (!strcmp("F5", key))
edit_link_activate(ed);
return EINA_FALSE;
}

View File

@ -372,7 +372,6 @@ type_init_thread_blocking(void *data, Ecore_Thread *thread EINA_UNUSED)
{
type_init_td *td = data;
parser_attr attr;
td->attrs = eina_inarray_new(sizeof(parser_attr), 24);
eina_inarray_step_set(td->attrs, sizeof(Eina_Inarray), sizeof(parser_attr),
4);
@ -1739,33 +1738,26 @@ parser_init(void)
void
parser_term(parser_data *pd)
{
if (pd->cntd)
{
pd->cntd->pd = NULL;
ecore_thread_cancel(pd->cntd->thread);
}
if (pd->titd)
{
pd->titd->pd = NULL;
ecore_thread_cancel(pd->titd->thread);
}
if (pd->cntd) ecore_thread_cancel(pd->cntd->thread);
if (pd->titd) ecore_thread_cancel(pd->titd->thread);
if (pd->btd) ecore_thread_cancel(pd->btd->thread);
parser_attr *attr;
EINA_INARRAY_FOREACH(pd->attrs, attr)
if (pd->attrs)
{
eina_stringshare_del(attr->keyword);
if (attr->value.strs)
parser_attr *attr;
EINA_INARRAY_FOREACH(pd->attrs, attr)
{
while (eina_array_count(attr->value.strs))
eina_stringshare_del(eina_array_pop(attr->value.strs));
eina_array_free(attr->value.strs);
}
}
eina_stringshare_del(attr->keyword);
eina_inarray_free(pd->attrs);
if (attr->value.strs)
{
while (eina_array_count(attr->value.strs))
eina_stringshare_del(eina_array_pop(attr->value.strs));
eina_array_free(attr->value.strs);
}
}
eina_inarray_free(pd->attrs);
}
free(pd);
}

View File

@ -21,6 +21,7 @@ const char SIG_CTXPOPUP_DISMISSED[] = "ctxpopup,dismissed";
const char SIG_CTXPOPUP_ACTIVATED[] = "ctxpopup,activated";
const char SIG_EDC_MODIFIED[] = "edc,modified";
const char SIG_FOCUSED[] = "focused";
const char SIG_FILE_OPEN_REQUESTED[] = "file,open,requested";
static int _enventor_init_count = 0;
static int _enventor_log_dom = -1;

View File

@ -235,5 +235,6 @@ class Enventor.Object (Elm.Widget, Efl.File) {
ctxpopup,dismissed;
edc,modified;
focused;
file,open,requested;
}
}

View File

@ -35,6 +35,7 @@ extern const char SIG_CTXPOPUP_DISMISSED[];
extern const char SIG_CTXPOPUP_ACTIVATED[];
extern const char SIG_EDC_MODIFIED[];
extern const char SIG_FOCUSED[];
extern const char SIG_FILE_OPEN_REQUESTED[];
typedef struct viewer_s view_data;
typedef struct syntax_color_s color_data;

View File

@ -74,6 +74,7 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = {
{SIG_CTXPOPUP_ACTIVATED, ""},
{SIG_EDC_MODIFIED, ""},
{SIG_FOCUSED, ""},
{SIG_FILE_OPEN_REQUESTED, ""},
{NULL, NULL}
};
@ -810,8 +811,6 @@ enventor_object_sub_item_add(Enventor_Object *obj, const char *file)
return NULL;
}
pd->sub_its = eina_list_append(pd->sub_its, it);
it->ed = edit_init(obj, it);
it->pd = pd;
@ -825,6 +824,8 @@ enventor_object_sub_item_add(Enventor_Object *obj, const char *file)
edit_changed_set(it->ed, EINA_FALSE);
edit_disabled_set(it->ed, EINA_TRUE);
pd->sub_its = eina_list_append(pd->sub_its, it);
return it;
}