2 Search functions for diffviewer.
4 Copyright (C) 2010-2024
5 Free Software Foundation, Inc.
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/>.
31 #include "lib/global.h"
32 #include "lib/strutil.h"
33 #include "lib/tty/key.h"
34 #include "lib/widget.h"
36 #include "lib/charsets.h"
39 #include "src/history.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
;
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
,
67 .all_codepages
= FALSE
,
70 /* --------------------------------------------------------------------------------------------- */
71 /*** file scope functions ************************************************************************/
72 /* --------------------------------------------------------------------------------------------- */
75 mcdiffview_dialog_search (WDiff
*dview
)
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
[] = {
87 QUICK_LABELED_INPUT (N_("Enter search string:"), input_label_above
, INPUT_LAST_TEXT
,
88 MC_HISTORY_SHARED_SEARCH
, &exp
, NULL
, FALSE
, FALSE
,
90 QUICK_SEPARATOR (TRUE
),
92 QUICK_RADIO (num_of_types
, (const char **) list_of_types
,
93 (int *) &mcdiffview_search_options
.type
, NULL
),
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
),
99 QUICK_CHECKBOX (N_("&All charsets"), &mcdiffview_search_options
.all_codepages
, NULL
),
102 QUICK_BUTTONS_OK_CANCEL
,
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')
129 tmp
= str_convert_to_input (exp
);
132 exp
= g_string_free (tmp
, FALSE
);
138 g_free (dview
->search
.last_string
);
139 dview
->search
.last_string
= exp
;
144 /* --------------------------------------------------------------------------------------------- */
147 mcdiffview_do_search_backward (WDiff
*dview
)
151 if (dview
->search
.last_accessed_num_line
< 0)
153 dview
->search
.last_accessed_num_line
= -1;
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
--)
164 p
= (DIFFLN
*) & g_array_index (dview
->a
[dview
->ord
], DIFFLN
, (size_t) ind
);
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
;
178 /* --------------------------------------------------------------------------------------------- */
182 mcdiffview_do_search_forward (WDiff
*dview
)
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
;
194 for (ind
= (size_t) ++dview
->search
.last_accessed_num_line
; ind
< dview
->a
[dview
->ord
]->len
;
199 p
= (DIFFLN
*) & g_array_index (dview
->a
[dview
->ord
], DIFFLN
, ind
);
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
;
213 /* --------------------------------------------------------------------------------------------- */
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
);
228 present_result
= mcdiffview_do_search_forward (dview
);
231 tty_disable_interrupt_key ();
235 dview
->search
.last_found_line
= -1;
236 query_dialog (_("Search"), _(STR_E_NOTFOUND
), D_NORMAL
, 1, _("&Dismiss"));
240 /* --------------------------------------------------------------------------------------------- */
241 /*** public functions ****************************************************************************/
242 /* --------------------------------------------------------------------------------------------- */
245 dview_search_cmd (WDiff
*dview
)
247 if (dview
->dsrc
!= DATA_SRC_MEM
)
249 error_dialog (_("Search"), _("Search is disabled"));
253 if (!mcdiffview_dialog_search (dview
))
256 mc_search_free (dview
->search
.handle
);
258 dview
->search
.handle
= mc_search_new (dview
->search
.last_string
, cp_source
);
260 dview
->search
.handle
= mc_search_new (dview
->search
.last_string
, NULL
);
263 if (dview
->search
.handle
== NULL
)
266 dview
->search
.handle
->search_type
= mcdiffview_search_options
.type
;
268 dview
->search
.handle
->is_all_charsets
= mcdiffview_search_options
.all_codepages
;
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 /* --------------------------------------------------------------------------------------------- */
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
);
286 mcdiffview_do_search (dview
);
289 /* --------------------------------------------------------------------------------------------- */