Confirmer la réinitialisation de la disposition du graphe
This commit is contained in:
parent
0f67118f5b
commit
0069e99529
3 changed files with 645 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
|
||||
|
|
|
|||
|
|
@ -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,61 @@ 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_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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue