1 /* Find file command for the Midnight Commander
2 Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007 Free Software Foundation, Inc.
4 Written 1995 by Miguel de Icaza
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
23 * \brief Source: Find file command
42 /* Dialog manager and widgets */
47 #include "panel.h" /* current_panel */
48 #include "main.h" /* do_cd, try_to_select */
50 #include "cmd.h" /* view_file_at_line */
53 #include "../src/search/search.h"
55 /* Size of the find parameters window */
57 static int FIND_X
= 60;
59 /* Size of the find window */
60 #define FIND2_Y (LINES - 4)
62 static int FIND2_X
= 64;
63 #define FIND2_X_USE (FIND2_X - 20)
65 /* A couple of extra messages we need */
80 /* List of directories to be ignored, separated by ':' */
81 char *find_ignore_dirs
= 0;
83 static WInput
*in_start
; /* Start path */
84 static WInput
*in_name
; /* Pattern to search */
85 static WInput
*in_with
; /* Text inside filename */
86 static WCheck
*case_sense
; /* "case sensitive" checkbox */
87 static WCheck
*find_regex_cbox
; /* [x] find regular expression */
89 static int running
= 0; /* nice flag */
90 static char *find_pattern
; /* Pattern to search */
91 static char *content_pattern
; /* pattern to search inside files; if
92 content_regexp_flag is true, it contains the
93 regex pattern, else the search string. */
94 static int count
; /* Number of files displayed */
95 static int matches
; /* Number of matches */
96 static int is_start
; /* Status of the start/stop toggle button */
99 /* Where did we stop */
101 static int last_line
;
104 static Dlg_head
*find_dlg
; /* The dialog */
106 static WButton
*stop_button
; /* pointer to the stop button */
107 static WLabel
*status_label
; /* Finished, Searching etc. */
108 static WListbox
*find_list
; /* Listbox with the file list */
110 /* This keeps track of the directory stack */
111 typedef struct dir_stack
{
113 struct dir_stack
*prev
;
116 static dir_stack
*dir_stack_base
= 0;
120 int len
; /* length including space and brackets */
123 { N_("&Suspend"), 11, 29 },
124 { N_("Con&tinue"), 12, 29 },
125 { N_("&Chdir"), 11, 3 },
126 { N_("&Again"), 9, 17 },
127 { N_("&Quit"), 8, 43 },
128 { N_("Pane&lize"), 12, 3 },
129 { N_("&View - F3"), 13, 20 },
130 { N_("&Edit - F4"), 13, 38 }
133 static inline char * add_to_list (const char *text
, void *data
) {
134 return listbox_add_item (find_list
, 0, 0, text
, data
);
136 static inline void stop_idle (void *data
) {
137 set_idle_proc (data
, 0);
139 static inline void status_update (const char *text
) {
140 label_set_text (status_label
, text
);
142 static void get_list_info (char **file
, char **dir
) {
143 listbox_get_current (find_list
, file
, dir
);
146 static mc_search_t
*search_file_handle
= NULL
;
147 static gboolean skip_hidden_flag
= FALSE
;
148 static gboolean file_regexp_flag
= FALSE
;
149 static gboolean file_all_charsets_flag
= FALSE
;
150 static gboolean file_case_sentitive
= TRUE
;
152 static mc_search_t
*search_content_handle
= NULL
;
153 static gboolean content_regexp_flag
= FALSE
;
154 static gboolean content_all_charsets_flag
= FALSE
;
155 static gboolean content_case_sensitive
= TRUE
;
157 static int find_recursively
= 1;
160 * Callback for the parameter dialog.
161 * Validate regex, prevent closing the dialog if it's invalid.
164 find_parm_callback (struct Dlg_head
*h
, dlg_msg_t msg
, int parm
)
168 if ((h
->ret_value
!= B_ENTER
) || !in_with
->buffer
[0]
169 || !(find_regex_cbox
->state
& C_BOOL
))
176 if (regcomp (r, in_with->buffer, flags)) {
177 message (D_ERROR, MSG_ERROR, _(" Malformed regular expression "));
178 dlg_select_widget (in_with);
179 h->running = 1; // Don't stop the dialog
185 return default_dlg_callback (h
, msg
, parm
);
190 * find_parameters: gets information from the user
192 * If the return value is true, then the following holds:
194 * START_DIR and PATTERN are pointers to char * and upon return they
195 * contain the information provided by the user.
197 * CONTENT holds a strdup of the contents specified by the user if he
198 * asked for them or 0 if not (note, this is different from the
199 * behavior for the other two parameters.
203 find_parameters (char **start_dir
, char **pattern
, char **content
)
207 static const char *case_label
= N_("case &Sensitive");
208 static const char *recurs_label
= N_("&Find recursively");
209 static const char *skip_hidden_label
= N_("S&kip hidden");
210 static const char *all_charsets_label
= N_("All charsets");
211 static const char *regexp_label
= N_("&Regular expression");
212 static const char *file_regexp_label
= N_("Regular expression");
214 WCheck
*recursively_cbox
;
215 WCheck
*file_regexp_cbox
;
216 WCheck
*skip_hidden_cbox
;
218 WCheck
*file_all_charsets_cbox
;
219 WCheck
*content_all_charsets_cbox
;
222 static char *in_contents
= NULL
;
223 static char *in_start_dir
= NULL
;
224 static char *in_start_name
= NULL
;
226 static const char *labs
[] =
227 { N_("Start at:"), N_("Filename:"), N_("Content: ") };
228 static const char *buts
[] = { N_("&OK"), N_("&Tree"), N_("&Cancel") };
229 static int ilen
= 30, istart
= 14;
230 static int b0
= 3, b1
= 16, b2
= 36;
233 static int i18n_flag
= 0;
236 register int i
= sizeof (labs
) / sizeof (labs
[0]);
240 l1
= str_term_width1 (labs
[i
] = _(labs
[i
]));
244 i
= maxlen
+ ilen
+ 7;
248 for (i
= sizeof (buts
) / sizeof (buts
[0]), l1
= 0; i
--;) {
249 l1
+= str_term_width1 (buts
[i
] = _(buts
[i
]));
255 ilen
= FIND_X
- 7 - maxlen
; /* for the case of very long buttons :) */
256 istart
= FIND_X
- 3 - ilen
;
258 b1
= b0
+ str_term_width1 (buts
[0]) + 7;
259 b2
= FIND_X
- (str_term_width1 (buts
[2]) + 6);
262 case_label
= _(case_label
);
263 recurs_label
= _(recurs_label
);
265 #endif /* ENABLE_NLS */
269 in_start_dir
= g_strdup (".");
271 in_start_name
= g_strdup (easy_patterns
? "*" : ".");
273 in_contents
= g_strdup ("");
276 create_dlg (0, 0, FIND_Y
, FIND_X
, dialog_colors
,
277 find_parm_callback
, "[Find File]", _("Find File"),
278 DLG_CENTER
| DLG_REVERSE
);
280 add_widget (find_dlg
,
281 button_new (FIND_Y
- 3, b2
, B_CANCEL
, NORMAL_BUTTON
, buts
[2], 0));
282 add_widget (find_dlg
,
283 button_new (FIND_Y
- 3, b1
, B_TREE
, NORMAL_BUTTON
, buts
[1], 0));
284 add_widget (find_dlg
,
285 button_new (FIND_Y
- 3, b0
, B_ENTER
, DEFPUSH_BUTTON
, buts
[0], 0));
287 file_regexp_cbox
= check_new (6, 3, file_regexp_flag
, file_regexp_label
);
288 recursively_cbox
= check_new (7, 3, find_recursively
, recurs_label
);
289 skip_hidden_cbox
= check_new (6, 33, skip_hidden_flag
, skip_hidden_label
);
291 file_all_charsets_cbox
= check_new (7, 33, file_all_charsets_flag
, all_charsets_label
);
294 find_regex_cbox
= check_new (11, 3, content_regexp_flag
, regexp_label
);
295 case_sense
= check_new (10, 3, content_case_sensitive
, case_label
);
297 content_all_charsets_cbox
= check_new (10, 33, content_all_charsets_flag
, all_charsets_label
);
300 in_with
= input_new (9, istart
, INPUT_COLOR
, ilen
, in_contents
, "content", INPUT_COMPLETE_DEFAULT
);
301 in_name
= input_new (5, istart
, INPUT_COLOR
, ilen
, in_start_name
, "name", INPUT_COMPLETE_DEFAULT
);
302 in_start
= input_new (3, istart
, INPUT_COLOR
, ilen
, in_start_dir
, "start", INPUT_COMPLETE_DEFAULT
);
305 add_widget (find_dlg
, content_all_charsets_cbox
);
307 add_widget (find_dlg
, find_regex_cbox
);
308 add_widget (find_dlg
, case_sense
);
309 add_widget (find_dlg
, in_with
);
311 add_widget (find_dlg
, file_all_charsets_cbox
);
313 add_widget (find_dlg
, skip_hidden_cbox
);
314 add_widget (find_dlg
, recursively_cbox
);
315 add_widget (find_dlg
, file_regexp_cbox
);
316 add_widget (find_dlg
, in_name
);
317 add_widget (find_dlg
, in_start
);
319 add_widget (find_dlg
, label_new (9, 3, labs
[2]));
320 add_widget (find_dlg
, label_new (5, 3, labs
[1]));
321 add_widget (find_dlg
, label_new (3, 3, labs
[0]));
323 dlg_select_widget (in_name
);
327 switch (find_dlg
->ret_value
) {
333 temp_dir
= g_strdup (in_start
->buffer
);
335 file_all_charsets_flag
= file_all_charsets_cbox
->state
& C_BOOL
;
336 content_all_charsets_flag
= content_all_charsets_cbox
->state
& C_BOOL
;
338 content_case_sensitive
= case_sense
->state
& C_BOOL
;
339 content_regexp_flag
= find_regex_cbox
->state
& C_BOOL
;
340 file_regexp_flag
= file_regexp_cbox
->state
& C_BOOL
;
341 find_recursively
= recursively_cbox
->state
& C_BOOL
;
342 skip_hidden_flag
= skip_hidden_cbox
->state
& C_BOOL
;
343 destroy_dlg (find_dlg
);
344 g_free (in_start_dir
);
345 if (strcmp (temp_dir
, ".") == 0) {
347 temp_dir
= g_strdup (current_panel
->cwd
);
349 in_start_dir
= tree_box (temp_dir
);
353 in_start_dir
= temp_dir
;
354 /* Warning: Dreadful goto */
359 g_free (in_contents
);
360 if (in_with
->buffer
[0]) {
361 *content
= g_strdup (in_with
->buffer
);
362 in_contents
= g_strdup (*content
);
364 *content
= in_contents
= NULL
;
367 file_all_charsets_flag
= file_all_charsets_cbox
->state
& C_BOOL
;
368 content_all_charsets_flag
= content_all_charsets_cbox
->state
& C_BOOL
;
370 content_case_sensitive
= case_sense
->state
& C_BOOL
;
371 content_regexp_flag
= find_regex_cbox
->state
& C_BOOL
;
372 find_recursively
= recursively_cbox
->state
& C_BOOL
;
373 file_regexp_flag
= file_regexp_cbox
->state
& C_BOOL
;
374 skip_hidden_flag
= skip_hidden_cbox
->state
& C_BOOL
;
376 *start_dir
= g_strdup (in_start
->buffer
);
377 *pattern
= g_strdup (in_name
->buffer
);
379 g_free (in_start_dir
);
380 in_start_dir
= g_strdup (*start_dir
);
381 g_free (in_start_name
);
382 in_start_name
= g_strdup (*pattern
);
385 destroy_dlg (find_dlg
);
391 push_directory (const char *dir
)
395 new = g_new (dir_stack
, 1);
396 new->name
= concat_dir_and_file (dir
, "");
397 new->prev
= dir_stack_base
;
398 dir_stack_base
= new;
408 name
= dir_stack_base
->name
;
409 next
= dir_stack_base
->prev
;
410 g_free (dir_stack_base
);
411 dir_stack_base
= next
;
418 insert_file (const char *dir
, const char *file
)
421 static char *dirname
;
423 while (dir
[0] == PATH_SEP
&& dir
[1] == PATH_SEP
)
427 if (strcmp (old_dir
, dir
)){
429 old_dir
= g_strdup (dir
);
430 dirname
= add_to_list (dir
, NULL
);
433 old_dir
= g_strdup (dir
);
434 dirname
= add_to_list (dir
, NULL
);
437 tmp_name
= g_strconcat (" ", file
, (char *) NULL
);
438 add_to_list (tmp_name
, dirname
);
443 find_add_match (Dlg_head
*h
, const char *dir
, const char *file
)
445 int p
= ++matches
& 7;
449 insert_file (dir
, file
);
453 listbox_select_last (find_list
, 1);
455 listbox_select_last (find_list
, 0);
456 /* Updates the current listing */
457 send_message (&find_list
->widget
, WIDGET_DRAW
, 0);
465 * Returns malloced null-terminated line from file file_fd.
466 * Input is buffered in buf_size long buffer.
467 * Current pos in buf is stored in pos.
468 * n_read - number of read chars.
469 * has_newline - is there newline ?
472 get_line_at (int file_fd
, char *buf
, int *pos
, int *n_read
, int buf_size
,
481 if (*pos
>= *n_read
) {
483 if ((*n_read
= mc_read (file_fd
, buf
, buf_size
)) <= 0)
489 /* skip possible leading zero(s) */
496 if (i
>= buffer_size
- 1) {
497 buffer
= g_realloc (buffer
, buffer_size
+= 80);
506 *has_newline
= ch
? 1 : 0;
515 static FindProgressStatus
516 check_find_events(Dlg_head
*h
)
521 c
= get_event (&event
, h
->mouse_status
== MOU_REPEAT
, 0);
523 dlg_process_event (h
, c
, &event
);
524 if (h
->ret_value
== B_ENTER
525 || h
->ret_value
== B_CANCEL
526 || h
->ret_value
== B_AGAIN
527 || h
->ret_value
== B_PANELIZE
) {
528 /* dialog terminated */
531 if (!(h
->flags
& DLG_WANT_IDLE
)) {
532 /* searching suspended */
543 * Search the global (FIXME) regexp compiled content_pattern string in the
544 * DIRECTORY/FILE. It will add the found entries to the find listbox.
546 * returns 0 if do_search should look for another file
547 * 1 if do_search should exit and proceed to the event handler
550 search_content (Dlg_head
*h
, const char *directory
, const char *filename
)
553 char buffer
[BUF_4K
];
558 fname
= concat_dir_and_file (directory
, filename
);
560 if (mc_stat (fname
, &s
) != 0 || !S_ISREG (s
.st_mode
)){
565 file_fd
= mc_open (fname
, O_RDONLY
);
571 g_snprintf (buffer
, sizeof (buffer
), _("Grepping in %s"), str_trunc (filename
, FIND2_X_USE
));
573 status_update (buffer
);
576 enable_interrupt_key ();
585 gboolean found
= FALSE
;
589 /* We've been previously suspended, start from the previous position */
594 while ((p
= get_line_at (file_fd
, buffer
, &pos
, &n_read
, sizeof (buffer
), &has_newline
)) && (ret_val
== 0)){
595 if (found
== FALSE
){ /* Search in binary line once */
596 if (mc_search_run (search_content_handle
, (const void *) p
, 0, strlen(p
), &founded_len
))
598 char *fnd_info
= g_strdup_printf ("%d:%s", line
, filename
);
599 find_add_match (h
, directory
, fnd_info
);
609 if ((line
& 0xff) == 0) {
610 FindProgressStatus res
;
611 res
= check_find_events(h
);
630 disable_interrupt_key ();
636 do_search (struct Dlg_head
*h
)
638 static struct dirent
*dp
= 0;
639 static DIR *dirp
= 0;
640 static char *directory
;
641 struct stat tmp_stat
;
643 static int subdirs_left
= 0;
646 if (!h
) { /* someone forces me to close dirp */
657 search_content_handle
= mc_search_new(content_pattern
, -1);
658 if (search_content_handle
)
660 search_content_handle
->search_type
= (content_regexp_flag
) ? MC_SEARCH_T_REGEX
: MC_SEARCH_T_NORMAL
;
661 search_content_handle
->is_case_sentitive
= content_case_sensitive
;
662 search_content_handle
->is_all_charsets
= content_all_charsets_flag
;
664 search_file_handle
= mc_search_new(find_pattern
, -1);
665 search_file_handle
->search_type
= (file_regexp_flag
) ? MC_SEARCH_T_REGEX
: MC_SEARCH_T_GLOB
;
666 search_file_handle
->is_case_sentitive
= file_case_sentitive
;
667 search_file_handle
->is_all_charsets
= file_all_charsets_flag
;
668 search_file_handle
->is_entire_line
= !file_regexp_flag
;
681 attrset (REVERSE_COLOR
);
683 tmp
= pop_directory ();
686 status_update (_("Finished"));
688 mc_search_free(search_file_handle
);
689 search_file_handle
= NULL
;
690 mc_search_free(search_content_handle
);
691 search_content_handle
= NULL
;
694 if (find_ignore_dirs
){
696 char *temp_dir
= g_strconcat (":", tmp
, ":", (char *) NULL
);
698 found
= strstr (find_ignore_dirs
, temp_dir
) != 0;
712 char buffer
[BUF_SMALL
];
714 g_snprintf (buffer
, sizeof (buffer
), _("Searching %s"),
715 str_trunc (directory
, FIND2_X_USE
));
716 status_update (buffer
);
718 /* mc_stat should not be called after mc_opendir
719 because vfs_s_opendir modifies the st_nlink
721 if (!mc_stat (directory
, &tmp_stat
))
722 subdirs_left
= tmp_stat
.st_nlink
- 2;
725 /* Commented out as unnecessary
726 if (subdirs_left < 0)
727 subdirs_left = MAXINT;
729 dirp
= mc_opendir (directory
);
730 } /* while (!dirp) */
731 dp
= mc_readdir (dirp
);
732 /* skip invalid filenames */
733 while (dp
!= NULL
&& !str_is_valid_string (dp
->d_name
))
734 dp
= mc_readdir (dirp
);
737 if (strcmp (dp
->d_name
, ".") == 0 ||
738 strcmp (dp
->d_name
, "..") == 0){
739 dp
= mc_readdir (dirp
);
740 /* skip invalid filenames */
741 while (dp
!= NULL
&& !str_is_valid_string (dp
->d_name
))
742 dp
= mc_readdir (dirp
);
744 mc_search_free(search_file_handle
);
745 search_file_handle
= NULL
;
746 mc_search_free(search_content_handle
);
747 search_content_handle
= NULL
;
751 if (!(skip_hidden_flag
&& dp
->d_name
[0] == '.')) {
752 if (subdirs_left
&& find_recursively
&& directory
) { /* Can directory be NULL ? */
753 char *tmp_name
= concat_dir_and_file (directory
, dp
->d_name
);
754 if (!mc_lstat (tmp_name
, &tmp_stat
)
755 && S_ISDIR (tmp_stat
.st_mode
)) {
756 push_directory (tmp_name
);
761 if (mc_search_run (search_file_handle
,dp
->d_name
, 0, strlen (dp
->d_name
), &bytes_found
)) {
762 if (content_pattern
) {
763 if (search_content (h
, directory
, dp
->d_name
)) {
764 mc_search_free(search_file_handle
);
765 search_file_handle
= NULL
;
766 mc_search_free(search_content_handle
);
767 search_content_handle
= NULL
;
771 find_add_match (h
, directory
, dp
->d_name
);
775 dp
= mc_readdir (dirp
);
776 /* skip invalid filenames */
777 while (dp
!= NULL
&& !str_is_valid_string (dp
->d_name
))
778 dp
= mc_readdir (dirp
);
780 /* Displays the nice dot */
783 /* For nice updating */
784 const char *rotating_dash
= "|/-\\";
788 attrset (DLG_NORMALC (h
));
789 dlg_move (h
, FIND2_Y
-6, FIND2_X
- 4);
790 addch (rotating_dash
[pos
]);
794 goto do_search_begin
;
795 mc_search_free(search_file_handle
);
796 search_file_handle
= NULL
;
797 mc_search_free(search_content_handle
);
798 search_content_handle
= NULL
;
803 init_find_vars (void)
812 /* Remove all the items in the stack */
813 while ((dir
= pop_directory ()) != NULL
)
818 make_fullname (const char *dirname
, const char *filename
)
821 if (strcmp(dirname
, ".") == 0 || strcmp(dirname
, "."PATH_SEP_STR
) == 0)
822 return g_strdup (filename
);
823 if (strncmp(dirname
, "."PATH_SEP_STR
, 2) == 0)
824 return concat_dir_and_file (dirname
+ 2, filename
);
825 return concat_dir_and_file (dirname
, filename
);
829 find_do_view_edit (int unparsed_view
, int edit
, char *dir
, char *file
)
832 const char *filename
;
835 if (content_pattern
){
836 filename
= strchr (file
+ 4, ':') + 1;
837 line
= atoi (file
+ 4);
843 fullname
= make_fullname (dir
, filename
);
845 do_edit_at_line (fullname
, line
);
847 view_file_at_line (fullname
, unparsed_view
, use_internal_view
, line
);
852 view_edit_currently_selected_file (int unparsed_view
, int edit
)
854 WLEntry
*entry
= find_list
->current
;
858 return MSG_NOT_HANDLED
;
862 if (!entry
->text
|| !dir
)
863 return MSG_NOT_HANDLED
;
865 find_do_view_edit (unparsed_view
, edit
, dir
, entry
->text
);
870 find_callback (struct Dlg_head
*h
, dlg_msg_t msg
, int parm
)
874 if (parm
== KEY_F (3) || parm
== KEY_F (13)) {
875 int unparsed_view
= (parm
== KEY_F (13));
876 return view_edit_currently_selected_file (unparsed_view
, 0);
878 if (parm
== KEY_F (4)) {
879 return view_edit_currently_selected_file (0, 1);
881 return MSG_NOT_HANDLED
;
888 return default_dlg_callback (h
, msg
, parm
);
892 /* Handles the Stop/Start button in the find window */
894 start_stop (int button
)
899 set_idle_proc (find_dlg
, running
);
900 is_start
= !is_start
;
902 status_update (is_start
? _("Stopped") : _("Searching"));
903 button_set_text (stop_button
, fbuts
[is_start
].text
);
908 /* Handle view command, when invoked as a button */
910 find_do_view_file (int button
)
914 view_edit_currently_selected_file (0, 0);
918 /* Handle edit command, when invoked as a button */
920 find_do_edit_file (int button
)
924 view_edit_currently_selected_file (0, 1);
932 static int i18n_flag
= 0;
934 register int i
= sizeof (fbuts
) / sizeof (fbuts
[0]);
936 fbuts
[i
].len
= str_term_width1 (fbuts
[i
].text
= _(fbuts
[i
].text
)) + 3;
937 fbuts
[2].len
+= 2; /* DEFPUSH_BUTTON */
940 #endif /* ENABLE_NLS */
943 * Dynamically place buttons centered within current window size
946 int l0
= max (fbuts
[0].len
, fbuts
[1].len
);
947 int l1
= fbuts
[2].len
+ fbuts
[3].len
+ l0
+ fbuts
[4].len
;
948 int l2
= fbuts
[5].len
+ fbuts
[6].len
+ fbuts
[7].len
;
953 /* Check, if both button rows fit within FIND2_X */
954 if (l1
+ 9 > FIND2_X
)
956 if (l2
+ 8 > FIND2_X
)
959 /* compute amount of space between buttons for each row */
960 r1
= (FIND2_X
- 4 - l1
) % 5;
961 l1
= (FIND2_X
- 4 - l1
) / 5;
962 r2
= (FIND2_X
- 4 - l2
) % 4;
963 l2
= (FIND2_X
- 4 - l2
) / 4;
965 /* ...and finally, place buttons */
966 fbuts
[2].x
= 2 + r1
/ 2 + l1
;
967 fbuts
[3].x
= fbuts
[2].x
+ fbuts
[2].len
+ l1
;
968 fbuts
[0].x
= fbuts
[3].x
+ fbuts
[3].len
+ l1
;
969 fbuts
[4].x
= fbuts
[0].x
+ l0
+ l1
;
970 fbuts
[5].x
= 2 + r2
/ 2 + l2
;
971 fbuts
[6].x
= fbuts
[5].x
+ fbuts
[5].len
+ l2
;
972 fbuts
[7].x
= fbuts
[6].x
+ fbuts
[6].len
+ l2
;
976 create_dlg (0, 0, FIND2_Y
, FIND2_X
, dialog_colors
, find_callback
,
977 "[Find File]", _("Find File"), DLG_CENTER
| DLG_REVERSE
);
979 add_widget (find_dlg
,
980 button_new (FIND2_Y
- 3, fbuts
[7].x
, B_VIEW
, NORMAL_BUTTON
,
981 fbuts
[7].text
, find_do_edit_file
));
982 add_widget (find_dlg
,
983 button_new (FIND2_Y
- 3, fbuts
[6].x
, B_VIEW
, NORMAL_BUTTON
,
984 fbuts
[6].text
, find_do_view_file
));
985 add_widget (find_dlg
,
986 button_new (FIND2_Y
- 3, fbuts
[5].x
, B_PANELIZE
,
987 NORMAL_BUTTON
, fbuts
[5].text
, 0));
989 add_widget (find_dlg
,
990 button_new (FIND2_Y
- 4, fbuts
[4].x
, B_CANCEL
,
991 NORMAL_BUTTON
, fbuts
[4].text
, 0));
993 button_new (FIND2_Y
- 4, fbuts
[0].x
, B_STOP
, NORMAL_BUTTON
,
994 fbuts
[0].text
, start_stop
);
995 add_widget (find_dlg
, stop_button
);
996 add_widget (find_dlg
,
997 button_new (FIND2_Y
- 4, fbuts
[3].x
, B_AGAIN
,
998 NORMAL_BUTTON
, fbuts
[3].text
, 0));
999 add_widget (find_dlg
,
1000 button_new (FIND2_Y
- 4, fbuts
[2].x
, B_ENTER
,
1001 DEFPUSH_BUTTON
, fbuts
[2].text
, 0));
1003 status_label
= label_new (FIND2_Y
- 6, 4, _("Searching"));
1004 add_widget (find_dlg
, status_label
);
1007 listbox_new (2, 2, FIND2_Y
- 9, FIND2_X
- 4, NULL
);
1008 add_widget (find_dlg
, find_list
);
1015 set_idle_proc (find_dlg
, 1);
1017 return find_dlg
->ret_value
;
1023 set_idle_proc (find_dlg
, 0);
1024 destroy_dlg (find_dlg
);
1028 find_file (char *start_dir
, char *pattern
, char *content
, char **dirname
,
1031 int return_value
= 0;
1033 char *dir_tmp
, *file_tmp
;
1037 /* FIXME: Need to cleanup this, this ought to be passed non-globaly */
1038 find_pattern
= pattern
;
1039 content_pattern
= (content
!= NULL
&& str_is_valid_string (content
))
1040 ? str_create_search_needle (content
, content_case_sensitive
)
1044 push_directory (start_dir
);
1046 return_value
= run_process ();
1048 /* Remove all the items in the stack */
1049 while ((dir
= pop_directory ()) != NULL
)
1052 get_list_info (&file_tmp
, &dir_tmp
);
1055 *dirname
= g_strdup (dir_tmp
);
1057 *filename
= g_strdup (file_tmp
);
1059 if (return_value
== B_PANELIZE
&& *filename
) {
1060 int status
, link_to_dir
, stale_link
;
1064 WLEntry
*entry
= find_list
->list
;
1065 dir_list
*list
= ¤t_panel
->dir
;
1068 for (i
= 0; entry
&& i
< find_list
->count
;
1069 entry
= entry
->next
, i
++) {
1070 const char *filename
;
1072 if (!entry
->text
|| !entry
->data
)
1075 if (content_pattern
)
1076 filename
= strchr (entry
->text
+ 4, ':') + 1;
1078 filename
= entry
->text
+ 4;
1080 name
= make_fullname (entry
->data
, filename
);
1082 handle_path (list
, name
, &st
, next_free
, &link_to_dir
,
1093 /* don't add files more than once to the panel */
1094 if (content_pattern
&& next_free
> 0) {
1095 if (strcmp (list
->list
[next_free
- 1].fname
, name
) == 0) {
1101 if (!next_free
) /* first turn i.e clean old list */
1102 panel_clean_dir (current_panel
);
1103 list
->list
[next_free
].fnamelen
= strlen (name
);
1104 list
->list
[next_free
].fname
= name
;
1105 list
->list
[next_free
].f
.marked
= 0;
1106 list
->list
[next_free
].f
.link_to_dir
= link_to_dir
;
1107 list
->list
[next_free
].f
.stale_link
= stale_link
;
1108 list
->list
[next_free
].f
.dir_size_computed
= 0;
1109 list
->list
[next_free
].st
= st
;
1110 list
->list
[next_free
].sort_key
= NULL
;
1111 list
->list
[next_free
].second_sort_key
= NULL
;
1113 if (!(next_free
& 15))
1117 current_panel
->count
= next_free
;
1118 current_panel
->is_panelized
= 1;
1119 /* Done by panel_clean_dir a few lines above
1120 current_panel->dirs_marked = 0;
1121 current_panel->marked = 0;
1122 current_panel->total = 0;
1123 current_panel->top_file = 0;
1124 current_panel->selected = 0; */
1126 if (start_dir
[0] == PATH_SEP
) {
1127 strcpy (current_panel
->cwd
, PATH_SEP_STR
);
1128 chdir (PATH_SEP_STR
);
1133 if (content_pattern
!= NULL
) str_release_search_needle (content_pattern
, content_case_sensitive
);
1135 do_search (0); /* force do_search to release resources */
1139 return return_value
;
1145 char *start_dir
= NULL
, *pattern
= NULL
, *content
= NULL
;
1146 char *filename
, *dirname
;
1147 int v
, dir_and_file_set
;
1149 while (find_parameters (&start_dir
, &pattern
, &content
)){
1151 dirname
= filename
= NULL
;
1153 v
= find_file (start_dir
, pattern
, content
, &dirname
, &filename
);
1158 if (dirname
|| filename
){
1160 do_cd (dirname
, cd_exact
);
1162 try_to_select (current_panel
, filename
+ (content
?
1163 (strchr (filename
+ 4, ':') - filename
+ 1) : 4) );
1164 } else if (filename
)
1165 do_cd (filename
, cd_exact
);
1166 select_item (current_panel
);
1173 dir_and_file_set
= dirname
&& filename
;
1179 if (v
== B_PANELIZE
){
1180 if (dir_and_file_set
){
1181 try_to_select (current_panel
, NULL
);
1182 panel_re_sort (current_panel
);
1183 try_to_select (current_panel
, NULL
);