diff options
Diffstat (limited to 'src/gtkext/statusstack.c')
-rw-r--r-- | src/gtkext/statusstack.c | 310 |
1 files changed, 290 insertions, 20 deletions
diff --git a/src/gtkext/statusstack.c b/src/gtkext/statusstack.c index 0d8ef62..92c296a 100644 --- a/src/gtkext/statusstack.c +++ b/src/gtkext/statusstack.c @@ -41,6 +41,25 @@ /* -------------------------- GESTION GENERALE DES STATUTS -------------------------- */ +/* Liste des propriétés */ + +typedef enum _StatusStackProperty { + + PROP_0, /* Réservé */ + + PROP_SHOW_BOTTOM, /* Affichage de la zone inf. */ + + N_PROPERTIES + +} StatusStackProperty; + +static GParamSpec *_status_stack_properties[N_PROPERTIES] = { NULL, }; + + +/* Source d'affichage par défaut */ +#define gtk_status_stack_default_source gtk_status_stack_show_simple_message + + /* Initialise la classe des barres de statut améliorées. */ static void gtk_status_stack_class_init(GtkStatusStackClass *); @@ -53,11 +72,33 @@ static void gtk_status_stack_dispose(GtkStatusStack *); /* Procède à la libération totale de la mémoire. */ static void gtk_status_stack_finalize(GtkStatusStack *); +/* Note le changement de verrouillage du stockage sécurisé. */ +static void gtk_status_stack_on_secret_storage_lock_update(GSecretStorage *, GtkStatusStack *); + /* Met à jour dans la barre les débits réseau observés. */ static gboolean gtk_status_stack_update_network_stats(GtkStatusStack *); +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Met à jour une propriété d'instance GObject. */ +static void gtk_status_stack_set_property(GObject *, guint, const GValue *, GParamSpec *); + +/* Fournit la valeur d'une propriété d'instance GObject. */ +static void gtk_status_stack_get_property(GObject *, guint, GValue *, GParamSpec *); + + + +/* ----------------------- MISE EN AVANT DES MESSAGES SIMPLES ----------------------- */ + + +/* S'assure de l'affichage à jour de la partie "default". */ +static gboolean gtk_status_stack_show_simple_message(gpointer); + + + /* -------------------- STATUT DES INFORMATIONS DE DESASSEMBLAGE -------------------- */ @@ -86,7 +127,7 @@ static void init_navigation_info(navigation_info_t *); static void fini_navigation_info(navigation_info_t *); /* S'assure de l'affichage à jour de la partie "navigation". */ -static gboolean gtk_status_stack_show_current_location(GtkStatusStack *); +static gboolean gtk_status_stack_show_current_location(gpointer); /* Réagit à un clic sur l'icône de zoom. */ static void gtk_status_stack_on_zoom_icon_press(GtkEntry *, GtkEntryIconPosition, GtkStatusStack *); @@ -136,7 +177,7 @@ static void fini_activity_info(activity_info_t *); static activity_status_t *find_activity_status_by_id(activity_info_t *, activity_id_t); /* S'assure de l'affichage à jour de la partie "activité". */ -static gboolean gtk_status_stack_show_current_activity(GtkStatusStack *); +static gboolean gtk_status_stack_show_current_activity(gpointer); @@ -170,6 +211,15 @@ static void gtk_status_stack_class_init(GtkStatusStackClass *class) object->dispose = (GObjectFinalizeFunc/* ! */)gtk_status_stack_dispose; object->finalize = (GObjectFinalizeFunc)gtk_status_stack_finalize; + object->set_property = gtk_status_stack_set_property; + object->get_property = gtk_status_stack_get_property; + + _status_stack_properties[PROP_SHOW_BOTTOM] = + g_param_spec_boolean("show-bottom", NULL, NULL, + TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object, N_PROPERTIES, _status_stack_properties); widget = GTK_WIDGET_CLASS(class); @@ -179,6 +229,8 @@ static void gtk_status_stack_class_init(GtkStatusStackClass *class) gtk_widget_class_bind_template_child(widget, GtkStatusStack, main); + gtk_widget_class_bind_template_child(widget, GtkStatusStack, def_label); + gtk_widget_class_bind_template_child(widget, GtkStatusStack, nav_segment); gtk_widget_class_bind_template_child(widget, GtkStatusStack, nav_phys); gtk_widget_class_bind_template_child(widget, GtkStatusStack, nav_virt); @@ -190,9 +242,13 @@ static void gtk_status_stack_class_init(GtkStatusStackClass *class) gtk_widget_class_bind_template_child(widget, GtkStatusStack, activity_message); gtk_widget_class_bind_template_child(widget, GtkStatusStack, activity_progress); + gtk_widget_class_bind_template_child(widget, GtkStatusStack, lock_update); + gtk_widget_class_bind_template_child(widget, GtkStatusStack, net_recv_speed); gtk_widget_class_bind_template_child(widget, GtkStatusStack, net_send_speed); + gtk_widget_class_bind_template_child(widget, GtkStatusStack, bottom_toggler); + } @@ -212,7 +268,9 @@ static void gtk_status_stack_init(GtkStatusStack *stack) { gtk_widget_init_template(GTK_WIDGET(stack)); - stack->def_source = NULL; + stack->def_source = gtk_status_stack_default_source; + + stack->msg = NULL; stack->nav_info = calloc(1, sizeof(navigation_info_t)); init_navigation_info(stack->nav_info); @@ -220,11 +278,26 @@ static void gtk_status_stack_init(GtkStatusStack *stack) stack->activity_info = calloc(1, sizeof(activity_info_t)); init_activity_info(stack->activity_info); + /* Suivi des évolutions relatives au stockage sécurisé */ + + stack->storage = get_secret_storage(); + + g_signal_connect(stack->storage, "lock-update", + G_CALLBACK(gtk_status_stack_on_secret_storage_lock_update), stack); + + gtk_status_stack_on_secret_storage_lock_update(stack->storage, stack); + + /* Suivi des débits de connexion */ + stack->next_index = 0; stack->network_update_tag = g_timeout_add(NETWORK_UPDATE_INTERVAL, G_SOURCE_FUNC(gtk_status_stack_update_network_stats), stack); + /* Premier affichage... */ + + gtk_status_stack_reset_to_default(stack); + } @@ -242,6 +315,12 @@ static void gtk_status_stack_init(GtkStatusStack *stack) static void gtk_status_stack_dispose(GtkStatusStack *stack) { + if (stack->storage != NULL) + g_signal_handlers_disconnect_by_func(stack->storage, + gtk_status_stack_on_secret_storage_lock_update, stack); + + g_clear_object(&stack->storage); + g_source_remove(stack->network_update_tag); gtk_widget_dispose_template(GTK_WIDGET(stack), GTK_TYPE_STATUS_STACK); @@ -265,6 +344,9 @@ static void gtk_status_stack_dispose(GtkStatusStack *stack) static void gtk_status_stack_finalize(GtkStatusStack *stack) { + if (stack->msg != NULL) + free(stack->msg); + fini_navigation_info(stack->nav_info); free(stack->nav_info); @@ -311,11 +393,49 @@ GtkStatusStack *gtk_status_stack_new(void) * * ******************************************************************************/ -void gtk_status_stack_reset(GtkStatusStack *stack) +void gtk_status_stack_reset_to_default(GtkStatusStack *stack) { - gtk_stack_set_visible_child_name(stack->main, "default"); + /** + * Une amélioration possible serait de passer à g_idle_add_once(), + * et de s'affranchir des retours G_SOURCE_REMOVE systématiques, + * mais la fonction n'est disponible qu'à partir de la GLib 2.74. + */ - stack->def_source = NULL; + g_idle_add(stack->def_source, stack); + +} + + +/****************************************************************************** +* * +* Paramètres : storage = gardien des secrets impliqué. * +* stack = barre de statut à actualiser. * +* * +* Description : Note le changement de verrouillage du stockage sécurisé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_status_stack_on_secret_storage_lock_update(GSecretStorage *storage, GtkStatusStack *stack) +{ + if (!g_secret_storage_has_key(stack->storage)) + { + gtk_widget_set_sensitive(GTK_WIDGET(stack->lock_update), false); + gtk_button_set_icon_name(GTK_BUTTON(stack->lock_update), "nolock-symbolic"); + } + else + { + gtk_widget_set_sensitive(GTK_WIDGET(stack->lock_update), true); + + if (g_secret_storage_is_locked(stack->storage)) + gtk_button_set_icon_name(GTK_BUTTON(stack->lock_update), "locked-symbolic"); + else + gtk_button_set_icon_name(GTK_BUTTON(stack->lock_update), "unlocked-symbolic"); + + } } @@ -441,6 +561,148 @@ static gboolean gtk_status_stack_update_network_stats(GtkStatusStack *stack) + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : object = instance d'objet GLib à mamnipuler. * +* prop_id = identifiant de la propriété visée. * +* value = valeur à prendre en compte. * +* pspec = définition de la propriété. * +* * +* Description : Met à jour une propriété d'instance GObject. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_status_stack_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GtkStatusStack *stack; /* Version spécialisée */ + + stack = GTK_STATUS_STACK(object); + + switch (prop_id) + { + case PROP_SHOW_BOTTOM: + gtk_toggle_button_set_active(stack->bottom_toggler, g_value_get_boolean(value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + + } + +} + + +/****************************************************************************** +* * +* Paramètres : object = instance d'objet GLib à mamnipuler. * +* prop_id = identifiant de la propriété visée. * +* value = valeur à transmettre. [OUT] * +* pspec = définition de la propriété. * +* * +* Description : Fournit la valeur d'une propriété d'instance GObject. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_status_stack_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GtkStatusStack *stack; /* Version spécialisée */ + + stack = GTK_STATUS_STACK(object); + + switch (prop_id) + { + case PROP_SHOW_BOTTOM: + g_value_set_boolean(value, gtk_toggle_button_get_active(stack->bottom_toggler)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + + } + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* MISE EN AVANT DES MESSAGES SIMPLES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : stack = barre de statut à actualiser. * +* msg = simple message à faire paraître. * +* * +* Description : Inscrit un message simple dans la barre de statut. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_status_stack_display_message(GtkStatusStack *stack, const char *msg) +{ + if (stack->msg != NULL) + free(stack->msg); + + if (msg != NULL) + stack->msg = strdup(msg); + else + stack->msg = NULL; + + gtk_status_stack_show_simple_message(stack); + +} + + +/****************************************************************************** +* * +* Paramètres : data = pile de statuts à manipuler. * +* * +* Description : S'assure de l'affichage à jour de la partie "default". * +* * +* Retour : G_SOURCE_REMOVE pour une exécution unique. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_status_stack_show_simple_message(gpointer data) +{ + GtkStatusStack *stack; /* Version spécialisée */ + + stack = GTK_STATUS_STACK(data); + + stack->def_source = gtk_status_stack_show_simple_message; + + gtk_label_set_text(stack->def_label, stack->msg != NULL ? stack->msg : ""); + + gtk_stack_set_visible_child_name(stack->main, "default"); + + return G_SOURCE_REMOVE; + +} + + + /* ---------------------------------------------------------------------------------- */ /* STATUT DES INFORMATIONS DE DESASSEMBLAGE */ /* ---------------------------------------------------------------------------------- */ @@ -572,7 +834,7 @@ void gtk_status_stack_update_current_location(GtkStatusStack *stack, const mrang /****************************************************************************** * * -* Paramètres : stack = pile de statuts à manipuler. * +* Paramètres : data = pile de statuts à manipuler. * * * * Description : S'assure de l'affichage à jour de la partie "navigation". * * * @@ -582,14 +844,15 @@ void gtk_status_stack_update_current_location(GtkStatusStack *stack, const mrang * * ******************************************************************************/ -static gboolean gtk_status_stack_show_current_location(GtkStatusStack *stack) +static gboolean gtk_status_stack_show_current_location(gpointer data) { + GtkStatusStack *stack; /* Version spécialisée */ navigation_info_t *info; /* Informations à constituer */ char raw_pos[6 + VMPA_MAX_LEN + 1]; /* Formatage final en direct */ - stack->def_source = (GSourceFunc)gtk_status_stack_show_current_location; + stack = GTK_STATUS_STACK(data); - gtk_stack_set_visible_child_name(stack->main, "navigation"); + stack->def_source = gtk_status_stack_show_current_location; info = stack->nav_info; @@ -613,6 +876,10 @@ static gboolean gtk_status_stack_show_current_location(GtkStatusStack *stack) gtk_label_set_text(stack->nav_details, info->details != NULL ? info->details : ""); + /* Conclusion */ + + gtk_stack_set_visible_child_name(stack->main, "navigation"); + return G_SOURCE_REMOVE; } @@ -813,7 +1080,7 @@ activity_id_t gtk_status_stack_add_activity(GtkStatusStack *stack, const char *m if (info->tag != 0) g_source_remove(info->tag); - info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack); + info->tag = g_idle_add(gtk_status_stack_show_current_activity, stack); g_mutex_unlock(&info->access); @@ -880,7 +1147,7 @@ void gtk_status_stack_update_activity_message(GtkStatusStack *stack, activity_id if (info->tag != 0) g_source_remove(info->tag); - info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack); + info->tag = g_idle_add(gtk_status_stack_show_current_activity, stack); } @@ -937,7 +1204,7 @@ void gtk_status_stack_update_activity_value(GtkStatusStack *stack, activity_id_t if (info->tag != 0) g_source_remove(info->tag); - info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack); + info->tag = g_idle_add(gtk_status_stack_show_current_activity, stack); } @@ -989,7 +1256,7 @@ void gtk_status_stack_extend_activity_max(GtkStatusStack *stack, activity_id_t i if (info->tag != 0) g_source_remove(info->tag); - info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack); + info->tag = g_idle_add(gtk_status_stack_show_current_activity, stack); } @@ -1055,10 +1322,10 @@ void gtk_status_stack_remove_activity(GtkStatusStack *stack, activity_id_t id) if (info->count == 0) { info->tag = 0; - g_idle_add(stack->def_source, stack); + gtk_status_stack_reset_to_default(stack); } else if (is_last) - info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack); + info->tag = g_idle_add(gtk_status_stack_show_current_activity, stack); exit: @@ -1069,7 +1336,7 @@ void gtk_status_stack_remove_activity(GtkStatusStack *stack, activity_id_t id) /****************************************************************************** * * -* Paramètres : stack = pile de statuts à manipuler. * +* Paramètres : data = pile de statuts à manipuler. * * * * Description : S'assure de l'affichage à jour de la partie "activité". * * * @@ -1079,11 +1346,14 @@ void gtk_status_stack_remove_activity(GtkStatusStack *stack, activity_id_t id) * * ******************************************************************************/ -static gboolean gtk_status_stack_show_current_activity(GtkStatusStack *stack) +static gboolean gtk_status_stack_show_current_activity(gpointer data) { + GtkStatusStack *stack; /* Version spécialisée */ activity_info_t *info; /* Informations à consulter */ activity_status_t *last; /* Dernier statut à traiter */ + stack = GTK_STATUS_STACK(data); + info = stack->activity_info; g_mutex_lock(&info->access); @@ -1092,14 +1362,14 @@ static gboolean gtk_status_stack_show_current_activity(GtkStatusStack *stack) { if (info->count > 0) { - gtk_stack_set_visible_child_name(stack->main, "activity"); - last = &info->statuses[info->count - 1]; gtk_label_set_text(stack->activity_message, last->message); gtk_progress_bar_set_fraction(stack->activity_progress, (last->current * 1.0) / last->max); + gtk_stack_set_visible_child_name(stack->main, "activity"); + } info->tag = 0; |