search: Add project-wide search and replace feature.
This commit is contained in:
parent
5cefe27e48
commit
c826dee557
|
@ -17,3 +17,104 @@ edi_file_path_hidden(const char *path)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
edi_file_text_replace(const char *path, const char *search, const char *replace)
|
||||||
|
{
|
||||||
|
char *map, *tempfilepath, *found;
|
||||||
|
FILE *tempfile;
|
||||||
|
Eina_File *f;
|
||||||
|
unsigned long long len, idx;
|
||||||
|
unsigned int slen;
|
||||||
|
|
||||||
|
f = eina_file_open(path, EINA_FALSE);
|
||||||
|
if (!f) return;
|
||||||
|
|
||||||
|
map = eina_file_map_all(f, EINA_FILE_POPULATE);
|
||||||
|
if (!map)
|
||||||
|
{
|
||||||
|
eina_file_close(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = eina_file_size_get(f);
|
||||||
|
if (!len)
|
||||||
|
{
|
||||||
|
eina_file_close(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tempfilepath = malloc(strlen(path)) + 5;
|
||||||
|
sprintf(tempfilepath, "/tmp/%s.tmp", ecore_file_file_get(path));
|
||||||
|
|
||||||
|
tempfile = fopen(tempfilepath, "wb");
|
||||||
|
if (!tempfile) goto done;
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
|
||||||
|
found = strstr(&map[idx], search);
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
fclose(tempfile);
|
||||||
|
unlink(tempfilepath);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
slen = strlen(search);
|
||||||
|
|
||||||
|
while (idx < len)
|
||||||
|
{
|
||||||
|
if (!found || &map[idx] < found)
|
||||||
|
{
|
||||||
|
fprintf(tempfile, "%c", map[idx]);
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(tempfile, "%s", replace);
|
||||||
|
idx += slen;
|
||||||
|
found = strstr(&map[idx], search);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(tempfile);
|
||||||
|
ecore_file_mv(tempfilepath, path);
|
||||||
|
done:
|
||||||
|
eina_file_map_free(f, map);
|
||||||
|
eina_file_close(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_edi_file_text_replace_all(const char *directory, const char *search, const char *replace)
|
||||||
|
{
|
||||||
|
char *path, *file;
|
||||||
|
Eina_List *files;
|
||||||
|
|
||||||
|
files = ecore_file_ls(directory);
|
||||||
|
|
||||||
|
EINA_LIST_FREE(files, file)
|
||||||
|
{
|
||||||
|
path = edi_path_append(directory, file);
|
||||||
|
if (!edi_file_path_hidden(path))
|
||||||
|
{
|
||||||
|
if (ecore_file_is_dir(path))
|
||||||
|
{
|
||||||
|
_edi_file_text_replace_all(path, search, replace);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
edi_file_text_replace(path, search, replace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(path);
|
||||||
|
free(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (files)
|
||||||
|
eina_list_free(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
edi_file_text_replace_all(const char *search, const char *replace)
|
||||||
|
{
|
||||||
|
_edi_file_text_replace_all(edi_project_get(), search, replace);
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,27 @@ extern "C" {
|
||||||
|
|
||||||
Eina_Bool edi_file_path_hidden(const char *path);
|
Eina_Bool edi_file_path_hidden(const char *path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace all occurences of text within whole project.
|
||||||
|
*
|
||||||
|
* @param search The text to be replaced.
|
||||||
|
* @param replace The text that will replace.
|
||||||
|
*
|
||||||
|
* @ingroup Lookup
|
||||||
|
*/
|
||||||
|
void edi_file_text_replace_all(const char *search, const char *replace);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace all occurences of text within given file.
|
||||||
|
*
|
||||||
|
* @param path The path of the file to replace all occurences of the text.
|
||||||
|
* @param search The text to be replaced.
|
||||||
|
* @param replace The text that will replace.
|
||||||
|
*
|
||||||
|
* @ingroup Lookup
|
||||||
|
*/
|
||||||
|
void edi_file_text_replace(const char *path, const char *search, const char *replace);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -926,6 +926,13 @@ _edi_menu_find_project_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
|
||||||
edi_mainview_project_search_popup_show();
|
edi_mainview_project_search_popup_show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_edi_menu_find_replace_project_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
|
||||||
|
void *event_info EINA_UNUSED)
|
||||||
|
{
|
||||||
|
edi_mainview_project_replace_popup_show();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_edi_menu_findfile_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
|
_edi_menu_findfile_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
|
||||||
void *event_info EINA_UNUSED)
|
void *event_info EINA_UNUSED)
|
||||||
|
@ -1137,6 +1144,7 @@ _edi_menu_setup(Evas_Object *win)
|
||||||
elm_menu_item_add(menu, menu_it, "go-jump", _("Goto Line ..."), _edi_menu_goto_cb, NULL);
|
elm_menu_item_add(menu, menu_it, "go-jump", _("Goto Line ..."), _edi_menu_goto_cb, NULL);
|
||||||
elm_menu_item_separator_add(menu, menu_it);
|
elm_menu_item_separator_add(menu, menu_it);
|
||||||
elm_menu_item_add(menu, menu_it, "edit-find", _("Find in project ..."), _edi_menu_find_project_cb, NULL);
|
elm_menu_item_add(menu, menu_it, "edit-find", _("Find in project ..."), _edi_menu_find_project_cb, NULL);
|
||||||
|
elm_menu_item_add(menu, menu_it, "edit-find-replace", _("Replace in project ..."), _edi_menu_find_replace_project_cb, NULL);
|
||||||
|
|
||||||
menu_it = elm_menu_item_add(menu, NULL, NULL, _("View"), NULL, NULL);
|
menu_it = elm_menu_item_add(menu, NULL, NULL, _("View"), NULL, NULL);
|
||||||
elm_menu_item_add(menu, menu_it, "window-new", _("New Window"), _edi_menu_view_open_window_cb, NULL);
|
elm_menu_item_add(menu, menu_it, "window-new", _("New Window"), _edi_menu_view_open_window_cb, NULL);
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
|
|
||||||
#include "editor/edi_editor.h"
|
#include "editor/edi_editor.h"
|
||||||
#include "edi_content_provider.h"
|
#include "edi_content_provider.h"
|
||||||
#include "../edi_searchpanel.h"
|
#include "edi_searchpanel.h"
|
||||||
|
#include "edi_file.h"
|
||||||
|
|
||||||
#include "edi_private.h"
|
#include "edi_private.h"
|
||||||
#include "edi_config.h"
|
#include "edi_config.h"
|
||||||
|
@ -465,6 +466,35 @@ edi_mainview_goto_popup_show()
|
||||||
edi_mainview_panel_goto_popup_show(_current_panel);
|
edi_mainview_panel_goto_popup_show(_current_panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_edi_mainview_popup_message_close_cb(void *data EINA_UNUSED,
|
||||||
|
Evas_Object *obj EINA_UNUSED,
|
||||||
|
void *event_info EINA_UNUSED)
|
||||||
|
{
|
||||||
|
Evas_Object *popup = data;
|
||||||
|
|
||||||
|
evas_object_del(popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_edi_mainview_popup_message_open(const char *message)
|
||||||
|
{
|
||||||
|
Evas_Object *popup, *button;
|
||||||
|
|
||||||
|
popup = elm_popup_add(_main_win);
|
||||||
|
elm_object_part_text_set(popup, "title,text",
|
||||||
|
message);
|
||||||
|
|
||||||
|
button = elm_button_add(popup);
|
||||||
|
|
||||||
|
elm_object_text_set(button, _("OK"));
|
||||||
|
elm_object_part_content_set(popup, "button1", button);
|
||||||
|
evas_object_smart_callback_add(button, "clicked",
|
||||||
|
_edi_mainview_popup_message_close_cb, popup);
|
||||||
|
|
||||||
|
evas_object_show(popup);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_edi_mainview_project_search_popup_cancel_cb(void *data EINA_UNUSED,
|
_edi_mainview_project_search_popup_cancel_cb(void *data EINA_UNUSED,
|
||||||
Evas_Object *obj EINA_UNUSED,
|
Evas_Object *obj EINA_UNUSED,
|
||||||
|
@ -482,7 +512,11 @@ _edi_mainview_project_search_cb(void *data,
|
||||||
char *text;
|
char *text;
|
||||||
|
|
||||||
text_markup = elm_object_text_get((Evas_Object *) data);
|
text_markup = elm_object_text_get((Evas_Object *) data);
|
||||||
if (!text_markup || !text_markup[0]) return;
|
if (!text_markup || !text_markup[0])
|
||||||
|
{
|
||||||
|
_edi_mainview_popup_message_open(_("Please enter a valid search term."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
text = elm_entry_markup_to_utf8(text_markup);
|
text = elm_entry_markup_to_utf8(text_markup);
|
||||||
|
|
||||||
|
@ -517,6 +551,7 @@ edi_mainview_project_search_popup_show(void)
|
||||||
_("Search for (whole project)"));
|
_("Search for (whole project)"));
|
||||||
|
|
||||||
box = elm_box_add(popup);
|
box = elm_box_add(popup);
|
||||||
|
evas_object_show(box);
|
||||||
sep = elm_separator_add(box);
|
sep = elm_separator_add(box);
|
||||||
elm_separator_horizontal_set(sep, EINA_TRUE);
|
elm_separator_horizontal_set(sep, EINA_TRUE);
|
||||||
evas_object_show(sep);
|
evas_object_show(sep);
|
||||||
|
@ -565,6 +600,127 @@ edi_mainview_project_search_popup_show(void)
|
||||||
evas_object_show(popup);
|
evas_object_show(popup);
|
||||||
elm_object_focus_set(input, EINA_TRUE);
|
elm_object_focus_set(input, EINA_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_edi_mainview_project_replace_cb(void *data,
|
||||||
|
Evas_Object *obj,
|
||||||
|
void *event_info EINA_UNUSED)
|
||||||
|
{
|
||||||
|
const char *search_markup, *replace_markup;
|
||||||
|
char *search, *replace;
|
||||||
|
|
||||||
|
search_markup = elm_object_text_get(evas_object_data_get(obj, "search"));
|
||||||
|
if (!search_markup || !search_markup[0])
|
||||||
|
{
|
||||||
|
_edi_mainview_popup_message_open(_("Please enter a valid search string."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
replace_markup = elm_object_text_get(data);
|
||||||
|
if (!replace_markup || !replace_markup[0])
|
||||||
|
{
|
||||||
|
_edi_mainview_popup_message_open(_("Please enter a valid replace string."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(replace_markup, search_markup))
|
||||||
|
{
|
||||||
|
_edi_mainview_popup_message_open(_("Strings cannot match."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
search = elm_entry_markup_to_utf8(search_markup);
|
||||||
|
replace = elm_entry_markup_to_utf8(replace_markup);
|
||||||
|
|
||||||
|
edi_file_text_replace_all(search, replace);
|
||||||
|
|
||||||
|
free(search);
|
||||||
|
free(replace);
|
||||||
|
|
||||||
|
evas_object_del(_edi_mainview_search_project_popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
edi_mainview_project_replace_popup_show(void)
|
||||||
|
{
|
||||||
|
Evas_Object *popup, *table, *box, *label, *sep, *search, *replace, *button;
|
||||||
|
|
||||||
|
popup = elm_popup_add(_main_win);
|
||||||
|
_edi_mainview_search_project_popup = popup;
|
||||||
|
elm_object_part_text_set(popup, "title,text", _("Search & Replace"));
|
||||||
|
|
||||||
|
box = elm_box_add(popup);
|
||||||
|
elm_object_content_set(popup, box);
|
||||||
|
|
||||||
|
sep = elm_separator_add(box);
|
||||||
|
elm_separator_horizontal_set(sep, EINA_TRUE);
|
||||||
|
evas_object_show(sep);
|
||||||
|
elm_box_pack_end(box, sep);
|
||||||
|
|
||||||
|
label = elm_label_add(box);
|
||||||
|
elm_object_text_set(label, _("Replace all occurences of text within the whole project."));
|
||||||
|
evas_object_show(label);
|
||||||
|
elm_box_pack_end(box, label);
|
||||||
|
|
||||||
|
sep = elm_separator_add(box);
|
||||||
|
elm_separator_horizontal_set(sep, EINA_TRUE);
|
||||||
|
evas_object_show(sep);
|
||||||
|
elm_box_pack_end(box, sep);
|
||||||
|
|
||||||
|
table = elm_table_add(box);
|
||||||
|
evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||||
|
evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||||
|
evas_object_show(table);
|
||||||
|
|
||||||
|
label = elm_label_add(table);
|
||||||
|
elm_object_text_set(label, _("Search: "));
|
||||||
|
evas_object_show(label);
|
||||||
|
elm_table_pack(table, label, 0, 0, 1, 1);
|
||||||
|
|
||||||
|
search = elm_entry_add(table);
|
||||||
|
elm_entry_single_line_set(search, EINA_TRUE);
|
||||||
|
elm_entry_scrollable_set(search, EINA_TRUE);
|
||||||
|
evas_object_size_hint_weight_set(search, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||||
|
evas_object_size_hint_align_set(search, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||||
|
evas_object_show(search);
|
||||||
|
elm_table_pack(table, search, 1, 0, 1, 1);
|
||||||
|
|
||||||
|
label = elm_label_add(table);
|
||||||
|
elm_object_text_set(label, _("Replace: "));
|
||||||
|
evas_object_show(label);
|
||||||
|
elm_table_pack(table, label, 0, 1, 1, 1);
|
||||||
|
|
||||||
|
replace = elm_entry_add(table);
|
||||||
|
elm_entry_single_line_set(replace, EINA_TRUE);
|
||||||
|
elm_entry_scrollable_set(replace, EINA_TRUE);
|
||||||
|
evas_object_size_hint_weight_set(replace, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||||
|
evas_object_size_hint_align_set(replace, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||||
|
evas_object_show(replace);
|
||||||
|
elm_table_pack(table, replace, 1, 1, 1, 1);
|
||||||
|
|
||||||
|
elm_box_pack_end(box, table);
|
||||||
|
|
||||||
|
sep = elm_separator_add(box);
|
||||||
|
elm_separator_horizontal_set(sep, EINA_TRUE);
|
||||||
|
evas_object_show(sep);
|
||||||
|
elm_box_pack_end(box, sep);
|
||||||
|
|
||||||
|
button = elm_button_add(popup);
|
||||||
|
elm_object_text_set(button, _("Cancel"));
|
||||||
|
elm_object_part_content_set(popup, "button1", button);
|
||||||
|
evas_object_smart_callback_add(button, "clicked",
|
||||||
|
_edi_mainview_project_search_popup_cancel_cb, NULL);
|
||||||
|
|
||||||
|
button = elm_button_add(popup);
|
||||||
|
evas_object_data_set(button, "search", search);
|
||||||
|
elm_object_text_set(button, _("Replace"));
|
||||||
|
elm_object_part_content_set(popup, "button2", button);
|
||||||
|
evas_object_smart_callback_add(button, "clicked",
|
||||||
|
_edi_mainview_project_replace_cb, replace);
|
||||||
|
|
||||||
|
evas_object_show(popup);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
edi_mainview_panel_remove(Edi_Mainview_Panel *panel)
|
edi_mainview_panel_remove(Edi_Mainview_Panel *panel)
|
||||||
{
|
{
|
||||||
|
|
|
@ -237,6 +237,14 @@ void edi_mainview_goto_popup_show();
|
||||||
*/
|
*/
|
||||||
void edi_mainview_project_search_popup_show();
|
void edi_mainview_project_search_popup_show();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Present a popup to initiate a project-wide search and replace.
|
||||||
|
*
|
||||||
|
* @ingroup Content
|
||||||
|
*/
|
||||||
|
void edi_mainview_project_replace_popup_show();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue