mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-23 12:56:51 +03:00
fdbd5b8a86
Editor completion became really confusing in 4.7.0-pre1: 1. The list is populated with words from the entire file. This is arguably better than the old style, which scanned only up to the cursor. But the number of suggestions are limited, and if you have a bigger file, some words won't make it in the list. Besides, I somehow liked the old way. 2. Suggestions do not end on a word boundary. This may or may be not useful; but it just increases the list of suggestions, which slows the user. In the end, it beats the purpose of completions. 3. It completes the word I am currently editing. That's smart. :) 4. The suggestions are displayed in the order in which they were found from the beginning of the file. This is my main gripe, because when using the editor for coding, it is better to have suggestions based on the distance to the cursor. Closer means higher. When writing a function, I am mainly interested in the variable names I recently used. 5. Sometimes, it does not work at all, but I haven't investigated the bug. :( Signed-off-by: Slava Zanko <slavazanko@gmail.com>
548 lines
18 KiB
C
548 lines
18 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 "../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;
|
|
|
|
{
|
|
gchar **list_of_types = mc_search_get_types_strings_array();
|
|
int REPLACE_DLG_HEIGHT = REPLACE_DLG_MIN_HEIGHT + g_strv_length (list_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,
|
|
g_strv_length (list_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;
|
|
|
|
{
|
|
int i;
|
|
gchar **list_of_types = mc_search_get_types_strings_array();
|
|
int SEARCH_DLG_HEIGHT = SEARCH_DLG_MIN_HEIGHT + g_strv_length (list_of_types) - SEARCH_DLG_HEIGHT_SUPPLY;
|
|
|
|
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,
|
|
g_strv_length (list_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
|
|
/* 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);
|
|
#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);
|
|
|
|
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)
|
|
for (curr += word_len; *curr; curr++)
|
|
edit_insert (edit, *curr);
|
|
}
|
|
|
|
/* 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;
|
|
}
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|