/* Chrysalide - Outil d'analyse de fichiers binaires * items.c - manipulation de l'ensemble des composants graphiques actifs * * Copyright (C) 2017 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide 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 3 of the License, or * (at your option) any later version. * * Chrysalide 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 Chrysalide. If not, see . */ #include "items.h" #include "global.h" #include "../editem-int.h" #include "../../analysis/db/items/move.h" /* Liste des éléments enregistrés */ static GEditorItem *_editem_list = NULL; /* Initialisations premières de façon unique */ static bool _first_content_change = true; static bool _first_panel_change = true; /* Lance une procédure de déplacement de la position courante. */ static void start_moving_to_cursor_in_loaded_panel(GLoadedPanel *, const GLineCursor *, gboolean, gpointer); /* Suit les changements de position dans du code d'assembleur. */ static void track_cursor_on_view_panel(GLoadedPanel *, const GLineCursor *, gpointer); /****************************************************************************** * * * Paramètres : - * * * * Description : Procède à l'enregistrement d'un élément reactif de l'éditeur.* * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void register_editor_item(GEditorItem *item) { editem_list_add_tail(item, &_editem_list); } /****************************************************************************** * * * Paramètres : content = nouvelle instance de contenu analysé. * * * * Description : Lance une actualisation du fait d'un changement de contenu. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void change_editor_items_current_content(GLoadedContent *content) { GLoadedContent *old; /* Ancien contenu */ GEditorItem *iter; /* Boucle de parcours */ old = get_current_content(); if (content != old || _first_content_change) { _first_content_change = false; if (content != NULL) g_object_ref(G_OBJECT(content)); set_current_content(content); editem_list_for_each(iter, _editem_list) { g_editor_item_change_content(iter, old, content); } } if (old != NULL) g_object_unref(G_OBJECT(old)); } /****************************************************************************** * * * Paramètres : panel = composant d'affichage parcouru. * * cursor = emplacement à cibler pour un déplacement. * * save = le changement est-il majeur ? * * unused = adresse non utilisée ici. * * * * Description : Lance une procédure de déplacement de la position courante. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void start_moving_to_cursor_in_loaded_panel(GLoadedPanel *panel, const GLineCursor *cursor, gboolean save, gpointer unused) { GLineCursor *src; /* Position courante de curseur*/ GDbMove *move; /* Déplacement à organiser */ GLoadedBinary *binary; /* Binaire en cours d'étude */ src = g_loaded_panel_get_cursor(panel); if (save && src != NULL) { move = g_db_move_new(src, cursor); binary = G_LOADED_BINARY(g_loaded_panel_get_content(panel)); g_loaded_binary_add_to_collection(binary, G_DB_ITEM(move)); g_object_unref(G_OBJECT(binary)); } else g_loaded_panel_scroll_to_cursor(panel, cursor, SPT_CENTER, true); if (src != NULL) g_object_unref(G_OBJECT(src)); } /****************************************************************************** * * * Paramètres : panel = composant d'affichage parcouru. * * cursor = nouvel emplacement du curseur courant. * * unused = adresse non utilisée ici. * * * * Description : Suit les changements de position dans du code d'assembleur. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void track_cursor_on_view_panel(GLoadedPanel *panel, const GLineCursor *cursor, gpointer unused) { GEditorItem *iter; /* Boucle de parcours */ editem_list_for_each(iter, _editem_list) { g_editor_item_track_cursor(iter, panel, cursor); } } /****************************************************************************** * * * Paramètres : panel = nouveau panneau d'affichage actif. * * * * Description : Lance une actualisation du fait d'un changement de vue. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void change_editor_items_current_view(GLoadedPanel *panel) { GLoadedPanel *old; /* Ancien affichage */ GEditorItem *iter; /* Boucle de parcours */ /* Suivi des affichages */ old = get_current_view(); if (panel != old || _first_panel_change) { _first_panel_change = false; if (panel != NULL) g_object_ref(G_OBJECT(panel)); set_current_view(panel); editem_list_for_each(iter, _editem_list) { g_editor_item_change_view(iter, old, panel); } /* Suivi du curseur */ if (old != NULL) { g_signal_handlers_disconnect_by_func(old, G_CALLBACK(start_moving_to_cursor_in_loaded_panel), NULL); g_signal_handlers_disconnect_by_func(old, G_CALLBACK(track_cursor_on_view_panel), NULL); } if (panel != NULL) { g_signal_connect(panel, "move-request", G_CALLBACK(start_moving_to_cursor_in_loaded_panel), NULL); g_signal_connect(panel, "cursor-moved", G_CALLBACK(track_cursor_on_view_panel), NULL); } } if (old != NULL) g_object_unref(G_OBJECT(old)); } /****************************************************************************** * * * Paramètres : panel = nouveau panneau d'affichage actif. * * * * Description : Lance une actualisation du fait d'un changement de contenu. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void update_editor_items_current_view(GLoadedPanel *panel) { GEditorItem *iter; /* Boucle de parcours */ editem_list_for_each(iter, _editem_list) { g_editor_item_update_view(iter, panel); } } /****************************************************************************** * * * Paramètres : content = contenu contenant le curseur à représenter. * * cursor = nouvel emplacement du curseur courant. * * source = composant à l'origine du changement. * * * * Description : Concentre l'attention de l'ensemble sur une adresse donnée. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void focus_cursor_in_editor_items(GLoadedContent *content, const GLineCursor *cursor, GEditorItem *source) { GEditorItem *iter; /* Boucle de parcours */ editem_list_for_each(iter, _editem_list) { if (iter != source) g_editor_item_focus_cursor(iter, content, cursor); } } /****************************************************************************** * * * Paramètres : project = projet concerné par l'évolution. * * * * Description : Lance une actualisation relative à l'étendue du projet. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void update_project_area(GStudyProject *project) { GEditorItem *iter; /* Boucle de parcours */ GEditorItemClass *klass; /* Classe correspondante */ editem_list_for_each(iter, _editem_list) { klass = G_EDITOR_ITEM_GET_CLASS(iter); if (klass->update_project != NULL) klass->update_project(iter, project); } }