LCOV - code coverage report
Current view: top level - ctrl/source - ctrl_undo_redo_list.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.63.2_covts Lines: 79.4 % 335 266
Test Date: 2025-05-01 10:10:14 Functions: 85.7 % 7 6

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

Generated by: LCOV version 2.0-1