2 Search functions for diffviewer.
4 Copyright (C) 2010, 2011
5 The Free Software Foundation, Inc.
8 Slava Zanko <slavazanko@gmail.com>, 2010.
10 This file is part of the Midnight Commander.
12 The Midnight Commander is free software: you can redistribute it
13 and/or modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation, either version 3 of the License,
15 or (at your option) any later version.
17 The Midnight Commander is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
30 #include "lib/global.h"
31 #include "lib/strutil.h"
32 #include "lib/tty/key.h"
33 #include "lib/widget.h"
35 #include "lib/charsets.h"
38 #include "src/history.h"
42 /*** global variables ****************************************************************************/
44 /*** file scope macro definitions ****************************************************************/
46 #define SEARCH_DLG_WIDTH 58
47 #define SEARCH_DLG_HEIGHT 13
49 /*** file scope type declarations ****************************************************************/
51 typedef struct mcdiffview_search_options_struct
53 mc_search_type_t type
;
57 gboolean all_codepages
;
58 } mcdiffview_search_options_t
;
60 /*** file scope variables ************************************************************************/
62 static mcdiffview_search_options_t mcdiffview_search_options
= {
63 .type
= MC_SEARCH_T_NORMAL
,
67 .all_codepages
= FALSE
,
70 /*** file scope functions ************************************************************************/
71 /* --------------------------------------------------------------------------------------------- */
73 #define DLG_BTN1_text N_("&Cancel")
74 #define DLG_BTN2_text N_("&OK")
77 mcdiffview_dialog_fix_buttons_positions (QuickDialog
* dlg
)
79 size_t str_cancel_len
, str_ok_len
;
80 size_t first_start_position
;
82 str_cancel_len
= str_term_width1 (_(DLG_BTN1_text
)) + 4;
83 str_ok_len
= str_term_width1 (_(DLG_BTN2_text
)) + 6;
85 first_start_position
= (SEARCH_DLG_WIDTH
- str_cancel_len
- str_ok_len
- 1) / 2;
86 dlg
->widgets
[1].relative_x
= first_start_position
;
87 dlg
->widgets
[0].relative_x
= first_start_position
+ str_ok_len
+ 1;
90 /* --------------------------------------------------------------------------------------------- */
93 mcdiffview_dialog_search (WDiff
* dview
)
100 gchar
**list_of_types
= mc_search_get_types_strings_array (&num_of_types
);
102 QuickWidget search_widgets
[] = {
104 QUICK_BUTTON (3, SEARCH_DLG_WIDTH
, SEARCH_DLG_HEIGHT
- 3, SEARCH_DLG_HEIGHT
, DLG_BTN1_text
,
107 QUICK_BUTTON (3, SEARCH_DLG_WIDTH
, SEARCH_DLG_HEIGHT
- 3, SEARCH_DLG_HEIGHT
, DLG_BTN2_text
,
111 QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH
, 8, SEARCH_DLG_HEIGHT
, N_("&All charsets"),
112 &mcdiffview_search_options
.all_codepages
),
115 QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH
, 7, SEARCH_DLG_HEIGHT
, N_("&Whole words"),
116 &mcdiffview_search_options
.whole_words
),
118 QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH
, 6, SEARCH_DLG_HEIGHT
, N_("&Backwards"),
119 &mcdiffview_search_options
.backwards
),
121 QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH
, 5, SEARCH_DLG_HEIGHT
, N_("Cas&e sensitive"),
122 &mcdiffview_search_options
.case_sens
),
124 QUICK_RADIO (3, SEARCH_DLG_WIDTH
, 5, SEARCH_DLG_HEIGHT
,
125 num_of_types
, (const char **) list_of_types
,
126 (int *) &mcdiffview_search_options
.type
),
128 QUICK_INPUT (3, SEARCH_DLG_WIDTH
, 3, SEARCH_DLG_HEIGHT
,
129 INPUT_LAST_TEXT
, SEARCH_DLG_WIDTH
- 6, 0,
130 MC_HISTORY_SHARED_SEARCH
,
133 QUICK_LABEL (3, SEARCH_DLG_WIDTH
, 2, SEARCH_DLG_HEIGHT
, N_("Enter search string:")),
137 QuickDialog search_input
= {
138 SEARCH_DLG_WIDTH
, SEARCH_DLG_HEIGHT
, -1, -1,
139 N_("Search"), "[Input Line Keys]",
140 search_widgets
, NULL
, NULL
, FALSE
143 mcdiffview_dialog_fix_buttons_positions (&search_input
);
145 qd_result
= quick_dialog (&search_input
);
146 g_strfreev (list_of_types
);
149 if ((qd_result
== B_CANCEL
) || (exp
== NULL
) || (exp
[0] == '\0'))
157 GString
*tmp
= str_convert_to_input (exp
);
162 exp
= g_string_free (tmp
, FALSE
);
167 g_free (dview
->search
.last_string
);
168 dview
->search
.last_string
= exp
;
173 /* --------------------------------------------------------------------------------------------- */
176 mcdiffview_do_search_backward (WDiff
* dview
)
181 if (dview
->search
.last_accessed_num_line
< 0)
183 dview
->search
.last_accessed_num_line
= -1;
187 if ((size_t) dview
->search
.last_accessed_num_line
>= dview
->a
[dview
->ord
]->len
)
188 dview
->search
.last_accessed_num_line
= (ssize_t
) dview
->a
[dview
->ord
]->len
;
190 for (ind
= --dview
->search
.last_accessed_num_line
; ind
>= 0; ind
--)
192 p
= (DIFFLN
*) & g_array_index (dview
->a
[dview
->ord
], DIFFLN
, (size_t) ind
);
196 if (mc_search_run (dview
->search
.handle
, p
->p
, 0, p
->u
.len
, NULL
))
198 dview
->skip_rows
= dview
->search
.last_found_line
=
199 dview
->search
.last_accessed_num_line
= ind
;
206 /* --------------------------------------------------------------------------------------------- */
210 mcdiffview_do_search_forward (WDiff
* dview
)
215 if (dview
->search
.last_accessed_num_line
< 0)
216 dview
->search
.last_accessed_num_line
= -1;
217 else if ((size_t) dview
->search
.last_accessed_num_line
>= dview
->a
[dview
->ord
]->len
)
219 dview
->search
.last_accessed_num_line
= (ssize_t
) dview
->a
[dview
->ord
]->len
;
223 for (ind
= (size_t)++ dview
->search
.last_accessed_num_line
; ind
< dview
->a
[dview
->ord
]->len
;
226 p
= (DIFFLN
*) & g_array_index (dview
->a
[dview
->ord
], DIFFLN
, ind
);
230 if (mc_search_run (dview
->search
.handle
, p
->p
, 0, p
->u
.len
, NULL
))
232 dview
->skip_rows
= dview
->search
.last_found_line
=
233 dview
->search
.last_accessed_num_line
= (ssize_t
) ind
;
240 /* --------------------------------------------------------------------------------------------- */
243 mcdiffview_do_search (WDiff
* dview
)
245 gboolean present_result
= FALSE
;
247 tty_enable_interrupt_key ();
249 if (mcdiffview_search_options
.backwards
)
251 present_result
= mcdiffview_do_search_backward (dview
);
255 present_result
= mcdiffview_do_search_forward (dview
);
258 tty_disable_interrupt_key ();
262 dview
->search
.last_found_line
= -1;
263 error_dialog (_("Search"), _("Search string not found"));
267 /* --------------------------------------------------------------------------------------------- */
268 /*** public functions ****************************************************************************/
269 /* --------------------------------------------------------------------------------------------- */
272 dview_search_cmd (WDiff
* dview
)
274 if (dview
->dsrc
!= DATA_SRC_MEM
)
276 error_dialog (_("Search"), _("Search is disabled"));
280 if (!mcdiffview_dialog_search (dview
))
283 mc_search_free (dview
->search
.handle
);
284 dview
->search
.handle
= mc_search_new (dview
->search
.last_string
, -1);
286 if (dview
->search
.handle
== NULL
)
289 dview
->search
.handle
->search_type
= mcdiffview_search_options
.type
;
290 dview
->search
.handle
->is_all_charsets
= mcdiffview_search_options
.all_codepages
;
291 dview
->search
.handle
->is_case_sensitive
= mcdiffview_search_options
.case_sens
;
292 dview
->search
.handle
->whole_words
= mcdiffview_search_options
.whole_words
;
294 mcdiffview_do_search (dview
);
297 /* --------------------------------------------------------------------------------------------- */
300 dview_continue_search_cmd (WDiff
* dview
)
302 if (dview
->dsrc
!= DATA_SRC_MEM
)
303 error_dialog (_("Search"), _("Search is disabled"));
304 else if (dview
->search
.handle
== NULL
)
305 dview_search_cmd (dview
);
307 mcdiffview_do_search (dview
);
310 /* --------------------------------------------------------------------------------------------- */