28 #include <glib/gi18n.h> 30 #include "dialog-utils.h" 31 #include "gnc-component-manager.h" 32 #include "gnc-session.h" 34 #include "gnc-gui-query.h" 39 #include "dialog-billterms.h" 41 #define DIALOG_BILLTERMS_CM_CLASS "billterms-dialog" 42 #define GNC_PREFS_GROUP "dialogs.bill-terms" 46 BILL_TERM_COL_NAME = 0,
51 void billterms_new_term_cb (GtkButton *button, BillTermsWindow *btw);
52 void billterms_delete_term_cb (GtkButton *button, BillTermsWindow *btw);
53 void billterms_edit_term_cb (GtkButton *button, BillTermsWindow *btw);
54 void billterms_window_close (GtkWidget *widget, gpointer data);
55 void billterms_window_destroy_cb (GtkWidget *widget, gpointer data);
56 void billterms_type_combobox_changed (GtkComboBox *cb, gpointer data);
58 typedef struct _billterm_notebook
63 GtkWidget *days_due_days;
64 GtkWidget *days_disc_days;
68 GtkWidget *prox_due_day;
69 GtkWidget *prox_disc_day;
71 GtkWidget *prox_cutoff;
80 GtkWidget *terms_view;
81 GtkWidget *desc_entry;
82 GtkWidget *type_label;
86 GncBillTerm *current_term;
92 typedef struct _new_billterms
95 GtkWidget *name_entry;
96 GtkWidget *desc_entry;
100 GncBillTerm *this_term;
105 read_widget (GtkBuilder *builder,
char *name, gboolean read_only)
107 GtkWidget *widget = GTK_WIDGET(gtk_builder_get_object (builder, name));
111 gtk_editable_set_editable (GTK_EDITABLE(widget), FALSE);
112 adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(widget));
113 gtk_adjustment_set_step_increment (adj, 0.0);
114 gtk_adjustment_set_page_increment (adj, 0.0);
122 init_notebook_widgets (
BillTermNB *notebook, gboolean read_only,
129 builder = gtk_builder_new ();
130 gnc_builder_add_from_file (builder,
"dialog-billterms.glade",
"discount_adj");
131 gnc_builder_add_from_file (builder,
"dialog-billterms.glade",
"discount_days_adj");
132 gnc_builder_add_from_file (builder,
"dialog-billterms.glade",
"due_days_adj");
133 gnc_builder_add_from_file (builder,
"dialog-billterms.glade",
"pdiscount_adj");
134 gnc_builder_add_from_file (builder,
"dialog-billterms.glade",
"pdiscount_day_adj");
135 gnc_builder_add_from_file (builder,
"dialog-billterms.glade",
"pdue_day_adj");
136 gnc_builder_add_from_file (builder,
"dialog-billterms.glade",
"pcutoff_day_adj");
137 gnc_builder_add_from_file (builder,
"dialog-billterms.glade",
"terms_notebook_window");
138 notebook->notebook = GTK_WIDGET(gtk_builder_get_object (builder,
"term_notebook"));
139 parent = GTK_WIDGET(gtk_builder_get_object (builder,
"terms_notebook_window"));
142 gtk_widget_set_name (GTK_WIDGET(notebook->notebook),
"gnc-id-bill-term");
143 gnc_widget_style_context_add_class (GTK_WIDGET(notebook->notebook),
"gnc-class-bill-terms");
146 notebook->days_due_days = read_widget (builder,
"days:due_days", read_only);
147 notebook->days_disc_days = read_widget (builder,
"days:discount_days", read_only);
148 notebook->days_disc = read_widget (builder,
"days:discount", read_only);
151 notebook->prox_due_day = read_widget (builder,
"prox:due_day", read_only);
152 notebook->prox_disc_day = read_widget (builder,
"prox:discount_day", read_only);
153 notebook->prox_disc = read_widget (builder,
"prox:discount", read_only);
154 notebook->prox_cutoff = read_widget (builder,
"prox:cutoff_day", read_only);
157 g_object_ref (notebook->notebook);
158 gtk_container_remove (GTK_CONTAINER(parent), notebook->notebook);
159 g_object_unref (G_OBJECT(builder));
160 gtk_widget_destroy (parent);
166 set_numeric (GtkWidget *widget, GncBillTerm *term,
167 void (*func)(GncBillTerm *, gnc_numeric))
172 fl = gtk_spin_button_get_value (GTK_SPIN_BUTTON(widget));
178 get_numeric (GtkWidget *widget, GncBillTerm *term,
179 gnc_numeric (*func)(
const GncBillTerm *))
186 gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), fl);
190 set_int (GtkWidget *widget, GncBillTerm *term,
191 void (*func)(GncBillTerm *, gint))
195 val = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(widget));
200 get_int (GtkWidget *widget, GncBillTerm *term,
201 gint (*func)(
const GncBillTerm *))
206 gtk_spin_button_set_value (GTK_SPIN_BUTTON(widget), (gfloat)val);
217 term = nbt->this_term;
218 notebook = &nbt->notebook;
220 text = gtk_entry_get_text (GTK_ENTRY(nbt->desc_entry));
222 gncBillTermSetDescription (term, text);
224 gncBillTermSetType (nbt->this_term, nbt->notebook.type);
226 switch (nbt->notebook.type)
228 case GNC_TERM_TYPE_DAYS:
229 set_int (notebook->days_due_days, term, gncBillTermSetDueDays);
230 set_int (notebook->days_disc_days, term, gncBillTermSetDiscountDays);
231 set_numeric (notebook->days_disc, term, gncBillTermSetDiscount);
234 case GNC_TERM_TYPE_PROXIMO:
235 set_int (notebook->prox_due_day, term, gncBillTermSetDueDays);
236 set_int (notebook->prox_disc_day, term, gncBillTermSetDiscountDays);
237 set_numeric (notebook->prox_disc, term, gncBillTermSetDiscount);
238 set_int (notebook->prox_cutoff, term, gncBillTermSetCutoff);
242 return gncBillTermIsDirty (term);
246 billterm_to_ui (GncBillTerm *term, GtkWidget *desc,
BillTermNB *notebook)
248 gtk_entry_set_text (GTK_ENTRY(desc), gncBillTermGetDescription (term));
249 notebook->type = gncBillTermGetType (term);
251 switch (notebook->type)
253 case GNC_TERM_TYPE_DAYS:
254 get_int (notebook->days_due_days, term, gncBillTermGetDueDays);
255 get_int (notebook->days_disc_days, term, gncBillTermGetDiscountDays);
256 get_numeric (notebook->days_disc, term, gncBillTermGetDiscount);
259 case GNC_TERM_TYPE_PROXIMO:
260 get_int (notebook->prox_due_day, term, gncBillTermGetDueDays);
261 get_int (notebook->prox_disc_day, term, gncBillTermGetDiscountDays);
262 get_numeric (notebook->prox_disc, term, gncBillTermGetDiscount);
263 get_int (notebook->prox_cutoff, term, gncBillTermGetCutoff);
271 char *message = _(
"Discount days cannot be more than due days.");
274 gint days_due_days, days_disc_days;
275 gint prox_due_days, prox_disc_days;
277 notebook = &nbt->notebook;
281 days_due_days = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(notebook->days_due_days));
282 days_disc_days = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(notebook->days_disc_days));
283 prox_due_days = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(notebook->prox_due_day));
284 prox_disc_days = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(notebook->prox_disc_day));
286 switch (nbt->notebook.type)
288 case GNC_TERM_TYPE_DAYS:
289 if (days_due_days<days_disc_days)
291 gnc_error_dialog (GTK_WINDOW(nbt->dialog),
"%s", message);
295 case GNC_TERM_TYPE_PROXIMO:
296 if (prox_due_days<prox_disc_days)
298 gnc_error_dialog (GTK_WINDOW(nbt->dialog),
"%s", message);
310 BillTermsWindow *btw;
311 const char *name = NULL;
314 g_return_val_if_fail (nbt, FALSE);
320 if (nbt->this_term == NULL)
322 name = gtk_entry_get_text (GTK_ENTRY(nbt->name_entry));
323 if (name == NULL || *name ==
'\0')
325 message = _(
"You must provide a name for this Billing Term.");
326 gnc_error_dialog (GTK_WINDOW(nbt->dialog),
"%s", message);
329 if (gncBillTermLookupByName (btw->book, name))
331 message = g_strdup_printf (_(
332 "You must provide a unique name for this Billing Term. " 333 "Your choice \"%s\" is already in use."), name);
334 gnc_error_dialog (GTK_WINDOW(nbt->dialog),
"%s", message);
341 if (!verify_term_ok (nbt))
344 gnc_suspend_gui_refresh ();
347 if (nbt->this_term == NULL)
349 nbt->this_term = gncBillTermCreate (btw->book);
350 gncBillTermBeginEdit (nbt->this_term);
351 gncBillTermSetName (nbt->this_term, name);
353 btw->current_term = nbt->this_term;
356 gncBillTermBeginEdit (btw->current_term);
359 if (ui_to_billterm (nbt))
360 gncBillTermChanged (btw->current_term);
363 gncBillTermCommitEdit (btw->current_term);
365 gnc_resume_gui_refresh ();
372 g_return_if_fail (notebook->type > 0);
373 gtk_notebook_set_current_page (GTK_NOTEBOOK(notebook->notebook),
378 maybe_set_type (
NewBillTerm *nbt, GncBillTermType type)
381 if (type == nbt->notebook.type)
385 nbt->notebook.type = type;
386 show_notebook (&nbt->notebook);
390 billterms_type_combobox_changed (GtkComboBox *cb, gpointer data)
395 value = gtk_combo_box_get_active (cb);
396 maybe_set_type (nbt, value + 1);
400 new_billterm_dialog (BillTermsWindow *btw, GncBillTerm *term,
403 GncBillTerm *created_term = NULL;
406 GtkWidget *box, *combo_box;
409 const gchar *dialog_name;
410 const gchar *dialog_desc;
411 const gchar *dialog_combo;
412 const gchar *dialog_nb;
414 if (!btw)
return NULL;
418 nbt->this_term = term;
423 dialog_name =
"new_term_dialog";
424 dialog_desc =
"description_entry";
425 dialog_combo =
"type_combobox";
426 dialog_nb =
"note_book_hbox";
430 dialog_name =
"edit_term_dialog";
431 dialog_desc =
"entry_desc";
432 dialog_combo =
"type_combo";
433 dialog_nb =
"notebook_hbox";
435 builder = gtk_builder_new ();
436 gnc_builder_add_from_file (builder,
"dialog-billterms.glade",
"type_liststore");
437 gnc_builder_add_from_file (builder,
"dialog-billterms.glade", dialog_name);
438 nbt->dialog = GTK_WIDGET(gtk_builder_get_object (builder, dialog_name));
439 nbt->name_entry = GTK_WIDGET(gtk_builder_get_object (builder,
"name_entry"));
440 nbt->desc_entry = GTK_WIDGET(gtk_builder_get_object (builder, dialog_desc));
443 gtk_widget_set_name (GTK_WIDGET(nbt->dialog),
"gnc-id-new-bill-terms");
444 gnc_widget_style_context_add_class (GTK_WIDGET(nbt->dialog),
"gnc-class-bill-terms");
447 gtk_entry_set_text (GTK_ENTRY(nbt->name_entry), name);
450 init_notebook_widgets (&nbt->notebook, FALSE, nbt);
453 box = GTK_WIDGET(gtk_builder_get_object (builder, dialog_nb));
454 gtk_box_pack_start (GTK_BOX(box), nbt->notebook.notebook, TRUE, TRUE, 0);
455 g_object_unref (nbt->notebook.notebook);
459 billterm_to_ui (term, nbt->desc_entry, &nbt->notebook);
461 nbt->notebook.type = GNC_TERM_TYPE_DAYS;
464 combo_box = GTK_WIDGET(gtk_builder_get_object (builder, dialog_combo));
465 gtk_combo_box_set_active (GTK_COMBO_BOX(combo_box), nbt->notebook.type - 1);
468 show_notebook (&nbt->notebook);
471 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, nbt);
473 gtk_window_set_transient_for (GTK_WINDOW(nbt->dialog),
474 GTK_WINDOW(btw->window));
477 gtk_widget_show_all (nbt->dialog);
480 gtk_widget_grab_focus (nbt->desc_entry);
483 gtk_widget_grab_focus (nbt->name_entry);
488 response = gtk_dialog_run (GTK_DIALOG(nbt->dialog));
491 case GTK_RESPONSE_OK:
492 if (new_billterm_ok_cb (nbt))
494 created_term = nbt->this_term;
504 g_object_unref (G_OBJECT(builder));
506 gtk_widget_destroy (nbt->dialog);
515 billterms_term_refresh (BillTermsWindow *btw)
519 g_return_if_fail (btw);
521 if (!btw->current_term)
523 gtk_widget_hide (btw->term_vbox);
527 gtk_widget_show_all (btw->term_vbox);
528 billterm_to_ui (btw->current_term, btw->desc_entry, &btw->notebook);
529 switch (gncBillTermGetType (btw->current_term))
531 case GNC_TERM_TYPE_DAYS:
532 type_label = _(
"Days");
534 case GNC_TERM_TYPE_PROXIMO:
535 type_label = _(
"Proximo");
538 type_label = _(
"Unknown");
541 show_notebook (&btw->notebook);
542 gtk_label_set_text (GTK_LABEL(btw->type_label), type_label);
546 billterms_window_refresh (BillTermsWindow *btw)
554 GtkTreeSelection *selection;
555 GtkTreeRowReference *reference = NULL;
557 g_return_if_fail (btw);
558 view = GTK_TREE_VIEW(btw->terms_view);
559 store = GTK_LIST_STORE(gtk_tree_view_get_model (view));
560 selection = gtk_tree_view_get_selection (view);
563 gtk_list_store_clear (store);
564 gnc_gui_component_clear_watches (btw->component_id);
567 list = gncBillTermGetTerms (btw->book);
572 btw->current_term = NULL;
573 billterms_term_refresh (btw);
577 list = g_list_reverse (g_list_copy (list));
580 for ( node = list; node; node = node->next)
583 gnc_gui_component_watch_entity (btw->component_id,
584 gncBillTermGetGUID (term),
587 gtk_list_store_prepend (store, &iter);
588 gtk_list_store_set (store, &iter,
589 BILL_TERM_COL_NAME, gncBillTermGetName (term),
590 BILL_TERM_COL_TERM, term,
592 if (term == btw->current_term)
594 path = gtk_tree_model_get_path (GTK_TREE_MODEL(store), &iter);
595 reference = gtk_tree_row_reference_new (GTK_TREE_MODEL(store), path);
596 gtk_tree_path_free (path);
602 gnc_gui_component_watch_entity_type (btw->component_id,
603 GNC_BILLTERM_MODULE_NAME,
604 QOF_EVENT_CREATE | QOF_EVENT_DESTROY);
608 path = gtk_tree_row_reference_get_path (reference);
609 gtk_tree_row_reference_free (reference);
612 gtk_tree_selection_select_path (selection, path);
613 gtk_tree_view_scroll_to_cell (view, path, NULL, TRUE, 0.5, 0.0);
614 gtk_tree_path_free (path);
620 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL(store), &iter))
621 gtk_tree_selection_select_iter (selection, &iter);
626 billterm_selection_changed (GtkTreeSelection *selection,
627 BillTermsWindow *btw)
629 GncBillTerm *term = NULL;
633 g_return_if_fail (btw);
635 if (gtk_tree_selection_get_selected (selection, &model, &iter))
636 gtk_tree_model_get (model, &iter, BILL_TERM_COL_TERM, &term, -1);
639 if (GNC_IS_BILLTERM(term) && (term != btw->current_term))
640 btw->current_term = term;
643 billterms_term_refresh (btw);
647 billterm_selection_activated (GtkTreeView *tree_view,
649 GtkTreeViewColumn *column,
650 BillTermsWindow *btw)
652 new_billterm_dialog (btw, btw->current_term, NULL);
656 billterms_new_term_cb (GtkButton *button, BillTermsWindow *btw)
658 g_return_if_fail (btw);
659 new_billterm_dialog (btw, NULL, NULL);
663 billterms_delete_term_cb (GtkButton *button, BillTermsWindow *btw)
665 g_return_if_fail (btw);
667 if (!btw->current_term)
670 if (gncBillTermGetRefcount (btw->current_term) > 0)
672 gnc_error_dialog (GTK_WINDOW(btw->window),
673 _(
"Term \"%s\" is in use. You cannot delete it."),
674 gncBillTermGetName (btw->current_term));
678 if (gnc_verify_dialog (GTK_WINDOW(btw->window), FALSE,
679 _(
"Are you sure you want to delete \"%s\"?"),
680 gncBillTermGetName (btw->current_term)))
683 gnc_suspend_gui_refresh ();
684 gncBillTermBeginEdit (btw->current_term);
685 gncBillTermDestroy (btw->current_term);
686 btw->current_term = NULL;
687 gnc_resume_gui_refresh ();
692 billterms_edit_term_cb (GtkButton *button, BillTermsWindow *btw)
694 g_return_if_fail (btw);
695 if (!btw->current_term)
697 new_billterm_dialog (btw, btw->current_term, NULL);
701 billterms_window_refresh_handler (GHashTable *changes, gpointer data)
703 BillTermsWindow *btw = data;
705 g_return_if_fail (data);
706 billterms_window_refresh (btw);
710 billterms_window_close_handler (gpointer data)
712 BillTermsWindow *btw = data;
714 g_return_if_fail (btw);
716 gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(btw->window));
717 gtk_widget_destroy (btw->window);
721 billterms_window_close (GtkWidget *widget, gpointer data)
723 BillTermsWindow *btw = data;
725 gnc_close_gui_component (btw->component_id);
729 billterms_window_delete_event_cb (GtkWidget *widget,
733 BillTermsWindow *btw = data;
735 if (!btw)
return FALSE;
738 gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(btw->window));
743 billterms_window_destroy_cb (GtkWidget *widget, gpointer data)
745 BillTermsWindow *btw = data;
749 gnc_unregister_gui_component (btw->component_id);
753 gtk_widget_destroy (btw->window);
760 billterms_window_key_press_cb (GtkWidget *widget, GdkEventKey *event,
763 BillTermsWindow *btw = data;
765 if (event->keyval == GDK_KEY_Escape)
767 billterms_window_close_handler (btw);
775 find_handler (gpointer
find_data, gpointer data)
777 BillTermsWindow *btw = data;
780 return (btw != NULL && btw->book == book);
785 gnc_ui_billterms_window_new (GtkWindow *parent, QofBook *book)
787 BillTermsWindow *btw;
791 GtkTreeViewColumn *column;
792 GtkCellRenderer *renderer;
794 GtkTreeSelection *selection;
796 if (!book)
return NULL;
803 btw = gnc_find_first_gui_component (DIALOG_BILLTERMS_CM_CLASS,
807 gtk_window_present (GTK_WINDOW(btw->window));
812 btw = g_new0 (BillTermsWindow, 1);
814 btw->session = gnc_get_current_session ();
817 builder = gtk_builder_new ();
818 gnc_builder_add_from_file (builder,
"dialog-billterms.glade",
"terms_window");
819 btw->window = GTK_WIDGET(gtk_builder_get_object (builder,
"terms_window"));
820 btw->terms_view = GTK_WIDGET(gtk_builder_get_object (builder,
"terms_view"));
821 btw->desc_entry = GTK_WIDGET(gtk_builder_get_object (builder,
"desc_entry"));
822 btw->type_label = GTK_WIDGET(gtk_builder_get_object (builder,
"type_label"));
823 btw->term_vbox = GTK_WIDGET(gtk_builder_get_object (builder,
"term_vbox"));
826 gtk_widget_set_name (GTK_WIDGET(btw->window),
"gnc-id-bill-terms");
827 gnc_widget_style_context_add_class (GTK_WIDGET(btw->window),
"gnc-class-bill-terms");
829 g_signal_connect (btw->window,
"key_press_event",
830 G_CALLBACK(billterms_window_key_press_cb), btw);
833 view = GTK_TREE_VIEW(btw->terms_view);
834 store = gtk_list_store_new (NUM_BILL_TERM_COLS, G_TYPE_STRING, G_TYPE_POINTER);
835 gtk_tree_view_set_model (view, GTK_TREE_MODEL(store));
836 g_object_unref (store);
838 renderer = gtk_cell_renderer_text_new ();
839 column = gtk_tree_view_column_new_with_attributes (
"", renderer,
840 "text", BILL_TERM_COL_NAME,
842 gtk_tree_view_append_column (view, column);
844 g_signal_connect (view,
"row-activated",
845 G_CALLBACK(billterm_selection_activated), btw);
846 selection = gtk_tree_view_get_selection (view);
847 g_signal_connect (selection,
"changed",
848 G_CALLBACK(billterm_selection_changed), btw);
851 init_notebook_widgets (&btw->notebook, TRUE, btw);
854 widget = GTK_WIDGET(gtk_builder_get_object (builder,
"notebook_box"));
855 gtk_box_pack_start (GTK_BOX(widget), btw->notebook.notebook,
857 g_object_unref (btw->notebook.notebook);
860 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, btw);
864 gnc_register_gui_component (DIALOG_BILLTERMS_CM_CLASS,
865 billterms_window_refresh_handler,
866 billterms_window_close_handler,
869 gnc_gui_component_set_session (btw->component_id, btw->session);
871 g_signal_connect (G_OBJECT(btw->window),
"delete-event",
872 G_CALLBACK(billterms_window_delete_event_cb), btw);
874 gnc_restore_window_size (GNC_PREFS_GROUP, GTK_WINDOW(btw->window), GTK_WINDOW(parent));
876 gtk_widget_show_all (btw->window);
877 billterms_window_refresh (btw);
879 g_object_unref (G_OBJECT(builder));
887 gnc_ui_billterms_new_from_name (GtkWindow *parent, QofBook *book,
const char *name)
889 BillTermsWindow *btw;
891 if (!book)
return NULL;
893 btw = gnc_ui_billterms_window_new (parent, book);
894 if (!btw)
return NULL;
896 return new_billterm_dialog (btw, NULL, name);
gnc_numeric double_to_gnc_numeric(double in, gint64 denom, gint how)
Convert a floating-point number to a gnc_numeric.
utility functions for the GnuCash UI
double gnc_numeric_to_double(gnc_numeric in)
Convert numeric to floating-point value.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...