1 /*
2    Internal file viewer for the Midnight Commander
3    Function for paint dialogs
4 
5    Copyright (C) 1994-2021
6    Free Software Foundation, Inc.
7 
8    Written by:
9    Miguel de Icaza, 1994, 1995, 1998
10    Janne Kukonlehto, 1994, 1995
11    Jakub Jelinek, 1995
12    Joseph M. Hinkle, 1996
13    Norbert Warmuth, 1997
14    Pavel Machek, 1998
15    Roland Illig <roland.illig@gmx.de>, 2004, 2005
16    Slava Zanko <slavazanko@google.com>, 2009
17    Andrew Borodin <aborodin@vmail.ru>, 2009, 2012
18    Ilia Maslakov <il.smind@gmail.com>, 2009
19 
20    This file is part of the Midnight Commander.
21 
22    The Midnight Commander is free software: you can redistribute it
23    and/or modify it under the terms of the GNU General Public License as
24    published by the Free Software Foundation, either version 3 of the License,
25    or (at your option) any later version.
26 
27    The Midnight Commander is distributed in the hope that it will be useful,
28    but WITHOUT ANY WARRANTY; without even the implied warranty of
29    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30    GNU General Public License for more details.
31 
32    You should have received a copy of the GNU General Public License
33    along with this program.  If not, see <http://www.gnu.org/licenses/>.
34  */
35 
36 #include <config.h>
37 
38 #include <stdlib.h>
39 #include <sys/types.h>
40 
41 #include "lib/global.h"
42 #include "lib/search.h"
43 #include "lib/strutil.h"
44 #include "lib/widget.h"
45 #ifdef HAVE_CHARSET
46 #include "lib/charsets.h"
47 #endif
48 
49 #include "src/history.h"
50 
51 #include "internal.h"
52 
53 /*** global variables ****************************************************************************/
54 
55 /*** file scope macro definitions ****************************************************************/
56 
57 /*** file scope type declarations ****************************************************************/
58 
59 /*** file scope variables ************************************************************************/
60 
61 /*** file scope functions ************************************************************************/
62 /* --------------------------------------------------------------------------------------------- */
63 
64 /* --------------------------------------------------------------------------------------------- */
65 /*** public functions ****************************************************************************/
66 /* --------------------------------------------------------------------------------------------- */
67 
68 gboolean
mcview_dialog_search(WView * view)69 mcview_dialog_search (WView * view)
70 {
71     char *exp = NULL;
72     int qd_result;
73     size_t num_of_types = 0;
74     gchar **list_of_types;
75 
76     list_of_types = mc_search_get_types_strings_array (&num_of_types);
77 
78     {
79         quick_widget_t quick_widgets[] = {
80             /* *INDENT-OFF* */
81             QUICK_LABELED_INPUT (N_("Enter search string:"), input_label_above,
82                                  INPUT_LAST_TEXT, MC_HISTORY_SHARED_SEARCH, &exp,
83                                  NULL, FALSE, FALSE, INPUT_COMPLETE_NONE),
84             QUICK_SEPARATOR (TRUE),
85             QUICK_START_COLUMNS,
86                 QUICK_RADIO (num_of_types, (const char **) list_of_types,
87                              (int *) &mcview_search_options.type, NULL),
88             QUICK_NEXT_COLUMN,
89                 QUICK_CHECKBOX (N_("Cas&e sensitive"), &mcview_search_options.case_sens, NULL),
90                 QUICK_CHECKBOX (N_("&Backwards"), &mcview_search_options.backwards, NULL),
91                 QUICK_CHECKBOX (N_("&Whole words"), &mcview_search_options.whole_words, NULL),
92 #ifdef HAVE_CHARSET
93                 QUICK_CHECKBOX (N_("&All charsets"), &mcview_search_options.all_codepages, NULL),
94 #endif
95             QUICK_STOP_COLUMNS,
96             QUICK_BUTTONS_OK_CANCEL,
97             QUICK_END
98             /* *INDENT-ON* */
99         };
100 
101         quick_dialog_t qdlg = {
102             -1, -1, 58,
103             N_("Search"), "[Input Line Keys]",
104             quick_widgets, NULL, NULL
105         };
106 
107         qd_result = quick_dialog (&qdlg);
108     }
109 
110     g_strfreev (list_of_types);
111 
112     if ((qd_result == B_CANCEL) || (exp == NULL) || (exp[0] == '\0'))
113     {
114         g_free (exp);
115         return FALSE;
116     }
117 
118 #ifdef HAVE_CHARSET
119     {
120         GString *tmp;
121 
122         tmp = str_convert_to_input (exp);
123         g_free (exp);
124         exp = g_string_free (tmp, FALSE);
125     }
126 #endif
127 
128     mcview_search_deinit (view);
129     view->last_search_string = exp;
130 
131     return mcview_search_init (view);
132 }
133 
134 /* --------------------------------------------------------------------------------------------- */
135 
136 gboolean
mcview_dialog_goto(WView * view,off_t * offset)137 mcview_dialog_goto (WView * view, off_t * offset)
138 {
139     typedef enum
140     {
141         MC_VIEW_GOTO_LINENUM = 0,
142         MC_VIEW_GOTO_PERCENT = 1,
143         MC_VIEW_GOTO_OFFSET_DEC = 2,
144         MC_VIEW_GOTO_OFFSET_HEX = 3
145     } mcview_goto_type_t;
146 
147     const char *mc_view_goto_str[] = {
148         N_("&Line number"),
149         N_("Pe&rcents"),
150         N_("&Decimal offset"),
151         N_("He&xadecimal offset")
152     };
153 
154     static mcview_goto_type_t current_goto_type = MC_VIEW_GOTO_LINENUM;
155 
156     size_t num_of_types;
157     char *exp = NULL;
158     int qd_result;
159     gboolean res;
160 
161     num_of_types = G_N_ELEMENTS (mc_view_goto_str);
162 
163 #ifdef ENABLE_NLS
164     {
165         size_t i;
166 
167         for (i = 0; i < num_of_types; i++)
168             mc_view_goto_str[i] = _(mc_view_goto_str[i]);
169     }
170 #endif
171 
172     {
173         quick_widget_t quick_widgets[] = {
174             /* *INDENT-OFF* */
175             QUICK_INPUT (INPUT_LAST_TEXT, MC_HISTORY_VIEW_GOTO, &exp, NULL,
176                          FALSE, FALSE, INPUT_COMPLETE_NONE),
177             QUICK_RADIO (num_of_types, (const char **) mc_view_goto_str, (int *) &current_goto_type,
178                          NULL),
179             QUICK_BUTTONS_OK_CANCEL,
180             QUICK_END
181             /* *INDENT-ON* */
182         };
183 
184         quick_dialog_t qdlg = {
185             -1, -1, 40,
186             N_("Goto"), "[Input Line Keys]",
187             quick_widgets, NULL, NULL
188         };
189 
190         /* run dialog */
191         qd_result = quick_dialog (&qdlg);
192     }
193 
194     *offset = -1;
195 
196     /* check input line value */
197     res = (qd_result != B_CANCEL && exp != NULL && exp[0] != '\0');
198     if (res)
199     {
200         int base = (current_goto_type == MC_VIEW_GOTO_OFFSET_HEX) ? 16 : 10;
201         off_t addr;
202         char *error;
203 
204         addr = (off_t) g_ascii_strtoll (exp, &error, base);
205         if ((*error == '\0') && (addr >= 0))
206         {
207             switch (current_goto_type)
208             {
209             case MC_VIEW_GOTO_LINENUM:
210                 /* Line number entered by user is 1-based. */
211                 if (addr > 0)
212                     addr--;
213                 mcview_coord_to_offset (view, offset, addr, 0);
214                 *offset = mcview_bol (view, *offset, 0);
215                 break;
216             case MC_VIEW_GOTO_PERCENT:
217                 if (addr > 100)
218                     addr = 100;
219                 /* read all data from pipe to get real size */
220                 if (view->growbuf_in_use)
221                     mcview_growbuf_read_all_data (view);
222                 *offset = addr * mcview_get_filesize (view) / 100;
223                 if (!view->mode_flags.hex)
224                     *offset = mcview_bol (view, *offset, 0);
225                 break;
226             case MC_VIEW_GOTO_OFFSET_DEC:
227             case MC_VIEW_GOTO_OFFSET_HEX:
228                 if (!view->mode_flags.hex)
229                 {
230                     if (view->growbuf_in_use)
231                         mcview_growbuf_read_until (view, addr);
232 
233                     *offset = mcview_bol (view, addr, 0);
234                 }
235                 else
236                 {
237                     /* read all data from pipe to get real size */
238                     if (view->growbuf_in_use)
239                         mcview_growbuf_read_all_data (view);
240 
241                     *offset = addr;
242                     addr = mcview_get_filesize (view);
243                     if (*offset > addr)
244                         *offset = addr;
245                 }
246                 break;
247             default:
248                 *offset = 0;
249                 break;
250             }
251         }
252     }
253 
254     g_free (exp);
255     return res;
256 }
257 
258 /* --------------------------------------------------------------------------------------------- */
259