2031 lines
40 KiB
C
2031 lines
40 KiB
C
/******************************************************************************
|
||
* @file workspace.c
|
||
* @brief Implémentation de la zone principale de travail.
|
||
******************************************************************************/
|
||
|
||
#include "widgets/workspace.h"
|
||
|
||
#include "widgets/entity_details_panel.h"
|
||
#include "widgets/investigation_graph_view.h"
|
||
|
||
#include <glib.h>
|
||
|
||
#define WORKSPACE_PAGE_WELCOME "welcome"
|
||
#define WORKSPACE_PAGE_NODE_INFORMATION "node-information"
|
||
#define WORKSPACE_PAGE_EVIDENCE_INFORMATION \
|
||
"evidence-information"
|
||
#define WORKSPACE_PAGE_GRAPH_STATE \
|
||
"graph-state"
|
||
#define WORKSPACE_PAGE_GRAPH_VIEW \
|
||
"graph-view"
|
||
|
||
/**
|
||
* @brief État métier représenté par la page du graphe.
|
||
*/
|
||
typedef enum
|
||
{
|
||
WORKSPACE_GRAPH_STATE_EMPTY,
|
||
WORKSPACE_GRAPH_STATE_LOADING,
|
||
WORKSPACE_GRAPH_STATE_READY,
|
||
WORKSPACE_GRAPH_STATE_ERROR
|
||
} WorkspaceGraphState;
|
||
|
||
/**
|
||
* @struct Workspace
|
||
* @brief Représentation interne de la zone de travail.
|
||
*/
|
||
struct Workspace
|
||
{
|
||
GtkWidget *root_widget;
|
||
GtkWidget *stack;
|
||
|
||
GtkWidget *welcome_page;
|
||
|
||
GtkWidget *graph_state_page;
|
||
GtkWidget *graph_spinner;
|
||
GtkWidget *graph_title_label;
|
||
GtkWidget *graph_details_label;
|
||
|
||
GtkWidget *graph_view_page;
|
||
GtkWidget *graph_toolbar;
|
||
GtkWidget *reset_graph_layout_button;
|
||
|
||
InvestigationGraphView *graph_view;
|
||
EntityDetailsPanel *entity_details_panel;
|
||
|
||
GtkWidget *node_page;
|
||
|
||
GtkWidget *evidence_page;
|
||
GtkWidget *evidence_name_label;
|
||
|
||
GtkWidget *evidence_type_label;
|
||
GtkWidget *evidence_integrity_label;
|
||
GtkWidget *evidence_size_label;
|
||
GtkWidget *evidence_imported_at_label;
|
||
GtkWidget *evidence_collected_at_label;
|
||
GtkWidget *evidence_source_label;
|
||
GtkWidget *evidence_description_label;
|
||
GtkWidget *evidence_relative_path_label;
|
||
GtkWidget *evidence_internal_name_label;
|
||
GtkWidget *evidence_identifier_label;
|
||
GtkWidget *evidence_sha256_label;
|
||
GtkWidget *verify_evidence_button;
|
||
|
||
char *selected_evidence_identifier;
|
||
|
||
WorkspaceVerifyEvidenceCallback
|
||
verify_evidence_callback;
|
||
|
||
gpointer
|
||
verify_evidence_user_data;
|
||
|
||
WorkspaceGraphNodeMovedCallback
|
||
graph_node_moved_callback;
|
||
|
||
gpointer
|
||
graph_node_moved_user_data;
|
||
|
||
WorkspaceResetGraphLayoutCallback
|
||
reset_graph_layout_callback;
|
||
|
||
gpointer
|
||
reset_graph_layout_user_data;
|
||
|
||
GtkWidget *node_name_label;
|
||
GtkWidget *node_path_label;
|
||
GtkWidget *node_type_label;
|
||
GtkWidget *node_parent_label;
|
||
GtkWidget *node_children_label;
|
||
|
||
const InvestigationGraphModel *graph_model;
|
||
const InvestigationGraphLayout *graph_layout;
|
||
|
||
WorkspaceGraphState graph_state;
|
||
};
|
||
|
||
/**
|
||
* @brief Ajoute une ligne de métadonnée dans la grille.
|
||
*
|
||
* @return Label GTK destiné à recevoir la valeur.
|
||
*/
|
||
static GtkWidget *workspace_add_evidence_field(
|
||
GtkGrid *grid,
|
||
gint row,
|
||
const char *title
|
||
)
|
||
{
|
||
GtkWidget *title_label = NULL;
|
||
GtkWidget *value_label = NULL;
|
||
|
||
if (grid == NULL ||
|
||
title == NULL ||
|
||
title[0] == '\0')
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
title_label =
|
||
gtk_label_new(
|
||
title
|
||
);
|
||
|
||
value_label =
|
||
gtk_label_new(
|
||
NULL
|
||
);
|
||
|
||
if (title_label == NULL ||
|
||
value_label == NULL)
|
||
{
|
||
g_clear_object(
|
||
&value_label
|
||
);
|
||
|
||
g_clear_object(
|
||
&title_label
|
||
);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
gtk_label_set_xalign(
|
||
GTK_LABEL(title_label),
|
||
0.0F
|
||
);
|
||
|
||
gtk_widget_set_valign(
|
||
title_label,
|
||
GTK_ALIGN_START
|
||
);
|
||
|
||
gtk_widget_add_css_class(
|
||
title_label,
|
||
"dim-label"
|
||
);
|
||
|
||
gtk_label_set_xalign(
|
||
GTK_LABEL(value_label),
|
||
0.0F
|
||
);
|
||
|
||
gtk_label_set_wrap(
|
||
GTK_LABEL(value_label),
|
||
TRUE
|
||
);
|
||
|
||
gtk_label_set_wrap_mode(
|
||
GTK_LABEL(value_label),
|
||
PANGO_WRAP_WORD_CHAR
|
||
);
|
||
|
||
gtk_label_set_selectable(
|
||
GTK_LABEL(value_label),
|
||
TRUE
|
||
);
|
||
|
||
gtk_widget_set_hexpand(
|
||
value_label,
|
||
TRUE
|
||
);
|
||
|
||
gtk_widget_set_halign(
|
||
value_label,
|
||
GTK_ALIGN_FILL
|
||
);
|
||
|
||
gtk_widget_set_valign(
|
||
value_label,
|
||
GTK_ALIGN_START
|
||
);
|
||
|
||
gtk_grid_attach(
|
||
grid,
|
||
title_label,
|
||
0,
|
||
row,
|
||
1,
|
||
1
|
||
);
|
||
|
||
gtk_grid_attach(
|
||
grid,
|
||
value_label,
|
||
1,
|
||
row,
|
||
1,
|
||
1
|
||
);
|
||
|
||
return value_label;
|
||
}
|
||
|
||
/**
|
||
* @brief Définit une valeur avec un texte de remplacement.
|
||
*/
|
||
static void workspace_set_field_text(
|
||
GtkWidget *label,
|
||
const char *value,
|
||
const char *fallback
|
||
)
|
||
{
|
||
if (label == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
gtk_label_set_text(
|
||
GTK_LABEL(label),
|
||
value != NULL && value[0] != '\0'
|
||
? value
|
||
: fallback
|
||
);
|
||
}
|
||
|
||
/**
|
||
* @brief Convertit un statut d'intégrité en texte utilisateur.
|
||
*/
|
||
static const char *workspace_get_integrity_status_text(
|
||
EvidenceIntegrityStatus integrity_status
|
||
)
|
||
{
|
||
switch (integrity_status)
|
||
{
|
||
case EVIDENCE_INTEGRITY_STATUS_UNKNOWN:
|
||
return "Non vérifiée";
|
||
|
||
case EVIDENCE_INTEGRITY_STATUS_VALID:
|
||
return "Valide";
|
||
|
||
case EVIDENCE_INTEGRITY_STATUS_MISSING:
|
||
return "Fichier absent";
|
||
|
||
case EVIDENCE_INTEGRITY_STATUS_MODIFIED:
|
||
return "Fichier modifié";
|
||
|
||
case EVIDENCE_INTEGRITY_STATUS_ERROR:
|
||
return "Erreur de vérification";
|
||
|
||
default:
|
||
return "Statut inconnu";
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief Transmet la sélection du graphe au volet de détails.
|
||
*/
|
||
static void workspace_on_graph_node_moved(
|
||
const char *entity_identifier,
|
||
double x,
|
||
double y,
|
||
gpointer user_data
|
||
)
|
||
{
|
||
Workspace *workspace =
|
||
user_data;
|
||
|
||
if (workspace == NULL ||
|
||
workspace->graph_node_moved_callback == NULL ||
|
||
entity_identifier == NULL ||
|
||
entity_identifier[0] == '\0')
|
||
{
|
||
return;
|
||
}
|
||
|
||
workspace->graph_node_moved_callback(
|
||
entity_identifier,
|
||
x,
|
||
y,
|
||
workspace->graph_node_moved_user_data
|
||
);
|
||
}
|
||
|
||
/**
|
||
* @brief Transmet la sélection du graphe au volet de détails.
|
||
*/
|
||
static void workspace_on_graph_entity_selected(
|
||
const EntityRecord *entity_record,
|
||
gpointer user_data
|
||
)
|
||
{
|
||
Workspace *workspace =
|
||
user_data;
|
||
|
||
if (workspace == NULL ||
|
||
workspace->entity_details_panel == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
entity_details_panel_set_entity(
|
||
workspace->entity_details_panel,
|
||
entity_record
|
||
);
|
||
}
|
||
|
||
/**
|
||
* @brief Désélectionne le nœud lorsque le volet est fermé manuellement.
|
||
*/
|
||
static void workspace_on_entity_details_closed(
|
||
gpointer user_data
|
||
)
|
||
{
|
||
Workspace *workspace =
|
||
user_data;
|
||
|
||
if (workspace == NULL ||
|
||
workspace->graph_view == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
investigation_graph_view_clear_selection(
|
||
workspace->graph_view
|
||
);
|
||
}
|
||
|
||
/**
|
||
* @brief Affiche l'état principal courant du Workspace.
|
||
*
|
||
* Sans enquête, la page d'accueil est utilisée. Le chargement et les erreurs
|
||
* utilisent la page d'état. Un graphe prêt utilise la vue graphique.
|
||
*/
|
||
static void workspace_show_default(
|
||
Workspace *workspace
|
||
)
|
||
{
|
||
if (workspace == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
switch (workspace->graph_state)
|
||
{
|
||
case WORKSPACE_GRAPH_STATE_EMPTY:
|
||
gtk_stack_set_visible_child_name(
|
||
GTK_STACK(workspace->stack),
|
||
WORKSPACE_PAGE_WELCOME
|
||
);
|
||
|
||
return;
|
||
|
||
case WORKSPACE_GRAPH_STATE_READY:
|
||
gtk_stack_set_visible_child_name(
|
||
GTK_STACK(workspace->stack),
|
||
WORKSPACE_PAGE_GRAPH_VIEW
|
||
);
|
||
|
||
return;
|
||
|
||
case WORKSPACE_GRAPH_STATE_LOADING:
|
||
case WORKSPACE_GRAPH_STATE_ERROR:
|
||
default:
|
||
gtk_stack_set_visible_child_name(
|
||
GTK_STACK(workspace->stack),
|
||
WORKSPACE_PAGE_GRAPH_STATE
|
||
);
|
||
|
||
return;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief Transmet la demande de vérification de la preuve affichée.
|
||
*/
|
||
static void workspace_on_reset_graph_layout_clicked(
|
||
GtkButton *button,
|
||
gpointer user_data
|
||
)
|
||
{
|
||
Workspace *workspace =
|
||
user_data;
|
||
|
||
(void) button;
|
||
|
||
if (workspace == NULL ||
|
||
workspace->graph_state != WORKSPACE_GRAPH_STATE_READY ||
|
||
workspace->graph_model == NULL ||
|
||
workspace->reset_graph_layout_callback == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
workspace->reset_graph_layout_callback(
|
||
workspace->reset_graph_layout_user_data
|
||
);
|
||
}
|
||
|
||
/**
|
||
* @brief Transmet la demande de vérification de la preuve affichée.
|
||
*/
|
||
static void workspace_on_verify_evidence_clicked(
|
||
GtkButton *button,
|
||
gpointer user_data
|
||
)
|
||
{
|
||
Workspace *workspace =
|
||
user_data;
|
||
|
||
(void) button;
|
||
|
||
if (workspace == NULL ||
|
||
workspace->verify_evidence_callback == NULL ||
|
||
workspace->selected_evidence_identifier == NULL ||
|
||
workspace->selected_evidence_identifier[0] == '\0')
|
||
{
|
||
return;
|
||
}
|
||
|
||
workspace->verify_evidence_callback(
|
||
workspace->selected_evidence_identifier,
|
||
workspace->verify_evidence_user_data
|
||
);
|
||
}
|
||
|
||
Workspace *workspace_new(void)
|
||
{
|
||
GtkWidget *evidence_content = NULL;
|
||
GtkWidget *evidence_separator = NULL;
|
||
GtkWidget *evidence_grid = NULL;
|
||
|
||
Workspace *workspace = NULL;
|
||
|
||
workspace = g_new0(Workspace, 1);
|
||
|
||
workspace->root_widget = gtk_box_new(
|
||
GTK_ORIENTATION_VERTICAL,
|
||
0
|
||
);
|
||
|
||
if (workspace->root_widget == NULL)
|
||
{
|
||
workspace_free(workspace);
|
||
return NULL;
|
||
}
|
||
|
||
gtk_widget_set_hexpand(
|
||
workspace->root_widget,
|
||
TRUE
|
||
);
|
||
|
||
gtk_widget_set_vexpand(
|
||
workspace->root_widget,
|
||
TRUE
|
||
);
|
||
|
||
workspace->stack = gtk_stack_new();
|
||
|
||
if (workspace->stack == NULL)
|
||
{
|
||
workspace_free(workspace);
|
||
return NULL;
|
||
}
|
||
|
||
gtk_widget_set_hexpand(
|
||
workspace->stack,
|
||
TRUE
|
||
);
|
||
|
||
gtk_widget_set_vexpand(
|
||
workspace->stack,
|
||
TRUE
|
||
);
|
||
|
||
gtk_box_append(
|
||
GTK_BOX(workspace->root_widget),
|
||
workspace->stack
|
||
);
|
||
|
||
/*
|
||
* Page d'accueil.
|
||
*/
|
||
workspace->welcome_page = gtk_box_new(
|
||
GTK_ORIENTATION_VERTICAL,
|
||
12
|
||
);
|
||
|
||
if (workspace->welcome_page == NULL)
|
||
{
|
||
workspace_free(workspace);
|
||
return NULL;
|
||
}
|
||
|
||
gtk_widget_set_halign(
|
||
workspace->welcome_page,
|
||
GTK_ALIGN_CENTER
|
||
);
|
||
|
||
gtk_widget_set_valign(
|
||
workspace->welcome_page,
|
||
GTK_ALIGN_CENTER
|
||
);
|
||
|
||
gtk_stack_add_named(
|
||
GTK_STACK(workspace->stack),
|
||
workspace->welcome_page,
|
||
WORKSPACE_PAGE_WELCOME
|
||
);
|
||
|
||
/*
|
||
* Page d'informations sur le nœud.
|
||
*/
|
||
workspace->node_page = gtk_box_new(
|
||
GTK_ORIENTATION_VERTICAL,
|
||
12
|
||
);
|
||
|
||
if (workspace->node_page == NULL)
|
||
{
|
||
workspace_free(workspace);
|
||
return NULL;
|
||
}
|
||
|
||
gtk_widget_set_halign(
|
||
workspace->node_page,
|
||
GTK_ALIGN_CENTER
|
||
);
|
||
|
||
gtk_widget_set_valign(
|
||
workspace->node_page,
|
||
GTK_ALIGN_CENTER
|
||
);
|
||
|
||
workspace->node_name_label = gtk_label_new(NULL);
|
||
workspace->node_path_label = gtk_label_new(NULL);
|
||
workspace->node_type_label = gtk_label_new(NULL);
|
||
workspace->node_parent_label = gtk_label_new(NULL);
|
||
workspace->node_children_label = gtk_label_new(NULL);
|
||
|
||
gtk_box_append(
|
||
GTK_BOX(workspace->node_page),
|
||
workspace->node_name_label
|
||
);
|
||
|
||
gtk_box_append(
|
||
GTK_BOX(workspace->node_page),
|
||
workspace->node_path_label
|
||
);
|
||
|
||
gtk_label_set_wrap(
|
||
GTK_LABEL(workspace->node_path_label),
|
||
TRUE
|
||
);
|
||
|
||
gtk_label_set_selectable(
|
||
GTK_LABEL(workspace->node_path_label),
|
||
TRUE
|
||
);
|
||
|
||
gtk_widget_set_halign(
|
||
workspace->node_path_label,
|
||
GTK_ALIGN_CENTER
|
||
);
|
||
|
||
gtk_box_append(
|
||
GTK_BOX(workspace->node_page),
|
||
workspace->node_type_label
|
||
);
|
||
|
||
gtk_box_append(
|
||
GTK_BOX(workspace->node_page),
|
||
workspace->node_parent_label
|
||
);
|
||
|
||
gtk_box_append(
|
||
GTK_BOX(workspace->node_page),
|
||
workspace->node_children_label
|
||
);
|
||
|
||
gtk_stack_add_named(
|
||
GTK_STACK(workspace->stack),
|
||
workspace->node_page,
|
||
WORKSPACE_PAGE_NODE_INFORMATION
|
||
);
|
||
|
||
/*
|
||
* Page détaillée d'une preuve.
|
||
*/
|
||
workspace->evidence_page =
|
||
gtk_scrolled_window_new();
|
||
|
||
if (workspace->evidence_page == NULL)
|
||
{
|
||
workspace_free(
|
||
workspace
|
||
);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
gtk_widget_set_hexpand(
|
||
workspace->evidence_page,
|
||
TRUE
|
||
);
|
||
|
||
gtk_widget_set_vexpand(
|
||
workspace->evidence_page,
|
||
TRUE
|
||
);
|
||
|
||
gtk_scrolled_window_set_policy(
|
||
GTK_SCROLLED_WINDOW(
|
||
workspace->evidence_page
|
||
),
|
||
GTK_POLICY_AUTOMATIC,
|
||
GTK_POLICY_AUTOMATIC
|
||
);
|
||
|
||
evidence_content =
|
||
gtk_box_new(
|
||
GTK_ORIENTATION_VERTICAL,
|
||
16
|
||
);
|
||
|
||
if (evidence_content == NULL)
|
||
{
|
||
workspace_free(
|
||
workspace
|
||
);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
gtk_widget_set_margin_start(
|
||
evidence_content,
|
||
24
|
||
);
|
||
|
||
gtk_widget_set_margin_end(
|
||
evidence_content,
|
||
24
|
||
);
|
||
|
||
gtk_widget_set_margin_top(
|
||
evidence_content,
|
||
24
|
||
);
|
||
|
||
gtk_widget_set_margin_bottom(
|
||
evidence_content,
|
||
24
|
||
);
|
||
|
||
workspace->evidence_name_label =
|
||
gtk_label_new(
|
||
NULL
|
||
);
|
||
|
||
if (workspace->evidence_name_label == NULL)
|
||
{
|
||
workspace_free(
|
||
workspace
|
||
);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
gtk_label_set_xalign(
|
||
GTK_LABEL(
|
||
workspace->evidence_name_label
|
||
),
|
||
0.0F
|
||
);
|
||
|
||
gtk_label_set_wrap(
|
||
GTK_LABEL(
|
||
workspace->evidence_name_label
|
||
),
|
||
TRUE
|
||
);
|
||
|
||
gtk_label_set_selectable(
|
||
GTK_LABEL(
|
||
workspace->evidence_name_label
|
||
),
|
||
TRUE
|
||
);
|
||
|
||
gtk_widget_add_css_class(
|
||
workspace->evidence_name_label,
|
||
"title-2"
|
||
);
|
||
|
||
gtk_box_append(
|
||
GTK_BOX(evidence_content),
|
||
workspace->evidence_name_label
|
||
);
|
||
|
||
workspace->verify_evidence_button =
|
||
gtk_button_new_with_label(
|
||
"Vérifier l'intégrité"
|
||
);
|
||
|
||
if (workspace->verify_evidence_button == NULL)
|
||
{
|
||
workspace_free(
|
||
workspace
|
||
);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
gtk_widget_set_halign(
|
||
workspace->verify_evidence_button,
|
||
GTK_ALIGN_START
|
||
);
|
||
|
||
gtk_widget_set_tooltip_text(
|
||
workspace->verify_evidence_button,
|
||
"Recalculer le SHA-256 et le comparer à l'empreinte enregistrée"
|
||
);
|
||
|
||
/*
|
||
* Aucun bouton actif tant qu'aucune preuve n'est affichée.
|
||
*/
|
||
gtk_widget_set_sensitive(
|
||
workspace->verify_evidence_button,
|
||
FALSE
|
||
);
|
||
|
||
g_signal_connect(
|
||
workspace->verify_evidence_button,
|
||
"clicked",
|
||
G_CALLBACK(
|
||
workspace_on_verify_evidence_clicked
|
||
),
|
||
workspace
|
||
);
|
||
|
||
gtk_box_append(
|
||
GTK_BOX(evidence_content),
|
||
workspace->verify_evidence_button
|
||
);
|
||
|
||
evidence_separator =
|
||
gtk_separator_new(
|
||
GTK_ORIENTATION_HORIZONTAL
|
||
);
|
||
|
||
gtk_box_append(
|
||
GTK_BOX(evidence_content),
|
||
evidence_separator
|
||
);
|
||
|
||
evidence_grid =
|
||
gtk_grid_new();
|
||
|
||
if (evidence_grid == NULL)
|
||
{
|
||
workspace_free(
|
||
workspace
|
||
);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
gtk_grid_set_column_spacing(
|
||
GTK_GRID(evidence_grid),
|
||
24
|
||
);
|
||
|
||
gtk_grid_set_row_spacing(
|
||
GTK_GRID(evidence_grid),
|
||
12
|
||
);
|
||
|
||
gtk_widget_set_hexpand(
|
||
evidence_grid,
|
||
TRUE
|
||
);
|
||
|
||
workspace->evidence_type_label =
|
||
workspace_add_evidence_field(
|
||
GTK_GRID(evidence_grid),
|
||
0,
|
||
"Type"
|
||
);
|
||
|
||
workspace->evidence_integrity_label =
|
||
workspace_add_evidence_field(
|
||
GTK_GRID(evidence_grid),
|
||
1,
|
||
"Intégrité"
|
||
);
|
||
|
||
workspace->evidence_size_label =
|
||
workspace_add_evidence_field(
|
||
GTK_GRID(evidence_grid),
|
||
2,
|
||
"Taille"
|
||
);
|
||
|
||
workspace->evidence_imported_at_label =
|
||
workspace_add_evidence_field(
|
||
GTK_GRID(evidence_grid),
|
||
3,
|
||
"Importée le"
|
||
);
|
||
|
||
workspace->evidence_collected_at_label =
|
||
workspace_add_evidence_field(
|
||
GTK_GRID(evidence_grid),
|
||
4,
|
||
"Collectée le"
|
||
);
|
||
|
||
workspace->evidence_source_label =
|
||
workspace_add_evidence_field(
|
||
GTK_GRID(evidence_grid),
|
||
5,
|
||
"Source"
|
||
);
|
||
|
||
workspace->evidence_description_label =
|
||
workspace_add_evidence_field(
|
||
GTK_GRID(evidence_grid),
|
||
6,
|
||
"Description"
|
||
);
|
||
|
||
workspace->evidence_relative_path_label =
|
||
workspace_add_evidence_field(
|
||
GTK_GRID(evidence_grid),
|
||
7,
|
||
"Chemin relatif"
|
||
);
|
||
|
||
workspace->evidence_internal_name_label =
|
||
workspace_add_evidence_field(
|
||
GTK_GRID(evidence_grid),
|
||
8,
|
||
"Nom interne"
|
||
);
|
||
|
||
workspace->evidence_identifier_label =
|
||
workspace_add_evidence_field(
|
||
GTK_GRID(evidence_grid),
|
||
9,
|
||
"Identifiant"
|
||
);
|
||
|
||
workspace->evidence_sha256_label =
|
||
workspace_add_evidence_field(
|
||
GTK_GRID(evidence_grid),
|
||
10,
|
||
"SHA-256"
|
||
);
|
||
|
||
if (workspace->evidence_type_label == NULL ||
|
||
workspace->evidence_integrity_label == NULL ||
|
||
workspace->evidence_size_label == NULL ||
|
||
workspace->evidence_imported_at_label == NULL ||
|
||
workspace->evidence_collected_at_label == NULL ||
|
||
workspace->evidence_source_label == NULL ||
|
||
workspace->evidence_description_label == NULL ||
|
||
workspace->evidence_relative_path_label == NULL ||
|
||
workspace->evidence_internal_name_label == NULL ||
|
||
workspace->evidence_identifier_label == NULL ||
|
||
workspace->evidence_sha256_label == NULL)
|
||
{
|
||
workspace_free(
|
||
workspace
|
||
);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
gtk_box_append(
|
||
GTK_BOX(evidence_content),
|
||
evidence_grid
|
||
);
|
||
|
||
gtk_scrolled_window_set_child(
|
||
GTK_SCROLLED_WINDOW(
|
||
workspace->evidence_page
|
||
),
|
||
evidence_content
|
||
);
|
||
|
||
gtk_stack_add_named(
|
||
GTK_STACK(workspace->stack),
|
||
workspace->evidence_page,
|
||
WORKSPACE_PAGE_EVIDENCE_INFORMATION
|
||
);
|
||
|
||
/*
|
||
* Page d'état utilisée pendant le chargement ou en cas d'erreur.
|
||
*/
|
||
workspace->graph_state_page =
|
||
gtk_box_new(
|
||
GTK_ORIENTATION_VERTICAL,
|
||
12
|
||
);
|
||
|
||
if (workspace->graph_state_page == NULL)
|
||
{
|
||
workspace_free(
|
||
workspace
|
||
);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
gtk_widget_set_halign(
|
||
workspace->graph_state_page,
|
||
GTK_ALIGN_CENTER
|
||
);
|
||
|
||
gtk_widget_set_valign(
|
||
workspace->graph_state_page,
|
||
GTK_ALIGN_CENTER
|
||
);
|
||
|
||
workspace->graph_spinner =
|
||
gtk_spinner_new();
|
||
|
||
workspace->graph_title_label =
|
||
gtk_label_new(
|
||
NULL
|
||
);
|
||
|
||
workspace->graph_details_label =
|
||
gtk_label_new(
|
||
NULL
|
||
);
|
||
|
||
if (workspace->graph_spinner == NULL ||
|
||
workspace->graph_title_label == NULL ||
|
||
workspace->graph_details_label == NULL)
|
||
{
|
||
workspace_free(
|
||
workspace
|
||
);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
gtk_widget_add_css_class(
|
||
workspace->graph_title_label,
|
||
"title-2"
|
||
);
|
||
|
||
gtk_label_set_wrap(
|
||
GTK_LABEL(
|
||
workspace->graph_details_label
|
||
),
|
||
TRUE
|
||
);
|
||
|
||
gtk_label_set_justify(
|
||
GTK_LABEL(
|
||
workspace->graph_details_label
|
||
),
|
||
GTK_JUSTIFY_CENTER
|
||
);
|
||
|
||
gtk_widget_set_visible(
|
||
workspace->graph_spinner,
|
||
FALSE
|
||
);
|
||
|
||
gtk_box_append(
|
||
GTK_BOX(
|
||
workspace->graph_state_page
|
||
),
|
||
workspace->graph_spinner
|
||
);
|
||
|
||
gtk_box_append(
|
||
GTK_BOX(
|
||
workspace->graph_state_page
|
||
),
|
||
workspace->graph_title_label
|
||
);
|
||
|
||
gtk_box_append(
|
||
GTK_BOX(
|
||
workspace->graph_state_page
|
||
),
|
||
workspace->graph_details_label
|
||
);
|
||
|
||
gtk_stack_add_named(
|
||
GTK_STACK(workspace->stack),
|
||
workspace->graph_state_page,
|
||
WORKSPACE_PAGE_GRAPH_STATE
|
||
);
|
||
|
||
/*
|
||
* Page graphique : canvas principal et volet de détails superposé.
|
||
*/
|
||
workspace->graph_view_page =
|
||
gtk_overlay_new();
|
||
|
||
if (workspace->graph_view_page == NULL)
|
||
{
|
||
workspace_free(
|
||
workspace
|
||
);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
gtk_widget_set_hexpand(
|
||
workspace->graph_view_page,
|
||
TRUE
|
||
);
|
||
|
||
gtk_widget_set_vexpand(
|
||
workspace->graph_view_page,
|
||
TRUE
|
||
);
|
||
|
||
workspace->graph_view =
|
||
investigation_graph_view_new();
|
||
|
||
workspace->entity_details_panel =
|
||
entity_details_panel_new();
|
||
|
||
if (workspace->graph_view == NULL ||
|
||
workspace->entity_details_panel == NULL)
|
||
{
|
||
workspace_free(
|
||
workspace
|
||
);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
investigation_graph_view_set_selection_callback(
|
||
workspace->graph_view,
|
||
workspace_on_graph_entity_selected,
|
||
workspace
|
||
);
|
||
|
||
investigation_graph_view_set_node_moved_callback(
|
||
workspace->graph_view,
|
||
workspace_on_graph_node_moved,
|
||
workspace
|
||
);
|
||
|
||
entity_details_panel_set_close_callback(
|
||
workspace->entity_details_panel,
|
||
workspace_on_entity_details_closed,
|
||
workspace
|
||
);
|
||
|
||
gtk_overlay_set_child(
|
||
GTK_OVERLAY(
|
||
workspace->graph_view_page
|
||
),
|
||
investigation_graph_view_get_widget(
|
||
workspace->graph_view
|
||
)
|
||
);
|
||
|
||
workspace->graph_toolbar =
|
||
gtk_box_new(
|
||
GTK_ORIENTATION_HORIZONTAL,
|
||
4
|
||
);
|
||
|
||
workspace->reset_graph_layout_button =
|
||
gtk_button_new_from_icon_name(
|
||
"view-refresh-symbolic"
|
||
);
|
||
|
||
if (workspace->graph_toolbar == NULL ||
|
||
workspace->reset_graph_layout_button == NULL)
|
||
{
|
||
workspace_free(
|
||
workspace
|
||
);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
gtk_widget_set_halign(
|
||
workspace->graph_toolbar,
|
||
GTK_ALIGN_START
|
||
);
|
||
|
||
gtk_widget_set_valign(
|
||
workspace->graph_toolbar,
|
||
GTK_ALIGN_START
|
||
);
|
||
|
||
gtk_widget_set_margin_start(
|
||
workspace->graph_toolbar,
|
||
12
|
||
);
|
||
|
||
gtk_widget_set_margin_top(
|
||
workspace->graph_toolbar,
|
||
12
|
||
);
|
||
|
||
gtk_widget_add_css_class(
|
||
workspace->graph_toolbar,
|
||
"toolbar"
|
||
);
|
||
|
||
gtk_widget_add_css_class(
|
||
workspace->reset_graph_layout_button,
|
||
"flat"
|
||
);
|
||
|
||
gtk_widget_set_tooltip_text(
|
||
workspace->reset_graph_layout_button,
|
||
"Réinitialiser la disposition du graphe"
|
||
);
|
||
|
||
gtk_widget_set_sensitive(
|
||
workspace->reset_graph_layout_button,
|
||
FALSE
|
||
);
|
||
|
||
g_signal_connect(
|
||
workspace->reset_graph_layout_button,
|
||
"clicked",
|
||
G_CALLBACK(
|
||
workspace_on_reset_graph_layout_clicked
|
||
),
|
||
workspace
|
||
);
|
||
|
||
gtk_box_append(
|
||
GTK_BOX(
|
||
workspace->graph_toolbar
|
||
),
|
||
workspace->reset_graph_layout_button
|
||
);
|
||
|
||
gtk_overlay_add_overlay(
|
||
GTK_OVERLAY(
|
||
workspace->graph_view_page
|
||
),
|
||
workspace->graph_toolbar
|
||
);
|
||
|
||
gtk_overlay_set_clip_overlay(
|
||
GTK_OVERLAY(
|
||
workspace->graph_view_page
|
||
),
|
||
workspace->graph_toolbar,
|
||
TRUE
|
||
);
|
||
|
||
gtk_overlay_add_overlay(
|
||
GTK_OVERLAY(
|
||
workspace->graph_view_page
|
||
),
|
||
entity_details_panel_get_widget(
|
||
workspace->entity_details_panel
|
||
)
|
||
);
|
||
|
||
gtk_overlay_set_clip_overlay(
|
||
GTK_OVERLAY(
|
||
workspace->graph_view_page
|
||
),
|
||
entity_details_panel_get_widget(
|
||
workspace->entity_details_panel
|
||
),
|
||
TRUE
|
||
);
|
||
|
||
gtk_stack_add_named(
|
||
GTK_STACK(workspace->stack),
|
||
workspace->graph_view_page,
|
||
WORKSPACE_PAGE_GRAPH_VIEW
|
||
);
|
||
|
||
workspace->graph_model =
|
||
NULL;
|
||
|
||
workspace->graph_layout =
|
||
NULL;
|
||
|
||
workspace->graph_state =
|
||
WORKSPACE_GRAPH_STATE_EMPTY;
|
||
|
||
workspace_show_default(
|
||
workspace
|
||
);
|
||
|
||
return workspace;
|
||
}
|
||
|
||
GtkWidget *workspace_get_widget(
|
||
const Workspace *workspace
|
||
)
|
||
{
|
||
if (workspace == NULL)
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
return workspace->root_widget;
|
||
}
|
||
|
||
void workspace_set_selected_node(
|
||
Workspace *workspace,
|
||
const InvestigationNode *node
|
||
)
|
||
{
|
||
const char *node_name = NULL;
|
||
const InvestigationNode *parent_node = NULL;
|
||
const char *parent_name = NULL;
|
||
const char *node_path = NULL;
|
||
InvestigationNodeType node_type;
|
||
size_t children_count = 0;
|
||
|
||
const char *type_text = NULL;
|
||
char *parent_text = NULL;
|
||
char *children_text = NULL;
|
||
|
||
if (workspace == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
g_clear_pointer(
|
||
&workspace->selected_evidence_identifier,
|
||
g_free
|
||
);
|
||
|
||
if (workspace->verify_evidence_button != NULL)
|
||
{
|
||
gtk_widget_set_sensitive(
|
||
workspace->verify_evidence_button,
|
||
FALSE
|
||
);
|
||
}
|
||
|
||
if (node == NULL)
|
||
{
|
||
workspace_show_default(workspace);
|
||
return;
|
||
}
|
||
|
||
node_name = investigation_node_get_name(node);
|
||
node_path = investigation_node_get_path(node);
|
||
node_type = investigation_node_get_type(node);
|
||
parent_node = investigation_node_get_parent(node);
|
||
|
||
gtk_label_set_text(
|
||
GTK_LABEL(workspace->node_name_label),
|
||
node_name != NULL ? node_name : "(sans nom)"
|
||
);
|
||
|
||
gtk_label_set_text(
|
||
GTK_LABEL(workspace->node_path_label),
|
||
node_path != NULL ? node_path : "(chemin indisponible)"
|
||
);
|
||
|
||
if (node_type == INVESTIGATION_NODE_DIRECTORY)
|
||
{
|
||
type_text = "Type : dossier";
|
||
}
|
||
else
|
||
{
|
||
type_text = "Type : fichier";
|
||
}
|
||
|
||
gtk_label_set_text(
|
||
GTK_LABEL(workspace->node_type_label),
|
||
type_text
|
||
);
|
||
|
||
if (parent_node != NULL)
|
||
{
|
||
parent_name = investigation_node_get_name(parent_node);
|
||
|
||
parent_text = g_strdup_printf(
|
||
"Parent : %s",
|
||
parent_name != NULL ? parent_name : "(sans nom)"
|
||
);
|
||
}
|
||
else
|
||
{
|
||
parent_text = g_strdup("Parent : aucun");
|
||
}
|
||
|
||
gtk_label_set_text(
|
||
GTK_LABEL(workspace->node_parent_label),
|
||
parent_text
|
||
);
|
||
|
||
if (node_type == INVESTIGATION_NODE_DIRECTORY)
|
||
{
|
||
children_count =
|
||
investigation_node_get_children_count(node);
|
||
|
||
children_text = g_strdup_printf(
|
||
"Enfants : %zu",
|
||
children_count
|
||
);
|
||
|
||
gtk_label_set_text(
|
||
GTK_LABEL(workspace->node_children_label),
|
||
children_text
|
||
);
|
||
|
||
gtk_widget_set_visible(
|
||
workspace->node_children_label,
|
||
TRUE
|
||
);
|
||
}
|
||
else
|
||
{
|
||
gtk_label_set_text(
|
||
GTK_LABEL(workspace->node_children_label),
|
||
""
|
||
);
|
||
|
||
gtk_widget_set_visible(
|
||
workspace->node_children_label,
|
||
FALSE
|
||
);
|
||
}
|
||
|
||
gtk_stack_set_visible_child_name(
|
||
GTK_STACK(workspace->stack),
|
||
WORKSPACE_PAGE_NODE_INFORMATION
|
||
);
|
||
|
||
g_free(children_text);
|
||
g_free(parent_text);
|
||
}
|
||
|
||
void workspace_set_selected_evidence(
|
||
Workspace *workspace,
|
||
const EvidenceRecord *evidence_record
|
||
)
|
||
{
|
||
char *human_size = NULL;
|
||
char *size_text = NULL;
|
||
|
||
guint64 size_bytes = 0;
|
||
|
||
if (workspace == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
g_clear_pointer(
|
||
&workspace->selected_evidence_identifier,
|
||
g_free
|
||
);
|
||
|
||
if (workspace->verify_evidence_button != NULL)
|
||
{
|
||
gtk_widget_set_sensitive(
|
||
workspace->verify_evidence_button,
|
||
FALSE
|
||
);
|
||
}
|
||
|
||
if (evidence_record == NULL)
|
||
{
|
||
workspace_show_default(
|
||
workspace
|
||
);
|
||
|
||
return;
|
||
}
|
||
|
||
workspace->selected_evidence_identifier =
|
||
g_strdup(
|
||
evidence_record_get_identifier(
|
||
evidence_record
|
||
)
|
||
);
|
||
|
||
if (workspace->selected_evidence_identifier == NULL)
|
||
{
|
||
workspace_show_default(
|
||
workspace
|
||
);
|
||
|
||
return;
|
||
}
|
||
|
||
gtk_widget_set_sensitive(
|
||
workspace->verify_evidence_button,
|
||
TRUE
|
||
);
|
||
|
||
size_bytes =
|
||
evidence_record_get_size_bytes(
|
||
evidence_record
|
||
);
|
||
|
||
human_size =
|
||
g_format_size_full(
|
||
size_bytes,
|
||
G_FORMAT_SIZE_IEC_UNITS
|
||
);
|
||
|
||
size_text =
|
||
g_strdup_printf(
|
||
"%s (%" G_GUINT64_FORMAT " octets)",
|
||
human_size != NULL
|
||
? human_size
|
||
: "taille inconnue",
|
||
size_bytes
|
||
);
|
||
|
||
workspace_set_field_text(
|
||
workspace->evidence_name_label,
|
||
evidence_record_get_original_name(
|
||
evidence_record
|
||
),
|
||
"(sans nom)"
|
||
);
|
||
|
||
workspace_set_field_text(
|
||
workspace->evidence_type_label,
|
||
evidence_record_get_type_identifier(
|
||
evidence_record
|
||
),
|
||
"(type inconnu)"
|
||
);
|
||
|
||
workspace_set_field_text(
|
||
workspace->evidence_integrity_label,
|
||
workspace_get_integrity_status_text(
|
||
evidence_record_get_integrity_status(
|
||
evidence_record
|
||
)
|
||
),
|
||
"Statut inconnu"
|
||
);
|
||
|
||
workspace_set_field_text(
|
||
workspace->evidence_size_label,
|
||
size_text,
|
||
"Taille inconnue"
|
||
);
|
||
|
||
workspace_set_field_text(
|
||
workspace->evidence_imported_at_label,
|
||
evidence_record_get_imported_at(
|
||
evidence_record
|
||
),
|
||
"(date inconnue)"
|
||
);
|
||
|
||
workspace_set_field_text(
|
||
workspace->evidence_collected_at_label,
|
||
evidence_record_get_collected_at(
|
||
evidence_record
|
||
),
|
||
"Non renseignée"
|
||
);
|
||
|
||
workspace_set_field_text(
|
||
workspace->evidence_source_label,
|
||
evidence_record_get_source(
|
||
evidence_record
|
||
),
|
||
"Non renseignée"
|
||
);
|
||
|
||
workspace_set_field_text(
|
||
workspace->evidence_description_label,
|
||
evidence_record_get_description(
|
||
evidence_record
|
||
),
|
||
"Non renseignée"
|
||
);
|
||
|
||
workspace_set_field_text(
|
||
workspace->evidence_relative_path_label,
|
||
evidence_record_get_relative_path(
|
||
evidence_record
|
||
),
|
||
"(chemin inconnu)"
|
||
);
|
||
|
||
workspace_set_field_text(
|
||
workspace->evidence_internal_name_label,
|
||
evidence_record_get_internal_name(
|
||
evidence_record
|
||
),
|
||
"(nom interne inconnu)"
|
||
);
|
||
|
||
workspace_set_field_text(
|
||
workspace->evidence_identifier_label,
|
||
evidence_record_get_identifier(
|
||
evidence_record
|
||
),
|
||
"(identifiant inconnu)"
|
||
);
|
||
|
||
workspace_set_field_text(
|
||
workspace->evidence_sha256_label,
|
||
evidence_record_get_sha256(
|
||
evidence_record
|
||
),
|
||
"(empreinte inconnue)"
|
||
);
|
||
|
||
gtk_stack_set_visible_child_name(
|
||
GTK_STACK(workspace->stack),
|
||
WORKSPACE_PAGE_EVIDENCE_INFORMATION
|
||
);
|
||
|
||
g_free(
|
||
size_text
|
||
);
|
||
|
||
g_free(
|
||
human_size
|
||
);
|
||
}
|
||
|
||
void workspace_set_graph_loading(
|
||
Workspace *workspace
|
||
)
|
||
{
|
||
if (workspace == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
g_clear_pointer(
|
||
&workspace->selected_evidence_identifier,
|
||
g_free
|
||
);
|
||
|
||
if (workspace->verify_evidence_button != NULL)
|
||
{
|
||
gtk_widget_set_sensitive(
|
||
workspace->verify_evidence_button,
|
||
FALSE
|
||
);
|
||
}
|
||
|
||
entity_details_panel_clear(
|
||
workspace->entity_details_panel
|
||
);
|
||
|
||
investigation_graph_view_clear(
|
||
workspace->graph_view
|
||
);
|
||
|
||
workspace->graph_model =
|
||
NULL;
|
||
|
||
workspace->graph_layout =
|
||
NULL;
|
||
|
||
workspace->graph_state =
|
||
WORKSPACE_GRAPH_STATE_LOADING;
|
||
|
||
gtk_widget_set_sensitive(
|
||
workspace->reset_graph_layout_button,
|
||
FALSE
|
||
);
|
||
|
||
gtk_label_set_text(
|
||
GTK_LABEL(
|
||
workspace->graph_title_label
|
||
),
|
||
"Chargement de l’enquête…"
|
||
);
|
||
|
||
gtk_label_set_text(
|
||
GTK_LABEL(
|
||
workspace->graph_details_label
|
||
),
|
||
"Lecture des entités et des relations"
|
||
);
|
||
|
||
gtk_widget_set_visible(
|
||
workspace->graph_spinner,
|
||
TRUE
|
||
);
|
||
|
||
gtk_spinner_start(
|
||
GTK_SPINNER(
|
||
workspace->graph_spinner
|
||
)
|
||
);
|
||
|
||
workspace_show_default(
|
||
workspace
|
||
);
|
||
}
|
||
|
||
void workspace_set_graph(
|
||
Workspace *workspace,
|
||
const InvestigationGraphModel *graph_model,
|
||
const InvestigationGraphLayout *graph_layout
|
||
)
|
||
{
|
||
if (workspace == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (graph_model == NULL)
|
||
{
|
||
workspace_clear_graph(
|
||
workspace
|
||
);
|
||
|
||
return;
|
||
}
|
||
|
||
g_clear_pointer(
|
||
&workspace->selected_evidence_identifier,
|
||
g_free
|
||
);
|
||
|
||
if (workspace->verify_evidence_button != NULL)
|
||
{
|
||
gtk_widget_set_sensitive(
|
||
workspace->verify_evidence_button,
|
||
FALSE
|
||
);
|
||
}
|
||
|
||
entity_details_panel_clear(
|
||
workspace->entity_details_panel
|
||
);
|
||
|
||
investigation_graph_view_clear(
|
||
workspace->graph_view
|
||
);
|
||
|
||
workspace->graph_model =
|
||
graph_model;
|
||
|
||
workspace->graph_layout =
|
||
graph_layout;
|
||
|
||
investigation_graph_view_set_layout(
|
||
workspace->graph_view,
|
||
graph_layout
|
||
);
|
||
|
||
investigation_graph_view_set_graph(
|
||
workspace->graph_view,
|
||
graph_model
|
||
);
|
||
|
||
workspace->graph_state =
|
||
WORKSPACE_GRAPH_STATE_READY;
|
||
|
||
gtk_widget_set_sensitive(
|
||
workspace->reset_graph_layout_button,
|
||
TRUE
|
||
);
|
||
|
||
gtk_spinner_stop(
|
||
GTK_SPINNER(
|
||
workspace->graph_spinner
|
||
)
|
||
);
|
||
|
||
gtk_widget_set_visible(
|
||
workspace->graph_spinner,
|
||
FALSE
|
||
);
|
||
|
||
gtk_label_set_text(
|
||
GTK_LABEL(
|
||
workspace->graph_title_label
|
||
),
|
||
""
|
||
);
|
||
|
||
gtk_label_set_text(
|
||
GTK_LABEL(
|
||
workspace->graph_details_label
|
||
),
|
||
""
|
||
);
|
||
|
||
workspace_show_default(
|
||
workspace
|
||
);
|
||
}
|
||
|
||
void workspace_set_graph_error(
|
||
Workspace *workspace,
|
||
const char *message
|
||
)
|
||
{
|
||
if (workspace == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
g_clear_pointer(
|
||
&workspace->selected_evidence_identifier,
|
||
g_free
|
||
);
|
||
|
||
if (workspace->verify_evidence_button != NULL)
|
||
{
|
||
gtk_widget_set_sensitive(
|
||
workspace->verify_evidence_button,
|
||
FALSE
|
||
);
|
||
}
|
||
|
||
entity_details_panel_clear(
|
||
workspace->entity_details_panel
|
||
);
|
||
|
||
investigation_graph_view_clear(
|
||
workspace->graph_view
|
||
);
|
||
|
||
workspace->graph_model =
|
||
NULL;
|
||
|
||
workspace->graph_layout =
|
||
NULL;
|
||
|
||
workspace->graph_state =
|
||
WORKSPACE_GRAPH_STATE_ERROR;
|
||
|
||
gtk_widget_set_sensitive(
|
||
workspace->reset_graph_layout_button,
|
||
FALSE
|
||
);
|
||
|
||
gtk_spinner_stop(
|
||
GTK_SPINNER(
|
||
workspace->graph_spinner
|
||
)
|
||
);
|
||
|
||
gtk_widget_set_visible(
|
||
workspace->graph_spinner,
|
||
FALSE
|
||
);
|
||
|
||
gtk_label_set_text(
|
||
GTK_LABEL(
|
||
workspace->graph_title_label
|
||
),
|
||
"Impossible de charger le graphe de l’enquête"
|
||
);
|
||
|
||
gtk_label_set_text(
|
||
GTK_LABEL(
|
||
workspace->graph_details_label
|
||
),
|
||
message != NULL &&
|
||
message[0] != '\0'
|
||
? message
|
||
: "Aucun détail supplémentaire n’est disponible."
|
||
);
|
||
|
||
workspace_show_default(
|
||
workspace
|
||
);
|
||
}
|
||
|
||
void workspace_clear_graph(
|
||
Workspace *workspace
|
||
)
|
||
{
|
||
if (workspace == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
g_clear_pointer(
|
||
&workspace->selected_evidence_identifier,
|
||
g_free
|
||
);
|
||
|
||
if (workspace->verify_evidence_button != NULL)
|
||
{
|
||
gtk_widget_set_sensitive(
|
||
workspace->verify_evidence_button,
|
||
FALSE
|
||
);
|
||
}
|
||
|
||
entity_details_panel_clear(
|
||
workspace->entity_details_panel
|
||
);
|
||
|
||
investigation_graph_view_clear(
|
||
workspace->graph_view
|
||
);
|
||
|
||
workspace->graph_model =
|
||
NULL;
|
||
|
||
workspace->graph_layout =
|
||
NULL;
|
||
|
||
workspace->graph_state =
|
||
WORKSPACE_GRAPH_STATE_EMPTY;
|
||
|
||
gtk_widget_set_sensitive(
|
||
workspace->reset_graph_layout_button,
|
||
FALSE
|
||
);
|
||
|
||
gtk_spinner_stop(
|
||
GTK_SPINNER(
|
||
workspace->graph_spinner
|
||
)
|
||
);
|
||
|
||
gtk_widget_set_visible(
|
||
workspace->graph_spinner,
|
||
FALSE
|
||
);
|
||
|
||
gtk_label_set_text(
|
||
GTK_LABEL(
|
||
workspace->graph_title_label
|
||
),
|
||
""
|
||
);
|
||
|
||
gtk_label_set_text(
|
||
GTK_LABEL(
|
||
workspace->graph_details_label
|
||
),
|
||
""
|
||
);
|
||
|
||
workspace_show_default(
|
||
workspace
|
||
);
|
||
}
|
||
|
||
void workspace_set_verify_evidence_callback(
|
||
Workspace *workspace,
|
||
WorkspaceVerifyEvidenceCallback callback,
|
||
gpointer user_data
|
||
)
|
||
{
|
||
if (workspace == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
workspace->verify_evidence_callback =
|
||
callback;
|
||
|
||
workspace->verify_evidence_user_data =
|
||
user_data;
|
||
}
|
||
|
||
void workspace_set_graph_node_moved_callback(
|
||
Workspace *workspace,
|
||
WorkspaceGraphNodeMovedCallback callback,
|
||
gpointer user_data
|
||
)
|
||
{
|
||
if (workspace == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
workspace->graph_node_moved_callback =
|
||
callback;
|
||
|
||
workspace->graph_node_moved_user_data =
|
||
user_data;
|
||
}
|
||
|
||
void workspace_set_reset_graph_layout_callback(
|
||
Workspace *workspace,
|
||
WorkspaceResetGraphLayoutCallback callback,
|
||
gpointer user_data
|
||
)
|
||
{
|
||
if (workspace == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
workspace->reset_graph_layout_callback =
|
||
callback;
|
||
|
||
workspace->reset_graph_layout_user_data =
|
||
user_data;
|
||
}
|
||
|
||
void workspace_reset_graph_layout(
|
||
Workspace *workspace
|
||
)
|
||
{
|
||
if (workspace == NULL ||
|
||
workspace->graph_view == NULL ||
|
||
workspace->graph_state != WORKSPACE_GRAPH_STATE_READY ||
|
||
workspace->graph_model == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
entity_details_panel_clear(
|
||
workspace->entity_details_panel
|
||
);
|
||
|
||
investigation_graph_view_clear_selection(
|
||
workspace->graph_view
|
||
);
|
||
|
||
investigation_graph_view_reset_layout(
|
||
workspace->graph_view
|
||
);
|
||
}
|
||
|
||
void workspace_free(Workspace *workspace)
|
||
{
|
||
if (workspace == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
investigation_graph_view_set_selection_callback(
|
||
workspace->graph_view,
|
||
NULL,
|
||
NULL
|
||
);
|
||
|
||
investigation_graph_view_set_node_moved_callback(
|
||
workspace->graph_view,
|
||
NULL,
|
||
NULL
|
||
);
|
||
|
||
entity_details_panel_set_close_callback(
|
||
workspace->entity_details_panel,
|
||
NULL,
|
||
NULL
|
||
);
|
||
|
||
entity_details_panel_clear(
|
||
workspace->entity_details_panel
|
||
);
|
||
|
||
investigation_graph_view_clear(
|
||
workspace->graph_view
|
||
);
|
||
|
||
investigation_graph_view_free(
|
||
workspace->graph_view
|
||
);
|
||
|
||
entity_details_panel_free(
|
||
workspace->entity_details_panel
|
||
);
|
||
|
||
workspace->graph_view =
|
||
NULL;
|
||
|
||
workspace->entity_details_panel =
|
||
NULL;
|
||
|
||
workspace->graph_model =
|
||
NULL;
|
||
|
||
workspace->graph_layout =
|
||
NULL;
|
||
|
||
workspace->verify_evidence_callback =
|
||
NULL;
|
||
|
||
workspace->verify_evidence_user_data =
|
||
NULL;
|
||
|
||
workspace->graph_node_moved_callback =
|
||
NULL;
|
||
|
||
workspace->graph_node_moved_user_data =
|
||
NULL;
|
||
|
||
workspace->reset_graph_layout_callback =
|
||
NULL;
|
||
|
||
workspace->reset_graph_layout_user_data =
|
||
NULL;
|
||
|
||
workspace->graph_toolbar =
|
||
NULL;
|
||
|
||
workspace->reset_graph_layout_button =
|
||
NULL;
|
||
|
||
g_clear_pointer(
|
||
&workspace->selected_evidence_identifier,
|
||
g_free
|
||
);
|
||
|
||
g_free(workspace);
|
||
}
|