root/src/diffviewer/search.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. mcdiffview_dialog_search
  2. mcdiffview_do_search_backward
  3. mcdiffview_do_search_forward
  4. mcdiffview_do_search
  5. dview_search_cmd
  6. dview_continue_search_cmd

   1 /*
   2    Search functions for diffviewer.
   3 
   4    Copyright (C) 2010-2019
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Slava Zanko <slavazanko@gmail.com>, 2010.
   9    Andrew Borodin <aborodin@vmail.ru>, 2012
  10 
  11    This file is part of the Midnight Commander.
  12 
  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.
  17 
  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.
  22 
  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/>.
  25  */
  26 
  27 #include <config.h>
  28 
  29 #include <stdio.h>
  30 
  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
  38 
  39 #include "src/history.h"
  40 
  41 #include "internal.h"
  42 
  43 /*** global variables ****************************************************************************/
  44 
  45 /*** file scope macro definitions ****************************************************************/
  46 
  47 /*** file scope type declarations ****************************************************************/
  48 
  49 typedef struct mcdiffview_search_options_struct
  50 {
  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;
  57 
  58 /*** file scope variables ************************************************************************/
  59 
  60 static mcdiffview_search_options_t mcdiffview_search_options = {
  61     .type = MC_SEARCH_T_NORMAL,
  62     .case_sens = FALSE,
  63     .backwards = FALSE,
  64     .whole_words = FALSE,
  65     .all_codepages = FALSE,
  66 };
  67 
  68 /* --------------------------------------------------------------------------------------------- */
  69 /*** file scope functions ************************************************************************/
  70 /* --------------------------------------------------------------------------------------------- */
  71 
  72 static gboolean
  73 mcdiffview_dialog_search (WDiff * dview)
     /* [previous][next][first][last][top][bottom][index][help]  */
  74 {
  75     char *exp = NULL;
  76     int qd_result;
  77     size_t num_of_types = 0;
  78     gchar **list_of_types;
  79 
  80     list_of_types = mc_search_get_types_strings_array (&num_of_types);
  81 
  82     {
  83         quick_widget_t quick_widgets[] = {
  84             /* *INDENT-OFF* */
  85             QUICK_LABELED_INPUT (N_("Enter search string:"), input_label_above, INPUT_LAST_TEXT,
  86             MC_HISTORY_SHARED_SEARCH, &exp, NULL, FALSE, FALSE, INPUT_COMPLETE_NONE),
  87             QUICK_SEPARATOR (TRUE),
  88             QUICK_START_COLUMNS,
  89                 QUICK_RADIO (num_of_types, (const char **) list_of_types,
  90                              (int *) &mcdiffview_search_options.type, NULL),
  91             QUICK_NEXT_COLUMN,
  92                 QUICK_CHECKBOX (N_("Cas&e sensitive"), &mcdiffview_search_options.case_sens, NULL),
  93                 QUICK_CHECKBOX (N_("&Backwards"), &mcdiffview_search_options.backwards, NULL),
  94                 QUICK_CHECKBOX (N_("&Whole words"), &mcdiffview_search_options.whole_words, NULL),
  95 #ifdef HAVE_CHARSET
  96                 QUICK_CHECKBOX (N_("&All charsets"), &mcdiffview_search_options.all_codepages, NULL),
  97 #endif
  98             QUICK_STOP_COLUMNS,
  99             QUICK_BUTTONS_OK_CANCEL,
 100             QUICK_END
 101             /* *INDENT-ON* */
 102         };
 103 
 104         quick_dialog_t qdlg = {
 105             -1, -1, 58,
 106             N_("Search"), "[Input Line Keys]",
 107             quick_widgets, NULL, NULL
 108         };
 109 
 110         qd_result = quick_dialog (&qdlg);
 111     }
 112 
 113     g_strfreev (list_of_types);
 114 
 115     if ((qd_result == B_CANCEL) || (exp == NULL) || (exp[0] == '\0'))
 116     {
 117         g_free (exp);
 118         return FALSE;
 119     }
 120 
 121 #ifdef HAVE_CHARSET
 122     {
 123         GString *tmp;
 124 
 125         tmp = str_convert_to_input (exp);
 126         g_free (exp);
 127         exp = g_string_free (tmp, FALSE);
 128     }
 129 #endif
 130 
 131     g_free (dview->search.last_string);
 132     dview->search.last_string = exp;
 133 
 134     return TRUE;
 135 }
 136 
 137 /* --------------------------------------------------------------------------------------------- */
 138 
 139 static gboolean
 140 mcdiffview_do_search_backward (WDiff * dview)
     /* [previous][next][first][last][top][bottom][index][help]  */
 141 {
 142     ssize_t ind;
 143 
 144     if (dview->search.last_accessed_num_line < 0)
 145     {
 146         dview->search.last_accessed_num_line = -1;
 147         return FALSE;
 148     }
 149 
 150     if ((size_t) dview->search.last_accessed_num_line >= dview->a[dview->ord]->len)
 151         dview->search.last_accessed_num_line = (ssize_t) dview->a[dview->ord]->len;
 152 
 153     for (ind = --dview->search.last_accessed_num_line; ind >= 0; ind--)
 154     {
 155         DIFFLN *p;
 156 
 157         p = (DIFFLN *) & g_array_index (dview->a[dview->ord], DIFFLN, (size_t) ind);
 158         if (p->u.len == 0)
 159             continue;
 160 
 161         if (mc_search_run (dview->search.handle, p->p, 0, p->u.len, NULL))
 162         {
 163             dview->skip_rows = dview->search.last_found_line =
 164                 dview->search.last_accessed_num_line = ind;
 165             return TRUE;
 166         }
 167     }
 168     return FALSE;
 169 }
 170 
 171 /* --------------------------------------------------------------------------------------------- */
 172 
 173 
 174 static gboolean
 175 mcdiffview_do_search_forward (WDiff * dview)
     /* [previous][next][first][last][top][bottom][index][help]  */
 176 {
 177     size_t ind;
 178 
 179     if (dview->search.last_accessed_num_line < 0)
 180         dview->search.last_accessed_num_line = -1;
 181     else if ((size_t) dview->search.last_accessed_num_line >= dview->a[dview->ord]->len)
 182     {
 183         dview->search.last_accessed_num_line = (ssize_t) dview->a[dview->ord]->len;
 184         return FALSE;
 185     }
 186 
 187     for (ind = (size_t)++ dview->search.last_accessed_num_line; ind < dview->a[dview->ord]->len;
 188          ind++)
 189     {
 190         DIFFLN *p;
 191 
 192         p = (DIFFLN *) & g_array_index (dview->a[dview->ord], DIFFLN, ind);
 193         if (p->u.len == 0)
 194             continue;
 195 
 196         if (mc_search_run (dview->search.handle, p->p, 0, p->u.len, NULL))
 197         {
 198             dview->skip_rows = dview->search.last_found_line =
 199                 dview->search.last_accessed_num_line = (ssize_t) ind;
 200             return TRUE;
 201         }
 202     }
 203     return FALSE;
 204 }
 205 
 206 /* --------------------------------------------------------------------------------------------- */
 207 
 208 static void
 209 mcdiffview_do_search (WDiff * dview)
     /* [previous][next][first][last][top][bottom][index][help]  */
 210 {
 211     gboolean present_result = FALSE;
 212 
 213     tty_enable_interrupt_key ();
 214 
 215     if (mcdiffview_search_options.backwards)
 216     {
 217         present_result = mcdiffview_do_search_backward (dview);
 218     }
 219     else
 220     {
 221         present_result = mcdiffview_do_search_forward (dview);
 222     }
 223 
 224     tty_disable_interrupt_key ();
 225 
 226     if (!present_result)
 227     {
 228         dview->search.last_found_line = -1;
 229         query_dialog (_("Search"), _(STR_E_NOTFOUND), D_NORMAL, 1, _("&Dismiss"));
 230     }
 231 }
 232 
 233 /* --------------------------------------------------------------------------------------------- */
 234 /*** public functions ****************************************************************************/
 235 /* --------------------------------------------------------------------------------------------- */
 236 
 237 void
 238 dview_search_cmd (WDiff * dview)
     /* [previous][next][first][last][top][bottom][index][help]  */
 239 {
 240     if (dview->dsrc != DATA_SRC_MEM)
 241     {
 242         error_dialog (_("Search"), _("Search is disabled"));
 243         return;
 244     }
 245 
 246     if (!mcdiffview_dialog_search (dview))
 247         return;
 248 
 249     mc_search_free (dview->search.handle);
 250 #ifdef HAVE_CHARSET
 251     dview->search.handle = mc_search_new (dview->search.last_string, cp_source);
 252 #else
 253     dview->search.handle = mc_search_new (dview->search.last_string, NULL);
 254 #endif
 255 
 256     if (dview->search.handle == NULL)
 257         return;
 258 
 259     dview->search.handle->search_type = mcdiffview_search_options.type;
 260 #ifdef HAVE_CHARSET
 261     dview->search.handle->is_all_charsets = mcdiffview_search_options.all_codepages;
 262 #endif
 263     dview->search.handle->is_case_sensitive = mcdiffview_search_options.case_sens;
 264     dview->search.handle->whole_words = mcdiffview_search_options.whole_words;
 265 
 266     mcdiffview_do_search (dview);
 267 }
 268 
 269 /* --------------------------------------------------------------------------------------------- */
 270 
 271 void
 272 dview_continue_search_cmd (WDiff * dview)
     /* [previous][next][first][last][top][bottom][index][help]  */
 273 {
 274     if (dview->dsrc != DATA_SRC_MEM)
 275         error_dialog (_("Search"), _("Search is disabled"));
 276     else if (dview->search.handle == NULL)
 277         dview_search_cmd (dview);
 278     else
 279         mcdiffview_do_search (dview);
 280 }
 281 
 282 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */