feat: add read-only investigation graph view
This commit is contained in:
parent
fb44188e01
commit
13a391b449
3 changed files with 1838 additions and 40 deletions
83
include/widgets/investigation_graph_view.h
Normal file
83
include/widgets/investigation_graph_view.h
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* @file investigation_graph_view.h
|
||||||
|
* @brief Vue GTK en lecture seule du graphe d'enquête.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef LABFY_INVESTIGATION_INVESTIGATION_GRAPH_VIEW_H
|
||||||
|
#define LABFY_INVESTIGATION_INVESTIGATION_GRAPH_VIEW_H
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Représentation opaque du graphe métier d'une enquête.
|
||||||
|
*/
|
||||||
|
typedef struct InvestigationGraphModel InvestigationGraphModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Représentation opaque de la vue graphique.
|
||||||
|
*/
|
||||||
|
typedef struct InvestigationGraphView InvestigationGraphView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Crée une nouvelle vue graphique vide.
|
||||||
|
*
|
||||||
|
* La vue ne possède jamais le graphe qui lui est transmis.
|
||||||
|
*
|
||||||
|
* @return Nouvelle vue graphique, ou NULL en cas d'échec.
|
||||||
|
*/
|
||||||
|
InvestigationGraphView *investigation_graph_view_new(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retourne le widget GTK racine de la vue.
|
||||||
|
*
|
||||||
|
* Le widget appartient à InvestigationGraphView.
|
||||||
|
*
|
||||||
|
* @param graph_view Vue graphique à consulter.
|
||||||
|
*
|
||||||
|
* @return Widget GTK racine, ou NULL.
|
||||||
|
*/
|
||||||
|
GtkWidget *investigation_graph_view_get_widget(
|
||||||
|
const InvestigationGraphView *graph_view
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Associe un graphe métier à la vue.
|
||||||
|
*
|
||||||
|
* Le graphe est emprunté et doit rester valide pendant son affichage.
|
||||||
|
* Passer NULL équivaut à investigation_graph_view_clear().
|
||||||
|
*
|
||||||
|
* @param graph_view Vue graphique à mettre à jour.
|
||||||
|
* @param graph_model Graphe emprunté, ou NULL.
|
||||||
|
*/
|
||||||
|
void investigation_graph_view_set_graph(
|
||||||
|
InvestigationGraphView *graph_view,
|
||||||
|
const InvestigationGraphModel *graph_model
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Détache le graphe actuellement affiché.
|
||||||
|
*
|
||||||
|
* Le graphe précédemment emprunté n'est pas libéré.
|
||||||
|
*
|
||||||
|
* @param graph_view Vue graphique à vider.
|
||||||
|
*/
|
||||||
|
void investigation_graph_view_clear(
|
||||||
|
InvestigationGraphView *graph_view
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Libère la structure d'encapsulation de la vue.
|
||||||
|
*
|
||||||
|
* Cette fonction accepte NULL et ne libère jamais le graphe emprunté.
|
||||||
|
*
|
||||||
|
* @param graph_view Vue graphique à libérer.
|
||||||
|
*/
|
||||||
|
void investigation_graph_view_free(
|
||||||
|
InvestigationGraphView *graph_view
|
||||||
|
);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif
|
||||||
1669
src/widgets/investigation_graph_view.c
Normal file
1669
src/widgets/investigation_graph_view.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include "widgets/workspace.h"
|
#include "widgets/workspace.h"
|
||||||
|
|
||||||
#include "models/investigation_graph_model.h"
|
#include "widgets/investigation_graph_view.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
|
|
@ -15,6 +15,8 @@
|
||||||
"evidence-information"
|
"evidence-information"
|
||||||
#define WORKSPACE_PAGE_GRAPH_STATE \
|
#define WORKSPACE_PAGE_GRAPH_STATE \
|
||||||
"graph-state"
|
"graph-state"
|
||||||
|
#define WORKSPACE_PAGE_GRAPH_VIEW \
|
||||||
|
"graph-view"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief État métier représenté par la page du graphe.
|
* @brief État métier représenté par la page du graphe.
|
||||||
|
|
@ -43,6 +45,8 @@ struct Workspace
|
||||||
GtkWidget *graph_title_label;
|
GtkWidget *graph_title_label;
|
||||||
GtkWidget *graph_details_label;
|
GtkWidget *graph_details_label;
|
||||||
|
|
||||||
|
InvestigationGraphView *graph_view;
|
||||||
|
|
||||||
GtkWidget *node_page;
|
GtkWidget *node_page;
|
||||||
|
|
||||||
GtkWidget *evidence_page;
|
GtkWidget *evidence_page;
|
||||||
|
|
@ -249,8 +253,8 @@ static const char *workspace_get_integrity_status_text(
|
||||||
/**
|
/**
|
||||||
* @brief Affiche l'état principal courant du Workspace.
|
* @brief Affiche l'état principal courant du Workspace.
|
||||||
*
|
*
|
||||||
* Sans enquête, la page d'accueil est utilisée. Lorsqu'un chargement, un
|
* Sans enquête, la page d'accueil est utilisée. Le chargement et les erreurs
|
||||||
* graphe ou une erreur existe, la page d'état du graphe est affichée.
|
* utilisent la page d'état. Un graphe prêt utilise la vue graphique.
|
||||||
*/
|
*/
|
||||||
static void workspace_show_default(
|
static void workspace_show_default(
|
||||||
Workspace *workspace
|
Workspace *workspace
|
||||||
|
|
@ -261,21 +265,34 @@ static void workspace_show_default(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (workspace->graph_state ==
|
switch (workspace->graph_state)
|
||||||
WORKSPACE_GRAPH_STATE_EMPTY)
|
|
||||||
{
|
{
|
||||||
|
case WORKSPACE_GRAPH_STATE_EMPTY:
|
||||||
gtk_stack_set_visible_child_name(
|
gtk_stack_set_visible_child_name(
|
||||||
GTK_STACK(workspace->stack),
|
GTK_STACK(workspace->stack),
|
||||||
WORKSPACE_PAGE_WELCOME
|
WORKSPACE_PAGE_WELCOME
|
||||||
);
|
);
|
||||||
|
|
||||||
return;
|
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_set_visible_child_name(
|
||||||
GTK_STACK(workspace->stack),
|
GTK_STACK(workspace->stack),
|
||||||
WORKSPACE_PAGE_GRAPH_STATE
|
WORKSPACE_PAGE_GRAPH_STATE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -776,8 +793,7 @@ Workspace *workspace_new(void)
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Page temporaire de chargement et de résumé du graphe.
|
* Page d'état utilisée pendant le chargement ou en cas d'erreur.
|
||||||
* Le futur canvas interactif remplacera cette représentation.
|
|
||||||
*/
|
*/
|
||||||
workspace->graph_state_page =
|
workspace->graph_state_page =
|
||||||
gtk_box_new(
|
gtk_box_new(
|
||||||
|
|
@ -879,6 +895,29 @@ Workspace *workspace_new(void)
|
||||||
WORKSPACE_PAGE_GRAPH_STATE
|
WORKSPACE_PAGE_GRAPH_STATE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Vue graphique en lecture seule.
|
||||||
|
*/
|
||||||
|
workspace->graph_view =
|
||||||
|
investigation_graph_view_new();
|
||||||
|
|
||||||
|
if (workspace->graph_view == NULL)
|
||||||
|
{
|
||||||
|
workspace_free(
|
||||||
|
workspace
|
||||||
|
);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_stack_add_named(
|
||||||
|
GTK_STACK(workspace->stack),
|
||||||
|
investigation_graph_view_get_widget(
|
||||||
|
workspace->graph_view
|
||||||
|
),
|
||||||
|
WORKSPACE_PAGE_GRAPH_VIEW
|
||||||
|
);
|
||||||
|
|
||||||
workspace->graph_model =
|
workspace->graph_model =
|
||||||
NULL;
|
NULL;
|
||||||
|
|
||||||
|
|
@ -1244,6 +1283,10 @@ void workspace_set_graph_loading(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
investigation_graph_view_clear(
|
||||||
|
workspace->graph_view
|
||||||
|
);
|
||||||
|
|
||||||
workspace->graph_model =
|
workspace->graph_model =
|
||||||
NULL;
|
NULL;
|
||||||
|
|
||||||
|
|
@ -1285,9 +1328,6 @@ void workspace_set_graph(
|
||||||
const InvestigationGraphModel *graph_model
|
const InvestigationGraphModel *graph_model
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
char *summary_text =
|
|
||||||
NULL;
|
|
||||||
|
|
||||||
if (workspace == NULL)
|
if (workspace == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
@ -1318,6 +1358,11 @@ void workspace_set_graph(
|
||||||
workspace->graph_model =
|
workspace->graph_model =
|
||||||
graph_model;
|
graph_model;
|
||||||
|
|
||||||
|
investigation_graph_view_set_graph(
|
||||||
|
workspace->graph_view,
|
||||||
|
graph_model
|
||||||
|
);
|
||||||
|
|
||||||
workspace->graph_state =
|
workspace->graph_state =
|
||||||
WORKSPACE_GRAPH_STATE_READY;
|
WORKSPACE_GRAPH_STATE_READY;
|
||||||
|
|
||||||
|
|
@ -1336,32 +1381,14 @@ void workspace_set_graph(
|
||||||
GTK_LABEL(
|
GTK_LABEL(
|
||||||
workspace->graph_title_label
|
workspace->graph_title_label
|
||||||
),
|
),
|
||||||
"Graphe chargé"
|
""
|
||||||
);
|
|
||||||
|
|
||||||
summary_text =
|
|
||||||
g_strdup_printf(
|
|
||||||
"%" G_GUINT64_FORMAT " entité(s)\n"
|
|
||||||
"%" G_GUINT64_FORMAT " relation(s)",
|
|
||||||
investigation_graph_model_get_entity_count(
|
|
||||||
graph_model
|
|
||||||
),
|
|
||||||
investigation_graph_model_get_relation_count(
|
|
||||||
graph_model
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
gtk_label_set_text(
|
gtk_label_set_text(
|
||||||
GTK_LABEL(
|
GTK_LABEL(
|
||||||
workspace->graph_details_label
|
workspace->graph_details_label
|
||||||
),
|
),
|
||||||
summary_text != NULL
|
""
|
||||||
? summary_text
|
|
||||||
: "Résumé indisponible"
|
|
||||||
);
|
|
||||||
|
|
||||||
g_free(
|
|
||||||
summary_text
|
|
||||||
);
|
);
|
||||||
|
|
||||||
workspace_show_default(
|
workspace_show_default(
|
||||||
|
|
@ -1392,6 +1419,10 @@ void workspace_set_graph_error(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
investigation_graph_view_clear(
|
||||||
|
workspace->graph_view
|
||||||
|
);
|
||||||
|
|
||||||
workspace->graph_model =
|
workspace->graph_model =
|
||||||
NULL;
|
NULL;
|
||||||
|
|
||||||
|
|
@ -1453,6 +1484,10 @@ void workspace_clear_graph(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
investigation_graph_view_clear(
|
||||||
|
workspace->graph_view
|
||||||
|
);
|
||||||
|
|
||||||
workspace->graph_model =
|
workspace->graph_model =
|
||||||
NULL;
|
NULL;
|
||||||
|
|
||||||
|
|
@ -1514,6 +1549,17 @@ void workspace_free(Workspace *workspace)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
investigation_graph_view_clear(
|
||||||
|
workspace->graph_view
|
||||||
|
);
|
||||||
|
|
||||||
|
investigation_graph_view_free(
|
||||||
|
workspace->graph_view
|
||||||
|
);
|
||||||
|
|
||||||
|
workspace->graph_view =
|
||||||
|
NULL;
|
||||||
|
|
||||||
workspace->graph_model =
|
workspace->graph_model =
|
||||||
NULL;
|
NULL;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue