OSDN Git Service

ca1cf70e276a03e0d00101533701ff96b2b88d81
[gpet/origin.git] / src / search.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /*
3  * Gui Policy Editor for TOMOYO Linux
4  *
5  * search.c
6  * Copyright (C) Yoshihiro Kusuno 2011 <yocto@users.sourceforge.jp>
7  *
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.
12  *
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.
17  *
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
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #  include <config.h>
25 #endif
26
27 #include <gtk/gtk.h>
28 #include <glib/gi18n.h>
29
30 #include "gpet.h"
31
32 typedef struct _search_t {
33         transition_t    *tran;
34         GtkWidget       *combo;
35 } search_t;
36
37 #define COMBO_LIST_LIMIT        10
38 static GList            *combolist = NULL;
39 static gchar            *S_entry = NULL;
40
41 enum screen_type_e {
42         SCREEN_DOMAIN_LIST,
43         SCREEN_PROCESS_LIST,
44         SCREEN_ACL_LIST,
45         SCREEN_EXCEPTION_LIST,
46         SCREEN_PROFILE_LIST,
47         SCREEN_MANAGER_LIST,
48         SCREEN_STAT_LIST,
49         MAXSCREEN
50 };
51 static  gint            locate_index[MAXSCREEN+1] = {0, };
52
53 static gint get_locate_index(transition_t *transition)
54 {
55         enum screen_type_e      screen;
56
57         switch((int)transition->current_page) {
58         case CCS_SCREEN_DOMAIN_LIST :
59                 if (transition->task_flag) {
60                         screen = SCREEN_PROCESS_LIST;
61                 } else {
62                         screen = SCREEN_DOMAIN_LIST;
63                 }
64                 break;
65         case CCS_SCREEN_ACL_LIST :
66                 screen = SCREEN_ACL_LIST;
67                 break;
68         case CCS_SCREEN_EXCEPTION_LIST :
69                 screen = SCREEN_EXCEPTION_LIST;
70                 break;
71         case CCS_SCREEN_PROFILE_LIST :
72                 screen = SCREEN_PROFILE_LIST;
73                 break;
74         case CCS_SCREEN_MANAGER_LIST :
75         default :
76                 screen = MAXSCREEN;
77                 break;
78         }
79
80         return locate_index[screen];
81 }
82
83 static void put_locate_index(transition_t *transition, gint index)
84 {
85         enum screen_type_e      screen;
86
87         switch((int)transition->current_page) {
88         case CCS_SCREEN_DOMAIN_LIST :
89                 if (transition->task_flag) {
90                         screen = SCREEN_PROCESS_LIST;
91                 } else {
92                         screen = SCREEN_DOMAIN_LIST;
93                 }
94                 break;
95         case CCS_SCREEN_ACL_LIST :
96                 screen = SCREEN_ACL_LIST;
97                 break;
98         case CCS_SCREEN_EXCEPTION_LIST :
99                 screen = SCREEN_EXCEPTION_LIST;
100                 break;
101         case CCS_SCREEN_PROFILE_LIST :
102                 screen = SCREEN_PROFILE_LIST;
103                 break;
104         case CCS_SCREEN_MANAGER_LIST :
105         default :
106                 screen = MAXSCREEN;
107                 break;
108         }
109
110         locate_index[screen] = index;
111 }
112
113 static gboolean search_pos_list(GtkTreeModel *model, GtkTreePath *path,
114                                 GtkTreeIter *iter, transition_t *transition)
115 {
116         GtkWidget               *view = NULL;
117         GtkTreeSelection        *selection;
118         gint                    index;
119         gchar                   *number = NULL;
120
121
122         switch((int)transition->current_page) {
123         case CCS_SCREEN_DOMAIN_LIST :
124                 if (transition->task_flag) {
125                         view = transition->tsk.treeview;
126                 } else {
127                         view = transition->treeview;
128                 }
129                 gtk_tree_model_get(model, iter, 0, &index, -1);
130                 break;
131         case CCS_SCREEN_ACL_LIST :
132                 view = transition->acl.listview;
133                 gtk_tree_model_get(model, iter, 0, &number, -1);
134                 index = atoi(number);
135                 break;
136         case CCS_SCREEN_EXCEPTION_LIST :
137                 view = transition->exp.listview;
138                 gtk_tree_model_get(model, iter, 0, &number, -1);
139                 index = atoi(number);
140                 break;
141         case CCS_SCREEN_PROFILE_LIST :
142                 view = transition->prf.listview;
143                 gtk_tree_model_get(model, iter, 0, &number, -1);
144                 index = atoi(number);
145                 break;
146         }
147         g_free(number);
148
149         if (index == get_locate_index(transition)) {
150                 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
151                 gtk_tree_selection_select_path(selection, path);
152                 view_cursor_set(view, gtk_tree_path_copy(path), NULL);
153                 return TRUE;
154         } else {
155                 return FALSE;
156         }
157 }
158
159 static gint get_list_count(transition_t *transition)
160 {
161         gint    count;
162
163         switch((int)transition->current_page) {
164         case CCS_SCREEN_DOMAIN_LIST :
165                 if (transition->task_flag) {
166                         count = transition->tsk.count;
167                 } else {
168                         count = transition->dp->list_len;
169                 }
170                 break;
171         case CCS_SCREEN_ACL_LIST :
172                 count = transition->acl.count;
173                 break;
174         case CCS_SCREEN_EXCEPTION_LIST :
175                 count = transition->exp.count;
176                 break;
177         case CCS_SCREEN_PROFILE_LIST :
178                 count = transition->prf.count;
179                 break;
180         case CCS_SCREEN_MANAGER_LIST :
181         default :
182                 count = -1;
183                 break;
184         }
185         return count;
186 }
187
188 static gint get_current_index(transition_t *transition)
189 {
190         gint    index;
191
192         switch((int)transition->current_page) {
193         case CCS_SCREEN_DOMAIN_LIST :
194                 if (transition->task_flag) {
195                         index = get_current_process_index(&(transition->tsk));
196                 } else {
197                         index = get_current_domain_index(transition);
198                 }
199                 break;
200         case CCS_SCREEN_ACL_LIST :
201                 index = select_list_line(&(transition->acl));
202                 break;
203         case CCS_SCREEN_EXCEPTION_LIST :
204                 index = select_list_line(&(transition->exp));
205                 break;
206         case CCS_SCREEN_PROFILE_LIST :
207                 index = select_list_line(&(transition->prf));
208                 break;
209         case CCS_SCREEN_MANAGER_LIST :
210         default :
211                 index = 0;
212                 break;
213         }
214         return index;
215 }
216
217 static void search(transition_t *transition, gboolean forward)
218 {
219         GtkWidget       *view = NULL;
220         gint            index, count;
221         gchar           *str_p = NULL;
222
223         index = get_current_index(transition);
224         count = get_list_count(transition);
225         while (S_entry) {
226                 forward ? index++ : index--;
227                 if (index < 0 || count <= index)
228                         break;
229
230                 switch((int)transition->current_page) {
231                 case CCS_SCREEN_DOMAIN_LIST :
232                         if (transition->task_flag) {
233                                 view = transition->tsk.treeview;
234                                 str_p = transition->tsk.task[index].name;
235                         } else {
236                                 view = transition->treeview;
237                                 str_p = (gchar *)get_domain_last_name(index);
238                         }
239                         break;
240                 case CCS_SCREEN_ACL_LIST :
241                         view = transition->acl.listview;
242                         str_p = g_strdup_printf("%s %s",
243                                         ccs_directives[transition->acl.list
244                                                 [index].directive].alias,
245                                         transition->acl.list[index].operand);
246                         break;
247                 case CCS_SCREEN_EXCEPTION_LIST :
248                         view = transition->exp.listview;
249                         str_p = g_strdup_printf("%s %s",
250                                         ccs_directives[transition->exp.list
251                                                 [index].directive].alias,
252                                         transition->exp.list[index].operand);
253                         break;
254                 case CCS_SCREEN_PROFILE_LIST :
255                         view = transition->prf.listview;
256                         str_p = g_strdup_printf("%u-%s",
257                                           transition->prf.list[index].directive,
258                                           transition->prf.list[index].operand);
259                         break;
260                 case CCS_SCREEN_MANAGER_LIST :
261                 default :
262                         return;
263                         break;
264                 }
265
266                 if(g_strrstr(str_p, S_entry)) {
267                         GtkTreeModel    *model;
268                         put_locate_index(transition, index);
269                         model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
270                         gtk_tree_model_foreach(model,
271                           (GtkTreeModelForeachFunc)search_pos_list, transition);
272                         break;
273                 }
274         }
275
276         if (transition->current_page != CCS_SCREEN_DOMAIN_LIST)
277                 g_free(str_p);
278
279         gtk_action_set_sensitive(gtk_action_group_get_action(
280                                 transition->actions, "SearchBack"), TRUE);
281         gtk_action_set_sensitive(gtk_action_group_get_action(
282                                 transition->actions, "SearchFoward"), TRUE);
283 }
284
285 /*-------+---------+---------+---------+---------+---------+---------+--------*/
286 static void cb_combo_changed(GtkComboBox *combobox, gpointer nothing)
287 {
288         GtkTreeModel    *model;
289         GtkTreeIter     iter;
290         gchar           *text;
291
292         model = gtk_combo_box_get_model(combobox);
293         if (gtk_combo_box_get_active_iter(combobox, &iter)) {
294                 gtk_tree_model_get(model, &iter, 0, &text, -1);
295                 g_free(S_entry);
296                 S_entry = text;
297 //              g_print("cb_combo_changed[%s]\n", text);
298         }
299 }
300
301 static void cb_combo_entry_activate(GtkEntry *entry, search_t *srch)
302 {
303         GtkComboBox     *combobox;
304         gchar           *new_text;
305         GList           *list;
306         gboolean        exist_flag = FALSE;
307
308         combobox = GTK_COMBO_BOX(srch->combo);
309         new_text = gtk_combo_box_get_active_text(combobox);
310         if(!new_text || strcmp(new_text, "") == 0)
311                 return;
312
313         g_free(S_entry);
314         S_entry = g_strdup(new_text);
315 //      g_print("cb_combo_entry_activate[%s]\n", new_text);
316
317         for (list = combolist; list; list = g_list_next(list)) {
318                 if (strcmp(new_text, (gchar *)list->data) == 0) {
319                         exist_flag = TRUE;
320                         break;
321                 }
322         }
323
324         if (!exist_flag) {
325                 guint len;
326                 combolist = insert_item(combobox, combolist, new_text, 0);
327                 len = g_list_length(combolist);
328                 if (len > COMBO_LIST_LIMIT) {
329                         combolist = remove_item(combobox, combolist, len - 1);
330                 }
331         }
332
333         if (entry)
334                 search(srch->tran, TRUE);
335 }
336
337 static void cb_btn_prev_clicked(GtkButton *widget , search_t *srch)
338 {
339         cb_combo_entry_activate(NULL, srch);
340         search(srch->tran, FALSE);
341 }
342
343 static void cb_btn_next_clicked(GtkButton *widget , search_t *srch)
344 {
345         cb_combo_entry_activate(NULL, srch);
346         search(srch->tran, TRUE);
347 }
348 /*-------+---------+---------+---------+---------+---------+---------+--------*/
349 GList *insert_item(GtkComboBox  *combobox,
350                         GList *cmblist, const gchar *item_label, gint index)
351 {
352         gtk_combo_box_insert_text(combobox, index, g_strdup(item_label));
353         return g_list_insert(cmblist, g_strdup(item_label), index);
354 }
355
356 GList *remove_item(GtkComboBox *combobox, GList *cmblist, gint index)
357 {
358         gtk_combo_box_remove_text(combobox, index);
359         g_free(g_list_nth_data(cmblist, index));
360         return g_list_delete_link(cmblist, g_list_nth(cmblist, index));
361 }
362
363 static gchar *search_title(transition_t *transition)
364 {
365         gchar           *title;
366
367         switch((int)transition->current_page) {
368         case CCS_SCREEN_DOMAIN_LIST :
369                 if (transition->task_flag) {
370                         title = _("Process Search for :");
371                 } else {
372                         title = _("Domain Search for :");
373                 }
374                 break;
375         case CCS_SCREEN_ACL_LIST :
376                 title = _("ACL Search for :");
377                 break;
378         case CCS_SCREEN_EXCEPTION_LIST :
379                 title = _("Exception Search for :");
380                 break;
381         case CCS_SCREEN_PROFILE_LIST :
382                 title = _("Profile Search for :");
383                 break;
384         case CCS_SCREEN_MANAGER_LIST :
385         default :
386                 title = _("Search for :");
387                 break;
388         }
389         return title;
390 }
391
392 void search_input(GtkAction *action, transition_t *transition)
393 {
394         GtkWidget               *dialog, *parent;
395         GtkWidget               *hbox, *vbox_l, *vbox_r;
396         GtkWidget               *label;
397         GtkWidget               *entry;
398         GtkWidget               *btn_next, *btn_prev;
399         GList                   *list;
400         search_t                srch;
401         gint                    response;
402
403         parent = (transition->acl_detached &&
404                 (int)transition->current_page == CCS_SCREEN_ACL_LIST) ?
405                         transition->acl_window : transition->window;
406
407         dialog = gtk_dialog_new_with_buttons(_("Find"),
408                         GTK_WINDOW(parent),
409                         GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
410                         GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
411                         NULL);
412
413         hbox = gtk_hbox_new(FALSE, 5);
414         gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
415                                                 hbox, TRUE, TRUE, 0);
416         gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
417
418         vbox_l = gtk_vbox_new(FALSE, 5);
419         gtk_box_pack_start(GTK_BOX(hbox), vbox_l, TRUE, TRUE, 0);
420
421         label = gtk_label_new(NULL);
422         gtk_label_set_markup(GTK_LABEL(label), search_title(transition));
423         gtk_box_pack_start(GTK_BOX(vbox_l), label, FALSE, FALSE, 0);
424
425         entry = gtk_combo_box_entry_new_text();
426         srch.tran = transition;
427         srch.combo = entry;
428         g_signal_connect(G_OBJECT(entry) , "changed",
429                         G_CALLBACK(cb_combo_changed), NULL);
430         g_signal_connect(G_OBJECT(GTK_BIN(entry)->child) , "activate" ,
431                         G_CALLBACK(cb_combo_entry_activate), &srch);
432         gtk_box_pack_start(GTK_BOX(vbox_l), entry, FALSE, FALSE, 0);
433
434         for (list = combolist; list; list = g_list_next(list)) {
435                 gtk_combo_box_append_text(
436                         GTK_COMBO_BOX(entry), (gchar *)list->data);
437         }
438         gtk_combo_box_set_active(GTK_COMBO_BOX(entry), 0);
439
440         vbox_r = gtk_vbox_new(FALSE, 5);
441         gtk_box_pack_start(GTK_BOX(hbox), vbox_r, FALSE, FALSE, 0);
442
443         btn_prev = gtk_button_new_from_stock(GTK_STOCK_GO_BACK);
444         gtk_box_pack_start(GTK_BOX(vbox_r), btn_prev, FALSE, FALSE, 0);
445         g_signal_connect(G_OBJECT(btn_prev) , "clicked" ,
446                         G_CALLBACK (cb_btn_prev_clicked) , &srch);
447
448         btn_next = gtk_button_new_from_stock(GTK_STOCK_GO_FORWARD);
449         gtk_box_pack_start(GTK_BOX(vbox_r), btn_next, FALSE, FALSE, 0);
450         g_signal_connect(G_OBJECT(btn_next) , "clicked" ,
451                         G_CALLBACK (cb_btn_next_clicked) , &srch);
452
453         gtk_widget_set_size_request(dialog, 400, -1);
454         put_locate_index(transition, get_current_index(transition));
455         gtk_widget_show_all(dialog);
456
457         response = gtk_dialog_run(GTK_DIALOG(dialog));
458         gtk_widget_destroy(dialog);
459 }
460
461 void search_back(GtkAction *action, transition_t *transition)
462 {
463         search(transition, FALSE);
464 }
465
466 void search_forward(GtkAction *action, transition_t *transition)
467 {
468         search(transition, TRUE);
469 }
470 /*-------+---------+---------+---------+---------+---------+---------+--------*/