1998-02-27 07:54:42 +03:00
|
|
|
/* Find file command for the Midnight Commander
|
2007-09-25 19:33:35 +04:00
|
|
|
Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
|
|
|
2006, 2007 Free Software Foundation, Inc.
|
1998-02-27 07:54:42 +03:00
|
|
|
Written 1995 by Miguel de Icaza
|
|
|
|
|
|
|
|
Complete rewrote.
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
2005-05-27 07:35:10 +04:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-02-05 21:28:18 +03:00
|
|
|
/** \file find.c
|
|
|
|
* \brief Source: Find file command
|
|
|
|
*/
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
#include <config.h>
|
2005-02-08 12:04:03 +03:00
|
|
|
|
|
|
|
#include <ctype.h>
|
1998-02-27 07:54:42 +03:00
|
|
|
#include <stdio.h>
|
2005-02-08 12:04:03 +03:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2009-02-06 02:30:45 +03:00
|
|
|
#include <fcntl.h>
|
1998-02-27 07:54:42 +03:00
|
|
|
#include <sys/stat.h>
|
2001-09-03 09:07:40 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
#include "global.h"
|
2009-05-09 19:17:57 +04:00
|
|
|
|
2009-05-08 14:01:05 +04:00
|
|
|
#include "../src/tty/tty.h"
|
2009-09-04 18:22:49 +04:00
|
|
|
#include "../src/skin/skin.h"
|
2009-05-09 19:17:57 +04:00
|
|
|
#include "../src/tty/key.h"
|
|
|
|
|
|
|
|
#include "../src/search/search.h"
|
|
|
|
|
1998-11-18 05:31:23 +03:00
|
|
|
#include "setup.h"
|
1998-12-03 00:27:27 +03:00
|
|
|
#include "find.h"
|
2008-12-29 02:06:38 +03:00
|
|
|
#include "strutil.h"
|
2003-10-25 03:20:30 +04:00
|
|
|
#include "dialog.h"
|
1998-02-27 07:54:42 +03:00
|
|
|
#include "widget.h"
|
|
|
|
#include "dir.h"
|
|
|
|
#include "panel.h" /* current_panel */
|
|
|
|
#include "main.h" /* do_cd, try_to_select */
|
|
|
|
#include "wtools.h"
|
|
|
|
#include "cmd.h" /* view_file_at_line */
|
2001-10-01 10:51:15 +04:00
|
|
|
#include "boxes.h"
|
2009-08-04 22:53:41 +04:00
|
|
|
#include "history.h" /* MC_HISTORY_SHARED_SEARCH */
|
2009-08-16 19:27:33 +04:00
|
|
|
#include "layout.h" /* mc_refresh() */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* Size of the find parameters window */
|
2009-06-22 21:46:34 +04:00
|
|
|
#if HAVE_CHARSET
|
|
|
|
static int FIND_Y = 16;
|
|
|
|
#else
|
|
|
|
static int FIND_Y = 15;
|
|
|
|
#endif
|
|
|
|
static int FIND_X = 68;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* Size of the find window */
|
2003-09-11 01:33:12 +04:00
|
|
|
#define FIND2_Y (LINES - 4)
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2001-07-15 01:44:39 +04:00
|
|
|
static int FIND2_X = 64;
|
2003-09-11 01:33:12 +04:00
|
|
|
#define FIND2_X_USE (FIND2_X - 20)
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* A couple of extra messages we need */
|
|
|
|
enum {
|
|
|
|
B_STOP = B_USER + 1,
|
|
|
|
B_AGAIN,
|
|
|
|
B_PANELIZE,
|
|
|
|
B_TREE,
|
|
|
|
B_VIEW
|
|
|
|
};
|
|
|
|
|
2004-09-19 15:32:30 +04:00
|
|
|
typedef enum {
|
2009-06-22 21:46:34 +04:00
|
|
|
FIND_CONT = 0,
|
2004-09-19 15:32:30 +04:00
|
|
|
FIND_SUSPEND,
|
|
|
|
FIND_ABORT
|
|
|
|
} FindProgressStatus;
|
|
|
|
|
2002-12-11 10:14:00 +03:00
|
|
|
/* List of directories to be ignored, separated by ':' */
|
2009-06-22 21:46:34 +04:00
|
|
|
char *find_ignore_dirs = NULL;
|
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
/* static variables to remember find parameters */
|
|
|
|
static WInput *in_start; /* Start path */
|
|
|
|
static WInput *in_name; /* Filename */
|
|
|
|
static WInput *in_with; /* Text inside filename */
|
|
|
|
static WCheck *file_case_sens_cbox; /* "case sensitive" checkbox */
|
|
|
|
static WCheck *file_pattern_cbox; /* File name is glob or regexp */
|
|
|
|
static WCheck *recursively_cbox;
|
|
|
|
static WCheck *skip_hidden_cbox;
|
|
|
|
static WCheck *content_case_sens_cbox; /* "case sensitive" checkbox */
|
|
|
|
static WCheck *content_regexp_cbox; /* "find regular expression" checkbox */
|
2009-08-05 14:37:43 +04:00
|
|
|
static WCheck *content_first_hit_cbox; /* "First hit" checkbox" */
|
2009-08-22 15:06:01 +04:00
|
|
|
static WCheck *content_whole_words_cbox; /* "whole words" checkbox */
|
2009-08-05 10:10:00 +04:00
|
|
|
#ifdef HAVE_CHARSET
|
|
|
|
static WCheck *file_all_charsets_cbox;
|
|
|
|
static WCheck *content_all_charsets_cbox;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static gboolean running = FALSE; /* nice flag */
|
2009-06-22 21:46:34 +04:00
|
|
|
static char *find_pattern = NULL; /* Pattern to search */
|
|
|
|
static char *content_pattern = NULL; /* pattern to search inside files; if
|
|
|
|
content_regexp_flag is true, it contains the
|
|
|
|
regex pattern, else the search string. */
|
|
|
|
static unsigned long matches; /* Number of matches */
|
2009-08-05 10:10:00 +04:00
|
|
|
static gboolean is_start = FALSE; /* Status of the start/stop toggle button */
|
2009-06-22 21:46:34 +04:00
|
|
|
static char *old_dir = NULL;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2004-09-19 15:32:30 +04:00
|
|
|
/* Where did we stop */
|
|
|
|
static int resuming;
|
|
|
|
static int last_line;
|
|
|
|
static int last_pos;
|
|
|
|
|
1999-02-11 08:52:55 +03:00
|
|
|
static Dlg_head *find_dlg; /* The dialog */
|
|
|
|
static WButton *stop_button; /* pointer to the stop button */
|
|
|
|
static WLabel *status_label; /* Finished, Searching etc. */
|
2009-06-22 21:46:34 +04:00
|
|
|
static WLabel *found_num_label; /* Number of found items */
|
1999-02-11 08:52:55 +03:00
|
|
|
static WListbox *find_list; /* Listbox with the file list */
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* This keeps track of the directory stack */
|
2009-06-22 21:46:34 +04:00
|
|
|
#if GLIB_CHECK_VERSION (2, 14, 0)
|
|
|
|
static GQueue dir_queue = G_QUEUE_INIT;
|
|
|
|
#else
|
1998-02-27 07:54:42 +03:00
|
|
|
typedef struct dir_stack {
|
|
|
|
char *name;
|
|
|
|
struct dir_stack *prev;
|
2009-08-05 10:10:00 +04:00
|
|
|
} dir_stack;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2001-07-15 01:44:39 +04:00
|
|
|
static dir_stack *dir_stack_base = 0;
|
2009-06-22 21:46:34 +04:00
|
|
|
#endif /* GLIB_CHECK_VERSION */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
1998-04-08 22:50:24 +04:00
|
|
|
static struct {
|
2004-08-17 03:48:46 +04:00
|
|
|
const char* text;
|
1998-04-08 22:50:24 +04:00
|
|
|
int len; /* length including space and brackets */
|
|
|
|
int x;
|
|
|
|
} fbuts [] = {
|
|
|
|
{ N_("&Suspend"), 11, 29 },
|
1998-09-29 00:41:28 +04:00
|
|
|
{ N_("Con&tinue"), 12, 29 },
|
1998-04-08 22:50:24 +04:00
|
|
|
{ N_("&Chdir"), 11, 3 },
|
|
|
|
{ N_("&Again"), 9, 17 },
|
|
|
|
{ N_("&Quit"), 8, 43 },
|
|
|
|
{ N_("Pane&lize"), 12, 3 },
|
|
|
|
{ N_("&View - F3"), 13, 20 },
|
|
|
|
{ N_("&Edit - F4"), 13, 38 }
|
|
|
|
};
|
|
|
|
|
2009-10-04 18:27:43 +04:00
|
|
|
static char *in_contents = NULL;
|
2009-09-20 21:20:17 +04:00
|
|
|
static char *in_start_dir = INPUT_LAST_TEXT;
|
2009-08-05 10:10:00 +04:00
|
|
|
|
|
|
|
static mc_search_t *search_file_handle = NULL;
|
2009-02-21 12:53:38 +03:00
|
|
|
static gboolean skip_hidden_flag = FALSE;
|
2009-06-22 21:46:34 +04:00
|
|
|
static gboolean file_pattern_flag = TRUE;
|
2009-05-04 16:47:49 +04:00
|
|
|
static gboolean file_all_charsets_flag = FALSE;
|
2009-08-05 10:10:00 +04:00
|
|
|
static gboolean file_case_sens_flag = TRUE;
|
|
|
|
static gboolean find_recurs_flag = TRUE;
|
2009-05-04 16:47:49 +04:00
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
static mc_search_t *search_content_handle = NULL;
|
2009-05-04 18:06:47 +04:00
|
|
|
static gboolean content_regexp_flag = FALSE;
|
2009-05-04 16:47:49 +04:00
|
|
|
static gboolean content_all_charsets_flag = FALSE;
|
2009-08-05 10:10:00 +04:00
|
|
|
static gboolean content_case_sens_flag = TRUE;
|
2009-08-05 14:37:43 +04:00
|
|
|
static gboolean content_first_hit_flag = FALSE;
|
2009-08-22 15:06:01 +04:00
|
|
|
static gboolean content_whole_words = FALSE;
|
2002-12-24 14:28:26 +03:00
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
static inline char *
|
|
|
|
add_to_list (const char *text, void *data)
|
|
|
|
{
|
|
|
|
return listbox_add_item (find_list, LISTBOX_APPEND_AT_END, 0, text, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
stop_idle (void *data)
|
|
|
|
{
|
|
|
|
set_idle_proc (data, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
status_update (const char *text)
|
|
|
|
{
|
|
|
|
label_set_text (status_label, text);
|
|
|
|
}
|
|
|
|
|
2009-08-31 05:54:10 +04:00
|
|
|
static void
|
2009-06-22 21:46:34 +04:00
|
|
|
found_num_update (void)
|
|
|
|
{
|
|
|
|
char buffer [BUF_TINY];
|
|
|
|
g_snprintf (buffer, sizeof (buffer), _("Found: %ld"), matches);
|
|
|
|
label_set_text (found_num_label, buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
get_list_info (char **file, char **dir)
|
|
|
|
{
|
|
|
|
listbox_get_current (find_list, file, dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check regular expression */
|
|
|
|
gboolean
|
|
|
|
find_check_regexp (const char *r)
|
|
|
|
{
|
|
|
|
mc_search_t *search;
|
|
|
|
gboolean regexp_ok = FALSE;
|
|
|
|
|
|
|
|
search = mc_search_new (r, -1);
|
|
|
|
|
|
|
|
if (search != NULL) {
|
|
|
|
search->search_type = MC_SEARCH_T_REGEX;
|
|
|
|
regexp_ok = mc_search_prepare (search);
|
|
|
|
mc_search_free (search);
|
|
|
|
}
|
|
|
|
|
|
|
|
return regexp_ok;
|
|
|
|
}
|
|
|
|
|
2002-12-24 14:28:26 +03:00
|
|
|
/*
|
|
|
|
* Callback for the parameter dialog.
|
|
|
|
* Validate regex, prevent closing the dialog if it's invalid.
|
|
|
|
*/
|
2003-09-08 01:24:01 +04:00
|
|
|
static cb_ret_t
|
|
|
|
find_parm_callback (struct Dlg_head *h, dlg_msg_t msg, int parm)
|
2002-12-24 14:28:26 +03:00
|
|
|
{
|
2003-09-08 01:24:01 +04:00
|
|
|
switch (msg) {
|
2002-12-24 14:28:26 +03:00
|
|
|
case DLG_VALIDATE:
|
2009-06-22 21:46:34 +04:00
|
|
|
if (h->ret_value != B_ENTER)
|
2002-12-24 14:28:26 +03:00
|
|
|
return MSG_HANDLED;
|
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
/* check filename regexp */
|
|
|
|
if (!(file_pattern_cbox->state & C_BOOL)
|
|
|
|
&& (in_name->buffer[0] != '\0')
|
|
|
|
&& !find_check_regexp (in_name->buffer)) {
|
|
|
|
message (D_ERROR, MSG_ERROR, _(" Malformed regular expression "));
|
|
|
|
dlg_select_widget (in_name);
|
|
|
|
h->running = 1; /* Don't stop the dialog */
|
|
|
|
return MSG_HANDLED;
|
|
|
|
}
|
2002-12-24 14:28:26 +03:00
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
/* check content regexp */
|
2009-08-05 10:10:00 +04:00
|
|
|
if ((content_regexp_cbox->state & C_BOOL)
|
2009-06-22 21:46:34 +04:00
|
|
|
&& (in_with->buffer[0] != '\0')
|
|
|
|
&& !find_check_regexp (in_with->buffer)) {
|
|
|
|
message (D_ERROR, MSG_ERROR, _(" Malformed regular expression "));
|
|
|
|
dlg_select_widget (in_with);
|
|
|
|
h->running = 1; /* Don't stop the dialog */
|
|
|
|
return MSG_HANDLED;
|
2002-12-24 14:28:26 +03:00
|
|
|
}
|
2009-06-22 21:46:34 +04:00
|
|
|
|
2002-12-24 14:28:26 +03:00
|
|
|
return MSG_HANDLED;
|
2003-09-08 01:24:01 +04:00
|
|
|
|
|
|
|
default:
|
|
|
|
return default_dlg_callback (h, msg, parm);
|
2002-12-24 14:28:26 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/*
|
|
|
|
* find_parameters: gets information from the user
|
|
|
|
*
|
|
|
|
* If the return value is true, then the following holds:
|
|
|
|
*
|
|
|
|
* START_DIR and PATTERN are pointers to char * and upon return they
|
|
|
|
* contain the information provided by the user.
|
|
|
|
*
|
|
|
|
* CONTENT holds a strdup of the contents specified by the user if he
|
|
|
|
* asked for them or 0 if not (note, this is different from the
|
|
|
|
* behavior for the other two parameters.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
find_parameters (char **start_dir, char **pattern, char **content)
|
|
|
|
{
|
|
|
|
int return_value;
|
2009-06-22 21:46:34 +04:00
|
|
|
char *temp_dir = NULL;
|
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
/* file name */
|
|
|
|
const char *file_case_label = N_("Cas&e sensitive");
|
|
|
|
const char *file_pattern_label = N_("&Using shell patterns");
|
|
|
|
const char *file_recurs_label = N_("&Find recursively");
|
|
|
|
const char *file_skip_hidden_label = N_("S&kip hidden");
|
|
|
|
const char *file_all_charsets_label = N_("&All charsets");
|
2009-06-22 21:46:34 +04:00
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
/* file content */
|
|
|
|
const char *content_case_label = N_("Case sens&itive");
|
|
|
|
const char *content_regexp_label = N_("Re&gular expression");
|
2009-08-05 14:37:43 +04:00
|
|
|
const char *content_first_hit_label = N_("Fir&st hit");
|
2009-08-24 23:31:31 +04:00
|
|
|
const char *content_whole_words_label = N_("&Whole words");
|
2009-08-05 10:10:00 +04:00
|
|
|
const char *content_all_charsets_label = N_("All cha&rsets");
|
2001-04-06 09:21:29 +04:00
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
const char *buts[] = { N_("&OK"), N_("&Cancel"), N_("&Tree") };
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
int b0, b1, b2;
|
1998-04-08 22:50:24 +04:00
|
|
|
|
|
|
|
#ifdef ENABLE_NLS
|
2009-08-05 10:10:00 +04:00
|
|
|
{
|
2009-06-22 21:46:34 +04:00
|
|
|
int i = sizeof (buts) / sizeof (buts[0]);
|
|
|
|
while (i-- != 0)
|
|
|
|
buts[i] = _(buts[i]);
|
|
|
|
|
|
|
|
file_case_label = _(file_case_label);
|
2009-08-07 13:09:52 +04:00
|
|
|
file_pattern_label = _(file_pattern_label);
|
2009-06-22 21:46:34 +04:00
|
|
|
file_recurs_label = _(file_recurs_label);
|
|
|
|
file_skip_hidden_label = _(file_skip_hidden_label);
|
|
|
|
file_all_charsets_label = _(file_all_charsets_label);
|
2009-08-07 13:09:52 +04:00
|
|
|
content_case_label = _(content_case_label);
|
2009-06-22 21:46:34 +04:00
|
|
|
content_regexp_label = _(content_regexp_label);
|
2009-08-07 13:09:52 +04:00
|
|
|
content_first_hit_label = _(content_first_hit_label);
|
2009-08-22 15:06:01 +04:00
|
|
|
content_whole_words_label = _(content_whole_words_label);
|
2009-08-07 13:09:52 +04:00
|
|
|
content_all_charsets_label = _(content_all_charsets_label);
|
2002-09-04 00:04:54 +04:00
|
|
|
}
|
|
|
|
#endif /* ENABLE_NLS */
|
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
b0 = str_term_width1 (buts[0]) + 6; /* default button */
|
|
|
|
b1 = str_term_width1 (buts[1]) + 4;
|
|
|
|
b2 = str_term_width1 (buts[2]) + 4;
|
|
|
|
|
2002-09-04 00:04:54 +04:00
|
|
|
find_par_start:
|
2009-10-04 18:27:43 +04:00
|
|
|
if (in_contents == NULL)
|
|
|
|
in_contents = INPUT_LAST_TEXT;
|
|
|
|
|
2009-09-20 21:20:17 +04:00
|
|
|
if (in_start_dir == NULL)
|
2009-02-06 01:40:32 +03:00
|
|
|
in_start_dir = g_strdup (".");
|
2002-09-04 00:04:54 +04:00
|
|
|
|
2002-12-24 14:28:26 +03:00
|
|
|
find_dlg =
|
|
|
|
create_dlg (0, 0, FIND_Y, FIND_X, dialog_colors,
|
|
|
|
find_parm_callback, "[Find File]", _("Find File"),
|
2003-09-13 01:22:01 +04:00
|
|
|
DLG_CENTER | DLG_REVERSE);
|
2002-12-24 14:28:26 +03:00
|
|
|
|
|
|
|
add_widget (find_dlg,
|
2009-06-22 21:46:34 +04:00
|
|
|
button_new (FIND_Y - 3, FIND_X * 3/4 - b1/2, B_CANCEL, NORMAL_BUTTON, buts[1], 0));
|
2002-12-24 14:28:26 +03:00
|
|
|
add_widget (find_dlg,
|
2009-06-22 21:46:34 +04:00
|
|
|
button_new (FIND_Y - 3, FIND_X/4 - b0/2, B_ENTER, DEFPUSH_BUTTON, buts[0], 0));
|
2004-12-02 23:08:06 +03:00
|
|
|
|
2009-05-25 15:50:38 +04:00
|
|
|
#ifdef HAVE_CHARSET
|
2009-08-22 15:06:01 +04:00
|
|
|
content_all_charsets_cbox = check_new (11, FIND_X / 2 + 1,
|
2009-06-22 21:46:34 +04:00
|
|
|
content_all_charsets_flag, content_all_charsets_label);
|
|
|
|
add_widget (find_dlg, content_all_charsets_cbox);
|
2009-05-25 15:50:38 +04:00
|
|
|
#endif
|
2009-05-04 16:47:49 +04:00
|
|
|
|
2009-08-22 15:06:01 +04:00
|
|
|
content_whole_words_cbox = check_new (10, FIND_X / 2 + 1, content_whole_words, content_whole_words_label);
|
|
|
|
add_widget (find_dlg, content_whole_words_cbox);
|
|
|
|
|
2009-08-05 14:37:43 +04:00
|
|
|
content_first_hit_cbox = check_new (9, FIND_X / 2 + 1, content_first_hit_flag, content_first_hit_label);
|
|
|
|
add_widget (find_dlg, content_first_hit_cbox);
|
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
content_regexp_cbox = check_new (8, FIND_X / 2 + 1, content_regexp_flag, content_regexp_label);
|
|
|
|
add_widget (find_dlg, content_regexp_cbox);
|
2009-02-21 12:53:38 +03:00
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
content_case_sens_cbox = check_new (7, FIND_X / 2 + 1, content_case_sens_flag, content_case_label);
|
|
|
|
add_widget (find_dlg, content_case_sens_cbox);
|
2009-02-21 12:53:38 +03:00
|
|
|
|
2009-05-25 15:50:38 +04:00
|
|
|
#ifdef HAVE_CHARSET
|
2009-06-22 21:46:34 +04:00
|
|
|
file_all_charsets_cbox = check_new (11, 3,
|
|
|
|
file_all_charsets_flag, file_all_charsets_label);
|
2009-05-04 16:47:49 +04:00
|
|
|
add_widget (find_dlg, file_all_charsets_cbox);
|
2009-05-25 15:50:38 +04:00
|
|
|
#endif
|
2009-06-22 21:46:34 +04:00
|
|
|
|
|
|
|
skip_hidden_cbox = check_new (10, 3, skip_hidden_flag, file_skip_hidden_label);
|
2009-02-21 17:48:00 +03:00
|
|
|
add_widget (find_dlg, skip_hidden_cbox);
|
2009-06-22 21:46:34 +04:00
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
recursively_cbox = check_new (9, 3, find_recurs_flag, file_recurs_label);
|
2005-05-10 23:30:22 +04:00
|
|
|
add_widget (find_dlg, recursively_cbox);
|
2009-06-22 21:46:34 +04:00
|
|
|
|
|
|
|
file_pattern_cbox = check_new (8, 3, file_pattern_flag, file_pattern_label);
|
|
|
|
add_widget (find_dlg, file_pattern_cbox);
|
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
file_case_sens_cbox = check_new (7, 3, file_case_sens_flag, file_case_label);
|
|
|
|
add_widget (find_dlg, file_case_sens_cbox);
|
2009-06-22 21:46:34 +04:00
|
|
|
|
2009-10-04 18:27:43 +04:00
|
|
|
in_with = input_new (6, FIND_X / 2 + 1, INPUT_COLOR, FIND_X / 2 - 4, in_contents,
|
2009-08-04 22:53:41 +04:00
|
|
|
MC_HISTORY_SHARED_SEARCH, INPUT_COMPLETE_DEFAULT);
|
2009-06-22 21:46:34 +04:00
|
|
|
add_widget (find_dlg, in_with);
|
|
|
|
add_widget (find_dlg, label_new (5, FIND_X / 2 + 1, _("Content:")));
|
|
|
|
|
2009-09-20 21:20:17 +04:00
|
|
|
in_name = input_new (6, 3, INPUT_COLOR, FIND_X / 2 - 4, INPUT_LAST_TEXT, "name",
|
2009-08-04 22:53:41 +04:00
|
|
|
INPUT_COMPLETE_DEFAULT);
|
2001-04-07 01:48:11 +04:00
|
|
|
add_widget (find_dlg, in_name);
|
2009-06-22 21:46:34 +04:00
|
|
|
add_widget (find_dlg, label_new (5, 3, _("File name:")));
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
add_widget (find_dlg,
|
|
|
|
button_new (3, FIND_X - b2 - 2, B_TREE, NORMAL_BUTTON, buts[2], 0));
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-08-04 22:53:41 +04:00
|
|
|
in_start = input_new (3, 3, INPUT_COLOR, FIND_X - b2 - 6, in_start_dir, "start",
|
|
|
|
INPUT_COMPLETE_DEFAULT);
|
2009-06-22 21:46:34 +04:00
|
|
|
add_widget (find_dlg, in_start);
|
|
|
|
add_widget (find_dlg, label_new (2, 3, _("Start at:")));
|
2003-09-10 04:29:09 +04:00
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
dlg_select_widget (in_name);
|
1998-12-02 08:18:20 +03:00
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
switch (run_dlg (find_dlg)) {
|
1998-12-02 08:18:20 +03:00
|
|
|
case B_CANCEL:
|
1998-02-27 07:54:42 +03:00
|
|
|
return_value = 0;
|
1998-12-02 08:18:20 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case B_TREE:
|
2009-06-10 23:21:44 +04:00
|
|
|
#ifdef HAVE_CHARSET
|
|
|
|
file_all_charsets_flag = file_all_charsets_cbox->state & C_BOOL;
|
|
|
|
content_all_charsets_flag = content_all_charsets_cbox->state & C_BOOL;
|
|
|
|
#endif
|
2009-08-05 10:10:00 +04:00
|
|
|
content_case_sens_flag = content_case_sens_cbox->state & C_BOOL;
|
|
|
|
content_regexp_flag = content_regexp_cbox->state & C_BOOL;
|
2009-08-05 14:37:43 +04:00
|
|
|
content_first_hit_flag = content_first_hit_cbox->state & C_BOOL;
|
2009-08-22 15:06:01 +04:00
|
|
|
content_whole_words = content_whole_words_cbox->state & C_BOOL;
|
2009-06-22 21:46:34 +04:00
|
|
|
file_pattern_flag = file_pattern_cbox->state & C_BOOL;
|
2009-08-05 10:10:00 +04:00
|
|
|
file_case_sens_flag = file_case_sens_cbox->state & C_BOOL;
|
|
|
|
find_recurs_flag = recursively_cbox->state & C_BOOL;
|
2009-02-21 12:53:38 +03:00
|
|
|
skip_hidden_flag = skip_hidden_cbox->state & C_BOOL;
|
1998-02-27 07:54:42 +03:00
|
|
|
destroy_dlg (find_dlg);
|
2009-09-20 21:20:17 +04:00
|
|
|
if (in_start_dir != INPUT_LAST_TEXT)
|
|
|
|
g_free (in_start_dir);
|
|
|
|
temp_dir = g_strdup (in_start->buffer);
|
2009-06-22 21:46:34 +04:00
|
|
|
if ((temp_dir[0] == '.') && (temp_dir[1] == '\0')) {
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (temp_dir);
|
2009-02-06 01:40:32 +03:00
|
|
|
temp_dir = g_strdup (current_panel->cwd);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2001-10-01 10:51:15 +04:00
|
|
|
in_start_dir = tree_box (temp_dir);
|
2009-09-20 21:20:17 +04:00
|
|
|
if (in_start_dir != NULL)
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (temp_dir);
|
1998-02-27 07:54:42 +03:00
|
|
|
else
|
|
|
|
in_start_dir = temp_dir;
|
|
|
|
/* Warning: Dreadful goto */
|
|
|
|
goto find_par_start;
|
1998-12-02 08:18:20 +03:00
|
|
|
break;
|
2002-09-04 00:04:54 +04:00
|
|
|
|
1998-12-02 08:18:20 +03:00
|
|
|
default:
|
2009-06-10 23:21:44 +04:00
|
|
|
#ifdef HAVE_CHARSET
|
2009-05-04 16:47:49 +04:00
|
|
|
file_all_charsets_flag = file_all_charsets_cbox->state & C_BOOL;
|
|
|
|
content_all_charsets_flag = content_all_charsets_cbox->state & C_BOOL;
|
2009-06-10 23:21:44 +04:00
|
|
|
#endif
|
2009-08-05 10:10:00 +04:00
|
|
|
content_case_sens_flag = content_case_sens_cbox->state & C_BOOL;
|
|
|
|
content_regexp_flag = content_regexp_cbox->state & C_BOOL;
|
2009-08-05 14:37:43 +04:00
|
|
|
content_first_hit_flag = content_first_hit_cbox->state & C_BOOL;
|
2009-08-22 15:06:01 +04:00
|
|
|
content_whole_words = content_whole_words_cbox->state & C_BOOL;
|
2009-08-05 10:10:00 +04:00
|
|
|
find_recurs_flag = recursively_cbox->state & C_BOOL;
|
2009-06-22 21:46:34 +04:00
|
|
|
file_pattern_flag = file_pattern_cbox->state & C_BOOL;
|
2009-08-05 10:10:00 +04:00
|
|
|
file_case_sens_flag = file_case_sens_cbox->state & C_BOOL;
|
2009-02-21 12:53:38 +03:00
|
|
|
skip_hidden_flag = skip_hidden_cbox->state & C_BOOL;
|
2009-10-04 18:27:43 +04:00
|
|
|
|
|
|
|
/* keep empty Content field */
|
|
|
|
/* if not empty, fill from history */
|
|
|
|
*content = NULL;
|
|
|
|
in_contents = "";
|
|
|
|
if (in_with->buffer[0] != '\0') {
|
|
|
|
*content = g_strdup (in_with->buffer);
|
|
|
|
in_contents = INPUT_LAST_TEXT;
|
|
|
|
}
|
|
|
|
|
2009-10-03 19:44:59 +04:00
|
|
|
*start_dir = g_strdup ((in_start->buffer[0] != '\0') ? in_start->buffer : ".");
|
2009-02-06 01:40:32 +03:00
|
|
|
*pattern = g_strdup (in_name->buffer);
|
2009-09-20 21:20:17 +04:00
|
|
|
if (in_start_dir != INPUT_LAST_TEXT)
|
|
|
|
g_free (in_start_dir);
|
2009-02-06 01:40:32 +03:00
|
|
|
in_start_dir = g_strdup (*start_dir);
|
2009-10-03 19:44:59 +04:00
|
|
|
return_value = 1;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
destroy_dlg (find_dlg);
|
2002-09-04 00:04:54 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
return return_value;
|
|
|
|
}
|
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
#if GLIB_CHECK_VERSION (2, 14, 0)
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
push_directory (const char *dir)
|
|
|
|
{
|
|
|
|
g_queue_push_head (&dir_queue, (void *) dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline char *
|
|
|
|
pop_directory (void)
|
|
|
|
{
|
|
|
|
return (char *) g_queue_pop_tail (&dir_queue);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remove all the items in the stack */
|
|
|
|
static void
|
|
|
|
clear_stack (void)
|
|
|
|
{
|
|
|
|
g_queue_foreach (&dir_queue, (GFunc) g_free, NULL);
|
|
|
|
g_queue_clear (&dir_queue);
|
|
|
|
}
|
|
|
|
|
|
|
|
#else /* GLIB_CHAECK_VERSION */
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
static void
|
2003-10-30 19:43:22 +03:00
|
|
|
push_directory (const char *dir)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
dir_stack *new;
|
|
|
|
|
Glibing..... (2)
Wed Jan 27 03:17:44 1999 Timur Bakeyev <mc@bat.ru>
* Converted memory managment to Glib. Now we use g_new()/g_malloc()/
g_strdup()/g_free() routings. Also, copy_strings() replaced by
g_strconcat(), strcasecmp() -> g_strcasecmp(),and sprintf() by
g_snprintf().
* Some sequences of malloc()/sprintf() changed to g_strdup_printf().
* mad.[ch]: Modified, to work with new GLib's memory managment. Fixed
a missing #undef for tempnam, which caused dead loop. Add several new
functions to emulate GLib memory managment.
*main.c, mad.[ch]: Add a new switch "-M", which allows to redirect MAD
messages to the file.
* util.[ch], utilunix.c: Modified, deleted our variants of strcasecmp()
and strdup() - we have g_ equivalences. Remove get_full_name() - it is
similar to concat_dir_and_file(). Some other tricks with g_* functions.
* global.h: Modified, extended. Now it is main memory mangment include -
i.e. all inclusions of <stdlib.h>, <malloc.h>, <glib.h>, "fs.h", "mem.h",
"util.h" and "mad.h" done there. This elimanates problem with proper or-
der of #include's.
* All around the source - changed order of #include's, most of them gone
to global.h (see above), minor changes, like "0" -> NULL in string func-
tions.
1999-01-27 04:08:30 +03:00
|
|
|
new = g_new (dir_stack, 1);
|
2009-06-22 21:46:34 +04:00
|
|
|
new->name = str_unconst (dir);
|
1998-02-27 07:54:42 +03:00
|
|
|
new->prev = dir_stack_base;
|
|
|
|
dir_stack_base = new;
|
|
|
|
}
|
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
static char *
|
1998-02-27 07:54:42 +03:00
|
|
|
pop_directory (void)
|
|
|
|
{
|
2009-06-22 21:46:34 +04:00
|
|
|
char *name = NULL;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
if (dir_stack_base != NULL) {
|
|
|
|
dir_stack *next;
|
1998-02-27 07:54:42 +03:00
|
|
|
name = dir_stack_base->name;
|
|
|
|
next = dir_stack_base->prev;
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (dir_stack_base);
|
1998-02-27 07:54:42 +03:00
|
|
|
dir_stack_base = next;
|
2009-06-22 21:46:34 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return name;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
/* Remove all the items in the stack */
|
|
|
|
static void
|
|
|
|
clear_stack (void)
|
|
|
|
{
|
|
|
|
char *dir = NULL;
|
|
|
|
while ((dir = pop_directory ()) != NULL)
|
|
|
|
g_free (dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* GLIB_CHAECK_VERSION */
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
static void
|
2003-10-30 19:43:22 +03:00
|
|
|
insert_file (const char *dir, const char *file)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2009-06-22 21:46:34 +04:00
|
|
|
char *tmp_name = NULL;
|
|
|
|
static char *dirname = NULL;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2003-10-30 19:43:22 +03:00
|
|
|
while (dir [0] == PATH_SEP && dir [1] == PATH_SEP)
|
1998-02-27 07:54:42 +03:00
|
|
|
dir++;
|
|
|
|
|
|
|
|
if (old_dir){
|
|
|
|
if (strcmp (old_dir, dir)){
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (old_dir);
|
2009-02-06 01:40:32 +03:00
|
|
|
old_dir = g_strdup (dir);
|
1999-02-11 08:52:55 +03:00
|
|
|
dirname = add_to_list (dir, NULL);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
} else {
|
2009-02-06 01:40:32 +03:00
|
|
|
old_dir = g_strdup (dir);
|
1999-02-11 08:52:55 +03:00
|
|
|
dirname = add_to_list (dir, NULL);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2009-06-22 21:46:34 +04:00
|
|
|
|
|
|
|
tmp_name = g_strdup_printf (" %s", file);
|
1999-02-11 08:52:55 +03:00
|
|
|
add_to_list (tmp_name, dirname);
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (tmp_name);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-06-22 21:46:34 +04:00
|
|
|
find_add_match (const char *dir, const char *file)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
insert_file (dir, file);
|
1999-02-11 08:52:55 +03:00
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
/* Don't scroll */
|
|
|
|
if (matches == 0)
|
|
|
|
listbox_select_by_number (find_list, 0);
|
|
|
|
send_message (&find_list->widget, WIDGET_DRAW, 0);
|
|
|
|
|
|
|
|
matches++;
|
|
|
|
found_num_update ();
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2001-09-23 08:06:35 +04:00
|
|
|
/*
|
|
|
|
* get_line_at:
|
|
|
|
*
|
|
|
|
* Returns malloced null-terminated line from file file_fd.
|
|
|
|
* Input is buffered in buf_size long buffer.
|
|
|
|
* Current pos in buf is stored in pos.
|
|
|
|
* n_read - number of read chars.
|
|
|
|
* has_newline - is there newline ?
|
|
|
|
*/
|
|
|
|
static char *
|
2009-08-07 10:41:17 +04:00
|
|
|
get_line_at (int file_fd, char *buf, int buf_size, int *pos, int *n_read,
|
|
|
|
gboolean *has_newline)
|
2001-09-23 08:06:35 +04:00
|
|
|
{
|
2009-06-22 21:46:34 +04:00
|
|
|
char *buffer = NULL;
|
2003-04-16 19:26:29 +04:00
|
|
|
int buffer_size = 0;
|
2001-09-23 08:06:35 +04:00
|
|
|
char ch = 0;
|
2003-04-16 19:26:29 +04:00
|
|
|
int i = 0;
|
2001-09-23 08:06:35 +04:00
|
|
|
|
2003-04-16 19:26:29 +04:00
|
|
|
for (;;) {
|
|
|
|
if (*pos >= *n_read) {
|
2001-09-23 08:06:35 +04:00
|
|
|
*pos = 0;
|
2009-06-22 21:46:34 +04:00
|
|
|
*n_read = mc_read (file_fd, buf, buf_size);
|
|
|
|
if (*n_read <= 0)
|
2001-09-23 08:06:35 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2003-04-16 19:26:29 +04:00
|
|
|
ch = buf[(*pos)++];
|
2009-08-07 10:41:17 +04:00
|
|
|
if (ch == '\0') {
|
2001-09-23 08:06:35 +04:00
|
|
|
/* skip possible leading zero(s) */
|
|
|
|
if (i == 0)
|
|
|
|
continue;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2003-04-16 19:26:29 +04:00
|
|
|
if (i >= buffer_size - 1) {
|
2001-09-23 08:06:35 +04:00
|
|
|
buffer = g_realloc (buffer, buffer_size += 80);
|
|
|
|
}
|
2003-04-16 19:26:29 +04:00
|
|
|
/* Strip newline */
|
|
|
|
if (ch == '\n')
|
|
|
|
break;
|
2001-09-23 08:06:35 +04:00
|
|
|
|
2003-04-16 19:26:29 +04:00
|
|
|
buffer[i++] = ch;
|
|
|
|
}
|
2001-09-23 08:06:35 +04:00
|
|
|
|
2009-08-07 10:41:17 +04:00
|
|
|
*has_newline = (ch != '\0');
|
2001-09-23 08:06:35 +04:00
|
|
|
|
2009-08-07 10:41:17 +04:00
|
|
|
if (buffer != NULL)
|
|
|
|
buffer[i] = '\0';
|
2001-09-23 08:06:35 +04:00
|
|
|
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
2004-09-19 15:32:30 +04:00
|
|
|
static FindProgressStatus
|
|
|
|
check_find_events(Dlg_head *h)
|
|
|
|
{
|
|
|
|
Gpm_Event event;
|
|
|
|
int c;
|
2009-08-05 10:10:00 +04:00
|
|
|
|
2009-08-12 15:53:23 +04:00
|
|
|
event.x = -1;
|
2009-06-19 21:33:41 +04:00
|
|
|
c = tty_get_event (&event, h->mouse_status == MOU_REPEAT, FALSE);
|
2004-09-19 15:32:30 +04:00
|
|
|
if (c != EV_NONE) {
|
|
|
|
dlg_process_event (h, c, &event);
|
|
|
|
if (h->ret_value == B_ENTER
|
|
|
|
|| h->ret_value == B_CANCEL
|
|
|
|
|| h->ret_value == B_AGAIN
|
|
|
|
|| h->ret_value == B_PANELIZE) {
|
|
|
|
/* dialog terminated */
|
|
|
|
return FIND_ABORT;
|
|
|
|
}
|
|
|
|
if (!(h->flags & DLG_WANT_IDLE)) {
|
|
|
|
/* searching suspended */
|
|
|
|
return FIND_SUSPEND;
|
|
|
|
}
|
|
|
|
}
|
2009-08-05 10:10:00 +04:00
|
|
|
|
2004-09-19 15:32:30 +04:00
|
|
|
return FIND_CONT;
|
|
|
|
}
|
2009-08-05 10:10:00 +04:00
|
|
|
|
|
|
|
/*
|
1998-02-27 07:54:42 +03:00
|
|
|
* search_content:
|
|
|
|
*
|
2009-08-07 10:41:17 +04:00
|
|
|
* Search the content_pattern string in the DIRECTORY/FILE.
|
|
|
|
* It will add the found entries to the find listbox.
|
2009-08-05 10:10:00 +04:00
|
|
|
*
|
2009-08-07 10:41:17 +04:00
|
|
|
* returns FALSE if do_search should look for another file
|
|
|
|
* TRUE if do_search should exit and proceed to the event handler
|
1998-02-27 07:54:42 +03:00
|
|
|
*/
|
2009-08-07 10:41:17 +04:00
|
|
|
static gboolean
|
2003-10-30 19:43:22 +03:00
|
|
|
search_content (Dlg_head *h, const char *directory, const char *filename)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
struct stat s;
|
2009-05-04 16:47:49 +04:00
|
|
|
char buffer [BUF_4K];
|
2009-06-22 21:46:34 +04:00
|
|
|
char *fname = NULL;
|
2001-09-23 08:06:35 +04:00
|
|
|
int file_fd;
|
2009-08-07 10:41:17 +04:00
|
|
|
gboolean ret_val = FALSE;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-02-06 13:17:03 +03:00
|
|
|
fname = concat_dir_and_file (directory, filename);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2001-04-24 18:39:38 +04:00
|
|
|
if (mc_stat (fname, &s) != 0 || !S_ISREG (s.st_mode)){
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (fname);
|
2004-09-19 15:32:30 +04:00
|
|
|
return 0;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2001-04-24 18:39:38 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
file_fd = mc_open (fname, O_RDONLY);
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (fname);
|
2001-04-27 14:07:45 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
if (file_fd == -1)
|
2004-09-19 15:32:30 +04:00
|
|
|
return 0;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2008-12-29 02:06:38 +03:00
|
|
|
g_snprintf (buffer, sizeof (buffer), _("Grepping in %s"), str_trunc (filename, FIND2_X_USE));
|
1998-02-27 07:54:42 +03:00
|
|
|
|
1999-02-11 08:52:55 +03:00
|
|
|
status_update (buffer);
|
2009-08-16 19:27:33 +04:00
|
|
|
mc_refresh ();
|
2001-04-27 14:07:45 +04:00
|
|
|
|
2009-05-19 17:42:37 +04:00
|
|
|
tty_enable_interrupt_key ();
|
|
|
|
tty_got_interrupt ();
|
2001-04-24 18:39:38 +04:00
|
|
|
|
2002-02-28 16:50:03 +03:00
|
|
|
{
|
2001-09-23 08:06:35 +04:00
|
|
|
int line = 1;
|
|
|
|
int pos = 0;
|
|
|
|
int n_read = 0;
|
2009-08-07 10:41:17 +04:00
|
|
|
gboolean has_newline;
|
2009-06-22 21:46:34 +04:00
|
|
|
char *p = NULL;
|
2009-05-04 16:47:49 +04:00
|
|
|
gboolean found = FALSE;
|
2009-06-22 21:46:34 +04:00
|
|
|
gsize found_len;
|
2009-08-07 10:41:17 +04:00
|
|
|
char result [BUF_MEDIUM];
|
2001-09-23 08:06:35 +04:00
|
|
|
|
2004-09-19 15:32:30 +04:00
|
|
|
if (resuming) {
|
|
|
|
/* We've been previously suspended, start from the previous position */
|
|
|
|
resuming = 0;
|
|
|
|
line = last_line;
|
|
|
|
pos = last_pos;
|
|
|
|
}
|
2009-08-07 10:41:17 +04:00
|
|
|
while (!ret_val
|
|
|
|
&& (p = get_line_at (file_fd, buffer, sizeof (buffer),
|
|
|
|
&pos, &n_read, &has_newline)) != NULL) {
|
|
|
|
if (!found /* Search in binary line once */
|
|
|
|
&& mc_search_run (search_content_handle,
|
|
|
|
(const void *) p, 0, strlen (p), &found_len)) {
|
|
|
|
g_snprintf (result, sizeof (result), "%d:%s", line, filename);
|
|
|
|
find_add_match (directory, result);
|
|
|
|
found = TRUE;
|
2001-09-23 08:06:35 +04:00
|
|
|
}
|
2009-08-05 10:10:00 +04:00
|
|
|
g_free (p);
|
|
|
|
|
2009-08-07 11:01:36 +04:00
|
|
|
if (found && content_first_hit_flag)
|
|
|
|
break;
|
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
if (has_newline) {
|
2009-08-07 11:01:36 +04:00
|
|
|
found = FALSE;
|
2001-09-23 08:06:35 +04:00
|
|
|
line++;
|
|
|
|
}
|
2009-06-22 21:46:34 +04:00
|
|
|
|
|
|
|
if ((line & 0xff) == 0) {
|
2004-09-19 15:32:30 +04:00
|
|
|
FindProgressStatus res;
|
|
|
|
res = check_find_events(h);
|
|
|
|
switch (res) {
|
|
|
|
case FIND_ABORT:
|
|
|
|
stop_idle (h);
|
2009-08-07 10:41:17 +04:00
|
|
|
ret_val = TRUE;
|
2004-09-19 15:32:30 +04:00
|
|
|
break;
|
|
|
|
case FIND_SUSPEND:
|
|
|
|
resuming = 1;
|
|
|
|
last_line = line;
|
|
|
|
last_pos = pos;
|
2009-08-07 10:41:17 +04:00
|
|
|
ret_val = TRUE;
|
2004-09-19 15:32:30 +04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-06-22 21:46:34 +04:00
|
|
|
|
2001-04-27 14:07:45 +04:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2009-05-19 17:42:37 +04:00
|
|
|
tty_disable_interrupt_key ();
|
1998-02-27 07:54:42 +03:00
|
|
|
mc_close (file_fd);
|
2004-09-19 15:32:30 +04:00
|
|
|
return ret_val;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
1999-02-11 08:52:55 +03:00
|
|
|
static int
|
1998-02-27 07:54:42 +03:00
|
|
|
do_search (struct Dlg_head *h)
|
|
|
|
{
|
2009-08-05 10:10:00 +04:00
|
|
|
static struct dirent *dp = NULL;
|
|
|
|
static DIR *dirp = NULL;
|
2009-06-22 21:46:34 +04:00
|
|
|
static char *directory = NULL;
|
1998-02-27 07:54:42 +03:00
|
|
|
struct stat tmp_stat;
|
2009-06-22 21:46:34 +04:00
|
|
|
static int pos = 0;
|
1998-02-27 07:54:42 +03:00
|
|
|
static int subdirs_left = 0;
|
2009-05-04 16:47:49 +04:00
|
|
|
gsize bytes_found;
|
2009-08-05 10:10:00 +04:00
|
|
|
unsigned long count; /* Number of files displayed */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
if (!h) { /* someone forces me to close dirp */
|
|
|
|
if (dirp) {
|
|
|
|
mc_closedir (dirp);
|
2009-08-05 10:10:00 +04:00
|
|
|
dirp = NULL;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (directory);
|
2004-09-04 02:00:27 +04:00
|
|
|
directory = NULL;
|
2009-08-05 10:10:00 +04:00
|
|
|
dp = NULL;
|
1999-02-11 08:52:55 +03:00
|
|
|
return 1;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2009-05-04 16:47:49 +04:00
|
|
|
|
|
|
|
search_content_handle = mc_search_new(content_pattern, -1);
|
2009-08-22 15:06:01 +04:00
|
|
|
if (search_content_handle) {
|
2009-05-05 17:16:09 +04:00
|
|
|
search_content_handle->search_type = (content_regexp_flag) ? MC_SEARCH_T_REGEX : MC_SEARCH_T_NORMAL;
|
2009-08-05 10:10:00 +04:00
|
|
|
search_content_handle->is_case_sentitive = content_case_sens_flag;
|
2009-08-22 15:06:01 +04:00
|
|
|
search_content_handle->whole_words = content_whole_words;
|
2009-05-05 17:16:09 +04:00
|
|
|
search_content_handle->is_all_charsets = content_all_charsets_flag;
|
|
|
|
}
|
2009-05-04 16:47:49 +04:00
|
|
|
search_file_handle = mc_search_new(find_pattern, -1);
|
2009-06-22 21:46:34 +04:00
|
|
|
search_file_handle->search_type = (file_pattern_flag) ? MC_SEARCH_T_GLOB : MC_SEARCH_T_REGEX;
|
2009-08-05 10:10:00 +04:00
|
|
|
search_file_handle->is_case_sentitive = file_case_sens_flag;
|
2009-05-04 16:47:49 +04:00
|
|
|
search_file_handle->is_all_charsets = file_all_charsets_flag;
|
2009-06-22 21:46:34 +04:00
|
|
|
search_file_handle->is_entire_line = file_pattern_flag;
|
2009-05-04 16:47:49 +04:00
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
count = 0;
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
do_search_begin:
|
|
|
|
while (!dp){
|
|
|
|
if (dirp){
|
|
|
|
mc_closedir (dirp);
|
|
|
|
dirp = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (!dirp){
|
2009-06-22 21:46:34 +04:00
|
|
|
char *tmp = NULL;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-05-11 16:13:58 +04:00
|
|
|
tty_setcolor (REVERSE_COLOR);
|
1998-02-27 07:54:42 +03:00
|
|
|
while (1) {
|
2009-06-22 21:46:34 +04:00
|
|
|
char *temp_dir = NULL;
|
|
|
|
gboolean found;
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
tmp = pop_directory ();
|
2009-06-22 21:46:34 +04:00
|
|
|
if (tmp == NULL) {
|
2009-08-05 10:10:00 +04:00
|
|
|
running = FALSE;
|
1999-02-11 08:52:55 +03:00
|
|
|
status_update (_("Finished"));
|
|
|
|
stop_idle (h);
|
2009-06-22 21:46:34 +04:00
|
|
|
mc_search_free (search_file_handle);
|
2009-05-04 16:47:49 +04:00
|
|
|
search_file_handle = NULL;
|
2009-06-22 21:46:34 +04:00
|
|
|
mc_search_free (search_content_handle);
|
2009-05-04 16:47:49 +04:00
|
|
|
search_content_handle = NULL;
|
1999-02-11 08:52:55 +03:00
|
|
|
return 0;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2009-06-22 21:46:34 +04:00
|
|
|
|
|
|
|
if ((find_ignore_dirs == NULL) || (find_ignore_dirs[0] == '\0'))
|
1998-02-27 07:54:42 +03:00
|
|
|
break;
|
2009-06-22 21:46:34 +04:00
|
|
|
|
|
|
|
temp_dir = g_strdup_printf (":%s:", tmp);
|
|
|
|
found = strstr (find_ignore_dirs, temp_dir) != 0;
|
|
|
|
g_free (temp_dir);
|
|
|
|
|
|
|
|
if (!found)
|
|
|
|
break;
|
|
|
|
|
|
|
|
g_free (tmp);
|
|
|
|
}
|
2003-09-29 19:58:08 +04:00
|
|
|
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (directory);
|
2003-10-30 19:43:22 +03:00
|
|
|
directory = tmp;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
if (verbose){
|
2003-09-29 19:58:08 +04:00
|
|
|
char buffer [BUF_SMALL];
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
g_snprintf (buffer, sizeof (buffer), _("Searching %s"),
|
2008-12-29 02:06:38 +03:00
|
|
|
str_trunc (directory, FIND2_X_USE));
|
2003-09-29 19:58:08 +04:00
|
|
|
status_update (buffer);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
1999-04-25 23:57:53 +04:00
|
|
|
/* mc_stat should not be called after mc_opendir
|
|
|
|
because vfs_s_opendir modifies the st_nlink
|
|
|
|
*/
|
2003-09-29 19:58:08 +04:00
|
|
|
if (!mc_stat (directory, &tmp_stat))
|
|
|
|
subdirs_left = tmp_stat.st_nlink - 2;
|
|
|
|
else
|
|
|
|
subdirs_left = 0;
|
2009-06-22 21:46:34 +04:00
|
|
|
|
1999-04-25 23:57:53 +04:00
|
|
|
dirp = mc_opendir (directory);
|
2003-09-29 19:58:08 +04:00
|
|
|
} /* while (!dirp) */
|
2009-06-22 21:46:34 +04:00
|
|
|
|
2008-12-29 02:06:38 +03:00
|
|
|
/* skip invalid filenames */
|
2009-06-22 21:46:34 +04:00
|
|
|
while ((dp = mc_readdir (dirp)) != NULL
|
|
|
|
&& !str_is_valid_string (dp->d_name))
|
|
|
|
;
|
2003-10-30 19:43:22 +03:00
|
|
|
} /* while (!dp) */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
if (strcmp (dp->d_name, ".") == 0 ||
|
|
|
|
strcmp (dp->d_name, "..") == 0){
|
|
|
|
dp = mc_readdir (dirp);
|
2008-12-29 02:06:38 +03:00
|
|
|
/* skip invalid filenames */
|
|
|
|
while (dp != NULL && !str_is_valid_string (dp->d_name))
|
|
|
|
dp = mc_readdir (dirp);
|
2009-05-04 16:47:49 +04:00
|
|
|
|
|
|
|
mc_search_free(search_file_handle);
|
|
|
|
search_file_handle = NULL;
|
|
|
|
mc_search_free(search_content_handle);
|
|
|
|
search_content_handle = NULL;
|
1999-02-11 08:52:55 +03:00
|
|
|
return 1;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2003-10-30 19:43:22 +03:00
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
if (!(skip_hidden_flag && (dp->d_name[0] == '.'))) {
|
|
|
|
gboolean search_ok;
|
|
|
|
|
2009-08-05 10:10:00 +04:00
|
|
|
if ((subdirs_left != 0) && find_recurs_flag
|
2009-06-22 21:46:34 +04:00
|
|
|
&& (directory != NULL)) { /* Can directory be NULL ? */
|
2009-02-21 12:53:38 +03:00
|
|
|
char *tmp_name = concat_dir_and_file (directory, dp->d_name);
|
|
|
|
if (!mc_lstat (tmp_name, &tmp_stat)
|
|
|
|
&& S_ISDIR (tmp_stat.st_mode)) {
|
|
|
|
push_directory (tmp_name);
|
|
|
|
subdirs_left--;
|
|
|
|
} else
|
2009-06-22 21:46:34 +04:00
|
|
|
g_free (tmp_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
search_ok = mc_search_run (search_file_handle, dp->d_name,
|
|
|
|
0, strlen (dp->d_name), &bytes_found);
|
|
|
|
|
|
|
|
if (search_ok) {
|
|
|
|
if (content_pattern == NULL)
|
|
|
|
find_add_match (directory, dp->d_name);
|
|
|
|
else if (search_content (h, directory, dp->d_name)) {
|
|
|
|
mc_search_free(search_file_handle);
|
|
|
|
search_file_handle = NULL;
|
|
|
|
mc_search_free(search_content_handle);
|
|
|
|
search_content_handle = NULL;
|
|
|
|
return 1;
|
|
|
|
}
|
2009-02-21 12:53:38 +03:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2008-12-29 02:06:38 +03:00
|
|
|
/* skip invalid filenames */
|
2009-06-22 21:46:34 +04:00
|
|
|
while ((dp = mc_readdir (dirp)) != NULL
|
|
|
|
&& !str_is_valid_string (dp->d_name))
|
|
|
|
;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* Displays the nice dot */
|
|
|
|
count++;
|
|
|
|
if (!(count & 31)){
|
2001-04-27 14:07:45 +04:00
|
|
|
/* For nice updating */
|
2009-06-22 21:46:34 +04:00
|
|
|
const char rotating_dash[] = "|/-\\";
|
2001-04-27 14:07:45 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
if (verbose){
|
1998-04-15 10:05:34 +04:00
|
|
|
pos = (pos + 1) % 4;
|
2009-05-11 16:13:58 +04:00
|
|
|
tty_setcolor (DLG_NORMALC (h));
|
2009-06-22 21:46:34 +04:00
|
|
|
dlg_move (h, FIND2_Y - 7, FIND2_X - 4);
|
2009-05-29 19:30:45 +04:00
|
|
|
tty_print_char (rotating_dash [pos]);
|
2009-08-16 19:27:33 +04:00
|
|
|
mc_refresh ();
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
} else
|
|
|
|
goto do_search_begin;
|
2009-06-22 21:46:34 +04:00
|
|
|
|
|
|
|
mc_search_free (search_file_handle);
|
2009-05-04 16:47:49 +04:00
|
|
|
search_file_handle = NULL;
|
2009-06-22 21:46:34 +04:00
|
|
|
mc_search_free (search_content_handle);
|
2009-05-04 16:47:49 +04:00
|
|
|
search_content_handle = NULL;
|
1999-02-11 08:52:55 +03:00
|
|
|
return 1;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
1999-02-11 08:52:55 +03:00
|
|
|
static void
|
|
|
|
init_find_vars (void)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (old_dir);
|
2009-06-22 21:46:34 +04:00
|
|
|
old_dir = NULL;
|
1999-02-11 08:52:55 +03:00
|
|
|
matches = 0;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
1999-02-11 08:52:55 +03:00
|
|
|
/* Remove all the items in the stack */
|
2009-06-22 21:46:34 +04:00
|
|
|
clear_stack ();
|
1999-02-11 08:52:55 +03:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2006-02-04 14:03:35 +03:00
|
|
|
static char *
|
|
|
|
make_fullname (const char *dirname, const char *filename)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (strcmp(dirname, ".") == 0 || strcmp(dirname, "."PATH_SEP_STR) == 0)
|
2009-02-06 01:40:32 +03:00
|
|
|
return g_strdup (filename);
|
2006-02-04 14:03:35 +03:00
|
|
|
if (strncmp(dirname, "."PATH_SEP_STR, 2) == 0)
|
2009-02-06 13:17:03 +03:00
|
|
|
return concat_dir_and_file (dirname + 2, filename);
|
|
|
|
return concat_dir_and_file (dirname, filename);
|
2006-02-04 14:03:35 +03:00
|
|
|
}
|
|
|
|
|
1999-02-11 08:52:55 +03:00
|
|
|
static void
|
|
|
|
find_do_view_edit (int unparsed_view, int edit, char *dir, char *file)
|
|
|
|
{
|
2009-06-22 21:46:34 +04:00
|
|
|
char *fullname = NULL;
|
|
|
|
const char *filename = NULL;
|
1999-02-11 08:52:55 +03:00
|
|
|
int line;
|
2009-06-22 21:46:34 +04:00
|
|
|
|
|
|
|
if (content_pattern != NULL) {
|
1999-02-11 08:52:55 +03:00
|
|
|
filename = strchr (file + 4, ':') + 1;
|
|
|
|
line = atoi (file + 4);
|
1998-02-27 07:54:42 +03:00
|
|
|
} else {
|
2009-06-22 21:46:34 +04:00
|
|
|
filename = file + 4;
|
|
|
|
line = 0;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2006-02-04 14:03:35 +03:00
|
|
|
fullname = make_fullname (dir, filename);
|
1998-02-27 07:54:42 +03:00
|
|
|
if (edit)
|
|
|
|
do_edit_at_line (fullname, line);
|
|
|
|
else
|
|
|
|
view_file_at_line (fullname, unparsed_view, use_internal_view, line);
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (fullname);
|
1999-02-11 08:52:55 +03:00
|
|
|
}
|
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
static cb_ret_t
|
1999-02-11 08:52:55 +03:00
|
|
|
view_edit_currently_selected_file (int unparsed_view, int edit)
|
|
|
|
{
|
|
|
|
WLEntry *entry = find_list->current;
|
2009-06-22 21:46:34 +04:00
|
|
|
char *dir = NULL;
|
1999-02-11 08:52:55 +03:00
|
|
|
|
|
|
|
if (!entry)
|
|
|
|
return MSG_NOT_HANDLED;
|
|
|
|
|
|
|
|
dir = entry->data;
|
|
|
|
|
|
|
|
if (!entry->text || !dir)
|
|
|
|
return MSG_NOT_HANDLED;
|
|
|
|
|
|
|
|
find_do_view_edit (unparsed_view, edit, dir, entry->text);
|
1998-02-27 07:54:42 +03:00
|
|
|
return MSG_HANDLED;
|
|
|
|
}
|
|
|
|
|
2003-09-08 01:24:01 +04:00
|
|
|
static cb_ret_t
|
|
|
|
find_callback (struct Dlg_head *h, dlg_msg_t msg, int parm)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2003-09-08 01:24:01 +04:00
|
|
|
switch (msg) {
|
1998-02-27 07:54:42 +03:00
|
|
|
case DLG_KEY:
|
2003-09-08 01:24:01 +04:00
|
|
|
if (parm == KEY_F (3) || parm == KEY_F (13)) {
|
|
|
|
int unparsed_view = (parm == KEY_F (13));
|
1998-02-27 07:54:42 +03:00
|
|
|
return view_edit_currently_selected_file (unparsed_view, 0);
|
|
|
|
}
|
2003-09-08 01:24:01 +04:00
|
|
|
if (parm == KEY_F (4)) {
|
1998-02-27 07:54:42 +03:00
|
|
|
return view_edit_currently_selected_file (0, 1);
|
2003-09-08 01:24:01 +04:00
|
|
|
}
|
|
|
|
return MSG_NOT_HANDLED;
|
|
|
|
|
|
|
|
case DLG_IDLE:
|
|
|
|
do_search (h);
|
|
|
|
return MSG_HANDLED;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return default_dlg_callback (h, msg, parm);
|
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Handles the Stop/Start button in the find window */
|
|
|
|
static int
|
2003-09-01 06:07:02 +04:00
|
|
|
start_stop (int button)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-02-09 01:33:52 +03:00
|
|
|
(void) button;
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
running = is_start;
|
|
|
|
set_idle_proc (find_dlg, running);
|
|
|
|
is_start = !is_start;
|
|
|
|
|
1999-02-11 08:52:55 +03:00
|
|
|
status_update (is_start ? _("Stopped") : _("Searching"));
|
2009-08-05 10:10:00 +04:00
|
|
|
button_set_text (stop_button, fbuts [is_start ? 1 : 0].text);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Handle view command, when invoked as a button */
|
|
|
|
static int
|
2003-09-01 06:07:02 +04:00
|
|
|
find_do_view_file (int button)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-02-09 01:33:52 +03:00
|
|
|
(void) button;
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
view_edit_currently_selected_file (0, 0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Handle edit command, when invoked as a button */
|
|
|
|
static int
|
2003-09-01 06:07:02 +04:00
|
|
|
find_do_edit_file (int button)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2005-02-09 01:33:52 +03:00
|
|
|
(void) button;
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
view_edit_currently_selected_file (0, 1);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-02-11 08:52:55 +03:00
|
|
|
setup_gui (void)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
1998-04-08 22:50:24 +04:00
|
|
|
#ifdef ENABLE_NLS
|
2009-06-22 21:46:34 +04:00
|
|
|
static gboolean i18n_flag = FALSE;
|
|
|
|
|
2002-09-04 00:04:54 +04:00
|
|
|
if (!i18n_flag) {
|
2009-06-22 21:46:34 +04:00
|
|
|
int i = sizeof (fbuts) / sizeof (fbuts[0]);
|
|
|
|
while (i-- != 0) {
|
|
|
|
fbuts[i].text = _(fbuts[i].text);
|
|
|
|
fbuts[i].len = str_term_width1 (fbuts[i].text) + 3;
|
|
|
|
}
|
|
|
|
|
2002-09-04 00:04:54 +04:00
|
|
|
fbuts[2].len += 2; /* DEFPUSH_BUTTON */
|
2009-06-22 21:46:34 +04:00
|
|
|
i18n_flag = TRUE;
|
2002-09-04 00:04:54 +04:00
|
|
|
}
|
|
|
|
#endif /* ENABLE_NLS */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Dynamically place buttons centered within current window size
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
int l0 = max (fbuts[0].len, fbuts[1].len);
|
|
|
|
int l1 = fbuts[2].len + fbuts[3].len + l0 + fbuts[4].len;
|
|
|
|
int l2 = fbuts[5].len + fbuts[6].len + fbuts[7].len;
|
|
|
|
int r1, r2;
|
|
|
|
|
|
|
|
/* Check, if both button rows fit within FIND2_X */
|
2009-06-22 21:46:34 +04:00
|
|
|
FIND2_X = max (l1 + 9, COLS - 16);
|
|
|
|
FIND2_X = max (l2 + 8, FIND2_X);
|
2002-09-04 00:04:54 +04:00
|
|
|
|
|
|
|
/* compute amount of space between buttons for each row */
|
|
|
|
r1 = (FIND2_X - 4 - l1) % 5;
|
|
|
|
l1 = (FIND2_X - 4 - l1) / 5;
|
|
|
|
r2 = (FIND2_X - 4 - l2) % 4;
|
|
|
|
l2 = (FIND2_X - 4 - l2) / 4;
|
|
|
|
|
|
|
|
/* ...and finally, place buttons */
|
|
|
|
fbuts[2].x = 2 + r1 / 2 + l1;
|
|
|
|
fbuts[3].x = fbuts[2].x + fbuts[2].len + l1;
|
|
|
|
fbuts[0].x = fbuts[3].x + fbuts[3].len + l1;
|
|
|
|
fbuts[4].x = fbuts[0].x + l0 + l1;
|
|
|
|
fbuts[5].x = 2 + r2 / 2 + l2;
|
|
|
|
fbuts[6].x = fbuts[5].x + fbuts[5].len + l2;
|
|
|
|
fbuts[7].x = fbuts[6].x + fbuts[6].len + l2;
|
|
|
|
}
|
|
|
|
|
2003-09-01 03:29:49 +04:00
|
|
|
find_dlg =
|
|
|
|
create_dlg (0, 0, FIND2_Y, FIND2_X, dialog_colors, find_callback,
|
2003-09-13 01:22:01 +04:00
|
|
|
"[Find File]", _("Find File"), DLG_CENTER | DLG_REVERSE);
|
2002-09-04 00:04:54 +04:00
|
|
|
|
|
|
|
add_widget (find_dlg,
|
|
|
|
button_new (FIND2_Y - 3, fbuts[7].x, B_VIEW, NORMAL_BUTTON,
|
2003-09-01 06:07:02 +04:00
|
|
|
fbuts[7].text, find_do_edit_file));
|
2002-09-04 00:04:54 +04:00
|
|
|
add_widget (find_dlg,
|
|
|
|
button_new (FIND2_Y - 3, fbuts[6].x, B_VIEW, NORMAL_BUTTON,
|
2003-09-01 06:07:02 +04:00
|
|
|
fbuts[6].text, find_do_view_file));
|
2002-09-04 00:04:54 +04:00
|
|
|
add_widget (find_dlg,
|
|
|
|
button_new (FIND2_Y - 3, fbuts[5].x, B_PANELIZE,
|
2003-09-01 06:07:02 +04:00
|
|
|
NORMAL_BUTTON, fbuts[5].text, 0));
|
2002-09-04 00:04:54 +04:00
|
|
|
|
|
|
|
add_widget (find_dlg,
|
|
|
|
button_new (FIND2_Y - 4, fbuts[4].x, B_CANCEL,
|
2003-09-01 06:07:02 +04:00
|
|
|
NORMAL_BUTTON, fbuts[4].text, 0));
|
2002-09-04 00:04:54 +04:00
|
|
|
stop_button =
|
|
|
|
button_new (FIND2_Y - 4, fbuts[0].x, B_STOP, NORMAL_BUTTON,
|
2003-09-01 06:07:02 +04:00
|
|
|
fbuts[0].text, start_stop);
|
2002-09-04 00:04:54 +04:00
|
|
|
add_widget (find_dlg, stop_button);
|
|
|
|
add_widget (find_dlg,
|
|
|
|
button_new (FIND2_Y - 4, fbuts[3].x, B_AGAIN,
|
2003-09-01 06:07:02 +04:00
|
|
|
NORMAL_BUTTON, fbuts[3].text, 0));
|
2002-09-04 00:04:54 +04:00
|
|
|
add_widget (find_dlg,
|
|
|
|
button_new (FIND2_Y - 4, fbuts[2].x, B_ENTER,
|
2003-09-01 06:07:02 +04:00
|
|
|
DEFPUSH_BUTTON, fbuts[2].text, 0));
|
2002-09-04 00:04:54 +04:00
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
status_label = label_new (FIND2_Y - 7, 4, _("Searching"));
|
2001-04-07 01:48:11 +04:00
|
|
|
add_widget (find_dlg, status_label);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
found_num_label = label_new (FIND2_Y - 6, 4, "");
|
|
|
|
add_widget (find_dlg, found_num_label);
|
|
|
|
|
2002-09-04 00:04:54 +04:00
|
|
|
find_list =
|
2009-06-22 21:46:34 +04:00
|
|
|
listbox_new (2, 2, FIND2_Y - 10, FIND2_X - 4, NULL);
|
2001-04-07 01:48:11 +04:00
|
|
|
add_widget (find_dlg, find_list);
|
1999-02-11 08:52:55 +03:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
|
1999-02-11 08:52:55 +03:00
|
|
|
static int
|
|
|
|
run_process (void)
|
|
|
|
{
|
2004-09-19 15:32:30 +04:00
|
|
|
resuming = 0;
|
1999-02-11 08:52:55 +03:00
|
|
|
set_idle_proc (find_dlg, 1);
|
2009-06-22 21:46:34 +04:00
|
|
|
return run_dlg (find_dlg);
|
1999-02-11 08:52:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
kill_gui (void)
|
|
|
|
{
|
|
|
|
set_idle_proc (find_dlg, 0);
|
|
|
|
destroy_dlg (find_dlg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2009-06-22 21:46:34 +04:00
|
|
|
find_file (const char *start_dir, const char *pattern, const char *content,
|
|
|
|
char **dirname, char **filename)
|
1999-02-11 08:52:55 +03:00
|
|
|
{
|
|
|
|
int return_value = 0;
|
2009-06-22 21:46:34 +04:00
|
|
|
char *dir_tmp = NULL, *file_tmp = NULL;
|
1999-02-11 08:52:55 +03:00
|
|
|
|
|
|
|
setup_gui ();
|
2003-09-23 02:05:27 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* FIXME: Need to cleanup this, this ought to be passed non-globaly */
|
2009-06-22 21:46:34 +04:00
|
|
|
find_pattern = str_unconst (pattern);
|
2008-12-29 02:06:38 +03:00
|
|
|
content_pattern = (content != NULL && str_is_valid_string (content))
|
2009-08-24 15:00:14 +04:00
|
|
|
? g_strdup(content)
|
2008-12-29 02:06:38 +03:00
|
|
|
: NULL;
|
2003-09-23 02:05:27 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
init_find_vars ();
|
|
|
|
push_directory (start_dir);
|
|
|
|
|
1999-02-11 08:52:55 +03:00
|
|
|
return_value = run_process ();
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* Remove all the items in the stack */
|
2009-06-22 21:46:34 +04:00
|
|
|
clear_stack ();
|
1999-02-11 08:52:55 +03:00
|
|
|
|
|
|
|
get_list_info (&file_tmp, &dir_tmp);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
if (dir_tmp)
|
2009-02-06 01:40:32 +03:00
|
|
|
*dirname = g_strdup (dir_tmp);
|
1998-02-27 07:54:42 +03:00
|
|
|
if (file_tmp)
|
2009-02-06 01:40:32 +03:00
|
|
|
*filename = g_strdup (file_tmp);
|
1999-02-11 08:52:55 +03:00
|
|
|
|
2003-09-23 02:05:27 +04:00
|
|
|
if (return_value == B_PANELIZE && *filename) {
|
2002-10-14 02:23:17 +04:00
|
|
|
int status, link_to_dir, stale_link;
|
1998-02-27 07:54:42 +03:00
|
|
|
int next_free = 0;
|
|
|
|
int i;
|
2003-08-18 04:47:43 +04:00
|
|
|
struct stat st;
|
1998-02-27 07:54:42 +03:00
|
|
|
WLEntry *entry = find_list->list;
|
2003-10-26 09:45:59 +03:00
|
|
|
dir_list *list = ¤t_panel->dir;
|
2009-06-22 21:46:34 +04:00
|
|
|
char *name = NULL;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
for (i = 0; entry != NULL && i < find_list->count;
|
|
|
|
entry = entry->next, i++) {
|
|
|
|
const char *filename = NULL;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2002-12-11 10:14:00 +03:00
|
|
|
if (!entry->text || !entry->data)
|
|
|
|
continue;
|
|
|
|
|
2009-06-22 21:46:34 +04:00
|
|
|
if (content_pattern != NULL)
|
2003-09-23 02:05:27 +04:00
|
|
|
filename = strchr (entry->text + 4, ':') + 1;
|
1998-02-27 07:54:42 +03:00
|
|
|
else
|
2003-09-23 02:05:27 +04:00
|
|
|
filename = entry->text + 4;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2006-02-04 14:03:35 +03:00
|
|
|
name = make_fullname (entry->data, filename);
|
2003-09-23 02:05:27 +04:00
|
|
|
status =
|
|
|
|
handle_path (list, name, &st, next_free, &link_to_dir,
|
|
|
|
&stale_link);
|
1998-02-27 07:54:42 +03:00
|
|
|
if (status == 0) {
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (name);
|
1998-02-27 07:54:42 +03:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (status == -1) {
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (name);
|
1998-02-27 07:54:42 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* don't add files more than once to the panel */
|
2009-06-22 21:46:34 +04:00
|
|
|
if (content_pattern != NULL && next_free > 0
|
|
|
|
&& strcmp (list->list[next_free - 1].fname, name) == 0) {
|
|
|
|
g_free (name);
|
|
|
|
continue;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2003-09-23 02:05:27 +04:00
|
|
|
if (!next_free) /* first turn i.e clean old list */
|
2003-10-26 09:45:59 +03:00
|
|
|
panel_clean_dir (current_panel);
|
2003-09-23 02:05:27 +04:00
|
|
|
list->list[next_free].fnamelen = strlen (name);
|
|
|
|
list->list[next_free].fname = name;
|
|
|
|
list->list[next_free].f.marked = 0;
|
|
|
|
list->list[next_free].f.link_to_dir = link_to_dir;
|
|
|
|
list->list[next_free].f.stale_link = stale_link;
|
|
|
|
list->list[next_free].f.dir_size_computed = 0;
|
|
|
|
list->list[next_free].st = st;
|
2008-12-29 02:07:48 +03:00
|
|
|
list->list[next_free].sort_key = NULL;
|
|
|
|
list->list[next_free].second_sort_key = NULL;
|
1998-02-27 07:54:42 +03:00
|
|
|
next_free++;
|
2003-09-23 02:05:27 +04:00
|
|
|
if (!(next_free & 15))
|
|
|
|
rotate_dash ();
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2009-06-22 21:46:34 +04:00
|
|
|
|
2003-09-23 02:05:27 +04:00
|
|
|
if (next_free) {
|
2003-10-26 09:45:59 +03:00
|
|
|
current_panel->count = next_free;
|
|
|
|
current_panel->is_panelized = 1;
|
2003-09-23 02:05:27 +04:00
|
|
|
|
|
|
|
if (start_dir[0] == PATH_SEP) {
|
2003-10-26 09:45:59 +03:00
|
|
|
strcpy (current_panel->cwd, PATH_SEP_STR);
|
1998-02-27 07:54:42 +03:00
|
|
|
chdir (PATH_SEP_STR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-24 15:00:14 +04:00
|
|
|
g_free (content_pattern);
|
1999-02-11 08:52:55 +03:00
|
|
|
kill_gui ();
|
2009-06-22 21:46:34 +04:00
|
|
|
do_search (NULL); /* force do_search to release resources */
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (old_dir);
|
2009-06-22 21:46:34 +04:00
|
|
|
old_dir = NULL;
|
2004-09-04 02:00:27 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
return return_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
do_find (void)
|
|
|
|
{
|
2005-05-21 07:26:36 +04:00
|
|
|
char *start_dir = NULL, *pattern = NULL, *content = NULL;
|
2009-06-22 21:46:34 +04:00
|
|
|
char *filename = NULL, *dirname = NULL;
|
|
|
|
int v;
|
|
|
|
gboolean dir_and_file_set;
|
2002-02-28 16:50:03 +03:00
|
|
|
|
2009-05-04 16:47:49 +04:00
|
|
|
while (find_parameters (&start_dir, &pattern, &content)){
|
2009-06-22 21:46:34 +04:00
|
|
|
if (pattern [0] == '\0')
|
|
|
|
break; /* nothing search*/
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
dirname = filename = NULL;
|
2009-08-05 10:10:00 +04:00
|
|
|
is_start = FALSE;
|
1998-02-27 07:54:42 +03:00
|
|
|
v = find_file (start_dir, pattern, content, &dirname, &filename);
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (pattern);
|
2009-05-04 16:47:49 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
if (v == B_ENTER){
|
|
|
|
if (dirname || filename){
|
|
|
|
if (dirname){
|
|
|
|
do_cd (dirname, cd_exact);
|
|
|
|
if (filename)
|
2003-10-26 09:45:59 +03:00
|
|
|
try_to_select (current_panel, filename + (content ?
|
1998-02-27 07:54:42 +03:00
|
|
|
(strchr (filename + 4, ':') - filename + 1) : 4) );
|
|
|
|
} else if (filename)
|
|
|
|
do_cd (filename, cd_exact);
|
2003-10-26 09:45:59 +03:00
|
|
|
select_item (current_panel);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (dirname);
|
|
|
|
g_free (filename);
|
1998-02-27 07:54:42 +03:00
|
|
|
break;
|
|
|
|
}
|
2009-06-22 21:46:34 +04:00
|
|
|
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (content);
|
1998-02-27 07:54:42 +03:00
|
|
|
dir_and_file_set = dirname && filename;
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (dirname);
|
|
|
|
g_free (filename);
|
2009-06-22 21:46:34 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
if (v == B_CANCEL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (v == B_PANELIZE){
|
|
|
|
if (dir_and_file_set){
|
2003-10-26 09:45:59 +03:00
|
|
|
try_to_select (current_panel, NULL);
|
|
|
|
panel_re_sort (current_panel);
|
2006-02-03 19:59:52 +03:00
|
|
|
try_to_select (current_panel, NULL);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|