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>
26 #include <libgnomevfs/gnome-vfs.h>
28 #include <libanjuta/anjuta-utils.h>
29 #include <libanjuta/anjuta-plugin.h>
30 #include <libanjuta/anjuta-debug.h>
31 #include <libanjuta/interfaces/ianjuta-message-manager.h>
32 #include <libanjuta/interfaces/ianjuta-message-view.h>
33 #include <libanjuta/interfaces/ianjuta-editor.h>
34 #include <libanjuta/interfaces/ianjuta-editor-selection.h>
35 #include <libanjuta/interfaces/ianjuta-markable.h>
36 #include <libanjuta/interfaces/ianjuta-bookmark.h>
37 #include <libanjuta/interfaces/ianjuta-indicable.h>
39 #include "search-replace_backend.h"
40 #include "search-replace.h"
41 #include "search_preferences.h"
43 #include <libanjuta/interfaces/ianjuta-project-manager.h>
44 #include <glib/gi18n.h>
46 #define GLADE_FILE_SEARCH_REPLACE PACKAGE_DATA_DIR"/glade/anjuta-search.glade"
48 /* LibGlade's auto-signal-connect will connect to these signals.
49 * Do not declare them static.
52 on_search_dialog_key_press_event(GtkWidget
*widget
, GdkEventKey
*event
,
54 void on_search_match_whole_word_toggled (GtkToggleButton
*togglebutton
,
56 void on_search_match_whole_line_toggled (GtkToggleButton
*togglebutton
,
58 void on_search_match_word_start_toggled (GtkToggleButton
*togglebutton
,
60 gboolean
on_search_replace_delete_event(GtkWidget
*window
, GdkEvent
*event
,
62 void on_replace_regex_toggled (GtkToggleButton
*togglebutton
, gpointer user_data
);
63 void on_search_regex_toggled (GtkToggleButton
*togglebutton
, gpointer user_data
);
64 void on_search_action_changed (GtkComboBox
*combo
, gpointer user_data
);
65 void on_search_target_changed(GtkComboBox
*combo
, gpointer user_data
);
66 void on_search_expression_changed(GtkComboBox
*combo
, gpointer user_data
);
67 void on_actions_no_limit_clicked(GtkButton
*button
, gpointer user_data
);
68 void on_search_button_close_clicked(GtkButton
*button
, gpointer user_data
);
69 void on_search_button_close_clicked(GtkButton
*button
, gpointer user_data
);
70 void on_search_button_help_clicked(GtkButton
*button
, gpointer user_data
);
71 void on_search_button_next_clicked(GtkButton
*button
, gpointer user_data
);
72 void on_search_button_jump_clicked(GtkButton
*button
, gpointer user_data
);
73 void on_search_expression_activate (GtkEditable
*edit
, gpointer user_data
);
74 void on_search_button_save_clicked(GtkButton
*button
, gpointer user_data
);
75 void on_search_button_stop_clicked(GtkButton
*button
, gpointer user_data
);
77 void on_search_direction_changed (GtkComboBox
*combo
, gpointer user_data
);
78 void on_search_full_buffer_toggled (GtkToggleButton
*togglebutton
,
80 void on_search_forward_toggled (GtkToggleButton
*togglebutton
,
82 void on_search_backward_toggled (GtkToggleButton
*togglebutton
,
84 void on_setting_basic_search_toggled (GtkToggleButton
*togglebutton
,
87 /* GUI dropdown option strings */
88 AnjutaUtilStringMap search_direction_strings
[] = {
89 /* the order of these matters - it must match the order of the corresponding
90 radio buttons on another page */
91 {SD_BEGINNING
, N_("Full Buffer")},
92 {SD_FORWARD
, N_("Forward")},
93 {SD_BACKWARD
, N_("Backward")},
97 AnjutaUtilStringMap search_target_strings
[] = {
98 {SR_BUFFER
, N_("Current Buffer")},
99 {SR_SELECTION
, N_("Current Selection")},
100 {SR_BLOCK
, N_("Current Block")},
101 {SR_FUNCTION
, N_("Current Function")},
102 {SR_OPEN_BUFFERS
, N_("All Open Buffers")},
103 {SR_PROJECT
, N_("All Project Files")},
104 /* {SR_VARIABLE, N_("Specify File List")},*/
105 {SR_FILES
, N_("Specify File Patterns")},
109 AnjutaUtilStringMap search_action_strings
[] = {
110 {SA_SELECT
, N_("Select next match")},
111 {SA_BOOKMARK
, N_("Bookmark all matched lines")},
112 {SA_HIGHLIGHT
, N_("Mark all matches")},
113 {SA_FIND_PANE
, N_("List matches in find pane")},
114 {SA_REPLACE
, N_("Replace next match")},
115 {SA_REPLACEALL
, N_("Replace all matches")},
120 typedef struct _SearchReplaceGUI
128 static GladeWidget glade_widgets
[] = {
130 {GE_BUTTON
, "button.close", NULL
, NULL
},
132 {GE_BUTTON
, "button.stop", NULL
, NULL
},
134 {GE_BUTTON
, "button.next", NULL
, NULL
},
136 {GE_BUTTON
, "button.jump", NULL
, NULL
},
137 /* SEARCH_NOTEBOOK */
138 {GE_NONE
, "search.notebook", NULL
, NULL
},
139 /* SEARCH_EXPR_FRAME */
140 {GE_NONE
, "frame.search.expression", NULL
, NULL
},
141 /* SEARCH_TARGET_FRAME */
142 {GE_NONE
, "frame.search.target", NULL
, NULL
},
143 /* SEARCH_VAR_FRAME */
144 {GE_NONE
, "frame.search.var", NULL
, NULL
},
145 /* FILE_FILTER_FRAME */
146 {GE_NONE
, "frame.file.filter", NULL
, NULL
},
147 /* FRAME_SEARCH_BASIC */
148 {GE_NONE
, "frame.search.basic", NULL
, NULL
},
150 {GE_NONE
, "label.replace", NULL
, NULL
},
152 {GE_COMBO_ENTRY
, "search.string.combo", NULL
, NULL
},
154 {GE_COMBO_ENTRY
, "search.var.combo", NULL
, NULL
},
156 {GE_COMBO_ENTRY
, "file.filter.match.combo", NULL
, NULL
},
158 {GE_COMBO_ENTRY
, "file.filter.unmatch.combo", NULL
, NULL
},
160 {GE_COMBO_ENTRY
, "dir.filter.match.combo", NULL
, NULL
},
162 {GE_COMBO_ENTRY
, "dir.filter.unmatch.combo", NULL
, NULL
},
164 {GE_COMBO_ENTRY
, "replace.string.combo", NULL
, NULL
},
166 {GE_TEXT
, "actions.max", NULL
, NULL
},
167 /* SETTING_PREF_ENTRY */
168 {GE_TEXT
, "setting.pref.entry", NULL
, NULL
},
170 {GE_BOOLEAN
, "search.regex", NULL
, NULL
},
172 {GE_BOOLEAN
, "search.greedy", NULL
, NULL
},
174 {GE_BOOLEAN
, "search.ignore.case", NULL
, NULL
},
176 {GE_BOOLEAN
, "search.match.whole.word", NULL
, NULL
},
178 {GE_BOOLEAN
, "search.match.word.start", NULL
, NULL
},
180 {GE_BOOLEAN
, "search.match.whole.line", NULL
, NULL
},
181 /* IGNORE_HIDDEN_FILES */
182 {GE_BOOLEAN
, "ignore.hidden.files", NULL
, NULL
},
183 /* IGNORE_BINARY_FILES */
184 {GE_BOOLEAN
, "ignore.binary.files", NULL
, NULL
},
185 /* IGNORE_HIDDEN_DIRS */
186 {GE_BOOLEAN
, "ignore.hidden.dirs", NULL
, NULL
},
187 /* SEARCH_RECURSIVE */
188 {GE_BOOLEAN
, "search.dir.recursive", NULL
, NULL
},
190 {GE_BOOLEAN
, "replace.regex", NULL
, NULL
},
191 /* ACTIONS_NO_LIMIT */
192 {GE_BOOLEAN
, "actions.no_limit", NULL
, NULL
},
193 /* SEARCH_FULL_BUFFER */
194 {GE_BOOLEAN
, "search.full_buffer", NULL
, NULL
},
196 {GE_BOOLEAN
, "search.forward", NULL
, NULL
},
197 /* SEARCH_BACKWARD */
198 {GE_BOOLEAN
, "search.backward", NULL
, NULL
},
200 {GE_BOOLEAN
, "search.basic", NULL
, NULL
},
201 /* SEARCH_STRING_COMBO */
202 {GE_COMBO
, "search.string.combo", NULL
, NULL
},
203 /* SEARCH_TARGET_COMBO */
204 {GE_COMBO
, "search.target.combo", search_target_strings
, NULL
},
205 /* SEARCH_ACTION_COMBO */
206 {GE_COMBO
, "search.action.combo", search_action_strings
, NULL
},
207 /* SEARCH_VAR_COMBO */
208 {GE_COMBO
, "search.var.combo", NULL
, NULL
},
209 /* MATCH_FILES_COMBO */
210 {GE_COMBO
, "file.filter.match.combo", NULL
, NULL
},
211 /* UNMATCH_FILES_COMBO */
212 {GE_COMBO
, "file.filter.unmatch.combo", NULL
, NULL
},
213 /* MATCH_DIRS_COMBO */
214 {GE_COMBO
, "dir.filter.match.combo", NULL
, NULL
},
215 /* UNMATCH_DIRS_COMBO */
216 {GE_COMBO
, "dir.filter.unmatch.combo", NULL
, NULL
},
217 /* REPLACE_STRING_COMBO */
218 {GE_COMBO
, "replace.string.combo", NULL
, NULL
},
219 /* SEARCH_DIRECTION_COMBO */
220 {GE_COMBO
, "search.direction.combo", search_direction_strings
, NULL
},
221 /* SETTING_PREF_TREEVIEW */
222 {GE_NONE
, "setting.pref.treeview", NULL
, NULL
},
223 {GE_NONE
, NULL
, NULL
, NULL
}
226 /***********************************************************/
229 write_message_pane(IAnjutaMessageView
* view
, FileBuffer
*fb
, SearchEntry
*se
, MatchInfo
*mi
);
230 static gboolean
on_message_clicked (GObject
* object
, gchar
* message
, gpointer data
);
231 static void on_message_view_destroyed (gpointer unused
, GObject
* where_the_object_was
);
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 view
= ianjuta_message_manager_add_view(msgman
, name
,
331 GTK_STOCK_FIND_AND_REPLACE
, NULL
);
332 g_return_if_fail(view
!= NULL
);
333 g_signal_connect (G_OBJECT(view
), "buffer_flushed",
334 G_CALLBACK (on_message_buffer_flush
), NULL
);
335 g_signal_connect (G_OBJECT(view
), "message_clicked",
336 G_CALLBACK (on_message_clicked
), NULL
);
337 g_object_weak_ref (G_OBJECT(view
), on_message_view_destroyed
, 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
))
412 IAnjutaIterable
*start_pos
, *end_pos
;
413 /* end-location is correct for sourceview, 1-too-big for scintilla */
414 start_pos
= ianjuta_editor_get_position_from_offset (fb
->te
, mi
->pos
, NULL
);
415 end_pos
= ianjuta_editor_get_position_from_offset (fb
->te
, mi
->pos
+ mi
->len
, NULL
);
416 ianjuta_indicable_set (IANJUTA_INDICABLE(fb
->te
),
418 IANJUTA_INDICABLE_IMPORTANT
, NULL
);
419 g_object_unref (start_pos
);
420 g_object_unref (end_pos
);
425 if (found_line
!= mi
->line
)
427 found_line
= mi
->line
;
431 IANJUTA_EDITOR (ianjuta_document_manager_get_current_document
434 if (IANJUTA_IS_MARKABLE (fb
->te
) &&
435 !ianjuta_markable_is_marker_set (
436 IANJUTA_MARKABLE(fb
->te
),
438 IANJUTA_MARKABLE_BOOKMARK
,
441 ianjuta_bookmark_toggle (IANJUTA_BOOKMARK(fb
->te
),
442 mi
->line
, FALSE
, NULL
);
448 if (found_line
!= mi
->line
|| fb
->te
== NULL
)
451 ianjuta_editor_goto_line (fb
->te
, mi
->line
, NULL
);
454 GFile
* file
= g_file_new_for_uri (fb
->uri
);
455 fb
->te
= ianjuta_document_manager_goto_file_line_mark
456 (sr
->docman
, file
, mi
->line
, FALSE
, NULL
);
457 g_object_unref (file
);
459 found_line
= mi
->line
;
462 IAnjutaIterable
* start
= ianjuta_editor_get_position_from_offset (fb
->te
, mi
->pos
, NULL
);
463 IAnjutaIterable
* end
= ianjuta_editor_get_position_from_offset (fb
->te
, mi
->pos
+ mi
->len
, NULL
);
464 ianjuta_editor_selection_set(IANJUTA_EDITOR_SELECTION (fb
->te
),
468 g_object_unref (start
);
469 g_object_unref (end
);
474 write_message_pane(view
, fb
, se
, mi
);
478 if (found_line
!= mi
->line
|| fb
->te
== NULL
)
481 ianjuta_editor_goto_line (fb
->te
, mi
->line
, NULL
);
484 GFile
* file
= g_file_new_for_uri (fb
->uri
);
485 fb
->te
= ianjuta_document_manager_goto_file_line_mark
486 (sr
->docman
, file
, mi
->line
, FALSE
, NULL
);
487 g_object_unref (file
);
489 found_line
= mi
->line
;
494 IAnjutaIterable
* start
= ianjuta_editor_get_position_from_offset (fb
->te
, mi
->pos
- offset
, NULL
);
495 IAnjutaIterable
* end
= ianjuta_editor_get_position_from_offset (fb
->te
, mi
->pos
- offset
+ mi
->len
, NULL
);
496 ianjuta_editor_selection_set(IANJUTA_EDITOR_SELECTION (fb
->te
),
500 g_object_unref (start
);
501 g_object_unref (end
);
504 modify_label_image_button(SEARCH_BUTTON
, _("Replace"),
505 GTK_STOCK_FIND_AND_REPLACE
);
506 show_jump_button(TRUE
);
507 if (sr
->replace
.regex
&& sr
->search
.expr
.regex
)
510 ch
= regex_backref (mi
, fb
);
515 if (ch
&& sr
->replace
.regex
&& sr
->search
.expr
.regex
)
517 g_free (sr
->replace
.repl_str
);
518 sr
->replace
.repl_str
= g_strdup (ch
);
523 IAnjutaIterable
* start
= ianjuta_editor_get_position_from_offset (fb
->te
, mi
->pos
- os
, NULL
);
524 IAnjutaIterable
* end
= ianjuta_editor_get_position_from_offset (fb
->te
, mi
->pos
+ mi
->len
- os
, NULL
);
525 ianjuta_editor_selection_set(IANJUTA_EDITOR_SELECTION (fb
->te
),
529 ianjuta_editor_selection_replace(IANJUTA_EDITOR_SELECTION (fb
->te
),
530 sr
->replace
.repl_str
,
531 strlen(sr
->replace
.repl_str
),
533 g_object_unref (start
);
534 g_object_unref (end
);
536 if (se
->direction
!= SD_BACKWARD
)
537 offset
+= mi
->len
- (sr
->replace
.repl_str
?strlen(sr
->replace
.repl_str
):0);
544 if (sr
->replace
.regex
&& sr
->search
.expr
.regex
)
546 regx_pattern
= sr
->replace
.repl_str
; /* preserve for later matches */
547 sr
->replace
.repl_str
= regex_backref (mi
, fb
);
551 if (fb
->te
== NULL
) /* NON OPENED FILES */
553 if (replace_in_not_opened_files(fb
, mi
, sr
->replace
.repl_str
))
558 IAnjutaIterable
* start
= ianjuta_editor_get_position_from_offset (fb
->te
, mi
->pos
- offset
, NULL
);
559 IAnjutaIterable
* end
= ianjuta_editor_get_position_from_offset (fb
->te
, mi
->pos
+ mi
->len
- offset
, NULL
);
560 ianjuta_editor_selection_set(IANJUTA_EDITOR_SELECTION (fb
->te
),
564 ianjuta_editor_selection_replace(IANJUTA_EDITOR_SELECTION (fb
->te
),
565 sr
->replace
.repl_str
,
566 strlen(sr
->replace
.repl_str
),
568 g_object_unref (start
);
569 g_object_unref (end
);
571 if (se
->direction
!= SD_BACKWARD
)
572 offset
+= mi
->len
- (sr
->replace
.repl_str
?strlen(sr
->replace
.repl_str
):0);
575 g_free (sr
->replace
.repl_str
);
576 sr
->replace
.repl_str
= regx_pattern
;
581 g_warning ("Not implemented - File %s - Line %d\n", __FILE__
, __LINE__
);
585 if (se
->direction
!= SD_BACKWARD
)
586 start_sel
= mi
->pos
+ mi
->len
- offset
;
588 start_sel
= mi
->pos
- offset
;
590 if (SA_REPLACE
!= s
->action
|| !interactive
)
593 if (SA_SELECT
== s
->action
||
594 ((SA_REPLACE
== s
->action
|| SA_REPLACEALL
== s
->action
) && interactive
))
599 save_not_opened_files (fb
);
604 file_buffer_free (fb
);
608 if (SA_SELECT
== s
->action
&& nb_results
> 0)
612 gtk_widget_set_sensitive (sr_get_gladewidget(STOP_BUTTON
)->widget
, FALSE
);
614 if (s
->range
.type
== SR_BLOCK
|| s
->range
.type
== SR_FUNCTION
||
615 s
->range
.type
== SR_SELECTION
)
619 g_list_free (entries
);
621 if (s
->action
== SA_FIND_PANE
)
623 ianjuta_message_view_append (view
, IANJUTA_MESSAGE_VIEW_TYPE_INFO
,
624 _("Search complete"), "", NULL
);
629 search_end_alert(sr
->search
.expr
.search_str
);
631 else if (nb_results
> sr
->search
.expr
.actions_max
)
633 else if (s
->action
== SA_REPLACEALL
)
634 nb_results_alert(nb_results
);
636 if ((s
->range
.direction
== SD_BEGINNING
) &&
637 ((s
->action
== SA_SELECT
) || (s
->action
== SA_REPLACE
)) )
639 search_set_direction(SD_FORWARD
);
644 write_message_pane(IAnjutaMessageView
* view
, FileBuffer
*fb
, SearchEntry
*se
,
651 match_line
= file_match_line_from_pos(fb
, mi
->pos
);
653 if (SE_BUFFER
== se
->type
)
655 /* DEBUG_PRINT ("FBPATH %s\n", fb->path); */
656 const gchar
* filename
= ianjuta_document_get_filename(IANJUTA_DOCUMENT(se
->te
), NULL
);
657 tmp
= g_strrstr(fb
->path
, "/");
658 tmp
= g_strndup(fb
->path
, tmp
+ 1 -(fb
->path
));
659 snprintf(buf
, BUFSIZ
, "%s%s:%d:%s\n", tmp
, filename
,
660 mi
->line
, match_line
);
663 else /* if (SE_FILE == se->type) */
665 snprintf(buf
, BUFSIZ
, "%s:%d:%s\n", se
->path
, mi
->line
+ 1, match_line
);
668 ianjuta_message_view_buffer_append (view
, buf
, NULL
);
672 on_message_view_destroyed (gpointer unused
, GObject
* where_the_object_was
)
678 on_message_buffer_flush (IAnjutaMessageView
*view
, const gchar
*one_line
,
681 ianjuta_message_view_append (view
, IANJUTA_MESSAGE_VIEW_TYPE_NORMAL
,
686 on_message_clicked (GObject
* object
, gchar
* message
, gpointer data
)
693 if (!(ptr
= g_strstr_len(message
, strlen(message
), ":")) )
695 path
= g_strndup(message
, ptr
- message
);
698 if (!(ptr2
= g_strstr_len(ptr
, strlen(ptr
), ":")) )
700 nline
= g_strndup(ptr
, ptr2
- ptr
);
703 file
= g_file_new_for_path (path
);
704 ianjuta_document_manager_goto_file_line_mark (sr
->docman
, file
, line
, TRUE
, NULL
);
705 g_object_unref (file
);
712 save_not_opened_files(FileBuffer
*fb
)
716 fp
= fopen(fb
->path
, "wb");
719 fwrite(fb
->buf
, fb
->len
, 1, fp
);
724 replace_in_not_opened_files(FileBuffer
*fb
, MatchInfo
*mi
, gchar
*repl_str
)
727 g_return_val_if_fail (repl_str
!= NULL
, FALSE
);
729 if (strlen(repl_str
) > mi
->len
)
731 l
= fb
->len
- mi
->pos
;
732 fb
->len
= fb
->len
+ strlen(repl_str
) - mi
->len
;
733 if ( (fb
->buf
= g_realloc(fb
->buf
, fb
->len
)) == NULL
)
735 memmove((fb
->buf
) + mi
->pos
+ strlen(repl_str
) - mi
->len
, fb
->buf
+ mi
->pos
,l
);
737 if (strlen(repl_str
) < mi
->len
)
739 l
= fb
->len
- mi
->pos
- mi
->len
;
740 memmove((fb
->buf
) + mi
->pos
+ strlen(repl_str
), fb
->buf
+ mi
->pos
+ mi
->len
,l
);
741 fb
->len
= fb
->len
+ strlen(repl_str
) - mi
->len
;
742 if ( (fb
->buf
= g_realloc(fb
->buf
, fb
->len
)) == NULL
)
746 for (l
=0; l
< strlen(repl_str
); l
++)
747 (fb
->buf
)[(mi
->pos
)+l
] = repl_str
[l
];
754 search_replace_next_previous(SearchDirection dir
)
756 SearchDirection save_direction
;
757 SearchAction save_action
;
758 SearchRangeType save_type
;
762 save_action
= sr
->search
.action
;
763 save_type
= sr
->search
.range
.type
;
764 save_direction
= sr
->search
.range
.direction
;
765 sr
->search
.range
.direction
= dir
;
766 if (save_type
== SR_OPEN_BUFFERS
|| save_type
== SR_PROJECT
||
767 save_type
== SR_FILES
)
768 sr
->search
.range
.direction
= SR_BUFFER
;
769 sr
->search
.action
= SA_SELECT
;
771 search_and_replace();
773 sr
->search
.action
= save_action
;
774 sr
->search
.range
.type
= save_type
;
775 sr
->search
.range
.direction
= save_direction
;
779 DEBUG_PRINT ("sr null\n");
784 search_replace_next(void)
786 search_replace_next_previous(SD_FORWARD
);
790 search_replace_previous(void)
792 search_replace_next_previous(SD_BACKWARD
);
795 /****************************************************************/
798 sr_get_gladewidget(GladeWidgetId id
)
800 return &glade_widgets
[id
];
804 search_set_popdown_strings (GtkComboBoxEntry
*combo
, GList
* strings
)
809 init
= gtk_combo_box_get_model (GTK_COMBO_BOX(combo
)) == NULL
;
811 store
= gtk_list_store_new (1, G_TYPE_STRING
);
812 for (; strings
!= NULL
; strings
= g_list_next(strings
))
816 gtk_list_store_append (store
, &iter
);
817 gtk_list_store_set (store
, &iter
, 0, strings
->data
, -1);
819 gtk_combo_box_set_model (GTK_COMBO_BOX(combo
), GTK_TREE_MODEL (store
));
820 g_object_unref (store
);
822 if (init
) gtk_combo_box_entry_set_text_column (combo
, 0);
826 search_set_popdown_map (GtkComboBox
*combo
, AnjutaUtilStringMap
*map
)
832 init
= gtk_combo_box_get_model (combo
) == NULL
;
834 store
= gtk_list_store_new (2, G_TYPE_STRING
, G_TYPE_INT
);
835 for (i
= 0; map
[i
].type
!= -1; ++i
)
839 gtk_list_store_append (store
, &iter
);
840 gtk_list_store_set (store
, &iter
, 0, map
[i
].name
, 1, map
[i
].type
, -1);
842 gtk_combo_box_set_model (combo
, GTK_TREE_MODEL (store
));
843 g_object_unref (store
);
844 gtk_combo_box_set_active (combo
, 0);
848 GtkCellRenderer
*cell
;
850 cell
= gtk_cell_renderer_text_new ();
851 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo
), cell
, TRUE
);
852 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo
), cell
,
858 search_select_item(GtkComboBox
* combo
, gint item
)
864 model
= gtk_combo_box_get_model(combo
);
866 /* Find item corresponding to command */
867 for (search
= gtk_tree_model_get_iter_first(model
, &iter
); search
;
868 gtk_tree_model_iter_next (model
, &iter
))
872 gtk_tree_model_get (model
, &iter
, 1, &id
, -1);
877 gtk_combo_box_set_active_iter(combo
, &iter
);
885 search_set_combo(GladeWidgetId id_combo
, gint command
)
889 combo
= GTK_COMBO_BOX(sr_get_gladewidget(id_combo
)->widget
);
890 search_select_item (combo
, command
);
894 search_set_action(SearchAction action
)
896 search_set_combo(SEARCH_ACTION_COMBO
, action
);
900 search_set_target(SearchRangeType target
)
902 search_set_combo(SEARCH_TARGET_COMBO
, target
);
906 search_set_direction(SearchDirection dir
)
908 search_set_combo(SEARCH_DIRECTION_COMBO
, dir
);
912 search_get_item_combo(GtkComboBox
*combo
)
919 sel
= gtk_combo_box_get_active_iter (combo
, &iter
);
920 model
= gtk_combo_box_get_model (combo
);
921 gtk_tree_model_get (model
, &iter
, 1, &item
, -1);
927 search_get_item_combo_name(GladeWidgetId id
)
929 GtkWidget
*combo
= sr_get_gladewidget(id
)->widget
;
930 return search_get_item_combo(GTK_COMBO_BOX(combo
));
934 search_direction_changed(SearchDirection dir
)
939 tgt
= search_get_item_combo_name(SEARCH_TARGET_COMBO
);
940 if (dir
!= SD_BEGINNING
)
942 if (tgt
== SR_OPEN_BUFFERS
|| tgt
== SR_PROJECT
944 search_set_target(SR_BUFFER
);
948 if (tgt
== SR_BUFFER
||tgt
== SR_SELECTION
|| tgt
== SR_BLOCK
||
950 search_set_target(SR_BUFFER
);
953 act
= search_get_item_combo_name(SEARCH_ACTION_COMBO
);
954 if (act
== SA_SELECT
)
955 search_set_action(SA_BOOKMARK
);
956 if (act
== SA_REPLACE
)
957 search_set_action(SA_REPLACEALL
);
963 populate_value(GladeWidgetId id
, gpointer val_ptr
)
967 g_return_if_fail(id
&& val_ptr
);
969 gw
= sr_get_gladewidget(id
);
970 g_return_if_fail(gw
);
975 if (*((char **) val_ptr
))
976 g_free(* ((char **) val_ptr
));
977 *((char **) val_ptr
) = gtk_editable_get_chars(
978 GTK_EDITABLE(gw
->widget
), 0, -1);
981 * ((gboolean
*) val_ptr
) = gtk_toggle_button_get_active(
982 GTK_TOGGLE_BUTTON(gw
->widget
));
985 g_return_if_fail (gw
->extra
!= NULL
);
987 *((int *) val_ptr
) = search_get_item_combo (GTK_COMBO_BOX(gw
->widget
));
990 g_warning("Bad option %d to populate_value", gw
->type
);
1003 reset_flags_and_search_button(void)
1006 if (sr
->search
.action
!= SA_REPLACEALL
)
1007 modify_label_image_button(SEARCH_BUTTON
, _("Search"), GTK_STOCK_FIND
);
1010 modify_label_image_button(SEARCH_BUTTON
, _("Replace All"),
1011 GTK_STOCK_FIND_AND_REPLACE
);
1013 show_jump_button(FALSE
);
1017 search_start_over (SearchDirection direction
)
1019 IAnjutaDocument
* doc
= ianjuta_document_manager_get_current_document(sr
->docman
,
1021 IAnjutaEditor
*te
= NULL
;
1022 if (IANJUTA_IS_EDITOR(doc
))
1023 te
= IANJUTA_EDITOR(doc
);
1027 if (direction
!= SD_BACKWARD
)
1028 /* search from doc start */
1029 ianjuta_editor_goto_start (te
, NULL
);
1031 /* search from doc end */
1032 ianjuta_editor_goto_end (te
, NULL
);
1037 search_end_alert(gchar
*string
)
1041 if (sr
->search
.range
.direction
!= SD_BEGINNING
&& !flag_select
)
1043 // Ask if user wants to wrap around the doc
1044 // Dialog to be made HIG compliant.
1045 dialog
= gtk_message_dialog_new (GTK_WINDOW (sg
->dialog
),
1046 GTK_DIALOG_DESTROY_WITH_PARENT
,
1047 GTK_MESSAGE_QUESTION
,
1049 _("The match \"%s\" was not found. Wrap search around the document?"),
1052 gtk_dialog_set_default_response (GTK_DIALOG (dialog
),
1054 g_signal_connect(G_OBJECT(dialog
), "key-press-event",
1055 G_CALLBACK(on_search_dialog_key_press_event
), NULL
);
1056 if (gtk_dialog_run (GTK_DIALOG (dialog
)) == GTK_RESPONSE_YES
)
1058 search_start_over (sr
->search
.range
.direction
);
1059 gtk_widget_destroy(dialog
);
1061 search_and_replace ();
1067 dialog
= gtk_message_dialog_new(GTK_WINDOW (sg
->dialog
),
1068 GTK_DIALOG_MODAL
, GTK_MESSAGE_WARNING
, GTK_BUTTONS_OK
,
1069 _("The match \"%s\" was not found."),
1071 g_signal_connect(G_OBJECT(dialog
), "key-press-event",
1072 G_CALLBACK(on_search_dialog_key_press_event
), NULL
);
1073 gtk_dialog_run(GTK_DIALOG(dialog
));
1075 gtk_widget_destroy(dialog
);
1080 max_results_alert(void)
1082 GtkWidget
*dialog
= gtk_message_dialog_new(GTK_WINDOW (sg
->dialog
),
1083 GTK_DIALOG_MODAL
, GTK_MESSAGE_WARNING
, GTK_BUTTONS_OK
,
1084 _("The maximum number of results has been reached."));
1085 g_signal_connect(G_OBJECT(dialog
), "key-press-event",
1086 G_CALLBACK(on_search_dialog_key_press_event
), NULL
);
1087 gtk_dialog_run(GTK_DIALOG(dialog
));
1088 gtk_widget_destroy(dialog
);
1093 nb_results_alert(gint nb
)
1095 GtkWidget
*dialog
= gtk_message_dialog_new(GTK_WINDOW (sg
->dialog
),
1096 GTK_DIALOG_MODAL
, GTK_MESSAGE_INFO
, GTK_BUTTONS_OK
,
1097 ngettext("%d match has been replaced.",
1098 "%d matches have been replaced.", nb
), nb
);
1099 g_signal_connect(G_OBJECT(dialog
), "key-press-event",
1100 G_CALLBACK(on_search_dialog_key_press_event
), NULL
);
1101 gtk_dialog_run(GTK_DIALOG(dialog
));
1102 gtk_widget_destroy(dialog
);
1107 search_show_replace(gboolean hide
)
1109 static GladeWidgetId hide_widgets
[] = {
1110 REPLACE_REGEX
, REPLACE_STRING_COMBO
, LABEL_REPLACE
1115 for (i
=0; i
< sizeof(hide_widgets
)/sizeof(hide_widgets
[0]); ++i
)
1117 widget
= sr_get_gladewidget(hide_widgets
[i
])->widget
;
1121 gtk_widget_show(widget
);
1123 gtk_widget_hide(widget
);
1129 modify_label_image_button(GladeWidgetId button_id
, gchar
*name
, char *stock_image
)
1133 GtkWidget
*alignment
;
1134 GtkWidget
*button
= sr_get_gladewidget(button_id
)->widget
;
1136 list
= gtk_container_get_children(GTK_CONTAINER (button
));
1137 alignment
= GTK_WIDGET(list
->data
);
1139 list
= gtk_container_get_children(GTK_CONTAINER (alignment
));
1140 hbox
= GTK_HBOX(list
->data
);
1142 list
= gtk_container_get_children(GTK_CONTAINER (hbox
));
1143 for (l
=list
; l
; l
= g_list_next(l
))
1145 if (GTK_IS_LABEL(l
->data
))
1146 gtk_label_set_text(GTK_LABEL(l
->data
), name
);
1147 if (GTK_IS_IMAGE(l
->data
))
1148 gtk_image_set_from_stock(GTK_IMAGE(l
->data
), stock_image
,
1149 GTK_ICON_SIZE_BUTTON
);
1155 /********************************************************************/
1157 #define POP_LIST(str, var) populate_value(str, &s);\
1160 sr->search.range.files.var = anjuta_util_glist_from_string(s);\
1163 /********************************************************************/
1166 search_replace_populate(void)
1171 /* Now, populate the instance with values from the GUI */
1172 populate_value(SEARCH_STRING
, &(sr
->search
.expr
.search_str
));
1173 populate_value(SEARCH_REGEX
, &(sr
->search
.expr
.regex
));
1174 populate_value(GREEDY
, &(sr
->search
.expr
.greedy
));
1175 populate_value(IGNORE_CASE
, &(sr
->search
.expr
.ignore_case
));
1176 populate_value(WHOLE_WORD
, &(sr
->search
.expr
.whole_word
));
1177 populate_value(WHOLE_LINE
, &(sr
->search
.expr
.whole_line
));
1178 populate_value(WORD_START
, &(sr
->search
.expr
.word_start
));
1179 populate_value(SEARCH_TARGET_COMBO
, &(sr
->search
.range
.type
));
1180 populate_value(SEARCH_DIRECTION_COMBO
, &(sr
->search
.range
.direction
));
1181 populate_value(ACTIONS_NO_LIMIT
, &(sr
->search
.expr
.no_limit
));
1183 populate_value(SEARCH_BASIC
, &(sr
->search
.basic_search
));
1185 if (sr
->search
.expr
.no_limit
)
1186 sr
->search
.expr
.actions_max
= G_MAXINT
;
1189 populate_value(ACTIONS_MAX
, &(max
));
1190 sr
->search
.expr
.actions_max
= atoi(max
);
1191 if (sr
->search
.expr
.actions_max
<= 0)
1192 sr
->search
.expr
.actions_max
= 200;
1196 switch (sr
->search
.range
.type
)
1201 sr
->search
.range
.type
= SR_SELECTION
;
1204 POP_LIST(MATCH_FILES
, match_files
);
1205 POP_LIST(UNMATCH_FILES
, ignore_files
);
1206 POP_LIST(MATCH_DIRS
, match_dirs
);
1207 POP_LIST(UNMATCH_DIRS
, ignore_dirs
);
1208 populate_value(IGNORE_HIDDEN_FILES
, &(sr
->search
.range
.files
.ignore_hidden_files
));
1209 populate_value(IGNORE_HIDDEN_DIRS
, &(sr
->search
.range
.files
.ignore_hidden_dirs
));
1210 populate_value(SEARCH_RECURSIVE
, &(sr
->search
.range
.files
.recurse
));
1215 populate_value(SEARCH_ACTION_COMBO
, &(sr
->search
.action
));
1216 switch (sr
->search
.action
)
1220 populate_value(REPLACE_STRING
, &(sr
->replace
.repl_str
));
1221 populate_value(REPLACE_REGEX
, &(sr
->replace
.regex
));
1229 show_jump_button (gboolean show
)
1231 GtkWidget
*jump_button
= sr_get_gladewidget(JUMP_BUTTON
)->widget
;
1233 gtk_widget_show(jump_button
);
1235 gtk_widget_hide(jump_button
);
1239 void translate_dialog_strings (AnjutaUtilStringMap labels
[])
1242 while (labels
[i
].name
!= NULL
)
1244 labels
[i
].name
= gettext (labels
[i
].name
);
1256 g_return_val_if_fail(NULL
!= sr
, FALSE
);
1257 if (NULL
!= sg
) return TRUE
;
1258 sg
= g_new0(SearchReplaceGUI
, 1);
1260 if (NULL
== (sg
->xml
= glade_xml_new(GLADE_FILE_SEARCH_REPLACE
,
1261 SEARCH_REPLACE_DIALOG
, NULL
)))
1263 anjuta_util_dialog_error(NULL
, _("Unable to build user interface for Search And Replace"));
1268 sg
->dialog
= glade_xml_get_widget(sg
->xml
, SEARCH_REPLACE_DIALOG
);
1269 /* gtk_window_set_transient_for (GTK_WINDOW(sg->dialog)
1270 , GTK_WINDOW(app->widgets.window)); */
1272 if (!labels_translated
)
1274 labels_translated
= TRUE
;
1275 translate_dialog_strings (search_direction_strings
);
1276 translate_dialog_strings (search_target_strings
);
1277 translate_dialog_strings (search_action_strings
);
1280 for (i
=0; NULL
!= glade_widgets
[i
].name
; ++i
)
1282 w
= &(glade_widgets
[i
]);
1283 w
->widget
= glade_xml_get_widget(sg
->xml
, w
->name
);
1284 if (GE_COMBO_ENTRY
== w
->type
)
1286 /* Get child of GtkComboBoxEntry */
1287 w
->widget
= GTK_BIN(w
->widget
)->child
;
1289 gtk_widget_ref(w
->widget
);
1290 if (GE_COMBO
== w
->type
&& NULL
!= w
->extra
)
1292 search_set_popdown_map(GTK_COMBO_BOX(w
->widget
), (AnjutaUtilStringMap
*)w
->extra
);
1296 widget
= sr_get_gladewidget(SEARCH_STRING_COMBO
)->widget
;
1297 g_signal_connect (widget
, "changed", G_CALLBACK (on_search_expression_changed
), NULL
);
1298 widget
= sr_get_gladewidget(SEARCH_STRING
)->widget
;
1299 g_signal_connect (widget
, "activate", G_CALLBACK (on_search_expression_activate
), NULL
);
1300 widget
= sr_get_gladewidget(REPLACE_STRING
)->widget
;
1301 g_signal_connect (widget
, "activate", G_CALLBACK (on_search_expression_activate
), NULL
);
1302 widget
= sr_get_gladewidget(SEARCH_ACTION_COMBO
)->widget
;
1303 g_signal_connect (widget
, "changed", G_CALLBACK (on_search_action_changed
), NULL
);
1304 widget
= sr_get_gladewidget(SEARCH_DIRECTION_COMBO
)->widget
;
1305 g_signal_connect (widget
, "changed", G_CALLBACK (on_search_direction_changed
), NULL
);
1306 widget
= sr_get_gladewidget(SEARCH_TARGET_COMBO
)->widget
;
1307 g_signal_connect (widget
, "changed", G_CALLBACK (on_search_target_changed
), NULL
);
1310 search_preferences_initialize_setting_treeview(sg
->dialog
);
1311 search_preferences_init();
1313 glade_xml_signal_autoconnect(sg
->xml
);
1320 gtk_window_present (GTK_WINDOW (sg
->dialog
));
1325 word_in_list(GList
*list
, gchar
*word
)
1331 if (strcmp(l
->data
, word
) == 0)
1338 /* Remove last item of the list if > nb_max */
1341 list_max_items(GList
*list
, guint nb_max
)
1345 if (g_list_length(list
) > nb_max
)
1347 last
= g_list_last(list
);
1349 list
= g_list_delete_link (list
, last
);
1354 #define MAX_ITEMS_SEARCH_COMBO 16
1357 search_update_combos(void)
1359 GtkWidget
*search_entry
= NULL
;
1360 gchar
*search_word
= NULL
;
1361 IAnjutaDocument
* doc
= ianjuta_document_manager_get_current_document(sr
->docman
,
1363 IAnjutaEditor
*te
= NULL
;
1364 if (IANJUTA_IS_EDITOR(doc
))
1365 te
= IANJUTA_EDITOR(doc
);
1367 search_entry
= sr_get_gladewidget(SEARCH_STRING
)->widget
;
1368 if (search_entry
&& te
)
1370 search_word
= g_strdup(gtk_entry_get_text(GTK_ENTRY (search_entry
)));
1371 if (search_word
&& strlen(search_word
) > 0)
1373 if (!word_in_list(sr
->search
.expr_history
, search_word
))
1375 GtkWidget
*search_list
=
1376 sr_get_gladewidget(SEARCH_STRING_COMBO
)->widget
;
1377 sr
->search
.expr_history
= g_list_prepend(sr
->search
.expr_history
,
1379 sr
->search
.expr_history
= list_max_items(sr
->search
.expr_history
,
1380 MAX_ITEMS_SEARCH_COMBO
);
1381 search_set_popdown_strings(GTK_COMBO_BOX_ENTRY (search_list
),
1382 sr
->search
.expr_history
);
1384 //search_toolbar_set_text(search_word);
1385 // FIXME comboentry instead of entry
1386 //~ entry_set_text_n_select (app->widgets.toolbar.main_toolbar.find_entry,
1387 //~ search_word, FALSE);
1394 replace_update_combos(void)
1396 GtkWidget
*replace_entry
= NULL
;
1397 gchar
*replace_word
= NULL
;
1398 IAnjutaDocument
* doc
= ianjuta_document_manager_get_current_document(sr
->docman
,
1400 IAnjutaEditor
*te
= NULL
;
1401 if (IANJUTA_IS_EDITOR(doc
))
1402 te
= IANJUTA_EDITOR(doc
);
1404 replace_entry
= sr_get_gladewidget(REPLACE_STRING
)->widget
;
1405 if (replace_entry
&& te
)
1407 replace_word
= g_strdup(gtk_entry_get_text(GTK_ENTRY (replace_entry
)));
1408 if (replace_word
&& strlen(replace_word
) > 0)
1410 if (!word_in_list(sr
->replace
.expr_history
, replace_word
))
1412 GtkWidget
*replace_list
=
1413 sr_get_gladewidget(REPLACE_STRING_COMBO
)->widget
;
1414 sr
->replace
.expr_history
= g_list_prepend(sr
->replace
.expr_history
,
1416 sr
->replace
.expr_history
= list_max_items(sr
->replace
.expr_history
,
1417 MAX_ITEMS_SEARCH_COMBO
);
1418 search_set_popdown_strings(GTK_COMBO_BOX_ENTRY (replace_list
),
1419 sr
->replace
.expr_history
);
1426 search_update_dialog(void)
1432 widget
= sr_get_gladewidget(SEARCH_REGEX
)->widget
;
1433 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->expr
.regex
);
1434 widget
= sr_get_gladewidget(GREEDY
)->widget
;
1435 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->expr
.greedy
);
1436 widget
= sr_get_gladewidget(IGNORE_CASE
)->widget
;
1437 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->expr
.ignore_case
);
1438 widget
= sr_get_gladewidget(WHOLE_WORD
)->widget
;
1439 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->expr
.whole_word
);
1440 widget
= sr_get_gladewidget(WHOLE_LINE
)->widget
;
1441 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->expr
.whole_line
);
1442 widget
= sr_get_gladewidget(WORD_START
)->widget
;
1443 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->expr
.word_start
);
1445 widget
= sr_get_gladewidget(ACTIONS_NO_LIMIT
)->widget
;
1446 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->expr
.no_limit
);
1447 widget
= sr_get_gladewidget(ACTIONS_MAX
)->widget
;
1448 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget
), s
->expr
.actions_max
);
1449 gtk_widget_set_sensitive (widget
, !s
->expr
.no_limit
);
1451 widget
= sr_get_gladewidget(REPLACE_REGEX
)->widget
;
1452 gtk_widget_set_sensitive(widget
, sr
->search
.expr
.regex
);
1454 widget
= sr_get_gladewidget(SEARCH_BUTTON
)->widget
;
1455 gtk_widget_set_sensitive (widget
, (s
->expr
.search_str
!= NULL
) && (*s
->expr
.search_str
!= '\0'));
1457 widget
= sr_get_gladewidget(SEARCH_STRING
)->widget
;
1458 if (s
->expr
.search_str
)
1459 gtk_entry_set_text(GTK_ENTRY(widget
), s
->expr
.search_str
);
1461 widget
= sr_get_gladewidget(SEARCH_DIRECTION_COMBO
)->widget
;
1462 search_select_item (GTK_COMBO_BOX(widget
), s
->range
.direction
);
1464 widget
= sr_get_gladewidget(SEARCH_ACTION_COMBO
)->widget
;
1465 search_select_item (GTK_COMBO_BOX(widget
), s
->action
);
1467 search_show_replace(s
->action
== SA_REPLACE
|| s
->action
== SA_REPLACEALL
);
1469 widget
= sr_get_gladewidget(SEARCH_TARGET_COMBO
)->widget
;
1470 search_select_item (GTK_COMBO_BOX(widget
), s
->range
.type
);
1472 widget
= sr_get_gladewidget(SEARCH_BASIC
)->widget
;
1473 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), s
->basic_search
);
1475 widget
= sr_get_gladewidget(STOP_BUTTON
)->widget
;
1476 gtk_widget_set_sensitive (widget
, FALSE
);
1478 basic_search_toggled();
1481 /* -------------- Callbacks --------------------- */
1484 on_search_replace_delete_event(GtkWidget
*window
, GdkEvent
*event
,
1489 gtk_widget_hide(sg
->dialog
);
1490 sg
->showing
= FALSE
;
1496 on_search_dialog_key_press_event(GtkWidget
*widget
, GdkEventKey
*event
,
1499 if (event
->keyval
== GDK_Escape
)
1503 /* Escape pressed in Find window */
1504 gtk_widget_hide(widget
);
1505 sg
->showing
= FALSE
;
1509 /* Escape pressed in wrap yes/no window */
1510 gtk_dialog_response (GTK_DIALOG (widget
), GTK_RESPONSE_NO
);
1516 if ( (event
->state
& GDK_CONTROL_MASK
) &&
1517 ((event
->keyval
& 0x5F) == GDK_G
))
1519 if (event
->state
& GDK_SHIFT_MASK
)
1520 search_replace_previous();
1522 search_replace_next();
1529 search_disconnect_set_toggle_connect(GladeWidgetId id
, GCallback function
,
1534 button
= sr_get_gladewidget(id
)->widget
;
1535 g_signal_handlers_disconnect_by_func(G_OBJECT(button
), function
, NULL
);
1536 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button
), active
);
1537 g_signal_connect(G_OBJECT(button
), "toggled", function
, NULL
);
1542 on_search_match_whole_word_toggled (GtkToggleButton
*togglebutton
,
1545 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton
)))
1547 search_disconnect_set_toggle_connect(WHOLE_LINE
, (GCallback
)
1548 on_search_match_whole_line_toggled
, FALSE
);
1549 search_disconnect_set_toggle_connect(WORD_START
, (GCallback
)
1550 on_search_match_word_start_toggled
, FALSE
);
1555 on_search_match_whole_line_toggled (GtkToggleButton
*togglebutton
,
1558 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton
)))
1560 search_disconnect_set_toggle_connect(WHOLE_WORD
, (GCallback
)
1561 on_search_match_whole_word_toggled
, FALSE
);
1562 search_disconnect_set_toggle_connect(WORD_START
, (GCallback
)
1563 on_search_match_word_start_toggled
, FALSE
);
1568 on_search_match_word_start_toggled (GtkToggleButton
*togglebutton
,
1571 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton
)))
1573 search_disconnect_set_toggle_connect(WHOLE_WORD
, (GCallback
)
1574 on_search_match_whole_word_toggled
, FALSE
);
1575 search_disconnect_set_toggle_connect(WHOLE_LINE
, (GCallback
)
1576 on_search_match_whole_line_toggled
, FALSE
);
1582 search_make_sensitive(gboolean sensitive)
1584 static char *widgets[] = {
1585 SEARCH_EXPR_FRAME, SEARCH_TARGET_FRAME, CLOSE_BUTTON, SEARCH_BUTTON,
1591 for (i=0; i < sizeof(widgets)/sizeof(widgets[0]); ++i)
1593 widget = sr_get_gladewidget(widgets[i])->widget;
1595 gtk_widget_set_sensitive(widget, sensitive);
1601 on_search_regex_toggled (GtkToggleButton
*togglebutton
, gpointer user_data
)
1603 static GladeWidgetId dependent_widgets
[] = {
1604 WHOLE_WORD
, WHOLE_LINE
, WORD_START
,
1605 SEARCH_BACKWARD
, SEARCH_FULL_BUFFER
1608 GtkWidget
*dircombo
= sr_get_gladewidget(SEARCH_DIRECTION_COMBO
)->widget
;
1609 GtkWidget
*repl_regex
= sr_get_gladewidget(REPLACE_REGEX
)->widget
;
1611 gboolean state
= gtk_toggle_button_get_active(togglebutton
);
1615 search_set_direction(SD_FORWARD
);
1618 gtk_widget_set_sensitive(dircombo
, !state
);
1619 gtk_widget_set_sensitive(repl_regex
, state
);
1621 for (i
=0; i
< sizeof(dependent_widgets
)/sizeof(dependent_widgets
[0]); ++i
)
1623 widget
= sr_get_gladewidget(dependent_widgets
[i
])->widget
;
1626 gtk_widget_set_sensitive(widget
, !state
);
1627 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget
), FALSE
);
1633 search_set_toggle_direction(SearchDirection dir
)
1638 search_disconnect_set_toggle_connect(SEARCH_FORWARD
, (GCallback
)
1639 on_search_forward_toggled
, TRUE
);
1642 search_disconnect_set_toggle_connect(SEARCH_BACKWARD
, (GCallback
)
1643 on_search_backward_toggled
, TRUE
);
1646 search_disconnect_set_toggle_connect(SEARCH_FULL_BUFFER
, (GCallback
)
1647 on_search_full_buffer_toggled
, TRUE
);
1653 on_search_direction_changed (GtkComboBox
*combo
, gpointer user_data
)
1655 SearchDirection dir
;
1657 dir
= search_get_item_combo(combo
);
1658 search_set_toggle_direction(dir
);
1659 search_direction_changed(dir
);
1663 on_search_action_changed (GtkComboBox
*combo
, gpointer user_data
)
1669 act
= search_get_item_combo(combo
);
1670 rt
= search_get_item_combo_name(SEARCH_TARGET_COMBO
);
1671 show_jump_button (FALSE
);
1675 search_show_replace(FALSE
);
1676 modify_label_image_button(SEARCH_BUTTON
, _("Search"), GTK_STOCK_FIND
);
1677 if (rt
== SR_OPEN_BUFFERS
|| rt
== SR_PROJECT
||
1679 search_set_target(SR_BUFFER
);
1682 search_show_replace(TRUE
);
1683 modify_label_image_button(SEARCH_BUTTON
, _("Search"), GTK_STOCK_FIND
);
1684 if (rt
== SR_OPEN_BUFFERS
|| rt
== SR_PROJECT
||
1686 search_set_target(SR_BUFFER
);
1689 search_show_replace(TRUE
);
1690 modify_label_image_button(SEARCH_BUTTON
, _("Replace All"),
1691 GTK_STOCK_FIND_AND_REPLACE
);
1694 search_show_replace(FALSE
);
1695 modify_label_image_button(SEARCH_BUTTON
, _("Search"), GTK_STOCK_FIND
);
1701 on_search_target_changed(GtkComboBox
*combo
, gpointer user_data
)
1703 SearchRangeType tgt
;
1704 SearchDirection dir
;
1706 GtkWidget
*search_var_frame
= sr_get_gladewidget(SEARCH_VAR_FRAME
)->widget
;
1707 GtkWidget
*file_filter_frame
= sr_get_gladewidget(FILE_FILTER_FRAME
)->widget
;
1709 tgt
= search_get_item_combo(combo
);
1713 gtk_widget_hide(search_var_frame
);
1714 gtk_widget_show(file_filter_frame
);
1717 gtk_widget_hide(search_var_frame
);
1718 gtk_widget_hide(file_filter_frame
);
1722 dir
= search_get_item_combo_name(SEARCH_DIRECTION_COMBO
);
1724 if (tgt
== SR_SELECTION
|| tgt
== SR_BLOCK
|| tgt
== SR_FUNCTION
)
1727 if (dir
== SD_BEGINNING
)
1729 search_set_direction(SD_FORWARD
);
1732 if (tgt
== SR_OPEN_BUFFERS
|| tgt
== SR_PROJECT
||
1735 search_set_direction(SD_BEGINNING
);
1737 act
= search_get_item_combo_name(SEARCH_ACTION_COMBO
);
1738 if (act
!= SA_REPLACE
&& act
!= SA_REPLACEALL
)
1740 if (tgt
== SR_OPEN_BUFFERS
)
1741 search_set_action(SA_BOOKMARK
);
1743 search_set_action(SA_FIND_PANE
);
1747 search_set_action(SA_REPLACEALL
);
1748 sr
->search
.action
= SA_REPLACEALL
;
1751 reset_flags_and_search_button();
1753 gtk_window_resize(GTK_WINDOW(sg
->dialog
), 10, 10);
1757 on_search_expression_changed(GtkComboBox
*combo
, gpointer user_data
)
1759 GtkWidget
*search_entry
= sr_get_gladewidget(SEARCH_STRING
)->widget
;
1760 GtkWidget
*widget
= sr_get_gladewidget(SEARCH_BUTTON
)->widget
;
1763 sensitive
= *gtk_entry_get_text (GTK_ENTRY (search_entry
)) == '\0' ? FALSE
: TRUE
;
1764 gtk_widget_set_sensitive (widget
, sensitive
);
1769 on_actions_no_limit_clicked(GtkButton
*button
, gpointer user_data
)
1771 GtkWidget
*actions_max
= sr_get_gladewidget(ACTIONS_MAX
)->widget
;
1773 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button
)))
1774 gtk_widget_set_sensitive (actions_max
, FALSE
);
1776 gtk_widget_set_sensitive (actions_max
, TRUE
);
1780 on_search_button_close_clicked(GtkButton
*button
, gpointer user_data
)
1784 gtk_widget_hide(sg
->dialog
);
1785 sg
->showing
= FALSE
;
1790 on_search_button_stop_clicked(GtkButton
*button
, gpointer user_data
)
1792 end_activity
= TRUE
;
1796 on_search_button_next_clicked(GtkButton
*button
, gpointer user_data
)
1798 if (sr
->search
.expr
.regex_info
)
1800 g_regex_unref (sr
->search
.expr
.regex_info
);
1801 sr
->search
.expr
.regex_info
= NULL
;
1803 search_replace_populate();
1805 search_and_replace();
1808 void search_replace_find_usage(const gchar
*symbol
)
1810 gchar
*project_root_uri
= NULL
;
1811 SearchReplace
*old_sr
= sr
;
1814 sr
= g_new (SearchReplace
, 1);
1816 sr
->search
.expr
.search_str
= g_strdup (symbol
);
1817 sr
->search
.expr
.regex
= FALSE
;
1818 sr
->search
.expr
.greedy
= FALSE
;
1819 sr
->search
.expr
.ignore_case
= FALSE
;
1820 sr
->search
.expr
.whole_word
= TRUE
;
1821 sr
->search
.expr
.whole_line
= FALSE
;
1822 sr
->search
.expr
.word_start
= FALSE
;
1823 sr
->search
.expr
.no_limit
= TRUE
;
1824 sr
->search
.expr
.actions_max
= G_MAXINT
;
1825 sr
->search
.expr
.regex_info
= NULL
;
1827 g_object_get(G_OBJECT(sr
->docman
), "shell", &shell
, NULL
);
1829 anjuta_shell_get (shell
,
1830 "project_root_uri", G_TYPE_STRING
,
1831 &project_root_uri
, NULL
);
1833 sr
->search
.range
.type
=
1834 project_root_uri
!= NULL
? SR_PROJECT
: SR_OPEN_BUFFERS
;
1835 g_free (project_root_uri
);
1837 sr
->search
.range
.direction
= SD_BEGINNING
;
1839 sr
->search
.range
.var
= NULL
;
1841 sr
->search
.range
.files
.top_dir
= NULL
;
1842 sr
->search
.range
.files
.match_files
= NULL
;
1843 sr
->search
.range
.files
.match_dirs
= NULL
;
1844 sr
->search
.range
.files
.ignore_files
= NULL
;
1845 sr
->search
.range
.files
.ignore_dirs
= NULL
;
1846 sr
->search
.range
.files
.ignore_hidden_files
= TRUE
;
1847 sr
->search
.range
.files
.ignore_hidden_dirs
= TRUE
;
1848 sr
->search
.range
.files
.recurse
= TRUE
;
1850 sr
->search
.action
= SA_FIND_PANE
;
1852 sr
->search
.expr_history
= NULL
;
1853 sr
->search
.incremental_pos
= 0;
1854 sr
->search
.incremental_wrap
= TRUE
;
1858 search_and_replace();
1864 on_search_button_jump_clicked(GtkButton
*button
, gpointer user_data
)
1867 interactive
= FALSE
;
1868 gtk_widget_hide(GTK_WIDGET(button
));
1870 search_replace_populate();
1871 search_and_replace();
1875 on_search_expression_activate (GtkEditable
*edit
, gpointer user_data
)
1879 search_replace_populate();
1881 search_and_replace();
1882 combo
= GTK_WIDGET(edit
)->parent
;
1883 reset_flags_and_search_button();
1888 on_search_full_buffer_toggled (GtkToggleButton
*togglebutton
,
1891 if (gtk_toggle_button_get_active(togglebutton
))
1893 search_set_direction(SD_BEGINNING
);
1898 on_search_forward_toggled (GtkToggleButton
*togglebutton
,
1901 if (gtk_toggle_button_get_active(togglebutton
))
1903 search_set_direction(SD_FORWARD
);
1908 on_search_backward_toggled (GtkToggleButton
*togglebutton
,
1911 if (gtk_toggle_button_get_active(togglebutton
))
1913 search_set_direction(SD_BACKWARD
);
1918 on_setting_basic_search_toggled (GtkToggleButton
*togglebutton
,
1922 GtkWidget
*frame_basic
= sr_get_gladewidget(FRAME_SEARCH_BASIC
)->widget
;
1924 if (gtk_toggle_button_get_active(togglebutton
))
1926 gtk_widget_show(frame_basic
);
1927 search_set_target(SR_BUFFER
);
1928 search_set_direction(SD_FORWARD
);
1930 act
= search_get_item_combo_name(SEARCH_ACTION_COMBO
);
1931 if (act
== SA_REPLACE
|| act
== SA_REPLACEALL
)
1932 search_set_action(SA_REPLACE
);
1934 search_set_action(SA_SELECT
);
1937 gtk_widget_hide(frame_basic
);
1942 basic_search_toggled(void)
1944 GtkToggleButton
*togglebutton
;
1946 togglebutton
= GTK_TOGGLE_BUTTON(sr_get_gladewidget(SEARCH_BASIC
)->widget
);
1948 on_setting_basic_search_toggled (togglebutton
, NULL
);
1951 /***********************************************************************/
1953 #define MAX_LENGTH_SEARCH 64
1956 anjuta_search_replace_activate (gboolean replace
, gboolean project
)
1958 GtkWidget
*notebook
;
1959 GtkWidget
*search_entry
;
1960 IAnjutaDocument
*doc
;
1965 search_update_dialog();
1967 search_replace_populate();
1969 reset_flags_and_search_button();
1971 search_entry
= sr_get_gladewidget(SEARCH_STRING
)->widget
;
1972 doc
= ianjuta_document_manager_get_current_document(sr
->docman
, NULL
);
1973 te
= (IANJUTA_IS_EDITOR (doc
)) ? IANJUTA_EDITOR (doc
) : NULL
;
1974 if (te
&& search_entry
&& sr
->search
.range
.type
!= SR_SELECTION
)
1976 /* Set properties */
1977 gchar
*current_word
;
1979 current_word
= ianjuta_editor_selection_get
1980 (IANJUTA_EDITOR_SELECTION (te
), NULL
);
1981 if (current_word
== NULL
)
1982 current_word
= ianjuta_editor_get_current_word (te
, NULL
);
1984 if (current_word
&& strlen(current_word
) > 0 )
1986 if (strlen(current_word
) > MAX_LENGTH_SEARCH
)
1987 current_word
[MAX_LENGTH_SEARCH
] = '\0';
1988 gtk_entry_set_text(GTK_ENTRY (search_entry
), current_word
);
1989 g_free(current_word
);
1995 if ( !(sr
->search
.action
== SA_REPLACE
||
1996 sr
->search
.action
== SA_REPLACEALL
))
1998 search_set_action(SA_REPLACE
);
1999 sr
->search
.action
= SA_REPLACE
;
2000 search_show_replace(TRUE
);
2005 if (sr
->search
.action
== SA_REPLACE
|| sr
->search
.action
== SA_REPLACEALL
)
2007 search_set_action(SA_SELECT
);
2008 sr
->search
.action
= SA_SELECT
;
2009 search_show_replace(FALSE
);
2012 if (sr
->search
.action
!= SA_REPLACEALL
)
2013 modify_label_image_button(SEARCH_BUTTON
, _("Search"), GTK_STOCK_FIND
);
2017 search_set_target(SR_PROJECT
);
2020 search_set_action (SA_FIND_PANE
);
2021 search_set_direction (SD_BEGINNING
);
2024 show_jump_button(FALSE
);
2026 notebook
= sr_get_gladewidget(SEARCH_NOTEBOOK
)->widget
;
2027 gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook
), 0);
2029 /* Show the dialog */
2031 gtk_widget_grab_focus (search_entry
);