Add edit_add_window() function.
[midnight-commander.git] / src / viewer / dialogs.c
blobed492616e7133744e759c0e2d61e9d31282a8063
1 /*
2 Internal file viewer for the Midnight Commander
3 Function for paint dialogs
5 Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003,
6 2004, 2005, 2006, 2007, 2009, 2011
7 The Free Software Foundation, Inc.
9 Written by:
10 Miguel de Icaza, 1994, 1995, 1998
11 Janne Kukonlehto, 1994, 1995
12 Jakub Jelinek, 1995
13 Joseph M. Hinkle, 1996
14 Norbert Warmuth, 1997
15 Pavel Machek, 1998
16 Roland Illig <roland.illig@gmx.de>, 2004, 2005
17 Slava Zanko <slavazanko@google.com>, 2009
18 Andrew Borodin <aborodin@vmail.ru>, 2009
19 Ilia Maslakov <il.smind@gmail.com>, 2009
21 This file is part of the Midnight Commander.
23 The Midnight Commander is free software: you can redistribute it
24 and/or modify it under the terms of the GNU General Public License as
25 published by the Free Software Foundation, either version 3 of the License,
26 or (at your option) any later version.
28 The Midnight Commander is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU General Public License for more details.
33 You should have received a copy of the GNU General Public License
34 along with this program. If not, see <http://www.gnu.org/licenses/>.
37 #include <config.h>
39 #include <stdlib.h>
40 #include <sys/types.h>
42 #include "lib/global.h"
43 #include "lib/search.h"
44 #include "lib/strutil.h"
45 #include "lib/widget.h"
46 #include "lib/charsets.h"
48 #include "src/history.h"
50 #include "internal.h"
52 /*** global variables ****************************************************************************/
54 mcview_search_options_t mcview_search_options = {
55 .type = MC_SEARCH_T_NORMAL,
56 .case_sens = FALSE,
57 .backwards = FALSE,
58 .whole_words = FALSE,
59 .all_codepages = FALSE
62 /*** file scope macro definitions ****************************************************************/
64 /*** file scope type declarations ****************************************************************/
66 /*** file scope variables ************************************************************************/
68 /*** file scope functions ************************************************************************/
69 /* --------------------------------------------------------------------------------------------- */
71 /* --------------------------------------------------------------------------------------------- */
72 /*** public functions ****************************************************************************/
73 /* --------------------------------------------------------------------------------------------- */
75 gboolean
76 mcview_dialog_search (mcview_t * view)
78 int SEARCH_DLG_MIN_HEIGHT = 12;
79 int SEARCH_DLG_HEIGHT_SUPPLY = 3;
80 int SEARCH_DLG_WIDTH = 58;
82 char *exp = NULL;
83 int qd_result;
85 size_t num_of_types;
86 gchar **list_of_types = mc_search_get_types_strings_array (&num_of_types);
87 int SEARCH_DLG_HEIGHT = SEARCH_DLG_MIN_HEIGHT + num_of_types - SEARCH_DLG_HEIGHT_SUPPLY;
89 QuickWidget quick_widgets[] = {
90 QUICK_BUTTON (6, 10, SEARCH_DLG_HEIGHT - 3, SEARCH_DLG_HEIGHT, N_("&Cancel"), B_CANCEL,
91 NULL),
92 QUICK_BUTTON (2, 10, SEARCH_DLG_HEIGHT - 3, SEARCH_DLG_HEIGHT, N_("&OK"), B_ENTER, NULL),
93 #ifdef HAVE_CHARSET
94 QUICK_CHECKBOX (SEARCH_DLG_WIDTH / 2 + 3, SEARCH_DLG_WIDTH, 8, SEARCH_DLG_HEIGHT,
95 N_("&All charsets"), &mcview_search_options.all_codepages),
96 #endif
97 QUICK_CHECKBOX (SEARCH_DLG_WIDTH / 2 + 3, SEARCH_DLG_WIDTH, 7, SEARCH_DLG_HEIGHT,
98 N_("&Whole words"), &mcview_search_options.whole_words),
99 QUICK_CHECKBOX (SEARCH_DLG_WIDTH / 2 + 3, SEARCH_DLG_WIDTH, 6, SEARCH_DLG_HEIGHT,
100 N_("&Backwards"), &mcview_search_options.backwards),
101 QUICK_CHECKBOX (SEARCH_DLG_WIDTH / 2 + 3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT,
102 N_("Cas&e sensitive"), &mcview_search_options.case_sens),
103 QUICK_RADIO (3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT,
104 num_of_types, (const char **) list_of_types,
105 (int *) &mcview_search_options.type),
106 QUICK_INPUT (3, SEARCH_DLG_WIDTH, 3, SEARCH_DLG_HEIGHT,
107 INPUT_LAST_TEXT, SEARCH_DLG_WIDTH - 6, 0, MC_HISTORY_SHARED_SEARCH, &exp),
108 QUICK_LABEL (3, SEARCH_DLG_WIDTH, 2, SEARCH_DLG_HEIGHT, N_("Enter search string:")),
109 QUICK_END
112 QuickDialog Quick_input = {
113 SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT, -1, -1,
114 N_("Search"), "[Input Line Keys]",
115 quick_widgets, NULL, NULL, FALSE
118 qd_result = quick_dialog (&Quick_input);
119 g_strfreev (list_of_types);
121 if ((qd_result == B_CANCEL) || (exp == NULL) || (exp[0] == '\0'))
123 g_free (exp);
124 return FALSE;
127 #ifdef HAVE_CHARSET
129 GString *tmp = str_convert_to_input (exp);
131 if (tmp)
133 g_free (exp);
134 exp = g_string_free (tmp, FALSE);
137 #endif
139 g_free (view->last_search_string);
140 view->last_search_string = exp;
141 mcview_nroff_seq_free (&view->search_nroff_seq);
142 mc_search_free (view->search);
144 view->search = mc_search_new (view->last_search_string, -1);
145 view->search_nroff_seq = mcview_nroff_seq_new (view);
146 if (view->search != NULL)
148 view->search->search_type = mcview_search_options.type;
149 view->search->is_all_charsets = mcview_search_options.all_codepages;
150 view->search->is_case_sensitive = mcview_search_options.case_sens;
151 view->search->whole_words = mcview_search_options.whole_words;
152 view->search->search_fn = mcview_search_cmd_callback;
153 view->search->update_fn = mcview_search_update_cmd_callback;
156 return (view->search != NULL);
159 /* --------------------------------------------------------------------------------------------- */
161 gboolean
162 mcview_dialog_goto (mcview_t * view, off_t * offset)
164 typedef enum
166 MC_VIEW_GOTO_LINENUM = 0,
167 MC_VIEW_GOTO_PERCENT = 1,
168 MC_VIEW_GOTO_OFFSET_DEC = 2,
169 MC_VIEW_GOTO_OFFSET_HEX = 3
170 } mcview_goto_type_t;
172 const char *mc_view_goto_str[] = {
173 N_("&Line number (decimal)"),
174 N_("Pe&rcents"),
175 N_("&Decimal offset"),
176 N_("He&xadecimal offset")
179 const int goto_dlg_height = 12;
180 int goto_dlg_width = 40;
182 static mcview_goto_type_t current_goto_type = MC_VIEW_GOTO_LINENUM;
184 size_t i;
186 size_t num_of_types = sizeof (mc_view_goto_str) / sizeof (mc_view_goto_str[0]);
187 char *exp = NULL;
188 int qd_result;
189 gboolean res = FALSE;
191 QuickWidget quick_widgets[] = {
192 QUICK_BUTTON (6, 10, goto_dlg_height - 3, goto_dlg_height, N_("&Cancel"), B_CANCEL, NULL),
193 QUICK_BUTTON (2, 10, goto_dlg_height - 3, goto_dlg_height, N_("&OK"), B_ENTER, NULL),
194 QUICK_RADIO (3, goto_dlg_width, 4, goto_dlg_height,
195 num_of_types, (const char **) mc_view_goto_str, (int *) &current_goto_type),
196 QUICK_INPUT (3, goto_dlg_width, 2, goto_dlg_height,
197 INPUT_LAST_TEXT, goto_dlg_width - 6, 0, MC_HISTORY_VIEW_GOTO, &exp),
198 QUICK_END
201 QuickDialog Quick_input = {
202 goto_dlg_width, goto_dlg_height, -1, -1,
203 N_("Goto"), "[Input Line Keys]",
204 quick_widgets, NULL, NULL, FALSE
207 #ifdef ENABLE_NLS
208 for (i = 0; i < num_of_types; i++)
209 mc_view_goto_str[i] = _(mc_view_goto_str[i]);
211 quick_widgets[0].u.button.text = _(quick_widgets[0].u.button.text);
212 quick_widgets[1].u.button.text = _(quick_widgets[1].u.button.text);
213 #endif
215 /* calculate widget coordinates */
217 int b0_len, b1_len, len;
218 const int button_gap = 2;
220 /* preliminary dialog width */
221 goto_dlg_width = max (goto_dlg_width, str_term_width1 (Quick_input.title) + 4);
223 /* length of radiobuttons */
224 for (i = 0; i < num_of_types; i++)
225 goto_dlg_width = max (goto_dlg_width, str_term_width1 (mc_view_goto_str[i]) + 10);
227 /* length of buttons */
228 b0_len = str_term_width1 (quick_widgets[0].u.button.text) + 3;
229 b1_len = str_term_width1 (quick_widgets[1].u.button.text) + 5; /* default button */
230 len = b0_len + b1_len + button_gap * 2;
232 /* dialog width */
233 Quick_input.xlen = max (goto_dlg_width, len + 6);
235 /* correct widget coordinates */
236 for (i = sizeof (quick_widgets) / sizeof (quick_widgets[0]); i > 0; i--)
237 quick_widgets[i - 1].x_divisions = Quick_input.xlen;
239 /* input length */
240 quick_widgets[3].u.input.len = Quick_input.xlen - 6;
242 /* button positions */
243 quick_widgets[1].relative_x = Quick_input.xlen / 2 - len / 2;
244 quick_widgets[0].relative_x = quick_widgets[1].relative_x + b1_len + button_gap;
247 /* run dialog */
248 qd_result = quick_dialog (&Quick_input);
250 *offset = -1;
252 /* check input line value */
253 if ((qd_result != B_CANCEL) && (exp != NULL) && (exp[0] != '\0'))
255 int base = (current_goto_type == MC_VIEW_GOTO_OFFSET_HEX) ? 16 : 10;
256 off_t addr;
257 char *error;
259 res = TRUE;
261 addr = strtoll (exp, &error, base);
262 if ((*error == '\0') && (addr >= 0))
264 switch (current_goto_type)
266 case MC_VIEW_GOTO_LINENUM:
267 mcview_coord_to_offset (view, offset, addr, 0);
268 *offset = mcview_bol (view, *offset, 0);
269 break;
270 case MC_VIEW_GOTO_PERCENT:
271 if (addr > 100)
272 addr = 100;
273 *offset = addr * mcview_get_filesize (view) / 100;
274 if (!view->hex_mode)
275 *offset = mcview_bol (view, *offset, 0);
276 break;
277 case MC_VIEW_GOTO_OFFSET_DEC:
278 case MC_VIEW_GOTO_OFFSET_HEX:
279 *offset = addr;
280 if (!view->hex_mode)
281 *offset = mcview_bol (view, *offset, 0);
282 else
284 addr = mcview_get_filesize (view);
285 if (*offset > addr)
286 *offset = addr;
288 break;
289 default:
290 *offset = 0;
291 break;
296 g_free (exp);
297 return res;