48#include <glib/gi18n.h>
54#include "dialog-sx-editor.h"
55#include "dialog-utils.h"
56#include "dialog-sx-since-last-run.h"
58#include "gnc-component-manager.h"
60#include "gnc-dense-cal.h"
67#include "gnc-plugin-page-sx-list.h"
69#include "gnc-session.h"
70#include "gnc-sx-instance-dense-cal-adapter.h"
72#include "gnc-sx-list-tree-model-adapter.h"
79#define G_LOG_DOMAIN "gnc.gui.plugin-page.sx-list"
81G_GNUC_UNUSED
static QofLogModule log_module = GNC_MOD_GUI_SX;
83#define PLUGIN_PAGE_SX_LIST_CM_CLASS "plugin-page-sx-list"
84#define STATE_SECTION "SX Transaction List"
85#define GNC_PREF_DIVIDER_POS "divider-position"
86#define GNC_PREF_NUM_OF_MONTHS "number-of-months"
93 gint gnc_component_id;
95 GncSxInstanceDenseCalAdapter *dense_cal_model;
98 GncSxInstanceModel* instances;
99 GtkTreeView* tree_view;
100 GList *selected_list;
104G_DEFINE_TYPE_WITH_PRIVATE(
GncPluginPageSxList, gnc_plugin_page_sx_list, GNC_TYPE_PLUGIN_PAGE)
106#define GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(o) \
107 ((GncPluginPageSxListPrivate*)gnc_plugin_page_sx_list_get_instance_private ((GncPluginPageSxList*)o))
113static void gnc_plugin_page_sx_list_dispose (GObject *
object);
114static void gnc_plugin_page_sx_list_finalize (GObject *
object);
116static GtkWidget *gnc_plugin_page_sx_list_create_widget (
GncPluginPage *plugin_page);
117static void gnc_plugin_page_sx_list_destroy_widget (
GncPluginPage *plugin_page);
118static void gnc_plugin_page_sx_list_save_page (
GncPluginPage *plugin_page, GKeyFile *file,
const gchar *group);
119static GncPluginPage *gnc_plugin_page_sx_list_recreate_page (GtkWidget *window, GKeyFile *file,
const gchar *group);
121static gboolean gppsl_key_press_cb (GtkTreeView *tree_view, GdkEventKey *event, gpointer user_data);
122static void gppsl_row_activated_cb (GtkTreeView *tree_view, GtkTreePath *path,
123 GtkTreeViewColumn *column, gpointer user_data);
125static void gnc_plugin_page_sx_list_cmd_new (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
126static void gnc_plugin_page_sx_list_cmd_edit (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
127static void gnc_plugin_page_sx_list_cmd_delete (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
128static void gnc_plugin_page_sx_list_cmd_run (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
129static void gnc_plugin_page_sx_list_cmd_refresh (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
130static void gnc_plugin_page_sx_list_cmd_save_layout (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
131static void gnc_plugin_page_sx_list_cmd_edit_tax_options (GSimpleAction *simple, GVariant *paramter, gpointer user_data);
134static GActionEntry gnc_plugin_page_sx_list_actions [] =
136 {
"SxListAction",
nullptr,
nullptr,
nullptr,
nullptr },
137 {
"SxListNewAction", gnc_plugin_page_sx_list_cmd_new,
nullptr,
nullptr,
nullptr },
138 {
"SxListEditAction", gnc_plugin_page_sx_list_cmd_edit,
nullptr,
nullptr,
nullptr },
139 {
"SxListDeleteAction", gnc_plugin_page_sx_list_cmd_delete,
nullptr,
nullptr,
nullptr },
140 {
"SxListRunAction", gnc_plugin_page_sx_list_cmd_run,
nullptr,
nullptr,
nullptr },
141 {
"ViewRefreshAction", gnc_plugin_page_sx_list_cmd_refresh,
nullptr,
nullptr,
nullptr },
142 {
"ViewSaveLayoutAction", gnc_plugin_page_sx_list_cmd_save_layout,
nullptr,
nullptr,
nullptr },
143 {
"EditTaxOptionsAction", gnc_plugin_page_sx_list_cmd_edit_tax_options,
nullptr,
nullptr,
nullptr },
146static guint gnc_plugin_page_sx_list_n_actions = G_N_ELEMENTS(gnc_plugin_page_sx_list_actions);
149static const gchar *gnc_plugin_load_ui_items [] =
155 "SchedulePlaceholder0",
165 if (
object && GNC_IS_PLUGIN_PAGE_SX_LIST(object->data))
166 plugin_page = GNC_PLUGIN_PAGE_SX_LIST(object->data);
171 return GNC_PLUGIN_PAGE(plugin_page);
180gnc_plugin_page_sx_list_focus_widget (
GncPluginPage *sx_plugin_page)
182 if (GNC_IS_PLUGIN_PAGE_SX_LIST(sx_plugin_page))
185 GtkTreeView *tree_view = priv->tree_view;
189 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
192 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
true);
195 g_simple_action_set_enabled (G_SIMPLE_ACTION(action),
false);
199 gnc_plugin_load_ui_items);
201 if (GTK_IS_TREE_VIEW(tree_view))
203 if (!gtk_widget_is_focus (GTK_WIDGET(tree_view)))
204 gtk_widget_grab_focus (GTK_WIDGET(tree_view));
213 GObjectClass *object_class = G_OBJECT_CLASS(klass);
216 object_class->dispose = gnc_plugin_page_sx_list_dispose;
217 object_class->finalize = gnc_plugin_page_sx_list_finalize;
219 gnc_plugin_class->
tab_icon = GNC_ICON_ACCOUNT;
220 gnc_plugin_class->
plugin_name = GNC_PLUGIN_PAGE_SX_LIST_NAME;
221 gnc_plugin_class->
create_widget = gnc_plugin_page_sx_list_create_widget;
222 gnc_plugin_class->
destroy_widget = gnc_plugin_page_sx_list_destroy_widget;
223 gnc_plugin_class->
save_page = gnc_plugin_page_sx_list_save_page;
224 gnc_plugin_class->
recreate_page = gnc_plugin_page_sx_list_recreate_page;
232 GSimpleActionGroup *simple_action_group;
236 parent = GNC_PLUGIN_PAGE(plugin_page);
237 g_object_set(G_OBJECT(plugin_page),
238 "page-name",
_(
"Scheduled Transactions"),
239 "ui-description",
"gnc-plugin-page-sx-list.ui",
244 g_action_map_add_action_entries (G_ACTION_MAP(simple_action_group),
245 gnc_plugin_page_sx_list_actions,
246 gnc_plugin_page_sx_list_n_actions,
252gnc_plugin_page_sx_list_dispose (GObject *
object)
257 page = GNC_PLUGIN_PAGE_SX_LIST(
object);
258 g_return_if_fail (GNC_IS_PLUGIN_PAGE_SX_LIST(page));
259 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
260 g_return_if_fail (priv !=
nullptr);
262 g_return_if_fail (!priv->disposed);
263 priv->disposed =
true;
265 g_object_unref (G_OBJECT(priv->dense_cal_model));
266 priv->dense_cal_model =
nullptr;
267 g_object_unref (GTK_WIDGET(priv->gdcal));
268 priv->gdcal =
nullptr;
269 g_object_unref (G_OBJECT(priv->instances));
270 priv->instances =
nullptr;
272 G_OBJECT_CLASS(gnc_plugin_page_sx_list_parent_class)->dispose (
object);
277gnc_plugin_page_sx_list_finalize (GObject *
object)
282 page = GNC_PLUGIN_PAGE_SX_LIST(
object);
283 g_return_if_fail (GNC_IS_PLUGIN_PAGE_SX_LIST(page));
284 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
285 g_return_if_fail (priv !=
nullptr);
287 G_OBJECT_CLASS(gnc_plugin_page_sx_list_parent_class)->finalize (
object);
293gnc_plugin_page_sx_list_refresh_cb (GHashTable *changes, gpointer user_data)
295 auto page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
298 g_return_if_fail (GNC_IS_PLUGIN_PAGE_SX_LIST(page));
304 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
305 gtk_widget_queue_draw (priv->widget);
310gnc_plugin_page_sx_list_close_cb (gpointer user_data)
318gppsl_selection_changed_cb (GtkTreeSelection *selection, gpointer user_data)
321 GAction *edit_action, *delete_action, *run_action;
322 gboolean selection_state =
true;
324 page = GNC_PLUGIN_PAGE(user_data);
328 selection_state = gtk_tree_selection_count_selected_rows (selection) == 0
331 g_simple_action_set_enabled (G_SIMPLE_ACTION(edit_action), selection_state);
332 g_simple_action_set_enabled (G_SIMPLE_ACTION(delete_action), selection_state);
333 g_simple_action_set_enabled (G_SIMPLE_ACTION(run_action), selection_state);
342 if (reset && priv->selected_list)
344 g_list_free (priv->selected_list);
345 priv->selected_list =
nullptr;
348 priv->selected_list = g_list_prepend (priv->selected_list, sx);
356 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->tree_view));
357 gboolean found =
false;
359 if (priv->selected_list)
362 for (GList *list = priv->selected_list; list !=
nullptr; list = list->next)
364 SchedXaction *sx = GNC_SCHEDXACTION(list->data);
365 GtkTreePath *path = gtk_tree_path_new_first ();
368 while (gnc_tree_view_path_is_valid (GNC_TREE_VIEW(priv->tree_view), path))
370 SchedXaction *sx_tmp = gnc_tree_view_sx_list_get_sx_from_path (
371 GNC_TREE_VIEW_SX_LIST(priv->tree_view), path);
377 gtk_tree_path_next (path);
380 gtk_tree_selection_select_path (selection, path);
382 gtk_tree_path_free (path);
388 GtkTreePath *path = gtk_tree_path_new_first ();
389 gtk_tree_selection_select_path (selection, path);
390 gtk_tree_path_free (path);
399 GtkWidget *menu, *menuitem;
400 gchar *full_action_name;
403 menu = gtk_menu_new();
405 menuitem = gtk_menu_item_new_with_mnemonic (
_(
"_New Schedule"));
406 full_action_name = g_strconcat (group_name,
".SxListNewAction",
nullptr);
407 gtk_actionable_set_action_name (GTK_ACTIONABLE(menuitem), full_action_name);
408 g_free (full_action_name);
409 gtk_menu_shell_append (GTK_MENU_SHELL(menu), menuitem);
411 menuitem = gtk_menu_item_new_with_mnemonic (
_(
"_Edit Schedule"));
412 full_action_name = g_strconcat (group_name,
".SxListEditAction",
nullptr);
413 gtk_actionable_set_action_name (GTK_ACTIONABLE(menuitem), full_action_name);
414 g_free (full_action_name);
415 gtk_menu_shell_append (GTK_MENU_SHELL(menu), menuitem);
417 menuitem = gtk_menu_item_new_with_mnemonic (
_(
"_Delete Schedule"));
418 full_action_name = g_strconcat (group_name,
".SxListDeleteAction",
nullptr);
419 gtk_actionable_set_action_name (GTK_ACTIONABLE(menuitem), full_action_name);
420 g_free (full_action_name);
421 gtk_menu_shell_append (GTK_MENU_SHELL(menu), menuitem);
423 menuitem = gtk_menu_item_new_with_mnemonic (
_(
"_Run Schedule"));
424 full_action_name = g_strconcat (group_name,
".SxListRunAction",
nullptr);
425 gtk_actionable_set_action_name (GTK_ACTIONABLE(menuitem), full_action_name);
426 g_free (full_action_name);
427 gtk_menu_shell_append (GTK_MENU_SHELL(menu), menuitem);
429 gtk_menu_attach_to_widget (GTK_MENU(menu), GTK_WIDGET(priv->tree_view),
nullptr);
430 gtk_widget_show_all (menu);
431 gtk_menu_popup_at_pointer (GTK_MENU(menu), event);
435treeview_button_press (GtkTreeView *treeview, GdkEvent *event,
439 GtkTreeView *tree_view = GTK_TREE_VIEW(priv->tree_view);
441 if (event->type == GDK_BUTTON_PRESS)
443 GdkEventButton *event_button = (GdkEventButton*)event;
444 if (event_button->button == GDK_BUTTON_SECONDARY)
446 GtkTreePath *path =
nullptr;
447 if (gtk_tree_view_get_path_at_pos (priv->tree_view, event_button->x, event_button->y,
448 &path,
nullptr,
nullptr,
nullptr))
450 GtkTreeSelection *selection = gtk_tree_view_get_selection (priv->tree_view);
452 if (!gtk_tree_selection_path_is_selected (selection, path))
454 gtk_tree_selection_unselect_all (selection);
455 gtk_tree_selection_select_path (selection, path);
458 gtk_tree_path_free (path);
460 treeview_popup (tree_view, event, page);
470 treeview_popup (treeview,
nullptr, page);
475gnc_plugin_page_sx_list_create_widget (
GncPluginPage *plugin_page)
485 page = GNC_PLUGIN_PAGE_SX_LIST(plugin_page);
486 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
487 if (priv->widget !=
nullptr)
493 widget = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
494 priv->widget = widget;
495 gtk_widget_show (priv->widget);
498 gtk_widget_set_name (GTK_WIDGET(priv->widget),
"gnc-id-sx-page");
501 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
502 gtk_box_set_homogeneous (GTK_BOX(vbox),
false);
503 gtk_paned_pack1 (GTK_PANED(widget), vbox,
true,
false);
505 label = gtk_label_new (
_(
"Transactions"));
506 gnc_widget_style_context_add_class (GTK_WIDGET(label),
"gnc-class-strong");
507 gtk_widget_set_margin_start (GTK_WIDGET(label), 6);
508 gnc_label_set_alignment (label, 0.0, 0);
509 gtk_widget_show (label);
510 gtk_box_pack_start (GTK_BOX(vbox), label,
false,
false, 0);
511 gtk_widget_show (vbox);
514 swin = gtk_scrolled_window_new (
nullptr,
nullptr);
515 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(swin),
516 GTK_POLICY_AUTOMATIC,
517 GTK_POLICY_AUTOMATIC);
518 gtk_box_pack_start (GTK_BOX(vbox), swin,
true,
true, 5);
519 gtk_widget_show (swin);
522 gtk_paned_set_position (GTK_PANED(priv->widget),
524 GNC_PREF_DIVIDER_POS));
528 g_date_clear (&end, 1);
530 g_date_add_years (&end, 1);
531 priv->instances = GNC_SX_INSTANCE_MODEL(gnc_sx_get_instances (&end,
true));
535 GAction *edit_action, *delete_action, *run_action;
539 g_simple_action_set_enabled (G_SIMPLE_ACTION(edit_action),
false);
540 g_simple_action_set_enabled (G_SIMPLE_ACTION(delete_action),
false);
541 g_simple_action_set_enabled (G_SIMPLE_ACTION(run_action),
false);
545 GtkTreeSelection *selection;
546 GtkTreePath *path = gtk_tree_path_new_first ();
548 priv->tree_view = GTK_TREE_VIEW(gnc_tree_view_sx_list_new (priv->instances));
549 g_object_set (G_OBJECT(priv->tree_view),
550 "state-section", STATE_SECTION,
551 "show-column-menu",
true,
553 gtk_container_add (GTK_CONTAINER(swin), GTK_WIDGET(priv->tree_view));
555 selection = gtk_tree_view_get_selection (priv->tree_view);
556 gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
558 g_signal_connect (G_OBJECT(selection),
"changed",
559 (GCallback)gppsl_selection_changed_cb, (gpointer)page);
560 g_signal_connect (G_OBJECT(priv->tree_view),
"key-press-event",
561 (GCallback)gppsl_key_press_cb, (gpointer)page);
562 g_signal_connect (G_OBJECT(priv->tree_view),
"row-activated",
563 (GCallback)gppsl_row_activated_cb, (gpointer)page);
564 g_signal_connect (G_OBJECT(gtk_tree_view_get_model (GTK_TREE_VIEW(priv->tree_view))),
565 "model-populated", (GCallback)gppsl_model_populated_cb, (gpointer)page);
567 gtk_tree_selection_select_path (selection, path);
568 gtk_tree_path_free (path);
571 g_signal_connect (G_OBJECT(priv->tree_view),
"button-press-event",
572 G_CALLBACK(treeview_button_press), page);
573 g_signal_connect (G_OBJECT(priv->tree_view),
"popup-menu",
574 G_CALLBACK(treeview_popup_menu), page);
577 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
578 gtk_box_set_homogeneous (GTK_BOX(vbox),
false);
579 gtk_paned_pack2 (GTK_PANED(widget), vbox,
true,
false);
581 label = gtk_label_new (
_(
"Upcoming Transactions"));
582 gnc_widget_style_context_add_class (GTK_WIDGET(label),
"gnc-class-strong");
583 gtk_widget_set_margin_start (GTK_WIDGET(label), 6);
584 gnc_label_set_alignment (label, 0.0, 0);
585 gtk_widget_show (label);
587 gtk_box_pack_start (GTK_BOX(vbox), label,
false,
false, 0);
588 gtk_widget_show (vbox);
591 swin = gtk_scrolled_window_new (
nullptr,
nullptr);
592 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(swin),
593 GTK_POLICY_AUTOMATIC,
594 GTK_POLICY_AUTOMATIC);
595 gtk_box_pack_start (GTK_BOX(vbox), swin,
true,
true, 5);
596 gtk_widget_show (swin);
599 priv->dense_cal_model = gnc_sx_instance_dense_cal_adapter_new (GNC_SX_INSTANCE_MODEL(priv->instances));
600 priv->gdcal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model (window, GNC_DENSE_CAL_MODEL(priv->dense_cal_model)));
601 g_object_ref_sink (priv->gdcal);
604 auto num_months =
gnc_prefs_get_int (GNC_PREFS_GROUP_SXED, GNC_PREF_NUM_OF_MONTHS);
607 PWARN (
"Got invalid value '0' for number of months to display. This suggests a gsettings configuration issue. Continuing with a default value of 12 instead.");
610 gnc_dense_cal_set_num_months (priv->gdcal, num_months);
612 gtk_container_add (GTK_CONTAINER(swin), GTK_WIDGET(priv->gdcal));
615 priv->gnc_component_id = gnc_register_gui_component (
"plugin-page-sx-list",
616 gnc_plugin_page_sx_list_refresh_cb,
617 gnc_plugin_page_sx_list_close_cb,
619 gnc_gui_component_set_session (priv->gnc_component_id,
620 gnc_get_current_session ());
622 g_signal_connect (G_OBJECT(plugin_page),
"inserted",
631gnc_plugin_page_sx_list_destroy_widget (
GncPluginPage *plugin_page)
636 page = GNC_PLUGIN_PAGE_SX_LIST(plugin_page);
637 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
643 g_idle_remove_by_data (plugin_page);
647 g_object_unref (G_OBJECT(priv->widget));
648 priv->widget =
nullptr;
651 if (priv->selected_list)
652 g_list_free (priv->selected_list);
654 if (priv->gnc_component_id)
656 gnc_unregister_gui_component (priv->gnc_component_id);
657 priv->gnc_component_id = 0;
670gnc_plugin_page_sx_list_save_page (
GncPluginPage *plugin_page,
672 const gchar *group_name)
677 g_return_if_fail (GNC_IS_PLUGIN_PAGE_SX_LIST(plugin_page));
678 g_return_if_fail (key_file !=
nullptr);
679 g_return_if_fail (group_name !=
nullptr);
681 page = GNC_PLUGIN_PAGE_SX_LIST(plugin_page);
682 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
684 g_key_file_set_integer (key_file, group_name,
"dense_cal_num_months",
685 gnc_dense_cal_get_num_months (priv->gdcal));
687 g_key_file_set_integer (key_file, group_name,
"paned_position",
688 gtk_paned_get_position (GTK_PANED(priv->widget)));
701gnc_plugin_page_sx_list_recreate_page (GtkWidget *window,
703 const gchar *group_name)
708 g_return_val_if_fail (key_file,
nullptr);
709 g_return_val_if_fail (group_name,
nullptr);
713 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
719 GError *err =
nullptr;
720 gint num_months = g_key_file_get_integer (key_file, group_name,
"dense_cal_num_months", &err);
722 gnc_dense_cal_set_num_months (priv->gdcal, num_months);
728 GError *err =
nullptr;
729 gint paned_position = g_key_file_get_integer (key_file, group_name,
730 "paned_position", &err);
732 gtk_paned_set_position (GTK_PANED(priv->widget), paned_position);
737 return GNC_PLUGIN_PAGE(page);
742gnc_plugin_page_sx_list_cmd_new (GSimpleAction *simple,
746 auto plugin_page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
748 SchedXaction *new_sx;
749 gboolean new_sx_flag =
true;
757 g_date_clear (&now, 1);
759 recurrenceSet (r, 1, PERIOD_MONTH, &now, WEEKEND_ADJ_NONE);
761 schedule = g_list_append (schedule, r);
764 gnc_ui_scheduled_xaction_editor_dialog_create (window, new_sx, new_sx_flag);
765 gppsl_update_selected_list (plugin_page,
true, new_sx);
769gnc_plugin_page_sx_list_cmd_refresh (GSimpleAction *simple,
773 auto plugin_page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
776 g_return_if_fail (GNC_IS_PLUGIN_PAGE_SX_LIST(plugin_page));
778 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(plugin_page);
779 gtk_widget_queue_draw (priv->widget);
783gnc_plugin_page_sx_list_cmd_save_layout (GSimpleAction *simple,
787 auto plugin_page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
791 g_return_if_fail (GNC_IS_PLUGIN_PAGE_SX_LIST(plugin_page));
793 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(plugin_page);
795 paned_position = gtk_paned_get_position (GTK_PANED(priv->widget));
801 gnc_dense_cal_get_num_months (priv->gdcal));
805_edit_sx(gpointer data, gpointer user_data)
807 gnc_ui_scheduled_xaction_editor_dialog_create (GTK_WINDOW(user_data),
808 GNC_SCHEDXACTION(data),
false);
812_argument_reorder_fn (GtkTreePath* list_path_data, GncTreeViewSxList* user_tree_view)
814 return gnc_tree_view_sx_list_get_sx_from_path (user_tree_view, list_path_data);
819gnc_plugin_page_sx_list_cmd_edit (GSimpleAction *simple,
823 auto plugin_page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
826 GtkTreeSelection *selection;
827 GList *selected_paths, *to_edit;
830 selection = gtk_tree_view_get_selection (priv->tree_view);
831 selected_paths = gtk_tree_selection_get_selected_rows (selection, &model);
834 g_warning (
"no selection edit.");
839 (GncGMapFunc)_argument_reorder_fn,
842 gppsl_update_selected_list (plugin_page,
true,
nullptr);
843 for (GList *list = to_edit; list !=
nullptr; list = list->next)
845 DEBUG (
"to-edit [%s]\n", xaccSchedXactionGetName (GNC_SCHEDXACTION(list->data)));
846 gppsl_update_selected_list (plugin_page,
false, GNC_SCHEDXACTION(list->data));
849 g_list_foreach (to_edit, (GFunc)_edit_sx, window);
850 g_list_free (to_edit);
851 g_list_foreach (selected_paths, (GFunc)gtk_tree_path_free,
nullptr);
852 g_list_free (selected_paths);
857gnc_plugin_page_sx_list_cmd_edit_tax_options (GSimpleAction *simple,
861 auto plugin_page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
864 ENTER (
"(action %p, page %p)", simple, plugin_page);
865 gnc_tax_info_dialog (window,
nullptr);
870gppsl_is_enable_column_visible (GtkTreeView *tree_view)
872 gboolean retval = FALSE;
873 GList *columns = gtk_tree_view_get_columns (tree_view);
875 for (GList *node = columns; node; node = node->next)
877 GtkTreeViewColumn *col = GTK_TREE_VIEW_COLUMN(node->data);
878 gint
id = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(col), MODEL_COLUMN));
880 if (
id == SXLTMA_COL_ENABLED)
882 retval = gtk_tree_view_column_get_visible(col);
886 g_list_free (columns);
891gppsl_set_toggle (GtkTreeView *tree_view)
893 GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
895 GList *sel_list = gtk_tree_selection_get_selected_rows (selection, &model);
896 gint num_selected = gtk_tree_selection_count_selected_rows (selection);
897 gint num_toggled = 0;
899 for (GList *node = sel_list; node; node = node->next)
901 GtkTreePath *path = (GtkTreePath *)node->data;
904 if (gtk_tree_model_get_iter (model, &iter, path))
908 gtk_tree_model_get (model, &iter, SXLTMA_COL_ENABLED, &toggled, -1);
915 gtk_tree_path_free (path);
917 g_list_free (sel_list);
919 return num_toggled != num_selected;
926 GtkTreeView *tree_view = priv->tree_view;
927 GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
929 GList *sel_list = gtk_tree_selection_get_selected_rows (selection, &model);
930 GList *sx_list =
nullptr;
932 gppsl_update_selected_list (sx_plugin_page,
true,
nullptr);
934 for (GList *node = sel_list; node; node = node->next)
936 GtkTreePath *path = (GtkTreePath *)node->data;
937 GncTreeViewSxList *view = GNC_TREE_VIEW_SX_LIST(tree_view);
938 SchedXaction *sx = gnc_tree_view_sx_list_get_sx_from_path (view, path);
944 gppsl_update_selected_list (sx_plugin_page,
false, sx);
946 if (gtk_tree_model_get_iter (model, &iter, path))
950 gtk_tree_model_get (model, &iter, SXLTMA_COL_ENABLED, &toggled, -1);
951 if (enable != toggled)
953 sx_list = g_list_prepend (sx_list, sx);
958 gtk_tree_path_free (path);
960 g_list_free (sel_list);
962 for (GList *node = sx_list; node; node = node->next)
971 else if (!node->next)
976 SchedXaction *sx = GNC_SCHEDXACTION(node->data);
978 xaccSchedXactionSetEnabled (sx, enable);
980 g_list_free (sx_list);
984gppsl_key_press_cb (GtkTreeView *tree_view, GdkEventKey *event, gpointer user_data)
986 if (event->keyval != GDK_KEY_space || !gppsl_is_enable_column_visible (tree_view))
991 g_signal_stop_emission_by_name (G_OBJECT(tree_view),
"key-press-event");
993 gboolean enable = gppsl_set_toggle (tree_view);
995 gppsl_set_list (GNC_PLUGIN_PAGE_SX_LIST(user_data), enable);
1002gppsl_row_activated_cb (GtkTreeView *tree_view,
1004 GtkTreeViewColumn *column,
1011 SchedXaction *sx = gnc_tree_view_sx_list_get_sx_from_path (
1012 GNC_TREE_VIEW_SX_LIST(priv->tree_view), path);
1013 gnc_ui_scheduled_xaction_editor_dialog_create (window, sx,
false);
1014 gppsl_update_selected_list (page,
true, sx);
1019_destroy_sx(gpointer data, gpointer user_data)
1021 SchedXactions *sxes;
1022 auto sx = GNC_SCHEDXACTION(data);
1024 book = gnc_get_current_book ();
1025 sxes = gnc_book_get_schedxactions (book);
1027 DEBUG(
"deleting sx [%s]", xaccSchedXactionGetName (sx));
1029 gnc_sxes_del_sx (sxes, sx);
1030 gnc_sx_begin_edit (sx);
1036_destroy_sx_names (gpointer data, gpointer user_data)
1038 auto sx = GNC_SCHEDXACTION(data);
1039 GList **to_delete_names = (GList**)user_data;
1040 *to_delete_names = g_list_append (*to_delete_names, xaccSchedXactionGetName (sx));
1045gnc_plugin_page_sx_list_cmd_delete (GSimpleAction *simple,
1046 GVariant *parameter,
1049 auto plugin_page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
1051 GtkTreeSelection *selection = gtk_tree_view_get_selection (priv->tree_view);
1052 GList *selected_paths, *to_delete =
nullptr, *to_delete_names =
nullptr;
1053 GtkTreeModel *model;
1055 gchar *message =
nullptr;
1057 gchar *text_list_of_scheduled_transaction_names =
nullptr;
1059 selected_paths = gtk_tree_selection_get_selected_rows (selection, &model);
1062 g_warning (
"no selection for delete.");
1067 (GncGMapFunc)_argument_reorder_fn,
1070 g_list_foreach (to_delete, (GFunc)_destroy_sx_names, &to_delete_names);
1074 length = g_list_length (to_delete);
1079 message = g_strdup_printf (
"%s\n\n%s",
1080 ngettext (
"Do you really want to delete this scheduled transaction?",
1081 "Do you really want to delete these scheduled transactions?",
1083 text_list_of_scheduled_transaction_names);
1085 g_free (text_list_of_scheduled_transaction_names);
1086 g_list_free (to_delete_names);
1088 if (gnc_verify_dialog (window,
false,
"%s", message))
1090 gppsl_update_selected_list (plugin_page,
true,
nullptr);
1092 g_list_foreach (to_delete, (GFunc)_destroy_sx,
nullptr);
1096 g_list_free (to_delete);
1097 g_list_foreach (selected_paths, (GFunc)gtk_tree_path_free,
nullptr);
1098 g_list_free (selected_paths);
1102gnc_plugin_page_sx_list_cmd_run (GSimpleAction *simple,
1103 GVariant *parameter,
1106 auto plugin_page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
1107 auto priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(plugin_page);
1108 auto selection = gtk_tree_view_get_selection (priv->tree_view);
1109 GtkTreeModel *model;
1110 auto selected_paths = gtk_tree_selection_get_selected_rows (selection, &model);
1112 if (!selected_paths)
1114 PWARN (
"no selection for run.");
1118 auto to_run =
gnc_g_list_map (selected_paths, (GncGMapFunc)_argument_reorder_fn, priv->tree_view);
1120 gnc_ui_sx_since_last_run_dialog (gnc_sx_get_select_instances (to_run));
1122 g_list_free (to_run);
1123 g_list_foreach (selected_paths, (GFunc)gtk_tree_path_free,
nullptr);
1124 g_list_free (selected_paths);
Anchor Scheduled Transaction info in a book.
API for Transactions and Splits (journal entries)
API for Transactions and Splits (journal entries)
Commodity handling public routines.
Date and Time handling routines.
All type declarations for the whole Gnucash engine.
Additional event handling code.
Functions for adding content to a window.
Functions for adding plugins to a GnuCash window.
Generic api to store and retrieve preferences.
GncTreeView implementation for Scheduled Transaction List.
utility functions for the GnuCash UI
Functions that are supported by all types of windows.
const gchar * gnc_plugin_page_get_simple_action_group_name(GncPluginPage *page)
Retrieve the simple action group name associated with this plugin page.
GSimpleActionGroup * gnc_plugin_page_create_action_group(GncPluginPage *page, const gchar *group_name)
Create the GSimpleActionGroup object associated with this page.
GtkWidget * gnc_plugin_page_get_window(GncPluginPage *page)
Retrieve a pointer to the GncMainWindow (GtkWindow) containing this page.
void gnc_plugin_page_disconnect_page_changed(GncPluginPage *page)
Disconnect the page_changed_id signal callback.
GAction * gnc_plugin_page_get_action(GncPluginPage *page, const gchar *name)
Retrieve a GAction object associated with this page.
void gnc_plugin_page_add_book(GncPluginPage *page, QofBook *book)
Add a book reference to the specified page.
void gnc_plugin_page_inserted_cb(GncPluginPage *page, gpointer user_data)
Set up the page_changed callback for when the current page is changed.
void gnc_gdate_set_today(GDate *gd)
Set a GDate to the current day.
void qof_event_resume(void)
Resume engine event generation.
void qof_event_suspend(void)
Suspend all engine events.
GAction * gnc_main_window_find_action(GncMainWindow *window, const gchar *action_name)
Find the GAction in the main window.
void gnc_main_window_open_page(GncMainWindow *window, GncPluginPage *page)
Display a data plugin page in a window.
void gnc_main_window_update_menu_and_toolbar(GncMainWindow *window, GncPluginPage *page, const gchar **ui_updates)
Update the main window menu with the placeholders listed in ui_updates and load the page specific too...
void gnc_main_window_close_page(GncPluginPage *page)
Remove a data plugin page from a window and display the previous page.
#define GNC_TYPE_PLUGIN_PAGE_SX_LIST
Functions providing a list of scheduled transactions as a plugin page.
GncPluginPage * gnc_plugin_page_sx_list_new(void)
const GList * gnc_gobject_tracking_get_list(const gchar *name)
Get a list of all known objects of a specified type.
gchar * gnc_g_list_stringjoin(GList *list_of_strings, const gchar *sep)
Return a string joining a GList whose elements are gchar* strings.
GList * gnc_g_list_map(GList *list, GncGMapFunc fn, gpointer user_data)
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...
#define DEBUG(format, args...)
Print a debugging message.
#define LEAVE(format, args...)
Print a function exit debugging message.
#define PWARN(format, args...)
Log a warning.
#define ENTER(format, args...)
Print a function entry debugging message.
gint gnc_prefs_get_int(const gchar *group, const gchar *pref_name)
Get an integer value from the preferences backend.
gboolean gnc_prefs_set_int(const gchar *group, const gchar *pref_name, gint value)
Store an integer value into the preferences backend.
void gnc_sx_set_schedule(SchedXaction *sx, GList *schedule)
SchedXaction * xaccSchedXactionMalloc(QofBook *book)
Creates and initializes a scheduled transaction.
GList * gnc_sx_get_schedule(const SchedXaction *sx)
void xaccSchedXactionDestroy(SchedXaction *sx)
Cleans up and frees a SchedXaction and its associated data.
The class data structure for a content plugin.
void(* save_page)(GncPluginPage *page, GKeyFile *file, const gchar *group)
Save enough information about this page so that it can be recreated next time the user starts gnucash...
const gchar * tab_icon
The relative name of the icon that should be shown on the tab for this page.
const gchar * plugin_name
The textual name of this plugin.
void(* destroy_widget)(GncPluginPage *plugin_page)
Function called to destroy the display widget for a particular type of plugin.
GncPluginPage *(* recreate_page)(GtkWidget *window, GKeyFile *file, const gchar *group)
Create a new page based on the information saved during a previous instantiation of gnucash.
GtkWidget *(* create_widget)(GncPluginPage *plugin_page)
Function called to create the display widget for a particular type of plugin.
gboolean(* focus_page_function)(GncPluginPage *plugin_page)
This function performs specific actions to set the focus on a specific widget.
The instance data structure for a content plugin.
GtkWidget * window
The window that contains the display widget for this plugin.