GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-plugin-page-sx-list.c
1 /********************************************************************\
2  * gnc-plugin-page-sx-list.c : scheduled transaction plugin *
3  * *
4  * Copyright (C) 2006 Joshua Sled <[email protected]> *
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 [email protected] *
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-gdate-utils.h>
51 #include <gnc-gobject-utils.h>
52 #include "SX-book.h"
53 #include "Split.h"
54 #include "Transaction.h"
55 #include "dialog-sx-editor.h"
56 /*################## Added for Reg2 #################*/
57 #include "dialog-sx-editor2.h"
58 /*################## Added for Reg2 #################*/
59 #include "dialog-utils.h"
60 #include "gnc-commodity.h"
61 #include "gnc-component-manager.h"
62 #include "gnc-dense-cal.h"
63 #include "gnc-engine.h"
64 #include "gnc-event.h"
65 #include "gnc-glib-utils.h"
66 #include "gnc-icons.h"
67 #include "gnc-main-window.h"
68 #include "gnc-plugin-page-sx-list.h"
69 #include "gnc-session.h"
70 #include "gnc-sx-instance-dense-cal-adapter.h"
71 #include "gnc-sx-instance-model.h"
72 #include "gnc-sx-list-tree-model-adapter.h"
73 #include "gnc-tree-view-sx-list.h"
74 #include "gnc-ui-util.h"
75 #include "gnc-ui.h"
76 
77 #undef G_LOG_DOMAIN
78 #define G_LOG_DOMAIN "gnc.gui.plugin-page.sx-list"
79 
80 G_GNUC_UNUSED static QofLogModule log_module = GNC_MOD_GUI_SX;
81 
82 #define PLUGIN_PAGE_SX_LIST_CM_CLASS "plugin-page-sx-list"
83 #define STATE_SECTION "SX Transaction List"
84 
86 {
87  gboolean disposed;
88 
89  GtkWidget* widget;
90  gint gnc_component_id;
91 
92  GncSxInstanceDenseCalAdapter *dense_cal_model;
93  GncDenseCal* gdcal;
94 
95  GncSxInstanceModel* instances;
96  GtkTreeView* tree_view;
97 
99 
100 #define GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(o) \
101  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_PLUGIN_PAGE_SX_LIST, GncPluginPageSxListPrivate))
102 
103 static GObjectClass *parent_class = NULL;
104 
105 /************************************************************
106  * Prototypes *
107  ************************************************************/
108 /* Plugin Actions */
109 static void gnc_plugin_page_sx_list_class_init (GncPluginPageSxListClass *klass);
110 static void gnc_plugin_page_sx_list_init (GncPluginPageSxList *plugin_page);
111 static void gnc_plugin_page_sx_list_dispose(GObject *object);
112 static void gnc_plugin_page_sx_list_finalize(GObject *object);
113 
114 static GtkWidget *gnc_plugin_page_sx_list_create_widget (GncPluginPage *plugin_page);
115 static void gnc_plugin_page_sx_list_destroy_widget (GncPluginPage *plugin_page);
116 static void gnc_plugin_page_sx_list_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
117 static GncPluginPage *gnc_plugin_page_sx_list_recreate_page (GtkWidget *window, GKeyFile *file, const gchar *group);
118 
119 static void gppsl_row_activated_cb(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data);
120 
121 static void gnc_plugin_page_sx_list_cmd_new(GtkAction *action, GncPluginPageSxList *page);
122 static void gnc_plugin_page_sx_list_cmd_edit(GtkAction *action, GncPluginPageSxList *page);
123 /*################## Added for Reg2 #################*/
124 static void gnc_plugin_page_sx_list_cmd_new2(GtkAction *action, GncPluginPageSxList *page);
125 static void gnc_plugin_page_sx_list_cmd_edit2(GtkAction *action, GncPluginPageSxList *page);
126 /*################## Added for Reg2 #################*/
127 static void gnc_plugin_page_sx_list_cmd_delete(GtkAction *action, GncPluginPageSxList *page);
128 
129 /* Command callbacks */
130 static GtkActionEntry gnc_plugin_page_sx_list_actions [] =
131 {
132  { "SxListAction", NULL, N_("_Scheduled"), NULL, NULL, NULL },
133  {
134  "SxListNewAction", GNC_STOCK_NEW_ACCOUNT, N_("_New"), NULL,
135  N_("Create a new scheduled transaction"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_new)
136  },
137 #ifdef REGISTER2_ENABLED
138 /*################## Added for Reg2 #################*/
139  {
140  "SxListNewAction2", GNC_STOCK_NEW_ACCOUNT, N_("_New 2"), NULL,
141  N_("Create a new scheduled transaction 2"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_new2)
142  },
143 /*################## Added for Reg2 #################*/
144 #endif
145  {
146  "SxListEditAction", GNC_STOCK_EDIT_ACCOUNT, N_("_Edit"), NULL,
147  N_("Edit the selected scheduled transaction"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_edit)
148  },
149 #ifdef REGISTER2_ENABLED
150 /*################## Added for Reg2 #################*/
151  {
152  "SxListEditAction2", GNC_STOCK_EDIT_ACCOUNT, N_("_Edit 2"), NULL,
153  N_("Edit the selected scheduled transaction 2"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_edit2)
154  },
155 /*################## Added for Reg2 #################*/
156 #endif
157  {
158  "SxListDeleteAction", GNC_STOCK_DELETE_ACCOUNT, N_("_Delete"), NULL,
159  N_("Delete the selected scheduled transaction"), G_CALLBACK(gnc_plugin_page_sx_list_cmd_delete)
160  },
161 };
163 static guint gnc_plugin_page_sx_list_n_actions = G_N_ELEMENTS (gnc_plugin_page_sx_list_actions);
164 
165 
166 GType
168 {
169  static GType gnc_plugin_page_sx_list_type = 0;
170 
171  if (gnc_plugin_page_sx_list_type == 0)
172  {
173  static const GTypeInfo our_info =
174  {
175  sizeof (GncPluginPageSxListClass),
176  NULL,
177  NULL,
178  (GClassInitFunc) gnc_plugin_page_sx_list_class_init,
179  NULL,
180  NULL,
181  sizeof (GncPluginPageSxList),
182  0,
183  (GInstanceInitFunc) gnc_plugin_page_sx_list_init
184  };
185 
186  gnc_plugin_page_sx_list_type = g_type_register_static (GNC_TYPE_PLUGIN_PAGE,
187  GNC_PLUGIN_PAGE_SX_LIST_NAME,
188  &our_info, 0);
189  }
190 
191  return gnc_plugin_page_sx_list_type;
192 }
193 
194 
197 {
198  GncPluginPageSxList *plugin_page;
199  const GList *object = gnc_gobject_tracking_get_list (GNC_PLUGIN_PAGE_SX_LIST_NAME);
200  if (object && GNC_IS_PLUGIN_PAGE_SX_LIST (object->data))
201  plugin_page = GNC_PLUGIN_PAGE_SX_LIST (object->data);
202  else
203  {
204  plugin_page = g_object_new (GNC_TYPE_PLUGIN_PAGE_SX_LIST, NULL);
205  }
206  return GNC_PLUGIN_PAGE(plugin_page);
207 }
208 
209 
210 static void
211 gnc_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  parent_class = g_type_class_peek_parent(klass);
217 
218  object_class->dispose = gnc_plugin_page_sx_list_dispose;
219  object_class->finalize = gnc_plugin_page_sx_list_finalize;
220 
221  gnc_plugin_class->tab_icon = GNC_STOCK_ACCOUNT;
222  gnc_plugin_class->plugin_name = GNC_PLUGIN_PAGE_SX_LIST_NAME;
223  gnc_plugin_class->create_widget = gnc_plugin_page_sx_list_create_widget;
224  gnc_plugin_class->destroy_widget = gnc_plugin_page_sx_list_destroy_widget;
225  gnc_plugin_class->save_page = gnc_plugin_page_sx_list_save_page;
226  gnc_plugin_class->recreate_page = gnc_plugin_page_sx_list_recreate_page;
227 
228  g_type_class_add_private(klass, sizeof(GncPluginPageSxListPrivate));
229 }
230 
231 
232 static void
233 gnc_plugin_page_sx_list_init (GncPluginPageSxList *plugin_page)
234 {
235  GtkActionGroup *action_group;
236  GncPluginPage *parent;
237  GncPluginPageSxListClass *klass = GNC_PLUGIN_PAGE_SX_LIST_GET_CLASS (plugin_page);
238 
239  /* Init parent declared variables */
240  parent = GNC_PLUGIN_PAGE(plugin_page);
241 #ifdef REGISTER2_ENABLED
242  g_object_set(G_OBJECT(plugin_page),
243  "page-name", _("Scheduled Transactions"),
244  "page-uri", "default:",
245  "ui-description", "gnc-plugin-page-sx-list2-ui.xml",
246  NULL);
247 #else
248  g_object_set(G_OBJECT(plugin_page),
249  "page-name", _("Scheduled Transactions"),
250  "page-uri", "default:",
251  "ui-description", "gnc-plugin-page-sx-list-ui.xml",
252  NULL);
253 #endif
254 
255  gnc_plugin_page_add_book(parent, gnc_get_current_book());
256  action_group =
258  "GncPluginPageSxListActions");
259  gtk_action_group_add_actions(action_group,
260  gnc_plugin_page_sx_list_actions,
261  gnc_plugin_page_sx_list_n_actions,
262  plugin_page);
263  /* gnc_plugin_init_short_names (action_group, toolbar_labels); */
264  gnc_gobject_tracking_remember (G_OBJECT (plugin_page),
265  G_OBJECT_CLASS (klass));
266 }
267 
268 
269 static void
270 gnc_plugin_page_sx_list_dispose(GObject *object)
271 {
272  GncPluginPageSxList *page;
274 
275  page = GNC_PLUGIN_PAGE_SX_LIST (object);
276  g_return_if_fail(GNC_IS_PLUGIN_PAGE_SX_LIST (page));
277  priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
278  g_return_if_fail(priv != NULL);
279 
280  g_return_if_fail(!priv->disposed);
281  priv->disposed = TRUE;
282 
283  g_object_unref(G_OBJECT(priv->dense_cal_model));
284  priv->dense_cal_model = NULL;
285  g_object_unref(GTK_WIDGET(priv->gdcal));
286  priv->gdcal = NULL;
287  g_object_unref(G_OBJECT(priv->instances));
288  priv->instances = NULL;
289 
290  G_OBJECT_CLASS (parent_class)->dispose(object);
291 }
292 
293 
294 static void
295 gnc_plugin_page_sx_list_finalize (GObject *object)
296 {
297  GncPluginPageSxList *page;
299 
300  page = GNC_PLUGIN_PAGE_SX_LIST (object);
301  g_return_if_fail(GNC_IS_PLUGIN_PAGE_SX_LIST (page));
302  priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
303  g_return_if_fail(priv != NULL);
304  gnc_gobject_tracking_forget (G_OBJECT (page));
305 
306  G_OBJECT_CLASS (parent_class)->finalize (object);
307 }
308 
309 
310 /* Virtual Functions */
311 static void
312 gnc_plugin_page_sx_list_refresh_cb (GHashTable *changes, gpointer user_data)
313 {
314  GncPluginPageSxList *page = user_data;
316 
317  g_return_if_fail(GNC_IS_PLUGIN_PAGE_SX_LIST(page));
318 
319  /* We're only looking for forced updates here. */
320  if (changes)
321  return;
322 
323  priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
324  gtk_widget_queue_draw(priv->widget);
325 }
326 
327 
328 static void
329 gnc_plugin_page_sx_list_close_cb (gpointer user_data)
330 {
331  GncPluginPage *plugin_page = GNC_PLUGIN_PAGE(user_data);
332  gnc_main_window_close_page(plugin_page);
333 }
334 
335 
336 static void
337 gppsl_selection_changed_cb(GtkTreeSelection *selection, gpointer user_data)
338 {
339  GncPluginPage *page;
340  GtkAction *edit_action, *delete_action;
341  gboolean selection_state = TRUE;
342 
343  page = GNC_PLUGIN_PAGE(user_data);
344  edit_action = gnc_plugin_page_get_action(page, "SxListEditAction");
345  delete_action = gnc_plugin_page_get_action(page, "SxListDeleteAction");
346  selection_state
347  = gtk_tree_selection_count_selected_rows(selection) == 0
348  ? FALSE
349  : TRUE;
350  gtk_action_set_sensitive(edit_action, selection_state);
351  gtk_action_set_sensitive(delete_action, selection_state);
352 }
353 
354 
355 static GtkWidget *
356 gnc_plugin_page_sx_list_create_widget (GncPluginPage *plugin_page)
357 {
358  GncPluginPageSxList *page;
360  GtkWidget *widget;
361  GtkWidget *vbox;
362  GtkWidget *label;
363  GtkWidget *swin;
364  char *markup;
365  char *text;
366 
367  page = GNC_PLUGIN_PAGE_SX_LIST(plugin_page);
368  priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
369  if (priv->widget != NULL)
370  return priv->widget;
371 
372  /* Create Vpaned widget for top level */
373  widget = gtk_vpaned_new();
374  priv->widget = widget;
375  gtk_widget_show (priv->widget);
376 
377  /* Add vbox and label */
378  vbox = gtk_vbox_new(FALSE, 0);
379  gtk_paned_pack1( GTK_PANED(widget), vbox, TRUE, FALSE);
380 
381  label = gtk_label_new(NULL);
382  text = g_strdup_printf(_("Transactions"));
383  markup = g_markup_printf_escaped ("<b> %s</b>", text);
384  gtk_label_set_markup (GTK_LABEL (label), markup);
385  g_free (markup);
386  g_free (text);
387  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0);
388  gtk_widget_show (label);
389  gtk_box_pack_start ( GTK_BOX(vbox), label, FALSE, FALSE, 0);
390  gtk_widget_show (vbox);
391 
392  /* Create scrolled window for top area */
393  swin = gtk_scrolled_window_new(NULL, NULL);
394  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
395  GTK_POLICY_AUTOMATIC,
396  GTK_POLICY_AUTOMATIC);
397  gtk_box_pack_start ( GTK_BOX(vbox), swin, TRUE, TRUE, 5);
398  gtk_widget_show (swin);
399 
400  {
401  // gint half_way;
402  // half_way = plugin_page->notebook_page->allocation.height * 0.5;
403  // fixme; get a real value:
404  gtk_paned_set_position(GTK_PANED(priv->widget), 160);
405  }
406 
407  {
408  GDate end;
409  g_date_clear(&end, 1);
410  gnc_gdate_set_today (&end);
411  g_date_add_years(&end, 1);
412  priv->instances = GNC_SX_INSTANCE_MODEL(gnc_sx_get_instances(&end, TRUE));
413  }
414 
415  {
416  GtkAction *edit_action, *delete_action;
417  edit_action = gnc_plugin_page_get_action(GNC_PLUGIN_PAGE(page), "SxListEditAction");
418  delete_action = gnc_plugin_page_get_action(GNC_PLUGIN_PAGE(page), "SxListDeleteAction");
419  gtk_action_set_sensitive(edit_action, FALSE);
420  gtk_action_set_sensitive(delete_action, FALSE);
421  }
422 
423  {
424  GtkTreeSelection *selection;
425 
426  priv->tree_view = GTK_TREE_VIEW(gnc_tree_view_sx_list_new(priv->instances));
427  g_object_set(G_OBJECT(priv->tree_view),
428  "state-section", STATE_SECTION,
429  "show-column-menu", TRUE,
430  NULL);
431  gtk_container_add(GTK_CONTAINER( swin ), GTK_WIDGET(priv->tree_view));
432 
433  selection = gtk_tree_view_get_selection(priv->tree_view);
434  gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
435  g_signal_connect(G_OBJECT(selection), "changed", (GCallback)gppsl_selection_changed_cb, (gpointer)page);
436  g_signal_connect(G_OBJECT(priv->tree_view), "row-activated", (GCallback)gppsl_row_activated_cb, (gpointer)page);
437  }
438 
439  /* Add vbox and label */
440  vbox = gtk_vbox_new(FALSE, 0);
441  gtk_paned_pack2( GTK_PANED(widget), vbox, TRUE, FALSE);
442 
443  label = gtk_label_new(NULL);
444  text = g_strdup_printf(_("Upcoming Transactions"));
445  markup = g_markup_printf_escaped ("<b> %s</b>", text);
446  gtk_label_set_markup (GTK_LABEL (label), markup);
447  g_free (markup);
448  g_free (text);
449  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0);
450  gtk_widget_show (label);
451 
452  gtk_box_pack_start ( GTK_BOX(vbox), label, FALSE, FALSE, 0);
453  gtk_widget_show (vbox);
454 
455  /* Create scrolled window for bottom area */
456  swin = gtk_scrolled_window_new(NULL, NULL);
457  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
458  GTK_POLICY_AUTOMATIC,
459  GTK_POLICY_AUTOMATIC);
460  gtk_box_pack_start ( GTK_BOX(vbox), swin, TRUE, TRUE, 5);
461  gtk_widget_show (swin);
462 
463  {
464  priv->dense_cal_model = gnc_sx_instance_dense_cal_adapter_new(GNC_SX_INSTANCE_MODEL(priv->instances));
465  priv->gdcal = GNC_DENSE_CAL(gnc_dense_cal_new_with_model(GNC_DENSE_CAL_MODEL(priv->dense_cal_model)));
466  g_object_ref_sink(priv->gdcal);
467 
468  gnc_dense_cal_set_months_per_col(priv->gdcal, 4);
469  gnc_dense_cal_set_num_months(priv->gdcal, 12);
470 
471  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swin), GTK_WIDGET(priv->gdcal));
472  }
473 
474  priv->gnc_component_id = gnc_register_gui_component("plugin-page-sx-list",
475  gnc_plugin_page_sx_list_refresh_cb,
476  gnc_plugin_page_sx_list_close_cb,
477  page);
478  gnc_gui_component_set_session (priv->gnc_component_id,
479  gnc_get_current_session());
480 
481  return priv->widget;
482 }
483 
484 
485 static void
486 gnc_plugin_page_sx_list_destroy_widget (GncPluginPage *plugin_page)
487 {
488  GncPluginPageSxList *page;
490 
491  page = GNC_PLUGIN_PAGE_SX_LIST (plugin_page);
492  priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
493 
494  if (priv->widget)
495  {
496  g_object_unref(G_OBJECT(priv->widget));
497  priv->widget = NULL;
498  }
499 
500  if (priv->gnc_component_id)
501  {
502  gnc_unregister_gui_component(priv->gnc_component_id);
503  priv->gnc_component_id = 0;
504  }
505 }
506 
507 
515 static void
516 gnc_plugin_page_sx_list_save_page (GncPluginPage *plugin_page,
517  GKeyFile *key_file,
518  const gchar *group_name)
519 {
520  GncPluginPageSxList *page;
522 
523  g_return_if_fail(GNC_IS_PLUGIN_PAGE_SX_LIST(plugin_page));
524  g_return_if_fail(key_file != NULL);
525  g_return_if_fail(group_name != NULL);
526 
527  page = GNC_PLUGIN_PAGE_SX_LIST(plugin_page);
528  priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
529 
530  g_key_file_set_integer(key_file, group_name, "dense_cal_num_months",
531  gnc_dense_cal_get_num_months(priv->gdcal));
532 
533  g_key_file_set_integer(key_file, group_name, "paned_position",
534  gtk_paned_get_position(GTK_PANED(priv->widget)));
535 }
536 
537 
546 static GncPluginPage *
547 gnc_plugin_page_sx_list_recreate_page (GtkWidget *window,
548  GKeyFile *key_file,
549  const gchar *group_name)
550 {
551  GncPluginPageSxList *page;
553 
554  g_return_val_if_fail(key_file, NULL);
555  g_return_val_if_fail(group_name, NULL);
556 
557  /* Create the new page. */
558  page = GNC_PLUGIN_PAGE_SX_LIST(gnc_plugin_page_sx_list_new());
559  priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
560 
561  /* Install it now so we can them manipulate the created widget */
562  gnc_main_window_open_page(GNC_MAIN_WINDOW(window), GNC_PLUGIN_PAGE(page));
563 
564  {
565  GError *err = NULL;
566  gint num_months = g_key_file_get_integer(key_file, group_name, "dense_cal_num_months", &err);
567  if (err == NULL)
568  gnc_dense_cal_set_num_months(priv->gdcal, num_months);
569  else
570  g_error_free(err);
571  }
572 
573  {
574  GError *err = NULL;
575  gint paned_position = g_key_file_get_integer(key_file, group_name,
576  "paned_position", &err);
577  if (err == NULL)
578  gtk_paned_set_position(GTK_PANED(priv->widget), paned_position);
579  else
580  g_error_free(err);
581  }
582 
583  return GNC_PLUGIN_PAGE(page);
584 }
585 
586 
587 static void
588 gnc_plugin_page_sx_list_cmd_new(GtkAction *action, GncPluginPageSxList *page)
589 {
590  SchedXaction *new_sx;
591  gboolean new_sx_flag = TRUE;
592 
593  new_sx = xaccSchedXactionMalloc(gnc_get_current_book());
594  {
595  GDate now;
596  Recurrence *r = g_new0(Recurrence, 1);
597  GList *schedule;
598 
599  g_date_clear(&now, 1);
600  gnc_gdate_set_today (&now);
601  recurrenceSet(r, 1, PERIOD_MONTH, &now, WEEKEND_ADJ_NONE);
602  schedule = gnc_sx_get_schedule(new_sx);
603  schedule = g_list_append(schedule, r);
604  gnc_sx_set_schedule(new_sx, schedule);
605  }
606  gnc_ui_scheduled_xaction_editor_dialog_create(new_sx, new_sx_flag);
607 }
608 
609 /*################## Added for Reg2 #################*/
610 static void
611 gnc_plugin_page_sx_list_cmd_new2 (GtkAction *action, GncPluginPageSxList *page)
612 {
613  SchedXaction *new_sx;
614  gboolean new_sx_flag = TRUE;
615 
616  new_sx = xaccSchedXactionMalloc (gnc_get_current_book());
617  {
618  GDate now;
619  Recurrence *r = g_new0 (Recurrence, 1);
620  GList *schedule;
621 
622  g_date_clear (&now, 1);
623  gnc_gdate_set_today (&now);
624  recurrenceSet(r, 1, PERIOD_MONTH, &now, WEEKEND_ADJ_NONE);
625  schedule = gnc_sx_get_schedule (new_sx);
626  schedule = g_list_append (schedule, r);
627  gnc_sx_set_schedule (new_sx, schedule);
628  }
629  gnc_ui_scheduled_xaction_editor_dialog_create2 (new_sx, new_sx_flag);
630 }
631 /*################## Added for Reg2 #################*/
632 
633 static void
634 _edit_sx(gpointer data, gpointer user_data)
635 {
636  gnc_ui_scheduled_xaction_editor_dialog_create((SchedXaction*)data, FALSE);
637 }
638 
639 /*################## Added for Reg2 #################*/
640 static void
641 _edit_sx2 (gpointer data, gpointer user_data)
642 {
643  gnc_ui_scheduled_xaction_editor_dialog_create2 ((SchedXaction*)data, FALSE);
644 }
645 /*################## Added for Reg2 #################*/
646 
647 static SchedXaction*
648 _argument_reorder_fn(GtkTreePath* list_path_data, GncTreeViewSxList* user_tree_view)
649 {
650  return gnc_tree_view_sx_list_get_sx_from_path(user_tree_view, list_path_data);
651 }
652 
653 
654 static void
655 gnc_plugin_page_sx_list_cmd_edit(GtkAction *action, GncPluginPageSxList *page)
656 {
657  GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
658  GtkTreeSelection *selection;
659  GList *selected_paths, *to_edit;
660  GtkTreeModel *model;
661 
662  selection = gtk_tree_view_get_selection(priv->tree_view);
663  selected_paths = gtk_tree_selection_get_selected_rows(selection, &model);
664  if (g_list_length(selected_paths) == 0)
665  {
666  g_warning("no selection edit.");
667  return;
668  }
669 
670  to_edit = gnc_g_list_map(selected_paths,
671  (GncGMapFunc)_argument_reorder_fn,
672  priv->tree_view);
673  g_list_foreach(to_edit, (GFunc)_edit_sx, NULL);
674  g_list_free(to_edit);
675  g_list_foreach(selected_paths, (GFunc)gtk_tree_path_free, NULL);
676  g_list_free(selected_paths);
677 }
678 
679 /*################## Added for Reg2 #################*/
680 static void
681 gnc_plugin_page_sx_list_cmd_edit2 (GtkAction *action, GncPluginPageSxList *page)
682 {
683  GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE (page);
684  GtkTreeSelection *selection;
685  GList *selected_paths, *to_edit;
686  GtkTreeModel *model;
687 
688  selection = gtk_tree_view_get_selection (priv->tree_view);
689  selected_paths = gtk_tree_selection_get_selected_rows (selection, &model);
690  if (g_list_length (selected_paths) == 0)
691  {
692  g_warning ("no selection edit.");
693  return;
694  }
695 
696  to_edit = gnc_g_list_map (selected_paths,
697  (GncGMapFunc)_argument_reorder_fn,
698  priv->tree_view);
699  g_list_foreach(to_edit, (GFunc)_edit_sx2, NULL);
700  g_list_free (to_edit);
701  g_list_foreach (selected_paths, (GFunc)gtk_tree_path_free, NULL);
702  g_list_free (selected_paths);
703 }
704 /*################## Added for Reg2 #################*/
705 
706 
707 static void
708 gppsl_row_activated_cb(GtkTreeView *tree_view,
709  GtkTreePath *path,
710  GtkTreeViewColumn *column,
711  gpointer user_data)
712 {
713  GncPluginPageSxList *page = GNC_PLUGIN_PAGE_SX_LIST(user_data);
714  GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
715 
716  SchedXaction *sx = gnc_tree_view_sx_list_get_sx_from_path(GNC_TREE_VIEW_SX_LIST(priv->tree_view), path);
717  gnc_ui_scheduled_xaction_editor_dialog_create(sx, FALSE);
718 }
719 
720 
721 static void
722 _destroy_sx(gpointer data, gpointer user_data)
723 {
724  SchedXactions *sxes;
725  SchedXaction *sx = (SchedXaction*)data;
726  QofBook *book;
727  book = gnc_get_current_book();
728  sxes = gnc_book_get_schedxactions(book);
729  gnc_sxes_del_sx(sxes, sx);
730  gnc_sx_begin_edit(sx);
732 }
733 
734 
735 static void
736 gnc_plugin_page_sx_list_cmd_delete(GtkAction *action, GncPluginPageSxList *page)
737 {
738  GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
739  GtkTreeSelection *selection;
740  GList *selected_paths, *to_delete = NULL;
741  GtkTreeModel *model;
742 
743  selection = gtk_tree_view_get_selection(priv->tree_view);
744  selected_paths = gtk_tree_selection_get_selected_rows(selection, &model);
745  if (g_list_length(selected_paths) == 0)
746  {
747  g_warning("no selection for delete.");
748  return;
749  }
750 
751  to_delete = gnc_g_list_map(selected_paths,
752  (GncGMapFunc)_argument_reorder_fn,
753  priv->tree_view);
754  {
755  GList *list;
756  for (list = to_delete; list != NULL; list = list->next)
757  {
758  g_debug("to-delete [%s]\n", xaccSchedXactionGetName((SchedXaction*)list->data));
759  }
760  }
761 
762  /* FIXME: Does this always refer to only one transaction? Or could
763  multiple SXs be deleted as well? Ideally, the number of
764  to-be-deleted SXs should be mentioned here; see
765  dialog-sx-since-last-run.c:807 */
766  if (gnc_verify_dialog(NULL, FALSE, "%s", _("Do you really want to delete this scheduled transaction?")))
767  {
768  g_list_foreach(to_delete, (GFunc)_destroy_sx, NULL);
769  }
770 
771  g_list_free(to_delete);
772  g_list_foreach(selected_paths, (GFunc)gtk_tree_path_free, NULL);
773  g_list_free(selected_paths);
774 }
775 
void gnc_gdate_set_today(GDate *gd)
void gnc_sx_set_schedule(SchedXaction *sx, GList *schedule)
Definition: SchedXaction.c:565
GList * gnc_g_list_map(GList *list, GncGMapFunc fn, gpointer user_data)
const gchar * tab_icon
GList * gnc_sx_get_schedule(const SchedXaction *sx)
Definition: SchedXaction.c:559
const GList * gnc_gobject_tracking_get_list(const gchar *name)
GncPluginPage *(* recreate_page)(GtkWidget *window, GKeyFile *file, const gchar *group)
utility functions for the GnuCash UI
void gnc_gobject_tracking_remember(GObject *object, GObjectClass *klass)
GncTreeView implementation for Scheduled Transaction List.
void gnc_gobject_tracking_forget(GObject *object)
API for Transactions and Splits (journal entries)
void gnc_main_window_open_page(GncMainWindow *window, GncPluginPage *page)
Functions for adding content to a window.
Gobject helper routines.
void(* destroy_widget)(GncPluginPage *plugin_page)
Anchor Scheduled Transaction info in a book. See src/doc/books.txt for design overview.
const gchar * plugin_name
Additional event handling code.
All type declarations for the whole Gnucash engine.
GLib helper routines.
GtkAction * gnc_plugin_page_get_action(GncPluginPage *page, const gchar *name)
GDate helper routines.
GncSxInstanceModel * gnc_sx_get_instances(const GDate *range_end, gboolean include_disabled)
GType gnc_plugin_page_sx_list_get_type(void)
GtkWidget *(* create_widget)(GncPluginPage *plugin_page)
void gnc_main_window_close_page(GncPluginPage *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)
void(* save_page)(GncPluginPage *page, GKeyFile *file, const gchar *group)
void gnc_plugin_page_add_book(GncPluginPage *page, QofBook *book)
SchedXaction * xaccSchedXactionMalloc(QofBook *book)
Definition: SchedXaction.c:404
GtkActionGroup * gnc_plugin_page_create_action_group(GncPluginPage *page, const gchar *group_name)
API for Transactions and Splits (journal entries)
void xaccSchedXactionDestroy(SchedXaction *sx)
Definition: SchedXaction.c:473
Commodity handling public routines.
const gchar * QofLogModule
Definition: qofid.h:89