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;
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)
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)
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)
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(GtkObject *
object, gpointer 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;
202 g_return_if_fail(progress);
204 builder = gtk_builder_new();
205 gnc_builder_add_from_file (builder,
"dialog-progress.glade",
"Progress Dialog");
208 dialog = GTK_WIDGET(gtk_builder_get_object (builder,
"Progress Dialog"));
209 progress->dialog = dialog;
210 tdo = GTK_OBJECT(dialog);
214 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(parent));
216 g_signal_connect(tdo,
"delete_event", G_CALLBACK(delete_cb), progress);
218 g_signal_connect(tdo,
"destroy", G_CALLBACK(destroy_cb), progress);
220 progress->primary_label = GTK_WIDGET(gtk_builder_get_object (builder,
"primary_label"));
221 gtk_widget_hide(progress->primary_label);
223 progress->secondary_label = GTK_WIDGET(gtk_builder_get_object (builder,
"secondary_label"));
224 gtk_widget_hide(progress->secondary_label);
226 progress->progress_bar = GTK_WIDGET(gtk_builder_get_object (builder,
"progress_bar"));
227 progress->total_offset = 0;
228 progress->total_weight = 1;
229 progress->bar_value = 0;
231 progress->sub_label = GTK_WIDGET(gtk_builder_get_object (builder,
"sub_label"));
232 gtk_widget_hide(progress->sub_label);
234 progress->log = GTK_WIDGET(gtk_builder_get_object (builder,
"progress_log"));
235 gtk_widget_hide(GTK_WIDGET(gtk_builder_get_object (builder,
"progress_log_window")));
237 progress->ok_button = GTK_WIDGET(gtk_builder_get_object (builder,
"ok_button"));
239 g_signal_connect(progress->ok_button,
"clicked",
240 G_CALLBACK(ok_cb), progress);
242 if (!progress->use_ok_button)
243 gtk_widget_hide(progress->ok_button);
245 progress->cancel_button = GTK_WIDGET(gtk_builder_get_object (builder,
"cancel_button"));
247 g_signal_connect(progress->cancel_button,
"clicked",
248 G_CALLBACK(cancel_cb), progress);
250 progress->cancel_func = NULL;
251 progress->user_data = NULL;
253 progress->cancel_scm_func = SCM_UNDEFINED;
255 progress->closed = FALSE;
256 progress->finished = FALSE;
257 progress->destroyed = FALSE;
258 progress->title_set = FALSE;
260 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, progress);
261 g_object_unref(G_OBJECT(builder));
272 progress->use_ok_button = use_ok_button;
274 gnc_progress_dialog_create(parent, progress);
276 gtk_widget_show(progress->dialog);
288 GtkLabel *suboperation,
296 progress->dialog = NULL;
297 progress->primary_label = GTK_WIDGET(primary);
298 progress->secondary_label = GTK_WIDGET(secondary);
299 progress->progress_bar = GTK_WIDGET(bar);
300 progress->sub_label = GTK_WIDGET(suboperation);
301 progress->log = GTK_WIDGET(log);
302 progress->ok_button = NULL;
303 progress->cancel_button = NULL;
306 progress->total_offset = 0;
307 progress->total_weight = 1;
308 progress->bar_value = 0;
309 progress->cancel_func = NULL;
310 progress->user_data = NULL;
311 progress->cancel_scm_func = SCM_UNDEFINED;
312 progress->use_ok_button = FALSE;
313 progress->closed = FALSE;
314 progress->finished = FALSE;
315 progress->destroyed = FALSE;
316 progress->title_set = FALSE;
325 g_return_if_fail(progress);
327 if (!progress->dialog)
333 gtk_window_set_title(GTK_WINDOW(progress->dialog), title);
335 progress->title_set = TRUE;
345 g_return_if_fail(progress);
347 if (progress->primary_label == NULL)
350 if (str == NULL || *str ==
'\0')
351 gtk_widget_hide(progress->primary_label);
355 char *markup = g_markup_printf_escaped(
"<span weight=\"bold\" size=\"larger\">%s</span>", str);
357 gtk_label_set_markup(GTK_LABEL(progress->primary_label), markup);
359 gtk_widget_show(progress->primary_label);
370 g_return_if_fail(progress);
372 if (progress->primary_label == NULL)
375 if (heading == NULL || *heading ==
'\0')
376 gtk_widget_hide(progress->primary_label);
379 gtk_label_set_text(GTK_LABEL(progress->primary_label), heading);
380 gtk_widget_show(progress->primary_label);
391 g_return_if_fail(progress);
393 if (progress->secondary_label == NULL)
396 if (str == NULL || *str ==
'\0')
397 gtk_widget_hide(progress->secondary_label);
400 gtk_label_set_text(GTK_LABEL(progress->secondary_label), str);
401 gtk_widget_show(progress->secondary_label);
412 g_return_if_fail(progress);
414 if (progress->sub_label == NULL)
417 if (str == NULL || *str ==
'\0')
418 gtk_widget_hide(progress->sub_label);
422 char *markup = g_markup_printf_escaped(
"<span style=\"italic\">%s</span>", str);
424 gtk_label_set_markup(GTK_LABEL(progress->sub_label), markup);
426 gtk_widget_show(progress->sub_label);
438 g_return_if_fail(progress);
440 if (progress->log == NULL)
444 buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(progress->log));
445 gtk_text_buffer_set_text(buf,
"", -1);
446 gtk_text_buffer_set_modified(buf, FALSE);
449 gtk_widget_show(progress->log);
450 gtk_widget_show(gtk_widget_get_parent(progress->log));
462 g_return_if_fail(progress);
464 if (progress->log == NULL || !str || !*str)
468 buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(progress->log));
469 gtk_text_buffer_get_end_iter(buf, &iter);
470 gtk_text_buffer_insert(buf, &iter, str, -1);
481 g_return_if_fail(progress);
483 suffix = g_strconcat(
" ", _(
"(paused)"), NULL);
485 if (progress->sub_label && gtk_widget_get_visible(progress->sub_label))
487 const gchar *txt = gtk_label_get_text(GTK_LABEL(progress->sub_label));
489 if (txt && !g_str_has_suffix(txt, suffix))
491 gchar *newtxt = g_strconcat(txt, suffix, NULL);
496 else if (progress->dialog)
498 const gchar *txt = gtk_window_get_title(GTK_WINDOW(progress->dialog));
500 if (txt && !g_str_has_suffix(txt, suffix))
502 gchar *newtxt = g_strconcat(txt, suffix, NULL);
503 gtk_window_set_title(GTK_WINDOW(progress->dialog), newtxt);
507 else if (progress->primary_label &&
508 gtk_widget_get_visible(progress->primary_label))
510 const gchar *txt = gtk_label_get_text(GTK_LABEL(progress->primary_label));
512 if (txt && !g_str_has_suffix(txt, suffix))
514 gchar *newtxt = g_strconcat(txt, suffix, NULL);
530 g_return_if_fail(progress);
532 suffix = g_strconcat(
" ", _(
"(paused)"), NULL);
535 if (progress->sub_label)
537 const gchar *txt = gtk_label_get_text(GTK_LABEL(progress->sub_label));
539 if (txt && g_str_has_suffix(txt, suffix))
541 gchar *newtxt = g_strndup(txt, strlen(txt) - strlen(suffix));
548 if (progress->dialog)
550 const gchar *txt = gtk_window_get_title(GTK_WINDOW(progress->dialog));
552 if (txt && g_str_has_suffix(txt, suffix))
554 gchar *newtxt = g_strndup(txt, strlen(txt) - strlen(suffix));
555 gtk_window_set_title(GTK_WINDOW(progress->dialog), newtxt);
561 if (progress->primary_label)
563 const gchar *txt = gtk_label_get_text(GTK_LABEL(progress->primary_label));
565 if (txt && g_str_has_suffix(txt, suffix))
567 gchar *newtxt = g_strndup(txt, strlen(txt) - strlen(suffix));
581 GNCProgressCancelFunc cancel_func,
584 g_return_if_fail(progress);
586 if (progress->cancel_button == NULL)
589 progress->cancel_func = cancel_func;
590 progress->user_data = user_data;
593 gtk_widget_show(progress->cancel_button);
601 g_return_if_fail(progress);
603 if (progress->cancel_button == NULL)
606 if (progress->cancel_scm_func != SCM_UNDEFINED)
607 scm_gc_unprotect_object(progress->cancel_scm_func);
609 if (scm_is_procedure(cancel_scm_func))
611 progress->cancel_scm_func = cancel_scm_func;
612 scm_gc_protect_object(cancel_scm_func);
613 gtk_widget_show(progress->cancel_button);
616 progress->cancel_scm_func = SCM_UNDEFINED;
625 g_return_if_fail(progress);
628 bar = GTK_PROGRESS_BAR(progress->progress_bar);
635 gtk_progress_bar_pulse(bar);
638 progress->bar_value = value > 0 ? value : 0;
639 gtk_progress_bar_set_fraction(bar,
640 progress->total_offset + progress->bar_value * progress->total_weight);
653 g_return_val_if_fail(progress, 0);
654 g_return_val_if_fail(weight > 0, 0);
657 bar = GTK_PROGRESS_BAR(progress->progress_bar);
663 newbar->offset = progress->bar_value;
664 if (newbar->offset + weight > 1)
666 newbar->weight = 1 - newbar->offset;
668 newbar->weight = weight;
669 progress->bars = g_list_prepend(progress->bars, newbar);
672 progress->total_offset = gtk_progress_bar_get_fraction(bar);
673 progress->total_weight *= newbar->weight;
676 progress->bar_value = 0;
678 return g_list_length(progress->bars);
687 g_return_val_if_fail(progress, 0);
690 if (progress->progress_bar == NULL || progress->bars == NULL)
694 bar = progress->bars->data;
695 progress->bars = g_list_delete_link(progress->bars, progress->bars);
698 progress->bar_value = bar->offset + bar->weight * progress->bar_value;
701 if (progress->bars == NULL)
703 progress->total_offset = 0;
704 progress->total_weight = 1;
708 progress->total_offset -= bar->offset *
709 ((
VirtualBar *) progress->bars->data)->weight;
710 progress->total_weight /= bar->weight;
714 if (progress->bars == NULL)
716 return g_list_length(progress->bars);
731 g_return_if_fail(progress);
744 while (gtk_events_pending())
745 gtk_main_iteration();
752 g_return_if_fail(progress);
754 if (!progress->use_ok_button)
756 if (progress->dialog != NULL)
757 gtk_widget_hide(progress->dialog);
758 progress->closed = TRUE;
761 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress->progress_bar), 1.0);
763 gtk_widget_set_sensitive(progress->ok_button, TRUE);
764 gtk_widget_set_sensitive(progress->cancel_button, FALSE);
766 if (gtk_widget_get_visible(progress->primary_label))
769 if (!progress->title_set)
770 gtk_window_set_title(GTK_WINDOW(progress->dialog), _(
"Complete"));
772 gtk_window_set_modal(GTK_WINDOW(progress->dialog), FALSE);
774 progress->finished = TRUE;
783 g_return_if_fail(progress);
786 progress->cancel_func = NULL;
787 if (progress->cancel_scm_func != SCM_UNDEFINED)
788 scm_gc_unprotect_object(progress->cancel_scm_func);
789 progress->cancel_scm_func = SCM_UNDEFINED;
791 if (!progress->finished)
793 if (progress->dialog != NULL)
794 gtk_widget_hide(progress->dialog);
795 progress->closed = TRUE;
798 progress->destroyed = TRUE;
800 gnc_progress_maybe_destroy(progress);
void gnc_progress_dialog_set_heading(GNCProgressDialog *progress, const char *heading)
void gnc_progress_dialog_set_secondary(GNCProgressDialog *progress, const gchar *str)
void gnc_progress_dialog_append_log(GNCProgressDialog *progress, const gchar *str)
void gnc_progress_dialog_destroy(GNCProgressDialog *progress)
void gnc_progress_dialog_set_value(GNCProgressDialog *progress, gdouble value)
API for displaying progress of long-running operations.
void gnc_progress_dialog_reset_value(GNCProgressDialog *progress)
void gnc_progress_dialog_set_cancel_func(GNCProgressDialog *progress, GNCProgressCancelFunc cancel_func, gpointer user_data)
GNCProgressDialog * gnc_progress_dialog_custom(GtkLabel *primary, GtkLabel *secondary, GtkProgressBar *bar, GtkLabel *suboperation, GtkTextView *log)
GNCProgressDialog * gnc_progress_dialog_new(GtkWidget *parent, gboolean use_ok_button)
void gnc_progress_dialog_set_sub(GNCProgressDialog *progress, const gchar *str)
void gnc_progress_dialog_finish(GNCProgressDialog *progress)
void gnc_progress_dialog_pause(GNCProgressDialog *progress)
void gnc_progress_dialog_reset_log(GNCProgressDialog *progress)
void gnc_progress_dialog_set_primary(GNCProgressDialog *progress, const gchar *str)
void gnc_progress_dialog_resume(GNCProgressDialog *progress)
guint gnc_progress_dialog_pop_full(GNCProgressDialog *progress)
guint gnc_progress_dialog_pop(GNCProgressDialog *progress)
void gnc_progress_dialog_update(GNCProgressDialog *progress)
guint gnc_progress_dialog_push(GNCProgressDialog *progress, gdouble weight)
void gnc_progress_dialog_set_title(GNCProgressDialog *progress, const char *title)
void gnc_progress_dialog_set_cancel_scm_func(GNCProgressDialog *progress, SCM cancel_scm_func)