document-manager: bgo#680554 - entry of find in files doesn't get focused
[anjuta.git] / plugins / document-manager / search-files.c
blob56274b92f3a1fbb6eb5fe5999eb5da9999cfb9ed
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta
4 * Copyright (C) Johannes Schmid 2012 <jhs@gnome.org>
6 * anjuta is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * anjuta is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "search-files.h"
21 #include "search-file-command.h"
22 #include "search-filter-file-command.h"
23 #include <libanjuta/anjuta-command-queue.h>
24 #include <libanjuta/interfaces/ianjuta-project-manager.h>
25 #include <libanjuta/interfaces/ianjuta-project-chooser.h>
26 #include <libanjuta/interfaces/ianjuta-language.h>
28 #define BUILDER_FILE PACKAGE_DATA_DIR"/glade/anjuta-document-manager.ui"
30 #define TEXT_MIME_TYPE "text/*"
32 struct _SearchFilesPrivate
34 GtkBuilder* builder;
36 GtkWidget* main_box;
38 GtkWidget* search_button;
39 GtkWidget* replace_button;
41 GtkWidget* search_entry;
42 GtkWidget* replace_entry;
44 GtkWidget* files_combo;
45 GtkWidget* project_combo;
46 GtkWidget* file_type_combo;
48 GtkWidget* case_check;
49 GtkWidget* regex_check;
51 GtkWidget* spinner_busy;
53 GtkWidget* files_tree;
54 GtkTreeModel* files_model;
56 GtkWidget* files_tree_check;
58 AnjutaDocman* docman;
59 SearchBox* search_box;
60 GtkWidget* dialog;
62 /* Saved from last search */
63 gboolean case_sensitive;
64 gboolean regex;
65 gchar* last_search_string;
66 gchar* last_replace_string;
68 /* Project uri of last search */
69 GFile* project_file;
71 gboolean busy;
74 enum
76 COMBO_LANG_NAME,
77 COMBO_LANG_TYPES,
78 COMBO_N_COLUMNS
81 enum
83 COLUMN_SELECTED,
84 COLUMN_FILENAME,
85 COLUMN_COUNT,
86 COLUMN_PULSE,
87 COLUMN_SPINNER,
88 COLUMN_FILE,
89 COLUMN_ERROR_TOOLTIP,
90 COLUMN_ERROR_CODE,
91 N_COLUMNS
94 G_DEFINE_TYPE (SearchFiles, search_files, G_TYPE_OBJECT);
96 G_MODULE_EXPORT void search_files_search_clicked (SearchFiles* sf);
97 G_MODULE_EXPORT void search_files_replace_clicked (SearchFiles* sf);
98 G_MODULE_EXPORT void search_files_update_ui (SearchFiles* sf);
100 void
101 search_files_update_ui (SearchFiles* sf)
103 GtkTreeIter iter;
104 gboolean can_replace = FALSE;
105 gboolean can_search = FALSE;
107 if (!sf->priv->busy)
109 gtk_spinner_stop(GTK_SPINNER (sf->priv->spinner_busy));
110 gtk_widget_hide (sf->priv->spinner_busy);
112 can_search =
113 strlen(gtk_entry_get_text (GTK_ENTRY (sf->priv->search_entry))) > 0;
115 if (gtk_tree_model_get_iter_first(sf->priv->files_model, &iter))
119 gboolean selected;
120 gtk_tree_model_get (sf->priv->files_model, &iter,
121 COLUMN_SELECTED, &selected, -1);
122 if (selected)
124 can_replace = TRUE;
125 break;
128 while (gtk_tree_model_iter_next(sf->priv->files_model, &iter));
131 else
133 gtk_spinner_start(GTK_SPINNER (sf->priv->spinner_busy));
134 gtk_widget_show (sf->priv->spinner_busy);
137 gtk_widget_set_sensitive (sf->priv->search_button, can_search);
138 gtk_widget_set_sensitive (sf->priv->replace_button, can_replace);
139 gtk_widget_set_sensitive (sf->priv->search_entry, !sf->priv->busy);
140 gtk_widget_set_sensitive (sf->priv->replace_entry, !sf->priv->busy);
143 static void
144 search_files_check_column_toggled (GtkCellRendererToggle* renderer,
145 gchar* path,
146 SearchFiles* sf)
148 GtkTreePath* tree_path;
149 GtkTreeIter iter;
150 gboolean state;
152 if (sf->priv->busy)
153 return;
155 tree_path = gtk_tree_path_new_from_string(path);
156 gtk_tree_model_get_iter (sf->priv->files_model, &iter, tree_path);
158 gtk_tree_path_free(tree_path);
160 gtk_tree_model_get (sf->priv->files_model, &iter,
161 COLUMN_SELECTED, &state, -1);
163 gtk_list_store_set (GTK_LIST_STORE (sf->priv->files_model), &iter,
164 COLUMN_SELECTED, !state,
165 -1);
168 static void
169 search_files_finished (SearchFiles* sf, AnjutaCommandQueue* queue)
171 g_object_unref (queue);
172 sf->priv->busy = FALSE;
173 search_files_update_ui(sf);
176 static void
177 search_files_command_finished (SearchFileCommand* cmd,
178 guint return_code,
179 SearchFiles* sf)
181 GtkTreeIter iter;
182 GtkTreeRowReference* tree_ref;
183 GtkTreePath* path;
185 tree_ref = g_object_get_data (G_OBJECT (cmd),
186 "__tree_ref");
187 path = gtk_tree_row_reference_get_path(tree_ref);
189 gtk_tree_model_get_iter(sf->priv->files_model, &iter, path);
190 gtk_list_store_set (GTK_LIST_STORE (sf->priv->files_model),
191 &iter,
192 COLUMN_COUNT, search_file_command_get_n_matches(cmd),
193 COLUMN_ERROR_CODE, return_code,
194 COLUMN_ERROR_TOOLTIP, NULL,
195 -1);
196 gtk_tree_row_reference_free(tree_ref);
197 gtk_tree_path_free(path);
199 if (return_code)
201 gtk_list_store_set (GTK_LIST_STORE (sf->priv->files_model),
202 &iter,
203 COLUMN_ERROR_CODE, return_code,
204 COLUMN_ERROR_TOOLTIP,
205 anjuta_command_get_error_message(ANJUTA_COMMAND(cmd)),
206 -1);
209 g_object_unref (cmd);
212 static void
213 search_files_search (SearchFiles* sf)
215 GtkTreeIter iter;
217 if (gtk_tree_model_get_iter_first(sf->priv->files_model, &iter))
219 AnjutaCommandQueue* queue = anjuta_command_queue_new(ANJUTA_COMMAND_QUEUE_EXECUTE_MANUAL);
220 const gchar* pattern =
221 gtk_entry_get_text (GTK_ENTRY (sf->priv->search_entry));
224 GFile* file;
225 gboolean selected;
227 /* Save the current values */
228 sf->priv->regex =
229 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (sf->priv->regex_check));
230 sf->priv->case_sensitive =
231 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (sf->priv->case_check));
233 g_free (sf->priv->last_search_string);
234 sf->priv->last_search_string = g_strdup(pattern);
235 g_free (sf->priv->last_replace_string);
236 sf->priv->last_replace_string = NULL;
238 gtk_tree_model_get (sf->priv->files_model, &iter,
239 COLUMN_FILE, &file,
240 COLUMN_SELECTED, &selected, -1);
241 if (selected)
243 GtkTreePath* path;
244 GtkTreeRowReference* ref;
246 path = gtk_tree_model_get_path(sf->priv->files_model, &iter);
247 ref = gtk_tree_row_reference_new(sf->priv->files_model,
248 path);
249 gtk_tree_path_free(path);
252 SearchFileCommand* cmd = search_file_command_new(file,
253 pattern,
254 NULL,
255 sf->priv->case_sensitive,
256 sf->priv->regex);
257 g_object_set_data (G_OBJECT (cmd), "__tree_ref",
258 ref);
260 g_signal_connect (cmd, "command-finished",
261 G_CALLBACK(search_files_command_finished), sf);
263 anjuta_command_queue_push(queue,
264 ANJUTA_COMMAND(cmd));
266 g_object_unref (file);
268 while (gtk_tree_model_iter_next(sf->priv->files_model, &iter));
270 g_signal_connect_swapped (queue, "finished", G_CALLBACK (search_files_finished), sf);
272 anjuta_command_queue_start (queue);
273 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (sf->priv->files_model),
274 COLUMN_COUNT,
275 GTK_SORT_DESCENDING);
277 sf->priv->busy = TRUE;
278 search_files_update_ui(sf);
282 void
283 search_files_replace_clicked (SearchFiles* sf)
285 GtkTreeIter iter;
287 if (gtk_tree_model_get_iter_first(sf->priv->files_model, &iter))
289 AnjutaCommandQueue* queue = anjuta_command_queue_new(ANJUTA_COMMAND_QUEUE_EXECUTE_MANUAL);
290 const gchar* pattern =
291 gtk_entry_get_text (GTK_ENTRY (sf->priv->search_entry));
292 const gchar* replace =
293 gtk_entry_get_text (GTK_ENTRY (sf->priv->replace_entry));
296 GFile* file;
297 gboolean selected;
299 /* Save the current values */
300 sf->priv->regex =
301 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (sf->priv->regex_check));
302 sf->priv->case_sensitive =
303 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (sf->priv->case_check));
305 g_free (sf->priv->last_search_string);
306 sf->priv->last_search_string = g_strdup(pattern);
307 g_free (sf->priv->last_replace_string);
308 sf->priv->last_replace_string = g_strdup(replace);
310 gtk_tree_model_get (sf->priv->files_model, &iter,
311 COLUMN_FILE, &file,
312 COLUMN_SELECTED, &selected, -1);
313 if (selected)
315 GtkTreePath* path;
316 GtkTreeRowReference* ref;
318 path = gtk_tree_model_get_path(sf->priv->files_model, &iter);
319 ref = gtk_tree_row_reference_new(sf->priv->files_model,
320 path);
321 gtk_tree_path_free(path);
324 SearchFileCommand* cmd = search_file_command_new(file,
325 pattern,
326 replace,
327 sf->priv->case_sensitive,
328 sf->priv->regex);
329 g_object_set_data (G_OBJECT (cmd), "__tree_ref",
330 ref);
332 g_signal_connect (cmd, "command-finished",
333 G_CALLBACK(search_files_command_finished), sf);
335 anjuta_command_queue_push(queue,
336 ANJUTA_COMMAND(cmd));
338 g_object_unref (file);
340 while (gtk_tree_model_iter_next(sf->priv->files_model, &iter));
342 g_signal_connect_swapped (queue, "finished", G_CALLBACK (search_files_finished), sf);
344 anjuta_command_queue_start (queue);
345 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (sf->priv->files_model),
346 COLUMN_COUNT,
347 GTK_SORT_DESCENDING);
349 sf->priv->busy = TRUE;
350 search_files_update_ui(sf);
354 static void
355 search_files_filter_command_finished (SearchFilterFileCommand* cmd,
356 guint return_code,
357 SearchFiles* sf)
359 GFile* file;
360 GtkTreeIter iter;
361 gchar* display_name = NULL;
363 if (return_code)
364 return;
366 g_object_get (cmd, "file", &file, NULL);
368 if (sf->priv->project_file)
370 display_name = g_file_get_relative_path (sf->priv->project_file,
371 G_FILE (file));
373 if (!display_name)
374 display_name = g_file_get_path (G_FILE(file));
376 gtk_list_store_append(GTK_LIST_STORE (sf->priv->files_model),
377 &iter);
378 gtk_list_store_set (GTK_LIST_STORE (sf->priv->files_model), &iter,
379 COLUMN_SELECTED, TRUE,
380 COLUMN_FILENAME, display_name,
381 COLUMN_FILE, file,
382 COLUMN_COUNT, 0,
383 COLUMN_SPINNER, FALSE,
384 COLUMN_PULSE, FALSE, -1);
386 g_object_unref (file);
387 g_free (display_name);
390 static void
391 search_files_filter_finished (AnjutaCommandQueue* queue,
392 SearchFiles* sf)
394 g_object_unref (queue);
395 search_files_search (sf);
398 void
399 search_files_search_clicked (SearchFiles* sf)
401 GFile* selected;
402 IAnjutaProjectManager* pm;
403 GList* files = NULL;
404 GList* file;
405 gchar* project_uri;
406 AnjutaCommandQueue* queue;
407 gchar* mime_types;
408 GtkComboBox* type_combo;
409 GtkTreeIter iter;
411 g_return_if_fail (sf != NULL && SEARCH_IS_FILES (sf));
413 /* Clear store */
414 gtk_list_store_clear(GTK_LIST_STORE (sf->priv->files_model));
415 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (sf->priv->files_model),
416 COLUMN_FILENAME,
417 GTK_SORT_DESCENDING);
419 /* Get file and type selection */
420 selected =
421 ianjuta_project_chooser_get_selected(IANJUTA_PROJECT_CHOOSER (sf->priv->project_combo),
422 NULL);
423 type_combo = GTK_COMBO_BOX (sf->priv->file_type_combo);
424 gtk_combo_box_get_active_iter(type_combo, &iter);
425 gtk_tree_model_get (gtk_combo_box_get_model (type_combo),
426 &iter,
427 COMBO_LANG_TYPES, &mime_types,
428 -1);
430 /* Get files from project manager */
431 pm = anjuta_shell_get_interface (sf->priv->docman->shell,
432 IAnjutaProjectManager,
433 NULL);
434 files = ianjuta_project_manager_get_children(pm, selected, ANJUTA_PROJECT_SOURCE, NULL);
436 /* Query project root uri */
437 anjuta_shell_get (sf->priv->docman->shell,
438 IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI,
439 G_TYPE_STRING,
440 &project_uri, NULL);
441 if (sf->priv->project_file)
442 g_object_unref (sf->priv->project_file);
444 if (project_uri)
446 sf->priv->project_file = g_file_new_for_uri (project_uri);
448 g_free (project_uri);
451 /* Check that there are some files to process */
452 if (files != NULL)
454 /* Queue file filtering */
455 queue = anjuta_command_queue_new(ANJUTA_COMMAND_QUEUE_EXECUTE_MANUAL);
456 g_signal_connect (queue, "finished",
457 G_CALLBACK (search_files_filter_finished), sf);
458 for (file = files; file != NULL; file = g_list_next (file))
460 SearchFilterFileCommand* cmd =
461 search_filter_file_command_new(G_FILE (file->data),
462 mime_types);
463 g_signal_connect (cmd, "command-finished",
464 G_CALLBACK (search_files_filter_command_finished), sf);
465 anjuta_command_queue_push(queue, ANJUTA_COMMAND(cmd));
467 sf->priv->busy = TRUE;
468 search_files_update_ui(sf);
469 anjuta_command_queue_start (queue);
471 g_list_foreach (files, (GFunc) g_object_unref, NULL);
472 g_list_free (files);
475 g_free (mime_types);
478 static void
479 search_files_render_count (GtkTreeViewColumn *tree_column,
480 GtkCellRenderer *cell,
481 GtkTreeModel *tree_model,
482 GtkTreeIter *iter,
483 gpointer data)
485 int count;
486 gchar* count_str;
488 gtk_tree_model_get (tree_model, iter,
489 COLUMN_COUNT, &count,
490 -1);
491 count_str = g_strdup_printf("%d", count);
492 g_object_set (cell, "text", count_str, NULL);
493 g_free (count_str);
496 static void
497 search_files_editor_loaded (SearchFiles* sf, IAnjutaEditor* editor)
499 search_box_set_search_string(sf->priv->search_box,
500 sf->priv->last_search_string);
501 if (sf->priv->last_replace_string)
503 search_box_set_replace_string(sf->priv->search_box,
504 sf->priv->last_replace_string);
505 search_box_set_replace(sf->priv->search_box,
506 TRUE);
508 else
510 search_box_set_replace(sf->priv->search_box,
511 FALSE);
513 search_box_toggle_case_sensitive(sf->priv->search_box,
514 sf->priv->case_sensitive);
515 search_box_toggle_highlight(sf->priv->search_box,
516 TRUE);
517 search_box_toggle_regex(sf->priv->search_box,
518 sf->priv->regex);
519 search_box_search_highlight_all(sf->priv->search_box, TRUE);
520 search_box_incremental_search(sf->priv->search_box, TRUE, FALSE);
522 gtk_widget_show (GTK_WIDGET(sf->priv->search_box));
526 static void
527 search_files_result_activated (GtkTreeView* files_tree,
528 GtkTreePath* path,
529 GtkTreeViewColumn* column,
530 SearchFiles* sf)
532 IAnjutaDocument* editor;
533 GFile* file;
534 GtkTreeIter iter;
536 gtk_tree_model_get_iter (sf->priv->files_model, &iter, path);
537 gtk_tree_model_get (sf->priv->files_model, &iter,
538 COLUMN_FILE, &file, -1);
540 /* Check if document is open */
541 editor = anjuta_docman_get_document_for_file(sf->priv->docman, file);
543 if (editor && IANJUTA_IS_EDITOR(editor))
545 anjuta_docman_present_notebook_page(sf->priv->docman,
546 editor);
547 search_files_editor_loaded (sf, IANJUTA_EDITOR(editor));
549 else
551 IAnjutaEditor* real_editor =
552 anjuta_docman_goto_file_line(sf->priv->docman, file, 0);
553 if (real_editor)
554 g_signal_connect_swapped (real_editor, "opened",
555 G_CALLBACK (search_files_editor_loaded), sf);
558 g_object_unref (file);
561 static void
562 search_files_init_tree (SearchFiles* sf)
564 GtkTreeViewColumn* column_select;
565 GtkTreeViewColumn* column_filename;
566 GtkTreeViewColumn* column_count;
568 GtkCellRenderer* selection_renderer;
569 GtkCellRenderer* filename_renderer;
570 GtkCellRenderer* count_renderer;
571 GtkCellRenderer* error_renderer;
573 column_select = gtk_tree_view_column_new();
574 sf->priv->files_tree_check = gtk_check_button_new();
575 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sf->priv->files_tree_check),
576 TRUE);
577 gtk_widget_show (sf->priv->files_tree_check);
578 gtk_tree_view_column_set_widget(column_select,
579 sf->priv->files_tree_check);
580 selection_renderer = gtk_cell_renderer_toggle_new ();
581 gtk_tree_view_column_pack_start(column_select,
582 selection_renderer,
583 FALSE);
584 gtk_tree_view_column_add_attribute(column_select,
585 selection_renderer,
586 "active",
587 COLUMN_SELECTED);
588 g_signal_connect (selection_renderer, "toggled",
589 G_CALLBACK(search_files_check_column_toggled), sf);
590 gtk_tree_view_column_set_sort_column_id(column_select,
591 COLUMN_SELECTED);
593 column_filename = gtk_tree_view_column_new();
594 gtk_tree_view_column_set_expand(column_filename,
595 TRUE);
596 gtk_tree_view_column_set_title (column_filename, _("Filename"));
597 filename_renderer = gtk_cell_renderer_text_new();
598 gtk_tree_view_column_pack_start(column_filename,
599 filename_renderer,
600 TRUE);
601 gtk_tree_view_column_add_attribute (column_filename,
602 filename_renderer,
603 "text",
604 COLUMN_FILENAME);
605 gtk_tree_view_column_add_attribute (column_filename,
606 filename_renderer,
607 "sensitive",
608 COLUMN_COUNT);
609 gtk_tree_view_column_set_sort_column_id(column_filename,
610 COLUMN_FILENAME);
611 error_renderer = gtk_cell_renderer_pixbuf_new();
612 g_object_set (error_renderer, "stock-id", GTK_STOCK_DIALOG_ERROR, NULL);
613 gtk_tree_view_column_pack_start(column_filename,
614 error_renderer,
615 FALSE);
616 gtk_tree_view_column_add_attribute (column_filename,
617 error_renderer,
618 "visible",
619 COLUMN_ERROR_CODE);
621 column_count = gtk_tree_view_column_new();
622 gtk_tree_view_column_set_title (column_count, "#");
623 count_renderer = gtk_cell_renderer_text_new();
624 gtk_tree_view_column_pack_start(column_count,
625 count_renderer,
626 TRUE);
627 gtk_tree_view_column_add_attribute (column_count,
628 count_renderer,
629 "sensitive",
630 COLUMN_COUNT);
631 gtk_tree_view_column_set_cell_data_func(column_count,
632 count_renderer,
633 search_files_render_count,
634 NULL,
635 NULL);
636 gtk_tree_view_column_set_sort_column_id(column_count,
637 COLUMN_COUNT);
639 sf->priv->files_model = GTK_TREE_MODEL (gtk_list_store_new (N_COLUMNS,
640 G_TYPE_BOOLEAN,
641 G_TYPE_STRING,
642 G_TYPE_INT,
643 G_TYPE_BOOLEAN,
644 G_TYPE_BOOLEAN,
645 G_TYPE_FILE,
646 G_TYPE_STRING,
647 G_TYPE_INT));
648 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (sf->priv->files_model),
649 COLUMN_FILENAME,
650 GTK_SORT_DESCENDING);
652 g_signal_connect_swapped (sf->priv->files_model,
653 "row-inserted",
654 G_CALLBACK (search_files_update_ui),
655 sf);
656 g_signal_connect_swapped (sf->priv->files_model,
657 "row-deleted",
658 G_CALLBACK (search_files_update_ui),
659 sf);
660 g_signal_connect_swapped (sf->priv->files_model,
661 "row-changed",
662 G_CALLBACK (search_files_update_ui),
663 sf);
665 gtk_tree_view_set_model (GTK_TREE_VIEW (sf->priv->files_tree), sf->priv->files_model);
666 gtk_tree_view_append_column(GTK_TREE_VIEW (sf->priv->files_tree),
667 column_select);
668 gtk_tree_view_append_column(GTK_TREE_VIEW (sf->priv->files_tree),
669 column_filename);
670 gtk_tree_view_append_column(GTK_TREE_VIEW (sf->priv->files_tree),
671 column_count);
672 gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW (sf->priv->files_tree),
673 COLUMN_ERROR_TOOLTIP);
674 g_signal_connect (sf->priv->files_tree, "row-activated",
675 G_CALLBACK (search_files_result_activated), sf);
678 static void
679 search_files_type_combo_init (SearchFiles* sf)
681 GtkCellRenderer* combo_renderer = gtk_cell_renderer_text_new();
683 GtkTreeIter iter;
684 GtkListStore* store;
686 IAnjutaLanguage* lang_manager =
687 anjuta_shell_get_interface (sf->priv->docman->shell,
688 IAnjutaLanguage,
689 NULL);
691 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (sf->priv->file_type_combo),
692 combo_renderer, TRUE);
693 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (sf->priv->file_type_combo),
694 combo_renderer, "text", 0);
696 store = gtk_list_store_new (COMBO_N_COLUMNS,
697 G_TYPE_STRING,
698 G_TYPE_STRING);
699 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (store),
700 COMBO_LANG_NAME,
701 GTK_SORT_DESCENDING);
703 gtk_combo_box_set_model(GTK_COMBO_BOX(sf->priv->file_type_combo),
704 GTK_TREE_MODEL (store));
706 gtk_list_store_append(store, &iter);
707 gtk_list_store_set (store, &iter,
708 COMBO_LANG_NAME, _("All text files"),
709 COMBO_LANG_TYPES, TEXT_MIME_TYPE,
710 -1);
711 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(sf->priv->file_type_combo),
712 &iter);
714 if (lang_manager)
716 GList* languages =
717 ianjuta_language_get_languages(lang_manager, NULL);
718 GList* lang;
719 for (lang = languages; lang != NULL; lang = g_list_next (lang))
721 GList* mime_type;
722 GString* type_string = g_string_new(NULL);
724 GList* mime_types = ianjuta_language_get_mime_types (lang_manager,
725 GPOINTER_TO_INT (lang->data),
726 NULL);
727 const gchar* name = ianjuta_language_get_name (lang_manager,
728 GPOINTER_TO_INT (lang->data),
729 NULL);
731 for (mime_type = mime_types; mime_type != NULL; mime_type = g_list_next (mime_type))
733 if (type_string->len)
735 g_string_append_c (type_string, ',');
737 g_string_append (type_string, mime_type->data);
739 gtk_list_store_append(store, &iter);
740 gtk_list_store_set (store, &iter,
741 COMBO_LANG_NAME, name,
742 COMBO_LANG_TYPES, type_string->str,
743 -1);
745 g_string_free (type_string, TRUE);
750 static void
751 search_files_init (SearchFiles* sf)
753 GError* error = NULL;
755 sf->priv =
756 G_TYPE_INSTANCE_GET_PRIVATE (sf, SEARCH_TYPE_FILES, SearchFilesPrivate);
758 sf->priv->builder = gtk_builder_new();
759 gtk_builder_add_from_file(sf->priv->builder, BUILDER_FILE, &error);
761 if (error)
763 g_warning("Could load ui file for search files: %s",
764 error->message);
765 g_error_free(error);
766 return;
769 sf->priv->main_box = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
770 "main_box"));
771 sf->priv->search_button = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
772 "search_button"));
773 sf->priv->replace_button = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
774 "replace_button"));
775 sf->priv->search_entry = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
776 "search_entry"));
777 sf->priv->replace_entry = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
778 "replace_entry"));
779 sf->priv->project_combo = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
780 "project_combo"));
781 sf->priv->file_type_combo = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
782 "file_type_combo"));
784 sf->priv->case_check = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
785 "case_check"));
786 sf->priv->regex_check = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
787 "regex_check"));
788 sf->priv->spinner_busy = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
789 "spinner_busy"));
791 sf->priv->files_tree = GTK_WIDGET (gtk_builder_get_object(sf->priv->builder,
792 "files_tree"));
794 search_files_init_tree(sf);
796 gtk_builder_connect_signals(sf->priv->builder, sf);
798 g_object_ref (sf->priv->main_box);
799 gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (sf->priv->main_box)),
800 sf->priv->main_box);
803 static void
804 search_files_finalize (GObject* object)
806 SearchFiles* sf = SEARCH_FILES(object);
808 g_object_unref (sf->priv->main_box);
809 g_object_unref (sf->priv->builder);
810 if (sf->priv->project_file)
811 g_object_unref (sf->priv->project_file);
812 g_free (sf->priv->last_search_string);
813 g_free (sf->priv->last_replace_string);
815 G_OBJECT_CLASS (search_files_parent_class)->finalize (object);
818 static void
819 search_files_class_init (SearchFilesClass* klass)
821 GObjectClass* object_class = G_OBJECT_CLASS (klass);
823 object_class->finalize = search_files_finalize;
825 g_type_class_add_private(klass, sizeof(SearchFilesPrivate));
828 void
829 search_files_update_project (SearchFiles* sf)
831 IAnjutaProjectManager* pm = anjuta_shell_get_interface(sf->priv->docman->shell,
832 IAnjutaProjectManager,
833 NULL);
834 ianjuta_project_chooser_set_project_model(IANJUTA_PROJECT_CHOOSER(sf->priv->project_combo),
836 ANJUTA_PROJECT_GROUP,
837 NULL);
840 SearchFiles*
841 search_files_new (AnjutaDocman* docman, SearchBox* search_box)
843 AnjutaShell* shell = docman->shell;
844 GObject* obj = g_object_new (SEARCH_TYPE_FILES, NULL);
845 SearchFiles* sf = SEARCH_FILES(obj);
847 anjuta_shell_add_widget(shell, sf->priv->main_box,
848 "search_files",
849 _("Find in files"),
850 GTK_STOCK_FIND_AND_REPLACE,
851 ANJUTA_SHELL_PLACEMENT_BOTTOM, NULL);
853 sf->priv->docman = docman;
854 sf->priv->search_box = search_box;
856 gtk_widget_show (sf->priv->main_box);
858 search_files_type_combo_init(sf);
859 search_files_update_ui(sf);
860 search_files_update_project (sf);
862 return sf;
865 void search_files_present (SearchFiles* sf)
867 g_return_if_fail (sf != NULL && SEARCH_IS_FILES(sf));
869 gtk_entry_set_text (GTK_ENTRY (sf->priv->search_entry),
870 search_box_get_search_string(sf->priv->search_box));
871 gtk_entry_set_text (GTK_ENTRY (sf->priv->replace_entry),
872 search_box_get_replace_string(sf->priv->search_box));
874 anjuta_shell_present_widget(sf->priv->docman->shell,
875 sf->priv->main_box,
876 NULL);
878 gtk_widget_grab_focus (sf->priv->search_entry);