aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/api/util/savefile.cpp
diff options
context:
space:
mode:
authorJean-Francois Mauguit <jfmauguit@mac.com>2024-09-24 09:03:25 -0400
committerGitHub <noreply@github.com>2024-09-24 09:03:25 -0400
commitbab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Wasabi/api/util/savefile.cpp
parent4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff)
parent20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff)
downloadwinamp-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.cpp228
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;
+}