1
0

savefile.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #include "precomp.h"
  2. //NONPORTABLE
  3. #include <windows.h>
  4. #include <commdlg.h>
  5. #include "savefile.h"
  6. #include "../bfc/basewnd.h"
  7. #include "../studio/api.h"
  8. #include "../studio/assert.h"
  9. #include "../bfc/encodedstr.h"
  10. #include "../studio/services/svc_stringconverter.h"
  11. SaveFileWnd::SaveFileWnd(const char *ident) : identifier(ident),
  12. force_initial_dir(0) {}
  13. void SaveFileWnd::setInitialDir(const char *dir, int force) {
  14. initial_dir = dir;
  15. force_initial_dir = force;
  16. }
  17. int SaveFileWnd::getSaveFile(api_window *parent, const char *ext, const char *suggext) {
  18. int retcode, failed = 0;
  19. if (ext == NULL) return 0;
  20. if (Std::encodingSupportedByOS(SvcStrCnv::UTF16)) {
  21. int ret = getSaveFileW(parent, ext, suggext);
  22. // If ret returns -1, the service is not available, we will call our own
  23. // OSNative translation failure routines below:
  24. if (ret != -1) {
  25. return ret;
  26. }
  27. }
  28. char savedir[WA_MAX_PATH];
  29. Std::getCurDir(savedir, WA_MAX_PATH);
  30. char filenamebuf[MAX_PATH]="";
  31. filename = NULL;
  32. OPENFILENAME ofn;
  33. ofn.lStructSize = sizeof ofn;
  34. ofn.hwndOwner = parent->gethWnd();
  35. ofn.hInstance = NULL;
  36. ofn.lpstrFilter = ext;
  37. ofn.lpstrCustomFilter = NULL;
  38. ofn.nMaxCustFilter = 0;
  39. ofn.nFilterIndex = 0;
  40. ofn.lpstrFile = filenamebuf;
  41. ofn.nMaxFile = MAX_PATH;
  42. ofn.lpstrFileTitle = NULL;
  43. ofn.nMaxFileTitle = 0;
  44. ofn.lpstrInitialDir = NULL;
  45. const char *initDir8 = NULL;
  46. // Figure out the initial directory in UTF8
  47. char dir[WA_MAX_PATH]="";
  48. String tname;
  49. if (identifier != NULL) {
  50. tname.printf("Recent directories/SaveFile/%s", identifier.getValue());
  51. if (force_initial_dir)
  52. initial_dir.strncpyTo(dir, sizeof(dir));
  53. else
  54. WASABI_API_CONFIG->getStringPublic(tname, dir, WA_MAX_PATH, initial_dir);
  55. if (*dir) initDir8 = dir;
  56. }
  57. // And then convert it when you're done to OSNATIVE.
  58. EncodedStr initDirOSenc;
  59. retcode = initDirOSenc.convertFromUTF8(SvcStrCnv::OSNATIVE, String(initDir8));
  60. if (retcode == SvcStrCnv::ERROR_UNAVAILABLE) {
  61. failed = 1;
  62. ofn.lpstrInitialDir = initDir8;
  63. } else {
  64. ofn.lpstrInitialDir = static_cast<char *>(initDirOSenc.getEncodedBuffer());
  65. }
  66. ofn.lpstrTitle = NULL;
  67. ofn.Flags = OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT|OFN_NOREADONLYRETURN|OFN_HIDEREADONLY;
  68. ofn.nFileOffset = 0;
  69. ofn.nFileExtension = 0;
  70. ofn.lpstrDefExt = suggext;
  71. ofn.lCustData = 0;
  72. ofn.lpfnHook = NULL;
  73. ofn.lpTemplateName = NULL;
  74. api->pushModalWnd();
  75. int ret = GetSaveFileName(&ofn);
  76. api->popModalWnd();
  77. if (failed) {
  78. if (ret)
  79. filename = filenamebuf;
  80. } else {
  81. // Okay, at this point we have the string in OSNATIVE format.
  82. // Now we downconvert everything to UTF8 and pass our information to the engine API's
  83. if (ret) {
  84. EncodedStr bufOSstr(SvcStrCnv::OSNATIVE, filenamebuf, STRLEN(filenamebuf)+1, 0/*no delete*/);
  85. bufOSstr.convertToUTF8(filename);
  86. }
  87. }
  88. // get new cur dir & save it off
  89. if ((identifier != NULL) && ret) {
  90. char newdir[WA_MAX_PATH];
  91. Std::getCurDir(newdir, WA_MAX_PATH);
  92. WASABI_API_CONFIG->setStringPublic(tname, newdir);
  93. }
  94. // put back old one
  95. Std::setCurDir(savedir);
  96. return ret;
  97. }
  98. int SaveFileWnd::getSaveFileW(api_window *parent, const char *ext, const char *suggext) {
  99. // The ultimate top level retrohack. (sigh).
  100. // Test to see if the service is available. If not, return -1.
  101. // The OSNATIVE codepath will include the proper failure handling.
  102. StringConverterEnum myServiceEnum(SvcStrCnv::UTF16); // _ASSUME_ that there is a converter for U16 (we should, but still...)
  103. svc_stringConverter *myConv = myServiceEnum.getFirst();
  104. if (myConv != NULL) {
  105. myServiceEnum.release(myConv);
  106. } else {
  107. return -1;
  108. }
  109. char savedir[WA_MAX_PATH];
  110. Std::getCurDir(savedir, WA_MAX_PATH);
  111. WCHAR filenamebufW[MAX_PATH] = L"";
  112. filename = NULL;
  113. // convert multi const char* ext to U16 (Ascii7 assumptive)
  114. int thisz = 0, lastz = 0;
  115. const char *px;
  116. WCHAR *pr, *ext16 = static_cast<WCHAR *>(MALLOC(WA_MAX_PATH));
  117. for (px = ext, pr = ext16; *px | (lastz); px++, pr++) {
  118. lastz = (thisz)?1:0;
  119. *pr = (*px) & 0xFF;
  120. thisz = (*pr)?1:0;
  121. }
  122. *pr = *px; // the last 0
  123. EncodedStr suggext16;
  124. suggext16.convertFromUTF8(SvcStrCnv::UTF16, String(suggext));
  125. OPENFILENAMEW ofnW;
  126. ofnW.lStructSize = sizeof ofnW;
  127. ofnW.hwndOwner = parent->gethWnd();
  128. ofnW.hInstance = NULL;
  129. ofnW.lpstrFilter = ext16;
  130. ofnW.lpstrCustomFilter = NULL;
  131. ofnW.nMaxCustFilter = 0;
  132. ofnW.nFilterIndex = 0;
  133. ofnW.lpstrFile = filenamebufW;
  134. ofnW.nMaxFile = MAX_PATH;
  135. ofnW.lpstrFileTitle = NULL;
  136. ofnW.nMaxFileTitle = 0;
  137. ofnW.lpstrInitialDir = NULL;
  138. char dir[WA_MAX_PATH]="";
  139. String tname;
  140. // Figure out the initial directory in UTF8
  141. const char *initDir8 = NULL;
  142. if (identifier != NULL) {
  143. tname.printf("Recent directories/SaveFile/%s", identifier.getValue());
  144. if (force_initial_dir)
  145. initial_dir.strncpyTo(dir, sizeof(dir));
  146. else
  147. WASABI_API_CONFIG->getStringPublic(tname, dir, WA_MAX_PATH, "");
  148. if (*dir) initDir8 = dir;
  149. }
  150. // And then convert it when you're done to UTF16.
  151. WCHAR *initDir16 = NULL;
  152. EncodedStr initDir16enc;
  153. if (initDir8 != NULL) {
  154. int written = initDir16enc.convertFromUTF8(SvcStrCnv::UTF16, String(initDir8));
  155. if (written > 0) {
  156. initDir16 = static_cast<WCHAR *>(initDir16enc.getEncodedBuffer());
  157. } else {
  158. return -1;
  159. }
  160. }
  161. // And then stuff it here. Phew!
  162. ofnW.lpstrInitialDir = initDir16;
  163. ofnW.lpstrTitle = NULL;
  164. ofnW.Flags = OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT|OFN_NOREADONLYRETURN|OFN_HIDEREADONLY;
  165. ofnW.nFileOffset = 0;
  166. ofnW.nFileExtension = 0;
  167. ofnW.lpstrDefExt = static_cast<WCHAR *>(suggext16.getEncodedBuffer());
  168. ofnW.lCustData = 0;
  169. ofnW.lpfnHook = NULL;
  170. ofnW.lpTemplateName = NULL;
  171. api->pushModalWnd();
  172. int ret = GetSaveFileNameW(&ofnW);
  173. api->popModalWnd();
  174. // Okay, at this point we have the string in UTF16 widechar format.
  175. // Now we downconvert everything to UTF8 and pass our information to the engine API's
  176. if (ret) {
  177. EncodedStr buf16str(SvcStrCnv::UTF16, filenamebufW, (WSTRLEN(filenamebufW)+1)*2, 0/*no delete*/);
  178. buf16str.convertToUTF8(filename);
  179. }
  180. // get new cur dir & save it off
  181. if ((identifier != NULL) && ret) {
  182. char newdir[WA_MAX_PATH];
  183. Std::getCurDir(newdir, WA_MAX_PATH);
  184. WASABI_API_CONFIG->setStringPublic(tname, newdir);
  185. }
  186. FREE(ext16);
  187. // put back old one
  188. Std::setCurDir(savedir);
  189. return ret;
  190. }