39 #include <glib/gi18n.h> 47 #include "dialog-sx-editor.h" 48 #include "dialog-utils.h" 49 #include "gnc-component-manager.h" 51 #include "gnc-date-edit.h" 52 #include "gnc-dense-cal.h" 53 #include "gnc-dense-cal-store.h" 56 #include "gnc-frequency.h" 57 #include "gnc-gui-query.h" 58 #include "gnc-hooks.h" 66 #include "gnc-session.h" 69 #include "gnc-split-reg.h" 72 #include "dialog-sx-since-last-run.h" 75 #define G_LOG_DOMAIN "gnc.gui.sx.editor" 77 static QofLogModule log_module = GNC_MOD_GUI_SX;
79 static gint _sx_engine_event_handler_id = -1;
81 #define END_NEVER_OPTION 0 82 #define END_DATE_OPTION 1 83 #define NUM_OCCUR_OPTION 2 85 #define NUM_LEDGER_LINES_DEFAULT 6 87 #define EX_CAL_NUM_MONTHS 12 88 #define EX_CAL_MO_PER_COL 3 90 #define GNC_D_WIDTH 25 91 #define GNC_D_BUF_WIDTH 26 95 typedef enum _EndTypeEnum
106 GtkNotebook *notebook;
112 GNCLedgerDisplay *ledger;
115 GncDenseCalStore *dense_cal_model;
116 GncDenseCal *example_cal;
119 GtkLabel *lastOccurLabel;
121 GtkToggleButton *enabledOpt;
122 GtkToggleButton *autocreateOpt;
123 GtkToggleButton *notifyOpt;
124 GtkToggleButton *advanceOpt;
125 GtkSpinButton *advanceSpin;
126 GtkToggleButton *remindOpt;
127 GtkSpinButton *remindSpin;
129 GtkToggleButton *optEndDate;
130 GtkToggleButton *optEndNone;
131 GtkToggleButton *optEndCount;
133 GtkEntry *endCountSpin;
134 GtkEntry *endRemainSpin;
139 GncEmbeddedWindow *embed_window;
145 static void schedXact_editor_create_freq_sel (GncSxEditorDialog *sxed);
146 static void schedXact_editor_create_ledger (GncSxEditorDialog *sxed);
147 static void schedXact_editor_populate (GncSxEditorDialog *);
148 static void endgroup_rb_toggled_cb (GtkButton *b, gpointer d);
149 static void set_endgroup_toggle_states (GncSxEditorDialog *sxed, EndType t);
150 static void advance_toggled_cb (GtkButton *b, GncSxEditorDialog *sxed);
151 static void remind_toggled_cb (GtkButton *b, GncSxEditorDialog *sxed);
152 static gboolean gnc_sxed_check_consistent (GncSxEditorDialog *sxed);
153 static gboolean gnc_sxed_check_changed (GncSxEditorDialog *sxed);
154 static void gnc_sxed_save_sx (GncSxEditorDialog *sxed);
155 static void gnc_sxed_freq_changed (
GncFrequency *gf, gpointer ud);
156 static void sxed_excal_update_adapt_cb (GtkWidget *o, gpointer ud);
157 static void gnc_sxed_update_cal (GncSxEditorDialog *sxed);
158 void on_sx_check_toggled_cb (GtkWidget *togglebutton, gpointer user_data);
159 static void gnc_sxed_reg_check_close (GncSxEditorDialog *sxed);
160 static gboolean sxed_delete_event (GtkWidget *widget, GdkEvent *event, gpointer ud);
161 static gboolean sxed_confirmed_cancel (GncSxEditorDialog *sxed);
162 static gboolean editor_component_sx_equality (gpointer
find_data,
165 static GActionEntry gnc_sxed_menu_entries [] =
167 {
"EditAction", NULL, NULL, NULL, NULL },
168 {
"TransactionAction", NULL, NULL, NULL, NULL },
169 {
"ViewAction", NULL, NULL, NULL, NULL },
170 {
"ActionsAction", NULL, NULL, NULL, NULL },
172 static guint gnc_sxed_menu_n_entries = G_N_ELEMENTS(gnc_sxed_menu_entries);
177 sxed_close_handler (gpointer user_data)
179 GncSxEditorDialog *sxed = user_data;
181 gnc_sxed_reg_check_close (sxed);
182 gnc_save_window_size (GNC_PREFS_GROUP_SXED, GTK_WINDOW (sxed->dialog));
183 gtk_widget_destroy (sxed->dialog);
193 sxed_confirmed_cancel (GncSxEditorDialog *sxed)
199 if (gnc_sxed_check_changed (sxed))
201 const char *sx_changed_msg =
202 _(
"This Scheduled Transaction has changed; are you " 203 "sure you want to cancel?");
204 if (!gnc_verify_dialog (GTK_WINDOW (sxed->dialog), FALSE,
"%s", sx_changed_msg))
219 editor_cancel_button_clicked_cb (GtkButton *b, GncSxEditorDialog *sxed)
222 if (!sxed_confirmed_cancel (sxed))
225 gnc_close_gui_component_by_data (DIALOG_SCHEDXACTION_EDITOR_CM_CLASS,
231 editor_help_button_clicked_cb (GtkButton *b, GncSxEditorDialog *sxed)
233 gnc_gnome_help (GTK_WINDOW (sxed->dialog), DF_MANUAL, DL_SXEDITOR);
238 editor_ok_button_clicked_cb (GtkButton *b, GncSxEditorDialog *sxed)
243 if (!gnc_sxed_check_consistent (sxed))
246 gnc_sxed_save_sx (sxed);
252 book = gnc_get_current_book ();
253 sxes = gnc_book_get_schedxactions (book);
254 gnc_sxes_add_sx (sxes, sxed->sx);
255 sxed->newsxP = FALSE;
259 gnc_close_gui_component_by_data (DIALOG_SCHEDXACTION_EDITOR_CM_CLASS,
265 gnc_sxed_check_name_changed (GncSxEditorDialog *sxed)
267 const char *name = gtk_entry_get_text (sxed->nameEntry);
269 if (!name || !name[0])
272 if (xaccSchedXactionGetName (sxed->sx) == NULL ||
273 strcmp (xaccSchedXactionGetName (sxed->sx), name) != 0)
280 gnc_sxed_check_end_date_changed (GncSxEditorDialog *sxed)
282 GDate sxEndDate, dlgEndDate;
284 if (!xaccSchedXactionHasEndDate (sxed->sx))
289 gnc_date_edit_get_date (sxed-> endDateEntry));
291 if (g_date_compare (&sxEndDate, &dlgEndDate) != 0)
298 gnc_sxed_check_num_occurs_changed (GncSxEditorDialog *sxed)
300 gint sxNumOccur, sxNumRem, dlgNumOccur, dlgNumRem;
302 if (!xaccSchedXactionGetNumOccur (sxed->sx))
305 gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->endCountSpin));
307 gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->endRemainSpin));
308 sxNumOccur = xaccSchedXactionGetNumOccur (sxed->sx);
309 sxNumRem = xaccSchedXactionGetRemOccur (sxed->sx);
311 if (dlgNumOccur != sxNumOccur || dlgNumRem != sxNumRem)
318 gnc_sxed_check_creation_changed (GncSxEditorDialog *sxed)
320 gboolean sxAutoCreate, sxNotify;
324 gboolean dlgEnabled =
325 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sxed->enabledOpt));
326 gboolean dlgAutoCreate =
327 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sxed->autocreateOpt));
329 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sxed->notifyOpt));
331 if (dlgEnabled != xaccSchedXactionGetEnabled (sxed->sx))
334 xaccSchedXactionGetAutoCreate (sxed->sx, &sxAutoCreate, &sxNotify);
335 if (dlgAutoCreate != sxAutoCreate || dlgNotify != sxNotify)
338 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sxed->advanceOpt)))
339 dlgAdvance = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->advanceSpin));
340 if (dlgAdvance != xaccSchedXactionGetAdvanceCreation (sxed->sx))
343 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sxed->remindOpt)))
344 dlgRemind = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->remindSpin));
345 if (dlgRemind != xaccSchedXactionGetAdvanceReminder (sxed->sx))
352 gnc_sxed_check_dates_changed (GncSxEditorDialog *sxed)
354 GList *dialog_schedule = NULL;
355 GDate dialog_start_date, sx_start_date;
356 gchar *dialog_schedule_str, *sx_schedule_str;
357 gboolean schedules_are_the_same, start_dates_are_the_same;
359 g_date_clear (&dialog_start_date, 1);
360 gnc_frequency_save_to_recurrence (sxed->gncfreq, &dialog_schedule,
362 dialog_schedule_str = recurrenceListToString (dialog_schedule);
363 recurrenceListFree (&dialog_schedule);
365 sx_start_date = *xaccSchedXactionGetStartDate (sxed->sx);
368 DEBUG (
"dialog schedule [%s], sx schedule [%s]",
369 dialog_schedule_str, sx_schedule_str);
371 schedules_are_the_same = (strcmp (dialog_schedule_str,
372 sx_schedule_str) == 0);
373 g_free (dialog_schedule_str);
374 g_free (sx_schedule_str);
376 start_dates_are_the_same = (g_date_compare (&dialog_start_date,
377 &sx_start_date) == 0);
379 if (schedules_are_the_same && start_dates_are_the_same)
391 gnc_sxed_check_changed (GncSxEditorDialog *sxed)
393 SplitRegister *sr = NULL;
398 if (gnc_sxed_check_name_changed (sxed))
402 if (gtk_toggle_button_get_active (sxed->optEndNone) &&
403 (xaccSchedXactionHasEndDate (sxed->sx) ||
408 if (gtk_toggle_button_get_active (sxed->optEndDate) &&
409 gnc_sxed_check_end_date_changed (sxed))
413 if (gtk_toggle_button_get_active (sxed->optEndCount) &&
414 gnc_sxed_check_num_occurs_changed (sxed))
417 if (gnc_sxed_check_creation_changed (sxed))
420 if (gnc_sxed_check_dates_changed (sxed))
436 typedef struct _txnCreditDebitSums
438 gnc_numeric creditSum;
439 gnc_numeric debitSum;
440 gnc_commodity *base_cmdty;
442 gboolean multi_commodity;
449 tcds->creditSum = tcds->debitSum = gnc_numeric_zero ();
450 tcds->base_cmdty = NULL;
452 tcds->multi_commodity = FALSE;
457 set_sums_to_zero (gpointer key,
462 tcds->creditSum = gnc_numeric_zero ();
463 tcds->debitSum = gnc_numeric_zero ();
464 tcds->base_cmdty = NULL;
465 tcds->multi_commodity = FALSE;
468 inline static gnc_numeric
471 return gnc_numeric_sub_fixed (tcds->debitSum, tcds->creditSum);
475 check_credit_debit_balance (gpointer key, gpointer val, gpointer ud)
478 Transaction *txn = GNC_TRANSACTION(key);
479 gboolean *unbalanced = (gboolean*)ud;
480 gnc_numeric diff = tcds_difference (tcds);
484 DEBUG (
"%p | %s [%s - %s = %s]", key, result,
497 msg_text = g_strdup_printf (_(
"Transaction with description '%s' can not be balanced.\n" 498 "The difference is %s"), desc,
string);
500 gnc_warning_dialog (tcds->window,
"%s", msg_text);
506 gnc_sxed_check_names (GncSxEditorDialog *sxed)
508 const gchar *name = gtk_entry_get_text (sxed->nameEntry);
509 if (!name || !name[0])
511 const char *sx_has_no_name_msg =
512 _(
"Please name the Scheduled Transaction.");
513 gnc_error_dialog (GTK_WINDOW (sxed->dialog),
"%s", sx_has_no_name_msg);
518 bool nameExists = FALSE;
519 gchar *nameKey = g_utf8_collate_key (name, -1);
520 bool nameHasChanged =
521 (xaccSchedXactionGetName (sxed->sx) == NULL)
522 || (strcmp (xaccSchedXactionGetName (sxed->sx), name) != 0);
523 for (GList *sxList = gnc_book_get_schedxactions (gnc_get_current_book ())->sx_list;
524 nameHasChanged && !nameExists && sxList;
525 sxList = sxList->next)
527 const char *existingName = xaccSchedXactionGetName ((SchedXaction*)sxList->data);
528 char *existingNameKey = g_utf8_collate_key (existingName, -1);
529 nameExists |= (strcmp (nameKey, existingNameKey) == 0);
530 g_free (existingNameKey);
533 if (nameHasChanged && nameExists)
535 const char *sx_has_existing_name_msg =
536 _(
"A Scheduled Transaction with the name \"%s\" already exists. " 537 "Are you sure you want to name this one the same?");
538 if (!gnc_verify_dialog (GTK_WINDOW (sxed->dialog), FALSE,
539 sx_has_existing_name_msg, name))
546 gnc_sxed_check_endpoint (GncSxEditorDialog *sxed)
548 GDate startDate, endDate, nextDate;
549 GList *schedule = NULL;
551 if (!gtk_toggle_button_get_active (sxed->optEndDate)
552 && !gtk_toggle_button_get_active (sxed->optEndCount)
553 && !gtk_toggle_button_get_active (sxed->optEndNone))
555 const char *sx_end_spec_msg =
556 _(
"Please provide a valid end selection.");
557 gnc_error_dialog (GTK_WINDOW (sxed->dialog),
"%s", sx_end_spec_msg);
561 if (gtk_toggle_button_get_active (sxed->optEndCount))
564 gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->endCountSpin));
566 gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->endRemainSpin));
570 const char *sx_occur_count_zero_msg =
571 _(
"There must be some number of occurrences.");
572 gnc_error_dialog (GTK_WINDOW (sxed->dialog),
"%s", sx_occur_count_zero_msg);
578 const char *sx_occur_counts_wrong_msg =
579 _(
"The number of remaining occurrences (%d) is greater than " 580 "the number of total occurrences (%d).");
581 gnc_error_dialog (GTK_WINDOW (sxed->dialog), sx_occur_counts_wrong_msg,
588 g_date_clear (&endDate, 1);
589 if (gtk_toggle_button_get_active (sxed->optEndDate))
592 gnc_date_edit_get_date (sxed-> endDateEntry));
595 g_date_clear (&nextDate, 1);
596 gnc_frequency_save_to_recurrence (sxed->gncfreq, &schedule, &startDate);
599 g_date_subtract_days (&startDate, 1);
600 recurrenceListNextInstance (schedule, &startDate, &nextDate);
602 recurrenceListFree (&schedule);
604 if (!g_date_valid (&nextDate) ||
605 (g_date_valid (&endDate) && (g_date_compare (&nextDate, &endDate) > 0)))
607 const char *invalid_sx_check_msg =
608 _(
"You have attempted to create a Scheduled Transaction which " 609 "will never run. Do you really want to do this?");
610 if (!gnc_verify_dialog (GTK_WINDOW (sxed->dialog), FALSE,
611 "%s", invalid_sx_check_msg))
618 gnc_sxed_check_autocreate (GncSxEditorDialog *sxed,
int ttVarCount,
619 int splitCount, gboolean multi_commodity)
621 gboolean autocreateState;
624 gtk_toggle_button_get_active (
625 GTK_TOGGLE_BUTTON (sxed->autocreateOpt));
627 if (((ttVarCount > 0) || multi_commodity) && autocreateState)
629 gnc_warning_dialog (GTK_WINDOW (sxed->dialog),
"%s",
630 _(
"Scheduled Transactions with variables " 631 "or involving more than one commodity " 632 "cannot be automatically created."));
638 if (autocreateState && splitCount == 0)
640 gnc_warning_dialog (GTK_WINDOW (sxed->dialog),
"%s",
641 _(
"Scheduled Transactions without a template " 642 "transaction cannot be automatically created."));
649 gnc_sxed_split_check_account (GncSxEditorDialog *sxed, Split *s,
txnCreditDebitSums *tcds)
654 guid_free (acct_guid);
661 if (!tcds->base_cmdty)
662 tcds->base_cmdty = split_cmdty;
670 gnc_sxed_split_calculate_formula (GncSxEditorDialog *sxed, Split *s,
671 GHashTable *vars,
const char *key,
674 gnc_numeric tmp = gnc_numeric_zero ();
685 if (gnc_sx_parse_vars_from_formula (str, vars, &tmp) < 0)
687 gchar *err = g_strdup_printf (_(
"Couldn't parse %s for split \"%s\"."),
689 gnc_error_dialog (GTK_WINDOW (sxed->dialog),
"%s", err);
695 if (g_strcmp0 (key,
"sx-credit-formula") == 0)
707 GncSxEditorDialog *sxed;
711 gboolean multi_commodity;
716 split_error_warning_dialog (GtkWidget *parent,
const gchar *title,
719 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (parent), 0,
723 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
725 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent));
726 g_signal_connect_swapped (dialog,
"response",
727 G_CALLBACK (gtk_widget_destroy), dialog);
728 gtk_dialog_run (GTK_DIALOG (dialog));
733 check_transaction_splits (Transaction *txn, gpointer data)
738 for (; splitList; splitList = splitList->next)
740 Split *s = (Split*)splitList->data;
742 if (g_hash_table_lookup (sd->txns, (gpointer)txn) == NULL)
744 sd->tcds = tcds_new ();
745 sd->tcds->window = GTK_WINDOW(sd->sxed->dialog);
746 g_hash_table_insert (sd->txns, (gpointer)txn, (gpointer)(sd->tcds));
749 if (!gnc_sxed_split_check_account (sd->sxed, s, sd->tcds))
751 gchar *message = g_strdup_printf
752 (_(
"Split with memo %s has an invalid account."),
754 split_error_warning_dialog (sd->sxed->dialog,
755 _(
"Invalid Account in Split"),
762 sd->multi_commodity |= sd->tcds->multi_commodity;
764 if (!gnc_sxed_split_calculate_formula (sd->sxed, s, sd->vars,
768 gchar *message = g_strdup_printf
769 (_(
"Split with memo %s has an unparsable Credit Formula."),
771 split_error_warning_dialog (sd->sxed->dialog,
772 _(
"Unparsable Formula in Split"),
779 if (!gnc_sxed_split_calculate_formula (sd->sxed, s, sd->vars,
784 gchar *message = g_strdup_printf
785 (_(
"Split with memo %s has an unparsable Debit Formula."),
787 split_error_warning_dialog (sd->sxed->dialog,
788 _(
"Unparsable Formula in Split"),
803 gnc_sxed_check_consistent (GncSxEditorDialog *sxed)
825 gint ttVarCount = 0, splitCount = 0;
826 static const int NUM_ITERS_WITH_VARS = 5;
827 static const int NUM_ITERS_NO_VARS = 1;
828 int numIters = NUM_ITERS_NO_VARS, i;
829 gboolean unbalanceable = FALSE;
830 gpointer unusedKey, unusedValue;
832 GHashTable *vars = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
833 (GDestroyNotify)gnc_sx_variable_free);
834 GHashTable *txns = g_hash_table_new_full (g_direct_hash, g_direct_equal,
847 gnc_sxed_reg_check_close (sxed);
849 gnc_sx_get_variables (sxed->sx, vars);
851 ttVarCount = g_hash_table_size (vars);
857 numIters = NUM_ITERS_WITH_VARS;
860 for (i = 0; i < numIters && !unbalanceable; i++)
862 GList *splitList = xaccSchedXactionGetSplits (sxed->sx);
863 Account *tmpl_acct = gnc_sx_get_template_transaction_account (sxed->sx);
864 gnc_sx_randomize_variables (vars);
865 g_hash_table_foreach (txns, set_sums_to_zero, NULL);
867 splitCount += g_list_length (splitList);
868 g_list_free (splitList);
874 g_hash_table_destroy (vars);
875 g_hash_table_destroy (txns);
879 g_hash_table_foreach (txns, check_credit_debit_balance, &unbalanceable);
883 if (g_hash_table_lookup_extended (vars,
"i", &unusedKey, &unusedValue))
886 g_hash_table_destroy (vars);
887 g_hash_table_destroy (txns);
892 _(
"The Scheduled Transaction Editor cannot automatically balance " 893 "all of the transactions in this this Scheduled Transaction.\n" 894 "Should it still be entered?");
895 if (!gnc_verify_dialog (GTK_WINDOW (sxed->dialog), FALSE,
"%s", msg))
899 if (!gnc_sxed_check_names (sxed))
902 if (!gnc_sxed_check_autocreate (sxed, ttVarCount,
903 splitCount, sd.multi_commodity))
906 if (!gnc_sxed_check_endpoint (sxed))
917 gnc_sxed_save_sx (GncSxEditorDialog *sxed)
919 gnc_sx_begin_edit (sxed->sx);
922 const gchar *name = gtk_entry_get_text (sxed->nameEntry);
930 if (gtk_toggle_button_get_active (sxed->optEndDate))
934 gnc_date_edit_get_date (
935 sxed->endDateEntry));
940 else if (gtk_toggle_button_get_active (sxed->optEndCount))
946 gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->endCountSpin));
950 gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->endRemainSpin));
951 xaccSchedXactionSetRemOccur (sxed->sx, num);
953 g_date_clear (&gdate, 1);
956 else if (gtk_toggle_button_get_active (sxed->optEndNone))
959 g_date_clear (&gdate, 1);
964 g_critical (
"no valid end specified\n");
970 gboolean enabledState;
972 enabledState = gtk_toggle_button_get_active (sxed->enabledOpt);
973 xaccSchedXactionSetEnabled (sxed->sx, enabledState);
978 gboolean autocreateState, notifyState;
980 autocreateState = gtk_toggle_button_get_active (sxed->autocreateOpt);
981 notifyState = gtk_toggle_button_get_active (sxed->notifyOpt);
984 xaccSchedXactionSetAutoCreate (sxed->sx,
986 (autocreateState & notifyState));
994 if (gtk_toggle_button_get_active (sxed->advanceOpt))
997 gtk_spin_button_get_value_as_int (sxed->advanceSpin);
999 xaccSchedXactionSetAdvanceCreation (sxed->sx, daysInAdvance);
1002 if (gtk_toggle_button_get_active (sxed->remindOpt))
1005 gtk_spin_button_get_value_as_int (sxed->remindSpin);
1007 xaccSchedXactionSetAdvanceReminder (sxed->sx, daysInAdvance);
1013 GList *schedule = NULL;
1015 gnc_frequency_save_to_recurrence (sxed->gncfreq, &schedule, &gdate);
1018 gchar *recurrence_str = recurrenceListToCompactString (schedule);
1019 DEBUG (
"recurrences parsed [%s]", recurrence_str);
1020 g_free (recurrence_str);
1024 xaccSchedXactionSetStartDate (sxed->sx, &gdate);
1027 gnc_sx_commit_edit (sxed->sx);
1031 update_sensitivity (GncSxEditorDialog *sxed)
1033 gboolean enabled = gtk_toggle_button_get_active (sxed->enabledOpt);
1034 gboolean autocreate = gtk_toggle_button_get_active (sxed->autocreateOpt);
1035 gboolean advance = gtk_toggle_button_get_active (sxed->advanceOpt);
1036 gboolean remind = gtk_toggle_button_get_active (sxed->remindOpt);
1037 gboolean type_date = (sxed->end_type == END_DATE);
1038 gboolean type_occur = (sxed->end_type == END_OCCUR);
1040 gnc_suspend_gui_refresh ();
1042 gtk_widget_set_sensitive (GTK_WIDGET (sxed->autocreateOpt), enabled);
1043 gtk_widget_set_sensitive (GTK_WIDGET (sxed->notifyOpt), enabled && autocreate);
1045 gtk_widget_set_sensitive (GTK_WIDGET (sxed->advanceOpt), enabled);
1046 gtk_widget_set_sensitive (GTK_WIDGET (sxed->advanceSpin), enabled && advance);
1048 gtk_widget_set_sensitive (GTK_WIDGET (sxed->remindOpt), enabled);
1049 gtk_widget_set_sensitive (GTK_WIDGET (sxed->remindSpin), enabled && remind);
1051 gtk_widget_set_sensitive (GTK_WIDGET (sxed->optEndNone), enabled);
1052 gtk_widget_set_sensitive (GTK_WIDGET (sxed->optEndDate), enabled);
1053 gtk_widget_set_sensitive (GTK_WIDGET (sxed->optEndCount), enabled);
1055 gtk_widget_set_sensitive (GTK_WIDGET (sxed->endDateEntry), enabled && type_date);
1056 gtk_widget_set_sensitive (GTK_WIDGET (sxed->endCountSpin), enabled && type_occur);
1057 gtk_widget_set_sensitive (GTK_WIDGET (sxed->endRemainSpin), enabled && type_occur);
1059 gtk_widget_set_sensitive (gtk_notebook_get_nth_page (sxed->notebook, 1), enabled);
1060 gtk_widget_set_sensitive (gtk_notebook_get_nth_page (sxed->notebook, 2), enabled);
1062 gnc_resume_gui_refresh ();
1066 enabled_toggled_cb (GtkToggleButton *o, GncSxEditorDialog *sxed)
1068 update_sensitivity (sxed);
1072 autocreate_toggled_cb (GtkToggleButton *o, GncSxEditorDialog *sxed)
1074 update_sensitivity (sxed);
1078 advance_toggled_cb (GtkButton *o, GncSxEditorDialog *sxed)
1080 update_sensitivity (sxed);
1084 remind_toggled_cb (GtkButton *o, GncSxEditorDialog *sxed)
1086 update_sensitivity (sxed);
1092 scheduledxaction_editor_dialog_destroy (GtkWidget *
object, gpointer data)
1094 GncSxEditorDialog *sxed = data;
1099 gnc_unregister_gui_component_by_data
1100 (DIALOG_SCHEDXACTION_EDITOR_CM_CLASS, sxed);
1103 gtk_widget_destroy (GTK_WIDGET (sxed->embed_window));
1104 sxed->embed_window = NULL;
1105 sxed->plugin_page = NULL;
1106 sxed->ledger = NULL;
1108 g_free (sxed->sxGUIDstr);
1109 sxed->sxGUIDstr = NULL;
1121 gnc_sx_begin_edit (sxed->sx);
1132 sxed_delete_event (GtkWidget *widget, GdkEvent *event, gpointer ud)
1134 GncSxEditorDialog *sxed = (GncSxEditorDialog*)ud;
1138 if (sxed->sx == NULL)
1143 if (!sxed_confirmed_cancel (sxed))
1151 focus_idle_callback(gpointer user_data)
1153 GNCLedgerDisplay *ledger_display = (GNCLedgerDisplay *)user_data;
1162 on_notebook_switch_page(GtkNotebook *notebook, GtkWidget *page,
1163 guint page_num, gpointer user_data)
1165 GtkWidget *current_page = gtk_notebook_get_nth_page(notebook, page_num);
1166 if (current_page && page_num == 2)
1168 GncSxEditorDialog *sxed = (GncSxEditorDialog *)user_data;
1171 g_idle_add (focus_idle_callback, sxed->ledger);
1179 gnc_ui_scheduled_xaction_editor_dialog_create (GtkWindow *parent,
1180 SchedXaction *sx, gboolean newSX)
1182 GncSxEditorDialog *sxed;
1183 GtkBuilder *builder;
1187 GList *dlgExists = NULL;
1189 static struct widgetSignalCallback
1194 gpointer objectData;
1197 {
"ok_button",
"clicked", editor_ok_button_clicked_cb, NULL },
1198 {
"cancel_button",
"clicked", editor_cancel_button_clicked_cb, NULL },
1199 {
"help_button",
"clicked", editor_help_button_clicked_cb, NULL },
1200 {
"rb_noend",
"toggled", endgroup_rb_toggled_cb, GINT_TO_POINTER (END_NEVER_OPTION) },
1201 {
"rb_enddate",
"toggled", endgroup_rb_toggled_cb, GINT_TO_POINTER (END_DATE_OPTION) },
1202 {
"rb_num_occur",
"toggled", endgroup_rb_toggled_cb, GINT_TO_POINTER (NUM_OCCUR_OPTION) },
1203 {
"remain_spin" ,
"value-changed", sxed_excal_update_adapt_cb, NULL },
1204 {
"enabled_opt",
"toggled", enabled_toggled_cb, NULL },
1205 {
"autocreate_opt",
"toggled", autocreate_toggled_cb, NULL },
1206 {
"advance_opt",
"toggled", advance_toggled_cb, NULL },
1207 {
"remind_opt",
"toggled", remind_toggled_cb, NULL },
1208 { NULL, NULL, NULL, NULL }
1211 dlgExists = gnc_find_gui_components (DIALOG_SCHEDXACTION_EDITOR_CM_CLASS,
1212 editor_component_sx_equality,
1216 DEBUG (
"dialog already exists; using that one.");
1217 sxed = (GncSxEditorDialog*)dlgExists->data;
1218 gtk_window_present (GTK_WINDOW (sxed->dialog));
1219 g_list_free (dlgExists);
1223 sxed = g_new0(GncSxEditorDialog, 1);
1226 sxed->newsxP = newSX;
1229 builder = gtk_builder_new ();
1230 gnc_builder_add_from_file (builder,
"dialog-sx.glade",
"advance_days_adj");
1231 gnc_builder_add_from_file (builder,
"dialog-sx.glade",
"remind_days_adj");
1232 gnc_builder_add_from_file (builder,
"dialog-sx.glade",
"end_spin_adj");
1233 gnc_builder_add_from_file (builder,
"dialog-sx.glade",
"remain_spin_adj");
1234 gnc_builder_add_from_file (builder,
"dialog-sx.glade",
"scheduled_transaction_editor_dialog");
1236 sxed->builder = builder;
1239 sxed->dialog = GTK_WIDGET (gtk_builder_get_object (builder,
"scheduled_transaction_editor_dialog"));
1240 sxed->notebook = GTK_NOTEBOOK (gtk_builder_get_object (builder,
"editor_notebook"));
1241 sxed->nameEntry = GTK_ENTRY (gtk_builder_get_object (builder,
"sxe_name"));
1242 sxed->enabledOpt = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder,
"enabled_opt"));
1243 sxed->autocreateOpt = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder,
"autocreate_opt"));
1244 sxed->notifyOpt = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder,
"notify_opt"));
1245 sxed->advanceOpt = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder,
"advance_opt"));
1246 sxed->advanceSpin = GTK_SPIN_BUTTON (gtk_builder_get_object (builder,
"advance_days"));
1247 sxed->remindOpt = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder,
"remind_opt"));
1248 sxed->remindSpin = GTK_SPIN_BUTTON (gtk_builder_get_object (builder,
"remind_days"));
1249 sxed->lastOccurLabel = GTK_LABEL (gtk_builder_get_object (builder,
"last_occur_label"));
1250 sxed->optEndNone = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder,
"rb_noend"));
1251 sxed->optEndDate = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder,
"rb_enddate"));
1252 sxed->optEndCount = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder,
"rb_num_occur"));
1253 sxed->endCountSpin = GTK_ENTRY (gtk_builder_get_object (builder,
"end_spin"));
1254 sxed->endRemainSpin = GTK_ENTRY (gtk_builder_get_object (builder,
"remain_spin"));
1257 gtk_widget_set_name (GTK_WIDGET (sxed->dialog),
"gnc-id-sx-editor");
1258 gnc_widget_style_context_add_class (GTK_WIDGET (sxed->dialog),
"gnc-class-sx");
1260 gtk_window_set_transient_for (GTK_WINDOW (sxed->dialog), parent);
1264 GtkWidget *endDateBox = GTK_WIDGET (gtk_builder_get_object (builder,
"editor_end_date_box"));
1265 sxed->endDateEntry = GNC_DATE_EDIT (gnc_date_edit_new (
gnc_time (NULL), FALSE, FALSE));
1266 gtk_widget_show (GTK_WIDGET (sxed->endDateEntry));
1267 g_signal_connect (sxed->endDateEntry,
"date-changed",
1268 G_CALLBACK (sxed_excal_update_adapt_cb), sxed);
1269 gtk_box_pack_start (GTK_BOX (endDateBox), GTK_WIDGET (sxed->endDateEntry),
1273 id = gnc_register_gui_component (DIALOG_SCHEDXACTION_EDITOR_CM_CLASS,
1278 gnc_gui_component_set_session (
id, gnc_get_current_session ());
1280 g_signal_connect (sxed->dialog,
"delete_event",
1281 G_CALLBACK (sxed_delete_event), sxed);
1282 g_signal_connect (sxed->dialog,
"destroy",
1283 G_CALLBACK (scheduledxaction_editor_dialog_destroy),
1285 g_signal_connect (sxed->notebook,
"switch-page",
1286 G_CALLBACK(on_notebook_switch_page),
1289 for (i = 0; widgets[i].name; i++)
1291 button = GTK_WIDGET (gtk_builder_get_object (builder, widgets[i].name));
1292 if (widgets[i].objectData)
1294 g_object_set_data (G_OBJECT (button),
"whichOneAmI",
1295 widgets[i].objectData);
1297 g_signal_connect (button, widgets[i].signal,
1298 G_CALLBACK (widgets[i].fn), sxed);
1302 gtk_widget_set_sensitive (GTK_WIDGET (sxed->notifyOpt), FALSE);
1303 gtk_widget_set_sensitive (GTK_WIDGET (sxed->advanceSpin), FALSE);
1304 gtk_widget_set_sensitive (GTK_WIDGET (sxed->remindSpin), FALSE);
1305 gtk_widget_set_sensitive (GTK_WIDGET (sxed->endCountSpin), FALSE);
1306 gtk_widget_set_sensitive (GTK_WIDGET (sxed->endRemainSpin), FALSE);
1307 gtk_editable_set_editable (GTK_EDITABLE (sxed->advanceSpin), TRUE);
1308 gtk_editable_set_editable (GTK_EDITABLE (sxed->remindSpin), TRUE);
1311 gtk_window_set_resizable (GTK_WINDOW (sxed->dialog), TRUE);
1312 gnc_restore_window_size (GNC_PREFS_GROUP_SXED, GTK_WINDOW (sxed->dialog), parent);
1315 schedXact_editor_create_freq_sel (sxed);
1318 schedXact_editor_create_ledger (sxed);
1321 schedXact_editor_populate (sxed);
1324 gtk_widget_show (sxed->dialog);
1325 gtk_notebook_set_current_page (GTK_NOTEBOOK (sxed->notebook), 0);
1328 gtk_widget_queue_resize (GTK_WIDGET (sxed->example_cal));
1333 gtk_widget_grab_focus (GTK_WIDGET (sxed->nameEntry));
1335 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, sxed);
1336 g_object_unref (G_OBJECT (builder));
1343 schedXact_editor_create_freq_sel (GncSxEditorDialog *sxed)
1346 GtkWidget *example_cal_scrolled_win = NULL;
1348 b = GTK_BOX (gtk_builder_get_object (sxed->builder,
"gncfreq_hbox"));
1352 xaccSchedXactionGetStartDate (sxed->sx)));
1353 g_assert (sxed->gncfreq);
1354 g_signal_connect (sxed->gncfreq,
"changed",
1355 G_CALLBACK (gnc_sxed_freq_changed),
1358 gtk_box_pack_start (GTK_BOX (b), GTK_WIDGET (sxed->gncfreq), TRUE, TRUE, 0);
1360 b = GTK_BOX (gtk_builder_get_object (sxed->builder,
"example_cal_hbox"));
1362 example_cal_scrolled_win = gtk_scrolled_window_new (NULL, NULL);
1363 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (example_cal_scrolled_win),
1364 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1365 gtk_box_pack_start (GTK_BOX (b), example_cal_scrolled_win, TRUE, TRUE, 0);
1367 sxed->dense_cal_model = gnc_dense_cal_store_new (EX_CAL_NUM_MONTHS * 31);
1368 sxed->example_cal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model (GTK_WINDOW(sxed->dialog),
1369 GNC_DENSE_CAL_MODEL(sxed->dense_cal_model)));
1370 g_assert (sxed->example_cal);
1371 gnc_dense_cal_set_num_months (sxed->example_cal, EX_CAL_NUM_MONTHS);
1372 gnc_dense_cal_set_months_per_col (sxed->example_cal, EX_CAL_MO_PER_COL);
1373 gtk_container_add (GTK_CONTAINER (example_cal_scrolled_win), GTK_WIDGET (sxed->example_cal));
1376 gtk_widget_show_all (example_cal_scrolled_win);
1381 schedXact_editor_create_ledger (GncSxEditorDialog *sxed)
1383 SplitRegister *splitreg;
1384 GtkWidget *main_vbox;
1392 main_vbox = GTK_WIDGET (gtk_builder_get_object (sxed->builder,
"register_vbox"));
1393 sxed->embed_window =
1395 gnc_sxed_menu_entries,
1396 gnc_sxed_menu_n_entries,
1397 "gnc-embedded-register-window.ui",
1401 gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (sxed->embed_window),
1409 gtk_widget_insert_action_group (GTK_WIDGET(sxed->embed_window),
1414 NUM_LEDGER_LINES_DEFAULT, FALSE);
1420 splitreg->type, splitreg->style,
1430 schedXact_editor_populate (GncSxEditorDialog *sxed)
1434 SplitRegister *splitReg;
1437 gboolean enabledState, autoCreateState, notifyState;
1439 name = xaccSchedXactionGetName (sxed->sx);
1442 gtk_entry_set_text (sxed->nameEntry, name);
1445 gd = xaccSchedXactionGetLastOccurDate (sxed->sx);
1446 if (g_date_valid (gd))
1450 gtk_label_set_text (sxed->lastOccurLabel, dateBuf);
1454 gtk_label_set_text (sxed->lastOccurLabel, _(
"(never)"));
1460 if (g_date_valid (gd))
1462 gtk_toggle_button_set_active (sxed->optEndDate, TRUE);
1464 gnc_date_edit_set_time (sxed->endDateEntry, tmpDate);
1466 set_endgroup_toggle_states (sxed, END_DATE);
1470 gint numOccur = xaccSchedXactionGetNumOccur (sxed->sx);
1471 gint numRemain = xaccSchedXactionGetRemOccur (sxed->sx);
1473 gtk_toggle_button_set_active (sxed->optEndCount, TRUE);
1475 gtk_spin_button_set_value (GTK_SPIN_BUTTON (sxed->endCountSpin), numOccur);
1476 gtk_spin_button_set_value (GTK_SPIN_BUTTON (sxed->endRemainSpin), numRemain);
1478 set_endgroup_toggle_states (sxed, END_OCCUR);
1482 gtk_toggle_button_set_active (sxed->optEndNone, TRUE);
1483 set_endgroup_toggle_states (sxed, END_NEVER);
1486 enabledState = xaccSchedXactionGetEnabled (sxed->sx);
1487 gtk_toggle_button_set_active (sxed->enabledOpt, enabledState);
1499 xaccSchedXactionGetAutoCreate (sxed->sx,
1503 gtk_toggle_button_set_active (sxed->autocreateOpt, autoCreateState);
1504 if (!autoCreateState)
1506 notifyState = FALSE;
1508 gtk_toggle_button_set_active (sxed->notifyOpt, notifyState);
1519 xaccSchedXactionGetAdvanceCreation (sxed->sx);
1521 if (daysInAdvance != 0)
1523 gtk_toggle_button_set_active (sxed->advanceOpt, TRUE);
1524 gtk_spin_button_set_value (sxed->advanceSpin,
1525 (gfloat)daysInAdvance);
1537 xaccSchedXactionGetAdvanceReminder (sxed->sx);
1539 if (daysInAdvance != 0)
1541 gtk_toggle_button_set_active (sxed->remindOpt, TRUE);
1542 gtk_spin_button_set_value (sxed->remindSpin,
1543 (gfloat)daysInAdvance);
1554 GList *splitList = xaccSchedXactionGetSplits (sxed->sx);
1560 g_list_free (splitList);
1564 gnc_sxed_update_cal (sxed);
1569 set_endgroup_toggle_states (GncSxEditorDialog *sxed, EndType type)
1571 sxed->end_type = type;
1572 update_sensitivity (sxed);
1577 endgroup_rb_toggled_cb (GtkButton *b, gpointer d)
1580 GncSxEditorDialog *sxed;
1583 sxed = (GncSxEditorDialog*)d;
1584 id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b),
"whichOneAmI"));
1588 case END_NEVER_OPTION:
1589 set_endgroup_toggle_states (sxed, END_NEVER);
1591 case END_DATE_OPTION:
1592 set_endgroup_toggle_states (sxed, END_DATE);
1594 case NUM_OCCUR_OPTION:
1595 set_endgroup_toggle_states (sxed, END_OCCUR);
1598 g_critical (
"Unknown id %d",
id);
1601 gnc_sxed_update_cal (sxed);
1612 gnc_sxed_reg_check_close (GncSxEditorDialog *sxed)
1614 gboolean pending_changes;
1616 const char *message =
1617 _(
"The current template transaction " 1618 "has been changed. " 1619 "Would you like to record the changes?");
1623 if (!pending_changes)
1628 if (gnc_verify_dialog (GTK_WINDOW (sxed->dialog), TRUE,
"%s", message))
1643 editor_component_sx_equality (gpointer
find_data,
1647 == ((GncSxEditorDialog*)user_data)->sx);
1651 gnc_sxed_update_cal (GncSxEditorDialog *sxed)
1653 GList *recurrences = NULL;
1654 GDate start_date, first_date;
1656 g_date_clear (&start_date, 1);
1658 gnc_frequency_save_to_recurrence (sxed->gncfreq, &recurrences, &start_date);
1659 recurrenceListNextInstance (recurrences, &start_date, &first_date);
1664 const GDate *last_sx_inst;
1666 last_sx_inst = xaccSchedXactionGetLastOccurDate (sxed->sx);
1667 if (g_date_valid (last_sx_inst)
1668 && g_date_valid (&first_date)
1669 && g_date_compare (last_sx_inst, &first_date) > 0)
1673 start_date = *last_sx_inst;
1674 recurrenceListNextInstance (recurrences, &start_date, &first_date);
1678 g_date_subtract_days (&start_date, 1);
1682 if (!g_date_valid (&first_date))
1686 gboolean do_nothing = TRUE;
1689 Recurrence *r = g_list_nth_data (recurrences, 0);
1690 if (r && r->ptype == PERIOD_ONCE)
1696 gnc_dense_cal_store_clear (sxed->dense_cal_model);
1701 gnc_dense_cal_store_update_name (sxed->dense_cal_model, xaccSchedXactionGetName (sxed->sx));
1703 gchar *schedule_desc = recurrenceListToCompactString (recurrences);
1704 gnc_dense_cal_store_update_info (sxed->dense_cal_model, schedule_desc);
1705 g_free (schedule_desc);
1712 if (gtk_toggle_button_get_active (sxed->optEndDate))
1715 g_date_clear (&end_date, 1);
1717 gnc_dense_cal_store_update_recurrences_date_end (sxed->dense_cal_model, &start_date, recurrences, &end_date);
1719 else if (gtk_toggle_button_get_active (sxed->optEndNone))
1721 gnc_dense_cal_store_update_recurrences_no_end (sxed->dense_cal_model, &start_date, recurrences);
1723 else if (gtk_toggle_button_get_active (sxed->optEndCount))
1726 = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (sxed->endRemainSpin));
1727 gnc_dense_cal_store_update_recurrences_count_end (sxed->dense_cal_model, &start_date, recurrences, num_remain);
1731 g_error (
"unknown end condition");
1735 recurrenceListFree (&recurrences);
1742 gnc_sxed_update_cal ((GncSxEditorDialog*)ud);
1747 sxed_excal_update_adapt_cb (GtkWidget *o, gpointer ud)
1749 gnc_sxed_update_cal ((GncSxEditorDialog*)ud);
1754 on_sx_check_toggled_cb (GtkWidget *togglebutton, gpointer user_data)
1756 GtkWidget *widget_auto;
1757 GtkWidget *widget_notify;
1760 PINFO (
"Togglebutton is %p and user_data is %p", togglebutton, user_data);
1761 PINFO (
"Togglebutton builder name is %s", gtk_buildable_get_name (GTK_BUILDABLE (togglebutton)));
1764 table = g_object_get_data (G_OBJECT (user_data),
"prefs_widget_hash");
1767 widget_auto = g_hash_table_lookup (
table,
"pref/" GNC_PREFS_GROUP_SXED
"/" GNC_PREF_CREATE_AUTO);
1768 widget_notify = g_hash_table_lookup (
table,
"pref/" GNC_PREFS_GROUP_SXED
"/" GNC_PREF_NOTIFY);
1770 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget_auto)))
1771 gtk_widget_set_sensitive (widget_notify, TRUE);
1773 gtk_widget_set_sensitive (widget_notify, FALSE);
1776 widget_auto = g_hash_table_lookup (
table,
"pref/" GNC_PREFS_GROUP_STARTUP
"/" GNC_PREF_RUN_AT_FOPEN);
1777 widget_notify = g_hash_table_lookup (
table,
"pref/" GNC_PREFS_GROUP_STARTUP
"/" GNC_PREF_SHOW_AT_FOPEN);
1779 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget_auto)))
1780 gtk_widget_set_sensitive (widget_notify, TRUE);
1782 gtk_widget_set_sensitive (widget_notify, FALSE);
1789 typedef struct _acct_deletion_handler_data
1791 GList *affected_sxes;
1798 _open_editors (GtkDialog *dialog, gint response_code, gpointer data)
1801 gtk_widget_hide (adhd->dialog);
1804 for (sx_iter = adhd->affected_sxes; sx_iter; sx_iter = sx_iter->next)
1806 gnc_ui_scheduled_xaction_editor_dialog_create (GTK_WINDOW (adhd->parent),
1807 (SchedXaction*)sx_iter->data, FALSE);
1810 g_list_free (adhd->affected_sxes);
1811 gtk_widget_destroy (GTK_WIDGET (adhd->dialog));
1817 _sx_engine_event_handler (
QofInstance *ent,
QofEventId event_type, gpointer user_data, gpointer evt_data)
1821 GList *affected_sxes;
1823 if (!(event_type & QOF_EVENT_DESTROY))
1825 if (!GNC_IS_ACCOUNT (ent))
1827 acct = GNC_ACCOUNT (ent);
1837 GtkBuilder *builder;
1840 GtkListStore *name_list;
1842 GtkTreeViewColumn *name_column;
1843 GtkCellRenderer *renderer;
1845 builder = gtk_builder_new ();
1846 gnc_builder_add_from_file (builder,
"dialog-sx.glade",
"account_deletion_dialog");
1848 dialog = GTK_WIDGET (gtk_builder_get_object (builder,
"account_deletion_dialog"));
1851 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
1853 list = GTK_TREE_VIEW (gtk_builder_get_object (builder,
"sx_list"));
1856 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (list), gnc_tree_view_get_grid_lines_pref ());
1859 data->dialog = dialog;
1860 data->parent = parent;
1861 data->affected_sxes = affected_sxes;
1862 name_list = gtk_list_store_new (1, G_TYPE_STRING);
1863 for (sx_iter = affected_sxes; sx_iter; sx_iter = sx_iter->next)
1869 sx = (SchedXaction*)sx_iter->data;
1870 sx_name = xaccSchedXactionGetName (sx);
1871 gtk_list_store_append (name_list, &iter);
1872 gtk_list_store_set (name_list, &iter, 0, sx_name, -1);
1874 gtk_tree_view_set_model (list, GTK_TREE_MODEL (name_list));
1875 g_object_unref (G_OBJECT (name_list));
1877 renderer = gtk_cell_renderer_text_new ();
1878 name_column = gtk_tree_view_column_new_with_attributes (_(
"Name"),
1881 gtk_tree_view_append_column (list, name_column);
1883 g_signal_connect (G_OBJECT (dialog),
"response",
1884 G_CALLBACK (_open_editors), data);
1886 gtk_widget_show_all (GTK_WIDGET (dialog));
1887 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, data);
1888 g_object_unref (G_OBJECT (builder));
1894 gnc_ui_sx_initialize (
void)
1898 gnc_hook_add_dangler (HOOK_BOOK_OPENED,
1899 (GFunc)gnc_sx_sxsincelast_book_opened, NULL, NULL);
1904 "create_days_adj,remind_days_adj,sx_prefs",
1905 _(
"Scheduled Transactions"));
const GDate * xaccSchedXactionGetEndDate(const SchedXaction *sx)
Returns invalid date when there is no end-date specified.
gint xaccAccountForEachTransaction(const Account *acc, TransactionCallback proc, void *data)
The xaccAccountForEachTransaction() routine will traverse all of the transactions in account and call...
Public declarations for GncLedgerDisplay class.
void gnc_sx_set_schedule(SchedXaction *sx, GList *schedule)
void gnc_ledger_display_refresh(GNCLedgerDisplay *ld)
redisplay/redraw only the indicated window.
void gnc_sx_set_instance_count(SchedXaction *sx, gint instance_num)
Sets the instance count to something other than the default.
GList * gnc_sx_get_schedule(const SchedXaction *sx)
void gnc_preferences_add_page(const gchar *filename, const gchar *widgetname, const gchar *tabname)
This function adds a full page of preferences to the preferences dialog.
gchar * gnc_num_dbg_to_string(gnc_numeric n)
Convert to string.
void qof_instance_get(const QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_get.
The instance data structure for a content plugin.
Date and Time handling routines.
gboolean gnc_split_register_save(SplitRegister *reg, gboolean do_commit)
Copy the contents of the current cursor to a split.
QofBook * qof_instance_get_book(gconstpointer inst)
Return the book pointer.
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.
utility functions for the GnuCash UI
#define PINFO(format, args...)
Print an informational note.
void xaccSchedXactionSetNumOccur(SchedXaction *sx, gint new_num)
Set to '0' to turn off number-of-occurrences definition.
void gnc_plugin_page_merge_actions(GncPluginPage *page)
Add the actions for a content page to the specified window.
void gnc_embedded_window_close_page(GncEmbeddedWindow *window, GncPluginPage *page)
Remove a data plugin page from a window.
size_t qof_print_gdate(char *buf, size_t bufflen, const GDate *gd)
Convenience; calls through to qof_print_date_dmy_buff().
#define DEBUG(format, args...)
Print a debugging message.
gboolean qof_instance_get_destroying(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object is about to be destroyed.
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal.
void gnc_embedded_window_open_page(GncEmbeddedWindow *window, GncPluginPage *page)
Display a data plugin page in a window.
GSimpleActionGroup * gnc_plugin_page_get_action_group(GncPluginPage *page)
Retrieve the GSimpleActionGroup object associated with this page.
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a+b.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
GncEmbeddedWindow * gnc_embedded_window_new(const gchar *action_group_name, GActionEntry *action_entries, gint n_action_entries, const gchar *ui_filename, GtkWidget *enclosing_win, gboolean add_accelerators, gpointer user_data)
Create a new gnc embedded window plugin.
void gnc_split_register_load(SplitRegister *reg, GList *slist, GList *pre_filter_slist, Account *default_account)
Populates the rows of a register.
GList * gnc_sx_get_sxes_referencing_account(QofBook *book, Account *acct)
GncPluginPage * gnc_plugin_page_register_new_ledger(GNCLedgerDisplay *ledger)
Create a new "register" plugin page, given a pointer to an already created ledger.
gint qof_event_register_handler(QofEventHandler handler, gpointer user_data)
Register a handler for events.
void gnc_split_register_redraw(SplitRegister *reg)
Causes a redraw of the register window associated with reg.
Functions providing a register page for the GnuCash UI.
Account handling public routines.
Find the least common multiple of the arguments' denominators and use that as the denominator of the ...
gint QofEventId
Define the type of events allowed.
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome's yelp for linux, and open to a given link within a gi...
gboolean gnc_split_register_changed(SplitRegister *reg)
Returns TRUE if the register has changed cells.
Anchor Scheduled Transaction info in a book.
Functions for adding plugins to a GnuCash window.
void gnc_split_register_config(SplitRegister *reg, SplitRegisterType newtype, SplitRegisterStyle newstyle, gboolean use_double_line)
Sets a split register's type, style or line use.
const gchar * gnc_plugin_page_get_simple_action_group_name(GncPluginPage *page)
Retrieve the simple action group name associated with this plugin page.
const char * xaccTransGetDescription(const Transaction *trans)
Gets the transaction Description.
Public declarations of GnucashRegister class.
gnc_numeric gnc_numeric_abs(gnc_numeric a)
Returns a newly created gnc_numeric that is the absolute value of the given gnc_numeric value...
#define MAX_DATE_LENGTH
The maximum length of a string created by the date printers.
Dialog for handling user preferences.
#define xaccSchedXactionGetGUID(X)
All type declarations for the whole Gnucash engine.
int xaccSPrintAmount(char *bufp, gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
Generic api to store and retrieve preferences.
void gnc_split_register_cancel_cursor_trans_changes(SplitRegister *reg)
Cancels any changes made to the current pending transaction, reloads the table from the engine...
GNCLedgerDisplay * gnc_ledger_display_template_gl(char *id)
Displays a template ledger.
void xaccSchedXactionSetName(SchedXaction *sx, const gchar *newName)
A copy of the name is made.
void gnc_gdate_set_time64(GDate *gd, time64 time)
Set a GDate to a time64.
gchar * guid_to_string(const GncGUID *guid)
The guid_to_string() routine returns a null-terminated string encoding of the id. ...
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
void gnc_split_register_set_auto_complete(SplitRegister *reg, gboolean do_auto_complete)
Sets whether a register uses auto-completion.
Functions that are supported by all types of windows.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
time64 gnc_time(time64 *tbuf)
get the current time
const char * xaccSplitGetMemo(const Split *split)
Returns the memo string.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
SplitRegister * gnc_ledger_display_get_split_register(GNCLedgerDisplay *ld)
return the split register associated with a ledger display
void gnc_split_register_show_present_divider(SplitRegister *reg, gboolean show_present)
If TRUE, visually indicate the demarcation between splits with post dates prior to the present...
gboolean xaccSchedXactionHasOccurDef(const SchedXaction *sx)
Returns true if the scheduled transaction has a defined number of occurrences, false if not...
Scheduled Transactions public handling routines.
gint gnc_list_length_cmp(const GList *list, size_t len)
Scans the GList elements the minimum number of iterations required to test it against a specified siz...
void xaccSchedXactionSetEndDate(SchedXaction *sx, const GDate *newEnd)
Set to an invalid GDate to turn off 'end-date' definition.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
The type used to store guids in C.
time64 gnc_time64_get_day_start_gdate(const GDate *date)
The gnc_time64_get_day_start() routine will take the given time in GLib GDate format and adjust it to...
void xaccSchedXactionDestroy(SchedXaction *sx)
Cleans up and frees a SchedXaction and its associated data.
void gnc_plugin_page_register_set_options(GncPluginPage *plugin_page, gint lines_default, gboolean read_only)
Set various register options on a newly created "register" plugin page.
SplitList * xaccTransGetSplitList(const Transaction *trans)
The xaccTransGetSplitList() method returns a GList of the splits in a transaction.
gdouble gnc_prefs_get_float(const gchar *group, const gchar *pref_name)
Get an float value from the preferences backend.
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)
The xaccAccountLookup() subroutine will return the account associated with the given id...