summaryrefslogtreecommitdiff
path: root/src/gtkext/statusstack.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtkext/statusstack.c')
-rw-r--r--src/gtkext/statusstack.c310
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;