/[beaver]/beaver/src/search.c
ViewVC logotype

Diff of /beaver/src/search.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by skypher, Sun Mar 16 19:04:03 2003 UTC revision 1.4 by mikix, Tue Mar 18 06:03:12 2003 UTC
# Line 25  Line 25 
25    
26  #include <gtk/gtk.h>  #include <gtk/gtk.h>
27  #include <stdio.h>  #include <stdio.h>
28    #include <stdlib.h>
29  #include <string.h>  #include <string.h>
30  #include <ctype.h>  #include <ctype.h>
31  #include <sys/stat.h>  #include <sys/stat.h>
32  #include "main.h"  #include <sys/types.h>
33    #include <sys/wait.h>
34    #include <unistd.h>
35    #include <wordexp.h>
36  #include "tools.h"  #include "tools.h"
37  #include "editor.h"  #include "editor.h"
38  #include "struct.h"  #include "struct.h"
39  #include "msgbar.h"  #include "msgbar.h"
40  #include "prefs.h"  #include "prefs.h"
41    #include "main.h"
42  #include "search.h"  #include "search.h"
43    #include "filesops.h"
44    
45  extern GArray *FileProperties;  extern GArray *FileProperties;
46  extern GtkWidget *MainNotebook;  extern GtkWidget *MainNotebook;
47    extern GtkWidget *MainWindow;
48    extern GtkWidget *MainVBox;
49  extern gint OpenedFilesCnt;  extern gint OpenedFilesCnt;
50  extern t_settings       Settings;  extern t_settings       Settings;
 static gboolean SearchIsVisible = FALSE;  
51  static gboolean GotoLineIsVisible = FALSE;  static gboolean GotoLineIsVisible = FALSE;
52  static t_search_prefs *SearchPrefs;  
53  static GtkWidget *SearchEntry;  static GtkWidget *SearchDisplay = NULL;
54  static GtkWidget *ReplaceEntry;  static GtkWidget *SearchTree = NULL;
55  static GtkWidget *List;  
56    struct line_match
57    {
58            gint line;
59            gchar *text;
60    };
61    
62    struct file_results
63    {
64            GtkWidget *buffer;      // NULL if not from a buffer or buffer is closed
65            gchar *path;    // Full path of file/buffer
66            
67            GPtrArray *results;
68    };
69    
70    void ensure_search_display (void)
71    {
72            START_FCN
73            
74            if (!SearchDisplay)
75            {
76                    SearchDisplay = gtk_vpaned_new ();
77                    GtkCellRenderer *renderer;
78                    GtkWidget *scroller;
79                    
80                    g_signal_connect_swapped (G_OBJECT (SearchDisplay), "destroy",
81                            G_CALLBACK (g_nullify_pointer), &SearchDisplay);
82                    
83                    g_object_ref (MainNotebook);
84                    gtk_container_remove (GTK_CONTAINER (MainVBox), MainNotebook);
85                    
86                    gtk_paned_pack1 (GTK_PANED (SearchDisplay), MainNotebook, TRUE, TRUE);
87                    g_object_unref (MainNotebook);
88                    
89                    scroller = gtk_scrolled_window_new (NULL, NULL);
90                    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroller),
91                            GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
92                    
93                    SearchTree = gtk_tree_view_new ();
94                    
95                    gtk_container_add (GTK_CONTAINER (scroller), SearchTree);
96                    gtk_paned_pack2 (GTK_PANED (SearchDisplay), scroller, FALSE, TRUE);
97                    
98                    /* add the column */
99                    renderer = gtk_cell_renderer_text_new ();
100                    gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (SearchTree),
101                                            -1, "Match",
102                                            renderer, "text",
103                                            0,
104                                            NULL);
105                    
106                    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (SearchTree), FALSE);
107                    gtk_tree_view_set_search_column (GTK_TREE_VIEW (SearchTree), 0);
108                    
109                    gtk_container_add (GTK_CONTAINER (MainVBox), SearchDisplay);
110                    gtk_widget_show_all (SearchDisplay);
111            }
112            
113            END_FCN
114    }
115    
116    void display_search_results (GArray *array)
117    {
118            gint i, j;
119            GtkTreeStore *store;
120            
121            START_FCN
122            
123            ensure_search_display ();
124            
125            store = gtk_tree_store_new (1, G_TYPE_STRING);
126            
127            for (i = 0; i < array->len; i++)
128            {
129                    GtkTreeIter iter, parent;
130                    gint max_size;
131                    struct line_match *match;
132                    GPtrArray *results;
133                    gchar *max_line;
134                    
135                    gtk_tree_store_append (store, &parent, NULL);
136                    gtk_tree_store_set (store, &parent, 0,
137                            str_get_last_part (
138                                    g_array_index (array, struct file_results, i).path,
139                                    PATH_SEP, TRUE),
140                            -1);
141                    
142                    results = g_array_index (array, struct file_results, i).results;
143                    
144                    // calculate the maximum number of digits in any of the line numbers
145                    match = g_ptr_array_index (results, results->len - 1);
146                    max_line = g_strdup_printf ("%i", match->line);
147                    max_size = strlen (max_line);
148                    g_free (max_line);
149                    
150                    for (j = 0; j < results->len; j++)
151                    {
152                            gchar *output;
153                            
154                            match = g_ptr_array_index (results, j);
155                            
156                            gtk_tree_store_append (store, &iter, &parent);
157                            output = g_strdup_printf ("%*i %s", max_size, match->line, match->text);
158                            gtk_tree_store_set (store, &iter, 0, output, -1);
159                            g_free (output);
160                    }
161            }
162            
163            gtk_tree_view_set_model (GTK_TREE_VIEW (SearchTree), GTK_TREE_MODEL (store));
164            g_object_unref (store);
165            gtk_widget_show_all (SearchTree);
166            
167            END_FCN
168    }
169    
170  /* A sort of 'strcmp' for the characters: it returns '0' if the characteres  /* A sort of 'strcmp' for the characters: it returns '0' if the characteres
171     are the same */     are the same */
# Line 173  gint replace_all (gint page, Line 293  gint replace_all (gint page,
293  void goto_search (GtkList *MyList,  void goto_search (GtkList *MyList,
294                    GtkWidget *Widget)                    GtkWidget *Widget)
295  {  {
296    gint CurrentPage;  }
297    
298    if (!OpenedFilesCnt)  
299      {  
300        print_msg (_("Cannot refer to file: you closed all files!"));  /* Used to set up Search preferences */
301        return;  
302      }  void refresh_search (GtkWidget *Widget, gchar *Data)
303    CurrentPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(MainNotebook));  {
304    if (!strcmp (SearchPrefs -> FileName, FPROPS(CurrentPage, Name)))  }
305      {  
306        gchar *string, *msg;  /* expands a reg exp file pattern to a list of files */
307        gint Line, Begin, End, length;  /* this returned list is an array of strings, with |pre|
308        GtkTextIter start, end;     NULL entries before the results, a bunch of results,
309        GtkTextBuffer *EditorBuffer;     and an ending NULL. */
310    gchar **get_files_for_search (const gchar *regexp, gint pre)
311        gtk_label_get (GTK_LABEL(GTK_BIN(Widget) -> child), &string);  {
312        sscanf (string, "%*d. Line %d (%d-%d)", &Line, &Begin, &End);          gchar **answer;
313        EditorBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(          wordexp_t word;
314              FPROPS(CurrentPage, Text)));          
315        length = gtk_text_buffer_get_char_count(EditorBuffer);          START_FCN
316        if (End <= length)          
317          {          /* note: I feel that this is the place to make sure
318            gchar *selection;             the user is not trying to screw us with funny
319                         syntax and reserved symbols.  we should do some checking. */
320            gtk_text_buffer_get_iter_at_offset(EditorBuffer, &start, Begin);          
321            gtk_text_buffer_get_iter_at_offset(EditorBuffer, &end, End);          word.we_offs = pre;
322            gtk_text_buffer_move_mark_by_name(EditorBuffer,          if (wordexp (regexp, &word, WRDE_DOOFFS))
323                     "insert", &start);          {
324            gtk_text_buffer_move_mark_by_name(EditorBuffer,                  gint i;
325                     "selection_bound", &end);                  
326            selection = gtk_text_buffer_get_text(EditorBuffer,                  answer = g_malloc (sizeof (gchar *) * (pre + 1));
327                     &start, &end, FALSE);                  
328            if (SearchPrefs -> CaseSen)                  for (i = 0; i < pre; i++)
             {  
               if (strcmp (selection, SearchPrefs -> StringToSearch))  
329                  {                  {
330                    print_msg (_("You should refresh the search."));                          answer[i] = NULL;
                   return;  
331                  }                  }
332              }                  answer[i] = NULL;
           else  
             if (strcasecmp (selection, SearchPrefs -> StringToSearch))  
               {  
                 print_msg (_("You should refresh the search."));  
                 return;  
               }  
           msg = g_strdup_printf (_("Line %d (%d-%d) selected..."),  
                                  Line, Begin, End);  
         show_on_screen (GTK_TEXT_VIEW (FPROPS(CurrentPage, Text)), start);  
   
           print_msg (msg);  
           g_free (msg);  
           g_free (selection);  
333          }          }
334        else          else
335          print_msg          {
336            (_("Apparently you deleted the part you try to reach now!"));                  gint i;
337        /* g_free (string);                  
338           ... causes seg fault, I don't know why... */                  // fill out our array
339      }                  answer = g_malloc (sizeof (gchar *) *
340    else                          (word.we_wordc + word.we_offs + 1));
341      print_msg (_("The current search didn't operate on this file..."));                  for (i = word.we_offs; i < word.we_offs + word.we_wordc; i++)
342    (void)MyList; /* avoid the "unused parameter" warning */                  {
343                            answer[i] = g_strdup (word.we_wordv[i]);
344                    }
345                    answer[i] = NULL;
346            }
347            
348            wordfree (&word);
349            
350            END_FCN
351            return answer;
352  }  }
353    
354    // returns stdout
355    gchar *run_program_with_args (const gchar *prog, gchar *const args[], const gchar *input)
356    {
357            int in[2];
358            int out[2];
359            pid_t pid;
360            gchar *result = NULL;
361            
362            START_FCN
363            
364            pipe (in);
365            pipe (out);
366            pid = fork ();
367            
368            if (pid == (pid_t) 0)
369            {
370                    /* this is the child process */
371                    close (in[1]);
372                    close (out[0]);
373                    
374                    /* connect pipe to stdin and stdout */
375                    dup2 (in[0], STDIN_FILENO);
376                    dup2 (out[1], STDOUT_FILENO);
377                    
378                    execvp (prog, args);
379                    exit (0);
380            }
381            else
382            {
383                    FILE *stream_out;
384                    gulong size;
385                    size_t read;
386                    
387                    /* this is the parent process */
388                    close (in[0]);
389                    close (out[1]);
390                    
391                    if (input)
392                    {
393                            FILE *stream_in;
394                            
395                            stream_in = fdopen (in[1], "w");
396                            if (stream_in)
397                            {
398                                    fwrite (input, strlen (input), 1, stream_in);
399                                    fflush (stream_in);
400                                    fclose (stream_in);
401                            }
402                    }
403                    
404                    close (in[1]);
405                    
406                    stream_out = fdopen (out[0], "r");
407                    
408                    size = 200;
409                    result = (gchar *) g_malloc (size);
410                    while ((read = fread (result + size - 200, 1, 200, stream_out)) >= 200)
411                    {
412                            size += 200;
413                            result = (gchar *) g_realloc (result, size);
414                    }
415                    result[size - 200 + read] = '\0';
416                    fflush (stream_out);
417                    
418                    close (out[0]);
419            }
420            
421            END_FCN
422            
423            return result;
424    }
425    
426  void search_window_not_visible (void)  struct line_match *parse_grep_output_line (gchar *line)
427  {  {
428    SearchIsVisible = FALSE;          struct line_match *rv = (struct line_match *) g_malloc (sizeof (struct line_match));
429            gchar *colon;
430            
431            START_FCN
432            
433            colon = strchr (line, ':');
434            if (colon)
435            {
436                    colon[0] = '\0';
437                    rv->line = atoi (line);
438                    colon[0] = ':';
439                    colon++;
440                    rv->text = g_strdup (colon);
441            }
442            else
443            {
444                    rv->line = 0;
445                    rv->text = g_strdup (line);
446            }
447            
448            END_FCN
449            
450            return rv;
451  }  }
452    
453    struct file_results parse_grep_output (gchar *output, GtkWidget *widget, const gchar *filename)
454    {
455            struct file_results rv;
456            gchar *next;
457            
458            START_FCN
459            
460            rv.buffer = widget;
461            if (widget)
462                    g_signal_connect_swapped (G_OBJECT (widget), "destroy",
463                            G_CALLBACK (g_nullify_pointer), &rv.buffer);
464            rv.path = g_strdup (filename);
465            rv.results = g_ptr_array_new ();
466            
467            while ((next = strchr (output, '\n')))
468            {
469                    next[0] = '\0';
470                    g_ptr_array_add (rv.results, parse_grep_output_line (output));
471                    next[0] = '\n';
472                    output = next + 1;
473            }
474            
475            if (rv.results->len == 0)
476            {
477                    g_ptr_array_free (rv.results, FALSE);
478                    rv.results = NULL;
479            }
480            
481            END_FCN
482            
483            return rv;
484    }
485    
486  /* Used to set up Search preferences */  struct file_results run_grep_on_file (gchar *pattern, gchar *filename, gint flags)
487    {
488            gchar *args[5];
489            gint i = 0;
490            gchar *answers;
491            struct file_results rv;
492            
493            START_FCN
494            
495            args[i++] = "grep";
496            if (pattern) args[i++] = pattern;
497            args[i++] = "-n";
498            args[i++] = filename;
499            args[i++] = NULL;
500            
501            answers = run_program_with_args ("grep", args, NULL);
502            
503            rv = parse_grep_output (answers, NULL, filename);
504            
505            g_free (answers);
506            
507            END_FCN
508            
509            return rv;
510    }
511    
512  void refresh_search (GtkWidget *Widget, gchar *Data)  struct file_results run_grep_on_text (gchar *pattern, gint page, gint flags)
513  {  {
514    if (!strcmp (Data, "cursor"))          gchar *args[5];
515      SearchPrefs -> BeginCursorPos = TRUE;          gint i = 0;
516    else if (!strcmp (Data, "begin"))          gchar *answers;
517      SearchPrefs -> BeginCursorPos = FALSE;          struct file_results rv;
518    else if (!strcmp (Data, "case_sen"))          gchar *text;
519      {          
520        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(Widget)))          START_FCN
521          SearchPrefs -> CaseSen = TRUE;          
522        else          text = get_text (FPROPS (page, Buffer));
523          SearchPrefs -> CaseSen = FALSE;          
524      }          args[i++] = "grep";
525  /* TODO: implement the regexp feature */          if (pattern) args[i++] = pattern;
526  /*  else if (!strcmp (Data, "reg_exp"))          args[i++] = "-n";
527      {          args[i++] = "-";
528        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(Widget)))          args[i++] = NULL;
529          SearchPrefs -> RegExp = TRUE;          
530        else          answers = run_program_with_args ("grep", args, text);
531          SearchPrefs -> RegExp = FALSE;          
532      } */          rv = parse_grep_output (answers, FPROPS (page, Text), FPROPS (page, Name));
533    else if (!strcmp (Data, "search"))          
534      {          g_free (answers);
535        gchar *msg;          g_free (text);
536        gint SearchBegin, i, CurrentPage;          
537        t_search_results *search_res;          END_FCN
538        GtkWidget *ListItem;          
539              return rv;
540        if (!OpenedFilesCnt)  }
         {  
           print_msg (_("Cannot refer to file: you closed all files!"));  
           return;  
         }  
       SearchPrefs -> StringToSearch = gtk_entry_get_text  
         (GTK_ENTRY(SearchEntry));  
       if (!strlen(SearchPrefs -> StringToSearch))  
         return;  
       CurrentPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(MainNotebook));  
       SearchPrefs -> FileName = g_strdup (FPROPS(CurrentPage, Name));  
       if (SearchPrefs -> BeginCursorPos)  
         SearchBegin = get_position (FPROPS(CurrentPage, Buffer));  
       else  
         SearchBegin = 0;  
       gtk_list_clear_items (GTK_LIST(List), 0, -1);  
       search_res = find (CurrentPage,  
                          SearchPrefs -> CaseSen,  
                          SearchPrefs -> RegExp,  
                          SearchBegin,  
                          SearchPrefs -> StringToSearch);  
       for (i = 1; i <= search_res[0].Line; i++)  
         {  
           gchar *str_temp;  
             
           str_temp = g_strdup_printf (_("%d. Line %d (%d-%d)"), i,  
                                       search_res[i].Line,  
                                       search_res[i].Begin,  
                                       search_res[i].End);  
           ListItem = gtk_list_item_new_with_label (str_temp);  
           gtk_container_add (GTK_CONTAINER(List), ListItem);  
           g_free (str_temp);  
         }  
       gtk_list_select_item (GTK_LIST(List), 0);  
       gtk_widget_show_all (List);  
       gtk_entry_set_text (GTK_ENTRY(SearchEntry),  
                           SearchPrefs -> StringToSearch);  
       if (search_res[0].Line == 0)  
         msg = g_strdup_printf(_("String \"%s\" could not be found."), SearchPrefs -> StringToSearch);  
       else  
         {  
           gtk_window_set_focus(GTK_WINDOW(gtk_widget_get_toplevel(Widget)),  
                                GTK_WIDGET(GTK_LIST(List)->children->data));  
           if (search_res[0].Line == 1)  
             msg = g_strdup_printf(_("Found one string (\"%s\")."),  
                SearchPrefs -> StringToSearch);  
           else  
             msg = g_strdup_printf (_("Found %d strings (\"%s\")."),  
                                    search_res[0].Line,  
                                    SearchPrefs -> StringToSearch);  
         }  
       print_msg (msg);  
       g_free (msg);  
       g_free (search_res);  
     }  
   else if (!strcmp (Data, "rep_all"))  
     {  
       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(Widget)))  
         {  
           SearchPrefs -> RepAll = TRUE;  
         }  
       else  
         {  
           SearchPrefs -> RepAll = FALSE;  
         }  
     }  
   else if (!strcmp (Data, "rep_all_buffers"))  
     {  
       if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(Widget)))  
         {  
           SearchPrefs -> RepAll = TRUE;  
         }  
       else  
         {  
           SearchPrefs -> RepAll = FALSE;  
         }  
     }  
   else if (!strcmp (Data, "replace"))  
     {  
       const gchar *ReplaceString;  
       gint SearchBegin, CurrentPage;  
541    
542        if (!OpenedFilesCnt)  void search_callback (GtkDialog *dialog, gint response, gpointer data)
543          {  {
544            print_msg(_("Cannot refer to file: you closed all files!"));          START_FCN
545            return;          
546          }          if (response == GTK_RESPONSE_ACCEPT)
547        SearchPrefs -> StringToSearch = gtk_entry_get_text          {
548          (GTK_ENTRY(SearchEntry));                        GtkWidget *widget;
549        if (!strlen(SearchPrefs -> StringToSearch))                  gint where;
550          return;                  gint page;
551        ReplaceString = gtk_entry_get_text (GTK_ENTRY(ReplaceEntry));                  gchar *pattern = NULL;
552        CurrentPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(MainNotebook));                  gchar *files = NULL;
553        if (SearchPrefs -> BeginCursorPos)                  gchar **expanded_files;
554        {                  gint i;
555          GtkTextBuffer *EditorBuffer;                  struct file_results output;
556          GtkTextIter current;                  GArray *array = g_array_new (FALSE, FALSE, sizeof (struct file_results));
557                            
558          EditorBuffer = gtk_text_view_get_buffer(                  widget = g_object_get_data (G_OBJECT (dialog), "text");
559                               GTK_TEXT_VIEW(FPROPS(CurrentPage, Text)));                  
560          gtk_text_buffer_get_iter_at_mark (EditorBuffer, &current,                  pattern = g_strdup (gtk_entry_get_text (GTK_ENTRY (widget)));
561                   gtk_text_buffer_get_insert (EditorBuffer));                  
562          SearchBegin = gtk_text_iter_get_offset(&current);                  where = 0;
563        }                  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
564        else                          g_object_get_data (G_OBJECT (dialog), "where_current"))))
565          SearchBegin = 0;                  {
566        if (SearchPrefs -> RepAllBuffers)                          where = 0;
567          {                  }
568            gchar *msg;                  else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
569            gint i;                          g_object_get_data (G_OBJECT (dialog), "where_all"))))
           gint rep_nb = 0;  
           for (i = 0; i < OpenedFilesCnt; i++)  
             {  
               rep_nb += replace_all (i,  
                                      SearchPrefs -> CaseSen,  
                                      SearchPrefs -> RegExp,  
                                      (i == CurrentPage) ? SearchBegin : 0,  
                                      SearchPrefs -> StringToSearch,  
                                      ReplaceString);  
             }  
           if (rep_nb == 0)  
             msg = g_strdup_printf  
               ("The string \"%s\" hasn't been found...",  
                SearchPrefs -> StringToSearch);  
           else if (rep_nb == 1)  
             msg = g_strdup_printf  
               ("The string \"%s\" has been replaced by \"%s\"...",  
                SearchPrefs -> StringToSearch, ReplaceString);  
           else  
             msg = g_strdup_printf  
               ("%d \"%s\" strings have been replaced by \"%s\"...",  
                rep_nb, SearchPrefs -> StringToSearch, ReplaceString);  
           print_msg (msg);  
           g_free (msg);  
         }  
       else if (SearchPrefs -> RepAll)  
         {  
           gchar *msg;  
           gint rep_nb;  
   
           rep_nb = replace_all (CurrentPage,  
                                 SearchPrefs -> CaseSen,  
                                 SearchPrefs -> RegExp,  
                                 SearchBegin,  
                                 SearchPrefs -> StringToSearch,  
                                 ReplaceString);  
           if (rep_nb == 0)  
             msg = g_strdup_printf  
               ("The string \"%s\" hasn't been found...",  
                SearchPrefs -> StringToSearch);  
           else if (rep_nb == 1)  
             msg = g_strdup_printf  
               ("The string \"%s\" has been replaced by \"%s\"...",  
                SearchPrefs -> StringToSearch, ReplaceString);  
           else  
             msg = g_strdup_printf  
               ("%d \"%s\" strings have been replaced by \"%s\"...",  
                rep_nb, SearchPrefs -> StringToSearch, ReplaceString);  
           print_msg (msg);  
           g_free (msg);  
         }  
       else  
         {  
           t_search_results *search_res;  
             
           search_res = find (CurrentPage,  
                              SearchPrefs -> CaseSen,  
                              SearchPrefs -> RegExp,  
                              SearchBegin,  
                              SearchPrefs -> StringToSearch);  
           if (search_res[0].Line)  
             {  
               GtkTextBuffer *EditorBuffer;  
               GtkTextIter start, end;  
               gchar *buffer;  
                 
               EditorBuffer = gtk_text_view_get_buffer(  
                              GTK_TEXT_VIEW(FPROPS(CurrentPage, Text)));  
               buffer = get_selection (EditorBuffer);  
               if (!g_ascii_strcasecmp (buffer, SearchPrefs -> StringToSearch))  
570                  {                  {
571                    replace_selection(FPROPS(CurrentPage, Buffer), ReplaceString);                          where = 1;
572                    print_msg ("Selection replaced...");                  }
573                  }                        else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
574                else                          g_object_get_data (G_OBJECT (dialog), "where_files"))))
575                  {                  {
576                    gtk_text_buffer_get_iter_at_offset(EditorBuffer,                          where = 2;
                     &start, search_res[1].Begin);  
                   gtk_text_buffer_get_iter_at_offset(EditorBuffer,  
                     &end, search_res[1].End);  
                   gtk_text_buffer_move_mark_by_name(EditorBuffer,  
                     "insert", &start);  
                   gtk_text_buffer_move_mark_by_name(EditorBuffer,  
                     "selection_bound", &end);  
577                  }                  }
578                g_free (buffer);                  
579              }                  switch (where)
580            else                  {
581              {                  case 0:
582                if (BEEP) gdk_beep ();                          page = gtk_notebook_get_current_page (GTK_NOTEBOOK (MainNotebook));
583                print_msg ("End of Search...");                          
584              }                          output = run_grep_on_text (pattern, page, 0);
585            g_free (search_res);                          if (output.results)
586          }                                  g_array_append_val (array, output);
587        gtk_entry_set_text (GTK_ENTRY(SearchEntry),                          
588                            SearchPrefs -> StringToSearch);                          break;
589        gtk_entry_set_text (GTK_ENTRY(ReplaceEntry), ReplaceString);                  case 1:
590      }                          for (i = 0; i < OpenedFilesCnt; i++)
591                            {
592                                    output = run_grep_on_text (pattern, i, 0);
593                                    if (output.results)
594                                            g_array_append_val (array, output);
595                            }
596                            
597                            break;
598                    case 2:
599                            widget = g_object_get_data (G_OBJECT (dialog), "files");
600                            files = g_strdup (gtk_entry_get_text (GTK_ENTRY (widget)));
601                            expanded_files = get_files_for_search (files, 0);
602                            
603                            for (i = 0; expanded_files[i]; i++)
604                            {
605                                    output = run_grep_on_file (pattern, expanded_files[i], 0);
606                                    if (output.results)
607                                            g_array_append_val (array, output);
608                            }
609                            
610                            g_strfreev (expanded_files);
611                            g_free (files);
612                            break;
613                    }
614                    
615                    display_search_results (array);
616                    
617                    for (i = 0; i < array->len; i++)
618                    {
619                            g_free (g_array_index (array, struct file_results, i).path);
620                            g_ptr_array_free (g_array_index (array, struct file_results, i).results, TRUE);
621                    }
622                    
623                    g_array_free (array, FALSE);
624            }
625            
626            gtk_widget_destroy (GTK_WIDGET (dialog));
627            
628            END_FCN
629  }  }
630    
   
631  /* Display a Search Dialog window */  /* Display a Search Dialog window */
632    
633  void search (gboolean Replace)  void search (void)
634  {  {
635    GtkWidget *SearchWindow;    static GtkWidget *SearchWindow = NULL;
636    GtkWidget *VBox1, *VBox2;    GtkWidget *main_vbox, *vbox, *hbox;
637    GtkWidget *Frame;    GtkWidget *widget, *radio1;
638    GtkWidget *ScrolledWindow;  
639    GtkWidget *Button;    if (SearchWindow)
640    GSList *Group;    {
641    gboolean homogenous = FALSE;          gtk_window_present (GTK_WINDOW (SearchWindow));
642            return;
643    if (SearchIsVisible) return;    }
644    SearchPrefs = g_malloc (sizeof(t_search_prefs));    
645    SearchPrefs -> BeginCursorPos = TRUE;    SearchWindow = gtk_dialog_new_with_buttons (
646    SearchPrefs -> CaseSen = FALSE;                  "Search",
647    SearchPrefs -> RegExp = FALSE;                  GTK_WINDOW (MainWindow),
648    SearchWindow = gtk_dialog_new ();                  GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
649    gtk_window_set_policy (GTK_WINDOW(SearchWindow), FALSE, FALSE, FALSE);                  GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
650    g_signal_connect (G_OBJECT(SearchWindow), "delete_event",                  GTK_STOCK_FIND, GTK_RESPONSE_ACCEPT,
651                        (GtkSignalFunc) search_window_not_visible, NULL);                  NULL);
652    g_signal_connect_swapped (G_OBJECT(SearchWindow), "delete_event",    gtk_widget_realize (SearchWindow);
653      gtk_window_set_resizable (GTK_WINDOW (SearchWindow), FALSE);
654      gdk_window_set_functions (SearchWindow->window, GDK_FUNC_MOVE | GDK_FUNC_MINIMIZE);
655      g_signal_connect_swapped (G_OBJECT(SearchWindow), "delete-event",
656                               (GtkSignalFunc) gtk_widget_destroy,                               (GtkSignalFunc) gtk_widget_destroy,
657                               G_OBJECT(SearchWindow));                               G_OBJECT(SearchWindow));
   g_signal_connect (G_OBJECT(SearchWindow), "destroy",  
                       (GtkSignalFunc) search_window_not_visible, NULL);  
658    g_signal_connect_swapped (G_OBJECT (SearchWindow), "destroy",    g_signal_connect_swapped (G_OBJECT (SearchWindow), "destroy",
659                               (GtkSignalFunc) gtk_widget_destroy,                               G_CALLBACK (g_nullify_pointer),
660                               G_OBJECT(SearchWindow));                               &SearchWindow);
661    if (Replace)    
662      {    main_vbox = gtk_vbox_new (FALSE, 12);
663        gtk_window_set_title (GTK_WINDOW(SearchWindow),    gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (SearchWindow)->vbox), 12);
664                              "Search and Replace Text");    gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 6);
665        SearchPrefs -> RepAll = FALSE;    gtk_container_set_border_width (GTK_CONTAINER (SearchWindow), 6);
666      }    gtk_container_add (GTK_CONTAINER (GTK_DIALOG (SearchWindow)->vbox), main_vbox);
667    else    
668      {    gtk_dialog_set_default_response (GTK_DIALOG (SearchWindow), GTK_RESPONSE_ACCEPT);
669        gtk_window_set_title (GTK_WINDOW(SearchWindow), "Search Text");    
670        homogenous = TRUE;    g_signal_connect (G_OBJECT (SearchWindow), "response", G_CALLBACK (search_callback), NULL);
671      }    
672    VBox1 = gtk_vbox_new (homogenous, 5);    hbox = gtk_hbox_new (FALSE, 12);
673    gtk_container_set_border_width (GTK_CONTAINER(VBox1), 10);    gtk_container_add (GTK_CONTAINER (main_vbox), hbox);
674    gtk_box_pack_start (GTK_BOX(GTK_DIALOG(SearchWindow) -> vbox),    
675                        VBox1, FALSE, FALSE, 0);    widget = gtk_label_new_with_mnemonic ("_Search for:");
676    Frame = gtk_frame_new ("Search");    gtk_container_add (GTK_CONTAINER (hbox), widget);
677    gtk_box_pack_start (GTK_BOX(VBox1), Frame, TRUE, TRUE, 0);    
678    VBox2 = gtk_vbox_new (FALSE, 5);    widget = gtk_entry_new ();
679    gtk_container_set_border_width (GTK_CONTAINER(VBox2), 5);    gtk_container_add (GTK_CONTAINER (hbox), widget);
680    gtk_container_add (GTK_CONTAINER(Frame), VBox2);    g_object_set_data (G_OBJECT (SearchWindow), "text", widget);
681    SearchEntry = gtk_entry_new ();    
682    gtk_entry_set_activates_default (GTK_ENTRY(SearchEntry), TRUE);    vbox = gtk_vbox_new (FALSE, 6);
683    gtk_box_pack_start (GTK_BOX(VBox2), SearchEntry, FALSE, FALSE, 0);    gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
684    Button = gtk_radio_button_new_with_mnemonic (NULL, "Start at cursor _position");    
685    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(Button), TRUE);    radio1 = gtk_radio_button_new_with_mnemonic (NULL, "Search in current _buffer");
686    g_signal_connect (G_OBJECT(Button), "toggled",    gtk_container_add (GTK_CONTAINER (vbox), radio1);
687                        (GtkSignalFunc)refresh_search, "cursor");    g_object_set_data (G_OBJECT (SearchWindow), "where_current", radio1);
688    gtk_box_pack_start (GTK_BOX(VBox2), Button, FALSE, FALSE, 0);    
689    Group = gtk_radio_button_group (GTK_RADIO_BUTTON(Button));    widget = gtk_radio_button_new_with_mnemonic_from_widget (
690    Button = gtk_radio_button_new_with_mnemonic          GTK_RADIO_BUTTON (radio1),
691      (Group, "Start at _beginning of the document");          "Search in _all open buffers");
692    g_signal_connect (G_OBJECT(Button), "toggled",    gtk_container_add (GTK_CONTAINER (vbox), widget);
693                        (GtkSignalFunc)refresh_search, "begin");    g_object_set_data (G_OBJECT (SearchWindow), "where_all", widget);
694    gtk_box_pack_start (GTK_BOX(VBox2), Button, FALSE, FALSE, 0);    
695    Button = gtk_check_button_new_with_mnemonic ("Case _sensitive");    hbox = gtk_hbox_new (FALSE, 12);
696    g_signal_connect (G_OBJECT(Button), "toggled",    gtk_container_add (GTK_CONTAINER (vbox), hbox);
697                        (GtkSignalFunc)refresh_search, "case_sen");    
698    gtk_box_pack_start (GTK_BOX(VBox2), Button, FALSE, FALSE, 0);    widget = gtk_radio_button_new_with_mnemonic_from_widget (
699              GTK_RADIO_BUTTON (radio1),
700  /* TODO: implement the regexp feature */          "Search in these _files: ");
701  /*  Button = gtk_check_button_new_with_label ("Regular expression search");    gtk_container_add (GTK_CONTAINER (hbox), widget);
702    g_signal_connect (G_OBJECT(Button), "toggled",    g_object_set_data (G_OBJECT (SearchWindow), "where_files", widget);
703                        (GtkSignalFunc)refresh_search, "reg_exp");    
704    gtk_box_pack_start (GTK_BOX(VBox2), Button, FALSE, FALSE, 0); */    widget = gtk_entry_new ();
705        gtk_container_add (GTK_CONTAINER (hbox), widget);
706    Button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);    g_object_set_data (G_OBJECT (SearchWindow), "files", widget);
707    g_signal_connect (G_OBJECT(Button), "clicked",    
708                        (GtkSignalFunc) search_window_not_visible, NULL);    widget = gtk_check_button_new_with_mnemonic ("Match c_ase");
709    g_signal_connect_swapped (G_OBJECT(Button), "clicked",    gtk_box_pack_start (GTK_BOX (main_vbox), widget, FALSE, FALSE, 0);
710                               (GtkSignalFunc) gtk_widget_destroy,    g_object_set_data (G_OBJECT (SearchWindow), "case", widget);
711                               G_OBJECT(SearchWindow));    
712    GTK_WIDGET_SET_FLAGS (Button, GTK_CAN_DEFAULT);    widget = gtk_check_button_new_with_mnemonic ("Match whole wor_d only");
713    gtk_box_pack_start (GTK_BOX(GTK_DIALOG(SearchWindow) -> action_area),    gtk_box_pack_start (GTK_BOX (main_vbox), widget, FALSE, FALSE, 0);
714                        Button, TRUE, TRUE, 0);    g_object_set_data (G_OBJECT (SearchWindow), "word", widget);
715      
716    if (Replace)    widget = gtk_check_button_new_with_mnemonic ("_Wrap around");
717      {    gtk_box_pack_start (GTK_BOX (main_vbox), widget, FALSE, FALSE, 0);
718        Frame = gtk_frame_new ("Replace");    g_object_set_data (G_OBJECT (SearchWindow), "wrap", widget);
719        gtk_box_pack_start (GTK_BOX(VBox1), Frame, TRUE, TRUE, 0);    
720        VBox2 = gtk_vbox_new (FALSE, 5);    widget = gtk_check_button_new_with_mnemonic ("Text is a _regular expression");
721        gtk_container_set_border_width (GTK_CONTAINER(VBox2), 5);    gtk_box_pack_start (GTK_BOX (main_vbox), widget, FALSE, FALSE, 0);
722        gtk_container_add (GTK_CONTAINER(Frame), VBox2);    g_object_set_data (G_OBJECT (SearchWindow), "regexp", widget);
723        ReplaceEntry = gtk_entry_new ();    
724        gtk_entry_set_activates_default (GTK_ENTRY(ReplaceEntry), TRUE);    widget = gtk_check_button_new_with_mnemonic ("Search s_ubdirectories");
725        gtk_box_pack_start (GTK_BOX(VBox2), ReplaceEntry, FALSE, FALSE, 0);    gtk_box_pack_start (GTK_BOX (main_vbox), widget, FALSE, FALSE, 0);
726        Button = gtk_check_button_new_with_mnemonic ("Replace _all");    g_object_set_data (G_OBJECT (SearchWindow), "subdirs", widget);
727        g_signal_connect (G_OBJECT(Button), "toggled",    
                           (GtkSignalFunc)refresh_search, "rep_all");  
       gtk_box_pack_start (GTK_BOX(VBox2), Button, FALSE, FALSE, 0);  
       Button = gtk_check_button_new_with_mnemonic ("Replace all in _every buffer");  
       gtk_signal_connect (GTK_OBJECT(Button), "toggled",  
                           (GtkSignalFunc)refresh_search, "rep_all_buffers");  
       gtk_box_pack_start (GTK_BOX(VBox2), Button, FALSE, FALSE, 0);  
       Button = gtk_button_new_from_stock (GTK_STOCK_FIND_AND_REPLACE);  
 //      gtk_button_set_label (GTK_BUTTON (Button), "Replace");  
       g_signal_connect (G_OBJECT(Button), "clicked",  
                           (GtkSignalFunc)refresh_search, "replace");  
       print_msg ("Display Search and Replace window...");  
     }  
   else  
     {  
       Frame = gtk_frame_new ("Results");  
       gtk_box_pack_start (GTK_BOX(VBox1), Frame, TRUE, TRUE, 0);  
       VBox2 = gtk_vbox_new (FALSE, 5);  
       gtk_container_set_border_width (GTK_CONTAINER(VBox2), 5);  
       gtk_container_add (GTK_CONTAINER(Frame), VBox2);  
       ScrolledWindow = gtk_scrolled_window_new (NULL, NULL);  
       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(ScrolledWindow),  
                                       GTK_POLICY_AUTOMATIC,  
                                       GTK_POLICY_AUTOMATIC);  
       gtk_box_pack_start (GTK_BOX(VBox2), ScrolledWindow, TRUE, TRUE, 0);  
       List = gtk_list_new ();  
       gtk_list_set_selection_mode (GTK_LIST(List), GTK_SELECTION_BROWSE);  
       g_signal_connect (G_OBJECT(List), "select_child",  
                           (GtkSignalFunc)goto_search, NULL);  
       gtk_scrolled_window_add_with_viewport  
         (GTK_SCROLLED_WINDOW(ScrolledWindow), List);  
       gtk_container_set_focus_vadjustment  
         (GTK_CONTAINER (List),  
          gtk_scrolled_window_get_vadjustment  
          (GTK_SCROLLED_WINDOW (ScrolledWindow)));  
       gtk_container_set_focus_hadjustment  
         (GTK_CONTAINER (List),  
          gtk_scrolled_window_get_hadjustment  
          (GTK_SCROLLED_WINDOW (ScrolledWindow)));  
       Button = gtk_button_new_from_stock (GTK_STOCK_FIND);  
       g_signal_connect (G_OBJECT(Button), "clicked",  
                           (GtkSignalFunc)refresh_search, "search");  
       print_msg ("Display Search window...");  
     }  
   GTK_WIDGET_SET_FLAGS (Button, GTK_CAN_DEFAULT);  
   gtk_box_pack_start (GTK_BOX(GTK_DIALOG(SearchWindow) -> action_area),  
                       Button, TRUE, TRUE, 0);  
   gtk_widget_grab_default (Button);  
728    gtk_widget_show_all (SearchWindow);    gtk_widget_show_all (SearchWindow);
   SearchIsVisible = TRUE;  
729  }  }
730    
731  void show_on_screen (GtkTextView *Text, GtkTextIter start)  void show_on_screen (GtkTextView *Text, GtkTextIter start)

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26