Line data Source code
1 : /* File: gui_file_action.c; Copyright and License: see below */
2 :
3 : #include "gui_file_action.h"
4 : #include "u8/u8_error_info.h"
5 : #include "u8/u8_trace.h"
6 : #ifndef NDEBUG
7 : #include "u8stream/universal_stream_output_stream.h"
8 : #include "utf8stream/utf8stream_writer.h"
9 : #endif /* not NDEBUG */
10 : #include <gtk/gtk.h>
11 : #include <stdio.h>
12 : #include <stdbool.h>
13 : #include <assert.h>
14 :
15 0 : void gui_file_action_init( gui_file_action_t *this_,
16 : ctrl_controller_t *controller,
17 : io_data_file_t *data_file,
18 : gui_simple_message_to_user_t *message_to_user )
19 : {
20 0 : U8_TRACE_BEGIN();
21 0 : assert( NULL != controller );
22 0 : assert( NULL != data_file );
23 0 : assert( NULL != message_to_user );
24 :
25 0 : (*this_).controller = controller;
26 0 : (*this_).data_file = data_file;
27 0 : (*this_).message_to_user = message_to_user;
28 :
29 0 : U8_TRACE_END();
30 0 : }
31 :
32 0 : void gui_file_action_destroy( gui_file_action_t *this_ )
33 : {
34 0 : U8_TRACE_BEGIN();
35 :
36 0 : (*this_).controller = NULL;
37 0 : (*this_).data_file = NULL;
38 0 : (*this_).message_to_user = NULL;
39 :
40 0 : U8_TRACE_END();
41 0 : }
42 :
43 0 : u8_error_t gui_file_action_use_db( gui_file_action_t *this_, const char *filename )
44 : {
45 0 : U8_TRACE_BEGIN();
46 :
47 0 : if ( io_data_file_is_open( (*this_).data_file ) )
48 : {
49 0 : const u8_error_t close_err = io_data_file_close( (*this_).data_file );
50 0 : if ( close_err != U8_ERROR_NONE )
51 : {
52 0 : U8_LOG_ERROR( "Closing the database was not possible" );
53 0 : U8_TRACE_INFO_STR( "Closing the database was not possible:", io_data_file_get_filename_const( (*this_).data_file ) );
54 : }
55 : }
56 :
57 : /* react immediately */
58 0 : gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
59 : GUI_SIMPLE_MESSAGE_TYPE_INFO,
60 : GUI_SIMPLE_MESSAGE_CONTENT_LOADING_WAIT,
61 : filename
62 : );
63 0 : bool events_handled = true;
64 0 : for ( uint_fast8_t max_loop = 40; events_handled && ( max_loop > 0 ); max_loop-- )
65 : {
66 0 : events_handled = g_main_context_iteration( NULL, /*may_block*/ FALSE );
67 : }
68 :
69 : u8_error_info_t err_info;
70 0 : const u8_error_t error = io_data_file_open_writeable ( (*this_).data_file, filename, &err_info );
71 :
72 0 : if ( U8_ERROR_NONE == error )
73 : {
74 : /* ensure that at least one diagram exists - otherwise the first window looks a bit empty */
75 : ctrl_diagram_controller_t *diag_control;
76 0 : diag_control = ctrl_controller_get_diagram_control_ptr( (*this_).controller );
77 0 : ctrl_diagram_controller_create_root_diagram_if_not_exists( diag_control,
78 : DATA_DIAGRAM_TYPE_UML_USE_CASE_DIAGRAM,
79 : "New Overview",
80 : NULL
81 : );
82 :
83 : /* remove the loading message if not overwritten: */
84 0 : if ( GUI_SIMPLE_MESSAGE_TYPE_INFO == gui_simple_message_to_user_get_type_id( (*this_).message_to_user ) )
85 : {
86 0 : gui_simple_message_to_user_hide( (*this_).message_to_user );
87 : }
88 : }
89 0 : else if ( U8_ERROR_NO_DB == error )
90 : {
91 : /* Most likely the parent directory of database is read only */
92 0 : gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
93 : GUI_SIMPLE_MESSAGE_TYPE_ERROR,
94 : GUI_SIMPLE_MESSAGE_CONTENT_DB_FILE_NOT_CREATEABLE,
95 : filename
96 : );
97 : }
98 : else
99 : {
100 0 : if ( u8_error_info_is_error( &err_info ) )
101 : {
102 0 : gui_simple_message_to_user_show_error_info( (*this_).message_to_user, &err_info );
103 : }
104 0 : else if ( io_data_file_is_open( (*this_).data_file ) )
105 : {
106 0 : gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
107 : GUI_SIMPLE_MESSAGE_TYPE_WARNING,
108 : GUI_SIMPLE_MESSAGE_CONTENT_DB_FILE_OPENED_WITH_ERROR,
109 : filename
110 : );
111 : }
112 : else
113 : {
114 0 : gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
115 : GUI_SIMPLE_MESSAGE_TYPE_ERROR,
116 : GUI_SIMPLE_MESSAGE_CONTENT_DB_FILE_NOT_OPENED,
117 : filename
118 : );
119 : }
120 : }
121 :
122 0 : U8_TRACE_END_ERR( error );
123 0 : return error;
124 : }
125 :
126 0 : u8_error_t gui_file_action_save( gui_file_action_t *this_ )
127 : {
128 0 : U8_TRACE_BEGIN();
129 0 : u8_error_t err = U8_ERROR_NONE;
130 :
131 : u8_error_t d_err;
132 0 : d_err = U8_ERROR_NONE;
133 0 : d_err |= io_data_file_trace_stats( (*this_).data_file );
134 0 : d_err |= io_data_file_sync_to_disk( (*this_).data_file );
135 0 : d_err |= io_data_file_trace_stats( (*this_).data_file );
136 0 : if ( U8_ERROR_NONE != d_err )
137 : {
138 0 : gui_simple_message_to_user_show_message( (*this_).message_to_user,
139 : GUI_SIMPLE_MESSAGE_TYPE_WARNING,
140 : GUI_SIMPLE_MESSAGE_CONTENT_DB_FILE_WRITE_ERROR
141 : );
142 : }
143 : else
144 : {
145 0 : gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
146 : GUI_SIMPLE_MESSAGE_TYPE_INFO,
147 : GUI_SIMPLE_MESSAGE_CONTENT_DB_FILE_WRITTEN,
148 0 : io_data_file_get_filename_const( (*this_).data_file )
149 : );
150 : #ifndef NDEBUG
151 : /* in debug mode, also check consistency of database */
152 : universal_stream_output_stream_t out_stream;
153 0 : universal_stream_output_stream_init( &out_stream, stdout );
154 0 : universal_output_stream_t *const out_base = universal_stream_output_stream_get_output_stream( &out_stream );
155 : utf8stream_writer_t out_report;
156 0 : utf8stream_writer_init( &out_report, out_base );
157 : uint32_t found_errors;
158 : uint32_t fixed_errors;
159 0 : ctrl_controller_repair_database( (*this_).controller,
160 : false /* no repair, just test */,
161 : &found_errors,
162 : &fixed_errors,
163 : &out_report
164 : );
165 0 : if (( found_errors != 0 ) || ( fixed_errors != 0 ))
166 : {
167 0 : gui_simple_message_to_user_show_message_with_quantity( (*this_).message_to_user,
168 : GUI_SIMPLE_MESSAGE_TYPE_ERROR,
169 : GUI_SIMPLE_MESSAGE_CONTENT_DB_INCONSISTENT,
170 : found_errors
171 : );
172 : }
173 0 : utf8stream_writer_destroy( &out_report );
174 0 : universal_stream_output_stream_destroy( &out_stream );
175 : #endif
176 : }
177 :
178 0 : U8_TRACE_END_ERR( err );
179 0 : return err;
180 : }
181 :
182 :
183 : /*
184 : Copyright 2016-2024 Andreas Warnke
185 :
186 : Licensed under the Apache License, Version 2.0 (the "License");
187 : you may not use this file except in compliance with the License.
188 : You may obtain a copy of the License at
189 :
190 : http://www.apache.org/licenses/LICENSE-2.0
191 :
192 : Unless required by applicable law or agreed to in writing, software
193 : distributed under the License is distributed on an "AS IS" BASIS,
194 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
195 : See the License for the specific language governing permissions and
196 : limitations under the License.
197 : */
|