Portability: use g_ascii_strtoll instead of strtoll, atoll and atof.
[midnight-commander.git] / src / viewer / dialogs.c
blob396667174d8e1fbb02488b257c8a605f93a99bbd
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 #ifdef HAVE_CHARSET
47 #include "lib/charsets.h"
48 #endif
50 #include "src/history.h"
52 #include "internal.h"
54 /*** global variables ****************************************************************************/
56 mcview_search_options_t mcview_search_options = {
57 .type = MC_SEARCH_T_NORMAL,
58 .case_sens = FALSE,
59 .backwards = FALSE,
60 .whole_words = FALSE,
61 .all_codepages = FALSE
64 /*** file scope macro definitions ****************************************************************/
66 /*** file scope type declarations ****************************************************************/
68 /*** file scope variables ************************************************************************/
70 /*** file scope functions ************************************************************************/
71 /* --------------------------------------------------------------------------------------------- */
73 /* --------------------------------------------------------------------------------------------- */
74 /*** public functions ****************************************************************************/
75 /* --------------------------------------------------------------------------------------------- */
77 gboolean
78 mcview_dialog_search (mcview_t * view)
80 int SEARCH_DLG_MIN_HEIGHT = 12;
81 int SEARCH_DLG_HEIGHT_SUPPLY = 3;
82 int SEARCH_DLG_WIDTH = 58;
84 char *exp = NULL;
85 int qd_result;
87 size_t num_of_types;
88 gchar **list_of_types = mc_search_get_types_strings_array (&num_of_types);
89 int SEARCH_DLG_HEIGHT = SEARCH_DLG_MIN_HEIGHT + num_of_types - SEARCH_DLG_HEIGHT_SUPPLY;
91 QuickWidget quick_widgets[] = {
92 QUICK_BUTTON (6, 10, SEARCH_DLG_HEIGHT - 3, SEARCH_DLG_HEIGHT, N_("&Cancel"), B_CANCEL,
93 NULL),
94 QUICK_BUTTON (2, 10, SEARCH_DLG_HEIGHT - 3, SEARCH_DLG_HEIGHT, N_("&OK"), B_ENTER, NULL),
95 #ifdef HAVE_CHARSET
96 QUICK_CHECKBOX (SEARCH_DLG_WIDTH / 2 + 3, SEARCH_DLG_WIDTH, 8, SEARCH_DLG_HEIGHT,
97 N_("&All charsets"), &mcview_search_options.all_codepages),
98 #endif
99 QUICK_CHECKBOX (SEARCH_DLG_WIDTH / 2 + 3, SEARCH_DLG_WIDTH, 7, SEARCH_DLG_HEIGHT,
100 N_("&Whole words"), &mcview_search_options.whole_words),
101 QUICK_CHECKBOX (SEARCH_DLG_WIDTH / 2 + 3, SEARCH_DLG_WIDTH, 6, SEARCH_DLG_HEIGHT,
102 N_("&Backwards"), &mcview_search_options.backwards),
103 QUICK_CHECKBOX (SEARCH_DLG_WIDTH / 2 + 3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT,
104 N_("Cas&e sensitive"), &mcview_search_options.case_sens),
105 QUICK_RADIO (3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT,
106 num_of_types, (const char **) list_of_types,
107 (int *) &mcview_search_options.type),
108 QUICK_INPUT (3, SEARCH_DLG_WIDTH, 3, SEARCH_DLG_HEIGHT,
109 INPUT_LAST_TEXT, SEARCH_DLG_WIDTH - 6, 0, MC_HISTORY_SHARED_SEARCH, &exp),
110 QUICK_LABEL (3, SEARCH_DLG_WIDTH, 2, SEARCH_DLG_HEIGHT, N_("Enter search string:")),
111 QUICK_END
114 QuickDialog Quick_input = {
115 SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT, -1, -1,
116 N_("Search"), "[Input Line Keys]",
117 quick_widgets, NULL, FALSE
120 qd_result = quick_dialog (&Quick_input);
121 g_strfreev (list_of_types);
123 if ((qd_result == B_CANCEL) || (exp == NULL) || (exp[0] == '\0'))
125 g_free (exp);
126 return FALSE;
129 #ifdef HAVE_CHARSET
131 GString *tmp = str_convert_to_input (exp);
133 if (tmp)
135 g_free (exp);
136 exp = g_string_free (tmp, FALSE);
139 #endif
141 g_free (view->last_search_string);
142 view->last_search_string = exp;
143 mcview_nroff_seq_free (&view->search_nroff_seq);
144 mc_search_free (view->search);
146 view->search = mc_search_new (view->last_search_string, -1);
147 view->search_nroff_seq = mcview_nroff_seq_new (view);
148 if (view->search != NULL)
150 view->search->search_type = mcview_search_options.type;
151 view->search->is_all_charsets = mcview_search_options.all_codepages;
152 view->search->is_case_sensitive = mcview_search_options.case_sens;
153 view->search->whole_words = mcview_search_options.whole_words;
154 view->search->search_fn = mcview_search_cmd_callback;
155 view->search->update_fn = mcview_search_update_cmd_callback;
158 return (view->search != NULL);
161 /* --------------------------------------------------------------------------------------------- */
163 gboolean
164 mcview_dialog_goto (mcview_t * view, off_t * offset)
166 typedef enum
168 MC_VIEW_GOTO_LINENUM = 0,
169 MC_VIEW_GOTO_PERCENT = 1,
170 MC_VIEW_GOTO_OFFSET_DEC = 2,
171 MC_VIEW_GOTO_OFFSET_HEX = 3
172 } mcview_goto_type_t;
174 const char *mc_view_goto_str[] = {
175 N_("&Line number (decimal)"),
176 N_("Pe&rcents"),
177 N_("&Decimal offset"),
178 N_("He&xadecimal offset")
181 const int goto_dlg_height = 12;
182 int goto_dlg_width = 40;
184 static mcview_goto_type_t current_goto_type = MC_VIEW_GOTO_LINENUM;
186 size_t i;
188 size_t num_of_types = sizeof (mc_view_goto_str) / sizeof (mc_view_goto_str[0]);
189 char *exp = NULL;
190 int qd_result;
191 gboolean res = FALSE;
193 QuickWidget quick_widgets[] = {
194 QUICK_BUTTON (6, 10, goto_dlg_height - 3, goto_dlg_height, N_("&Cancel"), B_CANCEL, NULL),
195 QUICK_BUTTON (2, 10, goto_dlg_height - 3, goto_dlg_height, N_("&OK"), B_ENTER, NULL),
196 QUICK_RADIO (3, goto_dlg_width, 4, goto_dlg_height,
197 num_of_types, (const char **) mc_view_goto_str, (int *) &current_goto_type),
198 QUICK_INPUT (3, goto_dlg_width, 2, goto_dlg_height,
199 INPUT_LAST_TEXT, goto_dlg_width - 6, 0, MC_HISTORY_VIEW_GOTO, &exp),
200 QUICK_END
203 QuickDialog Quick_input = {
204 goto_dlg_width, goto_dlg_height, -1, -1,
205 N_("Goto"), "[Input Line Keys]",
206 quick_widgets, NULL, FALSE
209 #ifdef ENABLE_NLS
210 for (i = 0; i < num_of_types; i++)
211 mc_view_goto_str[i] = _(mc_view_goto_str[i]);
213 quick_widgets[0].u.button.text = _(quick_widgets[0].u.button.text);
214 quick_widgets[1].u.button.text = _(quick_widgets[1].u.button.text);
215 #endif
217 /* calculate widget coordinates */
219 int b0_len, b1_len, len;
220 const int button_gap = 2;
222 /* preliminary dialog width */
223 goto_dlg_width = max (goto_dlg_width, str_term_width1 (Quick_input.title) + 4);
225 /* length of radiobuttons */
226 for (i = 0; i < num_of_types; i++)
227 goto_dlg_width = max (goto_dlg_width, str_term_width1 (mc_view_goto_str[i]) + 10);
229 /* length of buttons */
230 b0_len = str_term_width1 (quick_widgets[0].u.button.text) + 3;
231 b1_len = str_term_width1 (quick_widgets[1].u.button.text) + 5; /* default button */
232 len = b0_len + b1_len + button_gap * 2;
234 /* dialog width */
235 Quick_input.xlen = max (goto_dlg_width, len + 6);
237 /* correct widget coordinates */
238 for (i = sizeof (quick_widgets) / sizeof (quick_widgets[0]); i > 0; i--)
239 quick_widgets[i - 1].x_divisions = Quick_input.xlen;
241 /* input length */
242 quick_widgets[3].u.input.len = Quick_input.xlen - 6;
244 /* button positions */
245 quick_widgets[1].relative_x = Quick_input.xlen / 2 - len / 2;
246 quick_widgets[0].relative_x = quick_widgets[1].relative_x + b1_len + button_gap;
249 /* run dialog */
250 qd_result = quick_dialog (&Quick_input);
252 *offset = -1;
254 /* check input line value */
255 if ((qd_result != B_CANCEL) && (exp != NULL) && (exp[0] != '\0'))
257 int base = (current_goto_type == MC_VIEW_GOTO_OFFSET_HEX) ? 16 : 10;
258 off_t addr;
259 char *error;
261 res = TRUE;
263 addr = (off_t) g_ascii_strtoll (exp, &error, base);
264 if ((*error == '\0') && (addr >= 0))
266 switch (current_goto_type)
268 case MC_VIEW_GOTO_LINENUM:
269 mcview_coord_to_offset (view, offset, addr, 0);
270 *offset = mcview_bol (view, *offset, 0);
271 break;
272 case MC_VIEW_GOTO_PERCENT:
273 if (addr > 100)
274 addr = 100;
275 *offset = addr * mcview_get_filesize (view) / 100;
276 if (!view->hex_mode)
277 *offset = mcview_bol (view, *offset, 0);
278 break;
279 case MC_VIEW_GOTO_OFFSET_DEC:
280 case MC_VIEW_GOTO_OFFSET_HEX:
281 *offset = addr;
282 if (!view->hex_mode)
283 *offset = mcview_bol (view, *offset, 0);
284 else
286 addr = mcview_get_filesize (view);
287 if (*offset > addr)
288 *offset = addr;
290 break;
291 default:
292 *offset = 0;
293 break;
298 g_free (exp);
299 return res;