Manual pages: mcmcdiffmceditmcview

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

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