GnuCash  5.6-150-g038405b370+
dialog-progress.c
1 /********************************************************************\
2  * dialog-progress.c -- GnuCash progress dialog *
3  * Copyright (C) 2000 Dave Peticolas *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License*
16  * along with this program; if not, contact: *
17  * *
18  * Free Software Foundation Voice: +1-617-542-5942 *
19  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20  * Boston, MA 02110-1301, USA gnu@gnu.org *
21  * *
22 \********************************************************************/
23 
24 #include <config.h>
25 
26 #include <gtk/gtk.h>
27 #include <glib/gi18n.h>
28 #include <libguile.h>
29 #include "guile-mappings.h"
30 
31 #include "dialog-progress.h"
32 #include "dialog-utils.h"
33 
34 
36 {
37  GtkWidget *dialog;
38 
39  GtkWidget *primary_label;
40  GtkWidget *secondary_label;
41  GtkWidget *progress_bar;
42  GtkWidget *sub_label;
43  GtkWidget *log;
44 
45  GtkWidget *ok_button;
46  GtkWidget *cancel_button;
47 
48  /* The stack of virtual progress bars. */
49  GList *bars;
50  /* The fraction of the current bar that is filled. */
51  gdouble bar_value;
52  /* The value of the real (top-level) bar before the last push. */
53  gdouble total_offset;
54  /* The product of all weights in the stack. */
55  gdouble total_weight;
56 
57  GNCProgressCancelFunc cancel_func;
58  gpointer user_data;
59 
60  SCM cancel_scm_func;
61 
62  gboolean use_ok_button;
63  gboolean closed;
64  gboolean finished;
65  gboolean destroyed;
66  gboolean title_set;
67 };
68 
69 typedef struct
70 {
71  gdouble offset;
72  gdouble weight;
73 } VirtualBar;
74 
75 static void
76 gnc_progress_maybe_destroy(GNCProgressDialog *progress)
77 {
78  g_return_if_fail(progress);
79 
80  if (!(progress->closed && progress->destroyed))
81  return;
82 
83  if (progress->dialog != NULL)
84  gtk_widget_destroy(progress->dialog);
85 }
86 
87 
88 static void
89 ok_cb(GtkWidget * widget, gpointer data)
90 {
91  GNCProgressDialog *progress = data;
92 
93  g_return_if_fail(progress);
94 
95  if (progress->dialog != NULL)
96  gtk_widget_hide(progress->dialog);
97  progress->closed = TRUE;
98  gnc_progress_maybe_destroy(progress);
99 }
100 
101 
102 static void
103 cancel_cb(GtkWidget * widget, gpointer data)
104 {
105  GNCProgressDialog *progress = data;
106 
107  g_return_if_fail(progress);
108 
109  if (progress->cancel_func && !progress->cancel_func(progress->user_data))
110  return;
111 
112  if (progress->cancel_scm_func != SCM_UNDEFINED)
113  {
114  SCM result;
115 
116  result = scm_call_0(progress->cancel_scm_func);
117 
118  if (!scm_is_true(result))
119  return;
120  }
121 
122  if (progress->dialog != NULL)
123  gtk_widget_hide(progress->dialog);
124  progress->closed = TRUE;
125  gnc_progress_maybe_destroy(progress);
126 }
127 
128 
129 static gboolean
130 delete_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
131 {
132  GNCProgressDialog *progress = data;
133 
134  g_return_val_if_fail(progress, TRUE);
135 
136  if (progress->finished)
137  {
138  if (progress->dialog != NULL)
139  gtk_widget_hide(progress->dialog);
140  progress->closed = TRUE;
141  gnc_progress_maybe_destroy(progress);
142  return TRUE;
143  }
144 
145  if (progress->cancel_func)
146  {
147  if (progress->cancel_func(progress->user_data))
148  {
149  if (progress->dialog != NULL)
150  gtk_widget_hide(progress->dialog);
151  progress->closed = TRUE;
152  gnc_progress_maybe_destroy(progress);
153  return TRUE;
154  }
155  }
156 
157  if (progress->cancel_scm_func != SCM_UNDEFINED)
158  {
159  SCM result;
160 
161  result = scm_call_0(progress->cancel_scm_func);
162 
163  if (scm_is_true(result))
164  {
165  if (progress->dialog != NULL)
166  gtk_widget_hide(progress->dialog);
167  progress->closed = TRUE;
168  gnc_progress_maybe_destroy(progress);
169  return TRUE;
170  }
171  }
172 
173  /* Don't delete the window, wait for gnc_progress_dialog_destroy. */
174  return TRUE;
175 }
176 
177 
178 static void
179 destroy_cb(GtkWidget *object, gpointer data)
180 {
181  GNCProgressDialog *progress = data;
182 
183  g_return_if_fail(progress);
184 
185  /* Make sure the callbacks aren't invoked */
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;
190 
191  g_free(progress);
192 }
193 
194 
195 static void
196 gnc_progress_dialog_create(GtkWidget * parent, GNCProgressDialog *progress)
197 {
198  GtkWidget *dialog;
199  GtkBuilder *builder;
200 
201  g_return_if_fail(progress);
202 
203  builder = gtk_builder_new();
204  gnc_builder_add_from_file (builder, "dialog-progress.glade", "progress_dialog");
205 
206 
207  dialog = GTK_WIDGET(gtk_builder_get_object (builder, "progress_dialog"));
208  progress->dialog = dialog;
209 
210  // Set the name for this dialog so it can be easily manipulated with css
211  gtk_widget_set_name (GTK_WIDGET(dialog), "gnc-id-progress");
212 
213  /* parent */
214  if (parent != NULL)
215  gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(parent));
216 
217  g_signal_connect(G_OBJECT(dialog), "delete_event", G_CALLBACK(delete_cb), progress);
218 
219  g_signal_connect(G_OBJECT(dialog), "destroy", G_CALLBACK(destroy_cb), progress);
220 
221  progress->primary_label = GTK_WIDGET(gtk_builder_get_object (builder, "primary_label"));
222  gtk_widget_hide(progress->primary_label);
223 
224  progress->secondary_label = GTK_WIDGET(gtk_builder_get_object (builder, "secondary_label"));
225  gtk_widget_hide(progress->secondary_label);
226 
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;
231 
232  progress->sub_label = GTK_WIDGET(gtk_builder_get_object (builder, "sub_label"));
233  gtk_widget_hide(progress->sub_label);
234 
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")));
237 
238  progress->ok_button = GTK_WIDGET(gtk_builder_get_object (builder, "ok_button"));
239 
240  g_signal_connect(progress->ok_button, "clicked",
241  G_CALLBACK(ok_cb), progress);
242 
243  if (!progress->use_ok_button)
244  gtk_widget_hide(progress->ok_button);
245 
246  progress->cancel_button = GTK_WIDGET(gtk_builder_get_object (builder, "cancel_button"));
247 
248  g_signal_connect(progress->cancel_button, "clicked",
249  G_CALLBACK(cancel_cb), progress);
250 
251  progress->cancel_func = NULL;
252  progress->user_data = NULL;
253 
254  progress->cancel_scm_func = SCM_UNDEFINED;
255 
256  progress->closed = FALSE;
257  progress->finished = FALSE;
258  progress->destroyed = FALSE;
259  progress->title_set = FALSE;
260 
261  gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, progress);
262  g_object_unref(G_OBJECT(builder));
263 }
264 
265 
266 GNCProgressDialog *
267 gnc_progress_dialog_new(GtkWidget * parent, gboolean use_ok_button)
268 {
269  GNCProgressDialog *progress;
270 
271  progress = g_new0(GNCProgressDialog, 1);
272 
273  progress->use_ok_button = use_ok_button;
274 
275  gnc_progress_dialog_create(parent, progress);
276 
277  gtk_widget_show(progress->dialog);
278 
279  gnc_progress_dialog_update(progress);
280 
281  return progress;
282 }
283 
284 
285 GNCProgressDialog *
286 gnc_progress_dialog_custom(GtkLabel *primary,
287  GtkLabel *secondary,
288  GtkProgressBar *bar,
289  GtkLabel *suboperation,
290  GtkTextView *log)
291 {
292  GNCProgressDialog *progress;
293 
294  progress = g_new0(GNCProgressDialog, 1);
295 
296  /* Set up widgets. */
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;
305 
306  /* Initialize all other items. */
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;
318 
319  return progress;
320 }
321 
322 
323 void
324 gnc_progress_dialog_set_title(GNCProgressDialog *progress, const char *title)
325 {
326  g_return_if_fail(progress);
327 
328  if (!progress->dialog)
329  return;
330 
331  if (title == NULL)
332  title = "";
333 
334  gtk_window_set_title(GTK_WINDOW(progress->dialog), title);
335 
336  progress->title_set = TRUE;
337 
338  gnc_progress_dialog_update(progress);
339 }
340 
341 
342 void
343 gnc_progress_dialog_set_primary(GNCProgressDialog *progress,
344  const gchar *str)
345 {
346  g_return_if_fail(progress);
347 
348  if (progress->primary_label == NULL)
349  return;
350 
351  if (str == NULL || *str == '\0')
352  gtk_widget_hide(progress->primary_label);
353  else
354  {
355  /* Display the primary text with the HIG-recommended style. */
356  char *markup = g_markup_printf_escaped("<span weight=\"bold\" size=\"larger\">%s</span>", str);
357 
358  gtk_label_set_markup(GTK_LABEL(progress->primary_label), markup);
359  g_free(markup);
360  gtk_widget_show(progress->primary_label);
361  }
362 
363  gnc_progress_dialog_update(progress);
364 }
365 
366 
367 void
368 gnc_progress_dialog_set_heading(GNCProgressDialog *progress,
369  const char *heading)
370 {
371  g_return_if_fail(progress);
372 
373  if (progress->primary_label == NULL)
374  return;
375 
376  if (heading == NULL || *heading == '\0')
377  gtk_widget_hide(progress->primary_label);
378  else
379  {
380  gtk_label_set_text(GTK_LABEL(progress->primary_label), heading);
381  gtk_widget_show(progress->primary_label);
382  }
383 
384  gnc_progress_dialog_update(progress);
385 }
386 
387 
388 void
389 gnc_progress_dialog_set_secondary(GNCProgressDialog *progress,
390  const gchar *str)
391 {
392  g_return_if_fail(progress);
393 
394  if (progress->secondary_label == NULL)
395  return;
396 
397  if (str == NULL || *str == '\0')
398  gtk_widget_hide(progress->secondary_label);
399  else
400  {
401  gtk_label_set_text(GTK_LABEL(progress->secondary_label), str);
402  gtk_widget_show(progress->secondary_label);
403  }
404 
405  gnc_progress_dialog_update(progress);
406 }
407 
408 
409 void
410 gnc_progress_dialog_set_sub(GNCProgressDialog *progress,
411  const gchar *str)
412 {
413  g_return_if_fail(progress);
414 
415  if (progress->sub_label == NULL)
416  return;
417 
418  if (str == NULL || *str == '\0')
419  gtk_widget_hide(progress->sub_label);
420  else
421  {
422  /* Display the suboperation text with the HIG-recommended style. */
423  char *markup = g_markup_printf_escaped("<span style=\"italic\">%s</span>", str);
424 
425  gtk_label_set_markup(GTK_LABEL(progress->sub_label), markup);
426  g_free(markup);
427  gtk_widget_show(progress->sub_label);
428  }
429 
430  gnc_progress_dialog_update(progress);
431 }
432 
433 
434 void
435 gnc_progress_dialog_reset_log(GNCProgressDialog *progress)
436 {
437  GtkTextBuffer *buf;
438 
439  g_return_if_fail(progress);
440 
441  if (progress->log == NULL)
442  return;
443 
444  /* Reset the text buffer. */
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);
448 
449  /* Show the log and its parent (in case it is in a scrolled window). */
450  gtk_widget_show(progress->log);
451  gtk_widget_show(gtk_widget_get_parent(progress->log));
452 
453  gnc_progress_dialog_update(progress);
454 }
455 
456 
457 void
458 gnc_progress_dialog_append_log(GNCProgressDialog *progress, const gchar *str)
459 {
460  GtkTextBuffer *buf;
461  GtkTextIter iter;
462 
463  g_return_if_fail(progress);
464 
465  if (progress->log == NULL || !str || !*str)
466  return;
467 
468  /* Append to the text buffer. */
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);
472 
473  gnc_progress_dialog_update(progress);
474 }
475 
476 
477 void
478 gnc_progress_dialog_pause(GNCProgressDialog *progress)
479 {
480  gchar *suffix;
481 
482  g_return_if_fail(progress);
483 
484  suffix = g_strconcat(" ", _("(paused)"), NULL);
485 
486  if (progress->sub_label && gtk_widget_get_visible(progress->sub_label))
487  {
488  const gchar *txt = gtk_label_get_text(GTK_LABEL(progress->sub_label));
489 
490  if (txt && !g_str_has_suffix(txt, suffix))
491  {
492  gchar *newtxt = g_strconcat(txt, suffix, NULL);
493  gnc_progress_dialog_set_sub(progress, newtxt);
494  g_free(newtxt);
495  }
496  }
497  else if (progress->dialog)
498  {
499  const gchar *txt = gtk_window_get_title(GTK_WINDOW(progress->dialog));
500 
501  if (txt && !g_str_has_suffix(txt, suffix))
502  {
503  gchar *newtxt = g_strconcat(txt, suffix, NULL);
504  gtk_window_set_title(GTK_WINDOW(progress->dialog), newtxt);
505  g_free(newtxt);
506  }
507  }
508  else if (progress->primary_label &&
509  gtk_widget_get_visible(progress->primary_label))
510  {
511  const gchar *txt = gtk_label_get_text(GTK_LABEL(progress->primary_label));
512 
513  if (txt && !g_str_has_suffix(txt, suffix))
514  {
515  gchar *newtxt = g_strconcat(txt, suffix, NULL);
516  gnc_progress_dialog_set_primary(progress, newtxt);
517  g_free(newtxt);
518  }
519  }
520 
521  g_free(suffix);
522 
523  gnc_progress_dialog_update(progress);
524 }
525 
526 void
527 gnc_progress_dialog_resume(GNCProgressDialog *progress)
528 {
529  gchar *suffix;
530 
531  g_return_if_fail(progress);
532 
533  suffix = g_strconcat(" ", _("(paused)"), NULL);
534 
535  /* Remove any pause indication from the suboperation label. */
536  if (progress->sub_label)
537  {
538  const gchar *txt = gtk_label_get_text(GTK_LABEL(progress->sub_label));
539 
540  if (txt && g_str_has_suffix(txt, suffix))
541  {
542  gchar *newtxt = g_strndup(txt, strlen(txt) - strlen(suffix));
543  gnc_progress_dialog_set_sub(progress, newtxt);
544  g_free(newtxt);
545  }
546  }
547 
548  /* Remove any pause indication from the window title. */
549  if (progress->dialog)
550  {
551  const gchar *txt = gtk_window_get_title(GTK_WINDOW(progress->dialog));
552 
553  if (txt && g_str_has_suffix(txt, suffix))
554  {
555  gchar *newtxt = g_strndup(txt, strlen(txt) - strlen(suffix));
556  gtk_window_set_title(GTK_WINDOW(progress->dialog), newtxt);
557  g_free(newtxt);
558  }
559  }
560 
561  /* Remove any pause indication from the primary text. */
562  if (progress->primary_label)
563  {
564  const gchar *txt = gtk_label_get_text(GTK_LABEL(progress->primary_label));
565 
566  if (txt && g_str_has_suffix(txt, suffix))
567  {
568  gchar *newtxt = g_strndup(txt, strlen(txt) - strlen(suffix));
569  gnc_progress_dialog_set_primary(progress, newtxt);
570  g_free(newtxt);
571  }
572  }
573 
574  g_free(suffix);
575 
576  gnc_progress_dialog_update(progress);
577 }
578 
579 
580 void
581 gnc_progress_dialog_set_cancel_func(GNCProgressDialog *progress,
582  GNCProgressCancelFunc cancel_func,
583  gpointer user_data)
584 {
585  g_return_if_fail(progress);
586 
587  if (progress->cancel_button == NULL)
588  return;
589 
590  progress->cancel_func = cancel_func;
591  progress->user_data = user_data;
592 
593  if (cancel_func)
594  gtk_widget_show(progress->cancel_button);
595 }
596 
597 
598 void
599 gnc_progress_dialog_set_cancel_scm_func(GNCProgressDialog *progress,
600  SCM cancel_scm_func)
601 {
602  g_return_if_fail(progress);
603 
604  if (progress->cancel_button == NULL)
605  return;
606 
607  if (progress->cancel_scm_func != SCM_UNDEFINED)
608  scm_gc_unprotect_object(progress->cancel_scm_func);
609 
610  if (scm_is_procedure(cancel_scm_func))
611  {
612  progress->cancel_scm_func = cancel_scm_func;
613  scm_gc_protect_object(cancel_scm_func);
614  gtk_widget_show(progress->cancel_button);
615  }
616  else
617  progress->cancel_scm_func = SCM_UNDEFINED;
618 }
619 
620 
621 void
622 gnc_progress_dialog_set_value(GNCProgressDialog *progress, gdouble value)
623 {
624  GtkProgressBar *bar;
625 
626  g_return_if_fail(progress);
627 
628  /* Get the progress bar widget. */
629  bar = GTK_PROGRESS_BAR(progress->progress_bar);
630  if (bar == NULL)
631  return;
632 
633  /* Update the progress bar. If value is over 1,
634  * the bar will pulse instead of fill. */
635  if (value > 1)
636  gtk_progress_bar_pulse(bar);
637  else
638  {
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);
642  }
643 
644  gnc_progress_dialog_update(progress);
645 }
646 
647 
648 guint
649 gnc_progress_dialog_push(GNCProgressDialog *progress, gdouble weight)
650 {
651  GtkProgressBar *bar;
652  VirtualBar *newbar;
653 
654  g_return_val_if_fail(progress, 0);
655  g_return_val_if_fail(weight > 0, 0);
656 
657  /* Get the progress bar widget. */
658  bar = GTK_PROGRESS_BAR(progress->progress_bar);
659  if (bar == NULL)
660  return 0;
661 
662  /* Create the new virtual progress bar. */
663  newbar = g_new0(VirtualBar, 1);
664  newbar->offset = progress->bar_value;
665  if (newbar->offset + weight > 1)
666  /* The requested weight is more than the unfilled portion of the bar. */
667  newbar->weight = 1 - newbar->offset;
668  else
669  newbar->weight = weight;
670  progress->bars = g_list_prepend(progress->bars, newbar);
671 
672  /* Set the total effective offset and weight */
673  progress->total_offset = gtk_progress_bar_get_fraction(bar);
674  progress->total_weight *= newbar->weight;
675 
676  /* Set the new bar as unfilled. */
677  progress->bar_value = 0;
678 
679  return g_list_length(progress->bars);
680 }
681 
682 
683 guint
684 gnc_progress_dialog_pop(GNCProgressDialog *progress)
685 {
686  VirtualBar *bar;
687 
688  g_return_val_if_fail(progress, 0);
689 
690  /* Get the progress bar widget. */
691  if (progress->progress_bar == NULL || progress->bars == NULL)
692  return 0;
693 
694  /* Pop the bar off the bar stack. */
695  bar = progress->bars->data;
696  progress->bars = g_list_delete_link(progress->bars, progress->bars);
697 
698  /* Determine the value of the current bar. */
699  progress->bar_value = bar->offset + bar->weight * progress->bar_value;
700 
701  /* Set the total effective offset and weight. */
702  if (progress->bars == NULL)
703  {
704  progress->total_offset = 0;
705  progress->total_weight = 1;
706  }
707  else
708  {
709  progress->total_offset -= bar->offset *
710  ((VirtualBar *) progress->bars->data)->weight;
711  progress->total_weight /= bar->weight;
712  }
713  g_free(bar);
714 
715  if (progress->bars == NULL)
716  return 0;
717  return g_list_length(progress->bars);
718 }
719 
720 
721 guint
722 gnc_progress_dialog_pop_full(GNCProgressDialog *progress)
723 {
724  gnc_progress_dialog_set_value(progress, 1);
725  return gnc_progress_dialog_pop(progress);
726 }
727 
728 
729 void
730 gnc_progress_dialog_reset_value(GNCProgressDialog *progress)
731 {
732  g_return_if_fail(progress);
733 
734  /* Return to the top level. */
735  while (gnc_progress_dialog_pop(progress));
736 
737  /* Reset the bar to empty. */
738  gnc_progress_dialog_set_value(progress, 0);
739 }
740 
741 
742 void
743 gnc_progress_dialog_update(GNCProgressDialog *progress)
744 {
745  while (gtk_events_pending())
746  gtk_main_iteration();
747 }
748 
749 
750 void
751 gnc_progress_dialog_finish(GNCProgressDialog *progress)
752 {
753  g_return_if_fail(progress);
754 
755  if (!progress->use_ok_button)
756  {
757  if (progress->dialog != NULL)
758  gtk_widget_hide(progress->dialog);
759  progress->closed = TRUE;
760  }
761 
762  gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress->progress_bar), 1.0);
763 
764  gtk_widget_set_sensitive(progress->ok_button, TRUE);
765  gtk_widget_set_sensitive(progress->cancel_button, FALSE);
766 
767  if (gtk_widget_get_visible(progress->primary_label))
768  gnc_progress_dialog_set_heading(progress, _("Complete"));
769 
770  if (!progress->title_set)
771  gtk_window_set_title(GTK_WINDOW(progress->dialog), _("Complete"));
772 
773  gtk_window_set_modal(GTK_WINDOW(progress->dialog), FALSE);
774 
775  progress->finished = TRUE;
776 
777  gnc_progress_dialog_update(progress);
778 }
779 
780 
781 void
782 gnc_progress_dialog_destroy(GNCProgressDialog *progress)
783 {
784  g_return_if_fail(progress);
785 
786  /* Make sure the callbacks aren't invoked */
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;
791 
792  if (!progress->finished)
793  {
794  if (progress->dialog != NULL)
795  gtk_widget_hide(progress->dialog);
796  progress->closed = TRUE;
797  }
798 
799  progress->destroyed = TRUE;
800 
801  gnc_progress_maybe_destroy(progress);
802 }
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 &#39;OK&#39; 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...