nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList, const nfdchar_t *defaultPath, nfdchar_t **outPath ) { GtkWidget *dialog; nfdresult_t result; if ( !gtk_init_check( NULL, NULL ) ) { NFDi_SetError(INIT_FAIL_MSG); return NFD_ERROR; } dialog = gtk_file_chooser_dialog_new( "Save File", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, "_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_ACCEPT, NULL ); gtk_file_chooser_set_do_overwrite_confirmation( GTK_FILE_CHOOSER(dialog), TRUE ); /* Build the filter list */ AddFiltersToDialog(dialog, filterList); /* Set the default path */ SetDefaultPath(dialog, defaultPath); result = NFD_CANCEL; if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT ) { char *filename; filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) ); { size_t len = strlen(filename); *outPath = NFDi_Malloc( len + 1 ); memcpy( *outPath, filename, len + 1 ); if ( !*outPath ) { g_free( filename ); gtk_widget_destroy(dialog); return NFD_ERROR; } } g_free(filename); result = NFD_OKAY; } WaitForCleanup(); gtk_widget_destroy(dialog); WaitForCleanup(); return result; }
nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList, const nfdchar_t *defaultPath, nfdpathset_t *outPaths ) { GtkWidget *dialog; nfdresult_t result; if ( !gtk_init_check( NULL, NULL ) ) { NFDi_SetError(INIT_FAIL_MSG); return NFD_ERROR; } dialog = gtk_file_chooser_dialog_new( "Open Files", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, "_Cancel", GTK_RESPONSE_CANCEL, "_Open", GTK_RESPONSE_ACCEPT, NULL ); gtk_file_chooser_set_select_multiple( GTK_FILE_CHOOSER(dialog), TRUE ); /* Build the filter list */ AddFiltersToDialog(dialog, filterList); /* Set the default path */ SetDefaultPath(dialog, defaultPath); result = NFD_CANCEL; if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT ) { GSList *fileList = gtk_file_chooser_get_filenames( GTK_FILE_CHOOSER(dialog) ); if ( AllocPathSet( fileList, outPaths ) == NFD_ERROR ) { gtk_widget_destroy(dialog); return NFD_ERROR; } result = NFD_OKAY; } WaitForCleanup(); gtk_widget_destroy(dialog); WaitForCleanup(); return result; }
nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList, const nfdchar_t *defaultPath, nfdchar_t **outPath ) { nfdresult_t nfdResult = NFD_ERROR; // Init COM library. HRESULT result = ::CoInitializeEx(NULL, ::COINIT_APARTMENTTHREADED | ::COINIT_DISABLE_OLE1DDE ); if ( !SUCCEEDED(result)) { NFDi_SetError("Could not initialize COM."); return NFD_ERROR; } ::IFileSaveDialog *fileSaveDialog(NULL); // Create dialog result = ::CoCreateInstance(::CLSID_FileSaveDialog, NULL, CLSCTX_ALL, ::IID_IFileSaveDialog, reinterpret_cast<void**>(&fileSaveDialog) ); if ( !SUCCEEDED(result) ) { NFDi_SetError("Could not create dialog."); goto end; } // Build the filter list if ( !AddFiltersToDialog( fileSaveDialog, filterList ) ) { goto end; } // Set the default path if ( !SetDefaultPath( fileSaveDialog, defaultPath ) ) { goto end; } // Show the dialog. result = fileSaveDialog->Show(NULL); if ( SUCCEEDED(result) ) { // Get the file name ::IShellItem *shellItem; result = fileSaveDialog->GetResult(&shellItem); if ( !SUCCEEDED(result) ) { NFDi_SetError("Could not get shell item from dialog."); goto end; } wchar_t *filePath(NULL); result = shellItem->GetDisplayName(::SIGDN_FILESYSPATH, &filePath); if ( !SUCCEEDED(result) ) { NFDi_SetError("Could not get file path for selected."); goto end; } CopyWCharToNFDChar( filePath, outPath ); CoTaskMemFree(filePath); if ( !*outPath ) { /* error is malloc-based, error message would be redundant */ goto end; } nfdResult = NFD_OKAY; shellItem->Release(); } else if (result == HRESULT_FROM_WIN32(ERROR_CANCELLED) ) { nfdResult = NFD_CANCEL; } else { NFDi_SetError("File dialog box show failed."); nfdResult = NFD_ERROR; } end: ::CoUninitialize(); return nfdResult; }
nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList, const nfdchar_t *defaultPath, nfdpathset_t *outPaths ) { nfdresult_t nfdResult = NFD_ERROR; // Init COM library. HRESULT result = ::CoInitializeEx(NULL, ::COINIT_APARTMENTTHREADED | ::COINIT_DISABLE_OLE1DDE ); if ( !SUCCEEDED(result)) { NFDi_SetError("Could not initialize COM."); return NFD_ERROR; } ::IFileOpenDialog *fileOpenDialog(NULL); // Create dialog result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL, CLSCTX_ALL, ::IID_IFileOpenDialog, reinterpret_cast<void**>(&fileOpenDialog) ); if ( !SUCCEEDED(result) ) { NFDi_SetError("Could not create dialog."); goto end; } // Build the filter list if ( !AddFiltersToDialog( fileOpenDialog, filterList ) ) { goto end; } // Set the default path if ( !SetDefaultPath( fileOpenDialog, defaultPath ) ) { goto end; } // Set a flag for multiple options DWORD dwFlags; result = fileOpenDialog->GetOptions(&dwFlags); if ( !SUCCEEDED(result) ) { NFDi_SetError("Could not get options."); goto end; } result = fileOpenDialog->SetOptions(dwFlags | FOS_ALLOWMULTISELECT); if ( !SUCCEEDED(result) ) { NFDi_SetError("Could not set options."); goto end; } // Show the dialog. result = fileOpenDialog->Show(NULL); if ( SUCCEEDED(result) ) { IShellItemArray *shellItems; result = fileOpenDialog->GetResults( &shellItems ); if ( !SUCCEEDED(result) ) { NFDi_SetError("Could not get shell items."); goto end; } if ( AllocPathSet( shellItems, outPaths ) == NFD_ERROR ) { goto end; } shellItems->Release(); nfdResult = NFD_OKAY; } else if (result == HRESULT_FROM_WIN32(ERROR_CANCELLED) ) { nfdResult = NFD_CANCEL; } else { NFDi_SetError("File dialog box show failed."); nfdResult = NFD_ERROR; } end: ::CoUninitialize(); return nfdResult; }
nfdresult_t NFD_PickFolder(const nfdchar_t *defaultPath, nfdchar_t **outPath) { // Init COM AutoCoInit autoCoInit; if (!SUCCEEDED(autoCoInit.Result())) { NFDi_SetError("CoInitializeEx failed."); return NFD_ERROR; } // Create the file dialog COM object ComPtr<IFileDialog> pFileDialog; if (!SUCCEEDED(CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pFileDialog)))) { NFDi_SetError("CoCreateInstance for CLSID_FileOpenDialog failed."); return NFD_ERROR; } // Set the default path if (SetDefaultPath(pFileDialog.Ptr(), defaultPath) != NFD_OKAY) { NFDi_SetError("SetDefaultPath failed."); return NFD_ERROR; } // Get the dialogs options DWORD dwOptions = 0; if (!SUCCEEDED(pFileDialog->GetOptions(&dwOptions))) { NFDi_SetError("GetOptions for IFileDialog failed."); return NFD_ERROR; } // Add in FOS_PICKFOLDERS which hides files and only allows selection of folders if (!SUCCEEDED(pFileDialog->SetOptions(dwOptions | FOS_PICKFOLDERS))) { NFDi_SetError("SetOptions for IFileDialog failed."); return NFD_ERROR; } // Show the dialog to the user const HRESULT result = pFileDialog->Show(NULL); if (result == HRESULT_FROM_WIN32(ERROR_CANCELLED)) { return NFD_CANCEL; } else if (!SUCCEEDED(result)) { NFDi_SetError("Show for IFileDialog failed."); return NFD_ERROR; } // Get the shell item result ComPtr<IShellItem> pShellItem; if (!SUCCEEDED(pFileDialog->GetResult(&pShellItem))) { return NFD_OKAY; } // Finally get the path wchar_t *path = NULL; if (!SUCCEEDED(pShellItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &path))) { NFDi_SetError("GetDisplayName for IShellItem failed."); return NFD_ERROR; } // Convert string CopyWCharToNFDChar(path, outPath); CoTaskMemFree(path); if (!*outPath) { // error is malloc-based, error message would be redundant return NFD_ERROR; } return NFD_OKAY; }
nfdresult_t NFD_ChooseDirectory(const nfdchar_t *prompt, const nfdchar_t *defaultPath, nfdchar_t **outPath ) { nfdresult_t nfdResult = NFD_ERROR; // Init COM library. HRESULT result = ::CoInitializeEx(NULL, ::COINIT_APARTMENTTHREADED | ::COINIT_DISABLE_OLE1DDE ); wchar_t *promptW = {0}; if (prompt && strlen(prompt)) CopyNFDCharToWChar( prompt, &promptW ); if ( !SUCCEEDED(result)) { NFDi_SetError("Could not initialize COM."); goto end; } ::IFileOpenDialog *fileOpenDialog(NULL); // Create dialog result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL, CLSCTX_ALL, ::IID_IFileOpenDialog, reinterpret_cast<void**>(&fileOpenDialog) ); if ( !SUCCEEDED(result) ) { NFDi_SetError("Could not create dialog."); goto end; } DWORD dwOptions; if (SUCCEEDED(fileOpenDialog->GetOptions(&dwOptions))) { fileOpenDialog->SetOptions(dwOptions | FOS_PICKFOLDERS); } // Set the default path if ( !SetDefaultPath( fileOpenDialog, defaultPath ) ) { goto end; } fileOpenDialog->SetTitle(promptW); // Show the dialog. result = fileOpenDialog->Show(NULL); if ( SUCCEEDED(result) ) { // Get the file name ::IShellItem *shellItem(NULL); result = fileOpenDialog->GetResult(&shellItem); if ( !SUCCEEDED(result) ) { NFDi_SetError("Could not get shell item from dialog."); goto end; } wchar_t *filePath(NULL); result = shellItem->GetDisplayName(::SIGDN_FILESYSPATH, &filePath); if ( !SUCCEEDED(result) ) { NFDi_SetError("Could not get file path for selected."); goto end; } CopyWCharToNFDChar( filePath, outPath ); CoTaskMemFree(filePath); if ( !*outPath ) { /* error is malloc-based, error message would be redundant */ goto end; } nfdResult = NFD_OKAY; shellItem->Release(); } else if (result == HRESULT_FROM_WIN32(ERROR_CANCELLED) ) { nfdResult = NFD_CANCEL; } else { NFDi_SetError("File dialog box show failed."); nfdResult = NFD_ERROR; } end: if (prompt && strlen(prompt)); NFDi_Free( promptW ); ::CoUninitialize(); return nfdResult; }