/***** * * Copyright (C) 2004, 2005 Pablo Belin * All Rights Reserved * * This file is part of the gprelude program. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * *****/ #include #include #include #include #include #include #include #include #include #include "list.h" #include "gprelude-mem.h" #include "gprelude-gui.h" #include "gprelude-idmef.h" #include "db-interface.h" #include "gprelude-config.h" #include "idmef-tree.h" #include "idmef-value.h" #include "idmef-criteria.h" #include "idmef-criterion.h" #include "idmef-criteria-xml.h" #include "idmef-criteria-dialog.h" typedef enum { idmef_criteria_dialog_flags_init = 0, idmef_criteria_dialog_flags_changes = 1 } idmef_criteria_dialog_flags_t; struct idmef_criteria_dialog { GtkWidget *dialog; idmef_criteria_dialog_flags_t flags; GtkTreeStore *store; GtkWidget *view; GtkListStore *list_store; GtkWidget *list_view; GtkWidget *toolbar; gprelude_config_t *cfg; gprelude_idmef_criterion_t *criterion; }; static const char *get_idmef_relation_string ( idmef_relation_t r ) { const char *str; switch ( r ) { case relation_substring: str = "substr"; break; case relation_regexp: str = "=~"; break; case relation_greater: str = ">"; break; case relation_greater_or_equal: str = ">=" ; break; case relation_less: str = "<"; break; case relation_less_or_equal: str = "<="; break; case relation_equal: str = "=="; break; case relation_not_equal: str = "!="; break; case relation_is_null: str = "!"; break; case relation_is_not_null: str = ""; break; default: str = ""; } return str; } static idmef_relation_t get_idmef_relation_numeric ( const char *str ) { idmef_relation_t relation; if ( !str ) return relation_error; if ( strcmp ( str, "substr" ) == 0 ) relation = relation_substring; else if ( strcmp ( str, "=~" ) == 0 ) relation = relation_regexp; else if ( strcmp ( str, ">" ) == 0 ) relation = relation_greater; else if ( strcmp ( str, ">=" ) == 0 ) relation = relation_greater_or_equal; else if ( strcmp ( str, "<" ) == 0 ) relation = relation_less; else if ( strcmp ( str, "<=" ) == 0 ) relation = relation_less_or_equal; else if ( strcmp ( str, "==" ) == 0 ) relation = relation_equal; else if ( strcmp ( str, "!=" ) == 0 ) relation = relation_not_equal; else if ( strcmp ( str, "!" ) == 0 ) relation = relation_is_null; else if ( strcmp ( str, "" ) == 0 ) relation = relation_is_not_null; else relation = relation_error; return relation; } static const char *get_idmef_operator_string ( idmef_operator_t operator ) { const char *str; switch ( operator ) { case operator_and: str = "&&"; break; case operator_or: str = "||"; break; default: str = ""; break; } return str; } static idmef_operator_t get_idmef_operator_numeric ( const char *str ) { idmef_operator_t operator; if ( !str ) return operator_error; if ( strcmp ( str, "&&" ) == 0 ) operator = operator_and; else if ( strcmp ( str, "||" ) == 0 ) operator = operator_or; else operator = operator_error; return operator; } static void set_idmef_criteria_store_criterion ( GtkTreeStore *store, GtkTreeIter *iter, const char *operator, const char *object, idmef_relation_t relation, idmef_criterion_value_t *value ) { char *buff = NULL; if ( value ) buff = gprelude_idmef_criterion_value_to_string_fast ( value ); gtk_tree_store_set ( store, iter, IDMEF_CRITERIA_STORE_OPERATOR, operator, IDMEF_CRITERIA_STORE_OBJECT, object, IDMEF_CRITERIA_STORE_RELATION, get_idmef_relation_string ( relation ), IDMEF_CRITERIA_STORE_VALUE, buff ? buff : "", IDMEF_CRITERIA_STORE_VALUE_DATA, value, -1 ); gprelude_free ( buff ); } static void idmef_criteria_store ( GtkTreeStore *store, GtkTreeIter *parent, idmef_operator_t operator, idmef_criteria_t *criteria, int sub ) { GtkTreeIter iter; idmef_criteria_t *criteria_ptr = NULL; idmef_criterion_t *criterion; idmef_object_t *object; idmef_relation_t relation; idmef_criterion_value_t *criterion_value; const char *operator_string, *object_string; int first = sub; while ( (criteria_ptr = idmef_criteria_get_next ( criteria, criteria_ptr )) ) { operator_string = get_idmef_operator_string ( operator ); if ( !first ) gtk_tree_store_append ( store, &iter, parent ); criterion = idmef_criteria_get_criterion ( criteria_ptr ); if ( criterion ) { object = idmef_criterion_get_object ( criterion ); object_string = idmef_object_get_name ( object ); relation = idmef_criterion_get_relation ( criterion ); criterion_value = idmef_criterion_get_value ( criterion ); set_idmef_criteria_store_criterion ( store, first ? parent : &iter, operator_string, object_string, relation, criterion_value ); } else idmef_criteria_store ( store, first ? parent : &iter, operator, criteria_ptr, 1 ); operator = idmef_criteria_get_operator ( criteria_ptr ); first = 0; } } static void set_idmef_criteria_store ( GtkTreeStore *store, idmef_criteria_t *criteria ) { GtkTreeIter iter; gtk_tree_store_clear ( store ); gtk_tree_store_append ( store, &iter, NULL ); gtk_tree_store_set ( store, &iter, IDMEF_CRITERIA_STORE_OPERATOR, "", IDMEF_CRITERIA_STORE_OBJECT, "", IDMEF_CRITERIA_STORE_RELATION, "", IDMEF_CRITERIA_STORE_VALUE, "", IDMEF_CRITERIA_STORE_VALUE_DATA, NULL, -1 ); if ( criteria ) idmef_criteria_store ( store, &iter, operator_and, criteria, 0 ); } static void remove_idmef_criteria_store_iter ( GtkTreeStore *store, GtkTreeIter *iter ) { GtkTreeIter child; while ( gtk_tree_model_iter_nth_child ( GTK_TREE_MODEL(store), &child, iter, 0 ) ) remove_idmef_criteria_store_iter ( store, &child ); gtk_tree_store_remove ( store, iter ); } static int clear_idmef_criteria_store ( GtkTreeStore *store ) { GtkTreeIter parent, child; int ret = 0; if ( !gtk_tree_model_get_iter_first ( GTK_TREE_MODEL(store), &parent ) ) return 0; while ( gtk_tree_model_iter_nth_child ( GTK_TREE_MODEL(store), &child, &parent, 0 ) ) { remove_idmef_criteria_store_iter ( store, &child ); ret = 1; } return ret; } static GtkTreeStore *create_idmef_criteria_store ( void ) { GtkTreeStore *store; store = gtk_tree_store_new ( IDMEF_CRITERIA_STORE_NB, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER ); return store; } static int get_idmef_criteria_view_iter ( GtkWidget *view, GtkTreeIter *iter ) { GtkTreeSelection *selection; GtkTreeModel *model; selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(view) ); model = gtk_tree_view_get_model ( GTK_TREE_VIEW(view) ); if ( gtk_tree_selection_get_selected ( selection, &model, iter ) ) return 0; if ( gtk_tree_model_get_iter_first ( model, iter ) ) return 1; return -1; } static void expand_idmef_criteria_view ( idmef_criteria_dialog_t *dlg, GtkTreeIter *iter ) { GtkTreeModel *model; GtkTreePath *path; model = gtk_tree_view_get_model ( GTK_TREE_VIEW(dlg->view) ); if ( !model ) return; path = gtk_tree_model_get_path ( model, iter ); if ( path ) { gtk_tree_view_expand_row ( GTK_TREE_VIEW(dlg->view), path, FALSE ); gtk_tree_path_free ( path ); } } static GtkWidget *create_idmef_criteria_view () { GtkWidget *view; GtkTreeSelection *selection; GtkTreeViewColumn *column; GtkCellRenderer *renderer; view = gtk_tree_view_new (); selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(view) ); gtk_tree_selection_set_mode ( selection, GTK_SELECTION_SINGLE ); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ( "Operator", renderer, "text", IDMEF_CRITERIA_STORE_OPERATOR, NULL ); gtk_tree_view_append_column ( GTK_TREE_VIEW(view), column ); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ( "Object", renderer, "text", IDMEF_CRITERIA_STORE_OBJECT, NULL ); gtk_tree_view_append_column ( GTK_TREE_VIEW(view), column ); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ( "Relation", renderer, "text", IDMEF_CRITERIA_STORE_RELATION, NULL ); gtk_tree_view_append_column ( GTK_TREE_VIEW(view), column ); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ( "Value", renderer, "text", IDMEF_CRITERIA_STORE_VALUE, NULL ); gtk_tree_view_append_column ( GTK_TREE_VIEW(view), column ); return view; } static int get_idmef_criteria_store_criterion ( GtkTreeStore *store, GtkTreeIter *iter, idmef_criteria_t *criteria ) { idmef_operator_t operator = operator_and; idmef_criterion_t *criterion; idmef_object_t *object; idmef_relation_t relation = relation_error; idmef_criterion_value_t *value = NULL; char *operator_string = NULL, *object_string = NULL, *relation_string = NULL; int ret = -1; gtk_tree_model_get ( GTK_TREE_MODEL(store), iter, IDMEF_CRITERIA_STORE_OPERATOR, &operator_string, IDMEF_CRITERIA_STORE_OBJECT, &object_string, IDMEF_CRITERIA_STORE_RELATION, &relation_string, IDMEF_CRITERIA_STORE_VALUE_DATA, &value, -1 ); object = idmef_object_new_fast ( object_string ); gprelude_free ( object_string ); if ( object ) { operator = get_idmef_operator_numeric ( operator_string ); relation = get_idmef_relation_numeric ( relation_string ); criterion = idmef_criterion_new ( object, relation, value ); if ( !criterion ) idmef_object_destroy ( object ); else { idmef_criteria_add_criterion ( criteria, criterion, operator); ret = operator; } } else idmef_object_destroy ( object ); gprelude_free ( operator_string ); gprelude_free ( relation_string ); return ret; } static int get_idmef_criteria_store_criteria ( GtkTreeStore *store, GtkTreeIter *iter, idmef_criteria_t *criteria ) { GtkTreeIter child; idmef_criteria_t *sub; int i = 0, ret, operator; if ( gtk_tree_model_iter_nth_child ( GTK_TREE_MODEL(store), &child, iter, i++ ) ) { sub = idmef_criteria_new (); if ( !sub ) return -1; operator = get_idmef_criteria_store_criterion ( store, iter, sub ); if ( operator < 0 ) { idmef_criteria_destroy ( sub ); return -1; } do { ret = get_idmef_criteria_store_criteria ( store, &child, sub ); if ( ret < 0 ) { idmef_criteria_destroy ( sub ); return -1; } } while ( gtk_tree_model_iter_nth_child ( GTK_TREE_MODEL(store), &child, iter, i++ ) ); idmef_criteria_add_criteria ( criteria, sub, operator ); } else { ret = get_idmef_criteria_store_criterion ( store, iter, criteria ); if ( ret < 0 ) return -1; } return 0; } static idmef_criteria_t *get_idmef_criteria_store ( GtkTreeStore *store ) { GtkTreeIter root, child; idmef_criteria_t *criteria; int i = 0, ret; if ( !gtk_tree_model_get_iter_first ( GTK_TREE_MODEL(store), &root ) ) return NULL; if ( !gtk_tree_model_iter_nth_child ( GTK_TREE_MODEL(store), &child, &root, i++ ) ) return NULL; criteria = idmef_criteria_new (); if ( !criteria ) return NULL; do { ret = get_idmef_criteria_store_criteria ( store, &child, criteria ); if ( ret < 0 ) { idmef_criteria_destroy ( criteria ); criteria = NULL; break; } } while ( gtk_tree_model_iter_nth_child ( GTK_TREE_MODEL(store), &child, &root, i++ ) ); return criteria; } /* static void cb_idmef_criteria_ctl_apply ( GtkWidget *button, idmef_criteria_dialog_t *dlg ) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; idmef_criteria_t *criteria;//, *old_criteria = NULL; if ( !(dlg->flags & idmef_criteria_dialog_flags_changes) ) return; selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(dlg->list_view) ); model = gtk_tree_view_get_model ( GTK_TREE_VIEW(dlg->list_view) ); if ( !gtk_tree_selection_get_selected ( selection, &model, &iter ) ) return; criteria = get_idmef_criteria_store ( dlg ); if ( !criteria ) return; gtk_tree_model_get ( model, &iter, IDMEF_CRITERIA_LIST_STORE_DATA, &old_criteria, -1 ); if ( old_criteria ) idmef_criteria_destroy ( old_criteria ); gtk_list_store_set ( dlg->list_store, &iter, IDMEF_CRITERIA_LIST_STORE_DATA, criteria, -1 ); dlg->flags ^= idmef_criteria_dialog_flags_changes; } */ static void cb_idmef_criteria_ctl_add ( GtkWidget *button, idmef_criteria_dialog_t *dlg ) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeStore *store = NULL; GtkTreeIter list_iter, parent, iter; int response, ret, changes = 0; char *object; idmef_relation_t relation; idmef_criterion_value_t *value; const char *operator; response = run_idmef_criterion ( dlg->criterion ); switch ( response ) { case GTK_RESPONSE_OK: selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(dlg->list_view) ); model = gtk_tree_view_get_model ( GTK_TREE_VIEW(dlg->list_view) ); if ( gtk_tree_selection_get_selected ( selection, &model, &list_iter ) ) { gtk_tree_model_get ( model, &list_iter, IDMEF_CRITERIA_LIST_STORE_STORE, &store, IDMEF_CRITERIA_LIST_STORE_CHANGES, &changes, -1 ); object = get_idmef_criterion_object ( dlg->criterion ); if ( !object ) { cb_idmef_criteria_ctl_add ( NULL, dlg ); break; } ret = get_idmef_criteria_view_iter ( dlg->view, &parent ); if ( ret != -1 ) { value = get_idmef_criterion_value ( dlg->criterion ); operator = get_idmef_criterion_operator ( dlg->criterion ); relation = get_idmef_criterion_relation ( dlg->criterion ); gtk_tree_store_append ( store, &iter, &parent ); set_idmef_criteria_store_criterion ( store, &iter, operator, object, relation, value ); expand_idmef_criteria_view ( dlg, &parent ); if ( !changes ) { gtk_list_store_set ( dlg->list_store, &list_iter, IDMEF_CRITERIA_LIST_STORE_CHANGES, 1, -1 ); } } free ( object ); } default: hide_idmef_criterion ( dlg->criterion ); break; } } static void cb_idmef_criteria_dialog_ctl_remove ( GtkWidget *button, idmef_criteria_dialog_t *dlg ) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeStore *store = NULL; GtkTreeIter list_iter, iter, parent; int ret, changes = 0; selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(dlg->list_view) ); model = gtk_tree_view_get_model ( GTK_TREE_VIEW(dlg->list_view) ); if ( gtk_tree_selection_get_selected ( selection, &model, &list_iter ) ) { gtk_tree_model_get ( model, &list_iter, IDMEF_CRITERIA_LIST_STORE_STORE, &store, IDMEF_CRITERIA_LIST_STORE_CHANGES, &changes, -1 ); ret = get_idmef_criteria_view_iter ( dlg->view, &iter ); if ( ret != 0 ) return; if ( !changes ) { gtk_list_store_set ( dlg->list_store, &list_iter, IDMEF_CRITERIA_LIST_STORE_CHANGES, 1, -1 ); } if ( !gtk_tree_model_iter_parent ( GTK_TREE_MODEL(store), &parent, &iter ) ) { clear_idmef_criteria_store ( store ); return; } remove_idmef_criteria_store_iter ( store, &iter ); } } static void cb_idmef_criteria_dialog_ctl_clear ( GtkWidget *button, idmef_criteria_dialog_t *dlg ) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeStore *store = NULL; GtkTreeIter list_iter; int changes = 0; selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(dlg->list_view) ); model = gtk_tree_view_get_model ( GTK_TREE_VIEW(dlg->list_view) ); if ( gtk_tree_selection_get_selected ( selection, &model, &list_iter ) ) { gtk_tree_model_get ( model, &list_iter, IDMEF_CRITERIA_LIST_STORE_STORE, &store, IDMEF_CRITERIA_LIST_STORE_CHANGES, &changes, -1 ); if ( clear_idmef_criteria_store ( store ) && !changes ) { gtk_list_store_set ( dlg->list_store, &list_iter, IDMEF_CRITERIA_LIST_STORE_CHANGES, 1, -1 ); } } } /* static void cb_idmef_criteria_dialog_ctl_up ( GtkWidget *button, idmef_criteria_dialog_t *dlg ) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeStore *store = NULL; GtkTreeIter list_iter, iter1, iter2; GtkTreePath *path; int ret; selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(dlg->list_view) ); model = gtk_tree_view_get_model ( GTK_TREE_VIEW(dlg->list_view) ); if ( gtk_tree_selection_get_selected ( selection, &model, &list_iter ) ) { gtk_tree_model_get ( model, &list_iter, IDMEF_CRITERIA_LIST_STORE_STORE, &store, -1 ); ret = get_idmef_criteria_view_iter ( dlg->view, &iter1 ); if ( ret != 0 ) return; path = gtk_tree_model_get_path ( GTK_TREE_MODEL(store), &iter1 ); if ( path ) { if ( gtk_tree_path_prev ( path ) && gtk_tree_model_get_iter ( GTK_TREE_MODEL(store), &iter2, path ) ) { gtk_tree_store_swap ( store, &iter2, &iter1 ); } gtk_tree_path_free ( path ); } } } static void cb_idmef_criteria_dialog_ctl_down ( GtkWidget *button, idmef_criteria_dialog_t *dlg ) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeStore *store = NULL; GtkTreeIter list_iter, iter1, iter2; int ret; selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(dlg->list_view) ); model = gtk_tree_view_get_model ( GTK_TREE_VIEW(dlg->list_view) ); if ( gtk_tree_selection_get_selected ( selection, &model, &list_iter ) ) { gtk_tree_model_get ( model, &list_iter, IDMEF_CRITERIA_LIST_STORE_STORE, &store, -1 ); ret = get_idmef_criteria_view_iter ( dlg->view, &iter1 ); if ( ret != 0 ) return; iter2 = iter1; if ( gtk_tree_model_iter_next ( GTK_TREE_MODEL(store), &iter1 ) ) { gtk_tree_store_swap ( store, &iter1, &iter2 ); } } } */ static GtkWidget *create_idmef_criteria_ctl ( idmef_criteria_dialog_t *dlg ) { GtkWidget *toolbar; toolbar = gtk_toolbar_new (); gtk_toolbar_set_orientation ( GTK_TOOLBAR(toolbar), GTK_ORIENTATION_HORIZONTAL ); gtk_toolbar_set_style ( GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS ); gtk_toolbar_set_icon_size ( GTK_TOOLBAR(toolbar), GTK_ICON_SIZE_SMALL_TOOLBAR ); gtk_toolbar_set_tooltips ( GTK_TOOLBAR(toolbar), TRUE ); /* gtk_toolbar_insert_stock ( GTK_TOOLBAR(toolbar), GTK_STOCK_APPLY, "Apply", NULL, G_CALLBACK(cb_idmef_criteria_ctl_apply), dlg, -1 ); */ gtk_toolbar_insert_stock ( GTK_TOOLBAR(toolbar), GTK_STOCK_ADD, "Add", NULL, G_CALLBACK(cb_idmef_criteria_ctl_add), dlg, -1 ); gtk_toolbar_insert_stock ( GTK_TOOLBAR(toolbar), GTK_STOCK_REMOVE, "Remove", NULL, G_CALLBACK(cb_idmef_criteria_dialog_ctl_remove), dlg, -1 ); gtk_toolbar_insert_stock ( GTK_TOOLBAR(toolbar), GTK_STOCK_CLEAR, "Clear", NULL, G_CALLBACK(cb_idmef_criteria_dialog_ctl_clear), dlg, -1 ); /* gtk_toolbar_append_space ( GTK_TOOLBAR(toolbar) ); gtk_toolbar_insert_stock ( GTK_TOOLBAR(toolbar), GTK_STOCK_GO_UP, "Up", NULL, G_CALLBACK(cb_idmef_criteria_dialog_ctl_up), dlg, -1 ); gtk_toolbar_insert_stock ( GTK_TOOLBAR(toolbar), GTK_STOCK_GO_DOWN, "Down", NULL, G_CALLBACK(cb_idmef_criteria_dialog_ctl_down), dlg, -1 ); */ return toolbar; } static GtkWidget *create_idmef_criteria_ornament ( idmef_criteria_dialog_t *dlg ) { GtkWidget *box, *frame, *scrolled; GtkTreeIter iter; box = gtk_vbox_new ( FALSE, 5 ); scrolled = gtk_scrolled_window_new ( NULL, NULL ); gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC ); gtk_container_add ( GTK_CONTAINER(scrolled), dlg->view ); gtk_widget_show ( dlg->view ); frame = gtk_frame_new ( NULL ); gtk_container_add ( GTK_CONTAINER(frame), scrolled ); gtk_widget_show ( scrolled ); gtk_box_pack_start ( GTK_BOX(box), frame, TRUE, TRUE, 0 ); gtk_widget_show ( frame ); dlg->toolbar = create_idmef_criteria_ctl ( dlg ); gtk_box_pack_start ( GTK_BOX(box), dlg->toolbar, FALSE, FALSE, 5 ); gtk_widget_show_all ( dlg->toolbar ); if ( !gtk_tree_model_get_iter_first ( GTK_TREE_MODEL(dlg->list_store), &iter ) ) gtk_widget_set_sensitive ( dlg->toolbar, FALSE ); else dlg->flags |= idmef_criteria_dialog_flags_changes; return box; } static GtkListStore *create_idmef_criteria_list_store ( list_t *list ) { list_t *tmp; GtkListStore *store; GtkTreeStore *store_tmp; GtkTreeIter iter; gprelude_idmef_criteria_t *gcriteria; idmef_criteria_t *criteria; store = gtk_list_store_new ( IDMEF_CRITERIA_LIST_STORE_NB, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_POINTER, G_TYPE_INT ); list_foreach ( list, tmp ) { gcriteria = list_get_data ( tmp ); if ( !gcriteria ) continue; if ( !gcriteria->name || !gcriteria->string ) continue; criteria = idmef_criteria_new_string ( gcriteria->string ); if ( !criteria ) continue; gtk_list_store_append ( store, &iter ); store_tmp = create_idmef_criteria_store (); set_idmef_criteria_store ( store_tmp, criteria ); gtk_list_store_set ( store, &iter, IDMEF_CRITERIA_LIST_STORE_NAME, gcriteria->name, IDMEF_CRITERIA_LIST_STORE_DATA, criteria, IDMEF_CRITERIA_LIST_STORE_STORE, store_tmp, IDMEF_CRITERIA_LIST_STORE_CHANGES, 0, IDMEF_CRITERIA_LIST_STORE_SUBSCRIBED, 0, -1 ); } return store; } static int idmef_criteria_list_name_exists ( idmef_criteria_dialog_t *dlg, const char *name, GtkTreeIter *viter ) { GtkTreeIter iter; char *buff = NULL; if ( !name || !gtk_tree_model_get_iter_first ( GTK_TREE_MODEL(dlg->list_store), &iter ) ) return 0; do { gtk_tree_model_get ( GTK_TREE_MODEL(dlg->list_store), &iter, IDMEF_CRITERIA_LIST_STORE_NAME, &buff, -1 ); if ( buff ) { if ( strcmp ( name, buff ) == 0 ) { if ( viter ) *viter = iter; free ( buff ); return 1; } free ( buff ); buff = NULL; } } while ( gtk_tree_model_iter_next ( GTK_TREE_MODEL(dlg->list_store), &iter ) ); return 0; } static void cb_idmef_criteria_list_edited ( GtkCellRendererText *renderer, char *str1, char *str2, idmef_criteria_dialog_t *dlg ) { GtkTreeModel *model; GtkTreeSelection *selection; GtkTreeIter iter; int subscribed = 0; char *name; selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(dlg->list_view) ); model = GTK_TREE_MODEL(dlg->list_store); if ( gtk_tree_selection_get_selected ( selection, &model, &iter ) ) { gtk_tree_model_get ( model, &iter, IDMEF_CRITERIA_LIST_STORE_SUBSCRIBED, &subscribed, -1 ); if ( subscribed ) return; gtk_tree_model_get ( model, &iter, IDMEF_CRITERIA_LIST_STORE_NAME, &name, -1 ); if ( (strlen ( str2 ) == 0) || (strcmp ( name, str2 ) == 0) ) { free ( name ); return; } free ( name ); if ( idmef_criteria_list_name_exists ( dlg, str2, NULL ) ) return; name = gprelude_strdup ( str2 ); if ( name ) { gtk_list_store_set ( dlg->list_store, &iter, IDMEF_CRITERIA_LIST_STORE_NAME, name, -1 ); free ( name ); dlg->flags |= idmef_criteria_dialog_flags_changes; } } } static void cb_idmef_criteria_list_changed ( GtkTreeSelection *selection, idmef_criteria_dialog_t *dlg ) { GtkTreeModel *model, *model_tmp = NULL; GtkTreeIter iter; idmef_criteria_t *criteria = NULL; int subscribed = 0; model = GTK_TREE_MODEL(dlg->store); if ( gtk_tree_selection_get_selected ( selection, &model, &iter ) ) { gtk_tree_model_get ( model, &iter, IDMEF_CRITERIA_LIST_STORE_DATA, &criteria, IDMEF_CRITERIA_LIST_STORE_SUBSCRIBED, &subscribed, IDMEF_CRITERIA_LIST_STORE_STORE, &model_tmp, -1 ); gtk_tree_view_set_model ( GTK_TREE_VIEW(dlg->view), GTK_TREE_MODEL(model_tmp) ); gtk_tree_view_expand_all ( GTK_TREE_VIEW(dlg->view) ); if ( subscribed ) { if ( GTK_WIDGET_SENSITIVE(dlg->toolbar) ) gtk_widget_set_sensitive ( dlg->toolbar, FALSE ); } else { if ( !GTK_WIDGET_SENSITIVE(dlg->toolbar) ) gtk_widget_set_sensitive ( dlg->toolbar, TRUE ); } } } static void cb_idmef_criteria_list_show ( GtkWidget *view, idmef_criteria_dialog_t *dlg ) { GtkTreeSelection *selection; selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(dlg->list_view) ); cb_idmef_criteria_list_changed ( selection, dlg ); } static GtkWidget *create_idmef_criteria_list_view ( idmef_criteria_dialog_t *dlg ) { GtkWidget *view; GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeSelection *selection; view = gtk_tree_view_new_with_model ( GTK_TREE_MODEL(dlg->list_store) ); renderer = gtk_cell_renderer_text_new (); g_object_set ( G_OBJECT(renderer), "editable", TRUE, "foreground", "gray", NULL ); g_signal_connect ( G_OBJECT(renderer), "edited", G_CALLBACK(cb_idmef_criteria_list_edited), dlg ); column = gtk_tree_view_column_new_with_attributes ( "Criteria Name :", renderer, "text", IDMEF_CRITERIA_LIST_STORE_NAME, "foreground-set", IDMEF_CRITERIA_LIST_STORE_SUBSCRIBED, NULL ); gtk_tree_view_append_column ( GTK_TREE_VIEW(view), column ); selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(view) ); gtk_tree_selection_set_mode ( selection, GTK_SELECTION_SINGLE ); g_signal_connect ( G_OBJECT(selection), "changed", G_CALLBACK(cb_idmef_criteria_list_changed), dlg ); return view; } static void cb_idmef_criteria_list_ctl_add ( GtkWidget *widget, idmef_criteria_dialog_t *dlg ) { GtkTreeStore *store; GtkTreeIter iter; GtkTreeSelection *selection; if ( idmef_criteria_list_name_exists ( dlg, "(unnamed)", NULL ) ) return; gtk_list_store_append ( dlg->list_store, &iter ); store = create_idmef_criteria_store (); set_idmef_criteria_store ( store, NULL ); gtk_list_store_set ( dlg->list_store, &iter, IDMEF_CRITERIA_LIST_STORE_NAME, "(unnamed)", IDMEF_CRITERIA_LIST_STORE_DATA, NULL, IDMEF_CRITERIA_LIST_STORE_STORE, store, IDMEF_CRITERIA_LIST_STORE_CHANGES, 1, IDMEF_CRITERIA_LIST_STORE_SUBSCRIBED, 0, -1 ); selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(dlg->list_view) ); gtk_tree_selection_select_iter ( selection, &iter ); if ( !GTK_WIDGET_SENSITIVE(dlg->toolbar) ) gtk_widget_set_sensitive ( dlg->toolbar, TRUE ); dlg->flags |= idmef_criteria_dialog_flags_changes; } static void cb_idmef_criteria_list_ctl_remove ( GtkWidget *widget, idmef_criteria_dialog_t *dlg ) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreePath *path; GtkTreeStore *store = NULL; GtkTreeIter iter, tmp; int subscribed = 0; idmef_criteria_t *criteria = NULL; selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(dlg->list_view) ); model = GTK_TREE_MODEL(dlg->list_store); if ( gtk_tree_selection_get_selected ( selection, &model, &iter ) ) { gtk_tree_model_get ( GTK_TREE_MODEL(dlg->list_store), &iter, IDMEF_CRITERIA_LIST_STORE_SUBSCRIBED, &subscribed, -1 ); if ( subscribed ) return; gtk_tree_model_get ( GTK_TREE_MODEL(dlg->list_store), &iter, IDMEF_CRITERIA_LIST_STORE_DATA, &criteria, IDMEF_CRITERIA_LIST_STORE_STORE, &store, -1 ); if ( criteria ) idmef_criteria_destroy ( criteria ); clear_idmef_criteria_store ( store ); path = gtk_tree_model_get_path ( GTK_TREE_MODEL(dlg->list_store), &iter ); tmp = iter; if ( gtk_tree_path_prev ( path ) ) gtk_tree_selection_select_path ( selection, path ); else if ( gtk_tree_model_iter_next ( model, &tmp ) ) gtk_tree_selection_select_iter ( selection, &tmp ); else gtk_widget_set_sensitive ( dlg->toolbar, FALSE ); gtk_tree_path_free ( path ); gtk_list_store_remove ( dlg->list_store, &iter ); dlg->flags |= idmef_criteria_dialog_flags_changes; } } static GtkWidget *create_idmef_criteria_list_ctl ( idmef_criteria_dialog_t *dlg ) { GtkWidget *box, *button; box = gtk_hbox_new ( TRUE, 0 ); button = gtk_button_new_from_stock ( GTK_STOCK_ADD ); g_signal_connect ( G_OBJECT(button), "clicked", G_CALLBACK(cb_idmef_criteria_list_ctl_add), dlg ); gtk_box_pack_start ( GTK_BOX(box), button, TRUE, TRUE, 0 ); button = gtk_button_new_from_stock ( GTK_STOCK_REMOVE ); g_signal_connect ( G_OBJECT(button), "clicked", G_CALLBACK(cb_idmef_criteria_list_ctl_remove), dlg ); gtk_box_pack_start ( GTK_BOX(box), button, TRUE, TRUE, 0 ); return box; } static GtkWidget *create_idmef_criteria_list_ornament ( idmef_criteria_dialog_t *dlg ) { GtkWidget *box, *scrolled, *frame, *ctl; box = gtk_vbox_new ( FALSE, 0 ); scrolled = gtk_scrolled_window_new ( NULL, NULL ); gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); gtk_container_add ( GTK_CONTAINER(scrolled), dlg->list_view ); gtk_widget_show ( dlg->list_view ); frame = gtk_frame_new ( NULL ); gtk_container_add ( GTK_CONTAINER(frame), scrolled ); gtk_widget_show ( scrolled ); gtk_box_pack_start ( GTK_BOX(box), frame, TRUE, TRUE, 0 ); gtk_widget_show ( frame ); ctl = create_idmef_criteria_list_ctl ( dlg ); gtk_box_pack_start ( GTK_BOX(box), ctl, FALSE, FALSE, 0 ); gtk_widget_show_all ( ctl ); return box; } static GtkWidget *create_idmef_criteria_list ( idmef_criteria_dialog_t *dlg, list_t *list ) { dlg->list_store = create_idmef_criteria_list_store ( list ); dlg->list_view = create_idmef_criteria_list_view ( dlg ); return create_idmef_criteria_list_ornament ( dlg ); } idmef_criteria_dialog_t *create_idmef_criteria_dialog ( GtkWidget *parent, gprelude_config_t *cfg ) { GtkWidget *table, *widget; idmef_criteria_dialog_t *dlg; dlg = malloc ( sizeof(idmef_criteria_dialog_t) ); if ( !dlg ) { log ( LOG_ERR, "memory exhausted.\n" ); return NULL; } dlg->flags = idmef_criteria_dialog_flags_init; dlg->cfg = cfg; dlg->dialog = gtk_dialog_new_with_buttons ( IDMEF_CRITERIA_DIALOG_TITLE, GTK_WINDOW(parent), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_SAVE, 1, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL ); gprelude_gui_window_set_size ( dlg->dialog, IDMEF_CRITERIA_DIALOG_WIDTH_RATE, IDMEF_CRITERIA_DIALOG_HEIGHT_RATE ); dlg->criterion = create_idmef_criterion ( dlg->dialog ); if ( !dlg->criterion ) { free ( dlg ); return NULL; } dlg->store = create_idmef_criteria_store (); dlg->view = create_idmef_criteria_view ( dlg->store ); table = gtk_table_new ( 3, 4, FALSE ); gtk_table_set_col_spacings ( GTK_TABLE(table), 15 ); gtk_table_set_row_spacings ( GTK_TABLE(table), 10 ); widget = create_idmef_criteria_list ( dlg, gprelude_config_get_idmef_criteria_list ( cfg ) ); gtk_table_attach ( GTK_TABLE(table), widget, 1, 2, 1, 2, 0, GTK_EXPAND|GTK_FILL, 0, 0 ); gtk_widget_show ( widget ); widget = create_idmef_criteria_ornament ( dlg ); gtk_table_attach_defaults ( GTK_TABLE(table), widget, 2, 3, 1, 2 ); gtk_widget_show ( widget ); gtk_container_add ( GTK_CONTAINER(GTK_DIALOG(dlg->dialog)->vbox), table ); gtk_widget_show ( table ); g_signal_connect ( G_OBJECT(dlg->dialog), "show", G_CALLBACK(cb_idmef_criteria_list_show), dlg ); return dlg; } int destroy_idmef_criteria_dialog ( idmef_criteria_dialog_t *dlg ) { if ( !dlg ) return -1; free ( dlg->criterion ); free ( dlg ); return 0; } /* static int get_idmef_criteria_dialog_list_valid ( GtkListStore *list_store, GtkTreeIter *list_iter ) { GtkTreeStore *store = NULL; GtkTreeIter iter; gtk_tree_model_get ( GTK_TREE_MODEL(list_store), &iter, IDMEF_CRITERIA_LIST_STORE_STORE, &store, -1 ); if ( !gtk_tree_model_get_iter_firt ( GTK_TREE_MODEL(store), &iter ) ) return 0; return gtk_tree_model_iter_has_children ( GTK_TREE_MODEL(store), &iter ); } */ GList *get_idmef_criteria_dialog_list ( idmef_criteria_dialog_t *dlg ) { GtkTreeIter iter; GList *list = NULL; char *name = NULL; idmef_criteria_t *criteria = NULL; if ( gtk_tree_model_get_iter_first ( GTK_TREE_MODEL(dlg->list_store), &iter ) ) { list = g_list_append ( NULL, "" ); do { gtk_tree_model_get ( GTK_TREE_MODEL(dlg->list_store), &iter, IDMEF_CRITERIA_LIST_STORE_NAME, &name, IDMEF_CRITERIA_LIST_STORE_DATA, &criteria, -1 ); if ( name ) { list = g_list_append ( list, name ); criteria = NULL; name = NULL; } } while ( gtk_tree_model_iter_next ( GTK_TREE_MODEL(dlg->list_store), &iter ) ); } return list; } idmef_criteria_t *get_idmef_criteria_dialog_by_name ( idmef_criteria_dialog_t *dlg, const char *name, int subscribe ) { GtkTreeStore *store = NULL; GtkTreeIter iter; int i = 0, changes = 0; idmef_criteria_t *criteria = NULL; if ( !idmef_criteria_list_name_exists ( dlg, name, &iter ) ) return NULL; gtk_tree_model_get ( GTK_TREE_MODEL(dlg->list_store), &iter, IDMEF_CRITERIA_LIST_STORE_DATA, &criteria, IDMEF_CRITERIA_LIST_STORE_STORE, &store, IDMEF_CRITERIA_LIST_STORE_CHANGES, &changes, IDMEF_CRITERIA_LIST_STORE_SUBSCRIBED, &i, -1 ); if ( !criteria || changes ) { criteria = get_idmef_criteria_store ( store ); if ( !criteria ) return NULL; if ( subscribe ) { gtk_list_store_set ( dlg->list_store, &iter, IDMEF_CRITERIA_LIST_STORE_SUBSCRIBED, ++i, IDMEF_CRITERIA_LIST_STORE_DATA, criteria, -1 ); } else { gtk_list_store_set ( dlg->list_store, &iter, IDMEF_CRITERIA_LIST_STORE_DATA, criteria, -1 ); } } return criteria; } int unsubscribe_idmef_criteria ( idmef_criteria_dialog_t *dlg, const char *name ) { GtkTreeIter iter; int subscribe = 0; if ( !idmef_criteria_list_name_exists ( dlg, name, &iter ) ) return -1; gtk_tree_model_get ( GTK_TREE_MODEL(dlg->list_store), &iter, IDMEF_CRITERIA_LIST_STORE_SUBSCRIBED, &subscribe, -1 ); if ( subscribe == 0 ) return 1; gtk_list_store_set ( dlg->list_store, &iter, IDMEF_CRITERIA_LIST_STORE_SUBSCRIBED, --subscribe, -1 ); return 0; } static void idmef_criteria_dialog_save ( idmef_criteria_dialog_t *dlg ) { char *cwd, *filename; cwd = gprelude_config_get_cwd ( dlg->cfg ); if ( !cwd ) return; filename = gprelude_sprintf ( "%s/%s", cwd, GPRELUDE_IDMEF_CRITERIA_FILENAME ); if ( !filename ) return; gprelude_idmef_criteria_xml ( dlg->list_store, filename ); free ( filename ); } int run_idmef_criteria_dialog ( idmef_criteria_dialog_t *dlg ) { int response, ret = 0; response = gtk_dialog_run ( GTK_DIALOG(dlg->dialog) ); if ( response == 1 ) { idmef_criteria_dialog_save ( dlg ); return run_idmef_criteria_dialog ( dlg ); } else { if ( dlg->flags & idmef_criteria_dialog_flags_changes ) { dlg->flags ^= idmef_criteria_dialog_flags_changes; ret = 1; } gtk_widget_hide ( dlg->dialog ); } return ret; }