GnuCash c935c2f+
Loading...
Searching...
No Matches
gnc-plugin-page-sx-list.cpp
1/********************************************************************\
2 * gnc-plugin-page-sx-list.cpp : scheduled transaction plugin *
3 * *
4 * Copyright (C) 2006 Joshua Sled <jsled@asynchronous.org> *
5 * Copyright (C) 2011 Robert Fewell *
6 * *
7 * This program is free software; you can redistribute it and/or *
8 * modify it under the terms of version 2 and/or version 3 of the *
9 * GNU General Public License as published by the Free Software *
10 * Foundation. *
11 * *
12 * As a special exception, permission is granted to link the binary *
13 * module resultant from this code with the OpenSSL project's *
14 * "OpenSSL" library (or modified versions of it that use the same *
15 * license as the "OpenSSL" library), and distribute the linked *
16 * executable. You must obey the GNU General Public License in all *
17 * respects for all of the code used other than "OpenSSL". If you *
18 * modify this file, you may extend this exception to your version *
19 * of the file, but you are not obligated to do so. If you do not *
20 * wish to do so, delete this exception statement from your version *
21 * of this file. *
22 * *
23 * This program is distributed in the hope that it will be useful, *
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
26 * GNU General Public License for more details. *
27 * *
28 * You should have received a copy of the GNU General Public License*
29 * along with this program; if not, contact: *
30 * *
31 * Free Software Foundation Voice: +1-617-542-5942 *
32 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
33 * Boston, MA 02110-1301, USA gnu@gnu.org *
34\********************************************************************/
35
44#include <config.h>
45
46#include <gtk/gtk.h>
47#include <glib.h>
48#include <glib/gi18n.h>
49
50#include <gnc-gobject-utils.h>
51#include "SX-book.h"
52#include "Split.h"
53#include "Transaction.h"
54#include "dialog-sx-editor.h"
55#include "dialog-utils.h"
56#include "dialog-sx-since-last-run.h"
57#include "gnc-commodity.h"
58#include "gnc-component-manager.h"
59#include "gnc-date.h"
60#include "gnc-dense-cal.h"
61#include "gnc-engine.h"
62#include "gnc-event.h"
63#include "gnc-glib-utils.h"
64#include "gnc-icons.h"
65#include "gnc-main-window.h"
66#include "gnc-plugin.h"
67#include "gnc-plugin-page-sx-list.h"
68#include "gnc-prefs.h"
69#include "gnc-session.h"
70#include "gnc-sx-instance-dense-cal-adapter.h"
72#include "gnc-sx-list-tree-model-adapter.h"
74#include "gnc-ui-util.h"
75#include "gnc-ui.h"
76#include "gnc-window.h"
77
78#undef G_LOG_DOMAIN
79#define G_LOG_DOMAIN "gnc.gui.plugin-page.sx-list"
80
81G_GNUC_UNUSED static QofLogModule log_module = GNC_MOD_GUI_SX;
82
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"
87
89{
90 gboolean disposed;
91
92 GtkWidget* widget;
93 gint gnc_component_id;
94
95 GncSxInstanceDenseCalAdapter *dense_cal_model;
96 GncDenseCal* gdcal;
97
98 GncSxInstanceModel* instances;
99 GtkTreeView* tree_view;
100 GList *selected_list;
101
103
104G_DEFINE_TYPE_WITH_PRIVATE(GncPluginPageSxList, gnc_plugin_page_sx_list, GNC_TYPE_PLUGIN_PAGE)
105
106#define GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(o) \
107 ((GncPluginPageSxListPrivate*)gnc_plugin_page_sx_list_get_instance_private ((GncPluginPageSxList*)o))
108
109/************************************************************
110 * Prototypes *
111 ************************************************************/
112/* Plugin Actions */
113static void gnc_plugin_page_sx_list_dispose (GObject *object);
114static void gnc_plugin_page_sx_list_finalize (GObject *object);
115
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);
120
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);
124
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);
132
133/* Command callbacks */
134static GActionEntry gnc_plugin_page_sx_list_actions [] =
135{
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 },
144};
146static guint gnc_plugin_page_sx_list_n_actions = G_N_ELEMENTS(gnc_plugin_page_sx_list_actions);
147
149static const gchar *gnc_plugin_load_ui_items [] =
150{
151 "FilePlaceholder3",
152 "EditPlaceholder3",
153 "EditPlaceholder5",
154 "ViewPlaceholder4",
155 "SchedulePlaceholder0",
156 nullptr,
157};
158
159
162{
163 GncPluginPageSxList *plugin_page;
164 const GList *object = gnc_gobject_tracking_get_list (GNC_PLUGIN_PAGE_SX_LIST_NAME);
165 if (object && GNC_IS_PLUGIN_PAGE_SX_LIST(object->data))
166 plugin_page = GNC_PLUGIN_PAGE_SX_LIST(object->data);
167 else
168 {
169 plugin_page = GNC_PLUGIN_PAGE_SX_LIST(g_object_new (GNC_TYPE_PLUGIN_PAGE_SX_LIST, nullptr));
170 }
171 return GNC_PLUGIN_PAGE(plugin_page);
172}
173
174
179static gboolean
180gnc_plugin_page_sx_list_focus_widget (GncPluginPage *sx_plugin_page)
181{
182 if (GNC_IS_PLUGIN_PAGE_SX_LIST(sx_plugin_page))
183 {
184 GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(sx_plugin_page);
185 GtkTreeView *tree_view = priv->tree_view;
186
187 /* Disable the Transaction Menu */
188 GAction *action = gnc_main_window_find_action (GNC_MAIN_WINDOW(sx_plugin_page->window), "TransactionAction");
189 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), false);
190 /* Enable the Schedule Menu */
191 action = gnc_main_window_find_action (GNC_MAIN_WINDOW(sx_plugin_page->window), "ScheduledAction");
192 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), true);
193 /* Disable the FilePrintAction */
194 action = gnc_main_window_find_action (GNC_MAIN_WINDOW(sx_plugin_page->window), "FilePrintAction");
195 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), false);
196
197 gnc_main_window_update_menu_and_toolbar (GNC_MAIN_WINDOW(sx_plugin_page->window),
198 sx_plugin_page,
199 gnc_plugin_load_ui_items);
200
201 if (GTK_IS_TREE_VIEW(tree_view))
202 {
203 if (!gtk_widget_is_focus (GTK_WIDGET(tree_view)))
204 gtk_widget_grab_focus (GTK_WIDGET(tree_view));
205 }
206 }
207 return false;
208}
209
210static void
211gnc_plugin_page_sx_list_class_init (GncPluginPageSxListClass *klass)
212{
213 GObjectClass *object_class = G_OBJECT_CLASS(klass);
214 GncPluginPageClass *gnc_plugin_class = GNC_PLUGIN_PAGE_CLASS(klass);
215
216 object_class->dispose = gnc_plugin_page_sx_list_dispose;
217 object_class->finalize = gnc_plugin_page_sx_list_finalize;
218
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;
225 gnc_plugin_class->focus_page_function = gnc_plugin_page_sx_list_focus_widget;
226}
227
228
229static void
230gnc_plugin_page_sx_list_init (GncPluginPageSxList *plugin_page)
231{
232 GSimpleActionGroup *simple_action_group;
233 GncPluginPage *parent;
234
235 /* Init parent declared variables */
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",
240 nullptr);
241
242 gnc_plugin_page_add_book (parent, gnc_get_current_book());
243 simple_action_group = gnc_plugin_page_create_action_group (parent, "GncPluginPageSxListActions");
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,
247 plugin_page);
248}
249
250
251static void
252gnc_plugin_page_sx_list_dispose (GObject *object)
253{
256
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);
261
262 g_return_if_fail (!priv->disposed);
263 priv->disposed = true;
264
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;
271
272 G_OBJECT_CLASS(gnc_plugin_page_sx_list_parent_class)->dispose (object);
273}
274
275
276static void
277gnc_plugin_page_sx_list_finalize (GObject *object)
278{
281
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);
286
287 G_OBJECT_CLASS(gnc_plugin_page_sx_list_parent_class)->finalize (object);
288}
289
290
291/* Virtual Functions */
292static void
293gnc_plugin_page_sx_list_refresh_cb (GHashTable *changes, gpointer user_data)
294{
295 auto page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
297
298 g_return_if_fail (GNC_IS_PLUGIN_PAGE_SX_LIST(page));
299
300 /* We're only looking for forced updates here. */
301 if (changes)
302 return;
303
304 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
305 gtk_widget_queue_draw (priv->widget);
306}
307
308
309static void
310gnc_plugin_page_sx_list_close_cb (gpointer user_data)
311{
312 GncPluginPage *plugin_page = GNC_PLUGIN_PAGE(user_data);
313 gnc_main_window_close_page (plugin_page);
314}
315
316
317static void
318gppsl_selection_changed_cb (GtkTreeSelection *selection, gpointer user_data)
319{
320 GncPluginPage *page;
321 GAction *edit_action, *delete_action, *run_action;
322 gboolean selection_state = true;
323
324 page = GNC_PLUGIN_PAGE(user_data);
325 edit_action = gnc_plugin_page_get_action (page, "SxListEditAction");
326 delete_action = gnc_plugin_page_get_action (page, "SxListDeleteAction");
327 run_action = gnc_plugin_page_get_action (page, "SxListRunAction");
328 selection_state = gtk_tree_selection_count_selected_rows (selection) == 0
329 ? false
330 : true;
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);
334}
335
336
337static void
338gppsl_update_selected_list (GncPluginPageSxList *page, gboolean reset, SchedXaction *sx)
339{
340 GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
341
342 if (reset && priv->selected_list)
343 {
344 g_list_free (priv->selected_list);
345 priv->selected_list = nullptr;
346 }
347 if (sx)
348 priv->selected_list = g_list_prepend (priv->selected_list, sx);
349}
350
351
352static void
353gppsl_model_populated_cb (GtkTreeModel *tree_model, GncPluginPageSxList *page)
354{
355 GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
356 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->tree_view));
357 gboolean found = false;
358
359 if (priv->selected_list)
360 {
361 // walk the list to see if we can reselect the sx
362 for (GList *list = priv->selected_list; list != nullptr; list = list->next)
363 {
364 SchedXaction *sx = GNC_SCHEDXACTION(list->data);
365 GtkTreePath *path = gtk_tree_path_new_first ();
366
367 // loop through the model trying to find selected sx's
368 while (gnc_tree_view_path_is_valid (GNC_TREE_VIEW(priv->tree_view), path))
369 {
370 SchedXaction *sx_tmp = gnc_tree_view_sx_list_get_sx_from_path (
371 GNC_TREE_VIEW_SX_LIST(priv->tree_view), path);
372 if (sx_tmp == sx)
373 {
374 found = true;
375 break;
376 }
377 gtk_tree_path_next (path);
378 }
379 if (found)
380 gtk_tree_selection_select_path (selection, path);
381
382 gtk_tree_path_free (path);
383 }
384 }
385 // this could be on load or if sx is deleted
386 if (!found)
387 {
388 GtkTreePath *path = gtk_tree_path_new_first ();
389 gtk_tree_selection_select_path (selection, path);
390 gtk_tree_path_free (path);
391 }
392}
393
394
395static void
396treeview_popup (GtkTreeView *treeview, GdkEvent *event, GncPluginPageSxList *page)
397{
398 GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
399 GtkWidget *menu, *menuitem;
400 gchar *full_action_name;
401 const gchar *group_name = gnc_plugin_page_get_simple_action_group_name (GNC_PLUGIN_PAGE(page));
402
403 menu = gtk_menu_new();
404
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);
410
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);
416
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);
422
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);
428
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);
432}
433
434static gboolean
435treeview_button_press (GtkTreeView *treeview, GdkEvent *event,
437{
438 GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
439 GtkTreeView *tree_view = GTK_TREE_VIEW(priv->tree_view);
440
441 if (event->type == GDK_BUTTON_PRESS)
442 {
443 GdkEventButton *event_button = (GdkEventButton*)event;
444 if (event_button->button == GDK_BUTTON_SECONDARY)
445 {
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))
449 {
450 GtkTreeSelection *selection = gtk_tree_view_get_selection (priv->tree_view);
451
452 if (!gtk_tree_selection_path_is_selected (selection, path))
453 {
454 gtk_tree_selection_unselect_all (selection);
455 gtk_tree_selection_select_path (selection, path);
456 }
457 }
458 gtk_tree_path_free (path);
459
460 treeview_popup (tree_view, event, page);
461 return true;
462 }
463 }
464 return false;
465}
466
467static gboolean
468treeview_popup_menu (GtkTreeView *treeview, GncPluginPageSxList *page)
469{
470 treeview_popup (treeview, nullptr, page);
471 return true;
472}
473
474static GtkWidget *
475gnc_plugin_page_sx_list_create_widget (GncPluginPage *plugin_page)
476{
479 GtkWidget *widget;
480 GtkWidget *vbox;
481 GtkWidget *label;
482 GtkWidget *swin;
483 GtkWindow *window;
484
485 page = GNC_PLUGIN_PAGE_SX_LIST(plugin_page);
486 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
487 if (priv->widget != nullptr)
488 return priv->widget;
489
490 window = GTK_WINDOW(gnc_plugin_page_get_window (GNC_PLUGIN_PAGE(page)));
491
492 /* Create Vpaned widget for top level */
493 widget = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
494 priv->widget = widget;
495 gtk_widget_show (priv->widget);
496
497 // Set the name for this widget so it can be easily manipulated with css
498 gtk_widget_set_name (GTK_WIDGET(priv->widget), "gnc-id-sx-page");
499
500 /* Add vbox and label */
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);
504
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);
512
513 /* Create scrolled window for top area */
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);
520
521 /* Set the paned position from the preferences, default 160 */
522 gtk_paned_set_position (GTK_PANED(priv->widget),
523 gnc_prefs_get_int (GNC_PREFS_GROUP_SXED,
524 GNC_PREF_DIVIDER_POS));
525
526 {
527 GDate end;
528 g_date_clear (&end, 1);
529 gnc_gdate_set_today (&end);
530 g_date_add_years (&end, 1);
531 priv->instances = GNC_SX_INSTANCE_MODEL(gnc_sx_get_instances (&end, true));
532 }
533
534 {
535 GAction *edit_action, *delete_action, *run_action;
536 edit_action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page), "SxListEditAction");
537 delete_action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page), "SxListDeleteAction");
538 run_action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page), "SxListRunAction");
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);
542 }
543
544 {
545 GtkTreeSelection *selection;
546 GtkTreePath *path = gtk_tree_path_new_first ();
547
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,
552 nullptr);
553 gtk_container_add (GTK_CONTAINER(swin), GTK_WIDGET(priv->tree_view));
554
555 selection = gtk_tree_view_get_selection (priv->tree_view);
556 gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
557
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);
566
567 gtk_tree_selection_select_path (selection, path);
568 gtk_tree_path_free (path);
569 }
570
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);
575
576 /* Add vbox and label */
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);
580
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);
586
587 gtk_box_pack_start (GTK_BOX(vbox), label, false, false, 0);
588 gtk_widget_show (vbox);
589
590 /* Create scrolled window for bottom area */
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);
597
598 {
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);
602
603 /* Set number of months from preference, default 12 */
604 auto num_months = gnc_prefs_get_int (GNC_PREFS_GROUP_SXED, GNC_PREF_NUM_OF_MONTHS);
605 if (num_months == 0)
606 {
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.");
608 num_months = 12;
609 }
610 gnc_dense_cal_set_num_months (priv->gdcal, num_months);
611
612 gtk_container_add (GTK_CONTAINER(swin), GTK_WIDGET(priv->gdcal));
613 }
614
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,
618 page);
619 gnc_gui_component_set_session (priv->gnc_component_id,
620 gnc_get_current_session ());
621
622 g_signal_connect (G_OBJECT(plugin_page), "inserted",
623 G_CALLBACK(gnc_plugin_page_inserted_cb),
624 nullptr);
625
626 return priv->widget;
627}
628
629
630static void
631gnc_plugin_page_sx_list_destroy_widget (GncPluginPage *plugin_page)
632{
635
636 page = GNC_PLUGIN_PAGE_SX_LIST(plugin_page);
637 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
638
639 // Remove the page_changed signal callback
640 gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
641
642 // Remove the page focus idle function if present
643 g_idle_remove_by_data (plugin_page);
644
645 if (priv->widget)
646 {
647 g_object_unref (G_OBJECT(priv->widget));
648 priv->widget = nullptr;
649 }
650
651 if (priv->selected_list)
652 g_list_free (priv->selected_list);
653
654 if (priv->gnc_component_id)
655 {
656 gnc_unregister_gui_component (priv->gnc_component_id);
657 priv->gnc_component_id = 0;
658 }
659}
660
661
669static void
670gnc_plugin_page_sx_list_save_page (GncPluginPage *plugin_page,
671 GKeyFile *key_file,
672 const gchar *group_name)
673{
676
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);
680
681 page = GNC_PLUGIN_PAGE_SX_LIST(plugin_page);
682 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
683
684 g_key_file_set_integer (key_file, group_name, "dense_cal_num_months",
685 gnc_dense_cal_get_num_months (priv->gdcal));
686
687 g_key_file_set_integer (key_file, group_name, "paned_position",
688 gtk_paned_get_position (GTK_PANED(priv->widget)));
689}
690
691
700static GncPluginPage *
701gnc_plugin_page_sx_list_recreate_page (GtkWidget *window,
702 GKeyFile *key_file,
703 const gchar *group_name)
704{
707
708 g_return_val_if_fail (key_file, nullptr);
709 g_return_val_if_fail (group_name, nullptr);
710
711 /* Create the new page. */
712 page = GNC_PLUGIN_PAGE_SX_LIST(gnc_plugin_page_sx_list_new ());
713 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
714
715 /* Install it now so we can them manipulate the created widget */
716 gnc_main_window_open_page (GNC_MAIN_WINDOW(window), GNC_PLUGIN_PAGE(page));
717
718 {
719 GError *err = nullptr;
720 gint num_months = g_key_file_get_integer (key_file, group_name, "dense_cal_num_months", &err);
721 if (err == nullptr)
722 gnc_dense_cal_set_num_months (priv->gdcal, num_months);
723 else
724 g_error_free (err);
725 }
726
727 {
728 GError *err = nullptr;
729 gint paned_position = g_key_file_get_integer (key_file, group_name,
730 "paned_position", &err);
731 if (err == nullptr)
732 gtk_paned_set_position (GTK_PANED(priv->widget), paned_position);
733 else
734 g_error_free (err);
735 }
736
737 return GNC_PLUGIN_PAGE(page);
738}
739
740
741static void
742gnc_plugin_page_sx_list_cmd_new (GSimpleAction *simple,
743 GVariant *parameter,
744 gpointer user_data)
745{
746 auto plugin_page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
747 GtkWindow *window = GTK_WINDOW(gnc_plugin_page_get_window (GNC_PLUGIN_PAGE(plugin_page)));
748 SchedXaction *new_sx;
749 gboolean new_sx_flag = true;
750
751 new_sx = xaccSchedXactionMalloc (gnc_get_current_book());
752 {
753 GDate now;
754 Recurrence *r = g_new0 (Recurrence, 1);
755 GList *schedule;
756
757 g_date_clear (&now, 1);
758 gnc_gdate_set_today (&now);
759 recurrenceSet (r, 1, PERIOD_MONTH, &now, WEEKEND_ADJ_NONE);
760 schedule = gnc_sx_get_schedule (new_sx);
761 schedule = g_list_append (schedule, r);
762 gnc_sx_set_schedule (new_sx, schedule);
763 }
764 gnc_ui_scheduled_xaction_editor_dialog_create (window, new_sx, new_sx_flag);
765 gppsl_update_selected_list (plugin_page, true, new_sx);
766}
767
768static void
769gnc_plugin_page_sx_list_cmd_refresh (GSimpleAction *simple,
770 GVariant *parameter,
771 gpointer user_data)
772{
773 auto plugin_page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
775
776 g_return_if_fail (GNC_IS_PLUGIN_PAGE_SX_LIST(plugin_page));
777
778 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(plugin_page);
779 gtk_widget_queue_draw (priv->widget);
780}
781
782static void
783gnc_plugin_page_sx_list_cmd_save_layout (GSimpleAction *simple,
784 GVariant *parameter,
785 gpointer user_data)
786{
787 auto plugin_page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
789 gint paned_position;
790
791 g_return_if_fail (GNC_IS_PLUGIN_PAGE_SX_LIST(plugin_page));
792
793 priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(plugin_page);
794
795 paned_position = gtk_paned_get_position (GTK_PANED(priv->widget));
796
797 gnc_prefs_set_int (GNC_PREFS_GROUP_SXED, GNC_PREF_DIVIDER_POS,
798 paned_position);
799
800 gnc_prefs_set_int (GNC_PREFS_GROUP_SXED, GNC_PREF_NUM_OF_MONTHS,
801 gnc_dense_cal_get_num_months (priv->gdcal));
802}
803
804static void
805_edit_sx(gpointer data, gpointer user_data)
806{
807 gnc_ui_scheduled_xaction_editor_dialog_create (GTK_WINDOW(user_data),
808 GNC_SCHEDXACTION(data), false);
809}
810
811static SchedXaction*
812_argument_reorder_fn (GtkTreePath* list_path_data, GncTreeViewSxList* user_tree_view)
813{
814 return gnc_tree_view_sx_list_get_sx_from_path (user_tree_view, list_path_data);
815}
816
817
818static void
819gnc_plugin_page_sx_list_cmd_edit (GSimpleAction *simple,
820 GVariant *parameter,
821 gpointer user_data)
822{
823 auto plugin_page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
824 GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(plugin_page);
825 GtkWindow *window = GTK_WINDOW(gnc_plugin_page_get_window (GNC_PLUGIN_PAGE(plugin_page)));
826 GtkTreeSelection *selection;
827 GList *selected_paths, *to_edit;
828 GtkTreeModel *model;
829
830 selection = gtk_tree_view_get_selection (priv->tree_view);
831 selected_paths = gtk_tree_selection_get_selected_rows (selection, &model);
832 if (!gnc_list_length_cmp (selected_paths, 0))
833 {
834 g_warning ("no selection edit.");
835 return;
836 }
837
838 to_edit = gnc_g_list_map (selected_paths,
839 (GncGMapFunc)_argument_reorder_fn,
840 priv->tree_view);
841
842 gppsl_update_selected_list (plugin_page, true, nullptr);
843 for (GList *list = to_edit; list != nullptr; list = list->next)
844 {
845 DEBUG ("to-edit [%s]\n", xaccSchedXactionGetName (GNC_SCHEDXACTION(list->data)));
846 gppsl_update_selected_list (plugin_page, false, GNC_SCHEDXACTION(list->data));
847 }
848
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);
853}
854
855
856static void
857gnc_plugin_page_sx_list_cmd_edit_tax_options (GSimpleAction *simple,
858 GVariant *parameter,
859 gpointer user_data)
860{
861 auto plugin_page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
862 GtkWidget *window = GTK_WIDGET(gnc_plugin_page_get_window (GNC_PLUGIN_PAGE(plugin_page)));
863
864 ENTER ("(action %p, page %p)", simple, plugin_page);
865 gnc_tax_info_dialog (window, nullptr);
866 LEAVE (" ");
867}
868
869static gboolean
870gppsl_is_enable_column_visible (GtkTreeView *tree_view)
871{
872 gboolean retval = FALSE;
873 GList *columns = gtk_tree_view_get_columns (tree_view);
874
875 for (GList *node = columns; node; node = node->next)
876 {
877 GtkTreeViewColumn *col = GTK_TREE_VIEW_COLUMN(node->data);
878 gint id = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(col), MODEL_COLUMN));
879
880 if (id == SXLTMA_COL_ENABLED)
881 {
882 retval = gtk_tree_view_column_get_visible(col);
883 break;
884 }
885 }
886 g_list_free (columns);
887 return retval;
888}
889
890static gboolean
891gppsl_set_toggle (GtkTreeView *tree_view)
892{
893 GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
894 GtkTreeModel *model;
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;
898
899 for (GList *node = sel_list; node; node = node->next)
900 {
901 GtkTreePath *path = (GtkTreePath *)node->data;
902 GtkTreeIter iter;
903
904 if (gtk_tree_model_get_iter (model, &iter, path))
905 {
906 gboolean toggled;
907
908 gtk_tree_model_get (model, &iter, SXLTMA_COL_ENABLED, &toggled, -1);
909
910 if (toggled)
911 {
912 num_toggled++;
913 }
914 }
915 gtk_tree_path_free (path);
916 }
917 g_list_free (sel_list);
918
919 return num_toggled != num_selected;
920}
921
922static void
923gppsl_set_list (GncPluginPageSxList *sx_plugin_page, gboolean enable)
924{
925 GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(sx_plugin_page);
926 GtkTreeView *tree_view = priv->tree_view;
927 GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
928 GtkTreeModel *model;
929 GList *sel_list = gtk_tree_selection_get_selected_rows (selection, &model);
930 GList *sx_list = nullptr;
931
932 gppsl_update_selected_list (sx_plugin_page, true, nullptr);
933
934 for (GList *node = sel_list; node; node = node->next)
935 {
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);
939
940 if (sx)
941 {
942 GtkTreeIter iter;
943
944 gppsl_update_selected_list (sx_plugin_page, false, sx);
945
946 if (gtk_tree_model_get_iter (model, &iter, path))
947 {
948 gboolean toggled;
949
950 gtk_tree_model_get (model, &iter, SXLTMA_COL_ENABLED, &toggled, -1);
951 if (enable != toggled)
952 {
953 sx_list = g_list_prepend (sx_list, sx);
954 }
955 }
956 }
957
958 gtk_tree_path_free (path);
959 }
960 g_list_free (sel_list);
961
962 for (GList *node = sx_list; node; node = node->next)
963 {
964 if (node == sx_list)
965 {
966 if (node->next)
967 {
969 }
970 }
971 else if (!node->next)
972 {
974 }
975
976 SchedXaction *sx = GNC_SCHEDXACTION(node->data);
977
978 xaccSchedXactionSetEnabled (sx, enable);
979 }
980 g_list_free (sx_list);
981}
982
983static gboolean
984gppsl_key_press_cb (GtkTreeView *tree_view, GdkEventKey *event, gpointer user_data)
985{
986 if (event->keyval != GDK_KEY_space || !gppsl_is_enable_column_visible (tree_view))
987 {
988 return FALSE;
989 }
990
991 g_signal_stop_emission_by_name (G_OBJECT(tree_view), "key-press-event");
992
993 gboolean enable = gppsl_set_toggle (tree_view);
994
995 gppsl_set_list (GNC_PLUGIN_PAGE_SX_LIST(user_data), enable);
996
997 return TRUE;
998}
999
1000
1001static void
1002gppsl_row_activated_cb (GtkTreeView *tree_view,
1003 GtkTreePath *path,
1004 GtkTreeViewColumn *column,
1005 gpointer user_data)
1006{
1007 GncPluginPageSxList *page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
1008 GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
1009 GtkWindow *window = GTK_WINDOW(gnc_plugin_page_get_window (GNC_PLUGIN_PAGE(page)));
1010
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);
1015}
1016
1017
1018static void
1019_destroy_sx(gpointer data, gpointer user_data)
1020{
1021 SchedXactions *sxes;
1022 auto sx = GNC_SCHEDXACTION(data);
1023 QofBook *book;
1024 book = gnc_get_current_book ();
1025 sxes = gnc_book_get_schedxactions (book);
1026
1027 DEBUG("deleting sx [%s]", xaccSchedXactionGetName (sx));
1028
1029 gnc_sxes_del_sx (sxes, sx);
1030 gnc_sx_begin_edit (sx);
1032}
1033
1034
1035static void
1036_destroy_sx_names (gpointer data, gpointer user_data)
1037{
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));
1041}
1042
1043
1044static void
1045gnc_plugin_page_sx_list_cmd_delete (GSimpleAction *simple,
1046 GVariant *parameter,
1047 gpointer user_data)
1048{
1049 auto plugin_page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
1050 GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(plugin_page);
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;
1054 GtkWindow *window;
1055 gchar *message = nullptr;
1056 gint length;
1057 gchar *text_list_of_scheduled_transaction_names = nullptr;
1058
1059 selected_paths = gtk_tree_selection_get_selected_rows (selection, &model);
1060 if (!gnc_list_length_cmp (selected_paths, 0))
1061 {
1062 g_warning ("no selection for delete.");
1063 return;
1064 }
1065
1066 to_delete = gnc_g_list_map (selected_paths,
1067 (GncGMapFunc)_argument_reorder_fn,
1068 priv->tree_view);
1069
1070 g_list_foreach (to_delete, (GFunc)_destroy_sx_names, &to_delete_names);
1071
1072 window = GTK_WINDOW(gnc_plugin_page_get_window (GNC_PLUGIN_PAGE(plugin_page)));
1073
1074 length = g_list_length (to_delete);
1075
1076 text_list_of_scheduled_transaction_names = gnc_g_list_stringjoin (to_delete_names, "\n");
1077
1078 /* Translators: This is a ngettext(3) message, question followed by list of scheduled transactions to be deleted */
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?",
1082 length),
1083 text_list_of_scheduled_transaction_names);
1084
1085 g_free (text_list_of_scheduled_transaction_names);
1086 g_list_free (to_delete_names);
1087
1088 if (gnc_verify_dialog (window, false, "%s", message))
1089 {
1090 gppsl_update_selected_list (plugin_page, true, nullptr);
1091
1092 g_list_foreach (to_delete, (GFunc)_destroy_sx, nullptr);
1093 }
1094
1095 g_free (message);
1096 g_list_free (to_delete);
1097 g_list_foreach (selected_paths, (GFunc)gtk_tree_path_free, nullptr);
1098 g_list_free (selected_paths);
1099}
1100
1101static void
1102gnc_plugin_page_sx_list_cmd_run (GSimpleAction *simple,
1103 GVariant *parameter,
1104 gpointer user_data)
1105{
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);
1111
1112 if (!selected_paths)
1113 {
1114 PWARN ("no selection for run.");
1115 return;
1116 }
1117
1118 auto to_run = gnc_g_list_map (selected_paths, (GncGMapFunc)_argument_reorder_fn, priv->tree_view);
1119
1120 gnc_ui_sx_since_last_run_dialog (gnc_sx_get_select_instances (to_run));
1121
1122 g_list_free (to_run);
1123 g_list_foreach (selected_paths, (GFunc)gtk_tree_path_free, nullptr);
1124 g_list_free (selected_paths);
1125}
1126
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.
GLib helper routines.
Gobject helper routines.
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.
Definition qofevent.cpp:156
void qof_event_suspend(void)
Suspend all engine events.
Definition qofevent.cpp:145
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.
Definition qoflog.h:264
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition qoflog.h:282
#define PWARN(format, args...)
Log a warning.
Definition qoflog.h:250
#define ENTER(format, args...)
Print a function entry debugging message.
Definition qoflog.h:272
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.
QofBook reference.
Definition qofbook-p.hpp:47