diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gui/panels/history.c | 178 | 
1 files changed, 135 insertions, 43 deletions
diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c index 1e86880..7d0cdd5 100644 --- a/src/gui/panels/history.c +++ b/src/gui/panels/history.c @@ -2,7 +2,7 @@  /* Chrysalide - Outil d'analyse de fichiers binaires   * history.c - panneau de la liste des évolutions d'utilisateur(s)   * - * Copyright (C) 2008-2013 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -94,8 +94,8 @@ static void on_history_changed(GDbCollection *, DBAction, GDbItem *, GHistoryPan  /* Compare deux lignes entre elles pour le tri des évolutions. */  static gint sort_history_lines(GtkTreeModel *, GtkTreeIter *, GtkTreeIter *, gpointer); -/* Réagit à une validation d'une ligne affichée. */ -static void on_history_row_activated(GtkTreeView *, GtkTreePath *, GtkTreeViewColumn *, GHistoryPanel *); +/* Réagit au changement de sélection des éléments d'historique. */ +static void on_history_selection_change(GtkTreeSelection *, GHistoryPanel *);  /* Annule l'élément d'évolution courant. */  static void do_history_undo(GtkButton *, GHistoryPanel *); @@ -163,6 +163,7 @@ static void g_history_panel_init(GHistoryPanel *panel)      GtkTreeViewColumn *column;              /* Colonne de la liste         */      GtkWidget *box;                         /* Séparation horizontale      */      GtkWidget *button;                      /* Bouton de cette même barre  */ +    GtkTreeSelection *select;               /* Sélection dans la liste     */      base = G_EDITOR_ITEM(panel); @@ -170,8 +171,7 @@ static void g_history_panel_init(GHistoryPanel *panel)      gtk_container_set_border_width(GTK_CONTAINER(base->widget), 8);      gtk_widget_show(base->widget); -    ref = G_OBJECT(base->widget); -    g_object_set_data(ref, "panel", panel); +    ref = G_OBJECT(panel);      /* Liste des éléments d'évolution */ @@ -194,8 +194,6 @@ static void g_history_panel_init(GHistoryPanel *panel)      gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(panel->store), sort_history_lines, NULL, NULL); -    g_signal_connect(treeview, "row-activated", G_CALLBACK(on_history_row_activated), panel); -      gtk_widget_show(treeview);      gtk_container_add(GTK_CONTAINER(scrollwnd), treeview); @@ -226,11 +224,11 @@ static void g_history_panel_init(GHistoryPanel *panel)      gtk_widget_show(box);      gtk_box_pack_start(GTK_BOX(base->widget), box, FALSE, TRUE, 0); -    button = qck_create_button_with_css_img(NULL, NULL, "img-undo", _("Undo"), +    button = qck_create_button_with_css_img(ref, "undo", "img-undo", _("Undo"),                                              G_CALLBACK(do_history_undo), panel);      gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); -    button = qck_create_button_with_css_img(NULL, NULL, "img-redo", _("Redo"), +    button = qck_create_button_with_css_img(ref, "redo", "img-redo", _("Redo"),                                              G_CALLBACK(do_history_redo), panel);      gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); @@ -238,6 +236,12 @@ static void g_history_panel_init(GHistoryPanel *panel)                                              G_CALLBACK(do_history_clean), panel);      gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); +    /* Prise en compte de la sélection */ + +    select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); +    gtk_tree_selection_set_mode(select, GTK_SELECTION_BROWSE); +    g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(on_history_selection_change), panel); +  } @@ -349,27 +353,39 @@ GPanelItem *create_history_panel(GObject *ref)  static void change_history_panel_current_binary(GHistoryPanel *panel, GLoadedBinary *binary)  { - - -    GtkTreeStore *store;                    /* Modèle de gestion           */      GList *collections;                     /* Ensemble de collections     */      GList *c;                               /* Boucle de parcours #1       */      GDbCollection *collec;                  /* Collection visée manipulée  */ +    GtkTreeStore *store;                    /* Modèle de gestion           */      GList *items;                           /* Liste des éléments groupés  */      GList *i;                               /* Boucle de parcours #2       */      GDbItem *item;                          /* Elément à intégrer          */      GtkTreeIter iter;                       /* Point d'insertion           */ -      /* Basculement du binaire utilisé */ +    if (panel->binary != NULL) +    { +        collections = g_loaded_binary_get_all_collections(panel->binary); +        rlock_collections(collections); -    panel->binary = binary; +        for (c = g_list_first(collections); c != NULL; c = g_list_next(c)) +        { +            collec = G_DB_COLLECTION(c->data); +            g_signal_handlers_disconnect_by_func(collec, G_CALLBACK(on_history_changed), panel); +        } +        runlock_collections(collections); +        g_object_unref(G_OBJECT(panel->binary)); +    } +    panel->binary = binary; + +    if (panel->binary != NULL) +        g_object_ref(G_OBJECT(binary));      store = GTK_TREE_STORE(gtk_tree_view_get_model(panel->treeview));      gtk_tree_store_clear(store); @@ -410,6 +426,9 @@ static void change_history_panel_current_binary(GHistoryPanel *panel, GLoadedBin      runlock_collections(collections); +    /* Force une sélection initiale */ +    on_history_changed(NULL, DBA_COUNT, NULL, panel); +  } @@ -432,34 +451,102 @@ static void on_history_changed(GDbCollection *collec, DBAction action, GDbItem *  {      GtkTreeModel *model;                    /* Modèle de gestion courant   */      GtkTreeIter iter;                       /* Boucle de parcours          */ -    GDbItem *displayed;                     /* Elément de collection       */ +    GtkTreeSelection *selection;            /* Nouvelle sélection à établir*/      model = GTK_TREE_MODEL(panel->store); -    switch (action) +    /* Mise à jour de la liste affichée */ + +    bool find_changed_item(GtkTreeModel *_model, GDbItem *target, GtkTreeIter *_found)      { -        case DBA_CHANGE_STATE: +        bool status; +        GtkTreeIter candidate; +        GDbItem *displayed; + +        status = false; + +        if (gtk_tree_model_get_iter_first(_model, &candidate)) +            do +            { +                gtk_tree_model_get(_model, &candidate, HTC_ITEM, &displayed, -1); -            if (gtk_tree_model_get_iter_first(model, &iter)) -                do +                if (target == displayed)                  { -                    gtk_tree_model_get(model, &iter, HTC_ITEM, &displayed, -1); +                    *_found = candidate; +                    status = true; +                } -                    if (item == displayed) -                    { -                        gtk_tree_store_set(panel->store, &iter, -                                           HTC_FOREGROUND, g_db_item_is_active(item) ? NULL : "grey", -                                           -1); -                        break; -                    } +                g_object_unref(G_OBJECT(displayed)); -                    g_object_unref(G_OBJECT(displayed)); +            } +            while (!status && gtk_tree_model_iter_next(_model, &candidate)); -                } -                while (gtk_tree_model_iter_next(model, &iter)); +        return status; + +    } + +    switch (action) +    { +        case DBA_ADD_ITEM: + +            gtk_tree_store_append(panel->store, &iter, NULL); +            gtk_tree_store_set(panel->store, &iter, +                               HTC_ITEM, item, +                               //HTC_PICTURE, G_BOOKMARKS_PANEL_GET_CLASS(panel)->bookmark_img, +                               HTC_FOREGROUND, g_db_item_is_active(item) ? NULL : "grey", +                               HTC_LABEL, g_db_item_get_label(item), +                               -1);              break; +        case DBA_REM_ITEM: + +            if (find_changed_item(model, item, &iter)) +                gtk_tree_store_remove(panel->store, &iter); + +            break; + +        case DBA_CHANGE_STATE: + +            if (find_changed_item(model, item, &iter)) +                gtk_tree_store_set(panel->store, &iter, +                                   HTC_FOREGROUND, g_db_item_is_active(item) ? NULL : "grey", +                                   -1); +            break; + +        case DBA_COUNT: +            /* Actualisation artificielle de la sélection */ +            break; + +    } + +    /* Redéfinition de la sélection */ + +    if (gtk_tree_model_get_iter_first(model, &iter)) +    { +        gboolean find_last_active(GtkTreeModel *_model, GtkTreePath *_path, GtkTreeIter *_iter, GtkTreeIter *last) +        { +            GDbItem *item; +            gboolean active; + +            gtk_tree_model_get(_model, _iter, HTC_ITEM, &item, -1); + +            active = g_db_item_is_active(item); + +            g_object_unref(G_OBJECT(item)); + +            if (active) +                *last = *_iter; + +            return !active; + +        } + +        gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)find_last_active, &iter); + +        selection = gtk_tree_view_get_selection(panel->treeview); +        gtk_tree_selection_select_iter(selection, &iter); +      }  } @@ -501,12 +588,10 @@ static gint sort_history_lines(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter  /******************************************************************************  *                                                                             * -*  Paramètres  : treeview = composant graphique manipulé par l'utilisateur.   * -*                path     = chemin d'accès à la ligne activée.                * -*                column   = colonne impactée par l'action.                    * -*                panel    = panneau d'historique concerné par la procédure.   * +*  Paramètres  : selection = sélection modifiée.                              * +*                panel     = structure contenant les informations maîtresses. *  *                                                                             * -*  Description : Réagit à une validation d'une ligne affichée.                * +*  Description : Réagit au changement de sélection des éléments d'historique. *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -514,20 +599,30 @@ static gint sort_history_lines(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter  *                                                                             *  ******************************************************************************/ -static void on_history_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *column, GHistoryPanel *panel) +static void on_history_selection_change(GtkTreeSelection *selection, GHistoryPanel *panel)  { +    GtkTreeIter iter;                       /* Point de sélection          */ +    GtkTreeModel *model;                    /* Modèle de gestion           */ +    GDbItem *item;                          /* Elément de collection       */ +    GtkWidget *button;                      /* Bouton de barre de contrôle */ +    if (gtk_tree_selection_get_selected(selection, &model, &iter)) +    { +        gtk_tree_model_get(model, &iter, HTC_ITEM, &item, -1); +        button = GTK_WIDGET(g_object_get_data(G_OBJECT(panel), "undo")); +        gtk_widget_set_sensitive(button, g_db_item_is_active(item)); +        button = GTK_WIDGET(g_object_get_data(G_OBJECT(panel), "redo")); +        gtk_widget_set_sensitive(button, !g_db_item_is_active(item)); +        g_object_unref(G_OBJECT(item)); +    }  } - - -  /******************************************************************************  *                                                                             *  *  Paramètres  : button = bouton d'édition de l'historique d'évolution.       * @@ -622,9 +717,6 @@ static void do_history_redo(GtkButton *button, GHistoryPanel *panel)  static void do_history_clean(GtkButton *button, GHistoryPanel *panel)  { - - - - +    /* TODO */  }  | 
