Compare commits
2 commits
0f67118f5b
...
ff512593da
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff512593da | ||
|
|
0069e99529 |
6 changed files with 1009 additions and 7 deletions
|
|
@ -18,6 +18,20 @@ typedef enum
|
|||
APPLICATION_MESSAGE_DIALOG_INFORMATION
|
||||
} ApplicationMessageDialogType;
|
||||
|
||||
/**
|
||||
* @brief Callback appelé à la fermeture d'un dialogue de confirmation.
|
||||
*
|
||||
* Le callback est appelé une seule fois après un clic sur l'un des boutons
|
||||
* ou après une fermeture manuelle de la fenêtre.
|
||||
*
|
||||
* @param confirmed TRUE si l'utilisateur confirme, sinon FALSE.
|
||||
* @param user_data Données empruntées fournies par l'appelant.
|
||||
*/
|
||||
typedef void (*ApplicationMessageDialogConfirmationCallback)(
|
||||
gboolean confirmed,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Affiche une fenêtre modale contenant un message.
|
||||
*
|
||||
|
|
@ -35,4 +49,31 @@ void application_message_dialog_present(
|
|||
const char *message
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Affiche un dialogue modal demandant une confirmation.
|
||||
*
|
||||
* Le bouton d'annulation transmet FALSE. Le bouton de confirmation transmet
|
||||
* TRUE. Fermer la fenêtre manuellement équivaut à une annulation.
|
||||
*
|
||||
* callback et user_data sont empruntés jusqu'à la fermeture du dialogue.
|
||||
* confirm_label peut être NULL ou vide pour utiliser « Confirmer ».
|
||||
*
|
||||
* @param parent_window Fenêtre parente, ou NULL.
|
||||
* @param message_type Type de message.
|
||||
* @param title Titre de la fenêtre, ou NULL.
|
||||
* @param message Message principal, ou NULL.
|
||||
* @param confirm_label Libellé du bouton de confirmation, ou NULL.
|
||||
* @param callback Callback facultatif recevant la réponse.
|
||||
* @param user_data Données empruntées transmises au callback.
|
||||
*/
|
||||
void application_message_dialog_present_confirmation(
|
||||
GtkWindow *parent_window,
|
||||
ApplicationMessageDialogType message_type,
|
||||
const char *title,
|
||||
const char *message,
|
||||
const char *confirm_label,
|
||||
ApplicationMessageDialogConfirmationCallback callback,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -49,6 +49,15 @@ typedef void (*MainWindowImportEvidenceCallback)(
|
|||
gpointer user_data
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Callback appelé lorsque l'utilisateur revient au graphe.
|
||||
*
|
||||
* @param user_data Données utilisateur associées au callback.
|
||||
*/
|
||||
typedef void (*MainWindowShowGraphCallback)(
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Callback appelé lorsqu'une preuve est sélectionnée.
|
||||
*
|
||||
|
|
@ -432,6 +441,21 @@ void main_window_set_import_evidence_callback(
|
|||
gpointer user_data
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Définit le callback du bouton « Revenir au graphe ».
|
||||
*
|
||||
* MainWindow transmet uniquement la demande au contrôleur.
|
||||
*
|
||||
* @param main_window Fenêtre principale.
|
||||
* @param callback Fonction appelée lors du clic, ou NULL.
|
||||
* @param user_data Données transmises au callback.
|
||||
*/
|
||||
void main_window_set_show_graph_callback(
|
||||
MainWindow *main_window,
|
||||
MainWindowShowGraphCallback callback,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Active ou désactive l'action d'import d'une preuve.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -4278,17 +4278,15 @@ static void application_on_graph_node_moved(
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Ferme proprement l'application.
|
||||
* @brief Supprime les positions persistées et restaure la grille automatique.
|
||||
*
|
||||
* @param user_data Pointeur vers Application.
|
||||
* Cette fonction est appelée uniquement après une confirmation explicite.
|
||||
* L'affichage et le modèle en mémoire restent inchangés en cas d'échec SQLite.
|
||||
*/
|
||||
static void application_on_reset_graph_layout_requested(
|
||||
gpointer user_data
|
||||
static void application_reset_graph_layout(
|
||||
Application *application
|
||||
)
|
||||
{
|
||||
Application *application =
|
||||
user_data;
|
||||
|
||||
Database *database =
|
||||
NULL;
|
||||
|
||||
|
|
@ -4402,6 +4400,98 @@ static void application_on_reset_graph_layout_requested(
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Traite la réponse du dialogue de confirmation.
|
||||
*/
|
||||
static void application_on_reset_graph_layout_confirmed(
|
||||
gboolean confirmed,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
Application *application =
|
||||
user_data;
|
||||
|
||||
if (!confirmed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
application_reset_graph_layout(
|
||||
application
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Demande confirmation avant toute suppression de position.
|
||||
*/
|
||||
static void application_on_show_graph_requested(
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
Application *application =
|
||||
user_data;
|
||||
|
||||
if (application == NULL ||
|
||||
application->main_window == NULL ||
|
||||
application->graph_model == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
application_set_selected_evidence_identifier(
|
||||
application,
|
||||
NULL
|
||||
);
|
||||
|
||||
/*
|
||||
* Passer NULL restaure l'état principal du Workspace. Quand le graphe
|
||||
* est prêt, workspace_show_default() affiche automatiquement le canvas.
|
||||
*/
|
||||
main_window_set_selected_evidence(
|
||||
application->main_window,
|
||||
NULL
|
||||
);
|
||||
|
||||
main_window_set_status(
|
||||
application->main_window,
|
||||
"Graphe de l'enquête affiché."
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Demande confirmation avant toute suppression de position.
|
||||
*/
|
||||
static void application_on_reset_graph_layout_requested(
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
Application *application =
|
||||
user_data;
|
||||
|
||||
if (application == NULL ||
|
||||
application->main_window == NULL ||
|
||||
application->session == NULL ||
|
||||
application->graph_model == NULL ||
|
||||
application->graph_layout == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
application_message_dialog_present_confirmation(
|
||||
main_window_get_window(
|
||||
application->main_window
|
||||
),
|
||||
APPLICATION_MESSAGE_DIALOG_WARNING,
|
||||
"Réinitialiser la disposition du graphe",
|
||||
"Toutes les positions personnalisées des nœuds seront supprimées. "
|
||||
"Le graphe retrouvera sa disposition automatique.\n\n"
|
||||
"Cette action ne peut pas être annulée.",
|
||||
"Réinitialiser",
|
||||
application_on_reset_graph_layout_confirmed,
|
||||
application
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ferme proprement l'application.
|
||||
*
|
||||
|
|
@ -4504,6 +4594,12 @@ static void application_on_activate(
|
|||
application
|
||||
);
|
||||
|
||||
main_window_set_show_graph_callback(
|
||||
application->main_window,
|
||||
application_on_show_graph_requested,
|
||||
application
|
||||
);
|
||||
|
||||
main_window_set_new_investigation_callback(
|
||||
application->main_window,
|
||||
application_on_new_investigation_requested,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,25 @@
|
|||
#define APPLICATION_MESSAGE_DIALOG_DEFAULT_MESSAGE \
|
||||
"Aucun détail supplémentaire n'est disponible."
|
||||
|
||||
/**
|
||||
* @brief Libellé par défaut du bouton de confirmation.
|
||||
*/
|
||||
#define APPLICATION_MESSAGE_DIALOG_DEFAULT_CONFIRM_LABEL \
|
||||
"Confirmer"
|
||||
|
||||
/**
|
||||
* @brief État privé d'un dialogue de confirmation.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
GtkWindow *dialog_window;
|
||||
|
||||
ApplicationMessageDialogConfirmationCallback callback;
|
||||
gpointer user_data;
|
||||
|
||||
gboolean completed;
|
||||
} ApplicationMessageDialogConfirmationContext;
|
||||
|
||||
/**
|
||||
* @brief Retourne le libellé correspondant au type de message.
|
||||
*
|
||||
|
|
@ -335,3 +354,528 @@ void application_message_dialog_present(
|
|||
dialog_window
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Libère le contexte associé à une fenêtre de confirmation.
|
||||
*/
|
||||
static void application_message_dialog_confirmation_context_free(
|
||||
gpointer data
|
||||
)
|
||||
{
|
||||
ApplicationMessageDialogConfirmationContext *context =
|
||||
data;
|
||||
|
||||
if (context == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
context->dialog_window =
|
||||
NULL;
|
||||
|
||||
context->callback =
|
||||
NULL;
|
||||
|
||||
context->user_data =
|
||||
NULL;
|
||||
|
||||
g_free(
|
||||
context
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Termine une confirmation et transmet son résultat une seule fois.
|
||||
*
|
||||
* Lorsque destroy_window vaut TRUE, la fenêtre est détruite avant l'appel
|
||||
* du callback. Les valeurs du callback sont donc copiées localement avant
|
||||
* la destruction du contexte attaché à la fenêtre.
|
||||
*/
|
||||
static void application_message_dialog_complete_confirmation(
|
||||
ApplicationMessageDialogConfirmationContext *context,
|
||||
gboolean confirmed,
|
||||
gboolean destroy_window
|
||||
)
|
||||
{
|
||||
ApplicationMessageDialogConfirmationCallback callback =
|
||||
NULL;
|
||||
|
||||
gpointer user_data =
|
||||
NULL;
|
||||
|
||||
GtkWindow *dialog_window =
|
||||
NULL;
|
||||
|
||||
if (context == NULL ||
|
||||
context->completed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
context->completed =
|
||||
TRUE;
|
||||
|
||||
callback =
|
||||
context->callback;
|
||||
|
||||
user_data =
|
||||
context->user_data;
|
||||
|
||||
dialog_window =
|
||||
context->dialog_window;
|
||||
|
||||
context->callback =
|
||||
NULL;
|
||||
|
||||
context->user_data =
|
||||
NULL;
|
||||
|
||||
if (destroy_window &&
|
||||
dialog_window != NULL)
|
||||
{
|
||||
gtk_window_destroy(
|
||||
dialog_window
|
||||
);
|
||||
}
|
||||
|
||||
if (callback != NULL)
|
||||
{
|
||||
callback(
|
||||
confirmed,
|
||||
user_data
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Annule le dialogue depuis son bouton.
|
||||
*/
|
||||
static void application_message_dialog_on_cancel_clicked(
|
||||
GtkButton *button,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
ApplicationMessageDialogConfirmationContext *context =
|
||||
user_data;
|
||||
|
||||
(void) button;
|
||||
|
||||
application_message_dialog_complete_confirmation(
|
||||
context,
|
||||
FALSE,
|
||||
TRUE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Confirme le dialogue depuis son bouton principal.
|
||||
*/
|
||||
static void application_message_dialog_on_confirm_clicked(
|
||||
GtkButton *button,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
ApplicationMessageDialogConfirmationContext *context =
|
||||
user_data;
|
||||
|
||||
(void) button;
|
||||
|
||||
application_message_dialog_complete_confirmation(
|
||||
context,
|
||||
TRUE,
|
||||
TRUE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Traite la fermeture manuelle comme une annulation.
|
||||
*/
|
||||
static gboolean application_message_dialog_on_confirmation_close_requested(
|
||||
GtkWindow *dialog_window,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
ApplicationMessageDialogConfirmationContext *context =
|
||||
user_data;
|
||||
|
||||
(void) dialog_window;
|
||||
|
||||
application_message_dialog_complete_confirmation(
|
||||
context,
|
||||
FALSE,
|
||||
FALSE
|
||||
);
|
||||
|
||||
/*
|
||||
* FALSE laisse GTK poursuivre la fermeture normale de la fenêtre.
|
||||
*/
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void application_message_dialog_present_confirmation(
|
||||
GtkWindow *parent_window,
|
||||
ApplicationMessageDialogType message_type,
|
||||
const char *title,
|
||||
const char *message,
|
||||
const char *confirm_label,
|
||||
ApplicationMessageDialogConfirmationCallback callback,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
GtkWindow *dialog_window =
|
||||
NULL;
|
||||
|
||||
GtkWidget *main_box =
|
||||
NULL;
|
||||
|
||||
GtkWidget *type_label =
|
||||
NULL;
|
||||
|
||||
GtkWidget *title_label =
|
||||
NULL;
|
||||
|
||||
GtkWidget *message_label =
|
||||
NULL;
|
||||
|
||||
GtkWidget *button_box =
|
||||
NULL;
|
||||
|
||||
GtkWidget *cancel_button =
|
||||
NULL;
|
||||
|
||||
GtkWidget *confirm_button =
|
||||
NULL;
|
||||
|
||||
ApplicationMessageDialogConfirmationContext *context =
|
||||
NULL;
|
||||
|
||||
const char *safe_title =
|
||||
NULL;
|
||||
|
||||
const char *safe_message =
|
||||
NULL;
|
||||
|
||||
const char *safe_confirm_label =
|
||||
NULL;
|
||||
|
||||
const char *type_text =
|
||||
NULL;
|
||||
|
||||
safe_title =
|
||||
application_message_dialog_get_safe_title(
|
||||
message_type,
|
||||
title
|
||||
);
|
||||
|
||||
safe_message =
|
||||
application_message_dialog_get_safe_message(
|
||||
message
|
||||
);
|
||||
|
||||
safe_confirm_label =
|
||||
confirm_label != NULL &&
|
||||
confirm_label[0] != '\0'
|
||||
? confirm_label
|
||||
: APPLICATION_MESSAGE_DIALOG_DEFAULT_CONFIRM_LABEL;
|
||||
|
||||
type_text =
|
||||
application_message_dialog_get_type_label(
|
||||
message_type
|
||||
);
|
||||
|
||||
context =
|
||||
g_try_new0(
|
||||
ApplicationMessageDialogConfirmationContext,
|
||||
1
|
||||
);
|
||||
|
||||
if (context == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dialog_window =
|
||||
GTK_WINDOW(
|
||||
gtk_window_new()
|
||||
);
|
||||
|
||||
context->dialog_window =
|
||||
dialog_window;
|
||||
|
||||
context->callback =
|
||||
callback;
|
||||
|
||||
context->user_data =
|
||||
user_data;
|
||||
|
||||
context->completed =
|
||||
FALSE;
|
||||
|
||||
g_object_set_data_full(
|
||||
G_OBJECT(
|
||||
dialog_window
|
||||
),
|
||||
"application-message-dialog-confirmation-context",
|
||||
context,
|
||||
application_message_dialog_confirmation_context_free
|
||||
);
|
||||
|
||||
gtk_window_set_title(
|
||||
dialog_window,
|
||||
safe_title
|
||||
);
|
||||
|
||||
gtk_window_set_default_size(
|
||||
dialog_window,
|
||||
APPLICATION_MESSAGE_DIALOG_DEFAULT_WIDTH,
|
||||
-1
|
||||
);
|
||||
|
||||
gtk_window_set_modal(
|
||||
dialog_window,
|
||||
TRUE
|
||||
);
|
||||
|
||||
gtk_window_set_destroy_with_parent(
|
||||
dialog_window,
|
||||
TRUE
|
||||
);
|
||||
|
||||
gtk_window_set_resizable(
|
||||
dialog_window,
|
||||
FALSE
|
||||
);
|
||||
|
||||
if (parent_window != NULL)
|
||||
{
|
||||
gtk_window_set_transient_for(
|
||||
dialog_window,
|
||||
parent_window
|
||||
);
|
||||
}
|
||||
|
||||
main_box =
|
||||
gtk_box_new(
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
12
|
||||
);
|
||||
|
||||
gtk_widget_set_margin_start(
|
||||
main_box,
|
||||
20
|
||||
);
|
||||
|
||||
gtk_widget_set_margin_end(
|
||||
main_box,
|
||||
20
|
||||
);
|
||||
|
||||
gtk_widget_set_margin_top(
|
||||
main_box,
|
||||
20
|
||||
);
|
||||
|
||||
gtk_widget_set_margin_bottom(
|
||||
main_box,
|
||||
20
|
||||
);
|
||||
|
||||
type_label =
|
||||
gtk_label_new(
|
||||
type_text
|
||||
);
|
||||
|
||||
gtk_widget_set_halign(
|
||||
type_label,
|
||||
GTK_ALIGN_START
|
||||
);
|
||||
|
||||
gtk_label_set_xalign(
|
||||
GTK_LABEL(
|
||||
type_label
|
||||
),
|
||||
0.0F
|
||||
);
|
||||
|
||||
title_label =
|
||||
gtk_label_new(
|
||||
safe_title
|
||||
);
|
||||
|
||||
gtk_widget_set_halign(
|
||||
title_label,
|
||||
GTK_ALIGN_START
|
||||
);
|
||||
|
||||
gtk_label_set_xalign(
|
||||
GTK_LABEL(
|
||||
title_label
|
||||
),
|
||||
0.0F
|
||||
);
|
||||
|
||||
gtk_label_set_wrap(
|
||||
GTK_LABEL(
|
||||
title_label
|
||||
),
|
||||
TRUE
|
||||
);
|
||||
|
||||
gtk_widget_add_css_class(
|
||||
title_label,
|
||||
"title-2"
|
||||
);
|
||||
|
||||
message_label =
|
||||
gtk_label_new(
|
||||
safe_message
|
||||
);
|
||||
|
||||
gtk_widget_set_halign(
|
||||
message_label,
|
||||
GTK_ALIGN_FILL
|
||||
);
|
||||
|
||||
gtk_label_set_xalign(
|
||||
GTK_LABEL(
|
||||
message_label
|
||||
),
|
||||
0.0F
|
||||
);
|
||||
|
||||
gtk_label_set_wrap(
|
||||
GTK_LABEL(
|
||||
message_label
|
||||
),
|
||||
TRUE
|
||||
);
|
||||
|
||||
gtk_label_set_wrap_mode(
|
||||
GTK_LABEL(
|
||||
message_label
|
||||
),
|
||||
PANGO_WRAP_WORD_CHAR
|
||||
);
|
||||
|
||||
gtk_label_set_selectable(
|
||||
GTK_LABEL(
|
||||
message_label
|
||||
),
|
||||
TRUE
|
||||
);
|
||||
|
||||
gtk_label_set_max_width_chars(
|
||||
GTK_LABEL(
|
||||
message_label
|
||||
),
|
||||
70
|
||||
);
|
||||
|
||||
button_box =
|
||||
gtk_box_new(
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
8
|
||||
);
|
||||
|
||||
gtk_widget_set_halign(
|
||||
button_box,
|
||||
GTK_ALIGN_END
|
||||
);
|
||||
|
||||
cancel_button =
|
||||
gtk_button_new_with_label(
|
||||
"Annuler"
|
||||
);
|
||||
|
||||
confirm_button =
|
||||
gtk_button_new_with_label(
|
||||
safe_confirm_label
|
||||
);
|
||||
|
||||
gtk_widget_add_css_class(
|
||||
confirm_button,
|
||||
"destructive-action"
|
||||
);
|
||||
|
||||
g_signal_connect(
|
||||
cancel_button,
|
||||
"clicked",
|
||||
G_CALLBACK(
|
||||
application_message_dialog_on_cancel_clicked
|
||||
),
|
||||
context
|
||||
);
|
||||
|
||||
g_signal_connect(
|
||||
confirm_button,
|
||||
"clicked",
|
||||
G_CALLBACK(
|
||||
application_message_dialog_on_confirm_clicked
|
||||
),
|
||||
context
|
||||
);
|
||||
|
||||
g_signal_connect(
|
||||
dialog_window,
|
||||
"close-request",
|
||||
G_CALLBACK(
|
||||
application_message_dialog_on_confirmation_close_requested
|
||||
),
|
||||
context
|
||||
);
|
||||
|
||||
gtk_box_append(
|
||||
GTK_BOX(
|
||||
button_box
|
||||
),
|
||||
cancel_button
|
||||
);
|
||||
|
||||
gtk_box_append(
|
||||
GTK_BOX(
|
||||
button_box
|
||||
),
|
||||
confirm_button
|
||||
);
|
||||
|
||||
gtk_box_append(
|
||||
GTK_BOX(
|
||||
main_box
|
||||
),
|
||||
type_label
|
||||
);
|
||||
|
||||
gtk_box_append(
|
||||
GTK_BOX(
|
||||
main_box
|
||||
),
|
||||
title_label
|
||||
);
|
||||
|
||||
gtk_box_append(
|
||||
GTK_BOX(
|
||||
main_box
|
||||
),
|
||||
message_label
|
||||
);
|
||||
|
||||
gtk_box_append(
|
||||
GTK_BOX(
|
||||
main_box
|
||||
),
|
||||
button_box
|
||||
);
|
||||
|
||||
gtk_window_set_child(
|
||||
dialog_window,
|
||||
main_box
|
||||
);
|
||||
|
||||
gtk_widget_grab_focus(
|
||||
cancel_button
|
||||
);
|
||||
|
||||
gtk_window_present(
|
||||
dialog_window
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ struct MainWindow
|
|||
GtkWidget *new_investigation_button;
|
||||
GtkWidget *open_investigation_button;
|
||||
GtkWidget *import_evidence_button;
|
||||
GtkWidget *show_graph_button;
|
||||
GtkWidget *content_paned;
|
||||
GtkWidget *main_paned;
|
||||
GtkWidget *status_label;
|
||||
|
|
@ -86,6 +87,12 @@ struct MainWindow
|
|||
gpointer
|
||||
import_evidence_user_data;
|
||||
|
||||
MainWindowShowGraphCallback
|
||||
show_graph_callback;
|
||||
|
||||
gpointer
|
||||
show_graph_user_data;
|
||||
|
||||
MainWindowVerifyEvidenceCallback
|
||||
verify_evidence_callback;
|
||||
|
||||
|
|
@ -190,6 +197,33 @@ static void main_window_on_import_evidence_clicked(
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transmet la demande de fermeture au contrôleur.
|
||||
*
|
||||
* @param button Bouton ayant reçu le clic.
|
||||
* @param user_data Pointeur vers MainWindow.
|
||||
*/
|
||||
static void main_window_on_show_graph_clicked(
|
||||
GtkButton *button,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
MainWindow *main_window =
|
||||
user_data;
|
||||
|
||||
(void) button;
|
||||
|
||||
if (main_window == NULL ||
|
||||
main_window->show_graph_callback == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
main_window->show_graph_callback(
|
||||
main_window->show_graph_user_data
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transmet la demande de fermeture au contrôleur.
|
||||
*
|
||||
|
|
@ -436,6 +470,12 @@ MainWindow *main_window_new(
|
|||
"Importer une preuve"
|
||||
);
|
||||
|
||||
main_window->show_graph_button =
|
||||
main_window_create_action_button(
|
||||
"go-previous-symbolic",
|
||||
"Revenir au graphe"
|
||||
);
|
||||
|
||||
main_window->quit_button =
|
||||
main_window_create_action_button(
|
||||
"application-exit-symbolic",
|
||||
|
|
@ -461,6 +501,11 @@ MainWindow *main_window_new(
|
|||
FALSE
|
||||
);
|
||||
|
||||
gtk_widget_set_sensitive(
|
||||
main_window->show_graph_button,
|
||||
FALSE
|
||||
);
|
||||
|
||||
gtk_box_append(
|
||||
GTK_BOX(main_window->action_bar),
|
||||
main_window->new_investigation_button
|
||||
|
|
@ -476,6 +521,11 @@ MainWindow *main_window_new(
|
|||
main_window->import_evidence_button
|
||||
);
|
||||
|
||||
gtk_box_append(
|
||||
GTK_BOX(main_window->action_bar),
|
||||
main_window->show_graph_button
|
||||
);
|
||||
|
||||
gtk_box_append(
|
||||
GTK_BOX(main_window->action_bar),
|
||||
action_spacer
|
||||
|
|
@ -513,6 +563,15 @@ MainWindow *main_window_new(
|
|||
main_window
|
||||
);
|
||||
|
||||
g_signal_connect(
|
||||
main_window->show_graph_button,
|
||||
"clicked",
|
||||
G_CALLBACK(
|
||||
main_window_on_show_graph_clicked
|
||||
),
|
||||
main_window
|
||||
);
|
||||
|
||||
g_signal_connect(
|
||||
main_window->quit_button,
|
||||
"clicked",
|
||||
|
|
@ -937,6 +996,11 @@ void main_window_set_graph_loading(
|
|||
return;
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive(
|
||||
main_window->show_graph_button,
|
||||
FALSE
|
||||
);
|
||||
|
||||
workspace_set_graph_loading(
|
||||
main_window->workspace
|
||||
);
|
||||
|
|
@ -958,6 +1022,11 @@ void main_window_set_graph(
|
|||
graph_model,
|
||||
graph_layout
|
||||
);
|
||||
|
||||
gtk_widget_set_sensitive(
|
||||
main_window->show_graph_button,
|
||||
graph_model != NULL
|
||||
);
|
||||
}
|
||||
|
||||
void main_window_set_graph_error(
|
||||
|
|
@ -970,6 +1039,11 @@ void main_window_set_graph_error(
|
|||
return;
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive(
|
||||
main_window->show_graph_button,
|
||||
FALSE
|
||||
);
|
||||
|
||||
workspace_set_graph_error(
|
||||
main_window->workspace,
|
||||
message
|
||||
|
|
@ -985,6 +1059,11 @@ void main_window_clear_graph(
|
|||
return;
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive(
|
||||
main_window->show_graph_button,
|
||||
FALSE
|
||||
);
|
||||
|
||||
workspace_clear_graph(
|
||||
main_window->workspace
|
||||
);
|
||||
|
|
@ -1113,6 +1192,24 @@ void main_window_set_import_evidence_callback(
|
|||
user_data;
|
||||
}
|
||||
|
||||
void main_window_set_show_graph_callback(
|
||||
MainWindow *main_window,
|
||||
MainWindowShowGraphCallback callback,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
if (main_window == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
main_window->show_graph_callback =
|
||||
callback;
|
||||
|
||||
main_window->show_graph_user_data =
|
||||
user_data;
|
||||
}
|
||||
|
||||
void main_window_set_import_evidence_enabled(
|
||||
MainWindow *main_window,
|
||||
gboolean enabled
|
||||
|
|
@ -1324,6 +1421,12 @@ void main_window_free(
|
|||
main_window->reset_graph_layout_user_data =
|
||||
NULL;
|
||||
|
||||
main_window->show_graph_callback =
|
||||
NULL;
|
||||
|
||||
main_window->show_graph_user_data =
|
||||
NULL;
|
||||
|
||||
main_window_clear_graph(
|
||||
main_window
|
||||
);
|
||||
|
|
@ -1354,3 +1457,4 @@ void main_window_free(
|
|||
main_window
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ struct Workspace
|
|||
GtkWidget *graph_view_page;
|
||||
GtkWidget *graph_toolbar;
|
||||
GtkWidget *reset_graph_layout_button;
|
||||
GtkWidget *graph_help_button;
|
||||
GtkWidget *graph_help_popover;
|
||||
|
||||
InvestigationGraphView *graph_view;
|
||||
EntityDetailsPanel *entity_details_panel;
|
||||
|
|
@ -1174,6 +1176,175 @@ Workspace *workspace_new(void)
|
|||
TRUE
|
||||
);
|
||||
|
||||
workspace->graph_help_button =
|
||||
gtk_menu_button_new();
|
||||
|
||||
workspace->graph_help_popover =
|
||||
gtk_popover_new();
|
||||
|
||||
GtkWidget *graph_help_content =
|
||||
gtk_box_new(
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
8
|
||||
);
|
||||
|
||||
GtkWidget *graph_help_title =
|
||||
gtk_label_new(
|
||||
"Commandes du graphe"
|
||||
);
|
||||
|
||||
GtkWidget *graph_help_text =
|
||||
gtk_label_new(
|
||||
"• Clic : sélectionner un nœud\n"
|
||||
"• Glisser un nœud : le déplacer\n"
|
||||
"• Maj + glisser : déplacer la vue\n"
|
||||
"• Ctrl + molette : zoomer\n"
|
||||
"• Pincement : zoomer"
|
||||
);
|
||||
|
||||
if (workspace->graph_help_button == NULL ||
|
||||
workspace->graph_help_popover == NULL ||
|
||||
graph_help_content == NULL ||
|
||||
graph_help_title == NULL ||
|
||||
graph_help_text == NULL)
|
||||
{
|
||||
workspace_free(
|
||||
workspace
|
||||
);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gtk_menu_button_set_label(
|
||||
GTK_MENU_BUTTON(
|
||||
workspace->graph_help_button
|
||||
),
|
||||
"?"
|
||||
);
|
||||
|
||||
gtk_widget_add_css_class(
|
||||
workspace->graph_help_button,
|
||||
"flat"
|
||||
);
|
||||
|
||||
gtk_widget_set_tooltip_text(
|
||||
workspace->graph_help_button,
|
||||
"Afficher les commandes du graphe"
|
||||
);
|
||||
|
||||
gtk_widget_set_can_target(
|
||||
workspace->graph_help_button,
|
||||
TRUE
|
||||
);
|
||||
|
||||
gtk_widget_set_halign(
|
||||
workspace->graph_help_button,
|
||||
GTK_ALIGN_END
|
||||
);
|
||||
|
||||
gtk_widget_set_valign(
|
||||
workspace->graph_help_button,
|
||||
GTK_ALIGN_START
|
||||
);
|
||||
|
||||
gtk_widget_set_margin_end(
|
||||
workspace->graph_help_button,
|
||||
12
|
||||
);
|
||||
|
||||
gtk_widget_set_margin_top(
|
||||
workspace->graph_help_button,
|
||||
12
|
||||
);
|
||||
|
||||
gtk_widget_set_margin_start(
|
||||
graph_help_content,
|
||||
16
|
||||
);
|
||||
|
||||
gtk_widget_set_margin_end(
|
||||
graph_help_content,
|
||||
16
|
||||
);
|
||||
|
||||
gtk_widget_set_margin_top(
|
||||
graph_help_content,
|
||||
14
|
||||
);
|
||||
|
||||
gtk_widget_set_margin_bottom(
|
||||
graph_help_content,
|
||||
14
|
||||
);
|
||||
|
||||
gtk_label_set_xalign(
|
||||
GTK_LABEL(
|
||||
graph_help_title
|
||||
),
|
||||
0.0F
|
||||
);
|
||||
|
||||
gtk_widget_add_css_class(
|
||||
graph_help_title,
|
||||
"heading"
|
||||
);
|
||||
|
||||
gtk_label_set_xalign(
|
||||
GTK_LABEL(
|
||||
graph_help_text
|
||||
),
|
||||
0.0F
|
||||
);
|
||||
|
||||
gtk_label_set_wrap(
|
||||
GTK_LABEL(
|
||||
graph_help_text
|
||||
),
|
||||
TRUE
|
||||
);
|
||||
|
||||
gtk_label_set_wrap_mode(
|
||||
GTK_LABEL(
|
||||
graph_help_text
|
||||
),
|
||||
PANGO_WRAP_WORD_CHAR
|
||||
);
|
||||
|
||||
gtk_label_set_max_width_chars(
|
||||
GTK_LABEL(
|
||||
graph_help_text
|
||||
),
|
||||
44
|
||||
);
|
||||
|
||||
gtk_box_append(
|
||||
GTK_BOX(
|
||||
graph_help_content
|
||||
),
|
||||
graph_help_title
|
||||
);
|
||||
|
||||
gtk_box_append(
|
||||
GTK_BOX(
|
||||
graph_help_content
|
||||
),
|
||||
graph_help_text
|
||||
);
|
||||
|
||||
gtk_popover_set_child(
|
||||
GTK_POPOVER(
|
||||
workspace->graph_help_popover
|
||||
),
|
||||
graph_help_content
|
||||
);
|
||||
|
||||
gtk_menu_button_set_popover(
|
||||
GTK_MENU_BUTTON(
|
||||
workspace->graph_help_button
|
||||
),
|
||||
workspace->graph_help_popover
|
||||
);
|
||||
|
||||
gtk_overlay_add_overlay(
|
||||
GTK_OVERLAY(
|
||||
workspace->graph_view_page
|
||||
|
|
@ -1193,6 +1364,22 @@ Workspace *workspace_new(void)
|
|||
TRUE
|
||||
);
|
||||
|
||||
gtk_overlay_add_overlay(
|
||||
GTK_OVERLAY(
|
||||
workspace->graph_view_page
|
||||
),
|
||||
workspace->graph_help_button
|
||||
);
|
||||
|
||||
gtk_overlay_set_clip_overlay(
|
||||
GTK_OVERLAY(
|
||||
workspace->graph_view_page
|
||||
),
|
||||
workspace->graph_help_button,
|
||||
TRUE
|
||||
);
|
||||
|
||||
|
||||
gtk_stack_add_named(
|
||||
GTK_STACK(workspace->stack),
|
||||
workspace->graph_view_page,
|
||||
|
|
@ -2022,6 +2209,12 @@ void workspace_free(Workspace *workspace)
|
|||
workspace->reset_graph_layout_button =
|
||||
NULL;
|
||||
|
||||
workspace->graph_help_button =
|
||||
NULL;
|
||||
|
||||
workspace->graph_help_popover =
|
||||
NULL;
|
||||
|
||||
g_clear_pointer(
|
||||
&workspace->selected_evidence_identifier,
|
||||
g_free
|
||||
|
|
|
|||
Loading…
Reference in a new issue