Merge remote branch 'osp/only-directories' into homework
[pantumic.git] / src / diffviewer / search.c
blob30134d90132aa301df123809001c9bba3c2d1e2b
1 /*
2 Search functions for diffviewer.
4 Copyright (C) 2010 The Free Software Foundation, Inc.
6 Written by:
7 Slava Zanko <slavazanko@gmail.com>, 2010.
9 This file is part of the Midnight Commander.
11 The Midnight Commander is free software; you can redistribute it
12 and/or modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2 of the
14 License, or (at your option) any later version.
16 The Midnight Commander is distributed in the hope that it will be
17 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
18 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
24 MA 02110-1301, USA.
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 #include "lib/charsets.h"
37 #include "src/history.h"
39 #include "internal.h"
41 /*** global variables ****************************************************************************/
43 /*** file scope macro definitions ****************************************************************/
45 #define SEARCH_DLG_WIDTH 58
46 #define SEARCH_DLG_HEIGHT 13
48 /*** file scope type declarations ****************************************************************/
50 typedef struct mcdiffview_search_options_struct
52 mc_search_type_t type;
53 gboolean case_sens;
54 gboolean backwards;
55 gboolean whole_words;
56 gboolean all_codepages;
57 } mcdiffview_search_options_t;
59 /*** file scope variables ************************************************************************/
61 static mcdiffview_search_options_t mcdiffview_search_options = {
62 .type = MC_SEARCH_T_NORMAL,
63 .case_sens = FALSE,
64 .backwards = FALSE,
65 .whole_words = FALSE,
66 .all_codepages = FALSE,
69 /*** file scope functions ************************************************************************/
70 /* --------------------------------------------------------------------------------------------- */
72 #define DLG_BTN1_text N_("&Cancel")
73 #define DLG_BTN2_text N_("&OK")
75 static void
76 mcdiffview_dialog_fix_buttons_positions (QuickDialog * dlg)
78 size_t str_cancel_len, str_ok_len;
79 size_t first_start_position;
81 str_cancel_len = str_term_width1 (_(DLG_BTN1_text)) + 4;
82 str_ok_len = str_term_width1 (_(DLG_BTN2_text)) + 6;
84 first_start_position = (SEARCH_DLG_WIDTH - str_cancel_len - str_ok_len - 1) / 2;
85 dlg->widgets[1].relative_x = first_start_position;
86 dlg->widgets[0].relative_x = first_start_position + str_ok_len + 1;
89 /* --------------------------------------------------------------------------------------------- */
91 static gboolean
92 mcdiffview_dialog_search (WDiff * dview)
94 char *exp = NULL;
96 int qd_result;
98 size_t num_of_types;
99 gchar **list_of_types = mc_search_get_types_strings_array (&num_of_types);
101 QuickWidget search_widgets[] = {
102 /* 0 */
103 QUICK_BUTTON (3, SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT - 3, SEARCH_DLG_HEIGHT, DLG_BTN1_text,
104 B_CANCEL, NULL),
105 /* 1 */
106 QUICK_BUTTON (3, SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT - 3, SEARCH_DLG_HEIGHT, DLG_BTN2_text,
107 B_ENTER, NULL),
108 /* 2 */
109 #ifdef HAVE_CHARSET
110 QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 8, SEARCH_DLG_HEIGHT, N_("All charsets"),
111 &mcdiffview_search_options.all_codepages),
112 #endif
114 QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 7, SEARCH_DLG_HEIGHT, N_("&Whole words"),
115 &mcdiffview_search_options.whole_words),
116 /* 3 */
117 QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 6, SEARCH_DLG_HEIGHT, N_("&Backwards"),
118 &mcdiffview_search_options.backwards),
119 /* 4 */
120 QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT, N_("Case &sensitive"),
121 &mcdiffview_search_options.case_sens),
122 /* 5 */
123 QUICK_RADIO (3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT,
124 num_of_types, (const char **) list_of_types,
125 (int *) &mcdiffview_search_options.type),
126 /* 6 */
127 QUICK_INPUT (3, SEARCH_DLG_WIDTH, 3, SEARCH_DLG_HEIGHT,
128 INPUT_LAST_TEXT, SEARCH_DLG_WIDTH - 6, 0,
129 MC_HISTORY_SHARED_SEARCH,
130 &exp),
131 /* 7 */
132 QUICK_LABEL (3, SEARCH_DLG_WIDTH, 2, SEARCH_DLG_HEIGHT, N_("Enter search string:")),
133 QUICK_END
136 QuickDialog search_input = {
137 SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT, -1, -1,
138 N_("Search"), "[Input Line Keys]",
139 search_widgets, NULL, FALSE
142 mcdiffview_dialog_fix_buttons_positions (&search_input);
144 qd_result = quick_dialog (&search_input);
145 g_strfreev (list_of_types);
148 if ((qd_result == B_CANCEL) || (exp == NULL) || (exp[0] == '\0'))
150 g_free (exp);
151 return FALSE;
154 #ifdef HAVE_CHARSET
156 GString *tmp = str_convert_to_input (exp);
158 if (tmp)
160 g_free (exp);
161 exp = g_string_free (tmp, FALSE);
164 #endif
166 g_free (dview->search.last_string);
167 dview->search.last_string = exp;
169 return TRUE;
172 /* --------------------------------------------------------------------------------------------- */
174 static gboolean
175 mcdiffview_do_search_backward (WDiff * dview)
177 ssize_t ind;
178 DIFFLN *p;
180 if (dview->search.last_accessed_num_line < 0)
182 dview->search.last_accessed_num_line = -1;
183 return FALSE;
186 if ((size_t) dview->search.last_accessed_num_line >= dview->a[dview->ord]->len)
187 dview->search.last_accessed_num_line = (ssize_t) dview->a[dview->ord]->len;
189 for (ind = --dview->search.last_accessed_num_line; ind >= 0; ind--)
191 p = (DIFFLN *) & g_array_index (dview->a[dview->ord], DIFFLN, (size_t) ind);
192 if (p->u.len == 0)
193 continue;
195 if (mc_search_run (dview->search.handle, p->p, 0, p->u.len, NULL))
197 dview->skip_rows = dview->search.last_found_line =
198 dview->search.last_accessed_num_line = ind;
199 return TRUE;
202 return FALSE;
205 /* --------------------------------------------------------------------------------------------- */
208 static gboolean
209 mcdiffview_do_search_forward (WDiff * dview)
211 size_t ind;
212 DIFFLN *p;
214 if (dview->search.last_accessed_num_line < 0)
215 dview->search.last_accessed_num_line = -1;
216 else if ((size_t) dview->search.last_accessed_num_line >= dview->a[dview->ord]->len)
218 dview->search.last_accessed_num_line = (ssize_t) dview->a[dview->ord]->len;
219 return FALSE;
222 for (ind = (size_t)++ dview->search.last_accessed_num_line; ind < dview->a[dview->ord]->len;
223 ind++)
225 p = (DIFFLN *) & g_array_index (dview->a[dview->ord], DIFFLN, ind);
226 if (p->u.len == 0)
227 continue;
229 if (mc_search_run (dview->search.handle, p->p, 0, p->u.len, NULL))
231 dview->skip_rows = dview->search.last_found_line =
232 dview->search.last_accessed_num_line = (ssize_t) ind;
233 return TRUE;
236 return FALSE;
239 /* --------------------------------------------------------------------------------------------- */
241 static void
242 mcdiffview_do_search (WDiff * dview)
244 gboolean present_result = FALSE;
246 tty_enable_interrupt_key ();
248 if (mcdiffview_search_options.backwards)
250 present_result = mcdiffview_do_search_backward (dview);
252 else
254 present_result = mcdiffview_do_search_forward (dview);
257 tty_disable_interrupt_key ();
259 if (!present_result)
261 dview->search.last_found_line = -1;
262 error_dialog (_("Search"), _("Search string not found"));
266 /* --------------------------------------------------------------------------------------------- */
267 /*** public functions ****************************************************************************/
268 /* --------------------------------------------------------------------------------------------- */
270 void
271 dview_search_cmd (WDiff * dview)
273 if (dview->dsrc != DATA_SRC_MEM)
275 error_dialog (_("Search"), _("Search is disabled"));
276 return;
279 if (!mcdiffview_dialog_search (dview))
280 return;
282 mc_search_free (dview->search.handle);
283 dview->search.handle = mc_search_new (dview->search.last_string, -1);
285 if (dview->search.handle == NULL)
286 return;
288 dview->search.handle->search_type = mcdiffview_search_options.type;
289 dview->search.handle->is_all_charsets = mcdiffview_search_options.all_codepages;
290 dview->search.handle->is_case_sensitive = mcdiffview_search_options.case_sens;
291 dview->search.handle->whole_words = mcdiffview_search_options.whole_words;
293 mcdiffview_do_search (dview);
296 /* --------------------------------------------------------------------------------------------- */
298 void
299 dview_continue_search_cmd (WDiff * dview)
301 if (dview->dsrc != DATA_SRC_MEM)
302 error_dialog (_("Search"), _("Search is disabled"));
303 else if (dview->search.handle == NULL)
304 dview_search_cmd (dview);
305 else
306 mcdiffview_do_search (dview);
309 /* --------------------------------------------------------------------------------------------- */