OSDN Git Service

for CentOS 5.5
[gpet/origin.git] / src / gpet.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  * gpet.c
6  * Copyright (C) Yoshihiro Kusuno 2010 <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 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include <stdio.h>
28
29 #ifdef HAVE_CONFIG_H
30 #  include <config.h>
31 #endif
32
33 #include <gtk/gtk.h>
34 #include <glib/gi18n.h>
35
36 #include "gpet.h"
37
38 /*---------------------------------------------------------------------------*/
39 enum tree_column_pos {
40         COLUMN_INDEX,                   // data index (invisible)
41         COLUMN_NUMBER,          // n
42         COLUMN_COLON,                   // :
43         COLUMN_PROFILE,         // profile
44         COLUMN_KEEPER_DOMAIN,   // #
45         COLUMN_INITIALIZER_TARGET,      // *
46         COLUMN_DOMAIN_UNREACHABLE,      // !
47         COLUMN_DOMAIN_NAME,             // domain name
48         COLUMN_COLOR,                   // text color
49         COLUMN_REDIRECT,                // redirect index (invisible)
50         N_COLUMNS_TREE
51 };
52 /*---------------------------------------------------------------------------*/
53 static int add_tree_store(GtkTreeStore *store, GtkTreeIter *parent_iter,
54                         struct ccs_domain_policy *dp, int *index, int nest)
55 {
56         GtkTreeIter     iter;
57         gchar           *color = "black";
58         gchar           *str_num, *str_prof;
59         gchar           *line = NULL, *is_dis = NULL, *domain;
60         const char      *sp;
61         const struct ccs_transition_control_entry *transition_control;
62         int             n, number, redirect_index = -1;
63
64         sp = ccs_domain_name(dp, *index);
65         for (n = 0; ; n++) {
66                 const char *cp = strchr(sp, ' ');
67                 if (!cp)
68                         break;
69                 sp = cp + 1;
70         }
71
72         gtk_tree_store_append(store, &iter, parent_iter);
73         number = dp->list[*index].number;
74         if (number >= 0) {
75                 str_num = g_strdup_printf("%4d", number);
76                 str_prof = dp->list[*index].profile_assigned ? 
77                         g_strdup_printf("%3u", dp->list[*index].profile) : 
78                         g_strdup("???");
79         } else {
80                 str_num = g_strdup("");
81                 str_prof = g_strdup("");
82         }
83
84         gtk_tree_store_set(store, &iter,
85                 COLUMN_INDEX,           *index,
86                 COLUMN_NUMBER,          str_num,
87                 COLUMN_COLON,           number >= 0 ? ":" : "",
88                 COLUMN_PROFILE,         str_prof,
89                 COLUMN_KEEPER_DOMAIN,   dp->list[*index].is_dk ? "#" : " ",
90                 COLUMN_INITIALIZER_TARGET, dp->list[*index].is_dit ? "*" : " ",
91                 COLUMN_DOMAIN_UNREACHABLE, dp->list[*index].is_du ? "!" : " ",
92                 -1);
93         g_free(str_num);
94         g_free(str_prof);
95
96         transition_control = dp->list[*index].d_t;
97         if (transition_control && !(dp->list[*index].is_dis)) {
98                 line = g_strdup_printf(" ( %s%s from %s )",
99                         get_transition_name(transition_control->type),
100                         transition_control->program ?
101                                 transition_control->program->name : "any",
102                         transition_control->domainname ?
103                                 transition_control->domainname->name : "any");
104                 color = 
105                 transition_control->type == CCS_TRANSITION_CONTROL_KEEP ?
106                 "green" : "cyan";
107         } else if (dp->list[*index].is_dis) {   /* initialize_domain */
108                 is_dis = g_strdup_printf(CCS_ROOT_NAME "%s", 
109                                 strrchr(ccs_domain_name(dp, *index), ' '));
110                 redirect_index = ccs_find_domain(dp, is_dis, false, false);
111                 g_free(is_dis);
112                 color = "blue";
113                 if (redirect_index >= 0)
114                         is_dis = g_strdup_printf(" ( -> %d )",
115                                         dp->list[redirect_index].number);
116                 else
117                         is_dis = g_strdup_printf(" ( -> Not Found )");
118         } else if (dp->list[*index].is_dd) {    /* delete_domain */
119                 color = "gray";
120         }
121         domain = g_strdup_printf("%s%s%s%s%s",
122                         dp->list[*index].is_dd ? "( " : "",
123                         sp,
124                         dp->list[*index].is_dd ? " )" : "",
125                         line ? line : "",
126                         is_dis ? is_dis : ""
127                         );
128         gtk_tree_store_set(store, &iter, COLUMN_DOMAIN_NAME, domain,
129                                          COLUMN_COLOR, color,
130                                          COLUMN_REDIRECT, redirect_index, -1);
131         g_free(line);
132         g_free(is_dis);
133         g_free(domain);
134
135         (*index)++;
136
137         while (*index < dp->list_len) {
138                 sp = ccs_domain_name(dp, *index);
139                 for (n = 0; ; n++) {
140                         const char *cp = strchr(sp, ' ');
141                         if (!cp)
142                                 break;
143                         sp = cp + 1;
144                 }
145
146                 if (n > nest)
147                         n = add_tree_store(store, &iter, dp, index, n);
148                 else
149                         break;
150         }
151
152         return n;
153 }
154
155 void add_tree_data(GtkTreeView *treeview, struct ccs_domain_policy *dp)
156 {
157         GtkTreeStore    *store;
158         GtkTreeIter     *iter = NULL;
159         int             index = 0, nest = -1;
160         
161         store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
162         gtk_tree_store_clear(store);
163         add_tree_store(store, iter, dp, &index, nest);
164 }
165 /*---------------------------------------------------------------------------*/
166 static GtkTreeViewColumn *column_add(
167                 GtkCellRenderer *renderer,
168                 const GtkWidget *treeview,
169                 const gchar *title,
170                 enum tree_column_pos pos,
171                 const gchar *attribute,
172                 const gfloat xalign
173                 )
174 {
175         GtkTreeViewColumn       *column;
176
177         g_object_set(renderer, "xalign", xalign, "ypad", 0, NULL);
178         column = gtk_tree_view_column_new_with_attributes(
179                                 title, renderer, attribute, pos, NULL);
180         gtk_tree_view_column_add_attribute(column, renderer,
181                                         "foreground", COLUMN_COLOR);
182 //      gtk_tree_view_column_set_alignment(column, xalign);
183         gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
184
185         return column;
186 }
187 /*---------------------------------------------------------------------------*/
188 /*
189 static void cb_status_toggled(GtkCellRendererToggle     *renderer,
190                                gchar                    *path_string,
191                                gpointer                 user_data)
192 {
193         GtkTreeModel    *model;
194         GtkTreeIter     iter;
195         GtkTreePath     *path;
196         gboolean        status;
197
198         model = gtk_tree_view_get_model(GTK_TREE_VIEW(user_data));
199         path  = gtk_tree_path_new_from_string(path_string);
200
201         gtk_tree_model_get_iter(model, &iter, path);
202         gtk_tree_model_get(model, &iter, COLUMN_INDEX, &status, -1);
203         gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
204                       COLUMN_INDEX, !status, -1);
205         gtk_tree_path_free(path);
206 }
207 */
208 /*---------------------------------------------------------------------------*/
209 static GtkWidget *create_tree_model(void)
210 {
211         GtkWidget               *treeview;
212         GtkTreeStore            *store;
213 //      GtkCellRenderer *renderer;
214         GtkTreeViewColumn       *column;
215
216         store = gtk_tree_store_new(N_COLUMNS_TREE,
217                                 G_TYPE_INT,
218                                 G_TYPE_STRING,
219                                 G_TYPE_STRING,
220                                 G_TYPE_STRING,
221                                 G_TYPE_STRING,
222                                 G_TYPE_STRING,
223                                 G_TYPE_STRING,
224                                 G_TYPE_STRING,
225                                 G_TYPE_STRING,
226                                 G_TYPE_INT);
227         treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
228         g_object_unref(store);
229
230 // TODO refactoring
231 //      renderer = gtk_cell_renderer_toggle_new();
232 //      g_signal_connect(renderer, "toggled",
233 //                  G_CALLBACK(cb_status_toggled), treeview);
234 /*
235         renderer = gtk_cell_renderer_text_new();
236         g_object_set(renderer, "visible", FALSE, NULL);
237         column = column_add(renderer, treeview,
238                         "", COLUMN_INDEX, "text", 0.0);
239 */
240         column = column_add(gtk_cell_renderer_text_new(), treeview,
241                         "No.", COLUMN_NUMBER, "text", 1.0);
242         column = column_add(gtk_cell_renderer_text_new(), treeview,
243                         " ", COLUMN_COLON, "text", 0.5);
244         column = column_add(gtk_cell_renderer_text_new(), treeview,
245                         "prof", COLUMN_PROFILE, "text", 1.0);
246         column = column_add(gtk_cell_renderer_text_new(), treeview,
247                         "#", COLUMN_KEEPER_DOMAIN, "text", 0.5);
248         column = column_add(gtk_cell_renderer_text_new(), treeview,
249                         "*", COLUMN_INITIALIZER_TARGET, "text", 0.5);
250         column = column_add(gtk_cell_renderer_text_new(), treeview,
251                         "!", COLUMN_DOMAIN_UNREACHABLE, "text", 0.5);
252         column = column_add(gtk_cell_renderer_text_new(), treeview,
253                         "Domain Name", COLUMN_DOMAIN_NAME, "text", 0.0);
254         // 開く位置
255         gtk_tree_view_set_expander_column(GTK_TREE_VIEW(treeview), column);
256 //      gtk_tree_view_column_set_spacing(column, 1);
257         // ヘッダ非表示
258         gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
259
260         return treeview;
261 }
262 /*---------------------------------------------------------------------------*/
263 enum list_column_pos {
264         LIST_NUMBER,            // n
265         LIST_COLON,             // :
266         LIST_ALIAS,             // 
267         LIST_OPERAND,           // 
268         N_COLUMNS_LIST
269 };
270
271 void add_list_data(generic_list_t *generic, gboolean alias_flag)
272 {
273         GtkListStore    *store;
274         GtkTreeIter     iter;
275         int             i;
276         gchar           *str_num, *profile, *alias;
277
278         store = GTK_LIST_STORE(gtk_tree_view_get_model(
279                                 GTK_TREE_VIEW(generic->listview)));
280
281         gtk_list_store_clear(store);
282         for(i = 0; i < generic->count; i++){
283                 str_num = g_strdup_printf("%4d", i);
284                 gtk_list_store_append(store, &iter);
285
286                 if (alias_flag) {
287                         alias = (gchar *)
288                           ccs_directives[generic->list[i].directive].alias;
289                         gtk_list_store_set(store, &iter,
290                                 LIST_NUMBER, str_num,
291                                 LIST_COLON,  ":",
292                                 LIST_ALIAS, alias,
293                                 LIST_OPERAND, generic->list[i].operand,
294                                 -1);
295                 } else {
296                         profile = g_strdup_printf("%3u-",
297                                         generic->list[i].directive);
298                         alias = g_strdup_printf("%s%s",
299                                         generic->list[i].directive < 256 ?
300                                         profile : "",
301                                         generic->list[i].operand);
302                         gtk_list_store_set(store, &iter,
303                                         LIST_NUMBER, str_num,
304                                         LIST_COLON,  ":",
305                                         LIST_OPERAND, alias,
306                                         -1);
307                         g_free(profile);
308                         g_free(alias);
309                 }
310                 g_free(str_num);
311         }
312 }
313
314 static GtkWidget *create_list_model(gboolean alias_flag)
315 {
316         GtkWidget               *treeview;
317         GtkListStore            *liststore;
318         GtkCellRenderer *renderer;
319         GtkTreeViewColumn       *column;
320
321         liststore = gtk_list_store_new(N_COLUMNS_LIST,
322                                   G_TYPE_STRING, G_TYPE_STRING,
323                                   G_TYPE_STRING, G_TYPE_STRING);
324         treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
325         g_object_unref(liststore);
326
327         renderer = gtk_cell_renderer_text_new();
328         g_object_set(renderer, "xalign", 1.0, "ypad", 0, NULL);
329         column = gtk_tree_view_column_new_with_attributes(
330                         "No.", renderer, "text", LIST_NUMBER, NULL);
331         gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
332         gtk_tree_view_column_set_sort_column_id(column, LIST_NUMBER);
333 //      gtk_tree_view_column_set_alignment(column, 1.0);
334
335         renderer = gtk_cell_renderer_text_new();
336         column = gtk_tree_view_column_new_with_attributes(" ", renderer,
337                                               "text", LIST_COLON, NULL);
338         gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
339
340         if (alias_flag) {
341                 renderer = gtk_cell_renderer_text_new();
342                 column = gtk_tree_view_column_new_with_attributes(
343                         "directive", renderer, "text", LIST_ALIAS, NULL);
344                 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
345                 gtk_tree_view_column_set_sort_column_id(column, LIST_ALIAS);
346         }
347
348         renderer = gtk_cell_renderer_text_new();
349         column = gtk_tree_view_column_new_with_attributes("operand", renderer,
350                                               "text", LIST_OPERAND, NULL);
351         gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
352         gtk_tree_view_column_set_sort_column_id(column, LIST_OPERAND);
353
354         // ヘッダ表示
355         gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), TRUE);
356
357         return treeview;
358 }
359 /*---------------------------------------------------------------------------*/
360 gint get_current_domain_index(transition_t *transition)
361 {
362         GtkTreeSelection        *selection;
363         GtkTreeIter             iter;
364         GtkTreeModel            *model;
365         GList                   *list;
366         gint                    index = -1;
367
368         selection = gtk_tree_view_get_selection(
369                                 GTK_TREE_VIEW(transition->treeview));
370         if (selection &&
371             gtk_tree_selection_count_selected_rows(selection)) {
372                 list = gtk_tree_selection_get_selected_rows(
373                                                         selection, NULL);
374                 model = gtk_tree_view_get_model(
375                                 GTK_TREE_VIEW(transition->treeview));
376                 gtk_tree_model_get_iter(model, &iter,
377                                                 g_list_first(list)->data);
378                 gtk_tree_model_get(model, &iter,
379                                                 COLUMN_INDEX, &index, -1);
380                 g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
381                 g_list_free(list);
382         }
383         DEBUG_PRINT("select Domain index[%d]\n", index);
384         return index;
385 }
386 /*---------------------------------------------------------------------------*/
387 static void cb_selection(GtkTreeSelection *selection,
388                                 transition_t *transition)
389 {
390         GtkTreeIter     iter;
391         gint            select_count;
392         GtkTreeModel    *model;
393         GList           *list;
394         gint            index;
395         GtkTreePath             *path = NULL;
396         GtkTreeViewColumn       *column = NULL;
397
398         select_count = gtk_tree_selection_count_selected_rows(selection);
399         DEBUG_PRINT("select count[%d]\n", select_count);
400         if (0 == select_count)
401                 return;
402
403         model = gtk_tree_view_get_model(
404                                 GTK_TREE_VIEW(transition->treeview));
405         list = gtk_tree_selection_get_selected_rows(selection, NULL);
406         gtk_tree_model_get_iter(model, &iter, g_list_first(list)->data);
407         g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
408         g_list_free(list);
409         gtk_tree_model_get(model, &iter, COLUMN_INDEX, &index, -1);
410         DEBUG_PRINT("--- index [%4d] ---\n", index);
411         gtk_entry_set_text(GTK_ENTRY(transition->domainbar),
412                                 ccs_domain_name(transition->dp, index));
413
414         gtk_tree_view_get_cursor(GTK_TREE_VIEW(
415                         transition->acl.listview), &path, &column);
416
417         get_acl_list(transition->dp, index,
418                 &(transition->acl.list), &(transition->acl.count));
419         add_list_data(&(transition->acl), TRUE);
420
421         view_cursor_set(transition->acl.listview, path, column);
422
423         if (transition->acl.count) {
424                 disp_statusbar(transition, CCS_SCREEN_ACL_LIST);
425         } else {        /* delete_domain or initializer_source */
426                 disp_statusbar(transition, CCS_MAXSCREEN);
427         }
428 }
429 /*---------------------------------------------------------------------------*/
430 struct FindIsDis_t {
431         gint            redirect_index;
432         GtkTreeIter     iter;
433         GtkTreePath     *path;
434 };
435
436 static gboolean find_is_dis(GtkTreeModel *model, GtkTreePath *path,
437                 GtkTreeIter *iter, struct FindIsDis_t *data)
438 {
439         gint            index;
440
441         gtk_tree_model_get(model, iter, COLUMN_INDEX, &index, -1);
442         if (data->redirect_index == index) {
443                 data->iter = *iter;
444                 data->path = gtk_tree_path_copy(path);
445                 return TRUE;
446         }
447         return FALSE;
448 }
449
450 static void cb_initialize_domain(GtkTreeView *treeview, GtkTreePath *treepath,
451                         GtkTreeViewColumn treeviewcolumn, gpointer dummy)
452 {
453         GtkTreeIter     iter;
454         GtkTreeModel    *model;
455         gboolean        ret;
456         struct FindIsDis_t      data;
457
458         model = gtk_tree_view_get_model(treeview);
459         ret = gtk_tree_model_get_iter(model, &iter, treepath);
460         if (ret)
461                 gtk_tree_model_get(model, &iter,
462                                 COLUMN_REDIRECT, &data.redirect_index, -1);
463         DEBUG_PRINT("redirect_index[%d]\n", data.redirect_index);
464         if (!ret || data.redirect_index < 0)
465                 return;         /* not initialize_domain */
466
467         data.path = NULL;
468         gtk_tree_model_foreach(model,
469                 (GtkTreeModelForeachFunc)find_is_dis, &data);
470
471         if (data.path) {
472                 gtk_tree_view_expand_to_path(GTK_TREE_VIEW(treeview), data.path);
473                 gtk_tree_selection_select_iter(
474                         gtk_tree_view_get_selection(
475                         GTK_TREE_VIEW(treeview)), &data.iter);
476                 gtk_tree_view_set_cursor(GTK_TREE_VIEW(treeview),
477                                                 data.path, NULL, FALSE);
478                 gtk_tree_path_free(data.path);
479         }
480 }
481 /*---------------------------------------------------------------------------*/
482 void set_sensitive(GtkActionGroup *actions, int task_flag,
483                                 enum ccs_screen_type current_page)
484 {
485         gboolean        sens_edt, sens_add, sens_del, sens_tsk;
486
487         sens_edt = sens_add = sens_del = sens_tsk = FALSE;
488
489         switch((int)current_page) {
490         case CCS_SCREEN_DOMAIN_LIST :
491         case CCS_MAXSCREEN :
492                 sens_edt = TRUE;
493                 sens_tsk = TRUE;
494                 if (task_flag) {
495                         sens_add = FALSE;
496                         sens_del = FALSE;
497                 } else {
498                         sens_add = TRUE;
499                         sens_del = TRUE;
500                 }
501                 break;
502         case CCS_SCREEN_ACL_LIST :
503                 sens_edt = FALSE;
504                 sens_add = TRUE;
505                 sens_del = TRUE;
506                 sens_tsk = TRUE;
507                 break;
508         case CCS_SCREEN_EXCEPTION_LIST :
509                 sens_edt = FALSE;
510                 sens_add = TRUE;
511                 sens_del = TRUE;
512                 sens_tsk = FALSE;
513                 break;
514         case CCS_SCREEN_PROFILE_LIST :
515                 sens_edt = TRUE;
516                 sens_add = TRUE;
517                 sens_del = FALSE;
518                 sens_tsk = FALSE;
519                 break;
520         }
521
522         gtk_action_set_sensitive(gtk_action_group_get_action(
523                                         actions, "Edit"), sens_edt);
524         gtk_action_set_sensitive(gtk_action_group_get_action(
525                                         actions, "Add"), sens_add);
526         gtk_action_set_sensitive(gtk_action_group_get_action(
527                                         actions, "Delete"), sens_del);
528         gtk_action_set_sensitive(gtk_action_group_get_action(
529                                         actions, "Process"), sens_tsk);
530 }
531
532 static gint popup_menu(transition_t *transition, guint button)
533 {
534         if (button == 3) {
535                 GtkWidget       *popup;
536                 /* get menu.c create_menu()*/
537                 popup = g_object_get_data(
538                                 G_OBJECT(transition->window), "popup");
539                 
540                 gtk_menu_popup(GTK_MENU(popup), NULL, NULL, NULL, NULL,
541                                         0, gtk_get_current_event_time());
542                 return TRUE;
543         }
544
545         return FALSE;
546 }
547
548 static gboolean cb_select_domain(GtkTreeView *treeview,  GdkEventButton *event,
549                                 transition_t *transition)
550 {
551         transition->current_page = CCS_SCREEN_DOMAIN_LIST;
552
553         set_sensitive(transition->actions, transition->task_flag,
554                                                 transition->current_page);
555         if (event->button == 3) {
556                 GtkWidget       *popup;
557                 /* get menu.c create_menu()*/
558                 popup = g_object_get_data(
559                                 G_OBJECT(transition->window), "popup");
560                 
561                 gtk_menu_popup(GTK_MENU(popup), NULL, NULL, NULL, NULL,
562                                         0, gtk_get_current_event_time());
563                 return TRUE;
564         }
565
566         return FALSE;
567 }
568
569 static gboolean cb_select_acl(GtkTreeView *listview,  GdkEventButton *event,
570                                 transition_t *transition)
571 {
572         transition->current_page = CCS_SCREEN_ACL_LIST;
573         set_sensitive(transition->actions, transition->task_flag,
574                                                 transition->current_page);
575         return popup_menu(transition, event->button);
576 }
577
578 static gboolean cb_select_exp(GtkTreeView *listview,  GdkEventButton *event,
579                                 transition_t *transition)
580 {
581         transition->current_page = CCS_SCREEN_EXCEPTION_LIST;
582         set_sensitive(transition->actions, transition->task_flag,
583                                                 transition->current_page);
584         return popup_menu(transition, event->button);
585 }
586
587 static gboolean cb_select_prf(GtkTreeView *listview,  GdkEventButton *event,
588                                 transition_t *transition)
589 {
590         transition->current_page = CCS_SCREEN_PROFILE_LIST;
591         set_sensitive(transition->actions, transition->task_flag,
592                                                 transition->current_page);
593         return popup_menu(transition, event->button);
594 }
595 /*---------------------------------------------------------------------------*/
596 static gboolean inc_search(GtkTreeModel *model, gint column,
597                 const gchar *key, GtkTreeIter *iter, gpointer search_data)
598 {
599         gchar   *buff;
600         gboolean ret;
601
602         gtk_tree_model_get(model, iter, column, &buff, -1);
603         DEBUG_PRINT("key[%s] buff[%s]\n", key, buff);
604         ret = g_strrstr(buff, key) ? FALSE : TRUE;
605         g_free(buff);
606
607         return ret;
608 }
609
610 void view_setting(GtkWidget *treeview, gint search_column)
611 {
612         // 複数行選択可
613         gtk_tree_selection_set_mode(
614                         gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)),
615                         GTK_SELECTION_MULTIPLE);
616         // マウス複数行選択
617         gtk_tree_view_set_rubber_banding(GTK_TREE_VIEW(treeview), TRUE);
618         // インクリメンタルサーチ
619         gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview),
620                                                         search_column);
621         gtk_tree_view_set_enable_search(GTK_TREE_VIEW(treeview), TRUE);
622         gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(treeview),
623                         (GtkTreeViewSearchEqualFunc)inc_search, NULL, NULL);
624 }
625
626 static GtkContainer *create_domain_view(GtkWidget *box,
627                 GtkWidget *treeview, void (*paned_pack)(), gboolean resize)
628 {
629         GtkWidget       *scrolledwin;
630         GtkContainer    *container;
631
632         scrolledwin = gtk_scrolled_window_new(NULL, NULL);
633         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
634                                 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
635         gtk_scrolled_window_set_shadow_type(
636                         GTK_SCROLLED_WINDOW(scrolledwin), GTK_SHADOW_IN);
637         paned_pack(GTK_PANED(box), scrolledwin, resize, TRUE);
638         container = GTK_CONTAINER(scrolledwin);
639         gtk_container_add(container, treeview);
640
641         view_setting(treeview, COLUMN_DOMAIN_NAME);
642
643         return container;
644 }
645 /*---------------------------------------------------------------------------*/
646 static void create_list_view(GtkWidget *box, GtkWidget *listview,
647                                 gboolean multi_flag)
648 {
649         GtkWidget       *scrolledwin;
650
651         scrolledwin = gtk_scrolled_window_new(NULL, NULL);
652         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
653                                         GTK_POLICY_AUTOMATIC,
654                                         GTK_POLICY_ALWAYS);
655         gtk_scrolled_window_set_shadow_type(
656                 GTK_SCROLLED_WINDOW(scrolledwin), GTK_SHADOW_IN);
657         gtk_box_pack_start(GTK_BOX(box), scrolledwin, TRUE, TRUE, 0);
658         gtk_container_add(GTK_CONTAINER(scrolledwin), listview);
659
660         if (multi_flag) {
661                 // 複数行選択可
662                 gtk_tree_selection_set_mode(
663                         gtk_tree_view_get_selection(
664                                 GTK_TREE_VIEW(listview)),
665                                 GTK_SELECTION_MULTIPLE);
666                 // マウス複数行選択
667                 gtk_tree_view_set_rubber_banding(
668                                         GTK_TREE_VIEW(listview), TRUE);
669         }
670         // インクリメンタルサーチ
671         gtk_tree_view_set_search_column(
672                 GTK_TREE_VIEW(listview), LIST_OPERAND);
673         gtk_tree_view_set_enable_search(
674                 GTK_TREE_VIEW(listview), TRUE);
675         gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(listview),
676                 (GtkTreeViewSearchEqualFunc)inc_search, NULL, NULL);
677 }
678 /*---------------------------------------------------------------------------*/
679 static void set_select_flag_domain(gpointer data,
680                                         transition_t *transition)
681 {
682         GtkTreeModel            *model;
683         GtkTreeIter             iter;
684         gint                    index;
685         struct ccs_domain_policy *dp = transition->dp;
686
687
688         model = gtk_tree_view_get_model(
689                                 GTK_TREE_VIEW(transition->treeview));
690         if (!model || !gtk_tree_model_get_iter(model, &iter, data)) {
691                 g_warning("ERROR: %s(%d)", __FILE__, __LINE__);
692                 return;
693         }
694         gtk_tree_model_get(model, &iter, COLUMN_INDEX, &index, -1);
695
696         DEBUG_PRINT("index[%d]\n", index);
697         /* deleted_domain or initializer_source */
698         if (!(dp->list[index].is_dd) && !(dp->list[index].is_dis))
699                 dp->list_selected[index] = 1;
700 }
701
702 gint delete_domain(transition_t *transition,
703                         GtkTreeSelection *selection, gint count)
704 {
705         GList           *list;
706         char            *err_buff = NULL;
707         int             result;
708
709
710         list = gtk_tree_selection_get_selected_rows(selection, NULL);
711         g_list_foreach(list, (GFunc)set_select_flag_domain, transition);
712
713         g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
714         g_list_free(list);
715
716         result = delete_domain_policy(transition->dp, &err_buff);
717         if (result) {
718                 g_warning("%s", err_buff);
719                 free(err_buff);
720         }
721
722         return result;
723 }
724 /*---------------------------------------------------------------------------*/
725 gint set_domain_profile(transition_t *transition,
726                         GtkTreeSelection *selection, guint profile)
727 {
728         char            *profile_str;
729         GList           *list;
730         char            *err_buff = NULL;
731         int             result;
732
733         list = gtk_tree_selection_get_selected_rows(selection, NULL);
734         if (transition->task_flag)
735                 g_list_foreach(list, (GFunc)set_select_flag_process,
736                                         &(transition->tsk));
737         else
738                 g_list_foreach(list, (GFunc)set_select_flag_domain,
739                                         transition);
740
741         g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
742         g_list_free(list);
743
744         profile_str = g_strdup_printf("%u", profile);
745         result = set_profile(transition->dp, profile_str, &err_buff);
746 //      g_free(profile_str);
747         if (result) {
748                 g_warning("%s", err_buff);
749                 free(err_buff);
750         }
751
752         return result;
753 }
754 /*---------------------------------------------------------------------------*/
755 gint select_profile_line(generic_list_t *prf)
756 {
757         GtkTreeSelection        *selection;
758         GtkTreeIter             iter;
759         GtkTreeModel            *model;
760         GList                   *list;
761         gchar                   *str_num;
762         gint                    index = -1;
763
764         selection = gtk_tree_view_get_selection(
765                                         GTK_TREE_VIEW(prf->listview));
766         if (!selection ||
767             !gtk_tree_selection_count_selected_rows(selection))
768                 return index;
769
770         list = gtk_tree_selection_get_selected_rows(selection, NULL);
771         model = gtk_tree_view_get_model(GTK_TREE_VIEW(prf->listview));
772         gtk_tree_model_get_iter(model, &iter, g_list_first(list)->data);
773         gtk_tree_model_get(model, &iter, LIST_NUMBER, &str_num, -1);
774         g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
775         g_list_free(list);
776
777         index = atoi(str_num);
778         g_free(str_num);
779
780         return index;
781 }
782 /*---------------------------------------------------------------------------*/
783 static void set_delete_flag_gen(gpointer data, generic_list_t *gen)
784 {
785         GtkTreeModel            *model;
786         GtkTreeIter             iter;
787         gchar                   *str_num;
788
789         model = gtk_tree_view_get_model(GTK_TREE_VIEW(gen->listview));
790         if (!model || !gtk_tree_model_get_iter(model, &iter, data)) {
791                 g_warning("ERROR: %s(%d)", __FILE__, __LINE__);
792                 return;
793         }
794         gtk_tree_model_get(model, &iter, LIST_NUMBER, &str_num, -1);
795
796         DEBUG_PRINT("index[%d]\n", atoi(str_num));
797         gen->list[atoi(str_num)].selected = 1;
798         g_free(str_num);
799 }
800
801 gint delete_acl(transition_t *transition,
802                         GtkTreeSelection *selection, gint count)
803 {
804         GList           *list;
805         char            *err_buff = NULL;
806         int             result;
807
808
809         list = gtk_tree_selection_get_selected_rows(selection, NULL);
810         g_list_foreach(list, (GFunc)set_delete_flag_gen, &(transition->acl));
811         g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
812         g_list_free(list);
813
814         result = delete_acl_policy(transition->dp, &err_buff,
815                         transition->acl.list, transition->acl.count);
816         if (result) {
817                 g_warning("%s", err_buff);
818                 free(err_buff);
819         }
820
821         return result;
822 }
823
824 gint delete_exp(transition_t *transition,
825                         GtkTreeSelection *selection, gint count)
826 {
827         GList           *list;
828         char            *err_buff = NULL;
829         int             result;
830
831         list = gtk_tree_selection_get_selected_rows(selection, NULL);
832         g_list_foreach(list, (GFunc)set_delete_flag_gen, &(transition->exp));
833         g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
834         g_list_free(list);
835
836         result = delete_exp_policy(transition->dp, &err_buff,
837                         transition->exp.list, transition->exp.count);
838         if (result) {
839                 g_warning("%s", err_buff);
840                 free(err_buff);
841         }
842
843         return result;
844 }
845 /*---------------------------------------------------------------------------*/
846 static void create_tabs(GtkWidget *notebook, GtkWidget *box, gchar *str)
847 {
848         GtkWidget       *label, *label_box, *menu_box;
849
850         // create tab
851         label_box = gtk_hbox_new(FALSE, 0);
852         label = gtk_label_new(str);
853         gtk_box_pack_start(GTK_BOX(label_box), label, FALSE, TRUE, 0);
854         gtk_widget_show_all(label_box);
855
856         // create context menu for tab
857         menu_box = gtk_hbox_new(FALSE, 0);
858         label = gtk_label_new(str);
859         gtk_box_pack_start(GTK_BOX(menu_box), label, FALSE, TRUE, 0);
860         gtk_widget_show_all(menu_box);
861
862         gtk_notebook_append_page_menu(GTK_NOTEBOOK(notebook),
863                                         box, label_box, menu_box);
864 }
865
866 static void disp_window_title(GtkWidget *window,
867                                         enum ccs_screen_type current_page)
868 {
869         char    *title;
870
871         switch((int)current_page) {
872         case CCS_SCREEN_DOMAIN_LIST :
873         case CCS_SCREEN_ACL_LIST :
874         case CCS_MAXSCREEN :
875                 title = is_offline() ?
876                  CCS_DISK_POLICY_DIR CCS_DISK_POLICY_DOMAIN_POLICY :
877                                         CCS_PROC_POLICY_DOMAIN_POLICY;
878                 break;
879         case CCS_SCREEN_EXCEPTION_LIST :
880                 title = is_offline() ?
881                 CCS_DISK_POLICY_DIR CCS_DISK_POLICY_EXCEPTION_POLICY :
882                                         CCS_PROC_POLICY_EXCEPTION_POLICY;
883                 break;
884         case CCS_SCREEN_PROFILE_LIST :
885                 title = is_offline() ?
886                  CCS_DISK_POLICY_DIR CCS_DISK_POLICY_PROFILE :
887                                         CCS_PROC_POLICY_PROFILE;
888                 break;
889         }
890         gtk_window_set_title(GTK_WINDOW(window), title); 
891 }
892
893 static void cb_switch_page(GtkWidget    *notebook,
894                                 GtkNotebookPage *page,
895                                 gint            page_num,
896                                 transition_t    *tran)
897 {
898         GtkTreeSelection        *selection_tree, *selection_list;
899         gint                    old_page_num;
900
901         old_page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
902         if (page_num == old_page_num)
903                 return;
904
905         switch(page_num) {
906         case 0 :
907                 selection_tree = gtk_tree_view_get_selection(
908                                         GTK_TREE_VIEW(tran->treeview));
909                 selection_list = gtk_tree_view_get_selection(
910                                         GTK_TREE_VIEW(tran->acl.listview));
911
912                 if (tran->task_flag ||
913                         (selection_tree &&
914                     gtk_tree_selection_count_selected_rows(selection_tree)))
915                         tran->current_page = CCS_SCREEN_DOMAIN_LIST;
916                 else if(selection_list &&
917                     gtk_tree_selection_count_selected_rows(selection_list))
918                         tran->current_page = CCS_SCREEN_ACL_LIST;
919                 else
920                         tran->current_page = CCS_MAXSCREEN;
921                 break;
922         case 1 :
923                 tran->current_page = CCS_SCREEN_EXCEPTION_LIST;
924                 break;
925         case 2 :
926                 tran->current_page = CCS_SCREEN_PROFILE_LIST;
927                 break;
928         }
929
930         disp_window_title(tran->window, tran->current_page);
931 //      disp_statusbar(tran, tran->current_page);
932         set_sensitive(tran->actions, tran->task_flag,
933                                         tran->current_page);
934
935         refresh_transition(NULL, tran);
936         DEBUG_PRINT("page[%2d]\n", page_num);
937 }
938 /*---------------------------------------------------------------------------*/
939 int gpet_main(void)
940 {
941         GtkWidget       *window;
942         GtkWidget       *menubar, *toolbar = NULL;
943         GtkWidget       *statusbar;
944         gint            contextid;
945         GtkWidget       *vbox, *vbox2, *vbox3, *vbox4;
946         GtkWidget       *notebook;
947         GtkWidget       *box;
948         GtkWidget       *domainbar;
949         GtkWidget       *treeview, *listview;
950         GtkContainer    *container;
951         struct ccs_domain_policy dp = { NULL, 0, NULL };
952         transition_t    transition;
953
954         transition.task_flag = 0;
955         if (get_domain_policy(&dp, &(transition.domain_count)))
956                 return 1;
957         /*-----------------------------------------------*/
958
959         window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
960         transition.window = window;
961         gtk_window_set_title(GTK_WINDOW(window), _("gpet"));
962         gtk_window_set_icon(GTK_WINDOW(window), get_png_file());
963         gtk_container_set_border_width(GTK_CONTAINER(window), 0);
964         g_signal_connect(G_OBJECT(window), "destroy",
965                                 G_CALLBACK(gtk_main_quit), NULL);
966
967         vbox = gtk_vbox_new(FALSE, 1);
968         gtk_container_add(GTK_CONTAINER(window), vbox);
969
970         // create menu bar & tool bar & popup menu
971         menubar = create_menu(window, &transition, &toolbar);
972         gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
973         gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
974
975         // create notebook
976         notebook = gtk_notebook_new();
977         gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), TRUE);
978         gtk_notebook_popup_enable(GTK_NOTEBOOK(notebook));
979         gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
980
981         // create status bar
982         statusbar = gtk_statusbar_new();
983         gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, FALSE, 0);
984         contextid = gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbar), "");
985         gtk_statusbar_push(GTK_STATUSBAR(statusbar), contextid, _("gpet"));
986
987
988         vbox2 = gtk_vbox_new(FALSE, 1);
989         // create name bar for full domain name
990         domainbar = gtk_entry_new();
991         gtk_box_pack_start(GTK_BOX(vbox2), domainbar, FALSE, FALSE, 0);
992         gtk_editable_set_editable(GTK_EDITABLE(domainbar), FALSE);
993         gtk_entry_set_has_frame(GTK_ENTRY(domainbar), FALSE);
994         gtk_entry_set_text(GTK_ENTRY(domainbar), "");
995
996         box = gtk_vpaned_new();
997         g_object_set_data(G_OBJECT(window), "pane", box);/* to save config */
998         gtk_container_add(GTK_CONTAINER(vbox2), box);
999
1000         // create domain transition view
1001         treeview = create_tree_model();
1002         container = create_domain_view(
1003                                 box, treeview, gtk_paned_pack1, TRUE);
1004         add_tree_data(GTK_TREE_VIEW(treeview), &dp);
1005         gtk_tree_view_expand_all(GTK_TREE_VIEW(treeview));
1006                 // ツリーインデント pixel(2.12)
1007 //      gtk_tree_view_set_level_indentation(GTK_TREE_VIEW(treeview), 0);
1008                 // ツリー開くマーク(2.12)
1009 //      gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(treeview), TRUE);
1010         g_object_set(G_OBJECT(treeview), "enable-tree-lines", FALSE,
1011                                                 NULL);
1012 //      gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(treeview),
1013 //                                      GTK_TREE_VIEW_GRID_LINES_NONE);
1014         // create domain policy view
1015         listview = create_list_model(TRUE);
1016         create_domain_view(box, listview, gtk_paned_pack2, FALSE);
1017
1018         // copy data pointer
1019         transition.domainbar = domainbar;
1020         transition.container = container;
1021         transition.treeview = treeview;
1022         transition.acl.listview = listview;
1023         transition.statusbar = statusbar;
1024         transition.contextid = contextid;
1025         transition.dp = &dp;
1026         transition.acl.count = 0;
1027         transition.acl.list = NULL;
1028         transition.tsk.treeview = create_task_tree_model(&transition);
1029
1030         // cursor move  domain window
1031         g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)),
1032                                 "changed", G_CALLBACK(cb_selection), &transition);
1033         // double click or enter key  domain window
1034         g_signal_connect(G_OBJECT(treeview), "row-activated", 
1035                          G_CALLBACK(cb_initialize_domain), NULL);
1036         // mouse click  domain window
1037         g_signal_connect(G_OBJECT(treeview), "button-press-event", 
1038                          G_CALLBACK(cb_select_domain), &transition);
1039         // mouse click  acl window
1040         g_signal_connect(G_OBJECT(listview), "button-press-event", 
1041                          G_CALLBACK(cb_select_acl), &transition);
1042
1043
1044         vbox3 = gtk_vbox_new(FALSE, 1);
1045         // create exception policy view
1046         listview = create_list_model(TRUE);
1047         create_list_view(vbox3, listview, TRUE);
1048         transition.exp.listview = listview;
1049         // mouse click  exception window
1050         g_signal_connect(G_OBJECT(listview), "button-press-event", 
1051                          G_CALLBACK(cb_select_exp), &transition);
1052
1053         vbox4 = gtk_vbox_new(FALSE, 1);
1054         // create profile view
1055         listview = create_list_model(FALSE);
1056         create_list_view(vbox4, listview, FALSE);
1057         transition.prf.listview = listview;
1058         transition.prf.count = 0;
1059         transition.prf.list = NULL;
1060         if (get_profile(&(transition.prf.list), &(transition.prf.count)))
1061                 g_warning("Read error : profile");
1062         else
1063                 add_list_data(&(transition.prf), FALSE);
1064         // mouse click  profile window
1065         g_signal_connect(G_OBJECT(listview), "button-press-event", 
1066                          G_CALLBACK(cb_select_prf), &transition);
1067
1068         // create tab
1069         create_tabs(notebook, vbox2, _("Domain Transition"));
1070         create_tabs(notebook, vbox3, _("Exception Policy"));
1071         create_tabs(notebook, vbox4, _("Profile"));
1072
1073         /* to save menu.c Process_state() */
1074         g_object_set_data(G_OBJECT(window), "notebook", notebook);
1075         g_object_set_data(G_OBJECT(window), "vbox2", vbox2);
1076
1077         // tab change
1078         g_signal_connect(G_OBJECT(notebook), "switch_page",
1079                                 G_CALLBACK(cb_switch_page), &transition);
1080 /*
1081         gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(transition.treeview), TRUE);
1082         gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(transition.acl.listview), TRUE);
1083         gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(transition.exp.listview), TRUE);
1084         gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(transition.prf.listview), TRUE);
1085 */
1086         read_config(&transition);
1087         gtk_widget_show_all(window);
1088
1089         gtk_main();
1090
1091         return 0;
1092 }
1093 /*---------------------------------------------------------------------------*/
1094 int main(int argc, char **argv)
1095 {
1096         int     result;
1097
1098 #ifdef ENABLE_NLS
1099         bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
1100         bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
1101         textdomain(GETTEXT_PACKAGE);
1102 #endif
1103         
1104         gtk_init(&argc, &argv);
1105
1106         result = ccs_main(argc, argv);
1107
1108         return result;
1109 }
1110 /*---------------------------------------------------------------------------*/