1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 ** search-replace.c: Generic Search and Replace
5 ** Author: Biswapesh Chattopadhyay
21 #include <sys/types.h>
25 #include <glade/glade.h>
27 #include <libanjuta/anjuta-utils.h>
28 #include <libanjuta/anjuta-plugin.h>
29 #include <libanjuta/anjuta-debug.h>
30 #include <libanjuta/interfaces/ianjuta-message-manager.h>
31 #include <libanjuta/interfaces/ianjuta-message-view.h>
32 #include <libanjuta/interfaces/ianjuta-editor.h>
33 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
34 #include <libanjuta/interfaces/ianjuta-markable.h>
35 #include <libanjuta/interfaces/ianjuta-bookmark.h>
36 #include <libanjuta/interfaces/ianjuta-indicable.h>
38 #include <libegg/menu/egg-entry-action.h>
40 #include "search-replace_backend.h"
41 #include "search-replace.h"
42 #include "search_preferences.h"
44 #include <libanjuta/interfaces/ianjuta-project-manager.h>
45 #include <glib/gi18n.h>
47 #define GLADE_FILE_SEARCH_REPLACE PACKAGE_DATA_DIR"/glade/anjuta-search.glade"
49 /* LibGlade's auto-signal-connect will connect to these signals.
50 * Do not declare them static.
53 on_search_dialog_key_press_event(GtkWidget
*widget
, GdkEventKey
*event
,
55 void on_search_match_whole_word_toggled (GtkToggleButton
*togglebutton
,
57 void on_search_match_whole_line_toggled (GtkToggleButton
*togglebutton
,
59 void on_search_match_word_start_toggled (GtkToggleButton
*togglebutton
,
61 gboolean
on_search_replace_delete_event(GtkWidget
*window
, GdkEvent
*event
,
63 void on_replace_regex_toggled (GtkToggleButton
*togglebutton
, gpointer user_data
);
64 void on_search_regex_toggled (GtkToggleButton
*togglebutton
, gpointer user_data
);
65 void on_search_action_changed (GtkComboBox
*combo
, gpointer user_data
);
66 void on_search_target_changed(GtkComboBox
*combo
, gpointer user_data
);
67 void on_search_expression_changed(GtkComboBox
*combo
, gpointer user_data
);
68 void on_actions_no_limit_clicked(GtkButton
*button
, gpointer user_data
);
69 void on_search_button_close_clicked(GtkButton
*button
, gpointer user_data
);
70 void on_search_button_close_clicked(GtkButton
*button
, gpointer user_data
);
71 void on_search_button_help_clicked(GtkButton
*button
, gpointer user_data
);
72 void on_search_button_next_clicked(GtkButton
*button
, gpointer user_data
);
73 void on_search_button_jump_clicked(GtkButton
*button
, gpointer user_data
);
74 void on_search_expression_activate (GtkEditable
*edit
, gpointer user_data
);
75 void on_search_button_save_clicked(GtkButton
*button
, gpointer user_data
);
76 void on_search_button_stop_clicked(GtkButton
*button
, gpointer user_data
);
78 void on_search_direction_changed (GtkComboBox
*combo
, gpointer user_data
);
79 void on_search_full_buffer_toggled (GtkToggleButton
*togglebutton
,
81 void on_search_forward_toggled (GtkToggleButton
*togglebutton
,
83 void on_search_backward_toggled (GtkToggleButton
*togglebutton
,
85 void on_setting_basic_search_toggled (GtkToggleButton
*togglebutton
,
88 /* GUI dropdown option strings */
89 AnjutaUtilStringMap search_direction_strings
[] = {
90 /* the order of these matters - it must match the order of the corresponding
91 radio buttons on another page */
92 {SD_BEGINNING
, N_("Full Buffer")},
93 {SD_FORWARD
, N_("Forward")},
94 {SD_BACKWARD
, N_("Backward")},
98 AnjutaUtilStringMap search_target_strings
[] = {
99 {SR_BUFFER
, N_("Current Buffer")},
100 {SR_SELECTION
, N_("Current Selection")},
101 {SR_BLOCK
, N_("Current Block")},
102 {SR_FUNCTION
, N_("Current Function")},
103 {SR_OPEN_BUFFERS
, N_("All Open Buffers")},
104 {SR_PROJECT
, N_("All Project Files")},
105 /* {SR_VARIABLE, N_("Specify File List")},*/
106 {SR_FILES
, N_("Specify File Patterns")},
110 AnjutaUtilStringMap search_action_strings
[] = {
111 {SA_SELECT
, N_("Select next match")},
112 {SA_BOOKMARK
, N_("Bookmark all matched lines")},
113 {SA_HIGHLIGHT
, N_("Mark all matches")},
114 {SA_FIND_PANE
, N_("List matches in find pane")},
115 {SA_REPLACE
, N_("Replace next match")},
116 {SA_REPLACEALL
, N_("Replace all matches")},
121 typedef struct _SearchReplaceGUI
129 static GladeWidget glade_widgets
[] = {
131 {GE_BUTTON
, "button.close", NULL
, NULL
},
133 {GE_BUTTON
, "button.stop", NULL
, NULL
},
135 {GE_BUTTON
, "button.next", NULL
, NULL
},
137 {GE_BUTTON
, "button.jump", NULL
, NULL
},
138 /* SEARCH_NOTEBOOK */
139 {GE_NONE
, "search.notebook", NULL
, NULL
},
140 /* SEARCH_EXPR_FRAME */
141 {GE_NONE
, "frame.search.expression", NULL
, NULL
},
142 /* SEARCH_TARGET_FRAME */
143 {GE_NONE
, "frame.search.target", NULL
, NULL
},
144 /* SEARCH_VAR_FRAME */
145 {GE_NONE
, "frame.search.var", NULL
, NULL
},
146 /* FILE_FILTER_FRAME */
147 {GE_NONE
, "frame.file.filter", NULL
, NULL
},
148 /* FRAME_SEARCH_BASIC */
149 {GE_NONE
, "frame.search.basic", NULL
, NULL
},
151 {GE_NONE
, "label.replace", NULL
, NULL
},
153 {GE_COMBO_ENTRY
, "search.string.combo", NULL
, NULL
},
155 {GE_COMBO_ENTRY
, "search.var.combo", NULL
, NULL
},
157 {GE_COMBO_ENTRY
, "file.filter.match.combo", NULL
, NULL
},
159 {GE_COMBO_ENTRY
, "file.filter.unmatch.combo", NULL
, NULL
},
161 {GE_COMBO_ENTRY
, "dir.filter.match.combo", NULL
, NULL
},
163 {GE_COMBO_ENTRY
, "dir.filter.unmatch.combo", NULL
, NULL
},
165 {GE_COMBO_ENTRY
, "replace.string.combo", NULL
, NULL
},
167 {GE_TEXT
, "actions.max", NULL
, NULL
},
168 /* SETTING_PREF_ENTRY */
169 {GE_TEXT
, "setting.pref.entry", NULL
, NULL
},
171 {GE_BOOLEAN
, "search.regex", NULL
, NULL
},
173 {GE_BOOLEAN
, "search.greedy", NULL
, NULL
},
175 {GE_BOOLEAN
, "search.ignore.case", NULL
, NULL
},
177 {GE_BOOLEAN
, "search.match.whole.word", NULL
, NULL
},
179 {GE_BOOLEAN
, "search.match.word.start", NULL
, NULL
},
181 {GE_BOOLEAN
, "search.match.whole.line", NULL
, NULL
},
182 /* IGNORE_HIDDEN_FILES */
183 {GE_BOOLEAN
, "ignore.hidden.files", NULL
, NULL
},
184 /* IGNORE_BINARY_FILES */
185 {GE_BOOLEAN
, "ignore.binary.files", NULL
, NULL
},
186 /* IGNORE_HIDDEN_DIRS */
187 {GE_BOOLEAN
, "ignore.hidden.dirs", NULL
, NULL
},
188 /* SEARCH_RECURSIVE */
189 {GE_BOOLEAN
, "search.dir.recursive", NULL
, NULL
},
191 {GE_BOOLEAN
, "replace.regex", NULL
, NULL
},
192 /* ACTIONS_NO_LIMIT */
193 {GE_BOOLEAN
, "actions.no_limit", NULL
, NULL
},
194 /* SEARCH_FULL_BUFFER */
195 {GE_BOOLEAN
, "search.full_buffer", NULL
, NULL
},
197 {GE_BOOLEAN
, "search.forward", NULL
, NULL
},
198 /* SEARCH_BACKWARD */
199 {GE_BOOLEAN
, "search.backward", NULL
, NULL
},
201 {GE_BOOLEAN
, "search.basic", NULL
, NULL
},
202 /* SEARCH_STRING_COMBO */
203 {GE_COMBO
, "search.string.combo", NULL
, NULL
},
204 /* SEARCH_TARGET_COMBO */
205 {GE_COMBO
, "search.target.combo", search_target_strings
, NULL
},
206 /* SEARCH_ACTION_COMBO */
207 {GE_COMBO
, "search.action.combo", search_action_strings
, NULL
},
208 /* SEARCH_VAR_COMBO */
209 {GE_COMBO
, "search.var.combo", NULL
, NULL
},
210 /* MATCH_FILES_COMBO */
211 {GE_COMBO
, "file.filter.match.combo", NULL
, NULL
},
212 /* UNMATCH_FILES_COMBO */
213 {GE_COMBO
, "file.filter.unmatch.combo", NULL
, NULL
},
214 /* MATCH_DIRS_COMBO */
215 {GE_COMBO
, "dir.filter.match.combo", NULL
, NULL
},
216 /* UNMATCH_DIRS_COMBO */
217 {GE_COMBO
, "dir.filter.unmatch.combo", NULL
, NULL
},
218 /* REPLACE_STRING_COMBO */
219 {GE_COMBO
, "replace.string.combo", NULL
, NULL
},
220 /* SEARCH_DIRECTION_COMBO */
221 {GE_COMBO
, "search.direction.combo", search_direction_strings
, NULL
},
222 /* SETTING_PREF_TREEVIEW */
223 {GE_NONE
, "setting.pref.treeview", NULL
, NULL
},
224 {GE_NONE
, NULL
, NULL
, NULL
}
227 /***********************************************************/
230 write_message_pane(IAnjutaMessageView
* view
, FileBuffer
*fb
, SearchEntry
*se
, MatchInfo
*mi
);
231 static gboolean
on_message_clicked (GObject
* object
, gchar
* message
, gpointer data
);
232 static void on_message_buffer_flush (IAnjutaMessageView
*view
, const gchar
*one_line
, gpointer data
);
233 static void save_not_opened_files(FileBuffer
*fb
);
234 static gboolean
replace_in_not_opened_files(FileBuffer
*fb
, MatchInfo
*mi
, gchar
*repl_str
);
235 static void search_set_action(SearchAction action
);
236 static void search_set_target(SearchRangeType target
);
237 static void search_set_direction(SearchDirection dir
);
238 static void populate_value(GladeWidgetId id
, gpointer val_ptr
);
239 static void reset_flags(void);
240 static void reset_flags_and_search_button (void);
241 static void search_start_over (SearchDirection direction
);
242 static void search_end_alert (gchar
*string
);
243 static void max_results_alert (void);
244 static void nb_results_alert (gint nb
);
245 static void search_show_replace(gboolean hide
);
246 static void modify_label_image_button(GladeWidgetId button_name
, gchar
*name
, char *stock_image
);
247 static void show_jump_button (gboolean show
);
248 static gboolean
create_dialog(void);
249 static void show_dialog(void);
250 static gboolean
word_in_list(GList
*list
, gchar
*word
);
251 static GList
* list_max_items(GList
*list
, guint nb_max
);
252 static void search_update_combos (void);
253 static void replace_update_combos (void);
254 static void search_direction_changed(SearchDirection dir
);
255 static void search_set_direction(SearchDirection dir
);
256 static void search_set_toggle_direction(SearchDirection dir
);
257 static void search_disconnect_set_toggle_connect(GladeWidgetId id
,
258 GCallback function
, gboolean active
);
259 static void search_replace_next_previous(SearchDirection dir
);
260 static void basic_search_toggled(void);
262 static SearchReplaceGUI
*sg
= NULL
;
264 static SearchReplace
*sr
= NULL
;
266 static gboolean flag_select
= FALSE
;
267 static gboolean interactive
= FALSE
;
268 static gboolean end_activity
= FALSE
;
269 static gboolean labels_translated
= FALSE
;
271 /***********************************************************/
274 search_and_replace_init (IAnjutaDocumentManager
*dm
)
276 sr
= create_search_replace_instance (dm
);
280 search_and_replace (void)
286 static MatchInfo
*mi
;
292 static long start_sel
= 0;
293 static long end_sel
= 0;
294 static gchar
*ch
= NULL
;
296 gboolean save_file
= FALSE
;
297 IAnjutaMessageManager
* msgman
;
298 IAnjutaMessageView
* view
= NULL
;
301 g_return_if_fail(sr
);
304 if (s
->expr
.search_str
== NULL
)
307 entries
= create_search_entries(s
);
311 end_activity
= FALSE
;
312 backward
= (s
->range
.direction
== SD_BACKWARD
);
314 search_update_combos ();
315 if (s
->action
== SA_REPLACE
|| s
->action
== SA_REPLACEALL
)
316 replace_update_combos ();
318 if (SA_FIND_PANE
== s
->action
)
320 gchar
* name
= g_strconcat(_("Find: "), s
->expr
.search_str
, NULL
);
322 g_object_get(G_OBJECT(sr
->docman
), "shell", &shell
, NULL
);
323 msgman
= anjuta_shell_get_interface(shell
,
324 IAnjutaMessageManager
, NULL
);
325 g_return_if_fail(msgman
!= NULL
);
327 view
= ianjuta_message_manager_get_view_by_name(msgman
, name
, NULL
);
330 // FIXME: Put a nice icon here:
331 view
= ianjuta_message_manager_add_view(msgman
, name
,
332 GTK_STOCK_FIND_AND_REPLACE
, NULL
);
333 g_return_if_fail(view
!= NULL
);
334 g_signal_connect (G_OBJECT(view
), "buffer_flushed",
335 G_CALLBACK (on_message_buffer_flush
), NULL
);
336 g_signal_connect (G_OBJECT(view
), "message_clicked",
337 G_CALLBACK (on_message_clicked
), NULL
);
340 ianjuta_message_view_clear(view
, NULL
);
341 ianjuta_message_manager_set_current_view(msgman
, view
, NULL
);
343 gtk_widget_set_sensitive (sr_get_gladewidget(STOP_BUTTON
)->widget
, TRUE
);
345 for (tmp
= entries
; tmp
&& (nb_results
<= s
->expr
.actions_max
);
346 tmp
= g_list_next(tmp
))
350 while(gtk_events_pending())
351 gtk_main_iteration();
353 /*to eliminate un-needed moves, when not bookmarking, this could be
354 current line i.e. ianjuta_editor_get_lineno (IANJUTA_EDITOR (se->te), NULL);
355 or sometimes last-line ? */
356 found_line
= (s
->action
== SA_BOOKMARK
) ? -1 : 1;
358 se
= (SearchEntry
*) tmp
->data
;
361 se
->start_pos
= start_sel
;
362 se
->end_pos
= end_sel
;
365 end_sel
= se
->end_pos
;
366 if (SE_BUFFER
== se
->type
)
367 fb
= file_buffer_new_from_te(se
->te
);
368 else /* if (SE_FILE == se->type) */
369 fb
= file_buffer_new_from_path(se
->path
, NULL
, -1, 0);
373 fb
->pos
= se
->start_pos
;
375 /* NO - there's no reason for user to expect existing marks to be removed.
376 And that can easily be done manually by user if so desired.
377 if (s->action == SA_BOOKMARK && IANJUTA_IS_MARKABLE (fb->te))
378 ianjuta_markable_delete_all_markers(IANJUTA_MARKABLE(fb->te),
379 IANJUTA_MARKABLE_LINEMARKER, NULL);
381 //FIXME enable clearing of marks by some means other than a 0-match search
382 if (s
->action
== SA_HIGHLIGHT
)
383 ianjuta_indicable_clear (IANJUTA_INDICABLE(fb
->te
), NULL
);
385 while (interactive
||
386 NULL
!= (mi
= get_next_match(fb
, s
->range
.direction
, &(s
->expr
))))
388 if ((s
->range
.direction
== SD_BACKWARD
) && (mi
->pos
< se
->end_pos
))
390 if ((s
->range
.direction
!= SD_BACKWARD
) && ((se
->end_pos
!= -1) &&
391 (mi
->pos
+mi
->len
> se
->end_pos
)))
394 if (nb_results
> sr
->search
.expr
.actions_max
)
397 /* NOTE - mi->line is "editor-style" 1-based, but some things
398 here use/expect 0-base, so adjustments are made as needed */
403 found_line
= mi
->line
;
407 IANJUTA_EDITOR (ianjuta_document_manager_get_current_document
410 if (IANJUTA_INDICABLE (fb
->te
))
411 /* end-location is correct for sourceview, 1-too-big for scintilla */
412 ianjuta_indicable_set (IANJUTA_INDICABLE(fb
->te
),
413 mi
->pos
, mi
->pos
+ mi
->len
,
414 IANJUTA_INDICABLE_IMPORTANT
, NULL
);
418 if (found_line
!= mi
->line
)
420 found_line
= mi
->line
;
424 IANJUTA_EDITOR (ianjuta_document_manager_get_current_document
427 if (IANJUTA_IS_MARKABLE (fb
->te
) &&
428 !ianjuta_markable_is_marker_set (
429 IANJUTA_MARKABLE(fb
->te
),
431 IANJUTA_MARKABLE_BOOKMARK
,
434 ianjuta_bookmark_toggle (IANJUTA_BOOKMARK(fb
->te
),
435 mi
->line
, FALSE
, NULL
);
441 if (found_line
!= mi
->line
|| fb
->te
== NULL
)
444 ianjuta_editor_goto_line (fb
->te
, mi
->line
, NULL
);
446 fb
->te
= ianjuta_document_manager_goto_file_line_mark
447 (sr
->docman
, fb
->path
, mi
->line
, FALSE
, NULL
);
448 found_line
= mi
->line
;
451 IAnjutaIterable
* start
= ianjuta_editor_get_cell_iter (fb
->te
, mi
->pos
, NULL
);
452 IAnjutaIterable
* end
= ianjuta_editor_get_cell_iter (fb
->te
, mi
->pos
+ mi
->len
, NULL
);
453 ianjuta_editor_selection_set(IANJUTA_EDITOR_SELECTION (fb
->te
),
457 g_object_unref (start
);
458 g_object_unref (end
);
463 write_message_pane(view
, fb
, se
, mi
);
467 if (found_line
!= mi
->line
|| fb
->te
== NULL
)
470 ianjuta_editor_goto_line (fb
->te
, mi
->line
, NULL
);
472 fb
->te
= ianjuta_document_manager_goto_file_line_mark
473 (sr
->docman
, fb
->path
, mi
->line
, FALSE
, NULL
);
474 found_line
= mi
->line
;
479 IAnjutaIterable
* start
= ianjuta_editor_get_cell_iter (fb
->te
, mi
->pos
- offset
, NULL
);
480 IAnjutaIterable
* end
= ianjuta_editor_get_cell_iter (fb
->te
, mi
->pos
- offset
+ mi
->len
, NULL
);
481 ianjuta_editor_selection_set(IANJUTA_EDITOR_SELECTION (fb
->te
),
485 g_object_unref (start
);
486 g_object_unref (end
);
489 modify_label_image_button(SEARCH_BUTTON
, _("Replace"),
490 GTK_STOCK_FIND_AND_REPLACE
);
491 show_jump_button(TRUE
);
492 if (sr
->replace
.regex
&& sr
->search
.expr
.regex
)
495 ch
= regex_backref (mi
, fb
);
500 if (ch
&& sr
->replace
.regex
&& sr
->search
.expr
.regex
)
502 g_free (sr
->replace
.repl_str
);
503 sr
->replace
.repl_str
= g_strdup (ch
);
508 IAnjutaIterable
* start
= ianjuta_editor_get_cell_iter (fb
->te
, mi
->pos
- os
, NULL
);
509 IAnjutaIterable
* end
= ianjuta_editor_get_cell_iter (fb
->te
, mi
->pos
+ mi
->len
- os
, NULL
);
510 ianjuta_editor_selection_set(IANJUTA_EDITOR_SELECTION (fb
->te
),
514 ianjuta_editor_selection_replace(IANJUTA_EDITOR_SELECTION (fb
->te
),
515 sr
->replace
.repl_str
,
516 strlen(sr
->replace
.repl_str
),
518 g_object_unref (start
);
519 g_object_unref (end
);
521 if (se
->direction
!= SD_BACKWARD
)
522 offset
+= mi
->len
- (sr
->replace
.repl_str
?strlen(sr
->replace
.repl_str
):0);
529 if (sr
->replace
.regex
&& sr
->search
.expr
.regex
)
531 regx_pattern
= sr
->replace
.repl_str
; /* preserve for later matches */
532 sr
->replace
.repl_str
= regex_backref (mi
, fb
);
536 if (fb
->te
== NULL
) /* NON OPENED FILES */
538 if (replace_in_not_opened_files(fb
, mi
, sr
->replace
.repl_str
))
543 IAnjutaIterable
* start
= ianjuta_editor_get_cell_iter (fb
->te
, mi
->pos
- offset
, NULL
);
544 IAnjutaIterable
* end
= ianjuta_editor_get_cell_iter (fb
->te
, mi
->pos
+ mi
->len
- offset
, NULL
);
545 ianjuta_editor_selection_set(IANJUTA_EDITOR_SELECTION (fb
->te
),
549 ianjuta_editor_selection_replace(IANJUTA_EDITOR_SELECTION (fb
->te
),
550 sr
->replace
.repl_str
,
551 strlen(sr
->replace
.repl_str
),
553 g_object_unref (start
);
554 g_object_unref (end
);
556 if (se
->direction
!= SD_BACKWARD
)
557 offset
+= mi
->len
- (sr
->replace
.repl_str
?strlen(sr
->replace
.repl_str
):0);
560 g_free (sr
->replace
.repl_str
);
561 sr
->replace
.repl_str
= regx_pattern
;
566 g_warning ("Not implemented - File %s - Line %d\n", __FILE__
, __LINE__
);
570 if (se
->direction
!= SD_BACKWARD
)
571 start_sel
= mi
->pos
+ mi
->len
- offset
;
573 start_sel
= mi
->pos
- offset
;
575 if (SA_REPLACE
!= s
->action
|| !interactive
)
578 if (SA_SELECT
== s
->action
||
579 ((SA_REPLACE
== s
->action
|| SA_REPLACEALL
== s
->action
) && interactive
))
582 /* NO - leave the current position unchanged when marking-all
589 ianjuta_editor_goto_line (fb->te, found_line, NULL);
597 save_not_opened_files (fb
);
601 file_buffer_free (fb
);
607 if (SA_SELECT
== s
->action
&& nb_results
> 0)
611 gtk_widget_set_sensitive (sr_get_gladewidget(STOP_BUTTON
)->widget
, FALSE
);
613 if (s
->range
.type
== SR_BLOCK
|| s
->range
.type
== SR_FUNCTION
||
614 s
->range
.type
== SR_SELECTION
)
618 g_list_free (entries
);
620 if (s
->action
== SA_FIND_PANE
)
622 ianjuta_message_view_append (view
, IANJUTA_MESSAGE_VIEW_TYPE_INFO
,
623 _("Search complete"), "", NULL
);
628 search_end_alert(sr
->search
.expr
.search_str
);
630 else if (nb_results
> sr
->search
.expr
.actions_max
)
632 else if (s
->action
== SA_REPLACEALL
)
633 nb_results_alert(nb_results
);
635 if ((s
->range
.direction
== SD_BEGINNING
) &&
636 ((s
->action
== SA_SELECT
) || (s
->action
== SA_REPLACE
)) )
638 search_set_direction(SD_FORWARD
);
643 write_message_pane(IAnjutaMessageView
* view
, FileBuffer
*fb
, SearchEntry
*se
,
650 match_line
= file_match_line_from_pos(fb
, mi
->pos
);
652 if (SE_BUFFER
== se
->type
)
654 /* DEBUG_PRINT ("FBPATH %s\n", fb->path); */
655 const gchar
* filename
= ianjuta_document_get_filename(IANJUTA_DOCUMENT(se
->te
), NULL
);
656 tmp
= g_strrstr(fb
->path
, "/");
657 tmp
= g_strndup(fb
->path
, tmp
+ 1 -(fb
->path
));
658 snprintf(buf
, BUFSIZ
, "%s%s:%d:%s\n", tmp
, filename
,
659 mi
->line
, match_line
);
662 else /* if (SE_FILE == se->type) */
664 snprintf(buf
, BUFSIZ
, "%s:%d:%s\n", se
->path
, mi
->line
+ 1, match_line
);
667 ianjuta_message_view_buffer_append (view
, buf
, NULL
);
671 on_message_buffer_flush (IAnjutaMessageView
*view
, const gchar
*one_line
,
674 ianjuta_message_view_append (view
, IANJUTA_MESSAGE_VIEW_TYPE_NORMAL
,
679 on_message_clicked (GObject
* object
, gchar
* message
, gpointer data
)
685 if (!(ptr
= g_strstr_len(message
, strlen(message
), ":")) )
687 path
= g_strndup(message
, ptr
- message
);
690 if (!(ptr2
= g_strstr_len(ptr
, strlen(ptr
), ":")) )
692 nline
= g_strndup(ptr
, ptr2
- ptr
);
695 ianjuta_document_manager_goto_file_line_mark (sr
->docman
, path
, line
, TRUE
, NULL
);
702 save_not_opened_files(FileBuffer
*fb
)
706 fp
= fopen(fb
->path
, "wb");
709 fwrite(fb
->buf
, fb
->len
, 1, fp
);
714 replace_in_not_opened_files(FileBuffer
*fb
, MatchInfo
*mi
, gchar
*repl_str
)
717 g_return_val_if_fail (repl_str
!= NULL
, FALSE
);
719 if (strlen(repl_str
) > mi
->len
)
721 l
= fb
->len
- mi
->pos
;
722 fb
->len
= fb
->len
+ strlen(repl_str
) - mi
->len
;
723 if ( (fb
->buf
= g_realloc(fb
->buf
, fb
->len
)) == NULL
)
725 memmove((fb
->buf
) + mi
->pos
+ strlen(repl_str
) - mi
->len
, fb
->buf
+ mi
->pos
,l
);
727 if (strlen(repl_str
) < mi
->len
)
729 l
= fb
->len
- mi
->pos
- mi
->len
;
730 memmove((fb
->buf
) + mi
->pos
+ strlen(repl_str
), fb
->buf
+ mi
->pos
+ mi
->len
,l
);
731 fb
->len
= fb
->len
+ strlen(repl_str
) - mi
->len
;
732 if ( (fb
->buf
= g_realloc(fb
->buf
, fb
->len
)) == NULL
)
736 for (l
=0; l
< strlen(repl_str
); l
++)
737 (fb
->buf
)[(mi
->pos
)+l
] = repl_str
[l
];
744 search_replace_next_previous(SearchDirection dir
)
746 SearchDirection save_direction
;
747 SearchAction save_action
;
748 SearchRangeType save_type
;
752 save_action
= sr
->search
.action
;
753 save_type
= sr
->search
.range
.type
;
754 save_direction
= sr
->search
.range
.direction
;
755 sr
->search
.range
.direction
= dir
;
756 if (save_type
== SR_OPEN_BUFFERS
|| save_type
== SR_PROJECT
||
757 save_type
== SR_FILES
)
758 sr
->search
.range
.direction
= SR_BUFFER
;
759 sr
->search
.action
= SA_SELECT
;
761 search_and_replace();
763 sr
->search
.action
= save_action
;
764 sr
->search
.range
.type
= save_type
;
765 sr
->search
.range
.direction
= save_direction
;
769 DEBUG_PRINT ("sr null\n");
774 search_replace_next(void)
776 search_replace_next_previous(SD_FORWARD
);
780 search_replace_previous(void)
782 search_replace_next_previous(SD_BACKWARD
);
785 /****************************************************************/
788 sr_get_gladewidget(GladeWidgetId id
)
790 return &glade_widgets
[id
];
794 search_set_popdown_strings (GtkComboBoxEntry
*combo
, GList
* strings
)
799 init
= gtk_combo_box_get_model (GTK_COMBO_BOX(combo
)) == NULL
;
801 store
= gtk_list_store_new (1, G_TYPE_STRING
);
802 for (; strings
!= NULL
; strings
= g_list_next(strings
))
806 gtk_list_store_append (store
, &iter
);
807 gtk_list_store_set (store
, &iter
, 0, strings
->data
, -1);
809 gtk_combo_box_set_model (GTK_COMBO_BOX(combo
), GTK_TREE_MODEL (store
));
810 g_object_unref (store
);
812 if (init
) gtk_combo_box_entry_set_text_column (combo
, 0);
816 search_set_popdown_map (GtkComboBox
*combo
, AnjutaUtilStringMap
*map
)
822 init
= gtk_combo_box_get_model (combo
) == NULL
;
824 store
= gtk_list_store_new (2, G_TYPE_STRING
, G_TYPE_INT
);
825 for (i
= 0; map
[i
].type
!= -1; ++i
)
829 gtk_list_store_append (store
, &iter
);
830 gtk_list_store_set (store
, &iter
, 0, map
[i
].name
, 1, map
[i
].type
, -1);
832 gtk_combo_box_set_model (combo
, GTK_TREE_MODEL (store
));
833 g_object_unref (store
);
834 gtk_combo_box_set_active (combo
, 0);
838 GtkCellRenderer
*cell
;
840 cell
= gtk_cell_renderer_text_new ();
841 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo
), cell
, TRUE
);
842 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo
), cell
,
848 search_select_item(GtkComboBox
* combo
, gint item
)
854 model
= gtk_combo_box_get_model(combo
);
856 /* Find item corresponding to command */
857 for (search
= gtk_tree_model_get_iter_first(model
, &iter
); search
;
858 gtk_tree_model_iter_next (model
, &iter
))
862 gtk_tree_model_get (model
, &iter
, 1, &id
, -1);
867 gtk_combo_box_set_active_iter(combo
, &iter
);
875 search_set_combo(GladeWidgetId id_combo
, gint command
)
879 combo
= GTK_COMBO_BOX(sr_get_gladewidget(id_combo
)->widget
);
880 search_select_item (combo
, command
);
884 search_set_action(SearchAction action
)
886 search_set_combo(SEARCH_ACTION_COMBO
, action
);
890 search_set_target(SearchRangeType target
)
892 search_set_combo(SEARCH_TARGET_COMBO
, target
);
896 search_set_direction(SearchDirection dir
)
898 search_set_combo(SEARCH_DIRECTION_COMBO
, dir
);
902 search_get_item_combo(GtkComboBox
*combo
)
909 sel
= gtk_combo_box_get_active_iter (combo
, &iter
);
910 model
= gtk_combo_box_get_model (combo
);
911 gtk_tree_model_get (model
, &iter
, 1, &item
, -1);
917 search_get_item_combo_name(GladeWidgetId id
)
919 GtkWidget
*combo
= sr_get_gladewidget(id
)->widget
;
920 return search_get_item_combo(GTK_COMBO_BOX(combo
));
924 search_direction_changed(SearchDirection dir
)
929 tgt
= search_get_item_combo_name(SEARCH_TARGET_COMBO
);
930 if (dir
!= SD_BEGINNING
)
932 if (tgt
== SR_OPEN_BUFFERS
|| tgt
== SR_PROJECT
934 search_set_target(SR_BUFFER
);
938 if (tgt
== SR_BUFFER
||tgt
== SR_SELECTION
|| tgt
== SR_BLOCK
||
940 search_set_target(SR_BUFFER
);
943 act
= search_get_item_combo_name(SEARCH_ACTION_COMBO
);
944 if (act
== SA_SELECT
)
945 search_set_action(SA_BOOKMARK
);
946 if (act
== SA_REPLACE
)
947 search_set_action(SA_REPLACEALL
);
953 populate_value(GladeWidgetId id
, gpointer val_ptr
)
957 g_return_if_fail(id
&& val_ptr
);
959 gw
= sr_get_gladewidget(id
);
960 g_return_if_fail(gw
);
965 if (*((char **) val_ptr
))
966 g_free(* ((char **) val_ptr
));
967 *((char **) val_ptr
) = gtk_editable_get_chars(
968 GTK_EDITABLE(gw
->widget
), 0, -1);
971 * ((gboolean
*) val_ptr
) = gtk_toggle_button_get_active(
972 GTK_TOGGLE_BUTTON(gw
->widget
));
975 g_return_if_fail (gw
->extra
!= NULL
);
977 *((int *) val_ptr
) = search_get_item_combo (GTK_COMBO_BOX(gw
->widget
));
980 g_warning("Bad option %d to populate_value", gw
->type
);
993 reset_flags_and_search_button(void)
996 if (sr
->search
.action
!= SA_REPLACEALL
)
997 modify_label_image_button(SEARCH_BUTTON
, _("Search"), GTK_STOCK_FIND
);
1000 modify_label_image_button(SEARCH_BUTTON
, _("Replace All"),
1001 GTK_STOCK_FIND_AND_REPLACE
);
1003 show_jump_button(FALSE
);
1007 search_start_over (SearchDirection direction
)
1009 IAnjutaDocument
* doc
= ianjuta_document_manager_get_current_document(sr
->docman
,
1011 IAnjutaEditor
*te
= NULL
;
1012 if (IANJUTA_IS_EDITOR(doc
))
1013 te
= IANJUTA_EDITOR(doc
);
1018 length
= ianjuta_editor_get_length(te
, NULL
);;
1020 if (direction
!= SD_BACKWARD
)
1021 /* search from doc start */
1022 ianjuta_editor_goto_position(te
, 0, NULL
);
1024 /* search from doc end */
1025 ianjuta_editor_goto_position (te
, length
, NULL
);
1030 search_end_alert(gchar
*string
)
1034 if (sr
->search
.range
.direction
!= SD_BEGINNING
&& !flag_select
)
1036 // Ask if user wants to wrap around the doc
1037 // Dialog to be made HIG compliant.
1038 dialog
= gtk_message_dialog_new (GTK_WINDOW (sg
->dialog
),
1039 GTK_DIALOG_DESTROY_WITH_PARENT
,
1040 GTK_MESSAGE_QUESTION
,
1042 _("The match \"%s\" was not found. Wrap search around the document?"),
1045 gtk_dialog_set_default_response (GTK_DIALOG (dialog
),
1047 g_signal_connect(G_OBJECT(dialog
), "key-press-event",
1048 G_CALLBACK(on_search_dialog_key_press_event
), NULL
);
1049 if (gtk_dialog_run (GTK_DIALOG (dialog
)) == GTK_RESPONSE_YES
)
1051 search_start_over (sr
->search
.range
.direction
);
1052 gtk_widget_destroy(dialog
);
1054 search_and_replace ();
1060 dialog
= gtk_message_dialog_new(GTK_WINDOW (sg
->dialog
),
1061 GTK_DIALOG_MODAL
, GTK_MESSAGE_WARNING
, GTK_BUTTONS_OK
,
1062 _("The match \"%s\" was not found."),
1064 g_signal_connect(G_OBJECT(dialog
), "key-press-event",
1065 G_CALLBACK(on_search_dialog_key_press_event
), NULL
);
1066 gtk_dialog_run(GTK_DIALOG(dialog
));
1068 gtk_widget_destroy(dialog
);
1073 max_results_alert(void)
1075 GtkWidget
*dialog
= gtk_message_dialog_new(GTK_WINDOW (sg
->dialog
),
1076 GTK_DIALOG_MODAL
, GTK_MESSAGE_WARNING
, GTK_BUTTONS_OK
,
1077 _("The maximum number of results has been reached."));
1078 g_signal_connect(G_OBJECT(dialog
), "key-press-event",
1079 G_CALLBACK(on_search_dialog_key_press_event
), NULL
);
1080 gtk_dialog_run(GTK_DIALOG(dialog
));
1081 gtk_widget_destroy(dialog
);
1086 nb_results_alert(gint nb
)
1088 GtkWidget
*dialog
= gtk_message_dialog_new(GTK_WINDOW (sg
->dialog
),
1089 GTK_DIALOG_MODAL
, GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
1090 _("%d matches have been replaced."), nb
);
1091 g_signal_connect(G_OBJECT(dialog
), "key-press-event",
1092 G_CALLBACK(on_search_dialog_key_press_event
), NULL
);
1093 gtk_dialog_run(GTK_DIALOG(dialog
));
1094 gtk_widget_destroy(dialog
);
1099 search_show_replace(gboolean hide
)
1101 static GladeWidgetId hide_widgets
[] = {
1102 REPLACE_REGEX
, REPLACE_STRING_COMBO
, LABEL_REPLACE
1107 for (i
=0; i
< sizeof(hide_widgets
)/sizeof(hide_widgets
[0]); ++i
)
1109 widget
= sr_get_gladewidget(hide_widgets
[i
])->widget
;
1113 gtk_widget_show(widget
);
1115 gtk_widget_hide(widget
);
1121 modify_label_image_button(GladeWidgetId button_id
, gchar
*name
, char *stock_image
)
1125 GtkWidget
*alignment
;
1126 GtkWidget
*button
= sr_get_gladewidget(button_id
)->widget
;
1128 list
= gtk_container_get_children(GTK_CONTAINER (button
));
1129 alignment
= GTK_WIDGET(list
->data
);
1131 list
= gtk_container_get_children(GTK_CONTAINER (alignment
));
1132 hbox
= GTK_HBOX(list
->data
);
1134 list
= gtk_container_get_children(GTK_CONTAINER (hbox
));
1135 for (l
=list
; l
; l
= g_list_next(l
))
1137 if (GTK_IS_LABEL(l
->data
))
1138 gtk_label_set_text(GTK_LABEL(l
->data
), name
);
1139 if (GTK_IS_IMAGE(l
->data
))
1140 gtk_image_set_from_stock(GTK_IMAGE(l
->data
), stock_image
,
1141 GTK_ICON_SIZE_BUTTON
);
1147 /********************************************************************/
1149 #define POP_LIST(str, var) populate_value(str, &s);\
1152 sr->search.range.files.var = anjuta_util_glist_from_string(s);\
1155 /********************************************************************/
1158 search_replace_populate(void)
1163 /* Now, populate the instance with values from the GUI */
1164 populate_value(SEARCH_STRING
, &(sr
->search
.expr
.search_str
));
1165 populate_value(SEARCH_REGEX
, &(sr
->search
.expr
.regex
));
1166 populate_value(GREEDY
, &(sr
->search
.expr
.greedy
));
1167 populate_value(IGNORE_CASE
, &(sr
->search
.expr
.ignore_case
));
1168 populate_value(WHOLE_WORD
, &(sr
->search
.expr
.whole_word
));
1169 populate_value(WHOLE_LINE
, &(sr
->search
.expr
.whole_line
));
1170 populate_value(WORD_START
, &(sr
->search
.expr
.word_start
));
1171 populate_value(SEARCH_TARGET_COMBO
, &(sr
->search
.range
.type
));
1172 populate_value(SEARCH_DIRECTION_COMBO
, &(sr
->search
.range
.direction
));
1173 populate_value(ACTIONS_NO_LIMIT
, &(sr
->search
.expr
.no_limit
));
1175 populate_value(SEARCH_BASIC
, &(sr
->search
.basic_search
));
1177 if (sr
->search
.expr
.no_limit
)
1178 sr
->search
.expr
.actions_max
= G_MAXINT
;
1181 populate_value(ACTIONS_MAX
, &(max
));
1182 sr
->search
.expr
.actions_max
= atoi(max
);
1183 if (sr
->search
.expr
.actions_max
<= 0)
1184 sr
->search
.expr
.actions_max
= 200;
1188 switch (sr
->search
.range
.type
)
1193 sr
->search
.range
.type
= SR_SELECTION
;
1196 POP_LIST(MATCH_FILES
, match_files
);
1197 POP_LIST(UNMATCH_FILES
, ignore_files
);
1198 POP_LIST(MATCH_DIRS
, match_dirs
);
1199 POP_LIST(UNMATCH_DIRS
, ignore_dirs
);
1200 populate_value(IGNORE_HIDDEN_FILES
, &(sr
->search
.range
.files
.ignore_hidden_files
));
1201 populate_value(IGNORE_HIDDEN_DIRS
, &(sr
->search
.range
.files
.ignore_hidden_dirs
));
1202 populate_value(SEARCH_RECURSIVE
, &(sr
->search
.range
.files
.recurse
));
1207 populate_value(SEARCH_ACTION_COMBO
, &(sr
->search
.action
));
1208 switch (sr
->search
.action
)
1212 populate_value(REPLACE_STRING
, &(sr
->replace
.repl_str
));
1213 populate_value(REPLACE_REGEX
, &(sr
->replace
.regex
));
1221 show_jump_button (gboolean show
)
1223 GtkWidget
*jump_button
= sr_get_gladewidget(JUMP_BUTTON
)->widget
;
1225 gtk_widget_show(jump_button
);
1227 gtk_widget_hide(jump_button
);
1231 void translate_dialog_strings (AnjutaUtilStringMap labels
[])
1234 while (labels
[i
].name
!= NULL
)
1236 labels
[i
].name
= gettext (labels
[i
].name
);
1248 g_return_val_if_fail(NULL
!= sr
, FALSE
);
1249 if (NULL
!= sg
) return TRUE
;
1250 sg
= g_new0(SearchReplaceGUI
, 1);
1252 if (NULL
== (sg
->xml
= glade_xml_new(GLADE_FILE_SEARCH_REPLACE
,
1253 SEARCH_REPLACE_DIALOG
, NULL
)))
1255 anjuta_util_dialog_error(NULL
, _("Unable to build user interface for Search And Replace"));
1260 sg
->dialog
= glade_xml_get_widget(sg
->xml
, SEARCH_REPLACE_DIALOG
);
1261 /* gtk_window_set_transient_for (GTK_WINDOW(sg->dialog)
1262 , GTK_WINDOW(app->widgets.window)); */
1264 if (!labels_translated
)
1266 labels_translated
= TRUE
;
1267 translate_dialog_strings (search_direction_strings
);
1268 translate_dialog_strings (search_target_strings
);
1269 translate_dialog_strings (search_action_strings
);
1272 for (i
=0; NULL
!= glade_widgets
[i
].name
; ++i
)
1274 w
= &(glade_widgets
[i
]);
1275 w
->widget
= glade_xml_get_widget(sg
->xml
, w
->name
);
1276 if (GE_COMBO_ENTRY
== w
->type
)
1278 /* Get child of GtkComboBoxEntry */
1279 w
->widget
= GTK_BIN(w
->widget
)->child
;
1281 gtk_widget_ref(w
->widget
);
1282 if (GE_COMBO
== w
->type
&& NULL
!= w
->extra
)
1284 search_set_popdown_map(GTK_COMBO_BOX(w
->widget
), (AnjutaUtilStringMap
*)w
->extra
);
1288 widget
= sr_get_gladewidget(SEARCH_STRING_COMBO
)->widget
;
1289 g_signal_connect (widget
, "changed", G_CALLBACK (on_search_expression_changed
), NULL
);
1290 widget
= sr_get_gladewidget(SEARCH_STRING
)->widget
;
1291 g_signal_connect (widget
, "activate", G_CALLBACK (on_search_expression_activate
), NULL
);
1292 widget
= sr_get_gladewidget(REPLACE_STRING
)->widget
;
1293 g_signal_connect (widget
, "activate", G_CALLBACK (on_search_expression_activate
), NULL
);
1294 widget
= sr_get_gladewidget(SEARCH_ACTION_COMBO
)->widget
;
1295 g_signal_connect (widget
, "changed", G_CALLBACK (on_search_action_changed
), NULL
);
1296 widget
= sr_get_gladewidget(SEARCH_DIRECTION_COMBO
)->widget
;
1297 g_signal_connect (widget
, "changed", G_CALLBACK (on_search_direction_changed
), NULL
);
1298 widget
= sr_get_gladewidget(SEARCH_TARGET_COMBO
)->widget
;
1299 g_signal_connect (widget
, "changed", G_CALLBACK (on_search_target_changed
), NULL
);
1302 search_preferences_initialize_setting_treeview(sg
->dialog
);
1303 search_preferences_init();
1305 glade_xml_signal_autoconnect(sg
->xml
);
1312 gtk_window_present (GTK_WINDOW (sg
->dialog
));
1317 word_in_list(GList
*list
, gchar
*word
)
1323 if (strcmp(l
->data
, word
) == 0)
1330 /* Remove last item of the list if > nb_max */
1333 list_max_items(GList
*list
, guint nb_max
)
1337 if (g_list_length(list
) > nb_max
)
1339 last
= g_list_last(list
);
1341 list
= g_list_delete_link (list
, last
);
1346 #define MAX_ITEMS_SEARCH_COMBO 16
1349 search_toolbar_set_text(gchar
*search_text
)
1355 g_object_get(G_OBJECT(sr
->docman
), "shell", &shell
, NULL
);
1357 ui
= anjuta_shell_get_ui (shell
, NULL
);
1358 action
= anjuta_ui_get_action (ui
, "ActionGroupNavigation",
1359 "ActionEditSearchEntry");
1360 egg_entry_action_set_text (EGG_ENTRY_ACTION(action
), search_text
);
1364 search_update_combos(void)
1366 GtkWidget
*search_entry
= NULL
;
1367 gchar
*search_word
= NULL
;
1368 IAnjutaDocument
* doc
= ianjuta_document_manager_get_current_document(sr
->docman
,
1370 IAnjutaEditor
*te
= NULL
;
1371 if (IANJUTA_IS_EDITOR(doc
))
1372 te
= IANJUTA_EDITOR(doc
);
1374 search_entry
= sr_get_gladewidget(SEARCH_STRING
)->widget
;
1375 if (search_entry
&& te
)
1377 search_word
= g_strdup(gtk_entry_get_text(GTK_ENTRY (search_entry
)));
1378 if (search_word
&& strlen(search_word
) > 0)
1380 if (!word_in_list(sr
->search
.expr_history
, search_word
))
1382 GtkWidget
*search_list
=
1383 sr_get_gladewidget(SEARCH_STRING_COMBO
)->widget
;
1384 sr
->search
.expr_history
= g_list_prepend(sr
->search
.expr_history
,
1386 sr
->search
.expr_history
= list_max_items(sr
->search
.expr_history
,
1387 MAX_ITEMS_SEARCH_COMBO
);
1388 search_set_popdown_strings(GTK_COMBO_BOX_ENTRY (search_list
),
1389 sr
->search
.expr_history
);
1391 //search_toolbar_set_text(search_word);
1392 // FIXME comboentry instead of entry
1393 //~ entry_set_text_n_select (app->widgets.toolbar.main_toolbar.find_entry,
1394 //~ search_word, FALSE);
1401 replace_update_combos(void)
1403 GtkWidget
*replace_entry
= NULL
;
1404 gchar
*replace_word
= NULL
;
1405 IAnjutaDocument
* doc
= ianjuta_document_manager_get_current_document(sr
->docman
,
1407 IAnjutaEditor
*te
= NULL
;
1408 if (IANJUTA_IS_EDITOR(doc
))
1409 te
= IANJUTA_EDITOR(doc
);
1411 replace_entry
= sr_get_gladewidget(REPLACE_STRING
)->widget
;
1412 if (replace_entry
&& te
)
1414 replace_word
= g_strdup(gtk_entry_get_text(GTK_ENTRY (replace_entry
)));
1415 if (replace_word
&& strlen(replace_word
) > 0)
1417 if (!word_in_list(sr
->replace
.expr_history
, replace_word
))
1419 GtkWidget
*replace_list
=
1420 sr_get_gladewidget(REPLACE_STRING_COMBO
)->widget
;
1421 sr
->replace
.expr_history
= g_list_prepend(sr
->replace
.expr_history
,
1423 sr
->replace
.expr_history
= list_max_items(sr
->replace
.expr_history
,
1424 MAX_ITEMS_SEARCH_COMBO
);
1425 search_set_popdown_strings(GTK_COMBO_BOX_ENTRY (replace_list
),
1426 sr
->replace
.expr_history
);
1433 search_update_dialog(void)
1439 widget
= sr_get_gladewidget(SEARCH_REGEX
)->widget
;
1440 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->expr
.regex
);
1441 widget
= sr_get_gladewidget(GREEDY
)->widget
;
1442 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->expr
.greedy
);
1443 widget
= sr_get_gladewidget(IGNORE_CASE
)->widget
;
1444 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->expr
.ignore_case
);
1445 widget
= sr_get_gladewidget(WHOLE_WORD
)->widget
;
1446 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->expr
.whole_word
);
1447 widget
= sr_get_gladewidget(WHOLE_LINE
)->widget
;
1448 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->expr
.whole_line
);
1449 widget
= sr_get_gladewidget(WORD_START
)->widget
;
1450 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->expr
.word_start
);
1452 widget
= sr_get_gladewidget(ACTIONS_NO_LIMIT
)->widget
;
1453 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->expr
.no_limit
);
1454 widget
= sr_get_gladewidget(ACTIONS_MAX
)->widget
;
1455 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget
), s
->expr
.actions_max
);
1457 widget
= sr_get_gladewidget(REPLACE_REGEX
)->widget
;
1458 gtk_widget_set_sensitive(widget
, sr
->search
.expr
.regex
);
1460 widget
= sr_get_gladewidget(SEARCH_BUTTON
)->widget
;
1461 gtk_widget_set_sensitive (widget
, (s
->expr
.search_str
!= NULL
) && (*s
->expr
.search_str
!= '\0'));
1463 widget
= sr_get_gladewidget(SEARCH_STRING
)->widget
;
1464 if (s
->expr
.search_str
)
1465 gtk_entry_set_text(GTK_ENTRY(widget
), s
->expr
.search_str
);
1467 widget
= sr_get_gladewidget(SEARCH_DIRECTION_COMBO
)->widget
;
1468 search_select_item (GTK_COMBO_BOX(widget
), s
->range
.direction
);
1470 widget
= sr_get_gladewidget(SEARCH_ACTION_COMBO
)->widget
;
1471 search_select_item (GTK_COMBO_BOX(widget
), s
->action
);
1473 search_show_replace(s
->action
== SA_REPLACE
|| s
->action
== SA_REPLACEALL
);
1475 widget
= sr_get_gladewidget(SEARCH_TARGET_COMBO
)->widget
;
1476 search_select_item (GTK_COMBO_BOX(widget
), s
->range
.type
);
1478 widget
= sr_get_gladewidget(SEARCH_BASIC
)->widget
;
1479 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->basic_search
);
1481 widget
= sr_get_gladewidget(STOP_BUTTON
)->widget
;
1482 gtk_widget_set_sensitive (widget
, FALSE
);
1484 basic_search_toggled();
1487 /* -------------- Callbacks --------------------- */
1490 on_search_replace_delete_event(GtkWidget
*window
, GdkEvent
*event
,
1495 gtk_widget_hide(sg
->dialog
);
1496 sg
->showing
= FALSE
;
1502 on_search_dialog_key_press_event(GtkWidget
*widget
, GdkEventKey
*event
,
1505 if (event
->keyval
== GDK_Escape
)
1509 /* Escape pressed in Find window */
1510 gtk_widget_hide(widget
);
1511 sg
->showing
= FALSE
;
1515 /* Escape pressed in wrap yes/no window */
1516 gtk_dialog_response (GTK_DIALOG (widget
), GTK_RESPONSE_NO
);
1522 if ( (event
->state
& GDK_CONTROL_MASK
) &&
1523 ((event
->keyval
& 0x5F) == GDK_G
))
1525 if (event
->state
& GDK_SHIFT_MASK
)
1526 search_replace_previous();
1528 search_replace_next();
1535 search_disconnect_set_toggle_connect(GladeWidgetId id
, GCallback function
,
1540 button
= sr_get_gladewidget(id
)->widget
;
1541 g_signal_handlers_disconnect_by_func(G_OBJECT(button
), function
, NULL
);
1542 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button
), active
);
1543 g_signal_connect(G_OBJECT(button
), "toggled", function
, NULL
);
1548 on_search_match_whole_word_toggled (GtkToggleButton
*togglebutton
,
1551 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton
)))
1553 search_disconnect_set_toggle_connect(WHOLE_LINE
, (GCallback
)
1554 on_search_match_whole_line_toggled
, FALSE
);
1555 search_disconnect_set_toggle_connect(WORD_START
, (GCallback
)
1556 on_search_match_word_start_toggled
, FALSE
);
1561 on_search_match_whole_line_toggled (GtkToggleButton
*togglebutton
,
1564 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton
)))
1566 search_disconnect_set_toggle_connect(WHOLE_WORD
, (GCallback
)
1567 on_search_match_whole_word_toggled
, FALSE
);
1568 search_disconnect_set_toggle_connect(WORD_START
, (GCallback
)
1569 on_search_match_word_start_toggled
, FALSE
);
1574 on_search_match_word_start_toggled (GtkToggleButton
*togglebutton
,
1577 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton
)))
1579 search_disconnect_set_toggle_connect(WHOLE_WORD
, (GCallback
)
1580 on_search_match_whole_word_toggled
, FALSE
);
1581 search_disconnect_set_toggle_connect(WHOLE_LINE
, (GCallback
)
1582 on_search_match_whole_line_toggled
, FALSE
);
1588 search_make_sensitive(gboolean sensitive)
1590 static char *widgets[] = {
1591 SEARCH_EXPR_FRAME, SEARCH_TARGET_FRAME, CLOSE_BUTTON, SEARCH_BUTTON,
1597 for (i=0; i < sizeof(widgets)/sizeof(widgets[0]); ++i)
1599 widget = sr_get_gladewidget(widgets[i])->widget;
1601 gtk_widget_set_sensitive(widget, sensitive);
1607 on_search_regex_toggled (GtkToggleButton
*togglebutton
, gpointer user_data
)
1609 static GladeWidgetId dependent_widgets
[] = {
1610 GREEDY
, IGNORE_CASE
, WHOLE_WORD
, WHOLE_LINE
, WORD_START
1613 GtkWidget
*dircombo
= sr_get_gladewidget(SEARCH_DIRECTION_COMBO
)->widget
;
1614 GtkWidget
*repl_regex
= sr_get_gladewidget(REPLACE_REGEX
)->widget
;
1616 gboolean state
= gtk_toggle_button_get_active(togglebutton
);
1620 search_set_direction(SD_FORWARD
);
1623 gtk_widget_set_sensitive(dircombo
, !state
);
1624 gtk_widget_set_sensitive(repl_regex
, state
);
1626 for (i
=0; i
< sizeof(dependent_widgets
)/sizeof(dependent_widgets
[0]); ++i
)
1628 widget
= sr_get_gladewidget(dependent_widgets
[i
])->widget
;
1631 gtk_widget_set_sensitive(widget
, !state
);
1632 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget
), FALSE
);
1638 search_set_toggle_direction(SearchDirection dir
)
1643 search_disconnect_set_toggle_connect(SEARCH_FORWARD
, (GCallback
)
1644 on_search_forward_toggled
, TRUE
);
1647 search_disconnect_set_toggle_connect(SEARCH_BACKWARD
, (GCallback
)
1648 on_search_backward_toggled
, TRUE
);
1651 search_disconnect_set_toggle_connect(SEARCH_FULL_BUFFER
, (GCallback
)
1652 on_search_full_buffer_toggled
, TRUE
);
1658 on_search_direction_changed (GtkComboBox
*combo
, gpointer user_data
)
1660 SearchDirection dir
;
1662 dir
= search_get_item_combo(combo
);
1663 search_set_toggle_direction(dir
);
1664 search_direction_changed(dir
);
1668 on_search_action_changed (GtkComboBox
*combo
, gpointer user_data
)
1674 act
= search_get_item_combo(combo
);
1675 rt
= search_get_item_combo_name(SEARCH_TARGET_COMBO
);
1676 show_jump_button (FALSE
);
1680 search_show_replace(FALSE
);
1681 modify_label_image_button(SEARCH_BUTTON
, _("Search"), GTK_STOCK_FIND
);
1682 if (rt
== SR_OPEN_BUFFERS
|| rt
== SR_PROJECT
||
1684 search_set_target(SR_BUFFER
);
1687 search_show_replace(TRUE
);
1688 modify_label_image_button(SEARCH_BUTTON
, _("Search"), GTK_STOCK_FIND
);
1689 if (rt
== SR_OPEN_BUFFERS
|| rt
== SR_PROJECT
||
1691 search_set_target(SR_BUFFER
);
1694 search_show_replace(TRUE
);
1695 modify_label_image_button(SEARCH_BUTTON
, _("Replace All"),
1696 GTK_STOCK_FIND_AND_REPLACE
);
1699 search_show_replace(FALSE
);
1700 modify_label_image_button(SEARCH_BUTTON
, _("Search"), GTK_STOCK_FIND
);
1706 on_search_target_changed(GtkComboBox
*combo
, gpointer user_data
)
1708 SearchRangeType tgt
;
1709 SearchDirection dir
;
1711 GtkWidget
*search_var_frame
= sr_get_gladewidget(SEARCH_VAR_FRAME
)->widget
;
1712 GtkWidget
*file_filter_frame
= sr_get_gladewidget(FILE_FILTER_FRAME
)->widget
;
1714 tgt
= search_get_item_combo(combo
);
1718 gtk_widget_hide(search_var_frame
);
1719 gtk_widget_show(file_filter_frame
);
1722 gtk_widget_hide(search_var_frame
);
1723 gtk_widget_hide(file_filter_frame
);
1727 dir
= search_get_item_combo_name(SEARCH_DIRECTION_COMBO
);
1729 if (tgt
== SR_SELECTION
|| tgt
== SR_BLOCK
|| tgt
== SR_FUNCTION
)
1732 if (dir
== SD_BEGINNING
)
1734 search_set_direction(SD_FORWARD
);
1737 if (tgt
== SR_OPEN_BUFFERS
|| tgt
== SR_PROJECT
||
1740 search_set_direction(SD_BEGINNING
);
1742 act
= search_get_item_combo_name(SEARCH_ACTION_COMBO
);
1743 if (act
!= SA_REPLACE
&& act
!= SA_REPLACEALL
)
1745 if (tgt
== SR_OPEN_BUFFERS
)
1746 search_set_action(SA_BOOKMARK
);
1748 search_set_action(SA_FIND_PANE
);
1752 search_set_action(SA_REPLACEALL
);
1753 sr
->search
.action
= SA_REPLACEALL
;
1756 reset_flags_and_search_button();
1758 gtk_window_resize(GTK_WINDOW(sg
->dialog
), 10, 10);
1762 on_search_expression_changed(GtkComboBox
*combo
, gpointer user_data
)
1764 GtkWidget
*search_entry
= sr_get_gladewidget(SEARCH_STRING
)->widget
;
1765 GtkWidget
*widget
= sr_get_gladewidget(SEARCH_BUTTON
)->widget
;
1768 sensitive
= *gtk_entry_get_text (GTK_ENTRY (search_entry
)) == '\0' ? FALSE
: TRUE
;
1769 gtk_widget_set_sensitive (widget
, sensitive
);
1774 on_actions_no_limit_clicked(GtkButton
*button
, gpointer user_data
)
1776 GtkWidget
*actions_max
= sr_get_gladewidget(ACTIONS_MAX
)->widget
;
1778 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button
)))
1779 gtk_widget_set_sensitive (actions_max
, FALSE
);
1781 gtk_widget_set_sensitive (actions_max
, TRUE
);
1785 on_search_button_close_clicked(GtkButton
*button
, gpointer user_data
)
1789 gtk_widget_hide(sg
->dialog
);
1790 sg
->showing
= FALSE
;
1795 on_search_button_stop_clicked(GtkButton
*button
, gpointer user_data
)
1797 end_activity
= TRUE
;
1801 on_search_button_next_clicked(GtkButton
*button
, gpointer user_data
)
1804 search_replace_populate();
1806 search_and_replace();
1809 void search_replace_find_usage(const gchar
*symbol
)
1811 gchar
*project_root_uri
= NULL
;
1812 SearchReplace
*old_sr
= sr
;
1815 sr
= g_new (SearchReplace
, 1);
1817 sr
->search
.expr
.search_str
= g_strdup (symbol
);
1818 sr
->search
.expr
.regex
= FALSE
;
1819 sr
->search
.expr
.greedy
= FALSE
;
1820 sr
->search
.expr
.ignore_case
= FALSE
;
1821 sr
->search
.expr
.whole_word
= TRUE
;
1822 sr
->search
.expr
.whole_line
= FALSE
;
1823 sr
->search
.expr
.word_start
= FALSE
;
1824 sr
->search
.expr
.no_limit
= TRUE
;
1825 sr
->search
.expr
.actions_max
= G_MAXINT
;
1826 sr
->search
.expr
.re
= NULL
;
1828 g_object_get(G_OBJECT(sr
->docman
), "shell", &shell
, NULL
);
1830 anjuta_shell_get (shell
,
1831 "project_root_uri", G_TYPE_STRING
,
1832 &project_root_uri
, NULL
);
1834 sr
->search
.range
.type
=
1835 project_root_uri
!= NULL
? SR_PROJECT
: SR_OPEN_BUFFERS
;
1836 g_free (project_root_uri
);
1838 sr
->search
.range
.direction
= SD_BEGINNING
;
1840 sr
->search
.range
.var
= NULL
;
1842 sr
->search
.range
.files
.top_dir
= NULL
;
1843 sr
->search
.range
.files
.match_files
= NULL
;
1844 sr
->search
.range
.files
.match_dirs
= NULL
;
1845 sr
->search
.range
.files
.ignore_files
= NULL
;
1846 sr
->search
.range
.files
.ignore_dirs
= NULL
;
1847 sr
->search
.range
.files
.ignore_hidden_files
= TRUE
;
1848 sr
->search
.range
.files
.ignore_hidden_dirs
= TRUE
;
1849 sr
->search
.range
.files
.recurse
= TRUE
;
1851 sr
->search
.action
= SA_FIND_PANE
;
1853 sr
->search
.expr_history
= NULL
;
1854 sr
->search
.incremental_pos
= 0;
1855 sr
->search
.incremental_wrap
= TRUE
;
1859 search_and_replace();
1865 on_search_button_jump_clicked(GtkButton
*button
, gpointer user_data
)
1868 interactive
= FALSE
;
1869 gtk_widget_hide(GTK_WIDGET(button
));
1871 search_replace_populate();
1872 search_and_replace();
1876 on_search_expression_activate (GtkEditable
*edit
, gpointer user_data
)
1880 search_replace_populate();
1882 search_and_replace();
1883 combo
= GTK_WIDGET(edit
)->parent
;
1884 reset_flags_and_search_button();
1889 on_search_full_buffer_toggled (GtkToggleButton
*togglebutton
,
1892 if (gtk_toggle_button_get_active(togglebutton
))
1894 search_set_direction(SD_BEGINNING
);
1899 on_search_forward_toggled (GtkToggleButton
*togglebutton
,
1902 if (gtk_toggle_button_get_active(togglebutton
))
1904 search_set_direction(SD_FORWARD
);
1909 on_search_backward_toggled (GtkToggleButton
*togglebutton
,
1912 if (gtk_toggle_button_get_active(togglebutton
))
1914 search_set_direction(SD_BACKWARD
);
1919 on_setting_basic_search_toggled (GtkToggleButton
*togglebutton
,
1923 GtkWidget
*frame_basic
= sr_get_gladewidget(FRAME_SEARCH_BASIC
)->widget
;
1925 if (gtk_toggle_button_get_active(togglebutton
))
1927 gtk_widget_show(frame_basic
);
1928 search_set_target(SR_BUFFER
);
1929 search_set_direction(SD_FORWARD
);
1931 act
= search_get_item_combo_name(SEARCH_ACTION_COMBO
);
1932 if (act
== SA_REPLACE
|| act
== SA_REPLACEALL
)
1933 search_set_action(SA_REPLACE
);
1935 search_set_action(SA_SELECT
);
1938 gtk_widget_hide(frame_basic
);
1943 basic_search_toggled(void)
1945 GtkToggleButton
*togglebutton
;
1947 togglebutton
= GTK_TOGGLE_BUTTON(sr_get_gladewidget(SEARCH_BASIC
)->widget
);
1949 on_setting_basic_search_toggled (togglebutton
, NULL
);
1952 /***********************************************************************/
1954 #define MAX_LENGTH_SEARCH 64
1957 anjuta_search_replace_activate (gboolean replace
, gboolean project
)
1959 GtkWidget
*notebook
;
1960 GtkWidget
*search_entry
;
1961 IAnjutaDocument
*doc
;
1966 search_update_dialog();
1968 search_replace_populate();
1970 reset_flags_and_search_button();
1972 search_entry
= sr_get_gladewidget(SEARCH_STRING
)->widget
;
1973 doc
= ianjuta_document_manager_get_current_document(sr
->docman
, NULL
);
1974 te
= (IANJUTA_IS_EDITOR (doc
)) ? IANJUTA_EDITOR (doc
) : NULL
;
1975 if (te
&& search_entry
&& sr
->search
.range
.type
!= SR_SELECTION
)
1977 /* Set properties */
1978 gchar
*current_word
;
1980 current_word
= ianjuta_editor_selection_get
1981 (IANJUTA_EDITOR_SELECTION (te
), NULL
);
1982 if (current_word
== NULL
)
1983 current_word
= ianjuta_editor_get_current_word (te
, NULL
);
1985 if (current_word
&& strlen(current_word
) > 0 )
1987 if (strlen(current_word
) > MAX_LENGTH_SEARCH
)
1988 current_word
[MAX_LENGTH_SEARCH
] = '\0';
1989 gtk_entry_set_text(GTK_ENTRY (search_entry
), current_word
);
1990 g_free(current_word
);
1996 if ( !(sr
->search
.action
== SA_REPLACE
||
1997 sr
->search
.action
== SA_REPLACEALL
))
1999 search_set_action(SA_REPLACE
);
2000 sr
->search
.action
= SA_REPLACE
;
2001 search_show_replace(TRUE
);
2006 if (sr
->search
.action
== SA_REPLACE
|| sr
->search
.action
== SA_REPLACEALL
)
2008 search_set_action(SA_SELECT
);
2009 sr
->search
.action
= SA_SELECT
;
2010 search_show_replace(FALSE
);
2013 if (sr
->search
.action
!= SA_REPLACEALL
)
2014 modify_label_image_button(SEARCH_BUTTON
, _("Search"), GTK_STOCK_FIND
);
2018 search_set_target(SR_PROJECT
);
2021 search_set_action (SA_FIND_PANE
);
2022 search_set_direction (SD_BEGINNING
);
2025 show_jump_button(FALSE
);
2027 notebook
= sr_get_gladewidget(SEARCH_NOTEBOOK
)->widget
;
2028 gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook
), 0);
2030 /* Show the dialog */
2032 gtk_widget_grab_focus (search_entry
);