1 /* Lepton EDA library
2  * Copyright (C) 1998-2010 Ales Hvezda
3  * Copyright (C) 1998-2015 gEDA Contributors
4  * Copyright (C) 2017-2021 Lepton EDA Contributors
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (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, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 /*! \file undo.c
21  */
22 
23 #include <config.h>
24 
25 #include <stdio.h>
26 #include <ctype.h>
27 #ifdef HAVE_STDLIB_H
28 #include <stdlib.h>
29 #endif
30 #ifdef HAVE_UNISTD_H
31 #include <unistd.h>
32 #endif
33 
34 #include "liblepton_priv.h"
35 
36 /*! \todo Finish function documentation!!!
37  *  \brief
38  *  \par Function Description
39  *
40  */
41 LeptonUndo*
s_undo_return_tail(LeptonUndo * head)42 s_undo_return_tail (LeptonUndo *head)
43 {
44   LeptonUndo *u_current=NULL;
45   LeptonUndo *ret_struct=NULL;
46 
47   u_current = head;
48   while ( u_current != NULL ) { /* goto end of list */
49     ret_struct = u_current;
50     u_current = u_current->next;
51   }
52 
53   return(ret_struct);
54 }
55 
56 /*! \todo Finish function documentation!!!
57  *  \brief
58  *  \par Function Description
59  *
60  */
61 LeptonUndo*
s_undo_return_head(LeptonUndo * tail)62 s_undo_return_head(LeptonUndo *tail)
63 {
64   LeptonUndo *u_current=NULL;
65   LeptonUndo *ret_struct=NULL;
66 
67   u_current = tail;
68   while ( u_current != NULL ) { /* goto end of list */
69     ret_struct = u_current;
70     u_current = u_current->prev;
71   }
72 
73   return(ret_struct);
74 }
75 
76 /*! \todo Finish function documentation!!!
77  *  \brief
78  *  \par Function Description
79  *
80  */
81 LeptonUndo*
s_undo_new_head(void)82 s_undo_new_head(void)
83 {
84   LeptonUndo *u_new;
85 
86   u_new = (LeptonUndo *) g_malloc (sizeof (LeptonUndo));
87   u_new->type = -1;
88   u_new->filename = NULL;
89   u_new->object_list = NULL;
90   u_new->x = u_new->y = 0;
91   u_new->scale = 0;
92 
93   u_new->page_control = 0;
94   u_new->up = -2;
95 
96   u_new->prev = NULL;
97   u_new->next = NULL;
98 
99   return(u_new);
100 }
101 
102 /*! \todo Finish function documentation!!!
103  *  \brief
104  *  \par Function Description
105  *
106  */
107 void
s_undo_destroy_head(LeptonUndo * u_head)108 s_undo_destroy_head (LeptonUndo *u_head)
109 {
110   g_free(u_head);
111 }
112 
113 /*! \todo Finish function documentation!!!
114  *  \brief
115  *  \par Function Description
116  *
117  */
118 LeptonUndo*
s_undo_add(LeptonUndo * head,int type,char * filename,GList * object_list,int x,int y,double scale,int page_control,int up)119 s_undo_add (LeptonUndo *head,
120             int type,
121             char *filename,
122             GList *object_list,
123             int x,
124             int y,
125             double scale,
126             int page_control,
127             int up)
128 {
129   LeptonUndo *tail;
130   LeptonUndo *u_new;
131 
132   u_new = (LeptonUndo *) g_malloc (sizeof (LeptonUndo));
133 
134   u_new->filename = g_strdup (filename);
135 
136   u_new->object_list = object_list;
137 
138   u_new->type = type;
139 
140   u_new->x = x;
141   u_new->y = y;
142   u_new->scale = scale;
143 
144   u_new->page_control = page_control;
145   u_new->up = up;
146 
147   if (head == NULL) {
148     u_new->prev = NULL; /* setup previous link */
149     u_new->next = NULL;
150     return(u_new);
151   } else {
152     tail = s_undo_return_tail(head);
153     u_new->prev = tail; /* setup previous link */
154     u_new->next = NULL;
155     tail->next = u_new;
156     return(tail->next);
157   }
158 }
159 
160 /*! \todo Finish function documentation!!!
161  *  \brief
162  *  \par Function Description
163  *
164  */
165 void
s_undo_print_all(LeptonUndo * head)166 s_undo_print_all (LeptonUndo *head)
167 {
168   LeptonUndo *u_current;
169 
170   u_current = head;
171 
172   printf("START printing undo ********************\n");
173   printf("BOTTOM\n");
174   while(u_current != NULL) {
175 
176     if (u_current->filename) printf("%s\n", u_current->filename);
177 
178     if (u_current->object_list) {
179       lepton_object_list_print (u_current->object_list);
180     }
181 
182     printf("\t%d %d %f\n", u_current->x, u_current->y, u_current->scale);
183     u_current = u_current->next;
184   }
185   printf("TOS\n");
186   printf("Number of levels: %d\n", s_undo_levels(head));
187   printf("DONE printing undo ********************\n");
188   printf("\n");
189 
190 }
191 
192 /*! \todo Finish function documentation!!!
193  *  \brief
194  *  \par Function Description
195  *
196  */
197 void
s_undo_destroy_all(LeptonUndo * head)198 s_undo_destroy_all (LeptonUndo *head)
199 {
200   LeptonUndo *u_current;
201   LeptonUndo *u_prev;
202 
203   u_current = s_undo_return_tail(head);
204 
205   while (u_current != NULL) {
206     u_prev = u_current->prev;
207     g_free(u_current->filename);
208 
209     if (u_current->object_list) {
210       lepton_object_list_delete (u_current->object_list);
211       u_current->object_list = NULL;
212     }
213 
214     g_free(u_current);
215     u_current = u_prev;
216   }
217 }
218 
219 
220 /*! \todo Finish function documentation!!!
221  *  \brief
222  *  \par Function Description
223  *
224  */
225 void
s_undo_remove_rest(LeptonUndo * head)226 s_undo_remove_rest (LeptonUndo *head)
227 {
228   LeptonUndo *u_current;
229   LeptonUndo *u_next;
230 
231   u_current = head;
232 
233   while (u_current != NULL) {
234     u_next = u_current->next;
235 
236     if (u_current->filename) {
237       unlink(u_current->filename);
238       g_free(u_current->filename);
239     }
240 
241     if (u_current->object_list) {
242       lepton_object_list_delete (u_current->object_list);
243       u_current->object_list = NULL;
244     }
245 
246     g_free(u_current);
247     u_current = u_next;
248   }
249 }
250 
251 /*! \todo Finish function documentation!!!
252  *  \brief
253  *  \par Function Description
254  *
255  */
256 int
s_undo_levels(LeptonUndo * head)257 s_undo_levels (LeptonUndo *head)
258 {
259   LeptonUndo *u_current;
260   int count = 0;
261 
262   u_current = head;
263   while (u_current != NULL) {
264     if (u_current->filename || u_current->object_list) {
265       count++;
266     }
267 
268     u_current = u_current->next;
269   }
270 
271   return(count);
272 }
273 
274 /*! \todo Finish function documentation!!!
275  *  \brief
276  *  \par Function Description
277  *
278  */
s_undo_init(LeptonPage * p_current)279 void s_undo_init (LeptonPage *p_current)
280 {
281   p_current->undo_tos = p_current->undo_bottom = NULL;
282   p_current->undo_current = NULL;
283 }
284 
285 /*! \todo Finish function documentation!!!
286  *  \brief
287  *  \par Function Description
288  *
289  */
290 void
s_undo_free_all(LeptonPage * p_current)291 s_undo_free_all (LeptonPage *p_current)
292 {
293   s_undo_destroy_all (p_current->undo_bottom);
294   p_current->undo_bottom = NULL;
295   p_current->undo_tos = NULL;
296   p_current->undo_current = NULL;
297 }
298