osxFileDialogs.mm 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #import "platformOSX/platformOSX.h"
  23. #import "platformOSX/osxCocoaUtilities.h"
  24. #include "platform/nativeDialogs/fileDialog.h"
  25. #include "io/resource/resourceManager.h"
  26. //-----------------------------------------------------------------------------
  27. bool FileDialog::Execute()
  28. {
  29. NSArray* nsFileArray;
  30. if (mData.mStyle & FileDialogData::FDS_OPEN)
  31. {
  32. nsFileArray = [NSOpenPanel showOpenPanel:&mData];
  33. }
  34. else if (mData.mStyle & FileDialogData::FDS_SAVE)
  35. {
  36. nsFileArray = [NSSavePanel showSavePanel:&mData];
  37. }
  38. else
  39. {
  40. Con::errorf("Bad File Dialog Setup.");
  41. return false;
  42. }
  43. if ([nsFileArray count] < 1)
  44. return false;
  45. // If multiple file selection was allowed and the dialog did grab multiple files
  46. // loop through and add them
  47. if ((mData.mStyle & FileDialogData::FDS_MULTIPLEFILES) && [nsFileArray count] >= 1)
  48. {
  49. for(U32 i = 0; i < [nsFileArray count]; i++)
  50. {
  51. NSURL* fileURL = [nsFileArray objectAtIndex:i];
  52. const UTF8* file = [[fileURL path] UTF8String];
  53. setDataField(StringTable->insert("files"), Con::getIntArg(i), StringTable->insert(file));
  54. }
  55. setDataField(StringTable->insert("fileCount"), NULL, Con::getIntArg((S32)[nsFileArray count]));
  56. }
  57. else
  58. {
  59. NSURL* fileURL = [nsFileArray objectAtIndex:0];
  60. const UTF8* file = [[fileURL path] UTF8String];
  61. mData.mFile = StringTable->insert(file);
  62. }
  63. return true;
  64. }
  65. //-----------------------------------------------------------------------------
  66. // Default Path Property - String Validated on Write
  67. bool FileDialog::setDefaultPath(void* obj, const char* data)
  68. {
  69. if (!data || !dStrncmp(data, "", 1))
  70. return true;
  71. // Expand the path to something fully qualified
  72. static char szPathValidate[512];
  73. Platform::makeFullPathName(data, szPathValidate, sizeof(szPathValidate));
  74. // Check to make sure the path is valid
  75. ResourceManager->addPath(szPathValidate, true);
  76. if (Platform::isDirectory(szPathValidate))
  77. {
  78. // Finally, assign in proper format.
  79. FileDialog *pDlg = static_cast<FileDialog*>(obj);
  80. pDlg->mData.mDefaultPath = StringTable->insert(szPathValidate);
  81. }
  82. return false;
  83. }
  84. //-----------------------------------------------------------------------------
  85. // Default Path Property - String Validated on Write
  86. bool FileDialog::setDefaultFile(void* obj, const char* data)
  87. {
  88. if (!data || !dStrncmp(data, "", 1))
  89. return true;
  90. // Copy and Backslash the path (Windows dialogs are VERY picky about this format)
  91. static char szPathValidate[512];
  92. Platform::makeFullPathName(data,szPathValidate, sizeof(szPathValidate));
  93. // Finally, assign in proper format.
  94. FileDialog *pDlg = static_cast<FileDialog*>(obj);
  95. pDlg->mData.mDefaultFile = StringTable->insert(szPathValidate);
  96. return false;
  97. };
  98. struct _NSStringMap
  99. {
  100. S32 num;
  101. NSString* ok;
  102. NSString* cancel;
  103. NSString* third;
  104. };
  105. static _NSStringMap sgButtonTextMap[] =
  106. {
  107. { MBOk, @"Ok", nil, nil },
  108. { MBOkCancel, @"Ok", @"Cancel", nil },
  109. { MBRetryCancel, @"Retry", @"Cancel", nil },
  110. { MBSaveDontSave, @"Yes", @"No", nil },
  111. { MBSaveDontSaveCancel, @"Save", @"Cancel", @"Don't Save" },
  112. { -1, nil, nil, nil }
  113. };
  114. //-----------------------------------------------------------------------------
  115. // Standard message box with a single "OK" button
  116. void Platform::AlertOK(const char *windowTitle, const char *message)
  117. {
  118. Platform::messageBox(windowTitle, message, MBOk, MIWarning);
  119. }
  120. //-----------------------------------------------------------------------------
  121. // Displays an alert with Cancel and OK as buttons
  122. bool Platform::AlertOKCancel(const char *windowTitle, const char *message)
  123. {
  124. S32 result = Platform::messageBox(windowTitle, message, MBOkCancel, MIWarning);
  125. return (result == NSAlertFirstButtonReturn);
  126. }
  127. //-----------------------------------------------------------------------------
  128. // Standard message box with Cancel and Retry buttons
  129. bool Platform::AlertRetry(const char *windowTitle, const char *message)
  130. {
  131. S32 result = Platform::messageBox(windowTitle, message, MBRetryCancel, MIWarning);
  132. return (result == NSAlertFirstButtonReturn);
  133. }
  134. //-----------------------------------------------------------------------------
  135. // Standard message box with No and Yes buttons
  136. bool Platform::AlertYesNo(const char *windowTitle, const char *message)
  137. {
  138. S32 result = Platform::messageBox(windowTitle, message, MBSaveDontSave, MIWarning);
  139. return (result == NSAlertFirstButtonReturn);
  140. }
  141. //-----------------------------------------------------------------------------
  142. // Responsible for creating, building, showing, and catching the return of
  143. // a NSAlert. The messageBox ConsoleFunction calls into this
  144. S32 Platform::messageBox(const UTF8 *title, const UTF8 *message, MBButtons buttons, MBIcons icon)
  145. {
  146. NSString *okBtn = nil;
  147. NSString *cancelBtn = nil;
  148. NSString *thirdBtn = nil;
  149. U32 i;
  150. for (i = 0; sgButtonTextMap[i].num != -1; i++)
  151. {
  152. if (sgButtonTextMap[i].num != buttons)
  153. continue;
  154. okBtn = sgButtonTextMap[i].ok;
  155. cancelBtn = sgButtonTextMap[i].cancel;
  156. thirdBtn = sgButtonTextMap[i].third;
  157. break;
  158. }
  159. if(sgButtonTextMap[i].num == -1)
  160. Con::errorf("Unknown message box button set requested. Mac Platform::messageBox() probably needs to be updated.");
  161. // convert title and message to NSStrings
  162. NSString *nsTitle = [NSString stringWithUTF8String:title];
  163. NSString *nsMessage = [NSString stringWithUTF8String:message];
  164. Input::setCursorShape(CursorManager::curIBeam);
  165. NSAlert *alert = [[[NSAlert alloc] init] autorelease];
  166. [alert setAlertStyle:NSWarningAlertStyle];
  167. [alert addButtonWithTitle:okBtn];
  168. [alert addButtonWithTitle:cancelBtn];
  169. [alert addButtonWithTitle:thirdBtn];
  170. [alert setMessageText:nsTitle];
  171. [alert setInformativeText:nsMessage];
  172. S32 result = (S32)[alert runModal];
  173. return result;
  174. }