LCOV - code coverage report
Current view: top level - gui/source - gui_main_window.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.57.0_covts Lines: 0 597 0.0 %
Date: 2024-04-07 11:14:42 Functions: 0 17 0.0 %

          Line data    Source code
       1             : /* File: gui_main_window.c; Copyright and License: see below */
       2             : 
       3             : #include "gui_main_window.h"
       4             : #include "gui_clipboard.h"
       5             : #include "gui_type_resource.h"
       6             : #include "u8/u8_trace.h"
       7             : #include "data_diagram_type.h"
       8             : #include "data_classifier_type.h"
       9             : #include "data_feature_type.h"
      10             : #include "data_relationship_type.h"
      11             : #include "storage/data_database.h"
      12             : #include "storage/data_change_notifier.h"
      13             : #include "meta/meta_info.h"
      14             : #ifndef NDEBUG
      15             : #include "u8stream/universal_stream_output_stream.h"
      16             : #include "utf8stream/utf8stream_writer.h"
      17             : #endif  /* not NDEBUG */
      18             : #include <gdk/gdk.h>
      19             : #include <gtk/gtk.h>
      20             : #include <stdio.h>
      21             : #include <stdbool.h>
      22             : 
      23           0 : void gui_main_window_init( gui_main_window_t *this_,
      24             :                            ctrl_controller_t *controller,
      25             :                            io_data_file_t *data_file,
      26             :                            data_database_reader_t *db_reader,
      27             :                            gui_resources_t *res,
      28             :                            GtkApplication *gtk_app,
      29             :                            observer_t *window_close_observer,
      30             :                            observer_t *window_open_observer )
      31             : {
      32           0 :     U8_TRACE_BEGIN();
      33           0 :     assert( gtk_app != NULL );
      34             : 
      35             :     /* init own attributes */
      36           0 :     (*this_).window_close_observer = window_close_observer;
      37           0 :     (*this_).window_open_observer = window_open_observer;
      38           0 :     (*this_).data_file = data_file;
      39             : #ifndef NDEBUG
      40           0 :     (*this_).controller = controller;
      41             : #endif  /* not NDEBUG */
      42             : 
      43             :     /* init window */
      44             :     {
      45           0 :         (*this_).window = gtk_application_window_new( gtk_app );
      46             :         const char *window_title;
      47           0 :         window_title = io_data_file_get_filename_const( data_file );
      48           0 :         gtk_window_set_title(GTK_WINDOW( (*this_).window ), ( window_title == NULL ) ? META_INFO_PROGRAM_NAME_STR : window_title );
      49           0 :         gtk_widget_set_size_request( (*this_).window, 800, 400 );
      50           0 :         gtk_window_set_default_size( GTK_WINDOW( (*this_).window ), 16*70, 9*70 );
      51             :     }
      52             : 
      53             :     /* init the message widgets */
      54           0 :     gui_main_window_private_init_simple_message_to_user( this_, res );
      55           0 :     gui_simple_message_to_user_init( &((*this_).message_to_user), (*this_).message_text_label, (*this_).message_icon_image, res );
      56             : 
      57             :     /* init the keyboard shortcuts */
      58             :     {
      59           0 :         (*this_).keyboard_shortcut_ctrl = GTK_SHORTCUT_CONTROLLER(gtk_shortcut_controller_new());
      60           0 :         gtk_widget_add_controller( (*this_).window, GTK_EVENT_CONTROLLER((*this_).keyboard_shortcut_ctrl) );
      61             :     }
      62             : 
      63             :     /* init tools */
      64           0 :     gui_main_window_private_init_toolbox( this_, res );
      65             : 
      66             :     /* determine the current/main clipboard */
      67           0 :     GdkClipboard *current_clipboard = NULL;
      68             :     {
      69           0 :         current_clipboard = gtk_widget_get_clipboard( GTK_WIDGET((*this_).window) );  /* idea taken from gtk demo */
      70             :     }
      71             : 
      72           0 :     gui_marked_set_init( &((*this_).marker_data), G_OBJECT((*this_).window) );
      73           0 :     gui_toolbox_init( &((*this_).tools_data),
      74           0 :                       GTK_WIDGET((*this_).tool_row),
      75           0 :                       GTK_WIDGET((*this_).view_navigate),
      76           0 :                       GTK_WIDGET((*this_).view_edit),
      77           0 :                       GTK_WIDGET((*this_).view_create),
      78           0 :                       GTK_WIDGET((*this_).view_search),
      79             :                       current_clipboard,
      80             :                       &((*this_).marker_data),
      81             :                       &((*this_).message_to_user),
      82             :                       db_reader,
      83             :                       controller
      84             :                     );
      85             : 
      86             :     /* init search widgets and sketch area */
      87           0 :     gui_main_window_private_init_search_and_sketch_area( this_, res );
      88           0 :     gui_search_runner_init( &((*this_).search_runner),
      89             :                             &((*this_).message_to_user),
      90             :                             db_reader,
      91             :                             io_data_file_get_database_ptr( data_file ),
      92             :                             &((*this_).sketcharea_data)
      93             :                           );
      94           0 :     gui_search_request_init( &((*this_).search_request),
      95             :                              (*this_).search_label,
      96             :                              (*this_).search_entry,
      97             :                              (*this_).search_button,
      98             :                              &((*this_).marker_data),
      99             :                              &((*this_).search_runner)
     100             :                            );
     101           0 :     gui_sketch_area_init( &((*this_).sketcharea_data),
     102             :                           (*this_).sketcharea,
     103             :                           &((*this_).marker_data),
     104             :                           &((*this_).tools_data),
     105             :                           &((*this_).message_to_user),
     106             :                           res,
     107             :                           controller,
     108             :                           db_reader
     109             :                         );
     110             : 
     111             :     /* init attribute editor widgets */
     112           0 :     gui_main_window_private_init_attributes_editor( this_, res );
     113             : 
     114           0 :     gui_attributes_editor_init( &((*this_).attributes_editor),
     115           0 :                                 GTK_LABEL( (*this_).id_label ),
     116           0 :                                 GTK_ENTRY( (*this_).name_entry ),
     117           0 :                                 GTK_ENTRY( (*this_).stereotype_entry ),
     118             :                                 (*this_).type_dropdown,
     119           0 :                                 GTK_WIDGET( (*this_).type_diag_grid ),
     120           0 :                                 GTK_WIDGET( (*this_).type_clas_grid ),
     121           0 :                                 GTK_WIDGET( (*this_).type_feat_grid ),
     122           0 :                                 GTK_WIDGET( (*this_).type_rel_grid ),
     123           0 :                                 GTK_TEXT_VIEW( (*this_).description_text_view ),
     124           0 :                                 GTK_BUTTON( (*this_).file_save_button ),
     125             :                                 res,
     126             :                                 controller,
     127             :                                 db_reader,
     128             :                                 io_data_file_get_database_ptr( data_file ),
     129             :                                 &((*this_).message_to_user)
     130             :                               );
     131             : 
     132             :     /* init the file choosers */
     133           0 :     gui_file_use_db_dialog_init( &((*this_).file_use_db_dialog),
     134             :                                  controller,
     135             :                                  data_file,
     136           0 :                                  GTK_WINDOW( (*this_).window ),
     137             :                                  &((*this_).message_to_user)
     138             :                                );
     139           0 :     gui_file_export_dialog_init( &((*this_).file_export_dialog),
     140             :                                  io_data_file_get_database_ptr( data_file ),
     141             :                                  db_reader,
     142           0 :                                  GTK_WINDOW( (*this_).window ),
     143             :                                  &((*this_).message_to_user)
     144             :                                );
     145             : 
     146           0 :     U8_TRACE_INFO("GTK+ Widgets are created.");
     147             : 
     148           0 :     (*this_).two_panes = gtk_paned_new( GTK_ORIENTATION_HORIZONTAL );
     149           0 :     gtk_paned_set_start_child( GTK_PANED((*this_).two_panes), (*this_).sketch_stack_column );
     150           0 :     gtk_paned_set_resize_start_child( GTK_PANED((*this_).two_panes), true );
     151           0 :     gtk_paned_set_shrink_start_child( GTK_PANED((*this_).two_panes), false );
     152           0 :     gtk_paned_set_end_child( GTK_PANED((*this_).two_panes), (*this_).attr_edit_column );
     153           0 :     gtk_paned_set_resize_end_child( GTK_PANED((*this_).two_panes), false );
     154           0 :     gtk_paned_set_shrink_end_child( GTK_PANED((*this_).two_panes), true );
     155           0 :     gtk_widget_set_vexpand( GTK_WIDGET( (*this_).sketch_stack_column ), true );
     156           0 :     gtk_widget_set_hexpand( GTK_WIDGET( (*this_).sketch_stack_column ), true );
     157           0 :     gtk_widget_set_vexpand( GTK_WIDGET( (*this_).attr_edit_column ), true );
     158           0 :     gtk_widget_set_hexpand( GTK_WIDGET( (*this_).attr_edit_column ), false );
     159           0 :     gtk_paned_set_position( GTK_PANED((*this_).two_panes), 11*70 );
     160             : 
     161           0 :     (*this_).main_stack_column = gtk_box_new( GTK_ORIENTATION_VERTICAL, /*spacing:*/ 0 );
     162           0 :     gtk_box_append( GTK_BOX((*this_).main_stack_column), GTK_WIDGET((*this_).tool_row) );
     163           0 :     (*this_).options_layout = gui_file_export_dialog_get_options( &((*this_).file_export_dialog) );
     164           0 :     gtk_box_append( GTK_BOX((*this_).main_stack_column), (*this_).options_layout );
     165           0 :     gtk_box_append( GTK_BOX((*this_).main_stack_column), GTK_WIDGET((*this_).two_panes) );
     166           0 :     gtk_box_append( GTK_BOX((*this_).main_stack_column), GTK_WIDGET((*this_).message_row) );
     167           0 :     gtk_widget_set_vexpand( GTK_WIDGET( (*this_).tool_row ), false );
     168           0 :     gtk_widget_set_hexpand( GTK_WIDGET( (*this_).tool_row ), true );
     169           0 :     gtk_widget_set_vexpand( GTK_WIDGET( (*this_).two_panes ), true );
     170           0 :     gtk_widget_set_hexpand( GTK_WIDGET( (*this_).two_panes ), true );
     171           0 :     gtk_widget_set_vexpand( GTK_WIDGET( (*this_).message_row ), false );
     172           0 :     gtk_widget_set_hexpand( GTK_WIDGET( (*this_).message_row ), true );
     173             : 
     174           0 :     gtk_window_set_child( GTK_WINDOW((*this_).window), (*this_).main_stack_column );
     175           0 :     gtk_window_set_resizable( GTK_WINDOW((*this_).window), true );
     176             : 
     177           0 :     U8_TRACE_INFO("GTK+ Widgets are added to containers.");
     178             : 
     179             :     /* inject dependencies by signals */
     180             :     /* parameter info: g_signal_connect( instance-that-emits-the-signal, signal-name, callback-handler, data-to-be-passed-to-callback-handler) */
     181           0 :     g_signal_connect( G_OBJECT((*this_).window), "close-request", G_CALLBACK(gui_main_window_delete_event_callback), this_ );
     182           0 :     g_signal_connect( G_OBJECT((*this_).window), "destroy", G_CALLBACK(gui_main_window_destroy_event_callback), this_ );
     183           0 :     g_signal_connect( G_OBJECT((*this_).window), DATA_CHANGE_NOTIFIER_GLIB_SIGNAL_NAME, G_CALLBACK(gui_main_window_data_changed_callback), this_ );
     184           0 :     g_signal_connect( G_OBJECT((*this_).sketcharea), DATA_CHANGE_NOTIFIER_GLIB_SIGNAL_NAME, G_CALLBACK(gui_sketch_area_data_changed_callback), &((*this_).sketcharea_data) );
     185           0 :     g_signal_connect( G_OBJECT((*this_).tool_row), GUI_TOOLBOX_GLIB_SIGNAL_NAME, G_CALLBACK(gui_sketch_area_tool_changed_callback), &((*this_).sketcharea_data) );
     186           0 :     g_signal_connect( G_OBJECT((*this_).file_new_db), "clicked", G_CALLBACK(gui_main_window_new_db_btn_callback), this_ );
     187           0 :     g_signal_connect( G_OBJECT((*this_).file_use_db), "clicked", G_CALLBACK(gui_main_window_open_db_btn_callback), this_ );
     188           0 :     g_signal_connect( G_OBJECT((*this_).file_save_button), "clicked", G_CALLBACK(gui_main_window_save_btn_callback), this_ );
     189           0 :     g_signal_connect( G_OBJECT((*this_).file_export), "clicked", G_CALLBACK(gui_main_window_export_btn_callback), this_ );
     190           0 :     g_signal_connect( G_OBJECT((*this_).view_new_window), "clicked", G_CALLBACK(gui_main_window_new_window_btn_callback), this_ );
     191             : 
     192           0 :     gui_toolbox_t *const tools = &((*this_).tools_data);
     193           0 :     g_signal_connect( G_OBJECT((*this_).view_navigate), "clicked", G_CALLBACK(gui_toolbox_navigate_btn_callback), tools );
     194           0 :     g_signal_connect( G_OBJECT((*this_).view_edit), "clicked", G_CALLBACK(gui_toolbox_edit_btn_callback), tools );
     195           0 :     g_signal_connect( G_OBJECT((*this_).view_create), "clicked", G_CALLBACK(gui_toolbox_create_btn_callback), tools );
     196           0 :     g_signal_connect( G_OBJECT((*this_).view_search), "clicked", G_CALLBACK(gui_toolbox_search_btn_callback), tools );
     197             : 
     198             :     /* The search id button is connected to two callback functions: one to switch to search mode, one to perform a search: */
     199           0 :     g_signal_connect( G_OBJECT((*this_).id_search_btn),
     200             :                       "clicked",
     201             :                       G_CALLBACK(gui_toolbox_search_id_btn_callback),
     202             :                       tools
     203             :                     );
     204           0 :     g_signal_connect( G_OBJECT((*this_).id_search_btn),
     205             :                       "clicked",
     206             :                       G_CALLBACK(gui_search_request_id_search_callback),
     207             :                       &((*this_).search_request)
     208             :                     );
     209             : 
     210           0 :     g_signal_connect( G_OBJECT((*this_).tool_row), GUI_TOOLBOX_GLIB_SIGNAL_NAME, G_CALLBACK(gui_search_request_tool_changed_callback), &((*this_).search_request) );
     211           0 :     g_signal_connect( G_OBJECT((*this_).search_entry), DATA_CHANGE_NOTIFIER_GLIB_SIGNAL_NAME, G_CALLBACK(gui_search_request_data_changed_callback), &((*this_).search_request) );
     212           0 :     g_signal_connect( G_OBJECT((*this_).search_entry), "activate", G_CALLBACK(gui_search_request_search_start_callback), &((*this_).search_request) );
     213           0 :     g_signal_connect( G_OBJECT((*this_).search_button), "clicked", G_CALLBACK(gui_search_request_search_start_callback), &((*this_).search_request) );
     214             : 
     215           0 :     g_signal_connect( G_OBJECT((*this_).edit_undo), "clicked", G_CALLBACK(gui_toolbox_undo_btn_callback), tools );
     216           0 :     g_signal_connect( G_OBJECT((*this_).edit_redo), "clicked", G_CALLBACK(gui_toolbox_redo_btn_callback), tools );
     217           0 :     g_signal_connect( G_OBJECT((*this_).edit_cut), "clicked", G_CALLBACK(gui_toolbox_cut_btn_callback), tools );
     218           0 :     g_signal_connect( G_OBJECT((*this_).edit_copy), "clicked", G_CALLBACK(gui_toolbox_copy_btn_callback), tools );
     219           0 :     g_signal_connect( G_OBJECT((*this_).edit_paste), "clicked", G_CALLBACK(gui_toolbox_paste_btn_callback), tools );
     220           0 :     g_signal_connect( G_OBJECT((*this_).edit_delete), "clicked", G_CALLBACK(gui_toolbox_delete_btn_callback), tools );
     221           0 :     g_signal_connect( G_OBJECT((*this_).edit_instantiate), "clicked", G_CALLBACK(gui_toolbox_instantiate_btn_callback), tools );
     222           0 :     g_signal_connect( G_OBJECT((*this_).edit_highlight), "clicked", G_CALLBACK(gui_toolbox_highlight_btn_callback), tools );
     223           0 :     g_signal_connect( G_OBJECT((*this_).edit_reset), "clicked", G_CALLBACK(gui_toolbox_reset_btn_callback), tools );
     224             : 
     225           0 :     g_signal_connect( G_OBJECT((*this_).name_entry),
     226             :                       "activate",
     227             :                       G_CALLBACK(gui_attributes_editor_name_enter_callback),
     228             :                       &((*this_).attributes_editor)
     229             :                     );
     230             :     {
     231           0 :         GtkEventControllerFocus *evt_focus_n = GTK_EVENT_CONTROLLER_FOCUS(gtk_event_controller_focus_new());
     232           0 :         g_signal_connect( evt_focus_n,
     233             :                           "leave",
     234             :                           G_CALLBACK(gui_attributes_editor_name_focus_left_callback),
     235             :                           &((*this_).attributes_editor)
     236             :                         );
     237           0 :         gtk_widget_add_controller( (*this_).name_entry, GTK_EVENT_CONTROLLER(evt_focus_n) );
     238             :     }
     239             :     {
     240           0 :         GtkEventControllerFocus *evt_focus_s = GTK_EVENT_CONTROLLER_FOCUS(gtk_event_controller_focus_new());
     241           0 :         g_signal_connect( evt_focus_s,
     242             :                           "leave",
     243             :                           G_CALLBACK(gui_attributes_editor_stereotype_focus_left_callback),
     244             :                           &((*this_).attributes_editor)
     245             :                         );
     246           0 :         gtk_widget_add_controller( (*this_).stereotype_entry, GTK_EVENT_CONTROLLER(evt_focus_s) );
     247             :     }
     248             :     {
     249           0 :         GtkEventControllerFocus *evt_focus_d = GTK_EVENT_CONTROLLER_FOCUS(gtk_event_controller_focus_new());
     250           0 :         g_signal_connect( evt_focus_d,
     251             :                           "leave",
     252             :                           G_CALLBACK(gui_attributes_editor_description_focus_left_callback),
     253             :                           &((*this_).attributes_editor)
     254             :                         );
     255           0 :         gtk_widget_add_controller( (*this_).description_text_view, GTK_EVENT_CONTROLLER(evt_focus_d) );
     256             :     }
     257           0 :     g_signal_connect( G_OBJECT((*this_).stereotype_entry), "activate", G_CALLBACK(gui_attributes_editor_stereotype_enter_callback), &((*this_).attributes_editor) );
     258           0 :     g_signal_connect_after( G_OBJECT((*this_).type_dropdown), "notify::selected", G_CALLBACK(gui_attributes_editor_type_changed_callback), &((*this_).attributes_editor));
     259           0 :     for( int_fast32_t diag_idx = 0; diag_idx < GUI_TYPE_RESOURCE_LIST_DIAGRAMS; diag_idx ++ )
     260             :     {
     261           0 :         g_signal_connect( G_OBJECT((*this_).type_diag_btn[ diag_idx ]),
     262             :                           "clicked",
     263             :                           G_CALLBACK( gui_attributes_editor_type_of_diagram_btn_callback ),
     264             :                           &((*this_).type_diag_data[diag_idx])
     265             :                         );
     266             :     }
     267           0 :     for( int_fast32_t clas_idx = 0; clas_idx < GUI_TYPE_RESOURCE_LIST_CLASSIFIERS; clas_idx ++ )
     268             :     {
     269           0 :         g_signal_connect( G_OBJECT((*this_).type_clas_btn[ clas_idx ]),
     270             :                           "clicked",
     271             :                           G_CALLBACK( gui_attributes_editor_type_of_classifier_btn_callback ),
     272             :                           &((*this_).type_clas_data[clas_idx])
     273             :                         );
     274             :     }
     275           0 :     for( int_fast32_t feat_idx = 0; feat_idx < GUI_TYPE_RESOURCE_LIST_INV_FEATURES; feat_idx ++ )
     276             :     {
     277           0 :         g_signal_connect( G_OBJECT((*this_).type_feat_btn[ feat_idx ]),
     278             :                           "clicked",
     279             :                           G_CALLBACK( gui_attributes_editor_type_of_feature_btn_callback ),
     280             :                           &((*this_).type_feat_data[feat_idx])
     281             :                         );
     282             :     }
     283           0 :     for( int_fast32_t rel_idx = 0; rel_idx < GUI_TYPE_RESOURCE_LIST_RELATIONS; rel_idx ++ )
     284             :     {
     285           0 :         g_signal_connect( G_OBJECT((*this_).type_rel_btn[ rel_idx ]),
     286             :                           "clicked",
     287             :                           G_CALLBACK( gui_attributes_editor_type_of_relationship_btn_callback ),
     288             :                           &((*this_).type_rel_data[rel_idx])
     289             :                         );
     290             :     }
     291           0 :     g_signal_connect( G_OBJECT((*this_).window), GUI_MARKED_SET_GLIB_SIGNAL_NAME, G_CALLBACK(gui_attributes_editor_focused_object_changed_callback), &((*this_).attributes_editor) );
     292           0 :     g_signal_connect( G_OBJECT((*this_).name_entry), DATA_CHANGE_NOTIFIER_GLIB_SIGNAL_NAME, G_CALLBACK(gui_attributes_editor_data_changed_callback), &((*this_).attributes_editor) );
     293             :         /* ^-- name_entry is the  proxy for all widgets of attributes_editor */
     294             : 
     295           0 :     g_signal_connect( G_OBJECT((*this_).tool_about), "clicked", G_CALLBACK(gui_main_window_about_btn_callback), this_ );
     296             : 
     297           0 :     U8_TRACE_INFO("GTK+ Callbacks are connected to widget events.");
     298             : 
     299             :     /* register observers */
     300             : 
     301           0 :     (*this_).data_notifier = data_database_get_notifier_ptr( io_data_file_get_database_ptr( data_file ) );
     302           0 :     data_change_notifier_add_listener( (*this_).data_notifier, G_OBJECT((*this_).window) );
     303           0 :     data_change_notifier_add_listener( (*this_).data_notifier, G_OBJECT((*this_).sketcharea) );
     304           0 :     data_change_notifier_add_listener( (*this_).data_notifier, G_OBJECT((*this_).name_entry) );
     305             :         /* ^-- name_entry is the  proxy for all widgets of attributes_editor */
     306           0 :     data_change_notifier_add_listener( (*this_).data_notifier, G_OBJECT((*this_).search_entry) );
     307             : 
     308           0 :     U8_TRACE_INFO("GTK+ Widgets are registered as listeners at signal emitter.");
     309             : 
     310           0 :     gtk_widget_set_visible( (*this_).window, TRUE );
     311           0 :     gtk_widget_set_sensitive( GTK_WIDGET((*this_).window), TRUE );  /* idea taken from gtk demo */
     312             : 
     313           0 :     GdkSurface *surface = gtk_native_get_surface( GTK_NATIVE((*this_).window) );
     314           0 :     gdk_surface_set_cursor( surface, NULL );  /* idea taken from gtk3->4 guide */
     315             : 
     316           0 :     gui_attributes_editor_update_widgets( &((*this_).attributes_editor) );  /* hide some widgets again */
     317             : #ifdef NDEBUG
     318             :     gui_simple_message_to_user_hide( &((*this_).message_to_user) );
     319             : #else
     320           0 :     gui_simple_message_to_user_show_message ( &((*this_).message_to_user), GUI_SIMPLE_MESSAGE_TYPE_INFO, GUI_SIMPLE_MESSAGE_CONTENT_DEBUG_MODE );
     321             : #endif
     322           0 :     gui_search_request_hide( &((*this_).search_request) );
     323           0 :     U8_TRACE_INFO("GTK+ Widgets are shown.");
     324           0 :     U8_TRACE_END();
     325           0 : }
     326             : 
     327           0 : void gui_main_window_destroy( gui_main_window_t *this_ )
     328             : {
     329           0 :     U8_TRACE_BEGIN();
     330             : 
     331             :     /* Note: The widgets may be destroyed already. A cast by G_OBJECT is therefore illegal. */
     332           0 :     data_change_notifier_remove_listener( (*this_).data_notifier, (GObject*)(*this_).window );
     333           0 :     data_change_notifier_remove_listener( (*this_).data_notifier, (GObject*)(*this_).name_entry );
     334           0 :     data_change_notifier_remove_listener( (*this_).data_notifier, (GObject*)(*this_).sketcharea );
     335           0 :     data_change_notifier_remove_listener( (*this_).data_notifier, (GObject*)(*this_).search_entry );
     336             : 
     337           0 :     U8_TRACE_INFO("GTK+ Widgets are unregistered as listeners from data module.");
     338           0 :     gui_file_export_dialog_destroy ( &((*this_).file_export_dialog) );
     339           0 :     gui_file_use_db_dialog_destroy ( &((*this_).file_use_db_dialog) );
     340           0 :     U8_TRACE_INFO("GTK+ hidden windows are destroyed.");
     341             : 
     342           0 :     gui_search_request_destroy( &((*this_).search_request) );
     343           0 :     gui_search_runner_destroy( &((*this_).search_runner) );
     344           0 :     gui_sketch_area_destroy( &((*this_).sketcharea_data) );
     345           0 :     gui_toolbox_destroy( &((*this_).tools_data) );
     346           0 :     gui_marked_set_destroy( &((*this_).marker_data) );
     347           0 :     gui_attributes_editor_destroy( &((*this_).attributes_editor) );
     348           0 :     gui_simple_message_to_user_destroy( &((*this_).message_to_user) );
     349           0 :     (*this_).data_file = NULL;
     350             : #ifndef NDEBUG
     351           0 :     (*this_).controller = NULL;
     352             : #endif  /* not NDEBUG */
     353             : 
     354           0 :     U8_TRACE_END();
     355           0 : }
     356             : 
     357           0 : static inline void gtk_button_set_image( GtkButton *btn, GtkWidget *icon )
     358             : {
     359           0 :     gtk_button_set_child( btn, icon );
     360           0 : }
     361             : 
     362           0 : void gui_main_window_private_init_toolbox( gui_main_window_t *this_, gui_resources_t *res )
     363             : {
     364           0 :     U8_TRACE_BEGIN();
     365             : 
     366           0 :     (*this_).file_new_db_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_file_new_db( res ) ) );
     367           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).file_new_db_icon), 32 /*=w*/ , 32 /*=h*/ );
     368           0 :     (*this_).file_new_db = GTK_BUTTON(gtk_button_new());
     369           0 :     gtk_button_set_image( GTK_BUTTON((*this_).file_new_db), (*this_).file_new_db_icon );
     370           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).file_new_db), "New DB" );
     371             : 
     372           0 :     (*this_).file_use_db_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_file_use_db( res ) ) );
     373           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).file_use_db_icon), 32 /*=w*/ , 32 /*=h*/ );
     374           0 :     (*this_).file_use_db = GTK_BUTTON(gtk_button_new());
     375           0 :     gtk_button_set_image( GTK_BUTTON((*this_).file_use_db), (*this_).file_use_db_icon );
     376           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).file_use_db), "Open DB" );
     377             : 
     378           0 :     (*this_).file_save_button = gtk_button_new();
     379           0 :     (*this_).file_save_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_file_save( res ) ) );
     380           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).file_save_icon), 32 /*=w*/ , 32 /*=h*/ );
     381           0 :     gtk_button_set_image( GTK_BUTTON((*this_).file_save_button), (*this_).file_save_icon );
     382           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).file_save_button), "Save (Ctrl-S)" );
     383           0 :     GtkShortcutTrigger *commit_trig = gtk_shortcut_trigger_parse_string( "<Control>S" );
     384           0 :     GtkShortcutAction *commit_act = gtk_callback_action_new( &gui_main_window_save_shortcut_callback,
     385             :                                                              this_,
     386             :                                                              NULL
     387             :                                                            );
     388           0 :     GtkShortcut* ctrl_s = gtk_shortcut_new_with_arguments( commit_trig,
     389             :                                                            commit_act,
     390             :                                                            NULL /* = format_string */
     391             :                                                          );
     392           0 :     gtk_shortcut_controller_add_shortcut( (*this_).keyboard_shortcut_ctrl, ctrl_s );
     393             : 
     394           0 :     (*this_).file_export_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_file_export( res ) ) );
     395           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).file_export_icon), 32 /*=w*/ , 32 /*=h*/ );
     396           0 :     (*this_).file_export = GTK_BUTTON(gtk_button_new());
     397           0 :     gtk_button_set_image( GTK_BUTTON((*this_).file_export), (*this_).file_export_icon );
     398           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).file_export), "Export" );
     399             : 
     400           0 :     (*this_).tool_sect_1_icon = gtk_image_new_from_paintable( GDK_PAINTABLE ( gui_resources_get_tool_sect( res ) ) );
     401           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).tool_sect_1_icon), 12 /*=w*/ , 32 /*=h*/ );
     402           0 :     gtk_image_set_pixel_size( GTK_IMAGE((*this_).tool_sect_1_icon), 32 );
     403           0 :     gtk_widget_set_halign( (*this_).tool_sect_1_icon, GTK_ALIGN_START );
     404             : 
     405           0 :      (*this_).tool_sect_2_icon = gtk_image_new_from_paintable( GDK_PAINTABLE ( gui_resources_get_tool_sect( res ) ) );
     406           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).tool_sect_2_icon), 12 /*=w*/ , 32 /*=h*/ );
     407           0 :     gtk_image_set_pixel_size( GTK_IMAGE((*this_).tool_sect_2_icon), 32 );
     408           0 :     gtk_widget_set_halign( (*this_).tool_sect_2_icon, GTK_ALIGN_START );
     409             : 
     410           0 :     (*this_).view_new_window_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_view_new_window( res ) ) );
     411           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).view_new_window_icon), 32 /*=w*/ , 32 /*=h*/ );
     412           0 :     (*this_).view_new_window = GTK_BUTTON(gtk_button_new());
     413           0 :     gtk_button_set_image( GTK_BUTTON((*this_).view_new_window), (*this_).view_new_window_icon );
     414           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).view_new_window), "New Window" );
     415             : 
     416           0 :     (*this_).view_navigate_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_view_navigate( res ) ) );
     417           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).view_navigate_icon), 32 /*=w*/ , 32 /*=h*/ );
     418           0 :     (*this_).view_edit_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_view_edit( res ) ) );
     419           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).view_edit_icon), 32 /*=w*/ , 32 /*=h*/ );
     420           0 :     (*this_).view_create_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_view_create( res ) ) );
     421           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).view_create_icon), 32 /*=w*/ , 32 /*=h*/ );
     422           0 :     (*this_).view_search_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_view_search( res ) ) );
     423           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).view_search_icon), 32 /*=w*/ , 32 /*=h*/ );
     424             : 
     425           0 :     (*this_).view_navigate = gtk_toggle_button_new();
     426           0 :     gtk_button_set_child( GTK_BUTTON((*this_).view_navigate), (*this_).view_navigate_icon );
     427             : 
     428           0 :     (*this_).view_edit = gtk_toggle_button_new();
     429           0 :     gtk_button_set_child( GTK_BUTTON((*this_).view_edit), (*this_).view_edit_icon );
     430           0 :     gtk_toggle_button_set_group( GTK_TOGGLE_BUTTON((*this_).view_edit), GTK_TOGGLE_BUTTON((*this_).view_navigate) );
     431             : 
     432           0 :     (*this_).view_create = gtk_toggle_button_new();
     433           0 :     gtk_button_set_child( GTK_BUTTON((*this_).view_create), (*this_).view_create_icon );
     434           0 :     gtk_toggle_button_set_group( GTK_TOGGLE_BUTTON((*this_).view_create), GTK_TOGGLE_BUTTON((*this_).view_edit) );
     435             : 
     436           0 :     (*this_).view_search = gtk_toggle_button_new();
     437           0 :     gtk_button_set_child( GTK_BUTTON((*this_).view_search), (*this_).view_search_icon );
     438           0 :     gtk_toggle_button_set_group( GTK_TOGGLE_BUTTON((*this_).view_search), GTK_TOGGLE_BUTTON((*this_).view_create) );
     439             : 
     440           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).view_navigate), "Navigate" );
     441           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).view_edit), "Edit" );
     442           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).view_create), "Create" );
     443           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).view_search), "Search" );
     444             : 
     445           0 :     (*this_).edit_undo_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_edit_undo( res ) ) );
     446           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).edit_undo_icon), 32 /*=w*/ , 32 /*=h*/ );
     447           0 :     (*this_).edit_undo = GTK_BUTTON(gtk_button_new());
     448           0 :     gtk_button_set_image( GTK_BUTTON((*this_).edit_undo), (*this_).edit_undo_icon );
     449           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).edit_undo), "Undo (Ctrl-Z)" );
     450           0 :     GtkShortcutTrigger *undo_trig = gtk_shortcut_trigger_parse_string( "<Control>Z" );
     451           0 :     GtkShortcutAction *undo_act = gtk_callback_action_new( &gui_toolbox_undo_shortcut_callback,
     452           0 :                                                            &((*this_).tools_data),
     453             :                                                            NULL
     454             :                                                          );
     455           0 :     GtkShortcut* ctrl_z = gtk_shortcut_new_with_arguments( undo_trig,
     456             :                                                            undo_act,
     457             :                                                            NULL /* = format_string */
     458             :                                                          );
     459           0 :     gtk_shortcut_controller_add_shortcut( (*this_).keyboard_shortcut_ctrl, ctrl_z );
     460             : 
     461           0 :     (*this_).edit_redo_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_edit_redo( res ) ) );
     462           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).edit_redo_icon), 32 /*=w*/ , 32 /*=h*/ );
     463           0 :     (*this_).edit_redo = GTK_BUTTON(gtk_button_new());
     464           0 :     gtk_button_set_image( GTK_BUTTON((*this_).edit_redo), (*this_).edit_redo_icon );
     465           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).edit_redo), "Redo (Ctrl-Y)" );
     466           0 :     GtkShortcutTrigger *redo_trig = gtk_shortcut_trigger_parse_string( "<Control>Y" );
     467           0 :     GtkShortcutAction *redo_act = gtk_callback_action_new( &gui_toolbox_redo_shortcut_callback,
     468           0 :                                                            &((*this_).tools_data),
     469             :                                                            NULL
     470             :                                                          );
     471           0 :     GtkShortcut* ctrl_y = gtk_shortcut_new_with_arguments( redo_trig,
     472             :                                                            redo_act,
     473             :                                                            NULL /* = format_string */
     474             :                                                          );
     475           0 :     gtk_shortcut_controller_add_shortcut( (*this_).keyboard_shortcut_ctrl, ctrl_y );
     476             : 
     477           0 :     (*this_).edit_cut_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_edit_cut( res ) ) );
     478           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).edit_cut_icon), 32 /*=w*/ , 32 /*=h*/ );
     479           0 :     (*this_).edit_cut = GTK_BUTTON(gtk_button_new());
     480           0 :     gtk_button_set_image( GTK_BUTTON((*this_).edit_cut), (*this_).edit_cut_icon );
     481           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).edit_cut), "Cut (Ctrl-X)" );
     482             :     /*
     483             :     GDK_KEY_x + GDK_CONTROL_MASK handling see gui_sketch_area_key_press_callback();
     484             :     moved there to not interfere with text input fields
     485             :     */
     486             : 
     487           0 :     (*this_).edit_copy_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_edit_copy( res ) ) );
     488           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).edit_copy_icon), 32 /*=w*/ , 32 /*=h*/ );
     489           0 :     (*this_).edit_copy = GTK_BUTTON(gtk_button_new());
     490           0 :     gtk_button_set_image( GTK_BUTTON((*this_).edit_copy), (*this_).edit_copy_icon );
     491           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).edit_copy), "Copy (Ctrl-C)" );
     492             :     /*
     493             :     GDK_KEY_c + GDK_CONTROL_MASK handling see gui_sketch_area_key_press_callback();
     494             :     moved there to not interfere with text input fields
     495             :     */
     496             : 
     497           0 :     (*this_).edit_paste_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_edit_paste( res ) ) );
     498           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).edit_paste_icon), 32 /*=w*/ , 32 /*=h*/ );
     499           0 :     (*this_).edit_paste = GTK_BUTTON(gtk_button_new());
     500           0 :     gtk_button_set_image( GTK_BUTTON((*this_).edit_paste), (*this_).edit_paste_icon );
     501           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).edit_paste), "Paste (Ctrl-V)" );
     502             :     /*
     503             :     GK_KEY_v + GDK_CONTROL_MASK handling see gui_sketch_area_key_press_callback();
     504             :     moved there to not interfere with text input fields
     505             :     */
     506             : 
     507           0 :     (*this_).edit_delete_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_edit_delete( res ) ) );
     508           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).edit_delete_icon), 32 /*=w*/ , 32 /*=h*/ );
     509           0 :     (*this_).edit_delete = GTK_BUTTON(gtk_button_new());
     510           0 :     gtk_button_set_image( GTK_BUTTON((*this_).edit_delete), (*this_).edit_delete_icon );
     511           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).edit_delete), "Delete (DEL)" );
     512             :     /*
     513             :     GDK_KEY_Delete handling see gui_sketch_area_key_press_callback();
     514             :     moved there to not interfere with text input fields
     515             :     */
     516             : 
     517           0 :     (*this_).edit_instantiate_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_edit_instantiate( res ) ) );
     518           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).edit_instantiate_icon), 32 /*=w*/ , 32 /*=h*/ );
     519           0 :     (*this_).edit_instantiate = GTK_BUTTON(gtk_button_new());
     520           0 :     gtk_button_set_image( GTK_BUTTON((*this_).edit_instantiate), (*this_).edit_instantiate_icon );
     521           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).edit_instantiate), "Instantiate" );
     522             : 
     523           0 :     (*this_).edit_highlight_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_edit_highlight( res ) ) );
     524           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).edit_highlight_icon), 32 /*=w*/ , 32 /*=h*/ );
     525           0 :     (*this_).edit_highlight = GTK_BUTTON(gtk_button_new());
     526           0 :     gtk_button_set_image( GTK_BUTTON((*this_).edit_highlight), (*this_).edit_highlight_icon );
     527           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).edit_highlight), "Highlight" );
     528             : 
     529           0 :     (*this_).edit_reset_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_edit_reset( res ) ) );
     530           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).edit_reset_icon), 32 /*=w*/ , 32 /*=h*/ );
     531           0 :     (*this_).edit_reset = GTK_BUTTON(gtk_button_new());
     532           0 :     gtk_button_set_image( GTK_BUTTON((*this_).edit_reset), (*this_).edit_reset_icon );
     533           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).edit_reset), "Reset Selection" );
     534             : 
     535           0 :     (*this_).tool_about_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_crystal_facet_uml( res ) ) );
     536           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).tool_about_icon), 32 /*=w*/ , 32 /*=h*/ );
     537           0 :     (*this_).tool_about = GTK_BUTTON(gtk_button_new());
     538           0 :     gtk_button_set_image( GTK_BUTTON((*this_).tool_about), (*this_).tool_about_icon );
     539           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).tool_about), "About" );
     540             : 
     541             :     /* insert widgets to box container */
     542             :     {
     543           0 :         (*this_).tool_row = gtk_box_new( GTK_ORIENTATION_HORIZONTAL, /*spacing:*/ 4 );
     544           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).file_new_db) );
     545           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).file_use_db) );
     546           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).file_save_button) );
     547           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).file_export) );
     548           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).tool_sect_1_icon) );
     549           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).view_new_window) );
     550           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).view_search) );
     551           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).view_navigate) );
     552           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).view_edit) );
     553           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).view_create) );
     554           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).tool_sect_2_icon) );
     555           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).edit_undo) );
     556           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).edit_redo) );
     557           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).edit_cut) );
     558           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).edit_copy) );
     559           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).edit_paste) );
     560           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).edit_delete) );
     561           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).edit_instantiate) );
     562           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).edit_highlight) );
     563           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).edit_reset) );
     564           0 :         gtk_box_append( GTK_BOX((*this_).tool_row), GTK_WIDGET((*this_).tool_about) );
     565             :     }
     566             : 
     567           0 :     U8_TRACE_END();
     568           0 : }
     569             : 
     570           0 : void gui_main_window_private_init_attributes_editor( gui_main_window_t *this_, gui_resources_t *res )
     571             : {
     572           0 :     U8_TRACE_BEGIN();
     573             : 
     574           0 :     (*this_).attr_section_icon = gtk_image_new_from_paintable( GDK_PAINTABLE ( gui_resources_get_edit_attributes_sect( res ) ) );
     575           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).attr_section_icon), 48 /*=w*/ , 12 /*=h*/ );
     576           0 :     gtk_image_set_pixel_size( GTK_IMAGE((*this_).attr_section_icon), 48 );
     577           0 :     gtk_widget_set_halign( (*this_).attr_section_icon, GTK_ALIGN_START );
     578             : 
     579           0 :     (*this_).id_label = gtk_label_new( "" );
     580           0 :     gtk_label_set_selectable( GTK_LABEL( (*this_).id_label ), true );
     581           0 :     (*this_).name_label = gtk_label_new( "Name:" );
     582           0 :     (*this_).description_label = gtk_label_new( "Description:" );
     583           0 :     (*this_).stereotype_label = gtk_label_new( "Stereotype:" );
     584           0 :     (*this_).type_label = gtk_label_new( "Type:" );
     585           0 :     gtk_label_set_xalign( GTK_LABEL( (*this_).id_label ), 1.0 ); /* align right */
     586           0 :     gtk_label_set_xalign( GTK_LABEL( (*this_).name_label ), 0.0 );
     587           0 :     gtk_label_set_xalign( GTK_LABEL( (*this_).description_label ), 0.0 );
     588           0 :     gtk_label_set_xalign( GTK_LABEL( (*this_).stereotype_label ), 0.0 );
     589           0 :     gtk_label_set_xalign( GTK_LABEL( (*this_).type_label ), 0.0 );
     590             : 
     591           0 :     (*this_).id_search_btn = gtk_button_new();
     592           0 :     (*this_).id_search_btn_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_search_search( res ) ) );
     593           0 :     gtk_button_set_image( GTK_BUTTON((*this_).id_search_btn), (*this_).id_search_btn_icon );
     594           0 :     gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).id_search_btn), "Find Occurrences" );
     595           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).id_search_btn_icon), 32 /*=w*/ , 32 /*=h*/ );
     596             : 
     597             :     /* insert widgets to box container */
     598             :     {
     599           0 :         (*this_).id_row = gtk_box_new( GTK_ORIENTATION_HORIZONTAL, /*spacing:*/ 8 );
     600           0 :         gtk_box_append( GTK_BOX((*this_).id_row), GTK_WIDGET((*this_).attr_section_icon) );
     601           0 :         gtk_box_append( GTK_BOX((*this_).id_row), GTK_WIDGET((*this_).id_label) );
     602           0 :         gtk_box_append( GTK_BOX((*this_).id_row), GTK_WIDGET((*this_).id_search_btn) );
     603             : 
     604           0 :         gtk_widget_set_vexpand ( GTK_WIDGET( (*this_).attr_section_icon ), false );
     605           0 :         gtk_widget_set_hexpand ( GTK_WIDGET( (*this_).attr_section_icon ), false );
     606           0 :         gtk_widget_set_vexpand ( GTK_WIDGET( (*this_).id_label ), false );
     607           0 :         gtk_widget_set_hexpand ( GTK_WIDGET( (*this_).id_label ), true );
     608           0 :         gtk_widget_set_vexpand ( GTK_WIDGET( (*this_).id_search_btn ), false );
     609           0 :         gtk_widget_set_hexpand ( GTK_WIDGET( (*this_).id_search_btn ), false );
     610             :     }
     611             : 
     612           0 :     (*this_).name_entry = gtk_entry_new();
     613             : 
     614           0 :     (*this_).stereotype_entry = gtk_entry_new();
     615             : 
     616           0 :     (*this_).description_text_view = gtk_text_view_new();
     617           0 :     gtk_text_view_set_wrap_mode( GTK_TEXT_VIEW( (*this_).description_text_view ),
     618             :                                  GTK_WRAP_WORD_CHAR
     619             :                                );
     620           0 :     gtk_widget_set_vexpand( GTK_WIDGET( (*this_).description_text_view ), true );
     621           0 :     gtk_widget_set_hexpand( GTK_WIDGET( (*this_).description_text_view ), false );
     622             :     //gtk_widget_set_size_request( GTK_WIDGET((*this_).description_text_view), 128 /*=w*/ , 48 /*=h*/ );
     623             :     /* need own scroll window container */
     624           0 :     gtk_text_view_set_bottom_margin( GTK_TEXT_VIEW( (*this_).description_text_view ), 12 );
     625           0 :     gtk_text_view_set_left_margin( GTK_TEXT_VIEW( (*this_).description_text_view ), 12 );
     626           0 :     gtk_text_view_set_right_margin( GTK_TEXT_VIEW( (*this_).description_text_view ), 12 );
     627           0 :     gtk_text_view_set_top_margin( GTK_TEXT_VIEW( (*this_).description_text_view ), 12 );
     628           0 :     (*this_).description_scroll_win = gtk_scrolled_window_new();
     629           0 :     gtk_scrolled_window_set_child( GTK_SCROLLED_WINDOW((*this_).description_scroll_win), (*this_).description_text_view );
     630           0 :     gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( (*this_).description_scroll_win ),
     631             :                                     GTK_POLICY_AUTOMATIC,
     632             :                                     GTK_POLICY_AUTOMATIC
     633             :                                   );
     634             : 
     635           0 :     GListStore *model = NULL;  /* the model is set later */
     636           0 :     GtkExpression *expression = NULL;  /* not needed: there is no search entry that could find list elements */
     637           0 :     (*this_).type_dropdown = GTK_DROP_DOWN( gtk_drop_down_new ( G_LIST_MODEL( model ), expression ) );
     638           0 :     GtkBuilderScope *scope = gtk_builder_cscope_new();
     639             :     static const char bytes[] =
     640             :     "<interface>\n"
     641             :     "<template class=\"GtkListItem\">\n"
     642             :     "  <property name=\"child\">\n"
     643             :     "    <object class=\"GtkPaned\">\n"
     644             :     "      <property name=\"start-child\">\n"
     645             :     "        <object class=\"GtkImage\">\n"
     646             :     "          <binding name=\"paintable\">\n"
     647             :     "            <lookup name=\"icon\" type=\"GuiTypeResource\">\n"
     648             :     "              <lookup name=\"item\">GtkListItem</lookup>\n"
     649             :     "            </lookup>\n"
     650             :     "          </binding>\n"
     651             :     "        </object>\n"
     652             :     "      </property>\n"
     653             :     "      <property name=\"end-child\">\n"
     654             :     "        <object class=\"GtkLabel\">\n"
     655             :     "          <property name=\"xalign\">0</property>\n"
     656             :     "          <binding name=\"label\">\n"
     657             :     "            <lookup name=\"name\" type=\"GuiTypeResource\">\n"
     658             :     "              <lookup name=\"item\">GtkListItem</lookup>\n"
     659             :     "            </lookup>\n"
     660             :     "          </binding>\n"
     661             :     "        </object>\n"
     662             :     "      </property>\n"
     663             :     "      <property name=\"position\">48</property>\n"
     664             :     "    </object>\n"
     665             :     "  </property>\n"
     666             :     "</template>\n"
     667             :     "</interface>\n";
     668           0 :     GBytes *byteptr = g_bytes_new( &bytes, sizeof(bytes)-sizeof(char) );
     669           0 :     GtkListItemFactory *factory = gtk_builder_list_item_factory_new_from_bytes( scope, byteptr );
     670           0 :     gtk_drop_down_set_factory( (*this_).type_dropdown, factory );
     671           0 :     g_object_unref( scope );
     672           0 :     g_object_unref( factory );
     673           0 :     g_bytes_unref( byteptr );
     674             : 
     675             :     static gui_type_resource_list_t res_select;
     676           0 :     gui_type_resource_list_init( &res_select, res );
     677             :     {
     678           0 :         (*this_).type_diag_grid = GTK_GRID( gtk_grid_new() );
     679           0 :         gtk_widget_set_halign( GTK_WIDGET( (*this_).type_diag_grid ), GTK_ALIGN_END );
     680             :         const gui_type_resource_t (*diag_data)[];
     681             :         unsigned int diag_data_length;
     682           0 :         gui_type_resource_list_get_all_diagram_types( &res_select, &diag_data, &diag_data_length );
     683           0 :         assert( diag_data_length == GUI_TYPE_RESOURCE_LIST_DIAGRAMS );
     684           0 :         for( int_fast32_t diag_idx = 0; diag_idx < GUI_TYPE_RESOURCE_LIST_DIAGRAMS; diag_idx ++ )
     685             :         {
     686           0 :             const gui_type_resource_t *const type_data = &((*diag_data)[diag_idx]);
     687           0 :             const data_diagram_type_t diag_type = data_type_get_diagram_type( gui_type_resource_get_type_id( type_data ) );
     688           0 :             GdkTexture *const diag_icon = gui_type_resource_get_icon( type_data );
     689           0 :             const char *const diag_name = gui_type_resource_get_name( type_data );
     690             : 
     691           0 :             gui_attribute_type_of_diagram_init( &((*this_).type_diag_data[diag_idx]), diag_type, &((*this_).attributes_editor) );
     692           0 :             (*this_).type_diag_img[ diag_idx ] = GTK_IMAGE( gtk_image_new_from_paintable( GDK_PAINTABLE( diag_icon ) ) );
     693           0 :             gtk_widget_set_size_request( GTK_WIDGET( (*this_).type_diag_img[ diag_idx ] ), 32 /*=w*/ , 24 /*=h*/ );
     694           0 :             (*this_).type_diag_btn[ diag_idx ] = GTK_BUTTON( gtk_button_new() );
     695           0 :             gtk_button_set_image( (*this_).type_diag_btn[ diag_idx ], GTK_WIDGET( (*this_).type_diag_img[ diag_idx ] ) );
     696           0 :             gtk_widget_set_tooltip_text( GTK_WIDGET( (*this_).type_diag_btn[ diag_idx ] ), diag_name );
     697           0 :             gtk_grid_attach( (*this_).type_diag_grid, GTK_WIDGET( (*this_).type_diag_btn[ diag_idx ] ), diag_idx%7, diag_idx/7, 1, 1 );
     698             :         }
     699             : 
     700           0 :         (*this_).type_clas_grid = GTK_GRID( gtk_grid_new() );
     701           0 :         gtk_widget_set_halign( GTK_WIDGET( (*this_).type_clas_grid ), GTK_ALIGN_END );
     702             :         const gui_type_resource_t (*clas_data)[];
     703             :         unsigned int clas_data_length;
     704           0 :         gui_type_resource_list_get_all_classifier_types( &res_select, &clas_data, &clas_data_length );
     705           0 :         assert( clas_data_length == GUI_TYPE_RESOURCE_LIST_CLASSIFIERS );
     706           0 :         for( int_fast32_t clas_idx = 0; clas_idx < GUI_TYPE_RESOURCE_LIST_CLASSIFIERS; clas_idx ++ )
     707             :         {
     708           0 :             const gui_type_resource_t *const type_data = &((*clas_data)[clas_idx]);
     709           0 :             const data_classifier_type_t clas_type = data_type_get_classifier_type( gui_type_resource_get_type_id( type_data ) );
     710           0 :             GdkTexture *const clas_icon = gui_type_resource_get_icon( type_data );
     711           0 :             const char *const clas_name = gui_type_resource_get_name( type_data );
     712             : 
     713           0 :             gui_attribute_type_of_classifier_init( &((*this_).type_clas_data[clas_idx]), clas_type, &((*this_).attributes_editor) );
     714           0 :             (*this_).type_clas_img[ clas_idx ] = GTK_IMAGE( gtk_image_new_from_paintable( GDK_PAINTABLE( clas_icon ) ) );
     715           0 :             gtk_widget_set_size_request( GTK_WIDGET( (*this_).type_clas_img[ clas_idx ] ), 32 /*=w*/ , 24 /*=h*/ );
     716           0 :             (*this_).type_clas_btn[ clas_idx ] = GTK_BUTTON( gtk_button_new() );
     717           0 :             gtk_button_set_image( (*this_).type_clas_btn[ clas_idx ], GTK_WIDGET( (*this_).type_clas_img[ clas_idx ] ) );
     718           0 :             gtk_widget_set_tooltip_text( GTK_WIDGET( (*this_).type_clas_btn[ clas_idx ] ), clas_name );
     719           0 :             gtk_grid_attach( (*this_).type_clas_grid, GTK_WIDGET( (*this_).type_clas_btn[ clas_idx ] ), clas_idx%7, clas_idx/7, 1, 1 );
     720             :         }
     721             : 
     722           0 :         (*this_).type_feat_grid = GTK_GRID( gtk_grid_new() );
     723           0 :         gtk_widget_set_halign( GTK_WIDGET( (*this_).type_feat_grid ), GTK_ALIGN_END );
     724             :         const gui_type_resource_t (*feat_data)[];
     725             :         unsigned int feat_data_length;
     726           0 :         gui_type_resource_list_get_invariant_feature_types( &res_select, &feat_data, &feat_data_length );
     727           0 :         assert( feat_data_length == GUI_TYPE_RESOURCE_LIST_INV_FEATURES );
     728           0 :         for( int_fast32_t feat_idx = 0; feat_idx < GUI_TYPE_RESOURCE_LIST_INV_FEATURES; feat_idx ++ )  /* ignore the lifeline */
     729             :         {
     730           0 :             const gui_type_resource_t *const type_data = &((*feat_data)[feat_idx]);
     731           0 :             const data_feature_type_t feat_type = data_type_get_feature_type( gui_type_resource_get_type_id( type_data ) );
     732           0 :             GdkTexture *const feat_icon = gui_type_resource_get_icon( type_data );
     733           0 :             const char *const feat_name = gui_type_resource_get_name( type_data );
     734             : 
     735           0 :             gui_attribute_type_of_feature_init( &((*this_).type_feat_data[feat_idx]), feat_type, &((*this_).attributes_editor) );
     736           0 :             (*this_).type_feat_img[ feat_idx ] = GTK_IMAGE( gtk_image_new_from_paintable( GDK_PAINTABLE( feat_icon ) ) );
     737           0 :             gtk_widget_set_size_request( GTK_WIDGET( (*this_).type_feat_img[ feat_idx ] ), 32 /*=w*/ , 24 /*=h*/ );
     738           0 :             (*this_).type_feat_btn[ feat_idx ] = GTK_BUTTON( gtk_button_new() );
     739           0 :             gtk_button_set_image( (*this_).type_feat_btn[ feat_idx ], GTK_WIDGET( (*this_).type_feat_img[ feat_idx ] ) );
     740           0 :             gtk_widget_set_tooltip_text( GTK_WIDGET( (*this_).type_feat_btn[ feat_idx ] ), feat_name );
     741           0 :             gtk_grid_attach( (*this_).type_feat_grid, GTK_WIDGET( (*this_).type_feat_btn[ feat_idx ] ), feat_idx%7, feat_idx/7, 1, 1 );
     742             :         }
     743             : 
     744           0 :         (*this_).type_rel_grid = GTK_GRID( gtk_grid_new() );
     745           0 :         gtk_widget_set_halign( GTK_WIDGET( (*this_).type_rel_grid ), GTK_ALIGN_END );
     746             :         const gui_type_resource_t (*rel_data)[];
     747             :         unsigned int rel_data_length;
     748           0 :         gui_type_resource_list_get_all_relationship_types( &res_select, &rel_data, &rel_data_length );
     749           0 :         assert( rel_data_length == GUI_TYPE_RESOURCE_LIST_RELATIONS );
     750           0 :         for( int_fast32_t rel_idx = 0; rel_idx < GUI_TYPE_RESOURCE_LIST_RELATIONS; rel_idx ++ )
     751             :         {
     752           0 :             const gui_type_resource_t *const type_data = &((*rel_data)[rel_idx]);
     753           0 :             const data_relationship_type_t rel_type = data_type_get_relationship_type( gui_type_resource_get_type_id( type_data ) );
     754           0 :             GdkTexture *const rel_icon = gui_type_resource_get_icon( type_data );
     755           0 :             const char *const rel_name = gui_type_resource_get_name( type_data );
     756             : 
     757           0 :             gui_attribute_type_of_relationship_init( &((*this_).type_rel_data[rel_idx]), rel_type, &((*this_).attributes_editor) );
     758           0 :             (*this_).type_rel_img[ rel_idx ] = GTK_IMAGE( gtk_image_new_from_paintable( GDK_PAINTABLE( rel_icon ) ) );
     759           0 :             gtk_widget_set_size_request( GTK_WIDGET( (*this_).type_rel_img[ rel_idx ] ), 32 /*=w*/ , 24 /*=h*/ );
     760           0 :             (*this_).type_rel_btn[ rel_idx ] = GTK_BUTTON( gtk_button_new() );
     761           0 :             gtk_button_set_image( (*this_).type_rel_btn[ rel_idx ], GTK_WIDGET( (*this_).type_rel_img[ rel_idx ] ) );
     762           0 :             gtk_widget_set_tooltip_text( GTK_WIDGET( (*this_).type_rel_btn[ rel_idx ] ), rel_name );
     763           0 :             gtk_grid_attach( (*this_).type_rel_grid, GTK_WIDGET( (*this_).type_rel_btn[ rel_idx ] ), rel_idx%7, rel_idx/7, 1, 1 );
     764             :         }
     765             :     }
     766           0 :     gui_type_resource_list_destroy( &res_select );
     767             : 
     768             :     /* insert widgets to box container */
     769             :     {
     770           0 :         (*this_).attr_edit_column = gtk_box_new( GTK_ORIENTATION_VERTICAL, /*spacing:*/ 4 );
     771           0 :         gtk_box_append( GTK_BOX((*this_).attr_edit_column), GTK_WIDGET((*this_).id_row) );
     772           0 :         gtk_box_append( GTK_BOX((*this_).attr_edit_column), GTK_WIDGET((*this_).name_label) );
     773           0 :         gtk_box_append( GTK_BOX((*this_).attr_edit_column), GTK_WIDGET((*this_).name_entry) );
     774           0 :         gtk_box_append( GTK_BOX((*this_).attr_edit_column), GTK_WIDGET((*this_).stereotype_label) );
     775           0 :         gtk_box_append( GTK_BOX((*this_).attr_edit_column), GTK_WIDGET((*this_).stereotype_entry) );
     776           0 :         gtk_box_append( GTK_BOX((*this_).attr_edit_column), GTK_WIDGET((*this_).type_label) );
     777           0 :         gtk_box_append( GTK_BOX((*this_).attr_edit_column), GTK_WIDGET((*this_).type_dropdown) );
     778           0 :         gtk_box_append( GTK_BOX((*this_).attr_edit_column), GTK_WIDGET((*this_).type_diag_grid) );
     779           0 :         gtk_box_append( GTK_BOX((*this_).attr_edit_column), GTK_WIDGET((*this_).type_clas_grid) );
     780           0 :         gtk_box_append( GTK_BOX((*this_).attr_edit_column), GTK_WIDGET((*this_).type_feat_grid) );
     781           0 :         gtk_box_append( GTK_BOX((*this_).attr_edit_column), GTK_WIDGET((*this_).type_rel_grid) );
     782           0 :         gtk_box_append( GTK_BOX((*this_).attr_edit_column), GTK_WIDGET((*this_).description_label) );
     783           0 :         gtk_box_append( GTK_BOX((*this_).attr_edit_column), GTK_WIDGET((*this_).description_scroll_win) );
     784             : 
     785           0 :         gtk_widget_set_vexpand( GTK_WIDGET( (*this_).description_scroll_win ), true );
     786           0 :         gtk_widget_set_hexpand( GTK_WIDGET( (*this_).description_scroll_win ), true );
     787             :     }
     788             : 
     789           0 :     U8_TRACE_END();
     790           0 : }
     791             : 
     792           0 : void gui_main_window_private_init_simple_message_to_user( gui_main_window_t *this_, gui_resources_t *res )
     793             : {
     794           0 :     U8_TRACE_BEGIN();
     795             : 
     796           0 :     (*this_).message_text_label = gtk_label_new( "" );
     797           0 :     gtk_label_set_xalign(GTK_LABEL( (*this_).message_text_label ), 0.0 );
     798             : 
     799           0 :     (*this_).message_icon_image = gtk_image_new_from_paintable( GDK_PAINTABLE ( gui_resources_get_crystal_facet_uml( res ) ) );
     800             :     /* TODO check if GtkPicture is better suited than GtkImage because of setting the size */
     801             :     // gtk_widget_set_size_request( GTK_WIDGET((*this_).message_icon_image), 32 /*=w*/ , 32 /*=h*/ );
     802             :     // gtk_image_set_pixel_size( GTK_IMAGE((*this_).message_icon_image), 32 );
     803           0 :     gtk_widget_set_size_request( GTK_WIDGET((*this_).message_icon_image), 32 /*=w*/ , 32 /*=h*/ );
     804             : 
     805             :     /* insert widgets to box container */
     806             :     {
     807           0 :         (*this_).message_row = gtk_box_new( GTK_ORIENTATION_HORIZONTAL, /*spacing:*/ 20 );
     808           0 :         gtk_box_append( GTK_BOX((*this_).message_row), GTK_WIDGET((*this_).message_icon_image) );
     809           0 :         gtk_box_append( GTK_BOX((*this_).message_row), GTK_WIDGET((*this_).message_text_label) );
     810             : 
     811           0 :         gtk_widget_set_vexpand( GTK_WIDGET( (*this_).message_icon_image ), false );
     812           0 :         gtk_widget_set_hexpand( GTK_WIDGET( (*this_).message_icon_image ), false );
     813           0 :         gtk_widget_set_vexpand( GTK_WIDGET( (*this_).message_text_label ), false );
     814           0 :         gtk_widget_set_hexpand( GTK_WIDGET( (*this_).message_text_label ), true );
     815             :     }
     816             : 
     817           0 :     U8_TRACE_END();
     818           0 : }
     819             : 
     820           0 : void gui_main_window_private_init_search_and_sketch_area( gui_main_window_t *this_, gui_resources_t *res )
     821             : {
     822           0 :     U8_TRACE_BEGIN();
     823             : 
     824             :     /* init search widgets */
     825             :     {
     826           0 :         (*this_).search_label = gtk_label_new ( "Search:" );
     827           0 :         gtk_label_set_xalign( GTK_LABEL( (*this_).search_label ), 1.0 ); /* align right */
     828           0 :         gtk_label_set_yalign( GTK_LABEL( (*this_).search_label ), 0.5 ); /* align middle-height */
     829             : 
     830           0 :         (*this_).search_entry = gtk_entry_new();
     831             : 
     832           0 :         (*this_).search_button = gtk_button_new();
     833           0 :         (*this_).search_btn_icon = gtk_image_new_from_paintable( GDK_PAINTABLE( gui_resources_get_search_search( res ) ) );
     834           0 :         gtk_button_set_image( GTK_BUTTON((*this_).search_button), (*this_).search_btn_icon );
     835           0 :         gtk_widget_set_tooltip_text( GTK_WIDGET((*this_).search_button), "Search" );
     836           0 :         gtk_widget_set_size_request( GTK_WIDGET((*this_).search_btn_icon), 32 /*=w*/ , 32 /*=h*/ );
     837             :     }
     838             : 
     839             :     /* insert widgets to box container */
     840             :     {
     841           0 :         (*this_).search_row = gtk_box_new( GTK_ORIENTATION_HORIZONTAL, /*spacing:*/ 4 );
     842           0 :         gtk_box_append( GTK_BOX((*this_).search_row), GTK_WIDGET((*this_).search_label) );
     843           0 :         gtk_box_append( GTK_BOX((*this_).search_row), GTK_WIDGET((*this_).search_entry) );
     844           0 :         gtk_box_append( GTK_BOX((*this_).search_row), GTK_WIDGET((*this_).search_button) );
     845             : 
     846           0 :         gtk_widget_set_vexpand ( GTK_WIDGET( (*this_).search_label ), false );
     847           0 :         gtk_widget_set_hexpand ( GTK_WIDGET( (*this_).search_label ), false );
     848           0 :         gtk_widget_set_vexpand ( GTK_WIDGET( (*this_).search_entry ), false );
     849           0 :         gtk_widget_set_hexpand ( GTK_WIDGET( (*this_).search_entry ), true );
     850           0 :         gtk_widget_set_vexpand ( GTK_WIDGET( (*this_).search_button ), false );
     851           0 :         gtk_widget_set_hexpand ( GTK_WIDGET( (*this_).search_button ), false );
     852             :     }
     853             : 
     854             :     /* init sketch area */
     855             :     {
     856           0 :         (*this_).sketcharea = gtk_drawing_area_new();
     857           0 :         gtk_widget_set_can_focus( GTK_WIDGET( (*this_).sketcharea ), TRUE );  /* this allows the text entry widgets to lose the focus */
     858           0 :         gtk_widget_set_size_request( GTK_WIDGET( (*this_).sketcharea ), 600, 360);  /* set a minimum initial size */
     859             :         /*gtk_widget_set_focus_on_click( GTK_WIDGET( (*this_).sketcharea ), TRUE ); not yet existing: since GTK 3.2 */
     860             :     }
     861             : 
     862             :     /* insert widgets to box container */
     863             :     {
     864           0 :         (*this_).sketch_stack_column = gtk_box_new( GTK_ORIENTATION_VERTICAL, /*spacing:*/ 0 );
     865           0 :         gtk_box_append( GTK_BOX((*this_).sketch_stack_column), GTK_WIDGET((*this_).search_row) );
     866           0 :         gtk_box_append( GTK_BOX((*this_).sketch_stack_column), GTK_WIDGET((*this_).sketcharea) );
     867             : 
     868           0 :         gtk_widget_set_vexpand ( GTK_WIDGET( (*this_).search_row ), false );
     869           0 :         gtk_widget_set_hexpand ( GTK_WIDGET( (*this_).search_row ), true );
     870           0 :         gtk_widget_set_vexpand ( GTK_WIDGET( (*this_).sketcharea ), true );
     871           0 :         gtk_widget_set_hexpand ( GTK_WIDGET( (*this_).sketcharea ), true );
     872             :     }
     873             : 
     874           0 :     U8_TRACE_END();
     875           0 : }
     876             : 
     877           0 : void gui_main_window_destroy_event_callback( GtkWidget *widget, gpointer data )
     878             : {
     879           0 :     U8_TRACE_BEGIN();
     880           0 :     gui_main_window_t *this_ = data;
     881           0 :     assert( (*this_).window == (void*)widget );
     882             : 
     883             :     /* forward destroy request to gui_window_manager: */
     884           0 :     observer_notify( (*this_).window_close_observer, this_ );
     885             : 
     886           0 :     U8_TRACE_TIMESTAMP();
     887           0 :     U8_TRACE_END();
     888           0 : }
     889             : 
     890           0 : gboolean gui_main_window_delete_event_callback( GtkWindow *widget, gpointer data )
     891             : {
     892           0 :     U8_TRACE_BEGIN();
     893           0 :     gui_main_window_t *this_ = data;
     894           0 :     assert( (*this_).window == (void*)widget );
     895             :     (void) this_;  /* unused in case of NDEBUG */
     896             : 
     897           0 :     U8_TRACE_TIMESTAMP();
     898           0 :     U8_TRACE_END();
     899           0 :     return false;  /* return false to trigger destroy event */
     900             : }
     901             : 
     902           0 : void gui_main_window_new_db_btn_callback( GtkWidget* button, gpointer data )
     903             : {
     904           0 :     U8_TRACE_BEGIN();
     905           0 :     gui_main_window_t *this_ = data;
     906             : 
     907           0 :     gui_simple_message_to_user_hide( &((*this_).message_to_user) );
     908             : 
     909           0 :     gui_file_use_db_dialog_show( &((*this_).file_use_db_dialog), false /* open_existing*/ );
     910             : 
     911           0 :     U8_TRACE_TIMESTAMP();
     912           0 :     U8_TRACE_END();
     913           0 : }
     914             : 
     915           0 : void gui_main_window_open_db_btn_callback( GtkWidget* button, gpointer data )
     916             : {
     917           0 :     U8_TRACE_BEGIN();
     918           0 :     gui_main_window_t *this_ = data;
     919             : 
     920           0 :     gui_simple_message_to_user_hide( &((*this_).message_to_user) );
     921             : 
     922           0 :     gui_file_use_db_dialog_show( &((*this_).file_use_db_dialog), true /* open_existing*/ );
     923             : 
     924           0 :     U8_TRACE_TIMESTAMP();
     925           0 :     U8_TRACE_END();
     926           0 : }
     927             : 
     928           0 : void gui_main_window_save_btn_callback( GtkButton *button, gpointer user_data )
     929             : {
     930           0 :     U8_TRACE_BEGIN();
     931             :     gui_main_window_t *this_;
     932           0 :     this_ = (gui_main_window_t*) user_data;
     933           0 :     assert( this_ != NULL );
     934             : 
     935           0 :     gui_simple_message_to_user_hide( &((*this_).message_to_user) );
     936             : 
     937           0 :     gui_attributes_editor_commit_changes ( &((*this_).attributes_editor) );
     938             : 
     939             :     u8_error_t d_err;
     940           0 :     d_err = U8_ERROR_NONE;
     941           0 :     d_err |= io_data_file_trace_stats( (*this_).data_file );
     942           0 :     d_err |= io_data_file_sync_to_disk( (*this_).data_file );
     943           0 :     d_err |= io_data_file_trace_stats( (*this_).data_file );
     944           0 :     if ( U8_ERROR_NONE != d_err )
     945             :     {
     946           0 :         gui_simple_message_to_user_show_message( &((*this_).message_to_user),
     947             :                                                  GUI_SIMPLE_MESSAGE_TYPE_WARNING,
     948             :                                                  GUI_SIMPLE_MESSAGE_CONTENT_DB_FILE_WRITE_ERROR
     949             :                                                );
     950             :     }
     951             :     else
     952             :     {
     953           0 :         gui_simple_message_to_user_show_message_with_name( &((*this_).message_to_user),
     954             :                                                            GUI_SIMPLE_MESSAGE_TYPE_INFO,
     955             :                                                            GUI_SIMPLE_MESSAGE_CONTENT_DB_FILE_WRITTEN,
     956           0 :                                                            io_data_file_get_filename_const( (*this_).data_file )
     957             :                                                          );
     958             : #ifndef NDEBUG
     959             :         /* in debug mode, also check consistency of database */
     960             :         universal_stream_output_stream_t out_stream;
     961           0 :         universal_stream_output_stream_init( &out_stream, stdout );
     962           0 :         universal_output_stream_t *const out_base = universal_stream_output_stream_get_output_stream( &out_stream );
     963             :         utf8stream_writer_t out_report;
     964           0 :         utf8stream_writer_init( &out_report, out_base );
     965             :         uint32_t found_errors;
     966             :         uint32_t fixed_errors;
     967           0 :         ctrl_controller_repair_database( (*this_).controller,
     968             :                                          false /* no repair, just test */,
     969             :                                          &found_errors,
     970             :                                          &fixed_errors,
     971             :                                          &out_report
     972             :                                        );
     973           0 :         if (( found_errors != 0 ) || ( fixed_errors != 0 ))
     974             :         {
     975           0 :             gui_simple_message_to_user_show_message_with_quantity( &((*this_).message_to_user),
     976             :                                                                    GUI_SIMPLE_MESSAGE_TYPE_ERROR,
     977             :                                                                    GUI_SIMPLE_MESSAGE_CONTENT_DB_INCONSISTENT,
     978             :                                                                    found_errors
     979             :                                                                  );
     980             :         }
     981           0 :         utf8stream_writer_destroy( &out_report );
     982           0 :         universal_stream_output_stream_destroy( &out_stream );
     983             : #endif
     984             :     }
     985             : 
     986           0 :     U8_TRACE_TIMESTAMP();
     987           0 :     U8_TRACE_END();
     988           0 : }
     989             : 
     990           0 : gboolean gui_main_window_save_shortcut_callback( GtkWidget* widget, GVariant* args, gpointer user_data )
     991             : {
     992           0 :     gui_main_window_save_btn_callback( (GtkButton*)widget, user_data );
     993           0 :     return TRUE;
     994             : }
     995             : 
     996           0 : void gui_main_window_export_btn_callback( GtkWidget* button, gpointer data )
     997             : {
     998           0 :     U8_TRACE_BEGIN();
     999           0 :     gui_main_window_t *this_ = data;
    1000             : 
    1001           0 :     gui_simple_message_to_user_hide( &((*this_).message_to_user) );
    1002             : 
    1003           0 :     const bool was_visible = gtk_widget_get_visible( (*this_).options_layout );
    1004           0 :     gtk_widget_set_visible( (*this_).options_layout, ! was_visible );
    1005             : 
    1006           0 :     U8_TRACE_TIMESTAMP();
    1007           0 :     U8_TRACE_END();
    1008           0 : }
    1009             : 
    1010           0 : void gui_main_window_new_window_btn_callback( GtkWidget* button, gpointer data )
    1011             : {
    1012           0 :     U8_TRACE_BEGIN();
    1013           0 :     gui_main_window_t *this_ = data;
    1014             : 
    1015             :     /* hide last message */
    1016           0 :     gui_simple_message_to_user_hide( &((*this_).message_to_user) );
    1017             : 
    1018             :     /* forward new window request to gui_window_manager: */
    1019           0 :     observer_notify( (*this_).window_open_observer, &((*this_).message_to_user) );
    1020             : 
    1021           0 :     U8_TRACE_TIMESTAMP();
    1022           0 :     U8_TRACE_END();
    1023           0 : }
    1024             : 
    1025           0 : void gui_main_window_about_btn_callback( GtkWidget* button, gpointer data )
    1026             : {
    1027           0 :     U8_TRACE_BEGIN();
    1028           0 :     gui_main_window_t *this_ = data;
    1029             : 
    1030           0 :     if ( GUI_SIMPLE_MESSAGE_TYPE_ABOUT == gui_simple_message_to_user_get_type_id( &((*this_).message_to_user) ) )
    1031             :     {
    1032             :         /* hide the already visible about message */
    1033           0 :         gui_simple_message_to_user_hide( &((*this_).message_to_user) );
    1034             :     }
    1035             :     else
    1036             :     {
    1037           0 :         gui_simple_message_to_user_show_message( &((*this_).message_to_user),
    1038             :                                                  GUI_SIMPLE_MESSAGE_TYPE_ABOUT,
    1039             :                                                  GUI_SIMPLE_MESSAGE_CONTENT_ABOUT
    1040             :                                                );
    1041             :     }
    1042             : 
    1043           0 :     U8_TRACE_TIMESTAMP();
    1044           0 :     U8_TRACE_END();
    1045           0 : }
    1046             : 
    1047           0 : void gui_main_window_data_changed_callback( GtkWidget *window, data_change_message_t *msg, gpointer user_data )
    1048             : {
    1049           0 :     U8_TRACE_BEGIN();
    1050           0 :     gui_main_window_t *this_ = user_data;
    1051             : 
    1052           0 :     if (( DATA_CHANGE_EVENT_TYPE_DB_OPENED == data_change_message_get_event( msg ) )
    1053           0 :         || ( DATA_CHANGE_EVENT_TYPE_DB_CLOSED == data_change_message_get_event( msg ) ))
    1054             :     {
    1055             :         /* the database has changed */
    1056           0 :         const char *filename = io_data_file_get_filename_const( (*this_).data_file );
    1057           0 :         if ( NULL == filename )
    1058             :         {
    1059           0 :             gtk_window_set_title(GTK_WINDOW((*this_).window), META_INFO_PROGRAM_NAME_STR );
    1060             :         }
    1061             :         else
    1062             :         {
    1063           0 :             gtk_window_set_title(GTK_WINDOW((*this_).window), filename );
    1064             :         }
    1065             :     }
    1066             : 
    1067           0 :     U8_TRACE_TIMESTAMP();
    1068           0 :     U8_TRACE_END();
    1069           0 : }
    1070             : 
    1071             : 
    1072             : /*
    1073             : Copyright 2016-2024 Andreas Warnke
    1074             : 
    1075             : Licensed under the Apache License, Version 2.0 (the "License");
    1076             : you may not use this file except in compliance with the License.
    1077             : You may obtain a copy of the License at
    1078             : 
    1079             :     http://www.apache.org/licenses/LICENSE-2.0
    1080             : 
    1081             : Unless required by applicable law or agreed to in writing, software
    1082             : distributed under the License is distributed on an "AS IS" BASIS,
    1083             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    1084             : See the License for the specific language governing permissions and
    1085             : limitations under the License.
    1086             : */

Generated by: LCOV version 1.16