OSDN Git Service

03fabb517e33b0a5b9e81c039bb273a40aec6c0a
[gpet/origin.git] / src / other.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  * other.c
6  * Copyright (C) Yoshihiro Kusuno 2010,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 #define PRINT_WARN(err) {g_warning("%s", err->message);g_error_free(err);err = NULL;}
33
34 typedef struct _other_t {
35         GtkWidget               *dialog;
36         GtkActionGroup  *actions;
37         GtkWidget               *popup;
38         generic_list_t  manager;
39         generic_list_t  memory;
40 } other_t;
41
42 static void edit_memory(GtkAction *action, other_t *data);
43 static void append_manager(GtkAction *action, other_t *data);
44 static void delete_manager(GtkAction *action, other_t *data);
45
46 static GtkActionEntry entries[] = {
47   {"Edit", GTK_STOCK_EDIT, N_("_Edit"), "<control>E",
48         N_("Edit the selected line"), G_CALLBACK(edit_memory)},
49   {"Add", GTK_STOCK_ADD, N_("_Add"), "<control>I",
50         N_("Append line"), G_CALLBACK(append_manager)},
51   {"Delete", GTK_STOCK_DELETE, N_("_Delete"), "<control>D",
52         N_("Delete the selected line"), G_CALLBACK(delete_manager)},
53 };
54
55 static guint n_entries = G_N_ELEMENTS(entries);
56
57 static const gchar *ui_info =
58 "<ui>"
59 "  <toolbar name='ToolBar'>"
60 "    <toolitem action='Edit'/>"
61 "    <toolitem action='Add'/>"
62 "    <toolitem action='Delete'/>"
63 "  </toolbar>"
64
65 "  <popup name='PopUp'>"
66 "      <menuitem action='Edit'/>"
67 "      <menuitem action='Add'/>"
68 "      <menuitem action='Delete'/>"
69 "  </popup>"
70 "</ui>";
71
72 static GtkWidget *create_dialog_menu(GtkWidget *parent, other_t *data)
73 {
74         GtkUIManager            *ui;
75         GtkActionGroup  *actions;
76         GtkWidget               *toolbar;
77         GError                  *error = NULL;
78
79         actions = gtk_action_group_new("Actions");
80         gtk_action_group_set_translation_domain(actions, GETTEXT_PACKAGE);
81         gtk_action_group_add_actions(actions, entries, n_entries, data);
82
83         ui = gtk_ui_manager_new();
84         gtk_ui_manager_insert_action_group(ui, actions, 0);
85
86         gtk_action_set_sensitive(gtk_action_group_get_action(
87                                                 actions, "Edit"), FALSE);
88         gtk_action_set_sensitive(gtk_action_group_get_action(
89                                                 actions, "Add"), FALSE);
90         gtk_action_set_sensitive(gtk_action_group_get_action(
91                                                 actions, "Delete"), FALSE);
92         data->actions = actions;
93
94         gtk_window_add_accel_group(GTK_WINDOW(parent),
95                                 gtk_ui_manager_get_accel_group(ui));
96         if (!gtk_ui_manager_add_ui_from_string(ui, ui_info, -1, NULL)) {
97                 g_message("building menus failed: %s", error->message);
98                 g_error_free(error);
99         }
100
101         toolbar = gtk_ui_manager_get_widget(ui, "/ToolBar");
102         gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
103
104         data->popup = gtk_ui_manager_get_widget(ui, "/PopUp");
105
106         return toolbar;
107 }
108 /*-------+---------+---------+---------+---------+---------+---------+--------*/
109
110 enum list_column_pos {
111         LIST_NUMBER,            // n
112         LIST_COLON,             // :
113         LIST_MANAGER,           // display
114         N_COLUMNS_LIST
115 };
116 static GtkWidget *create_list_manager(void)
117 {
118         GtkWidget               *treeview;
119         GtkListStore            *liststore;
120         GtkCellRenderer *renderer;
121         GtkTreeViewColumn       *column;
122
123         liststore = gtk_list_store_new(N_COLUMNS_LIST,
124                                 G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING);
125         treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
126         g_object_unref(liststore);
127
128         renderer = gtk_cell_renderer_text_new();
129         g_object_set(renderer, "xalign", 1.0, "ypad", 0, NULL);
130         column = gtk_tree_view_column_new_with_attributes(
131                         "No.", renderer, "text", LIST_NUMBER, NULL);
132         gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
133         gtk_tree_view_column_set_sort_column_id(column, LIST_NUMBER);
134
135         renderer = gtk_cell_renderer_text_new();
136         column = gtk_tree_view_column_new_with_attributes(" ", renderer,
137                                               "text", LIST_COLON, NULL);
138         gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
139
140         renderer = gtk_cell_renderer_text_new();
141         column = gtk_tree_view_column_new_with_attributes("operand",
142                         renderer, "text", LIST_MANAGER, NULL);
143         gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
144         gtk_tree_view_column_set_sort_column_id(column, LIST_MANAGER);
145
146         // ヘッダ表示
147         gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), TRUE);
148
149         return treeview;
150 }
151
152 static void add_list_manager(generic_list_t *man)
153 {
154         GtkTreePath             *path = NULL;
155         GtkTreeViewColumn       *column = NULL;
156         GtkListStore            *store;
157         GtkTreeIter             iter;
158         gint                    i;
159
160         gtk_tree_view_get_cursor(GTK_TREE_VIEW(
161                         man->listview), &path, &column);
162
163         get_manager(&(man->list), &(man->count));
164         store = GTK_LIST_STORE(gtk_tree_view_get_model(
165                                         GTK_TREE_VIEW(man->listview)));
166
167         gtk_list_store_clear(store);
168         for(i = 0; i < man->count; i++){
169                 gtk_list_store_append(store, &iter);
170                 gtk_list_store_set(store, &iter,
171                                         LIST_NUMBER, i,
172                                         LIST_COLON,  ":",
173                                         LIST_MANAGER, man->list[i].operand,
174                                         -1);
175         }
176
177         view_cursor_set(man->listview, path, column);
178         gtk_widget_grab_focus(man->listview);
179 }
180
181 static void create_manager_view(GtkWidget *dialog, GtkWidget *listview)
182 {
183         GtkWidget       *scrolledwin;
184
185         scrolledwin = gtk_scrolled_window_new(NULL, NULL);
186         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
187                         GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
188         gtk_scrolled_window_set_shadow_type(
189                 GTK_SCROLLED_WINDOW(scrolledwin), GTK_SHADOW_IN);
190
191         gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
192                                         scrolledwin, TRUE, TRUE, 0);
193         gtk_container_add(GTK_CONTAINER(scrolledwin), listview);
194
195         view_setting(listview, LIST_MANAGER);
196 }
197
198 static gboolean cb_select_list(GtkTreeView *listview,
199                                 GdkEventButton *event, other_t *data)
200 {
201         if (event->button == 3) {
202                 gtk_menu_popup(GTK_MENU(data->popup),
203                                         NULL, NULL, NULL, NULL,
204                                         0, gtk_get_current_event_time());
205                 return TRUE;
206         }
207
208         return FALSE;
209 }
210
211 /*-------+---------+---------+---------+---------+---------+---------+--------*/
212 static void cb_button(GtkButton *button, gpointer data)
213 {
214         GtkWidget               *dialog;
215         GtkWidget               *parent;
216         GtkWidget               *entry;
217         static gchar            *folder = NULL;
218         gint                    response;
219
220
221         parent = GTK_WIDGET(g_object_get_data(G_OBJECT(data), "parent"));
222         entry  = GTK_WIDGET(data);
223
224         dialog = gtk_file_chooser_dialog_new(_("File Selection Dialog"),
225                                 GTK_WINDOW(parent),
226                                 GTK_FILE_CHOOSER_ACTION_OPEN,
227                                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
228                                 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
229                                 NULL);
230         if (folder) {
231                 gtk_file_chooser_set_current_folder(
232                                 GTK_FILE_CHOOSER(dialog), folder);
233                 g_free(folder);
234         }
235         gtk_widget_show(dialog);
236
237         response = gtk_dialog_run (GTK_DIALOG(dialog));
238         if (response == GTK_RESPONSE_ACCEPT) {
239                 gchar   *filename;
240
241                 filename = gtk_file_chooser_get_filename(
242                                                 GTK_FILE_CHOOSER(dialog));
243                 folder = gtk_file_chooser_get_current_folder(
244                                                 GTK_FILE_CHOOSER(dialog));
245                 DEBUG_PRINT("%s\n", folder);
246                 gtk_entry_set_text(GTK_ENTRY(entry), filename);
247                 g_free(filename);
248         } else {
249                 DEBUG_PRINT("Another response was recieved.\n");
250         }
251         gtk_widget_destroy(dialog);
252 }
253
254 static void append_manager(GtkAction *action, other_t *data)
255 {
256         GtkWidget               *dialog;
257         GtkWidget               *hbox;
258         GtkWidget               *entry;
259         GtkWidget               *button;
260         gint                    response;
261
262         DEBUG_PRINT("append manager\n");
263
264         dialog = gtk_dialog_new_with_buttons(_("Manager Add"),
265                         GTK_WINDOW(data->dialog),
266                         GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
267                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
268                         GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
269                         NULL);
270
271         hbox = gtk_hbox_new(FALSE, 5);
272         gtk_container_add(
273                 GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
274
275         entry = gtk_entry_new();
276         gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
277         g_object_set_data(G_OBJECT(entry), "parent", (gpointer)dialog);
278
279         button = gtk_button_new_from_stock(GTK_STOCK_OPEN);
280         g_signal_connect(G_OBJECT(button), "clicked",
281                                 G_CALLBACK(cb_button), (gpointer)entry);
282         gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
283
284         gtk_widget_set_size_request(dialog, 600, -1);
285         gtk_widget_show_all(dialog);
286
287         response = gtk_dialog_run(GTK_DIALOG(dialog));
288         if (response == GTK_RESPONSE_APPLY) {
289                 DEBUG_PRINT("append path\n");
290                 const gchar     *input;
291                 char            *err_buff = NULL;
292                 gint            result;
293                 input = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
294                 result = add_manager((char *)input, &err_buff);
295                 if (result) {
296                         g_warning("%s", err_buff);
297                         free(err_buff);
298                 } else {
299                         add_list_manager(&(data->manager));
300                 }
301         }
302         gtk_widget_destroy(dialog);
303 }
304
305 /*-------+---------+---------+---------+---------+---------+---------+--------*/
306 static void set_delete_flag(gpointer data, generic_list_t *gen)
307 {
308         GtkTreeModel            *model;
309         GtkTreeIter             iter;
310         gint                    number;
311
312         model = gtk_tree_view_get_model(GTK_TREE_VIEW(gen->listview));
313         if (!model || !gtk_tree_model_get_iter(model, &iter, data)) {
314                 g_warning("ERROR: %s(%d)", __FILE__, __LINE__);
315                 return;
316         }
317         gtk_tree_model_get(model, &iter, LIST_NUMBER, &number, -1);
318
319         DEBUG_PRINT(" index[%d]\n", number);
320         gen->list[number].selected = 1;
321 }
322
323 static void delete_manager(GtkAction *action, other_t *data)
324 {
325         GtkWidget               *dialog;
326         GtkTreeSelection        *selection;
327         gint                    count;
328         gchar                   *message = NULL;
329         GList                   *list;
330         char                    *err_buff = NULL;
331         int                     result = 0;
332
333         DEBUG_PRINT("delete manager\n");
334         selection = gtk_tree_view_get_selection(
335                                 GTK_TREE_VIEW(data->manager.listview));
336         if (!selection || !(count =
337                     gtk_tree_selection_count_selected_rows(selection)))
338                 return;
339
340         DEBUG_PRINT("count[%d]\n", count);
341         message = count > 1 ?
342          g_strdup_printf(_("Delete the %d selected managers?"), count) :
343          g_strdup_printf(_("Delete the selected manager?"));
344         dialog = gtk_message_dialog_new(GTK_WINDOW(data->dialog),
345                 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
346                         GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
347                         "%s", message);
348
349         if (GTK_RESPONSE_YES == gtk_dialog_run(GTK_DIALOG(dialog))) {
350                 list = gtk_tree_selection_get_selected_rows(selection, NULL);
351                 g_list_foreach(list, (GFunc)set_delete_flag, &(data->manager));
352                 g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
353                 g_list_free(list);
354
355                 result = delete_manager_policy(data->manager.list,
356                                         data->manager.count, &err_buff);
357                 if (result) {
358                         g_warning("%s", err_buff);
359                         free(err_buff);
360                 } else {
361                         add_list_manager(&(data->manager));
362                 }
363         }
364         gtk_widget_destroy(dialog);
365         g_free(message);
366 }
367 /*-------+---------+---------+---------+---------+---------+---------+--------*/
368 void manager_main(transition_t *transition)
369 {
370         other_t         data;
371         GtkWidget               *dialog;
372         GtkWidget               *listview;
373         gchar                   *title;
374         gint                    response;
375
376         title = disp_window_title(CCS_SCREEN_MANAGER_LIST);
377         dialog = gtk_dialog_new_with_buttons(title,
378                         GTK_WINDOW(transition->window),
379                         GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
380                         GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
381                         NULL);
382         g_free(title);
383
384         create_dialog_menu(dialog, &data);
385         listview = create_list_manager();
386         create_manager_view(dialog, listview);
387
388         data.dialog = dialog;
389         data.manager.listview = listview;
390         data.manager.count = 0;
391         data.manager.list = NULL;
392         add_list_manager(&(data.manager));
393
394         gtk_action_set_sensitive(gtk_action_group_get_action(
395                                         data.actions, "Add"), TRUE);
396         gtk_action_set_sensitive(gtk_action_group_get_action(
397                                         data.actions, "Delete"), TRUE);
398         g_signal_connect(G_OBJECT(listview), "button-press-event",
399                                         G_CALLBACK(cb_select_list), &data);
400
401         gtk_widget_set_size_request(dialog, 640, 480);
402         gtk_widget_set_name(dialog, "GpetManagerDialog");       // .gpetrc
403         gtk_widget_show_all(dialog);
404
405         response = gtk_dialog_run(GTK_DIALOG(dialog));
406         if (response == GTK_RESPONSE_CLOSE) {
407                 DEBUG_PRINT("Close button was pressed.\n");
408         } else {
409                 DEBUG_PRINT("Another response was recieved.\n");
410         }
411         gtk_widget_destroy(dialog);
412
413         if (transition->acl_detached &&
414             transition->current_page == CCS_SCREEN_ACL_LIST)
415                 transition->current_page = CCS_SCREEN_DOMAIN_LIST;
416 }
417 /*-------+---------+---------+---------+---------+---------+---------+--------*/
418 static void get_disp_column(const char *data, gchar **head,
419                                 gchar **now_str, gchar **quota_str)
420 {
421         int             cnt;
422         gchar           name[16], date[16], time[16];
423         guint           now, quota;
424         gboolean        bNow = TRUE, bQuota = TRUE;
425
426
427         memset(name, 0, sizeof(name));
428         memset(date, 0, sizeof(date));
429         memset(time, 0, sizeof(time));
430         if ((cnt = sscanf(data, "Policy update: %u %s %s %s",
431          &now, name, date, time)) >= 1) {
432                 *head = "Policy update";
433         } else if ((cnt = sscanf(data,
434          "Policy violation in learning mode: %u %s %s %s",
435          &now, name, date, time)) >= 1) {
436                 *head = "Policy violation in learning mode";
437         } else if ((cnt = sscanf(data,
438          "Policy violation in permissive mode: %u %s %s %s",
439          &now, name, date, time)) >= 1) {
440                 *head = "Policy violation in permissive mode";
441         } else if ((cnt = sscanf(data,
442          "Policy violation in enforcing mode: %u %s %s %s",
443          &now, name, date, time)) >= 1) {
444                 *head = "Policy violation in enforcing mode";
445         } else if ((cnt = sscanf(data,
446          "Memory used by policy: %u (Quota: %u)",
447          &now, &quota)) >= 1) {
448                 *head = "Memory used by policy";
449         } else if ((cnt = sscanf(data,
450          "Memory used by audit log: %u (Quota: %u)",
451          &now, &quota)) >= 1) {
452                 *head = "Memory used by audit log";
453         } else if ((cnt = sscanf(data,
454          "Memory used by query message: %u (Quota: %u)",
455          &now, &quota)) >= 1) {
456                 *head = "Memory used by query message";
457         } else if ((cnt = sscanf(data,
458          "Total memory used: %u", &now)) == 1) {
459                 *head = "Total memory used";
460         } else {
461                 *head = (gchar *)data;
462                 bNow = FALSE;
463                 bQuota = FALSE;
464                 g_warning("Not found! (Statistics)\n");
465         }
466         if (cnt == 1)
467                 bQuota = FALSE;
468
469         *now_str = bNow ? g_strdup_printf("%u", now) : g_strdup("");
470         if (strlen(name))
471                 *quota_str = g_strdup_printf("%s %s %s", name, date, time);
472         else
473                 *quota_str = bQuota ? g_strdup_printf("%u", quota) : g_strdup("");
474 }
475
476 enum mem_column_pos {
477         LIST_HEAD,              //
478         LIST_NOW,               //
479         LIST_QUOTA,             //
480         N_COLUMNS_MEM_LIST
481 };
482
483 static void add_list_memory(generic_list_t *mem)
484 {
485         GtkListStore            *store;
486         GtkTreeIter             iter;
487         gint                    i;
488         gchar                   *head, *now, *quota;
489
490         get_memory(&(mem->list), &(mem->count));
491         store = GTK_LIST_STORE(gtk_tree_view_get_model(
492                                         GTK_TREE_VIEW(mem->listview)));
493
494         gtk_list_store_clear(store);
495         for(i = 0; i < mem->count; i++){
496                 gtk_list_store_append(store, &iter);
497                 get_disp_column(mem->list[i].operand,
498                                                 &head, &now, &quota);
499                 gtk_list_store_set(store, &iter,
500                                         LIST_HEAD, head,
501                                         LIST_NOW, now,
502                                         LIST_QUOTA, quota,
503                                         -1);
504                 g_free(now);
505                 g_free(quota);
506         }
507
508         view_cursor_set(mem->listview, NULL, NULL);
509         gtk_widget_grab_focus(mem->listview);
510 }
511
512 static void cb_cell_edited(GtkCellRendererText *cell,
513                 const gchar *path_string, const gchar *new_text,
514                 generic_list_t *mem)
515 {
516         GtkTreeModel    *model;
517         GtkTreePath     *path;
518         GtkTreeIter     iter;
519         gint            index;
520         gchar           *old_text, *cp, *start;
521
522         model = gtk_tree_view_get_model(GTK_TREE_VIEW(mem->listview));
523         path = gtk_tree_path_new_from_string(path_string);
524         gtk_tree_model_get_iter(model, &iter, path);
525         gtk_tree_model_get(model, &iter, LIST_QUOTA, &old_text, -1);
526
527         index = gtk_tree_path_get_indices(path)[0];
528 //(2.16)        if (g_strcmp0(old_text, new_text))
529         if (strcmp(old_text, new_text))
530                 mem->list[index].selected = 1;
531         g_free(old_text);
532
533         start = (gchar *)mem->list[index].operand;
534         cp = strchr(mem->list[index].operand, ':');
535         if (cp)
536                 *cp = '\0';
537         mem->list[index].operand = g_strdup_printf("%s:%s", start, new_text);
538         free(start);
539         DEBUG_PRINT(" Input mem:%2d[%s]\n", index, mem->list[index].operand);
540
541         gtk_list_store_set(GTK_LIST_STORE(model), &iter,
542                                         LIST_QUOTA, new_text, -1);
543
544         gtk_tree_path_free(path);
545 }
546
547 static GtkWidget *create_list_memory(generic_list_t *mem)
548 {
549         GtkWidget               *treeview;
550         GtkListStore            *liststore;
551         GtkCellRenderer *renderer;
552
553         liststore = gtk_list_store_new(N_COLUMNS_MEM_LIST,
554                 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
555         treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
556         g_object_unref(liststore);
557
558         renderer = gtk_cell_renderer_text_new();
559         gtk_tree_view_insert_column_with_attributes(
560                 GTK_TREE_VIEW(treeview), -1, _(" "),
561                 renderer, "text", LIST_HEAD, NULL);
562 //      gtk_cell_renderer_set_fixed_size(renderer, 250, -1);
563
564         renderer = gtk_cell_renderer_text_new();
565         g_object_set(renderer, "xalign", 1.0, "ypad", 0, NULL);
566         gtk_tree_view_insert_column_with_attributes(
567                 GTK_TREE_VIEW(treeview), -1, _("Now (bytes)"),
568                 renderer, "text", LIST_NOW, NULL);
569         gtk_cell_renderer_set_fixed_size(renderer, 100, -1);
570
571         renderer = gtk_cell_renderer_text_new();
572         g_object_set(renderer, "xalign", 1.0, "ypad", 0, NULL);
573         g_object_set(renderer, "editable", TRUE, NULL);
574         g_signal_connect(renderer, "edited",
575                                 G_CALLBACK(cb_cell_edited), mem);
576         gtk_tree_view_insert_column_with_attributes(
577                 GTK_TREE_VIEW(treeview), -1, _("Quota (bytes)"),
578                 renderer, "text", LIST_QUOTA, NULL);
579 //      gtk_cell_renderer_set_fixed_size(renderer, 170, -1);
580
581         // ヘッダ表示
582         gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), TRUE);
583
584         return treeview;
585 }
586
587 static void create_memory_view(GtkWidget *dialog, GtkWidget *listview)
588 {
589         GtkWidget       *scrolledwin;
590
591         scrolledwin = gtk_scrolled_window_new(NULL, NULL);
592         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
593                         GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
594         gtk_scrolled_window_set_shadow_type(
595                 GTK_SCROLLED_WINDOW(scrolledwin), GTK_SHADOW_IN);
596
597         gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
598                                         scrolledwin, TRUE, TRUE, 0);
599         gtk_container_add(GTK_CONTAINER(scrolledwin), listview);
600
601 //      gtk_tree_view_set_enable_search(GTK_TREE_VIEW(listview), FALSE);
602 }
603
604 static void edit_memory(GtkAction *action, other_t *data)
605 {
606         GtkTreeSelection        *selection;
607         GList                   *list;
608         GtkTreeViewColumn       *column;
609
610         DEBUG_PRINT("edit memory\n");
611
612         selection = gtk_tree_view_get_selection(
613                                 GTK_TREE_VIEW(data->memory.listview));
614         list = gtk_tree_selection_get_selected_rows(selection, NULL);
615         column = gtk_tree_view_get_column(
616                 GTK_TREE_VIEW(data->memory.listview), LIST_QUOTA);
617         gtk_tree_view_set_cursor_on_cell(
618                 GTK_TREE_VIEW(data->memory.listview),
619                 g_list_first(list)->data, column, NULL, TRUE);
620 }
621
622 void memory_main(transition_t *transition)
623 {
624         other_t         data;
625         GtkWidget               *dialog;
626         GtkWidget               *listview;
627         gchar                   *title;
628         gint                    response;
629
630         title = disp_window_title(CCS_SCREEN_STAT_LIST);
631         dialog = gtk_dialog_new_with_buttons(title,
632                         GTK_WINDOW(transition->window),
633                         GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
634                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
635                         GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
636                         NULL);
637         g_free(title);
638
639         data.dialog = dialog;
640         data.memory.count = 0;
641         data.memory.list = NULL;
642         create_dialog_menu(dialog, &data);
643         listview = create_list_memory(&(data.memory));
644         data.memory.listview = listview;
645         create_memory_view(dialog, listview);
646
647         add_list_memory(&(data.memory));
648
649         gtk_action_set_sensitive(gtk_action_group_get_action(
650                                         data.actions, "Edit"), TRUE);
651         g_signal_connect(G_OBJECT(listview), "button-press-event",
652                                         G_CALLBACK(cb_select_list), &data);
653
654         gtk_widget_set_size_request(dialog, 600, 300);
655         gtk_widget_set_name(dialog, "GpetStatisticsDialog");    // .gpetrc
656         gtk_widget_show_all(dialog);
657
658         response = gtk_dialog_run(GTK_DIALOG(dialog));
659         if (response == GTK_RESPONSE_APPLY) {
660                 char    *err_buff = NULL;
661                 DEBUG_PRINT("Apply button was pressed.\n");
662                 if (set_memory(data.memory.list,
663                                 data.memory.count, &err_buff)) {
664                         g_warning("%s", err_buff);
665                         free(err_buff);
666                 }
667         } else {
668                 DEBUG_PRINT("Another response was recieved.\n");
669         }
670         gtk_widget_destroy(dialog);
671
672         if (transition->acl_detached &&
673             transition->current_page == CCS_SCREEN_ACL_LIST)
674                 transition->current_page = CCS_SCREEN_DOMAIN_LIST;
675 }
676