Line data Source code
1 : /* File: ctrl_multi_step_changer.c; Copyright and License: see below */
2 :
3 : #include "ctrl_multi_step_changer.h"
4 : #include "u8/u8_trace.h"
5 : #include "u8/u8_log.h"
6 : #include <assert.h>
7 :
8 21 : void ctrl_multi_step_changer_init ( ctrl_multi_step_changer_t *this_,
9 : ctrl_controller_t *controller,
10 : data_database_reader_t *db_reader )
11 : {
12 21 : U8_TRACE_BEGIN();
13 21 : assert( NULL != controller );
14 21 : assert( NULL != db_reader );
15 :
16 : /* init member attributes */
17 21 : (*this_).controller = controller;
18 21 : (*this_).db_reader = db_reader;
19 :
20 21 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_START_NEW;
21 :
22 21 : U8_TRACE_END();
23 21 : }
24 :
25 21 : void ctrl_multi_step_changer_destroy ( ctrl_multi_step_changer_t *this_ )
26 : {
27 21 : U8_TRACE_BEGIN();
28 21 : assert( NULL != (*this_).controller );
29 21 : assert( NULL != (*this_).db_reader );
30 :
31 : /* destroy member attributes */
32 21 : (*this_).controller = NULL;
33 21 : (*this_).db_reader = NULL;
34 :
35 21 : U8_TRACE_END();
36 21 : }
37 :
38 : /* ================================ delete sets of elements ================================ */
39 :
40 3 : u8_error_t ctrl_multi_step_changer_delete_set ( ctrl_multi_step_changer_t *this_,
41 : const data_small_set_t *objects,
42 : data_stat_t *io_stat )
43 : {
44 3 : U8_TRACE_BEGIN();
45 3 : assert ( NULL != io_stat );
46 3 : u8_error_t result = U8_ERROR_NONE;
47 :
48 3 : if ( data_small_set_is_empty( objects ) )
49 : {
50 0 : result = U8_ERROR_INPUT_EMPTY;
51 : }
52 : else
53 : {
54 : int index;
55 :
56 3 : ctrl_classifier_controller_t *const classifier_ctrl = ctrl_controller_get_classifier_control_ptr( (*this_).controller);
57 3 : ctrl_diagram_controller_t *const diagram_ctrl = ctrl_controller_get_diagram_control_ptr( (*this_).controller );
58 :
59 : /* STEP ZERO: Delete all objects that can be immediately deleted */
60 :
61 15 : for ( index = 0; index < data_small_set_get_count( objects ); index ++ )
62 : {
63 : data_id_t current_id;
64 12 : current_id = data_small_set_get_id( objects, index );
65 12 : switch ( data_id_get_table( ¤t_id ) )
66 : {
67 2 : case DATA_TABLE_CLASSIFIER:
68 : {
69 : /* see step two */
70 : }
71 2 : break;
72 :
73 3 : case DATA_TABLE_FEATURE:
74 : {
75 3 : result |= ctrl_classifier_controller_delete_feature ( classifier_ctrl,
76 : data_id_get_row_id( ¤t_id ),
77 : (*this_).is_first_step
78 : );
79 3 : if ( result == U8_ERROR_NONE )
80 : {
81 2 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
82 : }
83 : else
84 : {
85 1 : data_stat_inc_count( io_stat, DATA_STAT_TABLE_FEATURE, DATA_STAT_SERIES_ERROR );
86 : }
87 : }
88 3 : break;
89 :
90 3 : case DATA_TABLE_RELATIONSHIP:
91 : {
92 3 : result |= ctrl_classifier_controller_delete_relationship ( classifier_ctrl,
93 : data_id_get_row_id( ¤t_id ),
94 : (*this_).is_first_step
95 : );
96 3 : if ( result == U8_ERROR_NONE )
97 : {
98 2 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
99 : }
100 : else
101 : {
102 1 : data_stat_inc_count( io_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_ERROR );
103 : }
104 : }
105 3 : break;
106 :
107 2 : case DATA_TABLE_DIAGRAMELEMENT:
108 : {
109 : /* see step one */
110 : }
111 2 : break;
112 :
113 2 : case DATA_TABLE_DIAGRAM:
114 : {
115 : /* see step two */
116 : }
117 2 : break;
118 :
119 0 : default:
120 : {
121 0 : result |= U8_ERROR_VALUE_OUT_OF_RANGE;
122 : }
123 0 : break;
124 : }
125 : }
126 :
127 : /* STEP ONE: Delete all objects that can be deleted after relationships and features are gone */
128 :
129 15 : for ( index = 0; index < data_small_set_get_count( objects ); index ++ )
130 : {
131 : data_id_t current_id;
132 12 : current_id = data_small_set_get_id( objects, index );
133 12 : switch ( data_id_get_table( ¤t_id ) )
134 : {
135 2 : case DATA_TABLE_CLASSIFIER:
136 : {
137 : /* see step two */
138 : }
139 2 : break;
140 :
141 3 : case DATA_TABLE_FEATURE:
142 : {
143 : /* see step zero */
144 : }
145 3 : break;
146 :
147 3 : case DATA_TABLE_RELATIONSHIP:
148 : {
149 : /* see step zero */
150 : }
151 3 : break;
152 :
153 2 : case DATA_TABLE_DIAGRAMELEMENT:
154 : {
155 2 : result |= ctrl_diagram_controller_delete_diagramelement ( diagram_ctrl,
156 : data_id_get_row_id( ¤t_id ),
157 : (*this_).is_first_step
158 : );
159 2 : if ( result == U8_ERROR_NONE )
160 : {
161 1 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
162 : }
163 : else
164 : {
165 1 : data_stat_inc_count( io_stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_ERROR );
166 : }
167 : }
168 2 : break;
169 :
170 2 : case DATA_TABLE_DIAGRAM:
171 : {
172 : /* see step two */
173 : }
174 2 : break;
175 :
176 0 : default:
177 : {
178 : /* see step zero */
179 : }
180 0 : break;
181 : }
182 : }
183 :
184 : /* STEP TWO: Delete all objects that can be deleted after step one */
185 :
186 15 : for ( index = 0; index < data_small_set_get_count( objects ); index ++ )
187 : {
188 : data_id_t current_id;
189 12 : current_id = data_small_set_get_id( objects, index );
190 12 : switch ( data_id_get_table( ¤t_id ) )
191 : {
192 2 : case DATA_TABLE_CLASSIFIER:
193 : {
194 2 : result |= ctrl_classifier_controller_delete_classifier( classifier_ctrl,
195 : data_id_get_row_id( ¤t_id ),
196 : (*this_).is_first_step
197 : );
198 2 : if ( result == U8_ERROR_NONE )
199 : {
200 1 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
201 : }
202 : else
203 : {
204 1 : data_stat_inc_count( io_stat, DATA_STAT_TABLE_CLASSIFIER, DATA_STAT_SERIES_ERROR );
205 : }
206 : }
207 2 : break;
208 :
209 3 : case DATA_TABLE_FEATURE:
210 : {
211 : /* see step zero */
212 : }
213 3 : break;
214 :
215 3 : case DATA_TABLE_RELATIONSHIP:
216 : {
217 : /* see step zero */
218 : }
219 3 : break;
220 :
221 2 : case DATA_TABLE_DIAGRAMELEMENT:
222 : {
223 : /* see step one */
224 : }
225 2 : break;
226 :
227 2 : case DATA_TABLE_DIAGRAM:
228 : {
229 2 : result |= ctrl_diagram_controller_delete_diagram ( diagram_ctrl,
230 : data_id_get_row_id( ¤t_id ),
231 : (*this_).is_first_step
232 : );
233 2 : if ( result == U8_ERROR_NONE )
234 : {
235 1 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
236 : }
237 : else
238 : {
239 1 : data_stat_inc_count( io_stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_ERROR );
240 : }
241 : }
242 2 : break;
243 :
244 0 : default:
245 : {
246 : /* see step zero */
247 : }
248 0 : break;
249 : }
250 : }
251 :
252 : /* update statistics based on undo redo list */
253 3 : result |= ctrl_controller_get_statistics( (*this_).controller, io_stat );
254 : }
255 :
256 3 : U8_TRACE_END_ERR( result );
257 3 : return result;
258 : }
259 :
260 : /* ================================ create elements without duplicate ids ================================ */
261 :
262 6 : u8_error_t ctrl_multi_step_changer_create_diagram ( ctrl_multi_step_changer_t *this_,
263 : data_diagram_t *new_diagram,
264 : u8_error_t* out_info )
265 : {
266 6 : U8_TRACE_BEGIN();
267 6 : assert( NULL != new_diagram );
268 6 : assert( NULL != out_info );
269 6 : u8_error_t result = U8_ERROR_NONE;
270 :
271 : /* ensure that a uuid exists */
272 6 : if ( 0 == utf8string_get_length( data_diagram_get_uuid_const( new_diagram ) ) )
273 : {
274 : data_uuid_t new_uuid;
275 0 : data_uuid_init_new( &new_uuid );
276 0 : data_diagram_set_uuid( new_diagram, data_uuid_get_string( &new_uuid ) );
277 0 : data_uuid_destroy( &new_uuid );
278 : }
279 :
280 : ctrl_diagram_controller_t *const diagram_ctrl
281 6 : = ctrl_controller_get_diagram_control_ptr( (*this_).controller );
282 :
283 : data_row_id_t new_diagram_id;
284 : const u8_error_t create_err
285 6 : = ctrl_diagram_controller_create_diagram( diagram_ctrl,
286 : new_diagram,
287 : (*this_).is_first_step,
288 : &new_diagram_id
289 : );
290 6 : *out_info = create_err;
291 6 : if ( create_err == U8_ERROR_NONE )
292 : {
293 5 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
294 5 : data_diagram_set_row_id( new_diagram, new_diagram_id );
295 : }
296 1 : else if ( u8_error_contains( create_err, U8_ERROR_DUPLICATE ) )
297 : {
298 1 : data_diagram_set_row_id( new_diagram, DATA_ROW_ID_VOID );
299 : const u8_error_t alt_create_err
300 1 : = ctrl_diagram_controller_create_diagram( diagram_ctrl,
301 : new_diagram,
302 : (*this_).is_first_step,
303 : &new_diagram_id
304 : );
305 1 : if ( alt_create_err == U8_ERROR_NONE )
306 : {
307 1 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
308 1 : data_diagram_set_row_id( new_diagram, new_diagram_id );
309 1 : *out_info |= U8_ERROR_DUPLICATE_ID;
310 : }
311 : else
312 : {
313 0 : result = alt_create_err;
314 : }
315 : }
316 : else
317 : {
318 0 : result = create_err;
319 : }
320 :
321 6 : U8_TRACE_END_ERR( result );
322 6 : return result;
323 : }
324 :
325 16 : u8_error_t ctrl_multi_step_changer_create_diagramelement ( ctrl_multi_step_changer_t *this_,
326 : data_diagramelement_t *new_diagramelement,
327 : u8_error_t* out_info )
328 : {
329 16 : U8_TRACE_BEGIN();
330 16 : assert( NULL != new_diagramelement );
331 16 : assert( NULL != out_info );
332 16 : u8_error_t result = U8_ERROR_NONE;
333 :
334 : /* ensure that a uuid exists */
335 16 : if ( 0 == utf8string_get_length( data_diagramelement_get_uuid_const( new_diagramelement ) ) )
336 : {
337 : data_uuid_t new_uuid;
338 0 : data_uuid_init_new( &new_uuid );
339 0 : data_diagramelement_set_uuid( new_diagramelement, data_uuid_get_string( &new_uuid ) );
340 0 : data_uuid_destroy( &new_uuid );
341 : }
342 :
343 : ctrl_diagram_controller_t *const diagram_ctrl
344 16 : = ctrl_controller_get_diagram_control_ptr( (*this_).controller );
345 :
346 : data_row_id_t new_diagramelement_id;
347 : const u8_error_t create_err
348 16 : = ctrl_diagram_controller_create_diagramelement( diagram_ctrl,
349 : new_diagramelement,
350 : (*this_).is_first_step,
351 : &new_diagramelement_id
352 : );
353 16 : *out_info = create_err;
354 16 : if ( create_err == U8_ERROR_NONE )
355 : {
356 16 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
357 16 : data_diagramelement_set_row_id( new_diagramelement, new_diagramelement_id );
358 : }
359 0 : else if ( u8_error_contains( create_err, U8_ERROR_DUPLICATE ) )
360 : {
361 0 : data_diagramelement_set_row_id( new_diagramelement, DATA_ROW_ID_VOID );
362 : const u8_error_t alt_create_err
363 0 : = ctrl_diagram_controller_create_diagramelement( diagram_ctrl,
364 : new_diagramelement,
365 : (*this_).is_first_step,
366 : &new_diagramelement_id
367 : );
368 0 : if ( alt_create_err == U8_ERROR_NONE )
369 : {
370 0 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
371 0 : data_diagramelement_set_row_id( new_diagramelement, new_diagramelement_id );
372 0 : *out_info |= U8_ERROR_DUPLICATE_ID;
373 : }
374 : else
375 : {
376 0 : result = alt_create_err;
377 : }
378 : }
379 : else
380 : {
381 0 : result = create_err;
382 : }
383 :
384 16 : U8_TRACE_END_ERR( result );
385 16 : return result;
386 : }
387 :
388 13 : u8_error_t ctrl_multi_step_changer_create_classifier ( ctrl_multi_step_changer_t *this_,
389 : data_classifier_t *new_classifier,
390 : u8_error_t* out_info )
391 : {
392 13 : U8_TRACE_BEGIN();
393 13 : assert( NULL != new_classifier );
394 13 : assert( NULL != out_info );
395 13 : u8_error_t result = U8_ERROR_NONE;
396 :
397 : /* ensure that a uuid exists */
398 13 : if ( 0 == utf8string_get_length( data_classifier_get_uuid_const( new_classifier ) ) )
399 : {
400 : data_uuid_t new_uuid;
401 0 : data_uuid_init_new( &new_uuid );
402 0 : data_classifier_set_uuid( new_classifier, data_uuid_get_string( &new_uuid ) );
403 0 : data_uuid_destroy( &new_uuid );
404 : }
405 :
406 : ctrl_classifier_controller_t *const classifier_ctrl
407 13 : = ctrl_controller_get_classifier_control_ptr( (*this_).controller);
408 :
409 : data_row_id_t new_classifier_id;
410 : const u8_error_t create_err
411 13 : = ctrl_classifier_controller_create_classifier( classifier_ctrl,
412 : new_classifier,
413 : (*this_).is_first_step,
414 : &new_classifier_id
415 : );
416 13 : *out_info = create_err;
417 13 : if ( create_err == U8_ERROR_NONE )
418 : {
419 10 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
420 10 : data_classifier_set_row_id( new_classifier, new_classifier_id );
421 : }
422 3 : else if ( u8_error_contains( create_err, U8_ERROR_DUPLICATE ) )
423 : {
424 3 : data_classifier_set_row_id( new_classifier, DATA_ROW_ID_VOID );
425 : const u8_error_t alt_create_err
426 3 : = ctrl_classifier_controller_create_classifier( classifier_ctrl,
427 : new_classifier,
428 : (*this_).is_first_step,
429 : &new_classifier_id
430 : );
431 3 : if ( alt_create_err == U8_ERROR_NONE )
432 : {
433 0 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
434 0 : data_classifier_set_row_id( new_classifier, new_classifier_id );
435 0 : *out_info |= U8_ERROR_DUPLICATE_ID;
436 : }
437 : else
438 : {
439 3 : result = alt_create_err;
440 : }
441 : }
442 : else
443 : {
444 0 : result = create_err;
445 : }
446 :
447 13 : if ( u8_error_contains( result, U8_ERROR_DUPLICATE ) )
448 : {
449 3 : *out_info |= result;
450 3 : result = U8_ERROR_NONE;
451 :
452 : /* find an alternative, unused name */
453 : char wish_name_buf[DATA_CLASSIFIER_MAX_NAME_SIZE];
454 3 : utf8stringbuf_t wish_name = UTF8STRINGBUF( wish_name_buf );
455 3 : result |= utf8stringbuf_copy_str( wish_name, data_classifier_get_name_const( new_classifier ) ); /* error to be reported to caller */
456 : {
457 3 : bool name_ok = false;
458 : static const uint_fast16_t MAX_SEARCH_STEP = 10000;
459 : static const uint_fast16_t FIRST_STEP = 2;
460 7 : for ( uint_fast16_t search_step = FIRST_STEP; ( search_step < MAX_SEARCH_STEP )&&( ! name_ok )&&( result == U8_ERROR_NONE ); search_step ++ )
461 : {
462 : char new_name_buf[DATA_CLASSIFIER_MAX_NAME_SIZE];
463 4 : utf8stringbuf_t new_name = UTF8STRINGBUF( new_name_buf );
464 : const u8_error_t trunc_err
465 4 : = ctrl_multi_step_changer_private_propose_classifier_name( this_,
466 4 : utf8stringbuf_get_string( wish_name ),
467 : search_step,
468 : new_name
469 : );
470 4 : if ( trunc_err != U8_ERROR_NONE )
471 : {
472 0 : U8_TRACE_INFO_STR("Name truncated at search for alternative:", utf8stringbuf_get_string( new_name ) );
473 : }
474 4 : data_classifier_set_name( new_classifier, utf8stringbuf_get_string( new_name ) );
475 : const u8_error_t retry_err
476 4 : = ctrl_classifier_controller_create_classifier( classifier_ctrl,
477 : new_classifier,
478 : (*this_).is_first_step,
479 : &new_classifier_id
480 : );
481 4 : if ( u8_error_contains( retry_err, U8_ERROR_DUPLICATE ) )
482 : {
483 1 : *out_info |= retry_err;
484 : }
485 3 : else if ( retry_err == U8_ERROR_NONE )
486 : {
487 3 : name_ok = true; /* name unused */
488 3 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
489 3 : data_classifier_set_row_id( new_classifier, new_classifier_id );
490 3 : *out_info |= U8_ERROR_DUPLICATE_NAME;
491 : }
492 : else
493 : {
494 0 : result |= retry_err;
495 : }
496 : }
497 : }
498 : }
499 :
500 13 : U8_TRACE_END_ERR( result );
501 13 : return result;
502 : }
503 :
504 9 : u8_error_t ctrl_multi_step_changer_create_feature ( ctrl_multi_step_changer_t *this_,
505 : data_feature_t *new_feature,
506 : u8_error_t* out_info )
507 : {
508 9 : U8_TRACE_BEGIN();
509 9 : assert( NULL != new_feature );
510 9 : assert( NULL != out_info );
511 9 : u8_error_t result = U8_ERROR_NONE;
512 :
513 : /* ensure that a uuid exists */
514 9 : if ( 0 == utf8string_get_length( data_feature_get_uuid_const( new_feature ) ) )
515 : {
516 : data_uuid_t new_uuid;
517 0 : data_uuid_init_new( &new_uuid );
518 0 : data_feature_set_uuid( new_feature, data_uuid_get_string( &new_uuid ) );
519 0 : data_uuid_destroy( &new_uuid );
520 : }
521 :
522 : ctrl_classifier_controller_t *const classifier_ctrl
523 9 : = ctrl_controller_get_classifier_control_ptr( (*this_).controller);
524 :
525 : data_row_id_t new_feature_id;
526 : const u8_error_t create_err
527 9 : = ctrl_classifier_controller_create_feature( classifier_ctrl,
528 : new_feature,
529 : (*this_).is_first_step,
530 : &new_feature_id
531 : );
532 9 : *out_info = create_err;
533 9 : if ( create_err == U8_ERROR_NONE )
534 : {
535 8 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
536 8 : data_feature_set_row_id( new_feature, new_feature_id );
537 : }
538 1 : else if ( u8_error_contains( create_err, U8_ERROR_DUPLICATE) )
539 : {
540 1 : data_feature_set_row_id( new_feature, DATA_ROW_ID_VOID );
541 : const u8_error_t alt_create_err
542 1 : = ctrl_classifier_controller_create_feature( classifier_ctrl,
543 : new_feature,
544 : (*this_).is_first_step,
545 : &new_feature_id
546 : );
547 1 : if ( alt_create_err == U8_ERROR_NONE )
548 : {
549 1 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
550 1 : data_feature_set_row_id( new_feature, new_feature_id );
551 1 : *out_info |= U8_ERROR_DUPLICATE_ID;
552 : }
553 : else
554 : {
555 0 : result = alt_create_err;
556 : }
557 : }
558 : else
559 : {
560 0 : result = create_err;
561 : }
562 :
563 9 : U8_TRACE_END_ERR( result );
564 9 : return result;
565 : }
566 :
567 7 : u8_error_t ctrl_multi_step_changer_create_relationship ( ctrl_multi_step_changer_t *this_,
568 : data_relationship_t *new_relationship,
569 : u8_error_t* out_info )
570 : {
571 7 : U8_TRACE_BEGIN();
572 7 : assert( NULL != new_relationship );
573 7 : assert( NULL != out_info );
574 7 : u8_error_t result = U8_ERROR_NONE;
575 :
576 : /* ensure that a uuid exists */
577 7 : if ( 0 == utf8string_get_length( data_relationship_get_uuid_const( new_relationship ) ) )
578 : {
579 : data_uuid_t new_uuid;
580 0 : data_uuid_init_new( &new_uuid );
581 0 : data_relationship_set_uuid( new_relationship, data_uuid_get_string( &new_uuid ) );
582 0 : data_uuid_destroy( &new_uuid );
583 : }
584 :
585 : ctrl_classifier_controller_t *const classifier_ctrl
586 7 : = ctrl_controller_get_classifier_control_ptr( (*this_).controller);
587 :
588 : data_row_id_t new_relationship_id;
589 : const u8_error_t create_err
590 7 : = ctrl_classifier_controller_create_relationship( classifier_ctrl,
591 : new_relationship,
592 : (*this_).is_first_step,
593 : &new_relationship_id
594 : );
595 7 : *out_info = create_err;
596 7 : if ( create_err == U8_ERROR_NONE )
597 : {
598 5 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
599 5 : data_relationship_set_row_id( new_relationship, new_relationship_id );
600 : }
601 2 : else if ( u8_error_contains( create_err, U8_ERROR_DUPLICATE) )
602 : {
603 2 : data_relationship_set_row_id( new_relationship, DATA_ROW_ID_VOID );
604 : const u8_error_t alt_create_err
605 2 : = ctrl_classifier_controller_create_relationship( classifier_ctrl,
606 : new_relationship,
607 : (*this_).is_first_step,
608 : &new_relationship_id
609 : );
610 2 : if ( alt_create_err == U8_ERROR_NONE )
611 : {
612 2 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
613 2 : data_relationship_set_row_id( new_relationship, new_relationship_id );
614 2 : *out_info |= U8_ERROR_DUPLICATE_ID;
615 : }
616 : else
617 : {
618 0 : result = alt_create_err;
619 : }
620 : }
621 : else
622 : {
623 0 : result = create_err;
624 : }
625 :
626 7 : U8_TRACE_END_ERR( result );
627 7 : return result;
628 : }
629 :
630 : /* ================================ update links of existing elements ================================ */
631 :
632 0 : u8_error_t ctrl_multi_step_changer_update_diagram_parent_id ( ctrl_multi_step_changer_t *this_,
633 : data_row_id_t diagram_id,
634 : data_row_id_t new_diagram_parent_id )
635 : {
636 0 : U8_TRACE_BEGIN();
637 0 : u8_error_t result = U8_ERROR_NONE;
638 :
639 : ctrl_diagram_controller_t *const diagram_ctrl
640 0 : = ctrl_controller_get_diagram_control_ptr( (*this_).controller );
641 :
642 0 : result = ctrl_diagram_controller_update_diagram_parent_id( diagram_ctrl,
643 : diagram_id,
644 : new_diagram_parent_id,
645 : (*this_).is_first_step
646 : );
647 0 : if ( result == U8_ERROR_NONE )
648 : {
649 0 : (*this_).is_first_step = CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND;
650 : }
651 :
652 0 : U8_TRACE_END_ERR( result );
653 0 : return result;
654 : }
655 :
656 : /* ================================ propose names of classifiers ================================ */
657 :
658 4 : u8_error_t ctrl_multi_step_changer_private_propose_classifier_name ( ctrl_multi_step_changer_t *this_,
659 : const char* base_classifier_name,
660 : uint_fast16_t iteration,
661 : utf8stringbuf_t out_name )
662 : {
663 4 : U8_TRACE_BEGIN();
664 4 : const size_t RESERVED_FOR_NUMBER = 5;
665 4 : assert( NULL != base_classifier_name );
666 4 : assert( utf8stringbuf_get_size(out_name) > RESERVED_FOR_NUMBER );
667 4 : u8_error_t result = U8_ERROR_NONE;
668 :
669 : /* find an alternative, unused name */
670 : /* copy the base_classifier_name to newname_buf */
671 : {
672 : utf8stringbuf_t shortened_new_name
673 4 : = utf8stringbuf_init( utf8stringbuf_get_size(out_name)-RESERVED_FOR_NUMBER, utf8stringbuf_get_string(out_name) );
674 4 : result |= utf8stringbuf_copy_str( shortened_new_name, base_classifier_name );
675 : /* null termination is guaranteed, also this function does not cut an utf8 code point in the middle. */
676 : }
677 : /* append a separator and the iteration number */
678 4 : result |= utf8stringbuf_append_str( out_name, "-" );
679 4 : result |= utf8stringbuf_append_int( out_name, iteration );
680 :
681 4 : U8_TRACE_END_ERR( result );
682 4 : return result;
683 : }
684 :
685 :
686 : /*
687 : Copyright 2016-2024 Andreas Warnke
688 :
689 : Licensed under the Apache License, Version 2.0 (the "License");
690 : you may not use this file except in compliance with the License.
691 : You may obtain a copy of the License at
692 :
693 : http://www.apache.org/licenses/LICENSE-2.0
694 :
695 : Unless required by applicable law or agreed to in writing, software
696 : distributed under the License is distributed on an "AS IS" BASIS,
697 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
698 : See the License for the specific language governing permissions and
699 : limitations under the License.
700 : */
|