| 437 | } |
| 438 | |
| 439 | std::vector<std::filesystem::path> runPortalFileDialog( const MR::FileDialog::Parameters& params ) |
| 440 | { |
| 441 | auto* conn = getConnection(); |
| 442 | if ( !conn ) |
| 443 | return {}; |
| 444 | |
| 445 | // https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.FileChooser.html |
| 446 | auto* callMsg = dbus_message_new_method_call( cPortalServiceName, cPortalObjectPath, cFileChooserInterface, params.saveDialog ? "SaveFile" : "OpenFile" ); |
| 447 | |
| 448 | const auto parentWindowId = getWindowId( getViewerInstance().window ); |
| 449 | |
| 450 | const auto* title = params.multiselect ? "Open Files" : "Open File"; |
| 451 | if ( params.folderDialog ) |
| 452 | title = params.multiselect ? "Open Folders" : "Open Folder"; |
| 453 | else if ( params.saveDialog ) |
| 454 | title = params.multiselect ? "Save Files" : "Save File"; |
| 455 | |
| 456 | FileChooserOptions options; |
| 457 | options.handleToken = "MeshLibFileDialogPortal"; // randomize token? |
| 458 | options.currentFolder = params.baseFolder; |
| 459 | for ( const auto& filter : params.filters ) |
| 460 | { |
| 461 | options.filters.push_back( { |
| 462 | .name = filter.name, |
| 463 | .globs = split( filter.extensions, ";" ), |
| 464 | } ); |
| 465 | } |
| 466 | if ( !params.saveDialog ) |
| 467 | { |
| 468 | options.multiple = params.multiselect; |
| 469 | options.directory = params.folderDialog; |
| 470 | } |
| 471 | else |
| 472 | { |
| 473 | options.currentName = params.fileName; |
| 474 | } |
| 475 | |
| 476 | initArgs( callMsg, parentWindowId.c_str(), title, options ); |
| 477 | |
| 478 | DBusError err; |
| 479 | dbus_error_init( &err ); |
| 480 | MR_FINALLY { dbus_error_free( &err ); }; |
| 481 | |
| 482 | dbus_connection_send_with_reply_and_block( conn, callMsg, DBUS_TIMEOUT_INFINITE, &err ); |
| 483 | dbus_connection_flush( conn ); |
| 484 | dbus_message_unref( callMsg ); |
| 485 | if ( dbus_error_is_set( &err ) ) |
| 486 | { |
| 487 | spdlog::warn( "Failed to send DBus message: {}", err.message ); |
| 488 | return {}; |
| 489 | } |
| 490 | |
| 491 | auto resp = waitForResponse( conn ); |
| 492 | if ( !resp ) |
| 493 | return {}; |
| 494 | if ( resp->code != Response::Succeeded ) |
| 495 | return {}; |
| 496 |
no test coverage detected