GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-dense-cal-store.c
1 /*
2  * gnc-dense-cal-store.h
3  *
4  * Copyright (C) 2006 Joshua Sled <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of version 2 and/or version 3 of the GNU General Public License as
8  * 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 [email protected]
31  */
32 
33 #include "config.h"
34 #include <glib.h>
35 #include <glib-object.h>
36 #include "gnc-dense-cal.h"
37 #include "gnc-dense-cal-model.h"
38 #include "gnc-dense-cal-store.h"
39 #include "Recurrence.h"
40 #include <gnc-gdate-utils.h>
41 
43 {
44  GObject parent;
45 
46  GDate start_date;
47  gdcs_end_type end_type;
48  GDate end_date;
49  gint n_occurrences;
50  gchar *name;
51  gchar *info;
52  int num_marks;
53  int num_real_marks;
54  GDate **cal_marks;
55 };
56 
58 {
59  GObjectClass parent_class;
60 };
61 
62 static GObjectClass *parent_class = NULL;
63 
64 static void gnc_dense_cal_store_class_init(GncDenseCalStoreClass *klass);
65 
66 static void gnc_dense_cal_store_finalize(GObject *obj);
67 
68 static GList* gdcs_get_contained(GncDenseCalModel *model);
69 static gchar* gdcs_get_name(GncDenseCalModel *model, guint tag);
70 static gchar* gdcs_get_info(GncDenseCalModel *model, guint tag);
71 static gint gdcs_get_instance_count(GncDenseCalModel *model, guint tag);
72 static void gdcs_get_instance(GncDenseCalModel *model, guint tag, gint instance_index, GDate *date);
73 
74 static void
75 gnc_dense_cal_store_class_init(GncDenseCalStoreClass *klass)
76 {
77  GObjectClass *object_class = G_OBJECT_CLASS(klass);
78  parent_class = g_type_class_peek_parent(klass);
79 
80  object_class->finalize = gnc_dense_cal_store_finalize;
81 }
82 
83 static void
84 gnc_dense_cal_store_iface_init(gpointer g_iface, gpointer iface_data)
85 {
87  iface->get_contained = gdcs_get_contained;
88  iface->get_name = gdcs_get_name;
89  iface->get_info = gdcs_get_info;
90  iface->get_instance_count = gdcs_get_instance_count;
91  iface->get_instance = gdcs_get_instance;
92 }
93 
94 GType
95 gnc_dense_cal_store_get_type(void)
96 {
97  static GType type = 0;
98  if (type == 0)
99  {
100  static const GTypeInfo info =
101  {
102  sizeof (GncDenseCalStoreClass),
103  NULL, /* base_init */
104  NULL, /* base_finalize */
105  (GClassInitFunc)gnc_dense_cal_store_class_init, /* class_init */
106  NULL, /* class_finalize */
107  NULL, /* class_data */
108  sizeof(GncDenseCalStore),
109  0, /* n_preallocs */
110  NULL /* instance_init */
111  };
112  static const GInterfaceInfo iDenseCalModelInfo =
113  {
114  (GInterfaceInitFunc)gnc_dense_cal_store_iface_init,
115  NULL, /* interface finalize */
116  NULL, /* interface data */
117  };
118  type = g_type_register_static(G_TYPE_OBJECT, "GncDenseCalStore", &info, 0);
119  g_type_add_interface_static(type,
120  GNC_TYPE_DENSE_CAL_MODEL,
121  &iDenseCalModelInfo);
122  }
123  return type;
124 }
125 
127 gnc_dense_cal_store_new(int num_marks)
128 {
129  GncDenseCalStore *model = g_object_new(GNC_TYPE_DENSE_CAL_STORE, NULL);
130  model->num_marks = num_marks;
131  model->cal_marks = g_new0(GDate*, num_marks);
132  {
133  int i = 0;
134  for (i = 0; i < model->num_marks; i++)
135  {
136  model->cal_marks[i] = g_date_new();
137  }
138  }
139  model->num_real_marks = 0;
140  g_date_clear(&model->start_date, 1);
141  gnc_gdate_set_today (&model->start_date);
142  model->end_type = NEVER_END;
143  g_date_clear(&model->end_date, 1);
144  gnc_gdate_set_today (&model->end_date);
145  model->n_occurrences = 0;
146  return model;
147 }
148 
149 void
150 gnc_dense_cal_store_clear(GncDenseCalStore *model)
151 {
152  model->num_real_marks = 0;
153  g_signal_emit_by_name(model, "update", GUINT_TO_POINTER(1));
154 }
155 
156 void
157 gnc_dense_cal_store_update_name(GncDenseCalStore *model, gchar *name)
158 {
159  if (model->name != NULL)
160  {
161  g_free(model->name);
162  }
163  model->name = g_strdup(name);
164  //g_signal_emit_by_name(model, "update", GUINT_TO_POINTER(1));
165 }
166 
167 void
168 gnc_dense_cal_store_update_info(GncDenseCalStore *model, gchar *info)
169 {
170  if (model->info != NULL)
171  {
172  g_free(model->info);
173  }
174  model->info = g_strdup(info);
175  //g_signal_emit_by_name(model, "update", GUINT_TO_POINTER(1));
176 }
177 
178 static void
179 gdcs_generic_update_recurrences(GncDenseCalStore *trans, GDate *start, GList *recurrences)
180 {
181  int i;
182  GDate date, next;
183 
184  date = *start;
185  /* go one day before what's in the box so we can get the correct start
186  * date. */
187  g_date_subtract_days(&date, 1);
188  recurrenceListNextInstance(recurrences, &date, &next);
189 
190  i = 0;
191  while ((i < trans->num_marks)
192  && g_date_valid(&next)
193  /* Do checking against end restriction. */
194  && ((trans->end_type == NEVER_END)
195  || (trans->end_type == END_ON_DATE
196  && g_date_compare(&next, &trans->end_date) <= 0)
197  || (trans->end_type == END_AFTER_N_OCCS
198  && i < trans->n_occurrences)))
199  {
200  *trans->cal_marks[i++] = next;
201  date = next;
202  recurrenceListNextInstance(recurrences, &date, &next);
203  }
204  trans->num_real_marks = i;
205  /* cstim: Previously this was i-1 but that's just plain wrong for
206  * occurrences which are coming to an end, because then i contains
207  * the number of (rest) occurrences exactly! Subtracting one means
208  * we will miss the last one. */
209 
210  g_signal_emit_by_name(trans, "update", GUINT_TO_POINTER(1));
211 }
212 
213 void
214 gnc_dense_cal_store_update_recurrences_no_end(GncDenseCalStore *model, GDate *start, GList *recurrences)
215 {
216  model->end_type = NEVER_END;
217  gdcs_generic_update_recurrences(model, start, recurrences);
218 }
219 
220 void
221 gnc_dense_cal_store_update_recurrences_count_end(GncDenseCalStore *model, GDate *start, GList *recurrences, int num_occur)
222 {
223  model->end_type = END_AFTER_N_OCCS;
224  model->n_occurrences = num_occur;
225  gdcs_generic_update_recurrences(model, start, recurrences);
226 }
227 
228 void
229 gnc_dense_cal_store_update_recurrences_date_end(GncDenseCalStore *model, GDate *start, GList *recurrences, GDate *end_date)
230 {
231  model->end_type = END_ON_DATE;
232  model->end_date = *end_date;
233  gdcs_generic_update_recurrences(model, start, recurrences);
234 }
235 
236 static GList*
237 gdcs_get_contained(GncDenseCalModel *model)
238 {
239  GList *rtn = NULL;
240  rtn = g_list_append(rtn, GUINT_TO_POINTER(1));
241  return rtn;
242 }
243 
244 static gchar*
245 gdcs_get_name(GncDenseCalModel *model, guint tag)
246 {
247  GncDenseCalStore *mdl = GNC_DENSE_CAL_STORE(model);
248  // assert(tag == 1)
249  return mdl->name;
250 }
251 
252 static gchar*
253 gdcs_get_info(GncDenseCalModel *model, guint tag)
254 {
255  GncDenseCalStore *mdl = GNC_DENSE_CAL_STORE(model);
256  // assert(tag == 1)
257  return g_strdup(mdl->info);
258 }
259 
260 static gint
261 gdcs_get_instance_count(GncDenseCalModel *model, guint tag)
262 {
263  GncDenseCalStore *mdl = GNC_DENSE_CAL_STORE(model);
264  // assert(tag == 1)
265  return mdl->num_real_marks;
266 }
267 
268 static void
269 gdcs_get_instance(GncDenseCalModel *model, guint tag, gint instance_index, GDate *date)
270 {
271  GncDenseCalStore *mdl = GNC_DENSE_CAL_STORE(model);
272  // assert(tag == 1)
273  // assert 0 < instance_index < model->num_marks;
274  *date = *mdl->cal_marks[instance_index];
275 }
276 
277 static void
278 gnc_dense_cal_store_finalize(GObject *obj)
279 {
280  int i;
281  GncDenseCalStore *store;
282  g_return_if_fail(obj != NULL);
283 
284  store = GNC_DENSE_CAL_STORE(obj);
285 
286  if (store->name != NULL)
287  {
288  g_free(store->name);
289  store->name = NULL;
290  }
291 
292  if (store->info != NULL)
293  {
294  g_free(store->info);
295  store->info = NULL;
296  }
297 
298  for (i = 0; i < store->num_marks; i++)
299  {
300  g_free(store->cal_marks[i]);
301  store->cal_marks[i] = NULL;
302  }
303  if (store->cal_marks != NULL)
304  {
305  g_free(store->cal_marks);
306  store->cal_marks = NULL;
307  }
308 
309  G_OBJECT_CLASS(parent_class)->finalize(obj);
310 }
void gnc_gdate_set_today(GDate *gd)
GDate helper routines.