1 /* Find file command for the Midnight Commander
2 Copyright (C) The Free Software Foundation
3 Written 1995 by Miguel de Icaza
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
29 #include <sys/param.h>
39 /* Dialog manager and widgets */
43 #include "dialog.h" /* For do_refresh() */
44 #define DIR_H_INCLUDE_HANDLE_DIRENT
46 #include "panel.h" /* current_panel */
47 #include "main.h" /* do_cd, try_to_select */
50 #include "cmd.h" /* view_file_at_line */
51 #include "../vfs/vfs.h"
53 #ifndef PORT_HAS_FLUSH_EVENTS
54 # define x_flush_events()
57 /* Size of the find parameters window */
59 static int FIND_X
= 50;
61 /* Size of the find window */
62 #define FIND2_Y LINES-4
63 static int FIND2_X
= 64;
66 # define FIND2_X_USE 35
68 # define FIND2_X_USE FIND2_X-20
71 /* A couple of extra messages we need */
80 /* A list of directories to be ignores, separated with ':' */
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 int running
= 0; /* nice flag */
87 static char *find_pattern
; /* Pattern to search */
88 static char *content_pattern
; /* pattern to search inside files */
89 static int count
; /* Number of files displayed */
90 static int matches
; /* Number of matches */
91 static int is_start
; /* Status of the start/stop toggle button */
92 int max_loops_in_idle
= 10;
95 static Dlg_head
*find_dlg
; /* The dialog */
98 static GtkWidget
*g_find_dlg
;
99 static GtkWidget
*g_status_label
;
100 static GtkWidget
*g_clist
;
101 static GtkWidget
*g_start_stop
;
102 static GtkWidget
*g_start_stop_label
;
103 static GtkWidget
*g_view
, *g_edit
;
104 static GtkWidget
*g_panelize
;
105 static int current_row
;
109 static WButton
*stop_button
; /* pointer to the stop button */
110 static WLabel
*status_label
; /* Finished, Searching etc. */
111 static WListbox
*find_list
; /* Listbox with the file list */
114 /* For nice updating */
115 static char *rotating_dash
= "|/-\\";
117 /* This keeps track of the directory stack */
118 typedef struct dir_stack
{
120 struct dir_stack
*prev
;
123 dir_stack
*dir_stack_base
= 0;
127 int len
; /* length including space and brackets */
130 { N_("&Suspend"), 11, 29 },
131 { N_("Con&tinue"), 12, 29 },
132 { N_("&Chdir"), 11, 3 },
133 { N_("&Again"), 9, 17 },
134 { N_("&Quit"), 8, 43 },
135 { N_("Pane&lize"), 12, 3 },
136 { N_("&View - F3"), 13, 20 },
137 { N_("&Edit - F4"), 13, 38 }
140 static char *add_to_list (char *text
, void *closure
);
141 static void stop_idle (void *data
);
142 static void status_update (char *text
);
143 static void get_list_info (char **file
, char **dir
);
146 * find_parameters: gets information from the user
148 * If the return value is true, then the following holds:
150 * START_DIR and PATTERN are pointers to char * and upon return they
151 * contain the information provided by the user.
153 * CONTENT holds a strdup of the contents specified by the user if he
154 * asked for them or 0 if not (note, this is different from the
155 * behavior for the other two parameters.
160 find_parameters (char **start_dir
, char **pattern
, char **content
)
166 static char *in_contents
= NULL
;
167 static char *in_start_dir
= NULL
;
168 static char *in_start_name
= NULL
;
170 static char* labs
[] = {N_("Start at:"), N_("Filename:"), N_("Content: ")};
171 static char* buts
[] = {N_("&Ok"), N_("&Tree"), N_("&Cancel")};
172 static int ilen
= 30, istart
= 14;
173 static int b0
= 3, b1
= 16, b2
= 36;
176 static int i18n_flag
= 0;
180 register int i
= sizeof(labs
)/sizeof(labs
[0]);
185 l1
= strlen (labs
[i
] = _(labs
[i
]));
189 i
= maxlen
+ ilen
+ 7;
193 for (i
= sizeof(buts
)/sizeof(buts
[0]), l1
= 0; i
--; )
195 l1
+= strlen (buts
[i
] = _(buts
[i
]));
201 ilen
= FIND_X
- 7 - maxlen
; /* for the case of very long buttons :) */
202 istart
= FIND_X
- 3 - ilen
;
204 b1
= b0
+ strlen(buts
[0]) + 7;
205 b2
= FIND_X
- (strlen(buts
[2]) + 6);
210 #endif /* ENABLE_NLS */
214 in_start_dir
= g_strdup (".");
216 in_start_name
= g_strdup (easy_patterns
? "*" : ".");
218 in_contents
= g_strdup ("");
220 find_dlg
= create_dlg (0, 0, FIND_Y
, FIND_X
, dialog_colors
,
221 common_dialog_callback
, "[Find File]", "findfile",
222 DLG_CENTER
| DLG_GRID
);
223 x_set_dialog_title (find_dlg
, _("Find File"));
225 add_widgetl (find_dlg
, button_new (9, b2
, B_CANCEL
, NORMAL_BUTTON
,
226 buts
[2], 0 ,0, "cancel"), XV_WLAY_RIGHTOF
);
228 add_widgetl (find_dlg
, button_new (9, b1
, B_TREE
, NORMAL_BUTTON
,
229 buts
[1], 0, 0, "tree"), XV_WLAY_RIGHTOF
);
231 add_widgetl (find_dlg
, button_new (9, b0
, B_ENTER
, DEFPUSH_BUTTON
,
232 buts
[0], 0, 0, "ok"), XV_WLAY_CENTERROW
);
234 in_with
= input_new (7, istart
, INPUT_COLOR
, ilen
, in_contents
, "content");
235 add_widgetl (find_dlg
, in_with
, XV_WLAY_BELOWOF
);
237 in_name
= input_new (5, istart
, INPUT_COLOR
, ilen
, in_start_name
, "name");
238 add_widgetl (find_dlg
, in_name
, XV_WLAY_BELOWOF
);
240 in_start
= input_new (3, istart
, INPUT_COLOR
, ilen
, in_start_dir
, "start");
241 add_widgetl (find_dlg
, in_start
, XV_WLAY_NEXTCOLUMN
);
243 add_widgetl (find_dlg
, label_new (7, 3, labs
[2], "label-cont"), XV_WLAY_BELOWOF
);
244 add_widgetl (find_dlg
, label_new (5, 3, labs
[1], "label-file"), XV_WLAY_BELOWOF
);
245 add_widgetl (find_dlg
, label_new (3, 3, labs
[0], "label-start"), XV_WLAY_NEXTCOLUMN
);
249 switch (find_dlg
->ret_value
){
256 temp_dir
= g_strdup (in_start
->buffer
);
257 destroy_dlg (find_dlg
);
258 g_free (in_start_dir
);
259 if (strcmp (temp_dir
, ".") == 0){
261 temp_dir
= g_strdup (cpanel
->cwd
);
263 in_start_dir
= tree (temp_dir
);
267 in_start_dir
= temp_dir
;
268 /* Warning: Dreadful goto */
275 *start_dir
= g_strdup (in_start
->buffer
);
276 *pattern
= g_strdup (in_name
->buffer
);
278 g_free (in_contents
);
279 if (in_with
->buffer
[0]){
280 *content
= g_strdup (in_with
->buffer
);
281 in_contents
= g_strdup (*content
);
283 *content
= in_contents
= NULL
;
285 g_free (in_start_dir
);
286 in_start_dir
= g_strdup (*start_dir
);
287 g_free (in_start_name
);
288 in_start_name
= g_strdup (*pattern
);
291 destroy_dlg (find_dlg
);
297 push_directory (char *dir
)
301 new = g_new (dir_stack
, 1);
302 new->name
= g_strdup (dir
);
303 new->prev
= dir_stack_base
;
304 dir_stack_base
= new;
314 name
= dir_stack_base
->name
;
315 next
= dir_stack_base
->prev
;
316 g_free (dir_stack_base
);
317 dir_stack_base
= next
;
324 insert_file (char *dir
, char *file
)
327 static char *dirname
;
330 if (dir
[0] == PATH_SEP
&& dir
[1] == PATH_SEP
)
334 if (dir
[i
- 1] != PATH_SEP
){
341 if (strcmp (old_dir
, dir
)){
343 old_dir
= g_strdup (dir
);
344 dirname
= add_to_list (dir
, NULL
);
347 old_dir
= g_strdup (dir
);
348 dirname
= add_to_list (dir
, NULL
);
351 tmp_name
= g_strconcat (" ", file
, NULL
);
352 add_to_list (tmp_name
, dirname
);
357 find_add_match (Dlg_head
*h
, char *dir
, char *file
)
359 int p
= ++matches
& 7;
361 insert_file (dir
, file
);
366 listbox_select_last (find_list
, 1);
368 listbox_select_last (find_list
, 0);
372 /* Updates the current listing */
373 send_message (h
, &find_list
->widget
, WIDGET_DRAW
, 0);
382 /* commented out because mc runs egrep via execvp() which searches PATH
383 itself. It is likely that egrep in PATH is better than in /bin */
395 for (p
= &paths
[0]; *p
; p
++){
396 if (stat (*p
, &s
) == 0)
406 * Search with egrep the global (FIXME) content_pattern string in the
407 * DIRECTORY/FILE. It will add the found entries to the find listbox.
410 search_content (Dlg_head
*h
, char *directory
, char *filename
)
413 char buffer
[BUF_SMALL
];
415 int file_fd
, pipe
, ignoring
;
419 static char *egrep_path
;
421 fname
= concat_dir_and_file (directory
, filename
);
423 if (mc_stat (fname
, &s
) != 0 && !S_ISREG (s
.st_mode
)){
427 if (!S_ISREG (s
.st_mode
)){
432 file_fd
= mc_open (fname
, O_RDONLY
);
439 egrep_path
= locate_egrep ();
442 pipe
= mc_doublepopen (file_fd
, -1, &pid
, egrep_path
, egrep_path
, "-n", content_pattern
, NULL
);
443 #else /* GREP_STDIN */
444 pipe
= mc_doublepopen (file_fd
, -1, &pid
, egrep_path
, egrep_path
, "-n", content_pattern
, "-", NULL
);
445 #endif /* GREP STDIN */
452 g_snprintf (buffer
, sizeof (buffer
), _("Grepping in %s"), name_trunc (filename
, FIND2_X_USE
));
454 status_update (buffer
);
459 enable_interrupt_key ();
462 i
= read (pipe
, &c
, 1);
478 the_name
= g_strconcat (buffer
, ":", filename
, NULL
);
479 find_add_match (h
, directory
, the_name
);
482 if (p
- buffer
< (sizeof (buffer
)-1) && ISASCII (c
) && isdigit (c
))
488 disable_interrupt_key ();
490 message (1, _(" Find/read "), _(" Problem reading from child "));
492 mc_doublepclose (pipe
, pid
);
497 do_search (struct Dlg_head
*h
)
499 static struct dirent
*dp
= 0;
500 static DIR *dirp
= 0;
501 static char directory
[MC_MAXPATHLEN
+2];
502 struct stat tmp_stat
;
506 static int subdirs_left
= 0;
507 char *tmp_name
; /* For bulding file names */
509 if (!h
) { /* someone forces me to close dirp */
531 attrset (REVERSE_COLOR
);
534 tmp
= pop_directory ();
537 status_update (_("Finished"));
541 if (find_ignore_dirs
){
543 char *temp_dir
= g_strconcat (":", tmp
, ":", NULL
);
545 found
= strstr (find_ignore_dirs
, temp_dir
) != 0;
555 strcpy (directory
, tmp
);
559 char buffer
[BUF_SMALL
];
561 g_snprintf (buffer
, sizeof (buffer
), _("Searching %s"), name_trunc (directory
, FIND2_X_USE
));
562 status_update (buffer
);
564 /* mc_stat should not be called after mc_opendir
565 because vfs_s_opendir modifies the st_nlink
567 mc_stat (directory
, &tmp_stat
);
568 subdirs_left
= tmp_stat
.st_nlink
- 2;
569 /* Commented out as unnecessary
570 if (subdirs_left < 0)
571 subdirs_left = MAXINT;
573 dirp
= mc_opendir (directory
);
575 dp
= mc_readdir (dirp
);
578 if (strcmp (dp
->d_name
, ".") == 0 ||
579 strcmp (dp
->d_name
, "..") == 0){
580 dp
= mc_readdir (dirp
);
584 tmp_name
= concat_dir_and_file (directory
, dp
->d_name
);
587 mc_lstat (tmp_name
, &tmp_stat
);
588 if (S_ISDIR (tmp_stat
.st_mode
)){
589 push_directory (tmp_name
);
594 if (regexp_match (find_pattern
, dp
->d_name
, match_file
)){
596 search_content (h
, directory
, dp
->d_name
);
598 find_add_match (h
, directory
, dp
->d_name
);
602 dp
= mc_readdir (dirp
);
604 /* Displays the nice dot */
611 dlg_move (h
, FIND2_Y
-6, FIND2_X
- 4);
612 addch (rotating_dash
[pos
]);
616 goto do_search_begin
;
626 init_find_vars (void)
637 /* Remove all the items in the stack */
638 while ((dir
= pop_directory ()) != NULL
)
643 find_do_view_edit (int unparsed_view
, int edit
, char *dir
, char *file
)
645 char *fullname
, *filename
;
648 if (content_pattern
){
649 filename
= strchr (file
+ 4, ':') + 1;
650 line
= atoi (file
+ 4);
655 if (dir
[0] == '.' && dir
[1] == 0)
656 fullname
= g_strdup (filename
);
657 else if (dir
[0] == '.' && dir
[1] == PATH_SEP
)
658 fullname
= concat_dir_and_file (dir
+2, filename
);
660 fullname
= concat_dir_and_file (dir
, filename
);
663 do_edit_at_line (fullname
, line
);
665 view_file_at_line (fullname
, unparsed_view
, use_internal_view
, line
);
671 select_row (GtkCList
*clist
, gint row
, gint column
, GdkEvent
*event
)
673 gtk_widget_set_sensitive (g_edit
, TRUE
);
674 gtk_widget_set_sensitive (g_view
, TRUE
);
681 gtk_idle_remove (idle_tag
);
690 gtk_idle_remove (idle_tag
);
697 find_do_panelize (void)
699 gtk_idle_remove (idle_tag
);
706 find_start_stop (void)
710 idle_tag
= gtk_idle_add ((GtkFunction
)do_search
, g_find_dlg
);
712 gtk_idle_remove (idle_tag
);
716 gtk_label_set_text (GTK_LABEL (g_start_stop_label
),
717 is_start
? _("Suspend") : _("Restart"));
718 is_start
= !is_start
;
719 status_update (is_start
? _("Stopped") : _("Searching"));
728 get_list_info (&file
, &dir
);
730 find_do_view_edit (0, 0, dir
, file
);
738 get_list_info (&file
, &dir
);
740 find_do_view_edit (0, 1, dir
, file
);
746 GtkWidget
*sw
, *b1
, *b2
, *b3
;
747 GtkWidget
*box
, *box2
;
749 g_find_dlg
= gnome_dialog_new (
751 GNOME_STOCK_BUTTON_OK
,
755 b1
= gtk_button_new_with_label (_("Change to this directory"));
756 b2
= gtk_button_new_with_label (_("Search again"));
757 g_start_stop_label
= gtk_label_new (_("Suspend"));
758 g_start_stop
= gtk_button_new ();
759 gtk_container_add (GTK_CONTAINER (g_start_stop
), g_start_stop_label
);
761 g_view
= gtk_button_new_with_label (_("View this file"));
762 g_edit
= gtk_button_new_with_label (_("Edit this file"));
763 g_panelize
= gtk_button_new_with_label (_("Send the results to a Panel"));
765 box
= gtk_hbox_new (TRUE
, GNOME_PAD
);
766 gtk_box_pack_start (GTK_BOX (box
), b1
, 0, 1, 0);
767 gtk_box_pack_start (GTK_BOX (box
), b2
, 0, 1, 0);
768 gtk_box_pack_start (GTK_BOX (box
), g_start_stop
, 0, 1, 0);
770 /* RECOONECT _("Panelize contents"), */
774 sw
= gtk_scrolled_window_new (NULL
, NULL
);
775 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw
),
777 GTK_POLICY_AUTOMATIC
);
778 g_clist
= gtk_clist_new (1);
779 gtk_clist_set_selection_mode (GTK_CLIST (g_clist
), GTK_SELECTION_SINGLE
);
780 gtk_widget_set_usize (g_clist
, -1, 200);
781 gtk_container_add (GTK_CONTAINER (sw
), g_clist
);
782 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (g_find_dlg
)->vbox
),
783 sw
, TRUE
, TRUE
, GNOME_PAD_SMALL
);
787 gtk_signal_connect (GTK_OBJECT (g_clist
), "select_row",
788 GTK_SIGNAL_FUNC (select_row
), NULL
);
791 * Connect the buttons
794 GTK_OBJECT (b1
), "clicked", GTK_SIGNAL_FUNC (find_do_chdir
), NULL
);
796 GTK_OBJECT (b2
), "clicked", GTK_SIGNAL_FUNC (find_do_again
), NULL
);
798 GTK_OBJECT (g_start_stop
), "clicked", GTK_SIGNAL_FUNC (find_start_stop
), NULL
);
800 GTK_OBJECT (g_panelize
), "clicked", GTK_SIGNAL_FUNC (find_do_panelize
), NULL
);
806 GTK_OBJECT (g_view
), "clicked", GTK_SIGNAL_FUNC (find_do_view
), NULL
);
808 GTK_OBJECT (g_edit
), "clicked", GTK_SIGNAL_FUNC (find_do_edit
), NULL
);
810 gtk_widget_set_sensitive (g_view
, FALSE
);
811 gtk_widget_set_sensitive (g_edit
, FALSE
);
812 box2
= gtk_hbox_new (1, GNOME_PAD
+ GNOME_PAD
);
813 gtk_box_pack_start (GTK_BOX (box2
), g_view
, 0, 0, 0);
814 gtk_box_pack_start (GTK_BOX (box2
), g_edit
, 0, 0, 0);
816 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (g_find_dlg
)->vbox
),
817 box
, TRUE
, TRUE
, GNOME_PAD_SMALL
);
818 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (g_find_dlg
)->vbox
),
819 box2
, TRUE
, TRUE
, GNOME_PAD_SMALL
);
821 g_status_label
= gtk_label_new (_("Searching"));
822 gtk_misc_set_alignment (GTK_MISC (g_status_label
), 0.0, 0.5);
823 gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (g_find_dlg
)->vbox
),
824 g_status_label
, TRUE
, TRUE
, GNOME_PAD_SMALL
);
826 gtk_widget_show_all (g_find_dlg
);
827 gtk_widget_hide (GTK_WIDGET (g_view
));
828 gtk_widget_hide (GTK_WIDGET (g_edit
));
834 idle_tag
= gtk_idle_add ((GtkFunction
)do_search
, g_find_dlg
);
836 gnome_dialog_run (GNOME_DIALOG (g_find_dlg
));
845 gtk_object_destroy (GTK_OBJECT (g_find_dlg
));
849 stop_idle (void *data
)
852 gtk_widget_set_sensitive (GTK_WIDGET (g_start_stop
), FALSE
);
856 status_update (char *text
)
858 gtk_label_set_text (GTK_LABEL (g_status_label
), text
);
863 add_to_list (char *text
, void *data
)
870 row
= gtk_clist_append (GTK_CLIST (g_clist
), texts
);
871 gtk_clist_set_row_data (GTK_CLIST (g_clist
), row
, data
);
873 if (gtk_clist_row_is_visible (GTK_CLIST (g_clist
), row
) != GTK_VISIBILITY_FULL
)
874 gtk_clist_moveto (GTK_CLIST (g_clist
), row
, 0, 0.5, 0.0);
880 get_list_info (char **file
, char **dir
)
882 if (current_row
== -1)
884 gtk_clist_get_text (GTK_CLIST (g_clist
), current_row
, 0, file
);
885 *dir
= gtk_clist_get_row_data (GTK_CLIST (g_clist
), current_row
);
890 get_list_info (char **file
, char **dir
)
892 listbox_get_current (find_list
, file
, dir
);
896 add_to_list (char *text
, void *data
)
898 return listbox_add_item (find_list
, 0, 0, text
, data
);
902 stop_idle (void *data
)
904 set_idle_proc (data
, 0);
908 view_edit_currently_selected_file (int unparsed_view
, int edit
)
910 WLEntry
*entry
= find_list
->current
;
914 return MSG_NOT_HANDLED
;
918 if (!entry
->text
|| !dir
)
919 return MSG_NOT_HANDLED
;
921 find_do_view_edit (unparsed_view
, edit
, dir
, entry
->text
);
926 find_callback (struct Dlg_head
*h
, int id
, int Msg
)
931 common_dialog_repaint (h
);
936 if (id
== KEY_F(3) || id
== KEY_F(13)){
937 int unparsed_view
= (id
== KEY_F(13));
938 return view_edit_currently_selected_file (unparsed_view
, 0);
941 return view_edit_currently_selected_file (0, 1);
943 return MSG_NOT_HANDLED
;
952 /* Handles the Stop/Start button in the find window */
954 start_stop (int button
, void *extra
)
957 set_idle_proc (find_dlg
, running
);
958 is_start
= !is_start
;
960 status_update (is_start
? _("Stopped") : _("Searching"));
961 button_set_text (stop_button
, fbuts
[is_start
].text
);
966 /* Handle view command, when invoked as a button */
968 find_do_view_file (int button
, void *extra
)
970 view_edit_currently_selected_file (0, 0);
974 /* Handle edit command, when invoked as a button */
976 find_do_edit_file (int button
, void *extra
)
978 view_edit_currently_selected_file (0, 1);
986 static int i18n_flag
= 0;
989 register int i
= sizeof (fbuts
) / sizeof (fbuts
[0]);
991 fbuts
[i
].len
= strlen (fbuts
[i
].text
= _(fbuts
[i
].text
)) + 3;
992 fbuts
[2].len
+= 2; /* DEFPUSH_BUTTON */
995 #endif /* ENABLE_NLS */
998 * Dynamically place buttons centered within current window size
1001 int l0
= max (fbuts
[0].len
, fbuts
[1].len
);
1002 int l1
= fbuts
[2].len
+ fbuts
[3].len
+ l0
+ fbuts
[4].len
;
1003 int l2
= fbuts
[5].len
+ fbuts
[6].len
+ fbuts
[7].len
;
1006 FIND2_X
= COLS
- 16;
1008 /* Check, if both button rows fit within FIND2_X */
1009 if (l1
+ 9 > FIND2_X
) FIND2_X
= l1
+ 9;
1010 if (l2
+ 8 > FIND2_X
) FIND2_X
= l2
+ 8;
1012 /* compute amount of space between buttons for each row */
1013 r1
= (FIND2_X
- 4 - l1
) % 5;
1014 l1
= (FIND2_X
- 4 - l1
) / 5;
1015 r2
= (FIND2_X
- 4 - l2
) % 4;
1016 l2
= (FIND2_X
- 4 - l2
) / 4;
1018 /* ...and finally, place buttons */
1019 fbuts
[2].x
= 2 + r1
/2 + l1
;
1020 fbuts
[3].x
= fbuts
[2].x
+ fbuts
[2].len
+ l1
;
1021 fbuts
[0].x
= fbuts
[3].x
+ fbuts
[3].len
+ l1
;
1022 fbuts
[4].x
= fbuts
[0].x
+ l0
+ l1
;
1023 fbuts
[5].x
= 2 + r2
/2 + l2
;
1024 fbuts
[6].x
= fbuts
[5].x
+ fbuts
[5].len
+ l2
;
1025 fbuts
[7].x
= fbuts
[6].x
+ fbuts
[6].len
+ l2
;
1028 find_dlg
= create_dlg (0, 0, FIND2_Y
, FIND2_X
, dialog_colors
,
1029 find_callback
, "[Find File]", "mfind", DLG_CENTER
| DLG_GRID
);
1031 x_set_dialog_title (find_dlg
, _("Find file"));
1033 add_widgetl (find_dlg
,
1034 button_new (FIND2_Y
-3, fbuts
[7].x
, B_VIEW
, NORMAL_BUTTON
,
1035 fbuts
[7].text
, find_do_edit_file
, find_dlg
, "button-edit"), 0);
1036 add_widgetl (find_dlg
,
1037 button_new (FIND2_Y
-3, fbuts
[6].x
, B_VIEW
, NORMAL_BUTTON
,
1038 fbuts
[6].text
, find_do_view_file
, find_dlg
, "button-view"), 0);
1039 add_widgetl (find_dlg
,
1040 button_new (FIND2_Y
-3, fbuts
[5].x
, B_PANELIZE
, NORMAL_BUTTON
,
1041 fbuts
[5].text
, 0, 0, "button-panelize"), XV_WLAY_CENTERROW
);
1043 add_widgetl (find_dlg
,
1044 button_new (FIND2_Y
-4, fbuts
[4].x
, B_CANCEL
, NORMAL_BUTTON
,
1045 fbuts
[4].text
, 0, 0, "button-quit"), XV_WLAY_RIGHTOF
);
1046 stop_button
= button_new (FIND2_Y
-4, fbuts
[0].x
, B_STOP
, NORMAL_BUTTON
,
1047 fbuts
[0].text
, start_stop
, find_dlg
, "start-stop");
1048 add_widgetl (find_dlg
, stop_button
, XV_WLAY_RIGHTOF
);
1049 add_widgetl (find_dlg
,
1050 button_new (FIND2_Y
-4, fbuts
[3].x
, B_AGAIN
, NORMAL_BUTTON
,
1051 fbuts
[3].text
, 0, 0, "button-again"), XV_WLAY_RIGHTOF
);
1052 add_widgetl (find_dlg
,
1053 button_new (FIND2_Y
-4, fbuts
[2].x
, B_ENTER
, DEFPUSH_BUTTON
,
1054 fbuts
[2].text
, 0, 0, "button-chdir"), XV_WLAY_CENTERROW
);
1056 status_label
= label_new (FIND2_Y
-6, 4, _("Searching"), "label-search");
1057 add_widgetl (find_dlg
, status_label
, XV_WLAY_BELOWOF
);
1059 find_list
= listbox_new (2, 2, FIND2_X
-4, FIND2_Y
-9, listbox_finish
, 0, "listbox");
1060 add_widgetl (find_dlg
, find_list
, XV_WLAY_EXTENDWIDTH
);
1066 set_idle_proc (find_dlg
, 1);
1068 return find_dlg
->ret_value
;
1072 status_update (char *text
)
1074 label_set_text (status_label
, text
);
1080 set_idle_proc (find_dlg
, 0);
1081 destroy_dlg (find_dlg
);
1086 find_file (char *start_dir
, char *pattern
, char *content
, char **dirname
, char **filename
)
1088 int return_value
= 0;
1090 char *dir_tmp
, *file_tmp
;
1094 /* FIXME: Need to cleanup this, this ought to be passed non-globaly */
1095 find_pattern
= pattern
;
1096 content_pattern
= content
;
1099 push_directory (start_dir
);
1101 return_value
= run_process ();
1103 /* Remove all the items in the stack */
1104 while ((dir
= pop_directory ()) != NULL
)
1107 get_list_info (&file_tmp
, &dir_tmp
);
1110 *dirname
= g_strdup (dir_tmp
);
1112 *filename
= g_strdup (file_tmp
);
1115 if (return_value
== B_PANELIZE
&& *filename
){
1116 int status
, link_to_dir
, stalled_link
;
1120 WLEntry
*entry
= find_list
->list
;
1121 dir_list
*list
= &cpanel
->dir
;
1124 for (i
= 0; entry
&& i
< find_list
->count
; entry
= entry
->next
, i
++){
1127 if (content_pattern
)
1128 filename
= strchr (entry
->text
+4, ':')+1;
1130 filename
= entry
->text
+4;
1132 if (!entry
->text
|| !entry
->data
)
1135 if (dir
[0] == '.' && dir
[1] == 0)
1136 name
= g_strdup (filename
);
1137 else if (dir
[0] == '.' && dir
[1] == PATH_SEP
)
1138 name
= concat_dir_and_file (dir
+ 2, filename
);
1140 name
= concat_dir_and_file (dir
, filename
);
1141 status
= handle_path (list
, name
, &buf
, next_free
, &link_to_dir
,
1152 /* don't add files more than once to the panel */
1153 if (content_pattern
&& next_free
> 0){
1154 if (strcmp (list
->list
[next_free
-1].fname
, name
) == 0) {
1160 if (!next_free
) /* first turn i.e clean old list */
1161 panel_clean_dir (cpanel
);
1162 list
->list
[next_free
].fnamelen
= strlen (name
);
1163 list
->list
[next_free
].fname
= name
;
1164 file_mark (cpanel
, next_free
, 0);
1165 list
->list
[next_free
].f
.link_to_dir
= link_to_dir
;
1166 list
->list
[next_free
].f
.stalled_link
= stalled_link
;
1167 list
->list
[next_free
].f
.dir_size_computed
= 0;
1168 list
->list
[next_free
].buf
= buf
;
1170 if (!(next_free
& 15))
1174 cpanel
->count
= next_free
;
1175 cpanel
->is_panelized
= 1;
1176 /* Done by panel_clean_dir a few lines above
1177 cpanel->dirs_marked = 0;
1180 cpanel->top_file = 0;
1181 cpanel->selected = 0;*/
1183 if (start_dir
[0] == PATH_SEP
){
1184 strcpy (cpanel
->cwd
, PATH_SEP_STR
);
1185 chdir (PATH_SEP_STR
);
1192 do_search (0); /* force do_search to release resources */
1197 return return_value
;
1203 char *start_dir
, *pattern
, *content
;
1204 char *filename
, *dirname
;
1205 int v
, dir_and_file_set
;
1209 if (!find_parameters (&start_dir
, &pattern
, &content
))
1212 dirname
= filename
= NULL
;
1214 v
= find_file (start_dir
, pattern
, content
, &dirname
, &filename
);
1219 if (dirname
|| filename
){
1221 do_cd (dirname
, cd_exact
);
1223 try_to_select (cpanel
, filename
+ (content
?
1224 (strchr (filename
+ 4, ':') - filename
+ 1) : 4) );
1225 } else if (filename
)
1226 do_cd (filename
, cd_exact
);
1227 paint_panel (cpanel
);
1228 select_item (cpanel
);
1238 dir_and_file_set
= dirname
&& filename
;
1239 if (dirname
) g_free (dirname
);
1240 if (filename
) g_free (filename
);
1244 if (v
== B_PANELIZE
){
1245 if (dir_and_file_set
){
1246 try_to_select (cpanel
, NULL
);
1247 paint_panel (cpanel
);