diff options
author | Jean-Francois Mauguit <jfmauguit@mac.com> | 2024-09-24 09:03:25 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-24 09:03:25 -0400 |
commit | bab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Wasabi/api/util/savefile.cpp | |
parent | 4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff) | |
parent | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff) | |
download | winamp-bab614c421ed7ae329d26bf028c4a3b1d2450f5a.tar.gz |
Merge pull request #5 from WinampDesktop/community
Merge to main
Diffstat (limited to 'Src/Wasabi/api/util/savefile.cpp')
-rw-r--r-- | Src/Wasabi/api/util/savefile.cpp | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/Src/Wasabi/api/util/savefile.cpp b/Src/Wasabi/api/util/savefile.cpp new file mode 100644 index 00000000..f7766fa7 --- /dev/null +++ b/Src/Wasabi/api/util/savefile.cpp @@ -0,0 +1,228 @@ +#include "precomp.h" +//NONPORTABLE + +#include <windows.h> +#include <commdlg.h> +#include "savefile.h" + +#include "../bfc/basewnd.h" + +#include "../studio/api.h" +#include "../studio/assert.h" + +#include "../bfc/encodedstr.h" +#include "../studio/services/svc_stringconverter.h" + +SaveFileWnd::SaveFileWnd(const char *ident) : identifier(ident), + force_initial_dir(0) {} + +void SaveFileWnd::setInitialDir(const char *dir, int force) { + initial_dir = dir; + force_initial_dir = force; +} + +int SaveFileWnd::getSaveFile(api_window *parent, const char *ext, const char *suggext) { + int retcode, failed = 0; + if (ext == NULL) return 0; + + if (Std::encodingSupportedByOS(SvcStrCnv::UTF16)) { + int ret = getSaveFileW(parent, ext, suggext); + // If ret returns -1, the service is not available, we will call our own + // OSNative translation failure routines below: + if (ret != -1) { + return ret; + } + } + + char savedir[WA_MAX_PATH]; + Std::getCurDir(savedir, WA_MAX_PATH); + + char filenamebuf[MAX_PATH]=""; + filename = NULL; + + OPENFILENAME ofn; + ofn.lStructSize = sizeof ofn; + ofn.hwndOwner = parent->gethWnd(); + ofn.hInstance = NULL; + ofn.lpstrFilter = ext; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxCustFilter = 0; + ofn.nFilterIndex = 0; + ofn.lpstrFile = filenamebuf; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + + ofn.lpstrInitialDir = NULL; + const char *initDir8 = NULL; + + // Figure out the initial directory in UTF8 + char dir[WA_MAX_PATH]=""; + String tname; + if (identifier != NULL) { + tname.printf("Recent directories/SaveFile/%s", identifier.getValue()); + if (force_initial_dir) + initial_dir.strncpyTo(dir, sizeof(dir)); + else + WASABI_API_CONFIG->getStringPublic(tname, dir, WA_MAX_PATH, initial_dir); + if (*dir) initDir8 = dir; + } + + // And then convert it when you're done to OSNATIVE. + EncodedStr initDirOSenc; + retcode = initDirOSenc.convertFromUTF8(SvcStrCnv::OSNATIVE, String(initDir8)); + if (retcode == SvcStrCnv::ERROR_UNAVAILABLE) { + failed = 1; + ofn.lpstrInitialDir = initDir8; + } else { + ofn.lpstrInitialDir = static_cast<char *>(initDirOSenc.getEncodedBuffer()); + } + + ofn.lpstrTitle = NULL; + ofn.Flags = OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT|OFN_NOREADONLYRETURN|OFN_HIDEREADONLY; + ofn.nFileOffset = 0; + ofn.nFileExtension = 0; + ofn.lpstrDefExt = suggext; + ofn.lCustData = 0; + ofn.lpfnHook = NULL; + ofn.lpTemplateName = NULL; + api->pushModalWnd(); + int ret = GetSaveFileName(&ofn); + api->popModalWnd(); + + if (failed) { + if (ret) + filename = filenamebuf; + } else { + // Okay, at this point we have the string in OSNATIVE format. + // Now we downconvert everything to UTF8 and pass our information to the engine API's + if (ret) { + EncodedStr bufOSstr(SvcStrCnv::OSNATIVE, filenamebuf, STRLEN(filenamebuf)+1, 0/*no delete*/); + bufOSstr.convertToUTF8(filename); + } + } + + // get new cur dir & save it off + if ((identifier != NULL) && ret) { + char newdir[WA_MAX_PATH]; + Std::getCurDir(newdir, WA_MAX_PATH); + + WASABI_API_CONFIG->setStringPublic(tname, newdir); + } + // put back old one + Std::setCurDir(savedir); + + return ret; +} + +int SaveFileWnd::getSaveFileW(api_window *parent, const char *ext, const char *suggext) { + + // The ultimate top level retrohack. (sigh). + // Test to see if the service is available. If not, return -1. + // The OSNATIVE codepath will include the proper failure handling. + StringConverterEnum myServiceEnum(SvcStrCnv::UTF16); // _ASSUME_ that there is a converter for U16 (we should, but still...) + svc_stringConverter *myConv = myServiceEnum.getFirst(); + if (myConv != NULL) { + myServiceEnum.release(myConv); + } else { + return -1; + } + + char savedir[WA_MAX_PATH]; + Std::getCurDir(savedir, WA_MAX_PATH); + + WCHAR filenamebufW[MAX_PATH] = L""; + filename = NULL; + + // convert multi const char* ext to U16 (Ascii7 assumptive) + int thisz = 0, lastz = 0; + const char *px; + WCHAR *pr, *ext16 = static_cast<WCHAR *>(MALLOC(WA_MAX_PATH)); + for (px = ext, pr = ext16; *px | (lastz); px++, pr++) { + lastz = (thisz)?1:0; + *pr = (*px) & 0xFF; + thisz = (*pr)?1:0; + } + *pr = *px; // the last 0 + + EncodedStr suggext16; + suggext16.convertFromUTF8(SvcStrCnv::UTF16, String(suggext)); + + OPENFILENAMEW ofnW; + ofnW.lStructSize = sizeof ofnW; + ofnW.hwndOwner = parent->gethWnd(); + ofnW.hInstance = NULL; + ofnW.lpstrFilter = ext16; + ofnW.lpstrCustomFilter = NULL; + ofnW.nMaxCustFilter = 0; + ofnW.nFilterIndex = 0; + ofnW.lpstrFile = filenamebufW; + ofnW.nMaxFile = MAX_PATH; + ofnW.lpstrFileTitle = NULL; + ofnW.nMaxFileTitle = 0; + + ofnW.lpstrInitialDir = NULL; + + char dir[WA_MAX_PATH]=""; + String tname; + + // Figure out the initial directory in UTF8 + const char *initDir8 = NULL; + if (identifier != NULL) { + tname.printf("Recent directories/SaveFile/%s", identifier.getValue()); + if (force_initial_dir) + initial_dir.strncpyTo(dir, sizeof(dir)); + else + WASABI_API_CONFIG->getStringPublic(tname, dir, WA_MAX_PATH, ""); + if (*dir) initDir8 = dir; + } + + // And then convert it when you're done to UTF16. + WCHAR *initDir16 = NULL; + EncodedStr initDir16enc; + if (initDir8 != NULL) { + int written = initDir16enc.convertFromUTF8(SvcStrCnv::UTF16, String(initDir8)); + if (written > 0) { + initDir16 = static_cast<WCHAR *>(initDir16enc.getEncodedBuffer()); + } else { + return -1; + } + } + + // And then stuff it here. Phew! + ofnW.lpstrInitialDir = initDir16; + + ofnW.lpstrTitle = NULL; + ofnW.Flags = OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT|OFN_NOREADONLYRETURN|OFN_HIDEREADONLY; + ofnW.nFileOffset = 0; + ofnW.nFileExtension = 0; + ofnW.lpstrDefExt = static_cast<WCHAR *>(suggext16.getEncodedBuffer()); + ofnW.lCustData = 0; + ofnW.lpfnHook = NULL; + ofnW.lpTemplateName = NULL; + api->pushModalWnd(); + int ret = GetSaveFileNameW(&ofnW); + api->popModalWnd(); + + // Okay, at this point we have the string in UTF16 widechar format. + // Now we downconvert everything to UTF8 and pass our information to the engine API's + if (ret) { + EncodedStr buf16str(SvcStrCnv::UTF16, filenamebufW, (WSTRLEN(filenamebufW)+1)*2, 0/*no delete*/); + buf16str.convertToUTF8(filename); + } + + // get new cur dir & save it off + if ((identifier != NULL) && ret) { + char newdir[WA_MAX_PATH]; + Std::getCurDir(newdir, WA_MAX_PATH); + + WASABI_API_CONFIG->setStringPublic(tname, newdir); + } + + FREE(ext16); + + // put back old one + Std::setCurDir(savedir); + + return ret; +} |