LCOV - code coverage report
Current view: top level - gui/source/attributes - gui_attributes_editor.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.70.5_covts Lines: 0.0 % 883 0
Test Date: 2026-05-28 21:31:40 Functions: 0.0 % 27 0

            Line data    Source code
       1              : /* File: gui_attributes_editor.c; Copyright and License: see below */
       2              : 
       3              : #include "gui_attributes_editor.h"
       4              : #include "gui_attribute_type_of_classifier.h"
       5              : #include "gui_attribute_type_of_diagram.h"
       6              : #include "gui_attribute_type_of_feature.h"
       7              : #include "gui_attribute_type_of_relationship.h"
       8              : #include "draw/draw_stereotype_icon.h"
       9              : #include "u8/u8_trace.h"
      10              : #include "ctrl_simple_changer.h"
      11              : #include "entity/data_table.h"
      12              : #include "entity/data_id.h"
      13              : #include "utf8stringbuf/utf8string.h"
      14              : #include "gui_gtk.h"
      15              : #include <stdbool.h>
      16              : 
      17            0 : void gui_attributes_editor_init ( gui_attributes_editor_t *this_,
      18              :                                   GtkLabel *id_label,
      19              :                                   GtkEntry *name_entry,
      20              :                                   GtkEntry *stereotype_entry,
      21              :                                   GtkDropDown *type_dropdown,
      22              :                                   GtkWidget *type_diag_grid,
      23              :                                   GtkWidget *type_clas_grid,
      24              :                                   GtkWidget *type_feat_grid,
      25              :                                   GtkWidget *type_rel_grid,
      26              :                                   GtkTextView *description_text_view,
      27              :                                   GtkButton *commit_button,
      28              :                                   const gui_resources_t *resources,
      29              :                                   ctrl_controller_t *controller,
      30              :                                   data_database_reader_t *db_reader,
      31              :                                   data_database_t *database,
      32              :                                   gui_simple_message_to_user_t *message_to_user )
      33              : {
      34            0 :     U8_TRACE_BEGIN();
      35            0 :     assert( NULL != id_label );
      36            0 :     assert( NULL != name_entry );
      37            0 :     assert( NULL != stereotype_entry );
      38            0 :     assert( NULL != type_dropdown );
      39            0 :     assert( NULL != type_diag_grid );
      40            0 :     assert( NULL != type_clas_grid );
      41            0 :     assert( NULL != type_feat_grid );
      42            0 :     assert( NULL != type_rel_grid );
      43            0 :     assert( NULL != description_text_view );
      44            0 :     assert( NULL != commit_button );
      45              : 
      46            0 :     assert( NULL != resources );
      47            0 :     assert( NULL != controller );
      48            0 :     assert( NULL != db_reader );
      49            0 :     assert( NULL != message_to_user );
      50              : 
      51            0 :     (*this_).id_label = id_label;
      52            0 :     (*this_).name_entry = name_entry;
      53            0 :     (*this_).stereotype_entry = stereotype_entry;
      54            0 :     (*this_).type_dropdown = type_dropdown;
      55            0 :     (*this_).type_diag_grid = type_diag_grid;
      56            0 :     (*this_).type_clas_grid = type_clas_grid;
      57            0 :     (*this_).type_feat_grid = type_feat_grid;
      58            0 :     (*this_).type_rel_grid = type_rel_grid;
      59            0 :     (*this_).description_text_view = description_text_view;
      60            0 :     (*this_).commit_button = commit_button;
      61              : 
      62            0 :     (*this_).db_reader = db_reader;
      63            0 :     (*this_).controller = controller;
      64            0 :     (*this_).database = database;
      65            0 :     (*this_).message_to_user = message_to_user;
      66            0 :     (*this_).sync_dir = GUI_ATTRIBUTES_EDITOR_SYNC_DIR_DB_TO_GUI;
      67            0 :     data_id_init_void( &((*this_).latest_created_id) );
      68            0 :     data_id_init_void( &((*this_).second_latest_id) );
      69            0 :     data_diagram_init_empty( &((*this_).private_diagram_cache) );
      70            0 :     data_classifier_init_empty( &((*this_).private_classifier_cache) );
      71            0 :     data_feature_init_empty( &((*this_).private_feature_cache) );
      72            0 :     data_relationship_init_empty( &((*this_).private_relationship_cache) );
      73            0 :     data_id_init_void( &((*this_).selected_object_id) );
      74              : 
      75            0 :     gui_type_resource_list_init( &((*this_).type_lists), resources );
      76            0 :     (*this_).temp_search_me = GUI_TYPE_RESOURCE( g_object_new( gui_type_resource_get_type(), NULL ) );
      77            0 :     (*this_).previous_selected_object_id = DATA_ID_VOID;
      78              : 
      79              :     /* update widgets */
      80            0 :     gui_attributes_editor_update_widgets( this_ );
      81              : 
      82            0 :     U8_TRACE_END();
      83            0 : }
      84              : 
      85            0 : void gui_attributes_editor_destroy ( gui_attributes_editor_t *this_ )
      86              : {
      87            0 :     U8_TRACE_BEGIN();
      88              : 
      89            0 :     data_id_destroy( &((*this_).selected_object_id) );
      90            0 :     data_diagram_destroy( &((*this_).private_diagram_cache) );
      91            0 :     data_classifier_destroy( &((*this_).private_classifier_cache) );
      92            0 :     data_feature_destroy( &((*this_).private_feature_cache) );
      93            0 :     data_relationship_destroy( &((*this_).private_relationship_cache) );
      94            0 :     data_id_destroy( &((*this_).second_latest_id) );
      95            0 :     data_id_destroy( &((*this_).latest_created_id) );
      96              : 
      97            0 :     g_object_unref( (*this_).temp_search_me );
      98            0 :     gui_type_resource_list_destroy( &((*this_).type_lists) );
      99              : 
     100            0 :     (*this_).db_reader = NULL;
     101            0 :     (*this_).controller = NULL;
     102            0 :     (*this_).message_to_user = NULL;
     103              : 
     104            0 :     (*this_).id_label = NULL;
     105            0 :     (*this_).name_entry = NULL;
     106            0 :     (*this_).stereotype_entry = NULL;
     107            0 :     (*this_).type_dropdown = NULL;
     108            0 :     (*this_).type_diag_grid = NULL;
     109            0 :     (*this_).type_clas_grid = NULL;
     110            0 :     (*this_).type_feat_grid = NULL;
     111            0 :     (*this_).type_rel_grid = NULL;
     112            0 :     (*this_).description_text_view = NULL;
     113              : 
     114            0 :     U8_TRACE_END();
     115            0 : }
     116              : 
     117            0 : void gui_attributes_editor_update_widgets ( gui_attributes_editor_t *this_ )
     118              : {
     119            0 :     U8_TRACE_BEGIN();
     120              : 
     121            0 :     if ( (*this_).sync_dir == GUI_ATTRIBUTES_EDITOR_SYNC_DIR_DB_TO_GUI )
     122              :     {
     123            0 :         gui_attributes_editor_private_id_update_view( this_ );
     124            0 :         gui_attributes_editor_private_name_update_view ( this_ );
     125            0 :         gui_attributes_editor_private_stereotype_update_view( this_ );
     126            0 :         gui_attributes_editor_private_description_update_view( this_ );
     127            0 :         gui_attributes_editor_private_type_update_view( this_ );
     128              :     }
     129              :     else
     130              :     {
     131              :         /* widgets are not updated in GUI TO DB mode */
     132            0 :         U8_LOG_WARNING( "gui_attributes_editor_update_widgets called in GUI_ATTRIBUTES_EDITOR_SYNC_DIR_GUI_TO_DB mode!" );
     133              :     }
     134              : 
     135            0 :     U8_TRACE_END();
     136            0 : }
     137              : 
     138            0 : void gui_attributes_editor_commit_changes ( gui_attributes_editor_t *this_ )
     139              : {
     140            0 :     U8_TRACE_BEGIN();
     141              : 
     142            0 :     const gui_attributes_editor_sync_dir_t original_dir = (*this_).sync_dir;
     143            0 :     if ( (*this_).sync_dir == GUI_ATTRIBUTES_EDITOR_SYNC_DIR_DB_TO_GUI )
     144              :     {
     145            0 :         U8_LOG_EVENT( "gui_attributes_editor entering state GUI_ATTRIBUTES_EDITOR_SYNC_DIR_GUI_TO_DB." );
     146            0 :         (*this_).sync_dir = GUI_ATTRIBUTES_EDITOR_SYNC_DIR_GUI_TO_DB;
     147              :     }
     148              : 
     149            0 :     gui_attributes_editor_private_name_commit_changes ( this_ );
     150            0 :     gui_attributes_editor_private_stereotype_commit_changes ( this_ );
     151            0 :     gui_attributes_editor_private_description_commit_changes ( this_ );
     152              : 
     153            0 :     if ( original_dir == GUI_ATTRIBUTES_EDITOR_SYNC_DIR_DB_TO_GUI )
     154              :     {
     155            0 :         U8_LOG_EVENT( "gui_attributes_editor leaving state GUI_ATTRIBUTES_EDITOR_SYNC_DIR_GUI_TO_DB." );
     156            0 :         (*this_).sync_dir = GUI_ATTRIBUTES_EDITOR_SYNC_DIR_DB_TO_GUI;
     157            0 :         gui_attributes_editor_private_load_object( this_, (*this_).selected_object_id );
     158            0 :         gui_attributes_editor_update_widgets( this_ );
     159              :     }
     160              : 
     161            0 :     U8_TRACE_END();
     162            0 : }
     163              : 
     164            0 : void gui_attributes_editor_trace ( const gui_attributes_editor_t *this_ )
     165              : {
     166            0 :     U8_TRACE_BEGIN();
     167              : 
     168            0 :     U8_TRACE_INFO( "gui_attributes_editor_t" );
     169            0 :     U8_TRACE_INFO( "- selected_object_id:" );
     170            0 :     data_id_trace( &((*this_).selected_object_id) );
     171              : 
     172            0 :     switch ( data_id_get_table( &((*this_).selected_object_id ) ) )
     173              :     {
     174            0 :         case DATA_TABLE_VOID:
     175              :         {
     176            0 :             U8_TRACE_INFO( "- cached object: none" );
     177              :         }
     178            0 :         break;
     179              : 
     180            0 :         case DATA_TABLE_CLASSIFIER:
     181              :         {
     182            0 :             U8_TRACE_INFO( "- cached object:" );
     183            0 :             data_classifier_trace( &((*this_).private_classifier_cache) );
     184              :         }
     185            0 :         break;
     186              : 
     187            0 :         case DATA_TABLE_FEATURE:
     188              :         {
     189            0 :             U8_TRACE_INFO( "- cached object:" );
     190            0 :             data_feature_trace( &((*this_).private_feature_cache) );
     191              :         }
     192            0 :         break;
     193              : 
     194            0 :         case DATA_TABLE_RELATIONSHIP:
     195              :         {
     196            0 :             U8_TRACE_INFO( "- cached object:" );
     197            0 :             data_relationship_trace( &((*this_).private_relationship_cache) );
     198              :         }
     199            0 :         break;
     200              : 
     201            0 :         case DATA_TABLE_DIAGRAMELEMENT:
     202              :         {
     203            0 :             U8_TRACE_INFO( "- cached object: ANOMALY, UNEXPECTED VALUE OF data_table_t" );
     204              :         }
     205            0 :         break;
     206              : 
     207            0 :         case DATA_TABLE_DIAGRAM:
     208              :         {
     209            0 :             U8_TRACE_INFO( "- cached object:" );
     210            0 :             data_diagram_trace( &((*this_).private_diagram_cache) );
     211              :         }
     212            0 :         break;
     213              : 
     214            0 :         default:
     215              :         {
     216            0 :             U8_TRACE_INFO( "- cached object: ERROR, ILLEGAL ENUM VALUE OF data_table_t" );
     217              :         }
     218            0 :         break;
     219              :     }
     220              : 
     221              :     /* id: */
     222              :     if ( U8_TRACE_ACTIVE )
     223              :     {
     224              :         GtkLabel *id_widget;
     225              :         const char* text;
     226            0 :         id_widget = GTK_LABEL( (*this_).id_label );
     227            0 :         text = gtk_label_get_text( id_widget );
     228              : 
     229            0 :         U8_TRACE_INFO_STR( "- visible id:", text );
     230              :     }
     231              : 
     232              :     /* name: */
     233              :     if ( U8_TRACE_ACTIVE )
     234              :     {
     235              :         const char* text;
     236            0 :         GtkEntry *const name_widget = GTK_ENTRY( (*this_).name_entry );
     237            0 :         GtkEntryBuffer *const name_buf = gtk_entry_get_buffer( name_widget );
     238            0 :         text = gtk_entry_buffer_get_text( name_buf );
     239            0 :         U8_TRACE_INFO_STR( "- visible name:", text );
     240              :     }
     241              : 
     242              :     /* stereotype: */
     243              :     if ( U8_TRACE_ACTIVE )
     244              :     {
     245              :         const char* text;
     246            0 :         GtkEntry *const stereotype_widget = GTK_ENTRY( (*this_).stereotype_entry );
     247            0 :         GtkEntryBuffer *const stereotype_buf = gtk_entry_get_buffer( stereotype_widget );
     248            0 :         text = gtk_entry_buffer_get_text( stereotype_buf );
     249            0 :         U8_TRACE_INFO_STR( "- visible stereotype:", text );
     250              :     }
     251              : 
     252              :     /* type: */
     253              :     if ( U8_TRACE_ACTIVE )
     254              :     {
     255              :         int obj_type;
     256            0 :         GObject *selected = gtk_drop_down_get_selected_item ( (*this_).type_dropdown );
     257            0 :         if ( selected == NULL )
     258              :         {
     259            0 :             obj_type = -1;
     260              :         }
     261              :         else
     262              :         {
     263            0 :             const data_type_t *obj_full_type = gui_type_resource_get_type_id( ((GuiTypeResource*)selected) );
     264            0 :             obj_type = data_type_get_type_as_int( obj_full_type );
     265              :         }
     266            0 :         U8_TRACE_INFO_INT( "- visible type id:", obj_type );
     267              :     }
     268              : 
     269              :     /* description: */
     270              :     if ( U8_TRACE_ACTIVE )
     271              :     {
     272              :         GtkTextView *description_widget;
     273              :         GtkTextBuffer *buffer;
     274            0 :         description_widget = GTK_TEXT_VIEW( (*this_).description_text_view );
     275            0 :         buffer = gtk_text_view_get_buffer ( description_widget );
     276              :         GtkTextIter start;
     277              :         GtkTextIter end;
     278            0 :         gtk_text_buffer_get_start_iter ( buffer, &start );
     279            0 :         gtk_text_buffer_get_end_iter ( buffer, &end );
     280              :         const char* text;
     281            0 :         text = gtk_text_buffer_get_text ( buffer, &start, &end, false );
     282            0 :         U8_TRACE_INFO_STR( "- visible description:", text );
     283              :     }
     284              : 
     285            0 :     U8_TRACE_INFO_STR( "- sync mode:", ((*this_).sync_dir==GUI_ATTRIBUTES_EDITOR_SYNC_DIR_DB_TO_GUI)?"db-2-gui":"GUI_TO_DB" );
     286              : 
     287            0 :     U8_TRACE_END();
     288            0 : }
     289              : 
     290              : /* ================================ USER INPUT CALLBACKS ================================ */
     291              : 
     292            0 : void gui_attributes_editor_name_focus_left_callback( GtkEventControllerFocus* self, gpointer user_data )
     293              : {
     294            0 :     U8_TRACE_BEGIN();
     295            0 :     assert( user_data != NULL );
     296            0 :     gui_attributes_editor_t *const this_ = (gui_attributes_editor_t*) user_data;
     297            0 :     assert( gtk_event_controller_get_widget( GTK_EVENT_CONTROLLER(self) ) == GTK_WIDGET( (*this_).name_entry ) );
     298              : 
     299              :     //gui_attributes_editor_private_name_commit_changes( this_ );
     300            0 :     gui_attributes_editor_commit_changes( this_ );
     301              : 
     302            0 :     U8_TRACE_TIMESTAMP();
     303            0 :     U8_TRACE_END();
     304            0 : }
     305              : 
     306            0 : void gui_attributes_editor_name_enter_callback ( GtkEntry *widget, gpointer user_data )
     307              : {
     308            0 :     U8_TRACE_BEGIN();
     309            0 :     assert( user_data != NULL );
     310            0 :     gui_attributes_editor_t *const this_ = (gui_attributes_editor_t*) user_data;
     311            0 :     assert( GTK_ENTRY( widget ) == GTK_ENTRY( (*this_).name_entry ) );
     312              : 
     313              :     //gui_attributes_editor_private_name_commit_changes( this_ );
     314            0 :     gui_attributes_editor_commit_changes ( this_ );
     315              : 
     316            0 :     U8_TRACE_TIMESTAMP();
     317            0 :     U8_TRACE_END();
     318            0 : }
     319              : 
     320            0 : void gui_attributes_editor_stereotype_focus_left_callback( GtkEventControllerFocus* self, gpointer user_data )
     321              : {
     322            0 :     U8_TRACE_BEGIN();
     323            0 :     assert( user_data != NULL );
     324            0 :     gui_attributes_editor_t *const this_ = (gui_attributes_editor_t*) user_data;
     325            0 :     assert( gtk_event_controller_get_widget( GTK_EVENT_CONTROLLER(self) ) == GTK_WIDGET( (*this_).stereotype_entry ) );
     326              : 
     327              :     //gui_attributes_editor_private_stereotype_commit_changes( this_ );
     328            0 :     gui_attributes_editor_commit_changes( this_ );
     329              : 
     330            0 :     U8_TRACE_TIMESTAMP();
     331            0 :     U8_TRACE_END();
     332            0 : }
     333              : 
     334            0 : void gui_attributes_editor_stereotype_enter_callback ( GtkEntry *widget, gpointer user_data )
     335              : {
     336            0 :     U8_TRACE_BEGIN();
     337            0 :     assert( user_data != NULL );
     338            0 :     gui_attributes_editor_t *const this_ = (gui_attributes_editor_t*) user_data;
     339            0 :     assert( GTK_ENTRY(widget) == GTK_ENTRY( (*this_).stereotype_entry ) );
     340              : 
     341              :     //gui_attributes_editor_private_stereotype_commit_changes( this_ );
     342            0 :     gui_attributes_editor_commit_changes ( this_ );
     343              : 
     344            0 :     U8_TRACE_TIMESTAMP();
     345            0 :     U8_TRACE_END();
     346            0 : }
     347              : 
     348            0 : void gui_attributes_editor_type_changed_callback ( GObject* self, GParamSpec* pspec, gpointer user_data )
     349              : {
     350            0 :     U8_TRACE_BEGIN();
     351              :     gui_attributes_editor_t *this_;
     352            0 :     this_ = (gui_attributes_editor_t*) user_data;
     353            0 :     assert ( NULL != this_ );
     354            0 :     assert ( GTK_DROP_DOWN( self ) == (*this_).type_dropdown );
     355              : 
     356              :     /* if the selected object has changed, this callback is triggered by that change, */
     357              :     /* not by the user selecting another type */
     358            0 :     bool user_requested = data_id_equals( &((*this_).previous_selected_object_id), &((*this_).selected_object_id) );
     359            0 :     (*this_).previous_selected_object_id = (*this_).selected_object_id;
     360              : 
     361              :     /* get type id from widget */
     362            0 :     GObject *selected = gtk_drop_down_get_selected_item ( (*this_).type_dropdown );
     363            0 :     if (( selected != NULL )&& user_requested )
     364              :     {
     365              :         const data_type_t *const obj_full_type
     366            0 :             = gui_type_resource_get_type_id( ((GuiTypeResource*)selected) );
     367            0 :         const int obj_type = data_type_get_type_as_int( obj_full_type );
     368            0 :         U8_TRACE_INFO_INT( "selected type_id:", obj_type );
     369              : 
     370              :         /* commit possibly changed texts before causing update events */
     371            0 :         gui_attributes_editor_commit_changes( this_ );
     372              : 
     373            0 :         gui_attributes_editor_private_type_commit_changes( this_, obj_type );
     374              :     }
     375              : 
     376            0 :     U8_TRACE_TIMESTAMP();
     377            0 :     U8_TRACE_END();
     378            0 : }
     379              : 
     380            0 : void gui_attributes_editor_type_of_diagram_btn_callback( GtkWidget* button, gpointer data )
     381              : {
     382            0 :     U8_TRACE_BEGIN();
     383            0 :     const gui_attribute_type_of_diagram_t *const btn_data = (gui_attribute_type_of_diagram_t*) data;
     384            0 :     assert ( NULL != btn_data );
     385            0 :     gui_attributes_editor_t *const this_ = gui_attribute_type_of_diagram_get_editor( btn_data );
     386            0 :     assert ( NULL != this_ );
     387            0 :     const data_diagram_type_t selected_type = gui_attribute_type_of_diagram_get_selected_type( btn_data );
     388            0 :     U8_TRACE_INFO_INT( "selected type:", selected_type );
     389              : 
     390              :     /* commit possibly changed texts before causing update events */
     391            0 :     gui_attributes_editor_commit_changes( this_ );
     392              : 
     393            0 :     gui_attributes_editor_private_type_commit_changes ( this_, selected_type );
     394              : 
     395            0 :     U8_TRACE_TIMESTAMP();
     396            0 :     U8_TRACE_END();
     397            0 : }
     398              : 
     399            0 : void gui_attributes_editor_type_of_classifier_btn_callback( GtkWidget* button, gpointer data )
     400              : {
     401            0 :     U8_TRACE_BEGIN();
     402            0 :     const gui_attribute_type_of_classifier_t *const btn_data = (gui_attribute_type_of_classifier_t*) data;
     403            0 :     assert ( NULL != btn_data );
     404            0 :     gui_attributes_editor_t *const this_ = gui_attribute_type_of_classifier_get_editor( btn_data );
     405            0 :     assert ( NULL != this_ );
     406            0 :     const data_diagram_type_t selected_type = gui_attribute_type_of_classifier_get_selected_type( btn_data );
     407            0 :     U8_TRACE_INFO_INT( "selected type:", selected_type );
     408              : 
     409              :     /* commit possibly changed texts before causing update events */
     410            0 :     gui_attributes_editor_commit_changes( this_ );
     411              : 
     412            0 :     gui_attributes_editor_private_type_commit_changes ( this_, selected_type );
     413              : 
     414            0 :     U8_TRACE_TIMESTAMP();
     415            0 :     U8_TRACE_END();
     416            0 : }
     417              : 
     418            0 : void gui_attributes_editor_type_of_feature_btn_callback( GtkWidget* button, gpointer data )
     419              : {
     420            0 :     U8_TRACE_BEGIN();
     421            0 :     const gui_attribute_type_of_feature_t *const btn_data = (gui_attribute_type_of_feature_t*) data;
     422            0 :     assert ( NULL != btn_data );
     423            0 :     gui_attributes_editor_t *const this_ = gui_attribute_type_of_feature_get_editor( btn_data );
     424            0 :     assert ( NULL != this_ );
     425            0 :     const data_diagram_type_t selected_type = gui_attribute_type_of_feature_get_selected_type( btn_data );
     426            0 :     U8_TRACE_INFO_INT( "selected type:", selected_type );
     427              : 
     428              :     /* commit possibly changed texts before causing update events */
     429            0 :     gui_attributes_editor_commit_changes( this_ );
     430              : 
     431            0 :     gui_attributes_editor_private_type_commit_changes ( this_, selected_type );
     432              : 
     433            0 :     U8_TRACE_TIMESTAMP();
     434            0 :     U8_TRACE_END();
     435            0 : }
     436              : 
     437            0 : void gui_attributes_editor_type_of_relationship_btn_callback( GtkWidget* button, gpointer data )
     438              : {
     439            0 :     U8_TRACE_BEGIN();
     440            0 :     const gui_attribute_type_of_relationship_t *const btn_data = (gui_attribute_type_of_relationship_t*) data;
     441            0 :     assert ( NULL != btn_data );
     442            0 :     gui_attributes_editor_t *const this_ = gui_attribute_type_of_relationship_get_editor( btn_data );
     443            0 :     assert ( NULL != this_ );
     444            0 :     const data_diagram_type_t selected_type = gui_attribute_type_of_relationship_get_selected_type( btn_data );
     445            0 :     U8_TRACE_INFO_INT( "selected type:", selected_type );
     446              : 
     447              :     /* commit possibly changed texts before causing update events */
     448            0 :     gui_attributes_editor_commit_changes( this_ );
     449              : 
     450            0 :     gui_attributes_editor_private_type_commit_changes ( this_, selected_type );
     451              : 
     452            0 :     U8_TRACE_TIMESTAMP();
     453            0 :     U8_TRACE_END();
     454            0 : }
     455              : 
     456            0 : void gui_attributes_editor_description_focus_left_callback( GtkEventControllerFocus* self, gpointer user_data )
     457              : {
     458            0 :     U8_TRACE_BEGIN();
     459            0 :     assert( user_data != NULL );
     460            0 :     gui_attributes_editor_t *const this_ = (gui_attributes_editor_t*) user_data;
     461            0 :     assert( gtk_event_controller_get_widget( GTK_EVENT_CONTROLLER(self) ) == GTK_WIDGET( (*this_).description_text_view ) );
     462              : 
     463            0 :     gui_attributes_editor_commit_changes( this_ );
     464              :     //gui_attributes_editor_private_description_commit_changes( this_ );
     465              : 
     466            0 :     U8_TRACE_TIMESTAMP();
     467            0 :     U8_TRACE_END();
     468            0 : }
     469              : 
     470              : /* ================================ SELECTION or MODEL CHANGED CALLBACKS ================================ */
     471              : 
     472            0 : void gui_attributes_editor_focused_object_changed_callback( GtkWidget *widget, data_id_t *id, gpointer user_data )
     473              : {
     474            0 :     U8_TRACE_BEGIN();
     475              :     gui_attributes_editor_t *this_;
     476            0 :     this_ = (gui_attributes_editor_t*) user_data;
     477            0 :     assert ( NULL != this_ );
     478            0 :     assert ( NULL != id );
     479            0 :     assert ( NULL != widget );
     480              : 
     481              :     /* is a new object selected ? */
     482            0 :     if ( ! data_id_equals( &((*this_).selected_object_id), id ) )
     483              :     {
     484              :         /* store all changes on the old object */
     485            0 :         gui_attributes_editor_commit_changes( this_ );
     486              : 
     487              :         /* load the new object */
     488            0 :         data_id_trace( id );
     489            0 :         gui_attributes_editor_private_load_object( this_, *id );
     490              : 
     491              :         /* update all widgets now */
     492            0 :         gui_attributes_editor_update_widgets( this_ );
     493              : 
     494              :         /* select the name so that typing replaces it immediately */
     495              :         /* latest_created_id allows to check if selected id new */
     496            0 :         if ( ( data_id_equals( &((*this_).latest_created_id), &((*this_).selected_object_id) ) )
     497            0 :            || ( data_id_equals( &((*this_).second_latest_id), &((*this_).selected_object_id) ) ) )
     498              :         {
     499            0 :             gtk_widget_grab_focus( GTK_WIDGET((*this_).name_entry) );
     500              :             /* the grab focus may cause focus-lost signals - which update the widgets */
     501            0 :             gtk_editable_select_region( GTK_EDITABLE((*this_).name_entry), 0, -1 );
     502            0 :             U8_TRACE_INFO( "gui_attributes_editor called gtk_widget_grab_focus" );
     503              :         }
     504              :     }
     505              : 
     506            0 :     U8_TRACE_TIMESTAMP();
     507            0 :     U8_TRACE_END();
     508            0 : }
     509              : 
     510            0 : void gui_attributes_editor_data_changed_callback( GtkWidget *widget, data_change_message_t *msg, gpointer user_data )
     511              : {
     512            0 :     U8_TRACE_BEGIN();
     513              :     gui_attributes_editor_t *this_;
     514            0 :     this_ = (gui_attributes_editor_t*) user_data;
     515            0 :     assert ( NULL != this_ );
     516            0 :     assert ( NULL != msg );
     517            0 :     assert ( NULL != widget );
     518              : 
     519              :     data_id_t id;
     520              :     data_change_event_type_t evt_type;
     521            0 :     id = data_change_message_get_modified( msg );
     522            0 :     evt_type = data_change_message_get_event ( msg );
     523              : 
     524            0 :     if ( evt_type == DATA_CHANGE_EVENT_TYPE_DB_PREPARE_CLOSE )
     525              :     {
     526              :         /* store all changes on the old object */
     527            0 :         gui_attributes_editor_commit_changes( this_ );
     528              :     }
     529            0 :     else if ( evt_type == DATA_CHANGE_EVENT_TYPE_DB_CLOSED )
     530              :     {
     531            0 :         data_id_reinit_void( &((*this_).latest_created_id) );
     532            0 :         data_id_reinit_void( &((*this_).second_latest_id) );
     533              :         /* data_id_t nothing;
     534              :         data_id_init_void( &nothing );
     535              :         gui_attributes_editor_private_load_object( this_, nothing );  / * clear cached data */
     536            0 :         gui_attributes_editor_private_load_object( this_, DATA_ID_VOID );  /* clear cached data */
     537            0 :         gui_attributes_editor_update_widgets ( this_ );
     538              :     }
     539            0 :     else if ( data_id_equals( &id, &((*this_).selected_object_id) ) )
     540              :     {
     541              :         /* DO NOT STORE DATA IN A DATA CHANGED CALLBACK - MAY CAUSE ENDLESS RECURSION */
     542            0 :         data_change_message_trace( msg );
     543            0 :         if ( (*this_).sync_dir == GUI_ATTRIBUTES_EDITOR_SYNC_DIR_DB_TO_GUI )
     544              :         {
     545              :             /* overwrite/update displayed values */
     546            0 :             gui_attributes_editor_private_load_object( this_, id );  /* checks if object still exists */
     547            0 :             gui_attributes_editor_update_widgets ( this_ );
     548              :         }
     549              :     }
     550            0 :     else if ( evt_type == DATA_CHANGE_EVENT_TYPE_CREATE )
     551              :     {
     552              :         /* diagram elements should not be remembered, only the new classifier is important */
     553            0 :         if ( DATA_TABLE_DIAGRAMELEMENT != data_id_get_table( &id ) )
     554              :         {
     555            0 :             (*this_).second_latest_id = (*this_).latest_created_id;
     556            0 :             (*this_).latest_created_id = id;
     557              :         }
     558              :     };
     559              : 
     560            0 :     U8_TRACE_TIMESTAMP();
     561            0 :     U8_TRACE_END();
     562            0 : }
     563              : 
     564              : /* ================================ PRIVATE METHODS ================================ */
     565              : 
     566            0 : void gui_attributes_editor_private_load_object ( gui_attributes_editor_t *this_, data_id_t id )
     567              : {
     568            0 :     U8_TRACE_BEGIN();
     569              : 
     570              :     /* before overwriting the current data, trace this_: */
     571            0 :     gui_attributes_editor_trace( this_ );
     572            0 :     if ( (*this_).sync_dir != GUI_ATTRIBUTES_EDITOR_SYNC_DIR_DB_TO_GUI )
     573              :     {
     574            0 :         U8_LOG_WARNING( "gui_attributes_editor_private_load_object called in GUI_ATTRIBUTES_EDITOR_SYNC_DIR_GUI_TO_DB mode!" );
     575              :     }
     576              : 
     577            0 :     switch ( data_id_get_table(&id) )
     578              :     {
     579            0 :         case DATA_TABLE_VOID:
     580              :         {
     581            0 :             data_diagram_reinit_empty( &((*this_).private_diagram_cache) );
     582            0 :             data_classifier_reinit_empty( &((*this_).private_classifier_cache) );
     583            0 :             data_feature_reinit_empty( &((*this_).private_feature_cache) );
     584            0 :             data_relationship_reinit_empty( &((*this_).private_relationship_cache) );
     585            0 :             data_id_reinit_void( &((*this_).selected_object_id) );
     586              :         }
     587            0 :         break;
     588              : 
     589            0 :         case DATA_TABLE_CLASSIFIER:
     590              :         {
     591            0 :             data_diagram_reinit_empty( &((*this_).private_diagram_cache) );
     592            0 :             data_feature_reinit_empty( &((*this_).private_feature_cache) );
     593            0 :             data_relationship_reinit_empty( &((*this_).private_relationship_cache) );
     594              : 
     595              :             /* load the object */
     596              :             {
     597              :                 u8_error_t db_err;
     598              : 
     599            0 :                 data_classifier_destroy( &((*this_).private_classifier_cache) );
     600            0 :                 db_err = data_database_reader_get_classifier_by_id ( (*this_).db_reader, data_id_get_row(&id), &((*this_).private_classifier_cache) );
     601            0 :                 data_id_replace( &((*this_).selected_object_id), &id );
     602              : 
     603            0 :                 if ( u8_error_contains( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED ) )
     604              :                 {
     605            0 :                     U8_LOG_ERROR( "U8_ERROR_STRING_BUFFER_EXCEEDED at loading a classifier" );
     606            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
     607              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
     608              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_STRING_TRUNCATED
     609              :                                                            );
     610              :                 }
     611            0 :                 if ( u8_error_more_than( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED ) )
     612              :                 {
     613              :                     /* error at loading */
     614            0 :                     data_classifier_reinit_empty( &((*this_).private_classifier_cache) );
     615            0 :                     data_id_reinit_void( &((*this_).selected_object_id) );
     616              :                 }
     617              :             }
     618              :         }
     619            0 :         break;
     620              : 
     621            0 :         case DATA_TABLE_FEATURE:
     622              :         {
     623            0 :             data_diagram_reinit_empty( &((*this_).private_diagram_cache) );
     624            0 :             data_classifier_reinit_empty( &((*this_).private_classifier_cache) );
     625            0 :             data_relationship_reinit_empty( &((*this_).private_relationship_cache) );
     626              : 
     627              :             /* load the object */
     628              :             {
     629              :                 u8_error_t db_err;
     630              : 
     631            0 :                 data_feature_destroy( &((*this_).private_feature_cache) );
     632            0 :                 db_err = data_database_reader_get_feature_by_id ( (*this_).db_reader, data_id_get_row(&id), &((*this_).private_feature_cache) );
     633            0 :                 data_id_replace( &((*this_).selected_object_id), &id );
     634              : 
     635            0 :                 if ( u8_error_contains( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED ) )
     636              :                 {
     637            0 :                     U8_LOG_ERROR( "U8_ERROR_STRING_BUFFER_EXCEEDED at loading a feature" );
     638            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
     639              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
     640              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_STRING_TRUNCATED
     641              :                                                            );
     642              :                 }
     643            0 :                 if ( u8_error_more_than( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED ) )
     644              :                 {
     645              :                     /* error at loading */
     646            0 :                     data_feature_reinit_empty( &((*this_).private_feature_cache) );
     647            0 :                     data_id_reinit_void( &((*this_).selected_object_id) );
     648              :                 }
     649              :             }
     650              :         }
     651            0 :         break;
     652              : 
     653            0 :         case DATA_TABLE_RELATIONSHIP:
     654              :         {
     655            0 :             data_diagram_reinit_empty( &((*this_).private_diagram_cache) );
     656            0 :             data_classifier_reinit_empty( &((*this_).private_classifier_cache) );
     657            0 :             data_feature_reinit_empty( &((*this_).private_feature_cache) );
     658              : 
     659              :             /* load the object */
     660              :             {
     661              :                 u8_error_t db_err;
     662              : 
     663            0 :                 data_relationship_destroy( &((*this_).private_relationship_cache) );
     664            0 :                 db_err = data_database_reader_get_relationship_by_id ( (*this_).db_reader, data_id_get_row(&id), &((*this_).private_relationship_cache) );
     665            0 :                 data_id_replace( &((*this_).selected_object_id), &id );
     666              : 
     667            0 :                 if ( u8_error_contains( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED ) )
     668              :                 {
     669            0 :                     U8_LOG_ERROR( "U8_ERROR_STRING_BUFFER_EXCEEDED at loading a relationship" );
     670            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
     671              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
     672              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_STRING_TRUNCATED
     673              :                                                            );
     674              :                 }
     675            0 :                 if ( u8_error_more_than( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED ) )
     676              :                 {
     677              :                     /* error at loading */
     678            0 :                     data_relationship_reinit_empty( &((*this_).private_relationship_cache) );
     679            0 :                     data_id_reinit_void( &((*this_).selected_object_id) );
     680              :                 }
     681              :             }
     682              :         }
     683            0 :         break;
     684              : 
     685            0 :         case DATA_TABLE_DIAGRAMELEMENT:
     686              :         {
     687              :             /* (*this_).selected_object_id should not be of type DATA_TABLE_DIAGRAMELEMENT */
     688            0 :             data_diagram_reinit_empty( &((*this_).private_diagram_cache) );
     689            0 :             data_classifier_reinit_empty( &((*this_).private_classifier_cache) );
     690            0 :             data_feature_reinit_empty( &((*this_).private_feature_cache) );
     691            0 :             data_relationship_reinit_empty( &((*this_).private_relationship_cache) );
     692            0 :             data_id_reinit_void( &((*this_).selected_object_id) );
     693              :         }
     694            0 :         break;
     695              : 
     696            0 :         case DATA_TABLE_DIAGRAM:
     697              :         {
     698            0 :             data_classifier_reinit_empty( &((*this_).private_classifier_cache) );
     699            0 :             data_feature_reinit_empty( &((*this_).private_feature_cache) );
     700            0 :             data_relationship_reinit_empty( &((*this_).private_relationship_cache) );
     701              : 
     702              :             /* load the object */
     703              :             {
     704              :                 u8_error_t db_err;
     705              : 
     706            0 :                 data_diagram_destroy( &((*this_).private_diagram_cache) );
     707            0 :                 db_err = data_database_reader_get_diagram_by_id ( (*this_).db_reader, data_id_get_row(&id), &((*this_).private_diagram_cache) );
     708            0 :                 data_id_replace( &((*this_).selected_object_id), &id );
     709              : 
     710            0 :                 if ( u8_error_contains( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED ) )
     711              :                 {
     712            0 :                     U8_LOG_ERROR( "U8_ERROR_STRING_BUFFER_EXCEEDED at loading a diagram" );
     713            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
     714              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
     715              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_STRING_TRUNCATED
     716              :                                                            );
     717              :                 }
     718            0 :                 if ( u8_error_more_than( db_err, U8_ERROR_STRING_BUFFER_EXCEEDED ) )
     719              :                 {
     720              :                     /* error at loading */
     721            0 :                     data_diagram_reinit_empty( &((*this_).private_diagram_cache) );
     722            0 :                     data_id_reinit_void( &((*this_).selected_object_id) );
     723              :                 }
     724              :             }
     725              :         }
     726            0 :         break;
     727              : 
     728            0 :         default:
     729              :         {
     730            0 :             U8_LOG_ERROR( "invalid data in data_id_t." );
     731              : 
     732            0 :             data_diagram_reinit_empty( &((*this_).private_diagram_cache) );
     733            0 :             data_classifier_reinit_empty( &((*this_).private_classifier_cache) );
     734            0 :             data_feature_reinit_empty( &((*this_).private_feature_cache) );
     735            0 :             data_relationship_reinit_empty( &((*this_).private_relationship_cache) );
     736            0 :             data_id_reinit_void( &((*this_).selected_object_id) );
     737              :         }
     738            0 :         break;
     739              :     }
     740              : 
     741              :     /* after loading the current data, trace this_: */
     742            0 :     gui_attributes_editor_trace( this_ );
     743              : 
     744            0 :     U8_TRACE_END();
     745            0 : }
     746              : 
     747            0 : void gui_attributes_editor_private_name_commit_changes ( gui_attributes_editor_t *this_ )
     748              : {
     749            0 :     U8_TRACE_BEGIN();
     750              : 
     751              :     const char* text;
     752            0 :     GtkEntry *const name_widget = GTK_ENTRY( (*this_).name_entry );
     753            0 :     GtkEntryBuffer *const name_buf = gtk_entry_get_buffer( name_widget );
     754            0 :     text = gtk_entry_buffer_get_text( name_buf );
     755              : 
     756            0 :     U8_TRACE_INFO_STR( "text:", text );
     757              : 
     758              :     u8_error_t ctrl_err;
     759            0 :     switch ( data_id_get_table( &((*this_).selected_object_id) ) )
     760              :     {
     761            0 :         case DATA_TABLE_VOID:
     762              :         {
     763              :             /* nothing to do */
     764            0 :             U8_TRACE_INFO( "no object selected where name can be updated." );
     765              :         }
     766            0 :         break;
     767              : 
     768            0 :         case DATA_TABLE_CLASSIFIER:
     769              :         {
     770              :             const char *const unchanged_text
     771            0 :                 = data_classifier_get_name_const( &((*this_).private_classifier_cache) );
     772            0 :             if ( ! utf8string_equals_str( text, unchanged_text ) )
     773              :             {
     774              :                 u8_error_t handled_err;
     775              :                 {
     776              :                     ctrl_simple_changer_t name_disambiguator;
     777            0 :                     ctrl_simple_changer_init( &name_disambiguator, (*this_).controller, (*this_).db_reader );
     778            0 :                     ctrl_err = ctrl_simple_changer_update_classifier_name( &name_disambiguator,
     779            0 :                                                                            data_id_get_row( &((*this_).selected_object_id) ),
     780              :                                                                            text,
     781              :                                                                            &handled_err
     782              :                                                                          );
     783            0 :                     ctrl_simple_changer_destroy( &name_disambiguator );
     784              :                 }
     785              : 
     786            0 :                 if ( u8_error_contains( handled_err, U8_ERROR_DUPLICATE_NAME ) )
     787              :                 {
     788            0 :                     gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
     789              :                                                                        GUI_SIMPLE_MESSAGE_TYPE_ERROR,
     790              :                                                                        GUI_SIMPLE_MESSAGE_CONTENT_NAME_NOT_UNIQUE,
     791              :                                                                        text
     792              :                                                                      );
     793              :                 }
     794            0 :                 else if ( u8_error_contains( ctrl_err, U8_ERROR_STRING_BUFFER_EXCEEDED ) )
     795              :                 {
     796            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
     797              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
     798              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_STRING_TRUNCATED
     799              :                                                            );
     800              :                 }
     801            0 :                 else if ( u8_error_contains( ctrl_err, U8_ERROR_READ_ONLY_DB ) )
     802              :                 {
     803              :                     /* notify read-only warning to user */
     804            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
     805              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
     806              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_DB_IS_READ_ONLY
     807              :                                                            );
     808              :                 }
     809            0 :                 else if ( U8_ERROR_NONE != ctrl_err )
     810              :                 {
     811            0 :                     U8_LOG_ERROR_HEX( "update name failed:", ctrl_err );
     812              :                 }
     813              :             }
     814              :         }
     815            0 :         break;
     816              : 
     817            0 :         case DATA_TABLE_FEATURE:
     818              :         {
     819              :             const char *const unchanged_text
     820            0 :                 = data_feature_get_key_const( &((*this_).private_feature_cache) );
     821            0 :             if ( ! utf8string_equals_str( text, unchanged_text ) )
     822              :             {
     823              :                 ctrl_classifier_controller_t *class_ctrl;
     824            0 :                 class_ctrl = ctrl_controller_get_classifier_control_ptr ( (*this_).controller );
     825              : 
     826            0 :                 ctrl_err = ctrl_classifier_controller_update_feature_key( class_ctrl,
     827            0 :                                                                           data_id_get_row( &((*this_).selected_object_id) ),
     828              :                                                                           text
     829              :                                                                         );
     830            0 :                 if ( U8_ERROR_STRING_BUFFER_EXCEEDED == ctrl_err )
     831              :                 {
     832            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
     833              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
     834              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_STRING_TRUNCATED
     835              :                                                            );
     836              :                 }
     837            0 :                 else if ( U8_ERROR_READ_ONLY_DB == ctrl_err )
     838              :                 {
     839              :                     /* notify read-only warning to user */
     840            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
     841              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
     842              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_DB_IS_READ_ONLY
     843              :                                                            );
     844              :                 }
     845            0 :                 else if ( U8_ERROR_NONE != ctrl_err )
     846              :                 {
     847            0 :                     U8_LOG_ERROR_HEX( "update key/name failed:", ctrl_err );
     848              :                 }
     849              :             }
     850              :         }
     851            0 :         break;
     852              : 
     853            0 :         case DATA_TABLE_RELATIONSHIP:
     854              :         {
     855              :             const char *const unchanged_text
     856            0 :                 = data_relationship_get_name_const( &((*this_).private_relationship_cache) );
     857            0 :             if ( ! utf8string_equals_str( text, unchanged_text ) )
     858              :             {
     859              :                 ctrl_classifier_controller_t *class_ctrl;
     860            0 :                 class_ctrl = ctrl_controller_get_classifier_control_ptr ( (*this_).controller );
     861              : 
     862            0 :                 ctrl_err = ctrl_classifier_controller_update_relationship_name( class_ctrl,
     863            0 :                                                                                 data_id_get_row( &((*this_).selected_object_id) ),
     864              :                                                                                 text
     865              :                                                                               );
     866            0 :                 if ( U8_ERROR_STRING_BUFFER_EXCEEDED == ctrl_err )
     867              :                 {
     868            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
     869              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
     870              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_STRING_TRUNCATED
     871              :                                                            );
     872              :                 }
     873            0 :                 else if ( U8_ERROR_READ_ONLY_DB == ctrl_err )
     874              :                 {
     875              :                     /* notify read-only warning to user */
     876            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
     877              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
     878              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_DB_IS_READ_ONLY
     879              :                                                            );
     880              :                 }
     881            0 :                 else if ( U8_ERROR_NONE != ctrl_err )
     882              :                 {
     883            0 :                     U8_LOG_ERROR_HEX( "update name failed:", ctrl_err );
     884              :                 }
     885              :             }
     886              :         }
     887            0 :         break;
     888              : 
     889            0 :         case DATA_TABLE_DIAGRAMELEMENT:
     890              :         {
     891              :             /* (*this_).selected_object_id should not be of type DATA_TABLE_DIAGRAMELEMENT */
     892            0 :             U8_LOG_WARNING( "no object selected where name can be updated." );
     893              :         }
     894            0 :         break;
     895              : 
     896            0 :         case DATA_TABLE_DIAGRAM:
     897              :         {
     898              :             const char *const unchanged_text
     899            0 :                 = data_diagram_get_name_const( &((*this_).private_diagram_cache) );
     900            0 :             if ( ! utf8string_equals_str( text, unchanged_text ) )
     901              :             {
     902              :                 ctrl_diagram_controller_t *diag_ctrl;
     903            0 :                 diag_ctrl = ctrl_controller_get_diagram_control_ptr ( (*this_).controller );
     904              : 
     905            0 :                 ctrl_err = ctrl_diagram_controller_update_diagram_name( diag_ctrl,
     906            0 :                                                                         data_id_get_row( &((*this_).selected_object_id) ),
     907              :                                                                         text
     908              :                                                                       );
     909            0 :                 if ( U8_ERROR_STRING_BUFFER_EXCEEDED == ctrl_err )
     910              :                 {
     911            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
     912              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
     913              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_STRING_TRUNCATED
     914              :                                                            );
     915              :                 }
     916            0 :                 else if ( U8_ERROR_READ_ONLY_DB == ctrl_err )
     917              :                 {
     918              :                     /* notify read-only warning to user */
     919            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
     920              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
     921              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_DB_IS_READ_ONLY
     922              :                                                            );
     923              :                 }
     924            0 :                 else if ( U8_ERROR_NONE != ctrl_err )
     925              :                 {
     926            0 :                     U8_LOG_ERROR_HEX( "update name failed:", ctrl_err );
     927              :                 }
     928              :             }
     929              :         }
     930            0 :         break;
     931              : 
     932            0 :         default:
     933              :         {
     934            0 :             U8_LOG_ERROR( "invalid data in data_id_t." );
     935              :         }
     936            0 :         break;
     937              :     }
     938              : 
     939            0 :     U8_TRACE_END();
     940            0 : }
     941              : 
     942            0 : void gui_attributes_editor_private_stereotype_commit_changes ( gui_attributes_editor_t *this_ )
     943              : {
     944            0 :     U8_TRACE_BEGIN();
     945              : 
     946              :     const char* text;
     947            0 :     GtkEntry *const stereotype_widget = GTK_ENTRY( (*this_).stereotype_entry );
     948            0 :     GtkEntryBuffer *const stereotype_buf = gtk_entry_get_buffer( stereotype_widget );
     949            0 :     text = gtk_entry_buffer_get_text( stereotype_buf );
     950              : 
     951            0 :     U8_TRACE_INFO_STR( "text:", text );
     952              : 
     953            0 :     ctrl_classifier_controller_t *const class_ctrl = ctrl_controller_get_classifier_control_ptr ( (*this_).controller );
     954            0 :     ctrl_diagram_controller_t *const diag_ctrl = ctrl_controller_get_diagram_control_ptr ( (*this_).controller );
     955            0 :     u8_error_t ctrl_update_err = U8_ERROR_NONE;
     956            0 :     switch ( data_id_get_table( &((*this_).selected_object_id) ) )
     957              :     {
     958            0 :         case DATA_TABLE_VOID:
     959              :         {
     960              :             /* nothing to do */
     961            0 :             U8_TRACE_INFO( "no object selected where stereotype can be updated." );
     962              :         }
     963            0 :         break;
     964              : 
     965            0 :         case DATA_TABLE_CLASSIFIER:
     966              :         {
     967            0 :             const char *const unchanged_text = data_classifier_get_stereotype_const( &((*this_).private_classifier_cache) );
     968            0 :             if ( ! utf8string_equals_str( text, unchanged_text ) )
     969              :             {
     970            0 :                 ctrl_update_err = ctrl_classifier_controller_update_classifier_stereotype( class_ctrl,
     971            0 :                                                                                            data_id_get_row( &((*this_).selected_object_id) ),
     972              :                                                                                            text
     973              :                                                                                          );
     974              :             }
     975              :         }
     976            0 :         break;
     977              : 
     978            0 :         case DATA_TABLE_FEATURE:
     979              :         {
     980            0 :             const char *const unchanged_text = data_feature_get_value_const( &((*this_).private_feature_cache) );
     981            0 :             if ( ! utf8string_equals_str( text, unchanged_text ) )
     982              :             {
     983            0 :                 ctrl_update_err = ctrl_classifier_controller_update_feature_value( class_ctrl,
     984            0 :                                                                                    data_id_get_row( &((*this_).selected_object_id) ),
     985              :                                                                                    text
     986              :                                                                                  );
     987              :             }
     988              :         }
     989            0 :         break;
     990              : 
     991            0 :         case DATA_TABLE_RELATIONSHIP:
     992              :         {
     993            0 :             const char *const unchanged_text = data_relationship_get_stereotype_const( &((*this_).private_relationship_cache) );
     994            0 :             if ( ! utf8string_equals_str( text, unchanged_text ) )
     995              :             {
     996            0 :                 ctrl_update_err = ctrl_classifier_controller_update_relationship_stereotype( class_ctrl,
     997            0 :                                                                                              data_id_get_row( &((*this_).selected_object_id) ),
     998              :                                                                                              text
     999              :                                                                                            );
    1000              :             }
    1001              :         }
    1002            0 :         break;
    1003              : 
    1004            0 :         case DATA_TABLE_DIAGRAMELEMENT:
    1005              :         {
    1006              :             /* (*this_).selected_object_id should not be of type DATA_TABLE_DIAGRAMELEMENT */
    1007            0 :             U8_LOG_WARNING( "no object selected where stereotype can be updated." );
    1008              :         }
    1009            0 :         break;
    1010              : 
    1011            0 :         case DATA_TABLE_DIAGRAM:
    1012              :         {
    1013            0 :             const char *const unchanged_text = data_diagram_get_stereotype_const( &((*this_).private_diagram_cache) );
    1014            0 :             if ( ! utf8string_equals_str( text, unchanged_text ) )
    1015              :             {
    1016            0 :                 ctrl_update_err = ctrl_diagram_controller_update_diagram_stereotype( diag_ctrl,
    1017            0 :                                                                                      data_id_get_row( &((*this_).selected_object_id) ),
    1018              :                                                                                      text
    1019              :                                                                                    );
    1020              :             }
    1021              :         }
    1022            0 :         break;
    1023              : 
    1024            0 :         default:
    1025              :         {
    1026            0 :             U8_LOG_ERROR( "invalid data in data_id_t." );
    1027              :         }
    1028            0 :         break;
    1029              :     }
    1030              : 
    1031              :     /* show warning to user in case of error: */
    1032            0 :     if ( U8_ERROR_STRING_BUFFER_EXCEEDED == ctrl_update_err )
    1033              :     {
    1034            0 :         gui_simple_message_to_user_show_message( (*this_).message_to_user,
    1035              :                                                  GUI_SIMPLE_MESSAGE_TYPE_WARNING,
    1036              :                                                  GUI_SIMPLE_MESSAGE_CONTENT_STRING_TRUNCATED
    1037              :                                                );
    1038              :     }
    1039            0 :     else if ( U8_ERROR_READ_ONLY_DB == ctrl_update_err )
    1040              :     {
    1041              :         /* notify read-only warning to user */
    1042            0 :         gui_simple_message_to_user_show_message( (*this_).message_to_user,
    1043              :                                                  GUI_SIMPLE_MESSAGE_TYPE_WARNING,
    1044              :                                                  GUI_SIMPLE_MESSAGE_CONTENT_DB_IS_READ_ONLY
    1045              :                                                );
    1046              :     }
    1047            0 :     else if ( U8_ERROR_NONE != ctrl_update_err )
    1048              :     {
    1049            0 :         U8_LOG_ERROR_HEX( "update stereotype failed:", ctrl_update_err );
    1050              :     }
    1051              : 
    1052            0 :     U8_TRACE_END();
    1053            0 : }
    1054              : 
    1055            0 : void gui_attributes_editor_private_type_commit_changes ( gui_attributes_editor_t *this_, int obj_type )
    1056              : {
    1057            0 :     U8_TRACE_BEGIN();
    1058              : 
    1059            0 :     U8_TRACE_INFO_INT( "obj_type:", obj_type );
    1060              : 
    1061              :     u8_error_t ctrl_err;
    1062            0 :     switch ( data_id_get_table( &((*this_).selected_object_id) ) )
    1063              :     {
    1064            0 :         case DATA_TABLE_VOID:
    1065              :         {
    1066              :             /* nothing to do */
    1067            0 :             U8_TRACE_INFO( "no object selected where type can be updated." );
    1068              :         }
    1069            0 :         break;
    1070              : 
    1071            0 :         case DATA_TABLE_CLASSIFIER:
    1072              :         {
    1073              :             const data_classifier_type_t unchanged_main_type
    1074            0 :                 = data_classifier_get_main_type( &((*this_).private_classifier_cache) );
    1075            0 :             if ( obj_type != unchanged_main_type )
    1076              :             {
    1077              :                 ctrl_classifier_controller_t *class_ctrl;
    1078            0 :                 class_ctrl = ctrl_controller_get_classifier_control_ptr ( (*this_).controller );
    1079              : 
    1080            0 :                 ctrl_err = ctrl_classifier_controller_update_classifier_main_type ( class_ctrl, data_id_get_row( &((*this_).selected_object_id) ), obj_type );
    1081            0 :                 if ( U8_ERROR_READ_ONLY_DB == ctrl_err )
    1082              :                 {
    1083              :                     /* notify read-only warning to user */
    1084            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
    1085              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
    1086              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_DB_IS_READ_ONLY
    1087              :                                                            );
    1088              :                 }
    1089            0 :                 else if ( U8_ERROR_NONE != ctrl_err )
    1090              :                 {
    1091            0 :                     U8_LOG_ERROR_HEX( "update main type failed:", ctrl_err );
    1092              :                 }
    1093              :             }
    1094              :         }
    1095            0 :         break;
    1096              : 
    1097            0 :         case DATA_TABLE_FEATURE:
    1098              :         {
    1099              :             const data_feature_type_t unchanged_main_type
    1100            0 :                 = data_feature_get_main_type( &((*this_).private_feature_cache) );
    1101            0 :             if ( obj_type != unchanged_main_type )
    1102              :             {
    1103              :                 ctrl_classifier_controller_t *class_ctrl;
    1104            0 :                 class_ctrl = ctrl_controller_get_classifier_control_ptr ( (*this_).controller );
    1105              : 
    1106            0 :                 ctrl_err = ctrl_classifier_controller_update_feature_main_type ( class_ctrl, data_id_get_row( &((*this_).selected_object_id) ), obj_type );
    1107            0 :                 if ( U8_ERROR_READ_ONLY_DB == ctrl_err )
    1108              :                 {
    1109              :                     /* notify read-only warning to user */
    1110            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
    1111              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
    1112              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_DB_IS_READ_ONLY
    1113              :                                                            );
    1114              :                 }
    1115            0 :                 else if ( U8_ERROR_NONE != ctrl_err )
    1116              :                 {
    1117            0 :                     U8_LOG_ERROR_HEX( "update main type failed:", ctrl_err );
    1118              :                 }
    1119              :             }
    1120              :         }
    1121            0 :         break;
    1122              : 
    1123            0 :         case DATA_TABLE_RELATIONSHIP:
    1124              :         {
    1125              :             const data_relationship_type_t unchanged_main_type
    1126            0 :                 = data_relationship_get_main_type( &((*this_).private_relationship_cache) );
    1127            0 :             if ( obj_type != unchanged_main_type )
    1128              :             {
    1129              :                 ctrl_classifier_controller_t *class_ctrl;
    1130            0 :                 class_ctrl = ctrl_controller_get_classifier_control_ptr ( (*this_).controller );
    1131              : 
    1132            0 :                 ctrl_err = ctrl_classifier_controller_update_relationship_main_type ( class_ctrl, data_id_get_row( &((*this_).selected_object_id) ), obj_type );
    1133            0 :                 if ( U8_ERROR_READ_ONLY_DB == ctrl_err )
    1134              :                 {
    1135              :                     /* notify read-only warning to user */
    1136            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
    1137              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
    1138              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_DB_IS_READ_ONLY
    1139              :                                                            );
    1140              :                 }
    1141            0 :                 else if ( U8_ERROR_NONE != ctrl_err )
    1142              :                 {
    1143            0 :                     U8_LOG_ERROR_HEX( "update main type failed:", ctrl_err );
    1144              :                 }
    1145              :             }
    1146              :         }
    1147            0 :         break;
    1148              : 
    1149            0 :         case DATA_TABLE_DIAGRAMELEMENT:
    1150              :         {
    1151              :             /* (*this_).selected_object_id should not be of type DATA_TABLE_DIAGRAMELEMENT */
    1152            0 :             U8_LOG_WARNING( "no object selected where type can be updated." );
    1153              :         }
    1154            0 :         break;
    1155              : 
    1156            0 :         case DATA_TABLE_DIAGRAM:
    1157              :         {
    1158              :             const data_diagram_type_t unchanged_type
    1159            0 :                 = data_diagram_get_diagram_type( &((*this_).private_diagram_cache) );
    1160            0 :             if ( obj_type != unchanged_type )
    1161              :             {
    1162              :                 ctrl_diagram_controller_t *diag_ctrl;
    1163            0 :                 diag_ctrl = ctrl_controller_get_diagram_control_ptr ( (*this_).controller );
    1164              :                 data_stat_t stat;
    1165            0 :                 data_stat_init( &stat );
    1166              :                 consistency_stat_t c_stat;
    1167            0 :                 consistency_stat_init( &c_stat );
    1168            0 :                 ctrl_err = ctrl_diagram_controller_update_diagram_type( diag_ctrl,
    1169            0 :                                                                         data_id_get_row( &((*this_).selected_object_id) ),
    1170              :                                                                         obj_type,
    1171              :                                                                         &c_stat
    1172              :                                                                       );
    1173            0 :                 consistency_stat_transfer_to( &c_stat, &stat );
    1174            0 :                 if ( U8_ERROR_READ_ONLY_DB == ctrl_err )
    1175              :                 {
    1176              :                     /* notify read-only warning to user */
    1177            0 :                     gui_simple_message_to_user_show_message( (*this_).message_to_user,
    1178              :                                                              GUI_SIMPLE_MESSAGE_TYPE_WARNING,
    1179              :                                                              GUI_SIMPLE_MESSAGE_CONTENT_DB_IS_READ_ONLY
    1180              :                                                            );
    1181              :                 }
    1182              :                 else
    1183              :                 {
    1184            0 :                     if ( U8_ERROR_NONE != ctrl_err )
    1185              :                     {
    1186            0 :                         U8_LOG_ERROR_HEX( "update type failed:", ctrl_err );
    1187              :                     }
    1188              :                     else
    1189              :                     {
    1190            0 :                         data_stat_inc_count( &stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_MODIFIED );
    1191              :                     }
    1192            0 :                     gui_simple_message_to_user_show_message_with_stat( (*this_).message_to_user,
    1193              :                                                                        GUI_SIMPLE_MESSAGE_TYPE_INFO,
    1194              :                                                                        GUI_SIMPLE_MESSAGE_CONTENT_TYPE_CHANGE,
    1195              :                                                                        &stat
    1196              :                                                                      );
    1197              :                 }
    1198            0 :                 consistency_stat_destroy( &c_stat );
    1199            0 :                 data_stat_destroy( &stat );
    1200              :             }
    1201              :         }
    1202            0 :         break;
    1203              : 
    1204            0 :         default:
    1205              :         {
    1206            0 :             U8_LOG_ERROR( "invalid data in data_id_t." );
    1207              :         }
    1208            0 :         break;
    1209              :     }
    1210              : 
    1211            0 :     U8_TRACE_END();
    1212            0 : }
    1213              : 
    1214            0 : void gui_attributes_editor_private_description_commit_changes ( gui_attributes_editor_t *this_ )
    1215              : {
    1216            0 :     U8_TRACE_BEGIN();
    1217              :     GtkTextView *description_widget;
    1218              :     GtkTextBuffer *buffer;
    1219            0 :     description_widget = GTK_TEXT_VIEW( (*this_).description_text_view );
    1220            0 :     buffer = gtk_text_view_get_buffer ( description_widget );
    1221              : 
    1222              :     GtkTextIter start;
    1223              :     GtkTextIter end;
    1224            0 :     gtk_text_buffer_get_start_iter ( buffer, &start );
    1225            0 :     gtk_text_buffer_get_end_iter ( buffer, &end );
    1226              : 
    1227              :     const char* text;
    1228            0 :     text = gtk_text_buffer_get_text ( buffer, &start, &end, false );
    1229              : 
    1230            0 :     U8_TRACE_INFO_STR( "text:", text );
    1231              : 
    1232            0 :     ctrl_classifier_controller_t *const class_ctrl = ctrl_controller_get_classifier_control_ptr ( (*this_).controller );
    1233            0 :     ctrl_diagram_controller_t *const diag_ctrl = ctrl_controller_get_diagram_control_ptr ( (*this_).controller );
    1234            0 :     u8_error_t ctrl_update_err = U8_ERROR_NONE;
    1235            0 :     switch ( data_id_get_table( &((*this_).selected_object_id) ) )
    1236              :     {
    1237            0 :         case DATA_TABLE_VOID:
    1238              :         {
    1239              :             /* nothing to do */
    1240            0 :             U8_TRACE_INFO( "no object selected where description can be updated." );
    1241              :         }
    1242            0 :         break;
    1243              : 
    1244            0 :         case DATA_TABLE_CLASSIFIER:
    1245              :         {
    1246              :             const char *const unchanged_text
    1247            0 :                 = data_classifier_get_description_const( &((*this_).private_classifier_cache) );
    1248            0 :             if ( ! utf8string_equals_str( text, unchanged_text ) )
    1249              :             {
    1250            0 :                 ctrl_update_err = ctrl_classifier_controller_update_classifier_description( class_ctrl,
    1251            0 :                                                                                             data_id_get_row( &((*this_).selected_object_id) ),
    1252              :                                                                                             text
    1253              :                                                                                           );
    1254              : 
    1255              :                 /* report errors in svg images in description in case of stereotype: */
    1256              :                 const data_classifier_type_t main_type
    1257            0 :                     = data_classifier_get_main_type( &((*this_).private_classifier_cache) );
    1258            0 :                 if ( main_type == DATA_CLASSIFIER_TYPE_STEREOTYPE )
    1259              :                 {
    1260              :                     geometry_rectangle_t view_rect;
    1261              :                     u8_error_info_t svg_err_info;
    1262              :                     draw_stereotype_icon_t svg_parser;
    1263            0 :                     draw_stereotype_icon_init( &svg_parser );
    1264              :                     const u8_error_t svg_err
    1265            0 :                         = draw_stereotype_icon_parse_svg_xml( &svg_parser,
    1266              :                                                               text,  /* drawing_directives */
    1267              :                                                               &view_rect,
    1268              :                                                               &svg_err_info
    1269              :                                                             );
    1270            0 :                     draw_stereotype_icon_destroy( &svg_parser );
    1271            0 :                     if ( svg_err == U8_ERROR_NOT_FOUND )
    1272              :                     {
    1273            0 :                         U8_TRACE_INFO( "the stereotype has no image." );
    1274              :                     }
    1275            0 :                     else if ( svg_err != U8_ERROR_NONE )
    1276              :                     {
    1277            0 :                         gui_simple_message_to_user_show_error_info( (*this_).message_to_user, &svg_err_info );
    1278              :                     }
    1279              :                 }
    1280              :             }
    1281              :         }
    1282            0 :         break;
    1283              : 
    1284            0 :         case DATA_TABLE_FEATURE:
    1285              :         {
    1286              :             const char *const unchanged_text
    1287            0 :                 = data_feature_get_description_const( &((*this_).private_feature_cache) );
    1288            0 :             if ( ! utf8string_equals_str( text, unchanged_text ) )
    1289              :             {
    1290            0 :                 ctrl_update_err = ctrl_classifier_controller_update_feature_description( class_ctrl,
    1291            0 :                                                                                          data_id_get_row( &((*this_).selected_object_id) ),
    1292              :                                                                                          text
    1293              :                                                                                        );
    1294              :             }
    1295              :         }
    1296            0 :         break;
    1297              : 
    1298            0 :         case DATA_TABLE_RELATIONSHIP:
    1299              :         {
    1300              :             const char *const unchanged_text
    1301            0 :                 = data_relationship_get_description_const( &((*this_).private_relationship_cache) );
    1302            0 :             if ( ! utf8string_equals_str( text, unchanged_text ) )
    1303              :             {
    1304            0 :                 ctrl_update_err = ctrl_classifier_controller_update_relationship_description( class_ctrl,
    1305            0 :                                                                                               data_id_get_row( &((*this_).selected_object_id) ),
    1306              :                                                                                               text
    1307              :                                                                                             );
    1308              :             }
    1309              :         }
    1310            0 :         break;
    1311              : 
    1312            0 :         case DATA_TABLE_DIAGRAMELEMENT:
    1313              :         {
    1314              :             /* (*this_).selected_object_id should not be of type DATA_TABLE_DIAGRAMELEMENT */
    1315            0 :             U8_LOG_WARNING( "no object selected where description can be updated." );
    1316              :         }
    1317            0 :         break;
    1318              : 
    1319            0 :         case DATA_TABLE_DIAGRAM:
    1320              :         {
    1321              :             const char *const unchanged_text
    1322            0 :                 = data_diagram_get_description_const( &((*this_).private_diagram_cache) );
    1323            0 :             if ( ! utf8string_equals_str( text, unchanged_text ) )
    1324              :             {
    1325            0 :                 ctrl_update_err = ctrl_diagram_controller_update_diagram_description( diag_ctrl,
    1326            0 :                                                                                       data_id_get_row( &((*this_).selected_object_id) ),
    1327              :                                                                                       text
    1328              :                                                                                     );
    1329              :             }
    1330              :         }
    1331            0 :         break;
    1332              : 
    1333            0 :         default:
    1334              :         {
    1335            0 :             U8_LOG_ERROR( "invalid data in data_id_t." );
    1336              :         }
    1337            0 :         break;
    1338              :     }
    1339              : 
    1340              :     /* show warning to user in case of error: */
    1341            0 :     if ( U8_ERROR_STRING_BUFFER_EXCEEDED == ctrl_update_err )
    1342              :     {
    1343            0 :         gui_simple_message_to_user_show_message( (*this_).message_to_user,
    1344              :                                                     GUI_SIMPLE_MESSAGE_TYPE_WARNING,
    1345              :                                                     GUI_SIMPLE_MESSAGE_CONTENT_STRING_TRUNCATED
    1346              :                                                 );
    1347              :     }
    1348            0 :     else if ( U8_ERROR_READ_ONLY_DB == ctrl_update_err )
    1349              :     {
    1350              :         /* notify read-only warning to user */
    1351            0 :         gui_simple_message_to_user_show_message( (*this_).message_to_user,
    1352              :                                                     GUI_SIMPLE_MESSAGE_TYPE_WARNING,
    1353              :                                                     GUI_SIMPLE_MESSAGE_CONTENT_DB_IS_READ_ONLY
    1354              :                                                 );
    1355              :     }
    1356            0 :     else if ( U8_ERROR_NONE != ctrl_update_err )
    1357              :     {
    1358            0 :         U8_LOG_ERROR_HEX( "update description failed:", ctrl_update_err );
    1359              :     }
    1360              : 
    1361            0 :     U8_TRACE_END();
    1362            0 : }
    1363              : 
    1364            0 : void gui_attributes_editor_private_id_update_view ( gui_attributes_editor_t *this_ )
    1365              : {
    1366            0 :     U8_TRACE_BEGIN();
    1367              :     GtkLabel *id_widget;
    1368            0 :     id_widget = GTK_LABEL( (*this_).id_label );
    1369              : 
    1370              :     char data_id_string_buf[DATA_ID_MAX_UTF8STRING_SIZE];
    1371            0 :     utf8stringbuf_t data_id_string = UTF8STRINGBUF( data_id_string_buf );
    1372            0 :     utf8stringbuf_clear( &data_id_string );
    1373            0 :     if ( data_id_is_valid( &((*this_).selected_object_id) ) )
    1374              :     {
    1375            0 :         utf8error_t str_err = data_id_to_utf8stringbuf ( &((*this_).selected_object_id), data_id_string );
    1376            0 :         if ( UTF8ERROR_SUCCESS != str_err )
    1377              :         {
    1378            0 :             U8_LOG_ERROR_HEX( "data_id_to_utf8stringbuf failed:", str_err );
    1379              :         }
    1380              :     }
    1381            0 :     gtk_label_set_text ( id_widget, utf8stringbuf_get_string( &data_id_string ) );
    1382              : 
    1383            0 :     U8_TRACE_END();
    1384            0 : }
    1385              : 
    1386            0 : void gui_attributes_editor_private_name_update_view ( gui_attributes_editor_t *this_ )
    1387              : {
    1388            0 :     U8_TRACE_BEGIN();
    1389              :     GtkEntry *name_widget;
    1390            0 :     name_widget = GTK_ENTRY( (*this_).name_entry );
    1391              : 
    1392            0 :     switch ( data_id_get_table( &((*this_).selected_object_id )) )
    1393              :     {
    1394            0 :         case DATA_TABLE_VOID:
    1395              :         {
    1396              :             /* prevent that a user accitentially enters text to a non-existing object */
    1397            0 :             gtk_widget_set_visible( GTK_WIDGET ( name_widget ), FALSE );
    1398              :         }
    1399            0 :         break;
    1400              : 
    1401            0 :         case DATA_TABLE_CLASSIFIER:
    1402              :         {
    1403            0 :             gtk_widget_set_visible( GTK_WIDGET ( name_widget ), TRUE );
    1404              : 
    1405              :             const char *const text
    1406            0 :                 = data_classifier_get_name_const( &((*this_).private_classifier_cache) );
    1407            0 :             GtkEntryBuffer *const name_buf = gtk_entry_get_buffer( name_widget );
    1408            0 :             gtk_entry_buffer_set_text( name_buf, text, -1 /* = n_chars */ );
    1409              :         }
    1410            0 :         break;
    1411              : 
    1412            0 :         case DATA_TABLE_FEATURE:
    1413              :         {
    1414            0 :             gtk_widget_set_visible( GTK_WIDGET ( name_widget ), TRUE );
    1415              : 
    1416              :             const char *const text
    1417            0 :                 = data_feature_get_key_const( &((*this_).private_feature_cache) );
    1418            0 :             GtkEntryBuffer *const name_buf = gtk_entry_get_buffer( name_widget );
    1419            0 :             gtk_entry_buffer_set_text( name_buf, text, -1 /* = n_chars */ );
    1420              :         }
    1421            0 :         break;
    1422              : 
    1423            0 :         case DATA_TABLE_RELATIONSHIP:
    1424              :         {
    1425            0 :             gtk_widget_set_visible( GTK_WIDGET ( name_widget ), TRUE );
    1426              : 
    1427              :             const char *const text
    1428            0 :                 = data_relationship_get_name_const( &((*this_).private_relationship_cache) );
    1429            0 :             GtkEntryBuffer *const name_buf = gtk_entry_get_buffer( name_widget );
    1430            0 :             gtk_entry_buffer_set_text( name_buf, text, -1 /* = n_chars */ );
    1431              :         }
    1432            0 :         break;
    1433              : 
    1434            0 :         case DATA_TABLE_DIAGRAMELEMENT:
    1435              :         {
    1436            0 :             gtk_widget_set_visible( GTK_WIDGET ( name_widget ), FALSE );
    1437              :         }
    1438            0 :         break;
    1439              : 
    1440            0 :         case DATA_TABLE_DIAGRAM:
    1441              :         {
    1442            0 :             gtk_widget_set_visible( GTK_WIDGET ( name_widget ), TRUE );
    1443              : 
    1444              :             const char *const text
    1445            0 :                 = data_diagram_get_name_const( &((*this_).private_diagram_cache) );
    1446            0 :             GtkEntryBuffer *const name_buf = gtk_entry_get_buffer( name_widget );
    1447            0 :             gtk_entry_buffer_set_text( name_buf, text, -1 /* = n_chars */ );
    1448              :         }
    1449            0 :         break;
    1450              : 
    1451            0 :         default:
    1452              :         {
    1453            0 :             U8_LOG_ERROR( "invalid data in data_id_t." );
    1454            0 :             GtkEntryBuffer *const name_buf = gtk_entry_get_buffer( name_widget );
    1455            0 :             gtk_entry_buffer_set_text( name_buf, "", 0 /* = n_chars */ );
    1456              :         }
    1457            0 :         break;
    1458              :     }
    1459              : 
    1460            0 :     U8_TRACE_END();
    1461            0 : }
    1462              : 
    1463            0 : void gui_attributes_editor_private_stereotype_update_view ( gui_attributes_editor_t *this_ )
    1464              : {
    1465            0 :     U8_TRACE_BEGIN();
    1466              :     GtkEntry *stereotype_widget;
    1467            0 :     stereotype_widget = GTK_ENTRY( (*this_).stereotype_entry );
    1468              : 
    1469            0 :     switch ( data_id_get_table( &((*this_).selected_object_id ) ) )
    1470              :     {
    1471            0 :         case DATA_TABLE_VOID:
    1472              :         {
    1473              :             /* prevent that a user accitentially enters text to a non-existing object */
    1474            0 :             gtk_widget_set_visible( GTK_WIDGET ( stereotype_widget ), FALSE );
    1475              :             /*gtk_entry_set_text( GTK_ENTRY ( stereotype_widget ), "    -- n/a --" );*/
    1476            0 :             gtk_editable_set_editable ( GTK_EDITABLE ( stereotype_widget ), false );
    1477              :         }
    1478            0 :         break;
    1479              : 
    1480            0 :         case DATA_TABLE_CLASSIFIER:
    1481              :         {
    1482            0 :             gtk_widget_set_visible( GTK_WIDGET ( stereotype_widget ), TRUE );
    1483            0 :             gtk_editable_set_editable ( GTK_EDITABLE ( stereotype_widget ), true );
    1484              : 
    1485              :             const char *const text
    1486            0 :                 = data_classifier_get_stereotype_const( &((*this_).private_classifier_cache) );
    1487            0 :             GtkEntryBuffer *const stereotype_buf = gtk_entry_get_buffer( stereotype_widget );
    1488            0 :             gtk_entry_buffer_set_text( stereotype_buf, text, -1 /* = n_chars */ );
    1489              :         }
    1490            0 :         break;
    1491              : 
    1492            0 :         case DATA_TABLE_FEATURE:
    1493              :         {
    1494            0 :             gtk_widget_set_visible( GTK_WIDGET ( stereotype_widget ), TRUE );
    1495            0 :             gtk_editable_set_editable ( GTK_EDITABLE ( stereotype_widget ), true );
    1496              : 
    1497              :             const char *const text
    1498            0 :                 = data_feature_get_value_const( &((*this_).private_feature_cache) );
    1499            0 :             GtkEntryBuffer *const stereotype_buf = gtk_entry_get_buffer( stereotype_widget );
    1500            0 :             gtk_entry_buffer_set_text( stereotype_buf, text, -1 /* = n_chars */ );
    1501              :         }
    1502            0 :         break;
    1503              : 
    1504            0 :         case DATA_TABLE_RELATIONSHIP:
    1505              :         {
    1506            0 :             gtk_widget_set_visible( GTK_WIDGET ( stereotype_widget ), TRUE );
    1507            0 :             gtk_editable_set_editable ( GTK_EDITABLE ( stereotype_widget ), true );
    1508              : 
    1509              :             const char *const text
    1510            0 :                 = data_relationship_get_stereotype_const( &((*this_).private_relationship_cache) );
    1511            0 :             GtkEntryBuffer *const stereotype_buf = gtk_entry_get_buffer( stereotype_widget );
    1512            0 :             gtk_entry_buffer_set_text( stereotype_buf, text, -1 /* = n_chars */ );
    1513              :         }
    1514            0 :         break;
    1515              : 
    1516            0 :         case DATA_TABLE_DIAGRAMELEMENT:
    1517              :         {
    1518            0 :             gtk_widget_set_visible( GTK_WIDGET ( stereotype_widget ), FALSE );
    1519            0 :             gtk_editable_set_editable ( GTK_EDITABLE ( stereotype_widget ), false );
    1520              :         }
    1521            0 :         break;
    1522              : 
    1523            0 :         case DATA_TABLE_DIAGRAM:
    1524              :         {
    1525            0 :             gtk_widget_set_visible( GTK_WIDGET ( stereotype_widget ), TRUE );
    1526            0 :             gtk_editable_set_editable ( GTK_EDITABLE ( stereotype_widget ), true );
    1527              : 
    1528              :             const char *const text
    1529            0 :                 = data_diagram_get_stereotype_const( &((*this_).private_diagram_cache) );
    1530            0 :             GtkEntryBuffer *const stereotype_buf = gtk_entry_get_buffer( stereotype_widget );
    1531            0 :             gtk_entry_buffer_set_text( stereotype_buf, text, -1 /* = n_chars */ );
    1532              :         }
    1533            0 :         break;
    1534              : 
    1535            0 :         default:
    1536              :         {
    1537            0 :             U8_LOG_ERROR( "invalid data in data_id_t." );
    1538              :         }
    1539            0 :         break;
    1540              :     }
    1541              : 
    1542            0 :     U8_TRACE_END();
    1543            0 : }
    1544              : 
    1545            0 : void gui_attributes_editor_private_type_update_view ( gui_attributes_editor_t *this_ )
    1546              : {
    1547            0 :     U8_TRACE_BEGIN();
    1548            0 :     GtkDropDown *type_widget = (*this_).type_dropdown;
    1549              : 
    1550            0 :     switch ( data_id_get_table( &((*this_).selected_object_id ) ) )
    1551              :     {
    1552            0 :         case DATA_TABLE_VOID:
    1553              :         {
    1554            0 :             gtk_widget_set_visible( GTK_WIDGET ( type_widget ), FALSE );
    1555            0 :             GListStore *const undef_type_list = gui_type_resource_list_get_undef( &((*this_).type_lists) );
    1556            0 :             gtk_drop_down_set_model( (*this_).type_dropdown, G_LIST_MODEL( undef_type_list ) );
    1557              : 
    1558              :             /* hide icon grid: */
    1559            0 :             gtk_widget_set_visible( (*this_).type_diag_grid, FALSE );
    1560            0 :             gtk_widget_set_visible( (*this_).type_clas_grid, FALSE );
    1561            0 :             gtk_widget_set_visible( (*this_).type_feat_grid, FALSE );
    1562            0 :             gtk_widget_set_visible( (*this_).type_rel_grid, FALSE );
    1563              :         }
    1564            0 :         break;
    1565              : 
    1566            0 :         case DATA_TABLE_CLASSIFIER:
    1567              :         {
    1568            0 :             const data_classifier_type_t class_type = data_classifier_get_main_type( &((*this_).private_classifier_cache) );
    1569            0 :             GListStore *const classifier_type_list = gui_type_resource_list_get_classifiers( &((*this_).type_lists) );
    1570            0 :             gtk_drop_down_set_model( (*this_).type_dropdown, G_LIST_MODEL( classifier_type_list ) );
    1571              :             guint selected_pos;
    1572            0 :             gui_type_resource_init_classifier( (*this_).temp_search_me, class_type, "", NULL );  /* type, name, icon */
    1573            0 :             const gboolean found = g_list_store_find_with_equal_func( classifier_type_list,
    1574            0 :                                                                       (*this_).temp_search_me,
    1575              :                                                                       (GEqualFunc)&gui_type_resource_equal,
    1576              :                                                                       &selected_pos
    1577              :                                                                     );
    1578            0 :             if ( found )
    1579              :             {
    1580            0 :                 gtk_drop_down_set_selected( (*this_).type_dropdown, selected_pos );
    1581              :             }
    1582            0 :             gtk_widget_set_visible( GTK_WIDGET ( type_widget ), TRUE );
    1583              : 
    1584              :             /* show classifier icon grid: */
    1585            0 :             gtk_widget_set_visible( (*this_).type_diag_grid, FALSE );
    1586            0 :             gtk_widget_set_visible( (*this_).type_clas_grid, TRUE );
    1587            0 :             gtk_widget_set_visible( (*this_).type_feat_grid, FALSE );
    1588            0 :             gtk_widget_set_visible( (*this_).type_rel_grid, FALSE );
    1589              :         }
    1590            0 :         break;
    1591              : 
    1592            0 :         case DATA_TABLE_FEATURE:
    1593              :         {
    1594            0 :             const data_feature_type_t feature_type = data_feature_get_main_type( &((*this_).private_feature_cache) );
    1595            0 :             if ( DATA_FEATURE_TYPE_LIFELINE == feature_type )
    1596              :             {
    1597            0 :                 GListStore *const lifeline_type_list = gui_type_resource_list_get_feature_lifeline( &((*this_).type_lists) );
    1598            0 :                 gtk_drop_down_set_model( (*this_).type_dropdown, G_LIST_MODEL( lifeline_type_list ) );
    1599              :                 guint selected_pos;
    1600            0 :                 gui_type_resource_init_feature( (*this_).temp_search_me, feature_type, "", NULL ); /* type, name, icon */
    1601            0 :                 const gboolean found = g_list_store_find_with_equal_func( lifeline_type_list,
    1602            0 :                                                                           (*this_).temp_search_me,
    1603              :                                                                           (GEqualFunc)&gui_type_resource_equal,
    1604              :                                                                           &selected_pos
    1605              :                                                                         );
    1606            0 :                 if ( found )
    1607              :                 {
    1608            0 :                     gtk_drop_down_set_selected( (*this_).type_dropdown, selected_pos );
    1609              :                 }
    1610            0 :                 gtk_widget_set_visible( GTK_WIDGET ( type_widget ), TRUE );
    1611              : 
    1612              :                 /* hide  icon grid: */
    1613            0 :                 gtk_widget_set_visible( (*this_).type_diag_grid, FALSE );
    1614            0 :                 gtk_widget_set_visible( (*this_).type_clas_grid, FALSE );
    1615            0 :                 gtk_widget_set_visible( (*this_).type_feat_grid, FALSE );
    1616            0 :                 gtk_widget_set_visible( (*this_).type_rel_grid, FALSE );
    1617              :             }
    1618              :             else
    1619              :             {
    1620            0 :                 GListStore *const feature_type_list = gui_type_resource_list_get_features( &((*this_).type_lists) );
    1621            0 :                 gtk_drop_down_set_model( (*this_).type_dropdown, G_LIST_MODEL( feature_type_list ) );
    1622              :                 guint selected_pos;
    1623            0 :                 gui_type_resource_init_feature( (*this_).temp_search_me, feature_type, "", NULL ); /* type, name, icon */
    1624            0 :                 const gboolean found = g_list_store_find_with_equal_func( feature_type_list,
    1625            0 :                                                                           (*this_).temp_search_me,
    1626              :                                                                           (GEqualFunc)&gui_type_resource_equal,
    1627              :                                                                           &selected_pos
    1628              :                                                                         );
    1629            0 :                 if ( found )
    1630              :                 {
    1631            0 :                     gtk_drop_down_set_selected( (*this_).type_dropdown, selected_pos );
    1632              :                 }
    1633            0 :                 gtk_widget_set_visible( GTK_WIDGET ( type_widget ), TRUE );
    1634              : 
    1635              :                 /* show feature icon grid: */
    1636            0 :                 gtk_widget_set_visible( (*this_).type_diag_grid, FALSE );
    1637            0 :                 gtk_widget_set_visible( (*this_).type_clas_grid, FALSE );
    1638            0 :                 gtk_widget_set_visible( (*this_).type_feat_grid, TRUE );
    1639            0 :                 gtk_widget_set_visible( (*this_).type_rel_grid, FALSE );
    1640              :             }
    1641              :         }
    1642            0 :         break;
    1643              : 
    1644            0 :         case DATA_TABLE_RELATIONSHIP:
    1645              :         {
    1646              :             const data_relationship_type_t relationship_type
    1647            0 :                 = data_relationship_get_main_type( &((*this_).private_relationship_cache) );
    1648            0 :             GListStore *const relationship_type_list = gui_type_resource_list_get_relationships( &((*this_).type_lists) );
    1649            0 :             gtk_drop_down_set_model( (*this_).type_dropdown, G_LIST_MODEL( relationship_type_list ) );
    1650              :             guint selected_pos;
    1651            0 :             gui_type_resource_init_relationship( (*this_).temp_search_me, relationship_type, "", NULL ); /* type, name, icon */
    1652            0 :             const gboolean found = g_list_store_find_with_equal_func( relationship_type_list,
    1653            0 :                                                                       (*this_).temp_search_me,
    1654              :                                                                       (GEqualFunc)&gui_type_resource_equal,
    1655              :                                                                       &selected_pos
    1656              :                                                                     );
    1657            0 :             if ( found )
    1658              :             {
    1659            0 :                 gtk_drop_down_set_selected( (*this_).type_dropdown, selected_pos );
    1660              :             }
    1661            0 :             gtk_widget_set_visible( GTK_WIDGET ( type_widget ), TRUE );
    1662              : 
    1663              :             /* show relationship icon grid: */
    1664            0 :             gtk_widget_set_visible( (*this_).type_diag_grid, FALSE );
    1665            0 :             gtk_widget_set_visible( (*this_).type_clas_grid, FALSE );
    1666            0 :             gtk_widget_set_visible( (*this_).type_feat_grid, FALSE );
    1667            0 :             gtk_widget_set_visible( (*this_).type_rel_grid, TRUE );
    1668              :         }
    1669            0 :         break;
    1670              : 
    1671            0 :         case DATA_TABLE_DIAGRAMELEMENT:
    1672              :         {
    1673            0 :             gtk_widget_set_visible( GTK_WIDGET ( type_widget ), FALSE );
    1674            0 :             GListStore *const undef_type_list = gui_type_resource_list_get_undef( &((*this_).type_lists) );
    1675            0 :             gtk_drop_down_set_model( (*this_).type_dropdown, G_LIST_MODEL( undef_type_list ) );
    1676              : 
    1677              :             /* hide icon grid: */
    1678            0 :             gtk_widget_set_visible( (*this_).type_diag_grid, FALSE );
    1679            0 :             gtk_widget_set_visible( (*this_).type_clas_grid, FALSE );
    1680            0 :             gtk_widget_set_visible( (*this_).type_feat_grid, FALSE );
    1681            0 :             gtk_widget_set_visible( (*this_).type_rel_grid, FALSE );
    1682              :         }
    1683            0 :         break;
    1684              : 
    1685            0 :         case DATA_TABLE_DIAGRAM:
    1686              :         {
    1687            0 :             const data_diagram_type_t diag_type = data_diagram_get_diagram_type( &((*this_).private_diagram_cache) );
    1688            0 :             GListStore *const diagram_type_list = gui_type_resource_list_get_diagrams( &((*this_).type_lists) );
    1689            0 :             gtk_drop_down_set_model( (*this_).type_dropdown, G_LIST_MODEL( diagram_type_list ) );
    1690              :             guint selected_pos;
    1691            0 :             gui_type_resource_init_diagram( (*this_).temp_search_me, diag_type, "", NULL ); /* type, name, icon */
    1692            0 :             const gboolean found = g_list_store_find_with_equal_func( diagram_type_list,
    1693            0 :                                                                       (*this_).temp_search_me,
    1694              :                                                                       (GEqualFunc)&gui_type_resource_equal,
    1695              :                                                                       &selected_pos
    1696              :                                                                     );
    1697            0 :             if ( found )
    1698              :             {
    1699            0 :                 gtk_drop_down_set_selected( (*this_).type_dropdown, selected_pos );
    1700              :             }
    1701            0 :             gtk_widget_set_visible( GTK_WIDGET ( type_widget ), TRUE );
    1702              : 
    1703              :             /* show diagram icon grid: */
    1704            0 :             gtk_widget_set_visible( (*this_).type_diag_grid, TRUE );
    1705            0 :             gtk_widget_set_visible( (*this_).type_clas_grid, FALSE );
    1706            0 :             gtk_widget_set_visible( (*this_).type_feat_grid, FALSE );
    1707            0 :             gtk_widget_set_visible( (*this_).type_rel_grid, FALSE );
    1708              :         }
    1709            0 :         break;
    1710              : 
    1711            0 :         default:
    1712              :         {
    1713            0 :             U8_LOG_ERROR( "invalid data in data_id_t." );
    1714              :         }
    1715            0 :         break;
    1716              :     }
    1717              : 
    1718            0 :     U8_TRACE_END();
    1719            0 : }
    1720              : 
    1721            0 : void gui_attributes_editor_private_description_update_view ( gui_attributes_editor_t *this_ )
    1722              : {
    1723            0 :     U8_TRACE_BEGIN();
    1724              : 
    1725              :     GtkTextView *description_widget;
    1726              :     GtkTextBuffer *buffer;
    1727            0 :     description_widget = GTK_TEXT_VIEW( (*this_).description_text_view );
    1728            0 :     buffer = gtk_text_view_get_buffer ( GTK_TEXT_VIEW( description_widget ) );
    1729              : 
    1730            0 :     switch ( data_id_get_table( &((*this_).selected_object_id ) ) )
    1731              :     {
    1732            0 :         case DATA_TABLE_VOID:
    1733              :         {
    1734              :             /* prevent that a user accitentially enters text to a non-existing object */
    1735            0 :             gtk_widget_set_visible( GTK_WIDGET ( description_widget ), FALSE );
    1736              :         }
    1737            0 :         break;
    1738              : 
    1739            0 :         case DATA_TABLE_CLASSIFIER:
    1740              :         {
    1741            0 :             gtk_widget_set_visible( GTK_WIDGET ( description_widget ), TRUE );
    1742              : 
    1743              :             const char* text;
    1744            0 :             text = data_classifier_get_description_const( &((*this_).private_classifier_cache) );
    1745            0 :             gtk_text_buffer_set_text ( buffer, text, -1 /*len*/ );
    1746              :         }
    1747            0 :         break;
    1748              : 
    1749            0 :         case DATA_TABLE_FEATURE:
    1750              :         {
    1751            0 :             gtk_widget_set_visible( GTK_WIDGET ( description_widget ), TRUE );
    1752              : 
    1753              :             const char* text;
    1754            0 :             text = data_feature_get_description_const( &((*this_).private_feature_cache) );
    1755            0 :             gtk_text_buffer_set_text ( buffer, text, -1 /*len*/ );
    1756              :         }
    1757            0 :         break;
    1758              : 
    1759            0 :         case DATA_TABLE_RELATIONSHIP:
    1760              :         {
    1761            0 :             gtk_widget_set_visible( GTK_WIDGET ( description_widget ), TRUE );
    1762              : 
    1763              :             const char* text;
    1764            0 :             text = data_relationship_get_description_const( &((*this_).private_relationship_cache) );
    1765            0 :             gtk_text_buffer_set_text ( buffer, text, -1 /*len*/ );
    1766              :         }
    1767            0 :         break;
    1768              : 
    1769            0 :         case DATA_TABLE_DIAGRAMELEMENT:
    1770              :         {
    1771            0 :             gtk_widget_set_visible( GTK_WIDGET ( description_widget ), FALSE );
    1772              :         }
    1773            0 :         break;
    1774              : 
    1775            0 :         case DATA_TABLE_DIAGRAM:
    1776              :         {
    1777            0 :             gtk_widget_set_visible( GTK_WIDGET ( description_widget ), TRUE );
    1778              : 
    1779              :             const char* text;
    1780            0 :             text = data_diagram_get_description_const( &((*this_).private_diagram_cache) );
    1781            0 :             gtk_text_buffer_set_text ( buffer, text, -1 /*len*/ );
    1782              :         }
    1783            0 :         break;
    1784              : 
    1785            0 :         default:
    1786              :         {
    1787            0 :             U8_LOG_ERROR( "invalid data in data_id_t." );
    1788              :         }
    1789            0 :         break;
    1790              :     }
    1791              : 
    1792            0 :     U8_TRACE_END();
    1793            0 : }
    1794              : 
    1795              : 
    1796              : /*
    1797              : Copyright 2016-2026 Andreas Warnke
    1798              : 
    1799              : Licensed under the Apache License, Version 2.0 (the "License");
    1800              : you may not use this file except in compliance with the License.
    1801              : You may obtain a copy of the License at
    1802              : 
    1803              :     http://www.apache.org/licenses/LICENSE-2.0
    1804              : 
    1805              : Unless required by applicable law or agreed to in writing, software
    1806              : distributed under the License is distributed on an "AS IS" BASIS,
    1807              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    1808              : See the License for the specific language governing permissions and
    1809              : limitations under the License.
    1810              : */
        

Generated by: LCOV version 2.0-1