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 "gui_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 : data_stat_t stat;
71 0 : data_stat_init( &stat );
72 0 : const u8_error_t error = io_data_file_open_writeable ( (*this_).data_file, filename, &stat, &err_info );
73 :
74 0 : if ( U8_ERROR_NONE == error )
75 : {
76 : /* ensure that at least one diagram exists - otherwise the first window looks a bit empty */
77 : ctrl_diagram_controller_t *diag_control;
78 0 : diag_control = ctrl_controller_get_diagram_control_ptr( (*this_).controller );
79 0 : ctrl_diagram_controller_create_root_diagram_if_not_exists( diag_control,
80 : DATA_DIAGRAM_TYPE_UML_USE_CASE_DIAGRAM,
81 : "New Diagram",
82 : NULL
83 : );
84 :
85 : /* remove the loading message if not overwritten: */
86 0 : if ( GUI_SIMPLE_MESSAGE_TYPE_INFO == gui_simple_message_to_user_get_type_id( (*this_).message_to_user ) )
87 : {
88 0 : const bool warning
89 0 : = 0 < ( data_stat_get_series_count( &stat, DATA_STAT_SERIES_WARNING )
90 0 : + data_stat_get_series_count( &stat, DATA_STAT_SERIES_ERROR ) );
91 0 : gui_simple_message_to_user_show_message_with_name_and_stat( (*this_).message_to_user,
92 : ( warning ? GUI_SIMPLE_MESSAGE_TYPE_WARNING : GUI_SIMPLE_MESSAGE_TYPE_INFO ),
93 : GUI_SIMPLE_MESSAGE_CONTENT_DB_FILE_OPENED,
94 : filename,
95 : &stat
96 : );
97 : /* gui_simple_message_to_user_hide( (*this_).message_to_user ); */
98 : }
99 : }
100 0 : else if ( U8_ERROR_NO_DB == error )
101 : {
102 : /* Most likely the parent directory of database is read only */
103 0 : gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
104 : GUI_SIMPLE_MESSAGE_TYPE_ERROR,
105 : GUI_SIMPLE_MESSAGE_CONTENT_DB_FILE_NOT_CREATEABLE,
106 : filename
107 : );
108 : }
109 0 : else if ( U8_ERROR_LOCKED_BY_TEMP_FILE == error )
110 : {
111 : /* Most likely the parent directory of database is read only */
112 0 : gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
113 : GUI_SIMPLE_MESSAGE_TYPE_ERROR,
114 : GUI_SIMPLE_MESSAGE_CONTENT_DB_FILE_LOCKED,
115 : filename
116 : );
117 : }
118 : else
119 : {
120 0 : if ( u8_error_info_is_error( &err_info ) )
121 : {
122 0 : gui_simple_message_to_user_show_error_info( (*this_).message_to_user, &err_info );
123 : }
124 0 : else if ( io_data_file_is_open( (*this_).data_file ) )
125 : {
126 0 : gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
127 : GUI_SIMPLE_MESSAGE_TYPE_WARNING,
128 : GUI_SIMPLE_MESSAGE_CONTENT_DB_FILE_OPENED_WITH_ERROR,
129 : filename
130 : );
131 : }
132 : else
133 : {
134 0 : gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
135 : GUI_SIMPLE_MESSAGE_TYPE_ERROR,
136 : GUI_SIMPLE_MESSAGE_CONTENT_DB_FILE_NOT_OPENED,
137 : filename
138 : );
139 : }
140 : }
141 0 : data_stat_destroy( &stat );
142 :
143 0 : U8_TRACE_END_ERR( error );
144 0 : return error;
145 : }
146 :
147 0 : u8_error_t gui_file_action_save( gui_file_action_t *this_ )
148 : {
149 0 : U8_TRACE_BEGIN();
150 0 : u8_error_t err = U8_ERROR_NONE;
151 :
152 : u8_error_t d_err;
153 0 : d_err = U8_ERROR_NONE;
154 0 : d_err |= io_data_file_trace_stats( (*this_).data_file );
155 0 : d_err |= io_data_file_sync_to_disk( (*this_).data_file );
156 0 : d_err |= io_data_file_trace_stats( (*this_).data_file );
157 0 : if ( U8_ERROR_NONE != d_err )
158 : {
159 0 : gui_simple_message_to_user_show_message( (*this_).message_to_user,
160 : GUI_SIMPLE_MESSAGE_TYPE_WARNING,
161 : GUI_SIMPLE_MESSAGE_CONTENT_DB_FILE_WRITE_ERROR
162 : );
163 : }
164 : else
165 : {
166 0 : gui_simple_message_to_user_show_message_with_name( (*this_).message_to_user,
167 : GUI_SIMPLE_MESSAGE_TYPE_INFO,
168 : GUI_SIMPLE_MESSAGE_CONTENT_DB_FILE_WRITTEN,
169 0 : io_data_file_get_filename_const( (*this_).data_file )
170 : );
171 : #ifndef NDEBUG
172 : /* in debug mode, also check consistency of database */
173 : universal_stream_output_stream_t out_stream;
174 0 : universal_stream_output_stream_init( &out_stream, stdout );
175 0 : universal_output_stream_t *const out_base = universal_stream_output_stream_get_output_stream( &out_stream );
176 : utf8stream_writer_t out_report;
177 0 : utf8stream_writer_init( &out_report, out_base );
178 : uint32_t found_errors;
179 : uint32_t fixed_errors;
180 0 : ctrl_controller_repair_database( (*this_).controller,
181 : false /* no repair, just test */,
182 : &found_errors,
183 : &fixed_errors,
184 : &out_report
185 : );
186 0 : if (( found_errors != 0 ) || ( fixed_errors != 0 ))
187 : {
188 0 : gui_simple_message_to_user_show_message_with_quantity( (*this_).message_to_user,
189 : GUI_SIMPLE_MESSAGE_TYPE_ERROR,
190 : GUI_SIMPLE_MESSAGE_CONTENT_DB_INCONSISTENT,
191 : found_errors
192 : );
193 : }
194 0 : utf8stream_writer_destroy( &out_report );
195 0 : universal_stream_output_stream_destroy( &out_stream );
196 : #endif
197 : }
198 :
199 0 : U8_TRACE_END_ERR( err );
200 0 : return err;
201 : }
202 :
203 :
204 : /*
205 : Copyright 2016-2026 Andreas Warnke
206 :
207 : Licensed under the Apache License, Version 2.0 (the "License");
208 : you may not use this file except in compliance with the License.
209 : You may obtain a copy of the License at
210 :
211 : http://www.apache.org/licenses/LICENSE-2.0
212 :
213 : Unless required by applicable law or agreed to in writing, software
214 : distributed under the License is distributed on an "AS IS" BASIS,
215 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
216 : See the License for the specific language governing permissions and
217 : limitations under the License.
218 : */
|