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.67.0_covts Lines: 79.6 % 339 270
Test Date: 2025-11-06 17:22:08 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 :                 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              : */
        

Generated by: LCOV version 2.0-1