Line data Source code
1 : /* File: gui_file_use_db_dialog.c; Copyright and License: see below */
2 :
3 : #include "gui_file_use_db_dialog.h"
4 : #include "u8/u8_trace.h"
5 : #include <gdk/gdk.h>
6 : #include <gtk/gtk.h>
7 : #include <stdio.h>
8 : #include <stdbool.h>
9 :
10 0 : void gui_file_use_db_dialog_init ( gui_file_use_db_dialog_t *this_,
11 : ctrl_controller_t *controller,
12 : io_data_file_t *database,
13 : GtkWindow *parent_window,
14 : gui_simple_message_to_user_t *message_to_user )
15 : {
16 0 : U8_TRACE_BEGIN();
17 :
18 0 : (*this_).parent_window = parent_window;
19 :
20 : #if (( GTK_MAJOR_VERSION == 4 )&&( GTK_MINOR_VERSION < 10 ))
21 0 : (*this_).use_db_file_chooser = gtk_file_chooser_dialog_new ( "Select DB to use",
22 : parent_window,
23 : GTK_FILE_CHOOSER_ACTION_SAVE,
24 : "Cancel",
25 : GTK_RESPONSE_CANCEL,
26 : "Use DB-File",
27 : GTK_RESPONSE_ACCEPT,
28 : NULL
29 : );
30 : /* set name postponed, see https://gitlab.gnome.org/GNOME/gtk/-/issues/4832 */
31 : #else
32 : (*this_).use_db_file_dialog = gtk_file_dialog_new();
33 : gtk_file_dialog_set_accept_label( (*this_).use_db_file_dialog, "Use DB-File" );
34 : gtk_file_dialog_set_modal( (*this_).use_db_file_dialog, false );
35 : gtk_file_dialog_set_title( (*this_).use_db_file_dialog, "Select DB to use" );
36 : gtk_file_dialog_set_initial_name( (*this_).use_db_file_dialog, "NewModel.cfuJ" );
37 : #endif
38 :
39 0 : gui_file_db_manager_init( &((*this_).file_manager), controller, database, message_to_user );
40 :
41 : #if (( GTK_MAJOR_VERSION == 4 )&&( GTK_MINOR_VERSION < 10 ))
42 0 : g_signal_connect( G_OBJECT((*this_).use_db_file_chooser),
43 : "response",
44 : G_CALLBACK(gui_file_use_db_dialog_response_callback),
45 : this_
46 : );
47 0 : gtk_window_set_hide_on_close( GTK_WINDOW((*this_).use_db_file_chooser), true);
48 : #else
49 : /* no signal at new FileDialog - this works with Async, see gtk_file_dialog_save */
50 : #endif
51 :
52 0 : U8_TRACE_END();
53 0 : }
54 :
55 0 : void gui_file_use_db_dialog_destroy( gui_file_use_db_dialog_t *this_ )
56 : {
57 0 : U8_TRACE_BEGIN();
58 :
59 : #if (( GTK_MAJOR_VERSION == 4 )&&( GTK_MINOR_VERSION < 10 ))
60 0 : gtk_window_destroy( GTK_WINDOW((*this_).use_db_file_chooser) );
61 : /* no need to g_object_unref ( (*this_).use_db_file_chooser ); here */
62 : #else
63 : g_object_unref( (*this_).use_db_file_dialog );
64 : #endif
65 :
66 0 : gui_file_db_manager_destroy( &((*this_).file_manager) );
67 :
68 0 : (*this_).parent_window = NULL;
69 :
70 0 : U8_TRACE_END();
71 0 : }
72 :
73 0 : void gui_file_use_db_dialog_show( gui_file_use_db_dialog_t *this_, bool open_existing )
74 : {
75 0 : U8_TRACE_BEGIN();
76 :
77 : #if (( GTK_MAJOR_VERSION == 4 )&&( GTK_MINOR_VERSION < 10 ))
78 0 : gtk_file_chooser_set_action( GTK_FILE_CHOOSER( (*this_).use_db_file_chooser ),
79 0 : open_existing ? GTK_FILE_CHOOSER_ACTION_OPEN : GTK_FILE_CHOOSER_ACTION_SAVE
80 : );
81 0 : if( ! open_existing )
82 : {
83 : /* moved here as workaround for disabled file dialog widgets, see https://gitlab.gnome.org/GNOME/gtk/-/issues/4832 */
84 0 : gtk_file_chooser_set_current_name( GTK_FILE_CHOOSER( (*this_).use_db_file_chooser ), "untitled.cfuJ" );
85 : }
86 :
87 0 : gtk_widget_set_visible( GTK_WIDGET( (*this_).use_db_file_chooser ), TRUE );
88 :
89 0 : gtk_widget_set_sensitive( GTK_WIDGET((*this_).use_db_file_chooser), TRUE ); /* idea taken from gtk demo */
90 :
91 0 : GdkSurface *surface = gtk_native_get_surface( GTK_NATIVE((*this_).use_db_file_chooser) );
92 0 : gdk_surface_set_cursor( surface, NULL ); /* idea taken from gtk3->4 guide */
93 : #else
94 : if ( open_existing )
95 : {
96 : gtk_file_dialog_open( (*this_).use_db_file_dialog,
97 : (*this_).parent_window,
98 : NULL,
99 : &gui_file_use_db_dialog_async_ready_callback_on_open,
100 : this_
101 : );
102 : }
103 : else
104 : {
105 : gtk_file_dialog_save( (*this_).use_db_file_dialog,
106 : (*this_).parent_window,
107 : NULL,
108 : &gui_file_use_db_dialog_async_ready_callback_on_save,
109 : this_
110 : );
111 : }
112 : #endif
113 :
114 0 : U8_TRACE_END();
115 0 : }
116 :
117 : #if (( GTK_MAJOR_VERSION == 4 )&&( GTK_MINOR_VERSION < 10 ))
118 :
119 0 : void gui_file_use_db_dialog_response_callback( GtkDialog *dialog, gint response_id, gpointer user_data )
120 : {
121 0 : U8_TRACE_BEGIN();
122 0 : gui_file_use_db_dialog_t *this_ = user_data;
123 :
124 0 : switch ( response_id )
125 : {
126 0 : case GTK_RESPONSE_ACCEPT:
127 : {
128 0 : U8_LOG_EVENT( "GTK_RESPONSE_ACCEPT" );
129 0 : gtk_widget_set_visible( GTK_WIDGET ( dialog ), FALSE );
130 :
131 0 : gchar *filename = NULL;
132 0 : GFile *selected_file = gtk_file_chooser_get_file( GTK_FILE_CHOOSER(dialog) );
133 0 : if ( selected_file != NULL )
134 : {
135 0 : filename = g_file_get_path( selected_file );
136 : }
137 0 : if ( filename != NULL )
138 : {
139 0 : U8_TRACE_INFO_STR( "File chosen:", filename );
140 :
141 0 : gui_file_db_manager_use_db( &((*this_).file_manager), filename );
142 :
143 0 : g_free (filename);
144 : }
145 : else
146 : {
147 0 : U8_LOG_WARNING( "Use DB dialog returned no file name" );
148 : }
149 0 : if ( selected_file != NULL )
150 : {
151 0 : g_object_unref( selected_file );
152 : }
153 : }
154 0 : break;
155 :
156 0 : case GTK_RESPONSE_CANCEL:
157 : {
158 0 : U8_LOG_EVENT( "GTK_RESPONSE_CANCEL" );
159 0 : gtk_widget_set_visible( GTK_WIDGET ( dialog ), FALSE );
160 : }
161 0 : break;
162 :
163 0 : case GTK_RESPONSE_DELETE_EVENT:
164 : {
165 0 : U8_LOG_EVENT( "GTK_RESPONSE_DELETE_EVENT" );
166 : }
167 0 : break;
168 :
169 0 : default:
170 : {
171 0 : U8_LOG_ERROR( "unexpected response_id" );
172 : }
173 : }
174 :
175 0 : U8_TRACE_END();
176 0 : }
177 :
178 : #else /* GTK >= 4.10 */
179 :
180 : void gui_file_use_db_dialog_async_ready_callback_on_open( GObject* source_object,
181 : GAsyncResult* res,
182 : gpointer user_data )
183 : {
184 : U8_TRACE_BEGIN();
185 :
186 : gui_file_use_db_dialog_t *this_ = user_data;
187 : GError* error = NULL;
188 : GFile *result = gtk_file_dialog_open_finish( GTK_FILE_DIALOG(source_object), res, &error );
189 : if ( error != NULL )
190 : {
191 : /* User pressed cancel */
192 : U8_TRACE_INFO_STR( "unexpected response from file dialog:", error->message );
193 : g_error_free( error );
194 : }
195 : if ( result != NULL )
196 : {
197 : gchar *folder_path = g_file_get_path ( result );
198 : if ( folder_path != NULL )
199 : {
200 : U8_LOG_EVENT( "User selected a database file to open." );
201 : U8_TRACE_INFO_STR( "File to open:", folder_path );
202 :
203 : /* react immediately, handle events */
204 : bool events_handled = true;
205 : for ( uint_fast8_t max_loop = 40; events_handled && ( max_loop > 0 ); max_loop-- )
206 : {
207 : events_handled = g_main_context_iteration( NULL, /*may_block*/ FALSE );
208 : }
209 :
210 : gui_file_db_manager_use_db( &((*this_).file_manager), folder_path );
211 :
212 : g_free (folder_path);
213 : }
214 : g_object_unref( result );
215 : }
216 :
217 : U8_TRACE_END();
218 : }
219 :
220 : void gui_file_use_db_dialog_async_ready_callback_on_save( GObject* source_object,
221 : GAsyncResult* res,
222 : gpointer user_data )
223 : {
224 : U8_TRACE_BEGIN();
225 :
226 : gui_file_use_db_dialog_t *this_ = user_data;
227 : GError* error = NULL;
228 : GFile *result = gtk_file_dialog_save_finish( GTK_FILE_DIALOG(source_object), res, &error );
229 : if ( error != NULL )
230 : {
231 : /* User pressed cancel */
232 : U8_TRACE_INFO_STR( "unexpected response from file dialog:", error->message );
233 : g_error_free( error );
234 : }
235 : if ( result != NULL )
236 : {
237 : gchar *folder_path = g_file_get_path ( result );
238 : if ( folder_path != NULL )
239 : {
240 : U8_LOG_EVENT( "User selected a new database file." );
241 : U8_TRACE_INFO_STR( "File to create:", folder_path );
242 :
243 : /* react immediately, handle events */
244 : bool events_handled = true;
245 : for ( uint_fast8_t max_loop = 40; events_handled && ( max_loop > 0 ); max_loop-- )
246 : {
247 : events_handled = g_main_context_iteration( NULL, /*may_block*/ FALSE );
248 : }
249 :
250 : gui_file_db_manager_use_db( &((*this_).file_manager), folder_path );
251 :
252 : g_free (folder_path);
253 : }
254 : g_object_unref( result );
255 : }
256 :
257 : U8_TRACE_END();
258 : }
259 :
260 : #endif
261 :
262 :
263 : /*
264 : Copyright 2019-2024 Andreas Warnke
265 :
266 : Licensed under the Apache License, Version 2.0 (the "License");
267 : you may not use this file except in compliance with the License.
268 : You may obtain a copy of the License at
269 :
270 : http://www.apache.org/licenses/LICENSE-2.0
271 :
272 : Unless required by applicable law or agreed to in writing, software
273 : distributed under the License is distributed on an "AS IS" BASIS,
274 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
275 : See the License for the specific language governing permissions and
276 : limitations under the License.
277 : */
|