| 256 | } |
| 257 | |
| 258 | std::vector<std::filesystem::path> gtkDialog( const MR::FileDialog::Parameters& params = {} ) |
| 259 | { |
| 260 | // Gtk has a nasty habit of overriding the locale to "".s |
| 261 | std::optional<std::string> localeStr; |
| 262 | if ( auto locale = std::setlocale( LC_ALL, nullptr ) ) |
| 263 | localeStr = std::string( locale ); |
| 264 | MR_FINALLY { |
| 265 | if ( localeStr ) |
| 266 | std::setlocale( LC_ALL, localeStr->c_str() ); |
| 267 | }; |
| 268 | |
| 269 | if ( !gtk_init_check( NULL, NULL ) ) |
| 270 | { |
| 271 | spdlog::error( "Failed to initialize GTK+" ); |
| 272 | return {}; |
| 273 | } |
| 274 | MR_FINALLY { |
| 275 | while ( gtk_events_pending() ) |
| 276 | gtk_main_iteration(); |
| 277 | }; |
| 278 | |
| 279 | auto [action, title] = gtkDialogParameters( params ); |
| 280 | auto* dialog = gtk_file_chooser_dialog_new( title.c_str(), NULL, action, NULL, NULL ); |
| 281 | MR_FINALLY { |
| 282 | gtk_widget_destroy( dialog ); |
| 283 | }; |
| 284 | |
| 285 | gtk_dialog_add_button( GTK_DIALOG( dialog ), params.saveDialog ? "_Save" : "_Open", GTK_RESPONSE_ACCEPT ); |
| 286 | gtk_dialog_add_button( GTK_DIALOG( dialog ), "_Cancel", GTK_RESPONSE_CANCEL ); |
| 287 | |
| 288 | auto* chooser = GTK_FILE_CHOOSER( dialog ); |
| 289 | |
| 290 | gtk_file_chooser_set_select_multiple( chooser, params.multiselect ); |
| 291 | |
| 292 | for ( const auto& filter: params.filters ) |
| 293 | { |
| 294 | auto* fileFilter = gtk_file_filter_new(); |
| 295 | gtk_file_filter_set_name( fileFilter, filter.name.c_str() ); |
| 296 | |
| 297 | size_t separatorPos = 0; |
| 298 | for (;;) |
| 299 | { |
| 300 | auto nextSeparatorPos = filter.extensions.find( ";", separatorPos ); |
| 301 | auto ext = filter.extensions.substr( separatorPos, nextSeparatorPos - separatorPos ); |
| 302 | |
| 303 | gtk_file_filter_add_pattern( fileFilter, ext.c_str() ); |
| 304 | |
| 305 | if ( nextSeparatorPos == std::string::npos ) |
| 306 | break; |
| 307 | separatorPos = nextSeparatorPos + 1; |
| 308 | } |
| 309 | |
| 310 | gtk_file_chooser_add_filter( chooser, fileFilter ); // the chooser takes ownership of the filter |
| 311 | } |
| 312 | |
| 313 | const auto currentFolder = MR::utf8string( params.baseFolder.empty() ? |
| 314 | MR::FileDialog::getLastUsedDir() : params.baseFolder ); |
| 315 |
no test coverage detected