Line data Source code
1 : /* File: ctrl_undo_redo_list.c; Copyright and License: see below */
2 :
3 : #include "ctrl_undo_redo_list.h"
4 : #include "u8/u8_trace.h"
5 : #include "u8/u8_log.h"
6 : #include <assert.h>
7 :
8 104 : u8_error_t ctrl_undo_redo_list_remove_boundary_from_end ( ctrl_undo_redo_list_t *this_ )
9 : {
10 104 : assert( (*this_).start < CTRL_UNDO_REDO_LIST_MAX_SIZE );
11 104 : assert( (*this_).length <= CTRL_UNDO_REDO_LIST_MAX_SIZE );
12 104 : assert( (*this_).current <= (*this_).length );
13 :
14 104 : u8_error_t result = U8_ERROR_NONE;
15 : ctrl_undo_redo_entry_t *boundary_entry;
16 :
17 104 : if ( (*this_).current == 0 )
18 : {
19 : /* there is no entry - therefore no boundary - to be removed */
20 0 : result = U8_ERROR_INVALID_REQUEST;
21 : }
22 : else
23 : {
24 : /* check if current is a boundary */
25 : uint32_t index;
26 : ctrl_undo_redo_entry_type_t action;
27 :
28 104 : index = ((*this_).start + (*this_).current + (CTRL_UNDO_REDO_LIST_MAX_SIZE-1)) % CTRL_UNDO_REDO_LIST_MAX_SIZE;
29 104 : boundary_entry = &((*this_).buffer[index]);
30 104 : action = ctrl_undo_redo_entry_get_action_type ( boundary_entry );
31 104 : if ( CTRL_UNDO_REDO_ENTRY_TYPE_BOUNDARY != action )
32 : {
33 : /* current is not a boundary */
34 0 : result = U8_ERROR_INVALID_REQUEST;
35 : }
36 : else
37 : {
38 : /* drop all list-entries newer than the current position */
39 104 : if ( (*this_).current < (*this_).length )
40 : {
41 : /* call destructor of all later entries */
42 0 : for ( uint32_t pos = (*this_).current; pos < (*this_).length; pos ++ )
43 : {
44 0 : uint32_t del_index = ((*this_).start + pos) % CTRL_UNDO_REDO_LIST_MAX_SIZE;
45 0 : ctrl_undo_redo_entry_destroy( &((*this_).buffer[del_index]) );
46 : }
47 :
48 : /* shrink the list */
49 0 : (*this_).length = (*this_).current;
50 : }
51 :
52 : /* call destructor of boundary and remove it */
53 104 : ctrl_undo_redo_entry_destroy( boundary_entry );
54 :
55 : /* remove the boundary */
56 104 : (*this_).length --;
57 104 : (*this_).current --;
58 : }
59 : }
60 :
61 104 : return result;
62 : }
63 :
64 146 : u8_error_t ctrl_undo_redo_list_undo ( ctrl_undo_redo_list_t *this_, data_stat_t *io_stat )
65 : {
66 146 : U8_TRACE_BEGIN();
67 146 : assert ( NULL != io_stat );
68 :
69 146 : u8_error_t result = U8_ERROR_NONE;
70 :
71 146 : if ( 2 > ctrl_undo_redo_list_private_count_boundaries( this_, (*this_).start, (*this_).current ) )
72 : {
73 4 : if ( (*this_).buffer_incomplete )
74 : {
75 2 : result = U8_ERROR_ARRAY_BUFFER_EXCEEDED;
76 : }
77 : else
78 : {
79 2 : result = U8_ERROR_INVALID_REQUEST;
80 : }
81 : }
82 : else
83 : {
84 142 : bool finished = false;
85 431 : for ( uint32_t pos = 0; (pos < CTRL_UNDO_REDO_LIST_MAX_SIZE) && (! finished); pos ++ )
86 : {
87 : /* move the current pointer back in the list */
88 289 : (*this_).current --;
89 :
90 : /* check if we are done */
91 289 : const uint32_t index
92 289 : = ((*this_).start + (*this_).current + (CTRL_UNDO_REDO_LIST_MAX_SIZE-1)) % CTRL_UNDO_REDO_LIST_MAX_SIZE;
93 289 : ctrl_undo_redo_entry_t *const cur_entry = &((*this_).buffer[index]);
94 :
95 289 : if ( CTRL_UNDO_REDO_ENTRY_TYPE_BOUNDARY == ctrl_undo_redo_entry_get_action_type( cur_entry ) )
96 : {
97 142 : U8_TRACE_INFO("boundary");
98 142 : const data_revision_t revision = ctrl_undo_redo_entry_get_boundary_revision( cur_entry );
99 142 : data_database_writer_set_revision( (*this_).db_writer, revision );
100 142 : finished = true;
101 : }
102 : else
103 : {
104 147 : U8_TRACE_INFO("undo");
105 147 : const uint32_t current_before = (*this_).current;
106 147 : const u8_error_t cur_err = ctrl_undo_redo_list_private_do_action( this_, cur_entry, true );
107 147 : ctrl_undo_redo_entry_to_statistics ( cur_entry, true /*=undo*/, (U8_ERROR_NONE!=cur_err), io_stat );
108 147 : result |= cur_err;
109 147 : if ( (*this_).current != current_before )
110 : {
111 0 : U8_LOG_ERROR("ctrl_undo_redo_list_t was modified while performing undo.");
112 : /* try to continue undo, this is the most likely way to get the db back to a consistent state */
113 : }
114 : }
115 : }
116 : }
117 :
118 146 : U8_TRACE_INFO_INT_INT( "current, length:", (*this_).current, (*this_).length );
119 :
120 146 : U8_TRACE_END_ERR( result );
121 146 : return result;
122 : }
123 :
124 16 : u8_error_t ctrl_undo_redo_list_redo ( ctrl_undo_redo_list_t *this_, data_stat_t *io_stat )
125 : {
126 16 : U8_TRACE_BEGIN();
127 16 : assert ( NULL != io_stat );
128 :
129 16 : u8_error_t result = U8_ERROR_NONE;
130 :
131 16 : if ( (*this_).current == (*this_).length )
132 : {
133 : /* current points already to the end of the list - no redo possible */
134 3 : result = U8_ERROR_INVALID_REQUEST;
135 : }
136 : else
137 : {
138 13 : bool finished = false;
139 43 : for ( uint32_t pos = 0; (pos < CTRL_UNDO_REDO_LIST_MAX_SIZE) && (! finished); pos ++ )
140 : {
141 : /* move the current pointer forward in the list */
142 30 : (*this_).current ++;
143 :
144 : /* check if we are done */
145 30 : const uint32_t index
146 30 : = ((*this_).start + (*this_).current + (CTRL_UNDO_REDO_LIST_MAX_SIZE-1)) % CTRL_UNDO_REDO_LIST_MAX_SIZE;
147 30 : ctrl_undo_redo_entry_t *const cur_entry = &((*this_).buffer[index]);
148 :
149 30 : if ( CTRL_UNDO_REDO_ENTRY_TYPE_BOUNDARY == ctrl_undo_redo_entry_get_action_type( cur_entry ) )
150 : {
151 13 : U8_TRACE_INFO("boundary");
152 13 : const data_revision_t revision = ctrl_undo_redo_entry_get_boundary_revision( cur_entry );
153 13 : data_database_writer_set_revision( (*this_).db_writer, revision );
154 13 : finished = true;
155 : }
156 17 : else if ( (*this_).current == (*this_).length )
157 : {
158 0 : U8_TRACE_INFO("boundary");
159 0 : finished = true;
160 : }
161 30 : if ( ! finished )
162 : {
163 17 : U8_TRACE_INFO("redo");
164 17 : const uint32_t current_before = (*this_).current;
165 17 : const u8_error_t cur_err = ctrl_undo_redo_list_private_do_action( this_, cur_entry, false );
166 17 : ctrl_undo_redo_entry_to_statistics ( cur_entry, false /*=undo*/, (U8_ERROR_NONE!=cur_err), io_stat );
167 17 : result |= cur_err;
168 17 : if ( (*this_).current != current_before )
169 : {
170 0 : U8_LOG_ERROR("ctrl_undo_redo_list_t was modified while performing redo.");
171 0 : result |= U8_ERROR_INVALID_REQUEST;
172 0 : finished = true;
173 : }
174 : }
175 : }
176 : }
177 :
178 16 : U8_TRACE_INFO_INT_INT( "current, length:", (*this_).current, (*this_).length );
179 :
180 16 : U8_TRACE_END_ERR( result );
181 16 : return result;
182 : }
183 :
184 8 : u8_error_t ctrl_undo_redo_list_get_undo_iterator ( const ctrl_undo_redo_list_t *this_,
185 : ctrl_undo_redo_iterator_t *out_undo_iterator )
186 : {
187 8 : U8_TRACE_BEGIN();
188 8 : assert( NULL != out_undo_iterator );
189 8 : assert( (*this_).start < CTRL_UNDO_REDO_LIST_MAX_SIZE );
190 8 : assert( (*this_).length <= CTRL_UNDO_REDO_LIST_MAX_SIZE );
191 8 : assert( (*this_).current <= (*this_).length ); /* current is in 0..length, relative to start */
192 : /* B0 A1 A2 A3 B1 A4 B2 X X */
193 : /* 0 1 2 3 4 5 6 7 8 9 */
194 : /* ^ start ^ current */
195 : /* Boundaries B0..2, Actions A1..4 */
196 8 : u8_error_t result = U8_ERROR_NONE;
197 :
198 8 : if ( (*this_).current > 0 )
199 : {
200 8 : const uint32_t last
201 8 : = ( (*this_).start + (*this_).current + CTRL_UNDO_REDO_LIST_MAX_SIZE - 2 ) % CTRL_UNDO_REDO_LIST_MAX_SIZE;
202 8 : const uint32_t undo_length = (*this_).current - 1; /* total number of undo entries */
203 8 : uint32_t count = 0;
204 : {
205 : ctrl_undo_redo_iterator_t pre_scan;
206 8 : ctrl_undo_redo_iterator_init( &pre_scan,
207 8 : &((*this_).buffer),
208 : CTRL_UNDO_REDO_LIST_MAX_SIZE,
209 : false, /* NOT iterate_upwards */
210 : last,
211 : undo_length
212 : );
213 37 : for( bool finished = false; ctrl_undo_redo_iterator_has_next( &pre_scan ) && ( ! finished ); )
214 : {
215 29 : const ctrl_undo_redo_entry_t *next = ctrl_undo_redo_iterator_next( &pre_scan );
216 29 : if ( CTRL_UNDO_REDO_ENTRY_TYPE_BOUNDARY == ctrl_undo_redo_entry_get_action_type( next ) )
217 : {
218 8 : finished = true;
219 : }
220 : else
221 : {
222 21 : count ++;
223 : }
224 : }
225 8 : ctrl_undo_redo_iterator_destroy( &pre_scan );
226 : }
227 8 : if ( count == undo_length )
228 : {
229 : /* no boundary found */
230 0 : if ( (*this_).buffer_incomplete )
231 : {
232 0 : result = U8_ERROR_ARRAY_BUFFER_EXCEEDED;
233 : }
234 : else
235 : {
236 0 : assert( count == 0 ); /* this should happen only when (*this_).current is at the initial boundary */
237 0 : result = U8_ERROR_INVALID_REQUEST;
238 : }
239 : }
240 : else
241 : {
242 8 : assert( count < undo_length );
243 8 : ctrl_undo_redo_iterator_reinit( out_undo_iterator,
244 8 : &((*this_).buffer),
245 : CTRL_UNDO_REDO_LIST_MAX_SIZE,
246 : false, /* NOT iterate_upwards */
247 : last,
248 : count
249 : );
250 : }
251 : }
252 : else
253 : {
254 0 : assert( false ); /* already at the start of the list, not even a single boundary is there anymore */
255 : result = U8_ERROR_ARRAY_BUFFER_EXCEEDED;
256 : }
257 :
258 8 : U8_TRACE_END_ERR( result );
259 8 : return result;
260 : }
261 :
262 0 : u8_error_t ctrl_undo_redo_list_get_redo_iterator ( const ctrl_undo_redo_list_t *this_,
263 : ctrl_undo_redo_iterator_t *out_redo_iterator )
264 : {
265 0 : U8_TRACE_BEGIN();
266 0 : assert( NULL != out_redo_iterator );
267 0 : assert( (*this_).start < CTRL_UNDO_REDO_LIST_MAX_SIZE );
268 0 : assert( (*this_).length <= CTRL_UNDO_REDO_LIST_MAX_SIZE );
269 0 : assert( (*this_).current <= (*this_).length ); /* current is in 0..length, relative to start */
270 : /* B0 A1 A2 A3 B1 A4 B2 X X */
271 : /* 0 1 2 3 4 5 6 7 8 9 */
272 : /* ^ start ^ current */
273 : /* Boundaries B0..2, Actions A1..4 */
274 0 : u8_error_t result = U8_ERROR_NONE;
275 :
276 0 : const uint32_t next
277 0 : = ( (*this_).start + (*this_).current ) % CTRL_UNDO_REDO_LIST_MAX_SIZE;
278 0 : const uint32_t redo_length = (*this_).length - (*this_).current; /* total number of redo entries */
279 0 : if ( redo_length > 0 )
280 : {
281 0 : uint32_t count = 0;
282 : {
283 : ctrl_undo_redo_iterator_t pre_scan;
284 0 : ctrl_undo_redo_iterator_init( &pre_scan,
285 0 : &((*this_).buffer),
286 : CTRL_UNDO_REDO_LIST_MAX_SIZE,
287 : true, /* iterate_upwards */
288 : next,
289 : redo_length
290 : );
291 0 : for( bool finished = false; ctrl_undo_redo_iterator_has_next( &pre_scan ) && ( ! finished ); )
292 : {
293 0 : const ctrl_undo_redo_entry_t *next = ctrl_undo_redo_iterator_next( &pre_scan );
294 0 : if ( CTRL_UNDO_REDO_ENTRY_TYPE_BOUNDARY == ctrl_undo_redo_entry_get_action_type( next ) )
295 : {
296 0 : finished = true;
297 : }
298 : else
299 : {
300 0 : count ++;
301 : }
302 : }
303 0 : ctrl_undo_redo_iterator_destroy( &pre_scan );
304 : }
305 0 : assert( count < redo_length );
306 0 : ctrl_undo_redo_iterator_reinit( out_redo_iterator,
307 0 : &((*this_).buffer),
308 : CTRL_UNDO_REDO_LIST_MAX_SIZE,
309 : true, /* iterate_upwards */
310 : next,
311 : count
312 : );
313 : }
314 : else
315 : {
316 0 : result = U8_ERROR_INVALID_REQUEST;
317 : }
318 :
319 0 : U8_TRACE_END_ERR( result );
320 0 : return result;
321 : }
322 :
323 : /* ================================ private ================================ */
324 :
325 682 : ctrl_undo_redo_entry_t *ctrl_undo_redo_list_private_add_entry_ptr ( ctrl_undo_redo_list_t *this_ )
326 : {
327 682 : U8_TRACE_BEGIN();
328 682 : assert( (*this_).start < CTRL_UNDO_REDO_LIST_MAX_SIZE );
329 682 : assert( (*this_).length <= CTRL_UNDO_REDO_LIST_MAX_SIZE );
330 682 : assert( (*this_).current <= (*this_).length );
331 :
332 : uint32_t index;
333 : ctrl_undo_redo_entry_t *result;
334 :
335 682 : if ( (*this_).current < (*this_).length )
336 : {
337 : /* overwrite an existing and new entry */
338 : /* (*this_).start stays untouched */
339 1 : (*this_).current ++;
340 :
341 : /* call destructor of all later entries */
342 252 : for ( uint32_t pos = (*this_).current; pos < (*this_).length; pos ++ )
343 : {
344 251 : uint32_t del_index = ((*this_).start + pos) % CTRL_UNDO_REDO_LIST_MAX_SIZE;
345 251 : ctrl_undo_redo_entry_destroy( &((*this_).buffer[del_index]) );
346 : }
347 :
348 : /* shrink the list */
349 1 : (*this_).length = (*this_).current;
350 :
351 1 : index = ((*this_).start + (*this_).current + (CTRL_UNDO_REDO_LIST_MAX_SIZE-1)) % CTRL_UNDO_REDO_LIST_MAX_SIZE;
352 1 : result = &((*this_).buffer[index]);
353 : }
354 681 : else if ( (*this_).current < CTRL_UNDO_REDO_LIST_MAX_SIZE )
355 : {
356 : /* add a new entry */
357 : /* (*this_).start stays untouched */
358 680 : (*this_).current ++;
359 680 : (*this_).length ++;
360 :
361 : /* call the constructor */
362 680 : index = ((*this_).start + (*this_).current + (CTRL_UNDO_REDO_LIST_MAX_SIZE-1)) % CTRL_UNDO_REDO_LIST_MAX_SIZE;
363 680 : result = &((*this_).buffer[index]);
364 680 : ctrl_undo_redo_entry_init_empty( result );
365 : }
366 : else
367 : {
368 : /* overwrite an existing old entry */
369 1 : (*this_).start = ((*this_).start+1) % CTRL_UNDO_REDO_LIST_MAX_SIZE;
370 : /* (*this_).current is already CTRL_UNDO_REDO_LIST_MAX_SIZE */
371 : /* (*this_).length is already CTRL_UNDO_REDO_LIST_MAX_SIZE */
372 1 : (*this_).buffer_incomplete = true;
373 :
374 1 : index = ((*this_).start + (*this_).current + (CTRL_UNDO_REDO_LIST_MAX_SIZE-1)) % CTRL_UNDO_REDO_LIST_MAX_SIZE;
375 1 : result = &((*this_).buffer[index]);
376 : }
377 :
378 682 : U8_TRACE_INFO_INT_INT( "current, length:", (*this_).current, (*this_).length );
379 :
380 682 : U8_TRACE_END();
381 682 : return result;
382 : }
383 :
384 164 : u8_error_t ctrl_undo_redo_list_private_do_action ( ctrl_undo_redo_list_t *this_, ctrl_undo_redo_entry_t *action, bool undo )
385 : {
386 164 : U8_TRACE_BEGIN();
387 :
388 164 : u8_error_t result = U8_ERROR_NONE;
389 :
390 164 : switch ( ctrl_undo_redo_entry_get_action_type( action ) )
391 : {
392 0 : case CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_DIAGRAM:
393 : {
394 0 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_DIAGRAM" );
395 0 : const data_diagram_t *diag = ctrl_undo_redo_entry_get_diagram_before_action_const ( action );
396 0 : if ( undo )
397 : {
398 0 : result |= (u8_error_t) data_database_writer_create_diagram ( (*this_).db_writer, diag, NULL );
399 : }
400 : else
401 : {
402 0 : data_row_t obj_id = data_diagram_get_row_id ( diag );
403 0 : result |= (u8_error_t) data_database_writer_delete_diagram ( (*this_).db_writer, obj_id, NULL );
404 : }
405 : }
406 0 : break;
407 :
408 4 : case CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_DIAGRAM:
409 : {
410 4 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_DIAGRAM" );
411 : const data_diagram_t *diag;
412 4 : if ( undo )
413 : {
414 2 : diag = ctrl_undo_redo_entry_get_diagram_before_action_const ( action );
415 : }
416 : else
417 : {
418 2 : diag = ctrl_undo_redo_entry_get_diagram_after_action_const ( action );
419 : }
420 4 : data_row_t diag_id = data_diagram_get_row_id ( diag );
421 4 : data_row_t diag_parent_id = data_diagram_get_parent_row_id ( diag );
422 4 : data_diagram_type_t diag_type = data_diagram_get_diagram_type ( diag );
423 4 : const char* diag_stereotype = data_diagram_get_stereotype_const ( diag );
424 4 : const char* diag_name = data_diagram_get_name_const ( diag );
425 4 : const char* diag_description = data_diagram_get_description_const ( diag );
426 4 : int32_t diag_list_oder = data_diagram_get_list_order ( diag );
427 4 : result |= (u8_error_t) data_database_writer_update_diagram_parent_id ( (*this_).db_writer, diag_id, diag_parent_id, NULL );
428 4 : result |= (u8_error_t) data_database_writer_update_diagram_type ( (*this_).db_writer, diag_id, diag_type, NULL );
429 4 : result |= (u8_error_t) data_database_writer_update_diagram_stereotype ( (*this_).db_writer, diag_id, diag_stereotype, NULL );
430 4 : result |= (u8_error_t) data_database_writer_update_diagram_name ( (*this_).db_writer, diag_id, diag_name, NULL );
431 4 : result |= (u8_error_t) data_database_writer_update_diagram_description ( (*this_).db_writer, diag_id, diag_description, NULL );
432 4 : result |= (u8_error_t) data_database_writer_update_diagram_list_order ( (*this_).db_writer, diag_id, diag_list_oder, NULL );
433 : }
434 4 : break;
435 :
436 134 : case CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_DIAGRAM:
437 : {
438 134 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_DIAGRAM" );
439 134 : const data_diagram_t *diag = ctrl_undo_redo_entry_get_diagram_after_action_const ( action );
440 134 : if ( undo )
441 : {
442 131 : data_row_t obj_id = data_diagram_get_row_id ( diag );
443 131 : result |= (u8_error_t) data_database_writer_delete_diagram ( (*this_).db_writer, obj_id, NULL );
444 : }
445 : else
446 : {
447 3 : result |= (u8_error_t) data_database_writer_create_diagram ( (*this_).db_writer, diag, NULL );
448 : }
449 : }
450 134 : break;
451 :
452 0 : case CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_DIAGRAMELEMENT:
453 : {
454 0 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_DIAGRAMELEMENT" );
455 0 : const data_diagramelement_t *diag_ele = ctrl_undo_redo_entry_get_diagramelement_before_action_const ( action );
456 0 : if ( undo )
457 : {
458 0 : result |= (u8_error_t) data_database_writer_create_diagramelement ( (*this_).db_writer, diag_ele, NULL );
459 : }
460 : else
461 : {
462 0 : data_row_t obj_id = data_diagramelement_get_row_id ( diag_ele );
463 0 : result |= (u8_error_t) data_database_writer_delete_diagramelement ( (*this_).db_writer, obj_id, NULL );
464 : }
465 : }
466 0 : break;
467 :
468 5 : case CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_DIAGRAMELEMENT:
469 : {
470 5 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_DIAGRAMELEMENT" );
471 : const data_diagramelement_t *diag_element;
472 5 : if ( undo )
473 : {
474 3 : diag_element = ctrl_undo_redo_entry_get_diagramelement_before_action_const ( action );
475 : }
476 : else
477 : {
478 2 : diag_element = ctrl_undo_redo_entry_get_diagramelement_after_action_const ( action );
479 : }
480 5 : data_row_t diag_elem_id = data_diagramelement_get_row_id ( diag_element );
481 5 : data_diagramelement_flag_t diag_elem_display_flags = data_diagramelement_get_display_flags ( diag_element );
482 5 : data_row_t diag_feature_id = data_diagramelement_get_focused_feature_row_id ( diag_element );
483 5 : result |= (u8_error_t) data_database_writer_update_diagramelement_display_flags ( (*this_).db_writer, diag_elem_id, diag_elem_display_flags, NULL );
484 5 : result |= (u8_error_t) data_database_writer_update_diagramelement_focused_feature_id ( (*this_).db_writer, diag_elem_id, diag_feature_id, NULL );
485 : }
486 5 : break;
487 :
488 2 : case CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_DIAGRAMELEMENT:
489 : {
490 2 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_DIAGRAMELEMENT" );
491 2 : const data_diagramelement_t *diag_ele = ctrl_undo_redo_entry_get_diagramelement_after_action_const ( action );
492 2 : if ( undo )
493 : {
494 1 : data_row_t obj_id = data_diagramelement_get_row_id ( diag_ele );
495 1 : result |= (u8_error_t) data_database_writer_delete_diagramelement ( (*this_).db_writer, obj_id, NULL );
496 : }
497 : else
498 : {
499 1 : result |= (u8_error_t) data_database_writer_create_diagramelement ( (*this_).db_writer, diag_ele, NULL );
500 : }
501 : }
502 2 : break;
503 :
504 0 : case CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_CLASSIFIER:
505 : {
506 0 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_CLASSIFIER" );
507 0 : const data_classifier_t *classfy = ctrl_undo_redo_entry_get_classifier_before_action_const ( action );
508 0 : if ( undo )
509 : {
510 0 : result |= (u8_error_t) data_database_writer_create_classifier ( (*this_).db_writer, classfy, NULL );
511 : }
512 : else
513 : {
514 0 : data_row_t obj_id = data_classifier_get_row_id ( classfy );
515 0 : result |= (u8_error_t) data_database_writer_delete_classifier ( (*this_).db_writer, obj_id, NULL );
516 : }
517 : }
518 0 : break;
519 :
520 2 : case CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_CLASSIFIER:
521 : {
522 2 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_CLASSIFIER" );
523 : const data_classifier_t *classfy;
524 2 : if ( undo )
525 : {
526 1 : classfy = ctrl_undo_redo_entry_get_classifier_before_action_const ( action );
527 : }
528 : else
529 : {
530 1 : classfy = ctrl_undo_redo_entry_get_classifier_after_action_const ( action );
531 : }
532 2 : data_row_t classfy_id = data_classifier_get_row_id ( classfy );
533 2 : data_classifier_type_t classfy_main_type = data_classifier_get_main_type ( classfy );
534 2 : const char* classfy_stereotype = data_classifier_get_stereotype_const ( classfy );
535 2 : const char* classfy_name = data_classifier_get_name_const ( classfy );
536 2 : const char* classfy_description = data_classifier_get_description_const ( classfy );
537 2 : int32_t classfy_x_order = data_classifier_get_x_order ( classfy );
538 2 : int32_t classfy_y_order = data_classifier_get_y_order ( classfy );
539 2 : int32_t classfy_list_order = data_classifier_get_list_order ( classfy );
540 2 : result |= (u8_error_t) data_database_writer_update_classifier_main_type ( (*this_).db_writer, classfy_id, classfy_main_type, NULL );
541 2 : result |= (u8_error_t) data_database_writer_update_classifier_stereotype ( (*this_).db_writer, classfy_id, classfy_stereotype, NULL );
542 2 : result |= (u8_error_t) data_database_writer_update_classifier_name ( (*this_).db_writer, classfy_id, classfy_name, NULL );
543 2 : result |= (u8_error_t) data_database_writer_update_classifier_description ( (*this_).db_writer, classfy_id, classfy_description, NULL );
544 2 : result |= (u8_error_t) data_database_writer_update_classifier_x_order ( (*this_).db_writer, classfy_id, classfy_x_order, NULL );
545 2 : result |= (u8_error_t) data_database_writer_update_classifier_y_order ( (*this_).db_writer, classfy_id, classfy_y_order, NULL );
546 2 : result |= (u8_error_t) data_database_writer_update_classifier_list_order ( (*this_).db_writer, classfy_id, classfy_list_order, NULL );
547 : }
548 2 : break;
549 :
550 2 : case CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_CLASSIFIER:
551 : {
552 2 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_CLASSIFIER" );
553 2 : const data_classifier_t *classfy = ctrl_undo_redo_entry_get_classifier_after_action_const ( action );
554 2 : if ( undo )
555 : {
556 1 : data_row_t obj_id = data_classifier_get_row_id ( classfy );
557 1 : result |= (u8_error_t) data_database_writer_delete_classifier ( (*this_).db_writer, obj_id, NULL );
558 : }
559 : else
560 : {
561 1 : result |= (u8_error_t) data_database_writer_create_classifier ( (*this_).db_writer, classfy, NULL );
562 : }
563 : }
564 2 : break;
565 :
566 3 : case CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_FEATURE:
567 : {
568 3 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_FEATURE" );
569 3 : const data_feature_t *feat = ctrl_undo_redo_entry_get_feature_before_action_const ( action );
570 3 : if ( undo )
571 : {
572 2 : result |= (u8_error_t) data_database_writer_create_feature ( (*this_).db_writer, feat, NULL );
573 : }
574 : else
575 : {
576 1 : data_row_t obj_id = data_feature_get_row_id ( feat );
577 1 : result |= (u8_error_t) data_database_writer_delete_feature ( (*this_).db_writer, obj_id, NULL );
578 : }
579 : }
580 3 : break;
581 :
582 4 : case CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_FEATURE:
583 : {
584 4 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_FEATURE" );
585 : const data_feature_t *feat;
586 4 : if ( undo )
587 : {
588 2 : feat = ctrl_undo_redo_entry_get_feature_before_action_const ( action );
589 : }
590 : else
591 : {
592 2 : feat = ctrl_undo_redo_entry_get_feature_after_action_const ( action );
593 : }
594 4 : data_row_t feature_id = data_feature_get_row_id ( feat );
595 4 : data_feature_type_t new_feature_type = data_feature_get_main_type ( feat );
596 4 : const char* new_feature_key = data_feature_get_key_const ( feat );
597 4 : const char* new_feature_value = data_feature_get_value_const ( feat );
598 4 : const char* new_feature_description = data_feature_get_description_const ( feat );
599 4 : int32_t new_feature_list_order = data_feature_get_list_order ( feat );
600 4 : result |= (u8_error_t) data_database_writer_update_feature_main_type ( (*this_).db_writer, feature_id, new_feature_type, NULL );
601 4 : result |= (u8_error_t) data_database_writer_update_feature_key ( (*this_).db_writer, feature_id, new_feature_key, NULL );
602 4 : result |= (u8_error_t) data_database_writer_update_feature_value ( (*this_).db_writer, feature_id, new_feature_value, NULL );
603 4 : result |= (u8_error_t) data_database_writer_update_feature_description ( (*this_).db_writer, feature_id, new_feature_description, NULL );
604 4 : result |= (u8_error_t) data_database_writer_update_feature_list_order ( (*this_).db_writer, feature_id, new_feature_list_order, NULL );
605 : }
606 4 : break;
607 :
608 2 : case CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_FEATURE:
609 : {
610 2 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_FEATURE" );
611 2 : const data_feature_t *feat = ctrl_undo_redo_entry_get_feature_after_action_const ( action );
612 2 : if ( undo )
613 : {
614 1 : data_row_t obj_id = data_feature_get_row_id ( feat );
615 1 : result |= (u8_error_t) data_database_writer_delete_feature ( (*this_).db_writer, obj_id, NULL );
616 : }
617 : else
618 : {
619 1 : result |= (u8_error_t) data_database_writer_create_feature ( (*this_).db_writer, feat, NULL );
620 : }
621 : }
622 2 : break;
623 :
624 2 : case CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_RELATIONSHIP:
625 : {
626 2 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_DELETE_RELATIONSHIP" );
627 2 : const data_relationship_t *relation = ctrl_undo_redo_entry_get_relationship_before_action_const ( action );
628 2 : if ( undo )
629 : {
630 1 : result |= (u8_error_t) data_database_writer_create_relationship ( (*this_).db_writer, relation, NULL );
631 : }
632 : else
633 : {
634 1 : data_row_t obj_id = data_relationship_get_row_id ( relation );
635 1 : result |= (u8_error_t) data_database_writer_delete_relationship ( (*this_).db_writer, obj_id, NULL );
636 : }
637 : }
638 2 : break;
639 :
640 2 : case CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_RELATIONSHIP:
641 : {
642 2 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_UPDATE_RELATIONSHIP" );
643 : const data_relationship_t *relation;
644 2 : if ( undo )
645 : {
646 1 : relation = ctrl_undo_redo_entry_get_relationship_before_action_const ( action );
647 : }
648 : else
649 : {
650 1 : relation = ctrl_undo_redo_entry_get_relationship_after_action_const ( action );
651 : }
652 2 : data_row_t relationship_id = data_relationship_get_row_id ( relation );
653 2 : data_relationship_type_t new_relationship_type = data_relationship_get_main_type ( relation );
654 2 : const char* new_relationship_stereotype = data_relationship_get_stereotype_const ( relation );
655 2 : const char* new_relationship_name = data_relationship_get_name_const ( relation );
656 2 : const char* new_relationship_description = data_relationship_get_description_const ( relation );
657 2 : int32_t new_relationship_list_order = data_relationship_get_list_order ( relation );
658 2 : result |= (u8_error_t) data_database_writer_update_relationship_main_type ( (*this_).db_writer, relationship_id, new_relationship_type, NULL );
659 2 : result |= (u8_error_t) data_database_writer_update_relationship_stereotype ( (*this_).db_writer, relationship_id, new_relationship_stereotype, NULL );
660 2 : result |= (u8_error_t) data_database_writer_update_relationship_name ( (*this_).db_writer, relationship_id, new_relationship_name, NULL );
661 2 : result |= (u8_error_t) data_database_writer_update_relationship_description ( (*this_).db_writer, relationship_id, new_relationship_description, NULL );
662 2 : result |= (u8_error_t) data_database_writer_update_relationship_list_order ( (*this_).db_writer, relationship_id, new_relationship_list_order, NULL );
663 : }
664 2 : break;
665 :
666 2 : case CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_RELATIONSHIP:
667 : {
668 2 : U8_TRACE_INFO( "CTRL_UNDO_REDO_ENTRY_TYPE_CREATE_RELATIONSHIP" );
669 2 : const data_relationship_t *relation = ctrl_undo_redo_entry_get_relationship_after_action_const ( action );
670 2 : if ( undo )
671 : {
672 1 : data_row_t obj_id = data_relationship_get_row_id ( relation );
673 1 : result |= (u8_error_t) data_database_writer_delete_relationship ( (*this_).db_writer, obj_id, NULL );
674 : }
675 : else
676 : {
677 1 : result |= (u8_error_t) data_database_writer_create_relationship ( (*this_).db_writer, relation, NULL );
678 : }
679 : }
680 2 : break;
681 :
682 0 : default:
683 : {
684 0 : U8_LOG_ERROR( "unexptected ctrl_undo_redo_entry_type_t" );
685 : }
686 : }
687 :
688 164 : U8_TRACE_END_ERR( result );
689 164 : return result;
690 : }
691 :
692 :
693 : /*
694 : Copyright 2016-2025 Andreas Warnke
695 :
696 : Licensed under the Apache License, Version 2.0 (the "License");
697 : you may not use this file except in compliance with the License.
698 : You may obtain a copy of the License at
699 :
700 : http://www.apache.org/licenses/LICENSE-2.0
701 :
702 : Unless required by applicable law or agreed to in writing, software
703 : distributed under the License is distributed on an "AS IS" BASIS,
704 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
705 : See the License for the specific language governing permissions and
706 : limitations under the License.
707 : */
|