1 /*
2  * gnc-sx-instance-dense-cal-adapter.c
3  *
4  * Copyright (C) 2006 Josh Sled <jsled@asynchronous.org>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of version 2 and/or version 3 of the GNU General Public
8  * License as published by the Free Software Foundation.
9  *
10  * As a special exception, permission is granted to link the binary module
11  * resultant from this code with the OpenSSL project's "OpenSSL" library (or
12  * modified versions of it that use the same license as the "OpenSSL"
13  * library), and distribute the linked executable.  You must obey the GNU
14  * General Public License in all respects for all of the code used other than
15  * "OpenSSL". If you modify this file, you may extend this exception to your
16  * version of the file, but you are not obligated to do so. If you do not
17  * wish to do so, delete this exception statement from your version of this
18  * file.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, contact:
27  *
28  * Free Software Foundation           Voice:  +1-617-542-5942
29  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
30  * Boston, MA  02110-1301,  USA       gnu@gnu.org
31  */
32 
33 #include <config.h>
34 #include <glib.h>
35 #include "gnc-sx-instance-dense-cal-adapter.h"
36 #include "gnc-dense-cal.h"
37 #include <qoflog.h>
38 
39 #undef G_LOG_DOMAIN
40 #define G_LOG_DOMAIN "gnc.gui.sx.adapter.sx-dense-cal"
41 static const QofLogModule log_module = G_LOG_DOMAIN;
42 
43 static void gnc_sx_instance_dense_cal_adapter_dispose(GObject *obj);
44 static void gnc_sx_instance_dense_cal_adapter_finalize(GObject *obj);
45 
46 static GList* gsidca_get_contained(GncDenseCalModel *model);
47 static gchar* gsidca_get_name(GncDenseCalModel *model, guint tag);
48 static gchar* gsidca_get_info(GncDenseCalModel *model, guint tag);
49 static gint gsidca_get_instance_count(GncDenseCalModel *model, guint tag);
50 static void gsidca_get_instance(GncDenseCalModel *model, guint tag, gint instance_index, GDate *date);
51 
52 static GObjectClass *parent_class = NULL;
53 
54 struct _GncSxInstanceDenseCalAdapterClass
55 {
56     GObjectClass parent;
57 };
58 
59 struct _GncSxInstanceDenseCalAdapter
60 {
61     GObject parent;
62     gboolean disposed;
63     GncSxInstanceModel *instances;
64 };
65 
66 static void
gnc_sx_instance_dense_cal_adapter_class_init(GncSxInstanceDenseCalAdapterClass * klass)67 gnc_sx_instance_dense_cal_adapter_class_init(GncSxInstanceDenseCalAdapterClass *klass)
68 {
69     GObjectClass *obj_class = G_OBJECT_CLASS(klass);
70 
71     obj_class->dispose = gnc_sx_instance_dense_cal_adapter_dispose;
72     obj_class->finalize = gnc_sx_instance_dense_cal_adapter_finalize;
73 
74     parent_class = g_type_class_peek_parent(klass);
75 }
76 
77 static void
gnc_sx_instance_dense_cal_adapter_init(GTypeInstance * instance,gpointer klass)78 gnc_sx_instance_dense_cal_adapter_init(GTypeInstance *instance, gpointer klass)
79 {
80     /*GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(instance);*/
81     ; /* nop */
82 }
83 
84 static void
gnc_sx_instance_dense_cal_adapter_interface_init(gpointer g_iface,gpointer iface_data)85 gnc_sx_instance_dense_cal_adapter_interface_init(gpointer g_iface, gpointer iface_data)
86 {
87     GncDenseCalModelIface *iface = (GncDenseCalModelIface*)g_iface;
88     iface->get_contained = gsidca_get_contained;
89     iface->get_name = gsidca_get_name;
90     iface->get_info = gsidca_get_info;
91     iface->get_instance_count = gsidca_get_instance_count;
92     iface->get_instance = gsidca_get_instance;
93 }
94 
95 static void
gsidca_instances_added_cb(GncSxInstanceModel * model,SchedXaction * sx_added,gpointer user_data)96 gsidca_instances_added_cb(GncSxInstanceModel *model, SchedXaction *sx_added, gpointer user_data)
97 {
98     GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(user_data);
99     DEBUG("instance added\n");
100     if (xaccSchedXactionGetEnabled(sx_added))
101     {
102         g_signal_emit_by_name(adapter, "added", GPOINTER_TO_UINT(sx_added));
103     }
104 }
105 
106 static void
gsidca_instances_updated_cb(GncSxInstanceModel * model,SchedXaction * sx_updated,gpointer user_data)107 gsidca_instances_updated_cb(GncSxInstanceModel *model, SchedXaction *sx_updated, gpointer user_data)
108 {
109     GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(user_data);
110     gnc_sx_instance_model_update_sx_instances(model, sx_updated);
111     DEBUG("instances updated\n");
112     if (xaccSchedXactionGetEnabled(sx_updated))
113     {
114         g_signal_emit_by_name(adapter, "update", GPOINTER_TO_UINT((gpointer)sx_updated));
115     }
116     else
117     {
118         g_signal_emit_by_name(adapter, "removing", GPOINTER_TO_UINT((gpointer)sx_updated));
119     }
120 }
121 
122 static void
gsidca_instances_removing_cb(GncSxInstanceModel * model,SchedXaction * sx_to_be_removed,gpointer user_data)123 gsidca_instances_removing_cb(GncSxInstanceModel *model, SchedXaction *sx_to_be_removed, gpointer user_data)
124 {
125     GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(user_data);
126     DEBUG("removing instance...\n");
127     g_signal_emit_by_name(adapter, "removing", GPOINTER_TO_UINT(sx_to_be_removed));
128     gnc_sx_instance_model_remove_sx_instances(model, sx_to_be_removed);
129 }
130 
131 GncSxInstanceDenseCalAdapter*
gnc_sx_instance_dense_cal_adapter_new(GncSxInstanceModel * instances)132 gnc_sx_instance_dense_cal_adapter_new(GncSxInstanceModel *instances)
133 {
134     GncSxInstanceDenseCalAdapter *adapter = g_object_new(GNC_TYPE_SX_INSTANCE_DENSE_CAL_ADAPTER, NULL);
135     adapter->instances = instances;
136     g_object_ref(G_OBJECT(adapter->instances));
137 
138     g_signal_connect(instances, "added", (GCallback)gsidca_instances_added_cb, adapter);
139     g_signal_connect(instances, "updated", (GCallback)gsidca_instances_updated_cb, adapter);
140     g_signal_connect(instances, "removing", (GCallback)gsidca_instances_removing_cb, adapter);
141     return adapter;
142 }
143 
144 GType
gnc_sx_instance_dense_cal_adapter_get_type(void)145 gnc_sx_instance_dense_cal_adapter_get_type(void)
146 {
147     static GType type = 0;
148     if (type == 0)
149     {
150         static const GTypeInfo info =
151         {
152             sizeof (GncSxInstanceDenseCalAdapterClass),
153             NULL, /* base init */
154             NULL, /* base finalize */
155             (GClassInitFunc)gnc_sx_instance_dense_cal_adapter_class_init,
156             NULL, /* class finalize */
157             NULL, /* class data */
158             sizeof(GncSxInstanceDenseCalAdapter),
159             0, /* n_preallocs */
160             (GInstanceInitFunc)gnc_sx_instance_dense_cal_adapter_init
161         };
162         static const GInterfaceInfo iDenseCalModelInfo =
163         {
164             (GInterfaceInitFunc)gnc_sx_instance_dense_cal_adapter_interface_init,
165             NULL, /* interface finalize */
166             NULL, /* interface data */
167         };
168 
169         type = g_type_register_static (G_TYPE_OBJECT,
170                                        "GncSxInstanceDenseCalAdapterType",
171                                        &info, 0);
172         g_type_add_interface_static(type,
173                                     GNC_TYPE_DENSE_CAL_MODEL,
174                                     &iDenseCalModelInfo);
175     }
176     return type;
177 }
178 
179 static gint
gsidca_find_sx_with_tag(gconstpointer list_data,gconstpointer find_data)180 gsidca_find_sx_with_tag(gconstpointer list_data,
181                         gconstpointer find_data)
182 {
183     GncSxInstances *sx_instances = (GncSxInstances*)list_data;
184     return (GUINT_TO_POINTER(GPOINTER_TO_UINT(sx_instances->sx)) == find_data ? 0 : 1);
185 }
186 
187 static GList*
gsidca_get_contained(GncDenseCalModel * model)188 gsidca_get_contained(GncDenseCalModel *model)
189 {
190     GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(model);
191     //"removing return gnc_g_list_map(instances->sxes, sx_to_tag, null);
192     GList *list = NULL, *sxes;
193     for (sxes = adapter->instances->sx_instance_list; sxes != NULL; sxes = sxes->next)
194     {
195         GncSxInstances *sx_instances = (GncSxInstances*)sxes->data;
196         if (xaccSchedXactionGetEnabled(sx_instances->sx))
197             list = g_list_prepend (list, GUINT_TO_POINTER
198                                    (GPOINTER_TO_UINT (sx_instances->sx)));
199     }
200     return g_list_reverse (list);
201 }
202 
203 static gchar*
gsidca_get_name(GncDenseCalModel * model,guint tag)204 gsidca_get_name(GncDenseCalModel *model, guint tag)
205 {
206     GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(model);
207     GncSxInstances *insts
208     = (GncSxInstances*)g_list_find_custom(adapter->instances->sx_instance_list, GUINT_TO_POINTER(tag), gsidca_find_sx_with_tag)->data;
209     if (insts == NULL)
210         return NULL;
211     return xaccSchedXactionGetName(insts->sx);
212 }
213 
214 static gchar*
gsidca_get_info(GncDenseCalModel * model,guint tag)215 gsidca_get_info(GncDenseCalModel *model, guint tag)
216 {
217     GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(model);
218     // g_list_find(instances->sxes, {sx_to_tag, tag}).get_freq_spec().get_freq_str();
219     GList *schedule;
220     gchar *schedule_str;
221     GncSxInstances *insts
222     = (GncSxInstances*)g_list_find_custom(adapter->instances->sx_instance_list, GUINT_TO_POINTER(tag), gsidca_find_sx_with_tag)->data;
223     if (insts == NULL)
224         return NULL;
225     schedule = gnc_sx_get_schedule(insts->sx);
226     schedule_str = recurrenceListToCompactString(schedule);
227     return schedule_str;
228 }
229 
230 static gint
gsidca_get_instance_count(GncDenseCalModel * model,guint tag)231 gsidca_get_instance_count(GncDenseCalModel *model, guint tag)
232 {
233     GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(model);
234     // g_list_find(instances->sxes, {sx_to_tag, tag}).length();
235     GncSxInstances *insts
236     = (GncSxInstances*)g_list_find_custom(adapter->instances->sx_instance_list, GUINT_TO_POINTER(tag), gsidca_find_sx_with_tag)->data;
237     if (insts == NULL)
238         return 0;
239     return g_list_length(insts->instance_list);
240 }
241 
242 static void
gsidca_get_instance(GncDenseCalModel * model,guint tag,gint instance_index,GDate * date)243 gsidca_get_instance(GncDenseCalModel *model, guint tag, gint instance_index, GDate *date)
244 {
245     GncSxInstanceDenseCalAdapter *adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(model);
246     GncSxInstance *inst;
247     GncSxInstances *insts
248     = (GncSxInstances*)g_list_find_custom(adapter->instances->sx_instance_list, GUINT_TO_POINTER(tag), gsidca_find_sx_with_tag)->data;
249     if (insts == NULL)
250         return;
251     inst = (GncSxInstance*)g_list_nth_data(insts->instance_list, instance_index);
252     g_date_valid(&inst->date);
253     *date = inst->date;
254     g_date_valid(date);
255 }
256 
257 static void
gnc_sx_instance_dense_cal_adapter_dispose(GObject * obj)258 gnc_sx_instance_dense_cal_adapter_dispose(GObject *obj)
259 {
260     GncSxInstanceDenseCalAdapter *adapter;
261     g_return_if_fail(obj != NULL);
262     adapter = GNC_SX_INSTANCE_DENSE_CAL_ADAPTER(obj);
263     // g_return_if_fail(!adapter->disposed);
264     if (adapter->disposed) return;
265     adapter->disposed = TRUE;
266 
267     g_object_unref(G_OBJECT(adapter->instances));
268     adapter->instances = NULL;
269 
270     G_OBJECT_CLASS(parent_class)->dispose(obj);
271 }
272 
gnc_sx_instance_dense_cal_adapter_finalize(GObject * obj)273 static void gnc_sx_instance_dense_cal_adapter_finalize(GObject *obj)
274 {
275     g_return_if_fail(obj != NULL);
276     // nop
277     G_OBJECT_CLASS(parent_class)->finalize(obj);
278 }
279