(file_op_context_create_ui): apply callback to the "Abort" button
[midnight-commander.git] / src / diffviewer / search.c
blobd022bf2218535b16d180f104d7b1f05263c43362
1 /*
2 Search functions for diffviewer.
4 Copyright (C) 2010-2024
5 Free Software Foundation, Inc.
7 Written by:
8 Slava Zanko <slavazanko@gmail.com>, 2010.
9 Andrew Borodin <aborodin@vmail.ru>, 2012-2022
11 This file is part of the Midnight Commander.
13 The Midnight Commander is free software: you can redistribute it
14 and/or modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation, either version 3 of the License,
16 or (at your option) any later version.
18 The Midnight Commander is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include <config.h>
29 #include <stdio.h>
31 #include "lib/global.h"
32 #include "lib/strutil.h"
33 #include "lib/tty/key.h"
34 #include "lib/widget.h"
35 #ifdef HAVE_CHARSET
36 #include "lib/charsets.h"
37 #endif
39 #include "src/history.h"
41 #include "internal.h"
43 /*** global variables ****************************************************************************/
45 /*** file scope macro definitions ****************************************************************/
47 /*** file scope type declarations ****************************************************************/
49 typedef struct mcdiffview_search_options_struct
51 mc_search_type_t type;
52 gboolean case_sens;
53 gboolean backwards;
54 gboolean whole_words;
55 gboolean all_codepages;
56 } mcdiffview_search_options_t;
58 /*** forward declarations (file scope functions) *************************************************/
60 /*** file scope variables ************************************************************************/
62 static mcdiffview_search_options_t mcdiffview_search_options = {
63 .type = MC_SEARCH_T_NORMAL,
64 .case_sens = FALSE,
65 .backwards = FALSE,
66 .whole_words = FALSE,
67 .all_codepages = FALSE,
70 /* --------------------------------------------------------------------------------------------- */
71 /*** file scope functions ************************************************************************/
72 /* --------------------------------------------------------------------------------------------- */
74 static gboolean
75 mcdiffview_dialog_search (WDiff *dview)
77 char *exp = NULL;
78 int qd_result;
79 size_t num_of_types = 0;
80 gchar **list_of_types;
82 list_of_types = mc_search_get_types_strings_array (&num_of_types);
85 quick_widget_t quick_widgets[] = {
86 /* *INDENT-OFF* */
87 QUICK_LABELED_INPUT (N_("Enter search string:"), input_label_above, INPUT_LAST_TEXT,
88 MC_HISTORY_SHARED_SEARCH, &exp, NULL, FALSE, FALSE,
89 INPUT_COMPLETE_NONE),
90 QUICK_SEPARATOR (TRUE),
91 QUICK_START_COLUMNS,
92 QUICK_RADIO (num_of_types, (const char **) list_of_types,
93 (int *) &mcdiffview_search_options.type, NULL),
94 QUICK_NEXT_COLUMN,
95 QUICK_CHECKBOX (N_("Cas&e sensitive"), &mcdiffview_search_options.case_sens, NULL),
96 QUICK_CHECKBOX (N_("&Backwards"), &mcdiffview_search_options.backwards, NULL),
97 QUICK_CHECKBOX (N_("&Whole words"), &mcdiffview_search_options.whole_words, NULL),
98 #ifdef HAVE_CHARSET
99 QUICK_CHECKBOX (N_("&All charsets"), &mcdiffview_search_options.all_codepages, NULL),
100 #endif
101 QUICK_STOP_COLUMNS,
102 QUICK_BUTTONS_OK_CANCEL,
103 QUICK_END
104 /* *INDENT-ON* */
107 WRect r = { -1, -1, 0, 58 };
109 quick_dialog_t qdlg = {
110 r, N_("Search"), "[Input Line Keys]",
111 quick_widgets, NULL, NULL
114 qd_result = quick_dialog (&qdlg);
117 g_strfreev (list_of_types);
119 if (qd_result == B_CANCEL || exp[0] == '\0')
121 g_free (exp);
122 return FALSE;
125 #ifdef HAVE_CHARSET
127 GString *tmp;
129 tmp = str_convert_to_input (exp);
130 g_free (exp);
131 if (tmp != NULL)
132 exp = g_string_free (tmp, FALSE);
133 else
134 exp = g_strdup ("");
136 #endif
138 g_free (dview->search.last_string);
139 dview->search.last_string = exp;
141 return TRUE;
144 /* --------------------------------------------------------------------------------------------- */
146 static gboolean
147 mcdiffview_do_search_backward (WDiff *dview)
149 ssize_t ind;
151 if (dview->search.last_accessed_num_line < 0)
153 dview->search.last_accessed_num_line = -1;
154 return FALSE;
157 if ((size_t) dview->search.last_accessed_num_line >= dview->a[dview->ord]->len)
158 dview->search.last_accessed_num_line = (ssize_t) dview->a[dview->ord]->len;
160 for (ind = --dview->search.last_accessed_num_line; ind >= 0; ind--)
162 DIFFLN *p;
164 p = (DIFFLN *) & g_array_index (dview->a[dview->ord], DIFFLN, (size_t) ind);
165 if (p->u.len == 0)
166 continue;
168 if (mc_search_run (dview->search.handle, p->p, 0, p->u.len, NULL))
170 dview->skip_rows = dview->search.last_found_line =
171 dview->search.last_accessed_num_line = ind;
172 return TRUE;
175 return FALSE;
178 /* --------------------------------------------------------------------------------------------- */
181 static gboolean
182 mcdiffview_do_search_forward (WDiff *dview)
184 size_t ind;
186 if (dview->search.last_accessed_num_line < 0)
187 dview->search.last_accessed_num_line = -1;
188 else if ((size_t) dview->search.last_accessed_num_line >= dview->a[dview->ord]->len)
190 dview->search.last_accessed_num_line = (ssize_t) dview->a[dview->ord]->len;
191 return FALSE;
194 for (ind = (size_t) ++dview->search.last_accessed_num_line; ind < dview->a[dview->ord]->len;
195 ind++)
197 DIFFLN *p;
199 p = (DIFFLN *) & g_array_index (dview->a[dview->ord], DIFFLN, ind);
200 if (p->u.len == 0)
201 continue;
203 if (mc_search_run (dview->search.handle, p->p, 0, p->u.len, NULL))
205 dview->skip_rows = dview->search.last_found_line =
206 dview->search.last_accessed_num_line = (ssize_t) ind;
207 return TRUE;
210 return FALSE;
213 /* --------------------------------------------------------------------------------------------- */
215 static void
216 mcdiffview_do_search (WDiff *dview)
218 gboolean present_result = FALSE;
220 tty_enable_interrupt_key ();
222 if (mcdiffview_search_options.backwards)
224 present_result = mcdiffview_do_search_backward (dview);
226 else
228 present_result = mcdiffview_do_search_forward (dview);
231 tty_disable_interrupt_key ();
233 if (!present_result)
235 dview->search.last_found_line = -1;
236 query_dialog (_("Search"), _(STR_E_NOTFOUND), D_NORMAL, 1, _("&Dismiss"));
240 /* --------------------------------------------------------------------------------------------- */
241 /*** public functions ****************************************************************************/
242 /* --------------------------------------------------------------------------------------------- */
244 void
245 dview_search_cmd (WDiff *dview)
247 if (dview->dsrc != DATA_SRC_MEM)
249 error_dialog (_("Search"), _("Search is disabled"));
250 return;
253 if (!mcdiffview_dialog_search (dview))
254 return;
256 mc_search_free (dview->search.handle);
257 #ifdef HAVE_CHARSET
258 dview->search.handle = mc_search_new (dview->search.last_string, cp_source);
259 #else
260 dview->search.handle = mc_search_new (dview->search.last_string, NULL);
261 #endif
263 if (dview->search.handle == NULL)
264 return;
266 dview->search.handle->search_type = mcdiffview_search_options.type;
267 #ifdef HAVE_CHARSET
268 dview->search.handle->is_all_charsets = mcdiffview_search_options.all_codepages;
269 #endif
270 dview->search.handle->is_case_sensitive = mcdiffview_search_options.case_sens;
271 dview->search.handle->whole_words = mcdiffview_search_options.whole_words;
273 mcdiffview_do_search (dview);
276 /* --------------------------------------------------------------------------------------------- */
278 void
279 dview_continue_search_cmd (WDiff *dview)
281 if (dview->dsrc != DATA_SRC_MEM)
282 error_dialog (_("Search"), _("Search is disabled"));
283 else if (dview->search.handle == NULL)
284 dview_search_cmd (dview);
285 else
286 mcdiffview_do_search (dview);
289 /* --------------------------------------------------------------------------------------------- */