GnuCash  5.6-150-g038405b370+
gnc-html-history.cpp
1 /********************************************************************
2  * gnc-html-history.c -- keep a HTML history *
3  * Copyright (C) 2000 Bill Gribble <grib@billgribble.com> *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License*
16  * along with this program; if not, contact: *
17  * *
18  * Free Software Foundation Voice: +1-617-542-5942 *
19  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20  * Boston, MA 02110-1301, USA gnu@gnu.org *
21  ********************************************************************/
22 
23 #include <config.h>
24 
25 #include <gtk/gtk.h>
26 #include <string>
27 
28 #include "gnc-html-history.h"
29 
31 {
32  GList * nodes;
33  GList * current_node;
34  GList * last_node;
35 
36  /* call this whenever a node is destroyed */
37  gnc_html_history_destroy_cb destroy_cb;
38  gpointer destroy_cb_data;
39 };
40 
41 /********************************************************************
42  * gnc_html_history_new
43  ********************************************************************/
44 
45 gnc_html_history *
46 gnc_html_history_new(void) noexcept
47 {
48  gnc_html_history * hist = g_new0(gnc_html_history, 1);
49  hist->nodes = nullptr;
50  hist->current_node = nullptr;
51  hist->last_node = nullptr;
52  return hist;
53 }
54 
55 
56 
57 /********************************************************************
58  * gnc_html_history_destroy
59  ********************************************************************/
60 
61 void
62 gnc_html_history_destroy(gnc_html_history * hist) noexcept
63 {
64  for (GList *n = hist->nodes; n ; n = n->next)
65  {
66  if (hist->destroy_cb)
67  {
68  (hist->destroy_cb)((gnc_html_history_node *)n->data,
69  hist->destroy_cb_data);
70  }
71  gnc_html_history_node_destroy((gnc_html_history_node *)n->data);
72  }
73  g_list_free(hist->nodes);
74 
75  hist->nodes = nullptr;
76  hist->current_node = nullptr;
77  hist->last_node = nullptr;
78  g_free(hist);
79 }
80 
81 /********************************************************************
82  * gnc_html_history_set_node_destroy_cb
83  ********************************************************************/
84 
85 void
86 gnc_html_history_set_node_destroy_cb(gnc_html_history * hist,
87  gnc_html_history_destroy_cb cb,
88  gpointer cb_data) noexcept
89 {
90  hist->destroy_cb = cb;
91  hist->destroy_cb_data = cb_data;
92 }
93 
94 static int
95 g_strcmp(char * a, char * b)
96 {
97  if (!a && b)
98  {
99  return 1;
100  }
101  else if (a && !b)
102  {
103  return -1;
104  }
105  else if (!a && !b)
106  {
107  return 0;
108  }
109  else
110  {
111  return strcmp(a, b);
112  }
113 
114 }
115 
116 
117 /********************************************************************
118  * gnc_html_history_append
119  ********************************************************************/
120 void
121 gnc_html_history_append(gnc_html_history * hist,
122  gnc_html_history_node * node) noexcept
123 {
124  if (hist->current_node)
125  {
126  auto hn = static_cast<gnc_html_history_node *>(hist->current_node->data);
127  if ((hn->type == node->type) &&
128  !g_strcmp(hn->location, node->location) &&
129  !g_strcmp(hn->label, node->label))
130  {
131  if (hist->destroy_cb)
132  {
133  (hist->destroy_cb)(hn, hist->destroy_cb_data);
134  }
135  gnc_html_history_node_destroy(node);
136  return;
137  }
138 
139  /* blow away the history after this point, if there is one */
140  for (GList *n = hist->current_node->next; n; n = n->next)
141  {
142  if (hist->destroy_cb)
143  {
144  (hist->destroy_cb)((gnc_html_history_node *)n->data,
145  hist->destroy_cb_data);
146  }
147  gnc_html_history_node_destroy((gnc_html_history_node *)n->data);
148  }
149  g_list_free(hist->current_node->next);
150  hist->current_node->next = nullptr;
151  hist->last_node = hist->current_node;
152  }
153 
154  GList *n = g_list_alloc();
155  n->data = (gpointer) node;
156  n->next = nullptr;
157  n->prev = nullptr;
158 
159  if (hist->nodes && hist->last_node)
160  {
161  n->prev = hist->last_node; /* back pointer */
162  hist->last_node->next = n; /* add n to the list */
163  hist->last_node = n; /* n is last */
164  hist->current_node = n;
165  }
166  else
167  {
168  /* this is the first entry in the list */
169  if (hist->nodes)
170  {
171  g_print ("???? hist->nodes non-NULL, but no last_node!\n");
172  }
173  hist->nodes = n;
174  hist->last_node = n;
175  hist->current_node = n;
176  }
177 }
178 
179 
180 /********************************************************************
181  * gnc_html_history_get_current
182  ********************************************************************/
183 
184 gnc_html_history_node *
185 gnc_html_history_get_current(gnc_html_history * hist) noexcept
186 {
187  if (!hist || !(hist->current_node)) return nullptr;
188 
189  return static_cast<gnc_html_history_node *>(hist->current_node->data);
190 }
191 
192 
193 /********************************************************************
194  * gnc_html_history_forward
195  ********************************************************************/
196 
197 gnc_html_history_node *
198 gnc_html_history_forward(gnc_html_history * hist) noexcept
199 {
200  if (!hist || !(hist->current_node))
201  {
202  return nullptr;
203  }
204 
205  if (hist->current_node->next)
206  {
207  hist->current_node = hist->current_node->next;
208  }
209 
210  return static_cast<gnc_html_history_node *>(hist->current_node->data);
211 }
212 
213 
214 /********************************************************************
215  * gnc_html_history_back
216  ********************************************************************/
217 
218 gnc_html_history_node *
219 gnc_html_history_back(gnc_html_history * hist) noexcept
220 {
221 
222  if (!hist || !(hist->current_node))
223  {
224  return nullptr;
225  }
226 
227  if (hist->current_node->prev)
228  {
229  hist->current_node = hist->current_node->prev;
230  }
231 
232  return static_cast<gnc_html_history_node *>(hist->current_node->data);
233 }
234 
235 
236 /********************************************************************
237  * gnc_html_history_back_p
238  * is it possible to go back?
239  ********************************************************************/
240 
241 int
242 gnc_html_history_back_p(gnc_html_history * hist) noexcept
243 {
244  if (hist && hist->current_node && hist->current_node->prev)
245  {
246  return TRUE;
247  }
248  else
249  {
250  return FALSE;
251  }
252 }
253 
254 
255 /********************************************************************
256  * gnc_html_history_forward_p
257  * is it possible to go forward?
258  ********************************************************************/
259 
260 int
261 gnc_html_history_forward_p(gnc_html_history * hist) noexcept
262 {
263  if (hist && hist->current_node && hist->current_node->next)
264  {
265  return TRUE;
266  }
267  else
268  {
269  return FALSE;
270  }
271 }
272 
273 
274 /********************************************************************
275  * gnc_html_history_node_new
276  ********************************************************************/
277 
278 gnc_html_history_node *
279 gnc_html_history_node_new(URLType type, const gchar * location,
280  const gchar * label) noexcept
281 {
282  gnc_html_history_node * rv = g_new0(gnc_html_history_node, 1);
283 
284  rv->type = g_strdup(type);
285  rv->location = g_strdup(location);
286  rv->label = g_strdup(label);
287  return rv;
288 }
289 
290 
291 /********************************************************************
292  * gnc_html_history_node_destroy
293  ********************************************************************/
294 
295 void
296 gnc_html_history_node_destroy(gnc_html_history_node * node) noexcept
297 {
298 
299  /* free the url resources and cached text */
300  g_free(node->type);
301  g_free(node->location);
302  g_free(node->label);
303 
304  node->location = nullptr;
305  node->label = nullptr;
306 
307  g_free(node);
308 }