mirror of
https://github.com/MidnightCommander/mc
synced 2025-01-10 21:42:00 +03:00
9c0a8e7d3f
Modified API of search engine: return the number of search types. This avoids the calculation of the search type count when need. Sync editor search, editor replace and viewer searc dialogs with new search API. Fixed memory leak in editcmd_dialog_search_show(). Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
583 lines
19 KiB
C
583 lines
19 KiB
C
/*
|
|
Editor dialogs for high level editing commands
|
|
|
|
Copyright (C) 2009 The Free Software Foundation, Inc.
|
|
|
|
Written by:
|
|
Slava Zanko <slavazanko@gmail.com>, 2009.
|
|
|
|
This file is part of the Midnight Commander.
|
|
|
|
The Midnight Commander is free software; you can redistribute it
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version.
|
|
|
|
The Midnight Commander is distributed in the hope that it will be
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include "../src/global.h"
|
|
|
|
#include "../src/tty/tty.h"
|
|
#include "../src/skin/skin.h" /* INPUT_COLOR */
|
|
#include "../src/tty/key.h"
|
|
|
|
#include "../src/search/search.h"
|
|
|
|
#include "../src/strutil.h"
|
|
#include "../src/widget.h"
|
|
#include "../src/wtools.h"
|
|
#include "../src/dialog.h" /* do_refresh() */
|
|
#include "../src/main.h"
|
|
#include "../src/history.h"
|
|
#include "../src/charsets.h"
|
|
|
|
#include "../edit/edit-widget.h"
|
|
#include "../edit/etags.h"
|
|
#include "../edit/editcmd_dialogs.h"
|
|
|
|
|
|
/*** global variables **************************************************/
|
|
|
|
/*** file scope macro definitions **************************************/
|
|
|
|
#define SEARCH_DLG_WIDTH 58
|
|
#define SEARCH_DLG_MIN_HEIGHT 13
|
|
#define SEARCH_DLG_HEIGHT_SUPPLY 3
|
|
|
|
#define REPLACE_DLG_WIDTH 58
|
|
#define REPLACE_DLG_MIN_HEIGHT 17
|
|
#define REPLACE_DLG_HEIGHT_SUPPLY 5
|
|
|
|
/*** file scope type declarations **************************************/
|
|
|
|
/*** file scope variables **********************************************/
|
|
|
|
|
|
/*** file scope functions **********************************************/
|
|
|
|
static cb_ret_t
|
|
editcmd_dialog_raw_key_query_cb (struct Dlg_head *h, dlg_msg_t msg, int parm)
|
|
{
|
|
switch (msg) {
|
|
case DLG_KEY:
|
|
dlg_stop (h);
|
|
h->ret_value = parm;
|
|
return MSG_HANDLED;
|
|
default:
|
|
return default_dlg_callback (h, msg, parm);
|
|
}
|
|
}
|
|
|
|
/*** public functions **************************************************/
|
|
|
|
void
|
|
editcmd_dialog_replace_show (WEdit * edit, const char *search_default, const char *replace_default,
|
|
/*@out@ */ char **search_text, /*@out@ */ char **replace_text)
|
|
{
|
|
if (*search_default == '\0')
|
|
search_default = INPUT_LAST_TEXT;
|
|
|
|
{
|
|
size_t num_of_types;
|
|
gchar **list_of_types = mc_search_get_types_strings_array (&num_of_types);
|
|
int REPLACE_DLG_HEIGHT = REPLACE_DLG_MIN_HEIGHT + num_of_types - REPLACE_DLG_HEIGHT_SUPPLY;
|
|
|
|
QuickWidget quick_widgets[] =
|
|
{
|
|
/* 0 */ QUICK_BUTTON (6, 10, 13, REPLACE_DLG_HEIGHT, N_("&Cancel"), B_CANCEL, NULL),
|
|
/* 1 */ QUICK_BUTTON (2, 10, 13, REPLACE_DLG_HEIGHT, N_("&OK"), B_ENTER, NULL),
|
|
#ifdef HAVE_CHARSET
|
|
/* 2 */ QUICK_CHECKBOX (33, REPLACE_DLG_WIDTH, 11, REPLACE_DLG_HEIGHT, N_("All charsets"), &edit->all_codepages),
|
|
#endif
|
|
/* 3 */ QUICK_CHECKBOX (33, REPLACE_DLG_WIDTH, 10, REPLACE_DLG_HEIGHT, N_("&Whole words"), &edit->whole_words),
|
|
/* 4 */ QUICK_CHECKBOX (33, REPLACE_DLG_WIDTH, 9, REPLACE_DLG_HEIGHT, N_("In se&lection"), &edit->only_in_selection),
|
|
/* 5 */ QUICK_CHECKBOX (33, REPLACE_DLG_WIDTH, 8, REPLACE_DLG_HEIGHT, N_("&Backwards"), &edit->replace_backwards),
|
|
/* 6 */ QUICK_CHECKBOX (33, REPLACE_DLG_WIDTH, 7, REPLACE_DLG_HEIGHT, N_("case &Sensitive"), &edit->replace_case),
|
|
/* 7 */ QUICK_RADIO (3, REPLACE_DLG_WIDTH, 7, REPLACE_DLG_HEIGHT,
|
|
num_of_types, (const char **) list_of_types, &edit->search_type),
|
|
/* 8 */ QUICK_LABEL (2, REPLACE_DLG_WIDTH, 4, REPLACE_DLG_HEIGHT, N_(" Enter replacement string:")),
|
|
/* 9 */ QUICK_INPUT (3, REPLACE_DLG_WIDTH, 5, REPLACE_DLG_HEIGHT,
|
|
replace_default, REPLACE_DLG_WIDTH - 6, 0, "replace", replace_text),
|
|
/* 10 */ QUICK_LABEL (2, REPLACE_DLG_WIDTH, 2, REPLACE_DLG_HEIGHT, N_(" Enter search string:")),
|
|
/* 11 */ QUICK_INPUT (3, REPLACE_DLG_WIDTH, 3, REPLACE_DLG_HEIGHT,
|
|
search_default, REPLACE_DLG_WIDTH - 6, 0, MC_HISTORY_SHARED_SEARCH, search_text),
|
|
QUICK_END
|
|
};
|
|
|
|
QuickDialog Quick_input =
|
|
{
|
|
REPLACE_DLG_WIDTH, REPLACE_DLG_HEIGHT, -1, -1, N_(" Replace "),
|
|
"[Input Line Keys]", quick_widgets, FALSE
|
|
};
|
|
|
|
if (quick_dialog (&Quick_input) != B_CANCEL) {
|
|
edit->replace_mode = 0;
|
|
} else {
|
|
*replace_text = NULL;
|
|
*search_text = NULL;
|
|
}
|
|
|
|
g_strfreev (list_of_types);
|
|
}
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
void
|
|
editcmd_dialog_search_show (WEdit * edit, char **search_text)
|
|
{
|
|
if (*search_text == '\0')
|
|
*search_text = INPUT_LAST_TEXT;
|
|
|
|
{
|
|
size_t num_of_types;
|
|
gchar **list_of_types = mc_search_get_types_strings_array (&num_of_types);
|
|
int SEARCH_DLG_HEIGHT = SEARCH_DLG_MIN_HEIGHT + num_of_types - SEARCH_DLG_HEIGHT_SUPPLY;
|
|
int i;
|
|
|
|
int dialog_result;
|
|
|
|
QuickWidget quick_widgets[] =
|
|
{
|
|
/* 0 */
|
|
QUICK_BUTTON (6, 10, 11, SEARCH_DLG_HEIGHT, N_("&Cancel"), B_CANCEL, NULL),
|
|
/* 1 */
|
|
QUICK_BUTTON (4, 10, 11, SEARCH_DLG_HEIGHT, N_("&Find all"), B_USER, NULL),
|
|
/* 2 */
|
|
QUICK_BUTTON (2, 10, 11, SEARCH_DLG_HEIGHT, N_("&OK"), B_ENTER, NULL),
|
|
#ifdef HAVE_CHARSET
|
|
/* 3 */
|
|
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 9, SEARCH_DLG_HEIGHT, N_("All charsets"), &edit->all_codepages),
|
|
#endif
|
|
/* 4 */
|
|
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 8, SEARCH_DLG_HEIGHT, N_("&Whole words"), &edit->whole_words),
|
|
/* 5 */
|
|
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 7, SEARCH_DLG_HEIGHT, N_("In se&lection"), &edit->only_in_selection),
|
|
/* 6 */
|
|
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 6, SEARCH_DLG_HEIGHT, N_("&Backwards"), &edit->replace_backwards),
|
|
/* 7 */
|
|
QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT, N_("case &Sensitive"), &edit->replace_case),
|
|
/* 8 */
|
|
QUICK_RADIO ( 3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT,
|
|
num_of_types, (const char **) list_of_types, &edit->search_type),
|
|
/* 9 */
|
|
QUICK_INPUT (3, SEARCH_DLG_WIDTH, 3, SEARCH_DLG_HEIGHT,
|
|
*search_text, SEARCH_DLG_WIDTH - 6, 0, MC_HISTORY_SHARED_SEARCH, search_text),
|
|
/* 10 */
|
|
QUICK_LABEL (2, SEARCH_DLG_WIDTH, 2, SEARCH_DLG_HEIGHT, N_(" Enter search string:")),
|
|
QUICK_END
|
|
};
|
|
|
|
#ifdef HAVE_CHARSET
|
|
int last_checkbox = 7;
|
|
#else
|
|
int last_checkbox = 6;
|
|
#endif
|
|
|
|
QuickDialog Quick_input =
|
|
{
|
|
SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT, -1, -1, N_("Search"),
|
|
"[Input Line Keys]", quick_widgets, TRUE
|
|
};
|
|
|
|
#ifdef ENABLE_NLS
|
|
char **list_of_types_nls;
|
|
|
|
/* header title */
|
|
Quick_input.title = _(Quick_input.title);
|
|
/* buttons */
|
|
for (i = 0; i < 3; i++)
|
|
quick_widgets[i].u.button.text = _(quick_widgets[i].u.button.text);
|
|
/* checkboxes */
|
|
for (i = 3; i <= last_checkbox; i++)
|
|
quick_widgets[i].u.checkbox.text = _(quick_widgets[i].u.checkbox.text);
|
|
/* label */
|
|
quick_widgets[10].u.label.text = _(quick_widgets[10].u.label.text);
|
|
|
|
/* radiobuttons */
|
|
/* create copy of radio items to avoid memory leak */
|
|
list_of_types_nls = g_new0 (char *, num_of_types + 1);
|
|
for (i = 0; i < num_of_types; i++)
|
|
list_of_types_nls[i] = g_strdup (_(list_of_types[i]));
|
|
g_strfreev (list_of_types);
|
|
list_of_types = list_of_types_nls;
|
|
quick_widgets[last_checkbox + 1].u.radio.items = (const char **) list_of_types;
|
|
#endif
|
|
|
|
/* calculate widget coordinates */
|
|
{
|
|
int len = 0;
|
|
int dlg_width;
|
|
gchar **radio = list_of_types;
|
|
int b0_len, b1_len, b2_len;
|
|
const int button_gap = 2;
|
|
|
|
/* length of radiobuttons */
|
|
while (*radio != NULL) {
|
|
len = max (len, str_term_width1 (*radio));
|
|
radio++;
|
|
}
|
|
/* length of checkboxes */
|
|
for (i = 3; i <= last_checkbox; i++)
|
|
len = max (len, str_term_width1 (quick_widgets[i].u.checkbox.text) + 4);
|
|
|
|
/* preliminary dialog width */
|
|
dlg_width = max (len * 2, str_term_width1 (Quick_input.title)) + 4;
|
|
|
|
/* length of buttons */
|
|
b0_len = str_term_width1 (quick_widgets[0].u.button.text) + 3;
|
|
b1_len = str_term_width1 (quick_widgets[1].u.button.text) + 3;
|
|
b2_len = str_term_width1 (quick_widgets[2].u.button.text) + 5; /* default button */
|
|
len = b0_len + b1_len + b2_len + 6 + button_gap * 2;
|
|
|
|
/* dialog width */
|
|
Quick_input.xlen = max (SEARCH_DLG_WIDTH, max (dlg_width, len));
|
|
|
|
/* correct widget coordinates */
|
|
for (i = 0; i < sizeof (quick_widgets)/sizeof (quick_widgets[0]); i++)
|
|
quick_widgets[i].x_divisions = Quick_input.xlen;
|
|
|
|
/* checkbox positions */
|
|
for (i = 3; i <= last_checkbox; i++)
|
|
quick_widgets[i].relative_x = Quick_input.xlen/2 + 2;
|
|
/* input length */
|
|
quick_widgets[last_checkbox + 2].u.input.len = Quick_input.xlen - 6;
|
|
/* button positions */
|
|
quick_widgets[1].relative_x = Quick_input.xlen/2 - b1_len/2;
|
|
quick_widgets[2].relative_x = quick_widgets[1].relative_x - button_gap - b2_len;
|
|
quick_widgets[0].relative_x = quick_widgets[1].relative_x + button_gap + b1_len;
|
|
}
|
|
|
|
dialog_result = quick_dialog (&Quick_input);
|
|
|
|
g_strfreev (list_of_types);
|
|
|
|
if (dialog_result == B_CANCEL)
|
|
*search_text = NULL;
|
|
else if (dialog_result == B_USER)
|
|
search_create_bookmark = 1;
|
|
}
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/* gets a raw key from the keyboard. Passing cancel = 1 draws
|
|
a cancel button thus allowing c-c etc. Alternatively, cancel = 0
|
|
will return the next key pressed. ctrl-a (=B_CANCEL), ctrl-g, ctrl-c,
|
|
and Esc are cannot returned */
|
|
|
|
int
|
|
editcmd_dialog_raw_key_query (const char *heading, const char *query, int cancel)
|
|
{
|
|
int w = str_term_width1 (query) + 7;
|
|
struct Dlg_head *raw_dlg =
|
|
create_dlg (0, 0, 7, w, dialog_colors, editcmd_dialog_raw_key_query_cb,
|
|
NULL, heading,
|
|
DLG_CENTER | DLG_TRYUP | DLG_WANT_TAB);
|
|
add_widget (raw_dlg,
|
|
input_new (3 - cancel, w - 5, INPUT_COLOR, 2, "", 0, INPUT_COMPLETE_DEFAULT));
|
|
add_widget (raw_dlg, label_new (3 - cancel, 2, query));
|
|
if (cancel)
|
|
add_widget (raw_dlg, button_new (4, w / 2 - 5, B_CANCEL, NORMAL_BUTTON, _("Cancel"), 0));
|
|
w = run_dlg (raw_dlg);
|
|
destroy_dlg (raw_dlg);
|
|
if (cancel) {
|
|
if (w == XCTRL ('g') || w == XCTRL ('c') || w == ESC_CHAR || w == B_CANCEL)
|
|
return 0;
|
|
}
|
|
|
|
return w;
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/* let the user select its preferred completion */
|
|
void
|
|
editcmd_dialog_completion_show (WEdit * edit, int max_len, int word_len,
|
|
struct selection *compl, int num_compl)
|
|
{
|
|
|
|
int start_x, start_y, offset, i;
|
|
char *curr = NULL;
|
|
Dlg_head *compl_dlg;
|
|
WListbox *compl_list;
|
|
int compl_dlg_h; /* completion dialog height */
|
|
int compl_dlg_w; /* completion dialog width */
|
|
|
|
/* calculate the dialog metrics */
|
|
compl_dlg_h = num_compl + 2;
|
|
compl_dlg_w = max_len + 4;
|
|
start_x = edit->curs_col + edit->start_col - (compl_dlg_w / 2) +
|
|
EDIT_TEXT_HORIZONTAL_OFFSET + option_line_state_width;
|
|
start_y = edit->curs_row + EDIT_TEXT_VERTICAL_OFFSET + 1;
|
|
|
|
if (start_x < 0)
|
|
start_x = 0;
|
|
if (compl_dlg_w > COLS)
|
|
compl_dlg_w = COLS;
|
|
if (compl_dlg_h > LINES - 2)
|
|
compl_dlg_h = LINES - 2;
|
|
|
|
offset = start_x + compl_dlg_w - COLS;
|
|
if (offset > 0)
|
|
start_x -= offset;
|
|
offset = start_y + compl_dlg_h - LINES;
|
|
if (offset > 0)
|
|
start_y -= (offset + 1);
|
|
|
|
/* create the dialog */
|
|
compl_dlg =
|
|
create_dlg (start_y, start_x, compl_dlg_h, compl_dlg_w,
|
|
dialog_colors, NULL, "[Completion]", NULL, DLG_COMPACT);
|
|
|
|
/* create the listbox */
|
|
compl_list = listbox_new (1, 1, compl_dlg_h - 2, compl_dlg_w - 2, NULL);
|
|
|
|
/* add the dialog */
|
|
add_widget (compl_dlg, compl_list);
|
|
|
|
/* fill the listbox with the completions */
|
|
for (i = num_compl - 1; i >= 0; i--) /* reverse order */
|
|
listbox_add_item (compl_list, LISTBOX_APPEND_AT_END, 0, (char *) compl[i].text, NULL);
|
|
|
|
/* pop up the dialog and apply the choosen completion */
|
|
if (run_dlg (compl_dlg) == B_ENTER) {
|
|
listbox_get_current (compl_list, &curr, NULL);
|
|
if (curr) {
|
|
#ifdef HAVE_CHARSET
|
|
GString *temp, *temp2;
|
|
temp = g_string_new("");
|
|
for (curr += word_len; *curr; curr++)
|
|
g_string_append_c(temp, *curr);
|
|
|
|
temp2 = str_convert_to_input (temp->str);
|
|
|
|
if (temp2 && temp2->len){
|
|
g_string_free(temp, TRUE);
|
|
temp = temp2;
|
|
}
|
|
else
|
|
g_string_free(temp2, TRUE);
|
|
for (curr = temp->str; *curr; curr++)
|
|
edit_insert (edit, *curr);
|
|
g_string_free(temp, TRUE);
|
|
#else
|
|
for (curr += word_len; *curr; curr++)
|
|
edit_insert (edit, *curr);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* destroy dialog before return */
|
|
destroy_dlg (compl_dlg);
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/* let the user select where function definition */
|
|
void
|
|
editcmd_dialog_select_definition_show (WEdit * edit, char *match_expr, int max_len, int word_len,
|
|
etags_hash_t * def_hash, int num_lines)
|
|
{
|
|
|
|
int start_x, start_y, offset, i;
|
|
char *curr = NULL;
|
|
etags_hash_t *curr_def = NULL;
|
|
Dlg_head *def_dlg;
|
|
WListbox *def_list;
|
|
int def_dlg_h; /* dialog height */
|
|
int def_dlg_w; /* dialog width */
|
|
char *label_def = NULL;
|
|
|
|
(void) word_len;
|
|
/* calculate the dialog metrics */
|
|
def_dlg_h = num_lines + 2;
|
|
def_dlg_w = max_len + 4;
|
|
start_x = edit->curs_col + edit->start_col - (def_dlg_w / 2) +
|
|
EDIT_TEXT_HORIZONTAL_OFFSET + option_line_state_width;
|
|
start_y = edit->curs_row + EDIT_TEXT_VERTICAL_OFFSET + 1;
|
|
|
|
if (start_x < 0)
|
|
start_x = 0;
|
|
if (def_dlg_w > COLS)
|
|
def_dlg_w = COLS;
|
|
if (def_dlg_h > LINES - 2)
|
|
def_dlg_h = LINES - 2;
|
|
|
|
offset = start_x + def_dlg_w - COLS;
|
|
if (offset > 0)
|
|
start_x -= offset;
|
|
offset = start_y + def_dlg_h - LINES;
|
|
if (offset > 0)
|
|
start_y -= (offset + 1);
|
|
|
|
/* create the dialog */
|
|
def_dlg = create_dlg (start_y, start_x, def_dlg_h, def_dlg_w,
|
|
dialog_colors, NULL, "[Definitions]", match_expr, DLG_COMPACT);
|
|
|
|
/* create the listbox */
|
|
def_list = listbox_new (1, 1, def_dlg_h - 2, def_dlg_w - 2, NULL);
|
|
|
|
/* add the dialog */
|
|
add_widget (def_dlg, def_list);
|
|
|
|
|
|
/* fill the listbox with the completions */
|
|
for (i = 0; i < num_lines; i++) {
|
|
label_def =
|
|
g_strdup_printf ("%s -> %s:%ld", def_hash[i].short_define, def_hash[i].filename,
|
|
def_hash[i].line);
|
|
listbox_add_item (def_list, LISTBOX_APPEND_AT_END, 0, label_def, &def_hash[i]);
|
|
g_free (label_def);
|
|
}
|
|
/* pop up the dialog */
|
|
run_dlg (def_dlg);
|
|
|
|
/* apply the choosen completion */
|
|
if (def_dlg->ret_value == B_ENTER) {
|
|
char *tmp_curr_def = (char *) curr_def;
|
|
int do_moveto = 0;
|
|
|
|
listbox_get_current (def_list, &curr, &tmp_curr_def);
|
|
curr_def = (etags_hash_t *) tmp_curr_def;
|
|
if (edit->modified) {
|
|
if (!edit_query_dialog2
|
|
(_("Warning"),
|
|
_(" Current text was modified without a file save. \n"
|
|
" Continue discards these changes. "), _("C&ontinue"), _("&Cancel"))) {
|
|
edit->force |= REDRAW_COMPLETELY;
|
|
do_moveto = 1;
|
|
}
|
|
} else {
|
|
do_moveto = 1;
|
|
}
|
|
if (curr && do_moveto) {
|
|
if (edit_stack_iterator + 1 < MAX_HISTORY_MOVETO) {
|
|
g_free (edit_history_moveto[edit_stack_iterator].filename);
|
|
if (edit->dir) {
|
|
edit_history_moveto[edit_stack_iterator].filename =
|
|
g_strdup_printf ("%s/%s", edit->dir, edit->filename);
|
|
} else {
|
|
edit_history_moveto[edit_stack_iterator].filename = g_strdup (edit->filename);
|
|
}
|
|
edit_history_moveto[edit_stack_iterator].line = edit->start_line +
|
|
edit->curs_row + 1;
|
|
edit_stack_iterator++;
|
|
g_free (edit_history_moveto[edit_stack_iterator].filename);
|
|
edit_history_moveto[edit_stack_iterator].filename =
|
|
g_strdup ((char *) curr_def->fullpath);
|
|
edit_history_moveto[edit_stack_iterator].line = curr_def->line;
|
|
edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename,
|
|
edit_history_moveto[edit_stack_iterator].line);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* clear definition hash */
|
|
for (i = 0; i < MAX_DEFINITIONS; i++) {
|
|
g_free (def_hash[i].filename);
|
|
}
|
|
|
|
/* destroy dialog before return */
|
|
destroy_dlg (def_dlg);
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
int
|
|
editcmd_dialog_replace_prompt_show (WEdit * edit, char *from_text, char *to_text, int xpos, int ypos)
|
|
{
|
|
/* dialog sizes */
|
|
int dlg_height = 9;
|
|
int dlg_width = 8;
|
|
|
|
int retval;
|
|
int i;
|
|
int btn_pos;
|
|
|
|
char *repl_from, *repl_to;
|
|
char tmp [BUF_MEDIUM];
|
|
|
|
QuickWidget quick_widgets[] =
|
|
{
|
|
/* 0 */ QUICK_BUTTON (44, dlg_width, 6, dlg_height, N_("&Cancel"), B_CANCEL, NULL),
|
|
/* 1 */ QUICK_BUTTON (29, dlg_width, 6, dlg_height, N_("&Skip"), B_SKIP_REPLACE, NULL),
|
|
/* 2 */ QUICK_BUTTON (21, dlg_width, 6, dlg_height, N_("A&ll"), B_REPLACE_ALL, NULL),
|
|
/* 3 */ QUICK_BUTTON ( 4, dlg_width, 6, dlg_height, N_("&Replace"), B_ENTER, NULL),
|
|
/* 4 */ QUICK_LABEL ( 3, dlg_width, 2, dlg_height, NULL),
|
|
/* 5 */ QUICK_LABEL ( 2, dlg_width, 3, dlg_height, N_(" Replace with: ")),
|
|
/* 6 */ QUICK_LABEL ( 3, dlg_width, 4, dlg_height, NULL),
|
|
QUICK_END
|
|
};
|
|
|
|
#ifdef ENABLE_NLS
|
|
for (i = 0; i < 4; i++)
|
|
quick_widgets[i].u.button.text = _(quick_widgets[i].u.button.text);
|
|
#endif
|
|
|
|
/* calculate button positions */
|
|
btn_pos = 4;
|
|
|
|
for (i = 3; i > -1; i--) {
|
|
quick_widgets[i].relative_x = btn_pos;
|
|
btn_pos += str_term_width1 (quick_widgets[i].u.button.text) + 5;
|
|
if (i == 3) /* default button */
|
|
btn_pos += 2;
|
|
}
|
|
|
|
dlg_width = btn_pos + 2;
|
|
|
|
/* correct widget coordinates */
|
|
for (i = 0; i < 7; i++)
|
|
quick_widgets[i].x_divisions = dlg_width;
|
|
|
|
g_snprintf (tmp, sizeof (tmp), " '%s'", from_text);
|
|
repl_from = g_strdup (str_fit_to_term (tmp, dlg_width - 7, J_LEFT));
|
|
|
|
g_snprintf (tmp, sizeof (tmp), " '%s'", to_text);
|
|
repl_to = g_strdup (str_fit_to_term (tmp, dlg_width - 7, J_LEFT));
|
|
|
|
quick_widgets[4].u.label.text = repl_from;
|
|
quick_widgets[6].u.label.text = repl_to;
|
|
|
|
if (xpos == -1)
|
|
xpos = (edit->num_widget_columns - dlg_width) / 2;
|
|
|
|
if (ypos == -1)
|
|
ypos = edit->num_widget_lines * 2 / 3;
|
|
|
|
{
|
|
QuickDialog Quick_input =
|
|
{
|
|
dlg_width, dlg_height, 0, 0, N_ (" Confirm replace "),
|
|
"[Input Line Keys]", quick_widgets, FALSE
|
|
};
|
|
|
|
/* Sometimes menu can hide replaced text. I don't like it */
|
|
if ((edit->curs_row >= ypos - 1) && (edit->curs_row <= ypos + dlg_height - 1))
|
|
ypos -= dlg_height;
|
|
|
|
Quick_input.ypos = ypos;
|
|
Quick_input.xpos = xpos;
|
|
|
|
retval = quick_dialog (&Quick_input);
|
|
g_free (repl_from);
|
|
g_free (repl_to);
|
|
|
|
return retval;
|
|
}
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|