257 |
257 |
258 WINDOW_SHOW(GTK_WIDGET(dialog_w)); |
258 WINDOW_SHOW(GTK_WIDGET(dialog_w)); |
259 } |
259 } |
260 |
260 |
261 |
261 |
262 #if GTK_MAJOR_VERSION >= 40 |
262 #if GTK_MAJOR_VERSION >= 3 |
263 static void ui_gtkfilechooser(UiObject *obj, GtkFileChooserAction action, unsigned int mode, ui_callback file_selected_callback, void *cbdata) { |
263 UiFileList listmodel2filelist(GListModel *selection) { |
264 // TODO |
264 UiFileList flist; |
|
265 flist.files = NULL; |
|
266 flist.nfiles = 0; |
|
267 flist.nfiles = g_list_model_get_n_items(selection); |
|
268 flist.files = calloc(flist.nfiles, sizeof(char*)); |
|
269 for(int i=0;i<flist.nfiles;i++) { |
|
270 GFile *file = g_list_model_get_item(selection, i); |
|
271 char *path = g_file_get_path(file); |
|
272 flist.files[i] = path ? strdup(path) : NULL; |
|
273 g_object_unref(file); |
|
274 } |
|
275 return flist; |
|
276 } |
|
277 #endif |
|
278 |
|
279 |
|
280 #if GTK_CHECK_VERSION(4, 10, 0) |
|
281 |
|
282 #define UI_GTK_FILEDIALOG_OPEN 16 |
|
283 #define UI_GTK_FILEDIALOG_SAVE 32 |
|
284 |
|
285 static void filechooser_opened(GObject *source, GAsyncResult *result, void *data) { |
|
286 UiEventData *event = data; |
|
287 |
|
288 GFile *file = NULL; |
|
289 GListModel *selection = NULL; |
|
290 GError *error = NULL; |
|
291 |
|
292 int mode = event->value; |
|
293 int multi = mode & UI_FILEDIALOG_SELECT_MULTI; |
|
294 if((mode & UI_FILEDIALOG_SELECT_FOLDER) == UI_FILEDIALOG_SELECT_FOLDER) { |
|
295 if(multi) { |
|
296 selection = gtk_file_dialog_select_multiple_folders_finish(GTK_FILE_DIALOG(source), result, &error); |
|
297 } else { |
|
298 file = gtk_file_dialog_select_folder_finish(GTK_FILE_DIALOG(source), result, &error); |
|
299 } |
|
300 } else if((mode & UI_GTK_FILEDIALOG_OPEN) == UI_GTK_FILEDIALOG_OPEN) { |
|
301 if(multi) { |
|
302 selection = gtk_file_dialog_open_multiple_finish(GTK_FILE_DIALOG(source), result, &error); |
|
303 } else { |
|
304 file = gtk_file_dialog_open_finish(GTK_FILE_DIALOG(source), result, &error); |
|
305 } |
|
306 } else { |
|
307 file = gtk_file_dialog_save_finish(GTK_FILE_DIALOG(source), result, &error); |
|
308 } |
|
309 |
|
310 UiEvent evt; |
|
311 evt.obj = event->obj; |
|
312 evt.document = evt.obj->ctx->document; |
|
313 evt.window = evt.obj->window; |
|
314 evt.intval = 0; |
|
315 |
|
316 UiFileList flist; |
|
317 flist.files = NULL; |
|
318 flist.nfiles = 0; |
|
319 evt.eventdata = &flist; |
|
320 |
|
321 if(selection) { |
|
322 flist = listmodel2filelist(selection); |
|
323 g_object_unref(selection); |
|
324 } else if(file) { |
|
325 char *path = g_file_get_path(file); |
|
326 if(path) { |
|
327 flist.nfiles = 1; |
|
328 flist.files = calloc(flist.nfiles, sizeof(char*)); |
|
329 flist.files[0] = strdup(path); |
|
330 } |
|
331 g_object_unref(file); |
|
332 } |
|
333 |
|
334 if(event->callback) { |
|
335 event->callback(&evt, event->userdata); |
|
336 } |
|
337 |
|
338 for(int i=0;i<flist.nfiles;i++) { |
|
339 free(flist.files[i]); |
|
340 } |
|
341 } |
|
342 |
|
343 static void ui_gtkfilechooser(UiObject *obj, GtkFileChooserAction action, unsigned int mode, const char *name, ui_callback file_selected_callback, void *cbdata) { |
|
344 if(action == GTK_FILE_CHOOSER_ACTION_OPEN) { |
|
345 mode |= UI_GTK_FILEDIALOG_OPEN; |
|
346 } else { |
|
347 mode |= UI_GTK_FILEDIALOG_SAVE; |
|
348 } |
|
349 |
|
350 UiEventData *event = malloc(sizeof(UiEventData)); |
|
351 event->callback = file_selected_callback; |
|
352 event->userdata = cbdata; |
|
353 event->customdata = NULL; |
|
354 event->value = mode; |
|
355 event->obj = obj; |
|
356 |
|
357 GtkWindow *parent = GTK_WINDOW(gtk_widget_get_root(obj->widget)); |
|
358 GtkFileDialog *dialog = gtk_file_dialog_new(); |
|
359 |
|
360 int multi = mode & UI_FILEDIALOG_SELECT_MULTI; |
|
361 if((mode & UI_FILEDIALOG_SELECT_FOLDER) == UI_FILEDIALOG_SELECT_FOLDER) { |
|
362 if(multi) { |
|
363 gtk_file_dialog_select_multiple_folders(dialog, parent, NULL, filechooser_opened, event); |
|
364 } else { |
|
365 gtk_file_dialog_select_folder(dialog, parent, NULL, filechooser_opened, event); |
|
366 } |
|
367 } else if(action == GTK_FILE_CHOOSER_ACTION_OPEN) { |
|
368 if(multi) { |
|
369 gtk_file_dialog_open_multiple(dialog, parent, NULL, filechooser_opened, event); |
|
370 } else { |
|
371 gtk_file_dialog_open(dialog, parent, NULL, filechooser_opened, event); |
|
372 } |
|
373 } else { |
|
374 gtk_file_dialog_save(dialog, parent, NULL, filechooser_opened, event); |
|
375 } |
|
376 |
|
377 g_object_unref(dialog); |
265 } |
378 } |
266 #else |
379 #else |
267 |
380 |
268 |
381 |
269 |
382 |
280 evt.eventdata = &flist; |
393 evt.eventdata = &flist; |
281 |
394 |
282 if(response_id == GTK_RESPONSE_ACCEPT) { |
395 if(response_id == GTK_RESPONSE_ACCEPT) { |
283 #if GTK_CHECK_VERSION(4, 0, 0) |
396 #if GTK_CHECK_VERSION(4, 0, 0) |
284 GListModel *selection = gtk_file_chooser_get_files(GTK_FILE_CHOOSER(self)); |
397 GListModel *selection = gtk_file_chooser_get_files(GTK_FILE_CHOOSER(self)); |
285 flist.nfiles = g_list_model_get_n_items(selection); |
398 flist = flist = listmodel2filelist(selection); |
286 flist.files = calloc(flist.nfiles, sizeof(char*)); |
|
287 for(int i=0;i<flist.nfiles;i++) { |
|
288 GFile *file = g_list_model_get_item(selection, i); |
|
289 char *path = g_file_get_path(file); |
|
290 flist.files[i] = strdup(path ? path : ""); |
|
291 g_object_unref(file); |
|
292 } |
|
293 g_object_unref(selection); |
399 g_object_unref(selection); |
294 #else |
400 #else |
295 GSList *selection = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(self)); |
401 GSList *selection = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(self)); |
296 flist.nfiles = g_slist_length(selection); |
402 flist.nfiles = g_slist_length(selection); |
297 flist.files = calloc(flist.nfiles, sizeof(char*)); |
403 flist.files = calloc(flist.nfiles, sizeof(char*)); |
393 gtk_widget_show(dialog); |
499 gtk_widget_show(dialog); |
394 } |
500 } |
395 #endif |
501 #endif |
396 |
502 |
397 void ui_openfiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata) { |
503 void ui_openfiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata) { |
398 ui_gtkfilechooser(obj, GTK_FILE_CHOOSER_ACTION_OPEN, mode, file_selected_callback, cbdata); |
504 ui_gtkfilechooser(obj, GTK_FILE_CHOOSER_ACTION_OPEN, mode, NULL, file_selected_callback, cbdata); |
399 } |
505 } |
400 |
506 |
401 void ui_savefiledialog(UiObject *obj, const char *name, ui_callback file_selected_callback, void *cbdata) { |
507 void ui_savefiledialog(UiObject *obj, const char *name, ui_callback file_selected_callback, void *cbdata) { |
402 ui_gtkfilechooser(obj, GTK_FILE_CHOOSER_ACTION_SAVE, 0, file_selected_callback, cbdata); |
508 ui_gtkfilechooser(obj, GTK_FILE_CHOOSER_ACTION_SAVE, 0, name, file_selected_callback, cbdata); |
403 } |
509 } |
404 |
510 |