LCOV - code coverage report
Current view: top level - ctrl/source - ctrl_undo_redo_list.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.61.0_covts Lines: 266 335 79.4 %
Date: 2024-10-26 21:44:38 Functions: 6 7 85.7 %

          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_id_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_id_t diag_id = data_diagram_get_row_id ( diag );
     418           4 :             data_row_id_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_id_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_id_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_id_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_id_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_id_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_id_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_id_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_id_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_id_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_id_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_id_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_id_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_id_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_id_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-2024 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 1.16