1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
3 * Gui Policy Editor for TOMOYO Linux
6 * Copyright (C) Yoshihiro Kusuno 2011 <yocto@users.sourceforge.jp>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA
28 #include <glib/gi18n.h>
33 typedef struct _search_t {
39 #define COMBO_LIST_LIMIT 10
40 static GList *combolist = NULL;
41 static gchar *S_entry = NULL;
47 SCREEN_EXCEPTION_LIST,
53 static gint locate_index[MAXSCREEN+1] = {0, };
55 static gint get_locate_index(transition_t *transition)
57 enum screen_type_e screen;
59 switch((int)transition->current_page) {
60 case CCS_SCREEN_DOMAIN_LIST :
61 if (transition->task_flag) {
62 screen = SCREEN_PROCESS_LIST;
64 screen = SCREEN_DOMAIN_LIST;
67 case CCS_SCREEN_ACL_LIST :
68 screen = SCREEN_ACL_LIST;
70 case CCS_SCREEN_EXCEPTION_LIST :
71 screen = SCREEN_EXCEPTION_LIST;
73 case CCS_SCREEN_PROFILE_LIST :
74 screen = SCREEN_PROFILE_LIST;
76 case CCS_SCREEN_MANAGER_LIST :
82 return locate_index[screen];
85 static void put_locate_index(transition_t *transition, gint index)
87 enum screen_type_e screen;
89 switch((int)transition->current_page) {
90 case CCS_SCREEN_DOMAIN_LIST :
91 if (transition->task_flag) {
92 screen = SCREEN_PROCESS_LIST;
94 screen = SCREEN_DOMAIN_LIST;
97 case CCS_SCREEN_ACL_LIST :
98 screen = SCREEN_ACL_LIST;
100 case CCS_SCREEN_EXCEPTION_LIST :
101 screen = SCREEN_EXCEPTION_LIST;
103 case CCS_SCREEN_PROFILE_LIST :
104 screen = SCREEN_PROFILE_LIST;
106 case CCS_SCREEN_MANAGER_LIST :
112 locate_index[screen] = index;
115 static gboolean search_pos_list(GtkTreeModel *model, GtkTreePath *path,
116 GtkTreeIter *iter, transition_t *transition)
118 GtkWidget *view = NULL;
119 GtkTreeSelection *selection;
121 gchar *number = NULL;
124 switch((int)transition->current_page) {
125 case CCS_SCREEN_DOMAIN_LIST :
126 if (transition->task_flag) {
127 view = transition->tsk.treeview;
129 view = transition->treeview;
131 gtk_tree_model_get(model, iter, 0, &index, -1);
133 case CCS_SCREEN_ACL_LIST :
134 view = transition->acl.listview;
135 gtk_tree_model_get(model, iter, 0, &number, -1);
136 index = atoi(number);
138 case CCS_SCREEN_EXCEPTION_LIST :
139 view = transition->exp.listview;
140 gtk_tree_model_get(model, iter, 0, &number, -1);
141 index = atoi(number);
143 case CCS_SCREEN_PROFILE_LIST :
144 view = transition->prf.listview;
145 gtk_tree_model_get(model, iter, 0, &number, -1);
146 index = atoi(number);
151 if (index == get_locate_index(transition)) {
152 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
153 gtk_tree_selection_select_path(selection, path);
154 view_cursor_set(view, gtk_tree_path_copy(path), NULL);
161 static gint get_list_count(transition_t *transition)
165 switch((int)transition->current_page) {
166 case CCS_SCREEN_DOMAIN_LIST :
167 if (transition->task_flag) {
168 count = transition->tsk.count;
170 count = transition->dp->list_len;
173 case CCS_SCREEN_ACL_LIST :
174 count = transition->acl.count;
176 case CCS_SCREEN_EXCEPTION_LIST :
177 count = transition->exp.count;
179 case CCS_SCREEN_PROFILE_LIST :
180 count = transition->prf.count;
182 case CCS_SCREEN_MANAGER_LIST :
190 static gint get_current_index(transition_t *transition)
194 switch((int)transition->current_page) {
195 case CCS_SCREEN_DOMAIN_LIST :
196 if (transition->task_flag) {
197 index = get_current_process_index(&(transition->tsk));
199 index = get_current_domain_index(transition);
202 case CCS_SCREEN_ACL_LIST :
203 index = select_list_line(&(transition->acl));
205 case CCS_SCREEN_EXCEPTION_LIST :
206 index = select_list_line(&(transition->exp));
208 case CCS_SCREEN_PROFILE_LIST :
209 index = select_list_line(&(transition->prf));
211 case CCS_SCREEN_MANAGER_LIST :
219 static void search(transition_t *transition, gboolean forward)
221 GtkWidget *view = NULL;
222 gint index, start_index, count;
224 gchar *haystack = NULL;
225 gchar *tmp_entry, *entry = NULL;
228 if (!S_entry || strcmp(S_entry, "") == 0)
231 get_conf_search(&conf);
233 tmp_entry = encode_to_octal_str(S_entry);
234 entry = conf.match ? g_strdup(tmp_entry) : g_ascii_strup(tmp_entry, -1);
237 start_index = index = get_current_index(transition);
238 count = get_list_count(transition);
242 if (count <= index) {
257 if (index == start_index)
260 switch((int)transition->current_page) {
261 case CCS_SCREEN_DOMAIN_LIST :
262 if (transition->task_flag) {
263 view = transition->tsk.treeview;
264 str_p = transition->tsk.task[index].name;
266 view = transition->treeview;
267 str_p = (gchar *)get_domain_last_name(index);
270 case CCS_SCREEN_ACL_LIST :
271 view = transition->acl.listview;
272 str_p = g_strdup_printf("%s %s",
273 ccs_directives[transition->acl.list
274 [index].directive].alias,
275 transition->acl.list[index].operand);
277 case CCS_SCREEN_EXCEPTION_LIST :
278 view = transition->exp.listview;
279 str_p = g_strdup_printf("%s %s",
280 ccs_directives[transition->exp.list
281 [index].directive].alias,
282 transition->exp.list[index].operand);
284 case CCS_SCREEN_PROFILE_LIST :
285 view = transition->prf.listview;
286 str_p = g_strdup_printf("%u-%s",
287 transition->prf.list[index].directive,
288 transition->prf.list[index].operand);
290 case CCS_SCREEN_MANAGER_LIST :
297 haystack = conf.match ?
298 g_strdup(str_p) : g_ascii_strup(str_p, -1);
300 if (transition->current_page != CCS_SCREEN_DOMAIN_LIST)
303 if(g_strrstr(haystack, entry)) {
305 put_locate_index(transition, index);
306 model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
307 gtk_tree_model_foreach(model,
308 (GtkTreeModelForeachFunc)search_pos_list, transition);
316 gtk_action_set_sensitive(gtk_action_group_get_action(
317 transition->actions, "SearchBack"), TRUE);
318 gtk_action_set_sensitive(gtk_action_group_get_action(
319 transition->actions, "SearchFoward"), TRUE);
322 /*-------+---------+---------+---------+---------+---------+---------+--------*/
323 static void cb_combo_changed(GtkComboBox *combobox, gpointer nothing)
329 model = gtk_combo_box_get_model(combobox);
330 if (gtk_combo_box_get_active_iter(combobox, &iter)) {
331 gtk_tree_model_get(model, &iter, 0, &text, -1);
334 // g_print("cb_combo_changed[%s]\n", text);
338 static void cb_search_entry_activate(GtkEntry *entry, search_t *srch)
340 GtkComboBox *combobox;
343 gboolean exist_flag = FALSE;
345 combobox = GTK_COMBO_BOX(srch->combo);
346 new_text = gtk_combo_box_get_active_text(combobox);
347 if (!new_text || strcmp(new_text, "") == 0) {
352 S_entry = g_strdup(new_text);
353 // g_print("cb_search_entry_activate[%s]\n", new_text);
355 for (list = combolist; list; list = g_list_next(list)) {
356 if (strcmp(new_text, (gchar *)list->data) == 0) {
364 combolist = insert_item(combobox, combolist, new_text, 0);
365 len = g_list_length(combolist);
366 if (len > COMBO_LIST_LIMIT) {
367 combolist = remove_item(combobox, combolist, len - 1);
373 search(srch->tran, TRUE);
374 get_conf_search(&conf);
376 gtk_dialog_response(GTK_DIALOG(srch->dialog),
381 static void cb_btn_prev_clicked(GtkButton *widget , search_t *srch)
384 cb_search_entry_activate(NULL, srch);
385 search(srch->tran, FALSE);
386 get_conf_search(&conf);
388 gtk_dialog_response(GTK_DIALOG(srch->dialog),
392 static void cb_btn_next_clicked(GtkButton *widget , search_t *srch)
395 cb_search_entry_activate(NULL, srch);
396 search(srch->tran, TRUE);
397 get_conf_search(&conf);
399 gtk_dialog_response(GTK_DIALOG(srch->dialog),
402 /*-------+---------+---------+---------+---------+---------+---------+--------*/
403 GList *insert_item(GtkComboBox *combobox,
404 GList *cmblist, const gchar *item_label, gint index)
406 gtk_combo_box_insert_text(combobox, index, g_strdup(item_label));
407 return g_list_insert(cmblist, g_strdup(item_label), index);
410 GList *remove_item(GtkComboBox *combobox, GList *cmblist, gint index)
412 gtk_combo_box_remove_text(combobox, index);
413 g_free(g_list_nth_data(cmblist, index));
414 return g_list_delete_link(cmblist, g_list_nth(cmblist, index));
417 static gchar *search_title(transition_t *transition)
421 switch((int)transition->current_page) {
422 case CCS_SCREEN_DOMAIN_LIST :
423 if (transition->task_flag) {
424 title = _("Process Search for :");
426 title = _("Domain Search for :");
429 case CCS_SCREEN_ACL_LIST :
430 title = _("ACL Search for :");
432 case CCS_SCREEN_EXCEPTION_LIST :
433 title = _("Exception Search for :");
435 case CCS_SCREEN_PROFILE_LIST :
436 title = _("Profile Search for :");
438 case CCS_SCREEN_MANAGER_LIST :
440 title = _("Search for :");
446 static void cb_toggled_match(GtkToggleButton *widget, search_conf_t *conf)
448 conf->match = gtk_toggle_button_get_active(widget);
449 put_conf_search(conf);
451 static void cb_toggled_wrap(GtkToggleButton *widget, search_conf_t *conf)
453 conf->wrap = gtk_toggle_button_get_active(widget);
454 put_conf_search(conf);
456 static void cb_toggled_close(GtkToggleButton *widget, search_conf_t *conf)
458 conf->close = gtk_toggle_button_get_active(widget);
459 put_conf_search(conf);
462 static void create_check_box(GtkWidget *parent, search_conf_t *conf)
464 GtkWidget *hbox, *vbox_l, *vbox_r;
465 GtkWidget *match, *wrap, *close;
467 hbox = gtk_hbox_new(FALSE, 15);
468 gtk_box_pack_start(GTK_BOX(parent), hbox, TRUE, TRUE, 10);
470 vbox_l = gtk_vbox_new(FALSE, 5);
471 gtk_box_pack_start(GTK_BOX(hbox), vbox_l, TRUE, FALSE, 0);
472 vbox_r = gtk_vbox_new(FALSE, 5);
473 gtk_box_pack_start(GTK_BOX(hbox), vbox_r, TRUE, FALSE, 0);
475 match = gtk_check_button_new_with_mnemonic(_("_Match case"));
476 gtk_box_pack_start(GTK_BOX(vbox_l), match, TRUE, FALSE, 0);
477 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(match), conf->match);
478 g_signal_connect(G_OBJECT(match), "toggled",
479 G_CALLBACK(cb_toggled_match), conf);
481 wrap = gtk_check_button_new_with_mnemonic(_("_Wrap around"));
482 gtk_box_pack_start(GTK_BOX(vbox_l), wrap, TRUE, FALSE, 0);
483 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wrap), conf->wrap);
484 g_signal_connect(G_OBJECT(wrap), "toggled",
485 G_CALLBACK(cb_toggled_wrap), conf);
487 close = gtk_check_button_new_with_mnemonic(_("Close _dialog"));
488 gtk_box_pack_start(GTK_BOX(vbox_r), close, FALSE, FALSE, 0);
489 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(close), conf->close);
490 g_signal_connect(G_OBJECT(close), "toggled",
491 G_CALLBACK(cb_toggled_close), conf);
494 大文字と小文字を区別する (M)atch case
495 折返しも対象にする (W)rap around
496 enterで閉じる Close (d)ialog
500 void search_input(GtkAction *action, transition_t *transition)
502 GtkWidget *dialog, *parent;
503 GtkWidget *hbox, *vbox_l, *vbox_r;
506 GtkWidget *btn_next, *btn_prev;
512 parent = (transition->acl_detached &&
513 (int)transition->current_page == CCS_SCREEN_ACL_LIST) ?
514 transition->acl_window : transition->window;
516 dialog = gtk_dialog_new_with_buttons(_("Find"),
518 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
519 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
522 hbox = gtk_hbox_new(FALSE, 5);
523 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
524 hbox, TRUE, TRUE, 0);
525 gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
527 vbox_l = gtk_vbox_new(FALSE, 5);
528 gtk_box_pack_start(GTK_BOX(hbox), vbox_l, TRUE, TRUE, 0);
530 label = gtk_label_new(NULL);
531 gtk_label_set_markup(GTK_LABEL(label), search_title(transition));
532 gtk_box_pack_start(GTK_BOX(vbox_l), label, FALSE, FALSE, 0);
534 entry = gtk_combo_box_entry_new_text();
535 srch.tran = transition;
537 srch.dialog = dialog;
538 g_signal_connect(G_OBJECT(entry) , "changed",
539 G_CALLBACK(cb_combo_changed), NULL);
540 g_signal_connect(G_OBJECT(GTK_BIN(entry)->child) , "activate" ,
541 G_CALLBACK(cb_search_entry_activate), &srch);
542 gtk_box_pack_start(GTK_BOX(vbox_l), entry, FALSE, FALSE, 0);
544 for (list = combolist; list; list = g_list_next(list)) {
545 gtk_combo_box_append_text(
546 GTK_COMBO_BOX(entry), (gchar *)list->data);
548 gtk_combo_box_set_active(GTK_COMBO_BOX(entry), 0);
550 get_conf_search(&conf);
551 create_check_box(vbox_l, &conf);
553 vbox_r = gtk_vbox_new(FALSE, 5);
554 gtk_box_pack_start(GTK_BOX(hbox), vbox_r, FALSE, FALSE, 0);
556 btn_prev = gtk_button_new_from_stock(GTK_STOCK_GO_BACK);
557 gtk_box_pack_start(GTK_BOX(vbox_r), btn_prev, TRUE, TRUE, 0);
558 g_signal_connect(G_OBJECT(btn_prev) , "clicked" ,
559 G_CALLBACK (cb_btn_prev_clicked) , &srch);
561 btn_next = gtk_button_new_from_stock(GTK_STOCK_GO_FORWARD);
562 gtk_box_pack_start(GTK_BOX(vbox_r), btn_next, TRUE, TRUE, 0);
563 g_signal_connect(G_OBJECT(btn_next) , "clicked" ,
564 G_CALLBACK (cb_btn_next_clicked) , &srch);
566 gtk_widget_set_size_request(dialog, 520, -1);
567 put_locate_index(transition, get_current_index(transition));
568 gtk_widget_show_all(dialog);
570 response = gtk_dialog_run(GTK_DIALOG(dialog));
571 gtk_widget_destroy(dialog);
574 void search_back(GtkAction *action, transition_t *transition)
576 search(transition, FALSE);
579 void search_forward(GtkAction *action, transition_t *transition)
581 search(transition, TRUE);
583 /*-------+---------+---------+---------+---------+---------+---------+--------*/