summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-03-27 20:26:06 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-03-27 20:26:06 (GMT)
commit33906ce366efc053dee0b76d5bd668797b99071e (patch)
treed04f37f89df4a0e7b2e7c2055138005707244f87
parent4bc86c5dc8d3cfa9780103b56f52024a49913c22 (diff)
Added a section in the status bar to display activity progress.
-rw-r--r--ChangeLog12
-rw-r--r--src/analysis/project.c14
-rw-r--r--src/glibext/delayed-int.h4
-rw-r--r--src/glibext/delayed.c42
-rw-r--r--src/glibext/gcodebuffer.c8
-rw-r--r--src/gtkext/gtkstatusstack.c471
-rw-r--r--src/gtkext/gtkstatusstack.h26
7 files changed, 518 insertions, 59 deletions
diff --git a/ChangeLog b/ChangeLog
index 87ff9df..846bc0a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+16-03-27 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/analysis/project.c:
+ * src/glibext/delayed-int.h:
+ * src/glibext/delayed.c:
+ * src/glibext/gcodebuffer.c:
+ Update code.
+
+ * src/gtkext/gtkstatusstack.c:
+ * src/gtkext/gtkstatusstack.h:
+ Add a section in the status bar to display activity progress.
+
16-03-26 Cyrille Bagard <nocbos@gmail.com>
* src/glibext/delayed.c:
diff --git a/src/analysis/project.c b/src/analysis/project.c
index cb7f4bd..1a73e74 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -148,7 +148,7 @@ static void g_delayed_study_dispose(GDelayedStudy *);
static void g_delayed_study_finalize(GDelayedStudy *);
/* Prépare une intégration de binaire au projet courant. */
-static void g_delayed_study_process(GDelayedStudy *, GtkExtStatusBar *);
+static void g_delayed_study_process(GDelayedStudy *, GtkStatusStack *);
@@ -1089,8 +1089,8 @@ GDelayedStudy *g_delayed_study_new(GStudyProject *project, GBinContent *content,
/******************************************************************************
* *
-* Paramètres : dstudy = intégration à mener. *
-* statusbar = barre de statut à tenir informée. *
+* Paramètres : dstudy = intégration à mener. *
+* status = barre de statut à tenir informée. *
* *
* Description : Prépare une intégration de binaire au projet courant. *
* *
@@ -1100,15 +1100,15 @@ GDelayedStudy *g_delayed_study_new(GStudyProject *project, GBinContent *content,
* *
******************************************************************************/
-static void g_delayed_study_process(GDelayedStudy *dstudy, GtkExtStatusBar *statusbar)
+static void g_delayed_study_process(GDelayedStudy *dstudy, GtkStatusStack *status)
{
- FormatMatchStatus status; /* Statut d'une reconnaissance */
+ FormatMatchStatus mstatus; /* Statut d'une reconnaissance */
char *target; /* Sous-traitance requise */
GLoadedBinary *binary; /* Représentation chargée */
- status = find_matching_format(dstudy->content, NULL, &target);
+ mstatus = find_matching_format(dstudy->content, NULL, &target);
- switch (status)
+ switch (mstatus)
{
case FMS_MATCHED:
diff --git a/src/glibext/delayed-int.h b/src/glibext/delayed-int.h
index ecd9b4e..2f6608f 100644
--- a/src/glibext/delayed-int.h
+++ b/src/glibext/delayed-int.h
@@ -25,7 +25,7 @@
#include "../common/dllist.h"
-#include "../gtkext/gtkextstatusbar.h"
+#include "../gtkext/gtkstatusstack.h"
@@ -33,7 +33,7 @@
/* Traite un travail programmé. */
-typedef void (* run_task_fc) (GDelayedWork *, GtkExtStatusBar *);
+typedef void (* run_task_fc) (GDelayedWork *, GtkStatusStack *);
/* Travail différé (instance) */
diff --git a/src/glibext/delayed.c b/src/glibext/delayed.c
index 1d27448..37b3ed7 100644
--- a/src/glibext/delayed.c
+++ b/src/glibext/delayed.c
@@ -50,7 +50,7 @@ static void g_delayed_work_dispose(GDelayedWork *);
static void g_delayed_work_finalize(GDelayedWork *);
/* Mène l'opération programmée. */
-static void g_delayed_work_process(GDelayedWork *, GtkExtStatusBar *);
+static void g_delayed_work_process(GDelayedWork *, GtkStatusStack *);
@@ -72,7 +72,7 @@ typedef struct _GWorkGroup
wgroup_id_t id; /* Identifiant de travaux menés*/
- GtkExtStatusBar *statusbar; /* Barre de statut principale */
+ GtkStatusStack *status; /* Barre de statut principale */
GDelayedWork *works; /* Tâches à mener à bien */
GMutex mutex; /* Verrou pour l'accès */
@@ -113,7 +113,7 @@ static void g_work_group_dispose(GWorkGroup *);
static void g_work_group_finalize(GWorkGroup *);
/* Crée un nouveau thread dédié à un type de travaux donné. */
-static GWorkGroup *g_work_group_new(wgroup_id_t, GtkExtStatusBar *);
+static GWorkGroup *g_work_group_new(wgroup_id_t, GtkStatusStack *);
/* Fournit l'identifiant associé à un groupe de travail. */
static wgroup_id_t g_work_group_get_id(const GWorkGroup *);
@@ -143,7 +143,7 @@ struct _GWorkQueue
{
GObject parent; /* A laisser en premier */
- GtkExtStatusBar *statusbar; /* Barre de statut principale */
+ GtkStatusStack *status; /* Barre de statut principale */
wgroup_id_t generator; /* Générateur d'identifiants */
@@ -286,8 +286,8 @@ static void g_delayed_work_finalize(GDelayedWork *work)
/******************************************************************************
* *
-* Paramètres : work = travail à effectuer. *
-* statusbar = barre de statut à tenir informée. *
+* Paramètres : work = travail à effectuer. *
+* status = barre de statut à tenir informée. *
* *
* Description : Mène l'opération programmée. *
* *
@@ -297,9 +297,9 @@ static void g_delayed_work_finalize(GDelayedWork *work)
* *
******************************************************************************/
-static void g_delayed_work_process(GDelayedWork *work, GtkExtStatusBar *statusbar)
+static void g_delayed_work_process(GDelayedWork *work, GtkStatusStack *status)
{
- G_DELAYED_WORK_GET_CLASS(work)->run(work, statusbar);
+ G_DELAYED_WORK_GET_CLASS(work)->run(work, status);
g_mutex_lock(&work->mutex);
@@ -446,7 +446,7 @@ static void g_work_group_dispose(GWorkGroup *group)
for (i = 0; i < group->threads_count; i++)
g_thread_join(group->threads[i]);
- g_object_unref(group->statusbar);
+ g_object_unref(group->status);
while (!dl_list_empty(group->works))
{
@@ -490,8 +490,8 @@ static void g_work_group_finalize(GWorkGroup *group)
/******************************************************************************
* *
-* Paramètres : type = type dont seront marqués tous les travaux donnés.*
-* statusbar = barre de statut à tenir informée. *
+* Paramètres : type = type dont seront marqués tous les travaux donnés. *
+* status = barre de statut à tenir informée. *
* *
* Description : Crée un nouveau thread dédié à un type de travaux donné. *
* *
@@ -501,7 +501,7 @@ static void g_work_group_finalize(GWorkGroup *group)
* *
******************************************************************************/
-static GWorkGroup *g_work_group_new(wgroup_id_t id, GtkExtStatusBar *statusbar)
+static GWorkGroup *g_work_group_new(wgroup_id_t id, GtkStatusStack *status)
{
GWorkGroup *result; /* Traiteur à retourner */
@@ -509,10 +509,10 @@ static GWorkGroup *g_work_group_new(wgroup_id_t id, GtkExtStatusBar *statusbar)
result->id = id;
- if (statusbar != NULL)
+ if (status != NULL)
{
- result->statusbar = statusbar;
- g_object_ref(statusbar);
+ result->status = status;
+ g_object_ref(status);
}
return result;
@@ -601,7 +601,7 @@ static void *g_work_group_process(GWorkGroup *group)
g_mutex_unlock(&group->mutex);
- g_delayed_work_process(work, group->statusbar);
+ g_delayed_work_process(work, group->status);
//g_object_unref(G_OBJECT(work)); // FIXME
@@ -774,7 +774,7 @@ static void g_work_queue_dispose(GWorkQueue *queue)
{
size_t i; /* Boucle de parcours */
- g_object_unref(G_OBJECT(queue->statusbar));
+ g_object_unref(G_OBJECT(queue->status));
g_mutex_lock(&queue->mutex);
@@ -832,11 +832,11 @@ bool init_work_queue(GObject *ref)
if (ref != NULL)
{
- queue->statusbar = g_object_get_data(ref, "statusbar");
- g_object_ref(G_OBJECT(queue->statusbar));
+ queue->status = g_object_get_data(ref, "statusbar");
+ g_object_ref(G_OBJECT(queue->status));
}
else
- queue->statusbar = NULL;
+ queue->status = NULL;
if (queue != NULL)
_get_work_queue(queue);
@@ -903,7 +903,7 @@ static GWorkGroup *g_work_queue_ensure_group_exists(GWorkQueue *queue, wgroup_id
queue->groups = (GWorkGroup **)realloc(queue->groups,
queue->groups_count * sizeof(GWorkGroup *));
- result = g_work_group_new(id, queue->statusbar);
+ result = g_work_group_new(id, queue->status);
queue->groups[queue->groups_count - 1] = result;
}
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index be7fa37..8979d2f 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -93,7 +93,7 @@ static void g_buffer_scan_finalize(GBufferScan *);
static GBufferScan *g_buffer_scan_new(GCodeBuffer *, const vmpa2t *, const vmpa2t *, const char *, process_line_fc, void *);
/* Assure l'exportation en différé. */
-static void g_buffer_scan_process(GBufferScan *, GtkExtStatusBar *);
+static void g_buffer_scan_process(GBufferScan *, GtkStatusStack *);
@@ -387,8 +387,8 @@ static GBufferScan *g_buffer_scan_new(GCodeBuffer *buffer, const vmpa2t *start,
/******************************************************************************
* *
-* Paramètres : scan = parcours à mener. *
-* statusbar = barre de statut à tenir informée. *
+* Paramètres : scan = parcours à mener. *
+* status = barre de statut à tenir informée. *
* *
* Description : Assure l'exportation en différé. *
* *
@@ -398,7 +398,7 @@ static GBufferScan *g_buffer_scan_new(GCodeBuffer *buffer, const vmpa2t *start,
* *
******************************************************************************/
-static void g_buffer_scan_process(GBufferScan *scan, GtkExtStatusBar *statusbar)
+static void g_buffer_scan_process(GBufferScan *scan, GtkStatusStack *status)
{
size_t first; /* Première ligne visée */
size_t last; /* Dernière ligne visée + 1 */
diff --git a/src/gtkext/gtkstatusstack.c b/src/gtkext/gtkstatusstack.c
index 8cc85cc..9177399 100644
--- a/src/gtkext/gtkstatusstack.c
+++ b/src/gtkext/gtkstatusstack.c
@@ -41,7 +41,10 @@
/* Navigation au sein d'assemblage */
-typedef union _assembly_info assembly_info;
+typedef struct _assembly_info assembly_info;
+
+/* Mémorisation des progressions */
+typedef struct _progress_info progress_info;
/* Abstration d'une gestion de barre de statut (instance) */
@@ -52,6 +55,9 @@ struct _GtkStatusStack
GtkWidget *asm_status; /* Barre de status d'assemblage*/
assembly_info *asm_info; /* Informations courantes */
+ GtkWidget *prog_status; /* Barre de status d'activité */
+ progress_info *prog_info; /* Informations courantes */
+
};
/* Abstration d'une gestion de barre de statut (classe) */
@@ -83,25 +89,21 @@ static void gtk_status_stack_switch(GtkStatusStack *, GtkWidget *);
/* Navigation au sein d'assemblage */
-union _assembly_info
+struct _assembly_info
{
bool reset; /* Réinitialisation */
- struct
- {
- mrange_t current; /* Emplacement correspondant */
-
- char *segment; /* Segment d'appartenance */
+ mrange_t current; /* Emplacement correspondant */
- VMPA_BUFFER(phys); /* Localisation physique */
- VMPA_BUFFER(virt); /* Localisation virtuelle */
+ char *segment; /* Segment d'appartenance */
- char *symbol; /* Eventuel symbole concerné */
+ VMPA_BUFFER(phys); /* Localisation physique */
+ VMPA_BUFFER(virt); /* Localisation virtuelle */
- const char *encoding; /* Encodage de l'instruction */
- phys_t size; /* Taille de l'instruction */
+ char *symbol; /* Eventuel symbole concerné */
- };
+ const char *encoding; /* Encodage de l'instruction */
+ phys_t size; /* Taille de l'instruction */
};
@@ -119,7 +121,45 @@ static void on_size_allocate_for_asm_status(GtkWidget *, GdkRectangle *, GObject
static void on_zoom_icon_press(GtkEntry *, GtkEntryIconPosition, GdkEventButton *, GtkStatusStack *);
/* S'assure de l'affichage à jour de la partie "assemblage". */
-static void gtk_status_stack_show_current_instruction(GtkStatusStack *);
+static gboolean gtk_status_stack_show_current_instruction(GtkStatusStack *);
+
+
+
+/* -------------------------- STATUT DES SUIVIS D'ACTIVITE -------------------------- */
+
+
+/* Informations de progression */
+typedef struct _progress_status
+{
+ activity_id_t id; /* Identifiant unique */
+
+ char *message; /* Indication à faire valoir */
+ double value; /* Centième de pourcentage */
+
+} progress_status;
+
+/* Mémorisation des progressions */
+struct _progress_info
+{
+ activity_id_t generator; /* Générateur de séquence */
+
+ progress_status *statuses; /* Statuts de progression */
+ size_t count; /* Nombre de ces statuts */
+ GMutex access; /* Accès à la pile */
+
+ guint tag; /* Identifiant de mise à jour */
+
+};
+
+
+/* Supprime l'empreinte mémoire d'informations d'activité. */
+static void reset_progress_info(progress_info *);
+
+/* Construit une barre d'état pour un suivi d'activité. */
+static GtkWidget *build_progress_status_stack(GtkStatusStack *);
+
+/* S'assure de l'affichage à jour de la partie "activité". */
+static gboolean gtk_status_stack_show_current_activity(GtkStatusStack *);
@@ -175,6 +215,11 @@ static void gtk_status_stack_init(GtkStatusStack *stack)
reset_assembly_info(stack->asm_info);
+ stack->prog_status = build_progress_status_stack(stack);
+ stack->prog_info = (progress_info *)calloc(1, sizeof(progress_info));
+
+ reset_progress_info(stack->prog_info);
+
}
@@ -214,9 +259,11 @@ static void gtk_status_stack_dispose(GtkStatusStack *stack)
static void gtk_status_stack_finalize(GtkStatusStack *stack)
{
reset_assembly_info(stack->asm_info);
-
free(stack->asm_info);
+ reset_progress_info(stack->prog_info);
+ free(stack->prog_info);
+
G_OBJECT_CLASS(gtk_status_stack_parent_class)->finalize(G_OBJECT(stack));
}
@@ -564,7 +611,7 @@ void gtk_status_stack_update_current_instruction(GtkStatusStack *stack, const GL
/******************************************************************************
* *
-* Paramètres : stack = barre de statut à actualiser. *
+* Paramètres : stack = barre de statut à actualiser. *
* *
* Description : Réinitialise les informations associées une position. *
* *
@@ -593,13 +640,13 @@ void gtk_status_stack_reset_current_instruction(GtkStatusStack *stack)
* *
* Description : S'assure de l'affichage à jour de la partie "assemblage". *
* *
-* Retour : - *
+* Retour : G_SOURCE_REMOVE pour une exécution unique. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void gtk_status_stack_show_current_instruction(GtkStatusStack *stack)
+static gboolean gtk_status_stack_show_current_instruction(GtkStatusStack *stack)
{
GObject *ref; /* Espace de référencements */
assembly_info *info; /* Informations à consulter */
@@ -677,4 +724,392 @@ static void gtk_status_stack_show_current_instruction(GtkStatusStack *stack)
}
+ return G_SOURCE_REMOVE;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* STATUT DES SUIVIS D'ACTIVITE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : info = informations à réinitialiser. *
+* *
+* Description : Supprime l'empreinte mémoire d'informations d'activité. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void reset_progress_info(progress_info *info)
+{
+ size_t i; /* Boucle de parcours */
+
+ if (info->tag != 0)
+ g_source_remove(info->tag);
+
+ info->tag = 0;
+
+ for (i = 0; i < info->count; i++)
+ {
+ if (info->statuses[i].message != NULL)
+ free(info->statuses[i].message);
+ }
+
+ if (info->statuses != NULL)
+ {
+ free(info->statuses);
+ info->statuses = NULL;
+ }
+
+ info->count = 0;
+
+ g_mutex_init(&info->access);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stack = composant global en cours de construction. *
+* *
+* Description : Construit une barre d'état pour un suivi d'activité. *
+* *
+* Retour : Composant GTK mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GtkWidget *build_progress_status_stack(GtkStatusStack *stack)
+{
+ GtkWidget *result; /* Support à retourner */
+ GObject *ref; /* Espace de référencements */
+ GtkWidget *progress; /* Barre de progression */
+ GtkWidget *label; /* Désignation de l'activité */
+
+ result = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_widget_show(result);
+
+ ref = G_OBJECT(result);
+
+ progress = gtk_progress_bar_new();
+ g_object_set_data(ref, "progress", progress);
+ gtk_widget_set_size_request(progress, 200, -1);
+ gtk_widget_show(progress);
+ gtk_box_pack_start(GTK_BOX(result), progress, FALSE, TRUE, 8);
+
+ label = qck_create_label(ref, "message", NULL);
+ gtk_box_pack_start(GTK_BOX(result), label, TRUE, TRUE, 0);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stack = barre de statut à actualiser. *
+* msg = nouveau message de statut à copier. *
+* value = nouvelle valeur pour une progression donnée. *
+* *
+* Description : Démarre le suivi d'une nouvelle activité. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+activity_id_t gtk_status_stack_add_activity(GtkStatusStack *stack, const char *msg, double value)
+{
+ activity_id_t result; /* Numéro unique à renvoyer */
+ progress_info *info; /* Informations à consulter */
+ size_t new; /* Indice de l'activité créée */
+
+ info = stack->prog_info;
+
+ g_mutex_lock(&info->access);
+
+ result = ++info->generator;
+
+ new = info->count++;
+
+ info->statuses = (progress_status *)realloc(info->statuses,
+ info->count * sizeof(progress_status));
+
+ info->statuses[new].id = new;
+
+ /* Intitulé */
+
+ if (msg == NULL)
+ info->statuses[new].message = NULL;
+ else
+ info->statuses[new].message = strdup(msg);
+
+ /* Valeur */
+
+ info->statuses[new].value = value;
+
+ /* Actualisation */
+
+ if (info->tag != 0)
+ g_source_remove(info->tag);
+
+ info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack);
+
+ g_mutex_unlock(&info->access);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stack = barre de statut à actualiser. *
+* id = identifiant de l'activité à cibler. *
+* msg = nouveau message de statut à copier. *
+* value = nouvelle valeur pour une progression donnée. *
+* *
+* Description : Actualise les informations concernant une activité. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void gtk_status_stack_update_activity(GtkStatusStack *stack, activity_id_t id, const char *msg, double value)
+{
+ progress_info *info; /* Informations à consulter */
+ size_t i; /* Boucle de parcours */
+ bool msg_changed; /* Changement d'intitulé */
+ double old; /* Conservation pour la diff. */
+
+ info = stack->prog_info;
+
+ g_mutex_lock(&info->access);
+
+ for (i = 0; i < info->count; i++)
+ if (info->statuses[i].id == id)
+ break;
+
+ if (i < info->count)
+ {
+ /* Intitulé */
+
+ if (info->statuses[i].message != NULL)
+ {
+ if (msg == NULL)
+ msg_changed = true;
+ else
+ msg_changed = (strcmp(info->statuses[i].message, msg) != 0);
+
+ free(info->statuses[i].message);
+
+ }
+ else
+ msg_changed = (msg != NULL);
+
+ if (msg == NULL)
+ info->statuses[i].message = NULL;
+ else
+ info->statuses[i].message = strdup(msg);
+
+ /* Valeur */
+
+ old = info->statuses[i].value;
+
+ info->statuses[i].value = value;
+
+ /* On n'actualise que le sommet de la pile */
+
+ if ((i + 1) == info->count && (msg_changed || (value - old) > 1.0))
+ {
+ if (info->tag != 0)
+ g_source_remove(info->tag);
+
+ info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack);
+
+ }
+
+ }
+
+ g_mutex_unlock(&info->access);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stack = barre de statut à actualiser. *
+* id = identifiant de l'activité à cibler. *
+* value = nouvelle valeur pour une progression donnée. *
+* *
+* Description : Actualise la progression d'une activité. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void gtk_status_stack_update_activity_value(GtkStatusStack *stack, activity_id_t id, double value)
+{
+ progress_info *info; /* Informations à consulter */
+ size_t i; /* Boucle de parcours */
+ double old; /* Conservation pour la diff. */
+
+ info = stack->prog_info;
+
+ g_mutex_lock(&info->access);
+
+ for (i = 0; i < info->count; i++)
+ if (info->statuses[i].id == id)
+ break;
+
+ if (i < info->count)
+ {
+ /* Valeur */
+
+ old = info->statuses[i].value;
+
+ info->statuses[i].value = value;
+
+ /* On n'actualise que le sommet de la pile */
+
+ if ((i + 1) == info->count && (value - old) > 1.0)
+ {
+ if (info->tag != 0)
+ g_source_remove(info->tag);
+
+ info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack);
+
+ }
+
+ }
+
+ g_mutex_unlock(&info->access);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stack = barre de statut à actualiser. *
+* *
+* Description : Met fin au suivi d'une activité donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void gtk_status_stack_remove_activity(GtkStatusStack *stack, activity_id_t id)
+{
+ progress_info *info; /* Informations à consulter */
+ size_t i; /* Boucle de parcours */
+
+ info = stack->prog_info;
+
+ g_mutex_lock(&info->access);
+
+ for (i = 0; i < info->count; i++)
+ if (info->statuses[i].id == id)
+ break;
+
+ if (i < info->count)
+ {
+ if (info->tag != 0)
+ g_source_remove(info->tag);
+
+ if (info->statuses[i].message != NULL)
+ free(info->statuses[i].message);
+
+ if (info->count == 1)
+ {
+ free(info->statuses);
+ info->statuses = NULL;
+ }
+ else
+ {
+ memmove(&info->statuses[i], &info->statuses[i + 1],
+ (info->count - i - 1) * sizeof(progress_status));
+
+ info->statuses = (progress_status *)realloc(info->statuses,
+ (info->count - 1) * sizeof(progress_status));
+
+ }
+
+ info->count--;
+
+ if (info->count == 0)
+ info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_instruction, stack);
+ else
+ info->tag = g_idle_add((GSourceFunc)gtk_status_stack_show_current_activity, stack);
+
+ }
+
+ g_mutex_unlock(&info->access);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : stack = pile de statuts à manipuler. *
+* *
+* Description : S'assure de l'affichage à jour de la partie "activité". *
+* *
+* Retour : G_SOURCE_REMOVE pour une exécution unique. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static gboolean gtk_status_stack_show_current_activity(GtkStatusStack *stack)
+{
+ GObject *ref; /* Espace de référencements */
+ progress_info *info; /* Informations à consulter */
+ progress_status *last; /* Dernier statut à traiter */
+ GtkProgressBar *progress; /* Barre de progression */
+ GtkLabel *label; /* Désignation de l'activité */
+
+ if (!g_source_is_destroyed(g_main_current_source()))
+ {
+ gtk_status_stack_switch(stack, stack->prog_status);
+
+ ref = G_OBJECT(stack->prog_status);
+ info = stack->prog_info;
+
+ g_mutex_lock(&info->access);
+
+ info->tag = 0;
+
+ if (info->count > 0)
+ {
+ last = &info->statuses[info->count - 1];
+
+ progress = GTK_PROGRESS_BAR(g_object_get_data(ref, "progress"));
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), last->value);
+
+ label = GTK_LABEL(g_object_get_data(ref, "message"));
+ gtk_label_set_text(label, last->message);
+
+ }
+
+ g_mutex_unlock(&info->access);
+
+ }
+
+ return G_SOURCE_REMOVE;
+
}
diff --git a/src/gtkext/gtkstatusstack.h b/src/gtkext/gtkstatusstack.h
index 8e93708..afc3213 100644
--- a/src/gtkext/gtkstatusstack.h
+++ b/src/gtkext/gtkstatusstack.h
@@ -25,7 +25,6 @@
#define _GTKEXT_GTKSTATUSSTACK_H
-
#include <gtk/gtk.h>
@@ -33,12 +32,6 @@
-/* FIXME */
-typedef int bstatus_id_t;
-
-
-
-
/* ------------------------- GESTION EXTERIEURE DE LA BARRE ------------------------- */
@@ -76,6 +69,25 @@ void gtk_status_stack_reset_current_instruction(GtkStatusStack *);
+/* -------------------------- STATUT DES SUIVIS D'ACTIVITE -------------------------- */
+
+
+/* Identifiant unique de rapport de progression */
+typedef unsigned long activity_id_t;
+
+
+/* Démarre le suivi d'une nouvelle activité. */
+activity_id_t gtk_status_stack_add_activity(GtkStatusStack *, const char *, double);
+
+/* Actualise les informations concernant une activité. */
+void gtk_status_stack_update_activity(GtkStatusStack *, activity_id_t, const char *, double);
+
+/* Actualise la progression d'une activité. */
+void gtk_status_stack_update_activity_value(GtkStatusStack *, activity_id_t, double);
+
+/* Met fin au suivi d'une activité donnée. */
+void gtk_status_stack_remove_activity(GtkStatusStack *, activity_id_t);
+
#endif /* _GTKEXT_GTKSTATUSSTACK_H */