27 #include <glib/gi18n.h> 29 #include "guile-mappings.h" 32 #include "dialog-utils.h" 39 GtkWidget *primary_label;
40 GtkWidget *secondary_label;
41 GtkWidget *progress_bar;
46 GtkWidget *cancel_button;
57 GNCProgressCancelFunc cancel_func;
62 gboolean use_ok_button;
76 gnc_progress_maybe_destroy(GNCProgressDialog *progress)
78 g_return_if_fail(progress);
80 if (!(progress->closed && progress->destroyed))
83 if (progress->dialog != NULL)
84 gtk_widget_destroy(progress->dialog);
89 ok_cb(GtkWidget * widget, gpointer data)
91 GNCProgressDialog *progress = data;
93 g_return_if_fail(progress);
95 if (progress->dialog != NULL)
96 gtk_widget_hide(progress->dialog);
97 progress->closed = TRUE;
98 gnc_progress_maybe_destroy(progress);
103 cancel_cb(GtkWidget * widget, gpointer data)
105 GNCProgressDialog *progress = data;
107 g_return_if_fail(progress);
109 if (progress->cancel_func && !progress->cancel_func(progress->user_data))
112 if (progress->cancel_scm_func != SCM_UNDEFINED)
116 result = scm_call_0(progress->cancel_scm_func);
118 if (!scm_is_true(result))
122 if (progress->dialog != NULL)
123 gtk_widget_hide(progress->dialog);
124 progress->closed = TRUE;
125 gnc_progress_maybe_destroy(progress);
130 delete_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
132 GNCProgressDialog *progress = data;
134 g_return_val_if_fail(progress, TRUE);
136 if (progress->finished)
138 if (progress->dialog != NULL)
139 gtk_widget_hide(progress->dialog);
140 progress->closed = TRUE;
141 gnc_progress_maybe_destroy(progress);
145 if (progress->cancel_func)
147 if (progress->cancel_func(progress->user_data))
149 if (progress->dialog != NULL)
150 gtk_widget_hide(progress->dialog);
151 progress->closed = TRUE;
152 gnc_progress_maybe_destroy(progress);
157 if (progress->cancel_scm_func != SCM_UNDEFINED)
161 result = scm_call_0(progress->cancel_scm_func);
163 if (scm_is_true(result))
165 if (progress->dialog != NULL)
166 gtk_widget_hide(progress->dialog);
167 progress->closed = TRUE;
168 gnc_progress_maybe_destroy(progress);
179 destroy_cb(GtkWidget *
object, gpointer data)
181 GNCProgressDialog *progress = data;
183 g_return_if_fail(progress);
186 progress->cancel_func = NULL;
187 if (progress->cancel_scm_func != SCM_UNDEFINED)
188 scm_gc_unprotect_object(progress->cancel_scm_func);
189 progress->cancel_scm_func = SCM_UNDEFINED;
196 gnc_progress_dialog_create(GtkWidget * parent, GNCProgressDialog *progress)
201 g_return_if_fail(progress);
203 builder = gtk_builder_new();
204 gnc_builder_add_from_file (builder,
"dialog-progress.glade",
"progress_dialog");
207 dialog = GTK_WIDGET(gtk_builder_get_object (builder,
"progress_dialog"));
208 progress->dialog = dialog;
211 gtk_widget_set_name (GTK_WIDGET(dialog),
"gnc-id-progress");
215 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(parent));
217 g_signal_connect(G_OBJECT(dialog),
"delete_event", G_CALLBACK(delete_cb), progress);
219 g_signal_connect(G_OBJECT(dialog),
"destroy", G_CALLBACK(destroy_cb), progress);
221 progress->primary_label = GTK_WIDGET(gtk_builder_get_object (builder,
"primary_label"));
222 gtk_widget_hide(progress->primary_label);
224 progress->secondary_label = GTK_WIDGET(gtk_builder_get_object (builder,
"secondary_label"));
225 gtk_widget_hide(progress->secondary_label);
227 progress->progress_bar = GTK_WIDGET(gtk_builder_get_object (builder,
"progress_bar"));
228 progress->total_offset = 0;
229 progress->total_weight = 1;
230 progress->bar_value = 0;
232 progress->sub_label = GTK_WIDGET(gtk_builder_get_object (builder,
"sub_label"));
233 gtk_widget_hide(progress->sub_label);
235 progress->log = GTK_WIDGET(gtk_builder_get_object (builder,
"progress_log"));
236 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object (builder,
"progress_log_window")));
238 progress->ok_button = GTK_WIDGET(gtk_builder_get_object (builder,
"ok_button"));
240 g_signal_connect(progress->ok_button,
"clicked",
241 G_CALLBACK(ok_cb), progress);
243 if (!progress->use_ok_button)
244 gtk_widget_hide(progress->ok_button);
246 progress->cancel_button = GTK_WIDGET(gtk_builder_get_object (builder,
"cancel_button"));
248 g_signal_connect(progress->cancel_button,
"clicked",
249 G_CALLBACK(cancel_cb), progress);
251 progress->cancel_func = NULL;
252 progress->user_data = NULL;
254 progress->cancel_scm_func = SCM_UNDEFINED;
256 progress->closed = FALSE;
257 progress->finished = FALSE;
258 progress->destroyed = FALSE;
259 progress->title_set = FALSE;
261 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, progress);
262 g_object_unref(G_OBJECT(builder));
269 GNCProgressDialog *progress;
271 progress = g_new0(GNCProgressDialog, 1);
273 progress->use_ok_button = use_ok_button;
275 gnc_progress_dialog_create(parent, progress);
277 gtk_widget_show(progress->dialog);
289 GtkLabel *suboperation,
292 GNCProgressDialog *progress;
294 progress = g_new0(GNCProgressDialog, 1);
297 progress->dialog = NULL;
298 progress->primary_label = GTK_WIDGET(primary);
299 progress->secondary_label = GTK_WIDGET(secondary);
300 progress->progress_bar = GTK_WIDGET(bar);
301 progress->sub_label = GTK_WIDGET(suboperation);
302 progress->log = GTK_WIDGET(log);
303 progress->ok_button = NULL;
304 progress->cancel_button = NULL;
307 progress->total_offset = 0;
308 progress->total_weight = 1;
309 progress->bar_value = 0;
310 progress->cancel_func = NULL;
311 progress->user_data = NULL;
312 progress->cancel_scm_func = SCM_UNDEFINED;
313 progress->use_ok_button = FALSE;
314 progress->closed = FALSE;
315 progress->finished = FALSE;
316 progress->destroyed = FALSE;
317 progress->title_set = FALSE;
326 g_return_if_fail(progress);
328 if (!progress->dialog)
334 gtk_window_set_title(GTK_WINDOW(progress->dialog), title);
336 progress->title_set = TRUE;
346 g_return_if_fail(progress);
348 if (progress->primary_label == NULL)
351 if (str == NULL || *str ==
'\0')
352 gtk_widget_hide(progress->primary_label);
356 char *markup = g_markup_printf_escaped(
"<span weight=\"bold\" size=\"larger\">%s</span>", str);
358 gtk_label_set_markup(GTK_LABEL(progress->primary_label), markup);
360 gtk_widget_show(progress->primary_label);
371 g_return_if_fail(progress);
373 if (progress->primary_label == NULL)
376 if (heading == NULL || *heading ==
'\0')
377 gtk_widget_hide(progress->primary_label);
380 gtk_label_set_text(GTK_LABEL(progress->primary_label), heading);
381 gtk_widget_show(progress->primary_label);
392 g_return_if_fail(progress);
394 if (progress->secondary_label == NULL)
397 if (str == NULL || *str ==
'\0')
398 gtk_widget_hide(progress->secondary_label);
401 gtk_label_set_text(GTK_LABEL(progress->secondary_label), str);
402 gtk_widget_show(progress->secondary_label);
413 g_return_if_fail(progress);
415 if (progress->sub_label == NULL)
418 if (str == NULL || *str ==
'\0')
419 gtk_widget_hide(progress->sub_label);
423 char *markup = g_markup_printf_escaped(
"<span style=\"italic\">%s</span>", str);
425 gtk_label_set_markup(GTK_LABEL(progress->sub_label), markup);
427 gtk_widget_show(progress->sub_label);
439 g_return_if_fail(progress);
441 if (progress->log == NULL)
445 buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(progress->log));
446 gtk_text_buffer_set_text(buf,
"", -1);
447 gtk_text_buffer_set_modified(buf, FALSE);
450 gtk_widget_show(progress->log);
451 gtk_widget_show(gtk_widget_get_parent(progress->log));
463 g_return_if_fail(progress);
465 if (progress->log == NULL || !str || !*str)
469 buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(progress->log));
470 gtk_text_buffer_get_end_iter(buf, &iter);
471 gtk_text_buffer_insert(buf, &iter, str, -1);
482 g_return_if_fail(progress);
484 suffix = g_strconcat(
" ", _(
"(paused)"), NULL);
486 if (progress->sub_label && gtk_widget_get_visible(progress->sub_label))
488 const gchar *txt = gtk_label_get_text(GTK_LABEL(progress->sub_label));
490 if (txt && !g_str_has_suffix(txt, suffix))
492 gchar *newtxt = g_strconcat(txt, suffix, NULL);
497 else if (progress->dialog)
499 const gchar *txt = gtk_window_get_title(GTK_WINDOW(progress->dialog));
501 if (txt && !g_str_has_suffix(txt, suffix))
503 gchar *newtxt = g_strconcat(txt, suffix, NULL);
504 gtk_window_set_title(GTK_WINDOW(progress->dialog), newtxt);
508 else if (progress->primary_label &&
509 gtk_widget_get_visible(progress->primary_label))
511 const gchar *txt = gtk_label_get_text(GTK_LABEL(progress->primary_label));
513 if (txt && !g_str_has_suffix(txt, suffix))
515 gchar *newtxt = g_strconcat(txt, suffix, NULL);
531 g_return_if_fail(progress);
533 suffix = g_strconcat(
" ", _(
"(paused)"), NULL);
536 if (progress->sub_label)
538 const gchar *txt = gtk_label_get_text(GTK_LABEL(progress->sub_label));
540 if (txt && g_str_has_suffix(txt, suffix))
542 gchar *newtxt = g_strndup(txt, strlen(txt) - strlen(suffix));
549 if (progress->dialog)
551 const gchar *txt = gtk_window_get_title(GTK_WINDOW(progress->dialog));
553 if (txt && g_str_has_suffix(txt, suffix))
555 gchar *newtxt = g_strndup(txt, strlen(txt) - strlen(suffix));
556 gtk_window_set_title(GTK_WINDOW(progress->dialog), newtxt);
562 if (progress->primary_label)
564 const gchar *txt = gtk_label_get_text(GTK_LABEL(progress->primary_label));
566 if (txt && g_str_has_suffix(txt, suffix))
568 gchar *newtxt = g_strndup(txt, strlen(txt) - strlen(suffix));
582 GNCProgressCancelFunc cancel_func,
585 g_return_if_fail(progress);
587 if (progress->cancel_button == NULL)
590 progress->cancel_func = cancel_func;
591 progress->user_data = user_data;
594 gtk_widget_show(progress->cancel_button);
602 g_return_if_fail(progress);
604 if (progress->cancel_button == NULL)
607 if (progress->cancel_scm_func != SCM_UNDEFINED)
608 scm_gc_unprotect_object(progress->cancel_scm_func);
610 if (scm_is_procedure(cancel_scm_func))
612 progress->cancel_scm_func = cancel_scm_func;
613 scm_gc_protect_object(cancel_scm_func);
614 gtk_widget_show(progress->cancel_button);
617 progress->cancel_scm_func = SCM_UNDEFINED;
626 g_return_if_fail(progress);
629 bar = GTK_PROGRESS_BAR(progress->progress_bar);
636 gtk_progress_bar_pulse(bar);
639 progress->bar_value = value > 0 ? value : 0;
640 gtk_progress_bar_set_fraction(bar,
641 progress->total_offset + progress->bar_value * progress->total_weight);
654 g_return_val_if_fail(progress, 0);
655 g_return_val_if_fail(weight > 0, 0);
658 bar = GTK_PROGRESS_BAR(progress->progress_bar);
664 newbar->offset = progress->bar_value;
665 if (newbar->offset + weight > 1)
667 newbar->weight = 1 - newbar->offset;
669 newbar->weight = weight;
670 progress->bars = g_list_prepend(progress->bars, newbar);
673 progress->total_offset = gtk_progress_bar_get_fraction(bar);
674 progress->total_weight *= newbar->weight;
677 progress->bar_value = 0;
679 return g_list_length(progress->bars);
688 g_return_val_if_fail(progress, 0);
691 if (progress->progress_bar == NULL || progress->bars == NULL)
695 bar = progress->bars->data;
696 progress->bars = g_list_delete_link(progress->bars, progress->bars);
699 progress->bar_value = bar->offset + bar->weight * progress->bar_value;
702 if (progress->bars == NULL)
704 progress->total_offset = 0;
705 progress->total_weight = 1;
709 progress->total_offset -= bar->offset *
710 ((
VirtualBar *) progress->bars->data)->weight;
711 progress->total_weight /= bar->weight;
715 if (progress->bars == NULL)
717 return g_list_length(progress->bars);
732 g_return_if_fail(progress);
745 while (gtk_events_pending())
746 gtk_main_iteration();
753 g_return_if_fail(progress);
755 if (!progress->use_ok_button)
757 if (progress->dialog != NULL)
758 gtk_widget_hide(progress->dialog);
759 progress->closed = TRUE;
762 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress->progress_bar), 1.0);
764 gtk_widget_set_sensitive(progress->ok_button, TRUE);
765 gtk_widget_set_sensitive(progress->cancel_button, FALSE);
767 if (gtk_widget_get_visible(progress->primary_label))
770 if (!progress->title_set)
771 gtk_window_set_title(GTK_WINDOW(progress->dialog), _(
"Complete"));
773 gtk_window_set_modal(GTK_WINDOW(progress->dialog), FALSE);
775 progress->finished = TRUE;
784 g_return_if_fail(progress);
787 progress->cancel_func = NULL;
788 if (progress->cancel_scm_func != SCM_UNDEFINED)
789 scm_gc_unprotect_object(progress->cancel_scm_func);
790 progress->cancel_scm_func = SCM_UNDEFINED;
792 if (!progress->finished)
794 if (progress->dialog != NULL)
795 gtk_widget_hide(progress->dialog);
796 progress->closed = TRUE;
799 progress->destroyed = TRUE;
801 gnc_progress_maybe_destroy(progress);
void gnc_progress_dialog_set_heading(GNCProgressDialog *progress, const char *heading)
Set the primary text of the progress dialog.
void gnc_progress_dialog_set_secondary(GNCProgressDialog *progress, const gchar *str)
Set the secondary text of the progress dialog.
void gnc_progress_dialog_append_log(GNCProgressDialog *progress, const gchar *str)
Append str to the progress log.
void gnc_progress_dialog_destroy(GNCProgressDialog *progress)
Destroy the dialog.
void gnc_progress_dialog_set_value(GNCProgressDialog *progress, gdouble value)
Set the fraction of the progress bar to fill, where 0 is empty and 1 is full.
API for displaying progress of long-running operations.
void gnc_progress_dialog_reset_value(GNCProgressDialog *progress)
Pop up to the top level and clear the progress bar.
void gnc_progress_dialog_set_cancel_func(GNCProgressDialog *progress, GNCProgressCancelFunc cancel_func, gpointer user_data)
Show a Cancel button and set the C function which will be called when it is pressed by the user...
GNCProgressDialog * gnc_progress_dialog_custom(GtkLabel *primary, GtkLabel *secondary, GtkProgressBar *bar, GtkLabel *suboperation, GtkTextView *log)
Creates a dialog for displaying the progress of an activity using existing widgets.
GNCProgressDialog * gnc_progress_dialog_new(GtkWidget *parent, gboolean use_ok_button)
Displays a pop-up dialog for showing the progress of a long-running activity.
void gnc_progress_dialog_set_sub(GNCProgressDialog *progress, const gchar *str)
Set the suboperation text of the progress dialog.
void gnc_progress_dialog_finish(GNCProgressDialog *progress)
Set the progress meter to fully complete, change the heading, if any, to "Complete", enable the 'OK' button, and make the dialog non-modal.
void gnc_progress_dialog_pause(GNCProgressDialog *progress)
Show that progress has been paused by appending "(paused)" to the suboperation text, the window title, or the primary text.
void gnc_progress_dialog_reset_log(GNCProgressDialog *progress)
Show the progress log and delete any existing text.
void gnc_progress_dialog_set_primary(GNCProgressDialog *progress, const gchar *str)
Set the primary text of the progress dialog.
void gnc_progress_dialog_resume(GNCProgressDialog *progress)
Remove any indication that progress has paused by removing any existing "(paused)" suffix from the su...
guint gnc_progress_dialog_pop_full(GNCProgressDialog *progress)
Fills the current progress bar, then calls gnc_progress_dialog_pop().
guint gnc_progress_dialog_pop(GNCProgressDialog *progress)
Moves up one level in the stack of virtual bars.
void gnc_progress_dialog_update(GNCProgressDialog *progress)
Update the GUI of the progress dialog, and call any pending cancel callbacks.
guint gnc_progress_dialog_push(GNCProgressDialog *progress, gdouble weight)
Create a new "virtual" progress bar that, as it becomes full, will fill the current bar by the fracti...
void gnc_progress_dialog_set_title(GNCProgressDialog *progress, const char *title)
Set the title of a pop-up progress dialog.
void gnc_progress_dialog_set_cancel_scm_func(GNCProgressDialog *progress, SCM cancel_scm_func)
Show a Cancel button and set the Guile procedure that will be called when it is pressed by the user...