Branch data Line data Source code
1 : : /*
2 : : * gnc-recurrence-xml-v2.c -- xml routines for Recurrence
3 : : *
4 : : * Copyright (C) 2005 Chris Shoemaker <c.shoemaker@cox.net>
5 : : *
6 : : * This program is free software; you can redistribute it and/or
7 : : * modify it under the terms of the GNU General Public License as
8 : : * published by the Free Software Foundation; either version 2 of
9 : : * the License, or (at your option) any later version.
10 : : *
11 : : * This program is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : : * GNU General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU General Public License
17 : : * along with this program; if not, contact:
18 : : *
19 : : * Free Software Foundation Voice: +1-617-542-5942
20 : : * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
21 : : * Boston, MA 02110-1301, USA gnu@gnu.org
22 : : */
23 : : #include <glib.h>
24 : :
25 : : #include <config.h>
26 : : #include <string.h>
27 : : #include "qof.h"
28 : : #include "Recurrence.h"
29 : :
30 : : #include "gnc-xml.h"
31 : : #include "gnc-xml-helper.h"
32 : :
33 : : #include "sixtp.h"
34 : : #include "sixtp-utils.h"
35 : : #include "sixtp-parsers.h"
36 : : #include "sixtp-utils.h"
37 : : #include "sixtp-dom-parsers.h"
38 : : #include "sixtp-dom-generators.h"
39 : : #include "io-gncxml-v2.h"
40 : :
41 : : static QofLogModule log_module = GNC_MOD_IO;
42 : :
43 : : const gchar* recurrence_version_string = "1.0.0";
44 : : #define recurrence_root "gnc:recurrence"
45 : : #define recurrence_mult "recurrence:mult"
46 : : #define recurrence_period_type "recurrence:period_type"
47 : : #define recurrence_start "recurrence:start"
48 : : #define recurrence_weekend_adj "recurrence:weekend_adj"
49 : :
50 : : //TODO: I think three of these functions rightly belong in Recurrence.c.
51 : :
52 : : static gboolean
53 : 6 : recurrence_period_type_handler (xmlNodePtr node, gpointer d)
54 : : {
55 : 6 : auto r = static_cast<Recurrence*>(d);
56 : 6 : auto set_ptype = [](Recurrence *r, const char* txt)
57 : : {
58 : 6 : r->ptype = recurrencePeriodTypeFromString (txt);
59 : 6 : };
60 : 6 : apply_xmlnode_text (set_ptype, r, node);
61 : 6 : return (r->ptype != -1);
62 : : }
63 : :
64 : : static gboolean
65 : 6 : recurrence_start_date_handler (xmlNodePtr node, gpointer r)
66 : : {
67 : : GDate* d;
68 : :
69 : 6 : d = dom_tree_to_gdate (node);
70 : 6 : g_return_val_if_fail (d, FALSE);
71 : 6 : g_return_val_if_fail (g_date_valid (d), FALSE);
72 : 6 : ((Recurrence*) r)->start = *d;
73 : 6 : g_date_free (d);
74 : 6 : return TRUE;
75 : : }
76 : :
77 : : static gboolean
78 : 6 : recurrence_mult_handler (xmlNodePtr node, gpointer r)
79 : : {
80 : 6 : return dom_tree_to_guint16 (node, & ((Recurrence*)r)->mult);
81 : : }
82 : :
83 : : static gboolean
84 : 2 : recurrence_weekend_adj_handler (xmlNodePtr node, gpointer d)
85 : : {
86 : 2 : auto r = static_cast<Recurrence*>(d);
87 : 2 : auto set_wadj = [](Recurrence *r, const char* txt)
88 : : {
89 : 2 : r->wadj = recurrenceWeekendAdjustFromString (txt);
90 : 2 : };
91 : 2 : apply_xmlnode_text (set_wadj, r, node);
92 : 2 : return (r->wadj != -1);
93 : : }
94 : :
95 : : static struct dom_tree_handler recurrence_dom_handlers[] =
96 : : {
97 : : { recurrence_mult, recurrence_mult_handler, 1, 0 },
98 : : { recurrence_period_type, recurrence_period_type_handler, 1, 0 },
99 : : { recurrence_start, recurrence_start_date_handler, 1, 0 },
100 : : { recurrence_weekend_adj, recurrence_weekend_adj_handler, 0, 0 },
101 : : { NULL, NULL, 0, 0 }
102 : : };
103 : :
104 : : Recurrence*
105 : 6 : dom_tree_to_recurrence (xmlNodePtr node)
106 : : {
107 : : gboolean successful;
108 : : Recurrence* r;
109 : :
110 : 6 : r = g_new (Recurrence, 1);
111 : : /* In case the file doesn't have a weekend adjustment element */
112 : 6 : r->wadj = WEEKEND_ADJ_NONE;
113 : 6 : successful = dom_tree_generic_parse (node, recurrence_dom_handlers, r);
114 : 6 : if (!successful)
115 : : {
116 : 0 : PERR ("failed to parse recurrence node");
117 : 0 : xmlElemDump (stdout, NULL, node);
118 : 0 : g_free (r);
119 : 0 : r = NULL;
120 : : }
121 : 6 : return r;
122 : : }
123 : :
124 : : xmlNodePtr
125 : 2 : recurrence_to_dom_tree (const gchar* tag, const Recurrence* r)
126 : : {
127 : : xmlNodePtr n;
128 : : PeriodType pt;
129 : : GDate d;
130 : : WeekendAdjust wadj;
131 : :
132 : 2 : n = xmlNewNode (NULL, BAD_CAST tag);
133 : 2 : xmlSetProp (n, BAD_CAST "version", BAD_CAST recurrence_version_string);
134 : 2 : xmlAddChild (n, guint_to_dom_tree (recurrence_mult,
135 : : recurrenceGetMultiplier (r)));
136 : 2 : pt = recurrenceGetPeriodType (r);
137 : 2 : xmlAddChild (n, text_to_dom_tree (recurrence_period_type,
138 : : recurrencePeriodTypeToString (pt)));
139 : 2 : d = recurrenceGetDate (r);
140 : 2 : xmlAddChild (n, gdate_to_dom_tree (recurrence_start, &d));
141 : 2 : wadj = recurrenceGetWeekendAdjust (r);
142 : 2 : if (wadj != WEEKEND_ADJ_NONE)
143 : : {
144 : : /* In r17725 and r17751, I introduced this extra XML child
145 : : element, but this means a gnucash-2.2.x cannot read the SX
146 : : recurrence of a >=2.3.x file anymore, which is bad. In order
147 : : to improve this broken backward compatibility for most of the
148 : : cases, we don't write out this XML element as long as it is
149 : : only "none". */
150 : 2 : xmlAddChild (n, text_to_dom_tree (recurrence_weekend_adj,
151 : : recurrenceWeekendAdjustToString (wadj)));
152 : : }
153 : 2 : return n;
154 : : }
|